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);
128 if(regs
[i
].name
==NULL
)
133 read(fd
, regs
[i
].name
, len
);
135 read(fd
,®s
[i
].len
,4);
136 regs
[i
].value
=(char*)malloc(regs
[i
].len
+1);
137 if(regs
[i
].value
==NULL
)
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
;
190 for(i
=0; i
<reg_size
; i
++)
199 if (localregpathname
!= regpathname
)
200 free(localregpathname
);
201 localregpathname
= 0;
205 static reg_handle_t
* find_handle_by_name(const char* name
)
208 for(t
=head
; t
; t
=t
->prev
)
210 if(!strcmp(t
->name
, name
))
217 static struct reg_value
* find_value_by_name(const char* name
)
220 for(i
=0; i
<reg_size
; i
++)
221 if(!strcmp(regs
[i
].name
, name
))
225 static reg_handle_t
* find_handle(int handle
)
228 for(t
=head
; t
; t
=t
->prev
)
230 if(t
->handle
==handle
)
237 static int generate_handle()
239 static unsigned int zz
=249;
241 while((zz
==HKEY_LOCAL_MACHINE
) || (zz
==HKEY_CURRENT_USER
))
246 static reg_handle_t
* insert_handle(long handle
, const char* name
)
249 t
=(reg_handle_t
*)malloc(sizeof(reg_handle_t
));
260 t
->name
=(char*)malloc(strlen(name
)+1);
261 strcpy(t
->name
, name
);
266 static char* build_keyname(long key
, const char* subkey
)
270 if((t
=find_handle(key
))==NULL
)
272 TRACE("Invalid key\n");
277 full_name
=(char*)malloc(strlen(t
->name
)+strlen(subkey
)+10);
278 strcpy(full_name
, t
->name
);
279 strcat(full_name
, "\\");
280 strcat(full_name
, subkey
);
283 static struct reg_value
* insert_reg_value(int handle
, const char* name
, int type
, const void* value
, int len
)
288 if((fullname
=build_keyname(handle
, name
))==NULL
)
290 TRACE("Invalid handle\n");
294 if((v
=find_value_by_name(fullname
))==NULL
)
295 //creating new value in registry
299 regs
=(struct reg_value
*)realloc(regs
, sizeof(struct reg_value
)*(reg_size
+1));
300 //regs=(struct reg_value*)my_realloc(regs, sizeof(struct reg_value)*(reg_size+1));
310 TRACE("RegInsert '%s' %p v:%d len:%d\n", name
, value
, *(int*)value
, len
);
313 v
->value
=(char*)malloc(len
);
314 memcpy(v
->value
, value
, len
);
315 v
->name
=(char*)malloc(strlen(fullname
)+1);
316 strcpy(v
->name
, fullname
);
322 static void init_registry(void)
324 TRACE("Initializing registry\n");
325 // can't be free-ed - it's static and probably thread
326 // unsafe structure which is stored in glibc
329 regpathname
= get_path("registry");
330 localregpathname
= regpathname
;
332 // regpathname is an external pointer
334 // registry.c is holding its own internal pointer
335 // localregpathname - which is being allocate/deallocated
337 if (localregpathname
== NULL
)
339 const char* pthn
= regpathname
;
342 // avifile - for now reading data from user's home
343 struct passwd
* pwent
;
344 pwent
= getpwuid(geteuid());
345 pthn
= pwent
->pw_dir
;
348 localregpathname
= (char*)malloc(strlen(pthn
)+20);
349 strcpy(localregpathname
, pthn
);
350 strcat(localregpathname
, "/.registry");
355 insert_handle(HKEY_LOCAL_MACHINE
, "HKLM");
356 insert_handle(HKEY_CURRENT_USER
, "HKCU");
359 static reg_handle_t
* find_handle_2(long key
, const char* subkey
)
363 if((t
=find_handle(key
))==NULL
)
365 TRACE("Invalid key\n");
366 return (reg_handle_t
*)-1;
370 full_name
=(char*)malloc(strlen(t
->name
)+strlen(subkey
)+10);
371 strcpy(full_name
, t
->name
);
372 strcat(full_name
, "\\");
373 strcat(full_name
, subkey
);
374 t
=find_handle_by_name(full_name
);
379 long __stdcall
RegOpenKeyExA(long key
, const char* subkey
, long reserved
, long access
, int* newkey
)
384 TRACE("Opening key %s\n", subkey
);
389 /* t=find_handle_2(key, subkey);
394 if(t==(reg_handle_t*)-1)
397 full_name
=build_keyname(key
, subkey
);
400 TRACE("Opening key Fullname %s\n", full_name
);
401 v
=find_value_by_name(full_name
);
403 t
=insert_handle(generate_handle(), full_name
);
409 long __stdcall
RegCloseKey(long key
)
411 reg_handle_t
*handle
;
412 if(key
==(long)HKEY_LOCAL_MACHINE
)
414 if(key
==(long)HKEY_CURRENT_USER
)
416 handle
=find_handle(key
);
420 handle
->prev
->next
=handle
->next
;
422 handle
->next
->prev
=handle
->prev
;
430 long __stdcall
RegQueryValueExA(long key
, const char* value
, int* reserved
, int* type
, int* data
, int* count
)
434 TRACE("Querying value %s\n", value
);
438 c
=build_keyname(key
, value
);
441 t
=find_value_by_name(c
);
449 memcpy(data
, t
->value
, (t
->len
<*count
)?t
->len
:*count
);
450 TRACE("returning %d bytes: %d\n", t
->len
, *(int*)data
);
455 return ERROR_MORE_DATA
;
463 long __stdcall
RegCreateKeyExA(long key
, const char* name
, long reserved
,
464 void* classs
, long options
, long security
,
465 void* sec_attr
, int* newkey
, int* status
)
470 // TRACE("Creating/Opening key %s\n", name);
474 fullname
=build_keyname(key
, name
);
477 TRACE("Creating/Opening key %s\n", fullname
);
478 v
=find_value_by_name(fullname
);
482 v
=insert_reg_value(key
, name
, DIR, &qw
, 4);
483 if (status
) *status
=REG_CREATED_NEW_KEY
;
487 t
=insert_handle(generate_handle(), fullname
);
495 HKEY hKey, // handle to key to query
496 DWORD dwIndex, // index of value to query
497 LPTSTR lpValueName, // address of buffer for value string
498 LPDWORD lpcbValueName, // address for size of value buffer
499 LPDWORD lpReserved, // reserved
500 LPDWORD lpType, // address of buffer for type code
501 LPBYTE lpData, // address of buffer for value data
502 LPDWORD lpcbData // address for size of data buffer
506 long __stdcall
RegEnumValueA(HKEY hkey
, DWORD index
, LPSTR value
, LPDWORD val_count
,
507 LPDWORD reserved
, LPDWORD type
, LPBYTE data
, LPDWORD count
)
509 // currenly just made to support MSZH & ZLIB
510 //printf("Reg Enum 0x%x %d %s %d data: %p %d %d >%s<\n", hkey, index,
511 // value, *val_count, data, *count, reg_size, data);
512 reg_handle_t
* t
= find_handle(hkey
);
515 struct reg_value
* v
=find_value_by_name(t
->name
);
518 memcpy(data
, v
->value
, (v
->len
< *count
) ? v
->len
: *count
);
523 //printf("Found handle %s\n", v->name);
527 return ERROR_NO_MORE_ITEMS
;
530 long __stdcall
RegSetValueExA(long key
, const char* name
, long v1
, long v2
, const void* data
, long size
)
534 TRACE("Request to set value %s %d\n", name
, *(const int*)data
);
538 c
=build_keyname(key
, name
);
541 insert_reg_value(key
, name
, v2
, data
, size
);
546 long __stdcall
RegEnumKeyExA(HKEY hKey
, DWORD dwIndex
, LPSTR lpName
, LPDWORD lpcbName
,
547 LPDWORD lpReserved
, LPSTR lpClass
, LPDWORD lpcbClass
,
548 LPFILETIME lpftLastWriteTime
)
550 return ERROR_NO_MORE_ITEMS
;