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

📄 partlist.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
		return STATUS_UNSUCCESSFUL;*/

	for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
	{
		if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific ||
			FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize != sizeof(CM_DISK_GEOMETRY_DEVICE_DATA))
			continue;

		DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1];
		BiosDiskEntry->DiskGeometry = *DiskGeometry;

		return STATUS_SUCCESS;
	}
	return STATUS_UNSUCCESSFUL;
}

NTSTATUS
NTAPI
SystemConfigurationDataQueryRoutine(PWSTR ValueName,
                                    ULONG ValueType,
                                    PVOID ValueData,
                                    ULONG ValueLength,
                                    PVOID Context,
                                    PVOID EntryContext)
{
	PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
	PCM_INT13_DRIVE_PARAMETER* Int13Drives = (PCM_INT13_DRIVE_PARAMETER*)Context;
	ULONG i;

	if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR ||
		ValueLength < sizeof (CM_FULL_RESOURCE_DESCRIPTOR))
		return STATUS_UNSUCCESSFUL;

	FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
	/* Hm. Version and Revision are not set on Microsoft Windows XP... */
	/*if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
		FullResourceDescriptor->PartialResourceList.Revision != 1)
		return STATUS_UNSUCCESSFUL;*/

	for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
	{
		if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific ||
			FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize % sizeof(CM_INT13_DRIVE_PARAMETER) != 0)
			continue;

		*Int13Drives = (CM_INT13_DRIVE_PARAMETER*) RtlAllocateHeap(ProcessHeap, 0, FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
		if (*Int13Drives == NULL)
			return STATUS_NO_MEMORY;
		memcpy(
			*Int13Drives,
			&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1],
			FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
		return STATUS_SUCCESS;
	}
	return STATUS_UNSUCCESSFUL;
}
#define ROOT_NAME   L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"

static VOID
EnumerateBiosDiskEntries(PPARTLIST PartList)
{
  RTL_QUERY_REGISTRY_TABLE QueryTable[3];
  WCHAR Name[120];
  ULONG AdapterCount;
  ULONG DiskCount;
  NTSTATUS Status;
  PCM_INT13_DRIVE_PARAMETER Int13Drives;
  PBIOSDISKENTRY BiosDiskEntry;

  memset(QueryTable, 0, sizeof(QueryTable));

  QueryTable[1].Name = L"Configuration Data";
  QueryTable[1].QueryRoutine = SystemConfigurationDataQueryRoutine;
  Int13Drives = NULL;
  Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
                                  L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
                                  &QueryTable[1],
                                  (PVOID)&Int13Drives,
                                  NULL);
  if (!NT_SUCCESS(Status))
    {
      DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status);
      return;
    }

  AdapterCount = 0;
  while (1)
    {
      swprintf(Name, L"%s\\%lu", ROOT_NAME, AdapterCount);
      Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
                                      Name,
                                      &QueryTable[2],
                                      NULL,
                                      NULL);
      if (!NT_SUCCESS(Status))
        {
          break;
        }

      swprintf(Name, L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount);
      Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
                                      Name,
                                      &QueryTable[2],
                                      NULL,
                                      NULL);
      if (NT_SUCCESS(Status))
        {
          while (1)
            {
              swprintf(Name, L"%s\\%lu\\DiskController\\0", ROOT_NAME, AdapterCount);
              Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
                                              Name,
                                              &QueryTable[2],
                                              NULL,
                                              NULL);
              if (!NT_SUCCESS(Status))
                {
                  RtlFreeHeap(ProcessHeap, 0, Int13Drives);
                  return;
                }

              swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral", ROOT_NAME, AdapterCount);
              Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
                                              Name,
                                              &QueryTable[2],
                                              NULL,
                                              NULL);
              if (NT_SUCCESS(Status))
                {
                  QueryTable[0].Name = L"Identifier";
                  QueryTable[0].QueryRoutine = DiskIdentifierQueryRoutine;
                  QueryTable[1].Name = L"Configuration Data";
                  QueryTable[1].QueryRoutine = DiskConfigurationDataQueryRoutine;
                  DiskCount = 0;
                  while (1)
                    {
                      BiosDiskEntry = (BIOSDISKENTRY*) RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY));
                      if (BiosDiskEntry == NULL)
                        {
                          break;
                        }
                      swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, DiskCount);
                      Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
                                                      Name,
                                                      QueryTable,
                                                      (PVOID)BiosDiskEntry,
                                                      NULL);
                      if (!NT_SUCCESS(Status))
                        {
                          RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
                          break;
                        }
                      BiosDiskEntry->DiskNumber = DiskCount;
                      BiosDiskEntry->Recognized = FALSE;

                      if (DiskCount < Int13Drives[0].NumberDrives)
                        {
                          BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount];
                        }
                      else
                        {
                          DPRINT1("Didn't find int13 drive datas for disk %u\n", DiskCount);
                        }


                      InsertTailList(&PartList->BiosDiskListHead, &BiosDiskEntry->ListEntry);

                      DPRINT("DiskNumber:        %lu\n", BiosDiskEntry->DiskNumber);
                      DPRINT("Signature:         %08lx\n", BiosDiskEntry->Signature);
                      DPRINT("Checksum:          %08lx\n", BiosDiskEntry->Checksum);
                      DPRINT("BytesPerSector:    %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector);
                      DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders);
                      DPRINT("NumberOfHeads:     %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads);
                      DPRINT("DriveSelect:       %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect);
                      DPRINT("MaxCylinders:      %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders);
                      DPRINT("SectorsPerTrack:   %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack);
                      DPRINT("MaxHeads:          %d\n", BiosDiskEntry->Int13DiskData.MaxHeads);
                      DPRINT("NumberDrives:      %d\n", BiosDiskEntry->Int13DiskData.NumberDrives);

                      DiskCount++;
                    }
                }
              RtlFreeHeap(ProcessHeap, 0, Int13Drives);
              return;
            }
        }
      AdapterCount++;
    }
  RtlFreeHeap(ProcessHeap, 0, Int13Drives);
}

static VOID
AddDiskToList (HANDLE FileHandle,
	       ULONG DiskNumber,
	       PPARTLIST List)
{
  DRIVE_LAYOUT_INFORMATION *LayoutBuffer;
  DISK_GEOMETRY DiskGeometry;
  SCSI_ADDRESS ScsiAddress;
  PDISKENTRY DiskEntry;
  IO_STATUS_BLOCK Iosb;
  NTSTATUS Status;
  PPARTITION_SECTOR Mbr;
  PULONG Buffer;
  LARGE_INTEGER FileOffset;
  WCHAR Identifier[20];
  ULONG Checksum;
  ULONG Signature;
  ULONG i;
  PLIST_ENTRY ListEntry;
  PBIOSDISKENTRY BiosDiskEntry;

  Status = NtDeviceIoControlFile (FileHandle,
				  NULL,
				  NULL,
				  NULL,
				  &Iosb,
				  IOCTL_DISK_GET_DRIVE_GEOMETRY,
				  NULL,
				  0,
				  &DiskGeometry,
				  sizeof(DISK_GEOMETRY));
  if (!NT_SUCCESS (Status))
    {
      return;
    }

  if (DiskGeometry.MediaType != FixedMedia)
    {
      return;
    }

  Status = NtDeviceIoControlFile (FileHandle,
				  NULL,
				  NULL,
				  NULL,
				  &Iosb,
				  IOCTL_SCSI_GET_ADDRESS,
				  NULL,
				  0,
				  &ScsiAddress,
				  sizeof(SCSI_ADDRESS));
  if (!NT_SUCCESS(Status))
    {
      return;
    }

  Mbr = (PARTITION_SECTOR*) RtlAllocateHeap(ProcessHeap,
                        0,
                        DiskGeometry.BytesPerSector);

  if (Mbr == NULL)
    {
      return;
    }

  FileOffset.QuadPart = 0;
  Status = NtReadFile(FileHandle,
                      NULL,
                      NULL,
                      NULL,
                      &Iosb,
                      (PVOID)Mbr,
                      DiskGeometry.BytesPerSector,
                      &FileOffset,
                      NULL);
  if (!NT_SUCCESS(Status))
    {
      RtlFreeHeap(ProcessHeap,
                  0,
                  Mbr);
      DPRINT1("NtReadFile failed, status=%x\n", Status);
      return;
    }
  Signature = Mbr->Signature;

  /* Calculate the MBR checksum */
  Checksum = 0;
  Buffer = (PULONG)Mbr;
  for (i = 0; i < 128; i++)
    {
      Checksum += Buffer[i];
    }
  Checksum = ~Checksum + 1;

  RtlFreeHeap (ProcessHeap,
	       0,
	       Mbr);

  swprintf(Identifier, L"%08x-%08x-A", Checksum, Signature);
  DPRINT("Identifier: %S\n", Identifier);

  DiskEntry = (PDISKENTRY)RtlAllocateHeap (ProcessHeap,
					   0,
					   sizeof(DISKENTRY));
  if (DiskEntry == NULL)
    {
      return;
    }

  DiskEntry->Checksum = Checksum;
  DiskEntry->Signature = Signature;
  if (Signature == 0)
    {
      /* If we have no signature, set the disk to dirty. WritePartitionsToDisk creates a new signature */
      DiskEntry->Modified = TRUE;
    }
  DiskEntry->BiosFound = FALSE;

  ListEntry = List->BiosDiskListHead.Flink;
  while(ListEntry != &List->BiosDiskListHead)
  {
     BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
     /* FIXME:
      *   Compare the size from bios and the reported size from driver.
      *   If we have more than one disk with a zero or with the same signatur
      *   we must create new signatures and reboot. After the reboot,
      *   it is possible to identify the disks.
      */
     if (BiosDiskEntry->Signature == Signature &&
         BiosDiskEntry->Checksum == Checksum &&
         !BiosDiskEntry->Recognized)
     {
        if (!DiskEntry->BiosFound)
        {
           DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber;
           DiskEntry->BiosFound = TRUE;
           BiosDiskEntry->Recognized = TRUE;
        }
        else
        {
        }
     }
     ListEntry = ListEntry->Flink;
  }

  if (!DiskEntry->BiosFound)
  {
     RtlFreeHeap(ProcessHeap, 0, DiskEntry);
     return;
  }

  InitializeListHead (&DiskEntry->PartListHead);

  DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
  DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
  DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
  DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;

  DPRINT ("Cylinders %d\n", DiskEntry->Cylinders);
  DPRINT ("TracksPerCylinder %d\n", DiskEntry->TracksPerCylinder);
  DPRINT ("SectorsPerTrack %d\n", DiskEntry->SectorsPerTrack);
  DPRINT ("BytesPerSector %d\n", DiskEntry->BytesPerSector);

  DiskEntry->DiskSize =
    DiskGeometry.Cylinders.QuadPart *
    (ULONGLONG)DiskGeometry.TracksPerCylinder *
    (ULONGLONG)DiskGeometry.SectorsPerTrack *
    (ULONGLONG)DiskGeometry.BytesPerSector;
  DiskEntry->CylinderSize =
    (ULONGLONG)DiskGeometry.TracksPerCylinder *
    (ULONGLONG)DiskGeometry.SectorsPerTrack *
    (ULONGLONG)DiskGeometry.BytesPerSector;
  DiskEntry->TrackSize =
    (ULONGLONG)DiskGeometry.SectorsPerTrack *
    (ULONGLONG)DiskGeometry.BytesPerSector;

  DiskEntry->DiskNumber = DiskNumber;
  DiskEntry->Port = ScsiAddress.PortNumber;
  DiskEntry->Bus = ScsiAddress.PathId;
  DiskEntry->Id = ScsiAddress.TargetId;

  GetDriverName (DiskEntry);

  InsertAscendingList(&List->DiskListHead, DiskEntry, DISKENTRY, ListEntry, BiosDiskNumber);

  LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap (ProcessHeap,
							     0,
							     8192);
  if (LayoutBuffer == NULL)
    {
      return;
    }

  Status = NtDeviceIoControlFile (FileHandle,
				  NULL,
				  NULL,
				  NULL,
				  &Iosb,
				  IOCTL_DISK_GET_DRIVE_LAYOUT,
				  NULL,
				  0,
				  LayoutBuffer,
				  8192);
  if (NT_SUCCESS (Status))
    {
      if (LayoutBuffer->PartitionCount == 0)
	{
	  DiskEntry->NewDisk = TRUE;
	}

      AddPartitionToList (DiskNumber,
			  DiskEntry,
			  LayoutBuffer);

      ScanForUnpartitionedDiskSpace (DiskEntry);
    }

  RtlFreeHeap (ProcessHeap,
	       0,
	       LayoutBuffer);
}


PPARTLIST
CreatePartitionList (SHORT Left,
		     SHORT Top,
		     SHORT Right,
		     SHORT Bottom)
{
  PPARTLIST List;
  OBJECT_ATTRIBUTES ObjectAttributes;
  SYSTEM_DEVICE_INFORMATION Sdi;
  IO_STATUS_BLOCK Iosb;
  SIZE_T ReturnSize;
  NTSTATUS Status;
  ULONG DiskNumber;
  WCHAR Buffer[MAX_PATH];
  UNICODE_STRING Name;
  HANDLE FileHandle;

  List = (PPARTLIST)RtlAllocateHeap (ProcessHeap,
				     0,
				     sizeof (PARTLIST));
  if (List == NULL)
    return NULL;

  List->Left = Left;
  List->Top = Top;
  List->Right = Right;
  List->Bottom = Bottom;

  List->Line = 0;

  List->TopDisk = (ULONG)-1;
  List->TopPartition = (ULONG)-1;

  List->CurrentDisk = NULL;
  List->CurrentPartition = NULL;

  InitializeListHead (&List->DiskListHead);
  InitializeListHead (&List->BiosDiskListHead);

  EnumerateBiosDiskEntries(List);

  Status = NtQuerySystemInformation (SystemDeviceInformation,
				     &Sdi,
				     sizeof(SYSTEM_DEVICE_INFORMATION),
				     &ReturnSize);
  if (!NT_SUCCESS (Status))
    {
      RtlFreeHeap (ProcessHeap, 0, List);
      return NULL;
    }

  for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
    {
      swprintf (Buffer,
		L"\\Device\\Harddisk%d\\Partition0",
		DiskNumber);
      RtlInitUnicodeString (&Name,

⌨️ 快捷键说明

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