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/
23 //#define LOADLIB_TRY_NATIVE
25 /* Hack to make sure the correct function declaration in com.h is used when
26 * this file is built for the test applications with WIN32_LOADER disabled. */
31 #ifdef CONFIG_QTX_CODECS
32 #define PSEUDO_SCREEN_WIDTH /*640*/800
33 #define PSEUDO_SCREEN_HEIGHT /*480*/600
36 #include "wine/winbase.h"
37 #include "wine/winreg.h"
38 #include "wine/winnt.h"
39 #include "wine/winerror.h"
40 #include "wine/debugtools.h"
41 #include "wine/module.h"
42 #include "wine/winuser.h"
43 #include "wine/objbase.h"
63 #include <sys/types.h>
67 #include <sys/timeb.h>
72 #ifdef HAVE_SYS_MMAN_H
75 #include "osdep/mmap.h"
77 #include "osdep/mmap_anon.h"
78 #include "libavutil/avstring.h"
80 char* def_path
= WIN32_PATH
;
82 static void do_cpuid(unsigned int ax
, unsigned int *regs
)
86 "pushl %%ebx; pushl %%ecx; pushl %%edx;"
92 "popl %%edx; popl %%ecx; popl %%ebx;"
94 : "0" (ax
), "S" (regs
)
97 static unsigned int c_localcount_tsc(void)
109 static void c_longcount_tsc(long long* z
)
114 "movl %%eax, %%ebx\n\t"
116 "movl %%eax, 0(%%ebx)\n\t"
117 "movl %%edx, 4(%%ebx)\n\t"
123 static unsigned int c_localcount_notsc(void)
128 gettimeofday(&tv
, 0);
129 return limit
*tv
.tv_usec
;
131 static void c_longcount_notsc(long long* z
)
134 unsigned long long result
;
138 gettimeofday(&tv
, 0);
141 result
+=limit
*tv
.tv_usec
;
144 static unsigned int localcount_stub(void);
145 static void longcount_stub(long long*);
146 static unsigned int (*localcount
)()=localcount_stub
;
147 static void (*longcount
)(long long*)=longcount_stub
;
149 static pthread_mutex_t memmut
;
151 static unsigned int localcount_stub(void)
153 unsigned int regs
[4];
155 if ((regs
[3] & 0x00000010) != 0)
157 localcount
=c_localcount_tsc
;
158 longcount
=c_longcount_tsc
;
162 localcount
=c_localcount_notsc
;
163 longcount
=c_longcount_notsc
;
167 static void longcount_stub(long long* z
)
169 unsigned int regs
[4];
171 if ((regs
[3] & 0x00000010) != 0)
173 localcount
=c_localcount_tsc
;
174 longcount
=c_longcount_tsc
;
178 localcount
=c_localcount_notsc
;
179 longcount
=c_longcount_notsc
;
185 int LOADER_DEBUG
=1; // active only if compiled with -DDETAILED_OUT
186 //#define DETAILED_OUT
187 static inline void dbgprintf(char* fmt
, ...)
195 f
=fopen("./log", "a");
200 vfprintf(f
, fmt
, va
);
207 if ( mp_msg_test(MSGT_WIN32
,MSGL_DBG3
) )
213 // mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va);
220 char export_names
[300][32]={
225 //#define min(x,y) ((x)<(y)?(x):(y))
227 void destroy_event(void* event
);
230 typedef struct th_list_t
{
233 struct th_list_t
* next
;
234 struct th_list_t
* prev
;
238 // have to be cleared by GARBAGE COLLECTOR
239 //static unsigned char* heap=NULL;
240 //static int heap_counter=0;
241 static tls_t
* g_tls
=NULL
;
242 static th_list
* list
=NULL
;
245 static void test_heap(void)
250 while(offset
<heap_counter
)
252 if(*(int*)(heap
+offset
)!=0x433476)
254 printf("Heap corruption at address %d\n", offset
);
257 offset
+=8+*(int*)(heap
+offset
+4);
259 for(;offset
<min(offset
+1000, 20000000); offset
++)
260 if(heap
[offset
]!=0xCC)
262 printf("Free heap corruption at address %d\n", offset
);
270 static void* my_mreq(int size
, int to_zero
)
274 if(test
%10==0)printf("Memory: %d bytes allocated\n", heap_counter
);
278 heap
=malloc(20000000);
279 memset(heap
, 0xCC,20000000);
283 printf("No enough memory\n");
286 if(heap_counter
+size
>20000000)
288 printf("No enough memory\n");
291 *(int*)(heap
+heap_counter
)=0x433476;
293 *(int*)(heap
+heap_counter
)=size
;
295 printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size
, heap_counter
-8, heap_counter
, heap_counter
+size
);
297 memset(heap
+heap_counter
, 0, size
);
299 memset(heap
+heap_counter
, 0xcc, size
); // make crash reproducable
301 return heap
+heap_counter
-size
;
303 static int my_release(char* memory
)
308 printf("ERROR: free(0)\n");
311 if(*(int*)(memory
-8)!=0x433476)
313 printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
316 printf("Freed %d bytes of memory\n", *(int*)(memory
-4));
317 // memset(memory-8, *(int*)(memory-4), 0xCC);
323 typedef struct alloc_header_t alloc_header
;
324 struct alloc_header_t
326 // let's keep allocated data 16 byte aligned
338 static alloc_header
* last_alloc
= NULL
;
339 static int alccnt
= 0;
342 #define AREATYPE_CLIENT 0
343 #define AREATYPE_EVENT 1
344 #define AREATYPE_MUTEX 2
345 #define AREATYPE_COND 3
346 #define AREATYPE_CRITSECT 4
348 /* -- critical sections -- */
352 pthread_mutex_t mutex
;
357 void* mreq_private(int size
, int to_zero
, int type
);
358 void* mreq_private(int size
, int to_zero
, int type
)
360 int nsize
= size
+ sizeof(alloc_header
);
361 alloc_header
* header
= malloc(nsize
);
365 memset(header
, 0, nsize
);
369 pthread_mutex_init(&memmut
, NULL
);
370 pthread_mutex_lock(&memmut
);
374 pthread_mutex_lock(&memmut
);
375 last_alloc
->next
= header
; /* set next */
378 header
->prev
= last_alloc
;
382 pthread_mutex_unlock(&memmut
);
384 header
->deadbeef
= 0xdeadbeef;
388 //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt);
392 static int my_release(void* memory
)
394 alloc_header
* header
= (alloc_header
*) memory
- 1;
396 alloc_header
* prevmem
;
397 alloc_header
* nextmem
;
402 if (header
->deadbeef
!= (long) 0xdeadbeef)
404 dbgprintf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
408 pthread_mutex_lock(&memmut
);
413 destroy_event(memory
);
416 pthread_cond_destroy((pthread_cond_t
*)memory
);
419 pthread_mutex_destroy((pthread_mutex_t
*)memory
);
421 case AREATYPE_CRITSECT
:
422 pthread_mutex_destroy(&((struct CRITSECT
*)memory
)->mutex
);
425 //memset(memory, 0xcc, header->size);
429 header
->deadbeef
= 0;
430 prevmem
= header
->prev
;
431 nextmem
= header
->next
;
434 prevmem
->next
= nextmem
;
436 nextmem
->prev
= prevmem
;
438 if (header
== last_alloc
)
439 last_alloc
= prevmem
;
444 pthread_mutex_unlock(&memmut
);
446 pthread_mutex_destroy(&memmut
);
448 //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt);
453 //memset(header + 1, 0xcc, header->size);
459 static inline void* my_mreq(int size
, int to_zero
)
461 return mreq_private(size
, to_zero
, AREATYPE_CLIENT
);
464 static int my_size(void* memory
)
466 if(!memory
) return 0;
467 return ((alloc_header
*)memory
)[-1].size
;
470 static void* my_realloc(void* memory
, int size
)
475 return my_mreq(size
, 0);
476 osize
= my_size(memory
);
479 ans
= my_mreq(size
, 0);
480 memcpy(ans
, memory
, osize
);
488 * WINE API - native implementation for several win32 libraries
492 static int WINAPI
ext_unknown(void)
494 printf("Unknown func called\n");
498 static int WINAPI
expGetVolumeInformationA( const char *root
, char *label
,
499 unsigned int label_len
, unsigned int *serial
,
500 unsigned int *filename_len
,unsigned int *flags
,
501 char *fsname
, unsigned int fsname_len
)
503 dbgprintf("GetVolumeInformationA( %s, 0x%x, %ld, 0x%x, 0x%x, 0x%x, 0x%x, %ld) => 1\n",
504 root
,label
,label_len
,serial
,filename_len
,flags
,fsname
,fsname_len
);
505 //hack Do not return any real data - do nothing
509 static unsigned int WINAPI
expGetDriveTypeA( const char *root
)
511 dbgprintf("GetDriveTypeA( %s ) => %d\n",root
,DRIVE_FIXED
);
512 // hack return as Fixed Drive Type
516 static unsigned int WINAPI
expGetLogicalDriveStringsA( unsigned int len
, char *buffer
)
518 dbgprintf("GetLogicalDriveStringsA(%d, 0x%x) => 4\n",len
,buffer
);
519 // hack only have one drive c:\ in this hack
525 return 4; // 1 drive * 4 bytes (includes null)
529 static int WINAPI
expIsBadWritePtr(void* ptr
, unsigned int count
)
531 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
532 dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
535 static int WINAPI
expIsBadReadPtr(void* ptr
, unsigned int count
)
537 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
538 dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
541 static int WINAPI
expDisableThreadLibraryCalls(int module
)
543 dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module
);
547 static HMODULE WINAPI
expGetDriverModuleHandle(DRVR
* pdrv
)
553 result
=pdrv
->hDriverModule
;
554 dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv
, result
);
558 #define MODULE_HANDLE_kernel32 ((HMODULE)0x120)
559 #define MODULE_HANDLE_user32 ((HMODULE)0x121)
560 #ifdef CONFIG_QTX_CODECS
561 #define MODULE_HANDLE_wininet ((HMODULE)0x122)
562 #define MODULE_HANDLE_ddraw ((HMODULE)0x123)
563 #define MODULE_HANDLE_advapi32 ((HMODULE)0x124)
565 #define MODULE_HANDLE_comdlg32 ((HMODULE)0x125)
566 #define MODULE_HANDLE_msvcrt ((HMODULE)0x126)
567 #define MODULE_HANDLE_ole32 ((HMODULE)0x127)
568 #define MODULE_HANDLE_winmm ((HMODULE)0x128)
569 #define MODULE_HANDLE_psapi ((HMODULE)0x129)
571 static HMODULE WINAPI
expGetModuleHandleA(const char* name
)
576 #ifdef CONFIG_QTX_CODECS
583 wm
=MODULE_FindModule(name
);
586 result
=(HMODULE
)(wm
->module
);
590 if(name
&& (strcasecmp(name
, "kernel32")==0 || !strcasecmp(name
, "kernel32.dll")))
591 result
=MODULE_HANDLE_kernel32
;
592 #ifdef CONFIG_QTX_CODECS
593 if(name
&& strcasecmp(name
, "user32")==0)
594 result
=MODULE_HANDLE_user32
;
597 dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name
, result
);
601 static HMODULE WINAPI
expGetModuleHandleW(const uint16_t* name
)
606 if (*name
> 256 || pos
>= sizeof(aname
) - 1)
608 aname
[pos
++] = *name
++;
611 return expGetModuleHandleA(aname
);
614 static void* WINAPI
expCreateThread(void* pSecAttr
, long dwStackSize
,
615 void* lpStartAddress
, void* lpParameter
,
616 long dwFlags
, long* dwThreadId
)
619 // printf("CreateThread:");
620 pth
= (pthread_t
*) my_mreq(sizeof(pthread_t
), 0);
621 pthread_create(pth
, NULL
, (void*(*)(void*))lpStartAddress
, lpParameter
);
623 printf( "WARNING: CreateThread flags not supported\n");
625 *dwThreadId
=(long)pth
;
628 list
=my_mreq(sizeof(th_list
), 1);
629 list
->next
=list
->prev
=NULL
;
633 list
->next
=my_mreq(sizeof(th_list
), 0);
634 list
->next
->prev
=list
;
635 list
->next
->next
=NULL
;
639 dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
640 pSecAttr
, dwStackSize
, lpStartAddress
, lpParameter
, dwFlags
, dwThreadId
, pth
);
655 struct mutex_list_t
* next
;
656 struct mutex_list_t
* prev
;
658 typedef struct mutex_list_t mutex_list
;
659 static mutex_list
* mlist
=NULL
;
661 void destroy_event(void* event
)
663 mutex_list
* pp
=mlist
;
664 // printf("garbage collector: destroy_event(%x)\n", event);
667 if(pp
==(mutex_list
*)event
)
670 pp
->next
->prev
=pp
->prev
;
672 pp
->prev
->next
=pp
->next
;
673 if(mlist
==(mutex_list
*)event
)
679 printf("%x => ", pp);
690 static void* WINAPI
expCreateEventA(void* pSecAttr
, char bManualReset
,
691 char bInitialState
, const char* name
)
700 printf("%x => ", pp);
707 mutex_list
* pp
=mlist
;
711 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==0))
713 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
714 pSecAttr
, bManualReset
, bInitialState
, name
, name
, pp
->pm
);
717 }while((pp
=pp
->prev
) != NULL
);
719 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
720 pthread_mutex_init(pm
, NULL
);
721 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
722 pthread_cond_init(pc
, NULL
);
725 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
726 mlist
->next
=mlist
->prev
=NULL
;
730 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
731 mlist
->next
->prev
=mlist
;
732 mlist
->next
->next
=NULL
;
735 mlist
->type
=0; /* Type Event */
738 mlist
->state
=bInitialState
;
739 mlist
->reset
=bManualReset
;
741 strncpy(mlist
->name
, name
, 127);
745 dbgprintf("ERROR::: CreateEventA failure\n");
748 pthread_mutex_lock(pm);
751 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
752 pSecAttr
, bManualReset
, bInitialState
, name
, name
, mlist
);
754 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
755 pSecAttr
, bManualReset
, bInitialState
, mlist
);
759 static void* WINAPI
expSetEvent(void* event
)
761 mutex_list
*ml
= (mutex_list
*)event
;
762 dbgprintf("SetEvent(%x) => 0x1\n", event
);
763 pthread_mutex_lock(ml
->pm
);
764 if (ml
->state
== 0) {
766 pthread_cond_signal(ml
->pc
);
768 pthread_mutex_unlock(ml
->pm
);
772 static void* WINAPI
expResetEvent(void* event
)
774 mutex_list
*ml
= (mutex_list
*)event
;
775 dbgprintf("ResetEvent(0x%x) => 0x1\n", event
);
776 pthread_mutex_lock(ml
->pm
);
778 pthread_mutex_unlock(ml
->pm
);
783 static void* WINAPI
expWaitForSingleObject(void* object
, int duration
)
785 mutex_list
*ml
= (mutex_list
*)object
;
786 // FIXME FIXME FIXME - this value is sometime unititialize !!!
787 int ret
= WAIT_FAILED
;
788 mutex_list
* pp
=mlist
;
789 if(object
== (void*)0xcfcf9898)
792 From GetCurrentThread() documentation:
793 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.
795 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.
797 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.
799 dbgprintf("WaitForSingleObject(thread_handle) called\n");
800 return (void*)WAIT_FAILED
;
802 dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object
, duration
);
804 // loop below was slightly fixed - its used just for checking if
805 // this object really exists in our list
808 while (pp
&& (pp
->pm
!= ml
->pm
))
811 dbgprintf("WaitForSingleObject: NotFound\n");
815 pthread_mutex_lock(ml
->pm
);
819 if (duration
== 0) { /* Check Only */
820 if (ml
->state
== 1) ret
= WAIT_FAILED
;
821 else ret
= WAIT_OBJECT_0
;
823 if (duration
== -1) { /* INFINITE */
825 pthread_cond_wait(ml
->pc
,ml
->pm
);
830 if (duration
> 0) { /* Timed Wait */
831 struct timespec abstime
;
833 gettimeofday(&now
, 0);
834 abstime
.tv_sec
= now
.tv_sec
+ (now
.tv_usec
+duration
)/1000000;
835 abstime
.tv_nsec
= ((now
.tv_usec
+duration
)%1000000)*1000;
837 ret
=pthread_cond_timedwait(ml
->pc
,ml
->pm
,&abstime
);
838 if (ret
== ETIMEDOUT
) ret
= WAIT_TIMEOUT
;
839 else ret
= WAIT_OBJECT_0
;
844 case 1: /* Semaphore */
846 if(ml
->semaphore
==0) ret
= WAIT_FAILED
;
852 if (duration
== -1) {
853 if (ml
->semaphore
==0)
854 pthread_cond_wait(ml
->pc
,ml
->pm
);
859 pthread_mutex_unlock(ml
->pm
);
861 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object
,duration
,ml
,ret
);
865 #ifdef CONFIG_QTX_CODECS
866 static void* WINAPI
expWaitForMultipleObjects(int count
, const void** objects
,
867 int WaitAll
, int duration
)
873 dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
874 count
, objects
, WaitAll
, duration
);
876 for (i
= 0; i
< count
; i
++)
878 object
= (void *)objects
[i
];
879 ret
= expWaitForSingleObject(object
, duration
);
881 dbgprintf("WaitAll flag not yet supported...\n");
888 static void WINAPI
expExitThread(int retcode
)
890 dbgprintf("ExitThread(%d)\n", retcode
);
891 pthread_exit(&retcode
);
894 static HANDLE WINAPI
expCreateMutexA(void *pSecAttr
,
895 char bInitialOwner
, const char *name
)
897 HANDLE mlist
= (HANDLE
)expCreateEventA(pSecAttr
, 0, 0, name
);
900 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
901 pSecAttr
, bInitialOwner
, name
, mlist
);
903 dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
904 pSecAttr
, bInitialOwner
, mlist
);
905 #ifndef CONFIG_QTX_CODECS
906 /* 10l to QTX, if CreateMutex returns a real mutex, WaitForSingleObject
907 waits for ever, else it works ;) */
912 static int WINAPI
expReleaseMutex(HANDLE hMutex
)
914 dbgprintf("ReleaseMutex(%x) => 1\n", hMutex
);
915 /* FIXME:XXX !! not yet implemented */
920 static int pf_set
= 0;
921 static BYTE PF
[64] = {0,};
923 static void DumpSystemInfo(const SYSTEM_INFO
* si
)
925 dbgprintf(" Processor architecture %d\n", si
->u
.s
.wProcessorArchitecture
);
926 dbgprintf(" Page size: %d\n", si
->dwPageSize
);
927 dbgprintf(" Minimum app address: %d\n", si
->lpMinimumApplicationAddress
);
928 dbgprintf(" Maximum app address: %d\n", si
->lpMaximumApplicationAddress
);
929 dbgprintf(" Active processor mask: 0x%x\n", si
->dwActiveProcessorMask
);
930 dbgprintf(" Number of processors: %d\n", si
->dwNumberOfProcessors
);
931 dbgprintf(" Processor type: 0x%x\n", si
->dwProcessorType
);
932 dbgprintf(" Allocation granularity: 0x%x\n", si
->dwAllocationGranularity
);
933 dbgprintf(" Processor level: 0x%x\n", si
->wProcessorLevel
);
934 dbgprintf(" Processor revision: 0x%x\n", si
->wProcessorRevision
);
937 static void WINAPI
expGetSystemInfo(SYSTEM_INFO
* si
)
939 /* FIXME: better values for the two entries below... */
940 static int cache
= 0;
941 static SYSTEM_INFO cachedsi
;
942 dbgprintf("GetSystemInfo(%p) =>\n", si
);
947 memset(PF
,0,sizeof(PF
));
950 cachedsi
.u
.s
.wProcessorArchitecture
= PROCESSOR_ARCHITECTURE_INTEL
;
951 cachedsi
.dwPageSize
= getpagesize();
953 /* FIXME: better values for the two entries below... */
954 cachedsi
.lpMinimumApplicationAddress
= (void *)0x00000000;
955 cachedsi
.lpMaximumApplicationAddress
= (void *)0x7FFFFFFF;
956 cachedsi
.dwActiveProcessorMask
= 1;
957 cachedsi
.dwNumberOfProcessors
= 1;
958 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
959 cachedsi
.dwAllocationGranularity
= 0x10000;
960 cachedsi
.wProcessorLevel
= 5; /* pentium */
961 cachedsi
.wProcessorRevision
= 0x0101;
963 /* mplayer's way to detect PF's */
965 #include "cpudetect.h"
968 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
970 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
971 if (gCpuCaps
.hasSSE2
)
972 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
973 if (gCpuCaps
.has3DNow
)
974 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
976 if (gCpuCaps
.cpuType
== 4)
978 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
979 cachedsi
.wProcessorLevel
= 4;
981 else if (gCpuCaps
.cpuType
>= 5)
983 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
984 cachedsi
.wProcessorLevel
= 5;
988 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
989 cachedsi
.wProcessorLevel
= 3;
991 cachedsi
.wProcessorRevision
= gCpuCaps
.cpuStepping
;
992 cachedsi
.dwNumberOfProcessors
= 1; /* hardcoded */
995 /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
996 fdiv_bug and fpu emulation flags -- alex/MPlayer */
1001 FILE *f
= fopen ("/proc/cpuinfo", "r");
1005 mp_msg(MSGT_WIN32
, MSGL_WARN
, "expGetSystemInfo: "
1006 "/proc/cpuinfo not readable! "
1007 "Expect bad performance and/or weird behaviour\n");
1010 while (fgets(line
,200,f
)!=NULL
) {
1013 /* NOTE: the ':' is the only character we can rely on */
1014 if (!(value
= strchr(line
,':')))
1016 /* terminate the valuename */
1018 /* skip any leading spaces */
1019 while (*value
==' ') value
++;
1020 if ((s
=strchr(value
,'\n')))
1024 if (!lstrncmpiA(line
, "cpu family",strlen("cpu family"))) {
1025 if (isdigit (value
[0])) {
1026 switch (value
[0] - '0') {
1027 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1028 cachedsi
.wProcessorLevel
= 3;
1030 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1031 cachedsi
.wProcessorLevel
= 4;
1033 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1034 cachedsi
.wProcessorLevel
= 5;
1036 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1037 cachedsi
.wProcessorLevel
= 5;
1039 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1040 cachedsi
.wProcessorLevel
= 5;
1044 /* set the CPU type of the current processor */
1045 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1048 /* old 2.0 method */
1049 if (!lstrncmpiA(line
, "cpu",strlen("cpu"))) {
1050 if ( isdigit (value
[0]) && value
[1] == '8' &&
1051 value
[2] == '6' && value
[3] == 0
1053 switch (value
[0] - '0') {
1054 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1055 cachedsi
.wProcessorLevel
= 3;
1057 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1058 cachedsi
.wProcessorLevel
= 4;
1060 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1061 cachedsi
.wProcessorLevel
= 5;
1063 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1064 cachedsi
.wProcessorLevel
= 5;
1066 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1067 cachedsi
.wProcessorLevel
= 5;
1071 /* set the CPU type of the current processor */
1072 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1075 if (!lstrncmpiA(line
,"fdiv_bug",strlen("fdiv_bug"))) {
1076 if (!lstrncmpiA(value
,"yes",3))
1077 PF
[PF_FLOATING_POINT_PRECISION_ERRATA
] = TRUE
;
1081 if (!lstrncmpiA(line
,"fpu",strlen("fpu"))) {
1082 if (!lstrncmpiA(value
,"no",2))
1083 PF
[PF_FLOATING_POINT_EMULATED
] = TRUE
;
1087 if (!lstrncmpiA(line
,"processor",strlen("processor"))) {
1088 /* processor number counts up...*/
1091 if (sscanf(value
,"%d",&x
))
1092 if (x
+1>cachedsi
.dwNumberOfProcessors
)
1093 cachedsi
.dwNumberOfProcessors
=x
+1;
1095 /* Create a new processor subkey on a multiprocessor
1098 sprintf(buf
,"%d",x
);
1100 if (!lstrncmpiA(line
,"stepping",strlen("stepping"))) {
1103 if (sscanf(value
,"%d",&x
))
1104 cachedsi
.wProcessorRevision
= x
;
1107 ( (!lstrncmpiA(line
,"flags",strlen("flags")))
1108 || (!lstrncmpiA(line
,"features",strlen("features"))) )
1110 if (strstr(value
,"cx8"))
1111 PF
[PF_COMPARE_EXCHANGE_DOUBLE
] = TRUE
;
1112 if (strstr(value
,"mmx"))
1113 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1114 if (strstr(value
,"tsc"))
1115 PF
[PF_RDTSC_INSTRUCTION_AVAILABLE
] = TRUE
;
1116 if (strstr(value
,"xmm") || strstr(value
,"sse"))
1117 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1118 if (strstr(value
,"sse2"))
1119 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1120 if (strstr(value
,"3dnow"))
1121 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1126 * ad hoc fix for smp machines.
1127 * some problems on WaitForSingleObject,CreateEvent,SetEvent
1128 * CreateThread ...etc..
1131 cachedsi
.dwNumberOfProcessors
=1;
1133 #endif /* __linux__ */
1136 memcpy(si
,&cachedsi
,sizeof(*si
));
1140 // avoid undefined expGetSystemInfo
1141 static WIN_BOOL WINAPI
expIsProcessorFeaturePresent(DWORD v
)
1143 WIN_BOOL result
= 0;
1147 expGetSystemInfo(&si
);
1149 if(v
<64) result
=PF
[v
];
1150 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v
, result
);
1154 static WIN_BOOL WINAPI
expIsDebuggerPresent(void)
1159 static long WINAPI
expGetVersion(void)
1161 dbgprintf("GetVersion() => 0xC0000004\n");
1162 return 0xC0000004;//Windows 95
1165 static HANDLE WINAPI
expHeapCreate(long flags
, long init_size
, long max_size
)
1167 // printf("HeapCreate:");
1170 result
=(HANDLE
)my_mreq(0x110000, 0);
1172 result
=(HANDLE
)my_mreq((init_size
+ 0xfff) & 0x7ffff000 , 0);
1173 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags
, init_size
, max_size
, result
);
1177 // this is another dirty hack
1178 // VP31 is releasing one allocated Heap chunk twice
1179 // we will silently ignore this second call...
1180 static void* heapfreehack
= 0;
1181 static int heapfreehackshown
= 0;
1182 //void trapbug(void);
1183 static void* WINAPI
expHeapAlloc(HANDLE heap
, int flags
, int size
)
1187 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1188 HeapAlloc returns area larger than size argument :-/
1190 actually according to M$ Doc HeapCreate size should be rounded
1191 to page boundaries thus we should simulate this
1193 //if (size == 22276) trapbug();
1194 z
=my_mreq((size
+ 0xfff) & 0x7ffff000, (flags
& HEAP_ZERO_MEMORY
));
1196 printf("HeapAlloc failure\n");
1197 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap
, flags
, size
, z
);
1198 heapfreehack
= 0; // reset
1201 static long WINAPI
expHeapDestroy(void* heap
)
1203 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap
);
1208 static long WINAPI
expHeapFree(HANDLE heap
, DWORD dwFlags
, LPVOID lpMem
)
1210 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap
, dwFlags
, lpMem
);
1211 if (heapfreehack
!= lpMem
&& lpMem
!= (void*)0xffffffff
1212 && lpMem
!= (void*)0xbdbdbdbd)
1213 // 0xbdbdbdbd is for i263_drv.drv && libefence
1214 // it seems to be reading from relased memory
1215 // EF_PROTECT_FREE doens't show any probleme
1219 if (!heapfreehackshown
++)
1220 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem
);
1222 heapfreehack
= lpMem
;
1225 static long WINAPI
expHeapSize(int heap
, int flags
, void* pointer
)
1227 long result
=my_size(pointer
);
1228 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap
, flags
, pointer
, result
);
1231 static void* WINAPI
expHeapReAlloc(HANDLE heap
,int flags
,void *lpMem
,int size
)
1233 long orgsize
= my_size(lpMem
);
1234 dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize
,size
);
1235 return my_realloc(lpMem
, size
);
1237 static long WINAPI
expGetProcessHeap(void)
1239 dbgprintf("GetProcessHeap() => 1\n");
1242 static void* WINAPI
expVirtualAlloc(void* v1
, long v2
, long v3
, long v4
)
1244 void* z
= VirtualAlloc(v1
, v2
, v3
, v4
);
1246 printf("VirtualAlloc failure\n");
1247 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1
,v2
,v3
,v4
, z
);
1250 static int WINAPI
expVirtualFree(void* v1
, int v2
, int v3
)
1252 int result
= VirtualFree(v1
,v2
,v3
);
1253 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1
,v2
,v3
, result
);
1257 /* we're building a table of critical sections. cs_win pointer uses the DLL
1258 cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1259 struct critsecs_list_t
1261 CRITICAL_SECTION
*cs_win
;
1262 struct CRITSECT
*cs_unix
;
1265 /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1266 #undef CRITSECS_NEWTYPE
1267 //#define CRITSECS_NEWTYPE 1
1269 #ifdef CRITSECS_NEWTYPE
1270 /* increased due to ucod needs more than 32 entries */
1271 /* and 64 should be enough for everything */
1272 #define CRITSECS_LIST_MAX 64
1273 static struct critsecs_list_t critsecs_list
[CRITSECS_LIST_MAX
];
1275 static int critsecs_get_pos(CRITICAL_SECTION
*cs_win
)
1279 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1280 if (critsecs_list
[i
].cs_win
== cs_win
)
1285 static int critsecs_get_unused(void)
1289 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1290 if (critsecs_list
[i
].cs_win
== NULL
)
1295 struct CRITSECT
*critsecs_get_unix(CRITICAL_SECTION
*cs_win
)
1299 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1300 if (critsecs_list
[i
].cs_win
== cs_win
&& critsecs_list
[i
].cs_unix
)
1301 return critsecs_list
[i
].cs_unix
;
1306 static void WINAPI
expInitializeCriticalSection(CRITICAL_SECTION
* c
)
1308 dbgprintf("InitializeCriticalSection(0x%x)\n", c
);
1309 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1311 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1312 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1315 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1316 #ifdef CRITSECS_NEWTYPE
1318 struct CRITSECT
*cs
;
1319 int i
= critsecs_get_unused();
1323 printf("InitializeCriticalSection(%p) - no more space in list\n", c
);
1326 dbgprintf("got unused space at %d\n", i
);
1327 cs
= malloc(sizeof(struct CRITSECT
));
1330 printf("InitializeCriticalSection(%p) - out of memory\n", c
);
1333 pthread_mutex_init(&cs
->mutex
, NULL
);
1335 critsecs_list
[i
].cs_win
= c
;
1336 critsecs_list
[i
].cs_unix
= cs
;
1337 dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1342 struct CRITSECT
* cs
= mreq_private(sizeof(struct CRITSECT
) + sizeof(CRITICAL_SECTION
),
1343 0, AREATYPE_CRITSECT
);
1344 pthread_mutex_init(&cs
->mutex
, NULL
);
1346 cs
->deadbeef
= 0xdeadbeef;
1353 static void WINAPI
expInitializeCriticalSectionAndSpinCount(CRITICAL_SECTION
* c
, DWORD spin
)
1355 expInitializeCriticalSection(c
);
1358 static void WINAPI
expEnterCriticalSection(CRITICAL_SECTION
* c
)
1360 #ifdef CRITSECS_NEWTYPE
1361 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1363 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1365 dbgprintf("EnterCriticalSection(0x%x) %p\n",c
, cs
);
1368 dbgprintf("entered uninitialized critisec!\n");
1369 expInitializeCriticalSection(c
);
1370 #ifdef CRITSECS_NEWTYPE
1371 cs
=critsecs_get_unix(c
);
1373 cs
= (*(struct CRITSECT
**)c
);
1375 dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c
);
1378 if(cs
->id
==pthread_self())
1380 pthread_mutex_lock(&(cs
->mutex
));
1382 cs
->id
=pthread_self();
1385 static void WINAPI
expLeaveCriticalSection(CRITICAL_SECTION
* c
)
1387 #ifdef CRITSECS_NEWTYPE
1388 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1390 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1392 // struct CRITSECT* cs=(struct CRITSECT*)c;
1393 dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c
, cs
);
1396 dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c
);
1402 pthread_mutex_unlock(&(cs
->mutex
));
1405 dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c
);
1409 static void expfree(void* mem
); /* forward declaration */
1411 static void WINAPI
expDeleteCriticalSection(CRITICAL_SECTION
*c
)
1413 #ifdef CRITSECS_NEWTYPE
1414 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1416 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1418 // struct CRITSECT* cs=(struct CRITSECT*)c;
1419 dbgprintf("DeleteCriticalSection(0x%x)\n",c
);
1423 dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c
);
1429 dbgprintf("Win32 Warning: Deleting unlocked Critical Section %p!!\n", c
);
1430 pthread_mutex_unlock(&(cs
->mutex
));
1434 pthread_mutex_destroy(&(cs
->mutex
));
1435 // released by GarbageCollector in my_relase otherwise
1438 #ifdef CRITSECS_NEWTYPE
1440 int i
= critsecs_get_pos(c
);
1444 printf("DeleteCriticalSection(%p) error (critsec not found)\n", c
);
1448 critsecs_list
[i
].cs_win
= NULL
;
1449 expfree(critsecs_list
[i
].cs_unix
);
1450 critsecs_list
[i
].cs_unix
= NULL
;
1451 dbgprintf("DeleteCriticalSection -> itemno=%d\n", i
);
1456 static int WINAPI
expGetCurrentThreadId(void)
1458 dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1459 return pthread_self();
1461 static int WINAPI
expGetCurrentProcess(void)
1463 dbgprintf("GetCurrentProcess() => %d\n", getpid());
1467 #ifdef CONFIG_QTX_CODECS
1468 // this version is required for Quicktime codecs (.qtx/.qts) to work.
1469 // (they assume some pointers at FS: segment)
1471 extern void* fs_seg
;
1473 //static int tls_count;
1474 static int tls_use_map
[64];
1475 static int WINAPI
expTlsAlloc(void)
1479 if(tls_use_map
[i
]==0)
1482 dbgprintf("TlsAlloc() => %d\n",i
);
1485 dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1489 //static int WINAPI expTlsSetValue(DWORD index, void* value)
1490 static int WINAPI
expTlsSetValue(int index
, void* value
)
1492 dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index
,value
);
1493 // if((index<0) || (index>64))
1496 *(void**)((char*)fs_seg
+0x88+4*index
) = value
;
1500 static void* WINAPI
expTlsGetValue(DWORD index
)
1502 dbgprintf("TlsGetValue(%d)\n",index
);
1503 // if((index<0) || (index>64))
1504 if((index
>=64)) return NULL
;
1505 return *(void**)((char*)fs_seg
+0x88+4*index
);
1508 static int WINAPI
expTlsFree(int idx
)
1510 int index
= (int) idx
;
1511 dbgprintf("TlsFree(%d)\n",index
);
1512 if((index
<0) || (index
>64))
1514 tls_use_map
[index
]=0;
1526 static void* WINAPI
expTlsAlloc(void)
1530 g_tls
=my_mreq(sizeof(tls_t
), 0);
1531 g_tls
->next
=g_tls
->prev
=NULL
;
1535 g_tls
->next
=my_mreq(sizeof(tls_t
), 0);
1536 g_tls
->next
->prev
=g_tls
;
1537 g_tls
->next
->next
=NULL
;
1540 dbgprintf("TlsAlloc() => 0x%x\n", g_tls
);
1542 g_tls
->value
=0; /* XXX For Divx.dll */
1546 static int WINAPI
expTlsSetValue(void* idx
, void* value
)
1548 tls_t
* index
= (tls_t
*) idx
;
1557 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index
, value
, result
);
1560 static void* WINAPI
expTlsGetValue(void* idx
)
1562 tls_t
* index
= (tls_t
*) idx
;
1567 result
=index
->value
;
1568 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index
, result
);
1571 static int WINAPI
expTlsFree(void* idx
)
1573 tls_t
* index
= (tls_t
*) idx
;
1580 index
->next
->prev
=index
->prev
;
1582 index
->prev
->next
=index
->next
;
1584 g_tls
= index
->prev
;
1585 my_release((void*)index
);
1588 dbgprintf("TlsFree(index 0x%x) => %d\n", index
, result
);
1593 static void* WINAPI
expLocalAlloc(int flags
, int size
)
1595 void* z
= my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1597 printf("LocalAlloc() failed\n");
1598 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1602 static void* WINAPI
expLocalReAlloc(int handle
,int size
, int flags
)
1608 if (flags
& LMEM_MODIFY
) {
1609 dbgprintf("LocalReAlloc MODIFY\n");
1610 return (void *)handle
;
1612 oldsize
= my_size((void *)handle
);
1613 newpointer
= my_realloc((void *)handle
,size
);
1614 dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle
,size
,oldsize
, flags
,newpointer
);
1619 static void* WINAPI
expLocalLock(void* z
)
1621 dbgprintf("LocalLock(0x%x) => 0x%x\n", z
, z
);
1625 static void* WINAPI
expGlobalAlloc(int flags
, int size
)
1628 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size
, flags
);
1630 z
=my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1631 //z=calloc(size, 1);
1634 printf("GlobalAlloc() failed\n");
1635 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1638 static void* WINAPI
expGlobalLock(void* z
)
1640 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z
, z
);
1643 // pvmjpg20 - but doesn't work anyway
1644 static int WINAPI
expGlobalSize(void* amem
)
1648 alloc_header
* header
= last_alloc
;
1649 alloc_header
* mem
= (alloc_header
*) amem
- 1;
1652 pthread_mutex_lock(&memmut
);
1655 if (header
->deadbeef
!= 0xdeadbeef)
1657 dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
1663 size
= header
->size
;
1667 header
= header
->prev
;
1669 pthread_mutex_unlock(&memmut
);
1672 dbgprintf("GlobalSize(0x%x)\n", amem
);
1676 static int WINAPI
expLoadIconA( long hinstance
, char *name
)
1678 dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance
,name
);
1682 static int WINAPI
expLoadStringA(long instance
, long id
, void* buf
, long size
)
1684 int result
=LoadStringA(instance
, id
, buf
, size
);
1686 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1687 instance
, id
, buf
, size
, result
, buf
);
1689 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1690 // instance, id, buf, size, result);
1694 static long WINAPI
expMultiByteToWideChar(long v1
, long v2
, char* s1
, long siz1
, short* s2
, int siz2
)
1703 if(siz1
>siz2
/2)siz1
=siz2
/2;
1704 for(i
=1; i
<=siz1
; i
++)
1714 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1715 "size %d, dest buffer 0x%x, dest size %d) => %d\n",
1716 v1
, v2
, s1
, s1
, siz1
, s2
, siz2
, result
);
1718 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1719 "size %d, dest buffer 0x%x, dest size %d) =>\n",
1720 v1
, v2
, siz1
, s2
, siz2
, result
);
1723 static void wch_print(const short* str
)
1725 dbgprintf(" src: ");
1726 while(*str
)dbgprintf("%c", *str
++);
1729 static long WINAPI
expWideCharToMultiByte(long v1
, long v2
, short* s1
, long siz1
,
1730 char* s2
, int siz2
, char* c3
, int* siz3
)
1733 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1734 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1735 result
=WideCharToMultiByte(v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1736 dbgprintf("=> %d\n", result
);
1737 //if(s1)wch_print(s1);
1738 if(s2
)dbgprintf(" dest: %s\n", s2
);
1741 static long WINAPI
expGetVersionExA(OSVERSIONINFOA
* c
)
1743 dbgprintf("GetVersionExA(0x%x) => 1\n");
1744 c
->dwOSVersionInfoSize
=sizeof(*c
);
1745 c
->dwMajorVersion
=4;
1746 c
->dwMinorVersion
=0;
1747 c
->dwBuildNumber
=0x4000457;
1749 // leave it here for testing win9x-only codecs
1750 c
->dwPlatformId
=VER_PLATFORM_WIN32_WINDOWS
;
1751 strcpy(c
->szCSDVersion
, " B");
1753 c
->dwPlatformId
=VER_PLATFORM_WIN32_NT
; // let's not make DLL assume that it can read CR* registers
1754 strcpy(c
->szCSDVersion
, "Service Pack 3");
1756 dbgprintf(" Major version: 4\n Minor version: 0\n Build number: 0x4000457\n"
1757 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 3'\n");
1760 static HANDLE WINAPI
expCreateSemaphoreA(char* v1
, long init_count
,
1761 long max_count
, char* name
)
1763 pthread_mutex_t
*pm
;
1767 printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1771 printf("%p => ", pp);
1778 mutex_list
* pp
=mlist
;
1782 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==1))
1784 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1785 v1
, init_count
, max_count
, name
, name
, mlist
);
1786 return (HANDLE
)mlist
;
1788 }while((pp
=pp
->prev
) != NULL
);
1790 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
1791 pthread_mutex_init(pm
, NULL
);
1792 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
1793 pthread_cond_init(pc
, NULL
);
1796 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1797 mlist
->next
=mlist
->prev
=NULL
;
1801 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1802 mlist
->next
->prev
=mlist
;
1803 mlist
->next
->next
=NULL
;
1805 // printf("new semaphore %p\n", mlist);
1807 mlist
->type
=1; /* Type Semaphore */
1812 mlist
->semaphore
=init_count
;
1814 strncpy(mlist
->name
, name
, 64);
1818 dbgprintf("ERROR::: CreateSemaphoreA failure\n");
1820 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1821 v1
, init_count
, max_count
, name
, name
, mlist
);
1823 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1824 v1
, init_count
, max_count
, mlist
);
1825 return (HANDLE
)mlist
;
1828 static long WINAPI
expReleaseSemaphore(long hsem
, long increment
, long* prev_count
)
1830 // The state of a semaphore object is signaled when its count
1831 // is greater than zero and nonsignaled when its count is equal to zero
1832 // Each time a waiting thread is released because of the semaphore's signaled
1833 // state, the count of the semaphore is decreased by one.
1834 mutex_list
*ml
= (mutex_list
*)hsem
;
1836 pthread_mutex_lock(ml
->pm
);
1837 if (prev_count
!= 0) *prev_count
= ml
->semaphore
;
1838 if (ml
->semaphore
== 0) pthread_cond_signal(ml
->pc
);
1839 ml
->semaphore
+= increment
;
1840 pthread_mutex_unlock(ml
->pm
);
1841 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1842 hsem
, increment
, prev_count
);
1847 static long WINAPI
expRegOpenKeyExA(long key
, const char* subkey
, long reserved
, long access
, int* newkey
)
1849 long result
=RegOpenKeyExA(key
, subkey
, reserved
, access
, newkey
);
1850 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
1851 key
, subkey
, reserved
, access
, newkey
, result
);
1852 if(newkey
)dbgprintf(" New key: 0x%x\n", *newkey
);
1855 static long WINAPI
expRegCloseKey(long key
)
1857 long result
=RegCloseKey(key
);
1858 dbgprintf("RegCloseKey(0x%x) => %d\n", key
, result
);
1861 static long WINAPI
expRegQueryValueExA(long key
, const char* value
, int* reserved
, int* type
, int* data
, int* count
)
1863 long result
=RegQueryValueExA(key
, value
, reserved
, type
, data
, count
);
1864 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
1865 " => 0x%x\n", key
, value
, reserved
, data
, count
, result
);
1866 if(data
&& count
)dbgprintf(" read %d bytes: '%s'\n", *count
, data
);
1870 //from wine source dlls/advapi32/registry.c
1871 static long WINAPI
expRegCreateKeyA(long hkey
, const char* name
, int *retkey
)
1873 dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey
,name
,retkey
);
1874 return RegCreateKeyExA( hkey
, name
, 0, NULL
,REG_OPTION_NON_VOLATILE
,
1875 KEY_ALL_ACCESS
, NULL
, retkey
, NULL
);
1878 static long WINAPI
expRegCreateKeyExA(long key
, const char* name
, long reserved
,
1879 void* classs
, long options
, long security
,
1880 void* sec_attr
, int* newkey
, int* status
)
1882 long result
=RegCreateKeyExA(key
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
);
1883 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
1884 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
1885 key
, name
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
, result
);
1886 if(!result
&& newkey
) dbgprintf(" New key: 0x%x\n", *newkey
);
1887 if(!result
&& status
) dbgprintf(" New key status: 0x%x\n", *status
);
1890 static long WINAPI
expRegSetValueExA(long key
, const char* name
, long v1
, long v2
, void* data
, long size
)
1892 long result
=RegSetValueExA(key
, name
, v1
, v2
, data
, size
);
1893 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
1894 key
, name
, v1
, v2
, data
, *(int*)data
, data
, size
, result
);
1898 static long WINAPI
expRegOpenKeyA (long hKey
, LPCSTR lpSubKey
, int* phkResult
)
1900 long result
=RegOpenKeyExA(hKey
, lpSubKey
, 0, 0, phkResult
);
1901 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
1902 hKey
, lpSubKey
, phkResult
, result
);
1903 if(!result
&& phkResult
) dbgprintf(" New key: 0x%x\n", *phkResult
);
1907 static DWORD WINAPI
expRegEnumValueA(HKEY hkey
, DWORD index
, LPSTR value
, LPDWORD val_count
,
1908 LPDWORD reserved
, LPDWORD type
, LPBYTE data
, LPDWORD count
)
1910 return RegEnumValueA(hkey
, index
, value
, val_count
,
1911 reserved
, type
, data
, count
);
1914 static DWORD WINAPI
expRegEnumKeyExA(HKEY hKey
, DWORD dwIndex
, LPSTR lpName
, LPDWORD lpcbName
,
1915 LPDWORD lpReserved
, LPSTR lpClass
, LPDWORD lpcbClass
,
1916 LPFILETIME lpftLastWriteTime
)
1918 return RegEnumKeyExA(hKey
, dwIndex
, lpName
, lpcbName
, lpReserved
, lpClass
,
1919 lpcbClass
, lpftLastWriteTime
);
1922 static long WINAPI
expQueryPerformanceCounter(long long* z
)
1925 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z
, *z
);
1930 * dummy function RegQueryInfoKeyA(), required by vss codecs
1932 static DWORD WINAPI
expRegQueryInfoKeyA( HKEY hkey
, LPSTR
class, LPDWORD class_len
, LPDWORD reserved
,
1933 LPDWORD subkeys
, LPDWORD max_subkey
, LPDWORD max_class
,
1934 LPDWORD values
, LPDWORD max_value
, LPDWORD max_data
,
1935 LPDWORD security
, FILETIME
*modif
)
1937 return ERROR_SUCCESS
;
1941 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
1943 static double linux_cpuinfo_freq(void)
1950 f
= fopen ("/proc/cpuinfo", "r");
1952 while (fgets(line
,sizeof(line
),f
)!=NULL
) {
1953 /* NOTE: the ':' is the only character we can rely on */
1954 if (!(value
= strchr(line
,':')))
1956 /* terminate the valuename */
1958 /* skip any leading spaces */
1959 while (*value
==' ') value
++;
1960 if ((s
=strchr(value
,'\n')))
1963 if (!strncasecmp(line
, "cpu MHz",strlen("cpu MHz"))
1964 && sscanf(value
, "%lf", &freq
) == 1) {
1975 static double solaris_kstat_freq(void)
1977 #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
1979 * try to extract the CPU speed from the solaris kernel's kstat data
1983 kstat_named_t
*kdata
;
1989 ksp
= kstat_lookup(kc
, "cpu_info", 0, "cpu_info0");
1991 /* kstat found and name/value pairs? */
1992 if (ksp
!= NULL
&& ksp
->ks_type
== KSTAT_TYPE_NAMED
)
1994 /* read the kstat data from the kernel */
1995 if (kstat_read(kc
, ksp
, NULL
) != -1)
1998 * lookup desired "clock_MHz" entry, check the expected
2001 kdata
= (kstat_named_t
*)kstat_data_lookup(ksp
, "clock_MHz");
2002 if (kdata
!= NULL
&& kdata
->data_type
== KSTAT_DATA_INT32
)
2003 mhz
= kdata
->value
.i32
;
2011 #endif /* HAVE_LIBKSTAT */
2012 return -1; // kstat stuff is not available, CPU freq is unknown
2016 * Measure CPU freq using the pentium's time stamp counter register (TSC)
2018 static double tsc_freq(void)
2020 static double ofreq
=0.0;
2024 if (ofreq
!= 0.0) return ofreq
;
2025 while(i
==time(NULL
));
2028 while(i
==time(NULL
));
2030 ofreq
= (double)(y
-x
)/1000.;
2034 static double CPU_Freq(void)
2038 if ((freq
= linux_cpuinfo_freq()) > 0)
2041 if ((freq
= solaris_kstat_freq()) > 0)
2047 static long WINAPI
expQueryPerformanceFrequency(long long* z
)
2049 *z
=(long long)CPU_Freq();
2050 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z
, *z
);
2053 static long WINAPI
exptimeGetTime(void)
2057 gettimeofday(&t
, 0);
2058 result
=1000*t
.tv_sec
+t
.tv_usec
/1000;
2059 dbgprintf("timeGetTime() => %d\n", result
);
2062 static void* WINAPI
expLocalHandle(void* v
)
2064 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v
, v
);
2068 static void* WINAPI
expGlobalHandle(void* v
)
2070 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v
, v
);
2073 static int WINAPI
expGlobalUnlock(void* v
)
2075 dbgprintf("GlobalUnlock(0x%x) => 1\n", v
);
2078 static void* WINAPI
expGlobalFree(void* v
)
2080 dbgprintf("GlobalFree(0x%x) => 0\n", v
);
2086 static void* WINAPI
expGlobalReAlloc(void* v
, int size
, int flags
)
2088 void* result
=my_realloc(v
, size
);
2089 //void* result=realloc(v, size);
2090 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v
,size
,flags
,result
);
2094 static int WINAPI
expLocalUnlock(void* v
)
2096 dbgprintf("LocalUnlock(0x%x) => 1\n", v
);
2100 static void* WINAPI
expLocalFree(void* v
)
2102 dbgprintf("LocalFree(0x%x) => 0\n", v
);
2106 static HRSRC WINAPI
expFindResourceA(HMODULE module
, char* name
, char* type
)
2110 result
=FindResourceA(module
, name
, type
);
2111 dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2112 module
, name
, HIWORD(name
) ? name
: "UNICODE", type
, HIWORD(type
) ? type
: "UNICODE", result
);
2116 static HGLOBAL WINAPI
expLoadResource(HMODULE module
, HRSRC res
)
2118 HGLOBAL result
=LoadResource(module
, res
);
2119 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module
, res
, result
);
2122 static void* WINAPI
expLockResource(long res
)
2124 void* result
=LockResource(res
);
2125 dbgprintf("LockResource(0x%x) => 0x%x\n", res
, result
);
2128 static int WINAPI
expFreeResource(long res
)
2130 int result
=FreeResource(res
);
2131 dbgprintf("FreeResource(0x%x) => %d\n", res
, result
);
2136 static int WINAPI
expCloseHandle(long v1
)
2138 dbgprintf("CloseHandle(0x%x) => 1\n", v1
);
2139 /* do not close stdin,stdout and stderr */
2146 static const char* WINAPI
expGetCommandLineA(void)
2148 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2149 return "c:\\aviplay.exe";
2151 static short envs
[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2152 static LPWSTR WINAPI
expGetEnvironmentStringsW(void)
2154 dbgprintf("GetEnvironmentStringsW() => 0\n", envs
);
2157 static void * WINAPI
expRtlZeroMemory(void *p
, size_t len
)
2159 void* result
=memset(p
,0,len
);
2160 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p
,len
,result
);
2163 static void * WINAPI
expRtlMoveMemory(void *dst
, void *src
, size_t len
)
2165 void* result
=memmove(dst
,src
,len
);
2166 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst
,src
,len
,result
);
2170 static void * WINAPI
expRtlFillMemory(void *p
, int ch
, size_t len
)
2172 void* result
=memset(p
,ch
,len
);
2173 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p
,ch
,len
,result
);
2176 static int WINAPI
expFreeEnvironmentStringsW(short* strings
)
2178 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings
);
2181 static int WINAPI
expFreeEnvironmentStringsA(char* strings
)
2183 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings
);
2187 static const char ch_envs
[]=
2188 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2189 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2190 static LPCSTR WINAPI
expGetEnvironmentStrings(void)
2192 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs
);
2193 return (LPCSTR
)ch_envs
;
2194 // dbgprintf("GetEnvironmentStrings() => 0\n");
2198 static int WINAPI
expGetStartupInfoA(STARTUPINFOA
*s
)
2200 dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2201 memset(s
, 0, sizeof(*s
));
2203 // s->lpReserved="Reserved";
2204 // s->lpDesktop="Desktop";
2205 // s->lpTitle="Title";
2207 // s->dwXSize=s->dwYSize=200;
2208 s
->dwFlags
=s
->wShowWindow
=1;
2209 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2210 dbgprintf(" cb=%d\n", s
->cb
);
2211 dbgprintf(" lpReserved='%s'\n", s
->lpReserved
);
2212 dbgprintf(" lpDesktop='%s'\n", s
->lpDesktop
);
2213 dbgprintf(" lpTitle='%s'\n", s
->lpTitle
);
2214 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2215 s
->dwX
, s
->dwY
, s
->dwXSize
, s
->dwYSize
);
2216 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2217 s
->dwXCountChars
, s
->dwYCountChars
, s
->dwFillAttribute
);
2218 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2219 s
->dwFlags
, s
->wShowWindow
, s
->cbReserved2
);
2220 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2221 s
->lpReserved2
, s
->hStdInput
, s
->hStdOutput
, s
->hStdError
);
2225 static int WINAPI
expGetStdHandle(int z
)
2227 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z
+0x1234);
2231 #ifdef CONFIG_QTX_CODECS
2232 #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2233 #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2236 static int WINAPI
expGetFileType(int handle
)
2238 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle
);
2241 #ifdef CONFIG_QTX_CODECS
2242 static int WINAPI
expGetFileAttributesA(char *filename
)
2244 dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename
);
2245 if (strstr(filename
, "QuickTime.qts"))
2246 return FILE_ATTRIBUTE_SYSTEM
;
2247 return FILE_ATTRIBUTE_NORMAL
;
2250 static int WINAPI
expSetHandleCount(int count
)
2252 dbgprintf("SetHandleCount(0x%x) => 1\n", count
);
2255 static int WINAPI
expGetACP(void)
2257 dbgprintf("GetACP() => 0\n");
2260 static int WINAPI
expGetModuleFileNameA(int module
, char* s
, int len
)
2264 //printf("File name of module %X (%s) requested\n", module, s);
2266 if (module
== 0 && len
>= 12)
2268 /* return caller program name */
2269 strcpy(s
, "aviplay.dll");
2280 strcpy(s
, "c:\\windows\\system\\");
2281 mr
=MODULE32_LookupHMODULE(module
);
2283 strcat(s
, "aviplay.dll");
2285 if(strrchr(mr
->filename
, '/')==NULL
)
2286 strcat(s
, mr
->filename
);
2288 strcat(s
, strrchr(mr
->filename
, '/')+1);
2291 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2292 module
, s
, len
, result
);
2294 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2295 module
, s
, len
, result
, s
);
2299 static int WINAPI
expGetModuleBaseNameA(int process
, int module
, char* s
, int len
)
2304 av_strlcpy(s
, "aviplay.dll", len
);
2308 dbgprintf("GetModuleBaseNameA(0x%x, 0x%x, 0x%x, %d) => %d\n",
2309 process
, module
, s
, len
, result
);
2314 static int WINAPI
expSetUnhandledExceptionFilter(void* filter
)
2316 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter
);
2317 return 1;//unsupported and probably won't ever be supported
2320 static int WINAPI
expLoadLibraryA(char* name
)
2326 // we skip to the last backslash
2327 // this is effectively eliminating weird characters in
2328 // the text output windows
2330 lastbc
= strrchr(name
, '\\');
2337 name
[i
] = *lastbc
++;
2342 if(strncmp(name
, "c:\\windows\\", 11)==0) name
+= 11;
2343 if(strncmp(name
, ".\\", 2)==0) name
+= 2;
2345 dbgprintf("Entering LoadLibraryA(%s)\n", name
);
2347 // PIMJ and VIVO audio are loading kernel32.dll
2348 if (strcasecmp(name
, "kernel32.dll") == 0 || strcasecmp(name
, "kernel32") == 0)
2349 return MODULE_HANDLE_kernel32
;
2350 // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2351 /* exported -> do not return failed! */
2353 if (strcasecmp(name
, "user32.dll") == 0 || strcasecmp(name
, "user32") == 0)
2354 // return MODULE_HANDLE_kernel32;
2355 return MODULE_HANDLE_user32
;
2357 #ifdef CONFIG_QTX_CODECS
2358 if (strcasecmp(name
, "wininet.dll") == 0 || strcasecmp(name
, "wininet") == 0)
2359 return MODULE_HANDLE_wininet
;
2360 if (strcasecmp(name
, "ddraw.dll") == 0 || strcasecmp(name
, "ddraw") == 0)
2361 return MODULE_HANDLE_ddraw
;
2362 if (strcasecmp(name
, "advapi32.dll") == 0 || strcasecmp(name
, "advapi32") == 0)
2363 return MODULE_HANDLE_advapi32
;
2366 if (strcasecmp(name
, "comdlg32.dll") == 0 || strcasecmp(name
, "comdlg32") == 0)
2367 return MODULE_HANDLE_comdlg32
;
2368 if (strcasecmp(name
, "msvcrt.dll") == 0 || strcasecmp(name
, "msvcrt") == 0)
2369 return MODULE_HANDLE_msvcrt
;
2370 if (strcasecmp(name
, "ole32.dll") == 0 || strcasecmp(name
, "ole32") == 0)
2371 return MODULE_HANDLE_ole32
;
2372 if (strcasecmp(name
, "winmm.dll") == 0 || strcasecmp(name
, "winmm") == 0)
2373 return MODULE_HANDLE_winmm
;
2374 if (strcasecmp(name
, "psapi.dll") == 0 || strcasecmp(name
, "psapi") == 0)
2375 return MODULE_HANDLE_psapi
;
2377 result
=LoadLibraryA(name
);
2378 dbgprintf("Returned LoadLibraryA(0x%x='%s'), def_path=%s => 0x%x\n", name
, name
, def_path
, result
);
2383 static int WINAPI
expFreeLibrary(int module
)
2385 #ifdef CONFIG_QTX_CODECS
2386 int result
=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2388 int result
=FreeLibrary(module
);
2390 dbgprintf("FreeLibrary(0x%x) => %d\n", module
, result
);
2394 static void* WINAPI
expGetProcAddress(HMODULE mod
, char* name
)
2398 case MODULE_HANDLE_kernel32
:
2399 result
=LookupExternalByName("kernel32.dll", name
); break;
2400 case MODULE_HANDLE_user32
:
2401 result
=LookupExternalByName("user32.dll", name
); break;
2402 #ifdef CONFIG_QTX_CODECS
2403 case MODULE_HANDLE_wininet
:
2404 result
=LookupExternalByName("wininet.dll", name
); break;
2405 case MODULE_HANDLE_ddraw
:
2406 result
=LookupExternalByName("ddraw.dll", name
); break;
2407 case MODULE_HANDLE_advapi32
:
2408 result
=LookupExternalByName("advapi32.dll", name
); break;
2410 case MODULE_HANDLE_comdlg32
:
2411 result
=LookupExternalByName("comdlg32.dll", name
); break;
2412 case MODULE_HANDLE_msvcrt
:
2413 result
=LookupExternalByName("msvcrt.dll", name
); break;
2414 case MODULE_HANDLE_ole32
:
2415 result
=LookupExternalByName("ole32.dll", name
); break;
2416 case MODULE_HANDLE_winmm
:
2417 result
=LookupExternalByName("winmm.dll", name
); break;
2418 case MODULE_HANDLE_psapi
:
2419 result
=LookupExternalByName("psapi.dll", name
); break;
2421 result
=GetProcAddress(mod
, name
);
2423 if((unsigned int)name
> 0xffff)
2424 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod
, name
, result
);
2426 dbgprintf("GetProcAddress(0x%x, '%d') => 0x%x\n", mod
, (int)name
, result
);
2430 static long WINAPI
expCreateFileMappingA(int hFile
, void* lpAttr
,
2431 long flProtect
, long dwMaxHigh
,
2432 long dwMaxLow
, const char* name
)
2434 long result
=CreateFileMappingA(hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
);
2436 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2437 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2438 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, result
);
2440 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2441 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2442 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
, name
, result
);
2446 static long WINAPI
expOpenFileMappingA(long hFile
, long hz
, const char* name
)
2448 long result
=OpenFileMappingA(hFile
, hz
, name
);
2450 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2453 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2454 hFile
, hz
, name
, name
, result
);
2458 static void* WINAPI
expMapViewOfFile(HANDLE file
, DWORD mode
, DWORD offHigh
,
2459 DWORD offLow
, DWORD size
)
2461 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2462 file
,mode
,offHigh
,offLow
,size
,(char*)file
+offLow
);
2463 return (char*)file
+offLow
;
2466 static void* WINAPI
expUnmapViewOfFile(void* view
)
2468 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view
);
2472 static void* WINAPI
expSleep(int time
)
2475 /* solaris doesn't have thread safe usleep */
2476 struct timespec tsp
;
2477 tsp
.tv_sec
= time
/ 1000000;
2478 tsp
.tv_nsec
= (time
% 1000000) * 1000;
2479 nanosleep(&tsp
, NULL
);
2483 dbgprintf("Sleep(%d) => 0\n", time
);
2487 // why does IV32 codec want to call this? I don't know ...
2488 static int WINAPI
expCreateCompatibleDC(int hdc
)
2491 //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2492 dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc
, dc
);
2496 static int WINAPI
expGetDeviceCaps(int hdc
, int unk
)
2498 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc
, unk
);
2499 #ifdef CONFIG_QTX_CODECS
2500 #define BITSPIXEL 12
2502 if (unk
== BITSPIXEL
)
2510 static WIN_BOOL WINAPI
expDeleteDC(int hdc
)
2512 dbgprintf("DeleteDC(0x%x) => 0\n", hdc
);
2518 static WIN_BOOL WINAPI
expDeleteObject(int hdc
)
2520 dbgprintf("DeleteObject(0x%x) => 1\n", hdc
);
2521 /* FIXME - implement code here */
2525 /* btvvc32.drv wants this one */
2526 static void* WINAPI
expGetWindowDC(int hdc
)
2528 dbgprintf("GetWindowDC(%d) => 0x0\n", hdc
);
2532 #ifdef CONFIG_QTX_CODECS
2533 static int WINAPI
expGetWindowRect(HWND win
, RECT
*r
)
2535 dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win
, r
);
2536 /* (win == 0) => desktop */
2537 r
->right
= PSEUDO_SCREEN_WIDTH
;
2539 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
2544 static int WINAPI
expMonitorFromWindow(HWND win
, int flags
)
2546 dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win
, flags
);
2550 static int WINAPI
expMonitorFromRect(RECT
*r
, int flags
)
2552 dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r
, flags
);
2556 static int WINAPI
expMonitorFromPoint(void *p
, int flags
)
2558 dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p
, flags
);
2562 static int WINAPI
expEnumDisplayMonitors(void *dc
, RECT
*r
,
2563 int WINAPI (*callback_proc
)(), void *callback_param
)
2565 dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2566 dc
, r
, callback_proc
, callback_param
);
2567 return callback_proc(0, dc
, r
, callback_param
);
2571 typedef struct tagMONITORINFO
{
2576 } MONITORINFO
, *LPMONITORINFO
;
2579 #define CCHDEVICENAME 8
2580 typedef struct tagMONITORINFOEX
{
2585 TCHAR szDevice
[CCHDEVICENAME
];
2586 } MONITORINFOEX
, *LPMONITORINFOEX
;
2588 static int WINAPI
expGetMonitorInfoA(void *mon
, LPMONITORINFO lpmi
)
2590 dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon
, lpmi
);
2592 lpmi
->rcMonitor
.right
= lpmi
->rcWork
.right
= PSEUDO_SCREEN_WIDTH
;
2593 lpmi
->rcMonitor
.left
= lpmi
->rcWork
.left
= 0;
2594 lpmi
->rcMonitor
.bottom
= lpmi
->rcWork
.bottom
= PSEUDO_SCREEN_HEIGHT
;
2595 lpmi
->rcMonitor
.top
= lpmi
->rcWork
.top
= 0;
2597 lpmi
->dwFlags
= 1; /* primary monitor */
2599 if (lpmi
->cbSize
== sizeof(MONITORINFOEX
))
2601 LPMONITORINFOEX lpmiex
= (LPMONITORINFOEX
)lpmi
;
2602 dbgprintf("MONITORINFOEX!\n");
2603 strncpy(lpmiex
->szDevice
, "Monitor1", CCHDEVICENAME
);
2609 static int WINAPI
expEnumDisplayDevicesA(const char *device
, int devnum
,
2610 void *dispdev
, int flags
)
2612 dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2613 device
, device
, devnum
, dispdev
, flags
);
2617 static int WINAPI
expIsWindowVisible(HWND win
)
2619 dbgprintf("IsWindowVisible(0x%x) => 1\n", win
);
2623 static HWND WINAPI
expGetActiveWindow(void)
2625 dbgprintf("GetActiveWindow() => 0\n");
2629 static int WINAPI
expGetClassNameA(HWND win
, LPTSTR classname
, int maxcount
)
2631 strncat(classname
, "QuickTime", maxcount
);
2632 dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2633 win
, classname
, maxcount
, strlen(classname
));
2634 return strlen(classname
);
2637 #define LPWNDCLASS void *
2638 static int WINAPI
expGetClassInfoA(HINSTANCE inst
, LPCSTR classname
, LPWNDCLASS wndclass
)
2640 dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst
,
2641 classname
, classname
, wndclass
);
2645 static int WINAPI
expGetWindowLongA(HWND win
, int index
)
2647 dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win
, index
);
2651 static int WINAPI
expGetObjectA(HGDIOBJ hobj
, int objsize
, LPVOID obj
)
2653 dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj
, objsize
, obj
, objsize
);
2657 static int WINAPI
expCreateRectRgn(int x
, int y
, int width
, int height
)
2659 dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x
, y
, width
, height
);
2663 static int WINAPI
expEnumWindows(int (*callback_func
)(), void *callback_param
)
2666 dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func
, callback_param
);
2667 i
= callback_func(0, callback_param
);
2668 i2
= callback_func(1, callback_param
);
2672 static int WINAPI
expGetWindowThreadProcessId(HWND win
, int *pid_data
)
2674 int tid
= pthread_self();
2675 dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2676 win
, pid_data
, tid
);
2678 *(int*)pid_data
= tid
;
2682 //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2683 // INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2685 static HWND WINAPI
expCreateWindowExA(int exstyle
, const char *classname
,
2686 const char *winname
, int style
, int x
, int y
, int w
, int h
,
2687 HWND parent
, HMENU menu
, HINSTANCE inst
, LPVOID param
)
2689 printf("CreateWindowEx() called\n");
2690 dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2691 exstyle
, classname
, classname
, winname
, winname
, style
, x
, y
, w
, h
,
2692 parent
, menu
, inst
, param
);
2693 printf("CreateWindowEx() called okey\n");
2697 static int WINAPI
expwaveOutGetNumDevs(void)
2699 dbgprintf("waveOutGetNumDevs() => 0\n");
2705 * Returns the number of milliseconds, modulo 2^32, since the start
2706 * of the wineserver.
2708 static int WINAPI
expGetTickCount(void)
2710 static int tcstart
= 0;
2713 gettimeofday( &t
, NULL
);
2714 tc
= ((t
.tv_sec
* 1000) + (t
.tv_usec
/ 1000)) - tcstart
;
2720 dbgprintf("GetTickCount() => %d\n", tc
);
2724 static int WINAPI
expCreateFontA(void)
2726 dbgprintf("CreateFontA() => 0x0\n");
2730 /* tried to get pvmjpg work in a different way - no success */
2731 static int WINAPI
expDrawTextA(int hDC
, char* lpString
, int nCount
,
2732 LPRECT lpRect
, unsigned int uFormat
)
2734 dbgprintf("expDrawTextA(%p,...) => 8\n", hDC
);
2738 static int WINAPI
expGetPrivateProfileIntA(const char* appname
,
2739 const char* keyname
,
2741 const char* filename
)
2749 if(!(appname
&& keyname
&& filename
) )
2751 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, default_value
);
2752 return default_value
;
2754 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2755 strcpy(fullname
, "Software\\IniFileMapping\\");
2756 strcat(fullname
, appname
);
2757 strcat(fullname
, "\\");
2758 strcat(fullname
, keyname
);
2759 strcat(fullname
, "\\");
2760 strcat(fullname
, filename
);
2761 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)buffer
, &size
);
2762 if((size
>=0)&&(size
<256))
2764 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2767 result
=default_value
;
2769 result
=atoi(buffer
);
2770 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, result
);
2773 static int WINAPI
expGetProfileIntA(const char* appname
,
2774 const char* keyname
,
2777 dbgprintf("GetProfileIntA -> ");
2778 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, "default");
2781 static int WINAPI
expGetPrivateProfileStringA(const char* appname
,
2782 const char* keyname
,
2783 const char* def_val
,
2784 char* dest
, unsigned int len
,
2785 const char* filename
)
2790 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname
, keyname
, def_val
, dest
, len
, filename
);
2791 if(!(appname
&& keyname
&& filename
) ) return 0;
2792 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2793 strcpy(fullname
, "Software\\IniFileMapping\\");
2794 strcat(fullname
, appname
);
2795 strcat(fullname
, "\\");
2796 strcat(fullname
, keyname
);
2797 strcat(fullname
, "\\");
2798 strcat(fullname
, filename
);
2800 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)dest
, &size
);
2804 strncpy(dest
, def_val
, size
);
2805 if (strlen(def_val
)< size
) size
= strlen(def_val
);
2807 dbgprintf(" => %d ( '%s' )\n", size
, dest
);
2810 static int WINAPI
expWritePrivateProfileStringA(const char* appname
,
2811 const char* keyname
,
2813 const char* filename
)
2816 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname
, keyname
, string
, filename
);
2817 if(!(appname
&& keyname
&& filename
) )
2819 dbgprintf(" => -1\n");
2822 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2823 strcpy(fullname
, "Software\\IniFileMapping\\");
2824 strcat(fullname
, appname
);
2825 strcat(fullname
, "\\");
2826 strcat(fullname
, keyname
);
2827 strcat(fullname
, "\\");
2828 strcat(fullname
, filename
);
2829 RegSetValueExA(HKEY_LOCAL_MACHINE
, fullname
, 0, REG_SZ
, (int*)string
, strlen(string
));
2830 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
2831 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
2833 dbgprintf(" => 0\n");
2837 unsigned int GetPrivateProfileIntA_(const char* appname
, const char* keyname
, INT default_value
, const char* filename
)
2839 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, filename
);
2841 int GetPrivateProfileStringA_(const char* appname
, const char* keyname
,
2842 const char* def_val
, char* dest
, unsigned int len
, const char* filename
)
2844 return expGetPrivateProfileStringA(appname
, keyname
, def_val
, dest
, len
, filename
);
2846 int WritePrivateProfileStringA_(const char* appname
, const char* keyname
,
2847 const char* string
, const char* filename
)
2849 return expWritePrivateProfileStringA(appname
, keyname
, string
, filename
);
2854 static int WINAPI
expDefDriverProc(int private, int id
, int msg
, int arg1
, int arg2
)
2856 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", private, id
, msg
, arg1
, arg2
);
2860 static int WINAPI
expSizeofResource(int v1
, int v2
)
2862 int result
=SizeofResource(v1
, v2
);
2863 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1
, v2
, result
);
2867 static int WINAPI
expGetLastError(void)
2869 int result
=GetLastError();
2870 dbgprintf("GetLastError() => 0x%x\n", result
);
2874 static void WINAPI
expSetLastError(int error
)
2876 dbgprintf("SetLastError(0x%x)\n", error
);
2877 SetLastError(error
);
2880 static int WINAPI
expStringFromGUID2(GUID
* guid
, char* str
, int cbMax
)
2882 int result
=snprintf(str
, cbMax
, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
2883 guid
->f1
, guid
->f2
, guid
->f3
,
2884 (unsigned char)guid
->f4
[0], (unsigned char)guid
->f4
[1],
2885 (unsigned char)guid
->f4
[2], (unsigned char)guid
->f4
[3],
2886 (unsigned char)guid
->f4
[4], (unsigned char)guid
->f4
[5],
2887 (unsigned char)guid
->f4
[6], (unsigned char)guid
->f4
[7]);
2888 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid
, str
, str
, cbMax
, result
);
2893 static int WINAPI
expGetFileVersionInfoSizeA(const char* name
, int* lpHandle
)
2895 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name
, name
, lpHandle
);
2899 static int WINAPI
expIsBadStringPtrW(const short* string
, int nchars
)
2902 if(string
==0)result
=1; else result
=0;
2903 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string
, nchars
, result
);
2904 if(string
)wch_print(string
);
2907 static int WINAPI
expIsBadStringPtrA(const char* string
, int nchars
)
2909 return expIsBadStringPtrW((const short*)string
, nchars
);
2911 static long WINAPI
expInterlockedExchangeAdd( long* dest
, long incr
)
2916 "lock; xaddl %0,(%1)"
2918 : "r" (dest
), "0" (incr
)
2924 static long WINAPI
expInterlockedCompareExchange( unsigned long* dest
, unsigned long exchange
, unsigned long comperand
)
2926 unsigned long retval
= *dest
;
2927 if(*dest
== comperand
)
2932 static long WINAPI
expInterlockedIncrement( long* dest
)
2934 long result
=expInterlockedExchangeAdd( dest
, 1 ) + 1;
2935 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
2938 static long WINAPI
expInterlockedDecrement( long* dest
)
2940 long result
=expInterlockedExchangeAdd( dest
, -1 ) - 1;
2941 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
2945 static void WINAPI
expOutputDebugStringA( const char* string
)
2947 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string
);
2948 fprintf(stderr
, "DEBUG: %s\n", string
);
2951 static int WINAPI
expGetDC(int hwnd
)
2953 dbgprintf("GetDC(0x%x) => 1\n", hwnd
);
2957 static int WINAPI
expReleaseDC(int hwnd
, int hdc
)
2959 dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd
, hdc
);
2963 static int WINAPI
expGetDesktopWindow(void)
2965 dbgprintf("GetDesktopWindow() => 0\n");
2969 static int cursor
[100];
2971 static int WINAPI
expLoadCursorA(int handle
,LPCSTR name
)
2973 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle
, name
, (int)&cursor
[0]);
2974 return (int)&cursor
[0];
2976 static int WINAPI
expSetCursor(void *cursor
)
2978 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor
, cursor
);
2981 static int WINAPI
expGetCursorPos(void *cursor
)
2983 dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor
, cursor
);
2986 #ifdef CONFIG_QTX_CODECS
2987 static int show_cursor
= 0;
2988 static int WINAPI
expShowCursor(int show
)
2990 dbgprintf("ShowCursor(%d) => %d\n", show
, show
);
2998 static int WINAPI
expRegisterWindowMessageA(char *message
)
3000 dbgprintf("RegisterWindowMessageA(%s)\n", message
);
3003 static int WINAPI
expGetProcessVersion(int pid
)
3005 dbgprintf("GetProcessVersion(%d)\n", pid
);
3008 static int WINAPI
expGetCurrentThread(void)
3011 dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
3014 static int WINAPI
expGetOEMCP(void)
3016 dbgprintf("GetOEMCP()\n");
3019 static int WINAPI
expGetCPInfo(int cp
,void *info
)
3021 dbgprintf("GetCPInfo()\n");
3024 #ifdef CONFIG_QTX_CODECS
3025 #define SM_CXSCREEN 0
3026 #define SM_CYSCREEN 1
3027 #define SM_XVIRTUALSCREEN 76
3028 #define SM_YVIRTUALSCREEN 77
3029 #define SM_CXVIRTUALSCREEN 78
3030 #define SM_CYVIRTUALSCREEN 79
3031 #define SM_CMONITORS 80
3033 static int WINAPI
expGetSystemMetrics(int index
)
3035 dbgprintf("GetSystemMetrics(%d)\n", index
);
3036 #ifdef CONFIG_QTX_CODECS
3039 case SM_XVIRTUALSCREEN
:
3040 case SM_YVIRTUALSCREEN
:
3043 case SM_CXVIRTUALSCREEN
:
3044 return PSEUDO_SCREEN_WIDTH
;
3046 case SM_CYVIRTUALSCREEN
:
3047 return PSEUDO_SCREEN_HEIGHT
;
3054 static int WINAPI
expGetSysColor(int index
)
3056 dbgprintf("GetSysColor(%d) => 1\n", index
);
3059 static int WINAPI
expGetSysColorBrush(int index
)
3061 dbgprintf("GetSysColorBrush(%d)\n", index
);
3067 static int WINAPI
expGetSystemPaletteEntries(int hdc
, int iStartIndex
, int nEntries
, void* lppe
)
3069 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3070 hdc
, iStartIndex
, nEntries
, lppe
);
3075 typedef struct TIME_ZONE_INFORMATION {
3077 char StandardName[32];
3078 SYSTEMTIME StandardDate;
3080 char DaylightName[32];
3081 SYSTEMTIME DaylightDate;
3083 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3086 static int WINAPI
expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation
)
3088 const short name
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3089 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3090 const short pname
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3091 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3092 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3093 memset(lpTimeZoneInformation
, 0, sizeof(TIME_ZONE_INFORMATION
));
3094 lpTimeZoneInformation
->Bias
=360;//GMT-6
3095 memcpy(lpTimeZoneInformation
->StandardName
, name
, sizeof(name
));
3096 lpTimeZoneInformation
->StandardDate
.wMonth
=10;
3097 lpTimeZoneInformation
->StandardDate
.wDay
=5;
3098 lpTimeZoneInformation
->StandardDate
.wHour
=2;
3099 lpTimeZoneInformation
->StandardBias
=0;
3100 memcpy(lpTimeZoneInformation
->DaylightName
, pname
, sizeof(pname
));
3101 lpTimeZoneInformation
->DaylightDate
.wMonth
=4;
3102 lpTimeZoneInformation
->DaylightDate
.wDay
=1;
3103 lpTimeZoneInformation
->DaylightDate
.wHour
=2;
3104 lpTimeZoneInformation
->DaylightBias
=-60;
3105 return TIME_ZONE_ID_STANDARD
;
3108 static void WINAPI
expGetLocalTime(SYSTEMTIME
* systime
)
3111 struct tm
*local_tm
;
3114 dbgprintf("GetLocalTime(0x%x)\n");
3115 gettimeofday(&tv
, NULL
);
3116 local_time
=tv
.tv_sec
;
3117 local_tm
=localtime(&local_time
);
3119 systime
->wYear
= local_tm
->tm_year
+ 1900;
3120 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3121 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3122 systime
->wDay
= local_tm
->tm_mday
;
3123 systime
->wHour
= local_tm
->tm_hour
;
3124 systime
->wMinute
= local_tm
->tm_min
;
3125 systime
->wSecond
= local_tm
->tm_sec
;
3126 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3127 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3128 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3129 " Milliseconds: %d\n",
3130 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3131 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3134 static int WINAPI
expGetSystemTime(SYSTEMTIME
* systime
)
3137 struct tm
*local_tm
;
3140 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3141 gettimeofday(&tv
, NULL
);
3142 local_time
=tv
.tv_sec
;
3143 local_tm
=gmtime(&local_time
);
3145 systime
->wYear
= local_tm
->tm_year
+ 1900;
3146 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3147 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3148 systime
->wDay
= local_tm
->tm_mday
;
3149 systime
->wHour
= local_tm
->tm_hour
;
3150 systime
->wMinute
= local_tm
->tm_min
;
3151 systime
->wSecond
= local_tm
->tm_sec
;
3152 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3153 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3154 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3155 " Milliseconds: %d\n",
3156 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3157 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3161 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3162 static void WINAPI
expGetSystemTimeAsFileTime(FILETIME
* systime
)
3165 unsigned long long secs
;
3167 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3168 gettimeofday(&tv
, NULL
);
3169 secs
= (tv
.tv_sec
+ SECS_1601_TO_1970
) * 10000000;
3170 secs
+= tv
.tv_usec
* 10;
3171 systime
->dwLowDateTime
= secs
& 0xffffffff;
3172 systime
->dwHighDateTime
= (secs
>> 32);
3175 static int WINAPI
expGetEnvironmentVariableA(const char* name
, char* field
, int size
)
3178 // printf("%s %x %x\n", name, field, size);
3179 if(field
)field
[0]=0;
3182 if (p) strncpy(field,p,size);
3184 if (strcmp(name
,"__MSVCRT_HEAP_SELECT")==0)
3185 strcpy(field
,"__GLOBAL_HEAP_SELECTED,1");
3186 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name
, name
, field
, size
, strlen(field
));
3187 return strlen(field
);
3190 static int WINAPI
expSetEnvironmentVariableA(const char *name
, const char *value
)
3192 dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name
, value
);
3196 static void* WINAPI
expCoTaskMemAlloc(ULONG cb
)
3198 return my_mreq(cb
, 0);
3200 static void WINAPI
expCoTaskMemFree(void* cb
)
3208 void* CoTaskMemAlloc(unsigned long cb
)
3210 return expCoTaskMemAlloc(cb
);
3212 void CoTaskMemFree(void* cb
)
3214 expCoTaskMemFree(cb
);
3217 struct COM_OBJECT_INFO
3220 long (*GetClassObject
) (GUID
* clsid
, const GUID
* iid
, void** ppv
);
3223 static struct COM_OBJECT_INFO
* com_object_table
=0;
3224 static int com_object_size
=0;
3225 int RegisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3229 com_object_table
=realloc(com_object_table
, sizeof(struct COM_OBJECT_INFO
)*(++com_object_size
));
3230 com_object_table
[com_object_size
-1].clsid
=*clsid
;
3231 com_object_table
[com_object_size
-1].GetClassObject
=gcs
;
3235 int UnregisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3242 if (com_object_table
== 0)
3243 printf("Warning: UnregisterComClass() called without any registered class\n");
3244 while (i
< com_object_size
)
3248 memcpy(&com_object_table
[i
- 1].clsid
,
3249 &com_object_table
[i
].clsid
, sizeof(GUID
));
3250 com_object_table
[i
- 1].GetClassObject
=
3251 com_object_table
[i
].GetClassObject
;
3253 else if (memcmp(&com_object_table
[i
].clsid
, clsid
, sizeof(GUID
)) == 0
3254 && com_object_table
[i
].GetClassObject
== gcs
)
3262 if (--com_object_size
== 0)
3264 free(com_object_table
);
3265 com_object_table
= 0;
3272 const GUID IID_IUnknown
=
3274 0x00000000, 0x0000, 0x0000,
3275 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3277 const GUID IID_IClassFactory
=
3279 0x00000001, 0x0000, 0x0000,
3280 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3283 static long WINAPI
expCoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3284 long dwClsContext
, const GUID
* riid
, void** ppv
)
3287 struct COM_OBJECT_INFO
* ci
=0;
3288 for(i
=0; i
<com_object_size
; i
++)
3289 if(!memcmp(rclsid
, &com_object_table
[i
].clsid
, sizeof(GUID
)))
3290 ci
=&com_object_table
[i
];
3291 if(!ci
)return REGDB_E_CLASSNOTREG
;
3292 // in 'real' world we should mess with IClassFactory here
3293 i
=ci
->GetClassObject(rclsid
, riid
, ppv
);
3297 long CoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3298 long dwClsContext
, const GUID
* riid
, void** ppv
)
3300 return expCoCreateInstance(rclsid
, pUnkOuter
, dwClsContext
, riid
, ppv
);
3303 static int WINAPI
expIsRectEmpty(CONST RECT
*lprc
)
3310 w
= lprc
->right
- lprc
->left
;
3311 h
= lprc
->bottom
- lprc
->top
;
3312 if (w
<= 0 || h
<= 0)
3318 dbgprintf("IsRectEmpty(%p) => %s\n", lprc
, (r
) ? "TRUE" : "FALSE");
3319 //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3320 // return 0; // wmv9?
3324 static int _adjust_fdiv
=0; //what's this? - used to adjust division
3325 static int _winver
= 0x510; // windows version
3330 static unsigned int WINAPI
expGetTempPathA(unsigned int len
, char* path
)
3332 dbgprintf("GetTempPathA(%d, 0x%x)", len
, path
);
3335 dbgprintf(" => 0\n");
3338 strcpy(path
, "/tmp");
3339 dbgprintf(" => 5 ( '/tmp' )\n");
3346 DWORD dwFileAttributes;
3347 FILETIME ftCreationTime;
3348 FILETIME ftLastAccessTime;
3349 FILETIME ftLastWriteTime;
3350 DWORD nFileSizeHigh;
3354 CHAR cFileName[260];
3355 CHAR cAlternateFileName[14];
3356 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3359 static DIR* qtx_dir
=NULL
;
3361 static WIN_BOOL WINAPI
expFindNextFileA(HANDLE h
,LPWIN32_FIND_DATAA lpfd
)
3363 #ifdef CONFIG_QTX_CODECS
3364 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h
, lpfd
);
3365 if(h
==FILE_HANDLE_quicktimeqtx
){
3367 if(!qtx_dir
) return 0;
3368 while((d
=readdir(qtx_dir
))){
3369 char* x
=strrchr(d
->d_name
,'.');
3371 if(strcmp(x
,".qtx")) continue;
3372 strcpy(lpfd
->cFileName
,d
->d_name
);
3373 // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3374 strcpy(lpfd
->cAlternateFileName
,"foobar.qtx");
3375 dbgprintf("### FindNext: %s\n",lpfd
->cFileName
);
3378 closedir(qtx_dir
); qtx_dir
=NULL
;
3385 static HANDLE WINAPI
expFindFirstFileA(LPCSTR s
, LPWIN32_FIND_DATAA lpfd
)
3387 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s
, s
, lpfd
);
3388 // printf("\n### FindFirstFileA('%s')...\n",s);
3389 #ifdef CONFIG_QTX_CODECS
3390 if(strstr(s
, "quicktime\\*.QTX")){
3391 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s
, s
, lpfd
);
3392 dbgprintf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",def_path
);
3393 qtx_dir
=opendir(def_path
);
3394 if(!qtx_dir
) return (HANDLE
)-1;
3395 memset(lpfd
,0,sizeof(*lpfd
));
3396 if(expFindNextFileA(FILE_HANDLE_quicktimeqtx
,lpfd
))
3397 return FILE_HANDLE_quicktimeqtx
;
3398 printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",def_path
);
3402 if(strstr(s
, "QuickTime.qts")){
3403 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s
, s
, lpfd
);
3404 // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3405 // return (HANDLE)-1;
3406 strcpy(lpfd
->cFileName
, "QuickTime.qts");
3407 strcpy(lpfd
->cAlternateFileName
, "QuickT~1.qts");
3408 return FILE_HANDLE_quicktimeqts
;
3412 if(strstr(s
, "*.vwp")){
3413 // hack for VoxWare codec plugins:
3414 strcpy(lpfd
->cFileName
, "msms001.vwp");
3415 strcpy(lpfd
->cAlternateFileName
, "msms001.vwp");
3418 // return 'file not found'
3422 static WIN_BOOL WINAPI
expFindClose(HANDLE h
)
3424 dbgprintf("FindClose(0x%x) => 0\n", h
);
3425 #ifdef CONFIG_QTX_CODECS
3426 // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3427 // closedir(qtx_dir);
3433 static UINT WINAPI
expSetErrorMode(UINT i
)
3435 dbgprintf("SetErrorMode(%d) => 0\n", i
);
3438 static UINT WINAPI
expGetWindowsDirectoryA(LPSTR s
,UINT c
)
3440 char windir
[]="c:\\windows";
3442 strncpy(s
, windir
, c
);
3443 result
=1+((c
<strlen(windir
))?c
:strlen(windir
));
3444 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3447 #ifdef CONFIG_QTX_CODECS
3448 static UINT WINAPI
expGetCurrentDirectoryA(UINT c
, LPSTR s
)
3450 char curdir
[]="c:\\";
3452 strncpy(s
, curdir
, c
);
3453 result
=1+((c
<strlen(curdir
))?c
:strlen(curdir
));
3454 dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3458 static int WINAPI
expSetCurrentDirectoryA(const char *pathname
)
3460 dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname
, pathname
);
3462 if (strrchr(pathname
, '\\'))
3463 chdir(strcat(strrchr(pathname
, '\\')+1, '/'));
3470 static int WINAPI
expCreateDirectoryA(const char *pathname
, void *sa
)
3472 dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3473 pathname
, pathname
, sa
);
3475 p
= strrchr(pathname
, '\\')+1;
3476 strcpy(&buf
[0], p
); /* should be strncpy */
3483 if (strrchr(pathname
, '\\'))
3484 mkdir(strcat(strrchr(pathname
, '\\')+1, '/'), 666);
3486 mkdir(pathname
, 666);
3493 static WIN_BOOL WINAPI
expDeleteFileA(LPCSTR s
)
3495 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s
, s
);
3498 static WIN_BOOL WINAPI
expFileTimeToLocalFileTime(const FILETIME
* cpf
, LPFILETIME pf
)
3500 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf
, pf
);
3504 static UINT WINAPI
expGetTempFileNameA(LPCSTR cs1
,LPCSTR cs2
,UINT i
,LPSTR ps
)
3506 char mask
[16]="/tmp/AP_XXXXXX";
3508 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1
, cs1
, cs2
, cs2
, i
, ps
);
3511 dbgprintf(" => -1\n");
3514 result
=mkstemp(mask
);
3515 sprintf(ps
, "AP%d", result
);
3516 dbgprintf(" => %d\n", strlen(ps
));
3520 // This func might need proper implementation if we want AngelPotion codec.
3521 // They try to open APmpeg4v1.apl with it.
3522 // DLL will close opened file with CloseHandle().
3524 static HANDLE WINAPI
expCreateFileA(LPCSTR cs1
,DWORD i1
,DWORD i2
,
3525 LPSECURITY_ATTRIBUTES p1
, DWORD i3
,DWORD i4
,HANDLE i5
)
3527 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1
, cs1
, i1
,
3528 i2
, p1
, i3
, i4
, i5
);
3529 if((!cs1
) || (strlen(cs1
)<2))return -1;
3531 #ifdef CONFIG_QTX_CODECS
3532 if(strstr(cs1
, "QuickTime.qts"))
3535 char* tmp
=malloc(strlen(def_path
)+50);
3536 strcpy(tmp
, def_path
);
3538 strcat(tmp
, "QuickTime.qts");
3539 result
=open(tmp
, O_RDONLY
);
3543 if(strstr(cs1
, ".qtx"))
3546 char* tmp
=malloc(strlen(def_path
)+250);
3547 char* x
=strrchr(cs1
,'\\');
3548 sprintf(tmp
,"%s/%s",def_path
,x
?(x
+1):cs1
);
3549 // printf("### Open: %s -> %s\n",cs1,tmp);
3550 result
=open(tmp
, O_RDONLY
);
3556 if(strncmp(cs1
, "AP", 2) == 0)
3559 char* tmp
=malloc(strlen(def_path
)+50);
3560 strcpy(tmp
, def_path
);
3562 strcat(tmp
, "APmpg4v1.apl");
3563 result
=open(tmp
, O_RDONLY
);
3567 if (strstr(cs1
, "vp3") || strstr(cs1
, ".fpf"))
3571 char* tmp
=malloc(20 + strlen(cs1
));
3572 strcpy(tmp
, "/tmp/");
3577 if (tmp
[r
] == ':' || tmp
[r
] == '\\')
3581 if (GENERIC_READ
& i1
)
3583 else if (GENERIC_WRITE
& i1
)
3585 flg
|= O_WRONLY
| O_CREAT
;
3586 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp
, r
, flg
);
3588 r
=open(tmp
, flg
, S_IRWXU
);
3593 // Needed by wnvplay1.dll
3594 if (strstr(cs1
, "WINNOV.bmp"))
3597 r
=open("/dev/null", O_RDONLY
);
3602 /* we need this for some virtualdub filters */
3606 if (GENERIC_READ
& i1
)
3608 else if (GENERIC_WRITE
& i1
)
3611 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1
, r
, flg
);
3620 static UINT WINAPI
expGetSystemDirectoryA(
3621 char* lpBuffer
, // address of buffer for system directory
3622 UINT uSize
// size of directory buffer
3624 dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer
,uSize
);
3625 if(!lpBuffer
) strcpy(lpBuffer
,".");
3629 static char sysdir[]=".";
3630 static LPCSTR WINAPI expGetSystemDirectoryA(void)
3632 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3636 static DWORD WINAPI expGetFullPathNameA
3639 DWORD nBufferLength
,
3643 if(!lpFileName
) return 0;
3644 dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName
,nBufferLength
,
3645 lpBuffer
, lpFilePart
);
3647 #ifdef CONFIG_QTX_CODECS
3648 strcpy(lpFilePart
, "Quick123.qts");
3650 strcpy(lpFilePart
, lpFileName
);
3653 if (strrchr(lpFileName
, '\\'))
3654 lpFilePart
= strrchr(lpFileName
, '\\');
3656 lpFilePart
= (LPTSTR
)lpFileName
;
3658 strcpy(lpBuffer
, lpFileName
);
3659 // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3660 return strlen(lpBuffer
);
3663 static DWORD WINAPI expGetShortPathNameA
3669 if(!longpath
) return 0;
3670 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath
,shortpath
,shortlen
);
3671 strcpy(shortpath
,longpath
);
3672 return strlen(shortpath
);
3675 static WIN_BOOL WINAPI
expReadFile(HANDLE h
,LPVOID pv
,DWORD size
,LPDWORD rd
,LPOVERLAPPED unused
)
3678 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, rd
);
3679 result
=read(h
, pv
, size
);
3681 if(!result
)return 0;
3685 static WIN_BOOL WINAPI
expWriteFile(HANDLE h
,LPCVOID pv
,DWORD size
,LPDWORD wr
,LPOVERLAPPED unused
)
3688 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, wr
);
3690 result
=write(h
, pv
, size
);
3692 if(!result
)return 0;
3695 static DWORD WINAPI
expSetFilePointer(HANDLE h
, LONG val
, LPLONG ext
, DWORD whence
)
3698 dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h
, val
, ext
, ext
? *ext
: NULL
, whence
);
3699 //why would DLL want temporary file with >2Gb size?
3711 #ifdef CONFIG_QTX_CODECS
3712 if (val
== 0 && ext
!= 0)
3715 return lseek(h
, val
, wh
);
3718 static HDRVR WINAPI
expOpenDriverA(LPCSTR szDriverName
, LPCSTR szSectionName
,
3721 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3724 static HDRVR WINAPI
expOpenDriver(LPCSTR szDriverName
, LPCSTR szSectionName
,
3727 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3732 static WIN_BOOL WINAPI
expGetProcessAffinityMask(HANDLE hProcess
,
3733 LPDWORD lpProcessAffinityMask
,
3734 LPDWORD lpSystemAffinityMask
)
3736 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3737 hProcess
, lpProcessAffinityMask
, lpSystemAffinityMask
);
3738 if(lpProcessAffinityMask
)*lpProcessAffinityMask
=1;
3739 if(lpSystemAffinityMask
)*lpSystemAffinityMask
=1;
3743 // Fake implementation: does nothing, but does it right :)
3744 static WIN_BOOL WINAPI
expSetProcessAffinityMask(HANDLE hProcess
,
3745 LPDWORD dwProcessAffinityMask
)
3747 dbgprintf("SetProcessAffinityMask(0x%x, 0x%x) => 1\n",
3748 hProcess
, dwProcessAffinityMask
);
3753 static int WINAPI
expMulDiv(int nNumber
, int nNumerator
, int nDenominator
)
3755 static const long long max_int
=0x7FFFFFFFLL
;
3756 static const long long min_int
=-0x80000000LL
;
3757 long long tmp
=(long long)nNumber
*(long long)nNumerator
;
3758 dbgprintf("expMulDiv %d * %d / %d\n", nNumber
, nNumerator
, nDenominator
);
3759 if(!nDenominator
)return 1;
3761 if(tmp
<min_int
) return 1;
3762 if(tmp
>max_int
) return 1;
3766 static LONG WINAPI
explstrcmpiA(const char* str1
, const char* str2
)
3768 LONG result
=strcasecmp(str1
, str2
);
3769 dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
3773 static LONG WINAPI
explstrlenA(const char* str1
)
3775 LONG result
=strlen(str1
);
3776 dbgprintf("strlen(0x%x='%.50s') => %d\n", str1
, str1
, result
);
3780 static LONG WINAPI
explstrcpyA(char* str1
, const char* str2
)
3782 int result
= (int) strcpy(str1
, str2
);
3783 dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1
, str2
, str2
, result
);
3786 static LONG WINAPI
explstrcpynA(char* str1
, const char* str2
,int len
)
3789 if (strlen(str2
)>len
)
3790 result
= (int) strncpy(str1
, str2
,len
);
3792 result
= (int) strcpy(str1
,str2
);
3793 dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1
, str2
, str2
,len
, strlen(str2
),result
);
3796 static LONG WINAPI
explstrcatA(char* str1
, const char* str2
)
3798 int result
= (int) strcat(str1
, str2
);
3799 dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1
, str2
, str2
, result
);
3804 static LONG WINAPI
expInterlockedExchange(long *dest
, long l
)
3806 long retval
= *dest
;
3811 static void WINAPI
expInitCommonControls(void)
3813 dbgprintf("InitCommonControls called!\n");
3817 #ifdef CONFIG_QTX_CODECS
3818 /* needed by QuickTime.qts */
3819 static HWND WINAPI
expCreateUpDownControl (DWORD style
, INT x
, INT y
, INT cx
, INT cy
,
3820 HWND parent
, INT id
, HINSTANCE inst
,
3821 HWND buddy
, INT maxVal
, INT minVal
, INT curVal
)
3823 dbgprintf("CreateUpDownControl(...)\n");
3828 /* alex: implement this call! needed for 3ivx */
3829 static HRESULT WINAPI
expCoCreateFreeThreadedMarshaler(void *pUnkOuter
, void **ppUnkInner
)
3831 dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
3832 pUnkOuter
, ppUnkInner
);
3834 return ERROR_CALL_NOT_IMPLEMENTED
;
3838 static int WINAPI
expDuplicateHandle(HANDLE hSourceProcessHandle
, // handle to source process
3839 HANDLE hSourceHandle
, // handle to duplicate
3840 HANDLE hTargetProcessHandle
, // handle to target process
3841 HANDLE
* lpTargetHandle
, // duplicate handle
3842 DWORD dwDesiredAccess
, // requested access
3843 int bInheritHandle
, // handle inheritance option
3844 DWORD dwOptions
// optional actions
3847 dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
3848 hSourceProcessHandle
, hSourceHandle
, hTargetProcessHandle
,
3849 lpTargetHandle
, dwDesiredAccess
, bInheritHandle
, dwOptions
);
3850 *lpTargetHandle
= hSourceHandle
;
3854 static HRESULT WINAPI
expCoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
3856 dbgprintf("CoInitializeEx(%p, %d) called\n", lpReserved
, dwCoInit
);
3860 // required by PIM1 codec (used by win98 PCTV Studio capture sw)
3861 static HRESULT WINAPI
expCoInitialize(
3862 LPVOID lpReserved
/* [in] pointer to win32 malloc interface
3863 (obsolete, should be NULL) */
3867 * Just delegate to the newer method.
3869 return expCoInitializeEx(lpReserved
, COINIT_APARTMENTTHREADED
);
3872 static void WINAPI
expCoUninitialize(void)
3874 dbgprintf("CoUninitialize() called\n");
3877 /* allow static linking */
3878 HRESULT WINAPI
CoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
3880 return expCoInitializeEx(lpReserved
, dwCoInit
);
3882 HRESULT WINAPI
CoInitialize(LPVOID lpReserved
)
3884 return expCoInitialize(lpReserved
);
3886 void WINAPI
CoUninitialize(void)
3888 expCoUninitialize();
3891 static DWORD WINAPI expSetThreadAffinityMask
3894 DWORD dwThreadAffinityMask
3900 * no WINAPI functions - CDECL
3902 static void* expmalloc(int size
)
3905 // return malloc(size);
3906 void* result
=my_mreq(size
,0);
3907 dbgprintf("malloc(0x%x) => 0x%x\n", size
,result
);
3909 printf("WARNING: malloc() failed\n");
3912 static void expfree(void* mem
)
3914 // return free(mem);
3915 dbgprintf("free(%p)\n", mem
);
3918 /* needed by atrac3.acm */
3919 static void *expcalloc(int num
, int size
)
3921 void* result
=my_mreq(num
*size
,1);
3922 dbgprintf("calloc(%d,%d) => %p\n", num
,size
,result
);
3924 printf("WARNING: calloc() failed\n");
3927 static void* expnew(int size
)
3929 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
3930 // printf("%08x %08x %08x %08x\n",
3931 // size, *(1+(int*)&size),
3932 // *(2+(int*)&size),*(3+(int*)&size));
3936 result
=my_mreq(size
,0);
3937 dbgprintf("new(%d) => %p\n", size
, result
);
3939 printf("WARNING: new() failed\n");
3943 static int expdelete(void* memory
)
3945 dbgprintf("delete(%p)\n", memory
);
3951 * local definition - we need only the last two members at this point
3952 * otherwice we would have to introduce here GUIDs and some more types..
3954 typedef struct __attribute__((__packed__
))
3957 unsigned long cbFormat
; //0x40
3958 char* pbFormat
; //0x44
3960 static HRESULT WINAPI
expMoCopyMediaType(MY_MEDIA_TYPE
* dest
, const MY_MEDIA_TYPE
* src
)
3964 memcpy(dest
, src
, sizeof(MY_MEDIA_TYPE
));
3967 dest
->pbFormat
= (char*) my_mreq(dest
->cbFormat
, 0);
3968 if (!dest
->pbFormat
)
3969 return E_OUTOFMEMORY
;
3970 memcpy(dest
->pbFormat
, src
->pbFormat
, dest
->cbFormat
);
3974 static HRESULT WINAPI
expMoInitMediaType(MY_MEDIA_TYPE
* dest
, DWORD cbFormat
)
3978 memset(dest
, 0, sizeof(MY_MEDIA_TYPE
));
3981 dest
->pbFormat
= (char*) my_mreq(cbFormat
, 0);
3982 if (!dest
->pbFormat
)
3983 return E_OUTOFMEMORY
;
3987 static HRESULT WINAPI
expMoCreateMediaType(MY_MEDIA_TYPE
** dest
, DWORD cbFormat
)
3991 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
3992 return expMoInitMediaType(*dest
, cbFormat
);
3994 static HRESULT WINAPI
expMoDuplicateMediaType(MY_MEDIA_TYPE
** dest
, const void* src
)
3998 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
3999 return expMoCopyMediaType(*dest
, src
);
4001 static HRESULT WINAPI
expMoFreeMediaType(MY_MEDIA_TYPE
* dest
)
4007 my_release(dest
->pbFormat
);
4013 static HRESULT WINAPI
expMoDeleteMediaType(MY_MEDIA_TYPE
* dest
)
4017 expMoFreeMediaType(dest
);
4022 static int exp_snprintf( char *str
, int size
, const char *format
, ... )
4026 va_start(va
, format
);
4027 x
=snprintf(str
,size
,format
,va
);
4028 dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str
,size
,format
,x
);
4034 static int exp_initterm(int v1
, int v2
)
4036 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1
, v2
);
4040 /* merged from wine - 2002.04.21 */
4041 typedef void (*INITTERMFUNC
)();
4042 static int exp_initterm(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
4044 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start
, end
, *start
);
4049 //printf("call _initfunc: from: %p %d\n", *start);
4050 // ok this trick with push/pop is necessary as otherwice
4051 // edi/esi registers are being trashed
4070 //printf("done %p %d:%d\n", end);
4078 /* Fake _initterm_e from msvcr80.dll, needed by sirenacm.dll
4079 * NOTE: If I make this an alias for _initterm, then sirenacm.dll tries to call
4080 other uninmplemented functions; keep this in mind if some future codec needs
4081 a real implementation of this function */
4082 static int exp_initterm_e(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
4084 dbgprintf("_initterm_e(0x%x, 0x%x)\n", start
, end
);
4088 static void* exp__dllonexit(void)
4090 // FIXME extract from WINE
4094 static int expwsprintfA(char* string
, const char* format
, ...)
4098 va_start(va
, format
);
4099 result
= vsprintf(string
, format
, va
);
4100 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string
, format
, result
);
4105 static int expsprintf(char* str
, const char* format
, ...)
4109 dbgprintf("sprintf(0x%x, %s)\n", str
, format
);
4110 va_start(args
, format
);
4111 r
= vsprintf(str
, format
, args
);
4115 static int expsscanf(const char* str
, const char* format
, ...)
4119 dbgprintf("sscanf(%s, %s)\n", str
, format
);
4120 va_start(args
, format
);
4121 r
= vsscanf(str
, format
, args
);
4125 static void* expfopen(const char* path
, const char* mode
)
4127 printf("fopen: \"%s\" mode:%s\n", path
, mode
);
4128 //return fopen(path, mode);
4129 return fdopen(0, mode
); // everything on screen
4131 static int expfprintf(void* stream
, const char* format
, ...)
4135 dbgprintf("fprintf(%p, %s, ...)\n", stream
, format
);
4136 va_start(args
, format
);
4137 r
= vfprintf((FILE*) stream
, format
, args
);
4142 static int expprintf(const char* format
, ...)
4146 dbgprintf("printf(%s, ...)\n", format
);
4147 va_start(args
, format
);
4148 r
= vprintf(format
, args
);
4153 static char* expgetenv(const char* varname
)
4155 char* v
= getenv(varname
);
4156 dbgprintf("getenv(%s) => %s\n", varname
, v
);
4160 static void* expwcscpy(WCHAR
* dst
, const WCHAR
* src
)
4163 while ((*p
++ = *src
++))
4168 static char* expstrrchr(char* string
, int value
)
4170 char* result
=strrchr(string
, value
);
4172 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4174 dbgprintf("strrchr(0x%x='%s', %d) => 0", string
, string
, value
);
4178 static char* expstrchr(char* string
, int value
)
4180 char* result
=strchr(string
, value
);
4182 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4184 dbgprintf("strchr(0x%x='%s', %d) => 0", string
, string
, value
);
4187 static int expstrlen(char* str
)
4189 int result
=strlen(str
);
4190 dbgprintf("strlen(0x%x='%s') => %d\n", str
, str
, result
);
4193 static char* expstrcpy(char* str1
, const char* str2
)
4195 char* result
= strcpy(str1
, str2
);
4196 dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1
, str2
, str2
, result
);
4199 static char* expstrncpy(char* str1
, const char* str2
, size_t count
)
4201 char* result
= strncpy(str1
, str2
, count
);
4202 dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1
, str2
, str2
, count
, result
);
4205 static int expstrcmp(const char* str1
, const char* str2
)
4207 int result
=strcmp(str1
, str2
);
4208 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4211 static int expstrncmp(const char* str1
, const char* str2
,int x
)
4213 int result
=strncmp(str1
, str2
,x
);
4214 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4217 static char* expstrcat(char* str1
, const char* str2
)
4219 char* result
= strcat(str1
, str2
);
4220 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1
, str1
, str2
, str2
, result
);
4223 static char* exp_strdup(const char* str1
)
4225 int l
= strlen(str1
);
4226 char* result
= (char*) my_mreq(l
+ 1,0);
4228 strcpy(result
, str1
);
4229 dbgprintf("_strdup(0x%x='%s') => %p\n", str1
, str1
, result
);
4232 static int expisalnum(int c
)
4234 int result
= (int) isalnum(c
);
4235 dbgprintf("isalnum(0x%x='%c' => %d\n", c
, c
, result
);
4238 static int expisspace(int c
)
4240 int result
= (int) isspace(c
);
4241 dbgprintf("isspace(0x%x='%c' => %d\n", c
, c
, result
);
4244 static int expisalpha(int c
)
4246 int result
= (int) isalpha(c
);
4247 dbgprintf("isalpha(0x%x='%c' => %d\n", c
, c
, result
);
4250 static int expisdigit(int c
)
4252 int result
= (int) isdigit(c
);
4253 dbgprintf("isdigit(0x%x='%c' => %d\n", c
, c
, result
);
4256 static void* expmemmove(void* dest
, void* src
, int n
)
4258 void* result
= memmove(dest
, src
, n
);
4259 dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4262 static int expmemcmp(void* dest
, void* src
, int n
)
4264 int result
= memcmp(dest
, src
, n
);
4265 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest
, src
, n
, result
);
4268 static void* expmemcpy(void* dest
, void* src
, int n
)
4270 void *result
= memcpy(dest
, src
, n
);
4271 dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4274 static void* expmemset(void* dest
, int c
, size_t n
)
4276 void *result
= memset(dest
, c
, n
);
4277 dbgprintf("memset(0x%x, %d, %d) => %p\n", dest
, c
, n
, result
);
4280 static time_t exptime(time_t* t
)
4282 time_t result
= time(t
);
4283 dbgprintf("time(0x%x) => %d\n", t
, result
);
4287 static int exprand(void)
4292 static void expsrand(int seed
)
4299 // preferred compilation with -O2 -ffast-math !
4301 static double explog10(double x
)
4303 /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4307 static double expcos(double x
)
4309 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4315 static void explog10(void)
4326 static void expcos(void)
4337 // this seem to be the only how to make this function working properly
4338 // ok - I've spent tremendous amount of time (many many many hours
4339 // of debuging fixing & testing - it's almost unimaginable - kabi
4341 // _ftol - operated on the float value which is already on the FPU stack
4343 static void exp_ftol(void)
4347 "sub $12, %esp \n\t"
4348 "fstcw -2(%ebp) \n\t"
4350 "movw -2(%ebp), %ax \n\t"
4351 "orb $0x0C, %ah \n\t"
4352 "movw %ax, -4(%ebp) \n\t"
4353 "fldcw -4(%ebp) \n\t"
4354 "fistpl -12(%ebp) \n\t"
4355 "fldcw -2(%ebp) \n\t"
4356 "movl -12(%ebp), %eax \n\t"
4357 //Note: gcc 3.03 does not do the following op if it
4358 // knows that ebp=esp
4359 "movl %ebp, %esp \n\t"
4363 #define FPU_DOUBLES(var1,var2) double var1,var2; \
4364 __asm__ volatile( "fstpl %0;fwait" : "=m" (var2) : ); \
4365 __asm__ volatile( "fstpl %0;fwait" : "=m" (var1) : )
4367 static double exp_CIpow(void)
4371 dbgprintf("_CIpow(%lf, %lf)\n", x
, y
);
4375 static double exppow(double x
, double y
)
4377 /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4381 static double expldexp(double x
, int expo
)
4383 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4384 return ldexp(x
, expo
);
4387 static double expfrexp(double x
, int* expo
)
4389 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4390 return frexp(x
, expo
);
4395 static int exp_stricmp(const char* s1
, const char* s2
)
4397 return strcasecmp(s1
, s2
);
4400 /* from declaration taken from Wine sources - this fountion seems to be
4401 * undocumented in any M$ doc */
4402 static int exp_setjmp3(void* jmpbuf
, int x
)
4404 //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4408 //"mov 4(%%esp), %%edx \n\t"
4409 "mov (%%esp), %%eax \n\t"
4410 "mov %%eax, (%%edx) \n\t" // store ebp
4412 //"mov %%ebp, (%%edx) \n\t"
4413 "mov %%ebx, 4(%%edx) \n\t"
4414 "mov %%edi, 8(%%edx) \n\t"
4415 "mov %%esi, 12(%%edx) \n\t"
4416 "mov %%esp, 16(%%edx) \n\t"
4418 "mov 4(%%esp), %%eax \n\t"
4419 "mov %%eax, 20(%%edx) \n\t"
4421 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4422 "movl $0, 36(%%edx) \n\t"
4424 : "d"(jmpbuf
) // input
4429 "mov %%fs:0, %%eax \n\t" // unsure
4430 "mov %%eax, 24(%%edx) \n\t"
4431 "cmp $0xffffffff, %%eax \n\t"
4433 "mov %%eax, 28(%%edx) \n\t"
4443 static DWORD WINAPI
expGetCurrentProcessId(void)
4445 dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4446 return getpid(); //(DWORD)NtCurrentTeb()->pid;
4453 } TIMECAPS
, *LPTIMECAPS
;
4455 static MMRESULT WINAPI
exptimeGetDevCaps(LPTIMECAPS lpCaps
, UINT wSize
)
4457 dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps
, wSize
);
4459 lpCaps
->wPeriodMin
= 1;
4460 lpCaps
->wPeriodMax
= 65535;
4464 static MMRESULT WINAPI
exptimeBeginPeriod(UINT wPeriod
)
4466 dbgprintf("timeBeginPeriod(%u) !\n", wPeriod
);
4468 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4472 #ifdef CONFIG_QTX_CODECS
4473 static MMRESULT WINAPI
exptimeEndPeriod(UINT wPeriod
)
4475 dbgprintf("timeEndPeriod(%u) !\n", wPeriod
);
4477 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4482 static void WINAPI
expGlobalMemoryStatus(
4483 LPMEMORYSTATUS lpmem
4485 static MEMORYSTATUS cached_memstatus
;
4486 static int cache_lastchecked
= 0;
4490 if (time(NULL
)==cache_lastchecked
) {
4491 memcpy(lpmem
,&cached_memstatus
,sizeof(MEMORYSTATUS
));
4495 f
= fopen( "/proc/meminfo", "r" );
4499 int total
, used
, free
, shared
, buffers
, cached
;
4501 lpmem
->dwLength
= sizeof(MEMORYSTATUS
);
4502 lpmem
->dwTotalPhys
= lpmem
->dwAvailPhys
= 0;
4503 lpmem
->dwTotalPageFile
= lpmem
->dwAvailPageFile
= 0;
4504 while (fgets( buffer
, sizeof(buffer
), f
))
4506 /* old style /proc/meminfo ... */
4507 if (sscanf( buffer
, "Mem: %d %d %d %d %d %d", &total
, &used
, &free
, &shared
, &buffers
, &cached
))
4509 lpmem
->dwTotalPhys
+= total
;
4510 lpmem
->dwAvailPhys
+= free
+ buffers
+ cached
;
4512 if (sscanf( buffer
, "Swap: %d %d %d", &total
, &used
, &free
))
4514 lpmem
->dwTotalPageFile
+= total
;
4515 lpmem
->dwAvailPageFile
+= free
;
4518 /* new style /proc/meminfo ... */
4519 if (sscanf(buffer
, "MemTotal: %d", &total
))
4520 lpmem
->dwTotalPhys
= total
*1024;
4521 if (sscanf(buffer
, "MemFree: %d", &free
))
4522 lpmem
->dwAvailPhys
= free
*1024;
4523 if (sscanf(buffer
, "SwapTotal: %d", &total
))
4524 lpmem
->dwTotalPageFile
= total
*1024;
4525 if (sscanf(buffer
, "SwapFree: %d", &free
))
4526 lpmem
->dwAvailPageFile
= free
*1024;
4527 if (sscanf(buffer
, "Buffers: %d", &buffers
))
4528 lpmem
->dwAvailPhys
+= buffers
*1024;
4529 if (sscanf(buffer
, "Cached: %d", &cached
))
4530 lpmem
->dwAvailPhys
+= cached
*1024;
4534 if (lpmem
->dwTotalPhys
)
4536 DWORD TotalPhysical
= lpmem
->dwTotalPhys
+lpmem
->dwTotalPageFile
;
4537 DWORD AvailPhysical
= lpmem
->dwAvailPhys
+lpmem
->dwAvailPageFile
;
4538 lpmem
->dwMemoryLoad
= (TotalPhysical
-AvailPhysical
)
4539 / (TotalPhysical
/ 100);
4543 /* FIXME: should do something for other systems */
4544 lpmem
->dwMemoryLoad
= 0;
4545 lpmem
->dwTotalPhys
= 16*1024*1024;
4546 lpmem
->dwAvailPhys
= 16*1024*1024;
4547 lpmem
->dwTotalPageFile
= 16*1024*1024;
4548 lpmem
->dwAvailPageFile
= 16*1024*1024;
4550 expGetSystemInfo(&si
);
4551 lpmem
->dwTotalVirtual
= si
.lpMaximumApplicationAddress
-si
.lpMinimumApplicationAddress
;
4552 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4553 lpmem
->dwAvailVirtual
= lpmem
->dwTotalVirtual
-64*1024;
4554 memcpy(&cached_memstatus
,lpmem
,sizeof(MEMORYSTATUS
));
4555 cache_lastchecked
= time(NULL
);
4557 /* it appears some memory display programs want to divide by these values */
4558 if(lpmem
->dwTotalPageFile
==0)
4559 lpmem
->dwTotalPageFile
++;
4561 if(lpmem
->dwAvailPageFile
==0)
4562 lpmem
->dwAvailPageFile
++;
4565 static INT WINAPI
expGetThreadPriority(HANDLE hthread
)
4567 dbgprintf("GetThreadPriority(%p)\n",hthread
);
4571 /**********************************************************************
4572 * SetThreadPriority [KERNEL32.@] Sets priority for thread.
4578 static WIN_BOOL WINAPI
expSetThreadPriority(
4579 HANDLE hthread
, /* [in] Handle to thread */
4580 INT priority
) /* [in] Thread priority level */
4582 dbgprintf("SetThreadPriority(%p,%d)\n",hthread
,priority
);
4586 static void WINAPI
expTerminateProcess( DWORD process
, DWORD status
)
4588 printf("EXIT - process %ld code %ld\n", process
, status
);
4592 static void WINAPI
expExitProcess( DWORD status
)
4594 printf("EXIT - code %ld\n",status
);
4598 static INT WINAPI
expMessageBoxA(HWND hWnd
, LPCSTR text
, LPCSTR title
, UINT type
){
4599 printf("MSGBOX '%s' '%s' (%d)\n",text
,title
,type
);
4600 #ifdef CONFIG_QTX_CODECS
4601 if (type
== MB_ICONHAND
&& !strlen(text
) && !strlen(title
))
4607 /* these are needed for mss1 */
4610 * \brief this symbol is defined within exp_EH_prolog_dummy
4611 * \param dest jump target
4613 void exp_EH_prolog(void *dest
);
4614 void exp_EH_prolog_dummy(void);
4615 //! just a dummy function that acts a container for the asm section
4616 void exp_EH_prolog_dummy(void) {
4618 // take care, this "function" may not change flags or
4619 // registers besides eax (which is also why we can't use
4620 // exp_EH_prolog_dummy directly)
4621 MANGLE(exp_EH_prolog
)": \n\t"
4624 "mov %esp, %ebp \n\t"
4625 "lea -12(%esp), %esp \n\t"
4630 #include <netinet/in.h>
4631 static WINAPI
inline unsigned long int exphtonl(unsigned long int hostlong
)
4633 // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4634 return htonl(hostlong
);
4637 static WINAPI
inline unsigned long int expntohl(unsigned long int netlong
)
4639 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4640 return ntohl(netlong
);
4643 static char* WINAPI
expSysAllocStringLen(char *pch
, unsigned cch
)
4646 dbgprintf("SysAllocStringLen('%s', %d)\n", pch
, cch
);
4647 str
= malloc(cch
* 2 + sizeof(unsigned) + 2);
4648 *(unsigned *)str
= cch
;
4649 str
+= sizeof(unsigned);
4651 memcpy(str
, pch
, cch
* 2);
4653 str
[cch
* 2 + 1] = 0;
4657 static void WINAPI
expSysFreeString(char *str
)
4660 free(str
- sizeof(unsigned));
4664 static void WINAPI
expVariantInit(void* p
)
4666 printf("InitCommonControls called!\n");
4670 static int WINAPI
expRegisterClassA(const void/*WNDCLASSA*/ *wc
)
4672 dbgprintf("RegisterClassA(%p) => random id\n", wc
);
4673 return time(NULL
); /* be precise ! */
4676 static int WINAPI
expUnregisterClassA(const char *className
, HINSTANCE hInstance
)
4678 dbgprintf("UnregisterClassA(%s, %p) => 0\n", className
, hInstance
);
4682 #ifdef CONFIG_QTX_CODECS
4683 /* should be fixed bcs it's not fully strlen equivalent */
4684 static int expSysStringByteLen(void *str
)
4686 dbgprintf("SysStringByteLen(%p) => %d\n", str
, strlen(str
));
4690 static int expDirectDrawCreate(void)
4692 dbgprintf("DirectDrawCreate(...) => NULL\n");
4697 typedef struct tagPALETTEENTRY
{
4704 /* reversed the first 2 entries */
4705 typedef struct tagLOGPALETTE
{
4708 PALETTEENTRY palPalEntry
[1];
4711 static HPALETTE WINAPI
expCreatePalette(CONST LOGPALETTE
*lpgpl
)
4716 dbgprintf("CreatePalette(%x) => NULL\n", lpgpl
);
4718 i
= sizeof(LOGPALETTE
)+((lpgpl
->palNumEntries
-1)*sizeof(PALETTEENTRY
));
4720 memcpy((void *)test
, lpgpl
, i
);
4725 static int expCreatePalette(void)
4727 dbgprintf("CreatePalette(...) => NULL\n");
4732 static int WINAPI
expGetClientRect(HWND win
, RECT
*r
)
4734 dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win
, r
);
4735 r
->right
= PSEUDO_SCREEN_WIDTH
;
4737 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
4743 typedef struct tagPOINT
{
4749 static int WINAPI
expClientToScreen(HWND win
, POINT
*p
)
4751 dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win
, p
, p
->x
, p
->y
);
4759 static int WINAPI
expSetThreadIdealProcessor(HANDLE thread
, int proc
)
4761 dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread
, proc
);
4765 static int WINAPI
expMessageBeep(int type
)
4767 dbgprintf("MessageBeep(%d) => 1\n", type
);
4771 static int WINAPI
expDialogBoxParamA(void *inst
, const char *name
,
4772 HWND parent
, void *dialog_func
, void *init_param
)
4774 dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
4775 inst
, name
, name
, parent
, dialog_func
, init_param
);
4779 static void WINAPI
expRegisterClipboardFormatA(const char *name
) {
4780 dbgprintf("RegisterClipboardFormatA(0x%x = %s)\n", name
, name
);
4783 /* needed by imagepower mjpeg2k */
4784 static void *exprealloc(void *ptr
, size_t size
)
4786 dbgprintf("realloc(0x%x, %x)\n", ptr
, size
);
4788 return my_mreq(size
,0);
4790 return my_realloc(ptr
, size
);
4793 /* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
4794 static WIN_BOOL WINAPI
expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn
)
4799 static char * WINAPI
expPathFindExtensionA(const char *path
) {
4804 ext
= strrchr(path
, '.');
4806 ext
= &path
[strlen(path
)];
4808 dbgprintf("PathFindExtensionA(0x%x = %s) => 0x%x, %s\n", path
, path
, ext
, ext
);
4812 static char * WINAPI
expPathFindFileNameA(const char *path
) {
4814 if (!path
|| strlen(path
) < 2)
4817 name
= strrchr(path
- 1, '\\');
4821 dbgprintf("PathFindFileNameA(0x%x = %s) => 0x%x, %s\n", path
, path
, name
, name
);
4825 static double expfloor(double x
)
4827 dbgprintf("floor(%lf)\n", x
);
4831 #define FPU_DOUBLE(var) double var; \
4832 __asm__ volatile( "fstpl %0;fwait" : "=m" (var) : )
4834 static double exp_CIcos(void)
4838 dbgprintf("_CIcos(%lf)\n", x
);
4842 static double exp_CIsin(void)
4846 dbgprintf("_CIsin(%lf)\n", x
);
4850 static double exp_CIsqrt(void)
4854 dbgprintf("_CIsqrt(%lf)\n", x
);
4858 /* Needed by rp8 sipr decoder */
4859 static LPSTR WINAPI
expCharNextA(LPCSTR ptr
)
4861 if (!*ptr
) return (LPSTR
)ptr
;
4862 // dbgprintf("CharNextA(0x%08x), %s\n", ptr, ptr);
4863 return (LPSTR
)(ptr
+ 1);
4866 // Fake implementation, needed by wvc1dmod.dll
4867 static int WINAPI
expPropVariantClear(void *pvar
)
4869 // dbgprintf("PropVariantclear (0x%08x), %s\n", ptr, ptr);
4873 // This define is fake, the real thing is a struct
4874 #define LPDEVMODEA void*
4875 // Dummy implementation, always return 1
4876 // Required for frapsvid.dll 2.8.1, return value does not matter
4877 static WIN_BOOL WINAPI
expEnumDisplaySettingsA(LPCSTR name
,DWORD n
,
4880 dbgprintf("EnumDisplaySettingsA (dummy) => 1\n");
4884 // Fake implementation of _decode_pointer from msvcr80.dll, needed by sirenacm.dll
4885 // NOTE: undocumented function, probably the declaration is not right
4886 static int exp_decode_pointer(void *ptr
)
4888 dbgprintf("_decode_pointer (0x%08x)\n", ptr
);
4892 /* Fake implementation of sdt::_Lockit::_Lockit(void) from msvcp60.dll
4893 Needed by SCLS.DLL */
4894 static int exp_0Lockit_dummy(void)
4896 dbgprintf("0Lockit_dummy (??0_Lockit@std@@QAE@XZ)\n");
4900 /* Fake implementation of sdt::_Lockit::~_Lockit(void) from msvcp60.dll
4901 Needed by SCLS.DLL */
4902 static int exp_1Lockit_dummy(void)
4904 dbgprintf("1Lockit_dummy (??1_Lockit@std@@QAE@XZ)\n");
4908 static void * WINAPI
expEncodePointer(void *p
)
4913 static void * WINAPI
expDecodePointer(void *p
)
4918 static DWORD WINAPI
expGetThreadLocale(void)
4924 * Very incomplete implementation, return an error for almost all cases.
4926 static DWORD WINAPI
expGetLocaleInfoA(DWORD locale
, DWORD lctype
, char* lpLCData
, int cchData
)
4928 if (lctype
== 0x1004) { // LOCALE_IDEFAULTANSICODEPAGE
4930 return cchData
== 0 ? 4 : 0;
4931 strcpy(lpLCData
, "437");
4947 struct exports
* exps
;
4951 {#X, Y, (void*)exp##X},
4953 #define UNDEFF(X, Y) \
4956 struct exports exp_kernel32
[]=
4958 FF(GetVolumeInformationA
,-1)
4959 FF(GetDriveTypeA
,-1)
4960 FF(GetLogicalDriveStringsA
,-1)
4961 FF(IsBadWritePtr
, 357)
4962 FF(IsBadReadPtr
, 354)
4963 FF(IsBadStringPtrW
, -1)
4964 FF(IsBadStringPtrA
, -1)
4965 FF(DisableThreadLibraryCalls
, -1)
4966 FF(CreateThread
, -1)
4967 FF(CreateEventA
, -1)
4970 FF(WaitForSingleObject
, -1)
4971 #ifdef CONFIG_QTX_CODECS
4972 FF(WaitForMultipleObjects
, -1)
4977 FF(GetSystemInfo
, -1)
4985 FF(GetProcessHeap
, -1)
4986 FF(VirtualAlloc
, -1)
4988 FF(InitializeCriticalSection
, -1)
4989 FF(InitializeCriticalSectionAndSpinCount
, -1)
4990 FF(EnterCriticalSection
, -1)
4991 FF(LeaveCriticalSection
, -1)
4992 FF(DeleteCriticalSection
, -1)
4997 FF(GetCurrentThreadId
, -1)
4998 FF(GetCurrentProcess
, -1)
5003 FF(GlobalReAlloc
, -1)
5006 FF(MultiByteToWideChar
, 427)
5007 FF(WideCharToMultiByte
, -1)
5008 FF(GetVersionExA
, -1)
5009 FF(CreateSemaphoreA
, -1)
5010 FF(QueryPerformanceCounter
, -1)
5011 FF(QueryPerformanceFrequency
, -1)
5015 FF(GlobalHandle
, -1)
5016 FF(GlobalUnlock
, -1)
5018 FF(LoadResource
, -1)
5019 FF(ReleaseSemaphore
, -1)
5020 FF(FindResourceA
, -1)
5021 FF(LockResource
, -1)
5022 FF(FreeResource
, -1)
5023 FF(SizeofResource
, -1)
5025 FF(GetCommandLineA
, -1)
5026 FF(GetEnvironmentStringsW
, -1)
5027 FF(FreeEnvironmentStringsW
, -1)
5028 FF(FreeEnvironmentStringsA
, -1)
5029 FF(GetEnvironmentStrings
, -1)
5030 FF(GetStartupInfoA
, -1)
5031 FF(GetStdHandle
, -1)
5033 #ifdef CONFIG_QTX_CODECS
5034 FF(GetFileAttributesA
, -1)
5036 FF(SetHandleCount
, -1)
5038 FF(GetModuleFileNameA
, -1)
5039 FF(SetUnhandledExceptionFilter
, -1)
5040 FF(LoadLibraryA
, -1)
5041 FF(GetProcAddress
, -1)
5043 FF(CreateFileMappingA
, -1)
5044 FF(OpenFileMappingA
, -1)
5045 FF(MapViewOfFile
, -1)
5046 FF(UnmapViewOfFile
, -1)
5048 FF(GetModuleHandleA
, -1)
5049 FF(GetModuleHandleW
, -1)
5050 FF(GetProfileIntA
, -1)
5051 FF(GetPrivateProfileIntA
, -1)
5052 FF(GetPrivateProfileStringA
, -1)
5053 FF(WritePrivateProfileStringA
, -1)
5054 FF(GetLastError
, -1)
5055 FF(SetLastError
, -1)
5056 FF(InterlockedIncrement
, -1)
5057 FF(InterlockedDecrement
, -1)
5058 FF(GetTimeZoneInformation
, -1)
5059 FF(OutputDebugStringA
, -1)
5060 FF(GetLocalTime
, -1)
5061 FF(GetSystemTime
, -1)
5062 FF(GetSystemTimeAsFileTime
, -1)
5063 FF(GetEnvironmentVariableA
, -1)
5064 FF(SetEnvironmentVariableA
, -1)
5065 FF(RtlZeroMemory
,-1)
5066 FF(RtlMoveMemory
,-1)
5067 FF(RtlFillMemory
,-1)
5069 FF(FindFirstFileA
,-1)
5070 FF(FindNextFileA
,-1)
5072 FF(FileTimeToLocalFileTime
,-1)
5076 FF(SetFilePointer
,-1)
5077 FF(GetTempFileNameA
,-1)
5079 FF(GetSystemDirectoryA
,-1)
5080 FF(GetWindowsDirectoryA
,-1)
5081 #ifdef CONFIG_QTX_CODECS
5082 FF(GetCurrentDirectoryA
,-1)
5083 FF(SetCurrentDirectoryA
,-1)
5084 FF(CreateDirectoryA
,-1)
5086 FF(GetShortPathNameA
,-1)
5087 FF(GetFullPathNameA
,-1)
5088 FF(SetErrorMode
, -1)
5089 FF(IsProcessorFeaturePresent
, -1)
5090 FF(IsDebuggerPresent
, -1)
5091 FF(GetProcessAffinityMask
, -1)
5092 FF(InterlockedExchange
, -1)
5093 FF(InterlockedCompareExchange
, -1)
5100 FF(GetProcessVersion
,-1)
5101 FF(GetCurrentThread
,-1)
5104 FF(DuplicateHandle
,-1)
5105 FF(GetTickCount
, -1)
5106 FF(SetThreadAffinityMask
,-1)
5107 FF(GetCurrentProcessId
,-1)
5108 FF(GlobalMemoryStatus
,-1)
5109 FF(GetThreadPriority
,-1)
5110 FF(SetThreadPriority
,-1)
5111 FF(TerminateProcess
,-1)
5113 {"LoadLibraryExA", -1, (void*)&LoadLibraryExA
},
5114 FF(SetThreadIdealProcessor
,-1)
5115 FF(SetProcessAffinityMask
, -1)
5116 FF(EncodePointer
, -1)
5117 FF(DecodePointer
, -1)
5118 FF(GetThreadLocale
, -1)
5119 FF(GetLocaleInfoA
, -1)
5120 UNDEFF(FlsAlloc
, -1)
5121 UNDEFF(FlsGetValue
, -1)
5122 UNDEFF(FlsSetValue
, -1)
5126 struct exports exp_msvcrt
[]={
5132 {"??3@YAXPAX@Z", -1, expdelete
},
5133 {"??2@YAPAXI@Z", -1, expnew
},
5134 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5135 {"_winver",-1,(void*)&_winver
},
5176 /* needed by frapsvid.dll */
5177 {"strstr",-1,(char *)&strstr
},
5178 {"qsort",-1,(void *)&qsort
},
5181 {"ceil",-1,(void*)&ceil
},
5182 /* needed by imagepower mjpeg2k */
5183 {"clock",-1,(void*)&clock
},
5184 {"memchr",-1,(void*)&memchr
},
5185 {"vfprintf",-1,(void*)&vfprintf
},
5186 // {"realloc",-1,(void*)&realloc},
5188 {"puts",-1,(void*)&puts
}
5190 struct exports exp_winmm
[]={
5191 FF(GetDriverModuleHandle
, -1)
5193 FF(DefDriverProc
, -1)
5196 FF(timeGetDevCaps
, -1)
5197 FF(timeBeginPeriod
, -1)
5198 #ifdef CONFIG_QTX_CODECS
5199 FF(timeEndPeriod
, -1)
5200 FF(waveOutGetNumDevs
, -1)
5203 struct exports exp_psapi
[]={
5204 FF(GetModuleBaseNameA
, -1)
5206 struct exports exp_user32
[]={
5211 FF(GetDesktopWindow
, -1)
5217 #ifdef CONFIG_QTX_CODECS
5220 FF(RegisterWindowMessageA
,-1)
5221 FF(GetSystemMetrics
,-1)
5223 FF(GetSysColorBrush
,-1)
5227 FF(RegisterClassA
, -1)
5228 FF(UnregisterClassA
, -1)
5229 #ifdef CONFIG_QTX_CODECS
5230 FF(GetWindowRect
, -1)
5231 FF(MonitorFromWindow
, -1)
5232 FF(MonitorFromRect
, -1)
5233 FF(MonitorFromPoint
, -1)
5234 FF(EnumDisplayMonitors
, -1)
5235 FF(GetMonitorInfoA
, -1)
5236 FF(EnumDisplayDevicesA
, -1)
5237 FF(GetClientRect
, -1)
5238 FF(ClientToScreen
, -1)
5239 FF(IsWindowVisible
, -1)
5240 FF(GetActiveWindow
, -1)
5241 FF(GetClassNameA
, -1)
5242 FF(GetClassInfoA
, -1)
5243 FF(GetWindowLongA
, -1)
5245 FF(GetWindowThreadProcessId
, -1)
5246 FF(CreateWindowExA
, -1)
5249 FF(DialogBoxParamA
, -1)
5250 FF(RegisterClipboardFormatA
, -1)
5252 FF(EnumDisplaySettingsA
, -1)
5254 struct exports exp_advapi32
[]={
5256 FF(RegCreateKeyA
, -1)
5257 FF(RegCreateKeyExA
, -1)
5258 FF(RegEnumKeyExA
, -1)
5259 FF(RegEnumValueA
, -1)
5261 FF(RegOpenKeyExA
, -1)
5262 FF(RegQueryValueExA
, -1)
5263 FF(RegSetValueExA
, -1)
5264 FF(RegQueryInfoKeyA
, -1)
5266 struct exports exp_gdi32
[]={
5267 FF(CreateCompatibleDC
, -1)
5270 FF(DeleteObject
, -1)
5271 FF(GetDeviceCaps
, -1)
5272 FF(GetSystemPaletteEntries
, -1)
5273 #ifdef CONFIG_QTX_CODECS
5274 FF(CreatePalette
, -1)
5276 FF(CreateRectRgn
, -1)
5279 struct exports exp_version
[]={
5280 FF(GetFileVersionInfoSizeA
, -1)
5282 struct exports exp_ole32
[]={
5283 FF(CoCreateFreeThreadedMarshaler
,-1)
5284 FF(CoCreateInstance
, -1)
5285 FF(CoInitialize
, -1)
5286 FF(CoInitializeEx
, -1)
5287 FF(CoUninitialize
, -1)
5288 FF(CoTaskMemAlloc
, -1)
5289 FF(CoTaskMemFree
, -1)
5290 FF(StringFromGUID2
, -1)
5291 FF(PropVariantClear
, -1)
5293 // do we really need crtdll ???
5294 // msvcrt is the correct place probably...
5295 struct exports exp_crtdll
[]={
5299 struct exports exp_comctl32
[]={
5300 FF(StringFromGUID2
, -1)
5301 FF(InitCommonControls
, 17)
5302 #ifdef CONFIG_QTX_CODECS
5303 FF(CreateUpDownControl
, 16)
5306 struct exports exp_wsock32
[]={
5310 struct exports exp_msdmo
[]={
5311 FF(memcpy
, -1) // just test
5312 FF(MoCopyMediaType
, -1)
5313 FF(MoCreateMediaType
, -1)
5314 FF(MoDeleteMediaType
, -1)
5315 FF(MoDuplicateMediaType
, -1)
5316 FF(MoFreeMediaType
, -1)
5317 FF(MoInitMediaType
, -1)
5319 struct exports exp_oleaut32
[]={
5320 FF(SysAllocStringLen
, 4)
5321 FF(SysFreeString
, 6)
5323 #ifdef CONFIG_QTX_CODECS
5324 FF(SysStringByteLen
, 149)
5330 vma: Hint/Ord Member-Name
5335 2305e 167 _adjust_fdiv
5338 22ffc 176 _beginthreadex
5340 2300e 85 __CxxFrameHandler
5344 struct exports exp_pncrt
[]={
5345 FF(malloc
, -1) // just test
5346 FF(free
, -1) // just test
5347 FF(fprintf
, -1) // just test
5348 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5351 {"??3@YAXPAX@Z", -1, expdelete
},
5352 {"??2@YAPAXI@Z", -1, expnew
},
5363 #ifdef CONFIG_QTX_CODECS
5364 struct exports exp_ddraw
[]={
5365 FF(DirectDrawCreate
, -1)
5369 struct exports exp_comdlg32
[]={
5370 FF(GetOpenFileNameA
, -1)
5373 struct exports exp_shlwapi
[]={
5374 FF(PathFindExtensionA
, -1)
5375 FF(PathFindFileNameA
, -1)
5378 struct exports exp_msvcr80
[]={
5386 FF(_decode_pointer
, -1)
5387 /* needed by KGV1-VFW.dll */
5388 {"??2@YAPAXI@Z", -1, expnew
},
5389 {"??3@YAXPAX@Z", -1, expdelete
}
5392 struct exports exp_msvcp60
[]={
5393 {"??0_Lockit@std@@QAE@XZ", -1, exp_0Lockit_dummy
},
5394 {"??1_Lockit@std@@QAE@XZ", -1, exp_1Lockit_dummy
}
5398 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5400 struct libs libraries
[]={
5418 #ifdef CONFIG_QTX_CODECS
5427 static WIN_BOOL WINAPI
ext_stubs(void)
5429 // NOTE! these magic values will be replaced at runtime, make sure
5430 // add_stub can still find them if you change them.
5431 volatile int idx
= 0x0deadabc;
5432 // make sure gcc does not do eip-relative call or something like that
5433 void (* volatile my_printf
)(char *, char *) = (void *)0xdeadfbcd;
5434 my_printf("Called unk_%s\n", export_names
[idx
]);
5438 #define MAX_STUB_SIZE 0x60
5439 #define MAX_NUM_STUBS 200
5441 static char *extcode
= NULL
;
5443 static void* add_stub(void)
5447 // generated code in runtime!
5450 extcode
= mmap_anon(NULL
, MAX_NUM_STUBS
* MAX_STUB_SIZE
,
5451 PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
, 0);
5452 answ
= extcode
+ pos
* MAX_STUB_SIZE
;
5453 if (pos
>= MAX_NUM_STUBS
) {
5454 printf("too many stubs, expect crash\n");
5457 memcpy(answ
, ext_stubs
, MAX_STUB_SIZE
);
5458 for (i
= 0; i
< MAX_STUB_SIZE
- 3; i
++) {
5459 int *magic
= (int *)(answ
+ i
);
5460 if (*magic
== 0x0deadabc) {
5464 if (*magic
== 0xdeadfbcd) {
5465 *magic
= (intptr_t)printf
;
5470 printf("magic code not found in ext_subs, expect crash\n");
5477 void* LookupExternal(const char* library
, int ordinal
)
5482 printf("ERROR: library=0\n");
5483 return (void*)ext_unknown
;
5485 // printf("%x %x\n", &unk_exp1, &unk_exp2);
5487 dbgprintf("External func %s:%d\n", library
, ordinal
);
5489 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5491 if(strcasecmp(library
, libraries
[i
].name
))
5493 for(j
=0; j
<libraries
[i
].length
; j
++)
5495 if(ordinal
!=libraries
[i
].exps
[j
].id
)
5497 //printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5498 return libraries
[i
].exps
[j
].func
;
5502 #ifndef LOADLIB_TRY_NATIVE
5503 /* hack for truespeech and vssh264*/
5504 if (!strcmp(library
, "tsd32.dll") || !strcmp(library
,"vssh264dec.dll") || !strcmp(library
,"LCMW2.dll") || !strcmp(library
,"VDODEC32.dll"))
5506 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5512 hand
= LoadLibraryA(library
);
5515 wm
= MODULE32_LookupHMODULE(hand
);
5521 func
= PE_FindExportedFunction(wm
, (LPCSTR
) ordinal
, 0);
5524 printf("No such ordinal in external dll\n");
5525 FreeLibrary((int)hand
);
5529 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5535 if(pos
>150)return 0;
5536 snprintf(export_names
[pos
], sizeof(export_names
[pos
]), "%s:%d", library
, ordinal
);
5540 void* LookupExternalByName(const char* library
, const char* name
)
5543 // return (void*)ext_unknown;
5546 printf("ERROR: library=0\n");
5547 return (void*)ext_unknown
;
5549 if((unsigned long)name
<=0xffff)
5551 return LookupExternal(library
, (int)name
);
5553 dbgprintf("External func %s:%s\n", library
, name
);
5554 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5556 if(strcasecmp(library
, libraries
[i
].name
))
5558 for(j
=0; j
<libraries
[i
].length
; j
++)
5560 if(strcmp(name
, libraries
[i
].exps
[j
].name
))
5562 if((unsigned int)(libraries
[i
].exps
[j
].func
) == -1)
5563 return NULL
; //undefined func
5564 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5565 return libraries
[i
].exps
[j
].func
;
5569 #ifndef LOADLIB_TRY_NATIVE
5570 /* hack for vss h264 */
5571 if (!strcmp(library
,"vssh264core.dll") || !strcmp(library
,"3ivx.dll"))
5573 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5579 hand
= LoadLibraryA(library
);
5582 wm
= MODULE32_LookupHMODULE(hand
);
5588 func
= PE_FindExportedFunction(wm
, name
, 0);
5591 printf("No such name in external dll\n");
5592 FreeLibrary((int)hand
);
5596 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5602 if(pos
>150)return 0;// to many symbols
5603 snprintf(export_names
[pos
], sizeof(export_names
[pos
]), "%s", name
);
5607 void my_garbagecollection(void)
5610 int unfree
= 0, unfreecnt
= 0;
5616 alloc_header
* mem
= last_alloc
+ 1;
5617 unfree
+= my_size(mem
);
5619 if (my_release(mem
) != 0)
5620 // avoid endless loop when memory is trashed
5621 if (--max_fatal
< 0)
5624 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree
, unfreecnt
, last_alloc
, alccnt
);