Second attempt to fix compilation of dvdread (I don't really like this but it might...
[vlc/asuraparaju-public.git] / libs / loader / registry.c
blob5bc802ff84d51169df6508f41d2df50d7efef27f
1 /*
2 * $Id$
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.
28 #include "config.h"
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <fcntl.h>
33 #include <unistd.h>
34 #include <pwd.h>
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"
42 #include "ext.h"
43 #include "registry.h"
45 //#undef TRACE
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
57 int handle;
58 char* name;
59 struct reg_handle_s* next;
60 struct reg_handle_s* prev;
61 } reg_handle_t;
63 struct reg_value
65 int type;
66 char* name;
67 int len;
68 char* value;
71 static struct reg_value* regs = NULL;
72 static int reg_size;
73 static reg_handle_t* head = NULL;
75 #define DIR -25
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){
84 if(regs)
86 printf("Logic error: create_registry() called with existing registry\n");
87 save_registry();
88 return;
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;
98 reg_size=2;
99 head = 0;
100 save_registry();
103 static void open_registry(void)
105 int fd;
106 int i;
107 unsigned int len;
108 if(regs)
110 printf("Multiple open_registry(>\n");
111 return;
113 fd = open(localregpathname, O_RDONLY);
114 if (fd == -1)
116 printf("Creating new registry\n");
117 create_registry();
118 return;
120 read(fd, &reg_size, 4);
121 regs=(struct reg_value*)malloc(reg_size*sizeof(struct reg_value));
122 head = 0;
123 for(i=0; i<reg_size; i++)
125 read(fd,&regs[i].type,4);
126 read(fd,&len,4);
127 regs[i].name=(char*)malloc(len+1);
128 if(regs[i].name==NULL)
130 reg_size=i+1;
131 goto error;
133 read(fd, regs[i].name, len);
134 regs[i].name[len]=0;
135 read(fd,&regs[i].len,4);
136 regs[i].value=(char*)malloc(regs[i].len+1);
137 if(regs[i].value==NULL)
139 free(regs[i].name);
140 reg_size=i+1;
141 goto error;
143 read(fd, regs[i].value, regs[i].len);
144 regs[i].value[regs[i].len]=0;
146 error:
147 close(fd);
148 return;
151 static void save_registry(void)
153 int fd, i;
154 if (!regs)
155 init_registry();
156 fd = open(localregpathname, O_WRONLY | O_CREAT, 00666);
157 if (fd == -1)
159 printf("Failed to open registry file '%s' for writing.\n",
160 localregpathname);
161 return;
163 write(fd, &reg_size, 4);
164 for(i=0; i<reg_size; i++)
166 unsigned len=strlen(regs[i].name);
167 write(fd, &regs[i].type, 4);
168 write(fd, &len, 4);
169 write(fd, regs[i].name, len);
170 write(fd, &regs[i].len, 4);
171 write(fd, regs[i].value, regs[i].len);
173 close(fd);
176 void free_registry(void)
178 reg_handle_t* t = head;
179 while (t)
181 reg_handle_t* f = t;
182 free(t->name);
183 t=t->prev;
184 free(f);
186 head = 0;
187 if (regs)
189 int i;
190 for(i=0; i<reg_size; i++)
192 free(regs[i].name);
193 free(regs[i].value);
195 free(regs);
196 regs = 0;
199 if (localregpathname != regpathname)
200 free(localregpathname);
201 localregpathname = 0;
205 static reg_handle_t* find_handle_by_name(const char* name)
207 reg_handle_t* t;
208 for(t=head; t; t=t->prev)
210 if(!strcmp(t->name, name))
212 return t;
215 return 0;
217 static struct reg_value* find_value_by_name(const char* name)
219 int i;
220 for(i=0; i<reg_size; i++)
221 if(!strcmp(regs[i].name, name))
222 return regs+i;
223 return 0;
225 static reg_handle_t* find_handle(int handle)
227 reg_handle_t* t;
228 for(t=head; t; t=t->prev)
230 if(t->handle==handle)
232 return t;
235 return 0;
237 static int generate_handle()
239 static unsigned int zz=249;
240 zz++;
241 while((zz==HKEY_LOCAL_MACHINE) || (zz==HKEY_CURRENT_USER))
242 zz++;
243 return zz;
246 static reg_handle_t* insert_handle(long handle, const char* name)
248 reg_handle_t* t;
249 t=(reg_handle_t*)malloc(sizeof(reg_handle_t));
250 if(head==NULL)
252 t->prev=0;
254 else
256 head->next=t;
257 t->prev=head;
259 t->next=0;
260 t->name=(char*)malloc(strlen(name)+1);
261 strcpy(t->name, name);
262 t->handle=handle;
263 head=t;
264 return t;
266 static char* build_keyname(long key, const char* subkey)
268 char* full_name;
269 reg_handle_t* t;
270 if((t=find_handle(key))==NULL)
272 TRACE("Invalid key\n");
273 return NULL;
275 if(subkey==NULL)
276 subkey="<default>";
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);
281 return full_name;
283 static struct reg_value* insert_reg_value(int handle, const char* name, int type, const void* value, int len)
285 reg_handle_t* t;
286 struct reg_value* v;
287 char* fullname;
288 if((fullname=build_keyname(handle, name))==NULL)
290 TRACE("Invalid handle\n");
291 return NULL;
294 if((v=find_value_by_name(fullname))==NULL)
295 //creating new value in registry
297 if(regs==NULL)
298 create_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));
301 v=regs+reg_size;
302 reg_size++;
304 else
305 //replacing old one
307 free(v->value);
308 free(v->name);
310 TRACE("RegInsert '%s' %p v:%d len:%d\n", name, value, *(int*)value, len);
311 v->type=type;
312 v->len=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);
317 free(fullname);
318 save_registry();
319 return v;
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
328 #ifdef MPLAYER
329 regpathname = get_path("registry");
330 localregpathname = regpathname;
331 #else
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;
340 if (!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");
352 #endif
354 open_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)
361 char* full_name;
362 reg_handle_t* t;
363 if((t=find_handle(key))==NULL)
365 TRACE("Invalid key\n");
366 return (reg_handle_t*)-1;
368 if(subkey==NULL)
369 return t;
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);
375 free(full_name);
376 return t;
379 long __stdcall RegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
381 char* full_name;
382 reg_handle_t* t;
383 struct reg_value* v;
384 TRACE("Opening key %s\n", subkey);
386 if(!regs)
387 init_registry()
389 /* t=find_handle_2(key, subkey);
391 if(t==0)
392 return -1;
394 if(t==(reg_handle_t*)-1)
395 return -1;
397 full_name=build_keyname(key, subkey);
398 if(!full_name)
399 return -1;
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);
404 *newkey=t->handle;
405 free(full_name);
407 return 0;
409 long __stdcall RegCloseKey(long key)
411 reg_handle_t *handle;
412 if(key==(long)HKEY_LOCAL_MACHINE)
413 return 0;
414 if(key==(long)HKEY_CURRENT_USER)
415 return 0;
416 handle=find_handle(key);
417 if(handle==NULL)
418 return 0;
419 if(handle->prev)
420 handle->prev->next=handle->next;
421 if(handle->next)
422 handle->next->prev=handle->prev;
423 free(handle->name);
424 if(handle==head)
425 head=head->prev;
426 free(handle);
427 return 1;
430 long __stdcall RegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count)
432 struct reg_value* t;
433 char* c;
434 TRACE("Querying value %s\n", value);
435 if(!regs)
436 init_registry();
438 c=build_keyname(key, value);
439 if (!c)
440 return 1;
441 t=find_value_by_name(c);
442 free(c);
443 if (t==NULL)
444 return 2;
445 if (type)
446 *type=t->type;
447 if (data)
449 memcpy(data, t->value, (t->len<*count)?t->len:*count);
450 TRACE("returning %d bytes: %d\n", t->len, *(int*)data);
452 if(*count<t->len)
454 *count=t->len;
455 return ERROR_MORE_DATA;
457 else
459 *count=t->len;
461 return 0;
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)
467 reg_handle_t* t;
468 char* fullname;
469 struct reg_value* v;
470 // TRACE("Creating/Opening key %s\n", name);
471 if(!regs)
472 init_registry();
474 fullname=build_keyname(key, name);
475 if (!fullname)
476 return 1;
477 TRACE("Creating/Opening key %s\n", fullname);
478 v=find_value_by_name(fullname);
479 if(v==NULL)
481 int qw=45708;
482 v=insert_reg_value(key, name, DIR, &qw, 4);
483 if (status) *status=REG_CREATED_NEW_KEY;
484 // return 0;
487 t=insert_handle(generate_handle(), fullname);
488 *newkey=t->handle;
489 free(fullname);
490 return 0;
494 LONG RegEnumValue(
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);
513 if (t && index < 10)
515 struct reg_value* v=find_value_by_name(t->name);
516 if (v)
518 memcpy(data, v->value, (v->len < *count) ? v->len : *count);
519 if(*count < v->len)
520 *count = v->len;
521 if (type)
522 *type = v->type;
523 //printf("Found handle %s\n", v->name);
524 return 0;
527 return ERROR_NO_MORE_ITEMS;
530 long __stdcall RegSetValueExA(long key, const char* name, long v1, long v2, const void* data, long size)
532 struct reg_value* t;
533 char* c;
534 TRACE("Request to set value %s %d\n", name, *(const int*)data);
535 if(!regs)
536 init_registry();
538 c=build_keyname(key, name);
539 if(c==NULL)
540 return 1;
541 insert_reg_value(key, name, v2, data, size);
542 free(c);
543 return 0;
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;