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/
28 //#define LOADLIB_TRY_NATIVE
32 #define PSEUDO_SCREEN_WIDTH /*640*/800
33 #define PSEUDO_SCREEN_HEIGHT /*480*/600
36 #include "wine/winbase.h"
37 #include "wine/winreg.h"
38 #include "wine/winnt.h"
39 #include "wine/winerror.h"
40 #include "wine/debugtools.h"
41 #include "wine/module.h"
42 #include "wine/winuser.h"
65 #include <sys/types.h>
68 #include <sys/timeb.h>
74 #include "osdep/mmap_anon.h"
77 int vsscanf( const char *str
, const char *format
, va_list ap
);
79 /* system has no vsscanf. try to provide one */
80 static int vsscanf( const char *str
, const char *format
, va_list ap
)
82 long p1
= va_arg(ap
, long);
83 long p2
= va_arg(ap
, long);
84 long p3
= va_arg(ap
, long);
85 long p4
= va_arg(ap
, long);
86 long p5
= va_arg(ap
, long);
87 return sscanf(str
, format
, p1
, p2
, p3
, p4
, p5
);
91 char* def_path
= WIN32_PATH
;
93 static void do_cpuid(unsigned int ax
, unsigned int *regs
)
97 "pushl %%ebx; pushl %%ecx; pushl %%edx;"
102 "movl %%edx, 12(%2);"
103 "popl %%edx; popl %%ecx; popl %%ebx;"
105 : "0" (ax
), "S" (regs
)
108 static unsigned int c_localcount_tsc()
120 static void c_longcount_tsc(long long* z
)
125 "movl %%eax, %%ebx\n\t"
127 "movl %%eax, 0(%%ebx)\n\t"
128 "movl %%edx, 4(%%ebx)\n\t"
134 static unsigned int c_localcount_notsc()
139 gettimeofday(&tv
, 0);
140 return limit
*tv
.tv_usec
;
142 static void c_longcount_notsc(long long* z
)
145 unsigned long long result
;
149 gettimeofday(&tv
, 0);
152 result
+=limit
*tv
.tv_usec
;
155 static unsigned int localcount_stub(void);
156 static void longcount_stub(long long*);
157 static unsigned int (*localcount
)()=localcount_stub
;
158 static void (*longcount
)(long long*)=longcount_stub
;
160 static pthread_mutex_t memmut
;
162 static unsigned int localcount_stub(void)
164 unsigned int regs
[4];
166 if ((regs
[3] & 0x00000010) != 0)
168 localcount
=c_localcount_tsc
;
169 longcount
=c_longcount_tsc
;
173 localcount
=c_localcount_notsc
;
174 longcount
=c_longcount_notsc
;
178 static void longcount_stub(long long* z
)
180 unsigned int regs
[4];
182 if ((regs
[3] & 0x00000010) != 0)
184 localcount
=c_localcount_tsc
;
185 longcount
=c_longcount_tsc
;
189 localcount
=c_localcount_notsc
;
190 longcount
=c_longcount_notsc
;
198 int LOADER_DEBUG
=1; // active only if compiled with -DDETAILED_OUT
199 //#define DETAILED_OUT
200 static inline void dbgprintf(char* fmt
, ...)
208 f
=fopen("./log", "a");
213 vfprintf(f
, fmt
, va
);
221 if ( mp_msg_test(MSGT_WIN32
,MSGL_DBG3
) )
227 // mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va);
235 char export_names
[300][32]={
240 //#define min(x,y) ((x)<(y)?(x):(y))
242 void destroy_event(void* event
);
245 typedef struct th_list_t
{
248 struct th_list_t
* next
;
249 struct th_list_t
* prev
;
253 // have to be cleared by GARBAGE COLLECTOR
254 static unsigned char* heap
=NULL
;
255 static int heap_counter
=0;
256 static tls_t
* g_tls
=NULL
;
257 static th_list
* list
=NULL
;
259 static void test_heap(void)
264 while(offset
<heap_counter
)
266 if(*(int*)(heap
+offset
)!=0x433476)
268 printf("Heap corruption at address %d\n", offset
);
271 offset
+=8+*(int*)(heap
+offset
+4);
273 for(;offset
<min(offset
+1000, 20000000); offset
++)
274 if(heap
[offset
]!=0xCC)
276 printf("Free heap corruption at address %d\n", offset
);
283 static void* my_mreq(int size
, int to_zero
)
287 if(test
%10==0)printf("Memory: %d bytes allocated\n", heap_counter
);
291 heap
=malloc(20000000);
292 memset(heap
, 0xCC,20000000);
296 printf("No enough memory\n");
299 if(heap_counter
+size
>20000000)
301 printf("No enough memory\n");
304 *(int*)(heap
+heap_counter
)=0x433476;
306 *(int*)(heap
+heap_counter
)=size
;
308 printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size
, heap_counter
-8, heap_counter
, heap_counter
+size
);
310 memset(heap
+heap_counter
, 0, size
);
312 memset(heap
+heap_counter
, 0xcc, size
); // make crash reproducable
314 return heap
+heap_counter
-size
;
316 static int my_release(char* memory
)
321 printf("ERROR: free(0)\n");
324 if(*(int*)(memory
-8)!=0x433476)
326 printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
329 printf("Freed %d bytes of memory\n", *(int*)(memory
-4));
330 // memset(memory-8, *(int*)(memory-4), 0xCC);
336 typedef struct alloc_header_t alloc_header
;
337 struct alloc_header_t
339 // let's keep allocated data 16 byte aligned
351 static alloc_header
* last_alloc
= NULL
;
352 static int alccnt
= 0;
355 #define AREATYPE_CLIENT 0
356 #define AREATYPE_EVENT 1
357 #define AREATYPE_MUTEX 2
358 #define AREATYPE_COND 3
359 #define AREATYPE_CRITSECT 4
361 /* -- critical sections -- */
365 pthread_mutex_t mutex
;
370 void* mreq_private(int size
, int to_zero
, int type
);
371 void* mreq_private(int size
, int to_zero
, int type
)
373 int nsize
= size
+ sizeof(alloc_header
);
374 alloc_header
* header
= (alloc_header
* ) malloc(nsize
);
378 memset(header
, 0, nsize
);
382 pthread_mutex_init(&memmut
, NULL
);
383 pthread_mutex_lock(&memmut
);
387 pthread_mutex_lock(&memmut
);
388 last_alloc
->next
= header
; /* set next */
391 header
->prev
= last_alloc
;
395 pthread_mutex_unlock(&memmut
);
397 header
->deadbeef
= 0xdeadbeef;
401 //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt);
405 static int my_release(void* memory
)
407 alloc_header
* header
= (alloc_header
*) memory
- 1;
409 alloc_header
* prevmem
;
410 alloc_header
* nextmem
;
415 if (header
->deadbeef
!= (long) 0xdeadbeef)
417 dbgprintf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
421 pthread_mutex_lock(&memmut
);
426 destroy_event(memory
);
429 pthread_cond_destroy((pthread_cond_t
*)memory
);
432 pthread_mutex_destroy((pthread_mutex_t
*)memory
);
434 case AREATYPE_CRITSECT
:
435 pthread_mutex_destroy(&((struct CRITSECT
*)memory
)->mutex
);
438 //memset(memory, 0xcc, header->size);
442 header
->deadbeef
= 0;
443 prevmem
= header
->prev
;
444 nextmem
= header
->next
;
447 prevmem
->next
= nextmem
;
449 nextmem
->prev
= prevmem
;
451 if (header
== last_alloc
)
452 last_alloc
= prevmem
;
457 pthread_mutex_unlock(&memmut
);
459 pthread_mutex_destroy(&memmut
);
461 //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt);
466 //memset(header + 1, 0xcc, header->size);
472 static inline void* my_mreq(int size
, int to_zero
)
474 return mreq_private(size
, to_zero
, AREATYPE_CLIENT
);
477 static int my_size(void* memory
)
479 if(!memory
) return 0;
480 return ((alloc_header
*)memory
)[-1].size
;
483 static void* my_realloc(void* memory
, int size
)
488 return my_mreq(size
, 0);
489 osize
= my_size(memory
);
492 ans
= my_mreq(size
, 0);
493 memcpy(ans
, memory
, osize
);
501 * WINE API - native implementation for several win32 libraries
505 static int WINAPI
ext_unknown()
507 printf("Unknown func called\n");
511 static int WINAPI
expGetVolumeInformationA( const char *root
, char *label
,
512 unsigned int label_len
, unsigned int *serial
,
513 unsigned int *filename_len
,unsigned int *flags
,
514 char *fsname
, unsigned int fsname_len
)
516 dbgprintf("GetVolumeInformationA( %s, 0x%x, %ld, 0x%x, 0x%x, 0x%x, 0x%x, %ld) => 1\n",
517 root
,label
,label_len
,serial
,filename_len
,flags
,fsname
,fsname_len
);
518 //hack Do not return any real data - do nothing
522 static unsigned int WINAPI
expGetDriveTypeA( const char *root
)
524 dbgprintf("GetDriveTypeA( %s ) => %d\n",root
,DRIVE_FIXED
);
525 // hack return as Fixed Drive Type
529 static unsigned int WINAPI
expGetLogicalDriveStringsA( unsigned int len
, char *buffer
)
531 dbgprintf("GetLogicalDriveStringsA(%d, 0x%x) => 4\n",len
,buffer
);
532 // hack only have one drive c:\ in this hack
538 return 4; // 1 drive * 4 bytes (includes null)
542 static int WINAPI
expIsBadWritePtr(void* ptr
, unsigned int count
)
544 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
545 dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
548 static int WINAPI
expIsBadReadPtr(void* ptr
, unsigned int count
)
550 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
551 dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
554 static int WINAPI
expDisableThreadLibraryCalls(int module
)
556 dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module
);
560 static HMODULE WINAPI
expGetDriverModuleHandle(DRVR
* pdrv
)
566 result
=pdrv
->hDriverModule
;
567 dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv
, result
);
571 #define MODULE_HANDLE_kernel32 ((HMODULE)0x120)
572 #define MODULE_HANDLE_user32 ((HMODULE)0x121)
574 #define MODULE_HANDLE_wininet ((HMODULE)0x122)
575 #define MODULE_HANDLE_ddraw ((HMODULE)0x123)
576 #define MODULE_HANDLE_advapi32 ((HMODULE)0x124)
578 #define MODULE_HANDLE_comdlg32 ((HMODULE)0x125)
579 #define MODULE_HANDLE_msvcrt ((HMODULE)0x126)
580 #define MODULE_HANDLE_ole32 ((HMODULE)0x127)
581 #define MODULE_HANDLE_winmm ((HMODULE)0x128)
583 static HMODULE WINAPI
expGetModuleHandleA(const char* name
)
595 wm
=MODULE_FindModule(name
);
598 result
=(HMODULE
)(wm
->module
);
602 if(name
&& (strcasecmp(name
, "kernel32")==0 || !strcasecmp(name
, "kernel32.dll")))
603 result
=MODULE_HANDLE_kernel32
;
605 if(name
&& strcasecmp(name
, "user32")==0)
606 result
=MODULE_HANDLE_user32
;
609 dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name
, result
);
613 static void* WINAPI
expCreateThread(void* pSecAttr
, long dwStackSize
,
614 void* lpStartAddress
, void* lpParameter
,
615 long dwFlags
, long* dwThreadId
)
618 // printf("CreateThread:");
619 pth
= (pthread_t
*) my_mreq(sizeof(pthread_t
), 0);
620 pthread_create(pth
, NULL
, (void*(*)(void*))lpStartAddress
, lpParameter
);
622 printf( "WARNING: CreateThread flags not supported\n");
624 *dwThreadId
=(long)pth
;
627 list
=my_mreq(sizeof(th_list
), 1);
628 list
->next
=list
->prev
=NULL
;
632 list
->next
=my_mreq(sizeof(th_list
), 0);
633 list
->next
->prev
=list
;
634 list
->next
->next
=NULL
;
638 dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
639 pSecAttr
, dwStackSize
, lpStartAddress
, lpParameter
, dwFlags
, dwThreadId
, pth
);
654 struct mutex_list_t
* next
;
655 struct mutex_list_t
* prev
;
657 typedef struct mutex_list_t mutex_list
;
658 static mutex_list
* mlist
=NULL
;
660 void destroy_event(void* event
)
662 mutex_list
* pp
=mlist
;
663 // printf("garbage collector: destroy_event(%x)\n", event);
666 if(pp
==(mutex_list
*)event
)
669 pp
->next
->prev
=pp
->prev
;
671 pp
->prev
->next
=pp
->next
;
672 if(mlist
==(mutex_list
*)event
)
678 printf("%x => ", pp);
689 static void* WINAPI
expCreateEventA(void* pSecAttr
, char bManualReset
,
690 char bInitialState
, const char* name
)
699 printf("%x => ", pp);
706 mutex_list
* pp
=mlist
;
710 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==0))
712 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
713 pSecAttr
, bManualReset
, bInitialState
, name
, name
, pp
->pm
);
716 }while((pp
=pp
->prev
) != NULL
);
718 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
719 pthread_mutex_init(pm
, NULL
);
720 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
721 pthread_cond_init(pc
, NULL
);
724 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
725 mlist
->next
=mlist
->prev
=NULL
;
729 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
730 mlist
->next
->prev
=mlist
;
731 mlist
->next
->next
=NULL
;
734 mlist
->type
=0; /* Type Event */
737 mlist
->state
=bInitialState
;
738 mlist
->reset
=bManualReset
;
740 strncpy(mlist
->name
, name
, 127);
744 dbgprintf("ERROR::: CreateEventA failure\n");
747 pthread_mutex_lock(pm);
750 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
751 pSecAttr
, bManualReset
, bInitialState
, name
, name
, mlist
);
753 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
754 pSecAttr
, bManualReset
, bInitialState
, mlist
);
758 static void* WINAPI
expSetEvent(void* event
)
760 mutex_list
*ml
= (mutex_list
*)event
;
761 dbgprintf("SetEvent(%x) => 0x1\n", event
);
762 pthread_mutex_lock(ml
->pm
);
763 if (ml
->state
== 0) {
765 pthread_cond_signal(ml
->pc
);
767 pthread_mutex_unlock(ml
->pm
);
771 static void* WINAPI
expResetEvent(void* event
)
773 mutex_list
*ml
= (mutex_list
*)event
;
774 dbgprintf("ResetEvent(0x%x) => 0x1\n", event
);
775 pthread_mutex_lock(ml
->pm
);
777 pthread_mutex_unlock(ml
->pm
);
782 static void* WINAPI
expWaitForSingleObject(void* object
, int duration
)
784 mutex_list
*ml
= (mutex_list
*)object
;
785 // FIXME FIXME FIXME - this value is sometime unititialize !!!
786 int ret
= WAIT_FAILED
;
787 mutex_list
* pp
=mlist
;
788 if(object
== (void*)0xcfcf9898)
791 From GetCurrentThread() documentation:
792 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.
794 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.
796 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.
798 dbgprintf("WaitForSingleObject(thread_handle) called\n");
799 return (void*)WAIT_FAILED
;
801 dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object
, duration
);
803 // loop below was slightly fixed - its used just for checking if
804 // this object really exists in our list
807 while (pp
&& (pp
->pm
!= ml
->pm
))
810 dbgprintf("WaitForSingleObject: NotFound\n");
814 pthread_mutex_lock(ml
->pm
);
818 if (duration
== 0) { /* Check Only */
819 if (ml
->state
== 1) ret
= WAIT_FAILED
;
820 else ret
= WAIT_OBJECT_0
;
822 if (duration
== -1) { /* INFINITE */
824 pthread_cond_wait(ml
->pc
,ml
->pm
);
829 if (duration
> 0) { /* Timed Wait */
830 struct timespec abstime
;
832 gettimeofday(&now
, 0);
833 abstime
.tv_sec
= now
.tv_sec
+ (now
.tv_usec
+duration
)/1000000;
834 abstime
.tv_nsec
= ((now
.tv_usec
+duration
)%1000000)*1000;
836 ret
=pthread_cond_timedwait(ml
->pc
,ml
->pm
,&abstime
);
837 if (ret
== ETIMEDOUT
) ret
= WAIT_TIMEOUT
;
838 else ret
= WAIT_OBJECT_0
;
843 case 1: /* Semaphore */
845 if(ml
->semaphore
==0) ret
= WAIT_FAILED
;
851 if (duration
== -1) {
852 if (ml
->semaphore
==0)
853 pthread_cond_wait(ml
->pc
,ml
->pm
);
858 pthread_mutex_unlock(ml
->pm
);
860 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object
,duration
,ml
,ret
);
865 static void* WINAPI
expWaitForMultipleObjects(int count
, const void** objects
,
866 int WaitAll
, int duration
)
872 dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
873 count
, objects
, WaitAll
, duration
);
875 for (i
= 0; i
< count
; i
++)
877 object
= (void *)objects
[i
];
878 ret
= expWaitForSingleObject(object
, duration
);
880 dbgprintf("WaitAll flag not yet supported...\n");
887 static void WINAPI
expExitThread(int retcode
)
889 dbgprintf("ExitThread(%d)\n", retcode
);
890 pthread_exit(&retcode
);
893 static HANDLE WINAPI
expCreateMutexA(void *pSecAttr
,
894 char bInitialOwner
, const char *name
)
896 HANDLE mlist
= (HANDLE
)expCreateEventA(pSecAttr
, 0, 0, name
);
899 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
900 pSecAttr
, bInitialOwner
, name
, mlist
);
902 dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
903 pSecAttr
, bInitialOwner
, mlist
);
905 /* 10l to QTX, if CreateMutex returns a real mutex, WaitForSingleObject
906 waits for ever, else it works ;) */
911 static int WINAPI
expReleaseMutex(HANDLE hMutex
)
913 dbgprintf("ReleaseMutex(%x) => 1\n", hMutex
);
914 /* FIXME:XXX !! not yet implemented */
919 static int pf_set
= 0;
920 static BYTE PF
[64] = {0,};
922 static void DumpSystemInfo(const SYSTEM_INFO
* si
)
924 dbgprintf(" Processor architecture %d\n", si
->u
.s
.wProcessorArchitecture
);
925 dbgprintf(" Page size: %d\n", si
->dwPageSize
);
926 dbgprintf(" Minimum app address: %d\n", si
->lpMinimumApplicationAddress
);
927 dbgprintf(" Maximum app address: %d\n", si
->lpMaximumApplicationAddress
);
928 dbgprintf(" Active processor mask: 0x%x\n", si
->dwActiveProcessorMask
);
929 dbgprintf(" Number of processors: %d\n", si
->dwNumberOfProcessors
);
930 dbgprintf(" Processor type: 0x%x\n", si
->dwProcessorType
);
931 dbgprintf(" Allocation granularity: 0x%x\n", si
->dwAllocationGranularity
);
932 dbgprintf(" Processor level: 0x%x\n", si
->wProcessorLevel
);
933 dbgprintf(" Processor revision: 0x%x\n", si
->wProcessorRevision
);
936 static void WINAPI
expGetSystemInfo(SYSTEM_INFO
* si
)
938 /* FIXME: better values for the two entries below... */
939 static int cache
= 0;
940 static SYSTEM_INFO cachedsi
;
941 unsigned int regs
[4];
942 dbgprintf("GetSystemInfo(%p) =>\n", si
);
947 memset(PF
,0,sizeof(PF
));
950 cachedsi
.u
.s
.wProcessorArchitecture
= PROCESSOR_ARCHITECTURE_INTEL
;
951 cachedsi
.dwPageSize
= getpagesize();
953 /* FIXME: better values for the two entries below... */
954 cachedsi
.lpMinimumApplicationAddress
= (void *)0x00000000;
955 cachedsi
.lpMaximumApplicationAddress
= (void *)0x7FFFFFFF;
956 cachedsi
.dwActiveProcessorMask
= 1;
957 cachedsi
.dwNumberOfProcessors
= 1;
958 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
959 cachedsi
.dwAllocationGranularity
= 0x10000;
960 cachedsi
.wProcessorLevel
= 5; /* pentium */
961 cachedsi
.wProcessorRevision
= 0x0101;
964 /* mplayer's way to detect PF's */
966 #include "cpudetect.h"
967 extern CpuCaps gCpuCaps
;
970 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
972 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
973 if (gCpuCaps
.hasSSE2
)
974 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
975 if (gCpuCaps
.has3DNow
)
976 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
978 if (gCpuCaps
.cpuType
== 4)
980 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
981 cachedsi
.wProcessorLevel
= 4;
983 else if (gCpuCaps
.cpuType
>= 5)
985 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
986 cachedsi
.wProcessorLevel
= 5;
990 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
991 cachedsi
.wProcessorLevel
= 3;
993 cachedsi
.wProcessorRevision
= gCpuCaps
.cpuStepping
;
994 cachedsi
.dwNumberOfProcessors
= 1; /* hardcoded */
998 /* disable cpuid based detection (mplayer's cpudetect.c does this - see above) */
1000 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__svr4__) || defined(__DragonFly__)
1002 switch ((regs
[0] >> 8) & 0xf) { // cpu family
1003 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1004 cachedsi
.wProcessorLevel
= 3;
1006 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1007 cachedsi
.wProcessorLevel
= 4;
1009 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1010 cachedsi
.wProcessorLevel
= 5;
1012 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1013 cachedsi
.wProcessorLevel
= 5;
1015 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1016 cachedsi
.wProcessorLevel
= 5;
1019 cachedsi
.wProcessorRevision
= regs
[0] & 0xf; // stepping
1020 if (regs
[3] & (1 << 8))
1021 PF
[PF_COMPARE_EXCHANGE_DOUBLE
] = TRUE
;
1022 if (regs
[3] & (1 << 23))
1023 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1024 if (regs
[3] & (1 << 25))
1025 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1026 if (regs
[3] & (1 << 31))
1027 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1028 cachedsi
.dwNumberOfProcessors
=1;
1030 #endif /* MPLAYER */
1032 /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
1033 fdiv_bug and fpu emulation flags -- alex/MPlayer */
1038 FILE *f
= fopen ("/proc/cpuinfo", "r");
1043 mp_msg(MSGT_WIN32
, MSGL_WARN
, "expGetSystemInfo: "
1044 "/proc/cpuinfo not readable! "
1045 "Expect bad performance and/or weird behaviour\n");
1049 while (fgets(line
,200,f
)!=NULL
) {
1052 /* NOTE: the ':' is the only character we can rely on */
1053 if (!(value
= strchr(line
,':')))
1055 /* terminate the valuename */
1057 /* skip any leading spaces */
1058 while (*value
==' ') value
++;
1059 if ((s
=strchr(value
,'\n')))
1063 if (!lstrncmpiA(line
, "cpu family",strlen("cpu family"))) {
1064 if (isdigit (value
[0])) {
1065 switch (value
[0] - '0') {
1066 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1067 cachedsi
.wProcessorLevel
= 3;
1069 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1070 cachedsi
.wProcessorLevel
= 4;
1072 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1073 cachedsi
.wProcessorLevel
= 5;
1075 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1076 cachedsi
.wProcessorLevel
= 5;
1078 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1079 cachedsi
.wProcessorLevel
= 5;
1083 /* set the CPU type of the current processor */
1084 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1087 /* old 2.0 method */
1088 if (!lstrncmpiA(line
, "cpu",strlen("cpu"))) {
1089 if ( isdigit (value
[0]) && value
[1] == '8' &&
1090 value
[2] == '6' && value
[3] == 0
1092 switch (value
[0] - '0') {
1093 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1094 cachedsi
.wProcessorLevel
= 3;
1096 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1097 cachedsi
.wProcessorLevel
= 4;
1099 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1100 cachedsi
.wProcessorLevel
= 5;
1102 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1103 cachedsi
.wProcessorLevel
= 5;
1105 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1106 cachedsi
.wProcessorLevel
= 5;
1110 /* set the CPU type of the current processor */
1111 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1114 if (!lstrncmpiA(line
,"fdiv_bug",strlen("fdiv_bug"))) {
1115 if (!lstrncmpiA(value
,"yes",3))
1116 PF
[PF_FLOATING_POINT_PRECISION_ERRATA
] = TRUE
;
1120 if (!lstrncmpiA(line
,"fpu",strlen("fpu"))) {
1121 if (!lstrncmpiA(value
,"no",2))
1122 PF
[PF_FLOATING_POINT_EMULATED
] = TRUE
;
1126 if (!lstrncmpiA(line
,"processor",strlen("processor"))) {
1127 /* processor number counts up...*/
1130 if (sscanf(value
,"%d",&x
))
1131 if (x
+1>cachedsi
.dwNumberOfProcessors
)
1132 cachedsi
.dwNumberOfProcessors
=x
+1;
1134 /* Create a new processor subkey on a multiprocessor
1137 sprintf(buf
,"%d",x
);
1139 if (!lstrncmpiA(line
,"stepping",strlen("stepping"))) {
1142 if (sscanf(value
,"%d",&x
))
1143 cachedsi
.wProcessorRevision
= x
;
1146 ( (!lstrncmpiA(line
,"flags",strlen("flags")))
1147 || (!lstrncmpiA(line
,"features",strlen("features"))) )
1149 if (strstr(value
,"cx8"))
1150 PF
[PF_COMPARE_EXCHANGE_DOUBLE
] = TRUE
;
1151 if (strstr(value
,"mmx"))
1152 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1153 if (strstr(value
,"tsc"))
1154 PF
[PF_RDTSC_INSTRUCTION_AVAILABLE
] = TRUE
;
1155 if (strstr(value
,"xmm") || strstr(value
,"sse"))
1156 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1157 if (strstr(value
,"sse2"))
1158 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1159 if (strstr(value
,"3dnow"))
1160 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1165 * ad hoc fix for smp machines.
1166 * some problems on WaitForSingleObject,CreateEvent,SetEvent
1167 * CreateThread ...etc..
1170 cachedsi
.dwNumberOfProcessors
=1;
1172 #endif /* __linux__ */
1175 memcpy(si
,&cachedsi
,sizeof(*si
));
1179 // avoid undefined expGetSystemInfo
1180 static WIN_BOOL WINAPI
expIsProcessorFeaturePresent(DWORD v
)
1182 WIN_BOOL result
= 0;
1186 expGetSystemInfo(&si
);
1188 if(v
<64) result
=PF
[v
];
1189 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v
, result
);
1194 static long WINAPI
expGetVersion()
1196 dbgprintf("GetVersion() => 0xC0000004\n");
1197 return 0xC0000004;//Windows 95
1200 static HANDLE WINAPI
expHeapCreate(long flags
, long init_size
, long max_size
)
1202 // printf("HeapCreate:");
1205 result
=(HANDLE
)my_mreq(0x110000, 0);
1207 result
=(HANDLE
)my_mreq((init_size
+ 0xfff) & 0x7ffff000 , 0);
1208 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags
, init_size
, max_size
, result
);
1212 // this is another dirty hack
1213 // VP31 is releasing one allocated Heap chunk twice
1214 // we will silently ignore this second call...
1215 static void* heapfreehack
= 0;
1216 static int heapfreehackshown
= 0;
1217 //extern void trapbug(void);
1218 static void* WINAPI
expHeapAlloc(HANDLE heap
, int flags
, int size
)
1222 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1223 HeapAlloc returns area larger than size argument :-/
1225 actually according to M$ Doc HeapCreate size should be rounded
1226 to page boundaries thus we should simulate this
1228 //if (size == 22276) trapbug();
1229 z
=my_mreq((size
+ 0xfff) & 0x7ffff000, (flags
& HEAP_ZERO_MEMORY
));
1231 printf("HeapAlloc failure\n");
1232 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap
, flags
, size
, z
);
1233 heapfreehack
= 0; // reset
1236 static long WINAPI
expHeapDestroy(void* heap
)
1238 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap
);
1243 static long WINAPI
expHeapFree(HANDLE heap
, DWORD dwFlags
, LPVOID lpMem
)
1245 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap
, dwFlags
, lpMem
);
1246 if (heapfreehack
!= lpMem
&& lpMem
!= (void*)0xffffffff
1247 && lpMem
!= (void*)0xbdbdbdbd)
1248 // 0xbdbdbdbd is for i263_drv.drv && libefence
1249 // it seems to be reading from relased memory
1250 // EF_PROTECT_FREE doens't show any probleme
1254 if (!heapfreehackshown
++)
1255 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem
);
1257 heapfreehack
= lpMem
;
1260 static long WINAPI
expHeapSize(int heap
, int flags
, void* pointer
)
1262 long result
=my_size(pointer
);
1263 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap
, flags
, pointer
, result
);
1266 static void* WINAPI
expHeapReAlloc(HANDLE heap
,int flags
,void *lpMem
,int size
)
1268 long orgsize
= my_size(lpMem
);
1269 dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize
,size
);
1270 return my_realloc(lpMem
, size
);
1272 static long WINAPI
expGetProcessHeap(void)
1274 dbgprintf("GetProcessHeap() => 1\n");
1277 static void* WINAPI
expVirtualAlloc(void* v1
, long v2
, long v3
, long v4
)
1279 void* z
= VirtualAlloc(v1
, v2
, v3
, v4
);
1281 printf("VirtualAlloc failure\n");
1282 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1
,v2
,v3
,v4
, z
);
1285 static int WINAPI
expVirtualFree(void* v1
, int v2
, int v3
)
1287 int result
= VirtualFree(v1
,v2
,v3
);
1288 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1
,v2
,v3
, result
);
1292 /* we're building a table of critical sections. cs_win pointer uses the DLL
1293 cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1294 struct critsecs_list_t
1296 CRITICAL_SECTION
*cs_win
;
1297 struct CRITSECT
*cs_unix
;
1300 /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1301 #undef CRITSECS_NEWTYPE
1302 //#define CRITSECS_NEWTYPE 1
1304 #ifdef CRITSECS_NEWTYPE
1305 /* increased due to ucod needs more than 32 entries */
1306 /* and 64 should be enough for everything */
1307 #define CRITSECS_LIST_MAX 64
1308 static struct critsecs_list_t critsecs_list
[CRITSECS_LIST_MAX
];
1310 static int critsecs_get_pos(CRITICAL_SECTION
*cs_win
)
1314 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1315 if (critsecs_list
[i
].cs_win
== cs_win
)
1320 static int critsecs_get_unused(void)
1324 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1325 if (critsecs_list
[i
].cs_win
== NULL
)
1330 struct CRITSECT
*critsecs_get_unix(CRITICAL_SECTION
*cs_win
)
1334 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1335 if (critsecs_list
[i
].cs_win
== cs_win
&& critsecs_list
[i
].cs_unix
)
1336 return(critsecs_list
[i
].cs_unix
);
1341 static void WINAPI
expInitializeCriticalSection(CRITICAL_SECTION
* c
)
1343 dbgprintf("InitializeCriticalSection(0x%x)\n", c
);
1344 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1346 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1347 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1350 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1351 #ifdef CRITSECS_NEWTYPE
1353 struct CRITSECT
*cs
;
1354 int i
= critsecs_get_unused();
1358 printf("InitializeCriticalSection(%p) - no more space in list\n", c
);
1361 dbgprintf("got unused space at %d\n", i
);
1362 cs
= malloc(sizeof(struct CRITSECT
));
1365 printf("InitializeCriticalSection(%p) - out of memory\n", c
);
1368 pthread_mutex_init(&cs
->mutex
, NULL
);
1370 critsecs_list
[i
].cs_win
= c
;
1371 critsecs_list
[i
].cs_unix
= cs
;
1372 dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1377 struct CRITSECT
* cs
= mreq_private(sizeof(struct CRITSECT
) + sizeof(CRITICAL_SECTION
),
1378 0, AREATYPE_CRITSECT
);
1379 pthread_mutex_init(&cs
->mutex
, NULL
);
1381 cs
->deadbeef
= 0xdeadbeef;
1388 static void WINAPI
expEnterCriticalSection(CRITICAL_SECTION
* c
)
1390 #ifdef CRITSECS_NEWTYPE
1391 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1393 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1395 dbgprintf("EnterCriticalSection(0x%x) %p\n",c
, cs
);
1398 dbgprintf("entered uninitialized critisec!\n");
1399 expInitializeCriticalSection(c
);
1400 #ifdef CRITSECS_NEWTYPE
1401 cs
=critsecs_get_unix(c
);
1403 cs
= (*(struct CRITSECT
**)c
);
1405 dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c
);
1408 if(cs
->id
==pthread_self())
1410 pthread_mutex_lock(&(cs
->mutex
));
1412 cs
->id
=pthread_self();
1415 static void WINAPI
expLeaveCriticalSection(CRITICAL_SECTION
* c
)
1417 #ifdef CRITSECS_NEWTYPE
1418 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1420 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1422 // struct CRITSECT* cs=(struct CRITSECT*)c;
1423 dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c
, cs
);
1426 dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c
);
1432 pthread_mutex_unlock(&(cs
->mutex
));
1435 dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c
);
1439 static void expfree(void* mem
); /* forward declaration */
1441 static void WINAPI
expDeleteCriticalSection(CRITICAL_SECTION
*c
)
1443 #ifdef CRITSECS_NEWTYPE
1444 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1446 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1448 // struct CRITSECT* cs=(struct CRITSECT*)c;
1449 dbgprintf("DeleteCriticalSection(0x%x)\n",c
);
1453 dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c
);
1459 dbgprintf("Win32 Warning: Deleting unlocked Critical Section %p!!\n", c
);
1460 pthread_mutex_unlock(&(cs
->mutex
));
1464 pthread_mutex_destroy(&(cs
->mutex
));
1465 // released by GarbageCollector in my_relase otherwise
1468 #ifdef CRITSECS_NEWTYPE
1470 int i
= critsecs_get_pos(c
);
1474 printf("DeleteCriticalSection(%p) error (critsec not found)\n", c
);
1478 critsecs_list
[i
].cs_win
= NULL
;
1479 expfree(critsecs_list
[i
].cs_unix
);
1480 critsecs_list
[i
].cs_unix
= NULL
;
1481 dbgprintf("DeleteCriticalSection -> itemno=%d\n", i
);
1486 static int WINAPI
expGetCurrentThreadId()
1488 dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1489 return pthread_self();
1491 static int WINAPI
expGetCurrentProcess()
1493 dbgprintf("GetCurrentProcess() => %d\n", getpid());
1498 // this version is required for Quicktime codecs (.qtx/.qts) to work.
1499 // (they assume some pointers at FS: segment)
1501 extern void* fs_seg
;
1503 //static int tls_count;
1504 static int tls_use_map
[64];
1505 static int WINAPI
expTlsAlloc()
1509 if(tls_use_map
[i
]==0)
1512 dbgprintf("TlsAlloc() => %d\n",i
);
1515 dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1519 //static int WINAPI expTlsSetValue(DWORD index, void* value)
1520 static int WINAPI
expTlsSetValue(int index
, void* value
)
1522 dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index
,value
);
1523 // if((index<0) || (index>64))
1526 *(void**)((char*)fs_seg
+0x88+4*index
) = value
;
1530 static void* WINAPI
expTlsGetValue(DWORD index
)
1532 dbgprintf("TlsGetValue(%d)\n",index
);
1533 // if((index<0) || (index>64))
1534 if((index
>=64)) return NULL
;
1535 return *(void**)((char*)fs_seg
+0x88+4*index
);
1538 static int WINAPI
expTlsFree(int idx
)
1540 int index
= (int) idx
;
1541 dbgprintf("TlsFree(%d)\n",index
);
1542 if((index
<0) || (index
>64))
1544 tls_use_map
[index
]=0;
1556 static void* WINAPI
expTlsAlloc()
1560 g_tls
=my_mreq(sizeof(tls_t
), 0);
1561 g_tls
->next
=g_tls
->prev
=NULL
;
1565 g_tls
->next
=my_mreq(sizeof(tls_t
), 0);
1566 g_tls
->next
->prev
=g_tls
;
1567 g_tls
->next
->next
=NULL
;
1570 dbgprintf("TlsAlloc() => 0x%x\n", g_tls
);
1572 g_tls
->value
=0; /* XXX For Divx.dll */
1576 static int WINAPI
expTlsSetValue(void* idx
, void* value
)
1578 tls_t
* index
= (tls_t
*) idx
;
1587 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index
, value
, result
);
1590 static void* WINAPI
expTlsGetValue(void* idx
)
1592 tls_t
* index
= (tls_t
*) idx
;
1597 result
=index
->value
;
1598 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index
, result
);
1601 static int WINAPI
expTlsFree(void* idx
)
1603 tls_t
* index
= (tls_t
*) idx
;
1610 index
->next
->prev
=index
->prev
;
1612 index
->prev
->next
=index
->next
;
1614 g_tls
= index
->prev
;
1615 my_release((void*)index
);
1618 dbgprintf("TlsFree(index 0x%x) => %d\n", index
, result
);
1623 static void* WINAPI
expLocalAlloc(int flags
, int size
)
1625 void* z
= my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1627 printf("LocalAlloc() failed\n");
1628 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1632 static void* WINAPI
expLocalReAlloc(int handle
,int size
, int flags
)
1638 if (flags
& LMEM_MODIFY
) {
1639 dbgprintf("LocalReAlloc MODIFY\n");
1640 return (void *)handle
;
1642 oldsize
= my_size((void *)handle
);
1643 newpointer
= my_realloc((void *)handle
,size
);
1644 dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle
,size
,oldsize
, flags
,newpointer
);
1649 static void* WINAPI
expLocalLock(void* z
)
1651 dbgprintf("LocalLock(0x%x) => 0x%x\n", z
, z
);
1655 static void* WINAPI
expGlobalAlloc(int flags
, int size
)
1658 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size
, flags
);
1660 z
=my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1661 //z=calloc(size, 1);
1664 printf("GlobalAlloc() failed\n");
1665 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1668 static void* WINAPI
expGlobalLock(void* z
)
1670 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z
, z
);
1673 // pvmjpg20 - but doesn't work anyway
1674 static int WINAPI
expGlobalSize(void* amem
)
1678 alloc_header
* header
= last_alloc
;
1679 alloc_header
* mem
= (alloc_header
*) amem
- 1;
1682 pthread_mutex_lock(&memmut
);
1685 if (header
->deadbeef
!= 0xdeadbeef)
1687 dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
1693 size
= header
->size
;
1697 header
= header
->prev
;
1699 pthread_mutex_unlock(&memmut
);
1702 dbgprintf("GlobalSize(0x%x)\n", amem
);
1706 static int WINAPI
expLoadIconA( long hinstance
, char *name
)
1708 dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance
,name
);
1712 static int WINAPI
expLoadStringA(long instance
, long id
, void* buf
, long size
)
1714 int result
=LoadStringA(instance
, id
, buf
, size
);
1716 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1717 instance
, id
, buf
, size
, result
, buf
);
1719 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1720 // instance, id, buf, size, result);
1724 static long WINAPI
expMultiByteToWideChar(long v1
, long v2
, char* s1
, long siz1
, short* s2
, int siz2
)
1733 if(siz1
>siz2
/2)siz1
=siz2
/2;
1734 for(i
=1; i
<=siz1
; i
++)
1744 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1745 "size %d, dest buffer 0x%x, dest size %d) => %d\n",
1746 v1
, v2
, s1
, s1
, siz1
, s2
, siz2
, result
);
1748 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1749 "size %d, dest buffer 0x%x, dest size %d) =>\n",
1750 v1
, v2
, siz1
, s2
, siz2
, result
);
1753 static void wch_print(const short* str
)
1755 dbgprintf(" src: ");
1756 while(*str
)dbgprintf("%c", *str
++);
1759 static long WINAPI
expWideCharToMultiByte(long v1
, long v2
, short* s1
, long siz1
,
1760 char* s2
, int siz2
, char* c3
, int* siz3
)
1763 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1764 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1765 result
=WideCharToMultiByte(v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1766 dbgprintf("=> %d\n", result
);
1767 //if(s1)wch_print(s1);
1768 if(s2
)dbgprintf(" dest: %s\n", s2
);
1771 static long WINAPI
expGetVersionExA(OSVERSIONINFOA
* c
)
1773 dbgprintf("GetVersionExA(0x%x) => 1\n");
1774 c
->dwOSVersionInfoSize
=sizeof(*c
);
1775 c
->dwMajorVersion
=4;
1776 c
->dwMinorVersion
=0;
1777 c
->dwBuildNumber
=0x4000457;
1779 // leave it here for testing win9x-only codecs
1780 c
->dwPlatformId
=VER_PLATFORM_WIN32_WINDOWS
;
1781 strcpy(c
->szCSDVersion
, " B");
1783 c
->dwPlatformId
=VER_PLATFORM_WIN32_NT
; // let's not make DLL assume that it can read CR* registers
1784 strcpy(c
->szCSDVersion
, "Service Pack 3");
1786 dbgprintf(" Major version: 4\n Minor version: 0\n Build number: 0x4000457\n"
1787 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 3'\n");
1790 static HANDLE WINAPI
expCreateSemaphoreA(char* v1
, long init_count
,
1791 long max_count
, char* name
)
1793 pthread_mutex_t
*pm
;
1797 printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1801 printf("%p => ", pp);
1808 mutex_list
* pp
=mlist
;
1812 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==1))
1814 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1815 v1
, init_count
, max_count
, name
, name
, mlist
);
1816 return (HANDLE
)mlist
;
1818 }while((pp
=pp
->prev
) != NULL
);
1820 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
1821 pthread_mutex_init(pm
, NULL
);
1822 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
1823 pthread_cond_init(pc
, NULL
);
1826 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1827 mlist
->next
=mlist
->prev
=NULL
;
1831 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1832 mlist
->next
->prev
=mlist
;
1833 mlist
->next
->next
=NULL
;
1835 // printf("new semaphore %p\n", mlist);
1837 mlist
->type
=1; /* Type Semaphore */
1842 mlist
->semaphore
=init_count
;
1844 strncpy(mlist
->name
, name
, 64);
1848 dbgprintf("ERROR::: CreateSemaphoreA failure\n");
1850 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1851 v1
, init_count
, max_count
, name
, name
, mlist
);
1853 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1854 v1
, init_count
, max_count
, mlist
);
1855 return (HANDLE
)mlist
;
1858 static long WINAPI
expReleaseSemaphore(long hsem
, long increment
, long* prev_count
)
1860 // The state of a semaphore object is signaled when its count
1861 // is greater than zero and nonsignaled when its count is equal to zero
1862 // Each time a waiting thread is released because of the semaphore's signaled
1863 // state, the count of the semaphore is decreased by one.
1864 mutex_list
*ml
= (mutex_list
*)hsem
;
1866 pthread_mutex_lock(ml
->pm
);
1867 if (prev_count
!= 0) *prev_count
= ml
->semaphore
;
1868 if (ml
->semaphore
== 0) pthread_cond_signal(ml
->pc
);
1869 ml
->semaphore
+= increment
;
1870 pthread_mutex_unlock(ml
->pm
);
1871 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1872 hsem
, increment
, prev_count
);
1877 static long WINAPI
expRegOpenKeyExA(long key
, const char* subkey
, long reserved
, long access
, int* newkey
)
1879 long result
=RegOpenKeyExA(key
, subkey
, reserved
, access
, newkey
);
1880 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
1881 key
, subkey
, reserved
, access
, newkey
, result
);
1882 if(newkey
)dbgprintf(" New key: 0x%x\n", *newkey
);
1885 static long WINAPI
expRegCloseKey(long key
)
1887 long result
=RegCloseKey(key
);
1888 dbgprintf("RegCloseKey(0x%x) => %d\n", key
, result
);
1891 static long WINAPI
expRegQueryValueExA(long key
, const char* value
, int* reserved
, int* type
, int* data
, int* count
)
1893 long result
=RegQueryValueExA(key
, value
, reserved
, type
, data
, count
);
1894 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
1895 " => 0x%x\n", key
, value
, reserved
, data
, count
, result
);
1896 if(data
&& count
)dbgprintf(" read %d bytes: '%s'\n", *count
, data
);
1900 //from wine source dlls/advapi32/registry.c
1901 static long WINAPI
expRegCreateKeyA(long hkey
, const char* name
, int *retkey
)
1903 dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey
,name
,retkey
);
1904 return RegCreateKeyExA( hkey
, name
, 0, NULL
,REG_OPTION_NON_VOLATILE
,
1905 KEY_ALL_ACCESS
, NULL
, retkey
, NULL
);
1908 static long WINAPI
expRegCreateKeyExA(long key
, const char* name
, long reserved
,
1909 void* classs
, long options
, long security
,
1910 void* sec_attr
, int* newkey
, int* status
)
1912 long result
=RegCreateKeyExA(key
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
);
1913 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
1914 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
1915 key
, name
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
, result
);
1916 if(!result
&& newkey
) dbgprintf(" New key: 0x%x\n", *newkey
);
1917 if(!result
&& status
) dbgprintf(" New key status: 0x%x\n", *status
);
1920 static long WINAPI
expRegSetValueExA(long key
, const char* name
, long v1
, long v2
, void* data
, long size
)
1922 long result
=RegSetValueExA(key
, name
, v1
, v2
, data
, size
);
1923 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
1924 key
, name
, v1
, v2
, data
, *(int*)data
, data
, size
, result
);
1928 static long WINAPI
expRegOpenKeyA (long hKey
, LPCSTR lpSubKey
, int* phkResult
)
1930 long result
=RegOpenKeyExA(hKey
, lpSubKey
, 0, 0, phkResult
);
1931 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
1932 hKey
, lpSubKey
, phkResult
, result
);
1933 if(!result
&& phkResult
) dbgprintf(" New key: 0x%x\n", *phkResult
);
1937 static DWORD WINAPI
expRegEnumValueA(HKEY hkey
, DWORD index
, LPSTR value
, LPDWORD val_count
,
1938 LPDWORD reserved
, LPDWORD type
, LPBYTE data
, LPDWORD count
)
1940 return RegEnumValueA(hkey
, index
, value
, val_count
,
1941 reserved
, type
, data
, count
);
1944 static DWORD WINAPI
expRegEnumKeyExA(HKEY hKey
, DWORD dwIndex
, LPSTR lpName
, LPDWORD lpcbName
,
1945 LPDWORD lpReserved
, LPSTR lpClass
, LPDWORD lpcbClass
,
1946 LPFILETIME lpftLastWriteTime
)
1948 return RegEnumKeyExA(hKey
, dwIndex
, lpName
, lpcbName
, lpReserved
, lpClass
,
1949 lpcbClass
, lpftLastWriteTime
);
1952 static long WINAPI
expQueryPerformanceCounter(long long* z
)
1955 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z
, *z
);
1960 * dummy function RegQueryInfoKeyA(), required by vss codecs
1962 static DWORD WINAPI
expRegQueryInfoKeyA( HKEY hkey
, LPSTR
class, LPDWORD class_len
, LPDWORD reserved
,
1963 LPDWORD subkeys
, LPDWORD max_subkey
, LPDWORD max_class
,
1964 LPDWORD values
, LPDWORD max_value
, LPDWORD max_data
,
1965 LPDWORD security
, FILETIME
*modif
)
1967 return ERROR_SUCCESS
;
1971 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
1973 static double linux_cpuinfo_freq()
1980 f
= fopen ("/proc/cpuinfo", "r");
1982 while (fgets(line
,sizeof(line
),f
)!=NULL
) {
1983 /* NOTE: the ':' is the only character we can rely on */
1984 if (!(value
= strchr(line
,':')))
1986 /* terminate the valuename */
1988 /* skip any leading spaces */
1989 while (*value
==' ') value
++;
1990 if ((s
=strchr(value
,'\n')))
1993 if (!strncasecmp(line
, "cpu MHz",strlen("cpu MHz"))
1994 && sscanf(value
, "%lf", &freq
) == 1) {
2005 static double solaris_kstat_freq()
2007 #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
2009 * try to extract the CPU speed from the solaris kernel's kstat data
2013 kstat_named_t
*kdata
;
2019 ksp
= kstat_lookup(kc
, "cpu_info", 0, "cpu_info0");
2021 /* kstat found and name/value pairs? */
2022 if (ksp
!= NULL
&& ksp
->ks_type
== KSTAT_TYPE_NAMED
)
2024 /* read the kstat data from the kernel */
2025 if (kstat_read(kc
, ksp
, NULL
) != -1)
2028 * lookup desired "clock_MHz" entry, check the expected
2031 kdata
= (kstat_named_t
*)kstat_data_lookup(ksp
, "clock_MHz");
2032 if (kdata
!= NULL
&& kdata
->data_type
== KSTAT_DATA_INT32
)
2033 mhz
= kdata
->value
.i32
;
2041 #endif /* HAVE_LIBKSTAT */
2042 return -1; // kstat stuff is not available, CPU freq is unknown
2046 * Measure CPU freq using the pentium's time stamp counter register (TSC)
2048 static double tsc_freq()
2050 static double ofreq
=0.0;
2054 if (ofreq
!= 0.0) return ofreq
;
2055 while(i
==time(NULL
));
2058 while(i
==time(NULL
));
2060 ofreq
= (double)(y
-x
)/1000.;
2064 static double CPU_Freq()
2068 if ((freq
= linux_cpuinfo_freq()) > 0)
2071 if ((freq
= solaris_kstat_freq()) > 0)
2077 static long WINAPI
expQueryPerformanceFrequency(long long* z
)
2079 *z
=(long long)CPU_Freq();
2080 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z
, *z
);
2083 static long WINAPI
exptimeGetTime()
2087 gettimeofday(&t
, 0);
2088 result
=1000*t
.tv_sec
+t
.tv_usec
/1000;
2089 dbgprintf("timeGetTime() => %d\n", result
);
2092 static void* WINAPI
expLocalHandle(void* v
)
2094 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v
, v
);
2098 static void* WINAPI
expGlobalHandle(void* v
)
2100 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v
, v
);
2103 static int WINAPI
expGlobalUnlock(void* v
)
2105 dbgprintf("GlobalUnlock(0x%x) => 1\n", v
);
2108 static void* WINAPI
expGlobalFree(void* v
)
2110 dbgprintf("GlobalFree(0x%x) => 0\n", v
);
2116 static void* WINAPI
expGlobalReAlloc(void* v
, int size
, int flags
)
2118 void* result
=my_realloc(v
, size
);
2119 //void* result=realloc(v, size);
2120 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v
,size
,flags
,result
);
2124 static int WINAPI
expLocalUnlock(void* v
)
2126 dbgprintf("LocalUnlock(0x%x) => 1\n", v
);
2130 static void* WINAPI
expLocalFree(void* v
)
2132 dbgprintf("LocalFree(0x%x) => 0\n", v
);
2136 static HRSRC WINAPI
expFindResourceA(HMODULE module
, char* name
, char* type
)
2140 result
=FindResourceA(module
, name
, type
);
2141 dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2142 module
, name
, HIWORD(name
) ? name
: "UNICODE", type
, HIWORD(type
) ? type
: "UNICODE", result
);
2146 extern HRSRC WINAPI
LoadResource(HMODULE
, HRSRC
);
2147 static HGLOBAL WINAPI
expLoadResource(HMODULE module
, HRSRC res
)
2149 HGLOBAL result
=LoadResource(module
, res
);
2150 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module
, res
, result
);
2153 static void* WINAPI
expLockResource(long res
)
2155 void* result
=LockResource(res
);
2156 dbgprintf("LockResource(0x%x) => 0x%x\n", res
, result
);
2159 static int WINAPI
expFreeResource(long res
)
2161 int result
=FreeResource(res
);
2162 dbgprintf("FreeResource(0x%x) => %d\n", res
, result
);
2167 static int WINAPI
expCloseHandle(long v1
)
2169 dbgprintf("CloseHandle(0x%x) => 1\n", v1
);
2170 /* do not close stdin,stdout and stderr */
2177 static const char* WINAPI
expGetCommandLineA()
2179 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2180 return "c:\\aviplay.exe";
2182 static short envs
[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2183 static LPWSTR WINAPI
expGetEnvironmentStringsW()
2185 dbgprintf("GetEnvironmentStringsW() => 0\n", envs
);
2188 static void * WINAPI
expRtlZeroMemory(void *p
, size_t len
)
2190 void* result
=memset(p
,0,len
);
2191 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p
,len
,result
);
2194 static void * WINAPI
expRtlMoveMemory(void *dst
, void *src
, size_t len
)
2196 void* result
=memmove(dst
,src
,len
);
2197 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst
,src
,len
,result
);
2201 static void * WINAPI
expRtlFillMemory(void *p
, int ch
, size_t len
)
2203 void* result
=memset(p
,ch
,len
);
2204 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p
,ch
,len
,result
);
2207 static int WINAPI
expFreeEnvironmentStringsW(short* strings
)
2209 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings
);
2212 static int WINAPI
expFreeEnvironmentStringsA(char* strings
)
2214 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings
);
2218 static const char ch_envs
[]=
2219 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2220 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2221 static LPCSTR WINAPI
expGetEnvironmentStrings()
2223 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs
);
2224 return (LPCSTR
)ch_envs
;
2225 // dbgprintf("GetEnvironmentStrings() => 0\n");
2229 static int WINAPI
expGetStartupInfoA(STARTUPINFOA
*s
)
2232 dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2233 memset(s
, 0, sizeof(*s
));
2235 // s->lpReserved="Reserved";
2236 // s->lpDesktop="Desktop";
2237 // s->lpTitle="Title";
2239 // s->dwXSize=s->dwYSize=200;
2240 s
->dwFlags
=s
->wShowWindow
=1;
2241 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2242 dbgprintf(" cb=%d\n", s
->cb
);
2243 dbgprintf(" lpReserved='%s'\n", s
->lpReserved
);
2244 dbgprintf(" lpDesktop='%s'\n", s
->lpDesktop
);
2245 dbgprintf(" lpTitle='%s'\n", s
->lpTitle
);
2246 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2247 s
->dwX
, s
->dwY
, s
->dwXSize
, s
->dwYSize
);
2248 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2249 s
->dwXCountChars
, s
->dwYCountChars
, s
->dwFillAttribute
);
2250 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2251 s
->dwFlags
, s
->wShowWindow
, s
->cbReserved2
);
2252 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2253 s
->lpReserved2
, s
->hStdInput
, s
->hStdOutput
, s
->hStdError
);
2257 static int WINAPI
expGetStdHandle(int z
)
2259 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z
+0x1234);
2264 #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2265 #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2268 static int WINAPI
expGetFileType(int handle
)
2270 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle
);
2274 static int WINAPI
expGetFileAttributesA(char *filename
)
2276 dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename
);
2277 if (strstr(filename
, "QuickTime.qts"))
2278 return FILE_ATTRIBUTE_SYSTEM
;
2279 return FILE_ATTRIBUTE_NORMAL
;
2282 static int WINAPI
expSetHandleCount(int count
)
2284 dbgprintf("SetHandleCount(0x%x) => 1\n", count
);
2287 static int WINAPI
expGetACP(void)
2289 dbgprintf("GetACP() => 0\n");
2292 extern WINE_MODREF
*MODULE32_LookupHMODULE(HMODULE m
);
2293 static int WINAPI
expGetModuleFileNameA(int module
, char* s
, int len
)
2297 //printf("File name of module %X (%s) requested\n", module, s);
2299 if (module
== 0 && len
>= 12)
2301 /* return caller program name */
2302 strcpy(s
, "aviplay.dll");
2313 strcpy(s
, "c:\\windows\\system\\");
2314 mr
=MODULE32_LookupHMODULE(module
);
2316 strcat(s
, "aviplay.dll");
2318 if(strrchr(mr
->filename
, '/')==NULL
)
2319 strcat(s
, mr
->filename
);
2321 strcat(s
, strrchr(mr
->filename
, '/')+1);
2324 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2325 module
, s
, len
, result
);
2327 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2328 module
, s
, len
, result
, s
);
2332 static int WINAPI
expSetUnhandledExceptionFilter(void* filter
)
2334 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter
);
2335 return 1;//unsupported and probably won't ever be supported
2338 static int WINAPI
expLoadLibraryA(char* name
)
2345 // we skip to the last backslash
2346 // this is effectively eliminating weird characters in
2347 // the text output windows
2349 lastbc
= strrchr(name
, '\\');
2356 name
[i
] = *lastbc
++;
2361 if(strncmp(name
, "c:\\windows\\", 11)==0) name
+= 11;
2362 if(strncmp(name
, ".\\", 2)==0) name
+= 2;
2364 dbgprintf("Entering LoadLibraryA(%s)\n", name
);
2366 // PIMJ and VIVO audio are loading kernel32.dll
2367 if (strcasecmp(name
, "kernel32.dll") == 0 || strcasecmp(name
, "kernel32") == 0)
2368 return MODULE_HANDLE_kernel32
;
2369 // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2370 /* exported -> do not return failed! */
2372 if (strcasecmp(name
, "user32.dll") == 0 || strcasecmp(name
, "user32") == 0)
2373 // return MODULE_HANDLE_kernel32;
2374 return MODULE_HANDLE_user32
;
2377 if (strcasecmp(name
, "wininet.dll") == 0 || strcasecmp(name
, "wininet") == 0)
2378 return MODULE_HANDLE_wininet
;
2379 if (strcasecmp(name
, "ddraw.dll") == 0 || strcasecmp(name
, "ddraw") == 0)
2380 return MODULE_HANDLE_ddraw
;
2381 if (strcasecmp(name
, "advapi32.dll") == 0 || strcasecmp(name
, "advapi32") == 0)
2382 return MODULE_HANDLE_advapi32
;
2385 if (strcasecmp(name
, "comdlg32.dll") == 0 || strcasecmp(name
, "comdlg32") == 0)
2386 return MODULE_HANDLE_comdlg32
;
2387 if (strcasecmp(name
, "msvcrt.dll") == 0 || strcasecmp(name
, "msvcrt") == 0)
2388 return MODULE_HANDLE_msvcrt
;
2389 if (strcasecmp(name
, "ole32.dll") == 0 || strcasecmp(name
, "ole32") == 0)
2390 return MODULE_HANDLE_ole32
;
2391 if (strcasecmp(name
, "winmm.dll") == 0 || strcasecmp(name
, "winmm") == 0)
2392 return MODULE_HANDLE_winmm
;
2394 result
=LoadLibraryA(name
);
2395 dbgprintf("Returned LoadLibraryA(0x%x='%s'), def_path=%s => 0x%x\n", name
, name
, def_path
, result
);
2400 static int WINAPI
expFreeLibrary(int module
)
2403 int result
=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2405 int result
=FreeLibrary(module
);
2407 dbgprintf("FreeLibrary(0x%x) => %d\n", module
, result
);
2411 static void* WINAPI
expGetProcAddress(HMODULE mod
, char* name
)
2415 case MODULE_HANDLE_kernel32
:
2416 result
=LookupExternalByName("kernel32.dll", name
); break;
2417 case MODULE_HANDLE_user32
:
2418 result
=LookupExternalByName("user32.dll", name
); break;
2420 case MODULE_HANDLE_wininet
:
2421 result
=LookupExternalByName("wininet.dll", name
); break;
2422 case MODULE_HANDLE_ddraw
:
2423 result
=LookupExternalByName("ddraw.dll", name
); break;
2424 case MODULE_HANDLE_advapi32
:
2425 result
=LookupExternalByName("advapi32.dll", name
); break;
2427 case MODULE_HANDLE_comdlg32
:
2428 result
=LookupExternalByName("comdlg32.dll", name
); break;
2429 case MODULE_HANDLE_msvcrt
:
2430 result
=LookupExternalByName("msvcrt.dll", name
); break;
2431 case MODULE_HANDLE_ole32
:
2432 result
=LookupExternalByName("ole32.dll", name
); break;
2433 case MODULE_HANDLE_winmm
:
2434 result
=LookupExternalByName("winmm.dll", name
); break;
2436 result
=GetProcAddress(mod
, name
);
2438 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod
, name
, result
);
2442 static long WINAPI
expCreateFileMappingA(int hFile
, void* lpAttr
,
2443 long flProtect
, long dwMaxHigh
,
2444 long dwMaxLow
, const char* name
)
2446 long result
=CreateFileMappingA(hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
);
2448 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2449 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2450 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, result
);
2452 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2453 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2454 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
, name
, result
);
2458 static long WINAPI
expOpenFileMappingA(long hFile
, long hz
, const char* name
)
2460 long result
=OpenFileMappingA(hFile
, hz
, name
);
2462 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2465 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2466 hFile
, hz
, name
, name
, result
);
2470 static void* WINAPI
expMapViewOfFile(HANDLE file
, DWORD mode
, DWORD offHigh
,
2471 DWORD offLow
, DWORD size
)
2473 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2474 file
,mode
,offHigh
,offLow
,size
,(char*)file
+offLow
);
2475 return (char*)file
+offLow
;
2478 static void* WINAPI
expUnmapViewOfFile(void* view
)
2480 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view
);
2484 static void* WINAPI
expSleep(int time
)
2487 /* solaris doesn't have thread safe usleep */
2488 struct timespec tsp
;
2489 tsp
.tv_sec
= time
/ 1000000;
2490 tsp
.tv_nsec
= (time
% 1000000) * 1000;
2491 nanosleep(&tsp
, NULL
);
2495 dbgprintf("Sleep(%d) => 0\n", time
);
2499 // why does IV32 codec want to call this? I don't know ...
2500 static int WINAPI
expCreateCompatibleDC(int hdc
)
2503 //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2504 dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc
, dc
);
2508 static int WINAPI
expGetDeviceCaps(int hdc
, int unk
)
2510 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc
, unk
);
2512 #define BITSPIXEL 12
2514 if (unk
== BITSPIXEL
)
2522 static WIN_BOOL WINAPI
expDeleteDC(int hdc
)
2524 dbgprintf("DeleteDC(0x%x) => 0\n", hdc
);
2530 static WIN_BOOL WINAPI
expDeleteObject(int hdc
)
2532 dbgprintf("DeleteObject(0x%x) => 1\n", hdc
);
2533 /* FIXME - implement code here */
2537 /* btvvc32.drv wants this one */
2538 static void* WINAPI
expGetWindowDC(int hdc
)
2540 dbgprintf("GetWindowDC(%d) => 0x0\n", hdc
);
2545 static int WINAPI
expGetWindowRect(HWND win
, RECT
*r
)
2547 dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win
, r
);
2548 /* (win == 0) => desktop */
2549 r
->right
= PSEUDO_SCREEN_WIDTH
;
2551 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
2556 static int WINAPI
expMonitorFromWindow(HWND win
, int flags
)
2558 dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win
, flags
);
2562 static int WINAPI
expMonitorFromRect(RECT
*r
, int flags
)
2564 dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r
, flags
);
2568 static int WINAPI
expMonitorFromPoint(void *p
, int flags
)
2570 dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p
, flags
);
2574 static int WINAPI
expEnumDisplayMonitors(void *dc
, RECT
*r
,
2575 int WINAPI (*callback_proc
)(), void *callback_param
)
2577 dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2578 dc
, r
, callback_proc
, callback_param
);
2579 return callback_proc(0, dc
, r
, callback_param
);
2583 typedef struct tagMONITORINFO
{
2588 } MONITORINFO
, *LPMONITORINFO
;
2591 #define CCHDEVICENAME 8
2592 typedef struct tagMONITORINFOEX
{
2597 TCHAR szDevice
[CCHDEVICENAME
];
2598 } MONITORINFOEX
, *LPMONITORINFOEX
;
2600 static int WINAPI
expGetMonitorInfoA(void *mon
, LPMONITORINFO lpmi
)
2602 dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon
, lpmi
);
2604 lpmi
->rcMonitor
.right
= lpmi
->rcWork
.right
= PSEUDO_SCREEN_WIDTH
;
2605 lpmi
->rcMonitor
.left
= lpmi
->rcWork
.left
= 0;
2606 lpmi
->rcMonitor
.bottom
= lpmi
->rcWork
.bottom
= PSEUDO_SCREEN_HEIGHT
;
2607 lpmi
->rcMonitor
.top
= lpmi
->rcWork
.top
= 0;
2609 lpmi
->dwFlags
= 1; /* primary monitor */
2611 if (lpmi
->cbSize
== sizeof(MONITORINFOEX
))
2613 LPMONITORINFOEX lpmiex
= (LPMONITORINFOEX
)lpmi
;
2614 dbgprintf("MONITORINFOEX!\n");
2615 strncpy(lpmiex
->szDevice
, "Monitor1", CCHDEVICENAME
);
2621 static int WINAPI
expEnumDisplayDevicesA(const char *device
, int devnum
,
2622 void *dispdev
, int flags
)
2624 dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2625 device
, device
, devnum
, dispdev
, flags
);
2629 static int WINAPI
expIsWindowVisible(HWND win
)
2631 dbgprintf("IsWindowVisible(0x%x) => 1\n", win
);
2635 static HWND WINAPI
expGetActiveWindow(void)
2637 dbgprintf("GetActiveWindow() => 0\n");
2641 static int WINAPI
expGetClassNameA(HWND win
, LPTSTR classname
, int maxcount
)
2643 strncat(classname
, "QuickTime", maxcount
);
2644 dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2645 win
, classname
, maxcount
, strlen(classname
));
2646 return strlen(classname
);
2649 #define LPWNDCLASS void *
2650 static int WINAPI
expGetClassInfoA(HINSTANCE inst
, LPCSTR classname
, LPWNDCLASS wndclass
)
2652 dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst
,
2653 classname
, classname
, wndclass
);
2657 static int WINAPI
expGetWindowLongA(HWND win
, int index
)
2659 dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win
, index
);
2663 static int WINAPI
expGetObjectA(HGDIOBJ hobj
, int objsize
, LPVOID obj
)
2665 dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj
, objsize
, obj
, objsize
);
2669 static int WINAPI
expCreateRectRgn(int x
, int y
, int width
, int height
)
2671 dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x
, y
, width
, height
);
2675 static int WINAPI
expEnumWindows(int (*callback_func
)(), void *callback_param
)
2678 dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func
, callback_param
);
2679 i
= callback_func(0, callback_param
);
2680 i2
= callback_func(1, callback_param
);
2684 static int WINAPI
expGetWindowThreadProcessId(HWND win
, int *pid_data
)
2686 int tid
= pthread_self();
2687 dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2688 win
, pid_data
, tid
);
2690 *(int*)pid_data
= tid
;
2694 //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2695 // INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2697 static HWND WINAPI
expCreateWindowExA(int exstyle
, const char *classname
,
2698 const char *winname
, int style
, int x
, int y
, int w
, int h
,
2699 HWND parent
, HMENU menu
, HINSTANCE inst
, LPVOID param
)
2701 printf("CreateWindowEx() called\n");
2702 dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2703 exstyle
, classname
, classname
, winname
, winname
, style
, x
, y
, w
, h
,
2704 parent
, menu
, inst
, param
);
2705 printf("CreateWindowEx() called okey\n");
2709 static int WINAPI
expwaveOutGetNumDevs(void)
2711 dbgprintf("waveOutGetNumDevs() => 0\n");
2717 * Returns the number of milliseconds, modulo 2^32, since the start
2718 * of the wineserver.
2720 static int WINAPI
expGetTickCount(void)
2722 static int tcstart
= 0;
2725 gettimeofday( &t
, NULL
);
2726 tc
= ((t
.tv_sec
* 1000) + (t
.tv_usec
/ 1000)) - tcstart
;
2732 dbgprintf("GetTickCount() => %d\n", tc
);
2736 static int WINAPI
expCreateFontA(void)
2738 dbgprintf("CreateFontA() => 0x0\n");
2742 /* tried to get pvmjpg work in a different way - no success */
2743 static int WINAPI
expDrawTextA(int hDC
, char* lpString
, int nCount
,
2744 LPRECT lpRect
, unsigned int uFormat
)
2746 dbgprintf("expDrawTextA(%p,...) => 8\n", hDC
);
2750 static int WINAPI
expGetPrivateProfileIntA(const char* appname
,
2751 const char* keyname
,
2753 const char* filename
)
2761 if(!(appname
&& keyname
&& filename
) )
2763 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, default_value
);
2764 return default_value
;
2766 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2767 strcpy(fullname
, "Software\\IniFileMapping\\");
2768 strcat(fullname
, appname
);
2769 strcat(fullname
, "\\");
2770 strcat(fullname
, keyname
);
2771 strcat(fullname
, "\\");
2772 strcat(fullname
, filename
);
2773 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)buffer
, &size
);
2774 if((size
>=0)&&(size
<256))
2776 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2779 result
=default_value
;
2781 result
=atoi(buffer
);
2782 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, result
);
2785 static int WINAPI
expGetProfileIntA(const char* appname
,
2786 const char* keyname
,
2789 dbgprintf("GetProfileIntA -> ");
2790 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, "default");
2793 static int WINAPI
expGetPrivateProfileStringA(const char* appname
,
2794 const char* keyname
,
2795 const char* def_val
,
2796 char* dest
, unsigned int len
,
2797 const char* filename
)
2802 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname
, keyname
, def_val
, dest
, len
, filename
);
2803 if(!(appname
&& keyname
&& filename
) ) return 0;
2804 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2805 strcpy(fullname
, "Software\\IniFileMapping\\");
2806 strcat(fullname
, appname
);
2807 strcat(fullname
, "\\");
2808 strcat(fullname
, keyname
);
2809 strcat(fullname
, "\\");
2810 strcat(fullname
, filename
);
2812 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)dest
, &size
);
2816 strncpy(dest
, def_val
, size
);
2817 if (strlen(def_val
)< size
) size
= strlen(def_val
);
2819 dbgprintf(" => %d ( '%s' )\n", size
, dest
);
2822 static int WINAPI
expWritePrivateProfileStringA(const char* appname
,
2823 const char* keyname
,
2825 const char* filename
)
2829 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname
, keyname
, string
, filename
);
2830 if(!(appname
&& keyname
&& filename
) )
2832 dbgprintf(" => -1\n");
2835 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2836 strcpy(fullname
, "Software\\IniFileMapping\\");
2837 strcat(fullname
, appname
);
2838 strcat(fullname
, "\\");
2839 strcat(fullname
, keyname
);
2840 strcat(fullname
, "\\");
2841 strcat(fullname
, filename
);
2842 RegSetValueExA(HKEY_LOCAL_MACHINE
, fullname
, 0, REG_SZ
, (int*)string
, strlen(string
));
2843 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
2844 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
2846 dbgprintf(" => 0\n");
2850 unsigned int _GetPrivateProfileIntA(const char* appname
, const char* keyname
, INT default_value
, const char* filename
)
2852 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, filename
);
2854 int _GetPrivateProfileStringA(const char* appname
, const char* keyname
,
2855 const char* def_val
, char* dest
, unsigned int len
, const char* filename
)
2857 return expGetPrivateProfileStringA(appname
, keyname
, def_val
, dest
, len
, filename
);
2859 int _WritePrivateProfileStringA(const char* appname
, const char* keyname
,
2860 const char* string
, const char* filename
)
2862 return expWritePrivateProfileStringA(appname
, keyname
, string
, filename
);
2867 static int WINAPI
expDefDriverProc(int _private
, int id
, int msg
, int arg1
, int arg2
)
2869 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", _private
, id
, msg
, arg1
, arg2
);
2873 static int WINAPI
expSizeofResource(int v1
, int v2
)
2875 int result
=SizeofResource(v1
, v2
);
2876 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1
, v2
, result
);
2880 static int WINAPI
expGetLastError()
2882 int result
=GetLastError();
2883 dbgprintf("GetLastError() => 0x%x\n", result
);
2887 static void WINAPI
expSetLastError(int error
)
2889 dbgprintf("SetLastError(0x%x)\n", error
);
2890 SetLastError(error
);
2893 static int WINAPI
expStringFromGUID2(GUID
* guid
, char* str
, int cbMax
)
2895 int result
=snprintf(str
, cbMax
, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
2896 guid
->f1
, guid
->f2
, guid
->f3
,
2897 (unsigned char)guid
->f4
[0], (unsigned char)guid
->f4
[1],
2898 (unsigned char)guid
->f4
[2], (unsigned char)guid
->f4
[3],
2899 (unsigned char)guid
->f4
[4], (unsigned char)guid
->f4
[5],
2900 (unsigned char)guid
->f4
[6], (unsigned char)guid
->f4
[7]);
2901 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid
, str
, str
, cbMax
, result
);
2906 static int WINAPI
expGetFileVersionInfoSizeA(const char* name
, int* lpHandle
)
2908 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name
, name
, lpHandle
);
2912 static int WINAPI
expIsBadStringPtrW(const short* string
, int nchars
)
2915 if(string
==0)result
=1; else result
=0;
2916 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string
, nchars
, result
);
2917 if(string
)wch_print(string
);
2920 static int WINAPI
expIsBadStringPtrA(const char* string
, int nchars
)
2922 return expIsBadStringPtrW((const short*)string
, nchars
);
2924 static long WINAPI
expInterlockedExchangeAdd( long* dest
, long incr
)
2927 __asm__ __volatile__
2929 "lock; xaddl %0,(%1)"
2931 : "r" (dest
), "0" (incr
)
2937 static long WINAPI
expInterlockedCompareExchange( unsigned long* dest
, unsigned long exchange
, unsigned long comperand
)
2939 unsigned long retval
= *dest
;
2940 if(*dest
== comperand
)
2945 static long WINAPI
expInterlockedIncrement( long* dest
)
2947 long result
=expInterlockedExchangeAdd( dest
, 1 ) + 1;
2948 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
2951 static long WINAPI
expInterlockedDecrement( long* dest
)
2953 long result
=expInterlockedExchangeAdd( dest
, -1 ) - 1;
2954 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
2958 static void WINAPI
expOutputDebugStringA( const char* string
)
2960 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string
);
2961 fprintf(stderr
, "DEBUG: %s\n", string
);
2964 static int WINAPI
expGetDC(int hwnd
)
2966 dbgprintf("GetDC(0x%x) => 1\n", hwnd
);
2970 static int WINAPI
expReleaseDC(int hwnd
, int hdc
)
2972 dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd
, hdc
);
2976 static int WINAPI
expGetDesktopWindow()
2978 dbgprintf("GetDesktopWindow() => 0\n");
2982 static int cursor
[100];
2984 static int WINAPI
expLoadCursorA(int handle
,LPCSTR name
)
2986 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle
, name
, (int)&cursor
[0]);
2987 return (int)&cursor
[0];
2989 static int WINAPI
expSetCursor(void *cursor
)
2991 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor
, cursor
);
2994 static int WINAPI
expGetCursorPos(void *cursor
)
2996 dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor
, cursor
);
3000 static int show_cursor
= 0;
3001 static int WINAPI
expShowCursor(int show
)
3003 dbgprintf("ShowCursor(%d) => %d\n", show
, show
);
3011 static int WINAPI
expRegisterWindowMessageA(char *message
)
3013 dbgprintf("RegisterWindowMessageA(%s)\n", message
);
3016 static int WINAPI
expGetProcessVersion(int pid
)
3018 dbgprintf("GetProcessVersion(%d)\n", pid
);
3021 static int WINAPI
expGetCurrentThread(void)
3024 dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
3027 static int WINAPI
expGetOEMCP(void)
3029 dbgprintf("GetOEMCP()\n");
3032 static int WINAPI
expGetCPInfo(int cp
,void *info
)
3034 dbgprintf("GetCPInfo()\n");
3038 #define SM_CXSCREEN 0
3039 #define SM_CYSCREEN 1
3040 #define SM_XVIRTUALSCREEN 76
3041 #define SM_YVIRTUALSCREEN 77
3042 #define SM_CXVIRTUALSCREEN 78
3043 #define SM_CYVIRTUALSCREEN 79
3044 #define SM_CMONITORS 80
3046 static int WINAPI
expGetSystemMetrics(int index
)
3048 dbgprintf("GetSystemMetrics(%d)\n", index
);
3052 case SM_XVIRTUALSCREEN
:
3053 case SM_YVIRTUALSCREEN
:
3056 case SM_CXVIRTUALSCREEN
:
3057 return PSEUDO_SCREEN_WIDTH
;
3059 case SM_CYVIRTUALSCREEN
:
3060 return PSEUDO_SCREEN_HEIGHT
;
3067 static int WINAPI
expGetSysColor(int index
)
3069 dbgprintf("GetSysColor(%d) => 1\n", index
);
3072 static int WINAPI
expGetSysColorBrush(int index
)
3074 dbgprintf("GetSysColorBrush(%d)\n", index
);
3080 static int WINAPI
expGetSystemPaletteEntries(int hdc
, int iStartIndex
, int nEntries
, void* lppe
)
3082 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3083 hdc
, iStartIndex
, nEntries
, lppe
);
3088 typedef struct _TIME_ZONE_INFORMATION {
3090 char StandardName[32];
3091 SYSTEMTIME StandardDate;
3093 char DaylightName[32];
3094 SYSTEMTIME DaylightDate;
3096 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3099 static int WINAPI
expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation
)
3101 const short name
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3102 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3103 const short pname
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3104 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3105 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3106 memset(lpTimeZoneInformation
, 0, sizeof(TIME_ZONE_INFORMATION
));
3107 lpTimeZoneInformation
->Bias
=360;//GMT-6
3108 memcpy(lpTimeZoneInformation
->StandardName
, name
, sizeof(name
));
3109 lpTimeZoneInformation
->StandardDate
.wMonth
=10;
3110 lpTimeZoneInformation
->StandardDate
.wDay
=5;
3111 lpTimeZoneInformation
->StandardDate
.wHour
=2;
3112 lpTimeZoneInformation
->StandardBias
=0;
3113 memcpy(lpTimeZoneInformation
->DaylightName
, pname
, sizeof(pname
));
3114 lpTimeZoneInformation
->DaylightDate
.wMonth
=4;
3115 lpTimeZoneInformation
->DaylightDate
.wDay
=1;
3116 lpTimeZoneInformation
->DaylightDate
.wHour
=2;
3117 lpTimeZoneInformation
->DaylightBias
=-60;
3118 return TIME_ZONE_ID_STANDARD
;
3121 static void WINAPI
expGetLocalTime(SYSTEMTIME
* systime
)
3124 struct tm
*local_tm
;
3127 dbgprintf("GetLocalTime(0x%x)\n");
3128 gettimeofday(&tv
, NULL
);
3129 local_time
=tv
.tv_sec
;
3130 local_tm
=localtime(&local_time
);
3132 systime
->wYear
= local_tm
->tm_year
+ 1900;
3133 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3134 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3135 systime
->wDay
= local_tm
->tm_mday
;
3136 systime
->wHour
= local_tm
->tm_hour
;
3137 systime
->wMinute
= local_tm
->tm_min
;
3138 systime
->wSecond
= local_tm
->tm_sec
;
3139 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3140 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3141 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3142 " Milliseconds: %d\n",
3143 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3144 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3147 static int WINAPI
expGetSystemTime(SYSTEMTIME
* systime
)
3150 struct tm
*local_tm
;
3153 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3154 gettimeofday(&tv
, NULL
);
3155 local_time
=tv
.tv_sec
;
3156 local_tm
=gmtime(&local_time
);
3158 systime
->wYear
= local_tm
->tm_year
+ 1900;
3159 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3160 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3161 systime
->wDay
= local_tm
->tm_mday
;
3162 systime
->wHour
= local_tm
->tm_hour
;
3163 systime
->wMinute
= local_tm
->tm_min
;
3164 systime
->wSecond
= local_tm
->tm_sec
;
3165 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3166 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3167 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3168 " Milliseconds: %d\n",
3169 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3170 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3174 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3175 static void WINAPI
expGetSystemTimeAsFileTime(FILETIME
* systime
)
3177 struct tm
*local_tm
;
3179 unsigned long long secs
;
3181 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3182 gettimeofday(&tv
, NULL
);
3183 secs
= (tv
.tv_sec
+ SECS_1601_TO_1970
) * 10000000;
3184 secs
+= tv
.tv_usec
* 10;
3185 systime
->dwLowDateTime
= secs
& 0xffffffff;
3186 systime
->dwHighDateTime
= (secs
>> 32);
3189 static int WINAPI
expGetEnvironmentVariableA(const char* name
, char* field
, int size
)
3192 // printf("%s %x %x\n", name, field, size);
3193 if(field
)field
[0]=0;
3196 if (p) strncpy(field,p,size);
3198 if (strcmp(name
,"__MSVCRT_HEAP_SELECT")==0)
3199 strcpy(field
,"__GLOBAL_HEAP_SELECTED,1");
3200 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name
, name
, field
, size
, strlen(field
));
3201 return strlen(field
);
3204 static int WINAPI
expSetEnvironmentVariableA(const char *name
, const char *value
)
3206 dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name
, value
);
3210 static void* WINAPI
expCoTaskMemAlloc(ULONG cb
)
3212 return my_mreq(cb
, 0);
3214 static void WINAPI
expCoTaskMemFree(void* cb
)
3222 void* CoTaskMemAlloc(unsigned long cb
)
3224 return expCoTaskMemAlloc(cb
);
3226 void CoTaskMemFree(void* cb
)
3228 expCoTaskMemFree(cb
);
3231 struct COM_OBJECT_INFO
3234 long (*GetClassObject
) (GUID
* clsid
, const GUID
* iid
, void** ppv
);
3237 static struct COM_OBJECT_INFO
* com_object_table
=0;
3238 static int com_object_size
=0;
3239 int RegisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3243 com_object_table
=realloc(com_object_table
, sizeof(struct COM_OBJECT_INFO
)*(++com_object_size
));
3244 com_object_table
[com_object_size
-1].clsid
=*clsid
;
3245 com_object_table
[com_object_size
-1].GetClassObject
=gcs
;
3249 int UnregisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3256 if (com_object_table
== 0)
3257 printf("Warning: UnregisterComClass() called without any registered class\n");
3258 while (i
< com_object_size
)
3262 memcpy(&com_object_table
[i
- 1].clsid
,
3263 &com_object_table
[i
].clsid
, sizeof(GUID
));
3264 com_object_table
[i
- 1].GetClassObject
=
3265 com_object_table
[i
].GetClassObject
;
3267 else if (memcmp(&com_object_table
[i
].clsid
, clsid
, sizeof(GUID
)) == 0
3268 && com_object_table
[i
].GetClassObject
== gcs
)
3276 if (--com_object_size
== 0)
3278 free(com_object_table
);
3279 com_object_table
= 0;
3286 const GUID IID_IUnknown
=
3288 0x00000000, 0x0000, 0x0000,
3289 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3291 const GUID IID_IClassFactory
=
3293 0x00000001, 0x0000, 0x0000,
3294 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3297 static long WINAPI
expCoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3298 long dwClsContext
, const GUID
* riid
, void** ppv
)
3301 struct COM_OBJECT_INFO
* ci
=0;
3302 for(i
=0; i
<com_object_size
; i
++)
3303 if(!memcmp(rclsid
, &com_object_table
[i
].clsid
, sizeof(GUID
)))
3304 ci
=&com_object_table
[i
];
3305 if(!ci
)return REGDB_E_CLASSNOTREG
;
3306 // in 'real' world we should mess with IClassFactory here
3307 i
=ci
->GetClassObject(rclsid
, riid
, ppv
);
3311 long CoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3312 long dwClsContext
, const GUID
* riid
, void** ppv
)
3314 return expCoCreateInstance(rclsid
, pUnkOuter
, dwClsContext
, riid
, ppv
);
3317 static int WINAPI
expIsRectEmpty(CONST RECT
*lprc
)
3324 w
= lprc
->right
- lprc
->left
;
3325 h
= lprc
->bottom
- lprc
->top
;
3326 if (w
<= 0 || h
<= 0)
3332 dbgprintf("IsRectEmpty(%p) => %s\n", lprc
, (r
) ? "TRUE" : "FALSE");
3333 //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3334 // return 0; // wmv9?
3338 static int _adjust_fdiv
=0; //what's this? - used to adjust division
3339 static int _winver
= 0x510; // windows version
3344 static unsigned int WINAPI
expGetTempPathA(unsigned int len
, char* path
)
3346 dbgprintf("GetTempPathA(%d, 0x%x)", len
, path
);
3349 dbgprintf(" => 0\n");
3352 strcpy(path
, "/tmp");
3353 dbgprintf(" => 5 ( '/tmp' )\n");
3360 DWORD dwFileAttributes;
3361 FILETIME ftCreationTime;
3362 FILETIME ftLastAccessTime;
3363 FILETIME ftLastWriteTime;
3364 DWORD nFileSizeHigh;
3368 CHAR cFileName[260];
3369 CHAR cAlternateFileName[14];
3370 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3373 static DIR* qtx_dir
=NULL
;
3375 static WIN_BOOL WINAPI
expFindNextFileA(HANDLE h
,LPWIN32_FIND_DATAA lpfd
)
3378 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h
, lpfd
);
3379 if(h
==FILE_HANDLE_quicktimeqtx
){
3381 if(!qtx_dir
) return 0;
3382 while((d
=readdir(qtx_dir
))){
3383 char* x
=strrchr(d
->d_name
,'.');
3385 if(strcmp(x
,".qtx")) continue;
3386 strcpy(lpfd
->cFileName
,d
->d_name
);
3387 // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3388 strcpy(lpfd
->cAlternateFileName
,"foobar.qtx");
3389 printf("### FindNext: %s\n",lpfd
->cFileName
);
3392 closedir(qtx_dir
); qtx_dir
=NULL
;
3399 static HANDLE WINAPI
expFindFirstFileA(LPCSTR s
, LPWIN32_FIND_DATAA lpfd
)
3401 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s
, s
, lpfd
);
3402 // printf("\n### FindFirstFileA('%s')...\n",s);
3404 if(strstr(s
, "quicktime\\*.QTX")){
3405 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s
, s
, lpfd
);
3406 printf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",def_path
);
3407 qtx_dir
=opendir(def_path
);
3408 if(!qtx_dir
) return (HANDLE
)-1;
3409 memset(lpfd
,0,sizeof(*lpfd
));
3410 if(expFindNextFileA(FILE_HANDLE_quicktimeqtx
,lpfd
))
3411 return FILE_HANDLE_quicktimeqtx
;
3412 printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",def_path
);
3416 if(strstr(s
, "QuickTime.qts")){
3417 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s
, s
, lpfd
);
3418 // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3419 // return (HANDLE)-1;
3420 strcpy(lpfd
->cFileName
, "QuickTime.qts");
3421 strcpy(lpfd
->cAlternateFileName
, "QuickT~1.qts");
3422 return FILE_HANDLE_quicktimeqts
;
3426 if(strstr(s
, "*.vwp")){
3427 // hack for VoxWare codec plugins:
3428 strcpy(lpfd
->cFileName
, "msms001.vwp");
3429 strcpy(lpfd
->cAlternateFileName
, "msms001.vwp");
3432 // return 'file not found'
3436 static WIN_BOOL WINAPI
expFindClose(HANDLE h
)
3438 dbgprintf("FindClose(0x%x) => 0\n", h
);
3440 // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3441 // closedir(qtx_dir);
3447 static UINT WINAPI
expSetErrorMode(UINT i
)
3449 dbgprintf("SetErrorMode(%d) => 0\n", i
);
3452 static UINT WINAPI
expGetWindowsDirectoryA(LPSTR s
,UINT c
)
3454 char windir
[]="c:\\windows";
3456 strncpy(s
, windir
, c
);
3457 result
=1+((c
<strlen(windir
))?c
:strlen(windir
));
3458 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3462 static UINT WINAPI
expGetCurrentDirectoryA(UINT c
, LPSTR s
)
3464 char curdir
[]="c:\\";
3466 strncpy(s
, curdir
, c
);
3467 result
=1+((c
<strlen(curdir
))?c
:strlen(curdir
));
3468 dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3472 static int WINAPI
expSetCurrentDirectoryA(const char *pathname
)
3474 dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname
, pathname
);
3476 if (strrchr(pathname
, '\\'))
3477 chdir(strcat(strrchr(pathname
, '\\')+1, '/'));
3484 static int WINAPI
expCreateDirectoryA(const char *pathname
, void *sa
)
3486 dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3487 pathname
, pathname
, sa
);
3489 p
= strrchr(pathname
, '\\')+1;
3490 strcpy(&buf
[0], p
); /* should be strncpy */
3497 if (strrchr(pathname
, '\\'))
3498 mkdir(strcat(strrchr(pathname
, '\\')+1, '/'), 666);
3500 mkdir(pathname
, 666);
3507 static WIN_BOOL WINAPI
expDeleteFileA(LPCSTR s
)
3509 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s
, s
);
3512 static WIN_BOOL WINAPI
expFileTimeToLocalFileTime(const FILETIME
* cpf
, LPFILETIME pf
)
3514 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf
, pf
);
3518 static UINT WINAPI
expGetTempFileNameA(LPCSTR cs1
,LPCSTR cs2
,UINT i
,LPSTR ps
)
3520 char mask
[16]="/tmp/AP_XXXXXX";
3522 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1
, cs1
, cs2
, cs2
, i
, ps
);
3525 dbgprintf(" => -1\n");
3528 result
=mkstemp(mask
);
3529 sprintf(ps
, "AP%d", result
);
3530 dbgprintf(" => %d\n", strlen(ps
));
3534 // This func might need proper implementation if we want AngelPotion codec.
3535 // They try to open APmpeg4v1.apl with it.
3536 // DLL will close opened file with CloseHandle().
3538 static HANDLE WINAPI
expCreateFileA(LPCSTR cs1
,DWORD i1
,DWORD i2
,
3539 LPSECURITY_ATTRIBUTES p1
, DWORD i3
,DWORD i4
,HANDLE i5
)
3541 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1
, cs1
, i1
,
3542 i2
, p1
, i3
, i4
, i5
);
3543 if((!cs1
) || (strlen(cs1
)<2))return -1;
3546 if(strstr(cs1
, "QuickTime.qts"))
3549 char* tmp
=malloc(strlen(def_path
)+50);
3550 strcpy(tmp
, def_path
);
3552 strcat(tmp
, "QuickTime.qts");
3553 result
=open(tmp
, O_RDONLY
);
3557 if(strstr(cs1
, ".qtx"))
3560 char* tmp
=malloc(strlen(def_path
)+250);
3561 char* x
=strrchr(cs1
,'\\');
3562 sprintf(tmp
,"%s/%s",def_path
,x
?(x
+1):cs1
);
3563 // printf("### Open: %s -> %s\n",cs1,tmp);
3564 result
=open(tmp
, O_RDONLY
);
3570 if(strncmp(cs1
, "AP", 2) == 0)
3573 char* tmp
=malloc(strlen(def_path
)+50);
3574 strcpy(tmp
, def_path
);
3576 strcat(tmp
, "APmpg4v1.apl");
3577 result
=open(tmp
, O_RDONLY
);
3581 if (strstr(cs1
, "vp3"))
3585 char* tmp
=malloc(20 + strlen(cs1
));
3586 strcpy(tmp
, "/tmp/");
3591 if (tmp
[r
] == ':' || tmp
[r
] == '\\')
3595 if (GENERIC_READ
& i1
)
3597 else if (GENERIC_WRITE
& i1
)
3600 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp
, r
, flg
);
3607 // Needed by wnvplay1.dll
3608 if (strstr(cs1
, "WINNOV.bmp"))
3611 r
=open("/dev/null", 0);
3616 /* we need this for some virtualdub filters */
3620 if (GENERIC_READ
& i1
)
3622 else if (GENERIC_WRITE
& i1
)
3625 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1
, r
, flg
);
3634 static UINT WINAPI
expGetSystemDirectoryA(
3635 char* lpBuffer
, // address of buffer for system directory
3636 UINT uSize
// size of directory buffer
3638 dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer
,uSize
);
3639 if(!lpBuffer
) strcpy(lpBuffer
,".");
3643 static char sysdir[]=".";
3644 static LPCSTR WINAPI expGetSystemDirectoryA()
3646 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3650 static DWORD WINAPI expGetFullPathNameA
3653 DWORD nBufferLength
,
3657 if(!lpFileName
) return 0;
3658 dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName
,nBufferLength
,
3659 lpBuffer
, lpFilePart
);
3662 strcpy(lpFilePart
, "Quick123.qts");
3664 strcpy(lpFilePart
, lpFileName
);
3667 if (strrchr(lpFileName
, '\\'))
3668 lpFilePart
= strrchr(lpFileName
, '\\');
3670 lpFilePart
= (LPTSTR
)lpFileName
;
3672 strcpy(lpBuffer
, lpFileName
);
3673 // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3674 return strlen(lpBuffer
);
3677 static DWORD WINAPI expGetShortPathNameA
3683 if(!longpath
) return 0;
3684 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath
,shortpath
,shortlen
);
3685 strcpy(shortpath
,longpath
);
3686 return strlen(shortpath
);
3689 static WIN_BOOL WINAPI
expReadFile(HANDLE h
,LPVOID pv
,DWORD size
,LPDWORD rd
,LPOVERLAPPED unused
)
3692 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, rd
);
3693 result
=read(h
, pv
, size
);
3695 if(!result
)return 0;
3699 static WIN_BOOL WINAPI
expWriteFile(HANDLE h
,LPCVOID pv
,DWORD size
,LPDWORD wr
,LPOVERLAPPED unused
)
3702 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, wr
);
3704 result
=write(h
, pv
, size
);
3706 if(!result
)return 0;
3709 static DWORD WINAPI
expSetFilePointer(HANDLE h
, LONG val
, LPLONG ext
, DWORD whence
)
3712 dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h
, val
, ext
, *ext
, whence
);
3713 //why would DLL want temporary file with >2Gb size?
3726 if (val
== 0 && ext
!= 0)
3729 return lseek(h
, val
, wh
);
3732 static HDRVR WINAPI
expOpenDriverA(LPCSTR szDriverName
, LPCSTR szSectionName
,
3735 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3738 static HDRVR WINAPI
expOpenDriver(LPCSTR szDriverName
, LPCSTR szSectionName
,
3741 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3746 static WIN_BOOL WINAPI
expGetProcessAffinityMask(HANDLE hProcess
,
3747 LPDWORD lpProcessAffinityMask
,
3748 LPDWORD lpSystemAffinityMask
)
3750 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3751 hProcess
, lpProcessAffinityMask
, lpSystemAffinityMask
);
3752 if(lpProcessAffinityMask
)*lpProcessAffinityMask
=1;
3753 if(lpSystemAffinityMask
)*lpSystemAffinityMask
=1;
3757 // Fake implementation: does nothing, but does it right :)
3758 static WIN_BOOL WINAPI
expSetProcessAffinityMask(HANDLE hProcess
,
3759 LPDWORD dwProcessAffinityMask
)
3761 dbgprintf("SetProcessAffinityMask(0x%x, 0x%x) => 1\n",
3762 hProcess
, dwProcessAffinityMask
);
3767 static int WINAPI
expMulDiv(int nNumber
, int nNumerator
, int nDenominator
)
3769 static const long long max_int
=0x7FFFFFFFLL
;
3770 static const long long min_int
=-0x80000000LL
;
3771 long long tmp
=(long long)nNumber
*(long long)nNumerator
;
3772 dbgprintf("expMulDiv %d * %d / %d\n", nNumber
, nNumerator
, nDenominator
);
3773 if(!nDenominator
)return 1;
3775 if(tmp
<min_int
) return 1;
3776 if(tmp
>max_int
) return 1;
3780 static LONG WINAPI
explstrcmpiA(const char* str1
, const char* str2
)
3782 LONG result
=strcasecmp(str1
, str2
);
3783 dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
3787 static LONG WINAPI
explstrlenA(const char* str1
)
3789 LONG result
=strlen(str1
);
3790 dbgprintf("strlen(0x%x='%.50s') => %d\n", str1
, str1
, result
);
3794 static LONG WINAPI
explstrcpyA(char* str1
, const char* str2
)
3796 int result
= (int) strcpy(str1
, str2
);
3797 dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1
, str2
, str2
, result
);
3800 static LONG WINAPI
explstrcpynA(char* str1
, const char* str2
,int len
)
3803 if (strlen(str2
)>len
)
3804 result
= (int) strncpy(str1
, str2
,len
);
3806 result
= (int) strcpy(str1
,str2
);
3807 dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1
, str2
, str2
,len
, strlen(str2
),result
);
3810 static LONG WINAPI
explstrcatA(char* str1
, const char* str2
)
3812 int result
= (int) strcat(str1
, str2
);
3813 dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1
, str2
, str2
, result
);
3818 static LONG WINAPI
expInterlockedExchange(long *dest
, long l
)
3820 long retval
= *dest
;
3825 static void WINAPI
expInitCommonControls(void)
3827 dbgprintf("InitCommonControls called!\n");
3832 /* needed by QuickTime.qts */
3833 static HWND WINAPI
expCreateUpDownControl (DWORD style
, INT x
, INT y
, INT cx
, INT cy
,
3834 HWND parent
, INT id
, HINSTANCE inst
,
3835 HWND buddy
, INT maxVal
, INT minVal
, INT curVal
)
3837 dbgprintf("CreateUpDownControl(...)\n");
3842 /* alex: implement this call! needed for 3ivx */
3843 static HRESULT WINAPI
expCoCreateFreeThreadedMarshaler(void *pUnkOuter
, void **ppUnkInner
)
3845 dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
3846 pUnkOuter
, ppUnkInner
);
3848 return ERROR_CALL_NOT_IMPLEMENTED
;
3852 static int WINAPI
expDuplicateHandle(HANDLE hSourceProcessHandle
, // handle to source process
3853 HANDLE hSourceHandle
, // handle to duplicate
3854 HANDLE hTargetProcessHandle
, // handle to target process
3855 HANDLE
* lpTargetHandle
, // duplicate handle
3856 DWORD dwDesiredAccess
, // requested access
3857 int bInheritHandle
, // handle inheritance option
3858 DWORD dwOptions
// optional actions
3861 dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
3862 hSourceProcessHandle
, hSourceHandle
, hTargetProcessHandle
,
3863 lpTargetHandle
, dwDesiredAccess
, bInheritHandle
, dwOptions
);
3864 *lpTargetHandle
= hSourceHandle
;
3868 // required by PIM1 codec (used by win98 PCTV Studio capture sw)
3869 static HRESULT WINAPI
expCoInitialize(
3870 LPVOID lpReserved
/* [in] pointer to win32 malloc interface
3871 (obsolete, should be NULL) */
3875 * Just delegate to the newer method.
3877 return 0; //CoInitializeEx(lpReserved, COINIT_APARTMENTTHREADED);
3880 static DWORD WINAPI expSetThreadAffinityMask
3883 DWORD dwThreadAffinityMask
3889 * no WINAPI functions - CDECL
3891 static void* expmalloc(int size
)
3894 // return malloc(size);
3895 void* result
=my_mreq(size
,0);
3896 dbgprintf("malloc(0x%x) => 0x%x\n", size
,result
);
3898 printf("WARNING: malloc() failed\n");
3901 static void expfree(void* mem
)
3903 // return free(mem);
3904 dbgprintf("free(%p)\n", mem
);
3907 /* needed by atrac3.acm */
3908 static void *expcalloc(int num
, int size
)
3910 void* result
=my_mreq(num
*size
,1);
3911 dbgprintf("calloc(%d,%d) => %p\n", num
,size
,result
);
3913 printf("WARNING: calloc() failed\n");
3916 static void* expnew(int size
)
3918 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
3919 // printf("%08x %08x %08x %08x\n",
3920 // size, *(1+(int*)&size),
3921 // *(2+(int*)&size),*(3+(int*)&size));
3925 result
=my_mreq(size
,0);
3926 dbgprintf("new(%d) => %p\n", size
, result
);
3928 printf("WARNING: new() failed\n");
3932 static int expdelete(void* memory
)
3934 dbgprintf("delete(%p)\n", memory
);
3940 * local definition - we need only the last two members at this point
3941 * otherwice we would have to introduce here GUIDs and some more types..
3943 typedef struct __attribute__((__packed__
))
3946 unsigned long cbFormat
; //0x40
3947 char* pbFormat
; //0x44
3949 static HRESULT WINAPI
expMoCopyMediaType(MY_MEDIA_TYPE
* dest
, const MY_MEDIA_TYPE
* src
)
3953 memcpy(dest
, src
, sizeof(MY_MEDIA_TYPE
));
3956 dest
->pbFormat
= (char*) my_mreq(dest
->cbFormat
, 0);
3957 if (!dest
->pbFormat
)
3958 return E_OUTOFMEMORY
;
3959 memcpy(dest
->pbFormat
, src
->pbFormat
, dest
->cbFormat
);
3963 static HRESULT WINAPI
expMoInitMediaType(MY_MEDIA_TYPE
* dest
, DWORD cbFormat
)
3967 memset(dest
, 0, sizeof(MY_MEDIA_TYPE
));
3970 dest
->pbFormat
= (char*) my_mreq(cbFormat
, 0);
3971 if (!dest
->pbFormat
)
3972 return E_OUTOFMEMORY
;
3976 static HRESULT WINAPI
expMoCreateMediaType(MY_MEDIA_TYPE
** dest
, DWORD cbFormat
)
3980 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
3981 return expMoInitMediaType(*dest
, cbFormat
);
3983 static HRESULT WINAPI
expMoDuplicateMediaType(MY_MEDIA_TYPE
** dest
, const void* src
)
3987 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
3988 return expMoCopyMediaType(*dest
, src
);
3990 static HRESULT WINAPI
expMoFreeMediaType(MY_MEDIA_TYPE
* dest
)
3996 my_release(dest
->pbFormat
);
4002 static HRESULT WINAPI
expMoDeleteMediaType(MY_MEDIA_TYPE
* dest
)
4006 expMoFreeMediaType(dest
);
4011 static int exp_snprintf( char *str
, int size
, const char *format
, ... )
4015 va_start(va
, format
);
4016 x
=snprintf(str
,size
,format
,va
);
4017 dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str
,size
,format
,x
);
4023 static int exp_initterm(int v1
, int v2
)
4025 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1
, v2
);
4029 /* merged from wine - 2002.04.21 */
4030 typedef void (*_INITTERMFUNC
)();
4031 static int exp_initterm(_INITTERMFUNC
*start
, _INITTERMFUNC
*end
)
4033 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start
, end
, *start
);
4038 //printf("call _initfunc: from: %p %d\n", *start);
4039 // ok this trick with push/pop is necessary as otherwice
4040 // edi/esi registers are being trashed
4042 __asm__ __volatile__
4059 //printf("done %p %d:%d\n", end);
4067 static void* exp__dllonexit()
4069 // FIXME extract from WINE
4073 static int expwsprintfA(char* string
, const char* format
, ...)
4077 va_start(va
, format
);
4078 result
= vsprintf(string
, format
, va
);
4079 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string
, format
, result
);
4084 static int expsprintf(char* str
, const char* format
, ...)
4088 dbgprintf("sprintf(0x%x, %s)\n", str
, format
);
4089 va_start(args
, format
);
4090 r
= vsprintf(str
, format
, args
);
4094 static int expsscanf(const char* str
, const char* format
, ...)
4098 dbgprintf("sscanf(%s, %s)\n", str
, format
);
4099 va_start(args
, format
);
4100 r
= vsscanf(str
, format
, args
);
4104 static void* expfopen(const char* path
, const char* mode
)
4106 printf("fopen: \"%s\" mode:%s\n", path
, mode
);
4107 //return fopen(path, mode);
4108 return fdopen(0, mode
); // everything on screen
4110 static int expfprintf(void* stream
, const char* format
, ...)
4114 dbgprintf("fprintf(%p, %s, ...)\n", stream
, format
);
4116 va_start(args
, format
);
4117 r
= vfprintf((FILE*) stream
, format
, args
);
4123 static int expprintf(const char* format
, ...)
4127 dbgprintf("printf(%s, ...)\n", format
);
4128 va_start(args
, format
);
4129 r
= vprintf(format
, args
);
4134 static char* expgetenv(const char* varname
)
4136 char* v
= getenv(varname
);
4137 dbgprintf("getenv(%s) => %s\n", varname
, v
);
4141 static void* expwcscpy(WCHAR
* dst
, const WCHAR
* src
)
4144 while ((*p
++ = *src
++))
4149 static char* expstrrchr(char* string
, int value
)
4151 char* result
=strrchr(string
, value
);
4153 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4155 dbgprintf("strrchr(0x%x='%s', %d) => 0", string
, string
, value
);
4159 static char* expstrchr(char* string
, int value
)
4161 char* result
=strchr(string
, value
);
4163 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4165 dbgprintf("strchr(0x%x='%s', %d) => 0", string
, string
, value
);
4168 static int expstrlen(char* str
)
4170 int result
=strlen(str
);
4171 dbgprintf("strlen(0x%x='%s') => %d\n", str
, str
, result
);
4174 static char* expstrcpy(char* str1
, const char* str2
)
4176 char* result
= strcpy(str1
, str2
);
4177 dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1
, str2
, str2
, result
);
4180 static char* expstrncpy(char* str1
, const char* str2
, size_t count
)
4182 char* result
= strncpy(str1
, str2
, count
);
4183 dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1
, str2
, str2
, count
, result
);
4186 static int expstrcmp(const char* str1
, const char* str2
)
4188 int result
=strcmp(str1
, str2
);
4189 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4192 static int expstrncmp(const char* str1
, const char* str2
,int x
)
4194 int result
=strncmp(str1
, str2
,x
);
4195 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4198 static char* expstrcat(char* str1
, const char* str2
)
4200 char* result
= strcat(str1
, str2
);
4201 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1
, str1
, str2
, str2
, result
);
4204 static char* exp_strdup(const char* str1
)
4206 int l
= strlen(str1
);
4207 char* result
= (char*) my_mreq(l
+ 1,0);
4209 strcpy(result
, str1
);
4210 dbgprintf("_strdup(0x%x='%s') => %p\n", str1
, str1
, result
);
4213 static int expisalnum(int c
)
4215 int result
= (int) isalnum(c
);
4216 dbgprintf("isalnum(0x%x='%c' => %d\n", c
, c
, result
);
4219 static int expisspace(int c
)
4221 int result
= (int) isspace(c
);
4222 dbgprintf("isspace(0x%x='%c' => %d\n", c
, c
, result
);
4225 static int expisalpha(int c
)
4227 int result
= (int) isalpha(c
);
4228 dbgprintf("isalpha(0x%x='%c' => %d\n", c
, c
, result
);
4231 static int expisdigit(int c
)
4233 int result
= (int) isdigit(c
);
4234 dbgprintf("isdigit(0x%x='%c' => %d\n", c
, c
, result
);
4237 static void* expmemmove(void* dest
, void* src
, int n
)
4239 void* result
= memmove(dest
, src
, n
);
4240 dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4243 static int expmemcmp(void* dest
, void* src
, int n
)
4245 int result
= memcmp(dest
, src
, n
);
4246 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest
, src
, n
, result
);
4249 static void* expmemcpy(void* dest
, void* src
, int n
)
4251 void *result
= memcpy(dest
, src
, n
);
4252 dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4255 static void* expmemset(void* dest
, int c
, size_t n
)
4257 void *result
= memset(dest
, c
, n
);
4258 dbgprintf("memset(0x%x, %d, %d) => %p\n", dest
, c
, n
, result
);
4261 static time_t exptime(time_t* t
)
4263 time_t result
= time(t
);
4264 dbgprintf("time(0x%x) => %d\n", t
, result
);
4268 static int exprand(void)
4273 static void expsrand(int seed
)
4280 // prefered compilation with -O2 -ffast-math !
4282 static double explog10(double x
)
4284 /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4288 static double expcos(double x
)
4290 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4295 static long exp_ftol_wrong(double x
)
4302 static void explog10(void)
4304 __asm__ __volatile__
4313 static void expcos(void)
4315 __asm__ __volatile__
4324 // this seem to be the only how to make this function working properly
4325 // ok - I've spent tremendous amount of time (many many many hours
4326 // of debuging fixing & testing - it's almost unimaginable - kabi
4328 // _ftol - operated on the float value which is already on the FPU stack
4330 static void exp_ftol(void)
4332 __asm__ __volatile__
4334 "sub $12, %esp \n\t"
4335 "fstcw -2(%ebp) \n\t"
4337 "movw -2(%ebp), %ax \n\t"
4338 "orb $0x0C, %ah \n\t"
4339 "movw %ax, -4(%ebp) \n\t"
4340 "fldcw -4(%ebp) \n\t"
4341 "fistpl -12(%ebp) \n\t"
4342 "fldcw -2(%ebp) \n\t"
4343 "movl -12(%ebp), %eax \n\t"
4344 //Note: gcc 3.03 does not do the following op if it
4345 // knows that ebp=esp
4346 "movl %ebp, %esp \n\t"
4350 #define FPU_DOUBLES(var1,var2) double var1,var2; \
4351 __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var2) : ); \
4352 __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var1) : )
4354 static double exp_CIpow(void)
4358 dbgprintf("_CIpow(%lf, %lf)\n", x
, y
);
4362 static double exppow(double x
, double y
)
4364 /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4368 static double expldexp(double x
, int expo
)
4370 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4371 return ldexp(x
, expo
);
4374 static double expfrexp(double x
, int* expo
)
4376 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4377 return frexp(x
, expo
);
4382 static int exp_stricmp(const char* s1
, const char* s2
)
4384 return strcasecmp(s1
, s2
);
4387 /* from declaration taken from Wine sources - this fountion seems to be
4388 * undocumented in any M$ doc */
4389 static int exp_setjmp3(void* jmpbuf
, int x
)
4391 //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4393 __asm__ __volatile__
4395 //"mov 4(%%esp), %%edx \n\t"
4396 "mov (%%esp), %%eax \n\t"
4397 "mov %%eax, (%%edx) \n\t" // store ebp
4399 //"mov %%ebp, (%%edx) \n\t"
4400 "mov %%ebx, 4(%%edx) \n\t"
4401 "mov %%edi, 8(%%edx) \n\t"
4402 "mov %%esi, 12(%%edx) \n\t"
4403 "mov %%esp, 16(%%edx) \n\t"
4405 "mov 4(%%esp), %%eax \n\t"
4406 "mov %%eax, 20(%%edx) \n\t"
4408 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4409 "movl $0, 36(%%edx) \n\t"
4411 : "d"(jmpbuf
) // input
4415 __asm__ __volatile__
4417 "mov %%fs:0, %%eax \n\t" // unsure
4418 "mov %%eax, 24(%%edx) \n\t"
4419 "cmp $0xffffffff, %%eax \n\t"
4421 "mov %%eax, 28(%%edx) \n\t"
4432 static DWORD WINAPI
expGetCurrentProcessId(void)
4434 dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4435 return getpid(); //(DWORD)NtCurrentTeb()->pid;
4442 } TIMECAPS
, *LPTIMECAPS
;
4444 static MMRESULT WINAPI
exptimeGetDevCaps(LPTIMECAPS lpCaps
, UINT wSize
)
4446 dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps
, wSize
);
4448 lpCaps
->wPeriodMin
= 1;
4449 lpCaps
->wPeriodMax
= 65535;
4453 static MMRESULT WINAPI
exptimeBeginPeriod(UINT wPeriod
)
4455 dbgprintf("timeBeginPeriod(%u) !\n", wPeriod
);
4457 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4462 static MMRESULT WINAPI
exptimeEndPeriod(UINT wPeriod
)
4464 dbgprintf("timeEndPeriod(%u) !\n", wPeriod
);
4466 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4471 static void WINAPI
expGlobalMemoryStatus(
4472 LPMEMORYSTATUS lpmem
4474 static MEMORYSTATUS cached_memstatus
;
4475 static int cache_lastchecked
= 0;
4479 if (time(NULL
)==cache_lastchecked
) {
4480 memcpy(lpmem
,&cached_memstatus
,sizeof(MEMORYSTATUS
));
4485 f
= fopen( "/proc/meminfo", "r" );
4489 int total
, used
, free
, shared
, buffers
, cached
;
4491 lpmem
->dwLength
= sizeof(MEMORYSTATUS
);
4492 lpmem
->dwTotalPhys
= lpmem
->dwAvailPhys
= 0;
4493 lpmem
->dwTotalPageFile
= lpmem
->dwAvailPageFile
= 0;
4494 while (fgets( buffer
, sizeof(buffer
), f
))
4496 /* old style /proc/meminfo ... */
4497 if (sscanf( buffer
, "Mem: %d %d %d %d %d %d", &total
, &used
, &free
, &shared
, &buffers
, &cached
))
4499 lpmem
->dwTotalPhys
+= total
;
4500 lpmem
->dwAvailPhys
+= free
+ buffers
+ cached
;
4502 if (sscanf( buffer
, "Swap: %d %d %d", &total
, &used
, &free
))
4504 lpmem
->dwTotalPageFile
+= total
;
4505 lpmem
->dwAvailPageFile
+= free
;
4508 /* new style /proc/meminfo ... */
4509 if (sscanf(buffer
, "MemTotal: %d", &total
))
4510 lpmem
->dwTotalPhys
= total
*1024;
4511 if (sscanf(buffer
, "MemFree: %d", &free
))
4512 lpmem
->dwAvailPhys
= free
*1024;
4513 if (sscanf(buffer
, "SwapTotal: %d", &total
))
4514 lpmem
->dwTotalPageFile
= total
*1024;
4515 if (sscanf(buffer
, "SwapFree: %d", &free
))
4516 lpmem
->dwAvailPageFile
= free
*1024;
4517 if (sscanf(buffer
, "Buffers: %d", &buffers
))
4518 lpmem
->dwAvailPhys
+= buffers
*1024;
4519 if (sscanf(buffer
, "Cached: %d", &cached
))
4520 lpmem
->dwAvailPhys
+= cached
*1024;
4524 if (lpmem
->dwTotalPhys
)
4526 DWORD TotalPhysical
= lpmem
->dwTotalPhys
+lpmem
->dwTotalPageFile
;
4527 DWORD AvailPhysical
= lpmem
->dwAvailPhys
+lpmem
->dwAvailPageFile
;
4528 lpmem
->dwMemoryLoad
= (TotalPhysical
-AvailPhysical
)
4529 / (TotalPhysical
/ 100);
4534 /* FIXME: should do something for other systems */
4535 lpmem
->dwMemoryLoad
= 0;
4536 lpmem
->dwTotalPhys
= 16*1024*1024;
4537 lpmem
->dwAvailPhys
= 16*1024*1024;
4538 lpmem
->dwTotalPageFile
= 16*1024*1024;
4539 lpmem
->dwAvailPageFile
= 16*1024*1024;
4541 expGetSystemInfo(&si
);
4542 lpmem
->dwTotalVirtual
= si
.lpMaximumApplicationAddress
-si
.lpMinimumApplicationAddress
;
4543 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4544 lpmem
->dwAvailVirtual
= lpmem
->dwTotalVirtual
-64*1024;
4545 memcpy(&cached_memstatus
,lpmem
,sizeof(MEMORYSTATUS
));
4546 cache_lastchecked
= time(NULL
);
4548 /* it appears some memory display programs want to divide by these values */
4549 if(lpmem
->dwTotalPageFile
==0)
4550 lpmem
->dwTotalPageFile
++;
4552 if(lpmem
->dwAvailPageFile
==0)
4553 lpmem
->dwAvailPageFile
++;
4556 static INT WINAPI
expGetThreadPriority(HANDLE hthread
)
4558 dbgprintf("GetThreadPriority(%p)\n",hthread
);
4562 /**********************************************************************
4563 * SetThreadPriority [KERNEL32.@] Sets priority for thread.
4569 static WIN_BOOL WINAPI
expSetThreadPriority(
4570 HANDLE hthread
, /* [in] Handle to thread */
4571 INT priority
) /* [in] Thread priority level */
4573 dbgprintf("SetThreadPriority(%p,%d)\n",hthread
,priority
);
4577 static void WINAPI
expExitProcess( DWORD status
)
4579 printf("EXIT - code %ld\n",status
);
4583 static INT WINAPI
expMessageBoxA(HWND hWnd
, LPCSTR text
, LPCSTR title
, UINT type
){
4584 printf("MSGBOX '%s' '%s' (%d)\n",text
,title
,type
);
4586 if (type
== MB_ICONHAND
&& !strlen(text
) && !strlen(title
))
4592 /* these are needed for mss1 */
4595 * \brief this symbol is defined within exp_EH_prolog_dummy
4596 * \param dest jump target
4598 void exp_EH_prolog(void *dest
);
4599 //! just a dummy function that acts a container for the asm section
4600 void exp_EH_prolog_dummy(void) {
4602 // take care, this "function" may not change flags or
4603 // registers besides eax (which is also why we can't use
4604 // exp_EH_prolog_dummy directly)
4605 MANGLE(exp_EH_prolog
)": \n\t"
4608 "mov %esp, %ebp \n\t"
4609 "lea -12(%esp), %esp \n\t"
4614 #include <netinet/in.h>
4615 static WINAPI
inline unsigned long int exphtonl(unsigned long int hostlong
)
4617 // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4618 return htonl(hostlong
);
4621 static WINAPI
inline unsigned long int expntohl(unsigned long int netlong
)
4623 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4624 return ntohl(netlong
);
4626 static void WINAPI
expVariantInit(void* p
)
4628 printf("InitCommonControls called!\n");
4632 static int WINAPI
expRegisterClassA(const void/*WNDCLASSA*/ *wc
)
4634 dbgprintf("RegisterClassA(%p) => random id\n", wc
);
4635 return time(NULL
); /* be precise ! */
4638 static int WINAPI
expUnregisterClassA(const char *className
, HINSTANCE hInstance
)
4640 dbgprintf("UnregisterClassA(%s, %p) => 0\n", className
, hInstance
);
4645 /* should be fixed bcs it's not fully strlen equivalent */
4646 static int expSysStringByteLen(void *str
)
4648 dbgprintf("SysStringByteLen(%p) => %d\n", str
, strlen(str
));
4652 static int expDirectDrawCreate(void)
4654 dbgprintf("DirectDrawCreate(...) => NULL\n");
4659 typedef struct tagPALETTEENTRY
{
4666 /* reversed the first 2 entries */
4667 typedef struct tagLOGPALETTE
{
4670 PALETTEENTRY palPalEntry
[1];
4673 static HPALETTE WINAPI
expCreatePalette(CONST LOGPALETTE
*lpgpl
)
4678 dbgprintf("CreatePalette(%x) => NULL\n", lpgpl
);
4680 i
= sizeof(LOGPALETTE
)+((lpgpl
->palNumEntries
-1)*sizeof(PALETTEENTRY
));
4681 test
= (HPALETTE
)malloc(i
);
4682 memcpy((void *)test
, lpgpl
, i
);
4687 static int expCreatePalette(void)
4689 dbgprintf("CreatePalette(...) => NULL\n");
4694 static int WINAPI
expGetClientRect(HWND win
, RECT
*r
)
4696 dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win
, r
);
4697 r
->right
= PSEUDO_SCREEN_WIDTH
;
4699 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
4705 typedef struct tagPOINT
{
4711 static int WINAPI
expClientToScreen(HWND win
, POINT
*p
)
4713 dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win
, p
, p
->x
, p
->y
);
4721 static int WINAPI
expSetThreadIdealProcessor(HANDLE thread
, int proc
)
4723 dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread
, proc
);
4727 static int WINAPI
expMessageBeep(int type
)
4729 dbgprintf("MessageBeep(%d) => 1\n", type
);
4733 static int WINAPI
expDialogBoxParamA(void *inst
, const char *name
,
4734 HWND parent
, void *dialog_func
, void *init_param
)
4736 dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
4737 inst
, name
, name
, parent
, dialog_func
, init_param
);
4741 static void WINAPI
expRegisterClipboardFormatA(const char *name
) {
4742 dbgprintf("RegisterClipboardFormatA(0x%x = %s)\n", name
, name
);
4745 /* needed by imagepower mjpeg2k */
4746 static void *exprealloc(void *ptr
, size_t size
)
4748 dbgprintf("realloc(0x%x, %x)\n", ptr
, size
);
4750 return my_mreq(size
,0);
4752 return my_realloc(ptr
, size
);
4755 /* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
4756 static WIN_BOOL WINAPI
expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn
)
4761 static char * WINAPI
expPathFindExtensionA(const char *path
) {
4766 ext
= strrchr(path
, '.');
4768 ext
= &path
[strlen(path
)];
4770 dbgprintf("PathFindExtensionA(0x%x = %s) => 0x%x, %s\n", path
, path
, ext
, ext
);
4774 static char * WINAPI
expPathFindFileNameA(const char *path
) {
4776 if (!path
|| strlen(path
) < 2)
4779 name
= strrchr(path
- 1, '\\');
4783 dbgprintf("PathFindFileNameA(0x%x = %s) => 0x%x, %s\n", path
, path
, name
, name
);
4787 static double expfloor(double x
)
4789 dbgprintf("floor(%lf)\n", x
);
4793 #define FPU_DOUBLE(var) double var; \
4794 __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var) : )
4796 static double exp_CIcos(void)
4800 dbgprintf("_CIcos(%lf)\n", x
);
4804 static double exp_CIsin(void)
4808 dbgprintf("_CIsin(%lf)\n", x
);
4812 static double exp_CIsqrt(void)
4816 dbgprintf("_CIsqrt(%lf)\n", x
);
4820 /* Needed by rp8 sipr decoder */
4821 static LPSTR WINAPI
expCharNextA(LPCSTR ptr
)
4823 if (!*ptr
) return (LPSTR
)ptr
;
4824 // dbgprintf("CharNextA(0x%08x), %s\n", ptr, ptr);
4825 return (LPSTR
)(ptr
+ 1);
4828 // Fake implementation, needed by wvc1dmod.dll
4829 static int WINAPI
expPropVariantClear(void *pvar
)
4831 // dbgprintf("PropVariantclear (0x%08x), %s\n", ptr, ptr);
4835 // This define is fake, the real thing is a struct
4836 #define LPDEVMODEA void*
4837 // Dummy implementation, always return 1
4838 // Required for frapsvid.dll 2.8.1, return value does not matter
4839 static WIN_BOOL WINAPI
expEnumDisplaySettingsA(LPCSTR name
,DWORD n
,
4842 dbgprintf("EnumDisplaySettingsA (dummy) => 1\n");
4856 struct exports
* exps
;
4860 {#X, Y, (void*)exp##X},
4862 struct exports exp_kernel32
[]=
4864 FF(GetVolumeInformationA
,-1)
4865 FF(GetDriveTypeA
,-1)
4866 FF(GetLogicalDriveStringsA
,-1)
4867 FF(IsBadWritePtr
, 357)
4868 FF(IsBadReadPtr
, 354)
4869 FF(IsBadStringPtrW
, -1)
4870 FF(IsBadStringPtrA
, -1)
4871 FF(DisableThreadLibraryCalls
, -1)
4872 FF(CreateThread
, -1)
4873 FF(CreateEventA
, -1)
4876 FF(WaitForSingleObject
, -1)
4878 FF(WaitForMultipleObjects
, -1)
4883 FF(GetSystemInfo
, -1)
4891 FF(GetProcessHeap
, -1)
4892 FF(VirtualAlloc
, -1)
4894 FF(InitializeCriticalSection
, -1)
4895 FF(EnterCriticalSection
, -1)
4896 FF(LeaveCriticalSection
, -1)
4897 FF(DeleteCriticalSection
, -1)
4902 FF(GetCurrentThreadId
, -1)
4903 FF(GetCurrentProcess
, -1)
4908 FF(GlobalReAlloc
, -1)
4911 FF(MultiByteToWideChar
, 427)
4912 FF(WideCharToMultiByte
, -1)
4913 FF(GetVersionExA
, -1)
4914 FF(CreateSemaphoreA
, -1)
4915 FF(QueryPerformanceCounter
, -1)
4916 FF(QueryPerformanceFrequency
, -1)
4920 FF(GlobalHandle
, -1)
4921 FF(GlobalUnlock
, -1)
4923 FF(LoadResource
, -1)
4924 FF(ReleaseSemaphore
, -1)
4925 FF(FindResourceA
, -1)
4926 FF(LockResource
, -1)
4927 FF(FreeResource
, -1)
4928 FF(SizeofResource
, -1)
4930 FF(GetCommandLineA
, -1)
4931 FF(GetEnvironmentStringsW
, -1)
4932 FF(FreeEnvironmentStringsW
, -1)
4933 FF(FreeEnvironmentStringsA
, -1)
4934 FF(GetEnvironmentStrings
, -1)
4935 FF(GetStartupInfoA
, -1)
4936 FF(GetStdHandle
, -1)
4939 FF(GetFileAttributesA
, -1)
4941 FF(SetHandleCount
, -1)
4943 FF(GetModuleFileNameA
, -1)
4944 FF(SetUnhandledExceptionFilter
, -1)
4945 FF(LoadLibraryA
, -1)
4946 FF(GetProcAddress
, -1)
4948 FF(CreateFileMappingA
, -1)
4949 FF(OpenFileMappingA
, -1)
4950 FF(MapViewOfFile
, -1)
4951 FF(UnmapViewOfFile
, -1)
4953 FF(GetModuleHandleA
, -1)
4954 FF(GetProfileIntA
, -1)
4955 FF(GetPrivateProfileIntA
, -1)
4956 FF(GetPrivateProfileStringA
, -1)
4957 FF(WritePrivateProfileStringA
, -1)
4958 FF(GetLastError
, -1)
4959 FF(SetLastError
, -1)
4960 FF(InterlockedIncrement
, -1)
4961 FF(InterlockedDecrement
, -1)
4962 FF(GetTimeZoneInformation
, -1)
4963 FF(OutputDebugStringA
, -1)
4964 FF(GetLocalTime
, -1)
4965 FF(GetSystemTime
, -1)
4966 FF(GetSystemTimeAsFileTime
, -1)
4967 FF(GetEnvironmentVariableA
, -1)
4968 FF(SetEnvironmentVariableA
, -1)
4969 FF(RtlZeroMemory
,-1)
4970 FF(RtlMoveMemory
,-1)
4971 FF(RtlFillMemory
,-1)
4973 FF(FindFirstFileA
,-1)
4974 FF(FindNextFileA
,-1)
4976 FF(FileTimeToLocalFileTime
,-1)
4980 FF(SetFilePointer
,-1)
4981 FF(GetTempFileNameA
,-1)
4983 FF(GetSystemDirectoryA
,-1)
4984 FF(GetWindowsDirectoryA
,-1)
4986 FF(GetCurrentDirectoryA
,-1)
4987 FF(SetCurrentDirectoryA
,-1)
4988 FF(CreateDirectoryA
,-1)
4990 FF(GetShortPathNameA
,-1)
4991 FF(GetFullPathNameA
,-1)
4992 FF(SetErrorMode
, -1)
4993 FF(IsProcessorFeaturePresent
, -1)
4994 FF(GetProcessAffinityMask
, -1)
4995 FF(InterlockedExchange
, -1)
4996 FF(InterlockedCompareExchange
, -1)
5003 FF(GetProcessVersion
,-1)
5004 FF(GetCurrentThread
,-1)
5007 FF(DuplicateHandle
,-1)
5008 FF(GetTickCount
, -1)
5009 FF(SetThreadAffinityMask
,-1)
5010 FF(GetCurrentProcessId
,-1)
5011 FF(GlobalMemoryStatus
,-1)
5012 FF(GetThreadPriority
,-1)
5013 FF(SetThreadPriority
,-1)
5015 {"LoadLibraryExA", -1, (void*)&LoadLibraryExA
},
5016 FF(SetThreadIdealProcessor
,-1)
5017 FF(SetProcessAffinityMask
, -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
},
5077 {"ceil",-1,(void*)&ceil
},
5078 /* needed by imagepower mjpeg2k */
5079 {"clock",-1,(void*)&clock
},
5080 {"memchr",-1,(void*)&memchr
},
5081 {"vfprintf",-1,(void*)&vfprintf
},
5082 // {"realloc",-1,(void*)&realloc},
5084 {"puts",-1,(void*)&puts
}
5086 struct exports exp_winmm
[]={
5087 FF(GetDriverModuleHandle
, -1)
5089 FF(DefDriverProc
, -1)
5092 FF(timeGetDevCaps
, -1)
5093 FF(timeBeginPeriod
, -1)
5095 FF(timeEndPeriod
, -1)
5096 FF(waveOutGetNumDevs
, -1)
5099 struct exports exp_user32
[]={
5104 FF(GetDesktopWindow
, -1)
5113 FF(RegisterWindowMessageA
,-1)
5114 FF(GetSystemMetrics
,-1)
5116 FF(GetSysColorBrush
,-1)
5120 FF(RegisterClassA
, -1)
5121 FF(UnregisterClassA
, -1)
5123 FF(GetWindowRect
, -1)
5124 FF(MonitorFromWindow
, -1)
5125 FF(MonitorFromRect
, -1)
5126 FF(MonitorFromPoint
, -1)
5127 FF(EnumDisplayMonitors
, -1)
5128 FF(GetMonitorInfoA
, -1)
5129 FF(EnumDisplayDevicesA
, -1)
5130 FF(GetClientRect
, -1)
5131 FF(ClientToScreen
, -1)
5132 FF(IsWindowVisible
, -1)
5133 FF(GetActiveWindow
, -1)
5134 FF(GetClassNameA
, -1)
5135 FF(GetClassInfoA
, -1)
5136 FF(GetWindowLongA
, -1)
5138 FF(GetWindowThreadProcessId
, -1)
5139 FF(CreateWindowExA
, -1)
5142 FF(DialogBoxParamA
, -1)
5143 FF(RegisterClipboardFormatA
, -1)
5145 FF(EnumDisplaySettingsA
, -1)
5147 struct exports exp_advapi32
[]={
5149 FF(RegCreateKeyA
, -1)
5150 FF(RegCreateKeyExA
, -1)
5151 FF(RegEnumKeyExA
, -1)
5152 FF(RegEnumValueA
, -1)
5154 FF(RegOpenKeyExA
, -1)
5155 FF(RegQueryValueExA
, -1)
5156 FF(RegSetValueExA
, -1)
5157 FF(RegQueryInfoKeyA
, -1)
5159 struct exports exp_gdi32
[]={
5160 FF(CreateCompatibleDC
, -1)
5163 FF(DeleteObject
, -1)
5164 FF(GetDeviceCaps
, -1)
5165 FF(GetSystemPaletteEntries
, -1)
5167 FF(CreatePalette
, -1)
5169 FF(CreateRectRgn
, -1)
5172 struct exports exp_version
[]={
5173 FF(GetFileVersionInfoSizeA
, -1)
5175 struct exports exp_ole32
[]={
5176 FF(CoCreateFreeThreadedMarshaler
,-1)
5177 FF(CoCreateInstance
, -1)
5178 FF(CoInitialize
, -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)
5268 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5270 struct libs libraries
[]={
5294 static void ext_stubs(void)
5296 volatile int idx
= 0xdeadabcd;
5297 // make sure gcc does not do eip-relative call or something like that
5298 volatile void (*my_printf
)(char *, char *) = (void *)0xdeadfbcd;
5299 my_printf("Called unk_%s\n", export_names
[idx
]);
5302 #define MAX_STUB_SIZE 0x60
5303 #define MAX_NUM_STUBS 200
5305 static char *extcode
= NULL
;
5307 static void* add_stub(void)
5311 // generated code in runtime!
5314 extcode
= mmap_anon(NULL
, MAX_NUM_STUBS
* MAX_STUB_SIZE
,
5315 PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
, 0);
5316 answ
= extcode
+ pos
* MAX_STUB_SIZE
;
5317 if (pos
>= MAX_NUM_STUBS
) {
5318 printf("too many stubs, expect crash\n");
5321 memcpy(answ
, ext_stubs
, MAX_STUB_SIZE
);
5322 for (i
= 0; i
< MAX_STUB_SIZE
- 3; i
++) {
5323 int *magic
= (int *)(answ
+ i
);
5324 if (*magic
== 0xdeadabcd) {
5328 if (*magic
== 0xdeadfbcd) {
5329 *magic
= (intptr_t)printf
;
5334 printf("magic code not found in ext_subs, expect crash\n");
5341 void* LookupExternal(const char* library
, int ordinal
)
5346 printf("ERROR: library=0\n");
5347 return (void*)ext_unknown
;
5349 // printf("%x %x\n", &unk_exp1, &unk_exp2);
5351 dbgprintf("External func %s:%d\n", library
, ordinal
);
5353 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5355 if(strcasecmp(library
, libraries
[i
].name
))
5357 for(j
=0; j
<libraries
[i
].length
; j
++)
5359 if(ordinal
!=libraries
[i
].exps
[j
].id
)
5361 //printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5362 return libraries
[i
].exps
[j
].func
;
5366 #ifndef LOADLIB_TRY_NATIVE
5367 /* hack for truespeech and vssh264*/
5368 if (!strcmp(library
, "tsd32.dll") || !strcmp(library
,"vssh264dec.dll") || !strcmp(library
,"LCMW2.dll") || !strcmp(library
,"VDODEC32.dll"))
5370 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5376 hand
= LoadLibraryA(library
);
5379 wm
= MODULE32_LookupHMODULE(hand
);
5385 func
= PE_FindExportedFunction(wm
, (LPCSTR
) ordinal
, 0);
5388 printf("No such ordinal in external dll\n");
5389 FreeLibrary((int)hand
);
5393 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5399 if(pos
>150)return 0;
5400 sprintf(export_names
[pos
], "%s:%d", library
, ordinal
);
5404 void* LookupExternalByName(const char* library
, const char* name
)
5408 // return (void*)ext_unknown;
5411 printf("ERROR: library=0\n");
5412 return (void*)ext_unknown
;
5416 printf("ERROR: name=0\n");
5417 return (void*)ext_unknown
;
5419 dbgprintf("External func %s:%s\n", library
, name
);
5420 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5422 if(strcasecmp(library
, libraries
[i
].name
))
5424 for(j
=0; j
<libraries
[i
].length
; j
++)
5426 if(strcmp(name
, libraries
[i
].exps
[j
].name
))
5428 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5429 return libraries
[i
].exps
[j
].func
;
5433 #ifndef LOADLIB_TRY_NATIVE
5434 /* hack for vss h264 */
5435 if (!strcmp(library
,"vssh264core.dll"))
5437 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5443 hand
= LoadLibraryA(library
);
5446 wm
= MODULE32_LookupHMODULE(hand
);
5452 func
= PE_FindExportedFunction(wm
, name
, 0);
5455 printf("No such name in external dll\n");
5456 FreeLibrary((int)hand
);
5460 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5466 if(pos
>150)return 0;// to many symbols
5467 strcpy(export_names
[pos
], name
);
5471 void my_garbagecollection(void)
5474 int unfree
= 0, unfreecnt
= 0;
5480 alloc_header
* mem
= last_alloc
+ 1;
5481 unfree
+= my_size(mem
);
5483 if (my_release(mem
) != 0)
5484 // avoid endless loop when memory is trashed
5485 if (--max_fatal
< 0)
5488 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree
, unfreecnt
, last_alloc
, alccnt
);