205 lines
6.2 KiB
C++
205 lines
6.2 KiB
C++
|
/*
|
||
|
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 <wdm.h>
|
||
|
};
|
||
|
|
||
|
#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;
|
||
|
}
|
||
|
|