Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Private/bryan/no wdfiotarget retries #52

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions TailLight/INSTALL_TailLight.bat
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
:: Goto current directory
cd /d "%~dp0"

:: Use DevCon for installation, since it allows providing HWID
devcon /r install TailLight.inf "HID\VID_045E&PID_082A&MI_01&Col05"
:: Use DevCon for unsigned installation, since it allows providing HWID
::devcon /r install TailLight.inf "HID\VID_045E&PID_082A&MI_01&Col05"

:: Use PnpUtil for installation (succeeds but driver isn't loaded)
:: Use PnpUtil for installation of signed drivers of all forms.
::devgen /add /bus ROOT /hardwareid "HID\VID_045E&PID_082A&MI_01&Col05"
::PNPUTIL /add-driver TailLight.inf /install /reboot
PNPUTIL /add-driver TailLight.inf /install /reboot

pause
6 changes: 6 additions & 0 deletions TailLight/SetBlack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

NTSTATUS CreateWorkItemForIoTargetOpenDevice(WDFDEVICE device);
NTSTATUS SetBlackAsync(WDFDEVICE device);


250 changes: 250 additions & 0 deletions TailLight/SetTaillightBlack.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
#include "driver.h"
#include <Hidport.h>

#include "debug.h"
#include "SetBlack.h"

EVT_WDF_REQUEST_COMPLETION_ROUTINE SetBlackCompletionRoutine;
EVT_WDF_WORKITEM SetBlackWorkItem;

NTSTATUS CreateWorkItemForIoTargetOpenDevice(WDFDEVICE device)
/*++

Routine Description:

Creates a WDF workitem to do the SetBlack() call after the driver
stack has initialized.

Arguments:

Device - Handle to a pre-allocated WDF work item.

Requirements:
Must be synchronized to the device.

--*/
{

//TRACE_FN_ENTRY

WDFWORKITEM hWorkItem = 0;
NTSTATUS status = STATUS_PNP_DRIVER_CONFIGURATION_INCOMPLETE;
{
WDF_WORKITEM_CONFIG workItemConfig;
WDF_OBJECT_ATTRIBUTES workItemAttributes;
WDF_OBJECT_ATTRIBUTES_INIT(&workItemAttributes);
workItemAttributes.ParentObject = device;

DEVICE_CONTEXT* pDeviceContext = WdfObjectGet_DEVICE_CONTEXT(device);

// It's possible to get called twice. Been there, done that?
if (pDeviceContext->fSetBlackSuccess) {
return STATUS_SUCCESS;
}

WDF_WORKITEM_CONFIG_INIT(&workItemConfig, SetBlackWorkItem);

status = WdfWorkItemCreate(&workItemConfig,
&workItemAttributes,
&hWorkItem);

if (!NT_SUCCESS(status)) {
KdPrintEx((DPFLTR_IHVDRIVER_ID,
DPFLTR_ERROR_LEVEL,
"TailLight: Workitem creation failure 0x%x\n",
status));
return status; // Maybe better luck next time.
}

InterlockedIncrement((PLONG)(&pDeviceContext->fSetBlackSuccess));
}

WdfWorkItemEnqueue(hWorkItem);

//TRACE_FN_EXIT

return status;
}

static NTSTATUS TryToOpenIoTarget(WDFIOTARGET target,
DEVICE_CONTEXT& DeviceContext) {

PAGED_CODE();

WDF_IO_TARGET_OPEN_PARAMS openParams = {};
WDF_IO_TARGET_OPEN_PARAMS_INIT_CREATE_BY_NAME(
&openParams,
&DeviceContext.PdoName,
FILE_WRITE_ACCESS);

openParams.ShareAccess = FILE_SHARE_WRITE | FILE_SHARE_READ;

NTSTATUS status = STATUS_UNSUCCESSFUL;

// Ensure freed if fails.
status = WdfIoTargetOpen(target, &openParams);
if (!NT_SUCCESS(status)) {
KdPrintEx((DPFLTR_IHVDRIVER_ID,
DPFLTR_ERROR_LEVEL,
"TailLight: 0x%x while opening the I/O target from worker thread\n",
status));
NukeWdfHandle<WDFIOTARGET>(target);
}

return status;
}

void SetBlackCompletionRoutine(
_In_ WDFREQUEST Request,
_In_ WDFIOTARGET Target,
_In_ PWDF_REQUEST_COMPLETION_PARAMS Params,
_In_ WDFCONTEXT Context)
{
UNREFERENCED_PARAMETER(Target);
UNREFERENCED_PARAMETER(Params);
UNREFERENCED_PARAMETER(Context);

NTSTATUS status = STATUS_UNSUCCESSFUL;
status = WdfRequestGetStatus(Request);
KdPrint(("TailLight: %s WdfRequestSend status: 0x%x\n", __func__, status));

// One-shot and top of stack, so delete and pray.
WdfObjectDelete(Request);
}

VOID SetBlackWorkItem(
WDFWORKITEM workItem)
/*++

Routine Description:

Creates a WDF workitem to do the SetBlack() call after the driver
stack has initialized.

Arguments:

workItem - Handle to a pre-allocated WDF work item.
--*/
{
TRACE_FN_ENTRY

NTSTATUS status = STATUS_UNSUCCESSFUL;
WDFDEVICE device = static_cast<WDFDEVICE>(WdfWorkItemGetParentObject(workItem));

status = SetBlackAsync(device);
NukeWdfHandle(workItem);

//TRACE_FN_EXIT
}

NTSTATUS SetBlackAsync(WDFDEVICE device) {

TRACE_FN_ENTRY

NTSTATUS status = STATUS_FAILED_DRIVER_ENTRY;
WDFIOTARGET hidTarget = NULL;

DEVICE_CONTEXT* pDeviceContext = NULL;

pDeviceContext =
WdfObjectGet_DEVICE_CONTEXT(device);

if (pDeviceContext == NULL) {
return STATUS_DEVICE_NOT_READY;
}
{
// Ensure freed if fails.
status = WdfIoTargetCreate(
device,
WDF_NO_OBJECT_ATTRIBUTES,
&hidTarget);

if (!NT_SUCCESS(status)) {
KdPrintEx((DPFLTR_IHVDRIVER_ID,
DPFLTR_ERROR_LEVEL,
"TailLight: 0x%x while creating I/O target from worker thread\n",
status));
return status;
}

status = TryToOpenIoTarget(hidTarget, *pDeviceContext);
}

if (NT_SUCCESS(status)) {

WDFREQUEST request = NULL;

status = WdfRequestCreate(WDF_NO_OBJECT_ATTRIBUTES,
hidTarget,
&request);

if (!NT_SUCCESS(status)) {
KdPrint(("TailLight: WdfRequestCreate failed 0x%x\n", status));
goto ExitAndFree;
}

WdfRequestSetCompletionRoutine(
request,
SetBlackCompletionRoutine,
WDF_NO_CONTEXT);

TailLightReport report = {};
report.Blue = 0x0;
report.Green = 0x0;
report.Red = 0x0;

// Set up a WDF memory object for the IOCTL request
WDF_OBJECT_ATTRIBUTES mem_attrib = {};
WDF_OBJECT_ATTRIBUTES_INIT(&mem_attrib);
mem_attrib.ParentObject = request; // auto-delete with request*/

WDFMEMORY InBuffer = 0;
BYTE* pInBuffer = nullptr;

status = WdfMemoryCreate(&mem_attrib,
NonPagedPoolNx,
POOL_TAG,
sizeof(TailLightReport),
&InBuffer,
(void**)&pInBuffer);

if (!NT_SUCCESS(status)) {
KdPrint(("TailLight: WdfMemoryCreate failed: 0x%x\n", status));
goto ExitAndFree;
}

// TODO: Wondering if we just cant cast pInBuffr as a TailLightReport
RtlCopyMemory(pInBuffer, &report, sizeof(TailLightReport));

// Format the request as write operation
status = WdfIoTargetFormatRequestForIoctl(hidTarget,
request,
IOCTL_HID_SET_FEATURE,
InBuffer,
NULL,
0,
0);

if (!NT_SUCCESS(status)) {
KdPrint(("TailLight: WdfIoTargetFormatRequestForIoctl failed: 0x%x\n", status));
goto ExitAndFree;
}

pDeviceContext->previousThread = KeGetCurrentThread();

if (!WdfRequestSend(request, hidTarget, WDF_NO_SEND_OPTIONS)) {
WdfObjectDelete(request);
request = NULL;
}
}

ExitAndFree:
if (hidTarget != NULL) {
WdfObjectDelete(hidTarget);
hidTarget = NULL;
}

TRACE_FN_EXIT

return status;
}
2 changes: 1 addition & 1 deletion TailLight/TailLight.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct TailLightReport {
}

if ((Unknown1 != 0xB2) || (Unknown2 != 0x03)) {
KdPrint(("TailLight: TailLightReport: Unknown control Code 0x%x 0x%x\n", Unknown1, Unknown2));
//KdPrint(("TailLight: TailLightReport: Unknown control Code 0x%x 0x%x\n", Unknown1, Unknown2));
return false;
}

Expand Down
6 changes: 5 additions & 1 deletion TailLight/TailLight.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,15 @@ copy ..\TailLight.ps1 $(OutDir)</Command>
<PostBuildEvent>
<Command>copy *.bat $(PackageDir)
copy "C:\Program Files (x86)\Windows Kits\10\tools\$(WDKBuildFolder)\x64\dev*.exe" $(PackageDir)
copy ..\TailLight.ps1 $(OutDir)</Command>
copy ..\IntelliMouse.ps1 $(OutDir)
copy $(OutDir)$(TargetName).cer $(PackageDir)</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="device.cpp" />
<ClCompile Include="driver.cpp" />
<ClCompile Include="eventlog.cpp" />
<ClCompile Include="SetTaillightBlack.cpp" />
<ClCompile Include="vfeature.cpp" />
<ClCompile Include="wmi.cpp" />
<ResourceCompile Include="module.rc" />
Expand All @@ -117,9 +119,11 @@ copy ..\TailLight.ps1 $(OutDir)</Command>
</ItemGroup>
<ItemGroup>
<ClInclude Include="CppAllocator.hpp" />
<ClInclude Include="debug.h" />
<ClInclude Include="device.h" />
<ClInclude Include="driver.h" />
<ClInclude Include="eventlog.h" />
<ClInclude Include="SetBlack.h" />
<ClInclude Include="TailLight.h" />
<ClInclude Include="vfeature.h" />
<ClInclude Include="wmi.h" />
Expand Down
10 changes: 10 additions & 0 deletions TailLight/debug.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#pragma once

#define TRACE_FN_ENTRY KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "TailLight: Entry %s\n", __func__));
#define TRACE_FN_EXIT KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "TailLight: Exit: %s\n", __func__));
#define TRACE_REQUEST_BOOL(ret) KdPrint(("TailLight: WdfRequestSend returned bool: 0x%x\n", ret));
#define TRACE_REQUEST_FAILURE(status) KdPrint(("TailLight: WdfRequestSend failed. Status=: 0x%x\n", ret));

NTSTATUS DumpTarget(WDFIOTARGET target, WDFMEMORY& memory);
Loading