_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; }
BOOLEAN SerialPutRegistryKeyValue( IN WDFDEVICE WdfDevice, _In_ PCWSTR Name, IN ULONG Value ) /*++ Routine Description: Can be used to write any REG_DWORD registry value stored under Device Parameter. Arguments: Return Value: TRUE - if write is successful FALSE - otherwise --*/ { WDFKEY hKey = NULL; NTSTATUS status; BOOLEAN retValue = FALSE; UNICODE_STRING valueName; PAGED_CODE(); SerialDbgPrintEx(TRACE_LEVEL_VERBOSE, DBG_PNP, "Entered PciDrvWriteRegistryValue\n"); // // write the value out to the registry // status = WdfDeviceOpenRegistryKey(WdfDevice, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_ALL, WDF_NO_OBJECT_ATTRIBUTES, &hKey); if (NT_SUCCESS (status)) { RtlInitUnicodeString(&valueName,Name); status = WdfRegistryAssignULong (hKey, &valueName, Value ); if (NT_SUCCESS (status)) { retValue = TRUE; } WdfRegistryClose(hKey); } return retValue; }
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; }
VOID EvtDeviceCleanup( _In_ WDFOBJECT Object ) { WDFDEVICE device = (WDFDEVICE) Object; PDEVICE_CONTEXT deviceContext = GetDeviceContext(device); NTSTATUS status; WDFKEY key = NULL; UNICODE_STRING pdoString = {0}; DECLARE_CONST_UNICODE_STRING(deviceSubkey, SERIAL_DEVICE_MAP); if (deviceContext->CreatedLegacyHardwareKey == TRUE) { RtlInitUnicodeString(&pdoString, deviceContext->PdoName); status = WdfDeviceOpenDevicemapKey(device, &deviceSubkey, KEY_SET_VALUE, WDF_NO_OBJECT_ATTRIBUTES, &key); if (!NT_SUCCESS(status)) { Trace(TRACE_LEVEL_ERROR, "Error: Failed to open DEVICEMAP\\SERIALCOMM key 0x%x", status); goto exit; } status = WdfRegistryRemoveValue(key, &pdoString); if (!NT_SUCCESS(status)) { Trace(TRACE_LEVEL_ERROR, "Error: Failed to delete %S key, 0x%x", pdoString.Buffer, status); goto exit; } status = WdfRegistryRemoveKey(key); if (!NT_SUCCESS(status)) { Trace(TRACE_LEVEL_ERROR, "Error: Failed to delete %S, 0x%x", SERIAL_DEVICE_MAP, status); goto exit; } } exit: if (key != NULL) { WdfRegistryClose(key); key = NULL; } return; }
VOID DeviceQueryDeviceParameters( _In_ WDFDRIVER _Driver ) /*++ Routine Description: Query driver's registry location for device specific parameter, such as baudrate. HLM\system\CCS\Services\serialhcibus\Parameters\ KeyName/Type/value Arguments: _Driver - WDF Driver object Return Value: None --*/ { WDFKEY Key; NTSTATUS Status; UNICODE_STRING ValueName; ULONG Value = 0; PAGED_CODE(); Status = WdfDriverOpenParametersRegistryKey(_Driver, GENERIC_READ, WDF_NO_OBJECT_ATTRIBUTES, &Key ); if (NT_SUCCESS(Status)) { RtlInitUnicodeString(&ValueName, STR_BAUDRATE); Status = WdfRegistryQueryULong(Key, &ValueName, &Value); if (NT_SUCCESS(Status)) { // Vendor: can cache and use this values. } WdfRegistryClose(Key); } }
NTSTATUS DeviceWriteLegacyHardwareKey( _In_ PWSTR PdoName, _In_ PWSTR ComPort, _In_ WDFDEVICE Device ) { WDFKEY key = NULL; NTSTATUS status; UNICODE_STRING pdoString = {0}; UNICODE_STRING comPort = {0}; DECLARE_CONST_UNICODE_STRING(deviceSubkey, SERIAL_DEVICE_MAP); RtlInitUnicodeString(&pdoString, PdoName); RtlInitUnicodeString(&comPort, ComPort); status = WdfDeviceOpenDevicemapKey(Device, &deviceSubkey, KEY_SET_VALUE, WDF_NO_OBJECT_ATTRIBUTES, &key); if (!NT_SUCCESS(status)) { Trace(TRACE_LEVEL_ERROR, "Error: Failed to open DEVICEMAP\\SERIALCOMM key 0x%x", status); goto exit; } status = WdfRegistryAssignUnicodeString(key, &pdoString, &comPort); if (!NT_SUCCESS(status)) { Trace(TRACE_LEVEL_ERROR, "Error: Failed to write to DEVICEMAP\\SERIALCOMM key 0x%x", status); goto exit; } exit: if (key != NULL) { WdfRegistryClose(key); key = NULL; } return status; }
VOID MamakuRegistryInit(IN WDFDRIVER Driver) { NTSTATUS status; WDFKEY key; DECLARE_CONST_UNICODE_STRING(UseMultitouchName, L"UseMultitouchDebug"); DECLARE_CONST_UNICODE_STRING(DragThresholdName, L"DragThreshold"); status = WdfDriverOpenParametersRegistryKey(Driver, STANDARD_RIGHTS_ALL, WDF_NO_OBJECT_ATTRIBUTES, &key); if (!NT_SUCCESS(status)) { MamakuPrint(DEBUG_LEVEL_ERROR, DBG_INIT, "WdfDriverOpenParametersRegistryKey failed with status 0x%x\n", status); return; } status = WdfRegistryQueryULong(key, &UseMultitouchName, &UseMultitouch); if (!NT_SUCCESS(status)) { MamakuPrint(DEBUG_LEVEL_ERROR, DBG_INIT, "WdfRegistryQueryULong(UseMultitouch) failed with status 0x%x\n", status); } MamakuPrint(DEBUG_LEVEL_ERROR, DBG_INIT, "UseMultitouchDebug = %d\n", UseMultitouch); status = WdfRegistryQueryULong(key, &DragThresholdName, &DragThreshold); if (!NT_SUCCESS(status)) { MamakuPrint(DEBUG_LEVEL_ERROR, DBG_INIT, "WdfRegistryQueryULong(DragThreshold) failed with status 0x%x\n", status); } MamakuPrint(DEBUG_LEVEL_ERROR, DBG_INIT, "DragThreshold = %d\n", DragThreshold); WdfRegistryClose(key); }
NTSTATUS registry_create_key(WDFKEY parent_key, PUNICODE_STRING key_str, WDFKEY *key) { NTSTATUS status; WDFKEY new_key; status = WdfRegistryCreateKey(parent_key, key_str, STANDARD_RIGHTS_ALL, REG_OPTION_NON_VOLATILE, NULL, WDF_NO_OBJECT_ATTRIBUTES, &new_key); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, "WdfRegistryCreateKey failed %!STATUS!", status); return status; } if (key) *key = new_key; else WdfRegistryClose(new_key); return status; }
/*++ Routine Description: Can be used to read any REG_DWORD registry value stored under Device Parameter. Arguments: Driver - pointer to the device object Name - Name of the registry value Value - Value... --*/ NTSTATUS ReadFdoRegistryKeyValue(__in WDFDRIVER Driver, __in LPWSTR Name, __out PULONG Value) { WDFKEY hKey = NULL; NTSTATUS status; UNICODE_STRING valueName; UNREFERENCED_PARAMETER(Driver); PAGED_CODE(); *Value = 0; status = WdfDriverOpenParametersRegistryKey(WdfGetDriver(), KEY_READ, WDF_NO_OBJECT_ATTRIBUTES, &hKey); if (NT_SUCCESS(status)) { RtlInitUnicodeString(&valueName,Name); status = WdfRegistryQueryULong (hKey, &valueName, Value); WdfRegistryClose(hKey); } return status; }
NTSTATUS Bus_DoStaticEnumeration( IN WDFDEVICE Device ) /*++ Routine Description: The routine enables you to statically enumerate child devices during start instead of running the enum.exe/notify.exe to enumerate toaster devices. In order to statically enumerate, user must specify the number of toasters in the Toaster Bus driver's device registry. The default value is zero. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root\SYSTEM\0002\ Device Parameters NumberOfToasters:REG_DWORD:2 You can also configure this value in the Toaster Bus Inf file. --*/ { WDFKEY hKey = NULL; NTSTATUS status; ULONG value, i; DECLARE_CONST_UNICODE_STRING(valueName, L"NumberOfToasters"); // // If the registry value doesn't exist, we will use the // hardcoded default number. // value = DEF_STATICALLY_ENUMERATED_TOASTERS; // // Open the device registry and read the "NumberOfToasters" value. // status = WdfDeviceOpenRegistryKey(Device, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_ALL, NULL, // PWDF_OBJECT_ATTRIBUTES &hKey); if (NT_SUCCESS (status)) { status = WdfRegistryQueryULong(hKey, &valueName, &value); WdfRegistryClose(hKey); hKey = NULL; // Set hKey to NULL to catch any accidental subsequent use. if (NT_SUCCESS (status)) { // // Make sure it doesn't exceed the max. This is required to prevent // denial of service by enumerating large number of child devices. // value = min(value, MAX_STATICALLY_ENUMERATED_TOASTERS); }else { return STATUS_SUCCESS; // This is an optional property. } } KdPrint(("Enumerating %d toaster devices\n", value)); for(i=1; i<= value; i++) { // // Value of i is used as serial number. // status = Bus_PlugInDevice(Device, BUS_HARDWARE_IDS, BUS_HARDWARE_IDS_LENGTH / sizeof(WCHAR), i ); } return status; }
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; }
BOOLEAN SerialGetFdoRegistryKeyValue( IN PWDFDEVICE_INIT DeviceInit, _In_ PCWSTR Name, OUT PULONG Value ) /*++ Routine Description: Can be used to read any REG_DWORD registry value stored under Device Parameter. Arguments: FdoData - pointer to the device extension Name - Name of the registry value Value - Return Value: TRUE if successful FALSE if not present/error in reading registry --*/ { WDFKEY hKey = NULL; NTSTATUS status; BOOLEAN retValue = FALSE; UNICODE_STRING valueName; PAGED_CODE(); SerialDbgPrintEx(TRACE_LEVEL_VERBOSE, DBG_PNP, "-->SerialGetFdoRegistryKeyValue\n"); *Value = 0; status = WdfFdoInitOpenRegistryKey(DeviceInit, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_ALL, WDF_NO_OBJECT_ATTRIBUTES, &hKey); if (NT_SUCCESS (status)) { RtlInitUnicodeString(&valueName,Name); status = WdfRegistryQueryULong (hKey, &valueName, Value); if (NT_SUCCESS (status)) { retValue = TRUE; } WdfRegistryClose(hKey); } SerialDbgPrintEx(TRACE_LEVEL_VERBOSE, DBG_PNP, "<--SerialGetFdoRegistryKeyValue %ws %d \n", Name, *Value); return retValue; }
NTSTATUS SerialGetConfigDefaults( IN PSERIAL_FIRMWARE_DATA DriverDefaultsPtr, IN WDFDRIVER Driver ) /*++ Routine Description: This routine reads the default configuration data from the registry for the serial driver. It also builds fields in the registry for several configuration options if they don't exist. Arguments: DriverDefaultsPtr - Pointer to a structure that will contain the default configuration values. RegistryPath - points to the entry for this driver in the current control set of the registry. Return Value: STATUS_SUCCESS if we got the defaults, otherwise we failed. The only way to fail this call is if the STATUS_INSUFFICIENT_RESOURCES. --*/ { NTSTATUS status = STATUS_SUCCESS; // return value WDFKEY hKey; DECLARE_UNICODE_STRING_SIZE(valueName,PARAMATER_NAME_LEN); status = WdfDriverOpenParametersRegistryKey(Driver, STANDARD_RIGHTS_ALL, WDF_NO_OBJECT_ATTRIBUTES, &hKey); if (!NT_SUCCESS (status)) { return status; } status = RtlUnicodeStringPrintf(&valueName,L"BreakOnEntry"); if (!NT_SUCCESS (status)) { goto End; } status = WdfRegistryQueryULong (hKey, &valueName, &DriverDefaultsPtr->ShouldBreakOnEntry); if (!NT_SUCCESS (status)) { DriverDefaultsPtr->ShouldBreakOnEntry = 0; } status = RtlUnicodeStringPrintf(&valueName,L"DebugLevel"); if (!NT_SUCCESS (status)) { goto End; } status = WdfRegistryQueryULong (hKey, &valueName, &DriverDefaultsPtr->DebugLevel); if (!NT_SUCCESS (status)) { DriverDefaultsPtr->DebugLevel = 0; } status = RtlUnicodeStringPrintf(&valueName,L"ForceFifoEnable"); if (!NT_SUCCESS (status)) { goto End; } status = WdfRegistryQueryULong (hKey, &valueName, &DriverDefaultsPtr->ForceFifoEnableDefault); if (!NT_SUCCESS (status)) { // // If it isn't then write out values so that it could // be adjusted later. // DriverDefaultsPtr->ForceFifoEnableDefault = SERIAL_FORCE_FIFO_DEFAULT; status = WdfRegistryAssignULong(hKey, &valueName, DriverDefaultsPtr->ForceFifoEnableDefault ); if (!NT_SUCCESS (status)) { goto End; } } status = RtlUnicodeStringPrintf(&valueName,L"RxFIFO"); if (!NT_SUCCESS (status)) { goto End; } status = WdfRegistryQueryULong (hKey, &valueName, &DriverDefaultsPtr->RxFIFODefault); if (!NT_SUCCESS (status)) { DriverDefaultsPtr->RxFIFODefault = SERIAL_RX_FIFO_DEFAULT; status = WdfRegistryAssignULong(hKey, &valueName, DriverDefaultsPtr->RxFIFODefault ); if (!NT_SUCCESS (status)) { goto End; } } status = RtlUnicodeStringPrintf(&valueName,L"TxFIFO"); if (!NT_SUCCESS (status)) { goto End; } status = WdfRegistryQueryULong (hKey, &valueName, &DriverDefaultsPtr->TxFIFODefault); if (!NT_SUCCESS (status)) { DriverDefaultsPtr->TxFIFODefault = SERIAL_TX_FIFO_DEFAULT; status = WdfRegistryAssignULong(hKey, &valueName, DriverDefaultsPtr->TxFIFODefault ); if (!NT_SUCCESS (status)) { goto End; } } status = RtlUnicodeStringPrintf(&valueName,L"PermitShare"); if (!NT_SUCCESS (status)) { goto End; } status = WdfRegistryQueryULong (hKey, &valueName, &DriverDefaultsPtr->PermitShareDefault); if (!NT_SUCCESS (status)) { DriverDefaultsPtr->PermitShareDefault = SERIAL_PERMIT_SHARE_DEFAULT; status = WdfRegistryAssignULong(hKey, &valueName, DriverDefaultsPtr->PermitShareDefault ); if (!NT_SUCCESS (status)) { goto End; } } status = RtlUnicodeStringPrintf(&valueName,L"LogFifo"); if (!NT_SUCCESS (status)) { goto End; } status = WdfRegistryQueryULong (hKey, &valueName, &DriverDefaultsPtr->LogFifoDefault); if (!NT_SUCCESS (status)) { DriverDefaultsPtr->LogFifoDefault = SERIAL_LOG_FIFO_DEFAULT; status = WdfRegistryAssignULong(hKey, &valueName, DriverDefaultsPtr->LogFifoDefault ); if (!NT_SUCCESS (status)) { goto End; } DriverDefaultsPtr->LogFifoDefault = 1; } status = RtlUnicodeStringPrintf(&valueName,L"UartRemovalDetect"); if (!NT_SUCCESS (status)) { goto End; } status = WdfRegistryQueryULong (hKey, &valueName, &DriverDefaultsPtr->UartRemovalDetect); if (!NT_SUCCESS (status)) { DriverDefaultsPtr->UartRemovalDetect = 0; } End: WdfRegistryClose(hKey); return (status); }
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- 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; }
_Use_decl_annotations_ NTSTATUS OnDeviceAdd (WDFDRIVER /*WdfDriver*/, WDFDEVICE_INIT* DeviceInitPtr) { PAGED_CODE(); BCM_I2C_ASSERT_MAX_IRQL(PASSIVE_LEVEL); NTSTATUS status; // // Configure DeviceInit structure // status = SpbDeviceInitConfig(DeviceInitPtr); if (!NT_SUCCESS(status)) { BSC_LOG_ERROR( "SpbDeviceInitConfig() failed. (DeviceInitPtr = %p, status = %!STATUS!)", DeviceInitPtr, status); return status; } // // 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(DeviceInitPtr, &pnpCallbacks); } // // Create the device. // WDFDEVICE wdfDevice; BCM_I2C_DEVICE_CONTEXT* devicePtr; { WDF_OBJECT_ATTRIBUTES deviceAttributes; WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE( &deviceAttributes, BCM_I2C_DEVICE_CONTEXT); status = WdfDeviceCreate( &DeviceInitPtr, &deviceAttributes, &wdfDevice); if (!NT_SUCCESS(status)) { BSC_LOG_ERROR( "Failed to create WDFDEVICE. (DeviceInitPtr = %p, status = %!STATUS!)", DeviceInitPtr, status); return status; } devicePtr = GetDeviceContext(wdfDevice); NT_ASSERT(devicePtr); devicePtr->WdfDevice = wdfDevice; } // // Query registry for ClockStretchTimeout // { WDFKEY wdfKey; status = WdfDeviceOpenRegistryKey( wdfDevice, PLUGPLAY_REGKEY_DEVICE, KEY_QUERY_VALUE, WDF_NO_OBJECT_ATTRIBUTES, &wdfKey); if (!NT_SUCCESS(status)) { BSC_LOG_ERROR( "Failed to open device parameters registry key. (status=%!STATUS!)", status); return status; } auto closeRegKey = Finally([&] { PAGED_CODE(); WdfRegistryClose(wdfKey); }); DECLARE_CONST_UNICODE_STRING( regValString, REGSTR_VAL_CLOCK_STRETCH_TIMEOUT); ULONG clockStretchTimeout; status = WdfRegistryQueryULong( wdfKey, ®ValString, &clockStretchTimeout); if (NT_SUCCESS(status)) { if ((clockStretchTimeout & BCM_I2C_REG_CLKT_TOUT_MASK) != clockStretchTimeout) { BSC_LOG_ERROR( "Clock stretch timeout value from registry is out of range. (clockStretchTimeout=0x%x, BCM_I2C_REG_CLKT_TOUT_MASK=0x%x)", clockStretchTimeout, BCM_I2C_REG_CLKT_TOUT_MASK); return STATUS_INVALID_PARAMETER; } BSC_LOG_INFORMATION( "Using ClockStretchTimeout value from registry. (clockStretchTimeout=0x%x)", clockStretchTimeout); } else { switch (status) { case STATUS_OBJECT_NAME_NOT_FOUND: clockStretchTimeout = BCM_I2C_REG_CLKT_TOUT_DEFAULT; status = STATUS_SUCCESS; break; default: BSC_LOG_ERROR( "Failed to query clock stretch timeout from registry. (status=%!STATUS!, REGSTR_VAL_CLOCK_STRETCH_TIMEOUT=%S)", status, REGSTR_VAL_CLOCK_STRETCH_TIMEOUT); return status; } } devicePtr->ClockStretchTimeout = clockStretchTimeout; } // // Ensure device is disable-able // { WDF_DEVICE_STATE deviceState; WDF_DEVICE_STATE_INIT(&deviceState); deviceState.NotDisableable = WdfFalse; WdfDeviceSetDeviceState(wdfDevice, &deviceState); } // // Bind a SPB controller object to the device. // { SPB_CONTROLLER_CONFIG spbConfig; SPB_CONTROLLER_CONFIG_INIT(&spbConfig); // // Register for target connect callback. The driver // does not need to respond to target disconnect. // spbConfig.EvtSpbTargetConnect = OnTargetConnect; // // Register for IO callbacks. // spbConfig.ControllerDispatchType = WdfIoQueueDispatchSequential; spbConfig.EvtSpbIoRead = OnRead; spbConfig.EvtSpbIoWrite = OnWrite; spbConfig.EvtSpbIoSequence = OnSequence; status = SpbDeviceInitialize(wdfDevice, &spbConfig); if (!NT_SUCCESS(status)) { BSC_LOG_ERROR( "SpbDeviceInitialize failed. (wdfDevice = %p, status = %!STATUS!)", wdfDevice, status); return status; } } // // Set target object attributes. // { WDF_OBJECT_ATTRIBUTES targetAttributes; WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE( &targetAttributes, BCM_I2C_TARGET_CONTEXT); SpbControllerSetTargetAttributes(wdfDevice, &targetAttributes); } // // Create an interrupt object // BCM_I2C_INTERRUPT_CONTEXT* interruptContextPtr; { WDF_OBJECT_ATTRIBUTES interruptObjectAttributes; WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE( &interruptObjectAttributes, BCM_I2C_INTERRUPT_CONTEXT); WDF_INTERRUPT_CONFIG interruptConfig; WDF_INTERRUPT_CONFIG_INIT( &interruptConfig, OnInterruptIsr, OnInterruptDpc); status = WdfInterruptCreate( wdfDevice, &interruptConfig, &interruptObjectAttributes, &devicePtr->WdfInterrupt); if (!NT_SUCCESS(status)) { BSC_LOG_ERROR( "Failed to create interrupt object. (wdfDevice = %p, status = %!STATUS!)", wdfDevice, status); return status; } interruptContextPtr = GetInterruptContext(devicePtr->WdfInterrupt); interruptContextPtr->WdfInterrupt = devicePtr->WdfInterrupt; } devicePtr->InterruptContextPtr = interruptContextPtr; NT_ASSERT(NT_SUCCESS(status)); return STATUS_SUCCESS; }
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; }
NTSTATUS Registry_ReadAllDeviceKeys(__in PDEVICE_CONTEXT deviceContext) { WDFKEY hKey = NULL; NTSTATUS status = STATUS_INVALID_DEVICE_STATE; UNICODE_STRING valueName; WDF_OBJECT_ATTRIBUTES collectionAttributes; WDF_OBJECT_ATTRIBUTES stringAttributes; GUID guidTest = {0}; PAGED_CODE(); if (!deviceContext->WdfDevice) { USBERR("deviceContext->WdfDevice is NULL.\n"); return status; } // The driver sets the PLUGPLAY_REGKEY_DEVICE flag to open the Device // Parameters subkey under the device's hardware key, or it sets the // PLUGPLAY_REGKEY_DRIVER flag to open the driver's software key. If the // PLUGPLAY_REGKEY_CURRENT_HWPROFILE flag is also set, // WdfDeviceOpenRegistryKey opens the copy of the hardware or software key // that is in the current hardware profile. status = WdfDeviceOpenRegistryKey(deviceContext->WdfDevice, PLUGPLAY_REGKEY_DEVICE, KEY_READ, WDF_NO_OBJECT_ATTRIBUTES, &hKey); if (!NT_SUCCESS (status)) { USBERR("WdfDeviceOpenRegistryKey failed.\n"); hKey = NULL; return status; } ////////////////////////////////////////////////////////////////////////// // Read the device interface guids from the registry. // These are set in the inf files [Device_AddReg] group. // WDF_OBJECT_ATTRIBUTES_INIT(&collectionAttributes); collectionAttributes.ParentObject = deviceContext->WdfDevice; status = WdfCollectionCreate(&collectionAttributes, &deviceContext->DeviceRegSettings.DeviceInterfaceGUIDs); if (!NT_SUCCESS(status)) { USBERR("collection object could not be allocated. status=%Xh", status); goto Done; } WDF_OBJECT_ATTRIBUTES_INIT(&stringAttributes); stringAttributes.ParentObject = deviceContext->DeviceRegSettings.DeviceInterfaceGUIDs; RtlInitUnicodeString(&valueName, L"DeviceInterfaceGUIDs"); status = WdfRegistryQueryMultiString(hKey, &valueName, &stringAttributes, deviceContext->DeviceRegSettings.DeviceInterfaceGUIDs); if (NT_SUCCESS(status)) { ULONG guidCount = WdfCollectionGetCount(deviceContext->DeviceRegSettings.DeviceInterfaceGUIDs); ULONG guidIndex; WDFSTRING wdfGuidString; BOOLEAN removeGuidFromCollection; USBMSG("Found %u DeviceInterfaceGUIDs strings.", guidCount); for (guidIndex = 0; guidIndex < guidCount; guidIndex++) { removeGuidFromCollection = TRUE; wdfGuidString = (WDFSTRING)WdfCollectionGetItem(deviceContext->DeviceRegSettings.DeviceInterfaceGUIDs, guidIndex); status = GUIDFromWdfString(wdfGuidString, &guidTest); if (!NT_SUCCESS(status)) { USBERR("removing invalid DeviceInterfaceGUID string at index %u\n", guidIndex); } else { if (IsEqualGUID(&guidTest, &Libusb0DeviceGuid)) { USBWRN("libusb0 device DeviceInterfaceGUID found. skippng..\n"); } else if (IsEqualGUID(&guidTest, &Libusb0FilterGuid)) { USBWRN("libusb0 filter DeviceInterfaceGUID found. skippng..\n"); } else if (IsEqualGUID(&guidTest, &LibusbKDeviceGuid)) { USBWRN("libusbK default device DeviceInterfaceGUID found. skippng..\n"); } else { removeGuidFromCollection = FALSE; } } if (removeGuidFromCollection) { WdfCollectionRemoveItem(deviceContext->DeviceRegSettings.DeviceInterfaceGUIDs, guidIndex); guidIndex--; guidCount--; } } } else { USBWRN("DeviceInterfaceGUIDs registry key does not exist.\n" " Ensure the DeviceInterfaceGUIDs key has been properly set in the .inf and re-install the device.\n\n"); } if (WdfCollectionGetCount(deviceContext->DeviceRegSettings.DeviceInterfaceGUIDs) == 0) { status = AddDefaultDeviceInterfaceGUID(deviceContext); if (!NT_SUCCESS(status)) { goto Done; } } ////////////////////////////////////////////////////////////////////////// // Read the device power policy settings (if any). // These are set in the inf files [Device_AddReg] group. // GetDeviceRegSettingKey(DeviceIdleEnabled, FALSE); GetDeviceRegSettingKey(DeviceIdleIgnoreWakeEnable, FALSE); GetDeviceRegSettingKey(UserSetDeviceIdleEnabled, FALSE); GetDeviceRegSettingKey(DefaultIdleState, FALSE); GetDeviceRegSettingKey(DefaultIdleTimeout, 5000); GetDeviceRegSettingKey(SystemWakeEnabled, FALSE); status = STATUS_SUCCESS; Done: if (hKey) { WdfRegistryClose(hKey); hKey = NULL; } 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; }
_Use_decl_annotations_ NTSTATUS GetSimBattStateFromRegistry ( WDFDEVICE Device, PSIMBATT_STATE State ) /* Routine Description: Called to return simbatt state data from the registry if it exists. Arguments: Device - Supplies WDF device handle. State - Supplies the pointer to return the simbatt state. Return Value: NTSTATUS --*/ { ULONG BufSize; WDFKEY KeyHandle; DECLARE_CONST_UNICODE_STRING(SimbattStateRegNameStr, SIMBATT_STATE_REG_NAME); NTSTATUS Status; ULONG ValueType; PAGED_CODE(); Status = WdfDeviceOpenRegistryKey( Device, PLUGPLAY_REGKEY_DEVICE, KEY_READ, NULL, &KeyHandle ); if (!NT_SUCCESS (Status)) { goto GetSimBattStateFromRegistryEnd; } Status = WdfRegistryQueryValue( KeyHandle, &SimbattStateRegNameStr, sizeof(SIMBATT_STATE), State, &BufSize, &ValueType ); WdfRegistryClose(KeyHandle); if (!NT_SUCCESS (Status)) { goto GetSimBattStateFromRegistryEnd; } if (ValueType != REG_BINARY) { Status = STATUS_INVALID_INFO_CLASS; goto GetSimBattStateFromRegistryEnd; } if (BufSize != sizeof(SIMBATT_STATE)) { // // WdfRegistryQueryValue will fail if the buffer was too small. // This check is validating if the data is smaller than the buffer. // Status = STATUS_INFO_LENGTH_MISMATCH; goto GetSimBattStateFromRegistryEnd; } if (State->Version != SIMBATT_STATE_VERSION) { Status = STATUS_REVISION_MISMATCH; goto GetSimBattStateFromRegistryEnd; } GetSimBattStateFromRegistryEnd: return Status; }
NTSTATUS FmCreateDosDevicesSymbolicLink( WDFDEVICE Device, PFM_DEVICE_DATA FmDeviceData ) { NTSTATUS status; UNICODE_STRING comPort; UNICODE_STRING pdoName; UNICODE_STRING symbolicLink; WDFKEY hKey = NULL; DECLARE_CONST_UNICODE_STRING(valueName, L"PortName"); WDFSTRING string = NULL; WDFMEMORY memory; WDF_OBJECT_ATTRIBUTES memoryAttributes; size_t bufferLength; PAGED_CODE(); symbolicLink.Buffer = NULL; // // Open the device registry and read the "PortName" value written by the // class installer. // status = WdfDeviceOpenRegistryKey(Device, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_ALL, NULL, // PWDF_OBJECT_ATTRIBUTES &hKey); if (!NT_SUCCESS (status)) { goto Error; } status = WdfStringCreate( NULL, WDF_NO_OBJECT_ATTRIBUTES , &string ); if (!NT_SUCCESS(status)) { goto Error; } // // Retrieve the value of ValueName from registry // status = WdfRegistryQueryString( hKey, &valueName, string ); if (!NT_SUCCESS (status)) { goto Error; } // // Retrieve the UNICODE_STRING from string object // WdfStringGetUnicodeString( string, &comPort ); WdfRegistryClose(hKey); hKey = NULL; symbolicLink.Length=0; symbolicLink.MaximumLength = sizeof(OBJECT_DIRECTORY) + comPort.MaximumLength; symbolicLink.Buffer = ExAllocatePoolWithTag(PagedPool, symbolicLink.MaximumLength + sizeof(WCHAR), 'wkaF'); if (symbolicLink.Buffer == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; goto Error; } RtlZeroMemory(symbolicLink.Buffer, symbolicLink.MaximumLength); RtlAppendUnicodeToString(&symbolicLink, OBJECT_DIRECTORY); RtlAppendUnicodeStringToString(&symbolicLink, &comPort); // // This DDI will get the underlying PDO name and create a symbolic to that // because our FDO doesn't have a name. // status = WdfDeviceCreateSymbolicLink(Device, &symbolicLink); if (!NT_SUCCESS(status)) { goto Error; } WDF_OBJECT_ATTRIBUTES_INIT(&memoryAttributes); memoryAttributes.ParentObject = Device; status = WdfDeviceAllocAndQueryProperty(Device, DevicePropertyPhysicalDeviceObjectName, PagedPool, &memoryAttributes, &memory); if (!NT_SUCCESS(status)) { // // We expect a zero length buffer. Anything else is fatal. // goto Error; } pdoName.Buffer = WdfMemoryGetBuffer(memory, &bufferLength); if (pdoName.Buffer == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; goto Error; } pdoName.MaximumLength = (USHORT) bufferLength; pdoName.Length = (USHORT) bufferLength - sizeof(UNICODE_NULL); status = RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP, L"SERIALCOMM", pdoName.Buffer, REG_SZ, comPort.Buffer, comPort.Length); if (!NT_SUCCESS(status)) { goto Error; } FmDeviceData->Flags |= REG_VALUE_CREATED_FLAG; // // Store it so it can be deleted later. // FmDeviceData->PdoName = pdoName; Error: if (symbolicLink.Buffer != NULL) { ExFreePool(symbolicLink.Buffer); } if (hKey != NULL) { WdfRegistryClose(hKey); } if (string != NULL) { WdfObjectDelete(string); } return status; }