예제 #1
0
NTSTATUS
AnajoystReadRegistryParameterDWORD(
    PUNICODE_STRING RegistryPathName,
    PWSTR  ParameterName,
    PDWORD ParameterValue
)
/*++

Routine Description:
    This routine reads registry values for the driver configuration

Arguments:
    RegistryPathName    -  Registry path containing the desired parameters
    ParameterName       -  The name of the parameter
    ParameterValue      -  Variable to receive the parameter value

Return Value:
    STATUS_SUCCESS                      --
    STATUS_NO_MORE_ENTRIES              --  Couldn't find any entries
    STATUS_INSUFFICIENT_RESOURCES       --  Couldn't allocate paged pool
    STATUS_DEVICE_CONFIGURATION_ERROR   --  Returned value wasn't a DWORD
    or error status from NT itself

-- */
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    NTSTATUS Status;

    HANDLE ServiceKey;
    HANDLE DeviceKey;           // Key handle of service node
    UNICODE_STRING DeviceName;  // Key to parameter node
    DWORD KeyIndex;
    DWORD KeyValueLength;
    PBYTE KeyData;
    BOOL  ValueWasFound;
    PKEY_VALUE_FULL_INFORMATION KeyInfo;

    InitializeObjectAttributes( &ObjectAttributes,
                                RegistryPathName,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                (PSECURITY_DESCRIPTOR) NULL);

    //
    // Open a key for our services node entry
    //

    Status = ZwOpenKey( &ServiceKey,
                        KEY_READ | KEY_WRITE,
                        &ObjectAttributes);

    if (!NT_SUCCESS(Status))
    {
        return Status;
    }


    //
    // Open the key to our device subkey
    //

    RtlInitUnicodeString(&DeviceName, L"Parameters");

    InitializeObjectAttributes( &ObjectAttributes,
                                &DeviceName,
                                OBJ_CASE_INSENSITIVE,
                                ServiceKey,
                                (PSECURITY_DESCRIPTOR) NULL);

    Status = ZwOpenKey (&DeviceKey,
                        KEY_READ | KEY_WRITE,
                        &ObjectAttributes);


    ZwClose(ServiceKey);


    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    //
    // Loop reading our key values
    //

    // TODO exit loop when value is found?
    ValueWasFound = FALSE;

    for (KeyIndex = 0; ; KeyIndex++)
    {
        KeyValueLength = 0;

        //
        // find out how much data we will get
        //

        Status = ZwEnumerateValueKey(
                     DeviceKey,
                     KeyIndex,
                     KeyValueFullInformation,
                     NULL,
                     0,
                     &KeyValueLength);

        if (STATUS_NO_MORE_ENTRIES == Status)
        {
            break;
        }

        if (0 == KeyValueLength)
        {
            return Status;
        }

        //
        // Read the data
        //

        KeyData = ExAllocatePool (PagedPool, KeyValueLength);

        if (NULL == KeyData)
        {
            return STATUS_INSUFFICIENT_RESOURCES;
        }


        Status = ZwEnumerateValueKey(
                     DeviceKey,
                     KeyIndex,
                     KeyValueFullInformation,
                     KeyData,
                     KeyValueLength,
                     &KeyValueLength);

        if (!NT_SUCCESS(Status))
        {
            ExFreePool(KeyData);
            return Status;
        }

        KeyInfo = (PKEY_VALUE_FULL_INFORMATION) KeyData;

        if (0 == lstrnicmpW(KeyInfo->Name,
                            ParameterName,
                            KeyInfo->NameLength / sizeof(WCHAR)))
        {
            // check its a DWORD

            if (REG_DWORD != KeyInfo->Type)
            {
                ExFreePool(KeyData);
                return STATUS_DEVICE_CONFIGURATION_ERROR;
            }

            ValueWasFound = TRUE;

            *ParameterValue = *(PDWORD) (KeyData + KeyInfo->DataOffset);
        }

        ExFreePool(KeyData);

    }

    return (ValueWasFound) ? STATUS_SUCCESS : STATUS_DEVICE_CONFIGURATION_ERROR;

}
예제 #2
0
VOID EnumSubValueTest()
{
	WCHAR MY_KEY_NAME[] = L"\\Registry\\Machine\\Software\\Microsoft\\.NETFramework";
	UNICODE_STRING RegUnicodeString;
	HANDLE hRegister;
	OBJECT_ATTRIBUTES objectAttributes;
	ULONG ulSize,i;
	UNICODE_STRING uniKeyName;
	PKEY_FULL_INFORMATION pfi;
	NTSTATUS ntStatus;
	//初始化UNICODE_STRING字符串
	RtlInitUnicodeString( &RegUnicodeString, MY_KEY_NAME);
	//初始化objectAttributes
	InitializeObjectAttributes(&objectAttributes,
							&RegUnicodeString,
							OBJ_CASE_INSENSITIVE,//对大小写敏感
							NULL, 
							NULL );
	//打开注册表
	ntStatus = ZwOpenKey( &hRegister,KEY_ALL_ACCESS,&objectAttributes);
	if (NT_SUCCESS(ntStatus))
	{
		DbgPrint("Open register successfully\n");
	}
	//查询VALUE的大小
	ZwQueryKey(hRegister,KeyFullInformation,NULL,0,&ulSize);
	pfi = (PKEY_FULL_INFORMATION)	ExAllocatePool(PagedPool,ulSize);
	ZwQueryKey(hRegister,KeyFullInformation,pfi,ulSize,&ulSize);
	for (i=0;i<pfi->Values;i++)
	{
		PKEY_VALUE_BASIC_INFORMATION pvbi;
		//查询单个VALUE的大小
		ZwEnumerateValueKey(hRegister,i,KeyValueBasicInformation,NULL,0,&ulSize);
		pvbi = (PKEY_VALUE_BASIC_INFORMATION)ExAllocatePool(PagedPool,ulSize);
		//查询单个VALUE的详情
		ZwEnumerateValueKey(hRegister,i,KeyValueBasicInformation,pvbi,ulSize,&ulSize);
		uniKeyName.Length = (USHORT)pvbi->NameLength;
		uniKeyName.MaximumLength = (USHORT)pvbi->NameLength;
		uniKeyName.Buffer = pvbi->Name;
		DbgPrint("The %d sub value name:%wZ\n",i,&uniKeyName);
		if (pvbi->Type==REG_SZ)
		{
			DbgPrint("The sub value type:REG_SZ\n");
		}
		else if (pvbi->Type==REG_MULTI_SZ)
		{
			DbgPrint("The sub value type:REG_MULTI_SZ\n"); 
		}
		else if (pvbi->Type==REG_DWORD)
		{
			DbgPrint("The sub value type:REG_DWORD\n"); 
		}
		else if (pvbi->Type==REG_BINARY)
		{
			DbgPrint("The sub value type:REG_BINARY\n"); 
		}
		ExFreePool(pvbi);
	}
	ExFreePool(pfi);
	ZwClose(hRegister);
}
예제 #3
0
NTSTATUS
NTAPI
IntCopyRegistryKey(
    _In_ HANDLE SourceKeyHandle,
    _In_ HANDLE DestKeyHandle)
{
    PVOID InfoBuffer;
    PKEY_BASIC_INFORMATION KeyInformation;
    PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
    OBJECT_ATTRIBUTES ObjectAttributes;
    ULONG Index, InformationLength, RequiredLength;
    UNICODE_STRING NameString;
    NTSTATUS Status;
    HANDLE SourceSubKeyHandle, DestSubKeyHandle;

    /* Start with no buffer, set initial size */
    InfoBuffer = NULL;
    InformationLength = 256;

    /* Start looping with key index 0 */
    Index = 0;
    while (TRUE)
    {
        /* Check if we have no buffer */
        if (InfoBuffer == NULL)
        {
            /* Allocate a new buffer */
            InfoBuffer = ExAllocatePoolWithTag(PagedPool,
                                               InformationLength,
                                               TAG_VIDEO_PORT_BUFFER);
            if (InfoBuffer == NULL)
            {
                ERR_(VIDEOPRT, "Could not allocate buffer for key info\n");
                return Status;
            }
        }

        /* Enumerate the next sub-key */
        KeyInformation = InfoBuffer;
        Status = ZwEnumerateKey(SourceKeyHandle,
                                Index,
                                KeyBasicInformation,
                                KeyInformation,
                                InformationLength,
                                &RequiredLength);
        if ((Status == STATUS_BUFFER_OVERFLOW) ||
            (Status == STATUS_BUFFER_TOO_SMALL))
        {
            /* Free the buffer and remember the required size */
            ExFreePoolWithTag(InfoBuffer, TAG_VIDEO_PORT_BUFFER);
            InfoBuffer = NULL;
            InformationLength = RequiredLength;

            /* Try again */
            continue;
        }
        else if (Status == STATUS_NO_MORE_ENTRIES)
        {
            /* We are done with the sub-keys */
            break;
        }
        else if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "ZwEnumerateKey failed, status 0x%lx\n", Status);
            goto Cleanup;
        }

        /* Initialize a unicode string from the key name */
        NameString.Buffer = KeyInformation->Name;
        NameString.Length = (USHORT)KeyInformation->NameLength;
        NameString.MaximumLength = NameString.Length;

        /* Initialize object attributes and open the source sub-key */
        InitializeObjectAttributes(&ObjectAttributes,
                                   &NameString,
                                   OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                                   SourceKeyHandle,
                                   NULL);
        Status = ZwOpenKey(&SourceSubKeyHandle, KEY_READ, &ObjectAttributes);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "failed to open the source key.\n");
            goto Cleanup;
        }

        /* Initialize object attributes and create the dest sub-key */
        InitializeObjectAttributes(&ObjectAttributes,
                                   &NameString,
                                   OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                                   DestKeyHandle,
                                   NULL);
        Status = ZwCreateKey(&DestSubKeyHandle,
                             KEY_WRITE,
                             &ObjectAttributes,
                             0,
                             NULL,
                             0,
                             NULL);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "failed to create the destination key.\n");
            ObCloseHandle(SourceSubKeyHandle, KernelMode);
            goto Cleanup;
        }

        /* Recursively copy the sub-key */
        Status = IntCopyRegistryKey(SourceSubKeyHandle, DestSubKeyHandle);
        if (!NT_SUCCESS(Status))
        {
            /* Just warn, but continue with the remaining sub-keys */
            WARN_(VIDEOPRT, "failed to copy subkey '%wZ'.\n", &NameString);
        }

        /* Close the sub-key handles */
        ObCloseHandle(SourceSubKeyHandle, KernelMode);
        ObCloseHandle(DestSubKeyHandle, KernelMode);

        /* Next sub-key */
        Index++;
    }

    /* Start looping with value index 0 */
    Index = 0;
    while (TRUE)
    {
        /* Check if we have no buffer */
        if (InfoBuffer == NULL)
        {
            /* Allocate a new buffer */
            InfoBuffer = ExAllocatePoolWithTag(PagedPool,
                                               InformationLength,
                                               TAG_VIDEO_PORT_BUFFER);
            if (InfoBuffer == NULL)
            {
                ERR_(VIDEOPRT, "Could not allocate buffer for key values\n");
                return Status;
            }
        }

        /* Enumerate the next value */
        KeyValueInformation = InfoBuffer;
        Status = ZwEnumerateValueKey(SourceKeyHandle,
                                     Index,
                                     KeyValueFullInformation,
                                     KeyValueInformation,
                                     InformationLength,
                                     &RequiredLength);
        if ((Status == STATUS_BUFFER_OVERFLOW) ||
            (Status == STATUS_BUFFER_TOO_SMALL))
        {
            /* Free the buffer and remember the required size */
            ExFreePoolWithTag(InfoBuffer, TAG_VIDEO_PORT_BUFFER);
            InfoBuffer = NULL;
            InformationLength = RequiredLength;

            /* Try again */
            continue;
        }
        else if (Status == STATUS_NO_MORE_ENTRIES)
        {
            /* We are done with the values */
            Status = STATUS_SUCCESS;
            break;
        }
        else if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "ZwEnumerateValueKey failed, status 0x%lx\n", Status);
            goto Cleanup;
        }

        /* Initialize a unicode string from the value name */
        NameString.Buffer = KeyValueInformation->Name;
        NameString.Length = (USHORT)KeyValueInformation->NameLength;
        NameString.MaximumLength = NameString.Length;

        /* Create the key value in the destination key */
        Status = ZwSetValueKey(DestKeyHandle,
                               &NameString,
                               KeyValueInformation->TitleIndex,
                               KeyValueInformation->Type,
                               (PUCHAR)KeyValueInformation + KeyValueInformation->DataOffset,
                               KeyValueInformation->DataLength);
        if (!NT_SUCCESS(Status))
        {
            /* Just warn, but continue with the remaining sub-keys */
            WARN_(VIDEOPRT, "failed to set value '%wZ'.\n", NameString);
        }

        /* Next subkey */
        Index++;
    }

Cleanup:
    /* Free the buffer and return the failure code */
    if (InfoBuffer != NULL)
		ExFreePoolWithTag(InfoBuffer, TAG_VIDEO_PORT_BUFFER);
    return Status;
}
예제 #4
0
NTSTATUS
RegistryEnumerateValues(
    IN  HANDLE                      Key,
    IN  NTSTATUS                    (*Callback)(PVOID, HANDLE, PCHAR),
    IN  PVOID                       Context
    )
{
    ULONG                           Size;
    NTSTATUS                        status;
    PKEY_FULL_INFORMATION           Full;
    PKEY_VALUE_BASIC_INFORMATION    Basic;
    ULONG                           Index;

    status = ZwQueryKey(Key,
                        KeyFullInformation,
                        NULL,
                        0,
                        &Size);
    if (status != STATUS_BUFFER_OVERFLOW &&
        status != STATUS_BUFFER_TOO_SMALL)
        goto fail1;

#pragma prefast(suppress:6102)
    Full = __RegistryAllocate(Size);

    status = STATUS_NO_MEMORY;
    if (Full == NULL)
        goto fail2;

    status = ZwQueryKey(Key,
                        KeyFullInformation,
                        Full,
                        Size,
                        &Size);
    if (!NT_SUCCESS(status))
        goto fail3;

    Size = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) +
           Full->MaxValueNameLen;

    Basic = __RegistryAllocate(Size);
    status = STATUS_NO_MEMORY;
    if (Basic == NULL)
        goto fail4;

    for (Index = 0; Index < Full->Values; Index++) {
        UNICODE_STRING  Unicode;
        ANSI_STRING     Ansi;

        status = ZwEnumerateValueKey(Key,
                                     Index,
                                     KeyValueBasicInformation,
                                     Basic,
                                     Size,
                                     &Size);
        if (!NT_SUCCESS(status))
            goto fail5;

        Unicode.MaximumLength = (USHORT)Basic->NameLength;
        Unicode.Buffer = Basic->Name;
        Unicode.Length = (USHORT)Basic->NameLength;

        Ansi.MaximumLength = (USHORT)((Basic->NameLength / sizeof (WCHAR)) + sizeof (CHAR));
        Ansi.Buffer = __RegistryAllocate(Ansi.MaximumLength);

        status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE);
        ASSERT(NT_SUCCESS(status));

        Ansi.Length = (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));        

        status = Callback(Context, Key, Ansi.Buffer);

        __RegistryFree(Ansi.Buffer);

        if (!NT_SUCCESS(status))
            goto fail6;
    }

    __RegistryFree(Basic);

    __RegistryFree(Full);

    return STATUS_SUCCESS;

fail6:
fail5:
    __RegistryFree(Basic);

fail4:
fail3:
    __RegistryFree(Full);
    
fail2:
fail1:
    return status;
}
예제 #5
0
파일: init.c 프로젝트: hoangduit/reactos
NTSTATUS
NTAPI
PciBuildHackTable(IN HANDLE KeyHandle)
{
    PKEY_FULL_INFORMATION FullInfo;
    ULONG i, HackCount;
    PKEY_VALUE_FULL_INFORMATION ValueInfo;
    PPCI_HACK_ENTRY Entry;
    NTSTATUS Status;
    ULONG NameLength, ResultLength;
    ULONGLONG HackFlags;

    /* So we know what to free at the end of the body */
    FullInfo = NULL;
    ValueInfo = NULL;
    do
    {
        /* Query the size required for full key information */
        Status = ZwQueryKey(KeyHandle,
                            KeyFullInformation,
                            NULL,
                            0,
                            &ResultLength);
        if (Status != STATUS_BUFFER_TOO_SMALL) break;

        /* Allocate the space required to hold the full key information */
        Status = STATUS_INSUFFICIENT_RESOURCES;
        ASSERT(ResultLength > 0);
        FullInfo = ExAllocatePoolWithTag(PagedPool, ResultLength, PCI_POOL_TAG);
        if (!FullInfo) break;

        /* Go ahead and query the key information */
        Status = ZwQueryKey(KeyHandle,
                            KeyFullInformation,
                            FullInfo,
                            ResultLength,
                            &ResultLength);
        if (!NT_SUCCESS(Status)) break;

        /* The only piece of information that's needed is the count of values */
        HackCount = FullInfo->Values;

        /* Free the structure now */
        ExFreePoolWithTag(FullInfo, 0);
        FullInfo = NULL;

        /* Allocate the hack table, now that the number of entries is known */
        Status = STATUS_INSUFFICIENT_RESOURCES;
        ResultLength = sizeof(PCI_HACK_ENTRY) * HackCount;
        PciHackTable = ExAllocatePoolWithTag(NonPagedPool,
                                             ResultLength +
                                             sizeof(PCI_HACK_ENTRY),
                                             PCI_POOL_TAG);
        if (!PciHackTable) break;

        /* Allocate the space needed to hold the full value information */
        ValueInfo = ExAllocatePoolWithTag(NonPagedPool,
                                          sizeof(KEY_VALUE_FULL_INFORMATION) +
                                          PCI_HACK_ENTRY_FULL_SIZE,
                                          PCI_POOL_TAG);
        if (!PciHackTable) break;

        /* Loop each value in the registry */
        Entry = &PciHackTable[0];
        for (i = 0; i < HackCount; i++)
        {
            /* Get the entry for this value */
            Entry = &PciHackTable[i];

            /* Query the value in the key */
            Status = ZwEnumerateValueKey(KeyHandle,
                                         i,
                                         KeyValueFullInformation,
                                         ValueInfo,
                                         sizeof(KEY_VALUE_FULL_INFORMATION) +
                                         PCI_HACK_ENTRY_FULL_SIZE,
                                         &ResultLength);
            if (!NT_SUCCESS(Status))
            {
                /* Check why the call failed */
                if ((Status != STATUS_BUFFER_OVERFLOW) &&
                    (Status != STATUS_BUFFER_TOO_SMALL))
                {
                    /* The call failed due to an unknown error, bail out */
                    break;
                }

                /* The data seems to mismatch, try the next key in the list */
                continue;
            }

            /* Check if the value data matches what's expected */
            if ((ValueInfo->Type != REG_BINARY) ||
                (ValueInfo->DataLength != sizeof(ULONGLONG)))
            {
                /* It doesn't, try the next key in the list */
                continue;
            }

            /* Read the actual hack flags */
            HackFlags = *(PULONGLONG)((ULONG_PTR)ValueInfo +
                                      ValueInfo->DataOffset);

            /* Check what kind of errata entry this is, based on the name */
            NameLength = ValueInfo->NameLength;
            if ((NameLength != PCI_HACK_ENTRY_SIZE) &&
                (NameLength != PCI_HACK_ENTRY_REV_SIZE) &&
                (NameLength != PCI_HACK_ENTRY_SUBSYS_SIZE) &&
                (NameLength != PCI_HACK_ENTRY_FULL_SIZE))
            {
                /* It's an invalid entry, skip it */
                DPRINT1("Skipping hack entry with invalid length name\n");
                continue;
            }

            /* Initialize the entry */
            RtlZeroMemory(Entry, sizeof(PCI_HACK_ENTRY));

            /* Get the vendor and device data */
            if (!(PciStringToUSHORT(ValueInfo->Name, &Entry->VendorID)) ||
                !(PciStringToUSHORT(&ValueInfo->Name[4], &Entry->DeviceID)))
            {
                /* This failed, try the next entry */
                continue;
            }

            /* Check if the entry contains subsystem information */
            if ((NameLength == PCI_HACK_ENTRY_SUBSYS_SIZE) ||
                (NameLength == PCI_HACK_ENTRY_FULL_SIZE))
            {
                /* Get the data */
                if (!(PciStringToUSHORT(&ValueInfo->Name[8],
                                        &Entry->SubVendorID)) ||
                    !(PciStringToUSHORT(&ValueInfo->Name[12],
                                        &Entry->SubSystemID)))
                  {
                      /* This failed, try the next entry */
                      continue;
                  }

                  /* Save the fact this entry has finer controls */
                  Entry->Flags |= PCI_HACK_HAS_SUBSYSTEM_INFO;
             }

             /* Check if the entry contains revision information */
             if ((NameLength == PCI_HACK_ENTRY_REV_SIZE) ||
                 (NameLength == PCI_HACK_ENTRY_FULL_SIZE))
             {
                 /* Get the data */
                 if (!PciStringToUSHORT(&ValueInfo->Name[16],
                                        &Entry->RevisionID))
                 {
                     /* This failed, try the next entry */
                     continue;
                 }

                 /* Save the fact this entry has finer controls */
                 Entry->Flags |= PCI_HACK_HAS_REVISION_INFO;
             }

            /* Only the last entry should have this set */
            ASSERT(Entry->VendorID != PCI_INVALID_VENDORID);

            /* Save the actual hack flags */
            Entry->HackFlags = HackFlags;

            /* Print out for the debugger's sake */
#ifdef HACK_DEBUG
            DPRINT1("Adding Hack entry for Vendor:0x%04x Device:0x%04x ",
                    Entry->VendorID, Entry->DeviceID);
            if (Entry->Flags & PCI_HACK_HAS_SUBSYSTEM_INFO)
                DbgPrint("SybSys:0x%04x SubVendor:0x%04x ",
                         Entry->SubSystemID, Entry->SubVendorID);
            if (Entry->Flags & PCI_HACK_HAS_REVISION_INFO)
                DbgPrint("Revision:0x%02x", Entry->RevisionID);
            DbgPrint(" = 0x%I64x\n", Entry->HackFlags);
#endif
        }

        /* Bail out in case of failure */
        if (!NT_SUCCESS(Status)) break;

        /* Terminate the table with an invalid entry */
        ASSERT(Entry < (PciHackTable + HackCount + 1));
        Entry->VendorID = PCI_INVALID_VENDORID;

        /* Success path, free the temporary registry data */
        ExFreePoolWithTag(ValueInfo, 0);
        return STATUS_SUCCESS;
    } while (TRUE);

    /* Failure path, free temporary allocations and return failure code */
    ASSERT(!NT_SUCCESS(Status));
    if (FullInfo) ExFreePool(FullInfo);
    if (ValueInfo) ExFreePool(ValueInfo);
    if (PciHackTable) ExFreePool(PciHackTable);
    return Status;
}
예제 #6
0
NTSTATUS
SampRegEnumerateValue(IN HANDLE KeyHandle,
                      IN ULONG Index,
                      OUT LPWSTR Name,
                      IN OUT PULONG NameLength,
                      OUT PULONG Type OPTIONAL,
                      OUT PVOID Data OPTIONAL,
                      IN OUT PULONG DataLength OPTIONAL)
{
    PKEY_VALUE_FULL_INFORMATION ValueInfo = NULL;
    ULONG BufferLength = 0;
    ULONG ReturnedLength;
    NTSTATUS Status;

    TRACE("Index: %lu\n", Index);

    /* Calculate the required buffer length */
    BufferLength = FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name);
    BufferLength += (MAX_PATH + 1) * sizeof(WCHAR);
    if (Data != NULL)
        BufferLength += *DataLength;

    /* Allocate the value buffer */
    ValueInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
    if (ValueInfo == NULL)
        return STATUS_NO_MEMORY;

    /* Enumerate the value*/
    Status = ZwEnumerateValueKey(KeyHandle,
                                 Index,
                                 KeyValueFullInformation,
                                 ValueInfo,
                                 BufferLength,
                                 &ReturnedLength);
    if (NT_SUCCESS(Status))
    {
        if (Name != NULL)
        {
            /* Check if the name fits */
            if (ValueInfo->NameLength < (*NameLength * sizeof(WCHAR)))
            {
                /* Copy it */
                RtlMoveMemory(Name,
                              ValueInfo->Name,
                              ValueInfo->NameLength);

                /* Terminate the string */
                Name[ValueInfo->NameLength / sizeof(WCHAR)] = 0;
            }
            else
            {
                /* Otherwise, we ran out of buffer space */
                Status = STATUS_BUFFER_OVERFLOW;
                goto done;
            }
        }

        if (Data != NULL)
        {
            /* Check if the data fits */
            if (ValueInfo->DataLength <= *DataLength)
            {
                /* Copy it */
                RtlMoveMemory(Data,
                              (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset),
                              ValueInfo->DataLength);

                /* if the type is REG_SZ and data is not 0-terminated
                 * and there is enough space in the buffer NT appends a \0 */
                if (IsStringType(ValueInfo->Type) &&
                    ValueInfo->DataLength <= *DataLength - sizeof(WCHAR))
                {
                    WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength);
                    if ((ptr > (WCHAR *)Data) && ptr[-1])
                        *ptr = 0;
                }
            }
            else
            {
                Status = STATUS_BUFFER_OVERFLOW;
                goto done;
            }
        }
    }

done:
    if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW))
    {
        if (Type != NULL)
            *Type = ValueInfo->Type;

        if (NameLength != NULL)
            *NameLength = ValueInfo->NameLength;

        if (DataLength != NULL)
            *DataLength = ValueInfo->DataLength;
    }

    /* Free the buffer and return status */
    if (ValueInfo)
        RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);

    return Status;
}
예제 #7
0
파일: pnpres.c 프로젝트: killvxk/NT_OS
NTSTATUS NTAPI
IopDetectResourceConflict(
   IN PCM_RESOURCE_LIST ResourceList,
   IN BOOLEAN Silent,
   OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
{
   OBJECT_ATTRIBUTES ObjectAttributes;
   UNICODE_STRING KeyName;
   HANDLE ResourceMapKey = INVALID_HANDLE_VALUE, ChildKey2 = INVALID_HANDLE_VALUE, ChildKey3 = INVALID_HANDLE_VALUE;
   ULONG KeyInformationLength, RequiredLength, KeyValueInformationLength, KeyNameInformationLength;
   PKEY_BASIC_INFORMATION KeyInformation;
   PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
   PKEY_VALUE_BASIC_INFORMATION KeyNameInformation;
   ULONG ChildKeyIndex1 = 0, ChildKeyIndex2 = 0, ChildKeyIndex3 = 0;
   NTSTATUS Status;

   RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
   InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, 0, NULL);
   Status = ZwOpenKey(&ResourceMapKey, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &ObjectAttributes);
   if (!NT_SUCCESS(Status))
   {
      /* The key is missing which means we are the first device */
      return STATUS_SUCCESS;
   }

   while (TRUE)
   {
      Status = ZwEnumerateKey(ResourceMapKey,
                              ChildKeyIndex1,
                              KeyBasicInformation,
                              NULL,
                              0,
                              &RequiredLength);
      if (Status == STATUS_NO_MORE_ENTRIES)
          break;
      else if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
      {
          KeyInformationLength = RequiredLength;
          KeyInformation = ExAllocatePool(PagedPool, KeyInformationLength);
          if (!KeyInformation)
          {
              Status = STATUS_INSUFFICIENT_RESOURCES;
              goto cleanup;
          }

          Status = ZwEnumerateKey(ResourceMapKey,
                                  ChildKeyIndex1,
                                  KeyBasicInformation,
                                  KeyInformation,
                                  KeyInformationLength,
                                  &RequiredLength);
      }
      else
         goto cleanup;
      ChildKeyIndex1++;
      if (!NT_SUCCESS(Status))
          goto cleanup;

      KeyName.Buffer = KeyInformation->Name;
      KeyName.MaximumLength = KeyName.Length = (USHORT)KeyInformation->NameLength;
      InitializeObjectAttributes(&ObjectAttributes,
                                 &KeyName,
                                 OBJ_CASE_INSENSITIVE,
                                 ResourceMapKey,
                                 NULL);
      Status = ZwOpenKey(&ChildKey2, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &ObjectAttributes);
      ExFreePool(KeyInformation);
      if (!NT_SUCCESS(Status))
          goto cleanup;

      while (TRUE)
      {
          Status = ZwEnumerateKey(ChildKey2,
                                  ChildKeyIndex2,
                                  KeyBasicInformation,
                                  NULL,
                                  0,
                                  &RequiredLength);
          if (Status == STATUS_NO_MORE_ENTRIES)
              break;
          else if (Status == STATUS_BUFFER_TOO_SMALL)
          {
              KeyInformationLength = RequiredLength;
              KeyInformation = ExAllocatePool(PagedPool, KeyInformationLength);
              if (!KeyInformation)
              {
                  Status = STATUS_INSUFFICIENT_RESOURCES;
                  goto cleanup;
              }

              Status = ZwEnumerateKey(ChildKey2,
                                      ChildKeyIndex2,
                                      KeyBasicInformation,
                                      KeyInformation,
                                      KeyInformationLength,
                                      &RequiredLength);
          }
          else
              goto cleanup;
          ChildKeyIndex2++;
          if (!NT_SUCCESS(Status))
              goto cleanup;

          KeyName.Buffer = KeyInformation->Name;
          KeyName.MaximumLength = KeyName.Length = (USHORT)KeyInformation->NameLength;
          InitializeObjectAttributes(&ObjectAttributes,
                                     &KeyName,
                                     OBJ_CASE_INSENSITIVE,
                                     ChildKey2,
                                     NULL);
          Status = ZwOpenKey(&ChildKey3, KEY_QUERY_VALUE, &ObjectAttributes);
          ExFreePool(KeyInformation);
          if (!NT_SUCCESS(Status))
              goto cleanup;

          while (TRUE)
          {
              Status = ZwEnumerateValueKey(ChildKey3,
                                           ChildKeyIndex3,
                                           KeyValuePartialInformation,
                                           NULL,
                                           0,
                                           &RequiredLength);
              if (Status == STATUS_NO_MORE_ENTRIES)
                  break;
              else if (Status == STATUS_BUFFER_TOO_SMALL)
              {
                  KeyValueInformationLength = RequiredLength;
                  KeyValueInformation = ExAllocatePool(PagedPool, KeyValueInformationLength);
                  if (!KeyValueInformation)
                  {
                      Status = STATUS_INSUFFICIENT_RESOURCES;
                      goto cleanup;
                  }

                  Status = ZwEnumerateValueKey(ChildKey3,
                                               ChildKeyIndex3,
                                               KeyValuePartialInformation,
                                               KeyValueInformation,
                                               KeyValueInformationLength,
                                               &RequiredLength);
              }
              else
                  goto cleanup;
              if (!NT_SUCCESS(Status))
                  goto cleanup;

              Status = ZwEnumerateValueKey(ChildKey3,
                                           ChildKeyIndex3,
                                           KeyValueBasicInformation,
                                           NULL,
                                           0,
                                           &RequiredLength);
              if (Status == STATUS_BUFFER_TOO_SMALL)
              {
                  KeyNameInformationLength = RequiredLength;
                  KeyNameInformation = ExAllocatePool(PagedPool, KeyNameInformationLength + sizeof(WCHAR));
                  if (!KeyNameInformation)
                  {
                      Status = STATUS_INSUFFICIENT_RESOURCES;
                      goto cleanup;
                  }

                  Status = ZwEnumerateValueKey(ChildKey3,
                                               ChildKeyIndex3,
                                               KeyValueBasicInformation,
                                               KeyNameInformation,
                                               KeyNameInformationLength,
                                               &RequiredLength);
              }
              else
                  goto cleanup;

              ChildKeyIndex3++;

              if (!NT_SUCCESS(Status))
                  goto cleanup;

              KeyNameInformation->Name[KeyNameInformation->NameLength / sizeof(WCHAR)] = UNICODE_NULL;

              /* Skip translated entries */
              if (wcsstr(KeyNameInformation->Name, L".Translated"))
              {
                  ExFreePool(KeyNameInformation);
                  continue;
              }

              ExFreePool(KeyNameInformation);

              if (IopCheckForResourceConflict(ResourceList,
                                              (PCM_RESOURCE_LIST)KeyValueInformation->Data,
                                              Silent,
                                              ConflictingDescriptor))
              {
                  ExFreePool(KeyValueInformation);
                  Status = STATUS_CONFLICTING_ADDRESSES;
                  goto cleanup;
              }

              ExFreePool(KeyValueInformation);
          }
      }
   }

cleanup:
   if (ResourceMapKey != INVALID_HANDLE_VALUE)
       ZwClose(ResourceMapKey);
   if (ChildKey2 != INVALID_HANDLE_VALUE)
       ZwClose(ChildKey2);
   if (ChildKey3 != INVALID_HANDLE_VALUE)
       ZwClose(ChildKey3);

   if (Status == STATUS_NO_MORE_ENTRIES)
       Status = STATUS_SUCCESS;

   return Status;
}
예제 #8
0
///////////////////////////////////////////////////////////////////////////////////////////////////
//  testdrvRegEnumerateValueKeys
//      Enumerates and print names of sub value keys using a given registry key handle.
//
//  Arguments:
//      IN  RegKeyHandle
//              Handle to root key
//
//  Return Value:
//      none
//
VOID testdrvRegEnumerateValueKeys(
    IN  HANDLE RegKeyHandle
    )
{
    NTSTATUS                        status;
    ULONG                           index;
    PKEY_VALUE_BASIC_INFORMATION    regBuffer;
    PWCHAR                          nameBuffer;
    ULONG                           length;

    status = STATUS_SUCCESS;
    index = 0;
    regBuffer = NULL;
    nameBuffer = NULL;

    while (status != STATUS_NO_MORE_ENTRIES)
    {
        // Get the buffer size necessary
        status = ZwEnumerateValueKey(
                    RegKeyHandle,
                    index,
                    KeyValueBasicInformation,
                    NULL,
                    0,
                    &length
                    );

        if ((status != STATUS_BUFFER_TOO_SMALL) && (status != STATUS_BUFFER_OVERFLOW))
        {
            if (status != STATUS_NO_MORE_ENTRIES)
            {
                testdrvDebugPrint(DBG_PNP, DBG_INFO, __FUNCTION__ ": ZwEnumerateValueKey failed %x", status);
            }
            else
            {
                testdrvDebugPrint(DBG_PNP, DBG_INFO, __FUNCTION__ ": Enumerated %d value keys", index);
            }

            break;
        }

        regBuffer = 
            (PKEY_VALUE_BASIC_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, length, TESTDRV_POOL_TAG);

        if (regBuffer == NULL)
        {
            continue;
        }

        // Now actually attempt to get subkey info
        status = ZwEnumerateValueKey(
                    RegKeyHandle,
                    index,
                    KeyValueBasicInformation,
                    regBuffer,
                    length,
                    &length
                    );

        if (!NT_SUCCESS(status))
        {
            testdrvDebugPrint(DBG_PNP, DBG_INFO, __FUNCTION__ ": ZwEnumerateValueKey failed %x", status);

            // Free our temporary storage
            ExFreePool(regBuffer);

            continue;
        }

        // Allocate a buffer for the display name
        nameBuffer = (PWCHAR)ExAllocatePoolWithTag(
                                    PagedPool, 
                                    regBuffer->NameLength + sizeof(WCHAR), 
                                    TESTDRV_POOL_TAG
                                    );

        if (nameBuffer == NULL)
        {
            // Free our temporary storage
            ExFreePool(regBuffer);

            continue;
        }

        // NULL terminate the string
        RtlZeroMemory(nameBuffer, regBuffer->NameLength + sizeof(WCHAR));

        // Copy the name over
        RtlCopyMemory(nameBuffer, regBuffer->Name, regBuffer->NameLength);
        
        testdrvDebugPrint(DBG_PNP, DBG_INFO, __FUNCTION__ ": ZwEnumerateValueKey returned %S", nameBuffer);

        // Free both buffers
        ExFreePool(regBuffer);
        ExFreePool(nameBuffer);

        // Increment our index
        ++index;
    }

    return;
}
예제 #9
0
NTSTATUS
NdasPortFdoRegEnumerateLogicalUnits(
	__in PNDASPORT_FDO_EXTENSION FdoExtension,
	__in PNDASPORT_ENUMERATE_LOGICALUNIT_CALLBACK Callback,
	__in PVOID CallbackContext)
{
	NTSTATUS status, status2;
	HANDLE keyHandle;
	PKEY_VALUE_FULL_INFORMATION keyValueInformation;
	ULONG keyValueInformationLength;
	ULONG resultLength;
	ULONG index;

	PNDAS_LOGICALUNIT_DESCRIPTOR descriptor;

	PAGED_CODE();

	keyHandle = NULL;
	status = NdasPortFdoOpenRegistryKey(
		FdoExtension,
		NDASPORT_FDO_REGKEY_LOGICALUNIT_LIST,
		KEY_READ,
		&keyHandle);

	if (!NT_SUCCESS(status))
	{
		NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_ERROR,
			"IoOpenDeviceRegistryKey failed, status=%X, fdo=%p\n", 
			status,
			FdoExtension->DeviceObject);
		return status;
	}

	keyValueInformation = NULL;
	keyValueInformationLength = 0;

	for (index = 0; ;)
	{
		status = ZwEnumerateValueKey(
			keyHandle,
			index,
			KeyValueFullInformation,
			keyValueInformation,
			keyValueInformationLength,
			&resultLength);

		if (NT_SUCCESS(status))
		{
			//
			// value prefix must be LU
			//
			ASSERT(NULL != keyValueInformation);
			if (keyValueInformation->NameLength < 4 ||
				!RtlEqualMemory(keyValueInformation->Name, L"LU", 4))
			{
				NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_WARNING,
					"Value is not prefixed with LU, value=%ws\n", 
					keyValueInformation->NameLength ? 
					keyValueInformation->Name : L"(default)");
				// ignore the invalid key values
				++index;
				continue;
			}
			//
			// It should contain valid logical unit descriptor
			//
			if (keyValueInformation->DataLength < sizeof(NDAS_LOGICALUNIT_DESCRIPTOR))
			{
				NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_WARNING,
					"Data is not a valid descriptor, DataLength=0x%X\n", 
					keyValueInformation->DataLength);
				// ignore the invalid key values
				++index;
				continue;
			}

			descriptor = (PNDAS_LOGICALUNIT_DESCRIPTOR) NdasPortOffsetOf(
				keyValueInformation, keyValueInformation->DataOffset);
			
			//
			// Descriptor version should be the size of the structure
			//
			if (sizeof(NDAS_LOGICALUNIT_DESCRIPTOR) != descriptor->Version)
			{	
				NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_WARNING,
					"Data is not a valid descriptor, descriptor->Version=0x%X\n", 
					descriptor->Version);
				// ignore the invalid key values
				++index;
				continue;
			}

			//
			// DataLength should be larger than the size specified in
			// the descriptor
			//
			if (keyValueInformation->DataLength < descriptor->Size)
			{
				NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_WARNING,
					"Data is not a valid descriptor, "
					"DataLength is less than the size in the descriptor "
					"descriptor->Size=0x%X, dataLength=0x%X\n", 
					descriptor->Size,
					keyValueInformation->DataLength);
				// ignore the invalid key values
				++index;
				continue;
			}

			//
			// Now we get the valid logical unit descriptor
			// Invoke the callback function
			//
			(*Callback)(FdoExtension, descriptor, CallbackContext);

			//
			// Next entry
			//
			++index;
			continue;
		}
		else if (STATUS_NO_MORE_ENTRIES == status)
		{
			//
			// STATUS_NO_MORE_ENTRIES means success for this function
			//
			status = STATUS_SUCCESS;
			break;
		}
		else if (STATUS_BUFFER_OVERFLOW == status ||
			STATUS_BUFFER_TOO_SMALL == status)
		{
			if (NULL != keyValueInformation)
			{
				ExFreePoolWithTag(
					keyValueInformation, 
					NDASPORT_TAG_REGISTRY_ENUM);
			}
			
			keyValueInformation = ExAllocatePoolWithTag(
				PagedPool, resultLength, NDASPORT_TAG_REGISTRY_ENUM);

			if (NULL == keyValueInformation)
			{
				status2 = ZwClose(keyHandle);
				ASSERT(NT_SUCCESS(status2));
				status = STATUS_NO_MEMORY;
				break;
			}
			
			keyValueInformationLength = resultLength;

			//
			// try again with the same index
			//
			continue;
		}
		else
		{
			//
			// retain the status value and return the status code
			//
			break;
		}
	}

	if (NULL != keyValueInformation)
	{
		ExFreePoolWithTag(
			keyValueInformation, 
			NDASPORT_TAG_REGISTRY_ENUM);
	}

	status2 = ZwClose(keyHandle);

	ASSERT(NT_SUCCESS(status2));
	if (!NT_SUCCESS(status2))
	{
		NdasPortTrace(NDASPORT_FDO_IOCTL, TRACE_LEVEL_WARNING,
			"ZwClose failed, keyHandle=%p, status=%X\n", 
			keyHandle, status2);
	}

	return status;
}
예제 #10
0
파일: pcibus.c 프로젝트: RareHare/reactos
PPCI_REGISTRY_INFO_INTERNAL
NTAPI
INIT_FUNCTION
HalpQueryPciRegistryInfo(VOID)
{
#ifndef _MINIHAL_
    WCHAR NameBuffer[8];
    OBJECT_ATTRIBUTES  ObjectAttributes;
    UNICODE_STRING KeyName, ConfigName, IdentName;
    HANDLE KeyHandle, BusKeyHandle, CardListHandle;
    NTSTATUS Status;
    UCHAR KeyBuffer[sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + 100];
    PKEY_VALUE_FULL_INFORMATION ValueInfo = (PVOID)KeyBuffer;
    UCHAR PartialKeyBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
                           sizeof(PCI_CARD_DESCRIPTOR)];
    PKEY_VALUE_PARTIAL_INFORMATION PartialValueInfo = (PVOID)PartialKeyBuffer;
    KEY_FULL_INFORMATION KeyInformation;
    ULONG ResultLength;
    PWSTR Tag;
    ULONG i, ElementCount;
    PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
    PPCI_REGISTRY_INFO PciRegInfo;
    PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo;
    PPCI_CARD_DESCRIPTOR CardDescriptor;

    /* Setup the object attributes for the key */
    RtlInitUnicodeString(&KeyName,
                         L"\\Registry\\Machine\\Hardware\\Description\\"
                         L"System\\MultiFunctionAdapter");
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    /* Open the key */
    Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
    if (!NT_SUCCESS(Status)) return NULL;

    /* Setup the receiving string */
    KeyName.Buffer = NameBuffer;
    KeyName.MaximumLength = sizeof(NameBuffer);

    /* Setup the configuration and identifier key names */
    RtlInitUnicodeString(&ConfigName, L"Configuration Data");
    RtlInitUnicodeString(&IdentName, L"Identifier");

    /* Keep looping for each ID */
    for (i = 0; TRUE; i++)
    {
        /* Setup the key name */
        RtlIntegerToUnicodeString(i, 10, &KeyName);
        InitializeObjectAttributes(&ObjectAttributes,
                                   &KeyName,
                                   OBJ_CASE_INSENSITIVE,
                                   KeyHandle,
                                   NULL);

        /* Open it */
        Status = ZwOpenKey(&BusKeyHandle, KEY_READ, &ObjectAttributes);
        if (!NT_SUCCESS(Status))
        {
            /* None left, fail */
            ZwClose(KeyHandle);
            return NULL;
        }

        /* Read the registry data */
        Status = ZwQueryValueKey(BusKeyHandle,
                                 &IdentName,
                                 KeyValueFullInformation,
                                 ValueInfo,
                                 sizeof(KeyBuffer),
                                 &ResultLength);
        if (!NT_SUCCESS(Status))
        {
            /* Failed, try the next one */
            ZwClose(BusKeyHandle);
            continue;
        }

        /* Get the PCI Tag and validate it */
        Tag = (PWSTR)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset);
        if ((Tag[0] != L'P') ||
            (Tag[1] != L'C') ||
            (Tag[2] != L'I') ||
            (Tag[3]))
        {
            /* Not a valid PCI entry, skip it */
            ZwClose(BusKeyHandle);
            continue;
        }

        /* Now read our PCI structure */
        Status = ZwQueryValueKey(BusKeyHandle,
                                 &ConfigName,
                                 KeyValueFullInformation,
                                 ValueInfo,
                                 sizeof(KeyBuffer),
                                 &ResultLength);
        ZwClose(BusKeyHandle);
        if (!NT_SUCCESS(Status)) continue;

        /* We read it OK! Get the actual resource descriptors */
        FullDescriptor  = (PCM_FULL_RESOURCE_DESCRIPTOR)
                          ((ULONG_PTR)ValueInfo + ValueInfo->DataOffset);
        PartialDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
                            ((ULONG_PTR)FullDescriptor->
                                        PartialResourceList.PartialDescriptors);

        /* Check if this is our PCI Registry Information */
        if (PartialDescriptor->Type == CmResourceTypeDeviceSpecific)
        {
            /* It is, stop searching */
            break;
        }
    }

    /* Close the key */
    ZwClose(KeyHandle);

    /* Save the PCI information for later */
    PciRegInfo = (PPCI_REGISTRY_INFO)(PartialDescriptor + 1);

    /* Assume no Card List entries */
    ElementCount = 0;

    /* Set up for checking the PCI Card List key */
    RtlInitUnicodeString(&KeyName,
                         L"\\Registry\\Machine\\System\\CurrentControlSet\\"
                         L"Control\\PnP\\PCI\\CardList");
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    /* Attempt to open it */
    Status = ZwOpenKey(&CardListHandle, KEY_READ, &ObjectAttributes);
    if (NT_SUCCESS(Status))
    {
        /* It exists, so let's query it */
        Status = ZwQueryKey(CardListHandle,
                            KeyFullInformation,
                            &KeyInformation,
                            sizeof(KEY_FULL_INFORMATION),
                            &ResultLength);
        if (!NT_SUCCESS(Status))
        {
            /* Failed to query, so no info */
            PciRegistryInfo = NULL;
        }
        else
        {
            /* Allocate the full structure */
            PciRegistryInfo =
                ExAllocatePoolWithTag(NonPagedPool,
                                      sizeof(PCI_REGISTRY_INFO_INTERNAL) +
                                      (KeyInformation.Values *
                                       sizeof(PCI_CARD_DESCRIPTOR)),
                                       TAG_HAL);
            if (PciRegistryInfo)
            {
                /* Get the first card descriptor entry */
                CardDescriptor = (PPCI_CARD_DESCRIPTOR)(PciRegistryInfo + 1);

                /* Loop all the values */
                for (i = 0; i < KeyInformation.Values; i++)
                {
                    /* Attempt to get the value */
                    Status = ZwEnumerateValueKey(CardListHandle,
                                                 i,
                                                 KeyValuePartialInformation,
                                                 PartialValueInfo,
                                                 sizeof(PartialKeyBuffer),
                                                 &ResultLength);
                    if (!NT_SUCCESS(Status))
                    {
                        /* Something went wrong, stop the search */
                        break;
                    }

                    /* Make sure it is correctly sized */
                    if (PartialValueInfo->DataLength == sizeof(PCI_CARD_DESCRIPTOR))
                    {
                        /* Sure is, copy it over */
                        *CardDescriptor = *(PPCI_CARD_DESCRIPTOR)
                                           PartialValueInfo->Data;

                        /* One more Card List entry */
                        ElementCount++;

                        /* Move to the next descriptor */
                        CardDescriptor = (CardDescriptor + 1);
                    }
                }
            }
        }

        /* Close the Card List key */
        ZwClose(CardListHandle);
    }
    else
    {
       /* No key, no Card List */
       PciRegistryInfo = NULL;
    }

    /* Check if we failed to get the full structure */
    if (!PciRegistryInfo)
    {
        /* Just allocate the basic structure then */
        PciRegistryInfo = ExAllocatePoolWithTag(NonPagedPool,
                                                sizeof(PCI_REGISTRY_INFO_INTERNAL),
                                                TAG_HAL);
        if (!PciRegistryInfo) return NULL;
    }

    /* Save the info we got */
    PciRegistryInfo->MajorRevision = PciRegInfo->MajorRevision;
    PciRegistryInfo->MinorRevision = PciRegInfo->MinorRevision;
    PciRegistryInfo->NoBuses = PciRegInfo->NoBuses;
    PciRegistryInfo->HardwareMechanism = PciRegInfo->HardwareMechanism;
    PciRegistryInfo->ElementCount = ElementCount;

    /* Return it */
    return PciRegistryInfo;
#else
    return NULL;
#endif
}
예제 #11
0
BOOLEAN QueryServiceRunType( PUNICODE_STRING pSrvName, PSERVICES_INFO pServicesInfo )
{
	OBJECT_ATTRIBUTES ObjectAttributes;
	HANDLE	HandleRegKey = NULL;
	NTSTATUS status = STATUS_UNSUCCESSFUL;
	ULONG SubItemIndex, SubItemCount, ulSize, ulItemValue;
	UNICODE_STRING usItemName, usItemValue;
	PKEY_VALUE_FULL_INFORMATION pKeyFullValueInfo = NULL;
	PKEY_FULL_INFORMATION pKeyFullInfo = NULL;
	BOOLEAN bRet = FALSE;

	/************************************************************************/
	/* ServiceType 服务类型:0×10为独立进程服务,0×20为共享进程服务(比如svchost);
	StartType 启动类型:0 系统引导时加载,1 OS初始化时加载,2 由SCM(服务控制管理器)自动启动,3 手动启动,4 禁用。(注意,0和1只能用于驱动程序)
	ErrorControl 错误控制:0 忽略,1 继续并警告,2 切换到LastKnownGood的设置,3 蓝屏。
	ServiceBinary 服务程序位置:%11%表示system32目录,%10%表示系统目录(WINNT或Windows),%12%为驱动目录system32\drivers。也可以不用变量,直接使用全路径。
	服务名MentoHUST后面有两个逗号,因为中间省略了一个不常用的参数flags。
	Description、ServiceType、StartType、ErrorControl四项是必须要有的,还有LoadOrderGroup、Dependencies等就不做详述了。                                                                     */
	/************************************************************************/

	__try
	{

		InitializeObjectAttributes(&ObjectAttributes, 
			pSrvName,
			OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
			NULL,    // handle
			NULL);
		status = ZwOpenKey(&HandleRegKey, KEY_READ, &ObjectAttributes);


		// 第一次调用是为了获取需要的长度
		ZwQueryKey(HandleRegKey, KeyFullInformation, NULL, 0, &ulSize);
		pKeyFullInfo = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool, ulSize);
		// 第二次调用是为了获取数据
		ZwQueryKey(HandleRegKey, KeyFullInformation, pKeyFullInfo, ulSize, &ulSize);
		SubItemCount = pKeyFullInfo->Values;

		//循环遍历各个子项
		for (SubItemIndex = 0; SubItemIndex < SubItemCount; SubItemIndex++)
		{
			//_asm int 3
			ZwEnumerateValueKey(HandleRegKey, SubItemIndex, KeyValueFullInformation, NULL, 0, &ulSize);
			pKeyFullValueInfo = (PKEY_VALUE_FULL_INFORMATION)ExAllocatePool(PagedPool, ulSize);
			//获取第I个子项的数据
			status = ZwEnumerateValueKey(HandleRegKey, SubItemIndex, KeyValueFullInformation, pKeyFullValueInfo, ulSize, &ulSize);

			if (status == STATUS_SUCCESS)
			{
				usItemName.Length = usItemName.MaximumLength =  (USHORT)pKeyFullValueInfo->NameLength;
				usItemName.Buffer = pKeyFullValueInfo->Name;
				usItemValue.Length = usItemValue.MaximumLength = (USHORT)pKeyFullValueInfo->DataLength;
				usItemValue.Buffer = (PWCHAR)((PUCHAR)pKeyFullValueInfo + pKeyFullValueInfo->DataOffset);


				if (RtlCompareMemory(usItemName.Buffer, L"Type", usItemName.Length))
				{
					ulItemValue = *(PULONG)usItemValue.Buffer;
					//RtlUnicodeStringToInteger(&usItemValue, 16, &ulItemValue);
					if (0x10 != ulItemValue && 0x20 != ulItemValue && 0x110 != ulItemValue && 0x120 != ulItemValue)
					{
						bRet = FALSE;
						break;
					}
					else
					{
						bRet = TRUE;
						//_asm int 3
					}
				}
				else if (RtlCompareMemory(usItemName.Buffer, L"DisplayName", usItemName.Length) == usItemName.Length)
				{
					RtlCopyMemory(pServicesInfo->lpwzSrvName, usItemValue.Buffer, usItemValue.Length);
				}
				else if (RtlCompareMemory(usItemName.Buffer, L"ImagePath", usItemName.Length) == usItemName.Length)
				{
					RtlCopyMemory(pServicesInfo->lpwzImageName, usItemValue.Buffer, usItemValue.Length);
				}
				else if (RtlCompareMemory(usItemName.Buffer, L"Description", usItemName.Length) == usItemName.Length)
				{
					RtlCopyMemory(pServicesInfo->lpwzDescription, usItemValue.Buffer, usItemValue.Length);
				}
				else if (RtlCompareMemory(usItemName.Buffer, L"Start", usItemName.Length) == usItemName.Length)
				{
					ulItemValue = *(PULONG)usItemValue.Buffer;
					switch(ulItemValue)
					{ 
					case(SERVICE_AUTO_START):
						RtlCopyMemory(pServicesInfo->lpwzBootType, L"自动", sizeof(L"自动"));
						break;
					case(SERVICE_BOOT_START):
						RtlCopyMemory(pServicesInfo->lpwzBootType, L"引导", sizeof(L"引导"));
						break;
					case(SERVICE_DEMAND_START):
						RtlCopyMemory(pServicesInfo->lpwzBootType, L"手动", sizeof(L"手动"));
						break;
					case(SERVICE_DISABLED):
						RtlCopyMemory(pServicesInfo->lpwzBootType, L"已禁用", sizeof(L"已禁用"));
						break;
					case(SERVICE_SYSTEM_START):
						RtlCopyMemory(pServicesInfo->lpwzBootType, L"系统", sizeof(L"系统"));
						break;
					default:
						RtlCopyMemory(pServicesInfo->lpwzBootType, L"未知", sizeof(L"未知"));
						break;
					}
				}
				if (pKeyFullValueInfo->Type == REG_SZ)
				{
					KdPrint(("The sub value type:REG_SZ\n"));
				}
				else if (pKeyFullValueInfo->Type == REG_EXPAND_SZ)
				{
					KdPrint(("The sub value type:REG_EXPAND_SZ\n"));
				}
				else if (pKeyFullValueInfo->Type == REG_DWORD)
				{
					KdPrint(("The sub value type:REG_DWORD\n"));
				}
				else if (pKeyFullValueInfo->Type == REG_BINARY)
				{
					KdPrint(("The sub value type:REG_BINARY\n"));
				}
			}

			if (NULL != pKeyFullValueInfo)
			{
				ExFreePool(pKeyFullValueInfo);
				pKeyFullValueInfo = NULL;
			}
		}
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		bRet = FALSE;

	}

	if (NULL != pKeyFullInfo)
	{
		ExFreePool(pKeyFullInfo);
		pKeyFullInfo = NULL;
	}
	if (NULL != pKeyFullValueInfo)
	{
		ExFreePool(pKeyFullValueInfo);
		pKeyFullValueInfo = NULL;
	}

	return bRet;
}