diff --git a/.appveyor.yml b/.appveyor.yml index 0f5e8d9..2a8aefc 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -3,7 +3,7 @@ image: Visual Studio 2015 version: build-{build}-{branch} before_build: - - copy /y tools\AppVeyor\Microsoft.DriverKit.Build.Tasks.14.0.dll "C:\Program Files (x86)\Windows Kits\10\build\bin" + - tools\AppVeyor\before-build.cmd build_script: buildAll.bat diff --git a/README.md b/README.md index c1a5b23..f8317f1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://ci.appveyor.com/api/projects/status/github/daynix/usbdk?branch=master&svg=true)](https://ci.appveyor.com/project/daynix/usbdk) +[![Build Status](https://ci.appveyor.com/api/projects/status/p3s6bdbx8mq8o0hu?svg=true)](https://ci.appveyor.com/api/projects/status/p3s6bdbx8mq8o0hu?svg=true) # UsbDk diff --git a/Tools/AppVeyor/Microsoft.DriverKit.Build.Tasks.14.0.dll b/Tools/AppVeyor/Microsoft.DriverKit.Build.Tasks.14.0.dll deleted file mode 100644 index da6d81c..0000000 Binary files a/Tools/AppVeyor/Microsoft.DriverKit.Build.Tasks.14.0.dll and /dev/null differ diff --git a/Tools/AppVeyor/before-build.cmd b/Tools/AppVeyor/before-build.cmd new file mode 100644 index 0000000..c3258d1 --- /dev/null +++ b/Tools/AppVeyor/before-build.cmd @@ -0,0 +1,5 @@ +@echo off +pushd "%~dp0" +curl -L -s https://drive.google.com/uc?id=17ZK6a1kxhTR-YOkWpAOqNJZA7UBUGkmu --output Microsoft.DriverKit.Build.Tasks.14.0.dll +copy /y Microsoft.DriverKit.Build.Tasks.14.0.dll "C:\Program Files (x86)\Windows Kits\10\build\bin" +popd diff --git a/UsbDk/ControlDevice.cpp b/UsbDk/ControlDevice.cpp index 75b09e3..a244a31 100644 --- a/UsbDk/ControlDevice.cpp +++ b/UsbDk/ControlDevice.cpp @@ -451,7 +451,7 @@ PDEVICE_OBJECT CUsbDkControlDevice::GetPDOByDeviceID(const USB_DK_DEVICE_ID &Dev return PDO; } -NTSTATUS CUsbDkControlDevice::ResetUsbDevice(const USB_DK_DEVICE_ID &DeviceID) +NTSTATUS CUsbDkControlDevice::ResetUsbDevice(const USB_DK_DEVICE_ID &DeviceID, bool ForceD0) { PDEVICE_OBJECT PDO = GetPDOByDeviceID(DeviceID); if (PDO == nullptr) @@ -460,7 +460,7 @@ NTSTATUS CUsbDkControlDevice::ResetUsbDevice(const USB_DK_DEVICE_ID &DeviceID) } CWdmUsbDeviceAccess pdoAccess(PDO); - auto status = pdoAccess.Reset(); + auto status = pdoAccess.Reset(ForceD0); ObDereferenceObject(PDO); return status; @@ -707,7 +707,7 @@ void CUsbDkControlDevice::AddRedirectRollBack(const USB_DK_DEVICE_ID &DeviceId, return; } - auto resetRes = ResetUsbDevice(DeviceId); + auto resetRes = ResetUsbDevice(DeviceId, false); if (!NT_SUCCESS(resetRes)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_CONTROLDEVICE, "%!FUNC! Roll-back reset failed. %!STATUS!", resetRes); @@ -737,7 +737,7 @@ NTSTATUS CUsbDkControlDevice::AddRedirect(const USB_DK_DEVICE_ID &DeviceId, HAND TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_CONTROLDEVICE, "%!FUNC! Success. New redirections list:"); m_Redirections.Dump(); - auto resetRes = ResetUsbDevice(DeviceId); + auto resetRes = ResetUsbDevice(DeviceId, true); if (!NT_SUCCESS(resetRes)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_CONTROLDEVICE, "%!FUNC! Reset after start redirection failed. %!STATUS!", resetRes); @@ -1029,7 +1029,7 @@ NTSTATUS CUsbDkControlDevice::RemoveRedirect(const USB_DK_DEVICE_ID &DeviceId) { if (NotifyRedirectorRemovalStarted(DeviceId)) { - auto res = ResetUsbDevice(DeviceId); + auto res = ResetUsbDevice(DeviceId, false); if (NT_SUCCESS(res)) { TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_CONTROLDEVICE, diff --git a/UsbDk/ControlDevice.h b/UsbDk/ControlDevice.h index 7e7cd0f..9223036 100644 --- a/UsbDk/ControlDevice.h +++ b/UsbDk/ControlDevice.h @@ -266,7 +266,7 @@ public: { return ReloadPersistentHideRules(); } bool EnumerateDevices(USB_DK_DEVICE_INFO *outBuff, size_t numberAllocatedDevices, size_t &numberExistingDevices); - NTSTATUS ResetUsbDevice(const USB_DK_DEVICE_ID &DeviceId); + NTSTATUS ResetUsbDevice(const USB_DK_DEVICE_ID &DeviceId, bool ForceD0); NTSTATUS AddRedirect(const USB_DK_DEVICE_ID &DeviceId, HANDLE RequestorProcess, PHANDLE ObjectHandle); NTSTATUS AddHideRule(const USB_DK_HIDE_RULE &UsbDkRule); diff --git a/UsbDk/DeviceAccess.cpp b/UsbDk/DeviceAccess.cpp index 657c0b9..6810a18 100644 --- a/UsbDk/DeviceAccess.cpp +++ b/UsbDk/DeviceAccess.cpp @@ -168,6 +168,41 @@ SIZE_T CWdmDeviceAccess::GetIdBufferLength(BUS_QUERY_ID_TYPE idType, PWCHAR idDa } } +bool CWdmDeviceAccess::QueryPowerData(CM_POWER_DATA& powerData) +{ + powerData.PD_Size = sizeof(powerData); +#if !TARGET_OS_WIN_XP + ULONG dummy; + DEVPROPTYPE propType; + auto status = IoGetDevicePropertyData(m_DevObj, &DEVPKEY_Device_PowerData, LOCALE_NEUTRAL, 0, + sizeof(powerData), &powerData, &dummy, &propType); + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVACCESS, "%!FUNC! Error %!STATUS!", status); + } + return NT_SUCCESS(status); +#else + return false; +#endif +} + +static void PowerRequestCompletion( + _In_ PDEVICE_OBJECT DeviceObject, + _In_ UCHAR MinorFunction, + _In_ POWER_STATE PowerState, + _In_opt_ PVOID Context, + _In_ PIO_STATUS_BLOCK IoStatus +) +{ + UNREFERENCED_PARAMETER(DeviceObject); + UNREFERENCED_PARAMETER(MinorFunction); + UNREFERENCED_PARAMETER(PowerState); + UNREFERENCED_PARAMETER(IoStatus); + CWdmEvent *pev = (CWdmEvent *)Context; + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVACCESS, "%!FUNC! -> D%d", PowerState.DeviceState - 1); + pev->Set(); +} + PWCHAR CWdmDeviceAccess::MakeNonPagedDuplicate(BUS_QUERY_ID_TYPE idType, PWCHAR idData) { auto bufferLength = GetIdBufferLength(idType, idData); @@ -215,9 +250,23 @@ NTSTATUS CWdmDeviceAccess::QueryForInterface(const GUID &guid, __out INTERFACE & return status; } -NTSTATUS CWdmUsbDeviceAccess::Reset() +NTSTATUS CWdmUsbDeviceAccess::Reset(bool ForceD0) { CIoControlIrp Irp; + CM_POWER_DATA powerData; + if (ForceD0 && QueryPowerData(powerData) && powerData.PD_MostRecentPowerState != PowerDeviceD0) + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVACCESS, "%!FUNC! device power state D%d", powerData.PD_MostRecentPowerState - 1); + POWER_STATE PowerState; + CWdmEvent Event; + PowerState.DeviceState = PowerDeviceD0; + auto status = PoRequestPowerIrp(m_DevObj, IRP_MN_SET_POWER, PowerState, PowerRequestCompletion, &Event, NULL); + if (NT_SUCCESS(status)) + { + Event.Wait(); + } + } + auto status = Irp.Create(m_DevObj, IOCTL_INTERNAL_USB_CYCLE_PORT); if (!NT_SUCCESS(status)) diff --git a/UsbDk/DeviceAccess.h b/UsbDk/DeviceAccess.h index 5520210..0749102 100644 --- a/UsbDk/DeviceAccess.h +++ b/UsbDk/DeviceAccess.h @@ -52,7 +52,7 @@ public: ULONG GetAddress(); CRegText *GetDeviceID() { return new CRegSz(QueryBusID(BusQueryDeviceID)); } CRegText *GetInstanceID() { return new CRegSz(QueryBusID(BusQueryInstanceID)); } - + bool QueryPowerData(CM_POWER_DATA& powerData); protected: PDEVICE_OBJECT m_DevObj; @@ -71,7 +71,7 @@ public: : CWdmDeviceAccess(WdmDevice) { } - NTSTATUS Reset(); + NTSTATUS Reset(bool ForceD0); NTSTATUS GetDeviceDescriptor(USB_DEVICE_DESCRIPTOR &Descriptor); NTSTATUS GetConfigurationDescriptor(UCHAR Index, USB_CONFIGURATION_DESCRIPTOR &Descriptor, size_t Length); diff --git a/UsbDk/FilterDevice.cpp b/UsbDk/FilterDevice.cpp index 8fe016e..22d4383 100644 --- a/UsbDk/FilterDevice.cpp +++ b/UsbDk/FilterDevice.cpp @@ -481,11 +481,19 @@ bool CUsbDkChildDevice::AttachToDeviceStack() void CUsbDkFilterDevice::OnFileCreate(WDFREQUEST Request) { - WDF_REQUEST_SEND_OPTIONS options; - WDF_REQUEST_SEND_OPTIONS_INIT(&options, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET); + CWdfRequest r(Request); + WdfRequestFormatRequestUsingCurrentType(Request); // in the log we'll see which process created the file TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FILTERDEVICE, "%!FUNC!"); - WdfRequestSend(Request, IOTarget(), &options); + r.SendWithCompletion(IOTarget(), [](WDFREQUEST Request, WDFIOTARGET Target, PWDF_REQUEST_COMPLETION_PARAMS Params, WDFCONTEXT Context) + { + UNREFERENCED_PARAMETER(Target); + CWdfRequest r(Request); + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FILTERDEVICE, "%s: completed", (LPCSTR)Context); + r.SetStatus(Params->IoStatus.Status); + r.SetBytesWritten(Params->IoStatus.Information); + }, + __FUNCTION__); } NTSTATUS CUsbDkFilterDevice::AttachToStack(WDFDRIVER Driver) diff --git a/UsbDk/stdafx.h b/UsbDk/stdafx.h index fccb90e..dc32ba2 100644 --- a/UsbDk/stdafx.h +++ b/UsbDk/stdafx.h @@ -16,7 +16,9 @@ extern "C" #include #if !TARGET_OS_WIN_XP +#include #include +#include #else #define USB_DEVICE_CLASS_AUDIO 0x01 #define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 diff --git a/buildAll.bat b/buildAll.bat index be49ab7..3e8f563 100644 --- a/buildAll.bat +++ b/buildAll.bat @@ -23,7 +23,7 @@ if !ERRORLEVEL! NEQ 0 exit /B 1 popd pushd Install_Debug -call :maketmf Debug +call :maketmf %DEBUG_CFG% if !ERRORLEVEL! NEQ 0 exit /B 1 popd