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