NTSTATUS WriteBackupRegistersToRegistry(HANDLE_DEV Device) { WDFKEY key = NULL; WDFKEY subkey = NULL; NTSTATUS status; // Retrieve registry settings. DECLARE_CONST_UNICODE_STRING(subConfigName, L"Config"); DECLARE_CONST_UNICODE_STRING(backupName, L"backup"); status = WdfDeviceOpenRegistryKey(Device, PLUGPLAY_REGKEY_DEVICE, KEY_READ, WDF_NO_OBJECT_ATTRIBUTES, &key); if (!NT_SUCCESS(status)) { TraceLog(TRACE_LEVEL_WARNING, TRACE_ALGO, "Error opening device registry key - %!STATUS!", status); } else { status = WdfRegistryOpenKey(key, &subConfigName, KEY_READ, WDF_NO_OBJECT_ATTRIBUTES, &subkey); if (!NT_SUCCESS(status)) { TraceLog(TRACE_LEVEL_WARNING, TRACE_ALGO, "Error opening registry subkey for 'Config' - %!STATUS!", status); } else { ULONG length = sizeof(gs_backupRegisters); status = WdfRegistryAssignValue(subkey, &backupName, REG_BINARY, length, gs_backupRegisters); if (!NT_SUCCESS(status)) { TraceLog(TRACE_LEVEL_WARNING, TRACE_ALGO, "Error querying registry value for 'backup reg' - %!STATUS!", status); } } if (subkey != NULL) { WdfRegistryClose(subkey); subkey = NULL; } } if (key != NULL) { WdfRegistryClose(key); key = NULL; } return status; }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DriverParametersKeyDelete -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // NTSTATUS DriverParametersKeyDelete( WDFDRIVER Driver, DtString* pKeyName) { NTSTATUS NtStatus; WDFKEY ParametersKey; WDFKEY Key = NULL; DT_ASSERT(KeGetCurrentIrql()<=PASSIVE_LEVEL); // Open the drivers parameters key (under services) NtStatus = WdfDriverOpenParametersRegistryKey(Driver, KEY_WRITE, WDF_NO_OBJECT_ATTRIBUTES, &ParametersKey); if (!NT_SUCCESS(NtStatus)) { DtDbgOut(ERR, SAL, "WdfDriverOpenParametersRegistryKey failed. Error: 0x%x", NtStatus); return NtStatus; } // Open subkey NtStatus = WdfRegistryOpenKey(ParametersKey, pKeyName, KEY_WRITE, WDF_NO_OBJECT_ATTRIBUTES, &Key); if (!NT_SUCCESS(NtStatus)) { if (NtStatus == STATUS_OBJECT_NAME_NOT_FOUND) DtDbgOut(MAX, SAL, "WdfRegistryOpenKey error:'STATUS_OBJECT_NAME_NOT_FOUND'"); else DtDbgOut(ERR, SAL, "WdfRegistryOpenKey failed. Error: 0x%x", NtStatus); } if (NT_SUCCESS(NtStatus)) { // Delete the key NtStatus = WdfRegistryRemoveKey(Key); if (!NT_SUCCESS(NtStatus)) DtDbgOut(ERR, SAL, "WdfRegistryRemoveKey failed. Error: 0x%x", NtStatus); else Key = NULL; } if (Key != NULL) WdfRegistryClose(Key); WdfRegistryClose(ParametersKey); return NtStatus; }
NTSTATUS OnDeviceAdd( _In_ WDFDRIVER FxDriver, _Inout_ PWDFDEVICE_INIT FxDeviceInit ) /*++ Routine Description: This routine creates the device object for an SPB controller and the device's child objects. Arguments: FxDriver - the WDF driver object handle FxDeviceInit - information about the PDO that we are loading on Return Value: Status --*/ { //FuncEntry(TRACE_FLAG_WDFLOADING); PDEVICE_CONTEXT pDevice; NTSTATUS status; UNREFERENCED_PARAMETER(FxDriver); // // Setup PNP/Power callbacks. // { WDF_PNPPOWER_EVENT_CALLBACKS pnpCallbacks; WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpCallbacks); pnpCallbacks.EvtDevicePrepareHardware = OnPrepareHardware; pnpCallbacks.EvtDeviceReleaseHardware = OnReleaseHardware; pnpCallbacks.EvtDeviceD0Entry = OnD0Entry; pnpCallbacks.EvtDeviceD0Exit = OnD0Exit; WdfDeviceInitSetPnpPowerEventCallbacks(FxDeviceInit, &pnpCallbacks); } // // Prepare for file object handling. // { WDF_FILEOBJECT_CONFIG fileObjectConfig; WDF_FILEOBJECT_CONFIG_INIT( &fileObjectConfig, nullptr, nullptr, OnFileCleanup); WDF_OBJECT_ATTRIBUTES fileObjectAttributes; WDF_OBJECT_ATTRIBUTES_INIT(&fileObjectAttributes); WdfDeviceInitSetFileObjectConfig( FxDeviceInit, &fileObjectConfig, &fileObjectAttributes); } // // Set request attributes. // { WDF_OBJECT_ATTRIBUTES attributes; WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE( &attributes, REQUEST_CONTEXT); WdfDeviceInitSetRequestAttributes(FxDeviceInit, &attributes); } // // Create the device. // { WDFDEVICE fxDevice; WDF_OBJECT_ATTRIBUTES deviceAttributes; WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT); status = WdfDeviceCreate( &FxDeviceInit, &deviceAttributes, &fxDevice); if (!NT_SUCCESS(status)) { Trace( TRACE_LEVEL_ERROR, TRACE_FLAG_WDFLOADING, "Error creating WDFDEVICE - %!STATUS!", status); goto exit; } pDevice = GetDeviceContext(fxDevice); NT_ASSERT(pDevice != nullptr); pDevice->FxDevice = fxDevice; } // // Ensure device is disable-able // { WDF_DEVICE_STATE deviceState; WDF_DEVICE_STATE_INIT(&deviceState); deviceState.NotDisableable = WdfFalse; WdfDeviceSetDeviceState(pDevice->FxDevice, &deviceState); } // // Create queues to handle IO // { WDF_IO_QUEUE_CONFIG queueConfig; WDFQUEUE queue; // // Top-level queue // WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE( &queueConfig, WdfIoQueueDispatchParallel); queueConfig.EvtIoDefault = OnTopLevelIoDefault; queueConfig.PowerManaged = WdfFalse; status = WdfIoQueueCreate( pDevice->FxDevice, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &queue ); if (!NT_SUCCESS(status)) { Trace( TRACE_LEVEL_ERROR, TRACE_FLAG_WDFLOADING, "Error creating top-level IO queue - %!STATUS!", status); goto exit; } // // Sequential SPB queue // WDF_IO_QUEUE_CONFIG_INIT( &queueConfig, WdfIoQueueDispatchSequential); queueConfig.EvtIoRead = OnIoRead; queueConfig.EvtIoWrite = OnIoWrite; queueConfig.EvtIoDeviceControl = OnIoDeviceControl; queueConfig.PowerManaged = WdfFalse; status = WdfIoQueueCreate( pDevice->FxDevice, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &pDevice->SpbQueue ); if (!NT_SUCCESS(status)) { Trace( TRACE_LEVEL_ERROR, TRACE_FLAG_WDFLOADING, "Error creating SPB IO queue - %!STATUS!", status); goto exit; } } // // Create a symbolic link. // { DECLARE_UNICODE_STRING_SIZE(symbolicLinkName, 128); status = RtlUnicodeStringPrintf( &symbolicLinkName, L"%ws", sensy_SYMBOLIC_NAME); if (!NT_SUCCESS(status)) { Trace( TRACE_LEVEL_ERROR, TRACE_FLAG_WDFLOADING, "Error creating symbolic link string for device " "- %!STATUS!", status); goto exit; } status = WdfDeviceCreateSymbolicLink( pDevice->FxDevice, &symbolicLinkName); if (!NT_SUCCESS(status)) { Trace( TRACE_LEVEL_ERROR, TRACE_FLAG_WDFLOADING, "Error creating symbolic link for device " "- %!STATUS!", status); goto exit; } } // // Retrieve registry settings. // { WDFKEY key = NULL; WDFKEY subkey = NULL; ULONG connectInterrupt = 0; NTSTATUS settingStatus; DECLARE_CONST_UNICODE_STRING(subkeyName, L"Settings"); DECLARE_CONST_UNICODE_STRING(connectInterruptName, L"ConnectInterrupt"); settingStatus = WdfDeviceOpenRegistryKey( pDevice->FxDevice, PLUGPLAY_REGKEY_DEVICE, KEY_READ, WDF_NO_OBJECT_ATTRIBUTES, &key); if (!NT_SUCCESS(settingStatus)) { Trace( TRACE_LEVEL_WARNING, TRACE_FLAG_WDFLOADING, "Error opening device registry key - %!STATUS!", settingStatus); } if (NT_SUCCESS(settingStatus)) { settingStatus = WdfRegistryOpenKey( key, &subkeyName, KEY_READ, WDF_NO_OBJECT_ATTRIBUTES, &subkey); if (!NT_SUCCESS(settingStatus)) { Trace( TRACE_LEVEL_WARNING, TRACE_FLAG_WDFLOADING, "Error opening registry subkey for 'Settings' - %!STATUS!", settingStatus); } } if (NT_SUCCESS(settingStatus)) { settingStatus = WdfRegistryQueryULong( subkey, &connectInterruptName, &connectInterrupt); if (!NT_SUCCESS(settingStatus)) { Trace( TRACE_LEVEL_WARNING, TRACE_FLAG_WDFLOADING, "Error querying registry value for 'ConnectInterrupt' - %!STATUS!", settingStatus); } } if (key != NULL) { WdfRegistryClose(key); } if (subkey != NULL) { WdfRegistryClose(subkey); } pDevice->ConnectInterrupt = (connectInterrupt == 1); } exit: //FuncExit(TRACE_FLAG_WDFLOADING); return status; }
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DriverParametersKeyWrite -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // NTSTATUS DriverParametersKeyWrite( WDFDRIVER Driver, DtString* pKeyName, DtString* pValueName, Int64 BinValue, DtString* pStrValue) { NTSTATUS NtStatus; WDFKEY ParametersKey; WDFKEY Key = NULL; WDFSTRING WdfString; DT_ASSERT(KeGetCurrentIrql()<=PASSIVE_LEVEL); // Check if the registry path already exists. If not, create the registry path. if (!DT_SUCCESS(CheckAndCreateRegistryPath(Driver, pKeyName))) return STATUS_UNSUCCESSFUL; // Open the drivers parameters key (under services) NtStatus = WdfDriverOpenParametersRegistryKey(Driver, KEY_WRITE, WDF_NO_OBJECT_ATTRIBUTES, &ParametersKey); if (!NT_SUCCESS(NtStatus)) { DtDbgOut(ERR, SAL, "WdfDriverOpenParametersRegistryKey failed. Error: 0x%x", NtStatus); return NtStatus; } // Open the key (including part of path) NtStatus = WdfRegistryOpenKey(ParametersKey, pKeyName, KEY_WRITE, WDF_NO_OBJECT_ATTRIBUTES, &Key); if (!NT_SUCCESS(NtStatus)) DtDbgOut(ERR, SAL, "WdfRegistryOpenKey failed. Error: 0x%x", NtStatus); if (NT_SUCCESS(NtStatus)) { // Write string or binary value if (pStrValue != NULL) { // Set string attributes with the key as parent object, so that the string // object is freed when the key object is destroyed. If we donot do this the // string object is freed when the driver unloads, meaning that the each call // to DriverParametersKeyWrite result in an increase of memory usage, only // to be freed on the unload. WDF_OBJECT_ATTRIBUTES WdfStringAttr; WDF_OBJECT_ATTRIBUTES_INIT(&WdfStringAttr); WdfStringAttr.ParentObject = Key; NtStatus = WdfStringCreate(pStrValue, &WdfStringAttr, &WdfString); if (NT_SUCCESS(NtStatus)) NtStatus = WdfRegistryAssignString(Key, pValueName, WdfString); } else NtStatus = WdfRegistryAssignValue(Key, pValueName, REG_QWORD, sizeof(Int64), &BinValue); if (!NT_SUCCESS(NtStatus)) DtDbgOut(ERR, SAL, "WdfRegistryAssignValue failed. Error: 0x%x", NtStatus); } if (Key != NULL) WdfRegistryClose(Key); WdfRegistryClose(ParametersKey); return NtStatus; }
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DriverParametersKeyRead -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. // NTSTATUS DriverParametersKeyRead( WDFDRIVER Driver, DtString* pKeyName, DtString* pValueName, Int64* pBinValue, DtString* pStrValue) { NTSTATUS NtStatus; WDFKEY ParametersKey; WDFKEY Key = NULL; WDFSTRING WdfString = NULL; DtString RegStrValue; DT_ASSERT(KeGetCurrentIrql()<=PASSIVE_LEVEL); // Only one value can be requested DT_ASSERT((pBinValue!=NULL && pStrValue==NULL)||(pBinValue==NULL && pStrValue!=NULL)); // Open the drivers parameters key (under services) NtStatus = WdfDriverOpenParametersRegistryKey(Driver, KEY_READ, WDF_NO_OBJECT_ATTRIBUTES, &ParametersKey); if (!NT_SUCCESS(NtStatus)) { DtDbgOut(ERR, SAL, "WdfDriverOpenParametersRegistryKey failed. Error: 0x%x", NtStatus); return NtStatus; } // Open subkey NtStatus = WdfRegistryOpenKey(ParametersKey, pKeyName, KEY_READ, WDF_NO_OBJECT_ATTRIBUTES, &Key); if (!NT_SUCCESS(NtStatus)) { if (NtStatus == STATUS_OBJECT_NAME_NOT_FOUND) DtDbgOut(MAX, SAL, "WdfRegistryOpenKey error:'STATUS_OBJECT_NAME_NOT_FOUND'"); else DtDbgOut(ERR, SAL, "WdfRegistryOpenKey failed. Error: 0x%x", NtStatus); } if (NT_SUCCESS(NtStatus)) { // Read string or binary value if (pStrValue != NULL) { // Set string attributes with the key as parent object, so that the string // object is freed when the key object is destroyed. If we donot do this the // string object is freed when the driver unloads, meaning that the each call // to DriverParametersKeyRead result in an increase of memory usage, only // to be freed on the unload. WDF_OBJECT_ATTRIBUTES WdfStringAttr; WDF_OBJECT_ATTRIBUTES_INIT(&WdfStringAttr); WdfStringAttr.ParentObject = Key; NtStatus = WdfStringCreate(pStrValue, &WdfStringAttr, &WdfString); // Read string from registry if (NT_SUCCESS(NtStatus)) NtStatus = WdfRegistryQueryString(Key, pValueName, WdfString); // Convert WdfString to DtString if (NT_SUCCESS(NtStatus)) WdfStringGetUnicodeString(WdfString, &RegStrValue); // Make a copy of the string if (NT_SUCCESS(NtStatus)) NtStatus = DtStringClear(pStrValue); if (NT_SUCCESS(NtStatus)) NtStatus = DtStringAppendDtString(pStrValue, &RegStrValue); } else NtStatus = WdfRegistryQueryValue(Key, pValueName, sizeof(Int64), pBinValue, NULL, NULL); if (!NT_SUCCESS(NtStatus)) { if (NtStatus == STATUS_OBJECT_NAME_NOT_FOUND) DtDbgOut(MAX, SAL, "WdfRegistryQueryValue error:" "'STATUS_OBJECT_NAME_NOT_FOUND'"); else DtDbgOut(ERR, SAL, "WdfRegistryQueryValue failed. Error: 0x%x", NtStatus); } } if (Key != NULL) WdfRegistryClose(Key); WdfRegistryClose(ParametersKey); return NtStatus; }