ReactOS  0.4.14-dev-833-g5f692ed
partlist.c File Reference
#include "precomp.h"
#include <ntddscsi.h>
#include "partlist.h"
#include "fsutil.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 SetPartitionType (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 1483 of file partlist.c.

1487 {
1488  DISK_GEOMETRY DiskGeometry;
1489  SCSI_ADDRESS ScsiAddress;
1490  PDISKENTRY DiskEntry;
1492  NTSTATUS Status;
1493  PPARTITION_SECTOR Mbr;
1494  PULONG Buffer;
1496  WCHAR Identifier[20];
1497  ULONG Checksum;
1498  ULONG Signature;
1499  ULONG i;
1500  PLIST_ENTRY ListEntry;
1501  PBIOSDISKENTRY BiosDiskEntry;
1502  ULONG LayoutBufferSize;
1503  PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
1504 
1505  /* Retrieve the drive geometry */
1507  NULL,
1508  NULL,
1509  NULL,
1510  &Iosb,
1512  NULL,
1513  0,
1514  &DiskGeometry,
1515  sizeof(DiskGeometry));
1516  if (!NT_SUCCESS(Status))
1517  return;
1518 
1519  if (DiskGeometry.MediaType != FixedMedia &&
1520  DiskGeometry.MediaType != RemovableMedia)
1521  {
1522  return;
1523  }
1524 
1525  /*
1526  * FIXME: Here we suppose the disk is always SCSI. What if it is
1527  * of another type? To check this we need to retrieve the name of
1528  * the driver the disk device belongs to.
1529  */
1531  NULL,
1532  NULL,
1533  NULL,
1534  &Iosb,
1536  NULL,
1537  0,
1538  &ScsiAddress,
1539  sizeof(ScsiAddress));
1540  if (!NT_SUCCESS(Status))
1541  return;
1542 
1543  /*
1544  * Check whether the disk is initialized, by looking at its MBR.
1545  * NOTE that this must be generalized to GPT disks as well!
1546  */
1547 
1549  0,
1550  DiskGeometry.BytesPerSector);
1551  if (Mbr == NULL)
1552  return;
1553 
1554  FileOffset.QuadPart = 0;
1556  NULL,
1557  NULL,
1558  NULL,
1559  &Iosb,
1560  (PVOID)Mbr,
1561  DiskGeometry.BytesPerSector,
1562  &FileOffset,
1563  NULL);
1564  if (!NT_SUCCESS(Status))
1565  {
1566  RtlFreeHeap(ProcessHeap, 0, Mbr);
1567  DPRINT1("NtReadFile failed, status=%x\n", Status);
1568  return;
1569  }
1570  Signature = Mbr->Signature;
1571 
1572  /* Calculate the MBR checksum */
1573  Checksum = 0;
1574  Buffer = (PULONG)Mbr;
1575  for (i = 0; i < 128; i++)
1576  {
1577  Checksum += Buffer[i];
1578  }
1579  Checksum = ~Checksum + 1;
1580 
1581  RtlStringCchPrintfW(Identifier, ARRAYSIZE(Identifier),
1582  L"%08x-%08x-%c",
1583  Checksum, Signature,
1584  (Mbr->Magic == PARTITION_MAGIC) ? L'A' : L'X');
1585  DPRINT("Identifier: %S\n", Identifier);
1586 
1587  DiskEntry = RtlAllocateHeap(ProcessHeap,
1589  sizeof(DISKENTRY));
1590  if (DiskEntry == NULL)
1591  {
1592  RtlFreeHeap(ProcessHeap, 0, Mbr);
1593  DPRINT1("Failed to allocate a new disk entry.\n");
1594  return;
1595  }
1596 
1597  DiskEntry->PartList = List;
1598 
1599 #if 0
1600  {
1601  FILE_FS_DEVICE_INFORMATION FileFsDevice;
1602 
1603  /* Query the device for its type */
1605  &Iosb,
1606  &FileFsDevice,
1607  sizeof(FileFsDevice),
1609  if (!NT_SUCCESS(Status))
1610  {
1611  DPRINT1("Couldn't detect device type for disk %lu of identifier '%S'...\n", DiskNumber, Identifier);
1612  }
1613  else
1614  {
1615  DPRINT1("Disk %lu : DeviceType: 0x%08x ; Characteristics: 0x%08x\n", DiskNumber, FileFsDevice.DeviceType, FileFsDevice.Characteristics);
1616  }
1617  }
1618  // NOTE: We may also use NtQueryVolumeInformationFile(FileFsDeviceInformation).
1619 #endif
1620  DiskEntry->MediaType = DiskGeometry.MediaType;
1621  if (DiskEntry->MediaType == RemovableMedia)
1622  {
1623  DPRINT1("Disk %lu of identifier '%S' is removable\n", DiskNumber, Identifier);
1624  }
1625  else // if (DiskEntry->MediaType == FixedMedia)
1626  {
1627  DPRINT1("Disk %lu of identifier '%S' is fixed\n", DiskNumber, Identifier);
1628  }
1629 
1630 // DiskEntry->Checksum = Checksum;
1631 // DiskEntry->Signature = Signature;
1632  DiskEntry->BiosFound = FALSE;
1633 
1634  /*
1635  * Check if this disk has a valid MBR: verify its signature,
1636  * and whether its two first bytes are a valid instruction
1637  * (related to this, see IsThereAValidBootSector() in partlist.c).
1638  *
1639  * See also ntoskrnl/fstub/fstubex.c!FstubDetectPartitionStyle().
1640  */
1641 
1642  // DiskEntry->NoMbr = (Mbr->Magic != PARTITION_MAGIC || (*(PUSHORT)Mbr->BootCode) == 0x0000);
1643 
1644  /* If we have not the 0xAA55 then it's raw partition */
1645  if (Mbr->Magic != PARTITION_MAGIC)
1646  {
1647  DiskEntry->DiskStyle = PARTITION_STYLE_RAW;
1648  }
1649  /* Check partitions types: if first is 0xEE and all the others 0, we have GPT */
1650  else if (Mbr->Partition[0].PartitionType == EFI_PMBR_OSTYPE_EFI &&
1651  Mbr->Partition[1].PartitionType == 0 &&
1652  Mbr->Partition[2].PartitionType == 0 &&
1653  Mbr->Partition[3].PartitionType == 0)
1654  {
1655  DiskEntry->DiskStyle = PARTITION_STYLE_GPT;
1656  }
1657  /* Otherwise, partition table is in MBR */
1658  else
1659  {
1660  DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
1661  }
1662 
1663  /* Free the MBR sector buffer */
1664  RtlFreeHeap(ProcessHeap, 0, Mbr);
1665 
1666 
1667  for (ListEntry = List->BiosDiskListHead.Flink;
1668  ListEntry != &List->BiosDiskListHead;
1669  ListEntry = ListEntry->Flink)
1670  {
1671  BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
1672  /* FIXME:
1673  * Compare the size from bios and the reported size from driver.
1674  * If we have more than one disk with a zero or with the same signature
1675  * we must create new signatures and reboot. After the reboot,
1676  * it is possible to identify the disks.
1677  */
1678  if (BiosDiskEntry->Signature == Signature &&
1679  BiosDiskEntry->Checksum == Checksum &&
1680  BiosDiskEntry->DiskEntry == NULL)
1681  {
1682  if (!DiskEntry->BiosFound)
1683  {
1684  DiskEntry->HwAdapterNumber = BiosDiskEntry->AdapterNumber;
1685  DiskEntry->HwControllerNumber = BiosDiskEntry->ControllerNumber;
1686  DiskEntry->HwDiskNumber = BiosDiskEntry->DiskNumber;
1687 
1688  if (DiskEntry->MediaType == RemovableMedia)
1689  {
1690  /* Set the removable disk number to zero */
1691  DiskEntry->HwFixedDiskNumber = 0;
1692  }
1693  else // if (DiskEntry->MediaType == FixedMedia)
1694  {
1695  /* The fixed disk number will later be adjusted using the number of removable disks */
1696  DiskEntry->HwFixedDiskNumber = BiosDiskEntry->DiskNumber;
1697  }
1698 
1699  DiskEntry->BiosFound = TRUE;
1700  BiosDiskEntry->DiskEntry = DiskEntry;
1701  break;
1702  }
1703  else
1704  {
1705  // FIXME: What to do?
1706  DPRINT1("Disk %lu of identifier '%S' has already been found?!\n", DiskNumber, Identifier);
1707  }
1708  }
1709  }
1710 
1711  if (!DiskEntry->BiosFound)
1712  {
1713  DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %lu may not be bootable by the BIOS!\n", DiskNumber);
1714  }
1715 
1716  DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
1717  DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
1718  DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
1719  DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
1720 
1721  DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders);
1722  DPRINT("TracksPerCylinder %lu\n", DiskEntry->TracksPerCylinder);
1723  DPRINT("SectorsPerTrack %lu\n", DiskEntry->SectorsPerTrack);
1724  DPRINT("BytesPerSector %lu\n", DiskEntry->BytesPerSector);
1725 
1726  DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart *
1727  (ULONGLONG)DiskGeometry.TracksPerCylinder *
1728  (ULONGLONG)DiskGeometry.SectorsPerTrack;
1729 
1730  DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
1731  DiskEntry->CylinderAlignment = DiskGeometry.TracksPerCylinder *
1732  DiskGeometry.SectorsPerTrack;
1733 
1734  DPRINT("SectorCount %I64u\n", DiskEntry->SectorCount.QuadPart);
1735  DPRINT("SectorAlignment %lu\n", DiskEntry->SectorAlignment);
1736 
1737  DiskEntry->DiskNumber = DiskNumber;
1738  DiskEntry->Port = ScsiAddress.PortNumber;
1739  DiskEntry->Bus = ScsiAddress.PathId;
1740  DiskEntry->Id = ScsiAddress.TargetId;
1741 
1742  GetDriverName(DiskEntry);
1743  /*
1744  * Actually it would be more correct somehow to use:
1745  *
1746  * OBJECT_NAME_INFORMATION NameInfo; // ObjectNameInfo;
1747  * ULONG ReturnedLength;
1748  *
1749  * Status = NtQueryObject(SomeHandleToTheDisk,
1750  * ObjectNameInformation,
1751  * &NameInfo,
1752  * sizeof(NameInfo),
1753  * &ReturnedLength);
1754  * etc...
1755  *
1756  * See examples in https://git.reactos.org/?p=reactos.git;a=blob;f=reactos/ntoskrnl/io/iomgr/error.c;hb=2f3a93ee9cec8322a86bf74b356f1ad83fc912dc#l267
1757  */
1758 
1761 
1762  InsertAscendingList(&List->DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber);
1763 
1764 
1765  /*
1766  * We now retrieve the disk partition layout
1767  */
1768 
1769  /*
1770  * Stop there now if the disk is GPT-partitioned,
1771  * since we currently do not support such disks.
1772  */
1773  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1774  {
1775  DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1776  return;
1777  }
1778 
1779  /* Allocate a layout buffer with 4 partition entries first */
1780  LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
1781  ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
1784  LayoutBufferSize);
1785  if (DiskEntry->LayoutBuffer == NULL)
1786  {
1787  DPRINT1("Failed to allocate the disk layout buffer!\n");
1788  return;
1789  }
1790 
1791  /* Keep looping while the drive layout buffer is too small */
1792  for (;;)
1793  {
1794  DPRINT1("Buffer size: %lu\n", LayoutBufferSize);
1796  NULL,
1797  NULL,
1798  NULL,
1799  &Iosb,
1801  NULL,
1802  0,
1803  DiskEntry->LayoutBuffer,
1804  LayoutBufferSize);
1805  if (NT_SUCCESS(Status))
1806  break;
1807 
1809  {
1810  DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status);
1811  return;
1812  }
1813 
1814  LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION);
1815  NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap,
1817  DiskEntry->LayoutBuffer,
1818  LayoutBufferSize);
1819  if (NewLayoutBuffer == NULL)
1820  {
1821  DPRINT1("Failed to reallocate the disk layout buffer!\n");
1822  return;
1823  }
1824 
1825  DiskEntry->LayoutBuffer = NewLayoutBuffer;
1826  }
1827 
1828  DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount);
1829 
1830 #ifdef DUMP_PARTITION_TABLE
1831  DumpPartitionTable(DiskEntry);
1832 #endif
1833 
1834  if (IsSuperFloppy(DiskEntry))
1835  DPRINT1("Disk %lu is a super-floppy\n", DiskNumber);
1836 
1837  if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
1838  DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0 &&
1840  {
1841  if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
1842  {
1843  DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
1844  }
1845  else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
1846  {
1847  DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1848  }
1849  else
1850  {
1851  DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
1852  }
1853  }
1854  else
1855  {
1856  DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1857  }
1858 
1859  if (DiskEntry->LayoutBuffer->PartitionCount == 0)
1860  {
1861  DiskEntry->NewDisk = TRUE;
1862  DiskEntry->LayoutBuffer->PartitionCount = 4;
1863 
1864  for (i = 0; i < 4; i++)
1865  {
1867  }
1868  }
1869  else
1870  {
1871  /* Enumerate and add the first four primary partitions */
1872  for (i = 0; i < 4; i++)
1873  {
1874  AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
1875  }
1876 
1877  /* Enumerate and add the remaining partitions as logical ones */
1878  for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
1879  {
1880  AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
1881  }
1882  }
1883 
1884  ScanForUnpartitionedDiskSpace(DiskEntry);
1885 }
UCHAR PathId
Definition: scsi_port.h:149
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:124
struct _PARTLIST * PartList
Definition: partlist.h:79
UCHAR PortNumber
Definition: scsi_port.h:148
USHORT Id
Definition: partlist.h:108
#define TRUE
Definition: types.h:120
LARGE_INTEGER PartitionLength
Definition: ntdddisk.h:399
#define IOCTL_SCSI_GET_ADDRESS
Definition: scsi_port.h:52
ULONG HwControllerNumber
Definition: partlist.h:97
ULONG CylinderAlignment
Definition: partlist.h:92
#define ANYSIZE_ARRAY
Definition: typedefs.h:45
USHORT Bus
Definition: partlist.h:107
ULONG HwAdapterNumber
Definition: partlist.h:96
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:139
ULONG Signature
Definition: partlist.h:138
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:136
ULONG DiskNumber
Definition: partlist.h:104
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
ULONG BytesPerSector
Definition: ntdddisk.h:381
ULONG TracksPerCylinder
Definition: ntdddisk.h:379
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
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2561
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
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
PARTITION_STYLE DiskStyle
Definition: partlist.h:114
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
struct _DRIVE_LAYOUT_INFORMATION DRIVE_LAYOUT_INFORMATION
smooth NULL
Definition: ftsmooth.c:416
PARTITION_INFORMATION PartitionEntry[1]
Definition: ntdddisk.h:476
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
MEDIA_TYPE MediaType
Definition: partlist.h:81
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:90
ULONG SectorAlignment
Definition: partlist.h:91
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
ULONG AdapterNumber
Definition: partlist.h:135
BOOLEAN BiosFound
Definition: partlist.h:95
ULONG BytesPerSector
Definition: partlist.h:88
LIST_ENTRY List
Definition: psmgr.c:57
#define EFI_PMBR_OSTYPE_EFI
Definition: partlist.h:168
__wchar_t WCHAR
Definition: xmlstorage.h:180
return Iosb
Definition: create.c:4426
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:398
uint64_t ULONGLONG
Definition: typedefs.h:65
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:377
ULONG SectorsPerTrack
Definition: ntdddisk.h:380
MEDIA_TYPE MediaType
Definition: ntdddisk.h:378
ULONG HwDiskNumber
Definition: partlist.h:98
unsigned char PartitionType
Definition: partlist.h:178
BOOLEAN RewritePartition
Definition: ntdddisk.h:405
static VOID ScanForUnpartitionedDiskSpace(IN PDISKENTRY DiskEntry)
Definition: partlist.c:1119
PDISKENTRY DiskEntry
Definition: partlist.h:140
static const WCHAR L[]
Definition: oid.c:1250
ULONG SectorsPerTrack
Definition: partlist.h:87
Definition: typedefs.h:117
#define InsertAscendingList(ListHead, NewEntry, Type, ListEntryField, SortField)
Definition: partlist.c:17
ULONGLONG Cylinders
Definition: partlist.h:85
HANDLE ProcessHeap
Definition: servman.c:15
Status
Definition: gdiplustypes.h:24
#define IOCTL_DISK_GET_DRIVE_LAYOUT
Definition: ntdddisk.h:76
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
ULONG DiskNumber
Definition: partlist.h:137
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
PARTITION Partition[PARTITION_TBL_SIZE]
Definition: partlist.h:191
ULONG HwFixedDiskNumber
Definition: partlist.h:99
USHORT Port
Definition: partlist.h:106
unsigned int * PULONG
Definition: retypes.h:1
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
ULONG TracksPerCylinder
Definition: partlist.h:86
#define DPRINT1
Definition: precomp.h:8
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:125
unsigned int ULONG
Definition: retypes.h:1
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define PARTITION_MAGIC
Definition: partlist.h:165
static const WCHAR Signature[]
Definition: parser.c:141
PDRIVE_LAYOUT_INFORMATION LayoutBuffer
Definition: partlist.h:118
BOOLEAN NewDisk
Definition: partlist.h:113
#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:112
static VOID AddPartitionToDisk(IN ULONG DiskNumber, IN PDISKENTRY DiskEntry, IN ULONG PartitionIndex, IN BOOLEAN LogicalPartition)
Definition: partlist.c:927

Referenced by CreatePartitionList().

◆ AddLogicalDiskSpace()

static VOID AddLogicalDiskSpace ( IN PDISKENTRY  DiskEntry)
static

Definition at line 2997 of file partlist.c.

2999 {
3000  ULONGLONG StartSector;
3002  PPARTENTRY NewPartEntry;
3003 
3004  DPRINT1("AddLogicalDiskSpace()\n");
3005 
3006  /* Create a partition entry that represents the empty space in the container partition */
3007 
3008  StartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
3009  SectorCount = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
3010 
3011  NewPartEntry = CreateInsertBlankRegion(DiskEntry,
3012  &DiskEntry->LogicalPartListHead,
3013  StartSector,
3014  SectorCount,
3015  TRUE);
3016  if (NewPartEntry == NULL)
3017  {
3018  DPRINT1("Failed to create a new empty region for extended partition space!\n");
3019  return;
3020  }
3021 }
#define TRUE
Definition: types.h:120
smooth NULL
Definition: ftsmooth.c:416
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:65
ULONG SectorCount
Definition: part_xbox.c:31
#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 927 of file partlist.c.

932 {
935  PPARTENTRY PartEntry;
936  HANDLE PartitionHandle;
939  WCHAR PathBuffer[MAX_PATH];
941  UCHAR LabelBuffer[sizeof(FILE_FS_VOLUME_INFORMATION) + 256 * sizeof(WCHAR)];
943 
944  PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
945 
946  if (PartitionInfo->PartitionType == PARTITION_ENTRY_UNUSED ||
947  ((LogicalPartition != FALSE) && IsContainerPartition(PartitionInfo->PartitionType)))
948  {
949  return;
950  }
951 
952  PartEntry = RtlAllocateHeap(ProcessHeap,
954  sizeof(PARTENTRY));
955  if (PartEntry == NULL)
956  return;
957 
958  PartEntry->DiskEntry = DiskEntry;
959 
960  PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
961  PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
962 
963  PartEntry->BootIndicator = PartitionInfo->BootIndicator;
964  PartEntry->PartitionType = PartitionInfo->PartitionType;
965 
966  PartEntry->LogicalPartition = LogicalPartition;
967  PartEntry->IsPartitioned = TRUE;
968  PartEntry->OnDiskPartitionNumber = PartitionInfo->PartitionNumber;
969  PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
970  PartEntry->PartitionIndex = PartitionIndex;
971 
972  /* Specify the partition as initially unformatted */
973  PartEntry->FormatState = Unformatted;
974  PartEntry->FileSystem[0] = L'\0';
975 
976  /* Initialize the partition volume label */
977  RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
978 
979  if (IsContainerPartition(PartEntry->PartitionType))
980  {
981  PartEntry->FormatState = Unformatted;
982 
983  if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
984  DiskEntry->ExtendedPartition = PartEntry;
985  }
986  else if (IsRecognizedPartition(PartEntry->PartitionType))
987  {
988  ASSERT(PartitionInfo->RecognizedPartition);
989  ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
990 
991  /* Try to open the volume so as to mount it */
992  RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
993  L"\\Device\\Harddisk%lu\\Partition%lu",
994  DiskEntry->DiskNumber,
995  PartEntry->PartitionNumber);
996  RtlInitUnicodeString(&Name, PathBuffer);
997 
999  &Name,
1001  NULL,
1002  NULL);
1003 
1004  PartitionHandle = NULL;
1005  Status = NtOpenFile(&PartitionHandle,
1008  &IoStatusBlock,
1011  if (!NT_SUCCESS(Status))
1012  {
1013  DPRINT1("NtOpenFile() failed, Status 0x%08lx\n", Status);
1014  }
1015 
1016  if (PartitionHandle)
1017  {
1019 
1020  /* We don't have a FS, try to guess one */
1021  Status = InferFileSystemByHandle(PartitionHandle,
1022  PartEntry->PartitionType,
1023  PartEntry->FileSystem,
1024  sizeof(PartEntry->FileSystem));
1025  if (!NT_SUCCESS(Status))
1026  DPRINT1("InferFileSystemByHandle() failed, Status 0x%08lx\n", Status);
1027  }
1028  if (*PartEntry->FileSystem)
1029  {
1030  ASSERT(PartitionHandle);
1031 
1032  /*
1033  * Handle partition mounted with RawFS: it is
1034  * either unformatted or has an unknown format.
1035  */
1036  if (wcsicmp(PartEntry->FileSystem, L"RAW") == 0)
1037  {
1038  /*
1039  * True unformatted partitions on NT are created with their
1040  * partition type set to either one of the following values,
1041  * and are mounted with RawFS. This is done this way since we
1042  * are assured to have FAT support, which is the only FS that
1043  * uses these partition types. Therefore, having a partition
1044  * mounted with RawFS and with these partition types means that
1045  * the FAT FS was unable to mount it beforehand and thus the
1046  * partition is unformatted.
1047  * However, any partition mounted by RawFS that does NOT have
1048  * any of these partition types must be considered as having
1049  * an unknown format.
1050  */
1051  if (PartEntry->PartitionType == PARTITION_FAT_12 ||
1052  PartEntry->PartitionType == PARTITION_FAT_16 ||
1053  PartEntry->PartitionType == PARTITION_HUGE ||
1054  PartEntry->PartitionType == PARTITION_XINT13 ||
1055  PartEntry->PartitionType == PARTITION_FAT32 ||
1056  PartEntry->PartitionType == PARTITION_FAT32_XINT13)
1057  {
1058  PartEntry->FormatState = Unformatted;
1059  }
1060  else
1061  {
1062  /* Close the partition before dismounting */
1063  NtClose(PartitionHandle);
1064  PartitionHandle = NULL;
1065  /*
1066  * Dismount the partition since RawFS owns it, and set its
1067  * format to unknown (may or may not be actually formatted).
1068  */
1069  DismountVolume(PartEntry);
1070  PartEntry->FormatState = UnknownFormat;
1071  PartEntry->FileSystem[0] = L'\0';
1072  }
1073  }
1074  else
1075  {
1076  PartEntry->FormatState = Preformatted;
1077  }
1078  }
1079  else
1080  {
1081  PartEntry->FormatState = UnknownFormat;
1082  }
1083 
1084  /* Retrieve the partition volume label */
1085  if (PartitionHandle)
1086  {
1087  Status = NtQueryVolumeInformationFile(PartitionHandle,
1088  &IoStatusBlock,
1089  &LabelBuffer,
1090  sizeof(LabelBuffer),
1092  if (NT_SUCCESS(Status))
1093  {
1094  /* Copy the (possibly truncated) volume label and NULL-terminate it */
1095  RtlStringCbCopyNW(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel),
1096  LabelInfo->VolumeLabel, LabelInfo->VolumeLabelLength);
1097  }
1098  else
1099  {
1100  DPRINT1("NtQueryVolumeInformationFile() failed, Status 0x%08lx\n", Status);
1101  }
1102  }
1103 
1104  /* Close the partition */
1105  if (PartitionHandle)
1106  NtClose(PartitionHandle);
1107  }
1108  else
1109  {
1110  /* Unknown partition, hence unknown format (may or may not be actually formatted) */
1111  PartEntry->FormatState = UnknownFormat;
1112  }
1113 
1114  InsertDiskRegion(DiskEntry, PartEntry, LogicalPartition);
1115 }
#define PARTITION_FAT32
Definition: disk.h:95
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
ULONG PartitionNumber
Definition: partlist.h:48
ULARGE_INTEGER StartSector
Definition: partlist.h:42
#define TRUE
Definition: types.h:120
WCHAR VolumeLabel[20]
Definition: partlist.h:52
ULARGE_INTEGER SectorCount
Definition: partlist.h:43
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:250
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_SHARE_READ
Definition: compat.h:125
#define PARTITION_XINT13
Definition: disk.h:97
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
BOOLEAN LogicalPartition
Definition: partlist.h:56
NTSTATUS DismountVolume(IN PPARTENTRY PartEntry)
Definition: partlist.c:3114
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
NTSTATUS InferFileSystemByHandle(IN HANDLE PartitionHandle, IN UCHAR PartitionType, IN OUT PWSTR FileSystemName, IN SIZE_T FileSystemNameSize)
Definition: fsutil.c:225
FORMATSTATE FormatState
Definition: partlist.h:54
#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:464
smooth NULL
Definition: ftsmooth.c:416
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
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:46
struct _DISKENTRY * DiskEntry
Definition: partlist.h:39
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:65
ULONG OnDiskPartitionNumber
Definition: partlist.h:47
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:276
#define MAX_PATH
Definition: compat.h:26
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2101
WCHAR FileSystem[MAX_PATH+1]
Definition: partlist.h:53
#define PARTITION_FAT_16
Definition: disk.h:90
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
static const WCHAR L[]
Definition: oid.c:1250
#define SYNCHRONIZE
Definition: nt_native.h:61
#define wcsicmp
Definition: string.h:1152
HANDLE ProcessHeap
Definition: servman.c:15
Status
Definition: gdiplustypes.h:24
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 HEAP_ZERO_MEMORY
Definition: compat.h:123
#define DPRINT1
Definition: precomp.h:8
BOOLEAN BootIndicator
Definition: partlist.h:45
#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:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define PARTITION_FAT32_XINT13
Definition: disk.h:96
BOOLEAN IsPartitioned
Definition: partlist.h:59
ULONG PartitionIndex
Definition: partlist.h:49

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 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2374
union Alignment_ Alignment
uint64_t ULONGLONG
Definition: typedefs.h:65

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 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2374
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
uint64_t ULONGLONG
Definition: typedefs.h:65

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:124
WCHAR DriveLetter
Definition: partlist.h:51
#define LL
Definition: tui.h:85
ULARGE_INTEGER SectorCount
Definition: partlist.h:43
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:250
#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:119
UCHAR PartitionType
Definition: partlist.h:46
LIST_ENTRY List
Definition: psmgr.c:57
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:276
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static const WCHAR L[]
Definition: oid.c:1250
WCHAR Letter
Definition: typedefs.h:117
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:125
BOOLEAN IsPartitioned
Definition: partlist.h:59

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

◆ CreateExtendedPartition()

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

Definition at line 3024 of file partlist.c.

3028 {
3030 
3031  DPRINT1("CreateExtendedPartition(%I64u)\n", SectorCount);
3032 
3033  if (List == NULL || PartEntry == NULL ||
3034  PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
3035  {
3036  return FALSE;
3037  }
3038 
3040  if (Error != NOT_AN_ERROR)
3041  {
3042  DPRINT1("ExtendedPartitionCreationChecks() failed with error %lu\n", Error);
3043  return FALSE;
3044  }
3045 
3046  /* Initialize the partition entry, inserting a new blank region if needed */
3047  if (!InitializePartitionEntry(PartEntry, SectorCount, FALSE))
3048  return FALSE;
3049 
3050  ASSERT(PartEntry->LogicalPartition == FALSE);
3051 
3052  if (PartEntry->StartSector.QuadPart < 1450560)
3053  {
3054  /* Partition starts below the 8.4GB boundary ==> CHS partition */
3055  PartEntry->PartitionType = PARTITION_EXTENDED;
3056  }
3057  else
3058  {
3059  /* Partition starts above the 8.4GB boundary ==> LBA partition */
3060  PartEntry->PartitionType = PARTITION_XINT13_EXTENDED;
3061  }
3062 
3063  // FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container)
3064  PartEntry->New = FALSE;
3065  PartEntry->FormatState = Formatted;
3066 
3067  PartEntry->DiskEntry->ExtendedPartition = PartEntry;
3068 
3069  AddLogicalDiskSpace(PartEntry->DiskEntry);
3070 
3071  UpdateDiskLayout(PartEntry->DiskEntry);
3073 
3074  return TRUE;
3075 }
ERROR_NUMBER ExtendedPartitionCreationChecks(IN PPARTENTRY PartEntry)
Definition: partlist.c:4150
#define TRUE
Definition: types.h:120
static BOOLEAN InitializePartitionEntry(IN OUT PPARTENTRY PartEntry, IN ULONGLONG SectorCount, IN BOOLEAN AutoCreate)
Definition: partlist.c:857
smooth NULL
Definition: ftsmooth.c:416
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2711
#define PARTITION_EXTENDED
Definition: disk.h:91
LIST_ENTRY List
Definition: psmgr.c:57
BOOL Error
Definition: chkdsk.c:66
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
enum _ERROR_NUMBER ERROR_NUMBER
ULONG SectorCount
Definition: part_xbox.c:31
#define PARTITION_XINT13_EXTENDED
Definition: disk.h:98
#define DPRINT1
Definition: precomp.h:8
static VOID AddLogicalDiskSpace(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2997
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:42
ULARGE_INTEGER SectorCount
Definition: partlist.h:43
#define InsertTailList(ListHead, Entry)
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
LIST_ENTRY ListEntry
Definition: partlist.h:36
BOOLEAN LogicalPartition
Definition: partlist.h:56
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
FORMATSTATE FormatState
Definition: partlist.h:54
smooth NULL
Definition: ftsmooth.c:416
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
UCHAR PartitionType
Definition: partlist.h:46
struct _DISKENTRY * DiskEntry
Definition: partlist.h:39
WCHAR FileSystem[MAX_PATH+1]
Definition: partlist.h:53
static const WCHAR L[]
Definition: oid.c:1250
ULONG SectorCount
Definition: part_xbox.c:31
HANDLE ProcessHeap
Definition: servman.c:15
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define DPRINT1
Definition: precomp.h:8
BOOLEAN IsPartitioned
Definition: partlist.h:59

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 3078 of file partlist.c.

3083 {
3085 
3086  DPRINT1("CreateLogicalPartition(%I64u)\n", SectorCount);
3087 
3088  if (List == NULL || PartEntry == NULL ||
3089  PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
3090  {
3091  return FALSE;
3092  }
3093 
3095  if (Error != NOT_AN_ERROR)
3096  {
3097  DPRINT1("LogicalPartitionCreationChecks() failed with error %lu\n", Error);
3098  return FALSE;
3099  }
3100 
3101  /* Initialize the partition entry, inserting a new blank region if needed */
3102  if (!InitializePartitionEntry(PartEntry, SectorCount, AutoCreate))
3103  return FALSE;
3104 
3105  ASSERT(PartEntry->LogicalPartition == TRUE);
3106 
3107  UpdateDiskLayout(PartEntry->DiskEntry);
3109 
3110  return TRUE;
3111 }
#define TRUE
Definition: types.h:120
ERROR_NUMBER LogicalPartitionCreationChecks(IN PPARTENTRY PartEntry)
Definition: partlist.c:4181
static BOOLEAN InitializePartitionEntry(IN OUT PPARTENTRY PartEntry, IN ULONGLONG SectorCount, IN BOOLEAN AutoCreate)
Definition: partlist.c:857
smooth NULL
Definition: ftsmooth.c:416
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2711
LIST_ENTRY List
Definition: psmgr.c:57
BOOL Error
Definition: chkdsk.c:66
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
enum _ERROR_NUMBER ERROR_NUMBER
ULONG SectorCount
Definition: part_xbox.c:31
#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 2024 of file partlist.c.

2025 {
2026  PPARTLIST List;
2027  PDISKENTRY SystemDisk;
2031  ULONG ReturnSize;
2032  NTSTATUS Status;
2033  ULONG DiskNumber;
2037 
2039  0,
2040  sizeof(PARTLIST));
2041  if (List == NULL)
2042  return NULL;
2043 
2044  List->SystemPartition = NULL;
2045 
2046  InitializeListHead(&List->DiskListHead);
2047  InitializeListHead(&List->BiosDiskListHead);
2048 
2049  /*
2050  * Enumerate the disks seen by the BIOS; this will be used later
2051  * to map drives seen by NTOS with their corresponding BIOS names.
2052  */
2054 
2055  /* Enumerate disks seen by NTOS */
2057  &Sdi,
2058  sizeof(Sdi),
2059  &ReturnSize);
2060  if (!NT_SUCCESS(Status))
2061  {
2062  DPRINT1("NtQuerySystemInformation() failed, Status 0x%08lx", Status);
2064  return NULL;
2065  }
2066 
2067  for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
2068  {
2070  L"\\Device\\Harddisk%lu\\Partition0",
2071  DiskNumber);
2073 
2075  &Name,
2077  NULL,
2078  NULL);
2079 
2083  &Iosb,
2086  if (NT_SUCCESS(Status))
2087  {
2088  AddDiskToList(FileHandle, DiskNumber, List);
2090  }
2091  }
2092 
2096 
2097  /*
2098  * Retrieve the system partition: the active partition on the system
2099  * disk (the one that will be booted by default by the hardware).
2100  */
2101  SystemDisk = GetSystemDisk(List);
2102  List->SystemPartition = (SystemDisk ? GetActiveDiskPartition(SystemDisk) : NULL);
2103 
2104  return List;
2105 }
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
static PPARTENTRY GetActiveDiskPartition(IN PDISKENTRY DiskEntry)
Definition: partlist.c:1968
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:1392
#define FILE_SHARE_READ
Definition: compat.h:125
HANDLE FileHandle
Definition: stats.c:38
#define FILE_READ_DATA
Definition: nt_native.h:628
struct NameRec_ * Name
Definition: cdprocs.h:464
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
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
LIST_ENTRY List
Definition: psmgr.c:57
__wchar_t WCHAR
Definition: xmlstorage.h:180
return Iosb
Definition: create.c:4426
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static VOID UpdateHwDiskNumbers(IN PPARTLIST List)
Definition: partlist.c:1422
#define MAX_PATH
Definition: compat.h:26
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
static PDISKENTRY GetSystemDisk(IN PPARTLIST List)
Definition: partlist.c:1895
static const WCHAR L[]
Definition: oid.c:1250
#define SYNCHRONIZE
Definition: nt_native.h:61
HANDLE ProcessHeap
Definition: servman.c:15
Status
Definition: gdiplustypes.h:24
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:1483
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#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 2960 of file partlist.c.

2965 {
2967 
2968  DPRINT1("CreatePrimaryPartition(%I64u)\n", SectorCount);
2969 
2970  if (List == NULL || PartEntry == NULL ||
2971  PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
2972  {
2973  return FALSE;
2974  }
2975 
2977  if (Error != NOT_AN_ERROR)
2978  {
2979  DPRINT1("PrimaryPartitionCreationChecks() failed with error %lu\n", Error);
2980  return FALSE;
2981  }
2982 
2983  /* Initialize the partition entry, inserting a new blank region if needed */
2984  if (!InitializePartitionEntry(PartEntry, SectorCount, AutoCreate))
2985  return FALSE;
2986 
2987  ASSERT(PartEntry->LogicalPartition == FALSE);
2988 
2989  UpdateDiskLayout(PartEntry->DiskEntry);
2991 
2992  return TRUE;
2993 }
#define TRUE
Definition: types.h:120
static BOOLEAN InitializePartitionEntry(IN OUT PPARTENTRY PartEntry, IN ULONGLONG SectorCount, IN BOOLEAN AutoCreate)
Definition: partlist.c:857
smooth NULL
Definition: ftsmooth.c:416
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2711
ERROR_NUMBER PrimaryPartitionCreationChecks(IN PPARTENTRY PartEntry)
Definition: partlist.c:4123
LIST_ENTRY List
Definition: psmgr.c:57
BOOL Error
Definition: chkdsk.c:66
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
enum _ERROR_NUMBER ERROR_NUMBER
ULONG SectorCount
Definition: part_xbox.c:31
#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 3221 of file partlist.c.

3225 {
3226  PDISKENTRY DiskEntry;
3227  PPARTENTRY PrevPartEntry;
3228  PPARTENTRY NextPartEntry;
3229  PPARTENTRY LogicalPartEntry;
3231 
3232  if (List == NULL || PartEntry == NULL ||
3233  PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned == FALSE)
3234  {
3235  return FALSE;
3236  }
3237 
3238  ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
3239 
3240  /* Clear the system partition if it is being deleted */
3241  if (List->SystemPartition == PartEntry)
3242  {
3243  ASSERT(List->SystemPartition);
3244  List->SystemPartition = NULL;
3245  }
3246 
3247  DiskEntry = PartEntry->DiskEntry;
3248 
3249  /* Check which type of partition (primary/logical or extended) is being deleted */
3250  if (DiskEntry->ExtendedPartition == PartEntry)
3251  {
3252  /* An extended partition is being deleted: delete all logical partition entries */
3253  while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
3254  {
3255  Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
3256  LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
3257 
3258  /* Dismount the logical partition */
3259  DismountVolume(LogicalPartEntry);
3260 
3261  /* Delete it */
3262  RtlFreeHeap(ProcessHeap, 0, LogicalPartEntry);
3263  }
3264 
3265  DiskEntry->ExtendedPartition = NULL;
3266  }
3267  else
3268  {
3269  /* A primary partition is being deleted: dismount it */
3270  DismountVolume(PartEntry);
3271  }
3272 
3273  /* Adjust the unpartitioned disk space entries */
3274 
3275  /* Get pointer to previous and next unpartitioned entries */
3276  PrevPartEntry = GetPrevUnpartitionedEntry(PartEntry);
3277  NextPartEntry = GetNextUnpartitionedEntry(PartEntry);
3278 
3279  if (PrevPartEntry != NULL && NextPartEntry != NULL)
3280  {
3281  /* Merge the previous, current and next unpartitioned entries */
3282 
3283  /* Adjust the previous entry length */
3284  PrevPartEntry->SectorCount.QuadPart += (PartEntry->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart);
3285 
3286  /* Remove the current and next entries */
3287  RemoveEntryList(&PartEntry->ListEntry);
3288  RtlFreeHeap(ProcessHeap, 0, PartEntry);
3289  RemoveEntryList(&NextPartEntry->ListEntry);
3290  RtlFreeHeap(ProcessHeap, 0, NextPartEntry);
3291 
3292  /* Optionally return the freed region */
3293  if (FreeRegion)
3294  *FreeRegion = PrevPartEntry;
3295  }
3296  else if (PrevPartEntry != NULL && NextPartEntry == NULL)
3297  {
3298  /* Merge the current and the previous unpartitioned entries */
3299 
3300  /* Adjust the previous entry length */
3301  PrevPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
3302 
3303  /* Remove the current entry */
3304  RemoveEntryList(&PartEntry->ListEntry);
3305  RtlFreeHeap(ProcessHeap, 0, PartEntry);
3306 
3307  /* Optionally return the freed region */
3308  if (FreeRegion)
3309  *FreeRegion = PrevPartEntry;
3310  }
3311  else if (PrevPartEntry == NULL && NextPartEntry != NULL)
3312  {
3313  /* Merge the current and the next unpartitioned entries */
3314 
3315  /* Adjust the next entry offset and length */
3316  NextPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
3317  NextPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
3318 
3319  /* Remove the current entry */
3320  RemoveEntryList(&PartEntry->ListEntry);
3321  RtlFreeHeap(ProcessHeap, 0, PartEntry);
3322 
3323  /* Optionally return the freed region */
3324  if (FreeRegion)
3325  *FreeRegion = NextPartEntry;
3326  }
3327  else
3328  {
3329  /* Nothing to merge but change the current entry */
3330  PartEntry->IsPartitioned = FALSE;
3331  PartEntry->OnDiskPartitionNumber = 0;
3332  PartEntry->PartitionNumber = 0;
3333  // PartEntry->PartitionIndex = 0;
3334  PartEntry->BootIndicator = FALSE;
3335  PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
3336  PartEntry->FormatState = Unformatted;
3337  PartEntry->FileSystem[0] = L'\0';
3338  PartEntry->DriveLetter = 0;
3339  RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
3340 
3341  /* Optionally return the freed region */
3342  if (FreeRegion)
3343  *FreeRegion = PartEntry;
3344  }
3345 
3346  UpdateDiskLayout(DiskEntry);
3348 
3349  return TRUE;
3350 }
ULARGE_INTEGER StartSector
Definition: partlist.h:42
#define TRUE
Definition: types.h:120
struct _Entry Entry
Definition: kefuncs.h:627
ULARGE_INTEGER SectorCount
Definition: partlist.h:43
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:128
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:36
NTSTATUS DismountVolume(IN PPARTENTRY PartEntry)
Definition: partlist.c:3114
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
smooth NULL
Definition: ftsmooth.c:416
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:2711
LIST_ENTRY List
Definition: psmgr.c:57
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static const WCHAR L[]
Definition: oid.c:1250
Definition: typedefs.h:117
HANDLE ProcessHeap
Definition: servman.c:15
static PPARTENTRY GetPrevUnpartitionedEntry(IN PPARTENTRY PartEntry)
Definition: partlist.c:2891
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:125
static PPARTENTRY GetNextUnpartitionedEntry(IN PPARTENTRY PartEntry)
Definition: partlist.c:2926
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
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:59

Referenced by DeletePartitionPage().

◆ DestroyPartitionList()

VOID DestroyPartitionList ( IN PPARTLIST  List)

Definition at line 2108 of file partlist.c.

2110 {
2111  PDISKENTRY DiskEntry;
2112  PBIOSDISKENTRY BiosDiskEntry;
2113  PPARTENTRY PartEntry;
2115 
2116  /* Release disk and partition info */
2117  while (!IsListEmpty(&List->DiskListHead))
2118  {
2119  Entry = RemoveHeadList(&List->DiskListHead);
2120  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2121 
2122  /* Release driver name */
2123  RtlFreeUnicodeString(&DiskEntry->DriverName);
2124 
2125  /* Release primary partition list */
2126  while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
2127  {
2128  Entry = RemoveHeadList(&DiskEntry->PrimaryPartListHead);
2129  PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2130 
2131  RtlFreeHeap(ProcessHeap, 0, PartEntry);
2132  }
2133 
2134  /* Release logical partition list */
2135  while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
2136  {
2137  Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
2138  PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2139 
2140  RtlFreeHeap(ProcessHeap, 0, PartEntry);
2141  }
2142 
2143  /* Release layout buffer */
2144  if (DiskEntry->LayoutBuffer != NULL)
2145  RtlFreeHeap(ProcessHeap, 0, DiskEntry->LayoutBuffer);
2146 
2147  /* Release disk entry */
2148  RtlFreeHeap(ProcessHeap, 0, DiskEntry);
2149  }
2150 
2151  /* Release the bios disk info */
2152  while (!IsListEmpty(&List->BiosDiskListHead))
2153  {
2154  Entry = RemoveHeadList(&List->BiosDiskListHead);
2155  BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
2156 
2157  RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
2158  }
2159 
2160  /* Release list head */
2162 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:124
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
smooth NULL
Definition: ftsmooth.c:416
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
LIST_ENTRY List
Definition: psmgr.c:57
UNICODE_STRING DriverName
Definition: partlist.h:116
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
Definition: typedefs.h:117
HANDLE ProcessHeap
Definition: servman.c:15
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:125
PDRIVE_LAYOUT_INFORMATION LayoutBuffer
Definition: partlist.h:118
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
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4047
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@378::@387 DeviceSpecificData
struct _CM_DISK_GEOMETRY_DEVICE_DATA * PCM_DISK_GEOMETRY_DEVICE_DATA
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@378 u
struct _BIOSDISKENTRY * PBIOSDISKENTRY
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
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
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:141
_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
_In_ GUID _In_ PVOID _In_ ULONG ValueLength
Definition: hubbusif.h:311
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:2938

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:139
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4047
ULONG Signature
Definition: partlist.h:138
uint16_t * PWCHAR
Definition: typedefs.h:54
struct _BIOSDISKENTRY * PBIOSDISKENTRY
__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
_In_ GUID _In_ PVOID _In_ ULONG ValueLength
Definition: hubbusif.h:311
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define REG_SZ
Definition: layer.c:22

Referenced by EnumerateBiosDiskEntries().

◆ DismountVolume()

NTSTATUS DismountVolume ( IN PPARTENTRY  PartEntry)

Definition at line 3114 of file partlist.c.

3116 {
3117  NTSTATUS Status;
3118  NTSTATUS LockStatus;
3122  HANDLE PartitionHandle;
3124 
3125  /* Check whether the partition is valid and was mounted by the system */
3126  if (!PartEntry->IsPartitioned ||
3127  IsContainerPartition(PartEntry->PartitionType) ||
3128  !IsRecognizedPartition(PartEntry->PartitionType) ||
3129  PartEntry->FormatState == UnknownFormat ||
3130  // NOTE: If FormatState == Unformatted but *FileSystem != 0 this means
3131  // it has been usually mounted with RawFS and thus needs to be dismounted.
3132  !*PartEntry->FileSystem ||
3133  PartEntry->PartitionNumber == 0)
3134  {
3135  /* The partition is not mounted, so just return success */
3136  return STATUS_SUCCESS;
3137  }
3138 
3139  ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
3140 
3141  /* Open the volume */
3143  L"\\Device\\Harddisk%lu\\Partition%lu",
3144  PartEntry->DiskEntry->DiskNumber,
3145  PartEntry->PartitionNumber);
3147 
3149  &Name,
3151  NULL,
3152  NULL);
3153 
3154  Status = NtOpenFile(&PartitionHandle,
3157  &IoStatusBlock,
3160  if (!NT_SUCCESS(Status))
3161  {
3162  DPRINT1("ERROR: Cannot open volume %wZ for dismounting! (Status 0x%lx)\n", &Name, Status);
3163  return Status;
3164  }
3165 
3166  /* Lock the volume */
3167  LockStatus = NtFsControlFile(PartitionHandle,
3168  NULL,
3169  NULL,
3170  NULL,
3171  &IoStatusBlock,
3173  NULL,
3174  0,
3175  NULL,
3176  0);
3177  if (!NT_SUCCESS(LockStatus))
3178  {
3179  DPRINT1("WARNING: Failed to lock volume! Operations may fail! (Status 0x%lx)\n", LockStatus);
3180  }
3181 
3182  /* Dismount the volume */
3183  Status = NtFsControlFile(PartitionHandle,
3184  NULL,
3185  NULL,
3186  NULL,
3187  &IoStatusBlock,
3189  NULL,
3190  0,
3191  NULL,
3192  0);
3193  if (!NT_SUCCESS(Status))
3194  {
3195  DPRINT1("Failed to unmount volume (Status 0x%lx)\n", Status);
3196  }
3197 
3198  /* Unlock the volume */
3199  LockStatus = NtFsControlFile(PartitionHandle,
3200  NULL,
3201  NULL,
3202  NULL,
3203  &IoStatusBlock,
3205  NULL,
3206  0,
3207  NULL,
3208  0);
3209  if (!NT_SUCCESS(LockStatus))
3210  {
3211  DPRINT1("Failed to unlock volume (Status 0x%lx)\n", LockStatus);
3212  }
3213 
3214  /* Close the volume */
3215  NtClose(PartitionHandle);
3216 
3217  return Status;
3218 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
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:250
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:125
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
#define GENERIC_WRITE
Definition: nt_native.h:90
struct NameRec_ * Name
Definition: cdprocs.h:464
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
#define FSCTL_DISMOUNT_VOLUME
Definition: nt_native.h:834
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
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:276
#define MAX_PATH
Definition: compat.h:26
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static const WCHAR L[]
Definition: oid.c:1250
#define GENERIC_READ
Definition: compat.h:124
#define SYNCHRONIZE
Definition: nt_native.h:61
Status
Definition: gdiplustypes.h:24
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#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
return STATUS_SUCCESS
Definition: btrfs.c:2938

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:4035
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:139
ULONG Signature
Definition: partlist.h:138
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:136
#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
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
ULONG AdapterNumber
Definition: partlist.h:135
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry
Definition: partlist.h:141
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
PDISKENTRY DiskEntry
Definition: partlist.h:140
static const WCHAR L[]
Definition: oid.c:1250
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
HANDLE ProcessHeap
Definition: servman.c:15
Status
Definition: gdiplustypes.h:24
LIST_ENTRY ListEntry
Definition: partlist.h:134
ULONG DiskNumber
Definition: partlist.h:137
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#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:142
#define memset(x, y, z)
Definition: compat.h:39

Referenced by CreatePartitionList().

◆ ExtendedPartitionCreationChecks()

ERROR_NUMBER ExtendedPartitionCreationChecks ( IN PPARTENTRY  PartEntry)

Definition at line 4150 of file partlist.c.

4152 {
4153  PDISKENTRY DiskEntry = PartEntry->DiskEntry;
4154 
4155  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
4156  {
4157  DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
4158  return ERROR_WARN_PARTITION;
4159  }
4160 
4161  /* Fail if the partition is already in use */
4162  if (PartEntry->IsPartitioned)
4163  return ERROR_NEW_PARTITION;
4164 
4165  /* Only one primary partition is allowed on super-floppy */
4166  if (IsSuperFloppy(DiskEntry))
4168 
4169  /* Fail if there are already 4 primary partitions in the list */
4170  if (GetPrimaryPartitionCount(DiskEntry) >= 4)
4172 
4173  /* Fail if there is another extended partition in the list */
4174  if (DiskEntry->ExtendedPartition != NULL)
4175  return ERROR_ONLY_ONE_EXTENDED;
4176 
4177  return ERROR_SUCCESS;
4178 }
#define ERROR_SUCCESS
Definition: deptool.c:10
PPARTENTRY ExtendedPartition
Definition: partlist.h:128
PARTITION_STYLE DiskStyle
Definition: partlist.h:114
smooth NULL
Definition: ftsmooth.c:416
static ULONG GetPrimaryPartitionCount(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2605
BOOLEAN IsSuperFloppy(IN PDISKENTRY DiskEntry)
Definition: partlist.c:680
#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 3434 of file partlist.c.

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

Referenced by SelectFileSystemPage().

◆ GetActiveDiskPartition()

static PPARTENTRY GetActiveDiskPartition ( IN PDISKENTRY  DiskEntry)
static

Definition at line 1968 of file partlist.c.

1970 {
1971  PLIST_ENTRY ListEntry;
1972  PPARTENTRY PartEntry;
1973  PPARTENTRY ActivePartition = NULL;
1974 
1975  /* Check for empty disk list */
1976  // ASSERT(DiskEntry);
1977  if (!DiskEntry)
1978  return NULL;
1979 
1980  /* Check for empty partition list */
1981  if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
1982  return NULL;
1983 
1984  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1985  {
1986  DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1987  return NULL;
1988  }
1989 
1990  /* Scan all (primary) partitions to find the active disk partition */
1991  for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
1992  ListEntry != &DiskEntry->PrimaryPartListHead;
1993  ListEntry = ListEntry->Flink)
1994  {
1995  /* Retrieve the partition */
1996  PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1997  if (IsPartitionActive(PartEntry))
1998  {
1999  /* Yes, we've found it */
2000  ASSERT(DiskEntry == PartEntry->DiskEntry);
2001  ASSERT(PartEntry->IsPartitioned);
2002 
2003  ActivePartition = PartEntry;
2004 
2005  DPRINT1("Found active system partition %lu in disk %lu, drive letter %C\n",
2006  PartEntry->PartitionNumber, DiskEntry->DiskNumber,
2007  (PartEntry->DriveLetter == 0) ? L'-' : PartEntry->DriveLetter);
2008  break;
2009  }
2010  }
2011 
2012  /* Check if the disk is new and if so, use its first partition as the active system partition */
2013  if (DiskEntry->NewDisk && ActivePartition != NULL)
2014  {
2015  // FIXME: What to do??
2016  DPRINT1("NewDisk TRUE but already existing active partition?\n");
2017  }
2018 
2019  /* Return the active partition found (or none) */
2020  return ActivePartition;
2021 }
WCHAR DriveLetter
Definition: partlist.h:51
ULONG PartitionNumber
Definition: partlist.h:48
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
smooth NULL
Definition: ftsmooth.c:416
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:119
struct _DISKENTRY * DiskEntry
Definition: partlist.h:39
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static const WCHAR L[]
Definition: oid.c:1250
Definition: typedefs.h:117
#define DPRINT1
Definition: precomp.h:8
BOOLEAN IsPartitionActive(IN PPARTENTRY PartEntry)
Definition: partlist.c:1945
BOOLEAN IsPartitioned
Definition: partlist.h:59

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

◆ GetDiskByBiosNumber()

PDISKENTRY GetDiskByBiosNumber ( IN PPARTLIST  List,
IN ULONG  HwDiskNumber 
)

Definition at line 2165 of file partlist.c.

2168 {
2169  PDISKENTRY DiskEntry;
2171 
2172  /* Loop over the disks and find the correct one */
2173  for (Entry = List->DiskListHead.Flink;
2174  Entry != &List->DiskListHead;
2175  Entry = Entry->Flink)
2176  {
2177  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2178 
2179  if (DiskEntry->HwDiskNumber == HwDiskNumber)
2180  {
2181  /* Disk found */
2182  return DiskEntry;
2183  }
2184  }
2185 
2186  /* Disk not found, stop there */
2187  return NULL;
2188 }
struct _Entry Entry
Definition: kefuncs.h:627
smooth NULL
Definition: ftsmooth.c:416
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:119
LIST_ENTRY List
Definition: psmgr.c:57
ULONG HwDiskNumber
Definition: partlist.h:98
Definition: typedefs.h:117
base of all file and directory entries
Definition: entries.h:82

◆ GetDiskByNumber()

PDISKENTRY GetDiskByNumber ( IN PPARTLIST  List,
IN ULONG  DiskNumber 
)

Definition at line 2191 of file partlist.c.

2194 {
2195  PDISKENTRY DiskEntry;
2197 
2198  /* Loop over the disks and find the correct one */
2199  for (Entry = List->DiskListHead.Flink;
2200  Entry != &List->DiskListHead;
2201  Entry = Entry->Flink)
2202  {
2203  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2204 
2205  if (DiskEntry->DiskNumber == DiskNumber)
2206  {
2207  /* Disk found */
2208  return DiskEntry;
2209  }
2210  }
2211 
2212  /* Disk not found, stop there */
2213  return NULL;
2214 }
struct _Entry Entry
Definition: kefuncs.h:627
ULONG DiskNumber
Definition: partlist.h:104
smooth NULL
Definition: ftsmooth.c:416
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:119
LIST_ENTRY List
Definition: psmgr.c:57
Definition: typedefs.h:117
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 2217 of file partlist.c.

2222 {
2223  PDISKENTRY DiskEntry;
2225 
2226  /* Loop over the disks and find the correct one */
2227  for (Entry = List->DiskListHead.Flink;
2228  Entry != &List->DiskListHead;
2229  Entry = Entry->Flink)
2230  {
2231  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2232 
2233  if (DiskEntry->Port == Port &&
2234  DiskEntry->Bus == Bus &&
2235  DiskEntry->Id == Id)
2236  {
2237  /* Disk found */
2238  return DiskEntry;
2239  }
2240  }
2241 
2242  /* Disk not found, stop there */
2243  return NULL;
2244 }
CPPORT Port[4]
Definition: headless.c:34
USHORT Id
Definition: partlist.h:108
struct _Entry Entry
Definition: kefuncs.h:627
USHORT Bus
Definition: partlist.h:107
DWORD Id
smooth NULL
Definition: ftsmooth.c:416
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:119
LIST_ENTRY List
Definition: psmgr.c:57
Definition: typedefs.h:117
USHORT Port
Definition: partlist.h:106
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 2247 of file partlist.c.

2250 {
2251  PDISKENTRY DiskEntry;
2253 
2254  /* Loop over the disks and find the correct one */
2255  for (Entry = List->DiskListHead.Flink;
2256  Entry != &List->DiskListHead;
2257  Entry = Entry->Flink)
2258  {
2259  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2260 
2261  if (DiskEntry->LayoutBuffer->Signature == Signature)
2262  {
2263  /* Disk found */
2264  return DiskEntry;
2265  }
2266  }
2267 
2268  /* Disk not found, stop there */
2269  return NULL;
2270 }
struct _Entry Entry
Definition: kefuncs.h:627
smooth NULL
Definition: ftsmooth.c:416
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:119
LIST_ENTRY List
Definition: psmgr.c:57
Definition: typedefs.h:117
static const WCHAR Signature[]
Definition: parser.c:141
PDRIVE_LAYOUT_INFORMATION LayoutBuffer
Definition: partlist.h:118
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 2320 of file partlist.c.

2326 {
2327  PDISKENTRY DiskEntry;
2328  PPARTENTRY PartEntry = NULL;
2329 
2330  /* Find the disk */
2331  DiskEntry = GetDiskByNumber(List, DiskNumber);
2332  if (!DiskEntry)
2333  return FALSE;
2334 
2335  /* If we have a partition (PartitionNumber != 0), find it */
2336  if (PartitionNumber != 0)
2337  {
2338  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2339  {
2340  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2341  return FALSE;
2342  }
2343 
2344  PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
2345  if (!PartEntry)
2346  return FALSE;
2347  ASSERT(PartEntry->DiskEntry == DiskEntry);
2348  }
2349 
2350  /* Return the disk (and optionally the partition) */
2351  *pDiskEntry = DiskEntry;
2352  if (pPartEntry) *pPartEntry = PartEntry;
2353  return TRUE;
2354 }
#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:2273
PARTITION_STYLE DiskStyle
Definition: partlist.h:114
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
PDISKENTRY GetDiskByNumber(IN PPARTLIST List, IN ULONG DiskNumber)
Definition: partlist.c:2191
struct _DISKENTRY * DiskEntry
Definition: partlist.h:39
LIST_ENTRY List
Definition: psmgr.c:57
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)

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 }
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4035
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
smooth NULL
Definition: ftsmooth.c:416
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#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 2632 of file partlist.c.

2634 {
2635  PLIST_ENTRY ListEntry;
2636  PPARTENTRY PartEntry;
2637  ULONG Count = 0;
2638 
2639  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2640  {
2641  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2642  return 0;
2643  }
2644 
2645  for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
2646  ListEntry != &DiskEntry->LogicalPartListHead;
2647  ListEntry = ListEntry->Flink)
2648  {
2649  PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
2650  if (PartEntry->IsPartitioned)
2651  Count++;
2652  }
2653 
2654  return Count;
2655 }
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
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:119
Definition: typedefs.h:117
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN IsPartitioned
Definition: partlist.h:59

Referenced by ReAllocateLayoutBuffer().

◆ GetNextPartition()

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

Definition at line 2384 of file partlist.c.

2387 {
2388  PLIST_ENTRY DiskListEntry;
2389  PLIST_ENTRY PartListEntry;
2391 
2392  /* Fail if no disks are available */
2393  if (IsListEmpty(&List->DiskListHead))
2394  return NULL;
2395 
2396  /* Check for the next usable entry on the current partition's disk */
2397  if (CurrentPart != NULL)
2398  {
2399  CurrentDisk = CurrentPart->DiskEntry;
2400 
2401  if (CurrentPart->LogicalPartition)
2402  {
2403  /* Logical partition */
2404 
2405  PartListEntry = CurrentPart->ListEntry.Flink;
2406  if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2407  {
2408  /* Next logical partition */
2409  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2410  return CurrentPart;
2411  }
2412  else
2413  {
2414  PartListEntry = CurrentDisk->ExtendedPartition->ListEntry.Flink;
2415  if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2416  {
2417  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2418  return CurrentPart;
2419  }
2420  }
2421  }
2422  else
2423  {
2424  /* Primary or extended partition */
2425 
2426  if (CurrentPart->IsPartitioned &&
2427  IsContainerPartition(CurrentPart->PartitionType))
2428  {
2429  /* First logical partition */
2430  PartListEntry = CurrentDisk->LogicalPartListHead.Flink;
2431  if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2432  {
2433  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2434  return CurrentPart;
2435  }
2436  }
2437  else
2438  {
2439  /* Next primary partition */
2440  PartListEntry = CurrentPart->ListEntry.Flink;
2441  if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2442  {
2443  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2444  return CurrentPart;
2445  }
2446  }
2447  }
2448  }
2449 
2450  /* Search for the first partition entry on the next disk */
2451  for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Flink
2452  : List->DiskListHead.Flink);
2453  DiskListEntry != &List->DiskListHead;
2454  DiskListEntry = DiskListEntry->Flink)
2455  {
2456  CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
2457 
2459  {
2460  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2461  continue;
2462  }
2463 
2464  PartListEntry = CurrentDisk->PrimaryPartListHead.Flink;
2465  if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2466  {
2467  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2468  return CurrentPart;
2469  }
2470  }
2471 
2472  return NULL;
2473 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:124
PDISKENTRY CurrentDisk
Definition: partlist.c:73
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:250
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
PPARTENTRY ExtendedPartition
Definition: partlist.h:128
LIST_ENTRY ListEntry
Definition: partlist.h:36
PARTITION_STYLE DiskStyle
Definition: partlist.h:114
smooth NULL
Definition: ftsmooth.c:416
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:119
LIST_ENTRY List
Definition: psmgr.c:57
LIST_ENTRY ListEntry
Definition: partlist.h:76
Definition: typedefs.h:117
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:125

Referenced by ScrollDownPartitionList().

◆ GetNextUncheckedPartition()

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

Definition at line 4263 of file partlist.c.

4267 {
4268  PLIST_ENTRY Entry1, Entry2;
4269  PDISKENTRY DiskEntry;
4270  PPARTENTRY PartEntry;
4271 
4272  for (Entry1 = List->DiskListHead.Flink;
4273  Entry1 != &List->DiskListHead;
4274  Entry1 = Entry1->Flink)
4275  {
4276  DiskEntry = CONTAINING_RECORD(Entry1,
4277  DISKENTRY,
4278  ListEntry);
4279 
4280  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
4281  {
4282  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
4283  continue;
4284  }
4285 
4286  for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
4287  Entry2 != &DiskEntry->PrimaryPartListHead;
4288  Entry2 = Entry2->Flink)
4289  {
4290  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4291  if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
4292  {
4293  ASSERT(DiskEntry == PartEntry->DiskEntry);
4294  if (pDiskEntry) *pDiskEntry = DiskEntry;
4295  *pPartEntry = PartEntry;
4296  return TRUE;
4297  }
4298  }
4299 
4300  for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
4301  Entry2 != &DiskEntry->LogicalPartListHead;
4302  Entry2 = Entry2->Flink)
4303  {
4304  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4305  if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
4306  {
4307  ASSERT(DiskEntry == PartEntry->DiskEntry);
4308  if (pDiskEntry) *pDiskEntry = DiskEntry;
4309  *pPartEntry = PartEntry;
4310  return TRUE;
4311  }
4312  }
4313  }
4314 
4315  if (pDiskEntry) *pDiskEntry = NULL;
4316  *pPartEntry = NULL;
4317 
4318  return FALSE;
4319 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:124
#define TRUE
Definition: types.h:120
PARTITION_STYLE DiskStyle
Definition: partlist.h:114
smooth NULL
Definition: ftsmooth.c:416
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:119
struct _DISKENTRY * DiskEntry
Definition: partlist.h:39
LIST_ENTRY List
Definition: psmgr.c:57
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: typedefs.h:117
BOOLEAN NeedsCheck
Definition: partlist.h:70
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:125
BOOLEAN IsPartitioned
Definition: partlist.h:59

Referenced by CheckFileSystemPage().

◆ GetNextUnformattedPartition()

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

Definition at line 4204 of file partlist.c.

4208 {
4209  PLIST_ENTRY Entry1, Entry2;
4210  PDISKENTRY DiskEntry;
4211  PPARTENTRY PartEntry;
4212 
4213  for (Entry1 = List->DiskListHead.Flink;
4214  Entry1 != &List->DiskListHead;
4215  Entry1 = Entry1->Flink)
4216  {
4217  DiskEntry = CONTAINING_RECORD(Entry1,
4218  DISKENTRY,
4219  ListEntry);
4220 
4221  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
4222  {
4223  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
4224  continue;
4225  }
4226 
4227  for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
4228  Entry2 != &DiskEntry->PrimaryPartListHead;
4229  Entry2 = Entry2->Flink)
4230  {
4231  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4232  if (PartEntry->IsPartitioned && PartEntry->New)
4233  {
4234  ASSERT(DiskEntry == PartEntry->DiskEntry);
4235  if (pDiskEntry) *pDiskEntry = DiskEntry;
4236  *pPartEntry = PartEntry;
4237  return TRUE;
4238  }
4239  }
4240 
4241  for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
4242  Entry2 != &DiskEntry->LogicalPartListHead;
4243  Entry2 = Entry2->Flink)
4244  {
4245  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4246  if (PartEntry->IsPartitioned && PartEntry->New)
4247  {
4248  ASSERT(DiskEntry == PartEntry->DiskEntry);
4249  if (pDiskEntry) *pDiskEntry = DiskEntry;
4250  *pPartEntry = PartEntry;
4251  return TRUE;
4252  }
4253  }
4254  }
4255 
4256  if (pDiskEntry) *pDiskEntry = NULL;
4257  *pPartEntry = NULL;
4258 
4259  return FALSE;
4260 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:124
#define TRUE
Definition: types.h:120
PARTITION_STYLE DiskStyle
Definition: partlist.h:114
smooth NULL
Definition: ftsmooth.c:416
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:119
struct _DISKENTRY * DiskEntry
Definition: partlist.h:39
LIST_ENTRY List
Definition: psmgr.c:57
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: typedefs.h:117
BOOLEAN New
Definition: partlist.h:64
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:125
BOOLEAN IsPartitioned
Definition: partlist.h:59

Referenced by SelectFileSystemPage().

◆ GetNextUnpartitionedEntry()

static PPARTENTRY GetNextUnpartitionedEntry ( IN PPARTENTRY  PartEntry)
static

Definition at line 2926 of file partlist.c.

2928 {
2929  PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2930  PPARTENTRY NextPartEntry;
2931  PLIST_ENTRY ListHead;
2932 
2933  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2934  {
2935  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2936  return NULL;
2937  }
2938 
2939  if (PartEntry->LogicalPartition)
2940  ListHead = &DiskEntry->LogicalPartListHead;
2941  else
2942  ListHead = &DiskEntry->PrimaryPartListHead;
2943 
2944  if (PartEntry->ListEntry.Flink != ListHead)
2945  {
2946  NextPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Flink,
2947  PARTENTRY,
2948  ListEntry);
2949  if (!NextPartEntry->IsPartitioned)
2950  {
2951  ASSERT(NextPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
2952  return NextPartEntry;
2953  }
2954  }
2955 
2956  return NULL;
2957 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:124
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
PARTITION_STYLE DiskStyle
Definition: partlist.h:114
smooth NULL
Definition: ftsmooth.c:416
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:46
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: typedefs.h:117
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:125
BOOLEAN IsPartitioned
Definition: partlist.h:59

Referenced by DeletePartition().

◆ GetPartition()

PPARTENTRY GetPartition ( IN PDISKENTRY  DiskEntry,
IN ULONG  PartitionNumber 
)

Definition at line 2273 of file partlist.c.

2277 {
2278  PPARTENTRY PartEntry;
2280 
2281  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2282  {
2283  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2284  return NULL;
2285  }
2286 
2287  /* Disk found, loop over the primary partitions first... */
2288  for (Entry = DiskEntry->PrimaryPartListHead.Flink;
2289  Entry != &DiskEntry->PrimaryPartListHead;
2290  Entry = Entry->Flink)
2291  {
2292  PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2293 
2294  if (PartEntry->PartitionNumber == PartitionNumber)
2295  {
2296  /* Partition found */
2297  return PartEntry;
2298  }
2299  }
2300 
2301  /* ... then over the logical partitions if needed */
2302  for (Entry = DiskEntry->LogicalPartListHead.Flink;
2303  Entry != &DiskEntry->LogicalPartListHead;
2304  Entry = Entry->Flink)
2305  {
2306  PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2307 
2308  if (PartEntry->PartitionNumber == PartitionNumber)
2309  {
2310  /* Partition found */
2311  return PartEntry;
2312  }
2313  }
2314 
2315  /* The partition was not found on the disk, stop there */
2316  return NULL;
2317 }
ULONG PartitionNumber
Definition: partlist.h:48
struct _Entry Entry
Definition: kefuncs.h:627
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2056
smooth NULL
Definition: ftsmooth.c:416
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:117
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 2476 of file partlist.c.

2479 {
2480  PLIST_ENTRY DiskListEntry;
2481  PLIST_ENTRY PartListEntry;
2483 
2484  /* Fail if no disks are available */
2485  if (IsListEmpty(&List->DiskListHead))
2486  return NULL;
2487 
2488  /* Check for the previous usable entry on the current partition's disk */
2489  if (CurrentPart != NULL)
2490  {
2491  CurrentDisk = CurrentPart->DiskEntry;
2492 
2493  if (CurrentPart->LogicalPartition)
2494  {
2495  /* Logical partition */
2496 
2497  PartListEntry = CurrentPart->ListEntry.Blink;
2498  if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2499  {
2500  /* Previous logical partition */
2501  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2502  }
2503  else
2504  {
2505  /* Extended partition */
2506  CurrentPart = CurrentDisk->ExtendedPartition;
2507  }
2508  return CurrentPart;
2509  }
2510  else
2511  {
2512  /* Primary or extended partition */
2513 
2514  PartListEntry = CurrentPart->ListEntry.Blink;
2515  if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2516  {
2517  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2518 
2519  if (CurrentPart->IsPartitioned &&
2520  IsContainerPartition(CurrentPart->PartitionType))
2521  {
2522  PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2523  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2524  }
2525 
2526  return CurrentPart;
2527  }
2528  }
2529  }
2530 
2531  /* Search for the last partition entry on the previous disk */
2532  for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Blink
2533  : List->DiskListHead.Blink);
2534  DiskListEntry != &List->DiskListHead;
2535  DiskListEntry = DiskListEntry->Blink)
2536  {
2537  CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
2538 
2540  {
2541  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2542  continue;
2543  }
2544 
2545  PartListEntry = CurrentDisk->PrimaryPartListHead.Blink;
2546  if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2547  {
2548  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2549 
2550  if (CurrentPart->IsPartitioned &&
2551  IsContainerPartition(CurrentPart->PartitionType))
2552  {
2553  PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2554  if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2555  {
2556  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2557  return CurrentPart;
2558  }
2559  }
2560  else
2561  {
2562  return CurrentPart;
2563  }
2564  }
2565  }
2566 
2567  return NULL;
2568 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:124
PDISKENTRY CurrentDisk
Definition: partlist.c:73
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:250
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
PPARTENTRY ExtendedPartition
Definition: partlist.h:128
PARTITION_STYLE DiskStyle
Definition: partlist.h:114
smooth NULL
Definition: ftsmooth.c:416
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 List
Definition: psmgr.c:57
LIST_ENTRY ListEntry
Definition: partlist.h:76
Definition: typedefs.h:117
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:125

Referenced by ScrollUpPartitionList().

◆ GetPrevUnpartitionedEntry()

static PPARTENTRY GetPrevUnpartitionedEntry ( IN PPARTENTRY  PartEntry)
static

Definition at line 2891 of file partlist.c.

2893 {
2894  PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2895  PPARTENTRY PrevPartEntry;
2896  PLIST_ENTRY ListHead;
2897 
2898  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2899  {
2900  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2901  return NULL;
2902  }
2903 
2904  if (PartEntry->LogicalPartition)
2905  ListHead = &DiskEntry->LogicalPartListHead;
2906  else
2907  ListHead = &DiskEntry->PrimaryPartListHead;
2908 
2909  if (PartEntry->ListEntry.Blink != ListHead)
2910  {
2911  PrevPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Blink,
2912  PARTENTRY,
2913  ListEntry);
2914  if (!PrevPartEntry->IsPartitioned)
2915  {
2916  ASSERT(PrevPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
2917  return PrevPartEntry;
2918  }
2919  }
2920 
2921  return NULL;
2922 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:124
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
PARTITION_STYLE DiskStyle
Definition: partlist.h:114
smooth NULL
Definition: ftsmooth.c:416
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:46
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: typedefs.h:117
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:125
BOOLEAN IsPartitioned
Definition: partlist.h:59

Referenced by DeletePartition().

◆ GetPrimaryPartitionCount()

static ULONG GetPrimaryPartitionCount ( IN PDISKENTRY  DiskEntry)
static

Definition at line 2605 of file partlist.c.

2607 {
2609  PPARTENTRY PartEntry;
2610  ULONG Count = 0;
2611 
2612  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2613  {
2614  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2615  return 0;
2616  }
2617 
2618  for (Entry = DiskEntry->PrimaryPartListHead.Flink;
2619  Entry != &DiskEntry->PrimaryPartListHead;
2620  Entry = Entry->Flink)
2621  {
2622  PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2623  if (PartEntry->IsPartitioned)
2624  Count++;
2625  }
2626 
2627  return Count;
2628 }
struct _Entry Entry
Definition: kefuncs.h:627
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
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:117
unsigned int ULONG
Definition: retypes.h:1
base of all file and directory entries
Definition: entries.h:82
BOOLEAN IsPartitioned
Definition: partlist.h:59

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

◆ GetSystemDisk()

static PDISKENTRY GetSystemDisk ( IN PPARTLIST  List)
static

Definition at line 1895 of file partlist.c.

1897 {
1899  PDISKENTRY DiskEntry;
1900 
1901  /* Check for empty disk list */
1902  if (IsListEmpty(&List->DiskListHead))
1903  return NULL;
1904 
1905  /*
1906  * If we already have a system partition, the system disk
1907  * is the one on which the system partition resides.
1908  */
1909  if (List->SystemPartition)
1910  return List->SystemPartition->DiskEntry;
1911 
1912  /* Loop over the disks and find the correct one */
1913  for (Entry = List->DiskListHead.Flink;
1914  Entry != &List->DiskListHead;
1915  Entry = Entry->Flink)
1916  {
1917  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
1918 
1919  /* The disk must be a fixed disk and be found by the firmware */
1920  if (DiskEntry->MediaType == FixedMedia && DiskEntry->BiosFound)
1921  {
1922  break;
1923  }
1924  }
1925  if (Entry == &List->DiskListHead)
1926  {
1927  /* We haven't encountered any suitable disk */
1928  return NULL;
1929  }
1930 
1931  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1932  {
1933  DPRINT1("System disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
1934  }
1935 
1936  return DiskEntry;
1937 }
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:114
smooth NULL
Definition: ftsmooth.c:416
MEDIA_TYPE MediaType
Definition: partlist.h:81
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:119
BOOLEAN BiosFound
Definition: partlist.h:95
LIST_ENTRY List
Definition: psmgr.c:57
Definition: typedefs.h:117
#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  PartEntry->PartitionType = FileSystemToPartitionType(L"RAW", &PartEntry->StartSector, &PartEntry->SectorCount);
910  ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
911 
912  PartEntry->FormatState = Unformatted;
913  PartEntry->FileSystem[0] = L'\0';
914  // PartEntry->AutoCreate = AutoCreate;
915  PartEntry->BootIndicator = FALSE;
916 
917  DPRINT1("First Sector : %I64u\n", PartEntry->StartSector.QuadPart);
918  DPRINT1("Last Sector : %I64u\n", PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1);
919  DPRINT1("Total Sectors: %I64u\n", PartEntry->SectorCount.QuadPart);
920 
921  return TRUE;
922 }
#define TRUE
Definition: types.h:120
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
smooth NULL
Definition: ftsmooth.c:416
ULONG SectorAlignment
Definition: partlist.h:91
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:65
ULONGLONG AlignDown(IN ULONGLONG Value, IN ULONG Alignment)
Definition: partlist.c:246
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static const WCHAR L[]
Definition: oid.c:1250
ULONG SectorCount
Definition: part_xbox.c:31
#define DPRINT1
Definition: precomp.h:8
UCHAR FileSystemToPartitionType(IN PCWSTR FileSystem, IN PULARGE_INTEGER StartSector, IN PULARGE_INTEGER SectorCount)
Definition: fsutil.c:457

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:42
#define TRUE
Definition: types.h:120
struct _Entry Entry
Definition: kefuncs.h:627
ULARGE_INTEGER SectorCount
Definition: partlist.h:43
#define InsertTailList(ListHead, Entry)
#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:119
UCHAR PartitionType
Definition: partlist.h:46
LIST_ENTRY List
Definition: psmgr.c:57
Definition: typedefs.h:117
#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 2573 of file partlist.c.

2575 {
2576  if (PartitionInfo->StartingOffset.QuadPart == 0 &&
2577  PartitionInfo->PartitionLength.QuadPart == 0)
2578  {
2579  return TRUE;
2580  }
2581 
2582  return FALSE;
2583 }
#define TRUE
Definition: types.h:120
_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 1945 of file partlist.c.

1947 {
1948  // TODO: Support for GPT disks!
1949 
1950  if (IsContainerPartition(PartEntry->PartitionType))
1951  return FALSE;
1952 
1953  /* Check if the partition is partitioned, used and active */
1954  if (PartEntry->IsPartitioned &&
1955  // !IsContainerPartition(PartEntry->PartitionType) &&
1956  PartEntry->BootIndicator)
1957  {
1958  /* Yes it is */
1959  ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
1960  return TRUE;
1961  }
1962 
1963  return FALSE;
1964 }
#define TRUE
Definition: types.h:120
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:250
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)

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

◆ IsSamePrimaryLayoutEntry()

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

Definition at line 2588 of file partlist.c.

2592 {
2593  if (PartitionInfo->StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector &&
2594  PartitionInfo->PartitionLength.QuadPart == PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector)
2595 // PartitionInfo->PartitionType == PartEntry->PartitionType
2596  {
2597  return TRUE;
2598  }
2599 
2600  return FALSE;
2601 }
#define TRUE
Definition: types.h:120
_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
smooth NULL
Definition: ftsmooth.c:416
uint64_t ULONGLONG
Definition: typedefs.h:65
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2101
#define PARTITION_FAT_16
Definition: disk.h:90
#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 3354 of file partlist.c.

3356 {
3357  /* Check the type and the file system of this partition */
3358 
3359  /*
3360  * We do not support extended partition containers (on MBR disks) marked
3361  * as active, and containing code inside their extended boot records.
3362  */
3363  if (IsContainerPartition(PartEntry->PartitionType))
3364  {
3365  DPRINT1("System partition %lu in disk %lu is an extended partition container?!\n",
3366  PartEntry->PartitionNumber, PartEntry->DiskEntry->DiskNumber);
3367  return FALSE;
3368  }
3369 
3370  /*
3371  * ADDITIONAL CHECKS / BIG HACK:
3372  *
3373  * Retrieve its file system and check whether we have
3374  * write support for it. If that is the case we are fine
3375  * and we can use it directly. However if we don't have
3376  * write support we will need to change the active system
3377  * partition.
3378  *
3379  * NOTE that this is completely useless on architectures
3380  * where a real system partition is required, as on these
3381  * architectures the partition uses the FAT FS, for which
3382  * we do have write support.
3383  * NOTE also that for those architectures looking for a
3384  * partition boot indicator is insufficient.
3385  */
3386  if (PartEntry->FormatState == Unformatted)
3387  {
3388  /* If this partition is mounted, it would use RawFS ("RAW") */
3389  return TRUE;
3390  }
3391  else if ((PartEntry->FormatState == Preformatted) ||
3392  (PartEntry->FormatState == Formatted))
3393  {
3394  ASSERT(*PartEntry->FileSystem);
3395 
3396  /* NOTE: Please keep in sync with the RegisteredFileSystems list! */
3397  if (wcsicmp(PartEntry->FileSystem, L"FAT") == 0 ||
3398  wcsicmp(PartEntry->FileSystem, L"FAT32") == 0 ||
3399  // wcsicmp(PartEntry->FileSystem, L"NTFS") == 0 ||
3400  wcsicmp(PartEntry->FileSystem, L"BTRFS") == 0)
3401  {
3402  return TRUE;
3403  }
3404  else
3405  {
3406  // WARNING: We cannot write on this FS yet!
3407  DPRINT1("Recognized file system '%S' that doesn't have write support yet!\n",
3408  PartEntry->FileSystem);
3409  return FALSE;
3410  }
3411  }
3412  else // if (PartEntry->FormatState == UnknownFormat)
3413  {
3414  ASSERT(!*PartEntry->FileSystem);
3415 
3416  DPRINT1("System partition %lu in disk %lu with no or unknown FS?!\n",
3417  PartEntry->PartitionNumber, PartEntry->DiskEntry->DiskNumber);
3418  return FALSE;
3419  }
3420 
3421  // HACK: WARNING: We cannot write on this FS yet!
3422  // See fsutil.c:InferFileSystem()
3423  if (PartEntry->PartitionType == PARTITION_IFS)
3424  {
3425  DPRINT1("Recognized file system '%S' that doesn't have write support yet!\n",
3426  PartEntry->FileSystem);
3427  return FALSE;
3428  }
3429 
3430  return TRUE;
3431 }
#define TRUE
Definition: types.h:120
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:250