_Use_decl_annotations_ NTSTATUS SaveSimBattStateToRegistry ( WDFDEVICE Device, PSIMBATT_STATE State ) /* Routine Description: Called to save simbatt state data to the registry. Arguments: Device - Supplies WDF device handle. State - Supplies the pointer to the simbatt state. Return Value: NTSTATUS --*/ { WDFKEY KeyHandle; DECLARE_CONST_UNICODE_STRING(SimbattStateRegNameStr, SIMBATT_STATE_REG_NAME); NTSTATUS Status; PAGED_CODE(); Status = WdfDeviceOpenRegistryKey( Device, PLUGPLAY_REGKEY_DEVICE, KEY_WRITE, NULL, &KeyHandle ); if (!NT_SUCCESS (Status)) { goto SaveSimBattStateToRegistryEnd; } Status = WdfRegistryAssignValue( KeyHandle, &SimbattStateRegNameStr, REG_BINARY, sizeof(SIMBATT_STATE), State ); WdfRegistryClose(KeyHandle); if (!NT_SUCCESS (Status)) { goto SaveSimBattStateToRegistryEnd; } SaveSimBattStateToRegistryEnd: return Status; }
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; }
NTSTATUS Ds4_AssignPdoContext(WDFDEVICE Device, PPDO_IDENTIFICATION_DESCRIPTION Description) { NTSTATUS status; PDS4_DEVICE_DATA ds4 = Ds4GetData(Device); KdPrint(("Initializing DS4 context...\n")); // I/O Queue for pending IRPs WDF_IO_QUEUE_CONFIG pendingUsbQueueConfig, notificationsQueueConfig; // Create and assign queue for incoming interrupt transfer WDF_IO_QUEUE_CONFIG_INIT(&pendingUsbQueueConfig, WdfIoQueueDispatchManual); status = WdfIoQueueCreate(Device, &pendingUsbQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, &ds4->PendingUsbInRequests); if (!NT_SUCCESS(status)) { KdPrint(("WdfIoQueueCreate failed 0x%x\n", status)); return status; } // Initialize periodic timer WDF_TIMER_CONFIG timerConfig; WDF_TIMER_CONFIG_INIT_PERIODIC(&timerConfig, Ds4_PendingUsbRequestsTimerFunc, DS4_QUEUE_FLUSH_PERIOD); // Timer object attributes WDF_OBJECT_ATTRIBUTES timerAttribs; WDF_OBJECT_ATTRIBUTES_INIT(&timerAttribs); // PDO is parent timerAttribs.ParentObject = Device; // Create timer status = WdfTimerCreate(&timerConfig, &timerAttribs, &ds4->PendingUsbInRequestsTimer); if (!NT_SUCCESS(status)) { KdPrint(("WdfTimerCreate failed 0x%x\n", status)); return status; } // Create and assign queue for user-land notification requests WDF_IO_QUEUE_CONFIG_INIT(¬ificationsQueueConfig, WdfIoQueueDispatchManual); status = WdfIoQueueCreate(Device, ¬ificationsQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, &ds4->PendingNotificationRequests); if (!NT_SUCCESS(status)) { KdPrint(("WdfIoQueueCreate failed 0x%x\n", status)); return status; } // Load/generate MAC address // TODO: tidy up this region WDFKEY keyParams, keyTargets, keyDS, keySerial; UNICODE_STRING keyName, valueName; status = WdfDriverOpenParametersRegistryKey(WdfGetDriver(), STANDARD_RIGHTS_ALL, WDF_NO_OBJECT_ATTRIBUTES, &keyParams); if (!NT_SUCCESS(status)) { KdPrint(("WdfDriverOpenParametersRegistryKey failed 0x%x\n", status)); return status; } RtlUnicodeStringInit(&keyName, L"Targets"); status = WdfRegistryCreateKey(keyParams, &keyName, KEY_ALL_ACCESS, REG_OPTION_NON_VOLATILE, NULL, WDF_NO_OBJECT_ATTRIBUTES, &keyTargets); if (!NT_SUCCESS(status)) { KdPrint(("WdfRegistryCreateKey failed 0x%x\n", status)); return status; } RtlUnicodeStringInit(&keyName, L"DualShock"); status = WdfRegistryCreateKey(keyTargets, &keyName, KEY_ALL_ACCESS, REG_OPTION_NON_VOLATILE, NULL, WDF_NO_OBJECT_ATTRIBUTES, &keyDS); if (!NT_SUCCESS(status)) { KdPrint(("WdfRegistryCreateKey failed 0x%x\n", status)); return status; } DECLARE_UNICODE_STRING_SIZE(serialPath, 4); RtlUnicodeStringPrintf(&serialPath, L"%04d", Description->SerialNo); status = WdfRegistryCreateKey(keyDS, &serialPath, KEY_ALL_ACCESS, REG_OPTION_NON_VOLATILE, NULL, WDF_NO_OBJECT_ATTRIBUTES, &keySerial); if (!NT_SUCCESS(status)) { KdPrint(("WdfRegistryCreateKey failed 0x%x\n", status)); return status; } RtlUnicodeStringInit(&valueName, L"TargetMacAddress"); status = WdfRegistryQueryValue(keySerial, &valueName, sizeof(MAC_ADDRESS), &ds4->TargetMacAddress, NULL, NULL); KdPrint(("MAC-Address: %02X:%02X:%02X:%02X:%02X:%02X\n", ds4->TargetMacAddress.Vendor0, ds4->TargetMacAddress.Vendor1, ds4->TargetMacAddress.Vendor2, ds4->TargetMacAddress.Nic0, ds4->TargetMacAddress.Nic1, ds4->TargetMacAddress.Nic2)); if (status == STATUS_OBJECT_NAME_NOT_FOUND) { GenerateRandomMacAddress(&ds4->TargetMacAddress); status = WdfRegistryAssignValue(keySerial, &valueName, REG_BINARY, sizeof(MAC_ADDRESS), (PVOID)&ds4->TargetMacAddress); if (!NT_SUCCESS(status)) { KdPrint(("WdfRegistryAssignValue failed 0x%x\n", status)); return status; } } else if (!NT_SUCCESS(status)) { KdPrint(("WdfRegistryQueryValue failed 0x%x\n", status)); return status; } WdfRegistryClose(keySerial); WdfRegistryClose(keyDS); WdfRegistryClose(keyTargets); WdfRegistryClose(keyParams); return STATUS_SUCCESS; }
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- 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; }