2008年9月5日星期五

RtlRegFunctions

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", ¶mTable[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;
}

没有评论: