181 lines
4.1 KiB
C
181 lines
4.1 KiB
C
/*
|
|
*
|
|
* api.c
|
|
*
|
|
* Implementation of the Win32 APIs needed for winsock, on top of ntoskrnl
|
|
*
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
#include "dm.h"
|
|
|
|
void SetLastError(DWORD dwErrCode)
|
|
{
|
|
DmGetCurrentDmtd()->LastError = dwErrCode;
|
|
}
|
|
|
|
DWORD GetLastError(void)
|
|
{
|
|
return DmGetCurrentDmtd()->LastError;
|
|
}
|
|
|
|
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 CreateEventA(LPSECURITY_ATTRIBUTES psa, BOOL fManualReset,
|
|
BOOL fInitState, LPCSTR 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;
|
|
}
|
|
|
|
void _ThreadStartup(PKSTART_ROUTINE StartRoutine, PVOID StartContext)
|
|
{
|
|
DmGetCurrentDmtd()->DebugFlags |= DMFLAG_DEBUGTHREAD;
|
|
StartRoutine(StartContext);
|
|
PsTerminateSystemThread(STATUS_SUCCESS);
|
|
}
|
|
|
|
HANDLE CreateThread(LPSECURITY_ATTRIBUTES psa, DWORD dwStack,
|
|
LPTHREAD_START_ROUTINE lpfn, LPVOID lpv, DWORD dwFlags, LPDWORD lpdwId)
|
|
{
|
|
NTSTATUS st;
|
|
HANDLE h;
|
|
CLIENT_ID clid;
|
|
|
|
st = PsCreateSystemThreadEx(&h, 0, dwStack, (PHANDLE)lpdwId,
|
|
(PKSTART_ROUTINE)lpfn, lpv,
|
|
(BOOLEAN)(dwFlags & CREATE_SUSPENDED ? TRUE : FALSE), _ThreadStartup);
|
|
|
|
if(!NT_SUCCESS(st))
|
|
{
|
|
SetLastError(RtlNtStatusToDosError(st));
|
|
return NULL;
|
|
}
|
|
|
|
return h;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
#if 0
|
|
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;
|
|
}
|
|
#endif
|
|
|
|
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;
|
|
}
|