2020-09-30 17:17:25 +02:00

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;
}