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 CVS changelog at
16
* http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
17
* $Id: win32.c,v 1.107 2005/12/01 21:59:24 rtognimp Exp $
27
//#define LOADLIB_TRY_NATIVE
31
#define PSEUDO_SCREEN_WIDTH /*640*/800
32
#define PSEUDO_SCREEN_HEIGHT /*480*/600
35
#include "wine/winbase.h"
36
#include "wine/winreg.h"
37
#include "wine/winnt.h"
38
#include "wine/winerror.h"
39
#include "wine/debugtools.h"
40
#include "wine/module.h"
41
#include "wine/winuser.h"
64
#include <sys/types.h>
67
#include <sys/timeb.h>
73
int vsscanf( const char *str, const char *format, va_list ap);
75
/* system has no vsscanf. try to provide one */
76
static int vsscanf( const char *str, const char *format, va_list ap)
78
long p1 = va_arg(ap, long);
79
long p2 = va_arg(ap, long);
80
long p3 = va_arg(ap, long);
81
long p4 = va_arg(ap, long);
82
long p5 = va_arg(ap, long);
83
return sscanf(str, format, p1, p2, p3, p4, p5);
87
char* def_path = WIN32_PATH;
89
static void do_cpuid(unsigned int ax, unsigned int *regs)
93
"pushl %%ebx; pushl %%ecx; pushl %%edx;"
99
"popl %%edx; popl %%ecx; popl %%ebx;"
101
: "0" (ax), "S" (regs)
104
static unsigned int c_localcount_tsc()
116
static void c_longcount_tsc(long long* z)
121
"movl %%eax, %%ebx\n\t"
123
"movl %%eax, 0(%%ebx)\n\t"
124
"movl %%edx, 4(%%ebx)\n\t"
130
static unsigned int c_localcount_notsc()
135
gettimeofday(&tv, 0);
136
return limit*tv.tv_usec;
138
static void c_longcount_notsc(long long* z)
141
unsigned long long result;
145
gettimeofday(&tv, 0);
148
result+=limit*tv.tv_usec;
151
static unsigned int localcount_stub(void);
152
static void longcount_stub(long long*);
153
static unsigned int (*localcount)()=localcount_stub;
154
static void (*longcount)(long long*)=longcount_stub;
156
static pthread_mutex_t memmut;
158
static unsigned int localcount_stub(void)
160
unsigned int regs[4];
162
if ((regs[3] & 0x00000010) != 0)
164
localcount=c_localcount_tsc;
165
longcount=c_longcount_tsc;
169
localcount=c_localcount_notsc;
170
longcount=c_longcount_notsc;
174
static void longcount_stub(long long* z)
176
unsigned int regs[4];
178
if ((regs[3] & 0x00000010) != 0)
180
localcount=c_localcount_tsc;
181
longcount=c_longcount_tsc;
185
localcount=c_localcount_notsc;
186
longcount=c_longcount_notsc;
194
int LOADER_DEBUG=1; // active only if compiled with -DDETAILED_OUT
195
//#define DETAILED_OUT
196
static inline void dbgprintf(char* fmt, ...)
204
f=fopen("./log", "a");
209
vfprintf(f, fmt, va);
223
// mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va);
231
char export_names[300][32]={
236
//#define min(x,y) ((x)<(y)?(x):(y))
238
void destroy_event(void* event);
241
typedef struct th_list_t{
244
struct th_list_t* next;
245
struct th_list_t* prev;
249
// have to be cleared by GARBAGE COLLECTOR
250
static unsigned char* heap=NULL;
251
static int heap_counter=0;
252
static tls_t* g_tls=NULL;
253
static th_list* list=NULL;
255
static void test_heap(void)
260
while(offset<heap_counter)
262
if(*(int*)(heap+offset)!=0x433476)
264
printf("Heap corruption at address %d\n", offset);
267
offset+=8+*(int*)(heap+offset+4);
269
for(;offset<min(offset+1000, 20000000); offset++)
270
if(heap[offset]!=0xCC)
272
printf("Free heap corruption at address %d\n", offset);
279
static void* my_mreq(int size, int to_zero)
283
if(test%10==0)printf("Memory: %d bytes allocated\n", heap_counter);
287
heap=malloc(20000000);
288
memset(heap, 0xCC,20000000);
292
printf("No enough memory\n");
295
if(heap_counter+size>20000000)
297
printf("No enough memory\n");
300
*(int*)(heap+heap_counter)=0x433476;
302
*(int*)(heap+heap_counter)=size;
304
printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size, heap_counter-8, heap_counter, heap_counter+size);
306
memset(heap+heap_counter, 0, size);
308
memset(heap+heap_counter, 0xcc, size); // make crash reproducable
310
return heap+heap_counter-size;
312
static int my_release(char* memory)
317
printf("ERROR: free(0)\n");
320
if(*(int*)(memory-8)!=0x433476)
322
printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
325
printf("Freed %d bytes of memory\n", *(int*)(memory-4));
326
// memset(memory-8, *(int*)(memory-4), 0xCC);
332
typedef struct alloc_header_t alloc_header;
333
struct alloc_header_t
335
// let's keep allocated data 16 byte aligned
347
static alloc_header* last_alloc = NULL;
348
static int alccnt = 0;
351
#define AREATYPE_CLIENT 0
352
#define AREATYPE_EVENT 1
353
#define AREATYPE_MUTEX 2
354
#define AREATYPE_COND 3
355
#define AREATYPE_CRITSECT 4
357
/* -- critical sections -- */
361
pthread_mutex_t mutex;
366
void* mreq_private(int size, int to_zero, int type);
367
void* mreq_private(int size, int to_zero, int type)
369
int nsize = size + sizeof(alloc_header);
370
alloc_header* header = (alloc_header* ) malloc(nsize);
374
memset(header, 0, nsize);
378
pthread_mutex_init(&memmut, NULL);
379
pthread_mutex_lock(&memmut);
383
pthread_mutex_lock(&memmut);
384
last_alloc->next = header; /* set next */
387
header->prev = last_alloc;
391
pthread_mutex_unlock(&memmut);
393
header->deadbeef = 0xdeadbeef;
397
//if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt);
401
static int my_release(void* memory)
403
alloc_header* header = (alloc_header*) memory - 1;
405
alloc_header* prevmem;
406
alloc_header* nextmem;
411
if (header->deadbeef != (long) 0xdeadbeef)
413
dbgprintf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt);
417
pthread_mutex_lock(&memmut);
422
destroy_event(memory);
425
pthread_cond_destroy((pthread_cond_t*)memory);
428
pthread_mutex_destroy((pthread_mutex_t*)memory);
430
case AREATYPE_CRITSECT:
431
pthread_mutex_destroy(&((struct CRITSECT*)memory)->mutex);
434
//memset(memory, 0xcc, header->size);
438
header->deadbeef = 0;
439
prevmem = header->prev;
440
nextmem = header->next;
443
prevmem->next = nextmem;
445
nextmem->prev = prevmem;
447
if (header == last_alloc)
448
last_alloc = prevmem;
453
pthread_mutex_unlock(&memmut);
455
pthread_mutex_destroy(&memmut);
457
//if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt);
462
//memset(header + 1, 0xcc, header->size);
468
static inline void* my_mreq(int size, int to_zero)
470
return mreq_private(size, to_zero, AREATYPE_CLIENT);
473
static int my_size(void* memory)
475
if(!memory) return 0;
476
return ((alloc_header*)memory)[-1].size;
479
static void* my_realloc(void* memory, int size)
484
return my_mreq(size, 0);
485
osize = my_size(memory);
488
ans = my_mreq(size, 0);
489
memcpy(ans, memory, osize);
497
* WINE API - native implementation for several win32 libraries
501
static int WINAPI ext_unknown()
503
printf("Unknown func called\n");
507
static int WINAPI expGetVolumeInformationA( const char *root, char *label,
508
unsigned int label_len, unsigned int *serial,
509
unsigned int *filename_len,unsigned int *flags,
510
char *fsname, unsigned int fsname_len )
512
dbgprintf("GetVolumeInformationA( %s, 0x%x, %ld, 0x%x, 0x%x, 0x%x, 0x%x, %ld) => 1\n",
513
root,label,label_len,serial,filename_len,flags,fsname,fsname_len);
514
//hack Do not return any real data - do nothing
518
static unsigned int WINAPI expGetDriveTypeA( const char *root )
520
dbgprintf("GetDriveTypeA( %s ) => %d\n",root,DRIVE_FIXED);
521
// hack return as Fixed Drive Type
525
static unsigned int WINAPI expGetLogicalDriveStringsA( unsigned int len, char *buffer )
527
dbgprintf("GetLogicalDriveStringsA(%d, 0x%x) => 4\n",len,buffer);
528
// hack only have one drive c:\ in this hack
534
return 4; // 1 drive * 4 bytes (includes null)
538
static int WINAPI expIsBadWritePtr(void* ptr, unsigned int count)
540
int result = (count == 0 || ptr != 0) ? 0 : 1;
541
dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr, count, result);
544
static int WINAPI expIsBadReadPtr(void* ptr, unsigned int count)
546
int result = (count == 0 || ptr != 0) ? 0 : 1;
547
dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr, count, result);
550
static int WINAPI expDisableThreadLibraryCalls(int module)
552
dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module);
556
static HMODULE WINAPI expGetDriverModuleHandle(DRVR* pdrv)
562
result=pdrv->hDriverModule;
563
dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv, result);
567
#define MODULE_HANDLE_kernel32 ((HMODULE)0x120)
568
#define MODULE_HANDLE_user32 ((HMODULE)0x121)
570
#define MODULE_HANDLE_wininet ((HMODULE)0x122)
571
#define MODULE_HANDLE_ddraw ((HMODULE)0x123)
572
#define MODULE_HANDLE_advapi32 ((HMODULE)0x124)
574
#define MODULE_HANDLE_comdlg32 ((HMODULE)0x125)
575
#define MODULE_HANDLE_msvcrt ((HMODULE)0x126)
576
#define MODULE_HANDLE_ole32 ((HMODULE)0x127)
577
#define MODULE_HANDLE_winmm ((HMODULE)0x128)
579
static HMODULE WINAPI expGetModuleHandleA(const char* name)
591
wm=MODULE_FindModule(name);
594
result=(HMODULE)(wm->module);
598
if(name && (strcasecmp(name, "kernel32")==0 || !strcasecmp(name, "kernel32.dll")))
599
result=MODULE_HANDLE_kernel32;
601
if(name && strcasecmp(name, "user32")==0)
602
result=MODULE_HANDLE_user32;
605
dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name, result);
609
static void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize,
610
void* lpStartAddress, void* lpParameter,
611
long dwFlags, long* dwThreadId)
614
// printf("CreateThread:");
615
pth = (pthread_t*) my_mreq(sizeof(pthread_t), 0);
616
pthread_create(pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter);
618
printf( "WARNING: CreateThread flags not supported\n");
620
*dwThreadId=(long)pth;
623
list=my_mreq(sizeof(th_list), 1);
624
list->next=list->prev=NULL;
628
list->next=my_mreq(sizeof(th_list), 0);
629
list->next->prev=list;
630
list->next->next=NULL;
634
dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
635
pSecAttr, dwStackSize, lpStartAddress, lpParameter, dwFlags, dwThreadId, pth);
650
struct mutex_list_t* next;
651
struct mutex_list_t* prev;
653
typedef struct mutex_list_t mutex_list;
654
static mutex_list* mlist=NULL;
656
void destroy_event(void* event)
658
mutex_list* pp=mlist;
659
// printf("garbage collector: destroy_event(%x)\n", event);
662
if(pp==(mutex_list*)event)
665
pp->next->prev=pp->prev;
667
pp->prev->next=pp->next;
668
if(mlist==(mutex_list*)event)
674
printf("%x => ", pp);
685
static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
686
char bInitialState, const char* name)
695
printf("%x => ", pp);
702
mutex_list* pp=mlist;
706
if((strcmp(pp->name, name)==0) && (pp->type==0))
708
dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
709
pSecAttr, bManualReset, bInitialState, name, name, pp->pm);
712
}while((pp=pp->prev) != NULL);
714
pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
715
pthread_mutex_init(pm, NULL);
716
pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
717
pthread_cond_init(pc, NULL);
720
mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
721
mlist->next=mlist->prev=NULL;
725
mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
726
mlist->next->prev=mlist;
727
mlist->next->next=NULL;
730
mlist->type=0; /* Type Event */
733
mlist->state=bInitialState;
734
mlist->reset=bManualReset;
736
strncpy(mlist->name, name, 127);
740
dbgprintf("ERROR::: CreateEventA failure\n");
743
pthread_mutex_lock(pm);
746
dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
747
pSecAttr, bManualReset, bInitialState, name, name, mlist);
749
dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
750
pSecAttr, bManualReset, bInitialState, mlist);
754
static void* WINAPI expSetEvent(void* event)
756
mutex_list *ml = (mutex_list *)event;
757
dbgprintf("SetEvent(%x) => 0x1\n", event);
758
pthread_mutex_lock(ml->pm);
759
if (ml->state == 0) {
761
pthread_cond_signal(ml->pc);
763
pthread_mutex_unlock(ml->pm);
767
static void* WINAPI expResetEvent(void* event)
769
mutex_list *ml = (mutex_list *)event;
770
dbgprintf("ResetEvent(0x%x) => 0x1\n", event);
771
pthread_mutex_lock(ml->pm);
773
pthread_mutex_unlock(ml->pm);
778
static void* WINAPI expWaitForSingleObject(void* object, int duration)
780
mutex_list *ml = (mutex_list *)object;
781
// FIXME FIXME FIXME - this value is sometime unititialize !!!
782
int ret = WAIT_FAILED;
783
mutex_list* pp=mlist;
784
if(object == (void*)0xcfcf9898)
787
From GetCurrentThread() documentation:
788
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.
790
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.
792
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.
794
dbgprintf("WaitForSingleObject(thread_handle) called\n");
795
return (void*)WAIT_FAILED;
797
dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object, duration);
799
// loop below was slightly fixed - its used just for checking if
800
// this object really exists in our list
803
while (pp && (pp->pm != ml->pm))
806
dbgprintf("WaitForSingleObject: NotFound\n");
810
pthread_mutex_lock(ml->pm);
814
if (duration == 0) { /* Check Only */
815
if (ml->state == 1) ret = WAIT_FAILED;
816
else ret = WAIT_OBJECT_0;
818
if (duration == -1) { /* INFINITE */
820
pthread_cond_wait(ml->pc,ml->pm);
825
if (duration > 0) { /* Timed Wait */
826
struct timespec abstime;
828
gettimeofday(&now, 0);
829
abstime.tv_sec = now.tv_sec + (now.tv_usec+duration)/1000000;
830
abstime.tv_nsec = ((now.tv_usec+duration)%1000000)*1000;
832
ret=pthread_cond_timedwait(ml->pc,ml->pm,&abstime);
833
if (ret == ETIMEDOUT) ret = WAIT_TIMEOUT;
834
else ret = WAIT_OBJECT_0;
839
case 1: /* Semaphore */
841
if(ml->semaphore==0) ret = WAIT_FAILED;
847
if (duration == -1) {
848
if (ml->semaphore==0)
849
pthread_cond_wait(ml->pc,ml->pm);
854
pthread_mutex_unlock(ml->pm);
856
dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object,duration,ml,ret);
861
static void* WINAPI expWaitForMultipleObjects(int count, const void** objects,
862
int WaitAll, int duration)
868
dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
869
count, objects, WaitAll, duration);
871
for (i = 0; i < count; i++)
873
object = (void *)objects[i];
874
ret = expWaitForSingleObject(object, duration);
876
dbgprintf("WaitAll flag not yet supported...\n");
883
static void WINAPI expExitThread(int retcode)
885
dbgprintf("ExitThread(%d)\n", retcode);
886
pthread_exit(&retcode);
889
static HANDLE WINAPI expCreateMutexA(void *pSecAttr,
890
char bInitialOwner, const char *name)
892
HANDLE mlist = (HANDLE)expCreateEventA(pSecAttr, 0, 0, name);
895
dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
896
pSecAttr, bInitialOwner, name, mlist);
898
dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
899
pSecAttr, bInitialOwner, mlist);
901
/* 10l to QTX, if CreateMutex returns a real mutex, WaitForSingleObject
902
waits for ever, else it works ;) */
907
static int WINAPI expReleaseMutex(HANDLE hMutex)
909
dbgprintf("ReleaseMutex(%x) => 1\n", hMutex);
910
/* FIXME:XXX !! not yet implemented */
915
static int pf_set = 0;
916
static BYTE PF[64] = {0,};
918
static void DumpSystemInfo(const SYSTEM_INFO* si)
920
dbgprintf(" Processor architecture %d\n", si->u.s.wProcessorArchitecture);
921
dbgprintf(" Page size: %d\n", si->dwPageSize);
922
dbgprintf(" Minimum app address: %d\n", si->lpMinimumApplicationAddress);
923
dbgprintf(" Maximum app address: %d\n", si->lpMaximumApplicationAddress);
924
dbgprintf(" Active processor mask: 0x%x\n", si->dwActiveProcessorMask);
925
dbgprintf(" Number of processors: %d\n", si->dwNumberOfProcessors);
926
dbgprintf(" Processor type: 0x%x\n", si->dwProcessorType);
927
dbgprintf(" Allocation granularity: 0x%x\n", si->dwAllocationGranularity);
928
dbgprintf(" Processor level: 0x%x\n", si->wProcessorLevel);
929
dbgprintf(" Processor revision: 0x%x\n", si->wProcessorRevision);
932
static void WINAPI expGetSystemInfo(SYSTEM_INFO* si)
934
/* FIXME: better values for the two entries below... */
935
static int cache = 0;
936
static SYSTEM_INFO cachedsi;
937
unsigned int regs[4];
938
dbgprintf("GetSystemInfo(%p) =>\n", si);
943
memset(PF,0,sizeof(PF));
946
cachedsi.u.s.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
947
cachedsi.dwPageSize = getpagesize();
949
/* FIXME: better values for the two entries below... */
950
cachedsi.lpMinimumApplicationAddress = (void *)0x00000000;
951
cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF;
952
cachedsi.dwActiveProcessorMask = 1;
953
cachedsi.dwNumberOfProcessors = 1;
954
cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
955
cachedsi.dwAllocationGranularity = 0x10000;
956
cachedsi.wProcessorLevel = 5; /* pentium */
957
cachedsi.wProcessorRevision = 0x0101;
960
/* mplayer's way to detect PF's */
962
#include "cpudetect.h"
963
extern CpuCaps gCpuCaps;
966
PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
968
PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
969
if (gCpuCaps.hasSSE2)
970
PF[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = TRUE;
971
if (gCpuCaps.has3DNow)
972
PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
974
if (gCpuCaps.cpuType == 4)
976
cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
977
cachedsi.wProcessorLevel = 4;
979
else if (gCpuCaps.cpuType >= 5)
981
cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
982
cachedsi.wProcessorLevel = 5;
986
cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
987
cachedsi.wProcessorLevel = 3;
989
cachedsi.wProcessorRevision = gCpuCaps.cpuStepping;
990
cachedsi.dwNumberOfProcessors = 1; /* hardcoded */
994
/* disable cpuid based detection (mplayer's cpudetect.c does this - see above) */
996
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__svr4__) || defined(__DragonFly__)
998
switch ((regs[0] >> 8) & 0xf) { // cpu family
999
case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1000
cachedsi.wProcessorLevel= 3;
1002
case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1003
cachedsi.wProcessorLevel= 4;
1005
case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1006
cachedsi.wProcessorLevel= 5;
1008
case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1009
cachedsi.wProcessorLevel= 5;
1011
default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1012
cachedsi.wProcessorLevel= 5;
1015
cachedsi.wProcessorRevision = regs[0] & 0xf; // stepping
1016
if (regs[3] & (1 << 8))
1017
PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
1018
if (regs[3] & (1 << 23))
1019
PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
1020
if (regs[3] & (1 << 25))
1021
PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
1022
if (regs[3] & (1 << 31))
1023
PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
1024
cachedsi.dwNumberOfProcessors=1;
1026
#endif /* MPLAYER */
1028
/* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
1029
fdiv_bug and fpu emulation flags -- alex/MPlayer */
1034
FILE *f = fopen ("/proc/cpuinfo", "r");
1039
mp_msg(MSGT_WIN32, MSGL_WARN, "expGetSystemInfo: "
1040
"/proc/cpuinfo not readable! "
1041
"Expect bad performance and/or weird behaviour\n");
1045
while (fgets(line,200,f)!=NULL) {
1048
/* NOTE: the ':' is the only character we can rely on */
1049
if (!(value = strchr(line,':')))
1051
/* terminate the valuename */
1053
/* skip any leading spaces */
1054
while (*value==' ') value++;
1055
if ((s=strchr(value,'\n')))
1059
if (!lstrncmpiA(line, "cpu family",strlen("cpu family"))) {
1060
if (isdigit (value[0])) {
1061
switch (value[0] - '0') {
1062
case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1063
cachedsi.wProcessorLevel= 3;
1065
case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1066
cachedsi.wProcessorLevel= 4;
1068
case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1069
cachedsi.wProcessorLevel= 5;
1071
case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1072
cachedsi.wProcessorLevel= 5;
1074
default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1075
cachedsi.wProcessorLevel= 5;
1079
/* set the CPU type of the current processor */
1080
sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
1083
/* old 2.0 method */
1084
if (!lstrncmpiA(line, "cpu",strlen("cpu"))) {
1085
if ( isdigit (value[0]) && value[1] == '8' &&
1086
value[2] == '6' && value[3] == 0
1088
switch (value[0] - '0') {
1089
case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1090
cachedsi.wProcessorLevel= 3;
1092
case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1093
cachedsi.wProcessorLevel= 4;
1095
case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1096
cachedsi.wProcessorLevel= 5;
1098
case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1099
cachedsi.wProcessorLevel= 5;
1101
default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1102
cachedsi.wProcessorLevel= 5;
1106
/* set the CPU type of the current processor */
1107
sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
1110
if (!lstrncmpiA(line,"fdiv_bug",strlen("fdiv_bug"))) {
1111
if (!lstrncmpiA(value,"yes",3))
1112
PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE;
1116
if (!lstrncmpiA(line,"fpu",strlen("fpu"))) {
1117
if (!lstrncmpiA(value,"no",2))
1118
PF[PF_FLOATING_POINT_EMULATED] = TRUE;
1122
if (!lstrncmpiA(line,"processor",strlen("processor"))) {
1123
/* processor number counts up...*/
1126
if (sscanf(value,"%d",&x))
1127
if (x+1>cachedsi.dwNumberOfProcessors)
1128
cachedsi.dwNumberOfProcessors=x+1;
1130
/* Create a new processor subkey on a multiprocessor
1133
sprintf(buf,"%d",x);
1135
if (!lstrncmpiA(line,"stepping",strlen("stepping"))) {
1138
if (sscanf(value,"%d",&x))
1139
cachedsi.wProcessorRevision = x;
1142
( (!lstrncmpiA(line,"flags",strlen("flags")))
1143
|| (!lstrncmpiA(line,"features",strlen("features"))) )
1145
if (strstr(value,"cx8"))
1146
PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
1147
if (strstr(value,"mmx"))
1148
PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
1149
if (strstr(value,"tsc"))
1150
PF[PF_RDTSC_INSTRUCTION_AVAILABLE] = TRUE;
1151
if (strstr(value,"xmm") || strstr(value,"sse"))
1152
PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
1153
if (strstr(value,"sse2"))
1154
PF[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = TRUE;
1155
if (strstr(value,"3dnow"))
1156
PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
1161
* ad hoc fix for smp machines.
1162
* some problems on WaitForSingleObject,CreateEvent,SetEvent
1163
* CreateThread ...etc..
1166
cachedsi.dwNumberOfProcessors=1;
1168
#endif /* __linux__ */
1171
memcpy(si,&cachedsi,sizeof(*si));
1175
// avoid undefined expGetSystemInfo
1176
static WIN_BOOL WINAPI expIsProcessorFeaturePresent(DWORD v)
1178
WIN_BOOL result = 0;
1182
expGetSystemInfo(&si);
1184
if(v<64) result=PF[v];
1185
dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v, result);
1190
static long WINAPI expGetVersion()
1192
dbgprintf("GetVersion() => 0xC0000004\n");
1193
return 0xC0000004;//Windows 95
1196
static HANDLE WINAPI expHeapCreate(long flags, long init_size, long max_size)
1198
// printf("HeapCreate:");
1201
result=(HANDLE)my_mreq(0x110000, 0);
1203
result=(HANDLE)my_mreq((init_size + 0xfff) & 0x7ffff000 , 0);
1204
dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags, init_size, max_size, result);
1208
// this is another dirty hack
1209
// VP31 is releasing one allocated Heap chunk twice
1210
// we will silently ignore this second call...
1211
static void* heapfreehack = 0;
1212
static int heapfreehackshown = 0;
1213
//extern void trapbug(void);
1214
static void* WINAPI expHeapAlloc(HANDLE heap, int flags, int size)
1218
Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1219
HeapAlloc returns area larger than size argument :-/
1221
actually according to M$ Doc HeapCreate size should be rounded
1222
to page boundaries thus we should simulate this
1224
//if (size == 22276) trapbug();
1225
z=my_mreq((size + 0xfff) & 0x7ffff000, (flags & HEAP_ZERO_MEMORY));
1227
printf("HeapAlloc failure\n");
1228
dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap, flags, size, z);
1229
heapfreehack = 0; // reset
1232
static long WINAPI expHeapDestroy(void* heap)
1234
dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap);
1239
static long WINAPI expHeapFree(HANDLE heap, DWORD dwFlags, LPVOID lpMem)
1241
dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap, dwFlags, lpMem);
1242
if (heapfreehack != lpMem && lpMem != (void*)0xffffffff
1243
&& lpMem != (void*)0xbdbdbdbd)
1244
// 0xbdbdbdbd is for i263_drv.drv && libefence
1245
// it seems to be reading from relased memory
1246
// EF_PROTECT_FREE doens't show any probleme
1250
if (!heapfreehackshown++)
1251
printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem);
1253
heapfreehack = lpMem;
1256
static long WINAPI expHeapSize(int heap, int flags, void* pointer)
1258
long result=my_size(pointer);
1259
dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap, flags, pointer, result);
1262
static void* WINAPI expHeapReAlloc(HANDLE heap,int flags,void *lpMem,int size)
1264
long orgsize = my_size(lpMem);
1265
dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize,size);
1266
return my_realloc(lpMem, size);
1268
static long WINAPI expGetProcessHeap(void)
1270
dbgprintf("GetProcessHeap() => 1\n");
1273
static void* WINAPI expVirtualAlloc(void* v1, long v2, long v3, long v4)
1275
void* z = VirtualAlloc(v1, v2, v3, v4);
1277
printf("VirtualAlloc failure\n");
1278
dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1,v2,v3,v4, z);
1281
static int WINAPI expVirtualFree(void* v1, int v2, int v3)
1283
int result = VirtualFree(v1,v2,v3);
1284
dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1,v2,v3, result);
1288
/* we're building a table of critical sections. cs_win pointer uses the DLL
1289
cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1290
struct critsecs_list_t
1292
CRITICAL_SECTION *cs_win;
1293
struct CRITSECT *cs_unix;
1296
/* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1297
#undef CRITSECS_NEWTYPE
1298
//#define CRITSECS_NEWTYPE 1
1300
#ifdef CRITSECS_NEWTYPE
1301
/* increased due to ucod needs more than 32 entries */
1302
/* and 64 should be enough for everything */
1303
#define CRITSECS_LIST_MAX 64
1304
static struct critsecs_list_t critsecs_list[CRITSECS_LIST_MAX];
1306
static int critsecs_get_pos(CRITICAL_SECTION *cs_win)
1310
for (i=0; i < CRITSECS_LIST_MAX; i++)
1311
if (critsecs_list[i].cs_win == cs_win)
1316
static int critsecs_get_unused(void)
1320
for (i=0; i < CRITSECS_LIST_MAX; i++)
1321
if (critsecs_list[i].cs_win == NULL)
1326
struct CRITSECT *critsecs_get_unix(CRITICAL_SECTION *cs_win)
1330
for (i=0; i < CRITSECS_LIST_MAX; i++)
1331
if (critsecs_list[i].cs_win == cs_win && critsecs_list[i].cs_unix)
1332
return(critsecs_list[i].cs_unix);
1337
static void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c)
1339
dbgprintf("InitializeCriticalSection(0x%x)\n", c);
1340
/* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1342
printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1343
sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1346
/* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1347
#ifdef CRITSECS_NEWTYPE
1349
struct CRITSECT *cs;
1350
int i = critsecs_get_unused();
1354
printf("InitializeCriticalSection(%p) - no more space in list\n", c);
1357
dbgprintf("got unused space at %d\n", i);
1358
cs = malloc(sizeof(struct CRITSECT));
1361
printf("InitializeCriticalSection(%p) - out of memory\n", c);
1364
pthread_mutex_init(&cs->mutex, NULL);
1366
critsecs_list[i].cs_win = c;
1367
critsecs_list[i].cs_unix = cs;
1368
dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1373
struct CRITSECT* cs = mreq_private(sizeof(struct CRITSECT) + sizeof(CRITICAL_SECTION),
1374
0, AREATYPE_CRITSECT);
1375
pthread_mutex_init(&cs->mutex, NULL);
1377
cs->deadbeef = 0xdeadbeef;
1384
static void WINAPI expEnterCriticalSection(CRITICAL_SECTION* c)
1386
#ifdef CRITSECS_NEWTYPE
1387
struct CRITSECT* cs = critsecs_get_unix(c);
1389
struct CRITSECT* cs = (*(struct CRITSECT**)c);
1391
dbgprintf("EnterCriticalSection(0x%x) %p\n",c, cs);
1394
dbgprintf("entered uninitialized critisec!\n");
1395
expInitializeCriticalSection(c);
1396
#ifdef CRITSECS_NEWTYPE
1397
cs=critsecs_get_unix(c);
1399
cs = (*(struct CRITSECT**)c);
1401
dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c);
1404
if(cs->id==pthread_self())
1406
pthread_mutex_lock(&(cs->mutex));
1408
cs->id=pthread_self();
1411
static void WINAPI expLeaveCriticalSection(CRITICAL_SECTION* c)
1413
#ifdef CRITSECS_NEWTYPE
1414
struct CRITSECT* cs = critsecs_get_unix(c);
1416
struct CRITSECT* cs = (*(struct CRITSECT**)c);
1418
// struct CRITSECT* cs=(struct CRITSECT*)c;
1419
dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c, cs);
1422
dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c);
1428
pthread_mutex_unlock(&(cs->mutex));
1431
dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c);
1435
static void expfree(void* mem); /* forward declaration */
1437
static void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c)
1439
#ifdef CRITSECS_NEWTYPE
1440
struct CRITSECT* cs = critsecs_get_unix(c);
1442
struct CRITSECT* cs= (*(struct CRITSECT**)c);
1444
// struct CRITSECT* cs=(struct CRITSECT*)c;
1445
dbgprintf("DeleteCriticalSection(0x%x)\n",c);
1449
dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c);
1455
dbgprintf("Win32 Warning: Deleting unlocked Critical Section %p!!\n", c);
1456
pthread_mutex_unlock(&(cs->mutex));
1460
pthread_mutex_destroy(&(cs->mutex));
1461
// released by GarbageCollector in my_relase otherwise
1464
#ifdef CRITSECS_NEWTYPE
1466
int i = critsecs_get_pos(c);
1470
printf("DeleteCriticalSection(%p) error (critsec not found)\n", c);
1474
critsecs_list[i].cs_win = NULL;
1475
expfree(critsecs_list[i].cs_unix);
1476
critsecs_list[i].cs_unix = NULL;
1477
dbgprintf("DeleteCriticalSection -> itemno=%d\n", i);
1482
static int WINAPI expGetCurrentThreadId()
1484
dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1485
return pthread_self();
1487
static int WINAPI expGetCurrentProcess()
1489
dbgprintf("GetCurrentProcess() => %d\n", getpid());
1494
// this version is required for Quicktime codecs (.qtx/.qts) to work.
1495
// (they assume some pointers at FS: segment)
1497
extern void* fs_seg;
1499
//static int tls_count;
1500
static int tls_use_map[64];
1501
static int WINAPI expTlsAlloc()
1505
if(tls_use_map[i]==0)
1508
dbgprintf("TlsAlloc() => %d\n",i);
1511
dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1515
//static int WINAPI expTlsSetValue(DWORD index, void* value)
1516
static int WINAPI expTlsSetValue(int index, void* value)
1518
dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index,value);
1519
// if((index<0) || (index>64))
1522
*(void**)((char*)fs_seg+0x88+4*index) = value;
1526
static void* WINAPI expTlsGetValue(DWORD index)
1528
dbgprintf("TlsGetValue(%d)\n",index);
1529
// if((index<0) || (index>64))
1530
if((index>=64)) return NULL;
1531
return *(void**)((char*)fs_seg+0x88+4*index);
1534
static int WINAPI expTlsFree(int idx)
1536
int index = (int) idx;
1537
dbgprintf("TlsFree(%d)\n",index);
1538
if((index<0) || (index>64))
1540
tls_use_map[index]=0;
1552
static void* WINAPI expTlsAlloc()
1556
g_tls=my_mreq(sizeof(tls_t), 0);
1557
g_tls->next=g_tls->prev=NULL;
1561
g_tls->next=my_mreq(sizeof(tls_t), 0);
1562
g_tls->next->prev=g_tls;
1563
g_tls->next->next=NULL;
1566
dbgprintf("TlsAlloc() => 0x%x\n", g_tls);
1568
g_tls->value=0; /* XXX For Divx.dll */
1572
static int WINAPI expTlsSetValue(void* idx, void* value)
1574
tls_t* index = (tls_t*) idx;
1583
dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index, value, result );
1586
static void* WINAPI expTlsGetValue(void* idx)
1588
tls_t* index = (tls_t*) idx;
1593
result=index->value;
1594
dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index, result);
1597
static int WINAPI expTlsFree(void* idx)
1599
tls_t* index = (tls_t*) idx;
1606
index->next->prev=index->prev;
1608
index->prev->next=index->next;
1610
g_tls = index->prev;
1611
my_release((void*)index);
1614
dbgprintf("TlsFree(index 0x%x) => %d\n", index, result);
1619
static void* WINAPI expLocalAlloc(int flags, int size)
1621
void* z = my_mreq(size, (flags & GMEM_ZEROINIT));
1623
printf("LocalAlloc() failed\n");
1624
dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z);
1628
static void* WINAPI expLocalReAlloc(int handle,int size, int flags)
1634
if (flags & LMEM_MODIFY) {
1635
dbgprintf("LocalReAlloc MODIFY\n");
1636
return (void *)handle;
1638
oldsize = my_size((void *)handle);
1639
newpointer = my_realloc((void *)handle,size);
1640
dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle,size,oldsize, flags,newpointer);
1645
static void* WINAPI expLocalLock(void* z)
1647
dbgprintf("LocalLock(0x%x) => 0x%x\n", z, z);
1651
static void* WINAPI expGlobalAlloc(int flags, int size)
1654
dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size, flags);
1656
z=my_mreq(size, (flags & GMEM_ZEROINIT));
1657
//z=calloc(size, 1);
1660
printf("GlobalAlloc() failed\n");
1661
dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z);
1664
static void* WINAPI expGlobalLock(void* z)
1666
dbgprintf("GlobalLock(0x%x) => 0x%x\n", z, z);
1669
// pvmjpg20 - but doesn't work anyway
1670
static int WINAPI expGlobalSize(void* amem)
1674
alloc_header* header = last_alloc;
1675
alloc_header* mem = (alloc_header*) amem - 1;
1678
pthread_mutex_lock(&memmut);
1681
if (header->deadbeef != 0xdeadbeef)
1683
dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt);
1689
size = header->size;
1693
header = header->prev;
1695
pthread_mutex_unlock(&memmut);
1698
dbgprintf("GlobalSize(0x%x)\n", amem);
1702
static int WINAPI expLoadIconA( long hinstance, char *name )
1704
dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance,name);
1708
static int WINAPI expLoadStringA(long instance, long id, void* buf, long size)
1710
int result=LoadStringA(instance, id, buf, size);
1712
dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1713
instance, id, buf, size, result, buf);
1715
// dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1716
// instance, id, buf, size, result);
1720
static long WINAPI expMultiByteToWideChar(long v1, long v2, char* s1, long siz1, short* s2, int siz2)
1729
if(siz1>siz2/2)siz1=siz2/2;
1730
for(i=1; i<=siz1; i++)
1740
dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1741
"size %d, dest buffer 0x%x, dest size %d) => %d\n",
1742
v1, v2, s1, s1, siz1, s2, siz2, result);
1744
dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1745
"size %d, dest buffer 0x%x, dest size %d) =>\n",
1746
v1, v2, siz1, s2, siz2, result);
1749
static void wch_print(const short* str)
1751
dbgprintf(" src: ");
1752
while(*str)dbgprintf("%c", *str++);
1755
static long WINAPI expWideCharToMultiByte(long v1, long v2, short* s1, long siz1,
1756
char* s2, int siz2, char* c3, int* siz3)
1759
dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1760
"dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1, v2, s1, siz1, s2, siz2, c3, siz3);
1761
result=WideCharToMultiByte(v1, v2, s1, siz1, s2, siz2, c3, siz3);
1762
dbgprintf("=> %d\n", result);
1763
//if(s1)wch_print(s1);
1764
if(s2)dbgprintf(" dest: %s\n", s2);
1767
static long WINAPI expGetVersionExA(OSVERSIONINFOA* c)
1769
dbgprintf("GetVersionExA(0x%x) => 1\n");
1770
c->dwOSVersionInfoSize=sizeof(*c);
1771
c->dwMajorVersion=4;
1772
c->dwMinorVersion=0;
1773
c->dwBuildNumber=0x4000457;
1775
// leave it here for testing win9x-only codecs
1776
c->dwPlatformId=VER_PLATFORM_WIN32_WINDOWS;
1777
strcpy(c->szCSDVersion, " B");
1779
c->dwPlatformId=VER_PLATFORM_WIN32_NT; // let's not make DLL assume that it can read CR* registers
1780
strcpy(c->szCSDVersion, "Service Pack 3");
1782
dbgprintf(" Major version: 4\n Minor version: 0\n Build number: 0x4000457\n"
1783
" Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 3'\n");
1786
static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count,
1787
long max_count, char* name)
1789
pthread_mutex_t *pm;
1793
printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1797
printf("%p => ", pp);
1804
mutex_list* pp=mlist;
1808
if((strcmp(pp->name, name)==0) && (pp->type==1))
1810
dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1811
v1, init_count, max_count, name, name, mlist);
1812
return (HANDLE)mlist;
1814
}while((pp=pp->prev) != NULL);
1816
pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
1817
pthread_mutex_init(pm, NULL);
1818
pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
1819
pthread_cond_init(pc, NULL);
1822
mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1823
mlist->next=mlist->prev=NULL;
1827
mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1828
mlist->next->prev=mlist;
1829
mlist->next->next=NULL;
1831
// printf("new semaphore %p\n", mlist);
1833
mlist->type=1; /* Type Semaphore */
1838
mlist->semaphore=init_count;
1840
strncpy(mlist->name, name, 64);
1844
dbgprintf("ERROR::: CreateSemaphoreA failure\n");
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);
1849
dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1850
v1, init_count, max_count, mlist);
1851
return (HANDLE)mlist;
1854
static long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count)
1856
// The state of a semaphore object is signaled when its count
1857
// is greater than zero and nonsignaled when its count is equal to zero
1858
// Each time a waiting thread is released because of the semaphore's signaled
1859
// state, the count of the semaphore is decreased by one.
1860
mutex_list *ml = (mutex_list *)hsem;
1862
pthread_mutex_lock(ml->pm);
1863
if (prev_count != 0) *prev_count = ml->semaphore;
1864
if (ml->semaphore == 0) pthread_cond_signal(ml->pc);
1865
ml->semaphore += increment;
1866
pthread_mutex_unlock(ml->pm);
1867
dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1868
hsem, increment, prev_count);
1873
static long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
1875
long result=RegOpenKeyExA(key, subkey, reserved, access, newkey);
1876
dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
1877
key, subkey, reserved, access, newkey, result);
1878
if(newkey)dbgprintf(" New key: 0x%x\n", *newkey);
1881
static long WINAPI expRegCloseKey(long key)
1883
long result=RegCloseKey(key);
1884
dbgprintf("RegCloseKey(0x%x) => %d\n", key, result);
1887
static long WINAPI expRegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count)
1889
long result=RegQueryValueExA(key, value, reserved, type, data, count);
1890
dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
1891
" => 0x%x\n", key, value, reserved, data, count, result);
1892
if(data && count)dbgprintf(" read %d bytes: '%s'\n", *count, data);
1896
//from wine source dlls/advapi32/registry.c
1897
static long WINAPI expRegCreateKeyA(long hkey, const char* name, int *retkey)
1899
dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey,name,retkey);
1900
return RegCreateKeyExA( hkey, name, 0, NULL,REG_OPTION_NON_VOLATILE,
1901
KEY_ALL_ACCESS , NULL, retkey, NULL );
1904
static long WINAPI expRegCreateKeyExA(long key, const char* name, long reserved,
1905
void* classs, long options, long security,
1906
void* sec_attr, int* newkey, int* status)
1908
long result=RegCreateKeyExA(key, name, reserved, classs, options, security, sec_attr, newkey, status);
1909
dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
1910
" 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
1911
key, name, name, reserved, classs, options, security, sec_attr, newkey, status, result);
1912
if(!result && newkey) dbgprintf(" New key: 0x%x\n", *newkey);
1913
if(!result && status) dbgprintf(" New key status: 0x%x\n", *status);
1916
static long WINAPI expRegSetValueExA(long key, const char* name, long v1, long v2, void* data, long size)
1918
long result=RegSetValueExA(key, name, v1, v2, data, size);
1919
dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
1920
key, name, v1, v2, data, *(int*)data, data, size, result);
1924
static long WINAPI expRegOpenKeyA (long hKey, LPCSTR lpSubKey, int* phkResult)
1926
long result=RegOpenKeyExA(hKey, lpSubKey, 0, 0, phkResult);
1927
dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
1928
hKey, lpSubKey, phkResult, result);
1929
if(!result && phkResult) dbgprintf(" New key: 0x%x\n", *phkResult);
1933
static DWORD WINAPI expRegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count,
1934
LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count)
1936
return RegEnumValueA(hkey, index, value, val_count,
1937
reserved, type, data, count);
1940
static DWORD WINAPI expRegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName,
1941
LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass,
1942
LPFILETIME lpftLastWriteTime)
1944
return RegEnumKeyExA(hKey, dwIndex, lpName, lpcbName, lpReserved, lpClass,
1945
lpcbClass, lpftLastWriteTime);
1948
static long WINAPI expQueryPerformanceCounter(long long* z)
1951
dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z, *z);
1956
* dummy function RegQueryInfoKeyA(), required by vss codecs
1958
static DWORD WINAPI expRegQueryInfoKeyA( HKEY hkey, LPSTR class, LPDWORD class_len, LPDWORD reserved,
1959
LPDWORD subkeys, LPDWORD max_subkey, LPDWORD max_class,
1960
LPDWORD values, LPDWORD max_value, LPDWORD max_data,
1961
LPDWORD security, FILETIME *modif )
1963
return ERROR_SUCCESS;
1967
* return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
1969
static double linux_cpuinfo_freq()
1976
f = fopen ("/proc/cpuinfo", "r");
1978
while (fgets(line,sizeof(line),f)!=NULL) {
1979
/* NOTE: the ':' is the only character we can rely on */
1980
if (!(value = strchr(line,':')))
1982
/* terminate the valuename */
1984
/* skip any leading spaces */
1985
while (*value==' ') value++;
1986
if ((s=strchr(value,'\n')))
1989
if (!strncasecmp(line, "cpu MHz",strlen("cpu MHz"))
1990
&& sscanf(value, "%lf", &freq) == 1) {
2001
static double solaris_kstat_freq()
2003
#if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
2005
* try to extract the CPU speed from the solaris kernel's kstat data
2009
kstat_named_t *kdata;
2015
ksp = kstat_lookup(kc, "cpu_info", 0, "cpu_info0");
2017
/* kstat found and name/value pairs? */
2018
if (ksp != NULL && ksp->ks_type == KSTAT_TYPE_NAMED)
2020
/* read the kstat data from the kernel */
2021
if (kstat_read(kc, ksp, NULL) != -1)
2024
* lookup desired "clock_MHz" entry, check the expected
2027
kdata = (kstat_named_t *)kstat_data_lookup(ksp, "clock_MHz");
2028
if (kdata != NULL && kdata->data_type == KSTAT_DATA_INT32)
2029
mhz = kdata->value.i32;
2037
#endif /* HAVE_LIBKSTAT */
2038
return -1; // kstat stuff is not available, CPU freq is unknown
2042
* Measure CPU freq using the pentium's time stamp counter register (TSC)
2044
static double tsc_freq()
2046
static double ofreq=0.0;
2050
if (ofreq != 0.0) return ofreq;
2051
while(i==time(NULL));
2054
while(i==time(NULL));
2056
ofreq = (double)(y-x)/1000.;
2060
static double CPU_Freq()
2064
if ((freq = linux_cpuinfo_freq()) > 0)
2067
if ((freq = solaris_kstat_freq()) > 0)
2073
static long WINAPI expQueryPerformanceFrequency(long long* z)
2075
*z=(long long)CPU_Freq();
2076
dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z, *z);
2079
static long WINAPI exptimeGetTime()
2083
gettimeofday(&t, 0);
2084
result=1000*t.tv_sec+t.tv_usec/1000;
2085
dbgprintf("timeGetTime() => %d\n", result);
2088
static void* WINAPI expLocalHandle(void* v)
2090
dbgprintf("LocalHandle(0x%x) => 0x%x\n", v, v);
2094
static void* WINAPI expGlobalHandle(void* v)
2096
dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v, v);
2099
static int WINAPI expGlobalUnlock(void* v)
2101
dbgprintf("GlobalUnlock(0x%x) => 1\n", v);
2104
static void* WINAPI expGlobalFree(void* v)
2106
dbgprintf("GlobalFree(0x%x) => 0\n", v);
2112
static void* WINAPI expGlobalReAlloc(void* v, int size, int flags)
2114
void* result=my_realloc(v, size);
2115
//void* result=realloc(v, size);
2116
dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v,size,flags,result);
2120
static int WINAPI expLocalUnlock(void* v)
2122
dbgprintf("LocalUnlock(0x%x) => 1\n", v);
2126
static void* WINAPI expLocalFree(void* v)
2128
dbgprintf("LocalFree(0x%x) => 0\n", v);
2132
static HRSRC WINAPI expFindResourceA(HMODULE module, char* name, char* type)
2136
result=FindResourceA(module, name, type);
2137
dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2138
module, name, HIWORD(name) ? name : "UNICODE", type, HIWORD(type) ? type : "UNICODE", result);
2142
extern HRSRC WINAPI LoadResource(HMODULE, HRSRC);
2143
static HGLOBAL WINAPI expLoadResource(HMODULE module, HRSRC res)
2145
HGLOBAL result=LoadResource(module, res);
2146
dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module, res, result);
2149
static void* WINAPI expLockResource(long res)
2151
void* result=LockResource(res);
2152
dbgprintf("LockResource(0x%x) => 0x%x\n", res, result);
2155
static int WINAPI expFreeResource(long res)
2157
int result=FreeResource(res);
2158
dbgprintf("FreeResource(0x%x) => %d\n", res, result);
2163
static int WINAPI expCloseHandle(long v1)
2165
dbgprintf("CloseHandle(0x%x) => 1\n", v1);
2166
/* do not close stdin,stdout and stderr */
2173
static const char* WINAPI expGetCommandLineA()
2175
dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2176
return "c:\\aviplay.exe";
2178
static short envs[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2179
static LPWSTR WINAPI expGetEnvironmentStringsW()
2181
dbgprintf("GetEnvironmentStringsW() => 0\n", envs);
2184
static void * WINAPI expRtlZeroMemory(void *p, size_t len)
2186
void* result=memset(p,0,len);
2187
dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p,len,result);
2190
static void * WINAPI expRtlMoveMemory(void *dst, void *src, size_t len)
2192
void* result=memmove(dst,src,len);
2193
dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst,src,len,result);
2197
static void * WINAPI expRtlFillMemory(void *p, int ch, size_t len)
2199
void* result=memset(p,ch,len);
2200
dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p,ch,len,result);
2203
static int WINAPI expFreeEnvironmentStringsW(short* strings)
2205
dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings);
2208
static int WINAPI expFreeEnvironmentStringsA(char* strings)
2210
dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings);
2214
static const char ch_envs[]=
2215
"__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2216
"PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2217
static LPCSTR WINAPI expGetEnvironmentStrings()
2219
dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs);
2220
return (LPCSTR)ch_envs;
2221
// dbgprintf("GetEnvironmentStrings() => 0\n");
2225
static int WINAPI expGetStartupInfoA(STARTUPINFOA *s)
2228
dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2229
memset(s, 0, sizeof(*s));
2231
// s->lpReserved="Reserved";
2232
// s->lpDesktop="Desktop";
2233
// s->lpTitle="Title";
2235
// s->dwXSize=s->dwYSize=200;
2236
s->dwFlags=s->wShowWindow=1;
2237
// s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2238
dbgprintf(" cb=%d\n", s->cb);
2239
dbgprintf(" lpReserved='%s'\n", s->lpReserved);
2240
dbgprintf(" lpDesktop='%s'\n", s->lpDesktop);
2241
dbgprintf(" lpTitle='%s'\n", s->lpTitle);
2242
dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2243
s->dwX, s->dwY, s->dwXSize, s->dwYSize);
2244
dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2245
s->dwXCountChars, s->dwYCountChars, s->dwFillAttribute);
2246
dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2247
s->dwFlags, s->wShowWindow, s->cbReserved2);
2248
dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2249
s->lpReserved2, s->hStdInput, s->hStdOutput, s->hStdError);
2253
static int WINAPI expGetStdHandle(int z)
2255
dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z+0x1234);
2260
#define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2261
#define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2264
static int WINAPI expGetFileType(int handle)
2266
dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle);
2270
static int WINAPI expGetFileAttributesA(char *filename)
2272
dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename);
2273
if (strstr(filename, "QuickTime.qts"))
2274
return FILE_ATTRIBUTE_SYSTEM;
2275
return FILE_ATTRIBUTE_NORMAL;
2278
static int WINAPI expSetHandleCount(int count)
2280
dbgprintf("SetHandleCount(0x%x) => 1\n", count);
2283
static int WINAPI expGetACP(void)
2285
dbgprintf("GetACP() => 0\n");
2288
extern WINE_MODREF *MODULE32_LookupHMODULE(HMODULE m);
2289
static int WINAPI expGetModuleFileNameA(int module, char* s, int len)
2293
//printf("File name of module %X (%s) requested\n", module, s);
2295
if (module == 0 && len >= 12)
2297
/* return caller program name */
2298
strcpy(s, "aviplay.dll");
2309
strcpy(s, "c:\\windows\\system\\");
2310
mr=MODULE32_LookupHMODULE(module);
2312
strcat(s, "aviplay.dll");
2314
if(strrchr(mr->filename, '/')==NULL)
2315
strcat(s, mr->filename);
2317
strcat(s, strrchr(mr->filename, '/')+1);
2320
dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2321
module, s, len, result);
2323
dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2324
module, s, len, result, s);
2328
static int WINAPI expSetUnhandledExceptionFilter(void* filter)
2330
dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter);
2331
return 1;//unsupported and probably won't ever be supported
2334
static int WINAPI expLoadLibraryA(char* name)
2341
// we skip to the last backslash
2342
// this is effectively eliminating weird characters in
2343
// the text output windows
2345
lastbc = strrchr(name, '\\');
2352
name[i] = *lastbc++;
2357
if(strncmp(name, "c:\\windows\\", 11)==0) name += 11;
2358
if(strncmp(name, ".\\", 2)==0) name += 2;
2360
dbgprintf("Entering LoadLibraryA(%s)\n", name);
2362
// PIMJ and VIVO audio are loading kernel32.dll
2363
if (strcasecmp(name, "kernel32.dll") == 0 || strcasecmp(name, "kernel32") == 0)
2364
return MODULE_HANDLE_kernel32;
2365
// return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2366
/* exported -> do not return failed! */
2368
if (strcasecmp(name, "user32.dll") == 0 || strcasecmp(name, "user32") == 0)
2369
// return MODULE_HANDLE_kernel32;
2370
return MODULE_HANDLE_user32;
2373
if (strcasecmp(name, "wininet.dll") == 0 || strcasecmp(name, "wininet") == 0)
2374
return MODULE_HANDLE_wininet;
2375
if (strcasecmp(name, "ddraw.dll") == 0 || strcasecmp(name, "ddraw") == 0)
2376
return MODULE_HANDLE_ddraw;
2377
if (strcasecmp(name, "advapi32.dll") == 0 || strcasecmp(name, "advapi32") == 0)
2378
return MODULE_HANDLE_advapi32;
2381
if (strcasecmp(name, "comdlg32.dll") == 0 || strcasecmp(name, "comdlg32") == 0)
2382
return MODULE_HANDLE_comdlg32;
2383
if (strcasecmp(name, "msvcrt.dll") == 0 || strcasecmp(name, "msvcrt") == 0)
2384
return MODULE_HANDLE_msvcrt;
2385
if (strcasecmp(name, "ole32.dll") == 0 || strcasecmp(name, "ole32") == 0)
2386
return MODULE_HANDLE_ole32;
2387
if (strcasecmp(name, "winmm.dll") == 0 || strcasecmp(name, "winmm") == 0)
2388
return MODULE_HANDLE_winmm;
2390
result=LoadLibraryA(name);
2391
dbgprintf("Returned LoadLibraryA(0x%x='%s'), def_path=%s => 0x%x\n", name, name, def_path, result);
2396
static int WINAPI expFreeLibrary(int module)
2399
int result=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2401
int result=FreeLibrary(module);
2403
dbgprintf("FreeLibrary(0x%x) => %d\n", module, result);
2407
static void* WINAPI expGetProcAddress(HMODULE mod, char* name)
2411
case MODULE_HANDLE_kernel32:
2412
result=LookupExternalByName("kernel32.dll", name); break;
2413
case MODULE_HANDLE_user32:
2414
result=LookupExternalByName("user32.dll", name); break;
2416
case MODULE_HANDLE_wininet:
2417
result=LookupExternalByName("wininet.dll", name); break;
2418
case MODULE_HANDLE_ddraw:
2419
result=LookupExternalByName("ddraw.dll", name); break;
2420
case MODULE_HANDLE_advapi32:
2421
result=LookupExternalByName("advapi32.dll", name); break;
2423
case MODULE_HANDLE_comdlg32:
2424
result=LookupExternalByName("comdlg32.dll", name); break;
2425
case MODULE_HANDLE_msvcrt:
2426
result=LookupExternalByName("msvcrt.dll", name); break;
2427
case MODULE_HANDLE_ole32:
2428
result=LookupExternalByName("ole32.dll", name); break;
2429
case MODULE_HANDLE_winmm:
2430
result=LookupExternalByName("winmm.dll", name); break;
2432
result=GetProcAddress(mod, name);
2434
dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod, name, result);
2438
static long WINAPI expCreateFileMappingA(int hFile, void* lpAttr,
2439
long flProtect, long dwMaxHigh,
2440
long dwMaxLow, const char* name)
2442
long result=CreateFileMappingA(hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name);
2444
dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2445
"flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2446
hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, result);
2448
dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2449
"flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2450
hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name, name, result);
2454
static long WINAPI expOpenFileMappingA(long hFile, long hz, const char* name)
2456
long result=OpenFileMappingA(hFile, hz, name);
2458
dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2461
dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2462
hFile, hz, name, name, result);
2466
static void* WINAPI expMapViewOfFile(HANDLE file, DWORD mode, DWORD offHigh,
2467
DWORD offLow, DWORD size)
2469
dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2470
file,mode,offHigh,offLow,size,(char*)file+offLow);
2471
return (char*)file+offLow;
2474
static void* WINAPI expUnmapViewOfFile(void* view)
2476
dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view);
2480
static void* WINAPI expSleep(int time)
2483
/* solaris doesn't have thread safe usleep */
2484
struct timespec tsp;
2485
tsp.tv_sec = time / 1000000;
2486
tsp.tv_nsec = (time % 1000000) * 1000;
2487
nanosleep(&tsp, NULL);
2491
dbgprintf("Sleep(%d) => 0\n", time);
2495
// why does IV32 codec want to call this? I don't know ...
2496
static int WINAPI expCreateCompatibleDC(int hdc)
2499
//dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2500
dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc, dc);
2504
static int WINAPI expGetDeviceCaps(int hdc, int unk)
2506
dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc, unk);
2508
#define BITSPIXEL 12
2510
if (unk == BITSPIXEL)
2518
static WIN_BOOL WINAPI expDeleteDC(int hdc)
2520
dbgprintf("DeleteDC(0x%x) => 0\n", hdc);
2526
static WIN_BOOL WINAPI expDeleteObject(int hdc)
2528
dbgprintf("DeleteObject(0x%x) => 1\n", hdc);
2529
/* FIXME - implement code here */
2533
/* btvvc32.drv wants this one */
2534
static void* WINAPI expGetWindowDC(int hdc)
2536
dbgprintf("GetWindowDC(%d) => 0x0\n", hdc);
2541
static int WINAPI expGetWindowRect(HWND win, RECT *r)
2543
dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win, r);
2544
/* (win == 0) => desktop */
2545
r->right = PSEUDO_SCREEN_WIDTH;
2547
r->bottom = PSEUDO_SCREEN_HEIGHT;
2552
static int WINAPI expMonitorFromWindow(HWND win, int flags)
2554
dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win, flags);
2558
static int WINAPI expMonitorFromRect(RECT *r, int flags)
2560
dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r, flags);
2564
static int WINAPI expMonitorFromPoint(void *p, int flags)
2566
dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p, flags);
2570
static int WINAPI expEnumDisplayMonitors(void *dc, RECT *r,
2571
int WINAPI (*callback_proc)(), void *callback_param)
2573
dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2574
dc, r, callback_proc, callback_param);
2575
return callback_proc(0, dc, r, callback_param);
2579
typedef struct tagMONITORINFO {
2584
} MONITORINFO, *LPMONITORINFO;
2587
#define CCHDEVICENAME 8
2588
typedef struct tagMONITORINFOEX {
2593
TCHAR szDevice[CCHDEVICENAME];
2594
} MONITORINFOEX, *LPMONITORINFOEX;
2596
static int WINAPI expGetMonitorInfoA(void *mon, LPMONITORINFO lpmi)
2598
dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon, lpmi);
2600
lpmi->rcMonitor.right = lpmi->rcWork.right = PSEUDO_SCREEN_WIDTH;
2601
lpmi->rcMonitor.left = lpmi->rcWork.left = 0;
2602
lpmi->rcMonitor.bottom = lpmi->rcWork.bottom = PSEUDO_SCREEN_HEIGHT;
2603
lpmi->rcMonitor.top = lpmi->rcWork.top = 0;
2605
lpmi->dwFlags = 1; /* primary monitor */
2607
if (lpmi->cbSize == sizeof(MONITORINFOEX))
2609
LPMONITORINFOEX lpmiex = (LPMONITORINFOEX)lpmi;
2610
dbgprintf("MONITORINFOEX!\n");
2611
strncpy(lpmiex->szDevice, "Monitor1", CCHDEVICENAME);
2617
static int WINAPI expEnumDisplayDevicesA(const char *device, int devnum,
2618
void *dispdev, int flags)
2620
dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2621
device, device, devnum, dispdev, flags);
2625
static int WINAPI expIsWindowVisible(HWND win)
2627
dbgprintf("IsWindowVisible(0x%x) => 1\n", win);
2631
static HWND WINAPI expGetActiveWindow(void)
2633
dbgprintf("GetActiveWindow() => 0\n");
2637
static int WINAPI expGetClassNameA(HWND win, LPTSTR classname, int maxcount)
2639
strncat(classname, "QuickTime", maxcount);
2640
dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2641
win, classname, maxcount, strlen(classname));
2642
return strlen(classname);
2645
#define LPWNDCLASS void *
2646
static int WINAPI expGetClassInfoA(HINSTANCE inst, LPCSTR classname, LPWNDCLASS wndclass)
2648
dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst,
2649
classname, classname, wndclass);
2653
static int WINAPI expGetWindowLongA(HWND win, int index)
2655
dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win, index);
2659
static int WINAPI expGetObjectA(HGDIOBJ hobj, int objsize, LPVOID obj)
2661
dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj, objsize, obj, objsize);
2665
static int WINAPI expCreateRectRgn(int x, int y, int width, int height)
2667
dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x, y, width, height);
2671
static int WINAPI expEnumWindows(int (*callback_func)(), void *callback_param)
2674
dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func, callback_param);
2675
i = callback_func(0, callback_param);
2676
i2 = callback_func(1, callback_param);
2680
static int WINAPI expGetWindowThreadProcessId(HWND win, int *pid_data)
2682
int tid = pthread_self();
2683
dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2684
win, pid_data, tid);
2686
*(int*)pid_data = tid;
2690
//HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2691
// INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2693
static HWND WINAPI expCreateWindowExA(int exstyle, const char *classname,
2694
const char *winname, int style, int x, int y, int w, int h,
2695
HWND parent, HMENU menu, HINSTANCE inst, LPVOID param)
2697
printf("CreateWindowEx() called\n");
2698
dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2699
exstyle, classname, classname, winname, winname, style, x, y, w, h,
2700
parent, menu, inst, param);
2701
printf("CreateWindowEx() called okey\n");
2705
static int WINAPI expwaveOutGetNumDevs(void)
2707
dbgprintf("waveOutGetNumDevs() => 0\n");
2713
* Returns the number of milliseconds, modulo 2^32, since the start
2714
* of the wineserver.
2716
static int WINAPI expGetTickCount(void)
2718
static int tcstart = 0;
2721
gettimeofday( &t, NULL );
2722
tc = ((t.tv_sec * 1000) + (t.tv_usec / 1000)) - tcstart;
2728
dbgprintf("GetTickCount() => %d\n", tc);
2732
static int WINAPI expCreateFontA(void)
2734
dbgprintf("CreateFontA() => 0x0\n");
2738
/* tried to get pvmjpg work in a different way - no success */
2739
static int WINAPI expDrawTextA(int hDC, char* lpString, int nCount,
2740
LPRECT lpRect, unsigned int uFormat)
2742
dbgprintf("expDrawTextA(%p,...) => 8\n", hDC);
2746
static int WINAPI expGetPrivateProfileIntA(const char* appname,
2747
const char* keyname,
2749
const char* filename)
2757
if(!(appname && keyname && filename) )
2759
dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, default_value );
2760
return default_value;
2762
fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2763
strcpy(fullname, "Software\\IniFileMapping\\");
2764
strcat(fullname, appname);
2765
strcat(fullname, "\\");
2766
strcat(fullname, keyname);
2767
strcat(fullname, "\\");
2768
strcat(fullname, filename);
2769
result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)buffer, &size);
2770
if((size>=0)&&(size<256))
2772
// printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2775
result=default_value;
2777
result=atoi(buffer);
2778
dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, result);
2781
static int WINAPI expGetProfileIntA(const char* appname,
2782
const char* keyname,
2785
dbgprintf("GetProfileIntA -> ");
2786
return expGetPrivateProfileIntA(appname, keyname, default_value, "default");
2789
static int WINAPI expGetPrivateProfileStringA(const char* appname,
2790
const char* keyname,
2791
const char* def_val,
2792
char* dest, unsigned int len,
2793
const char* filename)
2798
dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname, keyname, def_val, dest, len, filename );
2799
if(!(appname && keyname && filename) ) return 0;
2800
fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2801
strcpy(fullname, "Software\\IniFileMapping\\");
2802
strcat(fullname, appname);
2803
strcat(fullname, "\\");
2804
strcat(fullname, keyname);
2805
strcat(fullname, "\\");
2806
strcat(fullname, filename);
2808
result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)dest, &size);
2812
strncpy(dest, def_val, size);
2813
if (strlen(def_val)< size) size = strlen(def_val);
2815
dbgprintf(" => %d ( '%s' )\n", size, dest);
2818
static int WINAPI expWritePrivateProfileStringA(const char* appname,
2819
const char* keyname,
2821
const char* filename)
2825
dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname, keyname, string, filename );
2826
if(!(appname && keyname && filename) )
2828
dbgprintf(" => -1\n");
2831
fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2832
strcpy(fullname, "Software\\IniFileMapping\\");
2833
strcat(fullname, appname);
2834
strcat(fullname, "\\");
2835
strcat(fullname, keyname);
2836
strcat(fullname, "\\");
2837
strcat(fullname, filename);
2838
RegSetValueExA(HKEY_LOCAL_MACHINE, fullname, 0, REG_SZ, (int*)string, strlen(string));
2839
// printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
2840
// printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
2842
dbgprintf(" => 0\n");
2846
unsigned int _GetPrivateProfileIntA(const char* appname, const char* keyname, INT default_value, const char* filename)
2848
return expGetPrivateProfileIntA(appname, keyname, default_value, filename);
2850
int _GetPrivateProfileStringA(const char* appname, const char* keyname,
2851
const char* def_val, char* dest, unsigned int len, const char* filename)
2853
return expGetPrivateProfileStringA(appname, keyname, def_val, dest, len, filename);
2855
int _WritePrivateProfileStringA(const char* appname, const char* keyname,
2856
const char* string, const char* filename)
2858
return expWritePrivateProfileStringA(appname, keyname, string, filename);
2863
static int WINAPI expDefDriverProc(int _private, int id, int msg, int arg1, int arg2)
2865
dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", _private, id, msg, arg1, arg2);
2869
static int WINAPI expSizeofResource(int v1, int v2)
2871
int result=SizeofResource(v1, v2);
2872
dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1, v2, result);
2876
static int WINAPI expGetLastError()
2878
int result=GetLastError();
2879
dbgprintf("GetLastError() => 0x%x\n", result);
2883
static void WINAPI expSetLastError(int error)
2885
dbgprintf("SetLastError(0x%x)\n", error);
2886
SetLastError(error);
2889
static int WINAPI expStringFromGUID2(GUID* guid, char* str, int cbMax)
2891
int result=snprintf(str, cbMax, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
2892
guid->f1, guid->f2, guid->f3,
2893
(unsigned char)guid->f4[0], (unsigned char)guid->f4[1],
2894
(unsigned char)guid->f4[2], (unsigned char)guid->f4[3],
2895
(unsigned char)guid->f4[4], (unsigned char)guid->f4[5],
2896
(unsigned char)guid->f4[6], (unsigned char)guid->f4[7]);
2897
dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid, str, str, cbMax, result);
2902
static int WINAPI expGetFileVersionInfoSizeA(const char* name, int* lpHandle)
2904
dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name, name, lpHandle);
2908
static int WINAPI expIsBadStringPtrW(const short* string, int nchars)
2911
if(string==0)result=1; else result=0;
2912
dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string, nchars, result);
2913
if(string)wch_print(string);
2916
static int WINAPI expIsBadStringPtrA(const char* string, int nchars)
2918
return expIsBadStringPtrW((const short*)string, nchars);
2920
static long WINAPI expInterlockedExchangeAdd( long* dest, long incr )
2923
__asm__ __volatile__
2925
"lock; xaddl %0,(%1)"
2927
: "r" (dest), "0" (incr)
2933
static long WINAPI expInterlockedCompareExchange( unsigned long* dest, unsigned long exchange, unsigned long comperand)
2935
unsigned long retval = *dest;
2936
if(*dest == comperand)
2941
static long WINAPI expInterlockedIncrement( long* dest )
2943
long result=expInterlockedExchangeAdd( dest, 1 ) + 1;
2944
dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest, *dest, result);
2947
static long WINAPI expInterlockedDecrement( long* dest )
2949
long result=expInterlockedExchangeAdd( dest, -1 ) - 1;
2950
dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest, *dest, result);
2954
static void WINAPI expOutputDebugStringA( const char* string )
2956
dbgprintf("OutputDebugStringA(0x%x='%s')\n", string);
2957
fprintf(stderr, "DEBUG: %s\n", string);
2960
static int WINAPI expGetDC(int hwnd)
2962
dbgprintf("GetDC(0x%x) => 1\n", hwnd);
2966
static int WINAPI expReleaseDC(int hwnd, int hdc)
2968
dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd, hdc);
2972
static int WINAPI expGetDesktopWindow()
2974
dbgprintf("GetDesktopWindow() => 0\n");
2978
static int cursor[100];
2980
static int WINAPI expLoadCursorA(int handle,LPCSTR name)
2982
dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle, name, (int)&cursor[0]);
2983
return (int)&cursor[0];
2985
static int WINAPI expSetCursor(void *cursor)
2987
dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor, cursor);
2990
static int WINAPI expGetCursorPos(void *cursor)
2992
dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor, cursor);
2996
static int show_cursor = 0;
2997
static int WINAPI expShowCursor(int show)
2999
dbgprintf("ShowCursor(%d) => %d\n", show, show);
3007
static int WINAPI expRegisterWindowMessageA(char *message)
3009
dbgprintf("RegisterWindowMessageA(%s)\n", message);
3012
static int WINAPI expGetProcessVersion(int pid)
3014
dbgprintf("GetProcessVersion(%d)\n", pid);
3017
static int WINAPI expGetCurrentThread(void)
3020
dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
3023
static int WINAPI expGetOEMCP(void)
3025
dbgprintf("GetOEMCP()\n");
3028
static int WINAPI expGetCPInfo(int cp,void *info)
3030
dbgprintf("GetCPInfo()\n");
3034
#define SM_CXSCREEN 0
3035
#define SM_CYSCREEN 1
3036
#define SM_XVIRTUALSCREEN 76
3037
#define SM_YVIRTUALSCREEN 77
3038
#define SM_CXVIRTUALSCREEN 78
3039
#define SM_CYVIRTUALSCREEN 79
3040
#define SM_CMONITORS 80
3042
static int WINAPI expGetSystemMetrics(int index)
3044
dbgprintf("GetSystemMetrics(%d)\n", index);
3048
case SM_XVIRTUALSCREEN:
3049
case SM_YVIRTUALSCREEN:
3052
case SM_CXVIRTUALSCREEN:
3053
return PSEUDO_SCREEN_WIDTH;
3055
case SM_CYVIRTUALSCREEN:
3056
return PSEUDO_SCREEN_HEIGHT;
3063
static int WINAPI expGetSysColor(int index)
3065
dbgprintf("GetSysColor(%d) => 1\n", index);
3068
static int WINAPI expGetSysColorBrush(int index)
3070
dbgprintf("GetSysColorBrush(%d)\n", index);
3076
static int WINAPI expGetSystemPaletteEntries(int hdc, int iStartIndex, int nEntries, void* lppe)
3078
dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3079
hdc, iStartIndex, nEntries, lppe);
3084
typedef struct _TIME_ZONE_INFORMATION {
3086
char StandardName[32];
3087
SYSTEMTIME StandardDate;
3089
char DaylightName[32];
3090
SYSTEMTIME DaylightDate;
3092
} TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3095
static int WINAPI expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
3097
const short name[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3098
'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3099
const short pname[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3100
'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3101
dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3102
memset(lpTimeZoneInformation, 0, sizeof(TIME_ZONE_INFORMATION));
3103
lpTimeZoneInformation->Bias=360;//GMT-6
3104
memcpy(lpTimeZoneInformation->StandardName, name, sizeof(name));
3105
lpTimeZoneInformation->StandardDate.wMonth=10;
3106
lpTimeZoneInformation->StandardDate.wDay=5;
3107
lpTimeZoneInformation->StandardDate.wHour=2;
3108
lpTimeZoneInformation->StandardBias=0;
3109
memcpy(lpTimeZoneInformation->DaylightName, pname, sizeof(pname));
3110
lpTimeZoneInformation->DaylightDate.wMonth=4;
3111
lpTimeZoneInformation->DaylightDate.wDay=1;
3112
lpTimeZoneInformation->DaylightDate.wHour=2;
3113
lpTimeZoneInformation->DaylightBias=-60;
3114
return TIME_ZONE_ID_STANDARD;
3117
static void WINAPI expGetLocalTime(SYSTEMTIME* systime)
3120
struct tm *local_tm;
3123
dbgprintf("GetLocalTime(0x%x)\n");
3124
gettimeofday(&tv, NULL);
3125
local_time=tv.tv_sec;
3126
local_tm=localtime(&local_time);
3128
systime->wYear = local_tm->tm_year + 1900;
3129
systime->wMonth = local_tm->tm_mon + 1;
3130
systime->wDayOfWeek = local_tm->tm_wday;
3131
systime->wDay = local_tm->tm_mday;
3132
systime->wHour = local_tm->tm_hour;
3133
systime->wMinute = local_tm->tm_min;
3134
systime->wSecond = local_tm->tm_sec;
3135
systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
3136
dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3137
" Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3138
" Milliseconds: %d\n",
3139
systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay,
3140
systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds);
3143
static int WINAPI expGetSystemTime(SYSTEMTIME* systime)
3146
struct tm *local_tm;
3149
dbgprintf("GetSystemTime(0x%x)\n", systime);
3150
gettimeofday(&tv, NULL);
3151
local_time=tv.tv_sec;
3152
local_tm=gmtime(&local_time);
3154
systime->wYear = local_tm->tm_year + 1900;
3155
systime->wMonth = local_tm->tm_mon + 1;
3156
systime->wDayOfWeek = local_tm->tm_wday;
3157
systime->wDay = local_tm->tm_mday;
3158
systime->wHour = local_tm->tm_hour;
3159
systime->wMinute = local_tm->tm_min;
3160
systime->wSecond = local_tm->tm_sec;
3161
systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
3162
dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3163
" Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3164
" Milliseconds: %d\n",
3165
systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay,
3166
systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds);
3170
#define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3171
static void WINAPI expGetSystemTimeAsFileTime(FILETIME* systime)
3173
struct tm *local_tm;
3175
unsigned long long secs;
3177
dbgprintf("GetSystemTime(0x%x)\n", systime);
3178
gettimeofday(&tv, NULL);
3179
secs = (tv.tv_sec + SECS_1601_TO_1970) * 10000000;
3180
secs += tv.tv_usec * 10;
3181
systime->dwLowDateTime = secs & 0xffffffff;
3182
systime->dwHighDateTime = (secs >> 32);
3185
static int WINAPI expGetEnvironmentVariableA(const char* name, char* field, int size)
3188
// printf("%s %x %x\n", name, field, size);
3189
if(field)field[0]=0;
3192
if (p) strncpy(field,p,size);
3194
if (strcmp(name,"__MSVCRT_HEAP_SELECT")==0)
3195
strcpy(field,"__GLOBAL_HEAP_SELECTED,1");
3196
dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name, name, field, size, strlen(field));
3197
return strlen(field);
3200
static int WINAPI expSetEnvironmentVariableA(const char *name, const char *value)
3202
dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name, value);
3206
static void* WINAPI expCoTaskMemAlloc(ULONG cb)
3208
return my_mreq(cb, 0);
3210
static void WINAPI expCoTaskMemFree(void* cb)
3218
void* CoTaskMemAlloc(unsigned long cb)
3220
return expCoTaskMemAlloc(cb);
3222
void CoTaskMemFree(void* cb)
3224
expCoTaskMemFree(cb);
3227
struct COM_OBJECT_INFO
3230
long (*GetClassObject) (GUID* clsid, const GUID* iid, void** ppv);
3233
static struct COM_OBJECT_INFO* com_object_table=0;
3234
static int com_object_size=0;
3235
int RegisterComClass(const GUID* clsid, GETCLASSOBJECT gcs)
3239
com_object_table=realloc(com_object_table, sizeof(struct COM_OBJECT_INFO)*(++com_object_size));
3240
com_object_table[com_object_size-1].clsid=*clsid;
3241
com_object_table[com_object_size-1].GetClassObject=gcs;
3245
int UnregisterComClass(const GUID* clsid, GETCLASSOBJECT gcs)
3252
if (com_object_table == 0)
3253
printf("Warning: UnregisterComClass() called without any registered class\n");
3254
while (i < com_object_size)
3258
memcpy(&com_object_table[i - 1].clsid,
3259
&com_object_table[i].clsid, sizeof(GUID));
3260
com_object_table[i - 1].GetClassObject =
3261
com_object_table[i].GetClassObject;
3263
else if (memcmp(&com_object_table[i].clsid, clsid, sizeof(GUID)) == 0
3264
&& com_object_table[i].GetClassObject == gcs)
3272
if (--com_object_size == 0)
3274
free(com_object_table);
3275
com_object_table = 0;
3282
const GUID IID_IUnknown =
3284
0x00000000, 0x0000, 0x0000,
3285
{0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3287
const GUID IID_IClassFactory =
3289
0x00000001, 0x0000, 0x0000,
3290
{0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3293
static long WINAPI expCoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
3294
long dwClsContext, const GUID* riid, void** ppv)
3297
struct COM_OBJECT_INFO* ci=0;
3298
for(i=0; i<com_object_size; i++)
3299
if(!memcmp(rclsid, &com_object_table[i].clsid, sizeof(GUID)))
3300
ci=&com_object_table[i];
3301
if(!ci)return REGDB_E_CLASSNOTREG;
3302
// in 'real' world we should mess with IClassFactory here
3303
i=ci->GetClassObject(rclsid, riid, ppv);
3307
long CoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
3308
long dwClsContext, const GUID* riid, void** ppv)
3310
return expCoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
3313
static int WINAPI expIsRectEmpty(CONST RECT *lprc)
3320
w = lprc->right - lprc->left;
3321
h = lprc->bottom - lprc->top;
3322
if (w <= 0 || h <= 0)
3328
dbgprintf("IsRectEmpty(%p) => %s\n", lprc, (r) ? "TRUE" : "FALSE");
3329
//printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3330
// return 0; // wmv9?
3334
static int _adjust_fdiv=0; //what's this? - used to adjust division
3335
static int _winver = 0x510; // windows version
3340
static unsigned int WINAPI expGetTempPathA(unsigned int len, char* path)
3342
dbgprintf("GetTempPathA(%d, 0x%x)", len, path);
3345
dbgprintf(" => 0\n");
3348
strcpy(path, "/tmp");
3349
dbgprintf(" => 5 ( '/tmp' )\n");
3356
DWORD dwFileAttributes;
3357
FILETIME ftCreationTime;
3358
FILETIME ftLastAccessTime;
3359
FILETIME ftLastWriteTime;
3360
DWORD nFileSizeHigh;
3364
CHAR cFileName[260];
3365
CHAR cAlternateFileName[14];
3366
} WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3369
static DIR* qtx_dir=NULL;
3371
static WIN_BOOL WINAPI expFindNextFileA(HANDLE h,LPWIN32_FIND_DATAA lpfd)
3374
dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h, lpfd);
3375
if(h==FILE_HANDLE_quicktimeqtx){
3377
if(!qtx_dir) return 0;
3378
while((d=readdir(qtx_dir))){
3379
char* x=strrchr(d->d_name,'.');
3381
if(strcmp(x,".qtx")) continue;
3382
strcpy(lpfd->cFileName,d->d_name);
3383
// sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3384
strcpy(lpfd->cAlternateFileName,"foobar.qtx");
3385
printf("### FindNext: %s\n",lpfd->cFileName);
3388
closedir(qtx_dir); qtx_dir=NULL;
3395
static HANDLE WINAPI expFindFirstFileA(LPCSTR s, LPWIN32_FIND_DATAA lpfd)
3397
dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s, s, lpfd);
3398
// printf("\n### FindFirstFileA('%s')...\n",s);
3400
if(strstr(s, "quicktime\\*.QTX")){
3401
dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s, s, lpfd);
3402
printf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",def_path);
3403
qtx_dir=opendir(def_path);
3404
if(!qtx_dir) return (HANDLE)-1;
3405
memset(lpfd,0,sizeof(*lpfd));
3406
if(expFindNextFileA(FILE_HANDLE_quicktimeqtx,lpfd))
3407
return FILE_HANDLE_quicktimeqtx;
3408
printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",def_path);
3412
if(strstr(s, "QuickTime.qts")){
3413
dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s, s, lpfd);
3414
// if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3415
// return (HANDLE)-1;
3416
strcpy(lpfd->cFileName, "QuickTime.qts");
3417
strcpy(lpfd->cAlternateFileName, "QuickT~1.qts");
3418
return FILE_HANDLE_quicktimeqts;
3422
if(strstr(s, "*.vwp")){
3423
// hack for VoxWare codec plugins:
3424
strcpy(lpfd->cFileName, "msms001.vwp");
3425
strcpy(lpfd->cAlternateFileName, "msms001.vwp");
3428
// return 'file not found'
3432
static WIN_BOOL WINAPI expFindClose(HANDLE h)
3434
dbgprintf("FindClose(0x%x) => 0\n", h);
3436
// if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3437
// closedir(qtx_dir);
3443
static UINT WINAPI expSetErrorMode(UINT i)
3445
dbgprintf("SetErrorMode(%d) => 0\n", i);
3448
static UINT WINAPI expGetWindowsDirectoryA(LPSTR s,UINT c)
3450
char windir[]="c:\\windows";
3452
strncpy(s, windir, c);
3453
result=1+((c<strlen(windir))?c:strlen(windir));
3454
dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s, c, result);
3458
static UINT WINAPI expGetCurrentDirectoryA(UINT c, LPSTR s)
3460
char curdir[]="c:\\";
3462
strncpy(s, curdir, c);
3463
result=1+((c<strlen(curdir))?c:strlen(curdir));
3464
dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s, c, result);
3468
static int WINAPI expSetCurrentDirectoryA(const char *pathname)
3470
dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname, pathname);
3472
if (strrchr(pathname, '\\'))
3473
chdir(strcat(strrchr(pathname, '\\')+1, '/'));
3480
static int WINAPI expCreateDirectoryA(const char *pathname, void *sa)
3482
dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3483
pathname, pathname, sa);
3485
p = strrchr(pathname, '\\')+1;
3486
strcpy(&buf[0], p); /* should be strncpy */
3493
if (strrchr(pathname, '\\'))
3494
mkdir(strcat(strrchr(pathname, '\\')+1, '/'), 666);
3496
mkdir(pathname, 666);
3503
static WIN_BOOL WINAPI expDeleteFileA(LPCSTR s)
3505
dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s, s);
3508
static WIN_BOOL WINAPI expFileTimeToLocalFileTime(const FILETIME* cpf, LPFILETIME pf)
3510
dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf, pf);
3514
static UINT WINAPI expGetTempFileNameA(LPCSTR cs1,LPCSTR cs2,UINT i,LPSTR ps)
3516
char mask[16]="/tmp/AP_XXXXXX";
3518
dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1, cs1, cs2, cs2, i, ps);
3521
dbgprintf(" => -1\n");
3524
result=mkstemp(mask);
3525
sprintf(ps, "AP%d", result);
3526
dbgprintf(" => %d\n", strlen(ps));
3530
// This func might need proper implementation if we want AngelPotion codec.
3531
// They try to open APmpeg4v1.apl with it.
3532
// DLL will close opened file with CloseHandle().
3534
static HANDLE WINAPI expCreateFileA(LPCSTR cs1,DWORD i1,DWORD i2,
3535
LPSECURITY_ATTRIBUTES p1, DWORD i3,DWORD i4,HANDLE i5)
3537
dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1, cs1, i1,
3538
i2, p1, i3, i4, i5);
3539
if((!cs1) || (strlen(cs1)<2))return -1;
3542
if(strstr(cs1, "QuickTime.qts"))
3545
char* tmp=(char*)malloc(strlen(def_path)+50);
3546
strcpy(tmp, def_path);
3548
strcat(tmp, "QuickTime.qts");
3549
result=open(tmp, O_RDONLY);
3553
if(strstr(cs1, ".qtx"))
3556
char* tmp=(char*)malloc(strlen(def_path)+250);
3557
char* x=strrchr(cs1,'\\');
3558
sprintf(tmp,"%s/%s",def_path,x?(x+1):cs1);
3559
// printf("### Open: %s -> %s\n",cs1,tmp);
3560
result=open(tmp, O_RDONLY);
3566
if(strncmp(cs1, "AP", 2) == 0)
3569
char* tmp=(char*)malloc(strlen(def_path)+50);
3570
strcpy(tmp, def_path);
3572
strcat(tmp, "APmpg4v1.apl");
3573
result=open(tmp, O_RDONLY);
3577
if (strstr(cs1, "vp3"))
3581
char* tmp=(char*)malloc(20 + strlen(cs1));
3582
strcpy(tmp, "/tmp/");
3587
if (tmp[r] == ':' || tmp[r] == '\\')
3591
if (GENERIC_READ & i1)
3593
else if (GENERIC_WRITE & i1)
3596
printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp, r, flg);
3603
// Needed by wnvplay1.dll
3604
if (strstr(cs1, "WINNOV.bmp"))
3607
r=open("/dev/null", 0);
3612
/* we need this for some virtualdub filters */
3616
if (GENERIC_READ & i1)
3618
else if (GENERIC_WRITE & i1)
3621
printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1, r, flg);
3630
static UINT WINAPI expGetSystemDirectoryA(
3631
char* lpBuffer, // address of buffer for system directory
3632
UINT uSize // size of directory buffer
3634
dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer,uSize);
3635
if(!lpBuffer) strcpy(lpBuffer,".");
3639
static char sysdir[]=".";
3640
static LPCSTR WINAPI expGetSystemDirectoryA()
3642
dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3646
static DWORD WINAPI expGetFullPathNameA
3649
DWORD nBufferLength,
3653
if(!lpFileName) return 0;
3654
dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName,nBufferLength,
3655
lpBuffer, lpFilePart);
3658
strcpy(lpFilePart, "Quick123.qts");
3660
strcpy(lpFilePart, lpFileName);
3663
if (strrchr(lpFileName, '\\'))
3664
lpFilePart = strrchr(lpFileName, '\\');
3666
lpFilePart = (LPTSTR)lpFileName;
3668
strcpy(lpBuffer, lpFileName);
3669
// strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3670
return strlen(lpBuffer);
3673
static DWORD WINAPI expGetShortPathNameA
3679
if(!longpath) return 0;
3680
dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath,shortpath,shortlen);
3681
strcpy(shortpath,longpath);
3682
return strlen(shortpath);
3685
static WIN_BOOL WINAPI expReadFile(HANDLE h,LPVOID pv,DWORD size,LPDWORD rd,LPOVERLAPPED unused)
3688
dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, rd);
3689
result=read(h, pv, size);
3691
if(!result)return 0;
3695
static WIN_BOOL WINAPI expWriteFile(HANDLE h,LPCVOID pv,DWORD size,LPDWORD wr,LPOVERLAPPED unused)
3698
dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, wr);
3700
result=write(h, pv, size);
3702
if(!result)return 0;
3705
static DWORD WINAPI expSetFilePointer(HANDLE h, LONG val, LPLONG ext, DWORD whence)
3708
dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h, val, ext, *ext, whence);
3709
//why would DLL want temporary file with >2Gb size?
3722
if (val == 0 && ext != 0)
3725
return lseek(h, val, wh);
3728
static HDRVR WINAPI expOpenDriverA(LPCSTR szDriverName, LPCSTR szSectionName,
3731
dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2);
3734
static HDRVR WINAPI expOpenDriver(LPCSTR szDriverName, LPCSTR szSectionName,
3737
dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2);
3742
static WIN_BOOL WINAPI expGetProcessAffinityMask(HANDLE hProcess,
3743
LPDWORD lpProcessAffinityMask,
3744
LPDWORD lpSystemAffinityMask)
3746
dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3747
hProcess, lpProcessAffinityMask, lpSystemAffinityMask);
3748
if(lpProcessAffinityMask)*lpProcessAffinityMask=1;
3749
if(lpSystemAffinityMask)*lpSystemAffinityMask=1;
3753
static int WINAPI expMulDiv(int nNumber, int nNumerator, int nDenominator)
3755
static const long long max_int=0x7FFFFFFFLL;
3756
static const long long min_int=-0x80000000LL;
3757
long long tmp=(long long)nNumber*(long long)nNumerator;
3758
dbgprintf("expMulDiv %d * %d / %d\n", nNumber, nNumerator, nDenominator);
3759
if(!nDenominator)return 1;
3761
if(tmp<min_int) return 1;
3762
if(tmp>max_int) return 1;
3766
static LONG WINAPI explstrcmpiA(const char* str1, const char* str2)
3768
LONG result=strcasecmp(str1, str2);
3769
dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
3773
static LONG WINAPI explstrlenA(const char* str1)
3775
LONG result=strlen(str1);
3776
dbgprintf("strlen(0x%x='%.50s') => %d\n", str1, str1, result);
3780
static LONG WINAPI explstrcpyA(char* str1, const char* str2)
3782
int result= (int) strcpy(str1, str2);
3783
dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1, str2, str2, result);
3786
static LONG WINAPI explstrcpynA(char* str1, const char* str2,int len)
3789
if (strlen(str2)>len)
3790
result = (int) strncpy(str1, str2,len);
3792
result = (int) strcpy(str1,str2);
3793
dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1, str2, str2,len, strlen(str2),result);
3796
static LONG WINAPI explstrcatA(char* str1, const char* str2)
3798
int result= (int) strcat(str1, str2);
3799
dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1, str2, str2, result);
3804
static LONG WINAPI expInterlockedExchange(long *dest, long l)
3806
long retval = *dest;
3811
static void WINAPI expInitCommonControls(void)
3813
dbgprintf("InitCommonControls called!\n");
3818
/* needed by QuickTime.qts */
3819
static HWND WINAPI expCreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
3820
HWND parent, INT id, HINSTANCE inst,
3821
HWND buddy, INT maxVal, INT minVal, INT curVal)
3823
dbgprintf("CreateUpDownControl(...)\n");
3828
/* alex: implement this call! needed for 3ivx */
3829
static HRESULT WINAPI expCoCreateFreeThreadedMarshaler(void *pUnkOuter, void **ppUnkInner)
3831
dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
3832
pUnkOuter, ppUnkInner);
3834
return ERROR_CALL_NOT_IMPLEMENTED;
3838
static int WINAPI expDuplicateHandle(HANDLE hSourceProcessHandle, // handle to source process
3839
HANDLE hSourceHandle, // handle to duplicate
3840
HANDLE hTargetProcessHandle, // handle to target process
3841
HANDLE* lpTargetHandle, // duplicate handle
3842
DWORD dwDesiredAccess, // requested access
3843
int bInheritHandle, // handle inheritance option
3844
DWORD dwOptions // optional actions
3847
dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
3848
hSourceProcessHandle, hSourceHandle, hTargetProcessHandle,
3849
lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions);
3850
*lpTargetHandle = hSourceHandle;
3854
// required by PIM1 codec (used by win98 PCTV Studio capture sw)
3855
static HRESULT WINAPI expCoInitialize(
3856
LPVOID lpReserved /* [in] pointer to win32 malloc interface
3857
(obsolete, should be NULL) */
3861
* Just delegate to the newer method.
3863
return 0; //CoInitializeEx(lpReserved, COINIT_APARTMENTTHREADED);
3866
static DWORD WINAPI expSetThreadAffinityMask
3869
DWORD dwThreadAffinityMask
3875
* no WINAPI functions - CDECL
3877
static void* expmalloc(int size)
3880
// return malloc(size);
3881
void* result=my_mreq(size,0);
3882
dbgprintf("malloc(0x%x) => 0x%x\n", size,result);
3884
printf("WARNING: malloc() failed\n");
3887
static void expfree(void* mem)
3889
// return free(mem);
3890
dbgprintf("free(%p)\n", mem);
3893
/* needed by atrac3.acm */
3894
static void *expcalloc(int num, int size)
3896
void* result=my_mreq(num*size,1);
3897
dbgprintf("calloc(%d,%d) => %p\n", num,size,result);
3899
printf("WARNING: calloc() failed\n");
3902
static void* expnew(int size)
3904
// printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
3905
// printf("%08x %08x %08x %08x\n",
3906
// size, *(1+(int*)&size),
3907
// *(2+(int*)&size),*(3+(int*)&size));
3911
result=my_mreq(size,0);
3912
dbgprintf("new(%d) => %p\n", size, result);
3914
printf("WARNING: new() failed\n");
3918
static int expdelete(void* memory)
3920
dbgprintf("delete(%p)\n", memory);
3926
* local definition - we need only the last two members at this point
3927
* otherwice we would have to introduce here GUIDs and some more types..
3929
typedef struct __attribute__((__packed__))
3932
unsigned long cbFormat; //0x40
3933
char* pbFormat; //0x44
3935
static HRESULT WINAPI expMoCopyMediaType(MY_MEDIA_TYPE* dest, const MY_MEDIA_TYPE* src)
3939
memcpy(dest, src, sizeof(MY_MEDIA_TYPE));
3942
dest->pbFormat = (char*) my_mreq(dest->cbFormat, 0);
3943
if (!dest->pbFormat)
3944
return E_OUTOFMEMORY;
3945
memcpy(dest->pbFormat, src->pbFormat, dest->cbFormat);
3949
static HRESULT WINAPI expMoInitMediaType(MY_MEDIA_TYPE* dest, DWORD cbFormat)
3953
memset(dest, 0, sizeof(MY_MEDIA_TYPE));
3956
dest->pbFormat = (char*) my_mreq(cbFormat, 0);
3957
if (!dest->pbFormat)
3958
return E_OUTOFMEMORY;
3962
static HRESULT WINAPI expMoCreateMediaType(MY_MEDIA_TYPE** dest, DWORD cbFormat)
3966
*dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0);
3967
return expMoInitMediaType(*dest, cbFormat);
3969
static HRESULT WINAPI expMoDuplicateMediaType(MY_MEDIA_TYPE** dest, const void* src)
3973
*dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0);
3974
return expMoCopyMediaType(*dest, src);
3976
static HRESULT WINAPI expMoFreeMediaType(MY_MEDIA_TYPE* dest)
3982
my_release(dest->pbFormat);
3988
static HRESULT WINAPI expMoDeleteMediaType(MY_MEDIA_TYPE* dest)
3992
expMoFreeMediaType(dest);
3997
static int exp_snprintf( char *str, int size, const char *format, ... )
4001
va_start(va, format);
4002
x=snprintf(str,size,format,va);
4003
dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str,size,format,x);
4009
static int exp_initterm(int v1, int v2)
4011
dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1, v2);
4015
/* merged from wine - 2002.04.21 */
4016
typedef void (*_INITTERMFUNC)();
4017
static int exp_initterm(_INITTERMFUNC *start, _INITTERMFUNC *end)
4019
dbgprintf("_initterm(0x%x, 0x%x) %p\n", start, end, *start);
4024
//printf("call _initfunc: from: %p %d\n", *start);
4025
// ok this trick with push/pop is necessary as otherwice
4026
// edi/esi registers are being trashed
4028
__asm__ __volatile__
4045
//printf("done %p %d:%d\n", end);
4053
static void* exp__dllonexit()
4055
// FIXME extract from WINE
4059
static int expwsprintfA(char* string, const char* format, ...)
4063
va_start(va, format);
4064
result = vsprintf(string, format, va);
4065
dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string, format, result);
4070
static int expsprintf(char* str, const char* format, ...)
4074
dbgprintf("sprintf(0x%x, %s)\n", str, format);
4075
va_start(args, format);
4076
r = vsprintf(str, format, args);
4080
static int expsscanf(const char* str, const char* format, ...)
4084
dbgprintf("sscanf(%s, %s)\n", str, format);
4085
va_start(args, format);
4086
r = vsscanf(str, format, args);
4090
static void* expfopen(const char* path, const char* mode)
4092
printf("fopen: \"%s\" mode:%s\n", path, mode);
4093
//return fopen(path, mode);
4094
return fdopen(0, mode); // everything on screen
4096
static int expfprintf(void* stream, const char* format, ...)
4100
dbgprintf("fprintf(%p, %s, ...)\n", stream, format);
4102
va_start(args, format);
4103
r = vfprintf((FILE*) stream, format, args);
4109
static int expprintf(const char* format, ...)
4113
dbgprintf("printf(%s, ...)\n", format);
4114
va_start(args, format);
4115
r = vprintf(format, args);
4120
static char* expgetenv(const char* varname)
4122
char* v = getenv(varname);
4123
dbgprintf("getenv(%s) => %s\n", varname, v);
4127
static void* expwcscpy(WCHAR* dst, const WCHAR* src)
4130
while ((*p++ = *src++))
4135
static char* expstrrchr(char* string, int value)
4137
char* result=strrchr(string, value);
4139
dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result);
4141
dbgprintf("strrchr(0x%x='%s', %d) => 0", string, string, value);
4145
static char* expstrchr(char* string, int value)
4147
char* result=strchr(string, value);
4149
dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result);
4151
dbgprintf("strchr(0x%x='%s', %d) => 0", string, string, value);
4154
static int expstrlen(char* str)
4156
int result=strlen(str);
4157
dbgprintf("strlen(0x%x='%s') => %d\n", str, str, result);
4160
static char* expstrcpy(char* str1, const char* str2)
4162
char* result= strcpy(str1, str2);
4163
dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1, str2, str2, result);
4166
static char* expstrncpy(char* str1, const char* str2, size_t count)
4168
char* result= strncpy(str1, str2, count);
4169
dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1, str2, str2, count, result);
4172
static int expstrcmp(const char* str1, const char* str2)
4174
int result=strcmp(str1, str2);
4175
dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
4178
static int expstrncmp(const char* str1, const char* str2,int x)
4180
int result=strncmp(str1, str2,x);
4181
dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
4184
static char* expstrcat(char* str1, const char* str2)
4186
char* result = strcat(str1, str2);
4187
dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1, str1, str2, str2, result);
4190
static char* exp_strdup(const char* str1)
4192
int l = strlen(str1);
4193
char* result = (char*) my_mreq(l + 1,0);
4195
strcpy(result, str1);
4196
dbgprintf("_strdup(0x%x='%s') => %p\n", str1, str1, result);
4199
static int expisalnum(int c)
4201
int result= (int) isalnum(c);
4202
dbgprintf("isalnum(0x%x='%c' => %d\n", c, c, result);
4205
static int expisspace(int c)
4207
int result= (int) isspace(c);
4208
dbgprintf("isspace(0x%x='%c' => %d\n", c, c, result);
4211
static int expisalpha(int c)
4213
int result= (int) isalpha(c);
4214
dbgprintf("isalpha(0x%x='%c' => %d\n", c, c, result);
4217
static int expisdigit(int c)
4219
int result= (int) isdigit(c);
4220
dbgprintf("isdigit(0x%x='%c' => %d\n", c, c, result);
4223
static void* expmemmove(void* dest, void* src, int n)
4225
void* result = memmove(dest, src, n);
4226
dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest, src, n, result);
4229
static int expmemcmp(void* dest, void* src, int n)
4231
int result = memcmp(dest, src, n);
4232
dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest, src, n, result);
4235
static void* expmemcpy(void* dest, void* src, int n)
4237
void *result = memcpy(dest, src, n);
4238
dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest, src, n, result);
4241
static void* expmemset(void* dest, int c, size_t n)
4243
void *result = memset(dest, c, n);
4244
dbgprintf("memset(0x%x, %d, %d) => %p\n", dest, c, n, result);
4247
static time_t exptime(time_t* t)
4249
time_t result = time(t);
4250
dbgprintf("time(0x%x) => %d\n", t, result);
4254
static int exprand(void)
4259
static void expsrand(int seed)
4266
// prefered compilation with -O2 -ffast-math !
4268
static double explog10(double x)
4270
/*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4274
static double expcos(double x)
4276
/*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4281
static long exp_ftol_wrong(double x)
4288
static void explog10(void)
4290
__asm__ __volatile__
4299
static void expcos(void)
4301
__asm__ __volatile__
4310
// this seem to be the only how to make this function working properly
4311
// ok - I've spent tremendous amount of time (many many many hours
4312
// of debuging fixing & testing - it's almost unimaginable - kabi
4314
// _ftol - operated on the float value which is already on the FPU stack
4316
static void exp_ftol(void)
4318
__asm__ __volatile__
4320
"sub $12, %esp \n\t"
4321
"fstcw -2(%ebp) \n\t"
4323
"movw -2(%ebp), %ax \n\t"
4324
"orb $0x0C, %ah \n\t"
4325
"movw %ax, -4(%ebp) \n\t"
4326
"fldcw -4(%ebp) \n\t"
4327
"fistpl -12(%ebp) \n\t"
4328
"fldcw -2(%ebp) \n\t"
4329
"movl -12(%ebp), %eax \n\t"
4330
//Note: gcc 3.03 does not do the following op if it
4331
// knows that ebp=esp
4332
"movl %ebp, %esp \n\t"
4336
#define FPU_DOUBLES(var1,var2) double var1,var2; \
4337
__asm__ __volatile__( "fstpl %0;fwait" : "=m" (var2) : ); \
4338
__asm__ __volatile__( "fstpl %0;fwait" : "=m" (var1) : )
4340
static double exp_CIpow(void)
4344
dbgprintf("_CIpow(%lf, %lf)\n", x, y);
4348
static double exppow(double x, double y)
4350
/*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4354
static double expldexp(double x, int expo)
4356
/*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4357
return ldexp(x, expo);
4360
static double expfrexp(double x, int* expo)
4362
/*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4363
return frexp(x, expo);
4368
static int exp_stricmp(const char* s1, const char* s2)
4370
return strcasecmp(s1, s2);
4373
/* from declaration taken from Wine sources - this fountion seems to be
4374
* undocumented in any M$ doc */
4375
static int exp_setjmp3(void* jmpbuf, int x)
4377
//dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4379
__asm__ __volatile__
4381
//"mov 4(%%esp), %%edx \n\t"
4382
"mov (%%esp), %%eax \n\t"
4383
"mov %%eax, (%%edx) \n\t" // store ebp
4385
//"mov %%ebp, (%%edx) \n\t"
4386
"mov %%ebx, 4(%%edx) \n\t"
4387
"mov %%edi, 8(%%edx) \n\t"
4388
"mov %%esi, 12(%%edx) \n\t"
4389
"mov %%esp, 16(%%edx) \n\t"
4391
"mov 4(%%esp), %%eax \n\t"
4392
"mov %%eax, 20(%%edx) \n\t"
4394
"movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4395
"movl $0, 36(%%edx) \n\t"
4397
: "d"(jmpbuf) // input
4401
__asm__ __volatile__
4403
"mov %%fs:0, %%eax \n\t" // unsure
4404
"mov %%eax, 24(%%edx) \n\t"
4405
"cmp $0xffffffff, %%eax \n\t"
4407
"mov %%eax, 28(%%edx) \n\t"
4418
static DWORD WINAPI expGetCurrentProcessId(void)
4420
dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4421
return getpid(); //(DWORD)NtCurrentTeb()->pid;
4428
} TIMECAPS, *LPTIMECAPS;
4430
static MMRESULT WINAPI exptimeGetDevCaps(LPTIMECAPS lpCaps, UINT wSize)
4432
dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
4434
lpCaps->wPeriodMin = 1;
4435
lpCaps->wPeriodMax = 65535;
4439
static MMRESULT WINAPI exptimeBeginPeriod(UINT wPeriod)
4441
dbgprintf("timeBeginPeriod(%u) !\n", wPeriod);
4443
if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO;
4448
static MMRESULT WINAPI exptimeEndPeriod(UINT wPeriod)
4450
dbgprintf("timeEndPeriod(%u) !\n", wPeriod);
4452
if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO;
4457
static void WINAPI expGlobalMemoryStatus(
4458
LPMEMORYSTATUS lpmem
4460
static MEMORYSTATUS cached_memstatus;
4461
static int cache_lastchecked = 0;
4465
if (time(NULL)==cache_lastchecked) {
4466
memcpy(lpmem,&cached_memstatus,sizeof(MEMORYSTATUS));
4471
f = fopen( "/proc/meminfo", "r" );
4475
int total, used, free, shared, buffers, cached;
4477
lpmem->dwLength = sizeof(MEMORYSTATUS);
4478
lpmem->dwTotalPhys = lpmem->dwAvailPhys = 0;
4479
lpmem->dwTotalPageFile = lpmem->dwAvailPageFile = 0;
4480
while (fgets( buffer, sizeof(buffer), f ))
4482
/* old style /proc/meminfo ... */
4483
if (sscanf( buffer, "Mem: %d %d %d %d %d %d", &total, &used, &free, &shared, &buffers, &cached ))
4485
lpmem->dwTotalPhys += total;
4486
lpmem->dwAvailPhys += free + buffers + cached;
4488
if (sscanf( buffer, "Swap: %d %d %d", &total, &used, &free ))
4490
lpmem->dwTotalPageFile += total;
4491
lpmem->dwAvailPageFile += free;
4494
/* new style /proc/meminfo ... */
4495
if (sscanf(buffer, "MemTotal: %d", &total))
4496
lpmem->dwTotalPhys = total*1024;
4497
if (sscanf(buffer, "MemFree: %d", &free))
4498
lpmem->dwAvailPhys = free*1024;
4499
if (sscanf(buffer, "SwapTotal: %d", &total))
4500
lpmem->dwTotalPageFile = total*1024;
4501
if (sscanf(buffer, "SwapFree: %d", &free))
4502
lpmem->dwAvailPageFile = free*1024;
4503
if (sscanf(buffer, "Buffers: %d", &buffers))
4504
lpmem->dwAvailPhys += buffers*1024;
4505
if (sscanf(buffer, "Cached: %d", &cached))
4506
lpmem->dwAvailPhys += cached*1024;
4510
if (lpmem->dwTotalPhys)
4512
DWORD TotalPhysical = lpmem->dwTotalPhys+lpmem->dwTotalPageFile;
4513
DWORD AvailPhysical = lpmem->dwAvailPhys+lpmem->dwAvailPageFile;
4514
lpmem->dwMemoryLoad = (TotalPhysical-AvailPhysical)
4515
/ (TotalPhysical / 100);
4520
/* FIXME: should do something for other systems */
4521
lpmem->dwMemoryLoad = 0;
4522
lpmem->dwTotalPhys = 16*1024*1024;
4523
lpmem->dwAvailPhys = 16*1024*1024;
4524
lpmem->dwTotalPageFile = 16*1024*1024;
4525
lpmem->dwAvailPageFile = 16*1024*1024;
4527
expGetSystemInfo(&si);
4528
lpmem->dwTotalVirtual = si.lpMaximumApplicationAddress-si.lpMinimumApplicationAddress;
4529
/* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4530
lpmem->dwAvailVirtual = lpmem->dwTotalVirtual-64*1024;
4531
memcpy(&cached_memstatus,lpmem,sizeof(MEMORYSTATUS));
4532
cache_lastchecked = time(NULL);
4534
/* it appears some memory display programs want to divide by these values */
4535
if(lpmem->dwTotalPageFile==0)
4536
lpmem->dwTotalPageFile++;
4538
if(lpmem->dwAvailPageFile==0)
4539
lpmem->dwAvailPageFile++;
4542
static INT WINAPI expGetThreadPriority(HANDLE hthread)
4544
dbgprintf("GetThreadPriority(%p)\n",hthread);
4548
/**********************************************************************
4549
* SetThreadPriority [KERNEL32.@] Sets priority for thread.
4555
static WIN_BOOL WINAPI expSetThreadPriority(
4556
HANDLE hthread, /* [in] Handle to thread */
4557
INT priority) /* [in] Thread priority level */
4559
dbgprintf("SetThreadPriority(%p,%d)\n",hthread,priority);
4563
static void WINAPI expExitProcess( DWORD status )
4565
printf("EXIT - code %ld\n",status);
4569
static INT WINAPI expMessageBoxA(HWND hWnd, LPCSTR text, LPCSTR title, UINT type){
4570
printf("MSGBOX '%s' '%s' (%d)\n",text,title,type);
4572
if (type == MB_ICONHAND && !strlen(text) && !strlen(title))
4578
/* these are needed for mss1 */
4580
/* defined in stubs.s */
4581
void exp_EH_prolog(void);
4583
#include <netinet/in.h>
4584
static WINAPI inline unsigned long int exphtonl(unsigned long int hostlong)
4586
// dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4587
return htonl(hostlong);
4590
static WINAPI inline unsigned long int expntohl(unsigned long int netlong)
4592
// dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4593
return ntohl(netlong);
4595
static void WINAPI expVariantInit(void* p)
4597
printf("InitCommonControls called!\n");
4601
static int WINAPI expRegisterClassA(const void/*WNDCLASSA*/ *wc)
4603
dbgprintf("RegisterClassA(%p) => random id\n", wc);
4604
return time(NULL); /* be precise ! */
4607
static int WINAPI expUnregisterClassA(const char *className, HINSTANCE hInstance)
4609
dbgprintf("UnregisterClassA(%s, %p) => 0\n", className, hInstance);
4614
/* should be fixed bcs it's not fully strlen equivalent */
4615
static int expSysStringByteLen(void *str)
4617
dbgprintf("SysStringByteLen(%p) => %d\n", str, strlen(str));
4621
static int expDirectDrawCreate(void)
4623
dbgprintf("DirectDrawCreate(...) => NULL\n");
4628
typedef struct tagPALETTEENTRY {
4635
/* reversed the first 2 entries */
4636
typedef struct tagLOGPALETTE {
4639
PALETTEENTRY palPalEntry[1];
4642
static HPALETTE WINAPI expCreatePalette(CONST LOGPALETTE *lpgpl)
4647
dbgprintf("CreatePalette(%x) => NULL\n", lpgpl);
4649
i = sizeof(LOGPALETTE)+((lpgpl->palNumEntries-1)*sizeof(PALETTEENTRY));
4650
test = (HPALETTE)malloc(i);
4651
memcpy((void *)test, lpgpl, i);
4656
static int expCreatePalette(void)
4658
dbgprintf("CreatePalette(...) => NULL\n");
4663
static int WINAPI expGetClientRect(HWND win, RECT *r)
4665
dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win, r);
4666
r->right = PSEUDO_SCREEN_WIDTH;
4668
r->bottom = PSEUDO_SCREEN_HEIGHT;
4674
typedef struct tagPOINT {
4680
static int WINAPI expClientToScreen(HWND win, POINT *p)
4682
dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win, p, p->x, p->y);
4690
static int WINAPI expSetThreadIdealProcessor(HANDLE thread, int proc)
4692
dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread, proc);
4696
static int WINAPI expMessageBeep(int type)
4698
dbgprintf("MessageBeep(%d) => 1\n", type);
4702
static int WINAPI expDialogBoxParamA(void *inst, const char *name,
4703
HWND parent, void *dialog_func, void *init_param)
4705
dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
4706
inst, name, name, parent, dialog_func, init_param);
4710
static void WINAPI expRegisterClipboardFormatA(const char *name) {
4711
dbgprintf("RegisterClipboardFormatA(0x%x = %s)\n", name, name);
4714
/* needed by imagepower mjpeg2k */
4715
static void *exprealloc(void *ptr, size_t size)
4717
dbgprintf("realloc(0x%x, %x)\n", ptr, size);
4719
return my_mreq(size,0);
4721
return my_realloc(ptr, size);
4724
/* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
4725
static WIN_BOOL WINAPI expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn)
4730
static char * WINAPI expPathFindExtensionA(const char *path) {
4735
ext = strrchr(path, '.');
4737
ext = &path[strlen(path)];
4739
dbgprintf("PathFindExtensionA(0x%x = %s) => 0x%x, %s\n", path, path, ext, ext);
4743
static char * WINAPI expPathFindFileNameA(const char *path) {
4745
if (!path || strlen(path) < 2)
4748
name = strrchr(path - 1, '\\');
4752
dbgprintf("PathFindFileNameA(0x%x = %s) => 0x%x, %s\n", path, path, name, name);
4756
static double expfloor(double x)
4758
dbgprintf("floor(%lf)\n", x);
4762
#define FPU_DOUBLE(var) double var; \
4763
__asm__ __volatile__( "fstpl %0;fwait" : "=m" (var) : )
4765
static double exp_CIcos(void)
4769
dbgprintf("_CIcos(%lf)\n", x);
4773
static double exp_CIsin(void)
4777
dbgprintf("_CIsin(%lf)\n", x);
4781
/* Needed by rp8 sipr decoder */
4782
static LPSTR WINAPI expCharNextA(LPCSTR ptr)
4784
if (!*ptr) return (LPSTR)ptr;
4785
// dbgprintf("CharNextA(0x%08x), %s\n", ptr, ptr);
4786
return (LPSTR)(ptr + 1);
4799
struct exports* exps;
4803
{#X, Y, (void*)exp##X},
4805
struct exports exp_kernel32[]=
4807
FF(GetVolumeInformationA,-1)
4808
FF(GetDriveTypeA,-1)
4809
FF(GetLogicalDriveStringsA,-1)
4810
FF(IsBadWritePtr, 357)
4811
FF(IsBadReadPtr, 354)
4812
FF(IsBadStringPtrW, -1)
4813
FF(IsBadStringPtrA, -1)
4814
FF(DisableThreadLibraryCalls, -1)
4815
FF(CreateThread, -1)
4816
FF(CreateEventA, -1)
4819
FF(WaitForSingleObject, -1)
4821
FF(WaitForMultipleObjects, -1)
4826
FF(GetSystemInfo, -1)
4834
FF(GetProcessHeap, -1)
4835
FF(VirtualAlloc, -1)
4837
FF(InitializeCriticalSection, -1)
4838
FF(EnterCriticalSection, -1)
4839
FF(LeaveCriticalSection, -1)
4840
FF(DeleteCriticalSection, -1)
4845
FF(GetCurrentThreadId, -1)
4846
FF(GetCurrentProcess, -1)
4851
FF(GlobalReAlloc, -1)
4854
FF(MultiByteToWideChar, 427)
4855
FF(WideCharToMultiByte, -1)
4856
FF(GetVersionExA, -1)
4857
FF(CreateSemaphoreA, -1)
4858
FF(QueryPerformanceCounter, -1)
4859
FF(QueryPerformanceFrequency, -1)
4863
FF(GlobalHandle, -1)
4864
FF(GlobalUnlock, -1)
4866
FF(LoadResource, -1)
4867
FF(ReleaseSemaphore, -1)
4868
FF(FindResourceA, -1)
4869
FF(LockResource, -1)
4870
FF(FreeResource, -1)
4871
FF(SizeofResource, -1)
4873
FF(GetCommandLineA, -1)
4874
FF(GetEnvironmentStringsW, -1)
4875
FF(FreeEnvironmentStringsW, -1)
4876
FF(FreeEnvironmentStringsA, -1)
4877
FF(GetEnvironmentStrings, -1)
4878
FF(GetStartupInfoA, -1)
4879
FF(GetStdHandle, -1)
4882
FF(GetFileAttributesA, -1)
4884
FF(SetHandleCount, -1)
4886
FF(GetModuleFileNameA, -1)
4887
FF(SetUnhandledExceptionFilter, -1)
4888
FF(LoadLibraryA, -1)
4889
FF(GetProcAddress, -1)
4891
FF(CreateFileMappingA, -1)
4892
FF(OpenFileMappingA, -1)
4893
FF(MapViewOfFile, -1)
4894
FF(UnmapViewOfFile, -1)
4896
FF(GetModuleHandleA, -1)
4897
FF(GetProfileIntA, -1)
4898
FF(GetPrivateProfileIntA, -1)
4899
FF(GetPrivateProfileStringA, -1)
4900
FF(WritePrivateProfileStringA, -1)
4901
FF(GetLastError, -1)
4902
FF(SetLastError, -1)
4903
FF(InterlockedIncrement, -1)
4904
FF(InterlockedDecrement, -1)
4905
FF(GetTimeZoneInformation, -1)
4906
FF(OutputDebugStringA, -1)
4907
FF(GetLocalTime, -1)
4908
FF(GetSystemTime, -1)
4909
FF(GetSystemTimeAsFileTime, -1)
4910
FF(GetEnvironmentVariableA, -1)
4911
FF(SetEnvironmentVariableA, -1)
4912
FF(RtlZeroMemory,-1)
4913
FF(RtlMoveMemory,-1)
4914
FF(RtlFillMemory,-1)
4916
FF(FindFirstFileA,-1)
4917
FF(FindNextFileA,-1)
4919
FF(FileTimeToLocalFileTime,-1)
4923
FF(SetFilePointer,-1)
4924
FF(GetTempFileNameA,-1)
4926
FF(GetSystemDirectoryA,-1)
4927
FF(GetWindowsDirectoryA,-1)
4929
FF(GetCurrentDirectoryA,-1)
4930
FF(SetCurrentDirectoryA,-1)
4931
FF(CreateDirectoryA,-1)
4933
FF(GetShortPathNameA,-1)
4934
FF(GetFullPathNameA,-1)
4935
FF(SetErrorMode, -1)
4936
FF(IsProcessorFeaturePresent, -1)
4937
FF(GetProcessAffinityMask, -1)
4938
FF(InterlockedExchange, -1)
4939
FF(InterlockedCompareExchange, -1)
4946
FF(GetProcessVersion,-1)
4947
FF(GetCurrentThread,-1)
4950
FF(DuplicateHandle,-1)
4951
FF(GetTickCount, -1)
4952
FF(SetThreadAffinityMask,-1)
4953
FF(GetCurrentProcessId,-1)
4954
FF(GlobalMemoryStatus,-1)
4955
FF(GetThreadPriority,-1)
4956
FF(SetThreadPriority,-1)
4958
{"LoadLibraryExA", -1, (void*)&LoadLibraryExA},
4959
FF(SetThreadIdealProcessor,-1)
4962
struct exports exp_msvcrt[]={
4968
{"??3@YAXPAX@Z", -1, expdelete},
4969
{"??2@YAPAXI@Z", -1, expnew},
4970
{"_adjust_fdiv", -1, (void*)&_adjust_fdiv},
4971
{"_winver",-1,(void*)&_winver},
5011
/* needed by frapsvid.dll */
5012
{"strstr",-1,(char *)&strstr},
5013
{"qsort",-1,(void *)&qsort},
5018
{"ceil",-1,(void*)&ceil},
5019
/* needed by imagepower mjpeg2k */
5020
{"clock",-1,(void*)&clock},
5021
{"memchr",-1,(void*)&memchr},
5022
{"vfprintf",-1,(void*)&vfprintf},
5023
// {"realloc",-1,(void*)&realloc},
5025
{"puts",-1,(void*)&puts}
5027
struct exports exp_winmm[]={
5028
FF(GetDriverModuleHandle, -1)
5030
FF(DefDriverProc, -1)
5033
FF(timeGetDevCaps, -1)
5034
FF(timeBeginPeriod, -1)
5036
FF(timeEndPeriod, -1)
5037
FF(waveOutGetNumDevs, -1)
5040
struct exports exp_user32[]={
5045
FF(GetDesktopWindow, -1)
5054
FF(RegisterWindowMessageA,-1)
5055
FF(GetSystemMetrics,-1)
5057
FF(GetSysColorBrush,-1)
5061
FF(RegisterClassA, -1)
5062
FF(UnregisterClassA, -1)
5064
FF(GetWindowRect, -1)
5065
FF(MonitorFromWindow, -1)
5066
FF(MonitorFromRect, -1)
5067
FF(MonitorFromPoint, -1)
5068
FF(EnumDisplayMonitors, -1)
5069
FF(GetMonitorInfoA, -1)
5070
FF(EnumDisplayDevicesA, -1)
5071
FF(GetClientRect, -1)
5072
FF(ClientToScreen, -1)
5073
FF(IsWindowVisible, -1)
5074
FF(GetActiveWindow, -1)
5075
FF(GetClassNameA, -1)
5076
FF(GetClassInfoA, -1)
5077
FF(GetWindowLongA, -1)
5079
FF(GetWindowThreadProcessId, -1)
5080
FF(CreateWindowExA, -1)
5083
FF(DialogBoxParamA, -1)
5084
FF(RegisterClipboardFormatA, -1)
5087
struct exports exp_advapi32[]={
5089
FF(RegCreateKeyA, -1)
5090
FF(RegCreateKeyExA, -1)
5091
FF(RegEnumKeyExA, -1)
5092
FF(RegEnumValueA, -1)
5094
FF(RegOpenKeyExA, -1)
5095
FF(RegQueryValueExA, -1)
5096
FF(RegSetValueExA, -1)
5097
FF(RegQueryInfoKeyA, -1)
5099
struct exports exp_gdi32[]={
5100
FF(CreateCompatibleDC, -1)
5103
FF(DeleteObject, -1)
5104
FF(GetDeviceCaps, -1)
5105
FF(GetSystemPaletteEntries, -1)
5107
FF(CreatePalette, -1)
5109
FF(CreateRectRgn, -1)
5112
struct exports exp_version[]={
5113
FF(GetFileVersionInfoSizeA, -1)
5115
struct exports exp_ole32[]={
5116
FF(CoCreateFreeThreadedMarshaler,-1)
5117
FF(CoCreateInstance, -1)
5118
FF(CoInitialize, -1)
5119
FF(CoTaskMemAlloc, -1)
5120
FF(CoTaskMemFree, -1)
5121
FF(StringFromGUID2, -1)
5123
// do we really need crtdll ???
5124
// msvcrt is the correct place probably...
5125
struct exports exp_crtdll[]={
5129
struct exports exp_comctl32[]={
5130
FF(StringFromGUID2, -1)
5131
FF(InitCommonControls, 17)
5133
FF(CreateUpDownControl, 16)
5136
struct exports exp_wsock32[]={
5140
struct exports exp_msdmo[]={
5141
FF(memcpy, -1) // just test
5142
FF(MoCopyMediaType, -1)
5143
FF(MoCreateMediaType, -1)
5144
FF(MoDeleteMediaType, -1)
5145
FF(MoDuplicateMediaType, -1)
5146
FF(MoFreeMediaType, -1)
5147
FF(MoInitMediaType, -1)
5149
struct exports exp_oleaut32[]={
5152
FF(SysStringByteLen, 149)
5158
vma: Hint/Ord Member-Name
5163
2305e 167 _adjust_fdiv
5166
22ffc 176 _beginthreadex
5168
2300e 85 __CxxFrameHandler
5172
struct exports exp_pncrt[]={
5173
FF(malloc, -1) // just test
5174
FF(free, -1) // just test
5175
FF(fprintf, -1) // just test
5176
{"_adjust_fdiv", -1, (void*)&_adjust_fdiv},
5179
{"??3@YAXPAX@Z", -1, expdelete},
5180
{"??2@YAPAXI@Z", -1, expnew},
5192
struct exports exp_ddraw[]={
5193
FF(DirectDrawCreate, -1)
5197
struct exports exp_comdlg32[]={
5198
FF(GetOpenFileNameA, -1)
5201
struct exports exp_shlwapi[]={
5202
FF(PathFindExtensionA, -1)
5203
FF(PathFindFileNameA, -1)
5207
{#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5209
struct libs libraries[]={
5233
static void ext_stubs(void)
5236
// ax position index
5237
// cx address of printf function
5239
__asm__ __volatile__
5242
"movl $0xdeadbeef, %%eax \n\t"
5243
"movl $0xdeadbeef, %%edx \n\t"
5244
"shl $5, %%eax \n\t" // ax * 32
5245
"addl $0xdeadbeef, %%eax \n\t" // overwrite export_names
5247
"pushl $0xdeadbeef \n\t" // overwrite called_unk
5248
"call *%%edx \n\t" // printf (via dx)
5249
"addl $8, %%esp \n\t"
5250
"xorl %%eax, %%eax \n\t"
5257
__asm__ __volatile__
5260
"movl $0, %%eax \n\t"
5261
"movl $0, %%edx \n\t"
5262
"shl $5, %%eax \n\t" // ax * 32
5263
"addl %0, %%eax \n\t"
5266
"call *%%edx \n\t" // printf (via dx)
5267
"addl $8, %%esp \n\t"
5268
"xorl %%eax, %%eax \n\t"
5270
::"m"(*export_names), "m"(*called_unk)
5271
: "memory", "edx", "eax"
5277
//static void add_stub(int pos)
5279
extern int unk_exp1;
5281
static char extcode[20000];// place for 200 unresolved exports
5282
static const char* called_unk = "Called unk_%s\n";
5284
static void* add_stub(void)
5286
// generated code in runtime!
5287
char* answ = (char*)extcode+pos*0x30;
5289
memcpy(answ, &unk_exp1, 0x64);
5290
*(int*)(answ+9)=pos;
5291
*(int*)(answ+47)-=((int)answ-(int)&unk_exp1);
5293
memcpy(answ, ext_stubs, 0x2f); // 0x2c is current size
5294
//answ[4] = 0xb8; // movl $0, eax (0xb8 0x00000000)
5295
*((int*) (answ + 5)) = pos;
5296
//answ[9] = 0xba; // movl $0, edx (0xba 0x00000000)
5297
*((long*) (answ + 10)) = (long)printf;
5298
//answ[17] = 0x05; // addl $0, eax (0x05 0x00000000)
5299
*((long*) (answ + 18)) = (long)export_names;
5300
//answ[23] = 0x68; // pushl $0 (0x68 0x00000000)
5301
*((long*) (answ + 24)) = (long)called_unk;
5306
void* LookupExternal(const char* library, int ordinal)
5311
printf("ERROR: library=0\n");
5312
return (void*)ext_unknown;
5314
// printf("%x %x\n", &unk_exp1, &unk_exp2);
5316
dbgprintf("External func %s:%d\n", library, ordinal);
5318
for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
5320
if(strcasecmp(library, libraries[i].name))
5322
for(j=0; j<libraries[i].length; j++)
5324
if(ordinal!=libraries[i].exps[j].id)
5326
//printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5327
return libraries[i].exps[j].func;
5331
#ifndef LOADLIB_TRY_NATIVE
5332
/* hack for truespeech and vssh264*/
5333
if (!strcmp(library, "tsd32.dll") || !strcmp(library,"vssh264dec.dll") || !strcmp(library,"LCMW2.dll") || !strcmp(library,"VDODEC32.dll"))
5335
/* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5341
hand = LoadLibraryA(library);
5344
wm = MODULE32_LookupHMODULE(hand);
5350
func = PE_FindExportedFunction(wm, (LPCSTR) ordinal, 0);
5353
printf("No such ordinal in external dll\n");
5354
FreeLibrary((int)hand);
5358
printf("External dll loaded (offset: 0x%x, func: %p)\n",
5364
if(pos>150)return 0;
5365
sprintf(export_names[pos], "%s:%d", library, ordinal);
5369
void* LookupExternalByName(const char* library, const char* name)
5373
// return (void*)ext_unknown;
5376
printf("ERROR: library=0\n");
5377
return (void*)ext_unknown;
5381
printf("ERROR: name=0\n");
5382
return (void*)ext_unknown;
5384
dbgprintf("External func %s:%s\n", library, name);
5385
for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
5387
if(strcasecmp(library, libraries[i].name))
5389
for(j=0; j<libraries[i].length; j++)
5391
if(strcmp(name, libraries[i].exps[j].name))
5393
// printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5394
return libraries[i].exps[j].func;
5398
#ifndef LOADLIB_TRY_NATIVE
5399
/* hack for vss h264 */
5400
if (!strcmp(library,"vssh264core.dll"))
5402
/* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5408
hand = LoadLibraryA(library);
5411
wm = MODULE32_LookupHMODULE(hand);
5417
func = PE_FindExportedFunction(wm, name, 0);
5420
printf("No such name in external dll\n");
5421
FreeLibrary((int)hand);
5425
printf("External dll loaded (offset: 0x%x, func: %p)\n",
5431
if(pos>150)return 0;// to many symbols
5432
strcpy(export_names[pos], name);
5436
void my_garbagecollection(void)
5439
int unfree = 0, unfreecnt = 0;
5445
alloc_header* mem = last_alloc + 1;
5446
unfree += my_size(mem);
5448
if (my_release(mem) != 0)
5449
// avoid endless loop when memory is trashed
5450
if (--max_fatal < 0)
5453
dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree, unfreecnt, last_alloc, alccnt);