1 /***********************************************************
3 Win32 emulation code. Functions that emulate
4 responses from corresponding Win32 API calls.
5 Since we are not going to be able to load
6 virtually any DLL, we can only implement this
7 much, adding needed functions with each new codec.
9 Basic principle of implementation: it's not good
10 for DLL to know too much about its environment.
12 ************************************************************/
15 * Modified for use with MPlayer, detailed changelog at
16 * http://svn.mplayerhq.hu/mplayer/trunk/
22 #ifdef CONFIG_QTX_CODECS
26 //#define LOADLIB_TRY_NATIVE
29 #define PSEUDO_SCREEN_WIDTH /*640*/800
30 #define PSEUDO_SCREEN_HEIGHT /*480*/600
33 #include "wine/winbase.h"
34 #include "wine/winreg.h"
35 #include "wine/winnt.h"
36 #include "wine/winerror.h"
37 #include "wine/debugtools.h"
38 #include "wine/module.h"
39 #include "wine/winuser.h"
40 #include "wine/objbase.h"
63 #include <sys/types.h>
66 #include <sys/timeb.h>
71 #ifdef HAVE_SYS_MMAN_H
74 #include "osdep/mmap.h"
76 #include "osdep/mmap_anon.h"
78 char* def_path
= WIN32_PATH
;
80 static void do_cpuid(unsigned int ax
, unsigned int *regs
)
84 "pushl %%ebx; pushl %%ecx; pushl %%edx;"
90 "popl %%edx; popl %%ecx; popl %%ebx;"
92 : "0" (ax
), "S" (regs
)
95 static unsigned int c_localcount_tsc()
107 static void c_longcount_tsc(long long* z
)
112 "movl %%eax, %%ebx\n\t"
114 "movl %%eax, 0(%%ebx)\n\t"
115 "movl %%edx, 4(%%ebx)\n\t"
121 static unsigned int c_localcount_notsc()
126 gettimeofday(&tv
, 0);
127 return limit
*tv
.tv_usec
;
129 static void c_longcount_notsc(long long* z
)
132 unsigned long long result
;
136 gettimeofday(&tv
, 0);
139 result
+=limit
*tv
.tv_usec
;
142 static unsigned int localcount_stub(void);
143 static void longcount_stub(long long*);
144 static unsigned int (*localcount
)()=localcount_stub
;
145 static void (*longcount
)(long long*)=longcount_stub
;
147 static pthread_mutex_t memmut
;
149 static unsigned int localcount_stub(void)
151 unsigned int regs
[4];
153 if ((regs
[3] & 0x00000010) != 0)
155 localcount
=c_localcount_tsc
;
156 longcount
=c_longcount_tsc
;
160 localcount
=c_localcount_notsc
;
161 longcount
=c_longcount_notsc
;
165 static void longcount_stub(long long* z
)
167 unsigned int regs
[4];
169 if ((regs
[3] & 0x00000010) != 0)
171 localcount
=c_localcount_tsc
;
172 longcount
=c_longcount_tsc
;
176 localcount
=c_localcount_notsc
;
177 longcount
=c_longcount_notsc
;
183 int LOADER_DEBUG
=1; // active only if compiled with -DDETAILED_OUT
184 //#define DETAILED_OUT
185 static inline void dbgprintf(char* fmt
, ...)
193 f
=fopen("./log", "a");
198 vfprintf(f
, fmt
, va
);
205 if ( mp_msg_test(MSGT_WIN32
,MSGL_DBG3
) )
211 // mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va);
218 char export_names
[300][32]={
223 //#define min(x,y) ((x)<(y)?(x):(y))
225 void destroy_event(void* event
);
228 typedef struct th_list_t
{
231 struct th_list_t
* next
;
232 struct th_list_t
* prev
;
236 // have to be cleared by GARBAGE COLLECTOR
237 //static unsigned char* heap=NULL;
238 //static int heap_counter=0;
239 static tls_t
* g_tls
=NULL
;
240 static th_list
* list
=NULL
;
243 static void test_heap(void)
248 while(offset
<heap_counter
)
250 if(*(int*)(heap
+offset
)!=0x433476)
252 printf("Heap corruption at address %d\n", offset
);
255 offset
+=8+*(int*)(heap
+offset
+4);
257 for(;offset
<min(offset
+1000, 20000000); offset
++)
258 if(heap
[offset
]!=0xCC)
260 printf("Free heap corruption at address %d\n", offset
);
268 static void* my_mreq(int size
, int to_zero
)
272 if(test
%10==0)printf("Memory: %d bytes allocated\n", heap_counter
);
276 heap
=malloc(20000000);
277 memset(heap
, 0xCC,20000000);
281 printf("No enough memory\n");
284 if(heap_counter
+size
>20000000)
286 printf("No enough memory\n");
289 *(int*)(heap
+heap_counter
)=0x433476;
291 *(int*)(heap
+heap_counter
)=size
;
293 printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size
, heap_counter
-8, heap_counter
, heap_counter
+size
);
295 memset(heap
+heap_counter
, 0, size
);
297 memset(heap
+heap_counter
, 0xcc, size
); // make crash reproducable
299 return heap
+heap_counter
-size
;
301 static int my_release(char* memory
)
306 printf("ERROR: free(0)\n");
309 if(*(int*)(memory
-8)!=0x433476)
311 printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
314 printf("Freed %d bytes of memory\n", *(int*)(memory
-4));
315 // memset(memory-8, *(int*)(memory-4), 0xCC);
321 typedef struct alloc_header_t alloc_header
;
322 struct alloc_header_t
324 // let's keep allocated data 16 byte aligned
336 static alloc_header
* last_alloc
= NULL
;
337 static int alccnt
= 0;
340 #define AREATYPE_CLIENT 0
341 #define AREATYPE_EVENT 1
342 #define AREATYPE_MUTEX 2
343 #define AREATYPE_COND 3
344 #define AREATYPE_CRITSECT 4
346 /* -- critical sections -- */
350 pthread_mutex_t mutex
;
355 void* mreq_private(int size
, int to_zero
, int type
);
356 void* mreq_private(int size
, int to_zero
, int type
)
358 int nsize
= size
+ sizeof(alloc_header
);
359 alloc_header
* header
= (alloc_header
* ) malloc(nsize
);
363 memset(header
, 0, nsize
);
367 pthread_mutex_init(&memmut
, NULL
);
368 pthread_mutex_lock(&memmut
);
372 pthread_mutex_lock(&memmut
);
373 last_alloc
->next
= header
; /* set next */
376 header
->prev
= last_alloc
;
380 pthread_mutex_unlock(&memmut
);
382 header
->deadbeef
= 0xdeadbeef;
386 //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt);
390 static int my_release(void* memory
)
392 alloc_header
* header
= (alloc_header
*) memory
- 1;
394 alloc_header
* prevmem
;
395 alloc_header
* nextmem
;
400 if (header
->deadbeef
!= (long) 0xdeadbeef)
402 dbgprintf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
406 pthread_mutex_lock(&memmut
);
411 destroy_event(memory
);
414 pthread_cond_destroy((pthread_cond_t
*)memory
);
417 pthread_mutex_destroy((pthread_mutex_t
*)memory
);
419 case AREATYPE_CRITSECT
:
420 pthread_mutex_destroy(&((struct CRITSECT
*)memory
)->mutex
);
423 //memset(memory, 0xcc, header->size);
427 header
->deadbeef
= 0;
428 prevmem
= header
->prev
;
429 nextmem
= header
->next
;
432 prevmem
->next
= nextmem
;
434 nextmem
->prev
= prevmem
;
436 if (header
== last_alloc
)
437 last_alloc
= prevmem
;
442 pthread_mutex_unlock(&memmut
);
444 pthread_mutex_destroy(&memmut
);
446 //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt);
451 //memset(header + 1, 0xcc, header->size);
457 static inline void* my_mreq(int size
, int to_zero
)
459 return mreq_private(size
, to_zero
, AREATYPE_CLIENT
);
462 static int my_size(void* memory
)
464 if(!memory
) return 0;
465 return ((alloc_header
*)memory
)[-1].size
;
468 static void* my_realloc(void* memory
, int size
)
473 return my_mreq(size
, 0);
474 osize
= my_size(memory
);
477 ans
= my_mreq(size
, 0);
478 memcpy(ans
, memory
, osize
);
486 * WINE API - native implementation for several win32 libraries
490 static int WINAPI
ext_unknown()
492 printf("Unknown func called\n");
496 static int WINAPI
expGetVolumeInformationA( const char *root
, char *label
,
497 unsigned int label_len
, unsigned int *serial
,
498 unsigned int *filename_len
,unsigned int *flags
,
499 char *fsname
, unsigned int fsname_len
)
501 dbgprintf("GetVolumeInformationA( %s, 0x%x, %ld, 0x%x, 0x%x, 0x%x, 0x%x, %ld) => 1\n",
502 root
,label
,label_len
,serial
,filename_len
,flags
,fsname
,fsname_len
);
503 //hack Do not return any real data - do nothing
507 static unsigned int WINAPI
expGetDriveTypeA( const char *root
)
509 dbgprintf("GetDriveTypeA( %s ) => %d\n",root
,DRIVE_FIXED
);
510 // hack return as Fixed Drive Type
514 static unsigned int WINAPI
expGetLogicalDriveStringsA( unsigned int len
, char *buffer
)
516 dbgprintf("GetLogicalDriveStringsA(%d, 0x%x) => 4\n",len
,buffer
);
517 // hack only have one drive c:\ in this hack
523 return 4; // 1 drive * 4 bytes (includes null)
527 static int WINAPI
expIsBadWritePtr(void* ptr
, unsigned int count
)
529 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
530 dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
533 static int WINAPI
expIsBadReadPtr(void* ptr
, unsigned int count
)
535 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
536 dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
539 static int WINAPI
expDisableThreadLibraryCalls(int module
)
541 dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module
);
545 static HMODULE WINAPI
expGetDriverModuleHandle(DRVR
* pdrv
)
551 result
=pdrv
->hDriverModule
;
552 dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv
, result
);
556 #define MODULE_HANDLE_kernel32 ((HMODULE)0x120)
557 #define MODULE_HANDLE_user32 ((HMODULE)0x121)
559 #define MODULE_HANDLE_wininet ((HMODULE)0x122)
560 #define MODULE_HANDLE_ddraw ((HMODULE)0x123)
561 #define MODULE_HANDLE_advapi32 ((HMODULE)0x124)
563 #define MODULE_HANDLE_comdlg32 ((HMODULE)0x125)
564 #define MODULE_HANDLE_msvcrt ((HMODULE)0x126)
565 #define MODULE_HANDLE_ole32 ((HMODULE)0x127)
566 #define MODULE_HANDLE_winmm ((HMODULE)0x128)
568 static HMODULE WINAPI
expGetModuleHandleA(const char* name
)
580 wm
=MODULE_FindModule(name
);
583 result
=(HMODULE
)(wm
->module
);
587 if(name
&& (strcasecmp(name
, "kernel32")==0 || !strcasecmp(name
, "kernel32.dll")))
588 result
=MODULE_HANDLE_kernel32
;
590 if(name
&& strcasecmp(name
, "user32")==0)
591 result
=MODULE_HANDLE_user32
;
594 dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name
, result
);
598 static void* WINAPI
expCreateThread(void* pSecAttr
, long dwStackSize
,
599 void* lpStartAddress
, void* lpParameter
,
600 long dwFlags
, long* dwThreadId
)
603 // printf("CreateThread:");
604 pth
= (pthread_t
*) my_mreq(sizeof(pthread_t
), 0);
605 pthread_create(pth
, NULL
, (void*(*)(void*))lpStartAddress
, lpParameter
);
607 printf( "WARNING: CreateThread flags not supported\n");
609 *dwThreadId
=(long)pth
;
612 list
=my_mreq(sizeof(th_list
), 1);
613 list
->next
=list
->prev
=NULL
;
617 list
->next
=my_mreq(sizeof(th_list
), 0);
618 list
->next
->prev
=list
;
619 list
->next
->next
=NULL
;
623 dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
624 pSecAttr
, dwStackSize
, lpStartAddress
, lpParameter
, dwFlags
, dwThreadId
, pth
);
639 struct mutex_list_t
* next
;
640 struct mutex_list_t
* prev
;
642 typedef struct mutex_list_t mutex_list
;
643 static mutex_list
* mlist
=NULL
;
645 void destroy_event(void* event
)
647 mutex_list
* pp
=mlist
;
648 // printf("garbage collector: destroy_event(%x)\n", event);
651 if(pp
==(mutex_list
*)event
)
654 pp
->next
->prev
=pp
->prev
;
656 pp
->prev
->next
=pp
->next
;
657 if(mlist
==(mutex_list
*)event
)
663 printf("%x => ", pp);
674 static void* WINAPI
expCreateEventA(void* pSecAttr
, char bManualReset
,
675 char bInitialState
, const char* name
)
684 printf("%x => ", pp);
691 mutex_list
* pp
=mlist
;
695 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==0))
697 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
698 pSecAttr
, bManualReset
, bInitialState
, name
, name
, pp
->pm
);
701 }while((pp
=pp
->prev
) != NULL
);
703 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
704 pthread_mutex_init(pm
, NULL
);
705 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
706 pthread_cond_init(pc
, NULL
);
709 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
710 mlist
->next
=mlist
->prev
=NULL
;
714 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
715 mlist
->next
->prev
=mlist
;
716 mlist
->next
->next
=NULL
;
719 mlist
->type
=0; /* Type Event */
722 mlist
->state
=bInitialState
;
723 mlist
->reset
=bManualReset
;
725 strncpy(mlist
->name
, name
, 127);
729 dbgprintf("ERROR::: CreateEventA failure\n");
732 pthread_mutex_lock(pm);
735 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
736 pSecAttr
, bManualReset
, bInitialState
, name
, name
, mlist
);
738 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
739 pSecAttr
, bManualReset
, bInitialState
, mlist
);
743 static void* WINAPI
expSetEvent(void* event
)
745 mutex_list
*ml
= (mutex_list
*)event
;
746 dbgprintf("SetEvent(%x) => 0x1\n", event
);
747 pthread_mutex_lock(ml
->pm
);
748 if (ml
->state
== 0) {
750 pthread_cond_signal(ml
->pc
);
752 pthread_mutex_unlock(ml
->pm
);
756 static void* WINAPI
expResetEvent(void* event
)
758 mutex_list
*ml
= (mutex_list
*)event
;
759 dbgprintf("ResetEvent(0x%x) => 0x1\n", event
);
760 pthread_mutex_lock(ml
->pm
);
762 pthread_mutex_unlock(ml
->pm
);
767 static void* WINAPI
expWaitForSingleObject(void* object
, int duration
)
769 mutex_list
*ml
= (mutex_list
*)object
;
770 // FIXME FIXME FIXME - this value is sometime unititialize !!!
771 int ret
= WAIT_FAILED
;
772 mutex_list
* pp
=mlist
;
773 if(object
== (void*)0xcfcf9898)
776 From GetCurrentThread() documentation:
777 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.
779 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.
781 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.
783 dbgprintf("WaitForSingleObject(thread_handle) called\n");
784 return (void*)WAIT_FAILED
;
786 dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object
, duration
);
788 // loop below was slightly fixed - its used just for checking if
789 // this object really exists in our list
792 while (pp
&& (pp
->pm
!= ml
->pm
))
795 dbgprintf("WaitForSingleObject: NotFound\n");
799 pthread_mutex_lock(ml
->pm
);
803 if (duration
== 0) { /* Check Only */
804 if (ml
->state
== 1) ret
= WAIT_FAILED
;
805 else ret
= WAIT_OBJECT_0
;
807 if (duration
== -1) { /* INFINITE */
809 pthread_cond_wait(ml
->pc
,ml
->pm
);
814 if (duration
> 0) { /* Timed Wait */
815 struct timespec abstime
;
817 gettimeofday(&now
, 0);
818 abstime
.tv_sec
= now
.tv_sec
+ (now
.tv_usec
+duration
)/1000000;
819 abstime
.tv_nsec
= ((now
.tv_usec
+duration
)%1000000)*1000;
821 ret
=pthread_cond_timedwait(ml
->pc
,ml
->pm
,&abstime
);
822 if (ret
== ETIMEDOUT
) ret
= WAIT_TIMEOUT
;
823 else ret
= WAIT_OBJECT_0
;
828 case 1: /* Semaphore */
830 if(ml
->semaphore
==0) ret
= WAIT_FAILED
;
836 if (duration
== -1) {
837 if (ml
->semaphore
==0)
838 pthread_cond_wait(ml
->pc
,ml
->pm
);
843 pthread_mutex_unlock(ml
->pm
);
845 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object
,duration
,ml
,ret
);
850 static void* WINAPI
expWaitForMultipleObjects(int count
, const void** objects
,
851 int WaitAll
, int duration
)
857 dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
858 count
, objects
, WaitAll
, duration
);
860 for (i
= 0; i
< count
; i
++)
862 object
= (void *)objects
[i
];
863 ret
= expWaitForSingleObject(object
, duration
);
865 dbgprintf("WaitAll flag not yet supported...\n");
872 static void WINAPI
expExitThread(int retcode
)
874 dbgprintf("ExitThread(%d)\n", retcode
);
875 pthread_exit(&retcode
);
878 static HANDLE WINAPI
expCreateMutexA(void *pSecAttr
,
879 char bInitialOwner
, const char *name
)
881 HANDLE mlist
= (HANDLE
)expCreateEventA(pSecAttr
, 0, 0, name
);
884 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
885 pSecAttr
, bInitialOwner
, name
, mlist
);
887 dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
888 pSecAttr
, bInitialOwner
, mlist
);
890 /* 10l to QTX, if CreateMutex returns a real mutex, WaitForSingleObject
891 waits for ever, else it works ;) */
896 static int WINAPI
expReleaseMutex(HANDLE hMutex
)
898 dbgprintf("ReleaseMutex(%x) => 1\n", hMutex
);
899 /* FIXME:XXX !! not yet implemented */
904 static int pf_set
= 0;
905 static BYTE PF
[64] = {0,};
907 static void DumpSystemInfo(const SYSTEM_INFO
* si
)
909 dbgprintf(" Processor architecture %d\n", si
->u
.s
.wProcessorArchitecture
);
910 dbgprintf(" Page size: %d\n", si
->dwPageSize
);
911 dbgprintf(" Minimum app address: %d\n", si
->lpMinimumApplicationAddress
);
912 dbgprintf(" Maximum app address: %d\n", si
->lpMaximumApplicationAddress
);
913 dbgprintf(" Active processor mask: 0x%x\n", si
->dwActiveProcessorMask
);
914 dbgprintf(" Number of processors: %d\n", si
->dwNumberOfProcessors
);
915 dbgprintf(" Processor type: 0x%x\n", si
->dwProcessorType
);
916 dbgprintf(" Allocation granularity: 0x%x\n", si
->dwAllocationGranularity
);
917 dbgprintf(" Processor level: 0x%x\n", si
->wProcessorLevel
);
918 dbgprintf(" Processor revision: 0x%x\n", si
->wProcessorRevision
);
921 static void WINAPI
expGetSystemInfo(SYSTEM_INFO
* si
)
923 /* FIXME: better values for the two entries below... */
924 static int cache
= 0;
925 static SYSTEM_INFO cachedsi
;
926 dbgprintf("GetSystemInfo(%p) =>\n", si
);
931 memset(PF
,0,sizeof(PF
));
934 cachedsi
.u
.s
.wProcessorArchitecture
= PROCESSOR_ARCHITECTURE_INTEL
;
935 cachedsi
.dwPageSize
= getpagesize();
937 /* FIXME: better values for the two entries below... */
938 cachedsi
.lpMinimumApplicationAddress
= (void *)0x00000000;
939 cachedsi
.lpMaximumApplicationAddress
= (void *)0x7FFFFFFF;
940 cachedsi
.dwActiveProcessorMask
= 1;
941 cachedsi
.dwNumberOfProcessors
= 1;
942 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
943 cachedsi
.dwAllocationGranularity
= 0x10000;
944 cachedsi
.wProcessorLevel
= 5; /* pentium */
945 cachedsi
.wProcessorRevision
= 0x0101;
947 /* mplayer's way to detect PF's */
949 #include "cpudetect.h"
952 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
954 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
955 if (gCpuCaps
.hasSSE2
)
956 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
957 if (gCpuCaps
.has3DNow
)
958 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
960 if (gCpuCaps
.cpuType
== 4)
962 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
963 cachedsi
.wProcessorLevel
= 4;
965 else if (gCpuCaps
.cpuType
>= 5)
967 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
968 cachedsi
.wProcessorLevel
= 5;
972 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
973 cachedsi
.wProcessorLevel
= 3;
975 cachedsi
.wProcessorRevision
= gCpuCaps
.cpuStepping
;
976 cachedsi
.dwNumberOfProcessors
= 1; /* hardcoded */
979 /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
980 fdiv_bug and fpu emulation flags -- alex/MPlayer */
985 FILE *f
= fopen ("/proc/cpuinfo", "r");
989 mp_msg(MSGT_WIN32
, MSGL_WARN
, "expGetSystemInfo: "
990 "/proc/cpuinfo not readable! "
991 "Expect bad performance and/or weird behaviour\n");
994 while (fgets(line
,200,f
)!=NULL
) {
997 /* NOTE: the ':' is the only character we can rely on */
998 if (!(value
= strchr(line
,':')))
1000 /* terminate the valuename */
1002 /* skip any leading spaces */
1003 while (*value
==' ') value
++;
1004 if ((s
=strchr(value
,'\n')))
1008 if (!lstrncmpiA(line
, "cpu family",strlen("cpu family"))) {
1009 if (isdigit (value
[0])) {
1010 switch (value
[0] - '0') {
1011 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1012 cachedsi
.wProcessorLevel
= 3;
1014 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1015 cachedsi
.wProcessorLevel
= 4;
1017 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1018 cachedsi
.wProcessorLevel
= 5;
1020 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1021 cachedsi
.wProcessorLevel
= 5;
1023 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1024 cachedsi
.wProcessorLevel
= 5;
1028 /* set the CPU type of the current processor */
1029 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1032 /* old 2.0 method */
1033 if (!lstrncmpiA(line
, "cpu",strlen("cpu"))) {
1034 if ( isdigit (value
[0]) && value
[1] == '8' &&
1035 value
[2] == '6' && value
[3] == 0
1037 switch (value
[0] - '0') {
1038 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1039 cachedsi
.wProcessorLevel
= 3;
1041 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1042 cachedsi
.wProcessorLevel
= 4;
1044 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1045 cachedsi
.wProcessorLevel
= 5;
1047 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1048 cachedsi
.wProcessorLevel
= 5;
1050 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1051 cachedsi
.wProcessorLevel
= 5;
1055 /* set the CPU type of the current processor */
1056 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1059 if (!lstrncmpiA(line
,"fdiv_bug",strlen("fdiv_bug"))) {
1060 if (!lstrncmpiA(value
,"yes",3))
1061 PF
[PF_FLOATING_POINT_PRECISION_ERRATA
] = TRUE
;
1065 if (!lstrncmpiA(line
,"fpu",strlen("fpu"))) {
1066 if (!lstrncmpiA(value
,"no",2))
1067 PF
[PF_FLOATING_POINT_EMULATED
] = TRUE
;
1071 if (!lstrncmpiA(line
,"processor",strlen("processor"))) {
1072 /* processor number counts up...*/
1075 if (sscanf(value
,"%d",&x
))
1076 if (x
+1>cachedsi
.dwNumberOfProcessors
)
1077 cachedsi
.dwNumberOfProcessors
=x
+1;
1079 /* Create a new processor subkey on a multiprocessor
1082 sprintf(buf
,"%d",x
);
1084 if (!lstrncmpiA(line
,"stepping",strlen("stepping"))) {
1087 if (sscanf(value
,"%d",&x
))
1088 cachedsi
.wProcessorRevision
= x
;
1091 ( (!lstrncmpiA(line
,"flags",strlen("flags")))
1092 || (!lstrncmpiA(line
,"features",strlen("features"))) )
1094 if (strstr(value
,"cx8"))
1095 PF
[PF_COMPARE_EXCHANGE_DOUBLE
] = TRUE
;
1096 if (strstr(value
,"mmx"))
1097 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1098 if (strstr(value
,"tsc"))
1099 PF
[PF_RDTSC_INSTRUCTION_AVAILABLE
] = TRUE
;
1100 if (strstr(value
,"xmm") || strstr(value
,"sse"))
1101 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1102 if (strstr(value
,"sse2"))
1103 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1104 if (strstr(value
,"3dnow"))
1105 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1110 * ad hoc fix for smp machines.
1111 * some problems on WaitForSingleObject,CreateEvent,SetEvent
1112 * CreateThread ...etc..
1115 cachedsi
.dwNumberOfProcessors
=1;
1117 #endif /* __linux__ */
1120 memcpy(si
,&cachedsi
,sizeof(*si
));
1124 // avoid undefined expGetSystemInfo
1125 static WIN_BOOL WINAPI
expIsProcessorFeaturePresent(DWORD v
)
1127 WIN_BOOL result
= 0;
1131 expGetSystemInfo(&si
);
1133 if(v
<64) result
=PF
[v
];
1134 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v
, result
);
1139 static long WINAPI
expGetVersion()
1141 dbgprintf("GetVersion() => 0xC0000004\n");
1142 return 0xC0000004;//Windows 95
1145 static HANDLE WINAPI
expHeapCreate(long flags
, long init_size
, long max_size
)
1147 // printf("HeapCreate:");
1150 result
=(HANDLE
)my_mreq(0x110000, 0);
1152 result
=(HANDLE
)my_mreq((init_size
+ 0xfff) & 0x7ffff000 , 0);
1153 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags
, init_size
, max_size
, result
);
1157 // this is another dirty hack
1158 // VP31 is releasing one allocated Heap chunk twice
1159 // we will silently ignore this second call...
1160 static void* heapfreehack
= 0;
1161 static int heapfreehackshown
= 0;
1162 //void trapbug(void);
1163 static void* WINAPI
expHeapAlloc(HANDLE heap
, int flags
, int size
)
1167 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1168 HeapAlloc returns area larger than size argument :-/
1170 actually according to M$ Doc HeapCreate size should be rounded
1171 to page boundaries thus we should simulate this
1173 //if (size == 22276) trapbug();
1174 z
=my_mreq((size
+ 0xfff) & 0x7ffff000, (flags
& HEAP_ZERO_MEMORY
));
1176 printf("HeapAlloc failure\n");
1177 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap
, flags
, size
, z
);
1178 heapfreehack
= 0; // reset
1181 static long WINAPI
expHeapDestroy(void* heap
)
1183 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap
);
1188 static long WINAPI
expHeapFree(HANDLE heap
, DWORD dwFlags
, LPVOID lpMem
)
1190 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap
, dwFlags
, lpMem
);
1191 if (heapfreehack
!= lpMem
&& lpMem
!= (void*)0xffffffff
1192 && lpMem
!= (void*)0xbdbdbdbd)
1193 // 0xbdbdbdbd is for i263_drv.drv && libefence
1194 // it seems to be reading from relased memory
1195 // EF_PROTECT_FREE doens't show any probleme
1199 if (!heapfreehackshown
++)
1200 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem
);
1202 heapfreehack
= lpMem
;
1205 static long WINAPI
expHeapSize(int heap
, int flags
, void* pointer
)
1207 long result
=my_size(pointer
);
1208 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap
, flags
, pointer
, result
);
1211 static void* WINAPI
expHeapReAlloc(HANDLE heap
,int flags
,void *lpMem
,int size
)
1213 long orgsize
= my_size(lpMem
);
1214 dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize
,size
);
1215 return my_realloc(lpMem
, size
);
1217 static long WINAPI
expGetProcessHeap(void)
1219 dbgprintf("GetProcessHeap() => 1\n");
1222 static void* WINAPI
expVirtualAlloc(void* v1
, long v2
, long v3
, long v4
)
1224 void* z
= VirtualAlloc(v1
, v2
, v3
, v4
);
1226 printf("VirtualAlloc failure\n");
1227 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1
,v2
,v3
,v4
, z
);
1230 static int WINAPI
expVirtualFree(void* v1
, int v2
, int v3
)
1232 int result
= VirtualFree(v1
,v2
,v3
);
1233 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1
,v2
,v3
, result
);
1237 /* we're building a table of critical sections. cs_win pointer uses the DLL
1238 cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1239 struct critsecs_list_t
1241 CRITICAL_SECTION
*cs_win
;
1242 struct CRITSECT
*cs_unix
;
1245 /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1246 #undef CRITSECS_NEWTYPE
1247 //#define CRITSECS_NEWTYPE 1
1249 #ifdef CRITSECS_NEWTYPE
1250 /* increased due to ucod needs more than 32 entries */
1251 /* and 64 should be enough for everything */
1252 #define CRITSECS_LIST_MAX 64
1253 static struct critsecs_list_t critsecs_list
[CRITSECS_LIST_MAX
];
1255 static int critsecs_get_pos(CRITICAL_SECTION
*cs_win
)
1259 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1260 if (critsecs_list
[i
].cs_win
== cs_win
)
1265 static int critsecs_get_unused(void)
1269 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1270 if (critsecs_list
[i
].cs_win
== NULL
)
1275 struct CRITSECT
*critsecs_get_unix(CRITICAL_SECTION
*cs_win
)
1279 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1280 if (critsecs_list
[i
].cs_win
== cs_win
&& critsecs_list
[i
].cs_unix
)
1281 return critsecs_list
[i
].cs_unix
;
1286 static void WINAPI
expInitializeCriticalSection(CRITICAL_SECTION
* c
)
1288 dbgprintf("InitializeCriticalSection(0x%x)\n", c
);
1289 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1291 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1292 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1295 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1296 #ifdef CRITSECS_NEWTYPE
1298 struct CRITSECT
*cs
;
1299 int i
= critsecs_get_unused();
1303 printf("InitializeCriticalSection(%p) - no more space in list\n", c
);
1306 dbgprintf("got unused space at %d\n", i
);
1307 cs
= malloc(sizeof(struct CRITSECT
));
1310 printf("InitializeCriticalSection(%p) - out of memory\n", c
);
1313 pthread_mutex_init(&cs
->mutex
, NULL
);
1315 critsecs_list
[i
].cs_win
= c
;
1316 critsecs_list
[i
].cs_unix
= cs
;
1317 dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1322 struct CRITSECT
* cs
= mreq_private(sizeof(struct CRITSECT
) + sizeof(CRITICAL_SECTION
),
1323 0, AREATYPE_CRITSECT
);
1324 pthread_mutex_init(&cs
->mutex
, NULL
);
1326 cs
->deadbeef
= 0xdeadbeef;
1333 static void WINAPI
expEnterCriticalSection(CRITICAL_SECTION
* c
)
1335 #ifdef CRITSECS_NEWTYPE
1336 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1338 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1340 dbgprintf("EnterCriticalSection(0x%x) %p\n",c
, cs
);
1343 dbgprintf("entered uninitialized critisec!\n");
1344 expInitializeCriticalSection(c
);
1345 #ifdef CRITSECS_NEWTYPE
1346 cs
=critsecs_get_unix(c
);
1348 cs
= (*(struct CRITSECT
**)c
);
1350 dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c
);
1353 if(cs
->id
==pthread_self())
1355 pthread_mutex_lock(&(cs
->mutex
));
1357 cs
->id
=pthread_self();
1360 static void WINAPI
expLeaveCriticalSection(CRITICAL_SECTION
* c
)
1362 #ifdef CRITSECS_NEWTYPE
1363 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1365 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1367 // struct CRITSECT* cs=(struct CRITSECT*)c;
1368 dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c
, cs
);
1371 dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c
);
1377 pthread_mutex_unlock(&(cs
->mutex
));
1380 dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c
);
1384 static void expfree(void* mem
); /* forward declaration */
1386 static void WINAPI
expDeleteCriticalSection(CRITICAL_SECTION
*c
)
1388 #ifdef CRITSECS_NEWTYPE
1389 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1391 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1393 // struct CRITSECT* cs=(struct CRITSECT*)c;
1394 dbgprintf("DeleteCriticalSection(0x%x)\n",c
);
1398 dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c
);
1404 dbgprintf("Win32 Warning: Deleting unlocked Critical Section %p!!\n", c
);
1405 pthread_mutex_unlock(&(cs
->mutex
));
1409 pthread_mutex_destroy(&(cs
->mutex
));
1410 // released by GarbageCollector in my_relase otherwise
1413 #ifdef CRITSECS_NEWTYPE
1415 int i
= critsecs_get_pos(c
);
1419 printf("DeleteCriticalSection(%p) error (critsec not found)\n", c
);
1423 critsecs_list
[i
].cs_win
= NULL
;
1424 expfree(critsecs_list
[i
].cs_unix
);
1425 critsecs_list
[i
].cs_unix
= NULL
;
1426 dbgprintf("DeleteCriticalSection -> itemno=%d\n", i
);
1431 static int WINAPI
expGetCurrentThreadId()
1433 dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1434 return pthread_self();
1436 static int WINAPI
expGetCurrentProcess()
1438 dbgprintf("GetCurrentProcess() => %d\n", getpid());
1443 // this version is required for Quicktime codecs (.qtx/.qts) to work.
1444 // (they assume some pointers at FS: segment)
1446 extern void* fs_seg
;
1448 //static int tls_count;
1449 static int tls_use_map
[64];
1450 static int WINAPI
expTlsAlloc()
1454 if(tls_use_map
[i
]==0)
1457 dbgprintf("TlsAlloc() => %d\n",i
);
1460 dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1464 //static int WINAPI expTlsSetValue(DWORD index, void* value)
1465 static int WINAPI
expTlsSetValue(int index
, void* value
)
1467 dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index
,value
);
1468 // if((index<0) || (index>64))
1471 *(void**)((char*)fs_seg
+0x88+4*index
) = value
;
1475 static void* WINAPI
expTlsGetValue(DWORD index
)
1477 dbgprintf("TlsGetValue(%d)\n",index
);
1478 // if((index<0) || (index>64))
1479 if((index
>=64)) return NULL
;
1480 return *(void**)((char*)fs_seg
+0x88+4*index
);
1483 static int WINAPI
expTlsFree(int idx
)
1485 int index
= (int) idx
;
1486 dbgprintf("TlsFree(%d)\n",index
);
1487 if((index
<0) || (index
>64))
1489 tls_use_map
[index
]=0;
1501 static void* WINAPI
expTlsAlloc()
1505 g_tls
=my_mreq(sizeof(tls_t
), 0);
1506 g_tls
->next
=g_tls
->prev
=NULL
;
1510 g_tls
->next
=my_mreq(sizeof(tls_t
), 0);
1511 g_tls
->next
->prev
=g_tls
;
1512 g_tls
->next
->next
=NULL
;
1515 dbgprintf("TlsAlloc() => 0x%x\n", g_tls
);
1517 g_tls
->value
=0; /* XXX For Divx.dll */
1521 static int WINAPI
expTlsSetValue(void* idx
, void* value
)
1523 tls_t
* index
= (tls_t
*) idx
;
1532 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index
, value
, result
);
1535 static void* WINAPI
expTlsGetValue(void* idx
)
1537 tls_t
* index
= (tls_t
*) idx
;
1542 result
=index
->value
;
1543 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index
, result
);
1546 static int WINAPI
expTlsFree(void* idx
)
1548 tls_t
* index
= (tls_t
*) idx
;
1555 index
->next
->prev
=index
->prev
;
1557 index
->prev
->next
=index
->next
;
1559 g_tls
= index
->prev
;
1560 my_release((void*)index
);
1563 dbgprintf("TlsFree(index 0x%x) => %d\n", index
, result
);
1568 static void* WINAPI
expLocalAlloc(int flags
, int size
)
1570 void* z
= my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1572 printf("LocalAlloc() failed\n");
1573 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1577 static void* WINAPI
expLocalReAlloc(int handle
,int size
, int flags
)
1583 if (flags
& LMEM_MODIFY
) {
1584 dbgprintf("LocalReAlloc MODIFY\n");
1585 return (void *)handle
;
1587 oldsize
= my_size((void *)handle
);
1588 newpointer
= my_realloc((void *)handle
,size
);
1589 dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle
,size
,oldsize
, flags
,newpointer
);
1594 static void* WINAPI
expLocalLock(void* z
)
1596 dbgprintf("LocalLock(0x%x) => 0x%x\n", z
, z
);
1600 static void* WINAPI
expGlobalAlloc(int flags
, int size
)
1603 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size
, flags
);
1605 z
=my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1606 //z=calloc(size, 1);
1609 printf("GlobalAlloc() failed\n");
1610 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1613 static void* WINAPI
expGlobalLock(void* z
)
1615 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z
, z
);
1618 // pvmjpg20 - but doesn't work anyway
1619 static int WINAPI
expGlobalSize(void* amem
)
1623 alloc_header
* header
= last_alloc
;
1624 alloc_header
* mem
= (alloc_header
*) amem
- 1;
1627 pthread_mutex_lock(&memmut
);
1630 if (header
->deadbeef
!= 0xdeadbeef)
1632 dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
1638 size
= header
->size
;
1642 header
= header
->prev
;
1644 pthread_mutex_unlock(&memmut
);
1647 dbgprintf("GlobalSize(0x%x)\n", amem
);
1651 static int WINAPI
expLoadIconA( long hinstance
, char *name
)
1653 dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance
,name
);
1657 static int WINAPI
expLoadStringA(long instance
, long id
, void* buf
, long size
)
1659 int result
=LoadStringA(instance
, id
, buf
, size
);
1661 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1662 instance
, id
, buf
, size
, result
, buf
);
1664 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1665 // instance, id, buf, size, result);
1669 static long WINAPI
expMultiByteToWideChar(long v1
, long v2
, char* s1
, long siz1
, short* s2
, int siz2
)
1678 if(siz1
>siz2
/2)siz1
=siz2
/2;
1679 for(i
=1; i
<=siz1
; i
++)
1689 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1690 "size %d, dest buffer 0x%x, dest size %d) => %d\n",
1691 v1
, v2
, s1
, s1
, siz1
, s2
, siz2
, result
);
1693 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1694 "size %d, dest buffer 0x%x, dest size %d) =>\n",
1695 v1
, v2
, siz1
, s2
, siz2
, result
);
1698 static void wch_print(const short* str
)
1700 dbgprintf(" src: ");
1701 while(*str
)dbgprintf("%c", *str
++);
1704 static long WINAPI
expWideCharToMultiByte(long v1
, long v2
, short* s1
, long siz1
,
1705 char* s2
, int siz2
, char* c3
, int* siz3
)
1708 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1709 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1710 result
=WideCharToMultiByte(v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1711 dbgprintf("=> %d\n", result
);
1712 //if(s1)wch_print(s1);
1713 if(s2
)dbgprintf(" dest: %s\n", s2
);
1716 static long WINAPI
expGetVersionExA(OSVERSIONINFOA
* c
)
1718 dbgprintf("GetVersionExA(0x%x) => 1\n");
1719 c
->dwOSVersionInfoSize
=sizeof(*c
);
1720 c
->dwMajorVersion
=4;
1721 c
->dwMinorVersion
=0;
1722 c
->dwBuildNumber
=0x4000457;
1724 // leave it here for testing win9x-only codecs
1725 c
->dwPlatformId
=VER_PLATFORM_WIN32_WINDOWS
;
1726 strcpy(c
->szCSDVersion
, " B");
1728 c
->dwPlatformId
=VER_PLATFORM_WIN32_NT
; // let's not make DLL assume that it can read CR* registers
1729 strcpy(c
->szCSDVersion
, "Service Pack 3");
1731 dbgprintf(" Major version: 4\n Minor version: 0\n Build number: 0x4000457\n"
1732 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 3'\n");
1735 static HANDLE WINAPI
expCreateSemaphoreA(char* v1
, long init_count
,
1736 long max_count
, char* name
)
1738 pthread_mutex_t
*pm
;
1742 printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1746 printf("%p => ", pp);
1753 mutex_list
* pp
=mlist
;
1757 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==1))
1759 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1760 v1
, init_count
, max_count
, name
, name
, mlist
);
1761 return (HANDLE
)mlist
;
1763 }while((pp
=pp
->prev
) != NULL
);
1765 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
1766 pthread_mutex_init(pm
, NULL
);
1767 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
1768 pthread_cond_init(pc
, NULL
);
1771 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1772 mlist
->next
=mlist
->prev
=NULL
;
1776 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1777 mlist
->next
->prev
=mlist
;
1778 mlist
->next
->next
=NULL
;
1780 // printf("new semaphore %p\n", mlist);
1782 mlist
->type
=1; /* Type Semaphore */
1787 mlist
->semaphore
=init_count
;
1789 strncpy(mlist
->name
, name
, 64);
1793 dbgprintf("ERROR::: CreateSemaphoreA failure\n");
1795 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1796 v1
, init_count
, max_count
, name
, name
, mlist
);
1798 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1799 v1
, init_count
, max_count
, mlist
);
1800 return (HANDLE
)mlist
;
1803 static long WINAPI
expReleaseSemaphore(long hsem
, long increment
, long* prev_count
)
1805 // The state of a semaphore object is signaled when its count
1806 // is greater than zero and nonsignaled when its count is equal to zero
1807 // Each time a waiting thread is released because of the semaphore's signaled
1808 // state, the count of the semaphore is decreased by one.
1809 mutex_list
*ml
= (mutex_list
*)hsem
;
1811 pthread_mutex_lock(ml
->pm
);
1812 if (prev_count
!= 0) *prev_count
= ml
->semaphore
;
1813 if (ml
->semaphore
== 0) pthread_cond_signal(ml
->pc
);
1814 ml
->semaphore
+= increment
;
1815 pthread_mutex_unlock(ml
->pm
);
1816 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1817 hsem
, increment
, prev_count
);
1822 static long WINAPI
expRegOpenKeyExA(long key
, const char* subkey
, long reserved
, long access
, int* newkey
)
1824 long result
=RegOpenKeyExA(key
, subkey
, reserved
, access
, newkey
);
1825 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
1826 key
, subkey
, reserved
, access
, newkey
, result
);
1827 if(newkey
)dbgprintf(" New key: 0x%x\n", *newkey
);
1830 static long WINAPI
expRegCloseKey(long key
)
1832 long result
=RegCloseKey(key
);
1833 dbgprintf("RegCloseKey(0x%x) => %d\n", key
, result
);
1836 static long WINAPI
expRegQueryValueExA(long key
, const char* value
, int* reserved
, int* type
, int* data
, int* count
)
1838 long result
=RegQueryValueExA(key
, value
, reserved
, type
, data
, count
);
1839 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
1840 " => 0x%x\n", key
, value
, reserved
, data
, count
, result
);
1841 if(data
&& count
)dbgprintf(" read %d bytes: '%s'\n", *count
, data
);
1845 //from wine source dlls/advapi32/registry.c
1846 static long WINAPI
expRegCreateKeyA(long hkey
, const char* name
, int *retkey
)
1848 dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey
,name
,retkey
);
1849 return RegCreateKeyExA( hkey
, name
, 0, NULL
,REG_OPTION_NON_VOLATILE
,
1850 KEY_ALL_ACCESS
, NULL
, retkey
, NULL
);
1853 static long WINAPI
expRegCreateKeyExA(long key
, const char* name
, long reserved
,
1854 void* classs
, long options
, long security
,
1855 void* sec_attr
, int* newkey
, int* status
)
1857 long result
=RegCreateKeyExA(key
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
);
1858 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
1859 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
1860 key
, name
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
, result
);
1861 if(!result
&& newkey
) dbgprintf(" New key: 0x%x\n", *newkey
);
1862 if(!result
&& status
) dbgprintf(" New key status: 0x%x\n", *status
);
1865 static long WINAPI
expRegSetValueExA(long key
, const char* name
, long v1
, long v2
, void* data
, long size
)
1867 long result
=RegSetValueExA(key
, name
, v1
, v2
, data
, size
);
1868 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
1869 key
, name
, v1
, v2
, data
, *(int*)data
, data
, size
, result
);
1873 static long WINAPI
expRegOpenKeyA (long hKey
, LPCSTR lpSubKey
, int* phkResult
)
1875 long result
=RegOpenKeyExA(hKey
, lpSubKey
, 0, 0, phkResult
);
1876 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
1877 hKey
, lpSubKey
, phkResult
, result
);
1878 if(!result
&& phkResult
) dbgprintf(" New key: 0x%x\n", *phkResult
);
1882 static DWORD WINAPI
expRegEnumValueA(HKEY hkey
, DWORD index
, LPSTR value
, LPDWORD val_count
,
1883 LPDWORD reserved
, LPDWORD type
, LPBYTE data
, LPDWORD count
)
1885 return RegEnumValueA(hkey
, index
, value
, val_count
,
1886 reserved
, type
, data
, count
);
1889 static DWORD WINAPI
expRegEnumKeyExA(HKEY hKey
, DWORD dwIndex
, LPSTR lpName
, LPDWORD lpcbName
,
1890 LPDWORD lpReserved
, LPSTR lpClass
, LPDWORD lpcbClass
,
1891 LPFILETIME lpftLastWriteTime
)
1893 return RegEnumKeyExA(hKey
, dwIndex
, lpName
, lpcbName
, lpReserved
, lpClass
,
1894 lpcbClass
, lpftLastWriteTime
);
1897 static long WINAPI
expQueryPerformanceCounter(long long* z
)
1900 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z
, *z
);
1905 * dummy function RegQueryInfoKeyA(), required by vss codecs
1907 static DWORD WINAPI
expRegQueryInfoKeyA( HKEY hkey
, LPSTR
class, LPDWORD class_len
, LPDWORD reserved
,
1908 LPDWORD subkeys
, LPDWORD max_subkey
, LPDWORD max_class
,
1909 LPDWORD values
, LPDWORD max_value
, LPDWORD max_data
,
1910 LPDWORD security
, FILETIME
*modif
)
1912 return ERROR_SUCCESS
;
1916 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
1918 static double linux_cpuinfo_freq()
1925 f
= fopen ("/proc/cpuinfo", "r");
1927 while (fgets(line
,sizeof(line
),f
)!=NULL
) {
1928 /* NOTE: the ':' is the only character we can rely on */
1929 if (!(value
= strchr(line
,':')))
1931 /* terminate the valuename */
1933 /* skip any leading spaces */
1934 while (*value
==' ') value
++;
1935 if ((s
=strchr(value
,'\n')))
1938 if (!strncasecmp(line
, "cpu MHz",strlen("cpu MHz"))
1939 && sscanf(value
, "%lf", &freq
) == 1) {
1950 static double solaris_kstat_freq()
1952 #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
1954 * try to extract the CPU speed from the solaris kernel's kstat data
1958 kstat_named_t
*kdata
;
1964 ksp
= kstat_lookup(kc
, "cpu_info", 0, "cpu_info0");
1966 /* kstat found and name/value pairs? */
1967 if (ksp
!= NULL
&& ksp
->ks_type
== KSTAT_TYPE_NAMED
)
1969 /* read the kstat data from the kernel */
1970 if (kstat_read(kc
, ksp
, NULL
) != -1)
1973 * lookup desired "clock_MHz" entry, check the expected
1976 kdata
= (kstat_named_t
*)kstat_data_lookup(ksp
, "clock_MHz");
1977 if (kdata
!= NULL
&& kdata
->data_type
== KSTAT_DATA_INT32
)
1978 mhz
= kdata
->value
.i32
;
1986 #endif /* HAVE_LIBKSTAT */
1987 return -1; // kstat stuff is not available, CPU freq is unknown
1991 * Measure CPU freq using the pentium's time stamp counter register (TSC)
1993 static double tsc_freq()
1995 static double ofreq
=0.0;
1999 if (ofreq
!= 0.0) return ofreq
;
2000 while(i
==time(NULL
));
2003 while(i
==time(NULL
));
2005 ofreq
= (double)(y
-x
)/1000.;
2009 static double CPU_Freq()
2013 if ((freq
= linux_cpuinfo_freq()) > 0)
2016 if ((freq
= solaris_kstat_freq()) > 0)
2022 static long WINAPI
expQueryPerformanceFrequency(long long* z
)
2024 *z
=(long long)CPU_Freq();
2025 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z
, *z
);
2028 static long WINAPI
exptimeGetTime()
2032 gettimeofday(&t
, 0);
2033 result
=1000*t
.tv_sec
+t
.tv_usec
/1000;
2034 dbgprintf("timeGetTime() => %d\n", result
);
2037 static void* WINAPI
expLocalHandle(void* v
)
2039 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v
, v
);
2043 static void* WINAPI
expGlobalHandle(void* v
)
2045 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v
, v
);
2048 static int WINAPI
expGlobalUnlock(void* v
)
2050 dbgprintf("GlobalUnlock(0x%x) => 1\n", v
);
2053 static void* WINAPI
expGlobalFree(void* v
)
2055 dbgprintf("GlobalFree(0x%x) => 0\n", v
);
2061 static void* WINAPI
expGlobalReAlloc(void* v
, int size
, int flags
)
2063 void* result
=my_realloc(v
, size
);
2064 //void* result=realloc(v, size);
2065 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v
,size
,flags
,result
);
2069 static int WINAPI
expLocalUnlock(void* v
)
2071 dbgprintf("LocalUnlock(0x%x) => 1\n", v
);
2075 static void* WINAPI
expLocalFree(void* v
)
2077 dbgprintf("LocalFree(0x%x) => 0\n", v
);
2081 static HRSRC WINAPI
expFindResourceA(HMODULE module
, char* name
, char* type
)
2085 result
=FindResourceA(module
, name
, type
);
2086 dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2087 module
, name
, HIWORD(name
) ? name
: "UNICODE", type
, HIWORD(type
) ? type
: "UNICODE", result
);
2091 static HGLOBAL WINAPI
expLoadResource(HMODULE module
, HRSRC res
)
2093 HGLOBAL result
=LoadResource(module
, res
);
2094 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module
, res
, result
);
2097 static void* WINAPI
expLockResource(long res
)
2099 void* result
=LockResource(res
);
2100 dbgprintf("LockResource(0x%x) => 0x%x\n", res
, result
);
2103 static int WINAPI
expFreeResource(long res
)
2105 int result
=FreeResource(res
);
2106 dbgprintf("FreeResource(0x%x) => %d\n", res
, result
);
2111 static int WINAPI
expCloseHandle(long v1
)
2113 dbgprintf("CloseHandle(0x%x) => 1\n", v1
);
2114 /* do not close stdin,stdout and stderr */
2121 static const char* WINAPI
expGetCommandLineA()
2123 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2124 return "c:\\aviplay.exe";
2126 static short envs
[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2127 static LPWSTR WINAPI
expGetEnvironmentStringsW()
2129 dbgprintf("GetEnvironmentStringsW() => 0\n", envs
);
2132 static void * WINAPI
expRtlZeroMemory(void *p
, size_t len
)
2134 void* result
=memset(p
,0,len
);
2135 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p
,len
,result
);
2138 static void * WINAPI
expRtlMoveMemory(void *dst
, void *src
, size_t len
)
2140 void* result
=memmove(dst
,src
,len
);
2141 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst
,src
,len
,result
);
2145 static void * WINAPI
expRtlFillMemory(void *p
, int ch
, size_t len
)
2147 void* result
=memset(p
,ch
,len
);
2148 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p
,ch
,len
,result
);
2151 static int WINAPI
expFreeEnvironmentStringsW(short* strings
)
2153 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings
);
2156 static int WINAPI
expFreeEnvironmentStringsA(char* strings
)
2158 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings
);
2162 static const char ch_envs
[]=
2163 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2164 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2165 static LPCSTR WINAPI
expGetEnvironmentStrings()
2167 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs
);
2168 return (LPCSTR
)ch_envs
;
2169 // dbgprintf("GetEnvironmentStrings() => 0\n");
2173 static int WINAPI
expGetStartupInfoA(STARTUPINFOA
*s
)
2175 dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2176 memset(s
, 0, sizeof(*s
));
2178 // s->lpReserved="Reserved";
2179 // s->lpDesktop="Desktop";
2180 // s->lpTitle="Title";
2182 // s->dwXSize=s->dwYSize=200;
2183 s
->dwFlags
=s
->wShowWindow
=1;
2184 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2185 dbgprintf(" cb=%d\n", s
->cb
);
2186 dbgprintf(" lpReserved='%s'\n", s
->lpReserved
);
2187 dbgprintf(" lpDesktop='%s'\n", s
->lpDesktop
);
2188 dbgprintf(" lpTitle='%s'\n", s
->lpTitle
);
2189 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2190 s
->dwX
, s
->dwY
, s
->dwXSize
, s
->dwYSize
);
2191 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2192 s
->dwXCountChars
, s
->dwYCountChars
, s
->dwFillAttribute
);
2193 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2194 s
->dwFlags
, s
->wShowWindow
, s
->cbReserved2
);
2195 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2196 s
->lpReserved2
, s
->hStdInput
, s
->hStdOutput
, s
->hStdError
);
2200 static int WINAPI
expGetStdHandle(int z
)
2202 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z
+0x1234);
2207 #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2208 #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2211 static int WINAPI
expGetFileType(int handle
)
2213 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle
);
2217 static int WINAPI
expGetFileAttributesA(char *filename
)
2219 dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename
);
2220 if (strstr(filename
, "QuickTime.qts"))
2221 return FILE_ATTRIBUTE_SYSTEM
;
2222 return FILE_ATTRIBUTE_NORMAL
;
2225 static int WINAPI
expSetHandleCount(int count
)
2227 dbgprintf("SetHandleCount(0x%x) => 1\n", count
);
2230 static int WINAPI
expGetACP(void)
2232 dbgprintf("GetACP() => 0\n");
2235 static int WINAPI
expGetModuleFileNameA(int module
, char* s
, int len
)
2239 //printf("File name of module %X (%s) requested\n", module, s);
2241 if (module
== 0 && len
>= 12)
2243 /* return caller program name */
2244 strcpy(s
, "aviplay.dll");
2255 strcpy(s
, "c:\\windows\\system\\");
2256 mr
=MODULE32_LookupHMODULE(module
);
2258 strcat(s
, "aviplay.dll");
2260 if(strrchr(mr
->filename
, '/')==NULL
)
2261 strcat(s
, mr
->filename
);
2263 strcat(s
, strrchr(mr
->filename
, '/')+1);
2266 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2267 module
, s
, len
, result
);
2269 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2270 module
, s
, len
, result
, s
);
2274 static int WINAPI
expSetUnhandledExceptionFilter(void* filter
)
2276 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter
);
2277 return 1;//unsupported and probably won't ever be supported
2280 static int WINAPI
expLoadLibraryA(char* name
)
2286 // we skip to the last backslash
2287 // this is effectively eliminating weird characters in
2288 // the text output windows
2290 lastbc
= strrchr(name
, '\\');
2297 name
[i
] = *lastbc
++;
2302 if(strncmp(name
, "c:\\windows\\", 11)==0) name
+= 11;
2303 if(strncmp(name
, ".\\", 2)==0) name
+= 2;
2305 dbgprintf("Entering LoadLibraryA(%s)\n", name
);
2307 // PIMJ and VIVO audio are loading kernel32.dll
2308 if (strcasecmp(name
, "kernel32.dll") == 0 || strcasecmp(name
, "kernel32") == 0)
2309 return MODULE_HANDLE_kernel32
;
2310 // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2311 /* exported -> do not return failed! */
2313 if (strcasecmp(name
, "user32.dll") == 0 || strcasecmp(name
, "user32") == 0)
2314 // return MODULE_HANDLE_kernel32;
2315 return MODULE_HANDLE_user32
;
2318 if (strcasecmp(name
, "wininet.dll") == 0 || strcasecmp(name
, "wininet") == 0)
2319 return MODULE_HANDLE_wininet
;
2320 if (strcasecmp(name
, "ddraw.dll") == 0 || strcasecmp(name
, "ddraw") == 0)
2321 return MODULE_HANDLE_ddraw
;
2322 if (strcasecmp(name
, "advapi32.dll") == 0 || strcasecmp(name
, "advapi32") == 0)
2323 return MODULE_HANDLE_advapi32
;
2326 if (strcasecmp(name
, "comdlg32.dll") == 0 || strcasecmp(name
, "comdlg32") == 0)
2327 return MODULE_HANDLE_comdlg32
;
2328 if (strcasecmp(name
, "msvcrt.dll") == 0 || strcasecmp(name
, "msvcrt") == 0)
2329 return MODULE_HANDLE_msvcrt
;
2330 if (strcasecmp(name
, "ole32.dll") == 0 || strcasecmp(name
, "ole32") == 0)
2331 return MODULE_HANDLE_ole32
;
2332 if (strcasecmp(name
, "winmm.dll") == 0 || strcasecmp(name
, "winmm") == 0)
2333 return MODULE_HANDLE_winmm
;
2335 result
=LoadLibraryA(name
);
2336 dbgprintf("Returned LoadLibraryA(0x%x='%s'), def_path=%s => 0x%x\n", name
, name
, def_path
, result
);
2341 static int WINAPI
expFreeLibrary(int module
)
2344 int result
=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2346 int result
=FreeLibrary(module
);
2348 dbgprintf("FreeLibrary(0x%x) => %d\n", module
, result
);
2352 static void* WINAPI
expGetProcAddress(HMODULE mod
, char* name
)
2356 case MODULE_HANDLE_kernel32
:
2357 result
=LookupExternalByName("kernel32.dll", name
); break;
2358 case MODULE_HANDLE_user32
:
2359 result
=LookupExternalByName("user32.dll", name
); break;
2361 case MODULE_HANDLE_wininet
:
2362 result
=LookupExternalByName("wininet.dll", name
); break;
2363 case MODULE_HANDLE_ddraw
:
2364 result
=LookupExternalByName("ddraw.dll", name
); break;
2365 case MODULE_HANDLE_advapi32
:
2366 result
=LookupExternalByName("advapi32.dll", name
); break;
2368 case MODULE_HANDLE_comdlg32
:
2369 result
=LookupExternalByName("comdlg32.dll", name
); break;
2370 case MODULE_HANDLE_msvcrt
:
2371 result
=LookupExternalByName("msvcrt.dll", name
); break;
2372 case MODULE_HANDLE_ole32
:
2373 result
=LookupExternalByName("ole32.dll", name
); break;
2374 case MODULE_HANDLE_winmm
:
2375 result
=LookupExternalByName("winmm.dll", name
); break;
2377 result
=GetProcAddress(mod
, name
);
2379 if((unsigned int)name
> 0xffff)
2380 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod
, name
, result
);
2382 dbgprintf("GetProcAddress(0x%x, '%d') => 0x%x\n", mod
, (int)name
, result
);
2386 static long WINAPI
expCreateFileMappingA(int hFile
, void* lpAttr
,
2387 long flProtect
, long dwMaxHigh
,
2388 long dwMaxLow
, const char* name
)
2390 long result
=CreateFileMappingA(hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
);
2392 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2393 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2394 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, result
);
2396 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2397 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2398 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
, name
, result
);
2402 static long WINAPI
expOpenFileMappingA(long hFile
, long hz
, const char* name
)
2404 long result
=OpenFileMappingA(hFile
, hz
, name
);
2406 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2409 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2410 hFile
, hz
, name
, name
, result
);
2414 static void* WINAPI
expMapViewOfFile(HANDLE file
, DWORD mode
, DWORD offHigh
,
2415 DWORD offLow
, DWORD size
)
2417 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2418 file
,mode
,offHigh
,offLow
,size
,(char*)file
+offLow
);
2419 return (char*)file
+offLow
;
2422 static void* WINAPI
expUnmapViewOfFile(void* view
)
2424 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view
);
2428 static void* WINAPI
expSleep(int time
)
2431 /* solaris doesn't have thread safe usleep */
2432 struct timespec tsp
;
2433 tsp
.tv_sec
= time
/ 1000000;
2434 tsp
.tv_nsec
= (time
% 1000000) * 1000;
2435 nanosleep(&tsp
, NULL
);
2439 dbgprintf("Sleep(%d) => 0\n", time
);
2443 // why does IV32 codec want to call this? I don't know ...
2444 static int WINAPI
expCreateCompatibleDC(int hdc
)
2447 //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2448 dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc
, dc
);
2452 static int WINAPI
expGetDeviceCaps(int hdc
, int unk
)
2454 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc
, unk
);
2456 #define BITSPIXEL 12
2458 if (unk
== BITSPIXEL
)
2466 static WIN_BOOL WINAPI
expDeleteDC(int hdc
)
2468 dbgprintf("DeleteDC(0x%x) => 0\n", hdc
);
2474 static WIN_BOOL WINAPI
expDeleteObject(int hdc
)
2476 dbgprintf("DeleteObject(0x%x) => 1\n", hdc
);
2477 /* FIXME - implement code here */
2481 /* btvvc32.drv wants this one */
2482 static void* WINAPI
expGetWindowDC(int hdc
)
2484 dbgprintf("GetWindowDC(%d) => 0x0\n", hdc
);
2489 static int WINAPI
expGetWindowRect(HWND win
, RECT
*r
)
2491 dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win
, r
);
2492 /* (win == 0) => desktop */
2493 r
->right
= PSEUDO_SCREEN_WIDTH
;
2495 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
2500 static int WINAPI
expMonitorFromWindow(HWND win
, int flags
)
2502 dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win
, flags
);
2506 static int WINAPI
expMonitorFromRect(RECT
*r
, int flags
)
2508 dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r
, flags
);
2512 static int WINAPI
expMonitorFromPoint(void *p
, int flags
)
2514 dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p
, flags
);
2518 static int WINAPI
expEnumDisplayMonitors(void *dc
, RECT
*r
,
2519 int WINAPI (*callback_proc
)(), void *callback_param
)
2521 dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2522 dc
, r
, callback_proc
, callback_param
);
2523 return callback_proc(0, dc
, r
, callback_param
);
2527 typedef struct tagMONITORINFO
{
2532 } MONITORINFO
, *LPMONITORINFO
;
2535 #define CCHDEVICENAME 8
2536 typedef struct tagMONITORINFOEX
{
2541 TCHAR szDevice
[CCHDEVICENAME
];
2542 } MONITORINFOEX
, *LPMONITORINFOEX
;
2544 static int WINAPI
expGetMonitorInfoA(void *mon
, LPMONITORINFO lpmi
)
2546 dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon
, lpmi
);
2548 lpmi
->rcMonitor
.right
= lpmi
->rcWork
.right
= PSEUDO_SCREEN_WIDTH
;
2549 lpmi
->rcMonitor
.left
= lpmi
->rcWork
.left
= 0;
2550 lpmi
->rcMonitor
.bottom
= lpmi
->rcWork
.bottom
= PSEUDO_SCREEN_HEIGHT
;
2551 lpmi
->rcMonitor
.top
= lpmi
->rcWork
.top
= 0;
2553 lpmi
->dwFlags
= 1; /* primary monitor */
2555 if (lpmi
->cbSize
== sizeof(MONITORINFOEX
))
2557 LPMONITORINFOEX lpmiex
= (LPMONITORINFOEX
)lpmi
;
2558 dbgprintf("MONITORINFOEX!\n");
2559 strncpy(lpmiex
->szDevice
, "Monitor1", CCHDEVICENAME
);
2565 static int WINAPI
expEnumDisplayDevicesA(const char *device
, int devnum
,
2566 void *dispdev
, int flags
)
2568 dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2569 device
, device
, devnum
, dispdev
, flags
);
2573 static int WINAPI
expIsWindowVisible(HWND win
)
2575 dbgprintf("IsWindowVisible(0x%x) => 1\n", win
);
2579 static HWND WINAPI
expGetActiveWindow(void)
2581 dbgprintf("GetActiveWindow() => 0\n");
2585 static int WINAPI
expGetClassNameA(HWND win
, LPTSTR classname
, int maxcount
)
2587 strncat(classname
, "QuickTime", maxcount
);
2588 dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2589 win
, classname
, maxcount
, strlen(classname
));
2590 return strlen(classname
);
2593 #define LPWNDCLASS void *
2594 static int WINAPI
expGetClassInfoA(HINSTANCE inst
, LPCSTR classname
, LPWNDCLASS wndclass
)
2596 dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst
,
2597 classname
, classname
, wndclass
);
2601 static int WINAPI
expGetWindowLongA(HWND win
, int index
)
2603 dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win
, index
);
2607 static int WINAPI
expGetObjectA(HGDIOBJ hobj
, int objsize
, LPVOID obj
)
2609 dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj
, objsize
, obj
, objsize
);
2613 static int WINAPI
expCreateRectRgn(int x
, int y
, int width
, int height
)
2615 dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x
, y
, width
, height
);
2619 static int WINAPI
expEnumWindows(int (*callback_func
)(), void *callback_param
)
2622 dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func
, callback_param
);
2623 i
= callback_func(0, callback_param
);
2624 i2
= callback_func(1, callback_param
);
2628 static int WINAPI
expGetWindowThreadProcessId(HWND win
, int *pid_data
)
2630 int tid
= pthread_self();
2631 dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2632 win
, pid_data
, tid
);
2634 *(int*)pid_data
= tid
;
2638 //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2639 // INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2641 static HWND WINAPI
expCreateWindowExA(int exstyle
, const char *classname
,
2642 const char *winname
, int style
, int x
, int y
, int w
, int h
,
2643 HWND parent
, HMENU menu
, HINSTANCE inst
, LPVOID param
)
2645 printf("CreateWindowEx() called\n");
2646 dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2647 exstyle
, classname
, classname
, winname
, winname
, style
, x
, y
, w
, h
,
2648 parent
, menu
, inst
, param
);
2649 printf("CreateWindowEx() called okey\n");
2653 static int WINAPI
expwaveOutGetNumDevs(void)
2655 dbgprintf("waveOutGetNumDevs() => 0\n");
2661 * Returns the number of milliseconds, modulo 2^32, since the start
2662 * of the wineserver.
2664 static int WINAPI
expGetTickCount(void)
2666 static int tcstart
= 0;
2669 gettimeofday( &t
, NULL
);
2670 tc
= ((t
.tv_sec
* 1000) + (t
.tv_usec
/ 1000)) - tcstart
;
2676 dbgprintf("GetTickCount() => %d\n", tc
);
2680 static int WINAPI
expCreateFontA(void)
2682 dbgprintf("CreateFontA() => 0x0\n");
2686 /* tried to get pvmjpg work in a different way - no success */
2687 static int WINAPI
expDrawTextA(int hDC
, char* lpString
, int nCount
,
2688 LPRECT lpRect
, unsigned int uFormat
)
2690 dbgprintf("expDrawTextA(%p,...) => 8\n", hDC
);
2694 static int WINAPI
expGetPrivateProfileIntA(const char* appname
,
2695 const char* keyname
,
2697 const char* filename
)
2705 if(!(appname
&& keyname
&& filename
) )
2707 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, default_value
);
2708 return default_value
;
2710 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2711 strcpy(fullname
, "Software\\IniFileMapping\\");
2712 strcat(fullname
, appname
);
2713 strcat(fullname
, "\\");
2714 strcat(fullname
, keyname
);
2715 strcat(fullname
, "\\");
2716 strcat(fullname
, filename
);
2717 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)buffer
, &size
);
2718 if((size
>=0)&&(size
<256))
2720 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2723 result
=default_value
;
2725 result
=atoi(buffer
);
2726 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, result
);
2729 static int WINAPI
expGetProfileIntA(const char* appname
,
2730 const char* keyname
,
2733 dbgprintf("GetProfileIntA -> ");
2734 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, "default");
2737 static int WINAPI
expGetPrivateProfileStringA(const char* appname
,
2738 const char* keyname
,
2739 const char* def_val
,
2740 char* dest
, unsigned int len
,
2741 const char* filename
)
2746 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname
, keyname
, def_val
, dest
, len
, filename
);
2747 if(!(appname
&& keyname
&& filename
) ) return 0;
2748 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2749 strcpy(fullname
, "Software\\IniFileMapping\\");
2750 strcat(fullname
, appname
);
2751 strcat(fullname
, "\\");
2752 strcat(fullname
, keyname
);
2753 strcat(fullname
, "\\");
2754 strcat(fullname
, filename
);
2756 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)dest
, &size
);
2760 strncpy(dest
, def_val
, size
);
2761 if (strlen(def_val
)< size
) size
= strlen(def_val
);
2763 dbgprintf(" => %d ( '%s' )\n", size
, dest
);
2766 static int WINAPI
expWritePrivateProfileStringA(const char* appname
,
2767 const char* keyname
,
2769 const char* filename
)
2772 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname
, keyname
, string
, filename
);
2773 if(!(appname
&& keyname
&& filename
) )
2775 dbgprintf(" => -1\n");
2778 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2779 strcpy(fullname
, "Software\\IniFileMapping\\");
2780 strcat(fullname
, appname
);
2781 strcat(fullname
, "\\");
2782 strcat(fullname
, keyname
);
2783 strcat(fullname
, "\\");
2784 strcat(fullname
, filename
);
2785 RegSetValueExA(HKEY_LOCAL_MACHINE
, fullname
, 0, REG_SZ
, (int*)string
, strlen(string
));
2786 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
2787 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
2789 dbgprintf(" => 0\n");
2793 unsigned int GetPrivateProfileIntA_(const char* appname
, const char* keyname
, INT default_value
, const char* filename
)
2795 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, filename
);
2797 int GetPrivateProfileStringA_(const char* appname
, const char* keyname
,
2798 const char* def_val
, char* dest
, unsigned int len
, const char* filename
)
2800 return expGetPrivateProfileStringA(appname
, keyname
, def_val
, dest
, len
, filename
);
2802 int WritePrivateProfileStringA_(const char* appname
, const char* keyname
,
2803 const char* string
, const char* filename
)
2805 return expWritePrivateProfileStringA(appname
, keyname
, string
, filename
);
2810 static int WINAPI
expDefDriverProc(int private, int id
, int msg
, int arg1
, int arg2
)
2812 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", private, id
, msg
, arg1
, arg2
);
2816 static int WINAPI
expSizeofResource(int v1
, int v2
)
2818 int result
=SizeofResource(v1
, v2
);
2819 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1
, v2
, result
);
2823 static int WINAPI
expGetLastError()
2825 int result
=GetLastError();
2826 dbgprintf("GetLastError() => 0x%x\n", result
);
2830 static void WINAPI
expSetLastError(int error
)
2832 dbgprintf("SetLastError(0x%x)\n", error
);
2833 SetLastError(error
);
2836 static int WINAPI
expStringFromGUID2(GUID
* guid
, char* str
, int cbMax
)
2838 int result
=snprintf(str
, cbMax
, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
2839 guid
->f1
, guid
->f2
, guid
->f3
,
2840 (unsigned char)guid
->f4
[0], (unsigned char)guid
->f4
[1],
2841 (unsigned char)guid
->f4
[2], (unsigned char)guid
->f4
[3],
2842 (unsigned char)guid
->f4
[4], (unsigned char)guid
->f4
[5],
2843 (unsigned char)guid
->f4
[6], (unsigned char)guid
->f4
[7]);
2844 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid
, str
, str
, cbMax
, result
);
2849 static int WINAPI
expGetFileVersionInfoSizeA(const char* name
, int* lpHandle
)
2851 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name
, name
, lpHandle
);
2855 static int WINAPI
expIsBadStringPtrW(const short* string
, int nchars
)
2858 if(string
==0)result
=1; else result
=0;
2859 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string
, nchars
, result
);
2860 if(string
)wch_print(string
);
2863 static int WINAPI
expIsBadStringPtrA(const char* string
, int nchars
)
2865 return expIsBadStringPtrW((const short*)string
, nchars
);
2867 static long WINAPI
expInterlockedExchangeAdd( long* dest
, long incr
)
2872 "lock; xaddl %0,(%1)"
2874 : "r" (dest
), "0" (incr
)
2880 static long WINAPI
expInterlockedCompareExchange( unsigned long* dest
, unsigned long exchange
, unsigned long comperand
)
2882 unsigned long retval
= *dest
;
2883 if(*dest
== comperand
)
2888 static long WINAPI
expInterlockedIncrement( long* dest
)
2890 long result
=expInterlockedExchangeAdd( dest
, 1 ) + 1;
2891 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
2894 static long WINAPI
expInterlockedDecrement( long* dest
)
2896 long result
=expInterlockedExchangeAdd( dest
, -1 ) - 1;
2897 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
2901 static void WINAPI
expOutputDebugStringA( const char* string
)
2903 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string
);
2904 fprintf(stderr
, "DEBUG: %s\n", string
);
2907 static int WINAPI
expGetDC(int hwnd
)
2909 dbgprintf("GetDC(0x%x) => 1\n", hwnd
);
2913 static int WINAPI
expReleaseDC(int hwnd
, int hdc
)
2915 dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd
, hdc
);
2919 static int WINAPI
expGetDesktopWindow()
2921 dbgprintf("GetDesktopWindow() => 0\n");
2925 static int cursor
[100];
2927 static int WINAPI
expLoadCursorA(int handle
,LPCSTR name
)
2929 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle
, name
, (int)&cursor
[0]);
2930 return (int)&cursor
[0];
2932 static int WINAPI
expSetCursor(void *cursor
)
2934 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor
, cursor
);
2937 static int WINAPI
expGetCursorPos(void *cursor
)
2939 dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor
, cursor
);
2943 static int show_cursor
= 0;
2944 static int WINAPI
expShowCursor(int show
)
2946 dbgprintf("ShowCursor(%d) => %d\n", show
, show
);
2954 static int WINAPI
expRegisterWindowMessageA(char *message
)
2956 dbgprintf("RegisterWindowMessageA(%s)\n", message
);
2959 static int WINAPI
expGetProcessVersion(int pid
)
2961 dbgprintf("GetProcessVersion(%d)\n", pid
);
2964 static int WINAPI
expGetCurrentThread(void)
2967 dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
2970 static int WINAPI
expGetOEMCP(void)
2972 dbgprintf("GetOEMCP()\n");
2975 static int WINAPI
expGetCPInfo(int cp
,void *info
)
2977 dbgprintf("GetCPInfo()\n");
2981 #define SM_CXSCREEN 0
2982 #define SM_CYSCREEN 1
2983 #define SM_XVIRTUALSCREEN 76
2984 #define SM_YVIRTUALSCREEN 77
2985 #define SM_CXVIRTUALSCREEN 78
2986 #define SM_CYVIRTUALSCREEN 79
2987 #define SM_CMONITORS 80
2989 static int WINAPI
expGetSystemMetrics(int index
)
2991 dbgprintf("GetSystemMetrics(%d)\n", index
);
2995 case SM_XVIRTUALSCREEN
:
2996 case SM_YVIRTUALSCREEN
:
2999 case SM_CXVIRTUALSCREEN
:
3000 return PSEUDO_SCREEN_WIDTH
;
3002 case SM_CYVIRTUALSCREEN
:
3003 return PSEUDO_SCREEN_HEIGHT
;
3010 static int WINAPI
expGetSysColor(int index
)
3012 dbgprintf("GetSysColor(%d) => 1\n", index
);
3015 static int WINAPI
expGetSysColorBrush(int index
)
3017 dbgprintf("GetSysColorBrush(%d)\n", index
);
3023 static int WINAPI
expGetSystemPaletteEntries(int hdc
, int iStartIndex
, int nEntries
, void* lppe
)
3025 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3026 hdc
, iStartIndex
, nEntries
, lppe
);
3031 typedef struct TIME_ZONE_INFORMATION {
3033 char StandardName[32];
3034 SYSTEMTIME StandardDate;
3036 char DaylightName[32];
3037 SYSTEMTIME DaylightDate;
3039 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3042 static int WINAPI
expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation
)
3044 const short name
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3045 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3046 const short pname
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3047 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3048 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3049 memset(lpTimeZoneInformation
, 0, sizeof(TIME_ZONE_INFORMATION
));
3050 lpTimeZoneInformation
->Bias
=360;//GMT-6
3051 memcpy(lpTimeZoneInformation
->StandardName
, name
, sizeof(name
));
3052 lpTimeZoneInformation
->StandardDate
.wMonth
=10;
3053 lpTimeZoneInformation
->StandardDate
.wDay
=5;
3054 lpTimeZoneInformation
->StandardDate
.wHour
=2;
3055 lpTimeZoneInformation
->StandardBias
=0;
3056 memcpy(lpTimeZoneInformation
->DaylightName
, pname
, sizeof(pname
));
3057 lpTimeZoneInformation
->DaylightDate
.wMonth
=4;
3058 lpTimeZoneInformation
->DaylightDate
.wDay
=1;
3059 lpTimeZoneInformation
->DaylightDate
.wHour
=2;
3060 lpTimeZoneInformation
->DaylightBias
=-60;
3061 return TIME_ZONE_ID_STANDARD
;
3064 static void WINAPI
expGetLocalTime(SYSTEMTIME
* systime
)
3067 struct tm
*local_tm
;
3070 dbgprintf("GetLocalTime(0x%x)\n");
3071 gettimeofday(&tv
, NULL
);
3072 local_time
=tv
.tv_sec
;
3073 local_tm
=localtime(&local_time
);
3075 systime
->wYear
= local_tm
->tm_year
+ 1900;
3076 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3077 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3078 systime
->wDay
= local_tm
->tm_mday
;
3079 systime
->wHour
= local_tm
->tm_hour
;
3080 systime
->wMinute
= local_tm
->tm_min
;
3081 systime
->wSecond
= local_tm
->tm_sec
;
3082 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3083 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3084 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3085 " Milliseconds: %d\n",
3086 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3087 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3090 static int WINAPI
expGetSystemTime(SYSTEMTIME
* systime
)
3093 struct tm
*local_tm
;
3096 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3097 gettimeofday(&tv
, NULL
);
3098 local_time
=tv
.tv_sec
;
3099 local_tm
=gmtime(&local_time
);
3101 systime
->wYear
= local_tm
->tm_year
+ 1900;
3102 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3103 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3104 systime
->wDay
= local_tm
->tm_mday
;
3105 systime
->wHour
= local_tm
->tm_hour
;
3106 systime
->wMinute
= local_tm
->tm_min
;
3107 systime
->wSecond
= local_tm
->tm_sec
;
3108 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3109 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3110 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3111 " Milliseconds: %d\n",
3112 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3113 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3117 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3118 static void WINAPI
expGetSystemTimeAsFileTime(FILETIME
* systime
)
3121 unsigned long long secs
;
3123 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3124 gettimeofday(&tv
, NULL
);
3125 secs
= (tv
.tv_sec
+ SECS_1601_TO_1970
) * 10000000;
3126 secs
+= tv
.tv_usec
* 10;
3127 systime
->dwLowDateTime
= secs
& 0xffffffff;
3128 systime
->dwHighDateTime
= (secs
>> 32);
3131 static int WINAPI
expGetEnvironmentVariableA(const char* name
, char* field
, int size
)
3134 // printf("%s %x %x\n", name, field, size);
3135 if(field
)field
[0]=0;
3138 if (p) strncpy(field,p,size);
3140 if (strcmp(name
,"__MSVCRT_HEAP_SELECT")==0)
3141 strcpy(field
,"__GLOBAL_HEAP_SELECTED,1");
3142 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name
, name
, field
, size
, strlen(field
));
3143 return strlen(field
);
3146 static int WINAPI
expSetEnvironmentVariableA(const char *name
, const char *value
)
3148 dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name
, value
);
3152 static void* WINAPI
expCoTaskMemAlloc(ULONG cb
)
3154 return my_mreq(cb
, 0);
3156 static void WINAPI
expCoTaskMemFree(void* cb
)
3164 void* CoTaskMemAlloc(unsigned long cb
)
3166 return expCoTaskMemAlloc(cb
);
3168 void CoTaskMemFree(void* cb
)
3170 expCoTaskMemFree(cb
);
3173 struct COM_OBJECT_INFO
3176 long (*GetClassObject
) (GUID
* clsid
, const GUID
* iid
, void** ppv
);
3179 static struct COM_OBJECT_INFO
* com_object_table
=0;
3180 static int com_object_size
=0;
3181 int RegisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3185 com_object_table
=realloc(com_object_table
, sizeof(struct COM_OBJECT_INFO
)*(++com_object_size
));
3186 com_object_table
[com_object_size
-1].clsid
=*clsid
;
3187 com_object_table
[com_object_size
-1].GetClassObject
=gcs
;
3191 int UnregisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3198 if (com_object_table
== 0)
3199 printf("Warning: UnregisterComClass() called without any registered class\n");
3200 while (i
< com_object_size
)
3204 memcpy(&com_object_table
[i
- 1].clsid
,
3205 &com_object_table
[i
].clsid
, sizeof(GUID
));
3206 com_object_table
[i
- 1].GetClassObject
=
3207 com_object_table
[i
].GetClassObject
;
3209 else if (memcmp(&com_object_table
[i
].clsid
, clsid
, sizeof(GUID
)) == 0
3210 && com_object_table
[i
].GetClassObject
== gcs
)
3218 if (--com_object_size
== 0)
3220 free(com_object_table
);
3221 com_object_table
= 0;
3228 const GUID IID_IUnknown
=
3230 0x00000000, 0x0000, 0x0000,
3231 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3233 const GUID IID_IClassFactory
=
3235 0x00000001, 0x0000, 0x0000,
3236 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3239 static long WINAPI
expCoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3240 long dwClsContext
, const GUID
* riid
, void** ppv
)
3243 struct COM_OBJECT_INFO
* ci
=0;
3244 for(i
=0; i
<com_object_size
; i
++)
3245 if(!memcmp(rclsid
, &com_object_table
[i
].clsid
, sizeof(GUID
)))
3246 ci
=&com_object_table
[i
];
3247 if(!ci
)return REGDB_E_CLASSNOTREG
;
3248 // in 'real' world we should mess with IClassFactory here
3249 i
=ci
->GetClassObject(rclsid
, riid
, ppv
);
3253 long CoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3254 long dwClsContext
, const GUID
* riid
, void** ppv
)
3256 return expCoCreateInstance(rclsid
, pUnkOuter
, dwClsContext
, riid
, ppv
);
3259 static int WINAPI
expIsRectEmpty(CONST RECT
*lprc
)
3266 w
= lprc
->right
- lprc
->left
;
3267 h
= lprc
->bottom
- lprc
->top
;
3268 if (w
<= 0 || h
<= 0)
3274 dbgprintf("IsRectEmpty(%p) => %s\n", lprc
, (r
) ? "TRUE" : "FALSE");
3275 //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3276 // return 0; // wmv9?
3280 static int _adjust_fdiv
=0; //what's this? - used to adjust division
3281 static int _winver
= 0x510; // windows version
3286 static unsigned int WINAPI
expGetTempPathA(unsigned int len
, char* path
)
3288 dbgprintf("GetTempPathA(%d, 0x%x)", len
, path
);
3291 dbgprintf(" => 0\n");
3294 strcpy(path
, "/tmp");
3295 dbgprintf(" => 5 ( '/tmp' )\n");
3302 DWORD dwFileAttributes;
3303 FILETIME ftCreationTime;
3304 FILETIME ftLastAccessTime;
3305 FILETIME ftLastWriteTime;
3306 DWORD nFileSizeHigh;
3310 CHAR cFileName[260];
3311 CHAR cAlternateFileName[14];
3312 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3315 static DIR* qtx_dir
=NULL
;
3317 static WIN_BOOL WINAPI
expFindNextFileA(HANDLE h
,LPWIN32_FIND_DATAA lpfd
)
3320 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h
, lpfd
);
3321 if(h
==FILE_HANDLE_quicktimeqtx
){
3323 if(!qtx_dir
) return 0;
3324 while((d
=readdir(qtx_dir
))){
3325 char* x
=strrchr(d
->d_name
,'.');
3327 if(strcmp(x
,".qtx")) continue;
3328 strcpy(lpfd
->cFileName
,d
->d_name
);
3329 // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3330 strcpy(lpfd
->cAlternateFileName
,"foobar.qtx");
3331 printf("### FindNext: %s\n",lpfd
->cFileName
);
3334 closedir(qtx_dir
); qtx_dir
=NULL
;
3341 static HANDLE WINAPI
expFindFirstFileA(LPCSTR s
, LPWIN32_FIND_DATAA lpfd
)
3343 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s
, s
, lpfd
);
3344 // printf("\n### FindFirstFileA('%s')...\n",s);
3346 if(strstr(s
, "quicktime\\*.QTX")){
3347 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s
, s
, lpfd
);
3348 printf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",def_path
);
3349 qtx_dir
=opendir(def_path
);
3350 if(!qtx_dir
) return (HANDLE
)-1;
3351 memset(lpfd
,0,sizeof(*lpfd
));
3352 if(expFindNextFileA(FILE_HANDLE_quicktimeqtx
,lpfd
))
3353 return FILE_HANDLE_quicktimeqtx
;
3354 printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",def_path
);
3358 if(strstr(s
, "QuickTime.qts")){
3359 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s
, s
, lpfd
);
3360 // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3361 // return (HANDLE)-1;
3362 strcpy(lpfd
->cFileName
, "QuickTime.qts");
3363 strcpy(lpfd
->cAlternateFileName
, "QuickT~1.qts");
3364 return FILE_HANDLE_quicktimeqts
;
3368 if(strstr(s
, "*.vwp")){
3369 // hack for VoxWare codec plugins:
3370 strcpy(lpfd
->cFileName
, "msms001.vwp");
3371 strcpy(lpfd
->cAlternateFileName
, "msms001.vwp");
3374 // return 'file not found'
3378 static WIN_BOOL WINAPI
expFindClose(HANDLE h
)
3380 dbgprintf("FindClose(0x%x) => 0\n", h
);
3382 // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3383 // closedir(qtx_dir);
3389 static UINT WINAPI
expSetErrorMode(UINT i
)
3391 dbgprintf("SetErrorMode(%d) => 0\n", i
);
3394 static UINT WINAPI
expGetWindowsDirectoryA(LPSTR s
,UINT c
)
3396 char windir
[]="c:\\windows";
3398 strncpy(s
, windir
, c
);
3399 result
=1+((c
<strlen(windir
))?c
:strlen(windir
));
3400 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3404 static UINT WINAPI
expGetCurrentDirectoryA(UINT c
, LPSTR s
)
3406 char curdir
[]="c:\\";
3408 strncpy(s
, curdir
, c
);
3409 result
=1+((c
<strlen(curdir
))?c
:strlen(curdir
));
3410 dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3414 static int WINAPI
expSetCurrentDirectoryA(const char *pathname
)
3416 dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname
, pathname
);
3418 if (strrchr(pathname
, '\\'))
3419 chdir(strcat(strrchr(pathname
, '\\')+1, '/'));
3426 static int WINAPI
expCreateDirectoryA(const char *pathname
, void *sa
)
3428 dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3429 pathname
, pathname
, sa
);
3431 p
= strrchr(pathname
, '\\')+1;
3432 strcpy(&buf
[0], p
); /* should be strncpy */
3439 if (strrchr(pathname
, '\\'))
3440 mkdir(strcat(strrchr(pathname
, '\\')+1, '/'), 666);
3442 mkdir(pathname
, 666);
3449 static WIN_BOOL WINAPI
expDeleteFileA(LPCSTR s
)
3451 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s
, s
);
3454 static WIN_BOOL WINAPI
expFileTimeToLocalFileTime(const FILETIME
* cpf
, LPFILETIME pf
)
3456 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf
, pf
);
3460 static UINT WINAPI
expGetTempFileNameA(LPCSTR cs1
,LPCSTR cs2
,UINT i
,LPSTR ps
)
3462 char mask
[16]="/tmp/AP_XXXXXX";
3464 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1
, cs1
, cs2
, cs2
, i
, ps
);
3467 dbgprintf(" => -1\n");
3470 result
=mkstemp(mask
);
3471 sprintf(ps
, "AP%d", result
);
3472 dbgprintf(" => %d\n", strlen(ps
));
3476 // This func might need proper implementation if we want AngelPotion codec.
3477 // They try to open APmpeg4v1.apl with it.
3478 // DLL will close opened file with CloseHandle().
3480 static HANDLE WINAPI
expCreateFileA(LPCSTR cs1
,DWORD i1
,DWORD i2
,
3481 LPSECURITY_ATTRIBUTES p1
, DWORD i3
,DWORD i4
,HANDLE i5
)
3483 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1
, cs1
, i1
,
3484 i2
, p1
, i3
, i4
, i5
);
3485 if((!cs1
) || (strlen(cs1
)<2))return -1;
3488 if(strstr(cs1
, "QuickTime.qts"))
3491 char* tmp
=malloc(strlen(def_path
)+50);
3492 strcpy(tmp
, def_path
);
3494 strcat(tmp
, "QuickTime.qts");
3495 result
=open(tmp
, O_RDONLY
);
3499 if(strstr(cs1
, ".qtx"))
3502 char* tmp
=malloc(strlen(def_path
)+250);
3503 char* x
=strrchr(cs1
,'\\');
3504 sprintf(tmp
,"%s/%s",def_path
,x
?(x
+1):cs1
);
3505 // printf("### Open: %s -> %s\n",cs1,tmp);
3506 result
=open(tmp
, O_RDONLY
);
3512 if(strncmp(cs1
, "AP", 2) == 0)
3515 char* tmp
=malloc(strlen(def_path
)+50);
3516 strcpy(tmp
, def_path
);
3518 strcat(tmp
, "APmpg4v1.apl");
3519 result
=open(tmp
, O_RDONLY
);
3523 if (strstr(cs1
, "vp3"))
3527 char* tmp
=malloc(20 + strlen(cs1
));
3528 strcpy(tmp
, "/tmp/");
3533 if (tmp
[r
] == ':' || tmp
[r
] == '\\')
3537 if (GENERIC_READ
& i1
)
3539 else if (GENERIC_WRITE
& i1
)
3542 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp
, r
, flg
);
3549 // Needed by wnvplay1.dll
3550 if (strstr(cs1
, "WINNOV.bmp"))
3553 r
=open("/dev/null", O_RDONLY
);
3558 /* we need this for some virtualdub filters */
3562 if (GENERIC_READ
& i1
)
3564 else if (GENERIC_WRITE
& i1
)
3567 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1
, r
, flg
);
3576 static UINT WINAPI
expGetSystemDirectoryA(
3577 char* lpBuffer
, // address of buffer for system directory
3578 UINT uSize
// size of directory buffer
3580 dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer
,uSize
);
3581 if(!lpBuffer
) strcpy(lpBuffer
,".");
3585 static char sysdir[]=".";
3586 static LPCSTR WINAPI expGetSystemDirectoryA()
3588 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3592 static DWORD WINAPI expGetFullPathNameA
3595 DWORD nBufferLength
,
3599 if(!lpFileName
) return 0;
3600 dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName
,nBufferLength
,
3601 lpBuffer
, lpFilePart
);
3604 strcpy(lpFilePart
, "Quick123.qts");
3606 strcpy(lpFilePart
, lpFileName
);
3609 if (strrchr(lpFileName
, '\\'))
3610 lpFilePart
= strrchr(lpFileName
, '\\');
3612 lpFilePart
= (LPTSTR
)lpFileName
;
3614 strcpy(lpBuffer
, lpFileName
);
3615 // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3616 return strlen(lpBuffer
);
3619 static DWORD WINAPI expGetShortPathNameA
3625 if(!longpath
) return 0;
3626 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath
,shortpath
,shortlen
);
3627 strcpy(shortpath
,longpath
);
3628 return strlen(shortpath
);
3631 static WIN_BOOL WINAPI
expReadFile(HANDLE h
,LPVOID pv
,DWORD size
,LPDWORD rd
,LPOVERLAPPED unused
)
3634 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, rd
);
3635 result
=read(h
, pv
, size
);
3637 if(!result
)return 0;
3641 static WIN_BOOL WINAPI
expWriteFile(HANDLE h
,LPCVOID pv
,DWORD size
,LPDWORD wr
,LPOVERLAPPED unused
)
3644 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, wr
);
3646 result
=write(h
, pv
, size
);
3648 if(!result
)return 0;
3651 static DWORD WINAPI
expSetFilePointer(HANDLE h
, LONG val
, LPLONG ext
, DWORD whence
)
3654 dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h
, val
, ext
, ext
? *ext
: NULL
, whence
);
3655 //why would DLL want temporary file with >2Gb size?
3668 if (val
== 0 && ext
!= 0)
3671 return lseek(h
, val
, wh
);
3674 static HDRVR WINAPI
expOpenDriverA(LPCSTR szDriverName
, LPCSTR szSectionName
,
3677 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3680 static HDRVR WINAPI
expOpenDriver(LPCSTR szDriverName
, LPCSTR szSectionName
,
3683 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3688 static WIN_BOOL WINAPI
expGetProcessAffinityMask(HANDLE hProcess
,
3689 LPDWORD lpProcessAffinityMask
,
3690 LPDWORD lpSystemAffinityMask
)
3692 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3693 hProcess
, lpProcessAffinityMask
, lpSystemAffinityMask
);
3694 if(lpProcessAffinityMask
)*lpProcessAffinityMask
=1;
3695 if(lpSystemAffinityMask
)*lpSystemAffinityMask
=1;
3699 // Fake implementation: does nothing, but does it right :)
3700 static WIN_BOOL WINAPI
expSetProcessAffinityMask(HANDLE hProcess
,
3701 LPDWORD dwProcessAffinityMask
)
3703 dbgprintf("SetProcessAffinityMask(0x%x, 0x%x) => 1\n",
3704 hProcess
, dwProcessAffinityMask
);
3709 static int WINAPI
expMulDiv(int nNumber
, int nNumerator
, int nDenominator
)
3711 static const long long max_int
=0x7FFFFFFFLL
;
3712 static const long long min_int
=-0x80000000LL
;
3713 long long tmp
=(long long)nNumber
*(long long)nNumerator
;
3714 dbgprintf("expMulDiv %d * %d / %d\n", nNumber
, nNumerator
, nDenominator
);
3715 if(!nDenominator
)return 1;
3717 if(tmp
<min_int
) return 1;
3718 if(tmp
>max_int
) return 1;
3722 static LONG WINAPI
explstrcmpiA(const char* str1
, const char* str2
)
3724 LONG result
=strcasecmp(str1
, str2
);
3725 dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
3729 static LONG WINAPI
explstrlenA(const char* str1
)
3731 LONG result
=strlen(str1
);
3732 dbgprintf("strlen(0x%x='%.50s') => %d\n", str1
, str1
, result
);
3736 static LONG WINAPI
explstrcpyA(char* str1
, const char* str2
)
3738 int result
= (int) strcpy(str1
, str2
);
3739 dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1
, str2
, str2
, result
);
3742 static LONG WINAPI
explstrcpynA(char* str1
, const char* str2
,int len
)
3745 if (strlen(str2
)>len
)
3746 result
= (int) strncpy(str1
, str2
,len
);
3748 result
= (int) strcpy(str1
,str2
);
3749 dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1
, str2
, str2
,len
, strlen(str2
),result
);
3752 static LONG WINAPI
explstrcatA(char* str1
, const char* str2
)
3754 int result
= (int) strcat(str1
, str2
);
3755 dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1
, str2
, str2
, result
);
3760 static LONG WINAPI
expInterlockedExchange(long *dest
, long l
)
3762 long retval
= *dest
;
3767 static void WINAPI
expInitCommonControls(void)
3769 dbgprintf("InitCommonControls called!\n");
3774 /* needed by QuickTime.qts */
3775 static HWND WINAPI
expCreateUpDownControl (DWORD style
, INT x
, INT y
, INT cx
, INT cy
,
3776 HWND parent
, INT id
, HINSTANCE inst
,
3777 HWND buddy
, INT maxVal
, INT minVal
, INT curVal
)
3779 dbgprintf("CreateUpDownControl(...)\n");
3784 /* alex: implement this call! needed for 3ivx */
3785 static HRESULT WINAPI
expCoCreateFreeThreadedMarshaler(void *pUnkOuter
, void **ppUnkInner
)
3787 dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
3788 pUnkOuter
, ppUnkInner
);
3790 return ERROR_CALL_NOT_IMPLEMENTED
;
3794 static int WINAPI
expDuplicateHandle(HANDLE hSourceProcessHandle
, // handle to source process
3795 HANDLE hSourceHandle
, // handle to duplicate
3796 HANDLE hTargetProcessHandle
, // handle to target process
3797 HANDLE
* lpTargetHandle
, // duplicate handle
3798 DWORD dwDesiredAccess
, // requested access
3799 int bInheritHandle
, // handle inheritance option
3800 DWORD dwOptions
// optional actions
3803 dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
3804 hSourceProcessHandle
, hSourceHandle
, hTargetProcessHandle
,
3805 lpTargetHandle
, dwDesiredAccess
, bInheritHandle
, dwOptions
);
3806 *lpTargetHandle
= hSourceHandle
;
3810 static HRESULT WINAPI
expCoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
3812 dbgprintf("CoInitializeEx(%p, %d) called\n", lpReserved
, dwCoInit
);
3816 // required by PIM1 codec (used by win98 PCTV Studio capture sw)
3817 static HRESULT WINAPI
expCoInitialize(
3818 LPVOID lpReserved
/* [in] pointer to win32 malloc interface
3819 (obsolete, should be NULL) */
3823 * Just delegate to the newer method.
3825 return expCoInitializeEx(lpReserved
, COINIT_APARTMENTTHREADED
);
3828 static void WINAPI
expCoUninitialize(void)
3830 dbgprintf("CoUninitialize() called\n");
3833 /* allow static linking */
3834 HRESULT WINAPI
CoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
3836 return expCoInitializeEx(lpReserved
, dwCoInit
);
3838 HRESULT WINAPI
CoInitialize(LPVOID lpReserved
)
3840 return expCoInitialize(lpReserved
);
3842 void WINAPI
CoUninitialize(void)
3844 return expCoUninitialize();
3847 static DWORD WINAPI expSetThreadAffinityMask
3850 DWORD dwThreadAffinityMask
3856 * no WINAPI functions - CDECL
3858 static void* expmalloc(int size
)
3861 // return malloc(size);
3862 void* result
=my_mreq(size
,0);
3863 dbgprintf("malloc(0x%x) => 0x%x\n", size
,result
);
3865 printf("WARNING: malloc() failed\n");
3868 static void expfree(void* mem
)
3870 // return free(mem);
3871 dbgprintf("free(%p)\n", mem
);
3874 /* needed by atrac3.acm */
3875 static void *expcalloc(int num
, int size
)
3877 void* result
=my_mreq(num
*size
,1);
3878 dbgprintf("calloc(%d,%d) => %p\n", num
,size
,result
);
3880 printf("WARNING: calloc() failed\n");
3883 static void* expnew(int size
)
3885 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
3886 // printf("%08x %08x %08x %08x\n",
3887 // size, *(1+(int*)&size),
3888 // *(2+(int*)&size),*(3+(int*)&size));
3892 result
=my_mreq(size
,0);
3893 dbgprintf("new(%d) => %p\n", size
, result
);
3895 printf("WARNING: new() failed\n");
3899 static int expdelete(void* memory
)
3901 dbgprintf("delete(%p)\n", memory
);
3907 * local definition - we need only the last two members at this point
3908 * otherwice we would have to introduce here GUIDs and some more types..
3910 typedef struct __attribute__((__packed__
))
3913 unsigned long cbFormat
; //0x40
3914 char* pbFormat
; //0x44
3916 static HRESULT WINAPI
expMoCopyMediaType(MY_MEDIA_TYPE
* dest
, const MY_MEDIA_TYPE
* src
)
3920 memcpy(dest
, src
, sizeof(MY_MEDIA_TYPE
));
3923 dest
->pbFormat
= (char*) my_mreq(dest
->cbFormat
, 0);
3924 if (!dest
->pbFormat
)
3925 return E_OUTOFMEMORY
;
3926 memcpy(dest
->pbFormat
, src
->pbFormat
, dest
->cbFormat
);
3930 static HRESULT WINAPI
expMoInitMediaType(MY_MEDIA_TYPE
* dest
, DWORD cbFormat
)
3934 memset(dest
, 0, sizeof(MY_MEDIA_TYPE
));
3937 dest
->pbFormat
= (char*) my_mreq(cbFormat
, 0);
3938 if (!dest
->pbFormat
)
3939 return E_OUTOFMEMORY
;
3943 static HRESULT WINAPI
expMoCreateMediaType(MY_MEDIA_TYPE
** dest
, DWORD cbFormat
)
3947 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
3948 return expMoInitMediaType(*dest
, cbFormat
);
3950 static HRESULT WINAPI
expMoDuplicateMediaType(MY_MEDIA_TYPE
** dest
, const void* src
)
3954 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
3955 return expMoCopyMediaType(*dest
, src
);
3957 static HRESULT WINAPI
expMoFreeMediaType(MY_MEDIA_TYPE
* dest
)
3963 my_release(dest
->pbFormat
);
3969 static HRESULT WINAPI
expMoDeleteMediaType(MY_MEDIA_TYPE
* dest
)
3973 expMoFreeMediaType(dest
);
3978 static int exp_snprintf( char *str
, int size
, const char *format
, ... )
3982 va_start(va
, format
);
3983 x
=snprintf(str
,size
,format
,va
);
3984 dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str
,size
,format
,x
);
3990 static int exp_initterm(int v1
, int v2
)
3992 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1
, v2
);
3996 /* merged from wine - 2002.04.21 */
3997 typedef void (*INITTERMFUNC
)();
3998 static int exp_initterm(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
4000 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start
, end
, *start
);
4005 //printf("call _initfunc: from: %p %d\n", *start);
4006 // ok this trick with push/pop is necessary as otherwice
4007 // edi/esi registers are being trashed
4026 //printf("done %p %d:%d\n", end);
4034 /* Fake _initterm_e from msvcr80.dll, needed by sirenacm.dll
4035 * NOTE: If I make this an alias for _initterm, then sirenacm.dll tries to call
4036 other uninmplemented functions; keep this in mind if some future codec needs
4037 a real implementation of this function */
4038 static int exp_initterm_e(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
4040 dbgprintf("_initterm_e(0x%x, 0x%x)\n", start
, end
);
4044 static void* exp__dllonexit()
4046 // FIXME extract from WINE
4050 static int expwsprintfA(char* string
, const char* format
, ...)
4054 va_start(va
, format
);
4055 result
= vsprintf(string
, format
, va
);
4056 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string
, format
, result
);
4061 static int expsprintf(char* str
, const char* format
, ...)
4065 dbgprintf("sprintf(0x%x, %s)\n", str
, format
);
4066 va_start(args
, format
);
4067 r
= vsprintf(str
, format
, args
);
4071 static int expsscanf(const char* str
, const char* format
, ...)
4075 dbgprintf("sscanf(%s, %s)\n", str
, format
);
4076 va_start(args
, format
);
4077 r
= vsscanf(str
, format
, args
);
4081 static void* expfopen(const char* path
, const char* mode
)
4083 printf("fopen: \"%s\" mode:%s\n", path
, mode
);
4084 //return fopen(path, mode);
4085 return fdopen(0, mode
); // everything on screen
4087 static int expfprintf(void* stream
, const char* format
, ...)
4091 dbgprintf("fprintf(%p, %s, ...)\n", stream
, format
);
4093 va_start(args
, format
);
4094 r
= vfprintf((FILE*) stream
, format
, args
);
4100 static int expprintf(const char* format
, ...)
4104 dbgprintf("printf(%s, ...)\n", format
);
4105 va_start(args
, format
);
4106 r
= vprintf(format
, args
);
4111 static char* expgetenv(const char* varname
)
4113 char* v
= getenv(varname
);
4114 dbgprintf("getenv(%s) => %s\n", varname
, v
);
4118 static void* expwcscpy(WCHAR
* dst
, const WCHAR
* src
)
4121 while ((*p
++ = *src
++))
4126 static char* expstrrchr(char* string
, int value
)
4128 char* result
=strrchr(string
, value
);
4130 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4132 dbgprintf("strrchr(0x%x='%s', %d) => 0", string
, string
, value
);
4136 static char* expstrchr(char* string
, int value
)
4138 char* result
=strchr(string
, value
);
4140 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4142 dbgprintf("strchr(0x%x='%s', %d) => 0", string
, string
, value
);
4145 static int expstrlen(char* str
)
4147 int result
=strlen(str
);
4148 dbgprintf("strlen(0x%x='%s') => %d\n", str
, str
, result
);
4151 static char* expstrcpy(char* str1
, const char* str2
)
4153 char* result
= strcpy(str1
, str2
);
4154 dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1
, str2
, str2
, result
);
4157 static char* expstrncpy(char* str1
, const char* str2
, size_t count
)
4159 char* result
= strncpy(str1
, str2
, count
);
4160 dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1
, str2
, str2
, count
, result
);
4163 static int expstrcmp(const char* str1
, const char* str2
)
4165 int result
=strcmp(str1
, str2
);
4166 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4169 static int expstrncmp(const char* str1
, const char* str2
,int x
)
4171 int result
=strncmp(str1
, str2
,x
);
4172 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4175 static char* expstrcat(char* str1
, const char* str2
)
4177 char* result
= strcat(str1
, str2
);
4178 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1
, str1
, str2
, str2
, result
);
4181 static char* exp_strdup(const char* str1
)
4183 int l
= strlen(str1
);
4184 char* result
= (char*) my_mreq(l
+ 1,0);
4186 strcpy(result
, str1
);
4187 dbgprintf("_strdup(0x%x='%s') => %p\n", str1
, str1
, result
);
4190 static int expisalnum(int c
)
4192 int result
= (int) isalnum(c
);
4193 dbgprintf("isalnum(0x%x='%c' => %d\n", c
, c
, result
);
4196 static int expisspace(int c
)
4198 int result
= (int) isspace(c
);
4199 dbgprintf("isspace(0x%x='%c' => %d\n", c
, c
, result
);
4202 static int expisalpha(int c
)
4204 int result
= (int) isalpha(c
);
4205 dbgprintf("isalpha(0x%x='%c' => %d\n", c
, c
, result
);
4208 static int expisdigit(int c
)
4210 int result
= (int) isdigit(c
);
4211 dbgprintf("isdigit(0x%x='%c' => %d\n", c
, c
, result
);
4214 static void* expmemmove(void* dest
, void* src
, int n
)
4216 void* result
= memmove(dest
, src
, n
);
4217 dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4220 static int expmemcmp(void* dest
, void* src
, int n
)
4222 int result
= memcmp(dest
, src
, n
);
4223 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest
, src
, n
, result
);
4226 static void* expmemcpy(void* dest
, void* src
, int n
)
4228 void *result
= memcpy(dest
, src
, n
);
4229 dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4232 static void* expmemset(void* dest
, int c
, size_t n
)
4234 void *result
= memset(dest
, c
, n
);
4235 dbgprintf("memset(0x%x, %d, %d) => %p\n", dest
, c
, n
, result
);
4238 static time_t exptime(time_t* t
)
4240 time_t result
= time(t
);
4241 dbgprintf("time(0x%x) => %d\n", t
, result
);
4245 static int exprand(void)
4250 static void expsrand(int seed
)
4257 // preferred compilation with -O2 -ffast-math !
4259 static double explog10(double x
)
4261 /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4265 static double expcos(double x
)
4267 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4273 static void explog10(void)
4284 static void expcos(void)
4295 // this seem to be the only how to make this function working properly
4296 // ok - I've spent tremendous amount of time (many many many hours
4297 // of debuging fixing & testing - it's almost unimaginable - kabi
4299 // _ftol - operated on the float value which is already on the FPU stack
4301 static void exp_ftol(void)
4305 "sub $12, %esp \n\t"
4306 "fstcw -2(%ebp) \n\t"
4308 "movw -2(%ebp), %ax \n\t"
4309 "orb $0x0C, %ah \n\t"
4310 "movw %ax, -4(%ebp) \n\t"
4311 "fldcw -4(%ebp) \n\t"
4312 "fistpl -12(%ebp) \n\t"
4313 "fldcw -2(%ebp) \n\t"
4314 "movl -12(%ebp), %eax \n\t"
4315 //Note: gcc 3.03 does not do the following op if it
4316 // knows that ebp=esp
4317 "movl %ebp, %esp \n\t"
4321 #define FPU_DOUBLES(var1,var2) double var1,var2; \
4322 __asm__ volatile( "fstpl %0;fwait" : "=m" (var2) : ); \
4323 __asm__ volatile( "fstpl %0;fwait" : "=m" (var1) : )
4325 static double exp_CIpow(void)
4329 dbgprintf("_CIpow(%lf, %lf)\n", x
, y
);
4333 static double exppow(double x
, double y
)
4335 /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4339 static double expldexp(double x
, int expo
)
4341 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4342 return ldexp(x
, expo
);
4345 static double expfrexp(double x
, int* expo
)
4347 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4348 return frexp(x
, expo
);
4353 static int exp_stricmp(const char* s1
, const char* s2
)
4355 return strcasecmp(s1
, s2
);
4358 /* from declaration taken from Wine sources - this fountion seems to be
4359 * undocumented in any M$ doc */
4360 static int exp_setjmp3(void* jmpbuf
, int x
)
4362 //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4366 //"mov 4(%%esp), %%edx \n\t"
4367 "mov (%%esp), %%eax \n\t"
4368 "mov %%eax, (%%edx) \n\t" // store ebp
4370 //"mov %%ebp, (%%edx) \n\t"
4371 "mov %%ebx, 4(%%edx) \n\t"
4372 "mov %%edi, 8(%%edx) \n\t"
4373 "mov %%esi, 12(%%edx) \n\t"
4374 "mov %%esp, 16(%%edx) \n\t"
4376 "mov 4(%%esp), %%eax \n\t"
4377 "mov %%eax, 20(%%edx) \n\t"
4379 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4380 "movl $0, 36(%%edx) \n\t"
4382 : "d"(jmpbuf
) // input
4388 "mov %%fs:0, %%eax \n\t" // unsure
4389 "mov %%eax, 24(%%edx) \n\t"
4390 "cmp $0xffffffff, %%eax \n\t"
4392 "mov %%eax, 28(%%edx) \n\t"
4403 static DWORD WINAPI
expGetCurrentProcessId(void)
4405 dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4406 return getpid(); //(DWORD)NtCurrentTeb()->pid;
4413 } TIMECAPS
, *LPTIMECAPS
;
4415 static MMRESULT WINAPI
exptimeGetDevCaps(LPTIMECAPS lpCaps
, UINT wSize
)
4417 dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps
, wSize
);
4419 lpCaps
->wPeriodMin
= 1;
4420 lpCaps
->wPeriodMax
= 65535;
4424 static MMRESULT WINAPI
exptimeBeginPeriod(UINT wPeriod
)
4426 dbgprintf("timeBeginPeriod(%u) !\n", wPeriod
);
4428 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4433 static MMRESULT WINAPI
exptimeEndPeriod(UINT wPeriod
)
4435 dbgprintf("timeEndPeriod(%u) !\n", wPeriod
);
4437 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4442 static void WINAPI
expGlobalMemoryStatus(
4443 LPMEMORYSTATUS lpmem
4445 static MEMORYSTATUS cached_memstatus
;
4446 static int cache_lastchecked
= 0;
4450 if (time(NULL
)==cache_lastchecked
) {
4451 memcpy(lpmem
,&cached_memstatus
,sizeof(MEMORYSTATUS
));
4456 f
= fopen( "/proc/meminfo", "r" );
4460 int total
, used
, free
, shared
, buffers
, cached
;
4462 lpmem
->dwLength
= sizeof(MEMORYSTATUS
);
4463 lpmem
->dwTotalPhys
= lpmem
->dwAvailPhys
= 0;
4464 lpmem
->dwTotalPageFile
= lpmem
->dwAvailPageFile
= 0;
4465 while (fgets( buffer
, sizeof(buffer
), f
))
4467 /* old style /proc/meminfo ... */
4468 if (sscanf( buffer
, "Mem: %d %d %d %d %d %d", &total
, &used
, &free
, &shared
, &buffers
, &cached
))
4470 lpmem
->dwTotalPhys
+= total
;
4471 lpmem
->dwAvailPhys
+= free
+ buffers
+ cached
;
4473 if (sscanf( buffer
, "Swap: %d %d %d", &total
, &used
, &free
))
4475 lpmem
->dwTotalPageFile
+= total
;
4476 lpmem
->dwAvailPageFile
+= free
;
4479 /* new style /proc/meminfo ... */
4480 if (sscanf(buffer
, "MemTotal: %d", &total
))
4481 lpmem
->dwTotalPhys
= total
*1024;
4482 if (sscanf(buffer
, "MemFree: %d", &free
))
4483 lpmem
->dwAvailPhys
= free
*1024;
4484 if (sscanf(buffer
, "SwapTotal: %d", &total
))
4485 lpmem
->dwTotalPageFile
= total
*1024;
4486 if (sscanf(buffer
, "SwapFree: %d", &free
))
4487 lpmem
->dwAvailPageFile
= free
*1024;
4488 if (sscanf(buffer
, "Buffers: %d", &buffers
))
4489 lpmem
->dwAvailPhys
+= buffers
*1024;
4490 if (sscanf(buffer
, "Cached: %d", &cached
))
4491 lpmem
->dwAvailPhys
+= cached
*1024;
4495 if (lpmem
->dwTotalPhys
)
4497 DWORD TotalPhysical
= lpmem
->dwTotalPhys
+lpmem
->dwTotalPageFile
;
4498 DWORD AvailPhysical
= lpmem
->dwAvailPhys
+lpmem
->dwAvailPageFile
;
4499 lpmem
->dwMemoryLoad
= (TotalPhysical
-AvailPhysical
)
4500 / (TotalPhysical
/ 100);
4505 /* FIXME: should do something for other systems */
4506 lpmem
->dwMemoryLoad
= 0;
4507 lpmem
->dwTotalPhys
= 16*1024*1024;
4508 lpmem
->dwAvailPhys
= 16*1024*1024;
4509 lpmem
->dwTotalPageFile
= 16*1024*1024;
4510 lpmem
->dwAvailPageFile
= 16*1024*1024;
4512 expGetSystemInfo(&si
);
4513 lpmem
->dwTotalVirtual
= si
.lpMaximumApplicationAddress
-si
.lpMinimumApplicationAddress
;
4514 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4515 lpmem
->dwAvailVirtual
= lpmem
->dwTotalVirtual
-64*1024;
4516 memcpy(&cached_memstatus
,lpmem
,sizeof(MEMORYSTATUS
));
4517 cache_lastchecked
= time(NULL
);
4519 /* it appears some memory display programs want to divide by these values */
4520 if(lpmem
->dwTotalPageFile
==0)
4521 lpmem
->dwTotalPageFile
++;
4523 if(lpmem
->dwAvailPageFile
==0)
4524 lpmem
->dwAvailPageFile
++;
4527 static INT WINAPI
expGetThreadPriority(HANDLE hthread
)
4529 dbgprintf("GetThreadPriority(%p)\n",hthread
);
4533 /**********************************************************************
4534 * SetThreadPriority [KERNEL32.@] Sets priority for thread.
4540 static WIN_BOOL WINAPI
expSetThreadPriority(
4541 HANDLE hthread
, /* [in] Handle to thread */
4542 INT priority
) /* [in] Thread priority level */
4544 dbgprintf("SetThreadPriority(%p,%d)\n",hthread
,priority
);
4548 static void WINAPI
expExitProcess( DWORD status
)
4550 printf("EXIT - code %ld\n",status
);
4554 static INT WINAPI
expMessageBoxA(HWND hWnd
, LPCSTR text
, LPCSTR title
, UINT type
){
4555 printf("MSGBOX '%s' '%s' (%d)\n",text
,title
,type
);
4557 if (type
== MB_ICONHAND
&& !strlen(text
) && !strlen(title
))
4563 /* these are needed for mss1 */
4566 * \brief this symbol is defined within exp_EH_prolog_dummy
4567 * \param dest jump target
4569 void exp_EH_prolog(void *dest
);
4570 //! just a dummy function that acts a container for the asm section
4571 void exp_EH_prolog_dummy(void) {
4573 // take care, this "function" may not change flags or
4574 // registers besides eax (which is also why we can't use
4575 // exp_EH_prolog_dummy directly)
4576 MANGLE(exp_EH_prolog
)": \n\t"
4579 "mov %esp, %ebp \n\t"
4580 "lea -12(%esp), %esp \n\t"
4585 #include <netinet/in.h>
4586 static WINAPI
inline unsigned long int exphtonl(unsigned long int hostlong
)
4588 // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4589 return htonl(hostlong
);
4592 static WINAPI
inline unsigned long int expntohl(unsigned long int netlong
)
4594 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4595 return ntohl(netlong
);
4597 static void WINAPI
expVariantInit(void* p
)
4599 printf("InitCommonControls called!\n");
4603 static int WINAPI
expRegisterClassA(const void/*WNDCLASSA*/ *wc
)
4605 dbgprintf("RegisterClassA(%p) => random id\n", wc
);
4606 return time(NULL
); /* be precise ! */
4609 static int WINAPI
expUnregisterClassA(const char *className
, HINSTANCE hInstance
)
4611 dbgprintf("UnregisterClassA(%s, %p) => 0\n", className
, hInstance
);
4616 /* should be fixed bcs it's not fully strlen equivalent */
4617 static int expSysStringByteLen(void *str
)
4619 dbgprintf("SysStringByteLen(%p) => %d\n", str
, strlen(str
));
4623 static int expDirectDrawCreate(void)
4625 dbgprintf("DirectDrawCreate(...) => NULL\n");
4630 typedef struct tagPALETTEENTRY
{
4637 /* reversed the first 2 entries */
4638 typedef struct tagLOGPALETTE
{
4641 PALETTEENTRY palPalEntry
[1];
4644 static HPALETTE WINAPI
expCreatePalette(CONST LOGPALETTE
*lpgpl
)
4649 dbgprintf("CreatePalette(%x) => NULL\n", lpgpl
);
4651 i
= sizeof(LOGPALETTE
)+((lpgpl
->palNumEntries
-1)*sizeof(PALETTEENTRY
));
4652 test
= (HPALETTE
)malloc(i
);
4653 memcpy((void *)test
, lpgpl
, i
);
4658 static int expCreatePalette(void)
4660 dbgprintf("CreatePalette(...) => NULL\n");
4665 static int WINAPI
expGetClientRect(HWND win
, RECT
*r
)
4667 dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win
, r
);
4668 r
->right
= PSEUDO_SCREEN_WIDTH
;
4670 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
4676 typedef struct tagPOINT
{
4682 static int WINAPI
expClientToScreen(HWND win
, POINT
*p
)
4684 dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win
, p
, p
->x
, p
->y
);
4692 static int WINAPI
expSetThreadIdealProcessor(HANDLE thread
, int proc
)
4694 dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread
, proc
);
4698 static int WINAPI
expMessageBeep(int type
)
4700 dbgprintf("MessageBeep(%d) => 1\n", type
);
4704 static int WINAPI
expDialogBoxParamA(void *inst
, const char *name
,
4705 HWND parent
, void *dialog_func
, void *init_param
)
4707 dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
4708 inst
, name
, name
, parent
, dialog_func
, init_param
);
4712 static void WINAPI
expRegisterClipboardFormatA(const char *name
) {
4713 dbgprintf("RegisterClipboardFormatA(0x%x = %s)\n", name
, name
);
4716 /* needed by imagepower mjpeg2k */
4717 static void *exprealloc(void *ptr
, size_t size
)
4719 dbgprintf("realloc(0x%x, %x)\n", ptr
, size
);
4721 return my_mreq(size
,0);
4723 return my_realloc(ptr
, size
);
4726 /* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
4727 static WIN_BOOL WINAPI
expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn
)
4732 static char * WINAPI
expPathFindExtensionA(const char *path
) {
4737 ext
= strrchr(path
, '.');
4739 ext
= &path
[strlen(path
)];
4741 dbgprintf("PathFindExtensionA(0x%x = %s) => 0x%x, %s\n", path
, path
, ext
, ext
);
4745 static char * WINAPI
expPathFindFileNameA(const char *path
) {
4747 if (!path
|| strlen(path
) < 2)
4750 name
= strrchr(path
- 1, '\\');
4754 dbgprintf("PathFindFileNameA(0x%x = %s) => 0x%x, %s\n", path
, path
, name
, name
);
4758 static double expfloor(double x
)
4760 dbgprintf("floor(%lf)\n", x
);
4764 #define FPU_DOUBLE(var) double var; \
4765 __asm__ volatile( "fstpl %0;fwait" : "=m" (var) : )
4767 static double exp_CIcos(void)
4771 dbgprintf("_CIcos(%lf)\n", x
);
4775 static double exp_CIsin(void)
4779 dbgprintf("_CIsin(%lf)\n", x
);
4783 static double exp_CIsqrt(void)
4787 dbgprintf("_CIsqrt(%lf)\n", x
);
4791 /* Needed by rp8 sipr decoder */
4792 static LPSTR WINAPI
expCharNextA(LPCSTR ptr
)
4794 if (!*ptr
) return (LPSTR
)ptr
;
4795 // dbgprintf("CharNextA(0x%08x), %s\n", ptr, ptr);
4796 return (LPSTR
)(ptr
+ 1);
4799 // Fake implementation, needed by wvc1dmod.dll
4800 static int WINAPI
expPropVariantClear(void *pvar
)
4802 // dbgprintf("PropVariantclear (0x%08x), %s\n", ptr, ptr);
4806 // This define is fake, the real thing is a struct
4807 #define LPDEVMODEA void*
4808 // Dummy implementation, always return 1
4809 // Required for frapsvid.dll 2.8.1, return value does not matter
4810 static WIN_BOOL WINAPI
expEnumDisplaySettingsA(LPCSTR name
,DWORD n
,
4813 dbgprintf("EnumDisplaySettingsA (dummy) => 1\n");
4817 // Fake implementation of _decode_pointer from msvcr80.dll, needed by sirenacm.dll
4818 // NOTE: undocumented function, probably the declaration is not right
4819 static int exp_decode_pointer(void *ptr
)
4821 dbgprintf("_decode_pointer (0x%08x)\n", ptr
);
4825 /* Fake implementation of sdt::_Lockit::_Lockit(void) from msvcp60.dll
4826 Needed by SCLS.DLL */
4827 static int exp_0Lockit_dummy(void)
4829 dbgprintf("0Lockit_dummy (??0_Lockit@std@@QAE@XZ)\n");
4833 /* Fake implementation of sdt::_Lockit::~_Lockit(void) from msvcp60.dll
4834 Needed by SCLS.DLL */
4835 static int exp_1Lockit_dummy(void)
4837 dbgprintf("1Lockit_dummy (??1_Lockit@std@@QAE@XZ)\n");
4851 struct exports
* exps
;
4855 {#X, Y, (void*)exp##X},
4857 #define UNDEFF(X, Y) \
4860 struct exports exp_kernel32
[]=
4862 FF(GetVolumeInformationA
,-1)
4863 FF(GetDriveTypeA
,-1)
4864 FF(GetLogicalDriveStringsA
,-1)
4865 FF(IsBadWritePtr
, 357)
4866 FF(IsBadReadPtr
, 354)
4867 FF(IsBadStringPtrW
, -1)
4868 FF(IsBadStringPtrA
, -1)
4869 FF(DisableThreadLibraryCalls
, -1)
4870 FF(CreateThread
, -1)
4871 FF(CreateEventA
, -1)
4874 FF(WaitForSingleObject
, -1)
4876 FF(WaitForMultipleObjects
, -1)
4881 FF(GetSystemInfo
, -1)
4889 FF(GetProcessHeap
, -1)
4890 FF(VirtualAlloc
, -1)
4892 FF(InitializeCriticalSection
, -1)
4893 FF(EnterCriticalSection
, -1)
4894 FF(LeaveCriticalSection
, -1)
4895 FF(DeleteCriticalSection
, -1)
4900 FF(GetCurrentThreadId
, -1)
4901 FF(GetCurrentProcess
, -1)
4906 FF(GlobalReAlloc
, -1)
4909 FF(MultiByteToWideChar
, 427)
4910 FF(WideCharToMultiByte
, -1)
4911 FF(GetVersionExA
, -1)
4912 FF(CreateSemaphoreA
, -1)
4913 FF(QueryPerformanceCounter
, -1)
4914 FF(QueryPerformanceFrequency
, -1)
4918 FF(GlobalHandle
, -1)
4919 FF(GlobalUnlock
, -1)
4921 FF(LoadResource
, -1)
4922 FF(ReleaseSemaphore
, -1)
4923 FF(FindResourceA
, -1)
4924 FF(LockResource
, -1)
4925 FF(FreeResource
, -1)
4926 FF(SizeofResource
, -1)
4928 FF(GetCommandLineA
, -1)
4929 FF(GetEnvironmentStringsW
, -1)
4930 FF(FreeEnvironmentStringsW
, -1)
4931 FF(FreeEnvironmentStringsA
, -1)
4932 FF(GetEnvironmentStrings
, -1)
4933 FF(GetStartupInfoA
, -1)
4934 FF(GetStdHandle
, -1)
4937 FF(GetFileAttributesA
, -1)
4939 FF(SetHandleCount
, -1)
4941 FF(GetModuleFileNameA
, -1)
4942 FF(SetUnhandledExceptionFilter
, -1)
4943 FF(LoadLibraryA
, -1)
4944 FF(GetProcAddress
, -1)
4946 FF(CreateFileMappingA
, -1)
4947 FF(OpenFileMappingA
, -1)
4948 FF(MapViewOfFile
, -1)
4949 FF(UnmapViewOfFile
, -1)
4951 FF(GetModuleHandleA
, -1)
4952 FF(GetProfileIntA
, -1)
4953 FF(GetPrivateProfileIntA
, -1)
4954 FF(GetPrivateProfileStringA
, -1)
4955 FF(WritePrivateProfileStringA
, -1)
4956 FF(GetLastError
, -1)
4957 FF(SetLastError
, -1)
4958 FF(InterlockedIncrement
, -1)
4959 FF(InterlockedDecrement
, -1)
4960 FF(GetTimeZoneInformation
, -1)
4961 FF(OutputDebugStringA
, -1)
4962 FF(GetLocalTime
, -1)
4963 FF(GetSystemTime
, -1)
4964 FF(GetSystemTimeAsFileTime
, -1)
4965 FF(GetEnvironmentVariableA
, -1)
4966 FF(SetEnvironmentVariableA
, -1)
4967 FF(RtlZeroMemory
,-1)
4968 FF(RtlMoveMemory
,-1)
4969 FF(RtlFillMemory
,-1)
4971 FF(FindFirstFileA
,-1)
4972 FF(FindNextFileA
,-1)
4974 FF(FileTimeToLocalFileTime
,-1)
4978 FF(SetFilePointer
,-1)
4979 FF(GetTempFileNameA
,-1)
4981 FF(GetSystemDirectoryA
,-1)
4982 FF(GetWindowsDirectoryA
,-1)
4984 FF(GetCurrentDirectoryA
,-1)
4985 FF(SetCurrentDirectoryA
,-1)
4986 FF(CreateDirectoryA
,-1)
4988 FF(GetShortPathNameA
,-1)
4989 FF(GetFullPathNameA
,-1)
4990 FF(SetErrorMode
, -1)
4991 FF(IsProcessorFeaturePresent
, -1)
4992 FF(GetProcessAffinityMask
, -1)
4993 FF(InterlockedExchange
, -1)
4994 FF(InterlockedCompareExchange
, -1)
5001 FF(GetProcessVersion
,-1)
5002 FF(GetCurrentThread
,-1)
5005 FF(DuplicateHandle
,-1)
5006 FF(GetTickCount
, -1)
5007 FF(SetThreadAffinityMask
,-1)
5008 FF(GetCurrentProcessId
,-1)
5009 FF(GlobalMemoryStatus
,-1)
5010 FF(GetThreadPriority
,-1)
5011 FF(SetThreadPriority
,-1)
5013 {"LoadLibraryExA", -1, (void*)&LoadLibraryExA
},
5014 FF(SetThreadIdealProcessor
,-1)
5015 FF(SetProcessAffinityMask
, -1)
5016 UNDEFF(FlsAlloc
, -1)
5017 UNDEFF(FlsGetValue
, -1)
5018 UNDEFF(FlsSetValue
, -1)
5022 struct exports exp_msvcrt
[]={
5028 {"??3@YAXPAX@Z", -1, expdelete
},
5029 {"??2@YAPAXI@Z", -1, expnew
},
5030 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5031 {"_winver",-1,(void*)&_winver
},
5072 /* needed by frapsvid.dll */
5073 {"strstr",-1,(char *)&strstr
},
5074 {"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(CoInitializeEx
, -1)
5180 FF(CoUninitialize
, -1)
5181 FF(CoTaskMemAlloc
, -1)
5182 FF(CoTaskMemFree
, -1)
5183 FF(StringFromGUID2
, -1)
5184 FF(PropVariantClear
, -1)
5186 // do we really need crtdll ???
5187 // msvcrt is the correct place probably...
5188 struct exports exp_crtdll
[]={
5192 struct exports exp_comctl32
[]={
5193 FF(StringFromGUID2
, -1)
5194 FF(InitCommonControls
, 17)
5196 FF(CreateUpDownControl
, 16)
5199 struct exports exp_wsock32
[]={
5203 struct exports exp_msdmo
[]={
5204 FF(memcpy
, -1) // just test
5205 FF(MoCopyMediaType
, -1)
5206 FF(MoCreateMediaType
, -1)
5207 FF(MoDeleteMediaType
, -1)
5208 FF(MoDuplicateMediaType
, -1)
5209 FF(MoFreeMediaType
, -1)
5210 FF(MoInitMediaType
, -1)
5212 struct exports exp_oleaut32
[]={
5215 FF(SysStringByteLen
, 149)
5221 vma: Hint/Ord Member-Name
5226 2305e 167 _adjust_fdiv
5229 22ffc 176 _beginthreadex
5231 2300e 85 __CxxFrameHandler
5235 struct exports exp_pncrt
[]={
5236 FF(malloc
, -1) // just test
5237 FF(free
, -1) // just test
5238 FF(fprintf
, -1) // just test
5239 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5242 {"??3@YAXPAX@Z", -1, expdelete
},
5243 {"??2@YAPAXI@Z", -1, expnew
},
5255 struct exports exp_ddraw
[]={
5256 FF(DirectDrawCreate
, -1)
5260 struct exports exp_comdlg32
[]={
5261 FF(GetOpenFileNameA
, -1)
5264 struct exports exp_shlwapi
[]={
5265 FF(PathFindExtensionA
, -1)
5266 FF(PathFindFileNameA
, -1)
5269 struct exports exp_msvcr80
[]={
5277 FF(_decode_pointer
, -1)
5280 struct exports exp_msvcp60
[]={
5281 {"??0_Lockit@std@@QAE@XZ", -1, exp_0Lockit_dummy
},
5282 {"??1_Lockit@std@@QAE@XZ", -1, exp_1Lockit_dummy
}
5286 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5288 struct libs libraries
[]={
5314 static WIN_BOOL WINAPI
ext_stubs(void)
5316 volatile int idx
= 0xdeadabcd;
5317 // make sure gcc does not do eip-relative call or something like that
5318 volatile void (*my_printf
)(char *, char *) = (void *)0xdeadfbcd;
5319 my_printf("Called unk_%s\n", export_names
[idx
]);
5323 #define MAX_STUB_SIZE 0x60
5324 #define MAX_NUM_STUBS 200
5326 static char *extcode
= NULL
;
5328 static void* add_stub(void)
5332 // generated code in runtime!
5335 extcode
= mmap_anon(NULL
, MAX_NUM_STUBS
* MAX_STUB_SIZE
,
5336 PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
, 0);
5337 answ
= extcode
+ pos
* MAX_STUB_SIZE
;
5338 if (pos
>= MAX_NUM_STUBS
) {
5339 printf("too many stubs, expect crash\n");
5342 memcpy(answ
, ext_stubs
, MAX_STUB_SIZE
);
5343 for (i
= 0; i
< MAX_STUB_SIZE
- 3; i
++) {
5344 int *magic
= (int *)(answ
+ i
);
5345 if (*magic
== 0xdeadabcd) {
5349 if (*magic
== 0xdeadfbcd) {
5350 *magic
= (intptr_t)printf
;
5355 printf("magic code not found in ext_subs, expect crash\n");
5362 void* LookupExternal(const char* library
, int ordinal
)
5367 printf("ERROR: library=0\n");
5368 return (void*)ext_unknown
;
5370 // printf("%x %x\n", &unk_exp1, &unk_exp2);
5372 dbgprintf("External func %s:%d\n", library
, ordinal
);
5374 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5376 if(strcasecmp(library
, libraries
[i
].name
))
5378 for(j
=0; j
<libraries
[i
].length
; j
++)
5380 if(ordinal
!=libraries
[i
].exps
[j
].id
)
5382 //printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5383 return libraries
[i
].exps
[j
].func
;
5387 #ifndef LOADLIB_TRY_NATIVE
5388 /* hack for truespeech and vssh264*/
5389 if (!strcmp(library
, "tsd32.dll") || !strcmp(library
,"vssh264dec.dll") || !strcmp(library
,"LCMW2.dll") || !strcmp(library
,"VDODEC32.dll"))
5391 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5397 hand
= LoadLibraryA(library
);
5400 wm
= MODULE32_LookupHMODULE(hand
);
5406 func
= PE_FindExportedFunction(wm
, (LPCSTR
) ordinal
, 0);
5409 printf("No such ordinal in external dll\n");
5410 FreeLibrary((int)hand
);
5414 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5420 if(pos
>150)return 0;
5421 sprintf(export_names
[pos
], "%s:%d", library
, ordinal
);
5425 void* LookupExternalByName(const char* library
, const char* name
)
5428 // return (void*)ext_unknown;
5431 printf("ERROR: library=0\n");
5432 return (void*)ext_unknown
;
5434 if((unsigned long)name
<=0xffff)
5436 return LookupExternal(library
, (int)name
);
5438 dbgprintf("External func %s:%s\n", library
, name
);
5439 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5441 if(strcasecmp(library
, libraries
[i
].name
))
5443 for(j
=0; j
<libraries
[i
].length
; j
++)
5445 if(strcmp(name
, libraries
[i
].exps
[j
].name
))
5447 if((unsigned int)(libraries
[i
].exps
[j
].func
) == -1)
5448 return NULL
; //undefined func
5449 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5450 return libraries
[i
].exps
[j
].func
;
5454 #ifndef LOADLIB_TRY_NATIVE
5455 /* hack for vss h264 */
5456 if (!strcmp(library
,"vssh264core.dll") || !strcmp(library
,"3ivx.dll"))
5458 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5464 hand
= LoadLibraryA(library
);
5467 wm
= MODULE32_LookupHMODULE(hand
);
5473 func
= PE_FindExportedFunction(wm
, name
, 0);
5476 printf("No such name in external dll\n");
5477 FreeLibrary((int)hand
);
5481 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5487 if(pos
>150)return 0;// to many symbols
5488 strcpy(export_names
[pos
], name
);
5492 void my_garbagecollection(void)
5495 int unfree
= 0, unfreecnt
= 0;
5501 alloc_header
* mem
= last_alloc
+ 1;
5502 unfree
+= my_size(mem
);
5504 if (my_release(mem
) != 0)
5505 // avoid endless loop when memory is trashed
5506 if (--max_fatal
< 0)
5509 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree
, unfreecnt
, last_alloc
, alccnt
);