ReactOS 0.4.16-dev-1983-g1a17364
partlist.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS DiskPart
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/system/diskpart/partlist.c
5 * PURPOSE: Manages all the partitions of the OS in an interactive way.
6 * PROGRAMMERS: Eric Kohl
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include "diskpart.h"
12#include <ntddscsi.h>
13
14#define NDEBUG
15#include <debug.h>
16
17#define InsertAscendingList(ListHead, NewEntry, Type, ListEntryField, SortField)\
18{\
19 PLIST_ENTRY current;\
20\
21 current = (ListHead)->Flink;\
22 while (current != (ListHead))\
23 {\
24 if (CONTAINING_RECORD(current, Type, ListEntryField)->SortField >=\
25 (NewEntry)->SortField)\
26 {\
27 break;\
28 }\
29 current = current->Flink;\
30 }\
31\
32 InsertTailList(current, &((NewEntry)->ListEntryField));\
33}
34
35/* We have to define it there, because it is not in the MS DDK */
36#define PARTITION_LINUX 0x83
37
38#define PARTITION_TBL_SIZE 4
39
40#define MBR_MAGIC 0xAA55
41
42#include <pshpack1.h>
43
44typedef struct _PARTITION
45{
46 unsigned char BootFlags; /* bootable? 0=no, 128=yes */
47 unsigned char StartingHead; /* beginning head number */
48 unsigned char StartingSector; /* beginning sector number */
49 unsigned char StartingCylinder; /* 10 bit nmbr, with high 2 bits put in begsect */
50 unsigned char PartitionType; /* Operating System type indicator code */
51 unsigned char EndingHead; /* ending head number */
52 unsigned char EndingSector; /* ending sector number */
53 unsigned char EndingCylinder; /* also a 10 bit nmbr, with same high 2 bit trick */
54 unsigned int StartingBlock; /* first sector relative to start of disk */
55 unsigned int SectorCount; /* number of sectors in partition */
57
58typedef struct _PARTITION_SECTOR
59{
60 UCHAR BootCode[440]; /* 0x000 */
61 ULONG Signature; /* 0x1B8 */
62 UCHAR Reserved[2]; /* 0x1BC */
64 USHORT Magic; /* 0x1FE */
66
67#include <poppack.h>
68
69
70/* GLOBALS ********************************************************************/
71
75
79
80
81/* FUNCTIONS ******************************************************************/
82
83#ifdef DUMP_PARTITION_TABLE
84VOID
85DumpPartitionTable(
86 _In_ PDISKENTRY DiskEntry)
87{
89 ULONG i;
90
91 DbgPrint("\n");
92
93 if (DiskEntry->LayoutBuffer->PartitionStyle == PARTITION_STYLE_MBR)
94 {
95 DbgPrint("Index Start Length Hidden Nr Type Boot RW\n");
96 DbgPrint("----- ------------ ------------ ---------- -- ---- ---- --\n");
97
98 for (i = 0; i < DiskEntry->LayoutBuffer->PartitionCount; i++)
99 {
100 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[i];
101 DbgPrint(" %3lu %12I64u %12I64u %10lu %2lu %2x %c %c\n",
102 i,
103 PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector,
104 PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector,
105 PartitionInfo->Mbr.HiddenSectors,
106 PartitionInfo->PartitionNumber,
107 PartitionInfo->Mbr.PartitionType,
108 PartitionInfo->Mbr.BootIndicator ? '*': ' ',
109 PartitionInfo->RewritePartition ? 'Y': 'N');
110 }
111 }
112 else if (DiskEntry->LayoutBuffer->PartitionStyle == PARTITION_STYLE_GPT)
113 {
114 DbgPrint("Index Start Length Nr RW Type \n");
115 DbgPrint("----- ------------ ------------ -- -- --------\n");
116 for (i = 0; i < DiskEntry->LayoutBuffer->PartitionCount; i++)
117 {
118 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[i];
119
120 DbgPrint(" %3lu %12I64u %12I64u %2lu %c %08lx\n",
121 i,
122 PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector,
123 PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector,
124 PartitionInfo->PartitionNumber,
125 PartitionInfo->RewritePartition ? 'Y': 'N',
126 PartitionInfo->Gpt.PartitionType.Data1);
127 }
128 }
129
130 DbgPrint("\n");
131}
132#endif
133
138{
139 ULONGLONG Temp;
140
141 Temp = Value / Alignment;
142
143 return Temp * Alignment;
144}
145
146static
147VOID
149 PDISKENTRY DiskEntry)
150{
152 WCHAR KeyName[32];
154
156 NULL);
157
159 L"\\Scsi\\Scsi Port %lu",
160 DiskEntry->Port);
161
163 sizeof(QueryTable));
164
165 QueryTable[0].Name = L"Driver";
167 QueryTable[0].EntryContext = &DiskEntry->DriverName;
168
170 KeyName,
172 NULL,
173 NULL);
174 if (!NT_SUCCESS(Status))
175 {
176 DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
177 }
178}
179
180static
182NTAPI
190{
191 PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
192 UNICODE_STRING NameU;
193
194 if (ValueType == REG_SZ &&
195 ValueLength == 20 * sizeof(WCHAR))
196 {
197 NameU.Buffer = (PWCHAR)ValueData;
198 NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR);
199 RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum);
200
201 NameU.Buffer = (PWCHAR)ValueData + 9;
202 RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature);
203
204 return STATUS_SUCCESS;
205 }
206
207 return STATUS_UNSUCCESSFUL;
208}
209
210static
212NTAPI
220{
221 PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
222 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
224 ULONG i;
225
228 return STATUS_UNSUCCESSFUL;
229
230 FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
231
232 /* Hm. Version and Revision are not set on Microsoft Windows XP... */
233#if 0
234 if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
235 FullResourceDescriptor->PartialResourceList.Revision != 1)
236 return STATUS_UNSUCCESSFUL;
237#endif
238
239 for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
240 {
243 continue;
244
245 DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1];
246 BiosDiskEntry->DiskGeometry = *DiskGeometry;
247
248 return STATUS_SUCCESS;
249 }
250
251 return STATUS_UNSUCCESSFUL;
252}
253
254static
256NTAPI
264{
265 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
267 ULONG i;
268
271 return STATUS_UNSUCCESSFUL;
272
273 FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
274
275 /* Hm. Version and Revision are not set on Microsoft Windows XP... */
276#if 0
277 if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
278 FullResourceDescriptor->PartialResourceList.Revision != 1)
279 return STATUS_UNSUCCESSFUL;
280#endif
281
282 for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
283 {
285 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize % sizeof(CM_INT13_DRIVE_PARAMETER) != 0)
286 continue;
287
288 *Int13Drives = (CM_INT13_DRIVE_PARAMETER*)RtlAllocateHeap(RtlGetProcessHeap(), 0,
289 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
290 if (*Int13Drives == NULL)
291 return STATUS_NO_MEMORY;
292
293 memcpy(*Int13Drives,
294 &FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1],
295 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
296 return STATUS_SUCCESS;
297 }
298
299 return STATUS_UNSUCCESSFUL;
300}
301
302
303#define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
304
305static
306VOID
308{
310 WCHAR Name[120];
311 ULONG AdapterCount;
312 ULONG DiskCount;
314 PCM_INT13_DRIVE_PARAMETER Int13Drives;
315 PBIOSDISKENTRY BiosDiskEntry;
316
317 memset(QueryTable, 0, sizeof(QueryTable));
318
319 QueryTable[1].Name = L"Configuration Data";
321 Int13Drives = NULL;
323 L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
324 &QueryTable[1],
325 (PVOID)&Int13Drives,
326 NULL);
327 if (!NT_SUCCESS(Status))
328 {
329 DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status);
330 return;
331 }
332
333 AdapterCount = 0;
334 while (1)
335 {
337 L"%s\\%lu", ROOT_NAME, AdapterCount);
339 Name,
340 &QueryTable[2],
341 NULL,
342 NULL);
343 if (!NT_SUCCESS(Status))
344 {
345 break;
346 }
347
349 L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount);
351 Name,
352 &QueryTable[2],
353 NULL,
354 NULL);
355 if (NT_SUCCESS(Status))
356 {
357 while (1)
358 {
360 L"%s\\%lu\\DiskController\\0", ROOT_NAME, AdapterCount);
362 Name,
363 &QueryTable[2],
364 NULL,
365 NULL);
366 if (!NT_SUCCESS(Status))
367 {
368 RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
369 return;
370 }
371
373 L"%s\\%lu\\DiskController\\0\\DiskPeripheral", ROOT_NAME, AdapterCount);
375 Name,
376 &QueryTable[2],
377 NULL,
378 NULL);
379 if (NT_SUCCESS(Status))
380 {
381 QueryTable[0].Name = L"Identifier";
383 QueryTable[1].Name = L"Configuration Data";
385
386 DiskCount = 0;
387 while (1)
388 {
389 BiosDiskEntry = (BIOSDISKENTRY*)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY));
390 if (BiosDiskEntry == NULL)
391 {
392 break;
393 }
394
396 L"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, DiskCount);
398 Name,
400 (PVOID)BiosDiskEntry,
401 NULL);
402 if (!NT_SUCCESS(Status))
403 {
404 RtlFreeHeap(RtlGetProcessHeap(), 0, BiosDiskEntry);
405 break;
406 }
407
408 BiosDiskEntry->DiskNumber = DiskCount;
409 BiosDiskEntry->Recognized = FALSE;
410
411 if (DiskCount < Int13Drives[0].NumberDrives)
412 {
413 BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount];
414 }
415 else
416 {
417 DPRINT1("Didn't find int13 drive datas for disk %u\n", DiskCount);
418 }
419
420 InsertTailList(&BiosDiskListHead, &BiosDiskEntry->ListEntry);
421
422 DPRINT("DiskNumber: %lu\n", BiosDiskEntry->DiskNumber);
423 DPRINT("Signature: %08lx\n", BiosDiskEntry->Signature);
424 DPRINT("Checksum: %08lx\n", BiosDiskEntry->Checksum);
425 DPRINT("BytesPerSector: %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector);
426 DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders);
427 DPRINT("NumberOfHeads: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads);
428 DPRINT("DriveSelect: %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect);
429 DPRINT("MaxCylinders: %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders);
430 DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack);
431 DPRINT("MaxHeads: %d\n", BiosDiskEntry->Int13DiskData.MaxHeads);
432 DPRINT("NumberDrives: %d\n", BiosDiskEntry->Int13DiskData.NumberDrives);
433
434 DiskCount++;
435 }
436 }
437
438 RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
439 return;
440 }
441 }
442
443 AdapterCount++;
444 }
445
446 RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
447}
448
449
450static
451VOID
453 ULONG DiskNumber,
454 PDISKENTRY DiskEntry,
455 ULONG PartitionIndex,
457{
459 PPARTENTRY PartEntry;
460
461 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
462 if (PartitionInfo->Mbr.PartitionType == 0 ||
463 (LogicalPartition == TRUE && IsContainerPartition(PartitionInfo->Mbr.PartitionType)))
464 return;
465
466 PartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
468 sizeof(PARTENTRY));
469 if (PartEntry == NULL)
470 {
471 return;
472 }
473
474 PartEntry->DiskEntry = DiskEntry;
475
476 PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
477 PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
478
479 PartEntry->BootIndicator = PartitionInfo->Mbr.BootIndicator;
480 PartEntry->PartitionType = PartitionInfo->Mbr.PartitionType;
481
483 PartEntry->IsPartitioned = TRUE;
484 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
485 PartEntry->PartitionIndex = PartitionIndex;
486
487 if (IsContainerPartition(PartEntry->PartitionType))
488 {
489 PartEntry->FormatState = Unformatted;
490
491 if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
492 DiskEntry->ExtendedPartition = PartEntry;
493 }
494 else if ((PartEntry->PartitionType == PARTITION_FAT_12) ||
495 (PartEntry->PartitionType == PARTITION_FAT_16) ||
496 (PartEntry->PartitionType == PARTITION_HUGE) ||
497 (PartEntry->PartitionType == PARTITION_XINT13) ||
498 (PartEntry->PartitionType == PARTITION_FAT32) ||
500 {
501#if 0
502 if (CheckFatFormat())
503 {
504 PartEntry->FormatState = Preformatted;
505 }
506 else
507 {
508 PartEntry->FormatState = Unformatted;
509 }
510#endif
511 PartEntry->FormatState = Preformatted;
512 }
513 else if (PartEntry->PartitionType == PARTITION_LINUX)
514 {
515#if 0
516 if (CheckExt2Format())
517 {
518 PartEntry->FormatState = Preformatted;
519 }
520 else
521 {
522 PartEntry->FormatState = Unformatted;
523 }
524#endif
525 PartEntry->FormatState = Preformatted;
526 }
527 else if (PartEntry->PartitionType == PARTITION_IFS)
528 {
529#if 0
530 if (CheckNtfsFormat())
531 {
532 PartEntry->FormatState = Preformatted;
533 }
534 else if (CheckHpfsFormat())
535 {
536 PartEntry->FormatState = Preformatted;
537 }
538 else
539 {
540 PartEntry->FormatState = Unformatted;
541 }
542#endif
543 PartEntry->FormatState = Preformatted;
544 }
545 else
546 {
547 PartEntry->FormatState = UnknownFormat;
548 }
549
552 &PartEntry->ListEntry);
553 else
555 &PartEntry->ListEntry);
556}
557
558
559static
560VOID
562 PDISKENTRY DiskEntry)
563{
564 ULONGLONG LastStartSector;
565 ULONGLONG LastSectorCount;
566 ULONGLONG LastUnusedSectorCount;
567 PPARTENTRY PartEntry;
568 PPARTENTRY NewPartEntry;
570
571 DPRINT("ScanForUnpartitionedDiskSpace()\n");
572
573 if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
574 {
575 DPRINT1("No primary partition!\n");
576
577 /* Create a partition table that represents the empty disk */
578 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
580 sizeof(PARTENTRY));
581 if (NewPartEntry == NULL)
582 return;
583
584 NewPartEntry->DiskEntry = DiskEntry;
585
586 NewPartEntry->IsPartitioned = FALSE;
587 NewPartEntry->StartSector.QuadPart = (ULONGLONG)DiskEntry->SectorAlignment;
588 NewPartEntry->SectorCount.QuadPart = AlignDown(DiskEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment) -
589 NewPartEntry->StartSector.QuadPart;
590
591 DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
592 DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
593 DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
594
595 NewPartEntry->FormatState = Unformatted;
596
598 &NewPartEntry->ListEntry);
599
600 return;
601 }
602
603 /* Start partition at head 1, cylinder 0 */
604 LastStartSector = DiskEntry->SectorAlignment;
605 LastSectorCount = 0ULL;
606 LastUnusedSectorCount = 0ULL;
607
608 Entry = DiskEntry->PrimaryPartListHead.Flink;
609 while (Entry != &DiskEntry->PrimaryPartListHead)
610 {
611 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
612
613 if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
614 PartEntry->SectorCount.QuadPart != 0ULL)
615 {
616 LastUnusedSectorCount =
617 PartEntry->StartSector.QuadPart - (LastStartSector + LastSectorCount);
618
619 if (PartEntry->StartSector.QuadPart > (LastStartSector + LastSectorCount) &&
620 LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
621 {
622 DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
623
624 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
626 sizeof(PARTENTRY));
627 if (NewPartEntry == NULL)
628 return;
629
630 NewPartEntry->DiskEntry = DiskEntry;
631
632 NewPartEntry->IsPartitioned = FALSE;
633 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
634 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
635 NewPartEntry->StartSector.QuadPart;
636
637 DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
638 DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
639 DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
640
641 NewPartEntry->FormatState = Unformatted;
642
643 /* Insert the table into the list */
644 InsertTailList(&PartEntry->ListEntry,
645 &NewPartEntry->ListEntry);
646 }
647
648 LastStartSector = PartEntry->StartSector.QuadPart;
649 LastSectorCount = PartEntry->SectorCount.QuadPart;
650 }
651
652 Entry = Entry->Flink;
653 }
654
655 /* Check for trailing unpartitioned disk space */
656 if ((LastStartSector + LastSectorCount) < DiskEntry->SectorCount.QuadPart)
657 {
658 LastUnusedSectorCount = AlignDown(DiskEntry->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
659
660 if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
661 {
662 DPRINT1("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
663
664 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
666 sizeof(PARTENTRY));
667 if (NewPartEntry == NULL)
668 return;
669
670 NewPartEntry->DiskEntry = DiskEntry;
671
672 NewPartEntry->IsPartitioned = FALSE;
673 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
674 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
675 NewPartEntry->StartSector.QuadPart;
676
677 DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
678 DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
679 DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
680
681 NewPartEntry->FormatState = Unformatted;
682
683 /* Append the table to the list */
685 &NewPartEntry->ListEntry);
686 }
687 }
688
689 if (DiskEntry->ExtendedPartition != NULL)
690 {
691 if (IsListEmpty(&DiskEntry->LogicalPartListHead))
692 {
693 DPRINT1("No logical partition!\n");
694
695 /* Create a partition table entry that represents the empty extended partition */
696 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
698 sizeof(PARTENTRY));
699 if (NewPartEntry == NULL)
700 return;
701
702 NewPartEntry->DiskEntry = DiskEntry;
703 NewPartEntry->LogicalPartition = TRUE;
704
705 NewPartEntry->IsPartitioned = FALSE;
706 NewPartEntry->StartSector.QuadPart = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
707 NewPartEntry->SectorCount.QuadPart = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
708
709 DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
710 DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
711 DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
712
713 NewPartEntry->FormatState = Unformatted;
714
716 &NewPartEntry->ListEntry);
717
718 return;
719 }
720
721 /* Start partition at head 1, cylinder 0 */
722 LastStartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
723 LastSectorCount = 0ULL;
724 LastUnusedSectorCount = 0ULL;
725
726 Entry = DiskEntry->LogicalPartListHead.Flink;
727 while (Entry != &DiskEntry->LogicalPartListHead)
728 {
729 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
730
731 if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
732 PartEntry->SectorCount.QuadPart != 0ULL)
733 {
734 LastUnusedSectorCount =
735 PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment - (LastStartSector + LastSectorCount);
736
737 if ((PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment) > (LastStartSector + LastSectorCount) &&
738 LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
739 {
740 DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
741
742 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
744 sizeof(PARTENTRY));
745 if (NewPartEntry == NULL)
746 return;
747
748 NewPartEntry->DiskEntry = DiskEntry;
749 NewPartEntry->LogicalPartition = TRUE;
750
751 NewPartEntry->IsPartitioned = FALSE;
752 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
753 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
754 NewPartEntry->StartSector.QuadPart;
755
756 DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
757 DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
758 DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
759
760 NewPartEntry->FormatState = Unformatted;
761
762 /* Insert the table into the list */
763 InsertTailList(&PartEntry->ListEntry,
764 &NewPartEntry->ListEntry);
765 }
766
767 LastStartSector = PartEntry->StartSector.QuadPart;
768 LastSectorCount = PartEntry->SectorCount.QuadPart;
769 }
770
771 Entry = Entry->Flink;
772 }
773
774 /* Check for trailing unpartitioned disk space */
775 if ((LastStartSector + LastSectorCount) < DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart)
776 {
777 LastUnusedSectorCount = AlignDown(DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart - (LastStartSector + LastSectorCount),
778 DiskEntry->SectorAlignment);
779
780 if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
781 {
782 DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
783
784 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
786 sizeof(PARTENTRY));
787 if (NewPartEntry == NULL)
788 return;
789
790 NewPartEntry->DiskEntry = DiskEntry;
791 NewPartEntry->LogicalPartition = TRUE;
792
793 NewPartEntry->IsPartitioned = FALSE;
794 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
795 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
796 NewPartEntry->StartSector.QuadPart;
797
798 DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
799 DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
800 DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
801
802 NewPartEntry->FormatState = Unformatted;
803
804 /* Append the table to the list */
806 &NewPartEntry->ListEntry);
807 }
808 }
809 }
810
811 DPRINT("ScanForUnpartitionedDiskSpace() done\n");
812}
813
814
815VOID
818 _In_ PDISKENTRY DiskEntry)
819{
820 ULONG LayoutBufferSize;
821 PDRIVE_LAYOUT_INFORMATION_EX NewLayoutBuffer;
824
825 /* Allocate a layout buffer with 4 partition entries first */
826 LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
827 ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION_EX));
828 DiskEntry->LayoutBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
830 LayoutBufferSize);
831 if (DiskEntry->LayoutBuffer == NULL)
832 {
833 DPRINT1("Failed to allocate the disk layout buffer!\n");
834 return;
835 }
836
837 for (;;)
838 {
839 DPRINT1("Buffer size: %lu\n", LayoutBufferSize);
841 NULL,
842 NULL,
843 NULL,
844 &Iosb,
846 NULL,
847 0,
848 DiskEntry->LayoutBuffer,
849 LayoutBufferSize);
850 if (NT_SUCCESS(Status))
851 break;
852
854 {
855 DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status);
856 return;
857 }
858
859 LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION_EX);
860 NewLayoutBuffer = RtlReAllocateHeap(RtlGetProcessHeap(),
862 DiskEntry->LayoutBuffer,
863 LayoutBufferSize);
864 if (NewLayoutBuffer == NULL)
865 {
866 DPRINT1("Failed to reallocate the disk layout buffer!\n");
867 return;
868 }
869
870 DiskEntry->LayoutBuffer = NewLayoutBuffer;
871 }
872}
873
874
875static
876VOID
879 ULONG DiskNumber)
880{
881 DISK_GEOMETRY DiskGeometry;
882 SCSI_ADDRESS ScsiAddress;
883 PDISKENTRY DiskEntry;
889 WCHAR Identifier[20];
890 ULONG Checksum;
892 ULONG i;
893 PLIST_ENTRY ListEntry;
894 PBIOSDISKENTRY BiosDiskEntry;
895
897 NULL,
898 NULL,
899 NULL,
900 &Iosb,
902 NULL,
903 0,
904 &DiskGeometry,
905 sizeof(DISK_GEOMETRY));
906 if (!NT_SUCCESS(Status))
907 {
908 return;
909 }
910
911 if (DiskGeometry.MediaType != FixedMedia &&
912 DiskGeometry.MediaType != RemovableMedia)
913 {
914 return;
915 }
916
918 NULL,
919 NULL,
920 NULL,
921 &Iosb,
923 NULL,
924 0,
925 &ScsiAddress,
926 sizeof(SCSI_ADDRESS));
927 if (!NT_SUCCESS(Status))
928 {
929 return;
930 }
931
932 Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(RtlGetProcessHeap(),
933 0,
934 DiskGeometry.BytesPerSector);
935 if (Mbr == NULL)
936 {
937 return;
938 }
939
940 FileOffset.QuadPart = 0;
942 NULL,
943 NULL,
944 NULL,
945 &Iosb,
946 (PVOID)Mbr,
947 DiskGeometry.BytesPerSector,
948 &FileOffset,
949 NULL);
950 if (!NT_SUCCESS(Status))
951 {
952 RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr);
953 DPRINT1("NtReadFile failed, status=%x\n", Status);
954 return;
955 }
956 Signature = Mbr->Signature;
957
958 /* Calculate the MBR checksum */
959 Checksum = 0;
960 Buffer = (PULONG)Mbr;
961 for (i = 0; i < 128; i++)
962 {
963 Checksum += Buffer[i];
964 }
965 Checksum = ~Checksum + 1;
966
968 L"%08x-%08x-A", Checksum, Signature);
969 DPRINT("Identifier: %S\n", Identifier);
970
971 DiskEntry = RtlAllocateHeap(RtlGetProcessHeap(),
973 sizeof(DISKENTRY));
974 if (DiskEntry == NULL)
975 {
976 return;
977 }
978
979// DiskEntry->Checksum = Checksum;
980// DiskEntry->Signature = Signature;
981 DiskEntry->BiosFound = FALSE;
982
983 /* Check the disk partition style */
984 if (Mbr->Magic != MBR_MAGIC)
985 {
986 DPRINT("Partition style: RAW\n");
987 DiskEntry->PartitionStyle = PARTITION_STYLE_RAW;
988 }
989 else
990 {
992 {
993 DPRINT("Partition style: GPT\n");
995 }
996 else
997 {
998 DPRINT("Partition style: MBR\n");
1000 }
1001 }
1002
1003 /* Free Mbr sector buffer */
1004 RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr);
1005
1006 ListEntry = BiosDiskListHead.Flink;
1007 while (ListEntry != &BiosDiskListHead)
1008 {
1009 BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
1010 /* FIXME:
1011 * Compare the size from bios and the reported size from driver.
1012 * If we have more than one disk with a zero or with the same signatur
1013 * we must create new signatures and reboot. After the reboot,
1014 * it is possible to identify the disks.
1015 */
1016 if (BiosDiskEntry->Signature == Signature &&
1017 BiosDiskEntry->Checksum == Checksum &&
1018 !BiosDiskEntry->Recognized)
1019 {
1020 if (!DiskEntry->BiosFound)
1021 {
1022 DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber;
1023 DiskEntry->BiosFound = TRUE;
1024 BiosDiskEntry->Recognized = TRUE;
1025 }
1026 else
1027 {
1028 }
1029 }
1030 ListEntry = ListEntry->Flink;
1031 }
1032
1033 if (!DiskEntry->BiosFound)
1034 {
1035#if 0
1036 RtlFreeHeap(ProcessHeap, 0, DiskEntry);
1037 return;
1038#else
1039 DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %d is not be bootable by the BIOS!\n", DiskNumber);
1040#endif
1041 }
1042
1045
1046 DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
1047 DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
1048 DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
1049 DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
1050
1051 DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders);
1052 DPRINT("TracksPerCylinder %I64u\n", DiskEntry->TracksPerCylinder);
1053 DPRINT("SectorsPerTrack %I64u\n", DiskEntry->SectorsPerTrack);
1054 DPRINT("BytesPerSector %I64u\n", DiskEntry->BytesPerSector);
1055
1056 DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart *
1057 (ULONGLONG)DiskGeometry.TracksPerCylinder *
1058 (ULONGLONG)DiskGeometry.SectorsPerTrack;
1059
1060// DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
1061// DiskEntry->CylinderAlignment = DiskGeometry.SectorsPerTrack * DiskGeometry.TracksPerCylinder;
1062 DiskEntry->SectorAlignment = (1024 * 1024) / DiskGeometry.BytesPerSector;
1063 DiskEntry->CylinderAlignment = (1024 * 1024) / DiskGeometry.BytesPerSector;
1064
1065 DPRINT1("SectorCount: %I64u\n", DiskEntry->SectorCount);
1066 DPRINT1("SectorAlignment: %lu\n", DiskEntry->SectorAlignment);
1067 DPRINT1("CylinderAlignment: %lu\n", DiskEntry->CylinderAlignment);
1068
1069 DiskEntry->DiskNumber = DiskNumber;
1070 DiskEntry->Port = ScsiAddress.PortNumber;
1071 DiskEntry->PathId = ScsiAddress.PathId;
1072 DiskEntry->TargetId = ScsiAddress.TargetId;
1073 DiskEntry->Lun = ScsiAddress.Lun;
1074
1075 GetDriverName(DiskEntry);
1076
1077 InsertAscendingList(&DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber);
1078
1079 ReadLayoutBuffer(FileHandle, DiskEntry);
1080
1081 DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount);
1082
1083#ifdef DUMP_PARTITION_TABLE
1084 DumpPartitionTable(DiskEntry);
1085#endif
1086
1087 if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
1089 DiskEntry->LayoutBuffer->PartitionEntry[0].Mbr.PartitionType != 0)
1090 {
1091 if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
1092 {
1093 DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
1094 }
1095 else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
1096 {
1097 DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1098 }
1099 else
1100 {
1101 DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
1102 }
1103 }
1104 else
1105 {
1106 DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1107 }
1108
1109
1110 if (DiskEntry->LayoutBuffer->PartitionCount == 0)
1111 {
1112 DiskEntry->NewDisk = TRUE;
1113 DiskEntry->LayoutBuffer->PartitionCount = 4;
1114
1115 for (i = 0; i < 4; i++)
1117 }
1118 else
1119 {
1120 for (i = 0; i < 4; i++)
1121 {
1122 AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
1123 }
1124
1125 for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
1126 {
1127 AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
1128 }
1129 }
1130
1132}
1133
1134
1137{
1141 ULONG ReturnSize;
1143 ULONG DiskNumber;
1147
1148 CurrentDisk = NULL;
1150
1151// BootDisk = NULL;
1152// BootPartition = NULL;
1153
1154// TempDisk = NULL;
1155// TempPartition = NULL;
1156// FormatState = Start;
1157
1160
1162
1164 &Sdi,
1166 &ReturnSize);
1167 if (!NT_SUCCESS(Status))
1168 {
1169 return Status;
1170 }
1171
1172 for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
1173 {
1175 L"\\Device\\Harddisk%d\\Partition0",
1176 DiskNumber);
1177
1179 Buffer);
1180
1182 &Name,
1183 0,
1184 NULL,
1185 NULL);
1186
1190 &Iosb,
1193 if (NT_SUCCESS(Status))
1194 {
1195 AddDiskToList(FileHandle, DiskNumber);
1196
1198 }
1199 }
1200
1201// UpdateDiskSignatures(List);
1202
1203// AssignDriveLetters(List);
1204
1205 return STATUS_SUCCESS;
1206}
1207
1208
1209VOID
1211{
1212 PDISKENTRY DiskEntry;
1213 PBIOSDISKENTRY BiosDiskEntry;
1214 PPARTENTRY PartEntry;
1216
1217 CurrentDisk = NULL;
1219
1220 /* Release disk and partition info */
1221 while (!IsListEmpty(&DiskListHead))
1222 {
1224 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
1225
1226 /* Release driver name */
1227 RtlFreeUnicodeString(&DiskEntry->DriverName);
1228
1229 /* Release primary partition list */
1230 while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
1231 {
1233 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1234
1235 RtlFreeHeap(RtlGetProcessHeap(), 0, PartEntry);
1236 }
1237
1238 /* Release logical partition list */
1239 while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
1240 {
1242 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1243
1244 RtlFreeHeap(RtlGetProcessHeap(), 0, PartEntry);
1245 }
1246
1247 /* Release layout buffer */
1248 if (DiskEntry->LayoutBuffer != NULL)
1249 RtlFreeHeap(RtlGetProcessHeap(), 0, DiskEntry->LayoutBuffer);
1250
1251
1252 /* Release disk entry */
1253 RtlFreeHeap(RtlGetProcessHeap(), 0, DiskEntry);
1254 }
1255
1256 /* Release the bios disk info */
1257 while (!IsListEmpty(&BiosDiskListHead))
1258 {
1260 BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
1261
1262 RtlFreeHeap(RtlGetProcessHeap(), 0, BiosDiskEntry);
1263 }
1264}
1265
1266
1267static
1268VOID
1271 _In_ PVOLENTRY VolumeEntry)
1272{
1273 DWORD dwBytesReturned = 0, dwLength, i;
1274 PVOLUME_DISK_EXTENTS pExtents;
1275 BOOL bResult;
1276 DWORD dwError;
1277
1278 dwLength = sizeof(VOLUME_DISK_EXTENTS);
1279 pExtents = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
1280 if (pExtents == NULL)
1281 return;
1282
1283 bResult = DeviceIoControl(VolumeHandle,
1285 NULL,
1286 0,
1287 pExtents,
1288 dwLength,
1289 &dwBytesReturned,
1290 NULL);
1291 if (!bResult)
1292 {
1293 dwError = GetLastError();
1294
1295 if (dwError != ERROR_MORE_DATA)
1296 {
1297 RtlFreeHeap(RtlGetProcessHeap(), 0, pExtents);
1298 return;
1299 }
1300 else
1301 {
1302 dwLength = sizeof(VOLUME_DISK_EXTENTS) + ((pExtents->NumberOfDiskExtents - 1) * sizeof(DISK_EXTENT));
1303 RtlFreeHeap(RtlGetProcessHeap(), 0, pExtents);
1304 pExtents = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
1305 if (pExtents == NULL)
1306 {
1307 return;
1308 }
1309
1310 bResult = DeviceIoControl(VolumeHandle,
1312 NULL,
1313 0,
1314 pExtents,
1315 dwLength,
1316 &dwBytesReturned,
1317 NULL);
1318 if (!bResult)
1319 {
1320 RtlFreeHeap(RtlGetProcessHeap(), 0, pExtents);
1321 return;
1322 }
1323 }
1324 }
1325
1326 for (i = 0; i < pExtents->NumberOfDiskExtents; i++)
1327 VolumeEntry->Size.QuadPart += pExtents->Extents[i].ExtentLength.QuadPart;
1328
1329 VolumeEntry->pExtents = pExtents;
1330}
1331
1332
1333static
1334VOID
1337 _In_ PVOLENTRY VolumeEntry)
1338{
1342
1345 &DeviceInfo,
1348 if (!NT_SUCCESS(Status))
1349 return;
1350
1351 switch (DeviceInfo.DeviceType)
1352 {
1353 case FILE_DEVICE_CD_ROM:
1355 VolumeEntry->VolumeType = VOLUME_TYPE_CDROM;
1356 break;
1357
1358 case FILE_DEVICE_DISK:
1360 if (DeviceInfo.Characteristics & FILE_REMOVABLE_MEDIA)
1361 VolumeEntry->VolumeType = VOLUME_TYPE_REMOVABLE;
1362 else
1363 VolumeEntry->VolumeType = VOLUME_TYPE_PARTITION;
1364 break;
1365
1366 default:
1367 VolumeEntry->VolumeType = VOLUME_TYPE_UNKNOWN;
1368 break;
1369 }
1370}
1371
1372
1373static
1374VOID
1376 ULONG ulVolumeNumber,
1377 PWSTR pszVolumeName)
1378{
1379 PVOLENTRY VolumeEntry;
1381
1382 DWORD dwError, dwLength;
1383 WCHAR szPathNames[MAX_PATH + 1];
1384 WCHAR szVolumeName[MAX_PATH + 1];
1385 WCHAR szFilesystem[MAX_PATH + 1];
1386
1387 DWORD CharCount = 0;
1388 size_t Index = 0;
1389
1394
1395 DPRINT("AddVolumeToList(%S)\n", pszVolumeName);
1396
1397 VolumeEntry = RtlAllocateHeap(RtlGetProcessHeap(),
1399 sizeof(VOLENTRY));
1400 if (VolumeEntry == NULL)
1401 return;
1402
1403 VolumeEntry->VolumeNumber = ulVolumeNumber;
1404 wcscpy(VolumeEntry->VolumeName, pszVolumeName);
1405
1406 Index = wcslen(pszVolumeName) - 1;
1407
1408 pszVolumeName[Index] = L'\0';
1409
1410 CharCount = QueryDosDeviceW(&pszVolumeName[4], VolumeEntry->DeviceName, ARRAYSIZE(VolumeEntry->DeviceName));
1411
1412 pszVolumeName[Index] = L'\\';
1413
1414 if (CharCount == 0)
1415 {
1416 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry);
1417 return;
1418 }
1419
1420 DPRINT("DeviceName: %S\n", VolumeEntry->DeviceName);
1421
1422 RtlInitUnicodeString(&Name, VolumeEntry->DeviceName);
1423
1425 &Name,
1426 0,
1427 NULL,
1428 NULL);
1429
1433 &Iosb,
1434 0,
1436 if (NT_SUCCESS(Status))
1437 {
1438 GetVolumeType(VolumeHandle, VolumeEntry);
1439 GetVolumeExtents(VolumeHandle, VolumeEntry);
1441 }
1442
1443 if (GetVolumeInformationW(pszVolumeName,
1444 szVolumeName,
1445 MAX_PATH + 1,
1446 NULL, // [out, optional] LPDWORD lpVolumeSerialNumber,
1447 NULL, // [out, optional] LPDWORD lpMaximumComponentLength,
1448 NULL, // [out, optional] LPDWORD lpFileSystemFlags,
1449 szFilesystem,
1450 MAX_PATH + 1))
1451 {
1452 VolumeEntry->pszLabel = RtlAllocateHeap(RtlGetProcessHeap(),
1453 0,
1454 (wcslen(szVolumeName) + 1) * sizeof(WCHAR));
1455 if (VolumeEntry->pszLabel)
1456 wcscpy(VolumeEntry->pszLabel, szVolumeName);
1457
1458 VolumeEntry->pszFilesystem = RtlAllocateHeap(RtlGetProcessHeap(),
1459 0,
1460 (wcslen(szFilesystem) + 1) * sizeof(WCHAR));
1461 if (VolumeEntry->pszFilesystem)
1462 wcscpy(VolumeEntry->pszFilesystem, szFilesystem);
1463 }
1464 else
1465 {
1466 dwError = GetLastError();
1467 if (dwError == ERROR_UNRECOGNIZED_VOLUME)
1468 {
1469 VolumeEntry->pszFilesystem = RtlAllocateHeap(RtlGetProcessHeap(),
1470 0,
1471 (3 + 1) * sizeof(WCHAR));
1472 if (VolumeEntry->pszFilesystem)
1473 wcscpy(VolumeEntry->pszFilesystem, L"RAW");
1474 }
1475 }
1476
1477 if (GetVolumePathNamesForVolumeNameW(pszVolumeName,
1478 szPathNames,
1479 ARRAYSIZE(szPathNames),
1480 &dwLength))
1481 {
1482 VolumeEntry->DriveLetter = szPathNames[0];
1483 }
1484
1486 &VolumeEntry->ListEntry);
1487}
1488
1489
1492{
1493 HANDLE hVolume = INVALID_HANDLE_VALUE;
1494 WCHAR szVolumeName[MAX_PATH];
1495 ULONG ulVolumeNumber = 0;
1496 BOOL Success;
1497
1499
1501
1502 hVolume = FindFirstVolumeW(szVolumeName, ARRAYSIZE(szVolumeName));
1503 if (hVolume == INVALID_HANDLE_VALUE)
1504 {
1505
1506 return STATUS_UNSUCCESSFUL;
1507 }
1508
1509 AddVolumeToList(ulVolumeNumber++, szVolumeName);
1510
1511 for (;;)
1512 {
1513 Success = FindNextVolumeW(hVolume, szVolumeName, ARRAYSIZE(szVolumeName));
1514 if (!Success)
1515 {
1516 break;
1517 }
1518
1519 AddVolumeToList(ulVolumeNumber++, szVolumeName);
1520 }
1521
1522 FindVolumeClose(hVolume);
1523
1524 return STATUS_SUCCESS;
1525}
1526
1527
1528VOID
1530{
1532 PVOLENTRY VolumeEntry;
1533
1535
1536 /* Release disk and partition info */
1537 while (!IsListEmpty(&VolumeListHead))
1538 {
1540 VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
1541
1542 if (VolumeEntry->pszLabel)
1543 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszLabel);
1544
1545 if (VolumeEntry->pszFilesystem)
1546 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszFilesystem);
1547
1548 if (VolumeEntry->pExtents)
1549 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pExtents);
1550
1551 /* Release disk entry */
1552 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry);
1553 }
1554}
1555
1556
1559 _In_ PDISKENTRY DiskEntry)
1560{
1568 ULONG PartitionCount;
1569 PLIST_ENTRY ListEntry;
1570 PPARTENTRY PartEntry;
1572
1573 DPRINT("WritePartitions() Disk: %lu\n", DiskEntry->DiskNumber);
1574
1575 /* If the disk is not dirty, there is nothing to do */
1576 if (!DiskEntry->Dirty)
1577 return STATUS_SUCCESS;
1578
1580 L"\\Device\\Harddisk%lu\\Partition0",
1581 DiskEntry->DiskNumber);
1583
1585 &Name,
1587 NULL,
1588 NULL);
1589
1593 &Iosb,
1594 0,
1596 if (!NT_SUCCESS(Status))
1597 {
1598 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
1599 return Status;
1600 }
1601
1602 //
1603 // FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize
1604 // the disk in MBR or GPT format in case the disk was not initialized!!
1605 // For this we must ask the user which format to use.
1606 //
1607
1608 /* Save the original partition count to be restored later (see comment below) */
1609 PartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
1610
1611 /* Set the new disk layout and retrieve its updated version with possibly modified partition numbers */
1612 BufferSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
1613 ((PartitionCount - 1) * sizeof(PARTITION_INFORMATION_EX));
1615 NULL,
1616 NULL,
1617 NULL,
1618 &Iosb,
1620 DiskEntry->LayoutBuffer,
1621 BufferSize,
1622 DiskEntry->LayoutBuffer,
1623 BufferSize);
1625
1626 /*
1627 * IOCTL_DISK_SET_DRIVE_LAYOUT calls IoWritePartitionTable(), which converts
1628 * DiskEntry->LayoutBuffer->PartitionCount into a partition *table* count,
1629 * where such a table is expected to enumerate up to 4 partitions:
1630 * partition *table* count == ROUND_UP(PartitionCount, 4) / 4 .
1631 * Due to this we need to restore the original PartitionCount number.
1632 */
1633 DiskEntry->LayoutBuffer->PartitionCount = PartitionCount;
1634
1635 /* Check whether the IOCTL_DISK_SET_DRIVE_LAYOUT call succeeded */
1636 if (!NT_SUCCESS(Status))
1637 {
1638 DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status);
1639 return Status;
1640 }
1641
1642 /* Update the partition numbers */
1643
1644 /* Update the primary partition table */
1645 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
1646 ListEntry != &DiskEntry->PrimaryPartListHead;
1647 ListEntry = ListEntry->Flink)
1648 {
1649 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1650
1651 if (PartEntry->IsPartitioned)
1652 {
1654 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
1655 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
1656 }
1657 }
1658
1659 /* Update the logical partition table */
1660 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
1661 ListEntry != &DiskEntry->LogicalPartListHead;
1662 ListEntry = ListEntry->Flink)
1663 {
1664 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1665
1666 if (PartEntry->IsPartitioned)
1667 {
1669 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
1670 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
1671 }
1672 }
1673
1674 /* The layout has been successfully updated, the disk is not dirty anymore */
1675 DiskEntry->Dirty = FALSE;
1676
1677 return Status;
1678}
1679
1680
1681static
1682BOOLEAN
1685{
1686 if (PartitionInfo->StartingOffset.QuadPart == 0 &&
1687 PartitionInfo->PartitionLength.QuadPart == 0)
1688 {
1689 return TRUE;
1690 }
1691
1692 return FALSE;
1693}
1694
1695
1696static
1697BOOLEAN
1700 IN PDISKENTRY DiskEntry,
1701 IN PPARTENTRY PartEntry)
1702{
1703 if ((PartitionInfo->StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector) &&
1704 (PartitionInfo->PartitionLength.QuadPart == PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector))
1705 {
1706 return TRUE;
1707 }
1708
1709 return FALSE;
1710}
1711
1712
1713ULONG
1715 _In_ PDISKENTRY DiskEntry)
1716{
1718 PPARTENTRY PartEntry;
1719 ULONG Count = 0;
1720
1721 for (Entry = DiskEntry->PrimaryPartListHead.Flink;
1722 Entry != &DiskEntry->PrimaryPartListHead;
1723 Entry = Entry->Flink)
1724 {
1725 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1726 if (PartEntry->IsPartitioned)
1727 Count++;
1728 }
1729
1730 return Count;
1731}
1732
1733
1734static
1735ULONG
1737 _In_ PDISKENTRY DiskEntry)
1738{
1739 PLIST_ENTRY ListEntry;
1740 PPARTENTRY PartEntry;
1741 ULONG Count = 0;
1742
1743 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
1744 ListEntry != &DiskEntry->LogicalPartListHead;
1745 ListEntry = ListEntry->Flink)
1746 {
1747 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1748 if (PartEntry->IsPartitioned)
1749 Count++;
1750 }
1751
1752 return Count;
1753}
1754
1755
1756static
1757BOOLEAN
1759 _In_ PDISKENTRY DiskEntry)
1760{
1761 PDRIVE_LAYOUT_INFORMATION_EX NewLayoutBuffer;
1762 ULONG NewPartitionCount;
1763 ULONG CurrentPartitionCount = 0;
1764 ULONG LayoutBufferSize;
1765 ULONG i;
1766
1767 DPRINT1("ReAllocateLayoutBuffer()\n");
1768
1769 NewPartitionCount = 4 + GetLogicalPartitionCount(DiskEntry) * 4;
1770
1771 if (DiskEntry->LayoutBuffer)
1772 CurrentPartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
1773
1774 DPRINT1("CurrentPartitionCount: %lu ; NewPartitionCount: %lu\n",
1775 CurrentPartitionCount, NewPartitionCount);
1776
1777 if (CurrentPartitionCount == NewPartitionCount)
1778 return TRUE;
1779
1780 LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
1781 ((NewPartitionCount - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION_EX));
1782 NewLayoutBuffer = RtlReAllocateHeap(RtlGetProcessHeap(),
1784 DiskEntry->LayoutBuffer,
1785 LayoutBufferSize);
1786 if (NewLayoutBuffer == NULL)
1787 {
1788 DPRINT1("Failed to allocate the new layout buffer (size: %lu)\n", LayoutBufferSize);
1789 return FALSE;
1790 }
1791
1792 NewLayoutBuffer->PartitionCount = NewPartitionCount;
1793
1794 /* If the layout buffer grows, make sure the new (empty) entries are written to the disk */
1795 if (NewPartitionCount > CurrentPartitionCount)
1796 {
1797 for (i = CurrentPartitionCount; i < NewPartitionCount; i++)
1798 {
1799 NewLayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
1800 }
1801 }
1802
1803 DiskEntry->LayoutBuffer = NewLayoutBuffer;
1804
1805 return TRUE;
1806}
1807
1808
1809VOID
1811 _In_ PDISKENTRY DiskEntry)
1812{
1815 PLIST_ENTRY ListEntry;
1816 PPARTENTRY PartEntry;
1817 LARGE_INTEGER HiddenSectors64;
1818 ULONG Index;
1820
1821 DPRINT1("UpdateDiskLayout()\n");
1822
1823 /* Resize the layout buffer if necessary */
1824 if (ReAllocateLayoutBuffer(DiskEntry) == FALSE)
1825 {
1826 DPRINT("ReAllocateLayoutBuffer() failed.\n");
1827 return;
1828 }
1829
1830 DiskEntry->LayoutBuffer->PartitionStyle = PARTITION_STYLE_MBR;
1831
1832 /* Update the primary partition table */
1833 Index = 0;
1834 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
1835 ListEntry != &DiskEntry->PrimaryPartListHead;
1836 ListEntry = ListEntry->Flink)
1837 {
1838 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1839
1840 if (PartEntry->IsPartitioned)
1841 {
1843
1844 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
1845 PartEntry->PartitionIndex = Index;
1846
1847 /* Reset the current partition number only for newly-created (unmounted) partitions */
1848 if (PartEntry->New)
1849 PartEntry->PartitionNumber = 0;
1850
1852
1853 if (!IsSamePrimaryLayoutEntry(PartitionInfo, DiskEntry, PartEntry))
1854 {
1855 DPRINT1("Updating primary partition entry %lu\n", Index);
1856
1857 PartitionInfo->PartitionStyle = PARTITION_STYLE_MBR;
1858 PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
1859 PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
1860 PartitionInfo->Mbr.HiddenSectors = PartEntry->StartSector.LowPart;
1861 PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
1862 PartitionInfo->Mbr.PartitionType = PartEntry->PartitionType;
1863 PartitionInfo->Mbr.BootIndicator = PartEntry->BootIndicator;
1864 PartitionInfo->Mbr.RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
1865 PartitionInfo->RewritePartition = TRUE;
1866 }
1867
1868 if (!IsContainerPartition(PartEntry->PartitionType))
1870
1871 Index++;
1872 }
1873 }
1874
1875 ASSERT(Index <= 4);
1876
1877 /* Update the logical partition table */
1878 Index = 4;
1879 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
1880 ListEntry != &DiskEntry->LogicalPartListHead;
1881 ListEntry = ListEntry->Flink)
1882 {
1883 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1884
1885 if (PartEntry->IsPartitioned)
1886 {
1888
1889 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
1890 PartEntry->PartitionIndex = Index;
1891
1892 /* Reset the current partition number only for newly-created (unmounted) partitions */
1893 if (PartEntry->New)
1894 PartEntry->PartitionNumber = 0;
1895
1897
1898 DPRINT1("Updating logical partition entry %lu\n", Index);
1899
1900 PartitionInfo->PartitionStyle = PARTITION_STYLE_MBR;
1901 PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
1902 PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
1903 PartitionInfo->Mbr.HiddenSectors = DiskEntry->SectorAlignment;
1904 PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
1905 PartitionInfo->Mbr.PartitionType = PartEntry->PartitionType;
1906 PartitionInfo->Mbr.BootIndicator = FALSE;
1907 PartitionInfo->Mbr.RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
1908 PartitionInfo->RewritePartition = TRUE;
1909
1910 /* Fill the link entry of the previous partition entry */
1911 if (LinkInfo != NULL)
1912 {
1914 LinkInfo->StartingOffset.QuadPart = (PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
1915 LinkInfo->PartitionLength.QuadPart = (PartEntry->StartSector.QuadPart + DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
1916 HiddenSectors64.QuadPart = PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment - DiskEntry->ExtendedPartition->StartSector.QuadPart;
1917 LinkInfo->Mbr.HiddenSectors = HiddenSectors64.LowPart;
1918 LinkInfo->PartitionNumber = 0;
1920 LinkInfo->Mbr.BootIndicator = FALSE;
1921 LinkInfo->Mbr.RecognizedPartition = FALSE;
1922 LinkInfo->RewritePartition = TRUE;
1923 }
1924
1925 /* Save a pointer to the link entry of the current partition entry */
1926 LinkInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index + 1];
1927
1929 Index += 4;
1930 }
1931 }
1932
1933 /* Wipe unused primary partition entries */
1934 for (Index = GetPrimaryPartitionCount(DiskEntry); Index < 4; Index++)
1935 {
1936 DPRINT1("Primary partition entry %lu\n", Index);
1937
1938 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
1939
1941 {
1942 DPRINT1("Wiping primary partition entry %lu\n", Index);
1943
1944 PartitionInfo->PartitionStyle = PARTITION_STYLE_MBR;
1945 PartitionInfo->StartingOffset.QuadPart = 0;
1946 PartitionInfo->PartitionLength.QuadPart = 0;
1947 PartitionInfo->Mbr.HiddenSectors = 0;
1948 PartitionInfo->PartitionNumber = 0;
1949 PartitionInfo->Mbr.PartitionType = PARTITION_ENTRY_UNUSED;
1950 PartitionInfo->Mbr.BootIndicator = FALSE;
1951 PartitionInfo->Mbr.RecognizedPartition = FALSE;
1952 PartitionInfo->RewritePartition = TRUE;
1953 }
1954 }
1955
1956 /* Wipe unused logical partition entries */
1957 for (Index = 4; Index < DiskEntry->LayoutBuffer->PartitionCount; Index++)
1958 {
1959 if (Index % 4 >= 2)
1960 {
1961 DPRINT1("Logical partition entry %lu\n", Index);
1962
1963 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
1964
1966 {
1967 DPRINT1("Wiping partition entry %lu\n", Index);
1968
1969 PartitionInfo->PartitionStyle = PARTITION_STYLE_MBR;
1970 PartitionInfo->StartingOffset.QuadPart = 0;
1971 PartitionInfo->PartitionLength.QuadPart = 0;
1972 PartitionInfo->Mbr.HiddenSectors = 0;
1973 PartitionInfo->PartitionNumber = 0;
1974 PartitionInfo->Mbr.PartitionType = PARTITION_ENTRY_UNUSED;
1975 PartitionInfo->Mbr.BootIndicator = FALSE;
1976 PartitionInfo->Mbr.RecognizedPartition = FALSE;
1977 PartitionInfo->RewritePartition = TRUE;
1978 }
1979 }
1980 }
1981
1982 DiskEntry->Dirty = TRUE;
1983}
1984
1985
1988 _In_ PPARTENTRY PartEntry)
1989{
1990 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
1991 PPARTENTRY PrevPartEntry;
1992 PLIST_ENTRY ListHead;
1993
1994 if (PartEntry->LogicalPartition)
1995 ListHead = &DiskEntry->LogicalPartListHead;
1996 else
1997 ListHead = &DiskEntry->PrimaryPartListHead;
1998
1999 if (PartEntry->ListEntry.Blink != ListHead)
2000 {
2001 PrevPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Blink,
2002 PARTENTRY,
2003 ListEntry);
2004 if (!PrevPartEntry->IsPartitioned)
2005 {
2006 ASSERT(PrevPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
2007 return PrevPartEntry;
2008 }
2009 }
2010
2011 return NULL;
2012}
2013
2014
2017 _In_ PPARTENTRY PartEntry)
2018{
2019 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2020 PPARTENTRY NextPartEntry;
2021 PLIST_ENTRY ListHead;
2022
2023 if (PartEntry->LogicalPartition)
2024 ListHead = &DiskEntry->LogicalPartListHead;
2025 else
2026 ListHead = &DiskEntry->PrimaryPartListHead;
2027
2028 if (PartEntry->ListEntry.Flink != ListHead)
2029 {
2030 NextPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Flink,
2031 PARTENTRY,
2032 ListEntry);
2033 if (!NextPartEntry->IsPartitioned)
2034 {
2035 ASSERT(NextPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
2036 return NextPartEntry;
2037 }
2038 }
2039
2040 return NULL;
2041}
2042
2043
2046 _In_ PPARTENTRY PartEntry)
2047{
2049 NTSTATUS LockStatus;
2053 HANDLE PartitionHandle;
2055
2056 /* Check whether the partition is valid and was mounted by the system */
2057 if (!PartEntry->IsPartitioned ||
2058 IsContainerPartition(PartEntry->PartitionType) ||
2059 !IsRecognizedPartition(PartEntry->PartitionType) ||
2060 PartEntry->FormatState == UnknownFormat ||
2061 // NOTE: If FormatState == Unformatted but *FileSystem != 0 this means
2062 // it has been usually mounted with RawFS and thus needs to be dismounted.
2063/* !*PartEntry->FileSystem || */
2064 PartEntry->PartitionNumber == 0)
2065 {
2066 /* The partition is not mounted, so just return success */
2067 return STATUS_SUCCESS;
2068 }
2069
2070 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
2071
2072 /* Open the volume */
2074 L"\\Device\\Harddisk%lu\\Partition%lu",
2075 PartEntry->DiskEntry->DiskNumber,
2076 PartEntry->PartitionNumber);
2078
2080 &Name,
2082 NULL,
2083 NULL);
2084
2085 Status = NtOpenFile(&PartitionHandle,
2091 if (!NT_SUCCESS(Status))
2092 {
2093 DPRINT1("ERROR: Cannot open volume %wZ for dismounting! (Status 0x%lx)\n", &Name, Status);
2094 return Status;
2095 }
2096
2097 /* Lock the volume */
2098 LockStatus = NtFsControlFile(PartitionHandle,
2099 NULL,
2100 NULL,
2101 NULL,
2104 NULL,
2105 0,
2106 NULL,
2107 0);
2108 if (!NT_SUCCESS(LockStatus))
2109 {
2110 DPRINT1("WARNING: Failed to lock volume! Operations may fail! (Status 0x%lx)\n", LockStatus);
2111 }
2112
2113 /* Dismount the volume */
2114 Status = NtFsControlFile(PartitionHandle,
2115 NULL,
2116 NULL,
2117 NULL,
2120 NULL,
2121 0,
2122 NULL,
2123 0);
2124 if (!NT_SUCCESS(Status))
2125 {
2126 DPRINT1("Failed to unmount volume (Status 0x%lx)\n", Status);
2127 }
2128
2129 /* Unlock the volume */
2130 LockStatus = NtFsControlFile(PartitionHandle,
2131 NULL,
2132 NULL,
2133 NULL,
2136 NULL,
2137 0,
2138 NULL,
2139 0);
2140 if (!NT_SUCCESS(LockStatus))
2141 {
2142 DPRINT1("Failed to unlock volume (Status 0x%lx)\n", LockStatus);
2143 }
2144
2145 /* Close the volume */
2146 NtClose(PartitionHandle);
2147
2148 return Status;
2149}
2150
2151
2154 _In_ PPARTENTRY PartEntry)
2155{
2157 PVOLENTRY VolumeEntry;
2158 ULONG i;
2159
2160 if ((PartEntry == NULL) ||
2161 (PartEntry->DiskEntry == NULL))
2162 return NULL;
2163
2165 while (Entry != &VolumeListHead)
2166 {
2167 VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
2168
2169 if (VolumeEntry->pExtents == NULL)
2170 return NULL;
2171
2172 for (i = 0; i < VolumeEntry->pExtents->NumberOfDiskExtents; i++)
2173 {
2174 if (VolumeEntry->pExtents->Extents[i].DiskNumber == PartEntry->DiskEntry->DiskNumber)
2175 {
2176 if ((VolumeEntry->pExtents->Extents[i].StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * PartEntry->DiskEntry->BytesPerSector) &&
2177 (VolumeEntry->pExtents->Extents[i].ExtentLength.QuadPart == PartEntry->SectorCount.QuadPart * PartEntry->DiskEntry->BytesPerSector))
2178 return VolumeEntry;
2179 }
2180 }
2181
2182 Entry = Entry->Flink;
2183 }
2184
2185 return NULL;
2186}
2187
2188
2189VOID
2191 _In_ PVOLENTRY VolumeEntry)
2192{
2193 if (VolumeEntry == NULL)
2194 return;
2195
2196 if (VolumeEntry == CurrentVolume)
2198
2199 RemoveEntryList(&VolumeEntry->ListEntry);
2200
2201 if (VolumeEntry->pszLabel)
2202 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszLabel);
2203
2204 if (VolumeEntry->pszFilesystem)
2205 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszFilesystem);
2206
2207 if (VolumeEntry->pExtents)
2208 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pExtents);
2209
2210 /* Release disk entry */
2211 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry);
2212}
2213
2214/* EOF */
unsigned char BOOLEAN
@ Identifier
Definition: asmpp.cpp:95
LONG NTSTATUS
Definition: precomp.h:26
HANDLE ProcessHeap
Definition: servman.c:15
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define DPRINT1
Definition: precomp.h:8
#define PARTITION_IFS
Definition: disk.h:78
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:71
#define PARTITION_XINT13
Definition: disk.h:82
#define PARTITION_FAT32
Definition: disk.h:80
#define PARTITION_FAT_12
Definition: disk.h:72
#define PARTITION_EXTENDED
Definition: disk.h:76
#define PARTITION_HUGE
Definition: disk.h:77
#define PARTITION_FAT_16
Definition: disk.h:75
#define PARTITION_GPT
Definition: disk.h:90
#define PARTITION_FAT32_XINT13
Definition: disk.h:81
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
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
wcscpy
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define BufferSize
Definition: mmc.h:75
LPWSTR Name
Definition: desk.c:124
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
@ VOLUME_TYPE_UNKNOWN
Definition: diskpart.h:98
@ VOLUME_TYPE_REMOVABLE
Definition: diskpart.h:97
@ VOLUME_TYPE_CDROM
Definition: diskpart.h:95
@ VOLUME_TYPE_PARTITION
Definition: diskpart.h:96
PDISKENTRY CurrentDisk
Definition: partlist.c:76
@ Preformatted
Definition: diskpart.h:89
@ LogicalPartition
Definition: disksup.c:48
#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 INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define FILE_SHARE_READ
Definition: compat.h:136
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static DWORD DWORD * dwLength
Definition: fusion.c:86
DWORD WINAPI QueryDosDeviceW(LPCWSTR lpDeviceName, LPWSTR lpTargetPath, DWORD ucchMax)
Definition: dosdev.c:542
BOOL WINAPI FindNextVolumeW(IN HANDLE handle, IN LPWSTR volume, IN DWORD len)
Definition: volume.c:1082
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
HANDLE WINAPI FindFirstVolumeW(IN LPWSTR volume, IN DWORD len)
Definition: volume.c:660
BOOL WINAPI FindVolumeClose(IN HANDLE hFindVolume)
Definition: volume.c:741
BOOL WINAPI GetVolumePathNamesForVolumeNameW(IN LPCWSTR lpszVolumeName, IN LPWSTR lpszVolumePathNames, IN DWORD cchBufferLength, OUT PDWORD lpcchReturnLength)
Definition: volume.c:1227
static const WCHAR Signature[]
Definition: parser.c:141
#define L(x)
Definition: resources.c:13
return Iosb
Definition: create.c:4403
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
@ Success
Definition: eventcreate.c:712
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define IOCTL_DISK_GET_DRIVE_LAYOUT_EX
Definition: ntddk_ex.h:207
@ SystemDeviceInformation
Definition: ntddk_ex.h:18
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
_Must_inspect_result_ _Out_ PHANDLE VolumeHandle
Definition: fltkernel.h:2283
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
@ FileFsDeviceInformation
Definition: from_kernel.h:222
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
union Alignment_ Alignment
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
#define DbgPrint
Definition: hal.h:12
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T) __WINE_ALLOC_SIZE(4) __WINE_DEALLOC(RtlFreeHeap
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define REG_SZ
Definition: layer.c:22
struct _BIOSDISKENTRY * PBIOSDISKENTRY
@ UnknownFormat
Definition: partlist.h:36
@ Unformatted
Definition: partlist.h:34
struct _BIOSDISKENTRY BIOSDISKENTRY
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ASSERT(a)
Definition: mode.c:44
struct _PARTITION_INFORMATION_EX PARTITION_INFORMATION_EX
@ PARTITION_STYLE_GPT
Definition: imports.h:202
@ PARTITION_STYLE_MBR
Definition: imports.h:201
#define ULL(a, b)
Definition: format_msg.c:27
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4210
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4211
#define _In_
Definition: no_sal2.h:158
int Count
Definition: noreturn.cpp:7
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 FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_READ_DATA
Definition: nt_native.h:628
#define FSCTL_LOCK_VOLUME
Definition: nt_native.h:832
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
NTSYSAPI NTSTATUS NTAPI NtDeviceIoControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
#define RTL_REGISTRY_DEVICEMAP
Definition: nt_native.h:165
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#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 FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define REG_FULL_RESOURCE_DESCRIPTOR
Definition: nt_native.h:1506
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:321
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:342
@ RemovableMedia
Definition: ntdddisk.h:382
@ FixedMedia
Definition: ntdddisk.h:383
#define IOCTL_DISK_SET_DRIVE_LAYOUT_EX
Definition: ntdddisk.h:208
struct _VOLUME_DISK_EXTENTS VOLUME_DISK_EXTENTS
struct _DISK_EXTENT DISK_EXTENT
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
Definition: ntddvol.h:44
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned short USHORT
Definition: pedump.c:61
#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
struct _CM_FULL_RESOURCE_DESCRIPTOR * PCM_FULL_RESOURCE_DESCRIPTOR
#define CmResourceTypeDeviceSpecific
Definition: restypes.h:108
#define IOCTL_SCSI_GET_ADDRESS
Definition: scsi_port.h:52
#define memset(x, y, z)
Definition: compat.h:39
IN HANDLE DstPath
Definition: fsutil.h:81
static VOID AddPartitionToDisk(IN ULONG DiskNumber, IN PDISKENTRY DiskEntry, IN ULONG PartitionIndex, IN BOOLEAN LogicalPartition)
Definition: partlist.c:985
static VOID GetDriverName(IN PDISKENTRY DiskEntry)
Definition: partlist.c:105
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2589
VOID NTAPI DestroyPartitionList(IN PPARTLIST List)
Definition: partlist.c:2074
static BOOLEAN IsSamePrimaryLayoutEntry(_In_ PPARTITION_INFORMATION PartitionInfo, _In_ PPARTENTRY PartEntry)
Definition: partlist.c:2492
ULONGLONG AlignDown(IN ULONGLONG Value, IN ULONG Alignment)
Definition: partlist.c:67
static NTSTATUS NTAPI DiskConfigurationDataQueryRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: partlist.c:237
#define ROOT_NAME
static VOID AddDiskToList(IN HANDLE FileHandle, IN ULONG DiskNumber, IN PPARTLIST List)
Definition: partlist.c:1445
static VOID ScanForUnpartitionedDiskSpace(IN PDISKENTRY DiskEntry)
Definition: partlist.c:1095
static NTSTATUS NTAPI SystemConfigurationDataQueryRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: partlist.c:280
PPARTLIST NTAPI CreatePartitionList(VOID)
Definition: partlist.c:1988
static VOID EnumerateBiosDiskEntries(IN PPARTLIST PartList)
Definition: partlist.c:327
static BOOLEAN IsEmptyLayoutEntry(_In_ PPARTITION_INFORMATION PartitionInfo)
Definition: partlist.c:2483
static BOOLEAN ReAllocateLayoutBuffer(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2537
#define GetLogicalPartitionCount(DiskEntry)
Definition: partlist.c:2530
#define GetPrimaryPartitionCount(DiskEntry)
Definition: partlist.c:2527
static NTSTATUS NTAPI DiskIdentifierQueryRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: partlist.c:207
NTSTATUS WritePartitions(IN PDISKENTRY DiskEntry)
Definition: partlist.c:3593
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
NTSTATUS NTAPI NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
#define DPRINT
Definition: sndvol32.h:73
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
base of all file and directory entries
Definition: entries.h:83
BOOLEAN Recognized
Definition: diskpart.h:145
ULONG DiskNumber
Definition: partlist.h:162
ULONG Checksum
Definition: partlist.h:164
ULONG Signature
Definition: partlist.h:163
CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry
Definition: partlist.h:166
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: restypes.h:144
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@430::@439 DeviceSpecificData
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@430 u
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: restypes.h:100
ULONG SectorAlignment
Definition: partlist.h:116
ULONG BiosDiskNumber
Definition: diskpart.h:165
ULARGE_INTEGER SectorCount
Definition: partlist.h:115
UNICODE_STRING DriverName
Definition: partlist.h:141
ULONG SectorsPerTrack
Definition: partlist.h:112
USHORT TargetId
Definition: diskpart.h:172
PPARTENTRY ExtendedPartition
Definition: partlist.h:153
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:171
BOOLEAN BiosFound
Definition: partlist.h:120
ULONGLONG Cylinders
Definition: partlist.h:110
USHORT Lun
Definition: diskpart.h:173
USHORT Port
Definition: partlist.h:131
DWORD PartitionStyle
Definition: diskpart.h:179
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
ULONG DiskNumber
Definition: ntddvol.h:48
LARGE_INTEGER StartingOffset
Definition: ntddvol.h:49
LARGE_INTEGER ExtentLength
Definition: ntddvol.h:50
MEDIA_TYPE MediaType
Definition: ntdddisk.h:401
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:400
ULONG TracksPerCylinder
Definition: ntdddisk.h:402
ULONG SectorsPerTrack
Definition: ntdddisk.h:403
ULONG BytesPerSector
Definition: ntdddisk.h:404
PARTITION_INFORMATION PartitionEntry[1]
Definition: ntdddisk.h:421
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
BOOLEAN IsPartitioned
Definition: partlist.h:82
UCHAR PartitionType
Definition: partlist.h:73
BOOLEAN New
Definition: partlist.h:85
ULARGE_INTEGER SectorCount
Definition: partlist.h:70
BOOLEAN BootIndicator
Definition: partlist.h:72
struct _DISKENTRY * DiskEntry
Definition: partlist.h:66
BOOLEAN LogicalPartition
Definition: partlist.h:79
FORMATSTATE FormatState
Definition: diskpart.h:119
ULONG OnDiskPartitionNumber
Definition: partlist.h:74
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
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
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:408
LARGE_INTEGER PartitionLength
Definition: ntdddisk.h:409
BOOLEAN RewritePartition
Definition: ntdddisk.h:415
UCHAR BootCode[440]
Definition: partlist.h:216
PARTITION Partition[PARTITION_TBL_SIZE]
Definition: partlist.h:219
unsigned char PartitionType
Definition: partlist.h:206
unsigned char EndingSector
Definition: partlist.h:208
unsigned char BootFlags
Definition: partlist.h:202
unsigned char StartingHead
Definition: partlist.h:203
unsigned int StartingBlock
Definition: partlist.h:210
unsigned char EndingHead
Definition: partlist.h:207
unsigned char EndingCylinder
Definition: partlist.h:209
unsigned int SectorCount
Definition: partlist.h:211
unsigned char StartingSector
Definition: partlist.h:204
unsigned char StartingCylinder
Definition: partlist.h:205
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
UCHAR PathId
Definition: scsi_port.h:149
UCHAR TargetId
Definition: scsi_port.h:150
UCHAR PortNumber
Definition: scsi_port.h:148
$ULONG LowPart
Definition: ntbasedef.h:581
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
USHORT MaximumLength
Definition: env_spec_w32.h:370
PVOLUME_DISK_EXTENTS pExtents
Definition: diskpart.h:207
ULONG VolumeNumber
Definition: diskpart.h:196
PWSTR pszFilesystem
Definition: diskpart.h:203
WCHAR VolumeName[MAX_PATH]
Definition: diskpart.h:197
LIST_ENTRY ListEntry
Entry in VolumesList.
Definition: partlist.h:45
PWSTR pszLabel
Definition: diskpart.h:202
WCHAR DeviceName[MAX_PATH]
Definition: diskpart.h:198
WCHAR DriveLetter
Definition: diskpart.h:200
DISK_EXTENT Extents[1]
Definition: ntddvol.h:55
ULONG NumberOfDiskExtents
Definition: ntddvol.h:54
VOID RemoveVolume(_In_ PVOLENTRY VolumeEntry)
Definition: partlist.c:2190
LIST_ENTRY VolumeListHead
Definition: partlist.c:74
static VOID GetVolumeType(_In_ HANDLE VolumeHandle, _In_ PVOLENTRY VolumeEntry)
Definition: partlist.c:1335
struct _PARTITION * PPARTITION
#define PARTITION_LINUX
Definition: partlist.c:36
LIST_ENTRY BiosDiskListHead
Definition: partlist.c:73
PPARTENTRY GetPrevUnpartitionedEntry(_In_ PPARTENTRY PartEntry)
Definition: partlist.c:1987
VOID DestroyVolumeList(VOID)
Definition: partlist.c:1529
struct _PARTITION_SECTOR * PPARTITION_SECTOR
#define PARTITION_TBL_SIZE
Definition: partlist.c:38
static VOID AddVolumeToList(ULONG ulVolumeNumber, PWSTR pszVolumeName)
Definition: partlist.c:1375
NTSTATUS CreateVolumeList(VOID)
Definition: partlist.c:1491
VOID ReadLayoutBuffer(_In_ HANDLE FileHandle, _In_ PDISKENTRY DiskEntry)
Definition: partlist.c:816
LIST_ENTRY DiskListHead
Definition: partlist.c:72
struct _PARTITION_SECTOR PARTITION_SECTOR
PVOLENTRY CurrentVolume
Definition: partlist.c:78
PPARTENTRY CurrentPartition
Definition: partlist.c:77
PVOLENTRY GetVolumeFromPartition(_In_ PPARTENTRY PartEntry)
Definition: partlist.c:2153
PPARTENTRY GetNextUnpartitionedEntry(_In_ PPARTENTRY PartEntry)
Definition: partlist.c:2016
#define MBR_MAGIC
Definition: partlist.c:40
static VOID GetVolumeExtents(_In_ HANDLE VolumeHandle, _In_ PVOLENTRY VolumeEntry)
Definition: partlist.c:1269
struct _PARTITION PARTITION
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
#define ANYSIZE_ARRAY
Definition: typedefs.h:46
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
NTSTATUS DismountVolume(_Inout_ PVOLINFO Volume, _In_ BOOLEAN Force)
Attempts to dismount the designated volume.
Definition: volutil.c:152
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2705
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
_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 ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:275
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
#define ERROR_UNRECOGNIZED_VOLUME
Definition: winerror.h:908
struct _CM_DISK_GEOMETRY_DEVICE_DATA * PCM_DISK_GEOMETRY_DEVICE_DATA
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2105
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2061
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180