windows-nt/Source/XPSP1/NT/drivers/ddk/wdmaudio/ddksynth/kernhelp.cpp
2020-09-26 16:20:57 +08:00

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;
}