diff options
Diffstat (limited to 'loader/win32.c')
-rw-r--r-- | loader/win32.c | 1578 |
1 files changed, 1256 insertions, 322 deletions
diff --git a/loader/win32.c b/loader/win32.c index 06b499afd0..643da26c1e 100644 --- a/loader/win32.c +++ b/loader/win32.c @@ -5,6 +5,9 @@ Since we are not going to be able to load virtually any DLL, we can only implement this much, adding needed functions with each new codec. + + Basic principle of implementation: it's not good + for DLL to know too much about its environment. ************************************************************/ @@ -13,12 +16,15 @@ #include "win32.h" #include <stdio.h> #include <pthread.h> +#include <errno.h> #ifdef HAVE_MALLOC_H #include <malloc.h> #else #include <stdlib.h> #endif #include <time.h> +#include <unistd.h> +#include <fcntl.h> #include <sys/types.h> #include <sys/time.h> #include <sys/timeb.h> @@ -32,8 +38,26 @@ #include <registry.h> #include <loader.h> -#ifdef USE_TSC -static unsigned int localcount() +#include <com.h> + +char* def_path=WIN32_PATH; + +static void do_cpuid(unsigned int *regs) +{ + unsigned int ax; + ax=1; + __asm__ __volatile__( + "pushl %%ebx; pushl %%ecx; pushl %%edx; " + ".byte 0x0f, 0xa2;" + "movl %%eax, (%2);" + "movl %%ebx, 4(%2);" + "movl %%ecx, 8(%2);" + "movl %%edx, 12(%2);" + "popl %%edx; popl %%ecx; popl %%ebx; " + : "=a" (ax) + : "0" (ax), "S" (®s)); +} +static unsigned int c_localcount_tsc() { int a; __asm__ __volatile__("rdtsc\n\t" @@ -42,7 +66,7 @@ static unsigned int localcount() :"edx"); return a; } -static void longcount(long long* z) +static void c_longcount_tsc(long long* z) { __asm__ __volatile__( "pushl %%ebx\n\t" @@ -53,10 +77,9 @@ static void longcount(long long* z) "popl %%ebx\n\t" ::"a"(z)); } -#else #include <sys/time.h> #include <unistd.h> -static unsigned int localcount() +static unsigned int c_localcount_notsc() { struct timeval tv; unsigned limit=~0; @@ -64,7 +87,7 @@ static unsigned int localcount() gettimeofday(&tv, 0); return limit*tv.tv_usec; } -static void longcount(long long* z) +static void c_longcount_notsc(long long* z) { struct timeval tv; unsigned long long result; @@ -77,27 +100,62 @@ static void longcount(long long* z) result+=limit*tv.tv_usec; *z=result; } -#endif +static unsigned int localcount_stub(); +static void longcount_stub(long long*); +static unsigned int (*localcount)()=localcount_stub; +static void (*longcount)(long long*)=longcount_stub; -void dbgprintf(char* fmt, ...) +static unsigned int localcount_stub() { -#ifdef DETAILED_OUT -#if 1 - va_list va; - va_start(va, fmt); - vprintf(fmt, va); - va_end(va); -#else - va_list va; - FILE* f; - va_start(va, fmt); - f=fopen("./log", "a"); - if(f==0)return; - vfprintf(f, fmt, va); - fsync(f); - fclose(f); -#endif -#endif + unsigned int regs[4]; + do_cpuid(regs); + if ((regs[3] & 0x00000010) == 0) + { + localcount=c_localcount_tsc; + longcount=c_longcount_tsc; + } + else + { + localcount=c_localcount_notsc; + longcount=c_longcount_notsc; + } + return localcount(); +} +static void longcount_stub(long long* z) +{ + unsigned int regs[4]; + do_cpuid(regs); + if ((regs[3] & 0x00000010) == 0) + { + localcount=c_localcount_tsc; + longcount=c_longcount_tsc; + } + else + { + localcount=c_localcount_notsc; + longcount=c_longcount_notsc; + } + longcount(z); +} + +int LOADER_DEBUG=0; +inline void dbgprintf(char* fmt, ...) +{ + if(LOADER_DEBUG) + { + FILE* f; + va_list va; + va_start(va, fmt); + f=fopen("./log", "a"); + vprintf(fmt, va); + if(f) + { + vfprintf(f, fmt, va); + fsync(fileno(f)); + fclose(f); + } + va_end(va); + } } char export_names[500][30]={ "name1", @@ -182,6 +240,19 @@ int my_release(char* memory) } #else +#define GARBAGE +#ifdef GARBAGE +struct alc_list_t; +typedef struct alc_list_t { + int size; + int addr; + struct alc_list_t *prev; + struct alc_list_t *next; +}alc_list; +static alc_list *alclist=NULL; +static alccnt=0; +#endif + void* my_mreq(int size, int to_zero) { void* answer; @@ -190,11 +261,56 @@ void* my_mreq(int size, int to_zero) else answer=malloc(size+4); *(int*)answer=size; - return (int*)answer+1; +#ifdef GARBAGE + if (alclist==NULL) { + alclist=malloc(sizeof(alc_list)); + alclist->prev=alclist->next=NULL; + } + else { + alclist->next=malloc(sizeof(alc_list)); + alclist->next->prev=alclist; + alclist->next->next=NULL; + alclist=alclist->next; + } + alclist->size=size; + alclist->addr=answer; + alccnt++; +#endif + return (int*)((int)answer+sizeof(int)); } int my_release(char* memory) { +#ifdef GARBAGE + alc_list* pp; if(memory==0)return 0; + if(alclist!=NULL) + { + pp=alclist; + if ((pp->prev==NULL) && (pp->next == NULL)){ + free(pp); + alclist=NULL; + } + else { + for(;pp;pp=pp->prev) { + if (pp->addr == memory-4) { + if (pp->prev) + pp->prev->next=pp->next; + if (pp->next) + pp->next->prev=pp->prev; + if (pp == alclist) + alclist=pp->prev; + free(pp); + alccnt--; + break; + } + } + if (pp == NULL) { + printf("Not Found %x %d\n",memory-4,alccnt); + return 0; + } + } + } +#endif free(memory-4); return 0; } @@ -215,39 +331,44 @@ int WINAPI ext_unknown() } int WINAPI expIsBadWritePtr(void* ptr, unsigned int count) { - dbgprintf("IsBadWritePtr(%x, %x)\n", ptr, count); + int result; if(count==0) - return 0; + result=0; + else if(ptr==0) - return 1; - return 0; + result=1; + else + result=0; + dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr, count, result); + return result; } int WINAPI expIsBadReadPtr(void* ptr, unsigned int count) { - dbgprintf("IsBadReadPtr(%x, %x)\n", ptr, count); + int result; if(count==0) - return 0; + result=0; + else if(ptr==0) - return 1; - return 0; + result=1; + else + result=0; + dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr, count, result); + return result; } void* CDECL expmalloc(int size) { //printf("malloc"); // return malloc(size); void* result=my_mreq(size,0); - dbgprintf("malloc(%x)\n", size); + dbgprintf("malloc(0x%x) => 0x%x\n", size,result); if(result==0) - { - dbgprintf("returns 0\n"); printf("WARNING: malloc() failed\n"); - } return result; } void CDECL expfree(void* mem) { // return free(mem); - dbgprintf("free(%x)\n", mem); + dbgprintf("free(0x%x)\n", mem); my_release(mem); } void* CDECL expnew(int size) @@ -256,29 +377,27 @@ void* CDECL expnew(int size) // printf("%08x %08x %08x %08x\n", // size, *(1+(int*)&size), // *(2+(int*)&size),*(3+(int*)&size)); - void* result=expmalloc(size); - dbgprintf("new(%x)\n", size); + void* result=my_mreq(size,0); + dbgprintf("new(0x%x) => 0x%x\n", size, result); if(result==0) - { - dbgprintf("returns 0\n"); - printf("WARNING: malloc() failed\n"); - } + printf("WARNING: new() failed\n"); return result; } int CDECL expdelete(void* memory) { - dbgprintf("delete(%x)\n", memory); - expfree(memory); + dbgprintf("delete(0x%x)\n", memory); + my_release(memory); return 0; } int WINAPI expDisableThreadLibraryCalls(int module) { - dbgprintf("DisableThreadLibraryCalls(%x)\n", module); + dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module); return 0; } int CDECL exp_initterm(int v1, int v2) { + dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1, v2); return 0; } @@ -291,19 +410,35 @@ typedef struct { void* WINAPI expGetDriverModuleHandle(DRVR* pdrv) { - dbgprintf("GetDriverModuleHandle(%x)\n", pdrv); - return pdrv->hDriverModule; + void* result; + if (pdrv==NULL) result=NULL; + result=pdrv->hDriverModule; + dbgprintf("GetDriverModuleHandle(0x%x) => 0x%x\n", pdrv, result); + return result; } void* WINAPI expGetModuleHandleA(const char* name) { WINE_MODREF* wm; - dbgprintf("GetModuleHandleA(%s)\n", name); - if(!name)return 0; - wm=MODULE_FindModule(name); - if(wm==0)return 0; - return (void*)(wm->module); + void* result; + if(!name) + result=0; + else + { + wm=MODULE_FindModule(name); + if(wm==0)result=0; + else + result=(void*)(wm->module); + } + if(!result) + { + if(strcasecmp(name, "kernel32")==0) + result=0x120; + } + dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name, result); + return result; } + struct th_list_t; typedef struct th_list_t{ int id; @@ -322,13 +457,11 @@ void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize, void* lpStartAddr pthread_t *pth; // printf("CreateThread:"); pth=my_mreq(sizeof(pthread_t), 0); - dbgprintf("pthread_create\n"); pthread_create(pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter); if(dwFlags) - dbgprintf( "WARNING: CreateThread flags not supported\n"); + printf( "WARNING: CreateThread flags not supported\n"); if(dwThreadId) *dwThreadId=(long)pth; - dbgprintf( "Created thread %08X\n", pth); if(list==NULL) { list=my_mreq(sizeof(th_list), 1); @@ -342,6 +475,8 @@ void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize, void* lpStartAddr list=list->next; } list->thread=pth; + dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n", + pSecAttr, dwStackSize, lpStartAddress, lpParameter, dwFlags, dwThreadId, pth); return pth; } @@ -349,8 +484,13 @@ struct mutex_list_t; struct mutex_list_t { + char type; pthread_mutex_t *pm; + pthread_cond_t *pc; + char state; + char reset; char name[64]; + int semaphore; struct mutex_list_t* next; struct mutex_list_t* prev; }; @@ -359,21 +499,26 @@ static mutex_list* mlist=NULL; void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset, char bInitialState, const char* name) { -#warning ManualReset pthread_mutex_t *pm; - dbgprintf("CreateEvent\n"); + pthread_cond_t *pc; if(mlist!=NULL) { mutex_list* pp=mlist; if(name!=NULL) do { - if(strcmp(pp->name, name)==0) + if((strcmp(pp->name, name)==0) && (pp->type==0)) + { + dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n", + pSecAttr, bManualReset, bInitialState, name, name, pp->pm); return pp->pm; + } }while(pp=pp->prev); } pm=my_mreq(sizeof(pthread_mutex_t), 0); pthread_mutex_init(pm, NULL); + pc=my_mreq(sizeof(pthread_cond_t), 0); + pthread_cond_init(pc, NULL); if(mlist==NULL) { mlist=my_mreq(sizeof(mutex_list), 00); @@ -382,53 +527,158 @@ void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset, else { mlist->next=my_mreq(sizeof(mutex_list), 00); - mlist->next->prev=mlist->next; + mlist->next->prev=mlist; mlist->next->next=NULL; mlist=mlist->next; } + mlist->type=0; /* Type Event */ mlist->pm=pm; + mlist->pc=pc; + mlist->state=bInitialState; + mlist->reset=bManualReset; if(name!=NULL) strncpy(mlist->name, name, 64); else mlist->name[0]=0; if(pm==NULL) dbgprintf("ERROR::: CreateEventA failure\n"); +/* if(bInitialState) pthread_mutex_lock(pm); - return pm; +*/ + if(name) + dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n", + pSecAttr, bManualReset, bInitialState, name, name, mlist); + else + dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n", + pSecAttr, bManualReset, bInitialState, mlist); + return mlist; } void* WINAPI expSetEvent(void* event) { - dbgprintf("Trying to lock %X\n", event); - pthread_mutex_lock(event); + mutex_list *ml = (mutex_list *)event; + dbgprintf("SetEvent(%x) => 0x1\n", event); + pthread_mutex_lock(ml->pm); + if (ml->state == 0) { + ml->state = 1; + pthread_cond_signal(ml->pc); + } + pthread_mutex_unlock(ml->pm); + + return (void *)1; } void* WINAPI expResetEvent(void* event) { - dbgprintf("Unlocking %X\n", event); - pthread_mutex_unlock(event); + mutex_list *ml = (mutex_list *)event; + dbgprintf("ResetEvent(0x%x) => 0x1\n", event); + pthread_mutex_lock(ml->pm); + ml->state = 0; + pthread_mutex_unlock(ml->pm); + + return (void *)1; } void* WINAPI expWaitForSingleObject(void* object, int duration) { -#warning not sure - dbgprintf("WaitForSingleObject: duration %d\n", duration); - pthread_mutex_lock(object); - pthread_mutex_unlock(object); + mutex_list *ml = (mutex_list *)object; + int ret; + mutex_list* pp=mlist; +// dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object, duration); + do { + if (pp == NULL) dbgprintf("WaitForSingleObject: NotFound\n"); + if((pp->pm, mlist->pm)==0) + break;; + }while(pp=pp->prev); + + + pthread_mutex_lock(ml->pm); + + switch(ml->type) { + case 0: /* Event */ + if (duration == 0) { /* Check Only */ + if (ml->state == 1) ret = WAIT_FAILED; + else ret = WAIT_OBJECT_0; + } + if (duration == -1) { /* INFINITE */ + if (ml->state == 0) + pthread_cond_wait(ml->pc,ml->pm); + if (ml->reset) + ml->state = 0; + ret = WAIT_OBJECT_0; + } + if (duration > 0) { /* Timed Wait */ + struct timespec abstime; + struct timeval now; + gettimeofday(&now, 0); + abstime.tv_sec = now.tv_sec + (now.tv_usec+duration)/1000000; + abstime.tv_nsec = ((now.tv_usec+duration)%1000000)*1000; + if (ml->state == 0) + ret=pthread_cond_timedwait(ml->pc,ml->pm,&abstime); + if (ret == ETIMEDOUT) ret = WAIT_TIMEOUT; + else ret = WAIT_OBJECT_0; + if (ml->reset) + ml->state = 0; + } + break; + case 1: /* Semaphore */ + if (duration == 0) { + if(ml->semaphore==0) ret = WAIT_FAILED; + else { + ml->semaphore++; + ret = WAIT_OBJECT_0; + } + } + if (duration == -1) { + if (ml->semaphore==0) + pthread_cond_wait(ml->pc,ml->pm); + ml->semaphore--; + } + break; + } + pthread_mutex_unlock(ml->pm); + + dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object,duration,ml,ret); + return (void *)ret; } static BYTE PF[64] = {0,}; +WIN_BOOL WINAPI expIsProcessorFeaturePresent(DWORD v) +{ + WIN_BOOL result; + if(v>63)result=0; + else result=PF[v]; + dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v, result); + return result; +} + +static void DumpSystemInfo(const SYSTEM_INFO* si) +{ + dbgprintf(" Processor architecture %d\n", si->u.s.wProcessorArchitecture); + dbgprintf(" Page size: %d\n", si->dwPageSize); + dbgprintf(" Minimum app address: %d\n", si->lpMinimumApplicationAddress); + dbgprintf(" Maximum app address: %d\n", si->lpMaximumApplicationAddress); + dbgprintf(" Active processor mask: 0x%x\n", si->dwActiveProcessorMask); + dbgprintf(" Number of processors: %d\n", si->dwNumberOfProcessors); + dbgprintf(" Processor type: 0x%x\n", si->dwProcessorType); + dbgprintf(" Allocation granularity: 0x%x\n", si->dwAllocationGranularity); + dbgprintf(" Processor level: 0x%x\n", si->wProcessorLevel); + dbgprintf(" Processor revision: 0x%x\n", si->wProcessorRevision); +} + void WINAPI expGetSystemInfo(SYSTEM_INFO* si) { /* FIXME: better values for the two entries below... */ static int cache = 0; static SYSTEM_INFO cachedsi; + unsigned int regs[4]; HKEY xhkey=0,hkey; - dbgprintf("GetSystemInfo()\n"); + dbgprintf("GetSystemInfo(0x%d) =>\n"); if (cache) { memcpy(si,&cachedsi,sizeof(*si)); + DumpSystemInfo(si); return; } memset(PF,0,sizeof(PF)); @@ -437,22 +687,22 @@ void WINAPI expGetSystemInfo(SYSTEM_INFO* si) cachedsi.dwPageSize = getpagesize(); /* FIXME: better values for the two entries below... */ - cachedsi.lpMinimumApplicationAddress = (void *)0x40000000; + cachedsi.lpMinimumApplicationAddress = (void *)0x00000000; cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF; cachedsi.dwActiveProcessorMask = 1; cachedsi.dwNumberOfProcessors = 1; cachedsi.dwProcessorType = PROCESSOR_INTEL_386; cachedsi.dwAllocationGranularity = 0x10000; - cachedsi.wProcessorLevel = 3; /* pentium */ - cachedsi.wProcessorRevision = 0; + cachedsi.wProcessorLevel = 5; /* pentium */ + cachedsi.wProcessorRevision = 0x0101; -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE; -#ifdef MMX - PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE; -#endif + do_cpuid(regs); + if (regs[3] & 0x00800000) + PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE; cachedsi.dwNumberOfProcessors=1; #else { @@ -559,8 +809,10 @@ void WINAPI expGetSystemInfo(SYSTEM_INFO* si) if (sscanf(value,"%d",&x)) cachedsi.wProcessorRevision = x; } - if ( (!lstrncmpiA(line,"flags",strlen("flags"))) || - (!lstrncmpiA(line,"features",strlen("features"))) ) { + if + ( (!lstrncmpiA(line,"flags",strlen("flags"))) + || (!lstrncmpiA(line,"features",strlen("features"))) ) + { if (strstr(value,"cx8")) PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE; if (strstr(value,"mmx")) @@ -569,70 +821,89 @@ void WINAPI expGetSystemInfo(SYSTEM_INFO* si) } } fclose (f); +/* + * ad hoc fix for smp machines. + * some problems on WaitForSingleObject,CreateEvent,SetEvent + * CreateThread ...etc.. + * + */ + cachedsi.dwNumberOfProcessors=1; } #endif /* __FreeBSD__ */ memcpy(si,&cachedsi,sizeof(*si)); + DumpSystemInfo(si); } long WINAPI expGetVersion() { - return 0xC0000A04;//Windows 98 + dbgprintf("GetVersion() => 0xC0000004\n"); + return 0xC0000004;//Windows 95 } HANDLE WINAPI expHeapCreate(long flags, long init_size, long max_size) { // printf("HeapCreate:"); - dbgprintf("HeapCreate(%X, %X, %X)\n", flags, init_size, max_size); + HANDLE result; if(init_size==0) - return (HANDLE)my_mreq(0x110000, 0); + result=(HANDLE)my_mreq(0x110000, 0); else - return (HANDLE)my_mreq(init_size, 0); + result=(HANDLE)my_mreq(init_size, 0); + dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags, init_size, max_size, result); + return result; } void* WINAPI expHeapAlloc(HANDLE heap, int flags, int size) { void* z; - dbgprintf("HeapAlloc(%X, %X, %X)\n", heap, flags, size); // printf("HeapAlloc:"); - z=my_mreq(size, flags&8); +/** + Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for + HeapAlloc returns area larger than size argument :-/ +**/ + z=my_mreq(((size+4095)/4096)*4096, flags&8); // z=HeapAlloc(heap,flags,size); if(z==0) printf("HeapAlloc failure\n"); + dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size 0x%x) => 0x%x\n", heap, flags, size, z); return z; } long WINAPI expHeapDestroy(void* heap) { - dbgprintf("HeapDestroy(%X)\n", heap); + dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap); my_release(heap); return 1; } long WINAPI expHeapFree(int arg1, int arg2, void* ptr) { - dbgprintf("HeapFree(%X, %X, %X)\n", arg1, arg2, ptr); + dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", arg1, arg2, ptr); my_release(ptr); return 1; } long WINAPI expHeapSize(int heap, int flags, void* pointer) { - return my_size(pointer); + long result=my_size(pointer); + dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap, flags, pointer, result); + return result; } long WINAPI expGetProcessHeap(void) { + dbgprintf("GetProcessHeap() => 1\n"); return 1; } void* WINAPI expVirtualAlloc(void* v1, long v2, long v3, long v4) { void* z; - dbgprintf("VirtualAlloc(%d %d %d %d) \n",v1,v2,v3,v4); z=VirtualAlloc(v1, v2, v3, v4); if(z==0) printf("VirtualAlloc failure\n"); + dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1,v2,v3,v4, z); return z; } int WINAPI expVirtualFree(void* v1, int v2, int v3) { - dbgprintf("VirtualFree(%X %X %X) \n",v1,v2,v3); - return VirtualFree(v1,v2,v3); + int result=VirtualFree(v1,v2,v3); + dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1,v2,v3, result); + return result; } struct CRITSECT { @@ -643,7 +914,7 @@ struct CRITSECT void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c) { struct CRITSECT cs; - dbgprintf("InitCriticalSection(%X) \n", c); + dbgprintf("InitializeCriticalSection(0x%x)\n", c); /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION)) { printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n", @@ -659,8 +930,8 @@ void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c) } void WINAPI expEnterCriticalSection(CRITICAL_SECTION* c) { - struct CRITSECT* cs=(struct CRITSECT*)c; - dbgprintf("EnterCriticalSection(%X) \n",c); + struct CRITSECT* cs=*(struct CRITSECT**)c; + dbgprintf("EnterCriticalSection(0x%x)\n",c); // cs.id=pthread_self(); if(cs->locked) if(cs->id==pthread_self()) @@ -672,21 +943,30 @@ void WINAPI expEnterCriticalSection(CRITICAL_SECTION* c) } void WINAPI expLeaveCriticalSection(CRITICAL_SECTION* c) { - struct CRITSECT* cs=(struct CRITSECT*)c; - dbgprintf("LeaveCriticalSection(%X) \n",c); + struct CRITSECT* cs=*(struct CRITSECT**)c; +// struct CRITSECT* cs=(struct CRITSECT*)c; + dbgprintf("LeaveCriticalSection(0x%x)\n",c); cs->locked=0; pthread_mutex_unlock(&(cs->mutex)); return; } void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c) { - dbgprintf("DeleteCriticalSection(%X) \n",c); - pthread_mutex_destroy((pthread_mutex_t*)c); + struct CRITSECT* cs=*(struct CRITSECT**)c; +// struct CRITSECT* cs=(struct CRITSECT*)c; + dbgprintf("DeleteCriticalSection(0x%x)\n",c); + pthread_mutex_destroy(&(cs->mutex)); + free(cs); return; } int WINAPI expGetCurrentThreadId() { - dbgprintf("GetCurrentThreadId() \n"); + dbgprintf("GetCurrentThreadId() => %d\n", getpid()); + return getpid(); +} +int WINAPI expGetCurrentProcess() +{ + dbgprintf("GetCurrentProcess() => %d\n", getpid()); return getpid(); } struct tls_s; @@ -702,7 +982,6 @@ tls_t* g_tls=NULL; void* WINAPI expTlsAlloc() { - dbgprintf("TlsAlloc \n"); if(g_tls==NULL) { g_tls=my_mreq(sizeof(tls_t), 0); @@ -715,135 +994,212 @@ void* WINAPI expTlsAlloc() g_tls->next->next=NULL; g_tls=g_tls->next; } - return g_tls; + dbgprintf("TlsAlloc() => 0x%x\n", g_tls); + return g_tls; } int WINAPI expTlsSetValue(tls_t* index, void* value) { - dbgprintf("TlsSetVal(%X %X) \n", index, value ); + int result; if(index==0) - return 0; - index->value=value; - return 1; + result=0; + else + { + index->value=value; + result=1; + } + dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index, value, result ); + return result; } void* WINAPI expTlsGetValue(tls_t* index) { - dbgprintf("TlsGetVal(%X) \n", index ); + void* result; if(index==0) - return 0; - return index->value; + result=0; + else + result=index->value; + dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index, result); + return result; } int WINAPI expTlsFree(tls_t* index) { - dbgprintf("TlsFree(%X) \n", index); + int result; if(index==0) - return 0; - if(index->next) - index->next->prev=index->prev; - if(index->prev) - index->prev->next=index->next; - my_release((void*)index); - return 1; + result=0; + else + { + if(index->next) + index->next->prev=index->prev; + if(index->prev) + index->prev->next=index->next; + my_release((void*)index); + result=1; + } + dbgprintf("TlsFree(index 0x%x) => %d\n", index, result); + return result; } - void* WINAPI expLocalAlloc(int flags, int size) { void* z; - dbgprintf("LocalAlloc(%d, flags %X)\n", size, flags); if(flags&GMEM_ZEROINIT) z=my_mreq(size, 1); else z=my_mreq(size, 0); if(z==0) printf("LocalAlloc() failed\n"); + dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z); return z; } void* WINAPI expLocalLock(void* z) { - dbgprintf("LocalLock\n"); + dbgprintf("LocalLock(0x%x) => 0x%x\n", z, z); return z; } + void* WINAPI expGlobalAlloc(int flags, int size) { void* z; dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size, flags); if(flags&GMEM_ZEROINIT) - z=my_mreq(size, 1); + z=calloc(size, 1); +// z=my_mreq(size, 1); else - z=my_mreq(size, 0); + z=malloc(size); +// z=my_mreq(size, 0); if(z==0) - printf("LocalAlloc() failed\n"); + printf("GlobalAlloc() failed\n"); + dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z); return z; } void* WINAPI expGlobalLock(void* z) { - dbgprintf("GlobalLock\n"); + dbgprintf("GlobalLock(0x%x) => 0x%x\n", z, z); return z; } - int WINAPI expLoadStringA(long instance, long id, void* buf, long size) { - dbgprintf("LoadStringA\n"); - return LoadStringA(instance, id, buf, size); + int result=LoadStringA(instance, id, buf, size); +// if(buf) + dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n", + instance, id, buf, size, result, buf); +// else +// dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n", +// instance, id, buf, size, result); + return result; } -long WINAPI expMultiByteToWideChar(long v1, long v2, char* s1, long siz1, char* s2, int siz2) +long WINAPI expMultiByteToWideChar(long v1, long v2, char* s1, long siz1, short* s2, int siz2) { #warning FIXME - dbgprintf("MB2WCh\n"); - dbgprintf("WARNING: Unsupported call: MBToWCh %s\n", s1); + int i; + int result; if(s2==0) - return 1; - s2[0]=s2[1]=0; - return 1; + result=1; + else + { + if(siz1>siz2/2)siz1=siz2/2; + for(i=1; i<=siz1; i++) + { + *s2=*s1; + if(!*s1)break; + s2++; + s1++; + } + result=i; + } + if(s1) + dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s', + size %d, dest buffer 0x%x, dest size %d) => %d\n", + v1, v2, s1, s1, siz1, s2, siz2, result); + else + dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL, + size %d, dest buffer 0x%x, dest size %d) =>\n", + v1, v2, siz1, s2, siz2, result); + return result; +} +static void wch_print(const short* str) +{ + dbgprintf(" src: "); + while(*str)dbgprintf("%c", *str++); + dbgprintf("\n"); } long WINAPI expWideCharToMultiByte(long v1, long v2, short* s1, long siz1, char* s2, int siz2, char* c3, int* siz3) { int result; - dbgprintf("WCh2MB\n"); + dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, " + "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1, v2, s1, siz1, s2, siz2, c3, siz3); result=WideCharToMultiByte(v1, v2, s1, siz1, s2, siz2, c3, siz3); dbgprintf("=> %d\n", result); + if(s1)wch_print(s1); + if(s2)dbgprintf(" dest: %s\n", s2); return result; } long WINAPI expGetVersionExA(OSVERSIONINFOA* c) { - dbgprintf("GetVersionExA\n"); + dbgprintf("GetVersionExA(0x%x) => 1\n"); + c->dwOSVersionInfoSize=sizeof(*c); c->dwMajorVersion=4; - c->dwMinorVersion=10; - c->dwBuildNumber=0x40a07ce; + c->dwMinorVersion=0; + c->dwBuildNumber=0x4000457; c->dwPlatformId=VER_PLATFORM_WIN32_WINDOWS; - strcpy(c->szCSDVersion, "Win98"); + strcpy(c->szCSDVersion, " B"); + dbgprintf(" Major version: 4\n Minor version: 0\n Build number: 0x4000457\n" + " Platform Id: VER_PLATFORM_WIN32_WINDOWS\n Version string: ' B'\n"); return 1; } -#include <sys/types.h> -#include <sys/ipc.h> -#include <sys/sem.h> HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count, long max_count, char* name) { -#warning FIXME -/* struct sembuf buf[1]; - int sem=semget(IPC_PRIVATE,1,IPC_CREAT); - if(sem==-1) + pthread_mutex_t *pm; + pthread_cond_t *pc; + if(mlist!=NULL) { - printf("semget() failed\n"); - return (HANDLE)-1; + mutex_list* pp=mlist; + if(name!=NULL) + do + { + if((strcmp(pp->name, name)==0) && (pp->type==1)) + { + dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x", + v1, init_count, max_count, name, name, mlist); + return (HANDLE)mlist; + } + }while(pp=pp->prev); } - buf[0].sem_num=0; - printf("%s\n", name); - printf("Init count %d, max count %d\n", init_count, max_count); - buf[0].sem_op=-max_count+init_count; - buf[0].sem_flg=0; - if(semop(sem, &buf, 1)<0) + pm=my_mreq(sizeof(pthread_mutex_t), 0); + pthread_mutex_init(pm, NULL); + pc=my_mreq(sizeof(pthread_cond_t), 0); + pthread_cond_init(pc, NULL); + if(mlist==NULL) { - printf("semop() failed\n"); + mlist=my_mreq(sizeof(mutex_list), 00); + mlist->next=mlist->prev=NULL; } - return sem; -*/ - void* z; - dbgprintf("CreateSemaphoreA\n"); - z=my_mreq(24, 0); - pthread_mutex_init(z, NULL); - return (HANDLE)z; + else + { + mlist->next=my_mreq(sizeof(mutex_list), 00); + mlist->next->prev=mlist; + mlist->next->next=NULL; + mlist=mlist->next; + } + mlist->type=1; /* Type Semaphore */ + mlist->pm=pm; + mlist->pc=pc; + mlist->state=0; + mlist->reset=0; + mlist->semaphore=init_count; + if(name!=NULL) + strncpy(mlist->name, name, 64); + else + mlist->name[0]=0; + if(pm==NULL) + dbgprintf("ERROR::: CreateSemaphoreA failure\n"); + if(name) + dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x", + v1, init_count, max_count, name, name, mlist); + else + dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x", + v1, init_count, max_count, mlist); + return (HANDLE)mlist; } long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count) @@ -852,48 +1208,59 @@ long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count) // is greater than zero and nonsignaled when its count is equal to zero // Each time a waiting thread is released because of the semaphore's signaled // state, the count of the semaphore is decreased by one. - struct sembuf buf[1]; - dbgprintf("ReleaseSemaphore\n"); - dbgprintf("WARNING: Unsupported call: ReleaseSemaphoreA\n"); -/* if(hsem==-1)return 0; - buf[0].sem_num=0; - buf[0].sem_op=-1; - buf[0].sem_flg=0; - if(semop(hsem, &buf, 1)<0) - { - printf("ReleaseSemaphore: semop() failed\n"); - }*/ - - return 1;//zero on error + mutex_list *ml = (mutex_list *)hsem; + + pthread_mutex_lock(ml->pm); + if (prev_count != 0) *prev_count = ml->semaphore; + if (ml->semaphore == 0) pthread_cond_signal(ml->pc); + ml->semaphore += increment; + pthread_mutex_unlock(ml->pm); + dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n", + hsem, increment, prev_count); + return 1; } long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey) { - dbgprintf("RegOpenKeyExA(%d,%s)\n", key, subkey); - return RegOpenKeyExA(key, subkey, reserved, access, newkey); + long result=RegOpenKeyExA(key, subkey, reserved, access, newkey); + dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",< |