ReactOS  0.4.15-dev-3207-ga415bd4
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  totalPartitions++;
273 
274  // insert the structure to the partition list
275  curEntry = FdoExtension->PartitionList.Next;
276  prevEntry = NULL;
277  while (curEntry != NULL)
278  {
279  PPARTITION_EXTENSION curPart = CONTAINING_RECORD(curEntry,
281  ListEntry);
282  if (curPart->OnDiskNumber < partNumber)
283  {
284  prevEntry = curEntry;
285  curEntry = curPart->ListEntry.Next;
286  }
287  else
288  { // we found where to put the partition
289  break;
290  }
291  }
292 
293  PPARTITION_EXTENSION partExt = partitionDevice->DeviceExtension;
294 
295  if (prevEntry)
296  {
297  // insert after prevEntry
298  partExt->ListEntry.Next = prevEntry->Next;
299  prevEntry->Next = &partExt->ListEntry;
300  }
301  else
302  {
303  // insert in the beginning
304  partExt->ListEntry.Next = FdoExtension->PartitionList.Next;
305  FdoExtension->PartitionList.Next = &partExt->ListEntry;
306  }
307 
308  partExt->Attached = TRUE;
309  }
310 
311  FdoExtension->EnumeratedPartitionsTotal = totalPartitions;
312 }
313 
314 // requires partitioning lock held
315 static
316 CODE_SEG("PAGE")
317 NTSTATUS
320  _Out_ PDRIVE_LAYOUT_INFORMATION_EX *DriveLayout)
321 {
322  PAGED_CODE();
323 
324  if (FdoExtension->LayoutValid)
325  {
326  *DriveLayout = FdoExtension->LayoutCache;
327  return STATUS_SUCCESS;
328  }
329 
330  PDRIVE_LAYOUT_INFORMATION_EX layoutEx = NULL;
331  NTSTATUS status = IoReadPartitionTableEx(FdoExtension->LowerDevice, &layoutEx);
332 
333  if (!NT_SUCCESS(status))
334  {
335  return status;
336  }
337 
338  if (FdoExtension->LayoutCache)
339  {
340  ExFreePool(FdoExtension->LayoutCache);
341  }
342 
343  FdoExtension->LayoutCache = layoutEx;
344  FdoExtension->LayoutValid = TRUE;
345 
346  *DriveLayout = layoutEx;
347 
348  return status;
349 }
350 
351 static
352 CODE_SEG("PAGE")
353 NTSTATUS
356  _In_ PIRP Irp)
357 {
359 
360  PAGED_CODE();
361 
362  // We're patching the DISK_PARTITION_INFO part of the returned structure
363  // as disk.sys doesn't really know about the partition table on a disk
364 
365  PDISK_GEOMETRY_EX_INTERNAL geometryEx = Irp->AssociatedIrp.SystemBuffer;
366  size_t outBufferLength = ioStack->Parameters.DeviceIoControl.OutputBufferLength;
368 
370  FdoExtension->LowerDevice,
371  NULL,
372  0,
373  geometryEx,
374  outBufferLength,
375  FALSE);
376 
377  if (!NT_SUCCESS(status))
378  {
379  return status;
380  }
381 
382  // if DISK_PARTITION_INFO fits the output size
383  if (outBufferLength >= FIELD_OFFSET(DISK_GEOMETRY_EX_INTERNAL, Detection))
384  {
386 
387  geometryEx->Partition.SizeOfPartitionInfo = sizeof(geometryEx->Partition);
388  geometryEx->Partition.PartitionStyle = FdoExtension->DiskData.PartitionStyle;
389 
390  switch (geometryEx->Partition.PartitionStyle)
391  {
392  case PARTITION_STYLE_MBR:
393  geometryEx->Partition.Mbr.Signature = FdoExtension->DiskData.Mbr.Signature;
394  // checksum?
395  break;
396 
397  case PARTITION_STYLE_GPT:
398  geometryEx->Partition.Gpt.DiskId = FdoExtension->DiskData.Gpt.DiskId;
399  break;
400 
401  default:
402  RtlZeroMemory(&geometryEx->Partition, sizeof(geometryEx->Partition));
403  }
404 
406  }
407 
408  // the logic is copied from disk.sys
409  Irp->IoStatus.Information = min(outBufferLength, sizeof(DISK_GEOMETRY_EX_INTERNAL));
410 
411  return status;
412 }
413 
414 static
415 CODE_SEG("PAGE")
416 NTSTATUS
419  _In_ PIRP Irp)
420 {
421  PPARTITION_INFORMATION partInfo = Irp->AssociatedIrp.SystemBuffer;
422 
423  PAGED_CODE();
424 
425  if (!VerifyIrpOutBufferSize(Irp, sizeof(*partInfo)))
426  {
428  }
429 
431 
432  *partInfo = (PARTITION_INFORMATION){
434  .StartingOffset.QuadPart = 0,
435  .PartitionLength.QuadPart = FdoExtension->DiskData.DiskSize,
436  .HiddenSectors = 0,
437  .PartitionNumber = 0,
438  .BootIndicator = FALSE,
439  .RewritePartition = FALSE,
440  .RecognizedPartition = FALSE,
441  };
442 
444 
445  Irp->IoStatus.Information = sizeof(*partInfo);
446  return STATUS_SUCCESS;
447 }
448 
449 static
450 CODE_SEG("PAGE")
451 NTSTATUS
454  _In_ PIRP Irp)
455 {
456  PPARTITION_INFORMATION_EX partInfoEx = Irp->AssociatedIrp.SystemBuffer;
457 
458  PAGED_CODE();
459 
460  if (!VerifyIrpOutBufferSize(Irp, sizeof(*partInfoEx)))
461  {
463  }
464 
466 
467  // most of the fields a zeroed for Partition0
468  *partInfoEx = (PARTITION_INFORMATION_EX){
469  .PartitionLength.QuadPart = FdoExtension->DiskData.DiskSize,
470  .PartitionStyle = FdoExtension->DiskData.PartitionStyle,
471  };
472 
474 
475  Irp->IoStatus.Information = sizeof(*partInfoEx);
476  return STATUS_SUCCESS;
477 }
478 
479 static
480 CODE_SEG("PAGE")
481 NTSTATUS
484  _In_ PIRP Irp)
485 {
486  PAGED_CODE();
487 
489 
490  PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
492 
493  if (!NT_SUCCESS(status))
494  {
496  return status;
497  }
498 
499  // checking this value from layoutEx in case it has been changed
500  if (layoutEx->PartitionStyle != PARTITION_STYLE_MBR)
501  {
504  }
505 
506  size_t size = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry[0]);
507  size += layoutEx->PartitionCount * sizeof(PARTITION_INFORMATION);
508 
510  {
513  }
514 
516 
518 
519  if (partitionList == NULL)
520  {
521  Irp->IoStatus.Information = 0;
523  }
524 
525  RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, partitionList, size);
526  ExFreePoolWithTag(partitionList, TAG_PARTMGR);
527 
528  Irp->IoStatus.Information = size;
529  return STATUS_SUCCESS;
530 }
531 
532 static
533 CODE_SEG("PAGE")
534 NTSTATUS
537  _In_ PIRP Irp)
538 {
539  PAGED_CODE();
540 
542 
543  PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
545  if (!NT_SUCCESS(status))
546  {
548  return status;
549  }
550 
551  size_t size = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[0]);
552  size += layoutEx->PartitionCount * sizeof(PARTITION_INFORMATION_EX);
553 
555  {
558  }
559 
560  RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, layoutEx, size);
561 
563 
564  Irp->IoStatus.Information = size;
565  return STATUS_SUCCESS;
566 }
567 
568 static
569 CODE_SEG("PAGE")
570 NTSTATUS
573  _In_ PIRP Irp)
574 {
575  PDRIVE_LAYOUT_INFORMATION layoutInfo = Irp->AssociatedIrp.SystemBuffer;
576 
577  PAGED_CODE();
578 
579  if (!VerifyIrpInBufferSize(Irp, sizeof(*layoutInfo)))
580  {
582  }
583 
584  size_t layoutSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry[0]);
585  layoutSize += layoutInfo->PartitionCount * sizeof(PARTITION_INFORMATION);
586 
587  if (!VerifyIrpInBufferSize(Irp, layoutSize))
588  {
590  }
591 
592  PDRIVE_LAYOUT_INFORMATION_EX layoutEx = PartMgrConvertLayoutToExtended(layoutInfo);
593 
594  if (layoutEx == NULL)
595  {
596  Irp->IoStatus.Information = 0;
598  }
599 
601 
602  // this in fact updates the bus relations
604 
605  // write the partition table to the disk
606  NTSTATUS status = IoWritePartitionTableEx(FdoExtension->LowerDevice, layoutEx);
607  if (NT_SUCCESS(status))
608  {
609  // save the layout cache
610  if (FdoExtension->LayoutCache)
611  {
612  ExFreePool(FdoExtension->LayoutCache);
613  }
614  FdoExtension->LayoutCache = layoutEx;
615  FdoExtension->LayoutValid = TRUE;
616 
617  // set updated partition numbers
618  for (UINT32 i = 0; i < layoutInfo->PartitionCount; i++)
619  {
620  PPARTITION_INFORMATION part = &layoutInfo->PartitionEntry[i];
621 
622  part->PartitionNumber = layoutEx->PartitionEntry[i].PartitionNumber;
623  }
624  }
625  else
626  {
627  FdoExtension->LayoutValid = FALSE;
628  }
629 
631 
633 
634  // notify everyone that the disk layout has changed
636 
637  notification.Event = GUID_IO_DISK_LAYOUT_CHANGE;
638  notification.Version = 1;
640  notification.FileObject = NULL;
641  notification.NameBufferOffset = -1;
642 
644  &notification,
645  NULL,
646  NULL);
647 
648  Irp->IoStatus.Information = layoutSize;
649  return STATUS_SUCCESS;
650 }
651 
652 static
653 CODE_SEG("PAGE")
654 NTSTATUS
657  _In_ PIRP Irp)
658 {
659  PDRIVE_LAYOUT_INFORMATION_EX layoutEx, layoutUser = Irp->AssociatedIrp.SystemBuffer;
661 
662  PAGED_CODE();
663 
664  if (!VerifyIrpInBufferSize(Irp, sizeof(*layoutUser)))
665  {
667  }
668 
669  size_t layoutSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[0]);
670  layoutSize += layoutUser->PartitionCount * sizeof(PARTITION_INFORMATION_EX);
671 
672  if (!VerifyIrpInBufferSize(Irp, layoutSize))
673  {
675  }
676 
677  // we need to copy the structure from the IRP input buffer
678  layoutEx = ExAllocatePoolWithTag(PagedPool, layoutSize, TAG_PARTMGR);
679  if (!layoutEx)
680  {
681  Irp->IoStatus.Information = 0;
683  }
684 
685  RtlCopyMemory(layoutEx, layoutUser, layoutSize);
686 
688 
689  // if partition count is 0, it's the same as IOCTL_DISK_CREATE_DISK
690  if (layoutEx->PartitionCount == 0)
691  {
692  CREATE_DISK createDisk = {0};
693  createDisk.PartitionStyle = layoutEx->PartitionStyle;
694  if (createDisk.PartitionStyle == PARTITION_STYLE_MBR)
695  {
696  createDisk.Mbr.Signature = layoutEx->Mbr.Signature;
697  }
698  else if (createDisk.PartitionStyle == PARTITION_STYLE_GPT)
699  {
700  createDisk.Gpt.DiskId = layoutEx->Gpt.DiskId;
701  }
702 
703  status = IoCreateDisk(FdoExtension->LowerDevice, &createDisk);
704  }
705  else
706  {
707  // this in fact updates the bus relations
709 
710  // write the partition table to the disk
711  status = IoWritePartitionTableEx(FdoExtension->LowerDevice, layoutEx);
712  if (NT_SUCCESS(status))
713  {
714  // set updated partition numbers
715  for (UINT32 i = 0; i < layoutEx->PartitionCount; i++)
716  {
717  PPARTITION_INFORMATION_EX part = &layoutEx->PartitionEntry[i];
718 
719  part->PartitionNumber = layoutEx->PartitionEntry[i].PartitionNumber;
720  }
721  }
722  }
723 
724  // update the layout cache
725  if (NT_SUCCESS(status))
726  {
727  if (FdoExtension->LayoutCache)
728  {
729  ExFreePool(FdoExtension->LayoutCache);
730  }
731  FdoExtension->LayoutCache = layoutEx;
732  FdoExtension->LayoutValid = TRUE;
733  }
734  else
735  {
736  FdoExtension->LayoutValid = FALSE;
737  }
738 
740 
742 
743  // notify everyone that the disk layout has changed
745 
746  notification.Event = GUID_IO_DISK_LAYOUT_CHANGE;
747  notification.Version = 1;
749  notification.FileObject = NULL;
750  notification.NameBufferOffset = -1;
751 
753  &notification,
754  NULL,
755  NULL);
756 
757  Irp->IoStatus.Information = layoutSize;
758  return STATUS_SUCCESS;
759 }
760 
761 static
762 CODE_SEG("PAGE")
763 NTSTATUS
766  _In_ PIRP Irp)
767 {
768  PAGED_CODE();
769 
771  FdoExtension->LayoutValid = FALSE;
773 
775  return STATUS_SUCCESS;
776 }
777 
778 static
779 CODE_SEG("PAGE")
780 NTSTATUS
783  _In_ PIRP Irp)
784 {
785  PAGED_CODE();
786 
787  PCREATE_DISK createDisk = Irp->AssociatedIrp.SystemBuffer;
788  if (!VerifyIrpInBufferSize(Irp, sizeof(*createDisk)))
789  {
791  }
792 
794 
795  NTSTATUS status = IoCreateDisk(FdoExtension->LowerDevice, createDisk);
796 
797  FdoExtension->LayoutValid = FALSE;
799 
801  return status;
802 }
803 
804 static
805 CODE_SEG("PAGE")
806 NTSTATUS
809  _In_ PIRP Irp)
810 {
811  CREATE_DISK createDisk = { .PartitionStyle = PARTITION_STYLE_RAW };
812 
813  PAGED_CODE();
814 
816 
817  NTSTATUS status = IoCreateDisk(FdoExtension->LowerDevice, &createDisk);
818 
819  FdoExtension->LayoutValid = FALSE;
821 
823  return status;
824 }
825 
826 static
827 CODE_SEG("PAGE")
828 NTSTATUS
831  _In_ PIRP Irp)
832 {
833  // obtain the disk device number
834  // this is not expected to change thus not in PartMgrRefreshDiskData
835  STORAGE_DEVICE_NUMBER deviceNumber;
837  FdoExtension->LowerDevice,
838  NULL,
839  0,
840  &deviceNumber,
841  sizeof(deviceNumber),
842  FALSE);
843  if (!NT_SUCCESS(status))
844  {
845  return status;
846  }
847 
848  FdoExtension->DiskData.DeviceNumber = deviceNumber.DeviceNumber;
849 
850  // register the disk interface
851  // partmgr.sys from Windows 8.1 also registers a mysterious GUID_DEVINTERFACE_HIDDEN_DISK here
852  UNICODE_STRING interfaceName;
854  &GUID_DEVINTERFACE_DISK,
855  NULL,
856  &interfaceName);
857 
858  if(!NT_SUCCESS(status))
859  {
860  ERR("Failed to register GUID_DEVINTERFACE_DISK, status %x\n", status);
861  return status;
862  }
863 
864  FdoExtension->DiskInterfaceName = interfaceName;
865  status = IoSetDeviceInterfaceState(&interfaceName, TRUE);
866 
867  INFO("Disk interface %wZ\n", &interfaceName);
868 
869  if (!NT_SUCCESS(status))
870  {
871  RtlFreeUnicodeString(&interfaceName);
872  RtlInitUnicodeString(&FdoExtension->DiskInterfaceName, NULL);
873  }
874 
875  return status;
876 }
877 
878 // requires partitioning lock held
879 static
880 CODE_SEG("PAGE")
881 NTSTATUS
884 {
886 
887  PAGED_CODE();
888 
889  // get the DiskSize and BytesPerSector
890  DISK_GEOMETRY_EX geometryEx;
892  FdoExtension->LowerDevice,
893  NULL,
894  0,
895  &geometryEx,
896  sizeof(geometryEx),
897  FALSE);
898  if (!NT_SUCCESS(status))
899  {
900  return status;
901  }
902 
903  FdoExtension->DiskData.DiskSize = geometryEx.DiskSize.QuadPart;
904  FdoExtension->DiskData.BytesPerSector = geometryEx.Geometry.BytesPerSector;
905 
906  // get the partition style-related info
907  PDRIVE_LAYOUT_INFORMATION_EX layoutEx = NULL;
909  if (!NT_SUCCESS(status))
910  {
911  return status;
912  }
913 
914  FdoExtension->DiskData.PartitionStyle = layoutEx->PartitionStyle;
915  if (FdoExtension->DiskData.PartitionStyle == PARTITION_STYLE_MBR)
916  {
917  FdoExtension->DiskData.Mbr.Signature = layoutEx->Mbr.Signature;
918  // FdoExtension->DiskData.Mbr.Checksum = geometryEx.Partition.Mbr.CheckSum;
919  }
920  else
921  {
922  FdoExtension->DiskData.Gpt.DiskId = layoutEx->Gpt.DiskId;
923  }
924 
925  return STATUS_SUCCESS;
926 }
927 
928 static
929 CODE_SEG("PAGE")
930 NTSTATUS
933  _In_ PIRP Irp)
934 {
936  DEVICE_RELATION_TYPE type = ioStack->Parameters.QueryDeviceRelations.Type;
937 
938  PAGED_CODE();
939 
940  if (type == BusRelations)
941  {
943 
945  if (!NT_SUCCESS(status))
946  {
948  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
949  Irp->IoStatus.Information = 0;
951  return Irp->IoStatus.Status;
952  }
953 
954  INFO("Partition style %u\n", FdoExtension->DiskData.PartitionStyle);
955 
956  // PartMgrAcquireLayoutLock calls PartMgrGetDriveLayout inside
957  // so we're sure here that it returns only cached layout
958  PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
960 
962 
963  // now fill the DeviceRelations structure
964  TRACE("Reporting %u partitions\n", FdoExtension->EnumeratedPartitionsTotal);
965 
966  PDEVICE_RELATIONS deviceRelations =
968  sizeof(DEVICE_RELATIONS)
969  + sizeof(PDEVICE_OBJECT)
970  * (FdoExtension->EnumeratedPartitionsTotal - 1),
971  TAG_PARTMGR);
972 
973  if (!deviceRelations)
974  {
976  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
977  Irp->IoStatus.Information = 0;
979  return Irp->IoStatus.Status;
980  }
981 
982  deviceRelations->Count = 0;
983 
984  PSINGLE_LIST_ENTRY curEntry = FdoExtension->PartitionList.Next;
985  while (curEntry != NULL)
986  {
987  PPARTITION_EXTENSION partExt = CONTAINING_RECORD(curEntry,
989  ListEntry);
990 
991  // mark the PDO to know that we don't need to manually delete it
992  partExt->IsEnumerated = TRUE;
993  deviceRelations->Objects[deviceRelations->Count++] = partExt->DeviceObject;
995 
996  curEntry = partExt->ListEntry.Next;
997  }
998 
999  ASSERT(deviceRelations->Count == FdoExtension->EnumeratedPartitionsTotal);
1000 
1002 
1003  Irp->IoStatus.Information = (ULONG_PTR)deviceRelations;
1004  Irp->IoStatus.Status = STATUS_SUCCESS;
1005  }
1006 
1008  return IoCallDriver(FdoExtension->LowerDevice, Irp);
1009 }
1010 
1011 static
1012 CODE_SEG("PAGE")
1013 NTSTATUS
1016  _In_ PIRP Irp)
1017 {
1018  PAGED_CODE();
1019 
1020  if (FdoExtension->DiskInterfaceName.Buffer)
1021  {
1022  IoSetDeviceInterfaceState(&FdoExtension->DiskInterfaceName, FALSE);
1023  RtlFreeUnicodeString(&FdoExtension->DiskInterfaceName);
1024  RtlInitUnicodeString(&FdoExtension->DiskInterfaceName, NULL);
1025  }
1026 
1027  // Send the IRP down the stack
1029  Irp->IoStatus.Status = STATUS_SUCCESS;
1030  NTSTATUS status = IoCallDriver(FdoExtension->LowerDevice, Irp);
1031 
1032  IoDetachDevice(FdoExtension->LowerDevice);
1033  IoDeleteDevice(FdoExtension->DeviceObject);
1034  return status;
1035 }
1036 
1037 static
1038 CODE_SEG("PAGE")
1039 NTSTATUS
1042  _In_ PIRP Irp)
1043 {
1044  PAGED_CODE();
1045 
1046  // all enumerated child devices should receive IRP_MN_REMOVE_DEVICE
1047  // removing only non-enumerated ones here
1048  for (PSINGLE_LIST_ENTRY curEntry = FdoExtension->PartitionList.Next;
1049  curEntry != NULL;
1050  curEntry = curEntry->Next)
1051  {
1052  PPARTITION_EXTENSION partExt = CONTAINING_RECORD(curEntry,
1054  ListEntry);
1055 
1056  if (partExt->IsEnumerated)
1057  {
1058  PartitionHandleRemove(partExt, TRUE);
1059  }
1060  }
1061 
1062  // Send the IRP down the stack
1064  Irp->IoStatus.Status = STATUS_SUCCESS;
1065  return IoCallDriver(FdoExtension->LowerDevice, Irp);
1066 }
1067 
1068 static
1069 CODE_SEG("PAGE")
1070 NTSTATUS
1071 NTAPI
1075 {
1077 
1078  PAGED_CODE();
1079 
1081  sizeof(FDO_EXTENSION),
1082  0,
1085  FALSE,
1086  &deviceObject);
1087 
1088  if (!NT_SUCCESS(status))
1089  {
1090  ERR("Failed to create FDO 0x%x\n", status);
1091  return status;
1092  }
1093 
1094  PFDO_EXTENSION deviceExtension = deviceObject->DeviceExtension;
1095  RtlZeroMemory(deviceExtension, sizeof(*deviceExtension));
1096 
1097  deviceExtension->IsFDO = TRUE;
1098  deviceExtension->DeviceObject = deviceObject;
1100  deviceExtension->PhysicalDiskDO = PhysicalDeviceObject;
1102 
1103  // the the attaching failed
1104  if (!deviceExtension->LowerDevice)
1105  {
1107 
1108  return STATUS_DEVICE_REMOVED;
1109  }
1111 
1112  // device is initialized
1114 
1115  return STATUS_SUCCESS;
1116 }
1117 
1118 static
1119 NTSTATUS
1120 NTAPI
1123  _In_ PIRP Irp)
1124 {
1126  PFDO_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
1127  NTSTATUS status;
1128 
1129  // Note: IRP_MJ_DEVICE_CONTROL handler in the storage stack must be able to pass IOCTLs
1130  // at an IRQL higher than PASSIVE_LEVEL
1131 
1132  INFO("IRP_MJ_DEVICE_CONTROL %p Irp %p IOCTL %x isFdo: %u\n",
1133  DeviceObject, Irp, ioStack->Parameters.DeviceIoControl.IoControlCode, fdoExtension->IsFDO);
1134 
1135  if (!fdoExtension->IsFDO)
1136  {
1138  }
1139 
1140  switch (ioStack->Parameters.DeviceIoControl.IoControlCode)
1141  {
1143  status = FdoIoctlDiskGetDriveGeometryEx(fdoExtension, Irp);
1144  break;
1145 
1147  status = FdoIoctlDiskGetPartitionInfo(fdoExtension, Irp);
1148  break;
1149 
1151  status = FdoIoctlDiskGetPartitionInfoEx(fdoExtension, Irp);
1152  break;
1153 
1155  status = FdoIoctlDiskGetDriveLayout(fdoExtension, Irp);
1156  break;
1157 
1159  status = FdoIoctlDiskGetDriveLayoutEx(fdoExtension, Irp);
1160  break;
1161 
1163  status = FdoIoctlDiskSetDriveLayout(fdoExtension, Irp);
1164  break;
1165 
1167  status = FdoIoctlDiskSetDriveLayoutEx(fdoExtension, Irp);
1168  break;
1169 
1171  status = FdoIoctlDiskUpdateProperties(fdoExtension, Irp);
1172  break;
1173 
1175  status = FdoIoctlDiskCreateDisk(fdoExtension, Irp);
1176  break;
1177 
1179  status = FdoIoctlDiskDeleteDriveLayout(fdoExtension, Irp);
1180  break;
1181  // case IOCTL_DISK_GROW_PARTITION: // todo
1182  default:
1184  }
1185 
1186  Irp->IoStatus.Status = status;
1188  return status;
1189 }
1190 
1191 static
1192 CODE_SEG("PAGE")
1193 NTSTATUS
1194 NTAPI
1197  _In_ PIRP Irp)
1198 {
1199  PAGED_CODE();
1200 
1201  PFDO_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
1203 
1204  INFO("IRP_MJ_PNP %p Irp %p %s isFDO: %u\n",
1205  DeviceObject, Irp, GetIRPMinorFunctionString(ioStack->MinorFunction), fdoExtension->IsFDO);
1206 
1207  if (!fdoExtension->IsFDO)
1208  {
1210  }
1211 
1212  switch (ioStack->MinorFunction) {
1213 
1214  case IRP_MN_START_DEVICE:
1215  {
1216  NTSTATUS status;
1217 
1218  // if this is sent to the FDO so we should forward it down the
1219  // attachment chain before we can start the FDO
1220 
1221  if (!IoForwardIrpSynchronously(fdoExtension->LowerDevice, Irp))
1222  {
1224  }
1225  else
1226  {
1227  status = FdoHandleStartDevice(fdoExtension, Irp);
1228  }
1229 
1230  Irp->IoStatus.Status = status;
1232  return status;
1233  }
1235  {
1236  return FdoHandleDeviceRelations(fdoExtension, Irp);
1237  }
1239  {
1240  return FdoHandleSurpriseRemoval(fdoExtension, Irp);
1241  }
1242  case IRP_MN_REMOVE_DEVICE:
1243  {
1244  return FdoHandleRemoveDevice(fdoExtension, Irp);
1245  }
1250  case IRP_MN_STOP_DEVICE:
1251  {
1252  Irp->IoStatus.Status = STATUS_SUCCESS;
1253  // fallthrough
1254  }
1255  default:
1256  {
1258  return IoCallDriver(fdoExtension->LowerDevice, Irp);
1259  }
1260  }
1261 }
1262 
1263 static
1264 NTSTATUS
1265 NTAPI
1268  _In_ PIRP Irp)
1269 {
1270  PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
1272 
1273  if (!partExt->IsFDO)
1274  {
1275  if (!partExt->IsEnumerated)
1276  {
1277  Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
1280  }
1281  else
1282  {
1283  ioStack->Parameters.Read.ByteOffset.QuadPart += partExt->StartingOffset;
1284  }
1285  }
1286 
1288  return IoCallDriver(partExt->LowerDevice, Irp);
1289 }
1290 
1292 NTSTATUS
1293 NTAPI
1296  _In_ PIRP Irp)
1297 {
1298  PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
1300 
1302 
1303  if (!partExt->IsFDO)
1304  {
1305  NTSTATUS status;
1306 
1307  if (!partExt->IsEnumerated)
1308  {
1310  }
1311  else if (ioStack->MinorFunction == IRP_MN_SET_POWER ||
1312  ioStack->MinorFunction == IRP_MN_QUERY_POWER)
1313  {
1315  }
1316  else
1317  {
1318  status = Irp->IoStatus.Status;
1319  }
1320 
1321  Irp->IoStatus.Status = status;
1323  return status;
1324  }
1325  else
1326  {
1328  return PoCallDriver(partExt->LowerDevice, Irp);
1329  }
1330 }
1331 
1333 NTSTATUS
1334 NTAPI
1337  _In_ PIRP Irp)
1338 {
1339  PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
1340  PDEVICE_OBJECT lowerDevice;
1341 
1342  // forward to the partition0 device in both cases
1343  if (!partExt->IsFDO)
1344  {
1345  if (!partExt->IsEnumerated)
1346  {
1347  Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
1350  }
1351  else
1352  {
1353  PFDO_EXTENSION fdoExtension = partExt->LowerDevice->DeviceExtension;
1354  lowerDevice = fdoExtension->LowerDevice;
1355  }
1356  }
1357  else
1358  {
1359  lowerDevice = partExt->LowerDevice;
1360  }
1361 
1363  return IoCallDriver(lowerDevice, Irp);
1364 }
1365 
1366 CODE_SEG("PAGE")
1367 VOID
1368 NTAPI
1371 {
1372 
1373 }
1374 
1375 CODE_SEG("INIT")
1376 NTSTATUS
1377 NTAPI
1381 {
1382  DriverObject->DriverUnload = PartMgrUnload;
1383  DriverObject->DriverExtension->AddDevice = PartMgrAddDevice;
1385  DriverObject->MajorFunction[IRP_MJ_CLOSE] = ForwardIrpAndForget;
1386  DriverObject->MajorFunction[IRP_MJ_READ] = PartMgrReadWrite;
1387  DriverObject->MajorFunction[IRP_MJ_WRITE] = PartMgrReadWrite;
1389  DriverObject->MajorFunction[IRP_MJ_PNP] = PartMgrPnp;
1392  DriverObject->MajorFunction[IRP_MJ_POWER] = PartMgrPower;
1393 
1394  return STATUS_SUCCESS;
1395 }
#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:1040
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:1266
#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:1332
struct _PARTITION_INFORMATION PARTITION_INFORMATION
static NTSTATUS NTAPI PartMgrPnp(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partmgr.c:1195
static NTSTATUS FdoIoctlDiskGetDriveLayoutEx(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:535
struct _PARTITION_EXTENSION::@1267::@1269 Gpt
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:417
LARGE_INTEGER DiskSize
Definition: winioctl.h:331
static NTSTATUS FdoHandleStartDevice(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:829
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:1378
struct _PARTITION_INFORMATION_EX PARTITION_INFORMATION_EX
static NTSTATUS FdoIoctlDiskUpdateProperties(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:764
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:931
#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
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
struct _PARTITION_EXTENSION::@1267::@1270 Mbr
#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:1014
GLsizeiptr size
Definition: glext.h:5919
static NTSTATUS FdoIoctlDiskDeleteDriveLayout(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:807
#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:882
static NTSTATUS FdoIoctlDiskSetDriveLayout(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:571
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:452
#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:1072
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
DRIVER_DISPATCH PartMgrPower
Definition: partmgr.c:1291
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:318
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:1369
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:482
#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:781
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:354
#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:460
#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
#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:655
static NTSTATUS NTAPI PartMgrDeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partmgr.c:1121
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define PAGED_CODE()
Definition: ps.c:97