summaryrefslogtreecommitdiffstats
path: root/loader/win32.c
diff options
context:
space:
mode:
authorarpi_esp <arpi_esp@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-03-18 01:01:03 +0000
committerarpi_esp <arpi_esp@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-03-18 01:01:03 +0000
commitd71e31d0f702ebf8f872694f6e0f5d579c8378d3 (patch)
treeb8a816661c678a08769b45d34b394b1b5d04f134 /loader/win32.c
parent52d76c5f328bdb0268d266b21f91aac571b443f6 (diff)
downloadmpv-d71e31d0f702ebf8f872694f6e0f5d579c8378d3.tar.bz2
mpv-d71e31d0f702ebf8f872694f6e0f5d579c8378d3.tar.xz
DLL loader updated from avifile-0.60beta4
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@129 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'loader/win32.c')
-rw-r--r--loader/win32.c1578
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" (&regs));
+}
+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);