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

📄 iorsrce.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
   PULONG Bus,
   BOOLEAN KeyIsRoot)
{
   NTSTATUS Status;
   ULONG BusLoop;
   UNICODE_STRING SubRootRegName;
   UNICODE_STRING BusString;
   UNICODE_STRING SubBusString;
   ULONG LenBasicInformation = 0;
   ULONG LenFullInformation;
   ULONG LenKeyFullInformation;
   ULONG LenKey;
   HANDLE SubRootKeyHandle;
   PKEY_FULL_INFORMATION FullInformation;
   PKEY_BASIC_INFORMATION BasicInformation = NULL;
   OBJECT_ATTRIBUTES ObjectAttributes;
   PKEY_VALUE_FULL_INFORMATION BusInformation[3] = {NULL, NULL, NULL};

   /* How much buffer space */
   Status = ZwQueryKey(RootKeyHandle, KeyFullInformation, NULL, 0, &LenFullInformation);

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

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

   if(!FullInformation)
     return STATUS_NO_MEMORY;

   /* Get the Information */
   Status = ZwQueryKey(RootKeyHandle, KeyFullInformation, FullInformation, LenFullInformation, &LenFullInformation);

   /* Everything was fine */
   if (NT_SUCCESS(Status))
   {
      /* Buffer needed for all the keys under this one */
      LenBasicInformation = FullInformation->MaxNameLen + sizeof(KEY_BASIC_INFORMATION);

      /* Allocate it */
      BasicInformation = ExAllocatePoolWithTag(PagedPool, LenBasicInformation, TAG_IO_RESOURCE);
   }

   /* Deallocate the old Buffer */
   ExFreePool(FullInformation);

   /* Try to find a Bus */
   for (BusLoop = 0; NT_SUCCESS(Status); BusLoop++)
   {
      /* Bus parameter was passed and number was matched */
      if ((Query->BusNumber) && (*(Query->BusNumber)) == *Bus) break;

      /* Enumerate the Key */
      Status = ZwEnumerateKey(
         RootKeyHandle,
         BusLoop,
         KeyBasicInformation,
         BasicInformation,
         LenBasicInformation,
         &LenKey);

      /* Everything enumerated */
      if (!NT_SUCCESS(Status)) break;

      /* What Bus are we going to go down? (only check if this is a Root Key) */
      if (KeyIsRoot)
      {
         if (wcsncmp(BasicInformation->Name, L"MultifunctionAdapter", BasicInformation->NameLength / 2) &&
             wcsncmp(BasicInformation->Name, L"EisaAdapter", BasicInformation->NameLength / 2) &&
             wcsncmp(BasicInformation->Name, L"TcAdapter", BasicInformation->NameLength / 2))
         {
            /* Nothing found, check next */
            continue;
         }
      }

      /* Enumerate the Bus. */
      BusString.Buffer = BasicInformation->Name;
      BusString.Length = (USHORT)BasicInformation->NameLength;
      BusString.MaximumLength = (USHORT)BasicInformation->NameLength;

      /* Open a handle to the Root Registry Key */
      InitializeObjectAttributes(
         &ObjectAttributes,
         &BusString,
         OBJ_CASE_INSENSITIVE,
         RootKeyHandle,
         NULL);

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

      /* Go on if we can't */
      if (!NT_SUCCESS(Status)) continue;

      /* Key opened. Create the path */
      SubRootRegName = RootKey;
      RtlAppendUnicodeToString(&SubRootRegName, L"\\");
      RtlAppendUnicodeStringToString(&SubRootRegName, &BusString);

      if (!KeyIsRoot)
      {
         /* Parsing a SubBus-key */
         int SubBusLoop;
         PWSTR Strings[3] = {
            L"Identifier",
            L"Configuration Data",
            L"Component Information"};

         for (SubBusLoop = 0; SubBusLoop < 3; SubBusLoop++)
         {
            /* Identifier String First */
            RtlInitUnicodeString(&SubBusString, Strings[SubBusLoop]);

            /* How much buffer space */
            ZwQueryValueKey(SubRootKeyHandle, &SubBusString, KeyValueFullInformation, NULL, 0, &LenKeyFullInformation);

            /* Allocate it */
            BusInformation[SubBusLoop] = ExAllocatePoolWithTag(PagedPool, LenKeyFullInformation, TAG_IO_RESOURCE);

            /* Get the Information */
            Status = ZwQueryValueKey(SubRootKeyHandle, &SubBusString, KeyValueFullInformation, BusInformation[SubBusLoop], LenKeyFullInformation, &LenKeyFullInformation);
         }

         if (NT_SUCCESS(Status))
         {
            /* Do we have something */
            if (BusInformation[1] != NULL &&
                BusInformation[1]->DataLength != 0 &&
                /* Does it match what we want? */
                (((PCM_FULL_RESOURCE_DESCRIPTOR)((ULONG_PTR)BusInformation[1] + BusInformation[1]->DataOffset))->InterfaceType == *(Query->BusType)))
            {
               /* Found a bus */
               (*Bus)++;

               /* Is it the bus we wanted */
               if (Query->BusNumber == NULL || *(Query->BusNumber) == *Bus)
               {
                  /* If we don't want Controller Information, we're done... call the callback */
                  if (Query->ControllerType == NULL)
                  {
                     Status = Query->CalloutRoutine(
                        Query->Context,
                        &SubRootRegName,
                        *(Query->BusType),
                        *Bus,
                        BusInformation,
                        0,
                        0,
                        NULL,
                        0,
                        0,
                        NULL);
                  } else {
                     /* We want Controller Info...get it */
                     Status = IopQueryDeviceDescription(Query, SubRootRegName, RootKeyHandle, *Bus, (PKEY_VALUE_FULL_INFORMATION*)BusInformation);
                  }
               }
            }
         }

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

         /* Exit the Loop if we found the bus */
         if (Query->BusNumber != NULL && *(Query->BusNumber) == *Bus)
         {
            ZwClose(SubRootKeyHandle);
            SubRootKeyHandle = NULL;
            continue;
         }
      }

      /* Enumerate the buses below us recursively if we haven't found the bus yet */
      Status = IopQueryBusDescription(Query, SubRootRegName, SubRootKeyHandle, Bus, !KeyIsRoot);

      /* Everything enumerated */
      if (Status == STATUS_NO_MORE_ENTRIES) Status = STATUS_SUCCESS;

      ZwClose(SubRootKeyHandle);
      SubRootKeyHandle = NULL;
   }

   /* Free the last remaining Allocated Memory */
   if (BasicInformation)
      ExFreePool(BasicInformation);

   return Status;
}

/* PUBLIC FUNCTIONS ***********************************************************/

/*
 * @implemented
 */
PCONFIGURATION_INFORMATION STDCALL
IoGetConfigurationInformation(VOID)
{
  return(&_SystemConfigurationInformation);
}

/*
 * @unimplemented
 */
NTSTATUS STDCALL
IoReportResourceUsage(PUNICODE_STRING DriverClassName,
		      PDRIVER_OBJECT DriverObject,
		      PCM_RESOURCE_LIST DriverList,
		      ULONG DriverListSize,
		      PDEVICE_OBJECT DeviceObject,
		      PCM_RESOURCE_LIST DeviceList,
		      ULONG DeviceListSize,
		      BOOLEAN OverrideConflict,
		      PBOOLEAN ConflictDetected)
     /*
      * FUNCTION: Reports hardware resources in the
      * \Registry\Machine\Hardware\ResourceMap tree, so that a subsequently
      * loaded driver cannot attempt to use the same resources.
      * ARGUMENTS:
      *       DriverClassName - The class of driver under which the resource
      *       information should be stored.
      *       DriverObject - The driver object that was input to the
      *       DriverEntry.
      *       DriverList - Resources that claimed for the driver rather than
      *       per-device.
      *       DriverListSize - Size in bytes of the DriverList.
      *       DeviceObject - The device object for which resources should be
      *       claimed.
      *       DeviceList - List of resources which should be claimed for the
      *       device.
      *       DeviceListSize - Size of the per-device resource list in bytes.
      *       OverrideConflict - True if the resources should be cliamed
      *       even if a conflict is found.
      *       ConflictDetected - Points to a variable that receives TRUE if
      *       a conflict is detected with another driver.
      */
{
   UNIMPLEMENTED;
   *ConflictDetected = FALSE;
   return STATUS_SUCCESS;
}

/*
 * @unimplemented
 */
NTSTATUS STDCALL
IoAssignResources(PUNICODE_STRING RegistryPath,
		  PUNICODE_STRING DriverClassName,
		  PDRIVER_OBJECT DriverObject,
		  PDEVICE_OBJECT DeviceObject,
		  PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources,
		  PCM_RESOURCE_LIST* AllocatedResources)
{
   UNIMPLEMENTED;
   return(STATUS_NOT_IMPLEMENTED);
}

/*
 * FUNCTION:
 *     Reads and returns Hardware information from the appropriate hardware registry key.
 *
 * ARGUMENTS:
 *     BusType          - MCA, ISA, EISA...specifies the Bus Type
 *     BusNumber	- Which bus of above should be queried
 *     ControllerType	- Specifices the Controller Type
 *     ControllerNumber	- Which of the controllers to query.
 *     CalloutRoutine	- Which function to call for each valid query.
 *     Context          - Value to pass to the callback.
 *
 * RETURNS:
 *     Status
 *
 * STATUS:
 *     @implemented
 */

NTSTATUS NTAPI
IoQueryDeviceDescription(PINTERFACE_TYPE BusType OPTIONAL,
			 PULONG BusNumber OPTIONAL,
			 PCONFIGURATION_TYPE ControllerType OPTIONAL,
			 PULONG ControllerNumber OPTIONAL,
			 PCONFIGURATION_TYPE PeripheralType OPTIONAL,
			 PULONG PeripheralNumber OPTIONAL,
			 PIO_QUERY_DEVICE_ROUTINE CalloutRoutine,
			 PVOID Context)
{
   NTSTATUS Status;
   ULONG BusLoopNumber = -1; /* Root Bus */
   OBJECT_ATTRIBUTES ObjectAttributes;
   UNICODE_STRING RootRegKey;
   HANDLE RootRegHandle;
   WCHAR RootRegString[] = L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM";
   IO_QUERY Query;

   /* Set up the String */
   RootRegKey.Length = 0;
   RootRegKey.MaximumLength = 2048;
   RootRegKey.Buffer = ExAllocatePoolWithTag(PagedPool, RootRegKey.MaximumLength, TAG_IO_RESOURCE);
   RtlAppendUnicodeToString(&RootRegKey, RootRegString);

   /* Open a handle to the Root Registry Key */
   InitializeObjectAttributes(
      &ObjectAttributes,
      &RootRegKey,
      OBJ_CASE_INSENSITIVE,
      NULL,
      NULL);

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

   if (NT_SUCCESS(Status))
   {
      /* Use a helper function to loop though this key and get the info */
      Query.BusType = BusType;
      Query.BusNumber = BusNumber;
      Query.ControllerType = ControllerType;
      Query.ControllerNumber = ControllerNumber;
      Query.PeripheralType = PeripheralType;
      Query.PeripheralNumber = PeripheralNumber;
      Query.CalloutRoutine = CalloutRoutine;
      Query.Context = Context;
      Status = IopQueryBusDescription(&Query, RootRegKey, RootRegHandle, &BusLoopNumber, TRUE);

      /* Close registry */
      ZwClose(RootRegHandle);
   }

   /* Free Memory */
   ExFreePool(RootRegKey.Buffer);

   return Status;
}

/*
 * @implemented
 */
NTSTATUS STDCALL
IoReportHalResourceUsage(PUNICODE_STRING HalDescription,
			 PCM_RESOURCE_LIST RawList,
			 PCM_RESOURCE_LIST TranslatedList,
			 ULONG ListSize)
/*
 * FUNCTION:
 *      Reports hardware resources of the HAL in the
 *      \Registry\Machine\Hardware\ResourceMap tree.
 * ARGUMENTS:
 *      HalDescription: Descriptive name of the HAL.
 *      RawList: List of raw (bus specific) resources which should be
 *               claimed for the HAL.
 *      TranslatedList: List of translated (system wide) resources which
 *                      should be claimed for the HAL.
 *      ListSize: Size in bytes of the raw and translated resource lists.
 *                Both lists have the same size.
 * RETURNS:
 *      Status.
 */
{
  OBJECT_ATTRIBUTES ObjectAttributes;
  UNICODE_STRING Name;
  ULONG Disposition;
  NTSTATUS Status;
  HANDLE ResourcemapKey;
  HANDLE HalKey;
  HANDLE DescriptionKey;

  /* Open/Create 'RESOURCEMAP' key. */
  RtlInitUnicodeString(&Name,
		       L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
  InitializeObjectAttributes(&ObjectAttributes,
			     &Name,
			     OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
			     0,
			     NULL);
  Status = ZwCreateKey(&ResourcemapKey,
		       KEY_ALL_ACCESS,
		       &ObjectAttributes,
		       0,
		       NULL,
		       REG_OPTION_VOLATILE,
		       &Disposition);
  if (!NT_SUCCESS(Status))
    return(Status);

  /* Open/Create 'Hardware Abstraction Layer' key */
  RtlInitUnicodeString(&Name,
		       L"Hardware Abstraction Layer");
  InitializeObjectAttributes(&ObjectAttributes,
			     &Name,
			     OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
			     ResourcemapKey,
			     NULL);
  Status = ZwCreateKey(&HalKey,
		       KEY_ALL_ACCESS,
		       &ObjectAttributes,
		       0,
		       NULL,
		       REG_OPTION_VOLATILE,
		       &Disposition);
  ZwClose(ResourcemapKey);
  if (!NT_SUCCESS(Status))
      return(Status);

  /* Create 'HalDescription' key */
  InitializeObjectAttributes(&ObjectAttributes,
			     HalDescription,
			     OBJ_CASE_INSENSITIVE,
			     HalKey,
			     NULL);
  Status = ZwCreateKey(&DescriptionKey,
		       KEY_ALL_ACCESS,
		       &ObjectAttributes,
		       0,
		       NULL,
		       REG_OPTION_VOLATILE,
		       &Disposition);
  ZwClose(HalKey);
  if (!NT_SUCCESS(Status))
    return(Status);

  /* Add '.Raw' value. */
  RtlInitUnicodeString(&Name,
		       L".Raw");
  Status = ZwSetValueKey(DescriptionKey,
			 &Name,
			 0,
			 REG_RESOURCE_LIST,
			 RawList,
			 ListSize);
  if (!NT_SUCCESS(Status))
    {
      ZwClose(DescriptionKey);
      return(Status);
    }

  /* Add '.Translated' value. */
  RtlInitUnicodeString(&Name,
		       L".Translated");
  Status = ZwSetValueKey(DescriptionKey,
			 &Name,
			 0,
			 REG_RESOURCE_LIST,
			 TranslatedList,
			 ListSize);
  ZwClose(DescriptionKey);

  return(Status);
}

/* EOF */

⌨️ 快捷键说明

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