From 5564aacbbc06c61f59f253fd2e4387c78d2729f5 Mon Sep 17 00:00:00 2001 From: ManOnTheMountainTech Date: Wed, 24 Apr 2024 16:19:05 -0700 Subject: [PATCH 1/3] End of timer proc starts next timer. Went to com_ptr's for hidutil support. Updated TailLight.ps1 to invoke the BIST functionality. --- HidUtil/HidUtil.vcxproj | 15 ++ HidUtil/HidUtil.vcxproj.filters | 6 + HidUtil/Main.cpp | 42 ++++- HidUtil/Wbem.h | 34 ++++ HidUtil/WbemCore.cpp | 322 ++++++++++++++++++++++++++++++++ HidUtil/WbemExecute.cpp | 185 ++++++++++++++++++ HidUtil/packages.config | 4 + TailLight.ps1 | 8 + TailLight/TailLight.mof | 19 ++ TailLight/TailLight.vcxproj | 1 + TailLight/device.cpp | 26 +++ TailLight/device.h | 6 +- TailLight/vfeature.cpp | 2 +- TailLight/wmi.cpp | 126 +++++++++++-- TailLight/wmi.h | 20 ++ 15 files changed, 794 insertions(+), 22 deletions(-) create mode 100644 HidUtil/Wbem.h create mode 100644 HidUtil/WbemCore.cpp create mode 100644 HidUtil/WbemExecute.cpp create mode 100644 HidUtil/packages.config diff --git a/HidUtil/HidUtil.vcxproj b/HidUtil/HidUtil.vcxproj index a7c56586..802848ad 100644 --- a/HidUtil/HidUtil.vcxproj +++ b/HidUtil/HidUtil.vcxproj @@ -1,5 +1,6 @@ + Debug @@ -120,12 +121,26 @@ + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/HidUtil/HidUtil.vcxproj.filters b/HidUtil/HidUtil.vcxproj.filters index b75e5b0d..aa873169 100644 --- a/HidUtil/HidUtil.vcxproj.filters +++ b/HidUtil/HidUtil.vcxproj.filters @@ -2,9 +2,15 @@ + + + + + + \ No newline at end of file diff --git a/HidUtil/Main.cpp b/HidUtil/Main.cpp index 9bbb8890..24b59662 100644 --- a/HidUtil/Main.cpp +++ b/HidUtil/Main.cpp @@ -1,18 +1,46 @@ #include "HID.hpp" #include "TailLight.hpp" +#include "Wbem.h" +#define SWITCH_BIST "/bist" +#define CB_SWITCH_BIST_ONLY (sizeof(SWITCH_BIST) - 1) + +void PrintUsage() { + wprintf(L"IntelliMouse tail-light shifter .\n"); + wprintf(L"Usage:\n\"HidUtil.exe [/bist] [ \"" + " (example: \"HidUtil.exe 0 0 255\" or\n \"HidUtil.exe /bist\"]).\n"); +} int main(int argc, char* argv[]) { - if (argc < 4) { - wprintf(L"IntelliMouse tail-light shifter.\n"); - wprintf(L"Usage: \"HidUtil.exe \" (example: \"HidUtil.exe 0 0 255\").\n"); + + BYTE red = 0; + BYTE green = 0; + BYTE blue = 0; + + if (argc == 2 && lstrlenA(argv[1]) == CB_SWITCH_BIST_ONLY) { + if (memcmp(argv[1], SWITCH_BIST, CB_SWITCH_BIST_ONLY) == 0) { + if (SUCCEEDED(ConnectToWbem())) { + return 0; + } + else { + return -4; + } + } + else { + PrintUsage(); + return -1; + } + } + else if (argc == 4) { + red = (BYTE)atoi(argv[1]); + green = (BYTE)atoi(argv[2]); + blue = (BYTE)atoi(argv[3]); + } + else { + PrintUsage(); return -1; } - auto red = (BYTE)atoi(argv[1]); - auto green = (BYTE)atoi(argv[2]); - auto blue = (BYTE)atoi(argv[3]); - HID::Query query; query.VendorID = 0x045E; // Microsoft query.ProductID = 0x082A; // Pro IntelliMouse diff --git a/HidUtil/Wbem.h b/HidUtil/Wbem.h new file mode 100644 index 00000000..90dcdc9f --- /dev/null +++ b/HidUtil/Wbem.h @@ -0,0 +1,34 @@ +#pragma once +#include +#include +#include +#include +#include + +HRESULT +ConnectToWbem(); + +HRESULT +SetInterfaceSecurity( + _In_ IUnknown* InterfaceObj, + _In_opt_ PWSTR UserId, + _In_opt_ PWSTR Password, + _In_opt_ PWSTR DomainName +); + +HRESULT +ExecuteMethod_NoArgs_ReturnsValue( + _In_ winrt::com_ptr* pWbemServices, + _In_ winrt::com_ptr* pClassObj, + _In_ const BSTR InstancePath, + _In_ const OLECHAR* psz, + _Out_ HRESULT& wmiMethodRet +); + +HRESULT +ExecuteBISTOnAllDevices( + _In_ winrt::com_ptr* pWbemServices, + _In_opt_ PWSTR UserId, + _In_opt_ PWSTR Password, + _In_opt_ PWSTR DomainName +); \ No newline at end of file diff --git a/HidUtil/WbemCore.cpp b/HidUtil/WbemCore.cpp new file mode 100644 index 00000000..cabbb7f1 --- /dev/null +++ b/HidUtil/WbemCore.cpp @@ -0,0 +1,322 @@ +#include "Wbem.h" +#include "roapi.h" +#include + +#pragma comment(lib, "comsupp") +#pragma comment(lib, "wbemuuid") + +// Blatantly stolen from the Toaster sample + +HRESULT ConnectToWbem() { + HRESULT status = S_OK; + BOOLEAN initialized = FALSE; + + BSTR temp = NULL; + BSTR wmiRoot = NULL; + BSTR userIdString = NULL; + BSTR passwordString = NULL; + + PWSTR ComputerName = NULL; + PWSTR userId = NULL; + PWSTR password = NULL; + PWSTR domain = NULL; + + winrt::com_ptr wbemLocator; + winrt::com_ptr wbemServices; + + // + // Initialize COM environment for multi-threaded concurrency. + // + status = Windows::Foundation::Initialize(RO_INIT_MULTITHREADED); + if (FAILED(status)) { + return status; + } + + initialized = TRUE; + + // + // Initialize the security layer and set the specified values as the + // security default for the process. + // + status = CoInitializeSecurity(NULL, + -1, + NULL, + NULL, + RPC_C_AUTHN_LEVEL_PKT, + RPC_C_IMP_LEVEL_IMPERSONATE, + NULL, + EOAC_NONE, + 0); + + if (FAILED(status)) { + goto exit; + } + + // + // Create a single uninitialized object associated with the class id + // CLSID_WbemLocator. + // + status = CoCreateInstance(CLSID_WbemLocator, + NULL, + CLSCTX_INPROC_SERVER, + IID_IWbemLocator, + wbemLocator.put_void()); + + if (FAILED(status)) { + goto exit; + } + + // + // Construct the object path for the WMI namespace. For local access to the + // WMI namespace, use a simple object path: "\\.\root\WMI". For access to + // the WMI namespace on a remote computer, include the computer name in the + // object path: "\\myserver\root\WMI". + // + if (ComputerName != NULL) { + + status = VarBstrCat(_bstr_t(L"\\\\"), _bstr_t(ComputerName), &temp); + if (FAILED(status)) { + goto exit; + } + + } + else { + + status = VarBstrCat(_bstr_t(L"\\\\"), _bstr_t(L"."), &temp); + if (FAILED(status)) { + goto exit; + } + } + + status = VarBstrCat(temp, _bstr_t(L"\\root\\WMI"), &wmiRoot); + if (FAILED(status)) { + goto exit; + } + + SysFreeString(temp); + temp = NULL; + + // + // Construct the user id and password strings. + // + if (userId != NULL) { + + if (domain != NULL) { + + status = VarBstrCat(_bstr_t(domain), _bstr_t(L"\\"), &temp); + if (FAILED(status)) { + goto exit; + } + + status = VarBstrCat(temp, _bstr_t(userId), &userIdString); + if (FAILED(status)) { + goto exit; + } + + SysFreeString(temp); + temp = NULL; + + } + else { + + userIdString = SysAllocString(userId); + if (userIdString == NULL) { + status = E_OUTOFMEMORY; + goto exit; + } + } + + passwordString = SysAllocString(password); + if (passwordString == NULL) { + status = E_OUTOFMEMORY; + goto exit; + } + } + + // + // Connect to the WMI server on this computer and, possibly, through it to another system. + // + status = wbemLocator->ConnectServer(wmiRoot, + userIdString, + passwordString, + NULL, + 0, + NULL, + NULL, + wbemServices.put()); + if (FAILED(status)) { + if (status != WBEM_E_LOCAL_CREDENTIALS) { + goto exit; + } + + // + // Use the identity inherited from the current process. + // + status = wbemLocator->ConnectServer(wmiRoot, + NULL, + NULL, + NULL, + 0, + NULL, + NULL, + wbemServices.put()); + if (FAILED(status)) { + goto exit; + } + } + + // + // Set authentication information for the interface. + // + status = SetInterfaceSecurity(wbemServices.get(), userId, password, domain); + if (FAILED(status)) { + goto exit; + } + + // + // Execute the methods in each instance of the desired class. + // + printf("\n1. Execute Methods in class ...\n"); + status = ExecuteBISTOnAllDevices(&wbemServices, + userId, + password, + domain); + if (FAILED(status)) { + goto exit; + } + +exit: + + if (temp != NULL) { + SysFreeString(temp); + } + + if (userIdString != NULL) { + SysFreeString(userIdString); + } + + if (passwordString != NULL) { + SysFreeString(passwordString); + } + + if (wmiRoot != NULL) { + SysFreeString(wmiRoot); + } + + if (initialized == TRUE) { + CoUninitialize(); + } + + if (FAILED(status)) { + printf("FAILED with Status = 0x%08x\n", status); + } + return status; +} + +HRESULT +SetInterfaceSecurity( + _In_ IUnknown* InterfaceObj, + _In_opt_ PWSTR UserId, + _In_opt_ PWSTR Password, + _In_opt_ PWSTR DomainName +) + +/*++ + +Routine Description: + + Set the interface security to allow the server to impersonate the specified + user. + +Arguments: + + InterfaceObj - Pointer to interface for which the security settings need + to be applied. + + UserId - Pointer to the user id information or NULL. + + Password - Pointer to password or NULL. If the user id is not specified, + this parameter is ignored. + + DomainName - Pointer to domain name or NULL. If the user id is not specified, + this parameter is ignored. + +Return Value: + + HRESULT Status code. + +--*/ + +{ + HRESULT hr; + + COAUTHIDENTITY AuthIdentity; + DWORD AuthnSvc; + DWORD AuthzSvc; + DWORD AuthnLevel; + DWORD ImpLevel; + DWORD Capabilities; + PWSTR pServerPrinName = NULL; + RPC_AUTH_IDENTITY_HANDLE pAuthHndl = NULL; + + // + // Get current authentication information for interface. + // + hr = CoQueryProxyBlanket(InterfaceObj, + &AuthnSvc, + &AuthzSvc, + &pServerPrinName, + &AuthnLevel, + &ImpLevel, + &pAuthHndl, + &Capabilities); + + if (FAILED(hr)) { + goto exit; + } + + if (UserId == NULL) { + + AuthIdentity.User = NULL; + AuthIdentity.UserLength = 0; + AuthIdentity.Password = NULL; + AuthIdentity.PasswordLength = 0; + AuthIdentity.Domain = NULL; + AuthIdentity.DomainLength = 0; + + } + else { + + AuthIdentity.User = (USHORT*)UserId; +#pragma prefast(suppress:6387, "0 length UserId is valid") + AuthIdentity.UserLength = (ULONG)wcslen(UserId); + AuthIdentity.Password = (USHORT*)Password; +#pragma prefast(suppress:6387, "0 length Password is valid") + AuthIdentity.PasswordLength = (ULONG)wcslen(Password); + AuthIdentity.Domain = (USHORT*)DomainName; + AuthIdentity.DomainLength = (DomainName == NULL) ? 0 : (ULONG)wcslen(DomainName); + + } + + AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; + + // + // Change authentication information for interface, providing the identity + // information and "echoing back" everything else. + // + hr = CoSetProxyBlanket(InterfaceObj, + AuthnSvc, + AuthzSvc, + pServerPrinName, + AuthnLevel, + ImpLevel, + &AuthIdentity, + Capabilities); + + if (FAILED(hr)) { + goto exit; + } + +exit: + return hr; +} \ No newline at end of file diff --git a/HidUtil/WbemExecute.cpp b/HidUtil/WbemExecute.cpp new file mode 100644 index 00000000..3da148d4 --- /dev/null +++ b/HidUtil/WbemExecute.cpp @@ -0,0 +1,185 @@ +#include "wbem.h" +#include + +#define TAILLIGHT_WMI_BIST_CLASS L"TailLightBIST" +#define TAILLIGHT_WMI_BIST_METHOD L"BIST" + +// Blatantly stolen from the Toaster samples. +// Just like most other driver code. +// From WmiExecute.cpp +// Updated to use WinRT and RAII + +using namespace winrt; + +HRESULT +ExecuteMethod_NoArgs_ReturnsValue( + _In_ com_ptr* pWbemServices, + _In_ com_ptr* pClassObj, + _In_ const BSTR InstancePath, + _In_ const OLECHAR* psz, + _Out_ HRESULT& wmiMethodRet) +{ + HRESULT status; + + com_ptr inputParamsObj; + com_ptr resultControlObj; + + const BSTR methodName = SysAllocString(psz); + VARIANT retVal; + + // + // Get the input parameters class objects for the method. + // + status = (*pClassObj)->GetMethod(methodName, 0, inputParamsObj.put(), NULL); + if (FAILED(status)) { + goto exit; + } + + // + // Set the output variables values (i.e., return value for BIST). + // + retVal.vt = VT_I4; + retVal.ulVal = wmiMethodRet; + + // + // Call the method. + // + printf("\n"); + printf(" Start waiting for method : %ws to finish.\n", (wchar_t*)methodName); + status = (*pWbemServices)->ExecMethod(InstancePath, + methodName, + 0, + NULL, + NULL, + NULL, + resultControlObj.put()); + + if (FAILED(status) || NULL == resultControlObj) { + goto exit; + } + + // + // Get the result of the method call. + // + status = resultControlObj->GetCallStatus(4 * 1000, &wmiMethodRet); + printf(" Return value...: 0x%x\n", wmiMethodRet); +exit: + + if (methodName != NULL) { + SysFreeString(methodName); + } + + return status; +} + + +HRESULT +ExecuteBISTOnAllDevices( + _In_ com_ptr* pWbemServices, + _In_opt_ PWSTR UserId, + _In_opt_ PWSTR Password, + _In_opt_ PWSTR DomainName +) +{ + HRESULT status = S_OK; + + com_ptr enumerator; + com_ptr classObj; + com_ptr instanceObj; + + const BSTR className = SysAllocString(TAILLIGHT_WMI_BIST_CLASS); + + VARIANT pathVariable; + _bstr_t instancePath; + ULONG nbrObjsSought = 1; + ULONG nbrObjsReturned; + + VariantInit(&pathVariable); + + // + // Create an Enumeration object to enumerate the instances of the given class. + // + status = (*pWbemServices)->CreateInstanceEnum(className, + WBEM_FLAG_SHALLOW | WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, + NULL, + enumerator.put()); + if (FAILED(status)) { + goto exit; + } + + // + // Set authentication information for the interface. + // + status = SetInterfaceSecurity(enumerator.get(), UserId, Password, DomainName); + if (FAILED(status)) { + goto exit; + } + + // + // Get the class object for the method definition. + // + status = (*pWbemServices)->GetObject(className, 0, NULL, classObj.put(), NULL); + if (FAILED(status) || NULL == classObj) { + goto exit; + } + + do { + + // + // Get the instance object for each instance of the class. + // + status = enumerator->Next(WBEM_INFINITE, + nbrObjsSought, + instanceObj.put(), + &nbrObjsReturned); + + if (status == WBEM_S_FALSE) { + status = S_OK; + break; + } + + if (FAILED(status)) { + if (status == WBEM_E_INVALID_CLASS) { + printf("ERROR: TailLight driver may not be active on the system.\n"); + } + goto exit; + } + + // + // To obtain the object path of the object for which the method has to be + // executed, query the "__PATH" property of the WMI instance object. + // + + + status = instanceObj->Get(_bstr_t(L"__PATH"), 0, &pathVariable, NULL, NULL); + if (FAILED(status)) { + goto exit; + } + + instancePath = pathVariable.bstrVal; + printf("Instance Path .: %ws\n", (wchar_t*)instancePath); + + HRESULT hr = E_FAIL; + + // + // Execute the methods in this instance of the class. + // + status = ExecuteMethod_NoArgs_ReturnsValue(pWbemServices, + &classObj, + instancePath, + TAILLIGHT_WMI_BIST_METHOD, + hr); + if (FAILED(status)) { + goto exit; + } + + } while (!FAILED(status)); + +exit: + + if (className != NULL) { + SysFreeString(className); + } + + return status; +} \ No newline at end of file diff --git a/HidUtil/packages.config b/HidUtil/packages.config new file mode 100644 index 00000000..7a9561b2 --- /dev/null +++ b/HidUtil/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/TailLight.ps1 b/TailLight.ps1 index 5563571b..14c852de 100644 --- a/TailLight.ps1 +++ b/TailLight.ps1 @@ -15,3 +15,11 @@ Write-Host(" Changing color to {0:x}" -f $mouse.TailLight) # display as hex str Write-Host("Storing changes.") Set-CimInstance -CimInstance $mouse + +$mouse = Get-CimInstance -Namespace root/WMI -Class TailLightBIST + +Write-Host("IntelliMouse BIST:") +Write-Host(" InstanceName: {0}" -f $mouse.InstanceName) +Write-Host(" Active: {0}" -f $mouse.Active) + +Invoke-CimMethod -InputObject $mouse -MethodName BIST \ No newline at end of file diff --git a/TailLight/TailLight.mof b/TailLight/TailLight.mof index dd806411..730aa280 100644 --- a/TailLight/TailLight.mof +++ b/TailLight/TailLight.mof @@ -19,3 +19,22 @@ class TailLightDeviceInformation { [WmiDataId(1), read, write, Description("Tail-light in RGB COLORREF format.")] uint32 TailLight; }; + +[Dynamic, + Provider("WMIProv"), + WMI, + Locale("MS\\0x409"), + Description("TailLight BIST"), + guid("{ED9DA801-EEEA-44C7-8B1C-5E4C1039F95C}")] +class TailLightBIST { + [key, read] + string InstanceName; + + [read] + boolean Active; + + [WmiMethodId(1), + Implemented, + Description("BIST Command.")] + void BIST(); +}; \ No newline at end of file diff --git a/TailLight/TailLight.vcxproj b/TailLight/TailLight.vcxproj index 4ed53746..80fb69d0 100644 --- a/TailLight/TailLight.vcxproj +++ b/TailLight/TailLight.vcxproj @@ -120,6 +120,7 @@ copy $(OutDir)\TailLight.cer $(PackageDir) %(AdditionalDependencies);$(DDK_LIB_PATH)\hidparse.lib + sha256 diff --git a/TailLight/device.cpp b/TailLight/device.cpp index 0f583ec2..15af28ed 100644 --- a/TailLight/device.cpp +++ b/TailLight/device.cpp @@ -148,6 +148,32 @@ Routine Description: return status; } + // Initialize WMI FakeBIST + WDF_TIMER_CONFIG timerCfg = {}; + WDF_TIMER_CONFIG_INIT(&timerCfg, FakeBISTTimerProc); + + WDF_OBJECT_ATTRIBUTES attribs = {}; + WDF_OBJECT_ATTRIBUTES_INIT(&attribs); + WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attribs, COLOR_CONTROL); + + // The timer object needs to stick around until all of the timer callbacks + // have run. If we delete the timer handle in the timer callback then WDF + // will remind us of this being a deadlock scenario. The simplest solution + // is to parent it to the device and live with the "garbage". + attribs.ExecutionLevel = WdfExecutionLevelPassive; // required to access HID functions + attribs.ParentObject = device; + + WDFTIMER* pTimer = &WdfObjectGet_DEVICE_CONTEXT(device)->FakeBISTTimer; + status = WdfTimerCreate(&timerCfg, + &attribs, + pTimer); + IF_FAILED_RETURN_STATUS(1, "WdfTimerCreate") + + auto pColorController = WdfObjectGet_COLOR_CONTROL(*pTimer); + pColorController->Colors[0] = 0xFF00; + pColorController->Colors[1] = 0x0; + pColorController->RemainingColors = REMAINING_COLORS_COUNT; + return status; } diff --git a/TailLight/device.h b/TailLight/device.h index aad00741..d2979a1b 100644 --- a/TailLight/device.h +++ b/TailLight/device.h @@ -3,10 +3,12 @@ /** Driver-specific struct for storing instance-specific data. */ struct DEVICE_CONTEXT { UNICODE_STRING PdoName; - WDFWMIINSTANCE WmiInstance; + WDFWMIINSTANCE WmiReportInstance; + WDFWMIINSTANCE WmiBISTInstance; + WDFTIMER FakeBISTTimer; }; WDF_DECLARE_CONTEXT_TYPE(DEVICE_CONTEXT) WDF_DECLARE_CONTEXT_TYPE(TailLightDeviceInformation) -EVT_WDF_DEVICE_CONTEXT_CLEANUP EvtDeviceContextCleanup; +EVT_WDF_DEVICE_CONTEXT_CLEANUP EvtDeviceContextCleanup; \ No newline at end of file diff --git a/TailLight/vfeature.cpp b/TailLight/vfeature.cpp index 17cf4410..d4fcbf36 100644 --- a/TailLight/vfeature.cpp +++ b/TailLight/vfeature.cpp @@ -206,7 +206,7 @@ Routine Description: } // update last written color - TailLightDeviceInformation* pInfo = WdfObjectGet_TailLightDeviceInformation(deviceContext->WmiInstance); + TailLightDeviceInformation* pInfo = WdfObjectGet_TailLightDeviceInformation(deviceContext->WmiReportInstance); pInfo->TailLight = packet->GetColor(); return status; diff --git a/TailLight/wmi.cpp b/TailLight/wmi.cpp index 69a2bc2b..dc4f7a8b 100644 --- a/TailLight/wmi.cpp +++ b/TailLight/wmi.cpp @@ -1,6 +1,93 @@ #include "driver.h" + +VOID FakeBISTTimerProc(_In_ WDFTIMER timer) { + WDFDEVICE Device = static_cast(WdfTimerGetParentObject(timer)); + COLOR_CONTROL* pColorController = WdfObjectGet_COLOR_CONTROL(timer); + NTSTATUS status = SetFeatureColor(Device, pColorController->Colors[pColorController->RemainingColors]); + if (!NT_SUCCESS(status)) { + DPF_SOMETHING_FAILED(instance, something); } + + if (pColorController->RemainingColors) { + pColorController->RemainingColors = pColorController->RemainingColors - 1; + + BOOLEAN timerInQueue = WdfTimerStart(timer, WDF_REL_TIMEOUT_IN_SEC(1)); + NT_ASSERTMSG("Previous active timer overwritten", !timerInQueue); + } + else { + pColorController->RemainingColors = REMAINING_COLORS_COUNT; + } +} + +NTSTATUS FakeBIST(_In_ WDFDEVICE Device) { +/*++ + + Routine Description: Performs a fake Built-In Self Test (BIST) + +--*/ + NTSTATUS status = STATUS_UNSUCCESSFUL; + + WDFTIMER* pTimer = &WdfObjectGet_DEVICE_CONTEXT(Device)->FakeBISTTimer; + auto pColorController = WdfObjectGet_COLOR_CONTROL(*pTimer); + + // FakeBIST is called in an arbitrary thread. If more than one thread is in + // FakeBIST at the same time, then the call to SetFeatureColor will result + // in an invalid taillight color sequence. Simply return that the device is + // busy using an invalid COLOR_CONTROL::RemainingColors value to signify + // that the hardware is free. Otherwise we can queue up the request or + // block. Both of those mechanisms would require notifying that the + // hardware is busy and cancelation. + // + // TODO: Maybe a function to get the last BIST test result and time. + if (pColorController->RemainingColors != REMAINING_COLORS_COUNT) { + return STATUS_DEVICE_BUSY; + } + + InterlockedDecrement((LONG*) & pColorController->RemainingColors); + + // Indicate that we are "starting" the test. + status = SetFeatureColor(Device, 0xFF); + + pTimer = &WdfObjectGet_DEVICE_CONTEXT(Device)->FakeBISTTimer; + IF_FAILED_RETURN_STATUS(2, "SetFeatureColor") + + #pragma warning(suppress : 6387) // *pTimer initialized in AddDevice + BOOLEAN timerInQueue = WdfTimerStart(*pTimer, WDF_REL_TIMEOUT_IN_SEC(1)); + NT_ASSERTMSG("Previous active timer overwritten", !timerInQueue); + + return status; +} + +static NTSTATUS EvtWmiBISTInstanceExecuteMethod( + _In_ WDFWMIINSTANCE WmiReportInstance, + _In_ ULONG MethodId, + _In_ ULONG InBufferSize, + _In_ ULONG OutBufferSize, + _Inout_ PVOID Buffer, + _Out_ PULONG BufferUsed +) { + UNREFERENCED_PARAMETER(InBufferSize); + UNREFERENCED_PARAMETER(OutBufferSize); + UNREFERENCED_PARAMETER(Buffer); + + NTSTATUS status = STATUS_NOT_IMPLEMENTED; + + switch (MethodId) { + case BIST: + status = FakeBIST(WdfWmiInstanceGetDevice(WmiReportInstance)); + *BufferUsed = 0; + break; + + default: + break; + } + + KdPrint(("TailLight: Returning 0x%x from BIST launch.\n", status)); + return status; +} + + // Register our GUID and Datablock generated from the TailLight.mof file. NTSTATUS WmiInitialize(_In_ WDFDEVICE Device) { @@ -26,21 +113,36 @@ NTSTATUS WmiInitialize(_In_ WDFDEVICE Device) WDF_OBJECT_ATTRIBUTES woa = {}; WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&woa, TailLightDeviceInformation); - WDFWMIINSTANCE WmiInstance = 0; - status = WdfWmiInstanceCreate(Device, &instanceConfig, &woa, &WmiInstance); + WDFWMIINSTANCE WmiLastCreatedInstance = 0; + status = WdfWmiInstanceCreate(Device, &instanceConfig, &woa, &WmiLastCreatedInstance); if (!NT_SUCCESS(status)) { - KdPrint(("TailLight: WdfWmiInstanceCreate error %x\n", status)); + KdPrint(("TailLight: WdfWmiInstanceCreate of TailLightDeviceInformation error %x\n", status)); return status; } DEVICE_CONTEXT* deviceContext = WdfObjectGet_DEVICE_CONTEXT(Device); - deviceContext->WmiInstance = WmiInstance; + deviceContext->WmiReportInstance = WmiLastCreatedInstance; + + WDF_WMI_PROVIDER_CONFIG_INIT(&providerConfig, &TailLightBIST_GUID); + WDF_WMI_INSTANCE_CONFIG_INIT_PROVIDER_CONFIG(&instanceConfig, &providerConfig); + instanceConfig.Register = TRUE; + instanceConfig.EvtWmiInstanceExecuteMethod = EvtWmiBISTInstanceExecuteMethod; + status = WdfWmiInstanceCreate(Device, + &instanceConfig, + WDF_NO_OBJECT_ATTRIBUTES, + &WmiLastCreatedInstance); + if (!NT_SUCCESS(status)) { + KdPrint(("TailLight: WdfWmiInstanceCreate of TailLightBIST error is %x\n", status)); + return status; + } + + deviceContext->WmiBISTInstance = WmiLastCreatedInstance; return status; } NTSTATUS EvtWmiInstanceQueryInstance( - _In_ WDFWMIINSTANCE WmiInstance, + _In_ WDFWMIINSTANCE WmiReportInstance, _In_ ULONG OutBufferSize, _Out_writes_bytes_to_(OutBufferSize, *BufferUsed) PVOID OutBuffer, _Out_ PULONG BufferUsed @@ -50,7 +152,7 @@ NTSTATUS EvtWmiInstanceQueryInstance( KdPrint(("TailLight: WMI QueryInstance\n")); - TailLightDeviceInformation* pInfo = WdfObjectGet_TailLightDeviceInformation(WmiInstance); + TailLightDeviceInformation* pInfo = WdfObjectGet_TailLightDeviceInformation(WmiReportInstance); RtlCopyMemory(/*dst*/OutBuffer, /*src*/pInfo, sizeof(*pInfo)); *BufferUsed = sizeof(*pInfo); @@ -59,7 +161,7 @@ NTSTATUS EvtWmiInstanceQueryInstance( } NTSTATUS EvtWmiInstanceSetInstance( - _In_ WDFWMIINSTANCE WmiInstance, + _In_ WDFWMIINSTANCE WmiReportInstance, _In_ ULONG InBufferSize, _In_reads_bytes_(InBufferSize) PVOID InBuffer ) @@ -68,18 +170,18 @@ NTSTATUS EvtWmiInstanceSetInstance( KdPrint(("TailLight: WMI SetInstance\n")); - TailLightDeviceInformation* pInfo = WdfObjectGet_TailLightDeviceInformation(WmiInstance); + TailLightDeviceInformation* pInfo = WdfObjectGet_TailLightDeviceInformation(WmiReportInstance); RtlCopyMemory(/*dst*/pInfo, /*src*/InBuffer, sizeof(*pInfo)); // call SetFeatureColor to trigger tail-light update - NTSTATUS status = SetFeatureColor(WdfWmiInstanceGetDevice(WmiInstance), pInfo->TailLight); + NTSTATUS status = SetFeatureColor(WdfWmiInstanceGetDevice(WmiReportInstance), pInfo->TailLight); KdPrint(("TailLight: WMI SetInstance completed\n")); return status; } NTSTATUS EvtWmiInstanceSetItem( - _In_ WDFWMIINSTANCE WmiInstance, + _In_ WDFWMIINSTANCE WmiReportInstance, _In_ ULONG DataItemId, _In_ ULONG InBufferSize, _In_reads_bytes_(InBufferSize) PVOID InBuffer @@ -87,7 +189,7 @@ NTSTATUS EvtWmiInstanceSetItem( { KdPrint(("TailLight: WMI SetItem\n")); - TailLightDeviceInformation* pInfo = WdfObjectGet_TailLightDeviceInformation(WmiInstance); + TailLightDeviceInformation* pInfo = WdfObjectGet_TailLightDeviceInformation(WmiReportInstance); NTSTATUS status = STATUS_SUCCESS; if (DataItemId == TailLightDeviceInformation_TailLight_ID) { @@ -97,7 +199,7 @@ NTSTATUS EvtWmiInstanceSetItem( pInfo->TailLight = *(ULONG*)InBuffer; // call SetFeatureColor to trigger tail-light update - status = SetFeatureColor(WdfWmiInstanceGetDevice(WmiInstance), pInfo->TailLight); + status = SetFeatureColor(WdfWmiInstanceGetDevice(WmiReportInstance), pInfo->TailLight); } else { return STATUS_INVALID_DEVICE_REQUEST; } diff --git a/TailLight/wmi.h b/TailLight/wmi.h index b41caf56..43837a22 100644 --- a/TailLight/wmi.h +++ b/TailLight/wmi.h @@ -1,6 +1,25 @@ // Where they are described. #define MOFRESOURCENAME L"TailLightWMI" +#define DPF_SOMETHING_FAILED( instance, something ) KdPrint(("TailLight: %s: " #something " failed 0x%x(" ## #instance ## ")\n", __func__, status)); + +#define IF_FAILED_RETURN_STATUS( instance, something ) \ + if (!NT_SUCCESS(status)) { \ + DPF_SOMETHING_FAILED( instance, something ) \ + return status; \ + } + + +struct COLOR_CONTROL { + ULONG Colors[2] = { 0xFF00, 0x0 }; + ULONG RemainingColors = 0; +}; + +#define REMAINING_COLORS_COUNT sizeof(COLOR_CONTROL::Colors) / \ + sizeof(*COLOR_CONTROL::Colors) + +WDF_DECLARE_CONTEXT_TYPE(COLOR_CONTROL); + // Initialize WMI provider NTSTATUS WmiInitialize(_In_ WDFDEVICE Device); @@ -9,3 +28,4 @@ EVT_WDF_WMI_INSTANCE_QUERY_INSTANCE EvtWmiInstanceQueryInstance; EVT_WDF_WMI_INSTANCE_SET_INSTANCE EvtWmiInstanceSetInstance; EVT_WDF_WMI_INSTANCE_SET_ITEM EvtWmiInstanceSetItem; +VOID FakeBISTTimerProc(_In_ WDFTIMER timer); \ No newline at end of file From ec7843f52418e79182ecf2c1360c50e31a815e71 Mon Sep 17 00:00:00 2001 From: ManOnTheMountainTech Date: Mon, 29 Apr 2024 10:42:48 -0700 Subject: [PATCH 2/3] Use device syncscope for the fake BIST timer. Remove duplicate pTimer assignment. --- TailLight/device.cpp | 1 + TailLight/wmi.cpp | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/TailLight/device.cpp b/TailLight/device.cpp index 15af28ed..aa07a3ee 100644 --- a/TailLight/device.cpp +++ b/TailLight/device.cpp @@ -155,6 +155,7 @@ Routine Description: WDF_OBJECT_ATTRIBUTES attribs = {}; WDF_OBJECT_ATTRIBUTES_INIT(&attribs); WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attribs, COLOR_CONTROL); + attribs.SynchronizationScope = WdfSynchronizationScopeDevice; // The timer object needs to stick around until all of the timer callbacks // have run. If we delete the timer handle in the timer callback then WDF diff --git a/TailLight/wmi.cpp b/TailLight/wmi.cpp index dc4f7a8b..a6a3ce31 100644 --- a/TailLight/wmi.cpp +++ b/TailLight/wmi.cpp @@ -44,12 +44,10 @@ NTSTATUS FakeBIST(_In_ WDFDEVICE Device) { return STATUS_DEVICE_BUSY; } - InterlockedDecrement((LONG*) & pColorController->RemainingColors); + --pColorController->RemainingColors; // Indicate that we are "starting" the test. status = SetFeatureColor(Device, 0xFF); - - pTimer = &WdfObjectGet_DEVICE_CONTEXT(Device)->FakeBISTTimer; IF_FAILED_RETURN_STATUS(2, "SetFeatureColor") #pragma warning(suppress : 6387) // *pTimer initialized in AddDevice From eefe6b50af2f6ab049293b84e11e28ad8047da25 Mon Sep 17 00:00:00 2001 From: ManOnTheMountainTech Date: Mon, 29 Apr 2024 15:14:12 -0700 Subject: [PATCH 3/3] Separated out taillight --- TailLight.ps1 | 8 --- TailLight/TailLight.mof | 19 ------ TailLight/TailLight.vcxproj | 1 - TailLight/device.cpp | 27 -------- TailLight/device.h | 6 +- TailLight/vfeature.cpp | 2 +- TailLight/wmi.cpp | 124 ++++-------------------------------- TailLight/wmi.h | 20 ------ 8 files changed, 15 insertions(+), 192 deletions(-) diff --git a/TailLight.ps1 b/TailLight.ps1 index 14c852de..5563571b 100644 --- a/TailLight.ps1 +++ b/TailLight.ps1 @@ -15,11 +15,3 @@ Write-Host(" Changing color to {0:x}" -f $mouse.TailLight) # display as hex str Write-Host("Storing changes.") Set-CimInstance -CimInstance $mouse - -$mouse = Get-CimInstance -Namespace root/WMI -Class TailLightBIST - -Write-Host("IntelliMouse BIST:") -Write-Host(" InstanceName: {0}" -f $mouse.InstanceName) -Write-Host(" Active: {0}" -f $mouse.Active) - -Invoke-CimMethod -InputObject $mouse -MethodName BIST \ No newline at end of file diff --git a/TailLight/TailLight.mof b/TailLight/TailLight.mof index 730aa280..dd806411 100644 --- a/TailLight/TailLight.mof +++ b/TailLight/TailLight.mof @@ -19,22 +19,3 @@ class TailLightDeviceInformation { [WmiDataId(1), read, write, Description("Tail-light in RGB COLORREF format.")] uint32 TailLight; }; - -[Dynamic, - Provider("WMIProv"), - WMI, - Locale("MS\\0x409"), - Description("TailLight BIST"), - guid("{ED9DA801-EEEA-44C7-8B1C-5E4C1039F95C}")] -class TailLightBIST { - [key, read] - string InstanceName; - - [read] - boolean Active; - - [WmiMethodId(1), - Implemented, - Description("BIST Command.")] - void BIST(); -}; \ No newline at end of file diff --git a/TailLight/TailLight.vcxproj b/TailLight/TailLight.vcxproj index 80fb69d0..4ed53746 100644 --- a/TailLight/TailLight.vcxproj +++ b/TailLight/TailLight.vcxproj @@ -120,7 +120,6 @@ copy $(OutDir)\TailLight.cer $(PackageDir) %(AdditionalDependencies);$(DDK_LIB_PATH)\hidparse.lib - sha256 diff --git a/TailLight/device.cpp b/TailLight/device.cpp index aa07a3ee..0f583ec2 100644 --- a/TailLight/device.cpp +++ b/TailLight/device.cpp @@ -148,33 +148,6 @@ Routine Description: return status; } - // Initialize WMI FakeBIST - WDF_TIMER_CONFIG timerCfg = {}; - WDF_TIMER_CONFIG_INIT(&timerCfg, FakeBISTTimerProc); - - WDF_OBJECT_ATTRIBUTES attribs = {}; - WDF_OBJECT_ATTRIBUTES_INIT(&attribs); - WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attribs, COLOR_CONTROL); - attribs.SynchronizationScope = WdfSynchronizationScopeDevice; - - // The timer object needs to stick around until all of the timer callbacks - // have run. If we delete the timer handle in the timer callback then WDF - // will remind us of this being a deadlock scenario. The simplest solution - // is to parent it to the device and live with the "garbage". - attribs.ExecutionLevel = WdfExecutionLevelPassive; // required to access HID functions - attribs.ParentObject = device; - - WDFTIMER* pTimer = &WdfObjectGet_DEVICE_CONTEXT(device)->FakeBISTTimer; - status = WdfTimerCreate(&timerCfg, - &attribs, - pTimer); - IF_FAILED_RETURN_STATUS(1, "WdfTimerCreate") - - auto pColorController = WdfObjectGet_COLOR_CONTROL(*pTimer); - pColorController->Colors[0] = 0xFF00; - pColorController->Colors[1] = 0x0; - pColorController->RemainingColors = REMAINING_COLORS_COUNT; - return status; } diff --git a/TailLight/device.h b/TailLight/device.h index d2979a1b..aad00741 100644 --- a/TailLight/device.h +++ b/TailLight/device.h @@ -3,12 +3,10 @@ /** Driver-specific struct for storing instance-specific data. */ struct DEVICE_CONTEXT { UNICODE_STRING PdoName; - WDFWMIINSTANCE WmiReportInstance; - WDFWMIINSTANCE WmiBISTInstance; - WDFTIMER FakeBISTTimer; + WDFWMIINSTANCE WmiInstance; }; WDF_DECLARE_CONTEXT_TYPE(DEVICE_CONTEXT) WDF_DECLARE_CONTEXT_TYPE(TailLightDeviceInformation) -EVT_WDF_DEVICE_CONTEXT_CLEANUP EvtDeviceContextCleanup; \ No newline at end of file +EVT_WDF_DEVICE_CONTEXT_CLEANUP EvtDeviceContextCleanup; diff --git a/TailLight/vfeature.cpp b/TailLight/vfeature.cpp index d4fcbf36..17cf4410 100644 --- a/TailLight/vfeature.cpp +++ b/TailLight/vfeature.cpp @@ -206,7 +206,7 @@ Routine Description: } // update last written color - TailLightDeviceInformation* pInfo = WdfObjectGet_TailLightDeviceInformation(deviceContext->WmiReportInstance); + TailLightDeviceInformation* pInfo = WdfObjectGet_TailLightDeviceInformation(deviceContext->WmiInstance); pInfo->TailLight = packet->GetColor(); return status; diff --git a/TailLight/wmi.cpp b/TailLight/wmi.cpp index a6a3ce31..69a2bc2b 100644 --- a/TailLight/wmi.cpp +++ b/TailLight/wmi.cpp @@ -1,91 +1,6 @@ #include "driver.h" - -VOID FakeBISTTimerProc(_In_ WDFTIMER timer) { - WDFDEVICE Device = static_cast(WdfTimerGetParentObject(timer)); - COLOR_CONTROL* pColorController = WdfObjectGet_COLOR_CONTROL(timer); - NTSTATUS status = SetFeatureColor(Device, pColorController->Colors[pColorController->RemainingColors]); - if (!NT_SUCCESS(status)) { - DPF_SOMETHING_FAILED(instance, something); } - - if (pColorController->RemainingColors) { - pColorController->RemainingColors = pColorController->RemainingColors - 1; - - BOOLEAN timerInQueue = WdfTimerStart(timer, WDF_REL_TIMEOUT_IN_SEC(1)); - NT_ASSERTMSG("Previous active timer overwritten", !timerInQueue); - } - else { - pColorController->RemainingColors = REMAINING_COLORS_COUNT; - } -} - -NTSTATUS FakeBIST(_In_ WDFDEVICE Device) { -/*++ - - Routine Description: Performs a fake Built-In Self Test (BIST) - ---*/ - NTSTATUS status = STATUS_UNSUCCESSFUL; - - WDFTIMER* pTimer = &WdfObjectGet_DEVICE_CONTEXT(Device)->FakeBISTTimer; - auto pColorController = WdfObjectGet_COLOR_CONTROL(*pTimer); - - // FakeBIST is called in an arbitrary thread. If more than one thread is in - // FakeBIST at the same time, then the call to SetFeatureColor will result - // in an invalid taillight color sequence. Simply return that the device is - // busy using an invalid COLOR_CONTROL::RemainingColors value to signify - // that the hardware is free. Otherwise we can queue up the request or - // block. Both of those mechanisms would require notifying that the - // hardware is busy and cancelation. - // - // TODO: Maybe a function to get the last BIST test result and time. - if (pColorController->RemainingColors != REMAINING_COLORS_COUNT) { - return STATUS_DEVICE_BUSY; - } - - --pColorController->RemainingColors; - - // Indicate that we are "starting" the test. - status = SetFeatureColor(Device, 0xFF); - IF_FAILED_RETURN_STATUS(2, "SetFeatureColor") - - #pragma warning(suppress : 6387) // *pTimer initialized in AddDevice - BOOLEAN timerInQueue = WdfTimerStart(*pTimer, WDF_REL_TIMEOUT_IN_SEC(1)); - NT_ASSERTMSG("Previous active timer overwritten", !timerInQueue); - - return status; -} - -static NTSTATUS EvtWmiBISTInstanceExecuteMethod( - _In_ WDFWMIINSTANCE WmiReportInstance, - _In_ ULONG MethodId, - _In_ ULONG InBufferSize, - _In_ ULONG OutBufferSize, - _Inout_ PVOID Buffer, - _Out_ PULONG BufferUsed -) { - UNREFERENCED_PARAMETER(InBufferSize); - UNREFERENCED_PARAMETER(OutBufferSize); - UNREFERENCED_PARAMETER(Buffer); - - NTSTATUS status = STATUS_NOT_IMPLEMENTED; - - switch (MethodId) { - case BIST: - status = FakeBIST(WdfWmiInstanceGetDevice(WmiReportInstance)); - *BufferUsed = 0; - break; - - default: - break; - } - - KdPrint(("TailLight: Returning 0x%x from BIST launch.\n", status)); - return status; -} - - // Register our GUID and Datablock generated from the TailLight.mof file. NTSTATUS WmiInitialize(_In_ WDFDEVICE Device) { @@ -111,36 +26,21 @@ NTSTATUS WmiInitialize(_In_ WDFDEVICE Device) WDF_OBJECT_ATTRIBUTES woa = {}; WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&woa, TailLightDeviceInformation); - WDFWMIINSTANCE WmiLastCreatedInstance = 0; - status = WdfWmiInstanceCreate(Device, &instanceConfig, &woa, &WmiLastCreatedInstance); + WDFWMIINSTANCE WmiInstance = 0; + status = WdfWmiInstanceCreate(Device, &instanceConfig, &woa, &WmiInstance); if (!NT_SUCCESS(status)) { - KdPrint(("TailLight: WdfWmiInstanceCreate of TailLightDeviceInformation error %x\n", status)); + KdPrint(("TailLight: WdfWmiInstanceCreate error %x\n", status)); return status; } DEVICE_CONTEXT* deviceContext = WdfObjectGet_DEVICE_CONTEXT(Device); - deviceContext->WmiReportInstance = WmiLastCreatedInstance; - - WDF_WMI_PROVIDER_CONFIG_INIT(&providerConfig, &TailLightBIST_GUID); - WDF_WMI_INSTANCE_CONFIG_INIT_PROVIDER_CONFIG(&instanceConfig, &providerConfig); - instanceConfig.Register = TRUE; - instanceConfig.EvtWmiInstanceExecuteMethod = EvtWmiBISTInstanceExecuteMethod; - status = WdfWmiInstanceCreate(Device, - &instanceConfig, - WDF_NO_OBJECT_ATTRIBUTES, - &WmiLastCreatedInstance); - if (!NT_SUCCESS(status)) { - KdPrint(("TailLight: WdfWmiInstanceCreate of TailLightBIST error is %x\n", status)); - return status; - } - - deviceContext->WmiBISTInstance = WmiLastCreatedInstance; + deviceContext->WmiInstance = WmiInstance; return status; } NTSTATUS EvtWmiInstanceQueryInstance( - _In_ WDFWMIINSTANCE WmiReportInstance, + _In_ WDFWMIINSTANCE WmiInstance, _In_ ULONG OutBufferSize, _Out_writes_bytes_to_(OutBufferSize, *BufferUsed) PVOID OutBuffer, _Out_ PULONG BufferUsed @@ -150,7 +50,7 @@ NTSTATUS EvtWmiInstanceQueryInstance( KdPrint(("TailLight: WMI QueryInstance\n")); - TailLightDeviceInformation* pInfo = WdfObjectGet_TailLightDeviceInformation(WmiReportInstance); + TailLightDeviceInformation* pInfo = WdfObjectGet_TailLightDeviceInformation(WmiInstance); RtlCopyMemory(/*dst*/OutBuffer, /*src*/pInfo, sizeof(*pInfo)); *BufferUsed = sizeof(*pInfo); @@ -159,7 +59,7 @@ NTSTATUS EvtWmiInstanceQueryInstance( } NTSTATUS EvtWmiInstanceSetInstance( - _In_ WDFWMIINSTANCE WmiReportInstance, + _In_ WDFWMIINSTANCE WmiInstance, _In_ ULONG InBufferSize, _In_reads_bytes_(InBufferSize) PVOID InBuffer ) @@ -168,18 +68,18 @@ NTSTATUS EvtWmiInstanceSetInstance( KdPrint(("TailLight: WMI SetInstance\n")); - TailLightDeviceInformation* pInfo = WdfObjectGet_TailLightDeviceInformation(WmiReportInstance); + TailLightDeviceInformation* pInfo = WdfObjectGet_TailLightDeviceInformation(WmiInstance); RtlCopyMemory(/*dst*/pInfo, /*src*/InBuffer, sizeof(*pInfo)); // call SetFeatureColor to trigger tail-light update - NTSTATUS status = SetFeatureColor(WdfWmiInstanceGetDevice(WmiReportInstance), pInfo->TailLight); + NTSTATUS status = SetFeatureColor(WdfWmiInstanceGetDevice(WmiInstance), pInfo->TailLight); KdPrint(("TailLight: WMI SetInstance completed\n")); return status; } NTSTATUS EvtWmiInstanceSetItem( - _In_ WDFWMIINSTANCE WmiReportInstance, + _In_ WDFWMIINSTANCE WmiInstance, _In_ ULONG DataItemId, _In_ ULONG InBufferSize, _In_reads_bytes_(InBufferSize) PVOID InBuffer @@ -187,7 +87,7 @@ NTSTATUS EvtWmiInstanceSetItem( { KdPrint(("TailLight: WMI SetItem\n")); - TailLightDeviceInformation* pInfo = WdfObjectGet_TailLightDeviceInformation(WmiReportInstance); + TailLightDeviceInformation* pInfo = WdfObjectGet_TailLightDeviceInformation(WmiInstance); NTSTATUS status = STATUS_SUCCESS; if (DataItemId == TailLightDeviceInformation_TailLight_ID) { @@ -197,7 +97,7 @@ NTSTATUS EvtWmiInstanceSetItem( pInfo->TailLight = *(ULONG*)InBuffer; // call SetFeatureColor to trigger tail-light update - status = SetFeatureColor(WdfWmiInstanceGetDevice(WmiReportInstance), pInfo->TailLight); + status = SetFeatureColor(WdfWmiInstanceGetDevice(WmiInstance), pInfo->TailLight); } else { return STATUS_INVALID_DEVICE_REQUEST; } diff --git a/TailLight/wmi.h b/TailLight/wmi.h index 43837a22..b41caf56 100644 --- a/TailLight/wmi.h +++ b/TailLight/wmi.h @@ -1,25 +1,6 @@ // Where they are described. #define MOFRESOURCENAME L"TailLightWMI" -#define DPF_SOMETHING_FAILED( instance, something ) KdPrint(("TailLight: %s: " #something " failed 0x%x(" ## #instance ## ")\n", __func__, status)); - -#define IF_FAILED_RETURN_STATUS( instance, something ) \ - if (!NT_SUCCESS(status)) { \ - DPF_SOMETHING_FAILED( instance, something ) \ - return status; \ - } - - -struct COLOR_CONTROL { - ULONG Colors[2] = { 0xFF00, 0x0 }; - ULONG RemainingColors = 0; -}; - -#define REMAINING_COLORS_COUNT sizeof(COLOR_CONTROL::Colors) / \ - sizeof(*COLOR_CONTROL::Colors) - -WDF_DECLARE_CONTEXT_TYPE(COLOR_CONTROL); - // Initialize WMI provider NTSTATUS WmiInitialize(_In_ WDFDEVICE Device); @@ -28,4 +9,3 @@ EVT_WDF_WMI_INSTANCE_QUERY_INSTANCE EvtWmiInstanceQueryInstance; EVT_WDF_WMI_INSTANCE_SET_INSTANCE EvtWmiInstanceSetInstance; EVT_WDF_WMI_INSTANCE_SET_ITEM EvtWmiInstanceSetItem; -VOID FakeBISTTimerProc(_In_ WDFTIMER timer); \ No newline at end of file