ReactOS  0.4.14-dev-77-gd9e7c48
partlist.c File Reference
#include "precomp.h"
#include <ntddscsi.h>
#include "partlist.h"
#include "fsutil.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 15 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 1482 of file partlist.c.

1486 {
1487  DISK_GEOMETRY DiskGeometry;
1488  SCSI_ADDRESS ScsiAddress;
1489  PDISKENTRY DiskEntry;
1491  NTSTATUS Status;
1492  PPARTITION_SECTOR Mbr;
1493  PULONG Buffer;
1495  WCHAR Identifier[20];
1496  ULONG Checksum;
1497  ULONG Signature;
1498  ULONG i;
1499  PLIST_ENTRY ListEntry;
1500  PBIOSDISKENTRY BiosDiskEntry;
1501  ULONG LayoutBufferSize;
1502  PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
1503 
1504  /* Retrieve the drive geometry */
1506  NULL,
1507  NULL,
1508  NULL,
1509  &Iosb,
1511  NULL,
1512  0,
1513  &DiskGeometry,
1514  sizeof(DiskGeometry));
1515  if (!NT_SUCCESS(Status))
1516  return;
1517 
1518  if (DiskGeometry.MediaType != FixedMedia &&
1519  DiskGeometry.MediaType != RemovableMedia)
1520  {
1521  return;
1522  }
1523 
1524  /*
1525  * FIXME: Here we suppose the disk is always SCSI. What if it is
1526  * of another type? To check this we need to retrieve the name of
1527  * the driver the disk device belongs to.
1528  */
1530  NULL,
1531  NULL,
1532  NULL,
1533  &Iosb,
1535  NULL,
1536  0,
1537  &ScsiAddress,
1538  sizeof(ScsiAddress));
1539  if (!NT_SUCCESS(Status))
1540  return;
1541 
1542  /*
1543  * Check whether the disk is initialized, by looking at its MBR.
1544  * NOTE that this must be generalized to GPT disks as well!
1545  */
1546 
1548  0,
1549  DiskGeometry.BytesPerSector);
1550  if (Mbr == NULL)
1551  return;
1552 
1553  FileOffset.QuadPart = 0;
1555  NULL,
1556  NULL,
1557  NULL,
1558  &Iosb,
1559  (PVOID)Mbr,
1560  DiskGeometry.BytesPerSector,
1561  &FileOffset,
1562  NULL);
1563  if (!NT_SUCCESS(Status))
1564  {
1565  RtlFreeHeap(ProcessHeap, 0, Mbr);
1566  DPRINT1("NtReadFile failed, status=%x\n", Status);
1567  return;
1568  }
1569  Signature = Mbr->Signature;
1570 
1571  /* Calculate the MBR checksum */
1572  Checksum = 0;
1573  Buffer = (PULONG)Mbr;
1574  for (i = 0; i < 128; i++)
1575  {
1576  Checksum += Buffer[i];
1577  }
1578  Checksum = ~Checksum + 1;
1579 
1580  RtlStringCchPrintfW(Identifier, ARRAYSIZE(Identifier),
1581  L"%08x-%08x-%c",
1582  Checksum, Signature,
1583  (Mbr->Magic == PARTITION_MAGIC) ? L'A' : L'X');
1584  DPRINT("Identifier: %S\n", Identifier);
1585 
1586  DiskEntry = RtlAllocateHeap(ProcessHeap,
1588  sizeof(DISKENTRY));
1589  if (DiskEntry == NULL)
1590  {
1591  RtlFreeHeap(ProcessHeap, 0, Mbr);
1592  DPRINT1("Failed to allocate a new disk entry.\n");
1593  return;
1594  }
1595 
1596  DiskEntry->PartList = List;
1597 
1598 #if 0
1599  {
1600  FILE_FS_DEVICE_INFORMATION FileFsDevice;
1601 
1602  /* Query the device for its type */
1604  &Iosb,
1605  &FileFsDevice,
1606  sizeof(FileFsDevice),
1608  if (!NT_SUCCESS(Status))
1609  {
1610  DPRINT1("Couldn't detect device type for disk %lu of identifier '%S'...\n", DiskNumber, Identifier);
1611  }
1612  else
1613  {
1614  DPRINT1("Disk %lu : DeviceType: 0x%08x ; Characteristics: 0x%08x\n", DiskNumber, FileFsDevice.DeviceType, FileFsDevice.Characteristics);
1615  }
1616  }
1617  // NOTE: We may also use NtQueryVolumeInformationFile(FileFsDeviceInformation).
1618 #endif
1619  DiskEntry->MediaType = DiskGeometry.MediaType;
1620  if (DiskEntry->MediaType == RemovableMedia)
1621  {
1622  DPRINT1("Disk %lu of identifier '%S' is removable\n", DiskNumber, Identifier);
1623  }
1624  else // if (DiskEntry->MediaType == FixedMedia)
1625  {
1626  DPRINT1("Disk %lu of identifier '%S' is fixed\n", DiskNumber, Identifier);
1627  }
1628 
1629 // DiskEntry->Checksum = Checksum;
1630 // DiskEntry->Signature = Signature;
1631  DiskEntry->BiosFound = FALSE;
1632 
1633  /*
1634  * Check if this disk has a valid MBR: verify its signature,
1635  * and whether its two first bytes are a valid instruction
1636  * (related to this, see IsThereAValidBootSector() in partlist.c).
1637  *
1638  * See also ntoskrnl/fstub/fstubex.c!FstubDetectPartitionStyle().
1639  */
1640 
1641  // DiskEntry->NoMbr = (Mbr->Magic != PARTITION_MAGIC || (*(PUSHORT)Mbr->BootCode) == 0x0000);
1642 
1643  /* If we have not the 0xAA55 then it's raw partition */
1644  if (Mbr->Magic != PARTITION_MAGIC)
1645  {
1646  DiskEntry->DiskStyle = PARTITION_STYLE_RAW;
1647  }
1648  /* Check partitions types: if first is 0xEE and all the others 0, we have GPT */
1649  else if (Mbr->Partition[0].PartitionType == EFI_PMBR_OSTYPE_EFI &&
1650  Mbr->Partition[1].PartitionType == 0 &&
1651  Mbr->Partition[2].PartitionType == 0 &&
1652  Mbr->Partition[3].PartitionType == 0)
1653  {
1654  DiskEntry->DiskStyle = PARTITION_STYLE_GPT;
1655  }
1656  /* Otherwise, partition table is in MBR */
1657  else
1658  {
1659  DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
1660  }
1661 
1662  /* Free the MBR sector buffer */
1663  RtlFreeHeap(ProcessHeap, 0, Mbr);
1664 
1665 
1666  for (ListEntry = List->BiosDiskListHead.Flink;
1667  ListEntry != &List->BiosDiskListHead;
1668  ListEntry = ListEntry->Flink)
1669  {
1670  BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
1671  /* FIXME:
1672  * Compare the size from bios and the reported size from driver.
1673  * If we have more than one disk with a zero or with the same signature
1674  * we must create new signatures and reboot. After the reboot,
1675  * it is possible to identify the disks.
1676  */
1677  if (BiosDiskEntry->Signature == Signature &&
1678  BiosDiskEntry->Checksum == Checksum &&
1679  BiosDiskEntry->DiskEntry == NULL)
1680  {
1681  if (!DiskEntry->BiosFound)
1682  {
1683  DiskEntry->HwAdapterNumber = BiosDiskEntry->AdapterNumber;
1684  DiskEntry->HwControllerNumber = BiosDiskEntry->ControllerNumber;
1685  DiskEntry->HwDiskNumber = BiosDiskEntry->DiskNumber;
1686 
1687  if (DiskEntry->MediaType == RemovableMedia)
1688  {
1689  /* Set the removable disk number to zero */
1690  DiskEntry->HwFixedDiskNumber = 0;
1691  }
1692  else // if (DiskEntry->MediaType == FixedMedia)
1693  {
1694  /* The fixed disk number will later be adjusted using the number of removable disks */
1695  DiskEntry->HwFixedDiskNumber = BiosDiskEntry->DiskNumber;
1696  }
1697 
1698  DiskEntry->BiosFound = TRUE;
1699  BiosDiskEntry->DiskEntry = DiskEntry;
1700  break;
1701  }
1702  else
1703  {
1704  // FIXME: What to do?
1705  DPRINT1("Disk %lu of identifier '%S' has already been found?!\n", DiskNumber, Identifier);
1706  }
1707  }
1708  }
1709 
1710  if (!DiskEntry->BiosFound)
1711  {
1712  DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %lu may not be bootable by the BIOS!\n", DiskNumber);
1713  }
1714 
1715  DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
1716  DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
1717  DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
1718  DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
1719 
1720  DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders);
1721  DPRINT("TracksPerCylinder %lu\n", DiskEntry->TracksPerCylinder);
1722  DPRINT("SectorsPerTrack %lu\n", DiskEntry->SectorsPerTrack);
1723  DPRINT("BytesPerSector %lu\n", DiskEntry->BytesPerSector);
1724 
1725  DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart *
1726  (ULONGLONG)DiskGeometry.TracksPerCylinder *
1727  (ULONGLONG)DiskGeometry.SectorsPerTrack;
1728 
1729  DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
1730  DiskEntry->CylinderAlignment = DiskGeometry.TracksPerCylinder *
1731  DiskGeometry.SectorsPerTrack;
1732 
1733  DPRINT("SectorCount %I64u\n", DiskEntry->SectorCount.QuadPart);
1734  DPRINT("SectorAlignment %lu\n", DiskEntry->SectorAlignment);
1735 
1736  DiskEntry->DiskNumber = DiskNumber;
1737  DiskEntry->Port = ScsiAddress.PortNumber;
1738  DiskEntry->Bus = ScsiAddress.PathId;
1739  DiskEntry->Id = ScsiAddress.TargetId;
1740 
1741  GetDriverName(DiskEntry);
1742  /*
1743  * Actually it would be more correct somehow to use:
1744  *
1745  * OBJECT_NAME_INFORMATION NameInfo; // ObjectNameInfo;
1746  * ULONG ReturnedLength;
1747  *
1748  * Status = NtQueryObject(SomeHandleToTheDisk,
1749  * ObjectNameInformation,
1750  * &NameInfo,
1751  * sizeof(NameInfo),
1752  * &ReturnedLength);
1753  * etc...
1754  *
1755  * See examples in https://git.reactos.org/?p=reactos.git;a=blob;f=reactos/ntoskrnl/io/iomgr/error.c;hb=2f3a93ee9cec8322a86bf74b356f1ad83fc912dc#l267
1756  */
1757 
1760 
1761  InsertAscendingList(&List->DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber);
1762 
1763 
1764  /*
1765  * We now retrieve the disk partition layout
1766  */
1767 
1768  /*
1769  * Stop there now if the disk is GPT-partitioned,
1770  * since we currently do not support such disks.
1771  */
1772  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1773  {
1774  DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1775  return;
1776  }
1777 
1778  /* Allocate a layout buffer with 4 partition entries first */
1779  LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
1780  ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
1783  LayoutBufferSize);
1784  if (DiskEntry->LayoutBuffer == NULL)
1785  {
1786  DPRINT1("Failed to allocate the disk layout buffer!\n");
1787  return;
1788  }
1789 
1790  /* Keep looping while the drive layout buffer is too small */
1791  for (;;)
1792  {
1793  DPRINT1("Buffer size: %lu\n", LayoutBufferSize);
1795  NULL,
1796  NULL,
1797  NULL,
1798  &Iosb,
1800  NULL,
1801  0,
1802  DiskEntry->LayoutBuffer,
1803  LayoutBufferSize);
1804  if (NT_SUCCESS(Status))
1805  break;
1806 
1808  {
1809  DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status);
1810  return;
1811  }
1812 
1813  LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION);
1814  NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap,
1816  DiskEntry->LayoutBuffer,
1817  LayoutBufferSize);
1818  if (NewLayoutBuffer == NULL)
1819  {
1820  DPRINT1("Failed to reallocate the disk layout buffer!\n");
1821  return;
1822  }
1823 
1824  DiskEntry->LayoutBuffer = NewLayoutBuffer;
1825  }
1826 
1827  DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount);
1828 
1829 #ifdef DUMP_PARTITION_TABLE
1830  DumpPartitionTable(DiskEntry);
1831 #endif
1832 
1833  if (IsSuperFloppy(DiskEntry))
1834  DPRINT1("Disk %lu is a super-floppy\n", DiskNumber);
1835 
1836  if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
1837  DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0 &&
1839  {
1840  if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
1841  {
1842  DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
1843  }
1844  else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
1845  {
1846  DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1847  }
1848  else
1849  {
1850  DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
1851  }
1852  }
1853  else
1854  {
1855  DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1856  }
1857 
1858  if (DiskEntry->LayoutBuffer->PartitionCount == 0)
1859  {
1860  DiskEntry->NewDisk = TRUE;
1861  DiskEntry->LayoutBuffer->PartitionCount = 4;
1862 
1863  for (i = 0; i < 4; i++)
1864  {
1866  }
1867  }
1868  else
1869  {
1870  /* Enumerate and add the first four primary partitions */
1871  for (i = 0; i < 4; i++)
1872  {
1873  AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
1874  }
1875 
1876  /* Enumerate and add the remaining partitions as logical ones */
1877  for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
1878  {
1879  AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
1880  }
1881  }
1882 
1883  ScanForUnpartitionedDiskSpace(DiskEntry);
1884 }
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:394
#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:376
ULONG TracksPerCylinder
Definition: ntdddisk.h:374
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:64
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
HANDLE FileHandle
Definition: stats.c:38
static VOID GetDriverName(IN PDISKENTRY DiskEntry)
Definition: partlist.c:283
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:471
NTSTATUS NTAPI NtQueryVolumeInformationFile(IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FsInformation, IN ULONG Length, IN FS_INFORMATION_CLASS FsInformationClass)
Definition: iofunc.c:4084
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:393
uint64_t ULONGLONG
Definition: typedefs.h:65
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:372
ULONG SectorsPerTrack
Definition: ntdddisk.h:375
MEDIA_TYPE MediaType
Definition: ntdddisk.h:373
ULONG HwDiskNumber
Definition: partlist.h:98
unsigned char PartitionType
Definition: partlist.h:178
BOOLEAN RewritePartition
Definition: ntdddisk.h:400
static VOID ScanForUnpartitionedDiskSpace(IN PDISKENTRY DiskEntry)
Definition: partlist.c:1118
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
BOOLEAN IsSuperFloppy(IN PDISKENTRY DiskEntry)
Definition: partlist.c:679
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:926

Referenced by CreatePartitionList().

◆ AddLogicalDiskSpace()

static VOID AddLogicalDiskSpace ( IN PDISKENTRY  DiskEntry)
static

Definition at line 2996 of file partlist.c.

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

931 {
934  PPARTENTRY PartEntry;
935  HANDLE PartitionHandle;
938  WCHAR PathBuffer[MAX_PATH];
940  UCHAR LabelBuffer[sizeof(FILE_FS_VOLUME_INFORMATION) + 256 * sizeof(WCHAR)];
942 
943  PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
944 
945  if (PartitionInfo->PartitionType == PARTITION_ENTRY_UNUSED ||
946  ((LogicalPartition != FALSE) && IsContainerPartition(PartitionInfo->PartitionType)))
947  {
948  return;
949  }
950 
951  PartEntry = RtlAllocateHeap(ProcessHeap,
953  sizeof(PARTENTRY));
954  if (PartEntry == NULL)
955  return;
956 
957  PartEntry->DiskEntry = DiskEntry;
958 
959  PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
960  PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
961 
962  PartEntry->BootIndicator = PartitionInfo->BootIndicator;
963  PartEntry->PartitionType = PartitionInfo->PartitionType;
964 
965  PartEntry->LogicalPartition = LogicalPartition;
966  PartEntry->IsPartitioned = TRUE;
967  PartEntry->OnDiskPartitionNumber = PartitionInfo->PartitionNumber;
968  PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
969  PartEntry->PartitionIndex = PartitionIndex;
970 
971  /* Specify the partition as initially unformatted */
972  PartEntry->FormatState = Unformatted;
973  PartEntry->FileSystem[0] = L'\0';
974 
975  /* Initialize the partition volume label */
976  RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
977 
978  if (IsContainerPartition(PartEntry->PartitionType))
979  {
980  PartEntry->FormatState = Unformatted;
981 
982  if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
983  DiskEntry->ExtendedPartition = PartEntry;
984  }
985  else if (IsRecognizedPartition(PartEntry->PartitionType))
986  {
987  ASSERT(PartitionInfo->RecognizedPartition);
988  ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
989 
990  /* Try to open the volume so as to mount it */
991  RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
992  L"\\Device\\Harddisk%lu\\Partition%lu",
993  DiskEntry->DiskNumber,
994  PartEntry->PartitionNumber);
995  RtlInitUnicodeString(&Name, PathBuffer);
996 
998  &Name,
1000  NULL,
1001  NULL);
1002 
1003  PartitionHandle = NULL;
1004  Status = NtOpenFile(&PartitionHandle,
1007  &IoStatusBlock,
1010  if (!NT_SUCCESS(Status))
1011  {
1012  DPRINT1("NtOpenFile() failed, Status 0x%08lx\n", Status);
1013  }
1014 
1015  if (PartitionHandle)
1016  {
1018 
1019  /* We don't have a FS, try to guess one */
1020  Status = InferFileSystemByHandle(PartitionHandle,
1021  PartEntry->PartitionType,
1022  PartEntry->FileSystem,
1023  sizeof(PartEntry->FileSystem));
1024  if (!NT_SUCCESS(Status))
1025  DPRINT1("InferFileSystemByHandle() failed, Status 0x%08lx\n", Status);
1026  }
1027  if (*PartEntry->FileSystem)
1028  {
1029  ASSERT(PartitionHandle);
1030 
1031  /*
1032  * Handle partition mounted with RawFS: it is
1033  * either unformatted or has an unknown format.
1034  */
1035  if (wcsicmp(PartEntry->FileSystem, L"RAW") == 0)
1036  {
1037  /*
1038  * True unformatted partitions on NT are created with their
1039  * partition type set to either one of the following values,
1040  * and are mounted with RawFS. This is done this way since we
1041  * are assured to have FAT support, which is the only FS that
1042  * uses these partition types. Therefore, having a partition
1043  * mounted with RawFS and with these partition types means that
1044  * the FAT FS was unable to mount it beforehand and thus the
1045  * partition is unformatted.
1046  * However, any partition mounted by RawFS that does NOT have
1047  * any of these partition types must be considered as having
1048  * an unknown format.
1049  */
1050  if (PartEntry->PartitionType == PARTITION_FAT_12 ||
1051  PartEntry->PartitionType == PARTITION_FAT_16 ||
1052  PartEntry->PartitionType == PARTITION_HUGE ||
1053  PartEntry->PartitionType == PARTITION_XINT13 ||
1054  PartEntry->PartitionType == PARTITION_FAT32 ||
1055  PartEntry->PartitionType == PARTITION_FAT32_XINT13)
1056  {
1057  PartEntry->FormatState = Unformatted;
1058  }
1059  else
1060  {
1061  /* Close the partition before dismounting */
1062  NtClose(PartitionHandle);
1063  PartitionHandle = NULL;
1064  /*
1065  * Dismount the partition since RawFS owns it, and set its
1066  * format to unknown (may or may not be actually formatted).
1067  */
1068  DismountVolume(PartEntry);
1069  PartEntry->FormatState = UnknownFormat;
1070  PartEntry->FileSystem[0] = L'\0';
1071  }
1072  }
1073  else
1074  {
1075  PartEntry->FormatState = Preformatted;
1076  }
1077  }
1078  else
1079  {
1080  PartEntry->FormatState = UnknownFormat;
1081  }
1082 
1083  /* Retrieve the partition volume label */
1084  if (PartitionHandle)
1085  {
1086  Status = NtQueryVolumeInformationFile(PartitionHandle,
1087  &IoStatusBlock,
1088  &LabelBuffer,
1089  sizeof(LabelBuffer),
1091  if (NT_SUCCESS(Status))
1092  {
1093  /* Copy the (possibly truncated) volume label and NULL-terminate it */
1094  RtlStringCbCopyNW(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel),
1095  LabelInfo->VolumeLabel, LabelInfo->VolumeLabelLength);
1096  }
1097  else
1098  {
1099  DPRINT1("NtQueryVolumeInformationFile() failed, Status 0x%08lx\n", Status);
1100  }
1101  }
1102 
1103  /* Close the partition */
1104  if (PartitionHandle)
1105  NtClose(PartitionHandle);
1106  }
1107  else
1108  {
1109  /* Unknown partition, hence unknown format (may or may not be actually formatted) */
1110  PartEntry->FormatState = UnknownFormat;
1111  }
1112 
1113  InsertDiskRegion(DiskEntry, PartEntry, LogicalPartition);
1114 }
#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:245
#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:3113
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
NTSTATUS NTAPI NtQueryVolumeInformationFile(IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FsInformation, IN ULONG Length, IN FS_INFORMATION_CLASS FsInformationClass)
Definition: iofunc.c:4084
static BOOLEAN InsertDiskRegion(IN PDISKENTRY DiskEntry, IN PPARTENTRY PartEntry, IN BOOLEAN LogicalPartition)
Definition: partlist.c:752
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:271
#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
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 245 of file partlist.c.

248 {
249  ULONGLONG Temp;
250 
251  Temp = Value / Alignment;
252 
253  return Temp * Alignment;
254 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
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 257 of file partlist.c.

260 {
261  ULONGLONG Temp, Result;
262 
263  Temp = Value / Alignment;
264 
265  Result = Temp * Alignment;
266  if (Value % Alignment)
267  Result += Alignment;
268 
269  return Result;
270 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
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 316 of file partlist.c.

318 {
319  PDISKENTRY DiskEntry;
320  PPARTENTRY PartEntry;
321  PLIST_ENTRY Entry1;
322  PLIST_ENTRY Entry2;
323  WCHAR Letter;
324 
325  Letter = L'C';
326 
327  /* Assign drive letters to primary partitions */
328  for (Entry1 = List->DiskListHead.Flink;
329  Entry1 != &List->DiskListHead;
330  Entry1 = Entry1->Flink)
331  {
332  DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
333 
334  for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
335  Entry2 != &DiskEntry->PrimaryPartListHead;
336  Entry2 = Entry2->Flink)
337  {
338  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
339 
340  PartEntry->DriveLetter = 0;
341 
342  if (PartEntry->IsPartitioned &&
343  !IsContainerPartition(PartEntry->PartitionType))
344  {
346 
347  if (IsRecognizedPartition(PartEntry->PartitionType) ||
348  PartEntry->SectorCount.QuadPart != 0LL)
349  {
350  if (Letter <= L'Z')
351  {
352  PartEntry->DriveLetter = Letter;
353  Letter++;
354  }
355  }
356  }
357  }
358  }
359 
360  /* Assign drive letters to logical drives */
361  for (Entry1 = List->DiskListHead.Flink;
362  Entry1 != &List->DiskListHead;
363  Entry1 = Entry1->Flink)
364  {
365  DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
366 
367  for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
368  Entry2 != &DiskEntry->LogicalPartListHead;
369  Entry2 = Entry2->Flink)
370  {
371  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
372 
373  PartEntry->DriveLetter = 0;
374 
375  if (PartEntry->IsPartitioned)
376  {
378 
379  if (IsRecognizedPartition(PartEntry->PartitionType) ||
380  PartEntry->SectorCount.QuadPart != 0LL)
381  {
382  if (Letter <= L'Z')
383  {
384  PartEntry->DriveLetter = Letter;
385  Letter++;
386  }
387  }
388  }
389  }
390  }
391 }
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:245
#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:271
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 3023 of file partlist.c.

3027 {
3029 
3030  DPRINT1("CreateExtendedPartition(%I64u)\n", SectorCount);
3031 
3032  if (List == NULL || PartEntry == NULL ||
3033  PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
3034  {
3035  return FALSE;
3036  }
3037 
3039  if (Error != NOT_AN_ERROR)
3040  {
3041  DPRINT1("ExtendedPartitionCreationChecks() failed with error %lu\n", Error);
3042  return FALSE;
3043  }
3044 
3045  /* Initialize the partition entry, inserting a new blank region if needed */
3046  if (!InitializePartitionEntry(PartEntry, SectorCount, FALSE))
3047  return FALSE;
3048 
3049  ASSERT(PartEntry->LogicalPartition == FALSE);
3050 
3051  if (PartEntry->StartSector.QuadPart < 1450560)
3052  {
3053  /* Partition starts below the 8.4GB boundary ==> CHS partition */
3054  PartEntry->PartitionType = PARTITION_EXTENDED;
3055  }
3056  else
3057  {
3058  /* Partition starts above the 8.4GB boundary ==> LBA partition */
3059  PartEntry->PartitionType = PARTITION_XINT13_EXTENDED;
3060  }
3061 
3062  // FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container)
3063  PartEntry->New = FALSE;
3064  PartEntry->FormatState = Formatted;
3065 
3066  PartEntry->DiskEntry->ExtendedPartition = PartEntry;
3067 
3068  AddLogicalDiskSpace(PartEntry->DiskEntry);
3069 
3070  UpdateDiskLayout(PartEntry->DiskEntry);
3072 
3073  return TRUE;
3074 }
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:856
smooth NULL
Definition: ftsmooth.c:416
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2710
#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:32
#define PARTITION_XINT13_EXTENDED
Definition: disk.h:98
#define DPRINT1
Definition: precomp.h:8
static VOID AddLogicalDiskSpace(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2996
static VOID AssignDriveLetters(IN PPARTLIST List)
Definition: partlist.c:316

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

824 {
825  PPARTENTRY NewPartEntry;
826 
827  NewPartEntry = RtlAllocateHeap(ProcessHeap,
829  sizeof(PARTENTRY));
830  if (NewPartEntry == NULL)
831  return NULL;
832 
833  NewPartEntry->DiskEntry = DiskEntry;
834 
835  NewPartEntry->StartSector.QuadPart = StartSector;
836  NewPartEntry->SectorCount.QuadPart = SectorCount;
837 
838  NewPartEntry->LogicalPartition = LogicalSpace;
839  NewPartEntry->IsPartitioned = FALSE;
840  NewPartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
841  NewPartEntry->FormatState = Unformatted;
842  NewPartEntry->FileSystem[0] = L'\0';
843 
844  DPRINT1("First Sector : %I64u\n", NewPartEntry->StartSector.QuadPart);
845  DPRINT1("Last Sector : %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
846  DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
847 
848  /* Insert the new entry into the list */
849  InsertTailList(ListHead, &NewPartEntry->ListEntry);
850 
851  return NewPartEntry;
852 }
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:32
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 3077 of file partlist.c.

3082 {
3084 
3085  DPRINT1("CreateLogicalPartition(%I64u)\n", SectorCount);
3086 
3087  if (List == NULL || PartEntry == NULL ||
3088  PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
3089  {
3090  return FALSE;
3091  }
3092 
3094  if (Error != NOT_AN_ERROR)
3095  {
3096  DPRINT1("LogicalPartitionCreationChecks() failed with error %lu\n", Error);
3097  return FALSE;
3098  }
3099 
3100  /* Initialize the partition entry, inserting a new blank region if needed */
3101  if (!InitializePartitionEntry(PartEntry, SectorCount, AutoCreate))
3102  return FALSE;
3103 
3104  ASSERT(PartEntry->LogicalPartition == TRUE);
3105 
3106  UpdateDiskLayout(PartEntry->DiskEntry);
3108 
3109  return TRUE;
3110 }
#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:856
smooth NULL
Definition: ftsmooth.c:416
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2710
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:32
#define DPRINT1
Definition: precomp.h:8
static VOID AssignDriveLetters(IN PPARTLIST List)
Definition: partlist.c:316

Referenced by CreateLogicalPartitionPage(), and SelectPartitionPage().

◆ CreatePartitionList()

PPARTLIST CreatePartitionList ( VOID  )

Definition at line 2023 of file partlist.c.

2024 {
2025  PPARTLIST List;
2026  PDISKENTRY SystemDisk;
2030  ULONG ReturnSize;
2031  NTSTATUS Status;
2032  ULONG DiskNumber;
2036 
2038  0,
2039  sizeof(PARTLIST));
2040  if (List == NULL)
2041  return NULL;
2042 
2043  List->SystemPartition = NULL;
2044 
2045  InitializeListHead(&List->DiskListHead);
2046  InitializeListHead(&List->BiosDiskListHead);
2047 
2048  /*
2049  * Enumerate the disks seen by the BIOS; this will be used later
2050  * to map drives seen by NTOS with their corresponding BIOS names.
2051  */
2053 
2054  /* Enumerate disks seen by NTOS */
2056  &Sdi,
2057  sizeof(Sdi),
2058  &ReturnSize);
2059  if (!NT_SUCCESS(Status))
2060  {
2061  DPRINT1("NtQuerySystemInformation() failed, Status 0x%08lx", Status);
2063  return NULL;
2064  }
2065 
2066  for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
2067  {
2069  L"\\Device\\Harddisk%lu\\Partition0",
2070  DiskNumber);
2072 
2074  &Name,
2076  NULL,
2077  NULL);
2078 
2082  &Iosb,
2085  if (NT_SUCCESS(Status))
2086  {
2087  AddDiskToList(FileHandle, DiskNumber, List);
2089  }
2090  }
2091 
2095 
2096  /*
2097  * Retrieve the system partition: the active partition on the system
2098  * disk (the one that will be booted by default by the hardware).
2099  */
2100  SystemDisk = GetSystemDisk(List);
2101  List->SystemPartition = (SystemDisk ? GetActiveDiskPartition(SystemDisk) : NULL);
2102 
2103  return List;
2104 }
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:1967
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:1391
#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:1421
#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:1894
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:515
static VOID AddDiskToList(IN HANDLE FileHandle, IN ULONG DiskNumber, IN PPARTLIST List)
Definition: partlist.c:1482
#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:316

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

2964 {
2966 
2967  DPRINT1("CreatePrimaryPartition(%I64u)\n", SectorCount);
2968 
2969  if (List == NULL || PartEntry == NULL ||
2970  PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
2971  {
2972  return FALSE;
2973  }
2974 
2976  if (Error != NOT_AN_ERROR)
2977  {
2978  DPRINT1("PrimaryPartitionCreationChecks() failed with error %lu\n", Error);
2979  return FALSE;
2980  }
2981 
2982  /* Initialize the partition entry, inserting a new blank region if needed */
2983  if (!InitializePartitionEntry(PartEntry, SectorCount, AutoCreate))
2984  return FALSE;
2985 
2986  ASSERT(PartEntry->LogicalPartition == FALSE);
2987 
2988  UpdateDiskLayout(PartEntry->DiskEntry);
2990 
2991  return TRUE;
2992 }
#define TRUE
Definition: types.h:120
static BOOLEAN InitializePartitionEntry(IN OUT PPARTENTRY PartEntry, IN ULONGLONG SectorCount, IN BOOLEAN AutoCreate)
Definition: partlist.c:856
smooth NULL
Definition: ftsmooth.c:416
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2710
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:32
#define DPRINT1
Definition: precomp.h:8
static VOID AssignDriveLetters(IN PPARTLIST List)
Definition: partlist.c:316

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

◆ DeletePartition()

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

Definition at line 3220 of file partlist.c.

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

Referenced by DeletePartitionPage().

◆ DestroyPartitionList()

VOID DestroyPartitionList ( IN PPARTLIST  List)

Definition at line 2107 of file partlist.c.

2109 {
2110  PDISKENTRY DiskEntry;
2111  PBIOSDISKENTRY BiosDiskEntry;
2112  PPARTENTRY PartEntry;
2114 
2115  /* Release disk and partition info */
2116  while (!IsListEmpty(&List->DiskListHead))
2117  {
2118  Entry = RemoveHeadList(&List->DiskListHead);
2119  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2120 
2121  /* Release driver name */
2122  RtlFreeUnicodeString(&DiskEntry->DriverName);
2123 
2124  /* Release primary partition list */
2125  while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
2126  {
2127  Entry = RemoveHeadList(&DiskEntry->PrimaryPartListHead);
2128  PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2129 
2130  RtlFreeHeap(ProcessHeap, 0, PartEntry);
2131  }
2132 
2133  /* Release logical partition list */
2134  while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
2135  {
2136  Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
2137  PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2138 
2139  RtlFreeHeap(ProcessHeap, 0, PartEntry);
2140  }
2141 
2142  /* Release layout buffer */
2143  if (DiskEntry->LayoutBuffer != NULL)
2144  RtlFreeHeap(ProcessHeap, 0, DiskEntry->LayoutBuffer);
2145 
2146  /* Release disk entry */
2147  RtlFreeHeap(ProcessHeap, 0, DiskEntry);
2148  }
2149 
2150  /* Release the bios disk info */
2151  while (!IsListEmpty(&List->BiosDiskListHead))
2152  {
2153  Entry = RemoveHeadList(&List->BiosDiskListHead);
2154  BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
2155 
2156  RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
2157  }
2158 
2159  /* Release list head */
2161 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:124
struct _Entry Entry
Definition: kefuncs.h:640
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 425 of file partlist.c.

432 {
433  PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
434  PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
435  PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
436  ULONG i;
437 
440  return STATUS_UNSUCCESSFUL;
441 
442  FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
443 
444  /* Hm. Version and Revision are not set on Microsoft Windows XP... */
445 #if 0
446  if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
447  FullResourceDescriptor->PartialResourceList.Revision != 1)
448  return STATUS_UNSUCCESSFUL;
449 #endif
450 
451  for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
452  {
454  FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize != sizeof(CM_DISK_GEOMETRY_DEVICE_DATA))
455  continue;
456 
457  DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1];
458  BiosDiskEntry->DiskGeometry = *DiskGeometry;
459 
460  return STATUS_SUCCESS;
461  }
462 
463  return STATUS_UNSUCCESSFUL;
464 }
#define CmResourceTypeDeviceSpecific
Definition: hwresource.cpp:127
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4016
struct _CM_DISK_GEOMETRY_DEVICE_DATA * PCM_DISK_GEOMETRY_DEVICE_DATA
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
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@371 u
#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
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@371::@380 DeviceSpecificData
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:2966

Referenced by EnumerateBiosDiskEntries().

◆ DiskIdentifierQueryRoutine()

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

Definition at line 395 of file partlist.c.

402 {
403  PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
404  UNICODE_STRING NameU;
405 
406  if (ValueType == REG_SZ &&
407  ValueLength == 20 * sizeof(WCHAR) &&
408  ((PWCHAR)ValueData)[8] == L'-')
409  {
410  NameU.Buffer = (PWCHAR)ValueData;
411  NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR);
412  RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum);
413 
414  NameU.Buffer = (PWCHAR)ValueData + 9;
415  RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature);
416 
417  return STATUS_SUCCESS;
418  }
419 
420  return STATUS_UNSUCCESSFUL;
421 }
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:4016
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:2966
#define REG_SZ
Definition: layer.c:22

Referenced by EnumerateBiosDiskEntries().

◆ DismountVolume()

NTSTATUS DismountVolume ( IN PPARTENTRY  PartEntry)

Definition at line 3113 of file partlist.c.

3115 {
3116  NTSTATUS Status;
3117  NTSTATUS LockStatus;
3121  HANDLE PartitionHandle;
3123 
3124  /* Check whether the partition is valid and was mounted by the system */
3125  if (!PartEntry->IsPartitioned ||
3126  IsContainerPartition(PartEntry->PartitionType) ||
3127  !IsRecognizedPartition(PartEntry->PartitionType) ||
3128  PartEntry->FormatState == UnknownFormat ||
3129  // NOTE: If FormatState == Unformatted but *FileSystem != 0 this means
3130  // it has been usually mounted with RawFS and thus needs to be dismounted.
3131  !*PartEntry->FileSystem ||
3132  PartEntry->PartitionNumber == 0)
3133  {
3134  /* The partition is not mounted, so just return success */
3135  return STATUS_SUCCESS;
3136  }
3137 
3138  ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
3139 
3140  /* Open the volume */
3142  L"\\Device\\Harddisk%lu\\Partition%lu",
3143  PartEntry->DiskEntry->DiskNumber,
3144  PartEntry->PartitionNumber);
3146 
3148  &Name,
3150  NULL,
3151  NULL);
3152 
3153  Status = NtOpenFile(&PartitionHandle,
3156  &IoStatusBlock,
3159  if (!NT_SUCCESS(Status))
3160  {
3161  DPRINT1("ERROR: Cannot open volume %wZ for dismounting! (Status 0x%lx)\n", &Name, Status);
3162  return Status;
3163  }
3164 
3165  /* Lock the volume */
3166  LockStatus = NtFsControlFile(PartitionHandle,
3167  NULL,
3168  NULL,
3169  NULL,
3170  &IoStatusBlock,
3172  NULL,
3173  0,
3174  NULL,
3175  0);
3176  if (!NT_SUCCESS(LockStatus))
3177  {
3178  DPRINT1("WARNING: Failed to lock volume! Operations may fail! (Status 0x%lx)\n", LockStatus);
3179  }
3180 
3181  /* Dismount the volume */
3182  Status = NtFsControlFile(PartitionHandle,
3183  NULL,
3184  NULL,
3185  NULL,
3186  &IoStatusBlock,
3188  NULL,
3189  0,
3190  NULL,
3191  0);
3192  if (!NT_SUCCESS(Status))
3193  {
3194  DPRINT1("Failed to unmount volume (Status 0x%lx)\n", Status);
3195  }
3196 
3197  /* Unlock the volume */
3198  LockStatus = NtFsControlFile(PartitionHandle,
3199  NULL,
3200  NULL,
3201  NULL,
3202  &IoStatusBlock,
3204  NULL,
3205  0,
3206  NULL,
3207  0);
3208  if (!NT_SUCCESS(LockStatus))
3209  {
3210  DPRINT1("Failed to unlock volume (Status 0x%lx)\n", LockStatus);
3211  }
3212 
3213  /* Close the volume */
3214  NtClose(PartitionHandle);
3215 
3216  return Status;
3217 }
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:245
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:271
#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:2966

Referenced by AddPartitionToDisk(), and DeletePartition().

◆ EnumerateBiosDiskEntries()

static VOID EnumerateBiosDiskEntries ( IN PPARTLIST  PartList)
static

Definition at line 515 of file partlist.c.

517 {
519  WCHAR Name[120];
520  ULONG AdapterCount;
522  ULONG DiskCount;
524  PCM_INT13_DRIVE_PARAMETER Int13Drives;
525  PBIOSDISKENTRY BiosDiskEntry;
526 
527 #define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
528 
529  memset(QueryTable, 0, sizeof(QueryTable));
530 
531  QueryTable[1].Name = L"Configuration Data";
533  Int13Drives = NULL;
535  L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
536  &QueryTable[1],
537  (PVOID)&Int13Drives,
538  NULL);
539  if (!NT_SUCCESS(Status))
540  {
541  DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status);
542  return;
543  }
544 
545  for (AdapterCount = 0; ; ++AdapterCount)
546  {
548  L"%s\\%lu",
549  ROOT_NAME, AdapterCount);
551  Name,
552  &QueryTable[2],
553  NULL,
554  NULL);
555  if (!NT_SUCCESS(Status))
556  {
557  break;
558  }
559 
561  L"%s\\%lu\\DiskController",
562  ROOT_NAME, AdapterCount);
564  Name,
565  &QueryTable[2],
566  NULL,
567  NULL);
568  if (NT_SUCCESS(Status))
569  {
570  for (ControllerCount = 0; ; ++ControllerCount)
571  {
573  L"%s\\%lu\\DiskController\\%lu",
574  ROOT_NAME, AdapterCount, ControllerCount);
576  Name,
577  &QueryTable[2],
578  NULL,
579  NULL);
580  if (!NT_SUCCESS(Status))
581  {
582  RtlFreeHeap(ProcessHeap, 0, Int13Drives);
583  return;
584  }
585 
587  L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral",
588  ROOT_NAME, AdapterCount, ControllerCount);
590  Name,
591  &QueryTable[2],
592  NULL,
593  NULL);
594  if (NT_SUCCESS(Status))
595  {
596  QueryTable[0].Name = L"Identifier";
598  QueryTable[1].Name = L"Configuration Data";
600 
601  for (DiskCount = 0; ; ++DiskCount)
602  {
604  if (BiosDiskEntry == NULL)
605  {
606  RtlFreeHeap(ProcessHeap, 0, Int13Drives);
607  return;
608  }
609 
611  L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral\\%lu",
612  ROOT_NAME, AdapterCount, ControllerCount, DiskCount);
614  Name,
615  QueryTable,
616  (PVOID)BiosDiskEntry,
617  NULL);
618  if (!NT_SUCCESS(Status))
619  {
620  RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
621  RtlFreeHeap(ProcessHeap, 0, Int13Drives);
622  return;
623  }
624 
625  BiosDiskEntry->AdapterNumber = 0; // And NOT "AdapterCount" as it needs to be hardcoded for BIOS!
626  BiosDiskEntry->ControllerNumber = ControllerCount;
627  BiosDiskEntry->DiskNumber = DiskCount;
628  BiosDiskEntry->DiskEntry = NULL;
629 
630  if (DiskCount < Int13Drives[0].NumberDrives)
631  {
632  BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount];
633  }
634  else
635  {
636  DPRINT1("Didn't find Int13 drive data for disk %u\n", DiskCount);
637  }
638 
639  InsertTailList(&PartList->BiosDiskListHead, &BiosDiskEntry->ListEntry);
640 
641  DPRINT("--->\n");
642  DPRINT("AdapterNumber: %lu\n", BiosDiskEntry->AdapterNumber);
643  DPRINT("ControllerNumber: %lu\n", BiosDiskEntry->ControllerNumber);
644  DPRINT("DiskNumber: %lu\n", BiosDiskEntry->DiskNumber);
645  DPRINT("Signature: %08lx\n", BiosDiskEntry->Signature);
646  DPRINT("Checksum: %08lx\n", BiosDiskEntry->Checksum);
647  DPRINT("BytesPerSector: %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector);
648  DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders);
649  DPRINT("NumberOfHeads: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads);
650  DPRINT("DriveSelect: %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect);
651  DPRINT("MaxCylinders: %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders);
652  DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack);
653  DPRINT("MaxHeads: %d\n", BiosDiskEntry->Int13DiskData.MaxHeads);
654  DPRINT("NumberDrives: %d\n", BiosDiskEntry->Int13DiskData.NumberDrives);
655  DPRINT("<---\n");
656  }
657  }
658  }
659  }
660  }
661 
662  RtlFreeHeap(ProcessHeap, 0, Int13Drives);
663 
664 #undef ROOT_NAME
665 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4004
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:468
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:425
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:395
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:2604
BOOLEAN IsSuperFloppy(IN PDISKENTRY DiskEntry)
Definition: partlist.c:679
#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 3433 of file partlist.c.

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

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

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

◆ GetDiskByBiosNumber()

PDISKENTRY GetDiskByBiosNumber ( IN PPARTLIST  List,
IN ULONG  HwDiskNumber 
)

Definition at line 2164 of file partlist.c.

2167 {
2168  PDISKENTRY DiskEntry;
2170 
2171  /* Loop over the disks and find the correct one */
2172  for (Entry = List->DiskListHead.Flink;
2173  Entry != &List->DiskListHead;
2174  Entry = Entry->Flink)
2175  {
2176  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2177 
2178  if (DiskEntry->HwDiskNumber == HwDiskNumber)
2179  {
2180  /* Disk found */
2181  return DiskEntry;
2182  }
2183  }
2184 
2185  /* Disk not found, stop there */
2186  return NULL;
2187 }
struct _Entry Entry
Definition: kefuncs.h:640
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 2190 of file partlist.c.

2193 {
2194  PDISKENTRY DiskEntry;
2196 
2197  /* Loop over the disks and find the correct one */
2198  for (Entry = List->DiskListHead.Flink;
2199  Entry != &List->DiskListHead;
2200  Entry = Entry->Flink)
2201  {
2202  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2203 
2204  if (DiskEntry->DiskNumber == DiskNumber)
2205  {
2206  /* Disk found */
2207  return DiskEntry;
2208  }
2209  }
2210 
2211  /* Disk not found, stop there */
2212  return NULL;
2213 }
struct _Entry Entry
Definition: kefuncs.h:640
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 2216 of file partlist.c.

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

2249 {
2250  PDISKENTRY DiskEntry;
2252 
2253  /* Loop over the disks and find the correct one */
2254  for (Entry = List->DiskListHead.Flink;
2255  Entry != &List->DiskListHead;
2256  Entry = Entry->Flink)
2257  {
2258  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2259 
2260  if (DiskEntry->LayoutBuffer->Signature == Signature)
2261  {
2262  /* Disk found */
2263  return DiskEntry;
2264  }
2265  }
2266 
2267  /* Disk not found, stop there */
2268  return NULL;
2269 }
struct _Entry Entry
Definition: kefuncs.h:640
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 2319 of file partlist.c.

2325 {
2326  PDISKENTRY DiskEntry;
2327  PPARTENTRY PartEntry = NULL;
2328 
2329  /* Find the disk */
2330  DiskEntry = GetDiskByNumber(List, DiskNumber);
2331  if (!DiskEntry)
2332  return FALSE;
2333 
2334  /* If we have a partition (PartitionNumber != 0), find it */
2335  if (PartitionNumber != 0)
2336  {
2337  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2338  {
2339  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2340  return FALSE;
2341  }
2342 
2343  PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
2344  if (!PartEntry)
2345  return FALSE;
2346  ASSERT(PartEntry->DiskEntry == DiskEntry);
2347  }
2348 
2349  /* Return the disk (and optionally the partition) */
2350  *pDiskEntry = DiskEntry;
2351  if (pPartEntry) *pPartEntry = PartEntry;
2352  return TRUE;
2353 }
#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:2272
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:2190
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 283 of file partlist.c.

285 {
287  WCHAR KeyName[32];
289 
290  RtlInitUnicodeString(&DiskEntry->DriverName, NULL);
291 
293  L"\\Scsi\\Scsi Port %hu",
294  DiskEntry->Port);
295 
297 
298  QueryTable[0].Name = L"Driver";
300  QueryTable[0].EntryContext = &DiskEntry->DriverName;
301 
302  /* This will allocate DiskEntry->DriverName if needed */
304  KeyName,
305  QueryTable,
306  NULL,
307  NULL);
308  if (!NT_SUCCESS(Status))
309  {
310  DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
311  }
312 }
_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:4004
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 2631 of file partlist.c.

2633 {
2634  PLIST_ENTRY ListEntry;
2635  PPARTENTRY PartEntry;
2636  ULONG Count = 0;
2637 
2638  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2639  {
2640  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2641  return 0;
2642  }
2643 
2644  for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
2645  ListEntry != &DiskEntry->LogicalPartListHead;
2646  ListEntry = ListEntry->Flink)
2647  {
2648  PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
2649  if (PartEntry->IsPartitioned)
2650  Count++;
2651  }
2652 
2653  return Count;
2654 }
_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 2383 of file partlist.c.

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

2927 {
2928  PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2929  PPARTENTRY NextPartEntry;
2930  PLIST_ENTRY ListHead;
2931 
2932  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2933  {
2934  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2935  return NULL;
2936  }
2937 
2938  if (PartEntry->LogicalPartition)
2939  ListHead = &DiskEntry->LogicalPartListHead;
2940  else
2941  ListHead = &DiskEntry->PrimaryPartListHead;
2942 
2943  if (PartEntry->ListEntry.Flink != ListHead)
2944  {
2945  NextPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Flink,
2946  PARTENTRY,
2947  ListEntry);
2948  if (!NextPartEntry->IsPartitioned)
2949  {
2950  ASSERT(NextPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
2951  return NextPartEntry;
2952  }
2953  }
2954 
2955  return NULL;
2956 }
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 2272 of file partlist.c.

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

2478 {
2479  PLIST_ENTRY DiskListEntry;
2480  PLIST_ENTRY PartListEntry;
2482 
2483  /* Fail if no disks are available */
2484  if (IsListEmpty(&List->DiskListHead))
2485  return NULL;
2486 
2487  /* Check for the previous usable entry on the current partition's disk */
2488  if (CurrentPart != NULL)
2489  {
2490  CurrentDisk = CurrentPart->DiskEntry;
2491 
2492  if (CurrentPart->LogicalPartition)
2493  {
2494  /* Logical partition */
2495 
2496  PartListEntry = CurrentPart->ListEntry.Blink;
2497  if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2498  {
2499  /* Previous logical partition */
2500  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2501  }
2502  else
2503  {
2504  /* Extended partition */
2505  CurrentPart = CurrentDisk->ExtendedPartition;
2506  }
2507  return CurrentPart;
2508  }
2509  else
2510  {
2511  /* Primary or extended partition */
2512 
2513  PartListEntry = CurrentPart->ListEntry.Blink;
2514  if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2515  {
2516  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2517 
2518  if (CurrentPart->IsPartitioned &&
2519  IsContainerPartition(CurrentPart->PartitionType))
2520  {
2521  PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2522  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2523  }
2524 
2525  return CurrentPart;
2526  }
2527  }
2528  }
2529 
2530  /* Search for the last partition entry on the previous disk */
2531  for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Blink
2532  : List->DiskListHead.Blink);
2533  DiskListEntry != &List->DiskListHead;
2534  DiskListEntry = DiskListEntry->Blink)
2535  {
2536  CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
2537 
2539  {
2540  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2541  continue;
2542  }
2543 
2544  PartListEntry = CurrentDisk->PrimaryPartListHead.Blink;
2545  if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2546  {
2547  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2548 
2549  if (CurrentPart->IsPartitioned &&
2550  IsContainerPartition(CurrentPart->PartitionType))
2551  {
2552  PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2553  if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2554  {
2555  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2556  return CurrentPart;
2557  }
2558  }
2559  else
2560  {
2561  return CurrentPart;
2562  }
2563  }
2564  }
2565 
2566  return NULL;
2567 }
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:245
_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 2890 of file partlist.c.

2892 {
2893  PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2894  PPARTENTRY PrevPartEntry;
2895  PLIST_ENTRY ListHead;
2896 
2897  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2898  {
2899  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2900  return NULL;
2901  }
2902 
2903  if (PartEntry->LogicalPartition)
2904  ListHead = &DiskEntry->LogicalPartListHead;
2905  else
2906  ListHead = &DiskEntry->PrimaryPartListHead;
2907 
2908  if (PartEntry->ListEntry.Blink != ListHead)
2909  {
2910  PrevPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Blink,
2911  PARTENTRY,
2912  ListEntry);
2913  if (!PrevPartEntry->IsPartitioned)
2914  {
2915  ASSERT(PrevPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
2916  return PrevPartEntry;
2917  }
2918  }
2919 
2920  return NULL;
2921 }
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 2604 of file partlist.c.

2606 {
2608  PPARTENTRY PartEntry;
2609  ULONG Count = 0;
2610 
2611  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2612  {
2613  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2614  return 0;
2615  }
2616 
2617  for (Entry = DiskEntry->PrimaryPartListHead.Flink;
2618  Entry != &DiskEntry->PrimaryPartListHead;
2619  Entry = Entry->Flink)
2620  {
2621  PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2622  if (PartEntry->IsPartitioned)
2623  Count++;
2624  }
2625 
2626  return Count;
2627 }
struct _Entry Entry
Definition: kefuncs.h:640
_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 1894 of file partlist.c.

1896 {
1898  PDISKENTRY DiskEntry;
1899 
1900  /* Check for empty disk list */
1901  if (IsListEmpty(&List->DiskListHead))
1902  return NULL;
1903 
1904  /*
1905  * If we already have a system partition, the system disk
1906  * is the one on which the system partition resides.
1907  */
1908  if (List->SystemPartition)
1909  return List->SystemPartition->DiskEntry;
1910 
1911  /* Loop over the disks and find the correct one */
1912  for (Entry = List->DiskListHead.Flink;
1913  Entry != &List->DiskListHead;
1914  Entry = Entry->Flink)
1915  {
1916  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
1917 
1918  /* The disk must be a fixed disk and be found by the firmware */
1919  if (DiskEntry->MediaType == FixedMedia && DiskEntry->BiosFound)
1920  {
1921  break;
1922  }
1923  }
1924  if (Entry == &List->DiskListHead)
1925  {
1926  /* We haven't encountered any suitable disk */
1927  return NULL;
1928  }
1929 
1930  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1931  {
1932  DPRINT1("System disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
1933  }
1934 
1935  return DiskEntry;
1936 }
struct _Entry Entry
Definition: kefuncs.h:640
_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 856 of file partlist.c.

860 {
861  PDISKENTRY DiskEntry = PartEntry->DiskEntry;
862 
863  DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart);
864 
865  /* Fail if we try to initialize this partition entry with more sectors than what it actually contains */
866  if (SectorCount > PartEntry->SectorCount.QuadPart)
867  return FALSE;
868 
869  /* Fail if the partition is already in use */
870  ASSERT(!PartEntry->IsPartitioned);
871 
872  if ((AutoCreate != FALSE) ||
873  (AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) -
874  PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart))
875  {
876  PartEntry->AutoCreate = AutoCreate;
877  }
878  else
879  {
880  ULONGLONG StartSector;
881  ULONGLONG SectorCount2;
882  PPARTENTRY NewPartEntry;
883 
884  /* Create a partition entry that represents the remaining space after the partition to be initialized */
885 
886  StartSector = AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment);
887  SectorCount2 = PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - StartSector;
888 
889  NewPartEntry = CreateInsertBlankRegion(DiskEntry,
890  PartEntry->ListEntry.Flink,
891  StartSector,
892  SectorCount2,
893  PartEntry->LogicalPartition);
894  if (NewPartEntry == NULL)
895  {
896  DPRINT1("Failed to create a new empty region for disk space!\n");
897  return FALSE;
898  }
899 
900  /* Resize down the partition entry; its StartSector remains the same */
901  PartEntry->SectorCount.QuadPart = StartSector - PartEntry->StartSector.QuadPart;
902  }
903 
904  /* Convert the partition entry to 'New (Unformatted)' */
905  PartEntry->New = TRUE;
906  PartEntry->IsPartitioned = TRUE;
907 
908  PartEntry->PartitionType = FileSystemToPartitionType(L"RAW", &PartEntry->StartSector, &PartEntry->SectorCount);
909  ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
910 
911  PartEntry->FormatState = Unformatted;
912  PartEntry->FileSystem[0] = L'\0';
913  // PartEntry->AutoCreate = AutoCreate;
914  PartEntry->BootIndicator = FALSE;
915 
916  DPRINT1("First Sector : %I64u\n", PartEntry->StartSector.QuadPart);
917  DPRINT1("Last Sector : %I64u\n", PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1);
918  DPRINT1("Total Sectors: %I64u\n", PartEntry->SectorCount.QuadPart);
919 
920  return TRUE;
921 }
#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:818
uint64_t ULONGLONG
Definition: typedefs.h:65
ULONGLONG AlignDown(IN ULONGLONG Value, IN ULONG Alignment)
Definition: partlist.c:245
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static const WCHAR L[]
Definition: oid.c:1250
ULONG SectorCount
Definition: part_xbox.c:32
#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 752 of file partlist.c.

756 {
759  PPARTENTRY PartEntry2;
760 
761  /* Use the correct partition list */
762  if (LogicalPartition)
763  List = &DiskEntry->LogicalPartListHead;
764  else
765  List = &DiskEntry->PrimaryPartListHead;
766 
767  /* Find the first disk region before which we need to insert the new one */
768  for (Entry = List->Flink; Entry != List; Entry = Entry->Flink)
769  {
770  PartEntry2 = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
771 
772  /* Ignore any unused empty region */
773  if ((PartEntry2->PartitionType == PARTITION_ENTRY_UNUSED &&
774  PartEntry2->StartSector.QuadPart == 0) || PartEntry2->SectorCount.QuadPart == 0)
775  {
776  continue;
777  }
778 
779  /* If the current region ends before the one to be inserted, try again */
780  if (PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1 < PartEntry->StartSector.QuadPart)
781  continue;
782 
783  /*
784  * One of the disk region boundaries crosses the desired region
785  * (it starts after the desired region, or ends before the end
786  * of the desired region): this is an impossible situation because
787  * disk regions (partitions) cannot overlap!
788  * Throw an error and bail out.
789  */
790  if (max(PartEntry->StartSector.QuadPart, PartEntry2->StartSector.QuadPart)
791  <=
792  min( PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1,
793  PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1))
794  {
795  DPRINT1("Disk region overlap problem, stopping there!\n"
796  "Partition to be inserted:\n"
797  " StartSector = %I64u ; EndSector = %I64u\n"
798  "Existing disk region:\n"
799  " StartSector = %I64u ; EndSector = %I64u\n",
800  PartEntry->StartSector.QuadPart,
801  PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1,
802  PartEntry2->StartSector.QuadPart,
803  PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1);
804  return FALSE;
805  }
806 
807  /* We have found the first region before which the new one has to be inserted */
808  break;
809  }
810 
811  /* Insert the disk region */
812  InsertTailList(Entry, &PartEntry->ListEntry);
813  return TRUE;
814 }
#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:640
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 2572 of file partlist.c.

2574 {
2575  if (PartitionInfo->StartingOffset.QuadPart == 0 &&
2576  PartitionInfo->PartitionLength.QuadPart == 0)
2577  {
2578  return TRUE;
2579  }
2580 
2581  return FALSE;
2582 }
#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 1944 of file partlist.c.

1946 {
1947  // TODO: Support for GPT disks!
1948 
1949  if (IsContainerPartition(PartEntry->PartitionType))
1950  return FALSE;
1951 
1952  /* Check if the partition is partitioned, used and active */
1953  if (PartEntry->IsPartitioned &&
1954  // !IsContainerPartition(PartEntry->PartitionType) &&
1955  PartEntry->BootIndicator)
1956  {
1957  /* Yes it is */
1958  ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
1959  return TRUE;
1960  }
1961 
1962  return FALSE;
1963 }
#define TRUE
Definition: types.h:120
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:245
#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 2587 of file partlist.c.

2591 {
2592  if (PartitionInfo->StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector &&
2593  PartitionInfo->PartitionLength.QuadPart == PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector)
2594 // PartitionInfo->PartitionType == PartEntry->PartitionType
2595  {
2596  return TRUE;
2597  }
2598 
2599  return FALSE;
2600 }
#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 679 of file partlist.c.

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

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