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"
52 #include "ldt_keeper.h"
65 #include <sys/types.h>
73 #ifdef HAVE_SYS_MMAN_H
76 #include "osdep/mmap.h"
78 #include "osdep/mmap_anon.h"
79 #include "libavutil/avstring.h"
80 #include "cpudetect.h"
82 static unsigned int c_localcount_tsc(void)
94 static void c_longcount_tsc(long long* z
)
99 "movl %%eax, %%ebx\n\t"
101 "movl %%eax, 0(%%ebx)\n\t"
102 "movl %%edx, 4(%%ebx)\n\t"
108 static unsigned int c_localcount_notsc(void)
113 gettimeofday(&tv
, 0);
114 return limit
*tv
.tv_usec
;
116 static void c_longcount_notsc(long long* z
)
119 unsigned long long result
;
123 gettimeofday(&tv
, 0);
126 result
+=limit
*tv
.tv_usec
;
129 static unsigned int localcount_stub(void);
130 static void longcount_stub(long long*);
131 static unsigned int (*localcount
)(void)=localcount_stub
;
132 static void (*longcount
)(long long*)=longcount_stub
;
134 static pthread_mutex_t memmut
= PTHREAD_MUTEX_INITIALIZER
;
136 static unsigned int localcount_stub(void)
138 unsigned int regs
[4];
140 if ((regs
[3] & 0x00000010) != 0)
142 localcount
=c_localcount_tsc
;
143 longcount
=c_longcount_tsc
;
147 localcount
=c_localcount_notsc
;
148 longcount
=c_longcount_notsc
;
152 static void longcount_stub(long long* z
)
154 unsigned int regs
[4];
156 if ((regs
[3] & 0x00000010) != 0)
158 localcount
=c_localcount_tsc
;
159 longcount
=c_longcount_tsc
;
163 localcount
=c_localcount_notsc
;
164 longcount
=c_longcount_notsc
;
170 int LOADER_DEBUG
=1; // active only if compiled with -DDETAILED_OUT
171 //#define DETAILED_OUT
172 static inline void dbgprintf(char* fmt
, ...)
180 f
=fopen("./log", "a");
185 vfprintf(f
, fmt
, va
);
192 if ( mp_msg_test(MSGT_WIN32
,MSGL_DBG3
) )
198 // mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va);
205 char export_names
[300][32]={
210 //#define min(x,y) ((x)<(y)?(x):(y))
212 void destroy_event(void* event
);
215 typedef struct th_list_t
{
218 struct th_list_t
* next
;
219 struct th_list_t
* prev
;
223 // have to be cleared by GARBAGE COLLECTOR
224 //static unsigned char* heap=NULL;
225 //static int heap_counter=0;
226 static tls_t
* g_tls
=NULL
;
227 static th_list
* list
=NULL
;
228 static pthread_mutex_t list_lock
= PTHREAD_MUTEX_INITIALIZER
;
231 static void test_heap(void)
236 while(offset
<heap_counter
)
238 if(*(int*)(heap
+offset
)!=0x433476)
240 printf("Heap corruption at address %d\n", offset
);
243 offset
+=8+*(int*)(heap
+offset
+4);
245 for(;offset
<min(offset
+1000, 20000000); offset
++)
246 if(heap
[offset
]!=0xCC)
248 printf("Free heap corruption at address %d\n", offset
);
256 static void* my_mreq(int size
, int to_zero
)
260 if(test
%10==0)printf("Memory: %d bytes allocated\n", heap_counter
);
264 heap
=malloc(20000000);
265 memset(heap
, 0xCC,20000000);
269 printf("No enough memory\n");
272 if(heap_counter
+size
>20000000)
274 printf("No enough memory\n");
277 *(int*)(heap
+heap_counter
)=0x433476;
279 *(int*)(heap
+heap_counter
)=size
;
281 printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size
, heap_counter
-8, heap_counter
, heap_counter
+size
);
283 memset(heap
+heap_counter
, 0, size
);
285 memset(heap
+heap_counter
, 0xcc, size
); // make crash reproducable
287 return heap
+heap_counter
-size
;
289 static int my_release(char* memory
)
294 printf("ERROR: free(0)\n");
297 if(*(int*)(memory
-8)!=0x433476)
299 printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
302 printf("Freed %d bytes of memory\n", *(int*)(memory
-4));
303 // memset(memory-8, *(int*)(memory-4), 0xCC);
309 typedef struct alloc_header_t alloc_header
;
310 struct alloc_header_t
312 // let's keep allocated data 16 byte aligned
324 static alloc_header
* last_alloc
= NULL
;
325 static int alccnt
= 0;
328 #define AREATYPE_CLIENT 0
329 #define AREATYPE_EVENT 1
330 #define AREATYPE_MUTEX 2
331 #define AREATYPE_COND 3
332 #define AREATYPE_CRITSECT 4
334 /* -- critical sections -- */
338 pthread_mutex_t mutex
;
339 pthread_cond_t unlocked
;
344 void* mreq_private(int size
, int to_zero
, int type
);
345 void* mreq_private(int size
, int to_zero
, int type
)
347 int nsize
= size
+ sizeof(alloc_header
);
348 alloc_header
* header
= malloc(nsize
);
352 memset(header
, 0, nsize
);
354 pthread_mutex_lock(&memmut
);
357 last_alloc
->next
= header
; /* set next */
360 header
->prev
= last_alloc
;
364 pthread_mutex_unlock(&memmut
);
366 header
->deadbeef
= 0xdeadbeef;
370 //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt);
374 static int my_release(void* memory
)
376 alloc_header
* header
= (alloc_header
*) memory
- 1;
378 alloc_header
* prevmem
;
379 alloc_header
* nextmem
;
384 if (header
->deadbeef
!= (long) 0xdeadbeef)
386 dbgprintf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
390 pthread_mutex_lock(&memmut
);
395 destroy_event(memory
);
398 pthread_cond_destroy((pthread_cond_t
*)memory
);
401 pthread_mutex_destroy((pthread_mutex_t
*)memory
);
403 case AREATYPE_CRITSECT
:
404 pthread_mutex_destroy(&((struct CRITSECT
*)memory
)->mutex
);
407 //memset(memory, 0xcc, header->size);
411 header
->deadbeef
= 0;
412 prevmem
= header
->prev
;
413 nextmem
= header
->next
;
416 prevmem
->next
= nextmem
;
418 nextmem
->prev
= prevmem
;
420 if (header
== last_alloc
)
421 last_alloc
= prevmem
;
425 pthread_mutex_unlock(&memmut
);
427 //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt);
432 //memset(header + 1, 0xcc, header->size);
438 static inline void* my_mreq(int size
, int to_zero
)
440 return mreq_private(size
, to_zero
, AREATYPE_CLIENT
);
443 static int my_size(void* memory
)
445 if(!memory
) return 0;
446 return ((alloc_header
*)memory
)[-1].size
;
449 static void* my_realloc(void* memory
, int size
)
454 return my_mreq(size
, 0);
455 osize
= my_size(memory
);
458 ans
= my_mreq(size
, 0);
459 memcpy(ans
, memory
, osize
);
467 * WINE API - native implementation for several win32 libraries
471 static int WINAPI
ext_unknown(void)
473 printf("Unknown func called\n");
477 static int WINAPI
expGetVolumeInformationA( const char *root
, char *label
,
478 unsigned int label_len
, unsigned int *serial
,
479 unsigned int *filename_len
,unsigned int *flags
,
480 char *fsname
, unsigned int fsname_len
)
482 dbgprintf("GetVolumeInformationA( %s, 0x%x, %ld, 0x%x, 0x%x, 0x%x, 0x%x, %ld) => 1\n",
483 root
,label
,label_len
,serial
,filename_len
,flags
,fsname
,fsname_len
);
484 //hack Do not return any real data - do nothing
488 static unsigned int WINAPI
expGetDriveTypeA( const char *root
)
490 dbgprintf("GetDriveTypeA( %s ) => %d\n",root
,DRIVE_FIXED
);
491 // hack return as Fixed Drive Type
495 static unsigned int WINAPI
expGetLogicalDriveStringsA( unsigned int len
, char *buffer
)
497 dbgprintf("GetLogicalDriveStringsA(%d, 0x%x) => 4\n",len
,buffer
);
498 // hack only have one drive c:\ in this hack
504 return 4; // 1 drive * 4 bytes (includes null)
508 static int WINAPI
expIsBadWritePtr(void* ptr
, unsigned int count
)
510 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
511 dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
514 static int WINAPI
expIsBadReadPtr(void* ptr
, unsigned int count
)
516 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
517 dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
520 static int WINAPI
expDisableThreadLibraryCalls(int module
)
522 dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module
);
526 static HMODULE WINAPI
expGetDriverModuleHandle(DRVR
* pdrv
)
532 result
=pdrv
->hDriverModule
;
533 dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv
, result
);
537 #define MODULE_HANDLE_kernel32 ((HMODULE)0x120)
538 #define MODULE_HANDLE_user32 ((HMODULE)0x121)
539 #ifdef CONFIG_QTX_CODECS
540 #define MODULE_HANDLE_wininet ((HMODULE)0x122)
541 #define MODULE_HANDLE_ddraw ((HMODULE)0x123)
542 #define MODULE_HANDLE_advapi32 ((HMODULE)0x124)
544 #define MODULE_HANDLE_comdlg32 ((HMODULE)0x125)
545 #define MODULE_HANDLE_msvcrt ((HMODULE)0x126)
546 #define MODULE_HANDLE_ole32 ((HMODULE)0x127)
547 #define MODULE_HANDLE_winmm ((HMODULE)0x128)
548 #define MODULE_HANDLE_psapi ((HMODULE)0x129)
550 // Fake PE header, since some software (and the Microsoft CRT v8 and newer)
551 // assume GetModuleHandle(NULL) returns a pointer to a PE header.
552 // We simulate a very simple header with only one section.
554 // NOTE: If you have a section called .mixcrt, the Microsoft CRT will assume
555 // it's running in a POSIX binary, and stop using EncodePointer/DecodePointer.
556 static const struct {
557 IMAGE_DOS_HEADER doshdr
;
558 IMAGE_NT_HEADERS nthdr
;
559 IMAGE_SECTION_HEADER opthdr
;
560 } __attribute__((__packed__
)) mp_exe
= {
561 .doshdr
.e_lfanew
= sizeof(IMAGE_DOS_HEADER
),
562 .nthdr
.FileHeader
.NumberOfSections
= 1,
563 .nthdr
.FileHeader
.SizeOfOptionalHeader
=
564 sizeof(IMAGE_NT_HEADERS
) - FIELD_OFFSET(IMAGE_NT_HEADERS
, OptionalHeader
), /* 0xe0 */
565 .opthdr
.Name
= ".text"
568 static HMODULE WINAPI
expGetModuleHandleA(const char* name
)
573 result
=(HMODULE
)&mp_exe
.doshdr
;
576 wm
=MODULE_FindModule(name
);
579 result
=(HMODULE
)(wm
->module
);
583 if(name
&& (strcasecmp(name
, "kernel32")==0 || !strcasecmp(name
, "kernel32.dll")))
584 result
=MODULE_HANDLE_kernel32
;
585 #ifdef CONFIG_QTX_CODECS
586 if(name
&& strcasecmp(name
, "user32")==0)
587 result
=MODULE_HANDLE_user32
;
590 dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name
, result
);
594 static HMODULE WINAPI
expGetModuleHandleW(const uint16_t* name
)
599 if (*name
> 256 || pos
>= sizeof(aname
) - 1)
601 aname
[pos
++] = *name
++;
604 return expGetModuleHandleA(aname
);
607 static void* WINAPI
expCreateThread(void* pSecAttr
, long dwStackSize
,
608 void* lpStartAddress
, void* lpParameter
,
609 long dwFlags
, long* dwThreadId
)
612 // printf("CreateThread:");
613 pth
= (pthread_t
*) my_mreq(sizeof(pthread_t
), 0);
614 pthread_create(pth
, NULL
, (void*(*)(void*))lpStartAddress
, lpParameter
);
616 printf( "WARNING: CreateThread flags not supported\n");
618 *dwThreadId
=(long)pth
;
619 pthread_mutex_lock(&list_lock
);
622 list
=my_mreq(sizeof(th_list
), 1);
623 list
->next
=list
->prev
=NULL
;
627 list
->next
=my_mreq(sizeof(th_list
), 0);
628 list
->next
->prev
=list
;
629 list
->next
->next
=NULL
;
633 pthread_mutex_unlock(&list_lock
);
634 dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
635 pSecAttr
, dwStackSize
, lpStartAddress
, lpParameter
, dwFlags
, dwThreadId
, pth
);
639 static DWORD WINAPI
expResumeThread(HANDLE hThread
)
642 dbgprintf("ResumeThread(0x%x) => 0x%x\n", hThread
, ret
);
659 struct mutex_list_t
* next
;
660 struct mutex_list_t
* prev
;
662 typedef struct mutex_list_t mutex_list
;
663 static mutex_list
* mlist
=NULL
;
664 static pthread_mutex_t mlist_lock
= PTHREAD_MUTEX_INITIALIZER
;
666 void destroy_event(void* event
)
669 pthread_mutex_lock(&mlist_lock
);
671 // printf("garbage collector: destroy_event(%x)\n", event);
674 if(pp
==(mutex_list
*)event
)
677 pp
->next
->prev
=pp
->prev
;
679 pp
->prev
->next
=pp
->next
;
680 if(mlist
==(mutex_list
*)event
)
686 printf("%x => ", pp);
691 pthread_mutex_unlock(&mlist_lock
);
696 pthread_mutex_unlock(&mlist_lock
);
699 static void* WINAPI
expCreateEventA(void* pSecAttr
, char bManualReset
,
700 char bInitialState
, const char* name
)
710 printf("%x => ", pp);
715 pthread_mutex_lock(&mlist_lock
);
718 mutex_list
* pp
=mlist
;
722 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==0))
724 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
725 pSecAttr
, bManualReset
, bInitialState
, name
, name
, pp
->pm
);
726 pthread_mutex_unlock(&mlist_lock
);
729 }while((pp
=pp
->prev
) != NULL
);
731 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
732 pthread_mutex_init(pm
, NULL
);
733 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
734 pthread_cond_init(pc
, NULL
);
737 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
738 mlist
->next
=mlist
->prev
=NULL
;
742 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
743 mlist
->next
->prev
=mlist
;
744 mlist
->next
->next
=NULL
;
747 mlist
->type
=0; /* Type Event */
750 mlist
->state
=bInitialState
;
751 mlist
->reset
=!bManualReset
;
753 strncpy(mlist
->name
, name
, 127);
757 dbgprintf("ERROR::: CreateEventA failure\n");
760 pthread_mutex_lock(pm);
763 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
764 pSecAttr
, bManualReset
, bInitialState
, name
, name
, mlist
);
766 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
767 pSecAttr
, bManualReset
, bInitialState
, mlist
);
769 pthread_mutex_unlock(&mlist_lock
);
773 static void* WINAPI
expCreateEventW(void* pSecAttr
, char bManualReset
,
774 char bInitialState
, const WCHAR
* name
)
776 char ascii_name
[256];
779 WideCharToMultiByte(65001, 0x0, name
, -1, ascii_name
, 256, NULL
, NULL
);
782 return expCreateEventA(pSecAttr
, bManualReset
, bInitialState
, aname
);
785 static void* WINAPI
expSetEvent(void* event
)
787 mutex_list
*ml
= (mutex_list
*)event
;
788 dbgprintf("SetEvent(%x) => 0x1\n", event
);
789 pthread_mutex_lock(ml
->pm
);
790 if (ml
->state
== 0) {
792 pthread_cond_signal(ml
->pc
);
794 pthread_mutex_unlock(ml
->pm
);
798 static void* WINAPI
expResetEvent(void* event
)
800 mutex_list
*ml
= (mutex_list
*)event
;
801 dbgprintf("ResetEvent(0x%x) => 0x1\n", event
);
802 pthread_mutex_lock(ml
->pm
);
804 pthread_mutex_unlock(ml
->pm
);
809 static void* WINAPI
expWaitForSingleObject(void* object
, int duration
)
811 mutex_list
*ml
= (mutex_list
*)object
;
812 // FIXME FIXME FIXME - this value is sometime unititialize !!!
813 int ret
= WAIT_FAILED
;
816 if(object
== (void*)0xcfcf9898)
819 From GetCurrentThread() documentation:
820 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.
822 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.
824 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.
826 dbgprintf("WaitForSingleObject(thread_handle) called\n");
827 return (void*)WAIT_FAILED
;
829 dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object
, duration
);
831 // See if this is a thread.
832 pthread_mutex_lock(&list_lock
);
834 while (tp
&& (tp
->thread
!= object
))
836 pthread_mutex_unlock(&list_lock
);
838 if (pthread_join(*(pthread_t
*)object
, NULL
) == 0) {
839 return (void*)WAIT_OBJECT_0
;
841 return (void*)WAIT_FAILED
;
845 // loop below was slightly fixed - its used just for checking if
846 // this object really exists in our list
849 pthread_mutex_lock(&mlist_lock
);
851 while (pp
&& (pp
->pm
!= ml
->pm
))
853 pthread_mutex_unlock(&mlist_lock
);
855 dbgprintf("WaitForSingleObject: NotFound\n");
859 pthread_mutex_lock(ml
->pm
);
863 if (duration
== 0) { /* Check Only */
864 if (ml
->state
== 1) ret
= WAIT_OBJECT_0
;
865 else ret
= WAIT_FAILED
;
867 if (duration
== -1) { /* INFINITE */
869 pthread_cond_wait(ml
->pc
,ml
->pm
);
874 if (duration
> 0) { /* Timed Wait */
875 struct timespec abstime
;
877 gettimeofday(&now
, 0);
878 abstime
.tv_sec
= now
.tv_sec
+ (now
.tv_usec
+duration
)/1000000;
879 abstime
.tv_nsec
= ((now
.tv_usec
+duration
)%1000000)*1000;
881 ret
=pthread_cond_timedwait(ml
->pc
,ml
->pm
,&abstime
);
882 if (ret
== ETIMEDOUT
) ret
= WAIT_TIMEOUT
;
883 else ret
= WAIT_OBJECT_0
;
888 case 1: /* Semaphore */
890 if(ml
->semaphore
==0) ret
= WAIT_FAILED
;
896 if (duration
== -1) {
897 if (ml
->semaphore
==0)
898 pthread_cond_wait(ml
->pc
,ml
->pm
);
905 if(ml
->lock_count
> 0 && ml
->owner
!= pthread_self()) ret
= WAIT_FAILED
;
908 ml
->owner
= pthread_self();
912 if (duration
== -1) {
913 if (ml
->lock_count
> 0 && ml
->owner
!= pthread_self()) {
914 pthread_cond_wait(ml
->pc
,ml
->pm
);
917 ml
->owner
= pthread_self();
922 pthread_mutex_unlock(ml
->pm
);
924 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object
,duration
,ml
,ret
);
928 #ifdef CONFIG_QTX_CODECS
929 static void* WINAPI
expWaitForMultipleObjects(int count
, const void** objects
,
930 int WaitAll
, int duration
)
936 dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
937 count
, objects
, WaitAll
, duration
);
939 for (i
= 0; i
< count
; i
++)
941 object
= (void *)objects
[i
];
942 ret
= expWaitForSingleObject(object
, duration
);
944 dbgprintf("WaitAll flag not yet supported...\n");
951 static void WINAPI
expExitThread(int retcode
)
953 dbgprintf("ExitThread(%d)\n", retcode
);
954 pthread_exit(&retcode
);
958 static int pf_set
= 0;
959 static BYTE PF
[64] = {0,};
961 static void DumpSystemInfo(const SYSTEM_INFO
* si
)
963 dbgprintf(" Processor architecture %d\n", si
->u
.s
.wProcessorArchitecture
);
964 dbgprintf(" Page size: %d\n", si
->dwPageSize
);
965 dbgprintf(" Minimum app address: %d\n", si
->lpMinimumApplicationAddress
);
966 dbgprintf(" Maximum app address: %d\n", si
->lpMaximumApplicationAddress
);
967 dbgprintf(" Active processor mask: 0x%x\n", si
->dwActiveProcessorMask
);
968 dbgprintf(" Number of processors: %d\n", si
->dwNumberOfProcessors
);
969 dbgprintf(" Processor type: 0x%x\n", si
->dwProcessorType
);
970 dbgprintf(" Allocation granularity: 0x%x\n", si
->dwAllocationGranularity
);
971 dbgprintf(" Processor level: 0x%x\n", si
->wProcessorLevel
);
972 dbgprintf(" Processor revision: 0x%x\n", si
->wProcessorRevision
);
975 static void WINAPI
expGetSystemInfo(SYSTEM_INFO
* si
)
977 /* FIXME: better values for the two entries below... */
978 static int cache
= 0;
979 static SYSTEM_INFO cachedsi
;
980 dbgprintf("GetSystemInfo(%p) =>\n", si
);
985 memset(PF
,0,sizeof(PF
));
988 cachedsi
.u
.s
.wProcessorArchitecture
= PROCESSOR_ARCHITECTURE_INTEL
;
989 cachedsi
.dwPageSize
= getpagesize();
991 /* FIXME: better values for the two entries below... */
992 cachedsi
.lpMinimumApplicationAddress
= (void *)0x00000000;
993 cachedsi
.lpMaximumApplicationAddress
= (void *)0x7FFFFFFF;
994 cachedsi
.dwActiveProcessorMask
= 1;
995 cachedsi
.dwNumberOfProcessors
= 1;
996 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
997 cachedsi
.dwAllocationGranularity
= 0x10000;
998 cachedsi
.wProcessorLevel
= 5; /* pentium */
999 cachedsi
.wProcessorRevision
= 0x0101;
1001 /* mplayer's way to detect PF's */
1003 #include "cpudetect.h"
1005 if (gCpuCaps
.hasMMX
)
1006 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1007 if (gCpuCaps
.hasSSE
)
1008 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1009 if (gCpuCaps
.hasSSE2
)
1010 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1011 if (gCpuCaps
.has3DNow
)
1012 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1014 if (gCpuCaps
.cpuType
== 4)
1016 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1017 cachedsi
.wProcessorLevel
= 4;
1019 else if (gCpuCaps
.cpuType
>= 5)
1021 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1022 cachedsi
.wProcessorLevel
= 5;
1026 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1027 cachedsi
.wProcessorLevel
= 3;
1029 cachedsi
.wProcessorRevision
= gCpuCaps
.cpuStepping
;
1030 cachedsi
.dwNumberOfProcessors
= 1; /* hardcoded */
1033 /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
1034 fdiv_bug and fpu emulation flags -- alex/MPlayer */
1039 FILE *f
= fopen ("/proc/cpuinfo", "r");
1043 mp_msg(MSGT_WIN32
, MSGL_WARN
, "expGetSystemInfo: "
1044 "/proc/cpuinfo not readable! "
1045 "Expect bad performance and/or weird behaviour\n");
1048 while (fgets(line
,200,f
)!=NULL
) {
1051 /* NOTE: the ':' is the only character we can rely on */
1052 if (!(value
= strchr(line
,':')))
1054 /* terminate the valuename */
1056 /* skip any leading spaces */
1057 while (*value
==' ') value
++;
1058 if ((s
=strchr(value
,'\n')))
1062 if (!lstrncmpiA(line
, "cpu family",strlen("cpu family"))) {
1063 if (isdigit (value
[0])) {
1064 switch (value
[0] - '0') {
1065 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1066 cachedsi
.wProcessorLevel
= 3;
1068 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1069 cachedsi
.wProcessorLevel
= 4;
1071 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1072 cachedsi
.wProcessorLevel
= 5;
1074 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1075 cachedsi
.wProcessorLevel
= 5;
1077 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1078 cachedsi
.wProcessorLevel
= 5;
1082 /* set the CPU type of the current processor */
1083 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1086 /* old 2.0 method */
1087 if (!lstrncmpiA(line
, "cpu",strlen("cpu"))) {
1088 if ( isdigit (value
[0]) && value
[1] == '8' &&
1089 value
[2] == '6' && value
[3] == 0
1091 switch (value
[0] - '0') {
1092 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1093 cachedsi
.wProcessorLevel
= 3;
1095 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1096 cachedsi
.wProcessorLevel
= 4;
1098 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1099 cachedsi
.wProcessorLevel
= 5;
1101 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1102 cachedsi
.wProcessorLevel
= 5;
1104 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1105 cachedsi
.wProcessorLevel
= 5;
1109 /* set the CPU type of the current processor */
1110 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1113 if (!lstrncmpiA(line
,"fdiv_bug",strlen("fdiv_bug"))) {
1114 if (!lstrncmpiA(value
,"yes",3))
1115 PF
[PF_FLOATING_POINT_PRECISION_ERRATA
] = TRUE
;
1119 if (!lstrncmpiA(line
,"fpu",strlen("fpu"))) {
1120 if (!lstrncmpiA(value
,"no",2))
1121 PF
[PF_FLOATING_POINT_EMULATED
] = TRUE
;
1125 if (!lstrncmpiA(line
,"processor",strlen("processor"))) {
1126 /* processor number counts up...*/
1129 if (sscanf(value
,"%d",&x
))
1130 if (x
+1>cachedsi
.dwNumberOfProcessors
)
1131 cachedsi
.dwNumberOfProcessors
=x
+1;
1133 /* Create a new processor subkey on a multiprocessor
1136 sprintf(buf
,"%d",x
);
1138 if (!lstrncmpiA(line
,"stepping",strlen("stepping"))) {
1141 if (sscanf(value
,"%d",&x
))
1142 cachedsi
.wProcessorRevision
= x
;
1145 ( (!lstrncmpiA(line
,"flags",strlen("flags")))
1146 || (!lstrncmpiA(line
,"features",strlen("features"))) )
1148 if (strstr(value
,"cx8"))
1149 PF
[PF_COMPARE_EXCHANGE_DOUBLE
] = TRUE
;
1150 if (strstr(value
,"mmx"))
1151 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1152 if (strstr(value
,"tsc"))
1153 PF
[PF_RDTSC_INSTRUCTION_AVAILABLE
] = TRUE
;
1154 if (strstr(value
,"xmm") || strstr(value
,"sse"))
1155 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1156 if (strstr(value
,"sse2"))
1157 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1158 if (strstr(value
,"3dnow"))
1159 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1164 #endif /* __linux__ */
1167 memcpy(si
,&cachedsi
,sizeof(*si
));
1171 // avoid undefined expGetSystemInfo
1172 static WIN_BOOL WINAPI
expIsProcessorFeaturePresent(DWORD v
)
1174 WIN_BOOL result
= 0;
1178 expGetSystemInfo(&si
);
1180 if(v
<64) result
=PF
[v
];
1181 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v
, result
);
1185 static WIN_BOOL WINAPI
expIsDebuggerPresent(void)
1190 static long WINAPI
expGetVersion(void)
1192 dbgprintf("GetVersion() => 0xC0000004\n");
1193 return 0xC0000004;//Windows 95
1196 static HANDLE WINAPI
expHeapCreate(long flags
, long init_size
, long max_size
)
1198 // printf("HeapCreate:");
1201 result
=(HANDLE
)my_mreq(0x110000, 0);
1203 result
=(HANDLE
)my_mreq((init_size
+ 0xfff) & 0x7ffff000 , 0);
1204 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags
, init_size
, max_size
, result
);
1208 // this is another dirty hack
1209 // VP31 is releasing one allocated Heap chunk twice
1210 // we will silently ignore this second call...
1211 static void* heapfreehack
= 0;
1212 static int heapfreehackshown
= 0;
1213 //void trapbug(void);
1214 static void* WINAPI
expHeapAlloc(HANDLE heap
, int flags
, int size
)
1218 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1219 HeapAlloc returns area larger than size argument :-/
1221 actually according to M$ Doc HeapCreate size should be rounded
1222 to page boundaries thus we should simulate this
1224 //if (size == 22276) trapbug();
1225 z
=my_mreq((size
+ 0xfff) & 0x7ffff000, (flags
& HEAP_ZERO_MEMORY
));
1227 printf("HeapAlloc failure\n");
1228 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap
, flags
, size
, z
);
1229 heapfreehack
= 0; // reset
1232 static long WINAPI
expHeapDestroy(void* heap
)
1234 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap
);
1239 static long WINAPI
expHeapFree(HANDLE heap
, DWORD dwFlags
, LPVOID lpMem
)
1241 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap
, dwFlags
, lpMem
);
1242 if (heapfreehack
!= lpMem
&& lpMem
!= (void*)0xffffffff
1243 && lpMem
!= (void*)0xbdbdbdbd)
1244 // 0xbdbdbdbd is for i263_drv.drv && libefence
1245 // it seems to be reading from relased memory
1246 // EF_PROTECT_FREE doens't show any probleme
1250 if (!heapfreehackshown
++)
1251 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem
);
1253 heapfreehack
= lpMem
;
1256 static long WINAPI
expHeapSize(int heap
, int flags
, void* pointer
)
1258 long result
=my_size(pointer
);
1259 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap
, flags
, pointer
, result
);
1262 static void* WINAPI
expHeapReAlloc(HANDLE heap
,int flags
,void *lpMem
,int size
)
1264 long orgsize
= my_size(lpMem
);
1265 dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize
,size
);
1266 return my_realloc(lpMem
, size
);
1268 static long WINAPI
expGetProcessHeap(void)
1270 dbgprintf("GetProcessHeap() => 1\n");
1273 static void* WINAPI
expVirtualAlloc(void* v1
, long v2
, long v3
, long v4
)
1275 void* z
= VirtualAlloc(v1
, v2
, v3
, v4
);
1277 printf("VirtualAlloc failure\n");
1278 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1
,v2
,v3
,v4
, z
);
1281 static int WINAPI
expVirtualFree(void* v1
, int v2
, int v3
)
1283 int result
= VirtualFree(v1
,v2
,v3
);
1284 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1
,v2
,v3
, result
);
1288 /* we're building a table of critical sections. cs_win pointer uses the DLL
1289 cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1290 struct critsecs_list_t
1292 CRITICAL_SECTION
*cs_win
;
1293 struct CRITSECT
*cs_unix
;
1296 /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1297 #undef CRITSECS_NEWTYPE
1298 //#define CRITSECS_NEWTYPE 1
1300 #ifdef CRITSECS_NEWTYPE
1301 /* increased due to ucod needs more than 32 entries */
1302 /* and 64 should be enough for everything */
1303 #define CRITSECS_LIST_MAX 64
1304 static struct critsecs_list_t critsecs_list
[CRITSECS_LIST_MAX
];
1306 static int critsecs_get_pos(CRITICAL_SECTION
*cs_win
)
1310 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1311 if (critsecs_list
[i
].cs_win
== cs_win
)
1316 static int critsecs_get_unused(void)
1320 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1321 if (critsecs_list
[i
].cs_win
== NULL
)
1326 struct CRITSECT
*critsecs_get_unix(CRITICAL_SECTION
*cs_win
)
1330 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1331 if (critsecs_list
[i
].cs_win
== cs_win
&& critsecs_list
[i
].cs_unix
)
1332 return critsecs_list
[i
].cs_unix
;
1337 static void WINAPI
expInitializeCriticalSection(CRITICAL_SECTION
* c
)
1339 dbgprintf("InitializeCriticalSection(0x%x)\n", c
);
1340 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1342 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1343 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1346 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1347 #ifdef CRITSECS_NEWTYPE
1349 struct CRITSECT
*cs
;
1350 int i
= critsecs_get_unused();
1354 printf("InitializeCriticalSection(%p) - no more space in list\n", c
);
1357 dbgprintf("got unused space at %d\n", i
);
1358 cs
= malloc(sizeof(struct CRITSECT
));
1361 printf("InitializeCriticalSection(%p) - out of memory\n", c
);
1364 pthread_mutex_init(&cs
->mutex
, NULL
);
1365 pthread_cond_init(&cs
->unlocked
, NULL
);
1367 critsecs_list
[i
].cs_win
= c
;
1368 critsecs_list
[i
].cs_unix
= cs
;
1369 dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1374 struct CRITSECT
* cs
= mreq_private(sizeof(struct CRITSECT
) + sizeof(CRITICAL_SECTION
),
1375 0, AREATYPE_CRITSECT
);
1376 pthread_mutex_init(&cs
->mutex
, NULL
);
1377 pthread_cond_init(&cs
->unlocked
, NULL
);
1379 cs
->deadbeef
= 0xdeadbeef;
1386 static WIN_BOOL WINAPI
expInitializeCriticalSectionAndSpinCount(CRITICAL_SECTION
* c
, DWORD spin
)
1388 expInitializeCriticalSection(c
);
1392 static void WINAPI
expEnterCriticalSection(CRITICAL_SECTION
* c
)
1394 #ifdef CRITSECS_NEWTYPE
1395 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1397 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1399 dbgprintf("EnterCriticalSection(0x%x) %p\n",c
, cs
);
1402 dbgprintf("entered uninitialized critisec!\n");
1403 expInitializeCriticalSection(c
);
1404 #ifdef CRITSECS_NEWTYPE
1405 cs
=critsecs_get_unix(c
);
1407 cs
= (*(struct CRITSECT
**)c
);
1409 dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c
);
1411 pthread_mutex_lock(&(cs
->mutex
));
1412 if (cs
->lock_count
> 0 && cs
->id
== pthread_self()) {
1415 while (cs
->lock_count
!= 0) {
1416 pthread_cond_wait(&(cs
->unlocked
), &(cs
->mutex
));
1419 cs
->id
= pthread_self();
1421 pthread_mutex_unlock(&(cs
->mutex
));
1424 static void WINAPI
expLeaveCriticalSection(CRITICAL_SECTION
* c
)
1426 #ifdef CRITSECS_NEWTYPE
1427 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1429 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1431 // struct CRITSECT* cs=(struct CRITSECT*)c;
1432 dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c
, cs
);
1435 dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c
);
1438 pthread_mutex_lock(&(cs
->mutex
));
1439 if (cs
->lock_count
== 0) {
1440 dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c
);
1444 if (cs
->lock_count
== 0) {
1445 pthread_cond_signal(&(cs
->unlocked
));
1447 pthread_mutex_unlock(&(cs
->mutex
));
1451 static void expfree(void* mem
); /* forward declaration */
1453 static void WINAPI
expDeleteCriticalSection(CRITICAL_SECTION
*c
)
1455 #ifdef CRITSECS_NEWTYPE
1456 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1458 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1460 // struct CRITSECT* cs=(struct CRITSECT*)c;
1461 dbgprintf("DeleteCriticalSection(0x%x)\n",c
);
1465 dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c
);
1469 pthread_mutex_lock(&(cs
->mutex
));
1470 if (cs
->lock_count
> 0)
1472 dbgprintf("Win32 Warning: Deleting locked Critical Section %p!!\n", c
);
1474 pthread_mutex_unlock(&(cs
->mutex
));
1477 pthread_mutex_destroy(&(cs
->mutex
));
1478 pthread_cond_destroy(&(cs
->unlocked
));
1479 // released by GarbageCollector in my_relase otherwise
1482 #ifdef CRITSECS_NEWTYPE
1484 int i
= critsecs_get_pos(c
);
1488 printf("DeleteCriticalSection(%p) error (critsec not found)\n", c
);
1492 critsecs_list
[i
].cs_win
= NULL
;
1493 expfree(critsecs_list
[i
].cs_unix
);
1494 critsecs_list
[i
].cs_unix
= NULL
;
1495 dbgprintf("DeleteCriticalSection -> itemno=%d\n", i
);
1500 static int WINAPI
expGetCurrentThreadId(void)
1502 dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1503 return pthread_self();
1505 static int WINAPI
expGetCurrentProcess(void)
1507 dbgprintf("GetCurrentProcess() => %d\n", getpid());
1511 #ifdef CONFIG_QTX_CODECS
1512 // this version is required for Quicktime codecs (.qtx/.qts) to work.
1513 // (they assume some pointers at FS: segment)
1515 //static int tls_count;
1516 static int tls_use_map
[64];
1517 static int WINAPI
expTlsAlloc(void)
1521 if(tls_use_map
[i
]==0)
1524 dbgprintf("TlsAlloc() => %d\n",i
);
1527 dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1531 //static int WINAPI expTlsSetValue(DWORD index, void* value)
1532 static int WINAPI
expTlsSetValue(int index
, void* value
)
1534 dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index
,value
);
1535 // if((index<0) || (index>64))
1538 *(void**)((char*)fs_seg
+0x88+4*index
) = value
;
1542 static void* WINAPI
expTlsGetValue(DWORD index
)
1544 dbgprintf("TlsGetValue(%d)\n",index
);
1545 // if((index<0) || (index>64))
1546 if((index
>=64)) return NULL
;
1547 return *(void**)((char*)fs_seg
+0x88+4*index
);
1550 static int WINAPI
expTlsFree(int idx
)
1552 int index
= (int) idx
;
1553 dbgprintf("TlsFree(%d)\n",index
);
1554 if((index
<0) || (index
>64))
1556 tls_use_map
[index
]=0;
1568 static void* WINAPI
expTlsAlloc(void)
1572 g_tls
=my_mreq(sizeof(tls_t
), 0);
1573 g_tls
->next
=g_tls
->prev
=NULL
;
1577 g_tls
->next
=my_mreq(sizeof(tls_t
), 0);
1578 g_tls
->next
->prev
=g_tls
;
1579 g_tls
->next
->next
=NULL
;
1582 dbgprintf("TlsAlloc() => 0x%x\n", g_tls
);
1584 g_tls
->value
=0; /* XXX For Divx.dll */
1588 static int WINAPI
expTlsSetValue(void* idx
, void* value
)
1590 tls_t
* index
= (tls_t
*) idx
;
1599 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index
, value
, result
);
1602 static void* WINAPI
expTlsGetValue(void* idx
)
1604 tls_t
* index
= (tls_t
*) idx
;
1609 result
=index
->value
;
1610 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index
, result
);
1613 static int WINAPI
expTlsFree(void* idx
)
1615 tls_t
* index
= (tls_t
*) idx
;
1622 index
->next
->prev
=index
->prev
;
1624 index
->prev
->next
=index
->next
;
1626 g_tls
= index
->prev
;
1627 my_release((void*)index
);
1630 dbgprintf("TlsFree(index 0x%x) => %d\n", index
, result
);
1635 static void* WINAPI
expLocalAlloc(int flags
, int size
)
1637 void* z
= my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1639 printf("LocalAlloc() failed\n");
1640 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1644 static void* WINAPI
expLocalReAlloc(int handle
,int size
, int flags
)
1650 if (flags
& LMEM_MODIFY
) {
1651 dbgprintf("LocalReAlloc MODIFY\n");
1652 return (void *)handle
;
1654 oldsize
= my_size((void *)handle
);
1655 newpointer
= my_realloc((void *)handle
,size
);
1656 dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle
,size
,oldsize
, flags
,newpointer
);
1661 static void* WINAPI
expLocalLock(void* z
)
1663 dbgprintf("LocalLock(0x%x) => 0x%x\n", z
, z
);
1667 static void* WINAPI
expGlobalAlloc(int flags
, int size
)
1670 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size
, flags
);
1672 z
=my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1673 //z=calloc(size, 1);
1676 printf("GlobalAlloc() failed\n");
1677 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1680 static void* WINAPI
expGlobalLock(void* z
)
1682 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z
, z
);
1685 // pvmjpg20 - but doesn't work anyway
1686 static int WINAPI
expGlobalSize(void* amem
)
1690 alloc_header
* header
= last_alloc
;
1691 alloc_header
* mem
= (alloc_header
*) amem
- 1;
1694 pthread_mutex_lock(&memmut
);
1697 if (header
->deadbeef
!= 0xdeadbeef)
1699 dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
1705 size
= header
->size
;
1709 header
= header
->prev
;
1711 pthread_mutex_unlock(&memmut
);
1714 dbgprintf("GlobalSize(0x%x)\n", amem
);
1718 static int WINAPI
expLoadIconA( long hinstance
, char *name
)
1720 dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance
,name
);
1724 static int WINAPI
expLoadStringA(long instance
, long id
, void* buf
, long size
)
1726 int result
=LoadStringA(instance
, id
, buf
, size
);
1728 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1729 instance
, id
, buf
, size
, result
, buf
);
1731 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1732 // instance, id, buf, size, result);
1736 static long WINAPI
expMultiByteToWideChar(long v1
, long v2
, char* s1
, long siz1
, short* s2
, int siz2
)
1745 if(siz1
>siz2
/2)siz1
=siz2
/2;
1746 for(i
=1; i
<=siz1
; i
++)
1756 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1757 "size %d, dest buffer 0x%x, dest size %d) => %d\n",
1758 v1
, v2
, s1
, s1
, siz1
, s2
, siz2
, result
);
1760 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1761 "size %d, dest buffer 0x%x, dest size %d) =>\n",
1762 v1
, v2
, siz1
, s2
, siz2
, result
);
1765 static void wch_print(const short* str
)
1767 dbgprintf(" src: ");
1768 while(*str
)dbgprintf("%c", *str
++);
1771 static long WINAPI
expWideCharToMultiByte(long v1
, long v2
, short* s1
, long siz1
,
1772 char* s2
, int siz2
, char* c3
, int* siz3
)
1775 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1776 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1777 result
=WideCharToMultiByte(v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1778 dbgprintf("=> %d\n", result
);
1779 //if(s1)wch_print(s1);
1780 if(s2
)dbgprintf(" dest: %s\n", s2
);
1784 static long WINAPI
expGetVersionExA(OSVERSIONINFOA
* c
)
1786 dbgprintf("GetVersionExA(0x%x) => 1\n", c
);
1787 c
->dwOSVersionInfoSize
=sizeof(*c
);
1788 c
->dwMajorVersion
=5;
1789 c
->dwMinorVersion
=1;
1790 c
->dwBuildNumber
=0x5010a28;
1791 c
->dwPlatformId
=VER_PLATFORM_WIN32_NT
;
1792 strcpy(c
->szCSDVersion
, "Service Pack 2");
1793 dbgprintf(" Major version: 5\n Minor version: 1\n Build number: 0x5010a28\n"
1794 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 2'\n");
1798 static long WINAPI
expGetVersionExW(OSVERSIONINFOW
* c
)
1800 char CSDVersion
[128];
1801 dbgprintf("GetVersionExW(0x%x) => 1\n", c
);
1802 c
->dwOSVersionInfoSize
=sizeof(*c
);
1803 c
->dwMajorVersion
=5;
1804 c
->dwMinorVersion
=1;
1805 c
->dwBuildNumber
=0x5010a28;
1806 c
->dwPlatformId
=VER_PLATFORM_WIN32_NT
;
1807 strcpy(CSDVersion
, "Service Pack 2");
1808 MultiByteToWideChar(65001, 0x0, CSDVersion
, -1, c
->szCSDVersion
, 128);
1809 dbgprintf(" Major version: 5\n Minor version: 1\n Build number: 0x5010a28\n"
1810 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 2'\n");
1814 static HANDLE WINAPI
expCreateSemaphoreA(char* v1
, long init_count
,
1815 long max_count
, char* name
)
1817 pthread_mutex_t
*pm
;
1822 printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1826 printf("%p => ", pp);
1831 pthread_mutex_lock(&mlist_lock
);
1834 mutex_list
* pp
=mlist
;
1838 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==1))
1840 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1841 v1
, init_count
, max_count
, name
, name
, mlist
);
1842 ret
= (HANDLE
)mlist
;
1843 pthread_mutex_unlock(&mlist_lock
);
1846 }while((pp
=pp
->prev
) != NULL
);
1848 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
1849 pthread_mutex_init(pm
, NULL
);
1850 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
1851 pthread_cond_init(pc
, NULL
);
1854 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1855 mlist
->next
=mlist
->prev
=NULL
;
1859 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1860 mlist
->next
->prev
=mlist
;
1861 mlist
->next
->next
=NULL
;
1863 // printf("new semaphore %p\n", mlist);
1865 mlist
->type
=1; /* Type Semaphore */
1870 mlist
->semaphore
=init_count
;
1872 strncpy(mlist
->name
, name
, 64);
1876 dbgprintf("ERROR::: CreateSemaphoreA failure\n");
1878 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1879 v1
, init_count
, max_count
, name
, name
, mlist
);
1881 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1882 v1
, init_count
, max_count
, mlist
);
1883 ret
= (HANDLE
)mlist
;
1884 pthread_mutex_unlock(&mlist_lock
);
1888 static HANDLE WINAPI
expCreateSemaphoreW(char* v1
, long init_count
,
1889 long max_count
, const WCHAR
* name
)
1891 char ascii_name
[256];
1894 WideCharToMultiByte(65001, 0x0, name
, -1, ascii_name
, 256, NULL
, NULL
);
1897 return expCreateSemaphoreA(v1
, init_count
, max_count
, aname
);
1900 static long WINAPI
expReleaseSemaphore(long hsem
, long increment
, long* prev_count
)
1902 // The state of a semaphore object is signaled when its count
1903 // is greater than zero and nonsignaled when its count is equal to zero
1904 // Each time a waiting thread is released because of the semaphore's signaled
1905 // state, the count of the semaphore is decreased by one.
1906 mutex_list
*ml
= (mutex_list
*)hsem
;
1908 pthread_mutex_lock(ml
->pm
);
1909 if (prev_count
!= 0) *prev_count
= ml
->semaphore
;
1910 if (ml
->semaphore
== 0) pthread_cond_signal(ml
->pc
);
1911 ml
->semaphore
+= increment
;
1912 pthread_mutex_unlock(ml
->pm
);
1913 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1914 hsem
, increment
, prev_count
);
1918 static HANDLE WINAPI
expCreateMutexA(void *pSecAttr
,
1919 char bInitialOwner
, const char *name
)
1921 pthread_mutex_t
*pm
;
1924 pthread_mutex_lock(&mlist_lock
);
1927 mutex_list
* pp
=mlist
;
1931 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==2))
1933 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n", pSecAttr
, bInitialOwner
, name
, mlist
);
1934 ret
= (HANDLE
)mlist
;
1935 pthread_mutex_unlock(&mlist_lock
);
1938 }while((pp
=pp
->prev
) != NULL
);
1940 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
1941 pthread_mutex_init(pm
, NULL
);
1942 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
1943 pthread_cond_init(pc
, NULL
);
1946 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1947 mlist
->next
=mlist
->prev
=NULL
;
1951 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1952 mlist
->next
->prev
=mlist
;
1953 mlist
->next
->next
=NULL
;
1956 mlist
->type
=2; /* Type Mutex */
1962 if (bInitialOwner
) {
1963 mlist
->owner
= pthread_self();
1964 mlist
->lock_count
= 1;
1966 mlist
->owner
= (pthread_t
)0;
1967 mlist
->lock_count
= 0;
1970 strncpy(mlist
->name
, name
, 64);
1974 dbgprintf("ERROR::: CreateMutexA failure\n");
1976 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
1977 pSecAttr
, bInitialOwner
, name
, mlist
);
1979 dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
1980 pSecAttr
, bInitialOwner
, mlist
);
1981 ret
= (HANDLE
)mlist
;
1982 pthread_mutex_unlock(&mlist_lock
);
1986 static HANDLE WINAPI
expCreateMutexW(void *pSecAttr
, char bInitialOwner
, const WCHAR
*name
)
1988 char ascii_name
[256];
1991 WideCharToMultiByte(65001, 0x0, name
, -1, ascii_name
, 256, NULL
, NULL
);
1994 return expCreateMutexA(pSecAttr
, bInitialOwner
, aname
);
1997 static int WINAPI
expReleaseMutex(HANDLE hMutex
)
1999 mutex_list
*ml
= (mutex_list
*)hMutex
;
2001 pthread_mutex_lock(ml
->pm
);
2002 if (--ml
->lock_count
== 0) pthread_cond_signal(ml
->pc
);
2003 pthread_mutex_unlock(ml
->pm
);
2007 static DWORD WINAPI
expSignalObjectAndWait(HANDLE hObjectToSignal
,
2008 HANDLE hObjectToWaitOn
,
2009 DWORD dwMilliseconds
,
2010 WIN_BOOL bAlertable
) {
2011 mutex_list
* mlist
= (mutex_list
*)hObjectToSignal
;
2013 switch (mlist
->type
) {
2017 case 1: // Semaphore
2018 expReleaseSemaphore(mlist
, 1, NULL
);
2021 expReleaseMutex(mlist
);
2024 dbgprintf("Signalling unknown object type %d!\n", hObjectToSignal
);
2026 return expWaitForSingleObject(hObjectToWaitOn
, dwMilliseconds
);
2029 static long WINAPI
expRegOpenKeyExA(long key
, const char* subkey
, long reserved
, long access
, int* newkey
)
2031 long result
=RegOpenKeyExA(key
, subkey
, reserved
, access
, newkey
);
2032 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
2033 key
, subkey
, reserved
, access
, newkey
, result
);
2034 if(newkey
)dbgprintf(" New key: 0x%x\n", *newkey
);
2037 static long WINAPI
expRegCloseKey(long key
)
2039 long result
=RegCloseKey(key
);
2040 dbgprintf("RegCloseKey(0x%x) => %d\n", key
, result
);
2043 static long WINAPI
expRegQueryValueExA(long key
, const char* value
, int* reserved
, int* type
, int* data
, int* count
)
2045 long result
=RegQueryValueExA(key
, value
, reserved
, type
, data
, count
);
2046 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
2047 " => 0x%x\n", key
, value
, reserved
, data
, count
, result
);
2048 if(data
&& count
)dbgprintf(" read %d bytes: '%s'\n", *count
, data
);
2052 //from wine source dlls/advapi32/registry.c
2053 static long WINAPI
expRegCreateKeyA(long hkey
, const char* name
, int *retkey
)
2055 dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey
,name
,retkey
);
2056 return RegCreateKeyExA( hkey
, name
, 0, NULL
,REG_OPTION_NON_VOLATILE
,
2057 KEY_ALL_ACCESS
, NULL
, retkey
, NULL
);
2060 static long WINAPI
expRegCreateKeyExA(long key
, const char* name
, long reserved
,
2061 void* classs
, long options
, long security
,
2062 void* sec_attr
, int* newkey
, int* status
)
2064 long result
=RegCreateKeyExA(key
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
);
2065 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
2066 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
2067 key
, name
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
, result
);
2068 if(!result
&& newkey
) dbgprintf(" New key: 0x%x\n", *newkey
);
2069 if(!result
&& status
) dbgprintf(" New key status: 0x%x\n", *status
);
2072 static long WINAPI
expRegSetValueExA(long key
, const char* name
, long v1
, long v2
, void* data
, long size
)
2074 long result
=RegSetValueExA(key
, name
, v1
, v2
, data
, size
);
2075 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
2076 key
, name
, v1
, v2
, data
, *(int*)data
, data
, size
, result
);
2080 static long WINAPI
expRegOpenKeyA (long hKey
, LPCSTR lpSubKey
, int* phkResult
)
2082 long result
=RegOpenKeyExA(hKey
, lpSubKey
, 0, 0, phkResult
);
2083 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
2084 hKey
, lpSubKey
, phkResult
, result
);
2085 if(!result
&& phkResult
) dbgprintf(" New key: 0x%x\n", *phkResult
);
2089 static DWORD WINAPI
expRegEnumValueA(HKEY hkey
, DWORD index
, LPSTR value
, LPDWORD val_count
,
2090 LPDWORD reserved
, LPDWORD type
, LPBYTE data
, LPDWORD count
)
2092 return RegEnumValueA(hkey
, index
, value
, val_count
,
2093 reserved
, type
, data
, count
);
2096 static DWORD WINAPI
expRegEnumKeyExA(HKEY hKey
, DWORD dwIndex
, LPSTR lpName
, LPDWORD lpcbName
,
2097 LPDWORD lpReserved
, LPSTR lpClass
, LPDWORD lpcbClass
,
2098 LPFILETIME lpftLastWriteTime
)
2100 return RegEnumKeyExA(hKey
, dwIndex
, lpName
, lpcbName
, lpReserved
, lpClass
,
2101 lpcbClass
, lpftLastWriteTime
);
2104 static long WINAPI
expQueryPerformanceCounter(long long* z
)
2107 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z
, *z
);
2112 * dummy function RegQueryInfoKeyA(), required by vss codecs
2114 static DWORD WINAPI
expRegQueryInfoKeyA( HKEY hkey
, LPSTR
class, LPDWORD class_len
, LPDWORD reserved
,
2115 LPDWORD subkeys
, LPDWORD max_subkey
, LPDWORD max_class
,
2116 LPDWORD values
, LPDWORD max_value
, LPDWORD max_data
,
2117 LPDWORD security
, FILETIME
*modif
)
2119 return ERROR_SUCCESS
;
2123 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
2125 static double linux_cpuinfo_freq(void)
2132 f
= fopen ("/proc/cpuinfo", "r");
2134 while (fgets(line
,sizeof(line
),f
)!=NULL
) {
2135 /* NOTE: the ':' is the only character we can rely on */
2136 if (!(value
= strchr(line
,':')))
2138 /* terminate the valuename */
2140 /* skip any leading spaces */
2141 while (*value
==' ') value
++;
2142 if ((s
=strchr(value
,'\n')))
2145 if (!strncasecmp(line
, "cpu MHz",strlen("cpu MHz"))
2146 && sscanf(value
, "%lf", &freq
) == 1) {
2157 static double solaris_kstat_freq(void)
2159 #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
2161 * try to extract the CPU speed from the solaris kernel's kstat data
2165 kstat_named_t
*kdata
;
2171 ksp
= kstat_lookup(kc
, "cpu_info", 0, "cpu_info0");
2173 /* kstat found and name/value pairs? */
2174 if (ksp
!= NULL
&& ksp
->ks_type
== KSTAT_TYPE_NAMED
)
2176 /* read the kstat data from the kernel */
2177 if (kstat_read(kc
, ksp
, NULL
) != -1)
2180 * lookup desired "clock_MHz" entry, check the expected
2183 kdata
= (kstat_named_t
*)kstat_data_lookup(ksp
, "clock_MHz");
2184 if (kdata
!= NULL
&& kdata
->data_type
== KSTAT_DATA_INT32
)
2185 mhz
= kdata
->value
.i32
;
2193 #endif /* HAVE_LIBKSTAT */
2194 return -1; // kstat stuff is not available, CPU freq is unknown
2198 * Measure CPU freq using the pentium's time stamp counter register (TSC)
2200 static double tsc_freq(void)
2202 static double ofreq
=0.0;
2206 if (ofreq
!= 0.0) return ofreq
;
2207 while(i
==time(NULL
));
2210 while(i
==time(NULL
));
2212 ofreq
= (double)(y
-x
)/1000.;
2216 static double CPU_Freq(void)
2220 if ((freq
= linux_cpuinfo_freq()) > 0)
2223 if ((freq
= solaris_kstat_freq()) > 0)
2229 static long WINAPI
expQueryPerformanceFrequency(long long* z
)
2231 *z
=(long long)CPU_Freq();
2232 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z
, *z
);
2235 static long WINAPI
exptimeGetTime(void)
2239 gettimeofday(&t
, 0);
2240 result
=1000*t
.tv_sec
+t
.tv_usec
/1000;
2241 dbgprintf("timeGetTime() => %d\n", result
);
2244 static void* WINAPI
expLocalHandle(void* v
)
2246 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v
, v
);
2250 static void* WINAPI
expGlobalHandle(void* v
)
2252 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v
, v
);
2255 static int WINAPI
expGlobalUnlock(void* v
)
2257 dbgprintf("GlobalUnlock(0x%x) => 1\n", v
);
2260 static void* WINAPI
expGlobalFree(void* v
)
2262 dbgprintf("GlobalFree(0x%x) => 0\n", v
);
2268 static void* WINAPI
expGlobalReAlloc(void* v
, int size
, int flags
)
2270 void* result
=my_realloc(v
, size
);
2271 //void* result=realloc(v, size);
2272 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v
,size
,flags
,result
);
2276 static int WINAPI
expLocalUnlock(void* v
)
2278 dbgprintf("LocalUnlock(0x%x) => 1\n", v
);
2282 static void* WINAPI
expLocalFree(void* v
)
2284 dbgprintf("LocalFree(0x%x) => 0\n", v
);
2288 static HRSRC WINAPI
expFindResourceA(HMODULE module
, char* name
, char* type
)
2292 result
=FindResourceA(module
, name
, type
);
2293 dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2294 module
, name
, HIWORD(name
) ? name
: "UNICODE", type
, HIWORD(type
) ? type
: "UNICODE", result
);
2298 static HGLOBAL WINAPI
expLoadResource(HMODULE module
, HRSRC res
)
2300 HGLOBAL result
=LoadResource(module
, res
);
2301 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module
, res
, result
);
2304 static void* WINAPI
expLockResource(long res
)
2306 void* result
=LockResource(res
);
2307 dbgprintf("LockResource(0x%x) => 0x%x\n", res
, result
);
2310 static int WINAPI
expFreeResource(long res
)
2312 int result
=FreeResource(res
);
2313 dbgprintf("FreeResource(0x%x) => %d\n", res
, result
);
2318 static int WINAPI
expCloseHandle(long v1
)
2320 dbgprintf("CloseHandle(0x%x) => 1\n", v1
);
2321 /* do not close stdin,stdout and stderr */
2328 static const char* WINAPI
expGetCommandLineA(void)
2330 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2331 return "c:\\aviplay.exe";
2333 static short envs
[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2334 static LPWSTR WINAPI
expGetEnvironmentStringsW(void)
2336 dbgprintf("GetEnvironmentStringsW() => 0\n", envs
);
2339 static void * WINAPI
expRtlZeroMemory(void *p
, size_t len
)
2341 void* result
=memset(p
,0,len
);
2342 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p
,len
,result
);
2345 static void * WINAPI
expRtlMoveMemory(void *dst
, void *src
, size_t len
)
2347 void* result
=memmove(dst
,src
,len
);
2348 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst
,src
,len
,result
);
2352 static void * WINAPI
expRtlFillMemory(void *p
, int ch
, size_t len
)
2354 void* result
=memset(p
,ch
,len
);
2355 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p
,ch
,len
,result
);
2358 static int WINAPI
expFreeEnvironmentStringsW(short* strings
)
2360 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings
);
2363 static int WINAPI
expFreeEnvironmentStringsA(char* strings
)
2365 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings
);
2369 static const char ch_envs
[]=
2370 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2371 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2372 static LPCSTR WINAPI
expGetEnvironmentStrings(void)
2374 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs
);
2375 return (LPCSTR
)ch_envs
;
2376 // dbgprintf("GetEnvironmentStrings() => 0\n");
2380 static int WINAPI
expGetStartupInfoA(STARTUPINFOA
*s
)
2382 dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2383 memset(s
, 0, sizeof(*s
));
2385 // s->lpReserved="Reserved";
2386 // s->lpDesktop="Desktop";
2387 // s->lpTitle="Title";
2389 // s->dwXSize=s->dwYSize=200;
2390 s
->dwFlags
=s
->wShowWindow
=1;
2391 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2392 dbgprintf(" cb=%d\n", s
->cb
);
2393 dbgprintf(" lpReserved='%s'\n", s
->lpReserved
);
2394 dbgprintf(" lpDesktop='%s'\n", s
->lpDesktop
);
2395 dbgprintf(" lpTitle='%s'\n", s
->lpTitle
);
2396 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2397 s
->dwX
, s
->dwY
, s
->dwXSize
, s
->dwYSize
);
2398 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2399 s
->dwXCountChars
, s
->dwYCountChars
, s
->dwFillAttribute
);
2400 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2401 s
->dwFlags
, s
->wShowWindow
, s
->cbReserved2
);
2402 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2403 s
->lpReserved2
, s
->hStdInput
, s
->hStdOutput
, s
->hStdError
);
2407 static int WINAPI
expGetStdHandle(int z
)
2409 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z
+0x1234);
2413 #ifdef CONFIG_QTX_CODECS
2414 #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2415 #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2418 static int WINAPI
expGetFileType(int handle
)
2420 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle
);
2423 #ifdef CONFIG_QTX_CODECS
2424 static int WINAPI
expGetFileAttributesA(char *filename
)
2426 dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename
);
2427 if (strstr(filename
, "QuickTime.qts"))
2428 return FILE_ATTRIBUTE_SYSTEM
;
2429 return FILE_ATTRIBUTE_NORMAL
;
2432 static int WINAPI
expSetHandleCount(int count
)
2434 dbgprintf("SetHandleCount(0x%x) => 1\n", count
);
2437 static int WINAPI
expGetACP(void)
2439 dbgprintf("GetACP() => 0\n");
2442 static int WINAPI
expGetModuleFileNameA(int module
, char* s
, int len
)
2446 //printf("File name of module %X (%s) requested\n", module, s);
2448 if (module
== 0 && len
>= 12)
2450 /* return caller program name */
2451 strcpy(s
, "aviplay.dll");
2462 strcpy(s
, "c:\\windows\\system\\");
2463 mr
=MODULE32_LookupHMODULE(module
);
2465 strcat(s
, "aviplay.dll");
2467 if(strrchr(mr
->filename
, '/')==NULL
)
2468 strcat(s
, mr
->filename
);
2470 strcat(s
, strrchr(mr
->filename
, '/')+1);
2473 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2474 module
, s
, len
, result
);
2476 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2477 module
, s
, len
, result
, s
);
2481 static int WINAPI
expGetModuleBaseNameA(int process
, int module
, char* s
, int len
)
2486 av_strlcpy(s
, "aviplay.dll", len
);
2490 dbgprintf("GetModuleBaseNameA(0x%x, 0x%x, 0x%x, %d) => %d\n",
2491 process
, module
, s
, len
, result
);
2496 static int WINAPI
expSetUnhandledExceptionFilter(void* filter
)
2498 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter
);
2499 return 1;//unsupported and probably won't ever be supported
2502 static int WINAPI
expLoadLibraryA(char* name
)
2508 // we skip to the last backslash
2509 // this is effectively eliminating weird characters in
2510 // the text output windows
2512 lastbc
= strrchr(name
, '\\');
2519 name
[i
] = *lastbc
++;
2524 if(strncmp(name
, "c:\\windows\\", 11)==0) name
+= 11;
2525 if(strncmp(name
, ".\\", 2)==0) name
+= 2;
2527 dbgprintf("Entering LoadLibraryA(%s)\n", name
);
2529 // PIMJ and VIVO audio are loading kernel32.dll
2530 if (strcasecmp(name
, "kernel32.dll") == 0 || strcasecmp(name
, "kernel32") == 0)
2531 return MODULE_HANDLE_kernel32
;
2532 // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2533 /* exported -> do not return failed! */
2535 if (strcasecmp(name
, "user32.dll") == 0 || strcasecmp(name
, "user32") == 0)
2536 // return MODULE_HANDLE_kernel32;
2537 return MODULE_HANDLE_user32
;
2539 #ifdef CONFIG_QTX_CODECS
2540 if (strcasecmp(name
, "wininet.dll") == 0 || strcasecmp(name
, "wininet") == 0)
2541 return MODULE_HANDLE_wininet
;
2542 if (strcasecmp(name
, "ddraw.dll") == 0 || strcasecmp(name
, "ddraw") == 0)
2543 return MODULE_HANDLE_ddraw
;
2544 if (strcasecmp(name
, "advapi32.dll") == 0 || strcasecmp(name
, "advapi32") == 0)
2545 return MODULE_HANDLE_advapi32
;
2548 if (strcasecmp(name
, "comdlg32.dll") == 0 || strcasecmp(name
, "comdlg32") == 0)
2549 return MODULE_HANDLE_comdlg32
;
2550 if (strcasecmp(name
, "msvcrt.dll") == 0 || strcasecmp(name
, "msvcrt") == 0)
2551 return MODULE_HANDLE_msvcrt
;
2552 if (strcasecmp(name
, "ole32.dll") == 0 || strcasecmp(name
, "ole32") == 0)
2553 return MODULE_HANDLE_ole32
;
2554 if (strcasecmp(name
, "winmm.dll") == 0 || strcasecmp(name
, "winmm") == 0)
2555 return MODULE_HANDLE_winmm
;
2556 if (strcasecmp(name
, "psapi.dll") == 0 || strcasecmp(name
, "psapi") == 0)
2557 return MODULE_HANDLE_psapi
;
2559 result
=LoadLibraryA(name
);
2560 dbgprintf("Returned LoadLibraryA(0x%x='%s'), codec_path=%s => 0x%x\n",
2561 name
, name
, codec_path
, result
);
2566 static int WINAPI
expFreeLibrary(int module
)
2568 #ifdef CONFIG_QTX_CODECS
2569 int result
=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2571 int result
=FreeLibrary(module
);
2573 dbgprintf("FreeLibrary(0x%x) => %d\n", module
, result
);
2577 static void* WINAPI
expGetProcAddress(HMODULE mod
, char* name
)
2581 case MODULE_HANDLE_kernel32
:
2582 result
=LookupExternalByName("kernel32.dll", name
); break;
2583 case MODULE_HANDLE_user32
:
2584 result
=LookupExternalByName("user32.dll", name
); break;
2585 #ifdef CONFIG_QTX_CODECS
2586 case MODULE_HANDLE_wininet
:
2587 result
=LookupExternalByName("wininet.dll", name
); break;
2588 case MODULE_HANDLE_ddraw
:
2589 result
=LookupExternalByName("ddraw.dll", name
); break;
2590 case MODULE_HANDLE_advapi32
:
2591 result
=LookupExternalByName("advapi32.dll", name
); break;
2593 case MODULE_HANDLE_comdlg32
:
2594 result
=LookupExternalByName("comdlg32.dll", name
); break;
2595 case MODULE_HANDLE_msvcrt
:
2596 result
=LookupExternalByName("msvcrt.dll", name
); break;
2597 case MODULE_HANDLE_ole32
:
2598 result
=LookupExternalByName("ole32.dll", name
); break;
2599 case MODULE_HANDLE_winmm
:
2600 result
=LookupExternalByName("winmm.dll", name
); break;
2601 case MODULE_HANDLE_psapi
:
2602 result
=LookupExternalByName("psapi.dll", name
); break;
2604 result
=GetProcAddress(mod
, name
);
2606 if((unsigned int)name
> 0xffff)
2607 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod
, name
, result
);
2609 dbgprintf("GetProcAddress(0x%x, '%d') => 0x%x\n", mod
, (int)name
, result
);
2613 static long WINAPI
expCreateFileMappingA(int hFile
, void* lpAttr
,
2614 long flProtect
, long dwMaxHigh
,
2615 long dwMaxLow
, const char* name
)
2617 long result
=CreateFileMappingA(hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
);
2619 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2620 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2621 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, result
);
2623 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2624 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2625 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
, name
, result
);
2629 static long WINAPI
expOpenFileMappingA(long hFile
, long hz
, const char* name
)
2631 long result
=OpenFileMappingA(hFile
, hz
, name
);
2633 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2636 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2637 hFile
, hz
, name
, name
, result
);
2641 static void* WINAPI
expMapViewOfFile(HANDLE file
, DWORD mode
, DWORD offHigh
,
2642 DWORD offLow
, DWORD size
)
2644 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2645 file
,mode
,offHigh
,offLow
,size
,(char*)file
+offLow
);
2646 return (char*)file
+offLow
;
2649 static void* WINAPI
expUnmapViewOfFile(void* view
)
2651 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view
);
2655 static void* WINAPI
expSleep(int time
)
2658 /* solaris doesn't have thread safe usleep */
2659 struct timespec tsp
;
2660 tsp
.tv_sec
= time
/ 1000000;
2661 tsp
.tv_nsec
= (time
% 1000000) * 1000;
2662 nanosleep(&tsp
, NULL
);
2666 dbgprintf("Sleep(%d) => 0\n", time
);
2670 // why does IV32 codec want to call this? I don't know ...
2671 static int WINAPI
expCreateCompatibleDC(int hdc
)
2674 //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2675 dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc
, dc
);
2679 static int WINAPI
expGetDeviceCaps(int hdc
, int unk
)
2681 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc
, unk
);
2682 #ifdef CONFIG_QTX_CODECS
2683 #define BITSPIXEL 12
2685 if (unk
== BITSPIXEL
)
2693 static WIN_BOOL WINAPI
expDeleteDC(int hdc
)
2695 dbgprintf("DeleteDC(0x%x) => 0\n", hdc
);
2701 static WIN_BOOL WINAPI
expDeleteObject(int hdc
)
2703 dbgprintf("DeleteObject(0x%x) => 1\n", hdc
);
2704 /* FIXME - implement code here */
2708 /* btvvc32.drv wants this one */
2709 static void* WINAPI
expGetWindowDC(int hdc
)
2711 dbgprintf("GetWindowDC(%d) => 0x0\n", hdc
);
2715 #ifdef CONFIG_QTX_CODECS
2716 static int WINAPI
expGetWindowRect(HWND win
, RECT
*r
)
2718 dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win
, r
);
2719 /* (win == 0) => desktop */
2720 r
->right
= PSEUDO_SCREEN_WIDTH
;
2722 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
2727 static int WINAPI
expMonitorFromWindow(HWND win
, int flags
)
2729 dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win
, flags
);
2733 static int WINAPI
expMonitorFromRect(RECT
*r
, int flags
)
2735 dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r
, flags
);
2739 static int WINAPI
expMonitorFromPoint(void *p
, int flags
)
2741 dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p
, flags
);
2745 static int WINAPI
expEnumDisplayMonitors(void *dc
, RECT
*r
,
2746 int WINAPI (*callback_proc
)(HMONITOR
, HDC
, LPRECT
, LPARAM
), void *callback_param
)
2748 dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2749 dc
, r
, callback_proc
, callback_param
);
2750 return callback_proc(0, dc
, r
, callback_param
);
2754 typedef struct tagMONITORINFO
{
2759 } MONITORINFO
, *LPMONITORINFO
;
2762 #define CCHDEVICENAME 8
2763 typedef struct tagMONITORINFOEX
{
2768 TCHAR szDevice
[CCHDEVICENAME
];
2769 } MONITORINFOEX
, *LPMONITORINFOEX
;
2771 static int WINAPI
expGetMonitorInfoA(void *mon
, LPMONITORINFO lpmi
)
2773 dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon
, lpmi
);
2775 lpmi
->rcMonitor
.right
= lpmi
->rcWork
.right
= PSEUDO_SCREEN_WIDTH
;
2776 lpmi
->rcMonitor
.left
= lpmi
->rcWork
.left
= 0;
2777 lpmi
->rcMonitor
.bottom
= lpmi
->rcWork
.bottom
= PSEUDO_SCREEN_HEIGHT
;
2778 lpmi
->rcMonitor
.top
= lpmi
->rcWork
.top
= 0;
2780 lpmi
->dwFlags
= 1; /* primary monitor */
2782 if (lpmi
->cbSize
== sizeof(MONITORINFOEX
))
2784 LPMONITORINFOEX lpmiex
= (LPMONITORINFOEX
)lpmi
;
2785 dbgprintf("MONITORINFOEX!\n");
2786 strncpy(lpmiex
->szDevice
, "Monitor1", CCHDEVICENAME
);
2792 static int WINAPI
expEnumDisplayDevicesA(const char *device
, int devnum
,
2793 void *dispdev
, int flags
)
2795 dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2796 device
, device
, devnum
, dispdev
, flags
);
2800 static int WINAPI
expIsWindowVisible(HWND win
)
2802 dbgprintf("IsWindowVisible(0x%x) => 1\n", win
);
2806 static HWND WINAPI
expGetActiveWindow(void)
2808 dbgprintf("GetActiveWindow() => 0\n");
2812 static int WINAPI
expGetClassNameA(HWND win
, LPTSTR classname
, int maxcount
)
2814 strncat(classname
, "QuickTime", maxcount
);
2815 dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2816 win
, classname
, maxcount
, strlen(classname
));
2817 return strlen(classname
);
2820 #define LPWNDCLASS void *
2821 static int WINAPI
expGetClassInfoA(HINSTANCE inst
, LPCSTR classname
, LPWNDCLASS wndclass
)
2823 dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst
,
2824 classname
, classname
, wndclass
);
2828 static int WINAPI
expGetWindowLongA(HWND win
, int index
)
2830 dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win
, index
);
2834 static int WINAPI
expGetObjectA(HGDIOBJ hobj
, int objsize
, LPVOID obj
)
2836 dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj
, objsize
, obj
, objsize
);
2840 static int WINAPI
expCreateRectRgn(int x
, int y
, int width
, int height
)
2842 dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x
, y
, width
, height
);
2846 static int WINAPI
expEnumWindows(int (*callback_func
)(HWND
, LPARAM
), void *callback_param
)
2849 dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func
, callback_param
);
2850 i
= callback_func(0, callback_param
);
2851 i2
= callback_func(1, callback_param
);
2855 static int WINAPI
expGetWindowThreadProcessId(HWND win
, int *pid_data
)
2857 int tid
= pthread_self();
2858 dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2859 win
, pid_data
, tid
);
2861 *(int*)pid_data
= tid
;
2865 //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2866 // INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2868 static HWND WINAPI
expCreateWindowExA(int exstyle
, const char *classname
,
2869 const char *winname
, int style
, int x
, int y
, int w
, int h
,
2870 HWND parent
, HMENU menu
, HINSTANCE inst
, LPVOID param
)
2872 printf("CreateWindowEx() called\n");
2873 dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2874 exstyle
, classname
, classname
, winname
, winname
, style
, x
, y
, w
, h
,
2875 parent
, menu
, inst
, param
);
2876 printf("CreateWindowEx() called okey\n");
2880 static int WINAPI
expwaveOutGetNumDevs(void)
2882 dbgprintf("waveOutGetNumDevs() => 0\n");
2888 * Returns the number of milliseconds, modulo 2^32, since the start
2889 * of the wineserver.
2891 static int WINAPI
expGetTickCount(void)
2893 static int tcstart
= 0;
2896 gettimeofday( &t
, NULL
);
2897 tc
= ((t
.tv_sec
* 1000) + (t
.tv_usec
/ 1000)) - tcstart
;
2903 dbgprintf("GetTickCount() => %d\n", tc
);
2907 static int WINAPI
expCreateFontA(void)
2909 dbgprintf("CreateFontA() => 0x0\n");
2913 /* tried to get pvmjpg work in a different way - no success */
2914 static int WINAPI
expDrawTextA(int hDC
, char* lpString
, int nCount
,
2915 LPRECT lpRect
, unsigned int uFormat
)
2917 dbgprintf("expDrawTextA(%p,...) => 8\n", hDC
);
2921 static int WINAPI
expGetPrivateProfileIntA(const char* appname
,
2922 const char* keyname
,
2924 const char* filename
)
2932 if(!(appname
&& keyname
&& filename
) )
2934 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, default_value
);
2935 return default_value
;
2937 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2938 strcpy(fullname
, "Software\\IniFileMapping\\");
2939 strcat(fullname
, appname
);
2940 strcat(fullname
, "\\");
2941 strcat(fullname
, keyname
);
2942 strcat(fullname
, "\\");
2943 strcat(fullname
, filename
);
2944 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)buffer
, &size
);
2945 if((size
>=0)&&(size
<256))
2947 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2950 result
=default_value
;
2952 result
=atoi(buffer
);
2953 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, result
);
2956 static int WINAPI
expGetProfileIntA(const char* appname
,
2957 const char* keyname
,
2960 dbgprintf("GetProfileIntA -> ");
2961 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, "default");
2964 static int WINAPI
expGetPrivateProfileStringA(const char* appname
,
2965 const char* keyname
,
2966 const char* def_val
,
2967 char* dest
, unsigned int len
,
2968 const char* filename
)
2973 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname
, keyname
, def_val
, dest
, len
, filename
);
2974 if(!(appname
&& keyname
&& filename
) ) return 0;
2975 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2976 strcpy(fullname
, "Software\\IniFileMapping\\");
2977 strcat(fullname
, appname
);
2978 strcat(fullname
, "\\");
2979 strcat(fullname
, keyname
);
2980 strcat(fullname
, "\\");
2981 strcat(fullname
, filename
);
2983 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)dest
, &size
);
2987 strncpy(dest
, def_val
, size
);
2988 if (strlen(def_val
)< size
) size
= strlen(def_val
);
2990 dbgprintf(" => %d ( '%s' )\n", size
, dest
);
2993 static int WINAPI
expWritePrivateProfileStringA(const char* appname
,
2994 const char* keyname
,
2996 const char* filename
)
2999 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname
, keyname
, string
, filename
);
3000 if(!(appname
&& keyname
&& filename
) )
3002 dbgprintf(" => -1\n");
3005 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
3006 strcpy(fullname
, "Software\\IniFileMapping\\");
3007 strcat(fullname
, appname
);
3008 strcat(fullname
, "\\");
3009 strcat(fullname
, keyname
);
3010 strcat(fullname
, "\\");
3011 strcat(fullname
, filename
);
3012 RegSetValueExA(HKEY_LOCAL_MACHINE
, fullname
, 0, REG_SZ
, (int*)string
, strlen(string
));
3013 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
3014 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
3016 dbgprintf(" => 0\n");
3020 unsigned int GetPrivateProfileIntA_(const char* appname
, const char* keyname
, INT default_value
, const char* filename
)
3022 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, filename
);
3024 int GetPrivateProfileStringA_(const char* appname
, const char* keyname
,
3025 const char* def_val
, char* dest
, unsigned int len
, const char* filename
)
3027 return expGetPrivateProfileStringA(appname
, keyname
, def_val
, dest
, len
, filename
);
3029 int WritePrivateProfileStringA_(const char* appname
, const char* keyname
,
3030 const char* string
, const char* filename
)
3032 return expWritePrivateProfileStringA(appname
, keyname
, string
, filename
);
3037 static int WINAPI
expDefDriverProc(int private, int id
, int msg
, int arg1
, int arg2
)
3039 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", private, id
, msg
, arg1
, arg2
);
3043 static int WINAPI
expSizeofResource(int v1
, int v2
)
3045 int result
=SizeofResource(v1
, v2
);
3046 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1
, v2
, result
);
3050 static int WINAPI
expGetLastError(void)
3052 int result
=GetLastError();
3053 dbgprintf("GetLastError() => 0x%x\n", result
);
3057 static void WINAPI
expSetLastError(int error
)
3059 dbgprintf("SetLastError(0x%x)\n", error
);
3060 SetLastError(error
);
3063 static int WINAPI
expStringFromGUID2(GUID
* guid
, char* str
, int cbMax
)
3065 int result
=snprintf(str
, cbMax
, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
3066 guid
->f1
, guid
->f2
, guid
->f3
,
3067 (unsigned char)guid
->f4
[0], (unsigned char)guid
->f4
[1],
3068 (unsigned char)guid
->f4
[2], (unsigned char)guid
->f4
[3],
3069 (unsigned char)guid
->f4
[4], (unsigned char)guid
->f4
[5],
3070 (unsigned char)guid
->f4
[6], (unsigned char)guid
->f4
[7]);
3071 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid
, str
, str
, cbMax
, result
);
3076 static int WINAPI
expGetFileVersionInfoSizeA(const char* name
, int* lpHandle
)
3078 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name
, name
, lpHandle
);
3082 static int WINAPI
expIsBadStringPtrW(const short* string
, int nchars
)
3085 if(string
==0)result
=1; else result
=0;
3086 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string
, nchars
, result
);
3087 if(string
)wch_print(string
);
3090 static int WINAPI
expIsBadStringPtrA(const char* string
, int nchars
)
3092 return expIsBadStringPtrW((const short*)string
, nchars
);
3094 static long WINAPI
expInterlockedExchangeAdd( long* dest
, long incr
)
3099 "lock; xaddl %0,(%1)"
3101 : "r" (dest
), "0" (incr
)
3107 static long WINAPI
expInterlockedCompareExchange( unsigned long* dest
, unsigned long exchange
, unsigned long comperand
)
3109 unsigned long retval
= *dest
;
3110 if(*dest
== comperand
)
3115 static long WINAPI
expInterlockedIncrement( long* dest
)
3117 long result
=expInterlockedExchangeAdd( dest
, 1 ) + 1;
3118 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
3121 static long WINAPI
expInterlockedDecrement( long* dest
)
3123 long result
=expInterlockedExchangeAdd( dest
, -1 ) - 1;
3124 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
3128 static void WINAPI
expOutputDebugStringA( const char* string
)
3130 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string
);
3131 fprintf(stderr
, "DEBUG: %s\n", string
);
3134 static int WINAPI
expGetDC(int hwnd
)
3136 dbgprintf("GetDC(0x%x) => 1\n", hwnd
);
3140 static int WINAPI
expReleaseDC(int hwnd
, int hdc
)
3142 dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd
, hdc
);
3146 static int WINAPI
expGetDesktopWindow(void)
3148 dbgprintf("GetDesktopWindow() => 0\n");
3152 static int cursor
[100];
3154 static int WINAPI
expLoadCursorA(int handle
,LPCSTR name
)
3156 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle
, name
, (int)&cursor
[0]);
3157 return (int)&cursor
[0];
3159 static int WINAPI
expSetCursor(void *cursor
)
3161 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor
, cursor
);
3164 static int WINAPI
expGetCursorPos(void *cursor
)
3166 dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor
, cursor
);
3169 #ifdef CONFIG_QTX_CODECS
3170 static int show_cursor
= 0;
3171 static int WINAPI
expShowCursor(int show
)
3173 dbgprintf("ShowCursor(%d) => %d\n", show
, show
);
3181 static int WINAPI
expRegisterWindowMessageA(char *message
)
3183 dbgprintf("RegisterWindowMessageA(%s)\n", message
);
3186 static int WINAPI
expGetProcessVersion(int pid
)
3188 dbgprintf("GetProcessVersion(%d)\n", pid
);
3191 static int WINAPI
expGetCurrentThread(void)
3194 dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
3197 static int WINAPI
expGetOEMCP(void)
3199 dbgprintf("GetOEMCP()\n");
3202 static int WINAPI
expGetCPInfo(int cp
,void *info
)
3204 dbgprintf("GetCPInfo()\n");
3207 #ifdef CONFIG_QTX_CODECS
3208 #define SM_CXSCREEN 0
3209 #define SM_CYSCREEN 1
3210 #define SM_XVIRTUALSCREEN 76
3211 #define SM_YVIRTUALSCREEN 77
3212 #define SM_CXVIRTUALSCREEN 78
3213 #define SM_CYVIRTUALSCREEN 79
3214 #define SM_CMONITORS 80
3216 static int WINAPI
expGetSystemMetrics(int index
)
3218 dbgprintf("GetSystemMetrics(%d)\n", index
);
3219 #ifdef CONFIG_QTX_CODECS
3222 case SM_XVIRTUALSCREEN
:
3223 case SM_YVIRTUALSCREEN
:
3226 case SM_CXVIRTUALSCREEN
:
3227 return PSEUDO_SCREEN_WIDTH
;
3229 case SM_CYVIRTUALSCREEN
:
3230 return PSEUDO_SCREEN_HEIGHT
;
3237 static int WINAPI
expGetSysColor(int index
)
3239 dbgprintf("GetSysColor(%d) => 1\n", index
);
3242 static int WINAPI
expGetSysColorBrush(int index
)
3244 dbgprintf("GetSysColorBrush(%d)\n", index
);
3250 static int WINAPI
expGetSystemPaletteEntries(int hdc
, int iStartIndex
, int nEntries
, void* lppe
)
3252 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3253 hdc
, iStartIndex
, nEntries
, lppe
);
3258 typedef struct TIME_ZONE_INFORMATION {
3260 char StandardName[32];
3261 SYSTEMTIME StandardDate;
3263 char DaylightName[32];
3264 SYSTEMTIME DaylightDate;
3266 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3269 static int WINAPI
expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation
)
3271 const short name
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3272 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3273 const short pname
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3274 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3275 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3276 memset(lpTimeZoneInformation
, 0, sizeof(TIME_ZONE_INFORMATION
));
3277 lpTimeZoneInformation
->Bias
=360;//GMT-6
3278 memcpy(lpTimeZoneInformation
->StandardName
, name
, sizeof(name
));
3279 lpTimeZoneInformation
->StandardDate
.wMonth
=10;
3280 lpTimeZoneInformation
->StandardDate
.wDay
=5;
3281 lpTimeZoneInformation
->StandardDate
.wHour
=2;
3282 lpTimeZoneInformation
->StandardBias
=0;
3283 memcpy(lpTimeZoneInformation
->DaylightName
, pname
, sizeof(pname
));
3284 lpTimeZoneInformation
->DaylightDate
.wMonth
=4;
3285 lpTimeZoneInformation
->DaylightDate
.wDay
=1;
3286 lpTimeZoneInformation
->DaylightDate
.wHour
=2;
3287 lpTimeZoneInformation
->DaylightBias
=-60;
3288 return TIME_ZONE_ID_STANDARD
;
3291 static void WINAPI
expGetLocalTime(SYSTEMTIME
* systime
)
3294 struct tm
*local_tm
;
3297 dbgprintf("GetLocalTime(0x%x)\n");
3298 gettimeofday(&tv
, NULL
);
3299 local_time
=tv
.tv_sec
;
3300 local_tm
=localtime(&local_time
);
3302 systime
->wYear
= local_tm
->tm_year
+ 1900;
3303 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3304 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3305 systime
->wDay
= local_tm
->tm_mday
;
3306 systime
->wHour
= local_tm
->tm_hour
;
3307 systime
->wMinute
= local_tm
->tm_min
;
3308 systime
->wSecond
= local_tm
->tm_sec
;
3309 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3310 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3311 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3312 " Milliseconds: %d\n",
3313 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3314 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3317 static int WINAPI
expGetSystemTime(SYSTEMTIME
* systime
)
3320 struct tm
*local_tm
;
3323 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3324 gettimeofday(&tv
, NULL
);
3325 local_time
=tv
.tv_sec
;
3326 local_tm
=gmtime(&local_time
);
3328 systime
->wYear
= local_tm
->tm_year
+ 1900;
3329 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3330 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3331 systime
->wDay
= local_tm
->tm_mday
;
3332 systime
->wHour
= local_tm
->tm_hour
;
3333 systime
->wMinute
= local_tm
->tm_min
;
3334 systime
->wSecond
= local_tm
->tm_sec
;
3335 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3336 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3337 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3338 " Milliseconds: %d\n",
3339 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3340 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3344 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3345 static void WINAPI
expGetSystemTimeAsFileTime(FILETIME
* systime
)
3348 unsigned long long secs
;
3350 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3351 gettimeofday(&tv
, NULL
);
3352 secs
= (tv
.tv_sec
+ SECS_1601_TO_1970
) * 10000000;
3353 secs
+= tv
.tv_usec
* 10;
3354 systime
->dwLowDateTime
= secs
& 0xffffffff;
3355 systime
->dwHighDateTime
= (secs
>> 32);
3358 static int WINAPI
expGetEnvironmentVariableA(const char* name
, char* field
, int size
)
3361 // printf("%s %x %x\n", name, field, size);
3362 if(field
)field
[0]=0;
3365 if (p) strncpy(field,p,size);
3367 if (strcmp(name
,"__MSVCRT_HEAP_SELECT")==0)
3368 strcpy(field
,"__GLOBAL_HEAP_SELECTED,1");
3369 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name
, name
, field
, size
, strlen(field
));
3370 return strlen(field
);
3373 static int WINAPI
expSetEnvironmentVariableA(const char *name
, const char *value
)
3375 dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name
, value
);
3379 static void* WINAPI
expCoTaskMemAlloc(ULONG cb
)
3381 return my_mreq(cb
, 0);
3383 static void WINAPI
expCoTaskMemFree(void* cb
)
3391 void* CoTaskMemAlloc(unsigned long cb
)
3393 return expCoTaskMemAlloc(cb
);
3395 void CoTaskMemFree(void* cb
)
3397 expCoTaskMemFree(cb
);
3400 struct COM_OBJECT_INFO
3403 long (*GetClassObject
) (GUID
* clsid
, const GUID
* iid
, void** ppv
);
3406 static struct COM_OBJECT_INFO
* com_object_table
=0;
3407 static int com_object_size
=0;
3408 int RegisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3412 com_object_table
=realloc(com_object_table
, sizeof(struct COM_OBJECT_INFO
)*(++com_object_size
));
3413 com_object_table
[com_object_size
-1].clsid
=*clsid
;
3414 com_object_table
[com_object_size
-1].GetClassObject
=gcs
;
3418 int UnregisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3425 if (com_object_table
== 0)
3426 printf("Warning: UnregisterComClass() called without any registered class\n");
3427 while (i
< com_object_size
)
3431 memcpy(&com_object_table
[i
- 1].clsid
,
3432 &com_object_table
[i
].clsid
, sizeof(GUID
));
3433 com_object_table
[i
- 1].GetClassObject
=
3434 com_object_table
[i
].GetClassObject
;
3436 else if (memcmp(&com_object_table
[i
].clsid
, clsid
, sizeof(GUID
)) == 0
3437 && com_object_table
[i
].GetClassObject
== gcs
)
3445 if (--com_object_size
== 0)
3447 free(com_object_table
);
3448 com_object_table
= 0;
3455 const GUID IID_IUnknown
=
3457 0x00000000, 0x0000, 0x0000,
3458 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3460 const GUID IID_IClassFactory
=
3462 0x00000001, 0x0000, 0x0000,
3463 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3466 static long WINAPI
expCoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3467 long dwClsContext
, const GUID
* riid
, void** ppv
)
3470 struct COM_OBJECT_INFO
* ci
=0;
3471 for(i
=0; i
<com_object_size
; i
++)
3472 if(!memcmp(rclsid
, &com_object_table
[i
].clsid
, sizeof(GUID
)))
3473 ci
=&com_object_table
[i
];
3474 if(!ci
)return REGDB_E_CLASSNOTREG
;
3475 // in 'real' world we should mess with IClassFactory here
3476 i
=ci
->GetClassObject(rclsid
, riid
, ppv
);
3480 long CoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3481 long dwClsContext
, const GUID
* riid
, void** ppv
)
3483 return expCoCreateInstance(rclsid
, pUnkOuter
, dwClsContext
, riid
, ppv
);
3486 static int WINAPI
expIsRectEmpty(CONST RECT
*lprc
)
3493 w
= lprc
->right
- lprc
->left
;
3494 h
= lprc
->bottom
- lprc
->top
;
3495 if (w
<= 0 || h
<= 0)
3501 dbgprintf("IsRectEmpty(%p) => %s\n", lprc
, (r
) ? "TRUE" : "FALSE");
3502 //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3503 // return 0; // wmv9?
3507 static int _adjust_fdiv
=0; //what's this? - used to adjust division
3508 static int _winver
= 0x510; // windows version
3513 static unsigned int WINAPI
expGetTempPathA(unsigned int len
, char* path
)
3515 dbgprintf("GetTempPathA(%d, 0x%x)", len
, path
);
3518 dbgprintf(" => 0\n");
3521 strcpy(path
, "/tmp");
3522 dbgprintf(" => 5 ( '/tmp' )\n");
3529 DWORD dwFileAttributes;
3530 FILETIME ftCreationTime;
3531 FILETIME ftLastAccessTime;
3532 FILETIME ftLastWriteTime;
3533 DWORD nFileSizeHigh;
3537 CHAR cFileName[260];
3538 CHAR cAlternateFileName[14];
3539 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3542 static DIR* qtx_dir
=NULL
;
3544 static WIN_BOOL WINAPI
expFindNextFileA(HANDLE h
,LPWIN32_FIND_DATAA lpfd
)
3546 #ifdef CONFIG_QTX_CODECS
3547 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h
, lpfd
);
3548 if(h
==FILE_HANDLE_quicktimeqtx
){
3550 if(!qtx_dir
) return 0;
3551 while((d
=readdir(qtx_dir
))){
3552 char* x
=strrchr(d
->d_name
,'.');
3554 if(strcmp(x
,".qtx")) continue;
3555 strcpy(lpfd
->cFileName
,d
->d_name
);
3556 // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3557 strcpy(lpfd
->cAlternateFileName
,"foobar.qtx");
3558 dbgprintf("### FindNext: %s\n",lpfd
->cFileName
);
3561 closedir(qtx_dir
); qtx_dir
=NULL
;
3568 static HANDLE WINAPI
expFindFirstFileA(LPCSTR s
, LPWIN32_FIND_DATAA lpfd
)
3570 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s
, s
, lpfd
);
3571 // printf("\n### FindFirstFileA('%s')...\n",s);
3572 #ifdef CONFIG_QTX_CODECS
3573 if(strstr(s
, "quicktime\\*.QTX")){
3574 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s
, s
, lpfd
);
3575 dbgprintf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",
3577 qtx_dir
= opendir(codec_path
);
3578 if(!qtx_dir
) return (HANDLE
)-1;
3579 memset(lpfd
,0,sizeof(*lpfd
));
3580 if(expFindNextFileA(FILE_HANDLE_quicktimeqtx
,lpfd
))
3581 return FILE_HANDLE_quicktimeqtx
;
3582 printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",
3587 if(strstr(s
, "QuickTime.qts")){
3588 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s
, s
, lpfd
);
3589 // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3590 // return (HANDLE)-1;
3591 strcpy(lpfd
->cFileName
, "QuickTime.qts");
3592 strcpy(lpfd
->cAlternateFileName
, "QuickT~1.qts");
3593 return FILE_HANDLE_quicktimeqts
;
3597 if(strstr(s
, "*.vwp")){
3598 // hack for VoxWare codec plugins:
3599 strcpy(lpfd
->cFileName
, "msms001.vwp");
3600 strcpy(lpfd
->cAlternateFileName
, "msms001.vwp");
3603 // return 'file not found'
3607 static WIN_BOOL WINAPI
expFindClose(HANDLE h
)
3609 dbgprintf("FindClose(0x%x) => 0\n", h
);
3610 #ifdef CONFIG_QTX_CODECS
3611 // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3612 // closedir(qtx_dir);
3618 static UINT WINAPI
expSetErrorMode(UINT i
)
3620 dbgprintf("SetErrorMode(%d) => 0\n", i
);
3623 static UINT WINAPI
expGetWindowsDirectoryA(LPSTR s
,UINT c
)
3625 char windir
[]="c:\\windows";
3627 strncpy(s
, windir
, c
);
3628 result
=1+((c
<strlen(windir
))?c
:strlen(windir
));
3629 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3632 #ifdef CONFIG_QTX_CODECS
3633 static UINT WINAPI
expGetCurrentDirectoryA(UINT c
, LPSTR s
)
3635 char curdir
[]="c:\\";
3637 strncpy(s
, curdir
, c
);
3638 result
=1+((c
<strlen(curdir
))?c
:strlen(curdir
));
3639 dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3643 static int WINAPI
expSetCurrentDirectoryA(const char *pathname
)
3645 dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname
, pathname
);
3647 if (strrchr(pathname
, '\\'))
3648 chdir(strcat(strrchr(pathname
, '\\')+1, '/'));
3655 static int WINAPI
expCreateDirectoryA(const char *pathname
, void *sa
)
3657 dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3658 pathname
, pathname
, sa
);
3660 p
= strrchr(pathname
, '\\')+1;
3661 strcpy(&buf
[0], p
); /* should be strncpy */
3668 if (strrchr(pathname
, '\\'))
3669 mkdir(strcat(strrchr(pathname
, '\\')+1, '/'), 666);
3671 mkdir(pathname
, 666);
3678 static WIN_BOOL WINAPI
expDeleteFileA(LPCSTR s
)
3680 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s
, s
);
3683 static WIN_BOOL WINAPI
expFileTimeToLocalFileTime(const FILETIME
* cpf
, LPFILETIME pf
)
3685 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf
, pf
);
3689 static UINT WINAPI
expGetTempFileNameA(LPCSTR cs1
,LPCSTR cs2
,UINT i
,LPSTR ps
)
3691 char mask
[16]="/tmp/AP_XXXXXX";
3693 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1
, cs1
, cs2
, cs2
, i
, ps
);
3696 dbgprintf(" => -1\n");
3699 result
=mkstemp(mask
);
3700 sprintf(ps
, "AP%d", result
);
3701 dbgprintf(" => %d\n", strlen(ps
));
3705 // This func might need proper implementation if we want AngelPotion codec.
3706 // They try to open APmpeg4v1.apl with it.
3707 // DLL will close opened file with CloseHandle().
3709 static HANDLE WINAPI
expCreateFileA(LPCSTR cs1
,DWORD i1
,DWORD i2
,
3710 LPSECURITY_ATTRIBUTES p1
, DWORD i3
,DWORD i4
,HANDLE i5
)
3712 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1
, cs1
, i1
,
3713 i2
, p1
, i3
, i4
, i5
);
3714 if((!cs1
) || (strlen(cs1
)<2))return -1;
3716 #ifdef CONFIG_QTX_CODECS
3717 if(strstr(cs1
, "QuickTime.qts"))
3720 char* tmp
= malloc(strlen(codec_path
) + 50);
3721 strcpy(tmp
, codec_path
);
3723 strcat(tmp
, "QuickTime.qts");
3724 result
=open(tmp
, O_RDONLY
);
3728 if(strstr(cs1
, ".qtx"))
3731 char* tmp
= malloc(strlen(codec_path
) + 250);
3732 char* x
=strrchr(cs1
,'\\');
3733 sprintf(tmp
, "%s/%s", codec_path
, x
? (x
+ 1) : cs1
);
3734 // printf("### Open: %s -> %s\n",cs1,tmp);
3735 result
=open(tmp
, O_RDONLY
);
3741 if(strncmp(cs1
, "AP", 2) == 0)
3744 char* tmp
= malloc(strlen(codec_path
) + 50);
3745 strcpy(tmp
, codec_path
);
3747 strcat(tmp
, "APmpg4v1.apl");
3748 result
=open(tmp
, O_RDONLY
);
3752 if (strstr(cs1
, "vp3") || strstr(cs1
, ".fpf") || strstr(cs1
, ".col"))
3756 char* tmp
=malloc(20 + strlen(cs1
));
3757 strcpy(tmp
, "/tmp/");
3762 if (tmp
[r
] == ':' || tmp
[r
] == '\\')
3766 if (GENERIC_READ
& i1
)
3768 else if (GENERIC_WRITE
& i1
)
3770 flg
|= O_WRONLY
| O_CREAT
;
3771 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp
, r
, flg
);
3773 r
=open(tmp
, flg
, S_IRWXU
);
3778 // Needed by wnvplay1.dll
3779 if (strstr(cs1
, "WINNOV.bmp"))
3782 r
=open("/dev/null", O_RDONLY
);
3787 /* we need this for some virtualdub filters */
3791 if (GENERIC_READ
& i1
)
3793 else if (GENERIC_WRITE
& i1
)
3796 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1
, r
, flg
);
3805 static UINT WINAPI
expGetSystemDirectoryA(
3806 char* lpBuffer
, // address of buffer for system directory
3807 UINT uSize
// size of directory buffer
3809 dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer
,uSize
);
3810 if(!lpBuffer
) strcpy(lpBuffer
,".");
3814 static char sysdir[]=".";
3815 static LPCSTR WINAPI expGetSystemDirectoryA(void)
3817 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3821 static DWORD WINAPI expGetFullPathNameA
3824 DWORD nBufferLength
,
3828 if(!lpFileName
) return 0;
3829 dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName
,nBufferLength
,
3830 lpBuffer
, lpFilePart
);
3832 #ifdef CONFIG_QTX_CODECS
3833 strcpy(lpFilePart
, "Quick123.qts");
3835 strcpy(lpFilePart
, lpFileName
);
3838 if (strrchr(lpFileName
, '\\'))
3839 lpFilePart
= strrchr(lpFileName
, '\\');
3841 lpFilePart
= (LPTSTR
)lpFileName
;
3843 strcpy(lpBuffer
, lpFileName
);
3844 // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3845 return strlen(lpBuffer
);
3848 static DWORD WINAPI expGetShortPathNameA
3854 if(!longpath
) return 0;
3855 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath
,shortpath
,shortlen
);
3856 strcpy(shortpath
,longpath
);
3857 return strlen(shortpath
);
3860 static WIN_BOOL WINAPI
expReadFile(HANDLE h
,LPVOID pv
,DWORD size
,LPDWORD rd
,LPOVERLAPPED unused
)
3863 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, rd
);
3864 result
=read(h
, pv
, size
);
3866 if(!result
)return 0;
3870 static WIN_BOOL WINAPI
expWriteFile(HANDLE h
,LPCVOID pv
,DWORD size
,LPDWORD wr
,LPOVERLAPPED unused
)
3873 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, wr
);
3875 result
=write(h
, pv
, size
);
3877 if(!result
)return 0;
3880 static DWORD WINAPI
expSetFilePointer(HANDLE h
, LONG val
, LPLONG ext
, DWORD whence
)
3883 dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h
, val
, ext
, ext
? *ext
: 0, whence
);
3884 //why would DLL want temporary file with >2Gb size?
3896 #ifdef CONFIG_QTX_CODECS
3897 if (val
== 0 && ext
!= 0)
3900 return lseek(h
, val
, wh
);
3903 static HDRVR WINAPI
expOpenDriverA(LPCSTR szDriverName
, LPCSTR szSectionName
,
3906 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3909 static HDRVR WINAPI
expOpenDriver(LPCSTR szDriverName
, LPCSTR szSectionName
,
3912 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3917 static WIN_BOOL WINAPI
expGetProcessAffinityMask(HANDLE hProcess
,
3918 LPDWORD lpProcessAffinityMask
,
3919 LPDWORD lpSystemAffinityMask
)
3921 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3922 hProcess
, lpProcessAffinityMask
, lpSystemAffinityMask
);
3923 if(lpProcessAffinityMask
)*lpProcessAffinityMask
=1;
3924 if(lpSystemAffinityMask
)*lpSystemAffinityMask
=1;
3928 // Fake implementation: does nothing, but does it right :)
3929 static WIN_BOOL WINAPI
expSetProcessAffinityMask(HANDLE hProcess
,
3930 LPDWORD dwProcessAffinityMask
)
3932 dbgprintf("SetProcessAffinityMask(0x%x, 0x%x) => 1\n",
3933 hProcess
, dwProcessAffinityMask
);
3938 static int WINAPI
expMulDiv(int nNumber
, int nNumerator
, int nDenominator
)
3940 static const long long max_int
=0x7FFFFFFFLL
;
3941 static const long long min_int
=-0x80000000LL
;
3942 long long tmp
=(long long)nNumber
*(long long)nNumerator
;
3943 dbgprintf("expMulDiv %d * %d / %d\n", nNumber
, nNumerator
, nDenominator
);
3944 if(!nDenominator
)return 1;
3946 if(tmp
<min_int
) return 1;
3947 if(tmp
>max_int
) return 1;
3951 static LONG WINAPI
explstrcmpiA(const char* str1
, const char* str2
)
3953 LONG result
=strcasecmp(str1
, str2
);
3954 dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
3958 static LONG WINAPI
explstrlenA(const char* str1
)
3960 LONG result
=strlen(str1
);
3961 dbgprintf("strlen(0x%x='%.50s') => %d\n", str1
, str1
, result
);
3965 static LONG WINAPI
explstrcpyA(char* str1
, const char* str2
)
3967 int result
= (int) strcpy(str1
, str2
);
3968 dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1
, str2
, str2
, result
);
3971 static LONG WINAPI
explstrcpynA(char* str1
, const char* str2
,int len
)
3974 if (strlen(str2
)>len
)
3975 result
= (int) strncpy(str1
, str2
,len
);
3977 result
= (int) strcpy(str1
,str2
);
3978 dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1
, str2
, str2
,len
, strlen(str2
),result
);
3981 static LONG WINAPI
explstrcatA(char* str1
, const char* str2
)
3983 int result
= (int) strcat(str1
, str2
);
3984 dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1
, str2
, str2
, result
);
3989 static LONG WINAPI
expInterlockedExchange(long *dest
, long l
)
3991 long retval
= *dest
;
3996 static void WINAPI
expInitCommonControls(void)
3998 dbgprintf("InitCommonControls called!\n");
4002 #ifdef CONFIG_QTX_CODECS
4003 /* needed by QuickTime.qts */
4004 static HWND WINAPI
expCreateUpDownControl (DWORD style
, INT x
, INT y
, INT cx
, INT cy
,
4005 HWND parent
, INT id
, HINSTANCE inst
,
4006 HWND buddy
, INT maxVal
, INT minVal
, INT curVal
)
4008 dbgprintf("CreateUpDownControl(...)\n");
4013 /* alex: implement this call! needed for 3ivx */
4014 static HRESULT WINAPI
expCoCreateFreeThreadedMarshaler(void *pUnkOuter
, void **ppUnkInner
)
4016 dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
4017 pUnkOuter
, ppUnkInner
);
4019 return ERROR_CALL_NOT_IMPLEMENTED
;
4023 static int WINAPI
expDuplicateHandle(HANDLE hSourceProcessHandle
, // handle to source process
4024 HANDLE hSourceHandle
, // handle to duplicate
4025 HANDLE hTargetProcessHandle
, // handle to target process
4026 HANDLE
* lpTargetHandle
, // duplicate handle
4027 DWORD dwDesiredAccess
, // requested access
4028 int bInheritHandle
, // handle inheritance option
4029 DWORD dwOptions
// optional actions
4032 dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
4033 hSourceProcessHandle
, hSourceHandle
, hTargetProcessHandle
,
4034 lpTargetHandle
, dwDesiredAccess
, bInheritHandle
, dwOptions
);
4035 *lpTargetHandle
= hSourceHandle
;
4039 static HRESULT WINAPI
expCoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
4041 dbgprintf("CoInitializeEx(%p, %d) called\n", lpReserved
, dwCoInit
);
4045 // required by PIM1 codec (used by win98 PCTV Studio capture sw)
4046 static HRESULT WINAPI
expCoInitialize(
4047 LPVOID lpReserved
/* [in] pointer to win32 malloc interface
4048 (obsolete, should be NULL) */
4052 * Just delegate to the newer method.
4054 return expCoInitializeEx(lpReserved
, COINIT_APARTMENTTHREADED
);
4057 static void WINAPI
expCoUninitialize(void)
4059 dbgprintf("CoUninitialize() called\n");
4062 /* allow static linking */
4063 HRESULT WINAPI
CoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
4065 return expCoInitializeEx(lpReserved
, dwCoInit
);
4067 HRESULT WINAPI
CoInitialize(LPVOID lpReserved
)
4069 return expCoInitialize(lpReserved
);
4071 void WINAPI
CoUninitialize(void)
4073 expCoUninitialize();
4076 static DWORD WINAPI expSetThreadAffinityMask
4079 DWORD dwThreadAffinityMask
4085 * no WINAPI functions - CDECL
4087 static void* expmalloc(int size
)
4090 // return malloc(size);
4091 void* result
=my_mreq(size
,0);
4092 dbgprintf("malloc(0x%x) => 0x%x\n", size
,result
);
4094 printf("WARNING: malloc() failed\n");
4097 static void expfree(void* mem
)
4099 // return free(mem);
4100 dbgprintf("free(%p)\n", mem
);
4103 /* needed by atrac3.acm */
4104 static void *expcalloc(int num
, int size
)
4106 void* result
=my_mreq(num
*size
,1);
4107 dbgprintf("calloc(%d,%d) => %p\n", num
,size
,result
);
4109 printf("WARNING: calloc() failed\n");
4112 static void* expnew(int size
)
4114 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
4115 // printf("%08x %08x %08x %08x\n",
4116 // size, *(1+(int*)&size),
4117 // *(2+(int*)&size),*(3+(int*)&size));
4121 result
=my_mreq(size
,0);
4122 dbgprintf("new(%d) => %p\n", size
, result
);
4124 printf("WARNING: new() failed\n");
4128 static int expdelete(void* memory
)
4130 dbgprintf("delete(%p)\n", memory
);
4136 * local definition - we need only the last two members at this point
4137 * otherwice we would have to introduce here GUIDs and some more types..
4139 typedef struct __attribute__((__packed__
))
4142 unsigned long cbFormat
; //0x40
4143 char* pbFormat
; //0x44
4145 static HRESULT WINAPI
expMoCopyMediaType(MY_MEDIA_TYPE
* dest
, const MY_MEDIA_TYPE
* src
)
4149 memcpy(dest
, src
, sizeof(MY_MEDIA_TYPE
));
4152 dest
->pbFormat
= (char*) my_mreq(dest
->cbFormat
, 0);
4153 if (!dest
->pbFormat
)
4154 return E_OUTOFMEMORY
;
4155 memcpy(dest
->pbFormat
, src
->pbFormat
, dest
->cbFormat
);
4159 static HRESULT WINAPI
expMoInitMediaType(MY_MEDIA_TYPE
* dest
, DWORD cbFormat
)
4163 memset(dest
, 0, sizeof(MY_MEDIA_TYPE
));
4166 dest
->pbFormat
= (char*) my_mreq(cbFormat
, 0);
4167 if (!dest
->pbFormat
)
4168 return E_OUTOFMEMORY
;
4172 static HRESULT WINAPI
expMoCreateMediaType(MY_MEDIA_TYPE
** dest
, DWORD cbFormat
)
4176 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
4177 return expMoInitMediaType(*dest
, cbFormat
);
4179 static HRESULT WINAPI
expMoDuplicateMediaType(MY_MEDIA_TYPE
** dest
, const void* src
)
4183 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
4184 return expMoCopyMediaType(*dest
, src
);
4186 static HRESULT WINAPI
expMoFreeMediaType(MY_MEDIA_TYPE
* dest
)
4192 my_release(dest
->pbFormat
);
4198 static HRESULT WINAPI
expMoDeleteMediaType(MY_MEDIA_TYPE
* dest
)
4202 expMoFreeMediaType(dest
);
4207 static int exp_snprintf( char *str
, int size
, const char *format
, ... )
4211 va_start(va
, format
);
4212 x
=snprintf(str
,size
,format
,va
);
4213 dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str
,size
,format
,x
);
4219 static int exp_initterm(int v1
, int v2
)
4221 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1
, v2
);
4225 /* merged from wine - 2002.04.21 */
4226 typedef void (*INITTERMFUNC
)();
4227 static int exp_initterm(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
4229 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start
, end
, *start
);
4234 //printf("call _initfunc: from: %p %d\n", *start);
4235 // ok this trick with push/pop is necessary as otherwice
4236 // edi/esi registers are being trashed
4255 //printf("done %p %d:%d\n", end);
4263 /* Fake _initterm_e from msvcr80.dll, needed by sirenacm.dll
4264 * NOTE: If I make this an alias for _initterm, then sirenacm.dll tries to call
4265 other uninmplemented functions; keep this in mind if some future codec needs
4266 a real implementation of this function */
4267 static int exp_initterm_e(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
4269 dbgprintf("_initterm_e(0x%x, 0x%x)\n", start
, end
);
4273 static void* exp__dllonexit(void)
4275 // FIXME extract from WINE
4279 static int expwsprintfA(char* string
, const char* format
, ...)
4283 va_start(va
, format
);
4284 result
= vsprintf(string
, format
, va
);
4285 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string
, format
, result
);
4290 static int expsprintf(char* str
, const char* format
, ...)
4294 dbgprintf("sprintf(0x%x, %s)\n", str
, format
);
4295 va_start(args
, format
);
4296 r
= vsprintf(str
, format
, args
);
4300 static int expsscanf(const char* str
, const char* format
, ...)
4304 dbgprintf("sscanf(%s, %s)\n", str
, format
);
4305 va_start(args
, format
);
4306 r
= vsscanf(str
, format
, args
);
4310 static void* expfopen(const char* path
, const char* mode
)
4312 printf("fopen: \"%s\" mode:%s\n", path
, mode
);
4313 //return fopen(path, mode);
4314 return fdopen(0, mode
); // everything on screen
4316 static int expfprintf(void* stream
, const char* format
, ...)
4320 dbgprintf("fprintf(%p, %s, ...)\n", stream
, format
);
4321 va_start(args
, format
);
4322 r
= vfprintf((FILE*) stream
, format
, args
);
4327 static int expprintf(const char* format
, ...)
4331 dbgprintf("printf(%s, ...)\n", format
);
4332 va_start(args
, format
);
4333 r
= vprintf(format
, args
);
4338 static char* expgetenv(const char* varname
)
4340 char* v
= getenv(varname
);
4341 dbgprintf("getenv(%s) => %s\n", varname
, v
);
4345 static void* expwcscpy(WCHAR
* dst
, const WCHAR
* src
)
4348 while ((*p
++ = *src
++))
4353 static char* expstrrchr(char* string
, int value
)
4355 char* result
=strrchr(string
, value
);
4357 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4359 dbgprintf("strrchr(0x%x='%s', %d) => 0", string
, string
, value
);
4363 static char* expstrchr(char* string
, int value
)
4365 char* result
=strchr(string
, value
);
4367 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4369 dbgprintf("strchr(0x%x='%s', %d) => 0", string
, string
, value
);
4372 static int expstrlen(char* str
)
4374 int result
=strlen(str
);
4375 dbgprintf("strlen(0x%x='%s') => %d\n", str
, str
, result
);
4378 static char* expstrcpy(char* str1
, const char* str2
)
4380 char* result
= strcpy(str1
, str2
);
4381 dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1
, str2
, str2
, result
);
4384 static char* expstrncpy(char* str1
, const char* str2
, size_t count
)
4386 char* result
= strncpy(str1
, str2
, count
);
4387 dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1
, str2
, str2
, count
, result
);
4390 static int expstrcmp(const char* str1
, const char* str2
)
4392 int result
=strcmp(str1
, str2
);
4393 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4396 static int expstrncmp(const char* str1
, const char* str2
,int x
)
4398 int result
=strncmp(str1
, str2
,x
);
4399 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4402 static char* expstrcat(char* str1
, const char* str2
)
4404 char* result
= strcat(str1
, str2
);
4405 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1
, str1
, str2
, str2
, result
);
4408 static char* exp_strdup(const char* str1
)
4410 int l
= strlen(str1
);
4411 char* result
= (char*) my_mreq(l
+ 1,0);
4413 strcpy(result
, str1
);
4414 dbgprintf("_strdup(0x%x='%s') => %p\n", str1
, str1
, result
);
4417 static int expisalnum(int c
)
4419 int result
= (int) isalnum(c
);
4420 dbgprintf("isalnum(0x%x='%c' => %d\n", c
, c
, result
);
4423 static int expisspace(int c
)
4425 int result
= (int) isspace(c
);
4426 dbgprintf("isspace(0x%x='%c' => %d\n", c
, c
, result
);
4429 static int expisalpha(int c
)
4431 int result
= (int) isalpha(c
);
4432 dbgprintf("isalpha(0x%x='%c' => %d\n", c
, c
, result
);
4435 static int expisdigit(int c
)
4437 int result
= (int) isdigit(c
);
4438 dbgprintf("isdigit(0x%x='%c' => %d\n", c
, c
, result
);
4441 static void* expmemmove(void* dest
, void* src
, int n
)
4443 void* result
= memmove(dest
, src
, n
);
4444 dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4447 static int expmemcmp(void* dest
, void* src
, int n
)
4449 int result
= memcmp(dest
, src
, n
);
4450 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest
, src
, n
, result
);
4453 static void* expmemcpy(void* dest
, void* src
, int n
)
4455 void *result
= memcpy(dest
, src
, n
);
4456 dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4459 static void* expmemset(void* dest
, int c
, size_t n
)
4461 void *result
= memset(dest
, c
, n
);
4462 dbgprintf("memset(0x%x, %d, %d) => %p\n", dest
, c
, n
, result
);
4465 static time_t exptime(time_t* t
)
4467 time_t result
= time(t
);
4468 dbgprintf("time(0x%x) => %d\n", t
, result
);
4472 static int exprand(void)
4477 static void expsrand(int seed
)
4484 // preferred compilation with -O2 -ffast-math !
4486 static double explog10(double x
)
4488 /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4492 static double expcos(double x
)
4494 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4500 static void explog10(void)
4511 static void expcos(void)
4522 // this seem to be the only how to make this function working properly
4523 // ok - I've spent tremendous amount of time (many many many hours
4524 // of debuging fixing & testing - it's almost unimaginable - kabi
4526 // _ftol - operated on the float value which is already on the FPU stack
4528 static void exp_ftol(void)
4532 "sub $12, %esp \n\t"
4533 "fstcw -2(%ebp) \n\t"
4535 "movw -2(%ebp), %ax \n\t"
4536 "orb $0x0C, %ah \n\t"
4537 "movw %ax, -4(%ebp) \n\t"
4538 "fldcw -4(%ebp) \n\t"
4539 "fistpl -12(%ebp) \n\t"
4540 "fldcw -2(%ebp) \n\t"
4541 "movl -12(%ebp), %eax \n\t"
4542 //Note: gcc 3.03 does not do the following op if it
4543 // knows that ebp=esp
4544 "movl %ebp, %esp \n\t"
4548 #define FPU_DOUBLES(var1,var2) double var1,var2; \
4549 __asm__ volatile( "fstpl %0;fwait" : "=m" (var2) : ); \
4550 __asm__ volatile( "fstpl %0;fwait" : "=m" (var1) : )
4552 static double exp_CIpow(void)
4556 dbgprintf("_CIpow(%f, %f)\n", x
, y
);
4560 static double exppow(double x
, double y
)
4562 /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4566 static double expldexp(double x
, int expo
)
4568 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4569 return ldexp(x
, expo
);
4572 static double expfrexp(double x
, int* expo
)
4574 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4575 return frexp(x
, expo
);
4580 static int exp_stricmp(const char* s1
, const char* s2
)
4582 return strcasecmp(s1
, s2
);
4585 /* from declaration taken from Wine sources - this fountion seems to be
4586 * undocumented in any M$ doc */
4587 static int exp_setjmp3(void* jmpbuf
, int x
)
4589 //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4593 //"mov 4(%%esp), %%edx \n\t"
4594 "mov (%%esp), %%eax \n\t"
4595 "mov %%eax, (%%edx) \n\t" // store ebp
4597 //"mov %%ebp, (%%edx) \n\t"
4598 "mov %%ebx, 4(%%edx) \n\t"
4599 "mov %%edi, 8(%%edx) \n\t"
4600 "mov %%esi, 12(%%edx) \n\t"
4601 "mov %%esp, 16(%%edx) \n\t"
4603 "mov 4(%%esp), %%eax \n\t"
4604 "mov %%eax, 20(%%edx) \n\t"
4606 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4607 "movl $0, 36(%%edx) \n\t"
4609 : "d"(jmpbuf
) // input
4614 "mov %%fs:0, %%eax \n\t" // unsure
4615 "mov %%eax, 24(%%edx) \n\t"
4616 "cmp $0xffffffff, %%eax \n\t"
4618 "mov %%eax, 28(%%edx) \n\t"
4628 static DWORD WINAPI
expGetCurrentProcessId(void)
4630 dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4631 return getpid(); //(DWORD)NtCurrentTeb()->pid;
4638 } TIMECAPS
, *LPTIMECAPS
;
4640 static MMRESULT WINAPI
exptimeGetDevCaps(LPTIMECAPS lpCaps
, UINT wSize
)
4642 dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps
, wSize
);
4644 lpCaps
->wPeriodMin
= 1;
4645 lpCaps
->wPeriodMax
= 65535;
4649 static MMRESULT WINAPI
exptimeBeginPeriod(UINT wPeriod
)
4651 dbgprintf("timeBeginPeriod(%u) !\n", wPeriod
);
4653 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4657 #ifdef CONFIG_QTX_CODECS
4658 static MMRESULT WINAPI
exptimeEndPeriod(UINT wPeriod
)
4660 dbgprintf("timeEndPeriod(%u) !\n", wPeriod
);
4662 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4667 static void WINAPI
expGlobalMemoryStatus(
4668 LPMEMORYSTATUS lpmem
4670 static MEMORYSTATUS cached_memstatus
;
4671 static int cache_lastchecked
= 0;
4675 if (time(NULL
)==cache_lastchecked
) {
4676 memcpy(lpmem
,&cached_memstatus
,sizeof(MEMORYSTATUS
));
4680 f
= fopen( "/proc/meminfo", "r" );
4684 int total
, used
, free
, shared
, buffers
, cached
;
4686 lpmem
->dwLength
= sizeof(MEMORYSTATUS
);
4687 lpmem
->dwTotalPhys
= lpmem
->dwAvailPhys
= 0;
4688 lpmem
->dwTotalPageFile
= lpmem
->dwAvailPageFile
= 0;
4689 while (fgets( buffer
, sizeof(buffer
), f
))
4691 /* old style /proc/meminfo ... */
4692 if (sscanf( buffer
, "Mem: %d %d %d %d %d %d", &total
, &used
, &free
, &shared
, &buffers
, &cached
))
4694 lpmem
->dwTotalPhys
+= total
;
4695 lpmem
->dwAvailPhys
+= free
+ buffers
+ cached
;
4697 if (sscanf( buffer
, "Swap: %d %d %d", &total
, &used
, &free
))
4699 lpmem
->dwTotalPageFile
+= total
;
4700 lpmem
->dwAvailPageFile
+= free
;
4703 /* new style /proc/meminfo ... */
4704 if (sscanf(buffer
, "MemTotal: %d", &total
))
4705 lpmem
->dwTotalPhys
= total
*1024;
4706 if (sscanf(buffer
, "MemFree: %d", &free
))
4707 lpmem
->dwAvailPhys
= free
*1024;
4708 if (sscanf(buffer
, "SwapTotal: %d", &total
))
4709 lpmem
->dwTotalPageFile
= total
*1024;
4710 if (sscanf(buffer
, "SwapFree: %d", &free
))
4711 lpmem
->dwAvailPageFile
= free
*1024;
4712 if (sscanf(buffer
, "Buffers: %d", &buffers
))
4713 lpmem
->dwAvailPhys
+= buffers
*1024;
4714 if (sscanf(buffer
, "Cached: %d", &cached
))
4715 lpmem
->dwAvailPhys
+= cached
*1024;
4719 if (lpmem
->dwTotalPhys
)
4721 DWORD TotalPhysical
= lpmem
->dwTotalPhys
+lpmem
->dwTotalPageFile
;
4722 DWORD AvailPhysical
= lpmem
->dwAvailPhys
+lpmem
->dwAvailPageFile
;
4723 lpmem
->dwMemoryLoad
= (TotalPhysical
-AvailPhysical
)
4724 / (TotalPhysical
/ 100);
4728 /* FIXME: should do something for other systems */
4729 lpmem
->dwMemoryLoad
= 0;
4730 lpmem
->dwTotalPhys
= 16*1024*1024;
4731 lpmem
->dwAvailPhys
= 16*1024*1024;
4732 lpmem
->dwTotalPageFile
= 16*1024*1024;
4733 lpmem
->dwAvailPageFile
= 16*1024*1024;
4735 expGetSystemInfo(&si
);
4736 lpmem
->dwTotalVirtual
= (uint8_t *)si
.lpMaximumApplicationAddress
-(uint8_t *)si
.lpMinimumApplicationAddress
;
4737 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4738 lpmem
->dwAvailVirtual
= lpmem
->dwTotalVirtual
-64*1024;
4739 memcpy(&cached_memstatus
,lpmem
,sizeof(MEMORYSTATUS
));
4740 cache_lastchecked
= time(NULL
);
4742 /* it appears some memory display programs want to divide by these values */
4743 if(lpmem
->dwTotalPageFile
==0)
4744 lpmem
->dwTotalPageFile
++;
4746 if(lpmem
->dwAvailPageFile
==0)
4747 lpmem
->dwAvailPageFile
++;
4750 static INT WINAPI
expGetThreadPriority(HANDLE hthread
)
4752 dbgprintf("GetThreadPriority(%p)\n",hthread
);
4756 /**********************************************************************
4757 * SetThreadPriority [KERNEL32.@] Sets priority for thread.
4763 static WIN_BOOL WINAPI
expSetThreadPriority(
4764 HANDLE hthread
, /* [in] Handle to thread */
4765 INT priority
) /* [in] Thread priority level */
4767 dbgprintf("SetThreadPriority(%p,%d)\n",hthread
,priority
);
4771 static void WINAPI
expTerminateProcess( DWORD process
, DWORD status
)
4773 printf("EXIT - process %ld code %ld\n", process
, status
);
4777 static void WINAPI
expExitProcess( DWORD status
)
4779 printf("EXIT - code %ld\n",status
);
4783 static INT WINAPI
expMessageBoxA(HWND hWnd
, LPCSTR text
, LPCSTR title
, UINT type
){
4784 printf("MSGBOX '%s' '%s' (%d)\n",text
,title
,type
);
4785 #ifdef CONFIG_QTX_CODECS
4786 if (type
== MB_ICONHAND
&& !strlen(text
) && !strlen(title
))
4792 /* these are needed for mss1 */
4795 * \brief this symbol is defined within exp_EH_prolog_dummy
4796 * \param dest jump target
4798 void exp_EH_prolog(void *dest
);
4799 void exp_EH_prolog_dummy(void);
4800 //! just a dummy function that acts a container for the asm section
4801 void exp_EH_prolog_dummy(void) {
4803 // take care, this "function" may not change flags or
4804 // registers besides eax (which is also why we can't use
4805 // exp_EH_prolog_dummy directly)
4806 MANGLE(exp_EH_prolog
)": \n\t"
4809 "mov %esp, %ebp \n\t"
4810 "lea -12(%esp), %esp \n\t"
4815 #include <netinet/in.h>
4816 static WINAPI
inline unsigned long int exphtonl(unsigned long int hostlong
)
4818 // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4819 return htonl(hostlong
);
4822 static WINAPI
inline unsigned long int expntohl(unsigned long int netlong
)
4824 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4825 return ntohl(netlong
);
4828 static char* WINAPI
expSysAllocStringLen(char *pch
, unsigned cch
)
4831 dbgprintf("SysAllocStringLen('%s', %d)\n", pch
, cch
);
4832 str
= malloc(cch
* 2 + sizeof(unsigned) + 2);
4833 *(unsigned *)str
= cch
;
4834 str
+= sizeof(unsigned);
4836 memcpy(str
, pch
, cch
* 2);
4838 str
[cch
* 2 + 1] = 0;
4842 static void WINAPI
expSysFreeString(char *str
)
4845 free(str
- sizeof(unsigned));
4849 static void WINAPI
expVariantInit(void* p
)
4851 printf("InitCommonControls called!\n");
4855 static int WINAPI
expRegisterClassA(const void/*WNDCLASSA*/ *wc
)
4857 dbgprintf("RegisterClassA(%p) => random id\n", wc
);
4858 return time(NULL
); /* be precise ! */
4861 static int WINAPI
expUnregisterClassA(const char *className
, HINSTANCE hInstance
)
4863 dbgprintf("UnregisterClassA(%s, %p) => 0\n", className
, hInstance
);
4867 #ifdef CONFIG_QTX_CODECS
4868 /* should be fixed bcs it's not fully strlen equivalent */
4869 static int expSysStringByteLen(void *str
)
4871 dbgprintf("SysStringByteLen(%p) => %d\n", str
, strlen(str
));
4875 static int expDirectDrawCreate(void)
4877 dbgprintf("DirectDrawCreate(...) => NULL\n");
4882 typedef struct tagPALETTEENTRY
{
4889 typedef struct tagLOGPALETTE
{
4892 PALETTEENTRY palPalEntry
[1];
4895 static HPALETTE WINAPI
expCreatePalette(CONST LOGPALETTE
*lpgpl
)
4900 dbgprintf("CreatePalette(%x) => NULL\n", lpgpl
);
4902 i
= sizeof(LOGPALETTE
)+((lpgpl
->palNumEntries
-1)*sizeof(PALETTEENTRY
));
4904 memcpy((void *)test
, lpgpl
, i
);
4909 static int expCreatePalette(void)
4911 dbgprintf("CreatePalette(...) => NULL\n");
4916 static int WINAPI
expGetClientRect(HWND win
, RECT
*r
)
4918 dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win
, r
);
4919 r
->right
= PSEUDO_SCREEN_WIDTH
;
4921 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
4927 typedef struct tagPOINT
{
4933 static int WINAPI
expClientToScreen(HWND win
, POINT
*p
)
4935 dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win
, p
, p
->x
, p
->y
);
4943 static int WINAPI
expSetThreadIdealProcessor(HANDLE thread
, int proc
)
4945 dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread
, proc
);
4949 static int WINAPI
expMessageBeep(int type
)
4951 dbgprintf("MessageBeep(%d) => 1\n", type
);
4955 static int WINAPI
expDialogBoxParamA(void *inst
, const char *name
,
4956 HWND parent
, void *dialog_func
, void *init_param
)
4958 dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
4959 inst
, name
, name
, parent
, dialog_func
, init_param
);
4963 static void WINAPI
expRegisterClipboardFormatA(const char *name
) {
4964 dbgprintf("RegisterClipboardFormatA(0x%x = %s)\n", name
, name
);
4967 /* needed by imagepower mjpeg2k */
4968 static void *exprealloc(void *ptr
, size_t size
)
4970 dbgprintf("realloc(0x%x, %x)\n", ptr
, size
);
4972 return my_mreq(size
,0);
4974 return my_realloc(ptr
, size
);
4977 /* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
4978 static WIN_BOOL WINAPI
expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn
)
4983 static const char * WINAPI
expPathFindExtensionA(const char *path
) {
4988 ext
= strrchr(path
, '.');
4990 ext
= &path
[strlen(path
)];
4992 dbgprintf("PathFindExtensionA(0x%x = %s) => 0x%x, %s\n", path
, path
, ext
, ext
);
4996 static const char * WINAPI
expPathFindFileNameA(const char *path
) {
4998 if (!path
|| strlen(path
) < 2)
5001 name
= strrchr(path
- 1, '\\');
5005 dbgprintf("PathFindFileNameA(0x%x = %s) => 0x%x, %s\n", path
, path
, name
, name
);
5009 static double expfloor(double x
)
5011 dbgprintf("floor(%f)\n", x
);
5015 #define FPU_DOUBLE(var) double var; \
5016 __asm__ volatile( "fstpl %0;fwait" : "=m" (var) : )
5018 static double exp_CIcos(void)
5022 dbgprintf("_CIcos(%f)\n", x
);
5026 static double exp_CIsin(void)
5030 dbgprintf("_CIsin(%f)\n", x
);
5034 static double exp_CIsqrt(void)
5038 dbgprintf("_CIsqrt(%f)\n", x
);
5042 /* Needed by rp8 sipr decoder */
5043 static LPSTR WINAPI
expCharNextA(LPCSTR ptr
)
5045 if (!*ptr
) return (LPSTR
)ptr
;
5046 // dbgprintf("CharNextA(0x%08x), %s\n", ptr, ptr);
5047 return (LPSTR
)(ptr
+ 1);
5050 // Fake implementation, needed by wvc1dmod.dll
5051 static int WINAPI
expPropVariantClear(void *pvar
)
5053 // dbgprintf("PropVariantclear (0x%08x), %s\n", ptr, ptr);
5057 // This define is fake, the real thing is a struct
5058 #define LPDEVMODEA void*
5059 // Dummy implementation, always return 1
5060 // Required for frapsvid.dll 2.8.1, return value does not matter
5061 static WIN_BOOL WINAPI
expEnumDisplaySettingsA(LPCSTR name
,DWORD n
,
5064 dbgprintf("EnumDisplaySettingsA (dummy) => 1\n");
5068 // Fake implementation of _decode_pointer from msvcr80.dll, needed by sirenacm.dll
5069 // NOTE: undocumented function, probably the declaration is not right
5070 static int exp_decode_pointer(void *ptr
)
5072 dbgprintf("_decode_pointer (0x%08x)\n", ptr
);
5076 /* Fake implementation of sdt::_Lockit::_Lockit(void) from msvcp60.dll
5077 Needed by SCLS.DLL */
5078 static int exp_0Lockit_dummy(void)
5080 dbgprintf("0Lockit_dummy (??0_Lockit@std@@QAE@XZ)\n");
5084 /* Fake implementation of sdt::_Lockit::~_Lockit(void) from msvcp60.dll
5085 Needed by SCLS.DLL */
5086 static int exp_1Lockit_dummy(void)
5088 dbgprintf("1Lockit_dummy (??1_Lockit@std@@QAE@XZ)\n");
5092 static void * WINAPI
expEncodePointer(void *p
)
5097 static void * WINAPI
expDecodePointer(void *p
)
5102 static DWORD WINAPI
expGetThreadLocale(void)
5108 * Very incomplete implementation, return an error for almost all cases.
5110 static DWORD WINAPI
expGetLocaleInfoA(DWORD locale
, DWORD lctype
, char* lpLCData
, int cchData
)
5112 if (lctype
== 0x1004) { // LOCALE_IDEFAULTANSICODEPAGE
5114 return cchData
== 0 ? 4 : 0;
5115 strcpy(lpLCData
, "437");
5131 const struct exports
* exps
;
5135 {#X, Y, (void*)exp##X},
5137 #define UNDEFF(X, Y) \
5140 static const struct exports exp_kernel32
[]=
5142 FF(GetVolumeInformationA
,-1)
5143 FF(GetDriveTypeA
,-1)
5144 FF(GetLogicalDriveStringsA
,-1)
5145 FF(IsBadWritePtr
, 357)
5146 FF(IsBadReadPtr
, 354)
5147 FF(IsBadStringPtrW
, -1)
5148 FF(IsBadStringPtrA
, -1)
5149 FF(DisableThreadLibraryCalls
, -1)
5150 FF(CreateThread
, -1)
5151 FF(ResumeThread
, -1)
5152 FF(CreateEventA
, -1)
5153 FF(CreateEventW
, -1)
5156 FF(WaitForSingleObject
, -1)
5157 #ifdef CONFIG_QTX_CODECS
5158 FF(WaitForMultipleObjects
, -1)
5161 FF(GetSystemInfo
, -1)
5169 FF(GetProcessHeap
, -1)
5170 FF(VirtualAlloc
, -1)
5172 FF(InitializeCriticalSection
, -1)
5173 FF(InitializeCriticalSectionAndSpinCount
, -1)
5174 FF(EnterCriticalSection
, -1)
5175 FF(LeaveCriticalSection
, -1)
5176 FF(DeleteCriticalSection
, -1)
5181 FF(GetCurrentThreadId
, -1)
5182 FF(GetCurrentProcess
, -1)
5187 FF(GlobalReAlloc
, -1)
5190 FF(MultiByteToWideChar
, 427)
5191 FF(WideCharToMultiByte
, -1)
5192 FF(GetVersionExA
, -1)
5193 FF(GetVersionExW
, -1)
5194 FF(CreateSemaphoreA
, -1)
5195 FF(CreateSemaphoreW
, -1)
5196 FF(QueryPerformanceCounter
, -1)
5197 FF(QueryPerformanceFrequency
, -1)
5201 FF(GlobalHandle
, -1)
5202 FF(GlobalUnlock
, -1)
5204 FF(LoadResource
, -1)
5205 FF(ReleaseSemaphore
, -1)
5206 FF(CreateMutexA
, -1)
5207 FF(CreateMutexW
, -1)
5208 FF(ReleaseMutex
, -1)
5209 FF(SignalObjectAndWait
, -1)
5210 FF(FindResourceA
, -1)
5211 FF(LockResource
, -1)
5212 FF(FreeResource
, -1)
5213 FF(SizeofResource
, -1)
5215 FF(GetCommandLineA
, -1)
5216 FF(GetEnvironmentStringsW
, -1)
5217 FF(FreeEnvironmentStringsW
, -1)
5218 FF(FreeEnvironmentStringsA
, -1)
5219 FF(GetEnvironmentStrings
, -1)
5220 FF(GetStartupInfoA
, -1)
5221 FF(GetStdHandle
, -1)
5223 #ifdef CONFIG_QTX_CODECS
5224 FF(GetFileAttributesA
, -1)
5226 FF(SetHandleCount
, -1)
5228 FF(GetModuleFileNameA
, -1)
5229 FF(SetUnhandledExceptionFilter
, -1)
5230 FF(LoadLibraryA
, -1)
5231 FF(GetProcAddress
, -1)
5233 FF(CreateFileMappingA
, -1)
5234 FF(OpenFileMappingA
, -1)
5235 FF(MapViewOfFile
, -1)
5236 FF(UnmapViewOfFile
, -1)
5238 FF(GetModuleHandleA
, -1)
5239 FF(GetModuleHandleW
, -1)
5240 FF(GetProfileIntA
, -1)
5241 FF(GetPrivateProfileIntA
, -1)
5242 FF(GetPrivateProfileStringA
, -1)
5243 FF(WritePrivateProfileStringA
, -1)
5244 FF(GetLastError
, -1)
5245 FF(SetLastError
, -1)
5246 FF(InterlockedIncrement
, -1)
5247 FF(InterlockedDecrement
, -1)
5248 FF(GetTimeZoneInformation
, -1)
5249 FF(OutputDebugStringA
, -1)
5250 FF(GetLocalTime
, -1)
5251 FF(GetSystemTime
, -1)
5252 FF(GetSystemTimeAsFileTime
, -1)
5253 FF(GetEnvironmentVariableA
, -1)
5254 FF(SetEnvironmentVariableA
, -1)
5255 FF(RtlZeroMemory
,-1)
5256 FF(RtlMoveMemory
,-1)
5257 FF(RtlFillMemory
,-1)
5259 FF(FindFirstFileA
,-1)
5260 FF(FindNextFileA
,-1)
5262 FF(FileTimeToLocalFileTime
,-1)
5266 FF(SetFilePointer
,-1)
5267 FF(GetTempFileNameA
,-1)
5269 FF(GetSystemDirectoryA
,-1)
5270 FF(GetWindowsDirectoryA
,-1)
5271 #ifdef CONFIG_QTX_CODECS
5272 FF(GetCurrentDirectoryA
,-1)
5273 FF(SetCurrentDirectoryA
,-1)
5274 FF(CreateDirectoryA
,-1)
5276 FF(GetShortPathNameA
,-1)
5277 FF(GetFullPathNameA
,-1)
5278 FF(SetErrorMode
, -1)
5279 FF(IsProcessorFeaturePresent
, -1)
5280 FF(IsDebuggerPresent
, -1)
5281 FF(GetProcessAffinityMask
, -1)
5282 FF(InterlockedExchange
, -1)
5283 FF(InterlockedCompareExchange
, -1)
5290 FF(GetProcessVersion
,-1)
5291 FF(GetCurrentThread
,-1)
5294 FF(DuplicateHandle
,-1)
5295 FF(GetTickCount
, -1)
5296 FF(SetThreadAffinityMask
,-1)
5297 FF(GetCurrentProcessId
,-1)
5298 FF(GlobalMemoryStatus
,-1)
5299 FF(GetThreadPriority
,-1)
5300 FF(SetThreadPriority
,-1)
5301 FF(TerminateProcess
,-1)
5303 {"LoadLibraryExA", -1, (void*)&LoadLibraryExA
},
5304 FF(SetThreadIdealProcessor
,-1)
5305 FF(SetProcessAffinityMask
, -1)
5306 FF(EncodePointer
, -1)
5307 FF(DecodePointer
, -1)
5308 FF(GetThreadLocale
, -1)
5309 FF(GetLocaleInfoA
, -1)
5310 UNDEFF(FlsAlloc
, -1)
5311 UNDEFF(FlsGetValue
, -1)
5312 UNDEFF(FlsSetValue
, -1)
5316 static const struct exports exp_msvcrt
[]={
5322 {"??3@YAXPAX@Z", -1, expdelete
},
5323 {"??2@YAPAXI@Z", -1, expnew
},
5324 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5325 {"_winver",-1,(void*)&_winver
},
5366 /* needed by frapsvid.dll */
5367 {"strstr",-1,(char *)&strstr
},
5368 {"qsort",-1,(void *)&qsort
},
5371 {"ceil",-1,(void*)&ceil
},
5372 /* needed by imagepower mjpeg2k */
5373 {"clock",-1,(void*)&clock
},
5374 {"memchr",-1,(void*)&memchr
},
5375 {"vfprintf",-1,(void*)&vfprintf
},
5376 // {"realloc",-1,(void*)&realloc},
5378 {"puts",-1,(void*)&puts
}
5380 static const struct exports exp_winmm
[]={
5381 FF(GetDriverModuleHandle
, -1)
5383 FF(DefDriverProc
, -1)
5386 FF(timeGetDevCaps
, -1)
5387 FF(timeBeginPeriod
, -1)
5388 #ifdef CONFIG_QTX_CODECS
5389 FF(timeEndPeriod
, -1)
5390 FF(waveOutGetNumDevs
, -1)
5393 static const struct exports exp_psapi
[]={
5394 FF(GetModuleBaseNameA
, -1)
5396 static const struct exports exp_user32
[]={
5401 FF(GetDesktopWindow
, -1)
5407 #ifdef CONFIG_QTX_CODECS
5410 FF(RegisterWindowMessageA
,-1)
5411 FF(GetSystemMetrics
,-1)
5413 FF(GetSysColorBrush
,-1)
5417 FF(RegisterClassA
, -1)
5418 FF(UnregisterClassA
, -1)
5419 #ifdef CONFIG_QTX_CODECS
5420 FF(GetWindowRect
, -1)
5421 FF(MonitorFromWindow
, -1)
5422 FF(MonitorFromRect
, -1)
5423 FF(MonitorFromPoint
, -1)
5424 FF(EnumDisplayMonitors
, -1)
5425 FF(GetMonitorInfoA
, -1)
5426 FF(EnumDisplayDevicesA
, -1)
5427 FF(GetClientRect
, -1)
5428 FF(ClientToScreen
, -1)
5429 FF(IsWindowVisible
, -1)
5430 FF(GetActiveWindow
, -1)
5431 FF(GetClassNameA
, -1)
5432 FF(GetClassInfoA
, -1)
5433 FF(GetWindowLongA
, -1)
5435 FF(GetWindowThreadProcessId
, -1)
5436 FF(CreateWindowExA
, -1)
5439 FF(DialogBoxParamA
, -1)
5440 FF(RegisterClipboardFormatA
, -1)
5442 FF(EnumDisplaySettingsA
, -1)
5444 static const struct exports exp_advapi32
[]={
5446 FF(RegCreateKeyA
, -1)
5447 FF(RegCreateKeyExA
, -1)
5448 FF(RegEnumKeyExA
, -1)
5449 FF(RegEnumValueA
, -1)
5451 FF(RegOpenKeyExA
, -1)
5452 FF(RegQueryValueExA
, -1)
5453 FF(RegSetValueExA
, -1)
5454 FF(RegQueryInfoKeyA
, -1)
5456 static const struct exports exp_gdi32
[]={
5457 FF(CreateCompatibleDC
, -1)
5460 FF(DeleteObject
, -1)
5461 FF(GetDeviceCaps
, -1)
5462 FF(GetSystemPaletteEntries
, -1)
5463 #ifdef CONFIG_QTX_CODECS
5464 FF(CreatePalette
, -1)
5466 FF(CreateRectRgn
, -1)
5469 static const struct exports exp_version
[]={
5470 FF(GetFileVersionInfoSizeA
, -1)
5472 static const struct exports exp_ole32
[]={
5473 FF(CoCreateFreeThreadedMarshaler
,-1)
5474 FF(CoCreateInstance
, -1)
5475 FF(CoInitialize
, -1)
5476 FF(CoInitializeEx
, -1)
5477 FF(CoUninitialize
, -1)
5478 FF(CoTaskMemAlloc
, -1)
5479 FF(CoTaskMemFree
, -1)
5480 FF(StringFromGUID2
, -1)
5481 FF(PropVariantClear
, -1)
5483 // do we really need crtdll ???
5484 // msvcrt is the correct place probably...
5485 static const struct exports exp_crtdll
[]={
5489 static const struct exports exp_comctl32
[]={
5490 FF(StringFromGUID2
, -1)
5491 FF(InitCommonControls
, 17)
5492 #ifdef CONFIG_QTX_CODECS
5493 FF(CreateUpDownControl
, 16)
5496 static const struct exports exp_wsock32
[]={
5500 static const struct exports exp_msdmo
[]={
5501 FF(memcpy
, -1) // just test
5502 FF(MoCopyMediaType
, -1)
5503 FF(MoCreateMediaType
, -1)
5504 FF(MoDeleteMediaType
, -1)
5505 FF(MoDuplicateMediaType
, -1)
5506 FF(MoFreeMediaType
, -1)
5507 FF(MoInitMediaType
, -1)
5509 static const struct exports exp_oleaut32
[]={
5510 FF(SysAllocStringLen
, 4)
5511 FF(SysFreeString
, 6)
5513 #ifdef CONFIG_QTX_CODECS
5514 FF(SysStringByteLen
, 149)
5520 vma: Hint/Ord Member-Name
5525 2305e 167 _adjust_fdiv
5528 22ffc 176 _beginthreadex
5530 2300e 85 __CxxFrameHandler
5534 static const struct exports exp_pncrt
[]={
5535 FF(malloc
, -1) // just test
5536 FF(free
, -1) // just test
5537 FF(fprintf
, -1) // just test
5538 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5541 {"??3@YAXPAX@Z", -1, expdelete
},
5542 {"??2@YAPAXI@Z", -1, expnew
},
5553 #ifdef CONFIG_QTX_CODECS
5554 static const struct exports exp_ddraw
[]={
5555 FF(DirectDrawCreate
, -1)
5559 static const struct exports exp_comdlg32
[]={
5560 FF(GetOpenFileNameA
, -1)
5563 static const struct exports exp_shlwapi
[]={
5564 FF(PathFindExtensionA
, -1)
5565 FF(PathFindFileNameA
, -1)
5568 static const struct exports exp_msvcr80
[]={
5576 FF(_decode_pointer
, -1)
5577 /* needed by KGV1-VFW.dll */
5578 {"??2@YAPAXI@Z", -1, expnew
},
5579 {"??3@YAXPAX@Z", -1, expdelete
}
5582 static const struct exports exp_msvcp60
[]={
5583 {"??0_Lockit@std@@QAE@XZ", -1, exp_0Lockit_dummy
},
5584 {"??1_Lockit@std@@QAE@XZ", -1, exp_1Lockit_dummy
}
5587 static const struct exports exp_msvcr100
[]={
5592 {"??2@YAPAXI@Z", -1, expnew
},
5593 {"??3@YAXPAX@Z", -1, expdelete
}
5597 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5599 static const struct libs libraries
[]={
5617 #ifdef CONFIG_QTX_CODECS
5627 static WIN_BOOL WINAPI
ext_stubs(void)
5629 // NOTE! these magic values will be replaced at runtime, make sure
5630 // add_stub can still find them if you change them.
5631 volatile int idx
= 0x0deadabc;
5632 // make sure gcc does not do eip-relative call or something like that
5633 void (* volatile my_printf
)(char *, char *) = (void *)0xdeadfbcd;
5634 my_printf("Called unk_%s\n", export_names
[idx
]);
5638 #define MAX_STUB_SIZE 0x60
5639 #define MAX_NUM_STUBS 200
5641 static char *extcode
= NULL
;
5643 static void* add_stub(void)
5647 // generated code in runtime!
5650 extcode
= mmap_anon(NULL
, MAX_NUM_STUBS
* MAX_STUB_SIZE
,
5651 PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
, 0);
5652 answ
= extcode
+ pos
* MAX_STUB_SIZE
;
5653 if (pos
>= MAX_NUM_STUBS
) {
5654 printf("too many stubs, expect crash\n");
5657 memcpy(answ
, ext_stubs
, MAX_STUB_SIZE
);
5658 for (i
= 0; i
< MAX_STUB_SIZE
- 3; i
++) {
5659 int *magic
= (int *)(answ
+ i
);
5660 if (*magic
== 0x0deadabc) {
5664 if (*magic
== 0xdeadfbcd) {
5665 *magic
= (intptr_t)printf
;
5670 printf("magic code not found in ext_subs, expect crash\n");
5677 void* LookupExternal(const char* library
, int ordinal
)
5682 printf("ERROR: library=0\n");
5683 return (void*)ext_unknown
;
5685 // printf("%x %x\n", &unk_exp1, &unk_exp2);
5687 dbgprintf("External func %s:%d\n", library
, ordinal
);
5689 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5691 if(strcasecmp(library
, libraries
[i
].name
))
5693 for(j
=0; j
<libraries
[i
].length
; j
++)
5695 if(ordinal
!=libraries
[i
].exps
[j
].id
)
5697 //printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5698 return libraries
[i
].exps
[j
].func
;
5702 #ifndef LOADLIB_TRY_NATIVE
5703 /* hack for truespeech and vssh264*/
5704 if (!strcmp(library
, "tsd32.dll") || !strcmp(library
,"vssh264dec.dll") || !strcmp(library
,"LCMW2.dll") || !strcmp(library
,"VDODEC32.dll"))
5706 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5712 hand
= LoadLibraryA(library
);
5715 wm
= MODULE32_LookupHMODULE(hand
);
5721 func
= PE_FindExportedFunction(wm
, (LPCSTR
) ordinal
, 0);
5724 printf("No such ordinal in external dll\n");
5725 FreeLibrary((int)hand
);
5729 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5735 if(pos
>150)return 0;
5736 snprintf(export_names
[pos
], sizeof(export_names
[pos
]), "%s:%d", library
, ordinal
);
5740 void* LookupExternalByName(const char* library
, const char* name
)
5743 // return (void*)ext_unknown;
5746 printf("ERROR: library=0\n");
5747 return (void*)ext_unknown
;
5749 if((unsigned long)name
<=0xffff)
5751 return LookupExternal(library
, (int)name
);
5753 dbgprintf("External func %s:%s\n", library
, name
);
5754 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5756 if(strcasecmp(library
, libraries
[i
].name
))
5758 for(j
=0; j
<libraries
[i
].length
; j
++)
5760 if(strcmp(name
, libraries
[i
].exps
[j
].name
))
5762 if((unsigned int)(libraries
[i
].exps
[j
].func
) == -1)
5763 return NULL
; //undefined func
5764 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5765 return libraries
[i
].exps
[j
].func
;
5769 #ifndef LOADLIB_TRY_NATIVE
5770 /* hack for vss h264 */
5771 if (!strcmp(library
,"vssh264core.dll") || !strcmp(library
,"3ivx.dll"))
5773 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5779 hand
= LoadLibraryA(library
);
5782 wm
= MODULE32_LookupHMODULE(hand
);
5788 func
= PE_FindExportedFunction(wm
, name
, 0);
5791 printf("No such name in external dll\n");
5792 FreeLibrary((int)hand
);
5796 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5802 if(pos
>150)return 0;// to many symbols
5803 snprintf(export_names
[pos
], sizeof(export_names
[pos
]), "%s", name
);
5807 void my_garbagecollection(void)
5810 int unfree
= 0, unfreecnt
= 0;
5816 alloc_header
* mem
= last_alloc
+ 1;
5817 unfree
+= my_size(mem
);
5819 if (my_release(mem
) != 0)
5820 // avoid endless loop when memory is trashed
5821 if (--max_fatal
< 0)
5824 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree
, unfreecnt
, last_alloc
, alccnt
);
5827 pthread_mutex_lock(&list_lock
);
5829 pthread_mutex_unlock(&list_lock
);