Mercurial > mplayer.hg
annotate loader/registry.c @ 25836:bc425ba00960
added code to check and handle the presence of LATM streams in the init() and decode() functions
author | nicodvb |
---|---|
date | Sat, 26 Jan 2008 18:45:11 +0000 |
parents | 3cd1d60e7225 |
children | b70f5ac9c001 |
rev | line source |
---|---|
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9965
diff
changeset
|
1 /* |
18783 | 2 * Modified for use with MPlayer, detailed changelog at |
3 * http://svn.mplayerhq.hu/mplayer/trunk/ | |
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9965
diff
changeset
|
4 * $Id$ |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9965
diff
changeset
|
5 */ |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9965
diff
changeset
|
6 |
3465 | 7 #include "config.h" |
21261
a2e02e6b6379
Rename config.h --> debug.h and include config.h explicitly.
diego
parents:
18889
diff
changeset
|
8 #include "debug.h" |
1 | 9 |
10 #include <stdio.h> | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
11 #include <stdlib.h> |
1 | 12 #include <fcntl.h> |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
13 #include <unistd.h> |
1 | 14 #include <pwd.h> |
15 #include <sys/types.h> | |
16 | |
7386 | 17 #include "wine/winbase.h" |
18 #include "wine/winreg.h" | |
19 #include "wine/winnt.h" | |
20 #include "wine/winerror.h" | |
1 | 21 |
3465 | 22 #include "ext.h" |
23 #include "registry.h" | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
24 |
128 | 25 //#undef TRACE |
26 //#define TRACE printf | |
3128 | 27 |
18889
e60c8c7399d2
get_path as const, patch by Stefan Huehner, stefan AT huehner-org
reynaldo
parents:
18878
diff
changeset
|
28 extern char *get_path ( const char * ); |
3134 | 29 |
4384 | 30 // ...can be set before init_registry() call |
31 char* regpathname = NULL; | |
3134 | 32 |
4384 | 33 static char* localregpathname = NULL; |
3134 | 34 |
35 typedef struct reg_handle_s | |
36 { | |
37 int handle; | |
38 char* name; | |
39 struct reg_handle_s* next; | |
40 struct reg_handle_s* prev; | |
41 } reg_handle_t; | |
42 | |
1 | 43 struct reg_value |
44 { | |
45 int type; | |
46 char* name; | |
47 int len; | |
48 char* value; | |
49 }; | |
50 | |
3134 | 51 static struct reg_value* regs = NULL; |
52 static int reg_size; | |
53 static reg_handle_t* head = NULL; | |
1 | 54 |
55 #define DIR -25 | |
56 | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
57 static void create_registry(void); |
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
58 static void open_registry(void); |
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
59 static void save_registry(void); |
3128 | 60 static void init_registry(void); |
1 | 61 |
62 | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
63 static void create_registry(void){ |
1 | 64 if(regs) |
65 { | |
66 printf("Logic error: create_registry() called with existing registry\n"); | |
67 save_registry(); | |
68 return; | |
3128 | 69 } |
18878 | 70 regs=malloc(3*sizeof(struct reg_value)); |
1 | 71 regs[0].type=regs[1].type=DIR; |
18878 | 72 regs[0].name=malloc(5); |
1 | 73 strcpy(regs[0].name, "HKLM"); |
18878 | 74 regs[1].name=malloc(5); |
1 | 75 strcpy(regs[1].name, "HKCU"); |
76 regs[0].value=regs[1].value=NULL; | |
77 regs[0].len=regs[1].len=0; | |
78 reg_size=2; | |
3134 | 79 head = 0; |
1 | 80 save_registry(); |
81 } | |
3134 | 82 |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
83 static void open_registry(void) |
1 | 84 { |
85 int fd; | |
86 int i; | |
3128 | 87 unsigned int len; |
1 | 88 if(regs) |
89 { | |
90 printf("Multiple open_registry(>\n"); | |
91 return; | |
92 } | |
3134 | 93 fd = open(localregpathname, O_RDONLY); |
3128 | 94 if (fd == -1) |
1 | 95 { |
96 printf("Creating new registry\n"); | |
97 create_registry(); | |
98 return; | |
3128 | 99 } |
1 | 100 read(fd, ®_size, 4); |
18878 | 101 regs=malloc(reg_size*sizeof(struct reg_value)); |
3134 | 102 head = 0; |
1 | 103 for(i=0; i<reg_size; i++) |
104 { | |
105 read(fd,®s[i].type,4); | |
106 read(fd,&len,4); | |
18878 | 107 regs[i].name=malloc(len+1); |
1 | 108 if(regs[i].name==0) |
109 { | |
110 reg_size=i+1; | |
111 goto error; | |
112 } | |
113 read(fd, regs[i].name, len); | |
114 regs[i].name[len]=0; | |
115 read(fd,®s[i].len,4); | |
18878 | 116 regs[i].value=malloc(regs[i].len+1); |
1 | 117 if(regs[i].value==0) |
118 { | |
3134 | 119 free(regs[i].name); |
1 | 120 reg_size=i+1; |
121 goto error; | |
122 } | |
123 read(fd, regs[i].value, regs[i].len); | |
124 regs[i].value[regs[i].len]=0; | |
125 } | |
126 error: | |
127 close(fd); | |
128 return; | |
129 } | |
130 | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
131 static void save_registry(void) |
1 | 132 { |
3128 | 133 int fd, i; |
134 if (!regs) | |
135 init_registry(); | |
3134 | 136 fd = open(localregpathname, O_WRONLY | O_CREAT, 00666); |
3128 | 137 if (fd == -1) |
1 | 138 { |
3128 | 139 printf("Failed to open registry file '%s' for writing.\n", |
3134 | 140 localregpathname); |
3128 | 141 return; |
1 | 142 } |
143 write(fd, ®_size, 4); | |
144 for(i=0; i<reg_size; i++) | |
145 { | |
3128 | 146 unsigned len=strlen(regs[i].name); |
1 | 147 write(fd, ®s[i].type, 4); |
148 write(fd, &len, 4); | |
149 write(fd, regs[i].name, len); | |
150 write(fd, ®s[i].len, 4); | |
151 write(fd, regs[i].value, regs[i].len); | |
152 } | |
153 close(fd); | |
154 } | |
3134 | 155 |
156 void free_registry(void) | |
157 { | |
158 reg_handle_t* t = head; | |
159 while (t) | |
160 { | |
161 reg_handle_t* f = t; | |
162 if (t->name) | |
163 free(t->name); | |
164 t=t->prev; | |
165 free(f); | |
166 } | |
167 head = 0; | |
168 if (regs) | |
169 { | |
170 int i; | |
171 for(i=0; i<reg_size; i++) | |
172 { | |
173 free(regs[i].name); | |
174 free(regs[i].value); | |
175 } | |
176 free(regs); | |
177 regs = 0; | |
178 } | |
3465 | 179 |
180 if (localregpathname && localregpathname != regpathname) | |
3134 | 181 free(localregpathname); |
3465 | 182 localregpathname = 0; |
3134 | 183 } |
184 | |
185 | |
25807
3cd1d60e7225
Disable unused functions find_handle_2, find_handle_by_name, fixes the warning:
diego
parents:
24387
diff
changeset
|
186 #if 0 |
1 | 187 static reg_handle_t* find_handle_by_name(const char* name) |
188 { | |
189 reg_handle_t* t; | |
190 for(t=head; t; t=t->prev) | |
191 { | |
192 if(!strcmp(t->name, name)) | |
193 { | |
194 return t; | |
195 } | |
196 } | |
197 return 0; | |
198 } | |
25807
3cd1d60e7225
Disable unused functions find_handle_2, find_handle_by_name, fixes the warning:
diego
parents:
24387
diff
changeset
|
199 #endif |
1 | 200 static struct reg_value* find_value_by_name(const char* name) |
201 { | |
202 int i; | |
203 for(i=0; i<reg_size; i++) | |
204 if(!strcmp(regs[i].name, name)) | |
205 return regs+i; | |
206 return 0; | |
207 } | |
208 static reg_handle_t* find_handle(int handle) | |
209 { | |
210 reg_handle_t* t; | |
211 for(t=head; t; t=t->prev) | |
212 { | |
213 if(t->handle==handle) | |
214 { | |
215 return t; | |
216 } | |
217 } | |
218 return 0; | |
3128 | 219 } |
1 | 220 static int generate_handle() |
221 { | |
7386 | 222 static unsigned int zz=249; |
1 | 223 zz++; |
224 while((zz==HKEY_LOCAL_MACHINE) || (zz==HKEY_CURRENT_USER)) | |
225 zz++; | |
226 return zz; | |
227 } | |
228 | |
229 static reg_handle_t* insert_handle(long handle, const char* name) | |
230 { | |
231 reg_handle_t* t; | |
18878 | 232 t=malloc(sizeof(reg_handle_t)); |
1 | 233 if(head==0) |
234 { | |
235 t->prev=0; | |
236 } | |
237 else | |
238 { | |
239 head->next=t; | |
240 t->prev=head; | |
241 } | |
242 t->next=0; | |
18878 | 243 t->name=malloc(strlen(name)+1); |
1 | 244 strcpy(t->name, name); |
245 t->handle=handle; | |
246 head=t; | |
247 return t; | |
248 } | |
249 static char* build_keyname(long key, const char* subkey) | |
250 { | |
251 char* full_name; | |
252 reg_handle_t* t; | |
253 if((t=find_handle(key))==0) | |
254 { | |
255 TRACE("Invalid key\n"); | |
256 return NULL; | |
257 } | |
258 if(subkey==NULL) | |
259 subkey="<default>"; | |
18878 | 260 full_name=malloc(strlen(t->name)+strlen(subkey)+10); |
1 | 261 strcpy(full_name, t->name); |
262 strcat(full_name, "\\"); | |
263 strcat(full_name, subkey); | |
264 return full_name; | |
265 } | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
266 static struct reg_value* insert_reg_value(int handle, const char* name, int type, const void* value, int len) |
1 | 267 { |
268 struct reg_value* v; | |
269 char* fullname; | |
270 if((fullname=build_keyname(handle, name))==NULL) | |
271 { | |
272 TRACE("Invalid handle\n"); | |
273 return NULL; | |
274 } | |
275 | |
276 if((v=find_value_by_name(fullname))==0) | |
277 //creating new value in registry | |
278 { | |
279 if(regs==0) | |
280 create_registry(); | |
281 regs=(struct reg_value*)realloc(regs, sizeof(struct reg_value)*(reg_size+1)); | |
3134 | 282 //regs=(struct reg_value*)my_realloc(regs, sizeof(struct reg_value)*(reg_size+1)); |
1 | 283 v=regs+reg_size; |
284 reg_size++; | |
285 } | |
286 else | |
287 //replacing old one | |
288 { | |
3134 | 289 free(v->value); |
290 free(v->name); | |
1 | 291 } |
7386 | 292 TRACE("RegInsert '%s' %p v:%d len:%d\n", name, value, *(int*)value, len); |
1 | 293 v->type=type; |
294 v->len=len; | |
18878 | 295 v->value=malloc(len); |
1 | 296 memcpy(v->value, value, len); |
18878 | 297 v->name=malloc(strlen(fullname)+1); |
1 | 298 strcpy(v->name, fullname); |
3134 | 299 free(fullname); |
1 | 300 save_registry(); |
301 return v; | |
302 } | |
303 | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
304 static void init_registry(void) |
1 | 305 { |
3128 | 306 TRACE("Initializing registry\n"); |
307 // can't be free-ed - it's static and probably thread | |
308 // unsafe structure which is stored in glibc | |
309 | |
3465 | 310 regpathname = get_path("registry"); |
311 localregpathname = regpathname; | |
3128 | 312 |
1 | 313 open_registry(); |
314 insert_handle(HKEY_LOCAL_MACHINE, "HKLM"); | |
315 insert_handle(HKEY_CURRENT_USER, "HKCU"); | |
316 } | |
3128 | 317 |
25807
3cd1d60e7225
Disable unused functions find_handle_2, find_handle_by_name, fixes the warning:
diego
parents:
24387
diff
changeset
|
318 #if 0 |
1 | 319 static reg_handle_t* find_handle_2(long key, const char* subkey) |
320 { | |
321 char* full_name; | |
322 reg_handle_t* t; | |
323 if((t=find_handle(key))==0) | |
324 { | |
325 TRACE("Invalid key\n"); | |
326 return (reg_handle_t*)-1; | |
327 } | |
328 if(subkey==NULL) | |
329 return t; | |
18878 | 330 full_name=malloc(strlen(t->name)+strlen(subkey)+10); |
1 | 331 strcpy(full_name, t->name); |
332 strcat(full_name, "\\"); | |
333 strcat(full_name, subkey); | |
334 t=find_handle_by_name(full_name); | |
335 free(full_name); | |
336 return t; | |
337 } | |
25807
3cd1d60e7225
Disable unused functions find_handle_2, find_handle_by_name, fixes the warning:
diego
parents:
24387
diff
changeset
|
338 #endif |
1 | 339 |
9965 | 340 long __stdcall RegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey) |
1 | 341 { |
342 char* full_name; | |
343 reg_handle_t* t; | |
344 struct reg_value* v; | |
345 TRACE("Opening key %s\n", subkey); | |
3128 | 346 |
1 | 347 if(!regs) |
348 init_registry() | |
3128 | 349 ; |
1 | 350 /* t=find_handle_2(key, subkey); |
3128 | 351 |
1 | 352 if(t==0) |
353 return -1; | |
354 | |
355 if(t==(reg_handle_t*)-1) | |
356 return -1; | |
3128 | 357 */ |
358 full_name=build_keyname(key, subkey); | |
1 | 359 if(!full_name) |
360 return -1; | |
3128 | 361 TRACE("Opening key Fullname %s\n", full_name); |
362 v=find_value_by_name(full_name); | |
1 | 363 |
364 t=insert_handle(generate_handle(), full_name); | |
365 *newkey=t->handle; | |
366 free(full_name); | |
3128 | 367 |
1 | 368 return 0; |
3128 | 369 } |
9965 | 370 long __stdcall RegCloseKey(long key) |
1 | 371 { |
7386 | 372 reg_handle_t *handle; |
373 if(key==(long)HKEY_LOCAL_MACHINE) | |
1 | 374 return 0; |
7386 | 375 if(key==(long)HKEY_CURRENT_USER) |
1 | 376 return 0; |
377 handle=find_handle(key); | |
378 if(handle==0) | |
379 return 0; | |
380 if(handle->prev) | |
381 handle->prev->next=handle->next; | |
382 if(handle->next) | |
383 handle->next->prev=handle->prev; | |
384 if(handle->name) | |
385 free(handle->name); | |
386 if(handle==head) | |
387 head=head->prev; | |
388 free(handle); | |
389 return 1; | |
3128 | 390 } |
391 | |
9965 | 392 long __stdcall RegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count) |
1 | 393 { |
7386 | 394 struct reg_value* t; |
395 char* c; | |
396 TRACE("Querying value %s\n", value); | |
397 if(!regs) | |
398 init_registry(); | |
3465 | 399 |
7386 | 400 c=build_keyname(key, value); |
401 if (!c) | |
402 return 1; | |
403 t=find_value_by_name(c); | |
404 free(c); | |
405 if (t==0) | |
406 return 2; | |
407 if (type) | |
408 *type=t->type; | |
409 if (data) | |
410 { | |
411 memcpy(data, t->value, (t->len<*count)?t->len:*count); | |
412 TRACE("returning %d bytes: %d\n", t->len, *(int*)data); | |
413 } | |
414 if(*count<t->len) | |
415 { | |
416 *count=t->len; | |
417 return ERROR_MORE_DATA; | |
1 | 418 } |
419 else | |
420 { | |
7386 | 421 *count=t->len; |
422 } | |
1 | 423 return 0; |
3128 | 424 } |
9965 | 425 long __stdcall RegCreateKeyExA(long key, const char* name, long reserved, |
3128 | 426 void* classs, long options, long security, |
427 void* sec_attr, int* newkey, int* status) | |
1 | 428 { |
7386 | 429 reg_handle_t* t; |
430 char* fullname; | |
431 struct reg_value* v; | |
432 // TRACE("Creating/Opening key %s\n", name); | |
433 if(!regs) | |
434 init_registry(); | |
3465 | 435 |
7386 | 436 fullname=build_keyname(key, name); |
437 if (!fullname) | |
438 return 1; | |
439 TRACE("Creating/Opening key %s\n", fullname); | |
440 v=find_value_by_name(fullname); | |
441 if(v==0) | |
442 { | |
443 int qw=45708; | |
444 v=insert_reg_value(key, name, DIR, &qw, 4); | |
445 if (status) *status=REG_CREATED_NEW_KEY; | |
446 // return 0; | |
447 } | |
1 | 448 |
7386 | 449 t=insert_handle(generate_handle(), fullname); |
450 *newkey=t->handle; | |
451 free(fullname); | |
452 return 0; | |
1 | 453 } |
1416 | 454 |
3128 | 455 /* |
456 LONG RegEnumValue( | |
457 HKEY hKey, // handle to key to query | |
458 DWORD dwIndex, // index of value to query | |
459 LPTSTR lpValueName, // address of buffer for value string | |
460 LPDWORD lpcbValueName, // address for size of value buffer | |
461 LPDWORD lpReserved, // reserved | |
462 LPDWORD lpType, // address of buffer for type code | |
463 LPBYTE lpData, // address of buffer for value data | |
464 LPDWORD lpcbData // address for size of data buffer | |
465 ); | |
466 */ | |
467 | |
9965 | 468 long __stdcall RegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count, |
1416 | 469 LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count) |
470 { | |
3128 | 471 // currenly just made to support MSZH & ZLIB |
472 //printf("Reg Enum 0x%x %d %s %d data: %p %d %d >%s<\n", hkey, index, | |
473 // value, *val_count, data, *count, reg_size, data); | |
474 reg_handle_t* t = find_handle(hkey); | |
475 if (t && index < 10) | |
1416 | 476 { |
3128 | 477 struct reg_value* v=find_value_by_name(t->name); |
478 if (v) | |
1416 | 479 { |
3128 | 480 memcpy(data, v->value, (v->len < *count) ? v->len : *count); |
481 if(*count < v->len) | |
482 *count = v->len; | |
483 if (type) | |
1416 | 484 *type = v->type; |
485 //printf("Found handle %s\n", v->name); | |
3128 | 486 return 0; |
1416 | 487 } |
488 } | |
3128 | 489 return ERROR_NO_MORE_ITEMS; |
1416 | 490 } |
491 | |
9965 | 492 long __stdcall RegSetValueExA(long key, const char* name, long v1, long v2, const void* data, long size) |
1 | 493 { |
494 char* c; | |
7386 | 495 TRACE("Request to set value %s %d\n", name, *(const int*)data); |
1 | 496 if(!regs) |
3465 | 497 init_registry(); |
498 | |
1 | 499 c=build_keyname(key, name); |
500 if(c==NULL) | |
501 return 1; | |
502 insert_reg_value(key, name, v2, data, size); | |
503 free(c); | |
504 return 0; | |
3128 | 505 } |
3465 | 506 |
9965 | 507 long __stdcall RegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName, |
3465 | 508 LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass, |
509 LPFILETIME lpftLastWriteTime) | |
510 { | |
511 return ERROR_NO_MORE_ITEMS; | |
512 } |