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
;
170 for(i
=0; i
<reg_size
; i
++)
179 if (localregpathname
&& localregpathname
!= regpathname
)
180 free(localregpathname
);
181 localregpathname
= 0;
186 static reg_handle_t
* find_handle_by_name(const char* name
)
189 for(t
=head
; t
; t
=t
->prev
)
191 if(!strcmp(t
->name
, name
))
199 static struct reg_value
* find_value_by_name(const char* name
)
202 for(i
=0; i
<reg_size
; i
++)
203 if(!strcmp(regs
[i
].name
, name
))
207 static reg_handle_t
* find_handle(int handle
)
210 for(t
=head
; t
; t
=t
->prev
)
212 if(t
->handle
==handle
)
219 static int generate_handle(void)
221 static unsigned int zz
=249;
223 while((zz
==HKEY_LOCAL_MACHINE
) || (zz
==HKEY_CURRENT_USER
))
228 static reg_handle_t
* insert_handle(long handle
, const char* name
)
231 t
=malloc(sizeof(reg_handle_t
));
242 t
->name
=malloc(strlen(name
)+1);
243 strcpy(t
->name
, name
);
248 static char* build_keyname(long key
, const char* subkey
)
252 if((t
=find_handle(key
))==0)
254 TRACE("Invalid key\n");
259 full_name
=malloc(strlen(t
->name
)+strlen(subkey
)+10);
260 strcpy(full_name
, t
->name
);
261 strcat(full_name
, "\\");
262 strcat(full_name
, subkey
);
265 static struct reg_value
* insert_reg_value(int handle
, const char* name
, int type
, const void* value
, int len
)
269 if((fullname
=build_keyname(handle
, name
))==NULL
)
271 TRACE("Invalid handle\n");
275 if((v
=find_value_by_name(fullname
))==0)
276 //creating new value in registry
280 regs
= realloc(regs
, sizeof(struct reg_value
) * (reg_size
+1 ));
281 //regs=(struct reg_value*)my_realloc(regs, sizeof(struct reg_value)*(reg_size+1));
291 TRACE("RegInsert '%s' %p v:%d len:%d\n", name
, value
, *(int*)value
, len
);
294 v
->value
=malloc(len
);
295 memcpy(v
->value
, value
, len
);
296 v
->name
=malloc(strlen(fullname
)+1);
297 strcpy(v
->name
, fullname
);
303 static void init_registry(void)
305 TRACE("Initializing registry\n");
306 // can't be free-ed - it's static and probably thread
307 // unsafe structure which is stored in glibc
309 regpathname
= get_path("registry");
310 localregpathname
= regpathname
;
313 insert_handle(HKEY_LOCAL_MACHINE
, "HKLM");
314 insert_handle(HKEY_CURRENT_USER
, "HKCU");
318 static reg_handle_t
* find_handle_2(long key
, const char* subkey
)
322 if((t
=find_handle(key
))==0)
324 TRACE("Invalid key\n");
325 return (reg_handle_t
*)-1;
329 full_name
=malloc(strlen(t
->name
)+strlen(subkey
)+10);
330 strcpy(full_name
, t
->name
);
331 strcat(full_name
, "\\");
332 strcat(full_name
, subkey
);
333 t
=find_handle_by_name(full_name
);
339 long __stdcall
RegOpenKeyExA(long key
, const char* subkey
, long reserved
, long access
, int* newkey
)
344 TRACE("Opening key %s\n", subkey
);
349 /* t=find_handle_2(key, subkey);
354 if(t==(reg_handle_t*)-1)
357 full_name
=build_keyname(key
, subkey
);
360 TRACE("Opening key Fullname %s\n", full_name
);
361 v
=find_value_by_name(full_name
);
363 t
=insert_handle(generate_handle(), full_name
);
369 long __stdcall
RegCloseKey(long key
)
371 reg_handle_t
*handle
;
372 if(key
==(long)HKEY_LOCAL_MACHINE
)
374 if(key
==(long)HKEY_CURRENT_USER
)
376 handle
=find_handle(key
);
380 handle
->prev
->next
=handle
->next
;
382 handle
->next
->prev
=handle
->prev
;
391 long __stdcall
RegQueryValueExA(long key
, const char* value
, int* reserved
, int* type
, int* data
, int* count
)
395 TRACE("Querying value %s\n", value
);
399 c
=build_keyname(key
, value
);
402 t
=find_value_by_name(c
);
404 // Hacks for CineForm.
405 if (strcmp(c
, "HKCU\\SOFTWARE\\CineForm\\DecoderProperties\\Resolution") == 0) {
411 *count
= sizeof(DWORD
);
413 return ERROR_SUCCESS
;
415 if (strcmp(c
, "HKCU\\SOFTWARE\\CineForm\\DecoderProperties\\PixelFormats") == 0) {
421 *count
= sizeof(DWORD
);
423 return ERROR_SUCCESS
;
426 return ERROR_FILE_NOT_FOUND
;
433 memcpy(data
, t
->value
, (t
->len
<*count
)?t
->len
:*count
);
434 TRACE("returning %d bytes: %d\n", t
->len
, *(int*)data
);
439 return ERROR_MORE_DATA
;
445 return ERROR_SUCCESS
;
447 long __stdcall
RegCreateKeyExA(long key
, const char* name
, long reserved
,
448 void* classs
, long options
, long security
,
449 void* sec_attr
, int* newkey
, int* status
)
454 // TRACE("Creating/Opening key %s\n", name);
458 fullname
=build_keyname(key
, name
);
461 TRACE("Creating/Opening key %s\n", fullname
);
462 v
=find_value_by_name(fullname
);
466 v
=insert_reg_value(key
, name
, DIR, &qw
, 4);
467 if (status
) *status
=REG_CREATED_NEW_KEY
;
471 t
=insert_handle(generate_handle(), fullname
);
479 HKEY hKey, // handle to key to query
480 DWORD dwIndex, // index of value to query
481 LPTSTR lpValueName, // address of buffer for value string
482 LPDWORD lpcbValueName, // address for size of value buffer
483 LPDWORD lpReserved, // reserved
484 LPDWORD lpType, // address of buffer for type code
485 LPBYTE lpData, // address of buffer for value data
486 LPDWORD lpcbData // address for size of data buffer
490 long __stdcall
RegEnumValueA(HKEY hkey
, DWORD index
, LPSTR value
, LPDWORD val_count
,
491 LPDWORD reserved
, LPDWORD type
, LPBYTE data
, LPDWORD count
)
493 // currenly just made to support MSZH & ZLIB
494 //printf("Reg Enum 0x%x %d %s %d data: %p %d %d >%s<\n", hkey, index,
495 // value, *val_count, data, *count, reg_size, data);
496 reg_handle_t
* t
= find_handle(hkey
);
499 struct reg_value
* v
=find_value_by_name(t
->name
);
502 memcpy(data
, v
->value
, (v
->len
< *count
) ? v
->len
: *count
);
507 //printf("Found handle %s\n", v->name);
511 return ERROR_NO_MORE_ITEMS
;
514 long __stdcall
RegSetValueExA(long key
, const char* name
, long v1
, long v2
, const void* data
, long size
)
517 TRACE("Request to set value %s %d\n", name
, *(const int*)data
);
521 c
=build_keyname(key
, name
);
524 insert_reg_value(key
, name
, v2
, data
, size
);
529 long __stdcall
RegEnumKeyExA(HKEY hKey
, DWORD dwIndex
, LPSTR lpName
, LPDWORD lpcbName
,
530 LPDWORD lpReserved
, LPSTR lpClass
, LPDWORD lpcbClass
,
531 LPFILETIME lpftLastWriteTime
)
533 return ERROR_NO_MORE_ITEMS
;