注册表项:注册表中的一个项目,类似于目录的概念
注册表子项:类似于目录中的子目录
键名:通过键名可以寻找到相应的键值
键值类别:每个键值存储的时候有不同的类别,可以是整形,字符串等数据
键值:键名下对应存储的数据
1、创建关闭注册表
/************************************************************************ * 函数名称:ZwCreateKey * 功能描述:打开注册表句柄 * 参数列表: KeyHandle:获得的注册表句柄 DesiredAccess:访问权限,一般设置为KEY_ALL_ACCESS ObjectAttributes:OBJECT_ATTRIBUTES数据结构 TitleIndex:很少用到,一般设置为0 Class:很少用到,一般设置为NULL CreateOptions:创建时的选项,一般设置为REG_OPTION_NON_VOLATILE Disposition:返回时创建成功,还是打开成功。返回值是REG_CREATED_NEW_KEY 或者REG_OPENED_EXISTING_KEY * 返回值: *************************************************************************/ NTSTATUS ZwCreateKey( OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG TitleIndex, IN PUNICODE_STRING Class OPTIONAL, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL); /* *注意: * 如果ZwCreateKey指定的项目不存在,则直接创建这个项目 * 并利用Disposition参数返回REG_CREATED_NEW_KEY * 如果项目已经存在了,Disposition参数返回REG_OPENED_EXISTING_KEY */
演示如何使用ZwCreateKey函数打开注册表
//创建或打开某个注册表项目 UNICODE_STRING RegUnicodeString; HANDLE hRegister; #define MY_REG_SOFTWARE_KEY_NAME L"\\Registry\\Machine\\Software\\Itao" //初始化UNICODE_STRING字符串 RtlInitUnicodeString(&RegUnicodeString, MY_REG_SOFTWARE_KEY_NAME); OBJECT_ATTRIBUTES objectAttributes; //初始化objectAttributes InitializeObjectAttributes(&objectAttributes, &RegUnicodeString, OBJ_CASE_INSENSITIVE, //对大小写敏感 NULL, NULL); ULONG ulResult; //创建或打开注册表项目 NTSTATUS ntStatus = ZwCreateKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &ulResult); if( NT_SUCCESS(ntStatus) ) { //判断是被新创建,还是已经被创建 if(ulResult == REG_CREATED_NEW_KEY) { KdPrint(("The register item is created\n")); } else if(ulResult == REG_OPENED_EXISTING_KEY) { KdPrint(("The register item has been created, and now is opened\n")); } } //创建或打开某注册表项目的子项 UNICODE_STRING subRegUnicodeString; HANDLE hSubRegister; //初始化UNICODE_STRING字符串 RtlInitUnicodeString(&subRegUnicodeString, L"SubItem"); OBJECT_ATTRIBUTES subObjectAttributes; //初始化objectAttributes InitializeObjectAttributes(&subObjectAttributes, &subRegUnicodeString, OBJ_CASE_INSENSITIVE, //对大小写敏感 hRegister, NULL); //创建或打开注册表项目 NTSTATUS ntStatus = ZwCreateKey(&hSubRegister, KEY_ALL_ACCESS, &subObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &ulResult); if( NT_SUCCESS(ntStatus) ) { //判断是被新创建,还是已经被创建 if(ulResult == REG_CREATED_NEW_KEY) { KdPrint(("The register item is created\n")); } else if(ulResult == REG_OPENED_EXISTING_KEY) { KdPrint(("The register item has been created, and now is opened\n")); } } //关闭注册表句柄 ZwClose(hRegister); ZwClose(hSubhRegister);
2、打开注册表
/************************************************************************ * 函数名称:ZwOpenKey * 功能描述:打开注册表 * 参数列表: KeyHandle:返回被打开的句柄 DesiredAccess:打开的权限,一般设为KEY_ALL_ACCESS ObjectAttributes:OBJECT_ATTRIBUTES 数据结构,指示打开的状态 * 返回 值:返回是否打开成功 *************************************************************************/ NTSTATUS ZwOpenKey( OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes); /* *注意: * 如果ZwOpenKey指定的项不存在,不会创建这个项目 * 而是返回一个错误状态 */
演示如何使用ZwOpenKey打开注册表项目
#define MY_REG_SOFTWARE_KEY_NAME L"\\Registry\\Machine\\Software\\Itao" UNICODE_STRING RegUnicodeString; HANDLE hRegister; //初始化UNICODE_STRING字符串 RtlInitUnicodeString(&RegUnicodeString, MY_REG_SOFTWARE_KEY_NAME); OBJECT_ATTRIBUTES objectAttributes; //初始化objectAttributes InitializeObjectAttributes(&objectAttributes, &RegUnicodeString, OBJ_CASE_INSENSITIVE, //对大小写敏感 NULL, NULL); //打开注册表 NTSTATUS ntStatus = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes); //判断操作是否成功 if( NT_SUCCESS(ntStatus) ) { KdPrint(("Open register successfully\n")); } //关闭句柄 ZwClose(hRegister);
3、添加、修改注册表键值
键值的分类
分类 描述
REG_BINARY 键值用二进制存储
REG_SZ 键值用宽字符串,字符串以\0的结尾
REG_EXPAND_SZ 键值用宽字符串,字符串以\0的结尾,该字符串是扩展的字符
REG_MULTI_SZ 键值存储多个字符串,每个字符串以\0隔开
REG_DWORD 键值用4字节整形存储
REG_QWORD 键值用8字节存储
/************************************************************************ * 函数名称:ZwSetValueKey * 功能描述:在添加和修改注册表键值的时候,要分类进行添加和修改 * 参数列表: KeyHandle:注册表句柄 ValueName:要新建或者修改的键名 TitleIndex:很少用,一般设为0 Type:在表中选择一种类型 Data:键值数据 DataSize:记录键值数据的大小 * 返回 值:返回新建或者修改的结果 *************************************************************************/ NTSTATUS ZwSetValueKey( IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN ULONG TitleIndex OPTIONAL, IN ULONG Type, IN PVOID Data, IN ULONG DataSize); /* *注意: * 使用ZwSetValueKey函数的时候, * 如果指定的键名不存在,则直接创建。 * 如果指定的键名已存在,则对已有键值进行修改 */
演示如何修改和设置键值
#define MY_REG_SOFTWARE_KEY_NAME L"\\Registry\\Machine\\Software\\Itao" UNICODE_STRING RegUnicodeString; HANDLE hRegister; //初始化UNICODE_STRING字符串 RtlInitUnicodeString(&RegUnicodeString, MY_REG_SOFTWARE_KEY_NAME); OBJECT_ATTRIBUTES objectAttributes; //初始化objectAttributes InitializeObjectAttributes(&objectAttributes, &RegUnicodeString, OBJ_CASE_INSENSITIVE, //对大小写敏感 NULL, NULL); //打开注册表 NTSTATUS ntStatus = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes); //判断操作是否成功 if( NT_SUCCESS(ntStatus) ) { KdPrint(("Open register successfully\n")); } UNICODE_STRING ValueName; //初始化ValueName RtlInitUnicodeString(&ValueName, L"REG_DWORD value"); //设置REG_DWORD 子键 ULONG ulValue = 1000; ZwSetValueKey( hRegister, &ValueName, 0, REG_DWORD, &ulValue, sizeof(ulValue)); //初始化ValueName RtlInitUnicodeString(&ValueName, L"REG_SZ value"); WCHAR* strValue = L"hello world"; //设置REG_SZ 子键 ZwSetValueKey( hRegister, &ValueName, 0, REG_SZ, &strValue, wcslen(strValue) * 2 + 2); //初始化ValueName RtlInitUnicodeString(&ValueName, L"REG_BINARY value"); UCHAR buffer[10]; RtlFillMemory(buffer, sizeof(buffer), 0XFF); //设置REG_BINARY 子键 ZwSetValueKey( hRegister, &ValueName, 0, REG_BINARY, buffer, sizeof(buffer)); //关闭句柄 ZwClose(hRegister);
4、查询注册表
/************************************************************************ * 函数名称:ZwQueryValueKey * 功能描述:对注册表的项进行查询,从而获取注册表的键值 * 参数列表: KeyHandle:打开的注册表句柄 ValueName:要查询的键名 KeyValueInformationClass:根据KeyValueInformation的不同选择不同的查询类别 KeyValueInformation:选择一种查询类别 KeyValueBasicInformation:查询基本信息 KeyValueFullformation:查询全部信息 KeyValuePartialInformation:查询部分信息 每种查询类型会有对应的一种数据结构获得查询结果 Length:要查数据的长度 ResultLength:实际查询数据的长度 * 返回值:表示查询数据是否成功 *************************************************************************/ NTSTATUS ZwQueryValueKey( IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, OUT PVOID KeyValueInformation, IN ULONG Length, OUT PULONG ResultLength);
/************************************************************************ *1、KeyValuePartialInformation可以查询键值的数据, * 它对应的查询数据结构是KEY_VALUE_PARTIAL_INFORMATION *************************************************************************/ typedef struct KEY_VALUE_PARTIAL_INFORMATION{ ULONG TitleIndex; ULONG Type;//数据的类型,查询键值的分类 ULONG DataLength;//数据的长度 UCHAR Data[1]; //数据指针,这里是变长的数据 }KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION; /* *注意:KEY_VALUE_PARTIAL_INFORMATION的数据结构长度不固定 * 所以首先要确定这个长度 * 一般使用ZwQueryValueKey分为4个步骤: *1、用ZwQueryValueKey获取这个数据结构的长度 *2、分配入册长度的内存,用来查询 *3、再次调用ZwQueryValueKey,获取键值 *4、回收内存 */
查询注册表的示例代码
#define MY_REG_SOFTWARE_KEY_NAME L"\\Registry\\Machine\\Software\\Itao" UNICODE_STRING RegUnicodeString; HANDLE hRegister; //初始化UNICODE_STRING字符串 RtlInitUnicodeString(&RegUnicodeString, MY_REG_SOFTWARE_KEY_NAME); OBJECT_ATTRIBUTES objectAttributes; //初始化objectAttributes InitializeObjectAttributes(&objectAttributes, &RegUnicodeString, OBJ_CASE-INSENSITIVE, //对大小写敏感 NULL, NULL); //打开注册表 NTSTATUS ntStatus = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes); if(NT_SUCCESS(ntStatus)) { KdPrint(("Open register successfully\n")); } UNICODE_STRING ValueName; //初始化ValueName RtlInitUnicodeString(&ValueName, L"REG_DWORD value"); //读取REG_DWORD子键 ULONG ulSize; ntStatus = ZwQueryValueKey(hRegister, &ValueName, KeyValuePartialInformation, NULL, 0, &ulSize); if(ntStatus == STATUS_OBJECT_NAME_NOT_FOUND || ulSize == 0) { ZwClose(hRegister); KdPrint("The item is not exist\n"); return; } PKEY_VALUE_PARTIAL_INFORMATION pvpi = (PKEY_VALUE_PARTIAL_INFORMATION) ExAllocatePool(PagedPool, ulSize); //查询注册表 ntStatus = ZwQueryValueKey(hRegister, &ValueName, KeyValuePartialInformation, pvpi, ulSize, &ulSize); if(!NT_SUCCESS(ntStatus)) { ZwClose(hRegister); KdPrint(("Read register ERROR\n")); return; } //判断是否REG_DWORD类型 if(pvpi->Type == REG_DWORD && pvpi->DataLength == sizeof(ULONG)) { PULONG pulValue = (PULONG)pvpi->Data; KdPrint(("The value:%d\n", *pulValue)); } ExFreePool(pvpi); //初始化ValueName RtlInitUnicodeString(&ValueName, L"REG_SZ value"); //读取REG_SZ子键 ntStatus = ZwQueryValueKey(hRegister, &ValueName, KeyValuePartialInformation, NULL, 0, &ulSize); if(ntStatus == STATUS_OBJECT_NAME_NOT_FOUND || ulSize == 0) { ZwClose(hRegister); KdPrint("The item is not exist\n"); return; } pvpi = (PKEY_VALUE_PARTIAL_INFORMATION) ExAllocatePool(PagedPool, ulSize); //查询注册表 ntStatus = ZwQueryValueKey(hRegister, &ValueName, KeyValuePartialInformation, pvpi, ulSize, &ulSize); if(!NT_SUCCESS(ntStatus)) { ZwClose(hRegister); KdPrint(("Read register ERROR\n")); return; } if(pvpi->Type == REG_SZ) { KdPrint(("The value:%S\n", pvpi->Data)); } //关闭句柄 ZwClose(hRegister);
5、枚举子项
/************************************************************************ * 函数名称:ZwQueryKey * 功能描述:获得某注册表项究竟有多少个子项 * 参数列表: KeyHandle:获得的注册表句柄 KeyInformationClass:查询的类别,一般选择KeyFullInformation KeyInformation:查询的数据指针。 如果KeyInformationClass是KeyFullInformation 则该指针指向一个KEY_FULL_INFORMATION的数据结构 Length:数据长度 ResultLength:返回的数据长度 * 返回值:查询是否成功 *************************************************************************/ NTSTATUS ZwQueryKey( IN HANDLE KeyHandle, IN KEY_INFORMATION_CLASS KeyInformationClass, OUT PVOID KeyInformation, IN ULONG Length, OUT PULONG ResultLength ); /* *备注: * 1、使用ZwQueryKey时,可以将参数KeyInformationClass指定为KeyFullInformation * 这样参数KeyInformation就对应一个KEY_FULL_INFORMATION数据结构,该数据结构中的 * SubKeys指明了项中有多少个子项 * 2、KEY_FULL_INFORMATION数据结构的大小是变长的,所有要调用两次ZwQueryKey。 * 第一次获取KEY_FULL_INFORMATION数据的长度,第二次真正获取KEY_FULL_INFORMATION * 数据 */
/************************************************************************ * 函数名称:ZwEnumerateKey * 功能描述:针对第几个子项获取该子项的具体信息 * 参数列表: KeyHandle:获得的注册表句柄 Index:很好用到,一般为0 KeyInformationClass:查询的类别,一般选择KeyFullInformation KeyInformation:该子项的信息 Length:子项信息的长度 ResultLength:返回子键信息的长度 * 返回值:查询是否成功 *************************************************************************/ NTSTATUS ZwEnumerateKey( IN HANDLE KeyHandle, IN ULONG Index, IN KEY_INFORMATION_CLASS KeyInformationClass, OUT PVOID KeyInformation, IN ULONG Length, OUT PULONG ResultLength ); /* *备注: * 1、使用ZwEnumerateKey时,可以将参数KeyInformationClass指定为 * KeybasicInformation * 这样参数KeyInformation就对应一个KEY_BASIC_INFORMATION数据结构 * 2、KEY_BASIC_INFORMATION数据结构的大小是变长的,所有要调用两次 * ZwEnumerateKey。第一次获取KEY_BASIC_INFORMATION数据的长度,第二 * 次真正获取KEY_BASIC_INFORMATION数据 */
如何枚举子项
#define MY_REG_SOFTWARE_KEY_NAME L"\\Registry\\Machine\\Software\\Itao" UNICODE_STRING RegUnicodeString; HANDLE hRegister; //初始化UNICODE_STRING字符串 RtlInitUnicodeString(&RegUnicodeString, MY_REG_SOFTWARE_KEY_NAME); OBJECT_ATTRIBUTES objectAttributes; //初始化objectAttributes InitializeObjectAttributes(&objectAttributes, &RegUnicodeString, OBJ_CASE_INSENSITIVE, //对大小写敏感 NULL, NULL); //打开注册表 NTSTATUS ntStatus = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes); if(NT_SUCCESS(ntStatus)) { KdPrint(("Open register successfully\n")); } ULONG ulSize; //第一次调用ZwQueryKey,为了获取KEY_FULL_INFORMATION数据的长度 ZwQueryKey(hRegister, KeyFullInformation, NULL, 0, &ulSize); PKEY_FULL_INFORMATION pfi = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool, ulSize); //第二次调用ZwQueryKey,为了获取KEY_FULL_INFORMATION数据 ZwQueryKey(hRegister, KeyFullInformation, pfi, ulSize, &ulSize); for(ULONG i = 0; I < pfi->SubKeys; i++) { //第一次调用ZwEnumerateKey,为了获取KEY_BASIC_INFORMATION数据的长度 ZwEnumerateKey(hRegister, i, KeyBasicInformation, NULL, 0, &ulSize); PKEY_BASIC_INFORMATION pbi = (PKEY_BASIC_INFORMATION)ExAllocatePool(PagedPool, ulSize); //第二次调用ZwEnumerateKey,为了获取KEY_BASIC_INFORMATION数据 ZwEnumerateKey(hRegister, i, KeyBasicInformation, pbi, ulSize, &ulSize); UNICODE_STRING uniKeyName; uniKeyName.Length = uniKeyName.MaximumLength = (USHORT)pbi->NameLength; uniKeyName.Buffer = pbi->Name; KdPrint(("The %d sub item name:%wZ\n", i, &uniKeyName)); //回收内存 ExFreePool(pbi); } //回收内存 ExFreePool(pfi); //关闭句柄 ZwClose(hRegister);
6、枚举子键
/* *备注: * 1、枚举子键是通过ZwQueryKey和ZwEnumerateValueKey * 两个函数的配合完成的 * 2、ZwEnumerateValueKey函数的使用和ZwEnumerateKey * 函数的使用类似 */
演示枚举子键
#define MY_REG_SOFTWARE_KEY_NAME L"\\Registry\\Machine\\Software\\Itao" UNICODE_STRING RegUnicodeString; HANDLE hRegister; //初始化UNICODE_STRING字符串 RtlInitUnicodeString(&RegUnicodeString, MY_REG_SOFTWARE_KEY_NAME); OBJECT_ATTRIBUTES objectAttributes; //初始化objectAttributes InitializeObjectAttributes(&objectAttributes, &RegUnicodeString, OBJ_CASE_INSENSITIVE, //对大小写敏感 NULL, NULL); //打开注册表 NTSTATUS ntStatus = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes); if(NT_SUCCESS(ntStatus)) { KdPrint(("Open register successfully\n")); } ULONG ulSize; //第一次调用ZwQueryKey,为了获取KEY_FULL_INFORMATION数据的长度 ZwQueryKey(hRegister, KeyFullInformation, NULL, 0, &ulSize); PKEY_FULL_INFORMATION pfi = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool, ulSize); //第二次调用ZwQueryKey,为了获取KEY_FULL_INFORMATION数据 ZwQueryKey(hRegister, KeyFullInformation, pfi, ulSize, &ulSize); for(ULONG i = 0; i < pfi->Values; i++) { //枚举注册表 ZwEnumerateValueKey(hRegister, i, KeyValueBasicInformation, NULL, 0, &ulSize); PKEY_VALUE_BASIC_INFORMATION pvbi = (PKEY_VALUE_BASIC_INFORMATION)ExAllocatePool(PagedPool, ulSize); //枚举注册表 ZwEnumerateValueKey(hRegister, i, KeyValueBasicInformation, pvbi, ulSize, &ulSize); UNICODE_STRING uniKeyName; uniKeyName.Length = uniKeyName.MaximumLength = (USHORT)pvbi->NameLength; uniKeyName->Buffer = pvbi->Name; KdPrint(("The %d sub value name:%wZ\n", i, &uniKeyName)); if(pvbi->Type == REG_SZ) KdPrint(("The Sub value type:REG_SZ\n")); else if(pvbi->Type == REG_MULTI_SZ) KdPrint(("The Sub value type:REG_MULTI_SZ\n")); else if(pvbi->Type == REG_DWORD) KdPrint(("The Sub value type:REG_DWORD\n")); else if(pvbi->Type == REG_BINARY) KdPrint(("The Sub value type:REG_BINARY\n")); //回收内存 ExFreePool(pbi); } //回收内存 ExFreePool(pfi); //关闭句柄 ZwClose(hRegister);
7、删除子项
/************************************************************************ * 函数名称:ZwDeleteKey * 功能描述:删除子项 * 参数列表: KeyHandle:打开的文件句柄 * 返回值:是否删除成功 *************************************************************************/ NTSTATUS ZwDeleteKey( IN HANDLE KeyHandle ); /* *注意: * 该函数只能删除没有子项的项目 * 如果项中还有子项,则不能删除 * 需要先将该项中的所有子项全部删除后,再删除该项 */
演示如何在驱动程序中删除子项
UNICODE_STRING RegUnicodeString; HANDLE hRegister; #define MY_REG_SOFTWARE_KEY_NAME1 L"Registry\\Machine\\Software\\Itao\\SubItem" //初始化UNICODE_STRING字符串 RtlInitUnicodeString(&RegUnicodeString, MY_REG_SOFTWARE_KEY_NAME1); OBJECT_ATTRIBUTES objectAttributes; //初始化objectAttributes InitializeObjectAttributes(&objectAttributes, &RegUnicodeString, OBJ_CASE_INSENSITIVE, //对大小写敏感 NULL, NULL); //打开注册表 NTSTATUS ntStatus = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &objectAttributes); //判断操作是否成功 if(NT_SUCCESS(ntStatus)) { KdPrint(("Open register successfully\n")); } //删除注册表键 ntStatus = ZwDeleteKey(hRegister); if(NT_SUCCESS(ntStatus)) { KdPrint(("DELETE the item successfully\n")); } else if(ntStatus == STATUS_ACCESS_DENIED) { KdPrint(("STATUS_ACCESS_DENIED\n")); } else if(ntStatus == STATUS_INVALID_HANDLE) { KdPrint(("STATUS_INVALID_HANDLE\n")); } else { KdPrint(("Maybe the item has sub item to delete\n")); } //关闭句柄 ZwClose(hRegister);
8、其他
/* * RtlXX关于注册表的操作 * 分类 描述 *RtlCreateRegistryKey 创建注册表 *RtlCheckRegistryKey 查看某注册表项是否存在 *RtlWriteRegistryValue 写注册表 *RtlDeleteRegistryValue 删除注册表的子键 */
演示如何在驱动程序中使用这些函数
//创建子项 NTSTATUS ntStatus = RtlCreateRegistryKey( RTL_REGISTRY_SERVUCES, L"HelloDDK\\Itao"); if(NT_SUCCESS(ntStatus)) { KdPrint(("Create the item successfully\n")); } //检测某项是否存在 ntStatus = RtlCheckRegistryKey( RTL_REGISTRY_SERVUCES, L"HelloDDK\\Itao"); if(NT_SUCCESS(ntStatus)) { KdPrint(("The item is exist\n")); } //写入REG_DWORD的数据 ULONG value1 = 100; ntStatus = RtlWriteRegistryValue( RTL_REGISTRY_SERVUCES, L"HelloDDK\\Itao", L"DWORD_Value", REG_DWORD, &value1, sizeof(value1)); if(NT_SUCCESS(ntStatus)) { KdPrint(("Write thw DWORD value successfully\n")); } //写注册表 PWCHAR szString = L"Hello DDK"; ntStatus = RtlWriteRegistryValue( RTL_REGISTRY_SERVUCES, L"HelloDDK\\Itao", L"SZ_Value", REG_SZ, szString, wcslen(szStrubg) * 2 + 2); if(NT_SUCCESS(ntStatus)) { KdPrint(("Write thw REG_SZ value successfully\n")); } //初始化变量 RTL_QUERY_REGISTRY_TABLE paramTable[2]; RtlZeroMemory(paramTable, sizeof(paramTable)); ULONG defaultData = 0; ULONG uQueryValue; paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; paramTable[0].Name = L"DWORD_Value"; paramTable[0].EntryContext = &uQueryValue; paramTable[0].DefaultType = REG_DWORD; paramTable[0].DefaultData = &defaultData; paramTable[0].DefaultLenth = sizeof(ULONG); //查询REG_DWORD的数据 ntStatus = RtlQueryRegistryValue( RTL_REGISTRY_SERVUCES, L"HelloDDK\\Itao", NULL, NULL); if(NT_SUCCESS(ntStatus)) { KdPrint(("Query the item successfully\n")); KdPrint(("The item is :%d\n", uQueryValue)); } //删除子键 ntStatus = RtlDeleteRegistryValue( RTL_REGISTRY_SERVUCES, L"DWORD_Value"); if(NT_SUCCESS(ntStatus)) { KdPrint(("Delete the value successfully\n")); }