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
;