⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reg.c

📁 Vitual Ring Routing 管你知不知道
💻 C
字号:
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
//
// (c) Microsoft Corporation. All rights reserved. 
//
// This file is part of the Microsoft Virtual Ring Routing distribution.
// You should have received a copy of the Microsoft Research Shared Source
// license agreement (MSR-SSLA) for this software; see the file "license.txt".
// If not, please see http://research.microsoft.com/vrr/license.htm,
// or write to Microsoft Research, One Microsoft Way, Redmond, WA 98052-6399.
//
// This file is derived from the Microsoft Research Mesh Connectivity Layer,
// available under the MSR-SSLA license, and downloadable from
// http://research.microsoft.com/mesh/.
//

#include "headers.h"
#include <string.h>
#include <wchar.h>

#define WORK_BUFFER_SIZE  512

//* OpenRegKey
//
//  Opens a Registry key and returns a handle to it.
//
//  Returns (plus other failure codes):
//      STATUS_OBJECT_NAME_NOT_FOUND
//      STATUS_SUCCESS
//
NTSTATUS
OpenRegKey(
    PHANDLE HandlePtr,  // Where to write the opened handle.
    HANDLE Parent,
    const WCHAR *KeyName,     // Name of Registry key to open.
    OpenRegKeyAction Action)
{
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING UKeyName;

    PAGED_CODE();

    RtlInitUnicodeString(&UKeyName, KeyName);

    memset(&ObjectAttributes, 0, sizeof(OBJECT_ATTRIBUTES));
    InitializeObjectAttributes(&ObjectAttributes, &UKeyName,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               Parent, NULL);

    switch (Action) {
    case OpenRegKeyRead:
        Status = ZwOpenKey(HandlePtr, KEY_READ, &ObjectAttributes);
        break;

    case OpenRegKeyCreate:
        Status = ZwCreateKey(HandlePtr, KEY_WRITE, &ObjectAttributes,
                             0,         // TitleIndex
                             NULL,      // Class
                             REG_OPTION_NON_VOLATILE,
                             NULL);     // Disposition
        break;

    case OpenRegKeyDeleting:
        Status = ZwOpenKey(HandlePtr, KEY_ALL_ACCESS, &ObjectAttributes);
        break;

    default:
        VRRASSERT(!"bad Action");
        Status = STATUS_INVALID_PARAMETER;
        break;
    }

    return Status;
}

//* GetRegDWORDValue
//
//  Reads a REG_DWORD value from the registry into the supplied variable.
//
NTSTATUS  // Returns: STATUS_SUCCESS or an appropriate failure code.
GetRegDWORDValue(
    HANDLE KeyHandle,  // Open handle to the parent key of the value to read.
    const WCHAR *ValueName,  // Name of the value to read.
    PULONG ValueData)  // Variable into which to read the data.
{
    NTSTATUS status;
    ULONG resultLength;
    PKEY_VALUE_FULL_INFORMATION keyValueFullInformation;
    UCHAR keybuf[WORK_BUFFER_SIZE];
    UNICODE_STRING UValueName;

    PAGED_CODE();

    RtlInitUnicodeString(&UValueName, ValueName);

    keyValueFullInformation = (PKEY_VALUE_FULL_INFORMATION)keybuf;
    RtlZeroMemory(keyValueFullInformation, sizeof(*keyValueFullInformation));

    status = ZwQueryValueKey(KeyHandle, &UValueName, KeyValueFullInformation,
                             keyValueFullInformation, WORK_BUFFER_SIZE,
                             &resultLength);

    if (NT_SUCCESS(status)) {
        if (keyValueFullInformation->Type != REG_DWORD) {
            status = STATUS_INVALID_PARAMETER_MIX;
        } else {
            *ValueData = *((ULONG UNALIGNED *)
                           ((PCHAR)keyValueFullInformation +
                            keyValueFullInformation->DataOffset));
        }
    }

    return status;
}

//* SetRegDWORDValue
//
//  Writes the contents of a variable to a REG_DWORD value.
//
NTSTATUS  // Returns: STATUS_SUCCESS or an appropriate failure code.
SetRegDWORDValue(
    HANDLE KeyHandle,  // Open handle to the parent key of the value to write.
    const WCHAR *ValueName,  // Name of the value to write.
    ULONG ValueData)  // Variable from which to write the data.
{
    NTSTATUS status;
    UNICODE_STRING UValueName;

    PAGED_CODE();

    RtlInitUnicodeString(&UValueName, ValueName);

    status = ZwSetValueKey(KeyHandle, &UValueName, 0, REG_DWORD,
                           &ValueData, sizeof ValueData);

    return status;
}

//* GetRegStringValue
//
//  Reads a REG_*_SZ string value from the Registry into the supplied
//  key value buffer.  If the buffer string buffer is not large enough,
//  it is reallocated.
//
NTSTATUS  // Returns: STATUS_SUCCESS or an appropriate failure code.
GetRegStringValue(
    HANDLE KeyHandle,   // Open handle to the parent key of the value to read.
    const WCHAR *ValueName,   // Name of the value to read.
    PKEY_VALUE_PARTIAL_INFORMATION *ValueData,  // Destination of read data.
    PUSHORT ValueSize)  // Size of the ValueData buffer.  Updated on output.
{
    NTSTATUS status;
    ULONG resultLength;
    UNICODE_STRING UValueName;

    PAGED_CODE();

    RtlInitUnicodeString(&UValueName, ValueName);

    status = ZwQueryValueKey(KeyHandle, &UValueName,
                             KeyValuePartialInformation, *ValueData,
                             (ULONG) *ValueSize, &resultLength);

    if ((status == STATUS_BUFFER_OVERFLOW) ||
        (status == STATUS_BUFFER_TOO_SMALL)) {
        PVOID temp;

        //
        // Free the old buffer and allocate a new one of the
        // appropriate size.
        //

        VRRASSERT(resultLength > (ULONG) *ValueSize);

        if (resultLength <= 0xFFFF) {

            temp = ExAllocatePool(NonPagedPool, resultLength);

            if (temp != NULL) {

                if (*ValueData != NULL) {
                    ExFreePool(*ValueData);
                }

                *ValueData = temp;
                *ValueSize = (USHORT) resultLength;

                status = ZwQueryValueKey(KeyHandle, &UValueName,
                                         KeyValuePartialInformation,
                                         *ValueData, *ValueSize,
                                         &resultLength);

                VRRASSERT((status != STATUS_BUFFER_OVERFLOW) &&
                       (status != STATUS_BUFFER_TOO_SMALL));
            } else {
                status = STATUS_INSUFFICIENT_RESOURCES;
            }
        } else {
            status = STATUS_BUFFER_TOO_SMALL;
        }
    }

    return status;
}

//* GetRegSZValue
//
//  Reads a REG_SZ string value from the Registry as a Unicode string,
//  allocating the string buffer.
//
//  Note that the caller must free the string buffer even
//  if this function returns a failure code.
//
NTSTATUS  // Returns: STATUS_SUCCESS or an appropriate failure code.
GetRegSZValue(
    HANDLE KeyHandle,  // Open handle to the parent key of the value to read.
    const WCHAR *ValueName,  // Name of the value to read.
    PUNICODE_STRING ValueData)  // Destination string for the value data.
{
    PKEY_VALUE_PARTIAL_INFORMATION keyValuePartialInformation;
    NTSTATUS status;

    PAGED_CODE();

    ValueData->Buffer = NULL;
    ValueData->MaximumLength = 0;
    ValueData->Length = 0;

    status = GetRegStringValue(KeyHandle, ValueName,
                               (PKEY_VALUE_PARTIAL_INFORMATION *)
                               &(ValueData->Buffer),
                               &(ValueData->MaximumLength));

    if (NT_SUCCESS(status)) {

        keyValuePartialInformation =
            (PKEY_VALUE_PARTIAL_INFORMATION)ValueData->Buffer;

        if (keyValuePartialInformation->Type == REG_SZ) {
            WCHAR *src;
            WCHAR *dst;
            ULONG dataLength;

            dataLength = keyValuePartialInformation->DataLength;
            VRRASSERT(dataLength <= ValueData->MaximumLength);

            dst = ValueData->Buffer;
            src = (PWCHAR) &(keyValuePartialInformation->Data);

            while (ValueData->Length <= dataLength) {

                if ((*dst++ = *src++) == UNICODE_NULL)
                    break;

                ValueData->Length += sizeof(WCHAR);
            }

            if (ValueData->Length < (ValueData->MaximumLength - 1)) {
                ValueData->Buffer[ValueData->Length/sizeof(WCHAR)] =
                    UNICODE_NULL;
            }
        } else {
            status = STATUS_INVALID_PARAMETER_MIX;
        }
    }

    return status;
}

//* GetVirtualAddress
//
//  Reads a VirtualAddress from a string.
//
boolint
GetVirtualAddress(const WCHAR *astr, VirtualAddress Address)
{
    uint Number;
    uint i;

    for (i = 0; ; i++) {
        if ((L'0' <= astr[0]) && (astr[0] <= L'9'))
            Number = astr[0] - L'0';
        else if ((L'a' <= astr[0]) && (astr[0] <= L'f'))
            Number = 10 + (astr[0] - L'a');
        else if ((L'A' <= astr[0]) && (astr[0] <= L'F'))
            Number = 10 + (astr[0] - L'A');
        else
            return FALSE;

        Number *= 16;

        if ((L'0' <= astr[1]) && (astr[1] <= L'9'))
            Number += astr[1] - L'0';
        else if ((L'a' <= astr[1]) && (astr[1] <= L'f'))
            Number += 10 + (astr[1] - L'a');
        else if ((L'A' <= astr[1]) && (astr[1] <= L'F'))
            Number += 10 + (astr[1] - L'A');
        else
            return FALSE;

        Address[i] = (uchar) Number;

        if (i == 5) {
            if (astr[2] != L'\0')
                return FALSE;
            break;
        }

        if (astr[2] != L'-')
            return FALSE;

        astr += 3;
    }

    return TRUE;
}

//* GetRegNetworkAddress
//
//  Reads a virtual address from the registry.
//
NTSTATUS  // Returns: STATUS_SUCCESS or an appropriate failure code.
GetRegNetworkAddress(
    HANDLE KeyHandle,  // Open handle to the parent key of the value to read.
    const WCHAR *ValueName,
    OUT VirtualAddress Address)
{
    UNICODE_STRING String;
    NTSTATUS Status;

    Status = GetRegSZValue(KeyHandle, ValueName, &String);
    if (NT_SUCCESS(Status)) {

        if (GetVirtualAddress(String.Buffer, Address))
            Status = STATUS_SUCCESS;
        else
            Status = STATUS_INVALID_PARAMETER;
    }

    if (String.Buffer != NULL)
        ExFreePool(String.Buffer);

    return Status;
}

//* SetRegNetworkAddress
//
//  Writes a network address to the registry.
//
NTSTATUS
SetRegNetworkAddress(
    HANDLE KeyHandle,  // Open handle to the parent key.
    const WCHAR *ValueName,
    IN VirtualAddress Address)
{
    UNICODE_STRING UValueName;
    WCHAR Buffer[6*3];

    RtlInitUnicodeString(&UValueName, ValueName);

    swprintf(Buffer, L"%02x-%02x-%02x-%02x-%02x-%02x",
             Address[0], Address[1], Address[2],
             Address[3], Address[4], Address[5]);

    //
    // The trailing zero is included in the value.
    //
    return ZwSetValueKey(KeyHandle, &UValueName, 0, REG_SZ,
                         Buffer, sizeof Buffer);
}

//* GetRegGuid
//
//  Reads a GUID from the registry.
//
NTSTATUS  // Returns: STATUS_SUCCESS or an appropriate failure code.
GetRegGuid(
    HANDLE KeyHandle,  // Open handle to the parent key of the value to read.
    const WCHAR *ValueName,
    OUT GUID *Guid)
{
    UNICODE_STRING String;
    NTSTATUS Status;

    Status = GetRegSZValue(KeyHandle, ValueName, &String);
    if (NT_SUCCESS(Status)) {

        Status = RtlGUIDFromString(&String, Guid);
    }

    if (String.Buffer != NULL)
        ExFreePool(String.Buffer);

    return Status;
}

//* GetRegBinaryValue
//
//  Reads a binary value from the registry into the supplied buffer.
//
NTSTATUS  // Returns: STATUS_SUCCESS or an appropriate failure code.
GetRegBinaryValue(
    HANDLE KeyHandle,  // Open handle to the parent key of the value to read.
    const WCHAR *ValueName,  // Name of the value to read.
    OUT uchar *Buffer,  // Buffer into which to read the data.
    uint Length)        // Length of the buffer.
{
    KEY_VALUE_PARTIAL_INFORMATION *Value;
    UCHAR valbuf[WORK_BUFFER_SIZE];
    UNICODE_STRING UValueName;
    ULONG ValueSize;
    NTSTATUS Status;

    PAGED_CODE();

    RtlInitUnicodeString(&UValueName, ValueName);

    Value = (KEY_VALUE_PARTIAL_INFORMATION *) valbuf;

    Status = ZwQueryValueKey(KeyHandle, &UValueName,
                             KeyValuePartialInformation,
                             Value, sizeof valbuf,
                             &ValueSize);
    if (NT_SUCCESS(Status)) {
        if ((Value->Type != REG_BINARY) ||
            (Value->DataLength != Length)) {
            Status = STATUS_INVALID_PARAMETER_MIX;
        }
        else {
            RtlCopyMemory(Buffer, Value->Data, Length);
            Status = STATUS_SUCCESS;
        }
    }

    return Status;
}

//* SetRegBinaryValue
//
//  Write a binary value into the registry from the supplied buffer.
//
NTSTATUS  // Returns: STATUS_SUCCESS or an appropriate failure code.
SetRegBinaryValue(
    HANDLE KeyHandle,  // Open handle to the parent key of the value to read.
    const WCHAR *ValueName,  // Name of the value to write.
    IN uchar *Buffer,  // Buffer from which to read the data.
    uint Length)        // Length of the buffer.
{
    UNICODE_STRING UValueName;
    NTSTATUS Status;

    PAGED_CODE();

    RtlInitUnicodeString(&UValueName, ValueName);

    Status = ZwSetValueKey(KeyHandle, &UValueName,
                           0, REG_BINARY,
                           Buffer, Length);

    return Status;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -