ReactOS  0.4.15-dev-1377-ga59cecd
partlist.c File Reference
#include "precomp.h"
#include <ntddscsi.h>
#include "partlist.h"
#include "fsrec.h"
#include "registry.h"
#include <debug.h>
#include <pshpack1.h>
#include <poppack.h>
Include dependency graph for partlist.c:

Go to the source code of this file.

Classes

struct  _REG_DISK_MOUNT_INFO
 

Macros

#define NDEBUG
 
#define ROOT_NAME   L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
 

Typedefs

typedef struct _REG_DISK_MOUNT_INFO REG_DISK_MOUNT_INFO
 
typedef struct _REG_DISK_MOUNT_INFOPREG_DISK_MOUNT_INFO
 

Functions

ULONGLONG AlignDown (IN ULONGLONG Value, IN ULONG Alignment)
 
ULONGLONG AlignUp (IN ULONGLONG Value, IN ULONG Alignment)
 
ULONGLONG RoundingDivide (IN ULONGLONG Dividend, IN ULONGLONG Divisor)
 
static VOID GetDriverName (IN PDISKENTRY DiskEntry)
 
static VOID AssignDriveLetters (IN PPARTLIST List)
 
static NTSTATUS NTAPI DiskIdentifierQueryRoutine (PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
 
static NTSTATUS NTAPI DiskConfigurationDataQueryRoutine (PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
 
static NTSTATUS NTAPI SystemConfigurationDataQueryRoutine (PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
 
static VOID EnumerateBiosDiskEntries (IN PPARTLIST PartList)
 
BOOLEAN IsSuperFloppy (IN PDISKENTRY DiskEntry)
 
static BOOLEAN InsertDiskRegion (IN PDISKENTRY DiskEntry, IN PPARTENTRY PartEntry, IN BOOLEAN LogicalPartition)
 
static PPARTENTRY CreateInsertBlankRegion (IN PDISKENTRY DiskEntry, IN OUT PLIST_ENTRY ListHead, IN ULONGLONG StartSector, IN ULONGLONG SectorCount, IN BOOLEAN LogicalSpace)
 
static BOOLEAN InitializePartitionEntry (IN OUT PPARTENTRY PartEntry, IN ULONGLONG SectorCount, IN BOOLEAN AutoCreate)
 
static VOID AddPartitionToDisk (IN ULONG DiskNumber, IN PDISKENTRY DiskEntry, IN ULONG PartitionIndex, IN BOOLEAN LogicalPartition)
 
static VOID ScanForUnpartitionedDiskSpace (IN PDISKENTRY DiskEntry)
 
static VOID SetDiskSignature (IN PPARTLIST List, IN PDISKENTRY DiskEntry)
 
static VOID UpdateDiskSignatures (IN PPARTLIST List)
 
static VOID UpdateHwDiskNumbers (IN PPARTLIST List)
 
static VOID AddDiskToList (IN HANDLE FileHandle, IN ULONG DiskNumber, IN PPARTLIST List)
 
static PDISKENTRY GetSystemDisk (IN PPARTLIST List)
 
BOOLEAN IsPartitionActive (IN PPARTENTRY PartEntry)
 
static PPARTENTRY GetActiveDiskPartition (IN PDISKENTRY DiskEntry)
 
PPARTLIST CreatePartitionList (VOID)
 
VOID DestroyPartitionList (IN PPARTLIST List)
 
PDISKENTRY GetDiskByBiosNumber (IN PPARTLIST List, IN ULONG HwDiskNumber)
 
PDISKENTRY GetDiskByNumber (IN PPARTLIST List, IN ULONG DiskNumber)
 
PDISKENTRY GetDiskBySCSI (IN PPARTLIST List, IN USHORT Port, IN USHORT Bus, IN USHORT Id)
 
PDISKENTRY GetDiskBySignature (IN PPARTLIST List, IN ULONG Signature)
 
PPARTENTRY GetPartition (IN PDISKENTRY DiskEntry, IN ULONG PartitionNumber)
 
BOOLEAN GetDiskOrPartition (IN PPARTLIST List, IN ULONG DiskNumber, IN ULONG PartitionNumber OPTIONAL, OUT PDISKENTRY *pDiskEntry, OUT PPARTENTRY *pPartEntry OPTIONAL)
 
PPARTENTRY SelectPartition (IN PPARTLIST List, IN ULONG DiskNumber, IN ULONG PartitionNumber)
 
PPARTENTRY GetNextPartition (IN PPARTLIST List, IN PPARTENTRY CurrentPart OPTIONAL)
 
PPARTENTRY GetPrevPartition (IN PPARTLIST List, IN PPARTENTRY CurrentPart OPTIONAL)
 
FORCEINLINE BOOLEAN IsEmptyLayoutEntry (IN PPARTITION_INFORMATION PartitionInfo)
 
FORCEINLINE BOOLEAN IsSamePrimaryLayoutEntry (IN PPARTITION_INFORMATION PartitionInfo, IN PDISKENTRY DiskEntry, IN PPARTENTRY PartEntry)
 
static ULONG GetPrimaryPartitionCount (IN PDISKENTRY DiskEntry)
 
static ULONG GetLogicalPartitionCount (IN PDISKENTRY DiskEntry)
 
static BOOLEAN ReAllocateLayoutBuffer (IN PDISKENTRY DiskEntry)
 
static VOID UpdateDiskLayout (IN PDISKENTRY DiskEntry)
 
static PPARTENTRY GetPrevUnpartitionedEntry (IN PPARTENTRY PartEntry)
 
static PPARTENTRY GetNextUnpartitionedEntry (IN PPARTENTRY PartEntry)
 
BOOLEAN CreatePrimaryPartition (IN PPARTLIST List, IN OUT PPARTENTRY PartEntry, IN ULONGLONG SectorCount, IN BOOLEAN AutoCreate)
 
static VOID AddLogicalDiskSpace (IN PDISKENTRY DiskEntry)
 
BOOLEAN CreateExtendedPartition (IN PPARTLIST List, IN OUT PPARTENTRY PartEntry, IN ULONGLONG SectorCount)
 
BOOLEAN CreateLogicalPartition (IN PPARTLIST List, IN OUT PPARTENTRY PartEntry, IN ULONGLONG SectorCount, IN BOOLEAN AutoCreate)
 
NTSTATUS DismountVolume (IN PPARTENTRY PartEntry)
 
BOOLEAN DeletePartition (IN PPARTLIST List, IN PPARTENTRY PartEntry, OUT PPARTENTRY *FreeRegion OPTIONAL)
 
static BOOLEAN IsSupportedActivePartition (IN PPARTENTRY PartEntry)
 
PPARTENTRY FindSupportedSystemPartition (IN PPARTLIST List, IN BOOLEAN ForceSelect, IN PDISKENTRY AlternativeDisk OPTIONAL, IN PPARTENTRY AlternativePart OPTIONAL)
 
BOOLEAN SetActivePartition (IN PPARTLIST List, IN PPARTENTRY PartEntry, IN PPARTENTRY OldActivePart OPTIONAL)
 
NTSTATUS WritePartitions (IN PDISKENTRY DiskEntry)
 
BOOLEAN WritePartitionsToDisk (IN PPARTLIST List)
 
BOOLEAN SetMountedDeviceValue (IN WCHAR Letter, IN ULONG Signature, IN LARGE_INTEGER StartingOffset)
 
BOOLEAN SetMountedDeviceValues (IN PPARTLIST List)
 
VOID SetMBRPartitionType (IN PPARTENTRY PartEntry, IN UCHAR PartitionType)
 
ERROR_NUMBER PrimaryPartitionCreationChecks (IN PPARTENTRY PartEntry)
 
ERROR_NUMBER ExtendedPartitionCreationChecks (IN PPARTENTRY PartEntry)
 
ERROR_NUMBER LogicalPartitionCreationChecks (IN PPARTENTRY PartEntry)
 
BOOLEAN GetNextUnformattedPartition (IN PPARTLIST List, OUT PDISKENTRY *pDiskEntry OPTIONAL, OUT PPARTENTRY *pPartEntry)
 
BOOLEAN GetNextUncheckedPartition (IN PPARTLIST List, OUT PDISKENTRY *pDiskEntry OPTIONAL, OUT PPARTENTRY *pPartEntry)
 

Variables

PARTITION_TYPE PartitionTypes [NUM_PARTITION_TYPE_ENTRIES]
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 16 of file partlist.c.

◆ ROOT_NAME

#define ROOT_NAME   L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"

Typedef Documentation

◆ PREG_DISK_MOUNT_INFO

◆ REG_DISK_MOUNT_INFO

Function Documentation

◆ AddDiskToList()

static VOID AddDiskToList ( IN HANDLE  FileHandle,
IN ULONG  DiskNumber,
IN PPARTLIST  List 
)
static

Definition at line 1485 of file partlist.c.

1489 {
1490  DISK_GEOMETRY DiskGeometry;
1491  SCSI_ADDRESS ScsiAddress;
1492  PDISKENTRY DiskEntry;
1494  NTSTATUS Status;
1495  PPARTITION_SECTOR Mbr;
1496  PULONG Buffer;
1498  WCHAR Identifier[20];
1499  ULONG Checksum;
1500  ULONG Signature;
1501  ULONG i;
1502  PLIST_ENTRY ListEntry;
1503  PBIOSDISKENTRY BiosDiskEntry;
1504  ULONG LayoutBufferSize;
1505  PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
1506 
1507  /* Retrieve the drive geometry */
1509  NULL,
1510  NULL,
1511  NULL,
1512  &Iosb,
1514  NULL,
1515  0,
1516  &DiskGeometry,
1517  sizeof(DiskGeometry));
1518  if (!NT_SUCCESS(Status))
1519  return;
1520 
1521  if (DiskGeometry.MediaType != FixedMedia &&
1522  DiskGeometry.MediaType != RemovableMedia)
1523  {
1524  return;
1525  }
1526 
1527  /*
1528  * FIXME: Here we suppose the disk is always SCSI. What if it is
1529  * of another type? To check this we need to retrieve the name of
1530  * the driver the disk device belongs to.
1531  */
1533  NULL,
1534  NULL,
1535  NULL,
1536  &Iosb,
1538  NULL,
1539  0,
1540  &ScsiAddress,
1541  sizeof(ScsiAddress));
1542  if (!NT_SUCCESS(Status))
1543  return;
1544 
1545  /*
1546  * Check whether the disk is initialized, by looking at its MBR.
1547  * NOTE that this must be generalized to GPT disks as well!
1548  */
1549 
1551  0,
1552  DiskGeometry.BytesPerSector);
1553  if (Mbr == NULL)
1554  return;
1555 
1556  FileOffset.QuadPart = 0;
1558  NULL,
1559  NULL,
1560  NULL,
1561  &Iosb,
1562  (PVOID)Mbr,
1563  DiskGeometry.BytesPerSector,
1564  &FileOffset,
1565  NULL);
1566  if (!NT_SUCCESS(Status))
1567  {
1568  RtlFreeHeap(ProcessHeap, 0, Mbr);
1569  DPRINT1("NtReadFile failed, status=%x\n", Status);
1570  return;
1571  }
1572  Signature = Mbr->Signature;
1573 
1574  /* Calculate the MBR checksum */
1575  Checksum = 0;
1576  Buffer = (PULONG)Mbr;
1577  for (i = 0; i < 128; i++)
1578  {
1579  Checksum += Buffer[i];
1580  }
1581  Checksum = ~Checksum + 1;
1582 
1583  RtlStringCchPrintfW(Identifier, ARRAYSIZE(Identifier),
1584  L"%08x-%08x-%c",
1585  Checksum, Signature,
1586  (Mbr->Magic == PARTITION_MAGIC) ? L'A' : L'X');
1587  DPRINT("Identifier: %S\n", Identifier);
1588 
1589  DiskEntry = RtlAllocateHeap(ProcessHeap,
1591  sizeof(DISKENTRY));
1592  if (DiskEntry == NULL)
1593  {
1594  RtlFreeHeap(ProcessHeap, 0, Mbr);
1595  DPRINT1("Failed to allocate a new disk entry.\n");
1596  return;
1597  }
1598 
1599  DiskEntry->PartList = List;
1600 
1601 #if 0
1602  {
1603  FILE_FS_DEVICE_INFORMATION FileFsDevice;
1604 
1605  /* Query the device for its type */
1607  &Iosb,
1608  &FileFsDevice,
1609  sizeof(FileFsDevice),
1611  if (!NT_SUCCESS(Status))
1612  {
1613  DPRINT1("Couldn't detect device type for disk %lu of identifier '%S'...\n", DiskNumber, Identifier);
1614  }
1615  else
1616  {
1617  DPRINT1("Disk %lu : DeviceType: 0x%08x ; Characteristics: 0x%08x\n", DiskNumber, FileFsDevice.DeviceType, FileFsDevice.Characteristics);
1618  }
1619  }
1620  // NOTE: We may also use NtQueryVolumeInformationFile(FileFsDeviceInformation).
1621 #endif
1622  DiskEntry->MediaType = DiskGeometry.MediaType;
1623  if (DiskEntry->MediaType == RemovableMedia)
1624  {
1625  DPRINT1("Disk %lu of identifier '%S' is removable\n", DiskNumber, Identifier);
1626  }
1627  else // if (DiskEntry->MediaType == FixedMedia)
1628  {
1629  DPRINT1("Disk %lu of identifier '%S' is fixed\n", DiskNumber, Identifier);
1630  }
1631 
1632 // DiskEntry->Checksum = Checksum;
1633 // DiskEntry->Signature = Signature;
1634  DiskEntry->BiosFound = FALSE;
1635 
1636  /*
1637  * Check if this disk has a valid MBR: verify its signature,
1638  * and whether its two first bytes are a valid instruction
1639  * (related to this, see IsThereAValidBootSector() in partlist.c).
1640  *
1641  * See also ntoskrnl/fstub/fstubex.c!FstubDetectPartitionStyle().
1642  */
1643 
1644  // DiskEntry->NoMbr = (Mbr->Magic != PARTITION_MAGIC || (*(PUSHORT)Mbr->BootCode) == 0x0000);
1645 
1646  /* If we have not the 0xAA55 then it's raw partition */
1647  if (Mbr->Magic != PARTITION_MAGIC)
1648  {
1649  DiskEntry->DiskStyle = PARTITION_STYLE_RAW;
1650  }
1651  /* Check partitions types: if first is 0xEE and all the others 0, we have GPT */
1652  else if (Mbr->Partition[0].PartitionType == EFI_PMBR_OSTYPE_EFI &&
1653  Mbr->Partition[1].PartitionType == 0 &&
1654  Mbr->Partition[2].PartitionType == 0 &&
1655  Mbr->Partition[3].PartitionType == 0)
1656  {
1657  DiskEntry->DiskStyle = PARTITION_STYLE_GPT;
1658  }
1659  /* Otherwise, partition table is in MBR */
1660  else
1661  {
1662  DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
1663  }
1664 
1665  /* Free the MBR sector buffer */
1666  RtlFreeHeap(ProcessHeap, 0, Mbr);
1667 
1668 
1669  for (ListEntry = List->BiosDiskListHead.Flink;
1670  ListEntry != &List->BiosDiskListHead;
1671  ListEntry = ListEntry->Flink)
1672  {
1673  BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
1674  /* FIXME:
1675  * Compare the size from bios and the reported size from driver.
1676  * If we have more than one disk with a zero or with the same signature
1677  * we must create new signatures and reboot. After the reboot,
1678  * it is possible to identify the disks.
1679  */
1680  if (BiosDiskEntry->Signature == Signature &&
1681  BiosDiskEntry->Checksum == Checksum &&
1682  BiosDiskEntry->DiskEntry == NULL)
1683  {
1684  if (!DiskEntry->BiosFound)
1685  {
1686  DiskEntry->HwAdapterNumber = BiosDiskEntry->AdapterNumber;
1687  DiskEntry->HwControllerNumber = BiosDiskEntry->ControllerNumber;
1688  DiskEntry->HwDiskNumber = BiosDiskEntry->DiskNumber;
1689 
1690  if (DiskEntry->MediaType == RemovableMedia)
1691  {
1692  /* Set the removable disk number to zero */
1693  DiskEntry->HwFixedDiskNumber = 0;
1694  }
1695  else // if (DiskEntry->MediaType == FixedMedia)
1696  {
1697  /* The fixed disk number will later be adjusted using the number of removable disks */
1698  DiskEntry->HwFixedDiskNumber = BiosDiskEntry->DiskNumber;
1699  }
1700 
1701  DiskEntry->BiosFound = TRUE;
1702  BiosDiskEntry->DiskEntry = DiskEntry;
1703  break;
1704  }
1705  else
1706  {
1707  // FIXME: What to do?
1708  DPRINT1("Disk %lu of identifier '%S' has already been found?!\n", DiskNumber, Identifier);
1709  }
1710  }
1711  }
1712 
1713  if (!DiskEntry->BiosFound)
1714  {
1715  DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %lu may not be bootable by the BIOS!\n", DiskNumber);
1716  }
1717 
1718  DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
1719  DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
1720  DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
1721  DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
1722 
1723  DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders);
1724  DPRINT("TracksPerCylinder %lu\n", DiskEntry->TracksPerCylinder);
1725  DPRINT("SectorsPerTrack %lu\n", DiskEntry->SectorsPerTrack);
1726  DPRINT("BytesPerSector %lu\n", DiskEntry->BytesPerSector);
1727 
1728  DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart *
1729  (ULONGLONG)DiskGeometry.TracksPerCylinder *
1730  (ULONGLONG)DiskGeometry.SectorsPerTrack;
1731 
1732  DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
1733  DiskEntry->CylinderAlignment = DiskGeometry.TracksPerCylinder *
1734  DiskGeometry.SectorsPerTrack;
1735 
1736  DPRINT("SectorCount %I64u\n", DiskEntry->SectorCount.QuadPart);
1737  DPRINT("SectorAlignment %lu\n", DiskEntry->SectorAlignment);
1738 
1739  DiskEntry->DiskNumber = DiskNumber;
1740  DiskEntry->Port = ScsiAddress.PortNumber;
1741  DiskEntry->Bus = ScsiAddress.PathId;
1742  DiskEntry->Id = ScsiAddress.TargetId;
1743 
1744  GetDriverName(DiskEntry);
1745  /*
1746  * Actually it would be more correct somehow to use:
1747  *
1748  * OBJECT_NAME_INFORMATION NameInfo; // ObjectNameInfo;
1749  * ULONG ReturnedLength;
1750  *
1751  * Status = NtQueryObject(SomeHandleToTheDisk,
1752  * ObjectNameInformation,
1753  * &NameInfo,
1754  * sizeof(NameInfo),
1755  * &ReturnedLength);
1756  * etc...
1757  *
1758  * See examples in https://git.reactos.org/?p=reactos.git;a=blob;f=reactos/ntoskrnl/io/iomgr/error.c;hb=2f3a93ee9cec8322a86bf74b356f1ad83fc912dc#l267
1759  */
1760 
1763 
1764  InsertAscendingList(&List->DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber);
1765 
1766 
1767  /*
1768  * We now retrieve the disk partition layout
1769  */
1770 
1771  /*
1772  * Stop there now if the disk is GPT-partitioned,
1773  * since we currently do not support such disks.
1774  */
1775  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1776  {
1777  DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1778  return;
1779  }
1780 
1781  /* Allocate a layout buffer with 4 partition entries first */
1782  LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
1783  ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
1786  LayoutBufferSize);
1787  if (DiskEntry->LayoutBuffer == NULL)
1788  {
1789  DPRINT1("Failed to allocate the disk layout buffer!\n");
1790  return;
1791  }
1792 
1793  /* Keep looping while the drive layout buffer is too small */
1794  for (;;)
1795  {
1796  DPRINT1("Buffer size: %lu\n", LayoutBufferSize);
1798  NULL,
1799  NULL,
1800  NULL,
1801  &Iosb,
1803  NULL,
1804  0,
1805  DiskEntry->LayoutBuffer,
1806  LayoutBufferSize);
1807  if (NT_SUCCESS(Status))
1808  break;
1809 
1811  {
1812  DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status);
1813  return;
1814  }
1815 
1816  LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION);
1817  NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap,
1819  DiskEntry->LayoutBuffer,
1820  LayoutBufferSize);
1821  if (NewLayoutBuffer == NULL)
1822  {
1823  DPRINT1("Failed to reallocate the disk layout buffer!\n");
1824  return;
1825  }
1826 
1827  DiskEntry->LayoutBuffer = NewLayoutBuffer;
1828  }
1829 
1830  DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount);
1831 
1832 #ifdef DUMP_PARTITION_TABLE
1833  DumpPartitionTable(DiskEntry);
1834 #endif
1835 
1836  if (IsSuperFloppy(DiskEntry))
1837  DPRINT1("Disk %lu is a super-floppy\n", DiskNumber);
1838 
1839  if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
1840  DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0 &&
1842  {
1843  if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
1844  {
1845  DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
1846  }
1847  else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
1848  {
1849  DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1850  }
1851  else
1852  {
1853  DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
1854  }
1855  }
1856  else
1857  {
1858  DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1859  }
1860 
1861  if (DiskEntry->LayoutBuffer->PartitionCount == 0)
1862  {
1863  DiskEntry->NewDisk = TRUE;
1864  DiskEntry->LayoutBuffer->PartitionCount = 4;
1865 
1866  for (i = 0; i < 4; i++)
1867  {
1869  }
1870  }
1871  else
1872  {
1873  /* Enumerate and add the first four primary partitions */
1874  for (i = 0; i < 4; i++)
1875  {
1876  AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
1877  }
1878 
1879  /* Enumerate and add the remaining partitions as logical ones */
1880  for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
1881  {
1882  AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
1883  }
1884  }
1885 
1886  ScanForUnpartitionedDiskSpace(DiskEntry);
1887 }
UCHAR PathId
Definition: scsi_port.h:149
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:143
struct _PARTLIST * PartList
Definition: partlist.h:98
UCHAR PortNumber
Definition: scsi_port.h:148
USHORT Id
Definition: partlist.h:127
LARGE_INTEGER PartitionLength
Definition: ntdddisk.h:469
#define IOCTL_SCSI_GET_ADDRESS
Definition: scsi_port.h:52
ULONG HwControllerNumber
Definition: partlist.h:116
ULONG CylinderAlignment
Definition: partlist.h:111
#define ANYSIZE_ARRAY
Definition: typedefs.h:46
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define TRUE
Definition: types.h:120
USHORT Bus
Definition: partlist.h:126
ULONG HwAdapterNumber
Definition: partlist.h:115
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
ULONG Checksum
Definition: partlist.h:158
ULONG Signature
Definition: partlist.h:157
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
ULONG ControllerNumber
Definition: partlist.h:155
ULONG DiskNumber
Definition: partlist.h:123
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
ULONG BytesPerSector
Definition: ntdddisk.h:442
ULONG TracksPerCylinder
Definition: ntdddisk.h:440
NTSYSAPI NTSTATUS NTAPI NtDeviceIoControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
struct _PARTITION_INFORMATION PARTITION_INFORMATION
UCHAR TargetId
Definition: scsi_port.h:150
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
HANDLE FileHandle
Definition: stats.c:38
static VOID GetDriverName(IN PDISKENTRY DiskEntry)
Definition: partlist.c:284
PARTITION_STYLE DiskStyle
Definition: partlist.h:133
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define FALSE
Definition: types.h:117
struct _DRIVE_LAYOUT_INFORMATION DRIVE_LAYOUT_INFORMATION
PARTITION_INFORMATION PartitionEntry[1]
Definition: ntdddisk.h:549
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
MEDIA_TYPE MediaType
Definition: partlist.h:100
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
ULARGE_INTEGER SectorCount
Definition: partlist.h:109
ULONG SectorAlignment
Definition: partlist.h:110
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
ULONG AdapterNumber
Definition: partlist.h:154
BOOLEAN BiosFound
Definition: partlist.h:114
ULONG BytesPerSector
Definition: partlist.h:107
#define EFI_PMBR_OSTYPE_EFI
Definition: partlist.h:187
__wchar_t WCHAR
Definition: xmlstorage.h:180
return Iosb
Definition: create.c:4402
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:468
uint64_t ULONGLONG
Definition: typedefs.h:67
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:438
ULONG SectorsPerTrack
Definition: ntdddisk.h:441
MEDIA_TYPE MediaType
Definition: ntdddisk.h:439
ULONG HwDiskNumber
Definition: partlist.h:117
unsigned char PartitionType
Definition: partlist.h:197
BOOLEAN RewritePartition
Definition: ntdddisk.h:475
static VOID ScanForUnpartitionedDiskSpace(IN PDISKENTRY DiskEntry)
Definition: partlist.c:1121
PDISKENTRY DiskEntry
Definition: partlist.h:159
static const WCHAR L[]
Definition: oid.c:1250
ULONG SectorsPerTrack
Definition: partlist.h:106
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
#define InsertAscendingList(ListHead, NewEntry, Type, ListEntryField, SortField)
Definition: partlist.c:17
ULONGLONG Cylinders
Definition: partlist.h:104
HANDLE ProcessHeap
Definition: servman.c:15
#define IOCTL_DISK_GET_DRIVE_LAYOUT
Definition: ntdddisk.h:91
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass)
BOOLEAN IsSuperFloppy(IN PDISKENTRY DiskEntry)
Definition: partlist.c:680
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
ULONG DiskNumber
Definition: partlist.h:156
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
PARTITION Partition[PARTITION_TBL_SIZE]
Definition: partlist.h:210
ULONG HwFixedDiskNumber
Definition: partlist.h:118
USHORT Port
Definition: partlist.h:125
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
ULONG TracksPerCylinder
Definition: partlist.h:105
#define DPRINT1
Definition: precomp.h:8
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:144
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2622
#define PARTITION_MAGIC
Definition: partlist.h:184
static const WCHAR Signature[]
Definition: parser.c:141
PDRIVE_LAYOUT_INFORMATION LayoutBuffer
Definition: partlist.h:137
BOOLEAN NewDisk
Definition: partlist.h:132
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
NTSTATUS NTAPI NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
LONGLONG QuadPart
Definition: typedefs.h:114
static VOID AddPartitionToDisk(IN ULONG DiskNumber, IN PDISKENTRY DiskEntry, IN ULONG PartitionIndex, IN BOOLEAN LogicalPartition)
Definition: partlist.c:930

Referenced by CreatePartitionList().

◆ AddLogicalDiskSpace()

static VOID AddLogicalDiskSpace ( IN PDISKENTRY  DiskEntry)
static

Definition at line 3002 of file partlist.c.

3004 {
3005  ULONGLONG StartSector;
3007  PPARTENTRY NewPartEntry;
3008 
3009  DPRINT1("AddLogicalDiskSpace()\n");
3010 
3011  /* Create a partition entry that represents the empty space in the container partition */
3012 
3013  StartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
3014  SectorCount = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
3015 
3016  NewPartEntry = CreateInsertBlankRegion(DiskEntry,
3017  &DiskEntry->LogicalPartListHead,
3018  StartSector,
3019  SectorCount,
3020  TRUE);
3021  if (NewPartEntry == NULL)
3022  {
3023  DPRINT1("Failed to create a new empty region for extended partition space!\n");
3024  return;
3025  }
3026 }
#define TRUE
Definition: types.h:120
static PPARTENTRY CreateInsertBlankRegion(IN PDISKENTRY DiskEntry, IN OUT PLIST_ENTRY ListHead, IN ULONGLONG StartSector, IN ULONGLONG SectorCount, IN BOOLEAN LogicalSpace)
Definition: partlist.c:819
uint64_t ULONGLONG
Definition: typedefs.h:67
ULONG SectorCount
Definition: part_xbox.c:31
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8

Referenced by CreateExtendedPartition().

◆ AddPartitionToDisk()

static VOID AddPartitionToDisk ( IN ULONG  DiskNumber,
IN PDISKENTRY  DiskEntry,
IN ULONG  PartitionIndex,
IN BOOLEAN  LogicalPartition 
)
static

Definition at line 930 of file partlist.c.

935 {
938  PPARTENTRY PartEntry;
939  HANDLE PartitionHandle;
942  WCHAR PathBuffer[MAX_PATH];
944  UCHAR LabelBuffer[sizeof(FILE_FS_VOLUME_INFORMATION) + 256 * sizeof(WCHAR)];
946 
947  PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
948 
949  if (PartitionInfo->PartitionType == PARTITION_ENTRY_UNUSED ||
950  ((LogicalPartition != FALSE) && IsContainerPartition(PartitionInfo->PartitionType)))
951  {
952  return;
953  }
954 
955  PartEntry = RtlAllocateHeap(ProcessHeap,
957  sizeof(PARTENTRY));
958  if (PartEntry == NULL)
959  return;
960 
961  PartEntry->DiskEntry = DiskEntry;
962 
963  PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
964  PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
965 
966  PartEntry->BootIndicator = PartitionInfo->BootIndicator;
967  PartEntry->PartitionType = PartitionInfo->PartitionType;
968 
969  PartEntry->LogicalPartition = LogicalPartition;
970  PartEntry->IsPartitioned = TRUE;
971  PartEntry->OnDiskPartitionNumber = PartitionInfo->PartitionNumber;
972  PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
973  PartEntry->PartitionIndex = PartitionIndex;
974 
975  /* Specify the partition as initially unformatted */
976  PartEntry->FormatState = Unformatted;
977  PartEntry->FileSystem[0] = L'\0';
978 
979  /* Initialize the partition volume label */
980  RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
981 
982  if (IsContainerPartition(PartEntry->PartitionType))
983  {
984  PartEntry->FormatState = Unformatted;
985 
986  if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
987  DiskEntry->ExtendedPartition = PartEntry;
988  }
989  else if (IsRecognizedPartition(PartEntry->PartitionType))
990  {
991  ASSERT(PartitionInfo->RecognizedPartition);
992  ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
993 
994  /* Try to open the volume so as to mount it */
995  RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
996  L"\\Device\\Harddisk%lu\\Partition%lu",
997  DiskEntry->DiskNumber,
998  PartEntry->PartitionNumber);
999  RtlInitUnicodeString(&Name, PathBuffer);
1000 
1002  &Name,
1004  NULL,
1005  NULL);
1006 
1007  PartitionHandle = NULL;
1008  Status = NtOpenFile(&PartitionHandle,
1011  &IoStatusBlock,
1014  if (!NT_SUCCESS(Status))
1015  {
1016  DPRINT1("NtOpenFile() failed, Status 0x%08lx\n", Status);
1017  }
1018 
1019  if (PartitionHandle)
1020  {
1022 
1023  /* We don't have a FS, try to guess one */
1024  Status = InferFileSystem(NULL, PartitionHandle,
1025  PartEntry->FileSystem,
1026  sizeof(PartEntry->FileSystem));
1027  if (!NT_SUCCESS(Status))
1028  DPRINT1("InferFileSystem() failed, Status 0x%08lx\n", Status);
1029  }
1030  if (*PartEntry->FileSystem)
1031  {
1032  ASSERT(PartitionHandle);
1033 
1034  /*
1035  * Handle partition mounted with RawFS: it is
1036  * either unformatted or has an unknown format.
1037  */
1038  if (wcsicmp(PartEntry->FileSystem, L"RAW") == 0)
1039  {
1040  /*
1041  * True unformatted partitions on NT are created with their
1042  * partition type set to either one of the following values,
1043  * and are mounted with RawFS. This is done this way since we
1044  * are assured to have FAT support, which is the only FS that
1045  * uses these partition types. Therefore, having a partition
1046  * mounted with RawFS and with these partition types means that
1047  * the FAT FS was unable to mount it beforehand and thus the
1048  * partition is unformatted.
1049  * However, any partition mounted by RawFS that does NOT have
1050  * any of these partition types must be considered as having
1051  * an unknown format.
1052  */
1053  if (PartEntry->PartitionType == PARTITION_FAT_12 ||
1054  PartEntry->PartitionType == PARTITION_FAT_16 ||
1055  PartEntry->PartitionType == PARTITION_HUGE ||
1056  PartEntry->PartitionType == PARTITION_XINT13 ||
1057  PartEntry->PartitionType == PARTITION_FAT32 ||
1058  PartEntry->PartitionType == PARTITION_FAT32_XINT13)
1059  {
1060  PartEntry->FormatState = Unformatted;
1061  }
1062  else
1063  {
1064  /* Close the partition before dismounting */
1065  NtClose(PartitionHandle);
1066  PartitionHandle = NULL;
1067  /*
1068  * Dismount the partition since RawFS owns it, and set its
1069  * format to unknown (may or may not be actually formatted).
1070  */
1071  DismountVolume(PartEntry);
1072  PartEntry->FormatState = UnknownFormat;
1073  PartEntry->FileSystem[0] = L'\0';
1074  }
1075  }
1076  else
1077  {
1078  PartEntry->FormatState = Preformatted;
1079  }
1080  }
1081  else
1082  {
1083  PartEntry->FormatState = UnknownFormat;
1084  }
1085 
1086  /* Retrieve the partition volume label */
1087  if (PartitionHandle)
1088  {
1089  Status = NtQueryVolumeInformationFile(PartitionHandle,
1090  &IoStatusBlock,
1091  &LabelBuffer,
1092  sizeof(LabelBuffer),
1094  if (NT_SUCCESS(Status))
1095  {
1096  /* Copy the (possibly truncated) volume label and NULL-terminate it */
1097  RtlStringCbCopyNW(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel),
1098  LabelInfo->VolumeLabel, LabelInfo->VolumeLabelLength);
1099  }
1100  else
1101  {
1102  DPRINT1("NtQueryVolumeInformationFile() failed, Status 0x%08lx\n", Status);
1103  }
1104  }
1105 
1106  /* Close the partition */
1107  if (PartitionHandle)
1108  NtClose(PartitionHandle);
1109  }
1110  else
1111  {
1112  /* Unknown partition, hence unknown format (may or may not be actually formatted) */
1113  PartEntry->FormatState = UnknownFormat;
1114  }
1115 
1116  InsertDiskRegion(DiskEntry, PartEntry, LogicalPartition);
1117 }
#define PARTITION_FAT32
Definition: disk.h:95
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
ULONG PartitionNumber
Definition: partlist.h:67
ULARGE_INTEGER StartSector
Definition: partlist.h:61
WCHAR VolumeLabel[20]
Definition: partlist.h:71
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define TRUE
Definition: types.h:120
ULARGE_INTEGER SectorCount
Definition: partlist.h:62
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:316
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
NTSTATUS InferFileSystem(IN PCWSTR PartitionPath OPTIONAL, IN HANDLE PartitionHandle OPTIONAL, IN OUT PWSTR FileSystemName, IN SIZE_T FileSystemNameSize)
Definition: fsrec.c:269
#define FILE_SHARE_READ
Definition: compat.h:136
#define PARTITION_XINT13
Definition: disk.h:97
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
BOOLEAN LogicalPartition
Definition: partlist.h:75
NTSTATUS DismountVolume(IN PPARTENTRY PartEntry)
Definition: partlist.c:3119
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define FALSE
Definition: types.h:117
FORMATSTATE FormatState
Definition: partlist.h:73
#define PARTITION_HUGE
Definition: disk.h:92
#define FILE_READ_DATA
Definition: nt_native.h:628
NTSTRSAFEAPI RtlStringCbCopyNW(_Out_writes_bytes_(cbDest) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_reads_bytes_(cbToCopy) STRSAFE_LPCWSTR pszSrc, _In_ size_t cbToCopy)
Definition: ntstrsafe.h:416
struct NameRec_ * Name
Definition: cdprocs.h:459
static BOOLEAN InsertDiskRegion(IN PDISKENTRY DiskEntry, IN PPARTENTRY PartEntry, IN BOOLEAN LogicalPartition)
Definition: partlist.c:753
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
struct _FILE_FS_VOLUME_INFORMATION * PFILE_FS_VOLUME_INFORMATION
Status
Definition: gdiplustypes.h:24
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3951
UCHAR PartitionType
Definition: partlist.h:65
struct _DISKENTRY * DiskEntry
Definition: partlist.h:58
#define ASSERT(a)
Definition: mode.c:45
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:67
ULONG OnDiskPartitionNumber
Definition: partlist.h:66
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:342
#define MAX_PATH
Definition: compat.h:34
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2101
WCHAR FileSystem[MAX_PATH+1]
Definition: partlist.h:72
#define PARTITION_FAT_16
Definition: disk.h:90
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define wcsicmp
Definition: compat.h:15
unsigned char UCHAR
Definition: xmlstorage.h:181
static const WCHAR L[]
Definition: oid.c:1250
#define SYNCHRONIZE
Definition: nt_native.h:61
HANDLE ProcessHeap
Definition: servman.c:15
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass)
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define DPRINT1
Definition: precomp.h:8
BOOLEAN BootIndicator
Definition: partlist.h:64
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
struct _FILE_FS_VOLUME_INFORMATION FILE_FS_VOLUME_INFORMATION
#define PARTITION_FAT_12
Definition: disk.h:87
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define PARTITION_FAT32_XINT13
Definition: disk.h:96
BOOLEAN IsPartitioned
Definition: partlist.h:78
ULONG PartitionIndex
Definition: partlist.h:68

Referenced by AddDiskToList().

◆ AlignDown()

ULONGLONG AlignDown ( IN ULONGLONG  Value,
IN ULONG  Alignment 
)

Definition at line 246 of file partlist.c.

249 {
250  ULONGLONG Temp;
251 
252  Temp = Value / Alignment;
253 
254  return Temp * Alignment;
255 }
union Alignment_ Alignment
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by InitializePartitionEntry(), and ScanForUnpartitionedDiskSpace().

◆ AlignUp()

ULONGLONG AlignUp ( IN ULONGLONG  Value,
IN ULONG  Alignment 
)

Definition at line 258 of file partlist.c.

261 {
262  ULONGLONG Temp, Result;
263 
264  Temp = Value / Alignment;
265 
266  Result = Temp * Alignment;
267  if (Value % Alignment)
268  Result += Alignment;
269 
270  return Result;
271 }
union Alignment_ Alignment
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by PeFmtCreateSection().

◆ AssignDriveLetters()

static VOID AssignDriveLetters ( IN PPARTLIST  List)
static

Definition at line 317 of file partlist.c.

319 {
320  PDISKENTRY DiskEntry;
321  PPARTENTRY PartEntry;
322  PLIST_ENTRY Entry1;
323  PLIST_ENTRY Entry2;
324  WCHAR Letter;
325 
326  Letter = L'C';
327 
328  /* Assign drive letters to primary partitions */
329  for (Entry1 = List->DiskListHead.Flink;
330  Entry1 != &List->DiskListHead;
331  Entry1 = Entry1->Flink)
332  {
333  DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
334 
335  for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
336  Entry2 != &DiskEntry->PrimaryPartListHead;
337  Entry2 = Entry2->Flink)
338  {
339  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
340 
341  PartEntry->DriveLetter = 0;
342 
343  if (PartEntry->IsPartitioned &&
344  !IsContainerPartition(PartEntry->PartitionType))
345  {
347 
348  if (IsRecognizedPartition(PartEntry->PartitionType) ||
349  PartEntry->SectorCount.QuadPart != 0LL)
350  {
351  if (Letter <= L'Z')
352  {
353  PartEntry->DriveLetter = Letter;
354  Letter++;
355  }
356  }
357  }
358  }
359  }
360 
361  /* Assign drive letters to logical drives */
362  for (Entry1 = List->DiskListHead.Flink;
363  Entry1 != &List->DiskListHead;
364  Entry1 = Entry1->Flink)
365  {
366  DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
367 
368  for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
369  Entry2 != &DiskEntry->LogicalPartListHead;
370  Entry2 = Entry2->Flink)
371  {
372  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
373 
374  PartEntry->DriveLetter = 0;
375 
376  if (PartEntry->IsPartitioned)
377  {
379 
380  if (IsRecognizedPartition(PartEntry->PartitionType) ||
381  PartEntry->SectorCount.QuadPart != 0LL)
382  {
383  if (Letter <= L'Z')
384  {
385  PartEntry->DriveLetter = Letter;
386  Letter++;
387  }
388  }
389  }
390  }
391  }
392 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:143
WCHAR DriveLetter
Definition: partlist.h:70
#define LL
Definition: tui.h:84
ULARGE_INTEGER SectorCount
Definition: partlist.h:62
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:316
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
UCHAR PartitionType
Definition: partlist.h:65
#define ASSERT(a)
Definition: mode.c:45
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:342
static const WCHAR L[]
Definition: oid.c:1250
WCHAR Letter
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:144
BOOLEAN IsPartitioned
Definition: partlist.h:78

Referenced by CreateExtendedPartition(), CreateLogicalPartition(), CreatePartitionList(), CreatePrimaryPartition(), and DeletePartition().

◆ CreateExtendedPartition()

BOOLEAN CreateExtendedPartition ( IN PPARTLIST  List,
IN OUT PPARTENTRY  PartEntry,
IN ULONGLONG  SectorCount 
)

Definition at line 3029 of file partlist.c.

3033 {
3035 
3036  DPRINT1("CreateExtendedPartition(%I64u)\n", SectorCount);
3037 
3038  if (List == NULL || PartEntry == NULL ||
3039  PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
3040  {
3041  return FALSE;
3042  }
3043 
3045  if (Error != NOT_AN_ERROR)
3046  {
3047  DPRINT1("ExtendedPartitionCreationChecks() failed with error %lu\n", Error);
3048  return FALSE;
3049  }
3050 
3051  /* Initialize the partition entry, inserting a new blank region if needed */
3052  if (!InitializePartitionEntry(PartEntry, SectorCount, FALSE))
3053  return FALSE;
3054 
3055  ASSERT(PartEntry->LogicalPartition == FALSE);
3056 
3057  if (PartEntry->StartSector.QuadPart < 1450560)
3058  {
3059  /* Partition starts below the 8.4GB boundary ==> CHS partition */
3060  PartEntry->PartitionType = PARTITION_EXTENDED;
3061  }
3062  else
3063  {
3064  /* Partition starts above the 8.4GB boundary ==> LBA partition */
3065  PartEntry->PartitionType = PARTITION_XINT13_EXTENDED;
3066  }
3067 
3068  // FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container)
3069  PartEntry->New = FALSE;
3070  PartEntry->FormatState = Formatted;
3071 
3072  PartEntry->DiskEntry->ExtendedPartition = PartEntry;
3073 
3074  AddLogicalDiskSpace(PartEntry->DiskEntry);
3075 
3076  UpdateDiskLayout(PartEntry->DiskEntry);
3078 
3079  return TRUE;
3080 }
ERROR_NUMBER ExtendedPartitionCreationChecks(IN PPARTENTRY PartEntry)
Definition: partlist.c:4160
#define TRUE
Definition: types.h:120
static BOOLEAN InitializePartitionEntry(IN OUT PPARTENTRY PartEntry, IN ULONGLONG SectorCount, IN BOOLEAN AutoCreate)
Definition: partlist.c:857
#define FALSE
Definition: types.h:117
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2713
#define PARTITION_EXTENDED
Definition: disk.h:91
#define ASSERT(a)
Definition: mode.c:45
BOOL Error
Definition: chkdsk.c:66
enum _ERROR_NUMBER ERROR_NUMBER
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
ULONG SectorCount
Definition: part_xbox.c:31
#define PARTITION_XINT13_EXTENDED
Definition: disk.h:98
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
static VOID AddLogicalDiskSpace(IN PDISKENTRY DiskEntry)
Definition: partlist.c:3002
static VOID AssignDriveLetters(IN PPARTLIST List)
Definition: partlist.c:317

Referenced by CreateExtendedPartitionPage().

◆ CreateInsertBlankRegion()

static PPARTENTRY CreateInsertBlankRegion ( IN PDISKENTRY  DiskEntry,
IN OUT PLIST_ENTRY  ListHead,
IN ULONGLONG  StartSector,
IN ULONGLONG  SectorCount,
IN BOOLEAN  LogicalSpace 
)
static

Definition at line 819 of file partlist.c.

825 {
826  PPARTENTRY NewPartEntry;
827 
828  NewPartEntry = RtlAllocateHeap(ProcessHeap,
830  sizeof(PARTENTRY));
831  if (NewPartEntry == NULL)
832  return NULL;
833 
834  NewPartEntry->DiskEntry = DiskEntry;
835 
836  NewPartEntry->StartSector.QuadPart = StartSector;
837  NewPartEntry->SectorCount.QuadPart = SectorCount;
838 
839  NewPartEntry->LogicalPartition = LogicalSpace;
840  NewPartEntry->IsPartitioned = FALSE;
841  NewPartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
842  NewPartEntry->FormatState = Unformatted;
843  NewPartEntry->FileSystem[0] = L'\0';
844 
845  DPRINT1("First Sector : %I64u\n", NewPartEntry->StartSector.QuadPart);
846  DPRINT1("Last Sector : %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
847  DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
848 
849  /* Insert the new entry into the list */
850  InsertTailList(ListHead, &NewPartEntry->ListEntry);
851 
852  return NewPartEntry;
853 }
ULARGE_INTEGER StartSector
Definition: partlist.h:61
ULARGE_INTEGER SectorCount
Definition: partlist.h:62
#define InsertTailList(ListHead, Entry)
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
LIST_ENTRY ListEntry
Definition: partlist.h:55
BOOLEAN LogicalPartition
Definition: partlist.h:75
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define FALSE
Definition: types.h:117
FORMATSTATE FormatState
Definition: partlist.h:73
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
UCHAR PartitionType
Definition: partlist.h:65
struct _DISKENTRY * DiskEntry
Definition: partlist.h:58
WCHAR FileSystem[MAX_PATH+1]
Definition: partlist.h:72
static const WCHAR L[]
Definition: oid.c:1250
ULONG SectorCount
Definition: part_xbox.c:31
HANDLE ProcessHeap
Definition: servman.c:15
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define DPRINT1
Definition: precomp.h:8
BOOLEAN IsPartitioned
Definition: partlist.h:78

Referenced by AddLogicalDiskSpace(), InitializePartitionEntry(), and ScanForUnpartitionedDiskSpace().

◆ CreateLogicalPartition()

BOOLEAN CreateLogicalPartition ( IN PPARTLIST  List,
IN OUT PPARTENTRY  PartEntry,
IN ULONGLONG  SectorCount,
IN BOOLEAN  AutoCreate 
)

Definition at line 3083 of file partlist.c.

3088 {
3090 
3091  DPRINT1("CreateLogicalPartition(%I64u)\n", SectorCount);
3092 
3093  if (List == NULL || PartEntry == NULL ||
3094  PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
3095  {
3096  return FALSE;
3097  }
3098 
3100  if (Error != NOT_AN_ERROR)
3101  {
3102  DPRINT1("LogicalPartitionCreationChecks() failed with error %lu\n", Error);
3103  return FALSE;
3104  }
3105 
3106  /* Initialize the partition entry, inserting a new blank region if needed */
3107  if (!InitializePartitionEntry(PartEntry, SectorCount, AutoCreate))
3108  return FALSE;
3109 
3110  ASSERT(PartEntry->LogicalPartition == TRUE);
3111 
3112  UpdateDiskLayout(PartEntry->DiskEntry);
3114 
3115  return TRUE;
3116 }
#define TRUE
Definition: types.h:120
ERROR_NUMBER LogicalPartitionCreationChecks(IN PPARTENTRY PartEntry)
Definition: partlist.c:4191
static BOOLEAN InitializePartitionEntry(IN OUT PPARTENTRY PartEntry, IN ULONGLONG SectorCount, IN BOOLEAN AutoCreate)
Definition: partlist.c:857
#define FALSE
Definition: types.h:117
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2713
#define ASSERT(a)
Definition: mode.c:45
BOOL Error
Definition: chkdsk.c:66
enum _ERROR_NUMBER ERROR_NUMBER
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
ULONG SectorCount
Definition: part_xbox.c:31
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
static VOID AssignDriveLetters(IN PPARTLIST List)
Definition: partlist.c:317

Referenced by CreateLogicalPartitionPage(), and SelectPartitionPage().

◆ CreatePartitionList()

PPARTLIST CreatePartitionList ( VOID  )

Definition at line 2026 of file partlist.c.

2027 {
2028  PPARTLIST List;
2029  PDISKENTRY SystemDisk;
2033  ULONG ReturnSize;
2034  NTSTATUS Status;
2035  ULONG DiskNumber;
2039 
2041  0,
2042  sizeof(PARTLIST));
2043  if (List == NULL)
2044  return NULL;
2045 
2046  List->SystemPartition = NULL;
2047 
2048  InitializeListHead(&List->DiskListHead);
2049  InitializeListHead(&List->BiosDiskListHead);
2050 
2051  /*
2052  * Enumerate the disks seen by the BIOS; this will be used later
2053  * to map drives seen by NTOS with their corresponding BIOS names.
2054  */
2056 
2057  /* Enumerate disks seen by NTOS */
2059  &Sdi,
2060  sizeof(Sdi),
2061  &ReturnSize);
2062  if (!NT_SUCCESS(Status))
2063  {
2064  DPRINT1("NtQuerySystemInformation() failed, Status 0x%08lx", Status);
2066  return NULL;
2067  }
2068 
2069  for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
2070  {
2072  L"\\Device\\Harddisk%lu\\Partition0",
2073  DiskNumber);
2075 
2077  &Name,
2079  NULL,
2080  NULL);
2081 
2085  &Iosb,
2088  if (NT_SUCCESS(Status))
2089  {
2090  AddDiskToList(FileHandle, DiskNumber, List);
2092  }
2093  }
2094 
2098 
2099  /*
2100  * Retrieve the system partition: the active partition on the system
2101  * disk (the one that will be booted by default by the hardware).
2102  */
2103  SystemDisk = GetSystemDisk(List);
2104  List->SystemPartition = (SystemDisk ? GetActiveDiskPartition(SystemDisk) : NULL);
2105 
2106  return List;
2107 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
struct _PARTLIST * PPARTLIST
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static PPARTENTRY GetActiveDiskPartition(IN PDISKENTRY DiskEntry)
Definition: partlist.c:1970
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
static VOID UpdateDiskSignatures(IN PPARTLIST List)
Definition: partlist.c:1394
#define FILE_SHARE_READ
Definition: compat.h:136
HANDLE FileHandle
Definition: stats.c:38
#define FILE_READ_DATA
Definition: nt_native.h:628
struct NameRec_ * Name
Definition: cdprocs.h:459
Definition: bufpool.h:45
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
Status
Definition: gdiplustypes.h:24
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3951
__wchar_t WCHAR
Definition: xmlstorage.h:180
return Iosb
Definition: create.c:4402
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static VOID UpdateHwDiskNumbers(IN PPARTLIST List)
Definition: partlist.c:1424
#define MAX_PATH
Definition: compat.h:34
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
static PDISKENTRY GetSystemDisk(IN PPARTLIST List)
Definition: partlist.c:1897
static const WCHAR L[]
Definition: oid.c:1250
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
#define SYNCHRONIZE
Definition: nt_native.h:61
HANDLE ProcessHeap
Definition: servman.c:15
static VOID EnumerateBiosDiskEntries(IN PPARTLIST PartList)
Definition: partlist.c:516
static VOID AddDiskToList(IN HANDLE FileHandle, IN ULONG DiskNumber, IN PPARTLIST List)
Definition: partlist.c:1485
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
static VOID AssignDriveLetters(IN PPARTLIST List)
Definition: partlist.c:317

Referenced by LoadSetupData(), rescan_main(), SelectPartitionPage(), UpgradeRepairPage(), and wmain().

◆ CreatePrimaryPartition()

BOOLEAN CreatePrimaryPartition ( IN PPARTLIST  List,
IN OUT PPARTENTRY  PartEntry,
IN ULONGLONG  SectorCount,
IN BOOLEAN  AutoCreate 
)

Definition at line 2965 of file partlist.c.

2970 {
2972 
2973  DPRINT1("CreatePrimaryPartition(%I64u)\n", SectorCount);
2974 
2975  if (List == NULL || PartEntry == NULL ||
2976  PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
2977  {
2978  return FALSE;
2979  }
2980 
2982  if (Error != NOT_AN_ERROR)
2983  {
2984  DPRINT1("PrimaryPartitionCreationChecks() failed with error %lu\n", Error);
2985  return FALSE;
2986  }
2987 
2988  /* Initialize the partition entry, inserting a new blank region if needed */
2989  if (!InitializePartitionEntry(PartEntry, SectorCount, AutoCreate))
2990  return FALSE;
2991 
2992  ASSERT(PartEntry->LogicalPartition == FALSE);
2993 
2994  UpdateDiskLayout(PartEntry->DiskEntry);
2996 
2997  return TRUE;
2998 }
#define TRUE
Definition: types.h:120
static BOOLEAN InitializePartitionEntry(IN OUT PPARTENTRY PartEntry, IN ULONGLONG SectorCount, IN BOOLEAN AutoCreate)
Definition: partlist.c:857
#define FALSE
Definition: types.h:117
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2713
ERROR_NUMBER PrimaryPartitionCreationChecks(IN PPARTENTRY PartEntry)
Definition: partlist.c:4133
#define ASSERT(a)
Definition: mode.c:45
BOOL Error
Definition: chkdsk.c:66
enum _ERROR_NUMBER ERROR_NUMBER
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
ULONG SectorCount
Definition: part_xbox.c:31
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
static VOID AssignDriveLetters(IN PPARTLIST List)
Definition: partlist.c:317

Referenced by CreatePrimaryPartitionPage(), SelectFileSystemPage(), and SelectPartitionPage().

◆ DeletePartition()

BOOLEAN DeletePartition ( IN PPARTLIST  List,
IN PPARTENTRY  PartEntry,
OUT PPARTENTRY *FreeRegion  OPTIONAL 
)

Definition at line 3226 of file partlist.c.

3230 {
3231  PDISKENTRY DiskEntry;
3232  PPARTENTRY PrevPartEntry;
3233  PPARTENTRY NextPartEntry;
3234  PPARTENTRY LogicalPartEntry;
3236 
3237  if (List == NULL || PartEntry == NULL ||
3238  PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned == FALSE)
3239  {
3240  return FALSE;
3241  }
3242 
3243  ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
3244 
3245  /* Clear the system partition if it is being deleted */
3246  if (List->SystemPartition == PartEntry)
3247  {
3248  ASSERT(List->SystemPartition);
3249  List->SystemPartition = NULL;
3250  }
3251 
3252  DiskEntry = PartEntry->DiskEntry;
3253 
3254  /* Check which type of partition (primary/logical or extended) is being deleted */
3255  if (DiskEntry->ExtendedPartition == PartEntry)
3256  {
3257  /* An extended partition is being deleted: delete all logical partition entries */
3258  while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
3259  {
3260  Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
3261  LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
3262 
3263  /* Dismount the logical partition */
3264  DismountVolume(LogicalPartEntry);
3265 
3266  /* Delete it */
3267  RtlFreeHeap(ProcessHeap, 0, LogicalPartEntry);
3268  }
3269 
3270  DiskEntry->ExtendedPartition = NULL;
3271  }
3272  else
3273  {
3274  /* A primary partition is being deleted: dismount it */
3275  DismountVolume(PartEntry);
3276  }
3277 
3278  /* Adjust the unpartitioned disk space entries */
3279 
3280  /* Get pointer to previous and next unpartitioned entries */
3281  PrevPartEntry = GetPrevUnpartitionedEntry(PartEntry);
3282  NextPartEntry = GetNextUnpartitionedEntry(PartEntry);
3283 
3284  if (PrevPartEntry != NULL && NextPartEntry != NULL)
3285  {
3286  /* Merge the previous, current and next unpartitioned entries */
3287 
3288  /* Adjust the previous entry length */
3289  PrevPartEntry->SectorCount.QuadPart += (PartEntry->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart);
3290 
3291  /* Remove the current and next entries */
3292  RemoveEntryList(&PartEntry->ListEntry);
3293  RtlFreeHeap(ProcessHeap, 0, PartEntry);
3294  RemoveEntryList(&NextPartEntry->ListEntry);
3295  RtlFreeHeap(ProcessHeap, 0, NextPartEntry);
3296 
3297  /* Optionally return the freed region */
3298  if (FreeRegion)
3299  *FreeRegion = PrevPartEntry;
3300  }
3301  else if (PrevPartEntry != NULL && NextPartEntry == NULL)
3302  {
3303  /* Merge the current and the previous unpartitioned entries */
3304 
3305  /* Adjust the previous entry length */
3306  PrevPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
3307 
3308  /* Remove the current entry */
3309  RemoveEntryList(&PartEntry->ListEntry);
3310  RtlFreeHeap(ProcessHeap, 0, PartEntry);
3311 
3312  /* Optionally return the freed region */
3313  if (FreeRegion)
3314  *FreeRegion = PrevPartEntry;
3315  }
3316  else if (PrevPartEntry == NULL && NextPartEntry != NULL)
3317  {
3318  /* Merge the current and the next unpartitioned entries */
3319 
3320  /* Adjust the next entry offset and length */
3321  NextPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
3322  NextPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
3323 
3324  /* Remove the current entry */
3325  RemoveEntryList(&PartEntry->ListEntry);
3326  RtlFreeHeap(ProcessHeap, 0, PartEntry);
3327 
3328  /* Optionally return the freed region */
3329  if (FreeRegion)
3330  *FreeRegion = NextPartEntry;
3331  }
3332  else
3333  {
3334  /* Nothing to merge but change the current entry */
3335  PartEntry->IsPartitioned = FALSE;
3336  PartEntry->OnDiskPartitionNumber = 0;
3337  PartEntry->PartitionNumber = 0;
3338  // PartEntry->PartitionIndex = 0;
3339  PartEntry->BootIndicator = FALSE;
3340  PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
3341  PartEntry->FormatState = Unformatted;
3342  PartEntry->FileSystem[0] = L'\0';
3343  PartEntry->DriveLetter = 0;
3344  RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
3345 
3346  /* Optionally return the freed region */
3347  if (FreeRegion)
3348  *FreeRegion = PartEntry;
3349  }
3350 
3351  UpdateDiskLayout(DiskEntry);
3353 
3354  return TRUE;
3355 }
ULARGE_INTEGER StartSector
Definition: partlist.h:61
struct _Entry Entry
Definition: kefuncs.h:627
#define TRUE
Definition: types.h:120
ULARGE_INTEGER SectorCount
Definition: partlist.h:62
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
PPARTENTRY ExtendedPartition
Definition: partlist.h:147
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
LIST_ENTRY ListEntry
Definition: partlist.h:55
NTSTATUS DismountVolume(IN PPARTENTRY PartEntry)
Definition: partlist.c:3119
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define FALSE
Definition: types.h:117
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2713
#define ASSERT(a)
Definition: mode.c:45
static const WCHAR L[]
Definition: oid.c:1250
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
HANDLE ProcessHeap
Definition: servman.c:15
static PPARTENTRY GetPrevUnpartitionedEntry(IN PPARTENTRY PartEntry)
Definition: partlist.c:2896
#define NULL
Definition: types.h:112
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:144
static PPARTENTRY GetNextUnpartitionedEntry(IN PPARTENTRY PartEntry)
Definition: partlist.c:2931
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
base of all file and directory entries
Definition: entries.h:82
static VOID AssignDriveLetters(IN PPARTLIST List)
Definition: partlist.c:317
BOOLEAN IsPartitioned
Definition: partlist.h:78

Referenced by DeletePartitionPage().

◆ DestroyPartitionList()

VOID DestroyPartitionList ( IN PPARTLIST  List)

Definition at line 2110 of file partlist.c.

2112 {
2113  PDISKENTRY DiskEntry;
2114  PBIOSDISKENTRY BiosDiskEntry;
2115  PPARTENTRY PartEntry;
2117 
2118  /* Release disk and partition info */
2119  while (!IsListEmpty(&List->DiskListHead))
2120  {
2121  Entry = RemoveHeadList(&List->DiskListHead);
2122  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2123 
2124  /* Release driver name */
2125  RtlFreeUnicodeString(&DiskEntry->DriverName);
2126 
2127  /* Release primary partition list */
2128  while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
2129  {
2130  Entry = RemoveHeadList(&DiskEntry->PrimaryPartListHead);
2131  PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2132 
2133  RtlFreeHeap(ProcessHeap, 0, PartEntry);
2134  }
2135 
2136  /* Release logical partition list */
2137  while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
2138  {
2139  Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
2140  PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2141 
2142  RtlFreeHeap(ProcessHeap, 0, PartEntry);
2143  }
2144 
2145  /* Release layout buffer */
2146  if (DiskEntry->LayoutBuffer != NULL)
2147  RtlFreeHeap(ProcessHeap, 0, DiskEntry->LayoutBuffer);
2148 
2149  /* Release disk entry */
2150  RtlFreeHeap(ProcessHeap, 0, DiskEntry);
2151  }
2152 
2153  /* Release the bios disk info */
2154  while (!IsListEmpty(&List->BiosDiskListHead))
2155  {
2156  Entry = RemoveHeadList(&List->BiosDiskListHead);
2157  BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
2158 
2159  RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
2160  }
2161 
2162  /* Release list head */
2164 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:143
struct _Entry Entry
Definition: kefuncs.h:627
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
UNICODE_STRING DriverName
Definition: partlist.h:135
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
HANDLE ProcessHeap
Definition: servman.c:15
#define NULL
Definition: types.h:112
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:144
PDRIVE_LAYOUT_INFORMATION LayoutBuffer
Definition: partlist.h:137
base of all file and directory entries
Definition: entries.h:82

Referenced by QuitPage(), rescan_main(), SelectPartitionPage(), and wmain().

◆ DiskConfigurationDataQueryRoutine()

static NTSTATUS NTAPI DiskConfigurationDataQueryRoutine ( PWSTR  ValueName,
ULONG  ValueType,
PVOID  ValueData,
ULONG  ValueLength,
PVOID  Context,
PVOID  EntryContext 
)
static

Definition at line 426 of file partlist.c.

433 {
434  PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
435  PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
436  PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
437  ULONG i;
438 
441  return STATUS_UNSUCCESSFUL;
442 
443  FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
444 
445  /* Hm. Version and Revision are not set on Microsoft Windows XP... */
446 #if 0
447  if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
448  FullResourceDescriptor->PartialResourceList.Revision != 1)
449  return STATUS_UNSUCCESSFUL;
450 #endif
451 
452  for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
453  {
455  FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize != sizeof(CM_DISK_GEOMETRY_DEVICE_DATA))
456  continue;
457 
458  DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1];
459  BiosDiskEntry->DiskGeometry = *DiskGeometry;
460 
461  return STATUS_SUCCESS;
462  }
463 
464  return STATUS_UNSUCCESSFUL;
465 }
#define CmResourceTypeDeviceSpecific
Definition: hwresource.cpp:127
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@385::@394 DeviceSpecificData
struct _CM_DISK_GEOMETRY_DEVICE_DATA * PCM_DISK_GEOMETRY_DEVICE_DATA
struct _BIOSDISKENTRY * PBIOSDISKENTRY
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:279
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@385 u
struct _CM_FULL_RESOURCE_DESCRIPTOR * PCM_FULL_RESOURCE_DESCRIPTOR
#define REG_FULL_RESOURCE_DESCRIPTOR
Definition: nt_native.h:1503
CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry
Definition: partlist.h:160
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: hwresource.cpp:119
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:271

Referenced by EnumerateBiosDiskEntries().

◆ DiskIdentifierQueryRoutine()

static NTSTATUS NTAPI DiskIdentifierQueryRoutine ( PWSTR  ValueName,
ULONG  ValueType,
PVOID  ValueData,
ULONG  ValueLength,
PVOID  Context,
PVOID  EntryContext 
)
static

Definition at line 396 of file partlist.c.

403 {
404  PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
405  UNICODE_STRING NameU;
406 
407  if (ValueType == REG_SZ &&
408  ValueLength == 20 * sizeof(WCHAR) &&
409  ((PWCHAR)ValueData)[8] == L'-')
410  {
411  NameU.Buffer = (PWCHAR)ValueData;
412  NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR);
413  RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum);
414 
415  NameU.Buffer = (PWCHAR)ValueData + 9;
416  RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature);
417 
418  return STATUS_SUCCESS;
419  }
420 
421  return STATUS_UNSUCCESSFUL;
422 }
USHORT MaximumLength
Definition: env_spec_w32.h:370
ULONG Checksum
Definition: partlist.h:158
ULONG Signature
Definition: partlist.h:157
uint16_t * PWCHAR
Definition: typedefs.h:56
struct _BIOSDISKENTRY * PBIOSDISKENTRY
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:279
__wchar_t WCHAR
Definition: xmlstorage.h:180
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
static const WCHAR L[]
Definition: oid.c:1250
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define REG_SZ
Definition: layer.c:22
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:271

Referenced by EnumerateBiosDiskEntries().

◆ DismountVolume()

NTSTATUS DismountVolume ( IN PPARTENTRY  PartEntry)

Definition at line 3119 of file partlist.c.

3121 {
3122  NTSTATUS Status;
3123  NTSTATUS LockStatus;
3127  HANDLE PartitionHandle;
3129 
3130  /* Check whether the partition is valid and was mounted by the system */
3131  if (!PartEntry->IsPartitioned ||
3132  IsContainerPartition(PartEntry->PartitionType) ||
3133  !IsRecognizedPartition(PartEntry->PartitionType) ||
3134  PartEntry->FormatState == UnknownFormat ||
3135  // NOTE: If FormatState == Unformatted but *FileSystem != 0 this means
3136  // it has been usually mounted with RawFS and thus needs to be dismounted.
3137  !*PartEntry->FileSystem ||
3138  PartEntry->PartitionNumber == 0)
3139  {
3140  /* The partition is not mounted, so just return success */
3141  return STATUS_SUCCESS;
3142  }
3143 
3144  ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
3145 
3146  /* Open the volume */
3148  L"\\Device\\Harddisk%lu\\Partition%lu",
3149  PartEntry->DiskEntry->DiskNumber,
3150  PartEntry->PartitionNumber);
3152 
3154  &Name,
3156  NULL,
3157  NULL);
3158 
3159  Status = NtOpenFile(&PartitionHandle,
3162  &IoStatusBlock,
3165  if (!NT_SUCCESS(Status))
3166  {
3167  DPRINT1("ERROR: Cannot open volume %wZ for dismounting! (Status 0x%lx)\n", &Name, Status);
3168  return Status;
3169  }
3170 
3171  /* Lock the volume */
3172  LockStatus = NtFsControlFile(PartitionHandle,
3173  NULL,
3174  NULL,
3175  NULL,
3176  &IoStatusBlock,
3178  NULL,
3179  0,
3180  NULL,
3181  0);
3182  if (!NT_SUCCESS(LockStatus))
3183  {
3184  DPRINT1("WARNING: Failed to lock volume! Operations may fail! (Status 0x%lx)\n", LockStatus);
3185  }
3186 
3187  /* Dismount the volume */
3188  Status = NtFsControlFile(PartitionHandle,
3189  NULL,
3190  NULL,
3191  NULL,
3192  &IoStatusBlock,
3194  NULL,
3195  0,
3196  NULL,
3197  0);
3198  if (!NT_SUCCESS(Status))
3199  {
3200  DPRINT1("Failed to unmount volume (Status 0x%lx)\n", Status);
3201  }
3202 
3203  /* Unlock the volume */
3204  LockStatus = NtFsControlFile(PartitionHandle,
3205  NULL,
3206  NULL,
3207  NULL,
3208  &IoStatusBlock,
3210  NULL,
3211  0,
3212  NULL,
3213  0);
3214  if (!NT_SUCCESS(LockStatus))
3215  {
3216  DPRINT1("Failed to unlock volume (Status 0x%lx)\n", LockStatus);
3217  }
3218 
3219  /* Close the volume */
3220  NtClose(PartitionHandle);
3221 
3222  return Status;
3223 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:316
NTSYSCALLAPI NTSTATUS NTAPI NtFsControlFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG FsControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength)
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_SHARE_READ
Definition: compat.h:136
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
#define GENERIC_WRITE
Definition: nt_native.h:90
struct NameRec_ * Name
Definition: cdprocs.h:459
Definition: bufpool.h:45
#define FSCTL_DISMOUNT_VOLUME
Definition: nt_native.h:834
Status
Definition: gdiplustypes.h:24
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3951
#define ASSERT(a)
Definition: mode.c:45
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:342
#define MAX_PATH
Definition: compat.h:34
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
static const WCHAR L[]
Definition: oid.c:1250
#define GENERIC_READ
Definition: compat.h:135
#define SYNCHRONIZE
Definition: nt_native.h:61
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define FSCTL_LOCK_VOLUME
Definition: nt_native.h:832
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by AddPartitionToDisk(), and DeletePartition().

◆ EnumerateBiosDiskEntries()

static VOID EnumerateBiosDiskEntries ( IN PPARTLIST  PartList)
static

Definition at line 516 of file partlist.c.

518 {
520  WCHAR Name[120];
521  ULONG AdapterCount;
523  ULONG DiskCount;
525  PCM_INT13_DRIVE_PARAMETER Int13Drives;
526  PBIOSDISKENTRY BiosDiskEntry;
527 
528 #define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
529 
530  memset(QueryTable, 0, sizeof(QueryTable));
531 
532  QueryTable[1].Name = L"Configuration Data";
534  Int13Drives = NULL;
536  L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
537  &QueryTable[1],
538  (PVOID)&Int13Drives,
539  NULL);
540  if (!NT_SUCCESS(Status))
541  {
542  DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status);
543  return;
544  }
545 
546  for (AdapterCount = 0; ; ++AdapterCount)
547  {
549  L"%s\\%lu",
550  ROOT_NAME, AdapterCount);
552  Name,
553  &QueryTable[2],
554  NULL,
555  NULL);
556  if (!NT_SUCCESS(Status))
557  {
558  break;
559  }
560 
562  L"%s\\%lu\\DiskController",
563  ROOT_NAME, AdapterCount);
565  Name,
566  &QueryTable[2],
567  NULL,
568  NULL);
569  if (NT_SUCCESS(Status))
570  {
571  for (ControllerCount = 0; ; ++ControllerCount)
572  {
574  L"%s\\%lu\\DiskController\\%lu",
575  ROOT_NAME, AdapterCount, ControllerCount);
577  Name,
578  &QueryTable[2],
579  NULL,
580  NULL);
581  if (!NT_SUCCESS(Status))
582  {
583  RtlFreeHeap(ProcessHeap, 0, Int13Drives);
584  return;
585  }
586 
588  L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral",
589  ROOT_NAME, AdapterCount, ControllerCount);
591  Name,
592  &QueryTable[2],
593  NULL,
594  NULL);
595  if (NT_SUCCESS(Status))
596  {
597  QueryTable[0].Name = L"Identifier";
599  QueryTable[1].Name = L"Configuration Data";
601 
602  for (DiskCount = 0; ; ++DiskCount)
603  {
605  if (BiosDiskEntry == NULL)
606  {
607  RtlFreeHeap(ProcessHeap, 0, Int13Drives);
608  return;
609  }
610 
612  L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral\\%lu",
613  ROOT_NAME, AdapterCount, ControllerCount, DiskCount);
615  Name,
616  QueryTable,
617  (PVOID)BiosDiskEntry,
618  NULL);
619  if (!NT_SUCCESS(Status))
620  {
621  RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
622  RtlFreeHeap(ProcessHeap, 0, Int13Drives);
623  return;
624  }
625 
626  BiosDiskEntry->AdapterNumber = 0; // And NOT "AdapterCount" as it needs to be hardcoded for BIOS!
627  BiosDiskEntry->ControllerNumber = ControllerCount;
628  BiosDiskEntry->DiskNumber = DiskCount;
629  BiosDiskEntry->DiskEntry = NULL;
630 
631  if (DiskCount < Int13Drives[0].NumberDrives)
632  {
633  BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount];
634  }
635  else
636  {
637  DPRINT1("Didn't find Int13 drive data for disk %u\n", DiskCount);
638  }
639 
640  InsertTailList(&PartList->BiosDiskListHead, &BiosDiskEntry->ListEntry);
641 
642  DPRINT("--->\n");
643  DPRINT("AdapterNumber: %lu\n", BiosDiskEntry->AdapterNumber);
644  DPRINT("ControllerNumber: %lu\n", BiosDiskEntry->ControllerNumber);
645  DPRINT("DiskNumber: %lu\n", BiosDiskEntry->DiskNumber);
646  DPRINT("Signature: %08lx\n", BiosDiskEntry->Signature);
647  DPRINT("Checksum: %08lx\n", BiosDiskEntry->Checksum);
648  DPRINT("BytesPerSector: %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector);
649  DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders);
650  DPRINT("NumberOfHeads: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads);
651  DPRINT("DriveSelect: %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect);
652  DPRINT("MaxCylinders: %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders);
653  DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack);
654  DPRINT("MaxHeads: %d\n", BiosDiskEntry->Int13DiskData.MaxHeads);
655  DPRINT("NumberDrives: %d\n", BiosDiskEntry->Int13DiskData.NumberDrives);
656  DPRINT("<---\n");
657  }
658  }
659  }
660  }
661  }
662 
663  RtlFreeHeap(ProcessHeap, 0, Int13Drives);
664 
665 #undef ROOT_NAME
666 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4142
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
ULONG Checksum
Definition: partlist.h:158
ULONG Signature
Definition: partlist.h:157
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
ULONG ControllerNumber
Definition: partlist.h:155
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define InsertTailList(ListHead, Entry)
ULONG ControllerCount
Definition: fdc.c:18
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
static NTSTATUS NTAPI SystemConfigurationDataQueryRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: partlist.c:469
void DPRINT(...)
Definition: polytest.cpp:61
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
Status
Definition: gdiplustypes.h:24
ULONG AdapterNumber
Definition: partlist.h:154
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry
Definition: partlist.h:160
PDISKENTRY DiskEntry
Definition: partlist.h:159
static const WCHAR L[]
Definition: oid.c:1250
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
HANDLE ProcessHeap
Definition: servman.c:15
LIST_ENTRY ListEntry
Definition: partlist.h:153
ULONG DiskNumber
Definition: partlist.h:156
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define DPRINT1
Definition: precomp.h:8
#define ROOT_NAME
static NTSTATUS NTAPI DiskConfigurationDataQueryRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: partlist.c:426
unsigned int ULONG
Definition: retypes.h:1
static NTSTATUS NTAPI DiskIdentifierQueryRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: partlist.c:396
CM_INT13_DRIVE_PARAMETER Int13DiskData
Definition: partlist.h:161
#define memset(x, y, z)
Definition: compat.h:39

Referenced by CreatePartitionList().

◆ ExtendedPartitionCreationChecks()

ERROR_NUMBER ExtendedPartitionCreationChecks ( IN PPARTENTRY  PartEntry)

Definition at line 4160 of file partlist.c.

4162 {
4163  PDISKENTRY DiskEntry = PartEntry->DiskEntry;
4164 
4165  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
4166  {
4167  DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
4168  return ERROR_WARN_PARTITION;
4169  }
4170 
4171  /* Fail if the partition is already in use */
4172  if (PartEntry->IsPartitioned)
4173  return ERROR_NEW_PARTITION;
4174 
4175  /* Only one primary partition is allowed on super-floppy */
4176  if (IsSuperFloppy(DiskEntry))
4178 
4179  /* Fail if there are already 4 primary partitions in the list */
4180  if (GetPrimaryPartitionCount(DiskEntry) >= 4)
4182 
4183  /* Fail if there is another extended partition in the list */
4184  if (DiskEntry->ExtendedPartition != NULL)
4185  return ERROR_ONLY_ONE_EXTENDED;
4186 
4187  return ERROR_SUCCESS;
4188 }
#define ERROR_SUCCESS
Definition: deptool.c:10
PPARTENTRY ExtendedPartition
Definition: partlist.h:147
PARTITION_STYLE DiskStyle
Definition: partlist.h:133
static ULONG GetPrimaryPartitionCount(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2607
BOOLEAN IsSuperFloppy(IN PDISKENTRY DiskEntry)
Definition: partlist.c:680
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8

Referenced by CreateExtendedPartition(), and SelectPartitionPage().

◆ FindSupportedSystemPartition()

PPARTENTRY FindSupportedSystemPartition ( IN PPARTLIST  List,
IN BOOLEAN  ForceSelect,
IN PDISKENTRY AlternativeDisk  OPTIONAL,
IN PPARTENTRY AlternativePart  OPTIONAL 
)

Definition at line 3439 of file partlist.c.

3444 {
3445  PLIST_ENTRY ListEntry;
3446  PDISKENTRY DiskEntry;
3447  PPARTENTRY PartEntry;
3448  PPARTENTRY ActivePartition;
3449  PPARTENTRY CandidatePartition = NULL;
3450 
3451  /* Check for empty disk list */
3452  if (IsListEmpty(&List->DiskListHead))
3453  {
3454  /* No system partition! */
3455  ASSERT(List->SystemPartition == NULL);
3456  goto NoSystemPartition;
3457  }
3458 
3459  /* Adjust the optional alternative disk if needed */
3460  if (!AlternativeDisk && AlternativePart)
3461  AlternativeDisk = AlternativePart->DiskEntry;
3462 
3463  /* Ensure that the alternative partition is on the alternative disk */
3464  if (AlternativePart)
3465  ASSERT(AlternativeDisk && (AlternativePart->DiskEntry == AlternativeDisk));
3466 
3467  /* Ensure that the alternative disk is in the list */
3468  if (AlternativeDisk)
3469  ASSERT(AlternativeDisk->PartList == List);
3470 
3471  /* Start fresh */
3472  CandidatePartition = NULL;
3473 
3474 //
3475 // Step 1 : Check the system disk.
3476 //
3477 
3478  /*
3479  * First, check whether the system disk, i.e. the one that will be booted
3480  * by default by the hardware, contains an active partition. If so this
3481  * should be our system partition.
3482  */
3483  DiskEntry = GetSystemDisk(List);
3484 
3485  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3486  {
3487  DPRINT1("System disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
3488  goto UseAlternativeDisk;
3489  }
3490 
3491  /* If we have a system partition (in the system disk), validate it */
3492  ActivePartition = List->SystemPartition;
3493  if (ActivePartition && IsSupportedActivePartition(ActivePartition))
3494  {
3495  CandidatePartition = ActivePartition;
3496 
3497  DPRINT1("Use the current system partition %lu in disk %lu, drive letter %C\n",
3498  CandidatePartition->PartitionNumber,
3499  CandidatePartition->DiskEntry->DiskNumber,
3500  (CandidatePartition->DriveLetter == 0) ? L'-' : CandidatePartition->DriveLetter);
3501 
3502  /* Return the candidate system partition */
3503  return CandidatePartition;
3504  }
3505 
3506  /* If the system disk is not the optional alternative disk, perform the minimal checks */
3507  if (DiskEntry != AlternativeDisk)
3508  {
3509  /*
3510  * No active partition has been recognized. Enumerate all the (primary)
3511  * partitions in the system disk, excluding the possible current active
3512  * partition, to find a new candidate.
3513  */
3514  for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3515  ListEntry != &DiskEntry->PrimaryPartListHead;
3516  ListEntry = ListEntry->Flink)
3517  {
3518  /* Retrieve the partition */
3519  PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3520 
3521  /* Skip the current active partition */
3522  if (PartEntry == ActivePartition)
3523  continue;
3524 
3525  /* Check if the partition is partitioned and used */
3526  if (PartEntry->IsPartitioned &&
3527  !IsContainerPartition(PartEntry->PartitionType))
3528  {
3530 
3531  /* If we get a candidate active partition in the disk, validate it */
3532  if (IsSupportedActivePartition(PartEntry))
3533  {
3534  CandidatePartition = PartEntry;
3535  goto UseAlternativePartition;
3536  }
3537  }
3538 
3539 #if 0
3540  /* Check if the partition is partitioned and used */
3541  if (!PartEntry->IsPartitioned)
3542  {
3544 
3545  // TODO: Check for minimal size!!
3546  CandidatePartition = PartEntry;
3547  goto UseAlternativePartition;
3548  }
3549 #endif
3550  }
3551 
3552  /*
3553  * Still nothing, look whether there is some free space that we can use
3554  * for the new system partition. We must be sure that the total number
3555  * of partition is less than the maximum allowed, and that the minimal
3556  * size is fine.
3557  */
3558 //
3559 // TODO: Fix the handling of system partition being created in unpartitioned space!!
3560 // --> When to partition it? etc...
3561 //
3562  if (GetPrimaryPartitionCount(DiskEntry) < 4)
3563  {
3564  for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3565  ListEntry != &DiskEntry->PrimaryPartListHead;
3566  ListEntry = ListEntry->Flink)
3567  {
3568  /* Retrieve the partition */
3569  PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3570 
3571  /* Skip the current active partition */
3572  if (PartEntry == ActivePartition)
3573  continue;
3574 
3575  /* Check for unpartitioned space */
3576  if (!PartEntry->IsPartitioned)
3577  {
3579 
3580  // TODO: Check for minimal size!!
3581  CandidatePartition = PartEntry;
3582  goto UseAlternativePartition;
3583  }
3584  }
3585  }
3586  }
3587 
3588 
3589 //
3590 // Step 2 : No active partition found: Check the alternative disk if specified.
3591 //
3592 
3593 UseAlternativeDisk:
3594  if (!AlternativeDisk || (!ForceSelect && (DiskEntry != AlternativeDisk)))
3595  goto NoSystemPartition;
3596 
3597  if (AlternativeDisk->DiskStyle == PARTITION_STYLE_GPT)
3598  {
3599  DPRINT1("Alternative disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
3600  goto NoSystemPartition;
3601  }
3602 
3603  if (DiskEntry != AlternativeDisk)
3604  {
3605  /* Choose the alternative disk */
3606  DiskEntry = AlternativeDisk;
3607 
3608  /* If we get a candidate active partition, validate it */
3609  ActivePartition = GetActiveDiskPartition(DiskEntry);
3610  if (ActivePartition && IsSupportedActivePartition(ActivePartition))
3611  {
3612  CandidatePartition = ActivePartition;
3613  goto UseAlternativePartition;
3614  }
3615  }
3616 
3617  /* We now may have an unsupported active partition, or none */
3618 
3619 /***
3620  *** TODO: Improve the selection:
3621  *** - If we want a really separate system partition from the partition where
3622  *** we install, do something similar to what's done below in the code.
3623  *** - Otherwise if we allow for the system partition to be also the partition
3624  *** where we install, just directly fall down to using AlternativePart.
3625  ***/
3626 
3627  /* Retrieve the first partition of the disk */
3628  PartEntry = CONTAINING_RECORD(DiskEntry->PrimaryPartListHead.Flink,
3629  PARTENTRY, ListEntry);
3630  ASSERT(DiskEntry == PartEntry->DiskEntry);
3631 
3632  CandidatePartition = PartEntry;
3633 
3634  //
3635  // See: https://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/partlist.c?r1=63355&r2=63354&pathrev=63355#l2318
3636  //
3637 
3638  /* Check if the disk is new and if so, use its first partition as the active system partition */
3639  if (DiskEntry->NewDisk)
3640  {
3641  // !IsContainerPartition(PartEntry->PartitionType);
3642  if (!CandidatePartition->IsPartitioned || !CandidatePartition->BootIndicator) /* CandidatePartition != ActivePartition */
3643  {
3644  ASSERT(DiskEntry == CandidatePartition->DiskEntry);
3645 
3646  DPRINT1("Use new first active system partition %lu in disk %lu, drive letter %C\n",
3647  CandidatePartition->PartitionNumber,
3648  CandidatePartition->DiskEntry->DiskNumber,
3649  (CandidatePartition->DriveLetter == 0) ? L'-' : CandidatePartition->DriveLetter);
3650 
3651  /* Return the candidate system partition */
3652  return CandidatePartition;
3653  }
3654 
3655  // FIXME: What to do??
3656  DPRINT1("NewDisk TRUE but first partition is used?\n");
3657  }
3658 
3659  /*
3660  * The disk is not new, check if any partition is initialized;
3661  * if not, the first one becomes the system partition.
3662  */
3663  for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3664  ListEntry != &DiskEntry->PrimaryPartListHead;
3665  ListEntry = ListEntry->Flink)
3666  {
3667  /* Retrieve the partition */
3668  PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3669 
3670  /* Check if the partition is partitioned and is used */
3671  // !IsContainerPartition(PartEntry->PartitionType);
3672  if (/* PartEntry->IsPartitioned && */
3673  PartEntry->PartitionType != PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator)
3674  {
3675  break;
3676  }
3677  }
3678  if (ListEntry == &DiskEntry->PrimaryPartListHead)
3679  {
3680  /*
3681  * OK we haven't encountered any used and active partition,
3682  * so use the first one as the system partition.
3683  */
3684  ASSERT(DiskEntry == CandidatePartition->DiskEntry);
3685 
3686  DPRINT1("Use first active system partition %lu in disk %lu, drive letter %C\n",
3687  CandidatePartition->PartitionNumber,
3688  CandidatePartition->DiskEntry->DiskNumber,
3689  (CandidatePartition->DriveLetter == 0) ? L'-' : CandidatePartition->DriveLetter);
3690 
3691  /* Return the candidate system partition */
3692  return CandidatePartition;
3693  }
3694 
3695  /*
3696  * The disk is not new, we did not find any actual active partition,
3697  * or the one we found was not supported, or any possible other candidate
3698  * is not supported. We then use the alternative partition if specified.
3699  */
3700  if (AlternativePart)
3701  {
3702  DPRINT1("No valid or supported system partition has been found, use the alternative partition!\n");
3703  CandidatePartition = AlternativePart;
3704  goto UseAlternativePartition;
3705  }
3706  else
3707  {
3708 NoSystemPartition:
3709  DPRINT1("No valid or supported system partition has been found on this system!\n");
3710  return NULL;
3711  }
3712 
3713 UseAlternativePartition:
3714  /*
3715  * We are here because we did not find any (active) candidate system
3716  * partition that we know how to support. What we are going to do is
3717  * to change the existing system partition and use the alternative partition
3718  * (e.g. on which we install ReactOS) as the new system partition.
3719  * Then we will need to add in FreeLdr's boot menu an entry for booting
3720  * from the original system partition.
3721  */
3722  ASSERT(CandidatePartition);
3723 
3724  DPRINT1("Use alternative active system partition %lu in disk %lu, drive letter %C\n",
3725  CandidatePartition->PartitionNumber,
3726  CandidatePartition->DiskEntry->DiskNumber,
3727  (CandidatePartition->DriveLetter == 0) ? L'-' : CandidatePartition->DriveLetter);
3728 
3729  /* Return the candidate system partition */
3730  return CandidatePartition;
3731 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:143
WCHAR DriveLetter
Definition: partlist.h:70
ULONG PartitionNumber
Definition: partlist.h:67
static PPARTENTRY GetActiveDiskPartition(IN PDISKENTRY DiskEntry)
Definition: partlist.c:1970
static BOOLEAN IsSupportedActivePartition(IN PPARTENTRY PartEntry)
Definition: partlist.c:3359
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:316
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
PARTITION_STYLE DiskStyle
Definition: partlist.h:133
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
UCHAR PartitionType
Definition: partlist.h:65
struct _DISKENTRY * DiskEntry
Definition: partlist.h:58
#define ASSERT(a)
Definition: mode.c:45
static ULONG GetPrimaryPartitionCount(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2607
static PDISKENTRY GetSystemDisk(IN PPARTLIST List)
Definition: partlist.c:1897
static const WCHAR L[]
Definition: oid.c:1250
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
BOOLEAN BootIndicator
Definition: partlist.h:64
BOOLEAN NewDisk
Definition: partlist.h:132
BOOLEAN IsPartitioned
Definition: partlist.h:78

Referenced by SelectFileSystemPage().

◆ GetActiveDiskPartition()

static PPARTENTRY GetActiveDiskPartition ( IN PDISKENTRY  DiskEntry)
static

Definition at line 1970 of file partlist.c.

1972 {
1973  PLIST_ENTRY ListEntry;
1974  PPARTENTRY PartEntry;
1975  PPARTENTRY ActivePartition = NULL;
1976 
1977  /* Check for empty disk list */
1978  // ASSERT(DiskEntry);
1979  if (!DiskEntry)
1980  return NULL;
1981 
1982  /* Check for empty partition list */
1983  if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
1984  return NULL;
1985 
1986  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1987  {
1988  DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1989  return NULL;
1990  }
1991 
1992  /* Scan all (primary) partitions to find the active disk partition */
1993  for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
1994  ListEntry != &DiskEntry->PrimaryPartListHead;
1995  ListEntry = ListEntry->Flink)
1996  {
1997  /* Retrieve the partition */
1998  PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1999  if (IsPartitionActive(PartEntry))
2000  {
2001  /* Yes, we've found it */
2002  ASSERT(DiskEntry == PartEntry->DiskEntry);
2003  ASSERT(PartEntry->IsPartitioned);
2004 
2005  ActivePartition = PartEntry;
2006 
2007  DPRINT1("Found active system partition %lu in disk %lu, drive letter %C\n",
2008  PartEntry->PartitionNumber, DiskEntry->DiskNumber,
2009  (PartEntry->DriveLetter == 0) ? L'-' : PartEntry->DriveLetter);
2010  break;
2011  }
2012  }
2013 
2014  /* Check if the disk is new and if so, use its first partition as the active system partition */
2015  if (DiskEntry->NewDisk && ActivePartition != NULL)
2016  {
2017  // FIXME: What to do??
2018  DPRINT1("NewDisk TRUE but already existing active partition?\n");
2019  }
2020 
2021  /* Return the active partition found (or none) */
2022  return ActivePartition;
2023 }
WCHAR DriveLetter
Definition: partlist.h:70
ULONG PartitionNumber
Definition: partlist.h:67
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _DISKENTRY * DiskEntry
Definition: partlist.h:58
#define ASSERT(a)
Definition: mode.c:45
static const WCHAR L[]
Definition: oid.c:1250
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
BOOLEAN IsPartitionActive(IN PPARTENTRY PartEntry)
Definition: partlist.c:1947
BOOLEAN IsPartitioned
Definition: partlist.h:78

Referenced by CreatePartitionList(), FindSupportedSystemPartition(), and SetActivePartition().

◆ GetDiskByBiosNumber()

PDISKENTRY GetDiskByBiosNumber ( IN PPARTLIST  List,
IN ULONG  HwDiskNumber 
)

Definition at line 2167 of file partlist.c.

2170 {
2171  PDISKENTRY DiskEntry;
2173 
2174  /* Loop over the disks and find the correct one */
2175  for (Entry = List->DiskListHead.Flink;
2176  Entry != &List->DiskListHead;
2177  Entry = Entry->Flink)
2178  {
2179  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2180 
2181  if (DiskEntry->HwDiskNumber == HwDiskNumber)
2182  {
2183  /* Disk found */
2184  return DiskEntry;
2185  }
2186  }
2187 
2188  /* Disk not found, stop there */
2189  return NULL;
2190 }
struct _Entry Entry
Definition: kefuncs.h:627
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
ULONG HwDiskNumber
Definition: partlist.h:117
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
base of all file and directory entries
Definition: entries.h:82

◆ GetDiskByNumber()

PDISKENTRY GetDiskByNumber ( IN PPARTLIST  List,
IN ULONG  DiskNumber 
)

Definition at line 2193 of file partlist.c.

2196 {
2197  PDISKENTRY DiskEntry;
2199 
2200  /* Loop over the disks and find the correct one */
2201  for (Entry = List->DiskListHead.Flink;
2202  Entry != &List->DiskListHead;
2203  Entry = Entry->Flink)
2204  {
2205  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2206 
2207  if (DiskEntry->DiskNumber == DiskNumber)
2208  {
2209  /* Disk found */
2210  return DiskEntry;
2211  }
2212  }
2213 
2214  /* Disk not found, stop there */
2215  return NULL;
2216 }
struct _Entry Entry
Definition: kefuncs.h:627
ULONG DiskNumber
Definition: partlist.h:123
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
base of all file and directory entries
Definition: entries.h:82

Referenced by GetDiskOrPartition(), and SelectPartition().

◆ GetDiskBySCSI()

PDISKENTRY GetDiskBySCSI ( IN PPARTLIST  List,
IN USHORT  Port,
IN USHORT  Bus,
IN USHORT  Id 
)

Definition at line 2219 of file partlist.c.

2224 {
2225  PDISKENTRY DiskEntry;
2227 
2228  /* Loop over the disks and find the correct one */
2229  for (Entry = List->DiskListHead.Flink;
2230  Entry != &List->DiskListHead;
2231  Entry = Entry->Flink)
2232  {
2233  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2234 
2235  if (DiskEntry->Port == Port &&
2236  DiskEntry->Bus == Bus &&
2237  DiskEntry->Id == Id)
2238  {
2239  /* Disk found */
2240  return DiskEntry;
2241  }
2242  }
2243 
2244  /* Disk not found, stop there */
2245  return NULL;
2246 }
CPPORT Port[4]
Definition: headless.c:34
USHORT Id
Definition: partlist.h:127
struct _Entry Entry
Definition: kefuncs.h:627
USHORT Bus
Definition: partlist.h:126
DWORD Id
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
USHORT Port
Definition: partlist.h:125
#define NULL
Definition: types.h:112
base of all file and directory entries
Definition: entries.h:82

Referenced by ResolveArcNameManually().

◆ GetDiskBySignature()

PDISKENTRY GetDiskBySignature ( IN PPARTLIST  List,
IN ULONG  Signature 
)

Definition at line 2249 of file partlist.c.

2252 {
2253  PDISKENTRY DiskEntry;
2255 
2256  /* Loop over the disks and find the correct one */
2257  for (Entry = List->DiskListHead.Flink;
2258  Entry != &List->DiskListHead;
2259  Entry = Entry->Flink)
2260  {
2261  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2262 
2263  if (DiskEntry->LayoutBuffer->Signature == Signature)
2264  {
2265  /* Disk found */
2266  return DiskEntry;
2267  }
2268  }
2269 
2270  /* Disk not found, stop there */
2271  return NULL;
2272 }
struct _Entry Entry
Definition: kefuncs.h:627
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
static const WCHAR Signature[]
Definition: parser.c:141
PDRIVE_LAYOUT_INFORMATION LayoutBuffer
Definition: partlist.h:137
base of all file and directory entries
Definition: entries.h:82

Referenced by ResolveArcNameManually().

◆ GetDiskOrPartition()

BOOLEAN GetDiskOrPartition ( IN PPARTLIST  List,
IN ULONG  DiskNumber,
IN ULONG PartitionNumber  OPTIONAL,
OUT PDISKENTRY pDiskEntry,
OUT PPARTENTRY *pPartEntry  OPTIONAL 
)

Definition at line 2322 of file partlist.c.

2328 {
2329  PDISKENTRY DiskEntry;
2330  PPARTENTRY PartEntry = NULL;
2331 
2332  /* Find the disk */
2333  DiskEntry = GetDiskByNumber(List, DiskNumber);
2334  if (!DiskEntry)
2335  return FALSE;
2336 
2337  /* If we have a partition (PartitionNumber != 0), find it */
2338  if (PartitionNumber != 0)
2339  {
2340  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2341  {
2342  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2343  return FALSE;
2344  }
2345 
2346  PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
2347  if (!PartEntry)
2348  return FALSE;
2349  ASSERT(PartEntry->DiskEntry == DiskEntry);
2350  }
2351 
2352  /* Return the disk (and optionally the partition) */
2353  *pDiskEntry = DiskEntry;
2354  if (pPartEntry) *pPartEntry = PartEntry;
2355  return TRUE;
2356 }
#define TRUE
Definition: types.h:120
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2056
PPARTENTRY GetPartition(IN PDISKENTRY DiskEntry, IN ULONG PartitionNumber)
Definition: partlist.c:2275
PARTITION_STYLE DiskStyle
Definition: partlist.h:133
#define FALSE
Definition: types.h:117
void DPRINT(...)
Definition: polytest.cpp:61
PDISKENTRY GetDiskByNumber(IN PPARTLIST List, IN ULONG DiskNumber)
Definition: partlist.c:2193
struct _DISKENTRY * DiskEntry
Definition: partlist.h:58
#define ASSERT(a)
Definition: mode.c:45
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
#define NULL
Definition: types.h:112

Referenced by EnumerateInstallations().

◆ GetDriverName()

static VOID GetDriverName ( IN PDISKENTRY  DiskEntry)
static

Definition at line 284 of file partlist.c.

286 {
288  WCHAR KeyName[32];
290 
291  RtlInitUnicodeString(&DiskEntry->DriverName, NULL);
292 
294  L"\\Scsi\\Scsi Port %hu",
295  DiskEntry->Port);
296 
298 
299  QueryTable[0].Name = L"Driver";
301  QueryTable[0].EntryContext = &DiskEntry->DriverName;
302 
303  /* This will allocate DiskEntry->DriverName if needed */
305  KeyName,
306  QueryTable,
307  NULL,
308  NULL);
309  if (!NT_SUCCESS(Status))
310  {
311  DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
312  }
313 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4142
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2697
Status
Definition: gdiplustypes.h:24
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR L[]
Definition: oid.c:1250
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RTL_REGISTRY_DEVICEMAP
Definition: nt_native.h:165
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144

Referenced by AddDiskToList().

◆ GetLogicalPartitionCount()

static ULONG GetLogicalPartitionCount ( IN PDISKENTRY  DiskEntry)
static

Definition at line 2634 of file partlist.c.

2636 {
2637  PLIST_ENTRY ListEntry;
2638  PPARTENTRY PartEntry;
2639  ULONG Count = 0;
2640 
2641  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2642  {
2643  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2644  return 0;
2645  }
2646 
2647  for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
2648  ListEntry != &DiskEntry->LogicalPartListHead;
2649  ListEntry = ListEntry->Flink)
2650  {
2651  PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
2652  if (PartEntry->IsPartitioned)
2653  Count++;
2654  }
2655 
2656  return Count;
2657 }
void DPRINT(...)
Definition: polytest.cpp:61
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
int Count
Definition: noreturn.cpp:7
Definition: typedefs.h:119
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN IsPartitioned
Definition: partlist.h:78

Referenced by ReAllocateLayoutBuffer().

◆ GetNextPartition()

PPARTENTRY GetNextPartition ( IN PPARTLIST  List,
IN PPARTENTRY CurrentPart  OPTIONAL 
)

Definition at line 2386 of file partlist.c.

2389 {
2390  PLIST_ENTRY DiskListEntry;
2391  PLIST_ENTRY PartListEntry;
2393 
2394  /* Fail if no disks are available */
2395  if (IsListEmpty(&List->DiskListHead))
2396  return NULL;
2397 
2398  /* Check for the next usable entry on the current partition's disk */
2399  if (CurrentPart != NULL)
2400  {
2401  CurrentDisk = CurrentPart->DiskEntry;
2402 
2403  if (CurrentPart->LogicalPartition)
2404  {
2405  /* Logical partition */
2406 
2407  PartListEntry = CurrentPart->ListEntry.Flink;
2408  if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2409  {
2410  /* Next logical partition */
2411  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2412  return CurrentPart;
2413  }
2414  else
2415  {
2416  PartListEntry = CurrentDisk->ExtendedPartition->ListEntry.Flink;
2417  if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2418  {
2419  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2420  return CurrentPart;
2421  }
2422  }
2423  }
2424  else
2425  {
2426  /* Primary or extended partition */
2427 
2428  if (CurrentPart->IsPartitioned &&
2429  IsContainerPartition(CurrentPart->PartitionType))
2430  {
2431  /* First logical partition */
2432  PartListEntry = CurrentDisk->LogicalPartListHead.Flink;
2433  if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2434  {
2435  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2436  return CurrentPart;
2437  }
2438  }
2439  else
2440  {
2441  /* Next primary partition */
2442  PartListEntry = CurrentPart->ListEntry.Flink;
2443  if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2444  {
2445  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2446  return CurrentPart;
2447  }
2448  }
2449  }
2450  }
2451 
2452  /* Search for the first partition entry on the next disk */
2453  for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Flink
2454  : List->DiskListHead.Flink);
2455  DiskListEntry != &List->DiskListHead;
2456  DiskListEntry = DiskListEntry->Flink)
2457  {
2458  CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
2459 
2461  {
2462  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2463  continue;
2464  }
2465 
2466  PartListEntry = CurrentDisk->PrimaryPartListHead.Flink;
2467  if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2468  {
2469  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2470  return CurrentPart;
2471  }
2472  }
2473 
2474  return NULL;
2475 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:143
PDISKENTRY CurrentDisk
Definition: partlist.c:73
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:316
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
PPARTENTRY ExtendedPartition
Definition: partlist.h:147
LIST_ENTRY ListEntry
Definition: partlist.h:55
PARTITION_STYLE DiskStyle
Definition: partlist.h:133
void DPRINT(...)
Definition: polytest.cpp:61
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY ListEntry
Definition: partlist.h:95
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:144

Referenced by ScrollDownPartitionList().

◆ GetNextUncheckedPartition()

BOOLEAN GetNextUncheckedPartition ( IN PPARTLIST  List,
OUT PDISKENTRY *pDiskEntry  OPTIONAL,
OUT PPARTENTRY pPartEntry 
)

Definition at line 4273 of file partlist.c.

4277 {
4278  PLIST_ENTRY Entry1, Entry2;
4279  PDISKENTRY DiskEntry;
4280  PPARTENTRY PartEntry;
4281 
4282  for (Entry1 = List->DiskListHead.Flink;
4283  Entry1 != &List->DiskListHead;
4284  Entry1 = Entry1->Flink)
4285  {
4286  DiskEntry = CONTAINING_RECORD(Entry1,
4287  DISKENTRY,
4288  ListEntry);
4289 
4290  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
4291  {
4292  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
4293  continue;
4294  }
4295 
4296  for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
4297  Entry2 != &DiskEntry->PrimaryPartListHead;
4298  Entry2 = Entry2->Flink)
4299  {
4300  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4301  if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
4302  {
4303  ASSERT(DiskEntry == PartEntry->DiskEntry);
4304  if (pDiskEntry) *pDiskEntry = DiskEntry;
4305  *pPartEntry = PartEntry;
4306  return TRUE;
4307  }
4308  }
4309 
4310  for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
4311  Entry2 != &DiskEntry->LogicalPartListHead;
4312  Entry2 = Entry2->Flink)
4313  {
4314  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4315  if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
4316  {
4317  ASSERT(DiskEntry == PartEntry->DiskEntry);
4318  if (pDiskEntry) *pDiskEntry = DiskEntry;
4319  *pPartEntry = PartEntry;
4320  return TRUE;
4321  }
4322  }
4323  }
4324 
4325  if (pDiskEntry) *pDiskEntry = NULL;
4326  *pPartEntry = NULL;
4327 
4328  return FALSE;
4329 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:143
#define TRUE
Definition: types.h:120
PARTITION_STYLE DiskStyle
Definition: partlist.h:133
#define FALSE
Definition: types.h:117
void DPRINT(...)
Definition: polytest.cpp:61
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _DISKENTRY * DiskEntry
Definition: partlist.h:58
#define ASSERT(a)
Definition: mode.c:45
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
BOOLEAN NeedsCheck
Definition: partlist.h:89
#define NULL
Definition: types.h:112
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:144
BOOLEAN IsPartitioned
Definition: partlist.h:78

Referenced by CheckFileSystemPage().

◆ GetNextUnformattedPartition()

BOOLEAN GetNextUnformattedPartition ( IN PPARTLIST  List,
OUT PDISKENTRY *pDiskEntry  OPTIONAL,
OUT PPARTENTRY pPartEntry 
)

Definition at line 4214 of file partlist.c.

4218 {
4219  PLIST_ENTRY Entry1, Entry2;
4220  PDISKENTRY DiskEntry;
4221  PPARTENTRY PartEntry;
4222 
4223  for (Entry1 = List->DiskListHead.Flink;
4224  Entry1 != &List->DiskListHead;
4225  Entry1 = Entry1->Flink)
4226  {
4227  DiskEntry = CONTAINING_RECORD(Entry1,
4228  DISKENTRY,
4229  ListEntry);
4230 
4231  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
4232  {
4233  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
4234  continue;
4235  }
4236 
4237  for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
4238  Entry2 != &DiskEntry->PrimaryPartListHead;
4239  Entry2 = Entry2->Flink)
4240  {
4241  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4242  if (PartEntry->IsPartitioned && PartEntry->New)
4243  {
4244  ASSERT(DiskEntry == PartEntry->DiskEntry);
4245  if (pDiskEntry) *pDiskEntry = DiskEntry;
4246  *pPartEntry = PartEntry;
4247  return TRUE;
4248  }
4249  }
4250 
4251  for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
4252  Entry2 != &DiskEntry->LogicalPartListHead;
4253  Entry2 = Entry2->Flink)
4254  {
4255  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4256  if (PartEntry->IsPartitioned && PartEntry->New)
4257  {
4258  ASSERT(DiskEntry == PartEntry->DiskEntry);
4259  if (pDiskEntry) *pDiskEntry = DiskEntry;
4260  *pPartEntry = PartEntry;
4261  return TRUE;
4262  }
4263  }
4264  }
4265 
4266  if (pDiskEntry) *pDiskEntry = NULL;
4267  *pPartEntry = NULL;
4268 
4269  return FALSE;
4270 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:143
#define TRUE
Definition: types.h:120
PARTITION_STYLE DiskStyle
Definition: partlist.h:133
#define FALSE
Definition: types.h:117
void DPRINT(...)
Definition: polytest.cpp:61
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _DISKENTRY * DiskEntry
Definition: partlist.h:58
#define ASSERT(a)
Definition: mode.c:45
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
BOOLEAN New
Definition: partlist.h:83
#define NULL
Definition: types.h:112
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:144
BOOLEAN IsPartitioned
Definition: partlist.h:78

Referenced by SelectFileSystemPage().

◆ GetNextUnpartitionedEntry()

static PPARTENTRY GetNextUnpartitionedEntry ( IN PPARTENTRY  PartEntry)
static

Definition at line 2931 of file partlist.c.

2933 {
2934  PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2935  PPARTENTRY NextPartEntry;
2936  PLIST_ENTRY ListHead;
2937 
2938  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2939  {
2940  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2941  return NULL;
2942  }
2943 
2944  if (PartEntry->LogicalPartition)
2945  ListHead = &DiskEntry->LogicalPartListHead;
2946  else
2947  ListHead = &DiskEntry->PrimaryPartListHead;
2948 
2949  if (PartEntry->ListEntry.Flink != ListHead)
2950  {
2951  NextPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Flink,
2952  PARTENTRY,
2953  ListEntry);
2954  if (!NextPartEntry->IsPartitioned)
2955  {
2956  ASSERT(NextPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
2957  return NextPartEntry;
2958  }
2959  }
2960 
2961  return NULL;
2962 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:143
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
PARTITION_STYLE DiskStyle
Definition: partlist.h:133
void DPRINT(...)
Definition: polytest.cpp:61
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
UCHAR PartitionType
Definition: partlist.h:65
#define ASSERT(a)
Definition: mode.c:45
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:144
BOOLEAN IsPartitioned
Definition: partlist.h:78

Referenced by DeletePartition().

◆ GetPartition()

PPARTENTRY GetPartition ( IN PDISKENTRY  DiskEntry,
IN ULONG  PartitionNumber 
)

Definition at line 2275 of file partlist.c.

2279 {
2280  PPARTENTRY PartEntry;
2282 
2283  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2284  {
2285  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2286  return NULL;
2287  }
2288 
2289  /* Disk found, loop over the primary partitions first... */
2290  for (Entry = DiskEntry->PrimaryPartListHead.Flink;
2291  Entry != &DiskEntry->PrimaryPartListHead;
2292  Entry = Entry->Flink)
2293  {
2294  PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2295 
2296  if (PartEntry->PartitionNumber == PartitionNumber)
2297  {
2298  /* Partition found */
2299  return PartEntry;
2300  }
2301  }
2302 
2303  /* ... then over the logical partitions if needed */
2304  for (Entry = DiskEntry->LogicalPartListHead.Flink;
2305  Entry != &DiskEntry->LogicalPartListHead;
2306  Entry = Entry->Flink)
2307  {
2308  PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2309 
2310  if (PartEntry->PartitionNumber == PartitionNumber)
2311  {
2312  /* Partition found */
2313  return PartEntry;
2314  }
2315  }
2316 
2317  /* The partition was not found on the disk, stop there */
2318  return NULL;
2319 }
ULONG PartitionNumber
Definition: partlist.h:67
struct _Entry Entry
Definition: kefuncs.h:627
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2056
void DPRINT(...)
Definition: polytest.cpp:61
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
base of all file and directory entries
Definition: entries.h:82

Referenced by GetDiskOrPartition(), ResolveArcNameManually(), and SelectPartition().

◆ GetPrevPartition()

PPARTENTRY GetPrevPartition ( IN PPARTLIST  List,
IN PPARTENTRY CurrentPart  OPTIONAL 
)

Definition at line 2478 of file partlist.c.

2481 {
2482  PLIST_ENTRY DiskListEntry;
2483  PLIST_ENTRY PartListEntry;
2485 
2486  /* Fail if no disks are available */
2487  if (IsListEmpty(&List->DiskListHead))
2488  return NULL;
2489 
2490  /* Check for the previous usable entry on the current partition's disk */
2491  if (CurrentPart != NULL)
2492  {
2493  CurrentDisk = CurrentPart->DiskEntry;
2494 
2495  if (CurrentPart->LogicalPartition)
2496  {
2497  /* Logical partition */
2498 
2499  PartListEntry = CurrentPart->ListEntry.Blink;
2500  if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2501  {
2502  /* Previous logical partition */
2503  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2504  }
2505  else
2506  {
2507  /* Extended partition */
2508  CurrentPart = CurrentDisk->ExtendedPartition;
2509  }
2510  return CurrentPart;
2511  }
2512  else
2513  {
2514  /* Primary or extended partition */
2515 
2516  PartListEntry = CurrentPart->ListEntry.Blink;
2517  if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2518  {
2519  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2520 
2521  if (CurrentPart->IsPartitioned &&
2522  IsContainerPartition(CurrentPart->PartitionType))
2523  {
2524  PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2525  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2526  }
2527 
2528  return CurrentPart;
2529  }
2530  }
2531  }
2532 
2533  /* Search for the last partition entry on the previous disk */
2534  for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Blink
2535  : List->DiskListHead.Blink);
2536  DiskListEntry != &List->DiskListHead;
2537  DiskListEntry = DiskListEntry->Blink)
2538  {
2539  CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
2540 
2542  {
2543  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2544  continue;
2545  }
2546 
2547  PartListEntry = CurrentDisk->PrimaryPartListHead.Blink;
2548  if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2549  {
2550  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2551 
2552  if (CurrentPart->IsPartitioned &&
2553  IsContainerPartition(CurrentPart->PartitionType))
2554  {
2555  PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2556  if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2557  {
2558  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2559  return CurrentPart;
2560  }
2561  }
2562  else
2563  {
2564  return CurrentPart;
2565  }
2566  }
2567  }
2568 
2569  return NULL;
2570 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:143
PDISKENTRY CurrentDisk
Definition: partlist.c:73
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:316
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
PPARTENTRY ExtendedPartition
Definition: partlist.h:147
PARTITION_STYLE DiskStyle
Definition: partlist.h:133
void DPRINT(...)
Definition: polytest.cpp:61
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
LIST_ENTRY ListEntry
Definition: partlist.h:95
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:144

Referenced by ScrollUpPartitionList().

◆ GetPrevUnpartitionedEntry()

static PPARTENTRY GetPrevUnpartitionedEntry ( IN PPARTENTRY  PartEntry)
static

Definition at line 2896 of file partlist.c.

2898 {
2899  PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2900  PPARTENTRY PrevPartEntry;
2901  PLIST_ENTRY ListHead;
2902 
2903  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2904  {
2905  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2906  return NULL;
2907  }
2908 
2909  if (PartEntry->LogicalPartition)
2910  ListHead = &DiskEntry->LogicalPartListHead;
2911  else
2912  ListHead = &DiskEntry->PrimaryPartListHead;
2913 
2914  if (PartEntry->ListEntry.Blink != ListHead)
2915  {
2916  PrevPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Blink,
2917  PARTENTRY,
2918  ListEntry);
2919  if (!PrevPartEntry->IsPartitioned)
2920  {
2921  ASSERT(PrevPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
2922  return PrevPartEntry;
2923  }
2924  }
2925 
2926  return NULL;
2927 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:143
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
PARTITION_STYLE DiskStyle
Definition: partlist.h:133
void DPRINT(...)
Definition: polytest.cpp:61
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
UCHAR PartitionType
Definition: partlist.h:65
#define ASSERT(a)
Definition: mode.c:45
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:144
BOOLEAN IsPartitioned
Definition: partlist.h:78

Referenced by DeletePartition().

◆ GetPrimaryPartitionCount()

static ULONG GetPrimaryPartitionCount ( IN PDISKENTRY  DiskEntry)
static

Definition at line 2607 of file partlist.c.

2609 {
2611  PPARTENTRY PartEntry;
2612  ULONG Count = 0;
2613 
2614  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2615  {
2616  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2617  return 0;
2618  }
2619 
2620  for (Entry = DiskEntry->PrimaryPartListHead.Flink;
2621  Entry != &DiskEntry->PrimaryPartListHead;
2622  Entry = Entry->Flink)
2623  {
2624  PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2625  if (PartEntry->IsPartitioned)
2626  Count++;
2627  }
2628 
2629  return Count;
2630 }
struct _Entry Entry
Definition: kefuncs.h:627
void DPRINT(...)
Definition: polytest.cpp:61
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
int Count
Definition: noreturn.cpp:7
Definition: typedefs.h:119
unsigned int ULONG
Definition: retypes.h:1
base of all file and directory entries
Definition: entries.h:82
BOOLEAN IsPartitioned
Definition: partlist.h:78

Referenced by ExtendedPartitionCreationChecks(), FindSupportedSystemPartition(), PrimaryPartitionCreationChecks(), and UpdateDiskLayout().

◆ GetSystemDisk()

static PDISKENTRY GetSystemDisk ( IN PPARTLIST  List)
static

Definition at line 1897 of file partlist.c.

1899 {
1901  PDISKENTRY DiskEntry;
1902 
1903  /* Check for empty disk list */
1904  if (IsListEmpty(&List->DiskListHead))
1905  return NULL;
1906 
1907  /*
1908  * If we already have a system partition, the system disk
1909  * is the one on which the system partition resides.
1910  */
1911  if (List->SystemPartition)
1912  return List->SystemPartition->DiskEntry;
1913 
1914  /* Loop over the disks and find the correct one */
1915  for (Entry = List->DiskListHead.Flink;
1916  Entry != &List->DiskListHead;
1917  Entry = Entry->Flink)
1918  {
1919  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
1920 
1921  /* The disk must be a fixed disk and be found by the firmware */
1922  if (DiskEntry->MediaType == FixedMedia && DiskEntry->BiosFound)
1923  {
1924  break;
1925  }
1926  }
1927  if (Entry == &List->DiskListHead)
1928  {
1929  /* We haven't encountered any suitable disk */
1930  return NULL;
1931  }
1932 
1933  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1934  {
1935  DPRINT1("System disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
1936  }
1937 
1938  return DiskEntry;
1939 }
struct _Entry Entry
Definition: kefuncs.h:627
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
PARTITION_STYLE DiskStyle
Definition: partlist.h:133
MEDIA_TYPE MediaType
Definition: partlist.h:100
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
BOOLEAN BiosFound
Definition: partlist.h:114
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
base of all file and directory entries
Definition: entries.h:82

Referenced by CreatePartitionList(), FindSupportedSystemPartition(), and SetActivePartition().

◆ InitializePartitionEntry()

static BOOLEAN InitializePartitionEntry ( IN OUT PPARTENTRY  PartEntry,
IN ULONGLONG  SectorCount,
IN BOOLEAN  AutoCreate 
)
static

Definition at line 857 of file partlist.c.

861 {
862  PDISKENTRY DiskEntry = PartEntry->DiskEntry;
863 
864  DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart);
865 
866  /* Fail if we try to initialize this partition entry with more sectors than what it actually contains */
867  if (SectorCount > PartEntry->SectorCount.QuadPart)
868  return FALSE;
869 
870  /* Fail if the partition is already in use */
871  ASSERT(!PartEntry->IsPartitioned);
872 
873  if ((AutoCreate != FALSE) ||
874  (AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) -
875  PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart))
876  {
877  PartEntry->AutoCreate = AutoCreate;
878  }
879  else
880  {
881  ULONGLONG StartSector;
882  ULONGLONG SectorCount2;
883  PPARTENTRY NewPartEntry;
884 
885  /* Create a partition entry that represents the remaining space after the partition to be initialized */
886 
887  StartSector = AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment);
888  SectorCount2 = PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - StartSector;
889 
890  NewPartEntry = CreateInsertBlankRegion(DiskEntry,
891  PartEntry->ListEntry.Flink,
892  StartSector,
893  SectorCount2,
894  PartEntry->LogicalPartition);
895  if (NewPartEntry == NULL)
896  {
897  DPRINT1("Failed to create a new empty region for disk space!\n");
898  return FALSE;
899  }
900 
901  /* Resize down the partition entry; its StartSector remains the same */
902  PartEntry->SectorCount.QuadPart = StartSector - PartEntry->StartSector.QuadPart;
903  }
904 
905  /* Convert the partition entry to 'New (Unformatted)' */
906  PartEntry->New = TRUE;
907  PartEntry->IsPartitioned = TRUE;
908 
909 // FIXME: Use FileSystemToMBRPartitionType() only for MBR, otherwise use PARTITION_BASIC_DATA_GUID.
910  PartEntry->PartitionType = FileSystemToMBRPartitionType(L"RAW",
911  PartEntry->StartSector.QuadPart,
912  PartEntry->SectorCount.QuadPart);
913  ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
914 
915  PartEntry->FormatState = Unformatted;
916  PartEntry->FileSystem[0] = L'\0';
917  // PartEntry->AutoCreate = AutoCreate;
918  PartEntry->BootIndicator = FALSE;
919 
920  DPRINT1("First Sector : %I64u\n", PartEntry->StartSector.QuadPart);
921  DPRINT1("Last Sector : %I64u\n", PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1);
922  DPRINT1("Total Sectors: %I64u\n", PartEntry->SectorCount.QuadPart);
923 
924  return TRUE;
925 }
#define TRUE
Definition: types.h:120
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
#define FALSE
Definition: types.h:117
ULONG SectorAlignment
Definition: partlist.h:110
static PPARTENTRY CreateInsertBlankRegion(IN PDISKENTRY DiskEntry, IN OUT PLIST_ENTRY ListHead, IN ULONGLONG StartSector, IN ULONGLONG SectorCount, IN BOOLEAN LogicalSpace)
Definition: partlist.c:819
#define ASSERT(a)
Definition: mode.c:45
uint64_t ULONGLONG
Definition: typedefs.h:67
UCHAR FileSystemToMBRPartitionType(IN PCWSTR FileSystem, IN ULONGLONG StartSector, IN ULONGLONG SectorCount)
Definition: fsrec.c:333
ULONGLONG AlignDown(IN ULONGLONG Value, IN ULONG Alignment)
Definition: partlist.c:246
static const WCHAR L[]
Definition: oid.c:1250
ULONG SectorCount
Definition: part_xbox.c:31
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8

Referenced by CreateExtendedPartition(), CreateLogicalPartition(), and CreatePrimaryPartition().

◆ InsertDiskRegion()

static BOOLEAN InsertDiskRegion ( IN PDISKENTRY  DiskEntry,
IN PPARTENTRY  PartEntry,
IN BOOLEAN  LogicalPartition 
)
static

Definition at line 753 of file partlist.c.

757 {
760  PPARTENTRY PartEntry2;
761 
762  /* Use the correct partition list */
763  if (LogicalPartition)
764  List = &DiskEntry->LogicalPartListHead;
765  else
766  List = &DiskEntry->PrimaryPartListHead;
767 
768  /* Find the first disk region before which we need to insert the new one */
769  for (Entry = List->Flink; Entry != List; Entry = Entry->Flink)
770  {
771  PartEntry2 = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
772 
773  /* Ignore any unused empty region */
774  if ((PartEntry2->PartitionType == PARTITION_ENTRY_UNUSED &&
775  PartEntry2->StartSector.QuadPart == 0) || PartEntry2->SectorCount.QuadPart == 0)
776  {
777  continue;
778  }
779 
780  /* If the current region ends before the one to be inserted, try again */
781  if (PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1 < PartEntry->StartSector.QuadPart)
782  continue;
783 
784  /*
785  * One of the disk region boundaries crosses the desired region
786  * (it starts after the desired region, or ends before the end
787  * of the desired region): this is an impossible situation because
788  * disk regions (partitions) cannot overlap!
789  * Throw an error and bail out.
790  */
791  if (max(PartEntry->StartSector.QuadPart, PartEntry2->StartSector.QuadPart)
792  <=
793  min( PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1,
794  PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1))
795  {
796  DPRINT1("Disk region overlap problem, stopping there!\n"
797  "Partition to be inserted:\n"
798  " StartSector = %I64u ; EndSector = %I64u\n"
799  "Existing disk region:\n"
800  " StartSector = %I64u ; EndSector = %I64u\n",
801  PartEntry->StartSector.QuadPart,
802  PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1,
803  PartEntry2->StartSector.QuadPart,
804  PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1);
805  return FALSE;
806  }
807 
808  /* We have found the first region before which the new one has to be inserted */
809  break;
810  }
811 
812  /* Insert the disk region */
813  InsertTailList(Entry, &PartEntry->ListEntry);
814  return TRUE;
815 }
#define max(a, b)
Definition: svc.c:63
ULARGE_INTEGER StartSector
Definition: partlist.h:61
struct _Entry Entry
Definition: kefuncs.h:627
#define TRUE
Definition: types.h:120
ULARGE_INTEGER SectorCount
Definition: partlist.h:62
#define InsertTailList(ListHead, Entry)
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define FALSE
Definition: types.h:117
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
UCHAR PartitionType
Definition: partlist.h:65
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
#define min(a, b)
Definition: monoChain.cc:55
#define DPRINT1
Definition: precomp.h:8
base of all file and directory entries
Definition: entries.h:82

Referenced by AddPartitionToDisk().

◆ IsEmptyLayoutEntry()

FORCEINLINE BOOLEAN IsEmptyLayoutEntry ( IN PPARTITION_INFORMATION  PartitionInfo)

Definition at line 2575 of file partlist.c.

2577 {
2578  if (PartitionInfo->StartingOffset.QuadPart == 0 &&
2579  PartitionInfo->PartitionLength.QuadPart == 0)
2580  {
2581  return TRUE;
2582  }
2583 
2584  return FALSE;
2585 }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2101

Referenced by UpdateDiskLayout().

◆ IsPartitionActive()

BOOLEAN IsPartitionActive ( IN PPARTENTRY  PartEntry)

Definition at line 1947 of file partlist.c.

1949 {
1950  // TODO: Support for GPT disks!
1951 
1952  if (IsContainerPartition(PartEntry->PartitionType))
1953  return FALSE;
1954 
1955  /* Check if the partition is partitioned, used and active */
1956  if (PartEntry->IsPartitioned &&
1957  // !IsContainerPartition(PartEntry->PartitionType) &&
1958  PartEntry->BootIndicator)
1959  {
1960  /* Yes it is */
1961  ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
1962  return TRUE;
1963  }
1964 
1965  return FALSE;
1966 }
#define TRUE
Definition: types.h:120
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:316
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
#define FALSE
Definition: types.h:117
#define ASSERT(a)
Definition: mode.c:45

Referenced by GetActiveDiskPartition(), SelectPartitionPage(), and SetActivePartition().

◆ IsSamePrimaryLayoutEntry()

FORCEINLINE BOOLEAN IsSamePrimaryLayoutEntry ( IN PPARTITION_INFORMATION  PartitionInfo,
IN PDISKENTRY  DiskEntry,
IN PPARTENTRY  PartEntry 
)

Definition at line 2590 of file partlist.c.

2594 {
2595  if (PartitionInfo->StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector &&
2596  PartitionInfo->PartitionLength.QuadPart == PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector)
2597 // PartitionInfo->PartitionType == PartEntry->PartitionType
2598  {
2599  return TRUE;
2600  }
2601 
2602  return FALSE;
2603 }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2101

Referenced by UpdateDiskLayout().

◆ IsSuperFloppy()

BOOLEAN IsSuperFloppy ( IN PDISKENTRY  DiskEntry)

Definition at line 680 of file partlist.c.

682 {
684  ULONGLONG PartitionLengthEstimate;
685 
686  /* No layout buffer: we cannot say anything yet */
687  if (DiskEntry->LayoutBuffer == NULL)
688  return FALSE;
689 
690  /* We must have only one partition */
691  if (DiskEntry->LayoutBuffer->PartitionCount != 1)
692  return FALSE;
693 
694  /* Get the single partition entry */
695  PartitionInfo = DiskEntry->LayoutBuffer->PartitionEntry;
696 
697  /* The single partition must start at the beginning of the disk */
698  if (!(PartitionInfo->StartingOffset.QuadPart == 0 &&
699  PartitionInfo->HiddenSectors == 0))
700  {
701  return FALSE;
702  }
703 
704  /* The disk signature is usually set to one; warn in case it's not */
705  if (DiskEntry->LayoutBuffer->Signature != 1)
706  {
707  DPRINT1("Super-Floppy disk %lu signature %08x != 1!\n",
708  DiskEntry->DiskNumber, DiskEntry->LayoutBuffer->Signature);
709  }
710 
711  /*
712  * The partition number must be zero or one, be recognized,
713  * have FAT16 type and report as non-bootable.
714  */
715  if ((PartitionInfo->PartitionNumber != 0 &&
716  PartitionInfo->PartitionNumber != 1) ||
717  PartitionInfo->RecognizedPartition != TRUE ||
718  PartitionInfo->PartitionType != PARTITION_FAT_16 ||
719  PartitionInfo->BootIndicator != FALSE)
720  {
721  DPRINT1("Super-Floppy disk %lu does not return default settings!\n"
722  " PartitionNumber = %lu, expected 0\n"
723  " RecognizedPartition = %s, expected TRUE\n"
724  " PartitionType = 0x%02x, expected 0x04 (PARTITION_FAT_16)\n"
725  " BootIndicator = %s, expected FALSE\n",
726  DiskEntry->DiskNumber,
727  PartitionInfo->PartitionNumber,
728  PartitionInfo->RecognizedPartition ? "TRUE" : "FALSE",
729  PartitionInfo->PartitionType,
730  PartitionInfo->BootIndicator ? "TRUE" : "FALSE");
731  }
732 
733  /* The partition lengths should agree */
734  PartitionLengthEstimate = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
735  if (PartitionInfo->PartitionLength.QuadPart != PartitionLengthEstimate)
736  {
737  DPRINT1("PartitionLength = %I64u is different from PartitionLengthEstimate = %I64u\n",
738  PartitionInfo->PartitionLength.QuadPart, PartitionLengthEstimate);
739  }
740 
741  return TRUE;
742 }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
uint64_t ULONGLONG
Definition: typedefs.h:67
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2101
#define PARTITION_FAT_16
Definition: disk.h:90
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8

Referenced by AddDiskToList(), BootLoaderHarddiskMbrPage(), ExtendedPartitionCreationChecks(), LogicalPartitionCreationChecks(), PrimaryPartitionCreationChecks(), and xHalIoWritePartitionTable().

◆ IsSupportedActivePartition()

static BOOLEAN IsSupportedActivePartition ( IN PPARTENTRY  PartEntry)
static

Definition at line 3359 of file partlist.c.

3361 {
3362  /* Check the type and the file system of this partition */
3363 
3364  /*
3365  * We do not support extended partition containers (on MBR disks) marked
3366  * as active, and containing code inside their extended boot records.
3367  */
3368  if (IsContainerPartition(PartEntry->PartitionType))
3369  {
3370  DPRINT1("System partition %lu in disk %lu is an extended partition container?!\n",
3371  PartEntry->PartitionNumber, PartEntry->DiskEntry->DiskNumber);
3372  return FALSE;
3373  }
3374 
3375  /*
3376  * ADDITIONAL CHECKS / BIG HACK:
3377  *
3378  * Retrieve its file system and check whether we have
3379  * write support for it. If that is the case we are fine
3380  * and we can use it directly. However if we don't have
3381  * write support we will need to change the active system
3382  * partition.
3383  *
3384  * NOTE that this is completely useless on architectures
3385  * where a real system partition is required, as on these
3386  * architectures the partition uses the FAT FS, for which
3387  * we do have write support.
3388  * NOTE also that for those architectures looking for a
3389  * partition boot indicator is insufficient.
3390  */
3391  if (PartEntry->FormatState == Unformatted)
3392  {
3393  /* If this partition is mounted, it would use RawFS ("RAW") */
3394  return TRUE;
3395  }
3396  else if ((PartEntry->FormatState == Preformatted) ||
3397  (PartEntry->FormatState == Formatted))
3398  {
3399  ASSERT(*PartEntry->FileSystem);
3400 
3401  /* NOTE: Please keep in sync with the RegisteredFileSystems list! */
3402  if (wcsicmp(PartEntry->FileSystem, L"FAT") == 0 ||
3403  wcsicmp(PartEntry->FileSystem, L"FAT32") == 0 ||
3404  // wcsicmp(PartEntry->FileSystem, L"NTFS") == 0 ||
3405