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

Go to the source code of this file.

Classes

struct  _REG_DISK_MOUNT_INFO
 

Macros

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

Typedefs

typedef struct _REG_DISK_MOUNT_INFO REG_DISK_MOUNT_INFO
 
typedef struct _REG_DISK_MOUNT_INFOPREG_DISK_MOUNT_INFO
 

Functions

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

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 16 of file partlist.c.

◆ ROOT_NAME

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

Typedef Documentation

◆ PREG_DISK_MOUNT_INFO

◆ REG_DISK_MOUNT_INFO

Function Documentation

◆ AddDiskToList()

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

Definition at line 1306 of file partlist.c.

1310 {
1311  DISK_GEOMETRY DiskGeometry;
1312  SCSI_ADDRESS ScsiAddress;
1313  PDISKENTRY DiskEntry;
1315  NTSTATUS Status;
1316  PPARTITION_SECTOR Mbr;
1317  PULONG Buffer;
1319  WCHAR Identifier[20];
1320  ULONG Checksum;
1321  ULONG Signature;
1322  ULONG i;
1323  PLIST_ENTRY ListEntry;
1324  PBIOSDISKENTRY BiosDiskEntry;
1325  ULONG LayoutBufferSize;
1326  PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
1327 
1328  /* Retrieve the drive geometry */
1330  NULL,
1331  NULL,
1332  NULL,
1333  &Iosb,
1335  NULL,
1336  0,
1337  &DiskGeometry,
1338  sizeof(DiskGeometry));
1339  if (!NT_SUCCESS(Status))
1340  return;
1341 
1342  if (DiskGeometry.MediaType != FixedMedia &&
1343  DiskGeometry.MediaType != RemovableMedia)
1344  {
1345  return;
1346  }
1347 
1348  /*
1349  * FIXME: Here we suppose the disk is always SCSI. What if it is
1350  * of another type? To check this we need to retrieve the name of
1351  * the driver the disk device belongs to.
1352  */
1354  NULL,
1355  NULL,
1356  NULL,
1357  &Iosb,
1359  NULL,
1360  0,
1361  &ScsiAddress,
1362  sizeof(ScsiAddress));
1363  if (!NT_SUCCESS(Status))
1364  return;
1365 
1366  /*
1367  * Check whether the disk is initialized, by looking at its MBR.
1368  * NOTE that this must be generalized to GPT disks as well!
1369  */
1370 
1372  0,
1373  DiskGeometry.BytesPerSector);
1374  if (Mbr == NULL)
1375  return;
1376 
1377  FileOffset.QuadPart = 0;
1379  NULL,
1380  NULL,
1381  NULL,
1382  &Iosb,
1383  (PVOID)Mbr,
1384  DiskGeometry.BytesPerSector,
1385  &FileOffset,
1386  NULL);
1387  if (!NT_SUCCESS(Status))
1388  {
1389  RtlFreeHeap(ProcessHeap, 0, Mbr);
1390  DPRINT1("NtReadFile failed, status=%x\n", Status);
1391  return;
1392  }
1393  Signature = Mbr->Signature;
1394 
1395  /* Calculate the MBR checksum */
1396  Checksum = 0;
1397  Buffer = (PULONG)Mbr;
1398  for (i = 0; i < 128; i++)
1399  {
1400  Checksum += Buffer[i];
1401  }
1402  Checksum = ~Checksum + 1;
1403 
1404  RtlStringCchPrintfW(Identifier, ARRAYSIZE(Identifier),
1405  L"%08x-%08x-%c",
1406  Checksum, Signature,
1407  (Mbr->Magic == PARTITION_MAGIC) ? L'A' : L'X');
1408  DPRINT("Identifier: %S\n", Identifier);
1409 
1410  DiskEntry = RtlAllocateHeap(ProcessHeap,
1412  sizeof(DISKENTRY));
1413  if (DiskEntry == NULL)
1414  {
1415  RtlFreeHeap(ProcessHeap, 0, Mbr);
1416  DPRINT1("Failed to allocate a new disk entry.\n");
1417  return;
1418  }
1419 
1420  DiskEntry->PartList = List;
1421 
1422 #if 0
1423  {
1424  FILE_FS_DEVICE_INFORMATION FileFsDevice;
1425 
1426  /* Query the device for its type */
1428  &Iosb,
1429  &FileFsDevice,
1430  sizeof(FileFsDevice),
1432  if (!NT_SUCCESS(Status))
1433  {
1434  DPRINT1("Couldn't detect device type for disk %lu of identifier '%S'...\n", DiskNumber, Identifier);
1435  }
1436  else
1437  {
1438  DPRINT1("Disk %lu : DeviceType: 0x%08x ; Characteristics: 0x%08x\n", DiskNumber, FileFsDevice.DeviceType, FileFsDevice.Characteristics);
1439  }
1440  }
1441  // NOTE: We may also use NtQueryVolumeInformationFile(FileFsDeviceInformation).
1442 #endif
1443  DiskEntry->MediaType = DiskGeometry.MediaType;
1444  if (DiskEntry->MediaType == RemovableMedia)
1445  {
1446  DPRINT1("Disk %lu of identifier '%S' is removable\n", DiskNumber, Identifier);
1447  }
1448  else // if (DiskEntry->MediaType == FixedMedia)
1449  {
1450  DPRINT1("Disk %lu of identifier '%S' is fixed\n", DiskNumber, Identifier);
1451  }
1452 
1453 // DiskEntry->Checksum = Checksum;
1454 // DiskEntry->Signature = Signature;
1455  DiskEntry->BiosFound = FALSE;
1456 
1457  /*
1458  * Check if this disk has a valid MBR: verify its signature,
1459  * and whether its two first bytes are a valid instruction
1460  * (related to this, see IsThereAValidBootSector() in partlist.c).
1461  *
1462  * See also ntoskrnl/fstub/fstubex.c!FstubDetectPartitionStyle().
1463  */
1464 
1465  // DiskEntry->NoMbr = (Mbr->Magic != PARTITION_MAGIC || (*(PUSHORT)Mbr->BootCode) == 0x0000);
1466 
1467  /* If we have not the 0xAA55 then it's raw partition */
1468  if (Mbr->Magic != PARTITION_MAGIC)
1469  {
1470  DiskEntry->DiskStyle = PARTITION_STYLE_RAW;
1471  }
1472  /* Check partitions types: if first is 0xEE and all the others 0, we have GPT */
1473  else if (Mbr->Partition[0].PartitionType == EFI_PMBR_OSTYPE_EFI &&
1474  Mbr->Partition[1].PartitionType == 0 &&
1475  Mbr->Partition[2].PartitionType == 0 &&
1476  Mbr->Partition[3].PartitionType == 0)
1477  {
1478  DiskEntry->DiskStyle = PARTITION_STYLE_GPT;
1479  }
1480  /* Otherwise, partition table is in MBR */
1481  else
1482  {
1483  DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
1484  }
1485 
1486  /* Free the MBR sector buffer */
1487  RtlFreeHeap(ProcessHeap, 0, Mbr);
1488 
1489 
1490  for (ListEntry = List->BiosDiskListHead.Flink;
1491  ListEntry != &List->BiosDiskListHead;
1492  ListEntry = ListEntry->Flink)
1493  {
1494  BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
1495  /* FIXME:
1496  * Compare the size from bios and the reported size from driver.
1497  * If we have more than one disk with a zero or with the same signature
1498  * we must create new signatures and reboot. After the reboot,
1499  * it is possible to identify the disks.
1500  */
1501  if (BiosDiskEntry->Signature == Signature &&
1502  BiosDiskEntry->Checksum == Checksum &&
1503  BiosDiskEntry->DiskEntry == NULL)
1504  {
1505  if (!DiskEntry->BiosFound)
1506  {
1507  DiskEntry->HwAdapterNumber = BiosDiskEntry->AdapterNumber;
1508  DiskEntry->HwControllerNumber = BiosDiskEntry->ControllerNumber;
1509  DiskEntry->HwDiskNumber = BiosDiskEntry->DiskNumber;
1510 
1511  if (DiskEntry->MediaType == RemovableMedia)
1512  {
1513  /* Set the removable disk number to zero */
1514  DiskEntry->HwFixedDiskNumber = 0;
1515  }
1516  else // if (DiskEntry->MediaType == FixedMedia)
1517  {
1518  /* The fixed disk number will later be adjusted using the number of removable disks */
1519  DiskEntry->HwFixedDiskNumber = BiosDiskEntry->DiskNumber;
1520  }
1521 
1522  DiskEntry->BiosFound = TRUE;
1523  BiosDiskEntry->DiskEntry = DiskEntry;
1524  break;
1525  }
1526  else
1527  {
1528  // FIXME: What to do?
1529  DPRINT1("Disk %lu of identifier '%S' has already been found?!\n", DiskNumber, Identifier);
1530  }
1531  }
1532  }
1533 
1534  if (!DiskEntry->BiosFound)
1535  {
1536  DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %lu may not be bootable by the BIOS!\n", DiskNumber);
1537  }
1538 
1539  DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
1540  DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
1541  DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
1542  DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
1543 
1544  DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders);
1545  DPRINT("TracksPerCylinder %lu\n", DiskEntry->TracksPerCylinder);
1546  DPRINT("SectorsPerTrack %lu\n", DiskEntry->SectorsPerTrack);
1547  DPRINT("BytesPerSector %lu\n", DiskEntry->BytesPerSector);
1548 
1549  DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart *
1550  (ULONGLONG)DiskGeometry.TracksPerCylinder *
1551  (ULONGLONG)DiskGeometry.SectorsPerTrack;
1552 
1553  DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
1554  DiskEntry->CylinderAlignment = DiskGeometry.TracksPerCylinder *
1555  DiskGeometry.SectorsPerTrack;
1556 
1557  DPRINT("SectorCount %I64u\n", DiskEntry->SectorCount.QuadPart);
1558  DPRINT("SectorAlignment %lu\n", DiskEntry->SectorAlignment);
1559 
1560  DiskEntry->DiskNumber = DiskNumber;
1561  DiskEntry->Port = ScsiAddress.PortNumber;
1562  DiskEntry->Bus = ScsiAddress.PathId;
1563  DiskEntry->Id = ScsiAddress.TargetId;
1564 
1565  GetDriverName(DiskEntry);
1566  /*
1567  * Actually it would be more correct somehow to use:
1568  *
1569  * OBJECT_NAME_INFORMATION NameInfo; // ObjectNameInfo;
1570  * ULONG ReturnedLength;
1571  *
1572  * Status = NtQueryObject(SomeHandleToTheDisk,
1573  * ObjectNameInformation,
1574  * &NameInfo,
1575  * sizeof(NameInfo),
1576  * &ReturnedLength);
1577  * etc...
1578  *
1579  * See examples in https://git.reactos.org/?p=reactos.git;a=blob;f=reactos/ntoskrnl/io/iomgr/error.c;hb=2f3a93ee9cec8322a86bf74b356f1ad83fc912dc#l267
1580  */
1581 
1584 
1585  InsertAscendingList(&List->DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber);
1586 
1587 
1588  /*
1589  * We now retrieve the disk partition layout
1590  */
1591 
1592  /*
1593  * Stop there now if the disk is GPT-partitioned,
1594  * since we currently do not support such disks.
1595  */
1596  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1597  {
1598  DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1599  return;
1600  }
1601 
1602  /* Allocate a layout buffer with 4 partition entries first */
1603  LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
1604  ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
1607  LayoutBufferSize);
1608  if (DiskEntry->LayoutBuffer == NULL)
1609  {
1610  DPRINT1("Failed to allocate the disk layout buffer!\n");
1611  return;
1612  }
1613 
1614  /* Keep looping while the drive layout buffer is too small */
1615  for (;;)
1616  {
1617  DPRINT1("Buffer size: %lu\n", LayoutBufferSize);
1619  NULL,
1620  NULL,
1621  NULL,
1622  &Iosb,
1624  NULL,
1625  0,
1626  DiskEntry->LayoutBuffer,
1627  LayoutBufferSize);
1628  if (NT_SUCCESS(Status))
1629  break;
1630 
1632  {
1633  DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status);
1634  return;
1635  }
1636 
1637  LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION);
1638  NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap,
1640  DiskEntry->LayoutBuffer,
1641  LayoutBufferSize);
1642  if (NewLayoutBuffer == NULL)
1643  {
1644  DPRINT1("Failed to reallocate the disk layout buffer!\n");
1645  return;
1646  }
1647 
1648  DiskEntry->LayoutBuffer = NewLayoutBuffer;
1649  }
1650 
1651  DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount);
1652 
1653 #ifdef DUMP_PARTITION_TABLE
1654  DumpPartitionTable(DiskEntry);
1655 #endif
1656 
1657  if (IsSuperFloppy(DiskEntry))
1658  DPRINT1("Disk %lu is a super-floppy\n", DiskNumber);
1659 
1660  if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
1661  DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0 &&
1663  {
1664  if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
1665  {
1666  DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
1667  }
1668  else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
1669  {
1670  DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1671  }
1672  else
1673  {
1674  DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
1675  }
1676  }
1677  else
1678  {
1679  DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1680  }
1681 
1682  if (DiskEntry->LayoutBuffer->PartitionCount == 0)
1683  {
1684  DiskEntry->NewDisk = TRUE;
1685  DiskEntry->LayoutBuffer->PartitionCount = 4;
1686 
1687  for (i = 0; i < 4; i++)
1688  {
1690  }
1691  }
1692  else
1693  {
1694  /* Enumerate and add the first four primary partitions */
1695  for (i = 0; i < 4; i++)
1696  {
1697  AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
1698  }
1699 
1700  /* Enumerate and add the remaining partitions as logical ones */
1701  for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
1702  {
1703  AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
1704  }
1705  }
1706 
1707  ScanForUnpartitionedDiskSpace(DiskEntry);
1708 }
UCHAR PathId
Definition: scsi_port.h:149
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:131
struct _PARTLIST * PartList
Definition: partlist.h:86
UCHAR PortNumber
Definition: scsi_port.h:148
USHORT Id
Definition: partlist.h:115
LARGE_INTEGER PartitionLength
Definition: ntdddisk.h:414
#define IOCTL_SCSI_GET_ADDRESS
Definition: scsi_port.h:52
ULONG HwControllerNumber
Definition: partlist.h:104
ULONG CylinderAlignment
Definition: partlist.h:99
#define ANYSIZE_ARRAY
Definition: typedefs.h:46
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define TRUE
Definition: types.h:120
USHORT Bus
Definition: partlist.h:114
ULONG HwAdapterNumber
Definition: partlist.h:103
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:146
ULONG Signature
Definition: partlist.h:145
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:143
ULONG DiskNumber
Definition: partlist.h:111
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
ULONG BytesPerSector
Definition: ntdddisk.h:409
ULONG TracksPerCylinder
Definition: ntdddisk.h:407
NTSYSAPI NTSTATUS NTAPI NtDeviceIoControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
struct _PARTITION_INFORMATION PARTITION_INFORMATION
UCHAR TargetId
Definition: scsi_port.h:150
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
HANDLE FileHandle
Definition: stats.c:38
static VOID GetDriverName(IN PDISKENTRY DiskEntry)
Definition: partlist.c:105
PARTITION_STYLE DiskStyle
Definition: partlist.h:121
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define FALSE
Definition: types.h:117
struct _DRIVE_LAYOUT_INFORMATION DRIVE_LAYOUT_INFORMATION
PARTITION_INFORMATION PartitionEntry[1]
Definition: ntdddisk.h:426
Definition: bufpool.h:45
MEDIA_TYPE MediaType
Definition: partlist.h:88
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:97
ULONG SectorAlignment
Definition: partlist.h:98
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
ULONG AdapterNumber
Definition: partlist.h:142
BOOLEAN BiosFound
Definition: partlist.h:102
ULONG BytesPerSector
Definition: partlist.h:95
#define EFI_PMBR_OSTYPE_EFI
Definition: partlist.h:175
__wchar_t WCHAR
Definition: xmlstorage.h:180
return Iosb
Definition: create.c:4402
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:413
uint64_t ULONGLONG
Definition: typedefs.h:67
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:405
ULONG SectorsPerTrack
Definition: ntdddisk.h:408
MEDIA_TYPE MediaType
Definition: ntdddisk.h:406
ULONG HwDiskNumber
Definition: partlist.h:105
unsigned char PartitionType
Definition: partlist.h:185
BOOLEAN RewritePartition
Definition: ntdddisk.h:420
static VOID ScanForUnpartitionedDiskSpace(IN PDISKENTRY DiskEntry)
Definition: partlist.c:942
PDISKENTRY DiskEntry
Definition: partlist.h:147
static const WCHAR L[]
Definition: oid.c:1250
ULONG SectorsPerTrack
Definition: partlist.h:94
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
#define InsertAscendingList(ListHead, NewEntry, Type, ListEntryField, SortField)
Definition: partlist.c:17
ULONGLONG Cylinders
Definition: partlist.h:92
HANDLE ProcessHeap
Definition: servman.c:15
#define IOCTL_DISK_GET_DRIVE_LAYOUT
Definition: ntdddisk.h:91
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass)
BOOLEAN IsSuperFloppy(IN PDISKENTRY DiskEntry)
Definition: partlist.c:501
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
ULONG DiskNumber
Definition: partlist.h:144
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
PARTITION Partition[PARTITION_TBL_SIZE]
Definition: partlist.h:198
ULONG HwFixedDiskNumber
Definition: partlist.h:106
USHORT Port
Definition: partlist.h:113
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
ULONG TracksPerCylinder
Definition: partlist.h:93
#define DPRINT1
Definition: precomp.h:8
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:132
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2667
#define DPRINT
Definition: sndvol32.h:71
#define PARTITION_MAGIC
Definition: partlist.h:172
static const WCHAR Signature[]
Definition: parser.c:141
PDRIVE_LAYOUT_INFORMATION LayoutBuffer
Definition: partlist.h:125
BOOLEAN NewDisk
Definition: partlist.h:120
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
NTSTATUS NTAPI NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
LONGLONG QuadPart
Definition: typedefs.h:114
static VOID AddPartitionToDisk(IN ULONG DiskNumber, IN PDISKENTRY DiskEntry, IN ULONG PartitionIndex, IN BOOLEAN LogicalPartition)
Definition: partlist.c:751

Referenced by CreatePartitionList().

◆ AddLogicalDiskSpace()

static VOID AddLogicalDiskSpace ( IN PDISKENTRY  DiskEntry)
static

Definition at line 2823 of file partlist.c.

2825 {
2826  ULONGLONG StartSector;
2828  PPARTENTRY NewPartEntry;
2829 
2830  DPRINT1("AddLogicalDiskSpace()\n");
2831 
2832  /* Create a partition entry that represents the empty space in the container partition */
2833 
2834  StartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
2835  SectorCount = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
2836 
2837  NewPartEntry = CreateInsertBlankRegion(DiskEntry,
2838  &DiskEntry->LogicalPartListHead,
2839  StartSector,
2840  SectorCount,
2841  TRUE);
2842  if (NewPartEntry == NULL)
2843  {
2844  DPRINT1("Failed to create a new empty region for extended partition space!\n");
2845  return;
2846  }
2847 }
#define TRUE
Definition: types.h:120
static PPARTENTRY CreateInsertBlankRegion(IN PDISKENTRY DiskEntry, IN OUT PLIST_ENTRY ListHead, IN ULONGLONG StartSector, IN ULONGLONG SectorCount, IN BOOLEAN LogicalSpace)
Definition: partlist.c:640
uint64_t ULONGLONG
Definition: typedefs.h:67
ULONG SectorCount
Definition: part_xbox.c:31
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8

Referenced by CreateExtendedPartition().

◆ AddPartitionToDisk()

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

Definition at line 751 of file partlist.c.

756 {
759  PPARTENTRY PartEntry;
760  HANDLE PartitionHandle;
763  WCHAR PathBuffer[MAX_PATH];
765  UCHAR LabelBuffer[sizeof(FILE_FS_VOLUME_INFORMATION) + 256 * sizeof(WCHAR)];
767 
768  PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
769 
770  if (PartitionInfo->PartitionType == PARTITION_ENTRY_UNUSED ||
771  ((LogicalPartition != FALSE) && IsContainerPartition(PartitionInfo->PartitionType)))
772  {
773  return;
774  }
775 
776  PartEntry = RtlAllocateHeap(ProcessHeap,
778  sizeof(PARTENTRY));
779  if (PartEntry == NULL)
780  return;
781 
782  PartEntry->DiskEntry = DiskEntry;
783 
784  PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
785  PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
786 
787  PartEntry->BootIndicator = PartitionInfo->BootIndicator;
788  PartEntry->PartitionType = PartitionInfo->PartitionType;
789 
790  PartEntry->LogicalPartition = LogicalPartition;
791  PartEntry->IsPartitioned = TRUE;
792  PartEntry->OnDiskPartitionNumber = PartitionInfo->PartitionNumber;
793  PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
794  PartEntry->PartitionIndex = PartitionIndex;
795 
796  /* Specify the partition as initially unformatted */
797  PartEntry->FormatState = Unformatted;
798  PartEntry->FileSystem[0] = L'\0';
799 
800  /* Initialize the partition volume label */
801  RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
802 
803  if (IsContainerPartition(PartEntry->PartitionType))
804  {
805  PartEntry->FormatState = Unformatted;
806 
807  if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
808  DiskEntry->ExtendedPartition = PartEntry;
809  }
810  else if (IsRecognizedPartition(PartEntry->PartitionType))
811  {
812  ASSERT(PartitionInfo->RecognizedPartition);
813  ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
814 
815  /* Try to open the volume so as to mount it */
816  RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
817  L"\\Device\\Harddisk%lu\\Partition%lu",
818  DiskEntry->DiskNumber,
819  PartEntry->PartitionNumber);
820  RtlInitUnicodeString(&Name, PathBuffer);
821 
823  &Name,
825  NULL,
826  NULL);
827 
828  PartitionHandle = NULL;
829  Status = NtOpenFile(&PartitionHandle,
832  &IoStatusBlock,
835  if (!NT_SUCCESS(Status))
836  {
837  DPRINT1("NtOpenFile() failed, Status 0x%08lx\n", Status);
838  }
839 
840  if (PartitionHandle)
841  {
843 
844  /* We don't have a FS, try to guess one */
845  Status = InferFileSystem(NULL, PartitionHandle,
846  PartEntry->FileSystem,
847  sizeof(PartEntry->FileSystem));
848  if (!NT_SUCCESS(Status))
849  DPRINT1("InferFileSystem() failed, Status 0x%08lx\n", Status);
850  }
851  if (*PartEntry->FileSystem)
852  {
853  ASSERT(PartitionHandle);
854 
855  /*
856  * Handle partition mounted with RawFS: it is
857  * either unformatted or has an unknown format.
858  */
859  if (wcsicmp(PartEntry->FileSystem, L"RAW") == 0)
860  {
861  /*
862  * True unformatted partitions on NT are created with their
863  * partition type set to either one of the following values,
864  * and are mounted with RawFS. This is done this way since we
865  * are assured to have FAT support, which is the only FS that
866  * uses these partition types. Therefore, having a partition
867  * mounted with RawFS and with these partition types means that
868  * the FAT FS was unable to mount it beforehand and thus the
869  * partition is unformatted.
870  * However, any partition mounted by RawFS that does NOT have
871  * any of these partition types must be considered as having
872  * an unknown format.
873  */
874  if (PartEntry->PartitionType == PARTITION_FAT_12 ||
875  PartEntry->PartitionType == PARTITION_FAT_16 ||
876  PartEntry->PartitionType == PARTITION_HUGE ||
877  PartEntry->PartitionType == PARTITION_XINT13 ||
878  PartEntry->PartitionType == PARTITION_FAT32 ||
880  {
881  PartEntry->FormatState = Unformatted;
882  }
883  else
884  {
885  /* Close the partition before dismounting */
886  NtClose(PartitionHandle);
887  PartitionHandle = NULL;
888  /*
889  * Dismount the partition since RawFS owns it, and set its
890  * format to unknown (may or may not be actually formatted).
891  */
892  DismountVolume(PartEntry);
893  PartEntry->FormatState = UnknownFormat;
894  PartEntry->FileSystem[0] = L'\0';
895  }
896  }
897  else
898  {
899  PartEntry->FormatState = Preformatted;
900  }
901  }
902  else
903  {
904  PartEntry->FormatState = UnknownFormat;
905  }
906 
907  /* Retrieve the partition volume label */
908  if (PartitionHandle)
909  {
910  Status = NtQueryVolumeInformationFile(PartitionHandle,
911  &IoStatusBlock,
912  &LabelBuffer,
913  sizeof(LabelBuffer),
915  if (NT_SUCCESS(Status))
916  {
917  /* Copy the (possibly truncated) volume label and NULL-terminate it */
918  RtlStringCbCopyNW(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel),
919  LabelInfo->VolumeLabel, LabelInfo->VolumeLabelLength);
920  }
921  else
922  {
923  DPRINT1("NtQueryVolumeInformationFile() failed, Status 0x%08lx\n", Status);
924  }
925  }
926 
927  /* Close the partition */
928  if (PartitionHandle)
929  NtClose(PartitionHandle);
930  }
931  else
932  {
933  /* Unknown partition, hence unknown format (may or may not be actually formatted) */
934  PartEntry->FormatState = UnknownFormat;
935  }
936 
937  InsertDiskRegion(DiskEntry, PartEntry, LogicalPartition);
938 }
#define PARTITION_FAT32
Definition: disk.h:95
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
ULONG PartitionNumber
Definition: partlist.h:55
ULARGE_INTEGER StartSector
Definition: partlist.h:49
WCHAR VolumeLabel[20]
Definition: partlist.h:59
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define TRUE
Definition: types.h:120
ULARGE_INTEGER SectorCount
Definition: partlist.h:50
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:316
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
NTSTATUS InferFileSystem(IN PCWSTR PartitionPath OPTIONAL, IN HANDLE PartitionHandle OPTIONAL, IN OUT PWSTR FileSystemName, IN SIZE_T FileSystemNameSize)
Definition: fsrec.c:269
#define FILE_SHARE_READ
Definition: compat.h:136
#define PARTITION_XINT13
Definition: disk.h:97
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
BOOLEAN LogicalPartition
Definition: partlist.h:63
NTSTATUS DismountVolume(IN PPARTENTRY PartEntry)
Definition: partlist.c:2940
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define FALSE
Definition: types.h:117
FORMATSTATE FormatState
Definition: partlist.h:61
#define PARTITION_HUGE
Definition: disk.h:92
#define FILE_READ_DATA
Definition: nt_native.h:628
NTSTRSAFEAPI RtlStringCbCopyNW(_Out_writes_bytes_(cbDest) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_reads_bytes_(cbToCopy) STRSAFE_LPCWSTR pszSrc, _In_ size_t cbToCopy)
Definition: ntstrsafe.h:416
struct NameRec_ * Name
Definition: cdprocs.h:459
static BOOLEAN InsertDiskRegion(IN PDISKENTRY DiskEntry, IN PPARTENTRY PartEntry, IN BOOLEAN LogicalPartition)
Definition: partlist.c:574
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
struct _FILE_FS_VOLUME_INFORMATION * PFILE_FS_VOLUME_INFORMATION
Status
Definition: gdiplustypes.h:24
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3951
UCHAR PartitionType
Definition: partlist.h:53
struct _DISKENTRY * DiskEntry
Definition: partlist.h:46
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:67
ULONG OnDiskPartitionNumber
Definition: partlist.h:54
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:342
#define MAX_PATH
Definition: compat.h:34
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2105
WCHAR FileSystem[MAX_PATH+1]
Definition: partlist.h:60
#define PARTITION_FAT_16
Definition: disk.h:90
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3398
#define wcsicmp
Definition: compat.h:15
unsigned char UCHAR
Definition: xmlstorage.h:181
static const WCHAR L[]
Definition: oid.c:1250
#define SYNCHRONIZE
Definition: nt_native.h:61
HANDLE ProcessHeap
Definition: servman.c:15
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass)
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define DPRINT1
Definition: precomp.h:8
BOOLEAN BootIndicator
Definition: partlist.h:52
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
struct _FILE_FS_VOLUME_INFORMATION FILE_FS_VOLUME_INFORMATION
#define PARTITION_FAT_12
Definition: disk.h:87
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define PARTITION_FAT32_XINT13
Definition: disk.h:96
BOOLEAN IsPartitioned
Definition: partlist.h:66
ULONG PartitionIndex
Definition: partlist.h:56

Referenced by AddDiskToList().

◆ AlignDown()

ULONGLONG AlignDown ( IN ULONGLONG  Value,
IN ULONG  Alignment 
)

Definition at line 67 of file partlist.c.

70 {
71  ULONGLONG Temp;
72 
73  Temp = Value / Alignment;
74 
75  return Temp * Alignment;
76 }
union Alignment_ Alignment
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by InitializePartitionEntry(), and ScanForUnpartitionedDiskSpace().

◆ AlignUp()

ULONGLONG AlignUp ( IN ULONGLONG  Value,
IN ULONG  Alignment 
)

Definition at line 79 of file partlist.c.

82 {
83  ULONGLONG Temp, Result;
84 
85  Temp = Value / Alignment;
86 
87  Result = Temp * Alignment;
88  if (Value % Alignment)
89  Result += Alignment;
90 
91  return Result;
92 }
union Alignment_ Alignment
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by PeFmtCreateSection().

◆ AssignDriveLetters()

static VOID AssignDriveLetters ( IN PPARTLIST  List)
static

Definition at line 138 of file partlist.c.

140 {
141  PDISKENTRY DiskEntry;
142  PPARTENTRY PartEntry;
143  PLIST_ENTRY Entry1;
144  PLIST_ENTRY Entry2;
145  WCHAR Letter;
146 
147  Letter = L'C';
148 
149  /* Assign drive letters to primary partitions */
150  for (Entry1 = List->DiskListHead.Flink;
151  Entry1 != &List->DiskListHead;
152  Entry1 = Entry1->Flink)
153  {
154  DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
155 
156  for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
157  Entry2 != &DiskEntry->PrimaryPartListHead;
158  Entry2 = Entry2->Flink)
159  {
160  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
161 
162  PartEntry->DriveLetter = 0;
163 
164  if (PartEntry->IsPartitioned &&
165  !IsContainerPartition(PartEntry->PartitionType))
166  {
168 
169  if (IsRecognizedPartition(PartEntry->PartitionType) ||
170  PartEntry->SectorCount.QuadPart != 0LL)
171  {
172  if (Letter <= L'Z')
173  {
174  PartEntry->DriveLetter = Letter;
175  Letter++;
176  }
177  }
178  }
179  }
180  }
181 
182  /* Assign drive letters to logical drives */
183  for (Entry1 = List->DiskListHead.Flink;
184  Entry1 != &List->DiskListHead;
185  Entry1 = Entry1->Flink)
186  {
187  DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
188 
189  for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
190  Entry2 != &DiskEntry->LogicalPartListHead;
191  Entry2 = Entry2->Flink)
192  {
193  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
194 
195  PartEntry->DriveLetter = 0;
196 
197  if (PartEntry->IsPartitioned)
198  {
200 
201  if (IsRecognizedPartition(PartEntry->PartitionType) ||
202  PartEntry->SectorCount.QuadPart != 0LL)
203  {
204  if (Letter <= L'Z')
205  {
206  PartEntry->DriveLetter = Letter;
207  Letter++;
208  }
209  }
210  }
211  }
212  }
213 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:131
WCHAR DriveLetter
Definition: partlist.h:58
#define LL
Definition: tui.h:84
ULARGE_INTEGER SectorCount
Definition: partlist.h:50
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:316
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
UCHAR PartitionType
Definition: partlist.h:53
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:342
static const WCHAR L[]
Definition: oid.c:1250
WCHAR Letter
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:132
BOOLEAN IsPartitioned
Definition: partlist.h:66

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

◆ CreateExtendedPartition()

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

Definition at line 2850 of file partlist.c.

2854 {
2856 
2857  DPRINT1("CreateExtendedPartition(%I64u)\n", SectorCount);
2858 
2859  if (List == NULL || PartEntry == NULL ||
2860  PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
2861  {
2862  return FALSE;
2863  }
2864 
2866  if (Error != NOT_AN_ERROR)
2867  {
2868  DPRINT1("ExtendedPartitionCreationChecks() failed with error %lu\n", Error);
2869  return FALSE;
2870  }
2871 
2872  /* Initialize the partition entry, inserting a new blank region if needed */
2873  if (!InitializePartitionEntry(PartEntry, SectorCount, FALSE))
2874  return FALSE;
2875 
2876  ASSERT(PartEntry->LogicalPartition == FALSE);
2877 
2878  if (PartEntry->StartSector.QuadPart < 1450560)
2879  {
2880  /* Partition starts below the 8.4GB boundary ==> CHS partition */
2881  PartEntry->PartitionType = PARTITION_EXTENDED;
2882  }
2883  else
2884  {
2885  /* Partition starts above the 8.4GB boundary ==> LBA partition */
2886  PartEntry->PartitionType = PARTITION_XINT13_EXTENDED;
2887  }
2888 
2889  // FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container)
2890  PartEntry->New = FALSE;
2891  PartEntry->FormatState = Formatted;
2892 
2893  PartEntry->DiskEntry->ExtendedPartition = PartEntry;
2894 
2895  AddLogicalDiskSpace(PartEntry->DiskEntry);
2896 
2897  UpdateDiskLayout(PartEntry->DiskEntry);
2899 
2900  return TRUE;
2901 }
ERROR_NUMBER ExtendedPartitionCreationChecks(IN PPARTENTRY PartEntry)
Definition: partlist.c:3981
#define TRUE
Definition: types.h:120
static BOOLEAN InitializePartitionEntry(IN OUT PPARTENTRY PartEntry, IN ULONGLONG SectorCount, IN BOOLEAN AutoCreate)
Definition: partlist.c:678
#define FALSE
Definition: types.h:117
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2534
#define PARTITION_EXTENDED
Definition: disk.h:91
#define ASSERT(a)
Definition: mode.c:44
BOOL Error
Definition: chkdsk.c:66
enum _ERROR_NUMBER ERROR_NUMBER
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
ULONG SectorCount
Definition: part_xbox.c:31
#define PARTITION_XINT13_EXTENDED
Definition: disk.h:98
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
static VOID AddLogicalDiskSpace(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2823
static VOID AssignDriveLetters(IN PPARTLIST List)
Definition: partlist.c:138

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

646 {
647  PPARTENTRY NewPartEntry;
648 
649  NewPartEntry = RtlAllocateHeap(ProcessHeap,
651  sizeof(PARTENTRY));
652  if (NewPartEntry == NULL)
653  return NULL;
654 
655  NewPartEntry->DiskEntry = DiskEntry;
656 
657  NewPartEntry->StartSector.QuadPart = StartSector;
658  NewPartEntry->SectorCount.QuadPart = SectorCount;
659 
660  NewPartEntry->LogicalPartition = LogicalSpace;
661  NewPartEntry->IsPartitioned = FALSE;
662  NewPartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
663  NewPartEntry->FormatState = Unformatted;
664  NewPartEntry->FileSystem[0] = L'\0';
665 
666  DPRINT1("First Sector : %I64u\n", NewPartEntry->StartSector.QuadPart);
667  DPRINT1("Last Sector : %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
668  DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
669 
670  /* Insert the new entry into the list */
671  InsertTailList(ListHead, &NewPartEntry->ListEntry);
672 
673  return NewPartEntry;
674 }
ULARGE_INTEGER StartSector
Definition: partlist.h:49
ULARGE_INTEGER SectorCount
Definition: partlist.h:50
#define InsertTailList(ListHead, Entry)
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
LIST_ENTRY ListEntry
Definition: partlist.h:43
BOOLEAN LogicalPartition
Definition: partlist.h:63
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define FALSE
Definition: types.h:117
FORMATSTATE FormatState
Definition: partlist.h:61
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
UCHAR PartitionType
Definition: partlist.h:53
struct _DISKENTRY * DiskEntry
Definition: partlist.h:46
WCHAR FileSystem[MAX_PATH+1]
Definition: partlist.h:60
static const WCHAR L[]
Definition: oid.c:1250
ULONG SectorCount
Definition: part_xbox.c:31
HANDLE ProcessHeap
Definition: servman.c:15
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define DPRINT1
Definition: precomp.h:8
BOOLEAN IsPartitioned
Definition: partlist.h:66

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

2909 {
2911 
2912  DPRINT1("CreateLogicalPartition(%I64u)\n", SectorCount);
2913 
2914  if (List == NULL || PartEntry == NULL ||
2915  PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
2916  {
2917  return FALSE;
2918  }
2919 
2921  if (Error != NOT_AN_ERROR)
2922  {
2923  DPRINT1("LogicalPartitionCreationChecks() failed with error %lu\n", Error);
2924  return FALSE;
2925  }
2926 
2927  /* Initialize the partition entry, inserting a new blank region if needed */
2928  if (!InitializePartitionEntry(PartEntry, SectorCount, AutoCreate))
2929  return FALSE;
2930 
2931  ASSERT(PartEntry->LogicalPartition == TRUE);
2932 
2933  UpdateDiskLayout(PartEntry->DiskEntry);
2935 
2936  return TRUE;
2937 }
#define TRUE
Definition: types.h:120
ERROR_NUMBER LogicalPartitionCreationChecks(IN PPARTENTRY PartEntry)
Definition: partlist.c:4012
static BOOLEAN InitializePartitionEntry(IN OUT PPARTENTRY PartEntry, IN ULONGLONG SectorCount, IN BOOLEAN AutoCreate)
Definition: partlist.c:678
#define FALSE
Definition: types.h:117
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2534
#define ASSERT(a)
Definition: mode.c:44
BOOL Error
Definition: chkdsk.c:66
enum _ERROR_NUMBER ERROR_NUMBER
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
ULONG SectorCount
Definition: part_xbox.c:31
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
static VOID AssignDriveLetters(IN PPARTLIST List)
Definition: partlist.c:138

Referenced by CreateLogicalPartitionPage(), and SelectPartitionPage().

◆ CreatePartitionList()

PPARTLIST CreatePartitionList ( VOID  )

Definition at line 1847 of file partlist.c.

1848 {
1849  PPARTLIST List;
1850  PDISKENTRY SystemDisk;
1854  ULONG ReturnSize;
1855  NTSTATUS Status;
1856  ULONG DiskNumber;
1860 
1862  0,
1863  sizeof(PARTLIST));
1864  if (List == NULL)
1865  return NULL;
1866 
1867  List->SystemPartition = NULL;
1868 
1869  InitializeListHead(&List->DiskListHead);
1870  InitializeListHead(&List->BiosDiskListHead);
1871 
1872  /*
1873  * Enumerate the disks seen by the BIOS; this will be used later
1874  * to map drives seen by NTOS with their corresponding BIOS names.
1875  */
1877 
1878  /* Enumerate disks seen by NTOS */
1880  &Sdi,
1881  sizeof(Sdi),
1882  &ReturnSize);
1883  if (!NT_SUCCESS(Status))
1884  {
1885  DPRINT1("NtQuerySystemInformation() failed, Status 0x%08lx", Status);
1887  return NULL;
1888  }
1889 
1890  for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
1891  {
1893  L"\\Device\\Harddisk%lu\\Partition0",
1894  DiskNumber);
1896 
1898  &Name,
1900  NULL,
1901  NULL);
1902 
1906  &Iosb,
1909  if (NT_SUCCESS(Status))
1910  {
1911  AddDiskToList(FileHandle, DiskNumber, List);
1913  }
1914  }
1915 
1919 
1920  /*
1921  * Retrieve the system partition: the active partition on the system
1922  * disk (the one that will be booted by default by the hardware).
1923  */
1924  SystemDisk = GetSystemDisk(List);
1925  List->SystemPartition = (SystemDisk ? GetActiveDiskPartition(SystemDisk) : NULL);
1926 
1927  return List;
1928 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
struct _PARTLIST * PPARTLIST
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static PPARTENTRY GetActiveDiskPartition(IN PDISKENTRY DiskEntry)
Definition: partlist.c:1791
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:1215
#define FILE_SHARE_READ
Definition: compat.h:136
HANDLE FileHandle
Definition: stats.c:38
#define FILE_READ_DATA
Definition: nt_native.h:628
struct NameRec_ * Name
Definition: cdprocs.h:459
Definition: bufpool.h:45
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
Status
Definition: gdiplustypes.h:24
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3951
__wchar_t WCHAR
Definition: xmlstorage.h:180
return Iosb
Definition: create.c:4402
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static VOID UpdateHwDiskNumbers(IN PPARTLIST List)
Definition: partlist.c:1245
#define MAX_PATH
Definition: compat.h:34
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3398
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
static PDISKENTRY GetSystemDisk(IN PPARTLIST List)
Definition: partlist.c:1718
static const WCHAR L[]
Definition: oid.c:1250
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
#define SYNCHRONIZE
Definition: nt_native.h:61
HANDLE ProcessHeap
Definition: servman.c:15
static VOID EnumerateBiosDiskEntries(IN PPARTLIST PartList)
Definition: partlist.c:337
static VOID AddDiskToList(IN HANDLE FileHandle, IN ULONG DiskNumber, IN PPARTLIST List)
Definition: partlist.c:1306
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
static VOID AssignDriveLetters(IN PPARTLIST List)
Definition: partlist.c:138

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

2791 {
2793 
2794  DPRINT1("CreatePrimaryPartition(%I64u)\n", SectorCount);
2795 
2796  if (List == NULL || PartEntry == NULL ||
2797  PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
2798  {
2799  return FALSE;
2800  }
2801 
2803  if (Error != NOT_AN_ERROR)
2804  {
2805  DPRINT1("PrimaryPartitionCreationChecks() failed with error %lu\n", Error);
2806  return FALSE;
2807  }
2808 
2809  /* Initialize the partition entry, inserting a new blank region if needed */
2810  if (!InitializePartitionEntry(PartEntry, SectorCount, AutoCreate))
2811  return FALSE;
2812 
2813  ASSERT(PartEntry->LogicalPartition == FALSE);
2814 
2815  UpdateDiskLayout(PartEntry->DiskEntry);
2817 
2818  return TRUE;
2819 }
#define TRUE
Definition: types.h:120
static BOOLEAN InitializePartitionEntry(IN OUT PPARTENTRY PartEntry, IN ULONGLONG SectorCount, IN BOOLEAN AutoCreate)
Definition: partlist.c:678
#define FALSE
Definition: types.h:117
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2534
ERROR_NUMBER PrimaryPartitionCreationChecks(IN PPARTENTRY PartEntry)
Definition: partlist.c:3954
#define ASSERT(a)
Definition: mode.c:44
BOOL Error
Definition: chkdsk.c:66
enum _ERROR_NUMBER ERROR_NUMBER
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
ULONG SectorCount
Definition: part_xbox.c:31
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
static VOID AssignDriveLetters(IN PPARTLIST List)
Definition: partlist.c:138

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

◆ DeletePartition()

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

Definition at line 3047 of file partlist.c.

3051 {
3052  PDISKENTRY DiskEntry;
3053  PPARTENTRY PrevPartEntry;
3054  PPARTENTRY NextPartEntry;
3055  PPARTENTRY LogicalPartEntry;
3057 
3058  if (List == NULL || PartEntry == NULL ||
3059  PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned == FALSE)
3060  {
3061  return FALSE;
3062  }
3063 
3064  ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
3065 
3066  /* Clear the system partition if it is being deleted */
3067  if (List->SystemPartition == PartEntry)
3068  {
3069  ASSERT(List->SystemPartition);
3070  List->SystemPartition = NULL;
3071  }
3072 
3073  DiskEntry = PartEntry->DiskEntry;
3074 
3075  /* Check which type of partition (primary/logical or extended) is being deleted */
3076  if (DiskEntry->ExtendedPartition == PartEntry)
3077  {
3078  /* An extended partition is being deleted: delete all logical partition entries */
3079  while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
3080  {
3081  Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
3082  LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
3083 
3084  /* Dismount the logical partition */
3085  DismountVolume(LogicalPartEntry);
3086 
3087  /* Delete it */
3088  RtlFreeHeap(ProcessHeap, 0, LogicalPartEntry);
3089  }
3090 
3091  DiskEntry->ExtendedPartition = NULL;
3092  }
3093  else
3094  {
3095  /* A primary partition is being deleted: dismount it */
3096  DismountVolume(PartEntry);
3097  }
3098 
3099  /* Adjust the unpartitioned disk space entries */
3100 
3101  /* Get pointer to previous and next unpartitioned entries */
3102  PrevPartEntry = GetPrevUnpartitionedEntry(PartEntry);
3103  NextPartEntry = GetNextUnpartitionedEntry(PartEntry);
3104 
3105  if (PrevPartEntry != NULL && NextPartEntry != NULL)
3106  {
3107  /* Merge the previous, current and next unpartitioned entries */
3108 
3109  /* Adjust the previous entry length */
3110  PrevPartEntry->SectorCount.QuadPart += (PartEntry->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart);
3111 
3112  /* Remove the current and next entries */
3113  RemoveEntryList(&PartEntry->ListEntry);
3114  RtlFreeHeap(ProcessHeap, 0, PartEntry);
3115  RemoveEntryList(&NextPartEntry->ListEntry);
3116  RtlFreeHeap(ProcessHeap, 0, NextPartEntry);
3117 
3118  /* Optionally return the freed region */
3119  if (FreeRegion)
3120  *FreeRegion = PrevPartEntry;
3121  }
3122  else if (PrevPartEntry != NULL && NextPartEntry == NULL)
3123  {
3124  /* Merge the current and the previous unpartitioned entries */
3125 
3126  /* Adjust the previous entry length */
3127  PrevPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
3128 
3129  /* Remove the current entry */
3130  RemoveEntryList(&PartEntry->ListEntry);
3131  RtlFreeHeap(ProcessHeap, 0, PartEntry);
3132 
3133  /* Optionally return the freed region */
3134  if (FreeRegion)
3135  *FreeRegion = PrevPartEntry;
3136  }
3137  else if (PrevPartEntry == NULL && NextPartEntry != NULL)
3138  {
3139  /* Merge the current and the next unpartitioned entries */
3140 
3141  /* Adjust the next entry offset and length */
3142  NextPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
3143  NextPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
3144 
3145  /* Remove the current entry */
3146  RemoveEntryList(&PartEntry->ListEntry);
3147  RtlFreeHeap(ProcessHeap, 0, PartEntry);
3148 
3149  /* Optionally return the freed region */
3150  if (FreeRegion)
3151  *FreeRegion = NextPartEntry;
3152  }
3153  else
3154  {
3155  /* Nothing to merge but change the current entry */
3156  PartEntry->IsPartitioned = FALSE;
3157  PartEntry->OnDiskPartitionNumber = 0;
3158  PartEntry->PartitionNumber = 0;
3159  // PartEntry->PartitionIndex = 0;
3160  PartEntry->BootIndicator = FALSE;
3161  PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
3162  PartEntry->FormatState = Unformatted;
3163  PartEntry->FileSystem[0] = L'\0';
3164  PartEntry->DriveLetter = 0;
3165  RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
3166 
3167  /* Optionally return the freed region */
3168  if (FreeRegion)
3169  *FreeRegion = PartEntry;
3170  }
3171 
3172  UpdateDiskLayout(DiskEntry);
3174 
3175  return TRUE;
3176 }
ULARGE_INTEGER StartSector
Definition: partlist.h:49
struct _Entry Entry
Definition: kefuncs.h:627
#define TRUE
Definition: types.h:120
ULARGE_INTEGER SectorCount
Definition: partlist.h:50
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:135
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:43
NTSTATUS DismountVolume(IN PPARTENTRY PartEntry)
Definition: partlist.c:2940
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define FALSE
Definition: types.h:117
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2534
#define ASSERT(a)
Definition: mode.c:44
static const WCHAR L[]
Definition: oid.c:1250
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
HANDLE ProcessHeap
Definition: servman.c:15
static PPARTENTRY GetPrevUnpartitionedEntry(IN PPARTENTRY PartEntry)
Definition: partlist.c:2717
#define NULL
Definition: types.h:112
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:132
static PPARTENTRY GetNextUnpartitionedEntry(IN PPARTENTRY PartEntry)
Definition: partlist.c:2752
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
base of all file and directory entries
Definition: entries.h:82
static VOID AssignDriveLetters(IN PPARTLIST List)
Definition: partlist.c:138
BOOLEAN IsPartitioned
Definition: partlist.h:66

Referenced by DeletePartitionPage().

◆ DestroyPartitionList()

VOID DestroyPartitionList ( IN PPARTLIST  List)

Definition at line 1931 of file partlist.c.

1933 {
1934  PDISKENTRY DiskEntry;
1935  PBIOSDISKENTRY BiosDiskEntry;
1936  PPARTENTRY PartEntry;
1938 
1939  /* Release disk and partition info */
1940  while (!IsListEmpty(&List->DiskListHead))
1941  {
1942  Entry = RemoveHeadList(&List->DiskListHead);
1943  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
1944 
1945  /* Release driver name */
1946  RtlFreeUnicodeString(&DiskEntry->DriverName);
1947 
1948  /* Release primary partition list */
1949  while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
1950  {
1951  Entry = RemoveHeadList(&DiskEntry->PrimaryPartListHead);
1952  PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1953 
1954  RtlFreeHeap(ProcessHeap, 0, PartEntry);
1955  }
1956 
1957  /* Release logical partition list */
1958  while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
1959  {
1960  Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
1961  PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1962 
1963  RtlFreeHeap(ProcessHeap, 0, PartEntry);
1964  }
1965 
1966  /* Release layout buffer */
1967  if (DiskEntry->LayoutBuffer != NULL)
1968  RtlFreeHeap(ProcessHeap, 0, DiskEntry->LayoutBuffer);
1969 
1970  /* Release disk entry */
1971  RtlFreeHeap(ProcessHeap, 0, DiskEntry);
1972  }
1973 
1974  /* Release the bios disk info */
1975  while (!IsListEmpty(&List->BiosDiskListHead))
1976  {
1977  Entry = RemoveHeadList(&List->BiosDiskListHead);
1978  BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
1979 
1980  RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
1981  }
1982 
1983  /* Release list head */
1985 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:131
struct _Entry Entry
Definition: kefuncs.h:627
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
UNICODE_STRING DriverName
Definition: partlist.h:123
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
HANDLE ProcessHeap
Definition: servman.c:15
#define NULL
Definition: types.h:112
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:132
PDRIVE_LAYOUT_INFORMATION LayoutBuffer
Definition: partlist.h:125
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 247 of file partlist.c.

254 {
255  PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
256  PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
257  PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
258  ULONG i;
259 
262  return STATUS_UNSUCCESSFUL;
263 
264  FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
265 
266  /* Hm. Version and Revision are not set on Microsoft Windows XP... */
267 #if 0
268  if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
269  FullResourceDescriptor->PartialResourceList.Revision != 1)
270  return STATUS_UNSUCCESSFUL;
271 #endif
272 
273  for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
274  {
276  FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize != sizeof(CM_DISK_GEOMETRY_DEVICE_DATA))
277  continue;
278 
279  DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1];
280  BiosDiskEntry->DiskGeometry = *DiskGeometry;
281 
282  return STATUS_SUCCESS;
283  }
284 
285  return STATUS_UNSUCCESSFUL;
286 }
#define CmResourceTypeDeviceSpecific
Definition: hwresource.cpp:127
struct _CM_DISK_GEOMETRY_DEVICE_DATA * PCM_DISK_GEOMETRY_DEVICE_DATA
struct _BIOSDISKENTRY * PBIOSDISKENTRY
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:279
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
struct _CM_FULL_RESOURCE_DESCRIPTOR * PCM_FULL_RESOURCE_DESCRIPTOR
#define REG_FULL_RESOURCE_DESCRIPTOR
Definition: nt_native.h:1503
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@377 u
CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry
Definition: partlist.h:148
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@377::@386 DeviceSpecificData
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: hwresource.cpp:119
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:271

Referenced by EnumerateBiosDiskEntries().

◆ DiskIdentifierQueryRoutine()

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

Definition at line 217 of file partlist.c.

224 {
225  PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
226  UNICODE_STRING NameU;
227 
228  if (ValueType == REG_SZ &&
229  ValueLength == 20 * sizeof(WCHAR) &&
230  ((PWCHAR)ValueData)[8] == L'-')
231  {
232  NameU.Buffer = (PWCHAR)ValueData;
233  NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR);
234  RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum);
235 
236  NameU.Buffer = (PWCHAR)ValueData + 9;
237  RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature);
238 
239  return STATUS_SUCCESS;
240  }
241 
242  return STATUS_UNSUCCESSFUL;
243 }
USHORT MaximumLength
Definition: env_spec_w32.h:370
ULONG Checksum
Definition: partlist.h:146
ULONG Signature
Definition: partlist.h:145
uint16_t * PWCHAR
Definition: typedefs.h:56
struct _BIOSDISKENTRY * PBIOSDISKENTRY
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:279
__wchar_t WCHAR
Definition: xmlstorage.h:180
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
static const WCHAR L[]
Definition: oid.c:1250
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define REG_SZ
Definition: layer.c:22
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:271

Referenced by EnumerateBiosDiskEntries().

◆ DismountVolume()

NTSTATUS DismountVolume ( IN PPARTENTRY  PartEntry)

Definition at line 2940 of file partlist.c.

2942 {
2943  NTSTATUS Status;
2944  NTSTATUS LockStatus;
2948  HANDLE PartitionHandle;
2950 
2951  /* Check whether the partition is valid and was mounted by the system */
2952  if (!PartEntry->IsPartitioned ||
2953  IsContainerPartition(PartEntry->PartitionType) ||
2954  !IsRecognizedPartition(PartEntry->PartitionType) ||
2955  PartEntry->FormatState == UnknownFormat ||
2956  // NOTE: If FormatState == Unformatted but *FileSystem != 0 this means
2957  // it has been usually mounted with RawFS and thus needs to be dismounted.
2958  !*PartEntry->FileSystem ||
2959  PartEntry->PartitionNumber == 0)
2960  {
2961  /* The partition is not mounted, so just return success */
2962  return STATUS_SUCCESS;
2963  }
2964 
2965  ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
2966 
2967  /* Open the volume */
2969  L"\\Device\\Harddisk%lu\\Partition%lu",
2970  PartEntry->DiskEntry->DiskNumber,
2971  PartEntry->PartitionNumber);
2973 
2975  &Name,
2977  NULL,
2978  NULL);
2979 
2980  Status = NtOpenFile(&PartitionHandle,
2983  &IoStatusBlock,
2986  if (!NT_SUCCESS(Status))
2987  {
2988  DPRINT1("ERROR: Cannot open volume %wZ for dismounting! (Status 0x%lx)\n", &Name, Status);
2989  return Status;
2990  }
2991 
2992  /* Lock the volume */
2993  LockStatus = NtFsControlFile(PartitionHandle,
2994  NULL,
2995  NULL,
2996  NULL,
2997  &IoStatusBlock,
2999  NULL,
3000  0,
3001  NULL,
3002  0);
3003  if (!NT_SUCCESS(LockStatus))
3004  {
3005  DPRINT1("WARNING: Failed to lock volume! Operations may fail! (Status 0x%lx)\n", LockStatus);
3006  }
3007 
3008  /* Dismount the volume */
3009  Status = NtFsControlFile(PartitionHandle,
3010  NULL,
3011  NULL,
3012  NULL,
3013  &IoStatusBlock,
3015  NULL,
3016  0,
3017  NULL,
3018  0);
3019  if (!NT_SUCCESS(Status))
3020  {
3021  DPRINT1("Failed to unmount volume (Status 0x%lx)\n", Status);
3022  }
3023 
3024  /* Unlock the volume */
3025  LockStatus = NtFsControlFile(PartitionHandle,
3026  NULL,
3027  NULL,
3028  NULL,
3029  &IoStatusBlock,
3031  NULL,
3032  0,
3033  NULL,
3034  0);
3035  if (!NT_SUCCESS(LockStatus))
3036  {
3037  DPRINT1("Failed to unlock volume (Status 0x%lx)\n", LockStatus);
3038  }
3039 
3040  /* Close the volume */
3041  NtClose(PartitionHandle);
3042 
3043  return Status;
3044 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:316
NTSYSCALLAPI NTSTATUS NTAPI NtFsControlFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG FsControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength)
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_SHARE_READ
Definition: compat.h:136
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
#define GENERIC_WRITE
Definition: nt_native.h:90
struct NameRec_ * Name
Definition: cdprocs.h:459
Definition: bufpool.h:45
#define FSCTL_DISMOUNT_VOLUME
Definition: nt_native.h:834
Status
Definition: gdiplustypes.h:24
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3951
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:342
#define MAX_PATH
Definition: compat.h:34
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3398
static const WCHAR L[]
Definition: oid.c:1250
#define GENERIC_READ
Definition: compat.h:135
#define SYNCHRONIZE
Definition: nt_native.h:61
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define FSCTL_LOCK_VOLUME
Definition: nt_native.h:832
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by AddPartitionToDisk(), and DeletePartition().

◆ EnumerateBiosDiskEntries()

static VOID EnumerateBiosDiskEntries ( IN PPARTLIST  PartList)
static

Definition at line 337 of file partlist.c.

339 {
341  WCHAR Name[120];
342  ULONG AdapterCount;
344  ULONG DiskCount;
346  PCM_INT13_DRIVE_PARAMETER Int13Drives;
347  PBIOSDISKENTRY BiosDiskEntry;
348 
349 #define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
350 
351  memset(QueryTable, 0, sizeof(QueryTable));
352 
353  QueryTable[1].Name = L"Configuration Data";
355  Int13Drives = NULL;
357  L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
358  &QueryTable[1],
359  (PVOID)&Int13Drives,
360  NULL);
361  if (!NT_SUCCESS(Status))
362  {
363  DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status);
364  return;
365  }
366 
367  for (AdapterCount = 0; ; ++AdapterCount)
368  {
370  L"%s\\%lu",
371  ROOT_NAME, AdapterCount);
373  Name,
374  &QueryTable[2],
375  NULL,
376  NULL);
377  if (!NT_SUCCESS(Status))
378  {
379  break;
380  }
381 
383  L"%s\\%lu\\DiskController",
384  ROOT_NAME, AdapterCount);
386  Name,
387  &QueryTable[2],
388  NULL,
389  NULL);
390  if (NT_SUCCESS(Status))
391  {
392  for (ControllerCount = 0; ; ++ControllerCount)
393  {
395  L"%s\\%lu\\DiskController\\%lu",
396  ROOT_NAME, AdapterCount, ControllerCount);
398  Name,
399  &QueryTable[2],
400  NULL,
401  NULL);
402  if (!NT_SUCCESS(Status))
403  {
404  RtlFreeHeap(ProcessHeap, 0, Int13Drives);
405  return;
406  }
407 
409  L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral",
410  ROOT_NAME, AdapterCount, ControllerCount);
412  Name,
413  &QueryTable[2],
414  NULL,
415  NULL);
416  if (NT_SUCCESS(Status))
417  {
418  QueryTable[0].Name = L"Identifier";
420  QueryTable[1].Name = L"Configuration Data";
422 
423  for (DiskCount = 0; ; ++DiskCount)
424  {
426  if (BiosDiskEntry == NULL)
427  {
428  RtlFreeHeap(ProcessHeap, 0, Int13Drives);
429  return;
430  }
431 
433  L"%s\\%lu\\DiskController\\%lu\\DiskPeripheral\\%lu",
434  ROOT_NAME, AdapterCount, ControllerCount, DiskCount);
436  Name,
437  QueryTable,
438  (PVOID)BiosDiskEntry,
439  NULL);
440  if (!NT_SUCCESS(Status))
441  {
442  RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
443  RtlFreeHeap(ProcessHeap, 0, Int13Drives);
444  return;
445  }
446 
447  BiosDiskEntry->AdapterNumber = 0; // And NOT "AdapterCount" as it needs to be hardcoded for BIOS!
448  BiosDiskEntry->ControllerNumber = ControllerCount;
449  BiosDiskEntry->DiskNumber = DiskCount;
450  BiosDiskEntry->DiskEntry = NULL;
451 
452  if (DiskCount < Int13Drives[0].NumberDrives)
453  {
454  BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount];
455  }
456  else
457  {
458  DPRINT1("Didn't find Int13 drive data for disk %u\n", DiskCount);
459  }
460 
461  InsertTailList(&PartList->BiosDiskListHead, &BiosDiskEntry->ListEntry);
462 
463  DPRINT("--->\n");
464  DPRINT("AdapterNumber: %lu\n", BiosDiskEntry->AdapterNumber);
465  DPRINT("ControllerNumber: %lu\n", BiosDiskEntry->ControllerNumber);
466  DPRINT("DiskNumber: %lu\n", BiosDiskEntry->DiskNumber);
467  DPRINT("Signature: %08lx\n", BiosDiskEntry->Signature);
468  DPRINT("Checksum: %08lx\n", BiosDiskEntry->Checksum);
469  DPRINT("BytesPerSector: %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector);
470  DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders);
471  DPRINT("NumberOfHeads: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads);
472  DPRINT("DriveSelect: %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect);
473  DPRINT("MaxCylinders: %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders);
474  DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack);
475  DPRINT("MaxHeads: %d\n", BiosDiskEntry->Int13DiskData.MaxHeads);
476  DPRINT("NumberDrives: %d\n", BiosDiskEntry->Int13DiskData.NumberDrives);
477  DPRINT("<---\n");
478  }
479  }
480  }
481  }
482  }
483 
484  RtlFreeHeap(ProcessHeap, 0, Int13Drives);
485 
486 #undef ROOT_NAME
487 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4155
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
ULONG Checksum
Definition: partlist.h:146
ULONG Signature
Definition: partlist.h:145
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:143
#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:290
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
Status
Definition: gdiplustypes.h:24
ULONG AdapterNumber
Definition: partlist.h:142
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry
Definition: partlist.h:148
PDISKENTRY DiskEntry
Definition: partlist.h:147
static const WCHAR L[]
Definition: oid.c:1250
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
HANDLE ProcessHeap
Definition: servman.c:15
LIST_ENTRY ListEntry
Definition: partlist.h:141
ULONG DiskNumber
Definition: partlist.h:144
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define DPRINT1
Definition: precomp.h:8
#define ROOT_NAME
static NTSTATUS NTAPI DiskConfigurationDataQueryRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: partlist.c:247
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:217
CM_INT13_DRIVE_PARAMETER Int13DiskData
Definition: partlist.h:149
#define DPRINT
Definition: sndvol32.h:71
#define memset(x, y, z)
Definition: compat.h:39

Referenced by CreatePartitionList().

◆ ExtendedPartitionCreationChecks()

ERROR_NUMBER ExtendedPartitionCreationChecks ( IN PPARTENTRY  PartEntry)

Definition at line 3981 of file partlist.c.

3983 {
3984  PDISKENTRY DiskEntry = PartEntry->DiskEntry;
3985 
3986  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3987  {
3988  DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3989  return ERROR_WARN_PARTITION;
3990  }
3991 
3992  /* Fail if the partition is already in use */
3993  if (PartEntry->IsPartitioned)
3994  return ERROR_NEW_PARTITION;
3995 
3996  /* Only one primary partition is allowed on super-floppy */
3997  if (IsSuperFloppy(DiskEntry))
3999 
4000  /* Fail if there are already 4 primary partitions in the list */
4001  if (GetPrimaryPartitionCount(DiskEntry) >= 4)
4003 
4004  /* Fail if there is another extended partition in the list */
4005  if (DiskEntry->ExtendedPartition != NULL)
4006  return ERROR_ONLY_ONE_EXTENDED;
4007 
4008  return ERROR_SUCCESS;
4009 }
#define ERROR_SUCCESS
Definition: deptool.c:10
PPARTENTRY ExtendedPartition
Definition: partlist.h:135
PARTITION_STYLE DiskStyle
Definition: partlist.h:121
static ULONG GetPrimaryPartitionCount(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2428
BOOLEAN IsSuperFloppy(IN PDISKENTRY DiskEntry)
Definition: partlist.c:501
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8

Referenced by CreateExtendedPartition(), and SelectPartitionPage().

◆ FindSupportedSystemPartition()

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

Definition at line 3260 of file partlist.c.

3265 {
3266  PLIST_ENTRY ListEntry;
3267  PDISKENTRY DiskEntry;
3268  PPARTENTRY PartEntry;
3269  PPARTENTRY ActivePartition;
3270  PPARTENTRY CandidatePartition = NULL;
3271 
3272  /* Check for empty disk list */
3273  if (IsListEmpty(&List->DiskListHead))
3274  {
3275  /* No system partition! */
3276  ASSERT(List->SystemPartition == NULL);
3277  goto NoSystemPartition;
3278  }
3279 
3280  /* Adjust the optional alternative disk if needed */
3281  if (!AlternativeDisk && AlternativePart)
3282  AlternativeDisk = AlternativePart->DiskEntry;
3283 
3284  /* Ensure that the alternative partition is on the alternative disk */
3285  if (AlternativePart)
3286  ASSERT(AlternativeDisk && (AlternativePart->DiskEntry == AlternativeDisk));
3287 
3288  /* Ensure that the alternative disk is in the list */
3289  if (AlternativeDisk)
3290  ASSERT(AlternativeDisk->PartList == List);
3291 
3292  /* Start fresh */
3293  CandidatePartition = NULL;
3294 
3295 //
3296 // Step 1 : Check the system disk.
3297 //
3298 
3299  /*
3300  * First, check whether the system disk, i.e. the one that will be booted
3301  * by default by the hardware, contains an active partition. If so this
3302  * should be our system partition.
3303  */
3304  DiskEntry = GetSystemDisk(List);
3305 
3306  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3307  {
3308  DPRINT1("System disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
3309  goto UseAlternativeDisk;
3310  }
3311 
3312  /* If we have a system partition (in the system disk), validate it */
3313  ActivePartition = List->SystemPartition;
3314  if (ActivePartition && IsSupportedActivePartition(ActivePartition))
3315  {
3316  CandidatePartition = ActivePartition;
3317 
3318  DPRINT1("Use the current system partition %lu in disk %lu, drive letter %C\n",
3319  CandidatePartition->PartitionNumber,
3320  CandidatePartition->DiskEntry->DiskNumber,
3321  (CandidatePartition->DriveLetter == 0) ? L'-' : CandidatePartition->DriveLetter);
3322 
3323  /* Return the candidate system partition */
3324  return CandidatePartition;
3325  }
3326 
3327  /* If the system disk is not the optional alternative disk, perform the minimal checks */
3328  if (DiskEntry != AlternativeDisk)
3329  {
3330  /*
3331  * No active partition has been recognized. Enumerate all the (primary)
3332  * partitions in the system disk, excluding the possible current active
3333  * partition, to find a new candidate.
3334  */
3335  for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3336  ListEntry != &DiskEntry->PrimaryPartListHead;
3337  ListEntry = ListEntry->Flink)
3338  {
3339  /* Retrieve the partition */
3340  PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3341 
3342  /* Skip the current active partition */
3343  if (PartEntry == ActivePartition)
3344  continue;
3345 
3346  /* Check if the partition is partitioned and used */
3347  if (PartEntry->IsPartitioned &&
3348  !IsContainerPartition(PartEntry->PartitionType))
3349  {
3351 
3352  /* If we get a candidate active partition in the disk, validate it */
3353  if (IsSupportedActivePartition(PartEntry))
3354  {
3355  CandidatePartition = PartEntry;
3356  goto UseAlternativePartition;
3357  }
3358  }
3359 
3360 #if 0
3361  /* Check if the partition is partitioned and used */
3362  if (!PartEntry->IsPartitioned)
3363  {
3365 
3366  // TODO: Check for minimal size!!
3367  CandidatePartition = PartEntry;
3368  goto UseAlternativePartition;
3369  }
3370 #endif
3371  }
3372 
3373  /*
3374  * Still nothing, look whether there is some free space that we can use
3375  * for the new system partition. We must be sure that the total number
3376  * of partition is less than the maximum allowed, and that the minimal
3377  * size is fine.
3378  */
3379 //
3380 // TODO: Fix the handling of system partition being created in unpartitioned space!!
3381 // --> When to partition it? etc...
3382 //
3383  if (GetPrimaryPartitionCount(DiskEntry) < 4)
3384  {
3385  for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3386  ListEntry != &DiskEntry->PrimaryPartListHead;
3387  ListEntry = ListEntry->Flink)
3388  {
3389  /* Retrieve the partition */
3390  PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3391 
3392  /* Skip the current active partition */
3393  if (PartEntry == ActivePartition)
3394  continue;
3395 
3396  /* Check for unpartitioned space */
3397  if (!PartEntry->IsPartitioned)
3398  {
3400 
3401  // TODO: Check for minimal size!!
3402  CandidatePartition = PartEntry;
3403  goto UseAlternativePartition;
3404  }
3405  }
3406  }
3407  }
3408 
3409 
3410 //
3411 // Step 2 : No active partition found: Check the alternative disk if specified.
3412 //
3413 
3414 UseAlternativeDisk:
3415  if (!AlternativeDisk || (!ForceSelect && (DiskEntry != AlternativeDisk)))
3416  goto NoSystemPartition;
3417 
3418  if (AlternativeDisk->DiskStyle == PARTITION_STYLE_GPT)
3419  {
3420  DPRINT1("Alternative disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
3421  goto NoSystemPartition;
3422  }
3423 
3424  if (DiskEntry != AlternativeDisk)
3425  {
3426  /* Choose the alternative disk */
3427  DiskEntry = AlternativeDisk;
3428 
3429  /* If we get a candidate active partition, validate it */
3430  ActivePartition = GetActiveDiskPartition(DiskEntry);
3431  if (ActivePartition && IsSupportedActivePartition(ActivePartition))
3432  {
3433  CandidatePartition = ActivePartition;
3434  goto UseAlternativePartition;
3435  }
3436  }
3437 
3438  /* We now may have an unsupported active partition, or none */
3439 
3440 /***
3441  *** TODO: Improve the selection:
3442  *** - If we want a really separate system partition from the partition where
3443  *** we install, do something similar to what's done below in the code.
3444  *** - Otherwise if we allow for the system partition to be also the partition
3445  *** where we install, just directly fall down to using AlternativePart.
3446  ***/
3447 
3448  /* Retrieve the first partition of the disk */
3449  PartEntry = CONTAINING_RECORD(DiskEntry->PrimaryPartListHead.Flink,
3450  PARTENTRY, ListEntry);
3451  ASSERT(DiskEntry == PartEntry->DiskEntry);
3452 
3453  CandidatePartition = PartEntry;
3454 
3455  //
3456  // See: https://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/partlist.c?r1=63355&r2=63354&pathrev=63355#l2318
3457  //
3458 
3459  /* Check if the disk is new and if so, use its first partition as the active system partition */
3460  if (DiskEntry->NewDisk)
3461  {
3462  // !IsContainerPartition(PartEntry->PartitionType);
3463  if (!CandidatePartition->IsPartitioned || !CandidatePartition->BootIndicator) /* CandidatePartition != ActivePartition */
3464  {
3465  ASSERT(DiskEntry == CandidatePartition->DiskEntry);
3466 
3467  DPRINT1("Use new first active system partition %lu in disk %lu, drive letter %C\n",
3468  CandidatePartition->PartitionNumber,
3469  CandidatePartition->DiskEntry->DiskNumber,
3470  (CandidatePartition->DriveLetter == 0) ? L'-' : CandidatePartition->DriveLetter);
3471 
3472  /* Return the candidate system partition */
3473  return CandidatePartition;
3474  }
3475 
3476  // FIXME: What to do??
3477  DPRINT1("NewDisk TRUE but first partition is used?\n");
3478  }
3479 
3480  /*
3481  * The disk is not new, check if any partition is initialized;
3482  * if not, the first one becomes the system partition.
3483  */
3484  for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3485  ListEntry != &DiskEntry->PrimaryPartListHead;
3486  ListEntry = ListEntry->Flink)
3487  {
3488  /* Retrieve the partition */
3489  PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3490 
3491  /* Check if the partition is partitioned and is used */
3492  // !IsContainerPartition(PartEntry->PartitionType);
3493  if (/* PartEntry->IsPartitioned && */
3494  PartEntry->PartitionType != PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator)
3495  {
3496  break;
3497  }
3498  }
3499  if (ListEntry == &DiskEntry->PrimaryPartListHead)
3500  {
3501  /*
3502  * OK we haven't encountered any used and active partition,
3503  * so use the first one as the system partition.
3504  */
3505  ASSERT(DiskEntry == CandidatePartition->DiskEntry);
3506 
3507  DPRINT1("Use first active system partition %lu in disk %lu, drive letter %C\n",
3508  CandidatePartition->PartitionNumber,
3509  CandidatePartition->DiskEntry->DiskNumber,
3510  (CandidatePartition->DriveLetter == 0) ? L'-' : CandidatePartition->DriveLetter);
3511 
3512  /* Return the candidate system partition */
3513  return CandidatePartition;
3514  }
3515 
3516  /*
3517  * The disk is not new, we did not find any actual active partition,
3518  * or the one we found was not supported, or any possible other candidate
3519  * is not supported. We then use the alternative partition if specified.
3520  */
3521  if (AlternativePart)
3522  {
3523  DPRINT1("No valid or supported system partition has been found, use the alternative partition!\n");
3524  CandidatePartition = AlternativePart;
3525  goto UseAlternativePartition;
3526  }
3527  else
3528  {
3529 NoSystemPartition:
3530  DPRINT1("No valid or supported system partition has been found on this system!\n");
3531  return NULL;
3532  }
3533 
3534 UseAlternativePartition:
3535  /*
3536  * We are here because we did not find any (active) candidate system
3537  * partition that we know how to support. What we are going to do is
3538  * to change the existing system partition and use the alternative partition
3539  * (e.g. on which we install ReactOS) as the new system partition.
3540  * Then we will need to add in FreeLdr's boot menu an entry for booting
3541  * from the original system partition.
3542  */
3543  ASSERT(CandidatePartition);
3544 
3545  DPRINT1("Use alternative active system partition %lu in disk %lu, drive letter %C\n",
3546  CandidatePartition->PartitionNumber,
3547  CandidatePartition->DiskEntry->DiskNumber,
3548  (CandidatePartition->DriveLetter == 0) ? L'-' : CandidatePartition->DriveLetter);
3549 
3550  /* Return the candidate system partition */
3551  return CandidatePartition;
3552 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:131
WCHAR DriveLetter
Definition: partlist.h:58
ULONG PartitionNumber
Definition: partlist.h:55
static PPARTENTRY GetActiveDiskPartition(IN PDISKENTRY DiskEntry)
Definition: partlist.c:1791
static BOOLEAN IsSupportedActivePartition(IN PPARTENTRY PartEntry)
Definition: partlist.c:3180
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:316
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
PARTITION_STYLE DiskStyle
Definition: partlist.h:121
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
UCHAR PartitionType
Definition: partlist.h:53
struct _DISKENTRY * DiskEntry
Definition: partlist.h:46
#define ASSERT(a)
Definition: mode.c:44
static ULONG GetPrimaryPartitionCount(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2428
static PDISKENTRY GetSystemDisk(IN PPARTLIST List)
Definition: partlist.c:1718
static const WCHAR L[]
Definition: oid.c:1250
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
BOOLEAN BootIndicator
Definition: partlist.h:52
BOOLEAN NewDisk
Definition: partlist.h:120
BOOLEAN IsPartitioned
Definition: partlist.h:66

Referenced by SelectFileSystemPage().

◆ GetActiveDiskPartition()

static PPARTENTRY GetActiveDiskPartition ( IN PDISKENTRY  DiskEntry)
static

Definition at line 1791 of file partlist.c.

1793 {
1794  PLIST_ENTRY ListEntry;
1795  PPARTENTRY PartEntry;
1796  PPARTENTRY ActivePartition = NULL;
1797 
1798  /* Check for empty disk list */
1799  // ASSERT(DiskEntry);
1800  if (!DiskEntry)
1801  return NULL;
1802 
1803  /* Check for empty partition list */
1804  if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
1805  return NULL;
1806 
1807  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1808  {
1809  DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1810  return NULL;
1811  }
1812 
1813  /* Scan all (primary) partitions to find the active disk partition */
1814  for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
1815  ListEntry != &DiskEntry->PrimaryPartListHead;
1816  ListEntry = ListEntry->Flink)
1817  {
1818  /* Retrieve the partition */
1819  PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1820  if (IsPartitionActive(PartEntry))
1821  {
1822  /* Yes, we've found it */
1823  ASSERT(DiskEntry == PartEntry->DiskEntry);
1824  ASSERT(PartEntry->IsPartitioned);
1825 
1826  ActivePartition = PartEntry;
1827 
1828  DPRINT1("Found active system partition %lu in disk %lu, drive letter %C\n",
1829  PartEntry->PartitionNumber, DiskEntry->DiskNumber,
1830  (PartEntry->DriveLetter == 0) ? L'-' : PartEntry->DriveLetter);
1831  break;
1832  }
1833  }
1834 
1835  /* Check if the disk is new and if so, use its first partition as the active system partition */
1836  if (DiskEntry->NewDisk && ActivePartition != NULL)
1837  {
1838  // FIXME: What to do??
1839  DPRINT1("NewDisk TRUE but already existing active partition?\n");
1840  }
1841 
1842  /* Return the active partition found (or none) */
1843  return ActivePartition;
1844 }
WCHAR DriveLetter
Definition: partlist.h:58
ULONG PartitionNumber
Definition: partlist.h:55
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _DISKENTRY * DiskEntry
Definition: partlist.h:46
#define ASSERT(a)
Definition: mode.c:44
static const WCHAR L[]
Definition: oid.c:1250
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
BOOLEAN IsPartitionActive(IN PPARTENTRY PartEntry)
Definition: partlist.c:1768
BOOLEAN IsPartitioned
Definition: partlist.h:66

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

◆ GetDiskByBiosNumber()

PDISKENTRY GetDiskByBiosNumber ( IN PPARTLIST  List,
IN ULONG  HwDiskNumber 
)

Definition at line 1988 of file partlist.c.

1991 {
1992  PDISKENTRY DiskEntry;
1994 
1995  /* Loop over the disks and find the correct one */
1996  for (Entry = List->DiskListHead.Flink;
1997  Entry != &List->DiskListHead;
1998  Entry = Entry->Flink)
1999  {
2000  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2001 
2002  if (DiskEntry->HwDiskNumber == HwDiskNumber)
2003  {
2004  /* Disk found */
2005  return DiskEntry;
2006  }
2007  }
2008 
2009  /* Disk not found, stop there */
2010  return NULL;
2011 }
struct _Entry Entry
Definition: kefuncs.h:627
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
ULONG HwDiskNumber
Definition: partlist.h:105
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
base of all file and directory entries
Definition: entries.h:82

◆ GetDiskByNumber()

PDISKENTRY GetDiskByNumber ( IN PPARTLIST  List,
IN ULONG  DiskNumber 
)

Definition at line 2014 of file partlist.c.

2017 {
2018  PDISKENTRY DiskEntry;
2020 
2021  /* Loop over the disks and find the correct one */
2022  for (Entry = List->DiskListHead.Flink;
2023  Entry != &List->DiskListHead;
2024  Entry = Entry->Flink)
2025  {
2026  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2027 
2028  if (DiskEntry->DiskNumber == DiskNumber)
2029  {
2030  /* Disk found */
2031  return DiskEntry;
2032  }
2033  }
2034 
2035  /* Disk not found, stop there */
2036  return NULL;
2037 }
struct _Entry Entry
Definition: kefuncs.h:627
ULONG DiskNumber
Definition: partlist.h:111
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
base of all file and directory entries
Definition: entries.h:82

Referenced by GetDiskOrPartition(), and SelectPartition().

◆ GetDiskBySCSI()

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

Definition at line 2040 of file partlist.c.

2045 {
2046  PDISKENTRY DiskEntry;
2048 
2049  /* Loop over the disks and find the correct one */
2050  for (Entry = List->DiskListHead.Flink;
2051  Entry != &List->DiskListHead;
2052  Entry = Entry->Flink)
2053  {
2054  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2055 
2056  if (DiskEntry->Port == Port &&
2057  DiskEntry->Bus == Bus &&
2058  DiskEntry->Id == Id)
2059  {
2060  /* Disk found */
2061  return DiskEntry;
2062  }
2063  }
2064 
2065  /* Disk not found, stop there */
2066  return NULL;
2067 }
CPPORT Port[4]
Definition: headless.c:35
USHORT Id
Definition: partlist.h:115
struct _Entry Entry
Definition: kefuncs.h:627
USHORT Bus
Definition: partlist.h:114
DWORD Id
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
USHORT Port
Definition: partlist.h:113
#define NULL
Definition: types.h:112
base of all file and directory entries
Definition: entries.h:82

Referenced by ResolveArcNameManually().

◆ GetDiskBySignature()

PDISKENTRY GetDiskBySignature ( IN PPARTLIST  List,
IN ULONG  Signature 
)

Definition at line 2070 of file partlist.c.

2073 {
2074  PDISKENTRY DiskEntry;
2076 
2077  /* Loop over the disks and find the correct one */
2078  for (Entry = List->DiskListHead.Flink;
2079  Entry != &List->DiskListHead;
2080  Entry = Entry->Flink)
2081  {
2082  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2083 
2084  if (DiskEntry->LayoutBuffer->Signature == Signature)
2085  {
2086  /* Disk found */
2087  return DiskEntry;
2088  }
2089  }
2090 
2091  /* Disk not found, stop there */
2092  return NULL;
2093 }
struct _Entry Entry
Definition: kefuncs.h:627
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
static const WCHAR Signature[]
Definition: parser.c:141
PDRIVE_LAYOUT_INFORMATION LayoutBuffer
Definition: partlist.h:125
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 2143 of file partlist.c.

2149 {
2150  PDISKENTRY DiskEntry;
2151  PPARTENTRY PartEntry = NULL;
2152 
2153  /* Find the disk */
2154  DiskEntry = GetDiskByNumber(List, DiskNumber);
2155  if (!DiskEntry)
2156  return FALSE;
2157 
2158  /* If we have a partition (PartitionNumber != 0), find it */
2159  if (PartitionNumber != 0)
2160  {
2161  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2162  {
2163  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2164  return FALSE;
2165  }
2166 
2167  PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
2168  if (!PartEntry)
2169  return FALSE;
2170  ASSERT(PartEntry->DiskEntry == DiskEntry);
2171  }
2172 
2173  /* Return the disk (and optionally the partition) */
2174  *pDiskEntry = DiskEntry;
2175  if (pPartEntry) *pPartEntry = PartEntry;
2176  return TRUE;
2177 }
#define TRUE
Definition: types.h:120
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2060
PPARTENTRY GetPartition(IN PDISKENTRY DiskEntry, IN ULONG PartitionNumber)
Definition: partlist.c:2096
PARTITION_STYLE DiskStyle
Definition: partlist.h:121
#define FALSE
Definition: types.h:117
PDISKENTRY GetDiskByNumber(IN PPARTLIST List, IN ULONG DiskNumber)
Definition: partlist.c:2014
struct _DISKENTRY * DiskEntry
Definition: partlist.h:46
#define ASSERT(a)
Definition: mode.c:44
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
#define NULL
Definition: types.h:112
#define DPRINT
Definition: sndvol32.h:71

Referenced by EnumerateInstallations().

◆ GetDriverName()

static VOID GetDriverName ( IN PDISKENTRY  DiskEntry)
static

Definition at line 105 of file partlist.c.

107 {
109  WCHAR KeyName[32];
111 
112  RtlInitUnicodeString(&DiskEntry->DriverName, NULL);
113 
115  L"\\Scsi\\Scsi Port %hu",
116  DiskEntry->Port);
117 
119 
120  QueryTable[0].Name = L"Driver";
122  QueryTable[0].EntryContext = &DiskEntry->DriverName;
123 
124  /* This will allocate DiskEntry->DriverName if needed */
126  KeyName,
127  QueryTable,
128  NULL,
129  NULL);
130  if (!NT_SUCCESS(Status))
131  {
132  DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
133  }
134 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4155
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2697
Status
Definition: gdiplustypes.h:24
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR L[]
Definition: oid.c:1250
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RTL_REGISTRY_DEVICEMAP
Definition: nt_native.h:165
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144

Referenced by AddDiskToList().

◆ GetLogicalPartitionCount()

static ULONG GetLogicalPartitionCount ( IN PDISKENTRY  DiskEntry)
static

Definition at line 2455 of file partlist.c.

2457 {
2458  PLIST_ENTRY ListEntry;
2459  PPARTENTRY PartEntry;
2460  ULONG Count = 0;
2461 
2462  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2463  {
2464  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2465  return 0;
2466  }
2467 
2468  for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
2469  ListEntry != &DiskEntry->LogicalPartListHead;
2470  ListEntry = ListEntry->Flink)
2471  {
2472  PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
2473  if (PartEntry->IsPartitioned)
2474  Count++;
2475  }
2476 
2477  return Count;
2478 }
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
int Count
Definition: noreturn.cpp:7
Definition: typedefs.h:119
unsigned int ULONG
Definition: retypes.h:1
#define DPRINT
Definition: sndvol32.h:71
BOOLEAN IsPartitioned
Definition: partlist.h:66

Referenced by ReAllocateLayoutBuffer().

◆ GetNextPartition()

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

Definition at line 2207 of file partlist.c.

2210 {
2211  PLIST_ENTRY DiskListEntry;
2212  PLIST_ENTRY PartListEntry;
2214 
2215  /* Fail if no disks are available */
2216  if (IsListEmpty(&List->DiskListHead))
2217  return NULL;
2218 
2219  /* Check for the next usable entry on the current partition's disk */
2220  if (CurrentPart != NULL)
2221  {
2222  CurrentDisk = CurrentPart->DiskEntry;
2223 
2224  if (CurrentPart->LogicalPartition)
2225  {
2226  /* Logical partition */
2227 
2228  PartListEntry = CurrentPart->ListEntry.Flink;
2229  if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2230  {
2231  /* Next logical partition */
2232  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2233  return CurrentPart;
2234  }
2235  else
2236  {
2237  PartListEntry = CurrentDisk->ExtendedPartition->ListEntry.Flink;
2238  if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2239  {
2240  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2241  return CurrentPart;
2242  }
2243  }
2244  }
2245  else
2246  {
2247  /* Primary or extended partition */
2248 
2249  if (CurrentPart->IsPartitioned &&
2250  IsContainerPartition(CurrentPart->PartitionType))
2251  {
2252  /* First logical partition */
2253  PartListEntry = CurrentDisk->LogicalPartListHead.Flink;
2254  if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2255  {
2256  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2257  return CurrentPart;
2258  }
2259  }
2260  else
2261  {
2262  /* Next primary partition */
2263  PartListEntry = CurrentPart->ListEntry.Flink;
2264  if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2265  {
2266  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2267  return CurrentPart;
2268  }
2269  }
2270  }
2271  }
2272 
2273  /* Search for the first partition entry on the next disk */
2274  for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Flink
2275  : List->DiskListHead.Flink);
2276  DiskListEntry != &List->DiskListHead;
2277  DiskListEntry = DiskListEntry->Flink)
2278  {
2279  CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
2280 
2282  {
2283  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2284  continue;
2285  }
2286 
2287  PartListEntry = CurrentDisk->PrimaryPartListHead.Flink;
2288  if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2289  {
2290  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2291  return CurrentPart;
2292  }
2293  }
2294 
2295  return NULL;
2296 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:131
PDISKENTRY CurrentDisk
Definition: partlist.c:73
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:316
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
PPARTENTRY ExtendedPartition
Definition: partlist.h:135
LIST_ENTRY ListEntry
Definition: partlist.h:43
PARTITION_STYLE DiskStyle
Definition: partlist.h:121
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY ListEntry
Definition: partlist.h:83
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:132
#define DPRINT
Definition: sndvol32.h:71

Referenced by ScrollDownPartitionList().

◆ GetNextUncheckedPartition()

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

Definition at line 4094 of file partlist.c.

4098 {
4099  PLIST_ENTRY Entry1, Entry2;
4100  PDISKENTRY DiskEntry;
4101  PPARTENTRY PartEntry;
4102 
4103  for (Entry1 = List->DiskListHead.Flink;
4104  Entry1 != &List->DiskListHead;
4105  Entry1 = Entry1->Flink)
4106  {
4107  DiskEntry = CONTAINING_RECORD(Entry1,
4108  DISKENTRY,
4109  ListEntry);
4110 
4111  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
4112  {
4113  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
4114  continue;
4115  }
4116 
4117  for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
4118  Entry2 != &DiskEntry->PrimaryPartListHead;
4119  Entry2 = Entry2->Flink)
4120  {
4121  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4122  if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
4123  {
4124  ASSERT(DiskEntry == PartEntry->DiskEntry);
4125  if (pDiskEntry) *pDiskEntry = DiskEntry;
4126  *pPartEntry = PartEntry;
4127  return TRUE;
4128  }
4129  }
4130 
4131  for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
4132  Entry2 != &DiskEntry->LogicalPartListHead;
4133  Entry2 = Entry2->Flink)
4134  {
4135  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4136  if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
4137  {
4138  ASSERT(DiskEntry == PartEntry->DiskEntry);
4139  if (pDiskEntry) *pDiskEntry = DiskEntry;
4140  *pPartEntry = PartEntry;
4141  return TRUE;
4142  }
4143  }
4144  }
4145 
4146  if (pDiskEntry) *pDiskEntry = NULL;
4147  *pPartEntry = NULL;
4148 
4149  return FALSE;
4150 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:131
#define TRUE
Definition: types.h:120
PARTITION_STYLE DiskStyle
Definition: partlist.h:121
#define FALSE
Definition: types.h:117
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _DISKENTRY * DiskEntry
Definition: partlist.h:46
#define ASSERT(a)
Definition: mode.c:44
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
BOOLEAN NeedsCheck
Definition: partlist.h:77
#define NULL
Definition: types.h:112
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:132
#define DPRINT
Definition: sndvol32.h:71
BOOLEAN IsPartitioned
Definition: partlist.h:66

Referenced by CheckFileSystemPage().

◆ GetNextUnformattedPartition()

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

Definition at line 4035 of file partlist.c.

4039 {
4040  PLIST_ENTRY Entry1, Entry2;
4041  PDISKENTRY DiskEntry;
4042  PPARTENTRY PartEntry;
4043 
4044  for (Entry1 = List->DiskListHead.Flink;
4045  Entry1 != &List->DiskListHead;
4046  Entry1 = Entry1->Flink)
4047  {
4048  DiskEntry = CONTAINING_RECORD(Entry1,
4049  DISKENTRY,
4050  ListEntry);
4051 
4052  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
4053  {
4054  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
4055  continue;
4056  }
4057 
4058  for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
4059  Entry2 != &DiskEntry->PrimaryPartListHead;
4060  Entry2 = Entry2->Flink)
4061  {
4062  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4063  if (PartEntry->IsPartitioned && PartEntry->New)
4064  {
4065  ASSERT(DiskEntry == PartEntry->DiskEntry);
4066  if (pDiskEntry) *pDiskEntry = DiskEntry;
4067  *pPartEntry = PartEntry;
4068  return TRUE;
4069  }
4070  }
4071 
4072  for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
4073  Entry2 != &DiskEntry->LogicalPartListHead;
4074  Entry2 = Entry2->Flink)
4075  {
4076  PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4077  if (PartEntry->IsPartitioned && PartEntry->New)
4078  {
4079  ASSERT(DiskEntry == PartEntry->DiskEntry);
4080  if (pDiskEntry) *pDiskEntry = DiskEntry;
4081  *pPartEntry = PartEntry;
4082  return TRUE;
4083  }
4084  }
4085  }
4086 
4087  if (pDiskEntry) *pDiskEntry = NULL;
4088  *pPartEntry = NULL;
4089 
4090  return FALSE;
4091 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:131
#define TRUE
Definition: types.h:120
PARTITION_STYLE DiskStyle
Definition: partlist.h:121
#define FALSE
Definition: types.h:117
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _DISKENTRY * DiskEntry
Definition: partlist.h:46
#define ASSERT(a)
Definition: mode.c:44
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
BOOLEAN New
Definition: partlist.h:71
#define NULL
Definition: types.h:112
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:132
#define DPRINT
Definition: sndvol32.h:71
BOOLEAN IsPartitioned
Definition: partlist.h:66

Referenced by SelectFileSystemPage().

◆ GetNextUnpartitionedEntry()

static PPARTENTRY GetNextUnpartitionedEntry ( IN PPARTENTRY  PartEntry)
static

Definition at line 2752 of file partlist.c.

2754 {
2755  PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2756  PPARTENTRY NextPartEntry;
2757  PLIST_ENTRY ListHead;
2758 
2759  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2760  {
2761  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2762  return NULL;
2763  }
2764 
2765  if (PartEntry->LogicalPartition)
2766  ListHead = &DiskEntry->LogicalPartListHead;
2767  else
2768  ListHead = &DiskEntry->PrimaryPartListHead;
2769 
2770  if (PartEntry->ListEntry.Flink != ListHead)
2771  {
2772  NextPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Flink,
2773  PARTENTRY,
2774  ListEntry);
2775  if (!NextPartEntry->IsPartitioned)
2776  {
2777  ASSERT(NextPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
2778  return NextPartEntry;
2779  }
2780  }
2781 
2782  return NULL;
2783 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:131
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
PARTITION_STYLE DiskStyle
Definition: partlist.h:121
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:53
#define ASSERT(a)
Definition: mode.c:44
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:132
#define DPRINT
Definition: sndvol32.h:71
BOOLEAN IsPartitioned
Definition: partlist.h:66

Referenced by DeletePartition().

◆ GetPartition()

PPARTENTRY GetPartition ( IN PDISKENTRY  DiskEntry,
IN ULONG  PartitionNumber 
)

Definition at line 2096 of file partlist.c.

2100 {
2101  PPARTENTRY PartEntry;
2103 
2104  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2105  {
2106  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2107  return NULL;
2108  }
2109 
2110  /* Disk found, loop over the primary partitions first... */
2111  for (Entry = DiskEntry->PrimaryPartListHead.Flink;
2112  Entry != &DiskEntry->PrimaryPartListHead;
2113  Entry = Entry->Flink)
2114  {
2115  PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2116 
2117  if (PartEntry->PartitionNumber == PartitionNumber)
2118  {
2119  /* Partition found */
2120  return PartEntry;
2121  }
2122  }
2123 
2124  /* ... then over the logical partitions if needed */
2125  for (Entry = DiskEntry->LogicalPartListHead.Flink;
2126  Entry != &DiskEntry->LogicalPartListHead;
2127  Entry = Entry->Flink)
2128  {
2129  PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2130 
2131  if (PartEntry->PartitionNumber == PartitionNumber)
2132  {
2133  /* Partition found */
2134  return PartEntry;
2135  }
2136  }
2137 
2138  /* The partition was not found on the disk, stop there */
2139  return NULL;
2140 }
ULONG PartitionNumber
Definition: partlist.h:55
struct _Entry Entry
Definition: kefuncs.h:627
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2060
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
#define DPRINT
Definition: sndvol32.h:71
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 2299 of file partlist.c.

2302 {
2303  PLIST_ENTRY DiskListEntry;
2304  PLIST_ENTRY PartListEntry;
2306 
2307  /* Fail if no disks are available */
2308  if (IsListEmpty(&List->DiskListHead))
2309  return NULL;
2310 
2311  /* Check for the previous usable entry on the current partition's disk */
2312  if (CurrentPart != NULL)
2313  {
2314  CurrentDisk = CurrentPart->DiskEntry;
2315 
2316  if (CurrentPart->LogicalPartition)
2317  {
2318  /* Logical partition */
2319 
2320  PartListEntry = CurrentPart->ListEntry.Blink;
2321  if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2322  {
2323  /* Previous logical partition */
2324  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2325  }
2326  else
2327  {
2328  /* Extended partition */
2329  CurrentPart = CurrentDisk->ExtendedPartition;
2330  }
2331  return CurrentPart;
2332  }
2333  else
2334  {
2335  /* Primary or extended partition */
2336 
2337  PartListEntry = CurrentPart->ListEntry.Blink;
2338  if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2339  {
2340  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2341 
2342  if (CurrentPart->IsPartitioned &&
2343  IsContainerPartition(CurrentPart->PartitionType))
2344  {
2345  PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2346  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2347  }
2348 
2349  return CurrentPart;
2350  }
2351  }
2352  }
2353 
2354  /* Search for the last partition entry on the previous disk */
2355  for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Blink
2356  : List->DiskListHead.Blink);
2357  DiskListEntry != &List->DiskListHead;
2358  DiskListEntry = DiskListEntry->Blink)
2359  {
2360  CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
2361 
2363  {
2364  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2365  continue;
2366  }
2367 
2368  PartListEntry = CurrentDisk->PrimaryPartListHead.Blink;
2369  if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2370  {
2371  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2372 
2373  if (CurrentPart->IsPartitioned &&
2374  IsContainerPartition(CurrentPart->PartitionType))
2375  {
2376  PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2377  if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2378  {
2379  CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2380  return CurrentPart;
2381  }
2382  }
2383  else
2384  {
2385  return CurrentPart;
2386  }
2387  }
2388  }
2389 
2390  return NULL;
2391 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:131
PDISKENTRY CurrentDisk
Definition: partlist.c:73
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:316
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
PPARTENTRY ExtendedPartition
Definition: partlist.h:135
PARTITION_STYLE DiskStyle
Definition: partlist.h:121
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
LIST_ENTRY ListEntry
Definition: partlist.h:83
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:132
#define DPRINT
Definition: sndvol32.h:71

Referenced by ScrollUpPartitionList().

◆ GetPrevUnpartitionedEntry()

static PPARTENTRY GetPrevUnpartitionedEntry ( IN PPARTENTRY  PartEntry)
static

Definition at line 2717 of file partlist.c.

2719 {
2720  PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2721  PPARTENTRY PrevPartEntry;
2722  PLIST_ENTRY ListHead;
2723 
2724  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2725  {
2726  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2727  return NULL;
2728  }
2729 
2730  if (PartEntry->LogicalPartition)
2731  ListHead = &DiskEntry->LogicalPartListHead;
2732  else
2733  ListHead = &DiskEntry->PrimaryPartListHead;
2734 
2735  if (PartEntry->ListEntry.Blink != ListHead)
2736  {
2737  PrevPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Blink,
2738  PARTENTRY,
2739  ListEntry);
2740  if (!PrevPartEntry->IsPartitioned)
2741  {
2742  ASSERT(PrevPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
2743  return PrevPartEntry;
2744  }
2745  }
2746 
2747  return NULL;
2748 }
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:131
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
PARTITION_STYLE DiskStyle
Definition: partlist.h:121
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:53
#define ASSERT(a)
Definition: mode.c:44
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:132
#define DPRINT
Definition: sndvol32.h:71
BOOLEAN IsPartitioned
Definition: partlist.h:66

Referenced by DeletePartition().

◆ GetPrimaryPartitionCount()

static ULONG GetPrimaryPartitionCount ( IN PDISKENTRY  DiskEntry)
static

Definition at line 2428 of file partlist.c.

2430 {
2432  PPARTENTRY PartEntry;
2433  ULONG Count = 0;
2434 
2435  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2436  {
2437  DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2438  return 0;
2439  }
2440 
2441  for (Entry = DiskEntry->PrimaryPartListHead.Flink;
2442  Entry != &DiskEntry->PrimaryPartListHead;
2443  Entry = Entry->Flink)
2444  {
2445  PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2446  if (PartEntry->IsPartitioned)
2447  Count++;
2448  }
2449 
2450  return Count;
2451 }
struct _Entry Entry
Definition: kefuncs.h:627
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
int Count
Definition: noreturn.cpp:7
Definition: typedefs.h:119
unsigned int ULONG
Definition: retypes.h:1
#define DPRINT
Definition: sndvol32.h:71
base of all file and directory entries
Definition: entries.h:82
BOOLEAN IsPartitioned
Definition: partlist.h:66

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

◆ GetSystemDisk()

static PDISKENTRY GetSystemDisk ( IN PPARTLIST  List)
static

Definition at line 1718 of file partlist.c.

1720 {
1722  PDISKENTRY DiskEntry;
1723 
1724  /* Check for empty disk list */
1725  if (IsListEmpty(&List->DiskListHead))
1726  return NULL;
1727 
1728  /*
1729  * If we already have a system partition, the system disk
1730  * is the one on which the system partition resides.
1731  */
1732  if (List->SystemPartition)
1733  return List->SystemPartition->DiskEntry;
1734 
1735  /* Loop over the disks and find the correct one */
1736  for (Entry = List->DiskListHead.Flink;
1737  Entry != &List->DiskListHead;
1738  Entry = Entry->Flink)
1739  {
1740  DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
1741 
1742  /* The disk must be a fixed disk and be found by the firmware */
1743  if (DiskEntry->MediaType == FixedMedia && DiskEntry->BiosFound)
1744  {
1745  break;
1746  }
1747  }
1748  if (Entry == &List->DiskListHead)
1749  {
1750  /* We haven't encountered any suitable disk */
1751  return NULL;
1752  }
1753 
1754  if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1755  {
1756  DPRINT1("System disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
1757  }
1758 
1759  return DiskEntry;
1760 }
struct _Entry Entry
Definition: kefuncs.h:627
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
PARTITION_STYLE DiskStyle
Definition: partlist.h:121
MEDIA_TYPE MediaType
Definition: partlist.h:88
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
BOOLEAN BiosFound
Definition: partlist.h:102
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
base of all file and directory entries
Definition: entries.h:82

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

◆ InitializePartitionEntry()

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

Definition at line 678 of file partlist.c.

682 {
683  PDISKENTRY DiskEntry = PartEntry->DiskEntry;
684 
685  DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart);
686 
687  /* Fail if we try to initialize this partition entry with more sectors than what it actually contains */
688  if (SectorCount > PartEntry->SectorCount.QuadPart)
689  return FALSE;
690 
691  /* Fail if the partition is already in use */
692  ASSERT(!PartEntry->IsPartitioned);
693 
694  if ((AutoCreate != FALSE) ||
695  (AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) -
696  PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart))
697  {
698  PartEntry->AutoCreate = AutoCreate;
699  }
700  else
701  {
702  ULONGLONG StartSector;
703  ULONGLONG SectorCount2;
704  PPARTENTRY NewPartEntry;
705 
706  /* Create a partition entry that represents the remaining space after the partition to be initialized */
707 
708  StartSector = AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment);
709  SectorCount2 = PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - StartSector;
710 
711  NewPartEntry = CreateInsertBlankRegion(DiskEntry,
712  PartEntry->ListEntry.Flink,
713  StartSector,
714  SectorCount2,
715  PartEntry->LogicalPartition);
716  if (NewPartEntry == NULL)
717  {
718  DPRINT1("Failed to create a new empty region for disk space!\n");
719  return FALSE;
720  }
721 
722  /* Resize down the partition entry; its StartSector remains the same */
723  PartEntry->SectorCount.QuadPart = StartSector - PartEntry->StartSector.QuadPart;
724  }
725 
726  /* Convert the partition entry to 'New (Unformatted)' */
727  PartEntry->New = TRUE;
728  PartEntry->IsPartitioned = TRUE;
729 
730 // FIXME: Use FileSystemToMBRPartitionType() only for MBR, otherwise use PARTITION_BASIC_DATA_GUID.
731  PartEntry->PartitionType = FileSystemToMBRPartitionType(L"RAW",
732  PartEntry->StartSector.QuadPart,
733  PartEntry->SectorCount.QuadPart);
734  ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
735 
736  PartEntry->FormatState = Unformatted;
737  PartEntry->FileSystem[0] = L'\0';
738  // PartEntry->AutoCreate = AutoCreate;
739  PartEntry->BootIndicator = FALSE;
740 
741  DPRINT1("First Sector : %I64u\n", PartEntry->StartSector.QuadPart);
742  DPRINT1("Last Sector : %I64u\n", PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1);
743  DPRINT1("Total Sectors: %I64u\n", PartEntry->SectorCount.QuadPart);
744 
745  return TRUE;
746 }
#define TRUE
Definition: types.h:120
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
#define FALSE
Definition: types.h:117
ULONG SectorAlignment
Definition: partlist.h:98
static PPARTENTRY CreateInsertBlankRegion(IN PDISKENTRY DiskEntry, IN OUT PLIST_ENTRY ListHead, IN ULONGLONG StartSector, IN ULONGLONG SectorCount, IN BOOLEAN LogicalSpace)
Definition: partlist.c:640
#define ASSERT(a)
Definition: mode.c:44
uint64_t ULONGLONG
Definition: typedefs.h:67
UCHAR FileSystemToMBRPartitionType(IN PCWSTR FileSystem, IN ULONGLONG StartSector, IN ULONGLONG SectorCount)
Definition: fsrec.c:333
ULONGLONG AlignDown(IN ULONGLONG Value, IN ULONG Alignment)
Definition: partlist.c:67
static const WCHAR L[]
Definition: oid.c:1250
ULONG SectorCount
Definition: part_xbox.c:31
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8

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

◆ InsertDiskRegion()

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

Definition at line 574 of file partlist.c.

578 {
581  PPARTENTRY PartEntry2;
582 
583  /* Use the correct partition list */
584  if (LogicalPartition)
585  List = &DiskEntry->LogicalPartListHead;
586  else
587  List = &DiskEntry->PrimaryPartListHead;
588 
589  /* Find the first disk region before which we need to insert the new one */
590  for (Entry = List->Flink; Entry != List; Entry = Entry->Flink)
591  {
592  PartEntry2 = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
593 
594  /* Ignore any unused empty region */
595  if ((PartEntry2->PartitionType == PARTITION_ENTRY_UNUSED &&
596  PartEntry2->StartSector.QuadPart == 0) || PartEntry2->SectorCount.QuadPart == 0)
597  {
598  continue;
599  }
600 
601  /* If the current region ends before the one to be inserted, try again */
602  if (PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1 < PartEntry->StartSector.QuadPart)
603  continue;
604 
605  /*
606  * One of the disk region boundaries crosses the desired region
607  * (it starts after the desired region, or ends before the end
608  * of the desired region): this is an impossible situation because
609  * disk regions (partitions) cannot overlap!
610  * Throw an error and bail out.
611  */
612  if (max(PartEntry->StartSector.QuadPart, PartEntry2->StartSector.QuadPart)
613  <=
614  min( PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1,
615  PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1))
616  {
617  DPRINT1("Disk region overlap problem, stopping there!\n"
618  "Partition to be inserted:\n"
619  " StartSector = %I64u ; EndSector = %I64u\n"
620  "Existing disk region:\n"
621  " StartSector = %I64u ; EndSector = %I64u\n",
622  PartEntry->StartSector.QuadPart,
623  PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1,
624  PartEntry2->StartSector.QuadPart,
625  PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1);
626  return FALSE;
627  }
628 
629  /* We have found the first region before which the new one has to be inserted */
630  break;
631  }
632 
633  /* Insert the disk region */
634  InsertTailList(Entry, &PartEntry->ListEntry);
635  return TRUE;
636 }
#define max(a, b)
Definition: svc.c:63
ULARGE_INTEGER StartSector
Definition: partlist.h:49
struct _Entry Entry
Definition: kefuncs.h:627
#define TRUE
Definition: types.h:120
ULARGE_INTEGER SectorCount
Definition: partlist.h:50
#define InsertTailList(ListHead, Entry)
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define FALSE
Definition: types.h:117
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
UCHAR PartitionType
Definition: partlist.h:53
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
#define min(a, b)
Definition: monoChain.cc:55
#define DPRINT1
Definition: precomp.h:8
base of all file and directory entries
Definition: entries.h:82

Referenced by AddPartitionToDisk().

◆ IsEmptyLayoutEntry()

FORCEINLINE BOOLEAN IsEmptyLayoutEntry ( IN PPARTITION_INFORMATION  PartitionInfo)

Definition at line 2396 of file partlist.c.

2398 {
2399  if (PartitionInfo->StartingOffset.QuadPart == 0 &&
2400  PartitionInfo->PartitionLength.QuadPart == 0)
2401  {
2402  return TRUE;
2403  }
2404 
2405  return FALSE;
2406 }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2105

Referenced by UpdateDiskLayout().

◆ IsPartitionActive()

BOOLEAN IsPartitionActive ( IN PPARTENTRY  PartEntry)

Definition at line 1768 of file partlist.c.

1770 {
1771  // TODO: Support for GPT disks!
1772 
1773  if (IsContainerPartition(PartEntry->PartitionType))
1774  return FALSE;
1775 
1776  /* Check if the partition is partitioned, used and active */
1777  if (PartEntry->IsPartitioned &&
1778  // !IsContainerPartition(PartEntry->PartitionType) &&
1779  PartEntry->BootIndicator)
1780  {
1781  /* Yes it is */
1782  ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
1783  return TRUE;
1784  }
1785 
1786  return FALSE;
1787 }
#define TRUE
Definition: types.h:120
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:316
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
#define FALSE
Definition: types.h:117
#define ASSERT(a)
Definition: mode.c:44

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

◆ IsSamePrimaryLayoutEntry()

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

Definition at line 2411 of file partlist.c.

2415 {
2416  if (PartitionInfo->StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector &&
2417  PartitionInfo->PartitionLength.QuadPart == PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector)
2418 // PartitionInfo->PartitionType == PartEntry->PartitionType
2419  {
2420  return TRUE;
2421  }
2422 
2423  return FALSE;
2424 }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2105

Referenced by UpdateDiskLayout().

◆ IsSuperFloppy()

BOOLEAN IsSuperFloppy ( IN PDISKENTRY  DiskEntry)

Definition at line 501 of file partlist.c.

503 {
505  ULONGLONG PartitionLengthEstimate;
506 
507  /* No layout buffer: we cannot say anything yet */
508  if (DiskEntry->LayoutBuffer == NULL)
509  return FALSE;
510 
511  /* We must have only one partition */
512  if (DiskEntry->LayoutBuffer->PartitionCount != 1)
513  return FALSE;
514 
515  /* Get the single partition entry */
516  PartitionInfo = DiskEntry->LayoutBuffer->PartitionEntry;
517 
518  /* The single partition must start at the beginning of the disk */
519  if (!(PartitionInfo->StartingOffset.QuadPart == 0 &&
520  PartitionInfo->HiddenSectors == 0))
521  {
522  return FALSE;
523  }
524 
525  /* The disk signature is usually set to one; warn in case it's not */
526  if (DiskEntry->LayoutBuffer->Signature != 1)
527  {
528  DPRINT1("Super-Floppy disk %lu signature %08x != 1!\n",
529  DiskEntry->DiskNumber, DiskEntry->LayoutBuffer->Signature);
530  }
531 
532  /*
533  * The partition number must be zero or one, be recognized,
534  * have FAT16 type and report as non-bootable.
535  */
536  if ((PartitionInfo->PartitionNumber != 0 &&
537  PartitionInfo->PartitionNumber != 1) ||
538  PartitionInfo->RecognizedPartition != TRUE ||
539  PartitionInfo->PartitionType != PARTITION_FAT_16 ||
540  PartitionInfo->BootIndicator != FALSE)
541  {
542  DPRINT1("Super-Floppy disk %lu does not return default settings!\n"
543  " PartitionNumber = %lu, expected 0\n"
544  " RecognizedPartition = %s, expected TRUE\n"
545  " PartitionType = 0x%02x, expected 0x04 (PARTITION_FAT_16)\n"
546  " BootIndicator = %s, expected FALSE\n",
547  DiskEntry->DiskNumber,
548  PartitionInfo->PartitionNumber,
549  PartitionInfo->RecognizedPartition ? "TRUE" : "FALSE",
550  PartitionInfo->PartitionType,
551  PartitionInfo->BootIndicator ? "TRUE" : "FALSE");
552  }
553 
554  /* The partition lengths should agree */
555  PartitionLengthEstimate = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
556  if (PartitionInfo->PartitionLength.QuadPart != PartitionLengthEstimate)
557  {
558  DPRINT1("PartitionLength = %I64u is different from PartitionLengthEstimate = %I64u\n",
559  PartitionInfo->PartitionLength.QuadPart, PartitionLengthEstimate);
560  }
561 
562  return TRUE;
563 }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
uint64_t ULONGLONG
Definition: typedefs.h:67
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2105
#define PARTITION_FAT_16
Definition: disk.h:90
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8

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

◆ IsSupportedActivePartition()

static BOOLEAN IsSupportedActivePartition ( IN PPARTENTRY  PartEntry)
static

Definition at line 3180 of file partlist.c.

3182 {
3183  /* Check the type and the file system of this partition */
3184 
3185  /*
3186  * We do not support extended partition containers (on MBR disks) marked
3187  * as active, and containing code inside their extended boot records.
3188  */
3189  if (IsContainerPartition(PartEntry->PartitionType))
3190  {
3191  DPRINT1("System partition %lu in disk %lu is an extended partition container?!\n",
3192  PartEntry->PartitionNumber, PartEntry->DiskEntry->DiskNumber);
3193  return FALSE;
3194  }
3195 
3196  /*
3197  * ADDITIONAL CHECKS / BIG HACK:
3198  *
3199  * Retrieve its file system and check whether we have
3200  * write support for it. If that is the case we are fine
3201  * and we can use it directly. However if we don't have
3202  * write support we will need to change the active system
3203  * partition.
3204  *
3205  * NOTE that this is completely useless on architectures
3206  * where a real system partition is required, as on these
3207  * architectures the partition uses the FAT FS, for which
3208  * we do have write support.
3209  * NOTE also that for those architectures looking for a
3210  * partition boot indicator is insufficient.
3211  */
3212  if (PartEntry->FormatState == Unformatted)
3213  {
3214  /* If this partition is mounted, it would use RawFS ("RAW") */
3215  return TRUE;
3216  }
3217  else if ((PartEntry->FormatState == Preformatted) ||
3218  (PartEntry->FormatState == Formatted))
3219  {
3220  ASSERT(*PartEntry->FileSystem);
3221 
3222  /* NOTE: Please keep in sync with the RegisteredFileSystems list! */
3223  if (wcsicmp(PartEntry->FileSystem, L"FAT") == 0 ||
3224  wcsicmp(PartEntry->FileSystem, L"FAT32") == 0 ||
3225  // wcsicmp(PartEntry->FileSystem, L"NTFS") == 0 ||
3226  wcsicmp(PartEntry->FileSystem, L"BTRFS") == 0)
3227  {
3228  return TRUE;
3229  }
3230  else
3231  {
3232  // WARNING: We cannot write on this FS yet!
3233  DPRINT1("Recognized file system '%S' that doesn't have write support yet!\n",
3234  PartEntry->FileSyst