Mercurial > mplayer.hg
annotate loader/module.c @ 7427:f740737c54ce
-zoom will be handled by -vop scale
author | arpi |
---|---|
date | Tue, 17 Sep 2002 09:55:05 +0000 |
parents | 174e2a58b4cd |
children | 8b905703a450 |
rev | line source |
---|---|
1 | 1 /* |
2 * Modules | |
3 * | |
4 * Copyright 1995 Alexandre Julliard | |
5 */ | |
3465 | 6 #include "config.h" |
1 | 7 |
8 #include <assert.h> | |
9 #include <errno.h> | |
10 #include <fcntl.h> | |
11 #include <stdio.h> | |
12 #include <stdlib.h> | |
13 #include <string.h> | |
14 #include <unistd.h> | |
15 #include <sys/mman.h> | |
16 #include <sys/types.h> | |
17 | |
18 | |
7386 | 19 #include "wine/windef.h" |
20 #include "wine/winerror.h" | |
21 #include "wine/heap.h" | |
22 #include "wine/module.h" | |
23 #include "wine/pe_image.h" | |
24 #include "wine/debugtools.h" | |
2069 | 25 #ifdef HAVE_LIBDL |
26 #include <dlfcn.h> | |
7386 | 27 #include "wine/elfdll.h" |
2069 | 28 #endif |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
128
diff
changeset
|
29 #include "win32.h" |
7386 | 30 #include "driver.h" |
2651
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
31 |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
32 //#undef TRACE |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
33 //#define TRACE printf |
1 | 34 |
35 //WINE_MODREF *local_wm=NULL; | |
36 modref_list* local_wm=NULL; | |
37 | |
2651
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
38 HANDLE SegptrHeap; |
2069 | 39 |
3465 | 40 WINE_MODREF* MODULE_FindModule(LPCSTR m) |
1 | 41 { |
42 modref_list* list=local_wm; | |
43 TRACE("Module %s request\n", m); | |
44 if(list==NULL) | |
45 return NULL; | |
46 while(strcmp(m, list->wm->filename)) | |
47 { | |
128 | 48 TRACE("%s: %x\n", list->wm->filename, list->wm->module); |
1 | 49 list=list->prev; |
50 if(list==NULL) | |
51 return NULL; | |
2069 | 52 } |
1 | 53 TRACE("Resolved to %s\n", list->wm->filename); |
54 return list->wm; | |
2069 | 55 } |
1 | 56 |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
128
diff
changeset
|
57 static void MODULE_RemoveFromList(WINE_MODREF *mod) |
1 | 58 { |
59 modref_list* list=local_wm; | |
60 if(list==0) | |
61 return; | |
62 if(mod==0) | |
63 return; | |
64 if((list->prev==NULL)&&(list->next==NULL)) | |
65 { | |
66 free(list); | |
67 local_wm=NULL; | |
68 // uninstall_fs(); | |
69 return; | |
70 } | |
71 for(;list;list=list->prev) | |
72 { | |
73 if(list->wm==mod) | |
74 { | |
75 if(list->prev) | |
76 list->prev->next=list->next; | |
77 if(list->next) | |
78 list->next->prev=list->prev; | |
79 if(list==local_wm) | |
80 local_wm=list->prev; | |
81 free(list); | |
82 return; | |
83 } | |
84 } | |
2651
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
85 |
2069 | 86 } |
87 | |
1 | 88 WINE_MODREF *MODULE32_LookupHMODULE(HMODULE m) |
89 { | |
90 modref_list* list=local_wm; | |
91 TRACE("Module %X request\n", m); | |
92 if(list==NULL) | |
93 return NULL; | |
94 while(m!=list->wm->module) | |
95 { | |
96 // printf("Checking list %X wm %X module %X\n", | |
97 // list, list->wm, list->wm->module); | |
98 list=list->prev; | |
99 if(list==NULL) | |
100 return NULL; | |
2069 | 101 } |
102 TRACE("LookupHMODULE hit %p\n", list->wm); | |
1 | 103 return list->wm; |
2069 | 104 } |
1 | 105 |
106 /************************************************************************* | |
107 * MODULE_InitDll | |
108 */ | |
109 static WIN_BOOL MODULE_InitDll( WINE_MODREF *wm, DWORD type, LPVOID lpReserved ) | |
110 { | |
111 WIN_BOOL retv = TRUE; | |
112 | |
2069 | 113 static LPCSTR typeName[] = { "PROCESS_DETACH", "PROCESS_ATTACH", |
1 | 114 "THREAD_ATTACH", "THREAD_DETACH" }; |
115 assert( wm ); | |
116 | |
117 | |
118 /* Skip calls for modules loaded with special load flags */ | |
119 | |
120 if ( ( wm->flags & WINE_MODREF_DONT_RESOLVE_REFS ) | |
121 || ( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE ) ) | |
122 return TRUE; | |
123 | |
124 | |
125 TRACE("(%s,%s,%p) - CALL\n", wm->modname, typeName[type], lpReserved ); | |
126 | |
127 /* Call the initialization routine */ | |
128 switch ( wm->type ) | |
129 { | |
130 case MODULE32_PE: | |
131 retv = PE_InitDLL( wm, type, lpReserved ); | |
132 break; | |
133 | |
134 case MODULE32_ELF: | |
135 /* no need to do that, dlopen() already does */ | |
136 break; | |
137 | |
138 default: | |
139 ERR("wine_modref type %d not handled.\n", wm->type ); | |
140 retv = FALSE; | |
141 break; | |
142 } | |
143 | |
144 /* The state of the module list may have changed due to the call | |
145 to PE_InitDLL. We cannot assume that this module has not been | |
146 deleted. */ | |
147 TRACE("(%p,%s,%p) - RETURN %d\n", wm, typeName[type], lpReserved, retv ); | |
148 | |
149 return retv; | |
150 } | |
151 | |
152 /************************************************************************* | |
153 * MODULE_DllProcessAttach | |
2069 | 154 * |
1 | 155 * Send the process attach notification to all DLLs the given module |
156 * depends on (recursively). This is somewhat complicated due to the fact that | |
157 * | |
158 * - we have to respect the module dependencies, i.e. modules implicitly | |
159 * referenced by another module have to be initialized before the module | |
160 * itself can be initialized | |
2069 | 161 * |
1 | 162 * - the initialization routine of a DLL can itself call LoadLibrary, |
163 * thereby introducing a whole new set of dependencies (even involving | |
164 * the 'old' modules) at any time during the whole process | |
165 * | |
166 * (Note that this routine can be recursively entered not only directly | |
167 * from itself, but also via LoadLibrary from one of the called initialization | |
168 * routines.) | |
169 * | |
170 * Furthermore, we need to rearrange the main WINE_MODREF list to allow | |
171 * the process *detach* notifications to be sent in the correct order. | |
2069 | 172 * This must not only take into account module dependencies, but also |
1 | 173 * 'hidden' dependencies created by modules calling LoadLibrary in their |
174 * attach notification routine. | |
175 * | |
176 * The strategy is rather simple: we move a WINE_MODREF to the head of the | |
177 * list after the attach notification has returned. This implies that the | |
178 * detach notifications are called in the reverse of the sequence the attach | |
179 * notifications *returned*. | |
180 * | |
181 * NOTE: Assumes that the process critical section is held! | |
182 * | |
183 */ | |
3465 | 184 static WIN_BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved ) |
1 | 185 { |
186 WIN_BOOL retv = TRUE; | |
187 int i; | |
188 assert( wm ); | |
189 | |
190 /* prevent infinite recursion in case of cyclical dependencies */ | |
191 if ( ( wm->flags & WINE_MODREF_MARKER ) | |
192 || ( wm->flags & WINE_MODREF_PROCESS_ATTACHED ) ) | |
193 return retv; | |
194 | |
195 TRACE("(%s,%p) - START\n", wm->modname, lpReserved ); | |
196 | |
197 /* Tag current MODREF to prevent recursive loop */ | |
198 wm->flags |= WINE_MODREF_MARKER; | |
199 | |
200 /* Recursively attach all DLLs this one depends on */ | |
201 /* for ( i = 0; retv && i < wm->nDeps; i++ ) | |
202 if ( wm->deps[i] ) | |
203 retv = MODULE_DllProcessAttach( wm->deps[i], lpReserved ); | |
204 */ | |
205 /* Call DLL entry point */ | |
206 | |
207 //local_wm=wm; | |
208 if(local_wm) | |
209 { | |
7386 | 210 local_wm->next = (modref_list*) malloc(sizeof(modref_list)); |
1 | 211 local_wm->next->prev=local_wm; |
212 local_wm->next->next=NULL; | |
213 local_wm->next->wm=wm; | |
214 local_wm=local_wm->next; | |
215 } | |
216 else | |
217 { | |
7386 | 218 local_wm = (modref_list*)malloc(sizeof(modref_list)); |
1 | 219 local_wm->next=local_wm->prev=NULL; |
220 local_wm->wm=wm; | |
2069 | 221 } |
1 | 222 /* Remove recursion flag */ |
223 wm->flags &= ~WINE_MODREF_MARKER; | |
2069 | 224 |
1 | 225 if ( retv ) |
226 { | |
227 retv = MODULE_InitDll( wm, DLL_PROCESS_ATTACH, lpReserved ); | |
228 if ( retv ) | |
229 wm->flags |= WINE_MODREF_PROCESS_ATTACHED; | |
230 } | |
231 | |
232 | |
233 TRACE("(%s,%p) - END\n", wm->modname, lpReserved ); | |
234 | |
235 return retv; | |
236 } | |
237 | |
238 /************************************************************************* | |
239 * MODULE_DllProcessDetach | |
2069 | 240 * |
241 * Send DLL process detach notifications. See the comment about calling | |
1 | 242 * sequence at MODULE_DllProcessAttach. Unless the bForceDetach flag |
243 * is set, only DLLs with zero refcount are notified. | |
244 */ | |
3465 | 245 static void MODULE_DllProcessDetach( WINE_MODREF* wm, WIN_BOOL bForceDetach, LPVOID lpReserved ) |
1 | 246 { |
2651
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
247 // WINE_MODREF *wm=local_wm; |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
248 modref_list* l = local_wm; |
1 | 249 wm->flags &= ~WINE_MODREF_PROCESS_ATTACHED; |
250 MODULE_InitDll( wm, DLL_PROCESS_DETACH, lpReserved ); | |
2651
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
251 /* while (l) |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
252 { |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
253 modref_list* f = l; |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
254 l = l->next; |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
255 free(f); |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
256 } |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
257 local_wm = 0;*/ |
1 | 258 } |
259 | |
3465 | 260 /*********************************************************************** |
261 * MODULE_LoadLibraryExA (internal) | |
262 * | |
263 * Load a PE style module according to the load order. | |
264 * | |
265 * The HFILE parameter is not used and marked reserved in the SDK. I can | |
266 * only guess that it should force a file to be mapped, but I rather | |
267 * ignore the parameter because it would be extremely difficult to | |
268 * integrate this with different types of module represenations. | |
269 * | |
270 */ | |
271 static WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags ) | |
272 { | |
273 DWORD err = GetLastError(); | |
274 WINE_MODREF *pwm; | |
275 int i; | |
276 // module_loadorder_t *plo; | |
277 | |
278 SetLastError( ERROR_FILE_NOT_FOUND ); | |
279 TRACE("Trying native dll '%s'\n", libname); | |
280 pwm = PE_LoadLibraryExA(libname, flags); | |
281 #ifdef HAVE_LIBDL | |
282 if(!pwm) | |
283 { | |
284 TRACE("Trying ELF dll '%s'\n", libname); | |
285 pwm=(WINE_MODREF*)ELFDLL_LoadLibraryExA(libname, flags); | |
286 } | |
287 #endif | |
288 // printf("0x%08x\n", pwm); | |
289 // break; | |
290 if(pwm) | |
291 { | |
292 /* Initialize DLL just loaded */ | |
293 TRACE("Loaded module '%s' at 0x%08x, \n", libname, pwm->module); | |
294 /* Set the refCount here so that an attach failure will */ | |
295 /* decrement the dependencies through the MODULE_FreeLibrary call. */ | |
296 pwm->refCount++; | |
297 | |
298 SetLastError( err ); /* restore last error */ | |
299 return pwm; | |
300 } | |
301 | |
302 | |
303 WARN("Failed to load module '%s'; error=0x%08lx, \n", libname, GetLastError()); | |
304 return NULL; | |
305 } | |
306 | |
307 /*********************************************************************** | |
308 * MODULE_FreeLibrary | |
309 * | |
310 * NOTE: Assumes that the process critical section is held! | |
311 */ | |
312 static WIN_BOOL MODULE_FreeLibrary( WINE_MODREF *wm ) | |
313 { | |
314 TRACE("(%s) - START\n", wm->modname ); | |
315 | |
316 /* Recursively decrement reference counts */ | |
317 //MODULE_DecRefCount( wm ); | |
318 | |
319 /* Call process detach notifications */ | |
320 MODULE_DllProcessDetach( wm, FALSE, NULL ); | |
321 | |
322 PE_UnloadLibrary(wm); | |
323 | |
324 TRACE("END\n"); | |
325 | |
326 return TRUE; | |
327 } | |
1 | 328 |
329 /*********************************************************************** | |
330 * LoadLibraryExA (KERNEL32) | |
331 */ | |
332 HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags) | |
333 { | |
2069 | 334 WINE_MODREF *wm = 0; |
335 char* listpath[] = { "", "", "/usr/lib/win32", "/usr/local/lib/win32", 0 }; | |
336 extern char* def_path; | |
337 char path[512]; | |
338 char checked[2000]; | |
339 int i = -1; | |
1 | 340 |
2069 | 341 checked[0] = 0; |
1 | 342 if(!libname) |
343 { | |
344 SetLastError(ERROR_INVALID_PARAMETER); | |
345 return 0; | |
346 } | |
3465 | 347 // if(fs_installed==0) |
348 // install_fs(); | |
2069 | 349 |
350 while (wm == 0 && listpath[++i]) | |
351 { | |
352 if (i < 2) | |
353 { | |
354 if (i == 0) | |
355 /* check just original file name */ | |
2651
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
356 strncpy(path, libname, 511); |
2069 | 357 else |
358 /* check default user path */ | |
359 strncpy(path, def_path, 300); | |
360 } | |
361 else if (strcmp(def_path, listpath[i])) | |
362 /* path from the list */ | |
363 strncpy(path, listpath[i], 300); | |
364 else | |
365 continue; | |
1 | 366 |
2069 | 367 if (i > 0) |
368 { | |
369 strcat(path, "/"); | |
370 strncat(path, libname, 100); | |
371 } | |
372 path[511] = 0; | |
373 wm = MODULE_LoadLibraryExA( path, hfile, flags ); | |
374 | |
375 if (!wm) | |
376 { | |
377 if (checked[0]) | |
378 strcat(checked, ", "); | |
379 strcat(checked, path); | |
380 checked[1500] = 0; | |
381 | |
382 } | |
383 } | |
1 | 384 if ( wm ) |
385 { | |
386 if ( !MODULE_DllProcessAttach( wm, NULL ) ) | |
387 { | |
388 WARN_(module)("Attach failed for module '%s', \n", libname); | |
389 MODULE_FreeLibrary(wm); | |
390 SetLastError(ERROR_DLL_INIT_FAILED); | |
391 MODULE_RemoveFromList(wm); | |
392 wm = NULL; | |
393 } | |
394 } | |
395 | |
2069 | 396 if (!wm) |
397 printf("Win32 LoadLibrary failed to load: %s\n", checked); | |
7386 | 398 |
2069 | 399 |
1 | 400 return wm ? wm->module : 0; |
401 } | |
402 | |
403 | |
404 /*********************************************************************** | |
405 * LoadLibraryA (KERNEL32) | |
406 */ | |
407 HMODULE WINAPI LoadLibraryA(LPCSTR libname) { | |
408 return LoadLibraryExA(libname,0,0); | |
409 } | |
410 | |
411 /*********************************************************************** | |
412 * FreeLibrary | |
413 */ | |
414 WIN_BOOL WINAPI FreeLibrary(HINSTANCE hLibModule) | |
415 { | |
416 WIN_BOOL retv = FALSE; | |
417 WINE_MODREF *wm; | |
418 | |
419 wm=MODULE32_LookupHMODULE(hLibModule); | |
420 | |
421 if ( !wm || !hLibModule ) | |
422 { | |
423 SetLastError( ERROR_INVALID_HANDLE ); | |
424 return 0; | |
2069 | 425 } |
1 | 426 else |
427 retv = MODULE_FreeLibrary( wm ); | |
2069 | 428 |
1 | 429 MODULE_RemoveFromList(wm); |
430 | |
128 | 431 /* garbage... */ |
432 if (local_wm == NULL) my_garbagecollection(); | |
433 | |
1 | 434 return retv; |
435 } | |
436 | |
437 /*********************************************************************** | |
438 * MODULE_DecRefCount | |
439 * | |
440 * NOTE: Assumes that the process critical section is held! | |
441 */ | |
442 static void MODULE_DecRefCount( WINE_MODREF *wm ) | |
443 { | |
444 int i; | |
445 | |
446 if ( wm->flags & WINE_MODREF_MARKER ) | |
447 return; | |
448 | |
449 if ( wm->refCount <= 0 ) | |
450 return; | |
451 | |
452 --wm->refCount; | |
453 TRACE("(%s) refCount: %d\n", wm->modname, wm->refCount ); | |
454 | |
455 if ( wm->refCount == 0 ) | |
456 { | |
457 wm->flags |= WINE_MODREF_MARKER; | |
458 | |
459 for ( i = 0; i < wm->nDeps; i++ ) | |
460 if ( wm->deps[i] ) | |
461 MODULE_DecRefCount( wm->deps[i] ); | |
462 | |
463 wm->flags &= ~WINE_MODREF_MARKER; | |
464 } | |
465 } | |
466 | |
467 /*********************************************************************** | |
468 * GetProcAddress (KERNEL32.257) | |
469 */ | |
470 FARPROC WINAPI GetProcAddress( HMODULE hModule, LPCSTR function ) | |
471 { | |
472 return MODULE_GetProcAddress( hModule, function, TRUE ); | |
473 } | |
474 | |
475 /*********************************************************************** | |
476 * MODULE_GetProcAddress (internal) | |
477 */ | |
2069 | 478 FARPROC MODULE_GetProcAddress( |
1 | 479 HMODULE hModule, /* [in] current module handle */ |
480 LPCSTR function, /* [in] function to be looked up */ | |
481 WIN_BOOL snoop ) | |
482 { | |
483 WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); | |
2069 | 484 // WINE_MODREF *wm=local_wm; |
1 | 485 FARPROC retproc; |
486 | |
487 if (HIWORD(function)) | |
488 TRACE_(win32)("(%08lx,%s)\n",(DWORD)hModule,function); | |
489 else | |
490 TRACE_(win32)("(%08lx,%p)\n",(DWORD)hModule,function); | |
491 if (!wm) { | |
492 SetLastError(ERROR_INVALID_HANDLE); | |
493 return (FARPROC)0; | |
494 } | |
495 switch (wm->type) | |
496 { | |
497 case MODULE32_PE: | |
498 retproc = PE_FindExportedFunction( wm, function, snoop ); | |
499 if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND); | |
500 return retproc; | |
2069 | 501 #ifdef HAVE_LIBDL |
1 | 502 case MODULE32_ELF: |
2069 | 503 retproc = (FARPROC) dlsym( (void*) wm->module, function); |
1 | 504 if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND); |
505 return retproc; | |
506 #endif | |
507 default: | |
508 ERR("wine_modref type %d not handled.\n",wm->type); | |
509 SetLastError(ERROR_INVALID_HANDLE); | |
510 return (FARPROC)0; | |
511 } | |
512 } | |
513 | |
2651
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
514 static int acounter = 0; |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
515 void CodecAlloc(void) |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
516 { |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
517 acounter++; |
3465 | 518 //printf("**************CODEC ALLOC %d\n", acounter); |
2651
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
519 } |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
520 |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
521 void CodecRelease(void) |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
522 { |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
523 acounter--; |
3465 | 524 //printf("**************CODEC RELEASE %d\n", acounter); |
2651
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
525 if (acounter == 0) |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
526 { |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
527 for (;;) |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
528 { |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
529 modref_list* list = local_wm; |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
530 if (!local_wm) |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
531 break; |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
532 //printf("CODECRELEASE %p\n", list); |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
533 MODULE_FreeLibrary(list->wm); |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
534 MODULE_RemoveFromList(list->wm); |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
535 if (local_wm == NULL) |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
536 my_garbagecollection(); |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
537 } |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
538 } |
958d10763c34
partially synced with avifile... (TODO: migrate to new registry.c and driver.c)
arpi
parents:
2069
diff
changeset
|
539 } |