1 /***********************************************************
3 Win32 emulation code. Functions that emulate
4 responses from corresponding Win32 API calls.
5 Since we are not going to be able to load
6 virtually any DLL, we can only implement this
7 much, adding needed functions with each new codec.
9 Basic principle of implementation: it's not good
10 for DLL to know too much about its environment.
12 ************************************************************/
15 * Modified for use with MPlayer, detailed changelog at
16 * http://svn.mplayerhq.hu/mplayer/trunk/
22 #ifdef CONFIG_QTX_CODECS
26 //#define LOADLIB_TRY_NATIVE
29 #define PSEUDO_SCREEN_WIDTH /*640*/800
30 #define PSEUDO_SCREEN_HEIGHT /*480*/600
33 #include "wine/winbase.h"
34 #include "wine/winreg.h"
35 #include "wine/winnt.h"
36 #include "wine/winerror.h"
37 #include "wine/debugtools.h"
38 #include "wine/module.h"
39 #include "wine/winuser.h"
40 #include "wine/objbase.h"
63 #include <sys/types.h>
70 #ifdef HAVE_SYS_MMAN_H
73 #include "osdep/mmap.h"
75 #include "osdep/mmap_anon.h"
77 char* def_path
= WIN32_PATH
;
79 static void do_cpuid(unsigned int ax
, unsigned int *regs
)
83 "pushl %%ebx; pushl %%ecx; pushl %%edx;"
89 "popl %%edx; popl %%ecx; popl %%ebx;"
91 : "0" (ax
), "S" (regs
)
94 static unsigned int c_localcount_tsc()
106 static void c_longcount_tsc(long long* z
)
111 "movl %%eax, %%ebx\n\t"
113 "movl %%eax, 0(%%ebx)\n\t"
114 "movl %%edx, 4(%%ebx)\n\t"
120 static unsigned int c_localcount_notsc()
125 gettimeofday(&tv
, 0);
126 return limit
*tv
.tv_usec
;
128 static void c_longcount_notsc(long long* z
)
131 unsigned long long result
;
135 gettimeofday(&tv
, 0);
138 result
+=limit
*tv
.tv_usec
;
141 static unsigned int localcount_stub(void);
142 static void longcount_stub(long long*);
143 static unsigned int (*localcount
)()=localcount_stub
;
144 static void (*longcount
)(long long*)=longcount_stub
;
146 static pthread_mutex_t memmut
;
148 static unsigned int localcount_stub(void)
150 unsigned int regs
[4];
152 if ((regs
[3] & 0x00000010) != 0)
154 localcount
=c_localcount_tsc
;
155 longcount
=c_longcount_tsc
;
159 localcount
=c_localcount_notsc
;
160 longcount
=c_longcount_notsc
;
164 static void longcount_stub(long long* z
)
166 unsigned int regs
[4];
168 if ((regs
[3] & 0x00000010) != 0)
170 localcount
=c_localcount_tsc
;
171 longcount
=c_longcount_tsc
;
175 localcount
=c_localcount_notsc
;
176 longcount
=c_longcount_notsc
;
182 int LOADER_DEBUG
=1; // active only if compiled with -DDETAILED_OUT
183 //#define DETAILED_OUT
184 static inline void dbgprintf(char* fmt
, ...)
192 f
=fopen("./log", "a");
197 vfprintf(f
, fmt
, va
);
204 if ( mp_msg_test(MSGT_WIN32
,MSGL_DBG3
) )
210 // mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va);
217 char export_names
[300][32]={
222 //#define min(x,y) ((x)<(y)?(x):(y))
224 void destroy_event(void* event
);
227 typedef struct th_list_t
{
230 struct th_list_t
* next
;
231 struct th_list_t
* prev
;
235 // have to be cleared by GARBAGE COLLECTOR
236 //static unsigned char* heap=NULL;
237 //static int heap_counter=0;
238 static tls_t
* g_tls
=NULL
;
239 static th_list
* list
=NULL
;
242 static void test_heap(void)
247 while(offset
<heap_counter
)
249 if(*(int*)(heap
+offset
)!=0x433476)
251 printf("Heap corruption at address %d\n", offset
);
254 offset
+=8+*(int*)(heap
+offset
+4);
256 for(;offset
<min(offset
+1000, 20000000); offset
++)
257 if(heap
[offset
]!=0xCC)
259 printf("Free heap corruption at address %d\n", offset
);
267 static void* my_mreq(int size
, int to_zero
)
271 if(test
%10==0)printf("Memory: %d bytes allocated\n", heap_counter
);
275 heap
=malloc(20000000);
276 memset(heap
, 0xCC,20000000);
280 printf("No enough memory\n");
283 if(heap_counter
+size
>20000000)
285 printf("No enough memory\n");
288 *(int*)(heap
+heap_counter
)=0x433476;
290 *(int*)(heap
+heap_counter
)=size
;
292 printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size
, heap_counter
-8, heap_counter
, heap_counter
+size
);
294 memset(heap
+heap_counter
, 0, size
);
296 memset(heap
+heap_counter
, 0xcc, size
); // make crash reproducable
298 return heap
+heap_counter
-size
;
300 static int my_release(char* memory
)
305 printf("ERROR: free(0)\n");
308 if(*(int*)(memory
-8)!=0x433476)
310 printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
313 printf("Freed %d bytes of memory\n", *(int*)(memory
-4));
314 // memset(memory-8, *(int*)(memory-4), 0xCC);
320 typedef struct alloc_header_t alloc_header
;
321 struct alloc_header_t
323 // let's keep allocated data 16 byte aligned
335 static alloc_header
* last_alloc
= NULL
;
336 static int alccnt
= 0;
339 #define AREATYPE_CLIENT 0
340 #define AREATYPE_EVENT 1
341 #define AREATYPE_MUTEX 2
342 #define AREATYPE_COND 3
343 #define AREATYPE_CRITSECT 4
345 /* -- critical sections -- */
349 pthread_mutex_t mutex
;
354 void* mreq_private(int size
, int to_zero
, int type
);
355 void* mreq_private(int size
, int to_zero
, int type
)
357 int nsize
= size
+ sizeof(alloc_header
);
358 alloc_header
* header
= (alloc_header
* ) malloc(nsize
);
362 memset(header
, 0, nsize
);
366 pthread_mutex_init(&memmut
, NULL
);
367 pthread_mutex_lock(&memmut
);
371 pthread_mutex_lock(&memmut
);
372 last_alloc
->next
= header
; /* set next */
375 header
->prev
= last_alloc
;
379 pthread_mutex_unlock(&memmut
);
381 header
->deadbeef
= 0xdeadbeef;
385 //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt);
389 static int my_release(void* memory
)
391 alloc_header
* header
= (alloc_header
*) memory
- 1;
393 alloc_header
* prevmem
;
394 alloc_header
* nextmem
;
399 if (header
->deadbeef
!= (long) 0xdeadbeef)
401 dbgprintf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
405 pthread_mutex_lock(&memmut
);
410 destroy_event(memory
);
413 pthread_cond_destroy((pthread_cond_t
*)memory
);
416 pthread_mutex_destroy((pthread_mutex_t
*)memory
);
418 case AREATYPE_CRITSECT
:
419 pthread_mutex_destroy(&((struct CRITSECT
*)memory
)->mutex
);
422 //memset(memory, 0xcc, header->size);
426 header
->deadbeef
= 0;
427 prevmem
= header
->prev
;
428 nextmem
= header
->next
;
431 prevmem
->next
= nextmem
;
433 nextmem
->prev
= prevmem
;
435 if (header
== last_alloc
)
436 last_alloc
= prevmem
;
441 pthread_mutex_unlock(&memmut
);
443 pthread_mutex_destroy(&memmut
);
445 //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt);
450 //memset(header + 1, 0xcc, header->size);
456 static inline void* my_mreq(int size
, int to_zero
)
458 return mreq_private(size
, to_zero
, AREATYPE_CLIENT
);
461 static int my_size(void* memory
)
463 if(!memory
) return 0;
464 return ((alloc_header
*)memory
)[-1].size
;
467 static void* my_realloc(void* memory
, int size
)
472 return my_mreq(size
, 0);
473 osize
= my_size(memory
);
476 ans
= my_mreq(size
, 0);
477 memcpy(ans
, memory
, osize
);
485 * WINE API - native implementation for several win32 libraries
489 static int WINAPI
ext_unknown()
491 printf("Unknown func called\n");
495 static int WINAPI
expGetVolumeInformationA( const char *root
, char *label
,
496 unsigned int label_len
, unsigned int *serial
,
497 unsigned int *filename_len
,unsigned int *flags
,
498 char *fsname
, unsigned int fsname_len
)
500 dbgprintf("GetVolumeInformationA( %s, 0x%x, %ld, 0x%x, 0x%x, 0x%x, 0x%x, %ld) => 1\n",
501 root
,label
,label_len
,serial
,filename_len
,flags
,fsname
,fsname_len
);
502 //hack Do not return any real data - do nothing
506 static unsigned int WINAPI
expGetDriveTypeA( const char *root
)
508 dbgprintf("GetDriveTypeA( %s ) => %d\n",root
,DRIVE_FIXED
);
509 // hack return as Fixed Drive Type
513 static unsigned int WINAPI
expGetLogicalDriveStringsA( unsigned int len
, char *buffer
)
515 dbgprintf("GetLogicalDriveStringsA(%d, 0x%x) => 4\n",len
,buffer
);
516 // hack only have one drive c:\ in this hack
522 return 4; // 1 drive * 4 bytes (includes null)
526 static int WINAPI
expIsBadWritePtr(void* ptr
, unsigned int count
)
528 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
529 dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
532 static int WINAPI
expIsBadReadPtr(void* ptr
, unsigned int count
)
534 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
535 dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
538 static int WINAPI
expDisableThreadLibraryCalls(int module
)
540 dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module
);
544 static HMODULE WINAPI
expGetDriverModuleHandle(DRVR
* pdrv
)
550 result
=pdrv
->hDriverModule
;
551 dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv
, result
);
555 #define MODULE_HANDLE_kernel32 ((HMODULE)0x120)
556 #define MODULE_HANDLE_user32 ((HMODULE)0x121)
558 #define MODULE_HANDLE_wininet ((HMODULE)0x122)
559 #define MODULE_HANDLE_ddraw ((HMODULE)0x123)
560 #define MODULE_HANDLE_advapi32 ((HMODULE)0x124)
562 #define MODULE_HANDLE_comdlg32 ((HMODULE)0x125)
563 #define MODULE_HANDLE_msvcrt ((HMODULE)0x126)
564 #define MODULE_HANDLE_ole32 ((HMODULE)0x127)
565 #define MODULE_HANDLE_winmm ((HMODULE)0x128)
567 static HMODULE WINAPI
expGetModuleHandleA(const char* name
)
579 wm
=MODULE_FindModule(name
);
582 result
=(HMODULE
)(wm
->module
);
586 if(name
&& (strcasecmp(name
, "kernel32")==0 || !strcasecmp(name
, "kernel32.dll")))
587 result
=MODULE_HANDLE_kernel32
;
589 if(name
&& strcasecmp(name
, "user32")==0)
590 result
=MODULE_HANDLE_user32
;
593 dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name
, result
);
597 static void* WINAPI
expCreateThread(void* pSecAttr
, long dwStackSize
,
598 void* lpStartAddress
, void* lpParameter
,
599 long dwFlags
, long* dwThreadId
)
602 // printf("CreateThread:");
603 pth
= (pthread_t
*) my_mreq(sizeof(pthread_t
), 0);
604 pthread_create(pth
, NULL
, (void*(*)(void*))lpStartAddress
, lpParameter
);
606 printf( "WARNING: CreateThread flags not supported\n");
608 *dwThreadId
=(long)pth
;
611 list
=my_mreq(sizeof(th_list
), 1);
612 list
->next
=list
->prev
=NULL
;
616 list
->next
=my_mreq(sizeof(th_list
), 0);
617 list
->next
->prev
=list
;
618 list
->next
->next
=NULL
;
622 dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
623 pSecAttr
, dwStackSize
, lpStartAddress
, lpParameter
, dwFlags
, dwThreadId
, pth
);
638 struct mutex_list_t
* next
;
639 struct mutex_list_t
* prev
;
641 typedef struct mutex_list_t mutex_list
;
642 static mutex_list
* mlist
=NULL
;
644 void destroy_event(void* event
)
646 mutex_list
* pp
=mlist
;
647 // printf("garbage collector: destroy_event(%x)\n", event);
650 if(pp
==(mutex_list
*)event
)
653 pp
->next
->prev
=pp
->prev
;
655 pp
->prev
->next
=pp
->next
;
656 if(mlist
==(mutex_list
*)event
)
662 printf("%x => ", pp);
673 static void* WINAPI
expCreateEventA(void* pSecAttr
, char bManualReset
,
674 char bInitialState
, const char* name
)
683 printf("%x => ", pp);
690 mutex_list
* pp
=mlist
;
694 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==0))
696 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
697 pSecAttr
, bManualReset
, bInitialState
, name
, name
, pp
->pm
);
700 }while((pp
=pp
->prev
) != NULL
);
702 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
703 pthread_mutex_init(pm
, NULL
);
704 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
705 pthread_cond_init(pc
, NULL
);
708 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
709 mlist
->next
=mlist
->prev
=NULL
;
713 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
714 mlist
->next
->prev
=mlist
;
715 mlist
->next
->next
=NULL
;
718 mlist
->type
=0; /* Type Event */
721 mlist
->state
=bInitialState
;
722 mlist
->reset
=bManualReset
;
724 strncpy(mlist
->name
, name
, 127);
728 dbgprintf("ERROR::: CreateEventA failure\n");
731 pthread_mutex_lock(pm);
734 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
735 pSecAttr
, bManualReset
, bInitialState
, name
, name
, mlist
);
737 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
738 pSecAttr
, bManualReset
, bInitialState
, mlist
);
742 static void* WINAPI
expSetEvent(void* event
)
744 mutex_list
*ml
= (mutex_list
*)event
;
745 dbgprintf("SetEvent(%x) => 0x1\n", event
);
746 pthread_mutex_lock(ml
->pm
);
747 if (ml
->state
== 0) {
749 pthread_cond_signal(ml
->pc
);
751 pthread_mutex_unlock(ml
->pm
);
755 static void* WINAPI
expResetEvent(void* event
)
757 mutex_list
*ml
= (mutex_list
*)event
;
758 dbgprintf("ResetEvent(0x%x) => 0x1\n", event
);
759 pthread_mutex_lock(ml
->pm
);
761 pthread_mutex_unlock(ml
->pm
);
766 static void* WINAPI
expWaitForSingleObject(void* object
, int duration
)
768 mutex_list
*ml
= (mutex_list
*)object
;
769 // FIXME FIXME FIXME - this value is sometime unititialize !!!
770 int ret
= WAIT_FAILED
;
771 mutex_list
* pp
=mlist
;
772 if(object
== (void*)0xcfcf9898)
775 From GetCurrentThread() documentation:
776 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.
778 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.
780 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.
782 dbgprintf("WaitForSingleObject(thread_handle) called\n");
783 return (void*)WAIT_FAILED
;
785 dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object
, duration
);
787 // loop below was slightly fixed - its used just for checking if
788 // this object really exists in our list
791 while (pp
&& (pp
->pm
!= ml
->pm
))
794 dbgprintf("WaitForSingleObject: NotFound\n");
798 pthread_mutex_lock(ml
->pm
);
802 if (duration
== 0) { /* Check Only */
803 if (ml
->state
== 1) ret
= WAIT_FAILED
;
804 else ret
= WAIT_OBJECT_0
;
806 if (duration
== -1) { /* INFINITE */
808 pthread_cond_wait(ml
->pc
,ml
->pm
);
813 if (duration
> 0) { /* Timed Wait */
814 struct timespec abstime
;
816 gettimeofday(&now
, 0);
817 abstime
.tv_sec
= now
.tv_sec
+ (now
.tv_usec
+duration
)/1000000;
818 abstime
.tv_nsec
= ((now
.tv_usec
+duration
)%1000000)*1000;
820 ret
=pthread_cond_timedwait(ml
->pc
,ml
->pm
,&abstime
);
821 if (ret
== ETIMEDOUT
) ret
= WAIT_TIMEOUT
;
822 else ret
= WAIT_OBJECT_0
;
827 case 1: /* Semaphore */
829 if(ml
->semaphore
==0) ret
= WAIT_FAILED
;
835 if (duration
== -1) {
836 if (ml
->semaphore
==0)
837 pthread_cond_wait(ml
->pc
,ml
->pm
);
842 pthread_mutex_unlock(ml
->pm
);
844 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object
,duration
,ml
,ret
);
849 static void* WINAPI
expWaitForMultipleObjects(int count
, const void** objects
,
850 int WaitAll
, int duration
)
856 dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
857 count
, objects
, WaitAll
, duration
);
859 for (i
= 0; i
< count
; i
++)
861 object
= (void *)objects
[i
];
862 ret
= expWaitForSingleObject(object
, duration
);
864 dbgprintf("WaitAll flag not yet supported...\n");
871 static void WINAPI
expExitThread(int retcode
)
873 dbgprintf("ExitThread(%d)\n", retcode
);
874 pthread_exit(&retcode
);
877 static HANDLE WINAPI
expCreateMutexA(void *pSecAttr
,
878 char bInitialOwner
, const char *name
)
880 HANDLE mlist
= (HANDLE
)expCreateEventA(pSecAttr
, 0, 0, name
);
883 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
884 pSecAttr
, bInitialOwner
, name
, mlist
);
886 dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
887 pSecAttr
, bInitialOwner
, mlist
);
889 /* 10l to QTX, if CreateMutex returns a real mutex, WaitForSingleObject
890 waits for ever, else it works ;) */
895 static int WINAPI
expReleaseMutex(HANDLE hMutex
)
897 dbgprintf("ReleaseMutex(%x) => 1\n", hMutex
);
898 /* FIXME:XXX !! not yet implemented */
903 static int pf_set
= 0;
904 static BYTE PF
[64] = {0,};
906 static void DumpSystemInfo(const SYSTEM_INFO
* si
)
908 dbgprintf(" Processor architecture %d\n", si
->u
.s
.wProcessorArchitecture
);
909 dbgprintf(" Page size: %d\n", si
->dwPageSize
);
910 dbgprintf(" Minimum app address: %d\n", si
->lpMinimumApplicationAddress
);
911 dbgprintf(" Maximum app address: %d\n", si
->lpMaximumApplicationAddress
);
912 dbgprintf(" Active processor mask: 0x%x\n", si
->dwActiveProcessorMask
);
913 dbgprintf(" Number of processors: %d\n", si
->dwNumberOfProcessors
);
914 dbgprintf(" Processor type: 0x%x\n", si
->dwProcessorType
);
915 dbgprintf(" Allocation granularity: 0x%x\n", si
->dwAllocationGranularity
);
916 dbgprintf(" Processor level: 0x%x\n", si
->wProcessorLevel
);
917 dbgprintf(" Processor revision: 0x%x\n", si
->wProcessorRevision
);
920 static void WINAPI
expGetSystemInfo(SYSTEM_INFO
* si
)
922 /* FIXME: better values for the two entries below... */
923 static int cache
= 0;
924 static SYSTEM_INFO cachedsi
;
925 dbgprintf("GetSystemInfo(%p) =>\n", si
);
930 memset(PF
,0,sizeof(PF
));
933 cachedsi
.u
.s
.wProcessorArchitecture
= PROCESSOR_ARCHITECTURE_INTEL
;
934 cachedsi
.dwPageSize
= getpagesize();
936 /* FIXME: better values for the two entries below... */
937 cachedsi
.lpMinimumApplicationAddress
= (void *)0x00000000;
938 cachedsi
.lpMaximumApplicationAddress
= (void *)0x7FFFFFFF;
939 cachedsi
.dwActiveProcessorMask
= 1;
940 cachedsi
.dwNumberOfProcessors
= 1;
941 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
942 cachedsi
.dwAllocationGranularity
= 0x10000;
943 cachedsi
.wProcessorLevel
= 5; /* pentium */
944 cachedsi
.wProcessorRevision
= 0x0101;
946 /* mplayer's way to detect PF's */
948 #include "cpudetect.h"
951 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
953 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
954 if (gCpuCaps
.hasSSE2
)
955 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
956 if (gCpuCaps
.has3DNow
)
957 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
959 if (gCpuCaps
.cpuType
== 4)
961 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
962 cachedsi
.wProcessorLevel
= 4;
964 else if (gCpuCaps
.cpuType
>= 5)
966 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
967 cachedsi
.wProcessorLevel
= 5;
971 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
972 cachedsi
.wProcessorLevel
= 3;
974 cachedsi
.wProcessorRevision
= gCpuCaps
.cpuStepping
;
975 cachedsi
.dwNumberOfProcessors
= 1; /* hardcoded */
978 /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
979 fdiv_bug and fpu emulation flags -- alex/MPlayer */
984 FILE *f
= fopen ("/proc/cpuinfo", "r");
988 mp_msg(MSGT_WIN32
, MSGL_WARN
, "expGetSystemInfo: "
989 "/proc/cpuinfo not readable! "
990 "Expect bad performance and/or weird behaviour\n");
993 while (fgets(line
,200,f
)!=NULL
) {
996 /* NOTE: the ':' is the only character we can rely on */
997 if (!(value
= strchr(line
,':')))
999 /* terminate the valuename */
1001 /* skip any leading spaces */
1002 while (*value
==' ') value
++;
1003 if ((s
=strchr(value
,'\n')))
1007 if (!lstrncmpiA(line
, "cpu family",strlen("cpu family"))) {
1008 if (isdigit (value
[0])) {
1009 switch (value
[0] - '0') {
1010 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1011 cachedsi
.wProcessorLevel
= 3;
1013 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1014 cachedsi
.wProcessorLevel
= 4;
1016 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1017 cachedsi
.wProcessorLevel
= 5;
1019 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1020 cachedsi
.wProcessorLevel
= 5;
1022 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1023 cachedsi
.wProcessorLevel
= 5;
1027 /* set the CPU type of the current processor */
1028 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1031 /* old 2.0 method */
1032 if (!lstrncmpiA(line
, "cpu",strlen("cpu"))) {
1033 if ( isdigit (value
[0]) && value
[1] == '8' &&
1034 value
[2] == '6' && value
[3] == 0
1036 switch (value
[0] - '0') {
1037 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1038 cachedsi
.wProcessorLevel
= 3;
1040 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1041 cachedsi
.wProcessorLevel
= 4;
1043 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1044 cachedsi
.wProcessorLevel
= 5;
1046 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1047 cachedsi
.wProcessorLevel
= 5;
1049 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1050 cachedsi
.wProcessorLevel
= 5;
1054 /* set the CPU type of the current processor */
1055 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1058 if (!lstrncmpiA(line
,"fdiv_bug",strlen("fdiv_bug"))) {
1059 if (!lstrncmpiA(value
,"yes",3))
1060 PF
[PF_FLOATING_POINT_PRECISION_ERRATA
] = TRUE
;
1064 if (!lstrncmpiA(line
,"fpu",strlen("fpu"))) {
1065 if (!lstrncmpiA(value
,"no",2))
1066 PF
[PF_FLOATING_POINT_EMULATED
] = TRUE
;
1070 if (!lstrncmpiA(line
,"processor",strlen("processor"))) {
1071 /* processor number counts up...*/
1074 if (sscanf(value
,"%d",&x
))
1075 if (x
+1>cachedsi
.dwNumberOfProcessors
)
1076 cachedsi
.dwNumberOfProcessors
=x
+1;
1078 /* Create a new processor subkey on a multiprocessor
1081 sprintf(buf
,"%d",x
);
1083 if (!lstrncmpiA(line
,"stepping",strlen("stepping"))) {
1086 if (sscanf(value
,"%d",&x
))
1087 cachedsi
.wProcessorRevision
= x
;
1090 ( (!lstrncmpiA(line
,"flags",strlen("flags")))
1091 || (!lstrncmpiA(line
,"features",strlen("features"))) )
1093 if (strstr(value
,"cx8"))
1094 PF
[PF_COMPARE_EXCHANGE_DOUBLE
] = TRUE
;
1095 if (strstr(value
,"mmx"))
1096 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1097 if (strstr(value
,"tsc"))
1098 PF
[PF_RDTSC_INSTRUCTION_AVAILABLE
] = TRUE
;
1099 if (strstr(value
,"xmm") || strstr(value
,"sse"))
1100 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1101 if (strstr(value
,"sse2"))
1102 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1103 if (strstr(value
,"3dnow"))
1104 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1109 * ad hoc fix for smp machines.
1110 * some problems on WaitForSingleObject,CreateEvent,SetEvent
1111 * CreateThread ...etc..
1114 cachedsi
.dwNumberOfProcessors
=1;
1116 #endif /* __linux__ */
1119 memcpy(si
,&cachedsi
,sizeof(*si
));
1123 // avoid undefined expGetSystemInfo
1124 static WIN_BOOL WINAPI
expIsProcessorFeaturePresent(DWORD v
)
1126 WIN_BOOL result
= 0;
1130 expGetSystemInfo(&si
);
1132 if(v
<64) result
=PF
[v
];
1133 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v
, result
);
1138 static long WINAPI
expGetVersion()
1140 dbgprintf("GetVersion() => 0xC0000004\n");
1141 return 0xC0000004;//Windows 95
1144 static HANDLE WINAPI
expHeapCreate(long flags
, long init_size
, long max_size
)
1146 // printf("HeapCreate:");
1149 result
=(HANDLE
)my_mreq(0x110000, 0);
1151 result
=(HANDLE
)my_mreq((init_size
+ 0xfff) & 0x7ffff000 , 0);
1152 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags
, init_size
, max_size
, result
);
1156 // this is another dirty hack
1157 // VP31 is releasing one allocated Heap chunk twice
1158 // we will silently ignore this second call...
1159 static void* heapfreehack
= 0;
1160 static int heapfreehackshown
= 0;
1161 //void trapbug(void);
1162 static void* WINAPI
expHeapAlloc(HANDLE heap
, int flags
, int size
)
1166 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1167 HeapAlloc returns area larger than size argument :-/
1169 actually according to M$ Doc HeapCreate size should be rounded
1170 to page boundaries thus we should simulate this
1172 //if (size == 22276) trapbug();
1173 z
=my_mreq((size
+ 0xfff) & 0x7ffff000, (flags
& HEAP_ZERO_MEMORY
));
1175 printf("HeapAlloc failure\n");
1176 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap
, flags
, size
, z
);
1177 heapfreehack
= 0; // reset
1180 static long WINAPI
expHeapDestroy(void* heap
)
1182 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap
);
1187 static long WINAPI
expHeapFree(HANDLE heap
, DWORD dwFlags
, LPVOID lpMem
)
1189 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap
, dwFlags
, lpMem
);
1190 if (heapfreehack
!= lpMem
&& lpMem
!= (void*)0xffffffff
1191 && lpMem
!= (void*)0xbdbdbdbd)
1192 // 0xbdbdbdbd is for i263_drv.drv && libefence
1193 // it seems to be reading from relased memory
1194 // EF_PROTECT_FREE doens't show any probleme
1198 if (!heapfreehackshown
++)
1199 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem
);
1201 heapfreehack
= lpMem
;
1204 static long WINAPI
expHeapSize(int heap
, int flags
, void* pointer
)
1206 long result
=my_size(pointer
);
1207 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap
, flags
, pointer
, result
);
1210 static void* WINAPI
expHeapReAlloc(HANDLE heap
,int flags
,void *lpMem
,int size
)
1212 long orgsize
= my_size(lpMem
);
1213 dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize
,size
);
1214 return my_realloc(lpMem
, size
);
1216 static long WINAPI
expGetProcessHeap(void)
1218 dbgprintf("GetProcessHeap() => 1\n");
1221 static void* WINAPI
expVirtualAlloc(void* v1
, long v2
, long v3
, long v4
)
1223 void* z
= VirtualAlloc(v1
, v2
, v3
, v4
);
1225 printf("VirtualAlloc failure\n");
1226 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1
,v2
,v3
,v4
, z
);
1229 static int WINAPI
expVirtualFree(void* v1
, int v2
, int v3
)
1231 int result
= VirtualFree(v1
,v2
,v3
);
1232 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1
,v2
,v3
, result
);
1236 /* we're building a table of critical sections. cs_win pointer uses the DLL
1237 cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1238 struct critsecs_list_t
1240 CRITICAL_SECTION
*cs_win
;
1241 struct CRITSECT
*cs_unix
;
1244 /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1245 #undef CRITSECS_NEWTYPE
1246 //#define CRITSECS_NEWTYPE 1
1248 #ifdef CRITSECS_NEWTYPE
1249 /* increased due to ucod needs more than 32 entries */
1250 /* and 64 should be enough for everything */
1251 #define CRITSECS_LIST_MAX 64
1252 static struct critsecs_list_t critsecs_list
[CRITSECS_LIST_MAX
];
1254 static int critsecs_get_pos(CRITICAL_SECTION
*cs_win
)
1258 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1259 if (critsecs_list
[i
].cs_win
== cs_win
)
1264 static int critsecs_get_unused(void)
1268 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1269 if (critsecs_list
[i
].cs_win
== NULL
)
1274 struct CRITSECT
*critsecs_get_unix(CRITICAL_SECTION
*cs_win
)
1278 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1279 if (critsecs_list
[i
].cs_win
== cs_win
&& critsecs_list
[i
].cs_unix
)
1280 return critsecs_list
[i
].cs_unix
;
1285 static void WINAPI
expInitializeCriticalSection(CRITICAL_SECTION
* c
)
1287 dbgprintf("InitializeCriticalSection(0x%x)\n", c
);
1288 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1290 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1291 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1294 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1295 #ifdef CRITSECS_NEWTYPE
1297 struct CRITSECT
*cs
;
1298 int i
= critsecs_get_unused();
1302 printf("InitializeCriticalSection(%p) - no more space in list\n", c
);
1305 dbgprintf("got unused space at %d\n", i
);
1306 cs
= malloc(sizeof(struct CRITSECT
));
1309 printf("InitializeCriticalSection(%p) - out of memory\n", c
);
1312 pthread_mutex_init(&cs
->mutex
, NULL
);
1314 critsecs_list
[i
].cs_win
= c
;
1315 critsecs_list
[i
].cs_unix
= cs
;
1316 dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1321 struct CRITSECT
* cs
= mreq_private(sizeof(struct CRITSECT
) + sizeof(CRITICAL_SECTION
),
1322 0, AREATYPE_CRITSECT
);
1323 pthread_mutex_init(&cs
->mutex
, NULL
);
1325 cs
->deadbeef
= 0xdeadbeef;
1332 static void WINAPI
expEnterCriticalSection(CRITICAL_SECTION
* c
)
1334 #ifdef CRITSECS_NEWTYPE
1335 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1337 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1339 dbgprintf("EnterCriticalSection(0x%x) %p\n",c
, cs
);
1342 dbgprintf("entered uninitialized critisec!\n");
1343 expInitializeCriticalSection(c
);
1344 #ifdef CRITSECS_NEWTYPE
1345 cs
=critsecs_get_unix(c
);
1347 cs
= (*(struct CRITSECT
**)c
);
1349 dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c
);
1352 if(cs
->id
==pthread_self())
1354 pthread_mutex_lock(&(cs
->mutex
));
1356 cs
->id
=pthread_self();
1359 static void WINAPI
expLeaveCriticalSection(CRITICAL_SECTION
* c
)
1361 #ifdef CRITSECS_NEWTYPE
1362 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1364 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1366 // struct CRITSECT* cs=(struct CRITSECT*)c;
1367 dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c
, cs
);
1370 dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c
);
1376 pthread_mutex_unlock(&(cs
->mutex
));
1379 dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c
);
1383 static void expfree(void* mem
); /* forward declaration */
1385 static void WINAPI
expDeleteCriticalSection(CRITICAL_SECTION
*c
)
1387 #ifdef CRITSECS_NEWTYPE
1388 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1390 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1392 // struct CRITSECT* cs=(struct CRITSECT*)c;
1393 dbgprintf("DeleteCriticalSection(0x%x)\n",c
);
1397 dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c
);
1403 dbgprintf("Win32 Warning: Deleting unlocked Critical Section %p!!\n", c
);
1404 pthread_mutex_unlock(&(cs
->mutex
));
1408 pthread_mutex_destroy(&(cs
->mutex
));
1409 // released by GarbageCollector in my_relase otherwise
1412 #ifdef CRITSECS_NEWTYPE
1414 int i
= critsecs_get_pos(c
);
1418 printf("DeleteCriticalSection(%p) error (critsec not found)\n", c
);
1422 critsecs_list
[i
].cs_win
= NULL
;
1423 expfree(critsecs_list
[i
].cs_unix
);
1424 critsecs_list
[i
].cs_unix
= NULL
;
1425 dbgprintf("DeleteCriticalSection -> itemno=%d\n", i
);
1430 static int WINAPI
expGetCurrentThreadId()
1432 dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1433 return pthread_self();
1435 static int WINAPI
expGetCurrentProcess()
1437 dbgprintf("GetCurrentProcess() => %d\n", getpid());
1442 // this version is required for Quicktime codecs (.qtx/.qts) to work.
1443 // (they assume some pointers at FS: segment)
1445 extern void* fs_seg
;
1447 //static int tls_count;
1448 static int tls_use_map
[64];
1449 static int WINAPI
expTlsAlloc()
1453 if(tls_use_map
[i
]==0)
1456 dbgprintf("TlsAlloc() => %d\n",i
);
1459 dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1463 //static int WINAPI expTlsSetValue(DWORD index, void* value)
1464 static int WINAPI
expTlsSetValue(int index
, void* value
)
1466 dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index
,value
);
1467 // if((index<0) || (index>64))
1470 *(void**)((char*)fs_seg
+0x88+4*index
) = value
;
1474 static void* WINAPI
expTlsGetValue(DWORD index
)
1476 dbgprintf("TlsGetValue(%d)\n",index
);
1477 // if((index<0) || (index>64))
1478 if((index
>=64)) return NULL
;
1479 return *(void**)((char*)fs_seg
+0x88+4*index
);
1482 static int WINAPI
expTlsFree(int idx
)
1484 int index
= (int) idx
;
1485 dbgprintf("TlsFree(%d)\n",index
);
1486 if((index
<0) || (index
>64))
1488 tls_use_map
[index
]=0;
1500 static void* WINAPI
expTlsAlloc()
1504 g_tls
=my_mreq(sizeof(tls_t
), 0);
1505 g_tls
->next
=g_tls
->prev
=NULL
;
1509 g_tls
->next
=my_mreq(sizeof(tls_t
), 0);
1510 g_tls
->next
->prev
=g_tls
;
1511 g_tls
->next
->next
=NULL
;
1514 dbgprintf("TlsAlloc() => 0x%x\n", g_tls
);
1516 g_tls
->value
=0; /* XXX For Divx.dll */
1520 static int WINAPI
expTlsSetValue(void* idx
, void* value
)
1522 tls_t
* index
= (tls_t
*) idx
;
1531 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index
, value
, result
);
1534 static void* WINAPI
expTlsGetValue(void* idx
)
1536 tls_t
* index
= (tls_t
*) idx
;
1541 result
=index
->value
;
1542 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index
, result
);
1545 static int WINAPI
expTlsFree(void* idx
)
1547 tls_t
* index
= (tls_t
*) idx
;
1554 index
->next
->prev
=index
->prev
;
1556 index
->prev
->next
=index
->next
;
1558 g_tls
= index
->prev
;
1559 my_release((void*)index
);
1562 dbgprintf("TlsFree(index 0x%x) => %d\n", index
, result
);
1567 static void* WINAPI
expLocalAlloc(int flags
, int size
)
1569 void* z
= my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1571 printf("LocalAlloc() failed\n");
1572 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1576 static void* WINAPI
expLocalReAlloc(int handle
,int size
, int flags
)
1582 if (flags
& LMEM_MODIFY
) {
1583 dbgprintf("LocalReAlloc MODIFY\n");
1584 return (void *)handle
;
1586 oldsize
= my_size((void *)handle
);
1587 newpointer
= my_realloc((void *)handle
,size
);
1588 dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle
,size
,oldsize
, flags
,newpointer
);
1593 static void* WINAPI
expLocalLock(void* z
)
1595 dbgprintf("LocalLock(0x%x) => 0x%x\n", z
, z
);
1599 static void* WINAPI
expGlobalAlloc(int flags
, int size
)
1602 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size
, flags
);
1604 z
=my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1605 //z=calloc(size, 1);
1608 printf("GlobalAlloc() failed\n");
1609 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1612 static void* WINAPI
expGlobalLock(void* z
)
1614 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z
, z
);
1617 // pvmjpg20 - but doesn't work anyway
1618 static int WINAPI
expGlobalSize(void* amem
)
1622 alloc_header
* header
= last_alloc
;
1623 alloc_header
* mem
= (alloc_header
*) amem
- 1;
1626 pthread_mutex_lock(&memmut
);
1629 if (header
->deadbeef
!= 0xdeadbeef)
1631 dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
1637 size
= header
->size
;
1641 header
= header
->prev
;
1643 pthread_mutex_unlock(&memmut
);
1646 dbgprintf("GlobalSize(0x%x)\n", amem
);
1650 static int WINAPI
expLoadIconA( long hinstance
, char *name
)
1652 dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance
,name
);
1656 static int WINAPI
expLoadStringA(long instance
, long id
, void* buf
, long size
)
1658 int result
=LoadStringA(instance
, id
, buf
, size
);
1660 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1661 instance
, id
, buf
, size
, result
, buf
);
1663 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1664 // instance, id, buf, size, result);
1668 static long WINAPI
expMultiByteToWideChar(long v1
, long v2
, char* s1
, long siz1
, short* s2
, int siz2
)
1677 if(siz1
>siz2
/2)siz1
=siz2
/2;
1678 for(i
=1; i
<=siz1
; i
++)
1688 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1689 "size %d, dest buffer 0x%x, dest size %d) => %d\n",
1690 v1
, v2
, s1
, s1
, siz1
, s2
, siz2
, result
);
1692 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1693 "size %d, dest buffer 0x%x, dest size %d) =>\n",
1694 v1
, v2
, siz1
, s2
, siz2
, result
);
1697 static void wch_print(const short* str
)
1699 dbgprintf(" src: ");
1700 while(*str
)dbgprintf("%c", *str
++);
1703 static long WINAPI
expWideCharToMultiByte(long v1
, long v2
, short* s1
, long siz1
,
1704 char* s2
, int siz2
, char* c3
, int* siz3
)
1707 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1708 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1709 result
=WideCharToMultiByte(v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1710 dbgprintf("=> %d\n", result
);
1711 //if(s1)wch_print(s1);
1712 if(s2
)dbgprintf(" dest: %s\n", s2
);
1715 static long WINAPI
expGetVersionExA(OSVERSIONINFOA
* c
)
1717 dbgprintf("GetVersionExA(0x%x) => 1\n");
1718 c
->dwOSVersionInfoSize
=sizeof(*c
);
1719 c
->dwMajorVersion
=4;
1720 c
->dwMinorVersion
=0;
1721 c
->dwBuildNumber
=0x4000457;
1723 // leave it here for testing win9x-only codecs
1724 c
->dwPlatformId
=VER_PLATFORM_WIN32_WINDOWS
;
1725 strcpy(c
->szCSDVersion
, " B");
1727 c
->dwPlatformId
=VER_PLATFORM_WIN32_NT
; // let's not make DLL assume that it can read CR* registers
1728 strcpy(c
->szCSDVersion
, "Service Pack 3");
1730 dbgprintf(" Major version: 4\n Minor version: 0\n Build number: 0x4000457\n"
1731 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 3'\n");
1734 static HANDLE WINAPI
expCreateSemaphoreA(char* v1
, long init_count
,
1735 long max_count
, char* name
)
1737 pthread_mutex_t
*pm
;
1741 printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1745 printf("%p => ", pp);
1752 mutex_list
* pp
=mlist
;
1756 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==1))
1758 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1759 v1
, init_count
, max_count
, name
, name
, mlist
);
1760 return (HANDLE
)mlist
;
1762 }while((pp
=pp
->prev
) != NULL
);
1764 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
1765 pthread_mutex_init(pm
, NULL
);
1766 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
1767 pthread_cond_init(pc
, NULL
);
1770 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1771 mlist
->next
=mlist
->prev
=NULL
;
1775 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1776 mlist
->next
->prev
=mlist
;
1777 mlist
->next
->next
=NULL
;
1779 // printf("new semaphore %p\n", mlist);
1781 mlist
->type
=1; /* Type Semaphore */
1786 mlist
->semaphore
=init_count
;
1788 strncpy(mlist
->name
, name
, 64);
1792 dbgprintf("ERROR::: CreateSemaphoreA failure\n");
1794 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1795 v1
, init_count
, max_count
, name
, name
, mlist
);
1797 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1798 v1
, init_count
, max_count
, mlist
);
1799 return (HANDLE
)mlist
;
1802 static long WINAPI
expReleaseSemaphore(long hsem
, long increment
, long* prev_count
)
1804 // The state of a semaphore object is signaled when its count
1805 // is greater than zero and nonsignaled when its count is equal to zero
1806 // Each time a waiting thread is released because of the semaphore's signaled
1807 // state, the count of the semaphore is decreased by one.
1808 mutex_list
*ml
= (mutex_list
*)hsem
;
1810 pthread_mutex_lock(ml
->pm
);
1811 if (prev_count
!= 0) *prev_count
= ml
->semaphore
;
1812 if (ml
->semaphore
== 0) pthread_cond_signal(ml
->pc
);
1813 ml
->semaphore
+= increment
;
1814 pthread_mutex_unlock(ml
->pm
);
1815 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1816 hsem
, increment
, prev_count
);
1821 static long WINAPI
expRegOpenKeyExA(long key
, const char* subkey
, long reserved
, long access
, int* newkey
)
1823 long result
=RegOpenKeyExA(key
, subkey
, reserved
, access
, newkey
);
1824 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
1825 key
, subkey
, reserved
, access
, newkey
, result
);
1826 if(newkey
)dbgprintf(" New key: 0x%x\n", *newkey
);
1829 static long WINAPI
expRegCloseKey(long key
)
1831 long result
=RegCloseKey(key
);
1832 dbgprintf("RegCloseKey(0x%x) => %d\n", key
, result
);
1835 static long WINAPI
expRegQueryValueExA(long key
, const char* value
, int* reserved
, int* type
, int* data
, int* count
)
1837 long result
=RegQueryValueExA(key
, value
, reserved
, type
, data
, count
);
1838 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
1839 " => 0x%x\n", key
, value
, reserved
, data
, count
, result
);
1840 if(data
&& count
)dbgprintf(" read %d bytes: '%s'\n", *count
, data
);
1844 //from wine source dlls/advapi32/registry.c
1845 static long WINAPI
expRegCreateKeyA(long hkey
, const char* name
, int *retkey
)
1847 dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey
,name
,retkey
);
1848 return RegCreateKeyExA( hkey
, name
, 0, NULL
,REG_OPTION_NON_VOLATILE
,
1849 KEY_ALL_ACCESS
, NULL
, retkey
, NULL
);
1852 static long WINAPI
expRegCreateKeyExA(long key
, const char* name
, long reserved
,
1853 void* classs
, long options
, long security
,
1854 void* sec_attr
, int* newkey
, int* status
)
1856 long result
=RegCreateKeyExA(key
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
);
1857 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
1858 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
1859 key
, name
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
, result
);
1860 if(!result
&& newkey
) dbgprintf(" New key: 0x%x\n", *newkey
);
1861 if(!result
&& status
) dbgprintf(" New key status: 0x%x\n", *status
);
1864 static long WINAPI
expRegSetValueExA(long key
, const char* name
, long v1
, long v2
, void* data
, long size
)
1866 long result
=RegSetValueExA(key
, name
, v1
, v2
, data
, size
);
1867 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
1868 key
, name
, v1
, v2
, data
, *(int*)data
, data
, size
, result
);
1872 static long WINAPI
expRegOpenKeyA (long hKey
, LPCSTR lpSubKey
, int* phkResult
)
1874 long result
=RegOpenKeyExA(hKey
, lpSubKey
, 0, 0, phkResult
);
1875 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
1876 hKey
, lpSubKey
, phkResult
, result
);
1877 if(!result
&& phkResult
) dbgprintf(" New key: 0x%x\n", *phkResult
);
1881 static DWORD WINAPI
expRegEnumValueA(HKEY hkey
, DWORD index
, LPSTR value
, LPDWORD val_count
,
1882 LPDWORD reserved
, LPDWORD type
, LPBYTE data
, LPDWORD count
)
1884 return RegEnumValueA(hkey
, index
, value
, val_count
,
1885 reserved
, type
, data
, count
);
1888 static DWORD WINAPI
expRegEnumKeyExA(HKEY hKey
, DWORD dwIndex
, LPSTR lpName
, LPDWORD lpcbName
,
1889 LPDWORD lpReserved
, LPSTR lpClass
, LPDWORD lpcbClass
,
1890 LPFILETIME lpftLastWriteTime
)
1892 return RegEnumKeyExA(hKey
, dwIndex
, lpName
, lpcbName
, lpReserved
, lpClass
,
1893 lpcbClass
, lpftLastWriteTime
);
1896 static long WINAPI
expQueryPerformanceCounter(long long* z
)
1899 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z
, *z
);
1904 * dummy function RegQueryInfoKeyA(), required by vss codecs
1906 static DWORD WINAPI
expRegQueryInfoKeyA( HKEY hkey
, LPSTR
class, LPDWORD class_len
, LPDWORD reserved
,
1907 LPDWORD subkeys
, LPDWORD max_subkey
, LPDWORD max_class
,
1908 LPDWORD values
, LPDWORD max_value
, LPDWORD max_data
,
1909 LPDWORD security
, FILETIME
*modif
)
1911 return ERROR_SUCCESS
;
1915 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
1917 static double linux_cpuinfo_freq()
1924 f
= fopen ("/proc/cpuinfo", "r");
1926 while (fgets(line
,sizeof(line
),f
)!=NULL
) {
1927 /* NOTE: the ':' is the only character we can rely on */
1928 if (!(value
= strchr(line
,':')))
1930 /* terminate the valuename */
1932 /* skip any leading spaces */
1933 while (*value
==' ') value
++;
1934 if ((s
=strchr(value
,'\n')))
1937 if (!strncasecmp(line
, "cpu MHz",strlen("cpu MHz"))
1938 && sscanf(value
, "%lf", &freq
) == 1) {
1949 static double solaris_kstat_freq()
1951 #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
1953 * try to extract the CPU speed from the solaris kernel's kstat data
1957 kstat_named_t
*kdata
;
1963 ksp
= kstat_lookup(kc
, "cpu_info", 0, "cpu_info0");
1965 /* kstat found and name/value pairs? */
1966 if (ksp
!= NULL
&& ksp
->ks_type
== KSTAT_TYPE_NAMED
)
1968 /* read the kstat data from the kernel */
1969 if (kstat_read(kc
, ksp
, NULL
) != -1)
1972 * lookup desired "clock_MHz" entry, check the expected
1975 kdata
= (kstat_named_t
*)kstat_data_lookup(ksp
, "clock_MHz");
1976 if (kdata
!= NULL
&& kdata
->data_type
== KSTAT_DATA_INT32
)
1977 mhz
= kdata
->value
.i32
;
1985 #endif /* HAVE_LIBKSTAT */
1986 return -1; // kstat stuff is not available, CPU freq is unknown
1990 * Measure CPU freq using the pentium's time stamp counter register (TSC)
1992 static double tsc_freq()
1994 static double ofreq
=0.0;
1998 if (ofreq
!= 0.0) return ofreq
;
1999 while(i
==time(NULL
));
2002 while(i
==time(NULL
));
2004 ofreq
= (double)(y
-x
)/1000.;
2008 static double CPU_Freq()
2012 if ((freq
= linux_cpuinfo_freq()) > 0)
2015 if ((freq
= solaris_kstat_freq()) > 0)
2021 static long WINAPI
expQueryPerformanceFrequency(long long* z
)
2023 *z
=(long long)CPU_Freq();
2024 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z
, *z
);
2027 static long WINAPI
exptimeGetTime()
2031 gettimeofday(&t
, 0);
2032 result
=1000*t
.tv_sec
+t
.tv_usec
/1000;
2033 dbgprintf("timeGetTime() => %d\n", result
);
2036 static void* WINAPI
expLocalHandle(void* v
)
2038 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v
, v
);
2042 static void* WINAPI
expGlobalHandle(void* v
)
2044 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v
, v
);
2047 static int WINAPI
expGlobalUnlock(void* v
)
2049 dbgprintf("GlobalUnlock(0x%x) => 1\n", v
);
2052 static void* WINAPI
expGlobalFree(void* v
)
2054 dbgprintf("GlobalFree(0x%x) => 0\n", v
);
2060 static void* WINAPI
expGlobalReAlloc(void* v
, int size
, int flags
)
2062 void* result
=my_realloc(v
, size
);
2063 //void* result=realloc(v, size);
2064 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v
,size
,flags
,result
);
2068 static int WINAPI
expLocalUnlock(void* v
)
2070 dbgprintf("LocalUnlock(0x%x) => 1\n", v
);
2074 static void* WINAPI
expLocalFree(void* v
)
2076 dbgprintf("LocalFree(0x%x) => 0\n", v
);
2080 static HRSRC WINAPI
expFindResourceA(HMODULE module
, char* name
, char* type
)
2084 result
=FindResourceA(module
, name
, type
);
2085 dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2086 module
, name
, HIWORD(name
) ? name
: "UNICODE", type
, HIWORD(type
) ? type
: "UNICODE", result
);
2090 static HGLOBAL WINAPI
expLoadResource(HMODULE module
, HRSRC res
)
2092 HGLOBAL result
=LoadResource(module
, res
);
2093 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module
, res
, result
);
2096 static void* WINAPI
expLockResource(long res
)
2098 void* result
=LockResource(res
);
2099 dbgprintf("LockResource(0x%x) => 0x%x\n", res
, result
);
2102 static int WINAPI
expFreeResource(long res
)
2104 int result
=FreeResource(res
);
2105 dbgprintf("FreeResource(0x%x) => %d\n", res
, result
);
2110 static int WINAPI
expCloseHandle(long v1
)
2112 dbgprintf("CloseHandle(0x%x) => 1\n", v1
);
2113 /* do not close stdin,stdout and stderr */
2120 static const char* WINAPI
expGetCommandLineA()
2122 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2123 return "c:\\aviplay.exe";
2125 static short envs
[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2126 static LPWSTR WINAPI
expGetEnvironmentStringsW()
2128 dbgprintf("GetEnvironmentStringsW() => 0\n", envs
);
2131 static void * WINAPI
expRtlZeroMemory(void *p
, size_t len
)
2133 void* result
=memset(p
,0,len
);
2134 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p
,len
,result
);
2137 static void * WINAPI
expRtlMoveMemory(void *dst
, void *src
, size_t len
)
2139 void* result
=memmove(dst
,src
,len
);
2140 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst
,src
,len
,result
);
2144 static void * WINAPI
expRtlFillMemory(void *p
, int ch
, size_t len
)
2146 void* result
=memset(p
,ch
,len
);
2147 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p
,ch
,len
,result
);
2150 static int WINAPI
expFreeEnvironmentStringsW(short* strings
)
2152 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings
);
2155 static int WINAPI
expFreeEnvironmentStringsA(char* strings
)
2157 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings
);
2161 static const char ch_envs
[]=
2162 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2163 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2164 static LPCSTR WINAPI
expGetEnvironmentStrings()
2166 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs
);
2167 return (LPCSTR
)ch_envs
;
2168 // dbgprintf("GetEnvironmentStrings() => 0\n");
2172 static int WINAPI
expGetStartupInfoA(STARTUPINFOA
*s
)
2174 dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2175 memset(s
, 0, sizeof(*s
));
2177 // s->lpReserved="Reserved";
2178 // s->lpDesktop="Desktop";
2179 // s->lpTitle="Title";
2181 // s->dwXSize=s->dwYSize=200;
2182 s
->dwFlags
=s
->wShowWindow
=1;
2183 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2184 dbgprintf(" cb=%d\n", s
->cb
);
2185 dbgprintf(" lpReserved='%s'\n", s
->lpReserved
);
2186 dbgprintf(" lpDesktop='%s'\n", s
->lpDesktop
);
2187 dbgprintf(" lpTitle='%s'\n", s
->lpTitle
);
2188 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2189 s
->dwX
, s
->dwY
, s
->dwXSize
, s
->dwYSize
);
2190 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2191 s
->dwXCountChars
, s
->dwYCountChars
, s
->dwFillAttribute
);
2192 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2193 s
->dwFlags
, s
->wShowWindow
, s
->cbReserved2
);
2194 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2195 s
->lpReserved2
, s
->hStdInput
, s
->hStdOutput
, s
->hStdError
);
2199 static int WINAPI
expGetStdHandle(int z
)
2201 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z
+0x1234);
2206 #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2207 #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2210 static int WINAPI
expGetFileType(int handle
)
2212 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle
);
2216 static int WINAPI
expGetFileAttributesA(char *filename
)
2218 dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename
);
2219 if (strstr(filename
, "QuickTime.qts"))
2220 return FILE_ATTRIBUTE_SYSTEM
;
2221 return FILE_ATTRIBUTE_NORMAL
;
2224 static int WINAPI
expSetHandleCount(int count
)
2226 dbgprintf("SetHandleCount(0x%x) => 1\n", count
);
2229 static int WINAPI
expGetACP(void)
2231 dbgprintf("GetACP() => 0\n");
2234 static int WINAPI
expGetModuleFileNameA(int module
, char* s
, int len
)
2238 //printf("File name of module %X (%s) requested\n", module, s);
2240 if (module
== 0 && len
>= 12)
2242 /* return caller program name */
2243 strcpy(s
, "aviplay.dll");
2254 strcpy(s
, "c:\\windows\\system\\");
2255 mr
=MODULE32_LookupHMODULE(module
);
2257 strcat(s
, "aviplay.dll");
2259 if(strrchr(mr
->filename
, '/')==NULL
)
2260 strcat(s
, mr
->filename
);
2262 strcat(s
, strrchr(mr
->filename
, '/')+1);
2265 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2266 module
, s
, len
, result
);
2268 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2269 module
, s
, len
, result
, s
);
2273 static int WINAPI
expSetUnhandledExceptionFilter(void* filter
)
2275 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter
);
2276 return 1;//unsupported and probably won't ever be supported
2279 static int WINAPI
expLoadLibraryA(char* name
)
2285 // we skip to the last backslash
2286 // this is effectively eliminating weird characters in
2287 // the text output windows
2289 lastbc
= strrchr(name
, '\\');
2296 name
[i
] = *lastbc
++;
2301 if(strncmp(name
, "c:\\windows\\", 11)==0) name
+= 11;
2302 if(strncmp(name
, ".\\", 2)==0) name
+= 2;
2304 dbgprintf("Entering LoadLibraryA(%s)\n", name
);
2306 // PIMJ and VIVO audio are loading kernel32.dll
2307 if (strcasecmp(name
, "kernel32.dll") == 0 || strcasecmp(name
, "kernel32") == 0)
2308 return MODULE_HANDLE_kernel32
;
2309 // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2310 /* exported -> do not return failed! */
2312 if (strcasecmp(name
, "user32.dll") == 0 || strcasecmp(name
, "user32") == 0)
2313 // return MODULE_HANDLE_kernel32;
2314 return MODULE_HANDLE_user32
;
2317 if (strcasecmp(name
, "wininet.dll") == 0 || strcasecmp(name
, "wininet") == 0)
2318 return MODULE_HANDLE_wininet
;
2319 if (strcasecmp(name
, "ddraw.dll") == 0 || strcasecmp(name
, "ddraw") == 0)
2320 return MODULE_HANDLE_ddraw
;
2321 if (strcasecmp(name
, "advapi32.dll") == 0 || strcasecmp(name
, "advapi32") == 0)
2322 return MODULE_HANDLE_advapi32
;
2325 if (strcasecmp(name
, "comdlg32.dll") == 0 || strcasecmp(name
, "comdlg32") == 0)
2326 return MODULE_HANDLE_comdlg32
;
2327 if (strcasecmp(name
, "msvcrt.dll") == 0 || strcasecmp(name
, "msvcrt") == 0)
2328 return MODULE_HANDLE_msvcrt
;
2329 if (strcasecmp(name
, "ole32.dll") == 0 || strcasecmp(name
, "ole32") == 0)
2330 return MODULE_HANDLE_ole32
;
2331 if (strcasecmp(name
, "winmm.dll") == 0 || strcasecmp(name
, "winmm") == 0)
2332 return MODULE_HANDLE_winmm
;
2334 result
=LoadLibraryA(name
);
2335 dbgprintf("Returned LoadLibraryA(0x%x='%s'), def_path=%s => 0x%x\n", name
, name
, def_path
, result
);
2340 static int WINAPI
expFreeLibrary(int module
)
2343 int result
=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2345 int result
=FreeLibrary(module
);
2347 dbgprintf("FreeLibrary(0x%x) => %d\n", module
, result
);
2351 static void* WINAPI
expGetProcAddress(HMODULE mod
, char* name
)
2355 case MODULE_HANDLE_kernel32
:
2356 result
=LookupExternalByName("kernel32.dll", name
); break;
2357 case MODULE_HANDLE_user32
:
2358 result
=LookupExternalByName("user32.dll", name
); break;
2360 case MODULE_HANDLE_wininet
:
2361 result
=LookupExternalByName("wininet.dll", name
); break;
2362 case MODULE_HANDLE_ddraw
:
2363 result
=LookupExternalByName("ddraw.dll", name
); break;
2364 case MODULE_HANDLE_advapi32
:
2365 result
=LookupExternalByName("advapi32.dll", name
); break;
2367 case MODULE_HANDLE_comdlg32
:
2368 result
=LookupExternalByName("comdlg32.dll", name
); break;
2369 case MODULE_HANDLE_msvcrt
:
2370 result
=LookupExternalByName("msvcrt.dll", name
); break;
2371 case MODULE_HANDLE_ole32
:
2372 result
=LookupExternalByName("ole32.dll", name
); break;
2373 case MODULE_HANDLE_winmm
:
2374 result
=LookupExternalByName("winmm.dll", name
); break;
2376 result
=GetProcAddress(mod
, name
);
2378 if((unsigned int)name
> 0xffff)
2379 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod
, name
, result
);
2381 dbgprintf("GetProcAddress(0x%x, '%d') => 0x%x\n", mod
, (int)name
, result
);
2385 static long WINAPI
expCreateFileMappingA(int hFile
, void* lpAttr
,
2386 long flProtect
, long dwMaxHigh
,
2387 long dwMaxLow
, const char* name
)
2389 long result
=CreateFileMappingA(hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
);
2391 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2392 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2393 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, result
);
2395 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2396 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2397 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
, name
, result
);
2401 static long WINAPI
expOpenFileMappingA(long hFile
, long hz
, const char* name
)
2403 long result
=OpenFileMappingA(hFile
, hz
, name
);
2405 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2408 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2409 hFile
, hz
, name
, name
, result
);
2413 static void* WINAPI
expMapViewOfFile(HANDLE file
, DWORD mode
, DWORD offHigh
,
2414 DWORD offLow
, DWORD size
)
2416 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2417 file
,mode
,offHigh
,offLow
,size
,(char*)file
+offLow
);
2418 return (char*)file
+offLow
;
2421 static void* WINAPI
expUnmapViewOfFile(void* view
)
2423 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view
);
2427 static void* WINAPI
expSleep(int time
)
2430 /* solaris doesn't have thread safe usleep */
2431 struct timespec tsp
;
2432 tsp
.tv_sec
= time
/ 1000000;
2433 tsp
.tv_nsec
= (time
% 1000000) * 1000;
2434 nanosleep(&tsp
, NULL
);
2438 dbgprintf("Sleep(%d) => 0\n", time
);
2442 // why does IV32 codec want to call this? I don't know ...
2443 static int WINAPI
expCreateCompatibleDC(int hdc
)
2446 //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2447 dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc
, dc
);
2451 static int WINAPI
expGetDeviceCaps(int hdc
, int unk
)
2453 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc
, unk
);
2455 #define BITSPIXEL 12
2457 if (unk
== BITSPIXEL
)
2465 static WIN_BOOL WINAPI
expDeleteDC(int hdc
)
2467 dbgprintf("DeleteDC(0x%x) => 0\n", hdc
);
2473 static WIN_BOOL WINAPI
expDeleteObject(int hdc
)
2475 dbgprintf("DeleteObject(0x%x) => 1\n", hdc
);
2476 /* FIXME - implement code here */
2480 /* btvvc32.drv wants this one */
2481 static void* WINAPI
expGetWindowDC(int hdc
)
2483 dbgprintf("GetWindowDC(%d) => 0x0\n", hdc
);
2488 static int WINAPI
expGetWindowRect(HWND win
, RECT
*r
)
2490 dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win
, r
);
2491 /* (win == 0) => desktop */
2492 r
->right
= PSEUDO_SCREEN_WIDTH
;
2494 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
2499 static int WINAPI
expMonitorFromWindow(HWND win
, int flags
)
2501 dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win
, flags
);
2505 static int WINAPI
expMonitorFromRect(RECT
*r
, int flags
)
2507 dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r
, flags
);
2511 static int WINAPI
expMonitorFromPoint(void *p
, int flags
)
2513 dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p
, flags
);
2517 static int WINAPI
expEnumDisplayMonitors(void *dc
, RECT
*r
,
2518 int WINAPI (*callback_proc
)(), void *callback_param
)
2520 dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2521 dc
, r
, callback_proc
, callback_param
);
2522 return callback_proc(0, dc
, r
, callback_param
);
2526 typedef struct tagMONITORINFO
{
2531 } MONITORINFO
, *LPMONITORINFO
;
2534 #define CCHDEVICENAME 8
2535 typedef struct tagMONITORINFOEX
{
2540 TCHAR szDevice
[CCHDEVICENAME
];
2541 } MONITORINFOEX
, *LPMONITORINFOEX
;
2543 static int WINAPI
expGetMonitorInfoA(void *mon
, LPMONITORINFO lpmi
)
2545 dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon
, lpmi
);
2547 lpmi
->rcMonitor
.right
= lpmi
->rcWork
.right
= PSEUDO_SCREEN_WIDTH
;
2548 lpmi
->rcMonitor
.left
= lpmi
->rcWork
.left
= 0;
2549 lpmi
->rcMonitor
.bottom
= lpmi
->rcWork
.bottom
= PSEUDO_SCREEN_HEIGHT
;
2550 lpmi
->rcMonitor
.top
= lpmi
->rcWork
.top
= 0;
2552 lpmi
->dwFlags
= 1; /* primary monitor */
2554 if (lpmi
->cbSize
== sizeof(MONITORINFOEX
))
2556 LPMONITORINFOEX lpmiex
= (LPMONITORINFOEX
)lpmi
;
2557 dbgprintf("MONITORINFOEX!\n");
2558 strncpy(lpmiex
->szDevice
, "Monitor1", CCHDEVICENAME
);
2564 static int WINAPI
expEnumDisplayDevicesA(const char *device
, int devnum
,
2565 void *dispdev
, int flags
)
2567 dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2568 device
, device
, devnum
, dispdev
, flags
);
2572 static int WINAPI
expIsWindowVisible(HWND win
)
2574 dbgprintf("IsWindowVisible(0x%x) => 1\n", win
);
2578 static HWND WINAPI
expGetActiveWindow(void)
2580 dbgprintf("GetActiveWindow() => 0\n");
2584 static int WINAPI
expGetClassNameA(HWND win
, LPTSTR classname
, int maxcount
)
2586 strncat(classname
, "QuickTime", maxcount
);
2587 dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2588 win
, classname
, maxcount
, strlen(classname
));
2589 return strlen(classname
);
2592 #define LPWNDCLASS void *
2593 static int WINAPI
expGetClassInfoA(HINSTANCE inst
, LPCSTR classname
, LPWNDCLASS wndclass
)
2595 dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst
,
2596 classname
, classname
, wndclass
);
2600 static int WINAPI
expGetWindowLongA(HWND win
, int index
)
2602 dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win
, index
);
2606 static int WINAPI
expGetObjectA(HGDIOBJ hobj
, int objsize
, LPVOID obj
)
2608 dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj
, objsize
, obj
, objsize
);
2612 static int WINAPI
expCreateRectRgn(int x
, int y
, int width
, int height
)
2614 dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x
, y
, width
, height
);
2618 static int WINAPI
expEnumWindows(int (*callback_func
)(), void *callback_param
)
2621 dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func
, callback_param
);
2622 i
= callback_func(0, callback_param
);
2623 i2
= callback_func(1, callback_param
);
2627 static int WINAPI
expGetWindowThreadProcessId(HWND win
, int *pid_data
)
2629 int tid
= pthread_self();
2630 dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2631 win
, pid_data
, tid
);
2633 *(int*)pid_data
= tid
;
2637 //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2638 // INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2640 static HWND WINAPI
expCreateWindowExA(int exstyle
, const char *classname
,
2641 const char *winname
, int style
, int x
, int y
, int w
, int h
,
2642 HWND parent
, HMENU menu
, HINSTANCE inst
, LPVOID param
)
2644 printf("CreateWindowEx() called\n");
2645 dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2646 exstyle
, classname
, classname
, winname
, winname
, style
, x
, y
, w
, h
,
2647 parent
, menu
, inst
, param
);
2648 printf("CreateWindowEx() called okey\n");
2652 static int WINAPI
expwaveOutGetNumDevs(void)
2654 dbgprintf("waveOutGetNumDevs() => 0\n");
2660 * Returns the number of milliseconds, modulo 2^32, since the start
2661 * of the wineserver.
2663 static int WINAPI
expGetTickCount(void)
2665 static int tcstart
= 0;
2668 gettimeofday( &t
, NULL
);
2669 tc
= ((t
.tv_sec
* 1000) + (t
.tv_usec
/ 1000)) - tcstart
;
2675 dbgprintf("GetTickCount() => %d\n", tc
);
2679 static int WINAPI
expCreateFontA(void)
2681 dbgprintf("CreateFontA() => 0x0\n");
2685 /* tried to get pvmjpg work in a different way - no success */
2686 static int WINAPI
expDrawTextA(int hDC
, char* lpString
, int nCount
,
2687 LPRECT lpRect
, unsigned int uFormat
)
2689 dbgprintf("expDrawTextA(%p,...) => 8\n", hDC
);
2693 static int WINAPI
expGetPrivateProfileIntA(const char* appname
,
2694 const char* keyname
,
2696 const char* filename
)
2704 if(!(appname
&& keyname
&& filename
) )
2706 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, default_value
);
2707 return default_value
;
2709 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2710 strcpy(fullname
, "Software\\IniFileMapping\\");
2711 strcat(fullname
, appname
);
2712 strcat(fullname
, "\\");
2713 strcat(fullname
, keyname
);
2714 strcat(fullname
, "\\");
2715 strcat(fullname
, filename
);
2716 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)buffer
, &size
);
2717 if((size
>=0)&&(size
<256))
2719 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2722 result
=default_value
;
2724 result
=atoi(buffer
);
2725 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, result
);
2728 static int WINAPI
expGetProfileIntA(const char* appname
,
2729 const char* keyname
,
2732 dbgprintf("GetProfileIntA -> ");
2733 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, "default");
2736 static int WINAPI
expGetPrivateProfileStringA(const char* appname
,
2737 const char* keyname
,
2738 const char* def_val
,
2739 char* dest
, unsigned int len
,
2740 const char* filename
)
2745 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname
, keyname
, def_val
, dest
, len
, filename
);
2746 if(!(appname
&& keyname
&& filename
) ) return 0;
2747 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2748 strcpy(fullname
, "Software\\IniFileMapping\\");
2749 strcat(fullname
, appname
);
2750 strcat(fullname
, "\\");
2751 strcat(fullname
, keyname
);
2752 strcat(fullname
, "\\");
2753 strcat(fullname
, filename
);
2755 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)dest
, &size
);
2759 strncpy(dest
, def_val
, size
);
2760 if (strlen(def_val
)< size
) size
= strlen(def_val
);
2762 dbgprintf(" => %d ( '%s' )\n", size
, dest
);
2765 static int WINAPI
expWritePrivateProfileStringA(const char* appname
,
2766 const char* keyname
,
2768 const char* filename
)
2771 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname
, keyname
, string
, filename
);
2772 if(!(appname
&& keyname
&& filename
) )
2774 dbgprintf(" => -1\n");
2777 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2778 strcpy(fullname
, "Software\\IniFileMapping\\");
2779 strcat(fullname
, appname
);
2780 strcat(fullname
, "\\");
2781 strcat(fullname
, keyname
);
2782 strcat(fullname
, "\\");
2783 strcat(fullname
, filename
);
2784 RegSetValueExA(HKEY_LOCAL_MACHINE
, fullname
, 0, REG_SZ
, (int*)string
, strlen(string
));
2785 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
2786 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
2788 dbgprintf(" => 0\n");
2792 unsigned int GetPrivateProfileIntA_(const char* appname
, const char* keyname
, INT default_value
, const char* filename
)
2794 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, filename
);
2796 int GetPrivateProfileStringA_(const char* appname
, const char* keyname
,
2797 const char* def_val
, char* dest
, unsigned int len
, const char* filename
)
2799 return expGetPrivateProfileStringA(appname
, keyname
, def_val
, dest
, len
, filename
);
2801 int WritePrivateProfileStringA_(const char* appname
, const char* keyname
,
2802 const char* string
, const char* filename
)
2804 return expWritePrivateProfileStringA(appname
, keyname
, string
, filename
);
2809 static int WINAPI
expDefDriverProc(int private, int id
, int msg
, int arg1
, int arg2
)
2811 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", private, id
, msg
, arg1
, arg2
);
2815 static int WINAPI
expSizeofResource(int v1
, int v2
)
2817 int result
=SizeofResource(v1
, v2
);
2818 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1
, v2
, result
);
2822 static int WINAPI
expGetLastError()
2824 int result
=GetLastError();
2825 dbgprintf("GetLastError() => 0x%x\n", result
);
2829 static void WINAPI
expSetLastError(int error
)
2831 dbgprintf("SetLastError(0x%x)\n", error
);
2832 SetLastError(error
);
2835 static int WINAPI
expStringFromGUID2(GUID
* guid
, char* str
, int cbMax
)
2837 int result
=snprintf(str
, cbMax
, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
2838 guid
->f1
, guid
->f2
, guid
->f3
,
2839 (unsigned char)guid
->f4
[0], (unsigned char)guid
->f4
[1],
2840 (unsigned char)guid
->f4
[2], (unsigned char)guid
->f4
[3],
2841 (unsigned char)guid
->f4
[4], (unsigned char)guid
->f4
[5],
2842 (unsigned char)guid
->f4
[6], (unsigned char)guid
->f4
[7]);
2843 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid
, str
, str
, cbMax
, result
);
2848 static int WINAPI
expGetFileVersionInfoSizeA(const char* name
, int* lpHandle
)
2850 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name
, name
, lpHandle
);
2854 static int WINAPI
expIsBadStringPtrW(const short* string
, int nchars
)
2857 if(string
==0)result
=1; else result
=0;
2858 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string
, nchars
, result
);
2859 if(string
)wch_print(string
);
2862 static int WINAPI
expIsBadStringPtrA(const char* string
, int nchars
)
2864 return expIsBadStringPtrW((const short*)string
, nchars
);
2866 static long WINAPI
expInterlockedExchangeAdd( long* dest
, long incr
)
2871 "lock; xaddl %0,(%1)"
2873 : "r" (dest
), "0" (incr
)
2879 static long WINAPI
expInterlockedCompareExchange( unsigned long* dest
, unsigned long exchange
, unsigned long comperand
)
2881 unsigned long retval
= *dest
;
2882 if(*dest
== comperand
)
2887 static long WINAPI
expInterlockedIncrement( long* dest
)
2889 long result
=expInterlockedExchangeAdd( dest
, 1 ) + 1;
2890 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
2893 static long WINAPI
expInterlockedDecrement( long* dest
)
2895 long result
=expInterlockedExchangeAdd( dest
, -1 ) - 1;
2896 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
2900 static void WINAPI
expOutputDebugStringA( const char* string
)
2902 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string
);
2903 fprintf(stderr
, "DEBUG: %s\n", string
);
2906 static int WINAPI
expGetDC(int hwnd
)
2908 dbgprintf("GetDC(0x%x) => 1\n", hwnd
);
2912 static int WINAPI
expReleaseDC(int hwnd
, int hdc
)
2914 dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd
, hdc
);
2918 static int WINAPI
expGetDesktopWindow()
2920 dbgprintf("GetDesktopWindow() => 0\n");
2924 static int cursor
[100];
2926 static int WINAPI
expLoadCursorA(int handle
,LPCSTR name
)
2928 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle
, name
, (int)&cursor
[0]);
2929 return (int)&cursor
[0];
2931 static int WINAPI
expSetCursor(void *cursor
)
2933 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor
, cursor
);
2936 static int WINAPI
expGetCursorPos(void *cursor
)
2938 dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor
, cursor
);
2942 static int show_cursor
= 0;
2943 static int WINAPI
expShowCursor(int show
)
2945 dbgprintf("ShowCursor(%d) => %d\n", show
, show
);
2953 static int WINAPI
expRegisterWindowMessageA(char *message
)
2955 dbgprintf("RegisterWindowMessageA(%s)\n", message
);
2958 static int WINAPI
expGetProcessVersion(int pid
)
2960 dbgprintf("GetProcessVersion(%d)\n", pid
);
2963 static int WINAPI
expGetCurrentThread(void)
2966 dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
2969 static int WINAPI
expGetOEMCP(void)
2971 dbgprintf("GetOEMCP()\n");
2974 static int WINAPI
expGetCPInfo(int cp
,void *info
)
2976 dbgprintf("GetCPInfo()\n");
2980 #define SM_CXSCREEN 0
2981 #define SM_CYSCREEN 1
2982 #define SM_XVIRTUALSCREEN 76
2983 #define SM_YVIRTUALSCREEN 77
2984 #define SM_CXVIRTUALSCREEN 78
2985 #define SM_CYVIRTUALSCREEN 79
2986 #define SM_CMONITORS 80
2988 static int WINAPI
expGetSystemMetrics(int index
)
2990 dbgprintf("GetSystemMetrics(%d)\n", index
);
2994 case SM_XVIRTUALSCREEN
:
2995 case SM_YVIRTUALSCREEN
:
2998 case SM_CXVIRTUALSCREEN
:
2999 return PSEUDO_SCREEN_WIDTH
;
3001 case SM_CYVIRTUALSCREEN
:
3002 return PSEUDO_SCREEN_HEIGHT
;
3009 static int WINAPI
expGetSysColor(int index
)
3011 dbgprintf("GetSysColor(%d) => 1\n", index
);
3014 static int WINAPI
expGetSysColorBrush(int index
)
3016 dbgprintf("GetSysColorBrush(%d)\n", index
);
3022 static int WINAPI
expGetSystemPaletteEntries(int hdc
, int iStartIndex
, int nEntries
, void* lppe
)
3024 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3025 hdc
, iStartIndex
, nEntries
, lppe
);
3030 typedef struct TIME_ZONE_INFORMATION {
3032 char StandardName[32];
3033 SYSTEMTIME StandardDate;
3035 char DaylightName[32];
3036 SYSTEMTIME DaylightDate;
3038 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3041 static int WINAPI
expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation
)
3043 const short name
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3044 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3045 const short pname
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3046 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3047 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3048 memset(lpTimeZoneInformation
, 0, sizeof(TIME_ZONE_INFORMATION
));
3049 lpTimeZoneInformation
->Bias
=360;//GMT-6
3050 memcpy(lpTimeZoneInformation
->StandardName
, name
, sizeof(name
));
3051 lpTimeZoneInformation
->StandardDate
.wMonth
=10;
3052 lpTimeZoneInformation
->StandardDate
.wDay
=5;
3053 lpTimeZoneInformation
->StandardDate
.wHour
=2;
3054 lpTimeZoneInformation
->StandardBias
=0;
3055 memcpy(lpTimeZoneInformation
->DaylightName
, pname
, sizeof(pname
));
3056 lpTimeZoneInformation
->DaylightDate
.wMonth
=4;
3057 lpTimeZoneInformation
->DaylightDate
.wDay
=1;
3058 lpTimeZoneInformation
->DaylightDate
.wHour
=2;
3059 lpTimeZoneInformation
->DaylightBias
=-60;
3060 return TIME_ZONE_ID_STANDARD
;
3063 static void WINAPI
expGetLocalTime(SYSTEMTIME
* systime
)
3066 struct tm
*local_tm
;
3069 dbgprintf("GetLocalTime(0x%x)\n");
3070 gettimeofday(&tv
, NULL
);
3071 local_time
=tv
.tv_sec
;
3072 local_tm
=localtime(&local_time
);
3074 systime
->wYear
= local_tm
->tm_year
+ 1900;
3075 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3076 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3077 systime
->wDay
= local_tm
->tm_mday
;
3078 systime
->wHour
= local_tm
->tm_hour
;
3079 systime
->wMinute
= local_tm
->tm_min
;
3080 systime
->wSecond
= local_tm
->tm_sec
;
3081 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3082 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3083 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3084 " Milliseconds: %d\n",
3085 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3086 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3089 static int WINAPI
expGetSystemTime(SYSTEMTIME
* systime
)
3092 struct tm
*local_tm
;
3095 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3096 gettimeofday(&tv
, NULL
);
3097 local_time
=tv
.tv_sec
;
3098 local_tm
=gmtime(&local_time
);
3100 systime
->wYear
= local_tm
->tm_year
+ 1900;
3101 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3102 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3103 systime
->wDay
= local_tm
->tm_mday
;
3104 systime
->wHour
= local_tm
->tm_hour
;
3105 systime
->wMinute
= local_tm
->tm_min
;
3106 systime
->wSecond
= local_tm
->tm_sec
;
3107 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3108 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3109 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3110 " Milliseconds: %d\n",
3111 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3112 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3116 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3117 static void WINAPI
expGetSystemTimeAsFileTime(FILETIME
* systime
)
3120 unsigned long long secs
;
3122 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3123 gettimeofday(&tv
, NULL
);
3124 secs
= (tv
.tv_sec
+ SECS_1601_TO_1970
) * 10000000;
3125 secs
+= tv
.tv_usec
* 10;
3126 systime
->dwLowDateTime
= secs
& 0xffffffff;
3127 systime
->dwHighDateTime
= (secs
>> 32);
3130 static int WINAPI
expGetEnvironmentVariableA(const char* name
, char* field
, int size
)
3133 // printf("%s %x %x\n", name, field, size);
3134 if(field
)field
[0]=0;
3137 if (p) strncpy(field,p,size);
3139 if (strcmp(name
,"__MSVCRT_HEAP_SELECT")==0)
3140 strcpy(field
,"__GLOBAL_HEAP_SELECTED,1");
3141 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name
, name
, field
, size
, strlen(field
));
3142 return strlen(field
);
3145 static int WINAPI
expSetEnvironmentVariableA(const char *name
, const char *value
)
3147 dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name
, value
);
3151 static void* WINAPI
expCoTaskMemAlloc(ULONG cb
)
3153 return my_mreq(cb
, 0);
3155 static void WINAPI
expCoTaskMemFree(void* cb
)
3163 void* CoTaskMemAlloc(unsigned long cb
)
3165 return expCoTaskMemAlloc(cb
);
3167 void CoTaskMemFree(void* cb
)
3169 expCoTaskMemFree(cb
);
3172 struct COM_OBJECT_INFO
3175 long (*GetClassObject
) (GUID
* clsid
, const GUID
* iid
, void** ppv
);
3178 static struct COM_OBJECT_INFO
* com_object_table
=0;
3179 static int com_object_size
=0;
3180 int RegisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3184 com_object_table
=realloc(com_object_table
, sizeof(struct COM_OBJECT_INFO
)*(++com_object_size
));
3185 com_object_table
[com_object_size
-1].clsid
=*clsid
;
3186 com_object_table
[com_object_size
-1].GetClassObject
=gcs
;
3190 int UnregisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3197 if (com_object_table
== 0)
3198 printf("Warning: UnregisterComClass() called without any registered class\n");
3199 while (i
< com_object_size
)
3203 memcpy(&com_object_table
[i
- 1].clsid
,
3204 &com_object_table
[i
].clsid
, sizeof(GUID
));
3205 com_object_table
[i
- 1].GetClassObject
=
3206 com_object_table
[i
].GetClassObject
;
3208 else if (memcmp(&com_object_table
[i
].clsid
, clsid
, sizeof(GUID
)) == 0
3209 && com_object_table
[i
].GetClassObject
== gcs
)
3217 if (--com_object_size
== 0)
3219 free(com_object_table
);
3220 com_object_table
= 0;
3227 const GUID IID_IUnknown
=
3229 0x00000000, 0x0000, 0x0000,
3230 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3232 const GUID IID_IClassFactory
=
3234 0x00000001, 0x0000, 0x0000,
3235 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3238 static long WINAPI
expCoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3239 long dwClsContext
, const GUID
* riid
, void** ppv
)
3242 struct COM_OBJECT_INFO
* ci
=0;
3243 for(i
=0; i
<com_object_size
; i
++)
3244 if(!memcmp(rclsid
, &com_object_table
[i
].clsid
, sizeof(GUID
)))
3245 ci
=&com_object_table
[i
];
3246 if(!ci
)return REGDB_E_CLASSNOTREG
;
3247 // in 'real' world we should mess with IClassFactory here
3248 i
=ci
->GetClassObject(rclsid
, riid
, ppv
);
3252 long CoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3253 long dwClsContext
, const GUID
* riid
, void** ppv
)
3255 return expCoCreateInstance(rclsid
, pUnkOuter
, dwClsContext
, riid
, ppv
);
3258 static int WINAPI
expIsRectEmpty(CONST RECT
*lprc
)
3265 w
= lprc
->right
- lprc
->left
;
3266 h
= lprc
->bottom
- lprc
->top
;
3267 if (w
<= 0 || h
<= 0)
3273 dbgprintf("IsRectEmpty(%p) => %s\n", lprc
, (r
) ? "TRUE" : "FALSE");
3274 //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3275 // return 0; // wmv9?
3279 static int _adjust_fdiv
=0; //what's this? - used to adjust division
3280 static int _winver
= 0x510; // windows version
3285 static unsigned int WINAPI
expGetTempPathA(unsigned int len
, char* path
)
3287 dbgprintf("GetTempPathA(%d, 0x%x)", len
, path
);
3290 dbgprintf(" => 0\n");
3293 strcpy(path
, "/tmp");
3294 dbgprintf(" => 5 ( '/tmp' )\n");
3301 DWORD dwFileAttributes;
3302 FILETIME ftCreationTime;
3303 FILETIME ftLastAccessTime;
3304 FILETIME ftLastWriteTime;
3305 DWORD nFileSizeHigh;
3309 CHAR cFileName[260];
3310 CHAR cAlternateFileName[14];
3311 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3314 static DIR* qtx_dir
=NULL
;
3316 static WIN_BOOL WINAPI
expFindNextFileA(HANDLE h
,LPWIN32_FIND_DATAA lpfd
)
3319 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h
, lpfd
);
3320 if(h
==FILE_HANDLE_quicktimeqtx
){
3322 if(!qtx_dir
) return 0;
3323 while((d
=readdir(qtx_dir
))){
3324 char* x
=strrchr(d
->d_name
,'.');
3326 if(strcmp(x
,".qtx")) continue;
3327 strcpy(lpfd
->cFileName
,d
->d_name
);
3328 // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3329 strcpy(lpfd
->cAlternateFileName
,"foobar.qtx");
3330 dbgprintf("### FindNext: %s\n",lpfd
->cFileName
);
3333 closedir(qtx_dir
); qtx_dir
=NULL
;
3340 static HANDLE WINAPI
expFindFirstFileA(LPCSTR s
, LPWIN32_FIND_DATAA lpfd
)
3342 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s
, s
, lpfd
);
3343 // printf("\n### FindFirstFileA('%s')...\n",s);
3345 if(strstr(s
, "quicktime\\*.QTX")){
3346 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s
, s
, lpfd
);
3347 dbgprintf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",def_path
);
3348 qtx_dir
=opendir(def_path
);
3349 if(!qtx_dir
) return (HANDLE
)-1;
3350 memset(lpfd
,0,sizeof(*lpfd
));
3351 if(expFindNextFileA(FILE_HANDLE_quicktimeqtx
,lpfd
))
3352 return FILE_HANDLE_quicktimeqtx
;
3353 printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",def_path
);
3357 if(strstr(s
, "QuickTime.qts")){
3358 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s
, s
, lpfd
);
3359 // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3360 // return (HANDLE)-1;
3361 strcpy(lpfd
->cFileName
, "QuickTime.qts");
3362 strcpy(lpfd
->cAlternateFileName
, "QuickT~1.qts");
3363 return FILE_HANDLE_quicktimeqts
;
3367 if(strstr(s
, "*.vwp")){
3368 // hack for VoxWare codec plugins:
3369 strcpy(lpfd
->cFileName
, "msms001.vwp");
3370 strcpy(lpfd
->cAlternateFileName
, "msms001.vwp");
3373 // return 'file not found'
3377 static WIN_BOOL WINAPI
expFindClose(HANDLE h
)
3379 dbgprintf("FindClose(0x%x) => 0\n", h
);
3381 // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3382 // closedir(qtx_dir);
3388 static UINT WINAPI
expSetErrorMode(UINT i
)
3390 dbgprintf("SetErrorMode(%d) => 0\n", i
);
3393 static UINT WINAPI
expGetWindowsDirectoryA(LPSTR s
,UINT c
)
3395 char windir
[]="c:\\windows";
3397 strncpy(s
, windir
, c
);
3398 result
=1+((c
<strlen(windir
))?c
:strlen(windir
));
3399 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3403 static UINT WINAPI
expGetCurrentDirectoryA(UINT c
, LPSTR s
)
3405 char curdir
[]="c:\\";
3407 strncpy(s
, curdir
, c
);
3408 result
=1+((c
<strlen(curdir
))?c
:strlen(curdir
));
3409 dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3413 static int WINAPI
expSetCurrentDirectoryA(const char *pathname
)
3415 dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname
, pathname
);
3417 if (strrchr(pathname
, '\\'))
3418 chdir(strcat(strrchr(pathname
, '\\')+1, '/'));
3425 static int WINAPI
expCreateDirectoryA(const char *pathname
, void *sa
)
3427 dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3428 pathname
, pathname
, sa
);
3430 p
= strrchr(pathname
, '\\')+1;
3431 strcpy(&buf
[0], p
); /* should be strncpy */
3438 if (strrchr(pathname
, '\\'))
3439 mkdir(strcat(strrchr(pathname
, '\\')+1, '/'), 666);
3441 mkdir(pathname
, 666);
3448 static WIN_BOOL WINAPI
expDeleteFileA(LPCSTR s
)
3450 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s
, s
);
3453 static WIN_BOOL WINAPI
expFileTimeToLocalFileTime(const FILETIME
* cpf
, LPFILETIME pf
)
3455 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf
, pf
);
3459 static UINT WINAPI
expGetTempFileNameA(LPCSTR cs1
,LPCSTR cs2
,UINT i
,LPSTR ps
)
3461 char mask
[16]="/tmp/AP_XXXXXX";
3463 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1
, cs1
, cs2
, cs2
, i
, ps
);
3466 dbgprintf(" => -1\n");
3469 result
=mkstemp(mask
);
3470 sprintf(ps
, "AP%d", result
);
3471 dbgprintf(" => %d\n", strlen(ps
));
3475 // This func might need proper implementation if we want AngelPotion codec.
3476 // They try to open APmpeg4v1.apl with it.
3477 // DLL will close opened file with CloseHandle().
3479 static HANDLE WINAPI
expCreateFileA(LPCSTR cs1
,DWORD i1
,DWORD i2
,
3480 LPSECURITY_ATTRIBUTES p1
, DWORD i3
,DWORD i4
,HANDLE i5
)
3482 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1
, cs1
, i1
,
3483 i2
, p1
, i3
, i4
, i5
);
3484 if((!cs1
) || (strlen(cs1
)<2))return -1;
3487 if(strstr(cs1
, "QuickTime.qts"))
3490 char* tmp
=malloc(strlen(def_path
)+50);
3491 strcpy(tmp
, def_path
);
3493 strcat(tmp
, "QuickTime.qts");
3494 result
=open(tmp
, O_RDONLY
);
3498 if(strstr(cs1
, ".qtx"))
3501 char* tmp
=malloc(strlen(def_path
)+250);
3502 char* x
=strrchr(cs1
,'\\');
3503 sprintf(tmp
,"%s/%s",def_path
,x
?(x
+1):cs1
);
3504 // printf("### Open: %s -> %s\n",cs1,tmp);
3505 result
=open(tmp
, O_RDONLY
);
3511 if(strncmp(cs1
, "AP", 2) == 0)
3514 char* tmp
=malloc(strlen(def_path
)+50);
3515 strcpy(tmp
, def_path
);
3517 strcat(tmp
, "APmpg4v1.apl");
3518 result
=open(tmp
, O_RDONLY
);
3522 if (strstr(cs1
, "vp3"))
3526 char* tmp
=malloc(20 + strlen(cs1
));
3527 strcpy(tmp
, "/tmp/");
3532 if (tmp
[r
] == ':' || tmp
[r
] == '\\')
3536 if (GENERIC_READ
& i1
)
3538 else if (GENERIC_WRITE
& i1
)
3541 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp
, r
, flg
);
3548 // Needed by wnvplay1.dll
3549 if (strstr(cs1
, "WINNOV.bmp"))
3552 r
=open("/dev/null", O_RDONLY
);
3557 /* we need this for some virtualdub filters */
3561 if (GENERIC_READ
& i1
)
3563 else if (GENERIC_WRITE
& i1
)
3566 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1
, r
, flg
);
3575 static UINT WINAPI
expGetSystemDirectoryA(
3576 char* lpBuffer
, // address of buffer for system directory
3577 UINT uSize
// size of directory buffer
3579 dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer
,uSize
);
3580 if(!lpBuffer
) strcpy(lpBuffer
,".");
3584 static char sysdir[]=".";
3585 static LPCSTR WINAPI expGetSystemDirectoryA()
3587 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3591 static DWORD WINAPI expGetFullPathNameA
3594 DWORD nBufferLength
,
3598 if(!lpFileName
) return 0;
3599 dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName
,nBufferLength
,
3600 lpBuffer
, lpFilePart
);
3603 strcpy(lpFilePart
, "Quick123.qts");
3605 strcpy(lpFilePart
, lpFileName
);
3608 if (strrchr(lpFileName
, '\\'))
3609 lpFilePart
= strrchr(lpFileName
, '\\');
3611 lpFilePart
= (LPTSTR
)lpFileName
;
3613 strcpy(lpBuffer
, lpFileName
);
3614 // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3615 return strlen(lpBuffer
);
3618 static DWORD WINAPI expGetShortPathNameA
3624 if(!longpath
) return 0;
3625 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath
,shortpath
,shortlen
);
3626 strcpy(shortpath
,longpath
);
3627 return strlen(shortpath
);
3630 static WIN_BOOL WINAPI
expReadFile(HANDLE h
,LPVOID pv
,DWORD size
,LPDWORD rd
,LPOVERLAPPED unused
)
3633 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, rd
);
3634 result
=read(h
, pv
, size
);
3636 if(!result
)return 0;
3640 static WIN_BOOL WINAPI
expWriteFile(HANDLE h
,LPCVOID pv
,DWORD size
,LPDWORD wr
,LPOVERLAPPED unused
)
3643 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, wr
);
3645 result
=write(h
, pv
, size
);
3647 if(!result
)return 0;
3650 static DWORD WINAPI
expSetFilePointer(HANDLE h
, LONG val
, LPLONG ext
, DWORD whence
)
3653 dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h
, val
, ext
, ext
? *ext
: NULL
, whence
);
3654 //why would DLL want temporary file with >2Gb size?
3667 if (val
== 0 && ext
!= 0)
3670 return lseek(h
, val
, wh
);
3673 static HDRVR WINAPI
expOpenDriverA(LPCSTR szDriverName
, LPCSTR szSectionName
,
3676 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3679 static HDRVR WINAPI
expOpenDriver(LPCSTR szDriverName
, LPCSTR szSectionName
,
3682 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3687 static WIN_BOOL WINAPI
expGetProcessAffinityMask(HANDLE hProcess
,
3688 LPDWORD lpProcessAffinityMask
,
3689 LPDWORD lpSystemAffinityMask
)
3691 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3692 hProcess
, lpProcessAffinityMask
, lpSystemAffinityMask
);
3693 if(lpProcessAffinityMask
)*lpProcessAffinityMask
=1;
3694 if(lpSystemAffinityMask
)*lpSystemAffinityMask
=1;
3698 // Fake implementation: does nothing, but does it right :)
3699 static WIN_BOOL WINAPI
expSetProcessAffinityMask(HANDLE hProcess
,
3700 LPDWORD dwProcessAffinityMask
)
3702 dbgprintf("SetProcessAffinityMask(0x%x, 0x%x) => 1\n",
3703 hProcess
, dwProcessAffinityMask
);
3708 static int WINAPI
expMulDiv(int nNumber
, int nNumerator
, int nDenominator
)
3710 static const long long max_int
=0x7FFFFFFFLL
;
3711 static const long long min_int
=-0x80000000LL
;
3712 long long tmp
=(long long)nNumber
*(long long)nNumerator
;
3713 dbgprintf("expMulDiv %d * %d / %d\n", nNumber
, nNumerator
, nDenominator
);
3714 if(!nDenominator
)return 1;
3716 if(tmp
<min_int
) return 1;
3717 if(tmp
>max_int
) return 1;
3721 static LONG WINAPI
explstrcmpiA(const char* str1
, const char* str2
)
3723 LONG result
=strcasecmp(str1
, str2
);
3724 dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
3728 static LONG WINAPI
explstrlenA(const char* str1
)
3730 LONG result
=strlen(str1
);
3731 dbgprintf("strlen(0x%x='%.50s') => %d\n", str1
, str1
, result
);
3735 static LONG WINAPI
explstrcpyA(char* str1
, const char* str2
)
3737 int result
= (int) strcpy(str1
, str2
);
3738 dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1
, str2
, str2
, result
);
3741 static LONG WINAPI
explstrcpynA(char* str1
, const char* str2
,int len
)
3744 if (strlen(str2
)>len
)
3745 result
= (int) strncpy(str1
, str2
,len
);
3747 result
= (int) strcpy(str1
,str2
);
3748 dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1
, str2
, str2
,len
, strlen(str2
),result
);
3751 static LONG WINAPI
explstrcatA(char* str1
, const char* str2
)
3753 int result
= (int) strcat(str1
, str2
);
3754 dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1
, str2
, str2
, result
);
3759 static LONG WINAPI
expInterlockedExchange(long *dest
, long l
)
3761 long retval
= *dest
;
3766 static void WINAPI
expInitCommonControls(void)
3768 dbgprintf("InitCommonControls called!\n");
3773 /* needed by QuickTime.qts */
3774 static HWND WINAPI
expCreateUpDownControl (DWORD style
, INT x
, INT y
, INT cx
, INT cy
,
3775 HWND parent
, INT id
, HINSTANCE inst
,
3776 HWND buddy
, INT maxVal
, INT minVal
, INT curVal
)
3778 dbgprintf("CreateUpDownControl(...)\n");
3783 /* alex: implement this call! needed for 3ivx */
3784 static HRESULT WINAPI
expCoCreateFreeThreadedMarshaler(void *pUnkOuter
, void **ppUnkInner
)
3786 dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
3787 pUnkOuter
, ppUnkInner
);
3789 return ERROR_CALL_NOT_IMPLEMENTED
;
3793 static int WINAPI
expDuplicateHandle(HANDLE hSourceProcessHandle
, // handle to source process
3794 HANDLE hSourceHandle
, // handle to duplicate
3795 HANDLE hTargetProcessHandle
, // handle to target process
3796 HANDLE
* lpTargetHandle
, // duplicate handle
3797 DWORD dwDesiredAccess
, // requested access
3798 int bInheritHandle
, // handle inheritance option
3799 DWORD dwOptions
// optional actions
3802 dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
3803 hSourceProcessHandle
, hSourceHandle
, hTargetProcessHandle
,
3804 lpTargetHandle
, dwDesiredAccess
, bInheritHandle
, dwOptions
);
3805 *lpTargetHandle
= hSourceHandle
;
3809 static HRESULT WINAPI
expCoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
3811 dbgprintf("CoInitializeEx(%p, %d) called\n", lpReserved
, dwCoInit
);
3815 // required by PIM1 codec (used by win98 PCTV Studio capture sw)
3816 static HRESULT WINAPI
expCoInitialize(
3817 LPVOID lpReserved
/* [in] pointer to win32 malloc interface
3818 (obsolete, should be NULL) */
3822 * Just delegate to the newer method.
3824 return expCoInitializeEx(lpReserved
, COINIT_APARTMENTTHREADED
);
3827 static void WINAPI
expCoUninitialize(void)
3829 dbgprintf("CoUninitialize() called\n");
3832 /* allow static linking */
3833 HRESULT WINAPI
CoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
3835 return expCoInitializeEx(lpReserved
, dwCoInit
);
3837 HRESULT WINAPI
CoInitialize(LPVOID lpReserved
)
3839 return expCoInitialize(lpReserved
);
3841 void WINAPI
CoUninitialize(void)
3843 return expCoUninitialize();
3846 static DWORD WINAPI expSetThreadAffinityMask
3849 DWORD dwThreadAffinityMask
3855 * no WINAPI functions - CDECL
3857 static void* expmalloc(int size
)
3860 // return malloc(size);
3861 void* result
=my_mreq(size
,0);
3862 dbgprintf("malloc(0x%x) => 0x%x\n", size
,result
);
3864 printf("WARNING: malloc() failed\n");
3867 static void expfree(void* mem
)
3869 // return free(mem);
3870 dbgprintf("free(%p)\n", mem
);
3873 /* needed by atrac3.acm */
3874 static void *expcalloc(int num
, int size
)
3876 void* result
=my_mreq(num
*size
,1);
3877 dbgprintf("calloc(%d,%d) => %p\n", num
,size
,result
);
3879 printf("WARNING: calloc() failed\n");
3882 static void* expnew(int size
)
3884 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
3885 // printf("%08x %08x %08x %08x\n",
3886 // size, *(1+(int*)&size),
3887 // *(2+(int*)&size),*(3+(int*)&size));
3891 result
=my_mreq(size
,0);
3892 dbgprintf("new(%d) => %p\n", size
, result
);
3894 printf("WARNING: new() failed\n");
3898 static int expdelete(void* memory
)
3900 dbgprintf("delete(%p)\n", memory
);
3906 * local definition - we need only the last two members at this point
3907 * otherwice we would have to introduce here GUIDs and some more types..
3909 typedef struct __attribute__((__packed__
))
3912 unsigned long cbFormat
; //0x40
3913 char* pbFormat
; //0x44
3915 static HRESULT WINAPI
expMoCopyMediaType(MY_MEDIA_TYPE
* dest
, const MY_MEDIA_TYPE
* src
)
3919 memcpy(dest
, src
, sizeof(MY_MEDIA_TYPE
));
3922 dest
->pbFormat
= (char*) my_mreq(dest
->cbFormat
, 0);
3923 if (!dest
->pbFormat
)
3924 return E_OUTOFMEMORY
;
3925 memcpy(dest
->pbFormat
, src
->pbFormat
, dest
->cbFormat
);
3929 static HRESULT WINAPI
expMoInitMediaType(MY_MEDIA_TYPE
* dest
, DWORD cbFormat
)
3933 memset(dest
, 0, sizeof(MY_MEDIA_TYPE
));
3936 dest
->pbFormat
= (char*) my_mreq(cbFormat
, 0);
3937 if (!dest
->pbFormat
)
3938 return E_OUTOFMEMORY
;
3942 static HRESULT WINAPI
expMoCreateMediaType(MY_MEDIA_TYPE
** dest
, DWORD cbFormat
)
3946 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
3947 return expMoInitMediaType(*dest
, cbFormat
);
3949 static HRESULT WINAPI
expMoDuplicateMediaType(MY_MEDIA_TYPE
** dest
, const void* src
)
3953 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
3954 return expMoCopyMediaType(*dest
, src
);
3956 static HRESULT WINAPI
expMoFreeMediaType(MY_MEDIA_TYPE
* dest
)
3962 my_release(dest
->pbFormat
);
3968 static HRESULT WINAPI
expMoDeleteMediaType(MY_MEDIA_TYPE
* dest
)
3972 expMoFreeMediaType(dest
);
3977 static int exp_snprintf( char *str
, int size
, const char *format
, ... )
3981 va_start(va
, format
);
3982 x
=snprintf(str
,size
,format
,va
);
3983 dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str
,size
,format
,x
);
3989 static int exp_initterm(int v1
, int v2
)
3991 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1
, v2
);
3995 /* merged from wine - 2002.04.21 */
3996 typedef void (*INITTERMFUNC
)();
3997 static int exp_initterm(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
3999 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start
, end
, *start
);
4004 //printf("call _initfunc: from: %p %d\n", *start);
4005 // ok this trick with push/pop is necessary as otherwice
4006 // edi/esi registers are being trashed
4025 //printf("done %p %d:%d\n", end);
4033 /* Fake _initterm_e from msvcr80.dll, needed by sirenacm.dll
4034 * NOTE: If I make this an alias for _initterm, then sirenacm.dll tries to call
4035 other uninmplemented functions; keep this in mind if some future codec needs
4036 a real implementation of this function */
4037 static int exp_initterm_e(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
4039 dbgprintf("_initterm_e(0x%x, 0x%x)\n", start
, end
);
4043 static void* exp__dllonexit()
4045 // FIXME extract from WINE
4049 static int expwsprintfA(char* string
, const char* format
, ...)
4053 va_start(va
, format
);
4054 result
= vsprintf(string
, format
, va
);
4055 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string
, format
, result
);
4060 static int expsprintf(char* str
, const char* format
, ...)
4064 dbgprintf("sprintf(0x%x, %s)\n", str
, format
);
4065 va_start(args
, format
);
4066 r
= vsprintf(str
, format
, args
);
4070 static int expsscanf(const char* str
, const char* format
, ...)
4074 dbgprintf("sscanf(%s, %s)\n", str
, format
);
4075 va_start(args
, format
);
4076 r
= vsscanf(str
, format
, args
);
4080 static void* expfopen(const char* path
, const char* mode
)
4082 printf("fopen: \"%s\" mode:%s\n", path
, mode
);
4083 //return fopen(path, mode);
4084 return fdopen(0, mode
); // everything on screen
4086 static int expfprintf(void* stream
, const char* format
, ...)
4090 dbgprintf("fprintf(%p, %s, ...)\n", stream
, format
);
4092 va_start(args
, format
);
4093 r
= vfprintf((FILE*) stream
, format
, args
);
4099 static int expprintf(const char* format
, ...)
4103 dbgprintf("printf(%s, ...)\n", format
);
4104 va_start(args
, format
);
4105 r
= vprintf(format
, args
);
4110 static char* expgetenv(const char* varname
)
4112 char* v
= getenv(varname
);
4113 dbgprintf("getenv(%s) => %s\n", varname
, v
);
4117 static void* expwcscpy(WCHAR
* dst
, const WCHAR
* src
)
4120 while ((*p
++ = *src
++))
4125 static char* expstrrchr(char* string
, int value
)
4127 char* result
=strrchr(string
, value
);
4129 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4131 dbgprintf("strrchr(0x%x='%s', %d) => 0", string
, string
, value
);
4135 static char* expstrchr(char* string
, int value
)
4137 char* result
=strchr(string
, value
);
4139 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4141 dbgprintf("strchr(0x%x='%s', %d) => 0", string
, string
, value
);
4144 static int expstrlen(char* str
)
4146 int result
=strlen(str
);
4147 dbgprintf("strlen(0x%x='%s') => %d\n", str
, str
, result
);
4150 static char* expstrcpy(char* str1
, const char* str2
)
4152 char* result
= strcpy(str1
, str2
);
4153 dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1
, str2
, str2
, result
);
4156 static char* expstrncpy(char* str1
, const char* str2
, size_t count
)
4158 char* result
= strncpy(str1
, str2
, count
);
4159 dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1
, str2
, str2
, count
, result
);
4162 static int expstrcmp(const char* str1
, const char* str2
)
4164 int result
=strcmp(str1
, str2
);
4165 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4168 static int expstrncmp(const char* str1
, const char* str2
,int x
)
4170 int result
=strncmp(str1
, str2
,x
);
4171 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4174 static char* expstrcat(char* str1
, const char* str2
)
4176 char* result
= strcat(str1
, str2
);
4177 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1
, str1
, str2
, str2
, result
);
4180 static char* exp_strdup(const char* str1
)
4182 int l
= strlen(str1
);
4183 char* result
= (char*) my_mreq(l
+ 1,0);
4185 strcpy(result
, str1
);
4186 dbgprintf("_strdup(0x%x='%s') => %p\n", str1
, str1
, result
);
4189 static int expisalnum(int c
)
4191 int result
= (int) isalnum(c
);
4192 dbgprintf("isalnum(0x%x='%c' => %d\n", c
, c
, result
);
4195 static int expisspace(int c
)
4197 int result
= (int) isspace(c
);
4198 dbgprintf("isspace(0x%x='%c' => %d\n", c
, c
, result
);
4201 static int expisalpha(int c
)
4203 int result
= (int) isalpha(c
);
4204 dbgprintf("isalpha(0x%x='%c' => %d\n", c
, c
, result
);
4207 static int expisdigit(int c
)
4209 int result
= (int) isdigit(c
);
4210 dbgprintf("isdigit(0x%x='%c' => %d\n", c
, c
, result
);
4213 static void* expmemmove(void* dest
, void* src
, int n
)
4215 void* result
= memmove(dest
, src
, n
);
4216 dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4219 static int expmemcmp(void* dest
, void* src
, int n
)
4221 int result
= memcmp(dest
, src
, n
);
4222 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest
, src
, n
, result
);
4225 static void* expmemcpy(void* dest
, void* src
, int n
)
4227 void *result
= memcpy(dest
, src
, n
);
4228 dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4231 static void* expmemset(void* dest
, int c
, size_t n
)
4233 void *result
= memset(dest
, c
, n
);
4234 dbgprintf("memset(0x%x, %d, %d) => %p\n", dest
, c
, n
, result
);
4237 static time_t exptime(time_t* t
)
4239 time_t result
= time(t
);
4240 dbgprintf("time(0x%x) => %d\n", t
, result
);
4244 static int exprand(void)
4249 static void expsrand(int seed
)
4256 // preferred compilation with -O2 -ffast-math !
4258 static double explog10(double x
)
4260 /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4264 static double expcos(double x
)
4266 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4272 static void explog10(void)
4283 static void expcos(void)
4294 // this seem to be the only how to make this function working properly
4295 // ok - I've spent tremendous amount of time (many many many hours
4296 // of debuging fixing & testing - it's almost unimaginable - kabi
4298 // _ftol - operated on the float value which is already on the FPU stack
4300 static void exp_ftol(void)
4304 "sub $12, %esp \n\t"
4305 "fstcw -2(%ebp) \n\t"
4307 "movw -2(%ebp), %ax \n\t"
4308 "orb $0x0C, %ah \n\t"
4309 "movw %ax, -4(%ebp) \n\t"
4310 "fldcw -4(%ebp) \n\t"
4311 "fistpl -12(%ebp) \n\t"
4312 "fldcw -2(%ebp) \n\t"
4313 "movl -12(%ebp), %eax \n\t"
4314 //Note: gcc 3.03 does not do the following op if it
4315 // knows that ebp=esp
4316 "movl %ebp, %esp \n\t"
4320 #define FPU_DOUBLES(var1,var2) double var1,var2; \
4321 __asm__ volatile( "fstpl %0;fwait" : "=m" (var2) : ); \
4322 __asm__ volatile( "fstpl %0;fwait" : "=m" (var1) : )
4324 static double exp_CIpow(void)
4328 dbgprintf("_CIpow(%lf, %lf)\n", x
, y
);
4332 static double exppow(double x
, double y
)
4334 /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4338 static double expldexp(double x
, int expo
)
4340 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4341 return ldexp(x
, expo
);
4344 static double expfrexp(double x
, int* expo
)
4346 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4347 return frexp(x
, expo
);
4352 static int exp_stricmp(const char* s1
, const char* s2
)
4354 return strcasecmp(s1
, s2
);
4357 /* from declaration taken from Wine sources - this fountion seems to be
4358 * undocumented in any M$ doc */
4359 static int exp_setjmp3(void* jmpbuf
, int x
)
4361 //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4365 //"mov 4(%%esp), %%edx \n\t"
4366 "mov (%%esp), %%eax \n\t"
4367 "mov %%eax, (%%edx) \n\t" // store ebp
4369 //"mov %%ebp, (%%edx) \n\t"
4370 "mov %%ebx, 4(%%edx) \n\t"
4371 "mov %%edi, 8(%%edx) \n\t"
4372 "mov %%esi, 12(%%edx) \n\t"
4373 "mov %%esp, 16(%%edx) \n\t"
4375 "mov 4(%%esp), %%eax \n\t"
4376 "mov %%eax, 20(%%edx) \n\t"
4378 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4379 "movl $0, 36(%%edx) \n\t"
4381 : "d"(jmpbuf
) // input
4387 "mov %%fs:0, %%eax \n\t" // unsure
4388 "mov %%eax, 24(%%edx) \n\t"
4389 "cmp $0xffffffff, %%eax \n\t"
4391 "mov %%eax, 28(%%edx) \n\t"
4402 static DWORD WINAPI
expGetCurrentProcessId(void)
4404 dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4405 return getpid(); //(DWORD)NtCurrentTeb()->pid;
4412 } TIMECAPS
, *LPTIMECAPS
;
4414 static MMRESULT WINAPI
exptimeGetDevCaps(LPTIMECAPS lpCaps
, UINT wSize
)
4416 dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps
, wSize
);
4418 lpCaps
->wPeriodMin
= 1;
4419 lpCaps
->wPeriodMax
= 65535;
4423 static MMRESULT WINAPI
exptimeBeginPeriod(UINT wPeriod
)
4425 dbgprintf("timeBeginPeriod(%u) !\n", wPeriod
);
4427 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4432 static MMRESULT WINAPI
exptimeEndPeriod(UINT wPeriod
)
4434 dbgprintf("timeEndPeriod(%u) !\n", wPeriod
);
4436 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4441 static void WINAPI
expGlobalMemoryStatus(
4442 LPMEMORYSTATUS lpmem
4444 static MEMORYSTATUS cached_memstatus
;
4445 static int cache_lastchecked
= 0;
4449 if (time(NULL
)==cache_lastchecked
) {
4450 memcpy(lpmem
,&cached_memstatus
,sizeof(MEMORYSTATUS
));
4455 f
= fopen( "/proc/meminfo", "r" );
4459 int total
, used
, free
, shared
, buffers
, cached
;
4461 lpmem
->dwLength
= sizeof(MEMORYSTATUS
);
4462 lpmem
->dwTotalPhys
= lpmem
->dwAvailPhys
= 0;
4463 lpmem
->dwTotalPageFile
= lpmem
->dwAvailPageFile
= 0;
4464 while (fgets( buffer
, sizeof(buffer
), f
))
4466 /* old style /proc/meminfo ... */
4467 if (sscanf( buffer
, "Mem: %d %d %d %d %d %d", &total
, &used
, &free
, &shared
, &buffers
, &cached
))
4469 lpmem
->dwTotalPhys
+= total
;
4470 lpmem
->dwAvailPhys
+= free
+ buffers
+ cached
;
4472 if (sscanf( buffer
, "Swap: %d %d %d", &total
, &used
, &free
))
4474 lpmem
->dwTotalPageFile
+= total
;
4475 lpmem
->dwAvailPageFile
+= free
;
4478 /* new style /proc/meminfo ... */
4479 if (sscanf(buffer
, "MemTotal: %d", &total
))
4480 lpmem
->dwTotalPhys
= total
*1024;
4481 if (sscanf(buffer
, "MemFree: %d", &free
))
4482 lpmem
->dwAvailPhys
= free
*1024;
4483 if (sscanf(buffer
, "SwapTotal: %d", &total
))
4484 lpmem
->dwTotalPageFile
= total
*1024;
4485 if (sscanf(buffer
, "SwapFree: %d", &free
))
4486 lpmem
->dwAvailPageFile
= free
*1024;
4487 if (sscanf(buffer
, "Buffers: %d", &buffers
))
4488 lpmem
->dwAvailPhys
+= buffers
*1024;
4489 if (sscanf(buffer
, "Cached: %d", &cached
))
4490 lpmem
->dwAvailPhys
+= cached
*1024;
4494 if (lpmem
->dwTotalPhys
)
4496 DWORD TotalPhysical
= lpmem
->dwTotalPhys
+lpmem
->dwTotalPageFile
;
4497 DWORD AvailPhysical
= lpmem
->dwAvailPhys
+lpmem
->dwAvailPageFile
;
4498 lpmem
->dwMemoryLoad
= (TotalPhysical
-AvailPhysical
)
4499 / (TotalPhysical
/ 100);
4504 /* FIXME: should do something for other systems */
4505 lpmem
->dwMemoryLoad
= 0;
4506 lpmem
->dwTotalPhys
= 16*1024*1024;
4507 lpmem
->dwAvailPhys
= 16*1024*1024;
4508 lpmem
->dwTotalPageFile
= 16*1024*1024;
4509 lpmem
->dwAvailPageFile
= 16*1024*1024;
4511 expGetSystemInfo(&si
);
4512 lpmem
->dwTotalVirtual
= si
.lpMaximumApplicationAddress
-si
.lpMinimumApplicationAddress
;
4513 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4514 lpmem
->dwAvailVirtual
= lpmem
->dwTotalVirtual
-64*1024;
4515 memcpy(&cached_memstatus
,lpmem
,sizeof(MEMORYSTATUS
));
4516 cache_lastchecked
= time(NULL
);
4518 /* it appears some memory display programs want to divide by these values */
4519 if(lpmem
->dwTotalPageFile
==0)
4520 lpmem
->dwTotalPageFile
++;
4522 if(lpmem
->dwAvailPageFile
==0)
4523 lpmem
->dwAvailPageFile
++;
4526 static INT WINAPI
expGetThreadPriority(HANDLE hthread
)
4528 dbgprintf("GetThreadPriority(%p)\n",hthread
);
4532 /**********************************************************************
4533 * SetThreadPriority [KERNEL32.@] Sets priority for thread.
4539 static WIN_BOOL WINAPI
expSetThreadPriority(
4540 HANDLE hthread
, /* [in] Handle to thread */
4541 INT priority
) /* [in] Thread priority level */
4543 dbgprintf("SetThreadPriority(%p,%d)\n",hthread
,priority
);
4547 static void WINAPI
expExitProcess( DWORD status
)
4549 printf("EXIT - code %ld\n",status
);
4553 static INT WINAPI
expMessageBoxA(HWND hWnd
, LPCSTR text
, LPCSTR title
, UINT type
){
4554 printf("MSGBOX '%s' '%s' (%d)\n",text
,title
,type
);
4556 if (type
== MB_ICONHAND
&& !strlen(text
) && !strlen(title
))
4562 /* these are needed for mss1 */
4565 * \brief this symbol is defined within exp_EH_prolog_dummy
4566 * \param dest jump target
4568 void exp_EH_prolog(void *dest
);
4569 //! just a dummy function that acts a container for the asm section
4570 void exp_EH_prolog_dummy(void) {
4572 // take care, this "function" may not change flags or
4573 // registers besides eax (which is also why we can't use
4574 // exp_EH_prolog_dummy directly)
4575 MANGLE(exp_EH_prolog
)": \n\t"
4578 "mov %esp, %ebp \n\t"
4579 "lea -12(%esp), %esp \n\t"
4584 #include <netinet/in.h>
4585 static WINAPI
inline unsigned long int exphtonl(unsigned long int hostlong
)
4587 // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4588 return htonl(hostlong
);
4591 static WINAPI
inline unsigned long int expntohl(unsigned long int netlong
)
4593 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4594 return ntohl(netlong
);
4596 static void WINAPI
expVariantInit(void* p
)
4598 printf("InitCommonControls called!\n");
4602 static int WINAPI
expRegisterClassA(const void/*WNDCLASSA*/ *wc
)
4604 dbgprintf("RegisterClassA(%p) => random id\n", wc
);
4605 return time(NULL
); /* be precise ! */
4608 static int WINAPI
expUnregisterClassA(const char *className
, HINSTANCE hInstance
)
4610 dbgprintf("UnregisterClassA(%s, %p) => 0\n", className
, hInstance
);
4615 /* should be fixed bcs it's not fully strlen equivalent */
4616 static int expSysStringByteLen(void *str
)
4618 dbgprintf("SysStringByteLen(%p) => %d\n", str
, strlen(str
));
4622 static int expDirectDrawCreate(void)
4624 dbgprintf("DirectDrawCreate(...) => NULL\n");
4629 typedef struct tagPALETTEENTRY
{
4636 /* reversed the first 2 entries */
4637 typedef struct tagLOGPALETTE
{
4640 PALETTEENTRY palPalEntry
[1];
4643 static HPALETTE WINAPI
expCreatePalette(CONST LOGPALETTE
*lpgpl
)
4648 dbgprintf("CreatePalette(%x) => NULL\n", lpgpl
);
4650 i
= sizeof(LOGPALETTE
)+((lpgpl
->palNumEntries
-1)*sizeof(PALETTEENTRY
));
4651 test
= (HPALETTE
)malloc(i
);
4652 memcpy((void *)test
, lpgpl
, i
);
4657 static int expCreatePalette(void)
4659 dbgprintf("CreatePalette(...) => NULL\n");
4664 static int WINAPI
expGetClientRect(HWND win
, RECT
*r
)
4666 dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win
, r
);
4667 r
->right
= PSEUDO_SCREEN_WIDTH
;
4669 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
4675 typedef struct tagPOINT
{
4681 static int WINAPI
expClientToScreen(HWND win
, POINT
*p
)
4683 dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win
, p
, p
->x
, p
->y
);
4691 static int WINAPI
expSetThreadIdealProcessor(HANDLE thread
, int proc
)
4693 dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread
, proc
);
4697 static int WINAPI
expMessageBeep(int type
)
4699 dbgprintf("MessageBeep(%d) => 1\n", type
);
4703 static int WINAPI
expDialogBoxParamA(void *inst
, const char *name
,
4704 HWND parent
, void *dialog_func
, void *init_param
)
4706 dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
4707 inst
, name
, name
, parent
, dialog_func
, init_param
);
4711 static void WINAPI
expRegisterClipboardFormatA(const char *name
) {
4712 dbgprintf("RegisterClipboardFormatA(0x%x = %s)\n", name
, name
);
4715 /* needed by imagepower mjpeg2k */
4716 static void *exprealloc(void *ptr
, size_t size
)
4718 dbgprintf("realloc(0x%x, %x)\n", ptr
, size
);
4720 return my_mreq(size
,0);
4722 return my_realloc(ptr
, size
);
4725 /* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
4726 static WIN_BOOL WINAPI
expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn
)
4731 static char * WINAPI
expPathFindExtensionA(const char *path
) {
4736 ext
= strrchr(path
, '.');
4738 ext
= &path
[strlen(path
)];
4740 dbgprintf("PathFindExtensionA(0x%x = %s) => 0x%x, %s\n", path
, path
, ext
, ext
);
4744 static char * WINAPI
expPathFindFileNameA(const char *path
) {
4746 if (!path
|| strlen(path
) < 2)
4749 name
= strrchr(path
- 1, '\\');
4753 dbgprintf("PathFindFileNameA(0x%x = %s) => 0x%x, %s\n", path
, path
, name
, name
);
4757 static double expfloor(double x
)
4759 dbgprintf("floor(%lf)\n", x
);
4763 #define FPU_DOUBLE(var) double var; \
4764 __asm__ volatile( "fstpl %0;fwait" : "=m" (var) : )
4766 static double exp_CIcos(void)
4770 dbgprintf("_CIcos(%lf)\n", x
);
4774 static double exp_CIsin(void)
4778 dbgprintf("_CIsin(%lf)\n", x
);
4782 static double exp_CIsqrt(void)
4786 dbgprintf("_CIsqrt(%lf)\n", x
);
4790 /* Needed by rp8 sipr decoder */
4791 static LPSTR WINAPI
expCharNextA(LPCSTR ptr
)
4793 if (!*ptr
) return (LPSTR
)ptr
;
4794 // dbgprintf("CharNextA(0x%08x), %s\n", ptr, ptr);
4795 return (LPSTR
)(ptr
+ 1);
4798 // Fake implementation, needed by wvc1dmod.dll
4799 static int WINAPI
expPropVariantClear(void *pvar
)
4801 // dbgprintf("PropVariantclear (0x%08x), %s\n", ptr, ptr);
4805 // This define is fake, the real thing is a struct
4806 #define LPDEVMODEA void*
4807 // Dummy implementation, always return 1
4808 // Required for frapsvid.dll 2.8.1, return value does not matter
4809 static WIN_BOOL WINAPI
expEnumDisplaySettingsA(LPCSTR name
,DWORD n
,
4812 dbgprintf("EnumDisplaySettingsA (dummy) => 1\n");
4816 // Fake implementation of _decode_pointer from msvcr80.dll, needed by sirenacm.dll
4817 // NOTE: undocumented function, probably the declaration is not right
4818 static int exp_decode_pointer(void *ptr
)
4820 dbgprintf("_decode_pointer (0x%08x)\n", ptr
);
4824 /* Fake implementation of sdt::_Lockit::_Lockit(void) from msvcp60.dll
4825 Needed by SCLS.DLL */
4826 static int exp_0Lockit_dummy(void)
4828 dbgprintf("0Lockit_dummy (??0_Lockit@std@@QAE@XZ)\n");
4832 /* Fake implementation of sdt::_Lockit::~_Lockit(void) from msvcp60.dll
4833 Needed by SCLS.DLL */
4834 static int exp_1Lockit_dummy(void)
4836 dbgprintf("1Lockit_dummy (??1_Lockit@std@@QAE@XZ)\n");
4850 struct exports
* exps
;
4854 {#X, Y, (void*)exp##X},
4856 #define UNDEFF(X, Y) \
4859 struct exports exp_kernel32
[]=
4861 FF(GetVolumeInformationA
,-1)
4862 FF(GetDriveTypeA
,-1)
4863 FF(GetLogicalDriveStringsA
,-1)
4864 FF(IsBadWritePtr
, 357)
4865 FF(IsBadReadPtr
, 354)
4866 FF(IsBadStringPtrW
, -1)
4867 FF(IsBadStringPtrA
, -1)
4868 FF(DisableThreadLibraryCalls
, -1)
4869 FF(CreateThread
, -1)
4870 FF(CreateEventA
, -1)
4873 FF(WaitForSingleObject
, -1)
4875 FF(WaitForMultipleObjects
, -1)
4880 FF(GetSystemInfo
, -1)
4888 FF(GetProcessHeap
, -1)
4889 FF(VirtualAlloc
, -1)
4891 FF(InitializeCriticalSection
, -1)
4892 FF(EnterCriticalSection
, -1)
4893 FF(LeaveCriticalSection
, -1)
4894 FF(DeleteCriticalSection
, -1)
4899 FF(GetCurrentThreadId
, -1)
4900 FF(GetCurrentProcess
, -1)
4905 FF(GlobalReAlloc
, -1)
4908 FF(MultiByteToWideChar
, 427)
4909 FF(WideCharToMultiByte
, -1)
4910 FF(GetVersionExA
, -1)
4911 FF(CreateSemaphoreA
, -1)
4912 FF(QueryPerformanceCounter
, -1)
4913 FF(QueryPerformanceFrequency
, -1)
4917 FF(GlobalHandle
, -1)
4918 FF(GlobalUnlock
, -1)
4920 FF(LoadResource
, -1)
4921 FF(ReleaseSemaphore
, -1)
4922 FF(FindResourceA
, -1)
4923 FF(LockResource
, -1)
4924 FF(FreeResource
, -1)
4925 FF(SizeofResource
, -1)
4927 FF(GetCommandLineA
, -1)
4928 FF(GetEnvironmentStringsW
, -1)
4929 FF(FreeEnvironmentStringsW
, -1)
4930 FF(FreeEnvironmentStringsA
, -1)
4931 FF(GetEnvironmentStrings
, -1)
4932 FF(GetStartupInfoA
, -1)
4933 FF(GetStdHandle
, -1)
4936 FF(GetFileAttributesA
, -1)
4938 FF(SetHandleCount
, -1)
4940 FF(GetModuleFileNameA
, -1)
4941 FF(SetUnhandledExceptionFilter
, -1)
4942 FF(LoadLibraryA
, -1)
4943 FF(GetProcAddress
, -1)
4945 FF(CreateFileMappingA
, -1)
4946 FF(OpenFileMappingA
, -1)
4947 FF(MapViewOfFile
, -1)
4948 FF(UnmapViewOfFile
, -1)
4950 FF(GetModuleHandleA
, -1)
4951 FF(GetProfileIntA
, -1)
4952 FF(GetPrivateProfileIntA
, -1)
4953 FF(GetPrivateProfileStringA
, -1)
4954 FF(WritePrivateProfileStringA
, -1)
4955 FF(GetLastError
, -1)
4956 FF(SetLastError
, -1)
4957 FF(InterlockedIncrement
, -1)
4958 FF(InterlockedDecrement
, -1)
4959 FF(GetTimeZoneInformation
, -1)
4960 FF(OutputDebugStringA
, -1)
4961 FF(GetLocalTime
, -1)
4962 FF(GetSystemTime
, -1)
4963 FF(GetSystemTimeAsFileTime
, -1)
4964 FF(GetEnvironmentVariableA
, -1)
4965 FF(SetEnvironmentVariableA
, -1)
4966 FF(RtlZeroMemory
,-1)
4967 FF(RtlMoveMemory
,-1)
4968 FF(RtlFillMemory
,-1)
4970 FF(FindFirstFileA
,-1)
4971 FF(FindNextFileA
,-1)
4973 FF(FileTimeToLocalFileTime
,-1)
4977 FF(SetFilePointer
,-1)
4978 FF(GetTempFileNameA
,-1)
4980 FF(GetSystemDirectoryA
,-1)
4981 FF(GetWindowsDirectoryA
,-1)
4983 FF(GetCurrentDirectoryA
,-1)
4984 FF(SetCurrentDirectoryA
,-1)
4985 FF(CreateDirectoryA
,-1)
4987 FF(GetShortPathNameA
,-1)
4988 FF(GetFullPathNameA
,-1)
4989 FF(SetErrorMode
, -1)
4990 FF(IsProcessorFeaturePresent
, -1)
4991 FF(GetProcessAffinityMask
, -1)
4992 FF(InterlockedExchange
, -1)
4993 FF(InterlockedCompareExchange
, -1)
5000 FF(GetProcessVersion
,-1)
5001 FF(GetCurrentThread
,-1)
5004 FF(DuplicateHandle
,-1)
5005 FF(GetTickCount
, -1)
5006 FF(SetThreadAffinityMask
,-1)
5007 FF(GetCurrentProcessId
,-1)
5008 FF(GlobalMemoryStatus
,-1)
5009 FF(GetThreadPriority
,-1)
5010 FF(SetThreadPriority
,-1)
5012 {"LoadLibraryExA", -1, (void*)&LoadLibraryExA
},
5013 FF(SetThreadIdealProcessor
,-1)
5014 FF(SetProcessAffinityMask
, -1)
5015 UNDEFF(FlsAlloc
, -1)
5016 UNDEFF(FlsGetValue
, -1)
5017 UNDEFF(FlsSetValue
, -1)
5021 struct exports exp_msvcrt
[]={
5027 {"??3@YAXPAX@Z", -1, expdelete
},
5028 {"??2@YAPAXI@Z", -1, expnew
},
5029 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5030 {"_winver",-1,(void*)&_winver
},
5071 /* needed by frapsvid.dll */
5072 {"strstr",-1,(char *)&strstr
},
5073 {"qsort",-1,(void *)&qsort
},
5076 {"ceil",-1,(void*)&ceil
},
5077 /* needed by imagepower mjpeg2k */
5078 {"clock",-1,(void*)&clock
},
5079 {"memchr",-1,(void*)&memchr
},
5080 {"vfprintf",-1,(void*)&vfprintf
},
5081 // {"realloc",-1,(void*)&realloc},
5083 {"puts",-1,(void*)&puts
}
5085 struct exports exp_winmm
[]={
5086 FF(GetDriverModuleHandle
, -1)
5088 FF(DefDriverProc
, -1)
5091 FF(timeGetDevCaps
, -1)
5092 FF(timeBeginPeriod
, -1)
5094 FF(timeEndPeriod
, -1)
5095 FF(waveOutGetNumDevs
, -1)
5098 struct exports exp_user32
[]={
5103 FF(GetDesktopWindow
, -1)
5112 FF(RegisterWindowMessageA
,-1)
5113 FF(GetSystemMetrics
,-1)
5115 FF(GetSysColorBrush
,-1)
5119 FF(RegisterClassA
, -1)
5120 FF(UnregisterClassA
, -1)
5122 FF(GetWindowRect
, -1)
5123 FF(MonitorFromWindow
, -1)
5124 FF(MonitorFromRect
, -1)
5125 FF(MonitorFromPoint
, -1)
5126 FF(EnumDisplayMonitors
, -1)
5127 FF(GetMonitorInfoA
, -1)
5128 FF(EnumDisplayDevicesA
, -1)
5129 FF(GetClientRect
, -1)
5130 FF(ClientToScreen
, -1)
5131 FF(IsWindowVisible
, -1)
5132 FF(GetActiveWindow
, -1)
5133 FF(GetClassNameA
, -1)
5134 FF(GetClassInfoA
, -1)
5135 FF(GetWindowLongA
, -1)
5137 FF(GetWindowThreadProcessId
, -1)
5138 FF(CreateWindowExA
, -1)
5141 FF(DialogBoxParamA
, -1)
5142 FF(RegisterClipboardFormatA
, -1)
5144 FF(EnumDisplaySettingsA
, -1)
5146 struct exports exp_advapi32
[]={
5148 FF(RegCreateKeyA
, -1)
5149 FF(RegCreateKeyExA
, -1)
5150 FF(RegEnumKeyExA
, -1)
5151 FF(RegEnumValueA
, -1)
5153 FF(RegOpenKeyExA
, -1)
5154 FF(RegQueryValueExA
, -1)
5155 FF(RegSetValueExA
, -1)
5156 FF(RegQueryInfoKeyA
, -1)
5158 struct exports exp_gdi32
[]={
5159 FF(CreateCompatibleDC
, -1)
5162 FF(DeleteObject
, -1)
5163 FF(GetDeviceCaps
, -1)
5164 FF(GetSystemPaletteEntries
, -1)
5166 FF(CreatePalette
, -1)
5168 FF(CreateRectRgn
, -1)
5171 struct exports exp_version
[]={
5172 FF(GetFileVersionInfoSizeA
, -1)
5174 struct exports exp_ole32
[]={
5175 FF(CoCreateFreeThreadedMarshaler
,-1)
5176 FF(CoCreateInstance
, -1)
5177 FF(CoInitialize
, -1)
5178 FF(CoInitializeEx
, -1)
5179 FF(CoUninitialize
, -1)
5180 FF(CoTaskMemAlloc
, -1)
5181 FF(CoTaskMemFree
, -1)
5182 FF(StringFromGUID2
, -1)
5183 FF(PropVariantClear
, -1)
5185 // do we really need crtdll ???
5186 // msvcrt is the correct place probably...
5187 struct exports exp_crtdll
[]={
5191 struct exports exp_comctl32
[]={
5192 FF(StringFromGUID2
, -1)
5193 FF(InitCommonControls
, 17)
5195 FF(CreateUpDownControl
, 16)
5198 struct exports exp_wsock32
[]={
5202 struct exports exp_msdmo
[]={
5203 FF(memcpy
, -1) // just test
5204 FF(MoCopyMediaType
, -1)
5205 FF(MoCreateMediaType
, -1)
5206 FF(MoDeleteMediaType
, -1)
5207 FF(MoDuplicateMediaType
, -1)
5208 FF(MoFreeMediaType
, -1)
5209 FF(MoInitMediaType
, -1)
5211 struct exports exp_oleaut32
[]={
5214 FF(SysStringByteLen
, 149)
5220 vma: Hint/Ord Member-Name
5225 2305e 167 _adjust_fdiv
5228 22ffc 176 _beginthreadex
5230 2300e 85 __CxxFrameHandler
5234 struct exports exp_pncrt
[]={
5235 FF(malloc
, -1) // just test
5236 FF(free
, -1) // just test
5237 FF(fprintf
, -1) // just test
5238 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5241 {"??3@YAXPAX@Z", -1, expdelete
},
5242 {"??2@YAPAXI@Z", -1, expnew
},
5254 struct exports exp_ddraw
[]={
5255 FF(DirectDrawCreate
, -1)
5259 struct exports exp_comdlg32
[]={
5260 FF(GetOpenFileNameA
, -1)
5263 struct exports exp_shlwapi
[]={
5264 FF(PathFindExtensionA
, -1)
5265 FF(PathFindFileNameA
, -1)
5268 struct exports exp_msvcr80
[]={
5276 FF(_decode_pointer
, -1)
5279 struct exports exp_msvcp60
[]={
5280 {"??0_Lockit@std@@QAE@XZ", -1, exp_0Lockit_dummy
},
5281 {"??1_Lockit@std@@QAE@XZ", -1, exp_1Lockit_dummy
}
5285 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5287 struct libs libraries
[]={
5313 static WIN_BOOL WINAPI
ext_stubs(void)
5315 volatile int idx
= 0xdeadabcd;
5316 // make sure gcc does not do eip-relative call or something like that
5317 volatile void (*my_printf
)(char *, char *) = (void *)0xdeadfbcd;
5318 my_printf("Called unk_%s\n", export_names
[idx
]);
5322 #define MAX_STUB_SIZE 0x60
5323 #define MAX_NUM_STUBS 200
5325 static char *extcode
= NULL
;
5327 static void* add_stub(void)
5331 // generated code in runtime!
5334 extcode
= mmap_anon(NULL
, MAX_NUM_STUBS
* MAX_STUB_SIZE
,
5335 PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
, 0);
5336 answ
= extcode
+ pos
* MAX_STUB_SIZE
;
5337 if (pos
>= MAX_NUM_STUBS
) {
5338 printf("too many stubs, expect crash\n");
5341 memcpy(answ
, ext_stubs
, MAX_STUB_SIZE
);
5342 for (i
= 0; i
< MAX_STUB_SIZE
- 3; i
++) {
5343 int *magic
= (int *)(answ
+ i
);
5344 if (*magic
== 0xdeadabcd) {
5348 if (*magic
== 0xdeadfbcd) {
5349 *magic
= (intptr_t)printf
;
5354 printf("magic code not found in ext_subs, expect crash\n");
5361 void* LookupExternal(const char* library
, int ordinal
)
5366 printf("ERROR: library=0\n");
5367 return (void*)ext_unknown
;
5369 // printf("%x %x\n", &unk_exp1, &unk_exp2);
5371 dbgprintf("External func %s:%d\n", library
, ordinal
);
5373 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5375 if(strcasecmp(library
, libraries
[i
].name
))
5377 for(j
=0; j
<libraries
[i
].length
; j
++)
5379 if(ordinal
!=libraries
[i
].exps
[j
].id
)
5381 //printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5382 return libraries
[i
].exps
[j
].func
;
5386 #ifndef LOADLIB_TRY_NATIVE
5387 /* hack for truespeech and vssh264*/
5388 if (!strcmp(library
, "tsd32.dll") || !strcmp(library
,"vssh264dec.dll") || !strcmp(library
,"LCMW2.dll") || !strcmp(library
,"VDODEC32.dll"))
5390 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5396 hand
= LoadLibraryA(library
);
5399 wm
= MODULE32_LookupHMODULE(hand
);
5405 func
= PE_FindExportedFunction(wm
, (LPCSTR
) ordinal
, 0);
5408 printf("No such ordinal in external dll\n");
5409 FreeLibrary((int)hand
);
5413 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5419 if(pos
>150)return 0;
5420 sprintf(export_names
[pos
], "%s:%d", library
, ordinal
);
5424 void* LookupExternalByName(const char* library
, const char* name
)
5427 // return (void*)ext_unknown;
5430 printf("ERROR: library=0\n");
5431 return (void*)ext_unknown
;
5433 if((unsigned long)name
<=0xffff)
5435 return LookupExternal(library
, (int)name
);
5437 dbgprintf("External func %s:%s\n", library
, name
);
5438 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5440 if(strcasecmp(library
, libraries
[i
].name
))
5442 for(j
=0; j
<libraries
[i
].length
; j
++)
5444 if(strcmp(name
, libraries
[i
].exps
[j
].name
))
5446 if((unsigned int)(libraries
[i
].exps
[j
].func
) == -1)
5447 return NULL
; //undefined func
5448 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5449 return libraries
[i
].exps
[j
].func
;
5453 #ifndef LOADLIB_TRY_NATIVE
5454 /* hack for vss h264 */
5455 if (!strcmp(library
,"vssh264core.dll") || !strcmp(library
,"3ivx.dll"))
5457 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5463 hand
= LoadLibraryA(library
);
5466 wm
= MODULE32_LookupHMODULE(hand
);
5472 func
= PE_FindExportedFunction(wm
, name
, 0);
5475 printf("No such name in external dll\n");
5476 FreeLibrary((int)hand
);
5480 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5486 if(pos
>150)return 0;// to many symbols
5487 strcpy(export_names
[pos
], name
);
5491 void my_garbagecollection(void)
5494 int unfree
= 0, unfreecnt
= 0;
5500 alloc_header
* mem
= last_alloc
+ 1;
5501 unfree
+= my_size(mem
);
5503 if (my_release(mem
) != 0)
5504 // avoid endless loop when memory is trashed
5505 if (--max_fatal
< 0)
5508 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree
, unfreecnt
, last_alloc
, alccnt
);