#include "externals.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include static unsigned int localcount() { int a; __asm__ __volatile__("rdtsc\n\t" :"=a"(a) : :"edx"); return a; } void dbgprintf(char* fmt, ...) { #ifdef DETAILED_OUT va_list va; FILE* f; va_start(va, fmt); f=fopen("./log", "a"); vfprintf(f, fmt, va); fsync(f); fclose(f); #endif } char export_names[500][30]={ "name1", //"name2", //"name3" }; //#define min(x,y) ((x)<(y)?(x):(y)) static unsigned char* heap=NULL; static int heap_counter=0; void test_heap() { int offset=0; if(heap==0) return; while(offset20000000) { printf("No enough memory\n"); return 0; } *(int*)(heap+heap_counter)=0x433476; heap_counter+=4; *(int*)(heap+heap_counter)=size; heap_counter+=4; printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size, heap_counter-8, heap_counter, heap_counter+size); if(to_zero) memset(heap+heap_counter, 0, size); heap_counter+=size; return heap+heap_counter-size; } int my_release(char* memory) { test_heap(); if(memory==NULL) { printf("ERROR: free(0)\n"); return 0; } if(*(int*)(memory-8)!=0x433476) { printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n"); return 0; } printf("Freed %d bytes of memory\n", *(int*)(memory-4)); // memset(memory-8, *(int*)(memory-4), 0xCC); return 0; } #else void* my_mreq(int size, int to_zero) { if(to_zero) return calloc(size, 1); else return malloc(size); } int my_release(char* memory) { free(memory); return 0; } #endif extern int unk_exp1; char extcode[20000];// place for 200 unresolved exports int pos=0; int WINAPI ext_unknown() { printf("Unknown func called\n"); return 0; } int WINAPI expIsBadWritePtr(void* ptr, unsigned int count) { dbgprintf("IsBadWritePtr(%x, %x)\n", ptr, count); if(count==0) return 0; if(ptr==0) return 1; return 0; } int WINAPI expIsBadReadPtr(void* ptr, unsigned int count) { dbgprintf("IsBadReadPtr(%x, %x)\n", ptr, count); if(count==0) return 0; if(ptr==0) return 1; return 0; } void* CDECL expmalloc(int size) { //printf("malloc"); // return malloc(size); void* result=my_mreq(size,0); dbgprintf("malloc(%x)\n", size); 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); my_release(mem); } void* CDECL expnew(int size) { // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(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); if(result==0) { dbgprintf("returns 0\n"); printf("WARNING: malloc() failed\n"); } return result; } int CDECL expdelete(void* memory) { dbgprintf("delete(%x)\n", memory); expfree(memory); return 0; } int WINAPI expDisableThreadLibraryCalls(int module) { dbgprintf("DisableThreadLibraryCalls(%x)\n", module); return 0; } int CDECL exp_initterm(int v1, int v2) { return 0; } typedef struct { unsigned int uDriverSignature; void* hDriverModule; void* DriverProc; unsigned int dwDriverID; } DRVR; void* WINAPI expGetDriverModuleHandle(DRVR* pdrv) { dbgprintf("GetDriverModuleHandle(%x)\n", pdrv); return pdrv->hDriverModule; } void* WINAPI expGetModuleHandleA(const char* name) { WINE_MODREF* wm; dbgprintf("GetModuleHandleA(%s)\n", name); wm=MODULE_FindModule(name); if(wm==0)return 0; return (void*)(wm->module); } struct th_list_t; typedef struct th_list_t{ int id; void* thread; struct th_list_t* next; struct th_list_t* prev; }th_list; static th_list* list=NULL; void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize, void* lpStartAddress, void* lpParameter, long dwFlags, long* dwThreadId) { pthread_t *pth; // printf("CreateThread:"); pth=my_mreq(sizeof(pthread_t), 0); dbgprintf("pthread_create\n"); pthread_create(pth, NULL, lpStartAddress, lpParameter); if(dwFlags) dbgprintf( "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); list->next=list->prev=NULL; } else { list->next=my_mreq(sizeof(th_list), 0); list->next->prev=list; list->next->next=NULL; list=list->next; } list->thread=pth; return pth; } struct mutex_list_t; struct mutex_list_t { pthread_mutex_t *pm; char name[64]; struct mutex_list_t* next; struct mutex_list_t* prev; }; typedef struct mutex_list_t mutex_list; 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"); if(mlist!=NULL) { mutex_list* pp=mlist; if(name!=NULL) do { if(strcmp(pp->name, name)==0) return pp->pm; }while(pp=pp->prev); } pm=my_mreq(sizeof(pthread_mutex_t), 0); pthread_mutex_init(pm, NULL); if(mlist==NULL) { mlist=my_mreq(sizeof(mutex_list), 00); mlist->next=mlist->prev=NULL; } else { mlist->next=my_mreq(sizeof(mutex_list), 00); mlist->next->prev=mlist->next; mlist->next->next=NULL; mlist=mlist->next; } mlist->pm=pm; 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; } void* WINAPI expSetEvent(void* event) { dbgprintf("Trying to lock %X\n", event); pthread_mutex_lock(event); } void* WINAPI expResetEvent(void* event) { dbgprintf("Unlocking %X\n", event); pthread_mutex_unlock(event); } void* WINAPI expWaitForSingleObject(void* object, int duration) { #warning not sure dbgprintf("WaitForSingleObject: duration %d\n", duration); pthread_mutex_lock(object); pthread_mutex_unlock(object); } static BYTE PF[64] = {0,}; void WINAPI expGetSystemInfo(SYSTEM_INFO* si) { /* FIXME: better values for the two entries below... */ static int cache = 0; static SYSTEM_INFO cachedsi; HKEY xhkey=0,hkey; dbgprintf("GetSystemInfo()\n"); if (cache) { memcpy(si,&cachedsi,sizeof(*si)); return; } memset(PF,0,sizeof(PF)); cachedsi.u.s.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL; cachedsi.dwPageSize = getpagesize(); /* FIXME: better values for the two entries below... */ cachedsi.lpMinimumApplicationAddress = (void *)0x40000000; cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF; cachedsi.dwActiveProcessorMask = 1; cachedsi.dwNumberOfProcessors = 1; cachedsi.dwProcessorType = PROCESSOR_INTEL_386; cachedsi.dwAllocationGranularity = 0x10000; cachedsi.wProcessorLevel = 3; /* 386 */ cachedsi.wProcessorRevision = 0; { char buf[20]; char line[200]; FILE *f = fopen ("/proc/cpuinfo", "r"); if (!f) return; xhkey = 0; while (fgets(line,200,f)!=NULL) { char *s,*value; /* NOTE: the ':' is the only character we can rely on */ if (!(value = strchr(line,':'))) continue; /* terminate the valuename */ *value++ = '\0'; /* skip any leading spaces */ while (*value==' ') value++; if ((s=strchr(value,'\n'))) *s='\0'; /* 2.1 method */ if (!lstrncmpiA(line, "cpu family",strlen("cpu family"))) { if (isdigit (value[0])) { switch (value[0] - '0') { case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386; cachedsi.wProcessorLevel= 3; break; case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486; cachedsi.wProcessorLevel= 4; break; case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; default: break; } } /* set the CPU type of the current processor */ sprintf(buf,"CPU %ld",cachedsi.dwProcessorType); continue; } /* old 2.0 method */ if (!lstrncmpiA(line, "cpu",strlen("cpu"))) { if ( isdigit (value[0]) && value[1] == '8' && value[2] == '6' && value[3] == 0 ) { switch (value[0] - '0') { case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386; cachedsi.wProcessorLevel= 3; break; case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486; cachedsi.wProcessorLevel= 4; break; case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; default: break; } } /* set the CPU type of the current processor */ sprintf(buf,"CPU %ld",cachedsi.dwProcessorType); continue; } if (!lstrncmpiA(line,"fdiv_bug",strlen("fdiv_bug"))) { if (!lstrncmpiA(value,"yes",3)) PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE; continue; } if (!lstrncmpiA(line,"fpu",strlen("fpu"))) { if (!lstrncmpiA(value,"no",2)) PF[PF_FLOATING_POINT_EMULATED] = TRUE; continue; } if (!lstrncmpiA(line,"processor",strlen("processor"))) { /* processor number counts up...*/ int x; if (sscanf(value,"%d",&x)) if (x+1>cachedsi.dwNumberOfProcessors) cachedsi.dwNumberOfProcessors=x+1; /* Create a new processor subkey on a multiprocessor * system */ sprintf(buf,"%d",x); } if (!lstrncmpiA(line,"stepping",strlen("stepping"))) { int x; if (sscanf(value,"%d",&x)) cachedsi.wProcessorRevision = x; } if (!lstrncmpiA(line,"flags",strlen("flags"))) { if (strstr(value,"cx8")) PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE; if (strstr(value,"mmx")) PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE; } } fclose (f); } memcpy(si,&cachedsi,sizeof(*si)); } long WINAPI expGetVersion() { return 0xC0000A04;//Windows 98 } HANDLE WINAPI expHeapCreate(long flags, long init_size, long max_size) { // printf("HeapCreate:"); dbgprintf("HeapCreate(%X, %X, %X)\n", flags, init_size, max_size); if(init_size==0) return (HANDLE)my_mreq(0x110000, 0); else return (HANDLE)my_mreq(init_size, 0); } 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); // z=HeapAlloc(heap,flags,size); if(z==0) printf("HeapAlloc failure\n"); return z; } long WINAPI expHeapDestroy(void* heap) { dbgprintf("HeapDestroy(%X)\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); my_release(ptr); 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"); 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); } struct CRITSECT { pthread_t id; pthread_mutex_t mutex; int locked; }; void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c) { struct CRITSECT cs; dbgprintf("InitCriticalSection(%X) \n", c); /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION)) { printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n", sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION)); return; }*/ /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */ pthread_mutex_init(&cs.mutex, NULL); cs.locked=0; *(void**)c=malloc(sizeof cs); memcpy(*(void**)c, &cs, sizeof cs); return; } void WINAPI expEnterCriticalSection(CRITICAL_SECTION* c) { struct CRITSECT* cs=(struct CRITSECT*)c; dbgprintf("EnterCriticalSection(%X) \n",c); // cs.id=pthread_self(); if(cs->locked) if(cs->id==pthread_self()) return; pthread_mutex_lock(&(cs->mutex)); cs->locked=1; cs->id=pthread_self(); return; } void WINAPI expLeaveCriticalSection(CRITICAL_SECTION* c) { struct CRITSECT* cs=(struct CRITSECT*)c; dbgprintf("LeaveCriticalSection(%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); return; } int WINAPI expGetCurrentThreadId() { dbgprintf("GetCurrentThreadId() \n"); return getpid(); } struct tls_s; typedef struct tls_s { void* value; int used; struct tls_s* prev; struct tls_s* next; }tls_t; tls_t* g_tls=NULL; void* WINAPI expTlsAlloc() { dbgprintf("TlsAlloc \n"); if(g_tls==NULL) { g_tls=my_mreq(sizeof(tls_t), 0); g_tls->next=g_tls->prev=NULL; } else { g_tls->next=my_mreq(sizeof(tls_t), 0); g_tls->next->prev=g_tls; g_tls->next->next=NULL; g_tls=g_tls->next; } return g_tls; } int WINAPI expTlsSetValue(tls_t* index, void* value) { dbgprintf("TlsSetVal(%X %X) \n", index, value ); if(index==0) return 0; index->value=value; return 1; } void* WINAPI expTlsGetValue(tls_t* index) { dbgprintf("TlsGetVal(%X) \n", index ); if(index==0) return 0; return index->value; } int WINAPI expTlsFree(tls_t* index) { dbgprintf("TlsFree(%X) \n", index); 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; } 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"); return z; } void* WINAPI expLocalLock(void* z) { dbgprintf("LocalLock\n"); 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); else z=my_mreq(size, 0); if(z==0) printf("LocalAlloc() failed\n"); return z; } void* WINAPI expGlobalLock(void* z) { dbgprintf("GlobalLock\n"); return z; } int WINAPI expLoadStringA(long instance, long id, void* buf, long size) { dbgprintf("LoadStringA\n"); return LoadStringA(instance, id, buf, size); } long WINAPI expMultiByteToWideChar(long v1, long v2, char* s1, long siz1, char* s2, int siz2) { #warning FIXME dbgprintf("MB2WCh\n"); printf("WARNING: Unsupported call: MBToWCh %s\n", s1); if(s2==0) return 1; s2[0]=s2[1]=0; return 1; } long WINAPI expWideCharToMultiByte(long v1, long v2, short* s1, long siz1, char* s2, int siz2, char* c3, int* siz3) { dbgprintf("WCh2MB\n"); return WideCharToMultiByte(v1, v2, s1, siz1, s2, siz2, c3, siz3); } long WINAPI expGetVersionExA(OSVERSIONINFOA* c) { dbgprintf("GetVersionExA\n"); c->dwMajorVersion=4; c->dwMinorVersion=10; c->dwBuildNumber=0x40a07ce; c->dwPlatformId=VER_PLATFORM_WIN32_WINDOWS; strcpy(c->szCSDVersion, "Win98"); return 1; } #include #include #include 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) { printf("semget() failed\n"); return (HANDLE)-1; } 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) { printf("semop() failed\n"); } return sem; */ void* z; dbgprintf("CreateSemaphoreA\n"); z=my_mreq(24, 0); pthread_mutex_init(z, NULL); return (HANDLE)z; } long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count) { // The state of a semaphore object is signaled when its 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"); printf("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 } 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 WINAPI expRegCloseKey(long key) { dbgprintf("RegCloseKey()\n"); return RegCloseKey(key); } long WINAPI expRegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count) { dbgprintf("RegQueryValueExA()\n"); return RegQueryValueExA(key, value, reserved, type, data, count); } long WINAPI expRegCreateKeyExA(long key, const char* name, long reserved, void* classs, long options, long security, void* sec_attr, int* newkey, int* status) { dbgprintf("RegCreateKeyExA()\n"); return RegCreateKeyExA(key, name, reserved, classs, options, security, sec_attr, newkey, status); } long WINAPI expRegSetValueExA(long key, const char* name, long v1, long v2, void* data, long size) { dbgprintf("RegSetValueExA()\n"); return RegSetValueExA(key, name, v1, v2, data, size); } long WINAPI expRegOpenKeyA ( long hKey, LPCSTR lpSubKey, int* phkResult ){ return RegOpenKeyExA(hKey, lpSubKey, 0, 0, phkResult); } long WINAPI expQueryPerformanceCounter(long long* z) { dbgprintf("QueryPerformanceCounter()\n"); __asm__ __volatile__( "rdtsc\n\t" "movl %%eax, 0(%0)\n\t" "movl %%edx, 4(%0)\n\t" ::"c"(z)); return 1; } static double old_freq() { int i=time(NULL); int x,y; while(i==time(NULL)); x=localcount(); i++; while(i==time(NULL)); y=localcount(); return (double)(y-x)/1000.; } static double CPU_Freq() { FILE *f = fopen ("/proc/cpuinfo", "r"); char line[200]; char model[200]="unknown"; char flags[500]=""; char *s,*value; double freq=-1; if (!f) { printf("Can't open /proc/cpuinfo for reading\n"); return old_freq(); } while (fgets(line,200,f)!=NULL) { /* NOTE: the ':' is the only character we can rely on */ if (!(value = strchr(line,':'))) continue; /* terminate the valuename */ *value++ = '\0'; /* skip any leading spaces */ while (*value==' ') value++; if ((s=strchr(value,'\n'))) *s='\0'; if (!strncasecmp(line, "cpu MHz",strlen("cpu MHz"))) { sscanf(value, "%lf", &freq); freq*=1000; break; } continue; } fclose(f); if(freq<0)return old_freq(); return freq; } long WINAPI expQueryPerformanceFrequency(long long* z) { dbgprintf("QueryPerformanceFrequency()\n"); *z=(long long)CPU_Freq(); return 1; } long WINAPI exptimeGetTime() { struct timeval t; dbgprintf("timeGetTime()\n"); gettimeofday(&t, 0); return 1000*t.tv_sec+t.tv_usec/1000; } void* WINAPI expLocalHandle(void* v) { dbgprintf("LocalHandle\n"); return v; } void* WINAPI expGlobalHandle(void* v) { dbgprintf("GlobalHandle\n"); return v; } int WINAPI expGlobalUnlock(void* v) { dbgprintf("GlobalUnlock\n"); return 1; } // void* WINAPI expGlobalFree(void* v) { dbgprintf("GlobalFree(%X)\n", v); my_release(v); return 0; } int WINAPI expLocalUnlock(void* v) { dbgprintf("LocalUnlock\n"); return 1; } // void* WINAPI expLocalFree(void* v) { dbgprintf("LocalFree(%X)\n", v); my_release(v); return 0; } HRSRC WINAPI expFindResourceA(HMODULE module, char* name, char* type) { dbgprintf("FindResourceA\n"); return FindResourceA(module, name, type); } HGLOBAL WINAPI expLoadResource(HMODULE module, HRSRC res) { dbgprintf("LoadResource\n"); return LoadResource(module, res);; } void* WINAPI expLockResource(long res) { dbgprintf("LockResource\n"); return LockResource(res); } int WINAPI expFreeResource(long res) { dbgprintf("FreeResource\n"); return FreeResource(res); } //bool fun(HANDLE) //!0 on success int WINAPI expCloseHandle(long v1) { dbgprintf("CloseHandle\n"); return 1; } const char* WINAPI expGetCommandLineA() { dbgprintf("GetCommandLine\n"); return "c:\\aviplay.exe"; } LPWSTR WINAPI expGetEnvironmentStringsW() { static short envs[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0}; dbgprintf("GetEnvStringsW\n"); return envs; } int WINAPI expFreeEnvironmentStringsW(short* strings) { dbgprintf("FreeEnvStringsW\n"); return 1; } LPCSTR WINAPI expGetEnvironmentStrings() { dbgprintf("GetEnvStrings\n"); return "\0\0"; } int WINAPI expGetStartupInfoA(STARTUPINFOA *s) { dbgprintf("GetStartupInfoA\n"); return 1; } int WINAPI expGetStdHandle(int z) { dbgprintf("GetStdHandle\n"); printf("WARNING: Unsupported call: GetStdHandle\n"); return 1234; } int WINAPI expGetFileType(int handle) { dbgprintf("GetFileType\n"); printf("WARNING: Unsupported call: GetFileType\n"); return 5678; } int WINAPI expSetHandleCount(int count) { dbgprintf("SetHandleCount\n"); return 1; } int WINAPI expGetACP() { dbgprintf("GetACP\n"); printf("WARNING: Unsupported call: GetACP\n"); return 0; } extern WINE_MODREF *MODULE32_LookupHMODULE(HMODULE m); int WINAPI expGetModuleFileNameA(int module, char* s, int len) { WINE_MODREF *mr; dbgprintf("GetModuleFileNameA\n"); printf("File name of module %X requested\n", module); if(s==0) return 0; if(len<35) return 0; strcpy(s, "c:\\windows\\system\\"); mr=MODULE32_LookupHMODULE(module); if(mr==0)//oops { strcat(s, "aviplay.dll"); return 1; } if(strrchr(mr->filename, '/')==NULL) strcat(s, mr->filename); else strcat(s, strrchr(mr->filename, '/')+1); return 1; } int WINAPI expSetUnhandledExceptionFilter(void* filter) { dbgprintf("SetUnhandledExcFilter\n"); return 1;//unsupported and probably won't ever be supported } int WINAPI expLoadLibraryA(char* name) { char qq[20]="./"; dbgprintf("LoadLibraryA\n"); printf("They want library %s\n", name); strcat(qq, name); return LoadLibraryA(qq); } int WINAPI expFreeLibrary(int module) { dbgprintf("FreeLibrary\n"); return FreeLibrary(module); } void* WINAPI expGetProcAddress(HMODULE mod, char* name) { dbgprintf("GetProcAddress\n"); return GetProcAddress(mod, name); } long WINAPI expCreateFileMappingA(int hFile, void* lpAttr, long flProtect, long dwMaxHigh, long dwMaxLow, const char* name) { dbgprintf("CreateFileMappingA\n"); return CreateFileMappingA(hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name); } long WINAPI expOpenFileMappingA(long hFile, long hz, const char* name) { dbgprintf("OpenFileMappingA\n"); return OpenFileMappingA(hFile, hz, name); } void* WINAPI expMapViewOfFile(HANDLE file, DWORD mode, DWORD offHigh, DWORD offLow, DWORD size) { dbgprintf("MapViewOfFile(%d, %x, %x, %x, %x)\n", file,mode,offHigh,offLow,size); return (char*)file+offLow; } void* WINAPI expUnmapViewOfFile(void* view) { dbgprintf("UnmapViewOfFile()\n"); return 0; } void* WINAPI expSleep(int time) { dbgprintf("Sleep(%d)\n", time); usleep(time); return 0; } // why does IV32 codec want to call this? I don't know ... void* WINAPI expCreateCompatibleDC(int hdc) { dbgprintf("CreateCompatibleDC(%d)\n", hdc); return (void*)129; } int WINAPI expGetDeviceCaps(int hdc, int unk) { dbgprintf("GetDeviceCaps(%d, %d)\n", hdc, unk); return 0; } WIN_BOOL WINAPI expDeleteDC(int hdc) { dbgprintf("DeleteDC(%d)\n", hdc); return 0; } int expwsprintfA(char* string, char* format, ...) { va_list va; va_start(va, format); dbgprintf("wsprintfA\n"); return vsprintf(string, format, va); } int WINAPI expGetPrivateProfileIntA(char* appname, char* keyname, int default_value, char* filename) { int size=4; char* fullname; dbgprintf("GetPrivateProfileIntA(%s, %s, %s)\n", appname, keyname, filename ); if(!(appname && keyname && filename) ) return default_value; fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename)); strcpy(fullname, "Software\\IniFileMapping\\"); strcat(fullname, appname); strcat(fullname, "\\"); strcat(fullname, keyname); strcat(fullname, "\\"); strcat(fullname, filename); RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, &default_value, &size); free(fullname); return default_value; } int WINAPI expDefDriverProc(int _private, int id, int msg, int arg1, int arg2) { printf("Called DefDriverProc(%X)\n", msg); return 0; } int WINAPI expSizeofResource(int v1, int v2) { dbgprintf("SizeofResource()\n"); return SizeofResource(v1, v2); } int WINAPI expGetLastError() { dbgprintf("GetLastError()\n"); return GetLastError(); } void WINAPI expSetLastError(int error) { dbgprintf("SetLastError()\n"); SetLastError(error); } char* expstrrchr(char* string, int value) { return strrchr(string, value); } char* expstrchr(char* string, int value) { return strchr(string, value); } int WINAPI expGetFileVersionInfoSizeA(const char* name, int* lpHandle) { printf("GetFileVersionInfoSizeA(%s,0x%X)\n", name, lpHandle); return 0; } int WINAPI expIsBadStringPtrW(const short* string, int nchars) { if(string==0)return 1; return 0; } extern long WINAPI InterlockedExchangeAdd( long* dest, long incr ) { long ret; __asm__ __volatile__( "lock; xaddl %0,(%1)" : "=r" (ret) : "r" (dest), "0" (incr) : "memory" ); return ret; } extern long WINAPI expInterlockedIncrement( long* dest ) { return InterlockedExchangeAdd( dest, 1 ) + 1; } extern long WINAPI expInterlockedDecrement( long* dest ) { return InterlockedExchangeAdd( dest, -1 ) - 1; } extern void WINAPI expOutputDebugStringA( const char* string ) { fprintf(stderr, "DEBUG: %s\n", string); } struct exports { char name[64]; int id; void* func; }; struct libs { char name[64]; int length; struct exports* exps; }; #define FF(X,Y) \ {#X, Y, exp##X}, struct exports exp_kernel32[]={ FF(IsBadWritePtr, 357) FF(IsBadReadPtr, 354) FF(IsBadStringPtrW, -1) FF(DisableThreadLibraryCalls, -1) FF(CreateThread, -1) FF(CreateEventA, -1) FF(SetEvent, -1) FF(ResetEvent, -1) FF(WaitForSingleObject, -1) FF(GetSystemInfo, -1) FF(GetVersion, 332) FF(HeapCreate, 461) FF(HeapAlloc, -1) FF(HeapDestroy, -1) FF(HeapFree, -1) FF(VirtualAlloc, -1) FF(VirtualFree, -1) FF(InitializeCriticalSection, -1) FF(EnterCriticalSection, -1) FF(LeaveCriticalSection, -1) FF(DeleteCriticalSection, -1) FF(TlsAlloc, -1) FF(TlsFree, -1) FF(TlsGetValue, -1) FF(TlsSetValue, -1) FF(GetCurrentThreadId, -1) FF(LocalAlloc, -1) FF(LocalLock, -1) FF(GlobalAlloc, -1) FF(GlobalLock, -1) FF(MultiByteToWideChar, 427) FF(WideCharToMultiByte, -1) FF(GetVersionExA, -1) FF(CreateSemaphoreA, -1) FF(QueryPerformanceCounter, -1) FF(QueryPerformanceFrequency, -1) FF(LocalHandle, -1) FF(LocalUnlock, -1) FF(LocalFree, -1) FF(GlobalHandle, -1) FF(GlobalUnlock, -1) FF(GlobalFree, -1) FF(LoadResource, -1) FF(ReleaseSemaphore, -1) FF(FindResourceA, -1) FF(LockResource, -1) FF(FreeResource, -1) FF(SizeofResource, -1) FF(CloseHandle, -1) FF(GetCommandLineA, -1) FF(GetEnvironmentStringsW, -1) FF(FreeEnvironmentStringsW, -1) FF(GetEnvironmentStrings, -1) FF(GetStartupInfoA, -1) FF(GetStdHandle, -1) FF(GetFileType, -1) FF(SetHandleCount, -1) FF(GetACP, -1) FF(GetModuleFileNameA, -1) FF(SetUnhandledExceptionFilter, -1) FF(LoadLibraryA, -1) FF(GetProcAddress, -1) FF(FreeLibrary, -1) FF(CreateFileMappingA, -1) FF(OpenFileMappingA, -1) FF(MapViewOfFile, -1) FF(UnmapViewOfFile, -1) FF(Sleep, -1) FF(GetModuleHandleA, -1) FF(GetPrivateProfileIntA, -1) FF(GetLastError, -1) FF(SetLastError, -1) FF(InterlockedIncrement, -1) FF(InterlockedDecrement, -1) FF(OutputDebugStringA, -1) }; struct exports exp_msvcrt[]={ FF(malloc, -1) FF(_initterm, -1) FF(free, -1) {"??3@YAXPAX@Z", -1, expdelete}, {"??2@YAPAXI@Z", -1, expnew}, FF(strrchr, -1) FF(strchr, -1) }; struct exports exp_winmm[]={ FF(GetDriverModuleHandle, -1) FF(timeGetTime, -1) FF(DefDriverProc, -1) }; struct exports exp_user32[]={ FF(LoadStringA, -1) FF(wsprintfA, -1) }; struct exports exp_advapi32[]={ FF(RegOpenKeyA, -1) FF(RegOpenKeyExA, -1) FF(RegCreateKeyExA, -1) FF(RegQueryValueExA, -1) FF(RegSetValueExA, -1) FF(RegCloseKey, -1) }; struct exports exp_gdi32[]={ FF(CreateCompatibleDC, -1) FF(GetDeviceCaps, -1) FF(DeleteDC, -1) }; struct exports exp_version[]={ FF(GetFileVersionInfoSizeA, -1) }; #define LL(X) \ {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X}, struct libs libraries[]={ LL(kernel32) LL(msvcrt) LL(winmm) LL(user32) LL(advapi32) LL(gdi32) LL(version) }; void* LookupExternal(const char* library, int ordinal) { char* answ; int i,j; if(library==0) { printf("ERROR: library=0\n"); return (void*)ext_unknown; } printf("External func %s:%d\n", library, ordinal); // printf("%x %x\n", &unk_exp1, &unk_exp2); for(i=0; i