• 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"));
    }
  • 相关阅读:
    第八周作业。
    作业。
    第七周作业。
    作业。
    Android简易计算器
    Android第四周
    java6.12
    java5.29
    java5.28
    java5.22
  • 原文地址:https://www.cnblogs.com/qintangtao/p/3083825.html
Copyright © 2020-2023  润新知