290 lines
6.6 KiB
C
290 lines
6.6 KiB
C
/*
|
|
*
|
|
* api.c
|
|
*
|
|
* Implementation of the Win32 APIs needed for winsock, on top of ntoskrnl
|
|
*
|
|
*/
|
|
|
|
#include "dmp.h"
|
|
|
|
void SetLastError(DWORD dwErrCode)
|
|
{
|
|
DmGetCurrentDmtd()->LastError = dwErrCode;
|
|
}
|
|
|
|
DWORD GetLastError(void)
|
|
{
|
|
return DmGetCurrentDmtd()->LastError;
|
|
}
|
|
|
|
#if 0
|
|
void DebugBreak(void)
|
|
{
|
|
DbgBreakPoint();
|
|
}
|
|
#endif
|
|
|
|
HLOCAL LocalAlloc(UINT uFlags, SIZE_T cb)
|
|
{
|
|
PVOID pv;
|
|
|
|
if(uFlags & (LMEM_MOVEABLE | LMEM_DISCARDABLE))
|
|
pv = NULL;
|
|
else {
|
|
pv = ExAllocatePool(PagedPool, cb + 8);
|
|
if(pv) {
|
|
*((DWORD *)pv)++ = 'kmem';
|
|
*((DWORD *)pv)++ = 'dbgr';
|
|
if(uFlags & LMEM_ZEROINIT)
|
|
RtlZeroMemory(pv, cb);
|
|
}
|
|
}
|
|
return (HLOCAL)pv;
|
|
}
|
|
|
|
HLOCAL LocalFree(HLOCAL h)
|
|
{
|
|
HLOCAL hRet = h;
|
|
DWORD *pdw = (DWORD *)h;
|
|
try {
|
|
if(h && pdw[-1] == 'dbgr' && pdw[-2] == 'kmem') {
|
|
ExFreePool(pdw - 2);
|
|
hRet = NULL;
|
|
}
|
|
} except (EXCEPTION_EXECUTE_HANDLER) {
|
|
}
|
|
return hRet;
|
|
}
|
|
|
|
void Sleep(DWORD dw)
|
|
{
|
|
SleepEx(dw, FALSE);
|
|
}
|
|
|
|
DWORD SleepEx(DWORD dw, BOOL f)
|
|
{
|
|
LARGE_INTEGER li;
|
|
NTSTATUS st;
|
|
|
|
if(dw == -1)
|
|
{
|
|
li.LowPart = 0;
|
|
li.HighPart = 0x80000000;
|
|
}
|
|
else
|
|
{
|
|
li.QuadPart = UInt32x32To64(dw, 10000);
|
|
li.QuadPart *= -1;
|
|
}
|
|
do
|
|
st = KeDelayExecutionThread(UserMode, (BOOLEAN)f, &li);
|
|
while(f && STATUS_ALERTED == st);
|
|
return st == STATUS_USER_APC ? WAIT_IO_COMPLETION : 0;
|
|
}
|
|
|
|
HANDLE CreateEventW(LPSECURITY_ATTRIBUTES psa, BOOL fManualReset,
|
|
BOOL fInitState, LPCWSTR lpwzName)
|
|
{
|
|
NTSTATUS st;
|
|
HANDLE h;
|
|
OBJECT_ATTRIBUTES oa;
|
|
|
|
ASSERT(NULL == lpwzName);
|
|
|
|
InitializeObjectAttributes(&oa, NULL, 0, NULL, NULL);
|
|
st = NtCreateEvent(&h, EVENT_ALL_ACCESS, &oa, fManualReset ?
|
|
NotificationEvent : SynchronizationEvent, (BOOLEAN)fInitState);
|
|
if(NT_SUCCESS(st))
|
|
SetLastError(0);
|
|
else
|
|
{
|
|
SetLastError(RtlNtStatusToDosError(st));
|
|
h = NULL;
|
|
}
|
|
return h;
|
|
}
|
|
|
|
#if 0
|
|
ULONG _DmUnhandledException(PEXCEPTION_POINTERS pep)
|
|
{
|
|
KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
|
|
(ULONG_PTR)pep->ExceptionRecord->ExceptionAddress, 0, 0, 0);
|
|
return EXCEPTION_EXECUTE_HANDLER;
|
|
}
|
|
|
|
void _DmThreadStartup(PKSTART_ROUTINE StartRoutine, PVOID StartContext)
|
|
{
|
|
DWORD dwExit;
|
|
|
|
KeLowerIrql(0);
|
|
if(FAllocDmThread()) {
|
|
try {
|
|
dwExit = (*(LPTHREAD_START_ROUTINE)StartRoutine)(StartContext);
|
|
} except(_DmUnhandledException(GetExceptionInformation())) {
|
|
KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
|
|
}
|
|
} else
|
|
dwExit = 0;
|
|
|
|
PsTerminateSystemThread(dwExit);
|
|
}
|
|
|
|
HANDLE CreateThread(LPSECURITY_ATTRIBUTES psa, DWORD dwStack,
|
|
LPTHREAD_START_ROUTINE lpfn, LPVOID lpv, DWORD dwFlags, LPDWORD lpdwId)
|
|
{
|
|
NTSTATUS st;
|
|
HANDLE h;
|
|
|
|
st = PsCreateSystemThreadEx(&h, 0, dwStack, lpdwId, (PKSTART_ROUTINE)lpfn,
|
|
lpv, (BOOLEAN)(dwFlags & CREATE_SUSPENDED ? TRUE : FALSE), NULL);
|
|
|
|
if(!NT_SUCCESS(st))
|
|
{
|
|
SetLastError(RtlNtStatusToDosError(st));
|
|
return NULL;
|
|
}
|
|
|
|
if(lpdwId)
|
|
*lpdwId = HandleToUlong(clid.UniqueThread);
|
|
|
|
return h;
|
|
}
|
|
#endif
|
|
|
|
BOOL CloseHandle(HANDLE h)
|
|
{
|
|
NTSTATUS st = NtClose(h);
|
|
if(NT_SUCCESS(st))
|
|
return TRUE;
|
|
SetLastError(RtlNtStatusToDosError(st));
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL SetEvent(HANDLE h)
|
|
{
|
|
NTSTATUS st = NtSetEvent(h, NULL);
|
|
if(NT_SUCCESS(st))
|
|
return TRUE;
|
|
SetLastError(RtlNtStatusToDosError(st));
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL ResetEvent(HANDLE h)
|
|
{
|
|
NTSTATUS st = NtClearEvent(h);
|
|
if(NT_SUCCESS(st))
|
|
return TRUE;
|
|
SetLastError(RtlNtStatusToDosError(st));
|
|
return FALSE;
|
|
}
|
|
|
|
DWORD WaitForMultipleObjectsEx(DWORD nCount, const HANDLE *lph, BOOL fWaitAll,
|
|
DWORD dwTimeOut, BOOL fAlertable)
|
|
{
|
|
NTSTATUS st;
|
|
LARGE_INTEGER li;
|
|
PLARGE_INTEGER pli;
|
|
HANDLE rgh[MAXIMUM_WAIT_OBJECTS];
|
|
|
|
if(nCount > MAXIMUM_WAIT_OBJECTS)
|
|
{
|
|
SetLastError(RtlNtStatusToDosError(STATUS_INVALID_PARAMETER));
|
|
return (DWORD)-1;
|
|
}
|
|
|
|
RtlCopyMemory(rgh, lph, nCount * sizeof(HANDLE));
|
|
if(dwTimeOut == -1)
|
|
pli = NULL;
|
|
else
|
|
{
|
|
pli = &li;
|
|
li.QuadPart = UInt32x32To64(dwTimeOut, 10000);
|
|
li.QuadPart *= -1;
|
|
}
|
|
do
|
|
st = NtWaitForMultipleObjectsEx((CHAR)nCount, rgh,
|
|
fWaitAll ? WaitAll : WaitAny, UserMode, (BOOLEAN)fAlertable, pli);
|
|
while(st == STATUS_ALERTED && fAlertable);
|
|
if(!NT_SUCCESS(st)) {
|
|
SetLastError(RtlNtStatusToDosError(st));
|
|
st = (DWORD)-1;
|
|
}
|
|
return st;
|
|
}
|
|
|
|
DWORD WaitForSingleObject(HANDLE h, DWORD dwTimeOut)
|
|
{
|
|
NTSTATUS st;
|
|
LARGE_INTEGER li;
|
|
PLARGE_INTEGER pli;
|
|
|
|
if(dwTimeOut == -1)
|
|
pli = NULL;
|
|
else
|
|
{
|
|
pli = &li;
|
|
li.QuadPart = UInt32x32To64(dwTimeOut, 10000);
|
|
li.QuadPart *= -1;
|
|
}
|
|
st = NtWaitForSingleObjectEx(h, UserMode, FALSE, pli);
|
|
if(!NT_SUCCESS(st)) {
|
|
SetLastError(RtlNtStatusToDosError(st));
|
|
st = (DWORD)-1;
|
|
}
|
|
return st;
|
|
}
|
|
|
|
#if 0
|
|
BOOL SetWaitableTimer(HANDLE hTimer, const LARGE_INTEGER *pliDue, LONG lPer,
|
|
PTIMERAPCROUTINE pfn, LPVOID lpArg, BOOL fResume)
|
|
{
|
|
NTSTATUS st;
|
|
|
|
st = NtSetTimer(hTimer, (PLARGE_INTEGER)pliDue, (PTIMER_APC_ROUTINE)pfn,
|
|
lpArg, (BOOLEAN)fResume, lPer, NULL);
|
|
|
|
if(!NT_SUCCESS(st))
|
|
{
|
|
SetLastError(RtlNtStatusToDosError(st));
|
|
return FALSE;
|
|
}
|
|
if(st == STATUS_TIMER_RESUME_IGNORED)
|
|
SetLastError(ERROR_NOT_SUPPORTED);
|
|
else
|
|
SetLastError(0);
|
|
return TRUE;
|
|
}
|
|
|
|
HANDLE CreateWaitableTimerW(LPSECURITY_ATTRIBUTES psa, BOOL fManualReset,
|
|
LPCWSTR lpwzName)
|
|
{
|
|
NTSTATUS st;
|
|
HANDLE h;
|
|
OBJECT_ATTRIBUTES oa;
|
|
|
|
ASSERT(NULL == lpwzName);
|
|
|
|
InitializeObjectAttributes(&oa, NULL, 0, NULL, NULL);
|
|
st = NtCreateTimer(&h, TIMER_ALL_ACCESS, &oa, fManualReset ?
|
|
NotificationTimer : SynchronizationTimer);
|
|
if(NT_SUCCESS(st))
|
|
SetLastError(0);
|
|
else
|
|
{
|
|
SetLastError(RtlNtStatusToDosError(st));
|
|
h = NULL;
|
|
}
|
|
return h;
|
|
}
|
|
|
|
BOOL CancelWaitableTimer(HANDLE h)
|
|
{
|
|
NTSTATUS st = NtCancelTimer(h, NULL);
|
|
if(NT_SUCCESS(st))
|
|
return TRUE;
|
|
SetLastError(RtlNtStatusToDosError(st));
|
|
return FALSE;
|
|
}
|
|
#endif
|