구리의 창고

RtlQueryRegistryValues, RtlWriteRegistryValue, RtlDeleteRegistryValue 본문

Window Driver

RtlQueryRegistryValues, RtlWriteRegistryValue, RtlDeleteRegistryValue

구리z 2010. 3. 3. 14:00
드라이버에서 레지스트리를 읽고 쓰는 함수이다.

1、RtlQueryRegistryValues   读取所有的键值
     
    NTSTATUS status;
    NTSTATUS STATUS;
    RTL_QUERY_REGISTRY_TABLE  paramTable[2];

    RtlZeroMemory(paramTable, sizeof(paramTable));
    paramTable[0].QueryRoutine  = GetDirAndKey;
    paramTable[0].Flags         = RTL_QUERY_REGISTRY_TOPKEY;
    paramTable[0].Name          = NULL;

    STATUS = RtlQueryRegistryValues(RTL_REGISTRY_USER, L"Software\\CryptionDirectory", &paramTable[0], NULL, NULL);

    if( STATUS != STATUS_SUCCESS ) {
        KdPrint(("RtlQueryRegistryValue FAILED status=%x\n", STATUS));
    }

    NTSTATUS
    GetDirAndKey(
             IN PWSTR ValueName,
             IN ULONG ValueType,
             IN PVOID ValueData,
             IN ULONG ValueLength,
             IN PVOID Context,
             IN PVOID EntryContext
             )
    {
        UNREFERENCED_PARAMETER(ValueType);
        UNREFERENCED_PARAMETER(ValueLength);
        UNREFERENCED_PARAMETER(Context);
        UNREFERENCED_PARAMETER(EntryContext);
    
        KdPrint(("the name is :%ws, the value is :%ws", ValueName, (PWSTR)ValueData));
        return STATUS_SUCCESS;
    }
       



2、RtlWriteRegistryValue

STATUS = RtlWriteRegistryValue(RTL_REGISTRY_USER, L"Software\\CryptionDirectory", L"enc1", REG_SZ, L"PASSWORD", sizeof(L"PASSWORD"));
STATUS = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE, L"\\Registry\\Machine\\Software\\CryptionDirectory", L"enc1", REG_SZ, L"PASSWORD", sizeof(L"PASSWORD"));

3、RtlDeleteRegistryValue

STATUS = RtlDeleteRegistryValue(RTL_REGISTRY_ABSOLUTE, L"\\Registry\\Machine\\Software\\CryptionDirectory", L"enc1");

// 删除键值
NTSTATUS DeleteRegistryValue(PWSTR KeyName)
{
    return RtlDeleteRegistryValue(RTL_REGISTRY_ABSOLUTE, L"\\Registry\\Machine\\Software\\CryptionDirectory", KeyName);
}

// 更新键值
NTSTATUS UpdateRegistryValue(PWSTR KeyName, PWSTR NewValue)
{
    return RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE, L"\\Registry\\Machine\\Software\\CryptionDirectory", KeyName, REG_SZ, NewValue, wcslen(NewValue) * sizeof(WCHAR));
}
   
4、更新键名
NTSTATUS UpdateRegistryValue(PWSTR OldKey, PWSTR NewKey)
{
    NTSTATUS status;
    UNICODE_STRING KeyValue;

    UNREFERENCED_PARAMETER(NewKey);

    //UnicodeString变量是用来存放查询出的键值字符串,Buffer一开始是为NULL,在查完键值后,系统会自动填入字串的地址,并设置Length和MaximumLength的值,所以用完后要帮系统释放。否则该块内存无法释放,核心内存用完,后果不堪设想。

    RtlInitUnicodeString(&KeyValue, L"");
    KeyValue.Buffer = NULL;
    KeyValue.MaximumLength=0;
    KeyValue.Length=0;

    status = QueryRegistryValue(OldKey, &KeyValue);
    if (status != STATUS_SUCCESS)
    {
        return status;
    }

    status = RtlDeleteRegistryValue(RTL_REGISTRY_ABSOLUTE, L"\\Registry\\Machine\\Software\\CryptionDirectory", OldKey);
    if (status != STATUS_SUCCESS)
    {
        return status;
    }
    status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE, L"\\Registry\\Machine\\Software\\CryptionDirectory", NewKey, REG_SZ, KeyValue.Buffer, KeyValue.MaximumLength);

    RtlFreeUnicodeString(&KeyValue);
    return status;
}

// 读取指定的键值
NTSTATUS QueryRegistryValue(PWSTR KeyName, PUNICODE_STRING KeyValue)
{
    NTSTATUS status;
    RTL_QUERY_REGISTRY_TABLE  paramTable[2];
    // 读取Registry中的键值,必须要有一个RTL_QUERY_REGISTRY_TABLE结构的阵列,每一个要读的键值项目占一个阵列元素。最后要加一个空的阵列元素。所以如果要读取2个键值则阵列大小不应该小于3。我们这里要读一个元素,阵列大小为2,当然3、4...都可以。

    RtlZeroMemory(paramTable, sizeof(paramTable));
    paramTable[0].Flags         = RTL_QUERY_REGISTRY_DIRECT;
    paramTable[0].Name          = KeyName;
    paramTable[0].EntryContext = KeyValue;

    status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, L"\\Registry\\Machine\\Software\\CryptionDirectory", paramTable, NULL, NULL);
        
    return status;
}
Comments