diff --git a/UsbDk/Trace.h b/UsbDk/Trace.h index 291a8ff..4d8ed49 100644 --- a/UsbDk/Trace.h +++ b/UsbDk/Trace.h @@ -24,6 +24,10 @@ WPP_DEFINE_BIT(TRACE_FILTER) \ WPP_DEFINE_BIT(TRACE_DEVACCESS) \ WPP_DEFINE_BIT(TRACE_REGTEXT) \ + WPP_DEFINE_BIT(TRACE_DEVICEINIT) \ + WPP_DEFINE_BIT(TRACE_CONTROLDEVICE) \ + WPP_DEFINE_BIT(TRACE_WDFDEVICE) \ + WPP_DEFINE_BIT(TRACE_WDFQUEUE) \ ) #define WPP_FLAG_LEVEL_LOGGER(flag, level) \ diff --git a/UsbDk/UsbDk.vcxproj b/UsbDk/UsbDk.vcxproj index 775d2e2..17b7038 100644 --- a/UsbDk/UsbDk.vcxproj +++ b/UsbDk/UsbDk.vcxproj @@ -58,6 +58,7 @@ + @@ -71,6 +72,7 @@ + @@ -254,7 +256,7 @@ true - %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib + %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\wdmsec.lib @@ -264,7 +266,7 @@ true - %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib + %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\wdmsec.lib @@ -274,7 +276,7 @@ true - %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib + %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\wdmsec.lib @@ -284,7 +286,7 @@ true - %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib + %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\wdmsec.lib @@ -294,7 +296,7 @@ true - %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib + %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\wdmsec.lib @@ -304,7 +306,7 @@ true - %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib + %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\wdmsec.lib @@ -314,7 +316,7 @@ true - %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib + %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\wdmsec.lib @@ -324,7 +326,7 @@ true - %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib + %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\wdmsec.lib @@ -334,7 +336,7 @@ true - %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib + %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\wdmsec.lib @@ -344,7 +346,7 @@ true - %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib + %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\wdmsec.lib @@ -354,7 +356,7 @@ true - %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib + %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\wdmsec.lib @@ -364,7 +366,7 @@ true - %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib + %(AdditionalDependencies);$(DDK_LIB_PATH)\usbdex.lib;$(DDK_LIB_PATH)\ntstrsafe.lib;$(DDK_LIB_PATH)\wdmsec.lib diff --git a/UsbDk/UsbDk.vcxproj.filters b/UsbDk/UsbDk.vcxproj.filters index 04bb076..1e195c1 100644 --- a/UsbDk/UsbDk.vcxproj.filters +++ b/UsbDk/UsbDk.vcxproj.filters @@ -52,6 +52,9 @@ Header Files + + Header Files + @@ -78,5 +81,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/UsbDk/WdfDevice.cpp b/UsbDk/WdfDevice.cpp new file mode 100644 index 0000000..3868111 --- /dev/null +++ b/UsbDk/WdfDevice.cpp @@ -0,0 +1,83 @@ +#include "WdfDevice.h" +#include "trace.h" +#include "WdfDevice.tmh" + +bool CDeviceInit::Create(_In_ WDFDRIVER Driver, _In_ CONST UNICODE_STRING &SDDLString) +{ + m_DeviceInit = WdfControlDeviceInitAllocate(Driver, &SDDLString); + return m_DeviceInit != nullptr; +} + +CDeviceInit::~CDeviceInit() +{ + if (m_DeviceInit != nullptr) + { + WdfDeviceInitFree(m_DeviceInit); + } +} + +NTSTATUS CDeviceInit::SetName(const UNICODE_STRING &Name) +{ + auto status = WdfDeviceInitAssignName(m_DeviceInit, &Name); + + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICEINIT, "%!FUNC! failed %!STATUS!", status); + } + + return status; +} + +NTSTATUS CWdfDevice::CreateSymLink(const UNICODE_STRING &Name) +{ + auto status = WdfDeviceCreateSymbolicLink(m_Device, &Name); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_WDFDEVICE, "%!FUNC! failed %!STATUS!", status); + } + return status; +} + +NTSTATUS CWdfDevice::Create(CDeviceInit &DeviceInit, WDF_OBJECT_ATTRIBUTES &DeviceAttr) +{ + auto status = WdfDeviceCreate(DeviceInit, &DeviceAttr, &m_Device); + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_WDFDEVICE, "%!FUNC! failed %!STATUS!", status); + return status; + } + + return STATUS_SUCCESS; +} + +NTSTATUS CWdfQueue::Create() +{ + WDF_IO_QUEUE_CONFIG QueueConfig; + WDFQUEUE Queue; + WDF_OBJECT_ATTRIBUTES Attributes; + + InitConfig(QueueConfig); + SetCallbacks(QueueConfig); + + Attributes.ExecutionLevel = WdfExecutionLevelPassive; + + auto status = m_OwnerDevice.AddQueue(QueueConfig, Attributes, Queue); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_WDFQUEUE, "%!FUNC! failed %!STATUS!", status); + } + + return status; +} + +NTSTATUS CWdfDevice::AddQueue(WDF_IO_QUEUE_CONFIG &Config, WDF_OBJECT_ATTRIBUTES &Attributes, WDFQUEUE &Queue) +{ + auto status = WdfIoQueueCreate(m_Device, &Config, &Attributes, &Queue); + if (!NT_SUCCESS(status)) { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_WDFDEVICE, "%!FUNC! failed %!STATUS!", status); + } + + return status; +} + +void CWdfDefaultQueue::InitConfig(WDF_IO_QUEUE_CONFIG &QueueConfig) +{ + WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&QueueConfig, m_DispatchType); +} diff --git a/UsbDk/WdfDevice.h b/UsbDk/WdfDevice.h new file mode 100644 index 0000000..b284e22 --- /dev/null +++ b/UsbDk/WdfDevice.h @@ -0,0 +1,89 @@ +#pragma once + +#include "ntddk.h" +#include "wdf.h" + +class CDeviceInit +{ +public: + bool Create(_In_ WDFDRIVER Driver, _In_ CONST UNICODE_STRING &SDDLString); + CDeviceInit() + {} + ~CDeviceInit(); + + void SetExclusive() + { WdfDeviceInitSetExclusive(m_DeviceInit, TRUE); } + + void SetIoBuffered() + { WdfDeviceInitSetIoType(m_DeviceInit, WdfDeviceIoBuffered); } + + NTSTATUS SetName(const UNICODE_STRING &Name); + + operator PWDFDEVICE_INIT*() + { return &m_DeviceInit; } + + CDeviceInit(const CDeviceInit&) = delete; + CDeviceInit& operator= (const CDeviceInit&) = delete; +private: + PWDFDEVICE_INIT m_DeviceInit = nullptr; +}; + +class CWdfDevice +{ +public: + CWdfDevice() {} + + NTSTATUS CreateSymLink(const UNICODE_STRING &Name); + NTSTATUS Create(CDeviceInit &DeviceInit, WDF_OBJECT_ATTRIBUTES &DeviceAttr); + + CWdfDevice(const CWdfDevice&) = delete; + CWdfDevice& operator= (const CWdfDevice&) = delete; +protected: + WDFDEVICE m_Device; + +private: + NTSTATUS AddQueue(WDF_IO_QUEUE_CONFIG &Config, WDF_OBJECT_ATTRIBUTES &Attributes, WDFQUEUE &Queue); + + friend class CWdfQueue; +}; + +class CWdfControlDevice : public CWdfDevice +{ +public: + void FinishInitializing() + { WdfControlFinishInitializing(m_Device); } +}; + +class CWdfQueue +{ +public: + CWdfQueue(CWdfDevice &Device, WDF_IO_QUEUE_DISPATCH_TYPE DispatchType) + : m_OwnerDevice(Device) + , m_DispatchType(DispatchType) + {} + + NTSTATUS Create(); +protected: + virtual void InitConfig(WDF_IO_QUEUE_CONFIG &QueueConfig) = 0; + virtual void SetCallbacks(WDF_IO_QUEUE_CONFIG &QueueConfig) = 0; + + CWdfDevice &m_OwnerDevice; + WDF_IO_QUEUE_DISPATCH_TYPE m_DispatchType; + + CWdfQueue(const CWdfQueue&) = delete; + CWdfQueue& operator= (const CWdfQueue&) = delete; +}; + +class CWdfDefaultQueue : public CWdfQueue +{ +public: + CWdfDefaultQueue(CWdfDevice &Device, WDF_IO_QUEUE_DISPATCH_TYPE DispatchType) + : CWdfQueue(Device, DispatchType) + {} + +private: + virtual void InitConfig(WDF_IO_QUEUE_CONFIG &QueueConfig) override; + + CWdfDefaultQueue(const CWdfDefaultQueue&) = delete; + CWdfDefaultQueue& operator= (const CWdfDefaultQueue&) = delete; +};