diff --git a/UsbDk/ControlDevice.cpp b/UsbDk/ControlDevice.cpp index ef8f571..a13b1ac 100644 --- a/UsbDk/ControlDevice.cpp +++ b/UsbDk/ControlDevice.cpp @@ -71,6 +71,18 @@ void CUsbDkControlDeviceQueue::DeviceControl(WDFQUEUE Queue, ResetDevice(WdfRequest, Queue); break; } + case IOCTL_USBDK_ADD_REDIRECT: + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_CONTROLDEVICE, "Called IOCTL_USBDK_ADD_REDIRECT\n"); + AddRedirect(WdfRequest, Queue); + break; + } + case IOCTL_USBDK_REMOVE_REDIRECT: + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_CONTROLDEVICE, "Called IOCTL_USBDK_REMOVE_REDIRECT\n"); + RemoveRedirect(WdfRequest, Queue); + break; + } default: { TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_CONTROLDEVICE, "Wrong IoControlCode 0x%X\n", IoControlCode); @@ -154,6 +166,18 @@ void CUsbDkControlDeviceQueue::ResetDevice(CWdfRequest &Request, WDFQUEUE Queue) } //------------------------------------------------------------------------------------------------------------ +void CUsbDkControlDeviceQueue::AddRedirect(CWdfRequest &Request, WDFQUEUE Queue) +{ + DoUSBDeviceOp(Request, Queue, &CUsbDkControlDevice::AddRedirect); +} +//------------------------------------------------------------------------------------------------------------ + +void CUsbDkControlDeviceQueue::RemoveRedirect(CWdfRequest &Request, WDFQUEUE Queue) +{ + DoUSBDeviceOp(Request, Queue, &CUsbDkControlDevice::RemoveRedirect); +} +//------------------------------------------------------------------------------------------------------------ + ULONG CUsbDkControlDevice::CountDevices() { ULONG numberDevices = 0; @@ -301,6 +325,48 @@ bool CUsbDkControlDevice::Allocate() return true; } +NTSTATUS CUsbDkControlDevice::AddRedirect(const USB_DK_DEVICE_ID &DeviceId) +{ + CObjHolder newRedir(new CUsbDkRedirection()); + + if (!newRedir) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + auto status = newRedir->Create(DeviceId); + if (!NT_SUCCESS(status)) + { + return status; + } + + if (!m_Redirections.Add(newRedir)) + { + return STATUS_OBJECT_NAME_COLLISION; + } + + newRedir.detach(); + + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_CONTROLDEVICE, "%!FUNC! Success. New redirections list:"); + m_Redirections.Dump(); + + return STATUS_SUCCESS; +} + +NTSTATUS CUsbDkControlDevice::RemoveRedirect(const USB_DK_DEVICE_ID &DeviceId) +{ + auto res = m_Redirections.Delete(&DeviceId); + + if (res) + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_CONTROLDEVICE, "%!FUNC! Success. New redirections list:"); + m_Redirections.Dump(); + return STATUS_SUCCESS; + } + + return STATUS_OBJECT_NAME_NOT_FOUND; +} + NTSTATUS CUsbDkRedirection::Create(const USB_DK_DEVICE_ID &Id) { auto status = m_DeviceID.Create(Id.DeviceID); diff --git a/UsbDk/ControlDevice.h b/UsbDk/ControlDevice.h index 13ada60..04d0aab 100644 --- a/UsbDk/ControlDevice.h +++ b/UsbDk/ControlDevice.h @@ -29,6 +29,9 @@ private: static void CountDevices(CWdfRequest &Request, WDFQUEUE Queue); static void EnumerateDevices(CWdfRequest &Request, WDFQUEUE Queue); static void ResetDevice(CWdfRequest &Request, WDFQUEUE Queue); + static void AddRedirect(CWdfRequest &Request, WDFQUEUE Queue); + static void RemoveRedirect(CWdfRequest &Request, WDFQUEUE Queue); + typedef NTSTATUS(CUsbDkControlDevice::*USBDevControlMethod)(const USB_DK_DEVICE_ID&); static void DoUSBDeviceOp(CWdfRequest &Request, WDFQUEUE Queue, USBDevControlMethod Method); @@ -71,6 +74,8 @@ public: ULONG CountDevices(); bool EnumerateDevices(USB_DK_DEVICE_ID *outBuff, size_t numberAllocatedDevices, size_t &numberExistingDevices); NTSTATUS ResetUsbDevice(const USB_DK_DEVICE_ID &DeviceId); + NTSTATUS AddRedirect(const USB_DK_DEVICE_ID &DeviceId); + NTSTATUS RemoveRedirect(const USB_DK_DEVICE_ID &DeviceId); static bool Allocate(); static void Deallocate() @@ -84,6 +89,7 @@ private: static CRefCountingHolder *m_UsbDkControlDevice; CWdmList m_FilterDevices; + CWdmSet m_Redirections; template bool UsbDevicesForEachIf(TPredicate Predicate, TFunctor Functor) diff --git a/UsbDk/Public.h b/UsbDk/Public.h index c7ea796..d6c079d 100644 --- a/UsbDk/Public.h +++ b/UsbDk/Public.h @@ -36,3 +36,7 @@ DEFINE_GUID (GUID_DEVINTERFACE_UsbDk, ULONG(CTL_CODE( USBDK_DEVICE_TYPE, 0x852, METHOD_BUFFERED, FILE_READ_ACCESS )) #define IOCTL_USBDK_RESET_DEVICE \ ULONG(CTL_CODE( USBDK_DEVICE_TYPE, 0x853, METHOD_BUFFERED, FILE_READ_ACCESS )) +#define IOCTL_USBDK_ADD_REDIRECT \ + ULONG(CTL_CODE( USBDK_DEVICE_TYPE, 0x854, METHOD_BUFFERED, FILE_READ_ACCESS )) +#define IOCTL_USBDK_REMOVE_REDIRECT \ + ULONG(CTL_CODE( USBDK_DEVICE_TYPE, 0x855, METHOD_BUFFERED, FILE_READ_ACCESS ))