UsbDk: Move redirector classes to a separate file
Signed-off-by: Dmitry Fleytman <dfleytma@redhat.com>
This commit is contained in:
parent
74c65795e1
commit
090c69bc73
6 changed files with 278 additions and 258 deletions
|
|
@ -3,6 +3,7 @@
|
|||
#include "FilterDevice.tmh"
|
||||
#include "DeviceAccess.h"
|
||||
#include "ControlDevice.h"
|
||||
#include "RedirectorDevice.h"
|
||||
#include "UsbDkNames.h"
|
||||
|
||||
void CUsbDkChildDevice::Dump()
|
||||
|
|
@ -71,14 +72,6 @@ NTSTATUS CUsbDkFilterDevice::QDRPostProcess(PIRP Irp)
|
|||
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||
}
|
||||
|
||||
class CUsbDkRedirectorPDODevice;
|
||||
|
||||
typedef struct _USBDK_REDIRECTOR_PDO_EXTENSION {
|
||||
CUsbDkRedirectorPDODevice *UsbDkRedirectorPDO;
|
||||
} USBDK_REDIRECTOR_PDO_EXTENSION, *PUSBDK_REDIRECTOR_PDO_EXTENSION;
|
||||
|
||||
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(USBDK_REDIRECTOR_PDO_EXTENSION, UsbDkRedirectorPdoGetData)
|
||||
|
||||
class CDeviceRelations
|
||||
{
|
||||
public:
|
||||
|
|
@ -197,256 +190,6 @@ void CUsbDkFilterDevice::ApplyRedirectionPolicy(CUsbDkChildDevice &Device)
|
|||
}
|
||||
}
|
||||
|
||||
class CUsbDkRedirectorPDOInit : public CDeviceInit
|
||||
{
|
||||
public:
|
||||
CUsbDkRedirectorPDOInit()
|
||||
{}
|
||||
|
||||
NTSTATUS Create(const WDFDEVICE ParentDevice,
|
||||
PFN_WDFDEVICE_WDM_IRP_PREPROCESS PNPPreProcess,
|
||||
PFN_WDF_DEVICE_SELF_MANAGED_IO_INIT SelfManagedIoInit);
|
||||
|
||||
CUsbDkRedirectorPDOInit(const CUsbDkRedirectorPDOInit&) = delete;
|
||||
CUsbDkRedirectorPDOInit& operator= (const CUsbDkRedirectorPDOInit&) = delete;
|
||||
};
|
||||
|
||||
NTSTATUS CUsbDkRedirectorPDOInit::Create(const WDFDEVICE ParentDevice,
|
||||
PFN_WDFDEVICE_WDM_IRP_PREPROCESS PNPPreProcess,
|
||||
PFN_WDF_DEVICE_SELF_MANAGED_IO_INIT SelfManagedIoInit)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
auto DevInit = WdfPdoInitAllocate(ParentDevice);
|
||||
|
||||
if (DevInit == nullptr)
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_FILTERDEVICE, "%!FUNC! Cannot allocate DeviceInit for PDO");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Attach(DevInit);
|
||||
|
||||
//TODO: Put real values
|
||||
#define REDIRECTOR_HARDWARE_IDS L"USB\\Vid_FEED&Pid_CAFE&Rev_0001\0USB\\Vid_FEED&Pid_CAFE\0"
|
||||
#define REDIRECTOR_COMPATIBLE_IDS L"USB\\Class_FF&SubClass_FF&Prot_FF\0USB\\Class_FF&SubClass_FF\0USB\\Class_FF\0"
|
||||
#define REDIRECTOR_INSTANCE_ID L"111222333"
|
||||
|
||||
DECLARE_CONST_UNICODE_STRING(RedirectorHwId, REDIRECTOR_HARDWARE_IDS);
|
||||
DECLARE_CONST_UNICODE_STRING(RedirectorCompatId, REDIRECTOR_COMPATIBLE_IDS);
|
||||
DECLARE_CONST_UNICODE_STRING(RedirectorInstanceId, REDIRECTOR_INSTANCE_ID);
|
||||
|
||||
auto status = WdfPdoInitAssignDeviceID(DevInit, &RedirectorHwId);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_FILTERDEVICE, "%!FUNC! WdfPdoInitAssignDeviceID failed");
|
||||
return status;
|
||||
}
|
||||
|
||||
status = WdfPdoInitAddCompatibleID(DevInit, &RedirectorCompatId);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_FILTERDEVICE, "%!FUNC! WdfPdoInitAddCompatibleID failed");
|
||||
return status;
|
||||
}
|
||||
|
||||
status = WdfPdoInitAddHardwareID(DevInit, &RedirectorCompatId);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_FILTERDEVICE, "%!FUNC! WdfPdoInitAddHardwareID failed");
|
||||
return status;
|
||||
}
|
||||
|
||||
status = WdfPdoInitAssignInstanceID(DevInit, &RedirectorInstanceId);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_FILTERDEVICE, "%!FUNC! WdfPdoInitAssignInstanceID failed");
|
||||
return status;
|
||||
}
|
||||
|
||||
// {52AF46D0-AB11-4A38-96A5-BC0AC6ABD2AF}
|
||||
static const GUID GUID_USBDK_REDIRECTED_DEVICE =
|
||||
{ 0x52af46d0, 0xab11, 0x4a38, { 0x96, 0xa5, 0xbc, 0xa, 0xc6, 0xab, 0xd2, 0xaf } };
|
||||
|
||||
status = SetRaw(&GUID_USBDK_REDIRECTED_DEVICE);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_FILTERDEVICE, "%!FUNC! WdfPdoInitAssignRawDevice failed");
|
||||
return status;
|
||||
}
|
||||
|
||||
SetExclusive();
|
||||
SetIoDirect();
|
||||
SetPowerCallbacks(SelfManagedIoInit);
|
||||
|
||||
status = SetPreprocessCallback(PNPPreProcess, IRP_MJ_PNP);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_FILTERDEVICE, "%!FUNC! Setting pre-process callback for IRP_MJ_PNP failed");
|
||||
return status;
|
||||
}
|
||||
|
||||
DECLARE_CONST_UNICODE_STRING(ntDeviceName, USBDK_TEMP_REDIRECTOR_DEVICE_NAME);
|
||||
return SetName(ntDeviceName);
|
||||
}
|
||||
|
||||
class CUsbDkRedirectorPDODevice : public CWdfDevice, public CAllocatable<NonPagedPool, 'PRHR'>
|
||||
{
|
||||
public:
|
||||
CUsbDkRedirectorPDODevice()
|
||||
{}
|
||||
~CUsbDkRedirectorPDODevice();
|
||||
|
||||
NTSTATUS Create(WDFDEVICE ParentDevice, const PDEVICE_OBJECT OrigPDO);
|
||||
|
||||
WDFDEVICE RawObject() const { return m_Device; }
|
||||
|
||||
CUsbDkRedirectorPDODevice(const CUsbDkRedirectorPDODevice&) = delete;
|
||||
CUsbDkRedirectorPDODevice& operator= (const CUsbDkRedirectorPDODevice&) = delete;
|
||||
|
||||
private:
|
||||
static void ContextCleanup(_In_ WDFOBJECT DeviceObject);
|
||||
|
||||
NTSTATUS PNPPreProcess(_Inout_ PIRP Irp);
|
||||
|
||||
NTSTATUS PassThroughPreProcess(_Inout_ PIRP Irp)
|
||||
{
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return IoCallDriver(m_RequestTarget, Irp);
|
||||
}
|
||||
|
||||
NTSTATUS PassThroughPreProcessWithCompletion(_Inout_ PIRP Irp, PIO_COMPLETION_ROUTINE CompletionRoutine);
|
||||
|
||||
NTSTATUS QueryCapabilitiesPostProcess(_Inout_ PIRP Irp);
|
||||
|
||||
NTSTATUS SelfManagedIoInit();
|
||||
|
||||
PDEVICE_OBJECT m_RequestTarget = nullptr;
|
||||
};
|
||||
|
||||
CUsbDkRedirectorPDODevice::~CUsbDkRedirectorPDODevice()
|
||||
{
|
||||
//Life cycle of this device in controlled by PnP manager outside of WDF,
|
||||
//We detach WDF object here to avoid explicit deletion
|
||||
m_Device = WDF_NO_HANDLE;
|
||||
}
|
||||
|
||||
NTSTATUS CUsbDkRedirectorPDODevice::PassThroughPreProcessWithCompletion(_Inout_ PIRP Irp,
|
||||
PIO_COMPLETION_ROUTINE CompletionRoutine)
|
||||
{
|
||||
IoCopyCurrentIrpStackLocationToNext(Irp);
|
||||
|
||||
IoSetCompletionRoutineEx(WdfDeviceWdmGetDeviceObject(m_Device),
|
||||
Irp,
|
||||
CompletionRoutine,
|
||||
this,
|
||||
TRUE, FALSE, FALSE);
|
||||
|
||||
return IoCallDriver(m_RequestTarget, Irp);
|
||||
}
|
||||
|
||||
NTSTATUS CUsbDkRedirectorPDODevice::PNPPreProcess(_Inout_ PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FILTERDEVICE, "%!FUNC! Entry, IRP [%x:%x]", irpStack->MajorFunction, irpStack->MinorFunction);
|
||||
|
||||
switch (irpStack->MinorFunction)
|
||||
{
|
||||
case IRP_MN_QUERY_ID:
|
||||
case IRP_MN_DEVICE_ENUMERATED:
|
||||
case IRP_MN_START_DEVICE:
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return WdfDeviceWdmDispatchPreprocessedIrp(m_Device, Irp);
|
||||
case IRP_MN_QUERY_CAPABILITIES:
|
||||
return PassThroughPreProcessWithCompletion(Irp,
|
||||
[](_In_ PDEVICE_OBJECT, _In_ PIRP Irp, PVOID Context) -> NTSTATUS
|
||||
{
|
||||
auto This = static_cast<CUsbDkRedirectorPDODevice *>(Context);
|
||||
return This->QueryCapabilitiesPostProcess(Irp);
|
||||
});
|
||||
default:
|
||||
return PassThroughPreProcess(Irp);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS CUsbDkRedirectorPDODevice::QueryCapabilitiesPostProcess(_Inout_ PIRP Irp)
|
||||
{
|
||||
if (Irp->PendingReturned)
|
||||
{
|
||||
IoMarkIrpPending(Irp);
|
||||
}
|
||||
|
||||
auto irpStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
irpStack->Parameters.DeviceCapabilities.Capabilities->RawDeviceOK = 1;
|
||||
|
||||
return STATUS_CONTINUE_COMPLETION;
|
||||
}
|
||||
|
||||
NTSTATUS CUsbDkRedirectorPDODevice::SelfManagedIoInit()
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FILTERDEVICE, "%!FUNC! Entry");
|
||||
|
||||
DECLARE_CONST_UNICODE_STRING(ntDosDeviceName, USBDK_TEMP_REDIRECTOR_NAME);
|
||||
auto status = CreateSymLink(ntDosDeviceName);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_FILTERDEVICE, "%!FUNC! Failed to create a symbolic link for a redirector device (%!STATUS!)", status);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS CUsbDkRedirectorPDODevice::Create(WDFDEVICE ParentDevice, const PDEVICE_OBJECT OrigPDO)
|
||||
{
|
||||
CUsbDkRedirectorPDOInit devInit;
|
||||
|
||||
auto status = devInit.Create(ParentDevice,
|
||||
[](_In_ WDFDEVICE Device, _Inout_ PIRP Irp)
|
||||
{ return UsbDkRedirectorPdoGetData(Device)->UsbDkRedirectorPDO->PNPPreProcess(Irp); },
|
||||
[](_In_ WDFDEVICE Device)
|
||||
{ return UsbDkRedirectorPdoGetData(Device)->UsbDkRedirectorPDO->SelfManagedIoInit(); });
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
WDF_OBJECT_ATTRIBUTES attr;
|
||||
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attr, USBDK_REDIRECTOR_PDO_EXTENSION);
|
||||
|
||||
attr.EvtCleanupCallback = CUsbDkRedirectorPDODevice::ContextCleanup;
|
||||
|
||||
status = CWdfDevice::Create(devInit, attr);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
auto deviceContext = UsbDkRedirectorPdoGetData(m_Device);
|
||||
deviceContext->UsbDkRedirectorPDO = this;
|
||||
|
||||
auto redirectorDevObj = WdfDeviceWdmGetDeviceObject(m_Device);
|
||||
m_RequestTarget = IoAttachDeviceToDeviceStack(redirectorDevObj, OrigPDO);
|
||||
if (m_RequestTarget == nullptr)
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_FILTERDEVICE, "%!FUNC! Failed to attach device to device stack");
|
||||
status = STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void CUsbDkRedirectorPDODevice::ContextCleanup(_In_ WDFOBJECT DeviceObject)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FILTERDEVICE, "%!FUNC! Entry");
|
||||
|
||||
auto deviceContext = UsbDkRedirectorPdoGetData(DeviceObject);
|
||||
UNREFERENCED_PARAMETER(deviceContext);
|
||||
|
||||
delete deviceContext->UsbDkRedirectorPDO;
|
||||
}
|
||||
|
||||
WDFDEVICE CUsbDkFilterDevice::CreateRedirectorPDO(const PDEVICE_OBJECT origPDO)
|
||||
{
|
||||
CObjHolder<CUsbDkRedirectorPDODevice> Device(new CUsbDkRedirectorPDODevice);
|
||||
|
|
|
|||
228
UsbDk/RedirectorDevice.cpp
Normal file
228
UsbDk/RedirectorDevice.cpp
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
#include "RedirectorDevice.h"
|
||||
#include "trace.h"
|
||||
#include "RedirectorDevice.tmh"
|
||||
#include "DeviceAccess.h"
|
||||
#include "ControlDevice.h"
|
||||
#include "UsbDkNames.h"
|
||||
|
||||
typedef struct _USBDK_REDIRECTOR_PDO_EXTENSION {
|
||||
CUsbDkRedirectorPDODevice *UsbDkRedirectorPDO;
|
||||
} USBDK_REDIRECTOR_PDO_EXTENSION, *PUSBDK_REDIRECTOR_PDO_EXTENSION;
|
||||
|
||||
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(USBDK_REDIRECTOR_PDO_EXTENSION, UsbDkRedirectorPdoGetData)
|
||||
|
||||
class CUsbDkRedirectorPDOInit : public CDeviceInit
|
||||
{
|
||||
public:
|
||||
CUsbDkRedirectorPDOInit()
|
||||
{}
|
||||
|
||||
NTSTATUS Create(const WDFDEVICE ParentDevice,
|
||||
PFN_WDFDEVICE_WDM_IRP_PREPROCESS PNPPreProcess,
|
||||
PFN_WDF_DEVICE_SELF_MANAGED_IO_INIT SelfManagedIoInit);
|
||||
|
||||
CUsbDkRedirectorPDOInit(const CUsbDkRedirectorPDOInit&) = delete;
|
||||
CUsbDkRedirectorPDOInit& operator= (const CUsbDkRedirectorPDOInit&) = delete;
|
||||
};
|
||||
|
||||
NTSTATUS CUsbDkRedirectorPDOInit::Create(const WDFDEVICE ParentDevice,
|
||||
PFN_WDFDEVICE_WDM_IRP_PREPROCESS PNPPreProcess,
|
||||
PFN_WDF_DEVICE_SELF_MANAGED_IO_INIT SelfManagedIoInit)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
auto DevInit = WdfPdoInitAllocate(ParentDevice);
|
||||
|
||||
if (DevInit == nullptr)
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_REDIRECTOR, "%!FUNC! Cannot allocate DeviceInit for PDO");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Attach(DevInit);
|
||||
|
||||
//TODO: Put real values
|
||||
#define REDIRECTOR_HARDWARE_IDS L"USB\\Vid_FEED&Pid_CAFE&Rev_0001\0USB\\Vid_FEED&Pid_CAFE\0"
|
||||
#define REDIRECTOR_COMPATIBLE_IDS L"USB\\Class_FF&SubClass_FF&Prot_FF\0USB\\Class_FF&SubClass_FF\0USB\\Class_FF\0"
|
||||
#define REDIRECTOR_INSTANCE_ID L"111222333"
|
||||
|
||||
DECLARE_CONST_UNICODE_STRING(RedirectorHwId, REDIRECTOR_HARDWARE_IDS);
|
||||
DECLARE_CONST_UNICODE_STRING(RedirectorCompatId, REDIRECTOR_COMPATIBLE_IDS);
|
||||
DECLARE_CONST_UNICODE_STRING(RedirectorInstanceId, REDIRECTOR_INSTANCE_ID);
|
||||
|
||||
auto status = WdfPdoInitAssignDeviceID(DevInit, &RedirectorHwId);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_REDIRECTOR, "%!FUNC! WdfPdoInitAssignDeviceID failed");
|
||||
return status;
|
||||
}
|
||||
|
||||
status = WdfPdoInitAddCompatibleID(DevInit, &RedirectorCompatId);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_REDIRECTOR, "%!FUNC! WdfPdoInitAddCompatibleID failed");
|
||||
return status;
|
||||
}
|
||||
|
||||
status = WdfPdoInitAddHardwareID(DevInit, &RedirectorCompatId);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_REDIRECTOR, "%!FUNC! WdfPdoInitAddHardwareID failed");
|
||||
return status;
|
||||
}
|
||||
|
||||
status = WdfPdoInitAssignInstanceID(DevInit, &RedirectorInstanceId);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_REDIRECTOR, "%!FUNC! WdfPdoInitAssignInstanceID failed");
|
||||
return status;
|
||||
}
|
||||
|
||||
// {52AF46D0-AB11-4A38-96A5-BC0AC6ABD2AF}
|
||||
static const GUID GUID_USBDK_REDIRECTED_DEVICE =
|
||||
{ 0x52af46d0, 0xab11, 0x4a38, { 0x96, 0xa5, 0xbc, 0xa, 0xc6, 0xab, 0xd2, 0xaf } };
|
||||
|
||||
status = SetRaw(&GUID_USBDK_REDIRECTED_DEVICE);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_REDIRECTOR, "%!FUNC! WdfPdoInitAssignRawDevice failed");
|
||||
return status;
|
||||
}
|
||||
|
||||
SetExclusive();
|
||||
SetIoDirect();
|
||||
SetPowerCallbacks(SelfManagedIoInit);
|
||||
|
||||
status = SetPreprocessCallback(PNPPreProcess, IRP_MJ_PNP);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_REDIRECTOR, "%!FUNC! Setting pre-process callback for IRP_MJ_PNP failed");
|
||||
return status;
|
||||
}
|
||||
|
||||
DECLARE_CONST_UNICODE_STRING(ntDeviceName, USBDK_TEMP_REDIRECTOR_DEVICE_NAME);
|
||||
return SetName(ntDeviceName);
|
||||
}
|
||||
|
||||
CUsbDkRedirectorPDODevice::~CUsbDkRedirectorPDODevice()
|
||||
{
|
||||
//Life cycle of this device in controlled by PnP manager outside of WDF,
|
||||
//We detach WDF object here to avoid explicit deletion
|
||||
m_Device = WDF_NO_HANDLE;
|
||||
}
|
||||
|
||||
NTSTATUS CUsbDkRedirectorPDODevice::PassThroughPreProcessWithCompletion(_Inout_ PIRP Irp,
|
||||
PIO_COMPLETION_ROUTINE CompletionRoutine)
|
||||
{
|
||||
IoCopyCurrentIrpStackLocationToNext(Irp);
|
||||
|
||||
IoSetCompletionRoutineEx(WdfDeviceWdmGetDeviceObject(m_Device),
|
||||
Irp,
|
||||
CompletionRoutine,
|
||||
this,
|
||||
TRUE, FALSE, FALSE);
|
||||
|
||||
return IoCallDriver(m_RequestTarget, Irp);
|
||||
}
|
||||
|
||||
NTSTATUS CUsbDkRedirectorPDODevice::PNPPreProcess(_Inout_ PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_REDIRECTOR, "%!FUNC! Entry, IRP [%x:%x]", irpStack->MajorFunction, irpStack->MinorFunction);
|
||||
|
||||
switch (irpStack->MinorFunction)
|
||||
{
|
||||
case IRP_MN_QUERY_ID:
|
||||
case IRP_MN_DEVICE_ENUMERATED:
|
||||
case IRP_MN_START_DEVICE:
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return WdfDeviceWdmDispatchPreprocessedIrp(m_Device, Irp);
|
||||
case IRP_MN_QUERY_CAPABILITIES:
|
||||
return PassThroughPreProcessWithCompletion(Irp,
|
||||
[](_In_ PDEVICE_OBJECT, _In_ PIRP Irp, PVOID Context) -> NTSTATUS
|
||||
{
|
||||
auto This = static_cast<CUsbDkRedirectorPDODevice *>(Context);
|
||||
return This->QueryCapabilitiesPostProcess(Irp);
|
||||
});
|
||||
default:
|
||||
return PassThroughPreProcess(Irp);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS CUsbDkRedirectorPDODevice::QueryCapabilitiesPostProcess(_Inout_ PIRP Irp)
|
||||
{
|
||||
if (Irp->PendingReturned)
|
||||
{
|
||||
IoMarkIrpPending(Irp);
|
||||
}
|
||||
|
||||
auto irpStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
irpStack->Parameters.DeviceCapabilities.Capabilities->RawDeviceOK = 1;
|
||||
|
||||
return STATUS_CONTINUE_COMPLETION;
|
||||
}
|
||||
|
||||
NTSTATUS CUsbDkRedirectorPDODevice::SelfManagedIoInit()
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_REDIRECTOR, "%!FUNC! Entry");
|
||||
|
||||
DECLARE_CONST_UNICODE_STRING(ntDosDeviceName, USBDK_TEMP_REDIRECTOR_NAME);
|
||||
auto status = CreateSymLink(ntDosDeviceName);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_REDIRECTOR, "%!FUNC! Failed to create a symbolic link for a redirector device (%!STATUS!)", status);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS CUsbDkRedirectorPDODevice::Create(WDFDEVICE ParentDevice, const PDEVICE_OBJECT OrigPDO)
|
||||
{
|
||||
CUsbDkRedirectorPDOInit devInit;
|
||||
|
||||
auto status = devInit.Create(ParentDevice,
|
||||
[](_In_ WDFDEVICE Device, _Inout_ PIRP Irp)
|
||||
{ return UsbDkRedirectorPdoGetData(Device)->UsbDkRedirectorPDO->PNPPreProcess(Irp); },
|
||||
[](_In_ WDFDEVICE Device)
|
||||
{ return UsbDkRedirectorPdoGetData(Device)->UsbDkRedirectorPDO->SelfManagedIoInit(); });
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
WDF_OBJECT_ATTRIBUTES attr;
|
||||
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attr, USBDK_REDIRECTOR_PDO_EXTENSION);
|
||||
|
||||
attr.EvtCleanupCallback = CUsbDkRedirectorPDODevice::ContextCleanup;
|
||||
|
||||
status = CWdfDevice::Create(devInit, attr);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
auto deviceContext = UsbDkRedirectorPdoGetData(m_Device);
|
||||
deviceContext->UsbDkRedirectorPDO = this;
|
||||
|
||||
auto redirectorDevObj = WdfDeviceWdmGetDeviceObject(m_Device);
|
||||
m_RequestTarget = IoAttachDeviceToDeviceStack(redirectorDevObj, OrigPDO);
|
||||
if (m_RequestTarget == nullptr)
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_REDIRECTOR, "%!FUNC! Failed to attach device to device stack");
|
||||
status = STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void CUsbDkRedirectorPDODevice::ContextCleanup(_In_ WDFOBJECT DeviceObject)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_REDIRECTOR, "%!FUNC! Entry");
|
||||
|
||||
auto deviceContext = UsbDkRedirectorPdoGetData(DeviceObject);
|
||||
UNREFERENCED_PARAMETER(deviceContext);
|
||||
|
||||
delete deviceContext->UsbDkRedirectorPDO;
|
||||
}
|
||||
40
UsbDk/RedirectorDevice.h
Normal file
40
UsbDk/RedirectorDevice.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
|
||||
#include "ntddk.h"
|
||||
#include "wdf.h"
|
||||
#include "WdfDevice.h"
|
||||
#include "Alloc.h"
|
||||
|
||||
class CUsbDkRedirectorPDODevice : public CWdfDevice, public CAllocatable<NonPagedPool, 'PRHR'>
|
||||
{
|
||||
public:
|
||||
CUsbDkRedirectorPDODevice()
|
||||
{}
|
||||
~CUsbDkRedirectorPDODevice();
|
||||
|
||||
NTSTATUS Create(WDFDEVICE ParentDevice, const PDEVICE_OBJECT OrigPDO);
|
||||
|
||||
WDFDEVICE RawObject() const { return m_Device; }
|
||||
|
||||
CUsbDkRedirectorPDODevice(const CUsbDkRedirectorPDODevice&) = delete;
|
||||
CUsbDkRedirectorPDODevice& operator= (const CUsbDkRedirectorPDODevice&) = delete;
|
||||
|
||||
private:
|
||||
static void ContextCleanup(_In_ WDFOBJECT DeviceObject);
|
||||
|
||||
NTSTATUS PNPPreProcess(_Inout_ PIRP Irp);
|
||||
|
||||
NTSTATUS PassThroughPreProcess(_Inout_ PIRP Irp)
|
||||
{
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return IoCallDriver(m_RequestTarget, Irp);
|
||||
}
|
||||
|
||||
NTSTATUS PassThroughPreProcessWithCompletion(_Inout_ PIRP Irp, PIO_COMPLETION_ROUTINE CompletionRoutine);
|
||||
|
||||
NTSTATUS QueryCapabilitiesPostProcess(_Inout_ PIRP Irp);
|
||||
|
||||
NTSTATUS SelfManagedIoInit();
|
||||
|
||||
PDEVICE_OBJECT m_RequestTarget = nullptr;
|
||||
};
|
||||
|
|
@ -27,6 +27,7 @@
|
|||
WPP_DEFINE_BIT(TRACE_CONTROLDEVICE) \
|
||||
WPP_DEFINE_BIT(TRACE_FILTERDEVICE) \
|
||||
WPP_DEFINE_BIT(TRACE_WDFDEVICE) \
|
||||
WPP_DEFINE_BIT(TRACE_REDIRECTOR) \
|
||||
)
|
||||
|
||||
#define WPP_FLAG_LEVEL_LOGGER(flag, level) \
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
<ClCompile Include="FilterDevice.cpp" />
|
||||
<ClCompile Include="Irp.cpp" />
|
||||
<ClCompile Include="MemoryBuffer.cpp" />
|
||||
<ClCompile Include="RedirectorDevice.cpp" />
|
||||
<ClCompile Include="RegText.cpp" />
|
||||
<ClCompile Include="UsbDkUtil.cpp" />
|
||||
<ClCompile Include="WdfDevice.cpp" />
|
||||
|
|
@ -71,6 +72,7 @@
|
|||
<ClInclude Include="Irp.h" />
|
||||
<ClInclude Include="MemoryBuffer.h" />
|
||||
<ClInclude Include="Public.h" />
|
||||
<ClInclude Include="RedirectorDevice.h" />
|
||||
<ClInclude Include="RegText.h" />
|
||||
<ClInclude Include="UsbDkData.h" />
|
||||
<ClInclude Include="UsbDkNames.h" />
|
||||
|
|
|
|||
|
|
@ -67,6 +67,9 @@
|
|||
<ClInclude Include="UsbDkNames.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RedirectorDevice.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Driver.cpp">
|
||||
|
|
@ -99,5 +102,8 @@
|
|||
<ClCompile Include="UsbDkUtil.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RedirectorDevice.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Loading…
Add table
Add a link
Reference in a new issue