convert some printfs to mp_msg
[mplayer/glamo.git] / loader / registry.c
blob6946f85ba6d074c70aae2e8e2cc38c17e3ab5297
1 /*
2 * Modified for use with MPlayer, detailed CVS changelog at
3 * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
4 * $Id$
5 */
7 #include "config.h"
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <fcntl.h>
12 #include <unistd.h>
13 #include <pwd.h>
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"
21 #include "ext.h"
22 #include "registry.h"
24 //#undef TRACE
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
36 int handle;
37 char* name;
38 struct reg_handle_s* next;
39 struct reg_handle_s* prev;
40 } reg_handle_t;
42 struct reg_value
44 int type;
45 char* name;
46 int len;
47 char* value;
50 static struct reg_value* regs = NULL;
51 static int reg_size;
52 static reg_handle_t* head = NULL;
54 #define DIR -25
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){
63 if(regs)
65 printf("Logic error: create_registry() called with existing registry\n");
66 save_registry();
67 return;
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;
77 reg_size=2;
78 head = 0;
79 save_registry();
82 static void open_registry(void)
84 int fd;
85 int i;
86 unsigned int len;
87 if(regs)
89 printf("Multiple open_registry(>\n");
90 return;
92 fd = open(localregpathname, O_RDONLY);
93 if (fd == -1)
95 printf("Creating new registry\n");
96 create_registry();
97 return;
99 read(fd, &reg_size, 4);
100 regs=(struct reg_value*)malloc(reg_size*sizeof(struct reg_value));
101 head = 0;
102 for(i=0; i<reg_size; i++)
104 read(fd,&regs[i].type,4);
105 read(fd,&len,4);
106 regs[i].name=(char*)malloc(len+1);
107 if(regs[i].name==0)
109 reg_size=i+1;
110 goto error;
112 read(fd, regs[i].name, len);
113 regs[i].name[len]=0;
114 read(fd,&regs[i].len,4);
115 regs[i].value=(char*)malloc(regs[i].len+1);
116 if(regs[i].value==0)
118 free(regs[i].name);
119 reg_size=i+1;
120 goto error;
122 read(fd, regs[i].value, regs[i].len);
123 regs[i].value[regs[i].len]=0;
125 error:
126 close(fd);
127 return;
130 static void save_registry(void)
132 int fd, i;
133 if (!regs)
134 init_registry();
135 fd = open(localregpathname, O_WRONLY | O_CREAT, 00666);
136 if (fd == -1)
138 printf("Failed to open registry file '%s' for writing.\n",
139 localregpathname);
140 return;
142 write(fd, &reg_size, 4);
143 for(i=0; i<reg_size; i++)
145 unsigned len=strlen(regs[i].name);
146 write(fd, &regs[i].type, 4);
147 write(fd, &len, 4);
148 write(fd, regs[i].name, len);
149 write(fd, &regs[i].len, 4);
150 write(fd, regs[i].value, regs[i].len);
152 close(fd);
155 void free_registry(void)
157 reg_handle_t* t = head;
158 while (t)
160 reg_handle_t* f = t;
161 if (t->name)
162 free(t->name);
163 t=t->prev;
164 free(f);
166 head = 0;
167 if (regs)
169 int i;
170 for(i=0; i<reg_size; i++)
172 free(regs[i].name);
173 free(regs[i].value);
175 free(regs);
176 regs = 0;
179 if (localregpathname && localregpathname != regpathname)
180 free(localregpathname);
181 localregpathname = 0;
185 static reg_handle_t* find_handle_by_name(const char* name)
187 reg_handle_t* t;
188 for(t=head; t; t=t->prev)
190 if(!strcmp(t->name, name))
192 return t;
195 return 0;
197 static struct reg_value* find_value_by_name(const char* name)
199 int i;
200 for(i=0; i<reg_size; i++)
201 if(!strcmp(regs[i].name, name))
202 return regs+i;
203 return 0;
205 static reg_handle_t* find_handle(int handle)
207 reg_handle_t* t;
208 for(t=head; t; t=t->prev)
210 if(t->handle==handle)
212 return t;
215 return 0;
217 static int generate_handle()
219 static unsigned int zz=249;
220 zz++;
221 while((zz==HKEY_LOCAL_MACHINE) || (zz==HKEY_CURRENT_USER))
222 zz++;
223 return zz;
226 static reg_handle_t* insert_handle(long handle, const char* name)
228 reg_handle_t* t;
229 t=(reg_handle_t*)malloc(sizeof(reg_handle_t));
230 if(head==0)
232 t->prev=0;
234 else
236 head->next=t;
237 t->prev=head;
239 t->next=0;
240 t->name=(char*)malloc(strlen(name)+1);
241 strcpy(t->name, name);
242 t->handle=handle;
243 head=t;
244 return t;
246 static char* build_keyname(long key, const char* subkey)
248 char* full_name;
249 reg_handle_t* t;
250 if((t=find_handle(key))==0)
252 TRACE("Invalid key\n");
253 return NULL;
255 if(subkey==NULL)
256 subkey="<default>";
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);
261 return full_name;
263 static struct reg_value* insert_reg_value(int handle, const char* name, int type, const void* value, int len)
265 reg_handle_t* t;
266 struct reg_value* v;
267 char* fullname;
268 if((fullname=build_keyname(handle, name))==NULL)
270 TRACE("Invalid handle\n");
271 return NULL;
274 if((v=find_value_by_name(fullname))==0)
275 //creating new value in registry
277 if(regs==0)
278 create_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));
281 v=regs+reg_size;
282 reg_size++;
284 else
285 //replacing old one
287 free(v->value);
288 free(v->name);
290 TRACE("RegInsert '%s' %p v:%d len:%d\n", name, value, *(int*)value, len);
291 v->type=type;
292 v->len=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);
297 free(fullname);
298 save_registry();
299 return v;
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 #ifdef MPLAYER
309 regpathname = get_path("registry");
310 localregpathname = regpathname;
311 #else
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;
320 if (!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");
332 #endif
334 open_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)
341 char* full_name;
342 reg_handle_t* t;
343 if((t=find_handle(key))==0)
345 TRACE("Invalid key\n");
346 return (reg_handle_t*)-1;
348 if(subkey==NULL)
349 return t;
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);
355 free(full_name);
356 return t;
359 long __stdcall RegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
361 char* full_name;
362 reg_handle_t* t;
363 struct reg_value* v;
364 TRACE("Opening key %s\n", subkey);
366 if(!regs)
367 init_registry()
369 /* t=find_handle_2(key, subkey);
371 if(t==0)
372 return -1;
374 if(t==(reg_handle_t*)-1)
375 return -1;
377 full_name=build_keyname(key, subkey);
378 if(!full_name)
379 return -1;
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);
384 *newkey=t->handle;
385 free(full_name);
387 return 0;
389 long __stdcall RegCloseKey(long key)
391 reg_handle_t *handle;
392 if(key==(long)HKEY_LOCAL_MACHINE)
393 return 0;
394 if(key==(long)HKEY_CURRENT_USER)
395 return 0;
396 handle=find_handle(key);
397 if(handle==0)
398 return 0;
399 if(handle->prev)
400 handle->prev->next=handle->next;
401 if(handle->next)
402 handle->next->prev=handle->prev;
403 if(handle->name)
404 free(handle->name);
405 if(handle==head)
406 head=head->prev;
407 free(handle);
408 return 1;
411 long __stdcall RegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count)
413 struct reg_value* t;
414 char* c;
415 TRACE("Querying value %s\n", value);
416 if(!regs)
417 init_registry();
419 c=build_keyname(key, value);
420 if (!c)
421 return 1;
422 t=find_value_by_name(c);
423 free(c);
424 if (t==0)
425 return 2;
426 if (type)
427 *type=t->type;
428 if (data)
430 memcpy(data, t->value, (t->len<*count)?t->len:*count);
431 TRACE("returning %d bytes: %d\n", t->len, *(int*)data);
433 if(*count<t->len)
435 *count=t->len;
436 return ERROR_MORE_DATA;
438 else
440 *count=t->len;
442 return 0;
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)
448 reg_handle_t* t;
449 char* fullname;
450 struct reg_value* v;
451 // TRACE("Creating/Opening key %s\n", name);
452 if(!regs)
453 init_registry();
455 fullname=build_keyname(key, name);
456 if (!fullname)
457 return 1;
458 TRACE("Creating/Opening key %s\n", fullname);
459 v=find_value_by_name(fullname);
460 if(v==0)
462 int qw=45708;
463 v=insert_reg_value(key, name, DIR, &qw, 4);
464 if (status) *status=REG_CREATED_NEW_KEY;
465 // return 0;
468 t=insert_handle(generate_handle(), fullname);
469 *newkey=t->handle;
470 free(fullname);
471 return 0;
475 LONG RegEnumValue(
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);
494 if (t && index < 10)
496 struct reg_value* v=find_value_by_name(t->name);
497 if (v)
499 memcpy(data, v->value, (v->len < *count) ? v->len : *count);
500 if(*count < v->len)
501 *count = v->len;
502 if (type)
503 *type = v->type;
504 //printf("Found handle %s\n", v->name);
505 return 0;
508 return ERROR_NO_MORE_ITEMS;
511 long __stdcall RegSetValueExA(long key, const char* name, long v1, long v2, const void* data, long size)
513 struct reg_value* t;
514 char* c;
515 TRACE("Request to set value %s %d\n", name, *(const int*)data);
516 if(!regs)
517 init_registry();
519 c=build_keyname(key, name);
520 if(c==NULL)
521 return 1;
522 insert_reg_value(key, name, v2, data, size);
523 free(c);
524 return 0;
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;