ReactOS 0.4.16-dev-2104-gb84fa49
partlist.c File Reference
#include "diskpart.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  _PARTITION
 
struct  _PARTITION_SECTOR
 

Macros

#define NDEBUG
 
#define InsertAscendingList(ListHead, NewEntry, Type, ListEntryField, SortField)
 
#define PARTITION_LINUX   0x83
 
#define PARTITION_TBL_SIZE   4
 
#define MBR_MAGIC   0xAA55
 
#define ROOT_NAME   L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
 

Typedefs

typedef struct _PARTITION PARTITION
 
typedef struct _PARTITIONPPARTITION
 
typedef struct _PARTITION_SECTOR PARTITION_SECTOR
 
typedef struct _PARTITION_SECTORPPARTITION_SECTOR
 

Functions

ULONGLONG AlignDown (_In_ ULONGLONG Value, _In_ ULONG Alignment)
 
static VOID GetDriverName (PDISKENTRY DiskEntry)
 
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 (VOID)
 
static VOID AddMbrPartitionToDisk (ULONG DiskNumber, PDISKENTRY DiskEntry, ULONG PartitionIndex, BOOLEAN LogicalPartition)
 
static VOID AddGptPartitionToDisk (ULONG DiskNumber, PDISKENTRY DiskEntry, ULONG PartitionIndex)
 
VOID ScanForUnpartitionedMbrDiskSpace (PDISKENTRY DiskEntry)
 
VOID ScanForUnpartitionedGptDiskSpace (PDISKENTRY DiskEntry)
 
VOID ReadLayoutBuffer (_In_ HANDLE FileHandle, _In_ PDISKENTRY DiskEntry)
 
static VOID AddDiskToList (HANDLE FileHandle, ULONG DiskNumber)
 
NTSTATUS CreatePartitionList (VOID)
 
VOID DestroyPartitionList (VOID)
 
static VOID GetVolumeExtents (_In_ HANDLE VolumeHandle, _In_ PVOLENTRY VolumeEntry)
 
static VOID GetVolumeType (_In_ HANDLE VolumeHandle, _In_ PVOLENTRY VolumeEntry)
 
static VOID GetVolumeSize (_In_ HANDLE VolumeHandle, _In_ PVOLENTRY VolumeEntry)
 
static VOID AddVolumeToList (ULONG ulVolumeNumber, PWSTR pszVolumeName)
 
NTSTATUS CreateVolumeList (VOID)
 
VOID DestroyVolumeList (VOID)
 
NTSTATUS WriteMbrPartitions (_In_ PDISKENTRY DiskEntry)
 
NTSTATUS WriteGptPartitions (_In_ PDISKENTRY DiskEntry)
 
static BOOLEAN IsEmptyLayoutEntry (IN PPARTITION_INFORMATION_EX PartitionInfo)
 
static BOOLEAN IsSamePrimaryLayoutEntry (IN PPARTITION_INFORMATION_EX PartitionInfo, IN PDISKENTRY DiskEntry, IN PPARTENTRY PartEntry)
 
ULONG GetPrimaryPartitionCount (_In_ PDISKENTRY DiskEntry)
 
static ULONG GetLogicalPartitionCount (_In_ PDISKENTRY DiskEntry)
 
static BOOLEAN ReAllocateLayoutBuffer (_In_ PDISKENTRY DiskEntry)
 
VOID UpdateMbrDiskLayout (_In_ PDISKENTRY DiskEntry)
 
VOID UpdateGptDiskLayout (_In_ PDISKENTRY DiskEntry, _In_ BOOL DeleteEntry)
 
PPARTENTRY GetPrevUnpartitionedEntry (_In_ PPARTENTRY PartEntry)
 
PPARTENTRY GetNextUnpartitionedEntry (_In_ PPARTENTRY PartEntry)
 
NTSTATUS DismountVolume (_In_ PPARTENTRY PartEntry)
 
PVOLENTRY GetVolumeFromPartition (_In_ PPARTENTRY PartEntry)
 
VOID RemoveVolume (_In_ PVOLENTRY VolumeEntry)
 

Variables

LIST_ENTRY DiskListHead
 
LIST_ENTRY BiosDiskListHead
 
LIST_ENTRY VolumeListHead
 
PDISKENTRY CurrentDisk = NULL
 
PPARTENTRY CurrentPartition = NULL
 
PVOLENTRY CurrentVolume = NULL
 

Macro Definition Documentation

◆ InsertAscendingList

#define InsertAscendingList (   ListHead,
  NewEntry,
  Type,
  ListEntryField,
  SortField 
)
Value:
{\
\
current = (ListHead)->Flink;\
while (current != (ListHead))\
{\
if (CONTAINING_RECORD(current, Type, ListEntryField)->SortField >=\
(NewEntry)->SortField)\
{\
break;\
}\
current = current->Flink;\
}\
\
InsertTailList(current, &((NewEntry)->ListEntryField));\
}
Type
Definition: Type.h:7
struct task_struct * current
Definition: linux.c:32
Definition: typedefs.h:120
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Definition at line 16 of file partlist.c.

◆ MBR_MAGIC

#define MBR_MAGIC   0xAA55

Definition at line 39 of file partlist.c.

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file partlist.c.

◆ PARTITION_LINUX

#define PARTITION_LINUX   0x83

Definition at line 35 of file partlist.c.

◆ PARTITION_TBL_SIZE

#define PARTITION_TBL_SIZE   4

Definition at line 37 of file partlist.c.

◆ ROOT_NAME

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

Definition at line 357 of file partlist.c.

Typedef Documentation

◆ PARTITION

◆ PARTITION_SECTOR

◆ PPARTITION

◆ PPARTITION_SECTOR

Function Documentation

◆ AddDiskToList()

static VOID AddDiskToList ( HANDLE  FileHandle,
ULONG  DiskNumber 
)
static

Definition at line 1126 of file partlist.c.

1129{
1130 DISK_GEOMETRY DiskGeometry;
1131 SCSI_ADDRESS ScsiAddress;
1132 PDISKENTRY DiskEntry;
1136 PULONG Buffer;
1138 WCHAR Identifier[20];
1139 ULONG Checksum;
1141 ULONG i;
1142 PLIST_ENTRY ListEntry;
1143 PBIOSDISKENTRY BiosDiskEntry;
1144
1146 NULL,
1147 NULL,
1148 NULL,
1149 &Iosb,
1151 NULL,
1152 0,
1153 &DiskGeometry,
1154 sizeof(DISK_GEOMETRY));
1155 if (!NT_SUCCESS(Status))
1156 {
1157 return;
1158 }
1159
1160 if (DiskGeometry.MediaType != FixedMedia &&
1161 DiskGeometry.MediaType != RemovableMedia)
1162 {
1163 return;
1164 }
1165
1167 NULL,
1168 NULL,
1169 NULL,
1170 &Iosb,
1172 NULL,
1173 0,
1174 &ScsiAddress,
1175 sizeof(SCSI_ADDRESS));
1176 if (!NT_SUCCESS(Status))
1177 {
1178 return;
1179 }
1180
1181 PBYTE pBuffer = NULL;
1182
1183 pBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
1185 1024);
1186
1187 STORAGE_PROPERTY_QUERY StoragePropertyQuery;
1188 StoragePropertyQuery.PropertyId = StorageDeviceProperty;
1189 StoragePropertyQuery.QueryType = PropertyStandardQuery;
1191 NULL,
1192 NULL,
1193 NULL,
1194 &Iosb,
1196 &StoragePropertyQuery,
1197 sizeof(STORAGE_PROPERTY_QUERY),
1198 pBuffer,
1199 1024);
1200 if (!NT_SUCCESS(Status))
1201 {
1202 RtlFreeHeap(RtlGetProcessHeap(), 0, pBuffer);
1203 pBuffer = NULL;
1204 }
1205
1206
1207 Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(RtlGetProcessHeap(),
1208 0,
1209 DiskGeometry.BytesPerSector);
1210 if (Mbr == NULL)
1211 {
1212 return;
1213 }
1214
1215 FileOffset.QuadPart = 0;
1217 NULL,
1218 NULL,
1219 NULL,
1220 &Iosb,
1221 (PVOID)Mbr,
1222 DiskGeometry.BytesPerSector,
1223 &FileOffset,
1224 NULL);
1225 if (!NT_SUCCESS(Status))
1226 {
1227 RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr);
1228 DPRINT1("NtReadFile failed, status=%x\n", Status);
1229 return;
1230 }
1231 Signature = Mbr->Signature;
1232
1233 /* Calculate the MBR checksum */
1234 Checksum = 0;
1235 Buffer = (PULONG)Mbr;
1236 for (i = 0; i < 128; i++)
1237 {
1238 Checksum += Buffer[i];
1239 }
1240 Checksum = ~Checksum + 1;
1241
1243 L"%08x-%08x-A", Checksum, Signature);
1244 DPRINT("Identifier: %S\n", Identifier);
1245
1246 DiskEntry = RtlAllocateHeap(RtlGetProcessHeap(),
1248 sizeof(DISKENTRY));
1249 if (DiskEntry == NULL)
1250 {
1251 if (pBuffer)
1252 RtlFreeHeap(RtlGetProcessHeap(), 0, pBuffer);
1253 RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr);
1254 return;
1255 }
1256
1257 if (pBuffer)
1258 {
1259 PSTORAGE_DESCRIPTOR_HEADER pDescriptorHeader;
1260
1261 pDescriptorHeader = (PSTORAGE_DESCRIPTOR_HEADER)pBuffer;
1262 DPRINT("DescriptorHeader.Size %lu\n", pDescriptorHeader->Size);
1263
1264 if (pDescriptorHeader->Size <= 1024)
1265 {
1266 PSTORAGE_DEVICE_DESCRIPTOR pDeviceDescriptor;
1267 pDeviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)pBuffer;
1268 DPRINT("VendorIdOffset %lu\n", pDeviceDescriptor->VendorIdOffset);
1269 DPRINT("ProductIdOffset %lu\n", pDeviceDescriptor->ProductIdOffset);
1270 DPRINT("ProductRevisionOffset %lu\n", pDeviceDescriptor->ProductRevisionOffset);
1271 DPRINT("SerialNumberOffset %lu\n", pDeviceDescriptor->SerialNumberOffset);
1272 DPRINT("BusType: %u\n", pDeviceDescriptor->BusType);
1273 if (pDeviceDescriptor->VendorIdOffset)
1274 {
1275 DPRINT("Vendor: %s\n", (PSTR)((ULONG_PTR)pBuffer + pDeviceDescriptor->VendorIdOffset));
1276 }
1277
1278 if (pDeviceDescriptor->ProductIdOffset)
1279 {
1280 DPRINT("Product: %s\n", (PSTR)((ULONG_PTR)pBuffer + pDeviceDescriptor->ProductIdOffset));
1281 }
1282
1283 INT VendorLength = 0, ProductLength = 0;
1284 PWSTR VendorBuffer = NULL, ProductBuffer = NULL;
1285
1286 if (pDeviceDescriptor->VendorIdOffset)
1287 {
1288 VendorLength = MultiByteToWideChar(437,
1289 0,
1290 (PSTR)((ULONG_PTR)pBuffer + pDeviceDescriptor->VendorIdOffset),
1291 -1,
1292 NULL,
1293 0);
1294 VendorBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
1296 VendorLength * sizeof(WCHAR));
1297 if (VendorBuffer)
1299 0,
1300 (PSTR)((ULONG_PTR)pBuffer + pDeviceDescriptor->VendorIdOffset),
1301 -1,
1302 VendorBuffer,
1303 VendorLength);
1304 }
1305
1306 if (pDeviceDescriptor->ProductIdOffset)
1307 {
1308 ProductLength = MultiByteToWideChar(437,
1309 0,
1310 (PSTR)((ULONG_PTR)pBuffer + pDeviceDescriptor->ProductIdOffset),
1311 -1,
1312 NULL,
1313 0);
1314
1315 ProductBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
1317 ProductLength * sizeof(WCHAR));
1318 if (ProductBuffer)
1320 0,
1321 (PSTR)((ULONG_PTR)pBuffer + pDeviceDescriptor->ProductIdOffset),
1322 -1,
1323 ProductBuffer,
1324 ProductLength);
1325 }
1326
1327 DiskEntry->Description = RtlAllocateHeap(RtlGetProcessHeap(),
1329 (VendorLength + ProductLength + 2) * sizeof(WCHAR));
1330 if (VendorBuffer)
1331 wcscat(DiskEntry->Description, VendorBuffer);
1332
1333 if ((VendorLength > 0) && (ProductLength > 0))
1334 wcscat(DiskEntry->Description, L" ");
1335
1336 if (ProductBuffer)
1337 wcscat(DiskEntry->Description, ProductBuffer);
1338
1339 DiskEntry->BusType = pDeviceDescriptor->BusType;
1340
1341 if (VendorBuffer)
1342 RtlFreeHeap(RtlGetProcessHeap(), 0, VendorBuffer);
1343
1344 if (ProductBuffer)
1345 RtlFreeHeap(RtlGetProcessHeap(), 0, ProductBuffer);
1346 }
1347
1348 RtlFreeHeap(RtlGetProcessHeap(), 0, pBuffer);
1349 }
1350
1351// DiskEntry->Checksum = Checksum;
1352// DiskEntry->Signature = Signature;
1353 DiskEntry->BiosFound = FALSE;
1354
1355 /* Check the disk partition style */
1356 if (Mbr->Magic != MBR_MAGIC)
1357 {
1358 DPRINT("Partition style: RAW\n");
1359 DiskEntry->PartitionStyle = PARTITION_STYLE_RAW;
1360 }
1361 else
1362 {
1363 if (Mbr->Partition[0].PartitionType == PARTITION_GPT)
1364 {
1365 DPRINT("Partition style: GPT\n");
1367 }
1368 else
1369 {
1370 DPRINT("Partition style: MBR\n");
1372 }
1373 }
1374
1375 /* Free Mbr sector buffer */
1376 RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr);
1377
1378 ListEntry = BiosDiskListHead.Flink;
1379 while (ListEntry != &BiosDiskListHead)
1380 {
1381 BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
1382 /* FIXME:
1383 * Compare the size from bios and the reported size from driver.
1384 * If we have more than one disk with a zero or with the same signatur
1385 * we must create new signatures and reboot. After the reboot,
1386 * it is possible to identify the disks.
1387 */
1388 if (BiosDiskEntry->Signature == Signature &&
1389 BiosDiskEntry->Checksum == Checksum &&
1390 !BiosDiskEntry->Recognized)
1391 {
1392 if (!DiskEntry->BiosFound)
1393 {
1394 DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber;
1395 DiskEntry->BiosFound = TRUE;
1396 BiosDiskEntry->Recognized = TRUE;
1397 }
1398 else
1399 {
1400 }
1401 }
1402 ListEntry = ListEntry->Flink;
1403 }
1404
1405 if (!DiskEntry->BiosFound)
1406 {
1407#if 0
1408 RtlFreeHeap(ProcessHeap, 0, DiskEntry);
1409 return;
1410#else
1411 DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %d is not be bootable by the BIOS!\n", DiskNumber);
1412#endif
1413 }
1414
1417
1418 DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
1419 DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
1420 DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
1421 DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
1422
1423 DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders);
1424 DPRINT("TracksPerCylinder %I64u\n", DiskEntry->TracksPerCylinder);
1425 DPRINT("SectorsPerTrack %I64u\n", DiskEntry->SectorsPerTrack);
1426 DPRINT("BytesPerSector %I64u\n", DiskEntry->BytesPerSector);
1427
1428 DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart *
1429 (ULONGLONG)DiskGeometry.TracksPerCylinder *
1430 (ULONGLONG)DiskGeometry.SectorsPerTrack;
1431
1432// DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
1433// DiskEntry->CylinderAlignment = DiskGeometry.SectorsPerTrack * DiskGeometry.TracksPerCylinder;
1434 DiskEntry->SectorAlignment = (1024 * 1024) / DiskGeometry.BytesPerSector;
1435 DiskEntry->CylinderAlignment = (1024 * 1024) / DiskGeometry.BytesPerSector;
1436
1437 DPRINT("SectorCount: %I64u\n", DiskEntry->SectorCount);
1438 DPRINT("SectorAlignment: %lu\n", DiskEntry->SectorAlignment);
1439 DPRINT("CylinderAlignment: %lu\n", DiskEntry->CylinderAlignment);
1440
1441 DiskEntry->DiskNumber = DiskNumber;
1442 DiskEntry->Port = ScsiAddress.PortNumber;
1443 DiskEntry->PathId = ScsiAddress.PathId;
1444 DiskEntry->TargetId = ScsiAddress.TargetId;
1445 DiskEntry->Lun = ScsiAddress.Lun;
1446
1447 GetDriverName(DiskEntry);
1448
1449 InsertAscendingList(&DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber);
1450
1451 ReadLayoutBuffer(FileHandle, DiskEntry);
1452
1453 DPRINT("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount);
1454
1455#ifdef DUMP_PARTITION_TABLE
1456 DumpPartitionTable(DiskEntry);
1457#endif
1458
1459 if (DiskEntry->PartitionStyle == PARTITION_STYLE_MBR)
1460 {
1461 if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
1463 DiskEntry->LayoutBuffer->PartitionEntry[0].Mbr.PartitionType != 0)
1464 {
1465 if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
1466 {
1467 DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
1468 }
1469 else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
1470 {
1471 DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1472 }
1473 else
1474 {
1475 DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
1476 }
1477 }
1478 else
1479 {
1480 DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1481 }
1482
1483 /* Calculate the number of usable sectors */
1484 /* Limit the number of usable sectors to 2^32 */
1485 DiskEntry->StartSector.QuadPart = (ULONGLONG)DiskEntry->SectorAlignment;
1486 DiskEntry->EndSector.QuadPart = min(DiskEntry->SectorCount.QuadPart, 0x100000000) - 1;
1487
1488 if (DiskEntry->LayoutBuffer->PartitionCount == 0)
1489 {
1490 DiskEntry->NewDisk = TRUE;
1491 DiskEntry->LayoutBuffer->PartitionCount = 4;
1492
1493 for (i = 0; i < 4; i++)
1495 }
1496 else
1497 {
1498 for (i = 0; i < 4; i++)
1499 {
1500 AddMbrPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
1501 }
1502
1503 for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
1504 {
1505 AddMbrPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
1506 }
1507 }
1508
1510 }
1511 else if (DiskEntry->PartitionStyle == PARTITION_STYLE_GPT)
1512 {
1513 /* Calculate the number of usable sectors */
1514 DiskEntry->StartSector.QuadPart = AlignDown(DiskEntry->LayoutBuffer->Gpt.StartingUsableOffset.QuadPart / DiskEntry->BytesPerSector,
1515 DiskEntry->SectorAlignment) + (ULONGLONG)DiskEntry->SectorAlignment;
1516 DiskEntry->EndSector.QuadPart = AlignDown(DiskEntry->StartSector.QuadPart + (DiskEntry->LayoutBuffer->Gpt.UsableLength.QuadPart / DiskEntry->BytesPerSector) - 1,
1517 DiskEntry->SectorAlignment);
1518
1519 if (DiskEntry->LayoutBuffer->PartitionCount == 0)
1520 {
1521 DiskEntry->NewDisk = TRUE;
1522 }
1523 else
1524 {
1525 for (i = 0; i < DiskEntry->LayoutBuffer->PartitionCount; i++)
1526 {
1527 AddGptPartitionToDisk(DiskNumber, DiskEntry, i);
1528 }
1529 }
1530
1532 }
1533}
@ 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_GPT
Definition: disk.h:90
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
_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 MultiByteToWideChar
Definition: compat.h:110
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static const WCHAR Signature[]
Definition: parser.c:141
#define L(x)
Definition: resources.c:13
return Iosb
Definition: create.c:4403
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
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
@ PARTITION_STYLE_GPT
Definition: imports.h:202
@ PARTITION_STYLE_MBR
Definition: imports.h:201
#define min(a, b)
Definition: monoChain.cc:55
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)
@ RemovableMedia
Definition: ntdddisk.h:382
@ FixedMedia
Definition: ntdddisk.h:383
BYTE * PBYTE
Definition: pedump.c:66
#define IOCTL_STORAGE_QUERY_PROPERTY
Definition: ntddstor.h:178
@ StorageDeviceProperty
Definition: ntddstor.h:512
@ PropertyStandardQuery
Definition: ntddstor.h:505
PVOID pBuffer
#define IOCTL_SCSI_GET_ADDRESS
Definition: scsi_port.h:52
wcscat
static VOID GetDriverName(IN PDISKENTRY DiskEntry)
Definition: partlist.c:105
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
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
BOOLEAN Recognized
Definition: diskpart.h:178
ULONG DiskNumber
Definition: partlist.h:162
ULONG Checksum
Definition: partlist.h:164
ULONG Signature
Definition: partlist.h:163
ULARGE_INTEGER EndSector
Definition: diskpart.h:202
ULONG SectorAlignment
Definition: partlist.h:116
ULONG BiosDiskNumber
Definition: diskpart.h:205
ULARGE_INTEGER SectorCount
Definition: partlist.h:115
STORAGE_BUS_TYPE BusType
Definition: diskpart.h:190
ULONG SectorsPerTrack
Definition: partlist.h:112
USHORT TargetId
Definition: diskpart.h:212
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:150
BOOLEAN NewDisk
Definition: partlist.h:138
ULONG DiskNumber
Definition: partlist.h:129
ULONG BytesPerSector
Definition: partlist.h:113
USHORT PathId
Definition: diskpart.h:211
BOOLEAN BiosFound
Definition: partlist.h:120
ULONGLONG Cylinders
Definition: partlist.h:110
USHORT Lun
Definition: diskpart.h:213
ULARGE_INTEGER StartSector
Definition: diskpart.h:201
USHORT Port
Definition: partlist.h:131
DWORD PartitionStyle
Definition: diskpart.h:219
ULONG TracksPerCylinder
Definition: partlist.h:111
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:149
PWSTR Description
Definition: diskpart.h:188
ULONG CylinderAlignment
Definition: partlist.h:117
PDRIVE_LAYOUT_INFORMATION LayoutBuffer
Definition: partlist.h:143
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
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:219
unsigned char PartitionType
Definition: partlist.h:206
UCHAR PathId
Definition: scsi_port.h:149
UCHAR TargetId
Definition: scsi_port.h:150
UCHAR PortNumber
Definition: scsi_port.h:148
STORAGE_BUS_TYPE BusType
Definition: ntddstor.h:298
STORAGE_QUERY_TYPE QueryType
Definition: ntddstor.h:553
STORAGE_PROPERTY_ID PropertyId
Definition: ntddstor.h:552
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
ULONGLONG AlignDown(_In_ ULONGLONG Value, _In_ ULONG Alignment)
Definition: partlist.c:189
static VOID AddGptPartitionToDisk(ULONG DiskNumber, PDISKENTRY DiskEntry, ULONG PartitionIndex)
Definition: partlist.c:616
LIST_ENTRY BiosDiskListHead
Definition: partlist.c:72
static VOID AddMbrPartitionToDisk(ULONG DiskNumber, PDISKENTRY DiskEntry, ULONG PartitionIndex, BOOLEAN LogicalPartition)
Definition: partlist.c:506
VOID ReadLayoutBuffer(_In_ HANDLE FileHandle, _In_ PDISKENTRY DiskEntry)
Definition: partlist.c:1065
LIST_ENTRY DiskListHead
Definition: partlist.c:71
VOID ScanForUnpartitionedMbrDiskSpace(PDISKENTRY DiskEntry)
Definition: partlist.c:660
VOID ScanForUnpartitionedGptDiskSpace(PDISKENTRY DiskEntry)
Definition: partlist.c:921
#define MBR_MAGIC
Definition: partlist.c:39
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
char * PSTR
Definition: typedefs.h:51
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
LONGLONG QuadPart
Definition: typedefs.h:114
struct _STORAGE_DESCRIPTOR_HEADER * PSTORAGE_DESCRIPTOR_HEADER
struct _STORAGE_DEVICE_DESCRIPTOR * PSTORAGE_DEVICE_DESCRIPTOR
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ AddGptPartitionToDisk()

static VOID AddGptPartitionToDisk ( ULONG  DiskNumber,
PDISKENTRY  DiskEntry,
ULONG  PartitionIndex 
)
static

Definition at line 616 of file partlist.c.

620{
622 PPARTENTRY PartEntry;
623
624 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
625 if (IsEqualGUID(&PartitionInfo->Gpt.PartitionType, &PARTITION_ENTRY_UNUSED_GUID))
626 return;
627
628 PartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
630 sizeof(PARTENTRY));
631 if (PartEntry == NULL)
632 {
633 /* TODO: Error message */
634 return;
635 }
636
637 PartEntry->DiskEntry = DiskEntry;
638
639 PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
640 PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
641
642 CopyMemory(&PartEntry->Gpt.PartitionType, &PartitionInfo->Gpt.PartitionType, sizeof(GUID));
643 CopyMemory(&PartEntry->Gpt.PartitionId, &PartitionInfo->Gpt.PartitionId, sizeof(GUID));
644 PartEntry->Gpt.Attributes = PartitionInfo->Gpt.Attributes;
645
646 PartEntry->LogicalPartition = FALSE;
647 PartEntry->IsPartitioned = TRUE;
648 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
649 PartEntry->PartitionIndex = PartitionIndex;
650
651 /* TODO: Determine the format state */
652 PartEntry->FormatState = Unformatted;
653
655 &PartEntry->ListEntry);
656}
#define InsertTailList(ListHead, Entry)
@ Unformatted
Definition: partlist.h:34
#define CopyMemory
Definition: minwinbase.h:29
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
DWORD64 Attributes
Definition: diskpart.h:127
BOOLEAN IsPartitioned
Definition: partlist.h:82
ULARGE_INTEGER SectorCount
Definition: partlist.h:70
struct _DISKENTRY * DiskEntry
Definition: partlist.h:66
BOOLEAN LogicalPartition
Definition: partlist.h:79
FORMATSTATE FormatState
Definition: diskpart.h:152
GPT_PARTITION_DATA Gpt
Definition: diskpart.h:142
LIST_ENTRY ListEntry
Definition: partlist.h:63
ULONG PartitionNumber
Definition: partlist.h:75
ULARGE_INTEGER StartSector
Definition: partlist.h:69
ULONG PartitionIndex
Definition: partlist.h:76
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2105

Referenced by AddDiskToList().

◆ AddMbrPartitionToDisk()

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

Definition at line 506 of file partlist.c.

511{
513 PPARTENTRY PartEntry;
514
515 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
516 if (PartitionInfo->Mbr.PartitionType == 0 ||
517 (LogicalPartition == TRUE && IsContainerPartition(PartitionInfo->Mbr.PartitionType)))
518 return;
519
520 PartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
522 sizeof(PARTENTRY));
523 if (PartEntry == NULL)
524 {
525 /* TODO: Error message */
526 return;
527 }
528
529 PartEntry->DiskEntry = DiskEntry;
530
531 PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
532 PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
533
534 PartEntry->Mbr.BootIndicator = PartitionInfo->Mbr.BootIndicator;
535 PartEntry->Mbr.PartitionType = PartitionInfo->Mbr.PartitionType;
536
538 PartEntry->IsPartitioned = TRUE;
539 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
540 PartEntry->PartitionIndex = PartitionIndex;
541
542 if (IsContainerPartition(PartEntry->Mbr.PartitionType))
543 {
544 PartEntry->FormatState = Unformatted;
545
546 if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
547 DiskEntry->ExtendedPartition = PartEntry;
548 }
549 else if ((PartEntry->Mbr.PartitionType == PARTITION_FAT_12) ||
550 (PartEntry->Mbr.PartitionType == PARTITION_FAT_16) ||
551 (PartEntry->Mbr.PartitionType == PARTITION_HUGE) ||
552 (PartEntry->Mbr.PartitionType == PARTITION_XINT13) ||
553 (PartEntry->Mbr.PartitionType == PARTITION_FAT32) ||
555 {
556#if 0
557 if (CheckFatFormat())
558 {
559 PartEntry->FormatState = Preformatted;
560 }
561 else
562 {
563 PartEntry->FormatState = Unformatted;
564 }
565#endif
566 PartEntry->FormatState = Preformatted;
567 }
568 else if (PartEntry->Mbr.PartitionType == PARTITION_LINUX)
569 {
570#if 0
571 if (CheckExt2Format())
572 {
573 PartEntry->FormatState = Preformatted;
574 }
575 else
576 {
577 PartEntry->FormatState = Unformatted;
578 }
579#endif
580 PartEntry->FormatState = Preformatted;
581 }
582 else if (PartEntry->Mbr.PartitionType == PARTITION_IFS)
583 {
584#if 0
585 if (CheckNtfsFormat())
586 {
587 PartEntry->FormatState = Preformatted;
588 }
589 else if (CheckHpfsFormat())
590 {
591 PartEntry->FormatState = Preformatted;
592 }
593 else
594 {
595 PartEntry->FormatState = Unformatted;
596 }
597#endif
598 PartEntry->FormatState = Preformatted;
599 }
600 else
601 {
602 PartEntry->FormatState = UnknownFormat;
603 }
604
607 &PartEntry->ListEntry);
608 else
610 &PartEntry->ListEntry);
611}
#define PARTITION_IFS
Definition: disk.h:78
#define PARTITION_XINT13
Definition: disk.h:82
#define PARTITION_FAT32
Definition: disk.h:80
#define PARTITION_FAT_12
Definition: disk.h:72
#define PARTITION_HUGE
Definition: disk.h:77
#define PARTITION_FAT_16
Definition: disk.h:75
#define PARTITION_FAT32_XINT13
Definition: disk.h:81
@ Preformatted
Definition: diskpart.h:105
@ LogicalPartition
Definition: disksup.c:48
@ UnknownFormat
Definition: partlist.h:36
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:321
PPARTENTRY ExtendedPartition
Definition: partlist.h:153
BOOLEAN BootIndicator
Definition: diskpart.h:119
MBR_PARTITION_DATA Mbr
Definition: diskpart.h:141
#define PARTITION_LINUX
Definition: partlist.c:35

Referenced by AddDiskToList().

◆ AddVolumeToList()

static VOID AddVolumeToList ( ULONG  ulVolumeNumber,
PWSTR  pszVolumeName 
)
static

Definition at line 1834 of file partlist.c.

1837{
1838 PVOLENTRY VolumeEntry;
1840
1841 DWORD dwError, dwLength;
1842 WCHAR szPathNames[MAX_PATH + 1];
1843 WCHAR szVolumeName[MAX_PATH + 1];
1844 WCHAR szFilesystem[MAX_PATH + 1];
1845
1846 DWORD CharCount = 0;
1847 size_t Index = 0;
1848
1853
1854 DPRINT("AddVolumeToList(%S)\n", pszVolumeName);
1855
1856 VolumeEntry = RtlAllocateHeap(RtlGetProcessHeap(),
1858 sizeof(VOLENTRY));
1859 if (VolumeEntry == NULL)
1860 return;
1861
1862 VolumeEntry->VolumeNumber = ulVolumeNumber;
1863 wcscpy(VolumeEntry->VolumeName, pszVolumeName);
1864
1865 Index = wcslen(pszVolumeName) - 1;
1866
1867 pszVolumeName[Index] = L'\0';
1868
1869 CharCount = QueryDosDeviceW(&pszVolumeName[4], VolumeEntry->DeviceName, ARRAYSIZE(VolumeEntry->DeviceName));
1870
1871 pszVolumeName[Index] = L'\\';
1872
1873 if (CharCount == 0)
1874 {
1875 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry);
1876 return;
1877 }
1878
1879 wcscat(VolumeEntry->DeviceName, L"\\");
1880 DPRINT("DeviceName: %S\n", VolumeEntry->DeviceName);
1881
1882 RtlInitUnicodeString(&Name, VolumeEntry->DeviceName);
1883
1885 &Name,
1886 0,
1887 NULL,
1888 NULL);
1889
1893 &Iosb,
1894 0,
1896 if (NT_SUCCESS(Status))
1897 {
1898 GetVolumeType(VolumeHandle, VolumeEntry);
1899 GetVolumeExtents(VolumeHandle, VolumeEntry);
1900 GetVolumeSize(VolumeHandle, VolumeEntry);
1902 }
1903
1904 if (GetVolumeInformationW(pszVolumeName,
1905 szVolumeName,
1906 MAX_PATH + 1,
1907 &VolumeEntry->SerialNumber,
1908 NULL, // [out, optional] LPDWORD lpMaximumComponentLength,
1909 NULL, // [out, optional] LPDWORD lpFileSystemFlags,
1910 szFilesystem,
1911 MAX_PATH + 1))
1912 {
1913 VolumeEntry->pszLabel = RtlAllocateHeap(RtlGetProcessHeap(),
1914 0,
1915 (wcslen(szVolumeName) + 1) * sizeof(WCHAR));
1916 if (VolumeEntry->pszLabel)
1917 wcscpy(VolumeEntry->pszLabel, szVolumeName);
1918
1919 VolumeEntry->pszFilesystem = RtlAllocateHeap(RtlGetProcessHeap(),
1920 0,
1921 (wcslen(szFilesystem) + 1) * sizeof(WCHAR));
1922 if (VolumeEntry->pszFilesystem)
1923 wcscpy(VolumeEntry->pszFilesystem, szFilesystem);
1924 }
1925 else
1926 {
1927 dwError = GetLastError();
1928 if (dwError == ERROR_UNRECOGNIZED_VOLUME)
1929 {
1930 VolumeEntry->pszFilesystem = RtlAllocateHeap(RtlGetProcessHeap(),
1931 0,
1932 (3 + 1) * sizeof(WCHAR));
1933 if (VolumeEntry->pszFilesystem)
1934 wcscpy(VolumeEntry->pszFilesystem, L"RAW");
1935 VolumeEntry->SerialNumber = 0;
1936 VolumeEntry->SectorsPerAllocationUnit = 1;
1937 VolumeEntry->BytesPerSector = 512;
1938 VolumeEntry->VolumeType = VOLUME_TYPE_PARTITION;
1939 }
1940 }
1941
1942 if (GetVolumePathNamesForVolumeNameW(pszVolumeName,
1943 szPathNames,
1944 ARRAYSIZE(szPathNames),
1945 &dwLength))
1946 {
1947 INT nPathLength;
1948 PWSTR pszPath = szPathNames;
1949 while (*pszPath != UNICODE_NULL)
1950 {
1951 DPRINT("PathName: %S\n", pszPath);
1952 nPathLength = wcslen(pszPath);
1953 if ((nPathLength == 3) && (iswalpha(pszPath[0])) &&
1954 (pszPath[1] == L':') && (pszPath[2] == L'\\'))
1955 VolumeEntry->DriveLetter = pszPath[0];
1956
1957 pszPath += (nPathLength + 1);
1958 }
1959 }
1960
1962 &VolumeEntry->ListEntry);
1963}
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
LPWSTR Name
Definition: desk.c:124
@ VOLUME_TYPE_PARTITION
Definition: diskpart.h:112
#define MAX_PATH
Definition: compat.h:34
static DWORD DWORD * dwLength
Definition: fusion.c:86
DWORD WINAPI QueryDosDeviceW(LPCWSTR lpDeviceName, LPWSTR lpTargetPath, DWORD ucchMax)
Definition: dosdev.c:542
BOOL WINAPI GetVolumeInformationW(IN LPCWSTR lpRootPathName, IN LPWSTR lpVolumeNameBuffer, IN DWORD nVolumeNameSize, OUT LPDWORD lpVolumeSerialNumber OPTIONAL, OUT LPDWORD lpMaximumComponentLength OPTIONAL, OUT LPDWORD lpFileSystemFlags OPTIONAL, OUT LPWSTR lpFileSystemNameBuffer OPTIONAL, IN DWORD nFileSystemNameSize)
Definition: volume.c:226
BOOL WINAPI GetVolumePathNamesForVolumeNameW(IN LPCWSTR lpszVolumeName, IN LPWSTR lpszVolumePathNames, IN DWORD cchBufferLength, OUT PDWORD lpcchReturnLength)
Definition: volume.c:1227
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _Out_ PHANDLE VolumeHandle
Definition: fltkernel.h:2283
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
#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:3953
#define SYNCHRONIZE
Definition: nt_native.h:61
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define UNICODE_NULL
#define iswalpha(_c)
Definition: ctype.h:664
wcscpy
VOLUME_TYPE VolumeType
Definition: diskpart.h:245
ULONG VolumeNumber
Definition: diskpart.h:236
ULONG SectorsPerAllocationUnit
Definition: diskpart.h:250
PWSTR pszFilesystem
Definition: diskpart.h:244
ULONG BytesPerSector
Definition: diskpart.h:251
DWORD SerialNumber
Definition: diskpart.h:239
WCHAR VolumeName[MAX_PATH]
Definition: diskpart.h:237
LIST_ENTRY ListEntry
Entry in VolumesList.
Definition: partlist.h:45
PWSTR pszLabel
Definition: diskpart.h:243
WCHAR DeviceName[MAX_PATH]
Definition: diskpart.h:238
WCHAR DriveLetter
Definition: diskpart.h:241
LIST_ENTRY VolumeListHead
Definition: partlist.c:73
static VOID GetVolumeType(_In_ HANDLE VolumeHandle, _In_ PVOLENTRY VolumeEntry)
Definition: partlist.c:1741
static VOID GetVolumeSize(_In_ HANDLE VolumeHandle, _In_ PVOLENTRY VolumeEntry)
Definition: partlist.c:1781
static VOID GetVolumeExtents(_In_ HANDLE VolumeHandle, _In_ PVOLENTRY VolumeEntry)
Definition: partlist.c:1675
_In_ WDFCOLLECTION _In_ ULONG Index
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define ERROR_UNRECOGNIZED_VOLUME
Definition: winerror.h:908

Referenced by CreateVolumeList().

◆ AlignDown()

ULONGLONG AlignDown ( _In_ ULONGLONG  Value,
_In_ ULONG  Alignment 
)

Definition at line 189 of file partlist.c.

192{
193 ULONGLONG Temp;
194
195 Temp = Value / Alignment;
196
197 return Temp * Alignment;
198}
union Alignment_ Alignment
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

◆ CreatePartitionList()

NTSTATUS CreatePartitionList ( VOID  )

Definition at line 1537 of file partlist.c.

1538{
1542 ULONG ReturnSize;
1544 ULONG DiskNumber;
1548
1549 CurrentDisk = NULL;
1551
1552// BootDisk = NULL;
1553// BootPartition = NULL;
1554
1555// TempDisk = NULL;
1556// TempPartition = NULL;
1557// FormatState = Start;
1558
1561
1563
1565 &Sdi,
1567 &ReturnSize);
1568 if (!NT_SUCCESS(Status))
1569 {
1570 return Status;
1571 }
1572
1573 for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
1574 {
1576 L"\\Device\\Harddisk%d\\Partition0",
1577 DiskNumber);
1578
1580 Buffer);
1581
1583 &Name,
1584 0,
1585 NULL,
1586 NULL);
1587
1591 &Iosb,
1594 if (NT_SUCCESS(Status))
1595 {
1596 AddDiskToList(FileHandle, DiskNumber);
1597
1599 }
1600 }
1601
1602// UpdateDiskSignatures(List);
1603
1604// AssignDriveLetters(List);
1605
1606 return STATUS_SUCCESS;
1607}
PDISKENTRY CurrentDisk
Definition: partlist.c:75
#define FILE_SHARE_READ
Definition: compat.h:136
@ SystemDeviceInformation
Definition: ntddk_ex.h:18
#define FILE_READ_DATA
Definition: nt_native.h:628
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
static VOID AddDiskToList(IN HANDLE FileHandle, IN ULONG DiskNumber, IN PPARTLIST List)
Definition: partlist.c:1445
static VOID EnumerateBiosDiskEntries(IN PPARTLIST PartList)
Definition: partlist.c:327
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
PPARTENTRY CurrentPartition
Definition: partlist.c:76

◆ CreateVolumeList()

NTSTATUS CreateVolumeList ( VOID  )

Definition at line 1967 of file partlist.c.

1968{
1969 HANDLE hVolume = INVALID_HANDLE_VALUE;
1970 WCHAR szVolumeName[MAX_PATH];
1971 ULONG ulVolumeNumber = 0;
1972 BOOL Success;
1973
1975
1977
1978 hVolume = FindFirstVolumeW(szVolumeName, ARRAYSIZE(szVolumeName));
1979 if (hVolume == INVALID_HANDLE_VALUE)
1980 {
1981
1982 return STATUS_UNSUCCESSFUL;
1983 }
1984
1985 AddVolumeToList(ulVolumeNumber++, szVolumeName);
1986
1987 for (;;)
1988 {
1989 Success = FindNextVolumeW(hVolume, szVolumeName, ARRAYSIZE(szVolumeName));
1990 if (!Success)
1991 {
1992 break;
1993 }
1994
1995 AddVolumeToList(ulVolumeNumber++, szVolumeName);
1996 }
1997
1998 FindVolumeClose(hVolume);
1999
2000 return STATUS_SUCCESS;
2001}
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
BOOL WINAPI FindNextVolumeW(IN HANDLE handle, IN LPWSTR volume, IN DWORD len)
Definition: volume.c:1082
HANDLE WINAPI FindFirstVolumeW(IN LPWSTR volume, IN DWORD len)
Definition: volume.c:660
BOOL WINAPI FindVolumeClose(IN HANDLE hFindVolume)
Definition: volume.c:741
@ Success
Definition: eventcreate.c:712
unsigned int BOOL
Definition: ntddk_ex.h:94
static VOID AddVolumeToList(ULONG ulVolumeNumber, PWSTR pszVolumeName)
Definition: partlist.c:1834
PVOLENTRY CurrentVolume
Definition: partlist.c:77
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

Referenced by rescan_main(), and wmain().

◆ DestroyPartitionList()

VOID DestroyPartitionList ( VOID  )

Definition at line 1611 of file partlist.c.

1612{
1613 PDISKENTRY DiskEntry;
1614 PBIOSDISKENTRY BiosDiskEntry;
1615 PPARTENTRY PartEntry;
1617
1618 CurrentDisk = NULL;
1620
1621 /* Release disk and partition info */
1622 while (!IsListEmpty(&DiskListHead))
1623 {
1625 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
1626
1627 /* Release driver name */
1628 RtlFreeUnicodeString(&DiskEntry->DriverName);
1629
1630 /* Release primary partition list */
1631 while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
1632 {
1634 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1635
1636 RtlFreeHeap(RtlGetProcessHeap(), 0, PartEntry);
1637 }
1638
1639 /* Release logical partition list */
1640 while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
1641 {
1643 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1644
1645 RtlFreeHeap(RtlGetProcessHeap(), 0, PartEntry);
1646 }
1647
1648 /* Release layout buffer */
1649 if (DiskEntry->LayoutBuffer != NULL)
1650 RtlFreeHeap(RtlGetProcessHeap(), 0, DiskEntry->LayoutBuffer);
1651
1652 if (DiskEntry->Description != NULL)
1653 RtlFreeHeap(RtlGetProcessHeap(), 0, DiskEntry->Description);
1654
1655 if (DiskEntry->Location != NULL)
1656 RtlFreeHeap(RtlGetProcessHeap(), 0, DiskEntry->Location);
1657
1658 /* Release disk entry */
1659 RtlFreeHeap(RtlGetProcessHeap(), 0, DiskEntry);
1660 }
1661
1662 /* Release the bios disk info */
1663 while (!IsListEmpty(&BiosDiskListHead))
1664 {
1666 BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
1667
1668 RtlFreeHeap(RtlGetProcessHeap(), 0, BiosDiskEntry);
1669 }
1670}
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
base of all file and directory entries
Definition: entries.h:83
UNICODE_STRING DriverName
Definition: partlist.h:141
PWSTR Location
Definition: diskpart.h:189

◆ DestroyVolumeList()

VOID DestroyVolumeList ( VOID  )

Definition at line 2005 of file partlist.c.

2006{
2008 PVOLENTRY VolumeEntry;
2009
2011
2012 /* Release disk and partition info */
2013 while (!IsListEmpty(&VolumeListHead))
2014 {
2016 VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
2017
2018 if (VolumeEntry->pszLabel)
2019 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszLabel);
2020
2021 if (VolumeEntry->pszFilesystem)
2022 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszFilesystem);
2023
2024 if (VolumeEntry->pExtents)
2025 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pExtents);
2026
2027 /* Release disk entry */
2028 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry);
2029 }
2030}
PVOLUME_DISK_EXTENTS pExtents
Definition: diskpart.h:253

Referenced by rescan_main(), and wmain().

◆ DiskConfigurationDataQueryRoutine()

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

Definition at line 267 of file partlist.c.

274{
275 PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
276 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
278 ULONG i;
279
282 return STATUS_UNSUCCESSFUL;
283
284 FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
285
286 /* Hm. Version and Revision are not set on Microsoft Windows XP... */
287#if 0
288 if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
289 FullResourceDescriptor->PartialResourceList.Revision != 1)
290 return STATUS_UNSUCCESSFUL;
291#endif
292
293 for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
294 {
297 continue;
298
299 DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1];
300 BiosDiskEntry->DiskGeometry = *DiskGeometry;
301
302 return STATUS_SUCCESS;
303 }
304
305 return STATUS_UNSUCCESSFUL;
306}
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
struct _BIOSDISKENTRY * PBIOSDISKENTRY
#define REG_FULL_RESOURCE_DESCRIPTOR
Definition: nt_native.h:1506
struct _CM_FULL_RESOURCE_DESCRIPTOR * PCM_FULL_RESOURCE_DESCRIPTOR
#define CmResourceTypeDeviceSpecific
Definition: restypes.h:108
CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry
Definition: partlist.h:166
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: restypes.h:144
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@432 u
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@432::@441 DeviceSpecificData
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: restypes.h:100
_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

◆ DiskIdentifierQueryRoutine()

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

Definition at line 237 of file partlist.c.

244{
245 PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
246 UNICODE_STRING NameU;
247
248 if (ValueType == REG_SZ &&
249 ValueLength == 20 * sizeof(WCHAR))
250 {
251 NameU.Buffer = (PWCHAR)ValueData;
252 NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR);
253 RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum);
254
255 NameU.Buffer = (PWCHAR)ValueData + 9;
256 RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature);
257
258 return STATUS_SUCCESS;
259 }
260
261 return STATUS_UNSUCCESSFUL;
262}
#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

◆ DismountVolume()

NTSTATUS DismountVolume ( _In_ PPARTENTRY  PartEntry)

Definition at line 2687 of file partlist.c.

2689{
2691 NTSTATUS LockStatus;
2695 HANDLE PartitionHandle;
2697
2698 /* Check whether the partition is valid and was mounted by the system */
2699 if (!PartEntry->IsPartitioned ||
2700 IsContainerPartition(PartEntry->Mbr.PartitionType) ||
2701 !IsRecognizedPartition(PartEntry->Mbr.PartitionType) ||
2702 PartEntry->FormatState == UnknownFormat ||
2703 // NOTE: If FormatState == Unformatted but *FileSystem != 0 this means
2704 // it has been usually mounted with RawFS and thus needs to be dismounted.
2705/* !*PartEntry->FileSystem || */
2706 PartEntry->PartitionNumber == 0)
2707 {
2708 /* The partition is not mounted, so just return success */
2709 return STATUS_SUCCESS;
2710 }
2711
2712 ASSERT(PartEntry->Mbr.PartitionType != PARTITION_ENTRY_UNUSED);
2713
2714 /* Open the volume */
2716 L"\\Device\\Harddisk%lu\\Partition%lu",
2717 PartEntry->DiskEntry->DiskNumber,
2718 PartEntry->PartitionNumber);
2720
2722 &Name,
2724 NULL,
2725 NULL);
2726
2727 Status = NtOpenFile(&PartitionHandle,
2733 if (!NT_SUCCESS(Status))
2734 {
2735 DPRINT1("ERROR: Cannot open volume %wZ for dismounting! (Status 0x%lx)\n", &Name, Status);
2736 return Status;
2737 }
2738
2739 /* Lock the volume */
2740 LockStatus = NtFsControlFile(PartitionHandle,
2741 NULL,
2742 NULL,
2743 NULL,
2746 NULL,
2747 0,
2748 NULL,
2749 0);
2750 if (!NT_SUCCESS(LockStatus))
2751 {
2752 DPRINT1("WARNING: Failed to lock volume! Operations may fail! (Status 0x%lx)\n", LockStatus);
2753 }
2754
2755 /* Dismount the volume */
2756 Status = NtFsControlFile(PartitionHandle,
2757 NULL,
2758 NULL,
2759 NULL,
2762 NULL,
2763 0,
2764 NULL,
2765 0);
2766 if (!NT_SUCCESS(Status))
2767 {
2768 DPRINT1("Failed to unmount volume (Status 0x%lx)\n", Status);
2769 }
2770
2771 /* Unlock the volume */
2772 LockStatus = NtFsControlFile(PartitionHandle,
2773 NULL,
2774 NULL,
2775 NULL,
2778 NULL,
2779 0,
2780 NULL,
2781 0);
2782 if (!NT_SUCCESS(LockStatus))
2783 {
2784 DPRINT1("Failed to unlock volume (Status 0x%lx)\n", LockStatus);
2785 }
2786
2787 /* Close the volume */
2788 NtClose(PartitionHandle);
2789
2790 return Status;
2791}
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:71
#define GENERIC_READ
Definition: compat.h:135
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define ASSERT(a)
Definition: mode.c:44
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#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)
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:342
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75

◆ EnumerateBiosDiskEntries()

static VOID EnumerateBiosDiskEntries ( VOID  )
static

Definition at line 361 of file partlist.c.

362{
364 WCHAR Name[120];
365 ULONG AdapterCount;
366 ULONG DiskCount;
368 PCM_INT13_DRIVE_PARAMETER Int13Drives;
369 PBIOSDISKENTRY BiosDiskEntry;
370
371 memset(QueryTable, 0, sizeof(QueryTable));
372
373 QueryTable[1].Name = L"Configuration Data";
375 Int13Drives = NULL;
377 L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
378 &QueryTable[1],
379 (PVOID)&Int13Drives,
380 NULL);
381 if (!NT_SUCCESS(Status))
382 {
383 DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status);
384 return;
385 }
386
387 AdapterCount = 0;
388 while (1)
389 {
391 L"%s\\%lu", ROOT_NAME, AdapterCount);
393 Name,
394 &QueryTable[2],
395 NULL,
396 NULL);
397 if (!NT_SUCCESS(Status))
398 {
399 break;
400 }
401
403 L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount);
405 Name,
406 &QueryTable[2],
407 NULL,
408 NULL);
409 if (NT_SUCCESS(Status))
410 {
411 while (1)
412 {
414 L"%s\\%lu\\DiskController\\0", ROOT_NAME, AdapterCount);
416 Name,
417 &QueryTable[2],
418 NULL,
419 NULL);
420 if (!NT_SUCCESS(Status))
421 {
422 RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
423 return;
424 }
425
427 L"%s\\%lu\\DiskController\\0\\DiskPeripheral", ROOT_NAME, AdapterCount);
429 Name,
430 &QueryTable[2],
431 NULL,
432 NULL);
433 if (NT_SUCCESS(Status))
434 {
435 QueryTable[0].Name = L"Identifier";
437 QueryTable[1].Name = L"Configuration Data";
439
440 DiskCount = 0;
441 while (1)
442 {
443 BiosDiskEntry = (BIOSDISKENTRY*)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY));
444 if (BiosDiskEntry == NULL)
445 {
446 break;
447 }
448
450 L"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, DiskCount);
452 Name,
454 (PVOID)BiosDiskEntry,
455 NULL);
456 if (!NT_SUCCESS(Status))
457 {
458 RtlFreeHeap(RtlGetProcessHeap(), 0, BiosDiskEntry);
459 break;
460 }
461
462 BiosDiskEntry->DiskNumber = DiskCount;
463 BiosDiskEntry->Recognized = FALSE;
464
465 if (DiskCount < Int13Drives[0].NumberDrives)
466 {
467 BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount];
468 }
469 else
470 {
471 DPRINT1("Didn't find int13 drive datas for disk %u\n", DiskCount);
472 }
473
474 InsertTailList(&BiosDiskListHead, &BiosDiskEntry->ListEntry);
475
476 DPRINT("DiskNumber: %lu\n", BiosDiskEntry->DiskNumber);
477 DPRINT("Signature: %08lx\n", BiosDiskEntry->Signature);
478 DPRINT("Checksum: %08lx\n", BiosDiskEntry->Checksum);
479 DPRINT("BytesPerSector: %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector);
480 DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders);
481 DPRINT("NumberOfHeads: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads);
482 DPRINT("DriveSelect: %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect);
483 DPRINT("MaxCylinders: %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders);
484 DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack);
485 DPRINT("MaxHeads: %d\n", BiosDiskEntry->Int13DiskData.MaxHeads);
486 DPRINT("NumberDrives: %d\n", BiosDiskEntry->Int13DiskData.NumberDrives);
487
488 DiskCount++;
489 }
490 }
491
492 RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
493 return;
494 }
495 }
496
497 AdapterCount++;
498 }
499
500 RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
501}
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
struct _BIOSDISKENTRY BIOSDISKENTRY
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4211
#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:237
#define ROOT_NAME
static NTSTATUS NTAPI SystemConfigurationDataQueryRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: partlist.c:280
static NTSTATUS NTAPI DiskIdentifierQueryRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: partlist.c:207
LIST_ENTRY ListEntry
Definition: partlist.h:159
CM_INT13_DRIVE_PARAMETER Int13DiskData
Definition: partlist.h:167
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109

◆ GetDriverName()

static VOID GetDriverName ( PDISKENTRY  DiskEntry)
static

Definition at line 202 of file partlist.c.

204{
206 WCHAR KeyName[32];
208
210 NULL);
211
213 L"\\Scsi\\Scsi Port %lu",
214 DiskEntry->Port);
215
217 sizeof(QueryTable));
218
219 QueryTable[0].Name = L"Driver";
221 QueryTable[0].EntryContext = &DiskEntry->DriverName;
222
224 KeyName,
226 NULL,
227 NULL);
228 if (!NT_SUCCESS(Status))
229 {
230 DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
231 }
232}
#define RTL_REGISTRY_DEVICEMAP
Definition: nt_native.h:165
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2705

◆ GetLogicalPartitionCount()

static ULONG GetLogicalPartitionCount ( _In_ PDISKENTRY  DiskEntry)
static

Definition at line 2288 of file partlist.c.

2290{
2291 PLIST_ENTRY ListEntry;
2292 PPARTENTRY PartEntry;
2293 ULONG Count = 0;
2294
2295 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
2296 ListEntry != &DiskEntry->LogicalPartListHead;
2297 ListEntry = ListEntry->Flink)
2298 {
2299 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
2300 if (PartEntry->IsPartitioned)
2301 Count++;
2302 }
2303
2304 return Count;
2305}
int Count
Definition: noreturn.cpp:7

◆ GetNextUnpartitionedEntry()

PPARTENTRY GetNextUnpartitionedEntry ( _In_ PPARTENTRY  PartEntry)

Definition at line 2658 of file partlist.c.

2660{
2661 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2662 PPARTENTRY NextPartEntry;
2663 PLIST_ENTRY ListHead;
2664
2665 if (PartEntry->LogicalPartition)
2666 ListHead = &DiskEntry->LogicalPartListHead;
2667 else
2668 ListHead = &DiskEntry->PrimaryPartListHead;
2669
2670 if (PartEntry->ListEntry.Flink != ListHead)
2671 {
2672 NextPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Flink,
2673 PARTENTRY,
2674 ListEntry);
2675 if (!NextPartEntry->IsPartitioned)
2676 {
2678 return NextPartEntry;
2679 }
2680 }
2681
2682 return NULL;
2683}

Referenced by DeleteGptPartition(), and DeleteMbrPartition().

◆ GetPrevUnpartitionedEntry()

PPARTENTRY GetPrevUnpartitionedEntry ( _In_ PPARTENTRY  PartEntry)

Definition at line 2629 of file partlist.c.

2631{
2632 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2633 PPARTENTRY PrevPartEntry;
2634 PLIST_ENTRY ListHead;
2635
2636 if (PartEntry->LogicalPartition)
2637 ListHead = &DiskEntry->LogicalPartListHead;
2638 else
2639 ListHead = &DiskEntry->PrimaryPartListHead;
2640
2641 if (PartEntry->ListEntry.Blink != ListHead)
2642 {
2643 PrevPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Blink,
2644 PARTENTRY,
2645 ListEntry);
2646 if (!PrevPartEntry->IsPartitioned)
2647 {
2649 return PrevPartEntry;
2650 }
2651 }
2652
2653 return NULL;
2654}

Referenced by DeleteGptPartition(), and DeleteMbrPartition().

◆ GetPrimaryPartitionCount()

ULONG GetPrimaryPartitionCount ( _In_ PDISKENTRY  DiskEntry)

Definition at line 2266 of file partlist.c.

2268{
2270 PPARTENTRY PartEntry;
2271 ULONG Count = 0;
2272
2273 for (Entry = DiskEntry->PrimaryPartListHead.Flink;
2274 Entry != &DiskEntry->PrimaryPartListHead;
2275 Entry = Entry->Flink)
2276 {
2277 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2278 if (PartEntry->IsPartitioned)
2279 Count++;
2280 }
2281
2282 return Count;
2283}

◆ GetVolumeExtents()

static VOID GetVolumeExtents ( _In_ HANDLE  VolumeHandle,
_In_ PVOLENTRY  VolumeEntry 
)
static

Definition at line 1675 of file partlist.c.

1678{
1679 DWORD dwBytesReturned = 0, dwLength, i;
1680 PVOLUME_DISK_EXTENTS pExtents;
1681 BOOL bResult;
1682 DWORD dwError;
1683
1684 dwLength = sizeof(VOLUME_DISK_EXTENTS);
1685 pExtents = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
1686 if (pExtents == NULL)
1687 return;
1688
1689 bResult = DeviceIoControl(VolumeHandle,
1691 NULL,
1692 0,
1693 pExtents,
1694 dwLength,
1695 &dwBytesReturned,
1696 NULL);
1697 if (!bResult)
1698 {
1699 dwError = GetLastError();
1700
1701 if (dwError != ERROR_MORE_DATA)
1702 {
1703 RtlFreeHeap(RtlGetProcessHeap(), 0, pExtents);
1704 return;
1705 }
1706 else
1707 {
1708 dwLength = sizeof(VOLUME_DISK_EXTENTS) + ((pExtents->NumberOfDiskExtents - 1) * sizeof(DISK_EXTENT));
1709 RtlFreeHeap(RtlGetProcessHeap(), 0, pExtents);
1710 pExtents = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
1711 if (pExtents == NULL)
1712 {
1713 return;
1714 }
1715
1716 bResult = DeviceIoControl(VolumeHandle,
1718 NULL,
1719 0,
1720 pExtents,
1721 dwLength,
1722 &dwBytesReturned,
1723 NULL);
1724 if (!bResult)
1725 {
1726 RtlFreeHeap(RtlGetProcessHeap(), 0, pExtents);
1727 return;
1728 }
1729 }
1730 }
1731
1732 for (i = 0; i < pExtents->NumberOfDiskExtents; i++)
1733 VolumeEntry->Size.QuadPart += pExtents->Extents[i].ExtentLength.QuadPart;
1734
1735 VolumeEntry->pExtents = pExtents;
1736}
#define ERROR_MORE_DATA
Definition: dderror.h:13
BOOL WINAPI DeviceIoControl(IN HANDLE hDevice, IN DWORD dwIoControlCode, IN LPVOID lpInBuffer OPTIONAL, IN DWORD nInBufferSize OPTIONAL, OUT LPVOID lpOutBuffer OPTIONAL, IN DWORD nOutBufferSize OPTIONAL, OUT LPDWORD lpBytesReturned OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: deviceio.c:136
struct _VOLUME_DISK_EXTENTS VOLUME_DISK_EXTENTS
struct _DISK_EXTENT DISK_EXTENT
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
Definition: ntddvol.h:44
LARGE_INTEGER ExtentLength
Definition: ntddvol.h:50
DISK_EXTENT Extents[1]
Definition: ntddvol.h:55
ULONG NumberOfDiskExtents
Definition: ntddvol.h:54

Referenced by AddVolumeToList().

◆ GetVolumeFromPartition()

PVOLENTRY GetVolumeFromPartition ( _In_ PPARTENTRY  PartEntry)

Definition at line 2795 of file partlist.c.

2797{
2799 PVOLENTRY VolumeEntry;
2800 ULONG i;
2801
2802 if ((PartEntry == NULL) ||
2803 (PartEntry->DiskEntry == NULL))
2804 return NULL;
2805
2807 while (Entry != &VolumeListHead)
2808 {
2809 VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
2810
2811 if (VolumeEntry->pExtents == NULL)
2812 return NULL;
2813
2814 for (i = 0; i < VolumeEntry->pExtents->NumberOfDiskExtents; i++)
2815 {
2816 if (VolumeEntry->pExtents->Extents[i].DiskNumber == PartEntry->DiskEntry->DiskNumber)
2817 {
2818 if ((VolumeEntry->pExtents->Extents[i].StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * PartEntry->DiskEntry->BytesPerSector) &&
2819 (VolumeEntry->pExtents->Extents[i].ExtentLength.QuadPart == PartEntry->SectorCount.QuadPart * PartEntry->DiskEntry->BytesPerSector))
2820 return VolumeEntry;
2821 }
2822 }
2823
2824 Entry = Entry->Flink;
2825 }
2826
2827 return NULL;
2828}
ULONG DiskNumber
Definition: ntddvol.h:48
LARGE_INTEGER StartingOffset
Definition: ntddvol.h:49

Referenced by clean_main().

◆ GetVolumeSize()

static VOID GetVolumeSize ( _In_ HANDLE  VolumeHandle,
_In_ PVOLENTRY  VolumeEntry 
)
static

Definition at line 1781 of file partlist.c.

1784{
1786 FILE_FS_FULL_SIZE_INFORMATION FullSizeInfo;
1789
1790 ZeroMemory(&FullSizeInfo, sizeof(FullSizeInfo));
1793 &FullSizeInfo,
1796 if (NT_SUCCESS(Status))
1797 {
1798 DPRINT("FullSizeInfo.TotalAllocationUnits %I64u\n", FullSizeInfo.TotalAllocationUnits.QuadPart);
1799 DPRINT("FullSizeInfo.SectorsPerAllocationUnit %lu\n", FullSizeInfo.SectorsPerAllocationUnit);
1800 DPRINT("FullSizeInfo.BytesPerSector %lu\n", FullSizeInfo.BytesPerSector);
1801
1802 VolumeEntry->TotalAllocationUnits.QuadPart = FullSizeInfo.TotalAllocationUnits.QuadPart;
1803 VolumeEntry->SectorsPerAllocationUnit = FullSizeInfo.SectorsPerAllocationUnit;
1804 VolumeEntry->BytesPerSector = FullSizeInfo.BytesPerSector;
1805 }
1806 else
1807 {
1808 ZeroMemory(&SizeInfo, sizeof(SizeInfo));
1811 &SizeInfo,
1814 if (NT_SUCCESS(Status))
1815 {
1816 DPRINT("SizeInfo.TotalAllocationUnits %I64u\n", SizeInfo.TotalAllocationUnits.QuadPart);
1817 DPRINT("SizeInfo.SectorsPerAllocationUnit %lu\n", SizeInfo.SectorsPerAllocationUnit);
1818 DPRINT("SizeInfo.BytesPerSector %lu\n", SizeInfo.BytesPerSector);
1819
1820 VolumeEntry->TotalAllocationUnits.QuadPart = SizeInfo.TotalAllocationUnits.QuadPart;
1821 VolumeEntry->SectorsPerAllocationUnit = SizeInfo.SectorsPerAllocationUnit;
1822 VolumeEntry->BytesPerSector = SizeInfo.BytesPerSector;
1823 }
1824 else
1825 {
1826 DPRINT("GetVolumeSize() failed!\n");
1827 }
1828 }
1829}
@ FileFsSizeInformation
Definition: from_kernel.h:221
#define ZeroMemory
Definition: minwinbase.h:31
#define FileFsFullSizeInformation
Definition: ntifs_ex.h:389
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass)
LARGE_INTEGER TotalAllocationUnits
Definition: from_kernel.h:270

Referenced by AddVolumeToList().

◆ GetVolumeType()

static VOID GetVolumeType ( _In_ HANDLE  VolumeHandle,
_In_ PVOLENTRY  VolumeEntry 
)
static

Definition at line 1741 of file partlist.c.

1744{
1748
1751 &DeviceInfo,
1754 if (!NT_SUCCESS(Status))
1755 return;
1756
1757 switch (DeviceInfo.DeviceType)
1758 {
1759 case FILE_DEVICE_CD_ROM:
1761 VolumeEntry->VolumeType = VOLUME_TYPE_CDROM;
1762 break;
1763
1764 case FILE_DEVICE_DISK:
1766 if (DeviceInfo.Characteristics & FILE_REMOVABLE_MEDIA)
1767 VolumeEntry->VolumeType = VOLUME_TYPE_REMOVABLE;
1768 else
1769 VolumeEntry->VolumeType = VOLUME_TYPE_PARTITION;
1770 break;
1771
1772 default:
1773 VolumeEntry->VolumeType = VOLUME_TYPE_UNKNOWN;
1774 break;
1775 }
1776}
@ VOLUME_TYPE_UNKNOWN
Definition: diskpart.h:114
@ VOLUME_TYPE_REMOVABLE
Definition: diskpart.h:113
@ VOLUME_TYPE_CDROM
Definition: diskpart.h:111
@ FileFsDeviceInformation
Definition: from_kernel.h:222
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define FILE_DEVICE_DISK_FILE_SYSTEM
Definition: winioctl.h:53
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:47
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM
Definition: winioctl.h:48
#define FILE_DEVICE_DISK
Definition: winioctl.h:52

Referenced by AddVolumeToList().

◆ IsEmptyLayoutEntry()

static BOOLEAN IsEmptyLayoutEntry ( IN PPARTITION_INFORMATION_EX  PartitionInfo)
static

Definition at line 2235 of file partlist.c.

2237{
2238 if (PartitionInfo->StartingOffset.QuadPart == 0 &&
2239 PartitionInfo->PartitionLength.QuadPart == 0)
2240 {
2241 return TRUE;
2242 }
2243
2244 return FALSE;
2245}

◆ IsSamePrimaryLayoutEntry()

static BOOLEAN IsSamePrimaryLayoutEntry ( IN PPARTITION_INFORMATION_EX  PartitionInfo,
IN PDISKENTRY  DiskEntry,
IN PPARTENTRY  PartEntry 
)
static

Definition at line 2250 of file partlist.c.

2254{
2255 if ((PartitionInfo->StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector) &&
2256 (PartitionInfo->PartitionLength.QuadPart == PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector))
2257 {
2258 return TRUE;
2259 }
2260
2261 return FALSE;
2262}

◆ ReadLayoutBuffer()

VOID ReadLayoutBuffer ( _In_ HANDLE  FileHandle,
_In_ PDISKENTRY  DiskEntry 
)

Definition at line 1065 of file partlist.c.

1068{
1069 ULONG LayoutBufferSize;
1070 PDRIVE_LAYOUT_INFORMATION_EX NewLayoutBuffer;
1073
1074 /* Allocate a layout buffer with 4 partition entries first */
1075 LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
1076 ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION_EX));
1077 DiskEntry->LayoutBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
1079 LayoutBufferSize);
1080 if (DiskEntry->LayoutBuffer == NULL)
1081 {
1082 DPRINT1("Failed to allocate the disk layout buffer!\n");
1083 return;
1084 }
1085
1086 for (;;)
1087 {
1088 DPRINT("Buffer size: %lu\n", LayoutBufferSize);
1090 NULL,
1091 NULL,
1092 NULL,
1093 &Iosb,
1095 NULL,
1096 0,
1097 DiskEntry->LayoutBuffer,
1098 LayoutBufferSize);
1099 if (NT_SUCCESS(Status))
1100 break;
1101
1103 {
1104 DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status);
1105 return;
1106 }
1107
1108 LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION_EX);
1109 NewLayoutBuffer = RtlReAllocateHeap(RtlGetProcessHeap(),
1111 DiskEntry->LayoutBuffer,
1112 LayoutBufferSize);
1113 if (NewLayoutBuffer == NULL)
1114 {
1115 DPRINT1("Failed to reallocate the disk layout buffer!\n");
1116 return;
1117 }
1118
1119 DiskEntry->LayoutBuffer = NewLayoutBuffer;
1120 }
1121}
#define IOCTL_DISK_GET_DRIVE_LAYOUT_EX
Definition: ntddk_ex.h:207
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T) __WINE_ALLOC_SIZE(4) __WINE_DEALLOC(RtlFreeHeap
struct _PARTITION_INFORMATION_EX PARTITION_INFORMATION_EX
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define ANYSIZE_ARRAY
Definition: typedefs.h:46

Referenced by AddDiskToList(), and CreateDisk().

◆ ReAllocateLayoutBuffer()

static BOOLEAN ReAllocateLayoutBuffer ( _In_ PDISKENTRY  DiskEntry)
static

Definition at line 2310 of file partlist.c.

2312{
2313 PDRIVE_LAYOUT_INFORMATION_EX NewLayoutBuffer;
2314 ULONG NewPartitionCount;
2315 ULONG CurrentPartitionCount = 0;
2316 ULONG LayoutBufferSize;
2317 ULONG i;
2318
2319 DPRINT1("ReAllocateLayoutBuffer()\n");
2320
2321 NewPartitionCount = 4 + GetLogicalPartitionCount(DiskEntry) * 4;
2322
2323 if (DiskEntry->LayoutBuffer)
2324 CurrentPartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
2325
2326 DPRINT1("CurrentPartitionCount: %lu ; NewPartitionCount: %lu\n",
2327 CurrentPartitionCount, NewPartitionCount);
2328
2329 if (CurrentPartitionCount == NewPartitionCount)
2330 return TRUE;
2331
2332 LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
2333 ((NewPartitionCount - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION_EX));
2334 NewLayoutBuffer = RtlReAllocateHeap(RtlGetProcessHeap(),
2336 DiskEntry->LayoutBuffer,
2337 LayoutBufferSize);
2338 if (NewLayoutBuffer == NULL)
2339 {
2340 DPRINT1("Failed to allocate the new layout buffer (size: %lu)\n", LayoutBufferSize);
2341 return FALSE;
2342 }
2343
2344 NewLayoutBuffer->PartitionCount = NewPartitionCount;
2345
2346 /* If the layout buffer grows, make sure the new (empty) entries are written to the disk */
2347 if (NewPartitionCount > CurrentPartitionCount)
2348 {
2349 for (i = CurrentPartitionCount; i < NewPartitionCount; i++)
2350 {
2351 NewLayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
2352 }
2353 }
2354
2355 DiskEntry->LayoutBuffer = NewLayoutBuffer;
2356
2357 return TRUE;
2358}
#define GetLogicalPartitionCount(DiskEntry)
Definition: partlist.c:2530

◆ RemoveVolume()

VOID RemoveVolume ( _In_ PVOLENTRY  VolumeEntry)

Definition at line 2832 of file partlist.c.

2834{
2835 if (VolumeEntry == NULL)
2836 return;
2837
2838 if (VolumeEntry == CurrentVolume)
2840
2841 RemoveEntryList(&VolumeEntry->ListEntry);
2842
2843 if (VolumeEntry->pszLabel)
2844 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszLabel);
2845
2846 if (VolumeEntry->pszFilesystem)
2847 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszFilesystem);
2848
2849 if (VolumeEntry->pExtents)
2850 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pExtents);
2851
2852 /* Release disk entry */
2853 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry);
2854}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986

Referenced by clean_main().

◆ ScanForUnpartitionedGptDiskSpace()

VOID ScanForUnpartitionedGptDiskSpace ( PDISKENTRY  DiskEntry)

Definition at line 921 of file partlist.c.

923{
924 ULONGLONG LastStartSector;
925 ULONGLONG LastSectorCount;
926 ULONGLONG LastUnusedSectorCount;
927 PPARTENTRY PartEntry;
928 PPARTENTRY NewPartEntry;
930
931 DPRINT("ScanForUnpartitionedGptDiskSpace()\n");
932
933#ifdef DUMP_PARTITION_LIST
934 DumpPartitionList(DiskEntry);
935#endif
936
937 if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
938 {
939 DPRINT("No partitions!\n");
940
941 /* Create a partition table that represents the empty disk */
942 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
944 sizeof(PARTENTRY));
945 if (NewPartEntry == NULL)
946 return;
947
948 NewPartEntry->DiskEntry = DiskEntry;
949
950 NewPartEntry->IsPartitioned = FALSE;
951 NewPartEntry->StartSector.QuadPart = DiskEntry->StartSector.QuadPart;
952 NewPartEntry->SectorCount.QuadPart = DiskEntry->EndSector.QuadPart - DiskEntry->StartSector.QuadPart + 1;
953
954 DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
955 DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
956 DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
957
958 NewPartEntry->FormatState = Unformatted;
959
961 &NewPartEntry->ListEntry);
962
963#ifdef DUMP_PARTITION_LIST
964 DumpPartitionList(DiskEntry);
965#endif
966
967 return;
968 }
969
970 /* Start at the first usable sector */
971 LastStartSector = DiskEntry->StartSector.QuadPart;
972 LastSectorCount = 0ULL;
973 LastUnusedSectorCount = 0ULL;
974
975 Entry = DiskEntry->PrimaryPartListHead.Flink;
976 while (Entry != &DiskEntry->PrimaryPartListHead)
977 {
978 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
979
980 if (!IsEqualGUID(&PartEntry->Gpt.PartitionType, &PARTITION_ENTRY_UNUSED_GUID) ||
981 PartEntry->SectorCount.QuadPart != 0ULL)
982 {
983 LastUnusedSectorCount =
984 PartEntry->StartSector.QuadPart - (LastStartSector + LastSectorCount);
985
986 if (PartEntry->StartSector.QuadPart > (LastStartSector + LastSectorCount) &&
987 LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
988 {
989 DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
990
991 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
993 sizeof(PARTENTRY));
994 if (NewPartEntry == NULL)
995 return;
996
997 NewPartEntry->DiskEntry = DiskEntry;
998
999 NewPartEntry->IsPartitioned = FALSE;
1000 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
1001 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
1002 NewPartEntry->StartSector.QuadPart;
1003
1004 DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
1005 DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
1006 DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
1007
1008 NewPartEntry->FormatState = Unformatted;
1009
1010 /* Insert the table into the list */
1011 InsertTailList(&PartEntry->ListEntry,
1012 &NewPartEntry->ListEntry);
1013 }
1014
1015 LastStartSector = PartEntry->StartSector.QuadPart;
1016 LastSectorCount = PartEntry->SectorCount.QuadPart;
1017 }
1018
1019 Entry = Entry->Flink;
1020 }
1021
1022 /* Check for trailing unpartitioned disk space */
1023 if ((LastStartSector + LastSectorCount) < DiskEntry->EndSector.QuadPart + 1)
1024 {
1025 LastUnusedSectorCount = AlignDown(DiskEntry->EndSector.QuadPart + 1 - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
1026
1027 if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
1028 {
1029 DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
1030
1031 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
1033 sizeof(PARTENTRY));
1034 if (NewPartEntry == NULL)
1035 return;
1036
1037 NewPartEntry->DiskEntry = DiskEntry;
1038
1039 NewPartEntry->IsPartitioned = FALSE;
1040 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
1041 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
1042 NewPartEntry->StartSector.QuadPart;
1043
1044 DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
1045 DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
1046 DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
1047
1048 NewPartEntry->FormatState = Unformatted;
1049
1050 /* Append the table to the list */
1052 &NewPartEntry->ListEntry);
1053 }
1054 }
1055
1056#ifdef DUMP_PARTITION_LIST
1057 DumpPartitionList(DiskEntry);
1058#endif
1059
1060 DPRINT("ScanForUnpartitionedGptDiskSpace() done\n");
1061}
#define ULL(a, b)
Definition: format_msg.c:27

Referenced by AddDiskToList(), and ConvertGPT().

◆ ScanForUnpartitionedMbrDiskSpace()

VOID ScanForUnpartitionedMbrDiskSpace ( PDISKENTRY  DiskEntry)

Definition at line 660 of file partlist.c.

662{
663 ULONGLONG StartSector, EndSector;
664 ULONGLONG LastStartSector;
665 ULONGLONG LastSectorCount;
666 ULONGLONG LastUnusedSectorCount;
667 PPARTENTRY PartEntry;
668 PPARTENTRY NewPartEntry;
670
671 DPRINT("ScanForUnpartitionedMbrDiskSpace()\n");
672
673 /* Calculate the disk sector limits */
674 /* Limit the SectorCount to 2^32 sectors for MBR disks */
675 StartSector = (ULONGLONG)DiskEntry->SectorAlignment;
676 EndSector = min(DiskEntry->SectorCount.QuadPart, 0x100000000) - 1;
677
678 if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
679 {
680 DPRINT1("No primary partition!\n");
681
682 /* Create a partition table that represents the empty disk */
683 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
685 sizeof(PARTENTRY));
686 if (NewPartEntry == NULL)
687 return;
688
689 NewPartEntry->DiskEntry = DiskEntry;
690
691 NewPartEntry->IsPartitioned = FALSE;
692 NewPartEntry->StartSector.QuadPart = StartSector;
693 NewPartEntry->SectorCount.QuadPart = AlignDown(EndSector + 1, DiskEntry->SectorAlignment) -
694 NewPartEntry->StartSector.QuadPart;
695
696 DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
697 DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
698 DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
699
700 NewPartEntry->FormatState = Unformatted;
701
703 &NewPartEntry->ListEntry);
704
705 return;
706 }
707
708 /* Start at the first usable sector */
709 LastStartSector = StartSector;
710 LastSectorCount = 0ULL;
711 LastUnusedSectorCount = 0ULL;
712
713 Entry = DiskEntry->PrimaryPartListHead.Flink;
714 while (Entry != &DiskEntry->PrimaryPartListHead)
715 {
716 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
717
718 if (PartEntry->Mbr.PartitionType != PARTITION_ENTRY_UNUSED ||
719 PartEntry->SectorCount.QuadPart != 0ULL)
720 {
721 LastUnusedSectorCount =
722 PartEntry->StartSector.QuadPart - (LastStartSector + LastSectorCount);
723
724 if (PartEntry->StartSector.QuadPart > (LastStartSector + LastSectorCount) &&
725 LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
726 {
727 DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
728
729 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
731 sizeof(PARTENTRY));
732 if (NewPartEntry == NULL)
733 return;
734
735 NewPartEntry->DiskEntry = DiskEntry;
736
737 NewPartEntry->IsPartitioned = FALSE;
738 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
739 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
740 NewPartEntry->StartSector.QuadPart;
741
742 DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
743 DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
744 DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
745
746 NewPartEntry->FormatState = Unformatted;
747
748 /* Insert the table into the list */
749 InsertTailList(&PartEntry->ListEntry,
750 &NewPartEntry->ListEntry);
751 }
752
753 LastStartSector = PartEntry->StartSector.QuadPart;
754 LastSectorCount = PartEntry->SectorCount.QuadPart;
755 }
756
757 Entry = Entry->Flink;
758 }
759
760 /* Check for trailing unpartitioned disk space */
761 if ((LastStartSector + LastSectorCount) < (EndSector + 1))
762 {
763 LastUnusedSectorCount = AlignDown((EndSector + 1) - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
764
765 if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
766 {
767 DPRINT1("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
768
769 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
771 sizeof(PARTENTRY));
772 if (NewPartEntry == NULL)
773 return;
774
775 NewPartEntry->DiskEntry = DiskEntry;
776
777 NewPartEntry->IsPartitioned = FALSE;
778 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
779 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
780 NewPartEntry->StartSector.QuadPart;
781
782 DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
783 DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
784 DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
785
786 NewPartEntry->FormatState = Unformatted;
787
788 /* Append the table to the list */
790 &NewPartEntry->ListEntry);
791 }
792 }
793
794 if (DiskEntry->ExtendedPartition != NULL)
795 {
796 if (IsListEmpty(&DiskEntry->LogicalPartListHead))
797 {
798 DPRINT1("No logical partition!\n");
799
800 /* Create a partition table entry that represents the empty extended partition */
801 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
803 sizeof(PARTENTRY));
804 if (NewPartEntry == NULL)
805 return;
806
807 NewPartEntry->DiskEntry = DiskEntry;
808 NewPartEntry->LogicalPartition = TRUE;
809
810 NewPartEntry->IsPartitioned = FALSE;
811 NewPartEntry->StartSector.QuadPart = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
812 NewPartEntry->SectorCount.QuadPart = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
813
814 DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
815 DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
816 DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
817
818 NewPartEntry->FormatState = Unformatted;
819
821 &NewPartEntry->ListEntry);
822
823 return;
824 }
825
826 /* Start partition at head 1, cylinder 0 */
827 LastStartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
828 LastSectorCount = 0ULL;
829 LastUnusedSectorCount = 0ULL;
830
831 Entry = DiskEntry->LogicalPartListHead.Flink;
832 while (Entry != &DiskEntry->LogicalPartListHead)
833 {
834 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
835
836 if (PartEntry->Mbr.PartitionType != PARTITION_ENTRY_UNUSED ||
837 PartEntry->SectorCount.QuadPart != 0ULL)
838 {
839 LastUnusedSectorCount =
840 PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment - (LastStartSector + LastSectorCount);
841
842 if ((PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment) > (LastStartSector + LastSectorCount) &&
843 LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
844 {
845 DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
846
847 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
849 sizeof(PARTENTRY));
850 if (NewPartEntry == NULL)
851 return;
852
853 NewPartEntry->DiskEntry = DiskEntry;
854 NewPartEntry->LogicalPartition = TRUE;
855
856 NewPartEntry->IsPartitioned = FALSE;
857 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
858 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
859 NewPartEntry->StartSector.QuadPart;
860
861 DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
862 DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
863 DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
864
865 NewPartEntry->FormatState = Unformatted;
866
867 /* Insert the table into the list */
868 InsertTailList(&PartEntry->ListEntry,
869 &NewPartEntry->ListEntry);
870 }
871
872 LastStartSector = PartEntry->StartSector.QuadPart;
873 LastSectorCount = PartEntry->SectorCount.QuadPart;
874 }
875
876 Entry = Entry->Flink;
877 }
878
879 /* Check for trailing unpartitioned disk space */
880 if ((LastStartSector + LastSectorCount) < DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart)
881 {
882 LastUnusedSectorCount = AlignDown(DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart - (LastStartSector + LastSectorCount),
883 DiskEntry->SectorAlignment);
884
885 if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
886 {
887 DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
888
889 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
891 sizeof(PARTENTRY));
892 if (NewPartEntry == NULL)
893 return;
894
895 NewPartEntry->DiskEntry = DiskEntry;
896 NewPartEntry->LogicalPartition = TRUE;
897
898 NewPartEntry->IsPartitioned = FALSE;
899 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
900 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
901 NewPartEntry->StartSector.QuadPart;
902
903 DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
904 DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
905 DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
906
907 NewPartEntry->FormatState = Unformatted;
908
909 /* Append the table to the list */
911 &NewPartEntry->ListEntry);
912 }
913 }
914 }
915
916 DPRINT("ScanForUnpartitionedMbrDiskSpace() done\n");
917}
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))

Referenced by AddDiskToList(), ConvertMBR(), CreateExtendedPartition(), and CreatePrimaryPartition().

◆ SystemConfigurationDataQueryRoutine()

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

Definition at line 311 of file partlist.c.

318{
319 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
321 ULONG i;
322
325 return STATUS_UNSUCCESSFUL;
326
327 FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
328
329 /* Hm. Version and Revision are not set on Microsoft Windows XP... */
330#if 0
331 if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
332 FullResourceDescriptor->PartialResourceList.Revision != 1)
333 return STATUS_UNSUCCESSFUL;
334#endif
335
336 for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
337 {
339 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize % sizeof(CM_INT13_DRIVE_PARAMETER) != 0)
340 continue;
341
342 *Int13Drives = (CM_INT13_DRIVE_PARAMETER*)RtlAllocateHeap(RtlGetProcessHeap(), 0,
343 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
344 if (*Int13Drives == NULL)
345 return STATUS_NO_MEMORY;
346
347 memcpy(*Int13Drives,
348 &FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1],
349 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
350 return STATUS_SUCCESS;
351 }
352
353 return STATUS_UNSUCCESSFUL;
354}
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878

◆ UpdateGptDiskLayout()

VOID UpdateGptDiskLayout ( _In_ PDISKENTRY  DiskEntry,
_In_ BOOL  DeleteEntry 
)

Definition at line 2539 of file partlist.c.

2542{
2543 PLIST_ENTRY ListEntry;
2544 PPARTENTRY PartEntry;
2546 ULONG Count, Index;
2547
2548 DPRINT("UpdateGptDiskLayout()\n");
2549
2550 /* Count used partition entries */
2551 Count = 0;
2552 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
2553 ListEntry != &DiskEntry->PrimaryPartListHead;
2554 ListEntry = ListEntry->Flink)
2555 {
2556 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
2557
2558 if (!IsEqualGUID(&PartEntry->Gpt.PartitionType, &PARTITION_ENTRY_UNUSED_GUID))
2559 Count++;
2560 }
2561
2562 DPRINT("Used partition entries: %lu\n", Count);
2563
2564 if (DeleteEntry)
2565 Count++;
2566
2567 /* Reallocate the layout buffer */
2568 if (Count != DiskEntry->LayoutBuffer->PartitionCount)
2569 {
2570 PDRIVE_LAYOUT_INFORMATION_EX NewLayoutBuffer;
2571 ULONG NewLayoutBufferSize;
2572
2573 NewLayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
2575 NewLayoutBuffer = RtlReAllocateHeap(RtlGetProcessHeap(),
2577 DiskEntry->LayoutBuffer,
2578 NewLayoutBufferSize);
2579 if (NewLayoutBuffer == NULL)
2580 {
2581 DPRINT1("Failed to allocate the new layout buffer (size: %lu)\n", NewLayoutBufferSize);
2582 return;
2583 }
2584
2585 NewLayoutBuffer->PartitionCount = Count;
2586 DiskEntry->LayoutBuffer = NewLayoutBuffer;
2587 }
2588
2589 /* Fill the new layout buffer */
2590 Index = 0;
2591 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
2592 ListEntry != &DiskEntry->PrimaryPartListHead;
2593 ListEntry = ListEntry->Flink)
2594 {
2595 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
2596
2597 if (!IsEqualGUID(&PartEntry->Gpt.PartitionType, &PARTITION_ENTRY_UNUSED_GUID))
2598 {
2599 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
2600 PartEntry->PartitionIndex = Index;
2601
2602 DPRINT("Updating primary partition entry %lu\n", Index);
2603 PartitionInfo->PartitionStyle = PARTITION_STYLE_GPT;
2604 PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
2605 PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
2606 PartitionInfo->PartitionNumber = Index + 1;
2607 PartitionInfo->RewritePartition = TRUE;
2608 CopyMemory(&PartitionInfo->Gpt.PartitionType, &PartEntry->Gpt.PartitionType, sizeof(GUID));
2609 CopyMemory(&PartitionInfo->Gpt.PartitionId, &PartEntry->Gpt.PartitionId, sizeof(GUID));
2610 PartitionInfo->Gpt.Attributes = PartEntry->Gpt.Attributes;
2611 ZeroMemory(&PartitionInfo->Gpt.Name, 36 * sizeof(WCHAR)); /* ??? */
2612
2613 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
2614
2615 Index++;
2616 }
2617 }
2618
2619 if (DeleteEntry)
2620 {
2621 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
2623 PartitionInfo->RewritePartition = TRUE;
2624 }
2625}

Referenced by CreateEfiPartition(), CreateMsrPartition(), CreatePrimaryGptPartition(), DeleteGptPartition(), gpt_main(), setid_main(), and UniqueIdDisk().

◆ UpdateMbrDiskLayout()

VOID UpdateMbrDiskLayout ( _In_ PDISKENTRY  DiskEntry)

Definition at line 2362 of file partlist.c.

2364{
2367 PLIST_ENTRY ListEntry;
2368 PPARTENTRY PartEntry;
2369 LARGE_INTEGER HiddenSectors64;
2370 ULONG Index;
2372
2373 DPRINT("UpdateMbrDiskLayout()\n");
2374
2375 /* Resize the layout buffer if necessary */
2376 if (ReAllocateLayoutBuffer(DiskEntry) == FALSE)
2377 {
2378 DPRINT("ReAllocateLayoutBuffer() failed.\n");
2379 return;
2380 }
2381
2382 DiskEntry->LayoutBuffer->PartitionStyle = PARTITION_STYLE_MBR;
2383
2384 /* Update the primary partition table */
2385 Index = 0;
2386 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
2387 ListEntry != &DiskEntry->PrimaryPartListHead;
2388 ListEntry = ListEntry->Flink)
2389 {
2390 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
2391
2392 if (PartEntry->IsPartitioned)
2393 {
2395
2396 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
2397 PartEntry->PartitionIndex = Index;
2398
2399 /* Reset the current partition number only for newly-created (unmounted) partitions */
2400 if (PartEntry->New)
2401 PartEntry->PartitionNumber = 0;
2402
2404
2405 if (!IsSamePrimaryLayoutEntry(PartitionInfo, DiskEntry, PartEntry))
2406 {
2407 DPRINT1("Updating primary partition entry %lu\n", Index);
2408
2409 PartitionInfo->PartitionStyle = PARTITION_STYLE_MBR;
2410 PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
2411 PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
2412 PartitionInfo->Mbr.HiddenSectors = PartEntry->StartSector.LowPart;
2413 PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
2414 PartitionInfo->Mbr.PartitionType = PartEntry->Mbr.PartitionType;
2415 PartitionInfo->Mbr.BootIndicator = PartEntry->Mbr.BootIndicator;
2416 PartitionInfo->Mbr.RecognizedPartition = IsRecognizedPartition(PartEntry->Mbr.PartitionType);
2417 PartitionInfo->RewritePartition = TRUE;
2418 }
2419
2420 if (!IsContainerPartition(PartEntry->Mbr.PartitionType))
2422
2423 Index++;
2424 }
2425 }
2426
2427 ASSERT(Index <= 4);
2428
2429 /* Update the logical partition table */
2430 Index = 4;
2431 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
2432 ListEntry != &DiskEntry->LogicalPartListHead;
2433 ListEntry = ListEntry->Flink)
2434 {
2435 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
2436
2437 if (PartEntry->IsPartitioned)
2438 {
2440
2441 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
2442 PartEntry->PartitionIndex = Index;
2443
2444 /* Reset the current partition number only for newly-created (unmounted) partitions */
2445 if (PartEntry->New)
2446 PartEntry->PartitionNumber = 0;
2447
2449
2450 DPRINT1("Updating logical partition entry %lu\n", Index);
2451
2452 PartitionInfo->PartitionStyle = PARTITION_STYLE_MBR;
2453 PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
2454 PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
2455 PartitionInfo->Mbr.HiddenSectors = DiskEntry->SectorAlignment;
2456 PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
2457 PartitionInfo->Mbr.PartitionType = PartEntry->Mbr.PartitionType;
2458 PartitionInfo->Mbr.BootIndicator = FALSE;
2459 PartitionInfo->Mbr.RecognizedPartition = IsRecognizedPartition(PartEntry->Mbr.PartitionType);
2460 PartitionInfo->RewritePartition = TRUE;
2461
2462 /* Fill the link entry of the previous partition entry */
2463 if (LinkInfo != NULL)
2464 {
2466 LinkInfo->StartingOffset.QuadPart = (PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
2467 LinkInfo->PartitionLength.QuadPart = (PartEntry->StartSector.QuadPart + DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
2468 HiddenSectors64.QuadPart = PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment - DiskEntry->ExtendedPartition->StartSector.QuadPart;
2469 LinkInfo->Mbr.HiddenSectors = HiddenSectors64.LowPart;
2470 LinkInfo->PartitionNumber = 0;
2472 LinkInfo->Mbr.BootIndicator = FALSE;
2473 LinkInfo->Mbr.RecognizedPartition = FALSE;
2474 LinkInfo->RewritePartition = TRUE;
2475 }
2476
2477 /* Save a pointer to the link entry of the current partition entry */
2478 LinkInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index + 1];
2479
2481 Index += 4;
2482 }
2483 }
2484
2485 /* Wipe unused primary partition entries */
2486 for (Index = GetPrimaryPartitionCount(DiskEntry); Index < 4; Index++)
2487 {
2488 DPRINT1("Primary partition entry %lu\n", Index);
2489
2490 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
2491
2493 {
2494 DPRINT1("Wiping primary partition entry %lu\n", Index);
2495
2496 PartitionInfo->PartitionStyle = PARTITION_STYLE_MBR;
2497 PartitionInfo->StartingOffset.QuadPart = 0;
2498 PartitionInfo->PartitionLength.QuadPart = 0;
2499 PartitionInfo->Mbr.HiddenSectors = 0;
2500 PartitionInfo->PartitionNumber = 0;
2501 PartitionInfo->Mbr.PartitionType = PARTITION_ENTRY_UNUSED;
2502 PartitionInfo->Mbr.BootIndicator = FALSE;
2503 PartitionInfo->Mbr.RecognizedPartition = FALSE;
2504 PartitionInfo->RewritePartition = TRUE;
2505 }
2506 }
2507
2508 /* Wipe unused logical partition entries */
2509 for (Index = 4; Index < DiskEntry->LayoutBuffer->PartitionCount; Index++)
2510 {
2511 if (Index % 4 >= 2)
2512 {
2513 DPRINT1("Logical partition entry %lu\n", Index);
2514
2515 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
2516
2518 {
2519 DPRINT1("Wiping partition entry %lu\n", Index);
2520
2521 PartitionInfo->PartitionStyle = PARTITION_STYLE_MBR;
2522 PartitionInfo->StartingOffset.QuadPart = 0;
2523 PartitionInfo->PartitionLength.QuadPart = 0;
2524 PartitionInfo->Mbr.HiddenSectors = 0;
2525 PartitionInfo->PartitionNumber = 0;
2526 PartitionInfo->Mbr.PartitionType = PARTITION_ENTRY_UNUSED;
2527 PartitionInfo->Mbr.BootIndicator = FALSE;
2528 PartitionInfo->Mbr.RecognizedPartition = FALSE;
2529 PartitionInfo->RewritePartition = TRUE;
2530 }
2531 }
2532 }
2533
2534 DiskEntry->Dirty = TRUE;
2535}
#define PARTITION_EXTENDED
Definition: disk.h:76
#define GetPrimaryPartitionCount(DiskEntry)
Definition: partlist.c:2527
BOOLEAN New
Definition: partlist.h:85
ULONG OnDiskPartitionNumber
Definition: partlist.h:74
LARGE_INTEGER StartingOffset
Definition: imports.h:221
PARTITION_STYLE PartitionStyle
Definition: imports.h:220
PARTITION_INFORMATION_MBR Mbr
Definition: imports.h:226
LARGE_INTEGER PartitionLength
Definition: imports.h:222
$ULONG LowPart
Definition: ntbasedef.h:581
static BOOLEAN IsSamePrimaryLayoutEntry(IN PPARTITION_INFORMATION_EX PartitionInfo, IN PDISKENTRY DiskEntry, IN PPARTENTRY PartEntry)
Definition: partlist.c:2250
static BOOLEAN IsEmptyLayoutEntry(IN PPARTITION_INFORMATION_EX PartitionInfo)
Definition: partlist.c:2235
static BOOLEAN ReAllocateLayoutBuffer(_In_ PDISKENTRY DiskEntry)
Definition: partlist.c:2310
ULONG LowPart
Definition: typedefs.h:106
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2061

Referenced by active_main(), CreateExtendedPartition(), CreateLogicalPartition(), CreatePrimaryMbrPartition(), DeleteMbrPartition(), inactive_main(), setid_main(), and UniqueIdDisk().

◆ WriteGptPartitions()

NTSTATUS WriteGptPartitions ( _In_ PDISKENTRY  DiskEntry)

Definition at line 2158 of file partlist.c.

2160{
2168
2169 DPRINT("WriteGptPartitions() Disk: %lu\n", DiskEntry->DiskNumber);
2170
2171 /* If the disk is not dirty, there is nothing to do */
2172 if (!DiskEntry->Dirty)
2173 return STATUS_SUCCESS;
2174
2176 L"\\Device\\Harddisk%lu\\Partition0",
2177 DiskEntry->DiskNumber);
2179
2181 &Name,
2183 NULL,
2184 NULL);
2185
2189 &Iosb,
2190 0,
2192 if (!NT_SUCCESS(Status))
2193 {
2194 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
2195 return Status;
2196 }
2197
2198 //
2199 // FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize
2200 // the disk in MBR or GPT format in case the disk was not initialized!!
2201 // For this we must ask the user which format to use.
2202 //
2203
2204 /* Set the new disk layout and retrieve its updated version with possibly modified partition numbers */
2205 BufferSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
2206 ((DiskEntry->LayoutBuffer->PartitionCount - 1) * sizeof(PARTITION_INFORMATION_EX));
2208 NULL,
2209 NULL,
2210 NULL,
2211 &Iosb,
2213 DiskEntry->LayoutBuffer,
2214 BufferSize,
2215 DiskEntry->LayoutBuffer,
2216 BufferSize);
2218
2219 /* Check whether the IOCTL_DISK_SET_DRIVE_LAYOUT_EX call succeeded */
2220 if (!NT_SUCCESS(Status))
2221 {
2222 DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT_EX failed (Status 0x%08lx)\n", Status);
2223 return Status;
2224 }
2225
2226 /* The layout has been successfully updated, the disk is not dirty anymore */
2227 DiskEntry->Dirty = FALSE;
2228
2229 return Status;
2230}
#define BufferSize
Definition: mmc.h:75
#define IOCTL_DISK_SET_DRIVE_LAYOUT_EX
Definition: ntdddisk.h:208
IN HANDLE DstPath
Definition: fsutil.h:81
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254

Referenced by CreateEfiPartition(), CreateMsrPartition(), CreatePrimaryGptPartition(), DeleteGptPartition(), gpt_main(), setid_main(), and UniqueIdDisk().

◆ WriteMbrPartitions()

NTSTATUS WriteMbrPartitions ( _In_ PDISKENTRY  DiskEntry)

Definition at line 2034 of file partlist.c.

2036{
2044 ULONG PartitionCount;
2045 PLIST_ENTRY ListEntry;
2046 PPARTENTRY PartEntry;
2048
2049 DPRINT("WriteMbrPartitions() Disk: %lu\n", DiskEntry->DiskNumber);
2050
2051 /* If the disk is not dirty, there is nothing to do */
2052 if (!DiskEntry->Dirty)
2053 return STATUS_SUCCESS;
2054
2056 L"\\Device\\Harddisk%lu\\Partition0",
2057 DiskEntry->DiskNumber);
2059
2061 &Name,
2063 NULL,
2064 NULL);
2065
2069 &Iosb,
2070 0,
2072 if (!NT_SUCCESS(Status))
2073 {
2074 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
2075 return Status;
2076 }
2077
2078 //
2079 // FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize
2080 // the disk in MBR or GPT format in case the disk was not initialized!!
2081 // For this we must ask the user which format to use.
2082 //
2083
2084 /* Save the original partition count to be restored later (see comment below) */
2085 PartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
2086
2087 /* Set the new disk layout and retrieve its updated version with possibly modified partition numbers */
2088 BufferSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
2089 ((PartitionCount - 1) * sizeof(PARTITION_INFORMATION_EX));
2091 NULL,
2092 NULL,
2093 NULL,
2094 &Iosb,
2096 DiskEntry->LayoutBuffer,
2097 BufferSize,
2098 DiskEntry->LayoutBuffer,
2099 BufferSize);
2101
2102 /*
2103 * IOCTL_DISK_SET_DRIVE_LAYOUT calls IoWritePartitionTable(), which converts
2104 * DiskEntry->LayoutBuffer->PartitionCount into a partition *table* count,
2105 * where such a table is expected to enumerate up to 4 partitions:
2106 * partition *table* count == ROUND_UP(PartitionCount, 4) / 4 .
2107 * Due to this we need to restore the original PartitionCount number.
2108 */
2109 DiskEntry->LayoutBuffer->PartitionCount = PartitionCount;
2110
2111 /* Check whether the IOCTL_DISK_SET_DRIVE_LAYOUT call succeeded */
2112 if (!NT_SUCCESS(Status))
2113 {
2114 DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status);
2115 return Status;
2116 }
2117
2118 /* Update the partition numbers */
2119
2120 /* Update the primary partition table */
2121 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
2122 ListEntry != &DiskEntry->PrimaryPartListHead;
2123 ListEntry = ListEntry->Flink)
2124 {
2125 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
2126
2127 if (PartEntry->IsPartitioned)
2128 {
2130 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
2131 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
2132 }
2133 }
2134
2135 /* Update the logical partition table */
2136 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
2137 ListEntry != &DiskEntry->LogicalPartListHead;
2138 ListEntry = ListEntry->Flink)
2139 {
2140 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
2141
2142 if (PartEntry->IsPartitioned)
2143 {
2145 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
2146 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
2147 }
2148 }
2149
2150 /* The layout has been successfully updated, the disk is not dirty anymore */
2151 DiskEntry->Dirty = FALSE;
2152
2153 return Status;
2154}

Referenced by active_main(), CreateExtendedPartition(), CreateLogicalPartition(), CreatePrimaryMbrPartition(), DeleteMbrPartition(), inactive_main(), setid_main(), and UniqueIdDisk().

Variable Documentation

◆ BiosDiskListHead

LIST_ENTRY BiosDiskListHead

◆ CurrentDisk

◆ CurrentPartition

PPARTENTRY CurrentPartition = NULL

Definition at line 76 of file partlist.c.

Referenced by CreatePartitionList(), and DestroyPartitionList().

◆ CurrentVolume

◆ DiskListHead

◆ VolumeListHead