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"
60 #include <sys/types.h>
64 #include <sys/timeb.h>
69 #ifdef HAVE_SYS_MMAN_H
72 #include "osdep/mmap.h"
74 #include "osdep/mmap_anon.h"
76 char* def_path
= WIN32_PATH
;
78 static void do_cpuid(unsigned int ax
, unsigned int *regs
)
82 "pushl %%ebx; pushl %%ecx; pushl %%edx;"
88 "popl %%edx; popl %%ecx; popl %%ebx;"
90 : "0" (ax
), "S" (regs
)
93 static unsigned int c_localcount_tsc(void)
105 static void c_longcount_tsc(long long* z
)
110 "movl %%eax, %%ebx\n\t"
112 "movl %%eax, 0(%%ebx)\n\t"
113 "movl %%edx, 4(%%ebx)\n\t"
119 static unsigned int c_localcount_notsc(void)
124 gettimeofday(&tv
, 0);
125 return limit
*tv
.tv_usec
;
127 static void c_longcount_notsc(long long* z
)
130 unsigned long long result
;
134 gettimeofday(&tv
, 0);
137 result
+=limit
*tv
.tv_usec
;
140 static unsigned int localcount_stub(void);
141 static void longcount_stub(long long*);
142 static unsigned int (*localcount
)()=localcount_stub
;
143 static void (*longcount
)(long long*)=longcount_stub
;
145 static pthread_mutex_t memmut
;
147 static unsigned int localcount_stub(void)
149 unsigned int regs
[4];
151 if ((regs
[3] & 0x00000010) != 0)
153 localcount
=c_localcount_tsc
;
154 longcount
=c_longcount_tsc
;
158 localcount
=c_localcount_notsc
;
159 longcount
=c_longcount_notsc
;
163 static void longcount_stub(long long* z
)
165 unsigned int regs
[4];
167 if ((regs
[3] & 0x00000010) != 0)
169 localcount
=c_localcount_tsc
;
170 longcount
=c_longcount_tsc
;
174 localcount
=c_localcount_notsc
;
175 longcount
=c_longcount_notsc
;
181 int LOADER_DEBUG
=1; // active only if compiled with -DDETAILED_OUT
182 //#define DETAILED_OUT
183 static inline void dbgprintf(char* fmt
, ...)
191 f
=fopen("./log", "a");
196 vfprintf(f
, fmt
, va
);
203 if ( mp_msg_test(MSGT_WIN32
,MSGL_DBG3
) )
209 // mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va);
216 char export_names
[300][32]={
221 //#define min(x,y) ((x)<(y)?(x):(y))
223 void destroy_event(void* event
);
226 typedef struct th_list_t
{
229 struct th_list_t
* next
;
230 struct th_list_t
* prev
;
234 // have to be cleared by GARBAGE COLLECTOR
235 //static unsigned char* heap=NULL;
236 //static int heap_counter=0;
237 static tls_t
* g_tls
=NULL
;
238 static th_list
* list
=NULL
;
241 static void test_heap(void)
246 while(offset
<heap_counter
)
248 if(*(int*)(heap
+offset
)!=0x433476)
250 printf("Heap corruption at address %d\n", offset
);
253 offset
+=8+*(int*)(heap
+offset
+4);
255 for(;offset
<min(offset
+1000, 20000000); offset
++)
256 if(heap
[offset
]!=0xCC)
258 printf("Free heap corruption at address %d\n", offset
);
266 static void* my_mreq(int size
, int to_zero
)
270 if(test
%10==0)printf("Memory: %d bytes allocated\n", heap_counter
);
274 heap
=malloc(20000000);
275 memset(heap
, 0xCC,20000000);
279 printf("No enough memory\n");
282 if(heap_counter
+size
>20000000)
284 printf("No enough memory\n");
287 *(int*)(heap
+heap_counter
)=0x433476;
289 *(int*)(heap
+heap_counter
)=size
;
291 printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size
, heap_counter
-8, heap_counter
, heap_counter
+size
);
293 memset(heap
+heap_counter
, 0, size
);
295 memset(heap
+heap_counter
, 0xcc, size
); // make crash reproducable
297 return heap
+heap_counter
-size
;
299 static int my_release(char* memory
)
304 printf("ERROR: free(0)\n");
307 if(*(int*)(memory
-8)!=0x433476)
309 printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
312 printf("Freed %d bytes of memory\n", *(int*)(memory
-4));
313 // memset(memory-8, *(int*)(memory-4), 0xCC);
319 typedef struct alloc_header_t alloc_header
;
320 struct alloc_header_t
322 // let's keep allocated data 16 byte aligned
334 static alloc_header
* last_alloc
= NULL
;
335 static int alccnt
= 0;
338 #define AREATYPE_CLIENT 0
339 #define AREATYPE_EVENT 1
340 #define AREATYPE_MUTEX 2
341 #define AREATYPE_COND 3
342 #define AREATYPE_CRITSECT 4
344 /* -- critical sections -- */
348 pthread_mutex_t mutex
;
353 void* mreq_private(int size
, int to_zero
, int type
);
354 void* mreq_private(int size
, int to_zero
, int type
)
356 int nsize
= size
+ sizeof(alloc_header
);
357 alloc_header
* header
= (alloc_header
* ) malloc(nsize
);
361 memset(header
, 0, nsize
);
365 pthread_mutex_init(&memmut
, NULL
);
366 pthread_mutex_lock(&memmut
);
370 pthread_mutex_lock(&memmut
);
371 last_alloc
->next
= header
; /* set next */
374 header
->prev
= last_alloc
;
378 pthread_mutex_unlock(&memmut
);
380 header
->deadbeef
= 0xdeadbeef;
384 //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt);
388 static int my_release(void* memory
)
390 alloc_header
* header
= (alloc_header
*) memory
- 1;
392 alloc_header
* prevmem
;
393 alloc_header
* nextmem
;
398 if (header
->deadbeef
!= (long) 0xdeadbeef)
400 dbgprintf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
404 pthread_mutex_lock(&memmut
);
409 destroy_event(memory
);
412 pthread_cond_destroy((pthread_cond_t
*)memory
);
415 pthread_mutex_destroy((pthread_mutex_t
*)memory
);
417 case AREATYPE_CRITSECT
:
418 pthread_mutex_destroy(&((struct CRITSECT
*)memory
)->mutex
);
421 //memset(memory, 0xcc, header->size);
425 header
->deadbeef
= 0;
426 prevmem
= header
->prev
;
427 nextmem
= header
->next
;
430 prevmem
->next
= nextmem
;
432 nextmem
->prev
= prevmem
;
434 if (header
== last_alloc
)
435 last_alloc
= prevmem
;
440 pthread_mutex_unlock(&memmut
);
442 pthread_mutex_destroy(&memmut
);
444 //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt);
449 //memset(header + 1, 0xcc, header->size);
455 static inline void* my_mreq(int size
, int to_zero
)
457 return mreq_private(size
, to_zero
, AREATYPE_CLIENT
);
460 static int my_size(void* memory
)
462 if(!memory
) return 0;
463 return ((alloc_header
*)memory
)[-1].size
;
466 static void* my_realloc(void* memory
, int size
)
471 return my_mreq(size
, 0);
472 osize
= my_size(memory
);
475 ans
= my_mreq(size
, 0);
476 memcpy(ans
, memory
, osize
);
484 * WINE API - native implementation for several win32 libraries
488 static int WINAPI
ext_unknown(void)
490 printf("Unknown func called\n");
494 static int WINAPI
expGetVolumeInformationA( const char *root
, char *label
,
495 unsigned int label_len
, unsigned int *serial
,
496 unsigned int *filename_len
,unsigned int *flags
,
497 char *fsname
, unsigned int fsname_len
)
499 dbgprintf("GetVolumeInformationA( %s, 0x%x, %ld, 0x%x, 0x%x, 0x%x, 0x%x, %ld) => 1\n",
500 root
,label
,label_len
,serial
,filename_len
,flags
,fsname
,fsname_len
);
501 //hack Do not return any real data - do nothing
505 static unsigned int WINAPI
expGetDriveTypeA( const char *root
)
507 dbgprintf("GetDriveTypeA( %s ) => %d\n",root
,DRIVE_FIXED
);
508 // hack return as Fixed Drive Type
512 static unsigned int WINAPI
expGetLogicalDriveStringsA( unsigned int len
, char *buffer
)
514 dbgprintf("GetLogicalDriveStringsA(%d, 0x%x) => 4\n",len
,buffer
);
515 // hack only have one drive c:\ in this hack
521 return 4; // 1 drive * 4 bytes (includes null)
525 static int WINAPI
expIsBadWritePtr(void* ptr
, unsigned int count
)
527 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
528 dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
531 static int WINAPI
expIsBadReadPtr(void* ptr
, unsigned int count
)
533 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
534 dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
537 static int WINAPI
expDisableThreadLibraryCalls(int module
)
539 dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module
);
543 static HMODULE WINAPI
expGetDriverModuleHandle(DRVR
* pdrv
)
549 result
=pdrv
->hDriverModule
;
550 dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv
, result
);
554 #define MODULE_HANDLE_kernel32 ((HMODULE)0x120)
555 #define MODULE_HANDLE_user32 ((HMODULE)0x121)
557 #define MODULE_HANDLE_wininet ((HMODULE)0x122)
558 #define MODULE_HANDLE_ddraw ((HMODULE)0x123)
559 #define MODULE_HANDLE_advapi32 ((HMODULE)0x124)
561 #define MODULE_HANDLE_comdlg32 ((HMODULE)0x125)
562 #define MODULE_HANDLE_msvcrt ((HMODULE)0x126)
563 #define MODULE_HANDLE_ole32 ((HMODULE)0x127)
564 #define MODULE_HANDLE_winmm ((HMODULE)0x128)
566 static HMODULE WINAPI
expGetModuleHandleA(const char* name
)
578 wm
=MODULE_FindModule(name
);
581 result
=(HMODULE
)(wm
->module
);
585 if(name
&& (strcasecmp(name
, "kernel32")==0 || !strcasecmp(name
, "kernel32.dll")))
586 result
=MODULE_HANDLE_kernel32
;
588 if(name
&& strcasecmp(name
, "user32")==0)
589 result
=MODULE_HANDLE_user32
;
592 dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name
, result
);
596 static void* WINAPI
expCreateThread(void* pSecAttr
, long dwStackSize
,
597 void* lpStartAddress
, void* lpParameter
,
598 long dwFlags
, long* dwThreadId
)
601 // printf("CreateThread:");
602 pth
= (pthread_t
*) my_mreq(sizeof(pthread_t
), 0);
603 pthread_create(pth
, NULL
, (void*(*)(void*))lpStartAddress
, lpParameter
);
605 printf( "WARNING: CreateThread flags not supported\n");
607 *dwThreadId
=(long)pth
;
610 list
=my_mreq(sizeof(th_list
), 1);
611 list
->next
=list
->prev
=NULL
;
615 list
->next
=my_mreq(sizeof(th_list
), 0);
616 list
->next
->prev
=list
;
617 list
->next
->next
=NULL
;
621 dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
622 pSecAttr
, dwStackSize
, lpStartAddress
, lpParameter
, dwFlags
, dwThreadId
, pth
);
637 struct mutex_list_t
* next
;
638 struct mutex_list_t
* prev
;
640 typedef struct mutex_list_t mutex_list
;
641 static mutex_list
* mlist
=NULL
;
643 void destroy_event(void* event
)
645 mutex_list
* pp
=mlist
;
646 // printf("garbage collector: destroy_event(%x)\n", event);
649 if(pp
==(mutex_list
*)event
)
652 pp
->next
->prev
=pp
->prev
;
654 pp
->prev
->next
=pp
->next
;
655 if(mlist
==(mutex_list
*)event
)
661 printf("%x => ", pp);
672 static void* WINAPI
expCreateEventA(void* pSecAttr
, char bManualReset
,
673 char bInitialState
, const char* name
)
682 printf("%x => ", pp);
689 mutex_list
* pp
=mlist
;
693 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==0))
695 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
696 pSecAttr
, bManualReset
, bInitialState
, name
, name
, pp
->pm
);
699 }while((pp
=pp
->prev
) != NULL
);
701 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
702 pthread_mutex_init(pm
, NULL
);
703 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
704 pthread_cond_init(pc
, NULL
);
707 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
708 mlist
->next
=mlist
->prev
=NULL
;
712 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
713 mlist
->next
->prev
=mlist
;
714 mlist
->next
->next
=NULL
;
717 mlist
->type
=0; /* Type Event */
720 mlist
->state
=bInitialState
;
721 mlist
->reset
=bManualReset
;
723 strncpy(mlist
->name
, name
, 127);
727 dbgprintf("ERROR::: CreateEventA failure\n");
730 pthread_mutex_lock(pm);
733 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
734 pSecAttr
, bManualReset
, bInitialState
, name
, name
, mlist
);
736 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
737 pSecAttr
, bManualReset
, bInitialState
, mlist
);
741 static void* WINAPI
expSetEvent(void* event
)
743 mutex_list
*ml
= (mutex_list
*)event
;
744 dbgprintf("SetEvent(%x) => 0x1\n", event
);
745 pthread_mutex_lock(ml
->pm
);
746 if (ml
->state
== 0) {
748 pthread_cond_signal(ml
->pc
);
750 pthread_mutex_unlock(ml
->pm
);
754 static void* WINAPI
expResetEvent(void* event
)
756 mutex_list
*ml
= (mutex_list
*)event
;
757 dbgprintf("ResetEvent(0x%x) => 0x1\n", event
);
758 pthread_mutex_lock(ml
->pm
);
760 pthread_mutex_unlock(ml
->pm
);
765 static void* WINAPI
expWaitForSingleObject(void* object
, int duration
)
767 mutex_list
*ml
= (mutex_list
*)object
;
768 // FIXME FIXME FIXME - this value is sometime unititialize !!!
769 int ret
= WAIT_FAILED
;
770 mutex_list
* pp
=mlist
;
771 if(object
== (void*)0xcfcf9898)
774 From GetCurrentThread() documentation:
775 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.
777 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.
779 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.
781 dbgprintf("WaitForSingleObject(thread_handle) called\n");
782 return (void*)WAIT_FAILED
;
784 dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object
, duration
);
786 // loop below was slightly fixed - its used just for checking if
787 // this object really exists in our list
790 while (pp
&& (pp
->pm
!= ml
->pm
))
793 dbgprintf("WaitForSingleObject: NotFound\n");
797 pthread_mutex_lock(ml
->pm
);
801 if (duration
== 0) { /* Check Only */
802 if (ml
->state
== 1) ret
= WAIT_FAILED
;
803 else ret
= WAIT_OBJECT_0
;
805 if (duration
== -1) { /* INFINITE */
807 pthread_cond_wait(ml
->pc
,ml
->pm
);
812 if (duration
> 0) { /* Timed Wait */
813 struct timespec abstime
;
815 gettimeofday(&now
, 0);
816 abstime
.tv_sec
= now
.tv_sec
+ (now
.tv_usec
+duration
)/1000000;
817 abstime
.tv_nsec
= ((now
.tv_usec
+duration
)%1000000)*1000;
819 ret
=pthread_cond_timedwait(ml
->pc
,ml
->pm
,&abstime
);
820 if (ret
== ETIMEDOUT
) ret
= WAIT_TIMEOUT
;
821 else ret
= WAIT_OBJECT_0
;
826 case 1: /* Semaphore */
828 if(ml
->semaphore
==0) ret
= WAIT_FAILED
;
834 if (duration
== -1) {
835 if (ml
->semaphore
==0)
836 pthread_cond_wait(ml
->pc
,ml
->pm
);
841 pthread_mutex_unlock(ml
->pm
);
843 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object
,duration
,ml
,ret
);
848 static void* WINAPI
expWaitForMultipleObjects(int count
, const void** objects
,
849 int WaitAll
, int duration
)
855 dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
856 count
, objects
, WaitAll
, duration
);
858 for (i
= 0; i
< count
; i
++)
860 object
= (void *)objects
[i
];
861 ret
= expWaitForSingleObject(object
, duration
);
863 dbgprintf("WaitAll flag not yet supported...\n");
870 static void WINAPI
expExitThread(int retcode
)
872 dbgprintf("ExitThread(%d)\n", retcode
);
873 pthread_exit(&retcode
);
876 static HANDLE WINAPI
expCreateMutexA(void *pSecAttr
,
877 char bInitialOwner
, const char *name
)
879 HANDLE mlist
= (HANDLE
)expCreateEventA(pSecAttr
, 0, 0, name
);
882 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
883 pSecAttr
, bInitialOwner
, name
, mlist
);
885 dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
886 pSecAttr
, bInitialOwner
, mlist
);
888 /* 10l to QTX, if CreateMutex returns a real mutex, WaitForSingleObject
889 waits for ever, else it works ;) */
894 static int WINAPI
expReleaseMutex(HANDLE hMutex
)
896 dbgprintf("ReleaseMutex(%x) => 1\n", hMutex
);
897 /* FIXME:XXX !! not yet implemented */
902 static int pf_set
= 0;
903 static BYTE PF
[64] = {0,};
905 static void DumpSystemInfo(const SYSTEM_INFO
* si
)
907 dbgprintf(" Processor architecture %d\n", si
->u
.s
.wProcessorArchitecture
);
908 dbgprintf(" Page size: %d\n", si
->dwPageSize
);
909 dbgprintf(" Minimum app address: %d\n", si
->lpMinimumApplicationAddress
);
910 dbgprintf(" Maximum app address: %d\n", si
->lpMaximumApplicationAddress
);
911 dbgprintf(" Active processor mask: 0x%x\n", si
->dwActiveProcessorMask
);
912 dbgprintf(" Number of processors: %d\n", si
->dwNumberOfProcessors
);
913 dbgprintf(" Processor type: 0x%x\n", si
->dwProcessorType
);
914 dbgprintf(" Allocation granularity: 0x%x\n", si
->dwAllocationGranularity
);
915 dbgprintf(" Processor level: 0x%x\n", si
->wProcessorLevel
);
916 dbgprintf(" Processor revision: 0x%x\n", si
->wProcessorRevision
);
919 static void WINAPI
expGetSystemInfo(SYSTEM_INFO
* si
)
921 /* FIXME: better values for the two entries below... */
922 static int cache
= 0;
923 static SYSTEM_INFO cachedsi
;
924 dbgprintf("GetSystemInfo(%p) =>\n", si
);
929 memset(PF
,0,sizeof(PF
));
932 cachedsi
.u
.s
.wProcessorArchitecture
= PROCESSOR_ARCHITECTURE_INTEL
;
933 cachedsi
.dwPageSize
= getpagesize();
935 /* FIXME: better values for the two entries below... */
936 cachedsi
.lpMinimumApplicationAddress
= (void *)0x00000000;
937 cachedsi
.lpMaximumApplicationAddress
= (void *)0x7FFFFFFF;
938 cachedsi
.dwActiveProcessorMask
= 1;
939 cachedsi
.dwNumberOfProcessors
= 1;
940 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
941 cachedsi
.dwAllocationGranularity
= 0x10000;
942 cachedsi
.wProcessorLevel
= 5; /* pentium */
943 cachedsi
.wProcessorRevision
= 0x0101;
945 /* mplayer's way to detect PF's */
947 #include "cpudetect.h"
950 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
952 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
953 if (gCpuCaps
.hasSSE2
)
954 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
955 if (gCpuCaps
.has3DNow
)
956 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
958 if (gCpuCaps
.cpuType
== 4)
960 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
961 cachedsi
.wProcessorLevel
= 4;
963 else if (gCpuCaps
.cpuType
>= 5)
965 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
966 cachedsi
.wProcessorLevel
= 5;
970 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
971 cachedsi
.wProcessorLevel
= 3;
973 cachedsi
.wProcessorRevision
= gCpuCaps
.cpuStepping
;
974 cachedsi
.dwNumberOfProcessors
= 1; /* hardcoded */
977 /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
978 fdiv_bug and fpu emulation flags -- alex/MPlayer */
983 FILE *f
= fopen ("/proc/cpuinfo", "r");
987 mp_msg(MSGT_WIN32
, MSGL_WARN
, "expGetSystemInfo: "
988 "/proc/cpuinfo not readable! "
989 "Expect bad performance and/or weird behaviour\n");
992 while (fgets(line
,200,f
)!=NULL
) {
995 /* NOTE: the ':' is the only character we can rely on */
996 if (!(value
= strchr(line
,':')))
998 /* terminate the valuename */
1000 /* skip any leading spaces */
1001 while (*value
==' ') value
++;
1002 if ((s
=strchr(value
,'\n')))
1006 if (!lstrncmpiA(line
, "cpu family",strlen("cpu family"))) {
1007 if (isdigit (value
[0])) {
1008 switch (value
[0] - '0') {
1009 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1010 cachedsi
.wProcessorLevel
= 3;
1012 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1013 cachedsi
.wProcessorLevel
= 4;
1015 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1016 cachedsi
.wProcessorLevel
= 5;
1018 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1019 cachedsi
.wProcessorLevel
= 5;
1021 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1022 cachedsi
.wProcessorLevel
= 5;
1026 /* set the CPU type of the current processor */
1027 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1030 /* old 2.0 method */
1031 if (!lstrncmpiA(line
, "cpu",strlen("cpu"))) {
1032 if ( isdigit (value
[0]) && value
[1] == '8' &&
1033 value
[2] == '6' && value
[3] == 0
1035 switch (value
[0] - '0') {
1036 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1037 cachedsi
.wProcessorLevel
= 3;
1039 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1040 cachedsi
.wProcessorLevel
= 4;
1042 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1043 cachedsi
.wProcessorLevel
= 5;
1045 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1046 cachedsi
.wProcessorLevel
= 5;
1048 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1049 cachedsi
.wProcessorLevel
= 5;
1053 /* set the CPU type of the current processor */
1054 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1057 if (!lstrncmpiA(line
,"fdiv_bug",strlen("fdiv_bug"))) {
1058 if (!lstrncmpiA(value
,"yes",3))
1059 PF
[PF_FLOATING_POINT_PRECISION_ERRATA
] = TRUE
;
1063 if (!lstrncmpiA(line
,"fpu",strlen("fpu"))) {
1064 if (!lstrncmpiA(value
,"no",2))
1065 PF
[PF_FLOATING_POINT_EMULATED
] = TRUE
;
1069 if (!lstrncmpiA(line
,"processor",strlen("processor"))) {
1070 /* processor number counts up...*/
1073 if (sscanf(value
,"%d",&x
))
1074 if (x
+1>cachedsi
.dwNumberOfProcessors
)
1075 cachedsi
.dwNumberOfProcessors
=x
+1;
1077 /* Create a new processor subkey on a multiprocessor
1080 sprintf(buf
,"%d",x
);
1082 if (!lstrncmpiA(line
,"stepping",strlen("stepping"))) {
1085 if (sscanf(value
,"%d",&x
))
1086 cachedsi
.wProcessorRevision
= x
;
1089 ( (!lstrncmpiA(line
,"flags",strlen("flags")))
1090 || (!lstrncmpiA(line
,"features",strlen("features"))) )
1092 if (strstr(value
,"cx8"))
1093 PF
[PF_COMPARE_EXCHANGE_DOUBLE
] = TRUE
;
1094 if (strstr(value
,"mmx"))
1095 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1096 if (strstr(value
,"tsc"))
1097 PF
[PF_RDTSC_INSTRUCTION_AVAILABLE
] = TRUE
;
1098 if (strstr(value
,"xmm") || strstr(value
,"sse"))
1099 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1100 if (strstr(value
,"sse2"))
1101 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1102 if (strstr(value
,"3dnow"))
1103 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1108 * ad hoc fix for smp machines.
1109 * some problems on WaitForSingleObject,CreateEvent,SetEvent
1110 * CreateThread ...etc..
1113 cachedsi
.dwNumberOfProcessors
=1;
1115 #endif /* __linux__ */
1118 memcpy(si
,&cachedsi
,sizeof(*si
));
1122 // avoid undefined expGetSystemInfo
1123 static WIN_BOOL WINAPI
expIsProcessorFeaturePresent(DWORD v
)
1125 WIN_BOOL result
= 0;
1129 expGetSystemInfo(&si
);
1131 if(v
<64) result
=PF
[v
];
1132 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v
, result
);
1137 static long WINAPI
expGetVersion(void)
1139 dbgprintf("GetVersion() => 0xC0000004\n");
1140 return 0xC0000004;//Windows 95
1143 static HANDLE WINAPI
expHeapCreate(long flags
, long init_size
, long max_size
)
1145 // printf("HeapCreate:");
1148 result
=(HANDLE
)my_mreq(0x110000, 0);
1150 result
=(HANDLE
)my_mreq((init_size
+ 0xfff) & 0x7ffff000 , 0);
1151 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags
, init_size
, max_size
, result
);
1155 // this is another dirty hack
1156 // VP31 is releasing one allocated Heap chunk twice
1157 // we will silently ignore this second call...
1158 static void* heapfreehack
= 0;
1159 static int heapfreehackshown
= 0;
1160 //void trapbug(void);
1161 static void* WINAPI
expHeapAlloc(HANDLE heap
, int flags
, int size
)
1165 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1166 HeapAlloc returns area larger than size argument :-/
1168 actually according to M$ Doc HeapCreate size should be rounded
1169 to page boundaries thus we should simulate this
1171 //if (size == 22276) trapbug();
1172 z
=my_mreq((size
+ 0xfff) & 0x7ffff000, (flags
& HEAP_ZERO_MEMORY
));
1174 printf("HeapAlloc failure\n");
1175 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap
, flags
, size
, z
);
1176 heapfreehack
= 0; // reset
1179 static long WINAPI
expHeapDestroy(void* heap
)
1181 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap
);
1186 static long WINAPI
expHeapFree(HANDLE heap
, DWORD dwFlags
, LPVOID lpMem
)
1188 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap
, dwFlags
, lpMem
);
1189 if (heapfreehack
!= lpMem
&& lpMem
!= (void*)0xffffffff
1190 && lpMem
!= (void*)0xbdbdbdbd)
1191 // 0xbdbdbdbd is for i263_drv.drv && libefence
1192 // it seems to be reading from relased memory
1193 // EF_PROTECT_FREE doens't show any probleme
1197 if (!heapfreehackshown
++)
1198 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem
);
1200 heapfreehack
= lpMem
;
1203 static long WINAPI
expHeapSize(int heap
, int flags
, void* pointer
)
1205 long result
=my_size(pointer
);
1206 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap
, flags
, pointer
, result
);
1209 static void* WINAPI
expHeapReAlloc(HANDLE heap
,int flags
,void *lpMem
,int size
)
1211 long orgsize
= my_size(lpMem
);
1212 dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize
,size
);
1213 return my_realloc(lpMem
, size
);
1215 static long WINAPI
expGetProcessHeap(void)
1217 dbgprintf("GetProcessHeap() => 1\n");
1220 static void* WINAPI
expVirtualAlloc(void* v1
, long v2
, long v3
, long v4
)
1222 void* z
= VirtualAlloc(v1
, v2
, v3
, v4
);
1224 printf("VirtualAlloc failure\n");
1225 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1
,v2
,v3
,v4
, z
);
1228 static int WINAPI
expVirtualFree(void* v1
, int v2
, int v3
)
1230 int result
= VirtualFree(v1
,v2
,v3
);
1231 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1
,v2
,v3
, result
);
1235 /* we're building a table of critical sections. cs_win pointer uses the DLL
1236 cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1237 struct critsecs_list_t
1239 CRITICAL_SECTION
*cs_win
;
1240 struct CRITSECT
*cs_unix
;
1243 /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1244 #undef CRITSECS_NEWTYPE
1245 //#define CRITSECS_NEWTYPE 1
1247 #ifdef CRITSECS_NEWTYPE
1248 /* increased due to ucod needs more than 32 entries */
1249 /* and 64 should be enough for everything */
1250 #define CRITSECS_LIST_MAX 64
1251 static struct critsecs_list_t critsecs_list
[CRITSECS_LIST_MAX
];
1253 static int critsecs_get_pos(CRITICAL_SECTION
*cs_win
)
1257 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1258 if (critsecs_list
[i
].cs_win
== cs_win
)
1263 static int critsecs_get_unused(void)
1267 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1268 if (critsecs_list
[i
].cs_win
== NULL
)
1273 struct CRITSECT
*critsecs_get_unix(CRITICAL_SECTION
*cs_win
)
1277 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1278 if (critsecs_list
[i
].cs_win
== cs_win
&& critsecs_list
[i
].cs_unix
)
1279 return critsecs_list
[i
].cs_unix
;
1284 static void WINAPI
expInitializeCriticalSection(CRITICAL_SECTION
* c
)
1286 dbgprintf("InitializeCriticalSection(0x%x)\n", c
);
1287 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1289 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1290 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1293 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1294 #ifdef CRITSECS_NEWTYPE
1296 struct CRITSECT
*cs
;
1297 int i
= critsecs_get_unused();
1301 printf("InitializeCriticalSection(%p) - no more space in list\n", c
);
1304 dbgprintf("got unused space at %d\n", i
);
1305 cs
= malloc(sizeof(struct CRITSECT
));
1308 printf("InitializeCriticalSection(%p) - out of memory\n", c
);
1311 pthread_mutex_init(&cs
->mutex
, NULL
);
1313 critsecs_list
[i
].cs_win
= c
;
1314 critsecs_list
[i
].cs_unix
= cs
;
1315 dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1320 struct CRITSECT
* cs
= mreq_private(sizeof(struct CRITSECT
) + sizeof(CRITICAL_SECTION
),
1321 0, AREATYPE_CRITSECT
);
1322 pthread_mutex_init(&cs
->mutex
, NULL
);
1324 cs
->deadbeef
= 0xdeadbeef;
1331 static void WINAPI
expEnterCriticalSection(CRITICAL_SECTION
* c
)
1333 #ifdef CRITSECS_NEWTYPE
1334 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1336 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1338 dbgprintf("EnterCriticalSection(0x%x) %p\n",c
, cs
);
1341 dbgprintf("entered uninitialized critisec!\n");
1342 expInitializeCriticalSection(c
);
1343 #ifdef CRITSECS_NEWTYPE
1344 cs
=critsecs_get_unix(c
);
1346 cs
= (*(struct CRITSECT
**)c
);
1348 dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c
);
1351 if(cs
->id
==pthread_self())
1353 pthread_mutex_lock(&(cs
->mutex
));
1355 cs
->id
=pthread_self();
1358 static void WINAPI
expLeaveCriticalSection(CRITICAL_SECTION
* c
)
1360 #ifdef CRITSECS_NEWTYPE
1361 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1363 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1365 // struct CRITSECT* cs=(struct CRITSECT*)c;
1366 dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c
, cs
);
1369 dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c
);
1375 pthread_mutex_unlock(&(cs
->mutex
));
1378 dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c
);
1382 static void expfree(void* mem
); /* forward declaration */
1384 static void WINAPI
expDeleteCriticalSection(CRITICAL_SECTION
*c
)
1386 #ifdef CRITSECS_NEWTYPE
1387 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1389 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1391 // struct CRITSECT* cs=(struct CRITSECT*)c;
1392 dbgprintf("DeleteCriticalSection(0x%x)\n",c
);
1396 dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c
);
1402 dbgprintf("Win32 Warning: Deleting unlocked Critical Section %p!!\n", c
);
1403 pthread_mutex_unlock(&(cs
->mutex
));
1407 pthread_mutex_destroy(&(cs
->mutex
));
1408 // released by GarbageCollector in my_relase otherwise
1411 #ifdef CRITSECS_NEWTYPE
1413 int i
= critsecs_get_pos(c
);
1417 printf("DeleteCriticalSection(%p) error (critsec not found)\n", c
);
1421 critsecs_list
[i
].cs_win
= NULL
;
1422 expfree(critsecs_list
[i
].cs_unix
);
1423 critsecs_list
[i
].cs_unix
= NULL
;
1424 dbgprintf("DeleteCriticalSection -> itemno=%d\n", i
);
1429 static int WINAPI
expGetCurrentThreadId(void)
1431 dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1432 return pthread_self();
1434 static int WINAPI
expGetCurrentProcess(void)
1436 dbgprintf("GetCurrentProcess() => %d\n", getpid());
1441 // this version is required for Quicktime codecs (.qtx/.qts) to work.
1442 // (they assume some pointers at FS: segment)
1444 extern void* fs_seg
;
1446 //static int tls_count;
1447 static int tls_use_map
[64];
1448 static int WINAPI
expTlsAlloc(void)
1452 if(tls_use_map
[i
]==0)
1455 dbgprintf("TlsAlloc() => %d\n",i
);
1458 dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1462 //static int WINAPI expTlsSetValue(DWORD index, void* value)
1463 static int WINAPI
expTlsSetValue(int index
, void* value
)
1465 dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index
,value
);
1466 // if((index<0) || (index>64))
1469 *(void**)((char*)fs_seg
+0x88+4*index
) = value
;
1473 static void* WINAPI
expTlsGetValue(DWORD index
)
1475 dbgprintf("TlsGetValue(%d)\n",index
);
1476 // if((index<0) || (index>64))
1477 if((index
>=64)) return NULL
;
1478 return *(void**)((char*)fs_seg
+0x88+4*index
);
1481 static int WINAPI
expTlsFree(int idx
)
1483 int index
= (int) idx
;
1484 dbgprintf("TlsFree(%d)\n",index
);
1485 if((index
<0) || (index
>64))
1487 tls_use_map
[index
]=0;
1499 static void* WINAPI
expTlsAlloc(void)
1503 g_tls
=my_mreq(sizeof(tls_t
), 0);
1504 g_tls
->next
=g_tls
->prev
=NULL
;
1508 g_tls
->next
=my_mreq(sizeof(tls_t
), 0);
1509 g_tls
->next
->prev
=g_tls
;
1510 g_tls
->next
->next
=NULL
;
1513 dbgprintf("TlsAlloc() => 0x%x\n", g_tls
);
1515 g_tls
->value
=0; /* XXX For Divx.dll */
1519 static int WINAPI
expTlsSetValue(void* idx
, void* value
)
1521 tls_t
* index
= (tls_t
*) idx
;
1530 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index
, value
, result
);
1533 static void* WINAPI
expTlsGetValue(void* idx
)
1535 tls_t
* index
= (tls_t
*) idx
;
1540 result
=index
->value
;
1541 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index
, result
);
1544 static int WINAPI
expTlsFree(void* idx
)
1546 tls_t
* index
= (tls_t
*) idx
;
1553 index
->next
->prev
=index
->prev
;
1555 index
->prev
->next
=index
->next
;
1557 g_tls
= index
->prev
;
1558 my_release((void*)index
);
1561 dbgprintf("TlsFree(index 0x%x) => %d\n", index
, result
);
1566 static void* WINAPI
expLocalAlloc(int flags
, int size
)
1568 void* z
= my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1570 printf("LocalAlloc() failed\n");
1571 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1575 static void* WINAPI
expLocalReAlloc(int handle
,int size
, int flags
)
1581 if (flags
& LMEM_MODIFY
) {
1582 dbgprintf("LocalReAlloc MODIFY\n");
1583 return (void *)handle
;
1585 oldsize
= my_size((void *)handle
);
1586 newpointer
= my_realloc((void *)handle
,size
);
1587 dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle
,size
,oldsize
, flags
,newpointer
);
1592 static void* WINAPI
expLocalLock(void* z
)
1594 dbgprintf("LocalLock(0x%x) => 0x%x\n", z
, z
);
1598 static void* WINAPI
expGlobalAlloc(int flags
, int size
)
1601 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size
, flags
);
1603 z
=my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1604 //z=calloc(size, 1);
1607 printf("GlobalAlloc() failed\n");
1608 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1611 static void* WINAPI
expGlobalLock(void* z
)
1613 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z
, z
);
1616 // pvmjpg20 - but doesn't work anyway
1617 static int WINAPI
expGlobalSize(void* amem
)
1621 alloc_header
* header
= last_alloc
;
1622 alloc_header
* mem
= (alloc_header
*) amem
- 1;
1625 pthread_mutex_lock(&memmut
);
1628 if (header
->deadbeef
!= 0xdeadbeef)
1630 dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
1636 size
= header
->size
;
1640 header
= header
->prev
;
1642 pthread_mutex_unlock(&memmut
);
1645 dbgprintf("GlobalSize(0x%x)\n", amem
);
1649 static int WINAPI
expLoadIconA( long hinstance
, char *name
)
1651 dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance
,name
);
1655 static int WINAPI
expLoadStringA(long instance
, long id
, void* buf
, long size
)
1657 int result
=LoadStringA(instance
, id
, buf
, size
);
1659 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1660 instance
, id
, buf
, size
, result
, buf
);
1662 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1663 // instance, id, buf, size, result);
1667 static long WINAPI
expMultiByteToWideChar(long v1
, long v2
, char* s1
, long siz1
, short* s2
, int siz2
)
1676 if(siz1
>siz2
/2)siz1
=siz2
/2;
1677 for(i
=1; i
<=siz1
; i
++)
1687 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1688 "size %d, dest buffer 0x%x, dest size %d) => %d\n",
1689 v1
, v2
, s1
, s1
, siz1
, s2
, siz2
, result
);
1691 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1692 "size %d, dest buffer 0x%x, dest size %d) =>\n",
1693 v1
, v2
, siz1
, s2
, siz2
, result
);
1696 static void wch_print(const short* str
)
1698 dbgprintf(" src: ");
1699 while(*str
)dbgprintf("%c", *str
++);
1702 static long WINAPI
expWideCharToMultiByte(long v1
, long v2
, short* s1
, long siz1
,
1703 char* s2
, int siz2
, char* c3
, int* siz3
)
1706 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1707 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1708 result
=WideCharToMultiByte(v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1709 dbgprintf("=> %d\n", result
);
1710 //if(s1)wch_print(s1);
1711 if(s2
)dbgprintf(" dest: %s\n", s2
);
1714 static long WINAPI
expGetVersionExA(OSVERSIONINFOA
* c
)
1716 dbgprintf("GetVersionExA(0x%x) => 1\n");
1717 c
->dwOSVersionInfoSize
=sizeof(*c
);
1718 c
->dwMajorVersion
=4;
1719 c
->dwMinorVersion
=0;
1720 c
->dwBuildNumber
=0x4000457;
1722 // leave it here for testing win9x-only codecs
1723 c
->dwPlatformId
=VER_PLATFORM_WIN32_WINDOWS
;
1724 strcpy(c
->szCSDVersion
, " B");
1726 c
->dwPlatformId
=VER_PLATFORM_WIN32_NT
; // let's not make DLL assume that it can read CR* registers
1727 strcpy(c
->szCSDVersion
, "Service Pack 3");
1729 dbgprintf(" Major version: 4\n Minor version: 0\n Build number: 0x4000457\n"
1730 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 3'\n");
1733 static HANDLE WINAPI
expCreateSemaphoreA(char* v1
, long init_count
,
1734 long max_count
, char* name
)
1736 pthread_mutex_t
*pm
;
1740 printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1744 printf("%p => ", pp);
1751 mutex_list
* pp
=mlist
;
1755 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==1))
1757 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1758 v1
, init_count
, max_count
, name
, name
, mlist
);
1759 return (HANDLE
)mlist
;
1761 }while((pp
=pp
->prev
) != NULL
);
1763 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
1764 pthread_mutex_init(pm
, NULL
);
1765 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
1766 pthread_cond_init(pc
, NULL
);
1769 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1770 mlist
->next
=mlist
->prev
=NULL
;
1774 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1775 mlist
->next
->prev
=mlist
;
1776 mlist
->next
->next
=NULL
;
1778 // printf("new semaphore %p\n", mlist);
1780 mlist
->type
=1; /* Type Semaphore */
1785 mlist
->semaphore
=init_count
;
1787 strncpy(mlist
->name
, name
, 64);
1791 dbgprintf("ERROR::: CreateSemaphoreA failure\n");
1793 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1794 v1
, init_count
, max_count
, name
, name
, mlist
);
1796 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1797 v1
, init_count
, max_count
, mlist
);
1798 return (HANDLE
)mlist
;
1801 static long WINAPI
expReleaseSemaphore(long hsem
, long increment
, long* prev_count
)
1803 // The state of a semaphore object is signaled when its count
1804 // is greater than zero and nonsignaled when its count is equal to zero
1805 // Each time a waiting thread is released because of the semaphore's signaled
1806 // state, the count of the semaphore is decreased by one.
1807 mutex_list
*ml
= (mutex_list
*)hsem
;
1809 pthread_mutex_lock(ml
->pm
);
1810 if (prev_count
!= 0) *prev_count
= ml
->semaphore
;
1811 if (ml
->semaphore
== 0) pthread_cond_signal(ml
->pc
);
1812 ml
->semaphore
+= increment
;
1813 pthread_mutex_unlock(ml
->pm
);
1814 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1815 hsem
, increment
, prev_count
);
1820 static long WINAPI
expRegOpenKeyExA(long key
, const char* subkey
, long reserved
, long access
, int* newkey
)
1822 long result
=RegOpenKeyExA(key
, subkey
, reserved
, access
, newkey
);
1823 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
1824 key
, subkey
, reserved
, access
, newkey
, result
);
1825 if(newkey
)dbgprintf(" New key: 0x%x\n", *newkey
);
1828 static long WINAPI
expRegCloseKey(long key
)
1830 long result
=RegCloseKey(key
);
1831 dbgprintf("RegCloseKey(0x%x) => %d\n", key
, result
);
1834 static long WINAPI
expRegQueryValueExA(long key
, const char* value
, int* reserved
, int* type
, int* data
, int* count
)
1836 long result
=RegQueryValueExA(key
, value
, reserved
, type
, data
, count
);
1837 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
1838 " => 0x%x\n", key
, value
, reserved
, data
, count
, result
);
1839 if(data
&& count
)dbgprintf(" read %d bytes: '%s'\n", *count
, data
);
1843 //from wine source dlls/advapi32/registry.c
1844 static long WINAPI
expRegCreateKeyA(long hkey
, const char* name
, int *retkey
)
1846 dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey
,name
,retkey
);
1847 return RegCreateKeyExA( hkey
, name
, 0, NULL
,REG_OPTION_NON_VOLATILE
,
1848 KEY_ALL_ACCESS
, NULL
, retkey
, NULL
);
1851 static long WINAPI
expRegCreateKeyExA(long key
, const char* name
, long reserved
,
1852 void* classs
, long options
, long security
,
1853 void* sec_attr
, int* newkey
, int* status
)
1855 long result
=RegCreateKeyExA(key
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
);
1856 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
1857 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
1858 key
, name
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
, result
);
1859 if(!result
&& newkey
) dbgprintf(" New key: 0x%x\n", *newkey
);
1860 if(!result
&& status
) dbgprintf(" New key status: 0x%x\n", *status
);
1863 static long WINAPI
expRegSetValueExA(long key
, const char* name
, long v1
, long v2
, void* data
, long size
)
1865 long result
=RegSetValueExA(key
, name
, v1
, v2
, data
, size
);
1866 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
1867 key
, name
, v1
, v2
, data
, *(int*)data
, data
, size
, result
);
1871 static long WINAPI
expRegOpenKeyA (long hKey
, LPCSTR lpSubKey
, int* phkResult
)
1873 long result
=RegOpenKeyExA(hKey
, lpSubKey
, 0, 0, phkResult
);
1874 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
1875 hKey
, lpSubKey
, phkResult
, result
);
1876 if(!result
&& phkResult
) dbgprintf(" New key: 0x%x\n", *phkResult
);
1880 static DWORD WINAPI
expRegEnumValueA(HKEY hkey
, DWORD index
, LPSTR value
, LPDWORD val_count
,
1881 LPDWORD reserved
, LPDWORD type
, LPBYTE data
, LPDWORD count
)
1883 return RegEnumValueA(hkey
, index
, value
, val_count
,
1884 reserved
, type
, data
, count
);
1887 static DWORD WINAPI
expRegEnumKeyExA(HKEY hKey
, DWORD dwIndex
, LPSTR lpName
, LPDWORD lpcbName
,
1888 LPDWORD lpReserved
, LPSTR lpClass
, LPDWORD lpcbClass
,
1889 LPFILETIME lpftLastWriteTime
)
1891 return RegEnumKeyExA(hKey
, dwIndex
, lpName
, lpcbName
, lpReserved
, lpClass
,
1892 lpcbClass
, lpftLastWriteTime
);
1895 static long WINAPI
expQueryPerformanceCounter(long long* z
)
1898 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z
, *z
);
1903 * dummy function RegQueryInfoKeyA(), required by vss codecs
1905 static DWORD WINAPI
expRegQueryInfoKeyA( HKEY hkey
, LPSTR
class, LPDWORD class_len
, LPDWORD reserved
,
1906 LPDWORD subkeys
, LPDWORD max_subkey
, LPDWORD max_class
,
1907 LPDWORD values
, LPDWORD max_value
, LPDWORD max_data
,
1908 LPDWORD security
, FILETIME
*modif
)
1910 return ERROR_SUCCESS
;
1914 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
1916 static double linux_cpuinfo_freq(void)
1923 f
= fopen ("/proc/cpuinfo", "r");
1925 while (fgets(line
,sizeof(line
),f
)!=NULL
) {
1926 /* NOTE: the ':' is the only character we can rely on */
1927 if (!(value
= strchr(line
,':')))
1929 /* terminate the valuename */
1931 /* skip any leading spaces */
1932 while (*value
==' ') value
++;
1933 if ((s
=strchr(value
,'\n')))
1936 if (!strncasecmp(line
, "cpu MHz",strlen("cpu MHz"))
1937 && sscanf(value
, "%lf", &freq
) == 1) {
1948 static double solaris_kstat_freq(void)
1950 #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
1952 * try to extract the CPU speed from the solaris kernel's kstat data
1956 kstat_named_t
*kdata
;
1962 ksp
= kstat_lookup(kc
, "cpu_info", 0, "cpu_info0");
1964 /* kstat found and name/value pairs? */
1965 if (ksp
!= NULL
&& ksp
->ks_type
== KSTAT_TYPE_NAMED
)
1967 /* read the kstat data from the kernel */
1968 if (kstat_read(kc
, ksp
, NULL
) != -1)
1971 * lookup desired "clock_MHz" entry, check the expected
1974 kdata
= (kstat_named_t
*)kstat_data_lookup(ksp
, "clock_MHz");
1975 if (kdata
!= NULL
&& kdata
->data_type
== KSTAT_DATA_INT32
)
1976 mhz
= kdata
->value
.i32
;
1984 #endif /* HAVE_LIBKSTAT */
1985 return -1; // kstat stuff is not available, CPU freq is unknown
1989 * Measure CPU freq using the pentium's time stamp counter register (TSC)
1991 static double tsc_freq(void)
1993 static double ofreq
=0.0;
1997 if (ofreq
!= 0.0) return ofreq
;
1998 while(i
==time(NULL
));
2001 while(i
==time(NULL
));
2003 ofreq
= (double)(y
-x
)/1000.;
2007 static double CPU_Freq(void)
2011 if ((freq
= linux_cpuinfo_freq()) > 0)
2014 if ((freq
= solaris_kstat_freq()) > 0)
2020 static long WINAPI
expQueryPerformanceFrequency(long long* z
)
2022 *z
=(long long)CPU_Freq();
2023 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z
, *z
);
2026 static long WINAPI
exptimeGetTime(void)
2030 gettimeofday(&t
, 0);
2031 result
=1000*t
.tv_sec
+t
.tv_usec
/1000;
2032 dbgprintf("timeGetTime() => %d\n", result
);
2035 static void* WINAPI
expLocalHandle(void* v
)
2037 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v
, v
);
2041 static void* WINAPI
expGlobalHandle(void* v
)
2043 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v
, v
);
2046 static int WINAPI
expGlobalUnlock(void* v
)
2048 dbgprintf("GlobalUnlock(0x%x) => 1\n", v
);
2051 static void* WINAPI
expGlobalFree(void* v
)
2053 dbgprintf("GlobalFree(0x%x) => 0\n", v
);
2059 static void* WINAPI
expGlobalReAlloc(void* v
, int size
, int flags
)
2061 void* result
=my_realloc(v
, size
);
2062 //void* result=realloc(v, size);
2063 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v
,size
,flags
,result
);
2067 static int WINAPI
expLocalUnlock(void* v
)
2069 dbgprintf("LocalUnlock(0x%x) => 1\n", v
);
2073 static void* WINAPI
expLocalFree(void* v
)
2075 dbgprintf("LocalFree(0x%x) => 0\n", v
);
2079 static HRSRC WINAPI
expFindResourceA(HMODULE module
, char* name
, char* type
)
2083 result
=FindResourceA(module
, name
, type
);
2084 dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2085 module
, name
, HIWORD(name
) ? name
: "UNICODE", type
, HIWORD(type
) ? type
: "UNICODE", result
);
2089 static HGLOBAL WINAPI
expLoadResource(HMODULE module
, HRSRC res
)
2091 HGLOBAL result
=LoadResource(module
, res
);
2092 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module
, res
, result
);
2095 static void* WINAPI
expLockResource(long res
)
2097 void* result
=LockResource(res
);
2098 dbgprintf("LockResource(0x%x) => 0x%x\n", res
, result
);
2101 static int WINAPI
expFreeResource(long res
)
2103 int result
=FreeResource(res
);
2104 dbgprintf("FreeResource(0x%x) => %d\n", res
, result
);
2109 static int WINAPI
expCloseHandle(long v1
)
2111 dbgprintf("CloseHandle(0x%x) => 1\n", v1
);
2112 /* do not close stdin,stdout and stderr */
2119 static const char* WINAPI
expGetCommandLineA(void)
2121 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2122 return "c:\\aviplay.exe";
2124 static short envs
[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2125 static LPWSTR WINAPI
expGetEnvironmentStringsW(void)
2127 dbgprintf("GetEnvironmentStringsW() => 0\n", envs
);
2130 static void * WINAPI
expRtlZeroMemory(void *p
, size_t len
)
2132 void* result
=memset(p
,0,len
);
2133 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p
,len
,result
);
2136 static void * WINAPI
expRtlMoveMemory(void *dst
, void *src
, size_t len
)
2138 void* result
=memmove(dst
,src
,len
);
2139 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst
,src
,len
,result
);
2143 static void * WINAPI
expRtlFillMemory(void *p
, int ch
, size_t len
)
2145 void* result
=memset(p
,ch
,len
);
2146 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p
,ch
,len
,result
);
2149 static int WINAPI
expFreeEnvironmentStringsW(short* strings
)
2151 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings
);
2154 static int WINAPI
expFreeEnvironmentStringsA(char* strings
)
2156 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings
);
2160 static const char ch_envs
[]=
2161 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2162 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2163 static LPCSTR WINAPI
expGetEnvironmentStrings(void)
2165 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs
);
2166 return (LPCSTR
)ch_envs
;
2167 // dbgprintf("GetEnvironmentStrings() => 0\n");
2171 static int WINAPI
expGetStartupInfoA(STARTUPINFOA
*s
)
2173 dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2174 memset(s
, 0, sizeof(*s
));
2176 // s->lpReserved="Reserved";
2177 // s->lpDesktop="Desktop";
2178 // s->lpTitle="Title";
2180 // s->dwXSize=s->dwYSize=200;
2181 s
->dwFlags
=s
->wShowWindow
=1;
2182 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2183 dbgprintf(" cb=%d\n", s
->cb
);
2184 dbgprintf(" lpReserved='%s'\n", s
->lpReserved
);
2185 dbgprintf(" lpDesktop='%s'\n", s
->lpDesktop
);
2186 dbgprintf(" lpTitle='%s'\n", s
->lpTitle
);
2187 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2188 s
->dwX
, s
->dwY
, s
->dwXSize
, s
->dwYSize
);
2189 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2190 s
->dwXCountChars
, s
->dwYCountChars
, s
->dwFillAttribute
);
2191 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2192 s
->dwFlags
, s
->wShowWindow
, s
->cbReserved2
);
2193 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2194 s
->lpReserved2
, s
->hStdInput
, s
->hStdOutput
, s
->hStdError
);
2198 static int WINAPI
expGetStdHandle(int z
)
2200 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z
+0x1234);
2205 #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2206 #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2209 static int WINAPI
expGetFileType(int handle
)
2211 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle
);
2215 static int WINAPI
expGetFileAttributesA(char *filename
)
2217 dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename
);
2218 if (strstr(filename
, "QuickTime.qts"))
2219 return FILE_ATTRIBUTE_SYSTEM
;
2220 return FILE_ATTRIBUTE_NORMAL
;
2223 static int WINAPI
expSetHandleCount(int count
)
2225 dbgprintf("SetHandleCount(0x%x) => 1\n", count
);
2228 static int WINAPI
expGetACP(void)
2230 dbgprintf("GetACP() => 0\n");
2233 static int WINAPI
expGetModuleFileNameA(int module
, char* s
, int len
)
2237 //printf("File name of module %X (%s) requested\n", module, s);
2239 if (module
== 0 && len
>= 12)
2241 /* return caller program name */
2242 strcpy(s
, "aviplay.dll");
2253 strcpy(s
, "c:\\windows\\system\\");
2254 mr
=MODULE32_LookupHMODULE(module
);
2256 strcat(s
, "aviplay.dll");
2258 if(strrchr(mr
->filename
, '/')==NULL
)
2259 strcat(s
, mr
->filename
);
2261 strcat(s
, strrchr(mr
->filename
, '/')+1);
2264 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2265 module
, s
, len
, result
);
2267 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2268 module
, s
, len
, result
, s
);
2272 static int WINAPI
expSetUnhandledExceptionFilter(void* filter
)
2274 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter
);
2275 return 1;//unsupported and probably won't ever be supported
2278 static int WINAPI
expLoadLibraryA(char* name
)
2284 // we skip to the last backslash
2285 // this is effectively eliminating weird characters in
2286 // the text output windows
2288 lastbc
= strrchr(name
, '\\');
2295 name
[i
] = *lastbc
++;
2300 if(strncmp(name
, "c:\\windows\\", 11)==0) name
+= 11;
2301 if(strncmp(name
, ".\\", 2)==0) name
+= 2;
2303 dbgprintf("Entering LoadLibraryA(%s)\n", name
);
2305 // PIMJ and VIVO audio are loading kernel32.dll
2306 if (strcasecmp(name
, "kernel32.dll") == 0 || strcasecmp(name
, "kernel32") == 0)
2307 return MODULE_HANDLE_kernel32
;
2308 // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2309 /* exported -> do not return failed! */
2311 if (strcasecmp(name
, "user32.dll") == 0 || strcasecmp(name
, "user32") == 0)
2312 // return MODULE_HANDLE_kernel32;
2313 return MODULE_HANDLE_user32
;
2316 if (strcasecmp(name
, "wininet.dll") == 0 || strcasecmp(name
, "wininet") == 0)
2317 return MODULE_HANDLE_wininet
;
2318 if (strcasecmp(name
, "ddraw.dll") == 0 || strcasecmp(name
, "ddraw") == 0)
2319 return MODULE_HANDLE_ddraw
;
2320 if (strcasecmp(name
, "advapi32.dll") == 0 || strcasecmp(name
, "advapi32") == 0)
2321 return MODULE_HANDLE_advapi32
;
2324 if (strcasecmp(name
, "comdlg32.dll") == 0 || strcasecmp(name
, "comdlg32") == 0)
2325 return MODULE_HANDLE_comdlg32
;
2326 if (strcasecmp(name
, "msvcrt.dll") == 0 || strcasecmp(name
, "msvcrt") == 0)
2327 return MODULE_HANDLE_msvcrt
;
2328 if (strcasecmp(name
, "ole32.dll") == 0 || strcasecmp(name
, "ole32") == 0)
2329 return MODULE_HANDLE_ole32
;
2330 if (strcasecmp(name
, "winmm.dll") == 0 || strcasecmp(name
, "winmm") == 0)
2331 return MODULE_HANDLE_winmm
;
2333 result
=LoadLibraryA(name
);
2334 dbgprintf("Returned LoadLibraryA(0x%x='%s'), def_path=%s => 0x%x\n", name
, name
, def_path
, result
);
2339 static int WINAPI
expFreeLibrary(int module
)
2342 int result
=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2344 int result
=FreeLibrary(module
);
2346 dbgprintf("FreeLibrary(0x%x) => %d\n", module
, result
);
2350 static void* WINAPI
expGetProcAddress(HMODULE mod
, char* name
)
2354 case MODULE_HANDLE_kernel32
:
2355 result
=LookupExternalByName("kernel32.dll", name
); break;
2356 case MODULE_HANDLE_user32
:
2357 result
=LookupExternalByName("user32.dll", name
); break;
2359 case MODULE_HANDLE_wininet
:
2360 result
=LookupExternalByName("wininet.dll", name
); break;
2361 case MODULE_HANDLE_ddraw
:
2362 result
=LookupExternalByName("ddraw.dll", name
); break;
2363 case MODULE_HANDLE_advapi32
:
2364 result
=LookupExternalByName("advapi32.dll", name
); break;
2366 case MODULE_HANDLE_comdlg32
:
2367 result
=LookupExternalByName("comdlg32.dll", name
); break;
2368 case MODULE_HANDLE_msvcrt
:
2369 result
=LookupExternalByName("msvcrt.dll", name
); break;
2370 case MODULE_HANDLE_ole32
:
2371 result
=LookupExternalByName("ole32.dll", name
); break;
2372 case MODULE_HANDLE_winmm
:
2373 result
=LookupExternalByName("winmm.dll", name
); break;
2375 result
=GetProcAddress(mod
, name
);
2377 if((unsigned int)name
> 0xffff)
2378 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod
, name
, result
);
2380 dbgprintf("GetProcAddress(0x%x, '%d') => 0x%x\n", mod
, (int)name
, result
);
2384 static long WINAPI
expCreateFileMappingA(int hFile
, void* lpAttr
,
2385 long flProtect
, long dwMaxHigh
,
2386 long dwMaxLow
, const char* name
)
2388 long result
=CreateFileMappingA(hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
);
2390 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2391 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2392 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, result
);
2394 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2395 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2396 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
, name
, result
);
2400 static long WINAPI
expOpenFileMappingA(long hFile
, long hz
, const char* name
)
2402 long result
=OpenFileMappingA(hFile
, hz
, name
);
2404 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2407 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2408 hFile
, hz
, name
, name
, result
);
2412 static void* WINAPI
expMapViewOfFile(HANDLE file
, DWORD mode
, DWORD offHigh
,
2413 DWORD offLow
, DWORD size
)
2415 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2416 file
,mode
,offHigh
,offLow
,size
,(char*)file
+offLow
);
2417 return (char*)file
+offLow
;
2420 static void* WINAPI
expUnmapViewOfFile(void* view
)
2422 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view
);
2426 static void* WINAPI
expSleep(int time
)
2429 /* solaris doesn't have thread safe usleep */
2430 struct timespec tsp
;
2431 tsp
.tv_sec
= time
/ 1000000;
2432 tsp
.tv_nsec
= (time
% 1000000) * 1000;
2433 nanosleep(&tsp
, NULL
);
2437 dbgprintf("Sleep(%d) => 0\n", time
);
2441 // why does IV32 codec want to call this? I don't know ...
2442 static int WINAPI
expCreateCompatibleDC(int hdc
)
2445 //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2446 dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc
, dc
);
2450 static int WINAPI
expGetDeviceCaps(int hdc
, int unk
)
2452 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc
, unk
);
2454 #define BITSPIXEL 12
2456 if (unk
== BITSPIXEL
)
2464 static WIN_BOOL WINAPI
expDeleteDC(int hdc
)
2466 dbgprintf("DeleteDC(0x%x) => 0\n", hdc
);
2472 static WIN_BOOL WINAPI
expDeleteObject(int hdc
)
2474 dbgprintf("DeleteObject(0x%x) => 1\n", hdc
);
2475 /* FIXME - implement code here */
2479 /* btvvc32.drv wants this one */
2480 static void* WINAPI
expGetWindowDC(int hdc
)
2482 dbgprintf("GetWindowDC(%d) => 0x0\n", hdc
);
2487 static int WINAPI
expGetWindowRect(HWND win
, RECT
*r
)
2489 dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win
, r
);
2490 /* (win == 0) => desktop */
2491 r
->right
= PSEUDO_SCREEN_WIDTH
;
2493 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
2498 static int WINAPI
expMonitorFromWindow(HWND win
, int flags
)
2500 dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win
, flags
);
2504 static int WINAPI
expMonitorFromRect(RECT
*r
, int flags
)
2506 dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r
, flags
);
2510 static int WINAPI
expMonitorFromPoint(void *p
, int flags
)
2512 dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p
, flags
);
2516 static int WINAPI
expEnumDisplayMonitors(void *dc
, RECT
*r
,
2517 int WINAPI (*callback_proc
)(), void *callback_param
)
2519 dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2520 dc
, r
, callback_proc
, callback_param
);
2521 return callback_proc(0, dc
, r
, callback_param
);
2525 typedef struct tagMONITORINFO
{
2530 } MONITORINFO
, *LPMONITORINFO
;
2533 #define CCHDEVICENAME 8
2534 typedef struct tagMONITORINFOEX
{
2539 TCHAR szDevice
[CCHDEVICENAME
];
2540 } MONITORINFOEX
, *LPMONITORINFOEX
;
2542 static int WINAPI
expGetMonitorInfoA(void *mon
, LPMONITORINFO lpmi
)
2544 dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon
, lpmi
);
2546 lpmi
->rcMonitor
.right
= lpmi
->rcWork
.right
= PSEUDO_SCREEN_WIDTH
;
2547 lpmi
->rcMonitor
.left
= lpmi
->rcWork
.left
= 0;
2548 lpmi
->rcMonitor
.bottom
= lpmi
->rcWork
.bottom
= PSEUDO_SCREEN_HEIGHT
;
2549 lpmi
->rcMonitor
.top
= lpmi
->rcWork
.top
= 0;
2551 lpmi
->dwFlags
= 1; /* primary monitor */
2553 if (lpmi
->cbSize
== sizeof(MONITORINFOEX
))
2555 LPMONITORINFOEX lpmiex
= (LPMONITORINFOEX
)lpmi
;
2556 dbgprintf("MONITORINFOEX!\n");
2557 strncpy(lpmiex
->szDevice
, "Monitor1", CCHDEVICENAME
);
2563 static int WINAPI
expEnumDisplayDevicesA(const char *device
, int devnum
,
2564 void *dispdev
, int flags
)
2566 dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2567 device
, device
, devnum
, dispdev
, flags
);
2571 static int WINAPI
expIsWindowVisible(HWND win
)
2573 dbgprintf("IsWindowVisible(0x%x) => 1\n", win
);
2577 static HWND WINAPI
expGetActiveWindow(void)
2579 dbgprintf("GetActiveWindow() => 0\n");
2583 static int WINAPI
expGetClassNameA(HWND win
, LPTSTR classname
, int maxcount
)
2585 strncat(classname
, "QuickTime", maxcount
);
2586 dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2587 win
, classname
, maxcount
, strlen(classname
));
2588 return strlen(classname
);
2591 #define LPWNDCLASS void *
2592 static int WINAPI
expGetClassInfoA(HINSTANCE inst
, LPCSTR classname
, LPWNDCLASS wndclass
)
2594 dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst
,
2595 classname
, classname
, wndclass
);
2599 static int WINAPI
expGetWindowLongA(HWND win
, int index
)
2601 dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win
, index
);
2605 static int WINAPI
expGetObjectA(HGDIOBJ hobj
, int objsize
, LPVOID obj
)
2607 dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj
, objsize
, obj
, objsize
);
2611 static int WINAPI
expCreateRectRgn(int x
, int y
, int width
, int height
)
2613 dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x
, y
, width
, height
);
2617 static int WINAPI
expEnumWindows(int (*callback_func
)(), void *callback_param
)
2620 dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func
, callback_param
);
2621 i
= callback_func(0, callback_param
);
2622 i2
= callback_func(1, callback_param
);
2626 static int WINAPI
expGetWindowThreadProcessId(HWND win
, int *pid_data
)
2628 int tid
= pthread_self();
2629 dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2630 win
, pid_data
, tid
);
2632 *(int*)pid_data
= tid
;
2636 //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2637 // INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2639 static HWND WINAPI
expCreateWindowExA(int exstyle
, const char *classname
,
2640 const char *winname
, int style
, int x
, int y
, int w
, int h
,
2641 HWND parent
, HMENU menu
, HINSTANCE inst
, LPVOID param
)
2643 printf("CreateWindowEx() called\n");
2644 dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2645 exstyle
, classname
, classname
, winname
, winname
, style
, x
, y
, w
, h
,
2646 parent
, menu
, inst
, param
);
2647 printf("CreateWindowEx() called okey\n");
2651 static int WINAPI
expwaveOutGetNumDevs(void)
2653 dbgprintf("waveOutGetNumDevs() => 0\n");
2659 * Returns the number of milliseconds, modulo 2^32, since the start
2660 * of the wineserver.
2662 static int WINAPI
expGetTickCount(void)
2664 static int tcstart
= 0;
2667 gettimeofday( &t
, NULL
);
2668 tc
= ((t
.tv_sec
* 1000) + (t
.tv_usec
/ 1000)) - tcstart
;
2674 dbgprintf("GetTickCount() => %d\n", tc
);
2678 static int WINAPI
expCreateFontA(void)
2680 dbgprintf("CreateFontA() => 0x0\n");
2684 /* tried to get pvmjpg work in a different way - no success */
2685 static int WINAPI
expDrawTextA(int hDC
, char* lpString
, int nCount
,
2686 LPRECT lpRect
, unsigned int uFormat
)
2688 dbgprintf("expDrawTextA(%p,...) => 8\n", hDC
);
2692 static int WINAPI
expGetPrivateProfileIntA(const char* appname
,
2693 const char* keyname
,
2695 const char* filename
)
2703 if(!(appname
&& keyname
&& filename
) )
2705 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, default_value
);
2706 return default_value
;
2708 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2709 strcpy(fullname
, "Software\\IniFileMapping\\");
2710 strcat(fullname
, appname
);
2711 strcat(fullname
, "\\");
2712 strcat(fullname
, keyname
);
2713 strcat(fullname
, "\\");
2714 strcat(fullname
, filename
);
2715 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)buffer
, &size
);
2716 if((size
>=0)&&(size
<256))
2718 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2721 result
=default_value
;
2723 result
=atoi(buffer
);
2724 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, result
);
2727 static int WINAPI
expGetProfileIntA(const char* appname
,
2728 const char* keyname
,
2731 dbgprintf("GetProfileIntA -> ");
2732 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, "default");
2735 static int WINAPI
expGetPrivateProfileStringA(const char* appname
,
2736 const char* keyname
,
2737 const char* def_val
,
2738 char* dest
, unsigned int len
,
2739 const char* filename
)
2744 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname
, keyname
, def_val
, dest
, len
, filename
);
2745 if(!(appname
&& keyname
&& filename
) ) return 0;
2746 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2747 strcpy(fullname
, "Software\\IniFileMapping\\");
2748 strcat(fullname
, appname
);
2749 strcat(fullname
, "\\");
2750 strcat(fullname
, keyname
);
2751 strcat(fullname
, "\\");
2752 strcat(fullname
, filename
);
2754 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)dest
, &size
);
2758 strncpy(dest
, def_val
, size
);
2759 if (strlen(def_val
)< size
) size
= strlen(def_val
);
2761 dbgprintf(" => %d ( '%s' )\n", size
, dest
);
2764 static int WINAPI
expWritePrivateProfileStringA(const char* appname
,
2765 const char* keyname
,
2767 const char* filename
)
2770 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname
, keyname
, string
, filename
);
2771 if(!(appname
&& keyname
&& filename
) )
2773 dbgprintf(" => -1\n");
2776 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2777 strcpy(fullname
, "Software\\IniFileMapping\\");
2778 strcat(fullname
, appname
);
2779 strcat(fullname
, "\\");
2780 strcat(fullname
, keyname
);
2781 strcat(fullname
, "\\");
2782 strcat(fullname
, filename
);
2783 RegSetValueExA(HKEY_LOCAL_MACHINE
, fullname
, 0, REG_SZ
, (int*)string
, strlen(string
));
2784 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
2785 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
2787 dbgprintf(" => 0\n");
2791 unsigned int GetPrivateProfileIntA_(const char* appname
, const char* keyname
, INT default_value
, const char* filename
)
2793 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, filename
);
2795 int GetPrivateProfileStringA_(const char* appname
, const char* keyname
,
2796 const char* def_val
, char* dest
, unsigned int len
, const char* filename
)
2798 return expGetPrivateProfileStringA(appname
, keyname
, def_val
, dest
, len
, filename
);
2800 int WritePrivateProfileStringA_(const char* appname
, const char* keyname
,
2801 const char* string
, const char* filename
)
2803 return expWritePrivateProfileStringA(appname
, keyname
, string
, filename
);
2808 static int WINAPI
expDefDriverProc(int private, int id
, int msg
, int arg1
, int arg2
)
2810 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", private, id
, msg
, arg1
, arg2
);
2814 static int WINAPI
expSizeofResource(int v1
, int v2
)
2816 int result
=SizeofResource(v1
, v2
);
2817 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1
, v2
, result
);
2821 static int WINAPI
expGetLastError(void)
2823 int result
=GetLastError();
2824 dbgprintf("GetLastError() => 0x%x\n", result
);
2828 static void WINAPI
expSetLastError(int error
)
2830 dbgprintf("SetLastError(0x%x)\n", error
);
2831 SetLastError(error
);
2834 static int WINAPI
expStringFromGUID2(GUID
* guid
, char* str
, int cbMax
)
2836 int result
=snprintf(str
, cbMax
, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
2837 guid
->f1
, guid
->f2
, guid
->f3
,
2838 (unsigned char)guid
->f4
[0], (unsigned char)guid
->f4
[1],
2839 (unsigned char)guid
->f4
[2], (unsigned char)guid
->f4
[3],
2840 (unsigned char)guid
->f4
[4], (unsigned char)guid
->f4
[5],
2841 (unsigned char)guid
->f4
[6], (unsigned char)guid
->f4
[7]);
2842 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid
, str
, str
, cbMax
, result
);
2847 static int WINAPI
expGetFileVersionInfoSizeA(const char* name
, int* lpHandle
)
2849 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name
, name
, lpHandle
);
2853 static int WINAPI
expIsBadStringPtrW(const short* string
, int nchars
)
2856 if(string
==0)result
=1; else result
=0;
2857 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string
, nchars
, result
);
2858 if(string
)wch_print(string
);
2861 static int WINAPI
expIsBadStringPtrA(const char* string
, int nchars
)
2863 return expIsBadStringPtrW((const short*)string
, nchars
);
2865 static long WINAPI
expInterlockedExchangeAdd( long* dest
, long incr
)
2870 "lock; xaddl %0,(%1)"
2872 : "r" (dest
), "0" (incr
)
2878 static long WINAPI
expInterlockedCompareExchange( unsigned long* dest
, unsigned long exchange
, unsigned long comperand
)
2880 unsigned long retval
= *dest
;
2881 if(*dest
== comperand
)
2886 static long WINAPI
expInterlockedIncrement( long* dest
)
2888 long result
=expInterlockedExchangeAdd( dest
, 1 ) + 1;
2889 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
2892 static long WINAPI
expInterlockedDecrement( long* dest
)
2894 long result
=expInterlockedExchangeAdd( dest
, -1 ) - 1;
2895 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
2899 static void WINAPI
expOutputDebugStringA( const char* string
)
2901 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string
);
2902 fprintf(stderr
, "DEBUG: %s\n", string
);
2905 static int WINAPI
expGetDC(int hwnd
)
2907 dbgprintf("GetDC(0x%x) => 1\n", hwnd
);
2911 static int WINAPI
expReleaseDC(int hwnd
, int hdc
)
2913 dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd
, hdc
);
2917 static int WINAPI
expGetDesktopWindow(void)
2919 dbgprintf("GetDesktopWindow() => 0\n");
2923 static int cursor
[100];
2925 static int WINAPI
expLoadCursorA(int handle
,LPCSTR name
)
2927 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle
, name
, (int)&cursor
[0]);
2928 return (int)&cursor
[0];
2930 static int WINAPI
expSetCursor(void *cursor
)
2932 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor
, cursor
);
2935 static int WINAPI
expGetCursorPos(void *cursor
)
2937 dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor
, cursor
);
2941 static int show_cursor
= 0;
2942 static int WINAPI
expShowCursor(int show
)
2944 dbgprintf("ShowCursor(%d) => %d\n", show
, show
);
2952 static int WINAPI
expRegisterWindowMessageA(char *message
)
2954 dbgprintf("RegisterWindowMessageA(%s)\n", message
);
2957 static int WINAPI
expGetProcessVersion(int pid
)
2959 dbgprintf("GetProcessVersion(%d)\n", pid
);
2962 static int WINAPI
expGetCurrentThread(void)
2965 dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
2968 static int WINAPI
expGetOEMCP(void)
2970 dbgprintf("GetOEMCP()\n");
2973 static int WINAPI
expGetCPInfo(int cp
,void *info
)
2975 dbgprintf("GetCPInfo()\n");
2979 #define SM_CXSCREEN 0
2980 #define SM_CYSCREEN 1
2981 #define SM_XVIRTUALSCREEN 76
2982 #define SM_YVIRTUALSCREEN 77
2983 #define SM_CXVIRTUALSCREEN 78
2984 #define SM_CYVIRTUALSCREEN 79
2985 #define SM_CMONITORS 80
2987 static int WINAPI
expGetSystemMetrics(int index
)
2989 dbgprintf("GetSystemMetrics(%d)\n", index
);
2993 case SM_XVIRTUALSCREEN
:
2994 case SM_YVIRTUALSCREEN
:
2997 case SM_CXVIRTUALSCREEN
:
2998 return PSEUDO_SCREEN_WIDTH
;
3000 case SM_CYVIRTUALSCREEN
:
3001 return PSEUDO_SCREEN_HEIGHT
;
3008 static int WINAPI
expGetSysColor(int index
)
3010 dbgprintf("GetSysColor(%d) => 1\n", index
);
3013 static int WINAPI
expGetSysColorBrush(int index
)
3015 dbgprintf("GetSysColorBrush(%d)\n", index
);
3021 static int WINAPI
expGetSystemPaletteEntries(int hdc
, int iStartIndex
, int nEntries
, void* lppe
)
3023 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3024 hdc
, iStartIndex
, nEntries
, lppe
);
3029 typedef struct TIME_ZONE_INFORMATION {
3031 char StandardName[32];
3032 SYSTEMTIME StandardDate;
3034 char DaylightName[32];
3035 SYSTEMTIME DaylightDate;
3037 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3040 static int WINAPI
expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation
)
3042 const short name
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3043 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3044 const short pname
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3045 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3046 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3047 memset(lpTimeZoneInformation
, 0, sizeof(TIME_ZONE_INFORMATION
));
3048 lpTimeZoneInformation
->Bias
=360;//GMT-6
3049 memcpy(lpTimeZoneInformation
->StandardName
, name
, sizeof(name
));
3050 lpTimeZoneInformation
->StandardDate
.wMonth
=10;
3051 lpTimeZoneInformation
->StandardDate
.wDay
=5;
3052 lpTimeZoneInformation
->StandardDate
.wHour
=2;
3053 lpTimeZoneInformation
->StandardBias
=0;
3054 memcpy(lpTimeZoneInformation
->DaylightName
, pname
, sizeof(pname
));
3055 lpTimeZoneInformation
->DaylightDate
.wMonth
=4;
3056 lpTimeZoneInformation
->DaylightDate
.wDay
=1;
3057 lpTimeZoneInformation
->DaylightDate
.wHour
=2;
3058 lpTimeZoneInformation
->DaylightBias
=-60;
3059 return TIME_ZONE_ID_STANDARD
;
3062 static void WINAPI
expGetLocalTime(SYSTEMTIME
* systime
)
3065 struct tm
*local_tm
;
3068 dbgprintf("GetLocalTime(0x%x)\n");
3069 gettimeofday(&tv
, NULL
);
3070 local_time
=tv
.tv_sec
;
3071 local_tm
=localtime(&local_time
);
3073 systime
->wYear
= local_tm
->tm_year
+ 1900;
3074 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3075 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3076 systime
->wDay
= local_tm
->tm_mday
;
3077 systime
->wHour
= local_tm
->tm_hour
;
3078 systime
->wMinute
= local_tm
->tm_min
;
3079 systime
->wSecond
= local_tm
->tm_sec
;
3080 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3081 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3082 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3083 " Milliseconds: %d\n",
3084 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3085 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3088 static int WINAPI
expGetSystemTime(SYSTEMTIME
* systime
)
3091 struct tm
*local_tm
;
3094 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3095 gettimeofday(&tv
, NULL
);
3096 local_time
=tv
.tv_sec
;
3097 local_tm
=gmtime(&local_time
);
3099 systime
->wYear
= local_tm
->tm_year
+ 1900;
3100 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3101 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3102 systime
->wDay
= local_tm
->tm_mday
;
3103 systime
->wHour
= local_tm
->tm_hour
;
3104 systime
->wMinute
= local_tm
->tm_min
;
3105 systime
->wSecond
= local_tm
->tm_sec
;
3106 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3107 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3108 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3109 " Milliseconds: %d\n",
3110 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3111 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3115 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3116 static void WINAPI
expGetSystemTimeAsFileTime(FILETIME
* systime
)
3119 unsigned long long secs
;
3121 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3122 gettimeofday(&tv
, NULL
);
3123 secs
= (tv
.tv_sec
+ SECS_1601_TO_1970
) * 10000000;
3124 secs
+= tv
.tv_usec
* 10;
3125 systime
->dwLowDateTime
= secs
& 0xffffffff;
3126 systime
->dwHighDateTime
= (secs
>> 32);
3129 static int WINAPI
expGetEnvironmentVariableA(const char* name
, char* field
, int size
)
3132 // printf("%s %x %x\n", name, field, size);
3133 if(field
)field
[0]=0;
3136 if (p) strncpy(field,p,size);
3138 if (strcmp(name
,"__MSVCRT_HEAP_SELECT")==0)
3139 strcpy(field
,"__GLOBAL_HEAP_SELECTED,1");
3140 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name
, name
, field
, size
, strlen(field
));
3141 return strlen(field
);
3144 static int WINAPI
expSetEnvironmentVariableA(const char *name
, const char *value
)
3146 dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name
, value
);
3150 static void* WINAPI
expCoTaskMemAlloc(ULONG cb
)
3152 return my_mreq(cb
, 0);
3154 static void WINAPI
expCoTaskMemFree(void* cb
)
3162 void* CoTaskMemAlloc(unsigned long cb
)
3164 return expCoTaskMemAlloc(cb
);
3166 void CoTaskMemFree(void* cb
)
3168 expCoTaskMemFree(cb
);
3171 struct COM_OBJECT_INFO
3174 long (*GetClassObject
) (GUID
* clsid
, const GUID
* iid
, void** ppv
);
3177 static struct COM_OBJECT_INFO
* com_object_table
=0;
3178 static int com_object_size
=0;
3179 int RegisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3183 com_object_table
=realloc(com_object_table
, sizeof(struct COM_OBJECT_INFO
)*(++com_object_size
));
3184 com_object_table
[com_object_size
-1].clsid
=*clsid
;
3185 com_object_table
[com_object_size
-1].GetClassObject
=gcs
;
3189 int UnregisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3196 if (com_object_table
== 0)
3197 printf("Warning: UnregisterComClass() called without any registered class\n");
3198 while (i
< com_object_size
)
3202 memcpy(&com_object_table
[i
- 1].clsid
,
3203 &com_object_table
[i
].clsid
, sizeof(GUID
));
3204 com_object_table
[i
- 1].GetClassObject
=
3205 com_object_table
[i
].GetClassObject
;
3207 else if (memcmp(&com_object_table
[i
].clsid
, clsid
, sizeof(GUID
)) == 0
3208 && com_object_table
[i
].GetClassObject
== gcs
)
3216 if (--com_object_size
== 0)
3218 free(com_object_table
);
3219 com_object_table
= 0;
3226 const GUID IID_IUnknown
=
3228 0x00000000, 0x0000, 0x0000,
3229 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3231 const GUID IID_IClassFactory
=
3233 0x00000001, 0x0000, 0x0000,
3234 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3237 static long WINAPI
expCoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3238 long dwClsContext
, const GUID
* riid
, void** ppv
)
3241 struct COM_OBJECT_INFO
* ci
=0;
3242 for(i
=0; i
<com_object_size
; i
++)
3243 if(!memcmp(rclsid
, &com_object_table
[i
].clsid
, sizeof(GUID
)))
3244 ci
=&com_object_table
[i
];
3245 if(!ci
)return REGDB_E_CLASSNOTREG
;
3246 // in 'real' world we should mess with IClassFactory here
3247 i
=ci
->GetClassObject(rclsid
, riid
, ppv
);
3251 long CoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3252 long dwClsContext
, const GUID
* riid
, void** ppv
)
3254 return expCoCreateInstance(rclsid
, pUnkOuter
, dwClsContext
, riid
, ppv
);
3257 static int WINAPI
expIsRectEmpty(CONST RECT
*lprc
)
3264 w
= lprc
->right
- lprc
->left
;
3265 h
= lprc
->bottom
- lprc
->top
;
3266 if (w
<= 0 || h
<= 0)
3272 dbgprintf("IsRectEmpty(%p) => %s\n", lprc
, (r
) ? "TRUE" : "FALSE");
3273 //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3274 // return 0; // wmv9?
3278 static int _adjust_fdiv
=0; //what's this? - used to adjust division
3279 static int _winver
= 0x510; // windows version
3284 static unsigned int WINAPI
expGetTempPathA(unsigned int len
, char* path
)
3286 dbgprintf("GetTempPathA(%d, 0x%x)", len
, path
);
3289 dbgprintf(" => 0\n");
3292 strcpy(path
, "/tmp");
3293 dbgprintf(" => 5 ( '/tmp' )\n");
3300 DWORD dwFileAttributes;
3301 FILETIME ftCreationTime;
3302 FILETIME ftLastAccessTime;
3303 FILETIME ftLastWriteTime;
3304 DWORD nFileSizeHigh;
3308 CHAR cFileName[260];
3309 CHAR cAlternateFileName[14];
3310 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3313 static DIR* qtx_dir
=NULL
;
3315 static WIN_BOOL WINAPI
expFindNextFileA(HANDLE h
,LPWIN32_FIND_DATAA lpfd
)
3318 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h
, lpfd
);
3319 if(h
==FILE_HANDLE_quicktimeqtx
){
3321 if(!qtx_dir
) return 0;
3322 while((d
=readdir(qtx_dir
))){
3323 char* x
=strrchr(d
->d_name
,'.');
3325 if(strcmp(x
,".qtx")) continue;
3326 strcpy(lpfd
->cFileName
,d
->d_name
);
3327 // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3328 strcpy(lpfd
->cAlternateFileName
,"foobar.qtx");
3329 dbgprintf("### FindNext: %s\n",lpfd
->cFileName
);
3332 closedir(qtx_dir
); qtx_dir
=NULL
;
3339 static HANDLE WINAPI
expFindFirstFileA(LPCSTR s
, LPWIN32_FIND_DATAA lpfd
)
3341 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s
, s
, lpfd
);
3342 // printf("\n### FindFirstFileA('%s')...\n",s);
3344 if(strstr(s
, "quicktime\\*.QTX")){
3345 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s
, s
, lpfd
);
3346 dbgprintf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",def_path
);
3347 qtx_dir
=opendir(def_path
);
3348 if(!qtx_dir
) return (HANDLE
)-1;
3349 memset(lpfd
,0,sizeof(*lpfd
));
3350 if(expFindNextFileA(FILE_HANDLE_quicktimeqtx
,lpfd
))
3351 return FILE_HANDLE_quicktimeqtx
;
3352 printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",def_path
);
3356 if(strstr(s
, "QuickTime.qts")){
3357 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s
, s
, lpfd
);
3358 // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3359 // return (HANDLE)-1;
3360 strcpy(lpfd
->cFileName
, "QuickTime.qts");
3361 strcpy(lpfd
->cAlternateFileName
, "QuickT~1.qts");
3362 return FILE_HANDLE_quicktimeqts
;
3366 if(strstr(s
, "*.vwp")){
3367 // hack for VoxWare codec plugins:
3368 strcpy(lpfd
->cFileName
, "msms001.vwp");
3369 strcpy(lpfd
->cAlternateFileName
, "msms001.vwp");
3372 // return 'file not found'
3376 static WIN_BOOL WINAPI
expFindClose(HANDLE h
)
3378 dbgprintf("FindClose(0x%x) => 0\n", h
);
3380 // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3381 // closedir(qtx_dir);
3387 static UINT WINAPI
expSetErrorMode(UINT i
)
3389 dbgprintf("SetErrorMode(%d) => 0\n", i
);
3392 static UINT WINAPI
expGetWindowsDirectoryA(LPSTR s
,UINT c
)
3394 char windir
[]="c:\\windows";
3396 strncpy(s
, windir
, c
);
3397 result
=1+((c
<strlen(windir
))?c
:strlen(windir
));
3398 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3402 static UINT WINAPI
expGetCurrentDirectoryA(UINT c
, LPSTR s
)
3404 char curdir
[]="c:\\";
3406 strncpy(s
, curdir
, c
);
3407 result
=1+((c
<strlen(curdir
))?c
:strlen(curdir
));
3408 dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3412 static int WINAPI
expSetCurrentDirectoryA(const char *pathname
)
3414 dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname
, pathname
);
3416 if (strrchr(pathname
, '\\'))
3417 chdir(strcat(strrchr(pathname
, '\\')+1, '/'));
3424 static int WINAPI
expCreateDirectoryA(const char *pathname
, void *sa
)
3426 dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3427 pathname
, pathname
, sa
);
3429 p
= strrchr(pathname
, '\\')+1;
3430 strcpy(&buf
[0], p
); /* should be strncpy */
3437 if (strrchr(pathname
, '\\'))
3438 mkdir(strcat(strrchr(pathname
, '\\')+1, '/'), 666);
3440 mkdir(pathname
, 666);
3447 static WIN_BOOL WINAPI
expDeleteFileA(LPCSTR s
)
3449 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s
, s
);
3452 static WIN_BOOL WINAPI
expFileTimeToLocalFileTime(const FILETIME
* cpf
, LPFILETIME pf
)
3454 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf
, pf
);
3458 static UINT WINAPI
expGetTempFileNameA(LPCSTR cs1
,LPCSTR cs2
,UINT i
,LPSTR ps
)
3460 char mask
[16]="/tmp/AP_XXXXXX";
3462 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1
, cs1
, cs2
, cs2
, i
, ps
);
3465 dbgprintf(" => -1\n");
3468 result
=mkstemp(mask
);
3469 sprintf(ps
, "AP%d", result
);
3470 dbgprintf(" => %d\n", strlen(ps
));
3474 // This func might need proper implementation if we want AngelPotion codec.
3475 // They try to open APmpeg4v1.apl with it.
3476 // DLL will close opened file with CloseHandle().
3478 static HANDLE WINAPI
expCreateFileA(LPCSTR cs1
,DWORD i1
,DWORD i2
,
3479 LPSECURITY_ATTRIBUTES p1
, DWORD i3
,DWORD i4
,HANDLE i5
)
3481 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1
, cs1
, i1
,
3482 i2
, p1
, i3
, i4
, i5
);
3483 if((!cs1
) || (strlen(cs1
)<2))return -1;
3486 if(strstr(cs1
, "QuickTime.qts"))
3489 char* tmp
=malloc(strlen(def_path
)+50);
3490 strcpy(tmp
, def_path
);
3492 strcat(tmp
, "QuickTime.qts");
3493 result
=open(tmp
, O_RDONLY
);
3497 if(strstr(cs1
, ".qtx"))
3500 char* tmp
=malloc(strlen(def_path
)+250);
3501 char* x
=strrchr(cs1
,'\\');
3502 sprintf(tmp
,"%s/%s",def_path
,x
?(x
+1):cs1
);
3503 // printf("### Open: %s -> %s\n",cs1,tmp);
3504 result
=open(tmp
, O_RDONLY
);
3510 if(strncmp(cs1
, "AP", 2) == 0)
3513 char* tmp
=malloc(strlen(def_path
)+50);
3514 strcpy(tmp
, def_path
);
3516 strcat(tmp
, "APmpg4v1.apl");
3517 result
=open(tmp
, O_RDONLY
);
3521 if (strstr(cs1
, "vp3") || strstr(cs1
, ".fpf"))
3525 char* tmp
=malloc(20 + strlen(cs1
));
3526 strcpy(tmp
, "/tmp/");
3531 if (tmp
[r
] == ':' || tmp
[r
] == '\\')
3535 if (GENERIC_READ
& i1
)
3537 else if (GENERIC_WRITE
& i1
)
3539 flg
|= O_WRONLY
| O_CREAT
;
3540 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp
, r
, flg
);
3542 r
=open(tmp
, flg
, S_IRWXU
);
3547 // Needed by wnvplay1.dll
3548 if (strstr(cs1
, "WINNOV.bmp"))
3551 r
=open("/dev/null", O_RDONLY
);
3556 /* we need this for some virtualdub filters */
3560 if (GENERIC_READ
& i1
)
3562 else if (GENERIC_WRITE
& i1
)
3565 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1
, r
, flg
);
3574 static UINT WINAPI
expGetSystemDirectoryA(
3575 char* lpBuffer
, // address of buffer for system directory
3576 UINT uSize
// size of directory buffer
3578 dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer
,uSize
);
3579 if(!lpBuffer
) strcpy(lpBuffer
,".");
3583 static char sysdir[]=".";
3584 static LPCSTR WINAPI expGetSystemDirectoryA(void)
3586 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3590 static DWORD WINAPI expGetFullPathNameA
3593 DWORD nBufferLength
,
3597 if(!lpFileName
) return 0;
3598 dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName
,nBufferLength
,
3599 lpBuffer
, lpFilePart
);
3602 strcpy(lpFilePart
, "Quick123.qts");
3604 strcpy(lpFilePart
, lpFileName
);
3607 if (strrchr(lpFileName
, '\\'))
3608 lpFilePart
= strrchr(lpFileName
, '\\');
3610 lpFilePart
= (LPTSTR
)lpFileName
;
3612 strcpy(lpBuffer
, lpFileName
);
3613 // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3614 return strlen(lpBuffer
);
3617 static DWORD WINAPI expGetShortPathNameA
3623 if(!longpath
) return 0;
3624 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath
,shortpath
,shortlen
);
3625 strcpy(shortpath
,longpath
);
3626 return strlen(shortpath
);
3629 static WIN_BOOL WINAPI
expReadFile(HANDLE h
,LPVOID pv
,DWORD size
,LPDWORD rd
,LPOVERLAPPED unused
)
3632 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, rd
);
3633 result
=read(h
, pv
, size
);
3635 if(!result
)return 0;
3639 static WIN_BOOL WINAPI
expWriteFile(HANDLE h
,LPCVOID pv
,DWORD size
,LPDWORD wr
,LPOVERLAPPED unused
)
3642 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, wr
);
3644 result
=write(h
, pv
, size
);
3646 if(!result
)return 0;
3649 static DWORD WINAPI
expSetFilePointer(HANDLE h
, LONG val
, LPLONG ext
, DWORD whence
)
3652 dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h
, val
, ext
, ext
? *ext
: NULL
, whence
);
3653 //why would DLL want temporary file with >2Gb size?
3666 if (val
== 0 && ext
!= 0)
3669 return lseek(h
, val
, wh
);
3672 static HDRVR WINAPI
expOpenDriverA(LPCSTR szDriverName
, LPCSTR szSectionName
,
3675 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3678 static HDRVR WINAPI
expOpenDriver(LPCSTR szDriverName
, LPCSTR szSectionName
,
3681 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3686 static WIN_BOOL WINAPI
expGetProcessAffinityMask(HANDLE hProcess
,
3687 LPDWORD lpProcessAffinityMask
,
3688 LPDWORD lpSystemAffinityMask
)
3690 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3691 hProcess
, lpProcessAffinityMask
, lpSystemAffinityMask
);
3692 if(lpProcessAffinityMask
)*lpProcessAffinityMask
=1;
3693 if(lpSystemAffinityMask
)*lpSystemAffinityMask
=1;
3697 // Fake implementation: does nothing, but does it right :)
3698 static WIN_BOOL WINAPI
expSetProcessAffinityMask(HANDLE hProcess
,
3699 LPDWORD dwProcessAffinityMask
)
3701 dbgprintf("SetProcessAffinityMask(0x%x, 0x%x) => 1\n",
3702 hProcess
, dwProcessAffinityMask
);
3707 static int WINAPI
expMulDiv(int nNumber
, int nNumerator
, int nDenominator
)
3709 static const long long max_int
=0x7FFFFFFFLL
;
3710 static const long long min_int
=-0x80000000LL
;
3711 long long tmp
=(long long)nNumber
*(long long)nNumerator
;
3712 dbgprintf("expMulDiv %d * %d / %d\n", nNumber
, nNumerator
, nDenominator
);
3713 if(!nDenominator
)return 1;
3715 if(tmp
<min_int
) return 1;
3716 if(tmp
>max_int
) return 1;
3720 static LONG WINAPI
explstrcmpiA(const char* str1
, const char* str2
)
3722 LONG result
=strcasecmp(str1
, str2
);
3723 dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
3727 static LONG WINAPI
explstrlenA(const char* str1
)
3729 LONG result
=strlen(str1
);
3730 dbgprintf("strlen(0x%x='%.50s') => %d\n", str1
, str1
, result
);
3734 static LONG WINAPI
explstrcpyA(char* str1
, const char* str2
)
3736 int result
= (int) strcpy(str1
, str2
);
3737 dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1
, str2
, str2
, result
);
3740 static LONG WINAPI
explstrcpynA(char* str1
, const char* str2
,int len
)
3743 if (strlen(str2
)>len
)
3744 result
= (int) strncpy(str1
, str2
,len
);
3746 result
= (int) strcpy(str1
,str2
);
3747 dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1
, str2
, str2
,len
, strlen(str2
),result
);
3750 static LONG WINAPI
explstrcatA(char* str1
, const char* str2
)
3752 int result
= (int) strcat(str1
, str2
);
3753 dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1
, str2
, str2
, result
);
3758 static LONG WINAPI
expInterlockedExchange(long *dest
, long l
)
3760 long retval
= *dest
;
3765 static void WINAPI
expInitCommonControls(void)
3767 dbgprintf("InitCommonControls called!\n");
3772 /* needed by QuickTime.qts */
3773 static HWND WINAPI
expCreateUpDownControl (DWORD style
, INT x
, INT y
, INT cx
, INT cy
,
3774 HWND parent
, INT id
, HINSTANCE inst
,
3775 HWND buddy
, INT maxVal
, INT minVal
, INT curVal
)
3777 dbgprintf("CreateUpDownControl(...)\n");
3782 /* alex: implement this call! needed for 3ivx */
3783 static HRESULT WINAPI
expCoCreateFreeThreadedMarshaler(void *pUnkOuter
, void **ppUnkInner
)
3785 dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
3786 pUnkOuter
, ppUnkInner
);
3788 return ERROR_CALL_NOT_IMPLEMENTED
;
3792 static int WINAPI
expDuplicateHandle(HANDLE hSourceProcessHandle
, // handle to source process
3793 HANDLE hSourceHandle
, // handle to duplicate
3794 HANDLE hTargetProcessHandle
, // handle to target process
3795 HANDLE
* lpTargetHandle
, // duplicate handle
3796 DWORD dwDesiredAccess
, // requested access
3797 int bInheritHandle
, // handle inheritance option
3798 DWORD dwOptions
// optional actions
3801 dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
3802 hSourceProcessHandle
, hSourceHandle
, hTargetProcessHandle
,
3803 lpTargetHandle
, dwDesiredAccess
, bInheritHandle
, dwOptions
);
3804 *lpTargetHandle
= hSourceHandle
;
3808 static HRESULT WINAPI
expCoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
3810 dbgprintf("CoInitializeEx(%p, %d) called\n", lpReserved
, dwCoInit
);
3814 // required by PIM1 codec (used by win98 PCTV Studio capture sw)
3815 static HRESULT WINAPI
expCoInitialize(
3816 LPVOID lpReserved
/* [in] pointer to win32 malloc interface
3817 (obsolete, should be NULL) */
3821 * Just delegate to the newer method.
3823 return expCoInitializeEx(lpReserved
, COINIT_APARTMENTTHREADED
);
3826 static void WINAPI
expCoUninitialize(void)
3828 dbgprintf("CoUninitialize() called\n");
3831 /* allow static linking */
3832 HRESULT WINAPI
CoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
3834 return expCoInitializeEx(lpReserved
, dwCoInit
);
3836 HRESULT WINAPI
CoInitialize(LPVOID lpReserved
)
3838 return expCoInitialize(lpReserved
);
3840 void WINAPI
CoUninitialize(void)
3842 return expCoUninitialize();
3845 static DWORD WINAPI expSetThreadAffinityMask
3848 DWORD dwThreadAffinityMask
3854 * no WINAPI functions - CDECL
3856 static void* expmalloc(int size
)
3859 // return malloc(size);
3860 void* result
=my_mreq(size
,0);
3861 dbgprintf("malloc(0x%x) => 0x%x\n", size
,result
);
3863 printf("WARNING: malloc() failed\n");
3866 static void expfree(void* mem
)
3868 // return free(mem);
3869 dbgprintf("free(%p)\n", mem
);
3872 /* needed by atrac3.acm */
3873 static void *expcalloc(int num
, int size
)
3875 void* result
=my_mreq(num
*size
,1);
3876 dbgprintf("calloc(%d,%d) => %p\n", num
,size
,result
);
3878 printf("WARNING: calloc() failed\n");
3881 static void* expnew(int size
)
3883 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
3884 // printf("%08x %08x %08x %08x\n",
3885 // size, *(1+(int*)&size),
3886 // *(2+(int*)&size),*(3+(int*)&size));
3890 result
=my_mreq(size
,0);
3891 dbgprintf("new(%d) => %p\n", size
, result
);
3893 printf("WARNING: new() failed\n");
3897 static int expdelete(void* memory
)
3899 dbgprintf("delete(%p)\n", memory
);
3905 * local definition - we need only the last two members at this point
3906 * otherwice we would have to introduce here GUIDs and some more types..
3908 typedef struct __attribute__((__packed__
))
3911 unsigned long cbFormat
; //0x40
3912 char* pbFormat
; //0x44
3914 static HRESULT WINAPI
expMoCopyMediaType(MY_MEDIA_TYPE
* dest
, const MY_MEDIA_TYPE
* src
)
3918 memcpy(dest
, src
, sizeof(MY_MEDIA_TYPE
));
3921 dest
->pbFormat
= (char*) my_mreq(dest
->cbFormat
, 0);
3922 if (!dest
->pbFormat
)
3923 return E_OUTOFMEMORY
;
3924 memcpy(dest
->pbFormat
, src
->pbFormat
, dest
->cbFormat
);
3928 static HRESULT WINAPI
expMoInitMediaType(MY_MEDIA_TYPE
* dest
, DWORD cbFormat
)
3932 memset(dest
, 0, sizeof(MY_MEDIA_TYPE
));
3935 dest
->pbFormat
= (char*) my_mreq(cbFormat
, 0);
3936 if (!dest
->pbFormat
)
3937 return E_OUTOFMEMORY
;
3941 static HRESULT WINAPI
expMoCreateMediaType(MY_MEDIA_TYPE
** dest
, DWORD cbFormat
)
3945 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
3946 return expMoInitMediaType(*dest
, cbFormat
);
3948 static HRESULT WINAPI
expMoDuplicateMediaType(MY_MEDIA_TYPE
** dest
, const void* src
)
3952 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
3953 return expMoCopyMediaType(*dest
, src
);
3955 static HRESULT WINAPI
expMoFreeMediaType(MY_MEDIA_TYPE
* dest
)
3961 my_release(dest
->pbFormat
);
3967 static HRESULT WINAPI
expMoDeleteMediaType(MY_MEDIA_TYPE
* dest
)
3971 expMoFreeMediaType(dest
);
3976 static int exp_snprintf( char *str
, int size
, const char *format
, ... )
3980 va_start(va
, format
);
3981 x
=snprintf(str
,size
,format
,va
);
3982 dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str
,size
,format
,x
);
3988 static int exp_initterm(int v1
, int v2
)
3990 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1
, v2
);
3994 /* merged from wine - 2002.04.21 */
3995 typedef void (*INITTERMFUNC
)();
3996 static int exp_initterm(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
3998 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start
, end
, *start
);
4003 //printf("call _initfunc: from: %p %d\n", *start);
4004 // ok this trick with push/pop is necessary as otherwice
4005 // edi/esi registers are being trashed
4024 //printf("done %p %d:%d\n", end);
4032 /* Fake _initterm_e from msvcr80.dll, needed by sirenacm.dll
4033 * NOTE: If I make this an alias for _initterm, then sirenacm.dll tries to call
4034 other uninmplemented functions; keep this in mind if some future codec needs
4035 a real implementation of this function */
4036 static int exp_initterm_e(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
4038 dbgprintf("_initterm_e(0x%x, 0x%x)\n", start
, end
);
4042 static void* exp__dllonexit(void)
4044 // FIXME extract from WINE
4048 static int expwsprintfA(char* string
, const char* format
, ...)
4052 va_start(va
, format
);
4053 result
= vsprintf(string
, format
, va
);
4054 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string
, format
, result
);
4059 static int expsprintf(char* str
, const char* format
, ...)
4063 dbgprintf("sprintf(0x%x, %s)\n", str
, format
);
4064 va_start(args
, format
);
4065 r
= vsprintf(str
, format
, args
);
4069 static int expsscanf(const char* str
, const char* format
, ...)
4073 dbgprintf("sscanf(%s, %s)\n", str
, format
);
4074 va_start(args
, format
);
4075 r
= vsscanf(str
, format
, args
);
4079 static void* expfopen(const char* path
, const char* mode
)
4081 printf("fopen: \"%s\" mode:%s\n", path
, mode
);
4082 //return fopen(path, mode);
4083 return fdopen(0, mode
); // everything on screen
4085 static int expfprintf(void* stream
, const char* format
, ...)
4089 dbgprintf("fprintf(%p, %s, ...)\n", stream
, format
);
4091 va_start(args
, format
);
4092 r
= vfprintf((FILE*) stream
, format
, args
);
4098 static int expprintf(const char* format
, ...)
4102 dbgprintf("printf(%s, ...)\n", format
);
4103 va_start(args
, format
);
4104 r
= vprintf(format
, args
);
4109 static char* expgetenv(const char* varname
)
4111 char* v
= getenv(varname
);
4112 dbgprintf("getenv(%s) => %s\n", varname
, v
);
4116 static void* expwcscpy(WCHAR
* dst
, const WCHAR
* src
)
4119 while ((*p
++ = *src
++))
4124 static char* expstrrchr(char* string
, int value
)
4126 char* result
=strrchr(string
, value
);
4128 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4130 dbgprintf("strrchr(0x%x='%s', %d) => 0", string
, string
, value
);
4134 static char* expstrchr(char* string
, int value
)
4136 char* result
=strchr(string
, value
);
4138 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4140 dbgprintf("strchr(0x%x='%s', %d) => 0", string
, string
, value
);
4143 static int expstrlen(char* str
)
4145 int result
=strlen(str
);
4146 dbgprintf("strlen(0x%x='%s') => %d\n", str
, str
, result
);
4149 static char* expstrcpy(char* str1
, const char* str2
)
4151 char* result
= strcpy(str1
, str2
);
4152 dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1
, str2
, str2
, result
);
4155 static char* expstrncpy(char* str1
, const char* str2
, size_t count
)
4157 char* result
= strncpy(str1
, str2
, count
);
4158 dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1
, str2
, str2
, count
, result
);
4161 static int expstrcmp(const char* str1
, const char* str2
)
4163 int result
=strcmp(str1
, str2
);
4164 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4167 static int expstrncmp(const char* str1
, const char* str2
,int x
)
4169 int result
=strncmp(str1
, str2
,x
);
4170 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4173 static char* expstrcat(char* str1
, const char* str2
)
4175 char* result
= strcat(str1
, str2
);
4176 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1
, str1
, str2
, str2
, result
);
4179 static char* exp_strdup(const char* str1
)
4181 int l
= strlen(str1
);
4182 char* result
= (char*) my_mreq(l
+ 1,0);
4184 strcpy(result
, str1
);
4185 dbgprintf("_strdup(0x%x='%s') => %p\n", str1
, str1
, result
);
4188 static int expisalnum(int c
)
4190 int result
= (int) isalnum(c
);
4191 dbgprintf("isalnum(0x%x='%c' => %d\n", c
, c
, result
);
4194 static int expisspace(int c
)
4196 int result
= (int) isspace(c
);
4197 dbgprintf("isspace(0x%x='%c' => %d\n", c
, c
, result
);
4200 static int expisalpha(int c
)
4202 int result
= (int) isalpha(c
);
4203 dbgprintf("isalpha(0x%x='%c' => %d\n", c
, c
, result
);
4206 static int expisdigit(int c
)
4208 int result
= (int) isdigit(c
);
4209 dbgprintf("isdigit(0x%x='%c' => %d\n", c
, c
, result
);
4212 static void* expmemmove(void* dest
, void* src
, int n
)
4214 void* result
= memmove(dest
, src
, n
);
4215 dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4218 static int expmemcmp(void* dest
, void* src
, int n
)
4220 int result
= memcmp(dest
, src
, n
);
4221 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest
, src
, n
, result
);
4224 static void* expmemcpy(void* dest
, void* src
, int n
)
4226 void *result
= memcpy(dest
, src
, n
);
4227 dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4230 static void* expmemset(void* dest
, int c
, size_t n
)
4232 void *result
= memset(dest
, c
, n
);
4233 dbgprintf("memset(0x%x, %d, %d) => %p\n", dest
, c
, n
, result
);
4236 static time_t exptime(time_t* t
)
4238 time_t result
= time(t
);
4239 dbgprintf("time(0x%x) => %d\n", t
, result
);
4243 static int exprand(void)
4248 static void expsrand(int seed
)
4255 // preferred compilation with -O2 -ffast-math !
4257 static double explog10(double x
)
4259 /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4263 static double expcos(double x
)
4265 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4271 static void explog10(void)
4282 static void expcos(void)
4293 // this seem to be the only how to make this function working properly
4294 // ok - I've spent tremendous amount of time (many many many hours
4295 // of debuging fixing & testing - it's almost unimaginable - kabi
4297 // _ftol - operated on the float value which is already on the FPU stack
4299 static void exp_ftol(void)
4303 "sub $12, %esp \n\t"
4304 "fstcw -2(%ebp) \n\t"
4306 "movw -2(%ebp), %ax \n\t"
4307 "orb $0x0C, %ah \n\t"
4308 "movw %ax, -4(%ebp) \n\t"
4309 "fldcw -4(%ebp) \n\t"
4310 "fistpl -12(%ebp) \n\t"
4311 "fldcw -2(%ebp) \n\t"
4312 "movl -12(%ebp), %eax \n\t"
4313 //Note: gcc 3.03 does not do the following op if it
4314 // knows that ebp=esp
4315 "movl %ebp, %esp \n\t"
4319 #define FPU_DOUBLES(var1,var2) double var1,var2; \
4320 __asm__ volatile( "fstpl %0;fwait" : "=m" (var2) : ); \
4321 __asm__ volatile( "fstpl %0;fwait" : "=m" (var1) : )
4323 static double exp_CIpow(void)
4327 dbgprintf("_CIpow(%lf, %lf)\n", x
, y
);
4331 static double exppow(double x
, double y
)
4333 /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4337 static double expldexp(double x
, int expo
)
4339 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4340 return ldexp(x
, expo
);
4343 static double expfrexp(double x
, int* expo
)
4345 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4346 return frexp(x
, expo
);
4351 static int exp_stricmp(const char* s1
, const char* s2
)
4353 return strcasecmp(s1
, s2
);
4356 /* from declaration taken from Wine sources - this fountion seems to be
4357 * undocumented in any M$ doc */
4358 static int exp_setjmp3(void* jmpbuf
, int x
)
4360 //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4364 //"mov 4(%%esp), %%edx \n\t"
4365 "mov (%%esp), %%eax \n\t"
4366 "mov %%eax, (%%edx) \n\t" // store ebp
4368 //"mov %%ebp, (%%edx) \n\t"
4369 "mov %%ebx, 4(%%edx) \n\t"
4370 "mov %%edi, 8(%%edx) \n\t"
4371 "mov %%esi, 12(%%edx) \n\t"
4372 "mov %%esp, 16(%%edx) \n\t"
4374 "mov 4(%%esp), %%eax \n\t"
4375 "mov %%eax, 20(%%edx) \n\t"
4377 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4378 "movl $0, 36(%%edx) \n\t"
4380 : "d"(jmpbuf
) // input
4386 "mov %%fs:0, %%eax \n\t" // unsure
4387 "mov %%eax, 24(%%edx) \n\t"
4388 "cmp $0xffffffff, %%eax \n\t"
4390 "mov %%eax, 28(%%edx) \n\t"
4401 static DWORD WINAPI
expGetCurrentProcessId(void)
4403 dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4404 return getpid(); //(DWORD)NtCurrentTeb()->pid;
4411 } TIMECAPS
, *LPTIMECAPS
;
4413 static MMRESULT WINAPI
exptimeGetDevCaps(LPTIMECAPS lpCaps
, UINT wSize
)
4415 dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps
, wSize
);
4417 lpCaps
->wPeriodMin
= 1;
4418 lpCaps
->wPeriodMax
= 65535;
4422 static MMRESULT WINAPI
exptimeBeginPeriod(UINT wPeriod
)
4424 dbgprintf("timeBeginPeriod(%u) !\n", wPeriod
);
4426 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4431 static MMRESULT WINAPI
exptimeEndPeriod(UINT wPeriod
)
4433 dbgprintf("timeEndPeriod(%u) !\n", wPeriod
);
4435 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4440 static void WINAPI
expGlobalMemoryStatus(
4441 LPMEMORYSTATUS lpmem
4443 static MEMORYSTATUS cached_memstatus
;
4444 static int cache_lastchecked
= 0;
4448 if (time(NULL
)==cache_lastchecked
) {
4449 memcpy(lpmem
,&cached_memstatus
,sizeof(MEMORYSTATUS
));
4454 f
= fopen( "/proc/meminfo", "r" );
4458 int total
, used
, free
, shared
, buffers
, cached
;
4460 lpmem
->dwLength
= sizeof(MEMORYSTATUS
);
4461 lpmem
->dwTotalPhys
= lpmem
->dwAvailPhys
= 0;
4462 lpmem
->dwTotalPageFile
= lpmem
->dwAvailPageFile
= 0;
4463 while (fgets( buffer
, sizeof(buffer
), f
))
4465 /* old style /proc/meminfo ... */
4466 if (sscanf( buffer
, "Mem: %d %d %d %d %d %d", &total
, &used
, &free
, &shared
, &buffers
, &cached
))
4468 lpmem
->dwTotalPhys
+= total
;
4469 lpmem
->dwAvailPhys
+= free
+ buffers
+ cached
;
4471 if (sscanf( buffer
, "Swap: %d %d %d", &total
, &used
, &free
))
4473 lpmem
->dwTotalPageFile
+= total
;
4474 lpmem
->dwAvailPageFile
+= free
;
4477 /* new style /proc/meminfo ... */
4478 if (sscanf(buffer
, "MemTotal: %d", &total
))
4479 lpmem
->dwTotalPhys
= total
*1024;
4480 if (sscanf(buffer
, "MemFree: %d", &free
))
4481 lpmem
->dwAvailPhys
= free
*1024;
4482 if (sscanf(buffer
, "SwapTotal: %d", &total
))
4483 lpmem
->dwTotalPageFile
= total
*1024;
4484 if (sscanf(buffer
, "SwapFree: %d", &free
))
4485 lpmem
->dwAvailPageFile
= free
*1024;
4486 if (sscanf(buffer
, "Buffers: %d", &buffers
))
4487 lpmem
->dwAvailPhys
+= buffers
*1024;
4488 if (sscanf(buffer
, "Cached: %d", &cached
))
4489 lpmem
->dwAvailPhys
+= cached
*1024;
4493 if (lpmem
->dwTotalPhys
)
4495 DWORD TotalPhysical
= lpmem
->dwTotalPhys
+lpmem
->dwTotalPageFile
;
4496 DWORD AvailPhysical
= lpmem
->dwAvailPhys
+lpmem
->dwAvailPageFile
;
4497 lpmem
->dwMemoryLoad
= (TotalPhysical
-AvailPhysical
)
4498 / (TotalPhysical
/ 100);
4503 /* FIXME: should do something for other systems */
4504 lpmem
->dwMemoryLoad
= 0;
4505 lpmem
->dwTotalPhys
= 16*1024*1024;
4506 lpmem
->dwAvailPhys
= 16*1024*1024;
4507 lpmem
->dwTotalPageFile
= 16*1024*1024;
4508 lpmem
->dwAvailPageFile
= 16*1024*1024;
4510 expGetSystemInfo(&si
);
4511 lpmem
->dwTotalVirtual
= si
.lpMaximumApplicationAddress
-si
.lpMinimumApplicationAddress
;
4512 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4513 lpmem
->dwAvailVirtual
= lpmem
->dwTotalVirtual
-64*1024;
4514 memcpy(&cached_memstatus
,lpmem
,sizeof(MEMORYSTATUS
));
4515 cache_lastchecked
= time(NULL
);
4517 /* it appears some memory display programs want to divide by these values */
4518 if(lpmem
->dwTotalPageFile
==0)
4519 lpmem
->dwTotalPageFile
++;
4521 if(lpmem
->dwAvailPageFile
==0)
4522 lpmem
->dwAvailPageFile
++;
4525 static INT WINAPI
expGetThreadPriority(HANDLE hthread
)
4527 dbgprintf("GetThreadPriority(%p)\n",hthread
);
4531 /**********************************************************************
4532 * SetThreadPriority [KERNEL32.@] Sets priority for thread.
4538 static WIN_BOOL WINAPI
expSetThreadPriority(
4539 HANDLE hthread
, /* [in] Handle to thread */
4540 INT priority
) /* [in] Thread priority level */
4542 dbgprintf("SetThreadPriority(%p,%d)\n",hthread
,priority
);
4546 static void WINAPI
expExitProcess( DWORD status
)
4548 printf("EXIT - code %ld\n",status
);
4552 static INT WINAPI
expMessageBoxA(HWND hWnd
, LPCSTR text
, LPCSTR title
, UINT type
){
4553 printf("MSGBOX '%s' '%s' (%d)\n",text
,title
,type
);
4555 if (type
== MB_ICONHAND
&& !strlen(text
) && !strlen(title
))
4561 /* these are needed for mss1 */
4564 * \brief this symbol is defined within exp_EH_prolog_dummy
4565 * \param dest jump target
4567 void exp_EH_prolog(void *dest
);
4568 //! just a dummy function that acts a container for the asm section
4569 void exp_EH_prolog_dummy(void) {
4571 // take care, this "function" may not change flags or
4572 // registers besides eax (which is also why we can't use
4573 // exp_EH_prolog_dummy directly)
4574 MANGLE(exp_EH_prolog
)": \n\t"
4577 "mov %esp, %ebp \n\t"
4578 "lea -12(%esp), %esp \n\t"
4583 #include <netinet/in.h>
4584 static WINAPI
inline unsigned long int exphtonl(unsigned long int hostlong
)
4586 // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4587 return htonl(hostlong
);
4590 static WINAPI
inline unsigned long int expntohl(unsigned long int netlong
)
4592 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4593 return ntohl(netlong
);
4595 static void WINAPI
expVariantInit(void* p
)
4597 printf("InitCommonControls called!\n");
4601 static int WINAPI
expRegisterClassA(const void/*WNDCLASSA*/ *wc
)
4603 dbgprintf("RegisterClassA(%p) => random id\n", wc
);
4604 return time(NULL
); /* be precise ! */
4607 static int WINAPI
expUnregisterClassA(const char *className
, HINSTANCE hInstance
)
4609 dbgprintf("UnregisterClassA(%s, %p) => 0\n", className
, hInstance
);
4614 /* should be fixed bcs it's not fully strlen equivalent */
4615 static int expSysStringByteLen(void *str
)
4617 dbgprintf("SysStringByteLen(%p) => %d\n", str
, strlen(str
));
4621 static int expDirectDrawCreate(void)
4623 dbgprintf("DirectDrawCreate(...) => NULL\n");
4628 typedef struct tagPALETTEENTRY
{
4635 /* reversed the first 2 entries */
4636 typedef struct tagLOGPALETTE
{
4639 PALETTEENTRY palPalEntry
[1];
4642 static HPALETTE WINAPI
expCreatePalette(CONST LOGPALETTE
*lpgpl
)
4647 dbgprintf("CreatePalette(%x) => NULL\n", lpgpl
);
4649 i
= sizeof(LOGPALETTE
)+((lpgpl
->palNumEntries
-1)*sizeof(PALETTEENTRY
));
4650 test
= (HPALETTE
)malloc(i
);
4651 memcpy((void *)test
, lpgpl
, i
);
4656 static int expCreatePalette(void)
4658 dbgprintf("CreatePalette(...) => NULL\n");
4663 static int WINAPI
expGetClientRect(HWND win
, RECT
*r
)
4665 dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win
, r
);
4666 r
->right
= PSEUDO_SCREEN_WIDTH
;
4668 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
4674 typedef struct tagPOINT
{
4680 static int WINAPI
expClientToScreen(HWND win
, POINT
*p
)
4682 dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win
, p
, p
->x
, p
->y
);
4690 static int WINAPI
expSetThreadIdealProcessor(HANDLE thread
, int proc
)
4692 dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread
, proc
);
4696 static int WINAPI
expMessageBeep(int type
)
4698 dbgprintf("MessageBeep(%d) => 1\n", type
);
4702 static int WINAPI
expDialogBoxParamA(void *inst
, const char *name
,
4703 HWND parent
, void *dialog_func
, void *init_param
)
4705 dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
4706 inst
, name
, name
, parent
, dialog_func
, init_param
);
4710 static void WINAPI
expRegisterClipboardFormatA(const char *name
) {
4711 dbgprintf("RegisterClipboardFormatA(0x%x = %s)\n", name
, name
);
4714 /* needed by imagepower mjpeg2k */
4715 static void *exprealloc(void *ptr
, size_t size
)
4717 dbgprintf("realloc(0x%x, %x)\n", ptr
, size
);
4719 return my_mreq(size
,0);
4721 return my_realloc(ptr
, size
);
4724 /* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
4725 static WIN_BOOL WINAPI
expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn
)
4730 static char * WINAPI
expPathFindExtensionA(const char *path
) {
4735 ext
= strrchr(path
, '.');
4737 ext
= &path
[strlen(path
)];
4739 dbgprintf("PathFindExtensionA(0x%x = %s) => 0x%x, %s\n", path
, path
, ext
, ext
);
4743 static char * WINAPI
expPathFindFileNameA(const char *path
) {
4745 if (!path
|| strlen(path
) < 2)
4748 name
= strrchr(path
- 1, '\\');
4752 dbgprintf("PathFindFileNameA(0x%x = %s) => 0x%x, %s\n", path
, path
, name
, name
);
4756 static double expfloor(double x
)
4758 dbgprintf("floor(%lf)\n", x
);
4762 #define FPU_DOUBLE(var) double var; \
4763 __asm__ volatile( "fstpl %0;fwait" : "=m" (var) : )
4765 static double exp_CIcos(void)
4769 dbgprintf("_CIcos(%lf)\n", x
);
4773 static double exp_CIsin(void)
4777 dbgprintf("_CIsin(%lf)\n", x
);
4781 static double exp_CIsqrt(void)
4785 dbgprintf("_CIsqrt(%lf)\n", x
);
4789 /* Needed by rp8 sipr decoder */
4790 static LPSTR WINAPI
expCharNextA(LPCSTR ptr
)
4792 if (!*ptr
) return (LPSTR
)ptr
;
4793 // dbgprintf("CharNextA(0x%08x), %s\n", ptr, ptr);
4794 return (LPSTR
)(ptr
+ 1);
4797 // Fake implementation, needed by wvc1dmod.dll
4798 static int WINAPI
expPropVariantClear(void *pvar
)
4800 // dbgprintf("PropVariantclear (0x%08x), %s\n", ptr, ptr);
4804 // This define is fake, the real thing is a struct
4805 #define LPDEVMODEA void*
4806 // Dummy implementation, always return 1
4807 // Required for frapsvid.dll 2.8.1, return value does not matter
4808 static WIN_BOOL WINAPI
expEnumDisplaySettingsA(LPCSTR name
,DWORD n
,
4811 dbgprintf("EnumDisplaySettingsA (dummy) => 1\n");
4815 // Fake implementation of _decode_pointer from msvcr80.dll, needed by sirenacm.dll
4816 // NOTE: undocumented function, probably the declaration is not right
4817 static int exp_decode_pointer(void *ptr
)
4819 dbgprintf("_decode_pointer (0x%08x)\n", ptr
);
4823 /* Fake implementation of sdt::_Lockit::_Lockit(void) from msvcp60.dll
4824 Needed by SCLS.DLL */
4825 static int exp_0Lockit_dummy(void)
4827 dbgprintf("0Lockit_dummy (??0_Lockit@std@@QAE@XZ)\n");
4831 /* Fake implementation of sdt::_Lockit::~_Lockit(void) from msvcp60.dll
4832 Needed by SCLS.DLL */
4833 static int exp_1Lockit_dummy(void)
4835 dbgprintf("1Lockit_dummy (??1_Lockit@std@@QAE@XZ)\n");
4849 struct exports
* exps
;
4853 {#X, Y, (void*)exp##X},
4855 #define UNDEFF(X, Y) \
4858 struct exports exp_kernel32
[]=
4860 FF(GetVolumeInformationA
,-1)
4861 FF(GetDriveTypeA
,-1)
4862 FF(GetLogicalDriveStringsA
,-1)
4863 FF(IsBadWritePtr
, 357)
4864 FF(IsBadReadPtr
, 354)
4865 FF(IsBadStringPtrW
, -1)
4866 FF(IsBadStringPtrA
, -1)
4867 FF(DisableThreadLibraryCalls
, -1)
4868 FF(CreateThread
, -1)
4869 FF(CreateEventA
, -1)
4872 FF(WaitForSingleObject
, -1)
4874 FF(WaitForMultipleObjects
, -1)
4879 FF(GetSystemInfo
, -1)
4887 FF(GetProcessHeap
, -1)
4888 FF(VirtualAlloc
, -1)
4890 FF(InitializeCriticalSection
, -1)
4891 FF(EnterCriticalSection
, -1)
4892 FF(LeaveCriticalSection
, -1)
4893 FF(DeleteCriticalSection
, -1)
4898 FF(GetCurrentThreadId
, -1)
4899 FF(GetCurrentProcess
, -1)
4904 FF(GlobalReAlloc
, -1)
4907 FF(MultiByteToWideChar
, 427)
4908 FF(WideCharToMultiByte
, -1)
4909 FF(GetVersionExA
, -1)
4910 FF(CreateSemaphoreA
, -1)
4911 FF(QueryPerformanceCounter
, -1)
4912 FF(QueryPerformanceFrequency
, -1)
4916 FF(GlobalHandle
, -1)
4917 FF(GlobalUnlock
, -1)
4919 FF(LoadResource
, -1)
4920 FF(ReleaseSemaphore
, -1)
4921 FF(FindResourceA
, -1)
4922 FF(LockResource
, -1)
4923 FF(FreeResource
, -1)
4924 FF(SizeofResource
, -1)
4926 FF(GetCommandLineA
, -1)
4927 FF(GetEnvironmentStringsW
, -1)
4928 FF(FreeEnvironmentStringsW
, -1)
4929 FF(FreeEnvironmentStringsA
, -1)
4930 FF(GetEnvironmentStrings
, -1)
4931 FF(GetStartupInfoA
, -1)
4932 FF(GetStdHandle
, -1)
4935 FF(GetFileAttributesA
, -1)
4937 FF(SetHandleCount
, -1)
4939 FF(GetModuleFileNameA
, -1)
4940 FF(SetUnhandledExceptionFilter
, -1)
4941 FF(LoadLibraryA
, -1)
4942 FF(GetProcAddress
, -1)
4944 FF(CreateFileMappingA
, -1)
4945 FF(OpenFileMappingA
, -1)
4946 FF(MapViewOfFile
, -1)
4947 FF(UnmapViewOfFile
, -1)
4949 FF(GetModuleHandleA
, -1)
4950 FF(GetProfileIntA
, -1)
4951 FF(GetPrivateProfileIntA
, -1)
4952 FF(GetPrivateProfileStringA
, -1)
4953 FF(WritePrivateProfileStringA
, -1)
4954 FF(GetLastError
, -1)
4955 FF(SetLastError
, -1)
4956 FF(InterlockedIncrement
, -1)
4957 FF(InterlockedDecrement
, -1)
4958 FF(GetTimeZoneInformation
, -1)
4959 FF(OutputDebugStringA
, -1)
4960 FF(GetLocalTime
, -1)
4961 FF(GetSystemTime
, -1)
4962 FF(GetSystemTimeAsFileTime
, -1)
4963 FF(GetEnvironmentVariableA
, -1)
4964 FF(SetEnvironmentVariableA
, -1)
4965 FF(RtlZeroMemory
,-1)
4966 FF(RtlMoveMemory
,-1)
4967 FF(RtlFillMemory
,-1)
4969 FF(FindFirstFileA
,-1)
4970 FF(FindNextFileA
,-1)
4972 FF(FileTimeToLocalFileTime
,-1)
4976 FF(SetFilePointer
,-1)
4977 FF(GetTempFileNameA
,-1)
4979 FF(GetSystemDirectoryA
,-1)
4980 FF(GetWindowsDirectoryA
,-1)
4982 FF(GetCurrentDirectoryA
,-1)
4983 FF(SetCurrentDirectoryA
,-1)
4984 FF(CreateDirectoryA
,-1)
4986 FF(GetShortPathNameA
,-1)
4987 FF(GetFullPathNameA
,-1)
4988 FF(SetErrorMode
, -1)
4989 FF(IsProcessorFeaturePresent
, -1)
4990 FF(GetProcessAffinityMask
, -1)
4991 FF(InterlockedExchange
, -1)
4992 FF(InterlockedCompareExchange
, -1)
4999 FF(GetProcessVersion
,-1)
5000 FF(GetCurrentThread
,-1)
5003 FF(DuplicateHandle
,-1)
5004 FF(GetTickCount
, -1)
5005 FF(SetThreadAffinityMask
,-1)
5006 FF(GetCurrentProcessId
,-1)
5007 FF(GlobalMemoryStatus
,-1)
5008 FF(GetThreadPriority
,-1)
5009 FF(SetThreadPriority
,-1)
5011 {"LoadLibraryExA", -1, (void*)&LoadLibraryExA
},
5012 FF(SetThreadIdealProcessor
,-1)
5013 FF(SetProcessAffinityMask
, -1)
5014 UNDEFF(FlsAlloc
, -1)
5015 UNDEFF(FlsGetValue
, -1)
5016 UNDEFF(FlsSetValue
, -1)
5020 struct exports exp_msvcrt
[]={
5026 {"??3@YAXPAX@Z", -1, expdelete
},
5027 {"??2@YAPAXI@Z", -1, expnew
},
5028 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5029 {"_winver",-1,(void*)&_winver
},
5070 /* needed by frapsvid.dll */
5071 {"strstr",-1,(char *)&strstr
},
5072 {"qsort",-1,(void *)&qsort
},
5075 {"ceil",-1,(void*)&ceil
},
5076 /* needed by imagepower mjpeg2k */
5077 {"clock",-1,(void*)&clock
},
5078 {"memchr",-1,(void*)&memchr
},
5079 {"vfprintf",-1,(void*)&vfprintf
},
5080 // {"realloc",-1,(void*)&realloc},
5082 {"puts",-1,(void*)&puts
}
5084 struct exports exp_winmm
[]={
5085 FF(GetDriverModuleHandle
, -1)
5087 FF(DefDriverProc
, -1)
5090 FF(timeGetDevCaps
, -1)
5091 FF(timeBeginPeriod
, -1)
5093 FF(timeEndPeriod
, -1)
5094 FF(waveOutGetNumDevs
, -1)
5097 struct exports exp_user32
[]={
5102 FF(GetDesktopWindow
, -1)
5111 FF(RegisterWindowMessageA
,-1)
5112 FF(GetSystemMetrics
,-1)
5114 FF(GetSysColorBrush
,-1)
5118 FF(RegisterClassA
, -1)
5119 FF(UnregisterClassA
, -1)
5121 FF(GetWindowRect
, -1)
5122 FF(MonitorFromWindow
, -1)
5123 FF(MonitorFromRect
, -1)
5124 FF(MonitorFromPoint
, -1)
5125 FF(EnumDisplayMonitors
, -1)
5126 FF(GetMonitorInfoA
, -1)
5127 FF(EnumDisplayDevicesA
, -1)
5128 FF(GetClientRect
, -1)
5129 FF(ClientToScreen
, -1)
5130 FF(IsWindowVisible
, -1)
5131 FF(GetActiveWindow
, -1)
5132 FF(GetClassNameA
, -1)
5133 FF(GetClassInfoA
, -1)
5134 FF(GetWindowLongA
, -1)
5136 FF(GetWindowThreadProcessId
, -1)
5137 FF(CreateWindowExA
, -1)
5140 FF(DialogBoxParamA
, -1)
5141 FF(RegisterClipboardFormatA
, -1)
5143 FF(EnumDisplaySettingsA
, -1)
5145 struct exports exp_advapi32
[]={
5147 FF(RegCreateKeyA
, -1)
5148 FF(RegCreateKeyExA
, -1)
5149 FF(RegEnumKeyExA
, -1)
5150 FF(RegEnumValueA
, -1)
5152 FF(RegOpenKeyExA
, -1)
5153 FF(RegQueryValueExA
, -1)
5154 FF(RegSetValueExA
, -1)
5155 FF(RegQueryInfoKeyA
, -1)
5157 struct exports exp_gdi32
[]={
5158 FF(CreateCompatibleDC
, -1)
5161 FF(DeleteObject
, -1)
5162 FF(GetDeviceCaps
, -1)
5163 FF(GetSystemPaletteEntries
, -1)
5165 FF(CreatePalette
, -1)
5167 FF(CreateRectRgn
, -1)
5170 struct exports exp_version
[]={
5171 FF(GetFileVersionInfoSizeA
, -1)
5173 struct exports exp_ole32
[]={
5174 FF(CoCreateFreeThreadedMarshaler
,-1)
5175 FF(CoCreateInstance
, -1)
5176 FF(CoInitialize
, -1)
5177 FF(CoInitializeEx
, -1)
5178 FF(CoUninitialize
, -1)
5179 FF(CoTaskMemAlloc
, -1)
5180 FF(CoTaskMemFree
, -1)
5181 FF(StringFromGUID2
, -1)
5182 FF(PropVariantClear
, -1)
5184 // do we really need crtdll ???
5185 // msvcrt is the correct place probably...
5186 struct exports exp_crtdll
[]={
5190 struct exports exp_comctl32
[]={
5191 FF(StringFromGUID2
, -1)
5192 FF(InitCommonControls
, 17)
5194 FF(CreateUpDownControl
, 16)
5197 struct exports exp_wsock32
[]={
5201 struct exports exp_msdmo
[]={
5202 FF(memcpy
, -1) // just test
5203 FF(MoCopyMediaType
, -1)
5204 FF(MoCreateMediaType
, -1)
5205 FF(MoDeleteMediaType
, -1)
5206 FF(MoDuplicateMediaType
, -1)
5207 FF(MoFreeMediaType
, -1)
5208 FF(MoInitMediaType
, -1)
5210 struct exports exp_oleaut32
[]={
5213 FF(SysStringByteLen
, 149)
5219 vma: Hint/Ord Member-Name
5224 2305e 167 _adjust_fdiv
5227 22ffc 176 _beginthreadex
5229 2300e 85 __CxxFrameHandler
5233 struct exports exp_pncrt
[]={
5234 FF(malloc
, -1) // just test
5235 FF(free
, -1) // just test
5236 FF(fprintf
, -1) // just test
5237 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5240 {"??3@YAXPAX@Z", -1, expdelete
},
5241 {"??2@YAPAXI@Z", -1, expnew
},
5253 struct exports exp_ddraw
[]={
5254 FF(DirectDrawCreate
, -1)
5258 struct exports exp_comdlg32
[]={
5259 FF(GetOpenFileNameA
, -1)
5262 struct exports exp_shlwapi
[]={
5263 FF(PathFindExtensionA
, -1)
5264 FF(PathFindFileNameA
, -1)
5267 struct exports exp_msvcr80
[]={
5275 FF(_decode_pointer
, -1)
5278 struct exports exp_msvcp60
[]={
5279 {"??0_Lockit@std@@QAE@XZ", -1, exp_0Lockit_dummy
},
5280 {"??1_Lockit@std@@QAE@XZ", -1, exp_1Lockit_dummy
}
5284 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5286 struct libs libraries
[]={
5312 static WIN_BOOL WINAPI
ext_stubs(void)
5314 volatile int idx
= 0xdeadabcd;
5315 // make sure gcc does not do eip-relative call or something like that
5316 volatile void (*my_printf
)(char *, char *) = (void *)0xdeadfbcd;
5317 my_printf("Called unk_%s\n", export_names
[idx
]);
5321 #define MAX_STUB_SIZE 0x60
5322 #define MAX_NUM_STUBS 200
5324 static char *extcode
= NULL
;
5326 static void* add_stub(void)
5330 // generated code in runtime!
5333 extcode
= mmap_anon(NULL
, MAX_NUM_STUBS
* MAX_STUB_SIZE
,
5334 PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
, 0);
5335 answ
= extcode
+ pos
* MAX_STUB_SIZE
;
5336 if (pos
>= MAX_NUM_STUBS
) {
5337 printf("too many stubs, expect crash\n");
5340 memcpy(answ
, ext_stubs
, MAX_STUB_SIZE
);
5341 for (i
= 0; i
< MAX_STUB_SIZE
- 3; i
++) {
5342 int *magic
= (int *)(answ
+ i
);
5343 if (*magic
== 0xdeadabcd) {
5347 if (*magic
== 0xdeadfbcd) {
5348 *magic
= (intptr_t)printf
;
5353 printf("magic code not found in ext_subs, expect crash\n");
5360 void* LookupExternal(const char* library
, int ordinal
)
5365 printf("ERROR: library=0\n");
5366 return (void*)ext_unknown
;
5368 // printf("%x %x\n", &unk_exp1, &unk_exp2);
5370 dbgprintf("External func %s:%d\n", library
, ordinal
);
5372 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5374 if(strcasecmp(library
, libraries
[i
].name
))
5376 for(j
=0; j
<libraries
[i
].length
; j
++)
5378 if(ordinal
!=libraries
[i
].exps
[j
].id
)
5380 //printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5381 return libraries
[i
].exps
[j
].func
;
5385 #ifndef LOADLIB_TRY_NATIVE
5386 /* hack for truespeech and vssh264*/
5387 if (!strcmp(library
, "tsd32.dll") || !strcmp(library
,"vssh264dec.dll") || !strcmp(library
,"LCMW2.dll") || !strcmp(library
,"VDODEC32.dll"))
5389 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5395 hand
= LoadLibraryA(library
);
5398 wm
= MODULE32_LookupHMODULE(hand
);
5404 func
= PE_FindExportedFunction(wm
, (LPCSTR
) ordinal
, 0);
5407 printf("No such ordinal in external dll\n");
5408 FreeLibrary((int)hand
);
5412 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5418 if(pos
>150)return 0;
5419 sprintf(export_names
[pos
], "%s:%d", library
, ordinal
);
5423 void* LookupExternalByName(const char* library
, const char* name
)
5426 // return (void*)ext_unknown;
5429 printf("ERROR: library=0\n");
5430 return (void*)ext_unknown
;
5432 if((unsigned long)name
<=0xffff)
5434 return LookupExternal(library
, (int)name
);
5436 dbgprintf("External func %s:%s\n", library
, name
);
5437 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5439 if(strcasecmp(library
, libraries
[i
].name
))
5441 for(j
=0; j
<libraries
[i
].length
; j
++)
5443 if(strcmp(name
, libraries
[i
].exps
[j
].name
))
5445 if((unsigned int)(libraries
[i
].exps
[j
].func
) == -1)
5446 return NULL
; //undefined func
5447 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5448 return libraries
[i
].exps
[j
].func
;
5452 #ifndef LOADLIB_TRY_NATIVE
5453 /* hack for vss h264 */
5454 if (!strcmp(library
,"vssh264core.dll") || !strcmp(library
,"3ivx.dll"))
5456 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5462 hand
= LoadLibraryA(library
);
5465 wm
= MODULE32_LookupHMODULE(hand
);
5471 func
= PE_FindExportedFunction(wm
, name
, 0);
5474 printf("No such name in external dll\n");
5475 FreeLibrary((int)hand
);
5479 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5485 if(pos
>150)return 0;// to many symbols
5486 strcpy(export_names
[pos
], name
);
5490 void my_garbagecollection(void)
5493 int unfree
= 0, unfreecnt
= 0;
5499 alloc_header
* mem
= last_alloc
+ 1;
5500 unfree
+= my_size(mem
);
5502 if (my_release(mem
) != 0)
5503 // avoid endless loop when memory is trashed
5504 if (--max_fatal
< 0)
5507 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree
, unfreecnt
, last_alloc
, alccnt
);