ReactOS  0.4.15-dev-1636-gf634010
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  for (PSINGLE_LIST_ENTRY curEntry = FdoExtension->PartitionList.Next;
1021  curEntry != NULL;
1022  curEntry = curEntry->Next)
1023  {
1024  PPARTITION_EXTENSION partExt = CONTAINING_RECORD(curEntry,
1026  ListEntry);
1027 
1028  ASSERT(partExt->DeviceRemoved);
1029  }
1030 
1031  if (FdoExtension->DiskInterfaceName.Buffer)
1032  {
1033  IoSetDeviceInterfaceState(&FdoExtension->DiskInterfaceName, FALSE);
1034  RtlFreeUnicodeString(&FdoExtension->DiskInterfaceName);
1035  RtlInitUnicodeString(&FdoExtension->DiskInterfaceName, NULL);
1036  }
1037 
1038  // Send the IRP down the stack
1040  Irp->IoStatus.Status = STATUS_SUCCESS;
1041  NTSTATUS status = IoCallDriver(FdoExtension->LowerDevice, Irp);
1042 
1043  IoDetachDevice(FdoExtension->LowerDevice);
1044  IoDeleteDevice(FdoExtension->DeviceObject);
1045  return status;
1046 }
1047 
1048 static
1049 CODE_SEG("PAGE")
1050 NTSTATUS
1053  _In_ PIRP Irp)
1054 {
1055  PAGED_CODE();
1056 
1057  // all enumerated child devices should receive IRP_MN_REMOVE_DEVICE
1058  // removing only non-enumerated ones here
1059  for (PSINGLE_LIST_ENTRY curEntry = FdoExtension->PartitionList.Next;
1060  curEntry != NULL;
1061  curEntry = curEntry->Next)
1062  {
1063  PPARTITION_EXTENSION partExt = CONTAINING_RECORD(curEntry,
1065  ListEntry);
1066 
1067  if (partExt->IsEnumerated)
1068  {
1069  PartitionHandleRemove(partExt, TRUE);
1070  }
1071  }
1072 
1073  // Send the IRP down the stack
1075  Irp->IoStatus.Status = STATUS_SUCCESS;
1076  return IoCallDriver(FdoExtension->LowerDevice, Irp);
1077 }
1078 
1079 static
1080 CODE_SEG("PAGE")
1081 NTSTATUS
1082 NTAPI
1086 {
1088 
1089  PAGED_CODE();
1090 
1092  sizeof(FDO_EXTENSION),
1093  0,
1096  FALSE,
1097  &deviceObject);
1098 
1099  if (!NT_SUCCESS(status))
1100  {
1101  ERR("Failed to create FDO 0x%x\n", status);
1102  return status;
1103  }
1104 
1105  PFDO_EXTENSION deviceExtension = deviceObject->DeviceExtension;
1106  RtlZeroMemory(deviceExtension, sizeof(*deviceExtension));
1107 
1108  deviceExtension->IsFDO = TRUE;
1109  deviceExtension->DeviceObject = deviceObject;
1111  deviceExtension->PhysicalDiskDO = PhysicalDeviceObject;
1113 
1114  // the the attaching failed
1115  if (!deviceExtension->LowerDevice)
1116  {
1118 
1119  return STATUS_DEVICE_REMOVED;
1120  }
1122 
1123  // device is initialized
1125 
1126  return STATUS_SUCCESS;
1127 }
1128 
1129 static
1130 NTSTATUS
1131 NTAPI
1134  _In_ PIRP Irp)
1135 {
1137  PFDO_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
1138  NTSTATUS status;
1139 
1140  // Note: IRP_MJ_DEVICE_CONTROL handler in the storage stack must be able to pass IOCTLs
1141  // at an IRQL higher than PASSIVE_LEVEL
1142 
1143  INFO("IRP_MJ_DEVICE_CONTROL %p Irp %p IOCTL %x isFdo: %u\n",
1144  DeviceObject, Irp, ioStack->Parameters.DeviceIoControl.IoControlCode, fdoExtension->IsFDO);
1145 
1146  if (!fdoExtension->IsFDO)
1147  {
1149  }
1150 
1151  switch (ioStack->Parameters.DeviceIoControl.IoControlCode)
1152  {
1154  status = FdoIoctlDiskGetDriveGeometryEx(fdoExtension, Irp);
1155  break;
1156 
1158  status = FdoIoctlDiskGetPartitionInfo(fdoExtension, Irp);
1159  break;
1160 
1162  status = FdoIoctlDiskGetPartitionInfoEx(fdoExtension, Irp);
1163  break;
1164 
1166  status = FdoIoctlDiskGetDriveLayout(fdoExtension, Irp);
1167  break;
1168 
1170  status = FdoIoctlDiskGetDriveLayoutEx(fdoExtension, Irp);
1171  break;
1172 
1174  status = FdoIoctlDiskSetDriveLayout(fdoExtension, Irp);
1175  break;
1176 
1178  status = FdoIoctlDiskSetDriveLayoutEx(fdoExtension, Irp);
1179  break;
1180 
1182  status = FdoIoctlDiskUpdateProperties(fdoExtension, Irp);
1183  break;
1184 
1186  status = FdoIoctlDiskCreateDisk(fdoExtension, Irp);
1187  break;
1188 
1190  status = FdoIoctlDiskDeleteDriveLayout(fdoExtension, Irp);
1191  break;
1192  // case IOCTL_DISK_GROW_PARTITION: // todo
1193  default:
1195  }
1196 
1197  Irp->IoStatus.Status = status;
1199  return status;
1200 }
1201 
1202 static
1203 CODE_SEG("PAGE")
1204 NTSTATUS
1205 NTAPI
1208  _In_ PIRP Irp)
1209 {
1210  PAGED_CODE();
1211 
1212  PFDO_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
1214 
1215  INFO("IRP_MJ_PNP %p Irp %p %s isFDO: %u\n",
1216  DeviceObject, Irp, GetIRPMinorFunctionString(ioStack->MinorFunction), fdoExtension->IsFDO);
1217 
1218  if (!fdoExtension->IsFDO)
1219  {
1221  }
1222 
1223  switch (ioStack->MinorFunction) {
1224 
1225  case IRP_MN_START_DEVICE:
1226  {
1227  NTSTATUS status;
1228 
1229  // if this is sent to the FDO so we should forward it down the
1230  // attachment chain before we can start the FDO
1231 
1232  if (!IoForwardIrpSynchronously(fdoExtension->LowerDevice, Irp))
1233  {
1235  }
1236  else
1237  {
1238  status = FdoHandleStartDevice(fdoExtension, Irp);
1239  }
1240 
1241  Irp->IoStatus.Status = status;
1243  return status;
1244  }
1246  {
1247  return FdoHandleDeviceRelations(fdoExtension, Irp);
1248  }
1250  {
1251  return FdoHandleSurpriseRemoval(fdoExtension, Irp);
1252  }
1253  case IRP_MN_REMOVE_DEVICE:
1254  {
1255  return FdoHandleRemoveDevice(fdoExtension, Irp);
1256  }
1261  case IRP_MN_STOP_DEVICE:
1262  {
1263  Irp->IoStatus.Status = STATUS_SUCCESS;
1264  // fallthrough
1265  }
1266  default:
1267  {
1269  return IoCallDriver(fdoExtension->LowerDevice, Irp);
1270  }
1271  }
1272 }
1273 
1274 static
1275 NTSTATUS
1276 NTAPI
1279  _In_ PIRP Irp)
1280 {
1281  PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
1283 
1284  if (!partExt->IsFDO)
1285  {
1286  if (!partExt->IsEnumerated)
1287  {
1288  Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
1291  }
1292  else
1293  {
1294  ioStack->Parameters.Read.ByteOffset.QuadPart += partExt->StartingOffset;
1295  }
1296  }
1297 
1299  return IoCallDriver(partExt->LowerDevice, Irp);
1300 }
1301 
1303 NTSTATUS
1304 NTAPI
1307  _In_ PIRP Irp)
1308 {
1309  PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
1311 
1313 
1314  if (!partExt->IsFDO)
1315  {
1316  NTSTATUS status;
1317 
1318  if (!partExt->IsEnumerated)
1319  {
1321  }
1322  else if (ioStack->MinorFunction == IRP_MN_SET_POWER ||
1323  ioStack->MinorFunction == IRP_MN_QUERY_POWER)
1324  {
1326  }
1327  else
1328  {
1329  status = Irp->IoStatus.Status;
1330  }
1331 
1332  Irp->IoStatus.Status = status;
1334  return status;
1335  }
1336  else
1337  {
1339  return PoCallDriver(partExt->LowerDevice, Irp);
1340  }
1341 }
1342 
1344 NTSTATUS
1345 NTAPI
1348  _In_ PIRP Irp)
1349 {
1350  PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
1351  PDEVICE_OBJECT lowerDevice;
1352 
1353  // forward to the partition0 device in both cases
1354  if (!partExt->IsFDO)
1355  {
1356  if (!partExt->IsEnumerated)
1357  {
1358  Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
1361  }
1362  else
1363  {
1364  PFDO_EXTENSION fdoExtension = partExt->LowerDevice->DeviceExtension;
1365  lowerDevice = fdoExtension->LowerDevice;
1366  }
1367  }
1368  else
1369  {
1370  lowerDevice = partExt->LowerDevice;
1371  }
1372 
1374  return IoCallDriver(lowerDevice, Irp);
1375 }
1376 
1377 CODE_SEG("PAGE")
1378 VOID
1379 NTAPI
1382 {
1383 
1384 }
1385 
1386 CODE_SEG("INIT")
1387 NTSTATUS
1388 NTAPI
1392 {
1393  DriverObject->DriverUnload = PartMgrUnload;
1394  DriverObject->DriverExtension->AddDevice = PartMgrAddDevice;
1396  DriverObject->MajorFunction[IRP_MJ_CLOSE] = ForwardIrpAndForget;
1397  DriverObject->MajorFunction[IRP_MJ_READ] = PartMgrReadWrite;
1398  DriverObject->MajorFunction[IRP_MJ_WRITE] = PartMgrReadWrite;
1400  DriverObject->MajorFunction[IRP_MJ_PNP] = PartMgrPnp;
1403  DriverObject->MajorFunction[IRP_MJ_POWER] = PartMgrPower;
1404 
1405  return STATUS_SUCCESS;
1406 }
#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 IRP_MJ_FLUSH_BUFFERS
#define IRP_MN_QUERY_POWER
Definition: ntbasedef.h:628
struct _PARTITION_EXTENSION::@1303::@1305 Gpt
#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:2160
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:1051
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:1277
#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:409
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1155
DRIVER_DISPATCH PartMgrShutdownFlush
Definition: partmgr.c:1343
struct _PARTITION_INFORMATION PARTITION_INFORMATION
static NTSTATUS NTAPI PartMgrPnp(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partmgr.c:1206
static NTSTATUS FdoIoctlDiskGetDriveLayoutEx(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:535
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:473
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:1389
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:81
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 _Out_
Definition: no_sal2.h:160
#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:145
#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:45
#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
BOOLEAN DeviceRemoved
Definition: partmgr.h:80
#define IRP_MN_START_DEVICE
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
LARGE_INTEGER PartitionLength
Definition: imports.h:222
#define _Inout_
Definition: no_sal2.h:162
CODE_SEG("INIT")
Definition: fsrtlpc.c:19
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:2271
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:1083
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:2458
FORCEINLINE BOOLEAN VerifyIrpInBufferSize(_In_ PIRP Irp, _In_ SIZE_T Size)
Definition: partmgr.h:160
DRIVER_DISPATCH(nfs41_FsdDispatch)
MxDeviceObject deviceObject
struct _PARTITION_EXTENSION::@1303::@1306 Mbr
DRIVER_DISPATCH PartMgrPower
Definition: partmgr.c:1302
FORCEINLINE VOID PartMgrReleaseLayoutLock(_In_ PFDO_EXTENSION FDOExtension)
Definition: partmgr.h:185
#define IOCTL_DISK_GET_DRIVE_LAYOUT
Definition: ntdddisk.h:91
#define ERR(fmt,...)
Definition: debug.h:110
#define _In_
Definition: no_sal2.h:158
FORCEINLINE PCHAR GetIRPMinorFunctionString(UCHAR MinorFunction)
Definition: driverdbg.h:13
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
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:2419
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:737
#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:1380
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:182
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
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3124
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:510
FORCEINLINE VOID PartMgrAcquireLayoutLock(_In_ PFDO_EXTENSION FDOExtension)
Definition: partmgr.h:175
static SERVICE_STATUS status
Definition: service.c:31
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:1132
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define PAGED_CODE()
Definition: ps.c:97