4 * Originally distributed under LPGL 2.1 (or later) by the Wine project.
6 * Modified for use with MPlayer, detailed CVS changelog at
7 * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
9 * File now distributed as part of VLC media player with no modifications.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26 /***********************************************************
28 Win32 emulation code. Functions that emulate
29 responses from corresponding Win32 API calls.
30 Since we are not going to be able to load
31 virtually any DLL, we can only implement this
32 much, adding needed functions with each new codec.
34 Basic principle of implementation: it's not good
35 for DLL to know too much about its environment.
37 ************************************************************/
46 //#define LOADLIB_TRY_NATIVE
50 #define PSEUDO_SCREEN_WIDTH /*640*/800
51 #define PSEUDO_SCREEN_HEIGHT /*480*/600
54 #include "wine/winbase.h"
55 #include "wine/winreg.h"
56 #include "wine/winnt.h"
57 #include "wine/winerror.h"
58 #include "wine/debugtools.h"
59 #include "wine/module.h"
60 #include "wine/winuser.h"
83 #include <sys/types.h>
86 #include <sys/timeb.h>
92 int vsscanf( const char *str, const char *format, va_list ap);
94 /* system has no vsscanf. try to provide one */
95 static int vsscanf( const char *str, const char *format, va_list ap)
97 long p1 = va_arg(ap, long);
98 long p2 = va_arg(ap, long);
99 long p3 = va_arg(ap, long);
100 long p4 = va_arg(ap, long);
101 long p5 = va_arg(ap, long);
102 return sscanf(str, format, p1, p2, p3, p4, p5);
106 static char* def_path = WIN32_PATH;
108 static void do_cpuid(unsigned int ax, unsigned int *regs)
112 "pushl %%ebx; pushl %%ecx; pushl %%edx;"
117 "movl %%edx, 12(%2);"
118 "popl %%edx; popl %%ecx; popl %%ebx;"
120 : "0" (ax), "S" (regs)
123 static unsigned int c_localcount_tsc()
135 static void c_longcount_tsc(long long* z)
140 "movl %%eax, %%ebx\n\t"
142 "movl %%eax, 0(%%ebx)\n\t"
143 "movl %%edx, 4(%%ebx)\n\t"
149 static unsigned int c_localcount_notsc()
154 gettimeofday(&tv, 0);
155 return limit*tv.tv_usec;
157 static void c_longcount_notsc(long long* z)
160 unsigned long long result;
164 gettimeofday(&tv, 0);
167 result+=limit*tv.tv_usec;
170 static unsigned int localcount_stub(void);
171 static void longcount_stub(long long*);
172 static unsigned int (*localcount)()=localcount_stub;
173 static void (*longcount)(long long*)=longcount_stub;
175 static pthread_mutex_t memmut;
177 static unsigned int localcount_stub(void)
179 unsigned int regs[4];
181 if ((regs[3] & 0x00000010) != 0)
183 localcount=c_localcount_tsc;
184 longcount=c_longcount_tsc;
188 localcount=c_localcount_notsc;
189 longcount=c_longcount_notsc;
193 static void longcount_stub(long long* z)
195 unsigned int regs[4];
197 if ((regs[3] & 0x00000010) != 0)
199 localcount=c_localcount_tsc;
200 longcount=c_longcount_tsc;
204 localcount=c_localcount_notsc;
205 longcount=c_longcount_notsc;
211 #include "../mp_msg.h"
213 int LOADER_DEBUG=1; // active only if compiled with -DDETAILED_OUT
214 //#define DETAILED_OUT
215 static inline void dbgprintf(const char* fmt, ...)
223 f=fopen("./log", "a");
228 vfprintf(f, fmt, va);
242 // mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va);
250 char export_names[300][32]={
255 //#define min(x,y) ((x)<(y)?(x):(y))
257 void destroy_event(void* event);
260 typedef struct th_list_t{
263 struct th_list_t* next;
264 struct th_list_t* prev;
268 // have to be cleared by GARBAGE COLLECTOR
269 static unsigned char* heap=NULL;
270 static int heap_counter=0;
271 static tls_t* g_tls=NULL;
272 static th_list* list=NULL;
274 static void test_heap(void)
279 while(offset<heap_counter)
281 if(*(int*)(heap+offset)!=0x433476)
283 printf("Heap corruption at address %d\n", offset);
286 offset+=8+*(int*)(heap+offset+4);
288 for(;offset<min(offset+1000, 20000000); offset++)
289 if(heap[offset]!=0xCC)
291 printf("Free heap corruption at address %d\n", offset);
298 static void* my_mreq(int size, int to_zero)
302 if(test%10==0)printf("Memory: %d bytes allocated\n", heap_counter);
306 heap=malloc(20000000);
307 memset(heap, 0xCC,20000000);
311 printf("No enough memory\n");
314 if(heap_counter+size>20000000)
316 printf("No enough memory\n");
319 *(int*)(heap+heap_counter)=0x433476;
321 *(int*)(heap+heap_counter)=size;
323 printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size, heap_counter-8, heap_counter, heap_counter+size);
325 memset(heap+heap_counter, 0, size);
327 memset(heap+heap_counter, 0xcc, size); // make crash reproducable
329 return heap+heap_counter-size;
331 static int my_release(char* memory)
336 printf("ERROR: free(0)\n");
339 if(*(int*)(memory-8)!=0x433476)
341 printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
344 printf("Freed %d bytes of memory\n", *(int*)(memory-4));
345 // memset(memory-8, *(int*)(memory-4), 0xCC);
351 typedef struct alloc_header_t alloc_header;
352 struct alloc_header_t
354 // let's keep allocated data 16 byte aligned
366 static alloc_header* last_alloc = NULL;
367 static int alccnt = 0;
370 #define AREATYPE_CLIENT 0
371 #define AREATYPE_EVENT 1
372 #define AREATYPE_MUTEX 2
373 #define AREATYPE_COND 3
374 #define AREATYPE_CRITSECT 4
376 /* -- critical sections -- */
380 pthread_mutex_t mutex;
385 void* mreq_private(int size, int to_zero, int type);
386 void* mreq_private(int size, int to_zero, int type)
388 int nsize = size + sizeof(alloc_header);
389 alloc_header* header = (alloc_header* ) malloc(nsize);
393 memset(header, 0, nsize);
397 pthread_mutex_init(&memmut, NULL);
398 pthread_mutex_lock(&memmut);
402 pthread_mutex_lock(&memmut);
403 last_alloc->next = header; /* set next */
406 header->prev = last_alloc;
410 pthread_mutex_unlock(&memmut);
412 header->deadbeef = 0xdeadbeef;
416 //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt);
420 static int my_release(void* memory)
422 alloc_header* header = (alloc_header*) memory - 1;
424 alloc_header* prevmem;
425 alloc_header* nextmem;
430 if (header->deadbeef != (long) 0xdeadbeef)
432 dbgprintf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt);
436 pthread_mutex_lock(&memmut);
441 destroy_event(memory);
444 pthread_cond_destroy((pthread_cond_t*)memory);
447 pthread_mutex_destroy((pthread_mutex_t*)memory);
449 case AREATYPE_CRITSECT:
450 pthread_mutex_destroy(&((struct CRITSECT*)memory)->mutex);
453 //memset(memory, 0xcc, header->size);
457 header->deadbeef = 0;
458 prevmem = header->prev;
459 nextmem = header->next;
462 prevmem->next = nextmem;
464 nextmem->prev = prevmem;
466 if (header == last_alloc)
467 last_alloc = prevmem;
472 pthread_mutex_unlock(&memmut);
474 pthread_mutex_destroy(&memmut);
476 //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt);
481 //memset(header + 1, 0xcc, header->size);
487 static inline void* my_mreq(int size, int to_zero)
489 return mreq_private(size, to_zero, AREATYPE_CLIENT);
492 static int my_size(void* memory)
494 if(!memory) return 0;
495 return ((alloc_header*)memory)[-1].size;
498 static void* my_realloc(void* memory, int size)
503 return my_mreq(size, 0);
504 osize = my_size(memory);
507 ans = my_mreq(size, 0);
508 memcpy(ans, memory, osize);
516 * WINE API - native implementation for several win32 libraries
520 static int WINAPI ext_unknown()
522 printf("Unknown func called\n");
526 static int WINAPI expGetVolumeInformationA( const char *root, char *label,
527 unsigned int label_len, unsigned int *serial,
528 unsigned int *filename_len,unsigned int *flags,
529 char *fsname, unsigned int fsname_len )
531 dbgprintf("GetVolumeInformationA( %s, 0x%x, %ld, 0x%x, 0x%x, 0x%x, 0x%x, %ld) => 1\n",
532 root,label,label_len,serial,filename_len,flags,fsname,fsname_len);
533 //hack Do not return any real data - do nothing
537 static unsigned int WINAPI expGetDriveTypeA( const char *root )
539 dbgprintf("GetDriveTypeA( %s ) => %d\n",root,DRIVE_FIXED);
540 // hack return as Fixed Drive Type
544 static unsigned int WINAPI expGetLogicalDriveStringsA( unsigned int len, char *buffer )
546 dbgprintf("GetLogicalDriveStringsA(%d, 0x%x) => 4\n",len,buffer);
547 // hack only have one drive c:\ in this hack
553 return 4; // 1 drive * 4 bytes (includes null)
557 static int WINAPI expIsBadWritePtr(void* ptr, unsigned int count)
559 int result = (count == 0 || ptr != 0) ? 0 : 1;
560 dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr, count, result);
563 static int WINAPI expIsBadReadPtr(void* ptr, unsigned int count)
565 int result = (count == 0 || ptr != 0) ? 0 : 1;
566 dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr, count, result);
569 static int WINAPI expDisableThreadLibraryCalls(int module)
571 dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module);
575 static HMODULE WINAPI expGetDriverModuleHandle(DRVR* pdrv)
581 result=pdrv->hDriverModule;
582 dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv, result);
586 #define MODULE_HANDLE_kernel32 ((HMODULE)0x120)
587 #define MODULE_HANDLE_user32 ((HMODULE)0x121)
589 #define MODULE_HANDLE_wininet ((HMODULE)0x122)
590 #define MODULE_HANDLE_ddraw ((HMODULE)0x123)
591 #define MODULE_HANDLE_advapi32 ((HMODULE)0x124)
593 #define MODULE_HANDLE_comdlg32 ((HMODULE)0x125)
594 #define MODULE_HANDLE_msvcrt ((HMODULE)0x126)
595 #define MODULE_HANDLE_ole32 ((HMODULE)0x127)
596 #define MODULE_HANDLE_winmm ((HMODULE)0x128)
598 static HMODULE WINAPI expGetModuleHandleA(const char* name)
610 wm=MODULE_FindModule(name);
613 result=(HMODULE)(wm->module);
617 if(name && (strcasecmp(name, "kernel32")==0 || !strcasecmp(name, "kernel32.dll")))
618 result=MODULE_HANDLE_kernel32;
620 if(name && strcasecmp(name, "user32")==0)
621 result=MODULE_HANDLE_user32;
624 dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name, result);
628 static void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize,
629 void* lpStartAddress, void* lpParameter,
630 long dwFlags, long* dwThreadId)
633 // printf("CreateThread:");
634 pth = (pthread_t*) my_mreq(sizeof(pthread_t), 0);
635 pthread_create(pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter);
637 printf( "WARNING: CreateThread flags not supported\n");
639 *dwThreadId=(long)pth;
642 list=my_mreq(sizeof(th_list), 1);
643 list->next=list->prev=NULL;
647 list->next=my_mreq(sizeof(th_list), 0);
648 list->next->prev=list;
649 list->next->next=NULL;
653 dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
654 pSecAttr, dwStackSize, lpStartAddress, lpParameter, dwFlags, dwThreadId, pth);
669 struct mutex_list_t* next;
670 struct mutex_list_t* prev;
672 typedef struct mutex_list_t mutex_list;
673 static mutex_list* mlist=NULL;
675 void destroy_event(void* event)
677 mutex_list* pp=mlist;
678 // printf("garbage collector: destroy_event(%x)\n", event);
681 if(pp==(mutex_list*)event)
684 pp->next->prev=pp->prev;
686 pp->prev->next=pp->next;
687 if(mlist==(mutex_list*)event)
693 printf("%x => ", pp);
704 static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
705 char bInitialState, const char* name)
714 printf("%x => ", pp);
721 mutex_list* pp=mlist;
725 if((strcmp(pp->name, name)==0) && (pp->type==0))
727 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
728 pSecAttr, bManualReset, bInitialState, name, name, pp->pm);
731 }while((pp=pp->prev) != NULL);
733 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
734 pthread_mutex_init(pm, NULL);
735 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
736 pthread_cond_init(pc, NULL);
739 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
740 mlist->next=mlist->prev=NULL;
744 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
745 mlist->next->prev=mlist;
746 mlist->next->next=NULL;
749 mlist->type=0; /* Type Event */
752 mlist->state=bInitialState;
753 mlist->reset=bManualReset;
755 strncpy(mlist->name, name, 127);
759 dbgprintf("ERROR::: CreateEventA failure\n");
762 pthread_mutex_lock(pm);
765 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
766 pSecAttr, bManualReset, bInitialState, name, name, mlist);
768 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
769 pSecAttr, bManualReset, bInitialState, mlist);
773 static void* WINAPI expSetEvent(void* event)
775 mutex_list *ml = (mutex_list *)event;
776 dbgprintf("SetEvent(%x) => 0x1\n", event);
777 pthread_mutex_lock(ml->pm);
778 if (ml->state == 0) {
780 pthread_cond_signal(ml->pc);
782 pthread_mutex_unlock(ml->pm);
786 static void* WINAPI expResetEvent(void* event)
788 mutex_list *ml = (mutex_list *)event;
789 dbgprintf("ResetEvent(0x%x) => 0x1\n", event);
790 pthread_mutex_lock(ml->pm);
792 pthread_mutex_unlock(ml->pm);
797 static void* WINAPI expWaitForSingleObject(void* object, int duration)
799 mutex_list *ml = (mutex_list *)object;
800 // FIXME FIXME FIXME - this value is sometime unititialize !!!
801 int ret = WAIT_FAILED;
802 mutex_list* pp=mlist;
803 if(object == (void*)0xcfcf9898)
806 From GetCurrentThread() documentation:
807 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.
809 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.
811 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.
813 dbgprintf("WaitForSingleObject(thread_handle) called\n");
814 return (void*)WAIT_FAILED;
816 dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object, duration);
818 // loop below was slightly fixed - its used just for checking if
819 // this object really exists in our list
822 while (pp && (pp->pm != ml->pm))
825 dbgprintf("WaitForSingleObject: NotFound\n");
829 pthread_mutex_lock(ml->pm);
833 if (duration == 0) { /* Check Only */
834 if (ml->state == 1) ret = WAIT_FAILED;
835 else ret = WAIT_OBJECT_0;
837 if (duration == -1) { /* INFINITE */
839 pthread_cond_wait(ml->pc,ml->pm);
844 if (duration > 0) { /* Timed Wait */
845 struct timespec abstime;
847 gettimeofday(&now, 0);
848 abstime.tv_sec = now.tv_sec + (now.tv_usec+duration)/1000000;
849 abstime.tv_nsec = ((now.tv_usec+duration)%1000000)*1000;
851 ret=pthread_cond_timedwait(ml->pc,ml->pm,&abstime);
852 if (ret == ETIMEDOUT) ret = WAIT_TIMEOUT;
853 else ret = WAIT_OBJECT_0;
858 case 1: /* Semaphore */
860 if(ml->semaphore==0) ret = WAIT_FAILED;
866 if (duration == -1) {
867 if (ml->semaphore==0)
868 pthread_cond_wait(ml->pc,ml->pm);
873 pthread_mutex_unlock(ml->pm);
875 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object,duration,ml,ret);
880 static void* WINAPI expWaitForMultipleObjects(int count, const void** objects,
881 int WaitAll, int duration)
887 dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
888 count, objects, WaitAll, duration);
890 for (i = 0; i < count; i++)
892 object = (void *)objects[i];
893 ret = expWaitForSingleObject(object, duration);
895 dbgprintf("WaitAll flag not yet supported...\n");
902 static void WINAPI expExitThread(int retcode)
904 dbgprintf("ExitThread(%d)\n", retcode);
905 pthread_exit(&retcode);
908 static HANDLE WINAPI expCreateMutexA(void *pSecAttr,
909 char bInitialOwner, const char *name)
911 HANDLE mlist = (HANDLE)expCreateEventA(pSecAttr, 0, 0, name);
914 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
915 pSecAttr, bInitialOwner, name, mlist);
917 dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
918 pSecAttr, bInitialOwner, mlist);
920 /* 10l to QTX, if CreateMutex returns a real mutex, WaitForSingleObject
921 waits for ever, else it works ;) */
926 static int WINAPI expReleaseMutex(HANDLE hMutex)
928 dbgprintf("ReleaseMutex(%x) => 1\n", hMutex);
929 /* FIXME:XXX !! not yet implemented */
934 static int pf_set = 0;
935 static BYTE PF[64] = {0,};
937 static void DumpSystemInfo(const SYSTEM_INFO* si)
939 dbgprintf(" Processor architecture %d\n", si->u.s.wProcessorArchitecture);
940 dbgprintf(" Page size: %d\n", si->dwPageSize);
941 dbgprintf(" Minimum app address: %d\n", si->lpMinimumApplicationAddress);
942 dbgprintf(" Maximum app address: %d\n", si->lpMaximumApplicationAddress);
943 dbgprintf(" Active processor mask: 0x%x\n", si->dwActiveProcessorMask);
944 dbgprintf(" Number of processors: %d\n", si->dwNumberOfProcessors);
945 dbgprintf(" Processor type: 0x%x\n", si->dwProcessorType);
946 dbgprintf(" Allocation granularity: 0x%x\n", si->dwAllocationGranularity);
947 dbgprintf(" Processor level: 0x%x\n", si->wProcessorLevel);
948 dbgprintf(" Processor revision: 0x%x\n", si->wProcessorRevision);
951 static void WINAPI expGetSystemInfo(SYSTEM_INFO* si)
953 /* FIXME: better values for the two entries below... */
954 static int cache = 0;
955 static SYSTEM_INFO cachedsi;
956 unsigned int regs[4];
957 dbgprintf("GetSystemInfo(%p) =>\n", si);
960 memcpy(si,&cachedsi,sizeof(*si));
964 memset(PF,0,sizeof(PF));
967 cachedsi.u.s.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
968 cachedsi.dwPageSize = getpagesize();
970 /* FIXME: better values for the two entries below... */
971 cachedsi.lpMinimumApplicationAddress = (void *)0x00000000;
972 cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF;
973 cachedsi.dwActiveProcessorMask = 1;
974 cachedsi.dwNumberOfProcessors = 1;
975 cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
976 cachedsi.dwAllocationGranularity = 0x10000;
977 cachedsi.wProcessorLevel = 5; /* pentium */
978 cachedsi.wProcessorRevision = 0x0101;
981 /* mplayer's way to detect PF's */
983 #include "../cpudetect.h"
984 extern CpuCaps gCpuCaps;
987 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
989 PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
990 if (gCpuCaps.has3DNow)
991 PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
993 if (gCpuCaps.cpuType == 4)
995 cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
996 cachedsi.wProcessorLevel = 4;
998 else if (gCpuCaps.cpuType >= 5)
1000 cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1001 cachedsi.wProcessorLevel = 5;
1005 cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1006 cachedsi.wProcessorLevel = 3;
1008 cachedsi.wProcessorRevision = gCpuCaps.cpuStepping;
1009 cachedsi.dwNumberOfProcessors = 1; /* hardcoded */
1013 /* disable cpuid based detection (mplayer's cpudetect.c does this - see above) */
1015 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__svr4__) || defined(__DragonFly__)
1017 switch ((regs[0] >> 8) & 0xf) { // cpu family
1018 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1019 cachedsi.wProcessorLevel= 3;
1021 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1022 cachedsi.wProcessorLevel= 4;
1024 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1025 cachedsi.wProcessorLevel= 5;
1027 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1028 cachedsi.wProcessorLevel= 5;
1030 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1031 cachedsi.wProcessorLevel= 5;
1034 cachedsi.wProcessorRevision = regs[0] & 0xf; // stepping
1035 if (regs[3] & (1 << 8))
1036 PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
1037 if (regs[3] & (1 << 23))
1038 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
1039 if (regs[3] & (1 << 25))
1040 PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
1041 if (regs[3] & (1 << 31))
1042 PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
1043 cachedsi.dwNumberOfProcessors=1;
1045 #endif /* MPLAYER */
1047 /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
1048 fdiv_bug and fpu emulation flags -- alex/MPlayer */
1053 FILE *f = fopen ("/proc/cpuinfo", "r");
1057 while (fgets(line,200,f)!=NULL) {
1060 /* NOTE: the ':' is the only character we can rely on */
1061 if (!(value = strchr(line,':')))
1063 /* terminate the valuename */
1065 /* skip any leading spaces */
1066 while (*value==' ') value++;
1067 if ((s=strchr(value,'\n')))
1071 if (!lstrncmpiA(line, "cpu family",strlen("cpu family"))) {
1072 if (isdigit (value[0])) {
1073 switch (value[0] - '0') {
1074 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1075 cachedsi.wProcessorLevel= 3;
1077 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1078 cachedsi.wProcessorLevel= 4;
1080 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1081 cachedsi.wProcessorLevel= 5;
1083 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1084 cachedsi.wProcessorLevel= 5;
1086 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1087 cachedsi.wProcessorLevel= 5;
1091 /* set the CPU type of the current processor */
1092 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
1095 /* old 2.0 method */
1096 if (!lstrncmpiA(line, "cpu",strlen("cpu"))) {
1097 if ( isdigit (value[0]) && value[1] == '8' &&
1098 value[2] == '6' && value[3] == 0
1100 switch (value[0] - '0') {
1101 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1102 cachedsi.wProcessorLevel= 3;
1104 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1105 cachedsi.wProcessorLevel= 4;
1107 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1108 cachedsi.wProcessorLevel= 5;
1110 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1111 cachedsi.wProcessorLevel= 5;
1113 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1114 cachedsi.wProcessorLevel= 5;
1118 /* set the CPU type of the current processor */
1119 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
1122 if (!lstrncmpiA(line,"fdiv_bug",strlen("fdiv_bug"))) {
1123 if (!lstrncmpiA(value,"yes",3))
1124 PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE;
1128 if (!lstrncmpiA(line,"fpu",strlen("fpu"))) {
1129 if (!lstrncmpiA(value,"no",2))
1130 PF[PF_FLOATING_POINT_EMULATED] = TRUE;
1134 if (!lstrncmpiA(line,"processor",strlen("processor"))) {
1135 /* processor number counts up...*/
1138 if (sscanf(value,"%d",&x))
1139 if (x+1>cachedsi.dwNumberOfProcessors)
1140 cachedsi.dwNumberOfProcessors=x+1;
1142 /* Create a new processor subkey on a multiprocessor
1145 sprintf(buf,"%d",x);
1147 if (!lstrncmpiA(line,"stepping",strlen("stepping"))) {
1150 if (sscanf(value,"%d",&x))
1151 cachedsi.wProcessorRevision = x;
1154 ( (!lstrncmpiA(line,"flags",strlen("flags")))
1155 || (!lstrncmpiA(line,"features",strlen("features"))) )
1157 if (strstr(value,"cx8"))
1158 PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
1159 if (strstr(value,"mmx"))
1160 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
1161 if (strstr(value,"tsc"))
1162 PF[PF_RDTSC_INSTRUCTION_AVAILABLE] = TRUE;
1163 if (strstr(value,"xmm"))
1164 PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
1165 if (strstr(value,"3dnow"))
1166 PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
1171 * ad hoc fix for smp machines.
1172 * some problems on WaitForSingleObject,CreateEvent,SetEvent
1173 * CreateThread ...etc..
1176 cachedsi.dwNumberOfProcessors=1;
1178 #endif /* __linux__ */
1180 memcpy(si,&cachedsi,sizeof(*si));
1184 // avoid undefined expGetSystemInfo
1185 static WIN_BOOL WINAPI expIsProcessorFeaturePresent(DWORD v)
1187 WIN_BOOL result = 0;
1191 expGetSystemInfo(&si);
1193 if(v<64) result=PF[v];
1194 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v, result);
1199 static long WINAPI expGetVersion()
1201 dbgprintf("GetVersion() => 0xC0000004\n");
1202 return 0xC0000004;//Windows 95
1205 static HANDLE WINAPI expHeapCreate(long flags, long init_size, long max_size)
1207 // printf("HeapCreate:");
1210 result=(HANDLE)my_mreq(0x110000, 0);
1212 result=(HANDLE)my_mreq((init_size + 0xfff) & 0x7ffff000 , 0);
1213 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags, init_size, max_size, result);
1217 // this is another dirty hack
1218 // VP31 is releasing one allocated Heap chunk twice
1219 // we will silently ignore this second call...
1220 static void* heapfreehack = 0;
1221 static int heapfreehackshown = 0;
1222 //extern void trapbug(void);
1223 static void* WINAPI expHeapAlloc(HANDLE heap, int flags, int size)
1227 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1228 HeapAlloc returns area larger than size argument :-/
1230 actually according to M$ Doc HeapCreate size should be rounded
1231 to page boundaries thus we should simulate this
1233 //if (size == 22276) trapbug();
1234 z=my_mreq((size + 0xfff) & 0x7ffff000, (flags & HEAP_ZERO_MEMORY));
1236 printf("HeapAlloc failure\n");
1237 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap, flags, size, z);
1238 heapfreehack = 0; // reset
1241 static long WINAPI expHeapDestroy(void* heap)
1243 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap);
1248 static long WINAPI expHeapFree(HANDLE heap, DWORD dwFlags, LPVOID lpMem)
1250 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap, dwFlags, lpMem);
1251 if (heapfreehack != lpMem && lpMem != (void*)0xffffffff
1252 && lpMem != (void*)0xbdbdbdbd)
1253 // 0xbdbdbdbd is for i263_drv.drv && libefence
1254 // it seems to be reading from relased memory
1255 // EF_PROTECT_FREE doens't show any probleme
1259 if (!heapfreehackshown++)
1260 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem);
1262 heapfreehack = lpMem;
1265 static long WINAPI expHeapSize(int heap, int flags, void* pointer)
1267 long result=my_size(pointer);
1268 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap, flags, pointer, result);
1271 static void* WINAPI expHeapReAlloc(HANDLE heap,int flags,void *lpMem,int size)
1273 long orgsize = my_size(lpMem);
1274 dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize,size);
1275 return my_realloc(lpMem, size);
1277 static long WINAPI expGetProcessHeap(void)
1279 dbgprintf("GetProcessHeap() => 1\n");
1282 static void* WINAPI expVirtualAlloc(void* v1, long v2, long v3, long v4)
1284 void* z = VirtualAlloc(v1, v2, v3, v4);
1286 printf("VirtualAlloc failure\n");
1287 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1,v2,v3,v4, z);
1290 static int WINAPI expVirtualFree(void* v1, int v2, int v3)
1292 int result = VirtualFree(v1,v2,v3);
1293 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1,v2,v3, result);
1297 /* we're building a table of critical sections. cs_win pointer uses the DLL
1298 cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1299 struct critsecs_list_t
1301 CRITICAL_SECTION *cs_win;
1302 struct CRITSECT *cs_unix;
1305 /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1306 #undef CRITSECS_NEWTYPE
1307 //#define CRITSECS_NEWTYPE 1
1309 #ifdef CRITSECS_NEWTYPE
1310 /* increased due to ucod needs more than 32 entries */
1311 /* and 64 should be enough for everything */
1312 #define CRITSECS_LIST_MAX 64
1313 static struct critsecs_list_t critsecs_list[CRITSECS_LIST_MAX];
1315 static int critsecs_get_pos(CRITICAL_SECTION *cs_win)
1319 for (i=0; i < CRITSECS_LIST_MAX; i++)
1320 if (critsecs_list[i].cs_win == cs_win)
1325 static int critsecs_get_unused(void)
1329 for (i=0; i < CRITSECS_LIST_MAX; i++)
1330 if (critsecs_list[i].cs_win == NULL)
1335 struct CRITSECT *critsecs_get_unix(CRITICAL_SECTION *cs_win)
1339 for (i=0; i < CRITSECS_LIST_MAX; i++)
1340 if (critsecs_list[i].cs_win == cs_win && critsecs_list[i].cs_unix)
1341 return(critsecs_list[i].cs_unix);
1346 static void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c)
1348 dbgprintf("InitializeCriticalSection(0x%x)\n", c);
1349 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1351 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1352 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1355 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1356 #ifdef CRITSECS_NEWTYPE
1358 struct CRITSECT *cs;
1359 int i = critsecs_get_unused();
1363 printf("InitializeCriticalSection(%p) - no more space in list\n", c);
1366 dbgprintf("got unused space at %d\n", i);
1367 cs = malloc(sizeof(struct CRITSECT));
1370 printf("InitializeCriticalSection(%p) - out of memory\n", c);
1373 pthread_mutex_init(&cs->mutex, NULL);
1375 critsecs_list[i].cs_win = c;
1376 critsecs_list[i].cs_unix = cs;
1377 dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1382 struct CRITSECT* cs = mreq_private(sizeof(struct CRITSECT) + sizeof(CRITICAL_SECTION),
1383 0, AREATYPE_CRITSECT);
1384 pthread_mutex_init(&cs->mutex, NULL);
1386 cs->deadbeef = 0xdeadbeef;
1393 static void WINAPI expEnterCriticalSection(CRITICAL_SECTION* c)
1395 #ifdef CRITSECS_NEWTYPE
1396 struct CRITSECT* cs = critsecs_get_unix(c);
1398 struct CRITSECT* cs = (*(struct CRITSECT**)c);
1400 dbgprintf("EnterCriticalSection(0x%x) %p\n",c, cs);
1403 dbgprintf("entered uninitialized critisec!\n");
1404 expInitializeCriticalSection(c);
1405 #ifdef CRITSECS_NEWTYPE
1406 cs=critsecs_get_unix(c);
1408 cs = (*(struct CRITSECT**)c);
1410 dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c);
1413 if(cs->id==pthread_self())
1415 pthread_mutex_lock(&(cs->mutex));
1417 cs->id=pthread_self();
1420 static void WINAPI expLeaveCriticalSection(CRITICAL_SECTION* c)
1422 #ifdef CRITSECS_NEWTYPE
1423 struct CRITSECT* cs = critsecs_get_unix(c);
1425 struct CRITSECT* cs = (*(struct CRITSECT**)c);
1427 // struct CRITSECT* cs=(struct CRITSECT*)c;
1428 dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c, cs);
1431 dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c);
1437 pthread_mutex_unlock(&(cs->mutex));
1440 dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c);
1444 static void expfree(void* mem); /* forward declaration */
1446 static void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c)
1448 #ifdef CRITSECS_NEWTYPE
1449 struct CRITSECT* cs = critsecs_get_unix(c);
1451 struct CRITSECT* cs= (*(struct CRITSECT**)c);
1453 // struct CRITSECT* cs=(struct CRITSECT*)c;
1454 dbgprintf("DeleteCriticalSection(0x%x)\n",c);
1458 dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c);
1464 dbgprintf("Win32 Warning: Deleting unlocked Critical Section %p!!\n", c);
1465 pthread_mutex_unlock(&(cs->mutex));
1469 pthread_mutex_destroy(&(cs->mutex));
1470 // released by GarbageCollector in my_relase otherwise
1473 #ifdef CRITSECS_NEWTYPE
1475 int i = critsecs_get_pos(c);
1479 printf("DeleteCriticalSection(%p) error (critsec not found)\n", c);
1483 critsecs_list[i].cs_win = NULL;
1484 expfree(critsecs_list[i].cs_unix);
1485 critsecs_list[i].cs_unix = NULL;
1486 dbgprintf("DeleteCriticalSection -> itemno=%d\n", i);
1491 static int WINAPI expGetCurrentThreadId()
1493 dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1494 return pthread_self();
1496 static int WINAPI expGetCurrentProcess()
1498 dbgprintf("GetCurrentProcess() => %d\n", getpid());
1503 // this version is required for Quicktime codecs (.qtx/.qts) to work.
1504 // (they assume some pointers at FS: segment)
1506 extern void* fs_seg;
1508 //static int tls_count;
1509 static int tls_use_map[64];
1510 static int WINAPI expTlsAlloc()
1514 if(tls_use_map[i]==0)
1517 dbgprintf("TlsAlloc() => %d\n",i);
1520 dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1524 //static int WINAPI expTlsSetValue(DWORD index, void* value)
1525 static int WINAPI expTlsSetValue(int index, void* value)
1527 dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index,value);
1528 // if((index<0) || (index>64))
1531 *(void**)((char*)fs_seg+0x88+4*index) = value;
1535 static void* WINAPI expTlsGetValue(DWORD index)
1537 dbgprintf("TlsGetValue(%d)\n",index);
1538 // if((index<0) || (index>64))
1539 if((index>=64)) return NULL;
1540 return *(void**)((char*)fs_seg+0x88+4*index);
1543 static int WINAPI expTlsFree(int idx)
1545 int index = (int) idx;
1546 dbgprintf("TlsFree(%d)\n",index);
1547 if((index<0) || (index>64))
1549 tls_use_map[index]=0;
1561 static void* WINAPI expTlsAlloc()
1565 g_tls=my_mreq(sizeof(tls_t), 0);
1566 g_tls->next=g_tls->prev=NULL;
1570 g_tls->next=my_mreq(sizeof(tls_t), 0);
1571 g_tls->next->prev=g_tls;
1572 g_tls->next->next=NULL;
1575 dbgprintf("TlsAlloc() => 0x%x\n", g_tls);
1577 g_tls->value=0; /* XXX For Divx.dll */
1581 static int WINAPI expTlsSetValue(void* idx, void* value)
1583 tls_t* index = (tls_t*) idx;
1592 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index, value, result );
1595 static void* WINAPI expTlsGetValue(void* idx)
1597 tls_t* index = (tls_t*) idx;
1602 result=index->value;
1603 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index, result);
1606 static int WINAPI expTlsFree(void* idx)
1608 tls_t* index = (tls_t*) idx;
1615 index->next->prev=index->prev;
1617 index->prev->next=index->next;
1619 g_tls = index->prev;
1620 my_release((void*)index);
1623 dbgprintf("TlsFree(index 0x%x) => %d\n", index, result);
1628 static void* WINAPI expLocalAlloc(int flags, int size)
1630 void* z = my_mreq(size, (flags & GMEM_ZEROINIT));
1632 printf("LocalAlloc() failed\n");
1633 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z);
1637 static void* WINAPI expLocalReAlloc(int handle,int size, int flags)
1643 if (flags & LMEM_MODIFY) {
1644 dbgprintf("LocalReAlloc MODIFY\n");
1645 return (void *)handle;
1647 oldsize = my_size((void *)handle);
1648 newpointer = my_realloc((void *)handle,size);
1649 dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle,size,oldsize, flags,newpointer);
1654 static void* WINAPI expLocalLock(void* z)
1656 dbgprintf("LocalLock(0x%x) => 0x%x\n", z, z);
1660 static void* WINAPI expGlobalAlloc(int flags, int size)
1663 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size, flags);
1665 z=my_mreq(size, (flags & GMEM_ZEROINIT));
1666 //z=calloc(size, 1);
1669 printf("GlobalAlloc() failed\n");
1670 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z);
1673 static void* WINAPI expGlobalLock(void* z)
1675 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z, z);
1678 // pvmjpg20 - but doesn't work anyway
1679 static int WINAPI expGlobalSize(void* amem)
1683 alloc_header* header = last_alloc;
1684 alloc_header* mem = (alloc_header*) amem - 1;
1687 pthread_mutex_lock(&memmut);
1690 if (header->deadbeef != 0xdeadbeef)
1692 dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt);
1698 size = header->size;
1702 header = header->prev;
1704 pthread_mutex_unlock(&memmut);
1707 dbgprintf("GlobalSize(0x%x)\n", amem);
1711 static int WINAPI expLoadIconA( long hinstance, char *name )
1713 dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance,name);
1717 static int WINAPI expLoadStringA(long instance, long id, void* buf, long size)
1719 int result=LoadStringA(instance, id, buf, size);
1721 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1722 instance, id, buf, size, result, buf);
1724 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1725 // instance, id, buf, size, result);
1729 static long WINAPI expMultiByteToWideChar(long v1, long v2, char* s1, long siz1, short* s2, int siz2)
1738 if(siz1>siz2/2)siz1=siz2/2;
1739 for(i=1; i<=siz1; i++)
1749 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1750 "size %d, dest buffer 0x%x, dest size %d) => %d\n",
1751 v1, v2, s1, s1, siz1, s2, siz2, result);
1753 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1754 "size %d, dest buffer 0x%x, dest size %d) =>\n",
1755 v1, v2, siz1, s2, siz2, result);
1758 static void wch_print(const short* str)
1760 dbgprintf(" src: ");
1761 while(*str)dbgprintf("%c", *str++);
1764 static long WINAPI expWideCharToMultiByte(long v1, long v2, short* s1, long siz1,
1765 char* s2, int siz2, char* c3, int* siz3)
1768 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1769 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1, v2, s1, siz1, s2, siz2, c3, siz3);
1770 result=WideCharToMultiByte(v1, v2, s1, siz1, s2, siz2, c3, siz3);
1771 dbgprintf("=> %d\n", result);
1772 //if(s1)wch_print(s1);
1773 if(s2)dbgprintf(" dest: %s\n", s2);
1776 static long WINAPI expGetVersionExA(OSVERSIONINFOA* c)
1778 dbgprintf("GetVersionExA(0x%x) => 1\n");
1779 c->dwOSVersionInfoSize=sizeof(*c);
1780 c->dwMajorVersion=4;
1781 c->dwMinorVersion=0;
1782 c->dwBuildNumber=0x4000457;
1784 // leave it here for testing win9x-only codecs
1785 c->dwPlatformId=VER_PLATFORM_WIN32_WINDOWS;
1786 strcpy(c->szCSDVersion, " B");
1788 c->dwPlatformId=VER_PLATFORM_WIN32_NT; // let's not make DLL assume that it can read CR* registers
1789 strcpy(c->szCSDVersion, "Service Pack 3");
1791 dbgprintf(" Major version: 4\n Minor version: 0\n Build number: 0x4000457\n"
1792 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 3'\n");
1795 static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count,
1796 long max_count, char* name)
1798 pthread_mutex_t *pm;
1802 printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1806 printf("%p => ", pp);
1813 mutex_list* pp=mlist;
1817 if((strcmp(pp->name, name)==0) && (pp->type==1))
1819 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1820 v1, init_count, max_count, name, name, mlist);
1821 return (HANDLE)mlist;
1823 }while((pp=pp->prev) != NULL);
1825 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
1826 pthread_mutex_init(pm, NULL);
1827 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
1828 pthread_cond_init(pc, NULL);
1831 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1832 mlist->next=mlist->prev=NULL;
1836 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1837 mlist->next->prev=mlist;
1838 mlist->next->next=NULL;
1840 // printf("new semaphore %p\n", mlist);
1842 mlist->type=1; /* Type Semaphore */
1847 mlist->semaphore=init_count;
1849 strncpy(mlist->name, name, 64);
1853 dbgprintf("ERROR::: CreateSemaphoreA failure\n");
1855 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1856 v1, init_count, max_count, name, name, mlist);
1858 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1859 v1, init_count, max_count, mlist);
1860 return (HANDLE)mlist;
1863 static long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count)
1865 // The state of a semaphore object is signaled when its count
1866 // is greater than zero and nonsignaled when its count is equal to zero
1867 // Each time a waiting thread is released because of the semaphore's signaled
1868 // state, the count of the semaphore is decreased by one.
1869 mutex_list *ml = (mutex_list *)hsem;
1871 pthread_mutex_lock(ml->pm);
1872 if (prev_count != 0) *prev_count = ml->semaphore;
1873 if (ml->semaphore == 0) pthread_cond_signal(ml->pc);
1874 ml->semaphore += increment;
1875 pthread_mutex_unlock(ml->pm);
1876 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1877 hsem, increment, prev_count);
1882 static long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
1884 long result=RegOpenKeyExA(key, subkey, reserved, access, newkey);
1885 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
1886 key, subkey, reserved, access, newkey, result);
1887 if(newkey)dbgprintf(" New key: 0x%x\n", *newkey);
1890 static long WINAPI expRegCloseKey(long key)
1892 long result=RegCloseKey(key);
1893 dbgprintf("RegCloseKey(0x%x) => %d\n", key, result);
1896 static long WINAPI expRegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count)
1898 long result=RegQueryValueExA(key, value, reserved, type, data, count);
1899 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
1900 " => 0x%x\n", key, value, reserved, data, count, result);
1901 if(data && count)dbgprintf(" read %d bytes: '%s'\n", *count, data);
1905 //from wine source dlls/advapi32/registry.c
1906 static long WINAPI expRegCreateKeyA(long hkey, const char* name, int *retkey)
1908 dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey,name,retkey);
1909 return RegCreateKeyExA( hkey, name, 0, NULL,REG_OPTION_NON_VOLATILE,
1910 KEY_ALL_ACCESS , NULL, retkey, NULL );
1913 static long WINAPI expRegCreateKeyExA(long key, const char* name, long reserved,
1914 void* classs, long options, long security,
1915 void* sec_attr, int* newkey, int* status)
1917 long result=RegCreateKeyExA(key, name, reserved, classs, options, security, sec_attr, newkey, status);
1918 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
1919 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
1920 key, name, name, reserved, classs, options, security, sec_attr, newkey, status, result);
1921 if(!result && newkey) dbgprintf(" New key: 0x%x\n", *newkey);
1922 if(!result && status) dbgprintf(" New key status: 0x%x\n", *status);
1925 static long WINAPI expRegSetValueExA(long key, const char* name, long v1, long v2, void* data, long size)
1927 long result=RegSetValueExA(key, name, v1, v2, data, size);
1928 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
1929 key, name, v1, v2, data, *(int*)data, data, size, result);
1933 static long WINAPI expRegOpenKeyA (long hKey, LPCSTR lpSubKey, int* phkResult)
1935 long result=RegOpenKeyExA(hKey, lpSubKey, 0, 0, phkResult);
1936 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
1937 hKey, lpSubKey, phkResult, result);
1938 if(!result && phkResult) dbgprintf(" New key: 0x%x\n", *phkResult);
1942 static DWORD WINAPI expRegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count,
1943 LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count)
1945 return RegEnumValueA(hkey, index, value, val_count,
1946 reserved, type, data, count);
1949 static DWORD WINAPI expRegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName,
1950 LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass,
1951 LPFILETIME lpftLastWriteTime)
1953 return RegEnumKeyExA(hKey, dwIndex, lpName, lpcbName, lpReserved, lpClass,
1954 lpcbClass, lpftLastWriteTime);
1957 static long WINAPI expQueryPerformanceCounter(long long* z)
1960 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z, *z);
1965 * dummy function RegQueryInfoKeyA(), required by vss codecs
1967 static DWORD WINAPI expRegQueryInfoKeyA( HKEY hkey, LPSTR class, LPDWORD class_len, LPDWORD reserved,
1968 LPDWORD subkeys, LPDWORD max_subkey, LPDWORD max_class,
1969 LPDWORD values, LPDWORD max_value, LPDWORD max_data,
1970 LPDWORD security, FILETIME *modif )
1972 return ERROR_SUCCESS;
1976 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
1978 static double linux_cpuinfo_freq()
1985 f = fopen ("/proc/cpuinfo", "r");
1987 while (fgets(line,sizeof(line),f)!=NULL) {
1988 /* NOTE: the ':' is the only character we can rely on */
1989 if (!(value = strchr(line,':')))
1991 /* terminate the valuename */
1993 /* skip any leading spaces */
1994 while (*value==' ') value++;
1995 if ((s=strchr(value,'\n')))
1998 if (!strncasecmp(line, "cpu MHz",strlen("cpu MHz"))
1999 && sscanf(value, "%lf", &freq) == 1) {
2010 static double solaris_kstat_freq()
2012 #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
2014 * try to extract the CPU speed from the solaris kernel's kstat data
2018 kstat_named_t *kdata;
2024 ksp = kstat_lookup(kc, "cpu_info", 0, "cpu_info0");
2026 /* kstat found and name/value pairs? */
2027 if (ksp != NULL && ksp->ks_type == KSTAT_TYPE_NAMED)
2029 /* read the kstat data from the kernel */
2030 if (kstat_read(kc, ksp, NULL) != -1)
2033 * lookup desired "clock_MHz" entry, check the expected
2036 kdata = (kstat_named_t *)kstat_data_lookup(ksp, "clock_MHz");
2037 if (kdata != NULL && kdata->data_type == KSTAT_DATA_INT32)
2038 mhz = kdata->value.i32;
2046 #endif /* HAVE_LIBKSTAT */
2047 return -1; // kstat stuff is not available, CPU freq is unknown
2051 * Measure CPU freq using the pentium's time stamp counter register (TSC)
2053 static double tsc_freq()
2055 static double ofreq=0.0;
2059 if (ofreq != 0.0) return ofreq;
2060 while(i==time(NULL));
2063 while(i==time(NULL));
2065 ofreq = (double)(y-x)/1000.;
2069 static double CPU_Freq()
2073 if ((freq = linux_cpuinfo_freq()) > 0)
2076 if ((freq = solaris_kstat_freq()) > 0)
2082 static long WINAPI expQueryPerformanceFrequency(long long* z)
2084 *z=(long long)CPU_Freq();
2085 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z, *z);
2088 static long WINAPI exptimeGetTime()
2092 gettimeofday(&t, 0);
2093 result=1000*t.tv_sec+t.tv_usec/1000;
2094 dbgprintf("timeGetTime() => %d\n", result);
2097 static void* WINAPI expLocalHandle(void* v)
2099 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v, v);
2103 static void* WINAPI expGlobalHandle(void* v)
2105 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v, v);
2108 static int WINAPI expGlobalUnlock(void* v)
2110 dbgprintf("GlobalUnlock(0x%x) => 1\n", v);
2113 static void* WINAPI expGlobalFree(void* v)
2115 dbgprintf("GlobalFree(0x%x) => 0\n", v);
2121 static void* WINAPI expGlobalReAlloc(void* v, int size, int flags)
2123 void* result=my_realloc(v, size);
2124 //void* result=realloc(v, size);
2125 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v,size,flags,result);
2129 static int WINAPI expLocalUnlock(void* v)
2131 dbgprintf("LocalUnlock(0x%x) => 1\n", v);
2135 static void* WINAPI expLocalFree(void* v)
2137 dbgprintf("LocalFree(0x%x) => 0\n", v);
2141 static HRSRC WINAPI expFindResourceA(HMODULE module, char* name, char* type)
2145 result=FindResourceA(module, name, type);
2146 dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2147 module, name, HIWORD(name) ? name : "UNICODE", type, HIWORD(type) ? type : "UNICODE", result);
2151 extern HRSRC WINAPI LoadResource(HMODULE, HRSRC);
2152 static HGLOBAL WINAPI expLoadResource(HMODULE module, HRSRC res)
2154 HGLOBAL result=LoadResource(module, res);
2155 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module, res, result);
2158 static void* WINAPI expLockResource(long res)
2160 void* result=LockResource(res);
2161 dbgprintf("LockResource(0x%x) => 0x%x\n", res, result);
2164 static int WINAPI expFreeResource(long res)
2166 int result=FreeResource(res);
2167 dbgprintf("FreeResource(0x%x) => %d\n", res, result);
2172 static int WINAPI expCloseHandle(long v1)
2174 dbgprintf("CloseHandle(0x%x) => 1\n", v1);
2175 /* do not close stdin,stdout and stderr */
2182 static const char* WINAPI expGetCommandLineA()
2184 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2185 return "c:\\aviplay.exe";
2187 static short envs[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2188 static LPWSTR WINAPI expGetEnvironmentStringsW()
2190 dbgprintf("GetEnvironmentStringsW() => 0\n", envs);
2193 static void * WINAPI expRtlZeroMemory(void *p, size_t len)
2195 void* result=memset(p,0,len);
2196 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p,len,result);
2199 static void * WINAPI expRtlMoveMemory(void *dst, void *src, size_t len)
2201 void* result=memmove(dst,src,len);
2202 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst,src,len,result);
2206 static void * WINAPI expRtlFillMemory(void *p, int ch, size_t len)
2208 void* result=memset(p,ch,len);
2209 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p,ch,len,result);
2212 static int WINAPI expFreeEnvironmentStringsW(short* strings)
2214 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings);
2217 static int WINAPI expFreeEnvironmentStringsA(char* strings)
2219 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings);
2223 static const char ch_envs[]=
2224 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2225 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2226 static LPCSTR WINAPI expGetEnvironmentStrings()
2228 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs);
2229 return (LPCSTR)ch_envs;
2230 // dbgprintf("GetEnvironmentStrings() => 0\n");
2234 static int WINAPI expGetStartupInfoA(STARTUPINFOA *s)
2237 dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2238 memset(s, 0, sizeof(*s));
2240 // s->lpReserved="Reserved";
2241 // s->lpDesktop="Desktop";
2242 // s->lpTitle="Title";
2244 // s->dwXSize=s->dwYSize=200;
2245 s->dwFlags=s->wShowWindow=1;
2246 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2247 dbgprintf(" cb=%d\n", s->cb);
2248 dbgprintf(" lpReserved='%s'\n", s->lpReserved);
2249 dbgprintf(" lpDesktop='%s'\n", s->lpDesktop);
2250 dbgprintf(" lpTitle='%s'\n", s->lpTitle);
2251 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2252 s->dwX, s->dwY, s->dwXSize, s->dwYSize);
2253 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2254 s->dwXCountChars, s->dwYCountChars, s->dwFillAttribute);
2255 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2256 s->dwFlags, s->wShowWindow, s->cbReserved2);
2257 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2258 s->lpReserved2, s->hStdInput, s->hStdOutput, s->hStdError);
2262 static int WINAPI expGetStdHandle(int z)
2264 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z+0x1234);
2269 #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2270 #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2273 static int WINAPI expGetFileType(int handle)
2275 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle);
2279 static int WINAPI expGetFileAttributesA(char *filename)
2281 dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename);
2282 if (strstr(filename, "QuickTime.qts"))
2283 return FILE_ATTRIBUTE_SYSTEM;
2284 return FILE_ATTRIBUTE_NORMAL;
2287 static int WINAPI expSetHandleCount(int count)
2289 dbgprintf("SetHandleCount(0x%x) => 1\n", count);
2292 static int WINAPI expGetACP(void)
2294 dbgprintf("GetACP() => 0\n");
2297 extern WINE_MODREF *MODULE32_LookupHMODULE(HMODULE m);
2298 static int WINAPI expGetModuleFileNameA(int module, char* s, int len)
2302 //printf("File name of module %X (%s) requested\n", module, s);
2304 if (module == 0 && len >= 12)
2306 /* return caller program name */
2307 strcpy(s, "aviplay.dll");
2318 strcpy(s, "c:\\windows\\system\\");
2319 mr=MODULE32_LookupHMODULE(module);
2321 strcat(s, "aviplay.dll");
2323 if(strrchr(mr->filename, '/')==NULL)
2324 strcat(s, mr->filename);
2326 strcat(s, strrchr(mr->filename, '/')+1);
2329 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2330 module, s, len, result);
2332 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2333 module, s, len, result, s);
2337 static int WINAPI expSetUnhandledExceptionFilter(void* filter)
2339 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter);
2340 return 1;//unsupported and probably won't ever be supported
2343 static int WINAPI expLoadLibraryA(char* name)
2350 // we skip to the last backslash
2351 // this is effectively eliminating weird characters in
2352 // the text output windows
2354 lastbc = strrchr(name, '\\');
2361 name[i] = *lastbc++;
2366 if(strncmp(name, "c:\\windows\\", 11)==0) name += 11;
2367 if(strncmp(name, ".\\", 2)==0) name += 2;
2369 dbgprintf("Entering LoadLibraryA(%s)\n", name);
2371 // PIMJ and VIVO audio are loading kernel32.dll
2372 if (strcasecmp(name, "kernel32.dll") == 0 || strcasecmp(name, "kernel32") == 0)
2373 return MODULE_HANDLE_kernel32;
2374 // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2375 /* exported -> do not return failed! */
2377 if (strcasecmp(name, "user32.dll") == 0 || strcasecmp(name, "user32") == 0)
2378 // return MODULE_HANDLE_kernel32;
2379 return MODULE_HANDLE_user32;
2382 if (strcasecmp(name, "wininet.dll") == 0 || strcasecmp(name, "wininet") == 0)
2383 return MODULE_HANDLE_wininet;
2384 if (strcasecmp(name, "ddraw.dll") == 0 || strcasecmp(name, "ddraw") == 0)
2385 return MODULE_HANDLE_ddraw;
2386 if (strcasecmp(name, "advapi32.dll") == 0 || strcasecmp(name, "advapi32") == 0)
2387 return MODULE_HANDLE_advapi32;
2390 if (strcasecmp(name, "comdlg32.dll") == 0 || strcasecmp(name, "comdlg32") == 0)
2391 return MODULE_HANDLE_comdlg32;
2392 if (strcasecmp(name, "msvcrt.dll") == 0 || strcasecmp(name, "msvcrt") == 0)
2393 return MODULE_HANDLE_msvcrt;
2394 if (strcasecmp(name, "ole32.dll") == 0 || strcasecmp(name, "ole32") == 0)
2395 return MODULE_HANDLE_ole32;
2396 if (strcasecmp(name, "winmm.dll") == 0 || strcasecmp(name, "winmm") == 0)
2397 return MODULE_HANDLE_winmm;
2399 result=LoadLibraryA(name);
2400 dbgprintf("Returned LoadLibraryA(0x%x='%s'), def_path=%s => 0x%x\n", name, name, def_path, result);
2405 static int WINAPI expFreeLibrary(int module)
2408 int result=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2410 int result=FreeLibrary(module);
2412 dbgprintf("FreeLibrary(0x%x) => %d\n", module, result);
2416 static void* WINAPI expGetProcAddress(HMODULE mod, char* name)
2420 case MODULE_HANDLE_kernel32:
2421 result=LookupExternalByName("kernel32.dll", name); break;
2422 case MODULE_HANDLE_user32:
2423 result=LookupExternalByName("user32.dll", name); break;
2425 case MODULE_HANDLE_wininet:
2426 result=LookupExternalByName("wininet.dll", name); break;
2427 case MODULE_HANDLE_ddraw:
2428 result=LookupExternalByName("ddraw.dll", name); break;
2429 case MODULE_HANDLE_advapi32:
2430 result=LookupExternalByName("advapi32.dll", name); break;
2432 case MODULE_HANDLE_comdlg32:
2433 result=LookupExternalByName("comdlg32.dll", name); break;
2434 case MODULE_HANDLE_msvcrt:
2435 result=LookupExternalByName("msvcrt.dll", name); break;
2436 case MODULE_HANDLE_ole32:
2437 result=LookupExternalByName("ole32.dll", name); break;
2438 case MODULE_HANDLE_winmm:
2439 result=LookupExternalByName("winmm.dll", name); break;
2441 result=GetProcAddress(mod, name);
2443 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod, name, result);
2447 static long WINAPI expCreateFileMappingA(int hFile, void* lpAttr,
2448 long flProtect, long dwMaxHigh,
2449 long dwMaxLow, const char* name)
2451 long result=CreateFileMappingA(hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name);
2453 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2454 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2455 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, result);
2457 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2458 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2459 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name, name, result);
2463 static long WINAPI expOpenFileMappingA(long hFile, long hz, const char* name)
2465 long result=OpenFileMappingA(hFile, hz, name);
2467 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2470 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2471 hFile, hz, name, name, result);
2475 static void* WINAPI expMapViewOfFile(HANDLE file, DWORD mode, DWORD offHigh,
2476 DWORD offLow, DWORD size)
2478 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2479 file,mode,offHigh,offLow,size,(char*)file+offLow);
2480 return (char*)file+offLow;
2483 static void* WINAPI expUnmapViewOfFile(void* view)
2485 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view);
2489 static void* WINAPI expSleep(int time)
2492 /* solaris doesn't have thread safe usleep */
2493 struct timespec tsp;
2494 tsp.tv_sec = time / 1000000;
2495 tsp.tv_nsec = (time % 1000000) * 1000;
2496 nanosleep(&tsp, NULL);
2500 dbgprintf("Sleep(%d) => 0\n", time);
2504 // why does IV32 codec want to call this? I don't know ...
2505 static int WINAPI expCreateCompatibleDC(int hdc)
2508 //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2509 dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc, dc);
2513 static int WINAPI expGetDeviceCaps(int hdc, int unk)
2515 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc, unk);
2517 #define BITSPIXEL 12
2519 if (unk == BITSPIXEL)
2527 static WIN_BOOL WINAPI expDeleteDC(int hdc)
2529 dbgprintf("DeleteDC(0x%x) => 0\n", hdc);
2535 static WIN_BOOL WINAPI expDeleteObject(int hdc)
2537 dbgprintf("DeleteObject(0x%x) => 1\n", hdc);
2538 /* FIXME - implement code here */
2542 /* btvvc32.drv wants this one */
2543 static void* WINAPI expGetWindowDC(int hdc)
2545 dbgprintf("GetWindowDC(%d) => 0x0\n", hdc);
2550 static int WINAPI expGetWindowRect(HWND win, RECT *r)
2552 dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win, r);
2553 /* (win == 0) => desktop */
2554 r->right = PSEUDO_SCREEN_WIDTH;
2556 r->bottom = PSEUDO_SCREEN_HEIGHT;
2561 static int WINAPI expMonitorFromWindow(HWND win, int flags)
2563 dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win, flags);
2567 static int WINAPI expMonitorFromRect(RECT *r, int flags)
2569 dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r, flags);
2573 static int WINAPI expMonitorFromPoint(void *p, int flags)
2575 dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p, flags);
2579 static int WINAPI expEnumDisplayMonitors(void *dc, RECT *r,
2580 int WINAPI (*callback_proc)(), void *callback_param)
2582 dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2583 dc, r, callback_proc, callback_param);
2584 return callback_proc(0, dc, r, callback_param);
2588 typedef struct tagMONITORINFO {
2593 } MONITORINFO, *LPMONITORINFO;
2596 #define CCHDEVICENAME 8
2597 typedef struct tagMONITORINFOEX {
2602 TCHAR szDevice[CCHDEVICENAME];
2603 } MONITORINFOEX, *LPMONITORINFOEX;
2605 static int WINAPI expGetMonitorInfoA(void *mon, LPMONITORINFO lpmi)
2607 dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon, lpmi);
2609 lpmi->rcMonitor.right = lpmi->rcWork.right = PSEUDO_SCREEN_WIDTH;
2610 lpmi->rcMonitor.left = lpmi->rcWork.left = 0;
2611 lpmi->rcMonitor.bottom = lpmi->rcWork.bottom = PSEUDO_SCREEN_HEIGHT;
2612 lpmi->rcMonitor.top = lpmi->rcWork.top = 0;
2614 lpmi->dwFlags = 1; /* primary monitor */
2616 if (lpmi->cbSize == sizeof(MONITORINFOEX))
2618 LPMONITORINFOEX lpmiex = (LPMONITORINFOEX)lpmi;
2619 dbgprintf("MONITORINFOEX!\n");
2620 strncpy(lpmiex->szDevice, "Monitor1", CCHDEVICENAME);
2626 static int WINAPI expEnumDisplayDevicesA(const char *device, int devnum,
2627 void *dispdev, int flags)
2629 dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2630 device, device, devnum, dispdev, flags);
2634 static int WINAPI expIsWindowVisible(HWND win)
2636 dbgprintf("IsWindowVisible(0x%x) => 1\n", win);
2640 static HWND WINAPI expGetActiveWindow(void)
2642 dbgprintf("GetActiveWindow() => 0\n");
2646 static int WINAPI expGetClassNameA(HWND win, LPTSTR classname, int maxcount)
2648 strncat(classname, "QuickTime", maxcount);
2649 dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2650 win, classname, maxcount, strlen(classname));
2651 return strlen(classname);
2654 #define LPWNDCLASS void *
2655 static int WINAPI expGetClassInfoA(HINSTANCE inst, LPCSTR classname, LPWNDCLASS wndclass)
2657 dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst,
2658 classname, classname, wndclass);
2662 static int WINAPI expGetWindowLongA(HWND win, int index)
2664 dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win, index);
2668 static int WINAPI expGetObjectA(HGDIOBJ hobj, int objsize, LPVOID obj)
2670 dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj, objsize, obj, objsize);
2674 static int WINAPI expCreateRectRgn(int x, int y, int width, int height)
2676 dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x, y, width, height);
2680 static int WINAPI expEnumWindows(int (*callback_func)(), void *callback_param)
2683 dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func, callback_param);
2684 i = callback_func(0, callback_param);
2685 i2 = callback_func(1, callback_param);
2689 static int WINAPI expGetWindowThreadProcessId(HWND win, int *pid_data)
2691 int tid = pthread_self();
2692 dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2693 win, pid_data, tid);
2695 *(int*)pid_data = tid;
2699 //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2700 // INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2702 static HWND WINAPI expCreateWindowExA(int exstyle, const char *classname,
2703 const char *winname, int style, int x, int y, int w, int h,
2704 HWND parent, HMENU menu, HINSTANCE inst, LPVOID param)
2706 printf("CreateWindowEx() called\n");
2707 dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2708 exstyle, classname, classname, winname, winname, style, x, y, w, h,
2709 parent, menu, inst, param);
2710 printf("CreateWindowEx() called okey\n");
2714 static int WINAPI expwaveOutGetNumDevs(void)
2716 dbgprintf("waveOutGetNumDevs() => 0\n");
2722 * Returns the number of milliseconds, modulo 2^32, since the start
2723 * of the wineserver.
2725 static int WINAPI expGetTickCount(void)
2727 static int tcstart = 0;
2730 gettimeofday( &t, NULL );
2731 tc = ((t.tv_sec * 1000) + (t.tv_usec / 1000)) - tcstart;
2737 dbgprintf("GetTickCount() => %d\n", tc);
2741 static int WINAPI expCreateFontA(void)
2743 dbgprintf("CreateFontA() => 0x0\n");
2747 /* tried to get pvmjpg work in a different way - no success */
2748 static int WINAPI expDrawTextA(int hDC, char* lpString, int nCount,
2749 LPRECT lpRect, unsigned int uFormat)
2751 dbgprintf("expDrawTextA(%p,...) => 8\n", hDC);
2755 static int WINAPI expGetPrivateProfileIntA(const char* appname,
2756 const char* keyname,
2758 const char* filename)
2766 if(!(appname && keyname && filename) )
2768 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, default_value );
2769 return default_value;
2771 fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2772 strcpy(fullname, "Software\\IniFileMapping\\");
2773 strcat(fullname, appname);
2774 strcat(fullname, "\\");
2775 strcat(fullname, keyname);
2776 strcat(fullname, "\\");
2777 strcat(fullname, filename);
2778 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)buffer, &size);
2779 if((size>=0)&&(size<256))
2781 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2784 result=default_value;
2786 result=atoi(buffer);
2787 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, result);
2790 static int WINAPI expGetProfileIntA(const char* appname,
2791 const char* keyname,
2794 dbgprintf("GetProfileIntA -> ");
2795 return expGetPrivateProfileIntA(appname, keyname, default_value, "default");
2798 static int WINAPI expGetPrivateProfileStringA(const char* appname,
2799 const char* keyname,
2800 const char* def_val,
2801 char* dest, unsigned int len,
2802 const char* filename)
2807 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname, keyname, def_val, dest, len, filename );
2808 if(!(appname && keyname && filename) ) return 0;
2809 fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2810 strcpy(fullname, "Software\\IniFileMapping\\");
2811 strcat(fullname, appname);
2812 strcat(fullname, "\\");
2813 strcat(fullname, keyname);
2814 strcat(fullname, "\\");
2815 strcat(fullname, filename);
2817 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)dest, &size);
2821 strncpy(dest, def_val, size);
2822 if (strlen(def_val)< size) size = strlen(def_val);
2824 dbgprintf(" => %d ( '%s' )\n", size, dest);
2827 static int WINAPI expWritePrivateProfileStringA(const char* appname,
2828 const char* keyname,
2830 const char* filename)
2834 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname, keyname, string, filename );
2835 if(!(appname && keyname && filename) )
2837 dbgprintf(" => -1\n");
2840 fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2841 strcpy(fullname, "Software\\IniFileMapping\\");
2842 strcat(fullname, appname);
2843 strcat(fullname, "\\");
2844 strcat(fullname, keyname);
2845 strcat(fullname, "\\");
2846 strcat(fullname, filename);
2847 RegSetValueExA(HKEY_LOCAL_MACHINE, fullname, 0, REG_SZ, (int*)string, strlen(string));
2848 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
2849 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
2851 dbgprintf(" => 0\n");
2855 unsigned int _GetPrivateProfileIntA(const char* appname, const char* keyname, INT default_value, const char* filename)
2857 return expGetPrivateProfileIntA(appname, keyname, default_value, filename);
2859 int _GetPrivateProfileStringA(const char* appname, const char* keyname,
2860 const char* def_val, char* dest, unsigned int len, const char* filename)
2862 return expGetPrivateProfileStringA(appname, keyname, def_val, dest, len, filename);
2864 int _WritePrivateProfileStringA(const char* appname, const char* keyname,
2865 const char* string, const char* filename)
2867 return expWritePrivateProfileStringA(appname, keyname, string, filename);
2872 static int WINAPI expDefDriverProc(int _private, int id, int msg, int arg1, int arg2)
2874 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", _private, id, msg, arg1, arg2);
2878 static int WINAPI expSizeofResource(int v1, int v2)
2880 int result=SizeofResource(v1, v2);
2881 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1, v2, result);
2885 static int WINAPI expGetLastError()
2887 int result=GetLastError();
2888 dbgprintf("GetLastError() => 0x%x\n", result);
2892 static void WINAPI expSetLastError(int error)
2894 dbgprintf("SetLastError(0x%x)\n", error);
2895 SetLastError(error);
2898 static int WINAPI expStringFromGUID2(GUID* guid, char* str, int cbMax)
2900 int result=snprintf(str, cbMax, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
2901 guid->f1, guid->f2, guid->f3,
2902 (unsigned char)guid->f4[0], (unsigned char)guid->f4[1],
2903 (unsigned char)guid->f4[2], (unsigned char)guid->f4[3],
2904 (unsigned char)guid->f4[4], (unsigned char)guid->f4[5],
2905 (unsigned char)guid->f4[6], (unsigned char)guid->f4[7]);
2906 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid, str, str, cbMax, result);
2911 static int WINAPI expGetFileVersionInfoSizeA(const char* name, int* lpHandle)
2913 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name, name, lpHandle);
2917 static int WINAPI expIsBadStringPtrW(const short* string, int nchars)
2920 if(string==0)result=1; else result=0;
2921 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string, nchars, result);
2922 if(string)wch_print(string);
2925 static int WINAPI expIsBadStringPtrA(const char* string, int nchars)
2927 return expIsBadStringPtrW((const short*)string, nchars);
2929 static long WINAPI expInterlockedExchangeAdd( long* dest, long incr )
2932 __asm__ __volatile__
2934 "lock; xaddl %0,(%1)"
2936 : "r" (dest), "0" (incr)
2942 static long WINAPI expInterlockedCompareExchange( unsigned long* dest, unsigned long exchange, unsigned long comperand)
2944 unsigned long retval = *dest;
2945 if(*dest == comperand)
2950 static long WINAPI expInterlockedIncrement( long* dest )
2952 long result=expInterlockedExchangeAdd( dest, 1 ) + 1;
2953 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest, *dest, result);
2956 static long WINAPI expInterlockedDecrement( long* dest )
2958 long result=expInterlockedExchangeAdd( dest, -1 ) - 1;
2959 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest, *dest, result);
2963 static void WINAPI expOutputDebugStringA( const char* string )
2965 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string);
2966 fprintf(stderr, "DEBUG: %s\n", string);
2969 static int WINAPI expGetDC(int hwnd)
2971 dbgprintf("GetDC(0x%x) => 1\n", hwnd);
2975 static int WINAPI expReleaseDC(int hwnd, int hdc)
2977 dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd, hdc);
2981 static int WINAPI expGetDesktopWindow()
2983 dbgprintf("GetDesktopWindow() => 0\n");
2987 static int cursor[100];
2989 static int WINAPI expLoadCursorA(int handle,LPCSTR name)
2991 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle, name, (int)&cursor[0]);
2992 return (int)&cursor[0];
2994 static int WINAPI expSetCursor(void *cursor)
2996 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor, cursor);
2999 static int WINAPI expGetCursorPos(void *cursor)
3001 dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor, cursor);
3005 static int show_cursor = 0;
3006 static int WINAPI expShowCursor(int show)
3008 dbgprintf("ShowCursor(%d) => %d\n", show, show);
3016 static int WINAPI expRegisterWindowMessageA(char *message)
3018 dbgprintf("RegisterWindowMessageA(%s)\n", message);
3021 static int WINAPI expGetProcessVersion(int pid)
3023 dbgprintf("GetProcessVersion(%d)\n", pid);
3026 static int WINAPI expGetCurrentThread(void)
3029 dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
3032 static int WINAPI expGetOEMCP(void)
3034 dbgprintf("GetOEMCP()\n");
3037 static int WINAPI expGetCPInfo(int cp,void *info)
3039 dbgprintf("GetCPInfo()\n");
3043 #define SM_CXSCREEN 0
3044 #define SM_CYSCREEN 1
3045 #define SM_XVIRTUALSCREEN 76
3046 #define SM_YVIRTUALSCREEN 77
3047 #define SM_CXVIRTUALSCREEN 78
3048 #define SM_CYVIRTUALSCREEN 79
3049 #define SM_CMONITORS 80
3051 static int WINAPI expGetSystemMetrics(int index)
3053 dbgprintf("GetSystemMetrics(%d)\n", index);
3057 case SM_XVIRTUALSCREEN:
3058 case SM_YVIRTUALSCREEN:
3061 case SM_CXVIRTUALSCREEN:
3062 return PSEUDO_SCREEN_WIDTH;
3064 case SM_CYVIRTUALSCREEN:
3065 return PSEUDO_SCREEN_HEIGHT;
3072 static int WINAPI expGetSysColor(int index)
3074 dbgprintf("GetSysColor(%d) => 1\n", index);
3077 static int WINAPI expGetSysColorBrush(int index)
3079 dbgprintf("GetSysColorBrush(%d)\n", index);
3085 static int WINAPI expGetSystemPaletteEntries(int hdc, int iStartIndex, int nEntries, void* lppe)
3087 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3088 hdc, iStartIndex, nEntries, lppe);
3093 typedef struct _TIME_ZONE_INFORMATION {
3095 char StandardName[32];
3096 SYSTEMTIME StandardDate;
3098 char DaylightName[32];
3099 SYSTEMTIME DaylightDate;
3101 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3104 static int WINAPI expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
3106 const short name[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3107 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3108 const short pname[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3109 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3110 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3111 memset(lpTimeZoneInformation, 0, sizeof(TIME_ZONE_INFORMATION));
3112 lpTimeZoneInformation->Bias=360;//GMT-6
3113 memcpy(lpTimeZoneInformation->StandardName, name, sizeof(name));
3114 lpTimeZoneInformation->StandardDate.wMonth=10;
3115 lpTimeZoneInformation->StandardDate.wDay=5;
3116 lpTimeZoneInformation->StandardDate.wHour=2;
3117 lpTimeZoneInformation->StandardBias=0;
3118 memcpy(lpTimeZoneInformation->DaylightName, pname, sizeof(pname));
3119 lpTimeZoneInformation->DaylightDate.wMonth=4;
3120 lpTimeZoneInformation->DaylightDate.wDay=1;
3121 lpTimeZoneInformation->DaylightDate.wHour=2;
3122 lpTimeZoneInformation->DaylightBias=-60;
3123 return TIME_ZONE_ID_STANDARD;
3126 static void WINAPI expGetLocalTime(SYSTEMTIME* systime)
3129 struct tm *local_tm;
3132 dbgprintf("GetLocalTime(0x%x)\n");
3133 gettimeofday(&tv, NULL);
3134 local_time=tv.tv_sec;
3135 local_tm=localtime(&local_time);
3137 systime->wYear = local_tm->tm_year + 1900;
3138 systime->wMonth = local_tm->tm_mon + 1;
3139 systime->wDayOfWeek = local_tm->tm_wday;
3140 systime->wDay = local_tm->tm_mday;
3141 systime->wHour = local_tm->tm_hour;
3142 systime->wMinute = local_tm->tm_min;
3143 systime->wSecond = local_tm->tm_sec;
3144 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
3145 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3146 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3147 " Milliseconds: %d\n",
3148 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay,
3149 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds);
3152 static int WINAPI expGetSystemTime(SYSTEMTIME* systime)
3155 struct tm *local_tm;
3158 dbgprintf("GetSystemTime(0x%x)\n", systime);
3159 gettimeofday(&tv, NULL);
3160 local_time=tv.tv_sec;
3161 local_tm=gmtime(&local_time);
3163 systime->wYear = local_tm->tm_year + 1900;
3164 systime->wMonth = local_tm->tm_mon + 1;
3165 systime->wDayOfWeek = local_tm->tm_wday;
3166 systime->wDay = local_tm->tm_mday;
3167 systime->wHour = local_tm->tm_hour;
3168 systime->wMinute = local_tm->tm_min;
3169 systime->wSecond = local_tm->tm_sec;
3170 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
3171 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3172 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3173 " Milliseconds: %d\n",
3174 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay,
3175 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds);
3179 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3180 static void WINAPI expGetSystemTimeAsFileTime(FILETIME* systime)
3182 struct tm *local_tm;
3184 unsigned long long secs;
3186 dbgprintf("GetSystemTime(0x%x)\n", systime);
3187 gettimeofday(&tv, NULL);
3188 secs = (tv.tv_sec + SECS_1601_TO_1970) * 10000000;
3189 secs += tv.tv_usec * 10;
3190 systime->dwLowDateTime = secs & 0xffffffff;
3191 systime->dwHighDateTime = (secs >> 32);
3194 static int WINAPI expGetEnvironmentVariableA(const char* name, char* field, int size)
3197 // printf("%s %x %x\n", name, field, size);
3198 if(field)field[0]=0;
3201 if (p) strncpy(field,p,size);
3203 if (strcmp(name,"__MSVCRT_HEAP_SELECT")==0)
3204 strcpy(field,"__GLOBAL_HEAP_SELECTED,1");
3205 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name, name, field, size, strlen(field));
3206 return strlen(field);
3209 static int WINAPI expSetEnvironmentVariableA(const char *name, const char *value)
3211 dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name, value);
3215 static void* WINAPI expCoTaskMemAlloc(ULONG cb)
3217 return my_mreq(cb, 0);
3219 static void WINAPI expCoTaskMemFree(void* cb)
3227 void* CoTaskMemAlloc(unsigned long cb)
3229 return expCoTaskMemAlloc(cb);
3231 void CoTaskMemFree(void* cb)
3233 expCoTaskMemFree(cb);
3236 struct COM_OBJECT_INFO
3239 long (*GetClassObject) (GUID* clsid, const GUID* iid, void** ppv);
3242 static struct COM_OBJECT_INFO* com_object_table=0;
3243 static int com_object_size=0;
3244 int RegisterComClass(const GUID* clsid, GETCLASSOBJECT gcs)
3248 com_object_table=realloc(com_object_table, sizeof(struct COM_OBJECT_INFO)*(++com_object_size));
3249 com_object_table[com_object_size-1].clsid=*clsid;
3250 com_object_table[com_object_size-1].GetClassObject=gcs;
3254 int UnregisterComClass(const GUID* clsid, GETCLASSOBJECT gcs)
3261 if (com_object_table == 0)
3262 printf("Warning: UnregisterComClass() called without any registered class\n");
3263 while (i < com_object_size)
3267 memcpy(&com_object_table[i - 1].clsid,
3268 &com_object_table[i].clsid, sizeof(GUID));
3269 com_object_table[i - 1].GetClassObject =
3270 com_object_table[i].GetClassObject;
3272 else if (memcmp(&com_object_table[i].clsid, clsid, sizeof(GUID)) == 0
3273 && com_object_table[i].GetClassObject == gcs)
3281 if (--com_object_size == 0)
3283 free(com_object_table);
3284 com_object_table = 0;
3291 const GUID IID_IUnknown =
3293 0x00000000, 0x0000, 0x0000,
3294 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3296 const GUID IID_IClassFactory =
3298 0x00000001, 0x0000, 0x0000,
3299 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3302 static long WINAPI expCoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
3303 long dwClsContext, const GUID* riid, void** ppv)
3306 struct COM_OBJECT_INFO* ci=0;
3307 for(i=0; i<com_object_size; i++)
3308 if(!memcmp(rclsid, &com_object_table[i].clsid, sizeof(GUID)))
3309 ci=&com_object_table[i];
3310 if(!ci)return REGDB_E_CLASSNOTREG;
3311 // in 'real' world we should mess with IClassFactory here
3312 i=ci->GetClassObject(rclsid, riid, ppv);
3316 long CoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
3317 long dwClsContext, const GUID* riid, void** ppv)
3319 return expCoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
3322 static int WINAPI expIsRectEmpty(CONST RECT *lprc)
3329 w = lprc->right - lprc->left;
3330 h = lprc->bottom - lprc->top;
3331 if (w <= 0 || h <= 0)
3337 dbgprintf("IsRectEmpty(%p) => %s\n", lprc, (r) ? "TRUE" : "FALSE");
3338 //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3339 // return 0; // wmv9?
3343 static int _adjust_fdiv=0; //what's this? - used to adjust division
3348 static unsigned int WINAPI expGetTempPathA(unsigned int len, char* path)
3350 dbgprintf("GetTempPathA(%d, 0x%x)", len, path);
3353 dbgprintf(" => 0\n");
3356 strcpy(path, "/tmp");
3357 dbgprintf(" => 5 ( '/tmp' )\n");
3364 DWORD dwFileAttributes;
3365 FILETIME ftCreationTime;
3366 FILETIME ftLastAccessTime;
3367 FILETIME ftLastWriteTime;
3368 DWORD nFileSizeHigh;
3372 CHAR cFileName[260];
3373 CHAR cAlternateFileName[14];
3374 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3377 static DIR* qtx_dir=NULL;
3379 static WIN_BOOL WINAPI expFindNextFileA(HANDLE h,LPWIN32_FIND_DATAA lpfd)
3382 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h, lpfd);
3383 if(h==FILE_HANDLE_quicktimeqtx){
3385 if(!qtx_dir) return 0;
3386 while((d=readdir(qtx_dir))){
3387 char* x=strrchr(d->d_name,'.');
3389 if(strcmp(x,".qtx")) continue;
3390 strcpy(lpfd->cFileName,d->d_name);
3391 // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3392 strcpy(lpfd->cAlternateFileName,"foobar.qtx");
3393 printf("### FindNext: %s\n",lpfd->cFileName);
3396 closedir(qtx_dir); qtx_dir=NULL;
3403 static HANDLE WINAPI expFindFirstFileA(LPCSTR s, LPWIN32_FIND_DATAA lpfd)
3405 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s, s, lpfd);
3406 // printf("\n### FindFirstFileA('%s')...\n",s);
3408 if(strstr(s, "quicktime\\*.QTX")){
3409 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s, s, lpfd);
3410 printf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",def_path);
3411 qtx_dir=opendir(def_path);
3412 if(!qtx_dir) return (HANDLE)-1;
3413 memset(lpfd,0,sizeof(*lpfd));
3414 if(expFindNextFileA(FILE_HANDLE_quicktimeqtx,lpfd))
3415 return FILE_HANDLE_quicktimeqtx;
3416 printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",def_path);
3420 if(strstr(s, "QuickTime.qts")){
3421 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s, s, lpfd);
3422 // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3423 // return (HANDLE)-1;
3424 strcpy(lpfd->cFileName, "QuickTime.qts");
3425 strcpy(lpfd->cAlternateFileName, "QuickT~1.qts");
3426 return FILE_HANDLE_quicktimeqts;
3430 if(strstr(s, "*.vwp")){
3431 // hack for VoxWare codec plugins:
3432 strcpy(lpfd->cFileName, "msms001.vwp");
3433 strcpy(lpfd->cAlternateFileName, "msms001.vwp");
3436 // return 'file not found'
3440 static WIN_BOOL WINAPI expFindClose(HANDLE h)
3442 dbgprintf("FindClose(0x%x) => 0\n", h);
3444 // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3445 // closedir(qtx_dir);
3451 static UINT WINAPI expSetErrorMode(UINT i)
3453 dbgprintf("SetErrorMode(%d) => 0\n", i);
3456 static UINT WINAPI expGetWindowsDirectoryA(LPSTR s,UINT c)
3458 char windir[]="c:\\windows";
3460 strncpy(s, windir, c);
3461 result=1+((c<strlen(windir))?c:strlen(windir));
3462 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s, c, result);
3466 static UINT WINAPI expGetCurrentDirectoryA(UINT c, LPSTR s)
3468 char curdir[]="c:\\";
3470 strncpy(s, curdir, c);
3471 result=1+((c<strlen(curdir))?c:strlen(curdir));
3472 dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s, c, result);
3476 static int WINAPI expSetCurrentDirectoryA(const char *pathname)
3478 dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname, pathname);
3480 if (strrchr(pathname, '\\'))
3481 chdir(strcat(strrchr(pathname, '\\')+1, '/'));
3488 static int WINAPI expCreateDirectoryA(const char *pathname, void *sa)
3490 dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3491 pathname, pathname, sa);
3493 p = strrchr(pathname, '\\')+1;
3494 strcpy(&buf[0], p); /* should be strncpy */
3501 if (strrchr(pathname, '\\'))
3502 mkdir(strcat(strrchr(pathname, '\\')+1, '/'), 666);
3504 mkdir(pathname, 666);
3511 static WIN_BOOL WINAPI expDeleteFileA(LPCSTR s)
3513 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s, s);
3516 static WIN_BOOL WINAPI expFileTimeToLocalFileTime(const FILETIME* cpf, LPFILETIME pf)
3518 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf, pf);
3522 static UINT WINAPI expGetTempFileNameA(LPCSTR cs1,LPCSTR cs2,UINT i,LPSTR ps)
3524 char mask[16]="/tmp/AP_XXXXXX";
3526 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1, cs1, cs2, cs2, i, ps);
3529 dbgprintf(" => -1\n");
3532 result=mkstemp(mask);
3533 sprintf(ps, "AP%d", result);
3534 dbgprintf(" => %d\n", strlen(ps));
3538 // This func might need proper implementation if we want AngelPotion codec.
3539 // They try to open APmpeg4v1.apl with it.
3540 // DLL will close opened file with CloseHandle().
3542 static HANDLE WINAPI expCreateFileA(LPCSTR cs1,DWORD i1,DWORD i2,
3543 LPSECURITY_ATTRIBUTES p1, DWORD i3,DWORD i4,HANDLE i5)
3545 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1, cs1, i1,
3546 i2, p1, i3, i4, i5);
3547 if((!cs1) || (strlen(cs1)<2))return -1;
3550 if(strstr(cs1, "QuickTime.qts"))
3553 char* tmp=(char*)malloc(strlen(def_path)+50);
3554 strcpy(tmp, def_path);
3556 strcat(tmp, "QuickTime.qts");
3557 result=open(tmp, O_RDONLY);
3561 if(strstr(cs1, ".qtx"))
3564 char* tmp=(char*)malloc(strlen(def_path)+250);
3565 char* x=strrchr(cs1,'\\');
3566 sprintf(tmp,"%s/%s",def_path,x?(x+1):cs1);
3567 // printf("### Open: %s -> %s\n",cs1,tmp);
3568 result=open(tmp, O_RDONLY);
3574 if(strncmp(cs1, "AP", 2) == 0)
3577 char* tmp=(char*)malloc(strlen(def_path)+50);
3578 strcpy(tmp, def_path);
3580 strcat(tmp, "APmpg4v1.apl");
3581 result=open(tmp, O_RDONLY);
3585 if (strstr(cs1, "vp3"))
3589 char* tmp=(char*)malloc(20 + strlen(cs1));
3590 strcpy(tmp, "/tmp/");
3595 if (tmp[r] == ':' || tmp[r] == '\\')
3599 if (GENERIC_READ & i1)
3601 else if (GENERIC_WRITE & i1)
3604 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp, r, flg);
3611 // Needed by wnvplay1.dll
3612 if (strstr(cs1, "WINNOV.bmp"))
3615 r=open("/dev/null", 0);
3620 /* we need this for some virtualdub filters */
3624 if (GENERIC_READ & i1)
3626 else if (GENERIC_WRITE & i1)
3629 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1, r, flg);
3638 static UINT WINAPI expGetSystemDirectoryA(
3639 char* lpBuffer, // address of buffer for system directory
3640 UINT uSize // size of directory buffer
3642 dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer,uSize);
3643 if(!lpBuffer) strcpy(lpBuffer,".");
3647 static char sysdir[]=".";
3648 static LPCSTR WINAPI expGetSystemDirectoryA()
3650 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3654 static DWORD WINAPI expGetFullPathNameA
3657 DWORD nBufferLength,
3661 if(!lpFileName) return 0;
3662 dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName,nBufferLength,
3663 lpBuffer, lpFilePart);
3666 strcpy(lpFilePart, "Quick123.qts");
3668 strcpy(lpFilePart, lpFileName);
3671 if (strrchr(lpFileName, '\\'))
3672 lpFilePart = strrchr(lpFileName, '\\');
3674 lpFilePart = (LPTSTR)lpFileName;
3676 strcpy(lpBuffer, lpFileName);
3677 // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3678 return strlen(lpBuffer);
3681 static DWORD WINAPI expGetShortPathNameA
3687 if(!longpath) return 0;
3688 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath,shortpath,shortlen);
3689 strcpy(shortpath,longpath);
3690 return strlen(shortpath);
3693 static WIN_BOOL WINAPI expReadFile(HANDLE h,LPVOID pv,DWORD size,LPDWORD rd,LPOVERLAPPED unused)
3696 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, rd);
3697 result=read(h, pv, size);
3699 if(!result)return 0;
3703 static WIN_BOOL WINAPI expWriteFile(HANDLE h,LPCVOID pv,DWORD size,LPDWORD wr,LPOVERLAPPED unused)
3706 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, wr);
3708 result=write(h, pv, size);
3710 if(!result)return 0;
3713 static DWORD WINAPI expSetFilePointer(HANDLE h, LONG val, LPLONG ext, DWORD whence)
3716 dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h, val, ext, *ext, whence);
3717 //why would DLL want temporary file with >2Gb size?
3730 if (val == 0 && ext != 0)
3733 return lseek(h, val, wh);
3736 static HDRVR WINAPI expOpenDriverA(LPCSTR szDriverName, LPCSTR szSectionName,
3739 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2);
3742 static HDRVR WINAPI expOpenDriver(LPCSTR szDriverName, LPCSTR szSectionName,
3745 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2);
3750 static WIN_BOOL WINAPI expGetProcessAffinityMask(HANDLE hProcess,
3751 LPDWORD lpProcessAffinityMask,
3752 LPDWORD lpSystemAffinityMask)
3754 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3755 hProcess, lpProcessAffinityMask, lpSystemAffinityMask);
3756 if(lpProcessAffinityMask)*lpProcessAffinityMask=1;
3757 if(lpSystemAffinityMask)*lpSystemAffinityMask=1;
3761 static int WINAPI expMulDiv(int nNumber, int nNumerator, int nDenominator)
3763 static const long long max_int=0x7FFFFFFFLL;
3764 static const long long min_int=-0x80000000LL;
3765 long long tmp=(long long)nNumber*(long long)nNumerator;
3766 dbgprintf("expMulDiv %d * %d / %d\n", nNumber, nNumerator, nDenominator);
3767 if(!nDenominator)return 1;
3769 if(tmp<min_int) return 1;
3770 if(tmp>max_int) return 1;
3774 static LONG WINAPI explstrcmpiA(const char* str1, const char* str2)
3776 LONG result=strcasecmp(str1, str2);
3777 dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
3781 static LONG WINAPI explstrlenA(const char* str1)
3783 LONG result=strlen(str1);
3784 dbgprintf("strlen(0x%x='%.50s') => %d\n", str1, str1, result);
3788 static LONG WINAPI explstrcpyA(char* str1, const char* str2)
3790 int result= (int) strcpy(str1, str2);
3791 dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1, str2, str2, result);
3794 static LONG WINAPI explstrcpynA(char* str1, const char* str2,int len)
3797 if (strlen(str2)>len)
3798 result = (int) strncpy(str1, str2,len);
3800 result = (int) strcpy(str1,str2);
3801 dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1, str2, str2,len, strlen(str2),result);
3804 static LONG WINAPI explstrcatA(char* str1, const char* str2)
3806 int result= (int) strcat(str1, str2);
3807 dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1, str2, str2, result);
3812 static LONG WINAPI expInterlockedExchange(long *dest, long l)
3814 long retval = *dest;
3819 static void WINAPI expInitCommonControls(void)
3821 dbgprintf("InitCommonControls called!\n");
3826 /* needed by QuickTime.qts */
3827 static HWND WINAPI expCreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
3828 HWND parent, INT id, HINSTANCE inst,
3829 HWND buddy, INT maxVal, INT minVal, INT curVal)
3831 dbgprintf("CreateUpDownControl(...)\n");
3836 /* alex: implement this call! needed for 3ivx */
3837 static HRESULT WINAPI expCoCreateFreeThreadedMarshaler(void *pUnkOuter, void **ppUnkInner)
3839 dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
3840 pUnkOuter, ppUnkInner);
3842 return ERROR_CALL_NOT_IMPLEMENTED;
3846 static int WINAPI expDuplicateHandle(HANDLE hSourceProcessHandle, // handle to source process
3847 HANDLE hSourceHandle, // handle to duplicate
3848 HANDLE hTargetProcessHandle, // handle to target process
3849 HANDLE* lpTargetHandle, // duplicate handle
3850 DWORD dwDesiredAccess, // requested access
3851 int bInheritHandle, // handle inheritance option
3852 DWORD dwOptions // optional actions
3855 dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
3856 hSourceProcessHandle, hSourceHandle, hTargetProcessHandle,
3857 lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions);
3858 *lpTargetHandle = hSourceHandle;
3862 // required by PIM1 codec (used by win98 PCTV Studio capture sw)
3863 static HRESULT WINAPI expCoInitialize(
3864 LPVOID lpReserved /* [in] pointer to win32 malloc interface
3865 (obsolete, should be NULL) */
3869 * Just delegate to the newer method.
3871 return 0; //CoInitializeEx(lpReserved, COINIT_APARTMENTTHREADED);
3874 static DWORD WINAPI expSetThreadAffinityMask
3877 DWORD dwThreadAffinityMask
3883 * no WINAPI functions - CDECL
3885 static void* expmalloc(int size)
3888 // return malloc(size);
3889 void* result=my_mreq(size,0);
3890 dbgprintf("malloc(0x%x) => 0x%x\n", size,result);
3892 printf("WARNING: malloc() failed\n");
3895 static void expfree(void* mem)
3897 // return free(mem);
3898 dbgprintf("free(%p)\n", mem);
3901 /* needed by atrac3.acm */
3902 static void *expcalloc(int num, int size)
3904 void* result=my_mreq(num*size,1);
3905 dbgprintf("calloc(%d,%d) => %p\n", num,size,result);
3907 printf("WARNING: calloc() failed\n");
3910 static void* expnew(int size)
3912 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
3913 // printf("%08x %08x %08x %08x\n",
3914 // size, *(1+(int*)&size),
3915 // *(2+(int*)&size),*(3+(int*)&size));
3919 result=my_mreq(size,0);
3920 dbgprintf("new(%d) => %p\n", size, result);
3922 printf("WARNING: new() failed\n");
3926 static int expdelete(void* memory)
3928 dbgprintf("delete(%p)\n", memory);
3934 * local definition - we need only the last two members at this point
3935 * otherwice we would have to introduce here GUIDs and some more types..
3937 typedef struct __attribute__((__packed__))
3940 void* pbUnknown; //0x3C
3941 unsigned long cbFormat; //0x40
3942 char* pbFormat; //0x44
3944 static HRESULT WINAPI expMoCopyMediaType(MY_MEDIA_TYPE* dest, const MY_MEDIA_TYPE* src)
3948 memcpy(dest, src, sizeof(MY_MEDIA_TYPE));
3951 dest->pbFormat = (char*) my_mreq(dest->cbFormat, 0);
3952 if (!dest->pbFormat)
3953 return E_OUTOFMEMORY;
3954 memcpy(dest->pbFormat, src->pbFormat, dest->cbFormat);
3958 static HRESULT WINAPI expMoInitMediaType(MY_MEDIA_TYPE* dest, DWORD cbFormat)
3963 dest->pbUnknown = NULL;
3964 dest->cbFormat = cbFormat;
3967 dest->pbFormat = (char*) my_mreq(cbFormat, 0);
3968 if (!dest->pbFormat)
3969 return E_OUTOFMEMORY;
3973 dest->pbFormat=NULL;
3977 static HRESULT WINAPI expMoCreateMediaType(MY_MEDIA_TYPE** dest, DWORD cbFormat)
3981 *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0);
3982 return expMoInitMediaType(*dest, cbFormat);
3984 static HRESULT WINAPI expMoDuplicateMediaType(MY_MEDIA_TYPE** dest, const void* src)
3988 *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0);
3989 return expMoCopyMediaType(*dest, src);
3991 static HRESULT WINAPI expMoFreeMediaType(MY_MEDIA_TYPE* dest)
3997 my_release(dest->pbFormat);
4003 static HRESULT WINAPI expMoDeleteMediaType(MY_MEDIA_TYPE* dest)
4007 expMoFreeMediaType(dest);
4012 static int exp_snprintf( char *str, int size, const char *format, ... )
4016 va_start(va, format);
4017 x=snprintf(str,size,format,va);
4018 dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str,size,format,x);
4024 static int exp_initterm(int v1, int v2)
4026 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1, v2);
4030 /* merged from wine - 2002.04.21 */
4031 typedef void (*_INITTERMFUNC)();
4032 static int exp_initterm(_INITTERMFUNC *start, _INITTERMFUNC *end)
4034 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start, end, *start);
4039 //printf("call _initfunc: from: %p %d\n", *start);
4040 // ok this trick with push/pop is necessary as otherwice
4041 // edi/esi registers are being trashed
4043 __asm__ __volatile__
4060 //printf("done %p %d:%d\n", end);
4068 static void* exp__dllonexit()
4070 // FIXME extract from WINE
4074 static int expwsprintfA(char* string, const char* format, ...)
4078 va_start(va, format);
4079 result = vsprintf(string, format, va);
4080 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string, format, result);
4085 static int expsprintf(char* str, const char* format, ...)
4089 dbgprintf("sprintf(0x%x, %s)\n", str, format);
4090 va_start(args, format);
4091 r = vsprintf(str, format, args);
4095 static int expsscanf(const char* str, const char* format, ...)
4099 dbgprintf("sscanf(%s, %s)\n", str, format);
4100 va_start(args, format);
4101 r = vsscanf(str, format, args);
4105 static void* expfopen(const char* path, const char* mode)
4107 printf("fopen: \"%s\" mode:%s\n", path, mode);
4108 //return fopen(path, mode);
4109 return fdopen(0, mode); // everything on screen
4111 static int expfprintf(void* stream, const char* format, ...)
4115 dbgprintf("fprintf(%p, %s, ...)\n", stream, format);
4117 va_start(args, format);
4118 r = vfprintf((FILE*) stream, format, args);
4124 static int expprintf(const char* format, ...)
4128 dbgprintf("printf(%s, ...)\n", format);
4129 va_start(args, format);
4130 r = vprintf(format, args);
4135 static char* expgetenv(const char* varname)
4137 char* v = getenv(varname);
4138 dbgprintf("getenv(%s) => %s\n", varname, v);
4142 static void* expwcscpy(WCHAR* dst, const WCHAR* src)
4145 while ((*p++ = *src++))
4150 static char* expstrrchr(char* string, int value)
4152 char* result=strrchr(string, value);
4154 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result);
4156 dbgprintf("strrchr(0x%x='%s', %d) => 0", string, string, value);
4160 static char* expstrchr(char* string, int value)
4162 char* result=strchr(string, value);
4164 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result);
4166 dbgprintf("strchr(0x%x='%s', %d) => 0", string, string, value);
4169 static int expstrlen(char* str)
4171 int result=strlen(str);
4172 dbgprintf("strlen(0x%x='%s') => %d\n", str, str, result);
4175 static char* expstrcpy(char* str1, const char* str2)
4177 char* result= strcpy(str1, str2);
4178 dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1, str2, str2, result);
4181 static char* expstrncpy(char* str1, const char* str2, size_t count)
4183 char* result= strncpy(str1, str2, count);
4184 dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1, str2, str2, count, result);
4187 static int expstrcmp(const char* str1, const char* str2)
4189 int result=strcmp(str1, str2);
4190 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
4193 static int expstrncmp(const char* str1, const char* str2,int x)
4195 int result=strncmp(str1, str2,x);
4196 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
4199 static char* expstrcat(char* str1, const char* str2)
4201 char* result = strcat(str1, str2);
4202 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1, str1, str2, str2, result);
4205 static char* exp_strdup(const char* str1)
4207 int l = strlen(str1);
4208 char* result = (char*) my_mreq(l + 1,0);
4210 strcpy(result, str1);
4211 dbgprintf("_strdup(0x%x='%s') => %p\n", str1, str1, result);
4214 static int expisalnum(int c)
4216 int result= (int) isalnum(c);
4217 dbgprintf("isalnum(0x%x='%c' => %d\n", c, c, result);
4220 static int expisspace(int c)
4222 int result= (int) isspace(c);
4223 dbgprintf("isspace(0x%x='%c' => %d\n", c, c, result);
4226 static int expisalpha(int c)
4228 int result= (int) isalpha(c);
4229 dbgprintf("isalpha(0x%x='%c' => %d\n", c, c, result);
4232 static int expisdigit(int c)
4234 int result= (int) isdigit(c);
4235 dbgprintf("isdigit(0x%x='%c' => %d\n", c, c, result);
4238 static void* expmemmove(void* dest, void* src, int n)
4240 void* result = memmove(dest, src, n);
4241 dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest, src, n, result);
4244 static int expmemcmp(void* dest, void* src, int n)
4246 int result = memcmp(dest, src, n);
4247 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest, src, n, result);
4250 static void* expmemcpy(void* dest, void* src, int n)
4252 void *result = memcpy(dest, src, n);
4253 dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest, src, n, result);
4256 static void* expmemset(void* dest, int c, size_t n)
4258 void *result = memset(dest, c, n);
4259 dbgprintf("memset(0x%x, %d, %d) => %p\n", dest, c, n, result);
4262 static time_t exptime(time_t* t)
4264 time_t result = time(t);
4265 dbgprintf("time(0x%x) => %d\n", t, result);
4269 static int exprand(void)
4274 static void expsrand(int seed)
4281 // preferred compilation with -O2 -ffast-math !
4283 static double explog10(double x)
4285 /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4289 static double expcos(double x)
4291 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4296 static long exp_ftol_wrong(double x)
4303 static void explog10(void)
4305 __asm__ __volatile__
4314 static void expcos(void)
4316 __asm__ __volatile__
4325 // this seem to be the only how to make this function working properly
4326 // ok - I've spent tremendous amount of time (many many many hours
4327 // of debuging fixing & testing - it's almost unimaginable - kabi
4329 // _ftol - operated on the float value which is already on the FPU stack
4331 static void exp_ftol(void)
4333 __asm__ __volatile__
4335 "sub $12, %esp \n\t"
4336 "fstcw -2(%ebp) \n\t"
4338 "movw -2(%ebp), %ax \n\t"
4339 "orb $0x0C, %ah \n\t"
4340 "movw %ax, -4(%ebp) \n\t"
4341 "fldcw -4(%ebp) \n\t"
4342 "fistpl -12(%ebp) \n\t"
4343 "fldcw -2(%ebp) \n\t"
4344 "movl -12(%ebp), %eax \n\t"
4345 //Note: gcc 3.03 does not do the following op if it
4346 // knows that ebp=esp
4347 "movl %ebp, %esp \n\t"
4351 #define FPU_DOUBLES(var1,var2) double var1,var2; \
4352 __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var2) : ); \
4353 __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var1) : )
4355 static double exp_CIpow(void)
4359 dbgprintf("_CIpow(%lf, %lf)\n", x, y);
4363 static double exppow(double x, double y)
4365 /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4369 static double expldexp(double x, int expo)
4371 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4372 return ldexp(x, expo);
4375 static double expfrexp(double x, int* expo)
4377 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4378 return frexp(x, expo);
4383 static int exp_stricmp(const char* s1, const char* s2)
4385 return strcasecmp(s1, s2);
4388 /* from declaration taken from Wine sources - this fountion seems to be
4389 * undocumented in any M$ doc */
4390 static int exp_setjmp3(void* jmpbuf, int x)
4392 //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4394 __asm__ __volatile__
4396 //"mov 4(%%esp), %%edx \n\t"
4397 "mov (%%esp), %%eax \n\t"
4398 "mov %%eax, (%%edx) \n\t" // store ebp
4400 //"mov %%ebp, (%%edx) \n\t"
4401 "mov %%ebx, 4(%%edx) \n\t"
4402 "mov %%edi, 8(%%edx) \n\t"
4403 "mov %%esi, 12(%%edx) \n\t"
4404 "mov %%esp, 16(%%edx) \n\t"
4406 "mov 4(%%esp), %%eax \n\t"
4407 "mov %%eax, 20(%%edx) \n\t"
4409 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4410 "movl $0, 36(%%edx) \n\t"
4412 : "d"(jmpbuf) // input
4416 __asm__ __volatile__
4418 "mov %%fs:0, %%eax \n\t" // unsure
4419 "mov %%eax, 24(%%edx) \n\t"
4420 "cmp $0xffffffff, %%eax \n\t"
4422 "mov %%eax, 28(%%edx) \n\t"
4433 static DWORD WINAPI expGetCurrentProcessId(void)
4435 dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4436 return getpid(); //(DWORD)NtCurrentTeb()->pid;
4443 } TIMECAPS, *LPTIMECAPS;
4445 static MMRESULT WINAPI exptimeGetDevCaps(LPTIMECAPS lpCaps, UINT wSize)
4447 dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
4449 lpCaps->wPeriodMin = 1;
4450 lpCaps->wPeriodMax = 65535;
4454 static MMRESULT WINAPI exptimeBeginPeriod(UINT wPeriod)
4456 dbgprintf("timeBeginPeriod(%u) !\n", wPeriod);
4458 if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO;
4463 static MMRESULT WINAPI exptimeEndPeriod(UINT wPeriod)
4465 dbgprintf("timeEndPeriod(%u) !\n", wPeriod);
4467 if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO;
4472 static void WINAPI expGlobalMemoryStatus(
4473 LPMEMORYSTATUS lpmem
4475 static MEMORYSTATUS cached_memstatus;
4476 static int cache_lastchecked = 0;
4480 if (time(NULL)==cache_lastchecked) {
4481 memcpy(lpmem,&cached_memstatus,sizeof(MEMORYSTATUS));
4486 f = fopen( "/proc/meminfo", "r" );
4490 int total, used, free, shared, buffers, cached;
4492 lpmem->dwLength = sizeof(MEMORYSTATUS);
4493 lpmem->dwTotalPhys = lpmem->dwAvailPhys = 0;
4494 lpmem->dwTotalPageFile = lpmem->dwAvailPageFile = 0;
4495 while (fgets( buffer, sizeof(buffer), f ))
4497 /* old style /proc/meminfo ... */
4498 if (sscanf( buffer, "Mem: %d %d %d %d %d %d", &total, &used, &free, &shared, &buffers, &cached ))
4500 lpmem->dwTotalPhys += total;
4501 lpmem->dwAvailPhys += free + buffers + cached;
4503 if (sscanf( buffer, "Swap: %d %d %d", &total, &used, &free ))
4505 lpmem->dwTotalPageFile += total;
4506 lpmem->dwAvailPageFile += free;
4509 /* new style /proc/meminfo ... */
4510 if (sscanf(buffer, "MemTotal: %d", &total))
4511 lpmem->dwTotalPhys = total*1024;
4512 if (sscanf(buffer, "MemFree: %d", &free))
4513 lpmem->dwAvailPhys = free*1024;
4514 if (sscanf(buffer, "SwapTotal: %d", &total))
4515 lpmem->dwTotalPageFile = total*1024;
4516 if (sscanf(buffer, "SwapFree: %d", &free))
4517 lpmem->dwAvailPageFile = free*1024;
4518 if (sscanf(buffer, "Buffers: %d", &buffers))
4519 lpmem->dwAvailPhys += buffers*1024;
4520 if (sscanf(buffer, "Cached: %d", &cached))
4521 lpmem->dwAvailPhys += cached*1024;
4525 if (lpmem->dwTotalPhys)
4527 DWORD TotalPhysical = lpmem->dwTotalPhys+lpmem->dwTotalPageFile;
4528 DWORD AvailPhysical = lpmem->dwAvailPhys+lpmem->dwAvailPageFile;
4529 lpmem->dwMemoryLoad = (TotalPhysical-AvailPhysical)
4530 / (TotalPhysical / 100);
4535 /* FIXME: should do something for other systems */
4536 lpmem->dwMemoryLoad = 0;
4537 lpmem->dwTotalPhys = 16*1024*1024;
4538 lpmem->dwAvailPhys = 16*1024*1024;
4539 lpmem->dwTotalPageFile = 16*1024*1024;
4540 lpmem->dwAvailPageFile = 16*1024*1024;
4542 expGetSystemInfo(&si);
4543 lpmem->dwTotalVirtual = si.lpMaximumApplicationAddress-si.lpMinimumApplicationAddress;
4544 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4545 lpmem->dwAvailVirtual = lpmem->dwTotalVirtual-64*1024;
4546 memcpy(&cached_memstatus,lpmem,sizeof(MEMORYSTATUS));
4547 cache_lastchecked = time(NULL);
4549 /* it appears some memory display programs want to divide by these values */
4550 if(lpmem->dwTotalPageFile==0)
4551 lpmem->dwTotalPageFile++;
4553 if(lpmem->dwAvailPageFile==0)
4554 lpmem->dwAvailPageFile++;
4557 /**********************************************************************
4558 * SetThreadPriority [KERNEL32.@] Sets priority for thread.
4564 static WIN_BOOL WINAPI expSetThreadPriority(
4565 HANDLE hthread, /* [in] Handle to thread */
4566 INT priority) /* [in] Thread priority level */
4568 dbgprintf("SetThreadPriority(%p,%d)\n",hthread,priority);
4572 static void WINAPI expExitProcess( DWORD status )
4574 printf("EXIT - code %ld\n",status);
4578 static INT WINAPI expMessageBoxA(HWND hWnd, LPCSTR text, LPCSTR title, UINT type){
4579 printf("MSGBOX '%s' '%s' (%d)\n",text,title,type);
4581 if (type == MB_ICONHAND && !strlen(text) && !strlen(title))
4587 /* these are needed for mss1 */
4589 /* defined in stubs.s */
4590 void exp_EH_prolog(void);
4592 #include <netinet/in.h>
4593 static WINAPI inline unsigned long int exphtonl(unsigned long int hostlong)
4595 // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4596 return htonl(hostlong);
4599 static WINAPI inline unsigned long int expntohl(unsigned long int netlong)
4601 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4602 return ntohl(netlong);
4604 static void WINAPI expVariantInit(void* p)
4606 printf("InitCommonControls called!\n");
4610 static int WINAPI expRegisterClassA(const void/*WNDCLASSA*/ *wc)
4612 dbgprintf("RegisterClassA(%p) => random id\n", wc);
4613 return time(NULL); /* be precise ! */
4616 static int WINAPI expUnregisterClassA(const char *className, HINSTANCE hInstance)
4618 dbgprintf("UnregisterClassA(%s, %p) => 0\n", className, hInstance);
4623 /* should be fixed bcs it's not fully strlen equivalent */
4624 static int expSysStringByteLen(void *str)
4626 dbgprintf("SysStringByteLen(%p) => %d\n", str, strlen(str));
4630 static int expDirectDrawCreate(void)
4632 dbgprintf("DirectDrawCreate(...) => NULL\n");
4637 typedef struct tagPALETTEENTRY {
4644 /* reversed the first 2 entries */
4645 typedef struct tagLOGPALETTE {
4648 PALETTEENTRY palPalEntry[1];
4651 static HPALETTE WINAPI expCreatePalette(CONST LOGPALETTE *lpgpl)
4656 dbgprintf("CreatePalette(%x) => NULL\n", lpgpl);
4658 i = sizeof(LOGPALETTE)+((lpgpl->palNumEntries-1)*sizeof(PALETTEENTRY));
4659 test = (HPALETTE)malloc(i);
4660 memcpy((void *)test, lpgpl, i);
4665 static int expCreatePalette(void)
4667 dbgprintf("CreatePalette(...) => NULL\n");
4672 static int WINAPI expGetClientRect(HWND win, RECT *r)
4674 dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win, r);
4675 r->right = PSEUDO_SCREEN_WIDTH;
4677 r->bottom = PSEUDO_SCREEN_HEIGHT;
4683 typedef struct tagPOINT {
4689 static int WINAPI expClientToScreen(HWND win, POINT *p)
4691 dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win, p, p->x, p->y);
4699 static int WINAPI expSetThreadIdealProcessor(HANDLE thread, int proc)
4701 dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread, proc);
4705 static int WINAPI expMessageBeep(int type)
4707 dbgprintf("MessageBeep(%d) => 1\n", type);
4711 static int WINAPI expDialogBoxParamA(void *inst, const char *name,
4712 HWND parent, void *dialog_func, void *init_param)
4714 dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
4715 inst, name, name, parent, dialog_func, init_param);
4719 /* needed by imagepower mjpeg2k */
4720 static void *exprealloc(void *ptr, size_t size)
4722 dbgprintf("realloc(0x%x, %x)\n", ptr, size);
4724 return my_mreq(size,0);
4726 return my_realloc(ptr, size);
4729 /* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
4730 static WIN_BOOL WINAPI expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn)
4735 static double expfloor(double x)
4737 dbgprintf("floor(%lf)\n", x);
4741 #define FPU_DOUBLE(var) double var; \
4742 __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var) : )
4744 static double exp_CIcos(void)
4748 dbgprintf("_CIcos(%lf)\n", x);
4752 static double exp_CIsin(void)
4756 dbgprintf("_CIsin(%lf)\n", x);
4770 struct exports* exps;
4774 {#X, Y, (void*)exp##X},
4776 struct exports exp_kernel32[]=
4778 FF(GetVolumeInformationA,-1)
4779 FF(GetDriveTypeA,-1)
4780 FF(GetLogicalDriveStringsA,-1)
4781 FF(IsBadWritePtr, 357)
4782 FF(IsBadReadPtr, 354)
4783 FF(IsBadStringPtrW, -1)
4784 FF(IsBadStringPtrA, -1)
4785 FF(DisableThreadLibraryCalls, -1)
4786 FF(CreateThread, -1)
4787 FF(CreateEventA, -1)
4790 FF(WaitForSingleObject, -1)
4792 FF(WaitForMultipleObjects, -1)
4797 FF(GetSystemInfo, -1)
4805 FF(GetProcessHeap, -1)
4806 FF(VirtualAlloc, -1)
4808 FF(InitializeCriticalSection, -1)
4809 FF(EnterCriticalSection, -1)
4810 FF(LeaveCriticalSection, -1)
4811 FF(DeleteCriticalSection, -1)
4816 FF(GetCurrentThreadId, -1)
4817 FF(GetCurrentProcess, -1)
4822 FF(GlobalReAlloc, -1)
4825 FF(MultiByteToWideChar, 427)
4826 FF(WideCharToMultiByte, -1)
4827 FF(GetVersionExA, -1)
4828 FF(CreateSemaphoreA, -1)
4829 FF(QueryPerformanceCounter, -1)
4830 FF(QueryPerformanceFrequency, -1)
4834 FF(GlobalHandle, -1)
4835 FF(GlobalUnlock, -1)
4837 FF(LoadResource, -1)
4838 FF(ReleaseSemaphore, -1)
4839 FF(FindResourceA, -1)
4840 FF(LockResource, -1)
4841 FF(FreeResource, -1)
4842 FF(SizeofResource, -1)
4844 FF(GetCommandLineA, -1)
4845 FF(GetEnvironmentStringsW, -1)
4846 FF(FreeEnvironmentStringsW, -1)
4847 FF(FreeEnvironmentStringsA, -1)
4848 FF(GetEnvironmentStrings, -1)
4849 FF(GetStartupInfoA, -1)
4850 FF(GetStdHandle, -1)
4853 FF(GetFileAttributesA, -1)
4855 FF(SetHandleCount, -1)
4857 FF(GetModuleFileNameA, -1)
4858 FF(SetUnhandledExceptionFilter, -1)
4859 FF(LoadLibraryA, -1)
4860 FF(GetProcAddress, -1)
4862 FF(CreateFileMappingA, -1)
4863 FF(OpenFileMappingA, -1)
4864 FF(MapViewOfFile, -1)
4865 FF(UnmapViewOfFile, -1)
4867 FF(GetModuleHandleA, -1)
4868 FF(GetProfileIntA, -1)
4869 FF(GetPrivateProfileIntA, -1)
4870 FF(GetPrivateProfileStringA, -1)
4871 FF(WritePrivateProfileStringA, -1)
4872 FF(GetLastError, -1)
4873 FF(SetLastError, -1)
4874 FF(InterlockedIncrement, -1)
4875 FF(InterlockedDecrement, -1)
4876 FF(GetTimeZoneInformation, -1)
4877 FF(OutputDebugStringA, -1)
4878 FF(GetLocalTime, -1)
4879 FF(GetSystemTime, -1)
4880 FF(GetSystemTimeAsFileTime, -1)
4881 FF(GetEnvironmentVariableA, -1)
4882 FF(SetEnvironmentVariableA, -1)
4883 FF(RtlZeroMemory,-1)
4884 FF(RtlMoveMemory,-1)
4885 FF(RtlFillMemory,-1)
4887 FF(FindFirstFileA,-1)
4888 FF(FindNextFileA,-1)
4890 FF(FileTimeToLocalFileTime,-1)
4894 FF(SetFilePointer,-1)
4895 FF(GetTempFileNameA,-1)
4897 FF(GetSystemDirectoryA,-1)
4898 FF(GetWindowsDirectoryA,-1)
4900 FF(GetCurrentDirectoryA,-1)
4901 FF(SetCurrentDirectoryA,-1)
4902 FF(CreateDirectoryA,-1)
4904 FF(GetShortPathNameA,-1)
4905 FF(GetFullPathNameA,-1)
4906 FF(SetErrorMode, -1)
4907 FF(IsProcessorFeaturePresent, -1)
4908 FF(GetProcessAffinityMask, -1)
4909 FF(InterlockedExchange, -1)
4910 FF(InterlockedCompareExchange, -1)
4917 FF(GetProcessVersion,-1)
4918 FF(GetCurrentThread,-1)
4921 FF(DuplicateHandle,-1)
4922 FF(GetTickCount, -1)
4923 FF(SetThreadAffinityMask,-1)
4924 FF(GetCurrentProcessId,-1)
4925 FF(GlobalMemoryStatus,-1)
4926 FF(SetThreadPriority,-1)
4928 {"LoadLibraryExA", -1, (void*)&LoadLibraryExA},
4929 FF(SetThreadIdealProcessor,-1)
4932 struct exports exp_msvcrt[]={
4938 {"??3@YAXPAX@Z", -1, expdelete},
4939 {"??2@YAPAXI@Z", -1, expnew},
4940 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv},
4980 /* needed by frapsvid.dll */
4981 {"strstr",-1,(char *)&strstr},
4982 {"qsort",-1,(void *)&qsort},
4987 {"ceil",-1,(void*)&ceil},
4988 /* needed by imagepower mjpeg2k */
4989 {"clock",-1,(void*)&clock},
4990 {"memchr",-1,(void*)&memchr},
4991 {"vfprintf",-1,(void*)&vfprintf},
4992 // {"realloc",-1,(void*)&realloc},
4994 {"puts",-1,(void*)&puts}
4996 struct exports exp_winmm[]={
4997 FF(GetDriverModuleHandle, -1)
4999 FF(DefDriverProc, -1)
5002 FF(timeGetDevCaps, -1)
5003 FF(timeBeginPeriod, -1)
5005 FF(timeEndPeriod, -1)
5006 FF(waveOutGetNumDevs, -1)
5009 struct exports exp_user32[]={
5014 FF(GetDesktopWindow, -1)
5023 FF(RegisterWindowMessageA,-1)
5024 FF(GetSystemMetrics,-1)
5026 FF(GetSysColorBrush,-1)
5030 FF(RegisterClassA, -1)
5031 FF(UnregisterClassA, -1)
5033 FF(GetWindowRect, -1)
5034 FF(MonitorFromWindow, -1)
5035 FF(MonitorFromRect, -1)
5036 FF(MonitorFromPoint, -1)
5037 FF(EnumDisplayMonitors, -1)
5038 FF(GetMonitorInfoA, -1)
5039 FF(EnumDisplayDevicesA, -1)
5040 FF(GetClientRect, -1)
5041 FF(ClientToScreen, -1)
5042 FF(IsWindowVisible, -1)
5043 FF(GetActiveWindow, -1)
5044 FF(GetClassNameA, -1)
5045 FF(GetClassInfoA, -1)
5046 FF(GetWindowLongA, -1)
5048 FF(GetWindowThreadProcessId, -1)
5049 FF(CreateWindowExA, -1)
5052 FF(DialogBoxParamA, -1)
5054 struct exports exp_advapi32[]={
5056 FF(RegCreateKeyA, -1)
5057 FF(RegCreateKeyExA, -1)
5058 FF(RegEnumKeyExA, -1)
5059 FF(RegEnumValueA, -1)
5061 FF(RegOpenKeyExA, -1)
5062 FF(RegQueryValueExA, -1)
5063 FF(RegSetValueExA, -1)
5064 FF(RegQueryInfoKeyA, -1)
5066 struct exports exp_gdi32[]={
5067 FF(CreateCompatibleDC, -1)
5070 FF(DeleteObject, -1)
5071 FF(GetDeviceCaps, -1)
5072 FF(GetSystemPaletteEntries, -1)
5074 FF(CreatePalette, -1)
5076 FF(CreateRectRgn, -1)
5079 struct exports exp_version[]={
5080 FF(GetFileVersionInfoSizeA, -1)
5082 struct exports exp_ole32[]={
5083 FF(CoCreateFreeThreadedMarshaler,-1)
5084 FF(CoCreateInstance, -1)
5085 FF(CoInitialize, -1)
5086 FF(CoTaskMemAlloc, -1)
5087 FF(CoTaskMemFree, -1)
5088 FF(StringFromGUID2, -1)
5090 // do we really need crtdll ???
5091 // msvcrt is the correct place probably...
5092 struct exports exp_crtdll[]={
5096 struct exports exp_comctl32[]={
5097 FF(StringFromGUID2, -1)
5098 FF(InitCommonControls, 17)
5100 FF(CreateUpDownControl, 16)
5103 struct exports exp_wsock32[]={
5107 struct exports exp_msdmo[]={
5108 FF(memcpy, -1) // just test
5109 FF(MoCopyMediaType, -1)
5110 FF(MoCreateMediaType, -1)
5111 FF(MoDeleteMediaType, -1)
5112 FF(MoDuplicateMediaType, -1)
5113 FF(MoFreeMediaType, -1)
5114 FF(MoInitMediaType, -1)
5116 struct exports exp_oleaut32[]={
5119 FF(SysStringByteLen, 149)
5125 vma: Hint/Ord Member-Name
5130 2305e 167 _adjust_fdiv
5133 22ffc 176 _beginthreadex
5135 2300e 85 __CxxFrameHandler
5139 struct exports exp_pncrt[]={
5140 FF(malloc, -1) // just test
5141 FF(free, -1) // just test
5142 FF(fprintf, -1) // just test
5143 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv},
5146 {"??3@YAXPAX@Z", -1, expdelete},
5147 {"??2@YAPAXI@Z", -1, expnew},
5157 struct exports exp_ddraw[]={
5158 FF(DirectDrawCreate, -1)
5162 struct exports exp_comdlg32[]={
5163 FF(GetOpenFileNameA, -1)
5167 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5169 struct libs libraries[]={
5192 static void ext_stubs(void)
5195 // ax position index
5196 // cx address of printf function
5198 __asm__ __volatile__
5201 "movl $0xdeadbeef, %%eax \n\t"
5202 "movl $0xdeadbeef, %%edx \n\t"
5203 "shl $5, %%eax \n\t" // ax * 32
5204 "addl $0xdeadbeef, %%eax \n\t" // overwrite export_names
5206 "pushl $0xdeadbeef \n\t" // overwrite called_unk
5207 "call *%%edx \n\t" // printf (via dx)
5208 "addl $8, %%esp \n\t"
5209 "xorl %%eax, %%eax \n\t"
5216 __asm__ __volatile__
5219 "movl $0, %%eax \n\t"
5220 "movl $0, %%edx \n\t"
5221 "shl $5, %%eax \n\t" // ax * 32
5222 "addl %0, %%eax \n\t"
5225 "call *%%edx \n\t" // printf (via dx)
5226 "addl $8, %%esp \n\t"
5227 "xorl %%eax, %%eax \n\t"
5229 ::"m"(*export_names), "m"(*called_unk)
5230 : "memory", "edx", "eax"
5236 //static void add_stub(int pos)
5238 extern int unk_exp1;
5240 static char extcode[20000];// place for 200 unresolved exports
5241 static const char* called_unk = "Called unk_%s\n";
5243 static void* add_stub(void)
5245 // generated code in runtime!
5246 char* answ = (char*)extcode+pos*0x30;
5248 memcpy(answ, &unk_exp1, 0x64);
5249 *(int*)(answ+9)=pos;
5250 *(int*)(answ+47)-=((int)answ-(int)&unk_exp1);
5252 memcpy(answ, ext_stubs, 0x2f); // 0x2c is current size
5253 //answ[4] = 0xb8; // movl $0, eax (0xb8 0x00000000)
5254 *((int*) (answ + 5)) = pos;
5255 //answ[9] = 0xba; // movl $0, edx (0xba 0x00000000)
5256 *((long*) (answ + 10)) = (long)printf;
5257 //answ[17] = 0x05; // addl $0, eax (0x05 0x00000000)
5258 *((long*) (answ + 18)) = (long)export_names;
5259 //answ[23] = 0x68; // pushl $0 (0x68 0x00000000)
5260 *((long*) (answ + 24)) = (long)called_unk;
5265 void* LookupExternal(const char* library, int ordinal)
5270 printf("ERROR: library=0\n");
5271 return (void*)ext_unknown;
5273 // printf("%x %x\n", &unk_exp1, &unk_exp2);
5275 dbgprintf("External func %s:%d\n", library, ordinal);
5277 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
5279 if(strcasecmp(library, libraries[i].name))
5281 for(j=0; j<libraries[i].length; j++)
5283 if(ordinal!=libraries[i].exps[j].id)
5285 //printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5286 return libraries[i].exps[j].func;
5290 #ifndef LOADLIB_TRY_NATIVE
5291 /* hack for truespeech and vssh264*/
5292 if (!strcmp(library, "tsd32.dll") || !strcmp(library,"vssh264dec.dll") || !strcmp(library,"LCMW2.dll") || !strcmp(library,"VDODEC32.dll"))
5294 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5300 hand = LoadLibraryA(library);
5303 wm = MODULE32_LookupHMODULE(hand);
5309 func = PE_FindExportedFunction(wm, (LPCSTR) ordinal, 0);
5312 printf("No such ordinal in external dll\n");
5313 FreeLibrary((int)hand);
5317 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5323 if(pos>150)return 0;
5324 sprintf(export_names[pos], "%s:%d", library, ordinal);
5328 void* LookupExternalByName(const char* library, const char* name)
5332 // return (void*)ext_unknown;
5335 printf("ERROR: library=0\n");
5336 return (void*)ext_unknown;
5340 printf("ERROR: name=0\n");
5341 return (void*)ext_unknown;
5343 dbgprintf("External func %s:%s\n", library, name);
5344 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
5346 if(strcasecmp(library, libraries[i].name))
5348 for(j=0; j<libraries[i].length; j++)
5350 if(strcmp(name, libraries[i].exps[j].name))
5352 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5353 return libraries[i].exps[j].func;
5357 #ifndef LOADLIB_TRY_NATIVE
5358 /* hack for vss h264 */
5359 if (!strcmp(library,"vssh264core.dll"))
5361 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5367 hand = LoadLibraryA(library);
5370 wm = MODULE32_LookupHMODULE(hand);
5376 func = PE_FindExportedFunction(wm, name, 0);
5379 printf("No such name in external dll\n");
5380 FreeLibrary((int)hand);
5384 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5390 if(pos>150)return 0;// to many symbols
5391 strcpy(export_names[pos], name);
5395 void my_garbagecollection(void)
5398 int unfree = 0, unfreecnt = 0;
5404 alloc_header* mem = last_alloc + 1;
5405 unfree += my_size(mem);
5407 if (my_release(mem) != 0)
5408 // avoid endless loop when memory is trashed
5409 if (--max_fatal < 0)
5412 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree, unfreecnt, last_alloc, alccnt);