ReactOS 0.4.16-dev-852-gcfcc8d8
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 if (!NT_SUCCESS(status))
344 {
345 partEntry->PartitionNumber = 0;
346 continue;
347 }
348
349 // mark partition as removable if parent device is removable
350 if (FdoExtension->LowerDevice->Characteristics & FILE_REMOVABLE_MEDIA)
351 partitionDevice->Characteristics |= FILE_REMOVABLE_MEDIA;
352
353 totalPartitions++;
354
355 // insert the structure to the partition list
356 curEntry = FdoExtension->PartitionList.Next;
357 prevEntry = NULL;
358 while (curEntry != NULL)
359 {
360 PPARTITION_EXTENSION curPart = CONTAINING_RECORD(curEntry,
362 ListEntry);
363 if (curPart->OnDiskNumber < partNumber)
364 {
365 prevEntry = curEntry;
366 curEntry = curPart->ListEntry.Next;
367 }
368 else
369 { // we found where to put the partition
370 break;
371 }
372 }
373
374 PPARTITION_EXTENSION partExt = partitionDevice->DeviceExtension;
375
376 if (prevEntry)
377 {
378 // insert after prevEntry
379 partExt->ListEntry.Next = prevEntry->Next;
380 prevEntry->Next = &partExt->ListEntry;
381 }
382 else
383 {
384 // insert at the beginning
385 partExt->ListEntry.Next = FdoExtension->PartitionList.Next;
386 FdoExtension->PartitionList.Next = &partExt->ListEntry;
387 }
388
389 partExt->Attached = TRUE;
390 }
391
392 FdoExtension->EnumeratedPartitionsTotal = totalPartitions;
393}
394
404static
405CODE_SEG("PAGE")
409 _Out_ PDRIVE_LAYOUT_INFORMATION_EX *DriveLayout)
410{
411 PAGED_CODE();
412
413 if (FdoExtension->LayoutValid)
414 {
415 *DriveLayout = FdoExtension->LayoutCache;
416 return STATUS_SUCCESS;
417 }
418
419 PDRIVE_LAYOUT_INFORMATION_EX layoutEx = NULL;
420 NTSTATUS status = IoReadPartitionTableEx(FdoExtension->LowerDevice, &layoutEx);
421 if (!NT_SUCCESS(status))
422 return status;
423
424 if (FdoExtension->LayoutCache)
425 ExFreePool(FdoExtension->LayoutCache);
426
427 FdoExtension->LayoutCache = layoutEx;
428 FdoExtension->LayoutValid = TRUE;
429
430 FdoExtension->DiskData.PartitionStyle = layoutEx->PartitionStyle;
431 if (FdoExtension->DiskData.PartitionStyle == PARTITION_STYLE_MBR)
432 {
433 FdoExtension->DiskData.Mbr.Signature = layoutEx->Mbr.Signature;
434 // FdoExtension->DiskData.Mbr.Checksum = geometryEx.Partition.Mbr.CheckSum;
435 }
436 else
437 {
438 FdoExtension->DiskData.Gpt.DiskId = layoutEx->Gpt.DiskId;
439 }
440
442
443 *DriveLayout = layoutEx;
444 return status;
445}
446
447static
448CODE_SEG("PAGE")
452 _In_ PIRP Irp)
453{
455
456 PAGED_CODE();
457
458 // We're patching the DISK_PARTITION_INFO part of the returned structure
459 // as disk.sys doesn't really know about the partition table on a disk
460
461 PDISK_GEOMETRY_EX_INTERNAL geometryEx = Irp->AssociatedIrp.SystemBuffer;
462 ULONG outBufferLength = ioStack->Parameters.DeviceIoControl.OutputBufferLength;
464
466 FdoExtension->LowerDevice,
467 NULL,
468 0,
469 geometryEx,
470 outBufferLength,
471 FALSE);
472
473 if (!NT_SUCCESS(status))
474 {
475 return status;
476 }
477
478 // if DISK_PARTITION_INFO fits the output size
479 if (outBufferLength >= FIELD_OFFSET(DISK_GEOMETRY_EX_INTERNAL, Detection))
480 {
482
483 geometryEx->Partition.SizeOfPartitionInfo = sizeof(geometryEx->Partition);
484 geometryEx->Partition.PartitionStyle = FdoExtension->DiskData.PartitionStyle;
485
486 switch (geometryEx->Partition.PartitionStyle)
487 {
489 geometryEx->Partition.Mbr.Signature = FdoExtension->DiskData.Mbr.Signature;
490 // checksum?
491 break;
492
494 geometryEx->Partition.Gpt.DiskId = FdoExtension->DiskData.Gpt.DiskId;
495 break;
496
497 default:
498 RtlZeroMemory(&geometryEx->Partition, sizeof(geometryEx->Partition));
499 }
500
502 }
503
504 // the logic is copied from disk.sys
505 Irp->IoStatus.Information = min(outBufferLength, sizeof(DISK_GEOMETRY_EX_INTERNAL));
506
507 return status;
508}
509
510static
511CODE_SEG("PAGE")
515 _In_ PIRP Irp)
516{
517 PPARTITION_INFORMATION partInfo = Irp->AssociatedIrp.SystemBuffer;
518
519 PAGED_CODE();
520
521 if (!VerifyIrpOutBufferSize(Irp, sizeof(*partInfo)))
522 {
524 }
525
527
528 *partInfo = (PARTITION_INFORMATION){
530 .StartingOffset.QuadPart = 0,
531 .PartitionLength.QuadPart = FdoExtension->DiskData.DiskSize,
532 .HiddenSectors = 0,
533 .PartitionNumber = 0,
534 .BootIndicator = FALSE,
535 .RewritePartition = FALSE,
536 .RecognizedPartition = FALSE,
537 };
538
540
541 Irp->IoStatus.Information = sizeof(*partInfo);
542 return STATUS_SUCCESS;
543}
544
545static
546CODE_SEG("PAGE")
550 _In_ PIRP Irp)
551{
552 PPARTITION_INFORMATION_EX partInfoEx = Irp->AssociatedIrp.SystemBuffer;
553
554 PAGED_CODE();
555
556 if (!VerifyIrpOutBufferSize(Irp, sizeof(*partInfoEx)))
557 {
559 }
560
562
563 // most of the fields a zeroed for Partition0
564 *partInfoEx = (PARTITION_INFORMATION_EX){
565 .PartitionLength.QuadPart = FdoExtension->DiskData.DiskSize,
566 .PartitionStyle = FdoExtension->DiskData.PartitionStyle,
567 };
568
570
571 Irp->IoStatus.Information = sizeof(*partInfoEx);
572 return STATUS_SUCCESS;
573}
574
575static
576CODE_SEG("PAGE")
580 _In_ PIRP Irp)
581{
582 PAGED_CODE();
583
585
586 PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
588 if (!NT_SUCCESS(status))
589 {
591 return status;
592 }
593
594 // checking this value from layoutEx in case it has been changed
595 if (layoutEx->PartitionStyle != PARTITION_STYLE_MBR)
596 {
599 }
600
601 size_t size = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry[0]);
602 size += layoutEx->PartitionCount * sizeof(PARTITION_INFORMATION);
603
605 {
608 }
609
611
613
614 if (partitionList == NULL)
615 {
616 Irp->IoStatus.Information = 0;
618 }
619
620 RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, partitionList, size);
621 ExFreePoolWithTag(partitionList, TAG_PARTMGR);
622
623 Irp->IoStatus.Information = size;
624 return STATUS_SUCCESS;
625}
626
627static
628CODE_SEG("PAGE")
632 _In_ PIRP Irp)
633{
634 PAGED_CODE();
635
637
638 PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
640 if (!NT_SUCCESS(status))
641 {
643 return status;
644 }
645
646 size_t size = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[0]);
647 size += layoutEx->PartitionCount * sizeof(PARTITION_INFORMATION_EX);
648
650 {
653 }
654
655 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, layoutEx, size);
656
658
659 Irp->IoStatus.Information = size;
660 return STATUS_SUCCESS;
661}
662
663static
664CODE_SEG("PAGE")
668 _In_ PIRP Irp)
669{
670 PDRIVE_LAYOUT_INFORMATION layoutInfo = Irp->AssociatedIrp.SystemBuffer;
671
672 PAGED_CODE();
673
674 if (!VerifyIrpInBufferSize(Irp, sizeof(*layoutInfo)))
675 {
677 }
678
679 size_t layoutSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry[0]);
680 layoutSize += layoutInfo->PartitionCount * sizeof(PARTITION_INFORMATION);
681
682 if (!VerifyIrpInBufferSize(Irp, layoutSize))
683 {
685 }
686
687 PDRIVE_LAYOUT_INFORMATION_EX layoutEx = PartMgrConvertLayoutToExtended(layoutInfo);
688
689 if (layoutEx == NULL)
690 {
691 Irp->IoStatus.Information = 0;
693 }
694
696
697 // If the current disk is super-floppy but the user changes
698 // the number of partitions to > 1, fail the call.
699 if (FdoExtension->IsSuperFloppy && (layoutEx->PartitionCount > 1))
700 {
703 }
704
705 // this in fact updates the bus relations
707
708 // write the partition table to the disk
709 NTSTATUS status = IoWritePartitionTableEx(FdoExtension->LowerDevice, layoutEx);
710 if (NT_SUCCESS(status))
711 {
712 // save the layout cache
713 if (FdoExtension->LayoutCache)
714 {
715 ExFreePool(FdoExtension->LayoutCache);
716 }
717 FdoExtension->LayoutCache = layoutEx;
718 FdoExtension->LayoutValid = TRUE;
719
720 // set updated partition numbers
721 for (UINT32 i = 0; i < layoutInfo->PartitionCount; i++)
722 {
723 PPARTITION_INFORMATION part = &layoutInfo->PartitionEntry[i];
724
725 part->PartitionNumber = layoutEx->PartitionEntry[i].PartitionNumber;
726 }
727
729 }
730 else
731 {
732 FdoExtension->LayoutValid = FALSE;
733 }
734
736
738
739 // notify everyone that the disk layout has changed
741
742 notification.Event = GUID_IO_DISK_LAYOUT_CHANGE;
743 notification.Version = 1;
745 notification.FileObject = NULL;
746 notification.NameBufferOffset = -1;
747
750 NULL,
751 NULL);
752
753 Irp->IoStatus.Information = layoutSize;
754 return STATUS_SUCCESS;
755}
756
757static
758CODE_SEG("PAGE")
762 _In_ PIRP Irp)
763{
764 PDRIVE_LAYOUT_INFORMATION_EX layoutEx, layoutUser = Irp->AssociatedIrp.SystemBuffer;
766
767 PAGED_CODE();
768
769 if (!VerifyIrpInBufferSize(Irp, sizeof(*layoutUser)))
770 {
772 }
773
774 size_t layoutSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[0]);
775 layoutSize += layoutUser->PartitionCount * sizeof(PARTITION_INFORMATION_EX);
776
777 if (!VerifyIrpInBufferSize(Irp, layoutSize))
778 {
780 }
781
782 // we need to copy the structure from the IRP input buffer
783 layoutEx = ExAllocatePoolWithTag(PagedPool, layoutSize, TAG_PARTMGR);
784 if (!layoutEx)
785 {
786 Irp->IoStatus.Information = 0;
788 }
789
790 RtlCopyMemory(layoutEx, layoutUser, layoutSize);
791
793
794 // If the current disk is super-floppy but the user changes either
795 // the disk type or the number of partitions to > 1, fail the call.
796 if (FdoExtension->IsSuperFloppy &&
797 ((layoutEx->PartitionStyle != PARTITION_STYLE_MBR) ||
798 (layoutEx->PartitionCount > 1)))
799 {
802 }
803
804 // if partition count is 0, it's the same as IOCTL_DISK_CREATE_DISK
805 if (layoutEx->PartitionCount == 0)
806 {
807 CREATE_DISK createDisk = {0};
808 createDisk.PartitionStyle = layoutEx->PartitionStyle;
809 if (createDisk.PartitionStyle == PARTITION_STYLE_MBR)
810 {
811 createDisk.Mbr.Signature = layoutEx->Mbr.Signature;
812 }
813 else if (createDisk.PartitionStyle == PARTITION_STYLE_GPT)
814 {
815 createDisk.Gpt.DiskId = layoutEx->Gpt.DiskId;
816 }
817
818 status = IoCreateDisk(FdoExtension->LowerDevice, &createDisk);
819 }
820 else
821 {
822 // this in fact updates the bus relations
824
825 // write the partition table to the disk
826 status = IoWritePartitionTableEx(FdoExtension->LowerDevice, layoutEx);
827 if (NT_SUCCESS(status))
828 {
829 // set updated partition numbers
830 for (UINT32 i = 0; i < layoutEx->PartitionCount; i++)
831 {
832 PPARTITION_INFORMATION_EX part = &layoutEx->PartitionEntry[i];
833
834 part->PartitionNumber = layoutEx->PartitionEntry[i].PartitionNumber;
835 }
836 }
837 }
838
839 // update the layout cache
840 if (NT_SUCCESS(status))
841 {
842 if (FdoExtension->LayoutCache)
843 {
844 ExFreePool(FdoExtension->LayoutCache);
845 }
846 FdoExtension->LayoutCache = layoutEx;
847 FdoExtension->LayoutValid = TRUE;
848
850 }
851 else
852 {
853 FdoExtension->LayoutValid = FALSE;
854 }
855
857
859
860 // notify everyone that the disk layout has changed
862
863 notification.Event = GUID_IO_DISK_LAYOUT_CHANGE;
864 notification.Version = 1;
866 notification.FileObject = NULL;
867 notification.NameBufferOffset = -1;
868
871 NULL,
872 NULL);
873
874 Irp->IoStatus.Information = layoutSize;
875 return STATUS_SUCCESS;
876}
877
878static
879CODE_SEG("PAGE")
883 _In_ PIRP Irp)
884{
885 PAGED_CODE();
886
888 FdoExtension->LayoutValid = FALSE;
890
892 return STATUS_SUCCESS;
893}
894
895static
896CODE_SEG("PAGE")
900 _In_ PIRP Irp)
901{
902 PAGED_CODE();
903
904 PCREATE_DISK createDisk = Irp->AssociatedIrp.SystemBuffer;
905 if (!VerifyIrpInBufferSize(Irp, sizeof(*createDisk)))
906 {
908 }
909
911
912 NTSTATUS status = IoCreateDisk(FdoExtension->LowerDevice, createDisk);
913
914 FdoExtension->LayoutValid = FALSE;
916
918 return status;
919}
920
921static
922CODE_SEG("PAGE")
926 _In_ PIRP Irp)
927{
928 CREATE_DISK createDisk = { .PartitionStyle = PARTITION_STYLE_RAW };
929
930 PAGED_CODE();
931
933
934 NTSTATUS status = IoCreateDisk(FdoExtension->LowerDevice, &createDisk);
935
936 FdoExtension->LayoutValid = FALSE;
938
940 return status;
941}
942
943static
944CODE_SEG("PAGE")
948 _In_ PIRP Irp)
949{
950 // Obtain the disk device number.
951 // It is not expected to change, thus not in PartMgrRefreshDiskData().
952 STORAGE_DEVICE_NUMBER deviceNumber;
954 FdoExtension->LowerDevice,
955 NULL,
956 0,
957 &deviceNumber,
958 sizeof(deviceNumber),
959 FALSE);
960 if (!NT_SUCCESS(status))
961 {
962 return status;
963 }
964
965 FdoExtension->DiskData.DeviceNumber = deviceNumber.DeviceNumber;
966
967 // Register the disk interface.
968 // partmgr.sys from Windows 8.1 also registers a mysterious GUID_DEVINTERFACE_HIDDEN_DISK here.
969 UNICODE_STRING interfaceName;
971 &GUID_DEVINTERFACE_DISK,
972 NULL,
973 &interfaceName);
974 if(!NT_SUCCESS(status))
975 {
976 ERR("Failed to register GUID_DEVINTERFACE_DISK, status %x\n", status);
977 return status;
978 }
979
980 INFO("Disk interface %wZ\n", &interfaceName);
981 FdoExtension->DiskInterfaceName = interfaceName;
982 status = IoSetDeviceInterfaceState(&interfaceName, TRUE);
983 if (!NT_SUCCESS(status))
984 {
985 RtlFreeUnicodeString(&interfaceName);
986 RtlInitUnicodeString(&FdoExtension->DiskInterfaceName, NULL);
987 }
988
989 return status;
990}
991
999static
1000CODE_SEG("PAGE")
1004{
1006
1007 PAGED_CODE();
1008
1009 // get the DiskSize and BytesPerSector
1010 DISK_GEOMETRY_EX geometryEx;
1012 FdoExtension->LowerDevice,
1013 NULL,
1014 0,
1015 &geometryEx,
1016 sizeof(geometryEx),
1017 FALSE);
1018 if (!NT_SUCCESS(status))
1019 return status;
1020
1021 FdoExtension->DiskData.DiskSize = geometryEx.DiskSize.QuadPart;
1022 FdoExtension->DiskData.BytesPerSector = geometryEx.Geometry.BytesPerSector;
1023
1024 // get the partition style-related info
1025 PDRIVE_LAYOUT_INFORMATION_EX layoutEx = NULL;
1027 if (!NT_SUCCESS(status))
1028 return status;
1029
1030 return STATUS_SUCCESS;
1031}
1032
1033static
1034CODE_SEG("PAGE")
1038 _In_ PIRP Irp)
1039{
1042
1043 PAGED_CODE();
1044
1045 if (type == BusRelations)
1046 {
1048
1050 if (!NT_SUCCESS(status))
1051 {
1053 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1054 Irp->IoStatus.Information = 0;
1056 return Irp->IoStatus.Status;
1057 }
1058
1059 INFO("Partition style %u\n", FdoExtension->DiskData.PartitionStyle);
1060
1061 // PartMgrRefreshDiskData() calls PartMgrGetDriveLayout() inside
1062 // so we're sure here that it returns only the cached layout.
1063 PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
1065
1067
1068 // now fill the DeviceRelations structure
1069 TRACE("Reporting %u partitions\n", FdoExtension->EnumeratedPartitionsTotal);
1070
1071 PDEVICE_RELATIONS deviceRelations =
1073 sizeof(DEVICE_RELATIONS)
1074 + sizeof(PDEVICE_OBJECT)
1075 * (FdoExtension->EnumeratedPartitionsTotal - 1),
1076 TAG_PARTMGR);
1077
1078 if (!deviceRelations)
1079 {
1081 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1082 Irp->IoStatus.Information = 0;
1084 return Irp->IoStatus.Status;
1085 }
1086
1087 deviceRelations->Count = 0;
1088
1089 PSINGLE_LIST_ENTRY curEntry = FdoExtension->PartitionList.Next;
1090 while (curEntry != NULL)
1091 {
1092 PPARTITION_EXTENSION partExt = CONTAINING_RECORD(curEntry,
1094 ListEntry);
1095
1096 // mark the PDO to know that we don't need to manually delete it
1097 partExt->IsEnumerated = TRUE;
1098 deviceRelations->Objects[deviceRelations->Count++] = partExt->DeviceObject;
1100
1101 curEntry = partExt->ListEntry.Next;
1102 }
1103
1104 ASSERT(deviceRelations->Count == FdoExtension->EnumeratedPartitionsTotal);
1105
1107
1108 Irp->IoStatus.Information = (ULONG_PTR)deviceRelations;
1109 Irp->IoStatus.Status = STATUS_SUCCESS;
1110 }
1111
1113 return IoCallDriver(FdoExtension->LowerDevice, Irp);
1114}
1115
1116static
1117CODE_SEG("PAGE")
1121 _In_ PIRP Irp)
1122{
1123 PAGED_CODE();
1124
1125 if (FdoExtension->DiskInterfaceName.Buffer)
1126 {
1127 IoSetDeviceInterfaceState(&FdoExtension->DiskInterfaceName, FALSE);
1128 RtlFreeUnicodeString(&FdoExtension->DiskInterfaceName);
1129 RtlInitUnicodeString(&FdoExtension->DiskInterfaceName, NULL);
1130 }
1131
1132 // Send the IRP down the stack
1134 Irp->IoStatus.Status = STATUS_SUCCESS;
1135 NTSTATUS status = IoCallDriver(FdoExtension->LowerDevice, Irp);
1136
1137 IoDetachDevice(FdoExtension->LowerDevice);
1138 IoDeleteDevice(FdoExtension->DeviceObject);
1139 return status;
1140}
1141
1142static
1143CODE_SEG("PAGE")
1147 _In_ PIRP Irp)
1148{
1149 PAGED_CODE();
1150
1151 // all enumerated child devices should receive IRP_MN_REMOVE_DEVICE
1152 // removing only non-enumerated ones here
1153 for (PSINGLE_LIST_ENTRY curEntry = FdoExtension->PartitionList.Next;
1154 curEntry != NULL;
1155 curEntry = curEntry->Next)
1156 {
1157 PPARTITION_EXTENSION partExt = CONTAINING_RECORD(curEntry,
1159 ListEntry);
1160
1161 if (partExt->IsEnumerated)
1162 {
1163 PartitionHandleRemove(partExt, TRUE);
1164 }
1165 }
1166
1167 // Send the IRP down the stack
1169 Irp->IoStatus.Status = STATUS_SUCCESS;
1170 return IoCallDriver(FdoExtension->LowerDevice, Irp);
1171}
1172
1173static
1174CODE_SEG("PAGE")
1176NTAPI
1180{
1182
1183 PAGED_CODE();
1184
1185 /*
1186 * Create the disk FDO. Use FILE_DEVICE_MASS_STORAGE type (or any other
1187 * one that is NOT FILE_DEVICE_[DISK|VIRTUAL_DISK|CD_ROM|TAPE]), so that
1188 * IoCreateDevice() doesn't automatically create a VPB for this device,
1189 * even if we will later want this device to inherit the type of the
1190 * underlying PDO which can have any of the types mentioned above.
1191 */
1193 sizeof(FDO_EXTENSION),
1194 NULL,
1197 FALSE,
1198 &deviceObject);
1199 if (!NT_SUCCESS(status))
1200 {
1201 ERR("Failed to create FDO 0x%x\n", status);
1202 return status;
1203 }
1204
1205 PFDO_EXTENSION deviceExtension = deviceObject->DeviceExtension;
1206 RtlZeroMemory(deviceExtension, sizeof(*deviceExtension));
1207
1208 deviceExtension->IsFDO = TRUE;
1209 deviceExtension->DeviceObject = deviceObject;
1211 if (!deviceExtension->LowerDevice)
1212 {
1213 // The attachment failed
1215 return STATUS_DEVICE_REMOVED;
1216 }
1217 deviceExtension->PhysicalDiskDO = PhysicalDeviceObject;
1219
1220 // Update now the device type with the actual underlying device type
1221 deviceObject->DeviceType = deviceExtension->LowerDevice->DeviceType;
1222
1224
1225 // The device is initialized
1226 deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1227 return STATUS_SUCCESS;
1228}
1229
1230static
1232NTAPI
1235 _In_ PIRP Irp)
1236{
1238 PFDO_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
1240
1241 // Note: IRP_MJ_DEVICE_CONTROL handler in the storage stack must be able to pass IOCTLs
1242 // at an IRQL higher than PASSIVE_LEVEL
1243
1244 INFO("IRP_MJ_DEVICE_CONTROL %p Irp %p IOCTL %x isFdo: %u\n",
1245 DeviceObject, Irp, ioStack->Parameters.DeviceIoControl.IoControlCode, fdoExtension->IsFDO);
1246
1247 if (!fdoExtension->IsFDO)
1248 {
1250 }
1251
1252 switch (ioStack->Parameters.DeviceIoControl.IoControlCode)
1253 {
1255 status = FdoIoctlDiskGetDriveGeometryEx(fdoExtension, Irp);
1256 break;
1257
1259 status = FdoIoctlDiskGetPartitionInfo(fdoExtension, Irp);
1260 break;
1261
1263 status = FdoIoctlDiskGetPartitionInfoEx(fdoExtension, Irp);
1264 break;
1265
1267 status = FdoIoctlDiskGetDriveLayout(fdoExtension, Irp);
1268 break;
1269
1271 status = FdoIoctlDiskGetDriveLayoutEx(fdoExtension, Irp);
1272 break;
1273
1275 status = FdoIoctlDiskSetDriveLayout(fdoExtension, Irp);
1276 break;
1277
1279 status = FdoIoctlDiskSetDriveLayoutEx(fdoExtension, Irp);
1280 break;
1281
1283 status = FdoIoctlDiskUpdateProperties(fdoExtension, Irp);
1284 break;
1285
1287 status = FdoIoctlDiskCreateDisk(fdoExtension, Irp);
1288 break;
1289
1291 status = FdoIoctlDiskDeleteDriveLayout(fdoExtension, Irp);
1292 break;
1293 // case IOCTL_DISK_GROW_PARTITION: // todo
1294 default:
1296 }
1297
1298 Irp->IoStatus.Status = status;
1300 return status;
1301}
1302
1303static
1304CODE_SEG("PAGE")
1306NTAPI
1309 _In_ PIRP Irp)
1310{
1311 PAGED_CODE();
1312
1313 PFDO_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
1315
1316 INFO("IRP_MJ_PNP %p Irp %p %s isFDO: %u\n",
1317 DeviceObject, Irp, GetIRPMinorFunctionString(ioStack->MinorFunction), fdoExtension->IsFDO);
1318
1319 if (!fdoExtension->IsFDO)
1320 {
1322 }
1323
1324 switch (ioStack->MinorFunction) {
1325
1327 {
1329
1330 // if this is sent to the FDO so we should forward it down the
1331 // attachment chain before we can start the FDO
1332
1333 if (!IoForwardIrpSynchronously(fdoExtension->LowerDevice, Irp))
1334 {
1336 }
1337 else
1338 {
1339 status = FdoHandleStartDevice(fdoExtension, Irp);
1340 }
1341
1342 Irp->IoStatus.Status = status;
1344 return status;
1345 }
1347 {
1348 return FdoHandleDeviceRelations(fdoExtension, Irp);
1349 }
1351 {
1352 return FdoHandleSurpriseRemoval(fdoExtension, Irp);
1353 }
1355 {
1356 return FdoHandleRemoveDevice(fdoExtension, Irp);
1357 }
1362 case IRP_MN_STOP_DEVICE:
1363 {
1364 Irp->IoStatus.Status = STATUS_SUCCESS;
1365 // fallthrough
1366 }
1367 default:
1368 {
1370 return IoCallDriver(fdoExtension->LowerDevice, Irp);
1371 }
1372 }
1373}
1374
1375static
1377NTAPI
1380 _In_ PIRP Irp)
1381{
1382 PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
1384
1385 if (!partExt->IsFDO)
1386 {
1387 if (!partExt->IsEnumerated)
1388 {
1389 Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
1392 }
1393 else
1394 {
1395 ioStack->Parameters.Read.ByteOffset.QuadPart += partExt->StartingOffset;
1396 }
1397 }
1398
1400 return IoCallDriver(partExt->LowerDevice, Irp);
1401}
1402
1405NTAPI
1408 _In_ PIRP Irp)
1409{
1410 PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
1412
1414
1415 if (!partExt->IsFDO)
1416 {
1418
1419 if (!partExt->IsEnumerated)
1420 {
1422 }
1423 else if (ioStack->MinorFunction == IRP_MN_SET_POWER ||
1425 {
1427 }
1428 else
1429 {
1430 status = Irp->IoStatus.Status;
1431 }
1432
1433 Irp->IoStatus.Status = status;
1435 return status;
1436 }
1437 else
1438 {
1440 return PoCallDriver(partExt->LowerDevice, Irp);
1441 }
1442}
1443
1446NTAPI
1449 _In_ PIRP Irp)
1450{
1451 PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
1452 PDEVICE_OBJECT lowerDevice;
1453
1454 // forward to the partition0 device in both cases
1455 if (!partExt->IsFDO)
1456 {
1457 if (!partExt->IsEnumerated)
1458 {
1459 Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
1462 }
1463 else
1464 {
1465 PFDO_EXTENSION fdoExtension = partExt->LowerDevice->DeviceExtension;
1466 lowerDevice = fdoExtension->LowerDevice;
1467 }
1468 }
1469 else
1470 {
1471 lowerDevice = partExt->LowerDevice;
1472 }
1473
1475 return IoCallDriver(lowerDevice, Irp);
1476}
1477
1478CODE_SEG("PAGE")
1479VOID
1480NTAPI
1483{
1484
1485}
1486
1487CODE_SEG("INIT")
1489NTAPI
1493{
1494 DriverObject->DriverUnload = PartMgrUnload;
1495 DriverObject->DriverExtension->AddDevice = PartMgrAddDevice;
1498 DriverObject->MajorFunction[IRP_MJ_READ] = PartMgrReadWrite;
1499 DriverObject->MajorFunction[IRP_MJ_WRITE] = PartMgrReadWrite;
1501 DriverObject->MajorFunction[IRP_MJ_PNP] = PartMgrPnp;
1504 DriverObject->MajorFunction[IRP_MJ_POWER] = PartMgrPower;
1505
1506 return STATUS_SUCCESS;
1507}
#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:87
#define PARTITION_FAT_16
Definition: disk.h:91
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 STATUS_DEVICE_REMOVED
Definition: d3dkmdt.h:39
#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:284
NTSTATUS PartitionHandleDeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partition.c:571
NTSTATUS PartitionHandlePnp(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partition.c:507
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
#define FILE_DEVICE_MASS_STORAGE
Definition: imports.h:60
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 FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
DRIVER_DISPATCH(nfs41_FsdDispatch)
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
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:1437
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1793
#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_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:898
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:1177
static NTSTATUS FdoIoctlDiskSetDriveLayout(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:666
static NTSTATUS FdoHandleRemoveDevice(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:1119
static NTSTATUS FdoHandleDeviceRelations(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:1036
VOID NTAPI PartMgrUnload(_In_ PDRIVER_OBJECT DriverObject)
Definition: partmgr.c:1481
static NTSTATUS NTAPI PartMgrReadWrite(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partmgr.c:1378
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:407
static NTSTATUS FdoIoctlDiskDeleteDriveLayout(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:924
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:548
static NTSTATUS NTAPI PartMgrPnp(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partmgr.c:1307
static NTSTATUS FdoIoctlDiskUpdateProperties(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:881
DRIVER_DISPATCH PartMgrPower
Definition: partmgr.c:1403
static NTSTATUS FdoIoctlDiskGetPartitionInfo(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:513
static NTSTATUS FdoIoctlDiskGetDriveLayoutEx(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:630
static NTSTATUS FdoHandleSurpriseRemoval(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:1145
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:1444
static NTSTATUS FdoHandleStartDevice(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:946
static NTSTATUS FdoIoctlDiskGetDriveGeometryEx(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:450
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:1002
static NTSTATUS FdoIoctlDiskSetDriveLayoutEx(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:760
static NTSTATUS FdoIoctlDiskGetDriveLayout(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:578
static NTSTATUS NTAPI PartMgrDeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partmgr.c:1233
#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 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
struct _IO_STACK_LOCATION::@4065::@4069 Read
struct _IO_STACK_LOCATION::@4065::@4090 QueryDeviceRelations
struct _IO_STACK_LOCATION::@1605::@1606 DeviceIoControl
union _IO_STACK_LOCATION::@1605 Parameters
UINT64 StartingOffset
Definition: partmgr.h:96
PDEVICE_OBJECT LowerDevice
Definition: partmgr.h:93
struct _PARTITION_EXTENSION::@1357::@1360 Mbr
struct _PARTITION_EXTENSION::@1357::@1359 Gpt
SINGLE_LIST_ENTRY ListEntry
Definition: partmgr.h:98
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:636
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:637
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