urbackup_backend/btrfs/fuse/nt/windef.cpp
2021-07-05 19:49:25 +02:00

1912 lines
44 KiB
C++

extern "C"
{
#include "windef.h"
#include "guiddef.h"
#include "device.h"
}
#include "../fuse.h"
#include <memory>
#include <iostream>
#include <thread>
#include <stdarg.h>
#include <assert.h>
#include "../oslib/os.h"
#include <map>
#include <vector>
#include <mutex>
#include <atomic>
#include <set>
#include <array>
#include <thread>
#include <condition_variable>
#include "file.h"
#include "../oslib/utf8.h"
#include "../../../utf8/utf8.h"
#ifndef _WIN32
#define vsprintf_s vsnprintf
#define vprintf_s vprintf
#define vswprintf_s vswprintf
#endif
POBJECT_TYPE* IoFileObjectType;
namespace
{
struct SRegisteredDeviceObject
{
PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT FileObject;
};
std::map<std::wstring, SRegisteredDeviceObject> registered_device_objects;
struct SEventSlot
{
std::mutex m;
HANDLE evt;
HANDLE evt_a;
HANDLE evt_b;
unsigned int* waiters;
unsigned int waiters_a;
unsigned int waiters_b;
std::condition_variable wait_c;
};
std::array<SEventSlot, 100> event_slots;
std::atomic<unsigned int> curr_event_slot(0);
const unsigned short handle_tt_file = 1;
const unsigned short handle_tt_thread = 2;
const unsigned short handle_tt_registered = 3;
HANDLE addTypeTag(HANDLE h, unsigned short tt)
{
return reinterpret_cast<HANDLE>(reinterpret_cast<ULONG_PTR>(h) | (tt & 0xF));
}
HANDLE removeTypeTag(HANDLE h, unsigned short& tt)
{
tt = reinterpret_cast<ULONG_PTR>(h) & 0xF;
return reinterpret_cast<HANDLE>(reinterpret_cast<ULONG_PTR>(h) & ~0xF);
}
PFILE_OBJECT last_file_object = NULL;
}
struct KSPIN_LOCK_IMPL
{
std::mutex m;
};
LONG KeSetEvent(PKEVENT event, int a, BOOLEAN b)
{
LONG prev = std::atomic_load_explicit(reinterpret_cast<std::atomic<LONG>*>(&(event->eword)), std::memory_order_acquire);
if (prev == 0)
{
std::atomic_store_explicit(reinterpret_cast<std::atomic<LONG>*>(&(event->eword)), 1, std::memory_order_release);
os_wake_by_address_single(&(event->eword));
}
return prev;
}
void KeInitializeEvent(PKEVENT Event, EVENT_TYPE Type, BOOLEAN State)
{
Event->eword = State ? 1 : 0;
}
NTSTATUS KeWaitForSingleObject(PVOID Object, KWAIT_REASON WaitReason, REQMODE WaitMode, BOOLEAN Alertable, PLARGE_INTEGER Timeout)
{
PKEVENT Event = reinterpret_cast<PKEVENT>(Object);
if (std::atomic_load_explicit(reinterpret_cast<std::atomic<LONG>*>(&(Event->eword)), std::memory_order_relaxed) != 0)
{
return STATUS_SUCCESS;
}
LONG curr_eword = 0;
do
{
os_wait_on_address(&(Event->eword), &curr_eword, sizeof(curr_eword), INFINITE);
} while (std::atomic_load_explicit(reinterpret_cast<std::atomic<LONG>*>(&(Event->eword)), std::memory_order_acquire) == 0);
return STATUS_SUCCESS;
}
BOOLEAN KeReadStateEvent(PKEVENT Event)
{
return std::atomic_load_explicit(reinterpret_cast<std::atomic<LONG>*>(&(Event->eword)), std::memory_order_relaxed) > 0;
}
void KeClearEvent(PKEVENT Event)
{
std::atomic_store_explicit(reinterpret_cast<std::atomic<LONG>*>(&(Event->eword)), 0, std::memory_order_release);
}
void init_object_type()
{
IoFileObjectType = new POBJECT_TYPE;
}
void init_windef()
{
init_object_type();
}
BOOL OpenProcessToken(HANDLE hProc, ULONG Flags, PHANDLE Token)
{
return TRUE;
}
BOOL LookupPrivilegeValueW(PVOID ptr1, WCHAR* Name, PLUID Luid)
{
return TRUE;
}
ULONG WideCharToMultiByteInt(ULONG Codepage, DWORD Flags, WCHAR* Wchar, int NumWchar, char* buf, ULONG blen, PVOID ptr1, PVOID ptr2)
{
if (NumWchar == 0)
{
return 0;
}
if (NumWchar == -1)
{
NumWchar = wcslen(Wchar) + 1;
}
std::string ret;
try
{
if (sizeof(wchar_t) == 2)
{
utf8::utf16to8(Wchar, Wchar+NumWchar, back_inserter(ret));
}
else if (sizeof(wchar_t) == 4)
{
utf8::utf32to8(Wchar, Wchar + NumWchar, back_inserter(ret));
}
}
catch (...) {}
if (blen == 0)
{
return ret.size();
}
ULONG tocopy = (std::min)(blen, static_cast<ULONG>(ret.size()));
memcpy(buf, ret.data(), tocopy);
return tocopy;
}
NTSTATUS NtDeviceIoControlFile(HANDLE h, PVOID ptr1, PVOID ptr2, PVOID ptr3, PIO_STATUS_BLOCK Iocb, ULONG Cmd,
PVOID Apte1, ULONG Ape1Len, PVOID Apte2, ULONG Ape2Len)
{
if (Cmd == IOCTL_DISK_GET_LENGTH_INFO)
{
IFile* vol = reinterpret_cast<IFile*>(h);
GET_LENGTH_INFORMATION* gli = reinterpret_cast<GET_LENGTH_INFORMATION*>(Apte2);
gli->Length.QuadPart = vol->Size();
return STATUS_SUCCESS;
}
else if (Cmd == IOCTL_DISK_GET_DRIVE_GEOMETRY)
{
DISK_GEOMETRY* dg = reinterpret_cast<DISK_GEOMETRY*>(Apte2);
dg->BytesPerSector = 512;
dg->Cylinders.QuadPart = 0;
dg->SectorsPerTrack = 1;
dg->TracksPerCylinder = 1;
return STATUS_SUCCESS;
}
return STATUS_NOT_IMPLEMENTED;
}
std::mutex registered_files_mutex;
std::map<std::wstring, IFile*> registered_files;
void RegisterNtFile(WCHAR* Name, PVOID file)
{
std::lock_guard<std::mutex> lock(registered_files_mutex);
registered_files[Name] = reinterpret_cast<IFile*>(file);
}
void UnregisterNtFile(WCHAR* Name)
{
std::lock_guard<std::mutex> lock(registered_files_mutex);
auto it = registered_files.find(Name);
if (it != registered_files.end())
registered_files.erase(it);
}
NTSTATUS NtOpenFile(PHANDLE Handle, ULONG Attributes, POBJECT_ATTRIBUTES Atts, PIO_STATUS_BLOCK iosb, ULONG SharingMode, ULONG AlertMode)
{
std::lock_guard<std::mutex> lock(registered_files_mutex);
auto it = registered_files.find(Atts->path);
if (it == registered_files.end())
return STATUS_NOT_FOUND;
*Handle = it->second;
return STATUS_SUCCESS;
}
NTSTATUS NtWriteFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext,
PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
{
IFile* f = reinterpret_cast<IFile*>(FileHandle);
bool has_error = false;
_u32 rc = f->Write(ByteOffset->QuadPart, reinterpret_cast<char*>(Buffer), Length, &has_error);
IoStatusBlock->Information = rc;
IoStatusBlock->Status = STATUS_SUCCESS;
if (has_error)
{
IoStatusBlock->Status = STATUS_CRC_ERROR;
}
return IoStatusBlock->Status;
}
NTSTATUS NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext,
PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
{
IFile* f = reinterpret_cast<IFile*>(FileHandle);
bool has_error = false;
_u32 rc = f->Read(ByteOffset->QuadPart, reinterpret_cast<char*>(Buffer), Length, &has_error);
IoStatusBlock->Information = rc;
IoStatusBlock->Status = STATUS_SUCCESS;
if (has_error)
{
IoStatusBlock->Status = STATUS_CRC_ERROR;
}
return IoStatusBlock->Status;
}
BOOL AdjustTokenPrivileges(HANDLE token, BOOL b, TOKEN_PRIVILEGES* TokenPrivs, ULONG TokenPrivsSize, PVOID ptr1, PVOID ptr2)
{
return TRUE;
}
NTSTATUS NtFsControlFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG FsControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength)
{
return STATUS_SUCCESS;
}
BOOL FsRtlOplockIsFastIoPossible(POPLOCK lock)
{
return FALSE;
}
PEPROCESS PsGetCurrentProcess()
{
return PEPROCESS();
}
void* MmGetSystemAddressForMdlSafe(PMDL mdl, ULONG priority)
{
return mdl->ptr;
}
BOOLEAN FsRtlAreThereCurrentFileLocks(FILE_LOCK* lock)
{
return FALSE;
}
PVOID ExAllocate(size_t size)
{
return malloc(size);
}
PVOID ExAllocatePoolWithTag(POOL_TYPE PoolType, size_t size, unsigned int tag)
{
return malloc(size);
}
void DbgPrint(const char* msg, ...)
{
va_list arglist;
va_start(arglist, msg);
vprintf_s(msg, arglist);
va_end(arglist);
}
NTSTATUS RtlUnicodeStringPrintf(PUNICODE_STRING out, WCHAR* format, ...)
{
va_list arglist;
va_start(arglist, format);
int rc = vswprintf_s(out->Buffer, out->MaximumLength/sizeof(WCHAR), format, arglist);
va_end(arglist);
if (rc == -1)
{
return STATUS_INVALID_PARAMETER;
}
else
{
out->Length = static_cast<USHORT>(rc);
return STATUS_SUCCESS;
}
}
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING Dest, PUNICODE_STRING Source, BOOLEAN Allocate)
{
if (Allocate)
{
Dest->Buffer = new WCHAR[Source->Length/sizeof(WCHAR)];
Dest->Length = Source->Length;
Dest->MaximumLength = Source->MaximumLength;
}
USHORT i;
for (i = 0; i < Source->Length/sizeof(WCHAR) && i < Dest->MaximumLength/sizeof(WCHAR); ++i)
{
WCHAR ch = Source->Buffer[i];
WCHAR upch = os_toupper(ch);
Dest->Buffer[i] = upch;
}
Dest->Length = i*sizeof(WCHAR);
return STATUS_SUCCESS;
}
PETHREAD PsGetCurrentThread()
{
return PETHREAD();
}
NTSTATUS RtlStringCbVPrintfA(char* dest, size_t dest_size, const char* format, va_list argList)
{
int rc = vsprintf_s(dest, dest_size, format, argList);
if (rc == -1)
{
return STATUS_INVALID_PARAMETER;
}
else
{
return STATUS_SUCCESS;
}
}
NTSTATUS RtlUpperString(STRING* Dest, STRING* Source)
{
USHORT i;
for (i = 0; i < Source->Length && i < Dest->MaximumLength; ++i)
{
WCHAR ch = Source->Buffer[i];
WCHAR upch = os_toupper(ch);
Dest->Buffer[i] = static_cast<char>(upch);
}
Dest->Length = i;
return STATUS_SUCCESS;
}
void RtlZeroMemory(void* buf, size_t len)
{
memset(buf, 0, len);
}
PIRP IoAllocateIrp(const char StackSize, BOOLEAN ChargeQuota)
{
PIRP ret = new IRP;
memset(ret, 0, sizeof(IRP));
return ret;
}
PIO_STACK_LOCATION IoGetNextIrpStackLocation(PIRP Irp)
{
return &Irp->StackLocation;
}
PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
{
return &Irp->StackLocation;
}
PMDL IoAllocateMdl(PVOID VirtualAddress, ULONG Length, BOOLEAN SecondaryBuffer, BOOLEAN ChargeQuota, PIRP Irp)
{
PMDL mdl = new MDL;
mdl->ptr = VirtualAddress;
mdl->Length = Length;
return mdl;
}
void MmBuildMdlForNonPagedPool(PMDL Mdl)
{
}
void IoSetCompletionRoutine(PIRP Irp, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID Context, BOOLEAN InvokeOnSucces, BOOLEAN InvokeOnError, BOOLEAN InvokeOnCancel)
{
Irp->CompletionRoutine = CompletionRoutine;
Irp->CompletionRoutineContext = Context;
Irp->CompletionRoutineFlags = 0;
if (InvokeOnSucces)
Irp->CompletionRoutineFlags |= COMPLETION_ROUTINE_ON_SUCCESS;
if (InvokeOnError)
Irp->CompletionRoutineFlags |= COMPLETION_ROUTINE_ON_ERROR;
if (InvokeOnCancel)
Irp->CompletionRoutineFlags |= COMPLETION_ROUTINE_ON_CANCEL;
}
NTSTATUS IoCallDriver(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
if (DeviceObject->DiskDevice != NULL)
{
return DiskDeviceCall(DeviceObject->DiskDevice, Irp, DeviceObject);
}
return NTSTATUS();
}
void IoFreeMdl(PMDL mdl)
{
}
void IoFreeIrp(PIRP Irp)
{
delete Irp;
}
NTSTATUS ZwWriteFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
{
unsigned short tt;
FileHandle = removeTypeTag(FileHandle, tt);
if (tt != handle_tt_file)
return STATUS_INVALID_PARAMETER;
File* file = static_cast<File*>(FileHandle);
bool has_error = false;
_u32 written = file->Write(static_cast<char*>(Buffer), Length, &has_error);
if (has_error)
{
IoStatusBlock->Status = STATUS_UNEXPECTED_IO_ERROR;
}
return STATUS_SUCCESS;
}
void ExFreePool(PVOID buf)
{
free(buf);
}
PIRP IoGetTopLevelIrp()
{
return NULL;
}
void IoSetTopLevelIrp(PIRP Irp)
{
}
NTSTATUS IoDeleteSymbolicLink(PUNICODE_STRING Path)
{
return STATUS_SUCCESS;
}
NTSTATUS IoDeleteDevice(PDEVICE_OBJECT DeviceObject)
{
return STATUS_SUCCESS;
}
BOOLEAN IsListEmpty(const LIST_ENTRY* ListHead)
{
return ListHead->Flink == ListHead;
}
PLIST_ENTRY RemoveHeadList(PLIST_ENTRY ListHead)
{
PLIST_ENTRY ret = ListHead->Flink;
PLIST_ENTRY next = ListHead->Flink->Flink;
ListHead->Flink = next;
next->Blink = ListHead;
return ret;
}
PLIST_ENTRY RemoveTailList(PLIST_ENTRY ListHead)
{
PLIST_ENTRY ret = ListHead->Blink;
ret->Blink->Flink = ListHead;
ListHead->Blink = ret->Blink;
return ret;
}
BOOLEAN RemoveEntryList(PLIST_ENTRY ListEntry)
{
PLIST_ENTRY next = ListEntry->Flink;
PLIST_ENTRY prev = ListEntry->Blink;
next->Blink = prev;
prev->Flink = next;
return next == prev;
}
void InsertHeadList(PLIST_ENTRY ListHead, PLIST_ENTRY ListEntry)
{
PLIST_ENTRY next = ListHead->Flink;
ListHead->Flink = ListEntry;
ListEntry->Blink = ListHead;
ListEntry->Flink = next;
next->Blink = ListEntry;
ListHead->Flink = ListEntry;
}
void ObDereferenceObject(PVOID FileObject)
{
}
void ZwClose(HANDLE hFile)
{
if (hFile == NULL)
return;
unsigned short tt;
hFile = removeTypeTag(hFile, tt);
if (tt == handle_tt_file)
{
delete static_cast<File*>(hFile);
}
else if (tt == handle_tt_thread)
{
delete static_cast<std::thread*>(hFile);
}
else
{
assert(false);
}
}
size_t RtlCompareMemory(const void* const src1, const void* const src2, size_t len)
{
const char* const psrc1 = reinterpret_cast<const char* const>(src1);
const char* const psrc2 = reinterpret_cast<const char* const>(src2);
for (size_t i = 0; i < len; ++i)
{
if (psrc1[i] != psrc2[i])
{
return i;
}
}
return len;
}
void RtlMoveMemory(PVOID dst, const void* src, size_t len)
{
memmove(dst, src, len);
}
void FsRtlEnterFileSystem()
{
}
void FsRtlExitFileSystem()
{
}
void IoCompleteRequest(PIRP Irp, char PriorityBoost)
{
}
NTSTATUS FsRtlCheckOplock(POPLOCK Oplock, PVOID CallbackData, PVOID Context, PVOID WaitCompletionRoutine, PVOID PrePostCallbackDataRoutine)
{
return STATUS_SUCCESS;
}
void CcFlushCache(PSECTION_OBJECT_POINTERS SectionObjectPointers, PLARGE_INTEGER FileOffset, ULONG Length, PIO_STATUS_BLOCK IoStatus)
{
}
KAFFINITY KeQueryActiveProcessors()
{
KAFFINITY ret = 1;
size_t ncpus = os_get_num_cpus();
while (ncpus > 1)
{
ret *= 2;
ret += 1;
ncpus--;
}
return ret;
}
HANDLE NtCurrentProcess()
{
return HANDLE();
}
BOOLEAN FsRtlAreNamesEqual(PUNICODE_STRING name1, PUNICODE_STRING name2, BOOLEAN ignore_case, PVOID UpcaseTable)
{
if (name1->Length != name2->Length)
return FALSE;
if (memcmp(name1->Buffer, name2->Buffer, name1->Length) == 0)
return TRUE;
if (!ignore_case)
return FALSE;
for (USHORT i = 0; i < name1->Length/sizeof(WCHAR); ++i)
{
WCHAR ch1 = name1->Buffer[i];
WCHAR ch2 = name2->Buffer[i];
if (os_toupper(ch1) != os_toupper(ch2))
return FALSE;
}
return TRUE;
}
ULONG RtlWalkFrameChain(void** chain, ULONG n1, ULONG n2)
{
return size_t();
}
NTSTATUS FsRtlNotifyVolumeEvent(PFILE_OBJECT Vol, ULONG Action)
{
if (Action == FSRTL_VOLUME_MOUNT)
{
last_file_object = Vol;
return STATUS_SUCCESS;
}
return STATUS_NOT_IMPLEMENTED;
}
PFILE_OBJECT FsRtlNotifyGetLastVolumeEventsubject()
{
return last_file_object;
}
NTSTATUS FsRtlNotifyFilterReportChange(PNOTIFY_SYNC NotifySync, PLIST_ENTRY DirNotifyList, PSTRING fn, USHORT name_offset, PSTRING stream, PVOID arg1, ULONG filter_match, ULONG action, PVOID arg2, PVOID arg3)
{
return STATUS_NOT_IMPLEMENTED;
}
LONG InterlockedIncrement(LONG volatile* val)
{
return os_interlocked_increment(val);
}
LONGLONG InterlockedIncrement64(LONGLONG volatile* val)
{
return os_interlocked_increment64(val);
}
LONG InterlockedDecrement(LONG volatile* val)
{
return os_interlocked_decrement(val);
}
void ExFreeToNPagedLookasideList(PNPAGED_LOOKASIDE_LIST Lookaside, PVOID Entry)
{
ExFreePool(Entry);
}
void ExFreeToPagedLookasideList(PPAGED_LOOKASIDE_LIST Lookaside, PVOID Entry)
{
ExFreePool(Entry);
}
void ExDeletePagedLookasideList(PPAGED_LOOKASIDE_LIST Lookaside)
{
}
void ExDeleteNPagedLookasideList(PNPAGED_LOOKASIDE_LIST Lookaside)
{
}
void FsRtlUninitializeFileLock(PFILE_LOCK FileLock)
{
}
void FsRtlUninitializeOplock(POPLOCK Oplock)
{
}
void RtlFreeUnicodeString(PUNICODE_STRING String)
{
}
BOOLEAN CcUninitializeCacheMap(PFILE_OBJECT FileObject, PVOID arg1, PVOID arg2)
{
return TRUE;
}
std::mutex vpb_mutex;
void IoAcquireVpbSpinLock(PKIRQL Irql)
{
vpb_mutex.lock();
}
void IoReleaseVpbSpinLock(KIRQL Irql)
{
vpb_mutex.unlock();
}
void KeSetTimer(PKTIMER Timer, LARGE_INTEGER Time, PVOID arg1)
{
Timer->Timer = Time.QuadPart * -1;
}
void IoDetachDevice(PDEVICE_OBJECT DeviceObject)
{
}
void CcSetFileSizes(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes)
{
}
NTSTATUS GetExceptionCode()
{
return STATUS_NOT_IMPLEMENTED;
}
void KeQuerySystemTime(PLARGE_INTEGER Time)
{
}
void IoRemoveShareAccess(PFILE_OBJECT FileObject, PSHARE_ACCESS ShareAccess)
{
}
PEPROCESS IoGetRequestorProcess(PIRP Irp)
{
return PEPROCESS();
}
NTSTATUS FsRtlFastUnlockAll(PFILE_LOCK FileLock, PFILE_OBJECT FileObject, PEPROCESS Requestor, PVOID arg1)
{
return STATUS_NOT_IMPLEMENTED;
}
void FsRtlNotifyCleanup(PNOTIFY_SYNC NotifySync, PLIST_ENTRY NotifyList, PVOID arg1)
{
}
void CcPurgeCacheSection(PSECTION_OBJECT_POINTERS SectionPointers, PLARGE_INTEGER FileOffset, ULONG Length, ULONG Flags)
{
}
void MmProbeAndLockPages(PMDL Mdl, REQMODE Reqmode, ACCESS_MODE AccessMode)
{
}
void MmUnlockPages(PMDL Mdl)
{
}
PIRP IoBuildDeviceIoControlRequest(ULONG ControlCode, PDEVICE_OBJECT DeviceObject, PVOID InputBuffer, ULONG InputBufferSize, PVOID OutputBuffer, ULONG OutputBufferSize, BOOLEAN Internal, PKEVENT Event, PIO_STATUS_BLOCK IoStatusBlock)
{
PIRP Irp = new IRP;
memset(Irp, 0, sizeof(IRP));
if (Internal)
Irp->StackLocation.MajorFunction = IRP_MJ_DEVICE_CONTROL;
else
Irp->StackLocation.MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
Irp->AssociatedIrp.SystemBuffer = OutputBuffer;
if (InputBuffer != OutputBuffer)
{
Irp->MdlAddress = reinterpret_cast<PMDL>(InputBuffer);
}
Irp->StackLocation.Parameters.DeviceIoControl.IoControlCode = ControlCode;
Irp->StackLocation.Parameters.DeviceIoControl.InputBufferLength = InputBufferSize;
Irp->StackLocation.Parameters.DeviceIoControl.OutputBufferLength = OutputBufferSize;
Irp->UserEvent = Event;
*IoStatusBlock = Irp->IoStatus;
return Irp;
}
void CcInitializeCacheMap(PFILE_OBJECT FileObject, PCC_FILE_SIZES CcFileSizes, BOOLEAN PinAccess, PCACHE_MANAGER_CALLBACKS Callbacks, PVOID Context)
{
}
void CcSetReadAheadGranularity(PFILE_OBJECT FileObject, ULONG Size)
{
}
void KeInitializeSpinLock(PKSPIN_LOCK Spinlock)
{
//TODO: Use WaitOnAddress
Spinlock->Lock = new KSPIN_LOCK_IMPL;
}
void InitializeObjectAttributes(POBJECT_ATTRIBUTES ObjectAttributes, PUNICODE_STRING arg1, OBJECT_ATTRIBUTE_TYPE Type, PVOID arg2, PVOID arg3)
{
if (arg1 != NULL)
{
ULONG len = (std::min)(sizeof(ObjectAttributes->path) - 1, arg1->Length / sizeof(WCHAR));
memcpy(ObjectAttributes->path, arg1->Buffer, len * sizeof(WCHAR));
ObjectAttributes->path[len] = 0;
}
}
NTSTATUS PsCreateSystemThread(HANDLE* hThread, ULONG access, POBJECT_ATTRIBUTES attr, HANDLE process, PVOID arg1, PKSTART_ROUTINE Routine, PVOID Context)
{
std::thread* new_thread = new std::thread(Routine, Context);
new_thread->detach();
*hThread = addTypeTag(static_cast<HANDLE>(new_thread), handle_tt_thread);
return STATUS_SUCCESS;
}
std::atomic<size_t> max_volumes(0);
NTSTATUS IoGetDeviceInterfaces(PGUID arg1, PVOID arg2, ULONG len, WCHAR** list)
{
std::wstring devlist;
if (memcmp(arg1, &GUID_DEVINTERFACE_DISK, sizeof(GUID)) == 0)
{
for (size_t i = 0; i < max_volumes; ++i)
{
devlist += L"VOL" + std::to_wstring(i);
devlist += wchar_t{ 0 };
}
}
*list = reinterpret_cast<WCHAR*>(ExAllocate((devlist.size() + 1) * sizeof(WCHAR)));
memcpy(*list, devlist.data(), devlist.size() * sizeof(wchar_t));
(*list)[devlist.size()] = 0;
return STATUS_SUCCESS;
}
NTSTATUS IoRegisterDeviceObjectPointer(PUNICODE_STRING Name, PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject)
{
std::wstring wname(Name->Buffer, Name->Length/sizeof(WCHAR));
auto& it = registered_device_objects[wname];
it.DeviceObject = DeviceObject;
it.FileObject = FileObject;
return STATUS_SUCCESS;
}
NTSTATUS IoGetDeviceObjectPointer(PUNICODE_STRING Name, ULONG ObjectPointerType, PFILE_OBJECT* FileObject, PDEVICE_OBJECT* DeviceObject)
{
std::wstring wname(Name->Buffer, Name->Length / sizeof(WCHAR));
auto it = registered_device_objects.find(wname);
if (it != registered_device_objects.end())
{
*FileObject = it->second.FileObject;
*DeviceObject = it->second.DeviceObject;
return STATUS_SUCCESS;
}
else
{
return STATUS_NOT_FOUND;
}
}
void ObReferenceObject(PVOID Obj)
{
}
PDEVICE_OBJECT IoGetLowerDeviceObject(PDEVICE_OBJECT DeviceObject)
{
return PDEVICE_OBJECT();
}
NTSTATUS IoCreateDevice(PDRIVER_OBJECT DriverObject, ULONG Length, PUNICODE_STRING Name, DEVICE_TYPE Type, ULONG Characteristics, BOOLEAN Exclusive, PDEVICE_OBJECT* DeviceObject)
{
PDEVICE_OBJECT devobj = new DEVICE_OBJECT;
memset(devobj, 0, sizeof(devobj));
devobj->DriverObject = DriverObject;
devobj->DeviceExtension = new char[Length];
memset(devobj->DeviceExtension, 0, Length);
*DeviceObject = devobj;
if (Type == FILE_DEVICE_DISK)
{
register_new_disk(devobj);
}
return STATUS_SUCCESS;
}
BOOLEAN IoIsErrorUserInduced(NTSTATUS Status)
{
return BOOLEAN();
}
void IoSetHardErrorOrVerifyDevice(PIRP Irp, PDEVICE_OBJECT DeviceObject)
{
}
NTSTATUS ZwQueryInformationProcess(HANDLE ProcessHandle, PROCESSINFOCLASS InformationType, PVOID info, ULONG info_length, PULONG ret_len)
{
return STATUS_NOT_IMPLEMENTED;
}
void ExInitializeFastMutex(PFAST_MUTEX FastMutex)
{
//TODO: Convert to futex (WaitOnAddress etc...)
FastMutex->fast_mutex = reinterpret_cast<FAST_MUTEX_OP*>(new std::mutex);
}
void FsRtlNotifyInitializeSync(PNOTIFY_SYNC* NotifySync)
{
}
void ExInitializePagedLookasideList(PPAGED_LOOKASIDE_LIST LookasideList, PVOID arg1, PVOID arg2, ULONG Flags, SIZE_T Size, ULONG Tag, USHORT Depth)
{
LookasideList->entry_size = Size;
}
void ExInitializeNPagedLookasideList(PNPAGED_LOOKASIDE_LIST LookasideList, PVOID arg1, PVOID arg2, ULONG Flags, SIZE_T Size, ULONG Tag, USHORT Depth)
{
LookasideList->entry_size = Size;
}
void IoRaiseInformationalHardError(NTSTATUS Status, PUNICODE_STRING Msg, PKTHREAD Thread)
{
}
PFILE_OBJECT IoCreateStreamFileObject(PVOID arg1, PDEVICE_OBJECT DeviceObject)
{
PFILE_OBJECT ret = new FILE_OBJECT;
ret->DeviceObject = DeviceObject;
return ret;
}
NTSTATUS FsRtlProcessFileLock(PFILE_LOCK FileLock, PIRP Irp, PVOID arg1)
{
return NTSTATUS();
}
void RtlInitUnicodeString(PUNICODE_STRING InitStr, WCHAR* Str)
{
size_t len = 0;
if (Str != NULL)
{
while (Str[len] != 0)
{
++len;
}
}
if (len > 60000)
abort();
InitStr->Buffer = new wchar_t[static_cast<size_t>(len) + 1];
InitStr->Length = len*sizeof(WCHAR);
InitStr->MaximumLength = len*sizeof(WCHAR);
memcpy(InitStr->Buffer, Str, len * sizeof(wchar_t));
}
void IoUnregisterFileSystem(PDEVICE_OBJECT DeviceObject)
{
}
void IoUnregisterPlugPlayNotification(PVOID Entry)
{
}
void PoStartNextPowerIrp(PIRP Irp)
{
}
void IoSkipCurrentIrpStackLocation(PIRP Irp)
{
}
NTSTATUS PoCallDriver(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
return NTSTATUS();
}
PVOID ExAllocateFromNPagedLookasideList(PNPAGED_LOOKASIDE_LIST LookasideList)
{
return ExAllocate(LookasideList->entry_size);
}
PVOID ExAllocateFromPagedLookasideList(PPAGED_LOOKASIDE_LIST LookasideList)
{
return ExAllocate(LookasideList->entry_size);
}
void KeInitializeTimer(PKTIMER Timer)
{
Timer->Set = 0;
Timer->Slot = 0;
Timer->Timer = 0;
}
void KeCancelTimer(PKTIMER Timer)
{
}
void PsTerminateSystemThread(NTSTATUS Status)
{
}
NTSTATUS ZwCreateFile(HANDLE* pHandle, ULONG PointerType, POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock, PVOID arg1, ULONG Attributes, ULONG ShareMode, ULONG OpenMode, ULONG Flags, PVOID arg2, ULONG arg3)
{
int mode = 0;
if (OpenMode == FILE_OPEN_IF)
{
mode = MODE_RW_CREATE;
}
else
{
assert(false);
}
IoStatusBlock->Information = 0;
File* file = new File();
std::string fpath = ConvertFromWchar(ObjectAttributes->path);
if (fpath.find("\\??\\") == 0)
fpath = fpath.substr(4);
if (mode == MODE_RW_CREATE &&
file->Open(fpath, MODE_RW))
{
IoStatusBlock->Information |= FILE_OPENED;
}
else
{
if (!file->Open(fpath, mode))
{
delete file;
return STATUS_UNSUCCESSFUL;
}
}
*pHandle = addTypeTag(static_cast<HANDLE>(file), handle_tt_file);
return STATUS_SUCCESS;
}
NTSTATUS ZwQueryInformationFile(HANDLE Handle, PIO_STATUS_BLOCK IoStatusBlock, PVOID Out, ULONG OutLen, FILE_INFORMATION_CLASS InformationType)
{
if (InformationType == FileStandardInformation)
{
unsigned short tt;
Handle = removeTypeTag(Handle, tt);
if (tt != handle_tt_file)
return STATUS_INVALID_PARAMETER;
File* file = static_cast<File*>(Handle);
PFILE_STANDARD_INFORMATION fsi = static_cast<PFILE_STANDARD_INFORMATION>(Out);
fsi->EndOfFile.QuadPart = file->Size();
fsi->AllocationSize.QuadPart = 4096;
fsi->DeletePending = FALSE;
fsi->Directory = FALSE;
fsi->NumberOfLinks = 1;
return STATUS_SUCCESS;
}
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS ZwSetInformationFile(HANDLE Handle, PIO_STATUS_BLOCK IoStatusBlock, PVOID In, ULONG InLen, FILE_INFORMATION_CLASS InformationType)
{
if (InformationType == FilePositionInformation)
{
unsigned short tt;
Handle = removeTypeTag(Handle, tt);
if (tt != handle_tt_file)
return STATUS_INVALID_PARAMETER;
File* file = static_cast<File*>(Handle);
PFILE_POSITION_INFORMATION fpi = static_cast<PFILE_POSITION_INFORMATION>(Handle);
if (file->Seek(fpi->CurrentByteOffset.QuadPart))
{
return STATUS_SUCCESS;
}
else
{
return STATUS_UNSUCCESSFUL;
}
}
return NTSTATUS();
}
void RtlTimeToTimeFields(PLARGE_INTEGER Time, PTIME_FIELDS TimeFields)
{
}
NTSTATUS IoCreateSymbolicLink(PUNICODE_STRING Name, PUNICODE_STRING Target)
{
return NTSTATUS();
}
NTSTATUS IoRegisterDeviceInterface(PDEVICE_OBJECT DeviceObject, PGUID Guid, PVOID arg1, PUNICODE_STRING Name)
{
return NTSTATUS();
}
PDEVICE_OBJECT IoAttachDeviceToDeviceStack(PDEVICE_OBJECT DeviceObject, PDEVICE_OBJECT AttachDeviceObject)
{
PDEVICE_OBJECT ret = AttachDeviceObject->AttachedDevice;
AttachDeviceObject->AttachedDevice = DeviceObject;
return ret;
}
NTSTATUS IoSetDeviceInterfaceState(PUNICODE_STRING Name, BOOLEAN set)
{
return NTSTATUS();
}
PVOID MmGetSystemRoutineAddress(PUNICODE_STRING Name)
{
return PVOID();
}
NTSTATUS ZwCreateKey(HANDLE* hKey, ULONG Action, POBJECT_ATTRIBUTES ObjectAttributes, ULONG arg1, PVOID arg2, ULONG Flags, PULONG Disposition)
{
*hKey = NULL;
return NTSTATUS();
}
NTSTATUS IoReportDetectedDevice(PDRIVER_OBJECT DriverObject, REPORT_INTERFACE_TYPE InterfaceType, ULONG arg1, ULONG arg2, PVOID arg3, PVOID arg4, ULONG arg5, PDEVICE_OBJECT* DeviceObject)
{
if (DeviceObject != NULL
&& *DeviceObject == NULL)
{
*DeviceObject = new DEVICE_OBJECT;
}
return STATUS_SUCCESS;
}
void IoInvalidateDeviceRelations(PDEVICE_OBJECT DeviceObject, DEVICE_RELATIONS_TYPE DeviceRelation)
{
}
NTSTATUS IoRegisterPlugPlayNotification(PLUG_N_PLAY_EVENT_CATEGORIES EventCategory, ULONG Flags, PVOID arg1, PDRIVER_OBJECT DriverObject1, PNPNOTIFICATION_FUN NotificationFun, PVOID Context, PVOID arg2)
{
return NTSTATUS();
}
void IoRegisterFileSystem(PDEVICE_OBJECT DeviceObject)
{
}
void IoRegisterBootDriverReinitialization(PDRIVER_OBJECT DriverObject, BOOTDRIVERINIT_FUN InitFun, PVOID Context)
{
}
LUID RtlConvertLongToLuid(LONG Long)
{
LUID ret;
ret.LowPart = Long;
ret.HighPart = 0;
return ret;
}
BOOLEAN SeSinglePrivilegeCheck(LUID Lid, KPROCESSOR_MODE processor_mode)
{
return TRUE;
}
ULONG RtlRealBitmapSize(ULONG Size)
{
ULONG bitmap_size = (Size + 7) / 8;
bitmap_size = (bitmap_size + sizeof(ULONG) - 1) / sizeof(ULONG);
return bitmap_size;
}
void RtlInitializeBitMap(PRTL_BITMAP Bitmap, PULONG Buffer, ULONG Size)
{
Bitmap->SizeOfBitMap = Size;
Bitmap->Buffer = new ULONG[RtlRealBitmapSize(Size)];
}
void RtlSetAllBits(PRTL_BITMAP Bitmap)
{
memset(Bitmap->Buffer, 0xFF, RtlRealBitmapSize(Bitmap->SizeOfBitMap) * sizeof(ULONG));
}
void RtlSetBitInt(PRTL_BITMAP Bitmap, ULONG Idx, BOOLEAN v)
{
const ULONG bits_per = 8 * sizeof(ULONG);
ULONG bitmap_long = Idx / bits_per;
ULONG bitmap_bit = Idx % bits_per;
ULONG b = Bitmap->Buffer[bitmap_long];
if (v)
b = b | (1 << (bits_per - 1 - bitmap_bit));
else
b = b & (~(1 << (bits_per - 1 - bitmap_bit)));
Bitmap->Buffer[bitmap_long] = b;
}
void RtlClearBits(PRTL_BITMAP Bitmap, ULONG Start, ULONG Len)
{
for (ULONG i = 0; i < Len; ++i)
{
RtlSetBitInt(Bitmap, Start + i, FALSE);
}
}
void RtlSetBit(PRTL_BITMAP Bitmap, ULONG Off)
{
RtlSetBitInt(Bitmap, Off, TRUE);
}
void RtlClearAllBits(PRTL_BITMAP Bitmap)
{
memset(Bitmap->Buffer, 0, RtlRealBitmapSize(Bitmap->SizeOfBitMap) * sizeof(ULONG));
}
void RtlSetBits(PRTL_BITMAP Bitmap, ULONG Start, ULONG Len)
{
for (ULONG i = 0; i < Len; ++i)
{
RtlSetBitInt(Bitmap, Start + i, TRUE);
}
}
BOOLEAN RtlGetBit(PRTL_BITMAP Bitmap, ULONG Idx)
{
const ULONG bits_per = 8 * sizeof(ULONG);
ULONG bitmap_long = Idx / bits_per;
ULONG bitmap_bit = Idx % bits_per;
ULONG b = Bitmap->Buffer[bitmap_long];
return ((b & (1 << (bits_per - 1 - bitmap_bit))) > 0) ? TRUE : FALSE;
}
BOOLEAN RtlAreBitsClear(PRTL_BITMAP Bitmap, ULONG Start, ULONG Len)
{
for (ULONG i = 0; i < Len; ++i)
{
if (RtlGetBit(Bitmap, Start + i))
return FALSE;
}
return TRUE;
}
BOOLEAN RtlCheckBit(PRTL_BITMAP Bitmap, ULONG Off)
{
return RtlGetBit(Bitmap, Off);
}
ULONG RtlFindNextForwardRunClear(PRTL_BITMAP Bitmap, ULONG Off, PULONG Start)
{
ULONG i;
ULONG len = 0;
for (i = Off; i < Bitmap->SizeOfBitMap; ++i)
{
if (!RtlGetBit(Bitmap, i))
{
*Start = i;
len = 1;
++i;
break;
}
}
for (; i < Bitmap->SizeOfBitMap; ++i)
{
if (RtlGetBit(Bitmap, i))
{
break;
}
else
{
++len;
}
}
return len;
}
ULONG RtlFindFirstRunClear(PRTL_BITMAP Bitmap, PULONG Start)
{
return RtlFindNextForwardRunClear(Bitmap, 0, Start);
}
NTSTATUS ZwOpenSymbolicLinkObject(HANDLE hObj, ULONG OpenMode, POBJECT_ATTRIBUTES Attrs)
{
return NTSTATUS();
}
NTSTATUS ZwQuerySymbolicLinkObject(HANDLE hObj, PUNICODE_STRING Target, PULONG retlen)
{
return NTSTATUS();
}
void NtClose(HANDLE hObj)
{
}
NTSTATUS ZwQueryValueKey(HANDLE hObj, PUNICODE_STRING Name, QUERY_VALUE_TYPE Type, PKEY_VALUE_FULL_INFORMATION KvInf, ULONG KvInfLen, PULONG KvInfLenOut)
{
std::wstring wname;
wname.resize(Name->Length/sizeof(WCHAR));
memcpy(&wname[0], Name->Buffer, Name->Length);
if (wname == L"DebugLogLevel")
{
if (KvInf == NULL || KvInfLen < sizeof(KEY_VALUE_FULL_INFORMATION)+ sizeof(DWORD))
{
if (KvInfLenOut != NULL)
*KvInfLenOut = sizeof(KEY_VALUE_FULL_INFORMATION) + sizeof(DWORD);
return STATUS_BUFFER_TOO_SMALL;
}
if (KvInfLenOut != NULL)
*KvInfLenOut = sizeof(KEY_VALUE_FULL_INFORMATION) + sizeof(DWORD);
KvInf->DataLength = sizeof(DWORD);
KvInf->DataOffset = offsetof(KEY_VALUE_FULL_INFORMATION, Name);
KvInf->NameLength = 0;
KvInf->Type = REG_DWORD;
DWORD out = 10;
memcpy((char*)KvInf + KvInf->DataOffset, &out, sizeof(out));
return STATUS_SUCCESS;
}
return NTSTATUS();
}
PKTHREAD KeGetCurrentThread()
{
return PKTHREAD();
}
void KeAcquireSpinLock(PKSPIN_LOCK Spinlock, PKIRQL Irql)
{
//TODO: Use WaitOnAddress
Spinlock->Lock->m.lock();
}
void KeReleaseSpinLock(PKSPIN_LOCK Spinlock, KIRQL Irql)
{
Spinlock->Lock->m.unlock();
}
void KeSetSystemAffinityThread(KAFFINITY Affinity)
{
}
void FsRtlSetupAdvancedHeader(PFSRTL_ADVANCED_FCB_HEADER Header, PFAST_MUTEX FastMutex)
{
}
void FsRtlInitializeFileLock(PFILE_LOCK FileLock, PVOID arg1, PVOID arg2)
{
}
void FsRtlInitializeOplock(POPLOCK Oplock)
{
}
NTSTATUS IoCheckEaBufferValidity(PFILE_FULL_EA_INFORMATION EaInformation, ULONG Length, PULONG Offset)
{
return NTSTATUS();
}
BOOLEAN RtlValidRelativeSecurityDescriptor(PVOID SecurityDescriptor, ULONG Length, PVOID arg1)
{
return BOOLEAN();
}
void SeLockSubjectContext(PSECURITY_SUBJECT_CONTEXT SecSubjContext)
{
}
BOOLEAN SeAccessCheck(PSECURITY_DESCRIPTOR Sd, PSECURITY_SUBJECT_CONTEXT SecSubjContext, BOOLEAN b, ULONG FileOption, ULONG arg1, PVOID arg2, PGENERIC_MAPPING GenMap, REQMODE Reqmode, ACCESS_MASK* Access, NTSTATUS* status)
{
*Access = FileOption;
*status = STATUS_SUCCESS;
return TRUE;
}
PGENERIC_MAPPING IoGetFileObjectGenericMapping()
{
return PGENERIC_MAPPING();
}
void IoSetShareAccess(ACCESS_MASK Access, ULONG DesiredAccess, PFILE_OBJECT FileObj, PSHARE_ACCESS ShareAccess)
{
}
BOOLEAN FsRtlDoesNameContainWildCards(PUNICODE_STRING Str)
{
for (USHORT i = 0; i < Str->Length/sizeof(WCHAR); ++i)
{
if (Str->Buffer[i] == '*')
return TRUE;
}
return FALSE;
}
BOOLEAN FsRtlIsNameInExpression(PUNICODE_STRING Expression, PUNICODE_STRING Name, BOOLEAN IgnoreCase, PVOID arg1)
{
//TODO: Implement
return FALSE;
}
void FsRtlNotifyFilterChangeDirectory(PNOTIFY_SYNC NotifySync, PLIST_ENTRY DirList, PVOID FsContext, PSTRING Filename, ULONG Flags, BOOLEAN b1, ULONG CompletionFilter, PIRP Irp, PVOID arg1, PVOID arg2, PVOID arg3)
{
}
void FsRtlNotifyFullChangeDirectory(PNOTIFY_SYNC NotifySync, PLIST_ENTRY DirList, PVOID FsContext, PVOID arg1, BOOLEAN arg2, BOOLEAN arg3, ULONG arg4, PVOID arg5, PVOID arg6, PVOID arg7)
{
}
BOOLEAN FsRtlCopyRead(PFILE_OBJECT FileObject, PLARGE_INTEGER Offset, ULONG Length, BOOLEAN Wait, ULONG LockKey, PVOID Buf, PIO_STATUS_BLOCK Status, PDEVICE_OBJECT DeviceObject)
{
return BOOLEAN();
}
BOOLEAN FsRtlMdlReadDev(PFILE_OBJECT FileObject, PLARGE_INTEGER Offset, ULONG Length, ULONG LockKey, PMDL* Chain, PIO_STATUS_BLOCK Status, PDEVICE_OBJECT DeviceObject)
{
return BOOLEAN();
}
BOOLEAN FsRtlMdlReadCompleteDev(PFILE_OBJECT FileObject, PMDL Chain, PDEVICE_OBJECT DeviceObject)
{
return BOOLEAN();
}
BOOLEAN FsRtlPrepareMdlWriteDev(PFILE_OBJECT FileObject, PLARGE_INTEGER Offset, ULONG Length, ULONG LockKey, PMDL* Chain, PIO_STATUS_BLOCK Status, PDEVICE_OBJECT DeviceObject)
{
return BOOLEAN();
}
BOOLEAN FsRtlMdlWriteCompleteDev(PFILE_OBJECT FileObject, PLARGE_INTEGER Offset, PMDL Chain, PDEVICE_OBJECT DeviceObject)
{
return BOOLEAN();
}
BOOLEAN FsRtlFastCheckLockForRead(PFILE_LOCK FileLock, PLARGE_INTEGER Offset, PLARGE_INTEGER Len, ULONG Key, PFILE_OBJECT FileObj, PVOID ProcId)
{
return BOOLEAN();
}
BOOLEAN FsRtlFastCheckLockForWrite(PFILE_LOCK FileLock, PLARGE_INTEGER Offset, PLARGE_INTEGER Len, ULONG Key, PFILE_OBJECT FileObj, PVOID ProcId)
{
return BOOLEAN();
}
BOOLEAN FsRtlCopyWrite(PFILE_OBJECT FileObject, PLARGE_INTEGER Offset, ULONG Length, BOOLEAN Wait, ULONG LockKey, PVOID Buf, PIO_STATUS_BLOCK Status, PDEVICE_OBJECT DeviceObject)
{
return BOOLEAN();
}
BOOLEAN FsRtlFastLock(PFILE_LOCK FileLock, PFILE_OBJECT FileObject, PLARGE_INTEGER Offset, PLARGE_INTEGER Len, PEPROCESS ProcID, ULONG Key, BOOLEAN FailImmediately, BOOLEAN ExclusiveLock, PIO_STATUS_BLOCK Status, PVOID arg1, BOOLEAN arg2)
{
return BOOLEAN();
}
NTSTATUS FsRtlFastUnlockSingle(PFILE_LOCK FileLock, PFILE_OBJECT FileObject, PLARGE_INTEGER Offset, PLARGE_INTEGER Len, PEPROCESS ProcID, ULONG Key, PVOID arg1, BOOLEAN arg2)
{
return NTSTATUS();
}
NTSTATUS FsRtlFastUnlockAllByKey(PFILE_LOCK FileLock, PFILE_OBJECT FileObject, PEPROCESS ProcID, ULONG Key, PVOID arg1)
{
return NTSTATUS();
}
ULONG RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor)
{
return 0;
}
void SeCaptureSubjectContext(PSECURITY_SUBJECT_CONTEXT SecurityContext)
{
}
void SeReleaseSubjectContext(PSECURITY_SUBJECT_CONTEXT SecurityContext)
{
}
NTSTATUS SeAssignSecurity(PSECURITY_DESCRIPTOR SecurityDescriptor, PVOID arg1, PVOID* SdLink, BOOLEAN arg2, PSECURITY_SUBJECT_CONTEXT SecurityContext, PGENERIC_MAPPING Mapping, POOL_TYPE PoolType)
{
*SdLink = reinterpret_cast<void*>(0x1);
return STATUS_SUCCESS;
}
NTSTATUS RtlGetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, PSID* Owner, BOOLEAN* defaulted)
{
static SID lsid = {};
*Owner = &lsid;
return STATUS_SUCCESS;
}
LARGE_INTEGER KeQueryPerformanceCounter(PLARGE_INTEGER arg1)
{
LARGE_INTEGER ret;
if (arg1 != NULL)
ret.QuadPart = os_perf_counter(&arg1->QuadPart);
else
ret.QuadPart = os_perf_counter(NULL);
return ret;
}
ULONG RtlRandomEx(PULONG Prev)
{
ULONG ret = os_rand_next(*Prev);
*Prev = ret;
return ret;
}
BOOLEAN IoIs32bitProcess(PIRP Irp)
{
return BOOLEAN();
}
void SeUnlockSubjectContext(PSECURITY_SUBJECT_CONTEXT SecSubjContext)
{
}
BOOLEAN MmFlushImageSection(PSECTION_OBJECT_POINTERS SectionPointers, FLUSH_MODE FlushMode)
{
return TRUE;
}
BOOLEAN MmCanFileBeTruncated(PSECTION_OBJECT_POINTERS SectionPointers, PLARGE_INTEGER Size)
{
return BOOLEAN();
}
NTSTATUS IoCheckShareAccess(ACCESS_MASK AccessMask, ULONG Granted, PFILE_OBJECT FileObject, PSHARE_ACCESS ShareAccess, BOOLEAN b1)
{
return NTSTATUS();
}
void IoUpdateShareAccess(PFILE_OBJECT, PSHARE_ACCESS ShareAccess)
{
}
PDEVICE_OBJECT IoGetDeviceToVerify(PETHREAD Thread)
{
return PDEVICE_OBJECT();
}
void IoSetDeviceToVerify(PETHREAD Thread, PDEVICE_OBJECT DevObj)
{
}
NTSTATUS IoVerifyVolume(PDEVICE_OBJECT DevObj, BOOLEAN verify)
{
return NTSTATUS();
}
BOOLEAN SePrivilegeCheck(PPRIVILEGE_SET PrivilegeSet, PSECURITY_SUBJECT_CONTEXT SecSubjContext, KPROCESSOR_MODE ProcessorMode)
{
return BOOLEAN();
}
HANDLE ObRegisterHandle(PVOID Object)
{
PVOID* reg = new PVOID;
*reg = Object;
return addTypeTag(reg, handle_tt_registered);
}
NTSTATUS ObDeregisterHandle(HANDLE Handle)
{
unsigned short tt;
PVOID* reg = reinterpret_cast<PVOID*>(removeTypeTag(Handle, tt));
if (tt != handle_tt_registered)
{
return STATUS_INVALID_PARAMETER;
}
delete reg;
return STATUS_SUCCESS;
}
NTSTATUS ObReferenceObjectByHandle(HANDLE Handle, ACCESS_MASK Access,
POBJECT_TYPE ObjectType, KPROCESSOR_MODE ProcMode, PVOID* Object, PVOID arg1)
{
unsigned short tt;
PVOID* reg = reinterpret_cast<PVOID*>(removeTypeTag(Handle, tt));
if (tt != handle_tt_registered)
{
return STATUS_INVALID_PARAMETER;
}
*Object = *reg;
return STATUS_SUCCESS;
}
HANDLE LongToHandle(ULONG tLong)
{
return HANDLE();
}
void CcWaitForCurrentLazyWriterActivity()
{
}
NTSTATUS SeAssignSecurityEx(PSECURITY_DESCRIPTOR SecurityDescriptor, PVOID arg1, PVOID* Sd, PVOID arg2, BOOLEAN Directory, ULONG Flags, PSECURITY_SUBJECT_CONTEXT SecSubjContext, PGENERIC_MAPPING Mapping, POOL_TYPE PoolType)
{
return NTSTATUS();
}
NTSTATUS FsRtlOplockFsctrl(POPLOCK Oplock, PIRP Irp, ULONG Count)
{
return NTSTATUS();
}
BOOLEAN IsReparseTagMicrosoft(ULONG ReparseTag)
{
return BOOLEAN();
}
void IoAdjustPagingPathCount(LONG* Count, BOOL b1)
{
}
PIRP IoMakeAssociatedIrp(PIRP Irp, char StackSize)
{
PIRP ret = IoAllocateIrp(StackSize, FALSE);
Irp->AssociatedIRP = ret;
return ret;
}
void CcMdlRead(PFILE_OBJECT FileObject, PLARGE_INTEGER Offset, ULONG Length, PMDL* Address, PIO_STATUS_BLOCK Status)
{
}
void IoMarkIrpPending(PIRP Irp)
{
}
BOOLEAN CcCopyRead(PFILE_OBJECT FileObject, PLARGE_INTEGER Offset, ULONG Length, BOOLEAN Wait, PUCHAR Data, PIO_STATUS_BLOCK Status)
{
return FALSE;
}
BOOLEAN IoIsSystemThread(PETHREAD Thread)
{
return BOOLEAN();
}
PEPROCESS PsGetThreadProcess(PETHREAD Thread)
{
return PEPROCESS();
}
void CcMdlReadComplete(PFILE_OBJECT FileObject, PMDL Mdl)
{
}
BOOLEAN IoIsOperationSynchronous(PIRP Irp)
{
return TRUE;
}
BOOLEAN FsRtlCheckLockForReadAccess(PFILE_LOCK Lock, PIRP Irp)
{
return TRUE;
}
NTSTATUS ZwEnumerateValueKey(HANDLE h, ULONG index, REG_ENUM_TYPE EnumyType, PVOID Out, ULONG OutLen, PULONG retlen)
{
return STATUS_NO_MORE_ENTRIES;
}
NTSTATUS ZwOpenKey(PHANDLE h, ULONG Access, POBJECT_ATTRIBUTES Attr)
{
*h = NULL;
return NTSTATUS();
}
NTSTATUS ZwSetValueKey(HANDLE h, PUNICODE_STRING Path, ULONG Idx, ULONG Type, PVOID Data, ULONG DataLen)
{
return NTSTATUS();
}
NTSTATUS ZwDeleteKey(HANDLE h)
{
return NTSTATUS();
}
NTSTATUS ZwEnumerateKey(HANDLE h, ULONG Idx, REG_ENUM_TYPE EnumType, PVOID Out, ULONG OutLen, PULONG retlen)
{
return STATUS_NO_MORE_ENTRIES;
}
NTSTATUS ZwDeleteValueKey(HANDLE h, PUNICODE_STRING Path)
{
return NTSTATUS();
}
NTSTATUS ZwNotifyChangeKey(HANDLE h, PVOID arg1, PVOID arg2, PVOID arg3, PIO_STATUS_BLOCK IoSb, ULONG Action, BOOLEAN arg4, PVOID arg5, ULONG arg6, BOOLEAN arg7)
{
return NTSTATUS();
}
void ExInitializeWorkItem(PWORK_QUEUE_ITEM Wqi, WQFUN Fun, HANDLE h)
{
}
NTSTATUS SeQueryInformationToken(PACCESS_TOKEN Token, QUERY_INFORMATION_TOKEN_TYPE TokenType, PVOID Out)
{
return NTSTATUS();
}
ULONG RtlLengthSid(PSID Sid)
{
return 0;
}
BOOLEAN RtlEqualSid(PSID SidA, PSID SidB)
{
return BOOLEAN();
}
NTSTATUS RtlCreateSecurityDescriptor(PSECURITY_DESCRIPTOR Sd, ULONG SdRevision)
{
return NTSTATUS();
}
NTSTATUS RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR Sd, PSID Sid, BOOLEAN arg1)
{
return NTSTATUS();
}
NTSTATUS RtlSetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR Sd, PSID Sid, BOOLEAN arg1)
{
return NTSTATUS();
}
NTSTATUS RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR Sd, BOOLEAN ar1, PACL Acl, BOOLEAN arg2)
{
return NTSTATUS();
}
NTSTATUS RtlAbsoluteToSelfRelativeSD(PSECURITY_DESCRIPTOR Sd, PVOID arg1, PULONG len)
{
return NTSTATUS();
}
NTSTATUS RtlSelfRelativeToAbsoluteSD(PSECURITY_DESCRIPTOR Sd, PVOID arg1, PULONG Abslen, PVOID arg2, PULONG DaclLen, PVOID arg3, PULONG SaclLen, PVOID arg4, PULONG OwnerLen, PVOID arg5, PULONG GroupLen)
{
return NTSTATUS();
}
NTSTATUS SeQuerySecurityDescriptorInfo(PSECURITY_INFORMATION Flags, PSECURITY_DESCRIPTOR Sd, PULONG BufLen, PVOID* SdOut)
{
return NTSTATUS();
}
NTSTATUS SeSetSecurityDescriptorInfo(PVOID arg1, PSECURITY_INFORMATION Flags, PSECURITY_DESCRIPTOR Sd, PVOID* SdOut, POOL_TYPE PoolType, PGENERIC_MAPPING Mapping)
{
return NTSTATUS();
}
void ExAcquireFastMutex(PFAST_MUTEX Mutex)
{
std::mutex* m = reinterpret_cast<std::mutex*>(Mutex->fast_mutex);
m->lock();
}
void ExReleaseFastMutex(PFAST_MUTEX Mutex)
{
std::mutex* m = reinterpret_cast<std::mutex*>(Mutex->fast_mutex);
m->unlock();
}
PVOID MmGetMdlVirtualAddress(PMDL Mdl)
{
return PVOID();
}
void IoBuildPartialMdl(PMDL MdlAdress, PMDL Mdl, PVOID Ptr, ULONG Len)
{
}
void IoCancelIrp(PIRP Irp)
{
}
BOOLEAN CcCanIWrite(PFILE_OBJECT FileObject, ULONG Length, BOOLEAN Wait, BOOLEAN Deferred)
{
return BOOLEAN();
}
void CcPrepareMdlWrite(PFILE_OBJECT FileObject, PLARGE_INTEGER Offset, ULONG Length, PMDL* Mdl, PIO_STATUS_BLOCK Status)
{
}
BOOLEAN CcCopyWrite(PFILE_OBJECT FileObject, PLARGE_INTEGER Offset, ULONG Length, BOOLEAN Wait, PVOID Buffer)
{
return BOOLEAN();
}
BOOLEAN FsRtlCheckLockForWriteAccess(PFILE_LOCK FileLock, PIRP Irp)
{
return TRUE;
}
void CcMdlWriteComplete(PFILE_OBJECT FileObject, PLARGE_INTEGER Offset, PMDL Mdl)
{
}
BOOLEAN WdmlibRtlIsNtDdiVersionAvailable(ULONG Version)
{
return BOOLEAN();
}
HANDLE Handle32ToHandle(void* POINTER_32 ptr)
{
return HANDLE();
}
#ifndef _WIN32
int MultiByteToWideChar(UINT CodePage, DWORD Flags, char* ByteStr, int ByteStrSize, wchar_t* OutStr, int OutStrSize)
{
return 0;
}
PVOID GetModuleHandle(PVOID p1) { return nullptr; }
BOOL LoadStringW(PVOID module, int resid, WCHAR* str, size_t str_size)
{
return FALSE;
}
DWORD GetLastError(void)
{
return errno;
}
HMODULE LoadLibraryW(WCHAR* str)
{
return nullptr;
}
PVOID GetProcAddress(HMODULE, char* name)
{
return nullptr;
}
#endif