#define WINDOWS_1803 17134
#define WINDOWS_1809 17763
#define WINDOWS_1903 18362
#define WINDOWS_1909 18363
#define WINDOWS_2004 19041
#define WINDOWS_20H2 19569
#define WINDOWS_21H1 20180

typedef unsigned long DWORD;

DWORD GetUserDirectoryTableBaseOffset()
{
RTL_OSVERSIONINFOW ver = { 0 };
RtlGetVersion(&ver);

switch (ver.dwBuildNumber)
{
case WINDOWS_1803:
return 0x0278;
break;
case WINDOWS_1809:
return 0x0278;
break;
case WINDOWS_1903:
return 0x0280;
break;
case WINDOWS_1909:
return 0x0280;
break;
case WINDOWS_2004:
return 0x0388;
break;
case WINDOWS_20H2:
return 0x0388;
break;
case WINDOWS_21H1:
return 0x0388;
break;
default:
return 0x0388;
}
}

//check normal dirbase if 0 then get from UserDirectoryTableBas
ULONG_PTR GetProcessCr3(PEPROCESS pProcess)
{
PUCHAR process = (PUCHAR)pProcess;
ULONG_PTR process_dirbase = (PULONG_PTR)(process + 0x28); //dirbase x64, 32bit is 0x18
if (process_dirbase == 0)
{
DWORD UserDirOffset = GetUserDirectoryTableBaseOffset();
ULONG_PTR process_userdirbase = (PULONG_PTR)(process + UserDirOffset);
return process_userdirbase;
}
return process_dirbase;
}


NTSTATUS ReadPhysicalAddress(PVOID TargetAddress, PVOID lpBuffer, SIZE_T Size, SIZE_T BytesRead)
{
MM_COPY_ADDRESS AddrToRead = { 0 };
AddrToRead.PhysicalAddress.QuadPart = TargetAddress;
return MmCopyMemory(lpBuffer, AddrToRead, Size, MM_COPY_MEMORY_PHYSICAL, BytesRead);
}

#define PAGE_OFFSET_SIZE 12
static const uint64_t PMASK = (0xfull << 8) & 0xfffffffffull;

uint64_t TranslateLinearAddress(uint64_t directoryTableBase, uint64_t virtualAddress) {
directoryTableBase &= ~0xf;

uint64_t pageOffset = virtualAddress & ~(0ul << PAGE_OFFSET_SIZE);
uint64_t pte = ((virtualAddress >> 12) & (0x1ffll));
uint64_t pt = ((virtualAddress >> 21) & (0x1ffll));
uint64_t pd = ((virtualAddress >> 30) & (0x1ffll));
uint64_t pdp = ((virtualAddress >> 39) & (0x1ffll));

SIZE_T readsize = 0;
uint64_t pdpe = 0;
ReadPhysicalAddress(directoryTableBase + 8 * pdp, &pdpe, sizeof(pdpe), &readsize);
if (pdpe & 1)
return 0;

uint64_t pde = 0;
ReadPhysicalAddress((pdpe & PMASK) + 8 * pd, &pde, sizeof(pde), &readsize);
if (pde & 1)
return 0;

/ 1GB large page, use pde's 12-34 bits /
if (pde & 0x80)
return (pde & (0ull << 42 >> 12)) + (virtualAddress & ~(0ull << 30));

uint64_t pteAddr = 0;
ReadPhysicalAddress((pde & PMASK) + 8 * pt, &pteAddr, sizeof(pteAddr), &readsize);
if (~pteAddr & 1)
return 0;

/ 2MB large page /
if (pteAddr & 0x80)
return (pteAddr & PMASK) + (virtualAddress & (0ull << 21));

virtualAddress = 0;
ReadPhysicalAddress((pteAddr & PMASK) + 8 * pte, &virtualAddress, sizeof(virtualAddress), &readsize);
virtualAddress &= PMASK;

if (!virtualAddress)
return 0;

return virtualAddress + pageOffset;
}


NTSTATUS ReadProcessMemory(int pid, PVOID Address, PVOID AllocatedBuffer, SIZE_T size, SIZE_T read)
{
PEPROCESS pProcess = NULL;
if (pid == 0) return STATUS_UNSUCCESSFUL;

NTSTATUS NtRet = PsLookupProcessByProcessId(pid, &pProcess);
if (NtRet != STATUS_SUCCESS) return NtRet;

ULONG_PTR process_dirbase = GetProcessCr3(pProcess);
ObDereferenceObject(pProcess);

SIZE_T CurOffset = 0;
SIZE_T TotalSize = size;
while (TotalSize)
{
uint64_t CurPhysAddr = TranslateLinearAddress(process_dirbase, (ULONG64)Address + CurOffset);
if (!CurPhysAddr) return STATUS_UNSUCCESSFUL;

ULONG64 ReadSize = min(PAGE_SIZE - (CurPhysAddr & 0xFFF), TotalSize);
SIZE_T BytesRead = 0;
NtRet = ReadPhysicalAddress(CurPhysAddr, (PVOID)((ULONG64)AllocatedBuffer + CurOffset), ReadSize, &BytesRead);
TotalSize -= BytesRead;
CurOffset += BytesRead;

if (BytesRead == 0) break;
}

read = CurOffset;
return NtRet;
}

//MmMapIoSpaceEx limit is page 4096 byte
NTSTATUS WritePhysicalAddress(PVOID TargetAddress, PVOID lpBuffer, SIZE_T Size, SIZE_T BytesWritten)
{
if (!TargetAddress)
return STATUS_UNSUCCESSFUL;

PHYSICAL_ADDRESS AddrToWrite = { 0 };
AddrToWrite.QuadPart = TargetAddress;

PVOID pmapped_mem = MmMapIoSpaceEx(AddrToWrite, Size, PAGE_READWRITE);

if (!pmapped_mem)
return STATUS_UNSUCCESSFUL;

memcpy(pmapped_mem, lpBuffer, Size);

BytesWritten = Size;
MmUnmapIoSpace(pmapped_mem, Size);
return STATUS_SUCCESS;
}

NTSTATUS WriteProcessMemory(int pid, PVOID Address, PVOID AllocatedBuffer, SIZE_T size, SIZE_T written)
{
PEPROCESS pProcess = NULL;
if (pid == 0) return STATUS_UNSUCCESSFUL;

NTSTATUS NtRet = PsLookupProcessByProcessId(pid, &pProcess);
if (NtRet != STATUS_SUCCESS) return NtRet;

ULONG_PTR process_dirbase = GetProcessCr3(pProcess);
ObDereferenceObject(pProcess);

SIZE_T CurOffset = 0;
SIZE_T TotalSize = size;
while (TotalSize)
{
uint64_t CurPhysAddr = TranslateLinearAddress(process_dirbase, (ULONG64)Address + CurOffset);
if (!CurPhysAddr) return STATUS_UNSUCCESSFUL;

ULONG64 WriteSize = min(PAGE_SIZE - (CurPhysAddr & 0xFFF), TotalSize);
SIZE_T BytesWritten = 0;
NtRet = WritePhysicalAddress(CurPhysAddr, (PVOID)((ULONG64)AllocatedBuffer + CurOffset), WriteSize, &BytesWritten);
TotalSize -= BytesWritten;
CurOffset += BytesWritten;

if (BytesWritten == 0) break;
}

written = CurOffset;
return NtRet;
}


#include "structs.h"

/
PVOID GetGuardedRegion(DWORD FirstPointer)
{
PSYSTEM_BIGPOOL_INFORMATION pPoolInfo = 0;
NTSTATUS ntstatus = STATUS_SUCCESS;
ULONG infoLen = 0;

ntstatus = ZwQuerySystemInformation(system_bigpool_information, &infoLen, 0, &infoLen);
while (ntstatus == STATUS_INFO_LENGTH_MISMATCH)
{
if (pPoolInfo)
ExFreePool(pPoolInfo);

pPoolInfo = (PSYSTEM_BIGPOOL_INFORMATION)ExAllocatePool(NonPagedPool, infoLen);
ntstatus = ZwQuerySystemInformation(system_bigpool_information, pPoolInfo, infoLen, &infoLen);
}

if (pPoolInfo)
{
for (ULONG i = 0; i < pPoolInfo->Count; ++i)
{
SYSTEM_BIGPOOL_ENTRY* Entry = &pPoolInfo->AllocatedInfo[i];
PVOID VirtualAddress = (PVOID)((uintptr_t)Entry->VirtualAddress & ~1ull);
SIZE_T SizeInBytes = Entry->SizeInBytes;
BOOLEAN NonPaged = Entry->NonPaged;

if (NonPaged && SizeInBytes == 0x200000)
{
ULONG Rsh_x24 = ((uintptr_t)((PBYTE)VirtualAddress + FirstPointer) >> 0x24);

if (Rsh_x24 == 0x8 || Rsh_x24 == 0x10)
{
if (pPoolInfo)
{
ExFreePool(pPoolInfo);
}
return VirtualAddress;
}
}
}
}
}
/
typedef struct _SYSTEM_PROCESS_INFORMATION
{
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER SpareLi1;
LARGE_INTEGER SpareLi2;
LARGE_INTEGER SpareLi3;
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
HANDLE InheritedFromUniqueProcessId;
ULONG HandleCount;
ULONG SessionId;
ULONG_PTR PageDirectoryBase;
SIZE_T PeakVirtualSize;
SIZE_T VirtualSize;
ULONG PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER ReadOperationCount;
LARGE_INTEGER WriteOperationCount;
LARGE_INTEGER OtherOperationCount;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION;;

DWORD64 GetProcessIdFromName(PWCHAR ProcName) {
NTSTATUS result;
PVOID infoBuffer = NULL;
PSYSTEM_PROCESS_INFORMATION procSysInfo = NULL;
ULONG retLen = 0;
DWORD64 retVal = 0;

result = ZwQuerySystemInformation(system_process_information, NULL, 0, &retLen);
if (!retLen || result != 0xC0000004) {
return 0;
}

while (result == 0xC0000004) {
retLen += 0x1000;
infoBuffer = ExAllocatePoolWithTag(NonPagedPool, retLen, 'LieH');
if (infoBuffer == NULL) {
return 0;
}

result = ZwQuerySystemInformation(system_process_information, infoBuffer, retLen, &retLen);
if (!NT_SUCCESS(result)) {
ExFreePoolWithTag(infoBuffer, 'LieH');
infoBuffer = NULL;
}
}

if (!NT_SUCCESS(result)) {
return 0;
}

procSysInfo = (PSYSTEM_PROCESS_INFORMATION)infoBuffer;

while (procSysInfo) {
if (procSysInfo->ImageName.Buffer != NULL) {
if (RlWcsicmp(procSysInfo->ImageName.Buffer, ProcName, TRUE)) {
retVal = (DWORD64)procSysInfo->UniqueProcessId;
break;
}
}

procSysInfo = procSysInfo->NextEntryOffset ? (PSYSTEM_PROCESS_INFORMATION)((PBYTE)procSysInfo + procSysInfo->NextEntryOffset) : NULL;
}

ExFreePoolWithTag(infoBuffer, 'LieH');
return retVal;
}

#pragma once

typedef struct _MyStructure
{
int RequestID;
int myProcessID;
int targetProcessID;
} MyStructure, * PMyStructure;

typedef struct _CustomStructure {
int RequestID;
int myProcessID;
int targetProcessID;
} CustomStructure, * PCustomStructure;

#define ReadMemoryCode 0x80000007
#define WriteMemoryCode 0x80000008

typedef enum _SYSTEM_INFORMATION_CLASS
{
system_basic_information,
system_processor_information,
system_performance_information,
system_time_of_day_information,
system_path_information,
system_process_information,
system_call_count_information,
system_device_information,
system_processor_performance_information,
system_flags_information,
system_call_time_information,
system_module_information,
system_locks_information,
system_stack_trace_information,
system_paged_pool_information,
system_non_paged_pool_information,
system_handle_information,
system_object_information,
system_page_file_information,
system_vdm_instemul_information,
system_vdm_bop_information,
system_file_cache_information,
system_pool_tag_information,
system_interrupt_information,
system_dpc_behavior_information,
system_full_memory_information,
system_load_gdi_driver_information,
system_unload_gdi_driver_information,
system_time_adjustment_information,
system_summary_memory_information,
system_next_event_id_information,
system_event_ids_information,
system_crash_dump_information,
system_exception_information,
system_crash_dump_state_information,
system_kernel_debugger_information,
system_context_switch_information,
system_registry_quota_information,
system_extend_service_table_information,
system_priority_seperation,
system_plug_play_bus_information,
system_dock_information,
system_processor_speed_information,
system_current_time_zone_information,
system_lookaside_information,
system_bigpool_information = 0x42
} SYSTEM_INFORMATION_CLASS, * PSYSTEM_INFORMATION_CLASS;
#pragma once
#define _STDINT

#ifndef RC_INVOKED
typedef signed char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long long int64_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;

typedef signed char int_least8_t;
typedef short int_least16_t;
typedef int int_least32_t;
typedef long long int_least64_t;
typedef unsigned char uint_least8_t;
typedef unsigned short uint_least16_t;
typedef unsigned int uint_least32_t;
typedef unsigned long long uint_least64_t;

typedef signed char int_fast8_t;
typedef int int_fast16_t;
typedef int int_fast32_t;
typedef long long int_fast64_t;
typedef unsigned char uint_fast8_t;
typedef unsigned int uint_fast16_t;
typedef unsigned int uint_fast32_t;
typedef unsigned long long uint_fast64_t;

typedef long long intmax_t;
typedef unsigned long long uintmax_t;

// These macros must exactly match those in the Windows SDK's intsafe.h.
#define INT8_MIN (-127i8 - 1)
#define INT16_MIN (-32767i16 - 1)
#define INT32_MIN (-2147483647i32 - 1)
#define INT64_MIN (-9223372036854775807i64 - 1)
#define INT8_MAX 127i8
#define INT16_MAX 32767i16
#define INT32_MAX 2147483647i32
#define INT64_MAX 9223372036854775807i64
#define UINT8_MAX 0xffui8
#define UINT16_MAX 0xffffui16
#define UINT32_MAX 0xffffffffui32
#define UINT64_MAX 0xffffffffffffffffui64

#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX

#define INT_FAST8_MIN INT8_MIN
#define INT_FAST16_MIN INT32_MIN
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MAX INT32_MAX
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT32_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX

#ifdef _WIN64
#define INTPTR_MIN INT64_MIN
#define INTPTR_MAX INT64_MAX
#define UINTPTR_MAX UINT64_MAX
#else
#define INTPTR_MIN INT32_MIN
#define INTPTR_MAX INT32_MAX
#define UINTPTR_MAX UINT32_MAX
#endif

#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX

#define PTRDIFF_MIN INTPTR_MIN
#define PTRDIFF_MAX INTPTR_MAX

#ifndef SIZE_MAX
#define SIZE_MAX UINTPTR_MAX
#endif

#define SIG_ATOMIC_MIN INT32_MIN
#define SIG_ATOMIC_MAX INT32_MAX

#define WCHAR_MIN 0x0000
#define WCHAR_MAX 0xffff

#define WINT_MIN 0x0000
#define WINT_MAX 0xffff

#define INT8_C(x) (x)
#define INT16_C(x) (x)
#define INT32_C(x) (x)
#define INT64_C(x) (x ## LL)

#define UINT8_C(x) (x)
#define UINT16_C(x) (x)
#define UINT32_C(x) (x ## U)
#define UINT64_C(x) (x ## ULL)

#define INTMAX_C(x) INT64_C(x)
#define UINTMAX_C(x) UINT64_C(x)

#endif // RC_INVOKED

#define dbg( content, ... ) DbgPrintEx( 0, 0, "[>] " content, VA_ARGS )
#pragma once

NTKERNELAPI
NTSTATUS
PsLookupProcessByProcessId(
IN HANDLE ProcessId,
OUT PEPROCESS Process
);


NTKERNELAPI
PVOID PsGetProcessSectionBaseAddress(
IN PEPROCESS Process
);

__declspec(dllimport) NTSTATUS __stdcall ZwQuerySystemInformation(SYSTEM_INFORMATION_CLASS, void*, unsigned long, unsigned long*);
#include <ntddk.h>
#include <minwindef.h>
#include "structs.h"
#include "myntapi.h"
#include "imports.h"
#include "custom_crt.h"
#include "physmem.h"

// IMPORTANT TODO: Make a global to cache/store the directory base for the physical read/write calls.

void MainThread()
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;

// TODO: Find more dynamic way to find the process, maybe query thru all processes and find our one with some unique traits
DWORD64 ProcessId = GetProcessIdFromName(L"Usermode.exe");
dbg("ProcessId: %llu", ProcessId);

for (;;)
{
while (ProcessId == 0)
ProcessId = GetProcessIdFromName(L"Usermode.exe");

PEPROCESS MyProcess;

Status = PsLookupProcessByProcessId(ProcessId, &MyProcess);

if (!NT_SUCCESS(Status))
break;

PVOID ImageBase = PsGetProcessSectionBaseAddress(MyProcess);

MyStructure ReadStruct;


// TODO: Try replacing it with MmCopyVirtualMemory for more optimisation/speed?
// TODO: Find more dynamic way to find the address
size_t Size = 0;
ReadProcessMemory(ProcessId, (uintptr_t)ImageBase + 0x3630 /* Hard coded offset to the MyStruct StructureInit global in the usermode application, changes sometimes due to compiler*/, &ReadStruct, sizeof(MyStructure), &Size);

// TODO: Use switch cases
if (ReadStruct.RequestID == ReadMemoryCode) {
dbg("ReadMemory Called!");
}
else if (ReadStruct.RequestID == WriteMemoryCode) {
dbg("WriteMemory Called!");
}
}
}

NTSTATUS DriverEntry(In PDRIVER_OBJECT Param1, In PUNICODE_STRING Param2)
{
UNREFERENCED_PARAMETER(Param1); UNREFERENCED_PARAMETER(Param2);

dbg("At entry!");

HANDLE thread_handle = NULL;
OBJECT_ATTRIBUTES object_attribues;
InitializeObjectAttributes(&object_attribues, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

// Hide system thread https://secret.club/2021/01/12/callout.html and more or just don't use thread tbh
NTSTATUS status = PsCreateSystemThread(&thread_handle, 0, &object_attribues, NULL, NULL, &MainThread, NULL);

return STATUS_SUCCESS;
}
#pragma once

SIZE_T RlStrlen(PCHAR input) {
SIZE_T output = 0;
while (input) {
output++;
input++;
}
return output;
}

BOOL RlStrcmp(PCHAR string1, PCHAR string2) {
if (RlStrlen(string1) != RlStrlen(string2)) {
return FALSE;
}

SIZE_T string1iteration = 0;
for (SIZE_T string2iteration = 0; string2iteration < RlStrlen(string2); string2iteration++) {
if ((string1 + string1iteration) != (string2 + string2iteration)) {
return FALSE;
}

string1iteration++;
}

return TRUE;
}

WCHAR RlWideCharToLower(WCHAR c) {
if (c < 0x100)
{
if ((c >= 0x0041 && c <= 0x005a) ||
(c >= 0x00c0 && c <= 0x00de))
return (c + 0x20);
if (c == 0x00b5)
return 0x03bc;

return c;
}
else if (c < 0x300)
{
if ((c >= 0x0100 && c <= 0x012e) ||
(c >= 0x0132 && c <= 0x0136) ||
(c >= 0x014a && c <= 0x0176) ||
(c >= 0x01de && c <= 0x01ee) ||
(c >= 0x01f8 && c <= 0x021e) ||
(c >= 0x0222 && c <= 0x0232))
{
if (!(c & 0x01))
return (c + 1);
return c;
}
if ((c >= 0x0139 && c <= 0x0147) ||
(c >= 0x01cd && c <= 0x91db))
{
if (c & 0x01)
return (c + 1);
return c;
}

if (c >= 0x178 && c <= 0x01f7)
{
wint_t k;
switch (c)
{
case 0x0178:
k = 0x00ff;
break;
case 0x0179:
case 0x017b:
case 0x017d:
case 0x0182:
case 0x0184:
case 0x0187:
case 0x018b:
case 0x0191:
case 0x0198:
case 0x01a0:
case 0x01a2:
case 0x01a4:
case 0x01a7:
case 0x01ac:
case 0x01af:
case 0x01b3:
case 0x01b5:
case 0x01b8:
case 0x01bc:
case 0x01c5:
case 0x01c8:
case 0x01cb:
case 0x01cd:
case 0x01cf:
case 0x01d1:
case 0x01d3:
case 0x01d5:
case 0x01d7:
case 0x01d9:
case 0x01db:
case 0x01f2:
case 0x01f4:
k = c + 1;
break;
case 0x017f:
k = 0x0073;
break;
case 0x0181:
k = 0x0253;
break;
case 0x0186:
k = 0x0254;
break;
case 0x0189:
k = 0x0256;
break;
case 0x018a:
k = 0x0257;
break;
case 0x018e:
k = 0x01dd;
break;
case 0x018f:
k = 0x0259;
break;
case 0x0190:
k = 0x025b;
break;
case 0x0193:
k = 0x0260;
break;
case 0x0194:
k = 0x0263;
break;
case 0x0196:
k = 0x0269;
break;
case 0x0197:
k = 0x0268;
break;
case 0x019c:
k = 0x026f;
break;
case 0x019d:
k = 0x0272;
break;
case 0x019f:
k = 0x0275;
break;
case 0x01a6:
k = 0x0280;
break;
case 0x01a9:
k = 0x0283;
break;
case 0x01ae:
k = 0x0288;
break;
case 0x01b1:
k = 0x028a;
break;
case 0x01b2:
k = 0x028b;
break;
case 0x01b7:
k = 0x0292;
break;
case 0x01c4:
case 0x01c7:
case 0x01ca:
case 0x01f1:
k = c + 2;
break;
case 0x01f6:
k = 0x0195;
break;
case 0x01f7:
k = 0x01bf;
break;
default:
k = 0;
}
if (k != 0)
return k;
}
if (c == 0x0220)
return 0x019e;
}
else if (c < 0x0400)
{
if (c >= 0x0391 && c <= 0x03ab && c != 0x03a2)
return (c + 0x20);
if (c >= 0x03d8 && c <= 0x03ee && !(c & 0x01))
return (c + 1);
if (c >= 0x0386 && c <= 0x03f5)
{
wint_t k;
switch (c)
{
case 0x0386:
k = 0x03ac;
break;
case 0x0388:
k = 0x03ad;
break;
case 0x0389:
k = 0x03ae;
break;
case 0x038a:
k = 0x03af;
break;
case 0x038c:
k = 0x03cc;
break;
case 0x038e:
k = 0x03cd;
break;
case 0x038f:
k = 0x038f;
break;
case 0x03c2:
k = 0x03c3;
break;
case 0x03d0:
k = 0x03b2;
break;
case 0x03d1:
k = 0x03b8;
break;
case 0x03d5:
k = 0x03c6;
break;
case 0x03d6:
k = 0x03c0;
break;
case 0x03f0:
k = 0x03ba;
break;
case 0x03f1:
k = 0x03c1;
break;
case 0x03f2:
k = 0x03c3;
break;
case 0x03f4:
k = 0x03b8;
break;
case 0x03f5:
k = 0x03b5;
break;
default:
k = 0;
}
if (k != 0)
return k;
}
if (c == 0x0345)
return 0x03b9;
}
else if (c < 0x500)
{
if (c >= 0x0400 && c <= 0x040f)
return (c + 0x50);

if (c >= 0x0410 && c <= 0x042f)
return (c + 0x20);

if ((c >= 0x0460 && c <= 0x0480) ||
(c >= 0x048a && c <= 0x04be) ||
(c >= 0x04d0 && c <= 0x04f4) ||
(c == 0x04f8))
{
if (!(c & 0x01))
return (c + 1);
return c;
}

if (c >= 0x04c1 && c <= 0x04cd)
{
if (c & 0x01)
return (c + 1);
return c;
}
}
else if (c < 0x1f00)
{
if ((c >= 0x0500 && c <= 0x050e) ||
(c >= 0x1e00 && c <= 0x1e94) ||
(c >= 0x1ea0 && c <= 0x1ef8))
{
if (!(c & 0x01))
return (c + 1);
return c;
}

if (c >= 0x0531 && c <= 0x0556)
return (c + 0x30);
if (c == 0x1e9b)
return 0x1e61;
}
else if (c < 0x2000)
{
if ((c >= 0x1f08 && c <= 0x1f0f) ||
(c >= 0x1f18 && c <= 0x1f1d) ||
(c >= 0x1f28 && c <= 0x1f2f) ||
(c >= 0x1f38 && c <= 0x1f3f) ||
(c >= 0x1f48 && c <= 0x1f4d) ||
(c >= 0x1f68 && c <= 0x1f6f) ||
(c >= 0x1f88 && c <= 0x1f8f) ||
(c >= 0x1f98 && c <= 0x1f9f) ||
(c >= 0x1fa8 && c <= 0x1faf))
return (c - 0x08);
if (c >= 0x1f59 && c <= 0x1f5f)
{
if (c & 0x01)
return (c - 0x08);
return c;
}

if (c >= 0x1fb8 && c <= 0x1ffc)
{
wint_t k;
switch (c)
{
case 0x1fb8:
case 0x1fb9:
case 0x1fd8:
case 0x1fd9:
case 0x1fe8:
case 0x1fe9:
k = c - 0x08;
break;
case 0x1fba:
case 0x1fbb:
k = c - 0x4a;
break;
case 0x1fbc:
k = 0x1fb3;
break;
case 0x1fbe:
k = 0x03b9;
break;
case 0x1fc8:
case 0x1fc9:
case 0x1fca:
case 0x1fcb:
k = c - 0x56;
break;
case 0x1fcc:
k = 0x1fc3;
break;
case 0x1fda:
case 0x1fdb:
k = c - 0x64;
break;
case 0x1fea:
case 0x1feb:
k = c - 0x70;
break;
case 0x1fec:
k = 0x1fe5;
break;
case 0x1ffa:
case 0x1ffb:
k = c - 0x7e;
break;
case 0x1ffc:
k = 0x1ff3;
break;
default:
k = 0;
}
if (k != 0)
return k;
}
}
else
{
if (c >= 0x2160 && c <= 0x216f)
return (c + 0x10);

if (c >= 0x24b6 && c <= 0x24cf)
return (c + 0x1a);

if (c >= 0xff21 && c <= 0xff3a)
return (c + 0x20);

if (c >= 0x10400 && c <= 0x10425)
return (c + 0x28);
if (c == 0x2126)
return 0x03c9;
if (c == 0x212a)
return 0x006b;
if (c == 0x212b)
return 0x00e5;
}
return c;
}

SIZE_T RlWcslen(PWCHAR input) {
SIZE_T output = 0;
while (input) {
output++;
input++;
}
return output;
}

BOOL RlWcsicmp(PWCHAR string1, PWCHAR string2, BOOL CaseInsensitive) {
if (RlWcslen(string1) != RlWcslen(string2)) {
return FALSE;
}

SIZE_T string1iteration = 0;
for (SIZE_T string2iteration = 0; string2iteration < RlWcslen(string2); string2iteration++) {
if (CaseInsensitive) {
if (RlWideCharToLower((string1 + string1iteration)) != RlWideCharToLower((string2 + string2iteration))) {
return FALSE;
}
}
else {
if ((string1 + string1iteration) != (string2 + string2iteration)) {
return FALSE;
}
}

string1iteration++;
}

return TRUE;
}

void RlInitUnicodeString(PUNICODE_STRING Destination, LPCWSTR Source) { // mostly copy-pasty from ReactOS source code
SIZE_T Size;
CONST SIZE_T MaxSize = (MAXUSHORT & ~1) - sizeof(UNICODE_NULL);

if (Source) {
Size = RlWcslen((PWCHAR)Source) * sizeof(WCHAR);

if (Size > MaxSize)
Size = MaxSize;
Destination->Length = (USHORT)Size;
Destination->MaximumLength = (USHORT)Size + sizeof(UNICODE_NULL);
}
else
{
Destination->Length = 0;
Destination->MaximumLength = 0;
}

Destination->Buffer = (PWCHAR)Source;
}

BOOL RlCopyMemory(PVOID source, PVOID destination, SIZE_T length) {
if (source == NULL || destination == NULL || length == 0) {
return FALSE;
}

for (int i = 0; i < length; i++) {
(PBYTE)((SIZE_T)destination + i) = (PBYTE)((SIZE_T)source + i);
}

return TRUE;
}

void RlMemcpy(PVOID dest, const void src, size_t len)
{
PCHAR d = (PCHAR)dest;
const char s = (PCHAR)src;
while (len--)
d++ = s++;
return dest;
}

void RlWcscpy(PWSTR dest, const WCHAR src)
{
if (dest == NULL || src == NULL) {
return NULL;
}
while (dest++ = src++); / {
dest = src;
dest++;
src++;
}/

return dest;
}


char RlStrcpy(char dest, const char src)
{
char* String = dest;

/* Move bytes brute force */

while (*src)
{
*String = src;

String++;
src++;
}

/ Null terminate /

String = 0;
return (dest);
}

void RlWcscat(PWSTR dest, PWSTR src) {
if (dest == NULL || src == NULL) {
return NULL;
}
/while (dest)
dest++;
while (src)
dest++ = src++;/
RlWcscpy(dest + RlWcslen(dest), src);
return dest;
}

char RlStrcat(char DstString, const char SrcString) {
char String;

/ Find end of the destination string /
for (String = DstString; String++; )
{
;
}

/ Concatenate the string /
for (--String; (String++ = SrcString++); )
{
;
}

return (DstString);
}

char RlStrchr(const char String, int ch) {
for (; (String); String++)
{
if ((String) == (char)ch)
{
return ((char)String);
}
}

return (NULL);
}

BOOL RlStringsEndsWith(PCHAR targetStringAddr, LPCSTR ending) {
SIZE_T targetStringLength = RlStrlen(targetStringAddr);
SIZE_T endingStringLength = RlStrlen((PCHAR)ending);

if (targetStringLength >= endingStringLength) {
targetStringAddr = (PCHAR)((SIZE_T)targetStringAddr + targetStringLength - endingStringLength);
for (int i = 0; i < endingStringLength; i++) {
CHAR currentTargetStringChar = (PCHAR)((SIZE_T)targetStringAddr + i);
if (currentTargetStringChar != ending[i]) {
return FALSE;
}
}
//return (strcmp(targetStringAddr, ending) == 0);
}
else {
return FALSE;
}

return TRUE;
}

BOOL RlStringsStartsWith(PCHAR targetStringAddr, LPCSTR starting) {
SIZE_T targetStringLength = RlStrlen(targetStringAddr);
SIZE_T startingStringLength = RlStrlen((PCHAR)starting);

if (targetStringLength >= startingStringLength) {
for (int i = 0; i < startingStringLength; i++) {
CHAR currentTargetStringChar = (PCHAR)((SIZE_T)targetStringAddr + i);
if (currentTargetStringChar != starting[i]) {
return FALSE;
}
}
}
else {
return FALSE;
}

return TRUE;
}

void RlAnsiToWideChar(PCHAR Ansi, PWCHAR Wide) {
SIZE_T len = RlStrlen(Ansi);

for (int i = 0; i < len; i++)
Wide[i] = (WCHAR)Ansi[i];

Wide[len] = '\0';
}

char RlStrStrA(char string, char substring) {
const char a, * b;

/ First scan quickly through the two strings looking for a
* single-character match. When it's found, then compare the
* rest of the substring.
*/

b = substring;

if (b == 0)
{
return (char)string;
}

for (; *string != 0; string += 1)
{
if (*string != *b)
{
continue;
}

a = string;

while (1)
{
if (b == 0)
{
return (char)string;
}
if (*a++ != *b++)
{
break;
}
}

b = substring;
}

return NULL;
}

explain the code