在做Windows Phone驱动开发时,时常需要和注册表打交道,因此,作为手机驱动开发人员,有必要了解一下注册表相关的知识。本人目前对注册表也不怎么了解,也只是大概的知道在Windows Phone下,驱动的inf文件并不像桌面Windows那样提供驱动自动安装程序,在Windows Phone下,inf文件最终会被解析成注册表信息并添加到注册表中。我们驱动往往将一些硬件参数保存在注册表中,因此在软件编程时,自然就会涉及到注册表的读写更新操作。
本人目前在做触摸屏驱动时,就涉及到了注册表的读写操作。为了方便以后查阅,这里贴出注册表的更新UpdateRegistry()和读取ReadRegistry()函数代码。
更新注册表:
NTSTATUS __drv_requiresIRQL(PASSIVE_LEVEL) UpdateRegistry( __in WDFDEVICE FxDevice, __in PUNICODE_STRING SubkeyName, __in PUNICODE_STRING ValueName, __inout PUNICODE_STRING Value ) { NTSTATUS status; NTSTATUS RegFlushStatus; WDFKEY Key = NULL; WDFKEY Subkey = NULL; HANDLE KeyHandle; PAGED_CODE(); // // Find FileName from registry key // status = WdfDeviceOpenRegistryKey(FxDevice, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_ALL, WDF_NO_OBJECT_ATTRIBUTES, &Key); if (!NT_SUCCESS(status)) goto exit; status = WdfRegistryOpenKey(Key, SubkeyName, KEY_READ, WDF_NO_OBJECT_ATTRIBUTES, &Subkey); if (!NT_SUCCESS(status)) goto exit; status = WdfRegistryAssignUnicodeString(Subkey, ValueName, Value); if (!NT_SUCCESS(status)) goto exit; //flush the key for immediate effect KeyHandle = WdfRegistryWdmGetHandle(Subkey); if( NULL != KeyHandle) { RegFlushStatus = ZwFlushKey(KeyHandle); } exit: if (Subkey != NULL) WdfRegistryClose(Subkey); if (Key != NULL) WdfRegistryClose(Key); return status; }
读取注册表:
NTSTATUS __drv_requiresIRQL(PASSIVE_LEVEL) ReadRegistry( __in WDFDEVICE FxDevice, __in PUNICODE_STRING SubkeyName, __in PUNICODE_STRING ValueName, __inout PUNICODE_STRING Value ) { NTSTATUS Status; WDFKEY Key = NULL; WDFKEY Subkey = NULL; PAGED_CODE(); // // Find FileName from registry key // Status = WdfDeviceOpenRegistryKey(FxDevice, PLUGPLAY_REGKEY_DEVICE, KEY_READ, WDF_NO_OBJECT_ATTRIBUTES, &Key); if (!NT_SUCCESS(Status)) goto exit; Status = WdfRegistryOpenKey(Key, SubkeyName, KEY_READ, WDF_NO_OBJECT_ATTRIBUTES, &Subkey); if (!NT_SUCCESS(Status)) goto exit; // // Get String // Status = WdfRegistryQueryUnicodeString(Subkey, ValueName, NULL, Value); if (!NT_SUCCESS(Status)) goto exit; exit: if (Subkey != NULL) WdfRegistryClose(Subkey); if (Key != NULL) WdfRegistryClose(Key); return Status; }
函数使用案例
inf文件:
; ; TouchDetectionDriver.inf ; ... [TouchDetectionDriver_Device.NT.HW] AddReg = FilterInst.NT.HW.AddReg [FilterInst.NT.HW.AddReg] HKR,%QtTouchRegPath%,"TouchControllerID",0x00000002,"FF" HKR,%QtTouchRegPath%,"ForceControllerProbe",0x00000002,"1" ... [Strings] QtTouchRegPath = "Configuration File" ...该inf文件最终会被解析成注册表信息,并在添加到系统注册表中。可以看到,在子键Configuration File目录下,存在两个entry,它们分别为TouchControllerID和ForceControllerProbe,键值分别为"FF"和"1"。
驱动文件:
NTSTATUS RegistryTest(WDFDEVICE FxDevice) { NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING strControllerID; ULONG TouchControllerID = 0; WCHAR szIDBuffer[3] = {0}; UNICODE_STRING strForceProbe; ULONG ForceControllerProbe = 0; WCHAR szProbeBuffer[3] = {0}; DECLARE_CONST_UNICODE_STRING(SubkeyName, L"Configuration File"); DECLARE_CONST_UNICODE_STRING(KeyTouchControllerID, L"TouchControllerID"); DECLARE_CONST_UNICODE_STRING(KeyForceControllerProbeID, L"ForceControllerProbe"); //Read TouchControllerID RtlInitEmptyUnicodeString(&strControllerID, szIDBuffer, sizeof(szIDBuffer)); ReadRegistry(FxDevice,(PUNICODE_STRING)&SubkeyName,(PUNICODE_STRING)&KeyTouchControllerID,&strControllerID); RtlUnicodeStringToInteger(&strControllerID, 10, (PULONG)&TouchControllerID); TDDLog("TDD:ControllerIDFromRegistry:ControllerID Registry Value is %d\n", TouchControllerID); //Read ForceControllerProbe RtlInitEmptyUnicodeString(&strForceProbe, szProbeBuffer, sizeof(szProbeBuffer)); ReadRegistry(FxDevice,(PUNICODE_STRING)&SubkeyName,(PUNICODE_STRING)&KeyForceControllerProbeID, &strForceProbe); RtlUnicodeStringToInteger(&strForceProbe, 10, (PULONG)&ForceControllerProbe); TDDLog("TDD:ControllerIDFromRegistry:Force controller probe Register Value is %d\n", ForceControllerProbe); //Update TouchControllerID RtlIntegerToUnicodeString(1, 10, &strControllerID); UpdateRegistry(FxDevice, (PUNICODE_STRING)&SubkeyName, (PUNICODE_STRING)&KeyTouchControllerID, &strControllerID); //Update ForceControllerProbe RtlIntegerToUnicodeString(0, 10, &strForceProbe); UpdateRegistry(FxDevice, (PUNICODE_STRING)&SubkeyName, (PUNICODE_STRING)&KeyForceControllerProbeID, &strForceProbe); return status; }