diff --git a/UsbDk/ControlDevice.cpp b/UsbDk/ControlDevice.cpp index d476fc6..aeef267 100644 --- a/UsbDk/ControlDevice.cpp +++ b/UsbDk/ControlDevice.cpp @@ -366,12 +366,29 @@ NTSTATUS CUsbDkControlDevice::Create(WDFDRIVER Driver) attr.EvtCleanupCallback = ContextCleanup; status = CWdfControlDevice::Create(DeviceInit, attr); - if (NT_SUCCESS(status)) + if (!NT_SUCCESS(status)) { - UsbDkControlGetContext(m_Device)->UsbDkControl = this; + return status; } - return status; + UsbDkControlGetContext(m_Device)->UsbDkControl = this; + + CObjHolder HiderDevice(new CUsbDkHiderDevice()); + if (!HiderDevice) + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_CONTROLDEVICE, "%!FUNC! Hider device allocation failed"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + status = HiderDevice->Create(Driver); + if (!NT_SUCCESS(status)) + { + return status; + } + + m_HiderDevice = HiderDevice.detach(); + + return m_HiderDevice->Register(); } NTSTATUS CUsbDkControlDevice::Register() diff --git a/UsbDk/ControlDevice.h b/UsbDk/ControlDevice.h index 6b81310..9b9687b 100644 --- a/UsbDk/ControlDevice.h +++ b/UsbDk/ControlDevice.h @@ -240,6 +240,8 @@ private: CObjHolder m_DeviceQueue; static CRefCountingHolder *m_UsbDkControlDevice; + CObjHolder > m_HiderDevice; + CWdmList m_FilterDevices; typedef CWdmSet RedirectionsSet; diff --git a/UsbDk/HiderDevice.cpp b/UsbDk/HiderDevice.cpp new file mode 100644 index 0000000..32132cd --- /dev/null +++ b/UsbDk/HiderDevice.cpp @@ -0,0 +1,140 @@ +/********************************************************************** +* Copyright (c) 2013-2014 Red Hat, Inc. +* +* Developed by Daynix Computing LTD. +* +* Authors: +* Dmitry Fleytman +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +**********************************************************************/ + +#include "stdafx.h" +#include "HiderDevice.h" +#include "trace.h" +#include "WdfRequest.h" +#include "HiderDevice.tmh" +#include "Public.h" + +class CUsbDkHiderDeviceInit : public CDeviceInit +{ +public: + CUsbDkHiderDeviceInit() + {} + + NTSTATUS Create(WDFDRIVER Driver); + + CUsbDkHiderDeviceInit(const CUsbDkHiderDeviceInit&) = delete; + CUsbDkHiderDeviceInit& operator= (const CUsbDkHiderDeviceInit&) = delete; +}; + +NTSTATUS CUsbDkHiderDeviceInit::Create(WDFDRIVER Driver) +{ + auto DeviceInit = WdfControlDeviceInitAllocate(Driver, &SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_RWX); + if (DeviceInit == nullptr) + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_WDFDEVICE, "%!FUNC! Cannot allocate DeviceInit"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + Attach(DeviceInit); + SetExclusive(); + SetIoBuffered(); + + DECLARE_CONST_UNICODE_STRING(ntDeviceName, USBDK_HIDER_DEVICE_NAME); + return SetName(ntDeviceName); +} + +void CUsbDkHiderDeviceQueue::SetCallbacks(WDF_IO_QUEUE_CONFIG &QueueConfig) +{ + QueueConfig.EvtIoDeviceControl = CUsbDkHiderDeviceQueue::DeviceControl; +} + +void CUsbDkHiderDeviceQueue::DeviceControl(WDFQUEUE Queue, + WDFREQUEST Request, + size_t OutputBufferLength, + size_t InputBufferLength, + ULONG IoControlCode) +{ + UNREFERENCED_PARAMETER(Queue); + UNREFERENCED_PARAMETER(OutputBufferLength); + UNREFERENCED_PARAMETER(InputBufferLength); + + CWdfRequest WdfRequest(Request); + + TraceEvents(TRACE_LEVEL_ERROR, TRACE_HIDERDEVICE, "Wrong IoControlCode 0x%X\n", IoControlCode); + WdfRequest.SetStatus(STATUS_INVALID_DEVICE_REQUEST); +} +//------------------------------------------------------------------------------------------------------------ + +void CUsbDkHiderDevice::ContextCleanup(_In_ WDFOBJECT DeviceObject) +{ + PAGED_CODE(); + + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_HIDERDEVICE, "%!FUNC! Entry"); + + auto deviceContext = UsbDkHiderGetContext(DeviceObject); + delete deviceContext->UsbDkHider; +} +//------------------------------------------------------------------------------------------------------------ + +NTSTATUS CUsbDkHiderDevice::Create(WDFDRIVER Driver) +{ + CUsbDkHiderDeviceInit DeviceInit; + + auto status = DeviceInit.Create(Driver); + if (!NT_SUCCESS(status)) + { + return status; + } + + WDF_OBJECT_ATTRIBUTES attr; + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attr, USBDK_HIDER_DEVICE_EXTENSION); + attr.EvtCleanupCallback = ContextCleanup; + + status = CWdfControlDevice::Create(DeviceInit, attr); + if (NT_SUCCESS(status)) + { + UsbDkHiderGetContext(m_Device)->UsbDkHider = this; + m_Driver = Driver; + } + + return status; +} + +NTSTATUS CUsbDkHiderDevice::Register() +{ + DECLARE_CONST_UNICODE_STRING(ntDosDeviceName, USBDK_DOS_HIDER_DEVICE_NAME); + auto status = CreateSymLink(ntDosDeviceName); + if (!NT_SUCCESS(status)) + { + return status; + } + + m_DeviceQueue = new CUsbDkHiderDeviceQueue(*this, WdfIoQueueDispatchSequential); + if (m_DeviceQueue == nullptr) + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_HIDERDEVICE, "%!FUNC! Device queue allocation failed"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + status = m_DeviceQueue->Create(); + if (NT_SUCCESS(status)) + { + FinishInitializing(); + } + + return status; +} +//----------------------------------------------------------------------------------------------------- diff --git a/UsbDk/HiderDevice.h b/UsbDk/HiderDevice.h new file mode 100644 index 0000000..9ad13e8 --- /dev/null +++ b/UsbDk/HiderDevice.h @@ -0,0 +1,77 @@ +/********************************************************************** +* Copyright (c) 2013-2014 Red Hat, Inc. +* +* Developed by Daynix Computing LTD. +* +* Authors: +* Dmitry Fleytman +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +**********************************************************************/ + +#pragma once + +#include "WdfDevice.h" +#include "Alloc.h" +#include "UsbDkUtil.h" + +class CWdfRequest; + +class CUsbDkHiderDeviceQueue : public CWdfDefaultQueue, public CAllocatable +{ +public: + CUsbDkHiderDeviceQueue(CWdfDevice &Device, WDF_IO_QUEUE_DISPATCH_TYPE DispatchType) + : CWdfDefaultQueue(Device, DispatchType) + {} + +private: + virtual void SetCallbacks(WDF_IO_QUEUE_CONFIG &QueueConfig) override; + static void DeviceControl(WDFQUEUE Queue, + WDFREQUEST Request, + size_t OutputBufferLength, + size_t InputBufferLength, + ULONG IoControlCode); + + CUsbDkHiderDeviceQueue(const CUsbDkHiderDeviceQueue&) = delete; + CUsbDkHiderDeviceQueue& operator= (const CUsbDkHiderDeviceQueue&) = delete; +}; + +class CUsbDkHiderDevice : private CWdfControlDevice, public CAllocatable +{ +public: + CUsbDkHiderDevice() {} + NTSTATUS Create(WDFDRIVER Driver); + NTSTATUS Register(); + void Delete() + { CWdfControlDevice::Delete(); } + WDFDRIVER DriverHandle() const + { return m_Driver; } + +private: + static void ContextCleanup(_In_ WDFOBJECT DeviceObject); + CObjHolder m_DeviceQueue; + WDFDRIVER m_Driver = nullptr; + + friend class CUsbDkHiderDeviceInit; +}; + +typedef struct _USBDK_HIDER_DEVICE_EXTENSION { + + CUsbDkHiderDevice *UsbDkHider; + + _USBDK_HIDER_DEVICE_EXTENSION(const _USBDK_HIDER_DEVICE_EXTENSION&) = delete; + _USBDK_HIDER_DEVICE_EXTENSION& operator= (const _USBDK_HIDER_DEVICE_EXTENSION&) = delete; + +} USBDK_HIDER_DEVICE_EXTENSION, *PUSBDK_HIDER_DEVICE_EXTENSION; +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(USBDK_HIDER_DEVICE_EXTENSION, UsbDkHiderGetContext); diff --git a/UsbDk/Trace.h b/UsbDk/Trace.h index dce09d3..7270ec4 100644 --- a/UsbDk/Trace.h +++ b/UsbDk/Trace.h @@ -38,6 +38,7 @@ WPP_DEFINE_BIT(TRACE_DEVACCESS) \ WPP_DEFINE_BIT(TRACE_REGTEXT) \ WPP_DEFINE_BIT(TRACE_CONTROLDEVICE) \ + WPP_DEFINE_BIT(TRACE_HIDERDEVICE) \ WPP_DEFINE_BIT(TRACE_FILTERDEVICE) \ WPP_DEFINE_BIT(TRACE_WDFDEVICE) \ WPP_DEFINE_BIT(TRACE_REDIRECTOR) \ diff --git a/UsbDk/UsbDk.vcxproj b/UsbDk/UsbDk.vcxproj index 3e5bb4f..05b2cee 100644 --- a/UsbDk/UsbDk.vcxproj +++ b/UsbDk/UsbDk.vcxproj @@ -72,6 +72,7 @@ + @@ -91,6 +92,7 @@ + diff --git a/UsbDk/UsbDk.vcxproj.filters b/UsbDk/UsbDk.vcxproj.filters index 701b451..3de99ea 100644 --- a/UsbDk/UsbDk.vcxproj.filters +++ b/UsbDk/UsbDk.vcxproj.filters @@ -144,6 +144,9 @@ Source Files + + Source Files + diff --git a/UsbDk/UsbDkNames.h b/UsbDk/UsbDkNames.h index 2a2a8b0..8584e52 100644 --- a/UsbDk/UsbDkNames.h +++ b/UsbDk/UsbDkNames.h @@ -29,3 +29,8 @@ #define USBDK_DEVICE_NAME TEXT("\\Device\\") USBDK_DRIVER_NAME #define USBDK_DOSDEVICE_NAME TEXT("\\DosDevices\\") USBDK_DRIVER_NAME #define USBDK_USERMODE_NAME TEXT("\\\\.\\") USBDK_DRIVER_NAME + +#define _USBDK_HIDER_NAME TEXT("UsbDkHider") +#define USBDK_HIDER_DEVICE_NAME TEXT("\\Device\\") _USBDK_HIDER_NAME +#define USBDK_DOS_HIDER_DEVICE_NAME TEXT("\\DosDevices\\") _USBDK_HIDER_NAME +#define USBDK_USERMODE_HIDER_NAME TEXT("\\\\.\\") _USBDK_HIDER_NAME