ReactOS 0.4.15-dev-8417-gb6b82fe
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"
 
#define GetPrimaryPartitionCount(DiskEntry)    GetPartitionCount(&(DiskEntry)->PrimaryPartListHead)
 
#define GetLogicalPartitionCount(DiskEntry)
 

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 VOID AddLogicalDiskSpace (_In_ PDISKENTRY DiskEntry)
 
static BOOLEAN InitializePartitionEntry (_Inout_ PPARTENTRY PartEntry, _In_opt_ ULONGLONG SizeBytes, _In_opt_ ULONG_PTR PartitionInfo)
 
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)
 
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)
 
static BOOLEAN IsEmptyLayoutEntry (_In_ PPARTITION_INFORMATION PartitionInfo)
 
static BOOLEAN IsSamePrimaryLayoutEntry (_In_ PPARTITION_INFORMATION PartitionInfo, _In_ PPARTENTRY PartEntry)
 
static ULONG GetPartitionCount (_In_ PLIST_ENTRY PartListHead)
 Counts the number of partitioned disk regions in a given partition list.
 
static BOOLEAN ReAllocateLayoutBuffer (IN PDISKENTRY DiskEntry)
 
static VOID UpdateDiskLayout (IN PDISKENTRY DiskEntry)
 
static PPARTENTRY GetAdjUnpartitionedEntry (_In_ PPARTENTRY PartEntry, _In_ BOOLEAN Direction)
 Retrieves, if any, the unpartitioned disk region that is adjacent (next or previous) to the specified partition.
 
ERROR_NUMBER PartitionCreationChecks (_In_ PPARTENTRY PartEntry)
 
ERROR_NUMBER ExtendedPartitionCreationChecks (_In_ PPARTENTRY PartEntry)
 
BOOLEAN CreatePartition (_In_ PPARTLIST List, _Inout_ PPARTENTRY PartEntry, _In_opt_ ULONGLONG SizeBytes, _In_opt_ ULONG_PTR PartitionInfo)
 
NTSTATUS DismountVolume (IN PPARTENTRY PartEntry)
 
BOOLEAN DeletePartition (_In_ PPARTLIST List, _In_ PPARTENTRY PartEntry, _Out_opt_ PPARTENTRY *FreeRegion)
 
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)
 

Macro Definition Documentation

◆ GetLogicalPartitionCount

#define GetLogicalPartitionCount (   DiskEntry)
Value:
(((DiskEntry)->DiskStyle == PARTITION_STYLE_MBR) \
? GetPartitionCount(&(DiskEntry)->LogicalPartListHead) : 0)
@ PARTITION_STYLE_MBR
Definition: imports.h:201
static ULONG GetPartitionCount(_In_ PLIST_ENTRY PartListHead)
Counts the number of partitioned disk regions in a given partition list.
Definition: partlist.c:2442

Definition at line 2464 of file partlist.c.

◆ GetPrimaryPartitionCount

#define GetPrimaryPartitionCount (   DiskEntry)     GetPartitionCount(&(DiskEntry)->PrimaryPartListHead)

Definition at line 2461 of file partlist.c.

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

1386{
1387 DISK_GEOMETRY DiskGeometry;
1388 SCSI_ADDRESS ScsiAddress;
1389 PDISKENTRY DiskEntry;
1393 PULONG Buffer;
1395 WCHAR Identifier[20];
1396 ULONG Checksum;
1398 ULONG i;
1399 PLIST_ENTRY ListEntry;
1400 PBIOSDISKENTRY BiosDiskEntry;
1401 ULONG LayoutBufferSize;
1402 PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
1403
1404 /* Retrieve the drive geometry */
1406 NULL,
1407 NULL,
1408 NULL,
1409 &Iosb,
1411 NULL,
1412 0,
1413 &DiskGeometry,
1414 sizeof(DiskGeometry));
1415 if (!NT_SUCCESS(Status))
1416 return;
1417
1418 if (DiskGeometry.MediaType != FixedMedia &&
1419 DiskGeometry.MediaType != RemovableMedia)
1420 {
1421 return;
1422 }
1423
1424 /*
1425 * FIXME: Here we suppose the disk is always SCSI. What if it is
1426 * of another type? To check this we need to retrieve the name of
1427 * the driver the disk device belongs to.
1428 */
1430 NULL,
1431 NULL,
1432 NULL,
1433 &Iosb,
1435 NULL,
1436 0,
1437 &ScsiAddress,
1438 sizeof(ScsiAddress));
1439 if (!NT_SUCCESS(Status))
1440 return;
1441
1442 /*
1443 * Check whether the disk is initialized, by looking at its MBR.
1444 * NOTE that this must be generalized to GPT disks as well!
1445 */
1446
1448 0,
1449 DiskGeometry.BytesPerSector);
1450 if (Mbr == NULL)
1451 return;
1452
1453 FileOffset.QuadPart = 0;
1455 NULL,
1456 NULL,
1457 NULL,
1458 &Iosb,
1459 (PVOID)Mbr,
1460 DiskGeometry.BytesPerSector,
1461 &FileOffset,
1462 NULL);
1463 if (!NT_SUCCESS(Status))
1464 {
1465 RtlFreeHeap(ProcessHeap, 0, Mbr);
1466 DPRINT1("NtReadFile failed, status=%x\n", Status);
1467 return;
1468 }
1469 Signature = Mbr->Signature;
1470
1471 /* Calculate the MBR checksum */
1472 Checksum = 0;
1473 Buffer = (PULONG)Mbr;
1474 for (i = 0; i < 128; i++)
1475 {
1476 Checksum += Buffer[i];
1477 }
1478 Checksum = ~Checksum + 1;
1479
1481 L"%08x-%08x-%c",
1482 Checksum, Signature,
1483 (Mbr->Magic == PARTITION_MAGIC) ? L'A' : L'X');
1484 DPRINT("Identifier: %S\n", Identifier);
1485
1486 DiskEntry = RtlAllocateHeap(ProcessHeap,
1488 sizeof(DISKENTRY));
1489 if (DiskEntry == NULL)
1490 {
1491 RtlFreeHeap(ProcessHeap, 0, Mbr);
1492 DPRINT1("Failed to allocate a new disk entry.\n");
1493 return;
1494 }
1495
1496 DiskEntry->PartList = List;
1497
1498#if 0
1499 {
1500 FILE_FS_DEVICE_INFORMATION FileFsDevice;
1501
1502 /* Query the device for its type */
1504 &Iosb,
1505 &FileFsDevice,
1506 sizeof(FileFsDevice),
1508 if (!NT_SUCCESS(Status))
1509 {
1510 DPRINT1("Couldn't detect device type for disk %lu of identifier '%S'...\n", DiskNumber, Identifier);
1511 }
1512 else
1513 {
1514 DPRINT1("Disk %lu : DeviceType: 0x%08x ; Characteristics: 0x%08x\n", DiskNumber, FileFsDevice.DeviceType, FileFsDevice.Characteristics);
1515 }
1516 }
1517 // NOTE: We may also use NtQueryVolumeInformationFile(FileFsDeviceInformation).
1518#endif
1519 DiskEntry->MediaType = DiskGeometry.MediaType;
1520 if (DiskEntry->MediaType == RemovableMedia)
1521 {
1522 DPRINT1("Disk %lu of identifier '%S' is removable\n", DiskNumber, Identifier);
1523 }
1524 else // if (DiskEntry->MediaType == FixedMedia)
1525 {
1526 DPRINT1("Disk %lu of identifier '%S' is fixed\n", DiskNumber, Identifier);
1527 }
1528
1529// DiskEntry->Checksum = Checksum;
1530// DiskEntry->Signature = Signature;
1531 DiskEntry->BiosFound = FALSE;
1532
1533 /*
1534 * Check if this disk has a valid MBR: verify its signature,
1535 * and whether its two first bytes are a valid instruction
1536 * (related to this, see IsThereAValidBootSector() in partlist.c).
1537 *
1538 * See also ntoskrnl/fstub/fstubex.c!FstubDetectPartitionStyle().
1539 */
1540
1541 // DiskEntry->NoMbr = (Mbr->Magic != PARTITION_MAGIC || (*(PUSHORT)Mbr->BootCode) == 0x0000);
1542
1543 /* If we have not the 0xAA55 then it's raw partition */
1544 if (Mbr->Magic != PARTITION_MAGIC)
1545 {
1546 DiskEntry->DiskStyle = PARTITION_STYLE_RAW;
1547 }
1548 /* Check partitions types: if first is 0xEE and all the others 0, we have GPT */
1549 else if (Mbr->Partition[0].PartitionType == EFI_PMBR_OSTYPE_EFI &&
1550 Mbr->Partition[1].PartitionType == 0 &&
1551 Mbr->Partition[2].PartitionType == 0 &&
1552 Mbr->Partition[3].PartitionType == 0)
1553 {
1554 DiskEntry->DiskStyle = PARTITION_STYLE_GPT;
1555 }
1556 /* Otherwise, partition table is in MBR */
1557 else
1558 {
1559 DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
1560 }
1561
1562 /* Free the MBR sector buffer */
1563 RtlFreeHeap(ProcessHeap, 0, Mbr);
1564
1565
1566 for (ListEntry = List->BiosDiskListHead.Flink;
1567 ListEntry != &List->BiosDiskListHead;
1568 ListEntry = ListEntry->Flink)
1569 {
1570 BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
1571 /* FIXME:
1572 * Compare the size from bios and the reported size from driver.
1573 * If we have more than one disk with a zero or with the same signature
1574 * we must create new signatures and reboot. After the reboot,
1575 * it is possible to identify the disks.
1576 */
1577 if (BiosDiskEntry->Signature == Signature &&
1578 BiosDiskEntry->Checksum == Checksum &&
1579 BiosDiskEntry->DiskEntry == NULL)
1580 {
1581 if (!DiskEntry->BiosFound)
1582 {
1583 DiskEntry->HwAdapterNumber = BiosDiskEntry->AdapterNumber;
1584 DiskEntry->HwControllerNumber = BiosDiskEntry->ControllerNumber;
1585 DiskEntry->HwDiskNumber = BiosDiskEntry->DiskNumber;
1586
1587 if (DiskEntry->MediaType == RemovableMedia)
1588 {
1589 /* Set the removable disk number to zero */
1590 DiskEntry->HwFixedDiskNumber = 0;
1591 }
1592 else // if (DiskEntry->MediaType == FixedMedia)
1593 {
1594 /* The fixed disk number will later be adjusted using the number of removable disks */
1595 DiskEntry->HwFixedDiskNumber = BiosDiskEntry->DiskNumber;
1596 }
1597
1598 DiskEntry->BiosFound = TRUE;
1599 BiosDiskEntry->DiskEntry = DiskEntry;
1600 break;
1601 }
1602 else
1603 {
1604 // FIXME: What to do?
1605 DPRINT1("Disk %lu of identifier '%S' has already been found?!\n", DiskNumber, Identifier);
1606 }
1607 }
1608 }
1609
1610 if (!DiskEntry->BiosFound)
1611 {
1612 DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %lu may not be bootable by the BIOS!\n", DiskNumber);
1613 }
1614
1615 DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
1616 DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
1617 DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
1618 DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
1619
1620 DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders);
1621 DPRINT("TracksPerCylinder %lu\n", DiskEntry->TracksPerCylinder);
1622 DPRINT("SectorsPerTrack %lu\n", DiskEntry->SectorsPerTrack);
1623 DPRINT("BytesPerSector %lu\n", DiskEntry->BytesPerSector);
1624
1625 DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart *
1626 (ULONGLONG)DiskGeometry.TracksPerCylinder *
1627 (ULONGLONG)DiskGeometry.SectorsPerTrack;
1628
1629 DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
1630 DiskEntry->CylinderAlignment = DiskGeometry.TracksPerCylinder *
1631 DiskGeometry.SectorsPerTrack;
1632
1633 DPRINT("SectorCount %I64u\n", DiskEntry->SectorCount.QuadPart);
1634 DPRINT("SectorAlignment %lu\n", DiskEntry->SectorAlignment);
1635
1636 DiskEntry->DiskNumber = DiskNumber;
1637 DiskEntry->Port = ScsiAddress.PortNumber;
1638 DiskEntry->Bus = ScsiAddress.PathId;
1639 DiskEntry->Id = ScsiAddress.TargetId;
1640
1641 GetDriverName(DiskEntry);
1642 /*
1643 * Actually it would be more correct somehow to use:
1644 *
1645 * OBJECT_NAME_INFORMATION NameInfo; // ObjectNameInfo;
1646 * ULONG ReturnedLength;
1647 *
1648 * Status = NtQueryObject(SomeHandleToTheDisk,
1649 * ObjectNameInformation,
1650 * &NameInfo,
1651 * sizeof(NameInfo),
1652 * &ReturnedLength);
1653 * etc...
1654 *
1655 * See examples in https://git.reactos.org/?p=reactos.git;a=blob;f=reactos/ntoskrnl/io/iomgr/error.c;hb=2f3a93ee9cec8322a86bf74b356f1ad83fc912dc#l267
1656 */
1657
1660
1661 InsertAscendingList(&List->DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber);
1662
1663
1664 /*
1665 * We now retrieve the disk partition layout
1666 */
1667
1668 /*
1669 * Stop there now if the disk is GPT-partitioned,
1670 * since we currently do not support such disks.
1671 */
1672 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1673 {
1674 DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1675 return;
1676 }
1677
1678 /* Allocate a layout buffer with 4 partition entries first */
1679 LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
1680 ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
1683 LayoutBufferSize);
1684 if (DiskEntry->LayoutBuffer == NULL)
1685 {
1686 DPRINT1("Failed to allocate the disk layout buffer!\n");
1687 return;
1688 }
1689
1690 /* Keep looping while the drive layout buffer is too small */
1691 for (;;)
1692 {
1693 DPRINT1("Buffer size: %lu\n", LayoutBufferSize);
1695 NULL,
1696 NULL,
1697 NULL,
1698 &Iosb,
1700 NULL,
1701 0,
1702 DiskEntry->LayoutBuffer,
1703 LayoutBufferSize);
1704 if (NT_SUCCESS(Status))
1705 break;
1706
1708 {
1709 DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status);
1710 return;
1711 }
1712
1713 LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION);
1714 NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap,
1716 DiskEntry->LayoutBuffer,
1717 LayoutBufferSize);
1718 if (NewLayoutBuffer == NULL)
1719 {
1720 DPRINT1("Failed to reallocate the disk layout buffer!\n");
1721 return;
1722 }
1723
1724 DiskEntry->LayoutBuffer = NewLayoutBuffer;
1725 }
1726
1727 DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount);
1728
1729#ifdef DUMP_PARTITION_TABLE
1730 DumpPartitionTable(DiskEntry);
1731#endif
1732
1733 if (IsSuperFloppy(DiskEntry))
1734 DPRINT1("Disk %lu is a super-floppy\n", DiskNumber);
1735
1736 if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
1739 {
1740 if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
1741 {
1742 DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
1743 }
1744 else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
1745 {
1746 DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1747 }
1748 else
1749 {
1750 DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
1751 }
1752 }
1753 else
1754 {
1755 DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1756 }
1757
1758 if (DiskEntry->LayoutBuffer->PartitionCount == 0)
1759 {
1760 DiskEntry->NewDisk = TRUE;
1761 DiskEntry->LayoutBuffer->PartitionCount = 4;
1762
1763 for (i = 0; i < 4; i++)
1764 {
1766 }
1767 }
1768 else
1769 {
1770 /* Enumerate and add the first four primary partitions */
1771 for (i = 0; i < 4; i++)
1772 {
1773 AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
1774 }
1775
1776 /* Enumerate and add the remaining partitions as logical ones */
1777 for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
1778 {
1779 AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
1780 }
1781 }
1782
1784}
@ Identifier
Definition: asmpp.cpp:95
LONG NTSTATUS
Definition: precomp.h:26
HANDLE ProcessHeap
Definition: servman.c:15
#define DPRINT1
Definition: precomp.h:8
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static const WCHAR Signature[]
Definition: parser.c:141
return Iosb
Definition: create.c:4402
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
@ FileFsDeviceInformation
Definition: from_kernel.h:222
Status
Definition: gdiplustypes.h:25
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
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2686
#define EFI_PMBR_OSTYPE_EFI
Definition: partlist.h:172
#define PARTITION_MAGIC
Definition: partlist.h:169
@ PARTITION_STYLE_GPT
Definition: imports.h:202
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)
#define IOCTL_DISK_GET_DRIVE_LAYOUT
Definition: ntdddisk.h:91
struct _PARTITION_INFORMATION PARTITION_INFORMATION
@ RemovableMedia
Definition: ntdddisk.h:382
@ FixedMedia
Definition: ntdddisk.h:383
struct _DRIVE_LAYOUT_INFORMATION DRIVE_LAYOUT_INFORMATION
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
#define L(x)
Definition: ntvdm.h:50
#define IOCTL_SCSI_GET_ADDRESS
Definition: scsi_port.h:52
static VOID AddPartitionToDisk(IN ULONG DiskNumber, IN PDISKENTRY DiskEntry, IN ULONG PartitionIndex, IN BOOLEAN LogicalPartition)
Definition: partlist.c:841
static VOID GetDriverName(IN PDISKENTRY DiskEntry)
Definition: partlist.c:105
BOOLEAN IsSuperFloppy(IN PDISKENTRY DiskEntry)
Definition: partlist.c:501
static VOID ScanForUnpartitionedDiskSpace(IN PDISKENTRY DiskEntry)
Definition: partlist.c:1032
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
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)
#define DPRINT
Definition: sndvol32.h:73
ULONG AdapterNumber
Definition: partlist.h:139
ULONG ControllerNumber
Definition: partlist.h:140
ULONG DiskNumber
Definition: partlist.h:141
ULONG Checksum
Definition: partlist.h:143
ULONG Signature
Definition: partlist.h:142
PDISKENTRY DiskEntry
Definition: partlist.h:144
ULONG HwAdapterNumber
Definition: partlist.h:100
ULONG SectorAlignment
Definition: partlist.h:95
ULARGE_INTEGER SectorCount
Definition: partlist.h:94
ULONG HwControllerNumber
Definition: partlist.h:101
ULONG HwDiskNumber
Definition: partlist.h:102
ULONG SectorsPerTrack
Definition: partlist.h:91
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:129
struct _PARTLIST * PartList
Definition: partlist.h:83
BOOLEAN NewDisk
Definition: partlist.h:117
ULONG DiskNumber
Definition: partlist.h:108
ULONG BytesPerSector
Definition: partlist.h:92
BOOLEAN BiosFound
Definition: partlist.h:99
ULONGLONG Cylinders
Definition: partlist.h:89
USHORT Bus
Definition: partlist.h:111
USHORT Id
Definition: partlist.h:112
USHORT Port
Definition: partlist.h:110
PARTITION_STYLE DiskStyle
Definition: partlist.h:118
ULONG TracksPerCylinder
Definition: partlist.h:90
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:128
MEDIA_TYPE MediaType
Definition: partlist.h:85
ULONG HwFixedDiskNumber
Definition: partlist.h:103
ULONG CylinderAlignment
Definition: partlist.h:96
PDRIVE_LAYOUT_INFORMATION LayoutBuffer
Definition: partlist.h:122
MEDIA_TYPE MediaType
Definition: ntdddisk.h:401
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:400
ULONG TracksPerCylinder
Definition: ntdddisk.h:402
ULONG SectorsPerTrack
Definition: ntdddisk.h:403
ULONG BytesPerSector
Definition: ntdddisk.h:404
PARTITION_INFORMATION PartitionEntry[1]
Definition: ntdddisk.h:421
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:408
LARGE_INTEGER PartitionLength
Definition: ntdddisk.h:409
BOOLEAN RewritePartition
Definition: ntdddisk.h:415
PARTITION Partition[PARTITION_TBL_SIZE]
Definition: partlist.h:195
unsigned char PartitionType
Definition: partlist.h:182
UCHAR PathId
Definition: scsi_port.h:149
UCHAR TargetId
Definition: scsi_port.h:150
UCHAR PortNumber
Definition: scsi_port.h:148
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
uint32_t * PULONG
Definition: typedefs.h:59
#define ANYSIZE_ARRAY
Definition: typedefs.h:46
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by CreatePartitionList().

◆ AddLogicalDiskSpace()

static VOID AddLogicalDiskSpace ( _In_ PDISKENTRY  DiskEntry)
static

Definition at line 678 of file partlist.c.

680{
681 ULONGLONG StartSector;
683 PPARTENTRY NewPartEntry;
684
685 DPRINT("AddLogicalDiskSpace()\n");
686
687 /* Create a partition entry that represents the empty space in the container partition */
688
689 StartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
690 SectorCount = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
691
692 NewPartEntry = CreateInsertBlankRegion(DiskEntry,
693 &DiskEntry->LogicalPartListHead,
694 StartSector,
696 TRUE);
697 if (!NewPartEntry)
698 DPRINT1("Failed to create a new empty region for full extended partition space!\n");
699}
ULONG SectorCount
Definition: part_xbox.c:31
static PPARTENTRY CreateInsertBlankRegion(IN PDISKENTRY DiskEntry, IN OUT PLIST_ENTRY ListHead, IN ULONGLONG StartSector, IN ULONGLONG SectorCount, IN BOOLEAN LogicalSpace)
Definition: partlist.c:640

Referenced by InitializePartitionEntry(), and ScanForUnpartitionedDiskSpace().

◆ AddPartitionToDisk()

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

Definition at line 841 of file partlist.c.

846{
849 PPARTENTRY PartEntry;
850 HANDLE PartitionHandle;
853 WCHAR PathBuffer[MAX_PATH];
855 UCHAR LabelBuffer[sizeof(FILE_FS_VOLUME_INFORMATION) + 256 * sizeof(WCHAR)];
857
858 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
859
860 if (PartitionInfo->PartitionType == PARTITION_ENTRY_UNUSED ||
862 {
863 return;
864 }
865
866 PartEntry = RtlAllocateHeap(ProcessHeap,
868 sizeof(PARTENTRY));
869 if (PartEntry == NULL)
870 return;
871
872 PartEntry->DiskEntry = DiskEntry;
873
874 PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
875 PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
876
877 PartEntry->BootIndicator = PartitionInfo->BootIndicator;
878 PartEntry->PartitionType = PartitionInfo->PartitionType;
879
881 PartEntry->IsPartitioned = TRUE;
882 PartEntry->OnDiskPartitionNumber = PartitionInfo->PartitionNumber;
883 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
884 PartEntry->PartitionIndex = PartitionIndex;
885
886 /* Specify the partition as initially unformatted */
887 PartEntry->FormatState = Unformatted;
888 PartEntry->FileSystem[0] = L'\0';
889
890 /* Initialize the partition volume label */
891 RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
892
893 if (IsContainerPartition(PartEntry->PartitionType))
894 {
895 PartEntry->FormatState = Unformatted;
896
897 if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
898 DiskEntry->ExtendedPartition = PartEntry;
899 }
900 else if (IsRecognizedPartition(PartEntry->PartitionType))
901 {
902 ASSERT(PartitionInfo->RecognizedPartition);
903 ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
904
905 /* Try to open the volume so as to mount it */
906 RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
907 L"\\Device\\Harddisk%lu\\Partition%lu",
908 DiskEntry->DiskNumber,
909 PartEntry->PartitionNumber);
910 RtlInitUnicodeString(&Name, PathBuffer);
911
913 &Name,
915 NULL,
916 NULL);
917
918 PartitionHandle = NULL;
919 Status = NtOpenFile(&PartitionHandle,
925 if (!NT_SUCCESS(Status))
926 {
927 DPRINT1("NtOpenFile() failed, Status 0x%08lx\n", Status);
928 }
929
930 if (PartitionHandle)
931 {
933
934 /* We don't have a FS, try to guess one */
935 Status = InferFileSystem(NULL, PartitionHandle,
936 PartEntry->FileSystem,
937 sizeof(PartEntry->FileSystem));
938 if (!NT_SUCCESS(Status))
939 DPRINT1("InferFileSystem() failed, Status 0x%08lx\n", Status);
940 }
941 if (*PartEntry->FileSystem)
942 {
943 ASSERT(PartitionHandle);
944
945 /*
946 * Handle partition mounted with RawFS: it is
947 * either unformatted or has an unknown format.
948 */
949 if (wcsicmp(PartEntry->FileSystem, L"RAW") == 0)
950 {
951 /*
952 * True unformatted partitions on NT are created with their
953 * partition type set to either one of the following values,
954 * and are mounted with RawFS. This is done this way since we
955 * are assured to have FAT support, which is the only FS that
956 * uses these partition types. Therefore, having a partition
957 * mounted with RawFS and with these partition types means that
958 * the FAT FS was unable to mount it beforehand and thus the
959 * partition is unformatted.
960 * However, any partition mounted by RawFS that does NOT have
961 * any of these partition types must be considered as having
962 * an unknown format.
963 */
964 if (PartEntry->PartitionType == PARTITION_FAT_12 ||
965 PartEntry->PartitionType == PARTITION_FAT_16 ||
966 PartEntry->PartitionType == PARTITION_HUGE ||
967 PartEntry->PartitionType == PARTITION_XINT13 ||
968 PartEntry->PartitionType == PARTITION_FAT32 ||
970 {
971 PartEntry->FormatState = Unformatted;
972 }
973 else
974 {
975 /* Close the partition before dismounting */
976 NtClose(PartitionHandle);
977 PartitionHandle = NULL;
978 /*
979 * Dismount the partition since RawFS owns it, and set its
980 * format to unknown (may or may not be actually formatted).
981 */
982 DismountVolume(PartEntry);
983 PartEntry->FormatState = UnknownFormat;
984 PartEntry->FileSystem[0] = L'\0';
985 }
986 }
987 else
988 {
989 PartEntry->FormatState = Preformatted;
990 }
991 }
992 else
993 {
994 PartEntry->FormatState = UnknownFormat;
995 }
996
997 /* Retrieve the partition volume label */
998 if (PartitionHandle)
999 {
1000 Status = NtQueryVolumeInformationFile(PartitionHandle,
1002 &LabelBuffer,
1003 sizeof(LabelBuffer),
1005 if (NT_SUCCESS(Status))
1006 {
1007 /* Copy the (possibly truncated) volume label and NULL-terminate it */
1008 RtlStringCbCopyNW(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel),
1009 LabelInfo->VolumeLabel, LabelInfo->VolumeLabelLength);
1010 }
1011 else
1012 {
1013 DPRINT1("NtQueryVolumeInformationFile() failed, Status 0x%08lx\n", Status);
1014 }
1015 }
1016
1017 /* Close the partition */
1018 if (PartitionHandle)
1019 NtClose(PartitionHandle);
1020 }
1021 else
1022 {
1023 /* Unknown partition, hence unknown format (may or may not be actually formatted) */
1024 PartEntry->FormatState = UnknownFormat;
1025 }
1026
1027 InsertDiskRegion(DiskEntry, PartEntry, LogicalPartition);
1028}
struct NameRec_ * Name
Definition: cdprocs.h:460
#define PARTITION_XINT13
Definition: disk.h:97
#define PARTITION_FAT32
Definition: disk.h:95
#define PARTITION_FAT_12
Definition: disk.h:87
#define PARTITION_HUGE
Definition: disk.h:92
#define PARTITION_FAT_16
Definition: disk.h:90
#define PARTITION_FAT32_XINT13
Definition: disk.h:96
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
@ LogicalPartition
Definition: disksup.c:48
#define MAX_PATH
Definition: compat.h:34
#define FILE_SHARE_READ
Definition: compat.h:136
#define wcsicmp
Definition: compat.h:15
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
@ FileFsVolumeInformation
Definition: from_kernel.h:219
NTSTATUS InferFileSystem(IN PCWSTR PartitionPath OPTIONAL, IN HANDLE PartitionHandle OPTIONAL, IN OUT PWSTR FileSystemName, IN SIZE_T FileSystemNameSize)
Definition: fsrec.c:269
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
@ UnknownFormat
Definition: partlist.h:36
@ Preformatted
Definition: partlist.h:37
@ Unformatted
Definition: partlist.h:34
#define ASSERT(a)
Definition: mode.c:44
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
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:3952
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_READ_DATA
Definition: nt_native.h:628
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:321
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:342
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 _FILE_FS_VOLUME_INFORMATION * PFILE_FS_VOLUME_INFORMATION
struct _FILE_FS_VOLUME_INFORMATION FILE_FS_VOLUME_INFORMATION
static BOOLEAN InsertDiskRegion(IN PDISKENTRY DiskEntry, IN PPARTENTRY PartEntry, IN BOOLEAN LogicalPartition)
Definition: partlist.c:574
NTSTATUS DismountVolume(IN PPARTENTRY PartEntry)
Definition: partlist.c:2895
BOOLEAN IsPartitioned
Definition: partlist.h:66
UCHAR PartitionType
Definition: partlist.h:53
ULARGE_INTEGER SectorCount
Definition: partlist.h:50
BOOLEAN BootIndicator
Definition: partlist.h:52
WCHAR VolumeLabel[20]
Definition: partlist.h:59
WCHAR FileSystem[MAX_PATH+1]
Definition: partlist.h:60
struct _DISKENTRY * DiskEntry
Definition: partlist.h:46
BOOLEAN LogicalPartition
Definition: partlist.h:63
FORMATSTATE FormatState
Definition: partlist.h:61
ULONG OnDiskPartitionNumber
Definition: partlist.h:54
ULONG PartitionNumber
Definition: partlist.h:55
ULARGE_INTEGER StartSector
Definition: partlist.h:49
ULONG PartitionIndex
Definition: partlist.h:56
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2105
unsigned char UCHAR
Definition: xmlstorage.h:181

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:413

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)
90
91 return Result;
92}
_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:409

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;
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 &&
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}
WCHAR Letter
WCHAR DriveLetter
Definition: partlist.h:58
#define LL
Definition: tui.h:167

Referenced by CreatePartition(), CreatePartitionList(), and DeletePartition().

◆ 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;
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}
#define InsertTailList(ListHead, Entry)
LIST_ENTRY ListEntry
Definition: partlist.h:43

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

◆ CreatePartition()

BOOLEAN CreatePartition ( _In_ PPARTLIST  List,
_Inout_ PPARTENTRY  PartEntry,
_In_opt_ ULONGLONG  SizeBytes,
_In_opt_ ULONG_PTR  PartitionInfo 
)

Definition at line 2844 of file partlist.c.

2849{
2852 PCSTR mainType = "Primary";
2853
2854 if (isContainer)
2855 mainType = "Extended";
2856 else if (PartEntry && PartEntry->LogicalPartition)
2857 mainType = "Logical";
2858
2859 DPRINT1("CreatePartition(%s, %I64u bytes)\n", mainType, SizeBytes);
2860
2861 if (!List || !PartEntry ||
2862 !PartEntry->DiskEntry || PartEntry->IsPartitioned)
2863 {
2864 return FALSE;
2865 }
2866
2867 if (isContainer)
2869 else
2870 Error = PartitionCreationChecks(PartEntry);
2871 if (Error != NOT_AN_ERROR)
2872 {
2873 DPRINT1("PartitionCreationChecks(%s) failed with error %lu\n", mainType, Error);
2874 return FALSE;
2875 }
2876
2877 /* Initialize the partition entry, inserting a new blank region if needed */
2878 if (!InitializePartitionEntry(PartEntry, SizeBytes, PartitionInfo))
2879 return FALSE;
2880
2881 if (isContainer)
2882 {
2883 // FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container)
2884 PartEntry->New = FALSE;
2885 PartEntry->FormatState = Formatted;
2886 }
2887
2888 UpdateDiskLayout(PartEntry->DiskEntry);
2890
2891 return TRUE;
2892}
unsigned char BOOLEAN
BOOL Error
Definition: chkdsk.c:66
enum _ERROR_NUMBER ERROR_NUMBER
@ NOT_AN_ERROR
Definition: errorcode.h:17
@ Formatted
Definition: partlist.h:38
ERROR_NUMBER ExtendedPartitionCreationChecks(_In_ PPARTENTRY PartEntry)
Definition: partlist.c:2806
ERROR_NUMBER PartitionCreationChecks(_In_ PPARTENTRY PartEntry)
Definition: partlist.c:2761
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2523
static VOID AssignDriveLetters(IN PPARTLIST List)
Definition: partlist.c:138
static BOOLEAN InitializePartitionEntry(_Inout_ PPARTENTRY PartEntry, _In_opt_ ULONGLONG SizeBytes, _In_opt_ ULONG_PTR PartitionInfo)
Definition: partlist.c:708
const char * PCSTR
Definition: typedefs.h:52

Referenced by CreatePartitionPage(), InitSystemPartition(), and SelectPartitionPage().

◆ CreatePartitionList()

PPARTLIST CreatePartitionList ( VOID  )

Definition at line 1923 of file partlist.c.

1924{
1926 PDISKENTRY SystemDisk;
1930 ULONG ReturnSize;
1932 ULONG DiskNumber;
1936
1938 0,
1939 sizeof(PARTLIST));
1940 if (List == NULL)
1941 return NULL;
1942
1943 List->SystemPartition = NULL;
1944
1945 InitializeListHead(&List->DiskListHead);
1946 InitializeListHead(&List->BiosDiskListHead);
1947
1948 /*
1949 * Enumerate the disks seen by the BIOS; this will be used later
1950 * to map drives seen by NTOS with their corresponding BIOS names.
1951 */
1953
1954 /* Enumerate disks seen by NTOS */
1956 &Sdi,
1957 sizeof(Sdi),
1958 &ReturnSize);
1959 if (!NT_SUCCESS(Status))
1960 {
1961 DPRINT1("NtQuerySystemInformation() failed, Status 0x%08lx\n", Status);
1963 return NULL;
1964 }
1965
1966 for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
1967 {
1969 L"\\Device\\Harddisk%lu\\Partition0",
1970 DiskNumber);
1972
1974 &Name,
1976 NULL,
1977 NULL);
1978
1982 &Iosb,
1985 if (NT_SUCCESS(Status))
1986 {
1987 AddDiskToList(FileHandle, DiskNumber, List);
1989 }
1990 }
1991
1995
1996 /*
1997 * Retrieve the system partition: the active partition on the system
1998 * disk (the one that will be booted by default by the hardware).
1999 */
2000 SystemDisk = GetSystemDisk(List);
2001 List->SystemPartition = (SystemDisk ? GetActiveDiskPartition(SystemDisk) : NULL);
2002
2003 return List;
2004}
@ SystemDeviceInformation
Definition: ntddk_ex.h:18
struct _PARTLIST * PPARTLIST
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
static PDISKENTRY GetSystemDisk(IN PPARTLIST List)
Definition: partlist.c:1794
static VOID AddDiskToList(IN HANDLE FileHandle, IN ULONG DiskNumber, IN PPARTLIST List)
Definition: partlist.c:1382
static VOID UpdateDiskSignatures(IN PPARTLIST List)
Definition: partlist.c:1291
static VOID EnumerateBiosDiskEntries(IN PPARTLIST PartList)
Definition: partlist.c:337
static PPARTENTRY GetActiveDiskPartition(IN PDISKENTRY DiskEntry)
Definition: partlist.c:1867
static VOID UpdateHwDiskNumbers(IN PPARTLIST List)
Definition: partlist.c:1321
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)

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

◆ DeletePartition()

BOOLEAN DeletePartition ( _In_ PPARTLIST  List,
_In_ PPARTENTRY  PartEntry,
_Out_opt_ PPARTENTRY FreeRegion 
)

Definition at line 3002 of file partlist.c.

3006{
3007 PDISKENTRY DiskEntry;
3008 PPARTENTRY PrevPartEntry;
3009 PPARTENTRY NextPartEntry;
3010 PPARTENTRY LogicalPartEntry;
3012
3013 if (!List || !PartEntry ||
3014 !PartEntry->DiskEntry || !PartEntry->IsPartitioned)
3015 {
3016 return FALSE;
3017 }
3018
3019 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
3020
3021 /* Clear the system partition if it is being deleted */
3022 if (List->SystemPartition == PartEntry)
3023 {
3024 ASSERT(List->SystemPartition);
3025 List->SystemPartition = NULL;
3026 }
3027
3028 DiskEntry = PartEntry->DiskEntry;
3029
3030 /* Check which type of partition (primary/logical or extended) is being deleted */
3031 if (DiskEntry->ExtendedPartition == PartEntry)
3032 {
3033 /* An extended partition is being deleted: delete all logical partition entries */
3034 while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
3035 {
3037 LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
3038
3039 /* Dismount the logical partition */
3040 DismountVolume(LogicalPartEntry);
3041
3042 /* Delete it */
3043 RtlFreeHeap(ProcessHeap, 0, LogicalPartEntry);
3044 }
3045
3046 DiskEntry->ExtendedPartition = NULL;
3047 }
3048 else
3049 {
3050 /* A primary partition is being deleted: dismount it */
3051 DismountVolume(PartEntry);
3052 }
3053
3054 /* Adjust the unpartitioned disk space entries */
3055
3056 /* Get pointer to previous and next unpartitioned entries */
3057 PrevPartEntry = GetAdjUnpartitionedEntry(PartEntry, FALSE);
3058 NextPartEntry = GetAdjUnpartitionedEntry(PartEntry, TRUE);
3059
3060 if (PrevPartEntry != NULL && NextPartEntry != NULL)
3061 {
3062 /* Merge the previous, current and next unpartitioned entries */
3063
3064 /* Adjust the previous entry length */
3065 PrevPartEntry->SectorCount.QuadPart += (PartEntry->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart);
3066
3067 /* Remove the current and next entries */
3068 RemoveEntryList(&PartEntry->ListEntry);
3069 RtlFreeHeap(ProcessHeap, 0, PartEntry);
3070 RemoveEntryList(&NextPartEntry->ListEntry);
3071 RtlFreeHeap(ProcessHeap, 0, NextPartEntry);
3072
3073 /* Optionally return the freed region */
3074 if (FreeRegion)
3075 *FreeRegion = PrevPartEntry;
3076 }
3077 else if (PrevPartEntry != NULL && NextPartEntry == NULL)
3078 {
3079 /* Merge the current and the previous unpartitioned entries */
3080
3081 /* Adjust the previous entry length */
3082 PrevPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
3083
3084 /* Remove the current entry */
3085 RemoveEntryList(&PartEntry->ListEntry);
3086 RtlFreeHeap(ProcessHeap, 0, PartEntry);
3087
3088 /* Optionally return the freed region */
3089 if (FreeRegion)
3090 *FreeRegion = PrevPartEntry;
3091 }
3092 else if (PrevPartEntry == NULL && NextPartEntry != NULL)
3093 {
3094 /* Merge the current and the next unpartitioned entries */
3095
3096 /* Adjust the next entry offset and length */
3097 NextPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
3098 NextPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
3099
3100 /* Remove the current entry */
3101 RemoveEntryList(&PartEntry->ListEntry);
3102 RtlFreeHeap(ProcessHeap, 0, PartEntry);
3103
3104 /* Optionally return the freed region */
3105 if (FreeRegion)
3106 *FreeRegion = NextPartEntry;
3107 }
3108 else
3109 {
3110 /* Nothing to merge but change the current entry */
3111 PartEntry->IsPartitioned = FALSE;
3112 PartEntry->OnDiskPartitionNumber = 0;
3113 PartEntry->PartitionNumber = 0;
3114 // PartEntry->PartitionIndex = 0;
3115 PartEntry->BootIndicator = FALSE;
3116 PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
3117 PartEntry->FormatState = Unformatted;
3118 PartEntry->FileSystem[0] = L'\0';
3119 PartEntry->DriveLetter = 0;
3120 RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
3121
3122 /* Optionally return the freed region */
3123 if (FreeRegion)
3124 *FreeRegion = PartEntry;
3125 }
3126
3127 UpdateDiskLayout(DiskEntry);
3129
3130 return TRUE;
3131}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
static PPARTENTRY GetAdjUnpartitionedEntry(_In_ PPARTENTRY PartEntry, _In_ BOOLEAN Direction)
Retrieves, if any, the unpartitioned disk region that is adjacent (next or previous) to the specified...
Definition: partlist.c:2725
base of all file and directory entries
Definition: entries.h:83
PPARTENTRY ExtendedPartition
Definition: partlist.h:132

Referenced by DeletePartitionPage().

◆ DestroyPartitionList()

VOID DestroyPartitionList ( IN PPARTLIST  List)

Definition at line 2007 of file partlist.c.

2009{
2010 PDISKENTRY DiskEntry;
2011 PBIOSDISKENTRY BiosDiskEntry;
2012 PPARTENTRY PartEntry;
2014
2015 /* Release disk and partition info */
2016 while (!IsListEmpty(&List->DiskListHead))
2017 {
2018 Entry = RemoveHeadList(&List->DiskListHead);
2019 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2020
2021 /* Release driver name */
2022 RtlFreeUnicodeString(&DiskEntry->DriverName);
2023
2024 /* Release primary partition list */
2025 while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
2026 {
2028 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2029
2030 RtlFreeHeap(ProcessHeap, 0, PartEntry);
2031 }
2032
2033 /* Release logical partition list */
2034 while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
2035 {
2037 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2038
2039 RtlFreeHeap(ProcessHeap, 0, PartEntry);
2040 }
2041
2042 /* Release layout buffer */
2043 if (DiskEntry->LayoutBuffer != NULL)
2044 RtlFreeHeap(ProcessHeap, 0, DiskEntry->LayoutBuffer);
2045
2046 /* Release disk entry */
2047 RtlFreeHeap(ProcessHeap, 0, DiskEntry);
2048 }
2049
2050 /* Release the bios disk info */
2051 while (!IsListEmpty(&List->BiosDiskListHead))
2052 {
2053 Entry = RemoveHeadList(&List->BiosDiskListHead);
2054 BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
2055
2056 RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
2057 }
2058
2059 /* Release list head */
2061}
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
UNICODE_STRING DriverName
Definition: partlist.h:120

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;
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 {
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}
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
struct _CM_FULL_RESOURCE_DESCRIPTOR * PCM_FULL_RESOURCE_DESCRIPTOR
#define CmResourceTypeDeviceSpecific
Definition: hwresource.cpp:127
struct _BIOSDISKENTRY * PBIOSDISKENTRY
#define REG_FULL_RESOURCE_DESCRIPTOR
Definition: nt_native.h:1503
#define STATUS_SUCCESS
Definition: shellext.h:65
CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry
Definition: partlist.h:145
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@389 u
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@389::@398 DeviceSpecificData
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: hwresource.cpp:119
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:282
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:275
struct _CM_DISK_GEOMETRY_DEVICE_DATA * PCM_DISK_GEOMETRY_DEVICE_DATA

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}
#define REG_SZ
Definition: layer.c:22
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWCHAR
Definition: typedefs.h:56

Referenced by EnumerateBiosDiskEntries().

◆ DismountVolume()

NTSTATUS DismountVolume ( IN PPARTENTRY  PartEntry)

Definition at line 2895 of file partlist.c.

2897{
2899 NTSTATUS LockStatus;
2903 HANDLE PartitionHandle;
2905
2906 /* Check whether the partition is valid and was mounted by the system */
2907 if (!PartEntry->IsPartitioned ||
2908 IsContainerPartition(PartEntry->PartitionType) ||
2909 !IsRecognizedPartition(PartEntry->PartitionType) ||
2910 PartEntry->FormatState == UnknownFormat ||
2911 // NOTE: If FormatState == Unformatted but *FileSystem != 0 this means
2912 // it has been usually mounted with RawFS and thus needs to be dismounted.
2913 !*PartEntry->FileSystem ||
2914 PartEntry->PartitionNumber == 0)
2915 {
2916 /* The partition is not mounted, so just return success */
2917 return STATUS_SUCCESS;
2918 }
2919
2920 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
2921
2922 /* Open the volume */
2924 L"\\Device\\Harddisk%lu\\Partition%lu",
2925 PartEntry->DiskEntry->DiskNumber,
2926 PartEntry->PartitionNumber);
2928
2930 &Name,
2932 NULL,
2933 NULL);
2934
2935 Status = NtOpenFile(&PartitionHandle,
2941 if (!NT_SUCCESS(Status))
2942 {
2943 DPRINT1("ERROR: Cannot open volume %wZ for dismounting! (Status 0x%lx)\n", &Name, Status);
2944 return Status;
2945 }
2946
2947 /* Lock the volume */
2948 LockStatus = NtFsControlFile(PartitionHandle,
2949 NULL,
2950 NULL,
2951 NULL,
2954 NULL,
2955 0,
2956 NULL,
2957 0);
2958 if (!NT_SUCCESS(LockStatus))
2959 {
2960 DPRINT1("WARNING: Failed to lock volume! Operations may fail! (Status 0x%lx)\n", LockStatus);
2961 }
2962
2963 /* Dismount the volume */
2964 Status = NtFsControlFile(PartitionHandle,
2965 NULL,
2966 NULL,
2967 NULL,
2970 NULL,
2971 0,
2972 NULL,
2973 0);
2974 if (!NT_SUCCESS(Status))
2975 {
2976 DPRINT1("Failed to unmount volume (Status 0x%lx)\n", Status);
2977 }
2978
2979 /* Unlock the volume */
2980 LockStatus = NtFsControlFile(PartitionHandle,
2981 NULL,
2982 NULL,
2983 NULL,
2986 NULL,
2987 0,
2988 NULL,
2989 0);
2990 if (!NT_SUCCESS(LockStatus))
2991 {
2992 DPRINT1("Failed to unlock volume (Status 0x%lx)\n", LockStatus);
2993 }
2994
2995 /* Close the volume */
2996 NtClose(PartitionHandle);
2997
2998 return Status;
2999}
#define GENERIC_READ
Definition: compat.h:135
#define FSCTL_LOCK_VOLUME
Definition: nt_native.h:832
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
#define FSCTL_DISMOUNT_VOLUME
Definition: nt_native.h:834
#define GENERIC_WRITE
Definition: nt_native.h:90
NTSYSAPI NTSTATUS NTAPI NtFsControlFile(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)

Referenced by AddPartitionToDisk(), clean_main(), 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,
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}
ULONG ControllerCount
Definition: fdc.c:18
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4220
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define memset(x, y, z)
Definition: compat.h:39
static NTSTATUS NTAPI DiskConfigurationDataQueryRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: partlist.c:247
#define ROOT_NAME
static NTSTATUS NTAPI SystemConfigurationDataQueryRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: partlist.c:290
static NTSTATUS NTAPI DiskIdentifierQueryRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: partlist.c:217
LIST_ENTRY ListEntry
Definition: partlist.h:138
CM_INT13_DRIVE_PARAMETER Int13DiskData
Definition: partlist.h:146
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109

Referenced by CreatePartitionList().

◆ ExtendedPartitionCreationChecks()

ERROR_NUMBER ExtendedPartitionCreationChecks ( _In_ PPARTENTRY  PartEntry)

Definition at line 2806 of file partlist.c.

2808{
2809 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2810
2811 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2812 {
2813 DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2814 return ERROR_WARN_PARTITION;
2815 }
2816
2817 /* Fail if the partition is already in use */
2818 if (PartEntry->IsPartitioned)
2819 return ERROR_NEW_PARTITION;
2820
2821 /* Cannot create an extended partition within logical partition space */
2822 if (PartEntry->LogicalPartition)
2824
2825 /* Only one primary partition is allowed on super-floppy */
2826 if (IsSuperFloppy(DiskEntry))
2828
2829 /* Fail if there are already 4 primary partitions in the list */
2830 if (GetPrimaryPartitionCount(DiskEntry) >= 4)
2832
2833 /* Fail if there is another extended partition in the list */
2834 if (DiskEntry->ExtendedPartition)
2836
2837 return ERROR_SUCCESS;
2838}
#define ERROR_SUCCESS
Definition: deptool.c:10
@ ERROR_WARN_PARTITION
Definition: errorcode.h:33
@ ERROR_NEW_PARTITION
Definition: errorcode.h:34
@ ERROR_ONLY_ONE_EXTENDED
Definition: errorcode.h:59
@ ERROR_PARTITION_TABLE_FULL
Definition: errorcode.h:58
#define GetPrimaryPartitionCount(DiskEntry)
Definition: partlist.c:2461

Referenced by CreatePartition(), and SelectPartitionPage().

◆ FindSupportedSystemPartition()

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

Definition at line 3215 of file partlist.c.

3220{
3221 PLIST_ENTRY ListEntry;
3222 PDISKENTRY DiskEntry;
3223 PPARTENTRY PartEntry;
3224 PPARTENTRY ActivePartition;
3225 PPARTENTRY CandidatePartition = NULL;
3226
3227 /* Check for empty disk list */
3228 if (IsListEmpty(&List->DiskListHead))
3229 {
3230 /* No system partition! */
3231 ASSERT(List->SystemPartition == NULL);
3232 goto NoSystemPartition;
3233 }
3234
3235 /* Adjust the optional alternative disk if needed */
3236 if (!AlternativeDisk && AlternativePart)
3237 AlternativeDisk = AlternativePart->DiskEntry;
3238
3239 /* Ensure that the alternative partition is on the alternative disk */
3240 if (AlternativePart)
3241 ASSERT(AlternativeDisk && (AlternativePart->DiskEntry == AlternativeDisk));
3242
3243 /* Ensure that the alternative disk is in the list */
3244 if (AlternativeDisk)
3245 ASSERT(AlternativeDisk->PartList == List);
3246
3247 /* Start fresh */
3248 CandidatePartition = NULL;
3249
3250//
3251// Step 1 : Check the system disk.
3252//
3253
3254 /*
3255 * First, check whether the system disk, i.e. the one that will be booted
3256 * by default by the hardware, contains an active partition. If so this
3257 * should be our system partition.
3258 */
3259 DiskEntry = GetSystemDisk(List);
3260 if (!DiskEntry)
3261 {
3262 /* No system disk found, directly go check the alternative disk */
3263 goto UseAlternativeDisk;
3264 }
3265
3266 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3267 {
3268 DPRINT1("System disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
3269 goto UseAlternativeDisk;
3270 }
3271
3272 /* If we have a system partition (in the system disk), validate it */
3273 ActivePartition = List->SystemPartition;
3274 if (ActivePartition && IsSupportedActivePartition(ActivePartition))
3275 {
3276 CandidatePartition = ActivePartition;
3277
3278 DPRINT1("Use the current system partition %lu in disk %lu, drive letter %C\n",
3279 CandidatePartition->PartitionNumber,
3280 CandidatePartition->DiskEntry->DiskNumber,
3281 (CandidatePartition->DriveLetter == 0) ? L'-' : CandidatePartition->DriveLetter);
3282
3283 /* Return the candidate system partition */
3284 return CandidatePartition;
3285 }
3286
3287 /* If the system disk is not the optional alternative disk, perform the minimal checks */
3288 if (DiskEntry != AlternativeDisk)
3289 {
3290 /*
3291 * No active partition has been recognized. Enumerate all the (primary)
3292 * partitions in the system disk, excluding the possible current active
3293 * partition, to find a new candidate.
3294 */
3295 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3296 ListEntry != &DiskEntry->PrimaryPartListHead;
3297 ListEntry = ListEntry->Flink)
3298 {
3299 /* Retrieve the partition */
3300 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3301
3302 /* Skip the current active partition */
3303 if (PartEntry == ActivePartition)
3304 continue;
3305
3306 /* Check if the partition is partitioned and used */
3307 if (PartEntry->IsPartitioned &&
3309 {
3311
3312 /* If we get a candidate active partition in the disk, validate it */
3313 if (IsSupportedActivePartition(PartEntry))
3314 {
3315 CandidatePartition = PartEntry;
3316 goto UseAlternativePartition;
3317 }
3318 }
3319
3320#if 0
3321 /* Check if the partition is partitioned and used */
3322 if (!PartEntry->IsPartitioned)
3323 {
3325
3326 // TODO: Check for minimal size!!
3327 CandidatePartition = PartEntry;
3328 goto UseAlternativePartition;
3329 }
3330#endif
3331 }
3332
3333 /*
3334 * Still nothing, look whether there is some free space that we can use
3335 * for the new system partition. We must be sure that the total number
3336 * of partition is less than the maximum allowed, and that the minimal
3337 * size is fine.
3338 */
3339//
3340// TODO: Fix the handling of system partition being created in unpartitioned space!!
3341// --> When to partition it? etc...
3342//
3343 if (GetPrimaryPartitionCount(DiskEntry) < 4)
3344 {
3345 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3346 ListEntry != &DiskEntry->PrimaryPartListHead;
3347 ListEntry = ListEntry->Flink)
3348 {
3349 /* Retrieve the partition */
3350 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3351
3352 /* Skip the current active partition */
3353 if (PartEntry == ActivePartition)
3354 continue;
3355
3356 /* Check for unpartitioned space */
3357 if (!PartEntry->IsPartitioned)
3358 {
3360
3361 // TODO: Check for minimal size!!
3362 CandidatePartition = PartEntry;
3363 goto UseAlternativePartition;
3364 }
3365 }
3366 }
3367 }
3368
3369
3370//
3371// Step 2 : No active partition found: Check the alternative disk if specified.
3372//
3373
3374UseAlternativeDisk:
3375 if (!AlternativeDisk || (!ForceSelect && (DiskEntry != AlternativeDisk)))
3376 goto NoSystemPartition;
3377
3378 if (AlternativeDisk->DiskStyle == PARTITION_STYLE_GPT)
3379 {
3380 DPRINT1("Alternative disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
3381 goto NoSystemPartition;
3382 }
3383
3384 if (DiskEntry != AlternativeDisk)
3385 {
3386 /* Choose the alternative disk */
3387 DiskEntry = AlternativeDisk;
3388
3389 /* If we get a candidate active partition, validate it */
3390 ActivePartition = GetActiveDiskPartition(DiskEntry);
3391 if (ActivePartition && IsSupportedActivePartition(ActivePartition))
3392 {
3393 CandidatePartition = ActivePartition;
3394 goto UseAlternativePartition;
3395 }
3396 }
3397
3398 /* We now may have an unsupported active partition, or none */
3399
3400/***
3401 *** TODO: Improve the selection:
3402 *** - If we want a really separate system partition from the partition where
3403 *** we install, do something similar to what's done below in the code.
3404 *** - Otherwise if we allow for the system partition to be also the partition
3405 *** where we install, just directly fall down to using AlternativePart.
3406 ***/
3407
3408 /* Retrieve the first partition of the disk */
3409 PartEntry = CONTAINING_RECORD(DiskEntry->PrimaryPartListHead.Flink,
3410 PARTENTRY, ListEntry);
3411 ASSERT(DiskEntry == PartEntry->DiskEntry);
3412
3413 CandidatePartition = PartEntry;
3414
3415 //
3416 // See: https://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/partlist.c?r1=63355&r2=63354&pathrev=63355#l2318
3417 //
3418
3419 /* Check if the disk is new and if so, use its first partition as the active system partition */
3420 if (DiskEntry->NewDisk)
3421 {
3422 // !IsContainerPartition(PartEntry->PartitionType);
3423 if (!CandidatePartition->IsPartitioned || !CandidatePartition->BootIndicator) /* CandidatePartition != ActivePartition */
3424 {
3425 ASSERT(DiskEntry == CandidatePartition->DiskEntry);
3426
3427 DPRINT1("Use new first active system partition %lu in disk %lu, drive letter %C\n",
3428 CandidatePartition->PartitionNumber,
3429 CandidatePartition->DiskEntry->DiskNumber,
3430 (CandidatePartition->DriveLetter == 0) ? L'-' : CandidatePartition->DriveLetter);
3431
3432 /* Return the candidate system partition */
3433 return CandidatePartition;
3434 }
3435
3436 // FIXME: What to do??
3437 DPRINT1("NewDisk TRUE but first partition is used?\n");
3438 }
3439
3440 /*
3441 * The disk is not new, check if any partition is initialized;
3442 * if not, the first one becomes the system partition.
3443 */
3444 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3445 ListEntry != &DiskEntry->PrimaryPartListHead;
3446 ListEntry = ListEntry->Flink)
3447 {
3448 /* Retrieve the partition */
3449 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3450
3451 /* Check if the partition is partitioned and is used */
3452 // !IsContainerPartition(PartEntry->PartitionType);
3453 if (/* PartEntry->IsPartitioned && */
3454 PartEntry->PartitionType != PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator)
3455 {
3456 break;
3457 }
3458 }
3459 if (ListEntry == &DiskEntry->PrimaryPartListHead)
3460 {
3461 /*
3462 * OK we haven't encountered any used and active partition,
3463 * so use the first one as the system partition.
3464 */
3465 ASSERT(DiskEntry == CandidatePartition->DiskEntry);
3466
3467 DPRINT1("Use 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 /*
3477 * The disk is not new, we did not find any actual active partition,
3478 * or the one we found was not supported, or any possible other candidate
3479 * is not supported. We then use the alternative partition if specified.
3480 */
3481 if (AlternativePart)
3482 {
3483 DPRINT1("No valid or supported system partition has been found, use the alternative partition!\n");
3484 CandidatePartition = AlternativePart;
3485 goto UseAlternativePartition;
3486 }
3487 else
3488 {
3489NoSystemPartition:
3490 DPRINT1("No valid or supported system partition has been found on this system!\n");
3491 return NULL;
3492 }
3493
3494UseAlternativePartition:
3495 /*
3496 * We are here because we did not find any (active) candidate system
3497 * partition that we know how to support. What we are going to do is
3498 * to change the existing system partition and use the alternative partition
3499 * (e.g. on which we install ReactOS) as the new system partition.
3500 * Then we will need to add in FreeLdr's boot menu an entry for booting
3501 * from the original system partition.
3502 */
3503 ASSERT(CandidatePartition);
3504
3505 DPRINT1("Use alternative active system partition %lu in disk %lu, drive letter %C\n",
3506 CandidatePartition->PartitionNumber,
3507 CandidatePartition->DiskEntry->DiskNumber,
3508 (CandidatePartition->DriveLetter == 0) ? L'-' : CandidatePartition->DriveLetter);
3509
3510 /* Return the candidate system partition */
3511 return CandidatePartition;
3512}
static BOOLEAN IsSupportedActivePartition(IN PPARTENTRY PartEntry)
Definition: partlist.c:3135

Referenced by InitSystemPartition().

◆ GetActiveDiskPartition()

static PPARTENTRY GetActiveDiskPartition ( IN PDISKENTRY  DiskEntry)
static

Definition at line 1867 of file partlist.c.

1869{
1870 PLIST_ENTRY ListEntry;
1871 PPARTENTRY PartEntry;
1872 PPARTENTRY ActivePartition = NULL;
1873
1874 /* Check for empty disk list */
1875 // ASSERT(DiskEntry);
1876 if (!DiskEntry)
1877 return NULL;
1878
1879 /* Check for empty partition list */
1880 if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
1881 return NULL;
1882
1883 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1884 {
1885 DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1886 return NULL;
1887 }
1888
1889 /* Scan all (primary) partitions to find the active disk partition */
1890 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
1891 ListEntry != &DiskEntry->PrimaryPartListHead;
1892 ListEntry = ListEntry->Flink)
1893 {
1894 /* Retrieve the partition */
1895 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1896 if (IsPartitionActive(PartEntry))
1897 {
1898 /* Yes, we've found it */
1899 ASSERT(DiskEntry == PartEntry->DiskEntry);
1900 ASSERT(PartEntry->IsPartitioned);
1901
1902 ActivePartition = PartEntry;
1903
1904 DPRINT1("Found active system partition %lu in disk %lu, drive letter %C\n",
1905 PartEntry->PartitionNumber, DiskEntry->DiskNumber,
1906 (PartEntry->DriveLetter == 0) ? L'-' : PartEntry->DriveLetter);
1907 break;
1908 }
1909 }
1910
1911 /* Check if the disk is new and if so, use its first partition as the active system partition */
1912 if (DiskEntry->NewDisk && ActivePartition != NULL)
1913 {
1914 // FIXME: What to do??
1915 DPRINT1("NewDisk TRUE but already existing active partition?\n");
1916 }
1917
1918 /* Return the active partition found (or none) */
1919 return ActivePartition;
1920}
BOOLEAN IsPartitionActive(IN PPARTENTRY PartEntry)
Definition: partlist.c:1844

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

◆ GetAdjUnpartitionedEntry()

static PPARTENTRY GetAdjUnpartitionedEntry ( _In_ PPARTENTRY  PartEntry,
_In_ BOOLEAN  Direction 
)
static

Retrieves, if any, the unpartitioned disk region that is adjacent (next or previous) to the specified partition.

Parameters
[in]PartEntryPartition from where to find the adjacent unpartitioned region.
[in]DirectionTRUE or FALSE to search the next or previous region, respectively.
Returns
The adjacent unpartitioned region, if it exists, or NULL.

Definition at line 2725 of file partlist.c.

2728{
2729 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2730 PLIST_ENTRY ListHead, AdjEntry;
2731
2732 /* In case of MBR disks only, check the logical partitions if necessary */
2733 if ((DiskEntry->DiskStyle == PARTITION_STYLE_MBR) &&
2734 PartEntry->LogicalPartition)
2735 {
2736 ListHead = &DiskEntry->LogicalPartListHead;
2737 }
2738 else
2739 {
2740 ListHead = &DiskEntry->PrimaryPartListHead;
2741 }
2742
2743 if (Direction)
2744 AdjEntry = PartEntry->ListEntry.Flink; // Next region.
2745 else
2746 AdjEntry = PartEntry->ListEntry.Blink; // Previous region.
2747
2748 if (AdjEntry != ListHead)
2749 {
2750 PartEntry = CONTAINING_RECORD(AdjEntry, PARTENTRY, ListEntry);
2751 if (!PartEntry->IsPartitioned)
2752 {
2753 ASSERT(PartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
2754 return PartEntry;
2755 }
2756 }
2757 return NULL;
2758}
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
WDF_EXTERN_C_START typedef _In_ WDFDEVICE _In_ WDFCONTEXT _In_ WDF_DMA_DIRECTION Direction

Referenced by DeletePartition().

◆ GetDiskByBiosNumber()

PDISKENTRY GetDiskByBiosNumber ( _In_ PPARTLIST  List,
_In_ ULONG  HwDiskNumber 
)

Definition at line 2064 of file partlist.c.

2067{
2068 PDISKENTRY DiskEntry;
2070
2071 /* Loop over the disks and find the correct one */
2072 for (Entry = List->DiskListHead.Flink;
2073 Entry != &List->DiskListHead;
2074 Entry = Entry->Flink)
2075 {
2076 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2077
2078 if (DiskEntry->HwDiskNumber == HwDiskNumber)
2079 return DiskEntry; /* Disk found, return it */
2080 }
2081
2082 /* Disk not found, stop there */
2083 return NULL;
2084}

◆ GetDiskByNumber()

PDISKENTRY GetDiskByNumber ( _In_ PPARTLIST  List,
_In_ ULONG  DiskNumber 
)

Definition at line 2087 of file partlist.c.

2090{
2091 PDISKENTRY DiskEntry;
2093
2094 /* Loop over the disks and find the correct one */
2095 for (Entry = List->DiskListHead.Flink;
2096 Entry != &List->DiskListHead;
2097 Entry = Entry->Flink)
2098 {
2099 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2100
2101 if (DiskEntry->DiskNumber == DiskNumber)
2102 return DiskEntry; /* Disk found, return it */
2103 }
2104
2105 /* Disk not found, stop there */
2106 return NULL;
2107}

Referenced by SelectPartition().

◆ GetDiskBySCSI()

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

Definition at line 2110 of file partlist.c.

2115{
2116 PDISKENTRY DiskEntry;
2118
2119 /* Loop over the disks and find the correct one */
2120 for (Entry = List->DiskListHead.Flink;
2121 Entry != &List->DiskListHead;
2122 Entry = Entry->Flink)
2123 {
2124 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2125
2126 if (DiskEntry->Port == Port &&
2127 DiskEntry->Bus == Bus &&
2128 DiskEntry->Id == Id)
2129 {
2130 /* Disk found, return it */
2131 return DiskEntry;
2132 }
2133 }
2134
2135 /* Disk not found, stop there */
2136 return NULL;
2137}
DWORD Id
CPPORT Port[4]
Definition: headless.c:35

Referenced by ResolveArcNameManually().

◆ GetDiskBySignature()

PDISKENTRY GetDiskBySignature ( _In_ PPARTLIST  List,
_In_ ULONG  Signature 
)

Definition at line 2140 of file partlist.c.

2143{
2144 PDISKENTRY DiskEntry;
2146
2147 /* Loop over the disks and find the correct one */
2148 for (Entry = List->DiskListHead.Flink;
2149 Entry != &List->DiskListHead;
2150 Entry = Entry->Flink)
2151 {
2152 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2153
2154 if (DiskEntry->LayoutBuffer->Signature == Signature)
2155 return DiskEntry; /* Disk found, return it */
2156 }
2157
2158 /* Disk not found, stop there */
2159 return NULL;
2160}

Referenced by ResolveArcNameManually().

◆ 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,
128 NULL,
129 NULL);
130 if (!NT_SUCCESS(Status))
131 {
132 DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
133 }
134}
#define RTL_REGISTRY_DEVICEMAP
Definition: nt_native.h:165
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699

Referenced by AddDiskToList().

◆ GetNextPartition()

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

Definition at line 2229 of file partlist.c.

2232{
2233 PLIST_ENTRY DiskListEntry;
2234 PLIST_ENTRY PartListEntry;
2236
2237 /* Fail if no disks are available */
2238 if (IsListEmpty(&List->DiskListHead))
2239 return NULL;
2240
2241 /* Check for the next usable entry on the current partition's disk */
2242 if (CurrentPart != NULL)
2243 {
2244 CurrentDisk = CurrentPart->DiskEntry;
2245
2246 if (CurrentPart->LogicalPartition)
2247 {
2248 /* Logical partition */
2249
2250 PartListEntry = CurrentPart->ListEntry.Flink;
2251 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2252 {
2253 /* Next logical partition */
2254 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2255 return CurrentPart;
2256 }
2257 else
2258 {
2259 PartListEntry = CurrentDisk->ExtendedPartition->ListEntry.Flink;
2260 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2261 {
2262 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2263 return CurrentPart;
2264 }
2265 }
2266 }
2267 else
2268 {
2269 /* Primary or extended partition */
2270
2271 if (CurrentPart->IsPartitioned &&
2272 IsContainerPartition(CurrentPart->PartitionType))
2273 {
2274 /* First logical partition */
2275 PartListEntry = CurrentDisk->LogicalPartListHead.Flink;
2276 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2277 {
2278 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2279 return CurrentPart;
2280 }
2281 }
2282 else
2283 {
2284 /* Next primary partition */
2285 PartListEntry = CurrentPart->ListEntry.Flink;
2286 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2287 {
2288 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2289 return CurrentPart;
2290 }
2291 }
2292 }
2293 }
2294
2295 /* Search for the first partition entry on the next disk */
2296 for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Flink
2297 : List->DiskListHead.Flink);
2298 DiskListEntry != &List->DiskListHead;
2299 DiskListEntry = DiskListEntry->Flink)
2300 {
2301 CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
2302
2304 {
2305 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2306 continue;
2307 }
2308
2309 PartListEntry = CurrentDisk->PrimaryPartListHead.Flink;
2310 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2311 {
2312 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2313 return CurrentPart;
2314 }
2315 }
2316
2317 return NULL;
2318}
PDISKENTRY CurrentDisk
Definition: partlist.c:74
LIST_ENTRY ListEntry
Definition: partlist.h:80

Referenced by ScrollUpDownPartitionList().

◆ GetPartition()

PPARTENTRY GetPartition ( _In_ PDISKENTRY  DiskEntry,
_In_ ULONG  PartitionNumber 
)

Definition at line 2163 of file partlist.c.

2166{
2167 PPARTENTRY PartEntry;
2169
2170 /* Forbid whole-disk or extended container partition access */
2171 if (PartitionNumber == 0)
2172 return NULL;
2173
2174 /* Loop over the primary partitions first... */
2175 for (Entry = DiskEntry->PrimaryPartListHead.Flink;
2176 Entry != &DiskEntry->PrimaryPartListHead;
2177 Entry = Entry->Flink)
2178 {
2179 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2180
2181 if (PartEntry->PartitionNumber == PartitionNumber)
2182 return PartEntry; /* Partition found, return it */
2183 }
2184
2185 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2186 return NULL;
2187
2188 /* ... then over the logical partitions if needed */
2189 for (Entry = DiskEntry->LogicalPartListHead.Flink;
2190 Entry != &DiskEntry->LogicalPartListHead;
2191 Entry = Entry->Flink)
2192 {
2193 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2194
2195 if (PartEntry->PartitionNumber == PartitionNumber)
2196 return PartEntry; /* Partition found, return it */
2197 }
2198
2199 /* The partition was not found on the disk, stop there */
2200 return NULL;
2201}
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2061

Referenced by ResolveArcNameManually(), and SelectPartition().

◆ GetPartitionCount()

static ULONG GetPartitionCount ( _In_ PLIST_ENTRY  PartListHead)
static

Counts the number of partitioned disk regions in a given partition list.

Definition at line 2442 of file partlist.c.

2444{
2446 PPARTENTRY PartEntry;
2447 ULONG Count = 0;
2448
2449 for (Entry = PartListHead->Flink;
2450 Entry != PartListHead;
2451 Entry = Entry->Flink)
2452 {
2453 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2454 if (PartEntry->IsPartitioned)
2455 ++Count;
2456 }
2457
2458 return Count;
2459}
int Count
Definition: noreturn.cpp:7

◆ GetPrevPartition()

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

Definition at line 2321 of file partlist.c.

2324{
2325 PLIST_ENTRY DiskListEntry;
2326 PLIST_ENTRY PartListEntry;
2328
2329 /* Fail if no disks are available */
2330 if (IsListEmpty(&List->DiskListHead))
2331 return NULL;
2332
2333 /* Check for the previous usable entry on the current partition's disk */
2334 if (CurrentPart != NULL)
2335 {
2336 CurrentDisk = CurrentPart->DiskEntry;
2337
2338 if (CurrentPart->LogicalPartition)
2339 {
2340 /* Logical partition */
2341
2342 PartListEntry = CurrentPart->ListEntry.Blink;
2343 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2344 {
2345 /* Previous logical partition */
2346 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2347 }
2348 else
2349 {
2350 /* Extended partition */
2351 CurrentPart = CurrentDisk->ExtendedPartition;
2352 }
2353 return CurrentPart;
2354 }
2355 else
2356 {
2357 /* Primary or extended partition */
2358
2359 PartListEntry = CurrentPart->ListEntry.Blink;
2360 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2361 {
2362 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2363
2364 if (CurrentPart->IsPartitioned &&
2365 IsContainerPartition(CurrentPart->PartitionType))
2366 {
2367 PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2368 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2369 }
2370
2371 return CurrentPart;
2372 }
2373 }
2374 }
2375
2376 /* Search for the last partition entry on the previous disk */
2377 for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Blink
2378 : List->DiskListHead.Blink);
2379 DiskListEntry != &List->DiskListHead;
2380 DiskListEntry = DiskListEntry->Blink)
2381 {
2382 CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
2383
2385 {
2386 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2387 continue;
2388 }
2389
2390 PartListEntry = CurrentDisk->PrimaryPartListHead.Blink;
2391 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2392 {
2393 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2394
2395 if (CurrentPart->IsPartitioned &&
2396 IsContainerPartition(CurrentPart->PartitionType))
2397 {
2398 PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2399 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2400 {
2401 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2402 return CurrentPart;
2403 }
2404 }
2405 else
2406 {
2407 return CurrentPart;
2408 }
2409 }
2410 }
2411
2412 return NULL;
2413}

Referenced by ScrollUpDownPartitionList().

◆ GetSystemDisk()

static PDISKENTRY GetSystemDisk ( IN PPARTLIST  List)
static

Definition at line 1794 of file partlist.c.

1796{
1798 PDISKENTRY DiskEntry;
1799
1800 /* Check for empty disk list */
1801 if (IsListEmpty(&List->DiskListHead))
1802 return NULL;
1803
1804 /*
1805 * If we already have a system partition, the system disk
1806 * is the one on which the system partition resides.
1807 */
1808 if (List->SystemPartition)
1809 return List->SystemPartition->DiskEntry;
1810
1811 /* Loop over the disks and find the correct one */
1812 for (Entry = List->DiskListHead.Flink;
1813 Entry != &List->DiskListHead;
1814 Entry = Entry->Flink)
1815 {
1816 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
1817
1818 /* The disk must be a fixed disk and be found by the firmware */
1819 if (DiskEntry->MediaType == FixedMedia && DiskEntry->BiosFound)
1820 {
1821 break;
1822 }
1823 }
1824 if (Entry == &List->DiskListHead)
1825 {
1826 /* We haven't encountered any suitable disk */
1827 return NULL;
1828 }
1829
1830 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1831 {
1832 DPRINT1("System disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
1833 }
1834
1835 return DiskEntry;
1836}

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

◆ InitializePartitionEntry()

static BOOLEAN InitializePartitionEntry ( _Inout_ PPARTENTRY  PartEntry,
_In_opt_ ULONGLONG  SizeBytes,
_In_opt_ ULONG_PTR  PartitionInfo 
)
static

Definition at line 708 of file partlist.c.

712{
713 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
716
717 DPRINT1("Current entry sector count: %I64u\n", PartEntry->SectorCount.QuadPart);
718
719 /* The entry must not be already partitioned and not be void */
720 ASSERT(!PartEntry->IsPartitioned);
721 ASSERT(PartEntry->SectorCount.QuadPart);
722
723 /* Either we create a primary/logical partition, or we create an
724 * extended partition but the entry must not be logical space */
725 ASSERT(!isContainer || !PartEntry->LogicalPartition);
726
727 /* Convert the size in bytes to sector count. SizeBytes being
728 * zero means the caller wants to use all the empty space. */
729 if ((SizeBytes == 0) || (SizeBytes == GetPartEntrySizeInBytes(PartEntry)))
730 {
731 /* Use all of the unpartitioned disk space */
732 SectorCount = PartEntry->SectorCount.QuadPart;
733 }
734 else
735 {
736 SectorCount = SizeBytes / DiskEntry->BytesPerSector;
737 if (SectorCount == 0)
738 {
739 /* SizeBytes was certainly less than the minimal size, so fail */
740 DPRINT1("Partition size %I64u too small\n", SizeBytes);
741 return FALSE;
742 }
743 }
744 DPRINT1(" New sector count: %I64u\n", SectorCount);
745
746 /* Fail if we request more sectors than what the entry actually contains */
747 if (SectorCount > PartEntry->SectorCount.QuadPart)
748 return FALSE;
749
750 if ((SectorCount == 0) ||
751 (AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) -
752 PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart))
753 {
754 /* Reuse the whole current entry */
755 }
756 else
757 {
758 ULONGLONG StartSector;
759 ULONGLONG SectorCount2;
760 PPARTENTRY NewPartEntry;
761
762 /* Create a partition entry that represents the remaining space
763 * after the partition to be initialized */
764
765 StartSector = AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment);
766 SectorCount2 = PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - StartSector;
767
768 NewPartEntry = CreateInsertBlankRegion(DiskEntry,
769 PartEntry->ListEntry.Flink,
770 StartSector,
771 SectorCount2,
772 PartEntry->LogicalPartition);
773 if (!NewPartEntry)
774 {
775 DPRINT1("Failed to create a new empty region for disk space!\n");
776 return FALSE;
777 }
778
779 /* Resize down the partition entry; its StartSector remains the same */
780 PartEntry->SectorCount.QuadPart = StartSector - PartEntry->StartSector.QuadPart;
781 }
782
783 /* Convert the partition entry to 'New (Unformatted)' */
784 PartEntry->New = TRUE;
785 PartEntry->IsPartitioned = TRUE;
786
787 PartEntry->BootIndicator = FALSE;
788 if (PartitionInfo)
789 {
790 if (!isContainer)
791 {
792 PartEntry->PartitionType = (UCHAR)PartitionInfo;
793 }
794 else
795 {
796 /* Set the correct extended container partition type,
797 * depending on whether it is contained below or above
798 * the 1024-cylinder (usually 8.4GB/7.8GiB) boundary:
799 * - below: INT13h CHS partition;
800 * - above: Extended INT13h LBA partition. */
801 if ((PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1)
802 / (DiskEntry->TracksPerCylinder * DiskEntry->SectorsPerTrack) < 1024)
803 {
804 PartEntry->PartitionType = PARTITION_EXTENDED;
805 }
806 else
807 {
808 PartEntry->PartitionType = PARTITION_XINT13_EXTENDED;
809 }
810 }
811 }
812 else
813 {
814// FIXME: Use FileSystemToMBRPartitionType() only for MBR, otherwise use PARTITION_BASIC_DATA_GUID.
815 ASSERT(!isContainer);
816 PartEntry->PartitionType = FileSystemToMBRPartitionType(L"RAW",
817 PartEntry->StartSector.QuadPart,
818 PartEntry->SectorCount.QuadPart);
819 }
820 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
821
822 PartEntry->FormatState = Unformatted;
823 PartEntry->FileSystem[0] = L'\0';
824
825 if (isContainer)
826 {
827 DiskEntry->ExtendedPartition = PartEntry;
828 AddLogicalDiskSpace(DiskEntry);
829 }
830
831 DPRINT1("First Sector : %I64u\n", PartEntry->StartSector.QuadPart);
832 DPRINT1("Last Sector : %I64u\n", PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1);
833 DPRINT1("Total Sectors: %I64u\n", PartEntry->SectorCount.QuadPart);
834
835 return TRUE;
836}
#define PARTITION_EXTENDED
Definition: disk.h:91
#define PARTITION_XINT13_EXTENDED
Definition: disk.h:98
UCHAR FileSystemToMBRPartitionType(IN PCWSTR FileSystem, IN ULONGLONG StartSector, IN ULONGLONG SectorCount)
Definition: fsrec.c:333
#define GetPartEntrySizeInBytes(PartEntry)
Definition: partlist.h:230
ULONGLONG AlignDown(IN ULONGLONG Value, IN ULONG Alignment)
Definition: partlist.c:67
static VOID AddLogicalDiskSpace(_In_ PDISKENTRY DiskEntry)
Definition: partlist.c:678

Referenced by CreatePartition().

◆ 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 */
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 min(a, b)
Definition: monoChain.cc:55
#define max(a, b)
Definition: svc.c:63

Referenced by AddPartitionToDisk().

◆ IsEmptyLayoutEntry()

static BOOLEAN IsEmptyLayoutEntry ( _In_ PPARTITION_INFORMATION  PartitionInfo)
inlinestatic

Definition at line 2417 of file partlist.c.

2419{
2420 return (PartitionInfo->StartingOffset.QuadPart == 0 &&
2421 PartitionInfo->PartitionLength.QuadPart == 0);
2422}

Referenced by UpdateDiskLayout().

◆ IsPartitionActive()

BOOLEAN IsPartitionActive ( IN PPARTENTRY  PartEntry)

Definition at line 1844 of file partlist.c.

1846{
1847 // TODO: Support for GPT disks!
1848
1849 if (IsContainerPartition(PartEntry->PartitionType))
1850 return FALSE;
1851
1852 /* Check if the partition is partitioned, used and active */
1853 if (PartEntry->IsPartitioned &&
1854 // !IsContainerPartition(PartEntry->PartitionType) &&
1855 PartEntry->BootIndicator)
1856 {
1857 /* Yes it is */
1858 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
1859 return TRUE;
1860 }
1861
1862 return FALSE;
1863}

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

◆ IsSamePrimaryLayoutEntry()

static BOOLEAN IsSamePrimaryLayoutEntry ( _In_ PPARTITION_INFORMATION  PartitionInfo,
_In_ PPARTENTRY  PartEntry 
)
inlinestatic

Definition at line 2426 of file partlist.c.

2429{
2430 return ((PartitionInfo->StartingOffset.QuadPart == GetPartEntryOffsetInBytes(PartEntry)) &&
2431 (PartitionInfo->PartitionLength.QuadPart == GetPartEntrySizeInBytes(PartEntry)));
2432// PartitionInfo->PartitionType == PartEntry->PartitionType
2433}
#define GetPartEntryOffsetInBytes(PartEntry)
Definition: partlist.h:227

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 = GetDiskSizeInBytes(DiskEntry);
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 GetDiskSizeInBytes(DiskEntry)
Definition: partlist.h:233

Referenced by AddDiskToList(), BootLoaderHardDiskPage(), ExtendedPartitionCreationChecks(), PartitionCreationChecks(), and xHalIoWritePartitionTable().

◆ IsSupportedActivePartition()

static BOOLEAN IsSupportedActivePartition ( IN PPARTENTRY  PartEntry)
static

Definition at line 3135 of file partlist.c.

3137{
3138 /* Check the type and the file system of this partition */
3139
3140 /*
3141 * We do not support extended partition containers (on MBR disks) marked
3142 * as active, and containing code inside their extended boot records.
3143 */
3144 if (IsContainerPartition(PartEntry->PartitionType))
3145 {
3146 DPRINT1("System partition %lu in disk %lu is an extended partition container?!\n",
3147 PartEntry->PartitionNumber, PartEntry->DiskEntry->DiskNumber);
3148 return FALSE;
3149 }
3150
3151 /*
3152 * ADDITIONAL CHECKS / BIG HACK:
3153 *
3154 * Retrieve its file system and check whether we have
3155 * write support for it. If that is the case we are fine
3156 * and we can use it directly. However if we don't have
3157 * write support we will need to change the active system
3158 * partition.
3159 *
3160 * NOTE that this is completely useless on architectures
3161 * where a real system partition is required, as on these
3162 * architectures the partition uses the FAT FS, for which
3163 * we do have write support.
3164 * NOTE also that for those architectures looking for a
3165 * partition boot indicator is insufficient.
3166 */
3167 if (PartEntry->FormatState == Unformatted)
3168 {
3169 /* If this partition is mounted, it would use RawFS ("RAW") */
3170 return TRUE;
3171 }
3172 else if ((PartEntry->FormatState == Preformatted) ||
3173 (PartEntry->FormatState == Formatted))
3174 {
3175 ASSERT(*PartEntry->FileSystem);
3176
3177 /* NOTE: Please keep in sync with the RegisteredFileSystems list! */
3178 if (wcsicmp(PartEntry->FileSystem, L"FAT") == 0 ||
3179 wcsicmp(PartEntry->FileSystem, L"FAT32") == 0 ||
3180 // wcsicmp(PartEntry->FileSystem, L"NTFS") == 0 ||
3181 wcsicmp(PartEntry->FileSystem, L"BTRFS") == 0)
3182 {
3183 return TRUE;
3184 }
3185 else
3186 {
3187 // WARNING: We cannot write on this FS yet!
3188 DPRINT1("Recognized file system '%S' that doesn't have write support yet!\n",
3189 PartEntry->FileSystem);
3190 return FALSE;
3191 }
3192 }
3193 else // if (PartEntry->FormatState == UnknownFormat)
3194 {
3195 ASSERT(!*PartEntry->FileSystem);
3196
3197 DPRINT1("System partition %lu in disk %lu with no or unknown FS?!\n",
3198 PartEntry->PartitionNumber, PartEntry->DiskEntry->DiskNumber);
3199 return FALSE;
3200 }
3201
3202 // HACK: WARNING: We cannot write on this FS yet!
3203 // See fsutil.c:InferFileSystem()
3204 if (PartEntry->PartitionType == PARTITION_IFS)
3205 {
3206 DPRINT1("Recognized file system '%S' that doesn't have write support yet!\n",
3207 PartEntry->FileSystem);
3208 return FALSE;
3209 }
3210
3211 return TRUE;
3212}
#define PARTITION_IFS
Definition: disk.h:93

Referenced by FindSupportedSystemPartition().

◆ PartitionCreationChecks()

ERROR_NUMBER PartitionCreationChecks ( _In_ PPARTENTRY  PartEntry)

Definition at line 2761 of file partlist.c.

2763{
2764 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2765
2766 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2767 {
2768 DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2769 return ERROR_WARN_PARTITION;
2770 }
2771
2772 /* Fail if the partition is already in use */
2773 if (PartEntry->IsPartitioned)
2774 return ERROR_NEW_PARTITION;
2775
2776 /*
2777 * For primary partitions
2778 */
2779 if (!PartEntry->LogicalPartition)
2780 {
2781 /* Only one primary partition is allowed on super-floppy */
2782 if (IsSuperFloppy(DiskEntry))
2784
2785 /* Fail if there are already 4 primary partitions in the list */
2786 if (GetPrimaryPartitionCount(DiskEntry) >= 4)
2788 }
2789 /*
2790 * For logical partitions
2791 */
2792 else
2793 {
2794 // TODO: Check that we are inside an extended partition!!
2795 // Then the following check will be useless.
2796
2797 /* Only one (primary) partition is allowed on super-floppy */
2798 if (IsSuperFloppy(DiskEntry))
2800 }
2801
2802 return ERROR_SUCCESS;
2803}

Referenced by CreatePartition(), and SelectPartitionPage().

◆ ReAllocateLayoutBuffer()

static BOOLEAN ReAllocateLayoutBuffer ( IN PDISKENTRY  DiskEntry)
static

Definition at line 2471 of file partlist.c.

2473{
2474 PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
2475 ULONG NewPartitionCount;
2476 ULONG CurrentPartitionCount = 0;
2477 ULONG LayoutBufferSize;
2478 ULONG i;
2479
2480 DPRINT1("ReAllocateLayoutBuffer()\n");
2481
2482 NewPartitionCount = 4 + GetLogicalPartitionCount(DiskEntry) * 4;
2483
2484 if (DiskEntry->LayoutBuffer)
2485 CurrentPartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
2486
2487 DPRINT1("CurrentPartitionCount: %lu ; NewPartitionCount: %lu\n",
2488 CurrentPartitionCount, NewPartitionCount);
2489
2490 if (CurrentPartitionCount == NewPartitionCount)
2491 return TRUE;
2492
2493 LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
2494 ((NewPartitionCount - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
2495 NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap,
2497 DiskEntry->LayoutBuffer,
2498 LayoutBufferSize);
2499 if (NewLayoutBuffer == NULL)
2500 {
2501 DPRINT1("Failed to allocate the new layout buffer (size: %lu)\n", LayoutBufferSize);
2502 return FALSE;
2503 }
2504
2505 NewLayoutBuffer->PartitionCount = NewPartitionCount;
2506
2507 /* If the layout buffer grows, make sure the new (empty) entries are written to the disk */
2508 if (NewPartitionCount > CurrentPartitionCount)
2509 {
2510 for (i = CurrentPartitionCount; i < NewPartitionCount; i++)
2511 {
2512 NewLayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
2513 }
2514 }
2515
2516 DiskEntry->LayoutBuffer = NewLayoutBuffer;
2517
2518 return TRUE;
2519}
#define GetLogicalPartitionCount(DiskEntry)
Definition: partlist.c:2464

Referenced by UpdateDiskLayout().

◆ RoundingDivide()

ULONGLONG RoundingDivide ( IN ULONGLONG  Dividend,
IN ULONGLONG  Divisor 
)

Definition at line 95 of file partlist.c.

98{
99 return (Dividend + Divisor / 2) / Divisor;
100}
_In_ LARGE_INTEGER Divisor
Definition: rtlfuncs.h:3044

Referenced by CreatePartitionPage(), IsPartitionLargeEnough(), ListPartition(), PrettifySize1(), PrettifySize2(), PrintDisk(), PrintDiskData(), PrintPartitionData(), and PrintVolume().

◆ ScanForUnpartitionedDiskSpace()

static VOID ScanForUnpartitionedDiskSpace ( IN PDISKENTRY  DiskEntry)
static

Definition at line 1032 of file partlist.c.

1034{
1035 ULONGLONG StartSector;
1037 ULONGLONG LastStartSector;
1038 ULONGLONG LastSectorCount;
1039 ULONGLONG LastUnusedSectorCount;
1040 PPARTENTRY PartEntry;
1041 PPARTENTRY NewPartEntry;
1043
1044 DPRINT("ScanForUnpartitionedDiskSpace()\n");
1045
1046 if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
1047 {
1048 DPRINT1("No primary partition!\n");
1049
1050 /* Create a partition entry that represents the empty disk */
1051
1052 if (DiskEntry->SectorAlignment < 2048)
1053 StartSector = 2048ULL;
1054 else
1055 StartSector = (ULONGLONG)DiskEntry->SectorAlignment;
1056 SectorCount = AlignDown(DiskEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment) - StartSector;
1057
1058 NewPartEntry = CreateInsertBlankRegion(DiskEntry,
1059 &DiskEntry->PrimaryPartListHead,
1060 StartSector,
1062 FALSE);
1063 if (!NewPartEntry)
1064 DPRINT1("Failed to create a new empty region for full disk space!\n");
1065
1066 return;
1067 }
1068
1069 /* Start partition at head 1, cylinder 0 */
1070 if (DiskEntry->SectorAlignment < 2048)
1071 LastStartSector = 2048ULL;
1072 else
1073 LastStartSector = (ULONGLONG)DiskEntry->SectorAlignment;
1074 LastSectorCount = 0ULL;
1075 LastUnusedSectorCount = 0ULL;
1076
1077 for (Entry = DiskEntry->PrimaryPartListHead.Flink;
1078 Entry != &DiskEntry->PrimaryPartListHead;
1079 Entry = Entry->Flink)
1080 {
1081 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1082
1083 if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
1084 PartEntry->SectorCount.QuadPart != 0ULL)
1085 {
1086 LastUnusedSectorCount =
1087 PartEntry->StartSector.QuadPart - (LastStartSector + LastSectorCount);
1088
1089 if (PartEntry->StartSector.QuadPart > (LastStartSector + LastSectorCount) &&
1090 LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
1091 {
1092 DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
1093
1094 StartSector = LastStartSector + LastSectorCount;
1095 SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
1096
1097 /* Insert the table into the list */
1098 NewPartEntry = CreateInsertBlankRegion(DiskEntry,
1099 &PartEntry->ListEntry,
1100 StartSector,
1102 FALSE);
1103 if (!NewPartEntry)
1104 {
1105 DPRINT1("Failed to create a new empty region for disk space!\n");
1106 return;
1107 }
1108 }
1109
1110 LastStartSector = PartEntry->StartSector.QuadPart;
1111 LastSectorCount = PartEntry->SectorCount.QuadPart;
1112 }
1113 }
1114
1115 /* Check for trailing unpartitioned disk space */
1116 if ((LastStartSector + LastSectorCount) < DiskEntry->SectorCount.QuadPart)
1117 {
1118 LastUnusedSectorCount = AlignDown(DiskEntry->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
1119
1120 if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
1121 {
1122 DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
1123
1124 StartSector = LastStartSector + LastSectorCount;
1125 SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
1126
1127 /* Append the table to the list */
1128 NewPartEntry = CreateInsertBlankRegion(DiskEntry,
1129 &DiskEntry->PrimaryPartListHead,
1130 StartSector,
1132 FALSE);
1133 if (!NewPartEntry)
1134 {
1135 DPRINT1("Failed to create a new empty region for trailing disk space!\n");
1136 return;
1137 }
1138 }
1139 }
1140
1141 if (DiskEntry->ExtendedPartition != NULL)
1142 {
1143 if (IsListEmpty(&DiskEntry->LogicalPartListHead))
1144 {
1145 DPRINT1("No logical partition!\n");
1146
1147 /* Create a partition entry that represents the empty extended partition */
1148 AddLogicalDiskSpace(DiskEntry);
1149 return;
1150 }
1151
1152 /* Start partition at head 1, cylinder 0 */
1153 LastStartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
1154 LastSectorCount = 0ULL;
1155 LastUnusedSectorCount = 0ULL;
1156
1157 for (Entry = DiskEntry->LogicalPartListHead.Flink;
1158 Entry != &DiskEntry->LogicalPartListHead;
1159 Entry = Entry->Flink)
1160 {
1161 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1162
1163 if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
1164 PartEntry->SectorCount.QuadPart != 0ULL)
1165 {
1166 LastUnusedSectorCount =
1167 PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment - (LastStartSector + LastSectorCount);
1168
1169 if ((PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment) > (LastStartSector + LastSectorCount) &&
1170 LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
1171 {
1172 DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
1173
1174 StartSector = LastStartSector + LastSectorCount;
1175 SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
1176
1177 /* Insert the table into the list */
1178 NewPartEntry = CreateInsertBlankRegion(DiskEntry,
1179 &PartEntry->ListEntry,
1180 StartSector,
1182 TRUE);
1183 if (!NewPartEntry)
1184 {
1185 DPRINT1("Failed to create a new empty region for extended partition space!\n");
1186 return;
1187 }
1188 }
1189
1190 LastStartSector = PartEntry->StartSector.QuadPart;
1191 LastSectorCount = PartEntry->SectorCount.QuadPart;
1192 }
1193 }
1194
1195 /* Check for trailing unpartitioned disk space */
1196 if ((LastStartSector + LastSectorCount) < DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart)
1197 {
1198 LastUnusedSectorCount = AlignDown(DiskEntry->ExtendedPartition->StartSector.QuadPart +
1199 DiskEntry->ExtendedPartition->SectorCount.QuadPart - (LastStartSector + LastSectorCount),
1200 DiskEntry->SectorAlignment);
1201
1202 if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
1203 {
1204 DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
1205
1206 StartSector = LastStartSector + LastSectorCount;
1207 SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
1208
1209 /* Append the table to the list */
1210 NewPartEntry = CreateInsertBlankRegion(DiskEntry,
1211 &DiskEntry->LogicalPartListHead,
1212 StartSector,
1214 TRUE);
1215 if (!NewPartEntry)
1216 {
1217 DPRINT1("Failed to create a new empty region for extended partition space!\n");
1218 return;
1219 }
1220 }
1221 }
1222 }
1223
1224 DPRINT("ScanForUnpartitionedDiskSpace() done\n");
1225}
#define for
Definition: utility.h:88
#define ULL(a, b)
Definition: format_msg.c:27

Referenced by AddDiskToList().

◆ SelectPartition()

PPARTENTRY SelectPartition ( _In_ PPARTLIST  List,
_In_ ULONG  DiskNumber,
_In_ ULONG  PartitionNumber 
)

Definition at line 2204 of file partlist.c.

2208{
2209 PDISKENTRY DiskEntry;
2210 PPARTENTRY PartEntry;
2211
2212 /* Find the disk */
2213 DiskEntry = GetDiskByNumber(List, DiskNumber);
2214 if (!DiskEntry)
2215 return NULL;
2216 ASSERT(DiskEntry->DiskNumber == DiskNumber);
2217
2218 /* Find the partition */
2219 PartEntry = GetPartition(DiskEntry, PartitionNumber);
2220 if (!PartEntry)
2221 return NULL;
2222 ASSERT(PartEntry->DiskEntry == DiskEntry);
2223 ASSERT(PartEntry->PartitionNumber == PartitionNumber);
2224
2225 return PartEntry;
2226}
PPARTENTRY GetPartition(_In_ PDISKENTRY DiskEntry, _In_ ULONG PartitionNumber)
Definition: partlist.c:2163
PDISKENTRY GetDiskByNumber(_In_ PPARTLIST List, _In_ ULONG DiskNumber)
Definition: partlist.c:2087

Referenced by EnumerateInstallations(), and SelectPartitionPage().

◆ SetActivePartition()

BOOLEAN SetActivePartition ( IN PPARTLIST  List,
IN PPARTENTRY  PartEntry,
IN PPARTENTRY OldActivePart  OPTIONAL 
)

Definition at line 3515 of file partlist.c.

3519{
3520 /* Check for empty disk list */
3521 if (IsListEmpty(&List->DiskListHead))
3522 return FALSE;
3523
3524 /* Validate the partition entry */
3525 if (!PartEntry)
3526 return FALSE;
3527
3528 /*
3529 * If the partition entry is already the system partition, or if it is
3530 * the same as the old active partition hint the user provided (and if
3531 * it is already active), just return success.
3532 */
3533 if ((PartEntry == List->SystemPartition) ||
3534 ((PartEntry == OldActivePart) && IsPartitionActive(OldActivePart)))
3535 {
3536 return TRUE;
3537 }
3538
3539 ASSERT(PartEntry->DiskEntry);
3540
3541 /* Ensure that the partition's disk is in the list */
3542 ASSERT(PartEntry->DiskEntry->PartList == List);
3543
3544 /*
3545 * If the user provided an old active partition hint, verify that it is
3546 * indeeed active and belongs to the same disk where the new partition
3547 * belongs. Otherwise determine the current active partition on the disk
3548 * where the new partition belongs.
3549 */
3550 if (!(OldActivePart && IsPartitionActive(OldActivePart) && (OldActivePart->DiskEntry == PartEntry->DiskEntry)))
3551 {
3552 /* It's not, determine the current active partition for the disk */
3553 OldActivePart = GetActiveDiskPartition(PartEntry->DiskEntry);
3554 }
3555
3556 /* Unset the old active partition if it exists */
3557 if (OldActivePart)
3558 {
3559 OldActivePart->BootIndicator = FALSE;
3560 OldActivePart->DiskEntry->LayoutBuffer->PartitionEntry[OldActivePart->PartitionIndex].BootIndicator = FALSE;
3561 OldActivePart->DiskEntry->LayoutBuffer->PartitionEntry[OldActivePart->PartitionIndex].RewritePartition = TRUE;
3562 OldActivePart->DiskEntry->Dirty = TRUE;
3563 }
3564
3565 /* Modify the system partition if the new partition is on the system disk */
3566 if (PartEntry->DiskEntry == GetSystemDisk(List))
3567 List->SystemPartition = PartEntry;
3568
3569 /* Set the new active partition */
3570 PartEntry->BootIndicator = TRUE;
3571 PartEntry->DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].BootIndicator = TRUE;
3572 PartEntry->DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
3573 PartEntry->DiskEntry->Dirty = TRUE;
3574
3575 return TRUE;
3576}

Referenced by InitSystemPartition().

◆ SetDiskSignature()

static VOID SetDiskSignature ( IN PPARTLIST  List,
IN PDISKENTRY  DiskEntry 
)
static

Definition at line 1229 of file partlist.c.

1232{
1233 LARGE_INTEGER SystemTime;
1235 PLIST_ENTRY Entry2;
1236 PDISKENTRY DiskEntry2;
1237 PUCHAR Buffer;
1238
1239 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1240 {
1241 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1242 return;
1243 }
1244
1245 Buffer = (PUCHAR)&DiskEntry->LayoutBuffer->Signature;
1246
1247 while (TRUE)
1248 {
1249 NtQuerySystemTime(&SystemTime);
1250 RtlTimeToTimeFields(&SystemTime, &TimeFields);
1251
1252 Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF);
1253 Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF);
1254 Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF);
1255 Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF);
1256
1257 if (DiskEntry->LayoutBuffer->Signature == 0)
1258 {
1259 continue;
1260 }
1261
1262 /* Check if the signature already exist */
1263 /* FIXME:
1264 * Check also signatures from disks, which are
1265 * not visible (bootable) by the bios.
1266 */
1267 for (Entry2 = List->DiskListHead.Flink;
1268 Entry2 != &List->DiskListHead;
1269 Entry2 = Entry2->Flink)
1270 {
1271 DiskEntry2 = CONTAINING_RECORD(Entry2, DISKENTRY, ListEntry);
1272
1273 if (DiskEntry2->DiskStyle == PARTITION_STYLE_GPT)
1274 {
1275 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1276 continue;
1277 }
1278
1279 if (DiskEntry != DiskEntry2 &&
1280 DiskEntry->LayoutBuffer->Signature == DiskEntry2->LayoutBuffer->Signature)
1281 break;
1282 }
1283
1284 if (Entry2 == &List->DiskListHead)
1285 break;
1286 }
1287}
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
BOOLEAN RtlTimeToTimeFields(IN PLARGE_INTEGER Time, IN PTIME_FIELDS TimeFields)
static PTIME_FIELDS TimeFields
Definition: time.c:104
NTSTATUS NTAPI NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
Definition: time.c:569
USHORT Milliseconds
Definition: env_spec_w32.h:717
unsigned char * PUCHAR
Definition: typedefs.h:53

Referenced by UpdateDiskSignatures().

◆ SetMBRPartitionType()

VOID SetMBRPartitionType ( IN PPARTENTRY  PartEntry,
IN UCHAR  PartitionType 
)

Definition at line 3897 of file partlist.c.

3900{
3901 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
3902
3903 ASSERT(DiskEntry->DiskStyle == PARTITION_STYLE_MBR);
3904
3905 PartEntry->PartitionType = PartitionType;
3906
3907 DiskEntry->Dirty = TRUE;
3908 DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartitionType;
3909 DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RecognizedPartition = IsRecognizedPartition(PartitionType);
3910 DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
3911}
CHAR PartitionType
Definition: part_xbox.c:32
BOOLEAN Dirty
Definition: partlist.h:115
BOOLEAN RecognizedPartition
Definition: ntdddisk.h:414

Referenced by FormatPartition().

◆ SetMountedDeviceValue()

BOOLEAN SetMountedDeviceValue ( IN WCHAR  Letter,
IN ULONG  Signature,
IN LARGE_INTEGER  StartingOffset 
)

Definition at line 3760 of file partlist.c.

3764{
3767 UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"SYSTEM\\MountedDevices");
3769 WCHAR ValueNameBuffer[16];
3771 REG_DISK_MOUNT_INFO MountInfo;
3772
3773 RtlStringCchPrintfW(ValueNameBuffer, ARRAYSIZE(ValueNameBuffer),
3774 L"\\DosDevices\\%c:", Letter);
3775 RtlInitUnicodeString(&ValueName, ValueNameBuffer);
3776
3778 &KeyName,
3781 NULL);
3782
3786 if (!NT_SUCCESS(Status))
3787 {
3791 0,
3792 NULL,
3794 NULL);
3795 }
3796 if (!NT_SUCCESS(Status))
3797 {
3798 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
3799 return FALSE;
3800 }
3801
3802 MountInfo.Signature = Signature;
3803 MountInfo.StartingOffset = StartingOffset;
3805 &ValueName,
3806 0,
3807 REG_BINARY,
3808 (PVOID)&MountInfo,
3809 sizeof(MountInfo));
3811 if (!NT_SUCCESS(Status))
3812 {
3813 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
3814 return FALSE;
3815 }
3816
3817 return TRUE;
3818}
HANDLE GetRootKeyByPredefKey(IN HANDLE KeyHandle, OUT PCWSTR *RootKeyMountPoint OPTIONAL)
Definition: registry.c:90
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:291
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
NTSYSAPI NTSTATUS NTAPI NtSetValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN ULONG TitleIndex OPTIONAL, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: ntapi.c:859
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
NTSTATUS NTAPI NtCreateKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG TitleIndex, IN PUNICODE_STRING Class OPTIONAL, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
Definition: ntapi.c:240
LARGE_INTEGER StartingOffset
Definition: partlist.c:26
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by SetMountedDeviceValues().

◆ SetMountedDeviceValues()

BOOLEAN SetMountedDeviceValues ( IN PPARTLIST  List)

Definition at line 3821 of file partlist.c.

3823{
3824 PLIST_ENTRY Entry1, Entry2;
3825 PDISKENTRY DiskEntry;
3826 PPARTENTRY PartEntry;
3828
3829 if (List == NULL)
3830 return FALSE;
3831
3832 for (Entry1 = List->DiskListHead.Flink;
3833 Entry1 != &List->DiskListHead;
3834 Entry1 = Entry1->Flink)
3835 {
3836 DiskEntry = CONTAINING_RECORD(Entry1,
3837 DISKENTRY,
3838 ListEntry);
3839
3840 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3841 {
3842 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3843 continue;
3844 }
3845
3846 for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
3847 Entry2 != &DiskEntry->PrimaryPartListHead;
3848 Entry2 = Entry2->Flink)
3849 {
3850 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
3851 if (PartEntry->IsPartitioned) // && !IsContainerPartition(PartEntry->PartitionType)
3852 {
3854
3855 /* Assign a "\DosDevices\#:" mount point to this partition */
3856 if (PartEntry->DriveLetter)
3857 {
3858 StartingOffset.QuadPart = GetPartEntryOffsetInBytes(PartEntry);
3859 if (!SetMountedDeviceValue(PartEntry->DriveLetter,
3860 DiskEntry->LayoutBuffer->Signature,
3862 {
3863 return FALSE;
3864 }
3865 }
3866 }
3867 }
3868
3869 for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
3870 Entry2 != &DiskEntry->LogicalPartListHead;
3871 Entry2 = Entry2->Flink)
3872 {
3873 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
3874 if (PartEntry->IsPartitioned) // && !IsContainerPartition(PartEntry->PartitionType)
3875 {
3877
3878 /* Assign a "\DosDevices\#:" mount point to this partition */
3879 if (PartEntry->DriveLetter)
3880 {
3881 StartingOffset.QuadPart = GetPartEntryOffsetInBytes(PartEntry);
3882 if (!SetMountedDeviceValue(PartEntry->DriveLetter,
3883 DiskEntry->LayoutBuffer->Signature,
3885 {
3886 return FALSE;
3887 }
3888 }
3889 }
3890 }
3891 }
3892
3893 return TRUE;
3894}
BOOLEAN SetMountedDeviceValue(IN WCHAR Letter, IN ULONG Signature, IN LARGE_INTEGER StartingOffset)
Definition: partlist.c:3760

Referenced by UpdateRegistry().

◆ SystemConfigurationDataQueryRoutine()

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

Definition at line 290 of file partlist.c.

297{
298 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
300 ULONG i;
301
304 return STATUS_UNSUCCESSFUL;
305
306 FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
307
308 /* Hm. Version and Revision are not set on Microsoft Windows XP... */
309#if 0
310 if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
311 FullResourceDescriptor->PartialResourceList.Revision != 1)
312 return STATUS_UNSUCCESSFUL;
313#endif
314
315 for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
316 {
318 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize % sizeof(CM_INT13_DRIVE_PARAMETER) != 0)
319 continue;
320
322 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
323 if (*Int13Drives == NULL)
324 return STATUS_NO_MEMORY;
325
326 memcpy(*Int13Drives,
327 &FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1],
328 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
329 return STATUS_SUCCESS;
330 }
331
332 return STATUS_UNSUCCESSFUL;
333}
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260

Referenced by EnumerateBiosDiskEntries().

◆ UpdateDiskLayout()

static VOID UpdateDiskLayout ( IN PDISKENTRY  DiskEntry)
static

Definition at line 2523 of file partlist.c.

2525{
2527 PPARTITION_INFORMATION LinkInfo;
2528 PLIST_ENTRY ListEntry;
2529 PPARTENTRY PartEntry;
2530 LARGE_INTEGER HiddenSectors64;
2531 ULONG Index;
2533
2534 DPRINT1("UpdateDiskLayout()\n");
2535
2536 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2537 {
2538 DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2539 return;
2540 }
2541
2542 /* Resize the layout buffer if necessary */
2543 if (ReAllocateLayoutBuffer(DiskEntry) == FALSE)
2544 {
2545 DPRINT("ReAllocateLayoutBuffer() failed.\n");
2546 return;
2547 }
2548
2549 /* Update the primary partition table */
2550 Index = 0;
2551 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
2552 ListEntry != &DiskEntry->PrimaryPartListHead;
2553 ListEntry = ListEntry->Flink)
2554 {
2555 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
2556
2557 if (PartEntry->IsPartitioned)
2558 {
2560
2561 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
2562 PartEntry->PartitionIndex = Index;
2563
2564 /* Reset the current partition number only for newly-created (unmounted) partitions */
2565 if (PartEntry->New)
2566 PartEntry->PartitionNumber = 0;
2567
2569
2570 if (!IsSamePrimaryLayoutEntry(PartitionInfo, PartEntry))
2571 {
2572 DPRINT1("Updating primary partition entry %lu\n", Index);
2573
2574 PartitionInfo->StartingOffset.QuadPart = GetPartEntryOffsetInBytes(PartEntry);
2575 PartitionInfo->PartitionLength.QuadPart = GetPartEntrySizeInBytes(PartEntry);
2576 PartitionInfo->HiddenSectors = PartEntry->StartSector.LowPart;
2577 PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
2578 PartitionInfo->PartitionType = PartEntry->PartitionType;
2579 PartitionInfo->BootIndicator = PartEntry->BootIndicator;
2580 PartitionInfo->RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
2581 PartitionInfo->RewritePartition = TRUE;
2582 }
2583
2584 if (!IsContainerPartition(PartEntry->PartitionType))
2586
2587 Index++;
2588 }
2589 }
2590
2591 ASSERT(Index <= 4);
2592
2593 /* Update the logical partition table */
2594 LinkInfo = NULL;
2595 Index = 4;
2596 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
2597 ListEntry != &DiskEntry->LogicalPartListHead;
2598 ListEntry = ListEntry->Flink)
2599 {
2600 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
2601
2602 if (PartEntry->IsPartitioned)
2603 {
2605
2606 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
2607 PartEntry->PartitionIndex = Index;
2608
2609 /* Reset the current partition number only for newly-created (unmounted) partitions */
2610 if (PartEntry->New)
2611 PartEntry->PartitionNumber = 0;
2612
2614
2615 DPRINT1("Updating logical partition entry %lu\n", Index);
2616
2617 PartitionInfo->StartingOffset.QuadPart = GetPartEntryOffsetInBytes(PartEntry);
2618 PartitionInfo->PartitionLength.QuadPart = GetPartEntrySizeInBytes(PartEntry);
2619 PartitionInfo->HiddenSectors = DiskEntry->SectorAlignment;
2620 PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
2621 PartitionInfo->PartitionType = PartEntry->PartitionType;
2622 PartitionInfo->BootIndicator = FALSE;
2623 PartitionInfo->RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
2624 PartitionInfo->RewritePartition = TRUE;
2625
2626 /* Fill the link entry of the previous partition entry */
2627 if (LinkInfo)
2628 {
2629 LinkInfo->StartingOffset.QuadPart = (PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
2630 LinkInfo->PartitionLength.QuadPart = (PartEntry->StartSector.QuadPart + DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
2631 HiddenSectors64.QuadPart = PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment - DiskEntry->ExtendedPartition->StartSector.QuadPart;
2632 LinkInfo->HiddenSectors = HiddenSectors64.LowPart;
2633 LinkInfo->PartitionNumber = 0;
2634
2635 /* Extended partition links only use type 0x05, as observed
2636 * on Windows NT. Alternatively they could inherit the type
2637 * of the main extended container. */
2638 LinkInfo->PartitionType = PARTITION_EXTENDED; // DiskEntry->ExtendedPartition->PartitionType;
2639
2640 LinkInfo->BootIndicator = FALSE;
2641 LinkInfo->RecognizedPartition = FALSE;
2642 LinkInfo->RewritePartition = TRUE;
2643 }
2644
2645 /* Save a pointer to the link entry of the current partition entry */
2646 LinkInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index + 1];
2647
2649 Index += 4;
2650 }
2651 }
2652
2653 /* Wipe unused primary partition entries */
2654 for (Index = GetPrimaryPartitionCount(DiskEntry); Index < 4; Index++)
2655 {
2656 DPRINT1("Primary partition entry %lu\n", Index);
2657
2658 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
2659
2661 {
2662 DPRINT1("Wiping primary partition entry %lu\n", Index);
2663
2664 PartitionInfo->StartingOffset.QuadPart = 0;
2665 PartitionInfo->PartitionLength.QuadPart = 0;
2666 PartitionInfo->HiddenSectors = 0;
2667 PartitionInfo->PartitionNumber = 0;
2668 PartitionInfo->PartitionType = PARTITION_ENTRY_UNUSED;
2669 PartitionInfo->BootIndicator = FALSE;
2670 PartitionInfo->RecognizedPartition = FALSE;
2671 PartitionInfo->RewritePartition = TRUE;
2672 }
2673 }
2674
2675 /* Wipe unused logical partition entries */
2676 for (Index = 4; Index < DiskEntry->LayoutBuffer->PartitionCount; Index++)
2677 {
2678 if (Index % 4 >= 2)
2679 {
2680 DPRINT1("Logical partition entry %lu\n", Index);
2681
2682 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
2683
2685 {
2686 DPRINT1("Wiping partition entry %lu\n", Index);
2687
2688 PartitionInfo->StartingOffset.QuadPart = 0;
2689 PartitionInfo->PartitionLength.QuadPart = 0;
2690 PartitionInfo->HiddenSectors = 0;
2691 PartitionInfo->PartitionNumber = 0;
2692 PartitionInfo->PartitionType = PARTITION_ENTRY_UNUSED;
2693 PartitionInfo->BootIndicator = FALSE;
2694 PartitionInfo->RecognizedPartition = FALSE;
2695 PartitionInfo->RewritePartition = TRUE;
2696 }
2697 }
2698 }
2699
2700 // HACK: See the FIXMEs in WritePartitions(): (Re)set the PartitionStyle to MBR.
2701 DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
2702
2703 DiskEntry->Dirty = TRUE;
2704
2705#ifdef DUMP_PARTITION_TABLE
2706 DumpPartitionTable(DiskEntry);
2707#endif
2708}
BOOLEAN New
Definition: partlist.h:71
$ULONG LowPart
Definition: ntbasedef.h:569
static BOOLEAN IsSamePrimaryLayoutEntry(IN PPARTITION_INFORMATION PartitionInfo, IN PDISKENTRY DiskEntry, IN PPARTENTRY PartEntry)
Definition: partlist.c:1619
static BOOLEAN IsEmptyLayoutEntry(IN PPARTITION_INFORMATION PartitionInfo)
Definition: partlist.c:1604
static BOOLEAN ReAllocateLayoutBuffer(_In_ PDISKENTRY DiskEntry)
Definition: partlist.c:1679
ULONG LowPart
Definition: typedefs.h:106
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by active_main(), CreateExtendedPartition(), CreateLogicalPartition(), CreatePartition(), CreatePrimaryPartition(), DeletePartition(), inactive_main(), setid_main(), and UniqueIdDisk().

◆ UpdateDiskSignatures()

static VOID UpdateDiskSignatures ( IN PPARTLIST  List)
static

Definition at line 1291 of file partlist.c.

1293{
1295 PDISKENTRY DiskEntry;
1296
1297 /* Update each disk */
1298 for (Entry = List->DiskListHead.Flink;
1299 Entry != &List->DiskListHead;
1300 Entry = Entry->Flink)
1301 {
1302 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
1303
1304 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1305 {
1306 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1307 continue;
1308 }
1309
1310 if (DiskEntry->LayoutBuffer &&
1311 DiskEntry->LayoutBuffer->Signature == 0)
1312 {
1313 SetDiskSignature(List, DiskEntry);
1315 }
1316 }
1317}
static VOID SetDiskSignature(IN PPARTLIST List, IN PDISKENTRY DiskEntry)
Definition: partlist.c:1229

Referenced by CreatePartitionList().

◆ UpdateHwDiskNumbers()

static VOID UpdateHwDiskNumbers ( IN PPARTLIST  List)
static

Definition at line 1321 of file partlist.c.

1323{
1324 PLIST_ENTRY ListEntry;
1325 PBIOSDISKENTRY BiosDiskEntry;
1326 PDISKENTRY DiskEntry;
1327 ULONG HwAdapterNumber = 0;
1328 ULONG HwControllerNumber = 0;
1329 ULONG RemovableDiskCount = 0;
1330
1331 /*
1332 * Enumerate the disks recognized by the BIOS and recompute the disk
1333 * numbers on the system when *ALL* removable disks are not connected.
1334 * The entries are inserted in increasing order of AdapterNumber,
1335 * ControllerNumber and DiskNumber.
1336 */
1337 for (ListEntry = List->BiosDiskListHead.Flink;
1338 ListEntry != &List->BiosDiskListHead;
1339 ListEntry = ListEntry->Flink)
1340 {
1341 BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
1342 DiskEntry = BiosDiskEntry->DiskEntry;
1343
1344 /*
1345 * If the adapter or controller numbers change, update them and reset
1346 * the number of removable disks on this adapter/controller.
1347 */
1348 if (HwAdapterNumber != BiosDiskEntry->AdapterNumber ||
1349 HwControllerNumber != BiosDiskEntry->ControllerNumber)
1350 {
1351 HwAdapterNumber = BiosDiskEntry->AdapterNumber;
1352 HwControllerNumber = BiosDiskEntry->ControllerNumber;
1353 RemovableDiskCount = 0;
1354 }
1355
1356 /* Adjust the actual hardware disk number */
1357 if (DiskEntry)
1358 {
1359 ASSERT(DiskEntry->HwDiskNumber == BiosDiskEntry->DiskNumber);
1360
1361 if (DiskEntry->MediaType == RemovableMedia)
1362 {
1363 /* Increase the number of removable disks and set the disk number to zero */
1364 ++RemovableDiskCount;
1365 DiskEntry->HwFixedDiskNumber = 0;
1366 }
1367 else // if (DiskEntry->MediaType == FixedMedia)
1368 {
1369 /* Adjust the fixed disk number, offset by the number of removable disks found before this one */
1370 DiskEntry->HwFixedDiskNumber = BiosDiskEntry->DiskNumber - RemovableDiskCount;
1371 }
1372 }
1373 else
1374 {
1375 DPRINT1("BIOS disk %lu is not recognized by NTOS!\n", BiosDiskEntry->DiskNumber);
1376 }
1377 }
1378}

Referenced by CreatePartitionList().

◆ WritePartitions()

NTSTATUS WritePartitions ( IN PDISKENTRY  DiskEntry)

Definition at line 3579 of file partlist.c.

3581{
3589 ULONG PartitionCount;
3590 PLIST_ENTRY ListEntry;
3591 PPARTENTRY PartEntry;
3593
3594 DPRINT("WritePartitions() Disk: %lu\n", DiskEntry->DiskNumber);
3595
3596 /* If the disk is not dirty, there is nothing to do */
3597 if (!DiskEntry->Dirty)
3598 return STATUS_SUCCESS;
3599
3601 L"\\Device\\Harddisk%lu\\Partition0",
3602 DiskEntry->DiskNumber);
3604
3606 &Name,
3608 NULL,
3609 NULL);
3610
3614 &Iosb,
3615 0,
3617 if (!NT_SUCCESS(Status))
3618 {
3619 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
3620 return Status;
3621 }
3622
3623#ifdef DUMP_PARTITION_TABLE
3624 DumpPartitionTable(DiskEntry);
3625#endif
3626
3627 //
3628 // FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize
3629 // the disk in MBR or GPT format in case the disk was not initialized!!
3630 // For this we must ask the user which format to use.
3631 //
3632
3633 /* Save the original partition count to be restored later (see comment below) */
3634 PartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
3635
3636 /* Set the new disk layout and retrieve its updated version with possibly modified partition numbers */
3638 ((PartitionCount - 1) * sizeof(PARTITION_INFORMATION));
3640 NULL,
3641 NULL,
3642 NULL,
3643 &Iosb,
3645 DiskEntry->LayoutBuffer,
3646 BufferSize,
3647 DiskEntry->LayoutBuffer,
3648 BufferSize);
3650
3651 /*
3652 * IOCTL_DISK_SET_DRIVE_LAYOUT calls IoWritePartitionTable(), which converts
3653 * DiskEntry->LayoutBuffer->PartitionCount into a partition *table* count,
3654 * where such a table is expected to enumerate up to 4 partitions:
3655 * partition *table* count == ROUND_UP(PartitionCount, 4) / 4 .
3656 * Due to this we need to restore the original PartitionCount number.
3657 */
3658 DiskEntry->LayoutBuffer->PartitionCount = PartitionCount;
3659
3660 /* Check whether the IOCTL_DISK_SET_DRIVE_LAYOUT call succeeded */
3661 if (!NT_SUCCESS(Status))
3662 {
3663 DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status);
3664 return Status;
3665 }
3666
3667#ifdef DUMP_PARTITION_TABLE
3668 DumpPartitionTable(DiskEntry);
3669#endif
3670
3671 /* Update the partition numbers */
3672
3673 /* Update the primary partition table */
3674 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3675 ListEntry != &DiskEntry->PrimaryPartListHead;
3676 ListEntry = ListEntry->Flink)
3677 {
3678 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3679
3680 if (PartEntry->IsPartitioned)
3681 {
3683 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
3684 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
3685 }
3686 }
3687
3688 /* Update the logical partition table */
3689 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
3690 ListEntry != &DiskEntry->LogicalPartListHead;
3691 ListEntry = ListEntry->Flink)
3692 {
3693 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3694
3695 if (PartEntry->IsPartitioned)
3696 {
3698 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
3699 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
3700 }
3701 }
3702
3703 //
3704 // NOTE: Originally (see r40437), we used to install here also a new MBR
3705 // for this disk (by calling InstallMbrBootCodeToDisk), only if:
3706 // DiskEntry->NewDisk == TRUE and DiskEntry->HwDiskNumber == 0.
3707 // Then after that, both DiskEntry->NewDisk and DiskEntry->NoMbr were set
3708 // to FALSE. In the other place (in usetup.c) where InstallMbrBootCodeToDisk
3709 // was called too, the installation test was modified by checking whether
3710 // DiskEntry->NoMbr was TRUE (instead of NewDisk).
3711 //
3712
3713 // HACK: Parts of FIXMEs described above: (Re)set the PartitionStyle to MBR.
3714 DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
3715
3716 /* The layout has been successfully updated, the disk is not dirty anymore */
3717 DiskEntry->Dirty = FALSE;
3718
3719 return Status;
3720}
#define BufferSize
Definition: mmc.h:75
#define IOCTL_DISK_SET_DRIVE_LAYOUT
Definition: ntdddisk.h:205
IN HANDLE DstPath
Definition: fsutil.h:76
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254

Referenced by active_main(), CreateExtendedPartition(), CreateLogicalPartition(), CreatePrimaryPartition(), DeletePartition(), FormatPartition(), inactive_main(), setid_main(), UniqueIdDisk(), and WritePartitionsToDisk().

◆ WritePartitionsToDisk()

BOOLEAN WritePartitionsToDisk ( IN PPARTLIST  List)

Definition at line 3723 of file partlist.c.

3725{
3728 PDISKENTRY DiskEntry;
3729
3730 if (List == NULL)
3731 return TRUE;
3732
3733 for (Entry = List->DiskListHead.Flink;
3734 Entry != &List->DiskListHead;
3735 Entry = Entry->Flink)
3736 {
3737 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
3738
3739 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3740 {
3741 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3742 continue;
3743 }
3744
3745 if (DiskEntry->Dirty != FALSE)
3746 {
3747 Status = WritePartitions(DiskEntry);
3748 if (!NT_SUCCESS(Status))
3749 {
3750 DPRINT1("WritePartitionsToDisk() failed to update disk %lu, Status 0x%08lx\n",
3751 DiskEntry->DiskNumber, Status);
3752 }
3753 }
3754 }
3755
3756 return TRUE;
3757}
NTSTATUS WritePartitions(IN PDISKENTRY DiskEntry)
Definition: partlist.c:3579

Referenced by FsVolCommitOpsQueue().