ReactOS 0.4.15-dev-7788-g1ad9096
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#include <pshpack1.h>
41
42typedef struct _PARTITION
43{
44 unsigned char BootFlags; /* bootable? 0=no, 128=yes */
45 unsigned char StartingHead; /* beginning head number */
46 unsigned char StartingSector; /* beginning sector number */
47 unsigned char StartingCylinder; /* 10 bit nmbr, with high 2 bits put in begsect */
48 unsigned char PartitionType; /* Operating System type indicator code */
49 unsigned char EndingHead; /* ending head number */
50 unsigned char EndingSector; /* ending sector number */
51 unsigned char EndingCylinder; /* also a 10 bit nmbr, with same high 2 bit trick */
52 unsigned int StartingBlock; /* first sector relative to start of disk */
53 unsigned int SectorCount; /* number of sectors in partition */
55
56typedef struct _PARTITION_SECTOR
57{
58 UCHAR BootCode[440]; /* 0x000 */
59 ULONG Signature; /* 0x1B8 */
60 UCHAR Reserved[2]; /* 0x1BC */
62 USHORT Magic; /* 0x1FE */
64
65#include <poppack.h>
66
67
68/* GLOBALS ********************************************************************/
69
73
77
78
79/* FUNCTIONS ******************************************************************/
80
85{
86 ULONGLONG Temp;
87
88 Temp = Value / Alignment;
89
90 return Temp * Alignment;
91}
92
93static
94VOID
96 PDISKENTRY DiskEntry)
97{
99 WCHAR KeyName[32];
101
103 NULL);
104
106 L"\\Scsi\\Scsi Port %lu",
107 DiskEntry->Port);
108
110 sizeof(QueryTable));
111
112 QueryTable[0].Name = L"Driver";
114 QueryTable[0].EntryContext = &DiskEntry->DriverName;
115
117 KeyName,
119 NULL,
120 NULL);
121 if (!NT_SUCCESS(Status))
122 {
123 DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
124 }
125}
126
127static
129NTAPI
137{
138 PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
139 UNICODE_STRING NameU;
140
141 if (ValueType == REG_SZ &&
142 ValueLength == 20 * sizeof(WCHAR))
143 {
144 NameU.Buffer = (PWCHAR)ValueData;
145 NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR);
146 RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum);
147
148 NameU.Buffer = (PWCHAR)ValueData + 9;
149 RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature);
150
151 return STATUS_SUCCESS;
152 }
153
154 return STATUS_UNSUCCESSFUL;
155}
156
157static
159NTAPI
167{
168 PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
169 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
171 ULONG i;
172
175 return STATUS_UNSUCCESSFUL;
176
177 FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
178
179 /* Hm. Version and Revision are not set on Microsoft Windows XP... */
180#if 0
181 if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
182 FullResourceDescriptor->PartialResourceList.Revision != 1)
183 return STATUS_UNSUCCESSFUL;
184#endif
185
186 for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
187 {
190 continue;
191
192 DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1];
193 BiosDiskEntry->DiskGeometry = *DiskGeometry;
194
195 return STATUS_SUCCESS;
196 }
197
198 return STATUS_UNSUCCESSFUL;
199}
200
201static
203NTAPI
211{
212 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
214 ULONG i;
215
218 return STATUS_UNSUCCESSFUL;
219
220 FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
221
222 /* Hm. Version and Revision are not set on Microsoft Windows XP... */
223#if 0
224 if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
225 FullResourceDescriptor->PartialResourceList.Revision != 1)
226 return STATUS_UNSUCCESSFUL;
227#endif
228
229 for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
230 {
232 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize % sizeof(CM_INT13_DRIVE_PARAMETER) != 0)
233 continue;
234
235 *Int13Drives = (CM_INT13_DRIVE_PARAMETER*)RtlAllocateHeap(RtlGetProcessHeap(), 0,
236 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
237 if (*Int13Drives == NULL)
238 return STATUS_NO_MEMORY;
239
240 memcpy(*Int13Drives,
241 &FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1],
242 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
243 return STATUS_SUCCESS;
244 }
245
246 return STATUS_UNSUCCESSFUL;
247}
248
249
250#define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
251
252static
253VOID
255{
257 WCHAR Name[120];
258 ULONG AdapterCount;
259 ULONG DiskCount;
261 PCM_INT13_DRIVE_PARAMETER Int13Drives;
262 PBIOSDISKENTRY BiosDiskEntry;
263
264 memset(QueryTable, 0, sizeof(QueryTable));
265
266 QueryTable[1].Name = L"Configuration Data";
268 Int13Drives = NULL;
270 L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
271 &QueryTable[1],
272 (PVOID)&Int13Drives,
273 NULL);
274 if (!NT_SUCCESS(Status))
275 {
276 DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status);
277 return;
278 }
279
280 AdapterCount = 0;
281 while (1)
282 {
284 L"%s\\%lu", ROOT_NAME, AdapterCount);
286 Name,
287 &QueryTable[2],
288 NULL,
289 NULL);
290 if (!NT_SUCCESS(Status))
291 {
292 break;
293 }
294
296 L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount);
298 Name,
299 &QueryTable[2],
300 NULL,
301 NULL);
302 if (NT_SUCCESS(Status))
303 {
304 while (1)
305 {
307 L"%s\\%lu\\DiskController\\0", ROOT_NAME, AdapterCount);
309 Name,
310 &QueryTable[2],
311 NULL,
312 NULL);
313 if (!NT_SUCCESS(Status))
314 {
315 RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
316 return;
317 }
318
320 L"%s\\%lu\\DiskController\\0\\DiskPeripheral", ROOT_NAME, AdapterCount);
322 Name,
323 &QueryTable[2],
324 NULL,
325 NULL);
326 if (NT_SUCCESS(Status))
327 {
328 QueryTable[0].Name = L"Identifier";
330 QueryTable[1].Name = L"Configuration Data";
332
333 DiskCount = 0;
334 while (1)
335 {
336 BiosDiskEntry = (BIOSDISKENTRY*)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY));
337 if (BiosDiskEntry == NULL)
338 {
339 break;
340 }
341
343 L"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, DiskCount);
345 Name,
347 (PVOID)BiosDiskEntry,
348 NULL);
349 if (!NT_SUCCESS(Status))
350 {
351 RtlFreeHeap(RtlGetProcessHeap(), 0, BiosDiskEntry);
352 break;
353 }
354
355 BiosDiskEntry->DiskNumber = DiskCount;
356 BiosDiskEntry->Recognized = FALSE;
357
358 if (DiskCount < Int13Drives[0].NumberDrives)
359 {
360 BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount];
361 }
362 else
363 {
364 DPRINT1("Didn't find int13 drive datas for disk %u\n", DiskCount);
365 }
366
367 InsertTailList(&BiosDiskListHead, &BiosDiskEntry->ListEntry);
368
369 DPRINT("DiskNumber: %lu\n", BiosDiskEntry->DiskNumber);
370 DPRINT("Signature: %08lx\n", BiosDiskEntry->Signature);
371 DPRINT("Checksum: %08lx\n", BiosDiskEntry->Checksum);
372 DPRINT("BytesPerSector: %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector);
373 DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders);
374 DPRINT("NumberOfHeads: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads);
375 DPRINT("DriveSelect: %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect);
376 DPRINT("MaxCylinders: %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders);
377 DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack);
378 DPRINT("MaxHeads: %d\n", BiosDiskEntry->Int13DiskData.MaxHeads);
379 DPRINT("NumberDrives: %d\n", BiosDiskEntry->Int13DiskData.NumberDrives);
380
381 DiskCount++;
382 }
383 }
384
385 RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
386 return;
387 }
388 }
389
390 AdapterCount++;
391 }
392
393 RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
394}
395
396
397static
398VOID
400 ULONG DiskNumber,
401 PDISKENTRY DiskEntry,
402 ULONG PartitionIndex,
404{
406 PPARTENTRY PartEntry;
407
408 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
409 if (PartitionInfo->PartitionType == 0 ||
411 return;
412
413 PartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
415 sizeof(PARTENTRY));
416 if (PartEntry == NULL)
417 {
418 return;
419 }
420
421 PartEntry->DiskEntry = DiskEntry;
422
423 PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
424 PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
425
426 PartEntry->BootIndicator = PartitionInfo->BootIndicator;
427 PartEntry->PartitionType = PartitionInfo->PartitionType;
428
430 PartEntry->IsPartitioned = TRUE;
431 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
432 PartEntry->PartitionIndex = PartitionIndex;
433
434 if (IsContainerPartition(PartEntry->PartitionType))
435 {
436 PartEntry->FormatState = Unformatted;
437
438 if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
439 DiskEntry->ExtendedPartition = PartEntry;
440 }
441 else if ((PartEntry->PartitionType == PARTITION_FAT_12) ||
442 (PartEntry->PartitionType == PARTITION_FAT_16) ||
443 (PartEntry->PartitionType == PARTITION_HUGE) ||
444 (PartEntry->PartitionType == PARTITION_XINT13) ||
445 (PartEntry->PartitionType == PARTITION_FAT32) ||
447 {
448#if 0
449 if (CheckFatFormat())
450 {
451 PartEntry->FormatState = Preformatted;
452 }
453 else
454 {
455 PartEntry->FormatState = Unformatted;
456 }
457#endif
458 PartEntry->FormatState = Preformatted;
459 }
460 else if (PartEntry->PartitionType == PARTITION_LINUX)
461 {
462#if 0
463 if (CheckExt2Format())
464 {
465 PartEntry->FormatState = Preformatted;
466 }
467 else
468 {
469 PartEntry->FormatState = Unformatted;
470 }
471#endif
472 PartEntry->FormatState = Preformatted;
473 }
474 else if (PartEntry->PartitionType == PARTITION_IFS)
475 {
476#if 0
477 if (CheckNtfsFormat())
478 {
479 PartEntry->FormatState = Preformatted;
480 }
481 else if (CheckHpfsFormat())
482 {
483 PartEntry->FormatState = Preformatted;
484 }
485 else
486 {
487 PartEntry->FormatState = Unformatted;
488 }
489#endif
490 PartEntry->FormatState = Preformatted;
491 }
492 else
493 {
494 PartEntry->FormatState = UnknownFormat;
495 }
496
499 &PartEntry->ListEntry);
500 else
502 &PartEntry->ListEntry);
503}
504
505
506static
507VOID
509 PDISKENTRY DiskEntry)
510{
511 ULONGLONG LastStartSector;
512 ULONGLONG LastSectorCount;
513 ULONGLONG LastUnusedSectorCount;
514 PPARTENTRY PartEntry;
515 PPARTENTRY NewPartEntry;
517
518 DPRINT("ScanForUnpartitionedDiskSpace()\n");
519
520 if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
521 {
522 DPRINT1("No primary partition!\n");
523
524 /* Create a partition table that represents the empty disk */
525 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
527 sizeof(PARTENTRY));
528 if (NewPartEntry == NULL)
529 return;
530
531 NewPartEntry->DiskEntry = DiskEntry;
532
533 NewPartEntry->IsPartitioned = FALSE;
534 NewPartEntry->StartSector.QuadPart = (ULONGLONG)DiskEntry->SectorAlignment;
535 NewPartEntry->SectorCount.QuadPart = AlignDown(DiskEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment) -
536 NewPartEntry->StartSector.QuadPart;
537
538 DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
539 DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
540 DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
541
542 NewPartEntry->FormatState = Unformatted;
543
545 &NewPartEntry->ListEntry);
546
547 return;
548 }
549
550 /* Start partition at head 1, cylinder 0 */
551 LastStartSector = DiskEntry->SectorAlignment;
552 LastSectorCount = 0ULL;
553 LastUnusedSectorCount = 0ULL;
554
555 Entry = DiskEntry->PrimaryPartListHead.Flink;
556 while (Entry != &DiskEntry->PrimaryPartListHead)
557 {
558 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
559
560 if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
561 PartEntry->SectorCount.QuadPart != 0ULL)
562 {
563 LastUnusedSectorCount =
564 PartEntry->StartSector.QuadPart - (LastStartSector + LastSectorCount);
565
566 if (PartEntry->StartSector.QuadPart > (LastStartSector + LastSectorCount) &&
567 LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
568 {
569 DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
570
571 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
573 sizeof(PARTENTRY));
574 if (NewPartEntry == NULL)
575 return;
576
577 NewPartEntry->DiskEntry = DiskEntry;
578
579 NewPartEntry->IsPartitioned = FALSE;
580 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
581 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
582 NewPartEntry->StartSector.QuadPart;
583
584 DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
585 DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
586 DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
587
588 NewPartEntry->FormatState = Unformatted;
589
590 /* Insert the table into the list */
591 InsertTailList(&PartEntry->ListEntry,
592 &NewPartEntry->ListEntry);
593 }
594
595 LastStartSector = PartEntry->StartSector.QuadPart;
596 LastSectorCount = PartEntry->SectorCount.QuadPart;
597 }
598
599 Entry = Entry->Flink;
600 }
601
602 /* Check for trailing unpartitioned disk space */
603 if ((LastStartSector + LastSectorCount) < DiskEntry->SectorCount.QuadPart)
604 {
605 LastUnusedSectorCount = AlignDown(DiskEntry->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
606
607 if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
608 {
609 DPRINT1("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
610
611 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
613 sizeof(PARTENTRY));
614 if (NewPartEntry == NULL)
615 return;
616
617 NewPartEntry->DiskEntry = DiskEntry;
618
619 NewPartEntry->IsPartitioned = FALSE;
620 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
621 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
622 NewPartEntry->StartSector.QuadPart;
623
624 DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
625 DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
626 DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
627
628 NewPartEntry->FormatState = Unformatted;
629
630 /* Append the table to the list */
632 &NewPartEntry->ListEntry);
633 }
634 }
635
636 if (DiskEntry->ExtendedPartition != NULL)
637 {
638 if (IsListEmpty(&DiskEntry->LogicalPartListHead))
639 {
640 DPRINT1("No logical partition!\n");
641
642 /* Create a partition table entry that represents the empty extended partition */
643 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
645 sizeof(PARTENTRY));
646 if (NewPartEntry == NULL)
647 return;
648
649 NewPartEntry->DiskEntry = DiskEntry;
650 NewPartEntry->LogicalPartition = TRUE;
651
652 NewPartEntry->IsPartitioned = FALSE;
653 NewPartEntry->StartSector.QuadPart = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
654 NewPartEntry->SectorCount.QuadPart = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
655
656 DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
657 DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
658 DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
659
660 NewPartEntry->FormatState = Unformatted;
661
663 &NewPartEntry->ListEntry);
664
665 return;
666 }
667
668 /* Start partition at head 1, cylinder 0 */
669 LastStartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
670 LastSectorCount = 0ULL;
671 LastUnusedSectorCount = 0ULL;
672
673 Entry = DiskEntry->LogicalPartListHead.Flink;
674 while (Entry != &DiskEntry->LogicalPartListHead)
675 {
676 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
677
678 if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
679 PartEntry->SectorCount.QuadPart != 0ULL)
680 {
681 LastUnusedSectorCount =
682 PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment - (LastStartSector + LastSectorCount);
683
684 if ((PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment) > (LastStartSector + LastSectorCount) &&
685 LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
686 {
687 DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
688
689 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
691 sizeof(PARTENTRY));
692 if (NewPartEntry == NULL)
693 return;
694
695 NewPartEntry->DiskEntry = DiskEntry;
696 NewPartEntry->LogicalPartition = TRUE;
697
698 NewPartEntry->IsPartitioned = FALSE;
699 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
700 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
701 NewPartEntry->StartSector.QuadPart;
702
703 DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
704 DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
705 DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
706
707 NewPartEntry->FormatState = Unformatted;
708
709 /* Insert the table into the list */
710 InsertTailList(&PartEntry->ListEntry,
711 &NewPartEntry->ListEntry);
712 }
713
714 LastStartSector = PartEntry->StartSector.QuadPart;
715 LastSectorCount = PartEntry->SectorCount.QuadPart;
716 }
717
718 Entry = Entry->Flink;
719 }
720
721 /* Check for trailing unpartitioned disk space */
722 if ((LastStartSector + LastSectorCount) < DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart)
723 {
724 LastUnusedSectorCount = AlignDown(DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart - (LastStartSector + LastSectorCount),
725 DiskEntry->SectorAlignment);
726
727 if (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 NewPartEntry->LogicalPartition = TRUE;
739
740 NewPartEntry->IsPartitioned = FALSE;
741 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
742 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
743 NewPartEntry->StartSector.QuadPart;
744
745 DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
746 DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
747 DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
748
749 NewPartEntry->FormatState = Unformatted;
750
751 /* Append the table to the list */
753 &NewPartEntry->ListEntry);
754 }
755 }
756 }
757
758 DPRINT("ScanForUnpartitionedDiskSpace() done\n");
759}
760
761
762static
763VOID
766 ULONG DiskNumber)
767{
768 DISK_GEOMETRY DiskGeometry;
769 SCSI_ADDRESS ScsiAddress;
770 PDISKENTRY DiskEntry;
776 WCHAR Identifier[20];
777 ULONG Checksum;
779 ULONG i;
780 PLIST_ENTRY ListEntry;
781 PBIOSDISKENTRY BiosDiskEntry;
782 ULONG LayoutBufferSize;
783 PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
784
786 NULL,
787 NULL,
788 NULL,
789 &Iosb,
791 NULL,
792 0,
793 &DiskGeometry,
794 sizeof(DISK_GEOMETRY));
795 if (!NT_SUCCESS(Status))
796 {
797 return;
798 }
799
800 if (DiskGeometry.MediaType != FixedMedia &&
801 DiskGeometry.MediaType != RemovableMedia)
802 {
803 return;
804 }
805
807 NULL,
808 NULL,
809 NULL,
810 &Iosb,
812 NULL,
813 0,
814 &ScsiAddress,
815 sizeof(SCSI_ADDRESS));
816 if (!NT_SUCCESS(Status))
817 {
818 return;
819 }
820
821 Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(RtlGetProcessHeap(),
822 0,
823 DiskGeometry.BytesPerSector);
824 if (Mbr == NULL)
825 {
826 return;
827 }
828
829 FileOffset.QuadPart = 0;
831 NULL,
832 NULL,
833 NULL,
834 &Iosb,
835 (PVOID)Mbr,
836 DiskGeometry.BytesPerSector,
837 &FileOffset,
838 NULL);
839 if (!NT_SUCCESS(Status))
840 {
841 RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr);
842 DPRINT1("NtReadFile failed, status=%x\n", Status);
843 return;
844 }
845 Signature = Mbr->Signature;
846
847 /* Calculate the MBR checksum */
848 Checksum = 0;
849 Buffer = (PULONG)Mbr;
850 for (i = 0; i < 128; i++)
851 {
852 Checksum += Buffer[i];
853 }
854 Checksum = ~Checksum + 1;
855
857 L"%08x-%08x-A", Checksum, Signature);
858 DPRINT("Identifier: %S\n", Identifier);
859
860 DiskEntry = RtlAllocateHeap(RtlGetProcessHeap(),
862 sizeof(DISKENTRY));
863 if (DiskEntry == NULL)
864 {
865 return;
866 }
867
868// DiskEntry->Checksum = Checksum;
869// DiskEntry->Signature = Signature;
870 DiskEntry->BiosFound = FALSE;
871
872 /* Check if this disk has a valid MBR */
873 if (Mbr->BootCode[0] == 0 && Mbr->BootCode[1] == 0)
874 DiskEntry->NoMbr = TRUE;
875 else
876 DiskEntry->NoMbr = FALSE;
877
878 /* Free Mbr sector buffer */
879 RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr);
880
881 ListEntry = BiosDiskListHead.Flink;
882 while (ListEntry != &BiosDiskListHead)
883 {
884 BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
885 /* FIXME:
886 * Compare the size from bios and the reported size from driver.
887 * If we have more than one disk with a zero or with the same signatur
888 * we must create new signatures and reboot. After the reboot,
889 * it is possible to identify the disks.
890 */
891 if (BiosDiskEntry->Signature == Signature &&
892 BiosDiskEntry->Checksum == Checksum &&
893 !BiosDiskEntry->Recognized)
894 {
895 if (!DiskEntry->BiosFound)
896 {
897 DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber;
898 DiskEntry->BiosFound = TRUE;
899 BiosDiskEntry->Recognized = TRUE;
900 }
901 else
902 {
903 }
904 }
905 ListEntry = ListEntry->Flink;
906 }
907
908 if (!DiskEntry->BiosFound)
909 {
910#if 0
911 RtlFreeHeap(ProcessHeap, 0, DiskEntry);
912 return;
913#else
914 DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %d is not be bootable by the BIOS!\n", DiskNumber);
915#endif
916 }
917
920
921 DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
922 DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
923 DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
924 DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
925
926 DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders);
927 DPRINT("TracksPerCylinder %I64u\n", DiskEntry->TracksPerCylinder);
928 DPRINT("SectorsPerTrack %I64u\n", DiskEntry->SectorsPerTrack);
929 DPRINT("BytesPerSector %I64u\n", DiskEntry->BytesPerSector);
930
931 DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart *
932 (ULONGLONG)DiskGeometry.TracksPerCylinder *
933 (ULONGLONG)DiskGeometry.SectorsPerTrack;
934
935// DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
936// DiskEntry->CylinderAlignment = DiskGeometry.SectorsPerTrack * DiskGeometry.TracksPerCylinder;
937 DiskEntry->SectorAlignment = (1024 * 1024) / DiskGeometry.BytesPerSector;
938 DiskEntry->CylinderAlignment = (1024 * 1024) / DiskGeometry.BytesPerSector;
939
940 DPRINT1("SectorCount: %I64u\n", DiskEntry->SectorCount);
941 DPRINT1("SectorAlignment: %lu\n", DiskEntry->SectorAlignment);
942 DPRINT1("CylinderAlignment: %lu\n", DiskEntry->CylinderAlignment);
943
944 DiskEntry->DiskNumber = DiskNumber;
945 DiskEntry->Port = ScsiAddress.PortNumber;
946 DiskEntry->PathId = ScsiAddress.PathId;
947 DiskEntry->TargetId = ScsiAddress.TargetId;
948 DiskEntry->Lun = ScsiAddress.Lun;
949
950 GetDriverName(DiskEntry);
951
952 InsertAscendingList(&DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber);
953
954 /* Allocate a layout buffer with 4 partition entries first */
955 LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
956 ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
957 DiskEntry->LayoutBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
959 LayoutBufferSize);
960 if (DiskEntry->LayoutBuffer == NULL)
961 {
962 DPRINT1("Failed to allocate the disk layout buffer!\n");
963 return;
964 }
965
966 for (;;)
967 {
968 DPRINT1("Buffer size: %lu\n", LayoutBufferSize);
970 NULL,
971 NULL,
972 NULL,
973 &Iosb,
975 NULL,
976 0,
977 DiskEntry->LayoutBuffer,
978 LayoutBufferSize);
979 if (NT_SUCCESS(Status))
980 break;
981
983 {
984 DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status);
985 return;
986 }
987
988 LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION);
989 NewLayoutBuffer = RtlReAllocateHeap(RtlGetProcessHeap(),
991 DiskEntry->LayoutBuffer,
992 LayoutBufferSize);
993 if (NewLayoutBuffer == NULL)
994 {
995 DPRINT1("Failed to reallocate the disk layout buffer!\n");
996 return;
997 }
998
999 DiskEntry->LayoutBuffer = NewLayoutBuffer;
1000 }
1001
1002 DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount);
1003
1004#ifdef DUMP_PARTITION_TABLE
1005 DumpPartitionTable(DiskEntry);
1006#endif
1007
1008 if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
1010 DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionType != 0)
1011 {
1012 if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
1013 {
1014 DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
1015 }
1016 else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
1017 {
1018 DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1019 }
1020 else
1021 {
1022 DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
1023 }
1024 }
1025 else
1026 {
1027 DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1028 }
1029
1030
1031 if (DiskEntry->LayoutBuffer->PartitionCount == 0)
1032 {
1033 DiskEntry->NewDisk = TRUE;
1034 DiskEntry->LayoutBuffer->PartitionCount = 4;
1035
1036 for (i = 0; i < 4; i++)
1038 }
1039 else
1040 {
1041 for (i = 0; i < 4; i++)
1042 {
1043 AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
1044 }
1045
1046 for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
1047 {
1048 AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
1049 }
1050 }
1051
1053}
1054
1055
1058{
1062 ULONG ReturnSize;
1064 ULONG DiskNumber;
1068
1069 CurrentDisk = NULL;
1071
1072// BootDisk = NULL;
1073// BootPartition = NULL;
1074
1075// TempDisk = NULL;
1076// TempPartition = NULL;
1077// FormatState = Start;
1078
1081
1083
1085 &Sdi,
1087 &ReturnSize);
1088 if (!NT_SUCCESS(Status))
1089 {
1090 return Status;
1091 }
1092
1093 for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
1094 {
1096 L"\\Device\\Harddisk%d\\Partition0",
1097 DiskNumber);
1098
1100 Buffer);
1101
1103 &Name,
1104 0,
1105 NULL,
1106 NULL);
1107
1111 &Iosb,
1114 if (NT_SUCCESS(Status))
1115 {
1116 AddDiskToList(FileHandle, DiskNumber);
1117
1119 }
1120 }
1121
1122// UpdateDiskSignatures(List);
1123
1124// AssignDriveLetters(List);
1125
1126 return STATUS_SUCCESS;
1127}
1128
1129
1130VOID
1132{
1133 PDISKENTRY DiskEntry;
1134 PBIOSDISKENTRY BiosDiskEntry;
1135 PPARTENTRY PartEntry;
1137
1138 CurrentDisk = NULL;
1140
1141 /* Release disk and partition info */
1142 while (!IsListEmpty(&DiskListHead))
1143 {
1145 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
1146
1147 /* Release driver name */
1148 RtlFreeUnicodeString(&DiskEntry->DriverName);
1149
1150 /* Release primary partition list */
1151 while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
1152 {
1154 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1155
1156 RtlFreeHeap(RtlGetProcessHeap(), 0, PartEntry);
1157 }
1158
1159 /* Release logical partition list */
1160 while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
1161 {
1163 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1164
1165 RtlFreeHeap(RtlGetProcessHeap(), 0, PartEntry);
1166 }
1167
1168 /* Release layout buffer */
1169 if (DiskEntry->LayoutBuffer != NULL)
1170 RtlFreeHeap(RtlGetProcessHeap(), 0, DiskEntry->LayoutBuffer);
1171
1172
1173 /* Release disk entry */
1174 RtlFreeHeap(RtlGetProcessHeap(), 0, DiskEntry);
1175 }
1176
1177 /* Release the bios disk info */
1178 while (!IsListEmpty(&BiosDiskListHead))
1179 {
1181 BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
1182
1183 RtlFreeHeap(RtlGetProcessHeap(), 0, BiosDiskEntry);
1184 }
1185}
1186
1187
1188static
1189VOID
1192 _In_ PVOLENTRY VolumeEntry)
1193{
1194 DWORD dwBytesReturned = 0, dwLength, i;
1195 PVOLUME_DISK_EXTENTS pExtents;
1196 BOOL bResult;
1197 DWORD dwError;
1198
1199 dwLength = sizeof(VOLUME_DISK_EXTENTS);
1200 pExtents = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
1201 if (pExtents == NULL)
1202 return;
1203
1204 bResult = DeviceIoControl(VolumeHandle,
1206 NULL,
1207 0,
1208 pExtents,
1209 dwLength,
1210 &dwBytesReturned,
1211 NULL);
1212 if (!bResult)
1213 {
1214 dwError = GetLastError();
1215
1216 if (dwError != ERROR_MORE_DATA)
1217 {
1218 RtlFreeHeap(RtlGetProcessHeap(), 0, pExtents);
1219 return;
1220 }
1221 else
1222 {
1223 dwLength = sizeof(VOLUME_DISK_EXTENTS) + ((pExtents->NumberOfDiskExtents - 1) * sizeof(DISK_EXTENT));
1224 RtlFreeHeap(RtlGetProcessHeap(), 0, pExtents);
1225 pExtents = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
1226 if (pExtents == NULL)
1227 {
1228 return;
1229 }
1230
1231 bResult = DeviceIoControl(VolumeHandle,
1233 NULL,
1234 0,
1235 pExtents,
1236 dwLength,
1237 &dwBytesReturned,
1238 NULL);
1239 if (!bResult)
1240 {
1241 RtlFreeHeap(RtlGetProcessHeap(), 0, pExtents);
1242 return;
1243 }
1244 }
1245 }
1246
1247 for (i = 0; i < pExtents->NumberOfDiskExtents; i++)
1248 VolumeEntry->Size.QuadPart += pExtents->Extents[i].ExtentLength.QuadPart;
1249
1250 VolumeEntry->pExtents = pExtents;
1251}
1252
1253
1254static
1255VOID
1258 _In_ PVOLENTRY VolumeEntry)
1259{
1263
1266 &DeviceInfo,
1269 if (!NT_SUCCESS(Status))
1270 return;
1271
1272 switch (DeviceInfo.DeviceType)
1273 {
1274 case FILE_DEVICE_CD_ROM:
1276 VolumeEntry->VolumeType = VOLUME_TYPE_CDROM;
1277 break;
1278
1279 case FILE_DEVICE_DISK:
1281 if (DeviceInfo.Characteristics & FILE_REMOVABLE_MEDIA)
1282 VolumeEntry->VolumeType = VOLUME_TYPE_REMOVABLE;
1283 else
1284 VolumeEntry->VolumeType = VOLUME_TYPE_PARTITION;
1285 break;
1286
1287 default:
1288 VolumeEntry->VolumeType = VOLUME_TYPE_UNKNOWN;
1289 break;
1290 }
1291}
1292
1293
1294static
1295VOID
1297 ULONG ulVolumeNumber,
1298 PWSTR pszVolumeName)
1299{
1300 PVOLENTRY VolumeEntry;
1302
1303 DWORD dwError, dwLength;
1304 WCHAR szPathNames[MAX_PATH + 1];
1305 WCHAR szVolumeName[MAX_PATH + 1];
1306 WCHAR szFilesystem[MAX_PATH + 1];
1307
1308 DWORD CharCount = 0;
1309 size_t Index = 0;
1310
1315
1316 DPRINT("AddVolumeToList(%S)\n", pszVolumeName);
1317
1318 VolumeEntry = RtlAllocateHeap(RtlGetProcessHeap(),
1320 sizeof(VOLENTRY));
1321 if (VolumeEntry == NULL)
1322 return;
1323
1324 VolumeEntry->VolumeNumber = ulVolumeNumber;
1325 wcscpy(VolumeEntry->VolumeName, pszVolumeName);
1326
1327 Index = wcslen(pszVolumeName) - 1;
1328
1329 pszVolumeName[Index] = L'\0';
1330
1331 CharCount = QueryDosDeviceW(&pszVolumeName[4], VolumeEntry->DeviceName, ARRAYSIZE(VolumeEntry->DeviceName));
1332
1333 pszVolumeName[Index] = L'\\';
1334
1335 if (CharCount == 0)
1336 {
1337 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry);
1338 return;
1339 }
1340
1341 DPRINT("DeviceName: %S\n", VolumeEntry->DeviceName);
1342
1343 RtlInitUnicodeString(&Name, VolumeEntry->DeviceName);
1344
1346 &Name,
1347 0,
1348 NULL,
1349 NULL);
1350
1354 &Iosb,
1355 0,
1357 if (NT_SUCCESS(Status))
1358 {
1359 GetVolumeType(VolumeHandle, VolumeEntry);
1360 GetVolumeExtents(VolumeHandle, VolumeEntry);
1362 }
1363
1364 if (GetVolumeInformationW(pszVolumeName,
1365 szVolumeName,
1366 MAX_PATH + 1,
1367 NULL, // [out, optional] LPDWORD lpVolumeSerialNumber,
1368 NULL, // [out, optional] LPDWORD lpMaximumComponentLength,
1369 NULL, // [out, optional] LPDWORD lpFileSystemFlags,
1370 szFilesystem,
1371 MAX_PATH + 1))
1372 {
1373 VolumeEntry->pszLabel = RtlAllocateHeap(RtlGetProcessHeap(),
1374 0,
1375 (wcslen(szVolumeName) + 1) * sizeof(WCHAR));
1376 if (VolumeEntry->pszLabel)
1377 wcscpy(VolumeEntry->pszLabel, szVolumeName);
1378
1379 VolumeEntry->pszFilesystem = RtlAllocateHeap(RtlGetProcessHeap(),
1380 0,
1381 (wcslen(szFilesystem) + 1) * sizeof(WCHAR));
1382 if (VolumeEntry->pszFilesystem)
1383 wcscpy(VolumeEntry->pszFilesystem, szFilesystem);
1384 }
1385 else
1386 {
1387 dwError = GetLastError();
1388 if (dwError == ERROR_UNRECOGNIZED_VOLUME)
1389 {
1390 VolumeEntry->pszFilesystem = RtlAllocateHeap(RtlGetProcessHeap(),
1391 0,
1392 (3 + 1) * sizeof(WCHAR));
1393 if (VolumeEntry->pszFilesystem)
1394 wcscpy(VolumeEntry->pszFilesystem, L"RAW");
1395 }
1396 }
1397
1398 if (GetVolumePathNamesForVolumeNameW(pszVolumeName,
1399 szPathNames,
1400 ARRAYSIZE(szPathNames),
1401 &dwLength))
1402 {
1403 VolumeEntry->DriveLetter = szPathNames[0];
1404 }
1405
1407 &VolumeEntry->ListEntry);
1408}
1409
1410
1413{
1414 HANDLE hVolume = INVALID_HANDLE_VALUE;
1415 WCHAR szVolumeName[MAX_PATH];
1416 ULONG ulVolumeNumber = 0;
1417 BOOL Success;
1418
1420
1422
1423 hVolume = FindFirstVolumeW(szVolumeName, ARRAYSIZE(szVolumeName));
1424 if (hVolume == INVALID_HANDLE_VALUE)
1425 {
1426
1427 return STATUS_UNSUCCESSFUL;
1428 }
1429
1430 AddVolumeToList(ulVolumeNumber++, szVolumeName);
1431
1432 for (;;)
1433 {
1434 Success = FindNextVolumeW(hVolume, szVolumeName, ARRAYSIZE(szVolumeName));
1435 if (!Success)
1436 {
1437 break;
1438 }
1439
1440 AddVolumeToList(ulVolumeNumber++, szVolumeName);
1441 }
1442
1443 FindVolumeClose(hVolume);
1444
1445 return STATUS_SUCCESS;
1446}
1447
1448
1449VOID
1451{
1453 PVOLENTRY VolumeEntry;
1454
1456
1457 /* Release disk and partition info */
1458 while (!IsListEmpty(&VolumeListHead))
1459 {
1461 VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
1462
1463 if (VolumeEntry->pszLabel)
1464 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszLabel);
1465
1466 if (VolumeEntry->pszFilesystem)
1467 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszFilesystem);
1468
1469 if (VolumeEntry->pExtents)
1470 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pExtents);
1471
1472 /* Release disk entry */
1473 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry);
1474 }
1475}
1476
1477
1480 _In_ PDISKENTRY DiskEntry)
1481{
1489 ULONG PartitionCount;
1490 PLIST_ENTRY ListEntry;
1491 PPARTENTRY PartEntry;
1493
1494 DPRINT("WritePartitions() Disk: %lu\n", DiskEntry->DiskNumber);
1495
1496 /* If the disk is not dirty, there is nothing to do */
1497 if (!DiskEntry->Dirty)
1498 return STATUS_SUCCESS;
1499
1501 L"\\Device\\Harddisk%lu\\Partition0",
1502 DiskEntry->DiskNumber);
1504
1506 &Name,
1508 NULL,
1509 NULL);
1510
1514 &Iosb,
1515 0,
1517 if (!NT_SUCCESS(Status))
1518 {
1519 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
1520 return Status;
1521 }
1522
1523 //
1524 // FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize
1525 // the disk in MBR or GPT format in case the disk was not initialized!!
1526 // For this we must ask the user which format to use.
1527 //
1528
1529 /* Save the original partition count to be restored later (see comment below) */
1530 PartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
1531
1532 /* Set the new disk layout and retrieve its updated version with possibly modified partition numbers */
1534 ((PartitionCount - 1) * sizeof(PARTITION_INFORMATION));
1536 NULL,
1537 NULL,
1538 NULL,
1539 &Iosb,
1541 DiskEntry->LayoutBuffer,
1542 BufferSize,
1543 DiskEntry->LayoutBuffer,
1544 BufferSize);
1546
1547 /*
1548 * IOCTL_DISK_SET_DRIVE_LAYOUT calls IoWritePartitionTable(), which converts
1549 * DiskEntry->LayoutBuffer->PartitionCount into a partition *table* count,
1550 * where such a table is expected to enumerate up to 4 partitions:
1551 * partition *table* count == ROUND_UP(PartitionCount, 4) / 4 .
1552 * Due to this we need to restore the original PartitionCount number.
1553 */
1554 DiskEntry->LayoutBuffer->PartitionCount = PartitionCount;
1555
1556 /* Check whether the IOCTL_DISK_SET_DRIVE_LAYOUT call succeeded */
1557 if (!NT_SUCCESS(Status))
1558 {
1559 DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status);
1560 return Status;
1561 }
1562
1563 /* Update the partition numbers */
1564
1565 /* Update the primary partition table */
1566 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
1567 ListEntry != &DiskEntry->PrimaryPartListHead;
1568 ListEntry = ListEntry->Flink)
1569 {
1570 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1571
1572 if (PartEntry->IsPartitioned)
1573 {
1575 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
1576 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
1577 }
1578 }
1579
1580 /* Update the logical partition table */
1581 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
1582 ListEntry != &DiskEntry->LogicalPartListHead;
1583 ListEntry = ListEntry->Flink)
1584 {
1585 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1586
1587 if (PartEntry->IsPartitioned)
1588 {
1590 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
1591 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
1592 }
1593 }
1594
1595 /* The layout has been successfully updated, the disk is not dirty anymore */
1596 DiskEntry->Dirty = FALSE;
1597
1598 return Status;
1599}
1600
1601
1602static
1603BOOLEAN
1606{
1607 if (PartitionInfo->StartingOffset.QuadPart == 0 &&
1608 PartitionInfo->PartitionLength.QuadPart == 0)
1609 {
1610 return TRUE;
1611 }
1612
1613 return FALSE;
1614}
1615
1616
1617static
1618BOOLEAN
1621 IN PDISKENTRY DiskEntry,
1622 IN PPARTENTRY PartEntry)
1623{
1624 if ((PartitionInfo->StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector) &&
1625 (PartitionInfo->PartitionLength.QuadPart == PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector))
1626 {
1627 return TRUE;
1628 }
1629
1630 return FALSE;
1631}
1632
1633
1634ULONG
1636 _In_ PDISKENTRY DiskEntry)
1637{
1639 PPARTENTRY PartEntry;
1640 ULONG Count = 0;
1641
1642 for (Entry = DiskEntry->PrimaryPartListHead.Flink;
1643 Entry != &DiskEntry->PrimaryPartListHead;
1644 Entry = Entry->Flink)
1645 {
1646 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1647 if (PartEntry->IsPartitioned)
1648 Count++;
1649 }
1650
1651 return Count;
1652}
1653
1654
1655static
1656ULONG
1658 _In_ PDISKENTRY DiskEntry)
1659{
1660 PLIST_ENTRY ListEntry;
1661 PPARTENTRY PartEntry;
1662 ULONG Count = 0;
1663
1664 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
1665 ListEntry != &DiskEntry->LogicalPartListHead;
1666 ListEntry = ListEntry->Flink)
1667 {
1668 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1669 if (PartEntry->IsPartitioned)
1670 Count++;
1671 }
1672
1673 return Count;
1674}
1675
1676
1677static
1678BOOLEAN
1680 _In_ PDISKENTRY DiskEntry)
1681{
1682 PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
1683 ULONG NewPartitionCount;
1684 ULONG CurrentPartitionCount = 0;
1685 ULONG LayoutBufferSize;
1686 ULONG i;
1687
1688 DPRINT1("ReAllocateLayoutBuffer()\n");
1689
1690 NewPartitionCount = 4 + GetLogicalPartitionCount(DiskEntry) * 4;
1691
1692 if (DiskEntry->LayoutBuffer)
1693 CurrentPartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
1694
1695 DPRINT1("CurrentPartitionCount: %lu ; NewPartitionCount: %lu\n",
1696 CurrentPartitionCount, NewPartitionCount);
1697
1698 if (CurrentPartitionCount == NewPartitionCount)
1699 return TRUE;
1700
1701 LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
1702 ((NewPartitionCount - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
1703 NewLayoutBuffer = RtlReAllocateHeap(RtlGetProcessHeap(),
1705 DiskEntry->LayoutBuffer,
1706 LayoutBufferSize);
1707 if (NewLayoutBuffer == NULL)
1708 {
1709 DPRINT1("Failed to allocate the new layout buffer (size: %lu)\n", LayoutBufferSize);
1710 return FALSE;
1711 }
1712
1713 NewLayoutBuffer->PartitionCount = NewPartitionCount;
1714
1715 /* If the layout buffer grows, make sure the new (empty) entries are written to the disk */
1716 if (NewPartitionCount > CurrentPartitionCount)
1717 {
1718 for (i = CurrentPartitionCount; i < NewPartitionCount; i++)
1719 {
1720 NewLayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
1721 }
1722 }
1723
1724 DiskEntry->LayoutBuffer = NewLayoutBuffer;
1725
1726 return TRUE;
1727}
1728
1729
1730VOID
1732 _In_ PDISKENTRY DiskEntry)
1733{
1735 PPARTITION_INFORMATION LinkInfo = NULL;
1736 PLIST_ENTRY ListEntry;
1737 PPARTENTRY PartEntry;
1738 LARGE_INTEGER HiddenSectors64;
1739 ULONG Index;
1741
1742 DPRINT1("UpdateDiskLayout()\n");
1743
1744 /* Resize the layout buffer if necessary */
1745 if (ReAllocateLayoutBuffer(DiskEntry) == FALSE)
1746 {
1747 DPRINT("ReAllocateLayoutBuffer() failed.\n");
1748 return;
1749 }
1750
1751 /* Update the primary partition table */
1752 Index = 0;
1753 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
1754 ListEntry != &DiskEntry->PrimaryPartListHead;
1755 ListEntry = ListEntry->Flink)
1756 {
1757 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1758
1759 if (PartEntry->IsPartitioned)
1760 {
1762
1763 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
1764 PartEntry->PartitionIndex = Index;
1765
1766 /* Reset the current partition number only for newly-created (unmounted) partitions */
1767 if (PartEntry->New)
1768 PartEntry->PartitionNumber = 0;
1769
1771
1772 if (!IsSamePrimaryLayoutEntry(PartitionInfo, DiskEntry, PartEntry))
1773 {
1774 DPRINT1("Updating primary partition entry %lu\n", Index);
1775
1776 PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
1777 PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
1778 PartitionInfo->HiddenSectors = PartEntry->StartSector.LowPart;
1779 PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
1780 PartitionInfo->PartitionType = PartEntry->PartitionType;
1781 PartitionInfo->BootIndicator = PartEntry->BootIndicator;
1782 PartitionInfo->RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
1783 PartitionInfo->RewritePartition = TRUE;
1784 }
1785
1786 if (!IsContainerPartition(PartEntry->PartitionType))
1788
1789 Index++;
1790 }
1791 }
1792
1793 ASSERT(Index <= 4);
1794
1795 /* Update the logical partition table */
1796 Index = 4;
1797 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
1798 ListEntry != &DiskEntry->LogicalPartListHead;
1799 ListEntry = ListEntry->Flink)
1800 {
1801 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1802
1803 if (PartEntry->IsPartitioned)
1804 {
1806
1807 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
1808 PartEntry->PartitionIndex = Index;
1809
1810 /* Reset the current partition number only for newly-created (unmounted) partitions */
1811 if (PartEntry->New)
1812 PartEntry->PartitionNumber = 0;
1813
1815
1816 DPRINT1("Updating logical partition entry %lu\n", Index);
1817
1818 PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
1819 PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
1820 PartitionInfo->HiddenSectors = DiskEntry->SectorAlignment;
1821 PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
1822 PartitionInfo->PartitionType = PartEntry->PartitionType;
1823 PartitionInfo->BootIndicator = FALSE;
1824 PartitionInfo->RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
1825 PartitionInfo->RewritePartition = TRUE;
1826
1827 /* Fill the link entry of the previous partition entry */
1828 if (LinkInfo != NULL)
1829 {
1830 LinkInfo->StartingOffset.QuadPart = (PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
1831 LinkInfo->PartitionLength.QuadPart = (PartEntry->StartSector.QuadPart + DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
1832 HiddenSectors64.QuadPart = PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment - DiskEntry->ExtendedPartition->StartSector.QuadPart;
1833 LinkInfo->HiddenSectors = HiddenSectors64.LowPart;
1834 LinkInfo->PartitionNumber = 0;
1836 LinkInfo->BootIndicator = FALSE;
1837 LinkInfo->RecognizedPartition = FALSE;
1838 LinkInfo->RewritePartition = TRUE;
1839 }
1840
1841 /* Save a pointer to the link entry of the current partition entry */
1842 LinkInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index + 1];
1843
1845 Index += 4;
1846 }
1847 }
1848
1849 /* Wipe unused primary partition entries */
1850 for (Index = GetPrimaryPartitionCount(DiskEntry); Index < 4; Index++)
1851 {
1852 DPRINT1("Primary partition entry %lu\n", Index);
1853
1854 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
1855
1857 {
1858 DPRINT1("Wiping primary partition entry %lu\n", Index);
1859
1860 PartitionInfo->StartingOffset.QuadPart = 0;
1861 PartitionInfo->PartitionLength.QuadPart = 0;
1862 PartitionInfo->HiddenSectors = 0;
1863 PartitionInfo->PartitionNumber = 0;
1864 PartitionInfo->PartitionType = PARTITION_ENTRY_UNUSED;
1865 PartitionInfo->BootIndicator = FALSE;
1866 PartitionInfo->RecognizedPartition = FALSE;
1867 PartitionInfo->RewritePartition = TRUE;
1868 }
1869 }
1870
1871 /* Wipe unused logical partition entries */
1872 for (Index = 4; Index < DiskEntry->LayoutBuffer->PartitionCount; Index++)
1873 {
1874 if (Index % 4 >= 2)
1875 {
1876 DPRINT1("Logical partition entry %lu\n", Index);
1877
1878 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
1879
1881 {
1882 DPRINT1("Wiping partition entry %lu\n", Index);
1883
1884 PartitionInfo->StartingOffset.QuadPart = 0;
1885 PartitionInfo->PartitionLength.QuadPart = 0;
1886 PartitionInfo->HiddenSectors = 0;
1887 PartitionInfo->PartitionNumber = 0;
1888 PartitionInfo->PartitionType = PARTITION_ENTRY_UNUSED;
1889 PartitionInfo->BootIndicator = FALSE;
1890 PartitionInfo->RecognizedPartition = FALSE;
1891 PartitionInfo->RewritePartition = TRUE;
1892 }
1893 }
1894 }
1895
1896 DiskEntry->Dirty = TRUE;
1897}
1898
1899
1902 _In_ PPARTENTRY PartEntry)
1903{
1904 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
1905 PPARTENTRY PrevPartEntry;
1906 PLIST_ENTRY ListHead;
1907
1908 if (PartEntry->LogicalPartition)
1909 ListHead = &DiskEntry->LogicalPartListHead;
1910 else
1911 ListHead = &DiskEntry->PrimaryPartListHead;
1912
1913 if (PartEntry->ListEntry.Blink != ListHead)
1914 {
1915 PrevPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Blink,
1916 PARTENTRY,
1917 ListEntry);
1918 if (!PrevPartEntry->IsPartitioned)
1919 {
1920 ASSERT(PrevPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
1921 return PrevPartEntry;
1922 }
1923 }
1924
1925 return NULL;
1926}
1927
1928
1931 _In_ PPARTENTRY PartEntry)
1932{
1933 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
1934 PPARTENTRY NextPartEntry;
1935 PLIST_ENTRY ListHead;
1936
1937 if (PartEntry->LogicalPartition)
1938 ListHead = &DiskEntry->LogicalPartListHead;
1939 else
1940 ListHead = &DiskEntry->PrimaryPartListHead;
1941
1942 if (PartEntry->ListEntry.Flink != ListHead)
1943 {
1944 NextPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Flink,
1945 PARTENTRY,
1946 ListEntry);
1947 if (!NextPartEntry->IsPartitioned)
1948 {
1949 ASSERT(NextPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
1950 return NextPartEntry;
1951 }
1952 }
1953
1954 return NULL;
1955}
1956
1959 _In_ PPARTENTRY PartEntry)
1960{
1962 NTSTATUS LockStatus;
1966 HANDLE PartitionHandle;
1968
1969 /* Check whether the partition is valid and was mounted by the system */
1970 if (!PartEntry->IsPartitioned ||
1971 IsContainerPartition(PartEntry->PartitionType) ||
1972 !IsRecognizedPartition(PartEntry->PartitionType) ||
1973 PartEntry->FormatState == UnknownFormat ||
1974 // NOTE: If FormatState == Unformatted but *FileSystem != 0 this means
1975 // it has been usually mounted with RawFS and thus needs to be dismounted.
1976/* !*PartEntry->FileSystem || */
1977 PartEntry->PartitionNumber == 0)
1978 {
1979 /* The partition is not mounted, so just return success */
1980 return STATUS_SUCCESS;
1981 }
1982
1983 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
1984
1985 /* Open the volume */
1987 L"\\Device\\Harddisk%lu\\Partition%lu",
1988 PartEntry->DiskEntry->DiskNumber,
1989 PartEntry->PartitionNumber);
1991
1993 &Name,
1995 NULL,
1996 NULL);
1997
1998 Status = NtOpenFile(&PartitionHandle,
2004 if (!NT_SUCCESS(Status))
2005 {
2006 DPRINT1("ERROR: Cannot open volume %wZ for dismounting! (Status 0x%lx)\n", &Name, Status);
2007 return Status;
2008 }
2009
2010 /* Lock the volume */
2011 LockStatus = NtFsControlFile(PartitionHandle,
2012 NULL,
2013 NULL,
2014 NULL,
2017 NULL,
2018 0,
2019 NULL,
2020 0);
2021 if (!NT_SUCCESS(LockStatus))
2022 {
2023 DPRINT1("WARNING: Failed to lock volume! Operations may fail! (Status 0x%lx)\n", LockStatus);
2024 }
2025
2026 /* Dismount the volume */
2027 Status = NtFsControlFile(PartitionHandle,
2028 NULL,
2029 NULL,
2030 NULL,
2033 NULL,
2034 0,
2035 NULL,
2036 0);
2037 if (!NT_SUCCESS(Status))
2038 {
2039 DPRINT1("Failed to unmount volume (Status 0x%lx)\n", Status);
2040 }
2041
2042 /* Unlock the volume */
2043 LockStatus = NtFsControlFile(PartitionHandle,
2044 NULL,
2045 NULL,
2046 NULL,
2049 NULL,
2050 0,
2051 NULL,
2052 0);
2053 if (!NT_SUCCESS(LockStatus))
2054 {
2055 DPRINT1("Failed to unlock volume (Status 0x%lx)\n", LockStatus);
2056 }
2057
2058 /* Close the volume */
2059 NtClose(PartitionHandle);
2060
2061 return Status;
2062}
2063
2064
2067 _In_ PPARTENTRY PartEntry)
2068{
2070 PVOLENTRY VolumeEntry;
2071 ULONG i;
2072
2073 if ((PartEntry == NULL) ||
2074 (PartEntry->DiskEntry == NULL))
2075 return NULL;
2076
2078 while (Entry != &VolumeListHead)
2079 {
2080 VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
2081
2082 if (VolumeEntry->pExtents == NULL)
2083 return NULL;
2084
2085 for (i = 0; i < VolumeEntry->pExtents->NumberOfDiskExtents; i++)
2086 {
2087 if (VolumeEntry->pExtents->Extents[i].DiskNumber == PartEntry->DiskEntry->DiskNumber)
2088 {
2089 if ((VolumeEntry->pExtents->Extents[i].StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * PartEntry->DiskEntry->BytesPerSector) &&
2090 (VolumeEntry->pExtents->Extents[i].ExtentLength.QuadPart == PartEntry->SectorCount.QuadPart * PartEntry->DiskEntry->BytesPerSector))
2091 return VolumeEntry;
2092 }
2093 }
2094
2095 Entry = Entry->Flink;
2096 }
2097
2098 return NULL;
2099}
2100
2101
2102VOID
2104 _In_ PVOLENTRY VolumeEntry)
2105{
2106 if (VolumeEntry == NULL)
2107 return;
2108
2109 if (VolumeEntry == CurrentVolume)
2111
2112 RemoveEntryList(&VolumeEntry->ListEntry);
2113
2114 if (VolumeEntry->pszLabel)
2115 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszLabel);
2116
2117 if (VolumeEntry->pszFilesystem)
2118 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszFilesystem);
2119
2120 if (VolumeEntry->pExtents)
2121 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pExtents);
2122
2123 /* Release disk entry */
2124 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry);
2125}
2126
2127/* EOF */
unsigned char BOOLEAN
struct NameRec_ * Name
Definition: cdprocs.h:460
@ 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:93
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
#define PARTITION_XINT13
Definition: disk.h:97
#define PARTITION_FAT32
Definition: disk.h:95
#define PARTITION_FAT_12
Definition: disk.h:87
#define PARTITION_EXTENDED
Definition: disk.h:91
#define PARTITION_HUGE
Definition: disk.h:92
#define PARTITION_FAT_16
Definition: disk.h:90
#define PARTITION_FAT32_XINT13
Definition: disk.h:96
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
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
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define BufferSize
Definition: mmc.h:75
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:93
@ VOLUME_TYPE_REMOVABLE
Definition: diskpart.h:92
@ VOLUME_TYPE_CDROM
Definition: diskpart.h:90
@ VOLUME_TYPE_PARTITION
Definition: diskpart.h:91
PDISKENTRY CurrentDisk
Definition: partlist.c:74
@ 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:32
#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
return Iosb
Definition: create.c:4402
#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
@ 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
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
struct _CM_FULL_RESOURCE_DESCRIPTOR * PCM_FULL_RESOURCE_DESCRIPTOR
#define CmResourceTypeDeviceSpecific
Definition: hwresource.cpp:127
_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)
Definition: heap.c:2667
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
@ Preformatted
Definition: partlist.h:37
@ Unformatted
Definition: partlist.h:34
struct _BIOSDISKENTRY BIOSDISKENTRY
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ASSERT(a)
Definition: mode.c:44
#define ULL(a, b)
Definition: format_msg.c:27
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define _In_
Definition: ms_sal.h:308
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4207
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4208
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:3952
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_READ_DATA
Definition: nt_native.h:628
#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:1503
#define IOCTL_DISK_SET_DRIVE_LAYOUT
Definition: ntdddisk.h:205
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:316
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:342
#define IOCTL_DISK_GET_DRIVE_LAYOUT
Definition: ntdddisk.h:91
struct _PARTITION_INFORMATION PARTITION_INFORMATION
@ RemovableMedia
Definition: ntdddisk.h:387
@ FixedMedia
Definition: ntdddisk.h:388
struct _DRIVE_LAYOUT_INFORMATION DRIVE_LAYOUT_INFORMATION
struct _VOLUME_DISK_EXTENTS VOLUME_DISK_EXTENTS
struct _DISK_EXTENT DISK_EXTENT
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
Definition: ntddvol.h:41
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
#define FILE_DEVICE_DISK_FILE_SYSTEM
Definition: winioctl.h:114
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:108
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM
Definition: winioctl.h:109
#define FILE_DEVICE_DISK
Definition: winioctl.h:113
#define IOCTL_SCSI_GET_ADDRESS
Definition: scsi_port.h:52
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define memset(x, y, z)
Definition: compat.h:39
IN HANDLE DstPath
Definition: fsutil.h:76
VOID DestroyPartitionList(IN PPARTLIST List)
Definition: partlist.c:1951
static VOID AddPartitionToDisk(IN ULONG DiskNumber, IN PDISKENTRY DiskEntry, IN ULONG PartitionIndex, IN BOOLEAN LogicalPartition)
Definition: partlist.c:771
static VOID GetDriverName(IN PDISKENTRY DiskEntry)
Definition: partlist.c:105
static ULONG GetPrimaryPartitionCount(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2435
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2541
static BOOLEAN IsSamePrimaryLayoutEntry(_In_ PPARTITION_INFORMATION PartitionInfo, _In_ PPARTENTRY PartEntry)
Definition: partlist.c:2424
ULONGLONG AlignDown(IN ULONGLONG Value, IN ULONG Alignment)
Definition: partlist.c:67
static PPARTENTRY GetPrevUnpartitionedEntry(IN PPARTENTRY PartEntry)
Definition: partlist.c:2724
static PPARTENTRY GetNextUnpartitionedEntry(IN PPARTENTRY PartEntry)
Definition: partlist.c:2759
static ULONG GetLogicalPartitionCount(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2462
static NTSTATUS NTAPI DiskConfigurationDataQueryRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: partlist.c:247
PPARTLIST CreatePartitionList(VOID)
Definition: partlist.c:1867
#define ROOT_NAME
static VOID AddDiskToList(IN HANDLE FileHandle, IN ULONG DiskNumber, IN PPARTLIST List)
Definition: partlist.c:1326
static VOID ScanForUnpartitionedDiskSpace(IN PDISKENTRY DiskEntry)
Definition: partlist.c:962
static NTSTATUS NTAPI SystemConfigurationDataQueryRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: partlist.c:290
static VOID EnumerateBiosDiskEntries(IN PPARTLIST PartList)
Definition: partlist.c:337
static BOOLEAN IsEmptyLayoutEntry(_In_ PPARTITION_INFORMATION PartitionInfo)
Definition: partlist.c:2415
static BOOLEAN ReAllocateLayoutBuffer(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2489
NTSTATUS DismountVolume(IN PPARTENTRY PartEntry)
Definition: partlist.c:2984
static NTSTATUS NTAPI DiskIdentifierQueryRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: partlist.c:217
NTSTATUS WritePartitions(IN PDISKENTRY DiskEntry)
Definition: partlist.c:3663
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:71
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:140
ULONG DiskNumber
Definition: partlist.h:141
ULONG Checksum
Definition: partlist.h:143
ULONG Signature
Definition: partlist.h:142
CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry
Definition: partlist.h:145
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@393 u
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@393::@402 DeviceSpecificData
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: hwresource.cpp:119
ULONG SectorAlignment
Definition: partlist.h:95
ULONG BiosDiskNumber
Definition: diskpart.h:160
ULARGE_INTEGER SectorCount
Definition: partlist.h:94
UNICODE_STRING DriverName
Definition: partlist.h:120
ULONG SectorsPerTrack
Definition: partlist.h:91
USHORT TargetId
Definition: diskpart.h:167
PPARTENTRY ExtendedPartition
Definition: partlist.h:132
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:129
BOOLEAN NewDisk
Definition: partlist.h:117
ULONG DiskNumber
Definition: partlist.h:108
ULONG BytesPerSector
Definition: partlist.h:92
USHORT PathId
Definition: diskpart.h:166
BOOLEAN BiosFound
Definition: partlist.h:99
ULONGLONG Cylinders
Definition: partlist.h:89
USHORT Lun
Definition: diskpart.h:168
BOOLEAN NoMbr
Definition: diskpart.h:174
USHORT Port
Definition: partlist.h:110
ULONG TracksPerCylinder
Definition: partlist.h:90
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:128
ULONG CylinderAlignment
Definition: partlist.h:96
PDRIVE_LAYOUT_INFORMATION LayoutBuffer
Definition: partlist.h:122
ULONG DiskNumber
Definition: ntddvol.h:113
LARGE_INTEGER StartingOffset
Definition: ntddvol.h:114
LARGE_INTEGER ExtentLength
Definition: ntddvol.h:115
MEDIA_TYPE MediaType
Definition: ntdddisk.h:406
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:405
ULONG TracksPerCylinder
Definition: ntdddisk.h:407
ULONG SectorsPerTrack
Definition: ntdddisk.h:408
ULONG BytesPerSector
Definition: ntdddisk.h:409
PARTITION_INFORMATION PartitionEntry[1]
Definition: ntdddisk.h:426
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
BOOLEAN IsPartitioned
Definition: partlist.h:66
UCHAR PartitionType
Definition: partlist.h:53
BOOLEAN New
Definition: partlist.h:71
ULARGE_INTEGER SectorCount
Definition: partlist.h:50
BOOLEAN BootIndicator
Definition: partlist.h:52
struct _DISKENTRY * DiskEntry
Definition: partlist.h:46
BOOLEAN LogicalPartition
Definition: partlist.h:63
FORMATSTATE FormatState
Definition: partlist.h:61
ULONG OnDiskPartitionNumber
Definition: partlist.h:54
LIST_ENTRY ListEntry
Definition: partlist.h:43
ULONG PartitionNumber
Definition: partlist.h:55
ULARGE_INTEGER StartSector
Definition: partlist.h:49
ULONG PartitionIndex
Definition: partlist.h:56
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:413
LARGE_INTEGER PartitionLength
Definition: ntdddisk.h:414
BOOLEAN RecognizedPartition
Definition: ntdddisk.h:419
BOOLEAN RewritePartition
Definition: ntdddisk.h:420
UCHAR BootCode[440]
Definition: partlist.h:192
PARTITION Partition[PARTITION_TBL_SIZE]
Definition: partlist.h:195
unsigned char PartitionType
Definition: partlist.h:182
unsigned char EndingSector
Definition: partlist.h:184
unsigned char BootFlags
Definition: partlist.h:178
unsigned char StartingHead
Definition: partlist.h:179
unsigned int StartingBlock
Definition: partlist.h:186
unsigned char EndingHead
Definition: partlist.h:183
unsigned char EndingCylinder
Definition: partlist.h:185
unsigned int SectorCount
Definition: partlist.h:187
unsigned char StartingSector
Definition: partlist.h:180
unsigned char StartingCylinder
Definition: partlist.h:181
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:569
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
USHORT MaximumLength
Definition: env_spec_w32.h:370
PVOLUME_DISK_EXTENTS pExtents
Definition: diskpart.h:202
ULONG VolumeNumber
Definition: diskpart.h:191
PWSTR pszFilesystem
Definition: diskpart.h:198
WCHAR VolumeName[MAX_PATH]
Definition: diskpart.h:192
LIST_ENTRY ListEntry
Definition: diskpart.h:189
PWSTR pszLabel
Definition: diskpart.h:197
WCHAR DeviceName[MAX_PATH]
Definition: diskpart.h:193
WCHAR DriveLetter
Definition: diskpart.h:195
DISK_EXTENT Extents[1]
Definition: ntddvol.h:120
ULONG NumberOfDiskExtents
Definition: ntddvol.h:119
VOID RemoveVolume(_In_ PVOLENTRY VolumeEntry)
Definition: partlist.c:2103
LIST_ENTRY VolumeListHead
Definition: partlist.c:72
static VOID GetVolumeType(_In_ HANDLE VolumeHandle, _In_ PVOLENTRY VolumeEntry)
Definition: partlist.c:1256
struct _PARTITION * PPARTITION
#define PARTITION_LINUX
Definition: partlist.c:36
LIST_ENTRY BiosDiskListHead
Definition: partlist.c:71
VOID DestroyVolumeList(VOID)
Definition: partlist.c:1450
struct _PARTITION_SECTOR * PPARTITION_SECTOR
#define PARTITION_TBL_SIZE
Definition: partlist.c:38
static VOID AddVolumeToList(ULONG ulVolumeNumber, PWSTR pszVolumeName)
Definition: partlist.c:1296
NTSTATUS CreateVolumeList(VOID)
Definition: partlist.c:1412
LIST_ENTRY DiskListHead
Definition: partlist.c:70
struct _PARTITION_SECTOR PARTITION_SECTOR
PVOLENTRY CurrentVolume
Definition: partlist.c:76
PPARTENTRY CurrentPartition
Definition: partlist.c:75
PVOLENTRY GetVolumeFromPartition(_In_ PPARTENTRY PartEntry)
Definition: partlist.c:2066
static VOID GetVolumeExtents(_In_ HANDLE VolumeHandle, _In_ PVOLENTRY VolumeEntry)
Definition: partlist.c:1190
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
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_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:584
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