Compare commits

...
Sign in to create a new pull request.

6 commits

Author SHA1 Message Date
Yan Vugenfirer
af46b7ee33 Fix appveyor badge in Readme
Signed-off-by: Yan Vugenfirer <yan@daynix.com>
2020-10-05 15:14:09 +03:00
Yuri Benditovich
84752c3003 build: fix build of Debug_NoSign
Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
2020-02-27 17:34:04 +02:00
Yuri Benditovich
3b80562684 build: remove binary DLL from the repository
Collect all the 'before-build' actions in single batch file.
Download the DLL required for AppVeyor during the build.
Remove the DLL from the repository.

Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
2020-01-27 20:00:38 +02:00
Yuri Benditovich
3d2e5a6272 driver: bring device to D0 before redirection
Device redirection often fails when the device is in D3/D2 when
we start redirecting it. Current commit brings the device to
D0 before sending 'cycle power' command to the device port if
the device is in low power mode at the moment of starting
redirection.

Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
2020-01-27 19:49:45 +02:00
Yuri Benditovich
c565bd513e driver: add procedure for getting power data by PDO
Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
2020-01-27 19:49:45 +02:00
Yuri Benditovich
c736f5d8be driver: fix driver verifier assertion in FileCreate callback
Previous commit 4de57a9ff causes driver verifier assertion with
latest Windows builds. Note that this assertion is not in latest
WDF sources on GitHub. The verifier does not allow to forward
the MJ_CREATE requestto local IO target using "send-and-forget".
It requires the request to set completion callback.
There is an option to remove the file create callback at all, but
we prefer to have printout on file open for better diagnostics.
So we add completion callback for forwarded request and complete
the request in it.

Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
2020-01-27 19:49:45 +02:00
11 changed files with 79 additions and 15 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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,

View file

@ -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);

View file

@ -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))

View file

@ -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);

View file

@ -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)

View file

@ -16,7 +16,9 @@ extern "C"
#include <usb.h>
#if !TARGET_OS_WIN_XP
#include <initguid.h>
#include <UsbSpec.h>
#include <devpkey.h>
#else
#define USB_DEVICE_CLASS_AUDIO 0x01
#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02

View file

@ -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