2 * Modified for use with MPlayer, detailed changelog at
3 * http://svn.mplayerhq.hu/mplayer/trunk/
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"
27 //#define TRACE printf
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
=malloc(3*sizeof(struct reg_value
));
70 regs
[0].type
=regs
[1].type
=DIR;
71 regs
[0].name
=malloc(5);
72 strcpy(regs
[0].name
, "HKLM");
73 regs
[1].name
=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
=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
=malloc(len
+1);
112 read(fd
, regs
[i
].name
, len
);
114 read(fd
,®s
[i
].len
,4);
115 regs
[i
].value
=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
;
169 for(i
=0; i
<reg_size
; i
++)
178 if (localregpathname
&& localregpathname
!= regpathname
)
179 free(localregpathname
);
180 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
))
198 static struct reg_value
* find_value_by_name(const char* name
)
201 for(i
=0; i
<reg_size
; i
++)
202 if(!strcmp(regs
[i
].name
, name
))
206 static reg_handle_t
* find_handle(int handle
)
209 for(t
=head
; t
; t
=t
->prev
)
211 if(t
->handle
==handle
)
218 static int generate_handle(void)
220 static unsigned int zz
=249;
222 while((zz
==HKEY_LOCAL_MACHINE
) || (zz
==HKEY_CURRENT_USER
))
227 static reg_handle_t
* insert_handle(long handle
, const char* name
)
230 t
=malloc(sizeof(reg_handle_t
));
241 t
->name
=malloc(strlen(name
)+1);
242 strcpy(t
->name
, name
);
247 static char* build_keyname(long key
, const char* subkey
)
251 if((t
=find_handle(key
))==0)
253 TRACE("Invalid key\n");
258 full_name
=malloc(strlen(t
->name
)+strlen(subkey
)+10);
259 strcpy(full_name
, t
->name
);
260 strcat(full_name
, "\\");
261 strcat(full_name
, subkey
);
264 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
= 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
=malloc(len
);
294 memcpy(v
->value
, value
, len
);
295 v
->name
=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
308 regpathname
= get_path("registry");
309 localregpathname
= regpathname
;
312 insert_handle(HKEY_LOCAL_MACHINE
, "HKLM");
313 insert_handle(HKEY_CURRENT_USER
, "HKCU");
317 static reg_handle_t
* find_handle_2(long key
, const char* subkey
)
321 if((t
=find_handle(key
))==0)
323 TRACE("Invalid key\n");
324 return (reg_handle_t
*)-1;
328 full_name
=malloc(strlen(t
->name
)+strlen(subkey
)+10);
329 strcpy(full_name
, t
->name
);
330 strcat(full_name
, "\\");
331 strcat(full_name
, subkey
);
332 t
=find_handle_by_name(full_name
);
338 long __stdcall
RegOpenKeyExA(long key
, const char* subkey
, long reserved
, long access
, int* newkey
)
343 TRACE("Opening key %s\n", subkey
);
348 /* t=find_handle_2(key, subkey);
353 if(t==(reg_handle_t*)-1)
356 full_name
=build_keyname(key
, subkey
);
359 TRACE("Opening key Fullname %s\n", full_name
);
360 v
=find_value_by_name(full_name
);
362 t
=insert_handle(generate_handle(), full_name
);
368 long __stdcall
RegCloseKey(long key
)
370 reg_handle_t
*handle
;
371 if(key
==(long)HKEY_LOCAL_MACHINE
)
373 if(key
==(long)HKEY_CURRENT_USER
)
375 handle
=find_handle(key
);
379 handle
->prev
->next
=handle
->next
;
381 handle
->next
->prev
=handle
->prev
;
389 long __stdcall
RegQueryValueExA(long key
, const char* value
, int* reserved
, int* type
, int* data
, int* count
)
393 TRACE("Querying value %s\n", value
);
397 c
=build_keyname(key
, value
);
400 t
=find_value_by_name(c
);
402 // Hacks for CineForm.
403 if (strcmp(c
, "HKCU\\SOFTWARE\\CineForm\\DecoderProperties\\Resolution") == 0) {
409 *count
= sizeof(DWORD
);
411 return ERROR_SUCCESS
;
413 if (strcmp(c
, "HKCU\\SOFTWARE\\CineForm\\DecoderProperties\\PixelFormats") == 0) {
419 *count
= sizeof(DWORD
);
421 return ERROR_SUCCESS
;
424 return ERROR_FILE_NOT_FOUND
;
431 memcpy(data
, t
->value
, (t
->len
<*count
)?t
->len
:*count
);
432 TRACE("returning %d bytes: %d\n", t
->len
, *(int*)data
);
437 return ERROR_MORE_DATA
;
443 return ERROR_SUCCESS
;
445 long __stdcall
RegCreateKeyExA(long key
, const char* name
, long reserved
,
446 void* classs
, long options
, long security
,
447 void* sec_attr
, int* newkey
, int* status
)
452 // TRACE("Creating/Opening key %s\n", name);
456 fullname
=build_keyname(key
, name
);
459 TRACE("Creating/Opening key %s\n", fullname
);
460 v
=find_value_by_name(fullname
);
464 v
=insert_reg_value(key
, name
, DIR, &qw
, 4);
465 if (status
) *status
=REG_CREATED_NEW_KEY
;
469 t
=insert_handle(generate_handle(), fullname
);
477 HKEY hKey, // handle to key to query
478 DWORD dwIndex, // index of value to query
479 LPTSTR lpValueName, // address of buffer for value string
480 LPDWORD lpcbValueName, // address for size of value buffer
481 LPDWORD lpReserved, // reserved
482 LPDWORD lpType, // address of buffer for type code
483 LPBYTE lpData, // address of buffer for value data
484 LPDWORD lpcbData // address for size of data buffer
488 long __stdcall
RegEnumValueA(HKEY hkey
, DWORD index
, LPSTR value
, LPDWORD val_count
,
489 LPDWORD reserved
, LPDWORD type
, LPBYTE data
, LPDWORD count
)
491 // currenly just made to support MSZH & ZLIB
492 //printf("Reg Enum 0x%x %d %s %d data: %p %d %d >%s<\n", hkey, index,
493 // value, *val_count, data, *count, reg_size, data);
494 reg_handle_t
* t
= find_handle(hkey
);
497 struct reg_value
* v
=find_value_by_name(t
->name
);
500 memcpy(data
, v
->value
, (v
->len
< *count
) ? v
->len
: *count
);
505 //printf("Found handle %s\n", v->name);
509 return ERROR_NO_MORE_ITEMS
;
512 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
;