4 * Copyright (C) 1999 Alexandre Julliard
6 * Originally distributed under LPGL 2.1 (or later) by the Wine project.
8 * Modified for use with MPlayer, detailed CVS changelog at
9 * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
11 * File now distributed as part of VLC media player with no modifications.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
35 #include <sys/types.h>
37 #include "wine/winbase.h"
38 #include "wine/winreg.h"
39 #include "wine/winnt.h"
40 #include "wine/winerror.h"
46 //#define TRACE printf
48 extern char *get_path ( char * );
50 // ...can be set before init_registry() call
51 char* regpathname = NULL;
53 static char* localregpathname = NULL;
55 typedef struct reg_handle_s
59 struct reg_handle_s* next;
60 struct reg_handle_s* prev;
71 static struct reg_value* regs = NULL;
73 static reg_handle_t* head = NULL;
77 static void create_registry(void);
78 static void open_registry(void);
79 static void save_registry(void);
80 static void init_registry(void);
83 static void create_registry(void){
86 printf("Logic error: create_registry() called with existing registry\n");
90 regs=(struct reg_value*)malloc(3*sizeof(struct reg_value));
91 regs[0].type=regs[1].type=DIR;
92 regs[0].name=(char*)malloc(5);
93 strcpy(regs[0].name, "HKLM");
94 regs[1].name=(char*)malloc(5);
95 strcpy(regs[1].name, "HKCU");
96 regs[0].value=regs[1].value=NULL;
97 regs[0].len=regs[1].len=0;
103 static void open_registry(void)
110 printf("Multiple open_registry(>\n");
113 fd = open(localregpathname, O_RDONLY);
116 printf("Creating new registry\n");
120 read(fd, ®_size, 4);
121 regs=(struct reg_value*)malloc(reg_size*sizeof(struct reg_value));
123 for(i=0; i<reg_size; i++)
125 read(fd,®s[i].type,4);
127 regs[i].name=(char*)malloc(len+1);
133 read(fd, regs[i].name, len);
135 read(fd,®s[i].len,4);
136 regs[i].value=(char*)malloc(regs[i].len+1);
143 read(fd, regs[i].value, regs[i].len);
144 regs[i].value[regs[i].len]=0;
151 static void save_registry(void)
156 fd = open(localregpathname, O_WRONLY | O_CREAT, 00666);
159 printf("Failed to open registry file '%s' for writing.\n",
163 write(fd, ®_size, 4);
164 for(i=0; i<reg_size; i++)
166 unsigned len=strlen(regs[i].name);
167 write(fd, ®s[i].type, 4);
169 write(fd, regs[i].name, len);
170 write(fd, ®s[i].len, 4);
171 write(fd, regs[i].value, regs[i].len);
176 void free_registry(void)
178 reg_handle_t* t = head;
191 for(i=0; i<reg_size; i++)
200 if (localregpathname && localregpathname != regpathname)
201 free(localregpathname);
202 localregpathname = 0;
206 static reg_handle_t* find_handle_by_name(const char* name)
209 for(t=head; t; t=t->prev)
211 if(!strcmp(t->name, name))
218 static struct reg_value* find_value_by_name(const char* name)
221 for(i=0; i<reg_size; i++)
222 if(!strcmp(regs[i].name, name))
226 static reg_handle_t* find_handle(int handle)
229 for(t=head; t; t=t->prev)
231 if(t->handle==handle)
238 static int generate_handle()
240 static unsigned int zz=249;
242 while((zz==HKEY_LOCAL_MACHINE) || (zz==HKEY_CURRENT_USER))
247 static reg_handle_t* insert_handle(long handle, const char* name)
250 t=(reg_handle_t*)malloc(sizeof(reg_handle_t));
261 t->name=(char*)malloc(strlen(name)+1);
262 strcpy(t->name, name);
267 static char* build_keyname(long key, const char* subkey)
271 if((t=find_handle(key))==0)
273 TRACE("Invalid key\n");
278 full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10);
279 strcpy(full_name, t->name);
280 strcat(full_name, "\\");
281 strcat(full_name, subkey);
284 static struct reg_value* insert_reg_value(int handle, const char* name, int type, const void* value, int len)
289 if((fullname=build_keyname(handle, name))==NULL)
291 TRACE("Invalid handle\n");
295 if((v=find_value_by_name(fullname))==0)
296 //creating new value in registry
300 regs=(struct reg_value*)realloc(regs, sizeof(struct reg_value)*(reg_size+1));
301 //regs=(struct reg_value*)my_realloc(regs, sizeof(struct reg_value)*(reg_size+1));
311 TRACE("RegInsert '%s' %p v:%d len:%d\n", name, value, *(int*)value, len);
314 v->value=(char*)malloc(len);
315 memcpy(v->value, value, len);
316 v->name=(char*)malloc(strlen(fullname)+1);
317 strcpy(v->name, fullname);
323 static void init_registry(void)
325 TRACE("Initializing registry\n");
326 // can't be free-ed - it's static and probably thread
327 // unsafe structure which is stored in glibc
330 regpathname = get_path("registry");
331 localregpathname = regpathname;
333 // regpathname is an external pointer
335 // registry.c is holding its own internal pointer
336 // localregpathname - which is being allocate/deallocated
338 if (localregpathname == 0)
340 const char* pthn = regpathname;
343 // avifile - for now reading data from user's home
344 struct passwd* pwent;
345 pwent = getpwuid(geteuid());
346 pthn = pwent->pw_dir;
349 localregpathname = (char*)malloc(strlen(pthn)+20);
350 strcpy(localregpathname, pthn);
351 strcat(localregpathname, "/.registry");
356 insert_handle(HKEY_LOCAL_MACHINE, "HKLM");
357 insert_handle(HKEY_CURRENT_USER, "HKCU");
360 static reg_handle_t* find_handle_2(long key, const char* subkey)
364 if((t=find_handle(key))==0)
366 TRACE("Invalid key\n");
367 return (reg_handle_t*)-1;
371 full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10);
372 strcpy(full_name, t->name);
373 strcat(full_name, "\\");
374 strcat(full_name, subkey);
375 t=find_handle_by_name(full_name);
380 long __stdcall RegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
385 TRACE("Opening key %s\n", subkey);
390 /* t=find_handle_2(key, subkey);
395 if(t==(reg_handle_t*)-1)
398 full_name=build_keyname(key, subkey);
401 TRACE("Opening key Fullname %s\n", full_name);
402 v=find_value_by_name(full_name);
404 t=insert_handle(generate_handle(), full_name);
410 long __stdcall RegCloseKey(long key)
412 reg_handle_t *handle;
413 if(key==(long)HKEY_LOCAL_MACHINE)
415 if(key==(long)HKEY_CURRENT_USER)
417 handle=find_handle(key);
421 handle->prev->next=handle->next;
423 handle->next->prev=handle->prev;
432 long __stdcall RegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count)
436 TRACE("Querying value %s\n", value);
440 c=build_keyname(key, value);
443 t=find_value_by_name(c);
451 memcpy(data, t->value, (t->len<*count)?t->len:*count);
452 TRACE("returning %d bytes: %d\n", t->len, *(int*)data);
457 return ERROR_MORE_DATA;
465 long __stdcall RegCreateKeyExA(long key, const char* name, long reserved,
466 void* classs, long options, long security,
467 void* sec_attr, int* newkey, int* status)
472 // TRACE("Creating/Opening key %s\n", name);
476 fullname=build_keyname(key, name);
479 TRACE("Creating/Opening key %s\n", fullname);
480 v=find_value_by_name(fullname);
484 v=insert_reg_value(key, name, DIR, &qw, 4);
485 if (status) *status=REG_CREATED_NEW_KEY;
489 t=insert_handle(generate_handle(), fullname);
497 HKEY hKey, // handle to key to query
498 DWORD dwIndex, // index of value to query
499 LPTSTR lpValueName, // address of buffer for value string
500 LPDWORD lpcbValueName, // address for size of value buffer
501 LPDWORD lpReserved, // reserved
502 LPDWORD lpType, // address of buffer for type code
503 LPBYTE lpData, // address of buffer for value data
504 LPDWORD lpcbData // address for size of data buffer
508 long __stdcall RegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count,
509 LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count)
511 // currenly just made to support MSZH & ZLIB
512 //printf("Reg Enum 0x%x %d %s %d data: %p %d %d >%s<\n", hkey, index,
513 // value, *val_count, data, *count, reg_size, data);
514 reg_handle_t* t = find_handle(hkey);
517 struct reg_value* v=find_value_by_name(t->name);
520 memcpy(data, v->value, (v->len < *count) ? v->len : *count);
525 //printf("Found handle %s\n", v->name);
529 return ERROR_NO_MORE_ITEMS;
532 long __stdcall RegSetValueExA(long key, const char* name, long v1, long v2, const void* data, long size)
536 TRACE("Request to set value %s %d\n", name, *(const int*)data);
540 c=build_keyname(key, name);
543 insert_reg_value(key, name, v2, data, size);
548 long __stdcall RegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName,
549 LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass,
550 LPFILETIME lpftLastWriteTime)
552 return ERROR_NO_MORE_ITEMS;