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>
68 #include <sys/timeb.h>
73 #ifdef HAVE_SYS_MMAN_H
76 #include "osdep/mmap.h"
78 #include "osdep/mmap_anon.h"
79 #include "libavutil/avstring.h"
81 static void do_cpuid(unsigned int ax
, unsigned int *regs
)
85 "pushl %%ebx; pushl %%ecx; pushl %%edx;"
91 "popl %%edx; popl %%ecx; popl %%ebx;"
93 : "0" (ax
), "S" (regs
)
96 static unsigned int c_localcount_tsc(void)
108 static void c_longcount_tsc(long long* z
)
113 "movl %%eax, %%ebx\n\t"
115 "movl %%eax, 0(%%ebx)\n\t"
116 "movl %%edx, 4(%%ebx)\n\t"
122 static unsigned int c_localcount_notsc(void)
127 gettimeofday(&tv
, 0);
128 return limit
*tv
.tv_usec
;
130 static void c_longcount_notsc(long long* z
)
133 unsigned long long result
;
137 gettimeofday(&tv
, 0);
140 result
+=limit
*tv
.tv_usec
;
143 static unsigned int localcount_stub(void);
144 static void longcount_stub(long long*);
145 static unsigned int (*localcount
)()=localcount_stub
;
146 static void (*longcount
)(long long*)=longcount_stub
;
148 static pthread_mutex_t memmut
= PTHREAD_MUTEX_INITIALIZER
;
150 static unsigned int localcount_stub(void)
152 unsigned int regs
[4];
154 if ((regs
[3] & 0x00000010) != 0)
156 localcount
=c_localcount_tsc
;
157 longcount
=c_longcount_tsc
;
161 localcount
=c_localcount_notsc
;
162 longcount
=c_longcount_notsc
;
166 static void longcount_stub(long long* z
)
168 unsigned int regs
[4];
170 if ((regs
[3] & 0x00000010) != 0)
172 localcount
=c_localcount_tsc
;
173 longcount
=c_longcount_tsc
;
177 localcount
=c_localcount_notsc
;
178 longcount
=c_longcount_notsc
;
184 int LOADER_DEBUG
=1; // active only if compiled with -DDETAILED_OUT
185 //#define DETAILED_OUT
186 static inline void dbgprintf(char* fmt
, ...)
194 f
=fopen("./log", "a");
199 vfprintf(f
, fmt
, va
);
206 if ( mp_msg_test(MSGT_WIN32
,MSGL_DBG3
) )
212 // mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va);
219 char export_names
[300][32]={
224 //#define min(x,y) ((x)<(y)?(x):(y))
226 void destroy_event(void* event
);
229 typedef struct th_list_t
{
232 struct th_list_t
* next
;
233 struct th_list_t
* prev
;
237 // have to be cleared by GARBAGE COLLECTOR
238 //static unsigned char* heap=NULL;
239 //static int heap_counter=0;
240 static tls_t
* g_tls
=NULL
;
241 static th_list
* list
=NULL
;
242 static pthread_mutex_t list_lock
= PTHREAD_MUTEX_INITIALIZER
;
245 static void test_heap(void)
250 while(offset
<heap_counter
)
252 if(*(int*)(heap
+offset
)!=0x433476)
254 printf("Heap corruption at address %d\n", offset
);
257 offset
+=8+*(int*)(heap
+offset
+4);
259 for(;offset
<min(offset
+1000, 20000000); offset
++)
260 if(heap
[offset
]!=0xCC)
262 printf("Free heap corruption at address %d\n", offset
);
270 static void* my_mreq(int size
, int to_zero
)
274 if(test
%10==0)printf("Memory: %d bytes allocated\n", heap_counter
);
278 heap
=malloc(20000000);
279 memset(heap
, 0xCC,20000000);
283 printf("No enough memory\n");
286 if(heap_counter
+size
>20000000)
288 printf("No enough memory\n");
291 *(int*)(heap
+heap_counter
)=0x433476;
293 *(int*)(heap
+heap_counter
)=size
;
295 printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size
, heap_counter
-8, heap_counter
, heap_counter
+size
);
297 memset(heap
+heap_counter
, 0, size
);
299 memset(heap
+heap_counter
, 0xcc, size
); // make crash reproducable
301 return heap
+heap_counter
-size
;
303 static int my_release(char* memory
)
308 printf("ERROR: free(0)\n");
311 if(*(int*)(memory
-8)!=0x433476)
313 printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
316 printf("Freed %d bytes of memory\n", *(int*)(memory
-4));
317 // memset(memory-8, *(int*)(memory-4), 0xCC);
323 typedef struct alloc_header_t alloc_header
;
324 struct alloc_header_t
326 // let's keep allocated data 16 byte aligned
338 static alloc_header
* last_alloc
= NULL
;
339 static int alccnt
= 0;
342 #define AREATYPE_CLIENT 0
343 #define AREATYPE_EVENT 1
344 #define AREATYPE_MUTEX 2
345 #define AREATYPE_COND 3
346 #define AREATYPE_CRITSECT 4
348 /* -- critical sections -- */
352 pthread_mutex_t mutex
;
353 pthread_cond_t unlocked
;
358 void* mreq_private(int size
, int to_zero
, int type
);
359 void* mreq_private(int size
, int to_zero
, int type
)
361 int nsize
= size
+ sizeof(alloc_header
);
362 alloc_header
* header
= malloc(nsize
);
366 memset(header
, 0, nsize
);
368 pthread_mutex_lock(&memmut
);
371 last_alloc
->next
= header
; /* set next */
374 header
->prev
= last_alloc
;
378 pthread_mutex_unlock(&memmut
);
380 header
->deadbeef
= 0xdeadbeef;
384 //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt);
388 static int my_release(void* memory
)
390 alloc_header
* header
= (alloc_header
*) memory
- 1;
392 alloc_header
* prevmem
;
393 alloc_header
* nextmem
;
398 if (header
->deadbeef
!= (long) 0xdeadbeef)
400 dbgprintf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
404 pthread_mutex_lock(&memmut
);
409 destroy_event(memory
);
412 pthread_cond_destroy((pthread_cond_t
*)memory
);
415 pthread_mutex_destroy((pthread_mutex_t
*)memory
);
417 case AREATYPE_CRITSECT
:
418 pthread_mutex_destroy(&((struct CRITSECT
*)memory
)->mutex
);
421 //memset(memory, 0xcc, header->size);
425 header
->deadbeef
= 0;
426 prevmem
= header
->prev
;
427 nextmem
= header
->next
;
430 prevmem
->next
= nextmem
;
432 nextmem
->prev
= prevmem
;
434 if (header
== last_alloc
)
435 last_alloc
= prevmem
;
439 pthread_mutex_unlock(&memmut
);
441 //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt);
446 //memset(header + 1, 0xcc, header->size);
452 static inline void* my_mreq(int size
, int to_zero
)
454 return mreq_private(size
, to_zero
, AREATYPE_CLIENT
);
457 static int my_size(void* memory
)
459 if(!memory
) return 0;
460 return ((alloc_header
*)memory
)[-1].size
;
463 static void* my_realloc(void* memory
, int size
)
468 return my_mreq(size
, 0);
469 osize
= my_size(memory
);
472 ans
= my_mreq(size
, 0);
473 memcpy(ans
, memory
, osize
);
481 * WINE API - native implementation for several win32 libraries
485 static int WINAPI
ext_unknown(void)
487 printf("Unknown func called\n");
491 static int WINAPI
expGetVolumeInformationA( const char *root
, char *label
,
492 unsigned int label_len
, unsigned int *serial
,
493 unsigned int *filename_len
,unsigned int *flags
,
494 char *fsname
, unsigned int fsname_len
)
496 dbgprintf("GetVolumeInformationA( %s, 0x%x, %ld, 0x%x, 0x%x, 0x%x, 0x%x, %ld) => 1\n",
497 root
,label
,label_len
,serial
,filename_len
,flags
,fsname
,fsname_len
);
498 //hack Do not return any real data - do nothing
502 static unsigned int WINAPI
expGetDriveTypeA( const char *root
)
504 dbgprintf("GetDriveTypeA( %s ) => %d\n",root
,DRIVE_FIXED
);
505 // hack return as Fixed Drive Type
509 static unsigned int WINAPI
expGetLogicalDriveStringsA( unsigned int len
, char *buffer
)
511 dbgprintf("GetLogicalDriveStringsA(%d, 0x%x) => 4\n",len
,buffer
);
512 // hack only have one drive c:\ in this hack
518 return 4; // 1 drive * 4 bytes (includes null)
522 static int WINAPI
expIsBadWritePtr(void* ptr
, unsigned int count
)
524 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
525 dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
528 static int WINAPI
expIsBadReadPtr(void* ptr
, unsigned int count
)
530 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
531 dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
534 static int WINAPI
expDisableThreadLibraryCalls(int module
)
536 dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module
);
540 static HMODULE WINAPI
expGetDriverModuleHandle(DRVR
* pdrv
)
546 result
=pdrv
->hDriverModule
;
547 dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv
, result
);
551 #define MODULE_HANDLE_kernel32 ((HMODULE)0x120)
552 #define MODULE_HANDLE_user32 ((HMODULE)0x121)
553 #ifdef CONFIG_QTX_CODECS
554 #define MODULE_HANDLE_wininet ((HMODULE)0x122)
555 #define MODULE_HANDLE_ddraw ((HMODULE)0x123)
556 #define MODULE_HANDLE_advapi32 ((HMODULE)0x124)
558 #define MODULE_HANDLE_comdlg32 ((HMODULE)0x125)
559 #define MODULE_HANDLE_msvcrt ((HMODULE)0x126)
560 #define MODULE_HANDLE_ole32 ((HMODULE)0x127)
561 #define MODULE_HANDLE_winmm ((HMODULE)0x128)
562 #define MODULE_HANDLE_psapi ((HMODULE)0x129)
564 // Fake PE header, since some software (and the Microsoft CRT v8 and newer)
565 // assume GetModuleHandle(NULL) returns a pointer to a PE header.
566 // We simulate a very simple header with only one section.
568 // NOTE: If you have a section called .mixcrt, the Microsoft CRT will assume
569 // it's running in a POSIX binary, and stop using EncodePointer/DecodePointer.
570 static const struct {
571 IMAGE_DOS_HEADER doshdr
;
572 IMAGE_NT_HEADERS nthdr
;
573 IMAGE_SECTION_HEADER opthdr
;
574 } __attribute__((__packed__
)) mp_exe
= {
575 .doshdr
.e_lfanew
= sizeof(IMAGE_DOS_HEADER
),
576 .nthdr
.FileHeader
.NumberOfSections
= 1,
577 .nthdr
.FileHeader
.SizeOfOptionalHeader
=
578 sizeof(IMAGE_NT_HEADERS
) - FIELD_OFFSET(IMAGE_NT_HEADERS
, OptionalHeader
), /* 0xe0 */
579 .opthdr
.Name
= ".text"
582 static HMODULE WINAPI
expGetModuleHandleA(const char* name
)
587 result
=(HMODULE
)&mp_exe
.doshdr
;
590 wm
=MODULE_FindModule(name
);
593 result
=(HMODULE
)(wm
->module
);
597 if(name
&& (strcasecmp(name
, "kernel32")==0 || !strcasecmp(name
, "kernel32.dll")))
598 result
=MODULE_HANDLE_kernel32
;
599 #ifdef CONFIG_QTX_CODECS
600 if(name
&& strcasecmp(name
, "user32")==0)
601 result
=MODULE_HANDLE_user32
;
604 dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name
, result
);
608 static HMODULE WINAPI
expGetModuleHandleW(const uint16_t* name
)
613 if (*name
> 256 || pos
>= sizeof(aname
) - 1)
615 aname
[pos
++] = *name
++;
618 return expGetModuleHandleA(aname
);
621 static void* WINAPI
expCreateThread(void* pSecAttr
, long dwStackSize
,
622 void* lpStartAddress
, void* lpParameter
,
623 long dwFlags
, long* dwThreadId
)
626 // printf("CreateThread:");
627 pth
= (pthread_t
*) my_mreq(sizeof(pthread_t
), 0);
628 pthread_create(pth
, NULL
, (void*(*)(void*))lpStartAddress
, lpParameter
);
630 printf( "WARNING: CreateThread flags not supported\n");
632 *dwThreadId
=(long)pth
;
633 pthread_mutex_lock(&list_lock
);
636 list
=my_mreq(sizeof(th_list
), 1);
637 list
->next
=list
->prev
=NULL
;
641 list
->next
=my_mreq(sizeof(th_list
), 0);
642 list
->next
->prev
=list
;
643 list
->next
->next
=NULL
;
647 pthread_mutex_unlock(&list_lock
);
648 dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
649 pSecAttr
, dwStackSize
, lpStartAddress
, lpParameter
, dwFlags
, dwThreadId
, pth
);
653 static DWORD WINAPI
expResumeThread(HANDLE hThread
)
656 dbgprintf("ResumeThread(0x%x) => 0x%x\n", hThread
, ret
);
673 struct mutex_list_t
* next
;
674 struct mutex_list_t
* prev
;
676 typedef struct mutex_list_t mutex_list
;
677 static mutex_list
* mlist
=NULL
;
678 static pthread_mutex_t mlist_lock
= PTHREAD_MUTEX_INITIALIZER
;
680 void destroy_event(void* event
)
682 pthread_mutex_lock(&mlist_lock
);
683 mutex_list
* pp
=mlist
;
684 // printf("garbage collector: destroy_event(%x)\n", event);
687 if(pp
==(mutex_list
*)event
)
690 pp
->next
->prev
=pp
->prev
;
692 pp
->prev
->next
=pp
->next
;
693 if(mlist
==(mutex_list
*)event
)
699 printf("%x => ", pp);
704 pthread_mutex_unlock(&mlist_lock
);
709 pthread_mutex_unlock(&mlist_lock
);
712 static void* WINAPI
expCreateEventA(void* pSecAttr
, char bManualReset
,
713 char bInitialState
, const char* name
)
723 printf("%x => ", pp);
728 pthread_mutex_lock(&mlist_lock
);
731 mutex_list
* pp
=mlist
;
735 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==0))
737 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
738 pSecAttr
, bManualReset
, bInitialState
, name
, name
, pp
->pm
);
739 pthread_mutex_unlock(&mlist_lock
);
742 }while((pp
=pp
->prev
) != NULL
);
744 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
745 pthread_mutex_init(pm
, NULL
);
746 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
747 pthread_cond_init(pc
, NULL
);
750 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
751 mlist
->next
=mlist
->prev
=NULL
;
755 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
756 mlist
->next
->prev
=mlist
;
757 mlist
->next
->next
=NULL
;
760 mlist
->type
=0; /* Type Event */
763 mlist
->state
=bInitialState
;
764 mlist
->reset
=!bManualReset
;
766 strncpy(mlist
->name
, name
, 127);
770 dbgprintf("ERROR::: CreateEventA failure\n");
773 pthread_mutex_lock(pm);
776 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
777 pSecAttr
, bManualReset
, bInitialState
, name
, name
, mlist
);
779 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
780 pSecAttr
, bManualReset
, bInitialState
, mlist
);
782 pthread_mutex_unlock(&mlist_lock
);
786 static void* WINAPI
expCreateEventW(void* pSecAttr
, char bManualReset
,
787 char bInitialState
, const WCHAR
* name
)
789 char ascii_name
[256];
792 WideCharToMultiByte(65001, 0x0, name
, -1, ascii_name
, 256, NULL
, NULL
);
795 return expCreateEventA(pSecAttr
, bManualReset
, bInitialState
, aname
);
798 static void* WINAPI
expSetEvent(void* event
)
800 mutex_list
*ml
= (mutex_list
*)event
;
801 dbgprintf("SetEvent(%x) => 0x1\n", event
);
802 pthread_mutex_lock(ml
->pm
);
803 if (ml
->state
== 0) {
805 pthread_cond_signal(ml
->pc
);
807 pthread_mutex_unlock(ml
->pm
);
811 static void* WINAPI
expResetEvent(void* event
)
813 mutex_list
*ml
= (mutex_list
*)event
;
814 dbgprintf("ResetEvent(0x%x) => 0x1\n", event
);
815 pthread_mutex_lock(ml
->pm
);
817 pthread_mutex_unlock(ml
->pm
);
822 static void* WINAPI
expWaitForSingleObject(void* object
, int duration
)
824 mutex_list
*ml
= (mutex_list
*)object
;
825 // FIXME FIXME FIXME - this value is sometime unititialize !!!
826 int ret
= WAIT_FAILED
;
829 if(object
== (void*)0xcfcf9898)
832 From GetCurrentThread() documentation:
833 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.
835 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.
837 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.
839 dbgprintf("WaitForSingleObject(thread_handle) called\n");
840 return (void*)WAIT_FAILED
;
842 dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object
, duration
);
844 // See if this is a thread.
845 pthread_mutex_lock(&list_lock
);
847 while (tp
&& (tp
->thread
!= object
))
849 pthread_mutex_unlock(&list_lock
);
851 if (pthread_join(*(pthread_t
*)object
, NULL
) == 0) {
852 return (void*)WAIT_OBJECT_0
;
854 return (void*)WAIT_FAILED
;
858 // loop below was slightly fixed - its used just for checking if
859 // this object really exists in our list
862 pthread_mutex_lock(&mlist_lock
);
864 while (pp
&& (pp
->pm
!= ml
->pm
))
866 pthread_mutex_unlock(&mlist_lock
);
868 dbgprintf("WaitForSingleObject: NotFound\n");
872 pthread_mutex_lock(ml
->pm
);
876 if (duration
== 0) { /* Check Only */
877 if (ml
->state
== 1) ret
= WAIT_OBJECT_0
;
878 else ret
= WAIT_FAILED
;
880 if (duration
== -1) { /* INFINITE */
882 pthread_cond_wait(ml
->pc
,ml
->pm
);
887 if (duration
> 0) { /* Timed Wait */
888 struct timespec abstime
;
890 gettimeofday(&now
, 0);
891 abstime
.tv_sec
= now
.tv_sec
+ (now
.tv_usec
+duration
)/1000000;
892 abstime
.tv_nsec
= ((now
.tv_usec
+duration
)%1000000)*1000;
894 ret
=pthread_cond_timedwait(ml
->pc
,ml
->pm
,&abstime
);
895 if (ret
== ETIMEDOUT
) ret
= WAIT_TIMEOUT
;
896 else ret
= WAIT_OBJECT_0
;
901 case 1: /* Semaphore */
903 if(ml
->semaphore
==0) ret
= WAIT_FAILED
;
909 if (duration
== -1) {
910 if (ml
->semaphore
==0)
911 pthread_cond_wait(ml
->pc
,ml
->pm
);
918 if(ml
->lock_count
> 0 && ml
->owner
!= pthread_self()) ret
= WAIT_FAILED
;
921 ml
->owner
= pthread_self();
925 if (duration
== -1) {
926 if (ml
->lock_count
> 0 && ml
->owner
!= pthread_self()) {
927 pthread_cond_wait(ml
->pc
,ml
->pm
);
930 ml
->owner
= pthread_self();
935 pthread_mutex_unlock(ml
->pm
);
937 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object
,duration
,ml
,ret
);
941 #ifdef CONFIG_QTX_CODECS
942 static void* WINAPI
expWaitForMultipleObjects(int count
, const void** objects
,
943 int WaitAll
, int duration
)
949 dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
950 count
, objects
, WaitAll
, duration
);
952 for (i
= 0; i
< count
; i
++)
954 object
= (void *)objects
[i
];
955 ret
= expWaitForSingleObject(object
, duration
);
957 dbgprintf("WaitAll flag not yet supported...\n");
964 static void WINAPI
expExitThread(int retcode
)
966 dbgprintf("ExitThread(%d)\n", retcode
);
967 pthread_exit(&retcode
);
971 static int pf_set
= 0;
972 static BYTE PF
[64] = {0,};
974 static void DumpSystemInfo(const SYSTEM_INFO
* si
)
976 dbgprintf(" Processor architecture %d\n", si
->u
.s
.wProcessorArchitecture
);
977 dbgprintf(" Page size: %d\n", si
->dwPageSize
);
978 dbgprintf(" Minimum app address: %d\n", si
->lpMinimumApplicationAddress
);
979 dbgprintf(" Maximum app address: %d\n", si
->lpMaximumApplicationAddress
);
980 dbgprintf(" Active processor mask: 0x%x\n", si
->dwActiveProcessorMask
);
981 dbgprintf(" Number of processors: %d\n", si
->dwNumberOfProcessors
);
982 dbgprintf(" Processor type: 0x%x\n", si
->dwProcessorType
);
983 dbgprintf(" Allocation granularity: 0x%x\n", si
->dwAllocationGranularity
);
984 dbgprintf(" Processor level: 0x%x\n", si
->wProcessorLevel
);
985 dbgprintf(" Processor revision: 0x%x\n", si
->wProcessorRevision
);
988 static void WINAPI
expGetSystemInfo(SYSTEM_INFO
* si
)
990 /* FIXME: better values for the two entries below... */
991 static int cache
= 0;
992 static SYSTEM_INFO cachedsi
;
993 dbgprintf("GetSystemInfo(%p) =>\n", si
);
998 memset(PF
,0,sizeof(PF
));
1001 cachedsi
.u
.s
.wProcessorArchitecture
= PROCESSOR_ARCHITECTURE_INTEL
;
1002 cachedsi
.dwPageSize
= getpagesize();
1004 /* FIXME: better values for the two entries below... */
1005 cachedsi
.lpMinimumApplicationAddress
= (void *)0x00000000;
1006 cachedsi
.lpMaximumApplicationAddress
= (void *)0x7FFFFFFF;
1007 cachedsi
.dwActiveProcessorMask
= 1;
1008 cachedsi
.dwNumberOfProcessors
= 1;
1009 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1010 cachedsi
.dwAllocationGranularity
= 0x10000;
1011 cachedsi
.wProcessorLevel
= 5; /* pentium */
1012 cachedsi
.wProcessorRevision
= 0x0101;
1014 /* mplayer's way to detect PF's */
1016 #include "cpudetect.h"
1018 if (gCpuCaps
.hasMMX
)
1019 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1020 if (gCpuCaps
.hasSSE
)
1021 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1022 if (gCpuCaps
.hasSSE2
)
1023 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1024 if (gCpuCaps
.has3DNow
)
1025 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1027 if (gCpuCaps
.cpuType
== 4)
1029 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1030 cachedsi
.wProcessorLevel
= 4;
1032 else if (gCpuCaps
.cpuType
>= 5)
1034 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1035 cachedsi
.wProcessorLevel
= 5;
1039 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1040 cachedsi
.wProcessorLevel
= 3;
1042 cachedsi
.wProcessorRevision
= gCpuCaps
.cpuStepping
;
1043 cachedsi
.dwNumberOfProcessors
= 1; /* hardcoded */
1046 /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
1047 fdiv_bug and fpu emulation flags -- alex/MPlayer */
1052 FILE *f
= fopen ("/proc/cpuinfo", "r");
1056 mp_msg(MSGT_WIN32
, MSGL_WARN
, "expGetSystemInfo: "
1057 "/proc/cpuinfo not readable! "
1058 "Expect bad performance and/or weird behaviour\n");
1061 while (fgets(line
,200,f
)!=NULL
) {
1064 /* NOTE: the ':' is the only character we can rely on */
1065 if (!(value
= strchr(line
,':')))
1067 /* terminate the valuename */
1069 /* skip any leading spaces */
1070 while (*value
==' ') value
++;
1071 if ((s
=strchr(value
,'\n')))
1075 if (!lstrncmpiA(line
, "cpu family",strlen("cpu family"))) {
1076 if (isdigit (value
[0])) {
1077 switch (value
[0] - '0') {
1078 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1079 cachedsi
.wProcessorLevel
= 3;
1081 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1082 cachedsi
.wProcessorLevel
= 4;
1084 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1085 cachedsi
.wProcessorLevel
= 5;
1087 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1088 cachedsi
.wProcessorLevel
= 5;
1090 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1091 cachedsi
.wProcessorLevel
= 5;
1095 /* set the CPU type of the current processor */
1096 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1099 /* old 2.0 method */
1100 if (!lstrncmpiA(line
, "cpu",strlen("cpu"))) {
1101 if ( isdigit (value
[0]) && value
[1] == '8' &&
1102 value
[2] == '6' && value
[3] == 0
1104 switch (value
[0] - '0') {
1105 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1106 cachedsi
.wProcessorLevel
= 3;
1108 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1109 cachedsi
.wProcessorLevel
= 4;
1111 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1112 cachedsi
.wProcessorLevel
= 5;
1114 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1115 cachedsi
.wProcessorLevel
= 5;
1117 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1118 cachedsi
.wProcessorLevel
= 5;
1122 /* set the CPU type of the current processor */
1123 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1126 if (!lstrncmpiA(line
,"fdiv_bug",strlen("fdiv_bug"))) {
1127 if (!lstrncmpiA(value
,"yes",3))
1128 PF
[PF_FLOATING_POINT_PRECISION_ERRATA
] = TRUE
;
1132 if (!lstrncmpiA(line
,"fpu",strlen("fpu"))) {
1133 if (!lstrncmpiA(value
,"no",2))
1134 PF
[PF_FLOATING_POINT_EMULATED
] = TRUE
;
1138 if (!lstrncmpiA(line
,"processor",strlen("processor"))) {
1139 /* processor number counts up...*/
1142 if (sscanf(value
,"%d",&x
))
1143 if (x
+1>cachedsi
.dwNumberOfProcessors
)
1144 cachedsi
.dwNumberOfProcessors
=x
+1;
1146 /* Create a new processor subkey on a multiprocessor
1149 sprintf(buf
,"%d",x
);
1151 if (!lstrncmpiA(line
,"stepping",strlen("stepping"))) {
1154 if (sscanf(value
,"%d",&x
))
1155 cachedsi
.wProcessorRevision
= x
;
1158 ( (!lstrncmpiA(line
,"flags",strlen("flags")))
1159 || (!lstrncmpiA(line
,"features",strlen("features"))) )
1161 if (strstr(value
,"cx8"))
1162 PF
[PF_COMPARE_EXCHANGE_DOUBLE
] = TRUE
;
1163 if (strstr(value
,"mmx"))
1164 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1165 if (strstr(value
,"tsc"))
1166 PF
[PF_RDTSC_INSTRUCTION_AVAILABLE
] = TRUE
;
1167 if (strstr(value
,"xmm") || strstr(value
,"sse"))
1168 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1169 if (strstr(value
,"sse2"))
1170 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1171 if (strstr(value
,"3dnow"))
1172 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1177 #endif /* __linux__ */
1180 memcpy(si
,&cachedsi
,sizeof(*si
));
1184 // avoid undefined expGetSystemInfo
1185 static WIN_BOOL WINAPI
expIsProcessorFeaturePresent(DWORD v
)
1187 WIN_BOOL result
= 0;
1191 expGetSystemInfo(&si
);
1193 if(v
<64) result
=PF
[v
];
1194 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v
, result
);
1198 static WIN_BOOL WINAPI
expIsDebuggerPresent(void)
1203 static long WINAPI
expGetVersion(void)
1205 dbgprintf("GetVersion() => 0xC0000004\n");
1206 return 0xC0000004;//Windows 95
1209 static HANDLE WINAPI
expHeapCreate(long flags
, long init_size
, long max_size
)
1211 // printf("HeapCreate:");
1214 result
=(HANDLE
)my_mreq(0x110000, 0);
1216 result
=(HANDLE
)my_mreq((init_size
+ 0xfff) & 0x7ffff000 , 0);
1217 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags
, init_size
, max_size
, result
);
1221 // this is another dirty hack
1222 // VP31 is releasing one allocated Heap chunk twice
1223 // we will silently ignore this second call...
1224 static void* heapfreehack
= 0;
1225 static int heapfreehackshown
= 0;
1226 //void trapbug(void);
1227 static void* WINAPI
expHeapAlloc(HANDLE heap
, int flags
, int size
)
1231 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1232 HeapAlloc returns area larger than size argument :-/
1234 actually according to M$ Doc HeapCreate size should be rounded
1235 to page boundaries thus we should simulate this
1237 //if (size == 22276) trapbug();
1238 z
=my_mreq((size
+ 0xfff) & 0x7ffff000, (flags
& HEAP_ZERO_MEMORY
));
1240 printf("HeapAlloc failure\n");
1241 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap
, flags
, size
, z
);
1242 heapfreehack
= 0; // reset
1245 static long WINAPI
expHeapDestroy(void* heap
)
1247 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap
);
1252 static long WINAPI
expHeapFree(HANDLE heap
, DWORD dwFlags
, LPVOID lpMem
)
1254 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap
, dwFlags
, lpMem
);
1255 if (heapfreehack
!= lpMem
&& lpMem
!= (void*)0xffffffff
1256 && lpMem
!= (void*)0xbdbdbdbd)
1257 // 0xbdbdbdbd is for i263_drv.drv && libefence
1258 // it seems to be reading from relased memory
1259 // EF_PROTECT_FREE doens't show any probleme
1263 if (!heapfreehackshown
++)
1264 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem
);
1266 heapfreehack
= lpMem
;
1269 static long WINAPI
expHeapSize(int heap
, int flags
, void* pointer
)
1271 long result
=my_size(pointer
);
1272 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap
, flags
, pointer
, result
);
1275 static void* WINAPI
expHeapReAlloc(HANDLE heap
,int flags
,void *lpMem
,int size
)
1277 long orgsize
= my_size(lpMem
);
1278 dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize
,size
);
1279 return my_realloc(lpMem
, size
);
1281 static long WINAPI
expGetProcessHeap(void)
1283 dbgprintf("GetProcessHeap() => 1\n");
1286 static void* WINAPI
expVirtualAlloc(void* v1
, long v2
, long v3
, long v4
)
1288 void* z
= VirtualAlloc(v1
, v2
, v3
, v4
);
1290 printf("VirtualAlloc failure\n");
1291 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1
,v2
,v3
,v4
, z
);
1294 static int WINAPI
expVirtualFree(void* v1
, int v2
, int v3
)
1296 int result
= VirtualFree(v1
,v2
,v3
);
1297 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1
,v2
,v3
, result
);
1301 /* we're building a table of critical sections. cs_win pointer uses the DLL
1302 cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1303 struct critsecs_list_t
1305 CRITICAL_SECTION
*cs_win
;
1306 struct CRITSECT
*cs_unix
;
1309 /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1310 #undef CRITSECS_NEWTYPE
1311 //#define CRITSECS_NEWTYPE 1
1313 #ifdef CRITSECS_NEWTYPE
1314 /* increased due to ucod needs more than 32 entries */
1315 /* and 64 should be enough for everything */
1316 #define CRITSECS_LIST_MAX 64
1317 static struct critsecs_list_t critsecs_list
[CRITSECS_LIST_MAX
];
1319 static int critsecs_get_pos(CRITICAL_SECTION
*cs_win
)
1323 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1324 if (critsecs_list
[i
].cs_win
== cs_win
)
1329 static int critsecs_get_unused(void)
1333 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1334 if (critsecs_list
[i
].cs_win
== NULL
)
1339 struct CRITSECT
*critsecs_get_unix(CRITICAL_SECTION
*cs_win
)
1343 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1344 if (critsecs_list
[i
].cs_win
== cs_win
&& critsecs_list
[i
].cs_unix
)
1345 return critsecs_list
[i
].cs_unix
;
1350 static void WINAPI
expInitializeCriticalSection(CRITICAL_SECTION
* c
)
1352 dbgprintf("InitializeCriticalSection(0x%x)\n", c
);
1353 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1355 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1356 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1359 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1360 #ifdef CRITSECS_NEWTYPE
1362 struct CRITSECT
*cs
;
1363 int i
= critsecs_get_unused();
1367 printf("InitializeCriticalSection(%p) - no more space in list\n", c
);
1370 dbgprintf("got unused space at %d\n", i
);
1371 cs
= malloc(sizeof(struct CRITSECT
));
1374 printf("InitializeCriticalSection(%p) - out of memory\n", c
);
1377 pthread_mutex_init(&cs
->mutex
, NULL
);
1378 pthread_cond_init(&cs
->unlocked
, NULL
);
1380 critsecs_list
[i
].cs_win
= c
;
1381 critsecs_list
[i
].cs_unix
= cs
;
1382 dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1387 struct CRITSECT
* cs
= mreq_private(sizeof(struct CRITSECT
) + sizeof(CRITICAL_SECTION
),
1388 0, AREATYPE_CRITSECT
);
1389 pthread_mutex_init(&cs
->mutex
, NULL
);
1390 pthread_cond_init(&cs
->unlocked
, NULL
);
1392 cs
->deadbeef
= 0xdeadbeef;
1399 static WIN_BOOL WINAPI
expInitializeCriticalSectionAndSpinCount(CRITICAL_SECTION
* c
, DWORD spin
)
1401 expInitializeCriticalSection(c
);
1405 static void WINAPI
expEnterCriticalSection(CRITICAL_SECTION
* c
)
1407 #ifdef CRITSECS_NEWTYPE
1408 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1410 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1412 dbgprintf("EnterCriticalSection(0x%x) %p\n",c
, cs
);
1415 dbgprintf("entered uninitialized critisec!\n");
1416 expInitializeCriticalSection(c
);
1417 #ifdef CRITSECS_NEWTYPE
1418 cs
=critsecs_get_unix(c
);
1420 cs
= (*(struct CRITSECT
**)c
);
1422 dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c
);
1424 pthread_mutex_lock(&(cs
->mutex
));
1425 if (cs
->lock_count
> 0 && cs
->id
== pthread_self()) {
1428 while (cs
->lock_count
!= 0) {
1429 pthread_cond_wait(&(cs
->unlocked
), &(cs
->mutex
));
1432 cs
->id
= pthread_self();
1434 pthread_mutex_unlock(&(cs
->mutex
));
1437 static void WINAPI
expLeaveCriticalSection(CRITICAL_SECTION
* c
)
1439 #ifdef CRITSECS_NEWTYPE
1440 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1442 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1444 // struct CRITSECT* cs=(struct CRITSECT*)c;
1445 dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c
, cs
);
1448 dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c
);
1451 pthread_mutex_lock(&(cs
->mutex
));
1452 if (cs
->lock_count
== 0) {
1453 dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c
);
1457 if (cs
->lock_count
== 0) {
1458 pthread_cond_signal(&(cs
->unlocked
));
1460 pthread_mutex_unlock(&(cs
->mutex
));
1464 static void expfree(void* mem
); /* forward declaration */
1466 static void WINAPI
expDeleteCriticalSection(CRITICAL_SECTION
*c
)
1468 #ifdef CRITSECS_NEWTYPE
1469 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1471 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1473 // struct CRITSECT* cs=(struct CRITSECT*)c;
1474 dbgprintf("DeleteCriticalSection(0x%x)\n",c
);
1478 dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c
);
1482 pthread_mutex_lock(&(cs
->mutex
));
1483 if (cs
->lock_count
> 0)
1485 dbgprintf("Win32 Warning: Deleting locked Critical Section %p!!\n", c
);
1487 pthread_mutex_unlock(&(cs
->mutex
));
1490 pthread_mutex_destroy(&(cs
->mutex
));
1491 pthread_cond_destroy(&(cs
->unlocked
));
1492 // released by GarbageCollector in my_relase otherwise
1495 #ifdef CRITSECS_NEWTYPE
1497 int i
= critsecs_get_pos(c
);
1501 printf("DeleteCriticalSection(%p) error (critsec not found)\n", c
);
1505 critsecs_list
[i
].cs_win
= NULL
;
1506 expfree(critsecs_list
[i
].cs_unix
);
1507 critsecs_list
[i
].cs_unix
= NULL
;
1508 dbgprintf("DeleteCriticalSection -> itemno=%d\n", i
);
1513 static int WINAPI
expGetCurrentThreadId(void)
1515 dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1516 return pthread_self();
1518 static int WINAPI
expGetCurrentProcess(void)
1520 dbgprintf("GetCurrentProcess() => %d\n", getpid());
1524 #ifdef CONFIG_QTX_CODECS
1525 // this version is required for Quicktime codecs (.qtx/.qts) to work.
1526 // (they assume some pointers at FS: segment)
1528 extern void* fs_seg
;
1530 //static int tls_count;
1531 static int tls_use_map
[64];
1532 static int WINAPI
expTlsAlloc(void)
1536 if(tls_use_map
[i
]==0)
1539 dbgprintf("TlsAlloc() => %d\n",i
);
1542 dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1546 //static int WINAPI expTlsSetValue(DWORD index, void* value)
1547 static int WINAPI
expTlsSetValue(int index
, void* value
)
1549 dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index
,value
);
1550 // if((index<0) || (index>64))
1553 *(void**)((char*)fs_seg
+0x88+4*index
) = value
;
1557 static void* WINAPI
expTlsGetValue(DWORD index
)
1559 dbgprintf("TlsGetValue(%d)\n",index
);
1560 // if((index<0) || (index>64))
1561 if((index
>=64)) return NULL
;
1562 return *(void**)((char*)fs_seg
+0x88+4*index
);
1565 static int WINAPI
expTlsFree(int idx
)
1567 int index
= (int) idx
;
1568 dbgprintf("TlsFree(%d)\n",index
);
1569 if((index
<0) || (index
>64))
1571 tls_use_map
[index
]=0;
1583 static void* WINAPI
expTlsAlloc(void)
1587 g_tls
=my_mreq(sizeof(tls_t
), 0);
1588 g_tls
->next
=g_tls
->prev
=NULL
;
1592 g_tls
->next
=my_mreq(sizeof(tls_t
), 0);
1593 g_tls
->next
->prev
=g_tls
;
1594 g_tls
->next
->next
=NULL
;
1597 dbgprintf("TlsAlloc() => 0x%x\n", g_tls
);
1599 g_tls
->value
=0; /* XXX For Divx.dll */
1603 static int WINAPI
expTlsSetValue(void* idx
, void* value
)
1605 tls_t
* index
= (tls_t
*) idx
;
1614 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index
, value
, result
);
1617 static void* WINAPI
expTlsGetValue(void* idx
)
1619 tls_t
* index
= (tls_t
*) idx
;
1624 result
=index
->value
;
1625 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index
, result
);
1628 static int WINAPI
expTlsFree(void* idx
)
1630 tls_t
* index
= (tls_t
*) idx
;
1637 index
->next
->prev
=index
->prev
;
1639 index
->prev
->next
=index
->next
;
1641 g_tls
= index
->prev
;
1642 my_release((void*)index
);
1645 dbgprintf("TlsFree(index 0x%x) => %d\n", index
, result
);
1650 static void* WINAPI
expLocalAlloc(int flags
, int size
)
1652 void* z
= my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1654 printf("LocalAlloc() failed\n");
1655 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1659 static void* WINAPI
expLocalReAlloc(int handle
,int size
, int flags
)
1665 if (flags
& LMEM_MODIFY
) {
1666 dbgprintf("LocalReAlloc MODIFY\n");
1667 return (void *)handle
;
1669 oldsize
= my_size((void *)handle
);
1670 newpointer
= my_realloc((void *)handle
,size
);
1671 dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle
,size
,oldsize
, flags
,newpointer
);
1676 static void* WINAPI
expLocalLock(void* z
)
1678 dbgprintf("LocalLock(0x%x) => 0x%x\n", z
, z
);
1682 static void* WINAPI
expGlobalAlloc(int flags
, int size
)
1685 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size
, flags
);
1687 z
=my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1688 //z=calloc(size, 1);
1691 printf("GlobalAlloc() failed\n");
1692 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1695 static void* WINAPI
expGlobalLock(void* z
)
1697 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z
, z
);
1700 // pvmjpg20 - but doesn't work anyway
1701 static int WINAPI
expGlobalSize(void* amem
)
1705 alloc_header
* header
= last_alloc
;
1706 alloc_header
* mem
= (alloc_header
*) amem
- 1;
1709 pthread_mutex_lock(&memmut
);
1712 if (header
->deadbeef
!= 0xdeadbeef)
1714 dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
1720 size
= header
->size
;
1724 header
= header
->prev
;
1726 pthread_mutex_unlock(&memmut
);
1729 dbgprintf("GlobalSize(0x%x)\n", amem
);
1733 static int WINAPI
expLoadIconA( long hinstance
, char *name
)
1735 dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance
,name
);
1739 static int WINAPI
expLoadStringA(long instance
, long id
, void* buf
, long size
)
1741 int result
=LoadStringA(instance
, id
, buf
, size
);
1743 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1744 instance
, id
, buf
, size
, result
, buf
);
1746 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1747 // instance, id, buf, size, result);
1751 static long WINAPI
expMultiByteToWideChar(long v1
, long v2
, char* s1
, long siz1
, short* s2
, int siz2
)
1760 if(siz1
>siz2
/2)siz1
=siz2
/2;
1761 for(i
=1; i
<=siz1
; i
++)
1771 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1772 "size %d, dest buffer 0x%x, dest size %d) => %d\n",
1773 v1
, v2
, s1
, s1
, siz1
, s2
, siz2
, result
);
1775 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1776 "size %d, dest buffer 0x%x, dest size %d) =>\n",
1777 v1
, v2
, siz1
, s2
, siz2
, result
);
1780 static void wch_print(const short* str
)
1782 dbgprintf(" src: ");
1783 while(*str
)dbgprintf("%c", *str
++);
1786 static long WINAPI
expWideCharToMultiByte(long v1
, long v2
, short* s1
, long siz1
,
1787 char* s2
, int siz2
, char* c3
, int* siz3
)
1790 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1791 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1792 result
=WideCharToMultiByte(v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1793 dbgprintf("=> %d\n", result
);
1794 //if(s1)wch_print(s1);
1795 if(s2
)dbgprintf(" dest: %s\n", s2
);
1799 static long WINAPI
expGetVersionExA(OSVERSIONINFOA
* c
)
1801 dbgprintf("GetVersionExA(0x%x) => 1\n", c
);
1802 c
->dwOSVersionInfoSize
=sizeof(*c
);
1803 c
->dwMajorVersion
=5;
1804 c
->dwMinorVersion
=1;
1805 c
->dwBuildNumber
=0x5010a28;
1806 c
->dwPlatformId
=VER_PLATFORM_WIN32_NT
;
1807 strcpy(c
->szCSDVersion
, "Service Pack 2");
1808 dbgprintf(" Major version: 5\n Minor version: 1\n Build number: 0x5010a28\n"
1809 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 2'\n");
1813 static long WINAPI
expGetVersionExW(OSVERSIONINFOW
* c
)
1815 char CSDVersion
[128];
1816 dbgprintf("GetVersionExW(0x%x) => 1\n", c
);
1817 c
->dwOSVersionInfoSize
=sizeof(*c
);
1818 c
->dwMajorVersion
=5;
1819 c
->dwMinorVersion
=1;
1820 c
->dwBuildNumber
=0x5010a28;
1821 c
->dwPlatformId
=VER_PLATFORM_WIN32_NT
;
1822 strcpy(CSDVersion
, "Service Pack 2");
1823 MultiByteToWideChar(65001, 0x0, CSDVersion
, -1, c
->szCSDVersion
, 128);
1824 dbgprintf(" Major version: 5\n Minor version: 1\n Build number: 0x5010a28\n"
1825 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 2'\n");
1829 static HANDLE WINAPI
expCreateSemaphoreA(char* v1
, long init_count
,
1830 long max_count
, char* name
)
1832 pthread_mutex_t
*pm
;
1837 printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1841 printf("%p => ", pp);
1846 pthread_mutex_lock(&mlist_lock
);
1849 mutex_list
* pp
=mlist
;
1853 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==1))
1855 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1856 v1
, init_count
, max_count
, name
, name
, mlist
);
1857 ret
= (HANDLE
)mlist
;
1858 pthread_mutex_unlock(&mlist_lock
);
1861 }while((pp
=pp
->prev
) != NULL
);
1863 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
1864 pthread_mutex_init(pm
, NULL
);
1865 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
1866 pthread_cond_init(pc
, NULL
);
1869 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1870 mlist
->next
=mlist
->prev
=NULL
;
1874 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1875 mlist
->next
->prev
=mlist
;
1876 mlist
->next
->next
=NULL
;
1878 // printf("new semaphore %p\n", mlist);
1880 mlist
->type
=1; /* Type Semaphore */
1885 mlist
->semaphore
=init_count
;
1887 strncpy(mlist
->name
, name
, 64);
1891 dbgprintf("ERROR::: CreateSemaphoreA failure\n");
1893 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1894 v1
, init_count
, max_count
, name
, name
, mlist
);
1896 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1897 v1
, init_count
, max_count
, mlist
);
1898 ret
= (HANDLE
)mlist
;
1899 pthread_mutex_unlock(&mlist_lock
);
1903 static HANDLE WINAPI
expCreateSemaphoreW(char* v1
, long init_count
,
1904 long max_count
, const WCHAR
* name
)
1906 char ascii_name
[256];
1909 WideCharToMultiByte(65001, 0x0, name
, -1, ascii_name
, 256, NULL
, NULL
);
1912 return expCreateSemaphoreA(v1
, init_count
, max_count
, aname
);
1915 static long WINAPI
expReleaseSemaphore(long hsem
, long increment
, long* prev_count
)
1917 // The state of a semaphore object is signaled when its count
1918 // is greater than zero and nonsignaled when its count is equal to zero
1919 // Each time a waiting thread is released because of the semaphore's signaled
1920 // state, the count of the semaphore is decreased by one.
1921 mutex_list
*ml
= (mutex_list
*)hsem
;
1923 pthread_mutex_lock(ml
->pm
);
1924 if (prev_count
!= 0) *prev_count
= ml
->semaphore
;
1925 if (ml
->semaphore
== 0) pthread_cond_signal(ml
->pc
);
1926 ml
->semaphore
+= increment
;
1927 pthread_mutex_unlock(ml
->pm
);
1928 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1929 hsem
, increment
, prev_count
);
1933 static HANDLE WINAPI
expCreateMutexA(void *pSecAttr
,
1934 char bInitialOwner
, const char *name
)
1936 pthread_mutex_t
*pm
;
1939 pthread_mutex_lock(&mlist_lock
);
1942 mutex_list
* pp
=mlist
;
1946 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==2))
1948 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n", pSecAttr
, bInitialOwner
, name
, mlist
);
1949 ret
= (HANDLE
)mlist
;
1950 pthread_mutex_unlock(&mlist_lock
);
1953 }while((pp
=pp
->prev
) != NULL
);
1955 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
1956 pthread_mutex_init(pm
, NULL
);
1957 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
1958 pthread_cond_init(pc
, NULL
);
1961 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1962 mlist
->next
=mlist
->prev
=NULL
;
1966 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1967 mlist
->next
->prev
=mlist
;
1968 mlist
->next
->next
=NULL
;
1971 mlist
->type
=2; /* Type Mutex */
1977 if (bInitialOwner
) {
1978 mlist
->owner
= pthread_self();
1979 mlist
->lock_count
= 1;
1981 mlist
->owner
= (pthread_t
)0;
1982 mlist
->lock_count
= 0;
1985 strncpy(mlist
->name
, name
, 64);
1989 dbgprintf("ERROR::: CreateMutexA failure\n");
1991 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
1992 pSecAttr
, bInitialOwner
, name
, mlist
);
1994 dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
1995 pSecAttr
, bInitialOwner
, mlist
);
1996 ret
= (HANDLE
)mlist
;
1997 pthread_mutex_unlock(&mlist_lock
);
2001 static HANDLE WINAPI
expCreateMutexW(void *pSecAttr
, char bInitialOwner
, const WCHAR
*name
)
2003 char ascii_name
[256];
2006 WideCharToMultiByte(65001, 0x0, name
, -1, ascii_name
, 256, NULL
, NULL
);
2009 return expCreateMutexA(pSecAttr
, bInitialOwner
, aname
);
2012 static int WINAPI
expReleaseMutex(HANDLE hMutex
)
2014 mutex_list
*ml
= (mutex_list
*)hMutex
;
2016 pthread_mutex_lock(ml
->pm
);
2017 if (--ml
->lock_count
== 0) pthread_cond_signal(ml
->pc
);
2018 pthread_mutex_unlock(ml
->pm
);
2022 static DWORD WINAPI
expSignalObjectAndWait(HANDLE hObjectToSignal
,
2023 HANDLE hObjectToWaitOn
,
2024 DWORD dwMilliseconds
,
2025 WIN_BOOL bAlertable
) {
2026 mutex_list
* mlist
= (mutex_list
*)hObjectToSignal
;
2028 switch (mlist
->type
) {
2032 case 1: // Semaphore
2033 expReleaseSemaphore(mlist
, 1, NULL
);
2036 expReleaseMutex(mlist
);
2039 dbgprintf("Signalling unknown object type %d!\n", hObjectToSignal
);
2041 return expWaitForSingleObject(hObjectToWaitOn
, dwMilliseconds
);
2044 static long WINAPI
expRegOpenKeyExA(long key
, const char* subkey
, long reserved
, long access
, int* newkey
)
2046 long result
=RegOpenKeyExA(key
, subkey
, reserved
, access
, newkey
);
2047 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
2048 key
, subkey
, reserved
, access
, newkey
, result
);
2049 if(newkey
)dbgprintf(" New key: 0x%x\n", *newkey
);
2052 static long WINAPI
expRegCloseKey(long key
)
2054 long result
=RegCloseKey(key
);
2055 dbgprintf("RegCloseKey(0x%x) => %d\n", key
, result
);
2058 static long WINAPI
expRegQueryValueExA(long key
, const char* value
, int* reserved
, int* type
, int* data
, int* count
)
2060 long result
=RegQueryValueExA(key
, value
, reserved
, type
, data
, count
);
2061 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
2062 " => 0x%x\n", key
, value
, reserved
, data
, count
, result
);
2063 if(data
&& count
)dbgprintf(" read %d bytes: '%s'\n", *count
, data
);
2067 //from wine source dlls/advapi32/registry.c
2068 static long WINAPI
expRegCreateKeyA(long hkey
, const char* name
, int *retkey
)
2070 dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey
,name
,retkey
);
2071 return RegCreateKeyExA( hkey
, name
, 0, NULL
,REG_OPTION_NON_VOLATILE
,
2072 KEY_ALL_ACCESS
, NULL
, retkey
, NULL
);
2075 static long WINAPI
expRegCreateKeyExA(long key
, const char* name
, long reserved
,
2076 void* classs
, long options
, long security
,
2077 void* sec_attr
, int* newkey
, int* status
)
2079 long result
=RegCreateKeyExA(key
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
);
2080 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
2081 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
2082 key
, name
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
, result
);
2083 if(!result
&& newkey
) dbgprintf(" New key: 0x%x\n", *newkey
);
2084 if(!result
&& status
) dbgprintf(" New key status: 0x%x\n", *status
);
2087 static long WINAPI
expRegSetValueExA(long key
, const char* name
, long v1
, long v2
, void* data
, long size
)
2089 long result
=RegSetValueExA(key
, name
, v1
, v2
, data
, size
);
2090 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
2091 key
, name
, v1
, v2
, data
, *(int*)data
, data
, size
, result
);
2095 static long WINAPI
expRegOpenKeyA (long hKey
, LPCSTR lpSubKey
, int* phkResult
)
2097 long result
=RegOpenKeyExA(hKey
, lpSubKey
, 0, 0, phkResult
);
2098 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
2099 hKey
, lpSubKey
, phkResult
, result
);
2100 if(!result
&& phkResult
) dbgprintf(" New key: 0x%x\n", *phkResult
);
2104 static DWORD WINAPI
expRegEnumValueA(HKEY hkey
, DWORD index
, LPSTR value
, LPDWORD val_count
,
2105 LPDWORD reserved
, LPDWORD type
, LPBYTE data
, LPDWORD count
)
2107 return RegEnumValueA(hkey
, index
, value
, val_count
,
2108 reserved
, type
, data
, count
);
2111 static DWORD WINAPI
expRegEnumKeyExA(HKEY hKey
, DWORD dwIndex
, LPSTR lpName
, LPDWORD lpcbName
,
2112 LPDWORD lpReserved
, LPSTR lpClass
, LPDWORD lpcbClass
,
2113 LPFILETIME lpftLastWriteTime
)
2115 return RegEnumKeyExA(hKey
, dwIndex
, lpName
, lpcbName
, lpReserved
, lpClass
,
2116 lpcbClass
, lpftLastWriteTime
);
2119 static long WINAPI
expQueryPerformanceCounter(long long* z
)
2122 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z
, *z
);
2127 * dummy function RegQueryInfoKeyA(), required by vss codecs
2129 static DWORD WINAPI
expRegQueryInfoKeyA( HKEY hkey
, LPSTR
class, LPDWORD class_len
, LPDWORD reserved
,
2130 LPDWORD subkeys
, LPDWORD max_subkey
, LPDWORD max_class
,
2131 LPDWORD values
, LPDWORD max_value
, LPDWORD max_data
,
2132 LPDWORD security
, FILETIME
*modif
)
2134 return ERROR_SUCCESS
;
2138 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
2140 static double linux_cpuinfo_freq(void)
2147 f
= fopen ("/proc/cpuinfo", "r");
2149 while (fgets(line
,sizeof(line
),f
)!=NULL
) {
2150 /* NOTE: the ':' is the only character we can rely on */
2151 if (!(value
= strchr(line
,':')))
2153 /* terminate the valuename */
2155 /* skip any leading spaces */
2156 while (*value
==' ') value
++;
2157 if ((s
=strchr(value
,'\n')))
2160 if (!strncasecmp(line
, "cpu MHz",strlen("cpu MHz"))
2161 && sscanf(value
, "%lf", &freq
) == 1) {
2172 static double solaris_kstat_freq(void)
2174 #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
2176 * try to extract the CPU speed from the solaris kernel's kstat data
2180 kstat_named_t
*kdata
;
2186 ksp
= kstat_lookup(kc
, "cpu_info", 0, "cpu_info0");
2188 /* kstat found and name/value pairs? */
2189 if (ksp
!= NULL
&& ksp
->ks_type
== KSTAT_TYPE_NAMED
)
2191 /* read the kstat data from the kernel */
2192 if (kstat_read(kc
, ksp
, NULL
) != -1)
2195 * lookup desired "clock_MHz" entry, check the expected
2198 kdata
= (kstat_named_t
*)kstat_data_lookup(ksp
, "clock_MHz");
2199 if (kdata
!= NULL
&& kdata
->data_type
== KSTAT_DATA_INT32
)
2200 mhz
= kdata
->value
.i32
;
2208 #endif /* HAVE_LIBKSTAT */
2209 return -1; // kstat stuff is not available, CPU freq is unknown
2213 * Measure CPU freq using the pentium's time stamp counter register (TSC)
2215 static double tsc_freq(void)
2217 static double ofreq
=0.0;
2221 if (ofreq
!= 0.0) return ofreq
;
2222 while(i
==time(NULL
));
2225 while(i
==time(NULL
));
2227 ofreq
= (double)(y
-x
)/1000.;
2231 static double CPU_Freq(void)
2235 if ((freq
= linux_cpuinfo_freq()) > 0)
2238 if ((freq
= solaris_kstat_freq()) > 0)
2244 static long WINAPI
expQueryPerformanceFrequency(long long* z
)
2246 *z
=(long long)CPU_Freq();
2247 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z
, *z
);
2250 static long WINAPI
exptimeGetTime(void)
2254 gettimeofday(&t
, 0);
2255 result
=1000*t
.tv_sec
+t
.tv_usec
/1000;
2256 dbgprintf("timeGetTime() => %d\n", result
);
2259 static void* WINAPI
expLocalHandle(void* v
)
2261 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v
, v
);
2265 static void* WINAPI
expGlobalHandle(void* v
)
2267 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v
, v
);
2270 static int WINAPI
expGlobalUnlock(void* v
)
2272 dbgprintf("GlobalUnlock(0x%x) => 1\n", v
);
2275 static void* WINAPI
expGlobalFree(void* v
)
2277 dbgprintf("GlobalFree(0x%x) => 0\n", v
);
2283 static void* WINAPI
expGlobalReAlloc(void* v
, int size
, int flags
)
2285 void* result
=my_realloc(v
, size
);
2286 //void* result=realloc(v, size);
2287 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v
,size
,flags
,result
);
2291 static int WINAPI
expLocalUnlock(void* v
)
2293 dbgprintf("LocalUnlock(0x%x) => 1\n", v
);
2297 static void* WINAPI
expLocalFree(void* v
)
2299 dbgprintf("LocalFree(0x%x) => 0\n", v
);
2303 static HRSRC WINAPI
expFindResourceA(HMODULE module
, char* name
, char* type
)
2307 result
=FindResourceA(module
, name
, type
);
2308 dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2309 module
, name
, HIWORD(name
) ? name
: "UNICODE", type
, HIWORD(type
) ? type
: "UNICODE", result
);
2313 static HGLOBAL WINAPI
expLoadResource(HMODULE module
, HRSRC res
)
2315 HGLOBAL result
=LoadResource(module
, res
);
2316 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module
, res
, result
);
2319 static void* WINAPI
expLockResource(long res
)
2321 void* result
=LockResource(res
);
2322 dbgprintf("LockResource(0x%x) => 0x%x\n", res
, result
);
2325 static int WINAPI
expFreeResource(long res
)
2327 int result
=FreeResource(res
);
2328 dbgprintf("FreeResource(0x%x) => %d\n", res
, result
);
2333 static int WINAPI
expCloseHandle(long v1
)
2335 dbgprintf("CloseHandle(0x%x) => 1\n", v1
);
2336 /* do not close stdin,stdout and stderr */
2343 static const char* WINAPI
expGetCommandLineA(void)
2345 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2346 return "c:\\aviplay.exe";
2348 static short envs
[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2349 static LPWSTR WINAPI
expGetEnvironmentStringsW(void)
2351 dbgprintf("GetEnvironmentStringsW() => 0\n", envs
);
2354 static void * WINAPI
expRtlZeroMemory(void *p
, size_t len
)
2356 void* result
=memset(p
,0,len
);
2357 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p
,len
,result
);
2360 static void * WINAPI
expRtlMoveMemory(void *dst
, void *src
, size_t len
)
2362 void* result
=memmove(dst
,src
,len
);
2363 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst
,src
,len
,result
);
2367 static void * WINAPI
expRtlFillMemory(void *p
, int ch
, size_t len
)
2369 void* result
=memset(p
,ch
,len
);
2370 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p
,ch
,len
,result
);
2373 static int WINAPI
expFreeEnvironmentStringsW(short* strings
)
2375 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings
);
2378 static int WINAPI
expFreeEnvironmentStringsA(char* strings
)
2380 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings
);
2384 static const char ch_envs
[]=
2385 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2386 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2387 static LPCSTR WINAPI
expGetEnvironmentStrings(void)
2389 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs
);
2390 return (LPCSTR
)ch_envs
;
2391 // dbgprintf("GetEnvironmentStrings() => 0\n");
2395 static int WINAPI
expGetStartupInfoA(STARTUPINFOA
*s
)
2397 dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2398 memset(s
, 0, sizeof(*s
));
2400 // s->lpReserved="Reserved";
2401 // s->lpDesktop="Desktop";
2402 // s->lpTitle="Title";
2404 // s->dwXSize=s->dwYSize=200;
2405 s
->dwFlags
=s
->wShowWindow
=1;
2406 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2407 dbgprintf(" cb=%d\n", s
->cb
);
2408 dbgprintf(" lpReserved='%s'\n", s
->lpReserved
);
2409 dbgprintf(" lpDesktop='%s'\n", s
->lpDesktop
);
2410 dbgprintf(" lpTitle='%s'\n", s
->lpTitle
);
2411 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2412 s
->dwX
, s
->dwY
, s
->dwXSize
, s
->dwYSize
);
2413 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2414 s
->dwXCountChars
, s
->dwYCountChars
, s
->dwFillAttribute
);
2415 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2416 s
->dwFlags
, s
->wShowWindow
, s
->cbReserved2
);
2417 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2418 s
->lpReserved2
, s
->hStdInput
, s
->hStdOutput
, s
->hStdError
);
2422 static int WINAPI
expGetStdHandle(int z
)
2424 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z
+0x1234);
2428 #ifdef CONFIG_QTX_CODECS
2429 #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2430 #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2433 static int WINAPI
expGetFileType(int handle
)
2435 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle
);
2438 #ifdef CONFIG_QTX_CODECS
2439 static int WINAPI
expGetFileAttributesA(char *filename
)
2441 dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename
);
2442 if (strstr(filename
, "QuickTime.qts"))
2443 return FILE_ATTRIBUTE_SYSTEM
;
2444 return FILE_ATTRIBUTE_NORMAL
;
2447 static int WINAPI
expSetHandleCount(int count
)
2449 dbgprintf("SetHandleCount(0x%x) => 1\n", count
);
2452 static int WINAPI
expGetACP(void)
2454 dbgprintf("GetACP() => 0\n");
2457 static int WINAPI
expGetModuleFileNameA(int module
, char* s
, int len
)
2461 //printf("File name of module %X (%s) requested\n", module, s);
2463 if (module
== 0 && len
>= 12)
2465 /* return caller program name */
2466 strcpy(s
, "aviplay.dll");
2477 strcpy(s
, "c:\\windows\\system\\");
2478 mr
=MODULE32_LookupHMODULE(module
);
2480 strcat(s
, "aviplay.dll");
2482 if(strrchr(mr
->filename
, '/')==NULL
)
2483 strcat(s
, mr
->filename
);
2485 strcat(s
, strrchr(mr
->filename
, '/')+1);
2488 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2489 module
, s
, len
, result
);
2491 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2492 module
, s
, len
, result
, s
);
2496 static int WINAPI
expGetModuleBaseNameA(int process
, int module
, char* s
, int len
)
2501 av_strlcpy(s
, "aviplay.dll", len
);
2505 dbgprintf("GetModuleBaseNameA(0x%x, 0x%x, 0x%x, %d) => %d\n",
2506 process
, module
, s
, len
, result
);
2511 static int WINAPI
expSetUnhandledExceptionFilter(void* filter
)
2513 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter
);
2514 return 1;//unsupported and probably won't ever be supported
2517 static int WINAPI
expLoadLibraryA(char* name
)
2523 // we skip to the last backslash
2524 // this is effectively eliminating weird characters in
2525 // the text output windows
2527 lastbc
= strrchr(name
, '\\');
2534 name
[i
] = *lastbc
++;
2539 if(strncmp(name
, "c:\\windows\\", 11)==0) name
+= 11;
2540 if(strncmp(name
, ".\\", 2)==0) name
+= 2;
2542 dbgprintf("Entering LoadLibraryA(%s)\n", name
);
2544 // PIMJ and VIVO audio are loading kernel32.dll
2545 if (strcasecmp(name
, "kernel32.dll") == 0 || strcasecmp(name
, "kernel32") == 0)
2546 return MODULE_HANDLE_kernel32
;
2547 // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2548 /* exported -> do not return failed! */
2550 if (strcasecmp(name
, "user32.dll") == 0 || strcasecmp(name
, "user32") == 0)
2551 // return MODULE_HANDLE_kernel32;
2552 return MODULE_HANDLE_user32
;
2554 #ifdef CONFIG_QTX_CODECS
2555 if (strcasecmp(name
, "wininet.dll") == 0 || strcasecmp(name
, "wininet") == 0)
2556 return MODULE_HANDLE_wininet
;
2557 if (strcasecmp(name
, "ddraw.dll") == 0 || strcasecmp(name
, "ddraw") == 0)
2558 return MODULE_HANDLE_ddraw
;
2559 if (strcasecmp(name
, "advapi32.dll") == 0 || strcasecmp(name
, "advapi32") == 0)
2560 return MODULE_HANDLE_advapi32
;
2563 if (strcasecmp(name
, "comdlg32.dll") == 0 || strcasecmp(name
, "comdlg32") == 0)
2564 return MODULE_HANDLE_comdlg32
;
2565 if (strcasecmp(name
, "msvcrt.dll") == 0 || strcasecmp(name
, "msvcrt") == 0)
2566 return MODULE_HANDLE_msvcrt
;
2567 if (strcasecmp(name
, "ole32.dll") == 0 || strcasecmp(name
, "ole32") == 0)
2568 return MODULE_HANDLE_ole32
;
2569 if (strcasecmp(name
, "winmm.dll") == 0 || strcasecmp(name
, "winmm") == 0)
2570 return MODULE_HANDLE_winmm
;
2571 if (strcasecmp(name
, "psapi.dll") == 0 || strcasecmp(name
, "psapi") == 0)
2572 return MODULE_HANDLE_psapi
;
2574 result
=LoadLibraryA(name
);
2575 dbgprintf("Returned LoadLibraryA(0x%x='%s'), codec_path=%s => 0x%x\n",
2576 name
, name
, codec_path
, result
);
2581 static int WINAPI
expFreeLibrary(int module
)
2583 #ifdef CONFIG_QTX_CODECS
2584 int result
=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2586 int result
=FreeLibrary(module
);
2588 dbgprintf("FreeLibrary(0x%x) => %d\n", module
, result
);
2592 static void* WINAPI
expGetProcAddress(HMODULE mod
, char* name
)
2596 case MODULE_HANDLE_kernel32
:
2597 result
=LookupExternalByName("kernel32.dll", name
); break;
2598 case MODULE_HANDLE_user32
:
2599 result
=LookupExternalByName("user32.dll", name
); break;
2600 #ifdef CONFIG_QTX_CODECS
2601 case MODULE_HANDLE_wininet
:
2602 result
=LookupExternalByName("wininet.dll", name
); break;
2603 case MODULE_HANDLE_ddraw
:
2604 result
=LookupExternalByName("ddraw.dll", name
); break;
2605 case MODULE_HANDLE_advapi32
:
2606 result
=LookupExternalByName("advapi32.dll", name
); break;
2608 case MODULE_HANDLE_comdlg32
:
2609 result
=LookupExternalByName("comdlg32.dll", name
); break;
2610 case MODULE_HANDLE_msvcrt
:
2611 result
=LookupExternalByName("msvcrt.dll", name
); break;
2612 case MODULE_HANDLE_ole32
:
2613 result
=LookupExternalByName("ole32.dll", name
); break;
2614 case MODULE_HANDLE_winmm
:
2615 result
=LookupExternalByName("winmm.dll", name
); break;
2616 case MODULE_HANDLE_psapi
:
2617 result
=LookupExternalByName("psapi.dll", name
); break;
2619 result
=GetProcAddress(mod
, name
);
2621 if((unsigned int)name
> 0xffff)
2622 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod
, name
, result
);
2624 dbgprintf("GetProcAddress(0x%x, '%d') => 0x%x\n", mod
, (int)name
, result
);
2628 static long WINAPI
expCreateFileMappingA(int hFile
, void* lpAttr
,
2629 long flProtect
, long dwMaxHigh
,
2630 long dwMaxLow
, const char* name
)
2632 long result
=CreateFileMappingA(hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
);
2634 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2635 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2636 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, result
);
2638 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2639 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2640 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
, name
, result
);
2644 static long WINAPI
expOpenFileMappingA(long hFile
, long hz
, const char* name
)
2646 long result
=OpenFileMappingA(hFile
, hz
, name
);
2648 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2651 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2652 hFile
, hz
, name
, name
, result
);
2656 static void* WINAPI
expMapViewOfFile(HANDLE file
, DWORD mode
, DWORD offHigh
,
2657 DWORD offLow
, DWORD size
)
2659 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2660 file
,mode
,offHigh
,offLow
,size
,(char*)file
+offLow
);
2661 return (char*)file
+offLow
;
2664 static void* WINAPI
expUnmapViewOfFile(void* view
)
2666 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view
);
2670 static void* WINAPI
expSleep(int time
)
2673 /* solaris doesn't have thread safe usleep */
2674 struct timespec tsp
;
2675 tsp
.tv_sec
= time
/ 1000000;
2676 tsp
.tv_nsec
= (time
% 1000000) * 1000;
2677 nanosleep(&tsp
, NULL
);
2681 dbgprintf("Sleep(%d) => 0\n", time
);
2685 // why does IV32 codec want to call this? I don't know ...
2686 static int WINAPI
expCreateCompatibleDC(int hdc
)
2689 //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2690 dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc
, dc
);
2694 static int WINAPI
expGetDeviceCaps(int hdc
, int unk
)
2696 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc
, unk
);
2697 #ifdef CONFIG_QTX_CODECS
2698 #define BITSPIXEL 12
2700 if (unk
== BITSPIXEL
)
2708 static WIN_BOOL WINAPI
expDeleteDC(int hdc
)
2710 dbgprintf("DeleteDC(0x%x) => 0\n", hdc
);
2716 static WIN_BOOL WINAPI
expDeleteObject(int hdc
)
2718 dbgprintf("DeleteObject(0x%x) => 1\n", hdc
);
2719 /* FIXME - implement code here */
2723 /* btvvc32.drv wants this one */
2724 static void* WINAPI
expGetWindowDC(int hdc
)
2726 dbgprintf("GetWindowDC(%d) => 0x0\n", hdc
);
2730 #ifdef CONFIG_QTX_CODECS
2731 static int WINAPI
expGetWindowRect(HWND win
, RECT
*r
)
2733 dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win
, r
);
2734 /* (win == 0) => desktop */
2735 r
->right
= PSEUDO_SCREEN_WIDTH
;
2737 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
2742 static int WINAPI
expMonitorFromWindow(HWND win
, int flags
)
2744 dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win
, flags
);
2748 static int WINAPI
expMonitorFromRect(RECT
*r
, int flags
)
2750 dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r
, flags
);
2754 static int WINAPI
expMonitorFromPoint(void *p
, int flags
)
2756 dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p
, flags
);
2760 static int WINAPI
expEnumDisplayMonitors(void *dc
, RECT
*r
,
2761 int WINAPI (*callback_proc
)(), void *callback_param
)
2763 dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2764 dc
, r
, callback_proc
, callback_param
);
2765 return callback_proc(0, dc
, r
, callback_param
);
2769 typedef struct tagMONITORINFO
{
2774 } MONITORINFO
, *LPMONITORINFO
;
2777 #define CCHDEVICENAME 8
2778 typedef struct tagMONITORINFOEX
{
2783 TCHAR szDevice
[CCHDEVICENAME
];
2784 } MONITORINFOEX
, *LPMONITORINFOEX
;
2786 static int WINAPI
expGetMonitorInfoA(void *mon
, LPMONITORINFO lpmi
)
2788 dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon
, lpmi
);
2790 lpmi
->rcMonitor
.right
= lpmi
->rcWork
.right
= PSEUDO_SCREEN_WIDTH
;
2791 lpmi
->rcMonitor
.left
= lpmi
->rcWork
.left
= 0;
2792 lpmi
->rcMonitor
.bottom
= lpmi
->rcWork
.bottom
= PSEUDO_SCREEN_HEIGHT
;
2793 lpmi
->rcMonitor
.top
= lpmi
->rcWork
.top
= 0;
2795 lpmi
->dwFlags
= 1; /* primary monitor */
2797 if (lpmi
->cbSize
== sizeof(MONITORINFOEX
))
2799 LPMONITORINFOEX lpmiex
= (LPMONITORINFOEX
)lpmi
;
2800 dbgprintf("MONITORINFOEX!\n");
2801 strncpy(lpmiex
->szDevice
, "Monitor1", CCHDEVICENAME
);
2807 static int WINAPI
expEnumDisplayDevicesA(const char *device
, int devnum
,
2808 void *dispdev
, int flags
)
2810 dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2811 device
, device
, devnum
, dispdev
, flags
);
2815 static int WINAPI
expIsWindowVisible(HWND win
)
2817 dbgprintf("IsWindowVisible(0x%x) => 1\n", win
);
2821 static HWND WINAPI
expGetActiveWindow(void)
2823 dbgprintf("GetActiveWindow() => 0\n");
2827 static int WINAPI
expGetClassNameA(HWND win
, LPTSTR classname
, int maxcount
)
2829 strncat(classname
, "QuickTime", maxcount
);
2830 dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2831 win
, classname
, maxcount
, strlen(classname
));
2832 return strlen(classname
);
2835 #define LPWNDCLASS void *
2836 static int WINAPI
expGetClassInfoA(HINSTANCE inst
, LPCSTR classname
, LPWNDCLASS wndclass
)
2838 dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst
,
2839 classname
, classname
, wndclass
);
2843 static int WINAPI
expGetWindowLongA(HWND win
, int index
)
2845 dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win
, index
);
2849 static int WINAPI
expGetObjectA(HGDIOBJ hobj
, int objsize
, LPVOID obj
)
2851 dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj
, objsize
, obj
, objsize
);
2855 static int WINAPI
expCreateRectRgn(int x
, int y
, int width
, int height
)
2857 dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x
, y
, width
, height
);
2861 static int WINAPI
expEnumWindows(int (*callback_func
)(), void *callback_param
)
2864 dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func
, callback_param
);
2865 i
= callback_func(0, callback_param
);
2866 i2
= callback_func(1, callback_param
);
2870 static int WINAPI
expGetWindowThreadProcessId(HWND win
, int *pid_data
)
2872 int tid
= pthread_self();
2873 dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2874 win
, pid_data
, tid
);
2876 *(int*)pid_data
= tid
;
2880 //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2881 // INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2883 static HWND WINAPI
expCreateWindowExA(int exstyle
, const char *classname
,
2884 const char *winname
, int style
, int x
, int y
, int w
, int h
,
2885 HWND parent
, HMENU menu
, HINSTANCE inst
, LPVOID param
)
2887 printf("CreateWindowEx() called\n");
2888 dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2889 exstyle
, classname
, classname
, winname
, winname
, style
, x
, y
, w
, h
,
2890 parent
, menu
, inst
, param
);
2891 printf("CreateWindowEx() called okey\n");
2895 static int WINAPI
expwaveOutGetNumDevs(void)
2897 dbgprintf("waveOutGetNumDevs() => 0\n");
2903 * Returns the number of milliseconds, modulo 2^32, since the start
2904 * of the wineserver.
2906 static int WINAPI
expGetTickCount(void)
2908 static int tcstart
= 0;
2911 gettimeofday( &t
, NULL
);
2912 tc
= ((t
.tv_sec
* 1000) + (t
.tv_usec
/ 1000)) - tcstart
;
2918 dbgprintf("GetTickCount() => %d\n", tc
);
2922 static int WINAPI
expCreateFontA(void)
2924 dbgprintf("CreateFontA() => 0x0\n");
2928 /* tried to get pvmjpg work in a different way - no success */
2929 static int WINAPI
expDrawTextA(int hDC
, char* lpString
, int nCount
,
2930 LPRECT lpRect
, unsigned int uFormat
)
2932 dbgprintf("expDrawTextA(%p,...) => 8\n", hDC
);
2936 static int WINAPI
expGetPrivateProfileIntA(const char* appname
,
2937 const char* keyname
,
2939 const char* filename
)
2947 if(!(appname
&& keyname
&& filename
) )
2949 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, default_value
);
2950 return default_value
;
2952 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2953 strcpy(fullname
, "Software\\IniFileMapping\\");
2954 strcat(fullname
, appname
);
2955 strcat(fullname
, "\\");
2956 strcat(fullname
, keyname
);
2957 strcat(fullname
, "\\");
2958 strcat(fullname
, filename
);
2959 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)buffer
, &size
);
2960 if((size
>=0)&&(size
<256))
2962 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2965 result
=default_value
;
2967 result
=atoi(buffer
);
2968 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, result
);
2971 static int WINAPI
expGetProfileIntA(const char* appname
,
2972 const char* keyname
,
2975 dbgprintf("GetProfileIntA -> ");
2976 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, "default");
2979 static int WINAPI
expGetPrivateProfileStringA(const char* appname
,
2980 const char* keyname
,
2981 const char* def_val
,
2982 char* dest
, unsigned int len
,
2983 const char* filename
)
2988 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname
, keyname
, def_val
, dest
, len
, filename
);
2989 if(!(appname
&& keyname
&& filename
) ) return 0;
2990 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2991 strcpy(fullname
, "Software\\IniFileMapping\\");
2992 strcat(fullname
, appname
);
2993 strcat(fullname
, "\\");
2994 strcat(fullname
, keyname
);
2995 strcat(fullname
, "\\");
2996 strcat(fullname
, filename
);
2998 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)dest
, &size
);
3002 strncpy(dest
, def_val
, size
);
3003 if (strlen(def_val
)< size
) size
= strlen(def_val
);
3005 dbgprintf(" => %d ( '%s' )\n", size
, dest
);
3008 static int WINAPI
expWritePrivateProfileStringA(const char* appname
,
3009 const char* keyname
,
3011 const char* filename
)
3014 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname
, keyname
, string
, filename
);
3015 if(!(appname
&& keyname
&& filename
) )
3017 dbgprintf(" => -1\n");
3020 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
3021 strcpy(fullname
, "Software\\IniFileMapping\\");
3022 strcat(fullname
, appname
);
3023 strcat(fullname
, "\\");
3024 strcat(fullname
, keyname
);
3025 strcat(fullname
, "\\");
3026 strcat(fullname
, filename
);
3027 RegSetValueExA(HKEY_LOCAL_MACHINE
, fullname
, 0, REG_SZ
, (int*)string
, strlen(string
));
3028 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
3029 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
3031 dbgprintf(" => 0\n");
3035 unsigned int GetPrivateProfileIntA_(const char* appname
, const char* keyname
, INT default_value
, const char* filename
)
3037 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, filename
);
3039 int GetPrivateProfileStringA_(const char* appname
, const char* keyname
,
3040 const char* def_val
, char* dest
, unsigned int len
, const char* filename
)
3042 return expGetPrivateProfileStringA(appname
, keyname
, def_val
, dest
, len
, filename
);
3044 int WritePrivateProfileStringA_(const char* appname
, const char* keyname
,
3045 const char* string
, const char* filename
)
3047 return expWritePrivateProfileStringA(appname
, keyname
, string
, filename
);
3052 static int WINAPI
expDefDriverProc(int private, int id
, int msg
, int arg1
, int arg2
)
3054 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", private, id
, msg
, arg1
, arg2
);
3058 static int WINAPI
expSizeofResource(int v1
, int v2
)
3060 int result
=SizeofResource(v1
, v2
);
3061 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1
, v2
, result
);
3065 static int WINAPI
expGetLastError(void)
3067 int result
=GetLastError();
3068 dbgprintf("GetLastError() => 0x%x\n", result
);
3072 static void WINAPI
expSetLastError(int error
)
3074 dbgprintf("SetLastError(0x%x)\n", error
);
3075 SetLastError(error
);
3078 static int WINAPI
expStringFromGUID2(GUID
* guid
, char* str
, int cbMax
)
3080 int result
=snprintf(str
, cbMax
, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
3081 guid
->f1
, guid
->f2
, guid
->f3
,
3082 (unsigned char)guid
->f4
[0], (unsigned char)guid
->f4
[1],
3083 (unsigned char)guid
->f4
[2], (unsigned char)guid
->f4
[3],
3084 (unsigned char)guid
->f4
[4], (unsigned char)guid
->f4
[5],
3085 (unsigned char)guid
->f4
[6], (unsigned char)guid
->f4
[7]);
3086 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid
, str
, str
, cbMax
, result
);
3091 static int WINAPI
expGetFileVersionInfoSizeA(const char* name
, int* lpHandle
)
3093 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name
, name
, lpHandle
);
3097 static int WINAPI
expIsBadStringPtrW(const short* string
, int nchars
)
3100 if(string
==0)result
=1; else result
=0;
3101 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string
, nchars
, result
);
3102 if(string
)wch_print(string
);
3105 static int WINAPI
expIsBadStringPtrA(const char* string
, int nchars
)
3107 return expIsBadStringPtrW((const short*)string
, nchars
);
3109 static long WINAPI
expInterlockedExchangeAdd( long* dest
, long incr
)
3114 "lock; xaddl %0,(%1)"
3116 : "r" (dest
), "0" (incr
)
3122 static long WINAPI
expInterlockedCompareExchange( unsigned long* dest
, unsigned long exchange
, unsigned long comperand
)
3124 unsigned long retval
= *dest
;
3125 if(*dest
== comperand
)
3130 static long WINAPI
expInterlockedIncrement( long* dest
)
3132 long result
=expInterlockedExchangeAdd( dest
, 1 ) + 1;
3133 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
3136 static long WINAPI
expInterlockedDecrement( long* dest
)
3138 long result
=expInterlockedExchangeAdd( dest
, -1 ) - 1;
3139 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
3143 static void WINAPI
expOutputDebugStringA( const char* string
)
3145 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string
);
3146 fprintf(stderr
, "DEBUG: %s\n", string
);
3149 static int WINAPI
expGetDC(int hwnd
)
3151 dbgprintf("GetDC(0x%x) => 1\n", hwnd
);
3155 static int WINAPI
expReleaseDC(int hwnd
, int hdc
)
3157 dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd
, hdc
);
3161 static int WINAPI
expGetDesktopWindow(void)
3163 dbgprintf("GetDesktopWindow() => 0\n");
3167 static int cursor
[100];
3169 static int WINAPI
expLoadCursorA(int handle
,LPCSTR name
)
3171 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle
, name
, (int)&cursor
[0]);
3172 return (int)&cursor
[0];
3174 static int WINAPI
expSetCursor(void *cursor
)
3176 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor
, cursor
);
3179 static int WINAPI
expGetCursorPos(void *cursor
)
3181 dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor
, cursor
);
3184 #ifdef CONFIG_QTX_CODECS
3185 static int show_cursor
= 0;
3186 static int WINAPI
expShowCursor(int show
)
3188 dbgprintf("ShowCursor(%d) => %d\n", show
, show
);
3196 static int WINAPI
expRegisterWindowMessageA(char *message
)
3198 dbgprintf("RegisterWindowMessageA(%s)\n", message
);
3201 static int WINAPI
expGetProcessVersion(int pid
)
3203 dbgprintf("GetProcessVersion(%d)\n", pid
);
3206 static int WINAPI
expGetCurrentThread(void)
3209 dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
3212 static int WINAPI
expGetOEMCP(void)
3214 dbgprintf("GetOEMCP()\n");
3217 static int WINAPI
expGetCPInfo(int cp
,void *info
)
3219 dbgprintf("GetCPInfo()\n");
3222 #ifdef CONFIG_QTX_CODECS
3223 #define SM_CXSCREEN 0
3224 #define SM_CYSCREEN 1
3225 #define SM_XVIRTUALSCREEN 76
3226 #define SM_YVIRTUALSCREEN 77
3227 #define SM_CXVIRTUALSCREEN 78
3228 #define SM_CYVIRTUALSCREEN 79
3229 #define SM_CMONITORS 80
3231 static int WINAPI
expGetSystemMetrics(int index
)
3233 dbgprintf("GetSystemMetrics(%d)\n", index
);
3234 #ifdef CONFIG_QTX_CODECS
3237 case SM_XVIRTUALSCREEN
:
3238 case SM_YVIRTUALSCREEN
:
3241 case SM_CXVIRTUALSCREEN
:
3242 return PSEUDO_SCREEN_WIDTH
;
3244 case SM_CYVIRTUALSCREEN
:
3245 return PSEUDO_SCREEN_HEIGHT
;
3252 static int WINAPI
expGetSysColor(int index
)
3254 dbgprintf("GetSysColor(%d) => 1\n", index
);
3257 static int WINAPI
expGetSysColorBrush(int index
)
3259 dbgprintf("GetSysColorBrush(%d)\n", index
);
3265 static int WINAPI
expGetSystemPaletteEntries(int hdc
, int iStartIndex
, int nEntries
, void* lppe
)
3267 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3268 hdc
, iStartIndex
, nEntries
, lppe
);
3273 typedef struct TIME_ZONE_INFORMATION {
3275 char StandardName[32];
3276 SYSTEMTIME StandardDate;
3278 char DaylightName[32];
3279 SYSTEMTIME DaylightDate;
3281 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3284 static int WINAPI
expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation
)
3286 const short name
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3287 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3288 const short pname
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3289 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3290 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3291 memset(lpTimeZoneInformation
, 0, sizeof(TIME_ZONE_INFORMATION
));
3292 lpTimeZoneInformation
->Bias
=360;//GMT-6
3293 memcpy(lpTimeZoneInformation
->StandardName
, name
, sizeof(name
));
3294 lpTimeZoneInformation
->StandardDate
.wMonth
=10;
3295 lpTimeZoneInformation
->StandardDate
.wDay
=5;
3296 lpTimeZoneInformation
->StandardDate
.wHour
=2;
3297 lpTimeZoneInformation
->StandardBias
=0;
3298 memcpy(lpTimeZoneInformation
->DaylightName
, pname
, sizeof(pname
));
3299 lpTimeZoneInformation
->DaylightDate
.wMonth
=4;
3300 lpTimeZoneInformation
->DaylightDate
.wDay
=1;
3301 lpTimeZoneInformation
->DaylightDate
.wHour
=2;
3302 lpTimeZoneInformation
->DaylightBias
=-60;
3303 return TIME_ZONE_ID_STANDARD
;
3306 static void WINAPI
expGetLocalTime(SYSTEMTIME
* systime
)
3309 struct tm
*local_tm
;
3312 dbgprintf("GetLocalTime(0x%x)\n");
3313 gettimeofday(&tv
, NULL
);
3314 local_time
=tv
.tv_sec
;
3315 local_tm
=localtime(&local_time
);
3317 systime
->wYear
= local_tm
->tm_year
+ 1900;
3318 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3319 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3320 systime
->wDay
= local_tm
->tm_mday
;
3321 systime
->wHour
= local_tm
->tm_hour
;
3322 systime
->wMinute
= local_tm
->tm_min
;
3323 systime
->wSecond
= local_tm
->tm_sec
;
3324 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3325 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3326 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3327 " Milliseconds: %d\n",
3328 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3329 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3332 static int WINAPI
expGetSystemTime(SYSTEMTIME
* systime
)
3335 struct tm
*local_tm
;
3338 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3339 gettimeofday(&tv
, NULL
);
3340 local_time
=tv
.tv_sec
;
3341 local_tm
=gmtime(&local_time
);
3343 systime
->wYear
= local_tm
->tm_year
+ 1900;
3344 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3345 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3346 systime
->wDay
= local_tm
->tm_mday
;
3347 systime
->wHour
= local_tm
->tm_hour
;
3348 systime
->wMinute
= local_tm
->tm_min
;
3349 systime
->wSecond
= local_tm
->tm_sec
;
3350 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3351 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3352 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3353 " Milliseconds: %d\n",
3354 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3355 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3359 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3360 static void WINAPI
expGetSystemTimeAsFileTime(FILETIME
* systime
)
3363 unsigned long long secs
;
3365 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3366 gettimeofday(&tv
, NULL
);
3367 secs
= (tv
.tv_sec
+ SECS_1601_TO_1970
) * 10000000;
3368 secs
+= tv
.tv_usec
* 10;
3369 systime
->dwLowDateTime
= secs
& 0xffffffff;
3370 systime
->dwHighDateTime
= (secs
>> 32);
3373 static int WINAPI
expGetEnvironmentVariableA(const char* name
, char* field
, int size
)
3376 // printf("%s %x %x\n", name, field, size);
3377 if(field
)field
[0]=0;
3380 if (p) strncpy(field,p,size);
3382 if (strcmp(name
,"__MSVCRT_HEAP_SELECT")==0)
3383 strcpy(field
,"__GLOBAL_HEAP_SELECTED,1");
3384 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name
, name
, field
, size
, strlen(field
));
3385 return strlen(field
);
3388 static int WINAPI
expSetEnvironmentVariableA(const char *name
, const char *value
)
3390 dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name
, value
);
3394 static void* WINAPI
expCoTaskMemAlloc(ULONG cb
)
3396 return my_mreq(cb
, 0);
3398 static void WINAPI
expCoTaskMemFree(void* cb
)
3406 void* CoTaskMemAlloc(unsigned long cb
)
3408 return expCoTaskMemAlloc(cb
);
3410 void CoTaskMemFree(void* cb
)
3412 expCoTaskMemFree(cb
);
3415 struct COM_OBJECT_INFO
3418 long (*GetClassObject
) (GUID
* clsid
, const GUID
* iid
, void** ppv
);
3421 static struct COM_OBJECT_INFO
* com_object_table
=0;
3422 static int com_object_size
=0;
3423 int RegisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3427 com_object_table
=realloc(com_object_table
, sizeof(struct COM_OBJECT_INFO
)*(++com_object_size
));
3428 com_object_table
[com_object_size
-1].clsid
=*clsid
;
3429 com_object_table
[com_object_size
-1].GetClassObject
=gcs
;
3433 int UnregisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3440 if (com_object_table
== 0)
3441 printf("Warning: UnregisterComClass() called without any registered class\n");
3442 while (i
< com_object_size
)
3446 memcpy(&com_object_table
[i
- 1].clsid
,
3447 &com_object_table
[i
].clsid
, sizeof(GUID
));
3448 com_object_table
[i
- 1].GetClassObject
=
3449 com_object_table
[i
].GetClassObject
;
3451 else if (memcmp(&com_object_table
[i
].clsid
, clsid
, sizeof(GUID
)) == 0
3452 && com_object_table
[i
].GetClassObject
== gcs
)
3460 if (--com_object_size
== 0)
3462 free(com_object_table
);
3463 com_object_table
= 0;
3470 const GUID IID_IUnknown
=
3472 0x00000000, 0x0000, 0x0000,
3473 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3475 const GUID IID_IClassFactory
=
3477 0x00000001, 0x0000, 0x0000,
3478 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3481 static long WINAPI
expCoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3482 long dwClsContext
, const GUID
* riid
, void** ppv
)
3485 struct COM_OBJECT_INFO
* ci
=0;
3486 for(i
=0; i
<com_object_size
; i
++)
3487 if(!memcmp(rclsid
, &com_object_table
[i
].clsid
, sizeof(GUID
)))
3488 ci
=&com_object_table
[i
];
3489 if(!ci
)return REGDB_E_CLASSNOTREG
;
3490 // in 'real' world we should mess with IClassFactory here
3491 i
=ci
->GetClassObject(rclsid
, riid
, ppv
);
3495 long CoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3496 long dwClsContext
, const GUID
* riid
, void** ppv
)
3498 return expCoCreateInstance(rclsid
, pUnkOuter
, dwClsContext
, riid
, ppv
);
3501 static int WINAPI
expIsRectEmpty(CONST RECT
*lprc
)
3508 w
= lprc
->right
- lprc
->left
;
3509 h
= lprc
->bottom
- lprc
->top
;
3510 if (w
<= 0 || h
<= 0)
3516 dbgprintf("IsRectEmpty(%p) => %s\n", lprc
, (r
) ? "TRUE" : "FALSE");
3517 //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3518 // return 0; // wmv9?
3522 static int _adjust_fdiv
=0; //what's this? - used to adjust division
3523 static int _winver
= 0x510; // windows version
3528 static unsigned int WINAPI
expGetTempPathA(unsigned int len
, char* path
)
3530 dbgprintf("GetTempPathA(%d, 0x%x)", len
, path
);
3533 dbgprintf(" => 0\n");
3536 strcpy(path
, "/tmp");
3537 dbgprintf(" => 5 ( '/tmp' )\n");
3544 DWORD dwFileAttributes;
3545 FILETIME ftCreationTime;
3546 FILETIME ftLastAccessTime;
3547 FILETIME ftLastWriteTime;
3548 DWORD nFileSizeHigh;
3552 CHAR cFileName[260];
3553 CHAR cAlternateFileName[14];
3554 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3557 static DIR* qtx_dir
=NULL
;
3559 static WIN_BOOL WINAPI
expFindNextFileA(HANDLE h
,LPWIN32_FIND_DATAA lpfd
)
3561 #ifdef CONFIG_QTX_CODECS
3562 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h
, lpfd
);
3563 if(h
==FILE_HANDLE_quicktimeqtx
){
3565 if(!qtx_dir
) return 0;
3566 while((d
=readdir(qtx_dir
))){
3567 char* x
=strrchr(d
->d_name
,'.');
3569 if(strcmp(x
,".qtx")) continue;
3570 strcpy(lpfd
->cFileName
,d
->d_name
);
3571 // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3572 strcpy(lpfd
->cAlternateFileName
,"foobar.qtx");
3573 dbgprintf("### FindNext: %s\n",lpfd
->cFileName
);
3576 closedir(qtx_dir
); qtx_dir
=NULL
;
3583 static HANDLE WINAPI
expFindFirstFileA(LPCSTR s
, LPWIN32_FIND_DATAA lpfd
)
3585 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s
, s
, lpfd
);
3586 // printf("\n### FindFirstFileA('%s')...\n",s);
3587 #ifdef CONFIG_QTX_CODECS
3588 if(strstr(s
, "quicktime\\*.QTX")){
3589 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s
, s
, lpfd
);
3590 dbgprintf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",
3592 qtx_dir
= opendir(codec_path
);
3593 if(!qtx_dir
) return (HANDLE
)-1;
3594 memset(lpfd
,0,sizeof(*lpfd
));
3595 if(expFindNextFileA(FILE_HANDLE_quicktimeqtx
,lpfd
))
3596 return FILE_HANDLE_quicktimeqtx
;
3597 printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",
3602 if(strstr(s
, "QuickTime.qts")){
3603 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s
, s
, lpfd
);
3604 // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3605 // return (HANDLE)-1;
3606 strcpy(lpfd
->cFileName
, "QuickTime.qts");
3607 strcpy(lpfd
->cAlternateFileName
, "QuickT~1.qts");
3608 return FILE_HANDLE_quicktimeqts
;
3612 if(strstr(s
, "*.vwp")){
3613 // hack for VoxWare codec plugins:
3614 strcpy(lpfd
->cFileName
, "msms001.vwp");
3615 strcpy(lpfd
->cAlternateFileName
, "msms001.vwp");
3618 // return 'file not found'
3622 static WIN_BOOL WINAPI
expFindClose(HANDLE h
)
3624 dbgprintf("FindClose(0x%x) => 0\n", h
);
3625 #ifdef CONFIG_QTX_CODECS
3626 // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3627 // closedir(qtx_dir);
3633 static UINT WINAPI
expSetErrorMode(UINT i
)
3635 dbgprintf("SetErrorMode(%d) => 0\n", i
);
3638 static UINT WINAPI
expGetWindowsDirectoryA(LPSTR s
,UINT c
)
3640 char windir
[]="c:\\windows";
3642 strncpy(s
, windir
, c
);
3643 result
=1+((c
<strlen(windir
))?c
:strlen(windir
));
3644 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3647 #ifdef CONFIG_QTX_CODECS
3648 static UINT WINAPI
expGetCurrentDirectoryA(UINT c
, LPSTR s
)
3650 char curdir
[]="c:\\";
3652 strncpy(s
, curdir
, c
);
3653 result
=1+((c
<strlen(curdir
))?c
:strlen(curdir
));
3654 dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3658 static int WINAPI
expSetCurrentDirectoryA(const char *pathname
)
3660 dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname
, pathname
);
3662 if (strrchr(pathname
, '\\'))
3663 chdir(strcat(strrchr(pathname
, '\\')+1, '/'));
3670 static int WINAPI
expCreateDirectoryA(const char *pathname
, void *sa
)
3672 dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3673 pathname
, pathname
, sa
);
3675 p
= strrchr(pathname
, '\\')+1;
3676 strcpy(&buf
[0], p
); /* should be strncpy */
3683 if (strrchr(pathname
, '\\'))
3684 mkdir(strcat(strrchr(pathname
, '\\')+1, '/'), 666);
3686 mkdir(pathname
, 666);
3693 static WIN_BOOL WINAPI
expDeleteFileA(LPCSTR s
)
3695 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s
, s
);
3698 static WIN_BOOL WINAPI
expFileTimeToLocalFileTime(const FILETIME
* cpf
, LPFILETIME pf
)
3700 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf
, pf
);
3704 static UINT WINAPI
expGetTempFileNameA(LPCSTR cs1
,LPCSTR cs2
,UINT i
,LPSTR ps
)
3706 char mask
[16]="/tmp/AP_XXXXXX";
3708 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1
, cs1
, cs2
, cs2
, i
, ps
);
3711 dbgprintf(" => -1\n");
3714 result
=mkstemp(mask
);
3715 sprintf(ps
, "AP%d", result
);
3716 dbgprintf(" => %d\n", strlen(ps
));
3720 // This func might need proper implementation if we want AngelPotion codec.
3721 // They try to open APmpeg4v1.apl with it.
3722 // DLL will close opened file with CloseHandle().
3724 static HANDLE WINAPI
expCreateFileA(LPCSTR cs1
,DWORD i1
,DWORD i2
,
3725 LPSECURITY_ATTRIBUTES p1
, DWORD i3
,DWORD i4
,HANDLE i5
)
3727 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1
, cs1
, i1
,
3728 i2
, p1
, i3
, i4
, i5
);
3729 if((!cs1
) || (strlen(cs1
)<2))return -1;
3731 #ifdef CONFIG_QTX_CODECS
3732 if(strstr(cs1
, "QuickTime.qts"))
3735 char* tmp
= malloc(strlen(codec_path
) + 50);
3736 strcpy(tmp
, codec_path
);
3738 strcat(tmp
, "QuickTime.qts");
3739 result
=open(tmp
, O_RDONLY
);
3743 if(strstr(cs1
, ".qtx"))
3746 char* tmp
= malloc(strlen(codec_path
) + 250);
3747 char* x
=strrchr(cs1
,'\\');
3748 sprintf(tmp
, "%s/%s", codec_path
, x
? (x
+ 1) : cs1
);
3749 // printf("### Open: %s -> %s\n",cs1,tmp);
3750 result
=open(tmp
, O_RDONLY
);
3756 if(strncmp(cs1
, "AP", 2) == 0)
3759 char* tmp
= malloc(strlen(codec_path
) + 50);
3760 strcpy(tmp
, codec_path
);
3762 strcat(tmp
, "APmpg4v1.apl");
3763 result
=open(tmp
, O_RDONLY
);
3767 if (strstr(cs1
, "vp3") || strstr(cs1
, ".fpf") || strstr(cs1
, ".col"))
3771 char* tmp
=malloc(20 + strlen(cs1
));
3772 strcpy(tmp
, "/tmp/");
3777 if (tmp
[r
] == ':' || tmp
[r
] == '\\')
3781 if (GENERIC_READ
& i1
)
3783 else if (GENERIC_WRITE
& i1
)
3785 flg
|= O_WRONLY
| O_CREAT
;
3786 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp
, r
, flg
);
3788 r
=open(tmp
, flg
, S_IRWXU
);
3793 // Needed by wnvplay1.dll
3794 if (strstr(cs1
, "WINNOV.bmp"))
3797 r
=open("/dev/null", O_RDONLY
);
3802 /* we need this for some virtualdub filters */
3806 if (GENERIC_READ
& i1
)
3808 else if (GENERIC_WRITE
& i1
)
3811 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1
, r
, flg
);
3820 static UINT WINAPI
expGetSystemDirectoryA(
3821 char* lpBuffer
, // address of buffer for system directory
3822 UINT uSize
// size of directory buffer
3824 dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer
,uSize
);
3825 if(!lpBuffer
) strcpy(lpBuffer
,".");
3829 static char sysdir[]=".";
3830 static LPCSTR WINAPI expGetSystemDirectoryA(void)
3832 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3836 static DWORD WINAPI expGetFullPathNameA
3839 DWORD nBufferLength
,
3843 if(!lpFileName
) return 0;
3844 dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName
,nBufferLength
,
3845 lpBuffer
, lpFilePart
);
3847 #ifdef CONFIG_QTX_CODECS
3848 strcpy(lpFilePart
, "Quick123.qts");
3850 strcpy(lpFilePart
, lpFileName
);
3853 if (strrchr(lpFileName
, '\\'))
3854 lpFilePart
= strrchr(lpFileName
, '\\');
3856 lpFilePart
= (LPTSTR
)lpFileName
;
3858 strcpy(lpBuffer
, lpFileName
);
3859 // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3860 return strlen(lpBuffer
);
3863 static DWORD WINAPI expGetShortPathNameA
3869 if(!longpath
) return 0;
3870 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath
,shortpath
,shortlen
);
3871 strcpy(shortpath
,longpath
);
3872 return strlen(shortpath
);
3875 static WIN_BOOL WINAPI
expReadFile(HANDLE h
,LPVOID pv
,DWORD size
,LPDWORD rd
,LPOVERLAPPED unused
)
3878 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, rd
);
3879 result
=read(h
, pv
, size
);
3881 if(!result
)return 0;
3885 static WIN_BOOL WINAPI
expWriteFile(HANDLE h
,LPCVOID pv
,DWORD size
,LPDWORD wr
,LPOVERLAPPED unused
)
3888 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, wr
);
3890 result
=write(h
, pv
, size
);
3892 if(!result
)return 0;
3895 static DWORD WINAPI
expSetFilePointer(HANDLE h
, LONG val
, LPLONG ext
, DWORD whence
)
3898 dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h
, val
, ext
, ext
? *ext
: NULL
, whence
);
3899 //why would DLL want temporary file with >2Gb size?
3911 #ifdef CONFIG_QTX_CODECS
3912 if (val
== 0 && ext
!= 0)
3915 return lseek(h
, val
, wh
);
3918 static HDRVR WINAPI
expOpenDriverA(LPCSTR szDriverName
, LPCSTR szSectionName
,
3921 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3924 static HDRVR WINAPI
expOpenDriver(LPCSTR szDriverName
, LPCSTR szSectionName
,
3927 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3932 static WIN_BOOL WINAPI
expGetProcessAffinityMask(HANDLE hProcess
,
3933 LPDWORD lpProcessAffinityMask
,
3934 LPDWORD lpSystemAffinityMask
)
3936 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3937 hProcess
, lpProcessAffinityMask
, lpSystemAffinityMask
);
3938 if(lpProcessAffinityMask
)*lpProcessAffinityMask
=1;
3939 if(lpSystemAffinityMask
)*lpSystemAffinityMask
=1;
3943 // Fake implementation: does nothing, but does it right :)
3944 static WIN_BOOL WINAPI
expSetProcessAffinityMask(HANDLE hProcess
,
3945 LPDWORD dwProcessAffinityMask
)
3947 dbgprintf("SetProcessAffinityMask(0x%x, 0x%x) => 1\n",
3948 hProcess
, dwProcessAffinityMask
);
3953 static int WINAPI
expMulDiv(int nNumber
, int nNumerator
, int nDenominator
)
3955 static const long long max_int
=0x7FFFFFFFLL
;
3956 static const long long min_int
=-0x80000000LL
;
3957 long long tmp
=(long long)nNumber
*(long long)nNumerator
;
3958 dbgprintf("expMulDiv %d * %d / %d\n", nNumber
, nNumerator
, nDenominator
);
3959 if(!nDenominator
)return 1;
3961 if(tmp
<min_int
) return 1;
3962 if(tmp
>max_int
) return 1;
3966 static LONG WINAPI
explstrcmpiA(const char* str1
, const char* str2
)
3968 LONG result
=strcasecmp(str1
, str2
);
3969 dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
3973 static LONG WINAPI
explstrlenA(const char* str1
)
3975 LONG result
=strlen(str1
);
3976 dbgprintf("strlen(0x%x='%.50s') => %d\n", str1
, str1
, result
);
3980 static LONG WINAPI
explstrcpyA(char* str1
, const char* str2
)
3982 int result
= (int) strcpy(str1
, str2
);
3983 dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1
, str2
, str2
, result
);
3986 static LONG WINAPI
explstrcpynA(char* str1
, const char* str2
,int len
)
3989 if (strlen(str2
)>len
)
3990 result
= (int) strncpy(str1
, str2
,len
);
3992 result
= (int) strcpy(str1
,str2
);
3993 dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1
, str2
, str2
,len
, strlen(str2
),result
);
3996 static LONG WINAPI
explstrcatA(char* str1
, const char* str2
)
3998 int result
= (int) strcat(str1
, str2
);
3999 dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1
, str2
, str2
, result
);
4004 static LONG WINAPI
expInterlockedExchange(long *dest
, long l
)
4006 long retval
= *dest
;
4011 static void WINAPI
expInitCommonControls(void)
4013 dbgprintf("InitCommonControls called!\n");
4017 #ifdef CONFIG_QTX_CODECS
4018 /* needed by QuickTime.qts */
4019 static HWND WINAPI
expCreateUpDownControl (DWORD style
, INT x
, INT y
, INT cx
, INT cy
,
4020 HWND parent
, INT id
, HINSTANCE inst
,
4021 HWND buddy
, INT maxVal
, INT minVal
, INT curVal
)
4023 dbgprintf("CreateUpDownControl(...)\n");
4028 /* alex: implement this call! needed for 3ivx */
4029 static HRESULT WINAPI
expCoCreateFreeThreadedMarshaler(void *pUnkOuter
, void **ppUnkInner
)
4031 dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
4032 pUnkOuter
, ppUnkInner
);
4034 return ERROR_CALL_NOT_IMPLEMENTED
;
4038 static int WINAPI
expDuplicateHandle(HANDLE hSourceProcessHandle
, // handle to source process
4039 HANDLE hSourceHandle
, // handle to duplicate
4040 HANDLE hTargetProcessHandle
, // handle to target process
4041 HANDLE
* lpTargetHandle
, // duplicate handle
4042 DWORD dwDesiredAccess
, // requested access
4043 int bInheritHandle
, // handle inheritance option
4044 DWORD dwOptions
// optional actions
4047 dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
4048 hSourceProcessHandle
, hSourceHandle
, hTargetProcessHandle
,
4049 lpTargetHandle
, dwDesiredAccess
, bInheritHandle
, dwOptions
);
4050 *lpTargetHandle
= hSourceHandle
;
4054 static HRESULT WINAPI
expCoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
4056 dbgprintf("CoInitializeEx(%p, %d) called\n", lpReserved
, dwCoInit
);
4060 // required by PIM1 codec (used by win98 PCTV Studio capture sw)
4061 static HRESULT WINAPI
expCoInitialize(
4062 LPVOID lpReserved
/* [in] pointer to win32 malloc interface
4063 (obsolete, should be NULL) */
4067 * Just delegate to the newer method.
4069 return expCoInitializeEx(lpReserved
, COINIT_APARTMENTTHREADED
);
4072 static void WINAPI
expCoUninitialize(void)
4074 dbgprintf("CoUninitialize() called\n");
4077 /* allow static linking */
4078 HRESULT WINAPI
CoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
4080 return expCoInitializeEx(lpReserved
, dwCoInit
);
4082 HRESULT WINAPI
CoInitialize(LPVOID lpReserved
)
4084 return expCoInitialize(lpReserved
);
4086 void WINAPI
CoUninitialize(void)
4088 expCoUninitialize();
4091 static DWORD WINAPI expSetThreadAffinityMask
4094 DWORD dwThreadAffinityMask
4100 * no WINAPI functions - CDECL
4102 static void* expmalloc(int size
)
4105 // return malloc(size);
4106 void* result
=my_mreq(size
,0);
4107 dbgprintf("malloc(0x%x) => 0x%x\n", size
,result
);
4109 printf("WARNING: malloc() failed\n");
4112 static void expfree(void* mem
)
4114 // return free(mem);
4115 dbgprintf("free(%p)\n", mem
);
4118 /* needed by atrac3.acm */
4119 static void *expcalloc(int num
, int size
)
4121 void* result
=my_mreq(num
*size
,1);
4122 dbgprintf("calloc(%d,%d) => %p\n", num
,size
,result
);
4124 printf("WARNING: calloc() failed\n");
4127 static void* expnew(int size
)
4129 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
4130 // printf("%08x %08x %08x %08x\n",
4131 // size, *(1+(int*)&size),
4132 // *(2+(int*)&size),*(3+(int*)&size));
4136 result
=my_mreq(size
,0);
4137 dbgprintf("new(%d) => %p\n", size
, result
);
4139 printf("WARNING: new() failed\n");
4143 static int expdelete(void* memory
)
4145 dbgprintf("delete(%p)\n", memory
);
4151 * local definition - we need only the last two members at this point
4152 * otherwice we would have to introduce here GUIDs and some more types..
4154 typedef struct __attribute__((__packed__
))
4157 unsigned long cbFormat
; //0x40
4158 char* pbFormat
; //0x44
4160 static HRESULT WINAPI
expMoCopyMediaType(MY_MEDIA_TYPE
* dest
, const MY_MEDIA_TYPE
* src
)
4164 memcpy(dest
, src
, sizeof(MY_MEDIA_TYPE
));
4167 dest
->pbFormat
= (char*) my_mreq(dest
->cbFormat
, 0);
4168 if (!dest
->pbFormat
)
4169 return E_OUTOFMEMORY
;
4170 memcpy(dest
->pbFormat
, src
->pbFormat
, dest
->cbFormat
);
4174 static HRESULT WINAPI
expMoInitMediaType(MY_MEDIA_TYPE
* dest
, DWORD cbFormat
)
4178 memset(dest
, 0, sizeof(MY_MEDIA_TYPE
));
4181 dest
->pbFormat
= (char*) my_mreq(cbFormat
, 0);
4182 if (!dest
->pbFormat
)
4183 return E_OUTOFMEMORY
;
4187 static HRESULT WINAPI
expMoCreateMediaType(MY_MEDIA_TYPE
** dest
, DWORD cbFormat
)
4191 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
4192 return expMoInitMediaType(*dest
, cbFormat
);
4194 static HRESULT WINAPI
expMoDuplicateMediaType(MY_MEDIA_TYPE
** dest
, const void* src
)
4198 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
4199 return expMoCopyMediaType(*dest
, src
);
4201 static HRESULT WINAPI
expMoFreeMediaType(MY_MEDIA_TYPE
* dest
)
4207 my_release(dest
->pbFormat
);
4213 static HRESULT WINAPI
expMoDeleteMediaType(MY_MEDIA_TYPE
* dest
)
4217 expMoFreeMediaType(dest
);
4222 static int exp_snprintf( char *str
, int size
, const char *format
, ... )
4226 va_start(va
, format
);
4227 x
=snprintf(str
,size
,format
,va
);
4228 dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str
,size
,format
,x
);
4234 static int exp_initterm(int v1
, int v2
)
4236 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1
, v2
);
4240 /* merged from wine - 2002.04.21 */
4241 typedef void (*INITTERMFUNC
)();
4242 static int exp_initterm(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
4244 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start
, end
, *start
);
4249 //printf("call _initfunc: from: %p %d\n", *start);
4250 // ok this trick with push/pop is necessary as otherwice
4251 // edi/esi registers are being trashed
4270 //printf("done %p %d:%d\n", end);
4278 /* Fake _initterm_e from msvcr80.dll, needed by sirenacm.dll
4279 * NOTE: If I make this an alias for _initterm, then sirenacm.dll tries to call
4280 other uninmplemented functions; keep this in mind if some future codec needs
4281 a real implementation of this function */
4282 static int exp_initterm_e(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
4284 dbgprintf("_initterm_e(0x%x, 0x%x)\n", start
, end
);
4288 static void* exp__dllonexit(void)
4290 // FIXME extract from WINE
4294 static int expwsprintfA(char* string
, const char* format
, ...)
4298 va_start(va
, format
);
4299 result
= vsprintf(string
, format
, va
);
4300 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string
, format
, result
);
4305 static int expsprintf(char* str
, const char* format
, ...)
4309 dbgprintf("sprintf(0x%x, %s)\n", str
, format
);
4310 va_start(args
, format
);
4311 r
= vsprintf(str
, format
, args
);
4315 static int expsscanf(const char* str
, const char* format
, ...)
4319 dbgprintf("sscanf(%s, %s)\n", str
, format
);
4320 va_start(args
, format
);
4321 r
= vsscanf(str
, format
, args
);
4325 static void* expfopen(const char* path
, const char* mode
)
4327 printf("fopen: \"%s\" mode:%s\n", path
, mode
);
4328 //return fopen(path, mode);
4329 return fdopen(0, mode
); // everything on screen
4331 static int expfprintf(void* stream
, const char* format
, ...)
4335 dbgprintf("fprintf(%p, %s, ...)\n", stream
, format
);
4336 va_start(args
, format
);
4337 r
= vfprintf((FILE*) stream
, format
, args
);
4342 static int expprintf(const char* format
, ...)
4346 dbgprintf("printf(%s, ...)\n", format
);
4347 va_start(args
, format
);
4348 r
= vprintf(format
, args
);
4353 static char* expgetenv(const char* varname
)
4355 char* v
= getenv(varname
);
4356 dbgprintf("getenv(%s) => %s\n", varname
, v
);
4360 static void* expwcscpy(WCHAR
* dst
, const WCHAR
* src
)
4363 while ((*p
++ = *src
++))
4368 static char* expstrrchr(char* string
, int value
)
4370 char* result
=strrchr(string
, value
);
4372 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4374 dbgprintf("strrchr(0x%x='%s', %d) => 0", string
, string
, value
);
4378 static char* expstrchr(char* string
, int value
)
4380 char* result
=strchr(string
, value
);
4382 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4384 dbgprintf("strchr(0x%x='%s', %d) => 0", string
, string
, value
);
4387 static int expstrlen(char* str
)
4389 int result
=strlen(str
);
4390 dbgprintf("strlen(0x%x='%s') => %d\n", str
, str
, result
);
4393 static char* expstrcpy(char* str1
, const char* str2
)
4395 char* result
= strcpy(str1
, str2
);
4396 dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1
, str2
, str2
, result
);
4399 static char* expstrncpy(char* str1
, const char* str2
, size_t count
)
4401 char* result
= strncpy(str1
, str2
, count
);
4402 dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1
, str2
, str2
, count
, result
);
4405 static int expstrcmp(const char* str1
, const char* str2
)
4407 int result
=strcmp(str1
, str2
);
4408 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4411 static int expstrncmp(const char* str1
, const char* str2
,int x
)
4413 int result
=strncmp(str1
, str2
,x
);
4414 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4417 static char* expstrcat(char* str1
, const char* str2
)
4419 char* result
= strcat(str1
, str2
);
4420 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1
, str1
, str2
, str2
, result
);
4423 static char* exp_strdup(const char* str1
)
4425 int l
= strlen(str1
);
4426 char* result
= (char*) my_mreq(l
+ 1,0);
4428 strcpy(result
, str1
);
4429 dbgprintf("_strdup(0x%x='%s') => %p\n", str1
, str1
, result
);
4432 static int expisalnum(int c
)
4434 int result
= (int) isalnum(c
);
4435 dbgprintf("isalnum(0x%x='%c' => %d\n", c
, c
, result
);
4438 static int expisspace(int c
)
4440 int result
= (int) isspace(c
);
4441 dbgprintf("isspace(0x%x='%c' => %d\n", c
, c
, result
);
4444 static int expisalpha(int c
)
4446 int result
= (int) isalpha(c
);
4447 dbgprintf("isalpha(0x%x='%c' => %d\n", c
, c
, result
);
4450 static int expisdigit(int c
)
4452 int result
= (int) isdigit(c
);
4453 dbgprintf("isdigit(0x%x='%c' => %d\n", c
, c
, result
);
4456 static void* expmemmove(void* dest
, void* src
, int n
)
4458 void* result
= memmove(dest
, src
, n
);
4459 dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4462 static int expmemcmp(void* dest
, void* src
, int n
)
4464 int result
= memcmp(dest
, src
, n
);
4465 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest
, src
, n
, result
);
4468 static void* expmemcpy(void* dest
, void* src
, int n
)
4470 void *result
= memcpy(dest
, src
, n
);
4471 dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4474 static void* expmemset(void* dest
, int c
, size_t n
)
4476 void *result
= memset(dest
, c
, n
);
4477 dbgprintf("memset(0x%x, %d, %d) => %p\n", dest
, c
, n
, result
);
4480 static time_t exptime(time_t* t
)
4482 time_t result
= time(t
);
4483 dbgprintf("time(0x%x) => %d\n", t
, result
);
4487 static int exprand(void)
4492 static void expsrand(int seed
)
4499 // preferred compilation with -O2 -ffast-math !
4501 static double explog10(double x
)
4503 /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4507 static double expcos(double x
)
4509 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4515 static void explog10(void)
4526 static void expcos(void)
4537 // this seem to be the only how to make this function working properly
4538 // ok - I've spent tremendous amount of time (many many many hours
4539 // of debuging fixing & testing - it's almost unimaginable - kabi
4541 // _ftol - operated on the float value which is already on the FPU stack
4543 static void exp_ftol(void)
4547 "sub $12, %esp \n\t"
4548 "fstcw -2(%ebp) \n\t"
4550 "movw -2(%ebp), %ax \n\t"
4551 "orb $0x0C, %ah \n\t"
4552 "movw %ax, -4(%ebp) \n\t"
4553 "fldcw -4(%ebp) \n\t"
4554 "fistpl -12(%ebp) \n\t"
4555 "fldcw -2(%ebp) \n\t"
4556 "movl -12(%ebp), %eax \n\t"
4557 //Note: gcc 3.03 does not do the following op if it
4558 // knows that ebp=esp
4559 "movl %ebp, %esp \n\t"
4563 #define FPU_DOUBLES(var1,var2) double var1,var2; \
4564 __asm__ volatile( "fstpl %0;fwait" : "=m" (var2) : ); \
4565 __asm__ volatile( "fstpl %0;fwait" : "=m" (var1) : )
4567 static double exp_CIpow(void)
4571 dbgprintf("_CIpow(%lf, %lf)\n", x
, y
);
4575 static double exppow(double x
, double y
)
4577 /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4581 static double expldexp(double x
, int expo
)
4583 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4584 return ldexp(x
, expo
);
4587 static double expfrexp(double x
, int* expo
)
4589 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4590 return frexp(x
, expo
);
4595 static int exp_stricmp(const char* s1
, const char* s2
)
4597 return strcasecmp(s1
, s2
);
4600 /* from declaration taken from Wine sources - this fountion seems to be
4601 * undocumented in any M$ doc */
4602 static int exp_setjmp3(void* jmpbuf
, int x
)
4604 //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4608 //"mov 4(%%esp), %%edx \n\t"
4609 "mov (%%esp), %%eax \n\t"
4610 "mov %%eax, (%%edx) \n\t" // store ebp
4612 //"mov %%ebp, (%%edx) \n\t"
4613 "mov %%ebx, 4(%%edx) \n\t"
4614 "mov %%edi, 8(%%edx) \n\t"
4615 "mov %%esi, 12(%%edx) \n\t"
4616 "mov %%esp, 16(%%edx) \n\t"
4618 "mov 4(%%esp), %%eax \n\t"
4619 "mov %%eax, 20(%%edx) \n\t"
4621 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4622 "movl $0, 36(%%edx) \n\t"
4624 : "d"(jmpbuf
) // input
4629 "mov %%fs:0, %%eax \n\t" // unsure
4630 "mov %%eax, 24(%%edx) \n\t"
4631 "cmp $0xffffffff, %%eax \n\t"
4633 "mov %%eax, 28(%%edx) \n\t"
4643 static DWORD WINAPI
expGetCurrentProcessId(void)
4645 dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4646 return getpid(); //(DWORD)NtCurrentTeb()->pid;
4653 } TIMECAPS
, *LPTIMECAPS
;
4655 static MMRESULT WINAPI
exptimeGetDevCaps(LPTIMECAPS lpCaps
, UINT wSize
)
4657 dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps
, wSize
);
4659 lpCaps
->wPeriodMin
= 1;
4660 lpCaps
->wPeriodMax
= 65535;
4664 static MMRESULT WINAPI
exptimeBeginPeriod(UINT wPeriod
)
4666 dbgprintf("timeBeginPeriod(%u) !\n", wPeriod
);
4668 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4672 #ifdef CONFIG_QTX_CODECS
4673 static MMRESULT WINAPI
exptimeEndPeriod(UINT wPeriod
)
4675 dbgprintf("timeEndPeriod(%u) !\n", wPeriod
);
4677 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4682 static void WINAPI
expGlobalMemoryStatus(
4683 LPMEMORYSTATUS lpmem
4685 static MEMORYSTATUS cached_memstatus
;
4686 static int cache_lastchecked
= 0;
4690 if (time(NULL
)==cache_lastchecked
) {
4691 memcpy(lpmem
,&cached_memstatus
,sizeof(MEMORYSTATUS
));
4695 f
= fopen( "/proc/meminfo", "r" );
4699 int total
, used
, free
, shared
, buffers
, cached
;
4701 lpmem
->dwLength
= sizeof(MEMORYSTATUS
);
4702 lpmem
->dwTotalPhys
= lpmem
->dwAvailPhys
= 0;
4703 lpmem
->dwTotalPageFile
= lpmem
->dwAvailPageFile
= 0;
4704 while (fgets( buffer
, sizeof(buffer
), f
))
4706 /* old style /proc/meminfo ... */
4707 if (sscanf( buffer
, "Mem: %d %d %d %d %d %d", &total
, &used
, &free
, &shared
, &buffers
, &cached
))
4709 lpmem
->dwTotalPhys
+= total
;
4710 lpmem
->dwAvailPhys
+= free
+ buffers
+ cached
;
4712 if (sscanf( buffer
, "Swap: %d %d %d", &total
, &used
, &free
))
4714 lpmem
->dwTotalPageFile
+= total
;
4715 lpmem
->dwAvailPageFile
+= free
;
4718 /* new style /proc/meminfo ... */
4719 if (sscanf(buffer
, "MemTotal: %d", &total
))
4720 lpmem
->dwTotalPhys
= total
*1024;
4721 if (sscanf(buffer
, "MemFree: %d", &free
))
4722 lpmem
->dwAvailPhys
= free
*1024;
4723 if (sscanf(buffer
, "SwapTotal: %d", &total
))
4724 lpmem
->dwTotalPageFile
= total
*1024;
4725 if (sscanf(buffer
, "SwapFree: %d", &free
))
4726 lpmem
->dwAvailPageFile
= free
*1024;
4727 if (sscanf(buffer
, "Buffers: %d", &buffers
))
4728 lpmem
->dwAvailPhys
+= buffers
*1024;
4729 if (sscanf(buffer
, "Cached: %d", &cached
))
4730 lpmem
->dwAvailPhys
+= cached
*1024;
4734 if (lpmem
->dwTotalPhys
)
4736 DWORD TotalPhysical
= lpmem
->dwTotalPhys
+lpmem
->dwTotalPageFile
;
4737 DWORD AvailPhysical
= lpmem
->dwAvailPhys
+lpmem
->dwAvailPageFile
;
4738 lpmem
->dwMemoryLoad
= (TotalPhysical
-AvailPhysical
)
4739 / (TotalPhysical
/ 100);
4743 /* FIXME: should do something for other systems */
4744 lpmem
->dwMemoryLoad
= 0;
4745 lpmem
->dwTotalPhys
= 16*1024*1024;
4746 lpmem
->dwAvailPhys
= 16*1024*1024;
4747 lpmem
->dwTotalPageFile
= 16*1024*1024;
4748 lpmem
->dwAvailPageFile
= 16*1024*1024;
4750 expGetSystemInfo(&si
);
4751 lpmem
->dwTotalVirtual
= si
.lpMaximumApplicationAddress
-si
.lpMinimumApplicationAddress
;
4752 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4753 lpmem
->dwAvailVirtual
= lpmem
->dwTotalVirtual
-64*1024;
4754 memcpy(&cached_memstatus
,lpmem
,sizeof(MEMORYSTATUS
));
4755 cache_lastchecked
= time(NULL
);
4757 /* it appears some memory display programs want to divide by these values */
4758 if(lpmem
->dwTotalPageFile
==0)
4759 lpmem
->dwTotalPageFile
++;
4761 if(lpmem
->dwAvailPageFile
==0)
4762 lpmem
->dwAvailPageFile
++;
4765 static INT WINAPI
expGetThreadPriority(HANDLE hthread
)
4767 dbgprintf("GetThreadPriority(%p)\n",hthread
);
4771 /**********************************************************************
4772 * SetThreadPriority [KERNEL32.@] Sets priority for thread.
4778 static WIN_BOOL WINAPI
expSetThreadPriority(
4779 HANDLE hthread
, /* [in] Handle to thread */
4780 INT priority
) /* [in] Thread priority level */
4782 dbgprintf("SetThreadPriority(%p,%d)\n",hthread
,priority
);
4786 static void WINAPI
expTerminateProcess( DWORD process
, DWORD status
)
4788 printf("EXIT - process %ld code %ld\n", process
, status
);
4792 static void WINAPI
expExitProcess( DWORD status
)
4794 printf("EXIT - code %ld\n",status
);
4798 static INT WINAPI
expMessageBoxA(HWND hWnd
, LPCSTR text
, LPCSTR title
, UINT type
){
4799 printf("MSGBOX '%s' '%s' (%d)\n",text
,title
,type
);
4800 #ifdef CONFIG_QTX_CODECS
4801 if (type
== MB_ICONHAND
&& !strlen(text
) && !strlen(title
))
4807 /* these are needed for mss1 */
4810 * \brief this symbol is defined within exp_EH_prolog_dummy
4811 * \param dest jump target
4813 void exp_EH_prolog(void *dest
);
4814 void exp_EH_prolog_dummy(void);
4815 //! just a dummy function that acts a container for the asm section
4816 void exp_EH_prolog_dummy(void) {
4818 // take care, this "function" may not change flags or
4819 // registers besides eax (which is also why we can't use
4820 // exp_EH_prolog_dummy directly)
4821 MANGLE(exp_EH_prolog
)": \n\t"
4824 "mov %esp, %ebp \n\t"
4825 "lea -12(%esp), %esp \n\t"
4830 #include <netinet/in.h>
4831 static WINAPI
inline unsigned long int exphtonl(unsigned long int hostlong
)
4833 // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4834 return htonl(hostlong
);
4837 static WINAPI
inline unsigned long int expntohl(unsigned long int netlong
)
4839 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4840 return ntohl(netlong
);
4843 static char* WINAPI
expSysAllocStringLen(char *pch
, unsigned cch
)
4846 dbgprintf("SysAllocStringLen('%s', %d)\n", pch
, cch
);
4847 str
= malloc(cch
* 2 + sizeof(unsigned) + 2);
4848 *(unsigned *)str
= cch
;
4849 str
+= sizeof(unsigned);
4851 memcpy(str
, pch
, cch
* 2);
4853 str
[cch
* 2 + 1] = 0;
4857 static void WINAPI
expSysFreeString(char *str
)
4860 free(str
- sizeof(unsigned));
4864 static void WINAPI
expVariantInit(void* p
)
4866 printf("InitCommonControls called!\n");
4870 static int WINAPI
expRegisterClassA(const void/*WNDCLASSA*/ *wc
)
4872 dbgprintf("RegisterClassA(%p) => random id\n", wc
);
4873 return time(NULL
); /* be precise ! */
4876 static int WINAPI
expUnregisterClassA(const char *className
, HINSTANCE hInstance
)
4878 dbgprintf("UnregisterClassA(%s, %p) => 0\n", className
, hInstance
);
4882 #ifdef CONFIG_QTX_CODECS
4883 /* should be fixed bcs it's not fully strlen equivalent */
4884 static int expSysStringByteLen(void *str
)
4886 dbgprintf("SysStringByteLen(%p) => %d\n", str
, strlen(str
));
4890 static int expDirectDrawCreate(void)
4892 dbgprintf("DirectDrawCreate(...) => NULL\n");
4897 typedef struct tagPALETTEENTRY
{
4904 typedef struct tagLOGPALETTE
{
4907 PALETTEENTRY palPalEntry
[1];
4910 static HPALETTE WINAPI
expCreatePalette(CONST LOGPALETTE
*lpgpl
)
4915 dbgprintf("CreatePalette(%x) => NULL\n", lpgpl
);
4917 i
= sizeof(LOGPALETTE
)+((lpgpl
->palNumEntries
-1)*sizeof(PALETTEENTRY
));
4919 memcpy((void *)test
, lpgpl
, i
);
4924 static int expCreatePalette(void)
4926 dbgprintf("CreatePalette(...) => NULL\n");
4931 static int WINAPI
expGetClientRect(HWND win
, RECT
*r
)
4933 dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win
, r
);
4934 r
->right
= PSEUDO_SCREEN_WIDTH
;
4936 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
4942 typedef struct tagPOINT
{
4948 static int WINAPI
expClientToScreen(HWND win
, POINT
*p
)
4950 dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win
, p
, p
->x
, p
->y
);
4958 static int WINAPI
expSetThreadIdealProcessor(HANDLE thread
, int proc
)
4960 dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread
, proc
);
4964 static int WINAPI
expMessageBeep(int type
)
4966 dbgprintf("MessageBeep(%d) => 1\n", type
);
4970 static int WINAPI
expDialogBoxParamA(void *inst
, const char *name
,
4971 HWND parent
, void *dialog_func
, void *init_param
)
4973 dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
4974 inst
, name
, name
, parent
, dialog_func
, init_param
);
4978 static void WINAPI
expRegisterClipboardFormatA(const char *name
) {
4979 dbgprintf("RegisterClipboardFormatA(0x%x = %s)\n", name
, name
);
4982 /* needed by imagepower mjpeg2k */
4983 static void *exprealloc(void *ptr
, size_t size
)
4985 dbgprintf("realloc(0x%x, %x)\n", ptr
, size
);
4987 return my_mreq(size
,0);
4989 return my_realloc(ptr
, size
);
4992 /* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
4993 static WIN_BOOL WINAPI
expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn
)
4998 static char * WINAPI
expPathFindExtensionA(const char *path
) {
5003 ext
= strrchr(path
, '.');
5005 ext
= &path
[strlen(path
)];
5007 dbgprintf("PathFindExtensionA(0x%x = %s) => 0x%x, %s\n", path
, path
, ext
, ext
);
5011 static char * WINAPI
expPathFindFileNameA(const char *path
) {
5013 if (!path
|| strlen(path
) < 2)
5016 name
= strrchr(path
- 1, '\\');
5020 dbgprintf("PathFindFileNameA(0x%x = %s) => 0x%x, %s\n", path
, path
, name
, name
);
5024 static double expfloor(double x
)
5026 dbgprintf("floor(%lf)\n", x
);
5030 #define FPU_DOUBLE(var) double var; \
5031 __asm__ volatile( "fstpl %0;fwait" : "=m" (var) : )
5033 static double exp_CIcos(void)
5037 dbgprintf("_CIcos(%lf)\n", x
);
5041 static double exp_CIsin(void)
5045 dbgprintf("_CIsin(%lf)\n", x
);
5049 static double exp_CIsqrt(void)
5053 dbgprintf("_CIsqrt(%lf)\n", x
);
5057 /* Needed by rp8 sipr decoder */
5058 static LPSTR WINAPI
expCharNextA(LPCSTR ptr
)
5060 if (!*ptr
) return (LPSTR
)ptr
;
5061 // dbgprintf("CharNextA(0x%08x), %s\n", ptr, ptr);
5062 return (LPSTR
)(ptr
+ 1);
5065 // Fake implementation, needed by wvc1dmod.dll
5066 static int WINAPI
expPropVariantClear(void *pvar
)
5068 // dbgprintf("PropVariantclear (0x%08x), %s\n", ptr, ptr);
5072 // This define is fake, the real thing is a struct
5073 #define LPDEVMODEA void*
5074 // Dummy implementation, always return 1
5075 // Required for frapsvid.dll 2.8.1, return value does not matter
5076 static WIN_BOOL WINAPI
expEnumDisplaySettingsA(LPCSTR name
,DWORD n
,
5079 dbgprintf("EnumDisplaySettingsA (dummy) => 1\n");
5083 // Fake implementation of _decode_pointer from msvcr80.dll, needed by sirenacm.dll
5084 // NOTE: undocumented function, probably the declaration is not right
5085 static int exp_decode_pointer(void *ptr
)
5087 dbgprintf("_decode_pointer (0x%08x)\n", ptr
);
5091 /* Fake implementation of sdt::_Lockit::_Lockit(void) from msvcp60.dll
5092 Needed by SCLS.DLL */
5093 static int exp_0Lockit_dummy(void)
5095 dbgprintf("0Lockit_dummy (??0_Lockit@std@@QAE@XZ)\n");
5099 /* Fake implementation of sdt::_Lockit::~_Lockit(void) from msvcp60.dll
5100 Needed by SCLS.DLL */
5101 static int exp_1Lockit_dummy(void)
5103 dbgprintf("1Lockit_dummy (??1_Lockit@std@@QAE@XZ)\n");
5107 static void * WINAPI
expEncodePointer(void *p
)
5112 static void * WINAPI
expDecodePointer(void *p
)
5117 static DWORD WINAPI
expGetThreadLocale(void)
5123 * Very incomplete implementation, return an error for almost all cases.
5125 static DWORD WINAPI
expGetLocaleInfoA(DWORD locale
, DWORD lctype
, char* lpLCData
, int cchData
)
5127 if (lctype
== 0x1004) { // LOCALE_IDEFAULTANSICODEPAGE
5129 return cchData
== 0 ? 4 : 0;
5130 strcpy(lpLCData
, "437");
5146 struct exports
* exps
;
5150 {#X, Y, (void*)exp##X},
5152 #define UNDEFF(X, Y) \
5155 struct exports exp_kernel32
[]=
5157 FF(GetVolumeInformationA
,-1)
5158 FF(GetDriveTypeA
,-1)
5159 FF(GetLogicalDriveStringsA
,-1)
5160 FF(IsBadWritePtr
, 357)
5161 FF(IsBadReadPtr
, 354)
5162 FF(IsBadStringPtrW
, -1)
5163 FF(IsBadStringPtrA
, -1)
5164 FF(DisableThreadLibraryCalls
, -1)
5165 FF(CreateThread
, -1)
5166 FF(ResumeThread
, -1)
5167 FF(CreateEventA
, -1)
5168 FF(CreateEventW
, -1)
5171 FF(WaitForSingleObject
, -1)
5172 #ifdef CONFIG_QTX_CODECS
5173 FF(WaitForMultipleObjects
, -1)
5176 FF(GetSystemInfo
, -1)
5184 FF(GetProcessHeap
, -1)
5185 FF(VirtualAlloc
, -1)
5187 FF(InitializeCriticalSection
, -1)
5188 FF(InitializeCriticalSectionAndSpinCount
, -1)
5189 FF(EnterCriticalSection
, -1)
5190 FF(LeaveCriticalSection
, -1)
5191 FF(DeleteCriticalSection
, -1)
5196 FF(GetCurrentThreadId
, -1)
5197 FF(GetCurrentProcess
, -1)
5202 FF(GlobalReAlloc
, -1)
5205 FF(MultiByteToWideChar
, 427)
5206 FF(WideCharToMultiByte
, -1)
5207 FF(GetVersionExA
, -1)
5208 FF(GetVersionExW
, -1)
5209 FF(CreateSemaphoreA
, -1)
5210 FF(CreateSemaphoreW
, -1)
5211 FF(QueryPerformanceCounter
, -1)
5212 FF(QueryPerformanceFrequency
, -1)
5216 FF(GlobalHandle
, -1)
5217 FF(GlobalUnlock
, -1)
5219 FF(LoadResource
, -1)
5220 FF(ReleaseSemaphore
, -1)
5221 FF(CreateMutexA
, -1)
5222 FF(CreateMutexW
, -1)
5223 FF(ReleaseMutex
, -1)
5224 FF(SignalObjectAndWait
, -1)
5225 FF(FindResourceA
, -1)
5226 FF(LockResource
, -1)
5227 FF(FreeResource
, -1)
5228 FF(SizeofResource
, -1)
5230 FF(GetCommandLineA
, -1)
5231 FF(GetEnvironmentStringsW
, -1)
5232 FF(FreeEnvironmentStringsW
, -1)
5233 FF(FreeEnvironmentStringsA
, -1)
5234 FF(GetEnvironmentStrings
, -1)
5235 FF(GetStartupInfoA
, -1)
5236 FF(GetStdHandle
, -1)
5238 #ifdef CONFIG_QTX_CODECS
5239 FF(GetFileAttributesA
, -1)
5241 FF(SetHandleCount
, -1)
5243 FF(GetModuleFileNameA
, -1)
5244 FF(SetUnhandledExceptionFilter
, -1)
5245 FF(LoadLibraryA
, -1)
5246 FF(GetProcAddress
, -1)
5248 FF(CreateFileMappingA
, -1)
5249 FF(OpenFileMappingA
, -1)
5250 FF(MapViewOfFile
, -1)
5251 FF(UnmapViewOfFile
, -1)
5253 FF(GetModuleHandleA
, -1)
5254 FF(GetModuleHandleW
, -1)
5255 FF(GetProfileIntA
, -1)
5256 FF(GetPrivateProfileIntA
, -1)
5257 FF(GetPrivateProfileStringA
, -1)
5258 FF(WritePrivateProfileStringA
, -1)
5259 FF(GetLastError
, -1)
5260 FF(SetLastError
, -1)
5261 FF(InterlockedIncrement
, -1)
5262 FF(InterlockedDecrement
, -1)
5263 FF(GetTimeZoneInformation
, -1)
5264 FF(OutputDebugStringA
, -1)
5265 FF(GetLocalTime
, -1)
5266 FF(GetSystemTime
, -1)
5267 FF(GetSystemTimeAsFileTime
, -1)
5268 FF(GetEnvironmentVariableA
, -1)
5269 FF(SetEnvironmentVariableA
, -1)
5270 FF(RtlZeroMemory
,-1)
5271 FF(RtlMoveMemory
,-1)
5272 FF(RtlFillMemory
,-1)
5274 FF(FindFirstFileA
,-1)
5275 FF(FindNextFileA
,-1)
5277 FF(FileTimeToLocalFileTime
,-1)
5281 FF(SetFilePointer
,-1)
5282 FF(GetTempFileNameA
,-1)
5284 FF(GetSystemDirectoryA
,-1)
5285 FF(GetWindowsDirectoryA
,-1)
5286 #ifdef CONFIG_QTX_CODECS
5287 FF(GetCurrentDirectoryA
,-1)
5288 FF(SetCurrentDirectoryA
,-1)
5289 FF(CreateDirectoryA
,-1)
5291 FF(GetShortPathNameA
,-1)
5292 FF(GetFullPathNameA
,-1)
5293 FF(SetErrorMode
, -1)
5294 FF(IsProcessorFeaturePresent
, -1)
5295 FF(IsDebuggerPresent
, -1)
5296 FF(GetProcessAffinityMask
, -1)
5297 FF(InterlockedExchange
, -1)
5298 FF(InterlockedCompareExchange
, -1)
5305 FF(GetProcessVersion
,-1)
5306 FF(GetCurrentThread
,-1)
5309 FF(DuplicateHandle
,-1)
5310 FF(GetTickCount
, -1)
5311 FF(SetThreadAffinityMask
,-1)
5312 FF(GetCurrentProcessId
,-1)
5313 FF(GlobalMemoryStatus
,-1)
5314 FF(GetThreadPriority
,-1)
5315 FF(SetThreadPriority
,-1)
5316 FF(TerminateProcess
,-1)
5318 {"LoadLibraryExA", -1, (void*)&LoadLibraryExA
},
5319 FF(SetThreadIdealProcessor
,-1)
5320 FF(SetProcessAffinityMask
, -1)
5321 FF(EncodePointer
, -1)
5322 FF(DecodePointer
, -1)
5323 FF(GetThreadLocale
, -1)
5324 FF(GetLocaleInfoA
, -1)
5325 UNDEFF(FlsAlloc
, -1)
5326 UNDEFF(FlsGetValue
, -1)
5327 UNDEFF(FlsSetValue
, -1)
5331 struct exports exp_msvcrt
[]={
5337 {"??3@YAXPAX@Z", -1, expdelete
},
5338 {"??2@YAPAXI@Z", -1, expnew
},
5339 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5340 {"_winver",-1,(void*)&_winver
},
5381 /* needed by frapsvid.dll */
5382 {"strstr",-1,(char *)&strstr
},
5383 {"qsort",-1,(void *)&qsort
},
5386 {"ceil",-1,(void*)&ceil
},
5387 /* needed by imagepower mjpeg2k */
5388 {"clock",-1,(void*)&clock
},
5389 {"memchr",-1,(void*)&memchr
},
5390 {"vfprintf",-1,(void*)&vfprintf
},
5391 // {"realloc",-1,(void*)&realloc},
5393 {"puts",-1,(void*)&puts
}
5395 struct exports exp_winmm
[]={
5396 FF(GetDriverModuleHandle
, -1)
5398 FF(DefDriverProc
, -1)
5401 FF(timeGetDevCaps
, -1)
5402 FF(timeBeginPeriod
, -1)
5403 #ifdef CONFIG_QTX_CODECS
5404 FF(timeEndPeriod
, -1)
5405 FF(waveOutGetNumDevs
, -1)
5408 struct exports exp_psapi
[]={
5409 FF(GetModuleBaseNameA
, -1)
5411 struct exports exp_user32
[]={
5416 FF(GetDesktopWindow
, -1)
5422 #ifdef CONFIG_QTX_CODECS
5425 FF(RegisterWindowMessageA
,-1)
5426 FF(GetSystemMetrics
,-1)
5428 FF(GetSysColorBrush
,-1)
5432 FF(RegisterClassA
, -1)
5433 FF(UnregisterClassA
, -1)
5434 #ifdef CONFIG_QTX_CODECS
5435 FF(GetWindowRect
, -1)
5436 FF(MonitorFromWindow
, -1)
5437 FF(MonitorFromRect
, -1)
5438 FF(MonitorFromPoint
, -1)
5439 FF(EnumDisplayMonitors
, -1)
5440 FF(GetMonitorInfoA
, -1)
5441 FF(EnumDisplayDevicesA
, -1)
5442 FF(GetClientRect
, -1)
5443 FF(ClientToScreen
, -1)
5444 FF(IsWindowVisible
, -1)
5445 FF(GetActiveWindow
, -1)
5446 FF(GetClassNameA
, -1)
5447 FF(GetClassInfoA
, -1)
5448 FF(GetWindowLongA
, -1)
5450 FF(GetWindowThreadProcessId
, -1)
5451 FF(CreateWindowExA
, -1)
5454 FF(DialogBoxParamA
, -1)
5455 FF(RegisterClipboardFormatA
, -1)
5457 FF(EnumDisplaySettingsA
, -1)
5459 struct exports exp_advapi32
[]={
5461 FF(RegCreateKeyA
, -1)
5462 FF(RegCreateKeyExA
, -1)
5463 FF(RegEnumKeyExA
, -1)
5464 FF(RegEnumValueA
, -1)
5466 FF(RegOpenKeyExA
, -1)
5467 FF(RegQueryValueExA
, -1)
5468 FF(RegSetValueExA
, -1)
5469 FF(RegQueryInfoKeyA
, -1)
5471 struct exports exp_gdi32
[]={
5472 FF(CreateCompatibleDC
, -1)
5475 FF(DeleteObject
, -1)
5476 FF(GetDeviceCaps
, -1)
5477 FF(GetSystemPaletteEntries
, -1)
5478 #ifdef CONFIG_QTX_CODECS
5479 FF(CreatePalette
, -1)
5481 FF(CreateRectRgn
, -1)
5484 struct exports exp_version
[]={
5485 FF(GetFileVersionInfoSizeA
, -1)
5487 struct exports exp_ole32
[]={
5488 FF(CoCreateFreeThreadedMarshaler
,-1)
5489 FF(CoCreateInstance
, -1)
5490 FF(CoInitialize
, -1)
5491 FF(CoInitializeEx
, -1)
5492 FF(CoUninitialize
, -1)
5493 FF(CoTaskMemAlloc
, -1)
5494 FF(CoTaskMemFree
, -1)
5495 FF(StringFromGUID2
, -1)
5496 FF(PropVariantClear
, -1)
5498 // do we really need crtdll ???
5499 // msvcrt is the correct place probably...
5500 struct exports exp_crtdll
[]={
5504 struct exports exp_comctl32
[]={
5505 FF(StringFromGUID2
, -1)
5506 FF(InitCommonControls
, 17)
5507 #ifdef CONFIG_QTX_CODECS
5508 FF(CreateUpDownControl
, 16)
5511 struct exports exp_wsock32
[]={
5515 struct exports exp_msdmo
[]={
5516 FF(memcpy
, -1) // just test
5517 FF(MoCopyMediaType
, -1)
5518 FF(MoCreateMediaType
, -1)
5519 FF(MoDeleteMediaType
, -1)
5520 FF(MoDuplicateMediaType
, -1)
5521 FF(MoFreeMediaType
, -1)
5522 FF(MoInitMediaType
, -1)
5524 struct exports exp_oleaut32
[]={
5525 FF(SysAllocStringLen
, 4)
5526 FF(SysFreeString
, 6)
5528 #ifdef CONFIG_QTX_CODECS
5529 FF(SysStringByteLen
, 149)
5535 vma: Hint/Ord Member-Name
5540 2305e 167 _adjust_fdiv
5543 22ffc 176 _beginthreadex
5545 2300e 85 __CxxFrameHandler
5549 struct exports exp_pncrt
[]={
5550 FF(malloc
, -1) // just test
5551 FF(free
, -1) // just test
5552 FF(fprintf
, -1) // just test
5553 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5556 {"??3@YAXPAX@Z", -1, expdelete
},
5557 {"??2@YAPAXI@Z", -1, expnew
},
5568 #ifdef CONFIG_QTX_CODECS
5569 struct exports exp_ddraw
[]={
5570 FF(DirectDrawCreate
, -1)
5574 struct exports exp_comdlg32
[]={
5575 FF(GetOpenFileNameA
, -1)
5578 struct exports exp_shlwapi
[]={
5579 FF(PathFindExtensionA
, -1)
5580 FF(PathFindFileNameA
, -1)
5583 struct exports exp_msvcr80
[]={
5591 FF(_decode_pointer
, -1)
5592 /* needed by KGV1-VFW.dll */
5593 {"??2@YAPAXI@Z", -1, expnew
},
5594 {"??3@YAXPAX@Z", -1, expdelete
}
5597 struct exports exp_msvcp60
[]={
5598 {"??0_Lockit@std@@QAE@XZ", -1, exp_0Lockit_dummy
},
5599 {"??1_Lockit@std@@QAE@XZ", -1, exp_1Lockit_dummy
}
5603 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5605 struct libs libraries
[]={
5623 #ifdef CONFIG_QTX_CODECS
5632 static WIN_BOOL WINAPI
ext_stubs(void)
5634 // NOTE! these magic values will be replaced at runtime, make sure
5635 // add_stub can still find them if you change them.
5636 volatile int idx
= 0x0deadabc;
5637 // make sure gcc does not do eip-relative call or something like that
5638 void (* volatile my_printf
)(char *, char *) = (void *)0xdeadfbcd;
5639 my_printf("Called unk_%s\n", export_names
[idx
]);
5643 #define MAX_STUB_SIZE 0x60
5644 #define MAX_NUM_STUBS 200
5646 static char *extcode
= NULL
;
5648 static void* add_stub(void)
5652 // generated code in runtime!
5655 extcode
= mmap_anon(NULL
, MAX_NUM_STUBS
* MAX_STUB_SIZE
,
5656 PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
, 0);
5657 answ
= extcode
+ pos
* MAX_STUB_SIZE
;
5658 if (pos
>= MAX_NUM_STUBS
) {
5659 printf("too many stubs, expect crash\n");
5662 memcpy(answ
, ext_stubs
, MAX_STUB_SIZE
);
5663 for (i
= 0; i
< MAX_STUB_SIZE
- 3; i
++) {
5664 int *magic
= (int *)(answ
+ i
);
5665 if (*magic
== 0x0deadabc) {
5669 if (*magic
== 0xdeadfbcd) {
5670 *magic
= (intptr_t)printf
;
5675 printf("magic code not found in ext_subs, expect crash\n");
5682 void* LookupExternal(const char* library
, int ordinal
)
5687 printf("ERROR: library=0\n");
5688 return (void*)ext_unknown
;
5690 // printf("%x %x\n", &unk_exp1, &unk_exp2);
5692 dbgprintf("External func %s:%d\n", library
, ordinal
);
5694 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5696 if(strcasecmp(library
, libraries
[i
].name
))
5698 for(j
=0; j
<libraries
[i
].length
; j
++)
5700 if(ordinal
!=libraries
[i
].exps
[j
].id
)
5702 //printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5703 return libraries
[i
].exps
[j
].func
;
5707 #ifndef LOADLIB_TRY_NATIVE
5708 /* hack for truespeech and vssh264*/
5709 if (!strcmp(library
, "tsd32.dll") || !strcmp(library
,"vssh264dec.dll") || !strcmp(library
,"LCMW2.dll") || !strcmp(library
,"VDODEC32.dll"))
5711 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5717 hand
= LoadLibraryA(library
);
5720 wm
= MODULE32_LookupHMODULE(hand
);
5726 func
= PE_FindExportedFunction(wm
, (LPCSTR
) ordinal
, 0);
5729 printf("No such ordinal in external dll\n");
5730 FreeLibrary((int)hand
);
5734 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5740 if(pos
>150)return 0;
5741 snprintf(export_names
[pos
], sizeof(export_names
[pos
]), "%s:%d", library
, ordinal
);
5745 void* LookupExternalByName(const char* library
, const char* name
)
5748 // return (void*)ext_unknown;
5751 printf("ERROR: library=0\n");
5752 return (void*)ext_unknown
;
5754 if((unsigned long)name
<=0xffff)
5756 return LookupExternal(library
, (int)name
);
5758 dbgprintf("External func %s:%s\n", library
, name
);
5759 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5761 if(strcasecmp(library
, libraries
[i
].name
))
5763 for(j
=0; j
<libraries
[i
].length
; j
++)
5765 if(strcmp(name
, libraries
[i
].exps
[j
].name
))
5767 if((unsigned int)(libraries
[i
].exps
[j
].func
) == -1)
5768 return NULL
; //undefined func
5769 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5770 return libraries
[i
].exps
[j
].func
;
5774 #ifndef LOADLIB_TRY_NATIVE
5775 /* hack for vss h264 */
5776 if (!strcmp(library
,"vssh264core.dll") || !strcmp(library
,"3ivx.dll"))
5778 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5784 hand
= LoadLibraryA(library
);
5787 wm
= MODULE32_LookupHMODULE(hand
);
5793 func
= PE_FindExportedFunction(wm
, name
, 0);
5796 printf("No such name in external dll\n");
5797 FreeLibrary((int)hand
);
5801 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5807 if(pos
>150)return 0;// to many symbols
5808 snprintf(export_names
[pos
], sizeof(export_names
[pos
]), "%s", name
);
5812 void my_garbagecollection(void)
5815 int unfree
= 0, unfreecnt
= 0;
5821 alloc_header
* mem
= last_alloc
+ 1;
5822 unfree
+= my_size(mem
);
5824 if (my_release(mem
) != 0)
5825 // avoid endless loop when memory is trashed
5826 if (--max_fatal
< 0)
5829 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree
, unfreecnt
, last_alloc
, alccnt
);
5832 pthread_mutex_lock(&list_lock
);
5834 pthread_mutex_unlock(&list_lock
);