在做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;
}