00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #define EMU_QTX_API
00014
00015
00016
00017
00018 #include "config.h"
00019
00020 #include <assert.h>
00021 #include <errno.h>
00022 #include <fcntl.h>
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <unistd.h>
00027 #include <sys/mman.h>
00028 #include <inttypes.h>
00029
00030 #include "wine/windef.h"
00031 #include "wine/winerror.h"
00032 #include "wine/heap.h"
00033 #include "wine/module.h"
00034 #include "wine/pe_image.h"
00035 #include "wine/debugtools.h"
00036
00037 #undef HAVE_LIBDL
00038
00039 #ifdef HAVE_LIBDL
00040 #include <dlfcn.h>
00041 #include "wine/elfdll.h"
00042 #endif
00043 #include "win32.h"
00044 #include "driver.h"
00045
00046 #ifdef EMU_QTX_API
00047 #include "wrapper.h"
00048 static int report_func(void *stack_base, int stack_size, reg386_t *reg, uint32_t *flags);
00049 static int report_func_ret(void *stack_base, int stack_size, reg386_t *reg, uint32_t *flags);
00050 #endif
00051
00052
00053
00054
00055
00056 modref_list* local_wm=NULL;
00057
00058 HANDLE SegptrHeap;
00059
00060 WINE_MODREF* MODULE_FindModule(LPCSTR m)
00061 {
00062 modref_list* list=local_wm;
00063 TRACE("FindModule: Module %s request\n", m);
00064 if(list==NULL)
00065 return NULL;
00066
00067 while(!strstr(list->wm->filename, m))
00068 {
00069 TRACE("%s: %x\n", list->wm->filename, list->wm->module);
00070 list=list->prev;
00071 if(list==NULL)
00072 return NULL;
00073 }
00074 TRACE("Resolved to %s\n", list->wm->filename);
00075 return list->wm;
00076 }
00077
00078 static void MODULE_RemoveFromList(WINE_MODREF *mod)
00079 {
00080 modref_list* list=local_wm;
00081 if(list==0)
00082 return;
00083 if(mod==0)
00084 return;
00085 if((list->prev==NULL)&&(list->next==NULL))
00086 {
00087 free(list);
00088 local_wm=NULL;
00089
00090 return;
00091 }
00092 for(;list;list=list->prev)
00093 {
00094 if(list->wm==mod)
00095 {
00096 if(list->prev)
00097 list->prev->next=list->next;
00098 if(list->next)
00099 list->next->prev=list->prev;
00100 if(list==local_wm)
00101 local_wm=list->prev;
00102 free(list);
00103 return;
00104 }
00105 }
00106
00107 }
00108
00109 WINE_MODREF *MODULE32_LookupHMODULE(HMODULE m)
00110 {
00111 modref_list* list=local_wm;
00112 TRACE("LookupHMODULE: Module %X request\n", m);
00113 if(list==NULL)
00114 {
00115 TRACE("LookupHMODULE failed\n");
00116 return NULL;
00117 }
00118 while(m!=list->wm->module)
00119 {
00120
00121
00122 list=list->prev;
00123 if(list==NULL)
00124 {
00125 TRACE("LookupHMODULE failed\n");
00126 return NULL;
00127 }
00128 }
00129 TRACE("LookupHMODULE hit %p\n", list->wm);
00130 return list->wm;
00131 }
00132
00133
00134
00135
00136 static WIN_BOOL MODULE_InitDll( WINE_MODREF *wm, DWORD type, LPVOID lpReserved )
00137 {
00138 WIN_BOOL retv = TRUE;
00139
00140 static LPCSTR typeName[] = { "PROCESS_DETACH", "PROCESS_ATTACH",
00141 "THREAD_ATTACH", "THREAD_DETACH" };
00142 assert( wm );
00143
00144
00145
00146
00147 if ( ( wm->flags & WINE_MODREF_DONT_RESOLVE_REFS )
00148 || ( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE ) )
00149 return TRUE;
00150
00151
00152 TRACE("(%s,%s,%p) - CALL\n", wm->modname, typeName[type], lpReserved );
00153
00154
00155 switch ( wm->type )
00156 {
00157 case MODULE32_PE:
00158 retv = PE_InitDLL( wm, type, lpReserved );
00159 break;
00160
00161 case MODULE32_ELF:
00162
00163 break;
00164
00165 default:
00166 ERR("wine_modref type %d not handled.\n", wm->type );
00167 retv = FALSE;
00168 break;
00169 }
00170
00171
00172
00173
00174 TRACE("(%p,%s,%p) - RETURN %d\n", wm, typeName[type], lpReserved, retv );
00175
00176 return retv;
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 static WIN_BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved )
00212 {
00213 WIN_BOOL retv = TRUE;
00214 int i;
00215 assert( wm );
00216
00217
00218 if ( ( wm->flags & WINE_MODREF_MARKER )
00219 || ( wm->flags & WINE_MODREF_PROCESS_ATTACHED ) )
00220 return retv;
00221
00222 TRACE("(%s,%p) - START\n", wm->modname, lpReserved );
00223
00224
00225 wm->flags |= WINE_MODREF_MARKER;
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 if(local_wm)
00236 {
00237 local_wm->next = (modref_list*) malloc(sizeof(modref_list));
00238 local_wm->next->prev=local_wm;
00239 local_wm->next->next=NULL;
00240 local_wm->next->wm=wm;
00241 local_wm=local_wm->next;
00242 }
00243 else
00244 {
00245 local_wm = (modref_list*)malloc(sizeof(modref_list));
00246 local_wm->next=local_wm->prev=NULL;
00247 local_wm->wm=wm;
00248 }
00249
00250 wm->flags &= ~WINE_MODREF_MARKER;
00251
00252 if ( retv )
00253 {
00254 retv = MODULE_InitDll( wm, DLL_PROCESS_ATTACH, lpReserved );
00255 if ( retv )
00256 wm->flags |= WINE_MODREF_PROCESS_ATTACHED;
00257 }
00258
00259
00260 TRACE("(%s,%p) - END\n", wm->modname, lpReserved );
00261
00262 return retv;
00263 }
00264
00265
00266
00267
00268
00269
00270
00271
00272 static void MODULE_DllProcessDetach( WINE_MODREF* wm, WIN_BOOL bForceDetach, LPVOID lpReserved )
00273 {
00274
00275 modref_list* l = local_wm;
00276 wm->flags &= ~WINE_MODREF_PROCESS_ATTACHED;
00277 MODULE_InitDll( wm, DLL_PROCESS_DETACH, lpReserved );
00278
00279
00280
00281
00282
00283
00284
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 static WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
00299 {
00300 DWORD err = GetLastError();
00301 WINE_MODREF *pwm;
00302 int i;
00303
00304
00305 SetLastError( ERROR_FILE_NOT_FOUND );
00306 TRACE("Trying native dll '%s'\n", libname);
00307 pwm = PE_LoadLibraryExA(libname, flags);
00308 #ifdef HAVE_LIBDL
00309 if(!pwm)
00310 {
00311 TRACE("Trying ELF dll '%s'\n", libname);
00312 pwm=(WINE_MODREF*)ELFDLL_LoadLibraryExA(libname, flags);
00313 }
00314 #endif
00315
00316
00317 if(pwm)
00318 {
00319
00320 TRACE("Loaded module '%s' at 0x%08x, \n", libname, pwm->module);
00321
00322
00323 pwm->refCount++;
00324
00325 SetLastError( err );
00326 return pwm;
00327 }
00328
00329
00330 WARN("Failed to load module '%s'; error=0x%08lx, \n", libname, GetLastError());
00331 return NULL;
00332 }
00333
00334
00335
00336
00337
00338
00339 static WIN_BOOL MODULE_FreeLibrary( WINE_MODREF *wm )
00340 {
00341 TRACE("(%s) - START\n", wm->modname );
00342
00343
00344
00345
00346
00347 MODULE_DllProcessDetach( wm, FALSE, NULL );
00348
00349 PE_UnloadLibrary(wm);
00350
00351 TRACE("END\n");
00352
00353 return TRUE;
00354 }
00355
00356
00357
00358
00359 HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags)
00360 {
00361 WINE_MODREF *wm = 0;
00362 char* listpath[] = { "", "", "/usr/lib/win32", "/usr/local/lib/win32", 0 };
00363 extern char* def_path;
00364 char path[512];
00365 char checked[2000];
00366 int i = -1;
00367
00368 checked[0] = 0;
00369 if(!libname)
00370 {
00371 SetLastError(ERROR_INVALID_PARAMETER);
00372 return 0;
00373 }
00374
00375 wm=MODULE_FindModule(libname);
00376 if(wm) return wm->module;
00377
00378
00379
00380
00381 while (wm == 0 && listpath[++i])
00382 {
00383 if (i < 2)
00384 {
00385 if (i == 0)
00386
00387 strncpy(path, libname, 511);
00388 else
00389
00390 strncpy(path, def_path, 300);
00391 }
00392 else if (strcmp(def_path, listpath[i]))
00393
00394 strncpy(path, listpath[i], 300);
00395 else
00396 continue;
00397
00398 if (i > 0)
00399 {
00400 strcat(path, "/");
00401 strncat(path, libname, 100);
00402 }
00403 path[511] = 0;
00404 wm = MODULE_LoadLibraryExA( path, hfile, flags );
00405
00406 if (!wm)
00407 {
00408 if (checked[0])
00409 strcat(checked, ", ");
00410 strcat(checked, path);
00411 checked[1500] = 0;
00412
00413 }
00414 }
00415 if ( wm )
00416 {
00417 if ( !MODULE_DllProcessAttach( wm, NULL ) )
00418 {
00419 WARN_(module)("Attach failed for module '%s', \n", libname);
00420 MODULE_FreeLibrary(wm);
00421 SetLastError(ERROR_DLL_INIT_FAILED);
00422 MODULE_RemoveFromList(wm);
00423 wm = NULL;
00424 }
00425 }
00426
00427 if (!wm)
00428 printf("Win32 LoadLibrary failed to load: %s\n", checked);
00429
00430 if (strstr(libname,"vp31vfw.dll") && wm)
00431 {
00432 int i;
00433
00434
00435 if (PE_FindExportedFunction(wm, "DriverProc", TRUE)==(void*)0x10001000) {
00436 fprintf(stderr, "VP3 DLL found\n");
00437 for (i=0;i<18;i++) ((char*)0x10004bd6)[i]=0x90;
00438 }
00439 }
00440
00441
00442 if (strstr(libname,"vp5vfw.dll") && wm)
00443 {
00444 int i;
00445 if (PE_FindExportedFunction(wm, "DriverProc", TRUE)==(void*)0x10003930) {
00446 for (i=0;i<3;i++) ((char*)0x10004e86)[i]=0x90;
00447 for (i=0;i<3;i++) ((char*)0x10005a23)[i]=0x90;
00448 for (i=0;i<3;i++) ((char*)0x10005bff)[i]=0x90;
00449 } else {
00450 fprintf(stderr, "Unsupported VP5 version\n");
00451 return 0;
00452 }
00453 }
00454
00455 if (strstr(libname,"vp6vfw.dll") && wm)
00456 {
00457 int i;
00458 if (PE_FindExportedFunction(wm, "DriverProc", TRUE)==(void*)0x10003ef0) {
00459
00460 for (i=0;i<6;i++) ((char*)0x10007268)[i]=0x90;
00461 for (i=0;i<6;i++) ((char*)0x10007e83)[i]=0x90;
00462 for (i=0;i<6;i++) ((char*)0x1000806a)[i]=0x90;
00463 } else if (PE_FindExportedFunction(wm, "DriverProc", TRUE)==(void*)0x10004120) {
00464
00465 for (i=0;i<6;i++) ((char*)0x10007688)[i]=0x90;
00466 for (i=0;i<6;i++) ((char*)0x100082c3)[i]=0x90;
00467 for (i=0;i<6;i++) ((char*)0x100084aa)[i]=0x90;
00468 } else if (PE_FindExportedFunction(wm, "DriverProc", TRUE)==(void*)0x10003e70) {
00469
00470 for (i=0;i<6;i++) ((char*)0x10007559)[i]=0x90;
00471 for (i=0;i<6;i++) ((char*)0x100081c3)[i]=0x90;
00472 for (i=0;i<6;i++) ((char*)0x1000839e)[i]=0x90;
00473 } else {
00474 fprintf(stderr, "Unsupported VP6 version\n");
00475 return 0;
00476 }
00477 }
00478
00479
00480 if (strstr(libname,"wmvadvd.dll") && wm)
00481 {
00482
00483
00484 if (PE_FindExportedFunction(wm, "CreateInstance", TRUE)==(void*)0x08c4b812) {
00485
00486 *((char*)0x08c48b0f)=0xeb;
00487 } else {
00488 fprintf(stderr, "Unsupported WMVA version\n");
00489 return 0;
00490 }
00491 }
00492
00493 if (strstr(libname,"QuickTime.qts") && wm)
00494 {
00495 void** ptr;
00496 void *dispatch_addr;
00497 int i;
00498
00499
00500 dispatch_addr = PE_FindExportedFunction(wm, "theQuickTimeDispatcher", TRUE);
00501 if (dispatch_addr == (void *)0x62924c30)
00502 {
00503 fprintf(stderr, "QuickTime5 DLLs found\n");
00504 ptr = (void **)0x62b75ca4;
00505 for (i=0;i<5;i++) ((char*)0x6299e842)[i]=0x90;
00506 for (i=0;i<28;i++) ((char*)0x6299e86d)[i]=0x90;
00507 for (i=0;i<5;i++) ((char*)0x6299e898)[i]=0x90;
00508 for (i=0;i<9;i++) ((char*)0x6299e8ac)[i]=0x90;
00509 for (i=0;i<106;i++) ((char*)0x62a61b10)[i]=0x90;
00510 #if 0
00511
00512 for (i=0;i<5;i++) ((char*)0x629487c5)[i]=0x90;
00513 for (i=0;i<5;i++) ((char*)0x6294b275)[i]=0x90;
00514 for (i=0;i<5;i++) ((char*)0x629a24b1)[i]=0x90;
00515 for (i=0;i<5;i++) ((char*)0x629afc5a)[i]=0x90;
00516 for (i=0;i<5;i++) ((char*)0x62af799c)[i]=0x90;
00517 for (i=0;i<5;i++) ((char*)0x62af7efe)[i]=0x90;
00518 for (i=0;i<5;i++) ((char*)0x62afa33e)[i]=0x90;
00519 #endif
00520
00521 #if 0
00522
00523 for (i=0;i<47;i++) ((char*)0x62afa3b8)[i]=0x90;
00524 for (i=0;i<47;i++) ((char*)0x62af7f78)[i]=0x90;
00525 for (i=0;i<77;i++) ((char*)0x629a13d5)[i]=0x90;
00526 ((char *)0x6288e0ae)[0] = 0xc3;
00527 for (i=0;i<24;i++) ((char*)0x6287a1ad)[i]=0x90;
00528 #endif
00529 } else if (dispatch_addr == (void *)0x6693b330)
00530 {
00531 fprintf(stderr, "QuickTime6 DLLs found\n");
00532 ptr = (void **)0x66bb9524;
00533 for (i=0;i<5;i++) ((char *)0x66a730cc)[i]=0x90;
00534 for (i=0;i<28;i++) ((char *)0x66a730f7)[i]=0x90;
00535 for (i=0;i<5;i++) ((char *)0x66a73122)[i]=0x90;
00536 for (i=0;i<9;i++) ((char *)0x66a73131)[i]=0x90;
00537 for (i=0;i<96;i++) ((char *)0x66aac852)[i]=0x90;
00538 } else if (dispatch_addr == (void *)0x6693c3e0)
00539 {
00540 fprintf(stderr, "QuickTime6.3 DLLs found\n");
00541 ptr = (void **)0x66bca01c;
00542 for (i=0;i<5;i++) ((char *)0x66a68f6c)[i]=0x90;
00543 for (i=0;i<28;i++) ((char *)0x66a68f97)[i]=0x90;
00544 for (i=0;i<5;i++) ((char *)0x66a68fc2)[i]=0x90;
00545 for (i=0;i<9;i++) ((char *)0x66a68fd1)[i]=0x90;
00546 for (i=0;i<96;i++) ((char *)0x66ab4722)[i]=0x90;
00547 } else
00548 {
00549 fprintf(stderr, "Unsupported QuickTime version (%p)\n",
00550 dispatch_addr);
00551 return 0;
00552 }
00553
00554 fprintf(stderr,"QuickTime.qts patched!!! old entry=%p\n",ptr[0]);
00555
00556 #ifdef EMU_QTX_API
00557 report_entry = report_func;
00558 report_ret = report_func_ret;
00559 wrapper_target=ptr[0];
00560 ptr[0]=wrapper;
00561 #endif
00562 }
00563
00564 return wm ? wm->module : 0;
00565 }
00566
00567
00568
00569
00570
00571 HMODULE WINAPI LoadLibraryA(LPCSTR libname) {
00572 return LoadLibraryExA(libname,0,0);
00573 }
00574
00575
00576
00577
00578 WIN_BOOL WINAPI FreeLibrary(HINSTANCE hLibModule)
00579 {
00580 WIN_BOOL retv = FALSE;
00581 WINE_MODREF *wm;
00582
00583 wm=MODULE32_LookupHMODULE(hLibModule);
00584
00585 if ( !wm || !hLibModule )
00586 {
00587 SetLastError( ERROR_INVALID_HANDLE );
00588 return 0;
00589 }
00590 else
00591 retv = MODULE_FreeLibrary( wm );
00592
00593 MODULE_RemoveFromList(wm);
00594
00595
00596 if (local_wm == NULL) my_garbagecollection();
00597
00598 return retv;
00599 }
00600
00601
00602
00603
00604
00605
00606 static void MODULE_DecRefCount( WINE_MODREF *wm )
00607 {
00608 int i;
00609
00610 if ( wm->flags & WINE_MODREF_MARKER )
00611 return;
00612
00613 if ( wm->refCount <= 0 )
00614 return;
00615
00616 --wm->refCount;
00617 TRACE("(%s) refCount: %d\n", wm->modname, wm->refCount );
00618
00619 if ( wm->refCount == 0 )
00620 {
00621 wm->flags |= WINE_MODREF_MARKER;
00622
00623 for ( i = 0; i < wm->nDeps; i++ )
00624 if ( wm->deps[i] )
00625 MODULE_DecRefCount( wm->deps[i] );
00626
00627 wm->flags &= ~WINE_MODREF_MARKER;
00628 }
00629 }
00630
00631
00632
00633
00634 FARPROC WINAPI GetProcAddress( HMODULE hModule, LPCSTR function )
00635 {
00636 return MODULE_GetProcAddress( hModule, function, TRUE );
00637 }
00638
00639 #ifdef DEBUG_QTX_API
00640
00641
00642
00643
00644
00645 struct ComponentParameters {
00646 unsigned char flags;
00647 unsigned char paramSize;
00648 short what;
00649 long params[1];
00650 };
00651 typedef struct ComponentParameters ComponentParameters;
00652
00653 static char* component_func(int what){
00654 if (what < 0)
00655 switch(what){
00656 case -1: return "kComponentOpenSelect";
00657 case -2: return "kComponentCloseSelect";
00658 case -3: return "kComponentCanDoSelect";
00659 case -4: return "kComponentVersionSelect";
00660 case -5: return "kComponentRegisterSelect";
00661 case -6: return "kComponentTargetSelect";
00662 case -7: return "kComponentUnregisterSelect";
00663 }
00664
00665 if (what >= 0 && what <= 0xff)
00666 switch(what & 0xff){
00667 case 0: return "kImageCodecGetCodecInfoSelect";
00668 case 1: return "kImageCodecGetCompressionTimeSelect";
00669 case 2: return "kImageCodecGetMaxCompressionSizeSelect";
00670 case 3: return "kImageCodecPreCompressSelect";
00671 case 4: return "kImageCodecBandCompressSelect";
00672 case 5: return "kImageCodecPreDecompressSelect";
00673 case 6: return "kImageCodecBandDecompressSelect";
00674 case 7: return "kImageCodecBusySelect";
00675
00676 case 0x10: return "kImageCodecIsImageDescriptionEquivalentSelect";
00677 case 0x12: return "kImageCodecDisposeMemorySelect";
00678 case 0x14: return "kImageCodecNewImageBufferMemorySelect";
00679 case 0x28: return "kImageCodecRequestGammaLevelSelect";
00680 }
00681
00682
00683
00684 if (what >= 0x200 && what <= 0x2ff)
00685 switch(what & 0xff){
00686 case 0: return "Preflight";
00687 case 1: return "Initialize";
00688 case 2: return "BeginBand";
00689 case 3: return "DrawBand";
00690 case 4: return "EndBand";
00691 case 5: return "QueueStarting";
00692 case 6: return "QueueStopping";
00693 }
00694
00695 return "???";
00696 }
00697
00698 static int c_level=0;
00699
00700 static int dump_component(char* name,int type,void* _orig, ComponentParameters *params,void** glob){
00701 int ( *orig)(ComponentParameters *params, void** glob) = _orig;
00702 int ret,i;
00703
00704 fprintf(stderr,"%*sComponentCall: %s flags=0x%X size=%d what=0x%X %s\n",3*c_level,"",name,params->flags, params->paramSize, params->what, component_func(params->what));
00705
00706 for(i=0;i<params->paramSize/4;i++)
00707 fprintf(stderr,"%*s param[%d] = 0x%X\n",3*c_level,"",i,params->params[i]);
00708
00709 ++c_level;
00710 ret=orig(params,glob);
00711 --c_level;
00712
00713 if(ret>=0x1000)
00714 fprintf(stderr,"%*s return=0x%X\n",3*c_level,"",ret);
00715 else
00716 fprintf(stderr,"%*s return=%d\n",3*c_level,"",ret);
00717 return ret;
00718 }
00719
00720 #define DECL_COMPONENT(sname,name,type) \
00721 static void* real_ ## sname = NULL; \
00722 static int fake_ ## sname(ComponentParameters *params,void** glob){ \
00723 return dump_component(name,type,real_ ## sname, params, glob); \
00724 }
00725
00726 #include "qt_comp.h"
00727
00728 #undef DECL_COMPONENT
00729
00730 #include "qt_fv.h"
00731
00732 #endif
00733
00734 #ifdef EMU_QTX_API
00735
00736 static uint32_t ret_array[4096];
00737 static int ret_i=0;
00738
00739 static int report_func(void *stack_base, int stack_size, reg386_t *reg, uint32_t *flags)
00740 {
00741 #ifdef DEBUG_QTX_API
00742 int i;
00743 int* dptr;
00744 void* pwrapper=NULL;
00745 void* pptr=NULL;
00746 char* pname=NULL;
00747 int plen=-1;
00748
00749
00750 dptr=0x62b67ae0;dptr+=2*((reg->eax>>16)&255);
00751
00752 if(dptr[0]&255){
00753 dptr=dptr[1];dptr+=4*(reg->eax&65535);
00754
00755 pwrapper=dptr[1]; pptr=dptr[0]; plen=dptr[2];
00756 } else {
00757 pwrapper=0x62924910;
00758 switch(dptr[1]){
00759 case 0x629248d0:
00760 dptr=0x62b672c0;dptr+=2*(reg->eax&65535);
00761
00762 pptr=dptr[0]; plen=dptr[1];
00763 break;
00764 case 0x62924e40:
00765 dptr=0x62b67c70;dptr+=2*(reg->eax&65535);
00766
00767 pptr=dptr[0]; plen=dptr[1];
00768 break;
00769 case 0x62924e60:
00770 dptr=0x62b68108;if(reg->eax&0x8000) dptr+=2*(reg->eax|0xffff0000); else dptr+=2*(reg->eax&65535);
00771
00772 pptr=dptr[0]; plen=dptr[1];
00773 break;
00774 case 0x62924e80:
00775 dptr=0x62b68108;if(reg->eax&0x8000) dptr+=2*(reg->eax|0xffff0000); else dptr+=2*(reg->eax&65535);
00776
00777 pptr=dptr[0]; plen=dptr[1];
00778 break;
00779 default:
00780 printf("FUNC: unknown ptr & psize!\n");
00781 pwrapper=dptr[1];
00782 }
00783 }
00784
00785 for(i=0;qt_fv_list[i].name;i++){
00786 if(qt_fv_list[i].id==reg->eax){
00787 pname=qt_fv_list[i].name;
00788 break;
00789 }
00790 }
00791
00792 printf("FUNC[%X/%s]: wrapper=%p func=%p len=%d\n",reg->eax,
00793 pname?pname:"???",pwrapper,pptr,plen);
00794
00795 printf("FUNC: caller=%p ebx=%p\n",((uint32_t *)stack_base)[0],reg->ebx);
00796
00797 if(pname)
00798 printf("%*sENTER(%d): %s(",ret_i*2,"",ret_i,pname);
00799 else
00800 printf("%*sENTER(%d): %X(",ret_i*2,"",ret_i,reg->eax);
00801 for (i=0;i<plen/4;i++){
00802 unsigned int val=((uint32_t *)stack_base)[1+i];
00803 unsigned char* fcc=&val;
00804 printf("%s0x%X", i?", ":"",val);
00805 if(fcc[0]>=0x20 && fcc[0]<128 &&
00806 fcc[1]>=0x20 && fcc[1]<128 &&
00807 fcc[2]>=0x20 && fcc[2]<128 &&
00808 fcc[3]>=0x20 && fcc[3]<128) printf("='%c%c%c%c'",fcc[3],fcc[2],fcc[1],fcc[0]);
00809 else if(val>=8 && val<65536) printf("=%d",val);
00810 }
00811 printf(")\n");
00812 fflush(stdout);
00813
00814 #endif
00815
00816 #if 1
00817
00818 switch(reg->eax){
00819
00820 case 0x150011:
00821 case 0x150012:
00822 reg->eax=(uint32_t)malloc(((uint32_t *)stack_base)[1]);
00823 memset((void *)reg->eax,0,((uint32_t *)stack_base)[1]);
00824 #ifdef DEBUG_QTX_API
00825 printf("%*sLEAVE(%d): EMULATED! 0x%X\n",ret_i*2,"",ret_i, reg->eax);
00826 #endif
00827 return 1;
00828 case 0x15000F:
00829 case 0x150010:
00830 reg->eax=(uint32_t)malloc(((uint32_t *)stack_base)[1]);
00831 #ifdef DEBUG_QTX_API
00832 printf("%*sLEAVE(%d): EMULATED! 0x%X\n",ret_i*2,"",ret_i, reg->eax);
00833 #endif
00834 return 1;
00835 case 0x15002f:
00836 if(((uint32_t *)stack_base)[1]>=0x60000000)
00837 printf("WARNING! Invalid Ptr handle!\n");
00838 else
00839 free((void *)((uint32_t *)stack_base)[1]);
00840 reg->eax=0;
00841 #ifdef DEBUG_QTX_API
00842 printf("%*sLEAVE(%d): EMULATED! 0x%X\n",ret_i*2,"",ret_i, reg->eax);
00843 #endif
00844 return 1;
00845
00846 case 0x1d0033:
00847 reg->eax=0xdeadbabe;
00848 #ifdef DEBUG_QTX_API
00849 printf("%*sLEAVE(%d): EMULATED! 0x%X\n",ret_i*2,"",ret_i, reg->eax);
00850 #endif
00851 return 1;
00852 case 0x1d0034:
00853 case 0x1d0035:
00854 case 0x1d0036:
00855 case 0x1d003d:
00856 reg->eax=0;
00857 #ifdef DEBUG_QTX_API
00858 printf("%*sLEAVE(%d): EMULATED! 0x%X\n",ret_i*2,"",ret_i, reg->eax);
00859 #endif
00860 return 1;
00861 }
00862 #endif
00863
00864 #if 0
00865 switch(reg->eax){
00866
00867
00868
00869 case 0x00010003:
00870 printf("FUNC: CountComponents(&desc=%p)\n",((uint32_t *)stack_base)[1]);
00871 break;
00872 case 0x00010004:
00873 printf("FUNC: FindNextComponent(prev=%p,&desc=%p)\n",((uint32_t *)stack_base)[1],((uint32_t *)stack_base)[2]);
00874 break;
00875 case 0x00010007:
00876 printf("FUNC: OpenComponent(prev=%p)\n",((uint32_t *)stack_base)[1]);
00877 break;
00878 case 0x0003008b:
00879 printf("FUNC: QTNewGWorldFromPtr(&pts=%p,fourcc=%.4s,&rect=%p,x1=%p,x2=%p,x3=%p,plane=%p,stride=%d)\n",
00880 ((uint32_t *)stack_base)[1],
00881 &(((uint32_t *)stack_base)[2]),
00882 ((uint32_t *)stack_base)[3],
00883 ((uint32_t *)stack_base)[4],
00884 ((uint32_t *)stack_base)[5],
00885 ((uint32_t *)stack_base)[6],
00886 ((uint32_t *)stack_base)[7],
00887 ((uint32_t *)stack_base)[8]);
00888 break;
00889 case 0x001c0018:
00890 printf("FUNC: GetGWorldPixMap(gworld=%p)\n",((uint32_t *)stack_base)[1]);
00891 break;
00892 case 0x00110001:
00893 printf("FUNC: Gestalt(fourcc=%.4s, &ret=%p)\n",&(((uint32_t *)stack_base)[1]),((uint32_t *)stack_base)[2]);
00894 break;
00895 default: {
00896 int i;
00897 for(i=0;qt_fv_list[i].name;i++){
00898 if(qt_fv_list[i].id==reg->eax){
00899 printf("FUNC: %s\n",qt_fv_list[i].name);
00900 break;
00901 }
00902 }
00903 }
00904 }
00905
00906
00907 printf("ENTER(%d) stack = %d bytes @ %p\n"
00908 "eax = 0x%08x edx = 0x%08x ebx = 0x%08x ecx = 0x%08x\n"
00909 "esp = 0x%08x ebp = 0x%08x esi = 0x%08x edi = 0x%08x\n"
00910 "flags = 0x%08x\n", ret_i,
00911 stack_size, stack_base,
00912 reg->eax, reg->edx, reg->ebx, reg->ecx,
00913 reg->esp, reg->ebp, reg->esi, reg->edi,
00914 *flags);
00915 #endif
00916
00917
00918 ret_array[ret_i]=((uint32_t *)stack_base)[0];
00919 ++ret_i;
00920
00921 #if 0
00922
00923 printf("stack[] = { ");
00924 for (i=0;i<7;i++) {
00925 printf("%08x ", ((uint32_t *)stack_base)[i]);
00926 }
00927 printf("}\n\n");
00928 #endif
00929
00930
00931
00932
00933
00934
00935 return 0;
00936 }
00937
00938 static int report_func_ret(void *stack_base, int stack_size, reg386_t *reg, uint32_t *flags)
00939 {
00940 int i;
00941 short err;
00942
00943
00944 --ret_i;
00945 ((uint32_t *)stack_base)[0]=ret_array[ret_i];
00946
00947 #ifdef DEBUG_QTX_API
00948
00949 #if 1
00950 printf("%*sLEAVE(%d): 0x%X",ret_i*2,"",ret_i, reg->eax);
00951 err=reg->eax;
00952 if(err && (reg->eax>>16)==0) printf(" = %d",err);
00953 printf("\n");
00954 fflush(stdout);
00955 #else
00956
00957 printf("LEAVE(%d) stack = %d bytes @ %p\n"
00958 "eax = 0x%08x edx = 0x%08x ebx = 0x%08x ecx = 0x%08x\n"
00959 "esp = 0x%08x ebp = 0x%08x esi = 0x%08x edi = 0x%08x\n"
00960 "flags = 0x%08x\n", ret_i,
00961 stack_size, stack_base,
00962 reg->eax, reg->edx, reg->ebx, reg->ecx,
00963 reg->esp, reg->ebp, reg->esi, reg->edi,
00964 *flags);
00965 #endif
00966
00967 #if 0
00968
00969 printf("stack[] = { ");
00970 for (i=0;i<7;i++) {
00971 printf("%08x ", ((uint32_t *)stack_base)[i]);
00972 }
00973 printf("}\n\n");
00974 #endif
00975
00976 #endif
00977
00978
00979
00980
00981
00982
00983 return 0;
00984 }
00985
00986 #endif
00987
00988
00989
00990
00991 FARPROC MODULE_GetProcAddress(
00992 HMODULE hModule,
00993 LPCSTR function,
00994 WIN_BOOL snoop )
00995 {
00996 WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
00997
00998 FARPROC retproc;
00999
01000 #ifdef DEBUG_QTX_API
01001 if (HIWORD(function))
01002 fprintf(stderr,"XXX GetProcAddress(%08lx,%s)\n",(DWORD)hModule,function);
01003 else
01004 fprintf(stderr,"XXX GetProcAddress(%08lx,%p)\n",(DWORD)hModule,function);
01005 #endif
01006
01007
01008
01009
01010
01011 if (!wm) {
01012 SetLastError(ERROR_INVALID_HANDLE);
01013 return (FARPROC)0;
01014 }
01015 switch (wm->type)
01016 {
01017 case MODULE32_PE:
01018 retproc = PE_FindExportedFunction( wm, function, snoop );
01019 if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND);
01020 break;
01021 #ifdef HAVE_LIBDL
01022 case MODULE32_ELF:
01023 retproc = (FARPROC) dlsym( (void*) wm->module, function);
01024 if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND);
01025 return retproc;
01026 #endif
01027 default:
01028 ERR("wine_modref type %d not handled.\n",wm->type);
01029 SetLastError(ERROR_INVALID_HANDLE);
01030 return (FARPROC)0;
01031 }
01032
01033 #ifdef EMU_QTX_API
01034 if (HIWORD(function) && retproc){
01035
01036 #ifdef DEBUG_QTX_API
01037 #define DECL_COMPONENT(sname,name,type) \
01038 if(!strcmp(function,name)){ \
01039 fprintf(stderr,name "dispatcher catched -> %p\n",retproc); \
01040 real_ ## sname = retproc; retproc = fake_ ## sname; \
01041 }
01042 #include "qt_comp.h"
01043 #undef DECL_COMPONENT
01044 #endif
01045
01046 if(!strcmp(function,"theQuickTimeDispatcher")
01047
01048
01049 ){
01050 fprintf(stderr,"theQuickTimeDispatcher catched -> %p\n",retproc);
01051 report_entry = report_func;
01052 report_ret = report_func_ret;
01053 wrapper_target=(void(*)(void))retproc;
01054 retproc=(FARPROC)wrapper;
01055 }
01056
01057 }
01058 #endif
01059
01060 return retproc;
01061 }
01062
01063 static int acounter = 0;
01064 void CodecAlloc(void)
01065 {
01066 acounter++;
01067
01068 }
01069
01070 void CodecRelease(void)
01071 {
01072 acounter--;
01073
01074 if (acounter == 0)
01075 {
01076 for (;;)
01077 {
01078 modref_list* list = local_wm;
01079 if (!local_wm)
01080 break;
01081
01082 MODULE_FreeLibrary(list->wm);
01083 MODULE_RemoveFromList(list->wm);
01084 if (local_wm == NULL)
01085 my_garbagecollection();
01086 }
01087 }
01088 }