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

📄 iorsrce.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: iorsrce.c 28217 2007-08-07 11:45:30Z hpoussin $
 *
 * COPYRIGHT:       See COPYING in the top level directory
 * PROJECT:         ReactOS kernel
 * FILE:            ntoskrnl/io/resource.c
 * PURPOSE:         Hardware resource managment
 *
 * PROGRAMMERS:     David Welch (welch@mcmail.com)
 *                  Alex Ionescu (alex@relsoft.net)
 */

/* INCLUDES *****************************************************************/

#include <ntoskrnl.h>
#include <internal/debug.h>

/* GLOBALS *******************************************************************/

static CONFIGURATION_INFORMATION
_SystemConfigurationInformation = {0, 0, 0, 0, 0, 0, 0, FALSE, FALSE};

/* API Parameters to Pass in IopQueryBusDescription */
typedef struct IO_QUERY {
    PINTERFACE_TYPE  BusType;
    PULONG  BusNumber;
    PCONFIGURATION_TYPE  ControllerType;
    PULONG  ControllerNumber;
    PCONFIGURATION_TYPE  PeripheralType;
    PULONG  PeripheralNumber;
    PIO_QUERY_DEVICE_ROUTINE  CalloutRoutine;
    PVOID  Context;
} IO_QUERY, *PIO_QUERY;

PWSTR ArcTypes[42] = {
    L"System",
    L"CentralProcessor",
    L"FloatingPointProcessor",
    L"PrimaryICache",
    L"PrimaryDCache",
    L"SecondaryICache",
    L"SecondaryDCache",
    L"SecondaryCache",
    L"EisaAdapter",
    L"TcAdapter",
    L"ScsiAdapter",
    L"DtiAdapter",
    L"MultifunctionAdapter",
    L"DiskController",
    L"TapeController",
    L"CdRomController",
    L"WormController",
    L"SerialController",
    L"NetworkController",
    L"DisplayController",
    L"ParallelController",
    L"PointerController",
    L"KeyboardController",
    L"AudioController",
    L"OtherController",
    L"DiskPeripheral",
    L"FloppyDiskPeripheral",
    L"TapePeripheral",
    L"ModemPeripheral",
    L"MonitorPeripheral",
    L"PrinterPeripheral",
    L"PointerPeripheral",
    L"KeyboardPeripheral",
    L"TerminalPeripheral",
    L"OtherPeripheral",
    L"LinePeripheral",
    L"NetworkPeripheral",
    L"SystemMemory",
    L"DockingInformation",
    L"RealModeIrqRoutingTable",
    L"RealModePCIEnumeration",
    L"Undefined"
};

/* PRIVATE FUNCTIONS **********************************************************/

/*
 * IopQueryDeviceDescription
 *
 * FUNCTION:
 *     Reads and returns Hardware information from the appropriate hardware
 *     registry key. Helper sub of IopQueryBusDescription.
 *
 * ARGUMENTS:
 *     Query          - What the parent function wants.
 *     RootKey        - Which key to look in
 *     RootKeyHandle  - Handle to the key
 *     Bus            - Bus Number.
 *     BusInformation - The Configuration Information Sent
 *
 * RETURNS:
 *      Status
 */

NTSTATUS STDCALL
IopQueryDeviceDescription(
   PIO_QUERY Query,
   UNICODE_STRING RootKey,
   HANDLE RootKeyHandle,
   ULONG Bus,
   PKEY_VALUE_FULL_INFORMATION *BusInformation)
{
   NTSTATUS Status = STATUS_SUCCESS;

   /* Controller Stuff */
   UNICODE_STRING ControllerString;
   UNICODE_STRING ControllerRootRegName = RootKey;
   UNICODE_STRING ControllerRegName;
   HANDLE ControllerKeyHandle;
   PKEY_FULL_INFORMATION ControllerFullInformation = NULL;
   PKEY_VALUE_FULL_INFORMATION ControllerInformation[3] = {NULL, NULL, NULL};
   ULONG ControllerNumber;
   ULONG ControllerLoop;
   ULONG MaximumControllerNumber;

   /* Peripheral Stuff */
   UNICODE_STRING PeripheralString;
   HANDLE PeripheralKeyHandle;
   PKEY_FULL_INFORMATION PeripheralFullInformation;
   PKEY_VALUE_FULL_INFORMATION PeripheralInformation[3] = {NULL, NULL, NULL};
   ULONG PeripheralNumber;
   ULONG PeripheralLoop;
   ULONG MaximumPeripheralNumber;

   /* Global Registry Stuff */
   OBJECT_ATTRIBUTES ObjectAttributes;
   ULONG LenFullInformation;
   ULONG LenKeyFullInformation;
   UNICODE_STRING TempString;
   WCHAR TempBuffer[14];
   PWSTR Strings[3] = {
      L"Identifier",
      L"Configuration Data",
      L"Component Information"
   };

   /* Temporary String */
   TempString.MaximumLength = sizeof(TempBuffer);
   TempString.Length = 0;
   TempString.Buffer = TempBuffer;

   /* Add Controller Name to String */
   RtlAppendUnicodeToString(&ControllerRootRegName, L"\\");
   RtlAppendUnicodeToString(&ControllerRootRegName, ArcTypes[*Query->ControllerType]);

   /* Set the Controller Number if specified */
   if (Query->ControllerNumber && *(Query->ControllerNumber))
   {
      ControllerNumber = *Query->ControllerNumber;
      MaximumControllerNumber = ControllerNumber + 1;
   } else {
      /* Find out how many Controller Numbers there are */
      InitializeObjectAttributes(
         &ObjectAttributes,
         &ControllerRootRegName,
         OBJ_CASE_INSENSITIVE,
         NULL,
         NULL);

      Status = ZwOpenKey(&ControllerKeyHandle, KEY_READ, &ObjectAttributes);
      if (NT_SUCCESS(Status))
      {
         /* How much buffer space */
         ZwQueryKey(ControllerKeyHandle, KeyFullInformation, NULL, 0, &LenFullInformation);

         /* Allocate it */
         ControllerFullInformation = ExAllocatePoolWithTag(PagedPool, LenFullInformation, TAG_IO_RESOURCE);

         /* Get the Information */
         Status = ZwQueryKey(ControllerKeyHandle, KeyFullInformation, ControllerFullInformation, LenFullInformation, &LenFullInformation);
         ZwClose(ControllerKeyHandle);
         ControllerKeyHandle = NULL;
      }

      /* No controller was found, go back to function. */
      if (!NT_SUCCESS(Status))
      {
         if (ControllerFullInformation != NULL)
            ExFreePool(ControllerFullInformation);
         return Status;
      }

      /* Find out Controller Numbers */
      ControllerNumber = 0;
      MaximumControllerNumber = ControllerFullInformation->SubKeys;

      /* Free Memory */
      ExFreePool(ControllerFullInformation);
      ControllerFullInformation = NULL;
   }

   /* Save String */
   ControllerRegName = ControllerRootRegName;

   /* Loop through controllers */
   for (; ControllerNumber < MaximumControllerNumber; ControllerNumber++)
   {
      /* Load String */
      ControllerRootRegName = ControllerRegName;

      /* Controller Number to Registry String */
      Status = RtlIntegerToUnicodeString(ControllerNumber, 10, &TempString);

      /* Create String */
      Status |= RtlAppendUnicodeToString(&ControllerRootRegName, L"\\");
      Status |= RtlAppendUnicodeStringToString(&ControllerRootRegName, &TempString);

      /* Something messed up */
      if (!NT_SUCCESS(Status)) break;

      /* Open the Registry Key */
      InitializeObjectAttributes(
         &ObjectAttributes,
         &ControllerRootRegName,
         OBJ_CASE_INSENSITIVE,
         NULL,
         NULL);

      Status = ZwOpenKey(&ControllerKeyHandle, KEY_READ, &ObjectAttributes);

      /* Read the Configuration Data... */
      if (NT_SUCCESS(Status))
      {
         for (ControllerLoop = 0; ControllerLoop < 3; ControllerLoop++)
         {
            /* Identifier String First */
            RtlInitUnicodeString(&ControllerString, Strings[ControllerLoop]);

            /* How much buffer space */
            Status = ZwQueryValueKey(ControllerKeyHandle, &ControllerString, KeyValueFullInformation, NULL, 0, &LenKeyFullInformation);

	    if(!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL && Status != STATUS_BUFFER_OVERFLOW)
	      continue;

            /* Allocate it */
            ControllerInformation[ControllerLoop] = ExAllocatePoolWithTag(PagedPool, LenKeyFullInformation, TAG_IO_RESOURCE);

            /* Get the Information */
            Status = ZwQueryValueKey(ControllerKeyHandle, &ControllerString, KeyValueFullInformation, ControllerInformation[ControllerLoop], LenKeyFullInformation, &LenKeyFullInformation);
         }

         /* Clean Up */
         ZwClose(ControllerKeyHandle);
         ControllerKeyHandle = NULL;
      }

      /* Something messed up */
      if (!NT_SUCCESS(Status))
         goto EndLoop;

      /* We now have Bus *AND* Controller Information.. is it enough? */
      if (!Query->PeripheralType || !(*Query->PeripheralType))
      {
         Status = Query->CalloutRoutine(
            Query->Context,
            &ControllerRootRegName,
            *Query->BusType,
            Bus,
            BusInformation,
            *Query->ControllerType,
            ControllerNumber,
            ControllerInformation,
            0,
            0,
            NULL);
         goto EndLoop;
      }

      /* Not enough...caller also wants peripheral name */
      Status = RtlAppendUnicodeToString(&ControllerRootRegName, L"\\");
      Status |= RtlAppendUnicodeToString(&ControllerRootRegName, ArcTypes[*Query->PeripheralType]);

      /* Something messed up */
      if (!NT_SUCCESS(Status)) goto EndLoop;

      /* Set the Peripheral Number if specified */
      if (Query->PeripheralNumber && *Query->PeripheralNumber)
      {
         PeripheralNumber = *Query->PeripheralNumber;
         MaximumPeripheralNumber = PeripheralNumber + 1;
      } else {
         /* Find out how many Peripheral Numbers there are */
         InitializeObjectAttributes(
            &ObjectAttributes,
            &ControllerRootRegName,
            OBJ_CASE_INSENSITIVE,
            NULL,
            NULL);

         Status = ZwOpenKey(&PeripheralKeyHandle, KEY_READ, &ObjectAttributes);

         if (NT_SUCCESS(Status))
         {
            /* How much buffer space */
            ZwQueryKey(PeripheralKeyHandle, KeyFullInformation, NULL, 0, &LenFullInformation);

            /* Allocate it */
            PeripheralFullInformation = ExAllocatePoolWithTag(PagedPool, LenFullInformation, TAG_IO_RESOURCE);

            /* Get the Information */
            Status = ZwQueryKey(PeripheralKeyHandle, KeyFullInformation, PeripheralFullInformation, LenFullInformation, &LenFullInformation);
            ZwClose(PeripheralKeyHandle);
            PeripheralKeyHandle = NULL;
         }

         /* No controller was found, go back to function but clean up first */
         if (!NT_SUCCESS(Status))
         {
            Status = STATUS_SUCCESS;
            goto EndLoop;
         }

         /* Find out Peripheral Number */
         PeripheralNumber = 0;
         MaximumPeripheralNumber = PeripheralFullInformation->SubKeys;

         /* Free Memory */
         ExFreePool(PeripheralFullInformation);
         PeripheralFullInformation = NULL;
      }

      /* Save Name */
      ControllerRegName = ControllerRootRegName;

      /* Loop through Peripherals */
      for (; PeripheralNumber < MaximumPeripheralNumber; PeripheralNumber++)
      {
         /* Restore Name */
         ControllerRootRegName = ControllerRegName;

         /* Peripheral Number to Registry String */
         Status = RtlIntegerToUnicodeString(PeripheralNumber, 10, &TempString);

         /* Create String */
         Status |= RtlAppendUnicodeToString(&ControllerRootRegName, L"\\");
	 Status |= RtlAppendUnicodeStringToString(&ControllerRootRegName, &TempString);

         /* Something messed up */
         if (!NT_SUCCESS(Status)) break;

         /* Open the Registry Key */
         InitializeObjectAttributes(
            &ObjectAttributes,
            &ControllerRootRegName,
            OBJ_CASE_INSENSITIVE,
            NULL,
            NULL);

         Status = ZwOpenKey(&PeripheralKeyHandle, KEY_READ, &ObjectAttributes);

         if (NT_SUCCESS(Status))
         {
            for (PeripheralLoop = 0; PeripheralLoop < 3; PeripheralLoop++)
            {
               /* Identifier String First */
               RtlInitUnicodeString(&PeripheralString, Strings[PeripheralLoop]);

               /* How much buffer space */
               Status = ZwQueryValueKey(PeripheralKeyHandle, &PeripheralString, KeyValueFullInformation, NULL, 0, &LenKeyFullInformation);

	       if(!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL && Status != STATUS_BUFFER_OVERFLOW)
	       {
	         PeripheralInformation[PeripheralLoop] = NULL;
		 continue;
	       }

               /* Allocate it */
               PeripheralInformation[PeripheralLoop] = ExAllocatePoolWithTag(PagedPool, LenKeyFullInformation, TAG_IO_RESOURCE);

               /* Get the Information */
               Status = ZwQueryValueKey(PeripheralKeyHandle, &PeripheralString, KeyValueFullInformation, PeripheralInformation[PeripheralLoop], LenKeyFullInformation, &LenKeyFullInformation);
            }

            /* Clean Up */
            ZwClose(PeripheralKeyHandle);
            PeripheralKeyHandle = NULL;

            /* We now have everything the caller could possibly want */
            if (NT_SUCCESS(Status))
            {
               Status = Query->CalloutRoutine(
                  Query->Context,
                  &ControllerRootRegName,
                  *Query->BusType,
                  Bus,
                  BusInformation,
                  *Query->ControllerType,
                  ControllerNumber,
                  ControllerInformation,
                  *Query->PeripheralType,
                  PeripheralNumber,
                  PeripheralInformation);
            }

            /* Free the allocated memory */
            for (PeripheralLoop = 0; PeripheralLoop < 3; PeripheralLoop++)
            {
               if (PeripheralInformation[PeripheralLoop])
               {
                  ExFreePool(PeripheralInformation[PeripheralLoop]);
                  PeripheralInformation[PeripheralLoop] = NULL;
               }
            }

            /* Something Messed up */
            if (!NT_SUCCESS(Status)) break;
         }
      }

EndLoop:
      /* Free the allocated memory */
      for (ControllerLoop = 0; ControllerLoop < 3; ControllerLoop++)
      {
         if (ControllerInformation[ControllerLoop])
         {
            ExFreePool(ControllerInformation[ControllerLoop]);
            ControllerInformation[ControllerLoop] = NULL;
         }
      }

      /* Something Messed up */
      if (!NT_SUCCESS(Status)) break;
   }

   return Status;
}

/*
 * IopQueryBusDescription
 *
 * FUNCTION:
 *      Reads and returns Hardware information from the appropriate hardware
 *      registry key. Helper sub of IoQueryDeviceDescription. Has two modes
 *      of operation, either looking for Root Bus Types or for sub-Bus
 *      information.
 *
 * ARGUMENTS:
 *      Query         - What the parent function wants.
 *      RootKey	      - Which key to look in
 *      RootKeyHandle - Handle to the key
 *      Bus           - Bus Number.
 *      KeyIsRoot     - Whether we are looking for Root Bus Types or
 *                      information under them.
 *
 * RETURNS:
 *      Status
 */

NTSTATUS STDCALL
IopQueryBusDescription(
   PIO_QUERY Query,
   UNICODE_STRING RootKey,
   HANDLE RootKeyHandle,

⌨️ 快捷键说明

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