1 /***********************************************************
3 Win32 emulation code. Functions that emulate
4 responses from corresponding Win32 API calls.
5 Since we are not going to be able to load
6 virtually any DLL, we can only implement this
7 much, adding needed functions with each new codec.
9 Basic principle of implementation: it's not good
10 for DLL to know too much about its environment.
12 ************************************************************/
15 * Modified for use with MPlayer, detailed changelog at
16 * http://svn.mplayerhq.hu/mplayer/trunk/
23 //#define LOADLIB_TRY_NATIVE
25 /* Hack to make sure the correct function declaration in com.h is used when
26 * this file is built for the test applications with WIN32_LOADER disabled. */
31 #ifdef CONFIG_QTX_CODECS
32 #define PSEUDO_SCREEN_WIDTH /*640*/800
33 #define PSEUDO_SCREEN_HEIGHT /*480*/600
36 #include "wine/winbase.h"
37 #include "wine/winreg.h"
38 #include "wine/winnt.h"
39 #include "wine/winerror.h"
40 #include "wine/debugtools.h"
41 #include "wine/module.h"
42 #include "wine/winuser.h"
43 #include "wine/objbase.h"
63 #include <sys/types.h>
67 #include <sys/timeb.h>
72 #ifdef HAVE_SYS_MMAN_H
75 #include "osdep/mmap.h"
77 #include "osdep/mmap_anon.h"
78 #include "libavutil/avstring.h"
80 char* def_path
= BINARY_CODECS_PATH
;
82 static void do_cpuid(unsigned int ax
, unsigned int *regs
)
86 "pushl %%ebx; pushl %%ecx; pushl %%edx;"
92 "popl %%edx; popl %%ecx; popl %%ebx;"
94 : "0" (ax
), "S" (regs
)
97 static unsigned int c_localcount_tsc(void)
109 static void c_longcount_tsc(long long* z
)
114 "movl %%eax, %%ebx\n\t"
116 "movl %%eax, 0(%%ebx)\n\t"
117 "movl %%edx, 4(%%ebx)\n\t"
123 static unsigned int c_localcount_notsc(void)
128 gettimeofday(&tv
, 0);
129 return limit
*tv
.tv_usec
;
131 static void c_longcount_notsc(long long* z
)
134 unsigned long long result
;
138 gettimeofday(&tv
, 0);
141 result
+=limit
*tv
.tv_usec
;
144 static unsigned int localcount_stub(void);
145 static void longcount_stub(long long*);
146 static unsigned int (*localcount
)()=localcount_stub
;
147 static void (*longcount
)(long long*)=longcount_stub
;
149 static pthread_mutex_t memmut
;
151 static unsigned int localcount_stub(void)
153 unsigned int regs
[4];
155 if ((regs
[3] & 0x00000010) != 0)
157 localcount
=c_localcount_tsc
;
158 longcount
=c_longcount_tsc
;
162 localcount
=c_localcount_notsc
;
163 longcount
=c_longcount_notsc
;
167 static void longcount_stub(long long* z
)
169 unsigned int regs
[4];
171 if ((regs
[3] & 0x00000010) != 0)
173 localcount
=c_localcount_tsc
;
174 longcount
=c_longcount_tsc
;
178 localcount
=c_localcount_notsc
;
179 longcount
=c_longcount_notsc
;
185 int LOADER_DEBUG
=1; // active only if compiled with -DDETAILED_OUT
186 //#define DETAILED_OUT
187 static inline void dbgprintf(char* fmt
, ...)
195 f
=fopen("./log", "a");
200 vfprintf(f
, fmt
, va
);
207 if ( mp_msg_test(MSGT_WIN32
,MSGL_DBG3
) )
213 // mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va);
220 char export_names
[300][32]={
225 //#define min(x,y) ((x)<(y)?(x):(y))
227 void destroy_event(void* event
);
230 typedef struct th_list_t
{
233 struct th_list_t
* next
;
234 struct th_list_t
* prev
;
238 // have to be cleared by GARBAGE COLLECTOR
239 //static unsigned char* heap=NULL;
240 //static int heap_counter=0;
241 static tls_t
* g_tls
=NULL
;
242 static th_list
* list
=NULL
;
243 static pthread_mutex_t list_lock
= PTHREAD_MUTEX_INITIALIZER
;
246 static void test_heap(void)
251 while(offset
<heap_counter
)
253 if(*(int*)(heap
+offset
)!=0x433476)
255 printf("Heap corruption at address %d\n", offset
);
258 offset
+=8+*(int*)(heap
+offset
+4);
260 for(;offset
<min(offset
+1000, 20000000); offset
++)
261 if(heap
[offset
]!=0xCC)
263 printf("Free heap corruption at address %d\n", offset
);
271 static void* my_mreq(int size
, int to_zero
)
275 if(test
%10==0)printf("Memory: %d bytes allocated\n", heap_counter
);
279 heap
=malloc(20000000);
280 memset(heap
, 0xCC,20000000);
284 printf("No enough memory\n");
287 if(heap_counter
+size
>20000000)
289 printf("No enough memory\n");
292 *(int*)(heap
+heap_counter
)=0x433476;
294 *(int*)(heap
+heap_counter
)=size
;
296 printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size
, heap_counter
-8, heap_counter
, heap_counter
+size
);
298 memset(heap
+heap_counter
, 0, size
);
300 memset(heap
+heap_counter
, 0xcc, size
); // make crash reproducable
302 return heap
+heap_counter
-size
;
304 static int my_release(char* memory
)
309 printf("ERROR: free(0)\n");
312 if(*(int*)(memory
-8)!=0x433476)
314 printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
317 printf("Freed %d bytes of memory\n", *(int*)(memory
-4));
318 // memset(memory-8, *(int*)(memory-4), 0xCC);
324 typedef struct alloc_header_t alloc_header
;
325 struct alloc_header_t
327 // let's keep allocated data 16 byte aligned
339 static alloc_header
* last_alloc
= NULL
;
340 static int alccnt
= 0;
343 #define AREATYPE_CLIENT 0
344 #define AREATYPE_EVENT 1
345 #define AREATYPE_MUTEX 2
346 #define AREATYPE_COND 3
347 #define AREATYPE_CRITSECT 4
349 /* -- critical sections -- */
353 pthread_mutex_t mutex
;
354 pthread_cond_t unlocked
;
359 void* mreq_private(int size
, int to_zero
, int type
);
360 void* mreq_private(int size
, int to_zero
, int type
)
362 int nsize
= size
+ sizeof(alloc_header
);
363 alloc_header
* header
= malloc(nsize
);
367 memset(header
, 0, nsize
);
371 pthread_mutex_init(&memmut
, NULL
);
372 pthread_mutex_lock(&memmut
);
376 pthread_mutex_lock(&memmut
);
377 last_alloc
->next
= header
; /* set next */
380 header
->prev
= last_alloc
;
384 pthread_mutex_unlock(&memmut
);
386 header
->deadbeef
= 0xdeadbeef;
390 //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt);
394 static int my_release(void* memory
)
396 alloc_header
* header
= (alloc_header
*) memory
- 1;
398 alloc_header
* prevmem
;
399 alloc_header
* nextmem
;
404 if (header
->deadbeef
!= (long) 0xdeadbeef)
406 dbgprintf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
410 pthread_mutex_lock(&memmut
);
415 destroy_event(memory
);
418 pthread_cond_destroy((pthread_cond_t
*)memory
);
421 pthread_mutex_destroy((pthread_mutex_t
*)memory
);
423 case AREATYPE_CRITSECT
:
424 pthread_mutex_destroy(&((struct CRITSECT
*)memory
)->mutex
);
427 //memset(memory, 0xcc, header->size);
431 header
->deadbeef
= 0;
432 prevmem
= header
->prev
;
433 nextmem
= header
->next
;
436 prevmem
->next
= nextmem
;
438 nextmem
->prev
= prevmem
;
440 if (header
== last_alloc
)
441 last_alloc
= prevmem
;
446 pthread_mutex_unlock(&memmut
);
448 pthread_mutex_destroy(&memmut
);
450 //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt);
455 //memset(header + 1, 0xcc, header->size);
461 static inline void* my_mreq(int size
, int to_zero
)
463 return mreq_private(size
, to_zero
, AREATYPE_CLIENT
);
466 static int my_size(void* memory
)
468 if(!memory
) return 0;
469 return ((alloc_header
*)memory
)[-1].size
;
472 static void* my_realloc(void* memory
, int size
)
477 return my_mreq(size
, 0);
478 osize
= my_size(memory
);
481 ans
= my_mreq(size
, 0);
482 memcpy(ans
, memory
, osize
);
490 * WINE API - native implementation for several win32 libraries
494 static int WINAPI
ext_unknown(void)
496 printf("Unknown func called\n");
500 static int WINAPI
expGetVolumeInformationA( const char *root
, char *label
,
501 unsigned int label_len
, unsigned int *serial
,
502 unsigned int *filename_len
,unsigned int *flags
,
503 char *fsname
, unsigned int fsname_len
)
505 dbgprintf("GetVolumeInformationA( %s, 0x%x, %ld, 0x%x, 0x%x, 0x%x, 0x%x, %ld) => 1\n",
506 root
,label
,label_len
,serial
,filename_len
,flags
,fsname
,fsname_len
);
507 //hack Do not return any real data - do nothing
511 static unsigned int WINAPI
expGetDriveTypeA( const char *root
)
513 dbgprintf("GetDriveTypeA( %s ) => %d\n",root
,DRIVE_FIXED
);
514 // hack return as Fixed Drive Type
518 static unsigned int WINAPI
expGetLogicalDriveStringsA( unsigned int len
, char *buffer
)
520 dbgprintf("GetLogicalDriveStringsA(%d, 0x%x) => 4\n",len
,buffer
);
521 // hack only have one drive c:\ in this hack
527 return 4; // 1 drive * 4 bytes (includes null)
531 static int WINAPI
expIsBadWritePtr(void* ptr
, unsigned int count
)
533 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
534 dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
537 static int WINAPI
expIsBadReadPtr(void* ptr
, unsigned int count
)
539 int result
= (count
== 0 || ptr
!= 0) ? 0 : 1;
540 dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr
, count
, result
);
543 static int WINAPI
expDisableThreadLibraryCalls(int module
)
545 dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module
);
549 static HMODULE WINAPI
expGetDriverModuleHandle(DRVR
* pdrv
)
555 result
=pdrv
->hDriverModule
;
556 dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv
, result
);
560 #define MODULE_HANDLE_kernel32 ((HMODULE)0x120)
561 #define MODULE_HANDLE_user32 ((HMODULE)0x121)
562 #ifdef CONFIG_QTX_CODECS
563 #define MODULE_HANDLE_wininet ((HMODULE)0x122)
564 #define MODULE_HANDLE_ddraw ((HMODULE)0x123)
565 #define MODULE_HANDLE_advapi32 ((HMODULE)0x124)
567 #define MODULE_HANDLE_comdlg32 ((HMODULE)0x125)
568 #define MODULE_HANDLE_msvcrt ((HMODULE)0x126)
569 #define MODULE_HANDLE_ole32 ((HMODULE)0x127)
570 #define MODULE_HANDLE_winmm ((HMODULE)0x128)
571 #define MODULE_HANDLE_psapi ((HMODULE)0x129)
573 // Fake PE header, since some software (and the Microsoft CRT v8 and newer)
574 // assume GetModuleHandle(NULL) returns a pointer to a PE header.
575 // We simulate a very simple header with only one section.
577 // NOTE: If you have a section called .mixcrt, the Microsoft CRT will assume
578 // it's running in a POSIX binary, and stop using EncodePointer/DecodePointer.
579 static const struct {
580 IMAGE_DOS_HEADER doshdr
;
581 IMAGE_NT_HEADERS nthdr
;
582 IMAGE_SECTION_HEADER opthdr
;
583 } __attribute__((__packed__
)) mp_exe
= {
584 .doshdr
.e_lfanew
= sizeof(IMAGE_DOS_HEADER
),
585 .nthdr
.FileHeader
.NumberOfSections
= 1,
586 .nthdr
.FileHeader
.SizeOfOptionalHeader
=
587 sizeof(IMAGE_NT_HEADERS
) - FIELD_OFFSET(IMAGE_NT_HEADERS
, OptionalHeader
), /* 0xe0 */
588 .opthdr
.Name
= ".text"
591 static HMODULE WINAPI
expGetModuleHandleA(const char* name
)
596 result
=(HMODULE
)&mp_exe
.doshdr
;
599 wm
=MODULE_FindModule(name
);
602 result
=(HMODULE
)(wm
->module
);
606 if(name
&& (strcasecmp(name
, "kernel32")==0 || !strcasecmp(name
, "kernel32.dll")))
607 result
=MODULE_HANDLE_kernel32
;
608 #ifdef CONFIG_QTX_CODECS
609 if(name
&& strcasecmp(name
, "user32")==0)
610 result
=MODULE_HANDLE_user32
;
613 dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name
, result
);
617 static HMODULE WINAPI
expGetModuleHandleW(const uint16_t* name
)
622 if (*name
> 256 || pos
>= sizeof(aname
) - 1)
624 aname
[pos
++] = *name
++;
627 return expGetModuleHandleA(aname
);
630 static void* WINAPI
expCreateThread(void* pSecAttr
, long dwStackSize
,
631 void* lpStartAddress
, void* lpParameter
,
632 long dwFlags
, long* dwThreadId
)
635 // printf("CreateThread:");
636 pth
= (pthread_t
*) my_mreq(sizeof(pthread_t
), 0);
637 pthread_create(pth
, NULL
, (void*(*)(void*))lpStartAddress
, lpParameter
);
639 printf( "WARNING: CreateThread flags not supported\n");
641 *dwThreadId
=(long)pth
;
642 pthread_mutex_lock(&list_lock
);
645 list
=my_mreq(sizeof(th_list
), 1);
646 list
->next
=list
->prev
=NULL
;
650 list
->next
=my_mreq(sizeof(th_list
), 0);
651 list
->next
->prev
=list
;
652 list
->next
->next
=NULL
;
656 pthread_mutex_unlock(&list_lock
);
657 dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
658 pSecAttr
, dwStackSize
, lpStartAddress
, lpParameter
, dwFlags
, dwThreadId
, pth
);
662 static DWORD WINAPI
expResumeThread(HANDLE hThread
)
665 dbgprintf("ResumeThread(0x%x) => 0x%x\n", hThread
, ret
);
682 struct mutex_list_t
* next
;
683 struct mutex_list_t
* prev
;
685 typedef struct mutex_list_t mutex_list
;
686 static mutex_list
* mlist
=NULL
;
687 static pthread_mutex_t mlist_lock
= PTHREAD_MUTEX_INITIALIZER
;
689 void destroy_event(void* event
)
691 pthread_mutex_lock(&mlist_lock
);
692 mutex_list
* pp
=mlist
;
693 // printf("garbage collector: destroy_event(%x)\n", event);
696 if(pp
==(mutex_list
*)event
)
699 pp
->next
->prev
=pp
->prev
;
701 pp
->prev
->next
=pp
->next
;
702 if(mlist
==(mutex_list
*)event
)
708 printf("%x => ", pp);
713 pthread_mutex_unlock(&mlist_lock
);
718 pthread_mutex_unlock(&mlist_lock
);
721 static void* WINAPI
expCreateEventA(void* pSecAttr
, char bManualReset
,
722 char bInitialState
, const char* name
)
732 printf("%x => ", pp);
737 pthread_mutex_lock(&mlist_lock
);
740 mutex_list
* pp
=mlist
;
744 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==0))
746 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
747 pSecAttr
, bManualReset
, bInitialState
, name
, name
, pp
->pm
);
748 pthread_mutex_unlock(&mlist_lock
);
751 }while((pp
=pp
->prev
) != NULL
);
753 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
754 pthread_mutex_init(pm
, NULL
);
755 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
756 pthread_cond_init(pc
, NULL
);
759 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
760 mlist
->next
=mlist
->prev
=NULL
;
764 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
765 mlist
->next
->prev
=mlist
;
766 mlist
->next
->next
=NULL
;
769 mlist
->type
=0; /* Type Event */
772 mlist
->state
=bInitialState
;
773 mlist
->reset
=!bManualReset
;
775 strncpy(mlist
->name
, name
, 127);
779 dbgprintf("ERROR::: CreateEventA failure\n");
782 pthread_mutex_lock(pm);
785 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
786 pSecAttr
, bManualReset
, bInitialState
, name
, name
, mlist
);
788 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
789 pSecAttr
, bManualReset
, bInitialState
, mlist
);
791 pthread_mutex_unlock(&mlist_lock
);
795 static void* WINAPI
expCreateEventW(void* pSecAttr
, char bManualReset
,
796 char bInitialState
, const WCHAR
* name
)
798 char ascii_name
[256];
801 WideCharToMultiByte(65001, 0x0, name
, -1, ascii_name
, 256, NULL
, NULL
);
804 return expCreateEventA(pSecAttr
, bManualReset
, bInitialState
, aname
);
807 static void* WINAPI
expSetEvent(void* event
)
809 mutex_list
*ml
= (mutex_list
*)event
;
810 dbgprintf("SetEvent(%x) => 0x1\n", event
);
811 pthread_mutex_lock(ml
->pm
);
812 if (ml
->state
== 0) {
814 pthread_cond_signal(ml
->pc
);
816 pthread_mutex_unlock(ml
->pm
);
820 static void* WINAPI
expResetEvent(void* event
)
822 mutex_list
*ml
= (mutex_list
*)event
;
823 dbgprintf("ResetEvent(0x%x) => 0x1\n", event
);
824 pthread_mutex_lock(ml
->pm
);
826 pthread_mutex_unlock(ml
->pm
);
831 static void* WINAPI
expWaitForSingleObject(void* object
, int duration
)
833 mutex_list
*ml
= (mutex_list
*)object
;
834 // FIXME FIXME FIXME - this value is sometime unititialize !!!
835 int ret
= WAIT_FAILED
;
838 if(object
== (void*)0xcfcf9898)
841 From GetCurrentThread() documentation:
842 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.
844 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.
846 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.
848 dbgprintf("WaitForSingleObject(thread_handle) called\n");
849 return (void*)WAIT_FAILED
;
851 dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object
, duration
);
853 // See if this is a thread.
854 pthread_mutex_lock(&list_lock
);
856 while (tp
&& (tp
->thread
!= object
))
858 pthread_mutex_unlock(&list_lock
);
860 if (pthread_join(*(pthread_t
*)object
, NULL
) == 0) {
861 return (void*)WAIT_OBJECT_0
;
863 return (void*)WAIT_FAILED
;
867 // loop below was slightly fixed - its used just for checking if
868 // this object really exists in our list
871 pthread_mutex_lock(&mlist_lock
);
873 while (pp
&& (pp
->pm
!= ml
->pm
))
875 pthread_mutex_unlock(&mlist_lock
);
877 dbgprintf("WaitForSingleObject: NotFound\n");
881 pthread_mutex_lock(ml
->pm
);
885 if (duration
== 0) { /* Check Only */
886 if (ml
->state
== 1) ret
= WAIT_OBJECT_0
;
887 else ret
= WAIT_FAILED
;
889 if (duration
== -1) { /* INFINITE */
891 pthread_cond_wait(ml
->pc
,ml
->pm
);
896 if (duration
> 0) { /* Timed Wait */
897 struct timespec abstime
;
899 gettimeofday(&now
, 0);
900 abstime
.tv_sec
= now
.tv_sec
+ (now
.tv_usec
+duration
)/1000000;
901 abstime
.tv_nsec
= ((now
.tv_usec
+duration
)%1000000)*1000;
903 ret
=pthread_cond_timedwait(ml
->pc
,ml
->pm
,&abstime
);
904 if (ret
== ETIMEDOUT
) ret
= WAIT_TIMEOUT
;
905 else ret
= WAIT_OBJECT_0
;
910 case 1: /* Semaphore */
912 if(ml
->semaphore
==0) ret
= WAIT_FAILED
;
918 if (duration
== -1) {
919 if (ml
->semaphore
==0)
920 pthread_cond_wait(ml
->pc
,ml
->pm
);
927 if(ml
->lock_count
> 0 && ml
->owner
!= pthread_self()) ret
= WAIT_FAILED
;
930 ml
->owner
= pthread_self();
934 if (duration
== -1) {
935 if (ml
->lock_count
> 0 && ml
->owner
!= pthread_self()) {
936 pthread_cond_wait(ml
->pc
,ml
->pm
);
939 ml
->owner
= pthread_self();
944 pthread_mutex_unlock(ml
->pm
);
946 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object
,duration
,ml
,ret
);
950 #ifdef CONFIG_QTX_CODECS
951 static void* WINAPI
expWaitForMultipleObjects(int count
, const void** objects
,
952 int WaitAll
, int duration
)
958 dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
959 count
, objects
, WaitAll
, duration
);
961 for (i
= 0; i
< count
; i
++)
963 object
= (void *)objects
[i
];
964 ret
= expWaitForSingleObject(object
, duration
);
966 dbgprintf("WaitAll flag not yet supported...\n");
973 static void WINAPI
expExitThread(int retcode
)
975 dbgprintf("ExitThread(%d)\n", retcode
);
976 pthread_exit(&retcode
);
980 static int pf_set
= 0;
981 static BYTE PF
[64] = {0,};
983 static void DumpSystemInfo(const SYSTEM_INFO
* si
)
985 dbgprintf(" Processor architecture %d\n", si
->u
.s
.wProcessorArchitecture
);
986 dbgprintf(" Page size: %d\n", si
->dwPageSize
);
987 dbgprintf(" Minimum app address: %d\n", si
->lpMinimumApplicationAddress
);
988 dbgprintf(" Maximum app address: %d\n", si
->lpMaximumApplicationAddress
);
989 dbgprintf(" Active processor mask: 0x%x\n", si
->dwActiveProcessorMask
);
990 dbgprintf(" Number of processors: %d\n", si
->dwNumberOfProcessors
);
991 dbgprintf(" Processor type: 0x%x\n", si
->dwProcessorType
);
992 dbgprintf(" Allocation granularity: 0x%x\n", si
->dwAllocationGranularity
);
993 dbgprintf(" Processor level: 0x%x\n", si
->wProcessorLevel
);
994 dbgprintf(" Processor revision: 0x%x\n", si
->wProcessorRevision
);
997 static void WINAPI
expGetSystemInfo(SYSTEM_INFO
* si
)
999 /* FIXME: better values for the two entries below... */
1000 static int cache
= 0;
1001 static SYSTEM_INFO cachedsi
;
1002 dbgprintf("GetSystemInfo(%p) =>\n", si
);
1007 memset(PF
,0,sizeof(PF
));
1010 cachedsi
.u
.s
.wProcessorArchitecture
= PROCESSOR_ARCHITECTURE_INTEL
;
1011 cachedsi
.dwPageSize
= getpagesize();
1013 /* FIXME: better values for the two entries below... */
1014 cachedsi
.lpMinimumApplicationAddress
= (void *)0x00000000;
1015 cachedsi
.lpMaximumApplicationAddress
= (void *)0x7FFFFFFF;
1016 cachedsi
.dwActiveProcessorMask
= 1;
1017 cachedsi
.dwNumberOfProcessors
= 1;
1018 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1019 cachedsi
.dwAllocationGranularity
= 0x10000;
1020 cachedsi
.wProcessorLevel
= 5; /* pentium */
1021 cachedsi
.wProcessorRevision
= 0x0101;
1023 /* mplayer's way to detect PF's */
1025 #include "cpudetect.h"
1027 if (gCpuCaps
.hasMMX
)
1028 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1029 if (gCpuCaps
.hasSSE
)
1030 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1031 if (gCpuCaps
.hasSSE2
)
1032 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1033 if (gCpuCaps
.has3DNow
)
1034 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1036 if (gCpuCaps
.cpuType
== 4)
1038 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1039 cachedsi
.wProcessorLevel
= 4;
1041 else if (gCpuCaps
.cpuType
>= 5)
1043 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1044 cachedsi
.wProcessorLevel
= 5;
1048 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1049 cachedsi
.wProcessorLevel
= 3;
1051 cachedsi
.wProcessorRevision
= gCpuCaps
.cpuStepping
;
1052 cachedsi
.dwNumberOfProcessors
= 1; /* hardcoded */
1055 /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
1056 fdiv_bug and fpu emulation flags -- alex/MPlayer */
1061 FILE *f
= fopen ("/proc/cpuinfo", "r");
1065 mp_msg(MSGT_WIN32
, MSGL_WARN
, "expGetSystemInfo: "
1066 "/proc/cpuinfo not readable! "
1067 "Expect bad performance and/or weird behaviour\n");
1070 while (fgets(line
,200,f
)!=NULL
) {
1073 /* NOTE: the ':' is the only character we can rely on */
1074 if (!(value
= strchr(line
,':')))
1076 /* terminate the valuename */
1078 /* skip any leading spaces */
1079 while (*value
==' ') value
++;
1080 if ((s
=strchr(value
,'\n')))
1084 if (!lstrncmpiA(line
, "cpu family",strlen("cpu family"))) {
1085 if (isdigit (value
[0])) {
1086 switch (value
[0] - '0') {
1087 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1088 cachedsi
.wProcessorLevel
= 3;
1090 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1091 cachedsi
.wProcessorLevel
= 4;
1093 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1094 cachedsi
.wProcessorLevel
= 5;
1096 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1097 cachedsi
.wProcessorLevel
= 5;
1099 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1100 cachedsi
.wProcessorLevel
= 5;
1104 /* set the CPU type of the current processor */
1105 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1108 /* old 2.0 method */
1109 if (!lstrncmpiA(line
, "cpu",strlen("cpu"))) {
1110 if ( isdigit (value
[0]) && value
[1] == '8' &&
1111 value
[2] == '6' && value
[3] == 0
1113 switch (value
[0] - '0') {
1114 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1115 cachedsi
.wProcessorLevel
= 3;
1117 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1118 cachedsi
.wProcessorLevel
= 4;
1120 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1121 cachedsi
.wProcessorLevel
= 5;
1123 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1124 cachedsi
.wProcessorLevel
= 5;
1126 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1127 cachedsi
.wProcessorLevel
= 5;
1131 /* set the CPU type of the current processor */
1132 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1135 if (!lstrncmpiA(line
,"fdiv_bug",strlen("fdiv_bug"))) {
1136 if (!lstrncmpiA(value
,"yes",3))
1137 PF
[PF_FLOATING_POINT_PRECISION_ERRATA
] = TRUE
;
1141 if (!lstrncmpiA(line
,"fpu",strlen("fpu"))) {
1142 if (!lstrncmpiA(value
,"no",2))
1143 PF
[PF_FLOATING_POINT_EMULATED
] = TRUE
;
1147 if (!lstrncmpiA(line
,"processor",strlen("processor"))) {
1148 /* processor number counts up...*/
1151 if (sscanf(value
,"%d",&x
))
1152 if (x
+1>cachedsi
.dwNumberOfProcessors
)
1153 cachedsi
.dwNumberOfProcessors
=x
+1;
1155 /* Create a new processor subkey on a multiprocessor
1158 sprintf(buf
,"%d",x
);
1160 if (!lstrncmpiA(line
,"stepping",strlen("stepping"))) {
1163 if (sscanf(value
,"%d",&x
))
1164 cachedsi
.wProcessorRevision
= x
;
1167 ( (!lstrncmpiA(line
,"flags",strlen("flags")))
1168 || (!lstrncmpiA(line
,"features",strlen("features"))) )
1170 if (strstr(value
,"cx8"))
1171 PF
[PF_COMPARE_EXCHANGE_DOUBLE
] = TRUE
;
1172 if (strstr(value
,"mmx"))
1173 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1174 if (strstr(value
,"tsc"))
1175 PF
[PF_RDTSC_INSTRUCTION_AVAILABLE
] = TRUE
;
1176 if (strstr(value
,"xmm") || strstr(value
,"sse"))
1177 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1178 if (strstr(value
,"sse2"))
1179 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1180 if (strstr(value
,"3dnow"))
1181 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1186 * ad hoc fix for smp machines.
1187 * some problems on WaitForSingleObject,CreateEvent,SetEvent
1188 * CreateThread ...etc..
1191 cachedsi
.dwNumberOfProcessors
=1;
1193 #endif /* __linux__ */
1196 memcpy(si
,&cachedsi
,sizeof(*si
));
1200 // avoid undefined expGetSystemInfo
1201 static WIN_BOOL WINAPI
expIsProcessorFeaturePresent(DWORD v
)
1203 WIN_BOOL result
= 0;
1207 expGetSystemInfo(&si
);
1209 if(v
<64) result
=PF
[v
];
1210 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v
, result
);
1214 static WIN_BOOL WINAPI
expIsDebuggerPresent(void)
1219 static long WINAPI
expGetVersion(void)
1221 dbgprintf("GetVersion() => 0xC0000004\n");
1222 return 0xC0000004;//Windows 95
1225 static HANDLE WINAPI
expHeapCreate(long flags
, long init_size
, long max_size
)
1227 // printf("HeapCreate:");
1230 result
=(HANDLE
)my_mreq(0x110000, 0);
1232 result
=(HANDLE
)my_mreq((init_size
+ 0xfff) & 0x7ffff000 , 0);
1233 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags
, init_size
, max_size
, result
);
1237 // this is another dirty hack
1238 // VP31 is releasing one allocated Heap chunk twice
1239 // we will silently ignore this second call...
1240 static void* heapfreehack
= 0;
1241 static int heapfreehackshown
= 0;
1242 //void trapbug(void);
1243 static void* WINAPI
expHeapAlloc(HANDLE heap
, int flags
, int size
)
1247 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1248 HeapAlloc returns area larger than size argument :-/
1250 actually according to M$ Doc HeapCreate size should be rounded
1251 to page boundaries thus we should simulate this
1253 //if (size == 22276) trapbug();
1254 z
=my_mreq((size
+ 0xfff) & 0x7ffff000, (flags
& HEAP_ZERO_MEMORY
));
1256 printf("HeapAlloc failure\n");
1257 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap
, flags
, size
, z
);
1258 heapfreehack
= 0; // reset
1261 static long WINAPI
expHeapDestroy(void* heap
)
1263 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap
);
1268 static long WINAPI
expHeapFree(HANDLE heap
, DWORD dwFlags
, LPVOID lpMem
)
1270 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap
, dwFlags
, lpMem
);
1271 if (heapfreehack
!= lpMem
&& lpMem
!= (void*)0xffffffff
1272 && lpMem
!= (void*)0xbdbdbdbd)
1273 // 0xbdbdbdbd is for i263_drv.drv && libefence
1274 // it seems to be reading from relased memory
1275 // EF_PROTECT_FREE doens't show any probleme
1279 if (!heapfreehackshown
++)
1280 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem
);
1282 heapfreehack
= lpMem
;
1285 static long WINAPI
expHeapSize(int heap
, int flags
, void* pointer
)
1287 long result
=my_size(pointer
);
1288 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap
, flags
, pointer
, result
);
1291 static void* WINAPI
expHeapReAlloc(HANDLE heap
,int flags
,void *lpMem
,int size
)
1293 long orgsize
= my_size(lpMem
);
1294 dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize
,size
);
1295 return my_realloc(lpMem
, size
);
1297 static long WINAPI
expGetProcessHeap(void)
1299 dbgprintf("GetProcessHeap() => 1\n");
1302 static void* WINAPI
expVirtualAlloc(void* v1
, long v2
, long v3
, long v4
)
1304 void* z
= VirtualAlloc(v1
, v2
, v3
, v4
);
1306 printf("VirtualAlloc failure\n");
1307 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1
,v2
,v3
,v4
, z
);
1310 static int WINAPI
expVirtualFree(void* v1
, int v2
, int v3
)
1312 int result
= VirtualFree(v1
,v2
,v3
);
1313 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1
,v2
,v3
, result
);
1317 /* we're building a table of critical sections. cs_win pointer uses the DLL
1318 cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1319 struct critsecs_list_t
1321 CRITICAL_SECTION
*cs_win
;
1322 struct CRITSECT
*cs_unix
;
1325 /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1326 #undef CRITSECS_NEWTYPE
1327 //#define CRITSECS_NEWTYPE 1
1329 #ifdef CRITSECS_NEWTYPE
1330 /* increased due to ucod needs more than 32 entries */
1331 /* and 64 should be enough for everything */
1332 #define CRITSECS_LIST_MAX 64
1333 static struct critsecs_list_t critsecs_list
[CRITSECS_LIST_MAX
];
1335 static int critsecs_get_pos(CRITICAL_SECTION
*cs_win
)
1339 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1340 if (critsecs_list
[i
].cs_win
== cs_win
)
1345 static int critsecs_get_unused(void)
1349 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1350 if (critsecs_list
[i
].cs_win
== NULL
)
1355 struct CRITSECT
*critsecs_get_unix(CRITICAL_SECTION
*cs_win
)
1359 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1360 if (critsecs_list
[i
].cs_win
== cs_win
&& critsecs_list
[i
].cs_unix
)
1361 return critsecs_list
[i
].cs_unix
;
1366 static void WINAPI
expInitializeCriticalSection(CRITICAL_SECTION
* c
)
1368 dbgprintf("InitializeCriticalSection(0x%x)\n", c
);
1369 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1371 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1372 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1375 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1376 #ifdef CRITSECS_NEWTYPE
1378 struct CRITSECT
*cs
;
1379 int i
= critsecs_get_unused();
1383 printf("InitializeCriticalSection(%p) - no more space in list\n", c
);
1386 dbgprintf("got unused space at %d\n", i
);
1387 cs
= malloc(sizeof(struct CRITSECT
));
1390 printf("InitializeCriticalSection(%p) - out of memory\n", c
);
1393 pthread_mutex_init(&cs
->mutex
, NULL
);
1394 pthread_cond_init(&cs
->unlocked
, NULL
);
1396 critsecs_list
[i
].cs_win
= c
;
1397 critsecs_list
[i
].cs_unix
= cs
;
1398 dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1403 struct CRITSECT
* cs
= mreq_private(sizeof(struct CRITSECT
) + sizeof(CRITICAL_SECTION
),
1404 0, AREATYPE_CRITSECT
);
1405 pthread_mutex_init(&cs
->mutex
, NULL
);
1406 pthread_cond_init(&cs
->unlocked
, NULL
);
1408 cs
->deadbeef
= 0xdeadbeef;
1415 static WIN_BOOL WINAPI
expInitializeCriticalSectionAndSpinCount(CRITICAL_SECTION
* c
, DWORD spin
)
1417 expInitializeCriticalSection(c
);
1421 static void WINAPI
expEnterCriticalSection(CRITICAL_SECTION
* c
)
1423 #ifdef CRITSECS_NEWTYPE
1424 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1426 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1428 dbgprintf("EnterCriticalSection(0x%x) %p\n",c
, cs
);
1431 dbgprintf("entered uninitialized critisec!\n");
1432 expInitializeCriticalSection(c
);
1433 #ifdef CRITSECS_NEWTYPE
1434 cs
=critsecs_get_unix(c
);
1436 cs
= (*(struct CRITSECT
**)c
);
1438 dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c
);
1440 pthread_mutex_lock(&(cs
->mutex
));
1441 if (cs
->lock_count
> 0 && cs
->id
== pthread_self()) {
1444 while (cs
->lock_count
!= 0) {
1445 pthread_cond_wait(&(cs
->unlocked
), &(cs
->mutex
));
1448 cs
->id
= pthread_self();
1450 pthread_mutex_unlock(&(cs
->mutex
));
1453 static void WINAPI
expLeaveCriticalSection(CRITICAL_SECTION
* c
)
1455 #ifdef CRITSECS_NEWTYPE
1456 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1458 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1460 // struct CRITSECT* cs=(struct CRITSECT*)c;
1461 dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c
, cs
);
1464 dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c
);
1467 pthread_mutex_lock(&(cs
->mutex
));
1468 if (cs
->lock_count
== 0) {
1469 dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c
);
1473 if (cs
->lock_count
== 0) {
1474 pthread_cond_signal(&(cs
->unlocked
));
1476 pthread_mutex_unlock(&(cs
->mutex
));
1480 static void expfree(void* mem
); /* forward declaration */
1482 static void WINAPI
expDeleteCriticalSection(CRITICAL_SECTION
*c
)
1484 #ifdef CRITSECS_NEWTYPE
1485 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1487 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1489 // struct CRITSECT* cs=(struct CRITSECT*)c;
1490 dbgprintf("DeleteCriticalSection(0x%x)\n",c
);
1494 dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c
);
1498 pthread_mutex_lock(&(cs
->mutex
));
1499 if (cs
->lock_count
> 0)
1501 dbgprintf("Win32 Warning: Deleting locked Critical Section %p!!\n", c
);
1503 pthread_mutex_unlock(&(cs
->mutex
));
1506 pthread_mutex_destroy(&(cs
->mutex
));
1507 pthread_cond_destroy(&(cs
->unlocked
));
1508 // released by GarbageCollector in my_relase otherwise
1511 #ifdef CRITSECS_NEWTYPE
1513 int i
= critsecs_get_pos(c
);
1517 printf("DeleteCriticalSection(%p) error (critsec not found)\n", c
);
1521 critsecs_list
[i
].cs_win
= NULL
;
1522 expfree(critsecs_list
[i
].cs_unix
);
1523 critsecs_list
[i
].cs_unix
= NULL
;
1524 dbgprintf("DeleteCriticalSection -> itemno=%d\n", i
);
1529 static int WINAPI
expGetCurrentThreadId(void)
1531 dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1532 return pthread_self();
1534 static int WINAPI
expGetCurrentProcess(void)
1536 dbgprintf("GetCurrentProcess() => %d\n", getpid());
1540 #ifdef CONFIG_QTX_CODECS
1541 // this version is required for Quicktime codecs (.qtx/.qts) to work.
1542 // (they assume some pointers at FS: segment)
1544 extern void* fs_seg
;
1546 //static int tls_count;
1547 static int tls_use_map
[64];
1548 static int WINAPI
expTlsAlloc(void)
1552 if(tls_use_map
[i
]==0)
1555 dbgprintf("TlsAlloc() => %d\n",i
);
1558 dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1562 //static int WINAPI expTlsSetValue(DWORD index, void* value)
1563 static int WINAPI
expTlsSetValue(int index
, void* value
)
1565 dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index
,value
);
1566 // if((index<0) || (index>64))
1569 *(void**)((char*)fs_seg
+0x88+4*index
) = value
;
1573 static void* WINAPI
expTlsGetValue(DWORD index
)
1575 dbgprintf("TlsGetValue(%d)\n",index
);
1576 // if((index<0) || (index>64))
1577 if((index
>=64)) return NULL
;
1578 return *(void**)((char*)fs_seg
+0x88+4*index
);
1581 static int WINAPI
expTlsFree(int idx
)
1583 int index
= (int) idx
;
1584 dbgprintf("TlsFree(%d)\n",index
);
1585 if((index
<0) || (index
>64))
1587 tls_use_map
[index
]=0;
1599 static void* WINAPI
expTlsAlloc(void)
1603 g_tls
=my_mreq(sizeof(tls_t
), 0);
1604 g_tls
->next
=g_tls
->prev
=NULL
;
1608 g_tls
->next
=my_mreq(sizeof(tls_t
), 0);
1609 g_tls
->next
->prev
=g_tls
;
1610 g_tls
->next
->next
=NULL
;
1613 dbgprintf("TlsAlloc() => 0x%x\n", g_tls
);
1615 g_tls
->value
=0; /* XXX For Divx.dll */
1619 static int WINAPI
expTlsSetValue(void* idx
, void* value
)
1621 tls_t
* index
= (tls_t
*) idx
;
1630 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index
, value
, result
);
1633 static void* WINAPI
expTlsGetValue(void* idx
)
1635 tls_t
* index
= (tls_t
*) idx
;
1640 result
=index
->value
;
1641 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index
, result
);
1644 static int WINAPI
expTlsFree(void* idx
)
1646 tls_t
* index
= (tls_t
*) idx
;
1653 index
->next
->prev
=index
->prev
;
1655 index
->prev
->next
=index
->next
;
1657 g_tls
= index
->prev
;
1658 my_release((void*)index
);
1661 dbgprintf("TlsFree(index 0x%x) => %d\n", index
, result
);
1666 static void* WINAPI
expLocalAlloc(int flags
, int size
)
1668 void* z
= my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1670 printf("LocalAlloc() failed\n");
1671 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1675 static void* WINAPI
expLocalReAlloc(int handle
,int size
, int flags
)
1681 if (flags
& LMEM_MODIFY
) {
1682 dbgprintf("LocalReAlloc MODIFY\n");
1683 return (void *)handle
;
1685 oldsize
= my_size((void *)handle
);
1686 newpointer
= my_realloc((void *)handle
,size
);
1687 dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle
,size
,oldsize
, flags
,newpointer
);
1692 static void* WINAPI
expLocalLock(void* z
)
1694 dbgprintf("LocalLock(0x%x) => 0x%x\n", z
, z
);
1698 static void* WINAPI
expGlobalAlloc(int flags
, int size
)
1701 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size
, flags
);
1703 z
=my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1704 //z=calloc(size, 1);
1707 printf("GlobalAlloc() failed\n");
1708 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1711 static void* WINAPI
expGlobalLock(void* z
)
1713 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z
, z
);
1716 // pvmjpg20 - but doesn't work anyway
1717 static int WINAPI
expGlobalSize(void* amem
)
1721 alloc_header
* header
= last_alloc
;
1722 alloc_header
* mem
= (alloc_header
*) amem
- 1;
1725 pthread_mutex_lock(&memmut
);
1728 if (header
->deadbeef
!= 0xdeadbeef)
1730 dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
1736 size
= header
->size
;
1740 header
= header
->prev
;
1742 pthread_mutex_unlock(&memmut
);
1745 dbgprintf("GlobalSize(0x%x)\n", amem
);
1749 static int WINAPI
expLoadIconA( long hinstance
, char *name
)
1751 dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance
,name
);
1755 static int WINAPI
expLoadStringA(long instance
, long id
, void* buf
, long size
)
1757 int result
=LoadStringA(instance
, id
, buf
, size
);
1759 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1760 instance
, id
, buf
, size
, result
, buf
);
1762 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1763 // instance, id, buf, size, result);
1767 static long WINAPI
expMultiByteToWideChar(long v1
, long v2
, char* s1
, long siz1
, short* s2
, int siz2
)
1776 if(siz1
>siz2
/2)siz1
=siz2
/2;
1777 for(i
=1; i
<=siz1
; i
++)
1787 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1788 "size %d, dest buffer 0x%x, dest size %d) => %d\n",
1789 v1
, v2
, s1
, s1
, siz1
, s2
, siz2
, result
);
1791 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1792 "size %d, dest buffer 0x%x, dest size %d) =>\n",
1793 v1
, v2
, siz1
, s2
, siz2
, result
);
1796 static void wch_print(const short* str
)
1798 dbgprintf(" src: ");
1799 while(*str
)dbgprintf("%c", *str
++);
1802 static long WINAPI
expWideCharToMultiByte(long v1
, long v2
, short* s1
, long siz1
,
1803 char* s2
, int siz2
, char* c3
, int* siz3
)
1806 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1807 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1808 result
=WideCharToMultiByte(v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1809 dbgprintf("=> %d\n", result
);
1810 //if(s1)wch_print(s1);
1811 if(s2
)dbgprintf(" dest: %s\n", s2
);
1815 static long WINAPI
expGetVersionExA(OSVERSIONINFOA
* c
)
1817 dbgprintf("GetVersionExA(0x%x) => 1\n");
1818 c
->dwOSVersionInfoSize
=sizeof(*c
);
1819 c
->dwMajorVersion
=4;
1820 c
->dwMinorVersion
=0;
1821 c
->dwBuildNumber
=0x4000457;
1823 // leave it here for testing win9x-only codecs
1824 c
->dwPlatformId
=VER_PLATFORM_WIN32_WINDOWS
;
1825 strcpy(c
->szCSDVersion
, " B");
1827 c
->dwPlatformId
=VER_PLATFORM_WIN32_NT
; // let's not make DLL assume that it can read CR* registers
1828 strcpy(c
->szCSDVersion
, "Service Pack 3");
1830 dbgprintf(" Major version: 4\n Minor version: 0\n Build number: 0x4000457\n"
1831 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 3'\n");
1835 static long WINAPI
expGetVersionExW(OSVERSIONINFOW
* c
)
1837 char CSDVersion
[128];
1838 dbgprintf("GetVersionExW(0x%x) => 1\n");
1839 c
->dwOSVersionInfoSize
=sizeof(*c
);
1840 c
->dwMajorVersion
=5;
1841 c
->dwMinorVersion
=0;
1842 c
->dwBuildNumber
=0x5000457;
1844 // leave it here for testing win9x-only codecs
1845 c
->dwPlatformId
=VER_PLATFORM_WIN32_WINDOWS
;
1846 strcpy(CSDVersion
, " B");
1848 c
->dwPlatformId
=VER_PLATFORM_WIN32_NT
; // let's not make DLL assume that it can read CR* registers
1849 strcpy(CSDVersion
, "Service Pack 3");
1851 MultiByteToWideChar(65001, 0x0, CSDVersion
, -1, c
->szCSDVersion
, 128);
1852 dbgprintf(" Major version: %d\n Minor version: %d\n Build number: 0x%08x\n"
1853 " Platform Id: %s\n Version string: '%s'\n",
1854 c
->dwMajorVersion
, c
->dwMinorVersion
, c
->dwBuildNumber
,
1855 (c
->dwPlatformId
==VER_PLATFORM_WIN32_WINDOWS
? "VER_PLATFORM_WIN32_WINDOWS" :
1856 (c
->dwPlatformId
==VER_PLATFORM_WIN32_NT
? "VER_PLATFORM_WIN32_NT" : "Unknown")),
1861 static HANDLE WINAPI
expCreateSemaphoreA(char* v1
, long init_count
,
1862 long max_count
, char* name
)
1864 pthread_mutex_t
*pm
;
1869 printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1873 printf("%p => ", pp);
1878 pthread_mutex_lock(&mlist_lock
);
1881 mutex_list
* pp
=mlist
;
1885 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==1))
1887 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1888 v1
, init_count
, max_count
, name
, name
, mlist
);
1889 ret
= (HANDLE
)mlist
;
1890 pthread_mutex_unlock(&mlist_lock
);
1893 }while((pp
=pp
->prev
) != NULL
);
1895 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
1896 pthread_mutex_init(pm
, NULL
);
1897 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
1898 pthread_cond_init(pc
, NULL
);
1901 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1902 mlist
->next
=mlist
->prev
=NULL
;
1906 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1907 mlist
->next
->prev
=mlist
;
1908 mlist
->next
->next
=NULL
;
1910 // printf("new semaphore %p\n", mlist);
1912 mlist
->type
=1; /* Type Semaphore */
1917 mlist
->semaphore
=init_count
;
1919 strncpy(mlist
->name
, name
, 64);
1923 dbgprintf("ERROR::: CreateSemaphoreA failure\n");
1925 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1926 v1
, init_count
, max_count
, name
, name
, mlist
);
1928 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1929 v1
, init_count
, max_count
, mlist
);
1930 ret
= (HANDLE
)mlist
;
1931 pthread_mutex_unlock(&mlist_lock
);
1935 static HANDLE WINAPI
expCreateSemaphoreW(char* v1
, long init_count
,
1936 long max_count
, const WCHAR
* name
)
1938 char ascii_name
[256];
1941 WideCharToMultiByte(65001, 0x0, name
, -1, ascii_name
, 256, NULL
, NULL
);
1944 return expCreateSemaphoreA(v1
, init_count
, max_count
, aname
);
1947 static long WINAPI
expReleaseSemaphore(long hsem
, long increment
, long* prev_count
)
1949 // The state of a semaphore object is signaled when its count
1950 // is greater than zero and nonsignaled when its count is equal to zero
1951 // Each time a waiting thread is released because of the semaphore's signaled
1952 // state, the count of the semaphore is decreased by one.
1953 mutex_list
*ml
= (mutex_list
*)hsem
;
1955 pthread_mutex_lock(ml
->pm
);
1956 if (prev_count
!= 0) *prev_count
= ml
->semaphore
;
1957 if (ml
->semaphore
== 0) pthread_cond_signal(ml
->pc
);
1958 ml
->semaphore
+= increment
;
1959 pthread_mutex_unlock(ml
->pm
);
1960 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1961 hsem
, increment
, prev_count
);
1965 static HANDLE WINAPI
expCreateMutexA(void *pSecAttr
,
1966 char bInitialOwner
, const char *name
)
1968 pthread_mutex_t
*pm
;
1971 pthread_mutex_lock(&mlist_lock
);
1974 mutex_list
* pp
=mlist
;
1978 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==2))
1980 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n", pSecAttr
, bInitialOwner
, name
, mlist
);
1981 ret
= (HANDLE
)mlist
;
1982 pthread_mutex_unlock(&mlist_lock
);
1985 }while((pp
=pp
->prev
) != NULL
);
1987 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
1988 pthread_mutex_init(pm
, NULL
);
1989 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
1990 pthread_cond_init(pc
, NULL
);
1993 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1994 mlist
->next
=mlist
->prev
=NULL
;
1998 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1999 mlist
->next
->prev
=mlist
;
2000 mlist
->next
->next
=NULL
;
2003 mlist
->type
=2; /* Type Mutex */
2009 if (bInitialOwner
) {
2010 mlist
->owner
= pthread_self();
2011 mlist
->lock_count
= 1;
2013 mlist
->owner
= (pthread_t
)0;
2014 mlist
->lock_count
= 0;
2017 strncpy(mlist
->name
, name
, 64);
2021 dbgprintf("ERROR::: CreateMutexA failure\n");
2023 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
2024 pSecAttr
, bInitialOwner
, name
, mlist
);
2026 dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
2027 pSecAttr
, bInitialOwner
, mlist
);
2028 ret
= (HANDLE
)mlist
;
2029 pthread_mutex_unlock(&mlist_lock
);
2033 static HANDLE WINAPI
expCreateMutexW(void *pSecAttr
, char bInitialOwner
, const WCHAR
*name
)
2035 char ascii_name
[256];
2038 WideCharToMultiByte(65001, 0x0, name
, -1, ascii_name
, 256, NULL
, NULL
);
2041 return expCreateMutexA(pSecAttr
, bInitialOwner
, aname
);
2044 static int WINAPI
expReleaseMutex(HANDLE hMutex
)
2046 mutex_list
*ml
= (mutex_list
*)hMutex
;
2048 pthread_mutex_lock(ml
->pm
);
2049 if (--ml
->lock_count
== 0) pthread_cond_signal(ml
->pc
);
2050 pthread_mutex_unlock(ml
->pm
);
2054 static DWORD WINAPI
expSignalObjectAndWait(HANDLE hObjectToSignal
,
2055 HANDLE hObjectToWaitOn
,
2056 DWORD dwMilliseconds
,
2057 WIN_BOOL bAlertable
) {
2058 mutex_list
* mlist
= (mutex_list
*)hObjectToSignal
;
2060 switch (mlist
->type
) {
2064 case 1: // Semaphore
2065 expReleaseSemaphore(mlist
, 1, NULL
);
2068 expReleaseMutex(mlist
);
2071 dbgprintf("Signalling unknown object type %d!\n", hObjectToSignal
);
2073 return expWaitForSingleObject(hObjectToWaitOn
, dwMilliseconds
);
2076 static long WINAPI
expRegOpenKeyExA(long key
, const char* subkey
, long reserved
, long access
, int* newkey
)
2078 long result
=RegOpenKeyExA(key
, subkey
, reserved
, access
, newkey
);
2079 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
2080 key
, subkey
, reserved
, access
, newkey
, result
);
2081 if(newkey
)dbgprintf(" New key: 0x%x\n", *newkey
);
2084 static long WINAPI
expRegCloseKey(long key
)
2086 long result
=RegCloseKey(key
);
2087 dbgprintf("RegCloseKey(0x%x) => %d\n", key
, result
);
2090 static long WINAPI
expRegQueryValueExA(long key
, const char* value
, int* reserved
, int* type
, int* data
, int* count
)
2092 long result
=RegQueryValueExA(key
, value
, reserved
, type
, data
, count
);
2093 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
2094 " => 0x%x\n", key
, value
, reserved
, data
, count
, result
);
2095 if(data
&& count
)dbgprintf(" read %d bytes: '%s'\n", *count
, data
);
2099 //from wine source dlls/advapi32/registry.c
2100 static long WINAPI
expRegCreateKeyA(long hkey
, const char* name
, int *retkey
)
2102 dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey
,name
,retkey
);
2103 return RegCreateKeyExA( hkey
, name
, 0, NULL
,REG_OPTION_NON_VOLATILE
,
2104 KEY_ALL_ACCESS
, NULL
, retkey
, NULL
);
2107 static long WINAPI
expRegCreateKeyExA(long key
, const char* name
, long reserved
,
2108 void* classs
, long options
, long security
,
2109 void* sec_attr
, int* newkey
, int* status
)
2111 long result
=RegCreateKeyExA(key
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
);
2112 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
2113 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
2114 key
, name
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
, result
);
2115 if(!result
&& newkey
) dbgprintf(" New key: 0x%x\n", *newkey
);
2116 if(!result
&& status
) dbgprintf(" New key status: 0x%x\n", *status
);
2119 static long WINAPI
expRegSetValueExA(long key
, const char* name
, long v1
, long v2
, void* data
, long size
)
2121 long result
=RegSetValueExA(key
, name
, v1
, v2
, data
, size
);
2122 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
2123 key
, name
, v1
, v2
, data
, *(int*)data
, data
, size
, result
);
2127 static long WINAPI
expRegOpenKeyA (long hKey
, LPCSTR lpSubKey
, int* phkResult
)
2129 long result
=RegOpenKeyExA(hKey
, lpSubKey
, 0, 0, phkResult
);
2130 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
2131 hKey
, lpSubKey
, phkResult
, result
);
2132 if(!result
&& phkResult
) dbgprintf(" New key: 0x%x\n", *phkResult
);
2136 static DWORD WINAPI
expRegEnumValueA(HKEY hkey
, DWORD index
, LPSTR value
, LPDWORD val_count
,
2137 LPDWORD reserved
, LPDWORD type
, LPBYTE data
, LPDWORD count
)
2139 return RegEnumValueA(hkey
, index
, value
, val_count
,
2140 reserved
, type
, data
, count
);
2143 static DWORD WINAPI
expRegEnumKeyExA(HKEY hKey
, DWORD dwIndex
, LPSTR lpName
, LPDWORD lpcbName
,
2144 LPDWORD lpReserved
, LPSTR lpClass
, LPDWORD lpcbClass
,
2145 LPFILETIME lpftLastWriteTime
)
2147 return RegEnumKeyExA(hKey
, dwIndex
, lpName
, lpcbName
, lpReserved
, lpClass
,
2148 lpcbClass
, lpftLastWriteTime
);
2151 static long WINAPI
expQueryPerformanceCounter(long long* z
)
2154 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z
, *z
);
2159 * dummy function RegQueryInfoKeyA(), required by vss codecs
2161 static DWORD WINAPI
expRegQueryInfoKeyA( HKEY hkey
, LPSTR
class, LPDWORD class_len
, LPDWORD reserved
,
2162 LPDWORD subkeys
, LPDWORD max_subkey
, LPDWORD max_class
,
2163 LPDWORD values
, LPDWORD max_value
, LPDWORD max_data
,
2164 LPDWORD security
, FILETIME
*modif
)
2166 return ERROR_SUCCESS
;
2170 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
2172 static double linux_cpuinfo_freq(void)
2179 f
= fopen ("/proc/cpuinfo", "r");
2181 while (fgets(line
,sizeof(line
),f
)!=NULL
) {
2182 /* NOTE: the ':' is the only character we can rely on */
2183 if (!(value
= strchr(line
,':')))
2185 /* terminate the valuename */
2187 /* skip any leading spaces */
2188 while (*value
==' ') value
++;
2189 if ((s
=strchr(value
,'\n')))
2192 if (!strncasecmp(line
, "cpu MHz",strlen("cpu MHz"))
2193 && sscanf(value
, "%lf", &freq
) == 1) {
2204 static double solaris_kstat_freq(void)
2206 #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
2208 * try to extract the CPU speed from the solaris kernel's kstat data
2212 kstat_named_t
*kdata
;
2218 ksp
= kstat_lookup(kc
, "cpu_info", 0, "cpu_info0");
2220 /* kstat found and name/value pairs? */
2221 if (ksp
!= NULL
&& ksp
->ks_type
== KSTAT_TYPE_NAMED
)
2223 /* read the kstat data from the kernel */
2224 if (kstat_read(kc
, ksp
, NULL
) != -1)
2227 * lookup desired "clock_MHz" entry, check the expected
2230 kdata
= (kstat_named_t
*)kstat_data_lookup(ksp
, "clock_MHz");
2231 if (kdata
!= NULL
&& kdata
->data_type
== KSTAT_DATA_INT32
)
2232 mhz
= kdata
->value
.i32
;
2240 #endif /* HAVE_LIBKSTAT */
2241 return -1; // kstat stuff is not available, CPU freq is unknown
2245 * Measure CPU freq using the pentium's time stamp counter register (TSC)
2247 static double tsc_freq(void)
2249 static double ofreq
=0.0;
2253 if (ofreq
!= 0.0) return ofreq
;
2254 while(i
==time(NULL
));
2257 while(i
==time(NULL
));
2259 ofreq
= (double)(y
-x
)/1000.;
2263 static double CPU_Freq(void)
2267 if ((freq
= linux_cpuinfo_freq()) > 0)
2270 if ((freq
= solaris_kstat_freq()) > 0)
2276 static long WINAPI
expQueryPerformanceFrequency(long long* z
)
2278 *z
=(long long)CPU_Freq();
2279 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z
, *z
);
2282 static long WINAPI
exptimeGetTime(void)
2286 gettimeofday(&t
, 0);
2287 result
=1000*t
.tv_sec
+t
.tv_usec
/1000;
2288 dbgprintf("timeGetTime() => %d\n", result
);
2291 static void* WINAPI
expLocalHandle(void* v
)
2293 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v
, v
);
2297 static void* WINAPI
expGlobalHandle(void* v
)
2299 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v
, v
);
2302 static int WINAPI
expGlobalUnlock(void* v
)
2304 dbgprintf("GlobalUnlock(0x%x) => 1\n", v
);
2307 static void* WINAPI
expGlobalFree(void* v
)
2309 dbgprintf("GlobalFree(0x%x) => 0\n", v
);
2315 static void* WINAPI
expGlobalReAlloc(void* v
, int size
, int flags
)
2317 void* result
=my_realloc(v
, size
);
2318 //void* result=realloc(v, size);
2319 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v
,size
,flags
,result
);
2323 static int WINAPI
expLocalUnlock(void* v
)
2325 dbgprintf("LocalUnlock(0x%x) => 1\n", v
);
2329 static void* WINAPI
expLocalFree(void* v
)
2331 dbgprintf("LocalFree(0x%x) => 0\n", v
);
2335 static HRSRC WINAPI
expFindResourceA(HMODULE module
, char* name
, char* type
)
2339 result
=FindResourceA(module
, name
, type
);
2340 dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2341 module
, name
, HIWORD(name
) ? name
: "UNICODE", type
, HIWORD(type
) ? type
: "UNICODE", result
);
2345 static HGLOBAL WINAPI
expLoadResource(HMODULE module
, HRSRC res
)
2347 HGLOBAL result
=LoadResource(module
, res
);
2348 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module
, res
, result
);
2351 static void* WINAPI
expLockResource(long res
)
2353 void* result
=LockResource(res
);
2354 dbgprintf("LockResource(0x%x) => 0x%x\n", res
, result
);
2357 static int WINAPI
expFreeResource(long res
)
2359 int result
=FreeResource(res
);
2360 dbgprintf("FreeResource(0x%x) => %d\n", res
, result
);
2365 static int WINAPI
expCloseHandle(long v1
)
2367 dbgprintf("CloseHandle(0x%x) => 1\n", v1
);
2368 /* do not close stdin,stdout and stderr */
2375 static const char* WINAPI
expGetCommandLineA(void)
2377 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2378 return "c:\\aviplay.exe";
2380 static short envs
[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2381 static LPWSTR WINAPI
expGetEnvironmentStringsW(void)
2383 dbgprintf("GetEnvironmentStringsW() => 0\n", envs
);
2386 static void * WINAPI
expRtlZeroMemory(void *p
, size_t len
)
2388 void* result
=memset(p
,0,len
);
2389 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p
,len
,result
);
2392 static void * WINAPI
expRtlMoveMemory(void *dst
, void *src
, size_t len
)
2394 void* result
=memmove(dst
,src
,len
);
2395 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst
,src
,len
,result
);
2399 static void * WINAPI
expRtlFillMemory(void *p
, int ch
, size_t len
)
2401 void* result
=memset(p
,ch
,len
);
2402 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p
,ch
,len
,result
);
2405 static int WINAPI
expFreeEnvironmentStringsW(short* strings
)
2407 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings
);
2410 static int WINAPI
expFreeEnvironmentStringsA(char* strings
)
2412 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings
);
2416 static const char ch_envs
[]=
2417 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2418 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2419 static LPCSTR WINAPI
expGetEnvironmentStrings(void)
2421 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs
);
2422 return (LPCSTR
)ch_envs
;
2423 // dbgprintf("GetEnvironmentStrings() => 0\n");
2427 static int WINAPI
expGetStartupInfoA(STARTUPINFOA
*s
)
2429 dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2430 memset(s
, 0, sizeof(*s
));
2432 // s->lpReserved="Reserved";
2433 // s->lpDesktop="Desktop";
2434 // s->lpTitle="Title";
2436 // s->dwXSize=s->dwYSize=200;
2437 s
->dwFlags
=s
->wShowWindow
=1;
2438 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2439 dbgprintf(" cb=%d\n", s
->cb
);
2440 dbgprintf(" lpReserved='%s'\n", s
->lpReserved
);
2441 dbgprintf(" lpDesktop='%s'\n", s
->lpDesktop
);
2442 dbgprintf(" lpTitle='%s'\n", s
->lpTitle
);
2443 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2444 s
->dwX
, s
->dwY
, s
->dwXSize
, s
->dwYSize
);
2445 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2446 s
->dwXCountChars
, s
->dwYCountChars
, s
->dwFillAttribute
);
2447 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2448 s
->dwFlags
, s
->wShowWindow
, s
->cbReserved2
);
2449 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2450 s
->lpReserved2
, s
->hStdInput
, s
->hStdOutput
, s
->hStdError
);
2454 static int WINAPI
expGetStdHandle(int z
)
2456 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z
+0x1234);
2460 #ifdef CONFIG_QTX_CODECS
2461 #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2462 #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2465 static int WINAPI
expGetFileType(int handle
)
2467 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle
);
2470 #ifdef CONFIG_QTX_CODECS
2471 static int WINAPI
expGetFileAttributesA(char *filename
)
2473 dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename
);
2474 if (strstr(filename
, "QuickTime.qts"))
2475 return FILE_ATTRIBUTE_SYSTEM
;
2476 return FILE_ATTRIBUTE_NORMAL
;
2479 static int WINAPI
expSetHandleCount(int count
)
2481 dbgprintf("SetHandleCount(0x%x) => 1\n", count
);
2484 static int WINAPI
expGetACP(void)
2486 dbgprintf("GetACP() => 0\n");
2489 static int WINAPI
expGetModuleFileNameA(int module
, char* s
, int len
)
2493 //printf("File name of module %X (%s) requested\n", module, s);
2495 if (module
== 0 && len
>= 12)
2497 /* return caller program name */
2498 strcpy(s
, "aviplay.dll");
2509 strcpy(s
, "c:\\windows\\system\\");
2510 mr
=MODULE32_LookupHMODULE(module
);
2512 strcat(s
, "aviplay.dll");
2514 if(strrchr(mr
->filename
, '/')==NULL
)
2515 strcat(s
, mr
->filename
);
2517 strcat(s
, strrchr(mr
->filename
, '/')+1);
2520 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2521 module
, s
, len
, result
);
2523 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2524 module
, s
, len
, result
, s
);
2528 static int WINAPI
expGetModuleBaseNameA(int process
, int module
, char* s
, int len
)
2533 av_strlcpy(s
, "aviplay.dll", len
);
2537 dbgprintf("GetModuleBaseNameA(0x%x, 0x%x, 0x%x, %d) => %d\n",
2538 process
, module
, s
, len
, result
);
2543 static int WINAPI
expSetUnhandledExceptionFilter(void* filter
)
2545 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter
);
2546 return 1;//unsupported and probably won't ever be supported
2549 static int WINAPI
expLoadLibraryA(char* name
)
2555 // we skip to the last backslash
2556 // this is effectively eliminating weird characters in
2557 // the text output windows
2559 lastbc
= strrchr(name
, '\\');
2566 name
[i
] = *lastbc
++;
2571 if(strncmp(name
, "c:\\windows\\", 11)==0) name
+= 11;
2572 if(strncmp(name
, ".\\", 2)==0) name
+= 2;
2574 dbgprintf("Entering LoadLibraryA(%s)\n", name
);
2576 // PIMJ and VIVO audio are loading kernel32.dll
2577 if (strcasecmp(name
, "kernel32.dll") == 0 || strcasecmp(name
, "kernel32") == 0)
2578 return MODULE_HANDLE_kernel32
;
2579 // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2580 /* exported -> do not return failed! */
2582 if (strcasecmp(name
, "user32.dll") == 0 || strcasecmp(name
, "user32") == 0)
2583 // return MODULE_HANDLE_kernel32;
2584 return MODULE_HANDLE_user32
;
2586 #ifdef CONFIG_QTX_CODECS
2587 if (strcasecmp(name
, "wininet.dll") == 0 || strcasecmp(name
, "wininet") == 0)
2588 return MODULE_HANDLE_wininet
;
2589 if (strcasecmp(name
, "ddraw.dll") == 0 || strcasecmp(name
, "ddraw") == 0)
2590 return MODULE_HANDLE_ddraw
;
2591 if (strcasecmp(name
, "advapi32.dll") == 0 || strcasecmp(name
, "advapi32") == 0)
2592 return MODULE_HANDLE_advapi32
;
2595 if (strcasecmp(name
, "comdlg32.dll") == 0 || strcasecmp(name
, "comdlg32") == 0)
2596 return MODULE_HANDLE_comdlg32
;
2597 if (strcasecmp(name
, "msvcrt.dll") == 0 || strcasecmp(name
, "msvcrt") == 0)
2598 return MODULE_HANDLE_msvcrt
;
2599 if (strcasecmp(name
, "ole32.dll") == 0 || strcasecmp(name
, "ole32") == 0)
2600 return MODULE_HANDLE_ole32
;
2601 if (strcasecmp(name
, "winmm.dll") == 0 || strcasecmp(name
, "winmm") == 0)
2602 return MODULE_HANDLE_winmm
;
2603 if (strcasecmp(name
, "psapi.dll") == 0 || strcasecmp(name
, "psapi") == 0)
2604 return MODULE_HANDLE_psapi
;
2606 result
=LoadLibraryA(name
);
2607 dbgprintf("Returned LoadLibraryA(0x%x='%s'), def_path=%s => 0x%x\n", name
, name
, def_path
, result
);
2612 static int WINAPI
expFreeLibrary(int module
)
2614 #ifdef CONFIG_QTX_CODECS
2615 int result
=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2617 int result
=FreeLibrary(module
);
2619 dbgprintf("FreeLibrary(0x%x) => %d\n", module
, result
);
2623 static void* WINAPI
expGetProcAddress(HMODULE mod
, char* name
)
2627 case MODULE_HANDLE_kernel32
:
2628 result
=LookupExternalByName("kernel32.dll", name
); break;
2629 case MODULE_HANDLE_user32
:
2630 result
=LookupExternalByName("user32.dll", name
); break;
2631 #ifdef CONFIG_QTX_CODECS
2632 case MODULE_HANDLE_wininet
:
2633 result
=LookupExternalByName("wininet.dll", name
); break;
2634 case MODULE_HANDLE_ddraw
:
2635 result
=LookupExternalByName("ddraw.dll", name
); break;
2636 case MODULE_HANDLE_advapi32
:
2637 result
=LookupExternalByName("advapi32.dll", name
); break;
2639 case MODULE_HANDLE_comdlg32
:
2640 result
=LookupExternalByName("comdlg32.dll", name
); break;
2641 case MODULE_HANDLE_msvcrt
:
2642 result
=LookupExternalByName("msvcrt.dll", name
); break;
2643 case MODULE_HANDLE_ole32
:
2644 result
=LookupExternalByName("ole32.dll", name
); break;
2645 case MODULE_HANDLE_winmm
:
2646 result
=LookupExternalByName("winmm.dll", name
); break;
2647 case MODULE_HANDLE_psapi
:
2648 result
=LookupExternalByName("psapi.dll", name
); break;
2650 result
=GetProcAddress(mod
, name
);
2652 if((unsigned int)name
> 0xffff)
2653 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod
, name
, result
);
2655 dbgprintf("GetProcAddress(0x%x, '%d') => 0x%x\n", mod
, (int)name
, result
);
2659 static long WINAPI
expCreateFileMappingA(int hFile
, void* lpAttr
,
2660 long flProtect
, long dwMaxHigh
,
2661 long dwMaxLow
, const char* name
)
2663 long result
=CreateFileMappingA(hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
);
2665 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2666 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2667 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, result
);
2669 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2670 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2671 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
, name
, result
);
2675 static long WINAPI
expOpenFileMappingA(long hFile
, long hz
, const char* name
)
2677 long result
=OpenFileMappingA(hFile
, hz
, name
);
2679 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2682 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2683 hFile
, hz
, name
, name
, result
);
2687 static void* WINAPI
expMapViewOfFile(HANDLE file
, DWORD mode
, DWORD offHigh
,
2688 DWORD offLow
, DWORD size
)
2690 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2691 file
,mode
,offHigh
,offLow
,size
,(char*)file
+offLow
);
2692 return (char*)file
+offLow
;
2695 static void* WINAPI
expUnmapViewOfFile(void* view
)
2697 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view
);
2701 static void* WINAPI
expSleep(int time
)
2704 /* solaris doesn't have thread safe usleep */
2705 struct timespec tsp
;
2706 tsp
.tv_sec
= time
/ 1000000;
2707 tsp
.tv_nsec
= (time
% 1000000) * 1000;
2708 nanosleep(&tsp
, NULL
);
2712 dbgprintf("Sleep(%d) => 0\n", time
);
2716 // why does IV32 codec want to call this? I don't know ...
2717 static int WINAPI
expCreateCompatibleDC(int hdc
)
2720 //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2721 dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc
, dc
);
2725 static int WINAPI
expGetDeviceCaps(int hdc
, int unk
)
2727 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc
, unk
);
2728 #ifdef CONFIG_QTX_CODECS
2729 #define BITSPIXEL 12
2731 if (unk
== BITSPIXEL
)
2739 static WIN_BOOL WINAPI
expDeleteDC(int hdc
)
2741 dbgprintf("DeleteDC(0x%x) => 0\n", hdc
);
2747 static WIN_BOOL WINAPI
expDeleteObject(int hdc
)
2749 dbgprintf("DeleteObject(0x%x) => 1\n", hdc
);
2750 /* FIXME - implement code here */
2754 /* btvvc32.drv wants this one */
2755 static void* WINAPI
expGetWindowDC(int hdc
)
2757 dbgprintf("GetWindowDC(%d) => 0x0\n", hdc
);
2761 #ifdef CONFIG_QTX_CODECS
2762 static int WINAPI
expGetWindowRect(HWND win
, RECT
*r
)
2764 dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win
, r
);
2765 /* (win == 0) => desktop */
2766 r
->right
= PSEUDO_SCREEN_WIDTH
;
2768 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
2773 static int WINAPI
expMonitorFromWindow(HWND win
, int flags
)
2775 dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win
, flags
);
2779 static int WINAPI
expMonitorFromRect(RECT
*r
, int flags
)
2781 dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r
, flags
);
2785 static int WINAPI
expMonitorFromPoint(void *p
, int flags
)
2787 dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p
, flags
);
2791 static int WINAPI
expEnumDisplayMonitors(void *dc
, RECT
*r
,
2792 int WINAPI (*callback_proc
)(), void *callback_param
)
2794 dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2795 dc
, r
, callback_proc
, callback_param
);
2796 return callback_proc(0, dc
, r
, callback_param
);
2800 typedef struct tagMONITORINFO
{
2805 } MONITORINFO
, *LPMONITORINFO
;
2808 #define CCHDEVICENAME 8
2809 typedef struct tagMONITORINFOEX
{
2814 TCHAR szDevice
[CCHDEVICENAME
];
2815 } MONITORINFOEX
, *LPMONITORINFOEX
;
2817 static int WINAPI
expGetMonitorInfoA(void *mon
, LPMONITORINFO lpmi
)
2819 dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon
, lpmi
);
2821 lpmi
->rcMonitor
.right
= lpmi
->rcWork
.right
= PSEUDO_SCREEN_WIDTH
;
2822 lpmi
->rcMonitor
.left
= lpmi
->rcWork
.left
= 0;
2823 lpmi
->rcMonitor
.bottom
= lpmi
->rcWork
.bottom
= PSEUDO_SCREEN_HEIGHT
;
2824 lpmi
->rcMonitor
.top
= lpmi
->rcWork
.top
= 0;
2826 lpmi
->dwFlags
= 1; /* primary monitor */
2828 if (lpmi
->cbSize
== sizeof(MONITORINFOEX
))
2830 LPMONITORINFOEX lpmiex
= (LPMONITORINFOEX
)lpmi
;
2831 dbgprintf("MONITORINFOEX!\n");
2832 strncpy(lpmiex
->szDevice
, "Monitor1", CCHDEVICENAME
);
2838 static int WINAPI
expEnumDisplayDevicesA(const char *device
, int devnum
,
2839 void *dispdev
, int flags
)
2841 dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2842 device
, device
, devnum
, dispdev
, flags
);
2846 static int WINAPI
expIsWindowVisible(HWND win
)
2848 dbgprintf("IsWindowVisible(0x%x) => 1\n", win
);
2852 static HWND WINAPI
expGetActiveWindow(void)
2854 dbgprintf("GetActiveWindow() => 0\n");
2858 static int WINAPI
expGetClassNameA(HWND win
, LPTSTR classname
, int maxcount
)
2860 strncat(classname
, "QuickTime", maxcount
);
2861 dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2862 win
, classname
, maxcount
, strlen(classname
));
2863 return strlen(classname
);
2866 #define LPWNDCLASS void *
2867 static int WINAPI
expGetClassInfoA(HINSTANCE inst
, LPCSTR classname
, LPWNDCLASS wndclass
)
2869 dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst
,
2870 classname
, classname
, wndclass
);
2874 static int WINAPI
expGetWindowLongA(HWND win
, int index
)
2876 dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win
, index
);
2880 static int WINAPI
expGetObjectA(HGDIOBJ hobj
, int objsize
, LPVOID obj
)
2882 dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj
, objsize
, obj
, objsize
);
2886 static int WINAPI
expCreateRectRgn(int x
, int y
, int width
, int height
)
2888 dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x
, y
, width
, height
);
2892 static int WINAPI
expEnumWindows(int (*callback_func
)(), void *callback_param
)
2895 dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func
, callback_param
);
2896 i
= callback_func(0, callback_param
);
2897 i2
= callback_func(1, callback_param
);
2901 static int WINAPI
expGetWindowThreadProcessId(HWND win
, int *pid_data
)
2903 int tid
= pthread_self();
2904 dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2905 win
, pid_data
, tid
);
2907 *(int*)pid_data
= tid
;
2911 //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2912 // INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2914 static HWND WINAPI
expCreateWindowExA(int exstyle
, const char *classname
,
2915 const char *winname
, int style
, int x
, int y
, int w
, int h
,
2916 HWND parent
, HMENU menu
, HINSTANCE inst
, LPVOID param
)
2918 printf("CreateWindowEx() called\n");
2919 dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2920 exstyle
, classname
, classname
, winname
, winname
, style
, x
, y
, w
, h
,
2921 parent
, menu
, inst
, param
);
2922 printf("CreateWindowEx() called okey\n");
2926 static int WINAPI
expwaveOutGetNumDevs(void)
2928 dbgprintf("waveOutGetNumDevs() => 0\n");
2934 * Returns the number of milliseconds, modulo 2^32, since the start
2935 * of the wineserver.
2937 static int WINAPI
expGetTickCount(void)
2939 static int tcstart
= 0;
2942 gettimeofday( &t
, NULL
);
2943 tc
= ((t
.tv_sec
* 1000) + (t
.tv_usec
/ 1000)) - tcstart
;
2949 dbgprintf("GetTickCount() => %d\n", tc
);
2953 static int WINAPI
expCreateFontA(void)
2955 dbgprintf("CreateFontA() => 0x0\n");
2959 /* tried to get pvmjpg work in a different way - no success */
2960 static int WINAPI
expDrawTextA(int hDC
, char* lpString
, int nCount
,
2961 LPRECT lpRect
, unsigned int uFormat
)
2963 dbgprintf("expDrawTextA(%p,...) => 8\n", hDC
);
2967 static int WINAPI
expGetPrivateProfileIntA(const char* appname
,
2968 const char* keyname
,
2970 const char* filename
)
2978 if(!(appname
&& keyname
&& filename
) )
2980 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, default_value
);
2981 return default_value
;
2983 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2984 strcpy(fullname
, "Software\\IniFileMapping\\");
2985 strcat(fullname
, appname
);
2986 strcat(fullname
, "\\");
2987 strcat(fullname
, keyname
);
2988 strcat(fullname
, "\\");
2989 strcat(fullname
, filename
);
2990 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)buffer
, &size
);
2991 if((size
>=0)&&(size
<256))
2993 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2996 result
=default_value
;
2998 result
=atoi(buffer
);
2999 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, result
);
3002 static int WINAPI
expGetProfileIntA(const char* appname
,
3003 const char* keyname
,
3006 dbgprintf("GetProfileIntA -> ");
3007 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, "default");
3010 static int WINAPI
expGetPrivateProfileStringA(const char* appname
,
3011 const char* keyname
,
3012 const char* def_val
,
3013 char* dest
, unsigned int len
,
3014 const char* filename
)
3019 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname
, keyname
, def_val
, dest
, len
, filename
);
3020 if(!(appname
&& keyname
&& filename
) ) return 0;
3021 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
3022 strcpy(fullname
, "Software\\IniFileMapping\\");
3023 strcat(fullname
, appname
);
3024 strcat(fullname
, "\\");
3025 strcat(fullname
, keyname
);
3026 strcat(fullname
, "\\");
3027 strcat(fullname
, filename
);
3029 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)dest
, &size
);
3033 strncpy(dest
, def_val
, size
);
3034 if (strlen(def_val
)< size
) size
= strlen(def_val
);
3036 dbgprintf(" => %d ( '%s' )\n", size
, dest
);
3039 static int WINAPI
expWritePrivateProfileStringA(const char* appname
,
3040 const char* keyname
,
3042 const char* filename
)
3045 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname
, keyname
, string
, filename
);
3046 if(!(appname
&& keyname
&& filename
) )
3048 dbgprintf(" => -1\n");
3051 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
3052 strcpy(fullname
, "Software\\IniFileMapping\\");
3053 strcat(fullname
, appname
);
3054 strcat(fullname
, "\\");
3055 strcat(fullname
, keyname
);
3056 strcat(fullname
, "\\");
3057 strcat(fullname
, filename
);
3058 RegSetValueExA(HKEY_LOCAL_MACHINE
, fullname
, 0, REG_SZ
, (int*)string
, strlen(string
));
3059 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
3060 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
3062 dbgprintf(" => 0\n");
3066 unsigned int GetPrivateProfileIntA_(const char* appname
, const char* keyname
, INT default_value
, const char* filename
)
3068 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, filename
);
3070 int GetPrivateProfileStringA_(const char* appname
, const char* keyname
,
3071 const char* def_val
, char* dest
, unsigned int len
, const char* filename
)
3073 return expGetPrivateProfileStringA(appname
, keyname
, def_val
, dest
, len
, filename
);
3075 int WritePrivateProfileStringA_(const char* appname
, const char* keyname
,
3076 const char* string
, const char* filename
)
3078 return expWritePrivateProfileStringA(appname
, keyname
, string
, filename
);
3083 static int WINAPI
expDefDriverProc(int private, int id
, int msg
, int arg1
, int arg2
)
3085 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", private, id
, msg
, arg1
, arg2
);
3089 static int WINAPI
expSizeofResource(int v1
, int v2
)
3091 int result
=SizeofResource(v1
, v2
);
3092 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1
, v2
, result
);
3096 static int WINAPI
expGetLastError(void)
3098 int result
=GetLastError();
3099 dbgprintf("GetLastError() => 0x%x\n", result
);
3103 static void WINAPI
expSetLastError(int error
)
3105 dbgprintf("SetLastError(0x%x)\n", error
);
3106 SetLastError(error
);
3109 static int WINAPI
expStringFromGUID2(GUID
* guid
, char* str
, int cbMax
)
3111 int result
=snprintf(str
, cbMax
, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
3112 guid
->f1
, guid
->f2
, guid
->f3
,
3113 (unsigned char)guid
->f4
[0], (unsigned char)guid
->f4
[1],
3114 (unsigned char)guid
->f4
[2], (unsigned char)guid
->f4
[3],
3115 (unsigned char)guid
->f4
[4], (unsigned char)guid
->f4
[5],
3116 (unsigned char)guid
->f4
[6], (unsigned char)guid
->f4
[7]);
3117 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid
, str
, str
, cbMax
, result
);
3122 static int WINAPI
expGetFileVersionInfoSizeA(const char* name
, int* lpHandle
)
3124 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name
, name
, lpHandle
);
3128 static int WINAPI
expIsBadStringPtrW(const short* string
, int nchars
)
3131 if(string
==0)result
=1; else result
=0;
3132 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string
, nchars
, result
);
3133 if(string
)wch_print(string
);
3136 static int WINAPI
expIsBadStringPtrA(const char* string
, int nchars
)
3138 return expIsBadStringPtrW((const short*)string
, nchars
);
3140 static long WINAPI
expInterlockedExchangeAdd( long* dest
, long incr
)
3145 "lock; xaddl %0,(%1)"
3147 : "r" (dest
), "0" (incr
)
3153 static long WINAPI
expInterlockedCompareExchange( unsigned long* dest
, unsigned long exchange
, unsigned long comperand
)
3155 unsigned long retval
= *dest
;
3156 if(*dest
== comperand
)
3161 static long WINAPI
expInterlockedIncrement( long* dest
)
3163 long result
=expInterlockedExchangeAdd( dest
, 1 ) + 1;
3164 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
3167 static long WINAPI
expInterlockedDecrement( long* dest
)
3169 long result
=expInterlockedExchangeAdd( dest
, -1 ) - 1;
3170 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
3174 static void WINAPI
expOutputDebugStringA( const char* string
)
3176 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string
);
3177 fprintf(stderr
, "DEBUG: %s\n", string
);
3180 static int WINAPI
expGetDC(int hwnd
)
3182 dbgprintf("GetDC(0x%x) => 1\n", hwnd
);
3186 static int WINAPI
expReleaseDC(int hwnd
, int hdc
)
3188 dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd
, hdc
);
3192 static int WINAPI
expGetDesktopWindow(void)
3194 dbgprintf("GetDesktopWindow() => 0\n");
3198 static int cursor
[100];
3200 static int WINAPI
expLoadCursorA(int handle
,LPCSTR name
)
3202 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle
, name
, (int)&cursor
[0]);
3203 return (int)&cursor
[0];
3205 static int WINAPI
expSetCursor(void *cursor
)
3207 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor
, cursor
);
3210 static int WINAPI
expGetCursorPos(void *cursor
)
3212 dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor
, cursor
);
3215 #ifdef CONFIG_QTX_CODECS
3216 static int show_cursor
= 0;
3217 static int WINAPI
expShowCursor(int show
)
3219 dbgprintf("ShowCursor(%d) => %d\n", show
, show
);
3227 static int WINAPI
expRegisterWindowMessageA(char *message
)
3229 dbgprintf("RegisterWindowMessageA(%s)\n", message
);
3232 static int WINAPI
expGetProcessVersion(int pid
)
3234 dbgprintf("GetProcessVersion(%d)\n", pid
);
3237 static int WINAPI
expGetCurrentThread(void)
3240 dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
3243 static int WINAPI
expGetOEMCP(void)
3245 dbgprintf("GetOEMCP()\n");
3248 static int WINAPI
expGetCPInfo(int cp
,void *info
)
3250 dbgprintf("GetCPInfo()\n");
3253 #ifdef CONFIG_QTX_CODECS
3254 #define SM_CXSCREEN 0
3255 #define SM_CYSCREEN 1
3256 #define SM_XVIRTUALSCREEN 76
3257 #define SM_YVIRTUALSCREEN 77
3258 #define SM_CXVIRTUALSCREEN 78
3259 #define SM_CYVIRTUALSCREEN 79
3260 #define SM_CMONITORS 80
3262 static int WINAPI
expGetSystemMetrics(int index
)
3264 dbgprintf("GetSystemMetrics(%d)\n", index
);
3265 #ifdef CONFIG_QTX_CODECS
3268 case SM_XVIRTUALSCREEN
:
3269 case SM_YVIRTUALSCREEN
:
3272 case SM_CXVIRTUALSCREEN
:
3273 return PSEUDO_SCREEN_WIDTH
;
3275 case SM_CYVIRTUALSCREEN
:
3276 return PSEUDO_SCREEN_HEIGHT
;
3283 static int WINAPI
expGetSysColor(int index
)
3285 dbgprintf("GetSysColor(%d) => 1\n", index
);
3288 static int WINAPI
expGetSysColorBrush(int index
)
3290 dbgprintf("GetSysColorBrush(%d)\n", index
);
3296 static int WINAPI
expGetSystemPaletteEntries(int hdc
, int iStartIndex
, int nEntries
, void* lppe
)
3298 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3299 hdc
, iStartIndex
, nEntries
, lppe
);
3304 typedef struct TIME_ZONE_INFORMATION {
3306 char StandardName[32];
3307 SYSTEMTIME StandardDate;
3309 char DaylightName[32];
3310 SYSTEMTIME DaylightDate;
3312 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3315 static int WINAPI
expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation
)
3317 const short name
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3318 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3319 const short pname
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3320 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3321 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3322 memset(lpTimeZoneInformation
, 0, sizeof(TIME_ZONE_INFORMATION
));
3323 lpTimeZoneInformation
->Bias
=360;//GMT-6
3324 memcpy(lpTimeZoneInformation
->StandardName
, name
, sizeof(name
));
3325 lpTimeZoneInformation
->StandardDate
.wMonth
=10;
3326 lpTimeZoneInformation
->StandardDate
.wDay
=5;
3327 lpTimeZoneInformation
->StandardDate
.wHour
=2;
3328 lpTimeZoneInformation
->StandardBias
=0;
3329 memcpy(lpTimeZoneInformation
->DaylightName
, pname
, sizeof(pname
));
3330 lpTimeZoneInformation
->DaylightDate
.wMonth
=4;
3331 lpTimeZoneInformation
->DaylightDate
.wDay
=1;
3332 lpTimeZoneInformation
->DaylightDate
.wHour
=2;
3333 lpTimeZoneInformation
->DaylightBias
=-60;
3334 return TIME_ZONE_ID_STANDARD
;
3337 static void WINAPI
expGetLocalTime(SYSTEMTIME
* systime
)
3340 struct tm
*local_tm
;
3343 dbgprintf("GetLocalTime(0x%x)\n");
3344 gettimeofday(&tv
, NULL
);
3345 local_time
=tv
.tv_sec
;
3346 local_tm
=localtime(&local_time
);
3348 systime
->wYear
= local_tm
->tm_year
+ 1900;
3349 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3350 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3351 systime
->wDay
= local_tm
->tm_mday
;
3352 systime
->wHour
= local_tm
->tm_hour
;
3353 systime
->wMinute
= local_tm
->tm_min
;
3354 systime
->wSecond
= local_tm
->tm_sec
;
3355 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3356 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3357 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3358 " Milliseconds: %d\n",
3359 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3360 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3363 static int WINAPI
expGetSystemTime(SYSTEMTIME
* systime
)
3366 struct tm
*local_tm
;
3369 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3370 gettimeofday(&tv
, NULL
);
3371 local_time
=tv
.tv_sec
;
3372 local_tm
=gmtime(&local_time
);
3374 systime
->wYear
= local_tm
->tm_year
+ 1900;
3375 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3376 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3377 systime
->wDay
= local_tm
->tm_mday
;
3378 systime
->wHour
= local_tm
->tm_hour
;
3379 systime
->wMinute
= local_tm
->tm_min
;
3380 systime
->wSecond
= local_tm
->tm_sec
;
3381 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3382 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3383 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3384 " Milliseconds: %d\n",
3385 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3386 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3390 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3391 static void WINAPI
expGetSystemTimeAsFileTime(FILETIME
* systime
)
3394 unsigned long long secs
;
3396 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3397 gettimeofday(&tv
, NULL
);
3398 secs
= (tv
.tv_sec
+ SECS_1601_TO_1970
) * 10000000;
3399 secs
+= tv
.tv_usec
* 10;
3400 systime
->dwLowDateTime
= secs
& 0xffffffff;
3401 systime
->dwHighDateTime
= (secs
>> 32);
3404 static int WINAPI
expGetEnvironmentVariableA(const char* name
, char* field
, int size
)
3407 // printf("%s %x %x\n", name, field, size);
3408 if(field
)field
[0]=0;
3411 if (p) strncpy(field,p,size);
3413 if (strcmp(name
,"__MSVCRT_HEAP_SELECT")==0)
3414 strcpy(field
,"__GLOBAL_HEAP_SELECTED,1");
3415 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name
, name
, field
, size
, strlen(field
));
3416 return strlen(field
);
3419 static int WINAPI
expSetEnvironmentVariableA(const char *name
, const char *value
)
3421 dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name
, value
);
3425 static void* WINAPI
expCoTaskMemAlloc(ULONG cb
)
3427 return my_mreq(cb
, 0);
3429 static void WINAPI
expCoTaskMemFree(void* cb
)
3437 void* CoTaskMemAlloc(unsigned long cb
)
3439 return expCoTaskMemAlloc(cb
);
3441 void CoTaskMemFree(void* cb
)
3443 expCoTaskMemFree(cb
);
3446 struct COM_OBJECT_INFO
3449 long (*GetClassObject
) (GUID
* clsid
, const GUID
* iid
, void** ppv
);
3452 static struct COM_OBJECT_INFO
* com_object_table
=0;
3453 static int com_object_size
=0;
3454 int RegisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3458 com_object_table
=realloc(com_object_table
, sizeof(struct COM_OBJECT_INFO
)*(++com_object_size
));
3459 com_object_table
[com_object_size
-1].clsid
=*clsid
;
3460 com_object_table
[com_object_size
-1].GetClassObject
=gcs
;
3464 int UnregisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3471 if (com_object_table
== 0)
3472 printf("Warning: UnregisterComClass() called without any registered class\n");
3473 while (i
< com_object_size
)
3477 memcpy(&com_object_table
[i
- 1].clsid
,
3478 &com_object_table
[i
].clsid
, sizeof(GUID
));
3479 com_object_table
[i
- 1].GetClassObject
=
3480 com_object_table
[i
].GetClassObject
;
3482 else if (memcmp(&com_object_table
[i
].clsid
, clsid
, sizeof(GUID
)) == 0
3483 && com_object_table
[i
].GetClassObject
== gcs
)
3491 if (--com_object_size
== 0)
3493 free(com_object_table
);
3494 com_object_table
= 0;
3501 const GUID IID_IUnknown
=
3503 0x00000000, 0x0000, 0x0000,
3504 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3506 const GUID IID_IClassFactory
=
3508 0x00000001, 0x0000, 0x0000,
3509 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3512 static long WINAPI
expCoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3513 long dwClsContext
, const GUID
* riid
, void** ppv
)
3516 struct COM_OBJECT_INFO
* ci
=0;
3517 for(i
=0; i
<com_object_size
; i
++)
3518 if(!memcmp(rclsid
, &com_object_table
[i
].clsid
, sizeof(GUID
)))
3519 ci
=&com_object_table
[i
];
3520 if(!ci
)return REGDB_E_CLASSNOTREG
;
3521 // in 'real' world we should mess with IClassFactory here
3522 i
=ci
->GetClassObject(rclsid
, riid
, ppv
);
3526 long CoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3527 long dwClsContext
, const GUID
* riid
, void** ppv
)
3529 return expCoCreateInstance(rclsid
, pUnkOuter
, dwClsContext
, riid
, ppv
);
3532 static int WINAPI
expIsRectEmpty(CONST RECT
*lprc
)
3539 w
= lprc
->right
- lprc
->left
;
3540 h
= lprc
->bottom
- lprc
->top
;
3541 if (w
<= 0 || h
<= 0)
3547 dbgprintf("IsRectEmpty(%p) => %s\n", lprc
, (r
) ? "TRUE" : "FALSE");
3548 //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3549 // return 0; // wmv9?
3553 static int _adjust_fdiv
=0; //what's this? - used to adjust division
3554 static int _winver
= 0x510; // windows version
3559 static unsigned int WINAPI
expGetTempPathA(unsigned int len
, char* path
)
3561 dbgprintf("GetTempPathA(%d, 0x%x)", len
, path
);
3564 dbgprintf(" => 0\n");
3567 strcpy(path
, "/tmp");
3568 dbgprintf(" => 5 ( '/tmp' )\n");
3575 DWORD dwFileAttributes;
3576 FILETIME ftCreationTime;
3577 FILETIME ftLastAccessTime;
3578 FILETIME ftLastWriteTime;
3579 DWORD nFileSizeHigh;
3583 CHAR cFileName[260];
3584 CHAR cAlternateFileName[14];
3585 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3588 static DIR* qtx_dir
=NULL
;
3590 static WIN_BOOL WINAPI
expFindNextFileA(HANDLE h
,LPWIN32_FIND_DATAA lpfd
)
3592 #ifdef CONFIG_QTX_CODECS
3593 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h
, lpfd
);
3594 if(h
==FILE_HANDLE_quicktimeqtx
){
3596 if(!qtx_dir
) return 0;
3597 while((d
=readdir(qtx_dir
))){
3598 char* x
=strrchr(d
->d_name
,'.');
3600 if(strcmp(x
,".qtx")) continue;
3601 strcpy(lpfd
->cFileName
,d
->d_name
);
3602 // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3603 strcpy(lpfd
->cAlternateFileName
,"foobar.qtx");
3604 dbgprintf("### FindNext: %s\n",lpfd
->cFileName
);
3607 closedir(qtx_dir
); qtx_dir
=NULL
;
3614 static HANDLE WINAPI
expFindFirstFileA(LPCSTR s
, LPWIN32_FIND_DATAA lpfd
)
3616 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s
, s
, lpfd
);
3617 // printf("\n### FindFirstFileA('%s')...\n",s);
3618 #ifdef CONFIG_QTX_CODECS
3619 if(strstr(s
, "quicktime\\*.QTX")){
3620 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s
, s
, lpfd
);
3621 dbgprintf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",def_path
);
3622 qtx_dir
=opendir(def_path
);
3623 if(!qtx_dir
) return (HANDLE
)-1;
3624 memset(lpfd
,0,sizeof(*lpfd
));
3625 if(expFindNextFileA(FILE_HANDLE_quicktimeqtx
,lpfd
))
3626 return FILE_HANDLE_quicktimeqtx
;
3627 printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",def_path
);
3631 if(strstr(s
, "QuickTime.qts")){
3632 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s
, s
, lpfd
);
3633 // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3634 // return (HANDLE)-1;
3635 strcpy(lpfd
->cFileName
, "QuickTime.qts");
3636 strcpy(lpfd
->cAlternateFileName
, "QuickT~1.qts");
3637 return FILE_HANDLE_quicktimeqts
;
3641 if(strstr(s
, "*.vwp")){
3642 // hack for VoxWare codec plugins:
3643 strcpy(lpfd
->cFileName
, "msms001.vwp");
3644 strcpy(lpfd
->cAlternateFileName
, "msms001.vwp");
3647 // return 'file not found'
3651 static WIN_BOOL WINAPI
expFindClose(HANDLE h
)
3653 dbgprintf("FindClose(0x%x) => 0\n", h
);
3654 #ifdef CONFIG_QTX_CODECS
3655 // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3656 // closedir(qtx_dir);
3662 static UINT WINAPI
expSetErrorMode(UINT i
)
3664 dbgprintf("SetErrorMode(%d) => 0\n", i
);
3667 static UINT WINAPI
expGetWindowsDirectoryA(LPSTR s
,UINT c
)
3669 char windir
[]="c:\\windows";
3671 strncpy(s
, windir
, c
);
3672 result
=1+((c
<strlen(windir
))?c
:strlen(windir
));
3673 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3676 #ifdef CONFIG_QTX_CODECS
3677 static UINT WINAPI
expGetCurrentDirectoryA(UINT c
, LPSTR s
)
3679 char curdir
[]="c:\\";
3681 strncpy(s
, curdir
, c
);
3682 result
=1+((c
<strlen(curdir
))?c
:strlen(curdir
));
3683 dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3687 static int WINAPI
expSetCurrentDirectoryA(const char *pathname
)
3689 dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname
, pathname
);
3691 if (strrchr(pathname
, '\\'))
3692 chdir(strcat(strrchr(pathname
, '\\')+1, '/'));
3699 static int WINAPI
expCreateDirectoryA(const char *pathname
, void *sa
)
3701 dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3702 pathname
, pathname
, sa
);
3704 p
= strrchr(pathname
, '\\')+1;
3705 strcpy(&buf
[0], p
); /* should be strncpy */
3712 if (strrchr(pathname
, '\\'))
3713 mkdir(strcat(strrchr(pathname
, '\\')+1, '/'), 666);
3715 mkdir(pathname
, 666);
3722 static WIN_BOOL WINAPI
expDeleteFileA(LPCSTR s
)
3724 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s
, s
);
3727 static WIN_BOOL WINAPI
expFileTimeToLocalFileTime(const FILETIME
* cpf
, LPFILETIME pf
)
3729 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf
, pf
);
3733 static UINT WINAPI
expGetTempFileNameA(LPCSTR cs1
,LPCSTR cs2
,UINT i
,LPSTR ps
)
3735 char mask
[16]="/tmp/AP_XXXXXX";
3737 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1
, cs1
, cs2
, cs2
, i
, ps
);
3740 dbgprintf(" => -1\n");
3743 result
=mkstemp(mask
);
3744 sprintf(ps
, "AP%d", result
);
3745 dbgprintf(" => %d\n", strlen(ps
));
3749 // This func might need proper implementation if we want AngelPotion codec.
3750 // They try to open APmpeg4v1.apl with it.
3751 // DLL will close opened file with CloseHandle().
3753 static HANDLE WINAPI
expCreateFileA(LPCSTR cs1
,DWORD i1
,DWORD i2
,
3754 LPSECURITY_ATTRIBUTES p1
, DWORD i3
,DWORD i4
,HANDLE i5
)
3756 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1
, cs1
, i1
,
3757 i2
, p1
, i3
, i4
, i5
);
3758 if((!cs1
) || (strlen(cs1
)<2))return -1;
3760 #ifdef CONFIG_QTX_CODECS
3761 if(strstr(cs1
, "QuickTime.qts"))
3764 char* tmp
=malloc(strlen(def_path
)+50);
3765 strcpy(tmp
, def_path
);
3767 strcat(tmp
, "QuickTime.qts");
3768 result
=open(tmp
, O_RDONLY
);
3772 if(strstr(cs1
, ".qtx"))
3775 char* tmp
=malloc(strlen(def_path
)+250);
3776 char* x
=strrchr(cs1
,'\\');
3777 sprintf(tmp
,"%s/%s",def_path
,x
?(x
+1):cs1
);
3778 // printf("### Open: %s -> %s\n",cs1,tmp);
3779 result
=open(tmp
, O_RDONLY
);
3785 if(strncmp(cs1
, "AP", 2) == 0)
3788 char* tmp
=malloc(strlen(def_path
)+50);
3789 strcpy(tmp
, def_path
);
3791 strcat(tmp
, "APmpg4v1.apl");
3792 result
=open(tmp
, O_RDONLY
);
3796 if (strstr(cs1
, "vp3") || strstr(cs1
, ".fpf"))
3800 char* tmp
=malloc(20 + strlen(cs1
));
3801 strcpy(tmp
, "/tmp/");
3806 if (tmp
[r
] == ':' || tmp
[r
] == '\\')
3810 if (GENERIC_READ
& i1
)
3812 else if (GENERIC_WRITE
& i1
)
3814 flg
|= O_WRONLY
| O_CREAT
;
3815 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp
, r
, flg
);
3817 r
=open(tmp
, flg
, S_IRWXU
);
3822 // Needed by wnvplay1.dll
3823 if (strstr(cs1
, "WINNOV.bmp"))
3826 r
=open("/dev/null", O_RDONLY
);
3831 /* we need this for some virtualdub filters */
3835 if (GENERIC_READ
& i1
)
3837 else if (GENERIC_WRITE
& i1
)
3840 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1
, r
, flg
);
3849 static UINT WINAPI
expGetSystemDirectoryA(
3850 char* lpBuffer
, // address of buffer for system directory
3851 UINT uSize
// size of directory buffer
3853 dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer
,uSize
);
3854 if(!lpBuffer
) strcpy(lpBuffer
,".");
3858 static char sysdir[]=".";
3859 static LPCSTR WINAPI expGetSystemDirectoryA(void)
3861 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3865 static DWORD WINAPI expGetFullPathNameA
3868 DWORD nBufferLength
,
3872 if(!lpFileName
) return 0;
3873 dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName
,nBufferLength
,
3874 lpBuffer
, lpFilePart
);
3876 #ifdef CONFIG_QTX_CODECS
3877 strcpy(lpFilePart
, "Quick123.qts");
3879 strcpy(lpFilePart
, lpFileName
);
3882 if (strrchr(lpFileName
, '\\'))
3883 lpFilePart
= strrchr(lpFileName
, '\\');
3885 lpFilePart
= (LPTSTR
)lpFileName
;
3887 strcpy(lpBuffer
, lpFileName
);
3888 // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3889 return strlen(lpBuffer
);
3892 static DWORD WINAPI expGetShortPathNameA
3898 if(!longpath
) return 0;
3899 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath
,shortpath
,shortlen
);
3900 strcpy(shortpath
,longpath
);
3901 return strlen(shortpath
);
3904 static WIN_BOOL WINAPI
expReadFile(HANDLE h
,LPVOID pv
,DWORD size
,LPDWORD rd
,LPOVERLAPPED unused
)
3907 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, rd
);
3908 result
=read(h
, pv
, size
);
3910 if(!result
)return 0;
3914 static WIN_BOOL WINAPI
expWriteFile(HANDLE h
,LPCVOID pv
,DWORD size
,LPDWORD wr
,LPOVERLAPPED unused
)
3917 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, wr
);
3919 result
=write(h
, pv
, size
);
3921 if(!result
)return 0;
3924 static DWORD WINAPI
expSetFilePointer(HANDLE h
, LONG val
, LPLONG ext
, DWORD whence
)
3927 dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h
, val
, ext
, ext
? *ext
: NULL
, whence
);
3928 //why would DLL want temporary file with >2Gb size?
3940 #ifdef CONFIG_QTX_CODECS
3941 if (val
== 0 && ext
!= 0)
3944 return lseek(h
, val
, wh
);
3947 static HDRVR WINAPI
expOpenDriverA(LPCSTR szDriverName
, LPCSTR szSectionName
,
3950 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3953 static HDRVR WINAPI
expOpenDriver(LPCSTR szDriverName
, LPCSTR szSectionName
,
3956 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3961 static WIN_BOOL WINAPI
expGetProcessAffinityMask(HANDLE hProcess
,
3962 LPDWORD lpProcessAffinityMask
,
3963 LPDWORD lpSystemAffinityMask
)
3965 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3966 hProcess
, lpProcessAffinityMask
, lpSystemAffinityMask
);
3967 if(lpProcessAffinityMask
)*lpProcessAffinityMask
=1;
3968 if(lpSystemAffinityMask
)*lpSystemAffinityMask
=1;
3972 // Fake implementation: does nothing, but does it right :)
3973 static WIN_BOOL WINAPI
expSetProcessAffinityMask(HANDLE hProcess
,
3974 LPDWORD dwProcessAffinityMask
)
3976 dbgprintf("SetProcessAffinityMask(0x%x, 0x%x) => 1\n",
3977 hProcess
, dwProcessAffinityMask
);
3982 static int WINAPI
expMulDiv(int nNumber
, int nNumerator
, int nDenominator
)
3984 static const long long max_int
=0x7FFFFFFFLL
;
3985 static const long long min_int
=-0x80000000LL
;
3986 long long tmp
=(long long)nNumber
*(long long)nNumerator
;
3987 dbgprintf("expMulDiv %d * %d / %d\n", nNumber
, nNumerator
, nDenominator
);
3988 if(!nDenominator
)return 1;
3990 if(tmp
<min_int
) return 1;
3991 if(tmp
>max_int
) return 1;
3995 static LONG WINAPI
explstrcmpiA(const char* str1
, const char* str2
)
3997 LONG result
=strcasecmp(str1
, str2
);
3998 dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4002 static LONG WINAPI
explstrlenA(const char* str1
)
4004 LONG result
=strlen(str1
);
4005 dbgprintf("strlen(0x%x='%.50s') => %d\n", str1
, str1
, result
);
4009 static LONG WINAPI
explstrcpyA(char* str1
, const char* str2
)
4011 int result
= (int) strcpy(str1
, str2
);
4012 dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1
, str2
, str2
, result
);
4015 static LONG WINAPI
explstrcpynA(char* str1
, const char* str2
,int len
)
4018 if (strlen(str2
)>len
)
4019 result
= (int) strncpy(str1
, str2
,len
);
4021 result
= (int) strcpy(str1
,str2
);
4022 dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1
, str2
, str2
,len
, strlen(str2
),result
);
4025 static LONG WINAPI
explstrcatA(char* str1
, const char* str2
)
4027 int result
= (int) strcat(str1
, str2
);
4028 dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1
, str2
, str2
, result
);
4033 static LONG WINAPI
expInterlockedExchange(long *dest
, long l
)
4035 long retval
= *dest
;
4040 static void WINAPI
expInitCommonControls(void)
4042 dbgprintf("InitCommonControls called!\n");
4046 #ifdef CONFIG_QTX_CODECS
4047 /* needed by QuickTime.qts */
4048 static HWND WINAPI
expCreateUpDownControl (DWORD style
, INT x
, INT y
, INT cx
, INT cy
,
4049 HWND parent
, INT id
, HINSTANCE inst
,
4050 HWND buddy
, INT maxVal
, INT minVal
, INT curVal
)
4052 dbgprintf("CreateUpDownControl(...)\n");
4057 /* alex: implement this call! needed for 3ivx */
4058 static HRESULT WINAPI
expCoCreateFreeThreadedMarshaler(void *pUnkOuter
, void **ppUnkInner
)
4060 dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
4061 pUnkOuter
, ppUnkInner
);
4063 return ERROR_CALL_NOT_IMPLEMENTED
;
4067 static int WINAPI
expDuplicateHandle(HANDLE hSourceProcessHandle
, // handle to source process
4068 HANDLE hSourceHandle
, // handle to duplicate
4069 HANDLE hTargetProcessHandle
, // handle to target process
4070 HANDLE
* lpTargetHandle
, // duplicate handle
4071 DWORD dwDesiredAccess
, // requested access
4072 int bInheritHandle
, // handle inheritance option
4073 DWORD dwOptions
// optional actions
4076 dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
4077 hSourceProcessHandle
, hSourceHandle
, hTargetProcessHandle
,
4078 lpTargetHandle
, dwDesiredAccess
, bInheritHandle
, dwOptions
);
4079 *lpTargetHandle
= hSourceHandle
;
4083 static HRESULT WINAPI
expCoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
4085 dbgprintf("CoInitializeEx(%p, %d) called\n", lpReserved
, dwCoInit
);
4089 // required by PIM1 codec (used by win98 PCTV Studio capture sw)
4090 static HRESULT WINAPI
expCoInitialize(
4091 LPVOID lpReserved
/* [in] pointer to win32 malloc interface
4092 (obsolete, should be NULL) */
4096 * Just delegate to the newer method.
4098 return expCoInitializeEx(lpReserved
, COINIT_APARTMENTTHREADED
);
4101 static void WINAPI
expCoUninitialize(void)
4103 dbgprintf("CoUninitialize() called\n");
4106 /* allow static linking */
4107 HRESULT WINAPI
CoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
4109 return expCoInitializeEx(lpReserved
, dwCoInit
);
4111 HRESULT WINAPI
CoInitialize(LPVOID lpReserved
)
4113 return expCoInitialize(lpReserved
);
4115 void WINAPI
CoUninitialize(void)
4117 expCoUninitialize();
4120 static DWORD WINAPI expSetThreadAffinityMask
4123 DWORD dwThreadAffinityMask
4129 * no WINAPI functions - CDECL
4131 static void* expmalloc(int size
)
4134 // return malloc(size);
4135 void* result
=my_mreq(size
,0);
4136 dbgprintf("malloc(0x%x) => 0x%x\n", size
,result
);
4138 printf("WARNING: malloc() failed\n");
4141 static void expfree(void* mem
)
4143 // return free(mem);
4144 dbgprintf("free(%p)\n", mem
);
4147 /* needed by atrac3.acm */
4148 static void *expcalloc(int num
, int size
)
4150 void* result
=my_mreq(num
*size
,1);
4151 dbgprintf("calloc(%d,%d) => %p\n", num
,size
,result
);
4153 printf("WARNING: calloc() failed\n");
4156 static void* expnew(int size
)
4158 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
4159 // printf("%08x %08x %08x %08x\n",
4160 // size, *(1+(int*)&size),
4161 // *(2+(int*)&size),*(3+(int*)&size));
4165 result
=my_mreq(size
,0);
4166 dbgprintf("new(%d) => %p\n", size
, result
);
4168 printf("WARNING: new() failed\n");
4172 static int expdelete(void* memory
)
4174 dbgprintf("delete(%p)\n", memory
);
4180 * local definition - we need only the last two members at this point
4181 * otherwice we would have to introduce here GUIDs and some more types..
4183 typedef struct __attribute__((__packed__
))
4186 unsigned long cbFormat
; //0x40
4187 char* pbFormat
; //0x44
4189 static HRESULT WINAPI
expMoCopyMediaType(MY_MEDIA_TYPE
* dest
, const MY_MEDIA_TYPE
* src
)
4193 memcpy(dest
, src
, sizeof(MY_MEDIA_TYPE
));
4196 dest
->pbFormat
= (char*) my_mreq(dest
->cbFormat
, 0);
4197 if (!dest
->pbFormat
)
4198 return E_OUTOFMEMORY
;
4199 memcpy(dest
->pbFormat
, src
->pbFormat
, dest
->cbFormat
);
4203 static HRESULT WINAPI
expMoInitMediaType(MY_MEDIA_TYPE
* dest
, DWORD cbFormat
)
4207 memset(dest
, 0, sizeof(MY_MEDIA_TYPE
));
4210 dest
->pbFormat
= (char*) my_mreq(cbFormat
, 0);
4211 if (!dest
->pbFormat
)
4212 return E_OUTOFMEMORY
;
4216 static HRESULT WINAPI
expMoCreateMediaType(MY_MEDIA_TYPE
** dest
, DWORD cbFormat
)
4220 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
4221 return expMoInitMediaType(*dest
, cbFormat
);
4223 static HRESULT WINAPI
expMoDuplicateMediaType(MY_MEDIA_TYPE
** dest
, const void* src
)
4227 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
4228 return expMoCopyMediaType(*dest
, src
);
4230 static HRESULT WINAPI
expMoFreeMediaType(MY_MEDIA_TYPE
* dest
)
4236 my_release(dest
->pbFormat
);
4242 static HRESULT WINAPI
expMoDeleteMediaType(MY_MEDIA_TYPE
* dest
)
4246 expMoFreeMediaType(dest
);
4251 static int exp_snprintf( char *str
, int size
, const char *format
, ... )
4255 va_start(va
, format
);
4256 x
=snprintf(str
,size
,format
,va
);
4257 dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str
,size
,format
,x
);
4263 static int exp_initterm(int v1
, int v2
)
4265 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1
, v2
);
4269 /* merged from wine - 2002.04.21 */
4270 typedef void (*INITTERMFUNC
)();
4271 static int exp_initterm(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
4273 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start
, end
, *start
);
4278 //printf("call _initfunc: from: %p %d\n", *start);
4279 // ok this trick with push/pop is necessary as otherwice
4280 // edi/esi registers are being trashed
4299 //printf("done %p %d:%d\n", end);
4307 /* Fake _initterm_e from msvcr80.dll, needed by sirenacm.dll
4308 * NOTE: If I make this an alias for _initterm, then sirenacm.dll tries to call
4309 other uninmplemented functions; keep this in mind if some future codec needs
4310 a real implementation of this function */
4311 static int exp_initterm_e(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
4313 dbgprintf("_initterm_e(0x%x, 0x%x)\n", start
, end
);
4317 static void* exp__dllonexit(void)
4319 // FIXME extract from WINE
4323 static int expwsprintfA(char* string
, const char* format
, ...)
4327 va_start(va
, format
);
4328 result
= vsprintf(string
, format
, va
);
4329 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string
, format
, result
);
4334 static int expsprintf(char* str
, const char* format
, ...)
4338 dbgprintf("sprintf(0x%x, %s)\n", str
, format
);
4339 va_start(args
, format
);
4340 r
= vsprintf(str
, format
, args
);
4344 static int expsscanf(const char* str
, const char* format
, ...)
4348 dbgprintf("sscanf(%s, %s)\n", str
, format
);
4349 va_start(args
, format
);
4350 r
= vsscanf(str
, format
, args
);
4354 static void* expfopen(const char* path
, const char* mode
)
4356 printf("fopen: \"%s\" mode:%s\n", path
, mode
);
4357 //return fopen(path, mode);
4358 return fdopen(0, mode
); // everything on screen
4360 static int expfprintf(void* stream
, const char* format
, ...)
4364 dbgprintf("fprintf(%p, %s, ...)\n", stream
, format
);
4365 va_start(args
, format
);
4366 r
= vfprintf((FILE*) stream
, format
, args
);
4371 static int expprintf(const char* format
, ...)
4375 dbgprintf("printf(%s, ...)\n", format
);
4376 va_start(args
, format
);
4377 r
= vprintf(format
, args
);
4382 static char* expgetenv(const char* varname
)
4384 char* v
= getenv(varname
);
4385 dbgprintf("getenv(%s) => %s\n", varname
, v
);
4389 static void* expwcscpy(WCHAR
* dst
, const WCHAR
* src
)
4392 while ((*p
++ = *src
++))
4397 static char* expstrrchr(char* string
, int value
)
4399 char* result
=strrchr(string
, value
);
4401 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4403 dbgprintf("strrchr(0x%x='%s', %d) => 0", string
, string
, value
);
4407 static char* expstrchr(char* string
, int value
)
4409 char* result
=strchr(string
, value
);
4411 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4413 dbgprintf("strchr(0x%x='%s', %d) => 0", string
, string
, value
);
4416 static int expstrlen(char* str
)
4418 int result
=strlen(str
);
4419 dbgprintf("strlen(0x%x='%s') => %d\n", str
, str
, result
);
4422 static char* expstrcpy(char* str1
, const char* str2
)
4424 char* result
= strcpy(str1
, str2
);
4425 dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1
, str2
, str2
, result
);
4428 static char* expstrncpy(char* str1
, const char* str2
, size_t count
)
4430 char* result
= strncpy(str1
, str2
, count
);
4431 dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1
, str2
, str2
, count
, result
);
4434 static int expstrcmp(const char* str1
, const char* str2
)
4436 int result
=strcmp(str1
, str2
);
4437 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4440 static int expstrncmp(const char* str1
, const char* str2
,int x
)
4442 int result
=strncmp(str1
, str2
,x
);
4443 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4446 static char* expstrcat(char* str1
, const char* str2
)
4448 char* result
= strcat(str1
, str2
);
4449 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1
, str1
, str2
, str2
, result
);
4452 static char* exp_strdup(const char* str1
)
4454 int l
= strlen(str1
);
4455 char* result
= (char*) my_mreq(l
+ 1,0);
4457 strcpy(result
, str1
);
4458 dbgprintf("_strdup(0x%x='%s') => %p\n", str1
, str1
, result
);
4461 static int expisalnum(int c
)
4463 int result
= (int) isalnum(c
);
4464 dbgprintf("isalnum(0x%x='%c' => %d\n", c
, c
, result
);
4467 static int expisspace(int c
)
4469 int result
= (int) isspace(c
);
4470 dbgprintf("isspace(0x%x='%c' => %d\n", c
, c
, result
);
4473 static int expisalpha(int c
)
4475 int result
= (int) isalpha(c
);
4476 dbgprintf("isalpha(0x%x='%c' => %d\n", c
, c
, result
);
4479 static int expisdigit(int c
)
4481 int result
= (int) isdigit(c
);
4482 dbgprintf("isdigit(0x%x='%c' => %d\n", c
, c
, result
);
4485 static void* expmemmove(void* dest
, void* src
, int n
)
4487 void* result
= memmove(dest
, src
, n
);
4488 dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4491 static int expmemcmp(void* dest
, void* src
, int n
)
4493 int result
= memcmp(dest
, src
, n
);
4494 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest
, src
, n
, result
);
4497 static void* expmemcpy(void* dest
, void* src
, int n
)
4499 void *result
= memcpy(dest
, src
, n
);
4500 dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4503 static void* expmemset(void* dest
, int c
, size_t n
)
4505 void *result
= memset(dest
, c
, n
);
4506 dbgprintf("memset(0x%x, %d, %d) => %p\n", dest
, c
, n
, result
);
4509 static time_t exptime(time_t* t
)
4511 time_t result
= time(t
);
4512 dbgprintf("time(0x%x) => %d\n", t
, result
);
4516 static int exprand(void)
4521 static void expsrand(int seed
)
4528 // preferred compilation with -O2 -ffast-math !
4530 static double explog10(double x
)
4532 /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4536 static double expcos(double x
)
4538 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4544 static void explog10(void)
4555 static void expcos(void)
4566 // this seem to be the only how to make this function working properly
4567 // ok - I've spent tremendous amount of time (many many many hours
4568 // of debuging fixing & testing - it's almost unimaginable - kabi
4570 // _ftol - operated on the float value which is already on the FPU stack
4572 static void exp_ftol(void)
4576 "sub $12, %esp \n\t"
4577 "fstcw -2(%ebp) \n\t"
4579 "movw -2(%ebp), %ax \n\t"
4580 "orb $0x0C, %ah \n\t"
4581 "movw %ax, -4(%ebp) \n\t"
4582 "fldcw -4(%ebp) \n\t"
4583 "fistpl -12(%ebp) \n\t"
4584 "fldcw -2(%ebp) \n\t"
4585 "movl -12(%ebp), %eax \n\t"
4586 //Note: gcc 3.03 does not do the following op if it
4587 // knows that ebp=esp
4588 "movl %ebp, %esp \n\t"
4592 #define FPU_DOUBLES(var1,var2) double var1,var2; \
4593 __asm__ volatile( "fstpl %0;fwait" : "=m" (var2) : ); \
4594 __asm__ volatile( "fstpl %0;fwait" : "=m" (var1) : )
4596 static double exp_CIpow(void)
4600 dbgprintf("_CIpow(%lf, %lf)\n", x
, y
);
4604 static double exppow(double x
, double y
)
4606 /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4610 static double expldexp(double x
, int expo
)
4612 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4613 return ldexp(x
, expo
);
4616 static double expfrexp(double x
, int* expo
)
4618 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4619 return frexp(x
, expo
);
4624 static int exp_stricmp(const char* s1
, const char* s2
)
4626 return strcasecmp(s1
, s2
);
4629 /* from declaration taken from Wine sources - this fountion seems to be
4630 * undocumented in any M$ doc */
4631 static int exp_setjmp3(void* jmpbuf
, int x
)
4633 //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4637 //"mov 4(%%esp), %%edx \n\t"
4638 "mov (%%esp), %%eax \n\t"
4639 "mov %%eax, (%%edx) \n\t" // store ebp
4641 //"mov %%ebp, (%%edx) \n\t"
4642 "mov %%ebx, 4(%%edx) \n\t"
4643 "mov %%edi, 8(%%edx) \n\t"
4644 "mov %%esi, 12(%%edx) \n\t"
4645 "mov %%esp, 16(%%edx) \n\t"
4647 "mov 4(%%esp), %%eax \n\t"
4648 "mov %%eax, 20(%%edx) \n\t"
4650 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4651 "movl $0, 36(%%edx) \n\t"
4653 : "d"(jmpbuf
) // input
4658 "mov %%fs:0, %%eax \n\t" // unsure
4659 "mov %%eax, 24(%%edx) \n\t"
4660 "cmp $0xffffffff, %%eax \n\t"
4662 "mov %%eax, 28(%%edx) \n\t"
4672 static DWORD WINAPI
expGetCurrentProcessId(void)
4674 dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4675 return getpid(); //(DWORD)NtCurrentTeb()->pid;
4682 } TIMECAPS
, *LPTIMECAPS
;
4684 static MMRESULT WINAPI
exptimeGetDevCaps(LPTIMECAPS lpCaps
, UINT wSize
)
4686 dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps
, wSize
);
4688 lpCaps
->wPeriodMin
= 1;
4689 lpCaps
->wPeriodMax
= 65535;
4693 static MMRESULT WINAPI
exptimeBeginPeriod(UINT wPeriod
)
4695 dbgprintf("timeBeginPeriod(%u) !\n", wPeriod
);
4697 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4701 #ifdef CONFIG_QTX_CODECS
4702 static MMRESULT WINAPI
exptimeEndPeriod(UINT wPeriod
)
4704 dbgprintf("timeEndPeriod(%u) !\n", wPeriod
);
4706 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4711 static void WINAPI
expGlobalMemoryStatus(
4712 LPMEMORYSTATUS lpmem
4714 static MEMORYSTATUS cached_memstatus
;
4715 static int cache_lastchecked
= 0;
4719 if (time(NULL
)==cache_lastchecked
) {
4720 memcpy(lpmem
,&cached_memstatus
,sizeof(MEMORYSTATUS
));
4724 f
= fopen( "/proc/meminfo", "r" );
4728 int total
, used
, free
, shared
, buffers
, cached
;
4730 lpmem
->dwLength
= sizeof(MEMORYSTATUS
);
4731 lpmem
->dwTotalPhys
= lpmem
->dwAvailPhys
= 0;
4732 lpmem
->dwTotalPageFile
= lpmem
->dwAvailPageFile
= 0;
4733 while (fgets( buffer
, sizeof(buffer
), f
))
4735 /* old style /proc/meminfo ... */
4736 if (sscanf( buffer
, "Mem: %d %d %d %d %d %d", &total
, &used
, &free
, &shared
, &buffers
, &cached
))
4738 lpmem
->dwTotalPhys
+= total
;
4739 lpmem
->dwAvailPhys
+= free
+ buffers
+ cached
;
4741 if (sscanf( buffer
, "Swap: %d %d %d", &total
, &used
, &free
))
4743 lpmem
->dwTotalPageFile
+= total
;
4744 lpmem
->dwAvailPageFile
+= free
;
4747 /* new style /proc/meminfo ... */
4748 if (sscanf(buffer
, "MemTotal: %d", &total
))
4749 lpmem
->dwTotalPhys
= total
*1024;
4750 if (sscanf(buffer
, "MemFree: %d", &free
))
4751 lpmem
->dwAvailPhys
= free
*1024;
4752 if (sscanf(buffer
, "SwapTotal: %d", &total
))
4753 lpmem
->dwTotalPageFile
= total
*1024;
4754 if (sscanf(buffer
, "SwapFree: %d", &free
))
4755 lpmem
->dwAvailPageFile
= free
*1024;
4756 if (sscanf(buffer
, "Buffers: %d", &buffers
))
4757 lpmem
->dwAvailPhys
+= buffers
*1024;
4758 if (sscanf(buffer
, "Cached: %d", &cached
))
4759 lpmem
->dwAvailPhys
+= cached
*1024;
4763 if (lpmem
->dwTotalPhys
)
4765 DWORD TotalPhysical
= lpmem
->dwTotalPhys
+lpmem
->dwTotalPageFile
;
4766 DWORD AvailPhysical
= lpmem
->dwAvailPhys
+lpmem
->dwAvailPageFile
;
4767 lpmem
->dwMemoryLoad
= (TotalPhysical
-AvailPhysical
)
4768 / (TotalPhysical
/ 100);
4772 /* FIXME: should do something for other systems */
4773 lpmem
->dwMemoryLoad
= 0;
4774 lpmem
->dwTotalPhys
= 16*1024*1024;
4775 lpmem
->dwAvailPhys
= 16*1024*1024;
4776 lpmem
->dwTotalPageFile
= 16*1024*1024;
4777 lpmem
->dwAvailPageFile
= 16*1024*1024;
4779 expGetSystemInfo(&si
);
4780 lpmem
->dwTotalVirtual
= si
.lpMaximumApplicationAddress
-si
.lpMinimumApplicationAddress
;
4781 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4782 lpmem
->dwAvailVirtual
= lpmem
->dwTotalVirtual
-64*1024;
4783 memcpy(&cached_memstatus
,lpmem
,sizeof(MEMORYSTATUS
));
4784 cache_lastchecked
= time(NULL
);
4786 /* it appears some memory display programs want to divide by these values */
4787 if(lpmem
->dwTotalPageFile
==0)
4788 lpmem
->dwTotalPageFile
++;
4790 if(lpmem
->dwAvailPageFile
==0)
4791 lpmem
->dwAvailPageFile
++;
4794 static INT WINAPI
expGetThreadPriority(HANDLE hthread
)
4796 dbgprintf("GetThreadPriority(%p)\n",hthread
);
4800 /**********************************************************************
4801 * SetThreadPriority [KERNEL32.@] Sets priority for thread.
4807 static WIN_BOOL WINAPI
expSetThreadPriority(
4808 HANDLE hthread
, /* [in] Handle to thread */
4809 INT priority
) /* [in] Thread priority level */
4811 dbgprintf("SetThreadPriority(%p,%d)\n",hthread
,priority
);
4815 static void WINAPI
expTerminateProcess( DWORD process
, DWORD status
)
4817 printf("EXIT - process %ld code %ld\n", process
, status
);
4821 static void WINAPI
expExitProcess( DWORD status
)
4823 printf("EXIT - code %ld\n",status
);
4827 static INT WINAPI
expMessageBoxA(HWND hWnd
, LPCSTR text
, LPCSTR title
, UINT type
){
4828 printf("MSGBOX '%s' '%s' (%d)\n",text
,title
,type
);
4829 #ifdef CONFIG_QTX_CODECS
4830 if (type
== MB_ICONHAND
&& !strlen(text
) && !strlen(title
))
4836 /* these are needed for mss1 */
4839 * \brief this symbol is defined within exp_EH_prolog_dummy
4840 * \param dest jump target
4842 void exp_EH_prolog(void *dest
);
4843 void exp_EH_prolog_dummy(void);
4844 //! just a dummy function that acts a container for the asm section
4845 void exp_EH_prolog_dummy(void) {
4847 // take care, this "function" may not change flags or
4848 // registers besides eax (which is also why we can't use
4849 // exp_EH_prolog_dummy directly)
4850 MANGLE(exp_EH_prolog
)": \n\t"
4853 "mov %esp, %ebp \n\t"
4854 "lea -12(%esp), %esp \n\t"
4859 #include <netinet/in.h>
4860 static WINAPI
inline unsigned long int exphtonl(unsigned long int hostlong
)
4862 // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4863 return htonl(hostlong
);
4866 static WINAPI
inline unsigned long int expntohl(unsigned long int netlong
)
4868 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4869 return ntohl(netlong
);
4872 static char* WINAPI
expSysAllocStringLen(char *pch
, unsigned cch
)
4875 dbgprintf("SysAllocStringLen('%s', %d)\n", pch
, cch
);
4876 str
= malloc(cch
* 2 + sizeof(unsigned) + 2);
4877 *(unsigned *)str
= cch
;
4878 str
+= sizeof(unsigned);
4880 memcpy(str
, pch
, cch
* 2);
4882 str
[cch
* 2 + 1] = 0;
4886 static void WINAPI
expSysFreeString(char *str
)
4889 free(str
- sizeof(unsigned));
4893 static void WINAPI
expVariantInit(void* p
)
4895 printf("InitCommonControls called!\n");
4899 static int WINAPI
expRegisterClassA(const void/*WNDCLASSA*/ *wc
)
4901 dbgprintf("RegisterClassA(%p) => random id\n", wc
);
4902 return time(NULL
); /* be precise ! */
4905 static int WINAPI
expUnregisterClassA(const char *className
, HINSTANCE hInstance
)
4907 dbgprintf("UnregisterClassA(%s, %p) => 0\n", className
, hInstance
);
4911 #ifdef CONFIG_QTX_CODECS
4912 /* should be fixed bcs it's not fully strlen equivalent */
4913 static int expSysStringByteLen(void *str
)
4915 dbgprintf("SysStringByteLen(%p) => %d\n", str
, strlen(str
));
4919 static int expDirectDrawCreate(void)
4921 dbgprintf("DirectDrawCreate(...) => NULL\n");
4926 typedef struct tagPALETTEENTRY
{
4933 typedef struct tagLOGPALETTE
{
4936 PALETTEENTRY palPalEntry
[1];
4939 static HPALETTE WINAPI
expCreatePalette(CONST LOGPALETTE
*lpgpl
)
4944 dbgprintf("CreatePalette(%x) => NULL\n", lpgpl
);
4946 i
= sizeof(LOGPALETTE
)+((lpgpl
->palNumEntries
-1)*sizeof(PALETTEENTRY
));
4948 memcpy((void *)test
, lpgpl
, i
);
4953 static int expCreatePalette(void)
4955 dbgprintf("CreatePalette(...) => NULL\n");
4960 static int WINAPI
expGetClientRect(HWND win
, RECT
*r
)
4962 dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win
, r
);
4963 r
->right
= PSEUDO_SCREEN_WIDTH
;
4965 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
4971 typedef struct tagPOINT
{
4977 static int WINAPI
expClientToScreen(HWND win
, POINT
*p
)
4979 dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win
, p
, p
->x
, p
->y
);
4987 static int WINAPI
expSetThreadIdealProcessor(HANDLE thread
, int proc
)
4989 dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread
, proc
);
4993 static int WINAPI
expMessageBeep(int type
)
4995 dbgprintf("MessageBeep(%d) => 1\n", type
);
4999 static int WINAPI
expDialogBoxParamA(void *inst
, const char *name
,
5000 HWND parent
, void *dialog_func
, void *init_param
)
5002 dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
5003 inst
, name
, name
, parent
, dialog_func
, init_param
);
5007 static void WINAPI
expRegisterClipboardFormatA(const char *name
) {
5008 dbgprintf("RegisterClipboardFormatA(0x%x = %s)\n", name
, name
);
5011 /* needed by imagepower mjpeg2k */
5012 static void *exprealloc(void *ptr
, size_t size
)
5014 dbgprintf("realloc(0x%x, %x)\n", ptr
, size
);
5016 return my_mreq(size
,0);
5018 return my_realloc(ptr
, size
);
5021 /* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
5022 static WIN_BOOL WINAPI
expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn
)
5027 static char * WINAPI
expPathFindExtensionA(const char *path
) {
5032 ext
= strrchr(path
, '.');
5034 ext
= &path
[strlen(path
)];
5036 dbgprintf("PathFindExtensionA(0x%x = %s) => 0x%x, %s\n", path
, path
, ext
, ext
);
5040 static char * WINAPI
expPathFindFileNameA(const char *path
) {
5042 if (!path
|| strlen(path
) < 2)
5045 name
= strrchr(path
- 1, '\\');
5049 dbgprintf("PathFindFileNameA(0x%x = %s) => 0x%x, %s\n", path
, path
, name
, name
);
5053 static double expfloor(double x
)
5055 dbgprintf("floor(%lf)\n", x
);
5059 #define FPU_DOUBLE(var) double var; \
5060 __asm__ volatile( "fstpl %0;fwait" : "=m" (var) : )
5062 static double exp_CIcos(void)
5066 dbgprintf("_CIcos(%lf)\n", x
);
5070 static double exp_CIsin(void)
5074 dbgprintf("_CIsin(%lf)\n", x
);
5078 static double exp_CIsqrt(void)
5082 dbgprintf("_CIsqrt(%lf)\n", x
);
5086 /* Needed by rp8 sipr decoder */
5087 static LPSTR WINAPI
expCharNextA(LPCSTR ptr
)
5089 if (!*ptr
) return (LPSTR
)ptr
;
5090 // dbgprintf("CharNextA(0x%08x), %s\n", ptr, ptr);
5091 return (LPSTR
)(ptr
+ 1);
5094 // Fake implementation, needed by wvc1dmod.dll
5095 static int WINAPI
expPropVariantClear(void *pvar
)
5097 // dbgprintf("PropVariantclear (0x%08x), %s\n", ptr, ptr);
5101 // This define is fake, the real thing is a struct
5102 #define LPDEVMODEA void*
5103 // Dummy implementation, always return 1
5104 // Required for frapsvid.dll 2.8.1, return value does not matter
5105 static WIN_BOOL WINAPI
expEnumDisplaySettingsA(LPCSTR name
,DWORD n
,
5108 dbgprintf("EnumDisplaySettingsA (dummy) => 1\n");
5112 // Fake implementation of _decode_pointer from msvcr80.dll, needed by sirenacm.dll
5113 // NOTE: undocumented function, probably the declaration is not right
5114 static int exp_decode_pointer(void *ptr
)
5116 dbgprintf("_decode_pointer (0x%08x)\n", ptr
);
5120 /* Fake implementation of sdt::_Lockit::_Lockit(void) from msvcp60.dll
5121 Needed by SCLS.DLL */
5122 static int exp_0Lockit_dummy(void)
5124 dbgprintf("0Lockit_dummy (??0_Lockit@std@@QAE@XZ)\n");
5128 /* Fake implementation of sdt::_Lockit::~_Lockit(void) from msvcp60.dll
5129 Needed by SCLS.DLL */
5130 static int exp_1Lockit_dummy(void)
5132 dbgprintf("1Lockit_dummy (??1_Lockit@std@@QAE@XZ)\n");
5136 static void * WINAPI
expEncodePointer(void *p
)
5141 static void * WINAPI
expDecodePointer(void *p
)
5146 static DWORD WINAPI
expGetThreadLocale(void)
5152 * Very incomplete implementation, return an error for almost all cases.
5154 static DWORD WINAPI
expGetLocaleInfoA(DWORD locale
, DWORD lctype
, char* lpLCData
, int cchData
)
5156 if (lctype
== 0x1004) { // LOCALE_IDEFAULTANSICODEPAGE
5158 return cchData
== 0 ? 4 : 0;
5159 strcpy(lpLCData
, "437");
5175 struct exports
* exps
;
5179 {#X, Y, (void*)exp##X},
5181 #define UNDEFF(X, Y) \
5184 struct exports exp_kernel32
[]=
5186 FF(GetVolumeInformationA
,-1)
5187 FF(GetDriveTypeA
,-1)
5188 FF(GetLogicalDriveStringsA
,-1)
5189 FF(IsBadWritePtr
, 357)
5190 FF(IsBadReadPtr
, 354)
5191 FF(IsBadStringPtrW
, -1)
5192 FF(IsBadStringPtrA
, -1)
5193 FF(DisableThreadLibraryCalls
, -1)
5194 FF(CreateThread
, -1)
5195 FF(ResumeThread
, -1)
5196 FF(CreateEventA
, -1)
5197 FF(CreateEventW
, -1)
5200 FF(WaitForSingleObject
, -1)
5201 #ifdef CONFIG_QTX_CODECS
5202 FF(WaitForMultipleObjects
, -1)
5205 FF(GetSystemInfo
, -1)
5213 FF(GetProcessHeap
, -1)
5214 FF(VirtualAlloc
, -1)
5216 FF(InitializeCriticalSection
, -1)
5217 FF(InitializeCriticalSectionAndSpinCount
, -1)
5218 FF(EnterCriticalSection
, -1)
5219 FF(LeaveCriticalSection
, -1)
5220 FF(DeleteCriticalSection
, -1)
5225 FF(GetCurrentThreadId
, -1)
5226 FF(GetCurrentProcess
, -1)
5231 FF(GlobalReAlloc
, -1)
5234 FF(MultiByteToWideChar
, 427)
5235 FF(WideCharToMultiByte
, -1)
5236 FF(GetVersionExA
, -1)
5237 FF(GetVersionExW
, -1)
5238 FF(CreateSemaphoreA
, -1)
5239 FF(CreateSemaphoreW
, -1)
5240 FF(QueryPerformanceCounter
, -1)
5241 FF(QueryPerformanceFrequency
, -1)
5245 FF(GlobalHandle
, -1)
5246 FF(GlobalUnlock
, -1)
5248 FF(LoadResource
, -1)
5249 FF(ReleaseSemaphore
, -1)
5250 FF(CreateMutexA
, -1)
5251 FF(CreateMutexW
, -1)
5252 FF(ReleaseMutex
, -1)
5253 FF(SignalObjectAndWait
, -1)
5254 FF(FindResourceA
, -1)
5255 FF(LockResource
, -1)
5256 FF(FreeResource
, -1)
5257 FF(SizeofResource
, -1)
5259 FF(GetCommandLineA
, -1)
5260 FF(GetEnvironmentStringsW
, -1)
5261 FF(FreeEnvironmentStringsW
, -1)
5262 FF(FreeEnvironmentStringsA
, -1)
5263 FF(GetEnvironmentStrings
, -1)
5264 FF(GetStartupInfoA
, -1)
5265 FF(GetStdHandle
, -1)
5267 #ifdef CONFIG_QTX_CODECS
5268 FF(GetFileAttributesA
, -1)
5270 FF(SetHandleCount
, -1)
5272 FF(GetModuleFileNameA
, -1)
5273 FF(SetUnhandledExceptionFilter
, -1)
5274 FF(LoadLibraryA
, -1)
5275 FF(GetProcAddress
, -1)
5277 FF(CreateFileMappingA
, -1)
5278 FF(OpenFileMappingA
, -1)
5279 FF(MapViewOfFile
, -1)
5280 FF(UnmapViewOfFile
, -1)
5282 FF(GetModuleHandleA
, -1)
5283 FF(GetModuleHandleW
, -1)
5284 FF(GetProfileIntA
, -1)
5285 FF(GetPrivateProfileIntA
, -1)
5286 FF(GetPrivateProfileStringA
, -1)
5287 FF(WritePrivateProfileStringA
, -1)
5288 FF(GetLastError
, -1)
5289 FF(SetLastError
, -1)
5290 FF(InterlockedIncrement
, -1)
5291 FF(InterlockedDecrement
, -1)
5292 FF(GetTimeZoneInformation
, -1)
5293 FF(OutputDebugStringA
, -1)
5294 FF(GetLocalTime
, -1)
5295 FF(GetSystemTime
, -1)
5296 FF(GetSystemTimeAsFileTime
, -1)
5297 FF(GetEnvironmentVariableA
, -1)
5298 FF(SetEnvironmentVariableA
, -1)
5299 FF(RtlZeroMemory
,-1)
5300 FF(RtlMoveMemory
,-1)
5301 FF(RtlFillMemory
,-1)
5303 FF(FindFirstFileA
,-1)
5304 FF(FindNextFileA
,-1)
5306 FF(FileTimeToLocalFileTime
,-1)
5310 FF(SetFilePointer
,-1)
5311 FF(GetTempFileNameA
,-1)
5313 FF(GetSystemDirectoryA
,-1)
5314 FF(GetWindowsDirectoryA
,-1)
5315 #ifdef CONFIG_QTX_CODECS
5316 FF(GetCurrentDirectoryA
,-1)
5317 FF(SetCurrentDirectoryA
,-1)
5318 FF(CreateDirectoryA
,-1)
5320 FF(GetShortPathNameA
,-1)
5321 FF(GetFullPathNameA
,-1)
5322 FF(SetErrorMode
, -1)
5323 FF(IsProcessorFeaturePresent
, -1)
5324 FF(IsDebuggerPresent
, -1)
5325 FF(GetProcessAffinityMask
, -1)
5326 FF(InterlockedExchange
, -1)
5327 FF(InterlockedCompareExchange
, -1)
5334 FF(GetProcessVersion
,-1)
5335 FF(GetCurrentThread
,-1)
5338 FF(DuplicateHandle
,-1)
5339 FF(GetTickCount
, -1)
5340 FF(SetThreadAffinityMask
,-1)
5341 FF(GetCurrentProcessId
,-1)
5342 FF(GlobalMemoryStatus
,-1)
5343 FF(GetThreadPriority
,-1)
5344 FF(SetThreadPriority
,-1)
5345 FF(TerminateProcess
,-1)
5347 {"LoadLibraryExA", -1, (void*)&LoadLibraryExA
},
5348 FF(SetThreadIdealProcessor
,-1)
5349 FF(SetProcessAffinityMask
, -1)
5350 FF(EncodePointer
, -1)
5351 FF(DecodePointer
, -1)
5352 FF(GetThreadLocale
, -1)
5353 FF(GetLocaleInfoA
, -1)
5354 UNDEFF(FlsAlloc
, -1)
5355 UNDEFF(FlsGetValue
, -1)
5356 UNDEFF(FlsSetValue
, -1)
5360 struct exports exp_msvcrt
[]={
5366 {"??3@YAXPAX@Z", -1, expdelete
},
5367 {"??2@YAPAXI@Z", -1, expnew
},
5368 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5369 {"_winver",-1,(void*)&_winver
},
5410 /* needed by frapsvid.dll */
5411 {"strstr",-1,(char *)&strstr
},
5412 {"qsort",-1,(void *)&qsort
},
5415 {"ceil",-1,(void*)&ceil
},
5416 /* needed by imagepower mjpeg2k */
5417 {"clock",-1,(void*)&clock
},
5418 {"memchr",-1,(void*)&memchr
},
5419 {"vfprintf",-1,(void*)&vfprintf
},
5420 // {"realloc",-1,(void*)&realloc},
5422 {"puts",-1,(void*)&puts
}
5424 struct exports exp_winmm
[]={
5425 FF(GetDriverModuleHandle
, -1)
5427 FF(DefDriverProc
, -1)
5430 FF(timeGetDevCaps
, -1)
5431 FF(timeBeginPeriod
, -1)
5432 #ifdef CONFIG_QTX_CODECS
5433 FF(timeEndPeriod
, -1)
5434 FF(waveOutGetNumDevs
, -1)
5437 struct exports exp_psapi
[]={
5438 FF(GetModuleBaseNameA
, -1)
5440 struct exports exp_user32
[]={
5445 FF(GetDesktopWindow
, -1)
5451 #ifdef CONFIG_QTX_CODECS
5454 FF(RegisterWindowMessageA
,-1)
5455 FF(GetSystemMetrics
,-1)
5457 FF(GetSysColorBrush
,-1)
5461 FF(RegisterClassA
, -1)
5462 FF(UnregisterClassA
, -1)
5463 #ifdef CONFIG_QTX_CODECS
5464 FF(GetWindowRect
, -1)
5465 FF(MonitorFromWindow
, -1)
5466 FF(MonitorFromRect
, -1)
5467 FF(MonitorFromPoint
, -1)
5468 FF(EnumDisplayMonitors
, -1)
5469 FF(GetMonitorInfoA
, -1)
5470 FF(EnumDisplayDevicesA
, -1)
5471 FF(GetClientRect
, -1)
5472 FF(ClientToScreen
, -1)
5473 FF(IsWindowVisible
, -1)
5474 FF(GetActiveWindow
, -1)
5475 FF(GetClassNameA
, -1)
5476 FF(GetClassInfoA
, -1)
5477 FF(GetWindowLongA
, -1)
5479 FF(GetWindowThreadProcessId
, -1)
5480 FF(CreateWindowExA
, -1)
5483 FF(DialogBoxParamA
, -1)
5484 FF(RegisterClipboardFormatA
, -1)
5486 FF(EnumDisplaySettingsA
, -1)
5488 struct exports exp_advapi32
[]={
5490 FF(RegCreateKeyA
, -1)
5491 FF(RegCreateKeyExA
, -1)
5492 FF(RegEnumKeyExA
, -1)
5493 FF(RegEnumValueA
, -1)
5495 FF(RegOpenKeyExA
, -1)
5496 FF(RegQueryValueExA
, -1)
5497 FF(RegSetValueExA
, -1)
5498 FF(RegQueryInfoKeyA
, -1)
5500 struct exports exp_gdi32
[]={
5501 FF(CreateCompatibleDC
, -1)
5504 FF(DeleteObject
, -1)
5505 FF(GetDeviceCaps
, -1)
5506 FF(GetSystemPaletteEntries
, -1)
5507 #ifdef CONFIG_QTX_CODECS
5508 FF(CreatePalette
, -1)
5510 FF(CreateRectRgn
, -1)
5513 struct exports exp_version
[]={
5514 FF(GetFileVersionInfoSizeA
, -1)
5516 struct exports exp_ole32
[]={
5517 FF(CoCreateFreeThreadedMarshaler
,-1)
5518 FF(CoCreateInstance
, -1)
5519 FF(CoInitialize
, -1)
5520 FF(CoInitializeEx
, -1)
5521 FF(CoUninitialize
, -1)
5522 FF(CoTaskMemAlloc
, -1)
5523 FF(CoTaskMemFree
, -1)
5524 FF(StringFromGUID2
, -1)
5525 FF(PropVariantClear
, -1)
5527 // do we really need crtdll ???
5528 // msvcrt is the correct place probably...
5529 struct exports exp_crtdll
[]={
5533 struct exports exp_comctl32
[]={
5534 FF(StringFromGUID2
, -1)
5535 FF(InitCommonControls
, 17)
5536 #ifdef CONFIG_QTX_CODECS
5537 FF(CreateUpDownControl
, 16)
5540 struct exports exp_wsock32
[]={
5544 struct exports exp_msdmo
[]={
5545 FF(memcpy
, -1) // just test
5546 FF(MoCopyMediaType
, -1)
5547 FF(MoCreateMediaType
, -1)
5548 FF(MoDeleteMediaType
, -1)
5549 FF(MoDuplicateMediaType
, -1)
5550 FF(MoFreeMediaType
, -1)
5551 FF(MoInitMediaType
, -1)
5553 struct exports exp_oleaut32
[]={
5554 FF(SysAllocStringLen
, 4)
5555 FF(SysFreeString
, 6)
5557 #ifdef CONFIG_QTX_CODECS
5558 FF(SysStringByteLen
, 149)
5564 vma: Hint/Ord Member-Name
5569 2305e 167 _adjust_fdiv
5572 22ffc 176 _beginthreadex
5574 2300e 85 __CxxFrameHandler
5578 struct exports exp_pncrt
[]={
5579 FF(malloc
, -1) // just test
5580 FF(free
, -1) // just test
5581 FF(fprintf
, -1) // just test
5582 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5585 {"??3@YAXPAX@Z", -1, expdelete
},
5586 {"??2@YAPAXI@Z", -1, expnew
},
5597 #ifdef CONFIG_QTX_CODECS
5598 struct exports exp_ddraw
[]={
5599 FF(DirectDrawCreate
, -1)
5603 struct exports exp_comdlg32
[]={
5604 FF(GetOpenFileNameA
, -1)
5607 struct exports exp_shlwapi
[]={
5608 FF(PathFindExtensionA
, -1)
5609 FF(PathFindFileNameA
, -1)
5612 struct exports exp_msvcr80
[]={
5620 FF(_decode_pointer
, -1)
5621 /* needed by KGV1-VFW.dll */
5622 {"??2@YAPAXI@Z", -1, expnew
},
5623 {"??3@YAXPAX@Z", -1, expdelete
}
5626 struct exports exp_msvcp60
[]={
5627 {"??0_Lockit@std@@QAE@XZ", -1, exp_0Lockit_dummy
},
5628 {"??1_Lockit@std@@QAE@XZ", -1, exp_1Lockit_dummy
}
5632 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5634 struct libs libraries
[]={
5652 #ifdef CONFIG_QTX_CODECS
5661 static WIN_BOOL WINAPI
ext_stubs(void)
5663 // NOTE! these magic values will be replaced at runtime, make sure
5664 // add_stub can still find them if you change them.
5665 volatile int idx
= 0x0deadabc;
5666 // make sure gcc does not do eip-relative call or something like that
5667 void (* volatile my_printf
)(char *, char *) = (void *)0xdeadfbcd;
5668 my_printf("Called unk_%s\n", export_names
[idx
]);
5672 #define MAX_STUB_SIZE 0x60
5673 #define MAX_NUM_STUBS 200
5675 static char *extcode
= NULL
;
5677 static void* add_stub(void)
5681 // generated code in runtime!
5684 extcode
= mmap_anon(NULL
, MAX_NUM_STUBS
* MAX_STUB_SIZE
,
5685 PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
, 0);
5686 answ
= extcode
+ pos
* MAX_STUB_SIZE
;
5687 if (pos
>= MAX_NUM_STUBS
) {
5688 printf("too many stubs, expect crash\n");
5691 memcpy(answ
, ext_stubs
, MAX_STUB_SIZE
);
5692 for (i
= 0; i
< MAX_STUB_SIZE
- 3; i
++) {
5693 int *magic
= (int *)(answ
+ i
);
5694 if (*magic
== 0x0deadabc) {
5698 if (*magic
== 0xdeadfbcd) {
5699 *magic
= (intptr_t)printf
;
5704 printf("magic code not found in ext_subs, expect crash\n");
5711 void* LookupExternal(const char* library
, int ordinal
)
5716 printf("ERROR: library=0\n");
5717 return (void*)ext_unknown
;
5719 // printf("%x %x\n", &unk_exp1, &unk_exp2);
5721 dbgprintf("External func %s:%d\n", library
, ordinal
);
5723 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5725 if(strcasecmp(library
, libraries
[i
].name
))
5727 for(j
=0; j
<libraries
[i
].length
; j
++)
5729 if(ordinal
!=libraries
[i
].exps
[j
].id
)
5731 //printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5732 return libraries
[i
].exps
[j
].func
;
5736 #ifndef LOADLIB_TRY_NATIVE
5737 /* hack for truespeech and vssh264*/
5738 if (!strcmp(library
, "tsd32.dll") || !strcmp(library
,"vssh264dec.dll") || !strcmp(library
,"LCMW2.dll") || !strcmp(library
,"VDODEC32.dll"))
5740 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5746 hand
= LoadLibraryA(library
);
5749 wm
= MODULE32_LookupHMODULE(hand
);
5755 func
= PE_FindExportedFunction(wm
, (LPCSTR
) ordinal
, 0);
5758 printf("No such ordinal in external dll\n");
5759 FreeLibrary((int)hand
);
5763 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5769 if(pos
>150)return 0;
5770 snprintf(export_names
[pos
], sizeof(export_names
[pos
]), "%s:%d", library
, ordinal
);
5774 void* LookupExternalByName(const char* library
, const char* name
)
5777 // return (void*)ext_unknown;
5780 printf("ERROR: library=0\n");
5781 return (void*)ext_unknown
;
5783 if((unsigned long)name
<=0xffff)
5785 return LookupExternal(library
, (int)name
);
5787 dbgprintf("External func %s:%s\n", library
, name
);
5788 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5790 if(strcasecmp(library
, libraries
[i
].name
))
5792 for(j
=0; j
<libraries
[i
].length
; j
++)
5794 if(strcmp(name
, libraries
[i
].exps
[j
].name
))
5796 if((unsigned int)(libraries
[i
].exps
[j
].func
) == -1)
5797 return NULL
; //undefined func
5798 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5799 return libraries
[i
].exps
[j
].func
;
5803 #ifndef LOADLIB_TRY_NATIVE
5804 /* hack for vss h264 */
5805 if (!strcmp(library
,"vssh264core.dll") || !strcmp(library
,"3ivx.dll"))
5807 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5813 hand
= LoadLibraryA(library
);
5816 wm
= MODULE32_LookupHMODULE(hand
);
5822 func
= PE_FindExportedFunction(wm
, name
, 0);
5825 printf("No such name in external dll\n");
5826 FreeLibrary((int)hand
);
5830 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5836 if(pos
>150)return 0;// to many symbols
5837 snprintf(export_names
[pos
], sizeof(export_names
[pos
]), "%s", name
);
5841 void my_garbagecollection(void)
5844 int unfree
= 0, unfreecnt
= 0;
5850 alloc_header
* mem
= last_alloc
+ 1;
5851 unfree
+= my_size(mem
);
5853 if (my_release(mem
) != 0)
5854 // avoid endless loop when memory is trashed
5855 if (--max_fatal
< 0)
5858 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree
, unfreecnt
, last_alloc
, alccnt
);
5861 pthread_mutex_lock(&list_lock
);
5863 pthread_mutex_unlock(&list_lock
);