2 * Modified for use with MPlayer, detailed CVS changelog at
3 * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
14 #include <sys/types.h>
16 #include "wine/winbase.h"
17 #include "wine/winreg.h"
18 #include "wine/winnt.h"
19 #include "wine/winerror.h"
25 //#define TRACE printf
27 extern char *get_path ( char * );
29 // ...can be set before init_registry() call
30 char* regpathname = NULL;
32 static char* localregpathname = NULL;
34 typedef struct reg_handle_s
38 struct reg_handle_s* next;
39 struct reg_handle_s* prev;
50 static struct reg_value* regs = NULL;
52 static reg_handle_t* head = NULL;
56 static void create_registry(void);
57 static void open_registry(void);
58 static void save_registry(void);
59 static void init_registry(void);
62 static void create_registry(void){
65 printf("Logic error: create_registry() called with existing registry\n");
69 regs=(struct reg_value*)malloc(3*sizeof(struct reg_value));
70 regs[0].type=regs[1].type=DIR;
71 regs[0].name=(char*)malloc(5);
72 strcpy(regs[0].name, "HKLM");
73 regs[1].name=(char*)malloc(5);
74 strcpy(regs[1].name, "HKCU");
75 regs[0].value=regs[1].value=NULL;
76 regs[0].len=regs[1].len=0;
82 static void open_registry(void)
89 printf("Multiple open_registry(>\n");
92 fd = open(localregpathname, O_RDONLY);
95 printf("Creating new registry\n");
99 read(fd, ®_size, 4);
100 regs=(struct reg_value*)malloc(reg_size*sizeof(struct reg_value));
102 for(i=0; i<reg_size; i++)
104 read(fd,®s[i].type,4);
106 regs[i].name=(char*)malloc(len+1);
112 read(fd, regs[i].name, len);
114 read(fd,®s[i].len,4);
115 regs[i].value=(char*)malloc(regs[i].len+1);
122 read(fd, regs[i].value, regs[i].len);
123 regs[i].value[regs[i].len]=0;
130 static void save_registry(void)
135 fd = open(localregpathname, O_WRONLY | O_CREAT, 00666);
138 printf("Failed to open registry file '%s' for writing.\n",
142 write(fd, ®_size, 4);
143 for(i=0; i<reg_size; i++)
145 unsigned len=strlen(regs[i].name);
146 write(fd, ®s[i].type, 4);
148 write(fd, regs[i].name, len);
149 write(fd, ®s[i].len, 4);
150 write(fd, regs[i].value, regs[i].len);
155 void free_registry(void)
157 reg_handle_t* t = head;
170 for(i=0; i<reg_size; i++)
179 if (localregpathname && localregpathname != regpathname)
180 free(localregpathname);
181 localregpathname = 0;
185 static reg_handle_t* find_handle_by_name(const char* name)
188 for(t=head; t; t=t->prev)
190 if(!strcmp(t->name, name))
197 static struct reg_value* find_value_by_name(const char* name)
200 for(i=0; i<reg_size; i++)
201 if(!strcmp(regs[i].name, name))
205 static reg_handle_t* find_handle(int handle)
208 for(t=head; t; t=t->prev)
210 if(t->handle==handle)
217 static int generate_handle()
219 static unsigned int zz=249;
221 while((zz==HKEY_LOCAL_MACHINE) || (zz==HKEY_CURRENT_USER))
226 static reg_handle_t* insert_handle(long handle, const char* name)
229 t=(reg_handle_t*)malloc(sizeof(reg_handle_t));
240 t->name=(char*)malloc(strlen(name)+1);
241 strcpy(t->name, name);
246 static char* build_keyname(long key, const char* subkey)
250 if((t=find_handle(key))==0)
252 TRACE("Invalid key\n");
257 full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10);
258 strcpy(full_name, t->name);
259 strcat(full_name, "\\");
260 strcat(full_name, subkey);
263 static struct reg_value* insert_reg_value(int handle, const char* name, int type, const void* value, int len)
268 if((fullname=build_keyname(handle, name))==NULL)
270 TRACE("Invalid handle\n");
274 if((v=find_value_by_name(fullname))==0)
275 //creating new value in registry
279 regs=(struct reg_value*)realloc(regs, sizeof(struct reg_value)*(reg_size+1));
280 //regs=(struct reg_value*)my_realloc(regs, sizeof(struct reg_value)*(reg_size+1));
290 TRACE("RegInsert '%s' %p v:%d len:%d\n", name, value, *(int*)value, len);
293 v->value=(char*)malloc(len);
294 memcpy(v->value, value, len);
295 v->name=(char*)malloc(strlen(fullname)+1);
296 strcpy(v->name, fullname);
302 static void init_registry(void)
304 TRACE("Initializing registry\n");
305 // can't be free-ed - it's static and probably thread
306 // unsafe structure which is stored in glibc
309 regpathname = get_path("registry");
310 localregpathname = regpathname;
312 // regpathname is an external pointer
314 // registry.c is holding it's own internal pointer
315 // localregpathname - which is being allocate/deallocated
317 if (localregpathname == 0)
319 const char* pthn = regpathname;
322 // avifile - for now reading data from user's home
323 struct passwd* pwent;
324 pwent = getpwuid(geteuid());
325 pthn = pwent->pw_dir;
328 localregpathname = (char*)malloc(strlen(pthn)+20);
329 strcpy(localregpathname, pthn);
330 strcat(localregpathname, "/.registry");
335 insert_handle(HKEY_LOCAL_MACHINE, "HKLM");
336 insert_handle(HKEY_CURRENT_USER, "HKCU");
339 static reg_handle_t* find_handle_2(long key, const char* subkey)
343 if((t=find_handle(key))==0)
345 TRACE("Invalid key\n");
346 return (reg_handle_t*)-1;
350 full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10);
351 strcpy(full_name, t->name);
352 strcat(full_name, "\\");
353 strcat(full_name, subkey);
354 t=find_handle_by_name(full_name);
359 long __stdcall RegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
364 TRACE("Opening key %s\n", subkey);
369 /* t=find_handle_2(key, subkey);
374 if(t==(reg_handle_t*)-1)
377 full_name=build_keyname(key, subkey);
380 TRACE("Opening key Fullname %s\n", full_name);
381 v=find_value_by_name(full_name);
383 t=insert_handle(generate_handle(), full_name);
389 long __stdcall RegCloseKey(long key)
391 reg_handle_t *handle;
392 if(key==(long)HKEY_LOCAL_MACHINE)
394 if(key==(long)HKEY_CURRENT_USER)
396 handle=find_handle(key);
400 handle->prev->next=handle->next;
402 handle->next->prev=handle->prev;
411 long __stdcall RegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count)
415 TRACE("Querying value %s\n", value);
419 c=build_keyname(key, value);
422 t=find_value_by_name(c);
430 memcpy(data, t->value, (t->len<*count)?t->len:*count);
431 TRACE("returning %d bytes: %d\n", t->len, *(int*)data);
436 return ERROR_MORE_DATA;
444 long __stdcall RegCreateKeyExA(long key, const char* name, long reserved,
445 void* classs, long options, long security,
446 void* sec_attr, int* newkey, int* status)
451 // TRACE("Creating/Opening key %s\n", name);
455 fullname=build_keyname(key, name);
458 TRACE("Creating/Opening key %s\n", fullname);
459 v=find_value_by_name(fullname);
463 v=insert_reg_value(key, name, DIR, &qw, 4);
464 if (status) *status=REG_CREATED_NEW_KEY;
468 t=insert_handle(generate_handle(), fullname);
476 HKEY hKey, // handle to key to query
477 DWORD dwIndex, // index of value to query
478 LPTSTR lpValueName, // address of buffer for value string
479 LPDWORD lpcbValueName, // address for size of value buffer
480 LPDWORD lpReserved, // reserved
481 LPDWORD lpType, // address of buffer for type code
482 LPBYTE lpData, // address of buffer for value data
483 LPDWORD lpcbData // address for size of data buffer
487 long __stdcall RegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count,
488 LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count)
490 // currenly just made to support MSZH & ZLIB
491 //printf("Reg Enum 0x%x %d %s %d data: %p %d %d >%s<\n", hkey, index,
492 // value, *val_count, data, *count, reg_size, data);
493 reg_handle_t* t = find_handle(hkey);
496 struct reg_value* v=find_value_by_name(t->name);
499 memcpy(data, v->value, (v->len < *count) ? v->len : *count);
504 //printf("Found handle %s\n", v->name);
508 return ERROR_NO_MORE_ITEMS;
511 long __stdcall RegSetValueExA(long key, const char* name, long v1, long v2, const void* data, long size)
515 TRACE("Request to set value %s %d\n", name, *(const int*)data);
519 c=build_keyname(key, name);
522 insert_reg_value(key, name, v2, data, size);
527 long __stdcall RegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName,
528 LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass,
529 LPFILETIME lpftLastWriteTime)
531 return ERROR_NO_MORE_ITEMS;