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