ReactOS 0.4.15-dev-8434-g155a7c7
partmgr.c
Go to the documentation of this file.
1/*
2 * PROJECT: Partition manager driver
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Main file
5 * COPYRIGHT: 2020 Victor Perevertkin (victor.perevertkin@reactos.org)
6 */
7
8/* The Partition Manager Driver in ReactOS complements disk.sys/classpnp.sys drivers
9 * (which are derived from Windows 10 drivers) so does not do exactly what Windows 2003 partmgr.sys
10 * does. Here is acts like both partition and volume manager, because volmgr.sys does not (yet)
11 * exist in ReactOS. Thus handles some IOCTL_VOLUME_*, and IOCTL_MOUNTMGR_* IOCTLs.
12 */
13
14#include "partmgr.h"
15
16
17static
18CODE_SEG("PAGE")
21 _In_ CONST PDRIVE_LAYOUT_INFORMATION_EX LayoutEx)
22{
24 PPARTITION_INFORMATION Partition;
25 PPARTITION_INFORMATION_EX PartitionEx;
26
27 PAGED_CODE();
28
29 ASSERT(LayoutEx);
30
31 if (LayoutEx->PartitionStyle != PARTITION_STYLE_MBR)
32 {
34 return NULL;
35 }
36
37 size_t layoutSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry[0]) +
38 LayoutEx->PartitionCount * sizeof (PARTITION_INFORMATION);
39
40 Layout = ExAllocatePoolWithTag(PagedPool, layoutSize, TAG_PARTMGR);
41
42 if (Layout == NULL)
43 {
44 return NULL;
45 }
46
47 Layout->Signature = LayoutEx->Mbr.Signature;
48 Layout->PartitionCount = LayoutEx->PartitionCount;
49
50 for (UINT32 i = 0; i < LayoutEx->PartitionCount; i++)
51 {
52 Partition = &Layout->PartitionEntry[i];
53 PartitionEx = &LayoutEx->PartitionEntry[i];
54
55 Partition->StartingOffset = PartitionEx->StartingOffset;
56 Partition->PartitionLength = PartitionEx->PartitionLength;
57 Partition->RewritePartition = PartitionEx->RewritePartition;
58 Partition->PartitionNumber = PartitionEx->PartitionNumber;
59
60 Partition->PartitionType = PartitionEx->Mbr.PartitionType;
61 Partition->BootIndicator = PartitionEx->Mbr.BootIndicator;
62 Partition->RecognizedPartition = PartitionEx->Mbr.RecognizedPartition;
63 Partition->HiddenSectors = PartitionEx->Mbr.HiddenSectors;
64 }
65
66 return Layout;
67}
68
69static
70CODE_SEG("PAGE")
71PDRIVE_LAYOUT_INFORMATION_EX
74{
75 PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
76
77 PAGED_CODE();
78
79 ASSERT(Layout != NULL);
80
81 size_t layoutSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[0]) +
82 Layout->PartitionCount * sizeof (PARTITION_INFORMATION_EX);
83
84 layoutEx = ExAllocatePoolUninitialized(PagedPool, layoutSize, TAG_PARTMGR);
85
86 if (layoutEx == NULL)
87 {
88 return NULL;
89 }
90
91 layoutEx->PartitionStyle = PARTITION_STYLE_MBR;
92 layoutEx->PartitionCount = Layout->PartitionCount;
93 layoutEx->Mbr.Signature = Layout->Signature;
94
95 for (UINT32 i = 0; i < Layout->PartitionCount; i++)
96 {
97 PPARTITION_INFORMATION part = &Layout->PartitionEntry[i];
98
99 layoutEx->PartitionEntry[i] = (PARTITION_INFORMATION_EX) {
100 .PartitionStyle = PARTITION_STYLE_MBR,
101 .StartingOffset = part->StartingOffset,
102 .PartitionLength = part->PartitionLength,
103 .RewritePartition = part->RewritePartition,
104 .PartitionNumber = part->PartitionNumber,
105 .Mbr = {
106 .PartitionType = part->PartitionType,
107 .BootIndicator = part->BootIndicator,
108 .RecognizedPartition = part->RecognizedPartition,
109 .HiddenSectors = part->HiddenSectors,
110 }
111 };
112 }
113
114 return layoutEx;
115}
116
132static
133CODE_SEG("PAGE")
137{
139
140 PAGED_CODE();
141
142 ASSERT(FdoExtension->LayoutValid && FdoExtension->LayoutCache);
143
144 /* We must be MBR and have only one partition */
145 ASSERT(FdoExtension->DiskData.PartitionStyle == FdoExtension->LayoutCache->PartitionStyle);
146 if (FdoExtension->DiskData.PartitionStyle != PARTITION_STYLE_MBR)
147 return FALSE;
148 if (FdoExtension->LayoutCache->PartitionCount != 1)
149 return FALSE;
150
151 /* Get the single partition entry */
152 PartitionInfo = FdoExtension->LayoutCache->PartitionEntry;
153 ASSERT(FdoExtension->DiskData.PartitionStyle == PartitionInfo->PartitionStyle);
154
155 /* The single partition must start at the beginning of the disk */
156 if (!(PartitionInfo->StartingOffset.QuadPart == 0 &&
157 PartitionInfo->Mbr.HiddenSectors == 0))
158 {
159 return FALSE;
160 }
161
162 /* The disk signature is usually set to 1; warn in case it's not */
163 ASSERT(FdoExtension->DiskData.Mbr.Signature == FdoExtension->LayoutCache->Mbr.Signature);
164 if (FdoExtension->DiskData.Mbr.Signature != 1)
165 {
166 WARN("Super-Floppy disk %lu signature %08x != 1!\n",
167 FdoExtension->DiskData.DeviceNumber, FdoExtension->DiskData.Mbr.Signature);
168 }
169
170 /* The partition must be recognized and report as FAT16 non-bootable */
171 if ((PartitionInfo->Mbr.RecognizedPartition != TRUE) ||
172 (PartitionInfo->Mbr.PartitionType != PARTITION_FAT_16) ||
173 (PartitionInfo->Mbr.BootIndicator != FALSE))
174 {
175 WARN("Super-Floppy disk %lu does not return default settings!\n"
176 " RecognizedPartition = %s, expected TRUE\n"
177 " PartitionType = 0x%02x, expected 0x04 (PARTITION_FAT_16)\n"
178 " BootIndicator = %s, expected FALSE\n",
179 FdoExtension->DiskData.DeviceNumber,
180 PartitionInfo->Mbr.RecognizedPartition ? "TRUE" : "FALSE",
181 PartitionInfo->Mbr.PartitionType,
182 PartitionInfo->Mbr.BootIndicator ? "TRUE" : "FALSE");
183 }
184
185 /* The partition and disk sizes should agree */
186 if (PartitionInfo->PartitionLength.QuadPart != FdoExtension->DiskData.DiskSize)
187 {
188 WARN("PartitionLength = %I64u is different from DiskSize = %I64u\n",
189 PartitionInfo->PartitionLength.QuadPart, FdoExtension->DiskData.DiskSize);
190 }
191
192 return TRUE;
193}
194
195static
196CODE_SEG("PAGE")
197VOID
200 _Inout_ PDRIVE_LAYOUT_INFORMATION_EX NewLayout)
201{
203 PSINGLE_LIST_ENTRY curEntry, prevEntry;
204 UINT32 totalPartitions = 0;
205
206 // Clear the partition numbers from the list entries
207 for (UINT32 i = 0; i < NewLayout->PartitionCount; i++)
208 {
209 NewLayout->PartitionEntry[i].PartitionNumber = 0;
210 }
211
212 // iterate over old partition list
213 prevEntry = &FdoExtension->PartitionList;
214 curEntry = FdoExtension->PartitionList.Next;
215 while (curEntry != NULL)
216 {
217 PPARTITION_EXTENSION partExt = CONTAINING_RECORD(curEntry, PARTITION_EXTENSION, ListEntry);
218 UINT32 partNumber = 0; // count detected partitions for device symlinks
219 BOOLEAN found = FALSE;
221
222 // trying to find this partition in returned layout
223 for (UINT32 i = 0; i < NewLayout->PartitionCount; i++)
224 {
225 partEntry = &NewLayout->PartitionEntry[i];
226
227 // skip unused and container partitions
228 if (NewLayout->PartitionStyle == PARTITION_STYLE_MBR &&
231 {
232 continue;
233 }
234
235 partNumber++;
236
237 // skip already found partitions
238 if (partEntry->PartitionNumber)
239 {
240 continue;
241 }
242
243 // skip if partitions are not equal
244 if (partEntry->StartingOffset.QuadPart != partExt->StartingOffset ||
245 partEntry->PartitionLength.QuadPart != partExt->PartitionLength)
246 {
247 continue;
248 }
249
250 // found matching partition - processing it
251 found = TRUE;
252 break;
253 }
254
255 if (found)
256 {
257 // update (possibly changed) partition metadata
258 if (NewLayout->PartitionStyle == PARTITION_STYLE_MBR)
259 {
260 partExt->Mbr.PartitionType = partEntry->Mbr.PartitionType;
261 partExt->Mbr.BootIndicator = partEntry->Mbr.BootIndicator;
262 }
263 else
264 {
265 partExt->Gpt.PartitionType = partEntry->Gpt.PartitionType;
266 partExt->Gpt.PartitionId = partEntry->Gpt.PartitionId;
267 partExt->Gpt.Attributes = partEntry->Gpt.Attributes;
268
269 RtlCopyMemory(partExt->Gpt.Name, partEntry->Gpt.Name, sizeof(partExt->Gpt.Name));
270 }
271
272 partExt->OnDiskNumber = partNumber;
273 partEntry->PartitionNumber = partNumber; // mark it as a found one
274 totalPartitions++;
275 }
276 else
277 {
278 // detach the device from the list
279 prevEntry->Next = curEntry->Next;
280 curEntry = prevEntry;
281 partExt->Attached = FALSE;
282
283 // enumerated PDOs will receive IRP_MN_REMOVE_DEVICE
284 if (!partExt->IsEnumerated)
285 {
286 PartitionHandleRemove(partExt, TRUE);
287 }
288 }
289
290 prevEntry = curEntry;
291 curEntry = curEntry->Next;
292 }
293
294 UINT32 partNumber = 0;
295 UINT32 pdoNumber = 1;
296
297 // now looking through remaining "new" partitions
298 for (UINT32 i = 0; i < NewLayout->PartitionCount; i++)
299 {
300 PPARTITION_INFORMATION_EX partEntry = &NewLayout->PartitionEntry[i];
301
302 // again, skip unused and container partitions
303 if (NewLayout->PartitionStyle == PARTITION_STYLE_MBR &&
306 {
307 continue;
308 }
309
310 partNumber++;
311
312 // and skip processed partitions
313 if (partEntry->PartitionNumber != 0)
314 {
315 continue;
316 }
317
318 // find the first free PDO index
319 for (PSINGLE_LIST_ENTRY curEntry = FdoExtension->PartitionList.Next;
320 curEntry != NULL;
321 curEntry = curEntry->Next)
322 {
323 PPARTITION_EXTENSION partExt = CONTAINING_RECORD(curEntry,
325 ListEntry);
326
327 if (partExt->DetectedNumber == pdoNumber)
328 {
329 // found a matching pdo number - restart the search
330 curEntry = FdoExtension->PartitionList.Next;
331 pdoNumber++;
332 }
333 }
334
335 partEntry->PartitionNumber = partNumber;
336
337 PDEVICE_OBJECT partitionDevice;
339 partEntry,
340 pdoNumber,
341 NewLayout->PartitionStyle,
342 &partitionDevice);
343
344 if (!NT_SUCCESS(status))
345 {
346 partEntry->PartitionNumber = 0;
347 continue;
348 }
349
350 // mark partition as removable if parent device is removable
351 if (FdoExtension->LowerDevice->Characteristics & FILE_REMOVABLE_MEDIA)
352 partitionDevice->Characteristics |= FILE_REMOVABLE_MEDIA;
353
354 totalPartitions++;
355
356 // insert the structure to the partition list
357 curEntry = FdoExtension->PartitionList.Next;
358 prevEntry = NULL;
359 while (curEntry != NULL)
360 {
361 PPARTITION_EXTENSION curPart = CONTAINING_RECORD(curEntry,
363 ListEntry);
364 if (curPart->OnDiskNumber < partNumber)
365 {
366 prevEntry = curEntry;
367 curEntry = curPart->ListEntry.Next;
368 }
369 else
370 { // we found where to put the partition
371 break;
372 }
373 }
374
375 PPARTITION_EXTENSION partExt = partitionDevice->DeviceExtension;
376
377 if (prevEntry)
378 {
379 // insert after prevEntry
380 partExt->ListEntry.Next = prevEntry->Next;
381 prevEntry->Next = &partExt->ListEntry;
382 }
383 else
384 {
385 // insert at the beginning
386 partExt->ListEntry.Next = FdoExtension->PartitionList.Next;
387 FdoExtension->PartitionList.Next = &partExt->ListEntry;
388 }
389
390 partExt->Attached = TRUE;
391 }
392
393 FdoExtension->EnumeratedPartitionsTotal = totalPartitions;
394}
395
405static
406CODE_SEG("PAGE")
410 _Out_ PDRIVE_LAYOUT_INFORMATION_EX *DriveLayout)
411{
412 PAGED_CODE();
413
414 if (FdoExtension->LayoutValid)
415 {
416 *DriveLayout = FdoExtension->LayoutCache;
417 return STATUS_SUCCESS;
418 }
419
420 PDRIVE_LAYOUT_INFORMATION_EX layoutEx = NULL;
421 NTSTATUS status = IoReadPartitionTableEx(FdoExtension->LowerDevice, &layoutEx);
422 if (!NT_SUCCESS(status))
423 return status;
424
425 if (FdoExtension->LayoutCache)
426 ExFreePool(FdoExtension->LayoutCache);
427
428 FdoExtension->LayoutCache = layoutEx;
429 FdoExtension->LayoutValid = TRUE;
430
431 FdoExtension->DiskData.PartitionStyle = layoutEx->PartitionStyle;
432 if (FdoExtension->DiskData.PartitionStyle == PARTITION_STYLE_MBR)
433 {
434 FdoExtension->DiskData.Mbr.Signature = layoutEx->Mbr.Signature;
435 // FdoExtension->DiskData.Mbr.Checksum = geometryEx.Partition.Mbr.CheckSum;
436 }
437 else
438 {
439 FdoExtension->DiskData.Gpt.DiskId = layoutEx->Gpt.DiskId;
440 }
441
443
444 *DriveLayout = layoutEx;
445 return status;
446}
447
448static
449CODE_SEG("PAGE")
453 _In_ PIRP Irp)
454{
456
457 PAGED_CODE();
458
459 // We're patching the DISK_PARTITION_INFO part of the returned structure
460 // as disk.sys doesn't really know about the partition table on a disk
461
462 PDISK_GEOMETRY_EX_INTERNAL geometryEx = Irp->AssociatedIrp.SystemBuffer;
463 ULONG outBufferLength = ioStack->Parameters.DeviceIoControl.OutputBufferLength;
465
467 FdoExtension->LowerDevice,
468 NULL,
469 0,
470 geometryEx,
471 outBufferLength,
472 FALSE);
473
474 if (!NT_SUCCESS(status))
475 {
476 return status;
477 }
478
479 // if DISK_PARTITION_INFO fits the output size
480 if (outBufferLength >= FIELD_OFFSET(DISK_GEOMETRY_EX_INTERNAL, Detection))
481 {
483
484 geometryEx->Partition.SizeOfPartitionInfo = sizeof(geometryEx->Partition);
485 geometryEx->Partition.PartitionStyle = FdoExtension->DiskData.PartitionStyle;
486
487 switch (geometryEx->Partition.PartitionStyle)
488 {
490 geometryEx->Partition.Mbr.Signature = FdoExtension->DiskData.Mbr.Signature;
491 // checksum?
492 break;
493
495 geometryEx->Partition.Gpt.DiskId = FdoExtension->DiskData.Gpt.DiskId;
496 break;
497
498 default:
499 RtlZeroMemory(&geometryEx->Partition, sizeof(geometryEx->Partition));
500 }
501
503 }
504
505 // the logic is copied from disk.sys
506 Irp->IoStatus.Information = min(outBufferLength, sizeof(DISK_GEOMETRY_EX_INTERNAL));
507
508 return status;
509}
510
511static
512CODE_SEG("PAGE")
516 _In_ PIRP Irp)
517{
518 PPARTITION_INFORMATION partInfo = Irp->AssociatedIrp.SystemBuffer;
519
520 PAGED_CODE();
521
522 if (!VerifyIrpOutBufferSize(Irp, sizeof(*partInfo)))
523 {
525 }
526
528
529 *partInfo = (PARTITION_INFORMATION){
531 .StartingOffset.QuadPart = 0,
532 .PartitionLength.QuadPart = FdoExtension->DiskData.DiskSize,
533 .HiddenSectors = 0,
534 .PartitionNumber = 0,
535 .BootIndicator = FALSE,
536 .RewritePartition = FALSE,
537 .RecognizedPartition = FALSE,
538 };
539
541
542 Irp->IoStatus.Information = sizeof(*partInfo);
543 return STATUS_SUCCESS;
544}
545
546static
547CODE_SEG("PAGE")
551 _In_ PIRP Irp)
552{
553 PPARTITION_INFORMATION_EX partInfoEx = Irp->AssociatedIrp.SystemBuffer;
554
555 PAGED_CODE();
556
557 if (!VerifyIrpOutBufferSize(Irp, sizeof(*partInfoEx)))
558 {
560 }
561
563
564 // most of the fields a zeroed for Partition0
565 *partInfoEx = (PARTITION_INFORMATION_EX){
566 .PartitionLength.QuadPart = FdoExtension->DiskData.DiskSize,
567 .PartitionStyle = FdoExtension->DiskData.PartitionStyle,
568 };
569
571
572 Irp->IoStatus.Information = sizeof(*partInfoEx);
573 return STATUS_SUCCESS;
574}
575
576static
577CODE_SEG("PAGE")
581 _In_ PIRP Irp)
582{
583 PAGED_CODE();
584
586
587 PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
589 if (!NT_SUCCESS(status))
590 {
592 return status;
593 }
594
595 // checking this value from layoutEx in case it has been changed
596 if (layoutEx->PartitionStyle != PARTITION_STYLE_MBR)
597 {
600 }
601
602 size_t size = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry[0]);
603 size += layoutEx->PartitionCount * sizeof(PARTITION_INFORMATION);
604
606 {
609 }
610
612
614
615 if (partitionList == NULL)
616 {
617 Irp->IoStatus.Information = 0;
619 }
620
621 RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, partitionList, size);
622 ExFreePoolWithTag(partitionList, TAG_PARTMGR);
623
624 Irp->IoStatus.Information = size;
625 return STATUS_SUCCESS;
626}
627
628static
629CODE_SEG("PAGE")
633 _In_ PIRP Irp)
634{
635 PAGED_CODE();
636
638
639 PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
641 if (!NT_SUCCESS(status))
642 {
644 return status;
645 }
646
647 size_t size = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[0]);
648 size += layoutEx->PartitionCount * sizeof(PARTITION_INFORMATION_EX);
649
651 {
654 }
655
656 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, layoutEx, size);
657
659
660 Irp->IoStatus.Information = size;
661 return STATUS_SUCCESS;
662}
663
664static
665CODE_SEG("PAGE")
669 _In_ PIRP Irp)
670{
671 PDRIVE_LAYOUT_INFORMATION layoutInfo = Irp->AssociatedIrp.SystemBuffer;
672
673 PAGED_CODE();
674
675 if (!VerifyIrpInBufferSize(Irp, sizeof(*layoutInfo)))
676 {
678 }
679
680 size_t layoutSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry[0]);
681 layoutSize += layoutInfo->PartitionCount * sizeof(PARTITION_INFORMATION);
682
683 if (!VerifyIrpInBufferSize(Irp, layoutSize))
684 {
686 }
687
688 PDRIVE_LAYOUT_INFORMATION_EX layoutEx = PartMgrConvertLayoutToExtended(layoutInfo);
689
690 if (layoutEx == NULL)
691 {
692 Irp->IoStatus.Information = 0;
694 }
695
697
698 // If the current disk is super-floppy but the user changes
699 // the number of partitions to > 1, fail the call.
700 if (FdoExtension->IsSuperFloppy && (layoutEx->PartitionCount > 1))
701 {
704 }
705
706 // this in fact updates the bus relations
708
709 // write the partition table to the disk
710 NTSTATUS status = IoWritePartitionTableEx(FdoExtension->LowerDevice, layoutEx);
711 if (NT_SUCCESS(status))
712 {
713 // save the layout cache
714 if (FdoExtension->LayoutCache)
715 {
716 ExFreePool(FdoExtension->LayoutCache);
717 }
718 FdoExtension->LayoutCache = layoutEx;
719 FdoExtension->LayoutValid = TRUE;
720
721 // set updated partition numbers
722 for (UINT32 i = 0; i < layoutInfo->PartitionCount; i++)
723 {
724 PPARTITION_INFORMATION part = &layoutInfo->PartitionEntry[i];
725
726 part->PartitionNumber = layoutEx->PartitionEntry[i].PartitionNumber;
727 }
728
730 }
731 else
732 {
733 FdoExtension->LayoutValid = FALSE;
734 }
735
737
739
740 // notify everyone that the disk layout has changed
742
743 notification.Event = GUID_IO_DISK_LAYOUT_CHANGE;
744 notification.Version = 1;
746 notification.FileObject = NULL;
747 notification.NameBufferOffset = -1;
748
751 NULL,
752 NULL);
753
754 Irp->IoStatus.Information = layoutSize;
755 return STATUS_SUCCESS;
756}
757
758static
759CODE_SEG("PAGE")
763 _In_ PIRP Irp)
764{
765 PDRIVE_LAYOUT_INFORMATION_EX layoutEx, layoutUser = Irp->AssociatedIrp.SystemBuffer;
767
768 PAGED_CODE();
769
770 if (!VerifyIrpInBufferSize(Irp, sizeof(*layoutUser)))
771 {
773 }
774
775 size_t layoutSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[0]);
776 layoutSize += layoutUser->PartitionCount * sizeof(PARTITION_INFORMATION_EX);
777
778 if (!VerifyIrpInBufferSize(Irp, layoutSize))
779 {
781 }
782
783 // we need to copy the structure from the IRP input buffer
784 layoutEx = ExAllocatePoolWithTag(PagedPool, layoutSize, TAG_PARTMGR);
785 if (!layoutEx)
786 {
787 Irp->IoStatus.Information = 0;
789 }
790
791 RtlCopyMemory(layoutEx, layoutUser, layoutSize);
792
794
795 // If the current disk is super-floppy but the user changes either
796 // the disk type or the number of partitions to > 1, fail the call.
797 if (FdoExtension->IsSuperFloppy &&
798 ((layoutEx->PartitionStyle != PARTITION_STYLE_MBR) ||
799 (layoutEx->PartitionCount > 1)))
800 {
803 }
804
805 // if partition count is 0, it's the same as IOCTL_DISK_CREATE_DISK
806 if (layoutEx->PartitionCount == 0)
807 {
808 CREATE_DISK createDisk = {0};
809 createDisk.PartitionStyle = layoutEx->PartitionStyle;
810 if (createDisk.PartitionStyle == PARTITION_STYLE_MBR)
811 {
812 createDisk.Mbr.Signature = layoutEx->Mbr.Signature;
813 }
814 else if (createDisk.PartitionStyle == PARTITION_STYLE_GPT)
815 {
816 createDisk.Gpt.DiskId = layoutEx->Gpt.DiskId;
817 }
818
819 status = IoCreateDisk(FdoExtension->LowerDevice, &createDisk);
820 }
821 else
822 {
823 // this in fact updates the bus relations
825
826 // write the partition table to the disk
827 status = IoWritePartitionTableEx(FdoExtension->LowerDevice, layoutEx);
828 if (NT_SUCCESS(status))
829 {
830 // set updated partition numbers
831 for (UINT32 i = 0; i < layoutEx->PartitionCount; i++)
832 {
833 PPARTITION_INFORMATION_EX part = &layoutEx->PartitionEntry[i];
834
835 part->PartitionNumber = layoutEx->PartitionEntry[i].PartitionNumber;
836 }
837 }
838 }
839
840 // update the layout cache
841 if (NT_SUCCESS(status))
842 {
843 if (FdoExtension->LayoutCache)
844 {
845 ExFreePool(FdoExtension->LayoutCache);
846 }
847 FdoExtension->LayoutCache = layoutEx;
848 FdoExtension->LayoutValid = TRUE;
849
851 }
852 else
853 {
854 FdoExtension->LayoutValid = FALSE;
855 }
856
858
860
861 // notify everyone that the disk layout has changed
863
864 notification.Event = GUID_IO_DISK_LAYOUT_CHANGE;
865 notification.Version = 1;
867 notification.FileObject = NULL;
868 notification.NameBufferOffset = -1;
869
872 NULL,
873 NULL);
874
875 Irp->IoStatus.Information = layoutSize;
876 return STATUS_SUCCESS;
877}
878
879static
880CODE_SEG("PAGE")
884 _In_ PIRP Irp)
885{
886 PAGED_CODE();
887
889 FdoExtension->LayoutValid = FALSE;
891
893 return STATUS_SUCCESS;
894}
895
896static
897CODE_SEG("PAGE")
901 _In_ PIRP Irp)
902{
903 PAGED_CODE();
904
905 PCREATE_DISK createDisk = Irp->AssociatedIrp.SystemBuffer;
906 if (!VerifyIrpInBufferSize(Irp, sizeof(*createDisk)))
907 {
909 }
910
912
913 NTSTATUS status = IoCreateDisk(FdoExtension->LowerDevice, createDisk);
914
915 FdoExtension->LayoutValid = FALSE;
917
919 return status;
920}
921
922static
923CODE_SEG("PAGE")
927 _In_ PIRP Irp)
928{
929 CREATE_DISK createDisk = { .PartitionStyle = PARTITION_STYLE_RAW };
930
931 PAGED_CODE();
932
934
935 NTSTATUS status = IoCreateDisk(FdoExtension->LowerDevice, &createDisk);
936
937 FdoExtension->LayoutValid = FALSE;
939
941 return status;
942}
943
944static
945CODE_SEG("PAGE")
949 _In_ PIRP Irp)
950{
951 // obtain the disk device number
952 // this is not expected to change thus not in PartMgrRefreshDiskData
953 STORAGE_DEVICE_NUMBER deviceNumber;
955 FdoExtension->LowerDevice,
956 NULL,
957 0,
958 &deviceNumber,
959 sizeof(deviceNumber),
960 FALSE);
961 if (!NT_SUCCESS(status))
962 {
963 return status;
964 }
965
966 FdoExtension->DiskData.DeviceNumber = deviceNumber.DeviceNumber;
967
968 // register the disk interface
969 // partmgr.sys from Windows 8.1 also registers a mysterious GUID_DEVINTERFACE_HIDDEN_DISK here
970 UNICODE_STRING interfaceName;
972 &GUID_DEVINTERFACE_DISK,
973 NULL,
974 &interfaceName);
975
976 if(!NT_SUCCESS(status))
977 {
978 ERR("Failed to register GUID_DEVINTERFACE_DISK, status %x\n", status);
979 return status;
980 }
981
982 FdoExtension->DiskInterfaceName = interfaceName;
983 status = IoSetDeviceInterfaceState(&interfaceName, TRUE);
984
985 INFO("Disk interface %wZ\n", &interfaceName);
986
987 if (!NT_SUCCESS(status))
988 {
989 RtlFreeUnicodeString(&interfaceName);
990 RtlInitUnicodeString(&FdoExtension->DiskInterfaceName, NULL);
991 }
992
993 return status;
994}
995
1003static
1004CODE_SEG("PAGE")
1008{
1010
1011 PAGED_CODE();
1012
1013 // get the DiskSize and BytesPerSector
1014 DISK_GEOMETRY_EX geometryEx;
1016 FdoExtension->LowerDevice,
1017 NULL,
1018 0,
1019 &geometryEx,
1020 sizeof(geometryEx),
1021 FALSE);
1022 if (!NT_SUCCESS(status))
1023 return status;
1024
1025 FdoExtension->DiskData.DiskSize = geometryEx.DiskSize.QuadPart;
1026 FdoExtension->DiskData.BytesPerSector = geometryEx.Geometry.BytesPerSector;
1027
1028 // get the partition style-related info
1029 PDRIVE_LAYOUT_INFORMATION_EX layoutEx = NULL;
1031 if (!NT_SUCCESS(status))
1032 return status;
1033
1034 return STATUS_SUCCESS;
1035}
1036
1037static
1038CODE_SEG("PAGE")
1042 _In_ PIRP Irp)
1043{
1046
1047 PAGED_CODE();
1048
1049 if (type == BusRelations)
1050 {
1052
1054 if (!NT_SUCCESS(status))
1055 {
1057 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1058 Irp->IoStatus.Information = 0;
1060 return Irp->IoStatus.Status;
1061 }
1062
1063 INFO("Partition style %u\n", FdoExtension->DiskData.PartitionStyle);
1064
1065 // PartMgrRefreshDiskData() calls PartMgrGetDriveLayout() inside
1066 // so we're sure here that it returns only the cached layout.
1067 PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
1069
1071
1072 // now fill the DeviceRelations structure
1073 TRACE("Reporting %u partitions\n", FdoExtension->EnumeratedPartitionsTotal);
1074
1075 PDEVICE_RELATIONS deviceRelations =
1077 sizeof(DEVICE_RELATIONS)
1078 + sizeof(PDEVICE_OBJECT)
1079 * (FdoExtension->EnumeratedPartitionsTotal - 1),
1080 TAG_PARTMGR);
1081
1082 if (!deviceRelations)
1083 {
1085 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1086 Irp->IoStatus.Information = 0;
1088 return Irp->IoStatus.Status;
1089 }
1090
1091 deviceRelations->Count = 0;
1092
1093 PSINGLE_LIST_ENTRY curEntry = FdoExtension->PartitionList.Next;
1094 while (curEntry != NULL)
1095 {
1096 PPARTITION_EXTENSION partExt = CONTAINING_RECORD(curEntry,
1098 ListEntry);
1099
1100 // mark the PDO to know that we don't need to manually delete it
1101 partExt->IsEnumerated = TRUE;
1102 deviceRelations->Objects[deviceRelations->Count++] = partExt->DeviceObject;
1104
1105 curEntry = partExt->ListEntry.Next;
1106 }
1107
1108 ASSERT(deviceRelations->Count == FdoExtension->EnumeratedPartitionsTotal);
1109
1111
1112 Irp->IoStatus.Information = (ULONG_PTR)deviceRelations;
1113 Irp->IoStatus.Status = STATUS_SUCCESS;
1114 }
1115
1117 return IoCallDriver(FdoExtension->LowerDevice, Irp);
1118}
1119
1120static
1121CODE_SEG("PAGE")
1125 _In_ PIRP Irp)
1126{
1127 PAGED_CODE();
1128
1129 if (FdoExtension->DiskInterfaceName.Buffer)
1130 {
1131 IoSetDeviceInterfaceState(&FdoExtension->DiskInterfaceName, FALSE);
1132 RtlFreeUnicodeString(&FdoExtension->DiskInterfaceName);
1133 RtlInitUnicodeString(&FdoExtension->DiskInterfaceName, NULL);
1134 }
1135
1136 // Send the IRP down the stack
1138 Irp->IoStatus.Status = STATUS_SUCCESS;
1139 NTSTATUS status = IoCallDriver(FdoExtension->LowerDevice, Irp);
1140
1141 IoDetachDevice(FdoExtension->LowerDevice);
1142 IoDeleteDevice(FdoExtension->DeviceObject);
1143 return status;
1144}
1145
1146static
1147CODE_SEG("PAGE")
1151 _In_ PIRP Irp)
1152{
1153 PAGED_CODE();
1154
1155 // all enumerated child devices should receive IRP_MN_REMOVE_DEVICE
1156 // removing only non-enumerated ones here
1157 for (PSINGLE_LIST_ENTRY curEntry = FdoExtension->PartitionList.Next;
1158 curEntry != NULL;
1159 curEntry = curEntry->Next)
1160 {
1161 PPARTITION_EXTENSION partExt = CONTAINING_RECORD(curEntry,
1163 ListEntry);
1164
1165 if (partExt->IsEnumerated)
1166 {
1167 PartitionHandleRemove(partExt, TRUE);
1168 }
1169 }
1170
1171 // Send the IRP down the stack
1173 Irp->IoStatus.Status = STATUS_SUCCESS;
1174 return IoCallDriver(FdoExtension->LowerDevice, Irp);
1175}
1176
1177static
1178CODE_SEG("PAGE")
1180NTAPI
1184{
1186
1187 PAGED_CODE();
1188
1190 sizeof(FDO_EXTENSION),
1191 0,
1194 FALSE,
1195 &deviceObject);
1196
1197 if (!NT_SUCCESS(status))
1198 {
1199 ERR("Failed to create FDO 0x%x\n", status);
1200 return status;
1201 }
1202
1203 PFDO_EXTENSION deviceExtension = deviceObject->DeviceExtension;
1204 RtlZeroMemory(deviceExtension, sizeof(*deviceExtension));
1205
1206 deviceExtension->IsFDO = TRUE;
1207 deviceExtension->DeviceObject = deviceObject;
1209 deviceExtension->PhysicalDiskDO = PhysicalDeviceObject;
1211
1212 // the the attaching failed
1213 if (!deviceExtension->LowerDevice)
1214 {
1216
1217 return STATUS_DEVICE_REMOVED;
1218 }
1220
1221 // device is initialized
1222 deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1223
1224 return STATUS_SUCCESS;
1225}
1226
1227static
1229NTAPI
1232 _In_ PIRP Irp)
1233{
1235 PFDO_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
1237
1238 // Note: IRP_MJ_DEVICE_CONTROL handler in the storage stack must be able to pass IOCTLs
1239 // at an IRQL higher than PASSIVE_LEVEL
1240
1241 INFO("IRP_MJ_DEVICE_CONTROL %p Irp %p IOCTL %x isFdo: %u\n",
1242 DeviceObject, Irp, ioStack->Parameters.DeviceIoControl.IoControlCode, fdoExtension->IsFDO);
1243
1244 if (!fdoExtension->IsFDO)
1245 {
1247 }
1248
1249 switch (ioStack->Parameters.DeviceIoControl.IoControlCode)
1250 {
1252 status = FdoIoctlDiskGetDriveGeometryEx(fdoExtension, Irp);
1253 break;
1254
1256 status = FdoIoctlDiskGetPartitionInfo(fdoExtension, Irp);
1257 break;
1258
1260 status = FdoIoctlDiskGetPartitionInfoEx(fdoExtension, Irp);
1261 break;
1262
1264 status = FdoIoctlDiskGetDriveLayout(fdoExtension, Irp);
1265 break;
1266
1268 status = FdoIoctlDiskGetDriveLayoutEx(fdoExtension, Irp);
1269 break;
1270
1272 status = FdoIoctlDiskSetDriveLayout(fdoExtension, Irp);
1273 break;
1274
1276 status = FdoIoctlDiskSetDriveLayoutEx(fdoExtension, Irp);
1277 break;
1278
1280 status = FdoIoctlDiskUpdateProperties(fdoExtension, Irp);
1281 break;
1282
1284 status = FdoIoctlDiskCreateDisk(fdoExtension, Irp);
1285 break;
1286
1288 status = FdoIoctlDiskDeleteDriveLayout(fdoExtension, Irp);
1289 break;
1290 // case IOCTL_DISK_GROW_PARTITION: // todo
1291 default:
1293 }
1294
1295 Irp->IoStatus.Status = status;
1297 return status;
1298}
1299
1300static
1301CODE_SEG("PAGE")
1303NTAPI
1306 _In_ PIRP Irp)
1307{
1308 PAGED_CODE();
1309
1310 PFDO_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
1312
1313 INFO("IRP_MJ_PNP %p Irp %p %s isFDO: %u\n",
1314 DeviceObject, Irp, GetIRPMinorFunctionString(ioStack->MinorFunction), fdoExtension->IsFDO);
1315
1316 if (!fdoExtension->IsFDO)
1317 {
1319 }
1320
1321 switch (ioStack->MinorFunction) {
1322
1324 {
1326
1327 // if this is sent to the FDO so we should forward it down the
1328 // attachment chain before we can start the FDO
1329
1330 if (!IoForwardIrpSynchronously(fdoExtension->LowerDevice, Irp))
1331 {
1333 }
1334 else
1335 {
1336 status = FdoHandleStartDevice(fdoExtension, Irp);
1337 }
1338
1339 Irp->IoStatus.Status = status;
1341 return status;
1342 }
1344 {
1345 return FdoHandleDeviceRelations(fdoExtension, Irp);
1346 }
1348 {
1349 return FdoHandleSurpriseRemoval(fdoExtension, Irp);
1350 }
1352 {
1353 return FdoHandleRemoveDevice(fdoExtension, Irp);
1354 }
1359 case IRP_MN_STOP_DEVICE:
1360 {
1361 Irp->IoStatus.Status = STATUS_SUCCESS;
1362 // fallthrough
1363 }
1364 default:
1365 {
1367 return IoCallDriver(fdoExtension->LowerDevice, Irp);
1368 }
1369 }
1370}
1371
1372static
1374NTAPI
1377 _In_ PIRP Irp)
1378{
1379 PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
1381
1382 if (!partExt->IsFDO)
1383 {
1384 if (!partExt->IsEnumerated)
1385 {
1386 Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
1389 }
1390 else
1391 {
1392 ioStack->Parameters.Read.ByteOffset.QuadPart += partExt->StartingOffset;
1393 }
1394 }
1395
1397 return IoCallDriver(partExt->LowerDevice, Irp);
1398}
1399
1402NTAPI
1405 _In_ PIRP Irp)
1406{
1407 PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
1409
1411
1412 if (!partExt->IsFDO)
1413 {
1415
1416 if (!partExt->IsEnumerated)
1417 {
1419 }
1420 else if (ioStack->MinorFunction == IRP_MN_SET_POWER ||
1422 {
1424 }
1425 else
1426 {
1427 status = Irp->IoStatus.Status;
1428 }
1429
1430 Irp->IoStatus.Status = status;
1432 return status;
1433 }
1434 else
1435 {
1437 return PoCallDriver(partExt->LowerDevice, Irp);
1438 }
1439}
1440
1443NTAPI
1446 _In_ PIRP Irp)
1447{
1448 PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
1449 PDEVICE_OBJECT lowerDevice;
1450
1451 // forward to the partition0 device in both cases
1452 if (!partExt->IsFDO)
1453 {
1454 if (!partExt->IsEnumerated)
1455 {
1456 Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
1459 }
1460 else
1461 {
1462 PFDO_EXTENSION fdoExtension = partExt->LowerDevice->DeviceExtension;
1463 lowerDevice = fdoExtension->LowerDevice;
1464 }
1465 }
1466 else
1467 {
1468 lowerDevice = partExt->LowerDevice;
1469 }
1470
1472 return IoCallDriver(lowerDevice, Irp);
1473}
1474
1475CODE_SEG("PAGE")
1476VOID
1477NTAPI
1480{
1481
1482}
1483
1484CODE_SEG("INIT")
1486NTAPI
1490{
1491 DriverObject->DriverUnload = PartMgrUnload;
1492 DriverObject->DriverExtension->AddDevice = PartMgrAddDevice;
1495 DriverObject->MajorFunction[IRP_MJ_READ] = PartMgrReadWrite;
1496 DriverObject->MajorFunction[IRP_MJ_WRITE] = PartMgrReadWrite;
1498 DriverObject->MajorFunction[IRP_MJ_PNP] = PartMgrPnp;
1501 DriverObject->MajorFunction[IRP_MJ_POWER] = PartMgrPower;
1502
1503 return STATUS_SUCCESS;
1504}
#define ExAllocatePoolUninitialized
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
#define CODE_SEG(...)
unsigned char BOOLEAN
unsigned int UINT32
LONG NTSTATUS
Definition: precomp.h:26
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
#define PARTITION_FAT_16
Definition: disk.h:90
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
_In_ PIRP Irp
Definition: csq.h:116
#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
FORCEINLINE PCHAR GetIRPMinorFunctionString(UCHAR MinorFunction)
Definition: driverdbg.h:13
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
#define INFO
Definition: debug.h:89
#define ULONG_PTR
Definition: config.h:101
NTSTATUS PartitionHandleRemove(_In_ PPARTITION_EXTENSION PartExt, _In_ BOOLEAN FinalRemove)
Definition: partition.c:276
NTSTATUS PartitionHandleDeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partition.c:563
NTSTATUS PartitionHandlePnp(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partition.c:499
NTSTATUS PartitionCreateDevice(_In_ PDEVICE_OBJECT FDObject, _In_ PPARTITION_INFORMATION_EX PartitionEntry, _In_ UINT32 PdoNumber, _In_ PARTITION_STYLE PartitionStyle, _Out_ PDEVICE_OBJECT *PDO)
Definition: partition.c:15
@ FdoExtension
Definition: precomp.h:48
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define PagedPool
Definition: env_spec_w32.h:308
#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
Definition: ntddk_ex.h:208
#define IOCTL_DISK_GET_PARTITION_INFO_EX
Definition: ntddk_ex.h:206
#define IOCTL_DISK_GET_DRIVE_LAYOUT_EX
Definition: ntddk_ex.h:207
NTSTATUS NTAPI IoCreateDisk(IN PDEVICE_OBJECT DeviceObject, IN PCREATE_DISK Disk)
Definition: fstubex.c:1807
NTSTATUS NTAPI IoWritePartitionTableEx(IN PDEVICE_OBJECT DeviceObject, IN PDRIVE_LAYOUT_INFORMATION_EX DriveLayout)
Definition: fstubex.c:2466
NTSTATUS NTAPI IoReadPartitionTableEx(IN PDEVICE_OBJECT DeviceObject, IN PDRIVE_LAYOUT_INFORMATION_EX *DriveLayout)
Definition: fstubex.c:2279
MxDeviceObject deviceObject
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
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
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
struct _PARTITION_INFORMATION_EX PARTITION_INFORMATION_EX
@ PARTITION_STYLE_GPT
Definition: imports.h:202
@ PARTITION_STYLE_MBR
Definition: imports.h:201
#define min(a, b)
Definition: monoChain.cc:55
#define _Inout_
Definition: ms_sal.h:378
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
DRIVER_DISPATCH(nfs41_FsdDispatch)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define IOCTL_DISK_SET_DRIVE_LAYOUT
Definition: ntdddisk.h:205
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:321
#define IOCTL_DISK_GET_DRIVE_LAYOUT
Definition: ntdddisk.h:91
#define IOCTL_DISK_CREATE_DISK
Definition: ntdddisk.h:55
struct _PARTITION_INFORMATION PARTITION_INFORMATION
#define IOCTL_DISK_SET_DRIVE_LAYOUT_EX
Definition: ntdddisk.h:208
#define IOCTL_DISK_GET_PARTITION_INFO
Definition: ntdddisk.h:106
#define IOCTL_DISK_DELETE_DRIVE_LAYOUT
Definition: ntdddisk.h:58
#define IOCTL_DISK_UPDATE_PROPERTIES
Definition: ntdddisk.h:242
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:143
@ SynchronizationEvent
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
#define IoCompleteRequest
Definition: irp.c:1240
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1625
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:758
#define STATUS_DEVICE_REMOVED
Definition: ntstatus.h:809
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:428
static PDRIVE_LAYOUT_INFORMATION PartMgrConvertExtendedToLayout(_In_ CONST PDRIVE_LAYOUT_INFORMATION_EX LayoutEx)
Definition: partmgr.c:20
static NTSTATUS FdoIoctlDiskCreateDisk(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:899
static PDRIVE_LAYOUT_INFORMATION_EX PartMgrConvertLayoutToExtended(_In_ CONST PDRIVE_LAYOUT_INFORMATION Layout)
Definition: partmgr.c:72
static NTSTATUS NTAPI PartMgrAddDevice(_In_ PDRIVER_OBJECT DriverObject, _In_ PDEVICE_OBJECT PhysicalDeviceObject)
Definition: partmgr.c:1181
static NTSTATUS FdoIoctlDiskSetDriveLayout(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:667
static NTSTATUS FdoHandleRemoveDevice(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:1123
static NTSTATUS FdoHandleDeviceRelations(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:1040
VOID NTAPI PartMgrUnload(_In_ PDRIVER_OBJECT DriverObject)
Definition: partmgr.c:1478
static NTSTATUS NTAPI PartMgrReadWrite(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partmgr.c:1375
static NTSTATUS PartMgrGetDriveLayout(_In_ PFDO_EXTENSION FdoExtension, _Out_ PDRIVE_LAYOUT_INFORMATION_EX *DriveLayout)
Retrieves the disk partition layout from the given disk FDO.
Definition: partmgr.c:408
static NTSTATUS FdoIoctlDiskDeleteDriveLayout(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:925
static VOID PartMgrUpdatePartitionDevices(_In_ PFDO_EXTENSION FdoExtension, _Inout_ PDRIVE_LAYOUT_INFORMATION_EX NewLayout)
Definition: partmgr.c:198
static NTSTATUS FdoIoctlDiskGetPartitionInfoEx(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:549
static NTSTATUS NTAPI PartMgrPnp(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partmgr.c:1304
static NTSTATUS FdoIoctlDiskUpdateProperties(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:882
DRIVER_DISPATCH PartMgrPower
Definition: partmgr.c:1400
static NTSTATUS FdoIoctlDiskGetPartitionInfo(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:514
static NTSTATUS FdoIoctlDiskGetDriveLayoutEx(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:631
static NTSTATUS FdoHandleSurpriseRemoval(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:1149
static BOOLEAN PartMgrIsDiskSuperFloppy(_In_ PFDO_EXTENSION FdoExtension)
Detects whether a disk is a "super-floppy", i.e. an unpartitioned disk with only a valid VBR,...
Definition: partmgr.c:135
DRIVER_DISPATCH PartMgrShutdownFlush
Definition: partmgr.c:1441
static NTSTATUS FdoHandleStartDevice(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:947
static NTSTATUS FdoIoctlDiskGetDriveGeometryEx(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:451
static NTSTATUS PartMgrRefreshDiskData(_In_ PFDO_EXTENSION FdoExtension)
Refreshes all the cached disk FDO data. The geometry of the disk and its partition layout cache is up...
Definition: partmgr.c:1006
static NTSTATUS FdoIoctlDiskSetDriveLayoutEx(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:761
static NTSTATUS FdoIoctlDiskGetDriveLayout(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:579
static NTSTATUS NTAPI PartMgrDeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partmgr.c:1230
#define TAG_PARTMGR
Definition: partmgr.h:23
FORCEINLINE VOID PartMgrReleaseLayoutLock(_In_ PFDO_EXTENSION FDOExtension)
Definition: partmgr.h:212
FORCEINLINE VOID PartMgrAcquireLayoutLock(_In_ PFDO_EXTENSION FDOExtension)
Definition: partmgr.h:202
FORCEINLINE BOOLEAN VerifyIrpInBufferSize(_In_ PIRP Irp, _In_ SIZE_T Size)
Definition: partmgr.h:187
NTSTATUS IssueSyncIoControlRequest(_In_ UINT32 IoControlCode, _In_ PDEVICE_OBJECT DeviceObject, _In_ PVOID InputBuffer, _In_ ULONG InputBufferLength, _In_ PVOID OutputBuffer, _In_ ULONG OutputBufferLength, _In_ BOOLEAN InternalDeviceIoControl)
Definition: utils.c:19
FORCEINLINE BOOLEAN VerifyIrpOutBufferSize(_In_ PIRP Irp, _In_ SIZE_T Size)
Definition: partmgr.h:172
#define CONST
Definition: pedump.c:81
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:1772
NTSTATUS NTAPI IoReportTargetDeviceChangeAsynchronous(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PVOID NotificationStructure, IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL, IN PVOID Context OPTIONAL)
Definition: pnpreport.c:498
#define FILE_DEVICE_BUS_EXTENDER
Definition: winioctl.h:87
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define TRACE(s)
Definition: solgame.cpp:4
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
DISK_PARTITION_INFO Partition
Definition: disk.c:3667
DISK_GEOMETRY Geometry
Definition: winioctl.h:330
LARGE_INTEGER DiskSize
Definition: winioctl.h:331
ULONG BytesPerSector
Definition: ntdddisk.h:404
PARTITION_INFORMATION PartitionEntry[1]
Definition: ntdddisk.h:421
KEVENT SyncEvent
Definition: partmgr.h:63
PDEVICE_OBJECT PhysicalDiskDO
Definition: partmgr.h:62
PDEVICE_OBJECT DeviceObject
Definition: partmgr.h:60
PDEVICE_OBJECT LowerDevice
Definition: partmgr.h:61
BOOLEAN IsFDO
Definition: partmgr.h:59
union _IO_STACK_LOCATION::@1567 Parameters
struct _IO_STACK_LOCATION::@3976::@3980 Read
struct _IO_STACK_LOCATION::@1567::@1568 DeviceIoControl
struct _IO_STACK_LOCATION::@3976::@4001 QueryDeviceRelations
UINT64 StartingOffset
Definition: partmgr.h:96
PDEVICE_OBJECT LowerDevice
Definition: partmgr.h:93
struct _PARTITION_EXTENSION::@1322::@1325 Mbr
SINGLE_LIST_ENTRY ListEntry
Definition: partmgr.h:98
struct _PARTITION_EXTENSION::@1322::@1324 Gpt
UINT32 DetectedNumber
Definition: partmgr.h:101
UINT64 PartitionLength
Definition: partmgr.h:97
BOOLEAN IsEnumerated
Definition: partmgr.h:103
PDEVICE_OBJECT DeviceObject
Definition: partmgr.h:92
LARGE_INTEGER StartingOffset
Definition: imports.h:221
PARTITION_STYLE PartitionStyle
Definition: imports.h:220
PARTITION_INFORMATION_MBR Mbr
Definition: imports.h:226
PARTITION_INFORMATION_GPT Gpt
Definition: imports.h:227
LARGE_INTEGER PartitionLength
Definition: imports.h:222
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
Definition: ntbasedef.h:628
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
Definition: ps.c:97
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2105
#define IRP_MN_CANCEL_STOP_DEVICE
@ BusRelations
Definition: iotypes.h:2152
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_START_DEVICE
#define IRP_MN_REMOVE_DEVICE
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define DO_POWER_PAGABLE
#define IRP_MN_QUERY_STOP_DEVICE
#define IRP_MN_SET_POWER
#define IRP_MJ_FLUSH_BUFFERS
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IRP_MN_STOP_DEVICE
#define IRP_MJ_SHUTDOWN
#define IRP_MJ_POWER
enum _DEVICE_RELATION_TYPE DEVICE_RELATION_TYPE
#define IRP_MN_QUERY_POWER
#define IRP_MN_QUERY_REMOVE_DEVICE
#define ObReferenceObject
Definition: obfuncs.h:204