📄 win32.c
字号:
int result = (count == 0 || ptr != 0) ? 0 : 1; dbgprintf("IsBadWritePtr(%p, 0x%x) => %d\n", ptr, count, result); return result;}static int WINAPI expIsBadReadPtr(void* ptr, unsigned int count){ int result = (count == 0 || ptr != 0) ? 0 : 1; dbgprintf("IsBadReadPtr(%p, 0x%x) => %d\n", ptr, count, result); return result;}static int WINAPI expDisableThreadLibraryCalls(int module){ dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module); return 0;}static HMODULE WINAPI expGetDriverModuleHandle(DRVR* pdrv){ HMODULE result; if (pdrv==NULL) result=0; else result=pdrv->hDriverModule; dbgprintf("GetDriverModuleHandle(%p) => %d\n", pdrv, result); return result;}#define MODULE_HANDLE_kernel32 ((HMODULE)0x120)#define MODULE_HANDLE_user32 ((HMODULE)0x121)#ifdef QTX#define MODULE_HANDLE_wininet ((HMODULE)0x122)#define MODULE_HANDLE_ddraw ((HMODULE)0x123)#define MODULE_HANDLE_advapi32 ((HMODULE)0x124)#endifstatic HMODULE WINAPI expGetModuleHandleA(const char* name){ WINE_MODREF* wm; HMODULE result; if(!name)#ifdef QTX result=1;#else result=0;#endif else { wm=MODULE_FindModule(name); if(wm==0)result=0; else result=(HMODULE)(wm->module); } if(!result) { if(name && (strcasecmp(name, "kernel32")==0 || !strcasecmp(name, "kernel32.dll"))) result=MODULE_HANDLE_kernel32;#ifdef QTX if(name && strcasecmp(name, "user32")==0) result=MODULE_HANDLE_user32;#endif } dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name, result); return result;}static void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize, void* lpStartAddress, void* lpParameter, long dwFlags, long* dwThreadId){ pthread_t *pth; // printf("CreateThread:"); pth = (pthread_t*) my_mreq(sizeof(pthread_t), 0); pthread_create(pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter); if(dwFlags) printf( "WARNING: CreateThread flags not supported\n"); if(dwThreadId) *dwThreadId=(long)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; dbgprintf("CreateThread(%p, %ld, %p, %p, %ld, %p) => %p\n", pSecAttr, dwStackSize, lpStartAddress, lpParameter, dwFlags, dwThreadId, pth); return pth;}struct mutex_list_t;struct mutex_list_t{ char type; pthread_mutex_t *pm; pthread_cond_t *pc; char state; char reset; char name[128]; int semaphore; struct mutex_list_t* next; struct mutex_list_t* prev;};typedef struct mutex_list_t mutex_list;static mutex_list* mlist=NULL;void destroy_event(void* event){ mutex_list* pp=mlist; // printf("garbage collector: destroy_event(%x)\n", event); while(pp) { if(pp==(mutex_list*)event) { if(pp->next) pp->next->prev=pp->prev; if(pp->prev) pp->prev->next=pp->next; if(mlist==(mutex_list*)event) mlist=mlist->prev; /* pp=mlist; while(pp) { printf("%x => ", pp); pp=pp->prev; } printf("0\n"); */ return; } pp=pp->prev; }}static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset, char bInitialState, const char* name){ pthread_mutex_t *pm; pthread_cond_t *pc; /* mutex_list* pp; pp=mlist; while(pp) { printf("%x => ", pp); pp=pp->prev; } printf("0\n"); */ if(mlist!=NULL) { mutex_list* pp=mlist; if(name!=NULL) do { if((strcmp(pp->name, name)==0) && (pp->type==0)) { dbgprintf("CreateEventA(%p, 0x%x, 0x%x, %p='%s') => %p\n", pSecAttr, bManualReset, bInitialState, name, name, pp->pm); return pp->pm; } }while((pp=pp->prev) != NULL); } pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX); pthread_mutex_init(pm, NULL); pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND); pthread_cond_init(pc, NULL); if(mlist==NULL) { mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT); mlist->next=mlist->prev=NULL; } else { mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT); 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) strncpy(mlist->name, name, 127); else mlist->name[0]=0; if(pm==NULL) dbgprintf("ERROR::: CreateEventA failure\n"); /* if(bInitialState) pthread_mutex_lock(pm); */ if(name) dbgprintf("CreateEventA(%p, 0x%x, 0x%x, %p='%s') => %p\n", pSecAttr, bManualReset, bInitialState, name, name, mlist); else dbgprintf("CreateEventA(%p, 0x%x, 0x%x, NULL) => %p\n", pSecAttr, bManualReset, bInitialState, mlist); return mlist;}static void* WINAPI expSetEvent(void* event){ mutex_list *ml = (mutex_list *)event; dbgprintf("SetEvent(%p) => 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;}static void* WINAPI expResetEvent(void* event){ mutex_list *ml = (mutex_list *)event; dbgprintf("ResetEvent(%p) => 0x1\n", event); pthread_mutex_lock(ml->pm); ml->state = 0; pthread_mutex_unlock(ml->pm); return (void *)1;}static void* WINAPI expWaitForSingleObject(void* object, int duration){ mutex_list *ml = (mutex_list *)object; // FIXME FIXME FIXME - this value is sometime unititialize !!! int ret = WAIT_FAILED; mutex_list* pp=mlist; if(object == (void*)0xcfcf9898) { /** From GetCurrentThread() documentation: 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. 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. 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. **/ dbgprintf("WaitForSingleObject(thread_handle) called\n"); return (void*)WAIT_FAILED; } dbgprintf("WaitForSingleObject(%p, duration %d) =>\n", object, duration); // loop below was slightly fixed - its used just for checking if // this object really exists in our list if (!ml) return (void*) ret; while (pp && (pp->pm != ml->pm)) pp = pp->prev; if (!pp) { dbgprintf("WaitForSingleObject: NotFound\n"); return (void*)ret; } 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(%p, %d): %p => 0x%x \n",object,duration,ml,ret); return (void *)ret;}#ifdef QTXstatic void* WINAPI expWaitForMultipleObjects(int count, const void** objects, int WaitAll, int duration){ int i; void *object; void *ret; dbgprintf("WaitForMultipleObjects(%d, %p, %d, duration %d) =>\n", count, objects, WaitAll, duration); for (i = 0; i < count; i++) { object = (void *) objects[i]; ret = expWaitForSingleObject(object, duration); if (WaitAll) dbgprintf("WaitAll flag not yet supported...\n"); else return ret; } return NULL;}static void WINAPI expExitThread(int retcode){ dbgprintf("ExitThread(%d)\n", retcode); pthread_exit(&retcode);}static HANDLE WINAPI expCreateMutexA(void *pSecAttr, char bInitialOwner, const char *name){ HANDLE mlist = (HANDLE)expCreateEventA(pSecAttr, 0, 0, name); if (name) dbgprintf("CreateMutexA(%p, %d, '%s') => 0x%x\n", pSecAttr, bInitialOwner, name, mlist); else dbgprintf("CreateMutexA(%p, %d, NULL) => 0x%x\n", pSecAttr, bInitialOwner, mlist);#ifndef QTX /* 10l to QTX, if CreateMutex returns a real mutex, WaitForSingleObject waits for ever, else it works ;) */ return mlist;#else return 0;#endif}static int WINAPI expReleaseMutex(HANDLE hMutex){ dbgprintf("ReleaseMutex(%x) => 1\n", hMutex); /* FIXME:XXX !! not yet implemented */ return 1;}#endifstatic int pf_set = 0;static BYTE PF[64] = {0,};static void DumpSystemInfo(const SYSTEM_INFO* si){ dbgprintf(" Processor architecture %d\n", si->u.s.wProcessorArchitecture); dbgprintf(" Page size: %ld\n", si->dwPageSize); dbgprintf(" Minimum app address: %p\n", si->lpMinimumApplicationAddress); dbgprintf(" Maximum app address: %p\n", si->lpMaximumApplicationAddress); dbgprintf(" Active processor mask: 0x%lx\n", si->dwActiveProcessorMask); dbgprintf(" Number of processors: %ld\n", si->dwNumberOfProcessors); dbgprintf(" Processor type: 0x%lx\n", si->dwProcessorType); dbgprintf(" Allocation granularity: 0x%lx\n", si->dwAllocationGranularity); dbgprintf(" Processor level: 0x%x\n", si->wProcessorLevel); dbgprintf(" Processor revision: 0x%x\n", si->wProcessorRevision);}static void WINAPI expGetSystemInfo(SYSTEM_INFO* si){ /* FIXME: better values for the two entries below... */ static int cache = 0; static SYSTEM_INFO cachedsi;#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__svr4__) unsigned int regs[4];#endif dbgprintf("GetSystemInfo(%p) =>\n", si); if (cache) { memcpy(si,&cachedsi,sizeof(*si)); DumpSystemInfo(si); return; } memset(PF,0,sizeof(PF)); pf_set = 1; cachedsi.u.s.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL; cachedsi.dwPageSize = getpagesize(); /* FIXME: better values for the two entries below... */ cachedsi.lpMinimumApplicationAddress = (void *)0x00000000; cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF; cachedsi.dwActiveProcessorMask = 1; cachedsi.dwNumberOfProcessors = 1; cachedsi.dwProcessorType = PROCESSOR_INTEL_386; cachedsi.dwAllocationGranularity = 0x10000; cachedsi.wProcessorLevel = 5; /* pentium */ cachedsi.wProcessorRevision = 0x0101;#ifdef MPLAYER /* mplayer's way to detect PF's */ {#include "../cpudetect.h" extern CpuCaps gCpuCaps; if (gCpuCaps.hasMMX) PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE; if (gCpuCaps.hasSSE) PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE; if (gCpuCaps.has3DNow) PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE; switch(gCpuCaps.cpuType) { case CPUTYPE_I686: case CPUTYPE_I586: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel = 5; break; case CPUTYPE_I486: cachedsi.dwProcessorType = PROCESSOR_INTEL_486; cachedsi.wProcessorLevel = 4; break; case CPUTYPE_I386: default: cachedsi.dwProcessorType = PROCESSOR_INTEL_386; cachedsi.wProcessorLevel = 3; break; } cachedsi.wProcessorRevision = gCpuCaps.cpuStepping; cachedsi.dwNumberOfProcessors = 1; /* hardcoded */ }#endif/* disable cpuid based detection (mplayer's cpudetect.c does this - see above) */#ifndef MPLAYER#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__svr4__) do_cpuid(1, regs); switch ((regs[0] >> 8) & 0xf) { // cpu family 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:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; } cachedsi.wProcessorRevision = regs[0] & 0xf; // stepping if (regs[3] & (1 << 8)) PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE; if (regs[3] & (1 << 23)) PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE; if (regs[3] & (1 << 25)) PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE; if (regs[3] & (1 << 31)) PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE; cachedsi.dwNumberOfProcessors=1;#endif#endif /* MPLAYER *//* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking fdiv_bug and fpu emulation flags -- alex/MPlayer */#ifdef __linux__ { char buf[20]; char line[200]; FILE *f = fopen ("/proc/cpuinfo", "r"); if (!f) return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -