Mercurial > mplayer.hg
annotate loader/registry.c @ 15533:ddf15d233d58
Do not switch to audio tracks whose codec private data differs from the main audio track's as this will most likely result in messed up audio output. Patch by Michael Behrisch <list () behrisch ! de>
author | mosu |
---|---|
date | Sat, 21 May 2005 06:50:08 +0000 |
parents | f5537cc95b02 |
children | 0783dd397f74 |
rev | line source |
---|---|
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9965
diff
changeset
|
1 /* |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9965
diff
changeset
|
2 * Modified for use with MPlayer, detailed CVS changelog at |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9965
diff
changeset
|
3 * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/ |
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" |
1 | 8 |
9 #include <stdio.h> | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
10 #include <stdlib.h> |
1 | 11 #include <fcntl.h> |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
12 #include <unistd.h> |
1 | 13 #include <pwd.h> |
14 #include <sys/types.h> | |
15 | |
7386 | 16 #include "wine/winbase.h" |
17 #include "wine/winreg.h" | |
18 #include "wine/winnt.h" | |
19 #include "wine/winerror.h" | |
1 | 20 |
3465 | 21 #include "ext.h" |
22 #include "registry.h" | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
23 |
128 | 24 //#undef TRACE |
25 //#define TRACE printf | |
3128 | 26 |
4384 | 27 extern char *get_path ( char * ); |
3134 | 28 |
4384 | 29 // ...can be set before init_registry() call |
30 char* regpathname = NULL; | |
3134 | 31 |
4384 | 32 static char* localregpathname = NULL; |
3134 | 33 |
34 typedef struct reg_handle_s | |
35 { | |
36 int handle; | |
37 char* name; | |
38 struct reg_handle_s* next; | |
39 struct reg_handle_s* prev; | |
40 } reg_handle_t; | |
41 | |
1 | 42 struct reg_value |
43 { | |
44 int type; | |
45 char* name; | |
46 int len; | |
47 char* value; | |
48 }; | |
49 | |
3134 | 50 static struct reg_value* regs = NULL; |
51 static int reg_size; | |
52 static reg_handle_t* head = NULL; | |
1 | 53 |
54 #define DIR -25 | |
55 | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
56 static void create_registry(void); |
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
57 static void open_registry(void); |
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
58 static void save_registry(void); |
3128 | 59 static void init_registry(void); |
1 | 60 |
61 | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
62 static void create_registry(void){ |
1 | 63 if(regs) |
64 { | |
65 printf("Logic error: create_registry() called with existing registry\n"); | |
66 save_registry(); | |
67 return; | |
3128 | 68 } |
1 | 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; | |
3134 | 78 head = 0; |
1 | 79 save_registry(); |
80 } | |
3134 | 81 |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
82 static void open_registry(void) |
1 | 83 { |
84 int fd; | |
85 int i; | |
3128 | 86 unsigned int len; |
1 | 87 if(regs) |
88 { | |
89 printf("Multiple open_registry(>\n"); | |
90 return; | |
91 } | |
3134 | 92 fd = open(localregpathname, O_RDONLY); |
3128 | 93 if (fd == -1) |
1 | 94 { |
95 printf("Creating new registry\n"); | |
96 create_registry(); | |
97 return; | |
3128 | 98 } |
1 | 99 read(fd, ®_size, 4); |
100 regs=(struct reg_value*)malloc(reg_size*sizeof(struct reg_value)); | |
3134 | 101 head = 0; |
1 | 102 for(i=0; i<reg_size; i++) |
103 { | |
104 read(fd,®s[i].type,4); | |
105 read(fd,&len,4); | |
106 regs[i].name=(char*)malloc(len+1); | |
107 if(regs[i].name==0) | |
108 { | |
109 reg_size=i+1; | |
110 goto error; | |
111 } | |
112 read(fd, regs[i].name, len); | |
113 regs[i].name[len]=0; | |
114 read(fd,®s[i].len,4); | |
115 regs[i].value=(char*)malloc(regs[i].len+1); | |
116 if(regs[i].value==0) | |
117 { | |
3134 | 118 free(regs[i].name); |
1 | 119 reg_size=i+1; |
120 goto error; | |
121 } | |
122 read(fd, regs[i].value, regs[i].len); | |
123 regs[i].value[regs[i].len]=0; | |
124 } | |
125 error: | |
126 close(fd); | |
127 return; | |
128 } | |
129 | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
130 static void save_registry(void) |
1 | 131 { |
3128 | 132 int fd, i; |
133 if (!regs) | |
134 init_registry(); | |
3134 | 135 fd = open(localregpathname, O_WRONLY | O_CREAT, 00666); |
3128 | 136 if (fd == -1) |
1 | 137 { |
3128 | 138 printf("Failed to open registry file '%s' for writing.\n", |
3134 | 139 localregpathname); |
3128 | 140 return; |
1 | 141 } |
142 write(fd, ®_size, 4); | |
143 for(i=0; i<reg_size; i++) | |
144 { | |
3128 | 145 unsigned len=strlen(regs[i].name); |
1 | 146 write(fd, ®s[i].type, 4); |
147 write(fd, &len, 4); | |
148 write(fd, regs[i].name, len); | |
149 write(fd, ®s[i].len, 4); | |
150 write(fd, regs[i].value, regs[i].len); | |
151 } | |
152 close(fd); | |
153 } | |
3134 | 154 |
155 void free_registry(void) | |
156 { | |
157 reg_handle_t* t = head; | |
158 while (t) | |
159 { | |
160 reg_handle_t* f = t; | |
161 if (t->name) | |
162 free(t->name); | |
163 t=t->prev; | |
164 free(f); | |
165 } | |
166 head = 0; | |
167 if (regs) | |
168 { | |
169 int i; | |
170 for(i=0; i<reg_size; i++) | |
171 { | |
172 free(regs[i].name); | |
173 free(regs[i].value); | |
174 } | |
175 free(regs); | |
176 regs = 0; | |
177 } | |
3465 | 178 |
179 if (localregpathname && localregpathname != regpathname) | |
3134 | 180 free(localregpathname); |
3465 | 181 localregpathname = 0; |
3134 | 182 } |
183 | |
184 | |
1 | 185 static reg_handle_t* find_handle_by_name(const char* name) |
186 { | |
187 reg_handle_t* t; | |
188 for(t=head; t; t=t->prev) | |
189 { | |
190 if(!strcmp(t->name, name)) | |
191 { | |
192 return t; | |
193 } | |
194 } | |
195 return 0; | |
196 } | |
197 static struct reg_value* find_value_by_name(const char* name) | |
198 { | |
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; | |
204 } | |
205 static reg_handle_t* find_handle(int handle) | |
206 { | |
207 reg_handle_t* t; | |
208 for(t=head; t; t=t->prev) | |
209 { | |
210 if(t->handle==handle) | |
211 { | |
212 return t; | |
213 } | |
214 } | |
215 return 0; | |
3128 | 216 } |
1 | 217 static int generate_handle() |
218 { | |
7386 | 219 static unsigned int zz=249; |
1 | 220 zz++; |
221 while((zz==HKEY_LOCAL_MACHINE) || (zz==HKEY_CURRENT_USER)) | |
222 zz++; | |
223 return zz; | |
224 } | |
225 | |
226 static reg_handle_t* insert_handle(long handle, const char* name) | |
227 { | |
228 reg_handle_t* t; | |
229 t=(reg_handle_t*)malloc(sizeof(reg_handle_t)); | |
230 if(head==0) | |
231 { | |
232 t->prev=0; | |
233 } | |
234 else | |
235 { | |
236 head->next=t; | |
237 t->prev=head; | |
238 } | |
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; | |
245 } | |
246 static char* build_keyname(long key, const char* subkey) | |
247 { | |
248 char* full_name; | |
249 reg_handle_t* t; | |
250 if((t=find_handle(key))==0) | |
251 { | |
252 TRACE("Invalid key\n"); | |
253 return NULL; | |
254 } | |
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; | |
262 } | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
263 static struct reg_value* insert_reg_value(int handle, const char* name, int type, const void* value, int len) |
1 | 264 { |
265 reg_handle_t* t; | |
266 struct reg_value* v; | |
267 char* fullname; | |
268 if((fullname=build_keyname(handle, name))==NULL) | |
269 { | |
270 TRACE("Invalid handle\n"); | |
271 return NULL; | |
272 } | |
273 | |
274 if((v=find_value_by_name(fullname))==0) | |
275 //creating new value in registry | |
276 { | |
277 if(regs==0) | |
278 create_registry(); | |
279 regs=(struct reg_value*)realloc(regs, sizeof(struct reg_value)*(reg_size+1)); | |
3134 | 280 //regs=(struct reg_value*)my_realloc(regs, sizeof(struct reg_value)*(reg_size+1)); |
1 | 281 v=regs+reg_size; |
282 reg_size++; | |
283 } | |
284 else | |
285 //replacing old one | |
286 { | |
3134 | 287 free(v->value); |
288 free(v->name); | |
1 | 289 } |
7386 | 290 TRACE("RegInsert '%s' %p v:%d len:%d\n", name, value, *(int*)value, len); |
1 | 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); | |
3134 | 297 free(fullname); |
1 | 298 save_registry(); |
299 return v; | |
300 } | |
301 | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
302 static void init_registry(void) |
1 | 303 { |
3128 | 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 | |
307 | |
3465 | 308 #ifdef MPLAYER |
309 regpathname = get_path("registry"); | |
310 localregpathname = regpathname; | |
3128 | 311 #else |
3465 | 312 // regpathname is an external pointer |
313 // | |
314 // registry.c is holding it's own internal pointer | |
315 // localregpathname - which is being allocate/deallocated | |
316 | |
3134 | 317 if (localregpathname == 0) |
3128 | 318 { |
3134 | 319 const char* pthn = regpathname; |
320 if (!regpathname) | |
321 { | |
3465 | 322 // avifile - for now reading data from user's home |
3134 | 323 struct passwd* pwent; |
324 pwent = getpwuid(geteuid()); | |
325 pthn = pwent->pw_dir; | |
326 } | |
327 | |
328 localregpathname = (char*)malloc(strlen(pthn)+20); | |
329 strcpy(localregpathname, pthn); | |
330 strcat(localregpathname, "/.registry"); | |
3128 | 331 } |
340 | 332 #endif |
3128 | 333 |
1 | 334 open_registry(); |
335 insert_handle(HKEY_LOCAL_MACHINE, "HKLM"); | |
336 insert_handle(HKEY_CURRENT_USER, "HKCU"); | |
337 } | |
3128 | 338 |
1 | 339 static reg_handle_t* find_handle_2(long key, const char* subkey) |
340 { | |
341 char* full_name; | |
342 reg_handle_t* t; | |
343 if((t=find_handle(key))==0) | |
344 { | |
345 TRACE("Invalid key\n"); | |
346 return (reg_handle_t*)-1; | |
347 } | |
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; | |
357 } | |
358 | |
9965 | 359 long __stdcall RegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey) |
1 | 360 { |
361 char* full_name; | |
362 reg_handle_t* t; | |
363 struct reg_value* v; | |
364 TRACE("Opening key %s\n", subkey); | |
3128 | 365 |
1 | 366 if(!regs) |
367 init_registry() | |
3128 | 368 ; |
1 | 369 /* t=find_handle_2(key, subkey); |
3128 | 370 |
1 | 371 if(t==0) |
372 return -1; | |
373 | |
374 if(t==(reg_handle_t*)-1) | |
375 return -1; | |
3128 | 376 */ |
377 full_name=build_keyname(key, subkey); | |
1 | 378 if(!full_name) |
379 return -1; | |
3128 | 380 TRACE("Opening key Fullname %s\n", full_name); |
381 v=find_value_by_name(full_name); | |
1 | 382 |
383 t=insert_handle(generate_handle(), full_name); | |
384 *newkey=t->handle; | |
385 free(full_name); | |
3128 | 386 |
1 | 387 return 0; |
3128 | 388 } |
9965 | 389 long __stdcall RegCloseKey(long key) |
1 | 390 { |
7386 | 391 reg_handle_t *handle; |
392 if(key==(long)HKEY_LOCAL_MACHINE) | |
1 | 393 return 0; |
7386 | 394 if(key==(long)HKEY_CURRENT_USER) |
1 | 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; | |
3128 | 409 } |
410 | |
9965 | 411 long __stdcall RegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count) |
1 | 412 { |
7386 | 413 struct reg_value* t; |
414 char* c; | |
415 TRACE("Querying value %s\n", value); | |
416 if(!regs) | |
417 init_registry(); | |
3465 | 418 |
7386 | 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) | |
429 { | |
430 memcpy(data, t->value, (t->len<*count)?t->len:*count); | |
431 TRACE("returning %d bytes: %d\n", t->len, *(int*)data); | |
432 } | |
433 if(*count<t->len) | |
434 { | |
435 *count=t->len; | |
436 return ERROR_MORE_DATA; | |
1 | 437 } |
438 else | |
439 { | |
7386 | 440 *count=t->len; |
441 } | |
1 | 442 return 0; |
3128 | 443 } |
9965 | 444 long __stdcall RegCreateKeyExA(long key, const char* name, long reserved, |
3128 | 445 void* classs, long options, long security, |
446 void* sec_attr, int* newkey, int* status) | |
1 | 447 { |
7386 | 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(); | |
3465 | 454 |
7386 | 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) | |
461 { | |
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; | |
466 } | |
1 | 467 |
7386 | 468 t=insert_handle(generate_handle(), fullname); |
469 *newkey=t->handle; | |
470 free(fullname); | |
471 return 0; | |
1 | 472 } |
1416 | 473 |
3128 | 474 /* |
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 | |
484 ); | |
485 */ | |
486 | |
9965 | 487 long __stdcall RegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count, |
1416 | 488 LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count) |
489 { | |
3128 | 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) | |
1416 | 495 { |
3128 | 496 struct reg_value* v=find_value_by_name(t->name); |
497 if (v) | |
1416 | 498 { |
3128 | 499 memcpy(data, v->value, (v->len < *count) ? v->len : *count); |
500 if(*count < v->len) | |
501 *count = v->len; | |
502 if (type) | |
1416 | 503 *type = v->type; |
504 //printf("Found handle %s\n", v->name); | |
3128 | 505 return 0; |
1416 | 506 } |
507 } | |
3128 | 508 return ERROR_NO_MORE_ITEMS; |
1416 | 509 } |
510 | |
9965 | 511 long __stdcall RegSetValueExA(long key, const char* name, long v1, long v2, const void* data, long size) |
1 | 512 { |
513 struct reg_value* t; | |
514 char* c; | |
7386 | 515 TRACE("Request to set value %s %d\n", name, *(const int*)data); |
1 | 516 if(!regs) |
3465 | 517 init_registry(); |
518 | |
1 | 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; | |
3128 | 525 } |
3465 | 526 |
9965 | 527 long __stdcall RegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName, |
3465 | 528 LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass, |
529 LPFILETIME lpftLastWriteTime) | |
530 { | |
531 return ERROR_NO_MORE_ITEMS; | |
532 } |