1 /***********************************************************
3 Win32 emulation code. Functions that emulate
4 responses from corresponding Win32 API calls.
5 Since we are not going to be able to load
6 virtually any DLL, we can only implement this
7 much, adding needed functions with each new codec.
9 Basic principle of implementation: it's not good
10 for DLL to know too much about its environment.
12 ************************************************************/
15 * Modified for use with MPlayer, detailed changelog at
16 * http://svn.mplayerhq.hu/mplayer/trunk/
23 //#define LOADLIB_TRY_NATIVE
25 /* Hack to make sure the correct function declaration in com.h is used when
26 * this file is built for the test applications with WIN32_LOADER disabled. */
31 #ifdef CONFIG_QTX_CODECS
32 #define PSEUDO_SCREEN_WIDTH /*640*/800
33 #define PSEUDO_SCREEN_HEIGHT /*480*/600
36 #include "wine/winbase.h"
37 #include "wine/winreg.h"
38 #include "wine/winnt.h"
39 #include "wine/winerror.h"
40 #include "wine/debugtools.h"
41 #include "wine/module.h"
42 #include "wine/winuser.h"
43 #include "wine/objbase.h"
64 #include <sys/types.h>
72 #ifdef HAVE_SYS_MMAN_H
75 #include "osdep/mmap.h"
77 #include "osdep/mmap_anon.h"
78 #include "libavutil/avstring.h"
79 #include "cpudetect.h"
81 static unsigned int c_localcount_tsc(void)
93 static void c_longcount_tsc(long long* z
)
98 "movl %%eax, %%ebx\n\t"
100 "movl %%eax, 0(%%ebx)\n\t"
101 "movl %%edx, 4(%%ebx)\n\t"
107 static unsigned int c_localcount_notsc(void)
112 gettimeofday(&tv
, 0);
113 return limit
*tv
.tv_usec
;
115 static void c_longcount_notsc(long long* z
)
118 unsigned long long result
;
122 gettimeofday(&tv
, 0);
125 result
+=limit
*tv
.tv_usec
;
128 static unsigned int localcount_stub(void);
129 static void longcount_stub(long long*);
130 static unsigned int (*localcount
)(void)=localcount_stub
;
131 static void (*longcount
)(long long*)=longcount_stub
;
133 static pthread_mutex_t memmut
= PTHREAD_MUTEX_INITIALIZER
;
135 static unsigned int localcount_stub(void)
137 unsigned int regs
[4];
139 if ((regs
[3] & 0x00000010) != 0)
141 localcount
=c_localcount_tsc
;
142 longcount
=c_longcount_tsc
;
146 localcount
=c_localcount_notsc
;
147 longcount
=c_longcount_notsc
;
151 static void longcount_stub(long long* z
)
153 unsigned int regs
[4];
155 if ((regs
[3] & 0x00000010) != 0)
157 localcount
=c_localcount_tsc
;
158 longcount
=c_longcount_tsc
;
162 localcount
=c_localcount_notsc
;
163 longcount
=c_longcount_notsc
;
169 int LOADER_DEBUG
=1; // active only if compiled with -DDETAILED_OUT
170 //#define DETAILED_OUT
171 static inline void dbgprintf(char* fmt
, ...)
179 f
=fopen("./log", "a");
184 vfprintf(f
, fmt
, va
);
191 if ( mp_msg_test(MSGT_WIN32
,MSGL_DBG3
) )
197 // mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va);
204 char export_names
[300][32]={
209 //#define min(x,y) ((x)<(y)?(x):(y))
211 void destroy_event(void* event
);
214 typedef struct th_list_t
{
217 struct th_list_t
* next
;
218 struct th_list_t
* prev
;
222 // have to be cleared by GARBAGE COLLECTOR
223 //static unsigned char* heap=NULL;
224 //static int heap_counter=0;
225 static tls_t
* g_tls
=NULL
;
226 static th_list
* list
=NULL
;
227 static pthread_mutex_t list_lock
= PTHREAD_MUTEX_INITIALIZER
;
230 static void test_heap(void)
235 while(offset
<heap_counter
)
237 if(*(int*)(heap
+offset
)!=0x433476)
239 printf("Heap corruption at address %d\n", offset
);
242 offset
+=8+*(int*)(heap
+offset
+4);
244 for(;offset
<min(offset
+1000, 20000000); offset
++)
245 if(heap
[offset
]!=0xCC)
247 printf("Free heap corruption at address %d\n", offset
);
255 static void* my_mreq(int size
, int to_zero
)
259 if(test
%10==0)printf("Memory: %d bytes allocated\n", heap_counter
);
263 heap
=malloc(20000000);
264 memset(heap
, 0xCC,20000000);
268 printf("No enough memory\n");
271 if(heap_counter
+size
>20000000)
273 printf("No enough memory\n");
276 *(int*)(heap
+heap_counter
)=0x433476;
278 *(int*)(heap
+heap_counter
)=size
;
280 printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size
, heap_counter
-8, heap_counter
, heap_counter
+size
);
282 memset(heap
+heap_counter
, 0, size
);
284 memset(heap
+heap_counter
, 0xcc, size
); // make crash reproducable
286 return heap
+heap_counter
-size
;
288 static int my_release(char* memory
)
293 printf("ERROR: free(0)\n");
296 if(*(int*)(memory
-8)!=0x433476)
298 printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
301 printf("Freed %d bytes of memory\n", *(int*)(memory
-4));
302 // memset(memory-8, *(int*)(memory-4), 0xCC);
308 typedef struct alloc_header_t alloc_header
;
309 struct alloc_header_t
311 // let's keep allocated data 16 byte aligned
323 static alloc_header
* last_alloc
= NULL
;
324 static int alccnt
= 0;
327 #define AREATYPE_CLIENT 0
328 #define AREATYPE_EVENT 1
329 #define AREATYPE_MUTEX 2
330 #define AREATYPE_COND 3
331 #define AREATYPE_CRITSECT 4
333 /* -- critical sections -- */
337 pthread_mutex_t mutex
;
338 pthread_cond_t unlocked
;
343 void* mreq_private(int size
, int to_zero
, int type
);
344 void* mreq_private(int size
, int to_zero
, int type
)
346 int nsize
= size
+ sizeof(alloc_header
);
347 alloc_header
* header
= malloc(nsize
);
351 memset(header
, 0, nsize
);
353 pthread_mutex_lock(&memmut
);
356 last_alloc
->next
= header
; /* set next */
359 header
->prev
= last_alloc
;
363 pthread_mutex_unlock(&memmut
);
365 header
->deadbeef
= 0xdeadbeef;
369 //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt);
373 static int my_release(void* memory
)
375 alloc_header
* header
= (alloc_header
*) memory
- 1;
377 alloc_header
* prevmem
;
378 alloc_header
* nextmem
;
383 if (header
->deadbeef
!= (long) 0xdeadbeef)
385 dbgprintf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
389 pthread_mutex_lock(&memmut
);
394 destroy_event(memory
);
397 pthread_cond_destroy((pthread_cond_t
*)memory
);
400 pthread_mutex_destroy((pthread_mutex_t
*)memory
);
402 case AREATYPE_CRITSECT
:
403 pthread_mutex_destroy(&((struct CRITSECT
*)memory
)->mutex
);
406 //memset(memory, 0xcc, header->size);
410 header
->deadbeef
= 0;
411 prevmem
= header
->prev
;
412 nextmem
= header
->next
;
415 prevmem
->next
= nextmem
;
417 nextmem
->prev
= prevmem
;
419 if (header
== last_alloc
)
420 last_alloc
= prevmem
;
424 pthread_mutex_unlock(&memmut
);
426 //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt);
431 //memset(header + 1, 0xcc, header->size);
437 static inline void* my_mreq(int size
, int to_zero
)
439 return mreq_private(size
, to_zero
, AREATYPE_CLIENT
);
442 static int my_size(void* memory
)
444 if(!memory
) return 0;
445 return ((alloc_header
*)memory
)[-1].size
;
448 static void* my_realloc(void* memory
, int size
)
453 return my_mreq(size
, 0);
454 osize
= my_size(memory
);
457 ans
= my_mreq(size
, 0);
458 memcpy(ans
, memory
, osize
);
466 * WINE API - native implementation for several win32 libraries
470 static int WINAPI
ext_unknown(void)
472 printf("Unknown func called\n");
476 static int WINAPI
expGetVolumeInformationA( const char *root
, char *label
,
477 unsigned int label_len
, unsigned int *serial
,
478 unsigned int *filename_len
,unsigned int *flags
,
479 char *fsname
, unsigned int fsname_len
)
481 dbgprintf("GetVolumeInformationA( %s, 0x%x, %ld, 0x%x, 0x%x, 0x%x, 0x%x, %ld) => 1\n",
482 root
,label
,label_len
,serial
,filename_len
,flags
,fsname
,fsname_len
);
483 //hack Do not return any real data - do nothing
487 static unsigned int WINAPI
expGetDriveTypeA( const char *root
)
489 dbgprintf("GetDriveTypeA( %s ) => %d\n",root
,DRIVE_FIXED
);
490 // hack return as Fixed Drive Type
494 static unsigned int WINAPI
expGetLogicalDriveStringsA( unsigned int len
, char *buffer
)
496 dbgprintf("GetLogicalDriveStringsA(%d, 0x%x) => 4\n",len
,buffer
);
497 // hack only have one drive c:\ in this hack
503 return 4; // 1 drive * 4 bytes (includes null)
507 static int WINAPI
expIsBadWritePtr(void* ptr
, unsigned int count
)
509 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
510 dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
513 static int WINAPI
expIsBadReadPtr(void* ptr
, unsigned int count
)
515 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
516 dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
519 static int WINAPI
expDisableThreadLibraryCalls(int module
)
521 dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module
);
525 static HMODULE WINAPI
expGetDriverModuleHandle(DRVR
* pdrv
)
531 result
=pdrv
->hDriverModule
;
532 dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv
, result
);
536 #define MODULE_HANDLE_kernel32 ((HMODULE)0x120)
537 #define MODULE_HANDLE_user32 ((HMODULE)0x121)
538 #ifdef CONFIG_QTX_CODECS
539 #define MODULE_HANDLE_wininet ((HMODULE)0x122)
540 #define MODULE_HANDLE_ddraw ((HMODULE)0x123)
541 #define MODULE_HANDLE_advapi32 ((HMODULE)0x124)
543 #define MODULE_HANDLE_comdlg32 ((HMODULE)0x125)
544 #define MODULE_HANDLE_msvcrt ((HMODULE)0x126)
545 #define MODULE_HANDLE_ole32 ((HMODULE)0x127)
546 #define MODULE_HANDLE_winmm ((HMODULE)0x128)
547 #define MODULE_HANDLE_psapi ((HMODULE)0x129)
549 // Fake PE header, since some software (and the Microsoft CRT v8 and newer)
550 // assume GetModuleHandle(NULL) returns a pointer to a PE header.
551 // We simulate a very simple header with only one section.
553 // NOTE: If you have a section called .mixcrt, the Microsoft CRT will assume
554 // it's running in a POSIX binary, and stop using EncodePointer/DecodePointer.
555 static const struct {
556 IMAGE_DOS_HEADER doshdr
;
557 IMAGE_NT_HEADERS nthdr
;
558 IMAGE_SECTION_HEADER opthdr
;
559 } __attribute__((__packed__
)) mp_exe
= {
560 .doshdr
.e_lfanew
= sizeof(IMAGE_DOS_HEADER
),
561 .nthdr
.FileHeader
.NumberOfSections
= 1,
562 .nthdr
.FileHeader
.SizeOfOptionalHeader
=
563 sizeof(IMAGE_NT_HEADERS
) - FIELD_OFFSET(IMAGE_NT_HEADERS
, OptionalHeader
), /* 0xe0 */
564 .opthdr
.Name
= ".text"
567 static HMODULE WINAPI
expGetModuleHandleA(const char* name
)
572 result
=(HMODULE
)&mp_exe
.doshdr
;
575 wm
=MODULE_FindModule(name
);
578 result
=(HMODULE
)(wm
->module
);
582 if(name
&& (strcasecmp(name
, "kernel32")==0 || !strcasecmp(name
, "kernel32.dll")))
583 result
=MODULE_HANDLE_kernel32
;
584 #ifdef CONFIG_QTX_CODECS
585 if(name
&& strcasecmp(name
, "user32")==0)
586 result
=MODULE_HANDLE_user32
;
589 dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name
, result
);
593 static HMODULE WINAPI
expGetModuleHandleW(const uint16_t* name
)
598 if (*name
> 256 || pos
>= sizeof(aname
) - 1)
600 aname
[pos
++] = *name
++;
603 return expGetModuleHandleA(aname
);
606 static void* WINAPI
expCreateThread(void* pSecAttr
, long dwStackSize
,
607 void* lpStartAddress
, void* lpParameter
,
608 long dwFlags
, long* dwThreadId
)
611 // printf("CreateThread:");
612 pth
= (pthread_t
*) my_mreq(sizeof(pthread_t
), 0);
613 pthread_create(pth
, NULL
, (void*(*)(void*))lpStartAddress
, lpParameter
);
615 printf( "WARNING: CreateThread flags not supported\n");
617 *dwThreadId
=(long)pth
;
618 pthread_mutex_lock(&list_lock
);
621 list
=my_mreq(sizeof(th_list
), 1);
622 list
->next
=list
->prev
=NULL
;
626 list
->next
=my_mreq(sizeof(th_list
), 0);
627 list
->next
->prev
=list
;
628 list
->next
->next
=NULL
;
632 pthread_mutex_unlock(&list_lock
);
633 dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
634 pSecAttr
, dwStackSize
, lpStartAddress
, lpParameter
, dwFlags
, dwThreadId
, pth
);
638 static DWORD WINAPI
expResumeThread(HANDLE hThread
)
641 dbgprintf("ResumeThread(0x%x) => 0x%x\n", hThread
, ret
);
658 struct mutex_list_t
* next
;
659 struct mutex_list_t
* prev
;
661 typedef struct mutex_list_t mutex_list
;
662 static mutex_list
* mlist
=NULL
;
663 static pthread_mutex_t mlist_lock
= PTHREAD_MUTEX_INITIALIZER
;
665 void destroy_event(void* event
)
668 pthread_mutex_lock(&mlist_lock
);
670 // printf("garbage collector: destroy_event(%x)\n", event);
673 if(pp
==(mutex_list
*)event
)
676 pp
->next
->prev
=pp
->prev
;
678 pp
->prev
->next
=pp
->next
;
679 if(mlist
==(mutex_list
*)event
)
685 printf("%x => ", pp);
690 pthread_mutex_unlock(&mlist_lock
);
695 pthread_mutex_unlock(&mlist_lock
);
698 static void* WINAPI
expCreateEventA(void* pSecAttr
, char bManualReset
,
699 char bInitialState
, const char* name
)
709 printf("%x => ", pp);
714 pthread_mutex_lock(&mlist_lock
);
717 mutex_list
* pp
=mlist
;
721 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==0))
723 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
724 pSecAttr
, bManualReset
, bInitialState
, name
, name
, pp
->pm
);
725 pthread_mutex_unlock(&mlist_lock
);
728 }while((pp
=pp
->prev
) != NULL
);
730 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
731 pthread_mutex_init(pm
, NULL
);
732 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
733 pthread_cond_init(pc
, NULL
);
736 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
737 mlist
->next
=mlist
->prev
=NULL
;
741 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
742 mlist
->next
->prev
=mlist
;
743 mlist
->next
->next
=NULL
;
746 mlist
->type
=0; /* Type Event */
749 mlist
->state
=bInitialState
;
750 mlist
->reset
=!bManualReset
;
752 strncpy(mlist
->name
, name
, 127);
756 dbgprintf("ERROR::: CreateEventA failure\n");
759 pthread_mutex_lock(pm);
762 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
763 pSecAttr
, bManualReset
, bInitialState
, name
, name
, mlist
);
765 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
766 pSecAttr
, bManualReset
, bInitialState
, mlist
);
768 pthread_mutex_unlock(&mlist_lock
);
772 static void* WINAPI
expCreateEventW(void* pSecAttr
, char bManualReset
,
773 char bInitialState
, const WCHAR
* name
)
775 char ascii_name
[256];
778 WideCharToMultiByte(65001, 0x0, name
, -1, ascii_name
, 256, NULL
, NULL
);
781 return expCreateEventA(pSecAttr
, bManualReset
, bInitialState
, aname
);
784 static void* WINAPI
expSetEvent(void* event
)
786 mutex_list
*ml
= (mutex_list
*)event
;
787 dbgprintf("SetEvent(%x) => 0x1\n", event
);
788 pthread_mutex_lock(ml
->pm
);
789 if (ml
->state
== 0) {
791 pthread_cond_signal(ml
->pc
);
793 pthread_mutex_unlock(ml
->pm
);
797 static void* WINAPI
expResetEvent(void* event
)
799 mutex_list
*ml
= (mutex_list
*)event
;
800 dbgprintf("ResetEvent(0x%x) => 0x1\n", event
);
801 pthread_mutex_lock(ml
->pm
);
803 pthread_mutex_unlock(ml
->pm
);
808 static void* WINAPI
expWaitForSingleObject(void* object
, int duration
)
810 mutex_list
*ml
= (mutex_list
*)object
;
811 // FIXME FIXME FIXME - this value is sometime unititialize !!!
812 int ret
= WAIT_FAILED
;
815 if(object
== (void*)0xcfcf9898)
818 From GetCurrentThread() documentation:
819 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.
821 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.
823 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.
825 dbgprintf("WaitForSingleObject(thread_handle) called\n");
826 return (void*)WAIT_FAILED
;
828 dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object
, duration
);
830 // See if this is a thread.
831 pthread_mutex_lock(&list_lock
);
833 while (tp
&& (tp
->thread
!= object
))
835 pthread_mutex_unlock(&list_lock
);
837 if (pthread_join(*(pthread_t
*)object
, NULL
) == 0) {
838 return (void*)WAIT_OBJECT_0
;
840 return (void*)WAIT_FAILED
;
844 // loop below was slightly fixed - its used just for checking if
845 // this object really exists in our list
848 pthread_mutex_lock(&mlist_lock
);
850 while (pp
&& (pp
->pm
!= ml
->pm
))
852 pthread_mutex_unlock(&mlist_lock
);
854 dbgprintf("WaitForSingleObject: NotFound\n");
858 pthread_mutex_lock(ml
->pm
);
862 if (duration
== 0) { /* Check Only */
863 if (ml
->state
== 1) ret
= WAIT_OBJECT_0
;
864 else ret
= WAIT_FAILED
;
866 if (duration
== -1) { /* INFINITE */
868 pthread_cond_wait(ml
->pc
,ml
->pm
);
873 if (duration
> 0) { /* Timed Wait */
874 struct timespec abstime
;
876 gettimeofday(&now
, 0);
877 abstime
.tv_sec
= now
.tv_sec
+ (now
.tv_usec
+duration
)/1000000;
878 abstime
.tv_nsec
= ((now
.tv_usec
+duration
)%1000000)*1000;
880 ret
=pthread_cond_timedwait(ml
->pc
,ml
->pm
,&abstime
);
881 if (ret
== ETIMEDOUT
) ret
= WAIT_TIMEOUT
;
882 else ret
= WAIT_OBJECT_0
;
887 case 1: /* Semaphore */
889 if(ml
->semaphore
==0) ret
= WAIT_FAILED
;
895 if (duration
== -1) {
896 if (ml
->semaphore
==0)
897 pthread_cond_wait(ml
->pc
,ml
->pm
);
904 if(ml
->lock_count
> 0 && ml
->owner
!= pthread_self()) ret
= WAIT_FAILED
;
907 ml
->owner
= pthread_self();
911 if (duration
== -1) {
912 if (ml
->lock_count
> 0 && ml
->owner
!= pthread_self()) {
913 pthread_cond_wait(ml
->pc
,ml
->pm
);
916 ml
->owner
= pthread_self();
921 pthread_mutex_unlock(ml
->pm
);
923 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object
,duration
,ml
,ret
);
927 #ifdef CONFIG_QTX_CODECS
928 static void* WINAPI
expWaitForMultipleObjects(int count
, const void** objects
,
929 int WaitAll
, int duration
)
935 dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
936 count
, objects
, WaitAll
, duration
);
938 for (i
= 0; i
< count
; i
++)
940 object
= (void *)objects
[i
];
941 ret
= expWaitForSingleObject(object
, duration
);
943 dbgprintf("WaitAll flag not yet supported...\n");
950 static void WINAPI
expExitThread(int retcode
)
952 dbgprintf("ExitThread(%d)\n", retcode
);
953 pthread_exit(&retcode
);
957 static int pf_set
= 0;
958 static BYTE PF
[64] = {0,};
960 static void DumpSystemInfo(const SYSTEM_INFO
* si
)
962 dbgprintf(" Processor architecture %d\n", si
->u
.s
.wProcessorArchitecture
);
963 dbgprintf(" Page size: %d\n", si
->dwPageSize
);
964 dbgprintf(" Minimum app address: %d\n", si
->lpMinimumApplicationAddress
);
965 dbgprintf(" Maximum app address: %d\n", si
->lpMaximumApplicationAddress
);
966 dbgprintf(" Active processor mask: 0x%x\n", si
->dwActiveProcessorMask
);
967 dbgprintf(" Number of processors: %d\n", si
->dwNumberOfProcessors
);
968 dbgprintf(" Processor type: 0x%x\n", si
->dwProcessorType
);
969 dbgprintf(" Allocation granularity: 0x%x\n", si
->dwAllocationGranularity
);
970 dbgprintf(" Processor level: 0x%x\n", si
->wProcessorLevel
);
971 dbgprintf(" Processor revision: 0x%x\n", si
->wProcessorRevision
);
974 static void WINAPI
expGetSystemInfo(SYSTEM_INFO
* si
)
976 /* FIXME: better values for the two entries below... */
977 static int cache
= 0;
978 static SYSTEM_INFO cachedsi
;
979 dbgprintf("GetSystemInfo(%p) =>\n", si
);
984 memset(PF
,0,sizeof(PF
));
987 cachedsi
.u
.s
.wProcessorArchitecture
= PROCESSOR_ARCHITECTURE_INTEL
;
988 cachedsi
.dwPageSize
= getpagesize();
990 /* FIXME: better values for the two entries below... */
991 cachedsi
.lpMinimumApplicationAddress
= (void *)0x00000000;
992 cachedsi
.lpMaximumApplicationAddress
= (void *)0x7FFFFFFF;
993 cachedsi
.dwActiveProcessorMask
= 1;
994 cachedsi
.dwNumberOfProcessors
= 1;
995 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
996 cachedsi
.dwAllocationGranularity
= 0x10000;
997 cachedsi
.wProcessorLevel
= 5; /* pentium */
998 cachedsi
.wProcessorRevision
= 0x0101;
1000 /* mplayer's way to detect PF's */
1002 #include "cpudetect.h"
1004 if (gCpuCaps
.hasMMX
)
1005 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1006 if (gCpuCaps
.hasSSE
)
1007 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1008 if (gCpuCaps
.hasSSE2
)
1009 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1010 if (gCpuCaps
.has3DNow
)
1011 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1013 if (gCpuCaps
.cpuType
== 4)
1015 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1016 cachedsi
.wProcessorLevel
= 4;
1018 else if (gCpuCaps
.cpuType
>= 5)
1020 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1021 cachedsi
.wProcessorLevel
= 5;
1025 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1026 cachedsi
.wProcessorLevel
= 3;
1028 cachedsi
.wProcessorRevision
= gCpuCaps
.cpuStepping
;
1029 cachedsi
.dwNumberOfProcessors
= 1; /* hardcoded */
1032 /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
1033 fdiv_bug and fpu emulation flags -- alex/MPlayer */
1038 FILE *f
= fopen ("/proc/cpuinfo", "r");
1042 mp_msg(MSGT_WIN32
, MSGL_WARN
, "expGetSystemInfo: "
1043 "/proc/cpuinfo not readable! "
1044 "Expect bad performance and/or weird behaviour\n");
1047 while (fgets(line
,200,f
)!=NULL
) {
1050 /* NOTE: the ':' is the only character we can rely on */
1051 if (!(value
= strchr(line
,':')))
1053 /* terminate the valuename */
1055 /* skip any leading spaces */
1056 while (*value
==' ') value
++;
1057 if ((s
=strchr(value
,'\n')))
1061 if (!lstrncmpiA(line
, "cpu family",strlen("cpu family"))) {
1062 if (isdigit (value
[0])) {
1063 switch (value
[0] - '0') {
1064 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1065 cachedsi
.wProcessorLevel
= 3;
1067 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1068 cachedsi
.wProcessorLevel
= 4;
1070 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1071 cachedsi
.wProcessorLevel
= 5;
1073 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1074 cachedsi
.wProcessorLevel
= 5;
1076 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1077 cachedsi
.wProcessorLevel
= 5;
1081 /* set the CPU type of the current processor */
1082 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1085 /* old 2.0 method */
1086 if (!lstrncmpiA(line
, "cpu",strlen("cpu"))) {
1087 if ( isdigit (value
[0]) && value
[1] == '8' &&
1088 value
[2] == '6' && value
[3] == 0
1090 switch (value
[0] - '0') {
1091 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1092 cachedsi
.wProcessorLevel
= 3;
1094 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1095 cachedsi
.wProcessorLevel
= 4;
1097 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1098 cachedsi
.wProcessorLevel
= 5;
1100 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1101 cachedsi
.wProcessorLevel
= 5;
1103 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1104 cachedsi
.wProcessorLevel
= 5;
1108 /* set the CPU type of the current processor */
1109 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1112 if (!lstrncmpiA(line
,"fdiv_bug",strlen("fdiv_bug"))) {
1113 if (!lstrncmpiA(value
,"yes",3))
1114 PF
[PF_FLOATING_POINT_PRECISION_ERRATA
] = TRUE
;
1118 if (!lstrncmpiA(line
,"fpu",strlen("fpu"))) {
1119 if (!lstrncmpiA(value
,"no",2))
1120 PF
[PF_FLOATING_POINT_EMULATED
] = TRUE
;
1124 if (!lstrncmpiA(line
,"processor",strlen("processor"))) {
1125 /* processor number counts up...*/
1128 if (sscanf(value
,"%d",&x
))
1129 if (x
+1>cachedsi
.dwNumberOfProcessors
)
1130 cachedsi
.dwNumberOfProcessors
=x
+1;
1132 /* Create a new processor subkey on a multiprocessor
1135 sprintf(buf
,"%d",x
);
1137 if (!lstrncmpiA(line
,"stepping",strlen("stepping"))) {
1140 if (sscanf(value
,"%d",&x
))
1141 cachedsi
.wProcessorRevision
= x
;
1144 ( (!lstrncmpiA(line
,"flags",strlen("flags")))
1145 || (!lstrncmpiA(line
,"features",strlen("features"))) )
1147 if (strstr(value
,"cx8"))
1148 PF
[PF_COMPARE_EXCHANGE_DOUBLE
] = TRUE
;
1149 if (strstr(value
,"mmx"))
1150 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1151 if (strstr(value
,"tsc"))
1152 PF
[PF_RDTSC_INSTRUCTION_AVAILABLE
] = TRUE
;
1153 if (strstr(value
,"xmm") || strstr(value
,"sse"))
1154 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1155 if (strstr(value
,"sse2"))
1156 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1157 if (strstr(value
,"3dnow"))
1158 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1163 #endif /* __linux__ */
1166 memcpy(si
,&cachedsi
,sizeof(*si
));
1170 // avoid undefined expGetSystemInfo
1171 static WIN_BOOL WINAPI
expIsProcessorFeaturePresent(DWORD v
)
1173 WIN_BOOL result
= 0;
1177 expGetSystemInfo(&si
);
1179 if(v
<64) result
=PF
[v
];
1180 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v
, result
);
1184 static WIN_BOOL WINAPI
expIsDebuggerPresent(void)
1189 static long WINAPI
expGetVersion(void)
1191 dbgprintf("GetVersion() => 0xC0000004\n");
1192 return 0xC0000004;//Windows 95
1195 static HANDLE WINAPI
expHeapCreate(long flags
, long init_size
, long max_size
)
1197 // printf("HeapCreate:");
1200 result
=(HANDLE
)my_mreq(0x110000, 0);
1202 result
=(HANDLE
)my_mreq((init_size
+ 0xfff) & 0x7ffff000 , 0);
1203 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags
, init_size
, max_size
, result
);
1207 // this is another dirty hack
1208 // VP31 is releasing one allocated Heap chunk twice
1209 // we will silently ignore this second call...
1210 static void* heapfreehack
= 0;
1211 static int heapfreehackshown
= 0;
1212 //void trapbug(void);
1213 static void* WINAPI
expHeapAlloc(HANDLE heap
, int flags
, int size
)
1217 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1218 HeapAlloc returns area larger than size argument :-/
1220 actually according to M$ Doc HeapCreate size should be rounded
1221 to page boundaries thus we should simulate this
1223 //if (size == 22276) trapbug();
1224 z
=my_mreq((size
+ 0xfff) & 0x7ffff000, (flags
& HEAP_ZERO_MEMORY
));
1226 printf("HeapAlloc failure\n");
1227 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap
, flags
, size
, z
);
1228 heapfreehack
= 0; // reset
1231 static long WINAPI
expHeapDestroy(void* heap
)
1233 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap
);
1238 static long WINAPI
expHeapFree(HANDLE heap
, DWORD dwFlags
, LPVOID lpMem
)
1240 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap
, dwFlags
, lpMem
);
1241 if (heapfreehack
!= lpMem
&& lpMem
!= (void*)0xffffffff
1242 && lpMem
!= (void*)0xbdbdbdbd)
1243 // 0xbdbdbdbd is for i263_drv.drv && libefence
1244 // it seems to be reading from relased memory
1245 // EF_PROTECT_FREE doens't show any probleme
1249 if (!heapfreehackshown
++)
1250 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem
);
1252 heapfreehack
= lpMem
;
1255 static long WINAPI
expHeapSize(int heap
, int flags
, void* pointer
)
1257 long result
=my_size(pointer
);
1258 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap
, flags
, pointer
, result
);
1261 static void* WINAPI
expHeapReAlloc(HANDLE heap
,int flags
,void *lpMem
,int size
)
1263 long orgsize
= my_size(lpMem
);
1264 dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize
,size
);
1265 return my_realloc(lpMem
, size
);
1267 static long WINAPI
expGetProcessHeap(void)
1269 dbgprintf("GetProcessHeap() => 1\n");
1272 static void* WINAPI
expVirtualAlloc(void* v1
, long v2
, long v3
, long v4
)
1274 void* z
= VirtualAlloc(v1
, v2
, v3
, v4
);
1276 printf("VirtualAlloc failure\n");
1277 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1
,v2
,v3
,v4
, z
);
1280 static int WINAPI
expVirtualFree(void* v1
, int v2
, int v3
)
1282 int result
= VirtualFree(v1
,v2
,v3
);
1283 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1
,v2
,v3
, result
);
1287 /* we're building a table of critical sections. cs_win pointer uses the DLL
1288 cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1289 struct critsecs_list_t
1291 CRITICAL_SECTION
*cs_win
;
1292 struct CRITSECT
*cs_unix
;
1295 /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1296 #undef CRITSECS_NEWTYPE
1297 //#define CRITSECS_NEWTYPE 1
1299 #ifdef CRITSECS_NEWTYPE
1300 /* increased due to ucod needs more than 32 entries */
1301 /* and 64 should be enough for everything */
1302 #define CRITSECS_LIST_MAX 64
1303 static struct critsecs_list_t critsecs_list
[CRITSECS_LIST_MAX
];
1305 static int critsecs_get_pos(CRITICAL_SECTION
*cs_win
)
1309 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1310 if (critsecs_list
[i
].cs_win
== cs_win
)
1315 static int critsecs_get_unused(void)
1319 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1320 if (critsecs_list
[i
].cs_win
== NULL
)
1325 struct CRITSECT
*critsecs_get_unix(CRITICAL_SECTION
*cs_win
)
1329 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1330 if (critsecs_list
[i
].cs_win
== cs_win
&& critsecs_list
[i
].cs_unix
)
1331 return critsecs_list
[i
].cs_unix
;
1336 static void WINAPI
expInitializeCriticalSection(CRITICAL_SECTION
* c
)
1338 dbgprintf("InitializeCriticalSection(0x%x)\n", c
);
1339 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1341 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1342 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1345 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1346 #ifdef CRITSECS_NEWTYPE
1348 struct CRITSECT
*cs
;
1349 int i
= critsecs_get_unused();
1353 printf("InitializeCriticalSection(%p) - no more space in list\n", c
);
1356 dbgprintf("got unused space at %d\n", i
);
1357 cs
= malloc(sizeof(struct CRITSECT
));
1360 printf("InitializeCriticalSection(%p) - out of memory\n", c
);
1363 pthread_mutex_init(&cs
->mutex
, NULL
);
1364 pthread_cond_init(&cs
->unlocked
, NULL
);
1366 critsecs_list
[i
].cs_win
= c
;
1367 critsecs_list
[i
].cs_unix
= cs
;
1368 dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1373 struct CRITSECT
* cs
= mreq_private(sizeof(struct CRITSECT
) + sizeof(CRITICAL_SECTION
),
1374 0, AREATYPE_CRITSECT
);
1375 pthread_mutex_init(&cs
->mutex
, NULL
);
1376 pthread_cond_init(&cs
->unlocked
, NULL
);
1378 cs
->deadbeef
= 0xdeadbeef;
1385 static WIN_BOOL WINAPI
expInitializeCriticalSectionAndSpinCount(CRITICAL_SECTION
* c
, DWORD spin
)
1387 expInitializeCriticalSection(c
);
1391 static void WINAPI
expEnterCriticalSection(CRITICAL_SECTION
* c
)
1393 #ifdef CRITSECS_NEWTYPE
1394 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1396 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1398 dbgprintf("EnterCriticalSection(0x%x) %p\n",c
, cs
);
1401 dbgprintf("entered uninitialized critisec!\n");
1402 expInitializeCriticalSection(c
);
1403 #ifdef CRITSECS_NEWTYPE
1404 cs
=critsecs_get_unix(c
);
1406 cs
= (*(struct CRITSECT
**)c
);
1408 dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c
);
1410 pthread_mutex_lock(&(cs
->mutex
));
1411 if (cs
->lock_count
> 0 && cs
->id
== pthread_self()) {
1414 while (cs
->lock_count
!= 0) {
1415 pthread_cond_wait(&(cs
->unlocked
), &(cs
->mutex
));
1418 cs
->id
= pthread_self();
1420 pthread_mutex_unlock(&(cs
->mutex
));
1423 static void WINAPI
expLeaveCriticalSection(CRITICAL_SECTION
* c
)
1425 #ifdef CRITSECS_NEWTYPE
1426 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1428 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1430 // struct CRITSECT* cs=(struct CRITSECT*)c;
1431 dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c
, cs
);
1434 dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c
);
1437 pthread_mutex_lock(&(cs
->mutex
));
1438 if (cs
->lock_count
== 0) {
1439 dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c
);
1443 if (cs
->lock_count
== 0) {
1444 pthread_cond_signal(&(cs
->unlocked
));
1446 pthread_mutex_unlock(&(cs
->mutex
));
1450 static void expfree(void* mem
); /* forward declaration */
1452 static void WINAPI
expDeleteCriticalSection(CRITICAL_SECTION
*c
)
1454 #ifdef CRITSECS_NEWTYPE
1455 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1457 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1459 // struct CRITSECT* cs=(struct CRITSECT*)c;
1460 dbgprintf("DeleteCriticalSection(0x%x)\n",c
);
1464 dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c
);
1468 pthread_mutex_lock(&(cs
->mutex
));
1469 if (cs
->lock_count
> 0)
1471 dbgprintf("Win32 Warning: Deleting locked Critical Section %p!!\n", c
);
1473 pthread_mutex_unlock(&(cs
->mutex
));
1476 pthread_mutex_destroy(&(cs
->mutex
));
1477 pthread_cond_destroy(&(cs
->unlocked
));
1478 // released by GarbageCollector in my_relase otherwise
1481 #ifdef CRITSECS_NEWTYPE
1483 int i
= critsecs_get_pos(c
);
1487 printf("DeleteCriticalSection(%p) error (critsec not found)\n", c
);
1491 critsecs_list
[i
].cs_win
= NULL
;
1492 expfree(critsecs_list
[i
].cs_unix
);
1493 critsecs_list
[i
].cs_unix
= NULL
;
1494 dbgprintf("DeleteCriticalSection -> itemno=%d\n", i
);
1499 static int WINAPI
expGetCurrentThreadId(void)
1501 dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1502 return pthread_self();
1504 static int WINAPI
expGetCurrentProcess(void)
1506 dbgprintf("GetCurrentProcess() => %d\n", getpid());
1510 #ifdef CONFIG_QTX_CODECS
1511 // this version is required for Quicktime codecs (.qtx/.qts) to work.
1512 // (they assume some pointers at FS: segment)
1514 extern void* fs_seg
;
1516 //static int tls_count;
1517 static int tls_use_map
[64];
1518 static int WINAPI
expTlsAlloc(void)
1522 if(tls_use_map
[i
]==0)
1525 dbgprintf("TlsAlloc() => %d\n",i
);
1528 dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1532 //static int WINAPI expTlsSetValue(DWORD index, void* value)
1533 static int WINAPI
expTlsSetValue(int index
, void* value
)
1535 dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index
,value
);
1536 // if((index<0) || (index>64))
1539 *(void**)((char*)fs_seg
+0x88+4*index
) = value
;
1543 static void* WINAPI
expTlsGetValue(DWORD index
)
1545 dbgprintf("TlsGetValue(%d)\n",index
);
1546 // if((index<0) || (index>64))
1547 if((index
>=64)) return NULL
;
1548 return *(void**)((char*)fs_seg
+0x88+4*index
);
1551 static int WINAPI
expTlsFree(int idx
)
1553 int index
= (int) idx
;
1554 dbgprintf("TlsFree(%d)\n",index
);
1555 if((index
<0) || (index
>64))
1557 tls_use_map
[index
]=0;
1569 static void* WINAPI
expTlsAlloc(void)
1573 g_tls
=my_mreq(sizeof(tls_t
), 0);
1574 g_tls
->next
=g_tls
->prev
=NULL
;
1578 g_tls
->next
=my_mreq(sizeof(tls_t
), 0);
1579 g_tls
->next
->prev
=g_tls
;
1580 g_tls
->next
->next
=NULL
;
1583 dbgprintf("TlsAlloc() => 0x%x\n", g_tls
);
1585 g_tls
->value
=0; /* XXX For Divx.dll */
1589 static int WINAPI
expTlsSetValue(void* idx
, void* value
)
1591 tls_t
* index
= (tls_t
*) idx
;
1600 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index
, value
, result
);
1603 static void* WINAPI
expTlsGetValue(void* idx
)
1605 tls_t
* index
= (tls_t
*) idx
;
1610 result
=index
->value
;
1611 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index
, result
);
1614 static int WINAPI
expTlsFree(void* idx
)
1616 tls_t
* index
= (tls_t
*) idx
;
1623 index
->next
->prev
=index
->prev
;
1625 index
->prev
->next
=index
->next
;
1627 g_tls
= index
->prev
;
1628 my_release((void*)index
);
1631 dbgprintf("TlsFree(index 0x%x) => %d\n", index
, result
);
1636 static void* WINAPI
expLocalAlloc(int flags
, int size
)
1638 void* z
= my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1640 printf("LocalAlloc() failed\n");
1641 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1645 static void* WINAPI
expLocalReAlloc(int handle
,int size
, int flags
)
1651 if (flags
& LMEM_MODIFY
) {
1652 dbgprintf("LocalReAlloc MODIFY\n");
1653 return (void *)handle
;
1655 oldsize
= my_size((void *)handle
);
1656 newpointer
= my_realloc((void *)handle
,size
);
1657 dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle
,size
,oldsize
, flags
,newpointer
);
1662 static void* WINAPI
expLocalLock(void* z
)
1664 dbgprintf("LocalLock(0x%x) => 0x%x\n", z
, z
);
1668 static void* WINAPI
expGlobalAlloc(int flags
, int size
)
1671 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size
, flags
);
1673 z
=my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1674 //z=calloc(size, 1);
1677 printf("GlobalAlloc() failed\n");
1678 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1681 static void* WINAPI
expGlobalLock(void* z
)
1683 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z
, z
);
1686 // pvmjpg20 - but doesn't work anyway
1687 static int WINAPI
expGlobalSize(void* amem
)
1691 alloc_header
* header
= last_alloc
;
1692 alloc_header
* mem
= (alloc_header
*) amem
- 1;
1695 pthread_mutex_lock(&memmut
);
1698 if (header
->deadbeef
!= 0xdeadbeef)
1700 dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
1706 size
= header
->size
;
1710 header
= header
->prev
;
1712 pthread_mutex_unlock(&memmut
);
1715 dbgprintf("GlobalSize(0x%x)\n", amem
);
1719 static int WINAPI
expLoadIconA( long hinstance
, char *name
)
1721 dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance
,name
);
1725 static int WINAPI
expLoadStringA(long instance
, long id
, void* buf
, long size
)
1727 int result
=LoadStringA(instance
, id
, buf
, size
);
1729 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1730 instance
, id
, buf
, size
, result
, buf
);
1732 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1733 // instance, id, buf, size, result);
1737 static long WINAPI
expMultiByteToWideChar(long v1
, long v2
, char* s1
, long siz1
, short* s2
, int siz2
)
1746 if(siz1
>siz2
/2)siz1
=siz2
/2;
1747 for(i
=1; i
<=siz1
; i
++)
1757 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1758 "size %d, dest buffer 0x%x, dest size %d) => %d\n",
1759 v1
, v2
, s1
, s1
, siz1
, s2
, siz2
, result
);
1761 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1762 "size %d, dest buffer 0x%x, dest size %d) =>\n",
1763 v1
, v2
, siz1
, s2
, siz2
, result
);
1766 static void wch_print(const short* str
)
1768 dbgprintf(" src: ");
1769 while(*str
)dbgprintf("%c", *str
++);
1772 static long WINAPI
expWideCharToMultiByte(long v1
, long v2
, short* s1
, long siz1
,
1773 char* s2
, int siz2
, char* c3
, int* siz3
)
1776 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1777 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1778 result
=WideCharToMultiByte(v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1779 dbgprintf("=> %d\n", result
);
1780 //if(s1)wch_print(s1);
1781 if(s2
)dbgprintf(" dest: %s\n", s2
);
1785 static long WINAPI
expGetVersionExA(OSVERSIONINFOA
* c
)
1787 dbgprintf("GetVersionExA(0x%x) => 1\n", c
);
1788 c
->dwOSVersionInfoSize
=sizeof(*c
);
1789 c
->dwMajorVersion
=5;
1790 c
->dwMinorVersion
=1;
1791 c
->dwBuildNumber
=0x5010a28;
1792 c
->dwPlatformId
=VER_PLATFORM_WIN32_NT
;
1793 strcpy(c
->szCSDVersion
, "Service Pack 2");
1794 dbgprintf(" Major version: 5\n Minor version: 1\n Build number: 0x5010a28\n"
1795 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 2'\n");
1799 static long WINAPI
expGetVersionExW(OSVERSIONINFOW
* c
)
1801 char CSDVersion
[128];
1802 dbgprintf("GetVersionExW(0x%x) => 1\n", c
);
1803 c
->dwOSVersionInfoSize
=sizeof(*c
);
1804 c
->dwMajorVersion
=5;
1805 c
->dwMinorVersion
=1;
1806 c
->dwBuildNumber
=0x5010a28;
1807 c
->dwPlatformId
=VER_PLATFORM_WIN32_NT
;
1808 strcpy(CSDVersion
, "Service Pack 2");
1809 MultiByteToWideChar(65001, 0x0, CSDVersion
, -1, c
->szCSDVersion
, 128);
1810 dbgprintf(" Major version: 5\n Minor version: 1\n Build number: 0x5010a28\n"
1811 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 2'\n");
1815 static HANDLE WINAPI
expCreateSemaphoreA(char* v1
, long init_count
,
1816 long max_count
, char* name
)
1818 pthread_mutex_t
*pm
;
1823 printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1827 printf("%p => ", pp);
1832 pthread_mutex_lock(&mlist_lock
);
1835 mutex_list
* pp
=mlist
;
1839 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==1))
1841 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1842 v1
, init_count
, max_count
, name
, name
, mlist
);
1843 ret
= (HANDLE
)mlist
;
1844 pthread_mutex_unlock(&mlist_lock
);
1847 }while((pp
=pp
->prev
) != NULL
);
1849 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
1850 pthread_mutex_init(pm
, NULL
);
1851 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
1852 pthread_cond_init(pc
, NULL
);
1855 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1856 mlist
->next
=mlist
->prev
=NULL
;
1860 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1861 mlist
->next
->prev
=mlist
;
1862 mlist
->next
->next
=NULL
;
1864 // printf("new semaphore %p\n", mlist);
1866 mlist
->type
=1; /* Type Semaphore */
1871 mlist
->semaphore
=init_count
;
1873 strncpy(mlist
->name
, name
, 64);
1877 dbgprintf("ERROR::: CreateSemaphoreA failure\n");
1879 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1880 v1
, init_count
, max_count
, name
, name
, mlist
);
1882 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1883 v1
, init_count
, max_count
, mlist
);
1884 ret
= (HANDLE
)mlist
;
1885 pthread_mutex_unlock(&mlist_lock
);
1889 static HANDLE WINAPI
expCreateSemaphoreW(char* v1
, long init_count
,
1890 long max_count
, const WCHAR
* name
)
1892 char ascii_name
[256];
1895 WideCharToMultiByte(65001, 0x0, name
, -1, ascii_name
, 256, NULL
, NULL
);
1898 return expCreateSemaphoreA(v1
, init_count
, max_count
, aname
);
1901 static long WINAPI
expReleaseSemaphore(long hsem
, long increment
, long* prev_count
)
1903 // The state of a semaphore object is signaled when its count
1904 // is greater than zero and nonsignaled when its count is equal to zero
1905 // Each time a waiting thread is released because of the semaphore's signaled
1906 // state, the count of the semaphore is decreased by one.
1907 mutex_list
*ml
= (mutex_list
*)hsem
;
1909 pthread_mutex_lock(ml
->pm
);
1910 if (prev_count
!= 0) *prev_count
= ml
->semaphore
;
1911 if (ml
->semaphore
== 0) pthread_cond_signal(ml
->pc
);
1912 ml
->semaphore
+= increment
;
1913 pthread_mutex_unlock(ml
->pm
);
1914 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1915 hsem
, increment
, prev_count
);
1919 static HANDLE WINAPI
expCreateMutexA(void *pSecAttr
,
1920 char bInitialOwner
, const char *name
)
1922 pthread_mutex_t
*pm
;
1925 pthread_mutex_lock(&mlist_lock
);
1928 mutex_list
* pp
=mlist
;
1932 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==2))
1934 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n", pSecAttr
, bInitialOwner
, name
, mlist
);
1935 ret
= (HANDLE
)mlist
;
1936 pthread_mutex_unlock(&mlist_lock
);
1939 }while((pp
=pp
->prev
) != NULL
);
1941 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
1942 pthread_mutex_init(pm
, NULL
);
1943 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
1944 pthread_cond_init(pc
, NULL
);
1947 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1948 mlist
->next
=mlist
->prev
=NULL
;
1952 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1953 mlist
->next
->prev
=mlist
;
1954 mlist
->next
->next
=NULL
;
1957 mlist
->type
=2; /* Type Mutex */
1963 if (bInitialOwner
) {
1964 mlist
->owner
= pthread_self();
1965 mlist
->lock_count
= 1;
1967 mlist
->owner
= (pthread_t
)0;
1968 mlist
->lock_count
= 0;
1971 strncpy(mlist
->name
, name
, 64);
1975 dbgprintf("ERROR::: CreateMutexA failure\n");
1977 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
1978 pSecAttr
, bInitialOwner
, name
, mlist
);
1980 dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
1981 pSecAttr
, bInitialOwner
, mlist
);
1982 ret
= (HANDLE
)mlist
;
1983 pthread_mutex_unlock(&mlist_lock
);
1987 static HANDLE WINAPI
expCreateMutexW(void *pSecAttr
, char bInitialOwner
, const WCHAR
*name
)
1989 char ascii_name
[256];
1992 WideCharToMultiByte(65001, 0x0, name
, -1, ascii_name
, 256, NULL
, NULL
);
1995 return expCreateMutexA(pSecAttr
, bInitialOwner
, aname
);
1998 static int WINAPI
expReleaseMutex(HANDLE hMutex
)
2000 mutex_list
*ml
= (mutex_list
*)hMutex
;
2002 pthread_mutex_lock(ml
->pm
);
2003 if (--ml
->lock_count
== 0) pthread_cond_signal(ml
->pc
);
2004 pthread_mutex_unlock(ml
->pm
);
2008 static DWORD WINAPI
expSignalObjectAndWait(HANDLE hObjectToSignal
,
2009 HANDLE hObjectToWaitOn
,
2010 DWORD dwMilliseconds
,
2011 WIN_BOOL bAlertable
) {
2012 mutex_list
* mlist
= (mutex_list
*)hObjectToSignal
;
2014 switch (mlist
->type
) {
2018 case 1: // Semaphore
2019 expReleaseSemaphore(mlist
, 1, NULL
);
2022 expReleaseMutex(mlist
);
2025 dbgprintf("Signalling unknown object type %d!\n", hObjectToSignal
);
2027 return expWaitForSingleObject(hObjectToWaitOn
, dwMilliseconds
);
2030 static long WINAPI
expRegOpenKeyExA(long key
, const char* subkey
, long reserved
, long access
, int* newkey
)
2032 long result
=RegOpenKeyExA(key
, subkey
, reserved
, access
, newkey
);
2033 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
2034 key
, subkey
, reserved
, access
, newkey
, result
);
2035 if(newkey
)dbgprintf(" New key: 0x%x\n", *newkey
);
2038 static long WINAPI
expRegCloseKey(long key
)
2040 long result
=RegCloseKey(key
);
2041 dbgprintf("RegCloseKey(0x%x) => %d\n", key
, result
);
2044 static long WINAPI
expRegQueryValueExA(long key
, const char* value
, int* reserved
, int* type
, int* data
, int* count
)
2046 long result
=RegQueryValueExA(key
, value
, reserved
, type
, data
, count
);
2047 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
2048 " => 0x%x\n", key
, value
, reserved
, data
, count
, result
);
2049 if(data
&& count
)dbgprintf(" read %d bytes: '%s'\n", *count
, data
);
2053 //from wine source dlls/advapi32/registry.c
2054 static long WINAPI
expRegCreateKeyA(long hkey
, const char* name
, int *retkey
)
2056 dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey
,name
,retkey
);
2057 return RegCreateKeyExA( hkey
, name
, 0, NULL
,REG_OPTION_NON_VOLATILE
,
2058 KEY_ALL_ACCESS
, NULL
, retkey
, NULL
);
2061 static long WINAPI
expRegCreateKeyExA(long key
, const char* name
, long reserved
,
2062 void* classs
, long options
, long security
,
2063 void* sec_attr
, int* newkey
, int* status
)
2065 long result
=RegCreateKeyExA(key
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
);
2066 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
2067 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
2068 key
, name
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
, result
);
2069 if(!result
&& newkey
) dbgprintf(" New key: 0x%x\n", *newkey
);
2070 if(!result
&& status
) dbgprintf(" New key status: 0x%x\n", *status
);
2073 static long WINAPI
expRegSetValueExA(long key
, const char* name
, long v1
, long v2
, void* data
, long size
)
2075 long result
=RegSetValueExA(key
, name
, v1
, v2
, data
, size
);
2076 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
2077 key
, name
, v1
, v2
, data
, *(int*)data
, data
, size
, result
);
2081 static long WINAPI
expRegOpenKeyA (long hKey
, LPCSTR lpSubKey
, int* phkResult
)
2083 long result
=RegOpenKeyExA(hKey
, lpSubKey
, 0, 0, phkResult
);
2084 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
2085 hKey
, lpSubKey
, phkResult
, result
);
2086 if(!result
&& phkResult
) dbgprintf(" New key: 0x%x\n", *phkResult
);
2090 static DWORD WINAPI
expRegEnumValueA(HKEY hkey
, DWORD index
, LPSTR value
, LPDWORD val_count
,
2091 LPDWORD reserved
, LPDWORD type
, LPBYTE data
, LPDWORD count
)
2093 return RegEnumValueA(hkey
, index
, value
, val_count
,
2094 reserved
, type
, data
, count
);
2097 static DWORD WINAPI
expRegEnumKeyExA(HKEY hKey
, DWORD dwIndex
, LPSTR lpName
, LPDWORD lpcbName
,
2098 LPDWORD lpReserved
, LPSTR lpClass
, LPDWORD lpcbClass
,
2099 LPFILETIME lpftLastWriteTime
)
2101 return RegEnumKeyExA(hKey
, dwIndex
, lpName
, lpcbName
, lpReserved
, lpClass
,
2102 lpcbClass
, lpftLastWriteTime
);
2105 static long WINAPI
expQueryPerformanceCounter(long long* z
)
2108 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z
, *z
);
2113 * dummy function RegQueryInfoKeyA(), required by vss codecs
2115 static DWORD WINAPI
expRegQueryInfoKeyA( HKEY hkey
, LPSTR
class, LPDWORD class_len
, LPDWORD reserved
,
2116 LPDWORD subkeys
, LPDWORD max_subkey
, LPDWORD max_class
,
2117 LPDWORD values
, LPDWORD max_value
, LPDWORD max_data
,
2118 LPDWORD security
, FILETIME
*modif
)
2120 return ERROR_SUCCESS
;
2124 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
2126 static double linux_cpuinfo_freq(void)
2133 f
= fopen ("/proc/cpuinfo", "r");
2135 while (fgets(line
,sizeof(line
),f
)!=NULL
) {
2136 /* NOTE: the ':' is the only character we can rely on */
2137 if (!(value
= strchr(line
,':')))
2139 /* terminate the valuename */
2141 /* skip any leading spaces */
2142 while (*value
==' ') value
++;
2143 if ((s
=strchr(value
,'\n')))
2146 if (!strncasecmp(line
, "cpu MHz",strlen("cpu MHz"))
2147 && sscanf(value
, "%lf", &freq
) == 1) {
2158 static double solaris_kstat_freq(void)
2160 #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
2162 * try to extract the CPU speed from the solaris kernel's kstat data
2166 kstat_named_t
*kdata
;
2172 ksp
= kstat_lookup(kc
, "cpu_info", 0, "cpu_info0");
2174 /* kstat found and name/value pairs? */
2175 if (ksp
!= NULL
&& ksp
->ks_type
== KSTAT_TYPE_NAMED
)
2177 /* read the kstat data from the kernel */
2178 if (kstat_read(kc
, ksp
, NULL
) != -1)
2181 * lookup desired "clock_MHz" entry, check the expected
2184 kdata
= (kstat_named_t
*)kstat_data_lookup(ksp
, "clock_MHz");
2185 if (kdata
!= NULL
&& kdata
->data_type
== KSTAT_DATA_INT32
)
2186 mhz
= kdata
->value
.i32
;
2194 #endif /* HAVE_LIBKSTAT */
2195 return -1; // kstat stuff is not available, CPU freq is unknown
2199 * Measure CPU freq using the pentium's time stamp counter register (TSC)
2201 static double tsc_freq(void)
2203 static double ofreq
=0.0;
2207 if (ofreq
!= 0.0) return ofreq
;
2208 while(i
==time(NULL
));
2211 while(i
==time(NULL
));
2213 ofreq
= (double)(y
-x
)/1000.;
2217 static double CPU_Freq(void)
2221 if ((freq
= linux_cpuinfo_freq()) > 0)
2224 if ((freq
= solaris_kstat_freq()) > 0)
2230 static long WINAPI
expQueryPerformanceFrequency(long long* z
)
2232 *z
=(long long)CPU_Freq();
2233 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z
, *z
);
2236 static long WINAPI
exptimeGetTime(void)
2240 gettimeofday(&t
, 0);
2241 result
=1000*t
.tv_sec
+t
.tv_usec
/1000;
2242 dbgprintf("timeGetTime() => %d\n", result
);
2245 static void* WINAPI
expLocalHandle(void* v
)
2247 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v
, v
);
2251 static void* WINAPI
expGlobalHandle(void* v
)
2253 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v
, v
);
2256 static int WINAPI
expGlobalUnlock(void* v
)
2258 dbgprintf("GlobalUnlock(0x%x) => 1\n", v
);
2261 static void* WINAPI
expGlobalFree(void* v
)
2263 dbgprintf("GlobalFree(0x%x) => 0\n", v
);
2269 static void* WINAPI
expGlobalReAlloc(void* v
, int size
, int flags
)
2271 void* result
=my_realloc(v
, size
);
2272 //void* result=realloc(v, size);
2273 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v
,size
,flags
,result
);
2277 static int WINAPI
expLocalUnlock(void* v
)
2279 dbgprintf("LocalUnlock(0x%x) => 1\n", v
);
2283 static void* WINAPI
expLocalFree(void* v
)
2285 dbgprintf("LocalFree(0x%x) => 0\n", v
);
2289 static HRSRC WINAPI
expFindResourceA(HMODULE module
, char* name
, char* type
)
2293 result
=FindResourceA(module
, name
, type
);
2294 dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2295 module
, name
, HIWORD(name
) ? name
: "UNICODE", type
, HIWORD(type
) ? type
: "UNICODE", result
);
2299 static HGLOBAL WINAPI
expLoadResource(HMODULE module
, HRSRC res
)
2301 HGLOBAL result
=LoadResource(module
, res
);
2302 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module
, res
, result
);
2305 static void* WINAPI
expLockResource(long res
)
2307 void* result
=LockResource(res
);
2308 dbgprintf("LockResource(0x%x) => 0x%x\n", res
, result
);
2311 static int WINAPI
expFreeResource(long res
)
2313 int result
=FreeResource(res
);
2314 dbgprintf("FreeResource(0x%x) => %d\n", res
, result
);
2319 static int WINAPI
expCloseHandle(long v1
)
2321 dbgprintf("CloseHandle(0x%x) => 1\n", v1
);
2322 /* do not close stdin,stdout and stderr */
2329 static const char* WINAPI
expGetCommandLineA(void)
2331 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2332 return "c:\\aviplay.exe";
2334 static short envs
[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2335 static LPWSTR WINAPI
expGetEnvironmentStringsW(void)
2337 dbgprintf("GetEnvironmentStringsW() => 0\n", envs
);
2340 static void * WINAPI
expRtlZeroMemory(void *p
, size_t len
)
2342 void* result
=memset(p
,0,len
);
2343 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p
,len
,result
);
2346 static void * WINAPI
expRtlMoveMemory(void *dst
, void *src
, size_t len
)
2348 void* result
=memmove(dst
,src
,len
);
2349 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst
,src
,len
,result
);
2353 static void * WINAPI
expRtlFillMemory(void *p
, int ch
, size_t len
)
2355 void* result
=memset(p
,ch
,len
);
2356 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p
,ch
,len
,result
);
2359 static int WINAPI
expFreeEnvironmentStringsW(short* strings
)
2361 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings
);
2364 static int WINAPI
expFreeEnvironmentStringsA(char* strings
)
2366 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings
);
2370 static const char ch_envs
[]=
2371 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2372 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2373 static LPCSTR WINAPI
expGetEnvironmentStrings(void)
2375 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs
);
2376 return (LPCSTR
)ch_envs
;
2377 // dbgprintf("GetEnvironmentStrings() => 0\n");
2381 static int WINAPI
expGetStartupInfoA(STARTUPINFOA
*s
)
2383 dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2384 memset(s
, 0, sizeof(*s
));
2386 // s->lpReserved="Reserved";
2387 // s->lpDesktop="Desktop";
2388 // s->lpTitle="Title";
2390 // s->dwXSize=s->dwYSize=200;
2391 s
->dwFlags
=s
->wShowWindow
=1;
2392 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2393 dbgprintf(" cb=%d\n", s
->cb
);
2394 dbgprintf(" lpReserved='%s'\n", s
->lpReserved
);
2395 dbgprintf(" lpDesktop='%s'\n", s
->lpDesktop
);
2396 dbgprintf(" lpTitle='%s'\n", s
->lpTitle
);
2397 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2398 s
->dwX
, s
->dwY
, s
->dwXSize
, s
->dwYSize
);
2399 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2400 s
->dwXCountChars
, s
->dwYCountChars
, s
->dwFillAttribute
);
2401 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2402 s
->dwFlags
, s
->wShowWindow
, s
->cbReserved2
);
2403 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2404 s
->lpReserved2
, s
->hStdInput
, s
->hStdOutput
, s
->hStdError
);
2408 static int WINAPI
expGetStdHandle(int z
)
2410 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z
+0x1234);
2414 #ifdef CONFIG_QTX_CODECS
2415 #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2416 #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2419 static int WINAPI
expGetFileType(int handle
)
2421 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle
);
2424 #ifdef CONFIG_QTX_CODECS
2425 static int WINAPI
expGetFileAttributesA(char *filename
)
2427 dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename
);
2428 if (strstr(filename
, "QuickTime.qts"))
2429 return FILE_ATTRIBUTE_SYSTEM
;
2430 return FILE_ATTRIBUTE_NORMAL
;
2433 static int WINAPI
expSetHandleCount(int count
)
2435 dbgprintf("SetHandleCount(0x%x) => 1\n", count
);
2438 static int WINAPI
expGetACP(void)
2440 dbgprintf("GetACP() => 0\n");
2443 static int WINAPI
expGetModuleFileNameA(int module
, char* s
, int len
)
2447 //printf("File name of module %X (%s) requested\n", module, s);
2449 if (module
== 0 && len
>= 12)
2451 /* return caller program name */
2452 strcpy(s
, "aviplay.dll");
2463 strcpy(s
, "c:\\windows\\system\\");
2464 mr
=MODULE32_LookupHMODULE(module
);
2466 strcat(s
, "aviplay.dll");
2468 if(strrchr(mr
->filename
, '/')==NULL
)
2469 strcat(s
, mr
->filename
);
2471 strcat(s
, strrchr(mr
->filename
, '/')+1);
2474 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2475 module
, s
, len
, result
);
2477 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2478 module
, s
, len
, result
, s
);
2482 static int WINAPI
expGetModuleBaseNameA(int process
, int module
, char* s
, int len
)
2487 av_strlcpy(s
, "aviplay.dll", len
);
2491 dbgprintf("GetModuleBaseNameA(0x%x, 0x%x, 0x%x, %d) => %d\n",
2492 process
, module
, s
, len
, result
);
2497 static int WINAPI
expSetUnhandledExceptionFilter(void* filter
)
2499 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter
);
2500 return 1;//unsupported and probably won't ever be supported
2503 static int WINAPI
expLoadLibraryA(char* name
)
2509 // we skip to the last backslash
2510 // this is effectively eliminating weird characters in
2511 // the text output windows
2513 lastbc
= strrchr(name
, '\\');
2520 name
[i
] = *lastbc
++;
2525 if(strncmp(name
, "c:\\windows\\", 11)==0) name
+= 11;
2526 if(strncmp(name
, ".\\", 2)==0) name
+= 2;
2528 dbgprintf("Entering LoadLibraryA(%s)\n", name
);
2530 // PIMJ and VIVO audio are loading kernel32.dll
2531 if (strcasecmp(name
, "kernel32.dll") == 0 || strcasecmp(name
, "kernel32") == 0)
2532 return MODULE_HANDLE_kernel32
;
2533 // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2534 /* exported -> do not return failed! */
2536 if (strcasecmp(name
, "user32.dll") == 0 || strcasecmp(name
, "user32") == 0)
2537 // return MODULE_HANDLE_kernel32;
2538 return MODULE_HANDLE_user32
;
2540 #ifdef CONFIG_QTX_CODECS
2541 if (strcasecmp(name
, "wininet.dll") == 0 || strcasecmp(name
, "wininet") == 0)
2542 return MODULE_HANDLE_wininet
;
2543 if (strcasecmp(name
, "ddraw.dll") == 0 || strcasecmp(name
, "ddraw") == 0)
2544 return MODULE_HANDLE_ddraw
;
2545 if (strcasecmp(name
, "advapi32.dll") == 0 || strcasecmp(name
, "advapi32") == 0)
2546 return MODULE_HANDLE_advapi32
;
2549 if (strcasecmp(name
, "comdlg32.dll") == 0 || strcasecmp(name
, "comdlg32") == 0)
2550 return MODULE_HANDLE_comdlg32
;
2551 if (strcasecmp(name
, "msvcrt.dll") == 0 || strcasecmp(name
, "msvcrt") == 0)
2552 return MODULE_HANDLE_msvcrt
;
2553 if (strcasecmp(name
, "ole32.dll") == 0 || strcasecmp(name
, "ole32") == 0)
2554 return MODULE_HANDLE_ole32
;
2555 if (strcasecmp(name
, "winmm.dll") == 0 || strcasecmp(name
, "winmm") == 0)
2556 return MODULE_HANDLE_winmm
;
2557 if (strcasecmp(name
, "psapi.dll") == 0 || strcasecmp(name
, "psapi") == 0)
2558 return MODULE_HANDLE_psapi
;
2560 result
=LoadLibraryA(name
);
2561 dbgprintf("Returned LoadLibraryA(0x%x='%s'), codec_path=%s => 0x%x\n",
2562 name
, name
, codec_path
, result
);
2567 static int WINAPI
expFreeLibrary(int module
)
2569 #ifdef CONFIG_QTX_CODECS
2570 int result
=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2572 int result
=FreeLibrary(module
);
2574 dbgprintf("FreeLibrary(0x%x) => %d\n", module
, result
);
2578 static void* WINAPI
expGetProcAddress(HMODULE mod
, char* name
)
2582 case MODULE_HANDLE_kernel32
:
2583 result
=LookupExternalByName("kernel32.dll", name
); break;
2584 case MODULE_HANDLE_user32
:
2585 result
=LookupExternalByName("user32.dll", name
); break;
2586 #ifdef CONFIG_QTX_CODECS
2587 case MODULE_HANDLE_wininet
:
2588 result
=LookupExternalByName("wininet.dll", name
); break;
2589 case MODULE_HANDLE_ddraw
:
2590 result
=LookupExternalByName("ddraw.dll", name
); break;
2591 case MODULE_HANDLE_advapi32
:
2592 result
=LookupExternalByName("advapi32.dll", name
); break;
2594 case MODULE_HANDLE_comdlg32
:
2595 result
=LookupExternalByName("comdlg32.dll", name
); break;
2596 case MODULE_HANDLE_msvcrt
:
2597 result
=LookupExternalByName("msvcrt.dll", name
); break;
2598 case MODULE_HANDLE_ole32
:
2599 result
=LookupExternalByName("ole32.dll", name
); break;
2600 case MODULE_HANDLE_winmm
:
2601 result
=LookupExternalByName("winmm.dll", name
); break;
2602 case MODULE_HANDLE_psapi
:
2603 result
=LookupExternalByName("psapi.dll", name
); break;
2605 result
=GetProcAddress(mod
, name
);
2607 if((unsigned int)name
> 0xffff)
2608 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod
, name
, result
);
2610 dbgprintf("GetProcAddress(0x%x, '%d') => 0x%x\n", mod
, (int)name
, result
);
2614 static long WINAPI
expCreateFileMappingA(int hFile
, void* lpAttr
,
2615 long flProtect
, long dwMaxHigh
,
2616 long dwMaxLow
, const char* name
)
2618 long result
=CreateFileMappingA(hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
);
2620 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2621 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2622 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, result
);
2624 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2625 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2626 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
, name
, result
);
2630 static long WINAPI
expOpenFileMappingA(long hFile
, long hz
, const char* name
)
2632 long result
=OpenFileMappingA(hFile
, hz
, name
);
2634 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2637 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2638 hFile
, hz
, name
, name
, result
);
2642 static void* WINAPI
expMapViewOfFile(HANDLE file
, DWORD mode
, DWORD offHigh
,
2643 DWORD offLow
, DWORD size
)
2645 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2646 file
,mode
,offHigh
,offLow
,size
,(char*)file
+offLow
);
2647 return (char*)file
+offLow
;
2650 static void* WINAPI
expUnmapViewOfFile(void* view
)
2652 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view
);
2656 static void* WINAPI
expSleep(int time
)
2659 /* solaris doesn't have thread safe usleep */
2660 struct timespec tsp
;
2661 tsp
.tv_sec
= time
/ 1000000;
2662 tsp
.tv_nsec
= (time
% 1000000) * 1000;
2663 nanosleep(&tsp
, NULL
);
2667 dbgprintf("Sleep(%d) => 0\n", time
);
2671 // why does IV32 codec want to call this? I don't know ...
2672 static int WINAPI
expCreateCompatibleDC(int hdc
)
2675 //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2676 dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc
, dc
);
2680 static int WINAPI
expGetDeviceCaps(int hdc
, int unk
)
2682 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc
, unk
);
2683 #ifdef CONFIG_QTX_CODECS
2684 #define BITSPIXEL 12
2686 if (unk
== BITSPIXEL
)
2694 static WIN_BOOL WINAPI
expDeleteDC(int hdc
)
2696 dbgprintf("DeleteDC(0x%x) => 0\n", hdc
);
2702 static WIN_BOOL WINAPI
expDeleteObject(int hdc
)
2704 dbgprintf("DeleteObject(0x%x) => 1\n", hdc
);
2705 /* FIXME - implement code here */
2709 /* btvvc32.drv wants this one */
2710 static void* WINAPI
expGetWindowDC(int hdc
)
2712 dbgprintf("GetWindowDC(%d) => 0x0\n", hdc
);
2716 #ifdef CONFIG_QTX_CODECS
2717 static int WINAPI
expGetWindowRect(HWND win
, RECT
*r
)
2719 dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win
, r
);
2720 /* (win == 0) => desktop */
2721 r
->right
= PSEUDO_SCREEN_WIDTH
;
2723 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
2728 static int WINAPI
expMonitorFromWindow(HWND win
, int flags
)
2730 dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win
, flags
);
2734 static int WINAPI
expMonitorFromRect(RECT
*r
, int flags
)
2736 dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r
, flags
);
2740 static int WINAPI
expMonitorFromPoint(void *p
, int flags
)
2742 dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p
, flags
);
2746 static int WINAPI
expEnumDisplayMonitors(void *dc
, RECT
*r
,
2747 int WINAPI (*callback_proc
)(HMONITOR
, HDC
, LPRECT
, LPARAM
), void *callback_param
)
2749 dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2750 dc
, r
, callback_proc
, callback_param
);
2751 return callback_proc(0, dc
, r
, callback_param
);
2755 typedef struct tagMONITORINFO
{
2760 } MONITORINFO
, *LPMONITORINFO
;
2763 #define CCHDEVICENAME 8
2764 typedef struct tagMONITORINFOEX
{
2769 TCHAR szDevice
[CCHDEVICENAME
];
2770 } MONITORINFOEX
, *LPMONITORINFOEX
;
2772 static int WINAPI
expGetMonitorInfoA(void *mon
, LPMONITORINFO lpmi
)
2774 dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon
, lpmi
);
2776 lpmi
->rcMonitor
.right
= lpmi
->rcWork
.right
= PSEUDO_SCREEN_WIDTH
;
2777 lpmi
->rcMonitor
.left
= lpmi
->rcWork
.left
= 0;
2778 lpmi
->rcMonitor
.bottom
= lpmi
->rcWork
.bottom
= PSEUDO_SCREEN_HEIGHT
;
2779 lpmi
->rcMonitor
.top
= lpmi
->rcWork
.top
= 0;
2781 lpmi
->dwFlags
= 1; /* primary monitor */
2783 if (lpmi
->cbSize
== sizeof(MONITORINFOEX
))
2785 LPMONITORINFOEX lpmiex
= (LPMONITORINFOEX
)lpmi
;
2786 dbgprintf("MONITORINFOEX!\n");
2787 strncpy(lpmiex
->szDevice
, "Monitor1", CCHDEVICENAME
);
2793 static int WINAPI
expEnumDisplayDevicesA(const char *device
, int devnum
,
2794 void *dispdev
, int flags
)
2796 dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2797 device
, device
, devnum
, dispdev
, flags
);
2801 static int WINAPI
expIsWindowVisible(HWND win
)
2803 dbgprintf("IsWindowVisible(0x%x) => 1\n", win
);
2807 static HWND WINAPI
expGetActiveWindow(void)
2809 dbgprintf("GetActiveWindow() => 0\n");
2813 static int WINAPI
expGetClassNameA(HWND win
, LPTSTR classname
, int maxcount
)
2815 strncat(classname
, "QuickTime", maxcount
);
2816 dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2817 win
, classname
, maxcount
, strlen(classname
));
2818 return strlen(classname
);
2821 #define LPWNDCLASS void *
2822 static int WINAPI
expGetClassInfoA(HINSTANCE inst
, LPCSTR classname
, LPWNDCLASS wndclass
)
2824 dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst
,
2825 classname
, classname
, wndclass
);
2829 static int WINAPI
expGetWindowLongA(HWND win
, int index
)
2831 dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win
, index
);
2835 static int WINAPI
expGetObjectA(HGDIOBJ hobj
, int objsize
, LPVOID obj
)
2837 dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj
, objsize
, obj
, objsize
);
2841 static int WINAPI
expCreateRectRgn(int x
, int y
, int width
, int height
)
2843 dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x
, y
, width
, height
);
2847 static int WINAPI
expEnumWindows(int (*callback_func
)(HWND
, LPARAM
), void *callback_param
)
2850 dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func
, callback_param
);
2851 i
= callback_func(0, callback_param
);
2852 i2
= callback_func(1, callback_param
);
2856 static int WINAPI
expGetWindowThreadProcessId(HWND win
, int *pid_data
)
2858 int tid
= pthread_self();
2859 dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2860 win
, pid_data
, tid
);
2862 *(int*)pid_data
= tid
;
2866 //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2867 // INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2869 static HWND WINAPI
expCreateWindowExA(int exstyle
, const char *classname
,
2870 const char *winname
, int style
, int x
, int y
, int w
, int h
,
2871 HWND parent
, HMENU menu
, HINSTANCE inst
, LPVOID param
)
2873 printf("CreateWindowEx() called\n");
2874 dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2875 exstyle
, classname
, classname
, winname
, winname
, style
, x
, y
, w
, h
,
2876 parent
, menu
, inst
, param
);
2877 printf("CreateWindowEx() called okey\n");
2881 static int WINAPI
expwaveOutGetNumDevs(void)
2883 dbgprintf("waveOutGetNumDevs() => 0\n");
2889 * Returns the number of milliseconds, modulo 2^32, since the start
2890 * of the wineserver.
2892 static int WINAPI
expGetTickCount(void)
2894 static int tcstart
= 0;
2897 gettimeofday( &t
, NULL
);
2898 tc
= ((t
.tv_sec
* 1000) + (t
.tv_usec
/ 1000)) - tcstart
;
2904 dbgprintf("GetTickCount() => %d\n", tc
);
2908 static int WINAPI
expCreateFontA(void)
2910 dbgprintf("CreateFontA() => 0x0\n");
2914 /* tried to get pvmjpg work in a different way - no success */
2915 static int WINAPI
expDrawTextA(int hDC
, char* lpString
, int nCount
,
2916 LPRECT lpRect
, unsigned int uFormat
)
2918 dbgprintf("expDrawTextA(%p,...) => 8\n", hDC
);
2922 static int WINAPI
expGetPrivateProfileIntA(const char* appname
,
2923 const char* keyname
,
2925 const char* filename
)
2933 if(!(appname
&& keyname
&& filename
) )
2935 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, default_value
);
2936 return default_value
;
2938 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2939 strcpy(fullname
, "Software\\IniFileMapping\\");
2940 strcat(fullname
, appname
);
2941 strcat(fullname
, "\\");
2942 strcat(fullname
, keyname
);
2943 strcat(fullname
, "\\");
2944 strcat(fullname
, filename
);
2945 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)buffer
, &size
);
2946 if((size
>=0)&&(size
<256))
2948 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2951 result
=default_value
;
2953 result
=atoi(buffer
);
2954 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, result
);
2957 static int WINAPI
expGetProfileIntA(const char* appname
,
2958 const char* keyname
,
2961 dbgprintf("GetProfileIntA -> ");
2962 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, "default");
2965 static int WINAPI
expGetPrivateProfileStringA(const char* appname
,
2966 const char* keyname
,
2967 const char* def_val
,
2968 char* dest
, unsigned int len
,
2969 const char* filename
)
2974 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname
, keyname
, def_val
, dest
, len
, filename
);
2975 if(!(appname
&& keyname
&& filename
) ) return 0;
2976 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2977 strcpy(fullname
, "Software\\IniFileMapping\\");
2978 strcat(fullname
, appname
);
2979 strcat(fullname
, "\\");
2980 strcat(fullname
, keyname
);
2981 strcat(fullname
, "\\");
2982 strcat(fullname
, filename
);
2984 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)dest
, &size
);
2988 strncpy(dest
, def_val
, size
);
2989 if (strlen(def_val
)< size
) size
= strlen(def_val
);
2991 dbgprintf(" => %d ( '%s' )\n", size
, dest
);
2994 static int WINAPI
expWritePrivateProfileStringA(const char* appname
,
2995 const char* keyname
,
2997 const char* filename
)
3000 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname
, keyname
, string
, filename
);
3001 if(!(appname
&& keyname
&& filename
) )
3003 dbgprintf(" => -1\n");
3006 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
3007 strcpy(fullname
, "Software\\IniFileMapping\\");
3008 strcat(fullname
, appname
);
3009 strcat(fullname
, "\\");
3010 strcat(fullname
, keyname
);
3011 strcat(fullname
, "\\");
3012 strcat(fullname
, filename
);
3013 RegSetValueExA(HKEY_LOCAL_MACHINE
, fullname
, 0, REG_SZ
, (int*)string
, strlen(string
));
3014 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
3015 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
3017 dbgprintf(" => 0\n");
3021 unsigned int GetPrivateProfileIntA_(const char* appname
, const char* keyname
, INT default_value
, const char* filename
)
3023 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, filename
);
3025 int GetPrivateProfileStringA_(const char* appname
, const char* keyname
,
3026 const char* def_val
, char* dest
, unsigned int len
, const char* filename
)
3028 return expGetPrivateProfileStringA(appname
, keyname
, def_val
, dest
, len
, filename
);
3030 int WritePrivateProfileStringA_(const char* appname
, const char* keyname
,
3031 const char* string
, const char* filename
)
3033 return expWritePrivateProfileStringA(appname
, keyname
, string
, filename
);
3038 static int WINAPI
expDefDriverProc(int private, int id
, int msg
, int arg1
, int arg2
)
3040 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", private, id
, msg
, arg1
, arg2
);
3044 static int WINAPI
expSizeofResource(int v1
, int v2
)
3046 int result
=SizeofResource(v1
, v2
);
3047 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1
, v2
, result
);
3051 static int WINAPI
expGetLastError(void)
3053 int result
=GetLastError();
3054 dbgprintf("GetLastError() => 0x%x\n", result
);
3058 static void WINAPI
expSetLastError(int error
)
3060 dbgprintf("SetLastError(0x%x)\n", error
);
3061 SetLastError(error
);
3064 static int WINAPI
expStringFromGUID2(GUID
* guid
, char* str
, int cbMax
)
3066 int result
=snprintf(str
, cbMax
, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
3067 guid
->f1
, guid
->f2
, guid
->f3
,
3068 (unsigned char)guid
->f4
[0], (unsigned char)guid
->f4
[1],
3069 (unsigned char)guid
->f4
[2], (unsigned char)guid
->f4
[3],
3070 (unsigned char)guid
->f4
[4], (unsigned char)guid
->f4
[5],
3071 (unsigned char)guid
->f4
[6], (unsigned char)guid
->f4
[7]);
3072 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid
, str
, str
, cbMax
, result
);
3077 static int WINAPI
expGetFileVersionInfoSizeA(const char* name
, int* lpHandle
)
3079 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name
, name
, lpHandle
);
3083 static int WINAPI
expIsBadStringPtrW(const short* string
, int nchars
)
3086 if(string
==0)result
=1; else result
=0;
3087 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string
, nchars
, result
);
3088 if(string
)wch_print(string
);
3091 static int WINAPI
expIsBadStringPtrA(const char* string
, int nchars
)
3093 return expIsBadStringPtrW((const short*)string
, nchars
);
3095 static long WINAPI
expInterlockedExchangeAdd( long* dest
, long incr
)
3100 "lock; xaddl %0,(%1)"
3102 : "r" (dest
), "0" (incr
)
3108 static long WINAPI
expInterlockedCompareExchange( unsigned long* dest
, unsigned long exchange
, unsigned long comperand
)
3110 unsigned long retval
= *dest
;
3111 if(*dest
== comperand
)
3116 static long WINAPI
expInterlockedIncrement( long* dest
)
3118 long result
=expInterlockedExchangeAdd( dest
, 1 ) + 1;
3119 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
3122 static long WINAPI
expInterlockedDecrement( long* dest
)
3124 long result
=expInterlockedExchangeAdd( dest
, -1 ) - 1;
3125 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
3129 static void WINAPI
expOutputDebugStringA( const char* string
)
3131 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string
);
3132 fprintf(stderr
, "DEBUG: %s\n", string
);
3135 static int WINAPI
expGetDC(int hwnd
)
3137 dbgprintf("GetDC(0x%x) => 1\n", hwnd
);
3141 static int WINAPI
expReleaseDC(int hwnd
, int hdc
)
3143 dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd
, hdc
);
3147 static int WINAPI
expGetDesktopWindow(void)
3149 dbgprintf("GetDesktopWindow() => 0\n");
3153 static int cursor
[100];
3155 static int WINAPI
expLoadCursorA(int handle
,LPCSTR name
)
3157 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle
, name
, (int)&cursor
[0]);
3158 return (int)&cursor
[0];
3160 static int WINAPI
expSetCursor(void *cursor
)
3162 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor
, cursor
);
3165 static int WINAPI
expGetCursorPos(void *cursor
)
3167 dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor
, cursor
);
3170 #ifdef CONFIG_QTX_CODECS
3171 static int show_cursor
= 0;
3172 static int WINAPI
expShowCursor(int show
)
3174 dbgprintf("ShowCursor(%d) => %d\n", show
, show
);
3182 static int WINAPI
expRegisterWindowMessageA(char *message
)
3184 dbgprintf("RegisterWindowMessageA(%s)\n", message
);
3187 static int WINAPI
expGetProcessVersion(int pid
)
3189 dbgprintf("GetProcessVersion(%d)\n", pid
);
3192 static int WINAPI
expGetCurrentThread(void)
3195 dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
3198 static int WINAPI
expGetOEMCP(void)
3200 dbgprintf("GetOEMCP()\n");
3203 static int WINAPI
expGetCPInfo(int cp
,void *info
)
3205 dbgprintf("GetCPInfo()\n");
3208 #ifdef CONFIG_QTX_CODECS
3209 #define SM_CXSCREEN 0
3210 #define SM_CYSCREEN 1
3211 #define SM_XVIRTUALSCREEN 76
3212 #define SM_YVIRTUALSCREEN 77
3213 #define SM_CXVIRTUALSCREEN 78
3214 #define SM_CYVIRTUALSCREEN 79
3215 #define SM_CMONITORS 80
3217 static int WINAPI
expGetSystemMetrics(int index
)
3219 dbgprintf("GetSystemMetrics(%d)\n", index
);
3220 #ifdef CONFIG_QTX_CODECS
3223 case SM_XVIRTUALSCREEN
:
3224 case SM_YVIRTUALSCREEN
:
3227 case SM_CXVIRTUALSCREEN
:
3228 return PSEUDO_SCREEN_WIDTH
;
3230 case SM_CYVIRTUALSCREEN
:
3231 return PSEUDO_SCREEN_HEIGHT
;
3238 static int WINAPI
expGetSysColor(int index
)
3240 dbgprintf("GetSysColor(%d) => 1\n", index
);
3243 static int WINAPI
expGetSysColorBrush(int index
)
3245 dbgprintf("GetSysColorBrush(%d)\n", index
);
3251 static int WINAPI
expGetSystemPaletteEntries(int hdc
, int iStartIndex
, int nEntries
, void* lppe
)
3253 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3254 hdc
, iStartIndex
, nEntries
, lppe
);
3259 typedef struct TIME_ZONE_INFORMATION {
3261 char StandardName[32];
3262 SYSTEMTIME StandardDate;
3264 char DaylightName[32];
3265 SYSTEMTIME DaylightDate;
3267 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3270 static int WINAPI
expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation
)
3272 const short name
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3273 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3274 const short pname
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3275 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3276 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3277 memset(lpTimeZoneInformation
, 0, sizeof(TIME_ZONE_INFORMATION
));
3278 lpTimeZoneInformation
->Bias
=360;//GMT-6
3279 memcpy(lpTimeZoneInformation
->StandardName
, name
, sizeof(name
));
3280 lpTimeZoneInformation
->StandardDate
.wMonth
=10;
3281 lpTimeZoneInformation
->StandardDate
.wDay
=5;
3282 lpTimeZoneInformation
->StandardDate
.wHour
=2;
3283 lpTimeZoneInformation
->StandardBias
=0;
3284 memcpy(lpTimeZoneInformation
->DaylightName
, pname
, sizeof(pname
));
3285 lpTimeZoneInformation
->DaylightDate
.wMonth
=4;
3286 lpTimeZoneInformation
->DaylightDate
.wDay
=1;
3287 lpTimeZoneInformation
->DaylightDate
.wHour
=2;
3288 lpTimeZoneInformation
->DaylightBias
=-60;
3289 return TIME_ZONE_ID_STANDARD
;
3292 static void WINAPI
expGetLocalTime(SYSTEMTIME
* systime
)
3295 struct tm
*local_tm
;
3298 dbgprintf("GetLocalTime(0x%x)\n");
3299 gettimeofday(&tv
, NULL
);
3300 local_time
=tv
.tv_sec
;
3301 local_tm
=localtime(&local_time
);
3303 systime
->wYear
= local_tm
->tm_year
+ 1900;
3304 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3305 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3306 systime
->wDay
= local_tm
->tm_mday
;
3307 systime
->wHour
= local_tm
->tm_hour
;
3308 systime
->wMinute
= local_tm
->tm_min
;
3309 systime
->wSecond
= local_tm
->tm_sec
;
3310 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3311 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3312 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3313 " Milliseconds: %d\n",
3314 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3315 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3318 static int WINAPI
expGetSystemTime(SYSTEMTIME
* systime
)
3321 struct tm
*local_tm
;
3324 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3325 gettimeofday(&tv
, NULL
);
3326 local_time
=tv
.tv_sec
;
3327 local_tm
=gmtime(&local_time
);
3329 systime
->wYear
= local_tm
->tm_year
+ 1900;
3330 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3331 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3332 systime
->wDay
= local_tm
->tm_mday
;
3333 systime
->wHour
= local_tm
->tm_hour
;
3334 systime
->wMinute
= local_tm
->tm_min
;
3335 systime
->wSecond
= local_tm
->tm_sec
;
3336 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3337 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3338 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3339 " Milliseconds: %d\n",
3340 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3341 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3345 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3346 static void WINAPI
expGetSystemTimeAsFileTime(FILETIME
* systime
)
3349 unsigned long long secs
;
3351 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3352 gettimeofday(&tv
, NULL
);
3353 secs
= (tv
.tv_sec
+ SECS_1601_TO_1970
) * 10000000;
3354 secs
+= tv
.tv_usec
* 10;
3355 systime
->dwLowDateTime
= secs
& 0xffffffff;
3356 systime
->dwHighDateTime
= (secs
>> 32);
3359 static int WINAPI
expGetEnvironmentVariableA(const char* name
, char* field
, int size
)
3362 // printf("%s %x %x\n", name, field, size);
3363 if(field
)field
[0]=0;
3366 if (p) strncpy(field,p,size);
3368 if (strcmp(name
,"__MSVCRT_HEAP_SELECT")==0)
3369 strcpy(field
,"__GLOBAL_HEAP_SELECTED,1");
3370 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name
, name
, field
, size
, strlen(field
));
3371 return strlen(field
);
3374 static int WINAPI
expSetEnvironmentVariableA(const char *name
, const char *value
)
3376 dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name
, value
);
3380 static void* WINAPI
expCoTaskMemAlloc(ULONG cb
)
3382 return my_mreq(cb
, 0);
3384 static void WINAPI
expCoTaskMemFree(void* cb
)
3392 void* CoTaskMemAlloc(unsigned long cb
)
3394 return expCoTaskMemAlloc(cb
);
3396 void CoTaskMemFree(void* cb
)
3398 expCoTaskMemFree(cb
);
3401 struct COM_OBJECT_INFO
3404 long (*GetClassObject
) (GUID
* clsid
, const GUID
* iid
, void** ppv
);
3407 static struct COM_OBJECT_INFO
* com_object_table
=0;
3408 static int com_object_size
=0;
3409 int RegisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3413 com_object_table
=realloc(com_object_table
, sizeof(struct COM_OBJECT_INFO
)*(++com_object_size
));
3414 com_object_table
[com_object_size
-1].clsid
=*clsid
;
3415 com_object_table
[com_object_size
-1].GetClassObject
=gcs
;
3419 int UnregisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3426 if (com_object_table
== 0)
3427 printf("Warning: UnregisterComClass() called without any registered class\n");
3428 while (i
< com_object_size
)
3432 memcpy(&com_object_table
[i
- 1].clsid
,
3433 &com_object_table
[i
].clsid
, sizeof(GUID
));
3434 com_object_table
[i
- 1].GetClassObject
=
3435 com_object_table
[i
].GetClassObject
;
3437 else if (memcmp(&com_object_table
[i
].clsid
, clsid
, sizeof(GUID
)) == 0
3438 && com_object_table
[i
].GetClassObject
== gcs
)
3446 if (--com_object_size
== 0)
3448 free(com_object_table
);
3449 com_object_table
= 0;
3456 const GUID IID_IUnknown
=
3458 0x00000000, 0x0000, 0x0000,
3459 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3461 const GUID IID_IClassFactory
=
3463 0x00000001, 0x0000, 0x0000,
3464 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3467 static long WINAPI
expCoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3468 long dwClsContext
, const GUID
* riid
, void** ppv
)
3471 struct COM_OBJECT_INFO
* ci
=0;
3472 for(i
=0; i
<com_object_size
; i
++)
3473 if(!memcmp(rclsid
, &com_object_table
[i
].clsid
, sizeof(GUID
)))
3474 ci
=&com_object_table
[i
];
3475 if(!ci
)return REGDB_E_CLASSNOTREG
;
3476 // in 'real' world we should mess with IClassFactory here
3477 i
=ci
->GetClassObject(rclsid
, riid
, ppv
);
3481 long CoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3482 long dwClsContext
, const GUID
* riid
, void** ppv
)
3484 return expCoCreateInstance(rclsid
, pUnkOuter
, dwClsContext
, riid
, ppv
);
3487 static int WINAPI
expIsRectEmpty(CONST RECT
*lprc
)
3494 w
= lprc
->right
- lprc
->left
;
3495 h
= lprc
->bottom
- lprc
->top
;
3496 if (w
<= 0 || h
<= 0)
3502 dbgprintf("IsRectEmpty(%p) => %s\n", lprc
, (r
) ? "TRUE" : "FALSE");
3503 //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3504 // return 0; // wmv9?
3508 static int _adjust_fdiv
=0; //what's this? - used to adjust division
3509 static int _winver
= 0x510; // windows version
3514 static unsigned int WINAPI
expGetTempPathA(unsigned int len
, char* path
)
3516 dbgprintf("GetTempPathA(%d, 0x%x)", len
, path
);
3519 dbgprintf(" => 0\n");
3522 strcpy(path
, "/tmp");
3523 dbgprintf(" => 5 ( '/tmp' )\n");
3530 DWORD dwFileAttributes;
3531 FILETIME ftCreationTime;
3532 FILETIME ftLastAccessTime;
3533 FILETIME ftLastWriteTime;
3534 DWORD nFileSizeHigh;
3538 CHAR cFileName[260];
3539 CHAR cAlternateFileName[14];
3540 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3543 static DIR* qtx_dir
=NULL
;
3545 static WIN_BOOL WINAPI
expFindNextFileA(HANDLE h
,LPWIN32_FIND_DATAA lpfd
)
3547 #ifdef CONFIG_QTX_CODECS
3548 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h
, lpfd
);
3549 if(h
==FILE_HANDLE_quicktimeqtx
){
3551 if(!qtx_dir
) return 0;
3552 while((d
=readdir(qtx_dir
))){
3553 char* x
=strrchr(d
->d_name
,'.');
3555 if(strcmp(x
,".qtx")) continue;
3556 strcpy(lpfd
->cFileName
,d
->d_name
);
3557 // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3558 strcpy(lpfd
->cAlternateFileName
,"foobar.qtx");
3559 dbgprintf("### FindNext: %s\n",lpfd
->cFileName
);
3562 closedir(qtx_dir
); qtx_dir
=NULL
;
3569 static HANDLE WINAPI
expFindFirstFileA(LPCSTR s
, LPWIN32_FIND_DATAA lpfd
)
3571 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s
, s
, lpfd
);
3572 // printf("\n### FindFirstFileA('%s')...\n",s);
3573 #ifdef CONFIG_QTX_CODECS
3574 if(strstr(s
, "quicktime\\*.QTX")){
3575 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s
, s
, lpfd
);
3576 dbgprintf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",
3578 qtx_dir
= opendir(codec_path
);
3579 if(!qtx_dir
) return (HANDLE
)-1;
3580 memset(lpfd
,0,sizeof(*lpfd
));
3581 if(expFindNextFileA(FILE_HANDLE_quicktimeqtx
,lpfd
))
3582 return FILE_HANDLE_quicktimeqtx
;
3583 printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",
3588 if(strstr(s
, "QuickTime.qts")){
3589 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s
, s
, lpfd
);
3590 // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3591 // return (HANDLE)-1;
3592 strcpy(lpfd
->cFileName
, "QuickTime.qts");
3593 strcpy(lpfd
->cAlternateFileName
, "QuickT~1.qts");
3594 return FILE_HANDLE_quicktimeqts
;
3598 if(strstr(s
, "*.vwp")){
3599 // hack for VoxWare codec plugins:
3600 strcpy(lpfd
->cFileName
, "msms001.vwp");
3601 strcpy(lpfd
->cAlternateFileName
, "msms001.vwp");
3604 // return 'file not found'
3608 static WIN_BOOL WINAPI
expFindClose(HANDLE h
)
3610 dbgprintf("FindClose(0x%x) => 0\n", h
);
3611 #ifdef CONFIG_QTX_CODECS
3612 // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3613 // closedir(qtx_dir);
3619 static UINT WINAPI
expSetErrorMode(UINT i
)
3621 dbgprintf("SetErrorMode(%d) => 0\n", i
);
3624 static UINT WINAPI
expGetWindowsDirectoryA(LPSTR s
,UINT c
)
3626 char windir
[]="c:\\windows";
3628 strncpy(s
, windir
, c
);
3629 result
=1+((c
<strlen(windir
))?c
:strlen(windir
));
3630 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3633 #ifdef CONFIG_QTX_CODECS
3634 static UINT WINAPI
expGetCurrentDirectoryA(UINT c
, LPSTR s
)
3636 char curdir
[]="c:\\";
3638 strncpy(s
, curdir
, c
);
3639 result
=1+((c
<strlen(curdir
))?c
:strlen(curdir
));
3640 dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3644 static int WINAPI
expSetCurrentDirectoryA(const char *pathname
)
3646 dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname
, pathname
);
3648 if (strrchr(pathname
, '\\'))
3649 chdir(strcat(strrchr(pathname
, '\\')+1, '/'));
3656 static int WINAPI
expCreateDirectoryA(const char *pathname
, void *sa
)
3658 dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3659 pathname
, pathname
, sa
);
3661 p
= strrchr(pathname
, '\\')+1;
3662 strcpy(&buf
[0], p
); /* should be strncpy */
3669 if (strrchr(pathname
, '\\'))
3670 mkdir(strcat(strrchr(pathname
, '\\')+1, '/'), 666);
3672 mkdir(pathname
, 666);
3679 static WIN_BOOL WINAPI
expDeleteFileA(LPCSTR s
)
3681 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s
, s
);
3684 static WIN_BOOL WINAPI
expFileTimeToLocalFileTime(const FILETIME
* cpf
, LPFILETIME pf
)
3686 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf
, pf
);
3690 static UINT WINAPI
expGetTempFileNameA(LPCSTR cs1
,LPCSTR cs2
,UINT i
,LPSTR ps
)
3692 char mask
[16]="/tmp/AP_XXXXXX";
3694 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1
, cs1
, cs2
, cs2
, i
, ps
);
3697 dbgprintf(" => -1\n");
3700 result
=mkstemp(mask
);
3701 sprintf(ps
, "AP%d", result
);
3702 dbgprintf(" => %d\n", strlen(ps
));
3706 // This func might need proper implementation if we want AngelPotion codec.
3707 // They try to open APmpeg4v1.apl with it.
3708 // DLL will close opened file with CloseHandle().
3710 static HANDLE WINAPI
expCreateFileA(LPCSTR cs1
,DWORD i1
,DWORD i2
,
3711 LPSECURITY_ATTRIBUTES p1
, DWORD i3
,DWORD i4
,HANDLE i5
)
3713 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1
, cs1
, i1
,
3714 i2
, p1
, i3
, i4
, i5
);
3715 if((!cs1
) || (strlen(cs1
)<2))return -1;
3717 #ifdef CONFIG_QTX_CODECS
3718 if(strstr(cs1
, "QuickTime.qts"))
3721 char* tmp
= malloc(strlen(codec_path
) + 50);
3722 strcpy(tmp
, codec_path
);
3724 strcat(tmp
, "QuickTime.qts");
3725 result
=open(tmp
, O_RDONLY
);
3729 if(strstr(cs1
, ".qtx"))
3732 char* tmp
= malloc(strlen(codec_path
) + 250);
3733 char* x
=strrchr(cs1
,'\\');
3734 sprintf(tmp
, "%s/%s", codec_path
, x
? (x
+ 1) : cs1
);
3735 // printf("### Open: %s -> %s\n",cs1,tmp);
3736 result
=open(tmp
, O_RDONLY
);
3742 if(strncmp(cs1
, "AP", 2) == 0)
3745 char* tmp
= malloc(strlen(codec_path
) + 50);
3746 strcpy(tmp
, codec_path
);
3748 strcat(tmp
, "APmpg4v1.apl");
3749 result
=open(tmp
, O_RDONLY
);
3753 if (strstr(cs1
, "vp3") || strstr(cs1
, ".fpf") || strstr(cs1
, ".col"))
3757 char* tmp
=malloc(20 + strlen(cs1
));
3758 strcpy(tmp
, "/tmp/");
3763 if (tmp
[r
] == ':' || tmp
[r
] == '\\')
3767 if (GENERIC_READ
& i1
)
3769 else if (GENERIC_WRITE
& i1
)
3771 flg
|= O_WRONLY
| O_CREAT
;
3772 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp
, r
, flg
);
3774 r
=open(tmp
, flg
, S_IRWXU
);
3779 // Needed by wnvplay1.dll
3780 if (strstr(cs1
, "WINNOV.bmp"))
3783 r
=open("/dev/null", O_RDONLY
);
3788 /* we need this for some virtualdub filters */
3792 if (GENERIC_READ
& i1
)
3794 else if (GENERIC_WRITE
& i1
)
3797 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1
, r
, flg
);
3806 static UINT WINAPI
expGetSystemDirectoryA(
3807 char* lpBuffer
, // address of buffer for system directory
3808 UINT uSize
// size of directory buffer
3810 dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer
,uSize
);
3811 if(!lpBuffer
) strcpy(lpBuffer
,".");
3815 static char sysdir[]=".";
3816 static LPCSTR WINAPI expGetSystemDirectoryA(void)
3818 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3822 static DWORD WINAPI expGetFullPathNameA
3825 DWORD nBufferLength
,
3829 if(!lpFileName
) return 0;
3830 dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName
,nBufferLength
,
3831 lpBuffer
, lpFilePart
);
3833 #ifdef CONFIG_QTX_CODECS
3834 strcpy(lpFilePart
, "Quick123.qts");
3836 strcpy(lpFilePart
, lpFileName
);
3839 if (strrchr(lpFileName
, '\\'))
3840 lpFilePart
= strrchr(lpFileName
, '\\');
3842 lpFilePart
= (LPTSTR
)lpFileName
;
3844 strcpy(lpBuffer
, lpFileName
);
3845 // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3846 return strlen(lpBuffer
);
3849 static DWORD WINAPI expGetShortPathNameA
3855 if(!longpath
) return 0;
3856 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath
,shortpath
,shortlen
);
3857 strcpy(shortpath
,longpath
);
3858 return strlen(shortpath
);
3861 static WIN_BOOL WINAPI
expReadFile(HANDLE h
,LPVOID pv
,DWORD size
,LPDWORD rd
,LPOVERLAPPED unused
)
3864 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, rd
);
3865 result
=read(h
, pv
, size
);
3867 if(!result
)return 0;
3871 static WIN_BOOL WINAPI
expWriteFile(HANDLE h
,LPCVOID pv
,DWORD size
,LPDWORD wr
,LPOVERLAPPED unused
)
3874 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, wr
);
3876 result
=write(h
, pv
, size
);
3878 if(!result
)return 0;
3881 static DWORD WINAPI
expSetFilePointer(HANDLE h
, LONG val
, LPLONG ext
, DWORD whence
)
3884 dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h
, val
, ext
, ext
? *ext
: 0, whence
);
3885 //why would DLL want temporary file with >2Gb size?
3897 #ifdef CONFIG_QTX_CODECS
3898 if (val
== 0 && ext
!= 0)
3901 return lseek(h
, val
, wh
);
3904 static HDRVR WINAPI
expOpenDriverA(LPCSTR szDriverName
, LPCSTR szSectionName
,
3907 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3910 static HDRVR WINAPI
expOpenDriver(LPCSTR szDriverName
, LPCSTR szSectionName
,
3913 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3918 static WIN_BOOL WINAPI
expGetProcessAffinityMask(HANDLE hProcess
,
3919 LPDWORD lpProcessAffinityMask
,
3920 LPDWORD lpSystemAffinityMask
)
3922 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3923 hProcess
, lpProcessAffinityMask
, lpSystemAffinityMask
);
3924 if(lpProcessAffinityMask
)*lpProcessAffinityMask
=1;
3925 if(lpSystemAffinityMask
)*lpSystemAffinityMask
=1;
3929 // Fake implementation: does nothing, but does it right :)
3930 static WIN_BOOL WINAPI
expSetProcessAffinityMask(HANDLE hProcess
,
3931 LPDWORD dwProcessAffinityMask
)
3933 dbgprintf("SetProcessAffinityMask(0x%x, 0x%x) => 1\n",
3934 hProcess
, dwProcessAffinityMask
);
3939 static int WINAPI
expMulDiv(int nNumber
, int nNumerator
, int nDenominator
)
3941 static const long long max_int
=0x7FFFFFFFLL
;
3942 static const long long min_int
=-0x80000000LL
;
3943 long long tmp
=(long long)nNumber
*(long long)nNumerator
;
3944 dbgprintf("expMulDiv %d * %d / %d\n", nNumber
, nNumerator
, nDenominator
);
3945 if(!nDenominator
)return 1;
3947 if(tmp
<min_int
) return 1;
3948 if(tmp
>max_int
) return 1;
3952 static LONG WINAPI
explstrcmpiA(const char* str1
, const char* str2
)
3954 LONG result
=strcasecmp(str1
, str2
);
3955 dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
3959 static LONG WINAPI
explstrlenA(const char* str1
)
3961 LONG result
=strlen(str1
);
3962 dbgprintf("strlen(0x%x='%.50s') => %d\n", str1
, str1
, result
);
3966 static LONG WINAPI
explstrcpyA(char* str1
, const char* str2
)
3968 int result
= (int) strcpy(str1
, str2
);
3969 dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1
, str2
, str2
, result
);
3972 static LONG WINAPI
explstrcpynA(char* str1
, const char* str2
,int len
)
3975 if (strlen(str2
)>len
)
3976 result
= (int) strncpy(str1
, str2
,len
);
3978 result
= (int) strcpy(str1
,str2
);
3979 dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1
, str2
, str2
,len
, strlen(str2
),result
);
3982 static LONG WINAPI
explstrcatA(char* str1
, const char* str2
)
3984 int result
= (int) strcat(str1
, str2
);
3985 dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1
, str2
, str2
, result
);
3990 static LONG WINAPI
expInterlockedExchange(long *dest
, long l
)
3992 long retval
= *dest
;
3997 static void WINAPI
expInitCommonControls(void)
3999 dbgprintf("InitCommonControls called!\n");
4003 #ifdef CONFIG_QTX_CODECS
4004 /* needed by QuickTime.qts */
4005 static HWND WINAPI
expCreateUpDownControl (DWORD style
, INT x
, INT y
, INT cx
, INT cy
,
4006 HWND parent
, INT id
, HINSTANCE inst
,
4007 HWND buddy
, INT maxVal
, INT minVal
, INT curVal
)
4009 dbgprintf("CreateUpDownControl(...)\n");
4014 /* alex: implement this call! needed for 3ivx */
4015 static HRESULT WINAPI
expCoCreateFreeThreadedMarshaler(void *pUnkOuter
, void **ppUnkInner
)
4017 dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
4018 pUnkOuter
, ppUnkInner
);
4020 return ERROR_CALL_NOT_IMPLEMENTED
;
4024 static int WINAPI
expDuplicateHandle(HANDLE hSourceProcessHandle
, // handle to source process
4025 HANDLE hSourceHandle
, // handle to duplicate
4026 HANDLE hTargetProcessHandle
, // handle to target process
4027 HANDLE
* lpTargetHandle
, // duplicate handle
4028 DWORD dwDesiredAccess
, // requested access
4029 int bInheritHandle
, // handle inheritance option
4030 DWORD dwOptions
// optional actions
4033 dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
4034 hSourceProcessHandle
, hSourceHandle
, hTargetProcessHandle
,
4035 lpTargetHandle
, dwDesiredAccess
, bInheritHandle
, dwOptions
);
4036 *lpTargetHandle
= hSourceHandle
;
4040 static HRESULT WINAPI
expCoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
4042 dbgprintf("CoInitializeEx(%p, %d) called\n", lpReserved
, dwCoInit
);
4046 // required by PIM1 codec (used by win98 PCTV Studio capture sw)
4047 static HRESULT WINAPI
expCoInitialize(
4048 LPVOID lpReserved
/* [in] pointer to win32 malloc interface
4049 (obsolete, should be NULL) */
4053 * Just delegate to the newer method.
4055 return expCoInitializeEx(lpReserved
, COINIT_APARTMENTTHREADED
);
4058 static void WINAPI
expCoUninitialize(void)
4060 dbgprintf("CoUninitialize() called\n");
4063 /* allow static linking */
4064 HRESULT WINAPI
CoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
4066 return expCoInitializeEx(lpReserved
, dwCoInit
);
4068 HRESULT WINAPI
CoInitialize(LPVOID lpReserved
)
4070 return expCoInitialize(lpReserved
);
4072 void WINAPI
CoUninitialize(void)
4074 expCoUninitialize();
4077 static DWORD WINAPI expSetThreadAffinityMask
4080 DWORD dwThreadAffinityMask
4086 * no WINAPI functions - CDECL
4088 static void* expmalloc(int size
)
4091 // return malloc(size);
4092 void* result
=my_mreq(size
,0);
4093 dbgprintf("malloc(0x%x) => 0x%x\n", size
,result
);
4095 printf("WARNING: malloc() failed\n");
4098 static void expfree(void* mem
)
4100 // return free(mem);
4101 dbgprintf("free(%p)\n", mem
);
4104 /* needed by atrac3.acm */
4105 static void *expcalloc(int num
, int size
)
4107 void* result
=my_mreq(num
*size
,1);
4108 dbgprintf("calloc(%d,%d) => %p\n", num
,size
,result
);
4110 printf("WARNING: calloc() failed\n");
4113 static void* expnew(int size
)
4115 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
4116 // printf("%08x %08x %08x %08x\n",
4117 // size, *(1+(int*)&size),
4118 // *(2+(int*)&size),*(3+(int*)&size));
4122 result
=my_mreq(size
,0);
4123 dbgprintf("new(%d) => %p\n", size
, result
);
4125 printf("WARNING: new() failed\n");
4129 static int expdelete(void* memory
)
4131 dbgprintf("delete(%p)\n", memory
);
4137 * local definition - we need only the last two members at this point
4138 * otherwice we would have to introduce here GUIDs and some more types..
4140 typedef struct __attribute__((__packed__
))
4143 unsigned long cbFormat
; //0x40
4144 char* pbFormat
; //0x44
4146 static HRESULT WINAPI
expMoCopyMediaType(MY_MEDIA_TYPE
* dest
, const MY_MEDIA_TYPE
* src
)
4150 memcpy(dest
, src
, sizeof(MY_MEDIA_TYPE
));
4153 dest
->pbFormat
= (char*) my_mreq(dest
->cbFormat
, 0);
4154 if (!dest
->pbFormat
)
4155 return E_OUTOFMEMORY
;
4156 memcpy(dest
->pbFormat
, src
->pbFormat
, dest
->cbFormat
);
4160 static HRESULT WINAPI
expMoInitMediaType(MY_MEDIA_TYPE
* dest
, DWORD cbFormat
)
4164 memset(dest
, 0, sizeof(MY_MEDIA_TYPE
));
4167 dest
->pbFormat
= (char*) my_mreq(cbFormat
, 0);
4168 if (!dest
->pbFormat
)
4169 return E_OUTOFMEMORY
;
4173 static HRESULT WINAPI
expMoCreateMediaType(MY_MEDIA_TYPE
** dest
, DWORD cbFormat
)
4177 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
4178 return expMoInitMediaType(*dest
, cbFormat
);
4180 static HRESULT WINAPI
expMoDuplicateMediaType(MY_MEDIA_TYPE
** dest
, const void* src
)
4184 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
4185 return expMoCopyMediaType(*dest
, src
);
4187 static HRESULT WINAPI
expMoFreeMediaType(MY_MEDIA_TYPE
* dest
)
4193 my_release(dest
->pbFormat
);
4199 static HRESULT WINAPI
expMoDeleteMediaType(MY_MEDIA_TYPE
* dest
)
4203 expMoFreeMediaType(dest
);
4208 static int exp_snprintf( char *str
, int size
, const char *format
, ... )
4212 va_start(va
, format
);
4213 x
=snprintf(str
,size
,format
,va
);
4214 dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str
,size
,format
,x
);
4220 static int exp_initterm(int v1
, int v2
)
4222 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1
, v2
);
4226 /* merged from wine - 2002.04.21 */
4227 typedef void (*INITTERMFUNC
)();
4228 static int exp_initterm(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
4230 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start
, end
, *start
);
4235 //printf("call _initfunc: from: %p %d\n", *start);
4236 // ok this trick with push/pop is necessary as otherwice
4237 // edi/esi registers are being trashed
4256 //printf("done %p %d:%d\n", end);
4264 /* Fake _initterm_e from msvcr80.dll, needed by sirenacm.dll
4265 * NOTE: If I make this an alias for _initterm, then sirenacm.dll tries to call
4266 other uninmplemented functions; keep this in mind if some future codec needs
4267 a real implementation of this function */
4268 static int exp_initterm_e(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
4270 dbgprintf("_initterm_e(0x%x, 0x%x)\n", start
, end
);
4274 static void* exp__dllonexit(void)
4276 // FIXME extract from WINE
4280 static int expwsprintfA(char* string
, const char* format
, ...)
4284 va_start(va
, format
);
4285 result
= vsprintf(string
, format
, va
);
4286 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string
, format
, result
);
4291 static int expsprintf(char* str
, const char* format
, ...)
4295 dbgprintf("sprintf(0x%x, %s)\n", str
, format
);
4296 va_start(args
, format
);
4297 r
= vsprintf(str
, format
, args
);
4301 static int expsscanf(const char* str
, const char* format
, ...)
4305 dbgprintf("sscanf(%s, %s)\n", str
, format
);
4306 va_start(args
, format
);
4307 r
= vsscanf(str
, format
, args
);
4311 static void* expfopen(const char* path
, const char* mode
)
4313 printf("fopen: \"%s\" mode:%s\n", path
, mode
);
4314 //return fopen(path, mode);
4315 return fdopen(0, mode
); // everything on screen
4317 static int expfprintf(void* stream
, const char* format
, ...)
4321 dbgprintf("fprintf(%p, %s, ...)\n", stream
, format
);
4322 va_start(args
, format
);
4323 r
= vfprintf((FILE*) stream
, format
, args
);
4328 static int expprintf(const char* format
, ...)
4332 dbgprintf("printf(%s, ...)\n", format
);
4333 va_start(args
, format
);
4334 r
= vprintf(format
, args
);
4339 static char* expgetenv(const char* varname
)
4341 char* v
= getenv(varname
);
4342 dbgprintf("getenv(%s) => %s\n", varname
, v
);
4346 static void* expwcscpy(WCHAR
* dst
, const WCHAR
* src
)
4349 while ((*p
++ = *src
++))
4354 static char* expstrrchr(char* string
, int value
)
4356 char* result
=strrchr(string
, value
);
4358 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4360 dbgprintf("strrchr(0x%x='%s', %d) => 0", string
, string
, value
);
4364 static char* expstrchr(char* string
, int value
)
4366 char* result
=strchr(string
, value
);
4368 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4370 dbgprintf("strchr(0x%x='%s', %d) => 0", string
, string
, value
);
4373 static int expstrlen(char* str
)
4375 int result
=strlen(str
);
4376 dbgprintf("strlen(0x%x='%s') => %d\n", str
, str
, result
);
4379 static char* expstrcpy(char* str1
, const char* str2
)
4381 char* result
= strcpy(str1
, str2
);
4382 dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1
, str2
, str2
, result
);
4385 static char* expstrncpy(char* str1
, const char* str2
, size_t count
)
4387 char* result
= strncpy(str1
, str2
, count
);
4388 dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1
, str2
, str2
, count
, result
);
4391 static int expstrcmp(const char* str1
, const char* str2
)
4393 int result
=strcmp(str1
, str2
);
4394 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4397 static int expstrncmp(const char* str1
, const char* str2
,int x
)
4399 int result
=strncmp(str1
, str2
,x
);
4400 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4403 static char* expstrcat(char* str1
, const char* str2
)
4405 char* result
= strcat(str1
, str2
);
4406 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1
, str1
, str2
, str2
, result
);
4409 static char* exp_strdup(const char* str1
)
4411 int l
= strlen(str1
);
4412 char* result
= (char*) my_mreq(l
+ 1,0);
4414 strcpy(result
, str1
);
4415 dbgprintf("_strdup(0x%x='%s') => %p\n", str1
, str1
, result
);
4418 static int expisalnum(int c
)
4420 int result
= (int) isalnum(c
);
4421 dbgprintf("isalnum(0x%x='%c' => %d\n", c
, c
, result
);
4424 static int expisspace(int c
)
4426 int result
= (int) isspace(c
);
4427 dbgprintf("isspace(0x%x='%c' => %d\n", c
, c
, result
);
4430 static int expisalpha(int c
)
4432 int result
= (int) isalpha(c
);
4433 dbgprintf("isalpha(0x%x='%c' => %d\n", c
, c
, result
);
4436 static int expisdigit(int c
)
4438 int result
= (int) isdigit(c
);
4439 dbgprintf("isdigit(0x%x='%c' => %d\n", c
, c
, result
);
4442 static void* expmemmove(void* dest
, void* src
, int n
)
4444 void* result
= memmove(dest
, src
, n
);
4445 dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4448 static int expmemcmp(void* dest
, void* src
, int n
)
4450 int result
= memcmp(dest
, src
, n
);
4451 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest
, src
, n
, result
);
4454 static void* expmemcpy(void* dest
, void* src
, int n
)
4456 void *result
= memcpy(dest
, src
, n
);
4457 dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4460 static void* expmemset(void* dest
, int c
, size_t n
)
4462 void *result
= memset(dest
, c
, n
);
4463 dbgprintf("memset(0x%x, %d, %d) => %p\n", dest
, c
, n
, result
);
4466 static time_t exptime(time_t* t
)
4468 time_t result
= time(t
);
4469 dbgprintf("time(0x%x) => %d\n", t
, result
);
4473 static int exprand(void)
4478 static void expsrand(int seed
)
4485 // preferred compilation with -O2 -ffast-math !
4487 static double explog10(double x
)
4489 /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4493 static double expcos(double x
)
4495 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4501 static void explog10(void)
4512 static void expcos(void)
4523 // this seem to be the only how to make this function working properly
4524 // ok - I've spent tremendous amount of time (many many many hours
4525 // of debuging fixing & testing - it's almost unimaginable - kabi
4527 // _ftol - operated on the float value which is already on the FPU stack
4529 static void exp_ftol(void)
4533 "sub $12, %esp \n\t"
4534 "fstcw -2(%ebp) \n\t"
4536 "movw -2(%ebp), %ax \n\t"
4537 "orb $0x0C, %ah \n\t"
4538 "movw %ax, -4(%ebp) \n\t"
4539 "fldcw -4(%ebp) \n\t"
4540 "fistpl -12(%ebp) \n\t"
4541 "fldcw -2(%ebp) \n\t"
4542 "movl -12(%ebp), %eax \n\t"
4543 //Note: gcc 3.03 does not do the following op if it
4544 // knows that ebp=esp
4545 "movl %ebp, %esp \n\t"
4549 #define FPU_DOUBLES(var1,var2) double var1,var2; \
4550 __asm__ volatile( "fstpl %0;fwait" : "=m" (var2) : ); \
4551 __asm__ volatile( "fstpl %0;fwait" : "=m" (var1) : )
4553 static double exp_CIpow(void)
4557 dbgprintf("_CIpow(%lf, %lf)\n", x
, y
);
4561 static double exppow(double x
, double y
)
4563 /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4567 static double expldexp(double x
, int expo
)
4569 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4570 return ldexp(x
, expo
);
4573 static double expfrexp(double x
, int* expo
)
4575 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4576 return frexp(x
, expo
);
4581 static int exp_stricmp(const char* s1
, const char* s2
)
4583 return strcasecmp(s1
, s2
);
4586 /* from declaration taken from Wine sources - this fountion seems to be
4587 * undocumented in any M$ doc */
4588 static int exp_setjmp3(void* jmpbuf
, int x
)
4590 //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4594 //"mov 4(%%esp), %%edx \n\t"
4595 "mov (%%esp), %%eax \n\t"
4596 "mov %%eax, (%%edx) \n\t" // store ebp
4598 //"mov %%ebp, (%%edx) \n\t"
4599 "mov %%ebx, 4(%%edx) \n\t"
4600 "mov %%edi, 8(%%edx) \n\t"
4601 "mov %%esi, 12(%%edx) \n\t"
4602 "mov %%esp, 16(%%edx) \n\t"
4604 "mov 4(%%esp), %%eax \n\t"
4605 "mov %%eax, 20(%%edx) \n\t"
4607 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4608 "movl $0, 36(%%edx) \n\t"
4610 : "d"(jmpbuf
) // input
4615 "mov %%fs:0, %%eax \n\t" // unsure
4616 "mov %%eax, 24(%%edx) \n\t"
4617 "cmp $0xffffffff, %%eax \n\t"
4619 "mov %%eax, 28(%%edx) \n\t"
4629 static DWORD WINAPI
expGetCurrentProcessId(void)
4631 dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4632 return getpid(); //(DWORD)NtCurrentTeb()->pid;
4639 } TIMECAPS
, *LPTIMECAPS
;
4641 static MMRESULT WINAPI
exptimeGetDevCaps(LPTIMECAPS lpCaps
, UINT wSize
)
4643 dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps
, wSize
);
4645 lpCaps
->wPeriodMin
= 1;
4646 lpCaps
->wPeriodMax
= 65535;
4650 static MMRESULT WINAPI
exptimeBeginPeriod(UINT wPeriod
)
4652 dbgprintf("timeBeginPeriod(%u) !\n", wPeriod
);
4654 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4658 #ifdef CONFIG_QTX_CODECS
4659 static MMRESULT WINAPI
exptimeEndPeriod(UINT wPeriod
)
4661 dbgprintf("timeEndPeriod(%u) !\n", wPeriod
);
4663 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4668 static void WINAPI
expGlobalMemoryStatus(
4669 LPMEMORYSTATUS lpmem
4671 static MEMORYSTATUS cached_memstatus
;
4672 static int cache_lastchecked
= 0;
4676 if (time(NULL
)==cache_lastchecked
) {
4677 memcpy(lpmem
,&cached_memstatus
,sizeof(MEMORYSTATUS
));
4681 f
= fopen( "/proc/meminfo", "r" );
4685 int total
, used
, free
, shared
, buffers
, cached
;
4687 lpmem
->dwLength
= sizeof(MEMORYSTATUS
);
4688 lpmem
->dwTotalPhys
= lpmem
->dwAvailPhys
= 0;
4689 lpmem
->dwTotalPageFile
= lpmem
->dwAvailPageFile
= 0;
4690 while (fgets( buffer
, sizeof(buffer
), f
))
4692 /* old style /proc/meminfo ... */
4693 if (sscanf( buffer
, "Mem: %d %d %d %d %d %d", &total
, &used
, &free
, &shared
, &buffers
, &cached
))
4695 lpmem
->dwTotalPhys
+= total
;
4696 lpmem
->dwAvailPhys
+= free
+ buffers
+ cached
;
4698 if (sscanf( buffer
, "Swap: %d %d %d", &total
, &used
, &free
))
4700 lpmem
->dwTotalPageFile
+= total
;
4701 lpmem
->dwAvailPageFile
+= free
;
4704 /* new style /proc/meminfo ... */
4705 if (sscanf(buffer
, "MemTotal: %d", &total
))
4706 lpmem
->dwTotalPhys
= total
*1024;
4707 if (sscanf(buffer
, "MemFree: %d", &free
))
4708 lpmem
->dwAvailPhys
= free
*1024;
4709 if (sscanf(buffer
, "SwapTotal: %d", &total
))
4710 lpmem
->dwTotalPageFile
= total
*1024;
4711 if (sscanf(buffer
, "SwapFree: %d", &free
))
4712 lpmem
->dwAvailPageFile
= free
*1024;
4713 if (sscanf(buffer
, "Buffers: %d", &buffers
))
4714 lpmem
->dwAvailPhys
+= buffers
*1024;
4715 if (sscanf(buffer
, "Cached: %d", &cached
))
4716 lpmem
->dwAvailPhys
+= cached
*1024;
4720 if (lpmem
->dwTotalPhys
)
4722 DWORD TotalPhysical
= lpmem
->dwTotalPhys
+lpmem
->dwTotalPageFile
;
4723 DWORD AvailPhysical
= lpmem
->dwAvailPhys
+lpmem
->dwAvailPageFile
;
4724 lpmem
->dwMemoryLoad
= (TotalPhysical
-AvailPhysical
)
4725 / (TotalPhysical
/ 100);
4729 /* FIXME: should do something for other systems */
4730 lpmem
->dwMemoryLoad
= 0;
4731 lpmem
->dwTotalPhys
= 16*1024*1024;
4732 lpmem
->dwAvailPhys
= 16*1024*1024;
4733 lpmem
->dwTotalPageFile
= 16*1024*1024;
4734 lpmem
->dwAvailPageFile
= 16*1024*1024;
4736 expGetSystemInfo(&si
);
4737 lpmem
->dwTotalVirtual
= (uint8_t *)si
.lpMaximumApplicationAddress
-(uint8_t *)si
.lpMinimumApplicationAddress
;
4738 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4739 lpmem
->dwAvailVirtual
= lpmem
->dwTotalVirtual
-64*1024;
4740 memcpy(&cached_memstatus
,lpmem
,sizeof(MEMORYSTATUS
));
4741 cache_lastchecked
= time(NULL
);
4743 /* it appears some memory display programs want to divide by these values */
4744 if(lpmem
->dwTotalPageFile
==0)
4745 lpmem
->dwTotalPageFile
++;
4747 if(lpmem
->dwAvailPageFile
==0)
4748 lpmem
->dwAvailPageFile
++;
4751 static INT WINAPI
expGetThreadPriority(HANDLE hthread
)
4753 dbgprintf("GetThreadPriority(%p)\n",hthread
);
4757 /**********************************************************************
4758 * SetThreadPriority [KERNEL32.@] Sets priority for thread.
4764 static WIN_BOOL WINAPI
expSetThreadPriority(
4765 HANDLE hthread
, /* [in] Handle to thread */
4766 INT priority
) /* [in] Thread priority level */
4768 dbgprintf("SetThreadPriority(%p,%d)\n",hthread
,priority
);
4772 static void WINAPI
expTerminateProcess( DWORD process
, DWORD status
)
4774 printf("EXIT - process %ld code %ld\n", process
, status
);
4778 static void WINAPI
expExitProcess( DWORD status
)
4780 printf("EXIT - code %ld\n",status
);
4784 static INT WINAPI
expMessageBoxA(HWND hWnd
, LPCSTR text
, LPCSTR title
, UINT type
){
4785 printf("MSGBOX '%s' '%s' (%d)\n",text
,title
,type
);
4786 #ifdef CONFIG_QTX_CODECS
4787 if (type
== MB_ICONHAND
&& !strlen(text
) && !strlen(title
))
4793 /* these are needed for mss1 */
4796 * \brief this symbol is defined within exp_EH_prolog_dummy
4797 * \param dest jump target
4799 void exp_EH_prolog(void *dest
);
4800 void exp_EH_prolog_dummy(void);
4801 //! just a dummy function that acts a container for the asm section
4802 void exp_EH_prolog_dummy(void) {
4804 // take care, this "function" may not change flags or
4805 // registers besides eax (which is also why we can't use
4806 // exp_EH_prolog_dummy directly)
4807 MANGLE(exp_EH_prolog
)": \n\t"
4810 "mov %esp, %ebp \n\t"
4811 "lea -12(%esp), %esp \n\t"
4816 #include <netinet/in.h>
4817 static WINAPI
inline unsigned long int exphtonl(unsigned long int hostlong
)
4819 // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4820 return htonl(hostlong
);
4823 static WINAPI
inline unsigned long int expntohl(unsigned long int netlong
)
4825 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4826 return ntohl(netlong
);
4829 static char* WINAPI
expSysAllocStringLen(char *pch
, unsigned cch
)
4832 dbgprintf("SysAllocStringLen('%s', %d)\n", pch
, cch
);
4833 str
= malloc(cch
* 2 + sizeof(unsigned) + 2);
4834 *(unsigned *)str
= cch
;
4835 str
+= sizeof(unsigned);
4837 memcpy(str
, pch
, cch
* 2);
4839 str
[cch
* 2 + 1] = 0;
4843 static void WINAPI
expSysFreeString(char *str
)
4846 free(str
- sizeof(unsigned));
4850 static void WINAPI
expVariantInit(void* p
)
4852 printf("InitCommonControls called!\n");
4856 static int WINAPI
expRegisterClassA(const void/*WNDCLASSA*/ *wc
)
4858 dbgprintf("RegisterClassA(%p) => random id\n", wc
);
4859 return time(NULL
); /* be precise ! */
4862 static int WINAPI
expUnregisterClassA(const char *className
, HINSTANCE hInstance
)
4864 dbgprintf("UnregisterClassA(%s, %p) => 0\n", className
, hInstance
);
4868 #ifdef CONFIG_QTX_CODECS
4869 /* should be fixed bcs it's not fully strlen equivalent */
4870 static int expSysStringByteLen(void *str
)
4872 dbgprintf("SysStringByteLen(%p) => %d\n", str
, strlen(str
));
4876 static int expDirectDrawCreate(void)
4878 dbgprintf("DirectDrawCreate(...) => NULL\n");
4883 typedef struct tagPALETTEENTRY
{
4890 typedef struct tagLOGPALETTE
{
4893 PALETTEENTRY palPalEntry
[1];
4896 static HPALETTE WINAPI
expCreatePalette(CONST LOGPALETTE
*lpgpl
)
4901 dbgprintf("CreatePalette(%x) => NULL\n", lpgpl
);
4903 i
= sizeof(LOGPALETTE
)+((lpgpl
->palNumEntries
-1)*sizeof(PALETTEENTRY
));
4905 memcpy((void *)test
, lpgpl
, i
);
4910 static int expCreatePalette(void)
4912 dbgprintf("CreatePalette(...) => NULL\n");
4917 static int WINAPI
expGetClientRect(HWND win
, RECT
*r
)
4919 dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win
, r
);
4920 r
->right
= PSEUDO_SCREEN_WIDTH
;
4922 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
4928 typedef struct tagPOINT
{
4934 static int WINAPI
expClientToScreen(HWND win
, POINT
*p
)
4936 dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win
, p
, p
->x
, p
->y
);
4944 static int WINAPI
expSetThreadIdealProcessor(HANDLE thread
, int proc
)
4946 dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread
, proc
);
4950 static int WINAPI
expMessageBeep(int type
)
4952 dbgprintf("MessageBeep(%d) => 1\n", type
);
4956 static int WINAPI
expDialogBoxParamA(void *inst
, const char *name
,
4957 HWND parent
, void *dialog_func
, void *init_param
)
4959 dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
4960 inst
, name
, name
, parent
, dialog_func
, init_param
);
4964 static void WINAPI
expRegisterClipboardFormatA(const char *name
) {
4965 dbgprintf("RegisterClipboardFormatA(0x%x = %s)\n", name
, name
);
4968 /* needed by imagepower mjpeg2k */
4969 static void *exprealloc(void *ptr
, size_t size
)
4971 dbgprintf("realloc(0x%x, %x)\n", ptr
, size
);
4973 return my_mreq(size
,0);
4975 return my_realloc(ptr
, size
);
4978 /* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
4979 static WIN_BOOL WINAPI
expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn
)
4984 static const char * WINAPI
expPathFindExtensionA(const char *path
) {
4989 ext
= strrchr(path
, '.');
4991 ext
= &path
[strlen(path
)];
4993 dbgprintf("PathFindExtensionA(0x%x = %s) => 0x%x, %s\n", path
, path
, ext
, ext
);
4997 static const char * WINAPI
expPathFindFileNameA(const char *path
) {
4999 if (!path
|| strlen(path
) < 2)
5002 name
= strrchr(path
- 1, '\\');
5006 dbgprintf("PathFindFileNameA(0x%x = %s) => 0x%x, %s\n", path
, path
, name
, name
);
5010 static double expfloor(double x
)
5012 dbgprintf("floor(%lf)\n", x
);
5016 #define FPU_DOUBLE(var) double var; \
5017 __asm__ volatile( "fstpl %0;fwait" : "=m" (var) : )
5019 static double exp_CIcos(void)
5023 dbgprintf("_CIcos(%lf)\n", x
);
5027 static double exp_CIsin(void)
5031 dbgprintf("_CIsin(%lf)\n", x
);
5035 static double exp_CIsqrt(void)
5039 dbgprintf("_CIsqrt(%lf)\n", x
);
5043 /* Needed by rp8 sipr decoder */
5044 static LPSTR WINAPI
expCharNextA(LPCSTR ptr
)
5046 if (!*ptr
) return (LPSTR
)ptr
;
5047 // dbgprintf("CharNextA(0x%08x), %s\n", ptr, ptr);
5048 return (LPSTR
)(ptr
+ 1);
5051 // Fake implementation, needed by wvc1dmod.dll
5052 static int WINAPI
expPropVariantClear(void *pvar
)
5054 // dbgprintf("PropVariantclear (0x%08x), %s\n", ptr, ptr);
5058 // This define is fake, the real thing is a struct
5059 #define LPDEVMODEA void*
5060 // Dummy implementation, always return 1
5061 // Required for frapsvid.dll 2.8.1, return value does not matter
5062 static WIN_BOOL WINAPI
expEnumDisplaySettingsA(LPCSTR name
,DWORD n
,
5065 dbgprintf("EnumDisplaySettingsA (dummy) => 1\n");
5069 // Fake implementation of _decode_pointer from msvcr80.dll, needed by sirenacm.dll
5070 // NOTE: undocumented function, probably the declaration is not right
5071 static int exp_decode_pointer(void *ptr
)
5073 dbgprintf("_decode_pointer (0x%08x)\n", ptr
);
5077 /* Fake implementation of sdt::_Lockit::_Lockit(void) from msvcp60.dll
5078 Needed by SCLS.DLL */
5079 static int exp_0Lockit_dummy(void)
5081 dbgprintf("0Lockit_dummy (??0_Lockit@std@@QAE@XZ)\n");
5085 /* Fake implementation of sdt::_Lockit::~_Lockit(void) from msvcp60.dll
5086 Needed by SCLS.DLL */
5087 static int exp_1Lockit_dummy(void)
5089 dbgprintf("1Lockit_dummy (??1_Lockit@std@@QAE@XZ)\n");
5093 static void * WINAPI
expEncodePointer(void *p
)
5098 static void * WINAPI
expDecodePointer(void *p
)
5103 static DWORD WINAPI
expGetThreadLocale(void)
5109 * Very incomplete implementation, return an error for almost all cases.
5111 static DWORD WINAPI
expGetLocaleInfoA(DWORD locale
, DWORD lctype
, char* lpLCData
, int cchData
)
5113 if (lctype
== 0x1004) { // LOCALE_IDEFAULTANSICODEPAGE
5115 return cchData
== 0 ? 4 : 0;
5116 strcpy(lpLCData
, "437");
5132 const struct exports
* exps
;
5136 {#X, Y, (void*)exp##X},
5138 #define UNDEFF(X, Y) \
5141 static const struct exports exp_kernel32
[]=
5143 FF(GetVolumeInformationA
,-1)
5144 FF(GetDriveTypeA
,-1)
5145 FF(GetLogicalDriveStringsA
,-1)
5146 FF(IsBadWritePtr
, 357)
5147 FF(IsBadReadPtr
, 354)
5148 FF(IsBadStringPtrW
, -1)
5149 FF(IsBadStringPtrA
, -1)
5150 FF(DisableThreadLibraryCalls
, -1)
5151 FF(CreateThread
, -1)
5152 FF(ResumeThread
, -1)
5153 FF(CreateEventA
, -1)
5154 FF(CreateEventW
, -1)
5157 FF(WaitForSingleObject
, -1)
5158 #ifdef CONFIG_QTX_CODECS
5159 FF(WaitForMultipleObjects
, -1)
5162 FF(GetSystemInfo
, -1)
5170 FF(GetProcessHeap
, -1)
5171 FF(VirtualAlloc
, -1)
5173 FF(InitializeCriticalSection
, -1)
5174 FF(InitializeCriticalSectionAndSpinCount
, -1)
5175 FF(EnterCriticalSection
, -1)
5176 FF(LeaveCriticalSection
, -1)
5177 FF(DeleteCriticalSection
, -1)
5182 FF(GetCurrentThreadId
, -1)
5183 FF(GetCurrentProcess
, -1)
5188 FF(GlobalReAlloc
, -1)
5191 FF(MultiByteToWideChar
, 427)
5192 FF(WideCharToMultiByte
, -1)
5193 FF(GetVersionExA
, -1)
5194 FF(GetVersionExW
, -1)
5195 FF(CreateSemaphoreA
, -1)
5196 FF(CreateSemaphoreW
, -1)
5197 FF(QueryPerformanceCounter
, -1)
5198 FF(QueryPerformanceFrequency
, -1)
5202 FF(GlobalHandle
, -1)
5203 FF(GlobalUnlock
, -1)
5205 FF(LoadResource
, -1)
5206 FF(ReleaseSemaphore
, -1)
5207 FF(CreateMutexA
, -1)
5208 FF(CreateMutexW
, -1)
5209 FF(ReleaseMutex
, -1)
5210 FF(SignalObjectAndWait
, -1)
5211 FF(FindResourceA
, -1)
5212 FF(LockResource
, -1)
5213 FF(FreeResource
, -1)
5214 FF(SizeofResource
, -1)
5216 FF(GetCommandLineA
, -1)
5217 FF(GetEnvironmentStringsW
, -1)
5218 FF(FreeEnvironmentStringsW
, -1)
5219 FF(FreeEnvironmentStringsA
, -1)
5220 FF(GetEnvironmentStrings
, -1)
5221 FF(GetStartupInfoA
, -1)
5222 FF(GetStdHandle
, -1)
5224 #ifdef CONFIG_QTX_CODECS
5225 FF(GetFileAttributesA
, -1)
5227 FF(SetHandleCount
, -1)
5229 FF(GetModuleFileNameA
, -1)
5230 FF(SetUnhandledExceptionFilter
, -1)
5231 FF(LoadLibraryA
, -1)
5232 FF(GetProcAddress
, -1)
5234 FF(CreateFileMappingA
, -1)
5235 FF(OpenFileMappingA
, -1)
5236 FF(MapViewOfFile
, -1)
5237 FF(UnmapViewOfFile
, -1)
5239 FF(GetModuleHandleA
, -1)
5240 FF(GetModuleHandleW
, -1)
5241 FF(GetProfileIntA
, -1)
5242 FF(GetPrivateProfileIntA
, -1)
5243 FF(GetPrivateProfileStringA
, -1)
5244 FF(WritePrivateProfileStringA
, -1)
5245 FF(GetLastError
, -1)
5246 FF(SetLastError
, -1)
5247 FF(InterlockedIncrement
, -1)
5248 FF(InterlockedDecrement
, -1)
5249 FF(GetTimeZoneInformation
, -1)
5250 FF(OutputDebugStringA
, -1)
5251 FF(GetLocalTime
, -1)
5252 FF(GetSystemTime
, -1)
5253 FF(GetSystemTimeAsFileTime
, -1)
5254 FF(GetEnvironmentVariableA
, -1)
5255 FF(SetEnvironmentVariableA
, -1)
5256 FF(RtlZeroMemory
,-1)
5257 FF(RtlMoveMemory
,-1)
5258 FF(RtlFillMemory
,-1)
5260 FF(FindFirstFileA
,-1)
5261 FF(FindNextFileA
,-1)
5263 FF(FileTimeToLocalFileTime
,-1)
5267 FF(SetFilePointer
,-1)
5268 FF(GetTempFileNameA
,-1)
5270 FF(GetSystemDirectoryA
,-1)
5271 FF(GetWindowsDirectoryA
,-1)
5272 #ifdef CONFIG_QTX_CODECS
5273 FF(GetCurrentDirectoryA
,-1)
5274 FF(SetCurrentDirectoryA
,-1)
5275 FF(CreateDirectoryA
,-1)
5277 FF(GetShortPathNameA
,-1)
5278 FF(GetFullPathNameA
,-1)
5279 FF(SetErrorMode
, -1)
5280 FF(IsProcessorFeaturePresent
, -1)
5281 FF(IsDebuggerPresent
, -1)
5282 FF(GetProcessAffinityMask
, -1)
5283 FF(InterlockedExchange
, -1)
5284 FF(InterlockedCompareExchange
, -1)
5291 FF(GetProcessVersion
,-1)
5292 FF(GetCurrentThread
,-1)
5295 FF(DuplicateHandle
,-1)
5296 FF(GetTickCount
, -1)
5297 FF(SetThreadAffinityMask
,-1)
5298 FF(GetCurrentProcessId
,-1)
5299 FF(GlobalMemoryStatus
,-1)
5300 FF(GetThreadPriority
,-1)
5301 FF(SetThreadPriority
,-1)
5302 FF(TerminateProcess
,-1)
5304 {"LoadLibraryExA", -1, (void*)&LoadLibraryExA
},
5305 FF(SetThreadIdealProcessor
,-1)
5306 FF(SetProcessAffinityMask
, -1)
5307 FF(EncodePointer
, -1)
5308 FF(DecodePointer
, -1)
5309 FF(GetThreadLocale
, -1)
5310 FF(GetLocaleInfoA
, -1)
5311 UNDEFF(FlsAlloc
, -1)
5312 UNDEFF(FlsGetValue
, -1)
5313 UNDEFF(FlsSetValue
, -1)
5317 static const struct exports exp_msvcrt
[]={
5323 {"??3@YAXPAX@Z", -1, expdelete
},
5324 {"??2@YAPAXI@Z", -1, expnew
},
5325 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5326 {"_winver",-1,(void*)&_winver
},
5367 /* needed by frapsvid.dll */
5368 {"strstr",-1,(char *)&strstr
},
5369 {"qsort",-1,(void *)&qsort
},
5372 {"ceil",-1,(void*)&ceil
},
5373 /* needed by imagepower mjpeg2k */
5374 {"clock",-1,(void*)&clock
},
5375 {"memchr",-1,(void*)&memchr
},
5376 {"vfprintf",-1,(void*)&vfprintf
},
5377 // {"realloc",-1,(void*)&realloc},
5379 {"puts",-1,(void*)&puts
}
5381 static const struct exports exp_winmm
[]={
5382 FF(GetDriverModuleHandle
, -1)
5384 FF(DefDriverProc
, -1)
5387 FF(timeGetDevCaps
, -1)
5388 FF(timeBeginPeriod
, -1)
5389 #ifdef CONFIG_QTX_CODECS
5390 FF(timeEndPeriod
, -1)
5391 FF(waveOutGetNumDevs
, -1)
5394 static const struct exports exp_psapi
[]={
5395 FF(GetModuleBaseNameA
, -1)
5397 static const struct exports exp_user32
[]={
5402 FF(GetDesktopWindow
, -1)
5408 #ifdef CONFIG_QTX_CODECS
5411 FF(RegisterWindowMessageA
,-1)
5412 FF(GetSystemMetrics
,-1)
5414 FF(GetSysColorBrush
,-1)
5418 FF(RegisterClassA
, -1)
5419 FF(UnregisterClassA
, -1)
5420 #ifdef CONFIG_QTX_CODECS
5421 FF(GetWindowRect
, -1)
5422 FF(MonitorFromWindow
, -1)
5423 FF(MonitorFromRect
, -1)
5424 FF(MonitorFromPoint
, -1)
5425 FF(EnumDisplayMonitors
, -1)
5426 FF(GetMonitorInfoA
, -1)
5427 FF(EnumDisplayDevicesA
, -1)
5428 FF(GetClientRect
, -1)
5429 FF(ClientToScreen
, -1)
5430 FF(IsWindowVisible
, -1)
5431 FF(GetActiveWindow
, -1)
5432 FF(GetClassNameA
, -1)
5433 FF(GetClassInfoA
, -1)
5434 FF(GetWindowLongA
, -1)
5436 FF(GetWindowThreadProcessId
, -1)
5437 FF(CreateWindowExA
, -1)
5440 FF(DialogBoxParamA
, -1)
5441 FF(RegisterClipboardFormatA
, -1)
5443 FF(EnumDisplaySettingsA
, -1)
5445 static const struct exports exp_advapi32
[]={
5447 FF(RegCreateKeyA
, -1)
5448 FF(RegCreateKeyExA
, -1)
5449 FF(RegEnumKeyExA
, -1)
5450 FF(RegEnumValueA
, -1)
5452 FF(RegOpenKeyExA
, -1)
5453 FF(RegQueryValueExA
, -1)
5454 FF(RegSetValueExA
, -1)
5455 FF(RegQueryInfoKeyA
, -1)
5457 static const struct exports exp_gdi32
[]={
5458 FF(CreateCompatibleDC
, -1)
5461 FF(DeleteObject
, -1)
5462 FF(GetDeviceCaps
, -1)
5463 FF(GetSystemPaletteEntries
, -1)
5464 #ifdef CONFIG_QTX_CODECS
5465 FF(CreatePalette
, -1)
5467 FF(CreateRectRgn
, -1)
5470 static const struct exports exp_version
[]={
5471 FF(GetFileVersionInfoSizeA
, -1)
5473 static const struct exports exp_ole32
[]={
5474 FF(CoCreateFreeThreadedMarshaler
,-1)
5475 FF(CoCreateInstance
, -1)
5476 FF(CoInitialize
, -1)
5477 FF(CoInitializeEx
, -1)
5478 FF(CoUninitialize
, -1)
5479 FF(CoTaskMemAlloc
, -1)
5480 FF(CoTaskMemFree
, -1)
5481 FF(StringFromGUID2
, -1)
5482 FF(PropVariantClear
, -1)
5484 // do we really need crtdll ???
5485 // msvcrt is the correct place probably...
5486 static const struct exports exp_crtdll
[]={
5490 static const struct exports exp_comctl32
[]={
5491 FF(StringFromGUID2
, -1)
5492 FF(InitCommonControls
, 17)
5493 #ifdef CONFIG_QTX_CODECS
5494 FF(CreateUpDownControl
, 16)
5497 static const struct exports exp_wsock32
[]={
5501 static const struct exports exp_msdmo
[]={
5502 FF(memcpy
, -1) // just test
5503 FF(MoCopyMediaType
, -1)
5504 FF(MoCreateMediaType
, -1)
5505 FF(MoDeleteMediaType
, -1)
5506 FF(MoDuplicateMediaType
, -1)
5507 FF(MoFreeMediaType
, -1)
5508 FF(MoInitMediaType
, -1)
5510 static const struct exports exp_oleaut32
[]={
5511 FF(SysAllocStringLen
, 4)
5512 FF(SysFreeString
, 6)
5514 #ifdef CONFIG_QTX_CODECS
5515 FF(SysStringByteLen
, 149)
5521 vma: Hint/Ord Member-Name
5526 2305e 167 _adjust_fdiv
5529 22ffc 176 _beginthreadex
5531 2300e 85 __CxxFrameHandler
5535 static const struct exports exp_pncrt
[]={
5536 FF(malloc
, -1) // just test
5537 FF(free
, -1) // just test
5538 FF(fprintf
, -1) // just test
5539 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5542 {"??3@YAXPAX@Z", -1, expdelete
},
5543 {"??2@YAPAXI@Z", -1, expnew
},
5554 #ifdef CONFIG_QTX_CODECS
5555 static const struct exports exp_ddraw
[]={
5556 FF(DirectDrawCreate
, -1)
5560 static const struct exports exp_comdlg32
[]={
5561 FF(GetOpenFileNameA
, -1)
5564 static const struct exports exp_shlwapi
[]={
5565 FF(PathFindExtensionA
, -1)
5566 FF(PathFindFileNameA
, -1)
5569 static const struct exports exp_msvcr80
[]={
5577 FF(_decode_pointer
, -1)
5578 /* needed by KGV1-VFW.dll */
5579 {"??2@YAPAXI@Z", -1, expnew
},
5580 {"??3@YAXPAX@Z", -1, expdelete
}
5583 static const struct exports exp_msvcp60
[]={
5584 {"??0_Lockit@std@@QAE@XZ", -1, exp_0Lockit_dummy
},
5585 {"??1_Lockit@std@@QAE@XZ", -1, exp_1Lockit_dummy
}
5588 static const struct exports exp_msvcr100
[]={
5593 {"??2@YAPAXI@Z", -1, expnew
},
5594 {"??3@YAXPAX@Z", -1, expdelete
}
5598 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5600 static const struct libs libraries
[]={
5618 #ifdef CONFIG_QTX_CODECS
5628 static WIN_BOOL WINAPI
ext_stubs(void)
5630 // NOTE! these magic values will be replaced at runtime, make sure
5631 // add_stub can still find them if you change them.
5632 volatile int idx
= 0x0deadabc;
5633 // make sure gcc does not do eip-relative call or something like that
5634 void (* volatile my_printf
)(char *, char *) = (void *)0xdeadfbcd;
5635 my_printf("Called unk_%s\n", export_names
[idx
]);
5639 #define MAX_STUB_SIZE 0x60
5640 #define MAX_NUM_STUBS 200
5642 static char *extcode
= NULL
;
5644 static void* add_stub(void)
5648 // generated code in runtime!
5651 extcode
= mmap_anon(NULL
, MAX_NUM_STUBS
* MAX_STUB_SIZE
,
5652 PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
, 0);
5653 answ
= extcode
+ pos
* MAX_STUB_SIZE
;
5654 if (pos
>= MAX_NUM_STUBS
) {
5655 printf("too many stubs, expect crash\n");
5658 memcpy(answ
, ext_stubs
, MAX_STUB_SIZE
);
5659 for (i
= 0; i
< MAX_STUB_SIZE
- 3; i
++) {
5660 int *magic
= (int *)(answ
+ i
);
5661 if (*magic
== 0x0deadabc) {
5665 if (*magic
== 0xdeadfbcd) {
5666 *magic
= (intptr_t)printf
;
5671 printf("magic code not found in ext_subs, expect crash\n");
5678 void* LookupExternal(const char* library
, int ordinal
)
5683 printf("ERROR: library=0\n");
5684 return (void*)ext_unknown
;
5686 // printf("%x %x\n", &unk_exp1, &unk_exp2);
5688 dbgprintf("External func %s:%d\n", library
, ordinal
);
5690 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5692 if(strcasecmp(library
, libraries
[i
].name
))
5694 for(j
=0; j
<libraries
[i
].length
; j
++)
5696 if(ordinal
!=libraries
[i
].exps
[j
].id
)
5698 //printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5699 return libraries
[i
].exps
[j
].func
;
5703 #ifndef LOADLIB_TRY_NATIVE
5704 /* hack for truespeech and vssh264*/
5705 if (!strcmp(library
, "tsd32.dll") || !strcmp(library
,"vssh264dec.dll") || !strcmp(library
,"LCMW2.dll") || !strcmp(library
,"VDODEC32.dll"))
5707 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5713 hand
= LoadLibraryA(library
);
5716 wm
= MODULE32_LookupHMODULE(hand
);
5722 func
= PE_FindExportedFunction(wm
, (LPCSTR
) ordinal
, 0);
5725 printf("No such ordinal in external dll\n");
5726 FreeLibrary((int)hand
);
5730 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5736 if(pos
>150)return 0;
5737 snprintf(export_names
[pos
], sizeof(export_names
[pos
]), "%s:%d", library
, ordinal
);
5741 void* LookupExternalByName(const char* library
, const char* name
)
5744 // return (void*)ext_unknown;
5747 printf("ERROR: library=0\n");
5748 return (void*)ext_unknown
;
5750 if((unsigned long)name
<=0xffff)
5752 return LookupExternal(library
, (int)name
);
5754 dbgprintf("External func %s:%s\n", library
, name
);
5755 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5757 if(strcasecmp(library
, libraries
[i
].name
))
5759 for(j
=0; j
<libraries
[i
].length
; j
++)
5761 if(strcmp(name
, libraries
[i
].exps
[j
].name
))
5763 if((unsigned int)(libraries
[i
].exps
[j
].func
) == -1)
5764 return NULL
; //undefined func
5765 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5766 return libraries
[i
].exps
[j
].func
;
5770 #ifndef LOADLIB_TRY_NATIVE
5771 /* hack for vss h264 */
5772 if (!strcmp(library
,"vssh264core.dll") || !strcmp(library
,"3ivx.dll"))
5774 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5780 hand
= LoadLibraryA(library
);
5783 wm
= MODULE32_LookupHMODULE(hand
);
5789 func
= PE_FindExportedFunction(wm
, name
, 0);
5792 printf("No such name in external dll\n");
5793 FreeLibrary((int)hand
);
5797 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5803 if(pos
>150)return 0;// to many symbols
5804 snprintf(export_names
[pos
], sizeof(export_names
[pos
]), "%s", name
);
5808 void my_garbagecollection(void)
5811 int unfree
= 0, unfreecnt
= 0;
5817 alloc_header
* mem
= last_alloc
+ 1;
5818 unfree
+= my_size(mem
);
5820 if (my_release(mem
) != 0)
5821 // avoid endless loop when memory is trashed
5822 if (--max_fatal
< 0)
5825 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree
, unfreecnt
, last_alloc
, alccnt
);
5828 pthread_mutex_lock(&list_lock
);
5830 pthread_mutex_unlock(&list_lock
);