[WDF] Add Windows Driver Framework files

Takern from Microsoft GitHub repo:
d9c6040fe9

Licensed under MIT
This commit is contained in:
Victor Perevertkin 2020-09-24 23:51:15 +03:00
parent 545df81502
commit 8a978a179f
No known key found for this signature in database
GPG key ID: C750B7222E9C7830
475 changed files with 285099 additions and 0 deletions

View file

@ -0,0 +1,189 @@
/*++
Copyright (c) Microsoft Corporation
ModuleName:
MxDeviceObjectKm.h
Abstract:
Kernel Mode implementation of Device Object defined in MxDeviceObject.h
--*/
#pragma once
#include "MxDeviceObject.h"
__inline
CCHAR
MxDeviceObject::GetStackSize(
VOID
)
{
return m_DeviceObject->StackSize;
}
__inline
VOID
MxDeviceObject::SetStackSize(
_In_ CCHAR Size
)
{
m_DeviceObject->StackSize = Size;
}
__inline
VOID
MxDeviceObject::ReferenceObject(
)
{
ObReferenceObject(m_DeviceObject);
}
__inline
MdDeviceObject
MxDeviceObject::GetAttachedDeviceReference(
VOID
)
{
return IoGetAttachedDeviceReference(m_DeviceObject);
}
__inline
VOID
MxDeviceObject::DereferenceObject(
)
{
ObDereferenceObject(m_DeviceObject);
}
__inline
ULONG
MxDeviceObject::GetFlags(
VOID
)
{
#pragma warning(disable:28129)
return m_DeviceObject->Flags;
}
__inline
VOID
MxDeviceObject::SetFlags(
ULONG Flags
)
{
#pragma warning(disable:28129)
m_DeviceObject->Flags = Flags;
}
__inline
POWER_STATE
MxDeviceObject::SetPowerState(
__in POWER_STATE_TYPE Type,
__in POWER_STATE State
)
{
return PoSetPowerState(m_DeviceObject, Type, State);
}
__inline
VOID
MxDeviceObject::InvalidateDeviceRelations(
__in DEVICE_RELATION_TYPE Type
)
{
IoInvalidateDeviceRelations(m_DeviceObject, Type);
}
__inline
VOID
MxDeviceObject::InvalidateDeviceState(
__in MdDeviceObject Fdo
)
{
//
// UMDF currently needs Fdo for InvalidateDeviceState
// FDO is not used in km.
//
// m_DeviceObject holds PDO that is what is used below.
//
UNREFERENCED_PARAMETER(Fdo);
IoInvalidateDeviceState(m_DeviceObject);
}
__inline
PVOID
MxDeviceObject::GetDeviceExtension(
VOID
)
{
return m_DeviceObject->DeviceExtension;
}
__inline
VOID
MxDeviceObject::SetDeviceExtension(
PVOID Value
)
{
m_DeviceObject->DeviceExtension = Value;
}
__inline
DEVICE_TYPE
MxDeviceObject::GetDeviceType(
VOID
)
{
return m_DeviceObject->DeviceType;
}
__inline
ULONG
MxDeviceObject::GetCharacteristics(
VOID
)
{
return m_DeviceObject->Characteristics;
}
__inline
VOID
MxDeviceObject::SetDeviceType(
DEVICE_TYPE Value
)
{
m_DeviceObject->DeviceType = Value;
}
__inline
VOID
MxDeviceObject::SetCharacteristics(
ULONG Characteristics
)
{
m_DeviceObject->Characteristics = Characteristics;
}
__inline
VOID
MxDeviceObject::SetAlignmentRequirement(
_In_ ULONG Value
)
{
m_DeviceObject->AlignmentRequirement = Value;
}
__inline
ULONG
MxDeviceObject::GetAlignmentRequirement(
VOID
)
{
return m_DeviceObject->AlignmentRequirement;
}

View file

@ -0,0 +1,72 @@
/*++
Copyright (c) Microsoft Corporation
ModuleName:
MxDriverObjectKm.h
Abstract:
Kernel Mode implementation of Driver Object defined in MxDriverObject.h
--*/
#pragma once
typedef DRIVER_ADD_DEVICE MdDriverAddDeviceType, *MdDriverAddDevice;
typedef DRIVER_UNLOAD MdDriverUnloadType, *MdDriverUnload;
typedef DRIVER_DISPATCH MdDriverDispatchType, *MdDriverDispatch;
#include "MxDriverObject.h"
__inline
PVOID
MxDriverObject::GetDriverExtensionAddDevice(
VOID
)
{
return m_DriverObject->DriverExtension->AddDevice;
}
__inline
VOID
MxDriverObject::SetDriverExtensionAddDevice(
_In_ MdDriverAddDevice Value
)
{
m_DriverObject->DriverExtension->AddDevice = Value;
}
__inline
MdDriverUnload
MxDriverObject::GetDriverUnload(
VOID
)
{
return m_DriverObject->DriverUnload;
}
__inline
VOID
MxDriverObject::SetDriverUnload(
_In_ MdDriverUnload Value
)
{
m_DriverObject->DriverUnload = Value;
}
__inline
VOID
MxDriverObject::SetMajorFunction(
_In_ UCHAR i,
_In_ MdDriverDispatch Value
)
{
m_DriverObject->MajorFunction[i] = Value;
}

View file

@ -0,0 +1,148 @@
/*++
Copyright (c) Microsoft Corporation
ModuleName:
MxEvent.h
Abstract:
Kernel mode implementation of event
class defined in MxEvent.h
Author:
Revision History:
--*/
#pragma once
typedef KEVENT MdEvent;
#include "MxEvent.h"
__inline
MxEvent::MxEvent()
{
//
// Make sure that m_Event is the first member. That way if someone passes
// address of MxEvent to Ke*Event functions, it would still work.
//
// If this statement causes compilation failure, check if you added a field
// before m_Event.
//
C_ASSERT(FIELD_OFFSET(MxEvent, m_Event) == 0);
CLEAR_DBGFLAG_INITIALIZED;
}
__inline
MxEvent::~MxEvent()
{
}
__inline
NTSTATUS
#pragma prefast(suppress:__WARNING_UNMATCHED_DECL_ANNO, "_Must_inspect_result_ not needed in kernel mode as the function always succeeds");
MxEvent::Initialize(
__in EVENT_TYPE Type,
__in BOOLEAN InitialState
)
{
KeInitializeEvent(&m_Event, Type, InitialState);
SET_DBGFLAG_INITIALIZED;
return STATUS_SUCCESS;
}
__inline
PVOID
MxEvent::GetEvent(
)
{
ASSERT_DBGFLAG_INITIALIZED;
return &m_Event;
}
__inline
VOID
MxEvent::SetWithIncrement(
__in KPRIORITY Priority
)
{
ASSERT_DBGFLAG_INITIALIZED;
KeSetEvent(&m_Event, Priority, FALSE);
}
__inline
VOID
MxEvent::Set(
)
{
ASSERT_DBGFLAG_INITIALIZED;
KeSetEvent(&m_Event, IO_NO_INCREMENT, FALSE);
}
__inline
VOID
MxEvent::Clear(
)
{
ASSERT_DBGFLAG_INITIALIZED;
KeClearEvent(&m_Event);
}
__drv_when(Timeout == NULL && Alertable == FALSE, __drv_valueIs(==0))
__drv_when(Timeout != NULL && Alertable == FALSE, __drv_valueIs(==0;==258))
__drv_when(Timeout != NULL || Alertable == TRUE, _Must_inspect_result_)
__inline
NTSTATUS
MxEvent::WaitFor(
__in KWAIT_REASON WaitReason,
__in KPROCESSOR_MODE WaitMode,
__in BOOLEAN Alertable,
__in_opt PLARGE_INTEGER Timeout
)
{
ASSERT_DBGFLAG_INITIALIZED;
return KeWaitForSingleObject(
&m_Event,
WaitReason,
WaitMode,
Alertable,
Timeout
);
}
LONG
__inline
MxEvent::ReadState(
)
{
ASSERT_DBGFLAG_INITIALIZED;
return KeReadStateEvent(&m_Event);
}
__inline
VOID
MxEvent::Uninitialize(
)
{
CLEAR_DBGFLAG_INITIALIZED;
}

View file

@ -0,0 +1,82 @@
/*++
Copyright (c) Microsoft Corporation
ModuleName:
MxFileObjectKm.h
Abstract:
Kernel Mode implementation of File Object defined in MxFileObject.h
--*/
#pragma once
#include "MxFileObject.h"
__inline
PUNICODE_STRING
MxFileObject::GetFileName(
_Inout_opt_ PUNICODE_STRING Filename
)
{
UNREFERENCED_PARAMETER(Filename);
return &m_FileObject->FileName;
}
__inline
PLARGE_INTEGER
MxFileObject::GetCurrentByteOffset(
VOID
)
{
return &m_FileObject->CurrentByteOffset;
}
__inline
ULONG
MxFileObject::GetFlags(
VOID
)
{
return m_FileObject->Flags;
}
__inline
VOID
MxFileObject::SetFsContext(
_In_ PVOID Value
)
{
m_FileObject->FsContext = Value;
}
__inline
VOID
MxFileObject::SetFsContext2(
_In_ PVOID Value
)
{
m_FileObject->FsContext2 = Value;
}
__inline
PVOID
MxFileObject::GetFsContext(
VOID
)
{
return m_FileObject->FsContext;
}
__inline
PVOID
MxFileObject::GetFsContext2(
VOID
)
{
return m_FileObject->FsContext2;
}

View file

@ -0,0 +1,778 @@
/*++
Copyright (c) Microsoft Corporation
ModuleName:
MxGeneralKm.h
Abstract:
Kernel mode implementation for general OS
functions defined in MxGeneral.h
Author:
Revision History:
--*/
#pragma once
#define MAKE_MX_FUNC_NAME(x) L##x
typedef LPCWSTR MxFuncName;
typedef PKTHREAD MxThread;
typedef PETHREAD MdEThread;
typedef PDEVICE_OBJECT MdDeviceObject;
typedef PDRIVER_OBJECT MdDriverObject;
typedef PFILE_OBJECT MdFileObject;
typedef PIO_REMOVE_LOCK MdRemoveLock;
typedef PCALLBACK_OBJECT MdCallbackObject;
typedef CALLBACK_FUNCTION MdCallbackFunctionType, *MdCallbackFunction;
typedef PKINTERRUPT MdInterrupt;
typedef KSERVICE_ROUTINE MdInterruptServiceRoutineType, *MdInterruptServiceRoutine;
typedef KSYNCHRONIZE_ROUTINE MdInterruptSynchronizeRoutineType, *MdInterruptSynchronizeRoutine;
#include "MxGeneral.h"
#include <ntstrsafe.h>
__inline
BOOLEAN
Mx::IsUM(
)
{
return FALSE;
}
__inline
BOOLEAN
Mx::IsKM(
)
{
return TRUE;
}
__inline
MxThread
Mx::MxGetCurrentThread(
)
{
return KeGetCurrentThread();
}
__inline
MdEThread
Mx::GetCurrentEThread(
)
{
return PsGetCurrentThread();
}
__inline
NTSTATUS
Mx::MxTerminateCurrentThread(
__in NTSTATUS Status
)
{
return PsTerminateSystemThread(Status);
}
__inline
KIRQL
Mx::MxGetCurrentIrql(
)
{
return KeGetCurrentIrql();
}
__drv_maxIRQL(HIGH_LEVEL)
__drv_raisesIRQL(NewIrql)
__inline
VOID
Mx::MxRaiseIrql(
__in KIRQL NewIrql,
__out __deref __drv_savesIRQL PKIRQL OldIrql
)
{
KeRaiseIrql(NewIrql, OldIrql);
}
__drv_maxIRQL(HIGH_LEVEL)
__inline
VOID
Mx::MxLowerIrql(
__in __drv_restoresIRQL __drv_nonConstant KIRQL NewIrql
)
{
KeLowerIrql(NewIrql);
}
__inline
VOID
Mx::MxQueryTickCount(
__out PLARGE_INTEGER TickCount
)
{
KeQueryTickCount(TickCount);
}
__inline
ULONG
Mx::MxQueryTimeIncrement(
)
{
return KeQueryTimeIncrement();
}
__inline
VOID
Mx::MxBugCheckEx(
__in ULONG BugCheckCode,
__in ULONG_PTR BugCheckParameter1,
__in ULONG_PTR BugCheckParameter2,
__in ULONG_PTR BugCheckParameter3,
__in ULONG_PTR BugCheckParameter4
)
{
#pragma prefast(suppress:__WARNING_USE_OTHER_FUNCTION, "KeBugCheckEx is the intent.");
KeBugCheckEx(
BugCheckCode,
BugCheckParameter1,
BugCheckParameter2,
BugCheckParameter3,
BugCheckParameter4
);
}
__inline
VOID
Mx::MxDbgBreakPoint(
)
{
DbgBreakPoint();
}
__inline
VOID
Mx::MxAssert(
__in BOOLEAN Condition
)
{
UNREFERENCED_PARAMETER(Condition);
ASSERT(Condition); //this get defined as RtlAssert
}
__inline
VOID
Mx::MxAssertMsg(
__in LPSTR Message,
__in BOOLEAN Condition
)
{
UNREFERENCED_PARAMETER(Message);
UNREFERENCED_PARAMETER(Condition);
ASSERTMSG(Message, Condition);
}
_Acquires_lock_(_Global_critical_region_)
__inline
VOID
Mx::MxEnterCriticalRegion(
)
{
KeEnterCriticalRegion();
}
_Releases_lock_(_Global_critical_region_)
__inline
VOID
Mx::MxLeaveCriticalRegion(
)
{
KeLeaveCriticalRegion();
}
__inline
VOID
Mx::MxDelayExecutionThread(
__in KPROCESSOR_MODE WaitMode,
__in BOOLEAN Alertable,
__in PLARGE_INTEGER Interval
)
{
ASSERTMSG("Interval must be relative\n", Interval->QuadPart <= 0);
KeDelayExecutionThread(
WaitMode,
Alertable,
Interval
);
}
__inline
PVOID
Mx::MxGetSystemRoutineAddress(
__in MxFuncName FuncName
)
{
UNICODE_STRING funcName;
RtlInitUnicodeString(&funcName, FuncName);
return MmGetSystemRoutineAddress(&funcName);
}
__inline
VOID
Mx::MxReferenceObject(
__in PVOID Object
)
{
ObReferenceObject(Object);
}
__inline
VOID
Mx::MxDereferenceObject(
__in PVOID Object
)
{
ObDereferenceObject(Object);
}
__inline
VOID
Mx::MxInitializeRemoveLock(
__in MdRemoveLock Lock,
__in ULONG AllocateTag,
__in ULONG MaxLockedMinutes,
__in ULONG HighWatermark
)
{
IoInitializeRemoveLock(Lock, AllocateTag, MaxLockedMinutes, HighWatermark);
}
__inline
NTSTATUS
Mx::MxAcquireRemoveLock(
__in MdRemoveLock RemoveLock,
__in_opt PVOID Tag
)
{
return IoAcquireRemoveLock(RemoveLock, Tag);
}
__inline
VOID
Mx::MxReleaseRemoveLock(
__in MdRemoveLock RemoveLock,
__in PVOID Tag
)
{
IoReleaseRemoveLock(RemoveLock, Tag);
}
__inline
VOID
Mx::MxReleaseRemoveLockAndWait(
__in MdRemoveLock RemoveLock,
__in PVOID Tag
)
{
IoReleaseRemoveLockAndWait(RemoveLock, Tag);
}
__inline
BOOLEAN
Mx::MxHasEnoughRemainingThreadStack(
VOID
)
{
return (IoGetRemainingStackSize() < KERNEL_STACK_SIZE/2) ? FALSE : TRUE;
}
_Releases_lock_(_Global_cancel_spin_lock_)
__drv_requiresIRQL(DISPATCH_LEVEL)
__inline
VOID
Mx::ReleaseCancelSpinLock(
__in __drv_restoresIRQL __drv_useCancelIRQL KIRQL Irql
)
{
IoReleaseCancelSpinLock(Irql);
}
__inline
NTSTATUS
Mx::CreateCallback(
__out PCALLBACK_OBJECT *CallbackObject,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in BOOLEAN Create,
__in BOOLEAN AllowMultipleCallbacks
)
{
return ExCreateCallback(
CallbackObject,
ObjectAttributes,
Create,
AllowMultipleCallbacks);
}
__inline
PVOID
Mx::RegisterCallback(
__in PCALLBACK_OBJECT CallbackObject,
__in MdCallbackFunction CallbackFunction,
__in PVOID CallbackContext
)
{
return ExRegisterCallback(
CallbackObject,
CallbackFunction,
CallbackContext);
}
__inline
VOID
Mx::UnregisterCallback(
__in PVOID CbRegistration
)
{
ExUnregisterCallback(CbRegistration);
}
__inline
VOID
Mx::MxUnlockPages(
__in PMDL Mdl
)
{
MmUnlockPages(Mdl);
}
__inline
PVOID
Mx::MxGetSystemAddressForMdlSafe(
__inout PMDL Mdl,
__in ULONG Priority
)
{
return MmGetSystemAddressForMdlSafe(Mdl, Priority);
}
__inline
VOID
Mx::MxBuildMdlForNonPagedPool(
__inout PMDL Mdl
)
{
MmBuildMdlForNonPagedPool(Mdl);
}
__inline
PVOID
Mx::MxGetDriverObjectExtension(
__in PDRIVER_OBJECT DriverObject,
__in PVOID ClientIdentificationAddress
)
{
return IoGetDriverObjectExtension(DriverObject,
ClientIdentificationAddress);
}
__inline
NTSTATUS
Mx::MxAllocateDriverObjectExtension(
_In_ MdDriverObject DriverObject,
_In_ PVOID ClientIdentificationAddress,
_In_ ULONG DriverObjectExtensionSize,
// When successful, this always allocates already-aliased memory.
_Post_ _At_(*DriverObjectExtension, _When_(return==0,
__drv_aliasesMem __drv_allocatesMem(Mem) _Post_notnull_))
_When_(return == 0, _Outptr_result_bytebuffer_(DriverObjectExtensionSize))
PVOID *DriverObjectExtension
)
{
return IoAllocateDriverObjectExtension(DriverObject,
ClientIdentificationAddress,
DriverObjectExtensionSize,
DriverObjectExtension);
}
__inline
MdDeviceObject
Mx::MxGetAttachedDeviceReference(
__in PDEVICE_OBJECT DriverObject
)
{
return IoGetAttachedDeviceReference(DriverObject);
}
__inline
VOID
Mx::MxDeleteSymbolicLink(
__in PUNICODE_STRING Value
)
{
IoDeleteSymbolicLink(Value);
}
__inline
VOID
Mx::MxDeleteNPagedLookasideList(
_In_ PNPAGED_LOOKASIDE_LIST LookasideList
)
{
ExDeleteNPagedLookasideList(LookasideList);
}
__inline
VOID
Mx::MxDeletePagedLookasideList(
_In_ PPAGED_LOOKASIDE_LIST LookasideList
)
{
ExDeletePagedLookasideList(LookasideList);
}
__inline
VOID
Mx::MxInitializeNPagedLookasideList(
_Out_ PNPAGED_LOOKASIDE_LIST Lookaside,
_In_opt_ PALLOCATE_FUNCTION Allocate,
_In_opt_ PFREE_FUNCTION Free,
_In_ ULONG Flags,
_In_ SIZE_T Size,
_In_ ULONG Tag,
_In_ USHORT Depth
)
{
ExInitializeNPagedLookasideList(Lookaside,
Allocate,
Free,
Flags,
Size,
Tag,
Depth);
}
__inline
VOID
Mx::MxInitializePagedLookasideList(
_Out_ PPAGED_LOOKASIDE_LIST Lookaside,
_In_opt_ PALLOCATE_FUNCTION Allocate,
_In_opt_ PFREE_FUNCTION Free,
_In_ ULONG Flags,
_In_ SIZE_T Size,
_In_ ULONG Tag,
_In_ USHORT Depth
)
{
ExInitializePagedLookasideList(Lookaside,
Allocate,
Free,
Flags,
Size,
Tag,
Depth);
}
__inline
VOID
Mx::MxDeleteDevice(
_In_ MdDeviceObject Device
)
{
IoDeleteDevice(Device);
}
__inline
VOID
Mx::MxDetachDevice(
_Inout_ MdDeviceObject Device
)
{
IoDetachDevice(Device);
}
__inline
MdDeviceObject
Mx::MxAttachDeviceToDeviceStack(
_In_ MdDeviceObject SourceDevice,
_In_ MdDeviceObject TargetDevice
)
{
return IoAttachDeviceToDeviceStack(SourceDevice, TargetDevice);
}
__inline
NTSTATUS
Mx::MxCreateDeviceSecure(
_In_ PDRIVER_OBJECT DriverObject,
_In_ ULONG DeviceExtensionSize,
_In_opt_ PUNICODE_STRING DeviceName,
_In_ DEVICE_TYPE DeviceType,
_In_ ULONG DeviceCharacteristics,
_In_ BOOLEAN Exclusive,
_In_ PCUNICODE_STRING DefaultSDDLString,
_In_opt_ LPCGUID DeviceClassGuid,
_Out_ MdDeviceObject *DeviceObject
)
{
return IoCreateDeviceSecure(DriverObject,
DeviceExtensionSize,
DeviceName,
DeviceType,
DeviceCharacteristics,
Exclusive,
DefaultSDDLString,
DeviceClassGuid,
DeviceObject);
}
__inline
NTSTATUS
Mx::MxCreateDevice(
_In_ PDRIVER_OBJECT DriverObject,
_In_ ULONG DeviceExtensionSize,
_In_opt_ PUNICODE_STRING DeviceName,
_In_ DEVICE_TYPE DeviceType,
_In_ ULONG DeviceCharacteristics,
_In_ BOOLEAN Exclusive,
_Out_ MdDeviceObject *DeviceObject
)
{
return IoCreateDevice(DriverObject,
DeviceExtensionSize,
DeviceName,
DeviceType,
DeviceCharacteristics,
Exclusive,
DeviceObject);
}
__inline
NTSTATUS
Mx::MxCreateSymbolicLink(
_In_ PUNICODE_STRING SymbolicLinkName,
_In_ PUNICODE_STRING DeviceName
)
{
return IoCreateSymbolicLink(SymbolicLinkName, DeviceName);
}
__inline
VOID
Mx::MxFlushQueuedDpcs(
)
{
KeFlushQueuedDpcs();
}
__inline
NTSTATUS
Mx::MxOpenKey(
_Out_ PHANDLE KeyHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ POBJECT_ATTRIBUTES ObjectAttributes
)
{
return ZwOpenKey(KeyHandle, DesiredAccess, ObjectAttributes);
}
__inline
NTSTATUS
Mx::MxSetDeviceInterfaceState(
_In_ PUNICODE_STRING SymbolicLinkName,
_In_ BOOLEAN Enable
)
{
return IoSetDeviceInterfaceState(SymbolicLinkName, Enable);
}
__inline
NTSTATUS
Mx::MxRegisterDeviceInterface(
_In_ PDEVICE_OBJECT PhysicalDeviceObject,
_In_ const GUID *InterfaceClassGuid,
_In_opt_ PUNICODE_STRING ReferenceString,
_Out_ PUNICODE_STRING SymbolicLinkName
)
{
return IoRegisterDeviceInterface(PhysicalDeviceObject,
InterfaceClassGuid,
ReferenceString,
SymbolicLinkName);
}
__inline
NTSTATUS
Mx::MxDeleteKey(
_In_ HANDLE KeyHandle
)
{
return ZwDeleteKey(KeyHandle);
}
__inline
VOID
Mx::MxInitializeMdl(
_In_ PMDL MemoryDescriptorList,
_In_ PVOID BaseVa,
_In_ SIZE_T Length
)
{
MmInitializeMdl(MemoryDescriptorList, BaseVa, Length);
}
__inline
PVOID
Mx::MxGetMdlVirtualAddress(
_In_ PMDL Mdl
)
{
return MmGetMdlVirtualAddress(Mdl);
}
__inline
VOID
Mx::MxBuildPartialMdl(
_In_ PMDL SourceMdl,
_Inout_ PMDL TargetMdl,
_In_ PVOID VirtualAddress,
_In_ ULONG Length
)
{
IoBuildPartialMdl(SourceMdl,
TargetMdl,
VirtualAddress,
Length
);
}
__inline
VOID
Mx::MxQuerySystemTime(
_Out_ PLARGE_INTEGER CurrentTime
)
{
KeQuerySystemTime(CurrentTime);
}
__inline
NTSTATUS
Mx::MxSetValueKey(
_In_ HANDLE KeyHandle,
_In_ PUNICODE_STRING ValueName,
_In_opt_ ULONG TitleIndex,
_In_ ULONG Type,
_In_opt_ PVOID Data,
_In_ ULONG DataSize
)
{
return ZwSetValueKey(KeyHandle,
ValueName,
TitleIndex,
Type,
Data,
DataSize
);
}
__inline
NTSTATUS
Mx::MxQueryValueKey(
_In_ HANDLE KeyHandle,
_In_ PUNICODE_STRING ValueName,
_In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
_Out_opt_ PVOID KeyValueInformation,
_In_ ULONG Length,
_Out_ PULONG ResultLength
)
{
return ZwQueryValueKey(KeyHandle,
ValueName,
KeyValueInformationClass,
KeyValueInformation,
Length,
ResultLength
);
}
__inline
NTSTATUS
Mx::MxReferenceObjectByHandle(
__in HANDLE Handle,
__in ACCESS_MASK DesiredAccess,
__in_opt POBJECT_TYPE ObjectType,
__in KPROCESSOR_MODE AccessMode,
__out PVOID *Object,
__out_opt POBJECT_HANDLE_INFORMATION HandleInformation
)
{
return ObReferenceObjectByHandle(
Handle,
DesiredAccess,
ObjectType,
AccessMode,
Object,
HandleInformation);
}
__inline
NTSTATUS
Mx::MxUnRegisterPlugPlayNotification(
__in __drv_freesMem(Pool) PVOID NotificationEntry
)
{
return IoUnregisterPlugPlayNotification(NotificationEntry);
}
__inline
NTSTATUS
Mx::MxClose(
__in HANDLE Handle
)
{
return ZwClose(Handle);
}
__inline
KIRQL
Mx::MxAcquireInterruptSpinLock(
_Inout_ PKINTERRUPT Interrupt
)
{
return KeAcquireInterruptSpinLock(Interrupt);
}
__inline
VOID
Mx::MxReleaseInterruptSpinLock(
_Inout_ PKINTERRUPT Interrupt,
_In_ KIRQL OldIrql
)
{
KeReleaseInterruptSpinLock(Interrupt, OldIrql);
}
__inline
BOOLEAN
Mx::MxInsertQueueDpc(
__inout PRKDPC Dpc,
__in_opt PVOID SystemArgument1,
__in_opt PVOID SystemArgument2
)
{
return KeInsertQueueDpc(Dpc, SystemArgument1, SystemArgument2);
}

View file

@ -0,0 +1,49 @@
/*++
Copyright (c) Microsoft Corporation
ModuleName:
MxKm.h
Abstract:
This file includes ntddk.h and
kernel mode versions of mode agnostic headers
It also contains definitions pulled out from wdm.h
Author:
Revision History:
--*/
#pragma once
#include <ntddk.h>
#include <procgrp.h>
#include <wdmsec.h>
#include <wmikm.h>
#include <ntwmi.h>
typedef KDEFERRED_ROUTINE MdDeferredRoutineType, *MdDeferredRoutine;
typedef EXT_CALLBACK MdExtCallbackType, *MdExtCallback;
#define FX_DEVICEMAP_PATH L"\\REGISTRY\\MACHINE\\HARDWARE\\DEVICEMAP\\"
#include "MxGeneralKm.h"
#include "MxLockKm.h"
#include "MxPagedLockKm.h"
#include "MxEventKm.h"
#include "MxMemoryKm.h"
#include "MxTimerKm.h"
#include "MxWorkItemKm.h"
#include "MxDriverObjectKm.h"
#include "MxDeviceObjectKm.h"
#include "MxFileObjectKm.h"

View file

@ -0,0 +1,115 @@
/*++
Copyright (c) Microsoft Corporation
ModuleName:
MxLockKm.h
Abstract:
Kernel mode implementation of lock
class defined in MxLock.h
Author:
Revision History:
--*/
#pragma once
#include "DbgMacros.h"
typedef KSPIN_LOCK MdLock;
#include "MxLock.h"
__inline
MxLock::MxLock(
)
{
CLEAR_DBGFLAG_INITIALIZED;
MxLock::Initialize();
}
__inline
VOID
MxLockNoDynam::Initialize(
)
{
KeInitializeSpinLock(&m_Lock);
SET_DBGFLAG_INITIALIZED;
}
_Acquires_lock_(this->m_Lock)
__drv_maxIRQL(DISPATCH_LEVEL)
__drv_setsIRQL(DISPATCH_LEVEL)
__inline
VOID
MxLockNoDynam::Acquire(
__out __drv_deref(__drv_savesIRQL) KIRQL * OldIrql
)
{
ASSERT_DBGFLAG_INITIALIZED;
KeAcquireSpinLock(&m_Lock, OldIrql);
}
_Acquires_lock_(this->m_Lock)
__drv_requiresIRQL(DISPATCH_LEVEL)
__inline
VOID
MxLockNoDynam::AcquireAtDpcLevel(
)
{
ASSERT_DBGFLAG_INITIALIZED;
KeAcquireSpinLockAtDpcLevel(&m_Lock);
}
_Releases_lock_(this->m_Lock)
__drv_requiresIRQL(DISPATCH_LEVEL)
__inline
VOID
MxLockNoDynam::Release(
__drv_restoresIRQL KIRQL NewIrql
)
{
ASSERT_DBGFLAG_INITIALIZED;
KeReleaseSpinLock(&m_Lock, NewIrql);
}
_Releases_lock_(this->m_Lock)
__drv_requiresIRQL(DISPATCH_LEVEL)
__inline
VOID
MxLockNoDynam::ReleaseFromDpcLevel(
)
{
ASSERT_DBGFLAG_INITIALIZED;
KeReleaseSpinLockFromDpcLevel(&m_Lock);
}
__inline
VOID
MxLockNoDynam::Uninitialize(
)
{
CLEAR_DBGFLAG_INITIALIZED;
}
__inline
MxLock::~MxLock(
)
{
CLEAR_DBGFLAG_INITIALIZED;
}

View file

@ -0,0 +1,47 @@
/*++
Copyright (c) Microsoft Corporation
ModuleName:
MxMemoryKm.h
Abstract:
Kernel mode implementation of memory
class defined in MxMemory.h
Author:
Revision History:
--*/
#pragma once
#include "MxMemory.h"
__inline
PVOID
MxMemory::MxAllocatePoolWithTag(
__in POOL_TYPE PoolType,
__in SIZE_T NumberOfBytes,
__in ULONG Tag
)
{
return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag);
}
__inline
VOID
MxMemory::MxFreePool(
__in PVOID Ptr
)
{
ExFreePool(Ptr);
}

View file

@ -0,0 +1,137 @@
/*++
Copyright (c) Microsoft Corporation
ModuleName:
MxPagedLockKm.h
Abstract:
Kernel mode implementation of paged lock defined in
MxPagedLock.h
Author:
Revision History:
--*/
#pragma once
#include "DbgMacros.h"
typedef FAST_MUTEX MdPagedLock;
#include "MxPagedLock.h"
__inline
MxPagedLock::MxPagedLock(
)
{
CLEAR_DBGFLAG_INITIALIZED;
//
// Temporarily call initialize from c'tor
// so that we don't have to churn all of the KMDF code
//
#ifndef MERGE_COMPLETE
(VOID) MxPagedLock::Initialize();
#endif
}
__inline
NTSTATUS
#pragma prefast(suppress:__WARNING_UNMATCHED_DEFN, "_Must_inspect_result_ not needed in kernel mode as the function always succeeds");
MxPagedLockNoDynam::Initialize(
)
{
ExInitializeFastMutex(&m_Lock);
SET_DBGFLAG_INITIALIZED;
return STATUS_SUCCESS;
}
__drv_maxIRQL(APC_LEVEL)
__drv_setsIRQL(APC_LEVEL)
__drv_savesIRQLGlobal(FastMutexObject, this->m_Lock)
_Acquires_lock_(this->m_Lock)
__inline
VOID
MxPagedLockNoDynam::Acquire(
)
{
ASSERT_DBGFLAG_INITIALIZED;
ExAcquireFastMutex(&m_Lock);
}
__inline
VOID
MxPagedLockNoDynam::AcquireUnsafe(
)
{
ASSERT_DBGFLAG_INITIALIZED;
ExAcquireFastMutexUnsafe(&m_Lock);
}
_Must_inspect_result_
__drv_maxIRQL(APC_LEVEL)
__drv_savesIRQLGlobal(FastMutexObject, this->m_Lock)
__drv_valueIs(==1;==0)
__drv_when(return==1, __drv_setsIRQL(APC_LEVEL))
_When_(return==1, _Acquires_lock_(this->m_Lock))
__inline
BOOLEAN
MxPagedLockNoDynam::TryToAcquire(
)
{
ASSERT_DBGFLAG_INITIALIZED;
return ExTryToAcquireFastMutex(&m_Lock);
}
__drv_requiresIRQL(APC_LEVEL)
__drv_restoresIRQLGlobal(FastMutexObject, this->m_Lock)
_Releases_lock_(this->m_Lock)
__inline
VOID
MxPagedLockNoDynam::Release(
)
{
ASSERT_DBGFLAG_INITIALIZED;
ExReleaseFastMutex(&m_Lock);
}
__inline
VOID
MxPagedLockNoDynam::ReleaseUnsafe(
)
{
ASSERT_DBGFLAG_INITIALIZED;
ExReleaseFastMutexUnsafe(&m_Lock);
}
__inline
VOID
MxPagedLockNoDynam::Uninitialize(
)
{
CLEAR_DBGFLAG_INITIALIZED;
}
__inline
MxPagedLock::~MxPagedLock(
)
{
CLEAR_DBGFLAG_INITIALIZED;
}

View file

@ -0,0 +1,291 @@
/*++
Copyright (c) Microsoft Corporation
ModuleName:
MxTimerKm.h
Abstract:
Kernel mode implementation of timer defined in
MxTimer.h
Author:
Revision History:
--*/
#pragma once
#define TolerableDelayUnlimited ((ULONG)-1)
typedef
BOOLEAN
(*PFN_KE_SET_COALESCABLE_TIMER) (
__inout PKTIMER Timer,
__in LARGE_INTEGER DueTime,
__in ULONG Period,
__in ULONG TolerableDelay,
__in_opt PKDPC Dpc
);
typedef struct _MdTimer {
//
// The timer period
//
LONG m_Period;
//
// Tracks whether the ex timer is being used
//
BOOLEAN m_IsExtTimer;
#pragma warning(push)
#pragma warning( disable: 4201 ) // nonstandard extension used : nameless struct/union
union {
struct {
//
// Callback function to be invoked upon timer expiration
//
MdDeferredRoutine m_TimerCallback;
KTIMER KernelTimer;
KDPC TimerDpc;
};
struct {
//
// Callback function to be invoked upon timer expiration
//
MdExtCallback m_ExTimerCallback;
PEX_TIMER m_KernelExTimer;
};
};
#pragma warning(pop)
//
// Context to be passed in to the callback function
//
PVOID m_TimerContext;
} MdTimer;
#include "MxTimer.h"
MxTimer::MxTimer(
VOID
)
{
m_Timer.m_TimerContext = NULL;
m_Timer.m_TimerCallback = NULL;
m_Timer.m_Period = 0;
m_Timer.m_KernelExTimer = NULL;
}
MxTimer::~MxTimer(
VOID
)
{
BOOLEAN wasCancelled;
if (m_Timer.m_IsExtTimer &&
m_Timer.m_KernelExTimer) {
wasCancelled = ExDeleteTimer(m_Timer.m_KernelExTimer,
TRUE, // Cancel if pending. We don't expect
// it to be pending though
FALSE,// Wait
NULL);
//
// Timer should not have been pending
//
ASSERT(wasCancelled == FALSE);
m_Timer.m_KernelExTimer = NULL;
}
}
NTSTATUS
#pragma prefast(suppress:__WARNING_UNMATCHED_DECL_ANNO, "_Must_inspect_result_ not needed in kernel mode as the function always succeeds");
MxTimer::Initialize(
__in_opt PVOID TimerContext,
__in MdDeferredRoutine TimerCallback,
__in LONG Period
)
{
m_Timer.m_TimerContext = TimerContext;
m_Timer.m_TimerCallback = TimerCallback;
m_Timer.m_Period = Period;
KeInitializeTimerEx(&(m_Timer.KernelTimer), NotificationTimer);
KeInitializeDpc(&(m_Timer.TimerDpc), // Timer DPC
m_Timer.m_TimerCallback, // DeferredRoutine
m_Timer.m_TimerContext); // DeferredContext
m_Timer.m_IsExtTimer = FALSE;
return STATUS_SUCCESS;
}
_Must_inspect_result_
NTSTATUS
MxTimer::InitializeEx(
__in_opt PVOID TimerContext,
__in MdExtCallback TimerCallback,
__in LONG Period,
__in ULONG TolerableDelay,
__in BOOLEAN UseHighResolutionTimer
)
/*++
Routine Description:
Initializes an Ex timer. By invoking this routine instead of
Initialize, the client is implicitly declaring that it wants
to use the new timers
Arguments:
TimerContext - Context to be passed back with the cllback
TimerCallback - Callback to be invoked when the timer fires
Period - Period in ms
TolerableDelay - Tolerable delay in ms
UseHighResolutionTimer- Indicates whether to use the high
resolution timers
Returns:
Status
--*/
{
NTSTATUS status;
ULONG attributes = 0;
m_Timer.m_TimerContext = TimerContext;
m_Timer.m_ExTimerCallback = TimerCallback;
m_Timer.m_Period = Period;
if (TolerableDelay != 0) {
attributes |= EX_TIMER_NO_WAKE;
} else if (UseHighResolutionTimer) {
attributes |= EX_TIMER_HIGH_RESOLUTION;
}
m_Timer.m_KernelExTimer = ExAllocateTimer(m_Timer.m_ExTimerCallback,
TimerContext,
attributes);
if (m_Timer.m_KernelExTimer) {
status = STATUS_SUCCESS;
} else {
status = STATUS_INSUFFICIENT_RESOURCES;
}
m_Timer.m_IsExtTimer = TRUE;
return status;
}
__inline
BOOLEAN
MxTimer::StartWithReturn(
__in LARGE_INTEGER DueTime,
__in ULONG TolerableDelay
)
{
if (m_Timer.m_IsExtTimer) {
EXT_SET_PARAMETERS parameters;
ExInitializeSetTimerParameters(&parameters);
//
// We get the delay in ms but the underlying API needs it in 100 ns
// units. Convert tolerable delay from ms to 100 ns. However,
// MAXULONG (TolerableDelayUnlimited) has a special meaning that the
// system should never be woken up, so we assign the corresponding
// special value for Ex timers
//
if (TolerableDelay == TolerableDelayUnlimited) {
parameters.NoWakeTolerance = EX_TIMER_UNLIMITED_TOLERANCE;
} else {
parameters.NoWakeTolerance = ((LONGLONG) TolerableDelay) * 10 * 1000;
}
return ExSetTimer(m_Timer.m_KernelExTimer,
DueTime.QuadPart,
(((LONGLONG) m_Timer.m_Period) * 10 * 1000),
&parameters);
} else {
return KeSetCoalescableTimer(&(m_Timer.KernelTimer),
DueTime,
m_Timer.m_Period,
TolerableDelay,
&(m_Timer.TimerDpc));
}
}
VOID
MxTimer::Start(
__in LARGE_INTEGER DueTime,
__in ULONG TolerableDelay
)
{
if (m_Timer.m_IsExtTimer) {
StartWithReturn(DueTime,TolerableDelay);
} else {
KeSetCoalescableTimer(&(m_Timer.KernelTimer),
DueTime,
m_Timer.m_Period,
TolerableDelay,
&(m_Timer.TimerDpc));
}
return;
}
_Must_inspect_result_
BOOLEAN
MxTimer::Stop(
VOID
)
{
BOOLEAN bRetVal;
if (m_Timer.m_IsExtTimer) {
bRetVal = ExCancelTimer(m_Timer.m_KernelExTimer, NULL);
} else {
bRetVal = KeCancelTimer(&(m_Timer.KernelTimer));
}
return bRetVal;
}
VOID
MxTimer::FlushQueuedDpcs(
VOID
)
{
Mx::MxFlushQueuedDpcs();
}

View file

@ -0,0 +1,109 @@
/*++
Copyright (c) Microsoft Corporation
ModuleName:
MxWorkItemKm.h
Abstract:
Kernel mode implementation of work item
class defined in MxWorkItem.h
Author:
Revision History:
--*/
#pragma once
typedef IO_WORKITEM_ROUTINE MX_WORKITEM_ROUTINE, *PMX_WORKITEM_ROUTINE;
typedef PIO_WORKITEM MdWorkItem;
#include "MxWorkItem.h"
__inline
MxWorkItem::MxWorkItem(
)
{
m_WorkItem = NULL;
}
_Must_inspect_result_
__inline
NTSTATUS
MxWorkItem::Allocate(
__in MdDeviceObject DeviceObject,
__in_opt PVOID ThreadPoolEnv
)
{
UNREFERENCED_PARAMETER(ThreadPoolEnv);
m_WorkItem = IoAllocateWorkItem(DeviceObject);
if (NULL == m_WorkItem) {
return STATUS_INSUFFICIENT_RESOURCES;
}
return STATUS_SUCCESS;
}
__inline
VOID
MxWorkItem::Enqueue(
__in PMX_WORKITEM_ROUTINE Callback,
__in PVOID Context
)
{
IoQueueWorkItem(
m_WorkItem,
Callback,
DelayedWorkQueue,
Context
);
}
__inline
MdWorkItem
MxWorkItem::GetWorkItem(
)
{
return m_WorkItem;
}
__inline
VOID
MxWorkItem::_Free(
__in MdWorkItem Item
)
{
IoFreeWorkItem(Item);
}
__inline
VOID
MxWorkItem::Free(
)
{
if (NULL != m_WorkItem) {
MxWorkItem::_Free(m_WorkItem);
m_WorkItem = NULL;
}
}
//
// FxAutoWorkitem
//
__inline
MxAutoWorkItem::~MxAutoWorkItem(
)
{
this->Free();
}