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"
64 #include <sys/types.h>
72 #ifdef HAVE_SYS_MMAN_H
75 #include "osdep/mmap.h"
77 #include "osdep/mmap_anon.h"
78 #include "libavutil/avstring.h"
80 static void do_cpuid(unsigned int ax
, unsigned int *regs
)
84 "pushl %%ebx; pushl %%ecx; pushl %%edx;"
90 "popl %%edx; popl %%ecx; popl %%ebx;"
92 : "0" (ax
), "S" (regs
)
95 static unsigned int c_localcount_tsc(void)
107 static void c_longcount_tsc(long long* z
)
112 "movl %%eax, %%ebx\n\t"
114 "movl %%eax, 0(%%ebx)\n\t"
115 "movl %%edx, 4(%%ebx)\n\t"
121 static unsigned int c_localcount_notsc(void)
126 gettimeofday(&tv
, 0);
127 return limit
*tv
.tv_usec
;
129 static void c_longcount_notsc(long long* z
)
132 unsigned long long result
;
136 gettimeofday(&tv
, 0);
139 result
+=limit
*tv
.tv_usec
;
142 static unsigned int localcount_stub(void);
143 static void longcount_stub(long long*);
144 static unsigned int (*localcount
)()=localcount_stub
;
145 static void (*longcount
)(long long*)=longcount_stub
;
147 static pthread_mutex_t memmut
= PTHREAD_MUTEX_INITIALIZER
;
149 static unsigned int localcount_stub(void)
151 unsigned int regs
[4];
153 if ((regs
[3] & 0x00000010) != 0)
155 localcount
=c_localcount_tsc
;
156 longcount
=c_longcount_tsc
;
160 localcount
=c_localcount_notsc
;
161 longcount
=c_longcount_notsc
;
165 static void longcount_stub(long long* z
)
167 unsigned int regs
[4];
169 if ((regs
[3] & 0x00000010) != 0)
171 localcount
=c_localcount_tsc
;
172 longcount
=c_longcount_tsc
;
176 localcount
=c_localcount_notsc
;
177 longcount
=c_longcount_notsc
;
183 int LOADER_DEBUG
=1; // active only if compiled with -DDETAILED_OUT
184 //#define DETAILED_OUT
185 static inline void dbgprintf(char* fmt
, ...)
193 f
=fopen("./log", "a");
198 vfprintf(f
, fmt
, va
);
205 if ( mp_msg_test(MSGT_WIN32
,MSGL_DBG3
) )
211 // mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va);
218 char export_names
[300][32]={
223 //#define min(x,y) ((x)<(y)?(x):(y))
225 void destroy_event(void* event
);
228 typedef struct th_list_t
{
231 struct th_list_t
* next
;
232 struct th_list_t
* prev
;
236 // have to be cleared by GARBAGE COLLECTOR
237 //static unsigned char* heap=NULL;
238 //static int heap_counter=0;
239 static tls_t
* g_tls
=NULL
;
240 static th_list
* list
=NULL
;
241 static pthread_mutex_t list_lock
= PTHREAD_MUTEX_INITIALIZER
;
244 static void test_heap(void)
249 while(offset
<heap_counter
)
251 if(*(int*)(heap
+offset
)!=0x433476)
253 printf("Heap corruption at address %d\n", offset
);
256 offset
+=8+*(int*)(heap
+offset
+4);
258 for(;offset
<min(offset
+1000, 20000000); offset
++)
259 if(heap
[offset
]!=0xCC)
261 printf("Free heap corruption at address %d\n", offset
);
269 static void* my_mreq(int size
, int to_zero
)
273 if(test
%10==0)printf("Memory: %d bytes allocated\n", heap_counter
);
277 heap
=malloc(20000000);
278 memset(heap
, 0xCC,20000000);
282 printf("No enough memory\n");
285 if(heap_counter
+size
>20000000)
287 printf("No enough memory\n");
290 *(int*)(heap
+heap_counter
)=0x433476;
292 *(int*)(heap
+heap_counter
)=size
;
294 printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size
, heap_counter
-8, heap_counter
, heap_counter
+size
);
296 memset(heap
+heap_counter
, 0, size
);
298 memset(heap
+heap_counter
, 0xcc, size
); // make crash reproducable
300 return heap
+heap_counter
-size
;
302 static int my_release(char* memory
)
307 printf("ERROR: free(0)\n");
310 if(*(int*)(memory
-8)!=0x433476)
312 printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
315 printf("Freed %d bytes of memory\n", *(int*)(memory
-4));
316 // memset(memory-8, *(int*)(memory-4), 0xCC);
322 typedef struct alloc_header_t alloc_header
;
323 struct alloc_header_t
325 // let's keep allocated data 16 byte aligned
337 static alloc_header
* last_alloc
= NULL
;
338 static int alccnt
= 0;
341 #define AREATYPE_CLIENT 0
342 #define AREATYPE_EVENT 1
343 #define AREATYPE_MUTEX 2
344 #define AREATYPE_COND 3
345 #define AREATYPE_CRITSECT 4
347 /* -- critical sections -- */
351 pthread_mutex_t mutex
;
352 pthread_cond_t unlocked
;
357 void* mreq_private(int size
, int to_zero
, int type
);
358 void* mreq_private(int size
, int to_zero
, int type
)
360 int nsize
= size
+ sizeof(alloc_header
);
361 alloc_header
* header
= malloc(nsize
);
365 memset(header
, 0, nsize
);
367 pthread_mutex_lock(&memmut
);
370 last_alloc
->next
= header
; /* set next */
373 header
->prev
= last_alloc
;
377 pthread_mutex_unlock(&memmut
);
379 header
->deadbeef
= 0xdeadbeef;
383 //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt);
387 static int my_release(void* memory
)
389 alloc_header
* header
= (alloc_header
*) memory
- 1;
391 alloc_header
* prevmem
;
392 alloc_header
* nextmem
;
397 if (header
->deadbeef
!= (long) 0xdeadbeef)
399 dbgprintf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
403 pthread_mutex_lock(&memmut
);
408 destroy_event(memory
);
411 pthread_cond_destroy((pthread_cond_t
*)memory
);
414 pthread_mutex_destroy((pthread_mutex_t
*)memory
);
416 case AREATYPE_CRITSECT
:
417 pthread_mutex_destroy(&((struct CRITSECT
*)memory
)->mutex
);
420 //memset(memory, 0xcc, header->size);
424 header
->deadbeef
= 0;
425 prevmem
= header
->prev
;
426 nextmem
= header
->next
;
429 prevmem
->next
= nextmem
;
431 nextmem
->prev
= prevmem
;
433 if (header
== last_alloc
)
434 last_alloc
= prevmem
;
438 pthread_mutex_unlock(&memmut
);
440 //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt);
445 //memset(header + 1, 0xcc, header->size);
451 static inline void* my_mreq(int size
, int to_zero
)
453 return mreq_private(size
, to_zero
, AREATYPE_CLIENT
);
456 static int my_size(void* memory
)
458 if(!memory
) return 0;
459 return ((alloc_header
*)memory
)[-1].size
;
462 static void* my_realloc(void* memory
, int size
)
467 return my_mreq(size
, 0);
468 osize
= my_size(memory
);
471 ans
= my_mreq(size
, 0);
472 memcpy(ans
, memory
, osize
);
480 * WINE API - native implementation for several win32 libraries
484 static int WINAPI
ext_unknown(void)
486 printf("Unknown func called\n");
490 static int WINAPI
expGetVolumeInformationA( const char *root
, char *label
,
491 unsigned int label_len
, unsigned int *serial
,
492 unsigned int *filename_len
,unsigned int *flags
,
493 char *fsname
, unsigned int fsname_len
)
495 dbgprintf("GetVolumeInformationA( %s, 0x%x, %ld, 0x%x, 0x%x, 0x%x, 0x%x, %ld) => 1\n",
496 root
,label
,label_len
,serial
,filename_len
,flags
,fsname
,fsname_len
);
497 //hack Do not return any real data - do nothing
501 static unsigned int WINAPI
expGetDriveTypeA( const char *root
)
503 dbgprintf("GetDriveTypeA( %s ) => %d\n",root
,DRIVE_FIXED
);
504 // hack return as Fixed Drive Type
508 static unsigned int WINAPI
expGetLogicalDriveStringsA( unsigned int len
, char *buffer
)
510 dbgprintf("GetLogicalDriveStringsA(%d, 0x%x) => 4\n",len
,buffer
);
511 // hack only have one drive c:\ in this hack
517 return 4; // 1 drive * 4 bytes (includes null)
521 static int WINAPI
expIsBadWritePtr(void* ptr
, unsigned int count
)
523 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
524 dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
527 static int WINAPI
expIsBadReadPtr(void* ptr
, unsigned int count
)
529 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
530 dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
533 static int WINAPI
expDisableThreadLibraryCalls(int module
)
535 dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module
);
539 static HMODULE WINAPI
expGetDriverModuleHandle(DRVR
* pdrv
)
545 result
=pdrv
->hDriverModule
;
546 dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv
, result
);
550 #define MODULE_HANDLE_kernel32 ((HMODULE)0x120)
551 #define MODULE_HANDLE_user32 ((HMODULE)0x121)
552 #ifdef CONFIG_QTX_CODECS
553 #define MODULE_HANDLE_wininet ((HMODULE)0x122)
554 #define MODULE_HANDLE_ddraw ((HMODULE)0x123)
555 #define MODULE_HANDLE_advapi32 ((HMODULE)0x124)
557 #define MODULE_HANDLE_comdlg32 ((HMODULE)0x125)
558 #define MODULE_HANDLE_msvcrt ((HMODULE)0x126)
559 #define MODULE_HANDLE_ole32 ((HMODULE)0x127)
560 #define MODULE_HANDLE_winmm ((HMODULE)0x128)
561 #define MODULE_HANDLE_psapi ((HMODULE)0x129)
563 // Fake PE header, since some software (and the Microsoft CRT v8 and newer)
564 // assume GetModuleHandle(NULL) returns a pointer to a PE header.
565 // We simulate a very simple header with only one section.
567 // NOTE: If you have a section called .mixcrt, the Microsoft CRT will assume
568 // it's running in a POSIX binary, and stop using EncodePointer/DecodePointer.
569 static const struct {
570 IMAGE_DOS_HEADER doshdr
;
571 IMAGE_NT_HEADERS nthdr
;
572 IMAGE_SECTION_HEADER opthdr
;
573 } __attribute__((__packed__
)) mp_exe
= {
574 .doshdr
.e_lfanew
= sizeof(IMAGE_DOS_HEADER
),
575 .nthdr
.FileHeader
.NumberOfSections
= 1,
576 .nthdr
.FileHeader
.SizeOfOptionalHeader
=
577 sizeof(IMAGE_NT_HEADERS
) - FIELD_OFFSET(IMAGE_NT_HEADERS
, OptionalHeader
), /* 0xe0 */
578 .opthdr
.Name
= ".text"
581 static HMODULE WINAPI
expGetModuleHandleA(const char* name
)
586 result
=(HMODULE
)&mp_exe
.doshdr
;
589 wm
=MODULE_FindModule(name
);
592 result
=(HMODULE
)(wm
->module
);
596 if(name
&& (strcasecmp(name
, "kernel32")==0 || !strcasecmp(name
, "kernel32.dll")))
597 result
=MODULE_HANDLE_kernel32
;
598 #ifdef CONFIG_QTX_CODECS
599 if(name
&& strcasecmp(name
, "user32")==0)
600 result
=MODULE_HANDLE_user32
;
603 dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name
, result
);
607 static HMODULE WINAPI
expGetModuleHandleW(const uint16_t* name
)
612 if (*name
> 256 || pos
>= sizeof(aname
) - 1)
614 aname
[pos
++] = *name
++;
617 return expGetModuleHandleA(aname
);
620 static void* WINAPI
expCreateThread(void* pSecAttr
, long dwStackSize
,
621 void* lpStartAddress
, void* lpParameter
,
622 long dwFlags
, long* dwThreadId
)
625 // printf("CreateThread:");
626 pth
= (pthread_t
*) my_mreq(sizeof(pthread_t
), 0);
627 pthread_create(pth
, NULL
, (void*(*)(void*))lpStartAddress
, lpParameter
);
629 printf( "WARNING: CreateThread flags not supported\n");
631 *dwThreadId
=(long)pth
;
632 pthread_mutex_lock(&list_lock
);
635 list
=my_mreq(sizeof(th_list
), 1);
636 list
->next
=list
->prev
=NULL
;
640 list
->next
=my_mreq(sizeof(th_list
), 0);
641 list
->next
->prev
=list
;
642 list
->next
->next
=NULL
;
646 pthread_mutex_unlock(&list_lock
);
647 dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
648 pSecAttr
, dwStackSize
, lpStartAddress
, lpParameter
, dwFlags
, dwThreadId
, pth
);
652 static DWORD WINAPI
expResumeThread(HANDLE hThread
)
655 dbgprintf("ResumeThread(0x%x) => 0x%x\n", hThread
, ret
);
672 struct mutex_list_t
* next
;
673 struct mutex_list_t
* prev
;
675 typedef struct mutex_list_t mutex_list
;
676 static mutex_list
* mlist
=NULL
;
677 static pthread_mutex_t mlist_lock
= PTHREAD_MUTEX_INITIALIZER
;
679 void destroy_event(void* event
)
681 pthread_mutex_lock(&mlist_lock
);
682 mutex_list
* pp
=mlist
;
683 // printf("garbage collector: destroy_event(%x)\n", event);
686 if(pp
==(mutex_list
*)event
)
689 pp
->next
->prev
=pp
->prev
;
691 pp
->prev
->next
=pp
->next
;
692 if(mlist
==(mutex_list
*)event
)
698 printf("%x => ", pp);
703 pthread_mutex_unlock(&mlist_lock
);
708 pthread_mutex_unlock(&mlist_lock
);
711 static void* WINAPI
expCreateEventA(void* pSecAttr
, char bManualReset
,
712 char bInitialState
, const char* name
)
722 printf("%x => ", pp);
727 pthread_mutex_lock(&mlist_lock
);
730 mutex_list
* pp
=mlist
;
734 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==0))
736 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
737 pSecAttr
, bManualReset
, bInitialState
, name
, name
, pp
->pm
);
738 pthread_mutex_unlock(&mlist_lock
);
741 }while((pp
=pp
->prev
) != NULL
);
743 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
744 pthread_mutex_init(pm
, NULL
);
745 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
746 pthread_cond_init(pc
, NULL
);
749 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
750 mlist
->next
=mlist
->prev
=NULL
;
754 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
755 mlist
->next
->prev
=mlist
;
756 mlist
->next
->next
=NULL
;
759 mlist
->type
=0; /* Type Event */
762 mlist
->state
=bInitialState
;
763 mlist
->reset
=!bManualReset
;
765 strncpy(mlist
->name
, name
, 127);
769 dbgprintf("ERROR::: CreateEventA failure\n");
772 pthread_mutex_lock(pm);
775 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
776 pSecAttr
, bManualReset
, bInitialState
, name
, name
, mlist
);
778 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
779 pSecAttr
, bManualReset
, bInitialState
, mlist
);
781 pthread_mutex_unlock(&mlist_lock
);
785 static void* WINAPI
expCreateEventW(void* pSecAttr
, char bManualReset
,
786 char bInitialState
, const WCHAR
* name
)
788 char ascii_name
[256];
791 WideCharToMultiByte(65001, 0x0, name
, -1, ascii_name
, 256, NULL
, NULL
);
794 return expCreateEventA(pSecAttr
, bManualReset
, bInitialState
, aname
);
797 static void* WINAPI
expSetEvent(void* event
)
799 mutex_list
*ml
= (mutex_list
*)event
;
800 dbgprintf("SetEvent(%x) => 0x1\n", event
);
801 pthread_mutex_lock(ml
->pm
);
802 if (ml
->state
== 0) {
804 pthread_cond_signal(ml
->pc
);
806 pthread_mutex_unlock(ml
->pm
);
810 static void* WINAPI
expResetEvent(void* event
)
812 mutex_list
*ml
= (mutex_list
*)event
;
813 dbgprintf("ResetEvent(0x%x) => 0x1\n", event
);
814 pthread_mutex_lock(ml
->pm
);
816 pthread_mutex_unlock(ml
->pm
);
821 static void* WINAPI
expWaitForSingleObject(void* object
, int duration
)
823 mutex_list
*ml
= (mutex_list
*)object
;
824 // FIXME FIXME FIXME - this value is sometime unititialize !!!
825 int ret
= WAIT_FAILED
;
828 if(object
== (void*)0xcfcf9898)
831 From GetCurrentThread() documentation:
832 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.
834 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.
836 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.
838 dbgprintf("WaitForSingleObject(thread_handle) called\n");
839 return (void*)WAIT_FAILED
;
841 dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object
, duration
);
843 // See if this is a thread.
844 pthread_mutex_lock(&list_lock
);
846 while (tp
&& (tp
->thread
!= object
))
848 pthread_mutex_unlock(&list_lock
);
850 if (pthread_join(*(pthread_t
*)object
, NULL
) == 0) {
851 return (void*)WAIT_OBJECT_0
;
853 return (void*)WAIT_FAILED
;
857 // loop below was slightly fixed - its used just for checking if
858 // this object really exists in our list
861 pthread_mutex_lock(&mlist_lock
);
863 while (pp
&& (pp
->pm
!= ml
->pm
))
865 pthread_mutex_unlock(&mlist_lock
);
867 dbgprintf("WaitForSingleObject: NotFound\n");
871 pthread_mutex_lock(ml
->pm
);
875 if (duration
== 0) { /* Check Only */
876 if (ml
->state
== 1) ret
= WAIT_OBJECT_0
;
877 else ret
= WAIT_FAILED
;
879 if (duration
== -1) { /* INFINITE */
881 pthread_cond_wait(ml
->pc
,ml
->pm
);
886 if (duration
> 0) { /* Timed Wait */
887 struct timespec abstime
;
889 gettimeofday(&now
, 0);
890 abstime
.tv_sec
= now
.tv_sec
+ (now
.tv_usec
+duration
)/1000000;
891 abstime
.tv_nsec
= ((now
.tv_usec
+duration
)%1000000)*1000;
893 ret
=pthread_cond_timedwait(ml
->pc
,ml
->pm
,&abstime
);
894 if (ret
== ETIMEDOUT
) ret
= WAIT_TIMEOUT
;
895 else ret
= WAIT_OBJECT_0
;
900 case 1: /* Semaphore */
902 if(ml
->semaphore
==0) ret
= WAIT_FAILED
;
908 if (duration
== -1) {
909 if (ml
->semaphore
==0)
910 pthread_cond_wait(ml
->pc
,ml
->pm
);
917 if(ml
->lock_count
> 0 && ml
->owner
!= pthread_self()) ret
= WAIT_FAILED
;
920 ml
->owner
= pthread_self();
924 if (duration
== -1) {
925 if (ml
->lock_count
> 0 && ml
->owner
!= pthread_self()) {
926 pthread_cond_wait(ml
->pc
,ml
->pm
);
929 ml
->owner
= pthread_self();
934 pthread_mutex_unlock(ml
->pm
);
936 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object
,duration
,ml
,ret
);
940 #ifdef CONFIG_QTX_CODECS
941 static void* WINAPI
expWaitForMultipleObjects(int count
, const void** objects
,
942 int WaitAll
, int duration
)
948 dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
949 count
, objects
, WaitAll
, duration
);
951 for (i
= 0; i
< count
; i
++)
953 object
= (void *)objects
[i
];
954 ret
= expWaitForSingleObject(object
, duration
);
956 dbgprintf("WaitAll flag not yet supported...\n");
963 static void WINAPI
expExitThread(int retcode
)
965 dbgprintf("ExitThread(%d)\n", retcode
);
966 pthread_exit(&retcode
);
970 static int pf_set
= 0;
971 static BYTE PF
[64] = {0,};
973 static void DumpSystemInfo(const SYSTEM_INFO
* si
)
975 dbgprintf(" Processor architecture %d\n", si
->u
.s
.wProcessorArchitecture
);
976 dbgprintf(" Page size: %d\n", si
->dwPageSize
);
977 dbgprintf(" Minimum app address: %d\n", si
->lpMinimumApplicationAddress
);
978 dbgprintf(" Maximum app address: %d\n", si
->lpMaximumApplicationAddress
);
979 dbgprintf(" Active processor mask: 0x%x\n", si
->dwActiveProcessorMask
);
980 dbgprintf(" Number of processors: %d\n", si
->dwNumberOfProcessors
);
981 dbgprintf(" Processor type: 0x%x\n", si
->dwProcessorType
);
982 dbgprintf(" Allocation granularity: 0x%x\n", si
->dwAllocationGranularity
);
983 dbgprintf(" Processor level: 0x%x\n", si
->wProcessorLevel
);
984 dbgprintf(" Processor revision: 0x%x\n", si
->wProcessorRevision
);
987 static void WINAPI
expGetSystemInfo(SYSTEM_INFO
* si
)
989 /* FIXME: better values for the two entries below... */
990 static int cache
= 0;
991 static SYSTEM_INFO cachedsi
;
992 dbgprintf("GetSystemInfo(%p) =>\n", si
);
997 memset(PF
,0,sizeof(PF
));
1000 cachedsi
.u
.s
.wProcessorArchitecture
= PROCESSOR_ARCHITECTURE_INTEL
;
1001 cachedsi
.dwPageSize
= getpagesize();
1003 /* FIXME: better values for the two entries below... */
1004 cachedsi
.lpMinimumApplicationAddress
= (void *)0x00000000;
1005 cachedsi
.lpMaximumApplicationAddress
= (void *)0x7FFFFFFF;
1006 cachedsi
.dwActiveProcessorMask
= 1;
1007 cachedsi
.dwNumberOfProcessors
= 1;
1008 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1009 cachedsi
.dwAllocationGranularity
= 0x10000;
1010 cachedsi
.wProcessorLevel
= 5; /* pentium */
1011 cachedsi
.wProcessorRevision
= 0x0101;
1013 /* mplayer's way to detect PF's */
1015 #include "cpudetect.h"
1017 if (gCpuCaps
.hasMMX
)
1018 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1019 if (gCpuCaps
.hasSSE
)
1020 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1021 if (gCpuCaps
.hasSSE2
)
1022 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1023 if (gCpuCaps
.has3DNow
)
1024 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1026 if (gCpuCaps
.cpuType
== 4)
1028 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1029 cachedsi
.wProcessorLevel
= 4;
1031 else if (gCpuCaps
.cpuType
>= 5)
1033 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1034 cachedsi
.wProcessorLevel
= 5;
1038 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1039 cachedsi
.wProcessorLevel
= 3;
1041 cachedsi
.wProcessorRevision
= gCpuCaps
.cpuStepping
;
1042 cachedsi
.dwNumberOfProcessors
= 1; /* hardcoded */
1045 /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
1046 fdiv_bug and fpu emulation flags -- alex/MPlayer */
1051 FILE *f
= fopen ("/proc/cpuinfo", "r");
1055 mp_msg(MSGT_WIN32
, MSGL_WARN
, "expGetSystemInfo: "
1056 "/proc/cpuinfo not readable! "
1057 "Expect bad performance and/or weird behaviour\n");
1060 while (fgets(line
,200,f
)!=NULL
) {
1063 /* NOTE: the ':' is the only character we can rely on */
1064 if (!(value
= strchr(line
,':')))
1066 /* terminate the valuename */
1068 /* skip any leading spaces */
1069 while (*value
==' ') value
++;
1070 if ((s
=strchr(value
,'\n')))
1074 if (!lstrncmpiA(line
, "cpu family",strlen("cpu family"))) {
1075 if (isdigit (value
[0])) {
1076 switch (value
[0] - '0') {
1077 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1078 cachedsi
.wProcessorLevel
= 3;
1080 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1081 cachedsi
.wProcessorLevel
= 4;
1083 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1084 cachedsi
.wProcessorLevel
= 5;
1086 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1087 cachedsi
.wProcessorLevel
= 5;
1089 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1090 cachedsi
.wProcessorLevel
= 5;
1094 /* set the CPU type of the current processor */
1095 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1098 /* old 2.0 method */
1099 if (!lstrncmpiA(line
, "cpu",strlen("cpu"))) {
1100 if ( isdigit (value
[0]) && value
[1] == '8' &&
1101 value
[2] == '6' && value
[3] == 0
1103 switch (value
[0] - '0') {
1104 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1105 cachedsi
.wProcessorLevel
= 3;
1107 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1108 cachedsi
.wProcessorLevel
= 4;
1110 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1111 cachedsi
.wProcessorLevel
= 5;
1113 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1114 cachedsi
.wProcessorLevel
= 5;
1116 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1117 cachedsi
.wProcessorLevel
= 5;
1121 /* set the CPU type of the current processor */
1122 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1125 if (!lstrncmpiA(line
,"fdiv_bug",strlen("fdiv_bug"))) {
1126 if (!lstrncmpiA(value
,"yes",3))
1127 PF
[PF_FLOATING_POINT_PRECISION_ERRATA
] = TRUE
;
1131 if (!lstrncmpiA(line
,"fpu",strlen("fpu"))) {
1132 if (!lstrncmpiA(value
,"no",2))
1133 PF
[PF_FLOATING_POINT_EMULATED
] = TRUE
;
1137 if (!lstrncmpiA(line
,"processor",strlen("processor"))) {
1138 /* processor number counts up...*/
1141 if (sscanf(value
,"%d",&x
))
1142 if (x
+1>cachedsi
.dwNumberOfProcessors
)
1143 cachedsi
.dwNumberOfProcessors
=x
+1;
1145 /* Create a new processor subkey on a multiprocessor
1148 sprintf(buf
,"%d",x
);
1150 if (!lstrncmpiA(line
,"stepping",strlen("stepping"))) {
1153 if (sscanf(value
,"%d",&x
))
1154 cachedsi
.wProcessorRevision
= x
;
1157 ( (!lstrncmpiA(line
,"flags",strlen("flags")))
1158 || (!lstrncmpiA(line
,"features",strlen("features"))) )
1160 if (strstr(value
,"cx8"))
1161 PF
[PF_COMPARE_EXCHANGE_DOUBLE
] = TRUE
;
1162 if (strstr(value
,"mmx"))
1163 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1164 if (strstr(value
,"tsc"))
1165 PF
[PF_RDTSC_INSTRUCTION_AVAILABLE
] = TRUE
;
1166 if (strstr(value
,"xmm") || strstr(value
,"sse"))
1167 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1168 if (strstr(value
,"sse2"))
1169 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1170 if (strstr(value
,"3dnow"))
1171 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1176 #endif /* __linux__ */
1179 memcpy(si
,&cachedsi
,sizeof(*si
));
1183 // avoid undefined expGetSystemInfo
1184 static WIN_BOOL WINAPI
expIsProcessorFeaturePresent(DWORD v
)
1186 WIN_BOOL result
= 0;
1190 expGetSystemInfo(&si
);
1192 if(v
<64) result
=PF
[v
];
1193 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v
, result
);
1197 static WIN_BOOL WINAPI
expIsDebuggerPresent(void)
1202 static long WINAPI
expGetVersion(void)
1204 dbgprintf("GetVersion() => 0xC0000004\n");
1205 return 0xC0000004;//Windows 95
1208 static HANDLE WINAPI
expHeapCreate(long flags
, long init_size
, long max_size
)
1210 // printf("HeapCreate:");
1213 result
=(HANDLE
)my_mreq(0x110000, 0);
1215 result
=(HANDLE
)my_mreq((init_size
+ 0xfff) & 0x7ffff000 , 0);
1216 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags
, init_size
, max_size
, result
);
1220 // this is another dirty hack
1221 // VP31 is releasing one allocated Heap chunk twice
1222 // we will silently ignore this second call...
1223 static void* heapfreehack
= 0;
1224 static int heapfreehackshown
= 0;
1225 //void trapbug(void);
1226 static void* WINAPI
expHeapAlloc(HANDLE heap
, int flags
, int size
)
1230 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1231 HeapAlloc returns area larger than size argument :-/
1233 actually according to M$ Doc HeapCreate size should be rounded
1234 to page boundaries thus we should simulate this
1236 //if (size == 22276) trapbug();
1237 z
=my_mreq((size
+ 0xfff) & 0x7ffff000, (flags
& HEAP_ZERO_MEMORY
));
1239 printf("HeapAlloc failure\n");
1240 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap
, flags
, size
, z
);
1241 heapfreehack
= 0; // reset
1244 static long WINAPI
expHeapDestroy(void* heap
)
1246 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap
);
1251 static long WINAPI
expHeapFree(HANDLE heap
, DWORD dwFlags
, LPVOID lpMem
)
1253 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap
, dwFlags
, lpMem
);
1254 if (heapfreehack
!= lpMem
&& lpMem
!= (void*)0xffffffff
1255 && lpMem
!= (void*)0xbdbdbdbd)
1256 // 0xbdbdbdbd is for i263_drv.drv && libefence
1257 // it seems to be reading from relased memory
1258 // EF_PROTECT_FREE doens't show any probleme
1262 if (!heapfreehackshown
++)
1263 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem
);
1265 heapfreehack
= lpMem
;
1268 static long WINAPI
expHeapSize(int heap
, int flags
, void* pointer
)
1270 long result
=my_size(pointer
);
1271 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap
, flags
, pointer
, result
);
1274 static void* WINAPI
expHeapReAlloc(HANDLE heap
,int flags
,void *lpMem
,int size
)
1276 long orgsize
= my_size(lpMem
);
1277 dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize
,size
);
1278 return my_realloc(lpMem
, size
);
1280 static long WINAPI
expGetProcessHeap(void)
1282 dbgprintf("GetProcessHeap() => 1\n");
1285 static void* WINAPI
expVirtualAlloc(void* v1
, long v2
, long v3
, long v4
)
1287 void* z
= VirtualAlloc(v1
, v2
, v3
, v4
);
1289 printf("VirtualAlloc failure\n");
1290 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1
,v2
,v3
,v4
, z
);
1293 static int WINAPI
expVirtualFree(void* v1
, int v2
, int v3
)
1295 int result
= VirtualFree(v1
,v2
,v3
);
1296 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1
,v2
,v3
, result
);
1300 /* we're building a table of critical sections. cs_win pointer uses the DLL
1301 cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1302 struct critsecs_list_t
1304 CRITICAL_SECTION
*cs_win
;
1305 struct CRITSECT
*cs_unix
;
1308 /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1309 #undef CRITSECS_NEWTYPE
1310 //#define CRITSECS_NEWTYPE 1
1312 #ifdef CRITSECS_NEWTYPE
1313 /* increased due to ucod needs more than 32 entries */
1314 /* and 64 should be enough for everything */
1315 #define CRITSECS_LIST_MAX 64
1316 static struct critsecs_list_t critsecs_list
[CRITSECS_LIST_MAX
];
1318 static int critsecs_get_pos(CRITICAL_SECTION
*cs_win
)
1322 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1323 if (critsecs_list
[i
].cs_win
== cs_win
)
1328 static int critsecs_get_unused(void)
1332 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1333 if (critsecs_list
[i
].cs_win
== NULL
)
1338 struct CRITSECT
*critsecs_get_unix(CRITICAL_SECTION
*cs_win
)
1342 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1343 if (critsecs_list
[i
].cs_win
== cs_win
&& critsecs_list
[i
].cs_unix
)
1344 return critsecs_list
[i
].cs_unix
;
1349 static void WINAPI
expInitializeCriticalSection(CRITICAL_SECTION
* c
)
1351 dbgprintf("InitializeCriticalSection(0x%x)\n", c
);
1352 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1354 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1355 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1358 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1359 #ifdef CRITSECS_NEWTYPE
1361 struct CRITSECT
*cs
;
1362 int i
= critsecs_get_unused();
1366 printf("InitializeCriticalSection(%p) - no more space in list\n", c
);
1369 dbgprintf("got unused space at %d\n", i
);
1370 cs
= malloc(sizeof(struct CRITSECT
));
1373 printf("InitializeCriticalSection(%p) - out of memory\n", c
);
1376 pthread_mutex_init(&cs
->mutex
, NULL
);
1377 pthread_cond_init(&cs
->unlocked
, NULL
);
1379 critsecs_list
[i
].cs_win
= c
;
1380 critsecs_list
[i
].cs_unix
= cs
;
1381 dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1386 struct CRITSECT
* cs
= mreq_private(sizeof(struct CRITSECT
) + sizeof(CRITICAL_SECTION
),
1387 0, AREATYPE_CRITSECT
);
1388 pthread_mutex_init(&cs
->mutex
, NULL
);
1389 pthread_cond_init(&cs
->unlocked
, NULL
);
1391 cs
->deadbeef
= 0xdeadbeef;
1398 static WIN_BOOL WINAPI
expInitializeCriticalSectionAndSpinCount(CRITICAL_SECTION
* c
, DWORD spin
)
1400 expInitializeCriticalSection(c
);
1404 static void WINAPI
expEnterCriticalSection(CRITICAL_SECTION
* c
)
1406 #ifdef CRITSECS_NEWTYPE
1407 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1409 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1411 dbgprintf("EnterCriticalSection(0x%x) %p\n",c
, cs
);
1414 dbgprintf("entered uninitialized critisec!\n");
1415 expInitializeCriticalSection(c
);
1416 #ifdef CRITSECS_NEWTYPE
1417 cs
=critsecs_get_unix(c
);
1419 cs
= (*(struct CRITSECT
**)c
);
1421 dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c
);
1423 pthread_mutex_lock(&(cs
->mutex
));
1424 if (cs
->lock_count
> 0 && cs
->id
== pthread_self()) {
1427 while (cs
->lock_count
!= 0) {
1428 pthread_cond_wait(&(cs
->unlocked
), &(cs
->mutex
));
1431 cs
->id
= pthread_self();
1433 pthread_mutex_unlock(&(cs
->mutex
));
1436 static void WINAPI
expLeaveCriticalSection(CRITICAL_SECTION
* c
)
1438 #ifdef CRITSECS_NEWTYPE
1439 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1441 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1443 // struct CRITSECT* cs=(struct CRITSECT*)c;
1444 dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c
, cs
);
1447 dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c
);
1450 pthread_mutex_lock(&(cs
->mutex
));
1451 if (cs
->lock_count
== 0) {
1452 dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c
);
1456 if (cs
->lock_count
== 0) {
1457 pthread_cond_signal(&(cs
->unlocked
));
1459 pthread_mutex_unlock(&(cs
->mutex
));
1463 static void expfree(void* mem
); /* forward declaration */
1465 static void WINAPI
expDeleteCriticalSection(CRITICAL_SECTION
*c
)
1467 #ifdef CRITSECS_NEWTYPE
1468 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1470 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1472 // struct CRITSECT* cs=(struct CRITSECT*)c;
1473 dbgprintf("DeleteCriticalSection(0x%x)\n",c
);
1477 dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c
);
1481 pthread_mutex_lock(&(cs
->mutex
));
1482 if (cs
->lock_count
> 0)
1484 dbgprintf("Win32 Warning: Deleting locked Critical Section %p!!\n", c
);
1486 pthread_mutex_unlock(&(cs
->mutex
));
1489 pthread_mutex_destroy(&(cs
->mutex
));
1490 pthread_cond_destroy(&(cs
->unlocked
));
1491 // released by GarbageCollector in my_relase otherwise
1494 #ifdef CRITSECS_NEWTYPE
1496 int i
= critsecs_get_pos(c
);
1500 printf("DeleteCriticalSection(%p) error (critsec not found)\n", c
);
1504 critsecs_list
[i
].cs_win
= NULL
;
1505 expfree(critsecs_list
[i
].cs_unix
);
1506 critsecs_list
[i
].cs_unix
= NULL
;
1507 dbgprintf("DeleteCriticalSection -> itemno=%d\n", i
);
1512 static int WINAPI
expGetCurrentThreadId(void)
1514 dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1515 return pthread_self();
1517 static int WINAPI
expGetCurrentProcess(void)
1519 dbgprintf("GetCurrentProcess() => %d\n", getpid());
1523 #ifdef CONFIG_QTX_CODECS
1524 // this version is required for Quicktime codecs (.qtx/.qts) to work.
1525 // (they assume some pointers at FS: segment)
1527 extern void* fs_seg
;
1529 //static int tls_count;
1530 static int tls_use_map
[64];
1531 static int WINAPI
expTlsAlloc(void)
1535 if(tls_use_map
[i
]==0)
1538 dbgprintf("TlsAlloc() => %d\n",i
);
1541 dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1545 //static int WINAPI expTlsSetValue(DWORD index, void* value)
1546 static int WINAPI
expTlsSetValue(int index
, void* value
)
1548 dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index
,value
);
1549 // if((index<0) || (index>64))
1552 *(void**)((char*)fs_seg
+0x88+4*index
) = value
;
1556 static void* WINAPI
expTlsGetValue(DWORD index
)
1558 dbgprintf("TlsGetValue(%d)\n",index
);
1559 // if((index<0) || (index>64))
1560 if((index
>=64)) return NULL
;
1561 return *(void**)((char*)fs_seg
+0x88+4*index
);
1564 static int WINAPI
expTlsFree(int idx
)
1566 int index
= (int) idx
;
1567 dbgprintf("TlsFree(%d)\n",index
);
1568 if((index
<0) || (index
>64))
1570 tls_use_map
[index
]=0;
1582 static void* WINAPI
expTlsAlloc(void)
1586 g_tls
=my_mreq(sizeof(tls_t
), 0);
1587 g_tls
->next
=g_tls
->prev
=NULL
;
1591 g_tls
->next
=my_mreq(sizeof(tls_t
), 0);
1592 g_tls
->next
->prev
=g_tls
;
1593 g_tls
->next
->next
=NULL
;
1596 dbgprintf("TlsAlloc() => 0x%x\n", g_tls
);
1598 g_tls
->value
=0; /* XXX For Divx.dll */
1602 static int WINAPI
expTlsSetValue(void* idx
, void* value
)
1604 tls_t
* index
= (tls_t
*) idx
;
1613 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index
, value
, result
);
1616 static void* WINAPI
expTlsGetValue(void* idx
)
1618 tls_t
* index
= (tls_t
*) idx
;
1623 result
=index
->value
;
1624 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index
, result
);
1627 static int WINAPI
expTlsFree(void* idx
)
1629 tls_t
* index
= (tls_t
*) idx
;
1636 index
->next
->prev
=index
->prev
;
1638 index
->prev
->next
=index
->next
;
1640 g_tls
= index
->prev
;
1641 my_release((void*)index
);
1644 dbgprintf("TlsFree(index 0x%x) => %d\n", index
, result
);
1649 static void* WINAPI
expLocalAlloc(int flags
, int size
)
1651 void* z
= my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1653 printf("LocalAlloc() failed\n");
1654 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1658 static void* WINAPI
expLocalReAlloc(int handle
,int size
, int flags
)
1664 if (flags
& LMEM_MODIFY
) {
1665 dbgprintf("LocalReAlloc MODIFY\n");
1666 return (void *)handle
;
1668 oldsize
= my_size((void *)handle
);
1669 newpointer
= my_realloc((void *)handle
,size
);
1670 dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle
,size
,oldsize
, flags
,newpointer
);
1675 static void* WINAPI
expLocalLock(void* z
)
1677 dbgprintf("LocalLock(0x%x) => 0x%x\n", z
, z
);
1681 static void* WINAPI
expGlobalAlloc(int flags
, int size
)
1684 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size
, flags
);
1686 z
=my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1687 //z=calloc(size, 1);
1690 printf("GlobalAlloc() failed\n");
1691 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1694 static void* WINAPI
expGlobalLock(void* z
)
1696 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z
, z
);
1699 // pvmjpg20 - but doesn't work anyway
1700 static int WINAPI
expGlobalSize(void* amem
)
1704 alloc_header
* header
= last_alloc
;
1705 alloc_header
* mem
= (alloc_header
*) amem
- 1;
1708 pthread_mutex_lock(&memmut
);
1711 if (header
->deadbeef
!= 0xdeadbeef)
1713 dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
1719 size
= header
->size
;
1723 header
= header
->prev
;
1725 pthread_mutex_unlock(&memmut
);
1728 dbgprintf("GlobalSize(0x%x)\n", amem
);
1732 static int WINAPI
expLoadIconA( long hinstance
, char *name
)
1734 dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance
,name
);
1738 static int WINAPI
expLoadStringA(long instance
, long id
, void* buf
, long size
)
1740 int result
=LoadStringA(instance
, id
, buf
, size
);
1742 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1743 instance
, id
, buf
, size
, result
, buf
);
1745 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1746 // instance, id, buf, size, result);
1750 static long WINAPI
expMultiByteToWideChar(long v1
, long v2
, char* s1
, long siz1
, short* s2
, int siz2
)
1759 if(siz1
>siz2
/2)siz1
=siz2
/2;
1760 for(i
=1; i
<=siz1
; i
++)
1770 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1771 "size %d, dest buffer 0x%x, dest size %d) => %d\n",
1772 v1
, v2
, s1
, s1
, siz1
, s2
, siz2
, result
);
1774 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1775 "size %d, dest buffer 0x%x, dest size %d) =>\n",
1776 v1
, v2
, siz1
, s2
, siz2
, result
);
1779 static void wch_print(const short* str
)
1781 dbgprintf(" src: ");
1782 while(*str
)dbgprintf("%c", *str
++);
1785 static long WINAPI
expWideCharToMultiByte(long v1
, long v2
, short* s1
, long siz1
,
1786 char* s2
, int siz2
, char* c3
, int* siz3
)
1789 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1790 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1791 result
=WideCharToMultiByte(v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1792 dbgprintf("=> %d\n", result
);
1793 //if(s1)wch_print(s1);
1794 if(s2
)dbgprintf(" dest: %s\n", s2
);
1798 static long WINAPI
expGetVersionExA(OSVERSIONINFOA
* c
)
1800 dbgprintf("GetVersionExA(0x%x) => 1\n", c
);
1801 c
->dwOSVersionInfoSize
=sizeof(*c
);
1802 c
->dwMajorVersion
=5;
1803 c
->dwMinorVersion
=1;
1804 c
->dwBuildNumber
=0x5010a28;
1805 c
->dwPlatformId
=VER_PLATFORM_WIN32_NT
;
1806 strcpy(c
->szCSDVersion
, "Service Pack 2");
1807 dbgprintf(" Major version: 5\n Minor version: 1\n Build number: 0x5010a28\n"
1808 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 2'\n");
1812 static long WINAPI
expGetVersionExW(OSVERSIONINFOW
* c
)
1814 char CSDVersion
[128];
1815 dbgprintf("GetVersionExW(0x%x) => 1\n", c
);
1816 c
->dwOSVersionInfoSize
=sizeof(*c
);
1817 c
->dwMajorVersion
=5;
1818 c
->dwMinorVersion
=1;
1819 c
->dwBuildNumber
=0x5010a28;
1820 c
->dwPlatformId
=VER_PLATFORM_WIN32_NT
;
1821 strcpy(CSDVersion
, "Service Pack 2");
1822 MultiByteToWideChar(65001, 0x0, CSDVersion
, -1, c
->szCSDVersion
, 128);
1823 dbgprintf(" Major version: 5\n Minor version: 1\n Build number: 0x5010a28\n"
1824 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 2'\n");
1828 static HANDLE WINAPI
expCreateSemaphoreA(char* v1
, long init_count
,
1829 long max_count
, char* name
)
1831 pthread_mutex_t
*pm
;
1836 printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1840 printf("%p => ", pp);
1845 pthread_mutex_lock(&mlist_lock
);
1848 mutex_list
* pp
=mlist
;
1852 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==1))
1854 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1855 v1
, init_count
, max_count
, name
, name
, mlist
);
1856 ret
= (HANDLE
)mlist
;
1857 pthread_mutex_unlock(&mlist_lock
);
1860 }while((pp
=pp
->prev
) != NULL
);
1862 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
1863 pthread_mutex_init(pm
, NULL
);
1864 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
1865 pthread_cond_init(pc
, NULL
);
1868 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1869 mlist
->next
=mlist
->prev
=NULL
;
1873 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1874 mlist
->next
->prev
=mlist
;
1875 mlist
->next
->next
=NULL
;
1877 // printf("new semaphore %p\n", mlist);
1879 mlist
->type
=1; /* Type Semaphore */
1884 mlist
->semaphore
=init_count
;
1886 strncpy(mlist
->name
, name
, 64);
1890 dbgprintf("ERROR::: CreateSemaphoreA failure\n");
1892 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1893 v1
, init_count
, max_count
, name
, name
, mlist
);
1895 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1896 v1
, init_count
, max_count
, mlist
);
1897 ret
= (HANDLE
)mlist
;
1898 pthread_mutex_unlock(&mlist_lock
);
1902 static HANDLE WINAPI
expCreateSemaphoreW(char* v1
, long init_count
,
1903 long max_count
, const WCHAR
* name
)
1905 char ascii_name
[256];
1908 WideCharToMultiByte(65001, 0x0, name
, -1, ascii_name
, 256, NULL
, NULL
);
1911 return expCreateSemaphoreA(v1
, init_count
, max_count
, aname
);
1914 static long WINAPI
expReleaseSemaphore(long hsem
, long increment
, long* prev_count
)
1916 // The state of a semaphore object is signaled when its count
1917 // is greater than zero and nonsignaled when its count is equal to zero
1918 // Each time a waiting thread is released because of the semaphore's signaled
1919 // state, the count of the semaphore is decreased by one.
1920 mutex_list
*ml
= (mutex_list
*)hsem
;
1922 pthread_mutex_lock(ml
->pm
);
1923 if (prev_count
!= 0) *prev_count
= ml
->semaphore
;
1924 if (ml
->semaphore
== 0) pthread_cond_signal(ml
->pc
);
1925 ml
->semaphore
+= increment
;
1926 pthread_mutex_unlock(ml
->pm
);
1927 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1928 hsem
, increment
, prev_count
);
1932 static HANDLE WINAPI
expCreateMutexA(void *pSecAttr
,
1933 char bInitialOwner
, const char *name
)
1935 pthread_mutex_t
*pm
;
1938 pthread_mutex_lock(&mlist_lock
);
1941 mutex_list
* pp
=mlist
;
1945 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==2))
1947 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n", pSecAttr
, bInitialOwner
, name
, mlist
);
1948 ret
= (HANDLE
)mlist
;
1949 pthread_mutex_unlock(&mlist_lock
);
1952 }while((pp
=pp
->prev
) != NULL
);
1954 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
1955 pthread_mutex_init(pm
, NULL
);
1956 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
1957 pthread_cond_init(pc
, NULL
);
1960 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1961 mlist
->next
=mlist
->prev
=NULL
;
1965 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1966 mlist
->next
->prev
=mlist
;
1967 mlist
->next
->next
=NULL
;
1970 mlist
->type
=2; /* Type Mutex */
1976 if (bInitialOwner
) {
1977 mlist
->owner
= pthread_self();
1978 mlist
->lock_count
= 1;
1980 mlist
->owner
= (pthread_t
)0;
1981 mlist
->lock_count
= 0;
1984 strncpy(mlist
->name
, name
, 64);
1988 dbgprintf("ERROR::: CreateMutexA failure\n");
1990 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
1991 pSecAttr
, bInitialOwner
, name
, mlist
);
1993 dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
1994 pSecAttr
, bInitialOwner
, mlist
);
1995 ret
= (HANDLE
)mlist
;
1996 pthread_mutex_unlock(&mlist_lock
);
2000 static HANDLE WINAPI
expCreateMutexW(void *pSecAttr
, char bInitialOwner
, const WCHAR
*name
)
2002 char ascii_name
[256];
2005 WideCharToMultiByte(65001, 0x0, name
, -1, ascii_name
, 256, NULL
, NULL
);
2008 return expCreateMutexA(pSecAttr
, bInitialOwner
, aname
);
2011 static int WINAPI
expReleaseMutex(HANDLE hMutex
)
2013 mutex_list
*ml
= (mutex_list
*)hMutex
;
2015 pthread_mutex_lock(ml
->pm
);
2016 if (--ml
->lock_count
== 0) pthread_cond_signal(ml
->pc
);
2017 pthread_mutex_unlock(ml
->pm
);
2021 static DWORD WINAPI
expSignalObjectAndWait(HANDLE hObjectToSignal
,
2022 HANDLE hObjectToWaitOn
,
2023 DWORD dwMilliseconds
,
2024 WIN_BOOL bAlertable
) {
2025 mutex_list
* mlist
= (mutex_list
*)hObjectToSignal
;
2027 switch (mlist
->type
) {
2031 case 1: // Semaphore
2032 expReleaseSemaphore(mlist
, 1, NULL
);
2035 expReleaseMutex(mlist
);
2038 dbgprintf("Signalling unknown object type %d!\n", hObjectToSignal
);
2040 return expWaitForSingleObject(hObjectToWaitOn
, dwMilliseconds
);
2043 static long WINAPI
expRegOpenKeyExA(long key
, const char* subkey
, long reserved
, long access
, int* newkey
)
2045 long result
=RegOpenKeyExA(key
, subkey
, reserved
, access
, newkey
);
2046 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
2047 key
, subkey
, reserved
, access
, newkey
, result
);
2048 if(newkey
)dbgprintf(" New key: 0x%x\n", *newkey
);
2051 static long WINAPI
expRegCloseKey(long key
)
2053 long result
=RegCloseKey(key
);
2054 dbgprintf("RegCloseKey(0x%x) => %d\n", key
, result
);
2057 static long WINAPI
expRegQueryValueExA(long key
, const char* value
, int* reserved
, int* type
, int* data
, int* count
)
2059 long result
=RegQueryValueExA(key
, value
, reserved
, type
, data
, count
);
2060 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
2061 " => 0x%x\n", key
, value
, reserved
, data
, count
, result
);
2062 if(data
&& count
)dbgprintf(" read %d bytes: '%s'\n", *count
, data
);
2066 //from wine source dlls/advapi32/registry.c
2067 static long WINAPI
expRegCreateKeyA(long hkey
, const char* name
, int *retkey
)
2069 dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey
,name
,retkey
);
2070 return RegCreateKeyExA( hkey
, name
, 0, NULL
,REG_OPTION_NON_VOLATILE
,
2071 KEY_ALL_ACCESS
, NULL
, retkey
, NULL
);
2074 static long WINAPI
expRegCreateKeyExA(long key
, const char* name
, long reserved
,
2075 void* classs
, long options
, long security
,
2076 void* sec_attr
, int* newkey
, int* status
)
2078 long result
=RegCreateKeyExA(key
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
);
2079 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
2080 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
2081 key
, name
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
, result
);
2082 if(!result
&& newkey
) dbgprintf(" New key: 0x%x\n", *newkey
);
2083 if(!result
&& status
) dbgprintf(" New key status: 0x%x\n", *status
);
2086 static long WINAPI
expRegSetValueExA(long key
, const char* name
, long v1
, long v2
, void* data
, long size
)
2088 long result
=RegSetValueExA(key
, name
, v1
, v2
, data
, size
);
2089 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
2090 key
, name
, v1
, v2
, data
, *(int*)data
, data
, size
, result
);
2094 static long WINAPI
expRegOpenKeyA (long hKey
, LPCSTR lpSubKey
, int* phkResult
)
2096 long result
=RegOpenKeyExA(hKey
, lpSubKey
, 0, 0, phkResult
);
2097 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
2098 hKey
, lpSubKey
, phkResult
, result
);
2099 if(!result
&& phkResult
) dbgprintf(" New key: 0x%x\n", *phkResult
);
2103 static DWORD WINAPI
expRegEnumValueA(HKEY hkey
, DWORD index
, LPSTR value
, LPDWORD val_count
,
2104 LPDWORD reserved
, LPDWORD type
, LPBYTE data
, LPDWORD count
)
2106 return RegEnumValueA(hkey
, index
, value
, val_count
,
2107 reserved
, type
, data
, count
);
2110 static DWORD WINAPI
expRegEnumKeyExA(HKEY hKey
, DWORD dwIndex
, LPSTR lpName
, LPDWORD lpcbName
,
2111 LPDWORD lpReserved
, LPSTR lpClass
, LPDWORD lpcbClass
,
2112 LPFILETIME lpftLastWriteTime
)
2114 return RegEnumKeyExA(hKey
, dwIndex
, lpName
, lpcbName
, lpReserved
, lpClass
,
2115 lpcbClass
, lpftLastWriteTime
);
2118 static long WINAPI
expQueryPerformanceCounter(long long* z
)
2121 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z
, *z
);
2126 * dummy function RegQueryInfoKeyA(), required by vss codecs
2128 static DWORD WINAPI
expRegQueryInfoKeyA( HKEY hkey
, LPSTR
class, LPDWORD class_len
, LPDWORD reserved
,
2129 LPDWORD subkeys
, LPDWORD max_subkey
, LPDWORD max_class
,
2130 LPDWORD values
, LPDWORD max_value
, LPDWORD max_data
,
2131 LPDWORD security
, FILETIME
*modif
)
2133 return ERROR_SUCCESS
;
2137 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
2139 static double linux_cpuinfo_freq(void)
2146 f
= fopen ("/proc/cpuinfo", "r");
2148 while (fgets(line
,sizeof(line
),f
)!=NULL
) {
2149 /* NOTE: the ':' is the only character we can rely on */
2150 if (!(value
= strchr(line
,':')))
2152 /* terminate the valuename */
2154 /* skip any leading spaces */
2155 while (*value
==' ') value
++;
2156 if ((s
=strchr(value
,'\n')))
2159 if (!strncasecmp(line
, "cpu MHz",strlen("cpu MHz"))
2160 && sscanf(value
, "%lf", &freq
) == 1) {
2171 static double solaris_kstat_freq(void)
2173 #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
2175 * try to extract the CPU speed from the solaris kernel's kstat data
2179 kstat_named_t
*kdata
;
2185 ksp
= kstat_lookup(kc
, "cpu_info", 0, "cpu_info0");
2187 /* kstat found and name/value pairs? */
2188 if (ksp
!= NULL
&& ksp
->ks_type
== KSTAT_TYPE_NAMED
)
2190 /* read the kstat data from the kernel */
2191 if (kstat_read(kc
, ksp
, NULL
) != -1)
2194 * lookup desired "clock_MHz" entry, check the expected
2197 kdata
= (kstat_named_t
*)kstat_data_lookup(ksp
, "clock_MHz");
2198 if (kdata
!= NULL
&& kdata
->data_type
== KSTAT_DATA_INT32
)
2199 mhz
= kdata
->value
.i32
;
2207 #endif /* HAVE_LIBKSTAT */
2208 return -1; // kstat stuff is not available, CPU freq is unknown
2212 * Measure CPU freq using the pentium's time stamp counter register (TSC)
2214 static double tsc_freq(void)
2216 static double ofreq
=0.0;
2220 if (ofreq
!= 0.0) return ofreq
;
2221 while(i
==time(NULL
));
2224 while(i
==time(NULL
));
2226 ofreq
= (double)(y
-x
)/1000.;
2230 static double CPU_Freq(void)
2234 if ((freq
= linux_cpuinfo_freq()) > 0)
2237 if ((freq
= solaris_kstat_freq()) > 0)
2243 static long WINAPI
expQueryPerformanceFrequency(long long* z
)
2245 *z
=(long long)CPU_Freq();
2246 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z
, *z
);
2249 static long WINAPI
exptimeGetTime(void)
2253 gettimeofday(&t
, 0);
2254 result
=1000*t
.tv_sec
+t
.tv_usec
/1000;
2255 dbgprintf("timeGetTime() => %d\n", result
);
2258 static void* WINAPI
expLocalHandle(void* v
)
2260 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v
, v
);
2264 static void* WINAPI
expGlobalHandle(void* v
)
2266 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v
, v
);
2269 static int WINAPI
expGlobalUnlock(void* v
)
2271 dbgprintf("GlobalUnlock(0x%x) => 1\n", v
);
2274 static void* WINAPI
expGlobalFree(void* v
)
2276 dbgprintf("GlobalFree(0x%x) => 0\n", v
);
2282 static void* WINAPI
expGlobalReAlloc(void* v
, int size
, int flags
)
2284 void* result
=my_realloc(v
, size
);
2285 //void* result=realloc(v, size);
2286 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v
,size
,flags
,result
);
2290 static int WINAPI
expLocalUnlock(void* v
)
2292 dbgprintf("LocalUnlock(0x%x) => 1\n", v
);
2296 static void* WINAPI
expLocalFree(void* v
)
2298 dbgprintf("LocalFree(0x%x) => 0\n", v
);
2302 static HRSRC WINAPI
expFindResourceA(HMODULE module
, char* name
, char* type
)
2306 result
=FindResourceA(module
, name
, type
);
2307 dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2308 module
, name
, HIWORD(name
) ? name
: "UNICODE", type
, HIWORD(type
) ? type
: "UNICODE", result
);
2312 static HGLOBAL WINAPI
expLoadResource(HMODULE module
, HRSRC res
)
2314 HGLOBAL result
=LoadResource(module
, res
);
2315 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module
, res
, result
);
2318 static void* WINAPI
expLockResource(long res
)
2320 void* result
=LockResource(res
);
2321 dbgprintf("LockResource(0x%x) => 0x%x\n", res
, result
);
2324 static int WINAPI
expFreeResource(long res
)
2326 int result
=FreeResource(res
);
2327 dbgprintf("FreeResource(0x%x) => %d\n", res
, result
);
2332 static int WINAPI
expCloseHandle(long v1
)
2334 dbgprintf("CloseHandle(0x%x) => 1\n", v1
);
2335 /* do not close stdin,stdout and stderr */
2342 static const char* WINAPI
expGetCommandLineA(void)
2344 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2345 return "c:\\aviplay.exe";
2347 static short envs
[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2348 static LPWSTR WINAPI
expGetEnvironmentStringsW(void)
2350 dbgprintf("GetEnvironmentStringsW() => 0\n", envs
);
2353 static void * WINAPI
expRtlZeroMemory(void *p
, size_t len
)
2355 void* result
=memset(p
,0,len
);
2356 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p
,len
,result
);
2359 static void * WINAPI
expRtlMoveMemory(void *dst
, void *src
, size_t len
)
2361 void* result
=memmove(dst
,src
,len
);
2362 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst
,src
,len
,result
);
2366 static void * WINAPI
expRtlFillMemory(void *p
, int ch
, size_t len
)
2368 void* result
=memset(p
,ch
,len
);
2369 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p
,ch
,len
,result
);
2372 static int WINAPI
expFreeEnvironmentStringsW(short* strings
)
2374 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings
);
2377 static int WINAPI
expFreeEnvironmentStringsA(char* strings
)
2379 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings
);
2383 static const char ch_envs
[]=
2384 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2385 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2386 static LPCSTR WINAPI
expGetEnvironmentStrings(void)
2388 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs
);
2389 return (LPCSTR
)ch_envs
;
2390 // dbgprintf("GetEnvironmentStrings() => 0\n");
2394 static int WINAPI
expGetStartupInfoA(STARTUPINFOA
*s
)
2396 dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2397 memset(s
, 0, sizeof(*s
));
2399 // s->lpReserved="Reserved";
2400 // s->lpDesktop="Desktop";
2401 // s->lpTitle="Title";
2403 // s->dwXSize=s->dwYSize=200;
2404 s
->dwFlags
=s
->wShowWindow
=1;
2405 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2406 dbgprintf(" cb=%d\n", s
->cb
);
2407 dbgprintf(" lpReserved='%s'\n", s
->lpReserved
);
2408 dbgprintf(" lpDesktop='%s'\n", s
->lpDesktop
);
2409 dbgprintf(" lpTitle='%s'\n", s
->lpTitle
);
2410 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2411 s
->dwX
, s
->dwY
, s
->dwXSize
, s
->dwYSize
);
2412 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2413 s
->dwXCountChars
, s
->dwYCountChars
, s
->dwFillAttribute
);
2414 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2415 s
->dwFlags
, s
->wShowWindow
, s
->cbReserved2
);
2416 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2417 s
->lpReserved2
, s
->hStdInput
, s
->hStdOutput
, s
->hStdError
);
2421 static int WINAPI
expGetStdHandle(int z
)
2423 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z
+0x1234);
2427 #ifdef CONFIG_QTX_CODECS
2428 #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2429 #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2432 static int WINAPI
expGetFileType(int handle
)
2434 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle
);
2437 #ifdef CONFIG_QTX_CODECS
2438 static int WINAPI
expGetFileAttributesA(char *filename
)
2440 dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename
);
2441 if (strstr(filename
, "QuickTime.qts"))
2442 return FILE_ATTRIBUTE_SYSTEM
;
2443 return FILE_ATTRIBUTE_NORMAL
;
2446 static int WINAPI
expSetHandleCount(int count
)
2448 dbgprintf("SetHandleCount(0x%x) => 1\n", count
);
2451 static int WINAPI
expGetACP(void)
2453 dbgprintf("GetACP() => 0\n");
2456 static int WINAPI
expGetModuleFileNameA(int module
, char* s
, int len
)
2460 //printf("File name of module %X (%s) requested\n", module, s);
2462 if (module
== 0 && len
>= 12)
2464 /* return caller program name */
2465 strcpy(s
, "aviplay.dll");
2476 strcpy(s
, "c:\\windows\\system\\");
2477 mr
=MODULE32_LookupHMODULE(module
);
2479 strcat(s
, "aviplay.dll");
2481 if(strrchr(mr
->filename
, '/')==NULL
)
2482 strcat(s
, mr
->filename
);
2484 strcat(s
, strrchr(mr
->filename
, '/')+1);
2487 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2488 module
, s
, len
, result
);
2490 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2491 module
, s
, len
, result
, s
);
2495 static int WINAPI
expGetModuleBaseNameA(int process
, int module
, char* s
, int len
)
2500 av_strlcpy(s
, "aviplay.dll", len
);
2504 dbgprintf("GetModuleBaseNameA(0x%x, 0x%x, 0x%x, %d) => %d\n",
2505 process
, module
, s
, len
, result
);
2510 static int WINAPI
expSetUnhandledExceptionFilter(void* filter
)
2512 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter
);
2513 return 1;//unsupported and probably won't ever be supported
2516 static int WINAPI
expLoadLibraryA(char* name
)
2522 // we skip to the last backslash
2523 // this is effectively eliminating weird characters in
2524 // the text output windows
2526 lastbc
= strrchr(name
, '\\');
2533 name
[i
] = *lastbc
++;
2538 if(strncmp(name
, "c:\\windows\\", 11)==0) name
+= 11;
2539 if(strncmp(name
, ".\\", 2)==0) name
+= 2;
2541 dbgprintf("Entering LoadLibraryA(%s)\n", name
);
2543 // PIMJ and VIVO audio are loading kernel32.dll
2544 if (strcasecmp(name
, "kernel32.dll") == 0 || strcasecmp(name
, "kernel32") == 0)
2545 return MODULE_HANDLE_kernel32
;
2546 // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2547 /* exported -> do not return failed! */
2549 if (strcasecmp(name
, "user32.dll") == 0 || strcasecmp(name
, "user32") == 0)
2550 // return MODULE_HANDLE_kernel32;
2551 return MODULE_HANDLE_user32
;
2553 #ifdef CONFIG_QTX_CODECS
2554 if (strcasecmp(name
, "wininet.dll") == 0 || strcasecmp(name
, "wininet") == 0)
2555 return MODULE_HANDLE_wininet
;
2556 if (strcasecmp(name
, "ddraw.dll") == 0 || strcasecmp(name
, "ddraw") == 0)
2557 return MODULE_HANDLE_ddraw
;
2558 if (strcasecmp(name
, "advapi32.dll") == 0 || strcasecmp(name
, "advapi32") == 0)
2559 return MODULE_HANDLE_advapi32
;
2562 if (strcasecmp(name
, "comdlg32.dll") == 0 || strcasecmp(name
, "comdlg32") == 0)
2563 return MODULE_HANDLE_comdlg32
;
2564 if (strcasecmp(name
, "msvcrt.dll") == 0 || strcasecmp(name
, "msvcrt") == 0)
2565 return MODULE_HANDLE_msvcrt
;
2566 if (strcasecmp(name
, "ole32.dll") == 0 || strcasecmp(name
, "ole32") == 0)
2567 return MODULE_HANDLE_ole32
;
2568 if (strcasecmp(name
, "winmm.dll") == 0 || strcasecmp(name
, "winmm") == 0)
2569 return MODULE_HANDLE_winmm
;
2570 if (strcasecmp(name
, "psapi.dll") == 0 || strcasecmp(name
, "psapi") == 0)
2571 return MODULE_HANDLE_psapi
;
2573 result
=LoadLibraryA(name
);
2574 dbgprintf("Returned LoadLibraryA(0x%x='%s'), codec_path=%s => 0x%x\n",
2575 name
, name
, codec_path
, result
);
2580 static int WINAPI
expFreeLibrary(int module
)
2582 #ifdef CONFIG_QTX_CODECS
2583 int result
=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2585 int result
=FreeLibrary(module
);
2587 dbgprintf("FreeLibrary(0x%x) => %d\n", module
, result
);
2591 static void* WINAPI
expGetProcAddress(HMODULE mod
, char* name
)
2595 case MODULE_HANDLE_kernel32
:
2596 result
=LookupExternalByName("kernel32.dll", name
); break;
2597 case MODULE_HANDLE_user32
:
2598 result
=LookupExternalByName("user32.dll", name
); break;
2599 #ifdef CONFIG_QTX_CODECS
2600 case MODULE_HANDLE_wininet
:
2601 result
=LookupExternalByName("wininet.dll", name
); break;
2602 case MODULE_HANDLE_ddraw
:
2603 result
=LookupExternalByName("ddraw.dll", name
); break;
2604 case MODULE_HANDLE_advapi32
:
2605 result
=LookupExternalByName("advapi32.dll", name
); break;
2607 case MODULE_HANDLE_comdlg32
:
2608 result
=LookupExternalByName("comdlg32.dll", name
); break;
2609 case MODULE_HANDLE_msvcrt
:
2610 result
=LookupExternalByName("msvcrt.dll", name
); break;
2611 case MODULE_HANDLE_ole32
:
2612 result
=LookupExternalByName("ole32.dll", name
); break;
2613 case MODULE_HANDLE_winmm
:
2614 result
=LookupExternalByName("winmm.dll", name
); break;
2615 case MODULE_HANDLE_psapi
:
2616 result
=LookupExternalByName("psapi.dll", name
); break;
2618 result
=GetProcAddress(mod
, name
);
2620 if((unsigned int)name
> 0xffff)
2621 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod
, name
, result
);
2623 dbgprintf("GetProcAddress(0x%x, '%d') => 0x%x\n", mod
, (int)name
, result
);
2627 static long WINAPI
expCreateFileMappingA(int hFile
, void* lpAttr
,
2628 long flProtect
, long dwMaxHigh
,
2629 long dwMaxLow
, const char* name
)
2631 long result
=CreateFileMappingA(hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
);
2633 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2634 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2635 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, result
);
2637 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2638 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2639 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
, name
, result
);
2643 static long WINAPI
expOpenFileMappingA(long hFile
, long hz
, const char* name
)
2645 long result
=OpenFileMappingA(hFile
, hz
, name
);
2647 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2650 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2651 hFile
, hz
, name
, name
, result
);
2655 static void* WINAPI
expMapViewOfFile(HANDLE file
, DWORD mode
, DWORD offHigh
,
2656 DWORD offLow
, DWORD size
)
2658 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2659 file
,mode
,offHigh
,offLow
,size
,(char*)file
+offLow
);
2660 return (char*)file
+offLow
;
2663 static void* WINAPI
expUnmapViewOfFile(void* view
)
2665 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view
);
2669 static void* WINAPI
expSleep(int time
)
2672 /* solaris doesn't have thread safe usleep */
2673 struct timespec tsp
;
2674 tsp
.tv_sec
= time
/ 1000000;
2675 tsp
.tv_nsec
= (time
% 1000000) * 1000;
2676 nanosleep(&tsp
, NULL
);
2680 dbgprintf("Sleep(%d) => 0\n", time
);
2684 // why does IV32 codec want to call this? I don't know ...
2685 static int WINAPI
expCreateCompatibleDC(int hdc
)
2688 //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2689 dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc
, dc
);
2693 static int WINAPI
expGetDeviceCaps(int hdc
, int unk
)
2695 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc
, unk
);
2696 #ifdef CONFIG_QTX_CODECS
2697 #define BITSPIXEL 12
2699 if (unk
== BITSPIXEL
)
2707 static WIN_BOOL WINAPI
expDeleteDC(int hdc
)
2709 dbgprintf("DeleteDC(0x%x) => 0\n", hdc
);
2715 static WIN_BOOL WINAPI
expDeleteObject(int hdc
)
2717 dbgprintf("DeleteObject(0x%x) => 1\n", hdc
);
2718 /* FIXME - implement code here */
2722 /* btvvc32.drv wants this one */
2723 static void* WINAPI
expGetWindowDC(int hdc
)
2725 dbgprintf("GetWindowDC(%d) => 0x0\n", hdc
);
2729 #ifdef CONFIG_QTX_CODECS
2730 static int WINAPI
expGetWindowRect(HWND win
, RECT
*r
)
2732 dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win
, r
);
2733 /* (win == 0) => desktop */
2734 r
->right
= PSEUDO_SCREEN_WIDTH
;
2736 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
2741 static int WINAPI
expMonitorFromWindow(HWND win
, int flags
)
2743 dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win
, flags
);
2747 static int WINAPI
expMonitorFromRect(RECT
*r
, int flags
)
2749 dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r
, flags
);
2753 static int WINAPI
expMonitorFromPoint(void *p
, int flags
)
2755 dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p
, flags
);
2759 static int WINAPI
expEnumDisplayMonitors(void *dc
, RECT
*r
,
2760 int WINAPI (*callback_proc
)(), void *callback_param
)
2762 dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2763 dc
, r
, callback_proc
, callback_param
);
2764 return callback_proc(0, dc
, r
, callback_param
);
2768 typedef struct tagMONITORINFO
{
2773 } MONITORINFO
, *LPMONITORINFO
;
2776 #define CCHDEVICENAME 8
2777 typedef struct tagMONITORINFOEX
{
2782 TCHAR szDevice
[CCHDEVICENAME
];
2783 } MONITORINFOEX
, *LPMONITORINFOEX
;
2785 static int WINAPI
expGetMonitorInfoA(void *mon
, LPMONITORINFO lpmi
)
2787 dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon
, lpmi
);
2789 lpmi
->rcMonitor
.right
= lpmi
->rcWork
.right
= PSEUDO_SCREEN_WIDTH
;
2790 lpmi
->rcMonitor
.left
= lpmi
->rcWork
.left
= 0;
2791 lpmi
->rcMonitor
.bottom
= lpmi
->rcWork
.bottom
= PSEUDO_SCREEN_HEIGHT
;
2792 lpmi
->rcMonitor
.top
= lpmi
->rcWork
.top
= 0;
2794 lpmi
->dwFlags
= 1; /* primary monitor */
2796 if (lpmi
->cbSize
== sizeof(MONITORINFOEX
))
2798 LPMONITORINFOEX lpmiex
= (LPMONITORINFOEX
)lpmi
;
2799 dbgprintf("MONITORINFOEX!\n");
2800 strncpy(lpmiex
->szDevice
, "Monitor1", CCHDEVICENAME
);
2806 static int WINAPI
expEnumDisplayDevicesA(const char *device
, int devnum
,
2807 void *dispdev
, int flags
)
2809 dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2810 device
, device
, devnum
, dispdev
, flags
);
2814 static int WINAPI
expIsWindowVisible(HWND win
)
2816 dbgprintf("IsWindowVisible(0x%x) => 1\n", win
);
2820 static HWND WINAPI
expGetActiveWindow(void)
2822 dbgprintf("GetActiveWindow() => 0\n");
2826 static int WINAPI
expGetClassNameA(HWND win
, LPTSTR classname
, int maxcount
)
2828 strncat(classname
, "QuickTime", maxcount
);
2829 dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2830 win
, classname
, maxcount
, strlen(classname
));
2831 return strlen(classname
);
2834 #define LPWNDCLASS void *
2835 static int WINAPI
expGetClassInfoA(HINSTANCE inst
, LPCSTR classname
, LPWNDCLASS wndclass
)
2837 dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst
,
2838 classname
, classname
, wndclass
);
2842 static int WINAPI
expGetWindowLongA(HWND win
, int index
)
2844 dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win
, index
);
2848 static int WINAPI
expGetObjectA(HGDIOBJ hobj
, int objsize
, LPVOID obj
)
2850 dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj
, objsize
, obj
, objsize
);
2854 static int WINAPI
expCreateRectRgn(int x
, int y
, int width
, int height
)
2856 dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x
, y
, width
, height
);
2860 static int WINAPI
expEnumWindows(int (*callback_func
)(), void *callback_param
)
2863 dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func
, callback_param
);
2864 i
= callback_func(0, callback_param
);
2865 i2
= callback_func(1, callback_param
);
2869 static int WINAPI
expGetWindowThreadProcessId(HWND win
, int *pid_data
)
2871 int tid
= pthread_self();
2872 dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2873 win
, pid_data
, tid
);
2875 *(int*)pid_data
= tid
;
2879 //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2880 // INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2882 static HWND WINAPI
expCreateWindowExA(int exstyle
, const char *classname
,
2883 const char *winname
, int style
, int x
, int y
, int w
, int h
,
2884 HWND parent
, HMENU menu
, HINSTANCE inst
, LPVOID param
)
2886 printf("CreateWindowEx() called\n");
2887 dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2888 exstyle
, classname
, classname
, winname
, winname
, style
, x
, y
, w
, h
,
2889 parent
, menu
, inst
, param
);
2890 printf("CreateWindowEx() called okey\n");
2894 static int WINAPI
expwaveOutGetNumDevs(void)
2896 dbgprintf("waveOutGetNumDevs() => 0\n");
2902 * Returns the number of milliseconds, modulo 2^32, since the start
2903 * of the wineserver.
2905 static int WINAPI
expGetTickCount(void)
2907 static int tcstart
= 0;
2910 gettimeofday( &t
, NULL
);
2911 tc
= ((t
.tv_sec
* 1000) + (t
.tv_usec
/ 1000)) - tcstart
;
2917 dbgprintf("GetTickCount() => %d\n", tc
);
2921 static int WINAPI
expCreateFontA(void)
2923 dbgprintf("CreateFontA() => 0x0\n");
2927 /* tried to get pvmjpg work in a different way - no success */
2928 static int WINAPI
expDrawTextA(int hDC
, char* lpString
, int nCount
,
2929 LPRECT lpRect
, unsigned int uFormat
)
2931 dbgprintf("expDrawTextA(%p,...) => 8\n", hDC
);
2935 static int WINAPI
expGetPrivateProfileIntA(const char* appname
,
2936 const char* keyname
,
2938 const char* filename
)
2946 if(!(appname
&& keyname
&& filename
) )
2948 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, default_value
);
2949 return default_value
;
2951 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2952 strcpy(fullname
, "Software\\IniFileMapping\\");
2953 strcat(fullname
, appname
);
2954 strcat(fullname
, "\\");
2955 strcat(fullname
, keyname
);
2956 strcat(fullname
, "\\");
2957 strcat(fullname
, filename
);
2958 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)buffer
, &size
);
2959 if((size
>=0)&&(size
<256))
2961 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2964 result
=default_value
;
2966 result
=atoi(buffer
);
2967 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, result
);
2970 static int WINAPI
expGetProfileIntA(const char* appname
,
2971 const char* keyname
,
2974 dbgprintf("GetProfileIntA -> ");
2975 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, "default");
2978 static int WINAPI
expGetPrivateProfileStringA(const char* appname
,
2979 const char* keyname
,
2980 const char* def_val
,
2981 char* dest
, unsigned int len
,
2982 const char* filename
)
2987 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname
, keyname
, def_val
, dest
, len
, filename
);
2988 if(!(appname
&& keyname
&& filename
) ) return 0;
2989 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2990 strcpy(fullname
, "Software\\IniFileMapping\\");
2991 strcat(fullname
, appname
);
2992 strcat(fullname
, "\\");
2993 strcat(fullname
, keyname
);
2994 strcat(fullname
, "\\");
2995 strcat(fullname
, filename
);
2997 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)dest
, &size
);
3001 strncpy(dest
, def_val
, size
);
3002 if (strlen(def_val
)< size
) size
= strlen(def_val
);
3004 dbgprintf(" => %d ( '%s' )\n", size
, dest
);
3007 static int WINAPI
expWritePrivateProfileStringA(const char* appname
,
3008 const char* keyname
,
3010 const char* filename
)
3013 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname
, keyname
, string
, filename
);
3014 if(!(appname
&& keyname
&& filename
) )
3016 dbgprintf(" => -1\n");
3019 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
3020 strcpy(fullname
, "Software\\IniFileMapping\\");
3021 strcat(fullname
, appname
);
3022 strcat(fullname
, "\\");
3023 strcat(fullname
, keyname
);
3024 strcat(fullname
, "\\");
3025 strcat(fullname
, filename
);
3026 RegSetValueExA(HKEY_LOCAL_MACHINE
, fullname
, 0, REG_SZ
, (int*)string
, strlen(string
));
3027 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
3028 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
3030 dbgprintf(" => 0\n");
3034 unsigned int GetPrivateProfileIntA_(const char* appname
, const char* keyname
, INT default_value
, const char* filename
)
3036 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, filename
);
3038 int GetPrivateProfileStringA_(const char* appname
, const char* keyname
,
3039 const char* def_val
, char* dest
, unsigned int len
, const char* filename
)
3041 return expGetPrivateProfileStringA(appname
, keyname
, def_val
, dest
, len
, filename
);
3043 int WritePrivateProfileStringA_(const char* appname
, const char* keyname
,
3044 const char* string
, const char* filename
)
3046 return expWritePrivateProfileStringA(appname
, keyname
, string
, filename
);
3051 static int WINAPI
expDefDriverProc(int private, int id
, int msg
, int arg1
, int arg2
)
3053 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", private, id
, msg
, arg1
, arg2
);
3057 static int WINAPI
expSizeofResource(int v1
, int v2
)
3059 int result
=SizeofResource(v1
, v2
);
3060 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1
, v2
, result
);
3064 static int WINAPI
expGetLastError(void)
3066 int result
=GetLastError();
3067 dbgprintf("GetLastError() => 0x%x\n", result
);
3071 static void WINAPI
expSetLastError(int error
)
3073 dbgprintf("SetLastError(0x%x)\n", error
);
3074 SetLastError(error
);
3077 static int WINAPI
expStringFromGUID2(GUID
* guid
, char* str
, int cbMax
)
3079 int result
=snprintf(str
, cbMax
, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
3080 guid
->f1
, guid
->f2
, guid
->f3
,
3081 (unsigned char)guid
->f4
[0], (unsigned char)guid
->f4
[1],
3082 (unsigned char)guid
->f4
[2], (unsigned char)guid
->f4
[3],
3083 (unsigned char)guid
->f4
[4], (unsigned char)guid
->f4
[5],
3084 (unsigned char)guid
->f4
[6], (unsigned char)guid
->f4
[7]);
3085 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid
, str
, str
, cbMax
, result
);
3090 static int WINAPI
expGetFileVersionInfoSizeA(const char* name
, int* lpHandle
)
3092 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name
, name
, lpHandle
);
3096 static int WINAPI
expIsBadStringPtrW(const short* string
, int nchars
)
3099 if(string
==0)result
=1; else result
=0;
3100 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string
, nchars
, result
);
3101 if(string
)wch_print(string
);
3104 static int WINAPI
expIsBadStringPtrA(const char* string
, int nchars
)
3106 return expIsBadStringPtrW((const short*)string
, nchars
);
3108 static long WINAPI
expInterlockedExchangeAdd( long* dest
, long incr
)
3113 "lock; xaddl %0,(%1)"
3115 : "r" (dest
), "0" (incr
)
3121 static long WINAPI
expInterlockedCompareExchange( unsigned long* dest
, unsigned long exchange
, unsigned long comperand
)
3123 unsigned long retval
= *dest
;
3124 if(*dest
== comperand
)
3129 static long WINAPI
expInterlockedIncrement( long* dest
)
3131 long result
=expInterlockedExchangeAdd( dest
, 1 ) + 1;
3132 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
3135 static long WINAPI
expInterlockedDecrement( long* dest
)
3137 long result
=expInterlockedExchangeAdd( dest
, -1 ) - 1;
3138 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
3142 static void WINAPI
expOutputDebugStringA( const char* string
)
3144 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string
);
3145 fprintf(stderr
, "DEBUG: %s\n", string
);
3148 static int WINAPI
expGetDC(int hwnd
)
3150 dbgprintf("GetDC(0x%x) => 1\n", hwnd
);
3154 static int WINAPI
expReleaseDC(int hwnd
, int hdc
)
3156 dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd
, hdc
);
3160 static int WINAPI
expGetDesktopWindow(void)
3162 dbgprintf("GetDesktopWindow() => 0\n");
3166 static int cursor
[100];
3168 static int WINAPI
expLoadCursorA(int handle
,LPCSTR name
)
3170 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle
, name
, (int)&cursor
[0]);
3171 return (int)&cursor
[0];
3173 static int WINAPI
expSetCursor(void *cursor
)
3175 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor
, cursor
);
3178 static int WINAPI
expGetCursorPos(void *cursor
)
3180 dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor
, cursor
);
3183 #ifdef CONFIG_QTX_CODECS
3184 static int show_cursor
= 0;
3185 static int WINAPI
expShowCursor(int show
)
3187 dbgprintf("ShowCursor(%d) => %d\n", show
, show
);
3195 static int WINAPI
expRegisterWindowMessageA(char *message
)
3197 dbgprintf("RegisterWindowMessageA(%s)\n", message
);
3200 static int WINAPI
expGetProcessVersion(int pid
)
3202 dbgprintf("GetProcessVersion(%d)\n", pid
);
3205 static int WINAPI
expGetCurrentThread(void)
3208 dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
3211 static int WINAPI
expGetOEMCP(void)
3213 dbgprintf("GetOEMCP()\n");
3216 static int WINAPI
expGetCPInfo(int cp
,void *info
)
3218 dbgprintf("GetCPInfo()\n");
3221 #ifdef CONFIG_QTX_CODECS
3222 #define SM_CXSCREEN 0
3223 #define SM_CYSCREEN 1
3224 #define SM_XVIRTUALSCREEN 76
3225 #define SM_YVIRTUALSCREEN 77
3226 #define SM_CXVIRTUALSCREEN 78
3227 #define SM_CYVIRTUALSCREEN 79
3228 #define SM_CMONITORS 80
3230 static int WINAPI
expGetSystemMetrics(int index
)
3232 dbgprintf("GetSystemMetrics(%d)\n", index
);
3233 #ifdef CONFIG_QTX_CODECS
3236 case SM_XVIRTUALSCREEN
:
3237 case SM_YVIRTUALSCREEN
:
3240 case SM_CXVIRTUALSCREEN
:
3241 return PSEUDO_SCREEN_WIDTH
;
3243 case SM_CYVIRTUALSCREEN
:
3244 return PSEUDO_SCREEN_HEIGHT
;
3251 static int WINAPI
expGetSysColor(int index
)
3253 dbgprintf("GetSysColor(%d) => 1\n", index
);
3256 static int WINAPI
expGetSysColorBrush(int index
)
3258 dbgprintf("GetSysColorBrush(%d)\n", index
);
3264 static int WINAPI
expGetSystemPaletteEntries(int hdc
, int iStartIndex
, int nEntries
, void* lppe
)
3266 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3267 hdc
, iStartIndex
, nEntries
, lppe
);
3272 typedef struct TIME_ZONE_INFORMATION {
3274 char StandardName[32];
3275 SYSTEMTIME StandardDate;
3277 char DaylightName[32];
3278 SYSTEMTIME DaylightDate;
3280 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3283 static int WINAPI
expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation
)
3285 const short name
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3286 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3287 const short pname
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3288 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3289 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3290 memset(lpTimeZoneInformation
, 0, sizeof(TIME_ZONE_INFORMATION
));
3291 lpTimeZoneInformation
->Bias
=360;//GMT-6
3292 memcpy(lpTimeZoneInformation
->StandardName
, name
, sizeof(name
));
3293 lpTimeZoneInformation
->StandardDate
.wMonth
=10;
3294 lpTimeZoneInformation
->StandardDate
.wDay
=5;
3295 lpTimeZoneInformation
->StandardDate
.wHour
=2;
3296 lpTimeZoneInformation
->StandardBias
=0;
3297 memcpy(lpTimeZoneInformation
->DaylightName
, pname
, sizeof(pname
));
3298 lpTimeZoneInformation
->DaylightDate
.wMonth
=4;
3299 lpTimeZoneInformation
->DaylightDate
.wDay
=1;
3300 lpTimeZoneInformation
->DaylightDate
.wHour
=2;
3301 lpTimeZoneInformation
->DaylightBias
=-60;
3302 return TIME_ZONE_ID_STANDARD
;
3305 static void WINAPI
expGetLocalTime(SYSTEMTIME
* systime
)
3308 struct tm
*local_tm
;
3311 dbgprintf("GetLocalTime(0x%x)\n");
3312 gettimeofday(&tv
, NULL
);
3313 local_time
=tv
.tv_sec
;
3314 local_tm
=localtime(&local_time
);
3316 systime
->wYear
= local_tm
->tm_year
+ 1900;
3317 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3318 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3319 systime
->wDay
= local_tm
->tm_mday
;
3320 systime
->wHour
= local_tm
->tm_hour
;
3321 systime
->wMinute
= local_tm
->tm_min
;
3322 systime
->wSecond
= local_tm
->tm_sec
;
3323 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3324 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3325 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3326 " Milliseconds: %d\n",
3327 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3328 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3331 static int WINAPI
expGetSystemTime(SYSTEMTIME
* systime
)
3334 struct tm
*local_tm
;
3337 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3338 gettimeofday(&tv
, NULL
);
3339 local_time
=tv
.tv_sec
;
3340 local_tm
=gmtime(&local_time
);
3342 systime
->wYear
= local_tm
->tm_year
+ 1900;
3343 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3344 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3345 systime
->wDay
= local_tm
->tm_mday
;
3346 systime
->wHour
= local_tm
->tm_hour
;
3347 systime
->wMinute
= local_tm
->tm_min
;
3348 systime
->wSecond
= local_tm
->tm_sec
;
3349 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3350 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3351 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3352 " Milliseconds: %d\n",
3353 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3354 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3358 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3359 static void WINAPI
expGetSystemTimeAsFileTime(FILETIME
* systime
)
3362 unsigned long long secs
;
3364 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3365 gettimeofday(&tv
, NULL
);
3366 secs
= (tv
.tv_sec
+ SECS_1601_TO_1970
) * 10000000;
3367 secs
+= tv
.tv_usec
* 10;
3368 systime
->dwLowDateTime
= secs
& 0xffffffff;
3369 systime
->dwHighDateTime
= (secs
>> 32);
3372 static int WINAPI
expGetEnvironmentVariableA(const char* name
, char* field
, int size
)
3375 // printf("%s %x %x\n", name, field, size);
3376 if(field
)field
[0]=0;
3379 if (p) strncpy(field,p,size);
3381 if (strcmp(name
,"__MSVCRT_HEAP_SELECT")==0)
3382 strcpy(field
,"__GLOBAL_HEAP_SELECTED,1");
3383 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name
, name
, field
, size
, strlen(field
));
3384 return strlen(field
);
3387 static int WINAPI
expSetEnvironmentVariableA(const char *name
, const char *value
)
3389 dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name
, value
);
3393 static void* WINAPI
expCoTaskMemAlloc(ULONG cb
)
3395 return my_mreq(cb
, 0);
3397 static void WINAPI
expCoTaskMemFree(void* cb
)
3405 void* CoTaskMemAlloc(unsigned long cb
)
3407 return expCoTaskMemAlloc(cb
);
3409 void CoTaskMemFree(void* cb
)
3411 expCoTaskMemFree(cb
);
3414 struct COM_OBJECT_INFO
3417 long (*GetClassObject
) (GUID
* clsid
, const GUID
* iid
, void** ppv
);
3420 static struct COM_OBJECT_INFO
* com_object_table
=0;
3421 static int com_object_size
=0;
3422 int RegisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3426 com_object_table
=realloc(com_object_table
, sizeof(struct COM_OBJECT_INFO
)*(++com_object_size
));
3427 com_object_table
[com_object_size
-1].clsid
=*clsid
;
3428 com_object_table
[com_object_size
-1].GetClassObject
=gcs
;
3432 int UnregisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3439 if (com_object_table
== 0)
3440 printf("Warning: UnregisterComClass() called without any registered class\n");
3441 while (i
< com_object_size
)
3445 memcpy(&com_object_table
[i
- 1].clsid
,
3446 &com_object_table
[i
].clsid
, sizeof(GUID
));
3447 com_object_table
[i
- 1].GetClassObject
=
3448 com_object_table
[i
].GetClassObject
;
3450 else if (memcmp(&com_object_table
[i
].clsid
, clsid
, sizeof(GUID
)) == 0
3451 && com_object_table
[i
].GetClassObject
== gcs
)
3459 if (--com_object_size
== 0)
3461 free(com_object_table
);
3462 com_object_table
= 0;
3469 const GUID IID_IUnknown
=
3471 0x00000000, 0x0000, 0x0000,
3472 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3474 const GUID IID_IClassFactory
=
3476 0x00000001, 0x0000, 0x0000,
3477 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3480 static long WINAPI
expCoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3481 long dwClsContext
, const GUID
* riid
, void** ppv
)
3484 struct COM_OBJECT_INFO
* ci
=0;
3485 for(i
=0; i
<com_object_size
; i
++)
3486 if(!memcmp(rclsid
, &com_object_table
[i
].clsid
, sizeof(GUID
)))
3487 ci
=&com_object_table
[i
];
3488 if(!ci
)return REGDB_E_CLASSNOTREG
;
3489 // in 'real' world we should mess with IClassFactory here
3490 i
=ci
->GetClassObject(rclsid
, riid
, ppv
);
3494 long CoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3495 long dwClsContext
, const GUID
* riid
, void** ppv
)
3497 return expCoCreateInstance(rclsid
, pUnkOuter
, dwClsContext
, riid
, ppv
);
3500 static int WINAPI
expIsRectEmpty(CONST RECT
*lprc
)
3507 w
= lprc
->right
- lprc
->left
;
3508 h
= lprc
->bottom
- lprc
->top
;
3509 if (w
<= 0 || h
<= 0)
3515 dbgprintf("IsRectEmpty(%p) => %s\n", lprc
, (r
) ? "TRUE" : "FALSE");
3516 //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3517 // return 0; // wmv9?
3521 static int _adjust_fdiv
=0; //what's this? - used to adjust division
3522 static int _winver
= 0x510; // windows version
3527 static unsigned int WINAPI
expGetTempPathA(unsigned int len
, char* path
)
3529 dbgprintf("GetTempPathA(%d, 0x%x)", len
, path
);
3532 dbgprintf(" => 0\n");
3535 strcpy(path
, "/tmp");
3536 dbgprintf(" => 5 ( '/tmp' )\n");
3543 DWORD dwFileAttributes;
3544 FILETIME ftCreationTime;
3545 FILETIME ftLastAccessTime;
3546 FILETIME ftLastWriteTime;
3547 DWORD nFileSizeHigh;
3551 CHAR cFileName[260];
3552 CHAR cAlternateFileName[14];
3553 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3556 static DIR* qtx_dir
=NULL
;
3558 static WIN_BOOL WINAPI
expFindNextFileA(HANDLE h
,LPWIN32_FIND_DATAA lpfd
)
3560 #ifdef CONFIG_QTX_CODECS
3561 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h
, lpfd
);
3562 if(h
==FILE_HANDLE_quicktimeqtx
){
3564 if(!qtx_dir
) return 0;
3565 while((d
=readdir(qtx_dir
))){
3566 char* x
=strrchr(d
->d_name
,'.');
3568 if(strcmp(x
,".qtx")) continue;
3569 strcpy(lpfd
->cFileName
,d
->d_name
);
3570 // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3571 strcpy(lpfd
->cAlternateFileName
,"foobar.qtx");
3572 dbgprintf("### FindNext: %s\n",lpfd
->cFileName
);
3575 closedir(qtx_dir
); qtx_dir
=NULL
;
3582 static HANDLE WINAPI
expFindFirstFileA(LPCSTR s
, LPWIN32_FIND_DATAA lpfd
)
3584 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s
, s
, lpfd
);
3585 // printf("\n### FindFirstFileA('%s')...\n",s);
3586 #ifdef CONFIG_QTX_CODECS
3587 if(strstr(s
, "quicktime\\*.QTX")){
3588 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s
, s
, lpfd
);
3589 dbgprintf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",
3591 qtx_dir
= opendir(codec_path
);
3592 if(!qtx_dir
) return (HANDLE
)-1;
3593 memset(lpfd
,0,sizeof(*lpfd
));
3594 if(expFindNextFileA(FILE_HANDLE_quicktimeqtx
,lpfd
))
3595 return FILE_HANDLE_quicktimeqtx
;
3596 printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",
3601 if(strstr(s
, "QuickTime.qts")){
3602 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s
, s
, lpfd
);
3603 // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3604 // return (HANDLE)-1;
3605 strcpy(lpfd
->cFileName
, "QuickTime.qts");
3606 strcpy(lpfd
->cAlternateFileName
, "QuickT~1.qts");
3607 return FILE_HANDLE_quicktimeqts
;
3611 if(strstr(s
, "*.vwp")){
3612 // hack for VoxWare codec plugins:
3613 strcpy(lpfd
->cFileName
, "msms001.vwp");
3614 strcpy(lpfd
->cAlternateFileName
, "msms001.vwp");
3617 // return 'file not found'
3621 static WIN_BOOL WINAPI
expFindClose(HANDLE h
)
3623 dbgprintf("FindClose(0x%x) => 0\n", h
);
3624 #ifdef CONFIG_QTX_CODECS
3625 // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3626 // closedir(qtx_dir);
3632 static UINT WINAPI
expSetErrorMode(UINT i
)
3634 dbgprintf("SetErrorMode(%d) => 0\n", i
);
3637 static UINT WINAPI
expGetWindowsDirectoryA(LPSTR s
,UINT c
)
3639 char windir
[]="c:\\windows";
3641 strncpy(s
, windir
, c
);
3642 result
=1+((c
<strlen(windir
))?c
:strlen(windir
));
3643 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3646 #ifdef CONFIG_QTX_CODECS
3647 static UINT WINAPI
expGetCurrentDirectoryA(UINT c
, LPSTR s
)
3649 char curdir
[]="c:\\";
3651 strncpy(s
, curdir
, c
);
3652 result
=1+((c
<strlen(curdir
))?c
:strlen(curdir
));
3653 dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3657 static int WINAPI
expSetCurrentDirectoryA(const char *pathname
)
3659 dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname
, pathname
);
3661 if (strrchr(pathname
, '\\'))
3662 chdir(strcat(strrchr(pathname
, '\\')+1, '/'));
3669 static int WINAPI
expCreateDirectoryA(const char *pathname
, void *sa
)
3671 dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3672 pathname
, pathname
, sa
);
3674 p
= strrchr(pathname
, '\\')+1;
3675 strcpy(&buf
[0], p
); /* should be strncpy */
3682 if (strrchr(pathname
, '\\'))
3683 mkdir(strcat(strrchr(pathname
, '\\')+1, '/'), 666);
3685 mkdir(pathname
, 666);
3692 static WIN_BOOL WINAPI
expDeleteFileA(LPCSTR s
)
3694 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s
, s
);
3697 static WIN_BOOL WINAPI
expFileTimeToLocalFileTime(const FILETIME
* cpf
, LPFILETIME pf
)
3699 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf
, pf
);
3703 static UINT WINAPI
expGetTempFileNameA(LPCSTR cs1
,LPCSTR cs2
,UINT i
,LPSTR ps
)
3705 char mask
[16]="/tmp/AP_XXXXXX";
3707 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1
, cs1
, cs2
, cs2
, i
, ps
);
3710 dbgprintf(" => -1\n");
3713 result
=mkstemp(mask
);
3714 sprintf(ps
, "AP%d", result
);
3715 dbgprintf(" => %d\n", strlen(ps
));
3719 // This func might need proper implementation if we want AngelPotion codec.
3720 // They try to open APmpeg4v1.apl with it.
3721 // DLL will close opened file with CloseHandle().
3723 static HANDLE WINAPI
expCreateFileA(LPCSTR cs1
,DWORD i1
,DWORD i2
,
3724 LPSECURITY_ATTRIBUTES p1
, DWORD i3
,DWORD i4
,HANDLE i5
)
3726 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1
, cs1
, i1
,
3727 i2
, p1
, i3
, i4
, i5
);
3728 if((!cs1
) || (strlen(cs1
)<2))return -1;
3730 #ifdef CONFIG_QTX_CODECS
3731 if(strstr(cs1
, "QuickTime.qts"))
3734 char* tmp
= malloc(strlen(codec_path
) + 50);
3735 strcpy(tmp
, codec_path
);
3737 strcat(tmp
, "QuickTime.qts");
3738 result
=open(tmp
, O_RDONLY
);
3742 if(strstr(cs1
, ".qtx"))
3745 char* tmp
= malloc(strlen(codec_path
) + 250);
3746 char* x
=strrchr(cs1
,'\\');
3747 sprintf(tmp
, "%s/%s", codec_path
, x
? (x
+ 1) : cs1
);
3748 // printf("### Open: %s -> %s\n",cs1,tmp);
3749 result
=open(tmp
, O_RDONLY
);
3755 if(strncmp(cs1
, "AP", 2) == 0)
3758 char* tmp
= malloc(strlen(codec_path
) + 50);
3759 strcpy(tmp
, codec_path
);
3761 strcat(tmp
, "APmpg4v1.apl");
3762 result
=open(tmp
, O_RDONLY
);
3766 if (strstr(cs1
, "vp3") || strstr(cs1
, ".fpf") || strstr(cs1
, ".col"))
3770 char* tmp
=malloc(20 + strlen(cs1
));
3771 strcpy(tmp
, "/tmp/");
3776 if (tmp
[r
] == ':' || tmp
[r
] == '\\')
3780 if (GENERIC_READ
& i1
)
3782 else if (GENERIC_WRITE
& i1
)
3784 flg
|= O_WRONLY
| O_CREAT
;
3785 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp
, r
, flg
);
3787 r
=open(tmp
, flg
, S_IRWXU
);
3792 // Needed by wnvplay1.dll
3793 if (strstr(cs1
, "WINNOV.bmp"))
3796 r
=open("/dev/null", O_RDONLY
);
3801 /* we need this for some virtualdub filters */
3805 if (GENERIC_READ
& i1
)
3807 else if (GENERIC_WRITE
& i1
)
3810 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1
, r
, flg
);
3819 static UINT WINAPI
expGetSystemDirectoryA(
3820 char* lpBuffer
, // address of buffer for system directory
3821 UINT uSize
// size of directory buffer
3823 dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer
,uSize
);
3824 if(!lpBuffer
) strcpy(lpBuffer
,".");
3828 static char sysdir[]=".";
3829 static LPCSTR WINAPI expGetSystemDirectoryA(void)
3831 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3835 static DWORD WINAPI expGetFullPathNameA
3838 DWORD nBufferLength
,
3842 if(!lpFileName
) return 0;
3843 dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName
,nBufferLength
,
3844 lpBuffer
, lpFilePart
);
3846 #ifdef CONFIG_QTX_CODECS
3847 strcpy(lpFilePart
, "Quick123.qts");
3849 strcpy(lpFilePart
, lpFileName
);
3852 if (strrchr(lpFileName
, '\\'))
3853 lpFilePart
= strrchr(lpFileName
, '\\');
3855 lpFilePart
= (LPTSTR
)lpFileName
;
3857 strcpy(lpBuffer
, lpFileName
);
3858 // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3859 return strlen(lpBuffer
);
3862 static DWORD WINAPI expGetShortPathNameA
3868 if(!longpath
) return 0;
3869 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath
,shortpath
,shortlen
);
3870 strcpy(shortpath
,longpath
);
3871 return strlen(shortpath
);
3874 static WIN_BOOL WINAPI
expReadFile(HANDLE h
,LPVOID pv
,DWORD size
,LPDWORD rd
,LPOVERLAPPED unused
)
3877 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, rd
);
3878 result
=read(h
, pv
, size
);
3880 if(!result
)return 0;
3884 static WIN_BOOL WINAPI
expWriteFile(HANDLE h
,LPCVOID pv
,DWORD size
,LPDWORD wr
,LPOVERLAPPED unused
)
3887 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, wr
);
3889 result
=write(h
, pv
, size
);
3891 if(!result
)return 0;
3894 static DWORD WINAPI
expSetFilePointer(HANDLE h
, LONG val
, LPLONG ext
, DWORD whence
)
3897 dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h
, val
, ext
, ext
? *ext
: NULL
, whence
);
3898 //why would DLL want temporary file with >2Gb size?
3910 #ifdef CONFIG_QTX_CODECS
3911 if (val
== 0 && ext
!= 0)
3914 return lseek(h
, val
, wh
);
3917 static HDRVR WINAPI
expOpenDriverA(LPCSTR szDriverName
, LPCSTR szSectionName
,
3920 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3923 static HDRVR WINAPI
expOpenDriver(LPCSTR szDriverName
, LPCSTR szSectionName
,
3926 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3931 static WIN_BOOL WINAPI
expGetProcessAffinityMask(HANDLE hProcess
,
3932 LPDWORD lpProcessAffinityMask
,
3933 LPDWORD lpSystemAffinityMask
)
3935 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3936 hProcess
, lpProcessAffinityMask
, lpSystemAffinityMask
);
3937 if(lpProcessAffinityMask
)*lpProcessAffinityMask
=1;
3938 if(lpSystemAffinityMask
)*lpSystemAffinityMask
=1;
3942 // Fake implementation: does nothing, but does it right :)
3943 static WIN_BOOL WINAPI
expSetProcessAffinityMask(HANDLE hProcess
,
3944 LPDWORD dwProcessAffinityMask
)
3946 dbgprintf("SetProcessAffinityMask(0x%x, 0x%x) => 1\n",
3947 hProcess
, dwProcessAffinityMask
);
3952 static int WINAPI
expMulDiv(int nNumber
, int nNumerator
, int nDenominator
)
3954 static const long long max_int
=0x7FFFFFFFLL
;
3955 static const long long min_int
=-0x80000000LL
;
3956 long long tmp
=(long long)nNumber
*(long long)nNumerator
;
3957 dbgprintf("expMulDiv %d * %d / %d\n", nNumber
, nNumerator
, nDenominator
);
3958 if(!nDenominator
)return 1;
3960 if(tmp
<min_int
) return 1;
3961 if(tmp
>max_int
) return 1;
3965 static LONG WINAPI
explstrcmpiA(const char* str1
, const char* str2
)
3967 LONG result
=strcasecmp(str1
, str2
);
3968 dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
3972 static LONG WINAPI
explstrlenA(const char* str1
)
3974 LONG result
=strlen(str1
);
3975 dbgprintf("strlen(0x%x='%.50s') => %d\n", str1
, str1
, result
);
3979 static LONG WINAPI
explstrcpyA(char* str1
, const char* str2
)
3981 int result
= (int) strcpy(str1
, str2
);
3982 dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1
, str2
, str2
, result
);
3985 static LONG WINAPI
explstrcpynA(char* str1
, const char* str2
,int len
)
3988 if (strlen(str2
)>len
)
3989 result
= (int) strncpy(str1
, str2
,len
);
3991 result
= (int) strcpy(str1
,str2
);
3992 dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1
, str2
, str2
,len
, strlen(str2
),result
);
3995 static LONG WINAPI
explstrcatA(char* str1
, const char* str2
)
3997 int result
= (int) strcat(str1
, str2
);
3998 dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1
, str2
, str2
, result
);
4003 static LONG WINAPI
expInterlockedExchange(long *dest
, long l
)
4005 long retval
= *dest
;
4010 static void WINAPI
expInitCommonControls(void)
4012 dbgprintf("InitCommonControls called!\n");
4016 #ifdef CONFIG_QTX_CODECS
4017 /* needed by QuickTime.qts */
4018 static HWND WINAPI
expCreateUpDownControl (DWORD style
, INT x
, INT y
, INT cx
, INT cy
,
4019 HWND parent
, INT id
, HINSTANCE inst
,
4020 HWND buddy
, INT maxVal
, INT minVal
, INT curVal
)
4022 dbgprintf("CreateUpDownControl(...)\n");
4027 /* alex: implement this call! needed for 3ivx */
4028 static HRESULT WINAPI
expCoCreateFreeThreadedMarshaler(void *pUnkOuter
, void **ppUnkInner
)
4030 dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
4031 pUnkOuter
, ppUnkInner
);
4033 return ERROR_CALL_NOT_IMPLEMENTED
;
4037 static int WINAPI
expDuplicateHandle(HANDLE hSourceProcessHandle
, // handle to source process
4038 HANDLE hSourceHandle
, // handle to duplicate
4039 HANDLE hTargetProcessHandle
, // handle to target process
4040 HANDLE
* lpTargetHandle
, // duplicate handle
4041 DWORD dwDesiredAccess
, // requested access
4042 int bInheritHandle
, // handle inheritance option
4043 DWORD dwOptions
// optional actions
4046 dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
4047 hSourceProcessHandle
, hSourceHandle
, hTargetProcessHandle
,
4048 lpTargetHandle
, dwDesiredAccess
, bInheritHandle
, dwOptions
);
4049 *lpTargetHandle
= hSourceHandle
;
4053 static HRESULT WINAPI
expCoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
4055 dbgprintf("CoInitializeEx(%p, %d) called\n", lpReserved
, dwCoInit
);
4059 // required by PIM1 codec (used by win98 PCTV Studio capture sw)
4060 static HRESULT WINAPI
expCoInitialize(
4061 LPVOID lpReserved
/* [in] pointer to win32 malloc interface
4062 (obsolete, should be NULL) */
4066 * Just delegate to the newer method.
4068 return expCoInitializeEx(lpReserved
, COINIT_APARTMENTTHREADED
);
4071 static void WINAPI
expCoUninitialize(void)
4073 dbgprintf("CoUninitialize() called\n");
4076 /* allow static linking */
4077 HRESULT WINAPI
CoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
4079 return expCoInitializeEx(lpReserved
, dwCoInit
);
4081 HRESULT WINAPI
CoInitialize(LPVOID lpReserved
)
4083 return expCoInitialize(lpReserved
);
4085 void WINAPI
CoUninitialize(void)
4087 expCoUninitialize();
4090 static DWORD WINAPI expSetThreadAffinityMask
4093 DWORD dwThreadAffinityMask
4099 * no WINAPI functions - CDECL
4101 static void* expmalloc(int size
)
4104 // return malloc(size);
4105 void* result
=my_mreq(size
,0);
4106 dbgprintf("malloc(0x%x) => 0x%x\n", size
,result
);
4108 printf("WARNING: malloc() failed\n");
4111 static void expfree(void* mem
)
4113 // return free(mem);
4114 dbgprintf("free(%p)\n", mem
);
4117 /* needed by atrac3.acm */
4118 static void *expcalloc(int num
, int size
)
4120 void* result
=my_mreq(num
*size
,1);
4121 dbgprintf("calloc(%d,%d) => %p\n", num
,size
,result
);
4123 printf("WARNING: calloc() failed\n");
4126 static void* expnew(int size
)
4128 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
4129 // printf("%08x %08x %08x %08x\n",
4130 // size, *(1+(int*)&size),
4131 // *(2+(int*)&size),*(3+(int*)&size));
4135 result
=my_mreq(size
,0);
4136 dbgprintf("new(%d) => %p\n", size
, result
);
4138 printf("WARNING: new() failed\n");
4142 static int expdelete(void* memory
)
4144 dbgprintf("delete(%p)\n", memory
);
4150 * local definition - we need only the last two members at this point
4151 * otherwice we would have to introduce here GUIDs and some more types..
4153 typedef struct __attribute__((__packed__
))
4156 unsigned long cbFormat
; //0x40
4157 char* pbFormat
; //0x44
4159 static HRESULT WINAPI
expMoCopyMediaType(MY_MEDIA_TYPE
* dest
, const MY_MEDIA_TYPE
* src
)
4163 memcpy(dest
, src
, sizeof(MY_MEDIA_TYPE
));
4166 dest
->pbFormat
= (char*) my_mreq(dest
->cbFormat
, 0);
4167 if (!dest
->pbFormat
)
4168 return E_OUTOFMEMORY
;
4169 memcpy(dest
->pbFormat
, src
->pbFormat
, dest
->cbFormat
);
4173 static HRESULT WINAPI
expMoInitMediaType(MY_MEDIA_TYPE
* dest
, DWORD cbFormat
)
4177 memset(dest
, 0, sizeof(MY_MEDIA_TYPE
));
4180 dest
->pbFormat
= (char*) my_mreq(cbFormat
, 0);
4181 if (!dest
->pbFormat
)
4182 return E_OUTOFMEMORY
;
4186 static HRESULT WINAPI
expMoCreateMediaType(MY_MEDIA_TYPE
** dest
, DWORD cbFormat
)
4190 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
4191 return expMoInitMediaType(*dest
, cbFormat
);
4193 static HRESULT WINAPI
expMoDuplicateMediaType(MY_MEDIA_TYPE
** dest
, const void* src
)
4197 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
4198 return expMoCopyMediaType(*dest
, src
);
4200 static HRESULT WINAPI
expMoFreeMediaType(MY_MEDIA_TYPE
* dest
)
4206 my_release(dest
->pbFormat
);
4212 static HRESULT WINAPI
expMoDeleteMediaType(MY_MEDIA_TYPE
* dest
)
4216 expMoFreeMediaType(dest
);
4221 static int exp_snprintf( char *str
, int size
, const char *format
, ... )
4225 va_start(va
, format
);
4226 x
=snprintf(str
,size
,format
,va
);
4227 dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str
,size
,format
,x
);
4233 static int exp_initterm(int v1
, int v2
)
4235 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1
, v2
);
4239 /* merged from wine - 2002.04.21 */
4240 typedef void (*INITTERMFUNC
)();
4241 static int exp_initterm(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
4243 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start
, end
, *start
);
4248 //printf("call _initfunc: from: %p %d\n", *start);
4249 // ok this trick with push/pop is necessary as otherwice
4250 // edi/esi registers are being trashed
4269 //printf("done %p %d:%d\n", end);
4277 /* Fake _initterm_e from msvcr80.dll, needed by sirenacm.dll
4278 * NOTE: If I make this an alias for _initterm, then sirenacm.dll tries to call
4279 other uninmplemented functions; keep this in mind if some future codec needs
4280 a real implementation of this function */
4281 static int exp_initterm_e(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
4283 dbgprintf("_initterm_e(0x%x, 0x%x)\n", start
, end
);
4287 static void* exp__dllonexit(void)
4289 // FIXME extract from WINE
4293 static int expwsprintfA(char* string
, const char* format
, ...)
4297 va_start(va
, format
);
4298 result
= vsprintf(string
, format
, va
);
4299 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string
, format
, result
);
4304 static int expsprintf(char* str
, const char* format
, ...)
4308 dbgprintf("sprintf(0x%x, %s)\n", str
, format
);
4309 va_start(args
, format
);
4310 r
= vsprintf(str
, format
, args
);
4314 static int expsscanf(const char* str
, const char* format
, ...)
4318 dbgprintf("sscanf(%s, %s)\n", str
, format
);
4319 va_start(args
, format
);
4320 r
= vsscanf(str
, format
, args
);
4324 static void* expfopen(const char* path
, const char* mode
)
4326 printf("fopen: \"%s\" mode:%s\n", path
, mode
);
4327 //return fopen(path, mode);
4328 return fdopen(0, mode
); // everything on screen
4330 static int expfprintf(void* stream
, const char* format
, ...)
4334 dbgprintf("fprintf(%p, %s, ...)\n", stream
, format
);
4335 va_start(args
, format
);
4336 r
= vfprintf((FILE*) stream
, format
, args
);
4341 static int expprintf(const char* format
, ...)
4345 dbgprintf("printf(%s, ...)\n", format
);
4346 va_start(args
, format
);
4347 r
= vprintf(format
, args
);
4352 static char* expgetenv(const char* varname
)
4354 char* v
= getenv(varname
);
4355 dbgprintf("getenv(%s) => %s\n", varname
, v
);
4359 static void* expwcscpy(WCHAR
* dst
, const WCHAR
* src
)
4362 while ((*p
++ = *src
++))
4367 static char* expstrrchr(char* string
, int value
)
4369 char* result
=strrchr(string
, value
);
4371 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4373 dbgprintf("strrchr(0x%x='%s', %d) => 0", string
, string
, value
);
4377 static char* expstrchr(char* string
, int value
)
4379 char* result
=strchr(string
, value
);
4381 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4383 dbgprintf("strchr(0x%x='%s', %d) => 0", string
, string
, value
);
4386 static int expstrlen(char* str
)
4388 int result
=strlen(str
);
4389 dbgprintf("strlen(0x%x='%s') => %d\n", str
, str
, result
);
4392 static char* expstrcpy(char* str1
, const char* str2
)
4394 char* result
= strcpy(str1
, str2
);
4395 dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1
, str2
, str2
, result
);
4398 static char* expstrncpy(char* str1
, const char* str2
, size_t count
)
4400 char* result
= strncpy(str1
, str2
, count
);
4401 dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1
, str2
, str2
, count
, result
);
4404 static int expstrcmp(const char* str1
, const char* str2
)
4406 int result
=strcmp(str1
, str2
);
4407 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4410 static int expstrncmp(const char* str1
, const char* str2
,int x
)
4412 int result
=strncmp(str1
, str2
,x
);
4413 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4416 static char* expstrcat(char* str1
, const char* str2
)
4418 char* result
= strcat(str1
, str2
);
4419 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1
, str1
, str2
, str2
, result
);
4422 static char* exp_strdup(const char* str1
)
4424 int l
= strlen(str1
);
4425 char* result
= (char*) my_mreq(l
+ 1,0);
4427 strcpy(result
, str1
);
4428 dbgprintf("_strdup(0x%x='%s') => %p\n", str1
, str1
, result
);
4431 static int expisalnum(int c
)
4433 int result
= (int) isalnum(c
);
4434 dbgprintf("isalnum(0x%x='%c' => %d\n", c
, c
, result
);
4437 static int expisspace(int c
)
4439 int result
= (int) isspace(c
);
4440 dbgprintf("isspace(0x%x='%c' => %d\n", c
, c
, result
);
4443 static int expisalpha(int c
)
4445 int result
= (int) isalpha(c
);
4446 dbgprintf("isalpha(0x%x='%c' => %d\n", c
, c
, result
);
4449 static int expisdigit(int c
)
4451 int result
= (int) isdigit(c
);
4452 dbgprintf("isdigit(0x%x='%c' => %d\n", c
, c
, result
);
4455 static void* expmemmove(void* dest
, void* src
, int n
)
4457 void* result
= memmove(dest
, src
, n
);
4458 dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4461 static int expmemcmp(void* dest
, void* src
, int n
)
4463 int result
= memcmp(dest
, src
, n
);
4464 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest
, src
, n
, result
);
4467 static void* expmemcpy(void* dest
, void* src
, int n
)
4469 void *result
= memcpy(dest
, src
, n
);
4470 dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4473 static void* expmemset(void* dest
, int c
, size_t n
)
4475 void *result
= memset(dest
, c
, n
);
4476 dbgprintf("memset(0x%x, %d, %d) => %p\n", dest
, c
, n
, result
);
4479 static time_t exptime(time_t* t
)
4481 time_t result
= time(t
);
4482 dbgprintf("time(0x%x) => %d\n", t
, result
);
4486 static int exprand(void)
4491 static void expsrand(int seed
)
4498 // preferred compilation with -O2 -ffast-math !
4500 static double explog10(double x
)
4502 /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4506 static double expcos(double x
)
4508 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4514 static void explog10(void)
4525 static void expcos(void)
4536 // this seem to be the only how to make this function working properly
4537 // ok - I've spent tremendous amount of time (many many many hours
4538 // of debuging fixing & testing - it's almost unimaginable - kabi
4540 // _ftol - operated on the float value which is already on the FPU stack
4542 static void exp_ftol(void)
4546 "sub $12, %esp \n\t"
4547 "fstcw -2(%ebp) \n\t"
4549 "movw -2(%ebp), %ax \n\t"
4550 "orb $0x0C, %ah \n\t"
4551 "movw %ax, -4(%ebp) \n\t"
4552 "fldcw -4(%ebp) \n\t"
4553 "fistpl -12(%ebp) \n\t"
4554 "fldcw -2(%ebp) \n\t"
4555 "movl -12(%ebp), %eax \n\t"
4556 //Note: gcc 3.03 does not do the following op if it
4557 // knows that ebp=esp
4558 "movl %ebp, %esp \n\t"
4562 #define FPU_DOUBLES(var1,var2) double var1,var2; \
4563 __asm__ volatile( "fstpl %0;fwait" : "=m" (var2) : ); \
4564 __asm__ volatile( "fstpl %0;fwait" : "=m" (var1) : )
4566 static double exp_CIpow(void)
4570 dbgprintf("_CIpow(%lf, %lf)\n", x
, y
);
4574 static double exppow(double x
, double y
)
4576 /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4580 static double expldexp(double x
, int expo
)
4582 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4583 return ldexp(x
, expo
);
4586 static double expfrexp(double x
, int* expo
)
4588 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4589 return frexp(x
, expo
);
4594 static int exp_stricmp(const char* s1
, const char* s2
)
4596 return strcasecmp(s1
, s2
);
4599 /* from declaration taken from Wine sources - this fountion seems to be
4600 * undocumented in any M$ doc */
4601 static int exp_setjmp3(void* jmpbuf
, int x
)
4603 //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4607 //"mov 4(%%esp), %%edx \n\t"
4608 "mov (%%esp), %%eax \n\t"
4609 "mov %%eax, (%%edx) \n\t" // store ebp
4611 //"mov %%ebp, (%%edx) \n\t"
4612 "mov %%ebx, 4(%%edx) \n\t"
4613 "mov %%edi, 8(%%edx) \n\t"
4614 "mov %%esi, 12(%%edx) \n\t"
4615 "mov %%esp, 16(%%edx) \n\t"
4617 "mov 4(%%esp), %%eax \n\t"
4618 "mov %%eax, 20(%%edx) \n\t"
4620 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4621 "movl $0, 36(%%edx) \n\t"
4623 : "d"(jmpbuf
) // input
4628 "mov %%fs:0, %%eax \n\t" // unsure
4629 "mov %%eax, 24(%%edx) \n\t"
4630 "cmp $0xffffffff, %%eax \n\t"
4632 "mov %%eax, 28(%%edx) \n\t"
4642 static DWORD WINAPI
expGetCurrentProcessId(void)
4644 dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4645 return getpid(); //(DWORD)NtCurrentTeb()->pid;
4652 } TIMECAPS
, *LPTIMECAPS
;
4654 static MMRESULT WINAPI
exptimeGetDevCaps(LPTIMECAPS lpCaps
, UINT wSize
)
4656 dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps
, wSize
);
4658 lpCaps
->wPeriodMin
= 1;
4659 lpCaps
->wPeriodMax
= 65535;
4663 static MMRESULT WINAPI
exptimeBeginPeriod(UINT wPeriod
)
4665 dbgprintf("timeBeginPeriod(%u) !\n", wPeriod
);
4667 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4671 #ifdef CONFIG_QTX_CODECS
4672 static MMRESULT WINAPI
exptimeEndPeriod(UINT wPeriod
)
4674 dbgprintf("timeEndPeriod(%u) !\n", wPeriod
);
4676 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4681 static void WINAPI
expGlobalMemoryStatus(
4682 LPMEMORYSTATUS lpmem
4684 static MEMORYSTATUS cached_memstatus
;
4685 static int cache_lastchecked
= 0;
4689 if (time(NULL
)==cache_lastchecked
) {
4690 memcpy(lpmem
,&cached_memstatus
,sizeof(MEMORYSTATUS
));
4694 f
= fopen( "/proc/meminfo", "r" );
4698 int total
, used
, free
, shared
, buffers
, cached
;
4700 lpmem
->dwLength
= sizeof(MEMORYSTATUS
);
4701 lpmem
->dwTotalPhys
= lpmem
->dwAvailPhys
= 0;
4702 lpmem
->dwTotalPageFile
= lpmem
->dwAvailPageFile
= 0;
4703 while (fgets( buffer
, sizeof(buffer
), f
))
4705 /* old style /proc/meminfo ... */
4706 if (sscanf( buffer
, "Mem: %d %d %d %d %d %d", &total
, &used
, &free
, &shared
, &buffers
, &cached
))
4708 lpmem
->dwTotalPhys
+= total
;
4709 lpmem
->dwAvailPhys
+= free
+ buffers
+ cached
;
4711 if (sscanf( buffer
, "Swap: %d %d %d", &total
, &used
, &free
))
4713 lpmem
->dwTotalPageFile
+= total
;
4714 lpmem
->dwAvailPageFile
+= free
;
4717 /* new style /proc/meminfo ... */
4718 if (sscanf(buffer
, "MemTotal: %d", &total
))
4719 lpmem
->dwTotalPhys
= total
*1024;
4720 if (sscanf(buffer
, "MemFree: %d", &free
))
4721 lpmem
->dwAvailPhys
= free
*1024;
4722 if (sscanf(buffer
, "SwapTotal: %d", &total
))
4723 lpmem
->dwTotalPageFile
= total
*1024;
4724 if (sscanf(buffer
, "SwapFree: %d", &free
))
4725 lpmem
->dwAvailPageFile
= free
*1024;
4726 if (sscanf(buffer
, "Buffers: %d", &buffers
))
4727 lpmem
->dwAvailPhys
+= buffers
*1024;
4728 if (sscanf(buffer
, "Cached: %d", &cached
))
4729 lpmem
->dwAvailPhys
+= cached
*1024;
4733 if (lpmem
->dwTotalPhys
)
4735 DWORD TotalPhysical
= lpmem
->dwTotalPhys
+lpmem
->dwTotalPageFile
;
4736 DWORD AvailPhysical
= lpmem
->dwAvailPhys
+lpmem
->dwAvailPageFile
;
4737 lpmem
->dwMemoryLoad
= (TotalPhysical
-AvailPhysical
)
4738 / (TotalPhysical
/ 100);
4742 /* FIXME: should do something for other systems */
4743 lpmem
->dwMemoryLoad
= 0;
4744 lpmem
->dwTotalPhys
= 16*1024*1024;
4745 lpmem
->dwAvailPhys
= 16*1024*1024;
4746 lpmem
->dwTotalPageFile
= 16*1024*1024;
4747 lpmem
->dwAvailPageFile
= 16*1024*1024;
4749 expGetSystemInfo(&si
);
4750 lpmem
->dwTotalVirtual
= si
.lpMaximumApplicationAddress
-si
.lpMinimumApplicationAddress
;
4751 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4752 lpmem
->dwAvailVirtual
= lpmem
->dwTotalVirtual
-64*1024;
4753 memcpy(&cached_memstatus
,lpmem
,sizeof(MEMORYSTATUS
));
4754 cache_lastchecked
= time(NULL
);
4756 /* it appears some memory display programs want to divide by these values */
4757 if(lpmem
->dwTotalPageFile
==0)
4758 lpmem
->dwTotalPageFile
++;
4760 if(lpmem
->dwAvailPageFile
==0)
4761 lpmem
->dwAvailPageFile
++;
4764 static INT WINAPI
expGetThreadPriority(HANDLE hthread
)
4766 dbgprintf("GetThreadPriority(%p)\n",hthread
);
4770 /**********************************************************************
4771 * SetThreadPriority [KERNEL32.@] Sets priority for thread.
4777 static WIN_BOOL WINAPI
expSetThreadPriority(
4778 HANDLE hthread
, /* [in] Handle to thread */
4779 INT priority
) /* [in] Thread priority level */
4781 dbgprintf("SetThreadPriority(%p,%d)\n",hthread
,priority
);
4785 static void WINAPI
expTerminateProcess( DWORD process
, DWORD status
)
4787 printf("EXIT - process %ld code %ld\n", process
, status
);
4791 static void WINAPI
expExitProcess( DWORD status
)
4793 printf("EXIT - code %ld\n",status
);
4797 static INT WINAPI
expMessageBoxA(HWND hWnd
, LPCSTR text
, LPCSTR title
, UINT type
){
4798 printf("MSGBOX '%s' '%s' (%d)\n",text
,title
,type
);
4799 #ifdef CONFIG_QTX_CODECS
4800 if (type
== MB_ICONHAND
&& !strlen(text
) && !strlen(title
))
4806 /* these are needed for mss1 */
4809 * \brief this symbol is defined within exp_EH_prolog_dummy
4810 * \param dest jump target
4812 void exp_EH_prolog(void *dest
);
4813 void exp_EH_prolog_dummy(void);
4814 //! just a dummy function that acts a container for the asm section
4815 void exp_EH_prolog_dummy(void) {
4817 // take care, this "function" may not change flags or
4818 // registers besides eax (which is also why we can't use
4819 // exp_EH_prolog_dummy directly)
4820 MANGLE(exp_EH_prolog
)": \n\t"
4823 "mov %esp, %ebp \n\t"
4824 "lea -12(%esp), %esp \n\t"
4829 #include <netinet/in.h>
4830 static WINAPI
inline unsigned long int exphtonl(unsigned long int hostlong
)
4832 // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4833 return htonl(hostlong
);
4836 static WINAPI
inline unsigned long int expntohl(unsigned long int netlong
)
4838 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4839 return ntohl(netlong
);
4842 static char* WINAPI
expSysAllocStringLen(char *pch
, unsigned cch
)
4845 dbgprintf("SysAllocStringLen('%s', %d)\n", pch
, cch
);
4846 str
= malloc(cch
* 2 + sizeof(unsigned) + 2);
4847 *(unsigned *)str
= cch
;
4848 str
+= sizeof(unsigned);
4850 memcpy(str
, pch
, cch
* 2);
4852 str
[cch
* 2 + 1] = 0;
4856 static void WINAPI
expSysFreeString(char *str
)
4859 free(str
- sizeof(unsigned));
4863 static void WINAPI
expVariantInit(void* p
)
4865 printf("InitCommonControls called!\n");
4869 static int WINAPI
expRegisterClassA(const void/*WNDCLASSA*/ *wc
)
4871 dbgprintf("RegisterClassA(%p) => random id\n", wc
);
4872 return time(NULL
); /* be precise ! */
4875 static int WINAPI
expUnregisterClassA(const char *className
, HINSTANCE hInstance
)
4877 dbgprintf("UnregisterClassA(%s, %p) => 0\n", className
, hInstance
);
4881 #ifdef CONFIG_QTX_CODECS
4882 /* should be fixed bcs it's not fully strlen equivalent */
4883 static int expSysStringByteLen(void *str
)
4885 dbgprintf("SysStringByteLen(%p) => %d\n", str
, strlen(str
));
4889 static int expDirectDrawCreate(void)
4891 dbgprintf("DirectDrawCreate(...) => NULL\n");
4896 typedef struct tagPALETTEENTRY
{
4903 typedef struct tagLOGPALETTE
{
4906 PALETTEENTRY palPalEntry
[1];
4909 static HPALETTE WINAPI
expCreatePalette(CONST LOGPALETTE
*lpgpl
)
4914 dbgprintf("CreatePalette(%x) => NULL\n", lpgpl
);
4916 i
= sizeof(LOGPALETTE
)+((lpgpl
->palNumEntries
-1)*sizeof(PALETTEENTRY
));
4918 memcpy((void *)test
, lpgpl
, i
);
4923 static int expCreatePalette(void)
4925 dbgprintf("CreatePalette(...) => NULL\n");
4930 static int WINAPI
expGetClientRect(HWND win
, RECT
*r
)
4932 dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win
, r
);
4933 r
->right
= PSEUDO_SCREEN_WIDTH
;
4935 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
4941 typedef struct tagPOINT
{
4947 static int WINAPI
expClientToScreen(HWND win
, POINT
*p
)
4949 dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win
, p
, p
->x
, p
->y
);
4957 static int WINAPI
expSetThreadIdealProcessor(HANDLE thread
, int proc
)
4959 dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread
, proc
);
4963 static int WINAPI
expMessageBeep(int type
)
4965 dbgprintf("MessageBeep(%d) => 1\n", type
);
4969 static int WINAPI
expDialogBoxParamA(void *inst
, const char *name
,
4970 HWND parent
, void *dialog_func
, void *init_param
)
4972 dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
4973 inst
, name
, name
, parent
, dialog_func
, init_param
);
4977 static void WINAPI
expRegisterClipboardFormatA(const char *name
) {
4978 dbgprintf("RegisterClipboardFormatA(0x%x = %s)\n", name
, name
);
4981 /* needed by imagepower mjpeg2k */
4982 static void *exprealloc(void *ptr
, size_t size
)
4984 dbgprintf("realloc(0x%x, %x)\n", ptr
, size
);
4986 return my_mreq(size
,0);
4988 return my_realloc(ptr
, size
);
4991 /* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
4992 static WIN_BOOL WINAPI
expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn
)
4997 static char * WINAPI
expPathFindExtensionA(const char *path
) {
5002 ext
= strrchr(path
, '.');
5004 ext
= &path
[strlen(path
)];
5006 dbgprintf("PathFindExtensionA(0x%x = %s) => 0x%x, %s\n", path
, path
, ext
, ext
);
5010 static char * WINAPI
expPathFindFileNameA(const char *path
) {
5012 if (!path
|| strlen(path
) < 2)
5015 name
= strrchr(path
- 1, '\\');
5019 dbgprintf("PathFindFileNameA(0x%x = %s) => 0x%x, %s\n", path
, path
, name
, name
);
5023 static double expfloor(double x
)
5025 dbgprintf("floor(%lf)\n", x
);
5029 #define FPU_DOUBLE(var) double var; \
5030 __asm__ volatile( "fstpl %0;fwait" : "=m" (var) : )
5032 static double exp_CIcos(void)
5036 dbgprintf("_CIcos(%lf)\n", x
);
5040 static double exp_CIsin(void)
5044 dbgprintf("_CIsin(%lf)\n", x
);
5048 static double exp_CIsqrt(void)
5052 dbgprintf("_CIsqrt(%lf)\n", x
);
5056 /* Needed by rp8 sipr decoder */
5057 static LPSTR WINAPI
expCharNextA(LPCSTR ptr
)
5059 if (!*ptr
) return (LPSTR
)ptr
;
5060 // dbgprintf("CharNextA(0x%08x), %s\n", ptr, ptr);
5061 return (LPSTR
)(ptr
+ 1);
5064 // Fake implementation, needed by wvc1dmod.dll
5065 static int WINAPI
expPropVariantClear(void *pvar
)
5067 // dbgprintf("PropVariantclear (0x%08x), %s\n", ptr, ptr);
5071 // This define is fake, the real thing is a struct
5072 #define LPDEVMODEA void*
5073 // Dummy implementation, always return 1
5074 // Required for frapsvid.dll 2.8.1, return value does not matter
5075 static WIN_BOOL WINAPI
expEnumDisplaySettingsA(LPCSTR name
,DWORD n
,
5078 dbgprintf("EnumDisplaySettingsA (dummy) => 1\n");
5082 // Fake implementation of _decode_pointer from msvcr80.dll, needed by sirenacm.dll
5083 // NOTE: undocumented function, probably the declaration is not right
5084 static int exp_decode_pointer(void *ptr
)
5086 dbgprintf("_decode_pointer (0x%08x)\n", ptr
);
5090 /* Fake implementation of sdt::_Lockit::_Lockit(void) from msvcp60.dll
5091 Needed by SCLS.DLL */
5092 static int exp_0Lockit_dummy(void)
5094 dbgprintf("0Lockit_dummy (??0_Lockit@std@@QAE@XZ)\n");
5098 /* Fake implementation of sdt::_Lockit::~_Lockit(void) from msvcp60.dll
5099 Needed by SCLS.DLL */
5100 static int exp_1Lockit_dummy(void)
5102 dbgprintf("1Lockit_dummy (??1_Lockit@std@@QAE@XZ)\n");
5106 static void * WINAPI
expEncodePointer(void *p
)
5111 static void * WINAPI
expDecodePointer(void *p
)
5116 static DWORD WINAPI
expGetThreadLocale(void)
5122 * Very incomplete implementation, return an error for almost all cases.
5124 static DWORD WINAPI
expGetLocaleInfoA(DWORD locale
, DWORD lctype
, char* lpLCData
, int cchData
)
5126 if (lctype
== 0x1004) { // LOCALE_IDEFAULTANSICODEPAGE
5128 return cchData
== 0 ? 4 : 0;
5129 strcpy(lpLCData
, "437");
5145 struct exports
* exps
;
5149 {#X, Y, (void*)exp##X},
5151 #define UNDEFF(X, Y) \
5154 struct exports exp_kernel32
[]=
5156 FF(GetVolumeInformationA
,-1)
5157 FF(GetDriveTypeA
,-1)
5158 FF(GetLogicalDriveStringsA
,-1)
5159 FF(IsBadWritePtr
, 357)
5160 FF(IsBadReadPtr
, 354)
5161 FF(IsBadStringPtrW
, -1)
5162 FF(IsBadStringPtrA
, -1)
5163 FF(DisableThreadLibraryCalls
, -1)
5164 FF(CreateThread
, -1)
5165 FF(ResumeThread
, -1)
5166 FF(CreateEventA
, -1)
5167 FF(CreateEventW
, -1)
5170 FF(WaitForSingleObject
, -1)
5171 #ifdef CONFIG_QTX_CODECS
5172 FF(WaitForMultipleObjects
, -1)
5175 FF(GetSystemInfo
, -1)
5183 FF(GetProcessHeap
, -1)
5184 FF(VirtualAlloc
, -1)
5186 FF(InitializeCriticalSection
, -1)
5187 FF(InitializeCriticalSectionAndSpinCount
, -1)
5188 FF(EnterCriticalSection
, -1)
5189 FF(LeaveCriticalSection
, -1)
5190 FF(DeleteCriticalSection
, -1)
5195 FF(GetCurrentThreadId
, -1)
5196 FF(GetCurrentProcess
, -1)
5201 FF(GlobalReAlloc
, -1)
5204 FF(MultiByteToWideChar
, 427)
5205 FF(WideCharToMultiByte
, -1)
5206 FF(GetVersionExA
, -1)
5207 FF(GetVersionExW
, -1)
5208 FF(CreateSemaphoreA
, -1)
5209 FF(CreateSemaphoreW
, -1)
5210 FF(QueryPerformanceCounter
, -1)
5211 FF(QueryPerformanceFrequency
, -1)
5215 FF(GlobalHandle
, -1)
5216 FF(GlobalUnlock
, -1)
5218 FF(LoadResource
, -1)
5219 FF(ReleaseSemaphore
, -1)
5220 FF(CreateMutexA
, -1)
5221 FF(CreateMutexW
, -1)
5222 FF(ReleaseMutex
, -1)
5223 FF(SignalObjectAndWait
, -1)
5224 FF(FindResourceA
, -1)
5225 FF(LockResource
, -1)
5226 FF(FreeResource
, -1)
5227 FF(SizeofResource
, -1)
5229 FF(GetCommandLineA
, -1)
5230 FF(GetEnvironmentStringsW
, -1)
5231 FF(FreeEnvironmentStringsW
, -1)
5232 FF(FreeEnvironmentStringsA
, -1)
5233 FF(GetEnvironmentStrings
, -1)
5234 FF(GetStartupInfoA
, -1)
5235 FF(GetStdHandle
, -1)
5237 #ifdef CONFIG_QTX_CODECS
5238 FF(GetFileAttributesA
, -1)
5240 FF(SetHandleCount
, -1)
5242 FF(GetModuleFileNameA
, -1)
5243 FF(SetUnhandledExceptionFilter
, -1)
5244 FF(LoadLibraryA
, -1)
5245 FF(GetProcAddress
, -1)
5247 FF(CreateFileMappingA
, -1)
5248 FF(OpenFileMappingA
, -1)
5249 FF(MapViewOfFile
, -1)
5250 FF(UnmapViewOfFile
, -1)
5252 FF(GetModuleHandleA
, -1)
5253 FF(GetModuleHandleW
, -1)
5254 FF(GetProfileIntA
, -1)
5255 FF(GetPrivateProfileIntA
, -1)
5256 FF(GetPrivateProfileStringA
, -1)
5257 FF(WritePrivateProfileStringA
, -1)
5258 FF(GetLastError
, -1)
5259 FF(SetLastError
, -1)
5260 FF(InterlockedIncrement
, -1)
5261 FF(InterlockedDecrement
, -1)
5262 FF(GetTimeZoneInformation
, -1)
5263 FF(OutputDebugStringA
, -1)
5264 FF(GetLocalTime
, -1)
5265 FF(GetSystemTime
, -1)
5266 FF(GetSystemTimeAsFileTime
, -1)
5267 FF(GetEnvironmentVariableA
, -1)
5268 FF(SetEnvironmentVariableA
, -1)
5269 FF(RtlZeroMemory
,-1)
5270 FF(RtlMoveMemory
,-1)
5271 FF(RtlFillMemory
,-1)
5273 FF(FindFirstFileA
,-1)
5274 FF(FindNextFileA
,-1)
5276 FF(FileTimeToLocalFileTime
,-1)
5280 FF(SetFilePointer
,-1)
5281 FF(GetTempFileNameA
,-1)
5283 FF(GetSystemDirectoryA
,-1)
5284 FF(GetWindowsDirectoryA
,-1)
5285 #ifdef CONFIG_QTX_CODECS
5286 FF(GetCurrentDirectoryA
,-1)
5287 FF(SetCurrentDirectoryA
,-1)
5288 FF(CreateDirectoryA
,-1)
5290 FF(GetShortPathNameA
,-1)
5291 FF(GetFullPathNameA
,-1)
5292 FF(SetErrorMode
, -1)
5293 FF(IsProcessorFeaturePresent
, -1)
5294 FF(IsDebuggerPresent
, -1)
5295 FF(GetProcessAffinityMask
, -1)
5296 FF(InterlockedExchange
, -1)
5297 FF(InterlockedCompareExchange
, -1)
5304 FF(GetProcessVersion
,-1)
5305 FF(GetCurrentThread
,-1)
5308 FF(DuplicateHandle
,-1)
5309 FF(GetTickCount
, -1)
5310 FF(SetThreadAffinityMask
,-1)
5311 FF(GetCurrentProcessId
,-1)
5312 FF(GlobalMemoryStatus
,-1)
5313 FF(GetThreadPriority
,-1)
5314 FF(SetThreadPriority
,-1)
5315 FF(TerminateProcess
,-1)
5317 {"LoadLibraryExA", -1, (void*)&LoadLibraryExA
},
5318 FF(SetThreadIdealProcessor
,-1)
5319 FF(SetProcessAffinityMask
, -1)
5320 FF(EncodePointer
, -1)
5321 FF(DecodePointer
, -1)
5322 FF(GetThreadLocale
, -1)
5323 FF(GetLocaleInfoA
, -1)
5324 UNDEFF(FlsAlloc
, -1)
5325 UNDEFF(FlsGetValue
, -1)
5326 UNDEFF(FlsSetValue
, -1)
5330 struct exports exp_msvcrt
[]={
5336 {"??3@YAXPAX@Z", -1, expdelete
},
5337 {"??2@YAPAXI@Z", -1, expnew
},
5338 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5339 {"_winver",-1,(void*)&_winver
},
5380 /* needed by frapsvid.dll */
5381 {"strstr",-1,(char *)&strstr
},
5382 {"qsort",-1,(void *)&qsort
},
5385 {"ceil",-1,(void*)&ceil
},
5386 /* needed by imagepower mjpeg2k */
5387 {"clock",-1,(void*)&clock
},
5388 {"memchr",-1,(void*)&memchr
},
5389 {"vfprintf",-1,(void*)&vfprintf
},
5390 // {"realloc",-1,(void*)&realloc},
5392 {"puts",-1,(void*)&puts
}
5394 struct exports exp_winmm
[]={
5395 FF(GetDriverModuleHandle
, -1)
5397 FF(DefDriverProc
, -1)
5400 FF(timeGetDevCaps
, -1)
5401 FF(timeBeginPeriod
, -1)
5402 #ifdef CONFIG_QTX_CODECS
5403 FF(timeEndPeriod
, -1)
5404 FF(waveOutGetNumDevs
, -1)
5407 struct exports exp_psapi
[]={
5408 FF(GetModuleBaseNameA
, -1)
5410 struct exports exp_user32
[]={
5415 FF(GetDesktopWindow
, -1)
5421 #ifdef CONFIG_QTX_CODECS
5424 FF(RegisterWindowMessageA
,-1)
5425 FF(GetSystemMetrics
,-1)
5427 FF(GetSysColorBrush
,-1)
5431 FF(RegisterClassA
, -1)
5432 FF(UnregisterClassA
, -1)
5433 #ifdef CONFIG_QTX_CODECS
5434 FF(GetWindowRect
, -1)
5435 FF(MonitorFromWindow
, -1)
5436 FF(MonitorFromRect
, -1)
5437 FF(MonitorFromPoint
, -1)
5438 FF(EnumDisplayMonitors
, -1)
5439 FF(GetMonitorInfoA
, -1)
5440 FF(EnumDisplayDevicesA
, -1)
5441 FF(GetClientRect
, -1)
5442 FF(ClientToScreen
, -1)
5443 FF(IsWindowVisible
, -1)
5444 FF(GetActiveWindow
, -1)
5445 FF(GetClassNameA
, -1)
5446 FF(GetClassInfoA
, -1)
5447 FF(GetWindowLongA
, -1)
5449 FF(GetWindowThreadProcessId
, -1)
5450 FF(CreateWindowExA
, -1)
5453 FF(DialogBoxParamA
, -1)
5454 FF(RegisterClipboardFormatA
, -1)
5456 FF(EnumDisplaySettingsA
, -1)
5458 struct exports exp_advapi32
[]={
5460 FF(RegCreateKeyA
, -1)
5461 FF(RegCreateKeyExA
, -1)
5462 FF(RegEnumKeyExA
, -1)
5463 FF(RegEnumValueA
, -1)
5465 FF(RegOpenKeyExA
, -1)
5466 FF(RegQueryValueExA
, -1)
5467 FF(RegSetValueExA
, -1)
5468 FF(RegQueryInfoKeyA
, -1)
5470 struct exports exp_gdi32
[]={
5471 FF(CreateCompatibleDC
, -1)
5474 FF(DeleteObject
, -1)
5475 FF(GetDeviceCaps
, -1)
5476 FF(GetSystemPaletteEntries
, -1)
5477 #ifdef CONFIG_QTX_CODECS
5478 FF(CreatePalette
, -1)
5480 FF(CreateRectRgn
, -1)
5483 struct exports exp_version
[]={
5484 FF(GetFileVersionInfoSizeA
, -1)
5486 struct exports exp_ole32
[]={
5487 FF(CoCreateFreeThreadedMarshaler
,-1)
5488 FF(CoCreateInstance
, -1)
5489 FF(CoInitialize
, -1)
5490 FF(CoInitializeEx
, -1)
5491 FF(CoUninitialize
, -1)
5492 FF(CoTaskMemAlloc
, -1)
5493 FF(CoTaskMemFree
, -1)
5494 FF(StringFromGUID2
, -1)
5495 FF(PropVariantClear
, -1)
5497 // do we really need crtdll ???
5498 // msvcrt is the correct place probably...
5499 struct exports exp_crtdll
[]={
5503 struct exports exp_comctl32
[]={
5504 FF(StringFromGUID2
, -1)
5505 FF(InitCommonControls
, 17)
5506 #ifdef CONFIG_QTX_CODECS
5507 FF(CreateUpDownControl
, 16)
5510 struct exports exp_wsock32
[]={
5514 struct exports exp_msdmo
[]={
5515 FF(memcpy
, -1) // just test
5516 FF(MoCopyMediaType
, -1)
5517 FF(MoCreateMediaType
, -1)
5518 FF(MoDeleteMediaType
, -1)
5519 FF(MoDuplicateMediaType
, -1)
5520 FF(MoFreeMediaType
, -1)
5521 FF(MoInitMediaType
, -1)
5523 struct exports exp_oleaut32
[]={
5524 FF(SysAllocStringLen
, 4)
5525 FF(SysFreeString
, 6)
5527 #ifdef CONFIG_QTX_CODECS
5528 FF(SysStringByteLen
, 149)
5534 vma: Hint/Ord Member-Name
5539 2305e 167 _adjust_fdiv
5542 22ffc 176 _beginthreadex
5544 2300e 85 __CxxFrameHandler
5548 struct exports exp_pncrt
[]={
5549 FF(malloc
, -1) // just test
5550 FF(free
, -1) // just test
5551 FF(fprintf
, -1) // just test
5552 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5555 {"??3@YAXPAX@Z", -1, expdelete
},
5556 {"??2@YAPAXI@Z", -1, expnew
},
5567 #ifdef CONFIG_QTX_CODECS
5568 struct exports exp_ddraw
[]={
5569 FF(DirectDrawCreate
, -1)
5573 struct exports exp_comdlg32
[]={
5574 FF(GetOpenFileNameA
, -1)
5577 struct exports exp_shlwapi
[]={
5578 FF(PathFindExtensionA
, -1)
5579 FF(PathFindFileNameA
, -1)
5582 struct exports exp_msvcr80
[]={
5590 FF(_decode_pointer
, -1)
5591 /* needed by KGV1-VFW.dll */
5592 {"??2@YAPAXI@Z", -1, expnew
},
5593 {"??3@YAXPAX@Z", -1, expdelete
}
5596 struct exports exp_msvcp60
[]={
5597 {"??0_Lockit@std@@QAE@XZ", -1, exp_0Lockit_dummy
},
5598 {"??1_Lockit@std@@QAE@XZ", -1, exp_1Lockit_dummy
}
5602 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5604 struct libs libraries
[]={
5622 #ifdef CONFIG_QTX_CODECS
5631 static WIN_BOOL WINAPI
ext_stubs(void)
5633 // NOTE! these magic values will be replaced at runtime, make sure
5634 // add_stub can still find them if you change them.
5635 volatile int idx
= 0x0deadabc;
5636 // make sure gcc does not do eip-relative call or something like that
5637 void (* volatile my_printf
)(char *, char *) = (void *)0xdeadfbcd;
5638 my_printf("Called unk_%s\n", export_names
[idx
]);
5642 #define MAX_STUB_SIZE 0x60
5643 #define MAX_NUM_STUBS 200
5645 static char *extcode
= NULL
;
5647 static void* add_stub(void)
5651 // generated code in runtime!
5654 extcode
= mmap_anon(NULL
, MAX_NUM_STUBS
* MAX_STUB_SIZE
,
5655 PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
, 0);
5656 answ
= extcode
+ pos
* MAX_STUB_SIZE
;
5657 if (pos
>= MAX_NUM_STUBS
) {
5658 printf("too many stubs, expect crash\n");
5661 memcpy(answ
, ext_stubs
, MAX_STUB_SIZE
);
5662 for (i
= 0; i
< MAX_STUB_SIZE
- 3; i
++) {
5663 int *magic
= (int *)(answ
+ i
);
5664 if (*magic
== 0x0deadabc) {
5668 if (*magic
== 0xdeadfbcd) {
5669 *magic
= (intptr_t)printf
;
5674 printf("magic code not found in ext_subs, expect crash\n");
5681 void* LookupExternal(const char* library
, int ordinal
)
5686 printf("ERROR: library=0\n");
5687 return (void*)ext_unknown
;
5689 // printf("%x %x\n", &unk_exp1, &unk_exp2);
5691 dbgprintf("External func %s:%d\n", library
, ordinal
);
5693 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5695 if(strcasecmp(library
, libraries
[i
].name
))
5697 for(j
=0; j
<libraries
[i
].length
; j
++)
5699 if(ordinal
!=libraries
[i
].exps
[j
].id
)
5701 //printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5702 return libraries
[i
].exps
[j
].func
;
5706 #ifndef LOADLIB_TRY_NATIVE
5707 /* hack for truespeech and vssh264*/
5708 if (!strcmp(library
, "tsd32.dll") || !strcmp(library
,"vssh264dec.dll") || !strcmp(library
,"LCMW2.dll") || !strcmp(library
,"VDODEC32.dll"))
5710 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5716 hand
= LoadLibraryA(library
);
5719 wm
= MODULE32_LookupHMODULE(hand
);
5725 func
= PE_FindExportedFunction(wm
, (LPCSTR
) ordinal
, 0);
5728 printf("No such ordinal in external dll\n");
5729 FreeLibrary((int)hand
);
5733 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5739 if(pos
>150)return 0;
5740 snprintf(export_names
[pos
], sizeof(export_names
[pos
]), "%s:%d", library
, ordinal
);
5744 void* LookupExternalByName(const char* library
, const char* name
)
5747 // return (void*)ext_unknown;
5750 printf("ERROR: library=0\n");
5751 return (void*)ext_unknown
;
5753 if((unsigned long)name
<=0xffff)
5755 return LookupExternal(library
, (int)name
);
5757 dbgprintf("External func %s:%s\n", library
, name
);
5758 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5760 if(strcasecmp(library
, libraries
[i
].name
))
5762 for(j
=0; j
<libraries
[i
].length
; j
++)
5764 if(strcmp(name
, libraries
[i
].exps
[j
].name
))
5766 if((unsigned int)(libraries
[i
].exps
[j
].func
) == -1)
5767 return NULL
; //undefined func
5768 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5769 return libraries
[i
].exps
[j
].func
;
5773 #ifndef LOADLIB_TRY_NATIVE
5774 /* hack for vss h264 */
5775 if (!strcmp(library
,"vssh264core.dll") || !strcmp(library
,"3ivx.dll"))
5777 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5783 hand
= LoadLibraryA(library
);
5786 wm
= MODULE32_LookupHMODULE(hand
);
5792 func
= PE_FindExportedFunction(wm
, name
, 0);
5795 printf("No such name in external dll\n");
5796 FreeLibrary((int)hand
);
5800 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5806 if(pos
>150)return 0;// to many symbols
5807 snprintf(export_names
[pos
], sizeof(export_names
[pos
]), "%s", name
);
5811 void my_garbagecollection(void)
5814 int unfree
= 0, unfreecnt
= 0;
5820 alloc_header
* mem
= last_alloc
+ 1;
5821 unfree
+= my_size(mem
);
5823 if (my_release(mem
) != 0)
5824 // avoid endless loop when memory is trashed
5825 if (--max_fatal
< 0)
5828 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree
, unfreecnt
, last_alloc
, alccnt
);
5831 pthread_mutex_lock(&list_lock
);
5833 pthread_mutex_unlock(&list_lock
);