xbox-kernel/private/ntos/dm/msvc/dxt/api322.c
2020-09-30 17:17:25 +02:00

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