/* Copyright (c) 1998-2000 Microsoft Corporation. All rights reserved. */ // // KernHelp.cpp // // Wrappers for kernel functions to make synth core cross compilable // #define STR_MODULENAME "DDKSynth.sys:KernHelp: " extern "C" { #include }; #include "ksdebug.h" #include "KernHelp.h" #pragma code_seg() /***************************************************************************** * InitializeCriticalSection() ***************************************************************************** * In kernel mode, we use a KMUTEX to implement our critical section. * Initialize the KMUTEX. */ VOID InitializeCriticalSection(LPCRITICAL_SECTION CritSect) { KeInitializeMutex((PKMUTEX)CritSect, 1); } /***************************************************************************** * EnterCriticalSection() ***************************************************************************** * In kernel mode, we use a KMUTEX to implement our critical section. * Grab (wait for) the KMUTEX. */ VOID EnterCriticalSection(LPCRITICAL_SECTION CritSect) { KeWaitForSingleObject((PKMUTEX)CritSect, Executive, KernelMode, FALSE, 0); } /***************************************************************************** * LeaveCriticalSection() ***************************************************************************** * In kernel mode, we use a KMUTEX to implement our critical section. * Release the KMUTEX. */ VOID LeaveCriticalSection(LPCRITICAL_SECTION CritSect) { KeReleaseMutex((PKMUTEX)CritSect, FALSE); } /***************************************************************************** * DeleteCriticalSection() ***************************************************************************** * In kernel mode, we use a KMUTEX to implement our critical section. * No need to delete anything. */ VOID DeleteCriticalSection(LPCRITICAL_SECTION CritSect) { // NOP in kernel // } // GetRegValueDword // // Must be called at passive level // /***************************************************************************** * GetRegValueDword() ***************************************************************************** * Convenience function to encapsulate registry reads. */ int GetRegValueDword(LPTSTR RegPath,LPTSTR ValueName,PULONG Value) { int ReturnValue = 0; NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE KeyHandle; KEY_VALUE_PARTIAL_INFORMATION *Information; ULONG InformationSize; UNICODE_STRING UnicodeRegPath; UNICODE_STRING UnicodeValueName; RtlInitUnicodeString(&UnicodeRegPath, RegPath); RtlInitUnicodeString(&UnicodeValueName, ValueName); InitializeObjectAttributes(&ObjectAttributes, &UnicodeRegPath, OBJ_KERNEL_HANDLE, // Flags NULL, // Root directory NULL); // Security descriptor Status = ZwOpenKey(&KeyHandle, KEY_QUERY_VALUE, &ObjectAttributes); if (Status != STATUS_SUCCESS) { return 0; } InformationSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG); Information = (KEY_VALUE_PARTIAL_INFORMATION*)ExAllocatePoolWithTag(PagedPool, InformationSize,'ISmD'); // DmSI if (Information == NULL) { ZwClose(KeyHandle); return 0; } Status = ZwQueryValueKey(KeyHandle, &UnicodeValueName, KeyValuePartialInformation, Information, sizeof(Information), &InformationSize); if (Status == STATUS_SUCCESS) { if (Information->Type == REG_DWORD && Information->DataLength == sizeof(ULONG)) { RtlCopyMemory(Value, Information->Data, sizeof(ULONG)); ReturnValue = 1; } } ExFreePool(Information); ZwClose(KeyHandle); return ReturnValue; } /***************************************************************************** * GetTheCurrentTime() ***************************************************************************** * Get the current time, in milliseconds (KeQuerySystemTime returns units of * 100ns each). */ ULONG GetTheCurrentTime() { LARGE_INTEGER Time; KeQuerySystemTime(&Time); return (ULONG)(Time.QuadPart / (10 * 1000)); } /***************************************************************************** * KernHelpGetSysAddrForMdl() ***************************************************************************** * Safely map the MDL to system address space. This mapping * may fail "when the system runs out of system PTEs", and * without the flag set below, this condition causes a bugcheck * rather than a NULL return. */ PVOID KernHelpGetSysAddrForMdl(PMDL pMdl) { PVOID MappedAddress; #if UNDER_NT MappedAddress = MmGetSystemAddressForMdlSafe(pMdl,NormalPagePriority); #else // !UNDER_NT CSHORT LocalCopyOfMdlFlagBit; // // Note the manipulation of the MDL flags is only done if needed. // The driver is responsible for ensuring that it is not simultaneously // modifying this field anywhere else and synchronizing if needed. // LocalCopyOfMdlFlagBit = (pMdl->MdlFlags & MDL_MAPPING_CAN_FAIL); if (LocalCopyOfMdlFlagBit == 0) { pMdl->MdlFlags |= MDL_MAPPING_CAN_FAIL; } MappedAddress = MmGetSystemAddressForMdl(pMdl); // // Carefully restore only the single "can-fail" bit state. This is // because the call above will change the state of other flag bits and // we don't want this restore to wipe out those changes. Wiping out the // other changes will cause not-so-obvious effects like eventually // exhausting the system PTE pool and other resources, which will crash // the entire system. // if (LocalCopyOfMdlFlagBit == 0) { pMdl->MdlFlags &= ~MDL_MAPPING_CAN_FAIL; } #endif // !UNDER_NT return MappedAddress; }