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
= WIN32_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
expSetEvent(void* event
)
797 mutex_list
*ml
= (mutex_list
*)event
;
798 dbgprintf("SetEvent(%x) => 0x1\n", event
);
799 pthread_mutex_lock(ml
->pm
);
800 if (ml
->state
== 0) {
802 pthread_cond_signal(ml
->pc
);
804 pthread_mutex_unlock(ml
->pm
);
808 static void* WINAPI
expResetEvent(void* event
)
810 mutex_list
*ml
= (mutex_list
*)event
;
811 dbgprintf("ResetEvent(0x%x) => 0x1\n", event
);
812 pthread_mutex_lock(ml
->pm
);
814 pthread_mutex_unlock(ml
->pm
);
819 static void* WINAPI
expWaitForSingleObject(void* object
, int duration
)
821 mutex_list
*ml
= (mutex_list
*)object
;
822 // FIXME FIXME FIXME - this value is sometime unititialize !!!
823 int ret
= WAIT_FAILED
;
826 if(object
== (void*)0xcfcf9898)
829 From GetCurrentThread() documentation:
830 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.
832 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.
834 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.
836 dbgprintf("WaitForSingleObject(thread_handle) called\n");
837 return (void*)WAIT_FAILED
;
839 dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object
, duration
);
841 // See if this is a thread.
842 pthread_mutex_lock(&list_lock
);
844 while (tp
&& (tp
->thread
!= object
))
846 pthread_mutex_unlock(&list_lock
);
848 if (pthread_join(*(pthread_t
*)object
, NULL
) == 0) {
849 return (void*)WAIT_OBJECT_0
;
851 return (void*)WAIT_FAILED
;
855 // loop below was slightly fixed - its used just for checking if
856 // this object really exists in our list
859 pthread_mutex_lock(&mlist_lock
);
861 while (pp
&& (pp
->pm
!= ml
->pm
))
863 pthread_mutex_unlock(&mlist_lock
);
865 dbgprintf("WaitForSingleObject: NotFound\n");
869 pthread_mutex_lock(ml
->pm
);
873 if (duration
== 0) { /* Check Only */
874 if (ml
->state
== 1) ret
= WAIT_OBJECT_0
;
875 else ret
= WAIT_FAILED
;
877 if (duration
== -1) { /* INFINITE */
879 pthread_cond_wait(ml
->pc
,ml
->pm
);
884 if (duration
> 0) { /* Timed Wait */
885 struct timespec abstime
;
887 gettimeofday(&now
, 0);
888 abstime
.tv_sec
= now
.tv_sec
+ (now
.tv_usec
+duration
)/1000000;
889 abstime
.tv_nsec
= ((now
.tv_usec
+duration
)%1000000)*1000;
891 ret
=pthread_cond_timedwait(ml
->pc
,ml
->pm
,&abstime
);
892 if (ret
== ETIMEDOUT
) ret
= WAIT_TIMEOUT
;
893 else ret
= WAIT_OBJECT_0
;
898 case 1: /* Semaphore */
900 if(ml
->semaphore
==0) ret
= WAIT_FAILED
;
906 if (duration
== -1) {
907 if (ml
->semaphore
==0)
908 pthread_cond_wait(ml
->pc
,ml
->pm
);
915 if(ml
->lock_count
> 0 && ml
->owner
!= pthread_self()) ret
= WAIT_FAILED
;
918 ml
->owner
= pthread_self();
922 if (duration
== -1) {
923 if (ml
->lock_count
> 0 && ml
->owner
!= pthread_self()) {
924 pthread_cond_wait(ml
->pc
,ml
->pm
);
927 ml
->owner
= pthread_self();
932 pthread_mutex_unlock(ml
->pm
);
934 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object
,duration
,ml
,ret
);
938 #ifdef CONFIG_QTX_CODECS
939 static void* WINAPI
expWaitForMultipleObjects(int count
, const void** objects
,
940 int WaitAll
, int duration
)
946 dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
947 count
, objects
, WaitAll
, duration
);
949 for (i
= 0; i
< count
; i
++)
951 object
= (void *)objects
[i
];
952 ret
= expWaitForSingleObject(object
, duration
);
954 dbgprintf("WaitAll flag not yet supported...\n");
961 static void WINAPI
expExitThread(int retcode
)
963 dbgprintf("ExitThread(%d)\n", retcode
);
964 pthread_exit(&retcode
);
968 static int pf_set
= 0;
969 static BYTE PF
[64] = {0,};
971 static void DumpSystemInfo(const SYSTEM_INFO
* si
)
973 dbgprintf(" Processor architecture %d\n", si
->u
.s
.wProcessorArchitecture
);
974 dbgprintf(" Page size: %d\n", si
->dwPageSize
);
975 dbgprintf(" Minimum app address: %d\n", si
->lpMinimumApplicationAddress
);
976 dbgprintf(" Maximum app address: %d\n", si
->lpMaximumApplicationAddress
);
977 dbgprintf(" Active processor mask: 0x%x\n", si
->dwActiveProcessorMask
);
978 dbgprintf(" Number of processors: %d\n", si
->dwNumberOfProcessors
);
979 dbgprintf(" Processor type: 0x%x\n", si
->dwProcessorType
);
980 dbgprintf(" Allocation granularity: 0x%x\n", si
->dwAllocationGranularity
);
981 dbgprintf(" Processor level: 0x%x\n", si
->wProcessorLevel
);
982 dbgprintf(" Processor revision: 0x%x\n", si
->wProcessorRevision
);
985 static void WINAPI
expGetSystemInfo(SYSTEM_INFO
* si
)
987 /* FIXME: better values for the two entries below... */
988 static int cache
= 0;
989 static SYSTEM_INFO cachedsi
;
990 dbgprintf("GetSystemInfo(%p) =>\n", si
);
995 memset(PF
,0,sizeof(PF
));
998 cachedsi
.u
.s
.wProcessorArchitecture
= PROCESSOR_ARCHITECTURE_INTEL
;
999 cachedsi
.dwPageSize
= getpagesize();
1001 /* FIXME: better values for the two entries below... */
1002 cachedsi
.lpMinimumApplicationAddress
= (void *)0x00000000;
1003 cachedsi
.lpMaximumApplicationAddress
= (void *)0x7FFFFFFF;
1004 cachedsi
.dwActiveProcessorMask
= 1;
1005 cachedsi
.dwNumberOfProcessors
= 1;
1006 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1007 cachedsi
.dwAllocationGranularity
= 0x10000;
1008 cachedsi
.wProcessorLevel
= 5; /* pentium */
1009 cachedsi
.wProcessorRevision
= 0x0101;
1011 /* mplayer's way to detect PF's */
1013 #include "cpudetect.h"
1015 if (gCpuCaps
.hasMMX
)
1016 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1017 if (gCpuCaps
.hasSSE
)
1018 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1019 if (gCpuCaps
.hasSSE2
)
1020 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1021 if (gCpuCaps
.has3DNow
)
1022 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1024 if (gCpuCaps
.cpuType
== 4)
1026 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1027 cachedsi
.wProcessorLevel
= 4;
1029 else if (gCpuCaps
.cpuType
>= 5)
1031 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1032 cachedsi
.wProcessorLevel
= 5;
1036 cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1037 cachedsi
.wProcessorLevel
= 3;
1039 cachedsi
.wProcessorRevision
= gCpuCaps
.cpuStepping
;
1040 cachedsi
.dwNumberOfProcessors
= 1; /* hardcoded */
1043 /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
1044 fdiv_bug and fpu emulation flags -- alex/MPlayer */
1049 FILE *f
= fopen ("/proc/cpuinfo", "r");
1053 mp_msg(MSGT_WIN32
, MSGL_WARN
, "expGetSystemInfo: "
1054 "/proc/cpuinfo not readable! "
1055 "Expect bad performance and/or weird behaviour\n");
1058 while (fgets(line
,200,f
)!=NULL
) {
1061 /* NOTE: the ':' is the only character we can rely on */
1062 if (!(value
= strchr(line
,':')))
1064 /* terminate the valuename */
1066 /* skip any leading spaces */
1067 while (*value
==' ') value
++;
1068 if ((s
=strchr(value
,'\n')))
1072 if (!lstrncmpiA(line
, "cpu family",strlen("cpu family"))) {
1073 if (isdigit (value
[0])) {
1074 switch (value
[0] - '0') {
1075 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1076 cachedsi
.wProcessorLevel
= 3;
1078 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1079 cachedsi
.wProcessorLevel
= 4;
1081 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1082 cachedsi
.wProcessorLevel
= 5;
1084 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1085 cachedsi
.wProcessorLevel
= 5;
1087 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1088 cachedsi
.wProcessorLevel
= 5;
1092 /* set the CPU type of the current processor */
1093 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1096 /* old 2.0 method */
1097 if (!lstrncmpiA(line
, "cpu",strlen("cpu"))) {
1098 if ( isdigit (value
[0]) && value
[1] == '8' &&
1099 value
[2] == '6' && value
[3] == 0
1101 switch (value
[0] - '0') {
1102 case 3: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_386
;
1103 cachedsi
.wProcessorLevel
= 3;
1105 case 4: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_486
;
1106 cachedsi
.wProcessorLevel
= 4;
1108 case 5: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1109 cachedsi
.wProcessorLevel
= 5;
1111 case 6: cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1112 cachedsi
.wProcessorLevel
= 5;
1114 default:cachedsi
.dwProcessorType
= PROCESSOR_INTEL_PENTIUM
;
1115 cachedsi
.wProcessorLevel
= 5;
1119 /* set the CPU type of the current processor */
1120 sprintf(buf
,"CPU %ld",cachedsi
.dwProcessorType
);
1123 if (!lstrncmpiA(line
,"fdiv_bug",strlen("fdiv_bug"))) {
1124 if (!lstrncmpiA(value
,"yes",3))
1125 PF
[PF_FLOATING_POINT_PRECISION_ERRATA
] = TRUE
;
1129 if (!lstrncmpiA(line
,"fpu",strlen("fpu"))) {
1130 if (!lstrncmpiA(value
,"no",2))
1131 PF
[PF_FLOATING_POINT_EMULATED
] = TRUE
;
1135 if (!lstrncmpiA(line
,"processor",strlen("processor"))) {
1136 /* processor number counts up...*/
1139 if (sscanf(value
,"%d",&x
))
1140 if (x
+1>cachedsi
.dwNumberOfProcessors
)
1141 cachedsi
.dwNumberOfProcessors
=x
+1;
1143 /* Create a new processor subkey on a multiprocessor
1146 sprintf(buf
,"%d",x
);
1148 if (!lstrncmpiA(line
,"stepping",strlen("stepping"))) {
1151 if (sscanf(value
,"%d",&x
))
1152 cachedsi
.wProcessorRevision
= x
;
1155 ( (!lstrncmpiA(line
,"flags",strlen("flags")))
1156 || (!lstrncmpiA(line
,"features",strlen("features"))) )
1158 if (strstr(value
,"cx8"))
1159 PF
[PF_COMPARE_EXCHANGE_DOUBLE
] = TRUE
;
1160 if (strstr(value
,"mmx"))
1161 PF
[PF_MMX_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1162 if (strstr(value
,"tsc"))
1163 PF
[PF_RDTSC_INSTRUCTION_AVAILABLE
] = TRUE
;
1164 if (strstr(value
,"xmm") || strstr(value
,"sse"))
1165 PF
[PF_XMMI_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1166 if (strstr(value
,"sse2"))
1167 PF
[PF_XMMI64_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1168 if (strstr(value
,"3dnow"))
1169 PF
[PF_AMD3D_INSTRUCTIONS_AVAILABLE
] = TRUE
;
1174 * ad hoc fix for smp machines.
1175 * some problems on WaitForSingleObject,CreateEvent,SetEvent
1176 * CreateThread ...etc..
1179 cachedsi
.dwNumberOfProcessors
=1;
1181 #endif /* __linux__ */
1184 memcpy(si
,&cachedsi
,sizeof(*si
));
1188 // avoid undefined expGetSystemInfo
1189 static WIN_BOOL WINAPI
expIsProcessorFeaturePresent(DWORD v
)
1191 WIN_BOOL result
= 0;
1195 expGetSystemInfo(&si
);
1197 if(v
<64) result
=PF
[v
];
1198 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v
, result
);
1202 static WIN_BOOL WINAPI
expIsDebuggerPresent(void)
1207 static long WINAPI
expGetVersion(void)
1209 dbgprintf("GetVersion() => 0xC0000004\n");
1210 return 0xC0000004;//Windows 95
1213 static HANDLE WINAPI
expHeapCreate(long flags
, long init_size
, long max_size
)
1215 // printf("HeapCreate:");
1218 result
=(HANDLE
)my_mreq(0x110000, 0);
1220 result
=(HANDLE
)my_mreq((init_size
+ 0xfff) & 0x7ffff000 , 0);
1221 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags
, init_size
, max_size
, result
);
1225 // this is another dirty hack
1226 // VP31 is releasing one allocated Heap chunk twice
1227 // we will silently ignore this second call...
1228 static void* heapfreehack
= 0;
1229 static int heapfreehackshown
= 0;
1230 //void trapbug(void);
1231 static void* WINAPI
expHeapAlloc(HANDLE heap
, int flags
, int size
)
1235 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1236 HeapAlloc returns area larger than size argument :-/
1238 actually according to M$ Doc HeapCreate size should be rounded
1239 to page boundaries thus we should simulate this
1241 //if (size == 22276) trapbug();
1242 z
=my_mreq((size
+ 0xfff) & 0x7ffff000, (flags
& HEAP_ZERO_MEMORY
));
1244 printf("HeapAlloc failure\n");
1245 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap
, flags
, size
, z
);
1246 heapfreehack
= 0; // reset
1249 static long WINAPI
expHeapDestroy(void* heap
)
1251 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap
);
1256 static long WINAPI
expHeapFree(HANDLE heap
, DWORD dwFlags
, LPVOID lpMem
)
1258 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap
, dwFlags
, lpMem
);
1259 if (heapfreehack
!= lpMem
&& lpMem
!= (void*)0xffffffff
1260 && lpMem
!= (void*)0xbdbdbdbd)
1261 // 0xbdbdbdbd is for i263_drv.drv && libefence
1262 // it seems to be reading from relased memory
1263 // EF_PROTECT_FREE doens't show any probleme
1267 if (!heapfreehackshown
++)
1268 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem
);
1270 heapfreehack
= lpMem
;
1273 static long WINAPI
expHeapSize(int heap
, int flags
, void* pointer
)
1275 long result
=my_size(pointer
);
1276 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap
, flags
, pointer
, result
);
1279 static void* WINAPI
expHeapReAlloc(HANDLE heap
,int flags
,void *lpMem
,int size
)
1281 long orgsize
= my_size(lpMem
);
1282 dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize
,size
);
1283 return my_realloc(lpMem
, size
);
1285 static long WINAPI
expGetProcessHeap(void)
1287 dbgprintf("GetProcessHeap() => 1\n");
1290 static void* WINAPI
expVirtualAlloc(void* v1
, long v2
, long v3
, long v4
)
1292 void* z
= VirtualAlloc(v1
, v2
, v3
, v4
);
1294 printf("VirtualAlloc failure\n");
1295 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1
,v2
,v3
,v4
, z
);
1298 static int WINAPI
expVirtualFree(void* v1
, int v2
, int v3
)
1300 int result
= VirtualFree(v1
,v2
,v3
);
1301 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1
,v2
,v3
, result
);
1305 /* we're building a table of critical sections. cs_win pointer uses the DLL
1306 cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1307 struct critsecs_list_t
1309 CRITICAL_SECTION
*cs_win
;
1310 struct CRITSECT
*cs_unix
;
1313 /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1314 #undef CRITSECS_NEWTYPE
1315 //#define CRITSECS_NEWTYPE 1
1317 #ifdef CRITSECS_NEWTYPE
1318 /* increased due to ucod needs more than 32 entries */
1319 /* and 64 should be enough for everything */
1320 #define CRITSECS_LIST_MAX 64
1321 static struct critsecs_list_t critsecs_list
[CRITSECS_LIST_MAX
];
1323 static int critsecs_get_pos(CRITICAL_SECTION
*cs_win
)
1327 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1328 if (critsecs_list
[i
].cs_win
== cs_win
)
1333 static int critsecs_get_unused(void)
1337 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1338 if (critsecs_list
[i
].cs_win
== NULL
)
1343 struct CRITSECT
*critsecs_get_unix(CRITICAL_SECTION
*cs_win
)
1347 for (i
=0; i
< CRITSECS_LIST_MAX
; i
++)
1348 if (critsecs_list
[i
].cs_win
== cs_win
&& critsecs_list
[i
].cs_unix
)
1349 return critsecs_list
[i
].cs_unix
;
1354 static void WINAPI
expInitializeCriticalSection(CRITICAL_SECTION
* c
)
1356 dbgprintf("InitializeCriticalSection(0x%x)\n", c
);
1357 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1359 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1360 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1363 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1364 #ifdef CRITSECS_NEWTYPE
1366 struct CRITSECT
*cs
;
1367 int i
= critsecs_get_unused();
1371 printf("InitializeCriticalSection(%p) - no more space in list\n", c
);
1374 dbgprintf("got unused space at %d\n", i
);
1375 cs
= malloc(sizeof(struct CRITSECT
));
1378 printf("InitializeCriticalSection(%p) - out of memory\n", c
);
1381 pthread_mutex_init(&cs
->mutex
, NULL
);
1382 pthread_cond_init(&cs
->unlocked
, NULL
);
1384 critsecs_list
[i
].cs_win
= c
;
1385 critsecs_list
[i
].cs_unix
= cs
;
1386 dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1391 struct CRITSECT
* cs
= mreq_private(sizeof(struct CRITSECT
) + sizeof(CRITICAL_SECTION
),
1392 0, AREATYPE_CRITSECT
);
1393 pthread_mutex_init(&cs
->mutex
, NULL
);
1394 pthread_cond_init(&cs
->unlocked
, NULL
);
1396 cs
->deadbeef
= 0xdeadbeef;
1403 static void WINAPI
expInitializeCriticalSectionAndSpinCount(CRITICAL_SECTION
* c
, DWORD spin
)
1405 expInitializeCriticalSection(c
);
1408 static void WINAPI
expEnterCriticalSection(CRITICAL_SECTION
* c
)
1410 #ifdef CRITSECS_NEWTYPE
1411 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1413 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1415 dbgprintf("EnterCriticalSection(0x%x) %p\n",c
, cs
);
1418 dbgprintf("entered uninitialized critisec!\n");
1419 expInitializeCriticalSection(c
);
1420 #ifdef CRITSECS_NEWTYPE
1421 cs
=critsecs_get_unix(c
);
1423 cs
= (*(struct CRITSECT
**)c
);
1425 dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c
);
1427 pthread_mutex_lock(&(cs
->mutex
));
1428 if (cs
->lock_count
> 0 && cs
->id
== pthread_self()) {
1431 while (cs
->lock_count
!= 0) {
1432 pthread_cond_wait(&(cs
->unlocked
), &(cs
->mutex
));
1435 cs
->id
= pthread_self();
1437 pthread_mutex_unlock(&(cs
->mutex
));
1440 static void WINAPI
expLeaveCriticalSection(CRITICAL_SECTION
* c
)
1442 #ifdef CRITSECS_NEWTYPE
1443 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1445 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1447 // struct CRITSECT* cs=(struct CRITSECT*)c;
1448 dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c
, cs
);
1451 dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c
);
1454 pthread_mutex_lock(&(cs
->mutex
));
1455 if (cs
->lock_count
== 0) {
1456 dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c
);
1460 if (cs
->lock_count
== 0) {
1461 pthread_cond_signal(&(cs
->unlocked
));
1463 pthread_mutex_unlock(&(cs
->mutex
));
1467 static void expfree(void* mem
); /* forward declaration */
1469 static void WINAPI
expDeleteCriticalSection(CRITICAL_SECTION
*c
)
1471 #ifdef CRITSECS_NEWTYPE
1472 struct CRITSECT
* cs
= critsecs_get_unix(c
);
1474 struct CRITSECT
* cs
= (*(struct CRITSECT
**)c
);
1476 // struct CRITSECT* cs=(struct CRITSECT*)c;
1477 dbgprintf("DeleteCriticalSection(0x%x)\n",c
);
1481 dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c
);
1485 pthread_mutex_lock(&(cs
->mutex
));
1486 if (cs
->lock_count
> 0)
1488 dbgprintf("Win32 Warning: Deleting locked Critical Section %p!!\n", c
);
1490 pthread_mutex_unlock(&(cs
->mutex
));
1493 pthread_mutex_destroy(&(cs
->mutex
));
1494 pthread_cond_destroy(&(cs
->unlocked
));
1495 // released by GarbageCollector in my_relase otherwise
1498 #ifdef CRITSECS_NEWTYPE
1500 int i
= critsecs_get_pos(c
);
1504 printf("DeleteCriticalSection(%p) error (critsec not found)\n", c
);
1508 critsecs_list
[i
].cs_win
= NULL
;
1509 expfree(critsecs_list
[i
].cs_unix
);
1510 critsecs_list
[i
].cs_unix
= NULL
;
1511 dbgprintf("DeleteCriticalSection -> itemno=%d\n", i
);
1516 static int WINAPI
expGetCurrentThreadId(void)
1518 dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1519 return pthread_self();
1521 static int WINAPI
expGetCurrentProcess(void)
1523 dbgprintf("GetCurrentProcess() => %d\n", getpid());
1527 #ifdef CONFIG_QTX_CODECS
1528 // this version is required for Quicktime codecs (.qtx/.qts) to work.
1529 // (they assume some pointers at FS: segment)
1531 extern void* fs_seg
;
1533 //static int tls_count;
1534 static int tls_use_map
[64];
1535 static int WINAPI
expTlsAlloc(void)
1539 if(tls_use_map
[i
]==0)
1542 dbgprintf("TlsAlloc() => %d\n",i
);
1545 dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1549 //static int WINAPI expTlsSetValue(DWORD index, void* value)
1550 static int WINAPI
expTlsSetValue(int index
, void* value
)
1552 dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index
,value
);
1553 // if((index<0) || (index>64))
1556 *(void**)((char*)fs_seg
+0x88+4*index
) = value
;
1560 static void* WINAPI
expTlsGetValue(DWORD index
)
1562 dbgprintf("TlsGetValue(%d)\n",index
);
1563 // if((index<0) || (index>64))
1564 if((index
>=64)) return NULL
;
1565 return *(void**)((char*)fs_seg
+0x88+4*index
);
1568 static int WINAPI
expTlsFree(int idx
)
1570 int index
= (int) idx
;
1571 dbgprintf("TlsFree(%d)\n",index
);
1572 if((index
<0) || (index
>64))
1574 tls_use_map
[index
]=0;
1586 static void* WINAPI
expTlsAlloc(void)
1590 g_tls
=my_mreq(sizeof(tls_t
), 0);
1591 g_tls
->next
=g_tls
->prev
=NULL
;
1595 g_tls
->next
=my_mreq(sizeof(tls_t
), 0);
1596 g_tls
->next
->prev
=g_tls
;
1597 g_tls
->next
->next
=NULL
;
1600 dbgprintf("TlsAlloc() => 0x%x\n", g_tls
);
1602 g_tls
->value
=0; /* XXX For Divx.dll */
1606 static int WINAPI
expTlsSetValue(void* idx
, void* value
)
1608 tls_t
* index
= (tls_t
*) idx
;
1617 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index
, value
, result
);
1620 static void* WINAPI
expTlsGetValue(void* idx
)
1622 tls_t
* index
= (tls_t
*) idx
;
1627 result
=index
->value
;
1628 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index
, result
);
1631 static int WINAPI
expTlsFree(void* idx
)
1633 tls_t
* index
= (tls_t
*) idx
;
1640 index
->next
->prev
=index
->prev
;
1642 index
->prev
->next
=index
->next
;
1644 g_tls
= index
->prev
;
1645 my_release((void*)index
);
1648 dbgprintf("TlsFree(index 0x%x) => %d\n", index
, result
);
1653 static void* WINAPI
expLocalAlloc(int flags
, int size
)
1655 void* z
= my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1657 printf("LocalAlloc() failed\n");
1658 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1662 static void* WINAPI
expLocalReAlloc(int handle
,int size
, int flags
)
1668 if (flags
& LMEM_MODIFY
) {
1669 dbgprintf("LocalReAlloc MODIFY\n");
1670 return (void *)handle
;
1672 oldsize
= my_size((void *)handle
);
1673 newpointer
= my_realloc((void *)handle
,size
);
1674 dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle
,size
,oldsize
, flags
,newpointer
);
1679 static void* WINAPI
expLocalLock(void* z
)
1681 dbgprintf("LocalLock(0x%x) => 0x%x\n", z
, z
);
1685 static void* WINAPI
expGlobalAlloc(int flags
, int size
)
1688 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size
, flags
);
1690 z
=my_mreq(size
, (flags
& GMEM_ZEROINIT
));
1691 //z=calloc(size, 1);
1694 printf("GlobalAlloc() failed\n");
1695 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size
, flags
, z
);
1698 static void* WINAPI
expGlobalLock(void* z
)
1700 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z
, z
);
1703 // pvmjpg20 - but doesn't work anyway
1704 static int WINAPI
expGlobalSize(void* amem
)
1708 alloc_header
* header
= last_alloc
;
1709 alloc_header
* mem
= (alloc_header
*) amem
- 1;
1712 pthread_mutex_lock(&memmut
);
1715 if (header
->deadbeef
!= 0xdeadbeef)
1717 dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header
, header
->deadbeef
, alccnt
);
1723 size
= header
->size
;
1727 header
= header
->prev
;
1729 pthread_mutex_unlock(&memmut
);
1732 dbgprintf("GlobalSize(0x%x)\n", amem
);
1736 static int WINAPI
expLoadIconA( long hinstance
, char *name
)
1738 dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance
,name
);
1742 static int WINAPI
expLoadStringA(long instance
, long id
, void* buf
, long size
)
1744 int result
=LoadStringA(instance
, id
, buf
, size
);
1746 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1747 instance
, id
, buf
, size
, result
, buf
);
1749 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1750 // instance, id, buf, size, result);
1754 static long WINAPI
expMultiByteToWideChar(long v1
, long v2
, char* s1
, long siz1
, short* s2
, int siz2
)
1763 if(siz1
>siz2
/2)siz1
=siz2
/2;
1764 for(i
=1; i
<=siz1
; i
++)
1774 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1775 "size %d, dest buffer 0x%x, dest size %d) => %d\n",
1776 v1
, v2
, s1
, s1
, siz1
, s2
, siz2
, result
);
1778 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1779 "size %d, dest buffer 0x%x, dest size %d) =>\n",
1780 v1
, v2
, siz1
, s2
, siz2
, result
);
1783 static void wch_print(const short* str
)
1785 dbgprintf(" src: ");
1786 while(*str
)dbgprintf("%c", *str
++);
1789 static long WINAPI
expWideCharToMultiByte(long v1
, long v2
, short* s1
, long siz1
,
1790 char* s2
, int siz2
, char* c3
, int* siz3
)
1793 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1794 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1795 result
=WideCharToMultiByte(v1
, v2
, s1
, siz1
, s2
, siz2
, c3
, siz3
);
1796 dbgprintf("=> %d\n", result
);
1797 //if(s1)wch_print(s1);
1798 if(s2
)dbgprintf(" dest: %s\n", s2
);
1801 static long WINAPI
expGetVersionExA(OSVERSIONINFOA
* c
)
1803 dbgprintf("GetVersionExA(0x%x) => 1\n");
1804 c
->dwOSVersionInfoSize
=sizeof(*c
);
1805 c
->dwMajorVersion
=4;
1806 c
->dwMinorVersion
=0;
1807 c
->dwBuildNumber
=0x4000457;
1809 // leave it here for testing win9x-only codecs
1810 c
->dwPlatformId
=VER_PLATFORM_WIN32_WINDOWS
;
1811 strcpy(c
->szCSDVersion
, " B");
1813 c
->dwPlatformId
=VER_PLATFORM_WIN32_NT
; // let's not make DLL assume that it can read CR* registers
1814 strcpy(c
->szCSDVersion
, "Service Pack 3");
1816 dbgprintf(" Major version: 4\n Minor version: 0\n Build number: 0x4000457\n"
1817 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 3'\n");
1820 static HANDLE WINAPI
expCreateSemaphoreA(char* v1
, long init_count
,
1821 long max_count
, char* name
)
1823 pthread_mutex_t
*pm
;
1828 printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1832 printf("%p => ", pp);
1837 pthread_mutex_lock(&mlist_lock
);
1840 mutex_list
* pp
=mlist
;
1844 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==1))
1846 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1847 v1
, init_count
, max_count
, name
, name
, mlist
);
1848 ret
= (HANDLE
)mlist
;
1849 pthread_mutex_unlock(&mlist_lock
);
1852 }while((pp
=pp
->prev
) != NULL
);
1854 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
1855 pthread_mutex_init(pm
, NULL
);
1856 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
1857 pthread_cond_init(pc
, NULL
);
1860 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1861 mlist
->next
=mlist
->prev
=NULL
;
1865 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1866 mlist
->next
->prev
=mlist
;
1867 mlist
->next
->next
=NULL
;
1869 // printf("new semaphore %p\n", mlist);
1871 mlist
->type
=1; /* Type Semaphore */
1876 mlist
->semaphore
=init_count
;
1878 strncpy(mlist
->name
, name
, 64);
1882 dbgprintf("ERROR::: CreateSemaphoreA failure\n");
1884 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1885 v1
, init_count
, max_count
, name
, name
, mlist
);
1887 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1888 v1
, init_count
, max_count
, mlist
);
1889 ret
= (HANDLE
)mlist
;
1890 pthread_mutex_unlock(&mlist_lock
);
1894 static long WINAPI
expReleaseSemaphore(long hsem
, long increment
, long* prev_count
)
1896 // The state of a semaphore object is signaled when its count
1897 // is greater than zero and nonsignaled when its count is equal to zero
1898 // Each time a waiting thread is released because of the semaphore's signaled
1899 // state, the count of the semaphore is decreased by one.
1900 mutex_list
*ml
= (mutex_list
*)hsem
;
1902 pthread_mutex_lock(ml
->pm
);
1903 if (prev_count
!= 0) *prev_count
= ml
->semaphore
;
1904 if (ml
->semaphore
== 0) pthread_cond_signal(ml
->pc
);
1905 ml
->semaphore
+= increment
;
1906 pthread_mutex_unlock(ml
->pm
);
1907 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1908 hsem
, increment
, prev_count
);
1912 static HANDLE WINAPI
expCreateMutexA(void *pSecAttr
,
1913 char bInitialOwner
, const char *name
)
1915 pthread_mutex_t
*pm
;
1918 pthread_mutex_lock(&mlist_lock
);
1921 mutex_list
* pp
=mlist
;
1925 if((strcmp(pp
->name
, name
)==0) && (pp
->type
==2))
1927 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n", pSecAttr
, bInitialOwner
, name
, mlist
);
1928 ret
= (HANDLE
)mlist
;
1929 pthread_mutex_unlock(&mlist_lock
);
1932 }while((pp
=pp
->prev
) != NULL
);
1934 pm
=mreq_private(sizeof(pthread_mutex_t
), 0, AREATYPE_MUTEX
);
1935 pthread_mutex_init(pm
, NULL
);
1936 pc
=mreq_private(sizeof(pthread_cond_t
), 0, AREATYPE_COND
);
1937 pthread_cond_init(pc
, NULL
);
1940 mlist
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1941 mlist
->next
=mlist
->prev
=NULL
;
1945 mlist
->next
=mreq_private(sizeof(mutex_list
), 00, AREATYPE_EVENT
);
1946 mlist
->next
->prev
=mlist
;
1947 mlist
->next
->next
=NULL
;
1950 mlist
->type
=2; /* Type Mutex */
1956 if (bInitialOwner
) {
1957 mlist
->owner
= pthread_self();
1958 mlist
->lock_count
= 1;
1960 mlist
->owner
= (pthread_t
)0;
1961 mlist
->lock_count
= 0;
1964 strncpy(mlist
->name
, name
, 64);
1968 dbgprintf("ERROR::: CreateMutexA failure\n");
1970 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
1971 pSecAttr
, bInitialOwner
, name
, mlist
);
1973 dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
1974 pSecAttr
, bInitialOwner
, mlist
);
1975 ret
= (HANDLE
)mlist
;
1976 pthread_mutex_unlock(&mlist_lock
);
1980 static int WINAPI
expReleaseMutex(HANDLE hMutex
)
1982 mutex_list
*ml
= (mutex_list
*)hMutex
;
1984 pthread_mutex_lock(ml
->pm
);
1985 if (--ml
->lock_count
== 0) pthread_cond_signal(ml
->pc
);
1986 pthread_mutex_unlock(ml
->pm
);
1990 static DWORD WINAPI
expSignalObjectAndWait(HANDLE hObjectToSignal
,
1991 HANDLE hObjectToWaitOn
,
1992 DWORD dwMilliseconds
,
1993 WIN_BOOL bAlertable
) {
1994 mutex_list
* mlist
= (mutex_list
*)hObjectToSignal
;
1996 switch (mlist
->type
) {
2000 case 1: // Semaphore
2001 expReleaseSemaphore(mlist
, 1, NULL
);
2004 expReleaseMutex(mlist
);
2007 dbgprintf("Signalling unknown object type %d!\n", hObjectToSignal
);
2009 return expWaitForSingleObject(hObjectToWaitOn
, dwMilliseconds
);
2012 static long WINAPI
expRegOpenKeyExA(long key
, const char* subkey
, long reserved
, long access
, int* newkey
)
2014 long result
=RegOpenKeyExA(key
, subkey
, reserved
, access
, newkey
);
2015 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
2016 key
, subkey
, reserved
, access
, newkey
, result
);
2017 if(newkey
)dbgprintf(" New key: 0x%x\n", *newkey
);
2020 static long WINAPI
expRegCloseKey(long key
)
2022 long result
=RegCloseKey(key
);
2023 dbgprintf("RegCloseKey(0x%x) => %d\n", key
, result
);
2026 static long WINAPI
expRegQueryValueExA(long key
, const char* value
, int* reserved
, int* type
, int* data
, int* count
)
2028 long result
=RegQueryValueExA(key
, value
, reserved
, type
, data
, count
);
2029 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
2030 " => 0x%x\n", key
, value
, reserved
, data
, count
, result
);
2031 if(data
&& count
)dbgprintf(" read %d bytes: '%s'\n", *count
, data
);
2035 //from wine source dlls/advapi32/registry.c
2036 static long WINAPI
expRegCreateKeyA(long hkey
, const char* name
, int *retkey
)
2038 dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey
,name
,retkey
);
2039 return RegCreateKeyExA( hkey
, name
, 0, NULL
,REG_OPTION_NON_VOLATILE
,
2040 KEY_ALL_ACCESS
, NULL
, retkey
, NULL
);
2043 static long WINAPI
expRegCreateKeyExA(long key
, const char* name
, long reserved
,
2044 void* classs
, long options
, long security
,
2045 void* sec_attr
, int* newkey
, int* status
)
2047 long result
=RegCreateKeyExA(key
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
);
2048 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
2049 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
2050 key
, name
, name
, reserved
, classs
, options
, security
, sec_attr
, newkey
, status
, result
);
2051 if(!result
&& newkey
) dbgprintf(" New key: 0x%x\n", *newkey
);
2052 if(!result
&& status
) dbgprintf(" New key status: 0x%x\n", *status
);
2055 static long WINAPI
expRegSetValueExA(long key
, const char* name
, long v1
, long v2
, void* data
, long size
)
2057 long result
=RegSetValueExA(key
, name
, v1
, v2
, data
, size
);
2058 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
2059 key
, name
, v1
, v2
, data
, *(int*)data
, data
, size
, result
);
2063 static long WINAPI
expRegOpenKeyA (long hKey
, LPCSTR lpSubKey
, int* phkResult
)
2065 long result
=RegOpenKeyExA(hKey
, lpSubKey
, 0, 0, phkResult
);
2066 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
2067 hKey
, lpSubKey
, phkResult
, result
);
2068 if(!result
&& phkResult
) dbgprintf(" New key: 0x%x\n", *phkResult
);
2072 static DWORD WINAPI
expRegEnumValueA(HKEY hkey
, DWORD index
, LPSTR value
, LPDWORD val_count
,
2073 LPDWORD reserved
, LPDWORD type
, LPBYTE data
, LPDWORD count
)
2075 return RegEnumValueA(hkey
, index
, value
, val_count
,
2076 reserved
, type
, data
, count
);
2079 static DWORD WINAPI
expRegEnumKeyExA(HKEY hKey
, DWORD dwIndex
, LPSTR lpName
, LPDWORD lpcbName
,
2080 LPDWORD lpReserved
, LPSTR lpClass
, LPDWORD lpcbClass
,
2081 LPFILETIME lpftLastWriteTime
)
2083 return RegEnumKeyExA(hKey
, dwIndex
, lpName
, lpcbName
, lpReserved
, lpClass
,
2084 lpcbClass
, lpftLastWriteTime
);
2087 static long WINAPI
expQueryPerformanceCounter(long long* z
)
2090 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z
, *z
);
2095 * dummy function RegQueryInfoKeyA(), required by vss codecs
2097 static DWORD WINAPI
expRegQueryInfoKeyA( HKEY hkey
, LPSTR
class, LPDWORD class_len
, LPDWORD reserved
,
2098 LPDWORD subkeys
, LPDWORD max_subkey
, LPDWORD max_class
,
2099 LPDWORD values
, LPDWORD max_value
, LPDWORD max_data
,
2100 LPDWORD security
, FILETIME
*modif
)
2102 return ERROR_SUCCESS
;
2106 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
2108 static double linux_cpuinfo_freq(void)
2115 f
= fopen ("/proc/cpuinfo", "r");
2117 while (fgets(line
,sizeof(line
),f
)!=NULL
) {
2118 /* NOTE: the ':' is the only character we can rely on */
2119 if (!(value
= strchr(line
,':')))
2121 /* terminate the valuename */
2123 /* skip any leading spaces */
2124 while (*value
==' ') value
++;
2125 if ((s
=strchr(value
,'\n')))
2128 if (!strncasecmp(line
, "cpu MHz",strlen("cpu MHz"))
2129 && sscanf(value
, "%lf", &freq
) == 1) {
2140 static double solaris_kstat_freq(void)
2142 #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
2144 * try to extract the CPU speed from the solaris kernel's kstat data
2148 kstat_named_t
*kdata
;
2154 ksp
= kstat_lookup(kc
, "cpu_info", 0, "cpu_info0");
2156 /* kstat found and name/value pairs? */
2157 if (ksp
!= NULL
&& ksp
->ks_type
== KSTAT_TYPE_NAMED
)
2159 /* read the kstat data from the kernel */
2160 if (kstat_read(kc
, ksp
, NULL
) != -1)
2163 * lookup desired "clock_MHz" entry, check the expected
2166 kdata
= (kstat_named_t
*)kstat_data_lookup(ksp
, "clock_MHz");
2167 if (kdata
!= NULL
&& kdata
->data_type
== KSTAT_DATA_INT32
)
2168 mhz
= kdata
->value
.i32
;
2176 #endif /* HAVE_LIBKSTAT */
2177 return -1; // kstat stuff is not available, CPU freq is unknown
2181 * Measure CPU freq using the pentium's time stamp counter register (TSC)
2183 static double tsc_freq(void)
2185 static double ofreq
=0.0;
2189 if (ofreq
!= 0.0) return ofreq
;
2190 while(i
==time(NULL
));
2193 while(i
==time(NULL
));
2195 ofreq
= (double)(y
-x
)/1000.;
2199 static double CPU_Freq(void)
2203 if ((freq
= linux_cpuinfo_freq()) > 0)
2206 if ((freq
= solaris_kstat_freq()) > 0)
2212 static long WINAPI
expQueryPerformanceFrequency(long long* z
)
2214 *z
=(long long)CPU_Freq();
2215 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z
, *z
);
2218 static long WINAPI
exptimeGetTime(void)
2222 gettimeofday(&t
, 0);
2223 result
=1000*t
.tv_sec
+t
.tv_usec
/1000;
2224 dbgprintf("timeGetTime() => %d\n", result
);
2227 static void* WINAPI
expLocalHandle(void* v
)
2229 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v
, v
);
2233 static void* WINAPI
expGlobalHandle(void* v
)
2235 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v
, v
);
2238 static int WINAPI
expGlobalUnlock(void* v
)
2240 dbgprintf("GlobalUnlock(0x%x) => 1\n", v
);
2243 static void* WINAPI
expGlobalFree(void* v
)
2245 dbgprintf("GlobalFree(0x%x) => 0\n", v
);
2251 static void* WINAPI
expGlobalReAlloc(void* v
, int size
, int flags
)
2253 void* result
=my_realloc(v
, size
);
2254 //void* result=realloc(v, size);
2255 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v
,size
,flags
,result
);
2259 static int WINAPI
expLocalUnlock(void* v
)
2261 dbgprintf("LocalUnlock(0x%x) => 1\n", v
);
2265 static void* WINAPI
expLocalFree(void* v
)
2267 dbgprintf("LocalFree(0x%x) => 0\n", v
);
2271 static HRSRC WINAPI
expFindResourceA(HMODULE module
, char* name
, char* type
)
2275 result
=FindResourceA(module
, name
, type
);
2276 dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2277 module
, name
, HIWORD(name
) ? name
: "UNICODE", type
, HIWORD(type
) ? type
: "UNICODE", result
);
2281 static HGLOBAL WINAPI
expLoadResource(HMODULE module
, HRSRC res
)
2283 HGLOBAL result
=LoadResource(module
, res
);
2284 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module
, res
, result
);
2287 static void* WINAPI
expLockResource(long res
)
2289 void* result
=LockResource(res
);
2290 dbgprintf("LockResource(0x%x) => 0x%x\n", res
, result
);
2293 static int WINAPI
expFreeResource(long res
)
2295 int result
=FreeResource(res
);
2296 dbgprintf("FreeResource(0x%x) => %d\n", res
, result
);
2301 static int WINAPI
expCloseHandle(long v1
)
2303 dbgprintf("CloseHandle(0x%x) => 1\n", v1
);
2304 /* do not close stdin,stdout and stderr */
2311 static const char* WINAPI
expGetCommandLineA(void)
2313 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2314 return "c:\\aviplay.exe";
2316 static short envs
[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2317 static LPWSTR WINAPI
expGetEnvironmentStringsW(void)
2319 dbgprintf("GetEnvironmentStringsW() => 0\n", envs
);
2322 static void * WINAPI
expRtlZeroMemory(void *p
, size_t len
)
2324 void* result
=memset(p
,0,len
);
2325 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p
,len
,result
);
2328 static void * WINAPI
expRtlMoveMemory(void *dst
, void *src
, size_t len
)
2330 void* result
=memmove(dst
,src
,len
);
2331 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst
,src
,len
,result
);
2335 static void * WINAPI
expRtlFillMemory(void *p
, int ch
, size_t len
)
2337 void* result
=memset(p
,ch
,len
);
2338 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p
,ch
,len
,result
);
2341 static int WINAPI
expFreeEnvironmentStringsW(short* strings
)
2343 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings
);
2346 static int WINAPI
expFreeEnvironmentStringsA(char* strings
)
2348 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings
);
2352 static const char ch_envs
[]=
2353 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2354 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2355 static LPCSTR WINAPI
expGetEnvironmentStrings(void)
2357 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs
);
2358 return (LPCSTR
)ch_envs
;
2359 // dbgprintf("GetEnvironmentStrings() => 0\n");
2363 static int WINAPI
expGetStartupInfoA(STARTUPINFOA
*s
)
2365 dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2366 memset(s
, 0, sizeof(*s
));
2368 // s->lpReserved="Reserved";
2369 // s->lpDesktop="Desktop";
2370 // s->lpTitle="Title";
2372 // s->dwXSize=s->dwYSize=200;
2373 s
->dwFlags
=s
->wShowWindow
=1;
2374 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2375 dbgprintf(" cb=%d\n", s
->cb
);
2376 dbgprintf(" lpReserved='%s'\n", s
->lpReserved
);
2377 dbgprintf(" lpDesktop='%s'\n", s
->lpDesktop
);
2378 dbgprintf(" lpTitle='%s'\n", s
->lpTitle
);
2379 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2380 s
->dwX
, s
->dwY
, s
->dwXSize
, s
->dwYSize
);
2381 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2382 s
->dwXCountChars
, s
->dwYCountChars
, s
->dwFillAttribute
);
2383 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2384 s
->dwFlags
, s
->wShowWindow
, s
->cbReserved2
);
2385 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2386 s
->lpReserved2
, s
->hStdInput
, s
->hStdOutput
, s
->hStdError
);
2390 static int WINAPI
expGetStdHandle(int z
)
2392 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z
+0x1234);
2396 #ifdef CONFIG_QTX_CODECS
2397 #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2398 #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2401 static int WINAPI
expGetFileType(int handle
)
2403 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle
);
2406 #ifdef CONFIG_QTX_CODECS
2407 static int WINAPI
expGetFileAttributesA(char *filename
)
2409 dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename
);
2410 if (strstr(filename
, "QuickTime.qts"))
2411 return FILE_ATTRIBUTE_SYSTEM
;
2412 return FILE_ATTRIBUTE_NORMAL
;
2415 static int WINAPI
expSetHandleCount(int count
)
2417 dbgprintf("SetHandleCount(0x%x) => 1\n", count
);
2420 static int WINAPI
expGetACP(void)
2422 dbgprintf("GetACP() => 0\n");
2425 static int WINAPI
expGetModuleFileNameA(int module
, char* s
, int len
)
2429 //printf("File name of module %X (%s) requested\n", module, s);
2431 if (module
== 0 && len
>= 12)
2433 /* return caller program name */
2434 strcpy(s
, "aviplay.dll");
2445 strcpy(s
, "c:\\windows\\system\\");
2446 mr
=MODULE32_LookupHMODULE(module
);
2448 strcat(s
, "aviplay.dll");
2450 if(strrchr(mr
->filename
, '/')==NULL
)
2451 strcat(s
, mr
->filename
);
2453 strcat(s
, strrchr(mr
->filename
, '/')+1);
2456 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2457 module
, s
, len
, result
);
2459 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2460 module
, s
, len
, result
, s
);
2464 static int WINAPI
expGetModuleBaseNameA(int process
, int module
, char* s
, int len
)
2469 av_strlcpy(s
, "aviplay.dll", len
);
2473 dbgprintf("GetModuleBaseNameA(0x%x, 0x%x, 0x%x, %d) => %d\n",
2474 process
, module
, s
, len
, result
);
2479 static int WINAPI
expSetUnhandledExceptionFilter(void* filter
)
2481 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter
);
2482 return 1;//unsupported and probably won't ever be supported
2485 static int WINAPI
expLoadLibraryA(char* name
)
2491 // we skip to the last backslash
2492 // this is effectively eliminating weird characters in
2493 // the text output windows
2495 lastbc
= strrchr(name
, '\\');
2502 name
[i
] = *lastbc
++;
2507 if(strncmp(name
, "c:\\windows\\", 11)==0) name
+= 11;
2508 if(strncmp(name
, ".\\", 2)==0) name
+= 2;
2510 dbgprintf("Entering LoadLibraryA(%s)\n", name
);
2512 // PIMJ and VIVO audio are loading kernel32.dll
2513 if (strcasecmp(name
, "kernel32.dll") == 0 || strcasecmp(name
, "kernel32") == 0)
2514 return MODULE_HANDLE_kernel32
;
2515 // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2516 /* exported -> do not return failed! */
2518 if (strcasecmp(name
, "user32.dll") == 0 || strcasecmp(name
, "user32") == 0)
2519 // return MODULE_HANDLE_kernel32;
2520 return MODULE_HANDLE_user32
;
2522 #ifdef CONFIG_QTX_CODECS
2523 if (strcasecmp(name
, "wininet.dll") == 0 || strcasecmp(name
, "wininet") == 0)
2524 return MODULE_HANDLE_wininet
;
2525 if (strcasecmp(name
, "ddraw.dll") == 0 || strcasecmp(name
, "ddraw") == 0)
2526 return MODULE_HANDLE_ddraw
;
2527 if (strcasecmp(name
, "advapi32.dll") == 0 || strcasecmp(name
, "advapi32") == 0)
2528 return MODULE_HANDLE_advapi32
;
2531 if (strcasecmp(name
, "comdlg32.dll") == 0 || strcasecmp(name
, "comdlg32") == 0)
2532 return MODULE_HANDLE_comdlg32
;
2533 if (strcasecmp(name
, "msvcrt.dll") == 0 || strcasecmp(name
, "msvcrt") == 0)
2534 return MODULE_HANDLE_msvcrt
;
2535 if (strcasecmp(name
, "ole32.dll") == 0 || strcasecmp(name
, "ole32") == 0)
2536 return MODULE_HANDLE_ole32
;
2537 if (strcasecmp(name
, "winmm.dll") == 0 || strcasecmp(name
, "winmm") == 0)
2538 return MODULE_HANDLE_winmm
;
2539 if (strcasecmp(name
, "psapi.dll") == 0 || strcasecmp(name
, "psapi") == 0)
2540 return MODULE_HANDLE_psapi
;
2542 result
=LoadLibraryA(name
);
2543 dbgprintf("Returned LoadLibraryA(0x%x='%s'), def_path=%s => 0x%x\n", name
, name
, def_path
, result
);
2548 static int WINAPI
expFreeLibrary(int module
)
2550 #ifdef CONFIG_QTX_CODECS
2551 int result
=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2553 int result
=FreeLibrary(module
);
2555 dbgprintf("FreeLibrary(0x%x) => %d\n", module
, result
);
2559 static void* WINAPI
expGetProcAddress(HMODULE mod
, char* name
)
2563 case MODULE_HANDLE_kernel32
:
2564 result
=LookupExternalByName("kernel32.dll", name
); break;
2565 case MODULE_HANDLE_user32
:
2566 result
=LookupExternalByName("user32.dll", name
); break;
2567 #ifdef CONFIG_QTX_CODECS
2568 case MODULE_HANDLE_wininet
:
2569 result
=LookupExternalByName("wininet.dll", name
); break;
2570 case MODULE_HANDLE_ddraw
:
2571 result
=LookupExternalByName("ddraw.dll", name
); break;
2572 case MODULE_HANDLE_advapi32
:
2573 result
=LookupExternalByName("advapi32.dll", name
); break;
2575 case MODULE_HANDLE_comdlg32
:
2576 result
=LookupExternalByName("comdlg32.dll", name
); break;
2577 case MODULE_HANDLE_msvcrt
:
2578 result
=LookupExternalByName("msvcrt.dll", name
); break;
2579 case MODULE_HANDLE_ole32
:
2580 result
=LookupExternalByName("ole32.dll", name
); break;
2581 case MODULE_HANDLE_winmm
:
2582 result
=LookupExternalByName("winmm.dll", name
); break;
2583 case MODULE_HANDLE_psapi
:
2584 result
=LookupExternalByName("psapi.dll", name
); break;
2586 result
=GetProcAddress(mod
, name
);
2588 if((unsigned int)name
> 0xffff)
2589 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod
, name
, result
);
2591 dbgprintf("GetProcAddress(0x%x, '%d') => 0x%x\n", mod
, (int)name
, result
);
2595 static long WINAPI
expCreateFileMappingA(int hFile
, void* lpAttr
,
2596 long flProtect
, long dwMaxHigh
,
2597 long dwMaxLow
, const char* name
)
2599 long result
=CreateFileMappingA(hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
);
2601 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2602 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2603 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, result
);
2605 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2606 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2607 hFile
, lpAttr
, flProtect
, dwMaxHigh
, dwMaxLow
, name
, name
, result
);
2611 static long WINAPI
expOpenFileMappingA(long hFile
, long hz
, const char* name
)
2613 long result
=OpenFileMappingA(hFile
, hz
, name
);
2615 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2618 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2619 hFile
, hz
, name
, name
, result
);
2623 static void* WINAPI
expMapViewOfFile(HANDLE file
, DWORD mode
, DWORD offHigh
,
2624 DWORD offLow
, DWORD size
)
2626 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2627 file
,mode
,offHigh
,offLow
,size
,(char*)file
+offLow
);
2628 return (char*)file
+offLow
;
2631 static void* WINAPI
expUnmapViewOfFile(void* view
)
2633 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view
);
2637 static void* WINAPI
expSleep(int time
)
2640 /* solaris doesn't have thread safe usleep */
2641 struct timespec tsp
;
2642 tsp
.tv_sec
= time
/ 1000000;
2643 tsp
.tv_nsec
= (time
% 1000000) * 1000;
2644 nanosleep(&tsp
, NULL
);
2648 dbgprintf("Sleep(%d) => 0\n", time
);
2652 // why does IV32 codec want to call this? I don't know ...
2653 static int WINAPI
expCreateCompatibleDC(int hdc
)
2656 //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2657 dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc
, dc
);
2661 static int WINAPI
expGetDeviceCaps(int hdc
, int unk
)
2663 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc
, unk
);
2664 #ifdef CONFIG_QTX_CODECS
2665 #define BITSPIXEL 12
2667 if (unk
== BITSPIXEL
)
2675 static WIN_BOOL WINAPI
expDeleteDC(int hdc
)
2677 dbgprintf("DeleteDC(0x%x) => 0\n", hdc
);
2683 static WIN_BOOL WINAPI
expDeleteObject(int hdc
)
2685 dbgprintf("DeleteObject(0x%x) => 1\n", hdc
);
2686 /* FIXME - implement code here */
2690 /* btvvc32.drv wants this one */
2691 static void* WINAPI
expGetWindowDC(int hdc
)
2693 dbgprintf("GetWindowDC(%d) => 0x0\n", hdc
);
2697 #ifdef CONFIG_QTX_CODECS
2698 static int WINAPI
expGetWindowRect(HWND win
, RECT
*r
)
2700 dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win
, r
);
2701 /* (win == 0) => desktop */
2702 r
->right
= PSEUDO_SCREEN_WIDTH
;
2704 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
2709 static int WINAPI
expMonitorFromWindow(HWND win
, int flags
)
2711 dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win
, flags
);
2715 static int WINAPI
expMonitorFromRect(RECT
*r
, int flags
)
2717 dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r
, flags
);
2721 static int WINAPI
expMonitorFromPoint(void *p
, int flags
)
2723 dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p
, flags
);
2727 static int WINAPI
expEnumDisplayMonitors(void *dc
, RECT
*r
,
2728 int WINAPI (*callback_proc
)(), void *callback_param
)
2730 dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2731 dc
, r
, callback_proc
, callback_param
);
2732 return callback_proc(0, dc
, r
, callback_param
);
2736 typedef struct tagMONITORINFO
{
2741 } MONITORINFO
, *LPMONITORINFO
;
2744 #define CCHDEVICENAME 8
2745 typedef struct tagMONITORINFOEX
{
2750 TCHAR szDevice
[CCHDEVICENAME
];
2751 } MONITORINFOEX
, *LPMONITORINFOEX
;
2753 static int WINAPI
expGetMonitorInfoA(void *mon
, LPMONITORINFO lpmi
)
2755 dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon
, lpmi
);
2757 lpmi
->rcMonitor
.right
= lpmi
->rcWork
.right
= PSEUDO_SCREEN_WIDTH
;
2758 lpmi
->rcMonitor
.left
= lpmi
->rcWork
.left
= 0;
2759 lpmi
->rcMonitor
.bottom
= lpmi
->rcWork
.bottom
= PSEUDO_SCREEN_HEIGHT
;
2760 lpmi
->rcMonitor
.top
= lpmi
->rcWork
.top
= 0;
2762 lpmi
->dwFlags
= 1; /* primary monitor */
2764 if (lpmi
->cbSize
== sizeof(MONITORINFOEX
))
2766 LPMONITORINFOEX lpmiex
= (LPMONITORINFOEX
)lpmi
;
2767 dbgprintf("MONITORINFOEX!\n");
2768 strncpy(lpmiex
->szDevice
, "Monitor1", CCHDEVICENAME
);
2774 static int WINAPI
expEnumDisplayDevicesA(const char *device
, int devnum
,
2775 void *dispdev
, int flags
)
2777 dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2778 device
, device
, devnum
, dispdev
, flags
);
2782 static int WINAPI
expIsWindowVisible(HWND win
)
2784 dbgprintf("IsWindowVisible(0x%x) => 1\n", win
);
2788 static HWND WINAPI
expGetActiveWindow(void)
2790 dbgprintf("GetActiveWindow() => 0\n");
2794 static int WINAPI
expGetClassNameA(HWND win
, LPTSTR classname
, int maxcount
)
2796 strncat(classname
, "QuickTime", maxcount
);
2797 dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2798 win
, classname
, maxcount
, strlen(classname
));
2799 return strlen(classname
);
2802 #define LPWNDCLASS void *
2803 static int WINAPI
expGetClassInfoA(HINSTANCE inst
, LPCSTR classname
, LPWNDCLASS wndclass
)
2805 dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst
,
2806 classname
, classname
, wndclass
);
2810 static int WINAPI
expGetWindowLongA(HWND win
, int index
)
2812 dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win
, index
);
2816 static int WINAPI
expGetObjectA(HGDIOBJ hobj
, int objsize
, LPVOID obj
)
2818 dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj
, objsize
, obj
, objsize
);
2822 static int WINAPI
expCreateRectRgn(int x
, int y
, int width
, int height
)
2824 dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x
, y
, width
, height
);
2828 static int WINAPI
expEnumWindows(int (*callback_func
)(), void *callback_param
)
2831 dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func
, callback_param
);
2832 i
= callback_func(0, callback_param
);
2833 i2
= callback_func(1, callback_param
);
2837 static int WINAPI
expGetWindowThreadProcessId(HWND win
, int *pid_data
)
2839 int tid
= pthread_self();
2840 dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2841 win
, pid_data
, tid
);
2843 *(int*)pid_data
= tid
;
2847 //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2848 // INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2850 static HWND WINAPI
expCreateWindowExA(int exstyle
, const char *classname
,
2851 const char *winname
, int style
, int x
, int y
, int w
, int h
,
2852 HWND parent
, HMENU menu
, HINSTANCE inst
, LPVOID param
)
2854 printf("CreateWindowEx() called\n");
2855 dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2856 exstyle
, classname
, classname
, winname
, winname
, style
, x
, y
, w
, h
,
2857 parent
, menu
, inst
, param
);
2858 printf("CreateWindowEx() called okey\n");
2862 static int WINAPI
expwaveOutGetNumDevs(void)
2864 dbgprintf("waveOutGetNumDevs() => 0\n");
2870 * Returns the number of milliseconds, modulo 2^32, since the start
2871 * of the wineserver.
2873 static int WINAPI
expGetTickCount(void)
2875 static int tcstart
= 0;
2878 gettimeofday( &t
, NULL
);
2879 tc
= ((t
.tv_sec
* 1000) + (t
.tv_usec
/ 1000)) - tcstart
;
2885 dbgprintf("GetTickCount() => %d\n", tc
);
2889 static int WINAPI
expCreateFontA(void)
2891 dbgprintf("CreateFontA() => 0x0\n");
2895 /* tried to get pvmjpg work in a different way - no success */
2896 static int WINAPI
expDrawTextA(int hDC
, char* lpString
, int nCount
,
2897 LPRECT lpRect
, unsigned int uFormat
)
2899 dbgprintf("expDrawTextA(%p,...) => 8\n", hDC
);
2903 static int WINAPI
expGetPrivateProfileIntA(const char* appname
,
2904 const char* keyname
,
2906 const char* filename
)
2914 if(!(appname
&& keyname
&& filename
) )
2916 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, default_value
);
2917 return default_value
;
2919 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2920 strcpy(fullname
, "Software\\IniFileMapping\\");
2921 strcat(fullname
, appname
);
2922 strcat(fullname
, "\\");
2923 strcat(fullname
, keyname
);
2924 strcat(fullname
, "\\");
2925 strcat(fullname
, filename
);
2926 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)buffer
, &size
);
2927 if((size
>=0)&&(size
<256))
2929 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2932 result
=default_value
;
2934 result
=atoi(buffer
);
2935 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname
, keyname
, default_value
, filename
, result
);
2938 static int WINAPI
expGetProfileIntA(const char* appname
,
2939 const char* keyname
,
2942 dbgprintf("GetProfileIntA -> ");
2943 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, "default");
2946 static int WINAPI
expGetPrivateProfileStringA(const char* appname
,
2947 const char* keyname
,
2948 const char* def_val
,
2949 char* dest
, unsigned int len
,
2950 const char* filename
)
2955 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname
, keyname
, def_val
, dest
, len
, filename
);
2956 if(!(appname
&& keyname
&& filename
) ) return 0;
2957 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2958 strcpy(fullname
, "Software\\IniFileMapping\\");
2959 strcat(fullname
, appname
);
2960 strcat(fullname
, "\\");
2961 strcat(fullname
, keyname
);
2962 strcat(fullname
, "\\");
2963 strcat(fullname
, filename
);
2965 result
=RegQueryValueExA(HKEY_LOCAL_MACHINE
, fullname
, NULL
, NULL
, (int*)dest
, &size
);
2969 strncpy(dest
, def_val
, size
);
2970 if (strlen(def_val
)< size
) size
= strlen(def_val
);
2972 dbgprintf(" => %d ( '%s' )\n", size
, dest
);
2975 static int WINAPI
expWritePrivateProfileStringA(const char* appname
,
2976 const char* keyname
,
2978 const char* filename
)
2981 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname
, keyname
, string
, filename
);
2982 if(!(appname
&& keyname
&& filename
) )
2984 dbgprintf(" => -1\n");
2987 fullname
=malloc(50+strlen(appname
)+strlen(keyname
)+strlen(filename
));
2988 strcpy(fullname
, "Software\\IniFileMapping\\");
2989 strcat(fullname
, appname
);
2990 strcat(fullname
, "\\");
2991 strcat(fullname
, keyname
);
2992 strcat(fullname
, "\\");
2993 strcat(fullname
, filename
);
2994 RegSetValueExA(HKEY_LOCAL_MACHINE
, fullname
, 0, REG_SZ
, (int*)string
, strlen(string
));
2995 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
2996 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
2998 dbgprintf(" => 0\n");
3002 unsigned int GetPrivateProfileIntA_(const char* appname
, const char* keyname
, INT default_value
, const char* filename
)
3004 return expGetPrivateProfileIntA(appname
, keyname
, default_value
, filename
);
3006 int GetPrivateProfileStringA_(const char* appname
, const char* keyname
,
3007 const char* def_val
, char* dest
, unsigned int len
, const char* filename
)
3009 return expGetPrivateProfileStringA(appname
, keyname
, def_val
, dest
, len
, filename
);
3011 int WritePrivateProfileStringA_(const char* appname
, const char* keyname
,
3012 const char* string
, const char* filename
)
3014 return expWritePrivateProfileStringA(appname
, keyname
, string
, filename
);
3019 static int WINAPI
expDefDriverProc(int private, int id
, int msg
, int arg1
, int arg2
)
3021 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", private, id
, msg
, arg1
, arg2
);
3025 static int WINAPI
expSizeofResource(int v1
, int v2
)
3027 int result
=SizeofResource(v1
, v2
);
3028 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1
, v2
, result
);
3032 static int WINAPI
expGetLastError(void)
3034 int result
=GetLastError();
3035 dbgprintf("GetLastError() => 0x%x\n", result
);
3039 static void WINAPI
expSetLastError(int error
)
3041 dbgprintf("SetLastError(0x%x)\n", error
);
3042 SetLastError(error
);
3045 static int WINAPI
expStringFromGUID2(GUID
* guid
, char* str
, int cbMax
)
3047 int result
=snprintf(str
, cbMax
, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
3048 guid
->f1
, guid
->f2
, guid
->f3
,
3049 (unsigned char)guid
->f4
[0], (unsigned char)guid
->f4
[1],
3050 (unsigned char)guid
->f4
[2], (unsigned char)guid
->f4
[3],
3051 (unsigned char)guid
->f4
[4], (unsigned char)guid
->f4
[5],
3052 (unsigned char)guid
->f4
[6], (unsigned char)guid
->f4
[7]);
3053 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid
, str
, str
, cbMax
, result
);
3058 static int WINAPI
expGetFileVersionInfoSizeA(const char* name
, int* lpHandle
)
3060 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name
, name
, lpHandle
);
3064 static int WINAPI
expIsBadStringPtrW(const short* string
, int nchars
)
3067 if(string
==0)result
=1; else result
=0;
3068 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string
, nchars
, result
);
3069 if(string
)wch_print(string
);
3072 static int WINAPI
expIsBadStringPtrA(const char* string
, int nchars
)
3074 return expIsBadStringPtrW((const short*)string
, nchars
);
3076 static long WINAPI
expInterlockedExchangeAdd( long* dest
, long incr
)
3081 "lock; xaddl %0,(%1)"
3083 : "r" (dest
), "0" (incr
)
3089 static long WINAPI
expInterlockedCompareExchange( unsigned long* dest
, unsigned long exchange
, unsigned long comperand
)
3091 unsigned long retval
= *dest
;
3092 if(*dest
== comperand
)
3097 static long WINAPI
expInterlockedIncrement( long* dest
)
3099 long result
=expInterlockedExchangeAdd( dest
, 1 ) + 1;
3100 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
3103 static long WINAPI
expInterlockedDecrement( long* dest
)
3105 long result
=expInterlockedExchangeAdd( dest
, -1 ) - 1;
3106 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest
, *dest
, result
);
3110 static void WINAPI
expOutputDebugStringA( const char* string
)
3112 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string
);
3113 fprintf(stderr
, "DEBUG: %s\n", string
);
3116 static int WINAPI
expGetDC(int hwnd
)
3118 dbgprintf("GetDC(0x%x) => 1\n", hwnd
);
3122 static int WINAPI
expReleaseDC(int hwnd
, int hdc
)
3124 dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd
, hdc
);
3128 static int WINAPI
expGetDesktopWindow(void)
3130 dbgprintf("GetDesktopWindow() => 0\n");
3134 static int cursor
[100];
3136 static int WINAPI
expLoadCursorA(int handle
,LPCSTR name
)
3138 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle
, name
, (int)&cursor
[0]);
3139 return (int)&cursor
[0];
3141 static int WINAPI
expSetCursor(void *cursor
)
3143 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor
, cursor
);
3146 static int WINAPI
expGetCursorPos(void *cursor
)
3148 dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor
, cursor
);
3151 #ifdef CONFIG_QTX_CODECS
3152 static int show_cursor
= 0;
3153 static int WINAPI
expShowCursor(int show
)
3155 dbgprintf("ShowCursor(%d) => %d\n", show
, show
);
3163 static int WINAPI
expRegisterWindowMessageA(char *message
)
3165 dbgprintf("RegisterWindowMessageA(%s)\n", message
);
3168 static int WINAPI
expGetProcessVersion(int pid
)
3170 dbgprintf("GetProcessVersion(%d)\n", pid
);
3173 static int WINAPI
expGetCurrentThread(void)
3176 dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
3179 static int WINAPI
expGetOEMCP(void)
3181 dbgprintf("GetOEMCP()\n");
3184 static int WINAPI
expGetCPInfo(int cp
,void *info
)
3186 dbgprintf("GetCPInfo()\n");
3189 #ifdef CONFIG_QTX_CODECS
3190 #define SM_CXSCREEN 0
3191 #define SM_CYSCREEN 1
3192 #define SM_XVIRTUALSCREEN 76
3193 #define SM_YVIRTUALSCREEN 77
3194 #define SM_CXVIRTUALSCREEN 78
3195 #define SM_CYVIRTUALSCREEN 79
3196 #define SM_CMONITORS 80
3198 static int WINAPI
expGetSystemMetrics(int index
)
3200 dbgprintf("GetSystemMetrics(%d)\n", index
);
3201 #ifdef CONFIG_QTX_CODECS
3204 case SM_XVIRTUALSCREEN
:
3205 case SM_YVIRTUALSCREEN
:
3208 case SM_CXVIRTUALSCREEN
:
3209 return PSEUDO_SCREEN_WIDTH
;
3211 case SM_CYVIRTUALSCREEN
:
3212 return PSEUDO_SCREEN_HEIGHT
;
3219 static int WINAPI
expGetSysColor(int index
)
3221 dbgprintf("GetSysColor(%d) => 1\n", index
);
3224 static int WINAPI
expGetSysColorBrush(int index
)
3226 dbgprintf("GetSysColorBrush(%d)\n", index
);
3232 static int WINAPI
expGetSystemPaletteEntries(int hdc
, int iStartIndex
, int nEntries
, void* lppe
)
3234 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3235 hdc
, iStartIndex
, nEntries
, lppe
);
3240 typedef struct TIME_ZONE_INFORMATION {
3242 char StandardName[32];
3243 SYSTEMTIME StandardDate;
3245 char DaylightName[32];
3246 SYSTEMTIME DaylightDate;
3248 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3251 static int WINAPI
expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation
)
3253 const short name
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3254 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3255 const short pname
[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3256 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3257 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3258 memset(lpTimeZoneInformation
, 0, sizeof(TIME_ZONE_INFORMATION
));
3259 lpTimeZoneInformation
->Bias
=360;//GMT-6
3260 memcpy(lpTimeZoneInformation
->StandardName
, name
, sizeof(name
));
3261 lpTimeZoneInformation
->StandardDate
.wMonth
=10;
3262 lpTimeZoneInformation
->StandardDate
.wDay
=5;
3263 lpTimeZoneInformation
->StandardDate
.wHour
=2;
3264 lpTimeZoneInformation
->StandardBias
=0;
3265 memcpy(lpTimeZoneInformation
->DaylightName
, pname
, sizeof(pname
));
3266 lpTimeZoneInformation
->DaylightDate
.wMonth
=4;
3267 lpTimeZoneInformation
->DaylightDate
.wDay
=1;
3268 lpTimeZoneInformation
->DaylightDate
.wHour
=2;
3269 lpTimeZoneInformation
->DaylightBias
=-60;
3270 return TIME_ZONE_ID_STANDARD
;
3273 static void WINAPI
expGetLocalTime(SYSTEMTIME
* systime
)
3276 struct tm
*local_tm
;
3279 dbgprintf("GetLocalTime(0x%x)\n");
3280 gettimeofday(&tv
, NULL
);
3281 local_time
=tv
.tv_sec
;
3282 local_tm
=localtime(&local_time
);
3284 systime
->wYear
= local_tm
->tm_year
+ 1900;
3285 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3286 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3287 systime
->wDay
= local_tm
->tm_mday
;
3288 systime
->wHour
= local_tm
->tm_hour
;
3289 systime
->wMinute
= local_tm
->tm_min
;
3290 systime
->wSecond
= local_tm
->tm_sec
;
3291 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3292 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3293 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3294 " Milliseconds: %d\n",
3295 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3296 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3299 static int WINAPI
expGetSystemTime(SYSTEMTIME
* systime
)
3302 struct tm
*local_tm
;
3305 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3306 gettimeofday(&tv
, NULL
);
3307 local_time
=tv
.tv_sec
;
3308 local_tm
=gmtime(&local_time
);
3310 systime
->wYear
= local_tm
->tm_year
+ 1900;
3311 systime
->wMonth
= local_tm
->tm_mon
+ 1;
3312 systime
->wDayOfWeek
= local_tm
->tm_wday
;
3313 systime
->wDay
= local_tm
->tm_mday
;
3314 systime
->wHour
= local_tm
->tm_hour
;
3315 systime
->wMinute
= local_tm
->tm_min
;
3316 systime
->wSecond
= local_tm
->tm_sec
;
3317 systime
->wMilliseconds
= (tv
.tv_usec
/ 1000) % 1000;
3318 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3319 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3320 " Milliseconds: %d\n",
3321 systime
->wYear
, systime
->wMonth
, systime
->wDayOfWeek
, systime
->wDay
,
3322 systime
->wHour
, systime
->wMinute
, systime
->wSecond
, systime
->wMilliseconds
);
3326 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3327 static void WINAPI
expGetSystemTimeAsFileTime(FILETIME
* systime
)
3330 unsigned long long secs
;
3332 dbgprintf("GetSystemTime(0x%x)\n", systime
);
3333 gettimeofday(&tv
, NULL
);
3334 secs
= (tv
.tv_sec
+ SECS_1601_TO_1970
) * 10000000;
3335 secs
+= tv
.tv_usec
* 10;
3336 systime
->dwLowDateTime
= secs
& 0xffffffff;
3337 systime
->dwHighDateTime
= (secs
>> 32);
3340 static int WINAPI
expGetEnvironmentVariableA(const char* name
, char* field
, int size
)
3343 // printf("%s %x %x\n", name, field, size);
3344 if(field
)field
[0]=0;
3347 if (p) strncpy(field,p,size);
3349 if (strcmp(name
,"__MSVCRT_HEAP_SELECT")==0)
3350 strcpy(field
,"__GLOBAL_HEAP_SELECTED,1");
3351 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name
, name
, field
, size
, strlen(field
));
3352 return strlen(field
);
3355 static int WINAPI
expSetEnvironmentVariableA(const char *name
, const char *value
)
3357 dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name
, value
);
3361 static void* WINAPI
expCoTaskMemAlloc(ULONG cb
)
3363 return my_mreq(cb
, 0);
3365 static void WINAPI
expCoTaskMemFree(void* cb
)
3373 void* CoTaskMemAlloc(unsigned long cb
)
3375 return expCoTaskMemAlloc(cb
);
3377 void CoTaskMemFree(void* cb
)
3379 expCoTaskMemFree(cb
);
3382 struct COM_OBJECT_INFO
3385 long (*GetClassObject
) (GUID
* clsid
, const GUID
* iid
, void** ppv
);
3388 static struct COM_OBJECT_INFO
* com_object_table
=0;
3389 static int com_object_size
=0;
3390 int RegisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3394 com_object_table
=realloc(com_object_table
, sizeof(struct COM_OBJECT_INFO
)*(++com_object_size
));
3395 com_object_table
[com_object_size
-1].clsid
=*clsid
;
3396 com_object_table
[com_object_size
-1].GetClassObject
=gcs
;
3400 int UnregisterComClass(const GUID
* clsid
, GETCLASSOBJECT gcs
)
3407 if (com_object_table
== 0)
3408 printf("Warning: UnregisterComClass() called without any registered class\n");
3409 while (i
< com_object_size
)
3413 memcpy(&com_object_table
[i
- 1].clsid
,
3414 &com_object_table
[i
].clsid
, sizeof(GUID
));
3415 com_object_table
[i
- 1].GetClassObject
=
3416 com_object_table
[i
].GetClassObject
;
3418 else if (memcmp(&com_object_table
[i
].clsid
, clsid
, sizeof(GUID
)) == 0
3419 && com_object_table
[i
].GetClassObject
== gcs
)
3427 if (--com_object_size
== 0)
3429 free(com_object_table
);
3430 com_object_table
= 0;
3437 const GUID IID_IUnknown
=
3439 0x00000000, 0x0000, 0x0000,
3440 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3442 const GUID IID_IClassFactory
=
3444 0x00000001, 0x0000, 0x0000,
3445 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3448 static long WINAPI
expCoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3449 long dwClsContext
, const GUID
* riid
, void** ppv
)
3452 struct COM_OBJECT_INFO
* ci
=0;
3453 for(i
=0; i
<com_object_size
; i
++)
3454 if(!memcmp(rclsid
, &com_object_table
[i
].clsid
, sizeof(GUID
)))
3455 ci
=&com_object_table
[i
];
3456 if(!ci
)return REGDB_E_CLASSNOTREG
;
3457 // in 'real' world we should mess with IClassFactory here
3458 i
=ci
->GetClassObject(rclsid
, riid
, ppv
);
3462 long CoCreateInstance(GUID
* rclsid
, struct IUnknown
* pUnkOuter
,
3463 long dwClsContext
, const GUID
* riid
, void** ppv
)
3465 return expCoCreateInstance(rclsid
, pUnkOuter
, dwClsContext
, riid
, ppv
);
3468 static int WINAPI
expIsRectEmpty(CONST RECT
*lprc
)
3475 w
= lprc
->right
- lprc
->left
;
3476 h
= lprc
->bottom
- lprc
->top
;
3477 if (w
<= 0 || h
<= 0)
3483 dbgprintf("IsRectEmpty(%p) => %s\n", lprc
, (r
) ? "TRUE" : "FALSE");
3484 //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3485 // return 0; // wmv9?
3489 static int _adjust_fdiv
=0; //what's this? - used to adjust division
3490 static int _winver
= 0x510; // windows version
3495 static unsigned int WINAPI
expGetTempPathA(unsigned int len
, char* path
)
3497 dbgprintf("GetTempPathA(%d, 0x%x)", len
, path
);
3500 dbgprintf(" => 0\n");
3503 strcpy(path
, "/tmp");
3504 dbgprintf(" => 5 ( '/tmp' )\n");
3511 DWORD dwFileAttributes;
3512 FILETIME ftCreationTime;
3513 FILETIME ftLastAccessTime;
3514 FILETIME ftLastWriteTime;
3515 DWORD nFileSizeHigh;
3519 CHAR cFileName[260];
3520 CHAR cAlternateFileName[14];
3521 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3524 static DIR* qtx_dir
=NULL
;
3526 static WIN_BOOL WINAPI
expFindNextFileA(HANDLE h
,LPWIN32_FIND_DATAA lpfd
)
3528 #ifdef CONFIG_QTX_CODECS
3529 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h
, lpfd
);
3530 if(h
==FILE_HANDLE_quicktimeqtx
){
3532 if(!qtx_dir
) return 0;
3533 while((d
=readdir(qtx_dir
))){
3534 char* x
=strrchr(d
->d_name
,'.');
3536 if(strcmp(x
,".qtx")) continue;
3537 strcpy(lpfd
->cFileName
,d
->d_name
);
3538 // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3539 strcpy(lpfd
->cAlternateFileName
,"foobar.qtx");
3540 dbgprintf("### FindNext: %s\n",lpfd
->cFileName
);
3543 closedir(qtx_dir
); qtx_dir
=NULL
;
3550 static HANDLE WINAPI
expFindFirstFileA(LPCSTR s
, LPWIN32_FIND_DATAA lpfd
)
3552 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s
, s
, lpfd
);
3553 // printf("\n### FindFirstFileA('%s')...\n",s);
3554 #ifdef CONFIG_QTX_CODECS
3555 if(strstr(s
, "quicktime\\*.QTX")){
3556 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s
, s
, lpfd
);
3557 dbgprintf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",def_path
);
3558 qtx_dir
=opendir(def_path
);
3559 if(!qtx_dir
) return (HANDLE
)-1;
3560 memset(lpfd
,0,sizeof(*lpfd
));
3561 if(expFindNextFileA(FILE_HANDLE_quicktimeqtx
,lpfd
))
3562 return FILE_HANDLE_quicktimeqtx
;
3563 printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",def_path
);
3567 if(strstr(s
, "QuickTime.qts")){
3568 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s
, s
, lpfd
);
3569 // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3570 // return (HANDLE)-1;
3571 strcpy(lpfd
->cFileName
, "QuickTime.qts");
3572 strcpy(lpfd
->cAlternateFileName
, "QuickT~1.qts");
3573 return FILE_HANDLE_quicktimeqts
;
3577 if(strstr(s
, "*.vwp")){
3578 // hack for VoxWare codec plugins:
3579 strcpy(lpfd
->cFileName
, "msms001.vwp");
3580 strcpy(lpfd
->cAlternateFileName
, "msms001.vwp");
3583 // return 'file not found'
3587 static WIN_BOOL WINAPI
expFindClose(HANDLE h
)
3589 dbgprintf("FindClose(0x%x) => 0\n", h
);
3590 #ifdef CONFIG_QTX_CODECS
3591 // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3592 // closedir(qtx_dir);
3598 static UINT WINAPI
expSetErrorMode(UINT i
)
3600 dbgprintf("SetErrorMode(%d) => 0\n", i
);
3603 static UINT WINAPI
expGetWindowsDirectoryA(LPSTR s
,UINT c
)
3605 char windir
[]="c:\\windows";
3607 strncpy(s
, windir
, c
);
3608 result
=1+((c
<strlen(windir
))?c
:strlen(windir
));
3609 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3612 #ifdef CONFIG_QTX_CODECS
3613 static UINT WINAPI
expGetCurrentDirectoryA(UINT c
, LPSTR s
)
3615 char curdir
[]="c:\\";
3617 strncpy(s
, curdir
, c
);
3618 result
=1+((c
<strlen(curdir
))?c
:strlen(curdir
));
3619 dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s
, c
, result
);
3623 static int WINAPI
expSetCurrentDirectoryA(const char *pathname
)
3625 dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname
, pathname
);
3627 if (strrchr(pathname
, '\\'))
3628 chdir(strcat(strrchr(pathname
, '\\')+1, '/'));
3635 static int WINAPI
expCreateDirectoryA(const char *pathname
, void *sa
)
3637 dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3638 pathname
, pathname
, sa
);
3640 p
= strrchr(pathname
, '\\')+1;
3641 strcpy(&buf
[0], p
); /* should be strncpy */
3648 if (strrchr(pathname
, '\\'))
3649 mkdir(strcat(strrchr(pathname
, '\\')+1, '/'), 666);
3651 mkdir(pathname
, 666);
3658 static WIN_BOOL WINAPI
expDeleteFileA(LPCSTR s
)
3660 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s
, s
);
3663 static WIN_BOOL WINAPI
expFileTimeToLocalFileTime(const FILETIME
* cpf
, LPFILETIME pf
)
3665 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf
, pf
);
3669 static UINT WINAPI
expGetTempFileNameA(LPCSTR cs1
,LPCSTR cs2
,UINT i
,LPSTR ps
)
3671 char mask
[16]="/tmp/AP_XXXXXX";
3673 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1
, cs1
, cs2
, cs2
, i
, ps
);
3676 dbgprintf(" => -1\n");
3679 result
=mkstemp(mask
);
3680 sprintf(ps
, "AP%d", result
);
3681 dbgprintf(" => %d\n", strlen(ps
));
3685 // This func might need proper implementation if we want AngelPotion codec.
3686 // They try to open APmpeg4v1.apl with it.
3687 // DLL will close opened file with CloseHandle().
3689 static HANDLE WINAPI
expCreateFileA(LPCSTR cs1
,DWORD i1
,DWORD i2
,
3690 LPSECURITY_ATTRIBUTES p1
, DWORD i3
,DWORD i4
,HANDLE i5
)
3692 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1
, cs1
, i1
,
3693 i2
, p1
, i3
, i4
, i5
);
3694 if((!cs1
) || (strlen(cs1
)<2))return -1;
3696 #ifdef CONFIG_QTX_CODECS
3697 if(strstr(cs1
, "QuickTime.qts"))
3700 char* tmp
=malloc(strlen(def_path
)+50);
3701 strcpy(tmp
, def_path
);
3703 strcat(tmp
, "QuickTime.qts");
3704 result
=open(tmp
, O_RDONLY
);
3708 if(strstr(cs1
, ".qtx"))
3711 char* tmp
=malloc(strlen(def_path
)+250);
3712 char* x
=strrchr(cs1
,'\\');
3713 sprintf(tmp
,"%s/%s",def_path
,x
?(x
+1):cs1
);
3714 // printf("### Open: %s -> %s\n",cs1,tmp);
3715 result
=open(tmp
, O_RDONLY
);
3721 if(strncmp(cs1
, "AP", 2) == 0)
3724 char* tmp
=malloc(strlen(def_path
)+50);
3725 strcpy(tmp
, def_path
);
3727 strcat(tmp
, "APmpg4v1.apl");
3728 result
=open(tmp
, O_RDONLY
);
3732 if (strstr(cs1
, "vp3") || strstr(cs1
, ".fpf"))
3736 char* tmp
=malloc(20 + strlen(cs1
));
3737 strcpy(tmp
, "/tmp/");
3742 if (tmp
[r
] == ':' || tmp
[r
] == '\\')
3746 if (GENERIC_READ
& i1
)
3748 else if (GENERIC_WRITE
& i1
)
3750 flg
|= O_WRONLY
| O_CREAT
;
3751 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp
, r
, flg
);
3753 r
=open(tmp
, flg
, S_IRWXU
);
3758 // Needed by wnvplay1.dll
3759 if (strstr(cs1
, "WINNOV.bmp"))
3762 r
=open("/dev/null", O_RDONLY
);
3767 /* we need this for some virtualdub filters */
3771 if (GENERIC_READ
& i1
)
3773 else if (GENERIC_WRITE
& i1
)
3776 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1
, r
, flg
);
3785 static UINT WINAPI
expGetSystemDirectoryA(
3786 char* lpBuffer
, // address of buffer for system directory
3787 UINT uSize
// size of directory buffer
3789 dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer
,uSize
);
3790 if(!lpBuffer
) strcpy(lpBuffer
,".");
3794 static char sysdir[]=".";
3795 static LPCSTR WINAPI expGetSystemDirectoryA(void)
3797 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3801 static DWORD WINAPI expGetFullPathNameA
3804 DWORD nBufferLength
,
3808 if(!lpFileName
) return 0;
3809 dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName
,nBufferLength
,
3810 lpBuffer
, lpFilePart
);
3812 #ifdef CONFIG_QTX_CODECS
3813 strcpy(lpFilePart
, "Quick123.qts");
3815 strcpy(lpFilePart
, lpFileName
);
3818 if (strrchr(lpFileName
, '\\'))
3819 lpFilePart
= strrchr(lpFileName
, '\\');
3821 lpFilePart
= (LPTSTR
)lpFileName
;
3823 strcpy(lpBuffer
, lpFileName
);
3824 // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3825 return strlen(lpBuffer
);
3828 static DWORD WINAPI expGetShortPathNameA
3834 if(!longpath
) return 0;
3835 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath
,shortpath
,shortlen
);
3836 strcpy(shortpath
,longpath
);
3837 return strlen(shortpath
);
3840 static WIN_BOOL WINAPI
expReadFile(HANDLE h
,LPVOID pv
,DWORD size
,LPDWORD rd
,LPOVERLAPPED unused
)
3843 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, rd
);
3844 result
=read(h
, pv
, size
);
3846 if(!result
)return 0;
3850 static WIN_BOOL WINAPI
expWriteFile(HANDLE h
,LPCVOID pv
,DWORD size
,LPDWORD wr
,LPOVERLAPPED unused
)
3853 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h
, pv
, size
, wr
);
3855 result
=write(h
, pv
, size
);
3857 if(!result
)return 0;
3860 static DWORD WINAPI
expSetFilePointer(HANDLE h
, LONG val
, LPLONG ext
, DWORD whence
)
3863 dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h
, val
, ext
, ext
? *ext
: NULL
, whence
);
3864 //why would DLL want temporary file with >2Gb size?
3876 #ifdef CONFIG_QTX_CODECS
3877 if (val
== 0 && ext
!= 0)
3880 return lseek(h
, val
, wh
);
3883 static HDRVR WINAPI
expOpenDriverA(LPCSTR szDriverName
, LPCSTR szSectionName
,
3886 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3889 static HDRVR WINAPI
expOpenDriver(LPCSTR szDriverName
, LPCSTR szSectionName
,
3892 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName
, szDriverName
, szSectionName
, szSectionName
, lParam2
);
3897 static WIN_BOOL WINAPI
expGetProcessAffinityMask(HANDLE hProcess
,
3898 LPDWORD lpProcessAffinityMask
,
3899 LPDWORD lpSystemAffinityMask
)
3901 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3902 hProcess
, lpProcessAffinityMask
, lpSystemAffinityMask
);
3903 if(lpProcessAffinityMask
)*lpProcessAffinityMask
=1;
3904 if(lpSystemAffinityMask
)*lpSystemAffinityMask
=1;
3908 // Fake implementation: does nothing, but does it right :)
3909 static WIN_BOOL WINAPI
expSetProcessAffinityMask(HANDLE hProcess
,
3910 LPDWORD dwProcessAffinityMask
)
3912 dbgprintf("SetProcessAffinityMask(0x%x, 0x%x) => 1\n",
3913 hProcess
, dwProcessAffinityMask
);
3918 static int WINAPI
expMulDiv(int nNumber
, int nNumerator
, int nDenominator
)
3920 static const long long max_int
=0x7FFFFFFFLL
;
3921 static const long long min_int
=-0x80000000LL
;
3922 long long tmp
=(long long)nNumber
*(long long)nNumerator
;
3923 dbgprintf("expMulDiv %d * %d / %d\n", nNumber
, nNumerator
, nDenominator
);
3924 if(!nDenominator
)return 1;
3926 if(tmp
<min_int
) return 1;
3927 if(tmp
>max_int
) return 1;
3931 static LONG WINAPI
explstrcmpiA(const char* str1
, const char* str2
)
3933 LONG result
=strcasecmp(str1
, str2
);
3934 dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
3938 static LONG WINAPI
explstrlenA(const char* str1
)
3940 LONG result
=strlen(str1
);
3941 dbgprintf("strlen(0x%x='%.50s') => %d\n", str1
, str1
, result
);
3945 static LONG WINAPI
explstrcpyA(char* str1
, const char* str2
)
3947 int result
= (int) strcpy(str1
, str2
);
3948 dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1
, str2
, str2
, result
);
3951 static LONG WINAPI
explstrcpynA(char* str1
, const char* str2
,int len
)
3954 if (strlen(str2
)>len
)
3955 result
= (int) strncpy(str1
, str2
,len
);
3957 result
= (int) strcpy(str1
,str2
);
3958 dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1
, str2
, str2
,len
, strlen(str2
),result
);
3961 static LONG WINAPI
explstrcatA(char* str1
, const char* str2
)
3963 int result
= (int) strcat(str1
, str2
);
3964 dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1
, str2
, str2
, result
);
3969 static LONG WINAPI
expInterlockedExchange(long *dest
, long l
)
3971 long retval
= *dest
;
3976 static void WINAPI
expInitCommonControls(void)
3978 dbgprintf("InitCommonControls called!\n");
3982 #ifdef CONFIG_QTX_CODECS
3983 /* needed by QuickTime.qts */
3984 static HWND WINAPI
expCreateUpDownControl (DWORD style
, INT x
, INT y
, INT cx
, INT cy
,
3985 HWND parent
, INT id
, HINSTANCE inst
,
3986 HWND buddy
, INT maxVal
, INT minVal
, INT curVal
)
3988 dbgprintf("CreateUpDownControl(...)\n");
3993 /* alex: implement this call! needed for 3ivx */
3994 static HRESULT WINAPI
expCoCreateFreeThreadedMarshaler(void *pUnkOuter
, void **ppUnkInner
)
3996 dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
3997 pUnkOuter
, ppUnkInner
);
3999 return ERROR_CALL_NOT_IMPLEMENTED
;
4003 static int WINAPI
expDuplicateHandle(HANDLE hSourceProcessHandle
, // handle to source process
4004 HANDLE hSourceHandle
, // handle to duplicate
4005 HANDLE hTargetProcessHandle
, // handle to target process
4006 HANDLE
* lpTargetHandle
, // duplicate handle
4007 DWORD dwDesiredAccess
, // requested access
4008 int bInheritHandle
, // handle inheritance option
4009 DWORD dwOptions
// optional actions
4012 dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
4013 hSourceProcessHandle
, hSourceHandle
, hTargetProcessHandle
,
4014 lpTargetHandle
, dwDesiredAccess
, bInheritHandle
, dwOptions
);
4015 *lpTargetHandle
= hSourceHandle
;
4019 static HRESULT WINAPI
expCoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
4021 dbgprintf("CoInitializeEx(%p, %d) called\n", lpReserved
, dwCoInit
);
4025 // required by PIM1 codec (used by win98 PCTV Studio capture sw)
4026 static HRESULT WINAPI
expCoInitialize(
4027 LPVOID lpReserved
/* [in] pointer to win32 malloc interface
4028 (obsolete, should be NULL) */
4032 * Just delegate to the newer method.
4034 return expCoInitializeEx(lpReserved
, COINIT_APARTMENTTHREADED
);
4037 static void WINAPI
expCoUninitialize(void)
4039 dbgprintf("CoUninitialize() called\n");
4042 /* allow static linking */
4043 HRESULT WINAPI
CoInitializeEx(LPVOID lpReserved
, DWORD dwCoInit
)
4045 return expCoInitializeEx(lpReserved
, dwCoInit
);
4047 HRESULT WINAPI
CoInitialize(LPVOID lpReserved
)
4049 return expCoInitialize(lpReserved
);
4051 void WINAPI
CoUninitialize(void)
4053 expCoUninitialize();
4056 static DWORD WINAPI expSetThreadAffinityMask
4059 DWORD dwThreadAffinityMask
4065 * no WINAPI functions - CDECL
4067 static void* expmalloc(int size
)
4070 // return malloc(size);
4071 void* result
=my_mreq(size
,0);
4072 dbgprintf("malloc(0x%x) => 0x%x\n", size
,result
);
4074 printf("WARNING: malloc() failed\n");
4077 static void expfree(void* mem
)
4079 // return free(mem);
4080 dbgprintf("free(%p)\n", mem
);
4083 /* needed by atrac3.acm */
4084 static void *expcalloc(int num
, int size
)
4086 void* result
=my_mreq(num
*size
,1);
4087 dbgprintf("calloc(%d,%d) => %p\n", num
,size
,result
);
4089 printf("WARNING: calloc() failed\n");
4092 static void* expnew(int size
)
4094 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
4095 // printf("%08x %08x %08x %08x\n",
4096 // size, *(1+(int*)&size),
4097 // *(2+(int*)&size),*(3+(int*)&size));
4101 result
=my_mreq(size
,0);
4102 dbgprintf("new(%d) => %p\n", size
, result
);
4104 printf("WARNING: new() failed\n");
4108 static int expdelete(void* memory
)
4110 dbgprintf("delete(%p)\n", memory
);
4116 * local definition - we need only the last two members at this point
4117 * otherwice we would have to introduce here GUIDs and some more types..
4119 typedef struct __attribute__((__packed__
))
4122 unsigned long cbFormat
; //0x40
4123 char* pbFormat
; //0x44
4125 static HRESULT WINAPI
expMoCopyMediaType(MY_MEDIA_TYPE
* dest
, const MY_MEDIA_TYPE
* src
)
4129 memcpy(dest
, src
, sizeof(MY_MEDIA_TYPE
));
4132 dest
->pbFormat
= (char*) my_mreq(dest
->cbFormat
, 0);
4133 if (!dest
->pbFormat
)
4134 return E_OUTOFMEMORY
;
4135 memcpy(dest
->pbFormat
, src
->pbFormat
, dest
->cbFormat
);
4139 static HRESULT WINAPI
expMoInitMediaType(MY_MEDIA_TYPE
* dest
, DWORD cbFormat
)
4143 memset(dest
, 0, sizeof(MY_MEDIA_TYPE
));
4146 dest
->pbFormat
= (char*) my_mreq(cbFormat
, 0);
4147 if (!dest
->pbFormat
)
4148 return E_OUTOFMEMORY
;
4152 static HRESULT WINAPI
expMoCreateMediaType(MY_MEDIA_TYPE
** dest
, DWORD cbFormat
)
4156 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
4157 return expMoInitMediaType(*dest
, cbFormat
);
4159 static HRESULT WINAPI
expMoDuplicateMediaType(MY_MEDIA_TYPE
** dest
, const void* src
)
4163 *dest
= my_mreq(sizeof(MY_MEDIA_TYPE
), 0);
4164 return expMoCopyMediaType(*dest
, src
);
4166 static HRESULT WINAPI
expMoFreeMediaType(MY_MEDIA_TYPE
* dest
)
4172 my_release(dest
->pbFormat
);
4178 static HRESULT WINAPI
expMoDeleteMediaType(MY_MEDIA_TYPE
* dest
)
4182 expMoFreeMediaType(dest
);
4187 static int exp_snprintf( char *str
, int size
, const char *format
, ... )
4191 va_start(va
, format
);
4192 x
=snprintf(str
,size
,format
,va
);
4193 dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str
,size
,format
,x
);
4199 static int exp_initterm(int v1
, int v2
)
4201 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1
, v2
);
4205 /* merged from wine - 2002.04.21 */
4206 typedef void (*INITTERMFUNC
)();
4207 static int exp_initterm(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
4209 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start
, end
, *start
);
4214 //printf("call _initfunc: from: %p %d\n", *start);
4215 // ok this trick with push/pop is necessary as otherwice
4216 // edi/esi registers are being trashed
4235 //printf("done %p %d:%d\n", end);
4243 /* Fake _initterm_e from msvcr80.dll, needed by sirenacm.dll
4244 * NOTE: If I make this an alias for _initterm, then sirenacm.dll tries to call
4245 other uninmplemented functions; keep this in mind if some future codec needs
4246 a real implementation of this function */
4247 static int exp_initterm_e(INITTERMFUNC
*start
, INITTERMFUNC
*end
)
4249 dbgprintf("_initterm_e(0x%x, 0x%x)\n", start
, end
);
4253 static void* exp__dllonexit(void)
4255 // FIXME extract from WINE
4259 static int expwsprintfA(char* string
, const char* format
, ...)
4263 va_start(va
, format
);
4264 result
= vsprintf(string
, format
, va
);
4265 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string
, format
, result
);
4270 static int expsprintf(char* str
, const char* format
, ...)
4274 dbgprintf("sprintf(0x%x, %s)\n", str
, format
);
4275 va_start(args
, format
);
4276 r
= vsprintf(str
, format
, args
);
4280 static int expsscanf(const char* str
, const char* format
, ...)
4284 dbgprintf("sscanf(%s, %s)\n", str
, format
);
4285 va_start(args
, format
);
4286 r
= vsscanf(str
, format
, args
);
4290 static void* expfopen(const char* path
, const char* mode
)
4292 printf("fopen: \"%s\" mode:%s\n", path
, mode
);
4293 //return fopen(path, mode);
4294 return fdopen(0, mode
); // everything on screen
4296 static int expfprintf(void* stream
, const char* format
, ...)
4300 dbgprintf("fprintf(%p, %s, ...)\n", stream
, format
);
4301 va_start(args
, format
);
4302 r
= vfprintf((FILE*) stream
, format
, args
);
4307 static int expprintf(const char* format
, ...)
4311 dbgprintf("printf(%s, ...)\n", format
);
4312 va_start(args
, format
);
4313 r
= vprintf(format
, args
);
4318 static char* expgetenv(const char* varname
)
4320 char* v
= getenv(varname
);
4321 dbgprintf("getenv(%s) => %s\n", varname
, v
);
4325 static void* expwcscpy(WCHAR
* dst
, const WCHAR
* src
)
4328 while ((*p
++ = *src
++))
4333 static char* expstrrchr(char* string
, int value
)
4335 char* result
=strrchr(string
, value
);
4337 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4339 dbgprintf("strrchr(0x%x='%s', %d) => 0", string
, string
, value
);
4343 static char* expstrchr(char* string
, int value
)
4345 char* result
=strchr(string
, value
);
4347 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string
, string
, value
, result
, result
);
4349 dbgprintf("strchr(0x%x='%s', %d) => 0", string
, string
, value
);
4352 static int expstrlen(char* str
)
4354 int result
=strlen(str
);
4355 dbgprintf("strlen(0x%x='%s') => %d\n", str
, str
, result
);
4358 static char* expstrcpy(char* str1
, const char* str2
)
4360 char* result
= strcpy(str1
, str2
);
4361 dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1
, str2
, str2
, result
);
4364 static char* expstrncpy(char* str1
, const char* str2
, size_t count
)
4366 char* result
= strncpy(str1
, str2
, count
);
4367 dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1
, str2
, str2
, count
, result
);
4370 static int expstrcmp(const char* str1
, const char* str2
)
4372 int result
=strcmp(str1
, str2
);
4373 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4376 static int expstrncmp(const char* str1
, const char* str2
,int x
)
4378 int result
=strncmp(str1
, str2
,x
);
4379 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1
, str1
, str2
, str2
, result
);
4382 static char* expstrcat(char* str1
, const char* str2
)
4384 char* result
= strcat(str1
, str2
);
4385 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1
, str1
, str2
, str2
, result
);
4388 static char* exp_strdup(const char* str1
)
4390 int l
= strlen(str1
);
4391 char* result
= (char*) my_mreq(l
+ 1,0);
4393 strcpy(result
, str1
);
4394 dbgprintf("_strdup(0x%x='%s') => %p\n", str1
, str1
, result
);
4397 static int expisalnum(int c
)
4399 int result
= (int) isalnum(c
);
4400 dbgprintf("isalnum(0x%x='%c' => %d\n", c
, c
, result
);
4403 static int expisspace(int c
)
4405 int result
= (int) isspace(c
);
4406 dbgprintf("isspace(0x%x='%c' => %d\n", c
, c
, result
);
4409 static int expisalpha(int c
)
4411 int result
= (int) isalpha(c
);
4412 dbgprintf("isalpha(0x%x='%c' => %d\n", c
, c
, result
);
4415 static int expisdigit(int c
)
4417 int result
= (int) isdigit(c
);
4418 dbgprintf("isdigit(0x%x='%c' => %d\n", c
, c
, result
);
4421 static void* expmemmove(void* dest
, void* src
, int n
)
4423 void* result
= memmove(dest
, src
, n
);
4424 dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4427 static int expmemcmp(void* dest
, void* src
, int n
)
4429 int result
= memcmp(dest
, src
, n
);
4430 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest
, src
, n
, result
);
4433 static void* expmemcpy(void* dest
, void* src
, int n
)
4435 void *result
= memcpy(dest
, src
, n
);
4436 dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest
, src
, n
, result
);
4439 static void* expmemset(void* dest
, int c
, size_t n
)
4441 void *result
= memset(dest
, c
, n
);
4442 dbgprintf("memset(0x%x, %d, %d) => %p\n", dest
, c
, n
, result
);
4445 static time_t exptime(time_t* t
)
4447 time_t result
= time(t
);
4448 dbgprintf("time(0x%x) => %d\n", t
, result
);
4452 static int exprand(void)
4457 static void expsrand(int seed
)
4464 // preferred compilation with -O2 -ffast-math !
4466 static double explog10(double x
)
4468 /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4472 static double expcos(double x
)
4474 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4480 static void explog10(void)
4491 static void expcos(void)
4502 // this seem to be the only how to make this function working properly
4503 // ok - I've spent tremendous amount of time (many many many hours
4504 // of debuging fixing & testing - it's almost unimaginable - kabi
4506 // _ftol - operated on the float value which is already on the FPU stack
4508 static void exp_ftol(void)
4512 "sub $12, %esp \n\t"
4513 "fstcw -2(%ebp) \n\t"
4515 "movw -2(%ebp), %ax \n\t"
4516 "orb $0x0C, %ah \n\t"
4517 "movw %ax, -4(%ebp) \n\t"
4518 "fldcw -4(%ebp) \n\t"
4519 "fistpl -12(%ebp) \n\t"
4520 "fldcw -2(%ebp) \n\t"
4521 "movl -12(%ebp), %eax \n\t"
4522 //Note: gcc 3.03 does not do the following op if it
4523 // knows that ebp=esp
4524 "movl %ebp, %esp \n\t"
4528 #define FPU_DOUBLES(var1,var2) double var1,var2; \
4529 __asm__ volatile( "fstpl %0;fwait" : "=m" (var2) : ); \
4530 __asm__ volatile( "fstpl %0;fwait" : "=m" (var1) : )
4532 static double exp_CIpow(void)
4536 dbgprintf("_CIpow(%lf, %lf)\n", x
, y
);
4540 static double exppow(double x
, double y
)
4542 /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4546 static double expldexp(double x
, int expo
)
4548 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4549 return ldexp(x
, expo
);
4552 static double expfrexp(double x
, int* expo
)
4554 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4555 return frexp(x
, expo
);
4560 static int exp_stricmp(const char* s1
, const char* s2
)
4562 return strcasecmp(s1
, s2
);
4565 /* from declaration taken from Wine sources - this fountion seems to be
4566 * undocumented in any M$ doc */
4567 static int exp_setjmp3(void* jmpbuf
, int x
)
4569 //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4573 //"mov 4(%%esp), %%edx \n\t"
4574 "mov (%%esp), %%eax \n\t"
4575 "mov %%eax, (%%edx) \n\t" // store ebp
4577 //"mov %%ebp, (%%edx) \n\t"
4578 "mov %%ebx, 4(%%edx) \n\t"
4579 "mov %%edi, 8(%%edx) \n\t"
4580 "mov %%esi, 12(%%edx) \n\t"
4581 "mov %%esp, 16(%%edx) \n\t"
4583 "mov 4(%%esp), %%eax \n\t"
4584 "mov %%eax, 20(%%edx) \n\t"
4586 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4587 "movl $0, 36(%%edx) \n\t"
4589 : "d"(jmpbuf
) // input
4594 "mov %%fs:0, %%eax \n\t" // unsure
4595 "mov %%eax, 24(%%edx) \n\t"
4596 "cmp $0xffffffff, %%eax \n\t"
4598 "mov %%eax, 28(%%edx) \n\t"
4608 static DWORD WINAPI
expGetCurrentProcessId(void)
4610 dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4611 return getpid(); //(DWORD)NtCurrentTeb()->pid;
4618 } TIMECAPS
, *LPTIMECAPS
;
4620 static MMRESULT WINAPI
exptimeGetDevCaps(LPTIMECAPS lpCaps
, UINT wSize
)
4622 dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps
, wSize
);
4624 lpCaps
->wPeriodMin
= 1;
4625 lpCaps
->wPeriodMax
= 65535;
4629 static MMRESULT WINAPI
exptimeBeginPeriod(UINT wPeriod
)
4631 dbgprintf("timeBeginPeriod(%u) !\n", wPeriod
);
4633 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4637 #ifdef CONFIG_QTX_CODECS
4638 static MMRESULT WINAPI
exptimeEndPeriod(UINT wPeriod
)
4640 dbgprintf("timeEndPeriod(%u) !\n", wPeriod
);
4642 if (wPeriod
< 1 || wPeriod
> 65535) return 96+1; //TIMERR_NOCANDO;
4647 static void WINAPI
expGlobalMemoryStatus(
4648 LPMEMORYSTATUS lpmem
4650 static MEMORYSTATUS cached_memstatus
;
4651 static int cache_lastchecked
= 0;
4655 if (time(NULL
)==cache_lastchecked
) {
4656 memcpy(lpmem
,&cached_memstatus
,sizeof(MEMORYSTATUS
));
4660 f
= fopen( "/proc/meminfo", "r" );
4664 int total
, used
, free
, shared
, buffers
, cached
;
4666 lpmem
->dwLength
= sizeof(MEMORYSTATUS
);
4667 lpmem
->dwTotalPhys
= lpmem
->dwAvailPhys
= 0;
4668 lpmem
->dwTotalPageFile
= lpmem
->dwAvailPageFile
= 0;
4669 while (fgets( buffer
, sizeof(buffer
), f
))
4671 /* old style /proc/meminfo ... */
4672 if (sscanf( buffer
, "Mem: %d %d %d %d %d %d", &total
, &used
, &free
, &shared
, &buffers
, &cached
))
4674 lpmem
->dwTotalPhys
+= total
;
4675 lpmem
->dwAvailPhys
+= free
+ buffers
+ cached
;
4677 if (sscanf( buffer
, "Swap: %d %d %d", &total
, &used
, &free
))
4679 lpmem
->dwTotalPageFile
+= total
;
4680 lpmem
->dwAvailPageFile
+= free
;
4683 /* new style /proc/meminfo ... */
4684 if (sscanf(buffer
, "MemTotal: %d", &total
))
4685 lpmem
->dwTotalPhys
= total
*1024;
4686 if (sscanf(buffer
, "MemFree: %d", &free
))
4687 lpmem
->dwAvailPhys
= free
*1024;
4688 if (sscanf(buffer
, "SwapTotal: %d", &total
))
4689 lpmem
->dwTotalPageFile
= total
*1024;
4690 if (sscanf(buffer
, "SwapFree: %d", &free
))
4691 lpmem
->dwAvailPageFile
= free
*1024;
4692 if (sscanf(buffer
, "Buffers: %d", &buffers
))
4693 lpmem
->dwAvailPhys
+= buffers
*1024;
4694 if (sscanf(buffer
, "Cached: %d", &cached
))
4695 lpmem
->dwAvailPhys
+= cached
*1024;
4699 if (lpmem
->dwTotalPhys
)
4701 DWORD TotalPhysical
= lpmem
->dwTotalPhys
+lpmem
->dwTotalPageFile
;
4702 DWORD AvailPhysical
= lpmem
->dwAvailPhys
+lpmem
->dwAvailPageFile
;
4703 lpmem
->dwMemoryLoad
= (TotalPhysical
-AvailPhysical
)
4704 / (TotalPhysical
/ 100);
4708 /* FIXME: should do something for other systems */
4709 lpmem
->dwMemoryLoad
= 0;
4710 lpmem
->dwTotalPhys
= 16*1024*1024;
4711 lpmem
->dwAvailPhys
= 16*1024*1024;
4712 lpmem
->dwTotalPageFile
= 16*1024*1024;
4713 lpmem
->dwAvailPageFile
= 16*1024*1024;
4715 expGetSystemInfo(&si
);
4716 lpmem
->dwTotalVirtual
= si
.lpMaximumApplicationAddress
-si
.lpMinimumApplicationAddress
;
4717 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4718 lpmem
->dwAvailVirtual
= lpmem
->dwTotalVirtual
-64*1024;
4719 memcpy(&cached_memstatus
,lpmem
,sizeof(MEMORYSTATUS
));
4720 cache_lastchecked
= time(NULL
);
4722 /* it appears some memory display programs want to divide by these values */
4723 if(lpmem
->dwTotalPageFile
==0)
4724 lpmem
->dwTotalPageFile
++;
4726 if(lpmem
->dwAvailPageFile
==0)
4727 lpmem
->dwAvailPageFile
++;
4730 static INT WINAPI
expGetThreadPriority(HANDLE hthread
)
4732 dbgprintf("GetThreadPriority(%p)\n",hthread
);
4736 /**********************************************************************
4737 * SetThreadPriority [KERNEL32.@] Sets priority for thread.
4743 static WIN_BOOL WINAPI
expSetThreadPriority(
4744 HANDLE hthread
, /* [in] Handle to thread */
4745 INT priority
) /* [in] Thread priority level */
4747 dbgprintf("SetThreadPriority(%p,%d)\n",hthread
,priority
);
4751 static void WINAPI
expTerminateProcess( DWORD process
, DWORD status
)
4753 printf("EXIT - process %ld code %ld\n", process
, status
);
4757 static void WINAPI
expExitProcess( DWORD status
)
4759 printf("EXIT - code %ld\n",status
);
4763 static INT WINAPI
expMessageBoxA(HWND hWnd
, LPCSTR text
, LPCSTR title
, UINT type
){
4764 printf("MSGBOX '%s' '%s' (%d)\n",text
,title
,type
);
4765 #ifdef CONFIG_QTX_CODECS
4766 if (type
== MB_ICONHAND
&& !strlen(text
) && !strlen(title
))
4772 /* these are needed for mss1 */
4775 * \brief this symbol is defined within exp_EH_prolog_dummy
4776 * \param dest jump target
4778 void exp_EH_prolog(void *dest
);
4779 void exp_EH_prolog_dummy(void);
4780 //! just a dummy function that acts a container for the asm section
4781 void exp_EH_prolog_dummy(void) {
4783 // take care, this "function" may not change flags or
4784 // registers besides eax (which is also why we can't use
4785 // exp_EH_prolog_dummy directly)
4786 MANGLE(exp_EH_prolog
)": \n\t"
4789 "mov %esp, %ebp \n\t"
4790 "lea -12(%esp), %esp \n\t"
4795 #include <netinet/in.h>
4796 static WINAPI
inline unsigned long int exphtonl(unsigned long int hostlong
)
4798 // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4799 return htonl(hostlong
);
4802 static WINAPI
inline unsigned long int expntohl(unsigned long int netlong
)
4804 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4805 return ntohl(netlong
);
4808 static char* WINAPI
expSysAllocStringLen(char *pch
, unsigned cch
)
4811 dbgprintf("SysAllocStringLen('%s', %d)\n", pch
, cch
);
4812 str
= malloc(cch
* 2 + sizeof(unsigned) + 2);
4813 *(unsigned *)str
= cch
;
4814 str
+= sizeof(unsigned);
4816 memcpy(str
, pch
, cch
* 2);
4818 str
[cch
* 2 + 1] = 0;
4822 static void WINAPI
expSysFreeString(char *str
)
4825 free(str
- sizeof(unsigned));
4829 static void WINAPI
expVariantInit(void* p
)
4831 printf("InitCommonControls called!\n");
4835 static int WINAPI
expRegisterClassA(const void/*WNDCLASSA*/ *wc
)
4837 dbgprintf("RegisterClassA(%p) => random id\n", wc
);
4838 return time(NULL
); /* be precise ! */
4841 static int WINAPI
expUnregisterClassA(const char *className
, HINSTANCE hInstance
)
4843 dbgprintf("UnregisterClassA(%s, %p) => 0\n", className
, hInstance
);
4847 #ifdef CONFIG_QTX_CODECS
4848 /* should be fixed bcs it's not fully strlen equivalent */
4849 static int expSysStringByteLen(void *str
)
4851 dbgprintf("SysStringByteLen(%p) => %d\n", str
, strlen(str
));
4855 static int expDirectDrawCreate(void)
4857 dbgprintf("DirectDrawCreate(...) => NULL\n");
4862 typedef struct tagPALETTEENTRY
{
4869 typedef struct tagLOGPALETTE
{
4872 PALETTEENTRY palPalEntry
[1];
4875 static HPALETTE WINAPI
expCreatePalette(CONST LOGPALETTE
*lpgpl
)
4880 dbgprintf("CreatePalette(%x) => NULL\n", lpgpl
);
4882 i
= sizeof(LOGPALETTE
)+((lpgpl
->palNumEntries
-1)*sizeof(PALETTEENTRY
));
4884 memcpy((void *)test
, lpgpl
, i
);
4889 static int expCreatePalette(void)
4891 dbgprintf("CreatePalette(...) => NULL\n");
4896 static int WINAPI
expGetClientRect(HWND win
, RECT
*r
)
4898 dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win
, r
);
4899 r
->right
= PSEUDO_SCREEN_WIDTH
;
4901 r
->bottom
= PSEUDO_SCREEN_HEIGHT
;
4907 typedef struct tagPOINT
{
4913 static int WINAPI
expClientToScreen(HWND win
, POINT
*p
)
4915 dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win
, p
, p
->x
, p
->y
);
4923 static int WINAPI
expSetThreadIdealProcessor(HANDLE thread
, int proc
)
4925 dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread
, proc
);
4929 static int WINAPI
expMessageBeep(int type
)
4931 dbgprintf("MessageBeep(%d) => 1\n", type
);
4935 static int WINAPI
expDialogBoxParamA(void *inst
, const char *name
,
4936 HWND parent
, void *dialog_func
, void *init_param
)
4938 dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
4939 inst
, name
, name
, parent
, dialog_func
, init_param
);
4943 static void WINAPI
expRegisterClipboardFormatA(const char *name
) {
4944 dbgprintf("RegisterClipboardFormatA(0x%x = %s)\n", name
, name
);
4947 /* needed by imagepower mjpeg2k */
4948 static void *exprealloc(void *ptr
, size_t size
)
4950 dbgprintf("realloc(0x%x, %x)\n", ptr
, size
);
4952 return my_mreq(size
,0);
4954 return my_realloc(ptr
, size
);
4957 /* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
4958 static WIN_BOOL WINAPI
expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn
)
4963 static char * WINAPI
expPathFindExtensionA(const char *path
) {
4968 ext
= strrchr(path
, '.');
4970 ext
= &path
[strlen(path
)];
4972 dbgprintf("PathFindExtensionA(0x%x = %s) => 0x%x, %s\n", path
, path
, ext
, ext
);
4976 static char * WINAPI
expPathFindFileNameA(const char *path
) {
4978 if (!path
|| strlen(path
) < 2)
4981 name
= strrchr(path
- 1, '\\');
4985 dbgprintf("PathFindFileNameA(0x%x = %s) => 0x%x, %s\n", path
, path
, name
, name
);
4989 static double expfloor(double x
)
4991 dbgprintf("floor(%lf)\n", x
);
4995 #define FPU_DOUBLE(var) double var; \
4996 __asm__ volatile( "fstpl %0;fwait" : "=m" (var) : )
4998 static double exp_CIcos(void)
5002 dbgprintf("_CIcos(%lf)\n", x
);
5006 static double exp_CIsin(void)
5010 dbgprintf("_CIsin(%lf)\n", x
);
5014 static double exp_CIsqrt(void)
5018 dbgprintf("_CIsqrt(%lf)\n", x
);
5022 /* Needed by rp8 sipr decoder */
5023 static LPSTR WINAPI
expCharNextA(LPCSTR ptr
)
5025 if (!*ptr
) return (LPSTR
)ptr
;
5026 // dbgprintf("CharNextA(0x%08x), %s\n", ptr, ptr);
5027 return (LPSTR
)(ptr
+ 1);
5030 // Fake implementation, needed by wvc1dmod.dll
5031 static int WINAPI
expPropVariantClear(void *pvar
)
5033 // dbgprintf("PropVariantclear (0x%08x), %s\n", ptr, ptr);
5037 // This define is fake, the real thing is a struct
5038 #define LPDEVMODEA void*
5039 // Dummy implementation, always return 1
5040 // Required for frapsvid.dll 2.8.1, return value does not matter
5041 static WIN_BOOL WINAPI
expEnumDisplaySettingsA(LPCSTR name
,DWORD n
,
5044 dbgprintf("EnumDisplaySettingsA (dummy) => 1\n");
5048 // Fake implementation of _decode_pointer from msvcr80.dll, needed by sirenacm.dll
5049 // NOTE: undocumented function, probably the declaration is not right
5050 static int exp_decode_pointer(void *ptr
)
5052 dbgprintf("_decode_pointer (0x%08x)\n", ptr
);
5056 /* Fake implementation of sdt::_Lockit::_Lockit(void) from msvcp60.dll
5057 Needed by SCLS.DLL */
5058 static int exp_0Lockit_dummy(void)
5060 dbgprintf("0Lockit_dummy (??0_Lockit@std@@QAE@XZ)\n");
5064 /* Fake implementation of sdt::_Lockit::~_Lockit(void) from msvcp60.dll
5065 Needed by SCLS.DLL */
5066 static int exp_1Lockit_dummy(void)
5068 dbgprintf("1Lockit_dummy (??1_Lockit@std@@QAE@XZ)\n");
5072 static void * WINAPI
expEncodePointer(void *p
)
5077 static void * WINAPI
expDecodePointer(void *p
)
5082 static DWORD WINAPI
expGetThreadLocale(void)
5088 * Very incomplete implementation, return an error for almost all cases.
5090 static DWORD WINAPI
expGetLocaleInfoA(DWORD locale
, DWORD lctype
, char* lpLCData
, int cchData
)
5092 if (lctype
== 0x1004) { // LOCALE_IDEFAULTANSICODEPAGE
5094 return cchData
== 0 ? 4 : 0;
5095 strcpy(lpLCData
, "437");
5111 struct exports
* exps
;
5115 {#X, Y, (void*)exp##X},
5117 #define UNDEFF(X, Y) \
5120 struct exports exp_kernel32
[]=
5122 FF(GetVolumeInformationA
,-1)
5123 FF(GetDriveTypeA
,-1)
5124 FF(GetLogicalDriveStringsA
,-1)
5125 FF(IsBadWritePtr
, 357)
5126 FF(IsBadReadPtr
, 354)
5127 FF(IsBadStringPtrW
, -1)
5128 FF(IsBadStringPtrA
, -1)
5129 FF(DisableThreadLibraryCalls
, -1)
5130 FF(CreateThread
, -1)
5131 FF(ResumeThread
, -1)
5132 FF(CreateEventA
, -1)
5135 FF(WaitForSingleObject
, -1)
5136 #ifdef CONFIG_QTX_CODECS
5137 FF(WaitForMultipleObjects
, -1)
5140 FF(GetSystemInfo
, -1)
5148 FF(GetProcessHeap
, -1)
5149 FF(VirtualAlloc
, -1)
5151 FF(InitializeCriticalSection
, -1)
5152 FF(InitializeCriticalSectionAndSpinCount
, -1)
5153 FF(EnterCriticalSection
, -1)
5154 FF(LeaveCriticalSection
, -1)
5155 FF(DeleteCriticalSection
, -1)
5160 FF(GetCurrentThreadId
, -1)
5161 FF(GetCurrentProcess
, -1)
5166 FF(GlobalReAlloc
, -1)
5169 FF(MultiByteToWideChar
, 427)
5170 FF(WideCharToMultiByte
, -1)
5171 FF(GetVersionExA
, -1)
5172 FF(CreateSemaphoreA
, -1)
5173 FF(QueryPerformanceCounter
, -1)
5174 FF(QueryPerformanceFrequency
, -1)
5178 FF(GlobalHandle
, -1)
5179 FF(GlobalUnlock
, -1)
5181 FF(LoadResource
, -1)
5182 FF(ReleaseSemaphore
, -1)
5183 FF(CreateMutexA
, -1)
5184 FF(ReleaseMutex
, -1)
5185 FF(SignalObjectAndWait
, -1)
5186 FF(FindResourceA
, -1)
5187 FF(LockResource
, -1)
5188 FF(FreeResource
, -1)
5189 FF(SizeofResource
, -1)
5191 FF(GetCommandLineA
, -1)
5192 FF(GetEnvironmentStringsW
, -1)
5193 FF(FreeEnvironmentStringsW
, -1)
5194 FF(FreeEnvironmentStringsA
, -1)
5195 FF(GetEnvironmentStrings
, -1)
5196 FF(GetStartupInfoA
, -1)
5197 FF(GetStdHandle
, -1)
5199 #ifdef CONFIG_QTX_CODECS
5200 FF(GetFileAttributesA
, -1)
5202 FF(SetHandleCount
, -1)
5204 FF(GetModuleFileNameA
, -1)
5205 FF(SetUnhandledExceptionFilter
, -1)
5206 FF(LoadLibraryA
, -1)
5207 FF(GetProcAddress
, -1)
5209 FF(CreateFileMappingA
, -1)
5210 FF(OpenFileMappingA
, -1)
5211 FF(MapViewOfFile
, -1)
5212 FF(UnmapViewOfFile
, -1)
5214 FF(GetModuleHandleA
, -1)
5215 FF(GetModuleHandleW
, -1)
5216 FF(GetProfileIntA
, -1)
5217 FF(GetPrivateProfileIntA
, -1)
5218 FF(GetPrivateProfileStringA
, -1)
5219 FF(WritePrivateProfileStringA
, -1)
5220 FF(GetLastError
, -1)
5221 FF(SetLastError
, -1)
5222 FF(InterlockedIncrement
, -1)
5223 FF(InterlockedDecrement
, -1)
5224 FF(GetTimeZoneInformation
, -1)
5225 FF(OutputDebugStringA
, -1)
5226 FF(GetLocalTime
, -1)
5227 FF(GetSystemTime
, -1)
5228 FF(GetSystemTimeAsFileTime
, -1)
5229 FF(GetEnvironmentVariableA
, -1)
5230 FF(SetEnvironmentVariableA
, -1)
5231 FF(RtlZeroMemory
,-1)
5232 FF(RtlMoveMemory
,-1)
5233 FF(RtlFillMemory
,-1)
5235 FF(FindFirstFileA
,-1)
5236 FF(FindNextFileA
,-1)
5238 FF(FileTimeToLocalFileTime
,-1)
5242 FF(SetFilePointer
,-1)
5243 FF(GetTempFileNameA
,-1)
5245 FF(GetSystemDirectoryA
,-1)
5246 FF(GetWindowsDirectoryA
,-1)
5247 #ifdef CONFIG_QTX_CODECS
5248 FF(GetCurrentDirectoryA
,-1)
5249 FF(SetCurrentDirectoryA
,-1)
5250 FF(CreateDirectoryA
,-1)
5252 FF(GetShortPathNameA
,-1)
5253 FF(GetFullPathNameA
,-1)
5254 FF(SetErrorMode
, -1)
5255 FF(IsProcessorFeaturePresent
, -1)
5256 FF(IsDebuggerPresent
, -1)
5257 FF(GetProcessAffinityMask
, -1)
5258 FF(InterlockedExchange
, -1)
5259 FF(InterlockedCompareExchange
, -1)
5266 FF(GetProcessVersion
,-1)
5267 FF(GetCurrentThread
,-1)
5270 FF(DuplicateHandle
,-1)
5271 FF(GetTickCount
, -1)
5272 FF(SetThreadAffinityMask
,-1)
5273 FF(GetCurrentProcessId
,-1)
5274 FF(GlobalMemoryStatus
,-1)
5275 FF(GetThreadPriority
,-1)
5276 FF(SetThreadPriority
,-1)
5277 FF(TerminateProcess
,-1)
5279 {"LoadLibraryExA", -1, (void*)&LoadLibraryExA
},
5280 FF(SetThreadIdealProcessor
,-1)
5281 FF(SetProcessAffinityMask
, -1)
5282 FF(EncodePointer
, -1)
5283 FF(DecodePointer
, -1)
5284 FF(GetThreadLocale
, -1)
5285 FF(GetLocaleInfoA
, -1)
5286 UNDEFF(FlsAlloc
, -1)
5287 UNDEFF(FlsGetValue
, -1)
5288 UNDEFF(FlsSetValue
, -1)
5292 struct exports exp_msvcrt
[]={
5298 {"??3@YAXPAX@Z", -1, expdelete
},
5299 {"??2@YAPAXI@Z", -1, expnew
},
5300 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5301 {"_winver",-1,(void*)&_winver
},
5342 /* needed by frapsvid.dll */
5343 {"strstr",-1,(char *)&strstr
},
5344 {"qsort",-1,(void *)&qsort
},
5347 {"ceil",-1,(void*)&ceil
},
5348 /* needed by imagepower mjpeg2k */
5349 {"clock",-1,(void*)&clock
},
5350 {"memchr",-1,(void*)&memchr
},
5351 {"vfprintf",-1,(void*)&vfprintf
},
5352 // {"realloc",-1,(void*)&realloc},
5354 {"puts",-1,(void*)&puts
}
5356 struct exports exp_winmm
[]={
5357 FF(GetDriverModuleHandle
, -1)
5359 FF(DefDriverProc
, -1)
5362 FF(timeGetDevCaps
, -1)
5363 FF(timeBeginPeriod
, -1)
5364 #ifdef CONFIG_QTX_CODECS
5365 FF(timeEndPeriod
, -1)
5366 FF(waveOutGetNumDevs
, -1)
5369 struct exports exp_psapi
[]={
5370 FF(GetModuleBaseNameA
, -1)
5372 struct exports exp_user32
[]={
5377 FF(GetDesktopWindow
, -1)
5383 #ifdef CONFIG_QTX_CODECS
5386 FF(RegisterWindowMessageA
,-1)
5387 FF(GetSystemMetrics
,-1)
5389 FF(GetSysColorBrush
,-1)
5393 FF(RegisterClassA
, -1)
5394 FF(UnregisterClassA
, -1)
5395 #ifdef CONFIG_QTX_CODECS
5396 FF(GetWindowRect
, -1)
5397 FF(MonitorFromWindow
, -1)
5398 FF(MonitorFromRect
, -1)
5399 FF(MonitorFromPoint
, -1)
5400 FF(EnumDisplayMonitors
, -1)
5401 FF(GetMonitorInfoA
, -1)
5402 FF(EnumDisplayDevicesA
, -1)
5403 FF(GetClientRect
, -1)
5404 FF(ClientToScreen
, -1)
5405 FF(IsWindowVisible
, -1)
5406 FF(GetActiveWindow
, -1)
5407 FF(GetClassNameA
, -1)
5408 FF(GetClassInfoA
, -1)
5409 FF(GetWindowLongA
, -1)
5411 FF(GetWindowThreadProcessId
, -1)
5412 FF(CreateWindowExA
, -1)
5415 FF(DialogBoxParamA
, -1)
5416 FF(RegisterClipboardFormatA
, -1)
5418 FF(EnumDisplaySettingsA
, -1)
5420 struct exports exp_advapi32
[]={
5422 FF(RegCreateKeyA
, -1)
5423 FF(RegCreateKeyExA
, -1)
5424 FF(RegEnumKeyExA
, -1)
5425 FF(RegEnumValueA
, -1)
5427 FF(RegOpenKeyExA
, -1)
5428 FF(RegQueryValueExA
, -1)
5429 FF(RegSetValueExA
, -1)
5430 FF(RegQueryInfoKeyA
, -1)
5432 struct exports exp_gdi32
[]={
5433 FF(CreateCompatibleDC
, -1)
5436 FF(DeleteObject
, -1)
5437 FF(GetDeviceCaps
, -1)
5438 FF(GetSystemPaletteEntries
, -1)
5439 #ifdef CONFIG_QTX_CODECS
5440 FF(CreatePalette
, -1)
5442 FF(CreateRectRgn
, -1)
5445 struct exports exp_version
[]={
5446 FF(GetFileVersionInfoSizeA
, -1)
5448 struct exports exp_ole32
[]={
5449 FF(CoCreateFreeThreadedMarshaler
,-1)
5450 FF(CoCreateInstance
, -1)
5451 FF(CoInitialize
, -1)
5452 FF(CoInitializeEx
, -1)
5453 FF(CoUninitialize
, -1)
5454 FF(CoTaskMemAlloc
, -1)
5455 FF(CoTaskMemFree
, -1)
5456 FF(StringFromGUID2
, -1)
5457 FF(PropVariantClear
, -1)
5459 // do we really need crtdll ???
5460 // msvcrt is the correct place probably...
5461 struct exports exp_crtdll
[]={
5465 struct exports exp_comctl32
[]={
5466 FF(StringFromGUID2
, -1)
5467 FF(InitCommonControls
, 17)
5468 #ifdef CONFIG_QTX_CODECS
5469 FF(CreateUpDownControl
, 16)
5472 struct exports exp_wsock32
[]={
5476 struct exports exp_msdmo
[]={
5477 FF(memcpy
, -1) // just test
5478 FF(MoCopyMediaType
, -1)
5479 FF(MoCreateMediaType
, -1)
5480 FF(MoDeleteMediaType
, -1)
5481 FF(MoDuplicateMediaType
, -1)
5482 FF(MoFreeMediaType
, -1)
5483 FF(MoInitMediaType
, -1)
5485 struct exports exp_oleaut32
[]={
5486 FF(SysAllocStringLen
, 4)
5487 FF(SysFreeString
, 6)
5489 #ifdef CONFIG_QTX_CODECS
5490 FF(SysStringByteLen
, 149)
5496 vma: Hint/Ord Member-Name
5501 2305e 167 _adjust_fdiv
5504 22ffc 176 _beginthreadex
5506 2300e 85 __CxxFrameHandler
5510 struct exports exp_pncrt
[]={
5511 FF(malloc
, -1) // just test
5512 FF(free
, -1) // just test
5513 FF(fprintf
, -1) // just test
5514 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv
},
5517 {"??3@YAXPAX@Z", -1, expdelete
},
5518 {"??2@YAPAXI@Z", -1, expnew
},
5529 #ifdef CONFIG_QTX_CODECS
5530 struct exports exp_ddraw
[]={
5531 FF(DirectDrawCreate
, -1)
5535 struct exports exp_comdlg32
[]={
5536 FF(GetOpenFileNameA
, -1)
5539 struct exports exp_shlwapi
[]={
5540 FF(PathFindExtensionA
, -1)
5541 FF(PathFindFileNameA
, -1)
5544 struct exports exp_msvcr80
[]={
5552 FF(_decode_pointer
, -1)
5553 /* needed by KGV1-VFW.dll */
5554 {"??2@YAPAXI@Z", -1, expnew
},
5555 {"??3@YAXPAX@Z", -1, expdelete
}
5558 struct exports exp_msvcp60
[]={
5559 {"??0_Lockit@std@@QAE@XZ", -1, exp_0Lockit_dummy
},
5560 {"??1_Lockit@std@@QAE@XZ", -1, exp_1Lockit_dummy
}
5564 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5566 struct libs libraries
[]={
5584 #ifdef CONFIG_QTX_CODECS
5593 static WIN_BOOL WINAPI
ext_stubs(void)
5595 // NOTE! these magic values will be replaced at runtime, make sure
5596 // add_stub can still find them if you change them.
5597 volatile int idx
= 0x0deadabc;
5598 // make sure gcc does not do eip-relative call or something like that
5599 void (* volatile my_printf
)(char *, char *) = (void *)0xdeadfbcd;
5600 my_printf("Called unk_%s\n", export_names
[idx
]);
5604 #define MAX_STUB_SIZE 0x60
5605 #define MAX_NUM_STUBS 200
5607 static char *extcode
= NULL
;
5609 static void* add_stub(void)
5613 // generated code in runtime!
5616 extcode
= mmap_anon(NULL
, MAX_NUM_STUBS
* MAX_STUB_SIZE
,
5617 PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
, 0);
5618 answ
= extcode
+ pos
* MAX_STUB_SIZE
;
5619 if (pos
>= MAX_NUM_STUBS
) {
5620 printf("too many stubs, expect crash\n");
5623 memcpy(answ
, ext_stubs
, MAX_STUB_SIZE
);
5624 for (i
= 0; i
< MAX_STUB_SIZE
- 3; i
++) {
5625 int *magic
= (int *)(answ
+ i
);
5626 if (*magic
== 0x0deadabc) {
5630 if (*magic
== 0xdeadfbcd) {
5631 *magic
= (intptr_t)printf
;
5636 printf("magic code not found in ext_subs, expect crash\n");
5643 void* LookupExternal(const char* library
, int ordinal
)
5648 printf("ERROR: library=0\n");
5649 return (void*)ext_unknown
;
5651 // printf("%x %x\n", &unk_exp1, &unk_exp2);
5653 dbgprintf("External func %s:%d\n", library
, ordinal
);
5655 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5657 if(strcasecmp(library
, libraries
[i
].name
))
5659 for(j
=0; j
<libraries
[i
].length
; j
++)
5661 if(ordinal
!=libraries
[i
].exps
[j
].id
)
5663 //printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5664 return libraries
[i
].exps
[j
].func
;
5668 #ifndef LOADLIB_TRY_NATIVE
5669 /* hack for truespeech and vssh264*/
5670 if (!strcmp(library
, "tsd32.dll") || !strcmp(library
,"vssh264dec.dll") || !strcmp(library
,"LCMW2.dll") || !strcmp(library
,"VDODEC32.dll"))
5672 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5678 hand
= LoadLibraryA(library
);
5681 wm
= MODULE32_LookupHMODULE(hand
);
5687 func
= PE_FindExportedFunction(wm
, (LPCSTR
) ordinal
, 0);
5690 printf("No such ordinal in external dll\n");
5691 FreeLibrary((int)hand
);
5695 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5701 if(pos
>150)return 0;
5702 snprintf(export_names
[pos
], sizeof(export_names
[pos
]), "%s:%d", library
, ordinal
);
5706 void* LookupExternalByName(const char* library
, const char* name
)
5709 // return (void*)ext_unknown;
5712 printf("ERROR: library=0\n");
5713 return (void*)ext_unknown
;
5715 if((unsigned long)name
<=0xffff)
5717 return LookupExternal(library
, (int)name
);
5719 dbgprintf("External func %s:%s\n", library
, name
);
5720 for(i
=0; i
<sizeof(libraries
)/sizeof(struct libs
); i
++)
5722 if(strcasecmp(library
, libraries
[i
].name
))
5724 for(j
=0; j
<libraries
[i
].length
; j
++)
5726 if(strcmp(name
, libraries
[i
].exps
[j
].name
))
5728 if((unsigned int)(libraries
[i
].exps
[j
].func
) == -1)
5729 return NULL
; //undefined func
5730 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5731 return libraries
[i
].exps
[j
].func
;
5735 #ifndef LOADLIB_TRY_NATIVE
5736 /* hack for vss h264 */
5737 if (!strcmp(library
,"vssh264core.dll") || !strcmp(library
,"3ivx.dll"))
5739 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5745 hand
= LoadLibraryA(library
);
5748 wm
= MODULE32_LookupHMODULE(hand
);
5754 func
= PE_FindExportedFunction(wm
, name
, 0);
5757 printf("No such name in external dll\n");
5758 FreeLibrary((int)hand
);
5762 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5768 if(pos
>150)return 0;// to many symbols
5769 snprintf(export_names
[pos
], sizeof(export_names
[pos
]), "%s", name
);
5773 void my_garbagecollection(void)
5776 int unfree
= 0, unfreecnt
= 0;
5782 alloc_header
* mem
= last_alloc
+ 1;
5783 unfree
+= my_size(mem
);
5785 if (my_release(mem
) != 0)
5786 // avoid endless loop when memory is trashed
5787 if (--max_fatal
< 0)
5790 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree
, unfreecnt
, last_alloc
, alccnt
);
5793 pthread_mutex_lock(&list_lock
);
5795 pthread_mutex_unlock(&list_lock
);