ReactOS 0.4.16-dev-1996-g5047e62
partlist.c File Reference
#include "diskpart.h"
#include "guid.h"
#include <ntddscsi.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 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 18 of file partlist.c.

◆ MBR_MAGIC

#define MBR_MAGIC   0xAA55

Definition at line 41 of file partlist.c.

◆ NDEBUG

#define NDEBUG

Definition at line 15 of file partlist.c.

◆ PARTITION_LINUX

#define PARTITION_LINUX   0x83

Definition at line 37 of file partlist.c.

◆ PARTITION_TBL_SIZE

#define PARTITION_TBL_SIZE   4

Definition at line 39 of file partlist.c.

◆ ROOT_NAME

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

Definition at line 359 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 1129 of file partlist.c.

1132{
1133 DISK_GEOMETRY DiskGeometry;
1134 SCSI_ADDRESS ScsiAddress;
1135 PDISKENTRY DiskEntry;
1139 PULONG Buffer;
1141 WCHAR Identifier[20];
1142 ULONG Checksum;
1144 ULONG i;
1145 PLIST_ENTRY ListEntry;
1146 PBIOSDISKENTRY BiosDiskEntry;
1147
1149 NULL,
1150 NULL,
1151 NULL,
1152 &Iosb,
1154 NULL,
1155 0,
1156 &DiskGeometry,
1157 sizeof(DISK_GEOMETRY));
1158 if (!NT_SUCCESS(Status))
1159 {
1160 return;
1161 }
1162
1163 if (DiskGeometry.MediaType != FixedMedia &&
1164 DiskGeometry.MediaType != RemovableMedia)
1165 {
1166 return;
1167 }
1168
1170 NULL,
1171 NULL,
1172 NULL,
1173 &Iosb,
1175 NULL,
1176 0,
1177 &ScsiAddress,
1178 sizeof(SCSI_ADDRESS));
1179 if (!NT_SUCCESS(Status))
1180 {
1181 return;
1182 }
1183
1184 Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(RtlGetProcessHeap(),
1185 0,
1186 DiskGeometry.BytesPerSector);
1187 if (Mbr == NULL)
1188 {
1189 return;
1190 }
1191
1192 FileOffset.QuadPart = 0;
1194 NULL,
1195 NULL,
1196 NULL,
1197 &Iosb,
1198 (PVOID)Mbr,
1199 DiskGeometry.BytesPerSector,
1200 &FileOffset,
1201 NULL);
1202 if (!NT_SUCCESS(Status))
1203 {
1204 RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr);
1205 DPRINT1("NtReadFile failed, status=%x\n", Status);
1206 return;
1207 }
1208 Signature = Mbr->Signature;
1209
1210 /* Calculate the MBR checksum */
1211 Checksum = 0;
1212 Buffer = (PULONG)Mbr;
1213 for (i = 0; i < 128; i++)
1214 {
1215 Checksum += Buffer[i];
1216 }
1217 Checksum = ~Checksum + 1;
1218
1220 L"%08x-%08x-A", Checksum, Signature);
1221 DPRINT("Identifier: %S\n", Identifier);
1222
1223 DiskEntry = RtlAllocateHeap(RtlGetProcessHeap(),
1225 sizeof(DISKENTRY));
1226 if (DiskEntry == NULL)
1227 {
1228 return;
1229 }
1230
1231// DiskEntry->Checksum = Checksum;
1232// DiskEntry->Signature = Signature;
1233 DiskEntry->BiosFound = FALSE;
1234
1235 /* Check the disk partition style */
1236 if (Mbr->Magic != MBR_MAGIC)
1237 {
1238 DPRINT("Partition style: RAW\n");
1239 DiskEntry->PartitionStyle = PARTITION_STYLE_RAW;
1240 }
1241 else
1242 {
1243 if (Mbr->Partition[0].PartitionType == PARTITION_GPT)
1244 {
1245 DPRINT("Partition style: GPT\n");
1247 }
1248 else
1249 {
1250 DPRINT("Partition style: MBR\n");
1252 }
1253 }
1254
1255 /* Free Mbr sector buffer */
1256 RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr);
1257
1258 ListEntry = BiosDiskListHead.Flink;
1259 while (ListEntry != &BiosDiskListHead)
1260 {
1261 BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
1262 /* FIXME:
1263 * Compare the size from bios and the reported size from driver.
1264 * If we have more than one disk with a zero or with the same signatur
1265 * we must create new signatures and reboot. After the reboot,
1266 * it is possible to identify the disks.
1267 */
1268 if (BiosDiskEntry->Signature == Signature &&
1269 BiosDiskEntry->Checksum == Checksum &&
1270 !BiosDiskEntry->Recognized)
1271 {
1272 if (!DiskEntry->BiosFound)
1273 {
1274 DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber;
1275 DiskEntry->BiosFound = TRUE;
1276 BiosDiskEntry->Recognized = TRUE;
1277 }
1278 else
1279 {
1280 }
1281 }
1282 ListEntry = ListEntry->Flink;
1283 }
1284
1285 if (!DiskEntry->BiosFound)
1286 {
1287#if 0
1288 RtlFreeHeap(ProcessHeap, 0, DiskEntry);
1289 return;
1290#else
1291 DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %d is not be bootable by the BIOS!\n", DiskNumber);
1292#endif
1293 }
1294
1297
1298 DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
1299 DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
1300 DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
1301 DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
1302
1303 DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders);
1304 DPRINT("TracksPerCylinder %I64u\n", DiskEntry->TracksPerCylinder);
1305 DPRINT("SectorsPerTrack %I64u\n", DiskEntry->SectorsPerTrack);
1306 DPRINT("BytesPerSector %I64u\n", DiskEntry->BytesPerSector);
1307
1308 DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart *
1309 (ULONGLONG)DiskGeometry.TracksPerCylinder *
1310 (ULONGLONG)DiskGeometry.SectorsPerTrack;
1311
1312// DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
1313// DiskEntry->CylinderAlignment = DiskGeometry.SectorsPerTrack * DiskGeometry.TracksPerCylinder;
1314 DiskEntry->SectorAlignment = (1024 * 1024) / DiskGeometry.BytesPerSector;
1315 DiskEntry->CylinderAlignment = (1024 * 1024) / DiskGeometry.BytesPerSector;
1316
1317 DPRINT1("SectorCount: %I64u\n", DiskEntry->SectorCount);
1318 DPRINT1("SectorAlignment: %lu\n", DiskEntry->SectorAlignment);
1319 DPRINT1("CylinderAlignment: %lu\n", DiskEntry->CylinderAlignment);
1320
1321 DiskEntry->DiskNumber = DiskNumber;
1322 DiskEntry->Port = ScsiAddress.PortNumber;
1323 DiskEntry->PathId = ScsiAddress.PathId;
1324 DiskEntry->TargetId = ScsiAddress.TargetId;
1325 DiskEntry->Lun = ScsiAddress.Lun;
1326
1327 GetDriverName(DiskEntry);
1328
1329 InsertAscendingList(&DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber);
1330
1331 ReadLayoutBuffer(FileHandle, DiskEntry);
1332
1333 DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount);
1334
1335#ifdef DUMP_PARTITION_TABLE
1336 DumpPartitionTable(DiskEntry);
1337#endif
1338
1339 if (DiskEntry->PartitionStyle == PARTITION_STYLE_MBR)
1340 {
1341 if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
1343 DiskEntry->LayoutBuffer->PartitionEntry[0].Mbr.PartitionType != 0)
1344 {
1345 if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
1346 {
1347 DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
1348 }
1349 else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
1350 {
1351 DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1352 }
1353 else
1354 {
1355 DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
1356 }
1357 }
1358 else
1359 {
1360 DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1361 }
1362
1363 /* Calculate the number of usable sectors */
1364 /* Limit the number of usable sectors to 2^32 */
1365 DiskEntry->StartSector.QuadPart = (ULONGLONG)DiskEntry->SectorAlignment;
1366 DiskEntry->EndSector.QuadPart = min(DiskEntry->SectorCount.QuadPart, 0x100000000) - 1;
1367
1368 if (DiskEntry->LayoutBuffer->PartitionCount == 0)
1369 {
1370 DiskEntry->NewDisk = TRUE;
1371 DiskEntry->LayoutBuffer->PartitionCount = 4;
1372
1373 for (i = 0; i < 4; i++)
1375 }
1376 else
1377 {
1378 for (i = 0; i < 4; i++)
1379 {
1380 AddMbrPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
1381 }
1382
1383 for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
1384 {
1385 AddMbrPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
1386 }
1387 }
1388
1390 }
1391 else if (DiskEntry->PartitionStyle == PARTITION_STYLE_GPT)
1392 {
1393 /* Calculate the number of usable sectors */
1394 DiskEntry->StartSector.QuadPart = AlignDown(DiskEntry->LayoutBuffer->Gpt.StartingUsableOffset.QuadPart / DiskEntry->BytesPerSector,
1395 DiskEntry->SectorAlignment) + (ULONGLONG)DiskEntry->SectorAlignment;
1396 DiskEntry->EndSector.QuadPart = AlignDown(DiskEntry->StartSector.QuadPart + (DiskEntry->LayoutBuffer->Gpt.UsableLength.QuadPart / DiskEntry->BytesPerSector) - 1,
1397 DiskEntry->SectorAlignment);
1398
1399 if (DiskEntry->LayoutBuffer->PartitionCount == 0)
1400 {
1401 DiskEntry->NewDisk = TRUE;
1402 }
1403 else
1404 {
1405 for (i = 0; i < DiskEntry->LayoutBuffer->PartitionCount; i++)
1406 {
1407 AddGptPartitionToDisk(DiskNumber, DiskEntry, i);
1408 }
1409 }
1410
1412 }
1413}
@ 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 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
#define IOCTL_SCSI_GET_ADDRESS
Definition: scsi_port.h:52
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:165
ULONG DiskNumber
Definition: partlist.h:162
ULONG Checksum
Definition: partlist.h:164
ULONG Signature
Definition: partlist.h:163
ULARGE_INTEGER EndSector
Definition: diskpart.h:185
ULONG SectorAlignment
Definition: partlist.h:116
ULONG BiosDiskNumber
Definition: diskpart.h:188
ULARGE_INTEGER SectorCount
Definition: partlist.h:115
ULONG SectorsPerTrack
Definition: partlist.h:112
USHORT TargetId
Definition: diskpart.h:195
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:194
BOOLEAN BiosFound
Definition: partlist.h:120
ULONGLONG Cylinders
Definition: partlist.h:110
USHORT Lun
Definition: diskpart.h:196
ULARGE_INTEGER StartSector
Definition: diskpart.h:184
USHORT Port
Definition: partlist.h:131
DWORD PartitionStyle
Definition: diskpart.h:202
ULONG TracksPerCylinder
Definition: partlist.h:111
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:149
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
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
ULONGLONG AlignDown(_In_ ULONGLONG Value, _In_ ULONG Alignment)
Definition: partlist.c:191
static VOID AddGptPartitionToDisk(ULONG DiskNumber, PDISKENTRY DiskEntry, ULONG PartitionIndex)
Definition: partlist.c:618
LIST_ENTRY BiosDiskListHead
Definition: partlist.c:74
static VOID AddMbrPartitionToDisk(ULONG DiskNumber, PDISKENTRY DiskEntry, ULONG PartitionIndex, BOOLEAN LogicalPartition)
Definition: partlist.c:508
VOID ReadLayoutBuffer(_In_ HANDLE FileHandle, _In_ PDISKENTRY DiskEntry)
Definition: partlist.c:1067
LIST_ENTRY DiskListHead
Definition: partlist.c:73
VOID ScanForUnpartitionedMbrDiskSpace(PDISKENTRY DiskEntry)
Definition: partlist.c:662
VOID ScanForUnpartitionedGptDiskSpace(PDISKENTRY DiskEntry)
Definition: partlist.c:923
#define MBR_MAGIC
Definition: partlist.c:41
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
LONGLONG QuadPart
Definition: typedefs.h:114
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ AddGptPartitionToDisk()

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

Definition at line 618 of file partlist.c.

622{
624 PPARTENTRY PartEntry;
625
626 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
627 if (IsEqualGUID(&PartitionInfo->Gpt.PartitionType, &PARTITION_ENTRY_UNUSED_GUID))
628 return;
629
630 PartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
632 sizeof(PARTENTRY));
633 if (PartEntry == NULL)
634 {
635 /* TODO: Error message */
636 return;
637 }
638
639 PartEntry->DiskEntry = DiskEntry;
640
641 PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
642 PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
643
644 CopyMemory(&PartEntry->Gpt.PartitionType, &PartitionInfo->Gpt.PartitionType, sizeof(GUID));
645 CopyMemory(&PartEntry->Gpt.PartitionId, &PartitionInfo->Gpt.PartitionId, sizeof(GUID));
646 PartEntry->Gpt.Attributes = PartitionInfo->Gpt.Attributes;
647
648 PartEntry->LogicalPartition = FALSE;
649 PartEntry->IsPartitioned = TRUE;
650 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
651 PartEntry->PartitionIndex = PartitionIndex;
652
653 /* TODO: Determine the format state */
654 PartEntry->FormatState = Unformatted;
655
657 &PartEntry->ListEntry);
658}
#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:114
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:139
GPT_PARTITION_DATA Gpt
Definition: diskpart.h:129
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 508 of file partlist.c.

513{
515 PPARTENTRY PartEntry;
516
517 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
518 if (PartitionInfo->Mbr.PartitionType == 0 ||
519 (LogicalPartition == TRUE && IsContainerPartition(PartitionInfo->Mbr.PartitionType)))
520 return;
521
522 PartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
524 sizeof(PARTENTRY));
525 if (PartEntry == NULL)
526 {
527 /* TODO: Error message */
528 return;
529 }
530
531 PartEntry->DiskEntry = DiskEntry;
532
533 PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
534 PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
535
536 PartEntry->Mbr.BootIndicator = PartitionInfo->Mbr.BootIndicator;
537 PartEntry->Mbr.PartitionType = PartitionInfo->Mbr.PartitionType;
538
540 PartEntry->IsPartitioned = TRUE;
541 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
542 PartEntry->PartitionIndex = PartitionIndex;
543
544 if (IsContainerPartition(PartEntry->Mbr.PartitionType))
545 {
546 PartEntry->FormatState = Unformatted;
547
548 if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
549 DiskEntry->ExtendedPartition = PartEntry;
550 }
551 else if ((PartEntry->Mbr.PartitionType == PARTITION_FAT_12) ||
552 (PartEntry->Mbr.PartitionType == PARTITION_FAT_16) ||
553 (PartEntry->Mbr.PartitionType == PARTITION_HUGE) ||
554 (PartEntry->Mbr.PartitionType == PARTITION_XINT13) ||
555 (PartEntry->Mbr.PartitionType == PARTITION_FAT32) ||
557 {
558#if 0
559 if (CheckFatFormat())
560 {
561 PartEntry->FormatState = Preformatted;
562 }
563 else
564 {
565 PartEntry->FormatState = Unformatted;
566 }
567#endif
568 PartEntry->FormatState = Preformatted;
569 }
570 else if (PartEntry->Mbr.PartitionType == PARTITION_LINUX)
571 {
572#if 0
573 if (CheckExt2Format())
574 {
575 PartEntry->FormatState = Preformatted;
576 }
577 else
578 {
579 PartEntry->FormatState = Unformatted;
580 }
581#endif
582 PartEntry->FormatState = Preformatted;
583 }
584 else if (PartEntry->Mbr.PartitionType == PARTITION_IFS)
585 {
586#if 0
587 if (CheckNtfsFormat())
588 {
589 PartEntry->FormatState = Preformatted;
590 }
591 else if (CheckHpfsFormat())
592 {
593 PartEntry->FormatState = Preformatted;
594 }
595 else
596 {
597 PartEntry->FormatState = Unformatted;
598 }
599#endif
600 PartEntry->FormatState = Preformatted;
601 }
602 else
603 {
604 PartEntry->FormatState = UnknownFormat;
605 }
606
609 &PartEntry->ListEntry);
610 else
612 &PartEntry->ListEntry);
613}
#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:92
@ 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:106
MBR_PARTITION_DATA Mbr
Definition: diskpart.h:128
#define PARTITION_LINUX
Definition: partlist.c:37

Referenced by AddDiskToList().

◆ AddVolumeToList()

static VOID AddVolumeToList ( ULONG  ulVolumeNumber,
PWSTR  pszVolumeName 
)
static

Definition at line 1656 of file partlist.c.

1659{
1660 PVOLENTRY VolumeEntry;
1662
1663 DWORD dwError, dwLength;
1664 WCHAR szPathNames[MAX_PATH + 1];
1665 WCHAR szVolumeName[MAX_PATH + 1];
1666 WCHAR szFilesystem[MAX_PATH + 1];
1667
1668 DWORD CharCount = 0;
1669 size_t Index = 0;
1670
1675
1676 DPRINT("AddVolumeToList(%S)\n", pszVolumeName);
1677
1678 VolumeEntry = RtlAllocateHeap(RtlGetProcessHeap(),
1680 sizeof(VOLENTRY));
1681 if (VolumeEntry == NULL)
1682 return;
1683
1684 VolumeEntry->VolumeNumber = ulVolumeNumber;
1685 wcscpy(VolumeEntry->VolumeName, pszVolumeName);
1686
1687 Index = wcslen(pszVolumeName) - 1;
1688
1689 pszVolumeName[Index] = L'\0';
1690
1691 CharCount = QueryDosDeviceW(&pszVolumeName[4], VolumeEntry->DeviceName, ARRAYSIZE(VolumeEntry->DeviceName));
1692
1693 pszVolumeName[Index] = L'\\';
1694
1695 if (CharCount == 0)
1696 {
1697 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry);
1698 return;
1699 }
1700
1701 DPRINT("DeviceName: %S\n", VolumeEntry->DeviceName);
1702
1703 RtlInitUnicodeString(&Name, VolumeEntry->DeviceName);
1704
1706 &Name,
1707 0,
1708 NULL,
1709 NULL);
1710
1714 &Iosb,
1715 0,
1717 if (NT_SUCCESS(Status))
1718 {
1719 GetVolumeType(VolumeHandle, VolumeEntry);
1720 GetVolumeExtents(VolumeHandle, VolumeEntry);
1722 }
1723
1724 if (GetVolumeInformationW(pszVolumeName,
1725 szVolumeName,
1726 MAX_PATH + 1,
1727 NULL, // [out, optional] LPDWORD lpVolumeSerialNumber,
1728 NULL, // [out, optional] LPDWORD lpMaximumComponentLength,
1729 NULL, // [out, optional] LPDWORD lpFileSystemFlags,
1730 szFilesystem,
1731 MAX_PATH + 1))
1732 {
1733 VolumeEntry->pszLabel = RtlAllocateHeap(RtlGetProcessHeap(),
1734 0,
1735 (wcslen(szVolumeName) + 1) * sizeof(WCHAR));
1736 if (VolumeEntry->pszLabel)
1737 wcscpy(VolumeEntry->pszLabel, szVolumeName);
1738
1739 VolumeEntry->pszFilesystem = RtlAllocateHeap(RtlGetProcessHeap(),
1740 0,
1741 (wcslen(szFilesystem) + 1) * sizeof(WCHAR));
1742 if (VolumeEntry->pszFilesystem)
1743 wcscpy(VolumeEntry->pszFilesystem, szFilesystem);
1744 }
1745 else
1746 {
1747 dwError = GetLastError();
1748 if (dwError == ERROR_UNRECOGNIZED_VOLUME)
1749 {
1750 VolumeEntry->pszFilesystem = RtlAllocateHeap(RtlGetProcessHeap(),
1751 0,
1752 (3 + 1) * sizeof(WCHAR));
1753 if (VolumeEntry->pszFilesystem)
1754 wcscpy(VolumeEntry->pszFilesystem, L"RAW");
1755 }
1756 }
1757
1758 if (GetVolumePathNamesForVolumeNameW(pszVolumeName,
1759 szPathNames,
1760 ARRAYSIZE(szPathNames),
1761 &dwLength))
1762 {
1763 VolumeEntry->DriveLetter = szPathNames[0];
1764 }
1765
1767 &VolumeEntry->ListEntry);
1768}
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
wcscpy
LPWSTR Name
Definition: desk.c:124
#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
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
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#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
ULONG VolumeNumber
Definition: diskpart.h:219
PWSTR pszFilesystem
Definition: diskpart.h:226
WCHAR VolumeName[MAX_PATH]
Definition: diskpart.h:220
LIST_ENTRY ListEntry
Entry in VolumesList.
Definition: partlist.h:45
PWSTR pszLabel
Definition: diskpart.h:225
WCHAR DeviceName[MAX_PATH]
Definition: diskpart.h:221
WCHAR DriveLetter
Definition: diskpart.h:223
LIST_ENTRY VolumeListHead
Definition: partlist.c:75
static VOID GetVolumeType(_In_ HANDLE VolumeHandle, _In_ PVOLENTRY VolumeEntry)
Definition: partlist.c:1616
static VOID GetVolumeExtents(_In_ HANDLE VolumeHandle, _In_ PVOLENTRY VolumeEntry)
Definition: partlist.c:1550
_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 191 of file partlist.c.

194{
195 ULONGLONG Temp;
196
197 Temp = Value / Alignment;
198
199 return Temp * Alignment;
200}
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 1417 of file partlist.c.

1418{
1422 ULONG ReturnSize;
1424 ULONG DiskNumber;
1428
1429 CurrentDisk = NULL;
1431
1432// BootDisk = NULL;
1433// BootPartition = NULL;
1434
1435// TempDisk = NULL;
1436// TempPartition = NULL;
1437// FormatState = Start;
1438
1441
1443
1445 &Sdi,
1447 &ReturnSize);
1448 if (!NT_SUCCESS(Status))
1449 {
1450 return Status;
1451 }
1452
1453 for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
1454 {
1456 L"\\Device\\Harddisk%d\\Partition0",
1457 DiskNumber);
1458
1460 Buffer);
1461
1463 &Name,
1464 0,
1465 NULL,
1466 NULL);
1467
1471 &Iosb,
1474 if (NT_SUCCESS(Status))
1475 {
1476 AddDiskToList(FileHandle, DiskNumber);
1477
1479 }
1480 }
1481
1482// UpdateDiskSignatures(List);
1483
1484// AssignDriveLetters(List);
1485
1486 return STATUS_SUCCESS;
1487}
PDISKENTRY CurrentDisk
Definition: partlist.c:77
#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:78

◆ CreateVolumeList()

NTSTATUS CreateVolumeList ( VOID  )

Definition at line 1772 of file partlist.c.

1773{
1774 HANDLE hVolume = INVALID_HANDLE_VALUE;
1775 WCHAR szVolumeName[MAX_PATH];
1776 ULONG ulVolumeNumber = 0;
1777 BOOL Success;
1778
1780
1782
1783 hVolume = FindFirstVolumeW(szVolumeName, ARRAYSIZE(szVolumeName));
1784 if (hVolume == INVALID_HANDLE_VALUE)
1785 {
1786
1787 return STATUS_UNSUCCESSFUL;
1788 }
1789
1790 AddVolumeToList(ulVolumeNumber++, szVolumeName);
1791
1792 for (;;)
1793 {
1794 Success = FindNextVolumeW(hVolume, szVolumeName, ARRAYSIZE(szVolumeName));
1795 if (!Success)
1796 {
1797 break;
1798 }
1799
1800 AddVolumeToList(ulVolumeNumber++, szVolumeName);
1801 }
1802
1803 FindVolumeClose(hVolume);
1804
1805 return STATUS_SUCCESS;
1806}
#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:1656
PVOLENTRY CurrentVolume
Definition: partlist.c:79
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

Referenced by rescan_main(), and wmain().

◆ DestroyPartitionList()

VOID DestroyPartitionList ( VOID  )

Definition at line 1491 of file partlist.c.

1492{
1493 PDISKENTRY DiskEntry;
1494 PBIOSDISKENTRY BiosDiskEntry;
1495 PPARTENTRY PartEntry;
1497
1498 CurrentDisk = NULL;
1500
1501 /* Release disk and partition info */
1502 while (!IsListEmpty(&DiskListHead))
1503 {
1505 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
1506
1507 /* Release driver name */
1508 RtlFreeUnicodeString(&DiskEntry->DriverName);
1509
1510 /* Release primary partition list */
1511 while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
1512 {
1514 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1515
1516 RtlFreeHeap(RtlGetProcessHeap(), 0, PartEntry);
1517 }
1518
1519 /* Release logical partition list */
1520 while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
1521 {
1523 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1524
1525 RtlFreeHeap(RtlGetProcessHeap(), 0, PartEntry);
1526 }
1527
1528 /* Release layout buffer */
1529 if (DiskEntry->LayoutBuffer != NULL)
1530 RtlFreeHeap(RtlGetProcessHeap(), 0, DiskEntry->LayoutBuffer);
1531
1532
1533 /* Release disk entry */
1534 RtlFreeHeap(RtlGetProcessHeap(), 0, DiskEntry);
1535 }
1536
1537 /* Release the bios disk info */
1538 while (!IsListEmpty(&BiosDiskListHead))
1539 {
1541 BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
1542
1543 RtlFreeHeap(RtlGetProcessHeap(), 0, BiosDiskEntry);
1544 }
1545}
#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

◆ DestroyVolumeList()

VOID DestroyVolumeList ( VOID  )

Definition at line 1810 of file partlist.c.

1811{
1813 PVOLENTRY VolumeEntry;
1814
1816
1817 /* Release disk and partition info */
1818 while (!IsListEmpty(&VolumeListHead))
1819 {
1821 VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
1822
1823 if (VolumeEntry->pszLabel)
1824 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszLabel);
1825
1826 if (VolumeEntry->pszFilesystem)
1827 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszFilesystem);
1828
1829 if (VolumeEntry->pExtents)
1830 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pExtents);
1831
1832 /* Release disk entry */
1833 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry);
1834 }
1835}
PVOLUME_DISK_EXTENTS pExtents
Definition: diskpart.h:230

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

276{
277 PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
278 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
280 ULONG i;
281
284 return STATUS_UNSUCCESSFUL;
285
286 FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
287
288 /* Hm. Version and Revision are not set on Microsoft Windows XP... */
289#if 0
290 if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
291 FullResourceDescriptor->PartialResourceList.Revision != 1)
292 return STATUS_UNSUCCESSFUL;
293#endif
294
295 for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
296 {
299 continue;
300
301 DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1];
302 BiosDiskEntry->DiskGeometry = *DiskGeometry;
303
304 return STATUS_SUCCESS;
305 }
306
307 return STATUS_UNSUCCESSFUL;
308}
_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 239 of file partlist.c.

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

2494{
2496 NTSTATUS LockStatus;
2500 HANDLE PartitionHandle;
2502
2503 /* Check whether the partition is valid and was mounted by the system */
2504 if (!PartEntry->IsPartitioned ||
2505 IsContainerPartition(PartEntry->Mbr.PartitionType) ||
2506 !IsRecognizedPartition(PartEntry->Mbr.PartitionType) ||
2507 PartEntry->FormatState == UnknownFormat ||
2508 // NOTE: If FormatState == Unformatted but *FileSystem != 0 this means
2509 // it has been usually mounted with RawFS and thus needs to be dismounted.
2510/* !*PartEntry->FileSystem || */
2511 PartEntry->PartitionNumber == 0)
2512 {
2513 /* The partition is not mounted, so just return success */
2514 return STATUS_SUCCESS;
2515 }
2516
2517 ASSERT(PartEntry->Mbr.PartitionType != PARTITION_ENTRY_UNUSED);
2518
2519 /* Open the volume */
2521 L"\\Device\\Harddisk%lu\\Partition%lu",
2522 PartEntry->DiskEntry->DiskNumber,
2523 PartEntry->PartitionNumber);
2525
2527 &Name,
2529 NULL,
2530 NULL);
2531
2532 Status = NtOpenFile(&PartitionHandle,
2538 if (!NT_SUCCESS(Status))
2539 {
2540 DPRINT1("ERROR: Cannot open volume %wZ for dismounting! (Status 0x%lx)\n", &Name, Status);
2541 return Status;
2542 }
2543
2544 /* Lock the volume */
2545 LockStatus = NtFsControlFile(PartitionHandle,
2546 NULL,
2547 NULL,
2548 NULL,
2551 NULL,
2552 0,
2553 NULL,
2554 0);
2555 if (!NT_SUCCESS(LockStatus))
2556 {
2557 DPRINT1("WARNING: Failed to lock volume! Operations may fail! (Status 0x%lx)\n", LockStatus);
2558 }
2559
2560 /* Dismount the volume */
2561 Status = NtFsControlFile(PartitionHandle,
2562 NULL,
2563 NULL,
2564 NULL,
2567 NULL,
2568 0,
2569 NULL,
2570 0);
2571 if (!NT_SUCCESS(Status))
2572 {
2573 DPRINT1("Failed to unmount volume (Status 0x%lx)\n", Status);
2574 }
2575
2576 /* Unlock the volume */
2577 LockStatus = NtFsControlFile(PartitionHandle,
2578 NULL,
2579 NULL,
2580 NULL,
2583 NULL,
2584 0,
2585 NULL,
2586 0);
2587 if (!NT_SUCCESS(LockStatus))
2588 {
2589 DPRINT1("Failed to unlock volume (Status 0x%lx)\n", LockStatus);
2590 }
2591
2592 /* Close the volume */
2593 NtClose(PartitionHandle);
2594
2595 return Status;
2596}
#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 363 of file partlist.c.

364{
366 WCHAR Name[120];
367 ULONG AdapterCount;
368 ULONG DiskCount;
370 PCM_INT13_DRIVE_PARAMETER Int13Drives;
371 PBIOSDISKENTRY BiosDiskEntry;
372
373 memset(QueryTable, 0, sizeof(QueryTable));
374
375 QueryTable[1].Name = L"Configuration Data";
377 Int13Drives = NULL;
379 L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
380 &QueryTable[1],
381 (PVOID)&Int13Drives,
382 NULL);
383 if (!NT_SUCCESS(Status))
384 {
385 DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status);
386 return;
387 }
388
389 AdapterCount = 0;
390 while (1)
391 {
393 L"%s\\%lu", ROOT_NAME, AdapterCount);
395 Name,
396 &QueryTable[2],
397 NULL,
398 NULL);
399 if (!NT_SUCCESS(Status))
400 {
401 break;
402 }
403
405 L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount);
407 Name,
408 &QueryTable[2],
409 NULL,
410 NULL);
411 if (NT_SUCCESS(Status))
412 {
413 while (1)
414 {
416 L"%s\\%lu\\DiskController\\0", ROOT_NAME, AdapterCount);
418 Name,
419 &QueryTable[2],
420 NULL,
421 NULL);
422 if (!NT_SUCCESS(Status))
423 {
424 RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
425 return;
426 }
427
429 L"%s\\%lu\\DiskController\\0\\DiskPeripheral", ROOT_NAME, AdapterCount);
431 Name,
432 &QueryTable[2],
433 NULL,
434 NULL);
435 if (NT_SUCCESS(Status))
436 {
437 QueryTable[0].Name = L"Identifier";
439 QueryTable[1].Name = L"Configuration Data";
441
442 DiskCount = 0;
443 while (1)
444 {
445 BiosDiskEntry = (BIOSDISKENTRY*)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY));
446 if (BiosDiskEntry == NULL)
447 {
448 break;
449 }
450
452 L"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, DiskCount);
454 Name,
456 (PVOID)BiosDiskEntry,
457 NULL);
458 if (!NT_SUCCESS(Status))
459 {
460 RtlFreeHeap(RtlGetProcessHeap(), 0, BiosDiskEntry);
461 break;
462 }
463
464 BiosDiskEntry->DiskNumber = DiskCount;
465 BiosDiskEntry->Recognized = FALSE;
466
467 if (DiskCount < Int13Drives[0].NumberDrives)
468 {
469 BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount];
470 }
471 else
472 {
473 DPRINT1("Didn't find int13 drive datas for disk %u\n", DiskCount);
474 }
475
476 InsertTailList(&BiosDiskListHead, &BiosDiskEntry->ListEntry);
477
478 DPRINT("DiskNumber: %lu\n", BiosDiskEntry->DiskNumber);
479 DPRINT("Signature: %08lx\n", BiosDiskEntry->Signature);
480 DPRINT("Checksum: %08lx\n", BiosDiskEntry->Checksum);
481 DPRINT("BytesPerSector: %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector);
482 DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders);
483 DPRINT("NumberOfHeads: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads);
484 DPRINT("DriveSelect: %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect);
485 DPRINT("MaxCylinders: %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders);
486 DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack);
487 DPRINT("MaxHeads: %d\n", BiosDiskEntry->Int13DiskData.MaxHeads);
488 DPRINT("NumberDrives: %d\n", BiosDiskEntry->Int13DiskData.NumberDrives);
489
490 DiskCount++;
491 }
492 }
493
494 RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
495 return;
496 }
497 }
498
499 AdapterCount++;
500 }
501
502 RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
503}
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 204 of file partlist.c.

206{
208 WCHAR KeyName[32];
210
212 NULL);
213
215 L"\\Scsi\\Scsi Port %lu",
216 DiskEntry->Port);
217
219 sizeof(QueryTable));
220
221 QueryTable[0].Name = L"Driver";
223 QueryTable[0].EntryContext = &DiskEntry->DriverName;
224
226 KeyName,
228 NULL,
229 NULL);
230 if (!NT_SUCCESS(Status))
231 {
232 DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
233 }
234}
#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 2093 of file partlist.c.

2095{
2096 PLIST_ENTRY ListEntry;
2097 PPARTENTRY PartEntry;
2098 ULONG Count = 0;
2099
2100 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
2101 ListEntry != &DiskEntry->LogicalPartListHead;
2102 ListEntry = ListEntry->Flink)
2103 {
2104 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
2105 if (PartEntry->IsPartitioned)
2106 Count++;
2107 }
2108
2109 return Count;
2110}
int Count
Definition: noreturn.cpp:7

◆ GetNextUnpartitionedEntry()

PPARTENTRY GetNextUnpartitionedEntry ( _In_ PPARTENTRY  PartEntry)

Definition at line 2463 of file partlist.c.

2465{
2466 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2467 PPARTENTRY NextPartEntry;
2468 PLIST_ENTRY ListHead;
2469
2470 if (PartEntry->LogicalPartition)
2471 ListHead = &DiskEntry->LogicalPartListHead;
2472 else
2473 ListHead = &DiskEntry->PrimaryPartListHead;
2474
2475 if (PartEntry->ListEntry.Flink != ListHead)
2476 {
2477 NextPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Flink,
2478 PARTENTRY,
2479 ListEntry);
2480 if (!NextPartEntry->IsPartitioned)
2481 {
2483 return NextPartEntry;
2484 }
2485 }
2486
2487 return NULL;
2488}

Referenced by DeleteGptPartition(), and DeleteMbrPartition().

◆ GetPrevUnpartitionedEntry()

PPARTENTRY GetPrevUnpartitionedEntry ( _In_ PPARTENTRY  PartEntry)

Definition at line 2434 of file partlist.c.

2436{
2437 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2438 PPARTENTRY PrevPartEntry;
2439 PLIST_ENTRY ListHead;
2440
2441 if (PartEntry->LogicalPartition)
2442 ListHead = &DiskEntry->LogicalPartListHead;
2443 else
2444 ListHead = &DiskEntry->PrimaryPartListHead;
2445
2446 if (PartEntry->ListEntry.Blink != ListHead)
2447 {
2448 PrevPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Blink,
2449 PARTENTRY,
2450 ListEntry);
2451 if (!PrevPartEntry->IsPartitioned)
2452 {
2454 return PrevPartEntry;
2455 }
2456 }
2457
2458 return NULL;
2459}

Referenced by DeleteGptPartition(), and DeleteMbrPartition().

◆ GetPrimaryPartitionCount()

ULONG GetPrimaryPartitionCount ( _In_ PDISKENTRY  DiskEntry)

Definition at line 2071 of file partlist.c.

2073{
2075 PPARTENTRY PartEntry;
2076 ULONG Count = 0;
2077
2078 for (Entry = DiskEntry->PrimaryPartListHead.Flink;
2079 Entry != &DiskEntry->PrimaryPartListHead;
2080 Entry = Entry->Flink)
2081 {
2082 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2083 if (PartEntry->IsPartitioned)
2084 Count++;
2085 }
2086
2087 return Count;
2088}

◆ GetVolumeExtents()

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

Definition at line 1550 of file partlist.c.

1553{
1554 DWORD dwBytesReturned = 0, dwLength, i;
1555 PVOLUME_DISK_EXTENTS pExtents;
1556 BOOL bResult;
1557 DWORD dwError;
1558
1559 dwLength = sizeof(VOLUME_DISK_EXTENTS);
1560 pExtents = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
1561 if (pExtents == NULL)
1562 return;
1563
1564 bResult = DeviceIoControl(VolumeHandle,
1566 NULL,
1567 0,
1568 pExtents,
1569 dwLength,
1570 &dwBytesReturned,
1571 NULL);
1572 if (!bResult)
1573 {
1574 dwError = GetLastError();
1575
1576 if (dwError != ERROR_MORE_DATA)
1577 {
1578 RtlFreeHeap(RtlGetProcessHeap(), 0, pExtents);
1579 return;
1580 }
1581 else
1582 {
1583 dwLength = sizeof(VOLUME_DISK_EXTENTS) + ((pExtents->NumberOfDiskExtents - 1) * sizeof(DISK_EXTENT));
1584 RtlFreeHeap(RtlGetProcessHeap(), 0, pExtents);
1585 pExtents = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
1586 if (pExtents == NULL)
1587 {
1588 return;
1589 }
1590
1591 bResult = DeviceIoControl(VolumeHandle,
1593 NULL,
1594 0,
1595 pExtents,
1596 dwLength,
1597 &dwBytesReturned,
1598 NULL);
1599 if (!bResult)
1600 {
1601 RtlFreeHeap(RtlGetProcessHeap(), 0, pExtents);
1602 return;
1603 }
1604 }
1605 }
1606
1607 for (i = 0; i < pExtents->NumberOfDiskExtents; i++)
1608 VolumeEntry->Size.QuadPart += pExtents->Extents[i].ExtentLength.QuadPart;
1609
1610 VolumeEntry->pExtents = pExtents;
1611}
#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 2600 of file partlist.c.

2602{
2604 PVOLENTRY VolumeEntry;
2605 ULONG i;
2606
2607 if ((PartEntry == NULL) ||
2608 (PartEntry->DiskEntry == NULL))
2609 return NULL;
2610
2612 while (Entry != &VolumeListHead)
2613 {
2614 VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
2615
2616 if (VolumeEntry->pExtents == NULL)
2617 return NULL;
2618
2619 for (i = 0; i < VolumeEntry->pExtents->NumberOfDiskExtents; i++)
2620 {
2621 if (VolumeEntry->pExtents->Extents[i].DiskNumber == PartEntry->DiskEntry->DiskNumber)
2622 {
2623 if ((VolumeEntry->pExtents->Extents[i].StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * PartEntry->DiskEntry->BytesPerSector) &&
2624 (VolumeEntry->pExtents->Extents[i].ExtentLength.QuadPart == PartEntry->SectorCount.QuadPart * PartEntry->DiskEntry->BytesPerSector))
2625 return VolumeEntry;
2626 }
2627 }
2628
2629 Entry = Entry->Flink;
2630 }
2631
2632 return NULL;
2633}
ULONG DiskNumber
Definition: ntddvol.h:48
LARGE_INTEGER StartingOffset
Definition: ntddvol.h:49

Referenced by clean_main().

◆ GetVolumeType()

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

Definition at line 1616 of file partlist.c.

1619{
1623
1626 &DeviceInfo,
1629 if (!NT_SUCCESS(Status))
1630 return;
1631
1632 switch (DeviceInfo.DeviceType)
1633 {
1634 case FILE_DEVICE_CD_ROM:
1636 VolumeEntry->VolumeType = VOLUME_TYPE_CDROM;
1637 break;
1638
1639 case FILE_DEVICE_DISK:
1641 if (DeviceInfo.Characteristics & FILE_REMOVABLE_MEDIA)
1642 VolumeEntry->VolumeType = VOLUME_TYPE_REMOVABLE;
1643 else
1644 VolumeEntry->VolumeType = VOLUME_TYPE_PARTITION;
1645 break;
1646
1647 default:
1648 VolumeEntry->VolumeType = VOLUME_TYPE_UNKNOWN;
1649 break;
1650 }
1651}
@ VOLUME_TYPE_UNKNOWN
Definition: diskpart.h:101
@ VOLUME_TYPE_REMOVABLE
Definition: diskpart.h:100
@ VOLUME_TYPE_CDROM
Definition: diskpart.h:98
@ VOLUME_TYPE_PARTITION
Definition: diskpart.h:99
@ 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
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass)

Referenced by AddVolumeToList().

◆ IsEmptyLayoutEntry()

static BOOLEAN IsEmptyLayoutEntry ( IN PPARTITION_INFORMATION_EX  PartitionInfo)
static

Definition at line 2040 of file partlist.c.

2042{
2043 if (PartitionInfo->StartingOffset.QuadPart == 0 &&
2044 PartitionInfo->PartitionLength.QuadPart == 0)
2045 {
2046 return TRUE;
2047 }
2048
2049 return FALSE;
2050}

◆ IsSamePrimaryLayoutEntry()

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

Definition at line 2055 of file partlist.c.

2059{
2060 if ((PartitionInfo->StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector) &&
2061 (PartitionInfo->PartitionLength.QuadPart == PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector))
2062 {
2063 return TRUE;
2064 }
2065
2066 return FALSE;
2067}

◆ ReadLayoutBuffer()

VOID ReadLayoutBuffer ( _In_ HANDLE  FileHandle,
_In_ PDISKENTRY  DiskEntry 
)

Definition at line 1067 of file partlist.c.

1070{
1071 ULONG LayoutBufferSize;
1072 PDRIVE_LAYOUT_INFORMATION_EX NewLayoutBuffer;
1075
1076 /* Allocate a layout buffer with 4 partition entries first */
1077 LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
1078 ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION_EX));
1079 DiskEntry->LayoutBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
1081 LayoutBufferSize);
1082 if (DiskEntry->LayoutBuffer == NULL)
1083 {
1084 DPRINT1("Failed to allocate the disk layout buffer!\n");
1085 return;
1086 }
1087
1088 for (;;)
1089 {
1090 DPRINT1("Buffer size: %lu\n", LayoutBufferSize);
1092 NULL,
1093 NULL,
1094 NULL,
1095 &Iosb,
1097 NULL,
1098 0,
1099 DiskEntry->LayoutBuffer,
1100 LayoutBufferSize);
1101 if (NT_SUCCESS(Status))
1102 break;
1103
1105 {
1106 DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status);
1107 return;
1108 }
1109
1110 LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION_EX);
1111 NewLayoutBuffer = RtlReAllocateHeap(RtlGetProcessHeap(),
1113 DiskEntry->LayoutBuffer,
1114 LayoutBufferSize);
1115 if (NewLayoutBuffer == NULL)
1116 {
1117 DPRINT1("Failed to reallocate the disk layout buffer!\n");
1118 return;
1119 }
1120
1121 DiskEntry->LayoutBuffer = NewLayoutBuffer;
1122 }
1123
1124}
#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 2115 of file partlist.c.

2117{
2118 PDRIVE_LAYOUT_INFORMATION_EX NewLayoutBuffer;
2119 ULONG NewPartitionCount;
2120 ULONG CurrentPartitionCount = 0;
2121 ULONG LayoutBufferSize;
2122 ULONG i;
2123
2124 DPRINT1("ReAllocateLayoutBuffer()\n");
2125
2126 NewPartitionCount = 4 + GetLogicalPartitionCount(DiskEntry) * 4;
2127
2128 if (DiskEntry->LayoutBuffer)
2129 CurrentPartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
2130
2131 DPRINT1("CurrentPartitionCount: %lu ; NewPartitionCount: %lu\n",
2132 CurrentPartitionCount, NewPartitionCount);
2133
2134 if (CurrentPartitionCount == NewPartitionCount)
2135 return TRUE;
2136
2137 LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
2138 ((NewPartitionCount - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION_EX));
2139 NewLayoutBuffer = RtlReAllocateHeap(RtlGetProcessHeap(),
2141 DiskEntry->LayoutBuffer,
2142 LayoutBufferSize);
2143 if (NewLayoutBuffer == NULL)
2144 {
2145 DPRINT1("Failed to allocate the new layout buffer (size: %lu)\n", LayoutBufferSize);
2146 return FALSE;
2147 }
2148
2149 NewLayoutBuffer->PartitionCount = NewPartitionCount;
2150
2151 /* If the layout buffer grows, make sure the new (empty) entries are written to the disk */
2152 if (NewPartitionCount > CurrentPartitionCount)
2153 {
2154 for (i = CurrentPartitionCount; i < NewPartitionCount; i++)
2155 {
2156 NewLayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
2157 }
2158 }
2159
2160 DiskEntry->LayoutBuffer = NewLayoutBuffer;
2161
2162 return TRUE;
2163}
#define GetLogicalPartitionCount(DiskEntry)
Definition: partlist.c:2530

◆ RemoveVolume()

VOID RemoveVolume ( _In_ PVOLENTRY  VolumeEntry)

Definition at line 2637 of file partlist.c.

2639{
2640 if (VolumeEntry == NULL)
2641 return;
2642
2643 if (VolumeEntry == CurrentVolume)
2645
2646 RemoveEntryList(&VolumeEntry->ListEntry);
2647
2648 if (VolumeEntry->pszLabel)
2649 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszLabel);
2650
2651 if (VolumeEntry->pszFilesystem)
2652 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszFilesystem);
2653
2654 if (VolumeEntry->pExtents)
2655 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pExtents);
2656
2657 /* Release disk entry */
2658 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry);
2659}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986

Referenced by clean_main().

◆ ScanForUnpartitionedGptDiskSpace()

VOID ScanForUnpartitionedGptDiskSpace ( PDISKENTRY  DiskEntry)

Definition at line 923 of file partlist.c.

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

Referenced by AddDiskToList(), and ConvertGPT().

◆ ScanForUnpartitionedMbrDiskSpace()

VOID ScanForUnpartitionedMbrDiskSpace ( PDISKENTRY  DiskEntry)

Definition at line 662 of file partlist.c.

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

320{
321 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
323 ULONG i;
324
327 return STATUS_UNSUCCESSFUL;
328
329 FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
330
331 /* Hm. Version and Revision are not set on Microsoft Windows XP... */
332#if 0
333 if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
334 FullResourceDescriptor->PartialResourceList.Revision != 1)
335 return STATUS_UNSUCCESSFUL;
336#endif
337
338 for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
339 {
341 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize % sizeof(CM_INT13_DRIVE_PARAMETER) != 0)
342 continue;
343
344 *Int13Drives = (CM_INT13_DRIVE_PARAMETER*)RtlAllocateHeap(RtlGetProcessHeap(), 0,
345 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
346 if (*Int13Drives == NULL)
347 return STATUS_NO_MEMORY;
348
349 memcpy(*Int13Drives,
350 &FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1],
351 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
352 return STATUS_SUCCESS;
353 }
354
355 return STATUS_UNSUCCESSFUL;
356}
#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 2344 of file partlist.c.

2347{
2348 PLIST_ENTRY ListEntry;
2349 PPARTENTRY PartEntry;
2351 ULONG Count, Index;
2352
2353 DPRINT("UpdateGptDiskLayout()\n");
2354
2355 /* Count used partition entries */
2356 Count = 0;
2357 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
2358 ListEntry != &DiskEntry->PrimaryPartListHead;
2359 ListEntry = ListEntry->Flink)
2360 {
2361 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
2362
2363 if (!IsEqualGUID(&PartEntry->Gpt.PartitionType, &PARTITION_ENTRY_UNUSED_GUID))
2364 Count++;
2365 }
2366
2367 DPRINT("Used partition entries: %lu\n", Count);
2368
2369 if (DeleteEntry)
2370 Count++;
2371
2372 /* Reallocate the layout buffer */
2373 if (Count != DiskEntry->LayoutBuffer->PartitionCount)
2374 {
2375 PDRIVE_LAYOUT_INFORMATION_EX NewLayoutBuffer;
2376 ULONG NewLayoutBufferSize;
2377
2378 NewLayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
2380 NewLayoutBuffer = RtlReAllocateHeap(RtlGetProcessHeap(),
2382 DiskEntry->LayoutBuffer,
2383 NewLayoutBufferSize);
2384 if (NewLayoutBuffer == NULL)
2385 {
2386 DPRINT1("Failed to allocate the new layout buffer (size: %lu)\n", NewLayoutBufferSize);
2387 return;
2388 }
2389
2390 NewLayoutBuffer->PartitionCount = Count;
2391 DiskEntry->LayoutBuffer = NewLayoutBuffer;
2392 }
2393
2394 /* Fill the new layout buffer */
2395 Index = 0;
2396 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
2397 ListEntry != &DiskEntry->PrimaryPartListHead;
2398 ListEntry = ListEntry->Flink)
2399 {
2400 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
2401
2402 if (!IsEqualGUID(&PartEntry->Gpt.PartitionType, &PARTITION_ENTRY_UNUSED_GUID))
2403 {
2404 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
2405 PartEntry->PartitionIndex = Index;
2406
2407 DPRINT("Updating primary partition entry %lu\n", Index);
2408 PartitionInfo->PartitionStyle = PARTITION_STYLE_GPT;
2409 PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
2410 PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
2411 PartitionInfo->PartitionNumber = Index + 1;
2412 PartitionInfo->RewritePartition = TRUE;
2413 CopyMemory(&PartitionInfo->Gpt.PartitionType, &PartEntry->Gpt.PartitionType, sizeof(GUID));
2414 CopyMemory(&PartitionInfo->Gpt.PartitionId, &PartEntry->Gpt.PartitionId, sizeof(GUID));
2415 PartitionInfo->Gpt.Attributes = PartEntry->Gpt.Attributes;
2416 ZeroMemory(&PartitionInfo->Gpt.Name, 36 * sizeof(WCHAR)); /* ??? */
2417
2418 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
2419
2420 Index++;
2421 }
2422 }
2423
2424 if (DeleteEntry)
2425 {
2426 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
2428 PartitionInfo->RewritePartition = TRUE;
2429 }
2430}
#define ZeroMemory
Definition: minwinbase.h:31

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

◆ UpdateMbrDiskLayout()

VOID UpdateMbrDiskLayout ( _In_ PDISKENTRY  DiskEntry)

Definition at line 2167 of file partlist.c.

2169{
2172 PLIST_ENTRY ListEntry;
2173 PPARTENTRY PartEntry;
2174 LARGE_INTEGER HiddenSectors64;
2175 ULONG Index;
2177
2178 DPRINT("UpdateMbrDiskLayout()\n");
2179
2180 /* Resize the layout buffer if necessary */
2181 if (ReAllocateLayoutBuffer(DiskEntry) == FALSE)
2182 {
2183 DPRINT("ReAllocateLayoutBuffer() failed.\n");
2184 return;
2185 }
2186
2187 DiskEntry->LayoutBuffer->PartitionStyle = PARTITION_STYLE_MBR;
2188
2189 /* Update the primary partition table */
2190 Index = 0;
2191 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
2192 ListEntry != &DiskEntry->PrimaryPartListHead;
2193 ListEntry = ListEntry->Flink)
2194 {
2195 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
2196
2197 if (PartEntry->IsPartitioned)
2198 {
2200
2201 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
2202 PartEntry->PartitionIndex = Index;
2203
2204 /* Reset the current partition number only for newly-created (unmounted) partitions */
2205 if (PartEntry->New)
2206 PartEntry->PartitionNumber = 0;
2207
2209
2210 if (!IsSamePrimaryLayoutEntry(PartitionInfo, DiskEntry, PartEntry))
2211 {
2212 DPRINT1("Updating primary partition entry %lu\n", Index);
2213
2214 PartitionInfo->PartitionStyle = PARTITION_STYLE_MBR;
2215 PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
2216 PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
2217 PartitionInfo->Mbr.HiddenSectors = PartEntry->StartSector.LowPart;
2218 PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
2219 PartitionInfo->Mbr.PartitionType = PartEntry->Mbr.PartitionType;
2220 PartitionInfo->Mbr.BootIndicator = PartEntry->Mbr.BootIndicator;
2221 PartitionInfo->Mbr.RecognizedPartition = IsRecognizedPartition(PartEntry->Mbr.PartitionType);
2222 PartitionInfo->RewritePartition = TRUE;
2223 }
2224
2225 if (!IsContainerPartition(PartEntry->Mbr.PartitionType))
2227
2228 Index++;
2229 }
2230 }
2231
2232 ASSERT(Index <= 4);
2233
2234 /* Update the logical partition table */
2235 Index = 4;
2236 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
2237 ListEntry != &DiskEntry->LogicalPartListHead;
2238 ListEntry = ListEntry->Flink)
2239 {
2240 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
2241
2242 if (PartEntry->IsPartitioned)
2243 {
2245
2246 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
2247 PartEntry->PartitionIndex = Index;
2248
2249 /* Reset the current partition number only for newly-created (unmounted) partitions */
2250 if (PartEntry->New)
2251 PartEntry->PartitionNumber = 0;
2252
2254
2255 DPRINT1("Updating logical partition entry %lu\n", Index);
2256
2257 PartitionInfo->PartitionStyle = PARTITION_STYLE_MBR;
2258 PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
2259 PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
2260 PartitionInfo->Mbr.HiddenSectors = DiskEntry->SectorAlignment;
2261 PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
2262 PartitionInfo->Mbr.PartitionType = PartEntry->Mbr.PartitionType;
2263 PartitionInfo->Mbr.BootIndicator = FALSE;
2264 PartitionInfo->Mbr.RecognizedPartition = IsRecognizedPartition(PartEntry->Mbr.PartitionType);
2265 PartitionInfo->RewritePartition = TRUE;
2266
2267 /* Fill the link entry of the previous partition entry */
2268 if (LinkInfo != NULL)
2269 {
2271 LinkInfo->StartingOffset.QuadPart = (PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
2272 LinkInfo->PartitionLength.QuadPart = (PartEntry->StartSector.QuadPart + DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
2273 HiddenSectors64.QuadPart = PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment - DiskEntry->ExtendedPartition->StartSector.QuadPart;
2274 LinkInfo->Mbr.HiddenSectors = HiddenSectors64.LowPart;
2275 LinkInfo->PartitionNumber = 0;
2277 LinkInfo->Mbr.BootIndicator = FALSE;
2278 LinkInfo->Mbr.RecognizedPartition = FALSE;
2279 LinkInfo->RewritePartition = TRUE;
2280 }
2281
2282 /* Save a pointer to the link entry of the current partition entry */
2283 LinkInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index + 1];
2284
2286 Index += 4;
2287 }
2288 }
2289
2290 /* Wipe unused primary partition entries */
2291 for (Index = GetPrimaryPartitionCount(DiskEntry); Index < 4; Index++)
2292 {
2293 DPRINT1("Primary partition entry %lu\n", Index);
2294
2295 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
2296
2298 {
2299 DPRINT1("Wiping primary partition entry %lu\n", Index);
2300
2301 PartitionInfo->PartitionStyle = PARTITION_STYLE_MBR;
2302 PartitionInfo->StartingOffset.QuadPart = 0;
2303 PartitionInfo->PartitionLength.QuadPart = 0;
2304 PartitionInfo->Mbr.HiddenSectors = 0;
2305 PartitionInfo->PartitionNumber = 0;
2306 PartitionInfo->Mbr.PartitionType = PARTITION_ENTRY_UNUSED;
2307 PartitionInfo->Mbr.BootIndicator = FALSE;
2308 PartitionInfo->Mbr.RecognizedPartition = FALSE;
2309 PartitionInfo->RewritePartition = TRUE;
2310 }
2311 }
2312
2313 /* Wipe unused logical partition entries */
2314 for (Index = 4; Index < DiskEntry->LayoutBuffer->PartitionCount; Index++)
2315 {
2316 if (Index % 4 >= 2)
2317 {
2318 DPRINT1("Logical partition entry %lu\n", Index);
2319
2320 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
2321
2323 {
2324 DPRINT1("Wiping partition entry %lu\n", Index);
2325
2326 PartitionInfo->PartitionStyle = PARTITION_STYLE_MBR;
2327 PartitionInfo->StartingOffset.QuadPart = 0;
2328 PartitionInfo->PartitionLength.QuadPart = 0;
2329 PartitionInfo->Mbr.HiddenSectors = 0;
2330 PartitionInfo->PartitionNumber = 0;
2331 PartitionInfo->Mbr.PartitionType = PARTITION_ENTRY_UNUSED;
2332 PartitionInfo->Mbr.BootIndicator = FALSE;
2333 PartitionInfo->Mbr.RecognizedPartition = FALSE;
2334 PartitionInfo->RewritePartition = TRUE;
2335 }
2336 }
2337 }
2338
2339 DiskEntry->Dirty = TRUE;
2340}
#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:2055
static BOOLEAN IsEmptyLayoutEntry(IN PPARTITION_INFORMATION_EX PartitionInfo)
Definition: partlist.c:2040
static BOOLEAN ReAllocateLayoutBuffer(_In_ PDISKENTRY DiskEntry)
Definition: partlist.c:2115
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 1963 of file partlist.c.

1965{
1973
1974 DPRINT("WriteGptPartitions() Disk: %lu\n", DiskEntry->DiskNumber);
1975
1976 /* If the disk is not dirty, there is nothing to do */
1977 if (!DiskEntry->Dirty)
1978 return STATUS_SUCCESS;
1979
1981 L"\\Device\\Harddisk%lu\\Partition0",
1982 DiskEntry->DiskNumber);
1984
1986 &Name,
1988 NULL,
1989 NULL);
1990
1994 &Iosb,
1995 0,
1997 if (!NT_SUCCESS(Status))
1998 {
1999 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
2000 return Status;
2001 }
2002
2003 //
2004 // FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize
2005 // the disk in MBR or GPT format in case the disk was not initialized!!
2006 // For this we must ask the user which format to use.
2007 //
2008
2009 /* Set the new disk layout and retrieve its updated version with possibly modified partition numbers */
2010 BufferSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
2011 ((DiskEntry->LayoutBuffer->PartitionCount - 1) * sizeof(PARTITION_INFORMATION_EX));
2013 NULL,
2014 NULL,
2015 NULL,
2016 &Iosb,
2018 DiskEntry->LayoutBuffer,
2019 BufferSize,
2020 DiskEntry->LayoutBuffer,
2021 BufferSize);
2023
2024 /* Check whether the IOCTL_DISK_SET_DRIVE_LAYOUT_EX call succeeded */
2025 if (!NT_SUCCESS(Status))
2026 {
2027 DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT_EX failed (Status 0x%08lx)\n", Status);
2028 return Status;
2029 }
2030
2031 /* The layout has been successfully updated, the disk is not dirty anymore */
2032 DiskEntry->Dirty = FALSE;
2033
2034 return Status;
2035}
#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 1839 of file partlist.c.

1841{
1849 ULONG PartitionCount;
1850 PLIST_ENTRY ListEntry;
1851 PPARTENTRY PartEntry;
1853
1854 DPRINT("WriteMbrPartitions() Disk: %lu\n", DiskEntry->DiskNumber);
1855
1856 /* If the disk is not dirty, there is nothing to do */
1857 if (!DiskEntry->Dirty)
1858 return STATUS_SUCCESS;
1859
1861 L"\\Device\\Harddisk%lu\\Partition0",
1862 DiskEntry->DiskNumber);
1864
1866 &Name,
1868 NULL,
1869 NULL);
1870
1874 &Iosb,
1875 0,
1877 if (!NT_SUCCESS(Status))
1878 {
1879 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
1880 return Status;
1881 }
1882
1883 //
1884 // FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize
1885 // the disk in MBR or GPT format in case the disk was not initialized!!
1886 // For this we must ask the user which format to use.
1887 //
1888
1889 /* Save the original partition count to be restored later (see comment below) */
1890 PartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
1891
1892 /* Set the new disk layout and retrieve its updated version with possibly modified partition numbers */
1893 BufferSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
1894 ((PartitionCount - 1) * sizeof(PARTITION_INFORMATION_EX));
1896 NULL,
1897 NULL,
1898 NULL,
1899 &Iosb,
1901 DiskEntry->LayoutBuffer,
1902 BufferSize,
1903 DiskEntry->LayoutBuffer,
1904 BufferSize);
1906
1907 /*
1908 * IOCTL_DISK_SET_DRIVE_LAYOUT calls IoWritePartitionTable(), which converts
1909 * DiskEntry->LayoutBuffer->PartitionCount into a partition *table* count,
1910 * where such a table is expected to enumerate up to 4 partitions:
1911 * partition *table* count == ROUND_UP(PartitionCount, 4) / 4 .
1912 * Due to this we need to restore the original PartitionCount number.
1913 */
1914 DiskEntry->LayoutBuffer->PartitionCount = PartitionCount;
1915
1916 /* Check whether the IOCTL_DISK_SET_DRIVE_LAYOUT call succeeded */
1917 if (!NT_SUCCESS(Status))
1918 {
1919 DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status);
1920 return Status;
1921 }
1922
1923 /* Update the partition numbers */
1924
1925 /* Update the primary partition table */
1926 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
1927 ListEntry != &DiskEntry->PrimaryPartListHead;
1928 ListEntry = ListEntry->Flink)
1929 {
1930 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1931
1932 if (PartEntry->IsPartitioned)
1933 {
1935 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
1936 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
1937 }
1938 }
1939
1940 /* Update the logical partition table */
1941 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
1942 ListEntry != &DiskEntry->LogicalPartListHead;
1943 ListEntry = ListEntry->Flink)
1944 {
1945 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1946
1947 if (PartEntry->IsPartitioned)
1948 {
1950 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
1951 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
1952 }
1953 }
1954
1955 /* The layout has been successfully updated, the disk is not dirty anymore */
1956 DiskEntry->Dirty = FALSE;
1957
1958 return Status;
1959}

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

Referenced by CreatePartitionList(), and DestroyPartitionList().

◆ CurrentVolume

◆ DiskListHead

◆ VolumeListHead