| /* |
| * Win32 kernel functions |
| * |
| * Copyright 1995 Martin von Loewis |
| */ |
| |
| #include <stdio.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include <sys/times.h> |
| #include "windows.h" |
| #include "winerror.h" |
| #include "heap.h" |
| #include "thread.h" |
| #include "handle32.h" |
| #include "pe_image.h" |
| #include "file.h" |
| #include "stddebug.h" |
| #include "debug.h" |
| |
| typedef struct { |
| K32OBJ header; |
| DWORD maxcount; |
| DWORD count; |
| DWORD initial; |
| } K32SEMAPHORE; |
| |
| typedef struct { |
| K32OBJ header; |
| THDB *owning_thread; /* we are locked by this thread */ |
| } K32MUTEX; |
| |
| typedef struct { |
| K32OBJ header; |
| } K32EVENT; |
| |
| /*********************************************************************** |
| * CreateMutexA (KERNEL32.52) |
| */ |
| HANDLE32 WINAPI CreateMutex32A(SECURITY_ATTRIBUTES *sa,BOOL32 on,LPCSTR name) |
| { |
| K32MUTEX *mut; |
| HANDLE32 handle; |
| K32OBJ *obj = K32OBJ_FindName( name ); |
| |
| if (obj) { |
| if (obj->type == K32OBJ_MUTEX) { |
| SetLastError( ERROR_ALREADY_EXISTS ); |
| return PROCESS_AllocHandle( obj,0 ); |
| } |
| SetLastError( ERROR_DUP_NAME ); |
| return 0; |
| } |
| mut = (K32MUTEX*)HeapAlloc(GetProcessHeap(),0,sizeof(K32MUTEX)); |
| mut->header.type = K32OBJ_MUTEX; |
| mut->header.refcount = 1; |
| mut->owning_thread = NULL; |
| if (name) |
| K32OBJ_AddName(&(mut->header),name); |
| handle = PROCESS_AllocHandle(&(mut->header),0); |
| if (handle != INVALID_HANDLE_VALUE32) { |
| if (on) |
| mut->owning_thread = (THDB *)GetCurrentThreadId(); |
| return handle; |
| } |
| K32OBJ_DecCount(&(mut->header)); /* also frees name */ |
| HeapFree(GetProcessHeap(),0,mut); |
| return 0; |
| } |
| |
| /*********************************************************************** |
| * CreateMutexW (KERNEL32.53) |
| */ |
| HANDLE32 WINAPI CreateMutex32W(SECURITY_ATTRIBUTES *sa, BOOL32 on, LPCWSTR a) |
| { |
| LPSTR name = a?HEAP_strdupWtoA(GetProcessHeap(),0,a):NULL; |
| HANDLE32 ret; |
| |
| ret = CreateMutex32A(sa,on,name); |
| if (name) HeapFree(GetProcessHeap(),0,name); |
| return ret; |
| } |
| |
| /*********************************************************************** |
| * CreateSemaphoreA (KERNEL32.60) |
| */ |
| HANDLE32 WINAPI CreateSemaphore32A( LPSECURITY_ATTRIBUTES sa, |
| LONG initial,LONG max,LPCSTR name ) |
| { |
| K32SEMAPHORE *sem; |
| HANDLE32 handle; |
| K32OBJ *obj = K32OBJ_FindName( name ); |
| |
| if (obj) { |
| if (obj->type == K32OBJ_SEMAPHORE) { |
| SetLastError( ERROR_ALREADY_EXISTS ); |
| return PROCESS_AllocHandle( obj,0 ); |
| } |
| SetLastError( ERROR_DUP_NAME ); |
| return 0; |
| } |
| sem = (K32SEMAPHORE*)HeapAlloc(GetProcessHeap(),0,sizeof(K32SEMAPHORE)); |
| sem->header.type = K32OBJ_SEMAPHORE; |
| sem->header.refcount = 1; |
| |
| sem->maxcount = max; |
| sem->count = initial; |
| sem->initial = initial; |
| if (name) |
| K32OBJ_AddName(&(sem->header),name); |
| handle = PROCESS_AllocHandle(&(sem->header),0); |
| if (handle != INVALID_HANDLE_VALUE32) |
| return handle; |
| K32OBJ_DecCount(&(sem->header)); /* also frees name */ |
| HeapFree(GetProcessHeap(),0,sem); |
| return 0; |
| } |
| |
| /*********************************************************************** |
| * CreateSemaphoreW (KERNEL32.61) |
| */ |
| HANDLE32 WINAPI CreateSemaphore32W(SECURITY_ATTRIBUTES *sa,LONG initial,LONG max,LPCWSTR a) |
| { |
| LPSTR name =a?HEAP_strdupWtoA(GetProcessHeap(),0,a):NULL; |
| HANDLE32 ret; |
| |
| ret = CreateSemaphore32A(sa,initial,max,name); |
| if (a) HeapFree(GetProcessHeap(),0,name); |
| return ret; |
| } |
| |
| |
| /*********************************************************************** |
| * OpenSemaphoreA (KERNEL32.403) |
| */ |
| HANDLE32 WINAPI OpenSemaphore32A(DWORD desired,BOOL32 inherit,LPCSTR name) |
| { |
| K32OBJ *obj = K32OBJ_FindName( name ); |
| |
| if (obj) { |
| if (obj->type == K32OBJ_SEMAPHORE) |
| return PROCESS_AllocHandle( obj,0 ); |
| SetLastError( ERROR_DUP_NAME ); |
| return 0; |
| } |
| return 0; |
| } |
| |
| /*********************************************************************** |
| * OpenSemaphoreA (KERNEL32.404) |
| */ |
| HANDLE32 WINAPI OpenSemaphore32W(DWORD desired,BOOL32 inherit,LPCWSTR name) |
| { |
| LPSTR nameA = name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL; |
| HANDLE32 ret = OpenSemaphore32A(desired,inherit,nameA); |
| |
| if (name) HeapFree(GetProcessHeap(),0,nameA); |
| return ret; |
| } |
| |
| /*********************************************************************** |
| * ReleaseSemaphore (KERNEL32.403) |
| */ |
| BOOL32 WINAPI ReleaseSemaphore(HANDLE32 hSemaphore,LONG lReleaseCount,LPLONG lpPreviousCount) |
| { |
| K32SEMAPHORE *sem; |
| |
| sem = (K32SEMAPHORE*)PROCESS_GetObjPtr(hSemaphore,K32OBJ_SEMAPHORE); |
| if (!sem) |
| return FALSE; |
| if (lpPreviousCount) *lpPreviousCount = sem->count; |
| sem->count += lReleaseCount; |
| if (sem->count>sem->maxcount) { |
| fprintf(stderr,"ReleaseSemaphore(%d,%ld,.), released more then possible??\n",hSemaphore,lReleaseCount); |
| sem->count = sem->maxcount; |
| } |
| |
| /* FIXME: wake up all threads blocked on that semaphore */ |
| |
| K32OBJ_DecCount(&(sem->header)); |
| return TRUE; |
| } |
| |
| /*********************************************************************** |
| * OpenMutexA (KERNEL32.399) |
| */ |
| HANDLE32 WINAPI OpenMutex32A(DWORD desiredaccess, BOOL32 inherithandle, LPCSTR name) |
| { |
| K32OBJ *obj = K32OBJ_FindName( name ); |
| |
| if (obj) { |
| if (obj->type == K32OBJ_MUTEX) |
| return PROCESS_AllocHandle( obj,0 ); |
| SetLastError( ERROR_DUP_NAME ); |
| return 0; |
| } |
| return 0; |
| } |
| |
| /*********************************************************************** |
| * OpenMutexW (KERNEL32.400) |
| */ |
| HANDLE32 WINAPI OpenMutex32W(DWORD desiredaccess, BOOL32 inherithandle, |
| LPCWSTR name) |
| { |
| LPSTR nameA=name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL; |
| HANDLE32 ret = OpenMutex32A(desiredaccess,inherithandle,nameA); |
| |
| if (name) HeapFree(GetProcessHeap(),0,nameA); |
| return ret; |
| } |
| |
| /*********************************************************************** |
| * ReleaseMutex (KERNEL32.435) |
| */ |
| BOOL32 WINAPI ReleaseMutex (HANDLE32 h) |
| { |
| K32MUTEX *mut = (K32MUTEX*)PROCESS_GetObjPtr(h,K32OBJ_MUTEX); |
| |
| if (!mut) |
| return 0; |
| if (mut->owning_thread != (THDB *)GetCurrentThreadId()) { |
| /* set error ... */ |
| K32OBJ_DecCount(&(mut->header)); |
| return 0; |
| } |
| mut->owning_thread = NULL; |
| |
| /* FIXME: wake up all threads blocked on this mutex */ |
| |
| K32OBJ_DecCount(&(mut->header)); |
| return TRUE; |
| } |
| |
| /*********************************************************************** |
| * CreateEventA (KERNEL32.43) |
| */ |
| HANDLE32 WINAPI CreateEvent32A(SECURITY_ATTRIBUTES *sa,BOOL32 au,BOOL32 on, |
| LPCSTR name) |
| { |
| K32EVENT *evt; |
| HANDLE32 handle; |
| K32OBJ *obj = K32OBJ_FindName( name ); |
| |
| if (obj) { |
| if (obj->type == K32OBJ_EVENT) { |
| SetLastError( ERROR_ALREADY_EXISTS ); |
| return PROCESS_AllocHandle( obj,0 ); |
| } |
| SetLastError( ERROR_DUP_NAME ); |
| return 0; |
| } |
| evt = (K32EVENT*)HeapAlloc(GetProcessHeap(),0,sizeof(K32EVENT)); |
| evt->header.type = K32OBJ_EVENT; |
| evt->header.refcount = 1; |
| if (name) |
| K32OBJ_AddName(&(evt->header),name); |
| handle = PROCESS_AllocHandle(&(evt->header),0); |
| if (handle != INVALID_HANDLE_VALUE32) |
| return handle; |
| K32OBJ_DecCount(&(evt->header)); /* also frees name */ |
| HeapFree(GetProcessHeap(),0,evt); |
| return 0; |
| } |
| |
| /*********************************************************************** |
| * CreateEventW (KERNEL32.43) |
| */ |
| HANDLE32 WINAPI CreateEvent32W(SECURITY_ATTRIBUTES *sa, BOOL32 au, |
| BOOL32 on,LPCWSTR name) |
| { |
| LPSTR nameA=name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL; |
| HANDLE32 ret = CreateEvent32A(sa,au,on,nameA); |
| |
| if (name) HeapFree(GetProcessHeap(),0,nameA); |
| return ret; |
| } |
| |
| /*********************************************************************** |
| * OpenEventA (KERNEL32.394) |
| */ |
| HANDLE32 WINAPI OpenEvent32A(DWORD desiredaccess,BOOL32 inherithandle,LPCSTR name) |
| { |
| K32OBJ *obj = K32OBJ_FindName( name ); |
| |
| if (obj) { |
| if (obj->type == K32OBJ_EVENT) |
| return PROCESS_AllocHandle( obj,0 ); |
| SetLastError( ERROR_DUP_NAME ); |
| return 0; |
| } |
| return 0; |
| } |
| |
| /*********************************************************************** |
| * OpenEventW (KERNEL32.395) |
| */ |
| HANDLE32 WINAPI OpenEvent32W(DWORD desiredaccess,BOOL32 inherithandle,LPCWSTR name) |
| { |
| LPSTR nameA = name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL; |
| HANDLE32 ret = OpenEvent32A(desiredaccess,inherithandle,nameA); |
| |
| if (name) HeapFree(GetProcessHeap(),0,nameA); |
| return ret; |
| } |
| |
| /*********************************************************************** |
| * SetEvent (KERNEL32.487) |
| */ |
| BOOL32 WINAPI SetEvent (HANDLE32 h) |
| { |
| fprintf(stderr,"SetEvent(%d) stub\n",h); |
| return 0; |
| } |
| /*********************************************************************** |
| * ResetEvent (KERNEL32.439) |
| */ |
| BOOL32 WINAPI ResetEvent (HANDLE32 h) |
| { |
| fprintf(stderr,"ResetEvent(%d) stub\n",h); |
| return 0; |
| } |
| |
| /*********************************************************************** |
| * WaitForSingleObject (KERNEL32.561) |
| */ |
| DWORD WINAPI WaitForSingleObject(HANDLE32 h, DWORD timeout) |
| { |
| fprintf(stderr,"WaitForSingleObject(%d,%ld) stub\n",h,timeout); |
| return 0; |
| } |
| |
| /*********************************************************************** |
| * WaitForSingleObjectEx (KERNEL32) |
| */ |
| DWORD WINAPI WaitForSingleObjectEx(HANDLE32 h,DWORD timeout,BOOL32 bAlertable) |
| { |
| fprintf(stderr,"WaitForSingleObjectEx(%d,%ld,%d) stub\n",h,timeout,bAlertable); |
| return 0; |
| } |
| |
| |
| /*********************************************************************** |
| * WaitForMultipleObjects (USER32.399) |
| */ |
| DWORD WINAPI MsgWaitForMultipleObjects( |
| DWORD nCount,HANDLE32 *pHandles,BOOL32 fWaitAll,DWORD dwMilliseconds, |
| DWORD dwWakeMask |
| ) { |
| int i; |
| fprintf(stderr,"MsgWaitForMultipleObjects(%ld,[",nCount); |
| for (i=0;i<nCount;i++) |
| fprintf(stderr,"%ld,",(DWORD)pHandles[i]); |
| fprintf(stderr,"],%d,%ld,0x%08lx)\n",fWaitAll,dwMilliseconds,dwWakeMask); |
| return 0; |
| } |
| /*********************************************************************** |
| * DuplicateHandle (KERNEL32.78) |
| */ |
| BOOL32 WINAPI DuplicateHandle(HANDLE32 a, HANDLE32 b, HANDLE32 c, HANDLE32 * d, DWORD e, BOOL32 f, DWORD g) |
| { |
| fprintf(stderr,"DuplicateHandle(%d,%d,%d,%p,%ld,%d,%ld) stub\n",a,b,c,d,e,f,g); |
| *d = b; |
| return TRUE; |
| } |
| |
| HINSTANCE32 WINAPI LoadLibraryEx32A(LPCSTR libname,HFILE32 hfile,DWORD flags) |
| { |
| fprintf(stderr,"LoadLibraryEx32A(%s,%d,0x%08lx)\n",libname,hfile,flags); |
| return LoadLibrary32A(libname); |
| } |
| |
| /*********************************************************************** |
| * LoadLibraryA (KERNEL32.365) |
| * copied from LoadLibrary |
| * This does not currently support built-in libraries |
| */ |
| HINSTANCE32 WINAPI LoadLibrary32A(LPCSTR libname) |
| { |
| HINSTANCE32 handle; |
| dprintf_module( stddeb, "LoadLibrary: (%08x) %s\n", (int)libname, libname); |
| handle = LoadModule16( libname, (LPVOID)-1 ); |
| if (handle == (HINSTANCE32) -1) |
| { |
| char buffer[256]; |
| strcpy( buffer, libname ); |
| strcat( buffer, ".dll" ); |
| handle = LoadModule16( buffer, (LPVOID)-1 ); |
| } |
| /* Obtain module handle and call initialization function */ |
| #ifndef WINELIB |
| if (handle >= (HINSTANCE32)32) PE_InitializeDLLs( GetExePtr(handle), DLL_PROCESS_ATTACH, NULL); |
| #endif |
| return handle; |
| } |
| |
| /*********************************************************************** |
| * LoadLibrary32W (KERNEL32.368) |
| */ |
| HINSTANCE32 WINAPI LoadLibrary32W(LPCWSTR libnameW) |
| { |
| LPSTR libnameA = HEAP_strdupWtoA( GetProcessHeap(), 0, libnameW ); |
| HINSTANCE32 ret = LoadLibrary32A( libnameA ); |
| HeapFree( GetProcessHeap(), 0, libnameA ); |
| return ret; |
| } |
| |
| /*********************************************************************** |
| * FreeLibrary |
| */ |
| BOOL32 WINAPI FreeLibrary32(HINSTANCE32 hLibModule) |
| { |
| fprintf(stderr,"FreeLibrary: empty stub\n"); |
| return TRUE; |
| } |
| |
| /********************************************************************** |
| * GetProcessAffinityMask |
| */ |
| BOOL32 WINAPI GetProcessAffinityMask(HANDLE32 hProcess, |
| LPDWORD lpProcessAffinityMask, |
| LPDWORD lpSystemAffinityMask) |
| { |
| dprintf_task(stddeb,"GetProcessAffinityMask(%x,%lx,%lx)\n", |
| hProcess,(lpProcessAffinityMask?*lpProcessAffinityMask:0), |
| (lpSystemAffinityMask?*lpSystemAffinityMask:0)); |
| /* It is definitely important for a process to know on what processor |
| it is running :-) */ |
| if(lpProcessAffinityMask) |
| *lpProcessAffinityMask=1; |
| if(lpSystemAffinityMask) |
| *lpSystemAffinityMask=1; |
| return TRUE; |
| } |
| |
| /********************************************************************** |
| * SetThreadAffinityMask |
| * Works now like the Windows95 (no MP support) version |
| */ |
| BOOL32 WINAPI SetThreadAffinityMask(HANDLE32 hThread, DWORD dwThreadAffinityMask) |
| { |
| THDB *thdb = (THDB*)PROCESS_GetObjPtr(hThread,K32OBJ_THREAD); |
| |
| if (!thdb) |
| return FALSE; |
| if (dwThreadAffinityMask!=1) { |
| fprintf(stderr,"SetThreadAffinityMask(%d,%ld), only 1 processor supported.\n",(int)hThread,dwThreadAffinityMask); |
| K32OBJ_DecCount((K32OBJ*)thdb); |
| return FALSE; |
| } |
| K32OBJ_DecCount((K32OBJ*)thdb); |
| return TRUE; |
| } |
| |
| BOOL32 WINAPI CreateProcess32A( |
| LPCSTR appname,LPSTR cmdline,LPSECURITY_ATTRIBUTES processattributes, |
| LPSECURITY_ATTRIBUTES threadattributes,BOOL32 inherithandles, |
| DWORD creationflags,LPVOID env,LPCSTR curdir, |
| LPSTARTUPINFO32A startupinfo,LPPROCESS_INFORMATION processinfo |
| ) { |
| fprintf(stderr,"CreateProcess(%s,%s,%p,%p,%d,%08lx,%p,%s,%p,%p)\n", |
| appname,cmdline,processattributes,threadattributes, |
| inherithandles,creationflags,env,curdir,startupinfo,processinfo |
| ); |
| return TRUE; |
| } |
| |
| BOOL32 WINAPI ContinueDebugEvent(DWORD pid,DWORD tid,DWORD contstatus) { |
| fprintf(stderr,"ContinueDebugEvent(%ld,%ld,%ld), stub\n",pid,tid,contstatus); |
| return TRUE; |
| } |
| |
| /********************************************************************* |
| * GetProcessTimes [KERNEL32.262] |
| * |
| * FIXME: implement this better ... |
| */ |
| BOOL32 WINAPI GetProcessTimes( |
| HANDLE32 hprocess,LPFILETIME lpCreationTime,LPFILETIME lpExitTime, |
| LPFILETIME lpKernelTime, LPFILETIME lpUserTime |
| ) { |
| struct tms tms; |
| |
| times(&tms); |
| DOSFS_UnixTimeToFileTime(tms.tms_utime,lpUserTime,0); |
| DOSFS_UnixTimeToFileTime(tms.tms_stime,lpKernelTime,0); |
| return TRUE; |
| } |
| |