Windows内核编程之:注册表操作

注册表项:注册表中的一个项目,类似于目录的概念
注册表子项:类似于目录中的子目录
键名:通过键名可以寻找到相应的键值
键值类别:每个键值存储的时候有不同的类别,可以是整形,字符串等数据
键值:键名下对应存储的数据

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"));

}

 

 

你可能感兴趣的:(windows)