ReactOS  0.4.15-dev-3691-g3a4e5a6
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 
17 static
18 CODE_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  {
33  ASSERT(FALSE);
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 
69 static
70 CODE_SEG("PAGE")
71 PDRIVE_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 
117 static
118 CODE_SEG("PAGE")
119 VOID
122  _Inout_ PDRIVE_LAYOUT_INFORMATION_EX NewLayout)
123 {
125  PSINGLE_LIST_ENTRY curEntry, prevEntry;
126  UINT32 totalPartitions = 0;
127 
128  // Clear the partition numbers from the list entries
129  for (UINT32 i = 0; i < NewLayout->PartitionCount; i++)
130  {
131  NewLayout->PartitionEntry[i].PartitionNumber = 0;
132  }
133 
134  // iterate over old partition list
135  prevEntry = &FdoExtension->PartitionList;
136  curEntry = FdoExtension->PartitionList.Next;
137  while (curEntry != NULL)
138  {
139  PPARTITION_EXTENSION partExt = CONTAINING_RECORD(curEntry, PARTITION_EXTENSION, ListEntry);
140  UINT32 partNumber = 0; // count detected partitions for device symlinks
141  BOOLEAN found = FALSE;
142  PPARTITION_INFORMATION_EX partEntry;
143 
144  // trying to find this partition in returned layout
145  for (UINT32 i = 0; i < NewLayout->PartitionCount; i++)
146  {
147  partEntry = &NewLayout->PartitionEntry[i];
148 
149  // skip unused and container partitions
150  if (NewLayout->PartitionStyle == PARTITION_STYLE_MBR &&
151  (partEntry->Mbr.PartitionType == PARTITION_ENTRY_UNUSED ||
153  {
154  continue;
155  }
156 
157  partNumber++;
158 
159  // skip already found partitions
160  if (partEntry->PartitionNumber)
161  {
162  continue;
163  }
164 
165  // skip if partitions are not equal
166  if (partEntry->StartingOffset.QuadPart != partExt->StartingOffset ||
167  partEntry->PartitionLength.QuadPart != partExt->PartitionLength)
168  {
169  continue;
170  }
171 
172  // found matching partition - processing it
173  found = TRUE;
174  break;
175  }
176 
177  if (found)
178  {
179  // update (possibly changed) partition metadata
180  if (NewLayout->PartitionStyle == PARTITION_STYLE_MBR)
181  {
182  partExt->Mbr.PartitionType = partEntry->Mbr.PartitionType;
183  partExt->Mbr.BootIndicator = partEntry->Mbr.BootIndicator;
184  }
185  else
186  {
187  partExt->Gpt.PartitionType = partEntry->Gpt.PartitionType;
188  partExt->Gpt.PartitionId = partEntry->Gpt.PartitionId;
189  partExt->Gpt.Attributes = partEntry->Gpt.Attributes;
190 
191  RtlCopyMemory(partExt->Gpt.Name, partEntry->Gpt.Name, sizeof(partExt->Gpt.Name));
192  }
193 
194  partExt->OnDiskNumber = partNumber;
195  partEntry->PartitionNumber = partNumber; // mark it as a found one
196  totalPartitions++;
197  }
198  else
199  {
200  // detach the device from the list
201  prevEntry->Next = curEntry->Next;
202  curEntry = prevEntry;
203  partExt->Attached = FALSE;
204 
205  // enumerated PDOs will receive IRP_MN_REMOVE_DEVICE
206  if (!partExt->IsEnumerated)
207  {
208  PartitionHandleRemove(partExt, TRUE);
209  }
210  }
211 
212  prevEntry = curEntry;
213  curEntry = curEntry->Next;
214  }
215 
216  UINT32 partNumber = 0;
217  UINT32 pdoNumber = 1;
218 
219  // now looking through remaining "new" partitions
220  for (UINT32 i = 0; i < NewLayout->PartitionCount; i++)
221  {
222  PPARTITION_INFORMATION_EX partEntry = &NewLayout->PartitionEntry[i];
223 
224  // again, skip unused and container partitions
225  if (NewLayout->PartitionStyle == PARTITION_STYLE_MBR &&
226  (partEntry->Mbr.PartitionType == PARTITION_ENTRY_UNUSED ||
228  {
229  continue;
230  }
231 
232  partNumber++;
233 
234  // and skip processed partitions
235  if (partEntry->PartitionNumber != 0)
236  {
237  continue;
238  }
239 
240  // find the first free PDO index
241  for (PSINGLE_LIST_ENTRY curEntry = FdoExtension->PartitionList.Next;
242  curEntry != NULL;
243  curEntry = curEntry->Next)
244  {
245  PPARTITION_EXTENSION partExt = CONTAINING_RECORD(curEntry,
247  ListEntry);
248 
249  if (partExt->DetectedNumber == pdoNumber)
250  {
251  // found a matching pdo number - restart the search
252  curEntry = FdoExtension->PartitionList.Next;
253  pdoNumber++;
254  }
255  }
256 
257  partEntry->PartitionNumber = partNumber;
258 
259  PDEVICE_OBJECT partitionDevice;
260  status = PartitionCreateDevice(FdoExtension->DeviceObject,
261  partEntry,
262  pdoNumber,
263  NewLayout->PartitionStyle,
264  &partitionDevice);
265 
266  if (!NT_SUCCESS(status))
267  {
268  partEntry->PartitionNumber = 0;
269  continue;
270  }
271 
272  // mark partition as removable if parent device is removable
273  if (FdoExtension->LowerDevice->Characteristics & FILE_REMOVABLE_MEDIA)
274  partitionDevice->Characteristics |= FILE_REMOVABLE_MEDIA;
275 
276  totalPartitions++;
277 
278  // insert the structure to the partition list
279  curEntry = FdoExtension->PartitionList.Next;
280  prevEntry = NULL;
281  while (curEntry != NULL)
282  {
283  PPARTITION_EXTENSION curPart = CONTAINING_RECORD(curEntry,
285  ListEntry);
286  if (curPart->OnDiskNumber < partNumber)
287  {
288  prevEntry = curEntry;
289  curEntry = curPart->ListEntry.Next;
290  }
291  else
292  { // we found where to put the partition
293  break;
294  }
295  }
296 
297  PPARTITION_EXTENSION partExt = partitionDevice->DeviceExtension;
298 
299  if (prevEntry)
300  {
301  // insert after prevEntry
302  partExt->ListEntry.Next = prevEntry->Next;
303  prevEntry->Next = &partExt->ListEntry;
304  }
305  else
306  {
307  // insert in the beginning
308  partExt->ListEntry.Next = FdoExtension->PartitionList.Next;
309  FdoExtension->PartitionList.Next = &partExt->ListEntry;
310  }
311 
312  partExt->Attached = TRUE;
313  }
314 
315  FdoExtension->EnumeratedPartitionsTotal = totalPartitions;
316 }
317 
318 // requires partitioning lock held
319 static
320 CODE_SEG("PAGE")
321 NTSTATUS
324  _Out_ PDRIVE_LAYOUT_INFORMATION_EX *DriveLayout)
325 {
326  PAGED_CODE();
327 
328  if (FdoExtension->LayoutValid)
329  {
330  *DriveLayout = FdoExtension->LayoutCache;
331  return STATUS_SUCCESS;
332  }
333 
334  PDRIVE_LAYOUT_INFORMATION_EX layoutEx = NULL;
335  NTSTATUS status = IoReadPartitionTableEx(FdoExtension->LowerDevice, &layoutEx);
336 
337  if (!NT_SUCCESS(status))
338  {
339  return status;
340  }
341 
342  if (FdoExtension->LayoutCache)
343  {
344  ExFreePool(FdoExtension->LayoutCache);
345  }
346 
347  FdoExtension->LayoutCache = layoutEx;
348  FdoExtension->LayoutValid = TRUE;
349 
350  *DriveLayout = layoutEx;
351 
352  return status;
353 }
354 
355 static
356 CODE_SEG("PAGE")
357 NTSTATUS
360  _In_ PIRP Irp)
361 {
363 
364  PAGED_CODE();
365 
366  // We're patching the DISK_PARTITION_INFO part of the returned structure
367  // as disk.sys doesn't really know about the partition table on a disk
368 
369  PDISK_GEOMETRY_EX_INTERNAL geometryEx = Irp->AssociatedIrp.SystemBuffer;
370  size_t outBufferLength = ioStack->Parameters.DeviceIoControl.OutputBufferLength;
372 
374  FdoExtension->LowerDevice,
375  NULL,
376  0,
377  geometryEx,
378  outBufferLength,
379  FALSE);
380 
381  if (!NT_SUCCESS(status))
382  {
383  return status;
384  }
385 
386  // if DISK_PARTITION_INFO fits the output size
387  if (outBufferLength >= FIELD_OFFSET(DISK_GEOMETRY_EX_INTERNAL, Detection))
388  {
390 
391  geometryEx->Partition.SizeOfPartitionInfo = sizeof(geometryEx->Partition);
392  geometryEx->Partition.PartitionStyle = FdoExtension->DiskData.PartitionStyle;
393 
394  switch (geometryEx->Partition.PartitionStyle)
395  {
396  case PARTITION_STYLE_MBR:
397  geometryEx->Partition.Mbr.Signature = FdoExtension->DiskData.Mbr.Signature;
398  // checksum?
399  break;
400 
401  case PARTITION_STYLE_GPT:
402  geometryEx->Partition.Gpt.DiskId = FdoExtension->DiskData.Gpt.DiskId;
403  break;
404 
405  default:
406  RtlZeroMemory(&geometryEx->Partition, sizeof(geometryEx->Partition));
407  }
408 
410  }
411 
412  // the logic is copied from disk.sys
413  Irp->IoStatus.Information = min(outBufferLength, sizeof(DISK_GEOMETRY_EX_INTERNAL));
414 
415  return status;
416 }
417 
418 static
419 CODE_SEG("PAGE")
420 NTSTATUS
423  _In_ PIRP Irp)
424 {
425  PPARTITION_INFORMATION partInfo = Irp->AssociatedIrp.SystemBuffer;
426 
427  PAGED_CODE();
428 
429  if (!VerifyIrpOutBufferSize(Irp, sizeof(*partInfo)))
430  {
432  }
433 
435 
436  *partInfo = (PARTITION_INFORMATION){
438  .StartingOffset.QuadPart = 0,
439  .PartitionLength.QuadPart = FdoExtension->DiskData.DiskSize,
440  .HiddenSectors = 0,
441  .PartitionNumber = 0,
442  .BootIndicator = FALSE,
443  .RewritePartition = FALSE,
444  .RecognizedPartition = FALSE,
445  };
446 
448 
449  Irp->IoStatus.Information = sizeof(*partInfo);
450  return STATUS_SUCCESS;
451 }
452 
453 static
454 CODE_SEG("PAGE")
455 NTSTATUS
458  _In_ PIRP Irp)
459 {
460  PPARTITION_INFORMATION_EX partInfoEx = Irp->AssociatedIrp.SystemBuffer;
461 
462  PAGED_CODE();
463 
464  if (!VerifyIrpOutBufferSize(Irp, sizeof(*partInfoEx)))
465  {
467  }
468 
470 
471  // most of the fields a zeroed for Partition0
472  *partInfoEx = (PARTITION_INFORMATION_EX){
473  .PartitionLength.QuadPart = FdoExtension->DiskData.DiskSize,
474  .PartitionStyle = FdoExtension->DiskData.PartitionStyle,
475  };
476 
478 
479  Irp->IoStatus.Information = sizeof(*partInfoEx);
480  return STATUS_SUCCESS;
481 }
482 
483 static
484 CODE_SEG("PAGE")
485 NTSTATUS
488  _In_ PIRP Irp)
489 {
490  PAGED_CODE();
491 
493 
494  PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
496 
497  if (!NT_SUCCESS(status))
498  {
500  return status;
501  }
502 
503  // checking this value from layoutEx in case it has been changed
504  if (layoutEx->PartitionStyle != PARTITION_STYLE_MBR)
505  {
508  }
509 
510  size_t size = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry[0]);
511  size += layoutEx->PartitionCount * sizeof(PARTITION_INFORMATION);
512 
514  {
517  }
518 
520 
522 
523  if (partitionList == NULL)
524  {
525  Irp->IoStatus.Information = 0;
527  }
528 
529  RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, partitionList, size);
530  ExFreePoolWithTag(partitionList, TAG_PARTMGR);
531 
532  Irp->IoStatus.Information = size;
533  return STATUS_SUCCESS;
534 }
535 
536 static
537 CODE_SEG("PAGE")
538 NTSTATUS
541  _In_ PIRP Irp)
542 {
543  PAGED_CODE();
544 
546 
547  PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
549  if (!NT_SUCCESS(status))
550  {
552  return status;
553  }
554 
555  size_t size = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[0]);
556  size += layoutEx->PartitionCount * sizeof(PARTITION_INFORMATION_EX);
557 
559  {
562  }
563 
564  RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, layoutEx, size);
565 
567 
568  Irp->IoStatus.Information = size;
569  return STATUS_SUCCESS;
570 }
571 
572 static
573 CODE_SEG("PAGE")
574 NTSTATUS
577  _In_ PIRP Irp)
578 {
579  PDRIVE_LAYOUT_INFORMATION layoutInfo = Irp->AssociatedIrp.SystemBuffer;
580 
581  PAGED_CODE();
582 
583  if (!VerifyIrpInBufferSize(Irp, sizeof(*layoutInfo)))
584  {
586  }
587 
588  size_t layoutSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry[0]);
589  layoutSize += layoutInfo->PartitionCount * sizeof(PARTITION_INFORMATION);
590 
591  if (!VerifyIrpInBufferSize(Irp, layoutSize))
592  {
594  }
595 
596  PDRIVE_LAYOUT_INFORMATION_EX layoutEx = PartMgrConvertLayoutToExtended(layoutInfo);
597 
598  if (layoutEx == NULL)
599  {
600  Irp->IoStatus.Information = 0;
602  }
603 
605 
606  // this in fact updates the bus relations
608 
609  // write the partition table to the disk
610  NTSTATUS status = IoWritePartitionTableEx(FdoExtension->LowerDevice, layoutEx);
611  if (NT_SUCCESS(status))
612  {
613  // save the layout cache
614  if (FdoExtension->LayoutCache)
615  {
616  ExFreePool(FdoExtension->LayoutCache);
617  }
618  FdoExtension->LayoutCache = layoutEx;
619  FdoExtension->LayoutValid = TRUE;
620 
621  // set updated partition numbers
622  for (UINT32 i = 0; i < layoutInfo->PartitionCount; i++)
623  {
624  PPARTITION_INFORMATION part = &layoutInfo->PartitionEntry[i];
625 
626  part->PartitionNumber = layoutEx->PartitionEntry[i].PartitionNumber;
627  }
628  }
629  else
630  {
631  FdoExtension->LayoutValid = FALSE;
632  }
633 
635 
637 
638  // notify everyone that the disk layout has changed
640 
641  notification.Event = GUID_IO_DISK_LAYOUT_CHANGE;
642  notification.Version = 1;
644  notification.FileObject = NULL;
645  notification.NameBufferOffset = -1;
646 
648  &notification,
649  NULL,
650  NULL);
651 
652  Irp->IoStatus.Information = layoutSize;
653  return STATUS_SUCCESS;
654 }
655 
656 static
657 CODE_SEG("PAGE")
658 NTSTATUS
661  _In_ PIRP Irp)
662 {
663  PDRIVE_LAYOUT_INFORMATION_EX layoutEx, layoutUser = Irp->AssociatedIrp.SystemBuffer;
665 
666  PAGED_CODE();
667 
668  if (!VerifyIrpInBufferSize(Irp, sizeof(*layoutUser)))
669  {
671  }
672 
673  size_t layoutSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[0]);
674  layoutSize += layoutUser->PartitionCount * sizeof(PARTITION_INFORMATION_EX);
675 
676  if (!VerifyIrpInBufferSize(Irp, layoutSize))
677  {
679  }
680 
681  // we need to copy the structure from the IRP input buffer
682  layoutEx = ExAllocatePoolWithTag(PagedPool, layoutSize, TAG_PARTMGR);
683  if (!layoutEx)
684  {
685  Irp->IoStatus.Information = 0;
687  }
688 
689  RtlCopyMemory(layoutEx, layoutUser, layoutSize);
690 
692 
693  // if partition count is 0, it's the same as IOCTL_DISK_CREATE_DISK
694  if (layoutEx->PartitionCount == 0)
695  {
696  CREATE_DISK createDisk = {0};
697  createDisk.PartitionStyle = layoutEx->PartitionStyle;
698  if (createDisk.PartitionStyle == PARTITION_STYLE_MBR)
699  {
700  createDisk.Mbr.Signature = layoutEx->Mbr.Signature;
701  }
702  else if (createDisk.PartitionStyle == PARTITION_STYLE_GPT)
703  {
704  createDisk.Gpt.DiskId = layoutEx->Gpt.DiskId;
705  }
706 
707  status = IoCreateDisk(FdoExtension->LowerDevice, &createDisk);
708  }
709  else
710  {
711  // this in fact updates the bus relations
713 
714  // write the partition table to the disk
715  status = IoWritePartitionTableEx(FdoExtension->LowerDevice, layoutEx);
716  if (NT_SUCCESS(status))
717  {
718  // set updated partition numbers
719  for (UINT32 i = 0; i < layoutEx->PartitionCount; i++)
720  {
721  PPARTITION_INFORMATION_EX part = &layoutEx->PartitionEntry[i];
722 
723  part->PartitionNumber = layoutEx->PartitionEntry[i].PartitionNumber;
724  }
725  }
726  }
727 
728  // update the layout cache
729  if (NT_SUCCESS(status))
730  {
731  if (FdoExtension->LayoutCache)
732  {
733  ExFreePool(FdoExtension->LayoutCache);
734  }
735  FdoExtension->LayoutCache = layoutEx;
736  FdoExtension->LayoutValid = TRUE;
737  }
738  else
739  {
740  FdoExtension->LayoutValid = FALSE;
741  }
742 
744 
746 
747  // notify everyone that the disk layout has changed
749 
750  notification.Event = GUID_IO_DISK_LAYOUT_CHANGE;
751  notification.Version = 1;
753  notification.FileObject = NULL;
754  notification.NameBufferOffset = -1;
755 
757  &notification,
758  NULL,
759  NULL);
760 
761  Irp->IoStatus.Information = layoutSize;
762  return STATUS_SUCCESS;
763 }
764 
765 static
766 CODE_SEG("PAGE")
767 NTSTATUS
770  _In_ PIRP Irp)
771 {
772  PAGED_CODE();
773 
775  FdoExtension->LayoutValid = FALSE;
777 
779  return STATUS_SUCCESS;
780 }
781 
782 static
783 CODE_SEG("PAGE")
784 NTSTATUS
787  _In_ PIRP Irp)
788 {
789  PAGED_CODE();
790 
791  PCREATE_DISK createDisk = Irp->AssociatedIrp.SystemBuffer;
792  if (!VerifyIrpInBufferSize(Irp, sizeof(*createDisk)))
793  {
795  }
796 
798 
799  NTSTATUS status = IoCreateDisk(FdoExtension->LowerDevice, createDisk);
800 
801  FdoExtension->LayoutValid = FALSE;
803 
805  return status;
806 }
807 
808 static
809 CODE_SEG("PAGE")
810 NTSTATUS
813  _In_ PIRP Irp)
814 {
815  CREATE_DISK createDisk = { .PartitionStyle = PARTITION_STYLE_RAW };
816 
817  PAGED_CODE();
818 
820 
821  NTSTATUS status = IoCreateDisk(FdoExtension->LowerDevice, &createDisk);
822 
823  FdoExtension->LayoutValid = FALSE;
825 
827  return status;
828 }
829 
830 static
831 CODE_SEG("PAGE")
832 NTSTATUS
835  _In_ PIRP Irp)
836 {
837  // obtain the disk device number
838  // this is not expected to change thus not in PartMgrRefreshDiskData
839  STORAGE_DEVICE_NUMBER deviceNumber;
841  FdoExtension->LowerDevice,
842  NULL,
843  0,
844  &deviceNumber,
845  sizeof(deviceNumber),
846  FALSE);
847  if (!NT_SUCCESS(status))
848  {
849  return status;
850  }
851 
852  FdoExtension->DiskData.DeviceNumber = deviceNumber.DeviceNumber;
853 
854  // register the disk interface
855  // partmgr.sys from Windows 8.1 also registers a mysterious GUID_DEVINTERFACE_HIDDEN_DISK here
856  UNICODE_STRING interfaceName;
858  &GUID_DEVINTERFACE_DISK,
859  NULL,
860  &interfaceName);
861 
862  if(!NT_SUCCESS(status))
863  {
864  ERR("Failed to register GUID_DEVINTERFACE_DISK, status %x\n", status);
865  return status;
866  }
867 
868  FdoExtension->DiskInterfaceName = interfaceName;
869  status = IoSetDeviceInterfaceState(&interfaceName, TRUE);
870 
871  INFO("Disk interface %wZ\n", &interfaceName);
872 
873  if (!NT_SUCCESS(status))
874  {
875  RtlFreeUnicodeString(&interfaceName);
876  RtlInitUnicodeString(&FdoExtension->DiskInterfaceName, NULL);
877  }
878 
879  return status;
880 }
881 
882 // requires partitioning lock held
883 static
884 CODE_SEG("PAGE")
885 NTSTATUS
888 {
890 
891  PAGED_CODE();
892 
893  // get the DiskSize and BytesPerSector
894  DISK_GEOMETRY_EX geometryEx;
896  FdoExtension->LowerDevice,
897  NULL,
898  0,
899  &geometryEx,
900  sizeof(geometryEx),
901  FALSE);
902  if (!NT_SUCCESS(status))
903  {
904  return status;
905  }
906 
907  FdoExtension->DiskData.DiskSize = geometryEx.DiskSize.QuadPart;
908  FdoExtension->DiskData.BytesPerSector = geometryEx.Geometry.BytesPerSector;
909 
910  // get the partition style-related info
911  PDRIVE_LAYOUT_INFORMATION_EX layoutEx = NULL;
913  if (!NT_SUCCESS(status))
914  {
915  return status;
916  }
917 
918  FdoExtension->DiskData.PartitionStyle = layoutEx->PartitionStyle;
919  if (FdoExtension->DiskData.PartitionStyle == PARTITION_STYLE_MBR)
920  {
921  FdoExtension->DiskData.Mbr.Signature = layoutEx->Mbr.Signature;
922  // FdoExtension->DiskData.Mbr.Checksum = geometryEx.Partition.Mbr.CheckSum;
923  }
924  else
925  {
926  FdoExtension->DiskData.Gpt.DiskId = layoutEx->Gpt.DiskId;
927  }
928 
929  return STATUS_SUCCESS;
930 }
931 
932 static
933 CODE_SEG("PAGE")
934 NTSTATUS
937  _In_ PIRP Irp)
938 {
940  DEVICE_RELATION_TYPE type = ioStack->Parameters.QueryDeviceRelations.Type;
941 
942  PAGED_CODE();
943 
944  if (type == BusRelations)
945  {
947 
949  if (!NT_SUCCESS(status))
950  {
952  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
953  Irp->IoStatus.Information = 0;
955  return Irp->IoStatus.Status;
956  }
957 
958  INFO("Partition style %u\n", FdoExtension->DiskData.PartitionStyle);
959 
960  // PartMgrAcquireLayoutLock calls PartMgrGetDriveLayout inside
961  // so we're sure here that it returns only cached layout
962  PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
964 
966 
967  // now fill the DeviceRelations structure
968  TRACE("Reporting %u partitions\n", FdoExtension->EnumeratedPartitionsTotal);
969 
970  PDEVICE_RELATIONS deviceRelations =
972  sizeof(DEVICE_RELATIONS)
973  + sizeof(PDEVICE_OBJECT)
974  * (FdoExtension->EnumeratedPartitionsTotal - 1),
975  TAG_PARTMGR);
976 
977  if (!deviceRelations)
978  {
980  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
981  Irp->IoStatus.Information = 0;
983  return Irp->IoStatus.Status;
984  }
985 
986  deviceRelations->Count = 0;
987 
988  PSINGLE_LIST_ENTRY curEntry = FdoExtension->PartitionList.Next;
989  while (curEntry != NULL)
990  {
991  PPARTITION_EXTENSION partExt = CONTAINING_RECORD(curEntry,
993  ListEntry);
994 
995  // mark the PDO to know that we don't need to manually delete it
996  partExt->IsEnumerated = TRUE;
997  deviceRelations->Objects[deviceRelations->Count++] = partExt->DeviceObject;
999 
1000  curEntry = partExt->ListEntry.Next;
1001  }
1002 
1003  ASSERT(deviceRelations->Count == FdoExtension->EnumeratedPartitionsTotal);
1004 
1006 
1007  Irp->IoStatus.Information = (ULONG_PTR)deviceRelations;
1008  Irp->IoStatus.Status = STATUS_SUCCESS;
1009  }
1010 
1012  return IoCallDriver(FdoExtension->LowerDevice, Irp);
1013 }
1014 
1015 static
1016 CODE_SEG("PAGE")
1017 NTSTATUS
1020  _In_ PIRP Irp)
1021 {
1022  PAGED_CODE();
1023 
1024  if (FdoExtension->DiskInterfaceName.Buffer)
1025  {
1026  IoSetDeviceInterfaceState(&FdoExtension->DiskInterfaceName, FALSE);
1027  RtlFreeUnicodeString(&FdoExtension->DiskInterfaceName);
1028  RtlInitUnicodeString(&FdoExtension->DiskInterfaceName, NULL);
1029  }
1030 
1031  // Send the IRP down the stack
1033  Irp->IoStatus.Status = STATUS_SUCCESS;
1034  NTSTATUS status = IoCallDriver(FdoExtension->LowerDevice, Irp);
1035 
1036  IoDetachDevice(FdoExtension->LowerDevice);
1037  IoDeleteDevice(FdoExtension->DeviceObject);
1038  return status;
1039 }
1040 
1041 static
1042 CODE_SEG("PAGE")
1043 NTSTATUS
1046  _In_ PIRP Irp)
1047 {
1048  PAGED_CODE();
1049 
1050  // all enumerated child devices should receive IRP_MN_REMOVE_DEVICE
1051  // removing only non-enumerated ones here
1052  for (PSINGLE_LIST_ENTRY curEntry = FdoExtension->PartitionList.Next;
1053  curEntry != NULL;
1054  curEntry = curEntry->Next)
1055  {
1056  PPARTITION_EXTENSION partExt = CONTAINING_RECORD(curEntry,
1058  ListEntry);
1059 
1060  if (partExt->IsEnumerated)
1061  {
1062  PartitionHandleRemove(partExt, TRUE);
1063  }
1064  }
1065 
1066  // Send the IRP down the stack
1068  Irp->IoStatus.Status = STATUS_SUCCESS;
1069  return IoCallDriver(FdoExtension->LowerDevice, Irp);
1070 }
1071 
1072 static
1073 CODE_SEG("PAGE")
1074 NTSTATUS
1075 NTAPI
1079 {
1081 
1082  PAGED_CODE();
1083 
1085  sizeof(FDO_EXTENSION),
1086  0,
1089  FALSE,
1090  &deviceObject);
1091 
1092  if (!NT_SUCCESS(status))
1093  {
1094  ERR("Failed to create FDO 0x%x\n", status);
1095  return status;
1096  }
1097 
1098  PFDO_EXTENSION deviceExtension = deviceObject->DeviceExtension;
1099  RtlZeroMemory(deviceExtension, sizeof(*deviceExtension));
1100 
1101  deviceExtension->IsFDO = TRUE;
1102  deviceExtension->DeviceObject = deviceObject;
1104  deviceExtension->PhysicalDiskDO = PhysicalDeviceObject;
1106 
1107  // the the attaching failed
1108  if (!deviceExtension->LowerDevice)
1109  {
1111 
1112  return STATUS_DEVICE_REMOVED;
1113  }
1115 
1116  // device is initialized
1118 
1119  return STATUS_SUCCESS;
1120 }
1121 
1122 static
1123 NTSTATUS
1124 NTAPI
1127  _In_ PIRP Irp)
1128 {
1130  PFDO_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
1131  NTSTATUS status;
1132 
1133  // Note: IRP_MJ_DEVICE_CONTROL handler in the storage stack must be able to pass IOCTLs
1134  // at an IRQL higher than PASSIVE_LEVEL
1135 
1136  INFO("IRP_MJ_DEVICE_CONTROL %p Irp %p IOCTL %x isFdo: %u\n",
1137  DeviceObject, Irp, ioStack->Parameters.DeviceIoControl.IoControlCode, fdoExtension->IsFDO);
1138 
1139  if (!fdoExtension->IsFDO)
1140  {
1142  }
1143 
1144  switch (ioStack->Parameters.DeviceIoControl.IoControlCode)
1145  {
1147  status = FdoIoctlDiskGetDriveGeometryEx(fdoExtension, Irp);
1148  break;
1149 
1151  status = FdoIoctlDiskGetPartitionInfo(fdoExtension, Irp);
1152  break;
1153 
1155  status = FdoIoctlDiskGetPartitionInfoEx(fdoExtension, Irp);
1156  break;
1157 
1159  status = FdoIoctlDiskGetDriveLayout(fdoExtension, Irp);
1160  break;
1161 
1163  status = FdoIoctlDiskGetDriveLayoutEx(fdoExtension, Irp);
1164  break;
1165 
1167  status = FdoIoctlDiskSetDriveLayout(fdoExtension, Irp);
1168  break;
1169 
1171  status = FdoIoctlDiskSetDriveLayoutEx(fdoExtension, Irp);
1172  break;
1173 
1175  status = FdoIoctlDiskUpdateProperties(fdoExtension, Irp);
1176  break;
1177 
1179  status = FdoIoctlDiskCreateDisk(fdoExtension, Irp);
1180  break;
1181 
1183  status = FdoIoctlDiskDeleteDriveLayout(fdoExtension, Irp);
1184  break;
1185  // case IOCTL_DISK_GROW_PARTITION: // todo
1186  default:
1188  }
1189 
1190  Irp->IoStatus.Status = status;
1192  return status;
1193 }
1194 
1195 static
1196 CODE_SEG("PAGE")
1197 NTSTATUS
1198 NTAPI
1201  _In_ PIRP Irp)
1202 {
1203  PAGED_CODE();
1204 
1205  PFDO_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
1207 
1208  INFO("IRP_MJ_PNP %p Irp %p %s isFDO: %u\n",
1209  DeviceObject, Irp, GetIRPMinorFunctionString(ioStack->MinorFunction), fdoExtension->IsFDO);
1210 
1211  if (!fdoExtension->IsFDO)
1212  {
1214  }
1215 
1216  switch (ioStack->MinorFunction) {
1217 
1218  case IRP_MN_START_DEVICE:
1219  {
1220  NTSTATUS status;
1221 
1222  // if this is sent to the FDO so we should forward it down the
1223  // attachment chain before we can start the FDO
1224 
1225  if (!IoForwardIrpSynchronously(fdoExtension->LowerDevice, Irp))
1226  {
1228  }
1229  else
1230  {
1231  status = FdoHandleStartDevice(fdoExtension, Irp);
1232  }
1233 
1234  Irp->IoStatus.Status = status;
1236  return status;
1237  }
1239  {
1240  return FdoHandleDeviceRelations(fdoExtension, Irp);
1241  }
1243  {
1244  return FdoHandleSurpriseRemoval(fdoExtension, Irp);
1245  }
1246  case IRP_MN_REMOVE_DEVICE:
1247  {
1248  return FdoHandleRemoveDevice(fdoExtension, Irp);
1249  }
1254  case IRP_MN_STOP_DEVICE:
1255  {
1256  Irp->IoStatus.Status = STATUS_SUCCESS;
1257  // fallthrough
1258  }
1259  default:
1260  {
1262  return IoCallDriver(fdoExtension->LowerDevice, Irp);
1263  }
1264  }
1265 }
1266 
1267 static
1268 NTSTATUS
1269 NTAPI
1272  _In_ PIRP Irp)
1273 {
1274  PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
1276 
1277  if (!partExt->IsFDO)
1278  {
1279  if (!partExt->IsEnumerated)
1280  {
1281  Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
1284  }
1285  else
1286  {
1287  ioStack->Parameters.Read.ByteOffset.QuadPart += partExt->StartingOffset;
1288  }
1289  }
1290 
1292  return IoCallDriver(partExt->LowerDevice, Irp);
1293 }
1294 
1296 NTSTATUS
1297 NTAPI
1300  _In_ PIRP Irp)
1301 {
1302  PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
1304 
1306 
1307  if (!partExt->IsFDO)
1308  {
1309  NTSTATUS status;
1310 
1311  if (!partExt->IsEnumerated)
1312  {
1314  }
1315  else if (ioStack->MinorFunction == IRP_MN_SET_POWER ||
1316  ioStack->MinorFunction == IRP_MN_QUERY_POWER)
1317  {
1319  }
1320  else
1321  {
1322  status = Irp->IoStatus.Status;
1323  }
1324 
1325  Irp->IoStatus.Status = status;
1327  return status;
1328  }
1329  else
1330  {
1332  return PoCallDriver(partExt->LowerDevice, Irp);
1333  }
1334 }
1335 
1337 NTSTATUS
1338 NTAPI
1341  _In_ PIRP Irp)
1342 {
1343  PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
1344  PDEVICE_OBJECT lowerDevice;
1345 
1346  // forward to the partition0 device in both cases
1347  if (!partExt->IsFDO)
1348  {
1349  if (!partExt->IsEnumerated)
1350  {
1351  Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
1354  }
1355  else
1356  {
1357  PFDO_EXTENSION fdoExtension = partExt->LowerDevice->DeviceExtension;
1358  lowerDevice = fdoExtension->LowerDevice;
1359  }
1360  }
1361  else
1362  {
1363  lowerDevice = partExt->LowerDevice;
1364  }
1365 
1367  return IoCallDriver(lowerDevice, Irp);
1368 }
1369 
1370 CODE_SEG("PAGE")
1371 VOID
1372 NTAPI
1375 {
1376 
1377 }
1378 
1379 CODE_SEG("INIT")
1380 NTSTATUS
1381 NTAPI
1385 {
1386  DriverObject->DriverUnload = PartMgrUnload;
1387  DriverObject->DriverExtension->AddDevice = PartMgrAddDevice;
1389  DriverObject->MajorFunction[IRP_MJ_CLOSE] = ForwardIrpAndForget;
1390  DriverObject->MajorFunction[IRP_MJ_READ] = PartMgrReadWrite;
1391  DriverObject->MajorFunction[IRP_MJ_WRITE] = PartMgrReadWrite;
1393  DriverObject->MajorFunction[IRP_MJ_PNP] = PartMgrPnp;
1396  DriverObject->MajorFunction[IRP_MJ_POWER] = PartMgrPower;
1397 
1398  return STATUS_SUCCESS;
1399 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
Definition: ntddk_ex.h:208
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define DO_POWER_PAGABLE
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:428
#define IOCTL_DISK_SET_DRIVE_LAYOUT_EX
Definition: ntdddisk.h:208
#define STATUS_DEVICE_REMOVED
Definition: ntstatus.h:809
LARGE_INTEGER PartitionLength
Definition: ntdddisk.h:414
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define IRP_MN_REMOVE_DEVICE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define _Inout_
Definition: ms_sal.h:378
#define IRP_MJ_FLUSH_BUFFERS
#define IRP_MN_QUERY_POWER
Definition: ntbasedef.h:628
#define _Out_
Definition: ms_sal.h:345
#define IRP_MJ_SHUTDOWN
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1625
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
PDEVICE_OBJECT LowerDevice
Definition: partmgr.h:38
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
static PDRIVE_LAYOUT_INFORMATION PartMgrConvertExtendedToLayout(_In_ CONST PDRIVE_LAYOUT_INFORMATION_EX LayoutEx)
Definition: partmgr.c:20
static PDRIVE_LAYOUT_INFORMATION_EX PartMgrConvertLayoutToExtended(_In_ CONST PDRIVE_LAYOUT_INFORMATION Layout)
Definition: partmgr.c:72
static NTSTATUS FdoHandleSurpriseRemoval(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:1044
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
#define IOCTL_DISK_CREATE_DISK
Definition: ntdddisk.h:55
static VOID PartMgrUpdatePartitionDevices(_In_ PFDO_EXTENSION FdoExtension, _Inout_ PDRIVE_LAYOUT_INFORMATION_EX NewLayout)
Definition: partmgr.c:120
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
NTSTATUS NTAPI IoCreateDisk(IN PDEVICE_OBJECT DeviceObject, IN PCREATE_DISK Disk)
Definition: fstubex.c:1801
PDEVICE_OBJECT PhysicalDiskDO
Definition: partmgr.h:39
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
static NTSTATUS NTAPI PartMgrReadWrite(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partmgr.c:1270
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:316
ULONG BytesPerSector
Definition: ntdddisk.h:409
NTSTATUS PartitionHandlePnp(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partition.c:385
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1155
DRIVER_DISPATCH PartMgrShutdownFlush
Definition: partmgr.c:1336
struct _PARTITION_INFORMATION PARTITION_INFORMATION
static NTSTATUS NTAPI PartMgrPnp(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partmgr.c:1199
static NTSTATUS FdoIoctlDiskGetDriveLayoutEx(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:539
PARTITION_INFORMATION_MBR Mbr
Definition: imports.h:226
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
NTSTATUS PartitionHandleDeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partition.c:449
static NTSTATUS FdoIoctlDiskGetPartitionInfo(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:421
LARGE_INTEGER DiskSize
Definition: winioctl.h:331
static NTSTATUS FdoHandleStartDevice(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:833
PARTITION_INFORMATION_GPT Gpt
Definition: imports.h:227
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
PARTITION_STYLE PartitionStyle
Definition: imports.h:220
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
NTSTATUS NTAPI DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
Definition: partmgr.c:1382
struct _PARTITION_INFORMATION_EX PARTITION_INFORMATION_EX
static NTSTATUS FdoIoctlDiskUpdateProperties(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:768
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
static NTSTATUS FdoHandleDeviceRelations(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:935
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
BOOLEAN Attached
Definition: partmgr.h:80
unsigned int UINT32
#define IRP_MN_QUERY_REMOVE_DEVICE
#define IOCTL_DISK_DELETE_DRIVE_LAYOUT
Definition: ntdddisk.h:58
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
DISK_GEOMETRY Geometry
Definition: winioctl.h:330
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
PDEVICE_OBJECT DeviceObject
Definition: partmgr.h:37
PARTITION_INFORMATION PartitionEntry[1]
Definition: ntdddisk.h:426
#define _In_
Definition: ms_sal.h:308
#define IoCompleteRequest
Definition: irp.c:1240
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:143
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
enum _DEVICE_RELATION_TYPE DEVICE_RELATION_TYPE
#define IRP_MN_QUERY_STOP_DEVICE
#define IOCTL_DISK_UPDATE_PROPERTIES
Definition: ntdddisk.h:242
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
UINT64 PartitionLength
Definition: partmgr.h:73
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
FORCEINLINE BOOLEAN VerifyIrpOutBufferSize(_In_ PIRP Irp, _In_ SIZE_T Size)
Definition: partmgr.h:147
#define TRACE(s)
Definition: solgame.cpp:4
static NTSTATUS FdoHandleRemoveDevice(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:1018
GLsizeiptr size
Definition: glext.h:5919
static NTSTATUS FdoIoctlDiskDeleteDriveLayout(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:811
#define IRP_MN_STOP_DEVICE
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:413
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
#define IRP_MN_START_DEVICE
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
LARGE_INTEGER PartitionLength
Definition: imports.h:222
static NTSTATUS PartMgrRefreshDiskData(_In_ PFDO_EXTENSION FdoExtension)
Definition: partmgr.c:886
static NTSTATUS FdoIoctlDiskSetDriveLayout(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:575
UINT32 OnDiskNumber
Definition: partmgr.h:77
NTSTATUS NTAPI IoReadPartitionTableEx(IN PDEVICE_OBJECT DeviceObject, IN PDRIVE_LAYOUT_INFORMATION_EX *DriveLayout)
Definition: fstubex.c:2273
static NTSTATUS FdoIoctlDiskGetPartitionInfoEx(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:456
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
BOOLEAN RewritePartition
Definition: ntdddisk.h:420
LARGE_INTEGER StartingOffset
Definition: imports.h:221
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
#define IRP_MJ_POWER
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IOCTL_DISK_GET_PARTITION_INFO
Definition: ntdddisk.h:106
PDEVICE_OBJECT LowerDevice
Definition: partmgr.h:69
static NTSTATUS NTAPI PartMgrAddDevice(_In_ PDRIVER_OBJECT DriverObject, _In_ PDEVICE_OBJECT PhysicalDeviceObject)
Definition: partmgr.c:1076
UINT32 DetectedNumber
Definition: partmgr.h:76
#define IRP_MN_SET_POWER
NTSTATUS NTAPI IoWritePartitionTableEx(IN PDEVICE_OBJECT DeviceObject, IN PDRIVE_LAYOUT_INFORMATION_EX DriveLayout)
Definition: fstubex.c:2460
FORCEINLINE BOOLEAN VerifyIrpInBufferSize(_In_ PIRP Irp, _In_ SIZE_T Size)
Definition: partmgr.h:162
DRIVER_DISPATCH(nfs41_FsdDispatch)
MxDeviceObject deviceObject
struct _PARTITION_EXTENSION::@1269::@1272 Mbr
DRIVER_DISPATCH PartMgrPower
Definition: partmgr.c:1295
FORCEINLINE VOID PartMgrReleaseLayoutLock(_In_ PFDO_EXTENSION FDOExtension)
Definition: partmgr.h:187
#define IOCTL_DISK_GET_DRIVE_LAYOUT
Definition: ntdddisk.h:91
#define ERR(fmt,...)
Definition: debug.h:110
FORCEINLINE PCHAR GetIRPMinorFunctionString(UCHAR MinorFunction)
Definition: driverdbg.h:13
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
KEVENT SyncEvent
Definition: partmgr.h:40
static NTSTATUS PartMgrGetDriveLayout(_In_ PFDO_EXTENSION FdoExtension, _Out_ PDRIVE_LAYOUT_INFORMATION_EX *DriveLayout)
Definition: partmgr.c:322
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:2342
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:746
#define IOCTL_DISK_GET_DRIVE_LAYOUT_EX
Definition: ntddk_ex.h:207
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
VOID NTAPI PartMgrUnload(_In_ PDRIVER_OBJECT DriverObject)
Definition: partmgr.c:1373
PDEVICE_OBJECT DeviceObject
Definition: partmgr.h:68
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define INFO(fmt,...)
Definition: debug.h:13
static NTSTATUS FdoIoctlDiskGetDriveLayout(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:486
#define IRP_MJ_READ
Definition: rdpdr.c:46
NTSTATUS PartitionHandleRemove(_In_ PPARTITION_EXTENSION PartExt, _In_ BOOLEAN FinalRemove)
Definition: partition.c:175
DISK_PARTITION_INFO Partition
Definition: disk.c:3667
#define ObReferenceObject
Definition: obfuncs.h:204
BOOLEAN IsEnumerated
Definition: partmgr.h:78
#define IO_NO_INCREMENT
Definition: iotypes.h:598
SINGLE_LIST_ENTRY ListEntry
Definition: partmgr.h:74
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
static NTSTATUS FdoIoctlDiskCreateDisk(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:785
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IOCTL_DISK_SET_DRIVE_LAYOUT
Definition: ntdddisk.h:205
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
BOOLEAN RecognizedPartition
Definition: ntdddisk.h:419
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
#define IRP_MN_CANCEL_STOP_DEVICE
BOOLEAN IsFDO
Definition: partmgr.h:36
#define STATUS_SUCCESS
Definition: shellext.h:65
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
static NTSTATUS FdoIoctlDiskGetDriveGeometryEx(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:358
#define FILE_DEVICE_BUS_EXTENDER
Definition: winioctl.h:148
NTSTATUS NTAPI IoReportTargetDeviceChangeAsynchronous(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PVOID NotificationStructure, IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL, IN PVOID Context OPTIONAL)
Definition: pnpreport.c:497
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
FORCEINLINE VOID PartMgrAcquireLayoutLock(_In_ PFDO_EXTENSION FDOExtension)
Definition: partmgr.h:177
static SERVICE_STATUS status
Definition: service.c:31
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
UINT64 StartingOffset
Definition: partmgr.h:72
#define TAG_PARTMGR
Definition: partmgr.h:23
#define CONST
Definition: pedump.c:81
struct _PARTITION_EXTENSION::@1269::@1271 Gpt
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define IOCTL_DISK_GET_PARTITION_INFO_EX
Definition: ntddk_ex.h:206
LONGLONG QuadPart
Definition: typedefs.h:114
static NTSTATUS FdoIoctlDiskSetDriveLayoutEx(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:659
static NTSTATUS NTAPI PartMgrDeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partmgr.c:1125
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define PAGED_CODE()
Definition: ps.c:97