1 /***********************************************************
3 Win32 emulation code. Functions that emulate
4 responses from corresponding Win32 API calls.
5 Since we are not going to be able to load
6 virtually any DLL, we can only implement this
7 much, adding needed functions with each new codec.
9 Basic principle of implementation: it's not good
10 for DLL to know too much about its environment.
12 ************************************************************/
15 * Modified for use with MPlayer, detailed CVS changelog at
16 * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
27 //#define LOADLIB_TRY_NATIVE
31 #define PSEUDO_SCREEN_WIDTH /*640*/800
32 #define PSEUDO_SCREEN_HEIGHT /*480*/600
35 #include "wine/winbase.h"
36 #include "wine/winreg.h"
37 #include "wine/winnt.h"
38 #include "wine/winerror.h"
39 #include "wine/debugtools.h"
40 #include "wine/module.h"
41 #include "wine/winuser.h"
64 #include <sys/types.h>
67 #include <sys/timeb.h>
73 int vsscanf( const char *str, const char *format, va_list ap);
75 /* system has no vsscanf. try to provide one */
76 static int vsscanf( const char *str, const char *format, va_list ap)
78 long p1 = va_arg(ap, long);
79 long p2 = va_arg(ap, long);
80 long p3 = va_arg(ap, long);
81 long p4 = va_arg(ap, long);
82 long p5 = va_arg(ap, long);
83 return sscanf(str, format, p1, p2, p3, p4, p5);
87 static char* def_path = WIN32_PATH;
89 static void do_cpuid(unsigned int ax, unsigned int *regs)
93 "pushl %%ebx; pushl %%ecx; pushl %%edx;"
99 "popl %%edx; popl %%ecx; popl %%ebx;"
101 : "0" (ax), "S" (regs)
104 static unsigned int c_localcount_tsc()
116 static void c_longcount_tsc(long long* z)
121 "movl %%eax, %%ebx\n\t"
123 "movl %%eax, 0(%%ebx)\n\t"
124 "movl %%edx, 4(%%ebx)\n\t"
130 static unsigned int c_localcount_notsc()
135 gettimeofday(&tv, 0);
136 return limit*tv.tv_usec;
138 static void c_longcount_notsc(long long* z)
141 unsigned long long result;
145 gettimeofday(&tv, 0);
148 result+=limit*tv.tv_usec;
151 static unsigned int localcount_stub(void);
152 static void longcount_stub(long long*);
153 static unsigned int (*localcount)()=localcount_stub;
154 static void (*longcount)(long long*)=longcount_stub;
156 static pthread_mutex_t memmut;
158 static unsigned int localcount_stub(void)
160 unsigned int regs[4];
162 if ((regs[3] & 0x00000010) != 0)
164 localcount=c_localcount_tsc;
165 longcount=c_longcount_tsc;
169 localcount=c_localcount_notsc;
170 longcount=c_longcount_notsc;
174 static void longcount_stub(long long* z)
176 unsigned int regs[4];
178 if ((regs[3] & 0x00000010) != 0)
180 localcount=c_localcount_tsc;
181 longcount=c_longcount_tsc;
185 localcount=c_localcount_notsc;
186 longcount=c_longcount_notsc;
192 #include "../mp_msg.h"
194 int LOADER_DEBUG=1; // active only if compiled with -DDETAILED_OUT
195 //#define DETAILED_OUT
196 static inline void dbgprintf(char* fmt, ...)
204 f=fopen("./log", "a");
209 vfprintf(f, fmt, va);
223 // mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va);
231 char export_names[300][32]={
236 //#define min(x,y) ((x)<(y)?(x):(y))
238 void destroy_event(void* event);
241 typedef struct th_list_t{
244 struct th_list_t* next;
245 struct th_list_t* prev;
249 // have to be cleared by GARBAGE COLLECTOR
250 static unsigned char* heap=NULL;
251 static int heap_counter=0;
252 static tls_t* g_tls=NULL;
253 static th_list* list=NULL;
255 static void test_heap(void)
260 while(offset<heap_counter)
262 if(*(int*)(heap+offset)!=0x433476)
264 printf("Heap corruption at address %d\n", offset);
267 offset+=8+*(int*)(heap+offset+4);
269 for(;offset<min(offset+1000, 20000000); offset++)
270 if(heap[offset]!=0xCC)
272 printf("Free heap corruption at address %d\n", offset);
279 static void* my_mreq(int size, int to_zero)
283 if(test%10==0)printf("Memory: %d bytes allocated\n", heap_counter);
287 heap=malloc(20000000);
288 memset(heap, 0xCC,20000000);
292 printf("No enough memory\n");
295 if(heap_counter+size>20000000)
297 printf("No enough memory\n");
300 *(int*)(heap+heap_counter)=0x433476;
302 *(int*)(heap+heap_counter)=size;
304 printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size, heap_counter-8, heap_counter, heap_counter+size);
306 memset(heap+heap_counter, 0, size);
308 memset(heap+heap_counter, 0xcc, size); // make crash reproducable
310 return heap+heap_counter-size;
312 static int my_release(char* memory)
317 printf("ERROR: free(0)\n");
320 if(*(int*)(memory-8)!=0x433476)
322 printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
325 printf("Freed %d bytes of memory\n", *(int*)(memory-4));
326 // memset(memory-8, *(int*)(memory-4), 0xCC);
332 typedef struct alloc_header_t alloc_header;
333 struct alloc_header_t
335 // let's keep allocated data 16 byte aligned
347 static alloc_header* last_alloc = NULL;
348 static int alccnt = 0;
351 #define AREATYPE_CLIENT 0
352 #define AREATYPE_EVENT 1
353 #define AREATYPE_MUTEX 2
354 #define AREATYPE_COND 3
355 #define AREATYPE_CRITSECT 4
357 /* -- critical sections -- */
361 pthread_mutex_t mutex;
366 void* mreq_private(int size, int to_zero, int type);
367 void* mreq_private(int size, int to_zero, int type)
369 int nsize = size + sizeof(alloc_header);
370 alloc_header* header = (alloc_header* ) malloc(nsize);
374 memset(header, 0, nsize);
378 pthread_mutex_init(&memmut, NULL);
379 pthread_mutex_lock(&memmut);
383 pthread_mutex_lock(&memmut);
384 last_alloc->next = header; /* set next */
387 header->prev = last_alloc;
391 pthread_mutex_unlock(&memmut);
393 header->deadbeef = 0xdeadbeef;
397 //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt);
401 static int my_release(void* memory)
403 alloc_header* header = (alloc_header*) memory - 1;
405 alloc_header* prevmem;
406 alloc_header* nextmem;
411 if (header->deadbeef != (long) 0xdeadbeef)
413 dbgprintf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt);
417 pthread_mutex_lock(&memmut);
422 destroy_event(memory);
425 pthread_cond_destroy((pthread_cond_t*)memory);
428 pthread_mutex_destroy((pthread_mutex_t*)memory);
430 case AREATYPE_CRITSECT:
431 pthread_mutex_destroy(&((struct CRITSECT*)memory)->mutex);
434 //memset(memory, 0xcc, header->size);
438 header->deadbeef = 0;
439 prevmem = header->prev;
440 nextmem = header->next;
443 prevmem->next = nextmem;
445 nextmem->prev = prevmem;
447 if (header == last_alloc)
448 last_alloc = prevmem;
453 pthread_mutex_unlock(&memmut);
455 pthread_mutex_destroy(&memmut);
457 //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt);
462 //memset(header + 1, 0xcc, header->size);
468 static inline void* my_mreq(int size, int to_zero)
470 return mreq_private(size, to_zero, AREATYPE_CLIENT);
473 static int my_size(void* memory)
475 if(!memory) return 0;
476 return ((alloc_header*)memory)[-1].size;
479 static void* my_realloc(void* memory, int size)
484 return my_mreq(size, 0);
485 osize = my_size(memory);
488 ans = my_mreq(size, 0);
489 memcpy(ans, memory, osize);
497 * WINE API - native implementation for several win32 libraries
501 static int WINAPI ext_unknown()
503 printf("Unknown func called\n");
507 static int WINAPI expGetVolumeInformationA( const char *root, char *label,
508 unsigned int label_len, unsigned int *serial,
509 unsigned int *filename_len,unsigned int *flags,
510 char *fsname, unsigned int fsname_len )
512 dbgprintf("GetVolumeInformationA( %s, 0x%x, %ld, 0x%x, 0x%x, 0x%x, 0x%x, %ld) => 1\n",
513 root,label,label_len,serial,filename_len,flags,fsname,fsname_len);
514 //hack Do not return any real data - do nothing
518 static unsigned int WINAPI expGetDriveTypeA( const char *root )
520 dbgprintf("GetDriveTypeA( %s ) => %d\n",root,DRIVE_FIXED);
521 // hack return as Fixed Drive Type
525 static unsigned int WINAPI expGetLogicalDriveStringsA( unsigned int len, char *buffer )
527 dbgprintf("GetLogicalDriveStringsA(%d, 0x%x) => 4\n",len,buffer);
528 // hack only have one drive c:\ in this hack
534 return 4; // 1 drive * 4 bytes (includes null)
538 static int WINAPI expIsBadWritePtr(void* ptr, unsigned int count)
540 int result = (count == 0 || ptr != 0) ? 0 : 1;
541 dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr, count, result);
544 static int WINAPI expIsBadReadPtr(void* ptr, unsigned int count)
546 int result = (count == 0 || ptr != 0) ? 0 : 1;
547 dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr, count, result);
550 static int WINAPI expDisableThreadLibraryCalls(int module)
552 dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module);
556 static HMODULE WINAPI expGetDriverModuleHandle(DRVR* pdrv)
562 result=pdrv->hDriverModule;
563 dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv, result);
567 #define MODULE_HANDLE_kernel32 ((HMODULE)0x120)
568 #define MODULE_HANDLE_user32 ((HMODULE)0x121)
570 #define MODULE_HANDLE_wininet ((HMODULE)0x122)
571 #define MODULE_HANDLE_ddraw ((HMODULE)0x123)
572 #define MODULE_HANDLE_advapi32 ((HMODULE)0x124)
574 #define MODULE_HANDLE_comdlg32 ((HMODULE)0x125)
575 #define MODULE_HANDLE_msvcrt ((HMODULE)0x126)
576 #define MODULE_HANDLE_ole32 ((HMODULE)0x127)
577 #define MODULE_HANDLE_winmm ((HMODULE)0x128)
579 static HMODULE WINAPI expGetModuleHandleA(const char* name)
591 wm=MODULE_FindModule(name);
594 result=(HMODULE)(wm->module);
598 if(name && (strcasecmp(name, "kernel32")==0 || !strcasecmp(name, "kernel32.dll")))
599 result=MODULE_HANDLE_kernel32;
601 if(name && strcasecmp(name, "user32")==0)
602 result=MODULE_HANDLE_user32;
605 dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name, result);
609 static void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize,
610 void* lpStartAddress, void* lpParameter,
611 long dwFlags, long* dwThreadId)
614 // printf("CreateThread:");
615 pth = (pthread_t*) my_mreq(sizeof(pthread_t), 0);
616 pthread_create(pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter);
618 printf( "WARNING: CreateThread flags not supported\n");
620 *dwThreadId=(long)pth;
623 list=my_mreq(sizeof(th_list), 1);
624 list->next=list->prev=NULL;
628 list->next=my_mreq(sizeof(th_list), 0);
629 list->next->prev=list;
630 list->next->next=NULL;
634 dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
635 pSecAttr, dwStackSize, lpStartAddress, lpParameter, dwFlags, dwThreadId, pth);
650 struct mutex_list_t* next;
651 struct mutex_list_t* prev;
653 typedef struct mutex_list_t mutex_list;
654 static mutex_list* mlist=NULL;
656 void destroy_event(void* event)
658 mutex_list* pp=mlist;
659 // printf("garbage collector: destroy_event(%x)\n", event);
662 if(pp==(mutex_list*)event)
665 pp->next->prev=pp->prev;
667 pp->prev->next=pp->next;
668 if(mlist==(mutex_list*)event)
674 printf("%x => ", pp);
685 static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
686 char bInitialState, const char* name)
695 printf("%x => ", pp);
702 mutex_list* pp=mlist;
706 if((strcmp(pp->name, name)==0) && (pp->type==0))
708 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
709 pSecAttr, bManualReset, bInitialState, name, name, pp->pm);
712 }while((pp=pp->prev) != NULL);
714 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
715 pthread_mutex_init(pm, NULL);
716 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
717 pthread_cond_init(pc, NULL);
720 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
721 mlist->next=mlist->prev=NULL;
725 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
726 mlist->next->prev=mlist;
727 mlist->next->next=NULL;
730 mlist->type=0; /* Type Event */
733 mlist->state=bInitialState;
734 mlist->reset=bManualReset;
736 strncpy(mlist->name, name, 127);
740 dbgprintf("ERROR::: CreateEventA failure\n");
743 pthread_mutex_lock(pm);
746 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
747 pSecAttr, bManualReset, bInitialState, name, name, mlist);
749 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
750 pSecAttr, bManualReset, bInitialState, mlist);
754 static void* WINAPI expSetEvent(void* event)
756 mutex_list *ml = (mutex_list *)event;
757 dbgprintf("SetEvent(%x) => 0x1\n", event);
758 pthread_mutex_lock(ml->pm);
759 if (ml->state == 0) {
761 pthread_cond_signal(ml->pc);
763 pthread_mutex_unlock(ml->pm);
767 static void* WINAPI expResetEvent(void* event)
769 mutex_list *ml = (mutex_list *)event;
770 dbgprintf("ResetEvent(0x%x) => 0x1\n", event);
771 pthread_mutex_lock(ml->pm);
773 pthread_mutex_unlock(ml->pm);
778 static void* WINAPI expWaitForSingleObject(void* object, int duration)
780 mutex_list *ml = (mutex_list *)object;
781 // FIXME FIXME FIXME - this value is sometime unititialize !!!
782 int ret = WAIT_FAILED;
783 mutex_list* pp=mlist;
784 if(object == (void*)0xcfcf9898)
787 From GetCurrentThread() documentation:
788 A pseudo handle is a special constant that is interpreted as the current thread handle. The calling thread can use this handle to specify itself whenever a thread handle is required. Pseudo handles are not inherited by child processes.
790 This handle has the maximum possible access to the thread object. For systems that support security descriptors, this is the maximum access allowed by the security descriptor for the calling process. For systems that do not support security descriptors, this is THREAD_ALL_ACCESS.
792 The function cannot be used by one thread to create a handle that can be used by other threads to refer to the first thread. The handle is always interpreted as referring to the thread that is using it. A thread can create a "real" handle to itself that can be used by other threads, or inherited by other processes, by specifying the pseudo handle as the source handle in a call to the DuplicateHandle function.
794 dbgprintf("WaitForSingleObject(thread_handle) called\n");
795 return (void*)WAIT_FAILED;
797 dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object, duration);
799 // loop below was slightly fixed - its used just for checking if
800 // this object really exists in our list
803 while (pp && (pp->pm != ml->pm))
806 dbgprintf("WaitForSingleObject: NotFound\n");
810 pthread_mutex_lock(ml->pm);
814 if (duration == 0) { /* Check Only */
815 if (ml->state == 1) ret = WAIT_FAILED;
816 else ret = WAIT_OBJECT_0;
818 if (duration == -1) { /* INFINITE */
820 pthread_cond_wait(ml->pc,ml->pm);
825 if (duration > 0) { /* Timed Wait */
826 struct timespec abstime;
828 gettimeofday(&now, 0);
829 abstime.tv_sec = now.tv_sec + (now.tv_usec+duration)/1000000;
830 abstime.tv_nsec = ((now.tv_usec+duration)%1000000)*1000;
832 ret=pthread_cond_timedwait(ml->pc,ml->pm,&abstime);
833 if (ret == ETIMEDOUT) ret = WAIT_TIMEOUT;
834 else ret = WAIT_OBJECT_0;
839 case 1: /* Semaphore */
841 if(ml->semaphore==0) ret = WAIT_FAILED;
847 if (duration == -1) {
848 if (ml->semaphore==0)
849 pthread_cond_wait(ml->pc,ml->pm);
854 pthread_mutex_unlock(ml->pm);
856 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object,duration,ml,ret);
861 static void* WINAPI expWaitForMultipleObjects(int count, const void** objects,
862 int WaitAll, int duration)
868 dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
869 count, objects, WaitAll, duration);
871 for (i = 0; i < count; i++)
873 object = (void *)objects[i];
874 ret = expWaitForSingleObject(object, duration);
876 dbgprintf("WaitAll flag not yet supported...\n");
883 static void WINAPI expExitThread(int retcode)
885 dbgprintf("ExitThread(%d)\n", retcode);
886 pthread_exit(&retcode);
889 static HANDLE WINAPI expCreateMutexA(void *pSecAttr,
890 char bInitialOwner, const char *name)
892 HANDLE mlist = (HANDLE)expCreateEventA(pSecAttr, 0, 0, name);
895 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
896 pSecAttr, bInitialOwner, name, mlist);
898 dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
899 pSecAttr, bInitialOwner, mlist);
901 /* 10l to QTX, if CreateMutex returns a real mutex, WaitForSingleObject
902 waits for ever, else it works ;) */
907 static int WINAPI expReleaseMutex(HANDLE hMutex)
909 dbgprintf("ReleaseMutex(%x) => 1\n", hMutex);
910 /* FIXME:XXX !! not yet implemented */
915 static int pf_set = 0;
916 static BYTE PF[64] = {0,};
918 static void DumpSystemInfo(const SYSTEM_INFO* si)
920 dbgprintf(" Processor architecture %d\n", si->u.s.wProcessorArchitecture);
921 dbgprintf(" Page size: %d\n", si->dwPageSize);
922 dbgprintf(" Minimum app address: %d\n", si->lpMinimumApplicationAddress);
923 dbgprintf(" Maximum app address: %d\n", si->lpMaximumApplicationAddress);
924 dbgprintf(" Active processor mask: 0x%x\n", si->dwActiveProcessorMask);
925 dbgprintf(" Number of processors: %d\n", si->dwNumberOfProcessors);
926 dbgprintf(" Processor type: 0x%x\n", si->dwProcessorType);
927 dbgprintf(" Allocation granularity: 0x%x\n", si->dwAllocationGranularity);
928 dbgprintf(" Processor level: 0x%x\n", si->wProcessorLevel);
929 dbgprintf(" Processor revision: 0x%x\n", si->wProcessorRevision);
932 static void WINAPI expGetSystemInfo(SYSTEM_INFO* si)
934 /* FIXME: better values for the two entries below... */
935 static int cache = 0;
936 static SYSTEM_INFO cachedsi;
937 unsigned int regs[4];
938 dbgprintf("GetSystemInfo(%p) =>\n", si);
941 memcpy(si,&cachedsi,sizeof(*si));
945 memset(PF,0,sizeof(PF));
948 cachedsi.u.s.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
949 cachedsi.dwPageSize = getpagesize();
951 /* FIXME: better values for the two entries below... */
952 cachedsi.lpMinimumApplicationAddress = (void *)0x00000000;
953 cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF;
954 cachedsi.dwActiveProcessorMask = 1;
955 cachedsi.dwNumberOfProcessors = 1;
956 cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
957 cachedsi.dwAllocationGranularity = 0x10000;
958 cachedsi.wProcessorLevel = 5; /* pentium */
959 cachedsi.wProcessorRevision = 0x0101;
962 /* mplayer's way to detect PF's */
964 #include "../cpudetect.h"
965 extern CpuCaps gCpuCaps;
968 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
970 PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
971 if (gCpuCaps.has3DNow)
972 PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
974 if (gCpuCaps.cpuType == 4)
976 cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
977 cachedsi.wProcessorLevel = 4;
979 else if (gCpuCaps.cpuType >= 5)
981 cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
982 cachedsi.wProcessorLevel = 5;
986 cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
987 cachedsi.wProcessorLevel = 3;
989 cachedsi.wProcessorRevision = gCpuCaps.cpuStepping;
990 cachedsi.dwNumberOfProcessors = 1; /* hardcoded */
994 /* disable cpuid based detection (mplayer's cpudetect.c does this - see above) */
996 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__svr4__) || defined(__DragonFly__)
998 switch ((regs[0] >> 8) & 0xf) { // cpu family
999 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1000 cachedsi.wProcessorLevel= 3;
1002 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1003 cachedsi.wProcessorLevel= 4;
1005 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1006 cachedsi.wProcessorLevel= 5;
1008 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1009 cachedsi.wProcessorLevel= 5;
1011 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1012 cachedsi.wProcessorLevel= 5;
1015 cachedsi.wProcessorRevision = regs[0] & 0xf; // stepping
1016 if (regs[3] & (1 << 8))
1017 PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
1018 if (regs[3] & (1 << 23))
1019 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
1020 if (regs[3] & (1 << 25))
1021 PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
1022 if (regs[3] & (1 << 31))
1023 PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
1024 cachedsi.dwNumberOfProcessors=1;
1026 #endif /* MPLAYER */
1028 /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
1029 fdiv_bug and fpu emulation flags -- alex/MPlayer */
1034 FILE *f = fopen ("/proc/cpuinfo", "r");
1038 while (fgets(line,200,f)!=NULL) {
1041 /* NOTE: the ':' is the only character we can rely on */
1042 if (!(value = strchr(line,':')))
1044 /* terminate the valuename */
1046 /* skip any leading spaces */
1047 while (*value==' ') value++;
1048 if ((s=strchr(value,'\n')))
1052 if (!lstrncmpiA(line, "cpu family",strlen("cpu family"))) {
1053 if (isdigit (value[0])) {
1054 switch (value[0] - '0') {
1055 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1056 cachedsi.wProcessorLevel= 3;
1058 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1059 cachedsi.wProcessorLevel= 4;
1061 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1062 cachedsi.wProcessorLevel= 5;
1064 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1065 cachedsi.wProcessorLevel= 5;
1067 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1068 cachedsi.wProcessorLevel= 5;
1072 /* set the CPU type of the current processor */
1073 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
1076 /* old 2.0 method */
1077 if (!lstrncmpiA(line, "cpu",strlen("cpu"))) {
1078 if ( isdigit (value[0]) && value[1] == '8' &&
1079 value[2] == '6' && value[3] == 0
1081 switch (value[0] - '0') {
1082 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1083 cachedsi.wProcessorLevel= 3;
1085 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1086 cachedsi.wProcessorLevel= 4;
1088 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1089 cachedsi.wProcessorLevel= 5;
1091 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1092 cachedsi.wProcessorLevel= 5;
1094 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1095 cachedsi.wProcessorLevel= 5;
1099 /* set the CPU type of the current processor */
1100 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
1103 if (!lstrncmpiA(line,"fdiv_bug",strlen("fdiv_bug"))) {
1104 if (!lstrncmpiA(value,"yes",3))
1105 PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE;
1109 if (!lstrncmpiA(line,"fpu",strlen("fpu"))) {
1110 if (!lstrncmpiA(value,"no",2))
1111 PF[PF_FLOATING_POINT_EMULATED] = TRUE;
1115 if (!lstrncmpiA(line,"processor",strlen("processor"))) {
1116 /* processor number counts up...*/
1119 if (sscanf(value,"%d",&x))
1120 if (x+1>cachedsi.dwNumberOfProcessors)
1121 cachedsi.dwNumberOfProcessors=x+1;
1123 /* Create a new processor subkey on a multiprocessor
1126 sprintf(buf,"%d",x);
1128 if (!lstrncmpiA(line,"stepping",strlen("stepping"))) {
1131 if (sscanf(value,"%d",&x))
1132 cachedsi.wProcessorRevision = x;
1135 ( (!lstrncmpiA(line,"flags",strlen("flags")))
1136 || (!lstrncmpiA(line,"features",strlen("features"))) )
1138 if (strstr(value,"cx8"))
1139 PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
1140 if (strstr(value,"mmx"))
1141 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
1142 if (strstr(value,"tsc"))
1143 PF[PF_RDTSC_INSTRUCTION_AVAILABLE] = TRUE;
1144 if (strstr(value,"xmm"))
1145 PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
1146 if (strstr(value,"3dnow"))
1147 PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
1152 * ad hoc fix for smp machines.
1153 * some problems on WaitForSingleObject,CreateEvent,SetEvent
1154 * CreateThread ...etc..
1157 cachedsi.dwNumberOfProcessors=1;
1159 #endif /* __linux__ */
1161 memcpy(si,&cachedsi,sizeof(*si));
1165 // avoid undefined expGetSystemInfo
1166 static WIN_BOOL WINAPI expIsProcessorFeaturePresent(DWORD v)
1168 WIN_BOOL result = 0;
1172 expGetSystemInfo(&si);
1174 if(v<64) result=PF[v];
1175 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v, result);
1180 static long WINAPI expGetVersion()
1182 dbgprintf("GetVersion() => 0xC0000004\n");
1183 return 0xC0000004;//Windows 95
1186 static HANDLE WINAPI expHeapCreate(long flags, long init_size, long max_size)
1188 // printf("HeapCreate:");
1191 result=(HANDLE)my_mreq(0x110000, 0);
1193 result=(HANDLE)my_mreq((init_size + 0xfff) & 0x7ffff000 , 0);
1194 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags, init_size, max_size, result);
1198 // this is another dirty hack
1199 // VP31 is releasing one allocated Heap chunk twice
1200 // we will silently ignore this second call...
1201 static void* heapfreehack = 0;
1202 static int heapfreehackshown = 0;
1203 //extern void trapbug(void);
1204 static void* WINAPI expHeapAlloc(HANDLE heap, int flags, int size)
1208 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1209 HeapAlloc returns area larger than size argument :-/
1211 actually according to M$ Doc HeapCreate size should be rounded
1212 to page boundaries thus we should simulate this
1214 //if (size == 22276) trapbug();
1215 z=my_mreq((size + 0xfff) & 0x7ffff000, (flags & HEAP_ZERO_MEMORY));
1217 printf("HeapAlloc failure\n");
1218 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap, flags, size, z);
1219 heapfreehack = 0; // reset
1222 static long WINAPI expHeapDestroy(void* heap)
1224 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap);
1229 static long WINAPI expHeapFree(HANDLE heap, DWORD dwFlags, LPVOID lpMem)
1231 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap, dwFlags, lpMem);
1232 if (heapfreehack != lpMem && lpMem != (void*)0xffffffff
1233 && lpMem != (void*)0xbdbdbdbd)
1234 // 0xbdbdbdbd is for i263_drv.drv && libefence
1235 // it seems to be reading from relased memory
1236 // EF_PROTECT_FREE doens't show any probleme
1240 if (!heapfreehackshown++)
1241 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem);
1243 heapfreehack = lpMem;
1246 static long WINAPI expHeapSize(int heap, int flags, void* pointer)
1248 long result=my_size(pointer);
1249 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap, flags, pointer, result);
1252 static void* WINAPI expHeapReAlloc(HANDLE heap,int flags,void *lpMem,int size)
1254 long orgsize = my_size(lpMem);
1255 dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize,size);
1256 return my_realloc(lpMem, size);
1258 static long WINAPI expGetProcessHeap(void)
1260 dbgprintf("GetProcessHeap() => 1\n");
1263 static void* WINAPI expVirtualAlloc(void* v1, long v2, long v3, long v4)
1265 void* z = VirtualAlloc(v1, v2, v3, v4);
1267 printf("VirtualAlloc failure\n");
1268 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1,v2,v3,v4, z);
1271 static int WINAPI expVirtualFree(void* v1, int v2, int v3)
1273 int result = VirtualFree(v1,v2,v3);
1274 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1,v2,v3, result);
1278 /* we're building a table of critical sections. cs_win pointer uses the DLL
1279 cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1280 struct critsecs_list_t
1282 CRITICAL_SECTION *cs_win;
1283 struct CRITSECT *cs_unix;
1286 /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1287 #undef CRITSECS_NEWTYPE
1288 //#define CRITSECS_NEWTYPE 1
1290 #ifdef CRITSECS_NEWTYPE
1291 /* increased due to ucod needs more than 32 entries */
1292 /* and 64 should be enough for everything */
1293 #define CRITSECS_LIST_MAX 64
1294 static struct critsecs_list_t critsecs_list[CRITSECS_LIST_MAX];
1296 static int critsecs_get_pos(CRITICAL_SECTION *cs_win)
1300 for (i=0; i < CRITSECS_LIST_MAX; i++)
1301 if (critsecs_list[i].cs_win == cs_win)
1306 static int critsecs_get_unused(void)
1310 for (i=0; i < CRITSECS_LIST_MAX; i++)
1311 if (critsecs_list[i].cs_win == NULL)
1316 struct CRITSECT *critsecs_get_unix(CRITICAL_SECTION *cs_win)
1320 for (i=0; i < CRITSECS_LIST_MAX; i++)
1321 if (critsecs_list[i].cs_win == cs_win && critsecs_list[i].cs_unix)
1322 return(critsecs_list[i].cs_unix);
1327 static void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c)
1329 dbgprintf("InitializeCriticalSection(0x%x)\n", c);
1330 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1332 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1333 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1336 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1337 #ifdef CRITSECS_NEWTYPE
1339 struct CRITSECT *cs;
1340 int i = critsecs_get_unused();
1344 printf("InitializeCriticalSection(%p) - no more space in list\n", c);
1347 dbgprintf("got unused space at %d\n", i);
1348 cs = malloc(sizeof(struct CRITSECT));
1351 printf("InitializeCriticalSection(%p) - out of memory\n", c);
1354 pthread_mutex_init(&cs->mutex, NULL);
1356 critsecs_list[i].cs_win = c;
1357 critsecs_list[i].cs_unix = cs;
1358 dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1363 struct CRITSECT* cs = mreq_private(sizeof(struct CRITSECT) + sizeof(CRITICAL_SECTION),
1364 0, AREATYPE_CRITSECT);
1365 pthread_mutex_init(&cs->mutex, NULL);
1367 cs->deadbeef = 0xdeadbeef;
1374 static void WINAPI expEnterCriticalSection(CRITICAL_SECTION* c)
1376 #ifdef CRITSECS_NEWTYPE
1377 struct CRITSECT* cs = critsecs_get_unix(c);
1379 struct CRITSECT* cs = (*(struct CRITSECT**)c);
1381 dbgprintf("EnterCriticalSection(0x%x) %p\n",c, cs);
1384 dbgprintf("entered uninitialized critisec!\n");
1385 expInitializeCriticalSection(c);
1386 #ifdef CRITSECS_NEWTYPE
1387 cs=critsecs_get_unix(c);
1389 cs = (*(struct CRITSECT**)c);
1391 dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c);
1394 if(cs->id==pthread_self())
1396 pthread_mutex_lock(&(cs->mutex));
1398 cs->id=pthread_self();
1401 static void WINAPI expLeaveCriticalSection(CRITICAL_SECTION* c)
1403 #ifdef CRITSECS_NEWTYPE
1404 struct CRITSECT* cs = critsecs_get_unix(c);
1406 struct CRITSECT* cs = (*(struct CRITSECT**)c);
1408 // struct CRITSECT* cs=(struct CRITSECT*)c;
1409 dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c, cs);
1412 dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c);
1418 pthread_mutex_unlock(&(cs->mutex));
1421 dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c);
1425 static void expfree(void* mem); /* forward declaration */
1427 static void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c)
1429 #ifdef CRITSECS_NEWTYPE
1430 struct CRITSECT* cs = critsecs_get_unix(c);
1432 struct CRITSECT* cs= (*(struct CRITSECT**)c);
1434 // struct CRITSECT* cs=(struct CRITSECT*)c;
1435 dbgprintf("DeleteCriticalSection(0x%x)\n",c);
1439 dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c);
1445 dbgprintf("Win32 Warning: Deleting unlocked Critical Section %p!!\n", c);
1446 pthread_mutex_unlock(&(cs->mutex));
1450 pthread_mutex_destroy(&(cs->mutex));
1451 // released by GarbageCollector in my_relase otherwise
1454 #ifdef CRITSECS_NEWTYPE
1456 int i = critsecs_get_pos(c);
1460 printf("DeleteCriticalSection(%p) error (critsec not found)\n", c);
1464 critsecs_list[i].cs_win = NULL;
1465 expfree(critsecs_list[i].cs_unix);
1466 critsecs_list[i].cs_unix = NULL;
1467 dbgprintf("DeleteCriticalSection -> itemno=%d\n", i);
1472 static int WINAPI expGetCurrentThreadId()
1474 dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1475 return pthread_self();
1477 static int WINAPI expGetCurrentProcess()
1479 dbgprintf("GetCurrentProcess() => %d\n", getpid());
1484 // this version is required for Quicktime codecs (.qtx/.qts) to work.
1485 // (they assume some pointers at FS: segment)
1487 extern void* fs_seg;
1489 //static int tls_count;
1490 static int tls_use_map[64];
1491 static int WINAPI expTlsAlloc()
1495 if(tls_use_map[i]==0)
1498 dbgprintf("TlsAlloc() => %d\n",i);
1501 dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1505 //static int WINAPI expTlsSetValue(DWORD index, void* value)
1506 static int WINAPI expTlsSetValue(int index, void* value)
1508 dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index,value);
1509 // if((index<0) || (index>64))
1512 *(void**)((char*)fs_seg+0x88+4*index) = value;
1516 static void* WINAPI expTlsGetValue(DWORD index)
1518 dbgprintf("TlsGetValue(%d)\n",index);
1519 // if((index<0) || (index>64))
1520 if((index>=64)) return NULL;
1521 return *(void**)((char*)fs_seg+0x88+4*index);
1524 static int WINAPI expTlsFree(int idx)
1526 int index = (int) idx;
1527 dbgprintf("TlsFree(%d)\n",index);
1528 if((index<0) || (index>64))
1530 tls_use_map[index]=0;
1542 static void* WINAPI expTlsAlloc()
1546 g_tls=my_mreq(sizeof(tls_t), 0);
1547 g_tls->next=g_tls->prev=NULL;
1551 g_tls->next=my_mreq(sizeof(tls_t), 0);
1552 g_tls->next->prev=g_tls;
1553 g_tls->next->next=NULL;
1556 dbgprintf("TlsAlloc() => 0x%x\n", g_tls);
1558 g_tls->value=0; /* XXX For Divx.dll */
1562 static int WINAPI expTlsSetValue(void* idx, void* value)
1564 tls_t* index = (tls_t*) idx;
1573 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index, value, result );
1576 static void* WINAPI expTlsGetValue(void* idx)
1578 tls_t* index = (tls_t*) idx;
1583 result=index->value;
1584 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index, result);
1587 static int WINAPI expTlsFree(void* idx)
1589 tls_t* index = (tls_t*) idx;
1596 index->next->prev=index->prev;
1598 index->prev->next=index->next;
1600 g_tls = index->prev;
1601 my_release((void*)index);
1604 dbgprintf("TlsFree(index 0x%x) => %d\n", index, result);
1609 static void* WINAPI expLocalAlloc(int flags, int size)
1611 void* z = my_mreq(size, (flags & GMEM_ZEROINIT));
1613 printf("LocalAlloc() failed\n");
1614 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z);
1618 static void* WINAPI expLocalReAlloc(int handle,int size, int flags)
1624 if (flags & LMEM_MODIFY) {
1625 dbgprintf("LocalReAlloc MODIFY\n");
1626 return (void *)handle;
1628 oldsize = my_size((void *)handle);
1629 newpointer = my_realloc((void *)handle,size);
1630 dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle,size,oldsize, flags,newpointer);
1635 static void* WINAPI expLocalLock(void* z)
1637 dbgprintf("LocalLock(0x%x) => 0x%x\n", z, z);
1641 static void* WINAPI expGlobalAlloc(int flags, int size)
1644 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size, flags);
1646 z=my_mreq(size, (flags & GMEM_ZEROINIT));
1647 //z=calloc(size, 1);
1650 printf("GlobalAlloc() failed\n");
1651 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z);
1654 static void* WINAPI expGlobalLock(void* z)
1656 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z, z);
1659 // pvmjpg20 - but doesn't work anyway
1660 static int WINAPI expGlobalSize(void* amem)
1664 alloc_header* header = last_alloc;
1665 alloc_header* mem = (alloc_header*) amem - 1;
1668 pthread_mutex_lock(&memmut);
1671 if (header->deadbeef != 0xdeadbeef)
1673 dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt);
1679 size = header->size;
1683 header = header->prev;
1685 pthread_mutex_unlock(&memmut);
1688 dbgprintf("GlobalSize(0x%x)\n", amem);
1692 static int WINAPI expLoadIconA( long hinstance, char *name )
1694 dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance,name);
1698 static int WINAPI expLoadStringA(long instance, long id, void* buf, long size)
1700 int result=LoadStringA(instance, id, buf, size);
1702 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1703 instance, id, buf, size, result, buf);
1705 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1706 // instance, id, buf, size, result);
1710 static long WINAPI expMultiByteToWideChar(long v1, long v2, char* s1, long siz1, short* s2, int siz2)
1719 if(siz1>siz2/2)siz1=siz2/2;
1720 for(i=1; i<=siz1; i++)
1730 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1731 "size %d, dest buffer 0x%x, dest size %d) => %d\n",
1732 v1, v2, s1, s1, siz1, s2, siz2, result);
1734 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1735 "size %d, dest buffer 0x%x, dest size %d) =>\n",
1736 v1, v2, siz1, s2, siz2, result);
1739 static void wch_print(const short* str)
1741 dbgprintf(" src: ");
1742 while(*str)dbgprintf("%c", *str++);
1745 static long WINAPI expWideCharToMultiByte(long v1, long v2, short* s1, long siz1,
1746 char* s2, int siz2, char* c3, int* siz3)
1749 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1750 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1, v2, s1, siz1, s2, siz2, c3, siz3);
1751 result=WideCharToMultiByte(v1, v2, s1, siz1, s2, siz2, c3, siz3);
1752 dbgprintf("=> %d\n", result);
1753 //if(s1)wch_print(s1);
1754 if(s2)dbgprintf(" dest: %s\n", s2);
1757 static long WINAPI expGetVersionExA(OSVERSIONINFOA* c)
1759 dbgprintf("GetVersionExA(0x%x) => 1\n");
1760 c->dwOSVersionInfoSize=sizeof(*c);
1761 c->dwMajorVersion=4;
1762 c->dwMinorVersion=0;
1763 c->dwBuildNumber=0x4000457;
1765 // leave it here for testing win9x-only codecs
1766 c->dwPlatformId=VER_PLATFORM_WIN32_WINDOWS;
1767 strcpy(c->szCSDVersion, " B");
1769 c->dwPlatformId=VER_PLATFORM_WIN32_NT; // let's not make DLL assume that it can read CR* registers
1770 strcpy(c->szCSDVersion, "Service Pack 3");
1772 dbgprintf(" Major version: 4\n Minor version: 0\n Build number: 0x4000457\n"
1773 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 3'\n");
1776 static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count,
1777 long max_count, char* name)
1779 pthread_mutex_t *pm;
1783 printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1787 printf("%p => ", pp);
1794 mutex_list* pp=mlist;
1798 if((strcmp(pp->name, name)==0) && (pp->type==1))
1800 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1801 v1, init_count, max_count, name, name, mlist);
1802 return (HANDLE)mlist;
1804 }while((pp=pp->prev) != NULL);
1806 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
1807 pthread_mutex_init(pm, NULL);
1808 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
1809 pthread_cond_init(pc, NULL);
1812 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1813 mlist->next=mlist->prev=NULL;
1817 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1818 mlist->next->prev=mlist;
1819 mlist->next->next=NULL;
1821 // printf("new semaphore %p\n", mlist);
1823 mlist->type=1; /* Type Semaphore */
1828 mlist->semaphore=init_count;
1830 strncpy(mlist->name, name, 64);
1834 dbgprintf("ERROR::: CreateSemaphoreA failure\n");
1836 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1837 v1, init_count, max_count, name, name, mlist);
1839 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1840 v1, init_count, max_count, mlist);
1841 return (HANDLE)mlist;
1844 static long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count)
1846 // The state of a semaphore object is signaled when its count
1847 // is greater than zero and nonsignaled when its count is equal to zero
1848 // Each time a waiting thread is released because of the semaphore's signaled
1849 // state, the count of the semaphore is decreased by one.
1850 mutex_list *ml = (mutex_list *)hsem;
1852 pthread_mutex_lock(ml->pm);
1853 if (prev_count != 0) *prev_count = ml->semaphore;
1854 if (ml->semaphore == 0) pthread_cond_signal(ml->pc);
1855 ml->semaphore += increment;
1856 pthread_mutex_unlock(ml->pm);
1857 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1858 hsem, increment, prev_count);
1863 static long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
1865 long result=RegOpenKeyExA(key, subkey, reserved, access, newkey);
1866 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
1867 key, subkey, reserved, access, newkey, result);
1868 if(newkey)dbgprintf(" New key: 0x%x\n", *newkey);
1871 static long WINAPI expRegCloseKey(long key)
1873 long result=RegCloseKey(key);
1874 dbgprintf("RegCloseKey(0x%x) => %d\n", key, result);
1877 static long WINAPI expRegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count)
1879 long result=RegQueryValueExA(key, value, reserved, type, data, count);
1880 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
1881 " => 0x%x\n", key, value, reserved, data, count, result);
1882 if(data && count)dbgprintf(" read %d bytes: '%s'\n", *count, data);
1886 //from wine source dlls/advapi32/registry.c
1887 static long WINAPI expRegCreateKeyA(long hkey, const char* name, int *retkey)
1889 dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey,name,retkey);
1890 return RegCreateKeyExA( hkey, name, 0, NULL,REG_OPTION_NON_VOLATILE,
1891 KEY_ALL_ACCESS , NULL, retkey, NULL );
1894 static long WINAPI expRegCreateKeyExA(long key, const char* name, long reserved,
1895 void* classs, long options, long security,
1896 void* sec_attr, int* newkey, int* status)
1898 long result=RegCreateKeyExA(key, name, reserved, classs, options, security, sec_attr, newkey, status);
1899 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
1900 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
1901 key, name, name, reserved, classs, options, security, sec_attr, newkey, status, result);
1902 if(!result && newkey) dbgprintf(" New key: 0x%x\n", *newkey);
1903 if(!result && status) dbgprintf(" New key status: 0x%x\n", *status);
1906 static long WINAPI expRegSetValueExA(long key, const char* name, long v1, long v2, void* data, long size)
1908 long result=RegSetValueExA(key, name, v1, v2, data, size);
1909 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
1910 key, name, v1, v2, data, *(int*)data, data, size, result);
1914 static long WINAPI expRegOpenKeyA (long hKey, LPCSTR lpSubKey, int* phkResult)
1916 long result=RegOpenKeyExA(hKey, lpSubKey, 0, 0, phkResult);
1917 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
1918 hKey, lpSubKey, phkResult, result);
1919 if(!result && phkResult) dbgprintf(" New key: 0x%x\n", *phkResult);
1923 static DWORD WINAPI expRegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count,
1924 LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count)
1926 return RegEnumValueA(hkey, index, value, val_count,
1927 reserved, type, data, count);
1930 static DWORD WINAPI expRegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName,
1931 LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass,
1932 LPFILETIME lpftLastWriteTime)
1934 return RegEnumKeyExA(hKey, dwIndex, lpName, lpcbName, lpReserved, lpClass,
1935 lpcbClass, lpftLastWriteTime);
1938 static long WINAPI expQueryPerformanceCounter(long long* z)
1941 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z, *z);
1946 * dummy function RegQueryInfoKeyA(), required by vss codecs
1948 static DWORD WINAPI expRegQueryInfoKeyA( HKEY hkey, LPSTR class, LPDWORD class_len, LPDWORD reserved,
1949 LPDWORD subkeys, LPDWORD max_subkey, LPDWORD max_class,
1950 LPDWORD values, LPDWORD max_value, LPDWORD max_data,
1951 LPDWORD security, FILETIME *modif )
1953 return ERROR_SUCCESS;
1957 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
1959 static double linux_cpuinfo_freq()
1966 f = fopen ("/proc/cpuinfo", "r");
1968 while (fgets(line,sizeof(line),f)!=NULL) {
1969 /* NOTE: the ':' is the only character we can rely on */
1970 if (!(value = strchr(line,':')))
1972 /* terminate the valuename */
1974 /* skip any leading spaces */
1975 while (*value==' ') value++;
1976 if ((s=strchr(value,'\n')))
1979 if (!strncasecmp(line, "cpu MHz",strlen("cpu MHz"))
1980 && sscanf(value, "%lf", &freq) == 1) {
1991 static double solaris_kstat_freq()
1993 #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
1995 * try to extract the CPU speed from the solaris kernel's kstat data
1999 kstat_named_t *kdata;
2005 ksp = kstat_lookup(kc, "cpu_info", 0, "cpu_info0");
2007 /* kstat found and name/value pairs? */
2008 if (ksp != NULL && ksp->ks_type == KSTAT_TYPE_NAMED)
2010 /* read the kstat data from the kernel */
2011 if (kstat_read(kc, ksp, NULL) != -1)
2014 * lookup desired "clock_MHz" entry, check the expected
2017 kdata = (kstat_named_t *)kstat_data_lookup(ksp, "clock_MHz");
2018 if (kdata != NULL && kdata->data_type == KSTAT_DATA_INT32)
2019 mhz = kdata->value.i32;
2027 #endif /* HAVE_LIBKSTAT */
2028 return -1; // kstat stuff is not available, CPU freq is unknown
2032 * Measure CPU freq using the pentium's time stamp counter register (TSC)
2034 static double tsc_freq()
2036 static double ofreq=0.0;
2040 if (ofreq != 0.0) return ofreq;
2041 while(i==time(NULL));
2044 while(i==time(NULL));
2046 ofreq = (double)(y-x)/1000.;
2050 static double CPU_Freq()
2054 if ((freq = linux_cpuinfo_freq()) > 0)
2057 if ((freq = solaris_kstat_freq()) > 0)
2063 static long WINAPI expQueryPerformanceFrequency(long long* z)
2065 *z=(long long)CPU_Freq();
2066 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z, *z);
2069 static long WINAPI exptimeGetTime()
2073 gettimeofday(&t, 0);
2074 result=1000*t.tv_sec+t.tv_usec/1000;
2075 dbgprintf("timeGetTime() => %d\n", result);
2078 static void* WINAPI expLocalHandle(void* v)
2080 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v, v);
2084 static void* WINAPI expGlobalHandle(void* v)
2086 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v, v);
2089 static int WINAPI expGlobalUnlock(void* v)
2091 dbgprintf("GlobalUnlock(0x%x) => 1\n", v);
2094 static void* WINAPI expGlobalFree(void* v)
2096 dbgprintf("GlobalFree(0x%x) => 0\n", v);
2102 static void* WINAPI expGlobalReAlloc(void* v, int size, int flags)
2104 void* result=my_realloc(v, size);
2105 //void* result=realloc(v, size);
2106 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v,size,flags,result);
2110 static int WINAPI expLocalUnlock(void* v)
2112 dbgprintf("LocalUnlock(0x%x) => 1\n", v);
2116 static void* WINAPI expLocalFree(void* v)
2118 dbgprintf("LocalFree(0x%x) => 0\n", v);
2122 static HRSRC WINAPI expFindResourceA(HMODULE module, char* name, char* type)
2126 result=FindResourceA(module, name, type);
2127 dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2128 module, name, HIWORD(name) ? name : "UNICODE", type, HIWORD(type) ? type : "UNICODE", result);
2132 extern HRSRC WINAPI LoadResource(HMODULE, HRSRC);
2133 static HGLOBAL WINAPI expLoadResource(HMODULE module, HRSRC res)
2135 HGLOBAL result=LoadResource(module, res);
2136 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module, res, result);
2139 static void* WINAPI expLockResource(long res)
2141 void* result=LockResource(res);
2142 dbgprintf("LockResource(0x%x) => 0x%x\n", res, result);
2145 static int WINAPI expFreeResource(long res)
2147 int result=FreeResource(res);
2148 dbgprintf("FreeResource(0x%x) => %d\n", res, result);
2153 static int WINAPI expCloseHandle(long v1)
2155 dbgprintf("CloseHandle(0x%x) => 1\n", v1);
2156 /* do not close stdin,stdout and stderr */
2163 static const char* WINAPI expGetCommandLineA()
2165 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2166 return "c:\\aviplay.exe";
2168 static short envs[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2169 static LPWSTR WINAPI expGetEnvironmentStringsW()
2171 dbgprintf("GetEnvironmentStringsW() => 0\n", envs);
2174 static void * WINAPI expRtlZeroMemory(void *p, size_t len)
2176 void* result=memset(p,0,len);
2177 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p,len,result);
2180 static void * WINAPI expRtlMoveMemory(void *dst, void *src, size_t len)
2182 void* result=memmove(dst,src,len);
2183 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst,src,len,result);
2187 static void * WINAPI expRtlFillMemory(void *p, int ch, size_t len)
2189 void* result=memset(p,ch,len);
2190 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p,ch,len,result);
2193 static int WINAPI expFreeEnvironmentStringsW(short* strings)
2195 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings);
2198 static int WINAPI expFreeEnvironmentStringsA(char* strings)
2200 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings);
2204 static const char ch_envs[]=
2205 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2206 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2207 static LPCSTR WINAPI expGetEnvironmentStrings()
2209 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs);
2210 return (LPCSTR)ch_envs;
2211 // dbgprintf("GetEnvironmentStrings() => 0\n");
2215 static int WINAPI expGetStartupInfoA(STARTUPINFOA *s)
2218 dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2219 memset(s, 0, sizeof(*s));
2221 // s->lpReserved="Reserved";
2222 // s->lpDesktop="Desktop";
2223 // s->lpTitle="Title";
2225 // s->dwXSize=s->dwYSize=200;
2226 s->dwFlags=s->wShowWindow=1;
2227 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2228 dbgprintf(" cb=%d\n", s->cb);
2229 dbgprintf(" lpReserved='%s'\n", s->lpReserved);
2230 dbgprintf(" lpDesktop='%s'\n", s->lpDesktop);
2231 dbgprintf(" lpTitle='%s'\n", s->lpTitle);
2232 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2233 s->dwX, s->dwY, s->dwXSize, s->dwYSize);
2234 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2235 s->dwXCountChars, s->dwYCountChars, s->dwFillAttribute);
2236 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2237 s->dwFlags, s->wShowWindow, s->cbReserved2);
2238 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2239 s->lpReserved2, s->hStdInput, s->hStdOutput, s->hStdError);
2243 static int WINAPI expGetStdHandle(int z)
2245 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z+0x1234);
2250 #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2251 #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2254 static int WINAPI expGetFileType(int handle)
2256 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle);
2260 static int WINAPI expGetFileAttributesA(char *filename)
2262 dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename);
2263 if (strstr(filename, "QuickTime.qts"))
2264 return FILE_ATTRIBUTE_SYSTEM;
2265 return FILE_ATTRIBUTE_NORMAL;
2268 static int WINAPI expSetHandleCount(int count)
2270 dbgprintf("SetHandleCount(0x%x) => 1\n", count);
2273 static int WINAPI expGetACP(void)
2275 dbgprintf("GetACP() => 0\n");
2278 extern WINE_MODREF *MODULE32_LookupHMODULE(HMODULE m);
2279 static int WINAPI expGetModuleFileNameA(int module, char* s, int len)
2283 //printf("File name of module %X (%s) requested\n", module, s);
2285 if (module == 0 && len >= 12)
2287 /* return caller program name */
2288 strcpy(s, "aviplay.dll");
2299 strcpy(s, "c:\\windows\\system\\");
2300 mr=MODULE32_LookupHMODULE(module);
2302 strcat(s, "aviplay.dll");
2304 if(strrchr(mr->filename, '/')==NULL)
2305 strcat(s, mr->filename);
2307 strcat(s, strrchr(mr->filename, '/')+1);
2310 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2311 module, s, len, result);
2313 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2314 module, s, len, result, s);
2318 static int WINAPI expSetUnhandledExceptionFilter(void* filter)
2320 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter);
2321 return 1;//unsupported and probably won't ever be supported
2324 static int WINAPI expLoadLibraryA(char* name)
2331 // we skip to the last backslash
2332 // this is effectively eliminating weird characters in
2333 // the text output windows
2335 lastbc = strrchr(name, '\\');
2342 name[i] = *lastbc++;
2347 if(strncmp(name, "c:\\windows\\", 11)==0) name += 11;
2348 if(strncmp(name, ".\\", 2)==0) name += 2;
2350 dbgprintf("Entering LoadLibraryA(%s)\n", name);
2352 // PIMJ and VIVO audio are loading kernel32.dll
2353 if (strcasecmp(name, "kernel32.dll") == 0 || strcasecmp(name, "kernel32") == 0)
2354 return MODULE_HANDLE_kernel32;
2355 // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2356 /* exported -> do not return failed! */
2358 if (strcasecmp(name, "user32.dll") == 0 || strcasecmp(name, "user32") == 0)
2359 // return MODULE_HANDLE_kernel32;
2360 return MODULE_HANDLE_user32;
2363 if (strcasecmp(name, "wininet.dll") == 0 || strcasecmp(name, "wininet") == 0)
2364 return MODULE_HANDLE_wininet;
2365 if (strcasecmp(name, "ddraw.dll") == 0 || strcasecmp(name, "ddraw") == 0)
2366 return MODULE_HANDLE_ddraw;
2367 if (strcasecmp(name, "advapi32.dll") == 0 || strcasecmp(name, "advapi32") == 0)
2368 return MODULE_HANDLE_advapi32;
2371 if (strcasecmp(name, "comdlg32.dll") == 0 || strcasecmp(name, "comdlg32") == 0)
2372 return MODULE_HANDLE_comdlg32;
2373 if (strcasecmp(name, "msvcrt.dll") == 0 || strcasecmp(name, "msvcrt") == 0)
2374 return MODULE_HANDLE_msvcrt;
2375 if (strcasecmp(name, "ole32.dll") == 0 || strcasecmp(name, "ole32") == 0)
2376 return MODULE_HANDLE_ole32;
2377 if (strcasecmp(name, "winmm.dll") == 0 || strcasecmp(name, "winmm") == 0)
2378 return MODULE_HANDLE_winmm;
2380 result=LoadLibraryA(name);
2381 dbgprintf("Returned LoadLibraryA(0x%x='%s'), def_path=%s => 0x%x\n", name, name, def_path, result);
2386 static int WINAPI expFreeLibrary(int module)
2389 int result=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2391 int result=FreeLibrary(module);
2393 dbgprintf("FreeLibrary(0x%x) => %d\n", module, result);
2397 static void* WINAPI expGetProcAddress(HMODULE mod, char* name)
2401 case MODULE_HANDLE_kernel32:
2402 result=LookupExternalByName("kernel32.dll", name); break;
2403 case MODULE_HANDLE_user32:
2404 result=LookupExternalByName("user32.dll", name); break;
2406 case MODULE_HANDLE_wininet:
2407 result=LookupExternalByName("wininet.dll", name); break;
2408 case MODULE_HANDLE_ddraw:
2409 result=LookupExternalByName("ddraw.dll", name); break;
2410 case MODULE_HANDLE_advapi32:
2411 result=LookupExternalByName("advapi32.dll", name); break;
2413 case MODULE_HANDLE_comdlg32:
2414 result=LookupExternalByName("comdlg32.dll", name); break;
2415 case MODULE_HANDLE_msvcrt:
2416 result=LookupExternalByName("msvcrt.dll", name); break;
2417 case MODULE_HANDLE_ole32:
2418 result=LookupExternalByName("ole32.dll", name); break;
2419 case MODULE_HANDLE_winmm:
2420 result=LookupExternalByName("winmm.dll", name); break;
2422 result=GetProcAddress(mod, name);
2424 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod, name, result);
2428 static long WINAPI expCreateFileMappingA(int hFile, void* lpAttr,
2429 long flProtect, long dwMaxHigh,
2430 long dwMaxLow, const char* name)
2432 long result=CreateFileMappingA(hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name);
2434 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2435 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2436 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, result);
2438 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2439 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2440 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name, name, result);
2444 static long WINAPI expOpenFileMappingA(long hFile, long hz, const char* name)
2446 long result=OpenFileMappingA(hFile, hz, name);
2448 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2451 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2452 hFile, hz, name, name, result);
2456 static void* WINAPI expMapViewOfFile(HANDLE file, DWORD mode, DWORD offHigh,
2457 DWORD offLow, DWORD size)
2459 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2460 file,mode,offHigh,offLow,size,(char*)file+offLow);
2461 return (char*)file+offLow;
2464 static void* WINAPI expUnmapViewOfFile(void* view)
2466 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view);
2470 static void* WINAPI expSleep(int time)
2473 /* solaris doesn't have thread safe usleep */
2474 struct timespec tsp;
2475 tsp.tv_sec = time / 1000000;
2476 tsp.tv_nsec = (time % 1000000) * 1000;
2477 nanosleep(&tsp, NULL);
2481 dbgprintf("Sleep(%d) => 0\n", time);
2485 // why does IV32 codec want to call this? I don't know ...
2486 static int WINAPI expCreateCompatibleDC(int hdc)
2489 //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2490 dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc, dc);
2494 static int WINAPI expGetDeviceCaps(int hdc, int unk)
2496 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc, unk);
2498 #define BITSPIXEL 12
2500 if (unk == BITSPIXEL)
2508 static WIN_BOOL WINAPI expDeleteDC(int hdc)
2510 dbgprintf("DeleteDC(0x%x) => 0\n", hdc);
2516 static WIN_BOOL WINAPI expDeleteObject(int hdc)
2518 dbgprintf("DeleteObject(0x%x) => 1\n", hdc);
2519 /* FIXME - implement code here */
2523 /* btvvc32.drv wants this one */
2524 static void* WINAPI expGetWindowDC(int hdc)
2526 dbgprintf("GetWindowDC(%d) => 0x0\n", hdc);
2531 static int WINAPI expGetWindowRect(HWND win, RECT *r)
2533 dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win, r);
2534 /* (win == 0) => desktop */
2535 r->right = PSEUDO_SCREEN_WIDTH;
2537 r->bottom = PSEUDO_SCREEN_HEIGHT;
2542 static int WINAPI expMonitorFromWindow(HWND win, int flags)
2544 dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win, flags);
2548 static int WINAPI expMonitorFromRect(RECT *r, int flags)
2550 dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r, flags);
2554 static int WINAPI expMonitorFromPoint(void *p, int flags)
2556 dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p, flags);
2560 static int WINAPI expEnumDisplayMonitors(void *dc, RECT *r,
2561 int WINAPI (*callback_proc)(), void *callback_param)
2563 dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2564 dc, r, callback_proc, callback_param);
2565 return callback_proc(0, dc, r, callback_param);
2569 typedef struct tagMONITORINFO {
2574 } MONITORINFO, *LPMONITORINFO;
2577 #define CCHDEVICENAME 8
2578 typedef struct tagMONITORINFOEX {
2583 TCHAR szDevice[CCHDEVICENAME];
2584 } MONITORINFOEX, *LPMONITORINFOEX;
2586 static int WINAPI expGetMonitorInfoA(void *mon, LPMONITORINFO lpmi)
2588 dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon, lpmi);
2590 lpmi->rcMonitor.right = lpmi->rcWork.right = PSEUDO_SCREEN_WIDTH;
2591 lpmi->rcMonitor.left = lpmi->rcWork.left = 0;
2592 lpmi->rcMonitor.bottom = lpmi->rcWork.bottom = PSEUDO_SCREEN_HEIGHT;
2593 lpmi->rcMonitor.top = lpmi->rcWork.top = 0;
2595 lpmi->dwFlags = 1; /* primary monitor */
2597 if (lpmi->cbSize == sizeof(MONITORINFOEX))
2599 LPMONITORINFOEX lpmiex = (LPMONITORINFOEX)lpmi;
2600 dbgprintf("MONITORINFOEX!\n");
2601 strncpy(lpmiex->szDevice, "Monitor1", CCHDEVICENAME);
2607 static int WINAPI expEnumDisplayDevicesA(const char *device, int devnum,
2608 void *dispdev, int flags)
2610 dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2611 device, device, devnum, dispdev, flags);
2615 static int WINAPI expIsWindowVisible(HWND win)
2617 dbgprintf("IsWindowVisible(0x%x) => 1\n", win);
2621 static HWND WINAPI expGetActiveWindow(void)
2623 dbgprintf("GetActiveWindow() => 0\n");
2627 static int WINAPI expGetClassNameA(HWND win, LPTSTR classname, int maxcount)
2629 strncat(classname, "QuickTime", maxcount);
2630 dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2631 win, classname, maxcount, strlen(classname));
2632 return strlen(classname);
2635 #define LPWNDCLASS void *
2636 static int WINAPI expGetClassInfoA(HINSTANCE inst, LPCSTR classname, LPWNDCLASS wndclass)
2638 dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst,
2639 classname, classname, wndclass);
2643 static int WINAPI expGetWindowLongA(HWND win, int index)
2645 dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win, index);
2649 static int WINAPI expGetObjectA(HGDIOBJ hobj, int objsize, LPVOID obj)
2651 dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj, objsize, obj, objsize);
2655 static int WINAPI expCreateRectRgn(int x, int y, int width, int height)
2657 dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x, y, width, height);
2661 static int WINAPI expEnumWindows(int (*callback_func)(), void *callback_param)
2664 dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func, callback_param);
2665 i = callback_func(0, callback_param);
2666 i2 = callback_func(1, callback_param);
2670 static int WINAPI expGetWindowThreadProcessId(HWND win, int *pid_data)
2672 int tid = pthread_self();
2673 dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2674 win, pid_data, tid);
2676 *(int*)pid_data = tid;
2680 //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2681 // INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2683 static HWND WINAPI expCreateWindowExA(int exstyle, const char *classname,
2684 const char *winname, int style, int x, int y, int w, int h,
2685 HWND parent, HMENU menu, HINSTANCE inst, LPVOID param)
2687 printf("CreateWindowEx() called\n");
2688 dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2689 exstyle, classname, classname, winname, winname, style, x, y, w, h,
2690 parent, menu, inst, param);
2691 printf("CreateWindowEx() called okey\n");
2695 static int WINAPI expwaveOutGetNumDevs(void)
2697 dbgprintf("waveOutGetNumDevs() => 0\n");
2703 * Returns the number of milliseconds, modulo 2^32, since the start
2704 * of the wineserver.
2706 static int WINAPI expGetTickCount(void)
2708 static int tcstart = 0;
2711 gettimeofday( &t, NULL );
2712 tc = ((t.tv_sec * 1000) + (t.tv_usec / 1000)) - tcstart;
2718 dbgprintf("GetTickCount() => %d\n", tc);
2722 static int WINAPI expCreateFontA(void)
2724 dbgprintf("CreateFontA() => 0x0\n");
2728 /* tried to get pvmjpg work in a different way - no success */
2729 static int WINAPI expDrawTextA(int hDC, char* lpString, int nCount,
2730 LPRECT lpRect, unsigned int uFormat)
2732 dbgprintf("expDrawTextA(%p,...) => 8\n", hDC);
2736 static int WINAPI expGetPrivateProfileIntA(const char* appname,
2737 const char* keyname,
2739 const char* filename)
2747 if(!(appname && keyname && filename) )
2749 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, default_value );
2750 return default_value;
2752 fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2753 strcpy(fullname, "Software\\IniFileMapping\\");
2754 strcat(fullname, appname);
2755 strcat(fullname, "\\");
2756 strcat(fullname, keyname);
2757 strcat(fullname, "\\");
2758 strcat(fullname, filename);
2759 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)buffer, &size);
2760 if((size>=0)&&(size<256))
2762 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2765 result=default_value;
2767 result=atoi(buffer);
2768 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, result);
2771 static int WINAPI expGetProfileIntA(const char* appname,
2772 const char* keyname,
2775 dbgprintf("GetProfileIntA -> ");
2776 return expGetPrivateProfileIntA(appname, keyname, default_value, "default");
2779 static int WINAPI expGetPrivateProfileStringA(const char* appname,
2780 const char* keyname,
2781 const char* def_val,
2782 char* dest, unsigned int len,
2783 const char* filename)
2788 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname, keyname, def_val, dest, len, filename );
2789 if(!(appname && keyname && filename) ) return 0;
2790 fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2791 strcpy(fullname, "Software\\IniFileMapping\\");
2792 strcat(fullname, appname);
2793 strcat(fullname, "\\");
2794 strcat(fullname, keyname);
2795 strcat(fullname, "\\");
2796 strcat(fullname, filename);
2798 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)dest, &size);
2802 strncpy(dest, def_val, size);
2803 if (strlen(def_val)< size) size = strlen(def_val);
2805 dbgprintf(" => %d ( '%s' )\n", size, dest);
2808 static int WINAPI expWritePrivateProfileStringA(const char* appname,
2809 const char* keyname,
2811 const char* filename)
2815 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname, keyname, string, filename );
2816 if(!(appname && keyname && filename) )
2818 dbgprintf(" => -1\n");
2821 fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2822 strcpy(fullname, "Software\\IniFileMapping\\");
2823 strcat(fullname, appname);
2824 strcat(fullname, "\\");
2825 strcat(fullname, keyname);
2826 strcat(fullname, "\\");
2827 strcat(fullname, filename);
2828 RegSetValueExA(HKEY_LOCAL_MACHINE, fullname, 0, REG_SZ, (int*)string, strlen(string));
2829 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
2830 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
2832 dbgprintf(" => 0\n");
2836 unsigned int _GetPrivateProfileIntA(const char* appname, const char* keyname, INT default_value, const char* filename)
2838 return expGetPrivateProfileIntA(appname, keyname, default_value, filename);
2840 int _GetPrivateProfileStringA(const char* appname, const char* keyname,
2841 const char* def_val, char* dest, unsigned int len, const char* filename)
2843 return expGetPrivateProfileStringA(appname, keyname, def_val, dest, len, filename);
2845 int _WritePrivateProfileStringA(const char* appname, const char* keyname,
2846 const char* string, const char* filename)
2848 return expWritePrivateProfileStringA(appname, keyname, string, filename);
2853 static int WINAPI expDefDriverProc(int _private, int id, int msg, int arg1, int arg2)
2855 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", _private, id, msg, arg1, arg2);
2859 static int WINAPI expSizeofResource(int v1, int v2)
2861 int result=SizeofResource(v1, v2);
2862 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1, v2, result);
2866 static int WINAPI expGetLastError()
2868 int result=GetLastError();
2869 dbgprintf("GetLastError() => 0x%x\n", result);
2873 static void WINAPI expSetLastError(int error)
2875 dbgprintf("SetLastError(0x%x)\n", error);
2876 SetLastError(error);
2879 static int WINAPI expStringFromGUID2(GUID* guid, char* str, int cbMax)
2881 int result=snprintf(str, cbMax, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
2882 guid->f1, guid->f2, guid->f3,
2883 (unsigned char)guid->f4[0], (unsigned char)guid->f4[1],
2884 (unsigned char)guid->f4[2], (unsigned char)guid->f4[3],
2885 (unsigned char)guid->f4[4], (unsigned char)guid->f4[5],
2886 (unsigned char)guid->f4[6], (unsigned char)guid->f4[7]);
2887 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid, str, str, cbMax, result);
2892 static int WINAPI expGetFileVersionInfoSizeA(const char* name, int* lpHandle)
2894 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name, name, lpHandle);
2898 static int WINAPI expIsBadStringPtrW(const short* string, int nchars)
2901 if(string==0)result=1; else result=0;
2902 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string, nchars, result);
2903 if(string)wch_print(string);
2906 static int WINAPI expIsBadStringPtrA(const char* string, int nchars)
2908 return expIsBadStringPtrW((const short*)string, nchars);
2910 static long WINAPI expInterlockedExchangeAdd( long* dest, long incr )
2913 __asm__ __volatile__
2915 "lock; xaddl %0,(%1)"
2917 : "r" (dest), "0" (incr)
2923 static long WINAPI expInterlockedCompareExchange( unsigned long* dest, unsigned long exchange, unsigned long comperand)
2925 unsigned long retval = *dest;
2926 if(*dest == comperand)
2931 static long WINAPI expInterlockedIncrement( long* dest )
2933 long result=expInterlockedExchangeAdd( dest, 1 ) + 1;
2934 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest, *dest, result);
2937 static long WINAPI expInterlockedDecrement( long* dest )
2939 long result=expInterlockedExchangeAdd( dest, -1 ) - 1;
2940 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest, *dest, result);
2944 static void WINAPI expOutputDebugStringA( const char* string )
2946 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string);
2947 fprintf(stderr, "DEBUG: %s\n", string);
2950 static int WINAPI expGetDC(int hwnd)
2952 dbgprintf("GetDC(0x%x) => 1\n", hwnd);
2956 static int WINAPI expReleaseDC(int hwnd, int hdc)
2958 dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd, hdc);
2962 static int WINAPI expGetDesktopWindow()
2964 dbgprintf("GetDesktopWindow() => 0\n");
2968 static int cursor[100];
2970 static int WINAPI expLoadCursorA(int handle,LPCSTR name)
2972 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle, name, (int)&cursor[0]);
2973 return (int)&cursor[0];
2975 static int WINAPI expSetCursor(void *cursor)
2977 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor, cursor);
2980 static int WINAPI expGetCursorPos(void *cursor)
2982 dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor, cursor);
2986 static int show_cursor = 0;
2987 static int WINAPI expShowCursor(int show)
2989 dbgprintf("ShowCursor(%d) => %d\n", show, show);
2997 static int WINAPI expRegisterWindowMessageA(char *message)
2999 dbgprintf("RegisterWindowMessageA(%s)\n", message);
3002 static int WINAPI expGetProcessVersion(int pid)
3004 dbgprintf("GetProcessVersion(%d)\n", pid);
3007 static int WINAPI expGetCurrentThread(void)
3010 dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
3013 static int WINAPI expGetOEMCP(void)
3015 dbgprintf("GetOEMCP()\n");
3018 static int WINAPI expGetCPInfo(int cp,void *info)
3020 dbgprintf("GetCPInfo()\n");
3024 #define SM_CXSCREEN 0
3025 #define SM_CYSCREEN 1
3026 #define SM_XVIRTUALSCREEN 76
3027 #define SM_YVIRTUALSCREEN 77
3028 #define SM_CXVIRTUALSCREEN 78
3029 #define SM_CYVIRTUALSCREEN 79
3030 #define SM_CMONITORS 80
3032 static int WINAPI expGetSystemMetrics(int index)
3034 dbgprintf("GetSystemMetrics(%d)\n", index);
3038 case SM_XVIRTUALSCREEN:
3039 case SM_YVIRTUALSCREEN:
3042 case SM_CXVIRTUALSCREEN:
3043 return PSEUDO_SCREEN_WIDTH;
3045 case SM_CYVIRTUALSCREEN:
3046 return PSEUDO_SCREEN_HEIGHT;
3053 static int WINAPI expGetSysColor(int index)
3055 dbgprintf("GetSysColor(%d) => 1\n", index);
3058 static int WINAPI expGetSysColorBrush(int index)
3060 dbgprintf("GetSysColorBrush(%d)\n", index);
3066 static int WINAPI expGetSystemPaletteEntries(int hdc, int iStartIndex, int nEntries, void* lppe)
3068 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3069 hdc, iStartIndex, nEntries, lppe);
3074 typedef struct _TIME_ZONE_INFORMATION {
3076 char StandardName[32];
3077 SYSTEMTIME StandardDate;
3079 char DaylightName[32];
3080 SYSTEMTIME DaylightDate;
3082 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3085 static int WINAPI expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
3087 const short name[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3088 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3089 const short pname[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3090 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3091 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3092 memset(lpTimeZoneInformation, 0, sizeof(TIME_ZONE_INFORMATION));
3093 lpTimeZoneInformation->Bias=360;//GMT-6
3094 memcpy(lpTimeZoneInformation->StandardName, name, sizeof(name));
3095 lpTimeZoneInformation->StandardDate.wMonth=10;
3096 lpTimeZoneInformation->StandardDate.wDay=5;
3097 lpTimeZoneInformation->StandardDate.wHour=2;
3098 lpTimeZoneInformation->StandardBias=0;
3099 memcpy(lpTimeZoneInformation->DaylightName, pname, sizeof(pname));
3100 lpTimeZoneInformation->DaylightDate.wMonth=4;
3101 lpTimeZoneInformation->DaylightDate.wDay=1;
3102 lpTimeZoneInformation->DaylightDate.wHour=2;
3103 lpTimeZoneInformation->DaylightBias=-60;
3104 return TIME_ZONE_ID_STANDARD;
3107 static void WINAPI expGetLocalTime(SYSTEMTIME* systime)
3110 struct tm *local_tm;
3113 dbgprintf("GetLocalTime(0x%x)\n");
3114 gettimeofday(&tv, NULL);
3115 local_time=tv.tv_sec;
3116 local_tm=localtime(&local_time);
3118 systime->wYear = local_tm->tm_year + 1900;
3119 systime->wMonth = local_tm->tm_mon + 1;
3120 systime->wDayOfWeek = local_tm->tm_wday;
3121 systime->wDay = local_tm->tm_mday;
3122 systime->wHour = local_tm->tm_hour;
3123 systime->wMinute = local_tm->tm_min;
3124 systime->wSecond = local_tm->tm_sec;
3125 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
3126 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3127 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3128 " Milliseconds: %d\n",
3129 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay,
3130 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds);
3133 static int WINAPI expGetSystemTime(SYSTEMTIME* systime)
3136 struct tm *local_tm;
3139 dbgprintf("GetSystemTime(0x%x)\n", systime);
3140 gettimeofday(&tv, NULL);
3141 local_time=tv.tv_sec;
3142 local_tm=gmtime(&local_time);
3144 systime->wYear = local_tm->tm_year + 1900;
3145 systime->wMonth = local_tm->tm_mon + 1;
3146 systime->wDayOfWeek = local_tm->tm_wday;
3147 systime->wDay = local_tm->tm_mday;
3148 systime->wHour = local_tm->tm_hour;
3149 systime->wMinute = local_tm->tm_min;
3150 systime->wSecond = local_tm->tm_sec;
3151 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
3152 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3153 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3154 " Milliseconds: %d\n",
3155 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay,
3156 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds);
3160 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3161 static void WINAPI expGetSystemTimeAsFileTime(FILETIME* systime)
3163 struct tm *local_tm;
3165 unsigned long long secs;
3167 dbgprintf("GetSystemTime(0x%x)\n", systime);
3168 gettimeofday(&tv, NULL);
3169 secs = (tv.tv_sec + SECS_1601_TO_1970) * 10000000;
3170 secs += tv.tv_usec * 10;
3171 systime->dwLowDateTime = secs & 0xffffffff;
3172 systime->dwHighDateTime = (secs >> 32);
3175 static int WINAPI expGetEnvironmentVariableA(const char* name, char* field, int size)
3178 // printf("%s %x %x\n", name, field, size);
3179 if(field)field[0]=0;
3182 if (p) strncpy(field,p,size);
3184 if (strcmp(name,"__MSVCRT_HEAP_SELECT")==0)
3185 strcpy(field,"__GLOBAL_HEAP_SELECTED,1");
3186 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name, name, field, size, strlen(field));
3187 return strlen(field);
3190 static int WINAPI expSetEnvironmentVariableA(const char *name, const char *value)
3192 dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name, value);
3196 static void* WINAPI expCoTaskMemAlloc(ULONG cb)
3198 return my_mreq(cb, 0);
3200 static void WINAPI expCoTaskMemFree(void* cb)
3208 void* CoTaskMemAlloc(unsigned long cb)
3210 return expCoTaskMemAlloc(cb);
3212 void CoTaskMemFree(void* cb)
3214 expCoTaskMemFree(cb);
3217 struct COM_OBJECT_INFO
3220 long (*GetClassObject) (GUID* clsid, const GUID* iid, void** ppv);
3223 static struct COM_OBJECT_INFO* com_object_table=0;
3224 static int com_object_size=0;
3225 int RegisterComClass(const GUID* clsid, GETCLASSOBJECT gcs)
3229 com_object_table=realloc(com_object_table, sizeof(struct COM_OBJECT_INFO)*(++com_object_size));
3230 com_object_table[com_object_size-1].clsid=*clsid;
3231 com_object_table[com_object_size-1].GetClassObject=gcs;
3235 int UnregisterComClass(const GUID* clsid, GETCLASSOBJECT gcs)
3242 if (com_object_table == 0)
3243 printf("Warning: UnregisterComClass() called without any registered class\n");
3244 while (i < com_object_size)
3248 memcpy(&com_object_table[i - 1].clsid,
3249 &com_object_table[i].clsid, sizeof(GUID));
3250 com_object_table[i - 1].GetClassObject =
3251 com_object_table[i].GetClassObject;
3253 else if (memcmp(&com_object_table[i].clsid, clsid, sizeof(GUID)) == 0
3254 && com_object_table[i].GetClassObject == gcs)
3262 if (--com_object_size == 0)
3264 free(com_object_table);
3265 com_object_table = 0;
3272 const GUID IID_IUnknown =
3274 0x00000000, 0x0000, 0x0000,
3275 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3277 const GUID IID_IClassFactory =
3279 0x00000001, 0x0000, 0x0000,
3280 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3283 static long WINAPI expCoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
3284 long dwClsContext, const GUID* riid, void** ppv)
3287 struct COM_OBJECT_INFO* ci=0;
3288 for(i=0; i<com_object_size; i++)
3289 if(!memcmp(rclsid, &com_object_table[i].clsid, sizeof(GUID)))
3290 ci=&com_object_table[i];
3291 if(!ci)return REGDB_E_CLASSNOTREG;
3292 // in 'real' world we should mess with IClassFactory here
3293 i=ci->GetClassObject(rclsid, riid, ppv);
3297 long CoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
3298 long dwClsContext, const GUID* riid, void** ppv)
3300 return expCoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
3303 static int WINAPI expIsRectEmpty(CONST RECT *lprc)
3310 w = lprc->right - lprc->left;
3311 h = lprc->bottom - lprc->top;
3312 if (w <= 0 || h <= 0)
3318 dbgprintf("IsRectEmpty(%p) => %s\n", lprc, (r) ? "TRUE" : "FALSE");
3319 //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3320 // return 0; // wmv9?
3324 static int _adjust_fdiv=0; //what's this? - used to adjust division
3329 static unsigned int WINAPI expGetTempPathA(unsigned int len, char* path)
3331 dbgprintf("GetTempPathA(%d, 0x%x)", len, path);
3334 dbgprintf(" => 0\n");
3337 strcpy(path, "/tmp");
3338 dbgprintf(" => 5 ( '/tmp' )\n");
3345 DWORD dwFileAttributes;
3346 FILETIME ftCreationTime;
3347 FILETIME ftLastAccessTime;
3348 FILETIME ftLastWriteTime;
3349 DWORD nFileSizeHigh;
3353 CHAR cFileName[260];
3354 CHAR cAlternateFileName[14];
3355 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3358 static DIR* qtx_dir=NULL;
3360 static WIN_BOOL WINAPI expFindNextFileA(HANDLE h,LPWIN32_FIND_DATAA lpfd)
3363 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h, lpfd);
3364 if(h==FILE_HANDLE_quicktimeqtx){
3366 if(!qtx_dir) return 0;
3367 while((d=readdir(qtx_dir))){
3368 char* x=strrchr(d->d_name,'.');
3370 if(strcmp(x,".qtx")) continue;
3371 strcpy(lpfd->cFileName,d->d_name);
3372 // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3373 strcpy(lpfd->cAlternateFileName,"foobar.qtx");
3374 printf("### FindNext: %s\n",lpfd->cFileName);
3377 closedir(qtx_dir); qtx_dir=NULL;
3384 static HANDLE WINAPI expFindFirstFileA(LPCSTR s, LPWIN32_FIND_DATAA lpfd)
3386 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s, s, lpfd);
3387 // printf("\n### FindFirstFileA('%s')...\n",s);
3389 if(strstr(s, "quicktime\\*.QTX")){
3390 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s, s, lpfd);
3391 printf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",def_path);
3392 qtx_dir=opendir(def_path);
3393 if(!qtx_dir) return (HANDLE)-1;
3394 memset(lpfd,0,sizeof(*lpfd));
3395 if(expFindNextFileA(FILE_HANDLE_quicktimeqtx,lpfd))
3396 return FILE_HANDLE_quicktimeqtx;
3397 printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",def_path);
3401 if(strstr(s, "QuickTime.qts")){
3402 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s, s, lpfd);
3403 // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3404 // return (HANDLE)-1;
3405 strcpy(lpfd->cFileName, "QuickTime.qts");
3406 strcpy(lpfd->cAlternateFileName, "QuickT~1.qts");
3407 return FILE_HANDLE_quicktimeqts;
3411 if(strstr(s, "*.vwp")){
3412 // hack for VoxWare codec plugins:
3413 strcpy(lpfd->cFileName, "msms001.vwp");
3414 strcpy(lpfd->cAlternateFileName, "msms001.vwp");
3417 // return 'file not found'
3421 static WIN_BOOL WINAPI expFindClose(HANDLE h)
3423 dbgprintf("FindClose(0x%x) => 0\n", h);
3425 // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3426 // closedir(qtx_dir);
3432 static UINT WINAPI expSetErrorMode(UINT i)
3434 dbgprintf("SetErrorMode(%d) => 0\n", i);
3437 static UINT WINAPI expGetWindowsDirectoryA(LPSTR s,UINT c)
3439 char windir[]="c:\\windows";
3441 strncpy(s, windir, c);
3442 result=1+((c<strlen(windir))?c:strlen(windir));
3443 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s, c, result);
3447 static UINT WINAPI expGetCurrentDirectoryA(UINT c, LPSTR s)
3449 char curdir[]="c:\\";
3451 strncpy(s, curdir, c);
3452 result=1+((c<strlen(curdir))?c:strlen(curdir));
3453 dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s, c, result);
3457 static int WINAPI expSetCurrentDirectoryA(const char *pathname)
3459 dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname, pathname);
3461 if (strrchr(pathname, '\\'))
3462 chdir(strcat(strrchr(pathname, '\\')+1, '/'));
3469 static int WINAPI expCreateDirectoryA(const char *pathname, void *sa)
3471 dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3472 pathname, pathname, sa);
3474 p = strrchr(pathname, '\\')+1;
3475 strcpy(&buf[0], p); /* should be strncpy */
3482 if (strrchr(pathname, '\\'))
3483 mkdir(strcat(strrchr(pathname, '\\')+1, '/'), 666);
3485 mkdir(pathname, 666);
3492 static WIN_BOOL WINAPI expDeleteFileA(LPCSTR s)
3494 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s, s);
3497 static WIN_BOOL WINAPI expFileTimeToLocalFileTime(const FILETIME* cpf, LPFILETIME pf)
3499 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf, pf);
3503 static UINT WINAPI expGetTempFileNameA(LPCSTR cs1,LPCSTR cs2,UINT i,LPSTR ps)
3505 char mask[16]="/tmp/AP_XXXXXX";
3507 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1, cs1, cs2, cs2, i, ps);
3510 dbgprintf(" => -1\n");
3513 result=mkstemp(mask);
3514 sprintf(ps, "AP%d", result);
3515 dbgprintf(" => %d\n", strlen(ps));
3519 // This func might need proper implementation if we want AngelPotion codec.
3520 // They try to open APmpeg4v1.apl with it.
3521 // DLL will close opened file with CloseHandle().
3523 static HANDLE WINAPI expCreateFileA(LPCSTR cs1,DWORD i1,DWORD i2,
3524 LPSECURITY_ATTRIBUTES p1, DWORD i3,DWORD i4,HANDLE i5)
3526 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1, cs1, i1,
3527 i2, p1, i3, i4, i5);
3528 if((!cs1) || (strlen(cs1)<2))return -1;
3531 if(strstr(cs1, "QuickTime.qts"))
3534 char* tmp=(char*)malloc(strlen(def_path)+50);
3535 strcpy(tmp, def_path);
3537 strcat(tmp, "QuickTime.qts");
3538 result=open(tmp, O_RDONLY);
3542 if(strstr(cs1, ".qtx"))
3545 char* tmp=(char*)malloc(strlen(def_path)+250);
3546 char* x=strrchr(cs1,'\\');
3547 sprintf(tmp,"%s/%s",def_path,x?(x+1):cs1);
3548 // printf("### Open: %s -> %s\n",cs1,tmp);
3549 result=open(tmp, O_RDONLY);
3555 if(strncmp(cs1, "AP", 2) == 0)
3558 char* tmp=(char*)malloc(strlen(def_path)+50);
3559 strcpy(tmp, def_path);
3561 strcat(tmp, "APmpg4v1.apl");
3562 result=open(tmp, O_RDONLY);
3566 if (strstr(cs1, "vp3"))
3570 char* tmp=(char*)malloc(20 + strlen(cs1));
3571 strcpy(tmp, "/tmp/");
3576 if (tmp[r] == ':' || tmp[r] == '\\')
3580 if (GENERIC_READ & i1)
3582 else if (GENERIC_WRITE & i1)
3585 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp, r, flg);
3592 // Needed by wnvplay1.dll
3593 if (strstr(cs1, "WINNOV.bmp"))
3596 r=open("/dev/null", 0);
3601 /* we need this for some virtualdub filters */
3605 if (GENERIC_READ & i1)
3607 else if (GENERIC_WRITE & i1)
3610 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1, r, flg);
3619 static UINT WINAPI expGetSystemDirectoryA(
3620 char* lpBuffer, // address of buffer for system directory
3621 UINT uSize // size of directory buffer
3623 dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer,uSize);
3624 if(!lpBuffer) strcpy(lpBuffer,".");
3628 static char sysdir[]=".";
3629 static LPCSTR WINAPI expGetSystemDirectoryA()
3631 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3635 static DWORD WINAPI expGetFullPathNameA
3638 DWORD nBufferLength,
3642 if(!lpFileName) return 0;
3643 dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName,nBufferLength,
3644 lpBuffer, lpFilePart);
3647 strcpy(lpFilePart, "Quick123.qts");
3649 strcpy(lpFilePart, lpFileName);
3652 if (strrchr(lpFileName, '\\'))
3653 lpFilePart = strrchr(lpFileName, '\\');
3655 lpFilePart = (LPTSTR)lpFileName;
3657 strcpy(lpBuffer, lpFileName);
3658 // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3659 return strlen(lpBuffer);
3662 static DWORD WINAPI expGetShortPathNameA
3668 if(!longpath) return 0;
3669 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath,shortpath,shortlen);
3670 strcpy(shortpath,longpath);
3671 return strlen(shortpath);
3674 static WIN_BOOL WINAPI expReadFile(HANDLE h,LPVOID pv,DWORD size,LPDWORD rd,LPOVERLAPPED unused)
3677 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, rd);
3678 result=read(h, pv, size);
3680 if(!result)return 0;
3684 static WIN_BOOL WINAPI expWriteFile(HANDLE h,LPCVOID pv,DWORD size,LPDWORD wr,LPOVERLAPPED unused)
3687 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, wr);
3689 result=write(h, pv, size);
3691 if(!result)return 0;
3694 static DWORD WINAPI expSetFilePointer(HANDLE h, LONG val, LPLONG ext, DWORD whence)
3697 dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h, val, ext, *ext, whence);
3698 //why would DLL want temporary file with >2Gb size?
3711 if (val == 0 && ext != 0)
3714 return lseek(h, val, wh);
3717 static HDRVR WINAPI expOpenDriverA(LPCSTR szDriverName, LPCSTR szSectionName,
3720 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2);
3723 static HDRVR WINAPI expOpenDriver(LPCSTR szDriverName, LPCSTR szSectionName,
3726 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2);
3731 static WIN_BOOL WINAPI expGetProcessAffinityMask(HANDLE hProcess,
3732 LPDWORD lpProcessAffinityMask,
3733 LPDWORD lpSystemAffinityMask)
3735 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3736 hProcess, lpProcessAffinityMask, lpSystemAffinityMask);
3737 if(lpProcessAffinityMask)*lpProcessAffinityMask=1;
3738 if(lpSystemAffinityMask)*lpSystemAffinityMask=1;
3742 static int WINAPI expMulDiv(int nNumber, int nNumerator, int nDenominator)
3744 static const long long max_int=0x7FFFFFFFLL;
3745 static const long long min_int=-0x80000000LL;
3746 long long tmp=(long long)nNumber*(long long)nNumerator;
3747 dbgprintf("expMulDiv %d * %d / %d\n", nNumber, nNumerator, nDenominator);
3748 if(!nDenominator)return 1;
3750 if(tmp<min_int) return 1;
3751 if(tmp>max_int) return 1;
3755 static LONG WINAPI explstrcmpiA(const char* str1, const char* str2)
3757 LONG result=strcasecmp(str1, str2);
3758 dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
3762 static LONG WINAPI explstrlenA(const char* str1)
3764 LONG result=strlen(str1);
3765 dbgprintf("strlen(0x%x='%.50s') => %d\n", str1, str1, result);
3769 static LONG WINAPI explstrcpyA(char* str1, const char* str2)
3771 int result= (int) strcpy(str1, str2);
3772 dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1, str2, str2, result);
3775 static LONG WINAPI explstrcpynA(char* str1, const char* str2,int len)
3778 if (strlen(str2)>len)
3779 result = (int) strncpy(str1, str2,len);
3781 result = (int) strcpy(str1,str2);
3782 dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1, str2, str2,len, strlen(str2),result);
3785 static LONG WINAPI explstrcatA(char* str1, const char* str2)
3787 int result= (int) strcat(str1, str2);
3788 dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1, str2, str2, result);
3793 static LONG WINAPI expInterlockedExchange(long *dest, long l)
3795 long retval = *dest;
3800 static void WINAPI expInitCommonControls(void)
3802 dbgprintf("InitCommonControls called!\n");
3807 /* needed by QuickTime.qts */
3808 static HWND WINAPI expCreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
3809 HWND parent, INT id, HINSTANCE inst,
3810 HWND buddy, INT maxVal, INT minVal, INT curVal)
3812 dbgprintf("CreateUpDownControl(...)\n");
3817 /* alex: implement this call! needed for 3ivx */
3818 static HRESULT WINAPI expCoCreateFreeThreadedMarshaler(void *pUnkOuter, void **ppUnkInner)
3820 dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
3821 pUnkOuter, ppUnkInner);
3823 return ERROR_CALL_NOT_IMPLEMENTED;
3827 static int WINAPI expDuplicateHandle(HANDLE hSourceProcessHandle, // handle to source process
3828 HANDLE hSourceHandle, // handle to duplicate
3829 HANDLE hTargetProcessHandle, // handle to target process
3830 HANDLE* lpTargetHandle, // duplicate handle
3831 DWORD dwDesiredAccess, // requested access
3832 int bInheritHandle, // handle inheritance option
3833 DWORD dwOptions // optional actions
3836 dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
3837 hSourceProcessHandle, hSourceHandle, hTargetProcessHandle,
3838 lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions);
3839 *lpTargetHandle = hSourceHandle;
3843 // required by PIM1 codec (used by win98 PCTV Studio capture sw)
3844 static HRESULT WINAPI expCoInitialize(
3845 LPVOID lpReserved /* [in] pointer to win32 malloc interface
3846 (obsolete, should be NULL) */
3850 * Just delegate to the newer method.
3852 return 0; //CoInitializeEx(lpReserved, COINIT_APARTMENTTHREADED);
3855 static DWORD WINAPI expSetThreadAffinityMask
3858 DWORD dwThreadAffinityMask
3864 * no WINAPI functions - CDECL
3866 static void* expmalloc(int size)
3869 // return malloc(size);
3870 void* result=my_mreq(size,0);
3871 dbgprintf("malloc(0x%x) => 0x%x\n", size,result);
3873 printf("WARNING: malloc() failed\n");
3876 static void expfree(void* mem)
3878 // return free(mem);
3879 dbgprintf("free(%p)\n", mem);
3882 /* needed by atrac3.acm */
3883 static void *expcalloc(int num, int size)
3885 void* result=my_mreq(num*size,1);
3886 dbgprintf("calloc(%d,%d) => %p\n", num,size,result);
3888 printf("WARNING: calloc() failed\n");
3891 static void* expnew(int size)
3893 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
3894 // printf("%08x %08x %08x %08x\n",
3895 // size, *(1+(int*)&size),
3896 // *(2+(int*)&size),*(3+(int*)&size));
3900 result=my_mreq(size,0);
3901 dbgprintf("new(%d) => %p\n", size, result);
3903 printf("WARNING: new() failed\n");
3907 static int expdelete(void* memory)
3909 dbgprintf("delete(%p)\n", memory);
3915 * local definition - we need only the last two members at this point
3916 * otherwice we would have to introduce here GUIDs and some more types..
3918 typedef struct __attribute__((__packed__))
3921 unsigned long cbFormat; //0x40
3922 char* pbFormat; //0x44
3924 static HRESULT WINAPI expMoCopyMediaType(MY_MEDIA_TYPE* dest, const MY_MEDIA_TYPE* src)
3928 memcpy(dest, src, sizeof(MY_MEDIA_TYPE));
3931 dest->pbFormat = (char*) my_mreq(dest->cbFormat, 0);
3932 if (!dest->pbFormat)
3933 return E_OUTOFMEMORY;
3934 memcpy(dest->pbFormat, src->pbFormat, dest->cbFormat);
3938 static HRESULT WINAPI expMoInitMediaType(MY_MEDIA_TYPE* dest, DWORD cbFormat)
3942 memset(dest, 0, sizeof(MY_MEDIA_TYPE));
3945 dest->pbFormat = (char*) my_mreq(cbFormat, 0);
3946 if (!dest->pbFormat)
3947 return E_OUTOFMEMORY;
3951 static HRESULT WINAPI expMoCreateMediaType(MY_MEDIA_TYPE** dest, DWORD cbFormat)
3955 *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0);
3956 return expMoInitMediaType(*dest, cbFormat);
3958 static HRESULT WINAPI expMoDuplicateMediaType(MY_MEDIA_TYPE** dest, const void* src)
3962 *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0);
3963 return expMoCopyMediaType(*dest, src);
3965 static HRESULT WINAPI expMoFreeMediaType(MY_MEDIA_TYPE* dest)
3971 my_release(dest->pbFormat);
3977 static HRESULT WINAPI expMoDeleteMediaType(MY_MEDIA_TYPE* dest)
3981 expMoFreeMediaType(dest);
3986 static int exp_snprintf( char *str, int size, const char *format, ... )
3990 va_start(va, format);
3991 x=snprintf(str,size,format,va);
3992 dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str,size,format,x);
3998 static int exp_initterm(int v1, int v2)
4000 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1, v2);
4004 /* merged from wine - 2002.04.21 */
4005 typedef void (*_INITTERMFUNC)();
4006 static int exp_initterm(_INITTERMFUNC *start, _INITTERMFUNC *end)
4008 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start, end, *start);
4013 //printf("call _initfunc: from: %p %d\n", *start);
4014 // ok this trick with push/pop is necessary as otherwice
4015 // edi/esi registers are being trashed
4017 __asm__ __volatile__
4034 //printf("done %p %d:%d\n", end);
4042 static void* exp__dllonexit()
4044 // FIXME extract from WINE
4048 static int expwsprintfA(char* string, const char* format, ...)
4052 va_start(va, format);
4053 result = vsprintf(string, format, va);
4054 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string, format, result);
4059 static int expsprintf(char* str, const char* format, ...)
4063 dbgprintf("sprintf(0x%x, %s)\n", str, format);
4064 va_start(args, format);
4065 r = vsprintf(str, format, args);
4069 static int expsscanf(const char* str, const char* format, ...)
4073 dbgprintf("sscanf(%s, %s)\n", str, format);
4074 va_start(args, format);
4075 r = vsscanf(str, format, args);
4079 static void* expfopen(const char* path, const char* mode)
4081 printf("fopen: \"%s\" mode:%s\n", path, mode);
4082 //return fopen(path, mode);
4083 return fdopen(0, mode); // everything on screen
4085 static int expfprintf(void* stream, const char* format, ...)
4089 dbgprintf("fprintf(%p, %s, ...)\n", stream, format);
4091 va_start(args, format);
4092 r = vfprintf((FILE*) stream, format, args);
4098 static int expprintf(const char* format, ...)
4102 dbgprintf("printf(%s, ...)\n", format);
4103 va_start(args, format);
4104 r = vprintf(format, args);
4109 static char* expgetenv(const char* varname)
4111 char* v = getenv(varname);
4112 dbgprintf("getenv(%s) => %s\n", varname, v);
4116 static void* expwcscpy(WCHAR* dst, const WCHAR* src)
4119 while ((*p++ = *src++))
4124 static char* expstrrchr(char* string, int value)
4126 char* result=strrchr(string, value);
4128 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result);
4130 dbgprintf("strrchr(0x%x='%s', %d) => 0", string, string, value);
4134 static char* expstrchr(char* string, int value)
4136 char* result=strchr(string, value);
4138 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result);
4140 dbgprintf("strchr(0x%x='%s', %d) => 0", string, string, value);
4143 static int expstrlen(char* str)
4145 int result=strlen(str);
4146 dbgprintf("strlen(0x%x='%s') => %d\n", str, str, result);
4149 static char* expstrcpy(char* str1, const char* str2)
4151 char* result= strcpy(str1, str2);
4152 dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1, str2, str2, result);
4155 static char* expstrncpy(char* str1, const char* str2, size_t count)
4157 char* result= strncpy(str1, str2, count);
4158 dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1, str2, str2, count, result);
4161 static int expstrcmp(const char* str1, const char* str2)
4163 int result=strcmp(str1, str2);
4164 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
4167 static int expstrncmp(const char* str1, const char* str2,int x)
4169 int result=strncmp(str1, str2,x);
4170 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
4173 static char* expstrcat(char* str1, const char* str2)
4175 char* result = strcat(str1, str2);
4176 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1, str1, str2, str2, result);
4179 static char* exp_strdup(const char* str1)
4181 int l = strlen(str1);
4182 char* result = (char*) my_mreq(l + 1,0);
4184 strcpy(result, str1);
4185 dbgprintf("_strdup(0x%x='%s') => %p\n", str1, str1, result);
4188 static int expisalnum(int c)
4190 int result= (int) isalnum(c);
4191 dbgprintf("isalnum(0x%x='%c' => %d\n", c, c, result);
4194 static int expisspace(int c)
4196 int result= (int) isspace(c);
4197 dbgprintf("isspace(0x%x='%c' => %d\n", c, c, result);
4200 static int expisalpha(int c)
4202 int result= (int) isalpha(c);
4203 dbgprintf("isalpha(0x%x='%c' => %d\n", c, c, result);
4206 static int expisdigit(int c)
4208 int result= (int) isdigit(c);
4209 dbgprintf("isdigit(0x%x='%c' => %d\n", c, c, result);
4212 static void* expmemmove(void* dest, void* src, int n)
4214 void* result = memmove(dest, src, n);
4215 dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest, src, n, result);
4218 static int expmemcmp(void* dest, void* src, int n)
4220 int result = memcmp(dest, src, n);
4221 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest, src, n, result);
4224 static void* expmemcpy(void* dest, void* src, int n)
4226 void *result = memcpy(dest, src, n);
4227 dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest, src, n, result);
4230 static void* expmemset(void* dest, int c, size_t n)
4232 void *result = memset(dest, c, n);
4233 dbgprintf("memset(0x%x, %d, %d) => %p\n", dest, c, n, result);
4236 static time_t exptime(time_t* t)
4238 time_t result = time(t);
4239 dbgprintf("time(0x%x) => %d\n", t, result);
4243 static int exprand(void)
4248 static void expsrand(int seed)
4255 // prefered compilation with -O2 -ffast-math !
4257 static double explog10(double x)
4259 /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4263 static double expcos(double x)
4265 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4270 static long exp_ftol_wrong(double x)
4277 static void explog10(void)
4279 __asm__ __volatile__
4288 static void expcos(void)
4290 __asm__ __volatile__
4299 // this seem to be the only how to make this function working properly
4300 // ok - I've spent tremendous amount of time (many many many hours
4301 // of debuging fixing & testing - it's almost unimaginable - kabi
4303 // _ftol - operated on the float value which is already on the FPU stack
4305 static void exp_ftol(void)
4307 __asm__ __volatile__
4309 "sub $12, %esp \n\t"
4310 "fstcw -2(%ebp) \n\t"
4312 "movw -2(%ebp), %ax \n\t"
4313 "orb $0x0C, %ah \n\t"
4314 "movw %ax, -4(%ebp) \n\t"
4315 "fldcw -4(%ebp) \n\t"
4316 "fistpl -12(%ebp) \n\t"
4317 "fldcw -2(%ebp) \n\t"
4318 "movl -12(%ebp), %eax \n\t"
4319 //Note: gcc 3.03 does not do the following op if it
4320 // knows that ebp=esp
4321 "movl %ebp, %esp \n\t"
4325 #define FPU_DOUBLES(var1,var2) double var1,var2; \
4326 __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var2) : ); \
4327 __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var1) : )
4329 static double exp_CIpow(void)
4333 dbgprintf("_CIpow(%lf, %lf)\n", x, y);
4337 static double exppow(double x, double y)
4339 /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4343 static double expldexp(double x, int expo)
4345 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4346 return ldexp(x, expo);
4349 static double expfrexp(double x, int* expo)
4351 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4352 return frexp(x, expo);
4357 static int exp_stricmp(const char* s1, const char* s2)
4359 return strcasecmp(s1, s2);
4362 /* from declaration taken from Wine sources - this fountion seems to be
4363 * undocumented in any M$ doc */
4364 static int exp_setjmp3(void* jmpbuf, int x)
4366 //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4368 __asm__ __volatile__
4370 //"mov 4(%%esp), %%edx \n\t"
4371 "mov (%%esp), %%eax \n\t"
4372 "mov %%eax, (%%edx) \n\t" // store ebp
4374 //"mov %%ebp, (%%edx) \n\t"
4375 "mov %%ebx, 4(%%edx) \n\t"
4376 "mov %%edi, 8(%%edx) \n\t"
4377 "mov %%esi, 12(%%edx) \n\t"
4378 "mov %%esp, 16(%%edx) \n\t"
4380 "mov 4(%%esp), %%eax \n\t"
4381 "mov %%eax, 20(%%edx) \n\t"
4383 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4384 "movl $0, 36(%%edx) \n\t"
4386 : "d"(jmpbuf) // input
4390 __asm__ __volatile__
4392 "mov %%fs:0, %%eax \n\t" // unsure
4393 "mov %%eax, 24(%%edx) \n\t"
4394 "cmp $0xffffffff, %%eax \n\t"
4396 "mov %%eax, 28(%%edx) \n\t"
4407 static DWORD WINAPI expGetCurrentProcessId(void)
4409 dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4410 return getpid(); //(DWORD)NtCurrentTeb()->pid;
4417 } TIMECAPS, *LPTIMECAPS;
4419 static MMRESULT WINAPI exptimeGetDevCaps(LPTIMECAPS lpCaps, UINT wSize)
4421 dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
4423 lpCaps->wPeriodMin = 1;
4424 lpCaps->wPeriodMax = 65535;
4428 static MMRESULT WINAPI exptimeBeginPeriod(UINT wPeriod)
4430 dbgprintf("timeBeginPeriod(%u) !\n", wPeriod);
4432 if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO;
4437 static MMRESULT WINAPI exptimeEndPeriod(UINT wPeriod)
4439 dbgprintf("timeEndPeriod(%u) !\n", wPeriod);
4441 if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO;
4446 static void WINAPI expGlobalMemoryStatus(
4447 LPMEMORYSTATUS lpmem
4449 static MEMORYSTATUS cached_memstatus;
4450 static int cache_lastchecked = 0;
4454 if (time(NULL)==cache_lastchecked) {
4455 memcpy(lpmem,&cached_memstatus,sizeof(MEMORYSTATUS));
4460 f = fopen( "/proc/meminfo", "r" );
4464 int total, used, free, shared, buffers, cached;
4466 lpmem->dwLength = sizeof(MEMORYSTATUS);
4467 lpmem->dwTotalPhys = lpmem->dwAvailPhys = 0;
4468 lpmem->dwTotalPageFile = lpmem->dwAvailPageFile = 0;
4469 while (fgets( buffer, sizeof(buffer), f ))
4471 /* old style /proc/meminfo ... */
4472 if (sscanf( buffer, "Mem: %d %d %d %d %d %d", &total, &used, &free, &shared, &buffers, &cached ))
4474 lpmem->dwTotalPhys += total;
4475 lpmem->dwAvailPhys += free + buffers + cached;
4477 if (sscanf( buffer, "Swap: %d %d %d", &total, &used, &free ))
4479 lpmem->dwTotalPageFile += total;
4480 lpmem->dwAvailPageFile += free;
4483 /* new style /proc/meminfo ... */
4484 if (sscanf(buffer, "MemTotal: %d", &total))
4485 lpmem->dwTotalPhys = total*1024;
4486 if (sscanf(buffer, "MemFree: %d", &free))
4487 lpmem->dwAvailPhys = free*1024;
4488 if (sscanf(buffer, "SwapTotal: %d", &total))
4489 lpmem->dwTotalPageFile = total*1024;
4490 if (sscanf(buffer, "SwapFree: %d", &free))
4491 lpmem->dwAvailPageFile = free*1024;
4492 if (sscanf(buffer, "Buffers: %d", &buffers))
4493 lpmem->dwAvailPhys += buffers*1024;
4494 if (sscanf(buffer, "Cached: %d", &cached))
4495 lpmem->dwAvailPhys += cached*1024;
4499 if (lpmem->dwTotalPhys)
4501 DWORD TotalPhysical = lpmem->dwTotalPhys+lpmem->dwTotalPageFile;
4502 DWORD AvailPhysical = lpmem->dwAvailPhys+lpmem->dwAvailPageFile;
4503 lpmem->dwMemoryLoad = (TotalPhysical-AvailPhysical)
4504 / (TotalPhysical / 100);
4509 /* FIXME: should do something for other systems */
4510 lpmem->dwMemoryLoad = 0;
4511 lpmem->dwTotalPhys = 16*1024*1024;
4512 lpmem->dwAvailPhys = 16*1024*1024;
4513 lpmem->dwTotalPageFile = 16*1024*1024;
4514 lpmem->dwAvailPageFile = 16*1024*1024;
4516 expGetSystemInfo(&si);
4517 lpmem->dwTotalVirtual = si.lpMaximumApplicationAddress-si.lpMinimumApplicationAddress;
4518 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4519 lpmem->dwAvailVirtual = lpmem->dwTotalVirtual-64*1024;
4520 memcpy(&cached_memstatus,lpmem,sizeof(MEMORYSTATUS));
4521 cache_lastchecked = time(NULL);
4523 /* it appears some memory display programs want to divide by these values */
4524 if(lpmem->dwTotalPageFile==0)
4525 lpmem->dwTotalPageFile++;
4527 if(lpmem->dwAvailPageFile==0)
4528 lpmem->dwAvailPageFile++;
4531 /**********************************************************************
4532 * SetThreadPriority [KERNEL32.@] Sets priority for thread.
4538 static WIN_BOOL WINAPI expSetThreadPriority(
4539 HANDLE hthread, /* [in] Handle to thread */
4540 INT priority) /* [in] Thread priority level */
4542 dbgprintf("SetThreadPriority(%p,%d)\n",hthread,priority);
4546 static void WINAPI expExitProcess( DWORD status )
4548 printf("EXIT - code %ld\n",status);
4552 static INT WINAPI expMessageBoxA(HWND hWnd, LPCSTR text, LPCSTR title, UINT type){
4553 printf("MSGBOX '%s' '%s' (%d)\n",text,title,type);
4555 if (type == MB_ICONHAND && !strlen(text) && !strlen(title))
4561 /* these are needed for mss1 */
4563 /* defined in stubs.s */
4564 void exp_EH_prolog(void);
4566 #include <netinet/in.h>
4567 static WINAPI inline unsigned long int exphtonl(unsigned long int hostlong)
4569 // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4570 return htonl(hostlong);
4573 static WINAPI inline unsigned long int expntohl(unsigned long int netlong)
4575 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4576 return ntohl(netlong);
4578 static void WINAPI expVariantInit(void* p)
4580 printf("InitCommonControls called!\n");
4584 static int WINAPI expRegisterClassA(const void/*WNDCLASSA*/ *wc)
4586 dbgprintf("RegisterClassA(%p) => random id\n", wc);
4587 return time(NULL); /* be precise ! */
4590 static int WINAPI expUnregisterClassA(const char *className, HINSTANCE hInstance)
4592 dbgprintf("UnregisterClassA(%s, %p) => 0\n", className, hInstance);
4597 /* should be fixed bcs it's not fully strlen equivalent */
4598 static int expSysStringByteLen(void *str)
4600 dbgprintf("SysStringByteLen(%p) => %d\n", str, strlen(str));
4604 static int expDirectDrawCreate(void)
4606 dbgprintf("DirectDrawCreate(...) => NULL\n");
4611 typedef struct tagPALETTEENTRY {
4618 /* reversed the first 2 entries */
4619 typedef struct tagLOGPALETTE {
4622 PALETTEENTRY palPalEntry[1];
4625 static HPALETTE WINAPI expCreatePalette(CONST LOGPALETTE *lpgpl)
4630 dbgprintf("CreatePalette(%x) => NULL\n", lpgpl);
4632 i = sizeof(LOGPALETTE)+((lpgpl->palNumEntries-1)*sizeof(PALETTEENTRY));
4633 test = (HPALETTE)malloc(i);
4634 memcpy((void *)test, lpgpl, i);
4639 static int expCreatePalette(void)
4641 dbgprintf("CreatePalette(...) => NULL\n");
4646 static int WINAPI expGetClientRect(HWND win, RECT *r)
4648 dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win, r);
4649 r->right = PSEUDO_SCREEN_WIDTH;
4651 r->bottom = PSEUDO_SCREEN_HEIGHT;
4657 typedef struct tagPOINT {
4663 static int WINAPI expClientToScreen(HWND win, POINT *p)
4665 dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win, p, p->x, p->y);
4673 static int WINAPI expSetThreadIdealProcessor(HANDLE thread, int proc)
4675 dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread, proc);
4679 static int WINAPI expMessageBeep(int type)
4681 dbgprintf("MessageBeep(%d) => 1\n", type);
4685 static int WINAPI expDialogBoxParamA(void *inst, const char *name,
4686 HWND parent, void *dialog_func, void *init_param)
4688 dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
4689 inst, name, name, parent, dialog_func, init_param);
4693 /* needed by imagepower mjpeg2k */
4694 static void *exprealloc(void *ptr, size_t size)
4696 dbgprintf("realloc(0x%x, %x)\n", ptr, size);
4698 return my_mreq(size,0);
4700 return my_realloc(ptr, size);
4703 /* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
4704 static WIN_BOOL WINAPI expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn)
4709 static double expfloor(double x)
4711 dbgprintf("floor(%lf)\n", x);
4715 #define FPU_DOUBLE(var) double var; \
4716 __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var) : )
4718 static double exp_CIcos(void)
4722 dbgprintf("_CIcos(%lf)\n", x);
4726 static double exp_CIsin(void)
4730 dbgprintf("_CIsin(%lf)\n", x);
4744 struct exports* exps;
4748 {#X, Y, (void*)exp##X},
4750 struct exports exp_kernel32[]=
4752 FF(GetVolumeInformationA,-1)
4753 FF(GetDriveTypeA,-1)
4754 FF(GetLogicalDriveStringsA,-1)
4755 FF(IsBadWritePtr, 357)
4756 FF(IsBadReadPtr, 354)
4757 FF(IsBadStringPtrW, -1)
4758 FF(IsBadStringPtrA, -1)
4759 FF(DisableThreadLibraryCalls, -1)
4760 FF(CreateThread, -1)
4761 FF(CreateEventA, -1)
4764 FF(WaitForSingleObject, -1)
4766 FF(WaitForMultipleObjects, -1)
4771 FF(GetSystemInfo, -1)
4779 FF(GetProcessHeap, -1)
4780 FF(VirtualAlloc, -1)
4782 FF(InitializeCriticalSection, -1)
4783 FF(EnterCriticalSection, -1)
4784 FF(LeaveCriticalSection, -1)
4785 FF(DeleteCriticalSection, -1)
4790 FF(GetCurrentThreadId, -1)
4791 FF(GetCurrentProcess, -1)
4796 FF(GlobalReAlloc, -1)
4799 FF(MultiByteToWideChar, 427)
4800 FF(WideCharToMultiByte, -1)
4801 FF(GetVersionExA, -1)
4802 FF(CreateSemaphoreA, -1)
4803 FF(QueryPerformanceCounter, -1)
4804 FF(QueryPerformanceFrequency, -1)
4808 FF(GlobalHandle, -1)
4809 FF(GlobalUnlock, -1)
4811 FF(LoadResource, -1)
4812 FF(ReleaseSemaphore, -1)
4813 FF(FindResourceA, -1)
4814 FF(LockResource, -1)
4815 FF(FreeResource, -1)
4816 FF(SizeofResource, -1)
4818 FF(GetCommandLineA, -1)
4819 FF(GetEnvironmentStringsW, -1)
4820 FF(FreeEnvironmentStringsW, -1)
4821 FF(FreeEnvironmentStringsA, -1)
4822 FF(GetEnvironmentStrings, -1)
4823 FF(GetStartupInfoA, -1)
4824 FF(GetStdHandle, -1)
4827 FF(GetFileAttributesA, -1)
4829 FF(SetHandleCount, -1)
4831 FF(GetModuleFileNameA, -1)
4832 FF(SetUnhandledExceptionFilter, -1)
4833 FF(LoadLibraryA, -1)
4834 FF(GetProcAddress, -1)
4836 FF(CreateFileMappingA, -1)
4837 FF(OpenFileMappingA, -1)
4838 FF(MapViewOfFile, -1)
4839 FF(UnmapViewOfFile, -1)
4841 FF(GetModuleHandleA, -1)
4842 FF(GetProfileIntA, -1)
4843 FF(GetPrivateProfileIntA, -1)
4844 FF(GetPrivateProfileStringA, -1)
4845 FF(WritePrivateProfileStringA, -1)
4846 FF(GetLastError, -1)
4847 FF(SetLastError, -1)
4848 FF(InterlockedIncrement, -1)
4849 FF(InterlockedDecrement, -1)
4850 FF(GetTimeZoneInformation, -1)
4851 FF(OutputDebugStringA, -1)
4852 FF(GetLocalTime, -1)
4853 FF(GetSystemTime, -1)
4854 FF(GetSystemTimeAsFileTime, -1)
4855 FF(GetEnvironmentVariableA, -1)
4856 FF(SetEnvironmentVariableA, -1)
4857 FF(RtlZeroMemory,-1)
4858 FF(RtlMoveMemory,-1)
4859 FF(RtlFillMemory,-1)
4861 FF(FindFirstFileA,-1)
4862 FF(FindNextFileA,-1)
4864 FF(FileTimeToLocalFileTime,-1)
4868 FF(SetFilePointer,-1)
4869 FF(GetTempFileNameA,-1)
4871 FF(GetSystemDirectoryA,-1)
4872 FF(GetWindowsDirectoryA,-1)
4874 FF(GetCurrentDirectoryA,-1)
4875 FF(SetCurrentDirectoryA,-1)
4876 FF(CreateDirectoryA,-1)
4878 FF(GetShortPathNameA,-1)
4879 FF(GetFullPathNameA,-1)
4880 FF(SetErrorMode, -1)
4881 FF(IsProcessorFeaturePresent, -1)
4882 FF(GetProcessAffinityMask, -1)
4883 FF(InterlockedExchange, -1)
4884 FF(InterlockedCompareExchange, -1)
4891 FF(GetProcessVersion,-1)
4892 FF(GetCurrentThread,-1)
4895 FF(DuplicateHandle,-1)
4896 FF(GetTickCount, -1)
4897 FF(SetThreadAffinityMask,-1)
4898 FF(GetCurrentProcessId,-1)
4899 FF(GlobalMemoryStatus,-1)
4900 FF(SetThreadPriority,-1)
4902 {"LoadLibraryExA", -1, (void*)&LoadLibraryExA},
4903 FF(SetThreadIdealProcessor,-1)
4906 struct exports exp_msvcrt[]={
4912 {"??3@YAXPAX@Z", -1, expdelete},
4913 {"??2@YAPAXI@Z", -1, expnew},
4914 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv},
4954 /* needed by frapsvid.dll */
4955 {"strstr",-1,(char *)&strstr},
4956 {"qsort",-1,(void *)&qsort},
4961 {"ceil",-1,(void*)&ceil},
4962 /* needed by imagepower mjpeg2k */
4963 {"clock",-1,(void*)&clock},
4964 {"memchr",-1,(void*)&memchr},
4965 {"vfprintf",-1,(void*)&vfprintf},
4966 // {"realloc",-1,(void*)&realloc},
4968 {"puts",-1,(void*)&puts}
4970 struct exports exp_winmm[]={
4971 FF(GetDriverModuleHandle, -1)
4973 FF(DefDriverProc, -1)
4976 FF(timeGetDevCaps, -1)
4977 FF(timeBeginPeriod, -1)
4979 FF(timeEndPeriod, -1)
4980 FF(waveOutGetNumDevs, -1)
4983 struct exports exp_user32[]={
4988 FF(GetDesktopWindow, -1)
4997 FF(RegisterWindowMessageA,-1)
4998 FF(GetSystemMetrics,-1)
5000 FF(GetSysColorBrush,-1)
5004 FF(RegisterClassA, -1)
5005 FF(UnregisterClassA, -1)
5007 FF(GetWindowRect, -1)
5008 FF(MonitorFromWindow, -1)
5009 FF(MonitorFromRect, -1)
5010 FF(MonitorFromPoint, -1)
5011 FF(EnumDisplayMonitors, -1)
5012 FF(GetMonitorInfoA, -1)
5013 FF(EnumDisplayDevicesA, -1)
5014 FF(GetClientRect, -1)
5015 FF(ClientToScreen, -1)
5016 FF(IsWindowVisible, -1)
5017 FF(GetActiveWindow, -1)
5018 FF(GetClassNameA, -1)
5019 FF(GetClassInfoA, -1)
5020 FF(GetWindowLongA, -1)
5022 FF(GetWindowThreadProcessId, -1)
5023 FF(CreateWindowExA, -1)
5026 FF(DialogBoxParamA, -1)
5028 struct exports exp_advapi32[]={
5030 FF(RegCreateKeyA, -1)
5031 FF(RegCreateKeyExA, -1)
5032 FF(RegEnumKeyExA, -1)
5033 FF(RegEnumValueA, -1)
5035 FF(RegOpenKeyExA, -1)
5036 FF(RegQueryValueExA, -1)
5037 FF(RegSetValueExA, -1)
5038 FF(RegQueryInfoKeyA, -1)
5040 struct exports exp_gdi32[]={
5041 FF(CreateCompatibleDC, -1)
5044 FF(DeleteObject, -1)
5045 FF(GetDeviceCaps, -1)
5046 FF(GetSystemPaletteEntries, -1)
5048 FF(CreatePalette, -1)
5050 FF(CreateRectRgn, -1)
5053 struct exports exp_version[]={
5054 FF(GetFileVersionInfoSizeA, -1)
5056 struct exports exp_ole32[]={
5057 FF(CoCreateFreeThreadedMarshaler,-1)
5058 FF(CoCreateInstance, -1)
5059 FF(CoInitialize, -1)
5060 FF(CoTaskMemAlloc, -1)
5061 FF(CoTaskMemFree, -1)
5062 FF(StringFromGUID2, -1)
5064 // do we really need crtdll ???
5065 // msvcrt is the correct place probably...
5066 struct exports exp_crtdll[]={
5070 struct exports exp_comctl32[]={
5071 FF(StringFromGUID2, -1)
5072 FF(InitCommonControls, 17)
5074 FF(CreateUpDownControl, 16)
5077 struct exports exp_wsock32[]={
5081 struct exports exp_msdmo[]={
5082 FF(memcpy, -1) // just test
5083 FF(MoCopyMediaType, -1)
5084 FF(MoCreateMediaType, -1)
5085 FF(MoDeleteMediaType, -1)
5086 FF(MoDuplicateMediaType, -1)
5087 FF(MoFreeMediaType, -1)
5088 FF(MoInitMediaType, -1)
5090 struct exports exp_oleaut32[]={
5093 FF(SysStringByteLen, 149)
5099 vma: Hint/Ord Member-Name
5104 2305e 167 _adjust_fdiv
5107 22ffc 176 _beginthreadex
5109 2300e 85 __CxxFrameHandler
5113 struct exports exp_pncrt[]={
5114 FF(malloc, -1) // just test
5115 FF(free, -1) // just test
5116 FF(fprintf, -1) // just test
5117 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv},
5120 {"??3@YAXPAX@Z", -1, expdelete},
5121 {"??2@YAPAXI@Z", -1, expnew},
5131 struct exports exp_ddraw[]={
5132 FF(DirectDrawCreate, -1)
5136 struct exports exp_comdlg32[]={
5137 FF(GetOpenFileNameA, -1)
5141 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5143 struct libs libraries[]={
5166 static void ext_stubs(void)
5169 // ax position index
5170 // cx address of printf function
5172 __asm__ __volatile__
5175 "movl $0xdeadbeef, %%eax \n\t"
5176 "movl $0xdeadbeef, %%edx \n\t"
5177 "shl $5, %%eax \n\t" // ax * 32
5178 "addl $0xdeadbeef, %%eax \n\t" // overwrite export_names
5180 "pushl $0xdeadbeef \n\t" // overwrite called_unk
5181 "call *%%edx \n\t" // printf (via dx)
5182 "addl $8, %%esp \n\t"
5183 "xorl %%eax, %%eax \n\t"
5190 __asm__ __volatile__
5193 "movl $0, %%eax \n\t"
5194 "movl $0, %%edx \n\t"
5195 "shl $5, %%eax \n\t" // ax * 32
5196 "addl %0, %%eax \n\t"
5199 "call *%%edx \n\t" // printf (via dx)
5200 "addl $8, %%esp \n\t"
5201 "xorl %%eax, %%eax \n\t"
5203 ::"m"(*export_names), "m"(*called_unk)
5204 : "memory", "edx", "eax"
5210 //static void add_stub(int pos)
5212 extern int unk_exp1;
5214 static char extcode[20000];// place for 200 unresolved exports
5215 static const char* called_unk = "Called unk_%s\n";
5217 static void* add_stub(void)
5219 // generated code in runtime!
5220 char* answ = (char*)extcode+pos*0x30;
5222 memcpy(answ, &unk_exp1, 0x64);
5223 *(int*)(answ+9)=pos;
5224 *(int*)(answ+47)-=((int)answ-(int)&unk_exp1);
5226 memcpy(answ, ext_stubs, 0x2f); // 0x2c is current size
5227 //answ[4] = 0xb8; // movl $0, eax (0xb8 0x00000000)
5228 *((int*) (answ + 5)) = pos;
5229 //answ[9] = 0xba; // movl $0, edx (0xba 0x00000000)
5230 *((long*) (answ + 10)) = (long)printf;
5231 //answ[17] = 0x05; // addl $0, eax (0x05 0x00000000)
5232 *((long*) (answ + 18)) = (long)export_names;
5233 //answ[23] = 0x68; // pushl $0 (0x68 0x00000000)
5234 *((long*) (answ + 24)) = (long)called_unk;
5239 void* LookupExternal(const char* library, int ordinal)
5244 printf("ERROR: library=0\n");
5245 return (void*)ext_unknown;
5247 // printf("%x %x\n", &unk_exp1, &unk_exp2);
5249 dbgprintf("External func %s:%d\n", library, ordinal);
5251 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
5253 if(strcasecmp(library, libraries[i].name))
5255 for(j=0; j<libraries[i].length; j++)
5257 if(ordinal!=libraries[i].exps[j].id)
5259 //printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5260 return libraries[i].exps[j].func;
5264 #ifndef LOADLIB_TRY_NATIVE
5265 /* hack for truespeech and vssh264*/
5266 if (!strcmp(library, "tsd32.dll") || !strcmp(library,"vssh264dec.dll") || !strcmp(library,"LCMW2.dll") || !strcmp(library,"VDODEC32.dll"))
5268 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5274 hand = LoadLibraryA(library);
5277 wm = MODULE32_LookupHMODULE(hand);
5283 func = PE_FindExportedFunction(wm, (LPCSTR) ordinal, 0);
5286 printf("No such ordinal in external dll\n");
5287 FreeLibrary((int)hand);
5291 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5297 if(pos>150)return 0;
5298 sprintf(export_names[pos], "%s:%d", library, ordinal);
5302 void* LookupExternalByName(const char* library, const char* name)
5306 // return (void*)ext_unknown;
5309 printf("ERROR: library=0\n");
5310 return (void*)ext_unknown;
5314 printf("ERROR: name=0\n");
5315 return (void*)ext_unknown;
5317 dbgprintf("External func %s:%s\n", library, name);
5318 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
5320 if(strcasecmp(library, libraries[i].name))
5322 for(j=0; j<libraries[i].length; j++)
5324 if(strcmp(name, libraries[i].exps[j].name))
5326 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5327 return libraries[i].exps[j].func;
5331 #ifndef LOADLIB_TRY_NATIVE
5332 /* hack for vss h264 */
5333 if (!strcmp(library,"vssh264core.dll"))
5335 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5341 hand = LoadLibraryA(library);
5344 wm = MODULE32_LookupHMODULE(hand);
5350 func = PE_FindExportedFunction(wm, name, 0);
5353 printf("No such name in external dll\n");
5354 FreeLibrary((int)hand);
5358 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5364 if(pos>150)return 0;// to many symbols
5365 strcpy(export_names[pos], name);
5369 void my_garbagecollection(void)
5372 int unfree = 0, unfreecnt = 0;
5378 alloc_header* mem = last_alloc + 1;
5379 unfree += my_size(mem);
5381 if (my_release(mem) != 0)
5382 // avoid endless loop when memory is trashed
5383 if (--max_fatal < 0)
5386 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree, unfreecnt, last_alloc, alccnt);