UsbDk: Introduce UsbDkFilterDevice class

- Introduce filtering logic class
 - Make control device creation logic object oriented
 - Integrate control device creation with filter devices creation

Signed-off-by: Dmitry Fleytman <dfleytma@redhat.com>
This commit is contained in:
Dmitry Fleytman 2014-02-16 17:30:45 +02:00
parent ac848be907
commit 6ee40a363b
14 changed files with 276 additions and 298 deletions

View file

@ -2,6 +2,7 @@
#include "trace.h"
#include "ControlDevice.tmh"
#include "Public.h"
#include "DeviceAccess.h"
class CUsbDkControlDeviceInit : public CDeviceInit
{
@ -98,12 +99,58 @@ NTSTATUS CUsbDkControlDevice::Create(WDFDRIVER Driver)
m_DeviceQueue = new CUsbDkControlDeviceQueue(*this, WdfIoQueueDispatchSequential);
status = m_DeviceQueue->Create();
if (!NT_SUCCESS(status))
if (NT_SUCCESS(status))
{
return status;
FinishInitializing();
}
FinishInitializing();
return STATUS_SUCCESS;
return status;
}
CRefCountingHolder<CUsbDkControlDevice> *CUsbDkControlDevice::m_UsbDkControlDevice = nullptr;
CUsbDkControlDevice* CUsbDkControlDevice::Reference(WDFDRIVER Driver)
{
if (!m_UsbDkControlDevice->InitialAddRef())
{
TraceEvents(TRACE_LEVEL_ERROR, TRACE_CONTROLDEVICE, "%!FUNC! control device already exists");
return m_UsbDkControlDevice->Get();
}
else
{
TraceEvents(TRACE_LEVEL_ERROR, TRACE_CONTROLDEVICE, "%!FUNC! creating control device");
}
CUsbDkControlDevice *dev = new CUsbDkControlDevice();
if (dev == nullptr)
{
TraceEvents(TRACE_LEVEL_ERROR, TRACE_CONTROLDEVICE, "%!FUNC! cannot allocate control device");
m_UsbDkControlDevice->Release();
return nullptr;
}
*m_UsbDkControlDevice = dev;
auto status = (*m_UsbDkControlDevice)->Create(Driver);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR, TRACE_CONTROLDEVICE, "%!FUNC! cannot create control device %!STATUS!", status);
m_UsbDkControlDevice->Release();
return nullptr;
}
return dev;
}
bool CUsbDkControlDevice::Allocate()
{
ASSERT(m_UsbDkControlDevice == nullptr);
m_UsbDkControlDevice = new CRefCountingHolder<CUsbDkControlDevice>;
if (m_UsbDkControlDevice == nullptr)
{
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_CONTROLDEVICE, "%!FUNC! Cannot allocate control device holder");
return false;
}
return true;
}

View file

@ -31,17 +31,25 @@ public:
CUsbDkControlDevice() {}
NTSTATUS Create(WDFDRIVER hDriver);
static bool Allocate();
static void Deallocate()
{ delete m_UsbDkControlDevice; }
static CUsbDkControlDevice* Reference(WDFDRIVER Driver);
static void Release()
{ m_UsbDkControlDevice->Release(); }
private:
CObjHolder<CUsbDkControlDeviceQueue> m_DeviceQueue;
static CRefCountingHolder<CUsbDkControlDevice> *m_UsbDkControlDevice;
};
typedef struct _USBDK_CONTROL_DEVICE_EXTENSION {
CUsbDkControlDevice UsbDkControl; // Store your control data here
CUsbDkControlDevice *UsbDkControl; // Store your control data here
_USBDK_CONTROL_DEVICE_EXTENSION(const _USBDK_CONTROL_DEVICE_EXTENSION&) = delete;
_USBDK_CONTROL_DEVICE_EXTENSION& operator= (const _USBDK_CONTROL_DEVICE_EXTENSION&) = delete;
} USBDK_CONTROL_DEVICE_EXTENSION, *PUSBDK_CONTROL_DEVICE_EXTENSION;
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(USBDK_CONTROL_DEVICE_EXTENSION, UsbDkControlGetContext)
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(USBDK_CONTROL_DEVICE_EXTENSION, UsbDkControlGetContext);

View file

@ -1,29 +0,0 @@
/*
* UsbDk filter/redirector driver
*
* Copyright (c) 2013 Red Hat, Inc.
*
* Authors:
* Dmitry Fleytman <dfleytma@redhat.com>
*
*/
#include "public.h"
#include "WdfWorkitem.h"
typedef struct _DEVICE_CONTEXT
{
_DEVICE_CONTEXT() = delete;
WDFIOTARGET IOTarget;
PDEVICE_OBJECT ClonedPdo;
CWdfWorkitem QDRCompletionWorkItem;
//IRP_MN_QUERY_DEVICE_RELATIONS IRP being processed now or NULL
PIRP QDRIrp;
BOOLEAN Initialized;
} DEVICE_CONTEXT, *PDEVICE_CONTEXT;
NTSTATUS UsbDkCreateDevice(_Inout_ PWDFDEVICE_INIT DeviceInit);
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, DeviceGetContext)

View file

@ -10,14 +10,13 @@
#include "driver.h"
#include "ControlDevice.h"
#include "FilterDevice.h"
#include "driver.tmh"
#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, DriverEntry)
#endif
CRefCountingHolder<CUsbDkControlDevice> *g_UsbDkControlDevice;
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
@ -60,14 +59,14 @@ DriverEntry(
return status;
}
g_UsbDkControlDevice = new CRefCountingHolder<CUsbDkControlDevice>;
if (g_UsbDkControlDevice == nullptr) {
if (!CUsbDkControlDevice::Allocate())
{
return STATUS_INSUFFICIENT_RESOURCES;
}
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit");
return status;
return STATUS_SUCCESS;
}
VOID
@ -79,71 +78,31 @@ DriverUnload(IN WDFDRIVER Driver)
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
delete g_UsbDkControlDevice;
CUsbDkControlDevice::Deallocate();
return;
}
static NTSTATUS
UsbDkReferenceControlDevice(WDFDRIVER Driver)
{
if (!g_UsbDkControlDevice->InitialAddRef())
{
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC! control device already exists");
return STATUS_SUCCESS;
}
else
{
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC! creating control device");
}
CUsbDkControlDevice *dev = new CUsbDkControlDevice();
if (dev == nullptr)
{
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC! cannot allocate control device");
g_UsbDkControlDevice->Release();
return STATUS_INSUFFICIENT_RESOURCES;
}
*g_UsbDkControlDevice = dev;
auto status = (*g_UsbDkControlDevice)->Create(Driver);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC! cannot create control device %!STATUS!", status);
g_UsbDkControlDevice->Release();
return status;
}
return STATUS_SUCCESS;
}
VOID
UsbDkReleaseControlDevice()
{
g_UsbDkControlDevice->Release();
}
NTSTATUS
UsbDkEvtDeviceAdd(
_In_ WDFDRIVER Driver,
_Inout_ PWDFDEVICE_INIT DeviceInit
)
{
NTSTATUS status;
UNREFERENCED_PARAMETER(Driver);
PAGED_CODE();
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
status = UsbDkCreateDevice(DeviceInit);
if (NT_SUCCESS(status))
auto FilterDevice = new CUsbDkFilterDevice();
if (FilterDevice == nullptr)
{
status = UsbDkReferenceControlDevice(Driver);
return STATUS_INSUFFICIENT_RESOURCES;
}
auto status = FilterDevice->Create(DeviceInit, Driver);
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit %!STATUS!", status);
return status;

View file

@ -19,7 +19,6 @@ extern "C"
#include <wdfusb.h>
}
#include "device.h"
#include "trace.h"
//
@ -32,5 +31,3 @@ DRIVER_INITIALIZE DriverEntry;
EVT_WDF_DRIVER_UNLOAD DriverUnload;
EVT_WDF_DRIVER_DEVICE_ADD UsbDkEvtDeviceAdd;
EVT_WDF_OBJECT_CONTEXT_CLEANUP UsbDkEvtDriverContextCleanup;
VOID UsbDkReleaseControlDevice();

View file

@ -1,41 +0,0 @@
/*
* UsbDk filter/redirector driver
*
* Copyright (c) 2013 Red Hat, Inc.
*
* Authors:
* Dmitry Fleytman <dfleytma@redhat.com>
*
*/
#include "Filter.h"
#include "DeviceAccess.h"
#include "trace.h"
#include "filter.tmh"
extern "C"
{
#include <ntstrsafe.h>
#include <usb.h>
#include <usbioctl.h>
}
BOOLEAN
UsbDkShouldAttach(_In_ WDFDEVICE device)
{
PAGED_CODE();
CObjHolder<CDeviceAccess> devAccess(CDeviceAccess::GetDeviceAccess(device));
if (devAccess)
{
CObjHolder<CRegText> hwIDs(devAccess->GetHardwareIdProperty());
if (hwIDs)
{
hwIDs->Dump();
return hwIDs->Match(L"USB\\ROOT_HUB") ||
hwIDs->Match(L"USB\\ROOT_HUB20");
}
}
return FALSE;
}

View file

@ -1,17 +0,0 @@
/*
* UsbDk filter/redirector driver
*
* Copyright (c) 2013 Red Hat, Inc.
*
* Authors:
* Dmitry Fleytman <dfleytma@redhat.com>
*
*/
#pragma once
#include <ntddk.h>
#include <wdf.h>
BOOLEAN
UsbDkShouldAttach(_In_ WDFDEVICE device);

View file

@ -1,27 +1,71 @@
/*
* UsbDk filter/redirector driver
*
* Copyright (c) 2013 Red Hat, Inc.
*
* Authors:
* Dmitry Fleytman <dfleytma@redhat.com>
*
*/
#include "driver.h"
#include "Filter.h"
#include "FilterDevice.h"
#include "trace.h"
#include "FilterDevice.tmh"
#include "Public.h"
#include "DeviceAccess.h"
#include "device.tmh"
#include "ControlDevice.h"
extern "C"
class CUsbDkFilterDeviceInit : public CPreAllocatedDeviceInit
{
#include <ntstrsafe.h>
public:
CUsbDkFilterDeviceInit(PWDFDEVICE_INIT DeviceInit)
{ Attach(DeviceInit); }
NTSTATUS Configure(PFN_WDFDEVICE_WDM_IRP_PREPROCESS QDRPreProcessCallback);
CUsbDkFilterDeviceInit(const CUsbDkFilterDeviceInit&) = delete;
CUsbDkFilterDeviceInit& operator= (const CUsbDkFilterDeviceInit&) = delete;
};
NTSTATUS CUsbDkFilterDeviceInit::Configure(PFN_WDFDEVICE_WDM_IRP_PREPROCESS QDRPreProcessCallback)
{
PAGED_CODE();
SetFilter();
return SetPreprocessCallback(QDRPreProcessCallback, IRP_MJ_PNP, IRP_MN_QUERY_DEVICE_RELATIONS);
}
// {C0F2DADE-8235-4065-89A8-58DB74DDC9AC}
DEFINE_GUID(GUID_USBDK_CLONE_PDO,
0xc0f2dade, 0x8235, 0x4065, 0x89, 0xa8, 0x58, 0xdb, 0x74, 0xdd, 0xc9, 0xac);
NTSTATUS CUsbDkFilterDevice::QDRPreProcess(PIRP Irp)
{
PDEVICE_OBJECT wdmDevice = WdfDeviceWdmGetDeviceObject(m_Device);
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
if (BusRelations != irpStack->Parameters.QueryDeviceRelations.Type)
{
IoSkipCurrentIrpStackLocation(Irp);
}
else
{
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutineEx(wdmDevice,
Irp,
(PIO_COMPLETION_ROUTINE) CUsbDkFilterDevice::QDRPostProcessWrap,
this,
TRUE, FALSE, FALSE);
}
return WdfDeviceWdmDispatchPreprocessedIrp(m_Device, Irp);
}
NTSTATUS CUsbDkFilterDevice::QDRPostProcess(PIRP Irp)
{
if (Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
}
ASSERT(m_QDRIrp == nullptr);
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FILTERDEVICE, "%!FUNC! Queuing work item");
m_QDRIrp = Irp;
m_QDRCompletionWorkItem.Enqueue();
return STATUS_MORE_PROCESSING_REQUIRED;
}
//////////////////////////////////////////////////////////////////////////
//TODO: TEMP
typedef struct _CONTROL_DEVICE_EXTENSION {
} PDO_CLONE_EXTENSION, *PPDO_CLONE_EXTENSION;
@ -98,45 +142,43 @@ VOID UsbDkDumpHWIds(CDeviceAccess* devAcc)
DevIDs->Dump();
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
VOID UsbDkQDRPostProcessWi(_In_ PVOID WdfDevice)
void CUsbDkFilterDevice::QDRPostProcessWi()
{
WDFDEVICE Device = (WDFDEVICE) WdfDevice;
PDEVICE_CONTEXT Ctx = DeviceGetContext(WdfDevice);
ASSERT(m_QDRIrp != NULL);
ASSERT(Ctx->QDRIrp != NULL);
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FILTERDEVICE, "%!FUNC! Entry");
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "%!FUNC! Entry");
PDEVICE_RELATIONS Relations = (PDEVICE_RELATIONS) Ctx->QDRIrp->IoStatus.Information;
PDEVICE_RELATIONS Relations = (PDEVICE_RELATIONS) m_QDRIrp->IoStatus.Information;
if (Relations)
{
if (Relations->Count > 0)
{
Ctx->ClonedPdo = Relations->Objects[0];
m_ClonedPdo = Relations->Objects[0];
{
//TEMPORARY: To verify we see HW ids of PDO to be cloned
CObjHolder<CDeviceAccess> pdoAccess(CDeviceAccess::GetDeviceAccess(Ctx->ClonedPdo));
CObjHolder<CDeviceAccess> pdoAccess(CDeviceAccess::GetDeviceAccess(m_ClonedPdo));
if (pdoAccess)
{
UsbDkDumpHWIds(pdoAccess);
}
}
WDFDEVICE PdoClone = UsbDkClonePdo(Device);
WDFDEVICE PdoClone = UsbDkClonePdo(m_Device);
if (PdoClone != WDF_NO_HANDLE)
{
Relations->Objects[0] = WdfDeviceWdmGetDeviceObject(PdoClone);
ObReferenceObject(Relations->Objects[0]);
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "%!FUNC! Replaced PDO 0x%p with 0x%p",
Ctx->ClonedPdo, Relations->Objects[0]);
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FILTERDEVICE, "%!FUNC! Replaced PDO 0x%p with 0x%p",
m_ClonedPdo, Relations->Objects[0]);
//TODO: Temporary to allow normal USB hub driver unload
ObDereferenceObject(Ctx->ClonedPdo);
ObDereferenceObject(m_ClonedPdo);
}
else
{
@ -145,135 +187,100 @@ VOID UsbDkQDRPostProcessWi(_In_ PVOID WdfDevice)
}
}
PIRP QDRIrp = Ctx->QDRIrp;
Ctx->QDRIrp = NULL;
auto QDRIrp = m_QDRIrp;
m_QDRIrp = NULL;
IoCompleteRequest(QDRIrp, IO_NO_INCREMENT);
}
NTSTATUS UsbDkQDRPostProcess(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ PVOID WdfDevice)
CUsbDkFilterDevice::~CUsbDkFilterDevice()
{
PDEVICE_CONTEXT Ctx = DeviceGetContext(WdfDevice);
UNREFERENCED_PARAMETER(DeviceObject);
if (Irp->PendingReturned)
if (m_ControlDevice != nullptr)
{
IoMarkIrpPending(Irp);
CUsbDkControlDevice::Release();
}
ASSERT(Ctx->QDRIrp == NULL);
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "%!FUNC! Queuing work item");
Ctx->QDRIrp = Irp;
Ctx->QDRCompletionWorkItem.Enqueue();
return STATUS_MORE_PROCESSING_REQUIRED;
}
static NTSTATUS UsbDkQDRPreProcess(_In_ WDFDEVICE Device, _Inout_ PIRP Irp)
{
PDEVICE_OBJECT wdmDevice = WdfDeviceWdmGetDeviceObject(Device);
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
if (BusRelations != irpStack->Parameters.QueryDeviceRelations.Type)
{
IoSkipCurrentIrpStackLocation(Irp);
}
else
{
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutineEx(wdmDevice, Irp, UsbDkQDRPostProcess, Device, TRUE, FALSE, FALSE);
}
return WdfDeviceWdmDispatchPreprocessedIrp(Device, Irp);
}
static NTSTATUS
UsbDkSetupFiltering(_In_ PWDFDEVICE_INIT DeviceInit)
{
UCHAR minorCode = IRP_MN_QUERY_DEVICE_RELATIONS;
PAGED_CODE();
WdfFdoInitSetFilter(DeviceInit);
NTSTATUS status = WdfDeviceInitAssignWdmIrpPreprocessCallback(DeviceInit,
UsbDkQDRPreProcess,
IRP_MJ_PNP, &minorCode, 1);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, "%!FUNC! status: %!STATUS!", status);
}
return status;
}
VOID
UsbDkEvtDeviceContextCleanup(_In_ WDFOBJECT DeviceObject)
NTSTATUS CUsbDkFilterDevice::Create(PWDFDEVICE_INIT DevInit, WDFDRIVER Driver)
{
PAGED_CODE();
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "%!FUNC! Entry");
auto deviceContext = DeviceGetContext(DeviceObject);
if (deviceContext->Initialized)
{
deviceContext->QDRCompletionWorkItem.~CWdfWorkitem();
UsbDkReleaseControlDevice();
}
}
NTSTATUS
UsbDkCreateDevice(_Inout_ PWDFDEVICE_INIT DeviceInit)
{
WDF_OBJECT_ATTRIBUTES deviceAttributes;
WDFDEVICE device;
PAGED_CODE();
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "%!FUNC! Entry");
auto status = UsbDkSetupFiltering(DeviceInit);
auto status = CreateFilterDevice(DevInit);
if (!NT_SUCCESS(status))
{
return status;
}
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT);
deviceAttributes.EvtCleanupCallback = UsbDkEvtDeviceContextCleanup;
m_ControlDevice = CUsbDkControlDevice::Reference(Driver);
return (m_ControlDevice != nullptr) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
}
status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);
NTSTATUS CUsbDkFilterDevice::CreateFilterDevice(PWDFDEVICE_INIT DevInit)
{
CUsbDkFilterDeviceInit DeviceInit(DevInit);
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FILTERDEVICE, "%!FUNC! Entry");
auto status = DeviceInit.Configure(CUsbDkFilterDevice::QDRPreProcessWrap);
if (!NT_SUCCESS(status))
{
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, "%!FUNC! WdfDeviceCreate status: %!STATUS!", status);
return status;
}
if (UsbDkShouldAttach(device))
WDF_OBJECT_ATTRIBUTES attr;
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attr, USBDK_FILTER_DEVICE_EXTENSION);
attr.EvtCleanupCallback = CUsbDkFilterDevice::ContextCleanup;
status = CWdfDevice::Create(DeviceInit, attr);
if (!NT_SUCCESS(status))
{
auto deviceContext = DeviceGetContext(device);
deviceContext->IOTarget = WdfDeviceGetIoTarget(device);
deviceContext->QDRIrp = NULL;
deviceContext->ClonedPdo = NULL;
return status;
}
new (&deviceContext->QDRCompletionWorkItem) CWdfWorkitem(device, UsbDkQDRPostProcessWi, device);
status = deviceContext->QDRCompletionWorkItem.Create();
if (ShouldAttach())
{
auto deviceContext = UsbDkFilterGetContext(m_Device);
deviceContext->UsbDkFilter = this;
deviceContext->Initialized = TRUE;
status = m_QDRCompletionWorkItem.Create(m_Device);
ULONG traceLevel = NT_SUCCESS(status) ? TRACE_LEVEL_INFORMATION : TRACE_LEVEL_ERROR;
TraceEvents(traceLevel, TRACE_DEVICE, "%!FUNC! Attachment status: %!STATUS!", status);
TraceEvents(traceLevel, TRACE_FILTERDEVICE, "%!FUNC! Attachment status: %!STATUS!", status);
}
else
{
status = STATUS_NOT_SUPPORTED;
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "%!FUNC! Not attached");
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FILTERDEVICE, "%!FUNC! Not attached");
}
return status;
}
void CUsbDkFilterDevice::ContextCleanup(_In_ WDFOBJECT DeviceObject)
{
PAGED_CODE();
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FILTERDEVICE, "%!FUNC! Entry");
auto deviceContext = UsbDkFilterGetContext(DeviceObject);
delete deviceContext->UsbDkFilter;
}
bool CUsbDkFilterDevice::ShouldAttach()
{
PAGED_CODE();
CObjHolder<CDeviceAccess> devAccess(CDeviceAccess::GetDeviceAccess(m_Device));
if (devAccess)
{
CObjHolder<CRegText> hwIDs(devAccess->GetHardwareIdProperty());
if (hwIDs)
{
hwIDs->Dump();
return hwIDs->Match(L"USB\\ROOT_HUB") ||
hwIDs->Match(L"USB\\ROOT_HUB20");
}
}
return false;
}

56
UsbDk/FilterDevice.h Normal file
View file

@ -0,0 +1,56 @@
#pragma once
#include "ntddk.h"
#include "wdf.h"
#include "WdfDevice.h"
#include "WdfWorkitem.h"
#include "Alloc.h"
#include "UsbDkUtil.h"
class CUsbDkControlDevice;
class CUsbDkFilterDevice;
typedef struct _USBDK_FILTER_DEVICE_EXTENSION {
CUsbDkFilterDevice *UsbDkFilter;
_USBDK_FILTER_DEVICE_EXTENSION(const _USBDK_FILTER_DEVICE_EXTENSION&) = delete;
_USBDK_FILTER_DEVICE_EXTENSION& operator= (const _USBDK_FILTER_DEVICE_EXTENSION&) = delete;
} USBDK_FILTER_DEVICE_EXTENSION, *PUSBDK_FILTER_DEVICE_EXTENSION;
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(USBDK_FILTER_DEVICE_EXTENSION, UsbDkFilterGetContext);
class CUsbDkFilterDevice : private CWdfDevice, public CAllocatable<NonPagedPool, 'DFHR'>
{
public:
CUsbDkFilterDevice()
: m_QDRCompletionWorkItem(CUsbDkFilterDevice::QDRPostProcessWiWrap, this)
{}
~CUsbDkFilterDevice();
NTSTATUS Create(PWDFDEVICE_INIT DevInit, WDFDRIVER Driver);
NTSTATUS CreateFilterDevice(PWDFDEVICE_INIT DevInit);
private:
static void ContextCleanup(_In_ WDFOBJECT DeviceObject);
static NTSTATUS QDRPreProcessWrap(_In_ WDFDEVICE Device, _Inout_ PIRP Irp)
{ return UsbDkFilterGetContext(Device)->UsbDkFilter->QDRPreProcess(Irp); }
NTSTATUS QDRPreProcess(PIRP Irp);
static NTSTATUS QDRPostProcessWrap(_In_ PDEVICE_OBJECT, _In_ PIRP Irp, _In_ CUsbDkFilterDevice *This)
{ return This->QDRPostProcess(Irp); }
NTSTATUS QDRPostProcess(PIRP Irp);
static VOID CUsbDkFilterDevice::QDRPostProcessWiWrap(_In_ PVOID This)
{ static_cast<CUsbDkFilterDevice*>(This)->QDRPostProcessWi(); }
void CUsbDkFilterDevice::QDRPostProcessWi();
bool ShouldAttach();
CWdfWorkitem m_QDRCompletionWorkItem;
PIRP m_QDRIrp = nullptr;
PDEVICE_OBJECT m_ClonedPdo = nullptr;
CUsbDkControlDevice *m_ControlDevice = nullptr;
};

View file

@ -25,6 +25,7 @@
WPP_DEFINE_BIT(TRACE_DEVACCESS) \
WPP_DEFINE_BIT(TRACE_REGTEXT) \
WPP_DEFINE_BIT(TRACE_CONTROLDEVICE) \
WPP_DEFINE_BIT(TRACE_FILTERDEVICE) \
WPP_DEFINE_BIT(TRACE_WDFDEVICE) \
)

View file

@ -52,10 +52,9 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="ControlDevice.cpp" />
<ClCompile Include="Device.cpp" />
<ClCompile Include="DeviceAccess.cpp" />
<ClCompile Include="Driver.cpp" />
<ClCompile Include="Filter.cpp" />
<ClCompile Include="FilterDevice.cpp" />
<ClCompile Include="Irp.cpp" />
<ClCompile Include="MemoryBuffer.cpp" />
<ClCompile Include="RegText.cpp" />
@ -65,10 +64,9 @@
<ItemGroup>
<ClInclude Include="Alloc.h" />
<ClInclude Include="ControlDevice.h" />
<ClInclude Include="Device.h" />
<ClInclude Include="DeviceAccess.h" />
<ClInclude Include="Driver.h" />
<ClInclude Include="Filter.h" />
<ClInclude Include="FilterDevice.h" />
<ClInclude Include="Irp.h" />
<ClInclude Include="MemoryBuffer.h" />
<ClInclude Include="Public.h" />

View file

@ -19,9 +19,6 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Device.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Driver.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -31,9 +28,6 @@
<ClInclude Include="Trace.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Filter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="WdfWorkitem.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -61,14 +55,11 @@
<ClInclude Include="UsbDkUtil.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FilterDevice.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Filter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Device.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Driver.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -93,5 +84,8 @@
<ClCompile Include="WdfDevice.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FilterDevice.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View file

@ -21,14 +21,14 @@ VOID CWdfWorkitem::Callback(_In_ WDFWORKITEM WorkItem)
ctx->workItem->m_Payload(ctx->workItem->m_PayloadCtx);
}
NTSTATUS CWdfWorkitem::Create()
NTSTATUS CWdfWorkitem::Create(WDFOBJECT parent)
{
WDF_OBJECT_ATTRIBUTES attributes;
WDF_WORKITEM_CONFIG workitemConfig;
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attributes, WdfWorkItemContext);
attributes.ParentObject = m_hParent;
attributes.ParentObject = parent;
WDF_WORKITEM_CONFIG_INIT(&workitemConfig, Callback);
auto status = WdfWorkItemCreate(&workitemConfig, &attributes, &m_hWorkItem);

View file

@ -11,9 +11,8 @@ private:
typedef VOID(*PayloadFunc)(PVOID Ctx);
public:
CWdfWorkitem(_In_ WDFOBJECT parent, PayloadFunc payload, PVOID payloadCtx)
: m_hParent(parent)
, m_Payload(payload)
CWdfWorkitem(PayloadFunc payload, PVOID payloadCtx)
: m_Payload(payload)
, m_PayloadCtx(payloadCtx)
{}
@ -22,12 +21,11 @@ public:
~CWdfWorkitem();
NTSTATUS Create();
NTSTATUS Create(WDFOBJECT parent);
VOID Enqueue();
private:
WDFWORKITEM m_hWorkItem = WDF_NO_HANDLE;
WDFOBJECT m_hParent = WDF_NO_HANDLE;
static VOID Callback(_In_ WDFWORKITEM WorkItem);
PayloadFunc m_Payload;