ReactOS 0.4.15-dev-8219-ge8b88cf
partition.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: Partition device code
5 * COPYRIGHT: 2020 Victor Perevertkin (victor.perevertkin@reactos.org)
6 */
7
8#include "partmgr.h"
9
10static const WCHAR PartitionSymLinkFormat[] = L"\\Device\\Harddisk%lu\\Partition%lu";
11
12
13CODE_SEG("PAGE")
16 _In_ PDEVICE_OBJECT FDObject,
17 _In_ PPARTITION_INFORMATION_EX PartitionEntry,
18 _In_ UINT32 PdoNumber,
19 _In_ PARTITION_STYLE PartitionStyle,
21{
22 PAGED_CODE();
23
24 static UINT32 HarddiskVolumeNextId = 1; // this is 1-based
25
26 WCHAR nameBuf[64];
27 UNICODE_STRING deviceName;
28 UINT32 volumeNum;
29
30 // create the device object
31
32 volumeNum = HarddiskVolumeNextId++;
33 swprintf(nameBuf, L"\\Device\\HarddiskVolume%lu", volumeNum);
34 RtlCreateUnicodeString(&deviceName, nameBuf);
35
36 PDEVICE_OBJECT partitionDevice;
37 NTSTATUS status = IoCreateDevice(FDObject->DriverObject,
38 sizeof(PARTITION_EXTENSION),
39 &deviceName,
42 FALSE,
43 &partitionDevice);
44
45 if (!NT_SUCCESS(status))
46 {
47 ERR("Unable to create device object %wZ\n", &deviceName);
48 return status;
49 }
50
51 INFO("Created device object %p %wZ\n", partitionDevice, &deviceName);
52
53 PPARTITION_EXTENSION partExt = partitionDevice->DeviceExtension;
54 RtlZeroMemory(partExt, sizeof(*partExt));
55
56 partitionDevice->StackSize = FDObject->StackSize;
57 partitionDevice->Flags |= DO_DIRECT_IO;
58
59 if (PartitionStyle == PARTITION_STYLE_MBR)
60 {
61 partExt->Mbr.PartitionType = PartitionEntry->Mbr.PartitionType;
62 partExt->Mbr.BootIndicator = PartitionEntry->Mbr.BootIndicator;
63 partExt->Mbr.HiddenSectors = PartitionEntry->Mbr.HiddenSectors;
64 }
65 else
66 {
67 partExt->Gpt.PartitionType = PartitionEntry->Gpt.PartitionType;
68 partExt->Gpt.PartitionId = PartitionEntry->Gpt.PartitionId;
69 partExt->Gpt.Attributes = PartitionEntry->Gpt.Attributes;
70
71 RtlCopyMemory(partExt->Gpt.Name, PartitionEntry->Gpt.Name, sizeof(partExt->Gpt.Name));
72 }
73
74 partExt->DeviceName = deviceName;
75 partExt->StartingOffset = PartitionEntry->StartingOffset.QuadPart;
76 partExt->PartitionLength = PartitionEntry->PartitionLength.QuadPart;
77 partExt->OnDiskNumber = PartitionEntry->PartitionNumber; // the "physical" partition number
78 partExt->DetectedNumber = PdoNumber; // counts only partitions with PDO created
79 partExt->VolumeNumber = volumeNum;
80
81 partExt->DeviceObject = partitionDevice;
82 partExt->LowerDevice = FDObject;
83
84 partitionDevice->Flags &= ~DO_DEVICE_INITIALIZING;
85
86 *PDO = partitionDevice;
87
88 return status;
89}
90
91static
92CODE_SEG("PAGE")
97{
98 PAGED_CODE();
99
100 // first, create a symbolic link for our device
101 WCHAR nameBuf[64];
102 UNICODE_STRING partitionSymlink, interfaceName;
103 PFDO_EXTENSION fdoExtension = PartExt->LowerDevice->DeviceExtension;
104
105 // \\Device\\Harddisk%lu\\Partition%lu
107 fdoExtension->DiskData.DeviceNumber, PartExt->DetectedNumber);
108
109 if (!RtlCreateUnicodeString(&partitionSymlink, nameBuf))
110 {
112 }
113
114 NTSTATUS status = IoCreateSymbolicLink(&partitionSymlink, &PartExt->DeviceName);
115
116 if (!NT_SUCCESS(status))
117 {
118 return status;
119 }
120
121 PartExt->SymlinkCreated = TRUE;
122
123 INFO("Symlink created %wZ -> %wZ\n", &partitionSymlink, &PartExt->DeviceName);
124
125 // our partition device will have two interfaces:
126 // GUID_DEVINTERFACE_PARTITION and GUID_DEVINTERFACE_VOLUME
127 // the former one is used to notify mountmgr about new device
128
129 status = IoRegisterDeviceInterface(PartExt->DeviceObject,
130 &GUID_DEVINTERFACE_PARTITION,
131 NULL,
132 &interfaceName);
133
134 if (!NT_SUCCESS(status))
135 {
136 return status;
137 }
138
139 PartExt->PartitionInterfaceName = interfaceName;
140 status = IoSetDeviceInterfaceState(&interfaceName, TRUE);
141
142 INFO("Partition interface %wZ\n", &interfaceName);
143
144 if (!NT_SUCCESS(status))
145 {
146 RtlFreeUnicodeString(&interfaceName);
147 RtlInitUnicodeString(&PartExt->PartitionInterfaceName, NULL);
148 return status;
149 }
150
151 status = IoRegisterDeviceInterface(PartExt->DeviceObject,
152 &GUID_DEVINTERFACE_VOLUME,
153 NULL,
154 &interfaceName);
155
156 if (!NT_SUCCESS(status))
157 {
158 return status;
159 }
160
161 PartExt->VolumeInterfaceName = interfaceName;
162 status = IoSetDeviceInterfaceState(&interfaceName, TRUE);
163
164 INFO("Volume interface %wZ\n", &interfaceName);
165
166 if (!NT_SUCCESS(status))
167 {
168 RtlFreeUnicodeString(&interfaceName);
169 RtlInitUnicodeString(&PartExt->VolumeInterfaceName, NULL);
170 return status;
171 }
172
173 return STATUS_SUCCESS;
174}
175
176CODE_SEG("PAGE")
180 _In_ BOOLEAN FinalRemove)
181{
183
184 PAGED_CODE();
185
186 // remove the symbolic link
187 if (PartExt->SymlinkCreated)
188 {
189 WCHAR nameBuf[64];
190 UNICODE_STRING partitionSymlink;
191 PFDO_EXTENSION fdoExtension = PartExt->LowerDevice->DeviceExtension;
192
194 fdoExtension->DiskData.DeviceNumber, PartExt->DetectedNumber);
195
196 RtlInitUnicodeString(&partitionSymlink, nameBuf);
197
198 status = IoDeleteSymbolicLink(&partitionSymlink);
199
200 if (!NT_SUCCESS(status))
201 {
202 return status;
203 }
204 PartExt->SymlinkCreated = FALSE;
205
206 INFO("Symlink removed %wZ -> %wZ\n", &partitionSymlink, &PartExt->DeviceName);
207 }
208
209 // release device interfaces
210 if (PartExt->PartitionInterfaceName.Buffer)
211 {
212 status = IoSetDeviceInterfaceState(&PartExt->PartitionInterfaceName, FALSE);
213 if (!NT_SUCCESS(status))
214 {
215 return status;
216 }
217 RtlFreeUnicodeString(&PartExt->PartitionInterfaceName);
218 RtlInitUnicodeString(&PartExt->PartitionInterfaceName, NULL);
219 }
220
221 if (PartExt->VolumeInterfaceName.Buffer)
222 {
223 status = IoSetDeviceInterfaceState(&PartExt->VolumeInterfaceName, FALSE);
224 if (!NT_SUCCESS(status))
225 {
226 return status;
227 }
228 RtlFreeUnicodeString(&PartExt->VolumeInterfaceName);
229 RtlInitUnicodeString(&PartExt->VolumeInterfaceName, NULL);
230 }
231
232 if (FinalRemove)
233 {
234 ASSERT(PartExt->DeviceName.Buffer);
235 if (PartExt->DeviceName.Buffer)
236 {
237 INFO("Removed device %wZ\n", &PartExt->DeviceName);
238 RtlFreeUnicodeString(&PartExt->DeviceName);
239 }
240
241 IoDeleteDevice(PartExt->DeviceObject);
242 }
243
244 return STATUS_SUCCESS;
245}
246
247static
248CODE_SEG("PAGE")
252 _In_ PIRP Irp)
253{
254 PAGED_CODE();
255
258
260 {
261 // Device relations have one entry built into their size.
262 PDEVICE_RELATIONS deviceRelations =
263 ExAllocatePoolZero(PagedPool, sizeof(DEVICE_RELATIONS), TAG_PARTMGR);
264
265 if (deviceRelations != NULL)
266 {
267 deviceRelations->Count = 1;
268 deviceRelations->Objects[0] = PartExt->DeviceObject;
269 ObReferenceObject(deviceRelations->Objects[0]);
270
271 Irp->IoStatus.Information = (ULONG_PTR)deviceRelations;
272 return STATUS_SUCCESS;
273 }
274 else
275 {
277 }
278 }
279 else
280 {
281 Irp->IoStatus.Information = 0;
282 return Irp->IoStatus.Status;
283 }
284}
285
286static
287CODE_SEG("PAGE")
291 _In_ PIRP Irp)
292{
294 BUS_QUERY_ID_TYPE idType = ioStack->Parameters.QueryId.IdType;
295 UNICODE_STRING idString;
297
298 PAGED_CODE();
299
300 switch (idType)
301 {
302 case BusQueryDeviceID:
303 status = RtlCreateUnicodeString(&idString, L"STORAGE\\Partition")
305 break;
307 {
308 static WCHAR volumeID[] = L"STORAGE\\Volume\0";
309
310 idString.Buffer = ExAllocatePoolWithTag(PagedPool, sizeof(volumeID), TAG_PARTMGR);
311 RtlCopyMemory(idString.Buffer, volumeID, sizeof(volumeID));
312
314 break;
315 }
317 {
318 WCHAR string[64];
319 PFDO_EXTENSION fdoExtension = PartExt->LowerDevice->DeviceExtension;
320
321 PartMgrAcquireLayoutLock(fdoExtension);
322
323 if (fdoExtension->DiskData.PartitionStyle == PARTITION_STYLE_MBR)
324 {
325 swprintf(string, L"S%08lx_O%I64x_L%I64x",
326 fdoExtension->DiskData.Mbr.Signature,
327 PartExt->StartingOffset,
328 PartExt->PartitionLength);
329 }
330 else
331 {
332 swprintf(string,
333 L"S%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02xS_O%I64x_L%I64x",
334 fdoExtension->DiskData.Gpt.DiskId.Data1,
335 fdoExtension->DiskData.Gpt.DiskId.Data2,
336 fdoExtension->DiskData.Gpt.DiskId.Data3,
337 fdoExtension->DiskData.Gpt.DiskId.Data4[0],
338 fdoExtension->DiskData.Gpt.DiskId.Data4[1],
339 fdoExtension->DiskData.Gpt.DiskId.Data4[2],
340 fdoExtension->DiskData.Gpt.DiskId.Data4[3],
341 fdoExtension->DiskData.Gpt.DiskId.Data4[4],
342 fdoExtension->DiskData.Gpt.DiskId.Data4[5],
343 fdoExtension->DiskData.Gpt.DiskId.Data4[6],
344 fdoExtension->DiskData.Gpt.DiskId.Data4[7],
345 PartExt->StartingOffset,
346 PartExt->PartitionLength);
347 }
348
349 PartMgrReleaseLayoutLock(fdoExtension);
350
351 status = RtlCreateUnicodeString(&idString, string)
353 break;
354 }
355 default:
357 break;
358 }
359
360 Irp->IoStatus.Information = NT_SUCCESS(status) ? (ULONG_PTR) idString.Buffer : 0;
361 return status;
362}
363
364static
365CODE_SEG("PAGE")
369 _In_ PIRP Irp)
370{
372 PDEVICE_CAPABILITIES devCaps = ioStack->Parameters.DeviceCapabilities.Capabilities;
373
374 PAGED_CODE();
375 ASSERT(devCaps);
376
377 devCaps->SilentInstall = TRUE;
378 devCaps->RawDeviceOK = TRUE;
379 devCaps->NoDisplayInUI = TRUE;
380 devCaps->Address = PartExt->OnDiskNumber;
381 devCaps->UniqueID = FALSE;
382
383 return STATUS_SUCCESS;
384}
385
386CODE_SEG("PAGE")
390 _In_ PIRP Irp)
391{
392 PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
395
396 PAGED_CODE();
397
398 switch (ioStack->MinorFunction)
399 {
401 {
403 break;
404 }
406 {
408 break;
409 }
415 {
417 break;
418 }
420 {
422 break;
423 }
425 {
427 break;
428 }
429 case IRP_MN_QUERY_ID:
430 {
432 break;
433 }
435 {
437 break;
438 }
439 default:
440 {
441 Irp->IoStatus.Information = 0;
443 }
444 }
445
446 Irp->IoStatus.Status = status;
448 return status;
449}
450
454 _In_ PIRP Irp)
455{
457 PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
458 PFDO_EXTENSION fdoExtension = partExt->LowerDevice->DeviceExtension;
460
461 ASSERT(!partExt->IsFDO);
462
463 if (!partExt->IsEnumerated)
464 {
465 Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
468 }
469
470 switch (ioStack->Parameters.DeviceIoControl.IoControlCode)
471 {
472 // disk stuff
474 {
476 {
478 break;
479 }
480
481 PartMgrAcquireLayoutLock(fdoExtension);
482
483 // not supported on anything other than MBR
484 if (fdoExtension->DiskData.PartitionStyle != PARTITION_STYLE_MBR)
485 {
487 PartMgrReleaseLayoutLock(fdoExtension);
488 break;
489 }
490
491 PPARTITION_INFORMATION partInfo = Irp->AssociatedIrp.SystemBuffer;
492
493 *partInfo = (PARTITION_INFORMATION){
494 .PartitionType = partExt->Mbr.PartitionType,
495 .StartingOffset.QuadPart = partExt->StartingOffset,
496 .PartitionLength.QuadPart = partExt->PartitionLength,
497 .HiddenSectors = partExt->Mbr.HiddenSectors,
498 .PartitionNumber = partExt->DetectedNumber,
499 .BootIndicator = partExt->Mbr.BootIndicator,
500 .RecognizedPartition = partExt->Mbr.RecognizedPartition,
501 .RewritePartition = FALSE,
502 };
503
504 PartMgrReleaseLayoutLock(fdoExtension);
505
506 Irp->IoStatus.Information = sizeof(*partInfo);
508 break;
509 }
511 {
513 {
515 break;
516 }
517
518 PPARTITION_INFORMATION_EX partInfoEx = Irp->AssociatedIrp.SystemBuffer;
519
520 PartMgrAcquireLayoutLock(fdoExtension);
521
522 *partInfoEx = (PARTITION_INFORMATION_EX){
524 .PartitionLength.QuadPart = partExt->PartitionLength,
525 .PartitionNumber = partExt->DetectedNumber,
526 .PartitionStyle = fdoExtension->DiskData.PartitionStyle,
527 .RewritePartition = FALSE,
528 };
529
530 if (fdoExtension->DiskData.PartitionStyle == PARTITION_STYLE_MBR)
531 {
532 partInfoEx->Mbr = (PARTITION_INFORMATION_MBR){
533 .PartitionType = partExt->Mbr.PartitionType,
534 .HiddenSectors = partExt->Mbr.HiddenSectors,
535 .BootIndicator = partExt->Mbr.BootIndicator,
536 .RecognizedPartition = partExt->Mbr.RecognizedPartition,
537 };
538 }
539 else
540 {
541 partInfoEx->Gpt = (PARTITION_INFORMATION_GPT){
542 .PartitionType = partExt->Gpt.PartitionType,
543 .PartitionId = partExt->Gpt.PartitionId,
544 .Attributes = partExt->Gpt.Attributes,
545 };
546
547 RtlCopyMemory(partInfoEx->Gpt.Name,
548 partExt->Gpt.Name,
549 sizeof(partInfoEx->Gpt.Name));
550 }
551
552 PartMgrReleaseLayoutLock(fdoExtension);
553
554 Irp->IoStatus.Information = sizeof(*partInfoEx);
556 break;
557 }
559 {
560 PSET_PARTITION_INFORMATION inputBuffer = Irp->AssociatedIrp.SystemBuffer;
561 if (!VerifyIrpInBufferSize(Irp, sizeof(*inputBuffer)))
562 {
564 break;
565 }
566
567 PartMgrAcquireLayoutLock(fdoExtension);
568
569 // these functions use on disk numbers, not detected ones
571 fdoExtension->DiskData.BytesPerSector,
572 partExt->OnDiskNumber,
573 inputBuffer->PartitionType);
574
575 if (NT_SUCCESS(status))
576 {
577 partExt->Mbr.PartitionType = inputBuffer->PartitionType;
578 }
579
580 PartMgrReleaseLayoutLock(fdoExtension);
581
582 Irp->IoStatus.Information = 0;
583 break;
584 }
586 {
587 PSET_PARTITION_INFORMATION_EX inputBuffer = Irp->AssociatedIrp.SystemBuffer;
588 if (!VerifyIrpInBufferSize(Irp, sizeof(*inputBuffer)))
589 {
591 break;
592 }
593
594 PartMgrAcquireLayoutLock(fdoExtension);
595
596 // these functions use on disk numbers, not detected ones
598 partExt->OnDiskNumber,
599 inputBuffer);
600
601 if (NT_SUCCESS(status))
602 {
603 if (fdoExtension->DiskData.PartitionStyle == PARTITION_STYLE_MBR)
604 {
605 partExt->Mbr.PartitionType = inputBuffer->Mbr.PartitionType;
606 }
607 else
608 {
609 partExt->Gpt.PartitionType = inputBuffer->Gpt.PartitionType;
610 partExt->Gpt.PartitionId = inputBuffer->Gpt.PartitionId;
611 partExt->Gpt.Attributes = inputBuffer->Gpt.Attributes;
612
613 RtlMoveMemory(partExt->Gpt.Name,
614 inputBuffer->Gpt.Name,
615 sizeof(partExt->Gpt.Name));
616 }
617 }
618
619 PartMgrReleaseLayoutLock(fdoExtension);
620
621 Irp->IoStatus.Information = 0;
622 break;
623 }
625 {
626 PGET_LENGTH_INFORMATION lengthInfo = Irp->AssociatedIrp.SystemBuffer;
627 if (!VerifyIrpOutBufferSize(Irp, sizeof(*lengthInfo)))
628 {
630 break;
631 }
632
633 PartMgrAcquireLayoutLock(fdoExtension);
634
635 lengthInfo->Length.QuadPart = partExt->PartitionLength;
636
637 PartMgrReleaseLayoutLock(fdoExtension);
638
640 Irp->IoStatus.Information = sizeof(*lengthInfo);
641 break;
642 }
644 {
645 PVERIFY_INFORMATION verifyInfo = Irp->AssociatedIrp.SystemBuffer;
646 if (!VerifyIrpInBufferSize(Irp, sizeof(*verifyInfo)))
647 {
649 break;
650 }
651
652 // Partition device should just adjust the starting offset
653 verifyInfo->StartingOffset.QuadPart += partExt->StartingOffset;
655 }
657 {
658 fdoExtension->LayoutValid = FALSE;
660
662 break;
663 }
665 {
667 }
668 // volume stuff (most of that should be in volmgr.sys once it is implemented)
670 {
671 PVOLUME_DISK_EXTENTS volExts = Irp->AssociatedIrp.SystemBuffer;
672
673 // we fill only one extent entry so sizeof(*volExts) is enough
674 if (!VerifyIrpOutBufferSize(Irp, sizeof(*volExts)))
675 {
677 break;
678 }
679
680 PartMgrAcquireLayoutLock(fdoExtension);
681
682 // the only type of volume we support right now is disk partition
683 // so this structure is simple
684
685 *volExts = (VOLUME_DISK_EXTENTS) {
687 .Extents = {{
688 .DiskNumber = fdoExtension->DiskData.DeviceNumber,
689 .StartingOffset.QuadPart = partExt->StartingOffset,
690 .ExtentLength.QuadPart = partExt->PartitionLength
691 }}
692 };
693
694 PartMgrReleaseLayoutLock(fdoExtension);
695
697 Irp->IoStatus.Information = sizeof(*volExts);
698 break;
699 }
701 {
702 PVOLUME_NUMBER volNum = Irp->AssociatedIrp.SystemBuffer;
703 if (!VerifyIrpOutBufferSize(Irp, sizeof(*volNum)))
704 {
706 break;
707 }
708
709 PartMgrAcquireLayoutLock(fdoExtension);
710
711 volNum->VolumeNumber = partExt->VolumeNumber;
713 L"VOLMGR ", // Must be 8 space-padded characters
714 sizeof(volNum->VolumeManagerName));
715
716 PartMgrReleaseLayoutLock(fdoExtension);
717
719 Irp->IoStatus.Information = sizeof(*volNum);
720 break;
721 }
723 {
724 // The only type of volume we support right now is disk partition
725 // so we just return success. A more robust algorithm would be
726 // to check whether the volume has only one single extent, that
727 // covers the whole partition on which it lies upon. If this is
728 // not the case, return STATUS_UNSUCCESSFUL instead.
730 break;
731 }
733 {
735 break;
736 }
738 {
739 PVOLUME_GET_GPT_ATTRIBUTES_INFORMATION gptAttrs = Irp->AssociatedIrp.SystemBuffer;
740 if (!VerifyIrpOutBufferSize(Irp, sizeof(*gptAttrs)))
741 {
743 break;
744 }
745
746 // not supported on anything other than GPT
747 if (fdoExtension->DiskData.PartitionStyle != PARTITION_STYLE_GPT)
748 {
750 break;
751 }
752
753 gptAttrs->GptAttributes = partExt->Gpt.Attributes;
754
756 Irp->IoStatus.Information = sizeof(*gptAttrs);
757 break;
758 }
759 // mountmgr notifications (these should be in volmgr.sys once it is implemented)
761 {
762 PMOUNTDEV_NAME name = Irp->AssociatedIrp.SystemBuffer;
763
764 if (!VerifyIrpOutBufferSize(Irp, sizeof(USHORT)))
765 {
767 break;
768 }
769
770 name->NameLength = partExt->DeviceName.Length;
771
772 // return NameLength back
773 if (!VerifyIrpOutBufferSize(Irp, sizeof(USHORT) + name->NameLength))
774 {
775 Irp->IoStatus.Information = sizeof(USHORT);
777 break;
778 }
779
780 RtlCopyMemory(name->Name, partExt->DeviceName.Buffer, name->NameLength);
781
783 Irp->IoStatus.Information = sizeof(USHORT) + name->NameLength;
784 break;
785 }
787 {
788 const SIZE_T headerSize = FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId);
789 PMOUNTDEV_UNIQUE_ID uniqueId = Irp->AssociatedIrp.SystemBuffer;
791 PUNICODE_STRING InterfaceName;
792
793 // Check whether the minimal header size was provided
794 if (!VerifyIrpOutBufferSize(Irp, headerSize))
795 {
797 break;
798 }
799
800 PartMgrAcquireLayoutLock(fdoExtension);
801
802 InterfaceName = &partExt->VolumeInterfaceName;
803 if (fdoExtension->IsSuperFloppy)
804 InterfaceName = &fdoExtension->DiskInterfaceName;
805
806 // Calculate and return the necessary data size
807 if ((fdoExtension->DiskData.PartitionStyle == PARTITION_STYLE_MBR) &&
808 !fdoExtension->IsSuperFloppy)
809 {
810 uniqueId->UniqueIdLength = sizeof(basicVolId->Mbr);
811 }
812 else if (fdoExtension->DiskData.PartitionStyle == PARTITION_STYLE_GPT)
813 {
814 uniqueId->UniqueIdLength = sizeof(basicVolId->Gpt);
815 }
816 else
817 {
818 if (!InterfaceName->Buffer || !InterfaceName->Length)
819 {
820 PartMgrReleaseLayoutLock(fdoExtension);
822 break;
823 }
824 uniqueId->UniqueIdLength = InterfaceName->Length;
825 }
826
827 // Return UniqueIdLength back
828 if (!VerifyIrpOutBufferSize(Irp, headerSize + uniqueId->UniqueIdLength))
829 {
830 PartMgrReleaseLayoutLock(fdoExtension);
831 Irp->IoStatus.Information = headerSize;
833 break;
834 }
835
836 //
837 // Write the UniqueId
838 //
839 // Format:
840 // - Basic volume on MBR disk: disk Mbr.Signature + partition StartingOffset (length: 0x0C)
841 // - Basic volume on GPT disk: "DMIO:ID:" + Gpt.PartitionGuid (length: 0x18)
842 // - Volume on Basic disk (NT <= 4): 8-byte FTDisk identifier (length: 0x08)
843 // - Volume on Dynamic disk (NT 5+): "DMIO:ID:" + dmio VolumeGuid (length: 0x18)
844 // - Super-floppy (single-partition with StartingOffset == 0),
845 // or Removable media: DiskInterfaceName.
846 // - As fallback, we use the VolumeInterfaceName.
847 //
848 if ((fdoExtension->DiskData.PartitionStyle == PARTITION_STYLE_MBR) &&
849 !fdoExtension->IsSuperFloppy)
850 {
851 basicVolId->Mbr.Signature = fdoExtension->DiskData.Mbr.Signature;
852 basicVolId->Mbr.StartingOffset = partExt->StartingOffset;
853 }
854 else if (fdoExtension->DiskData.PartitionStyle == PARTITION_STYLE_GPT)
855 {
856 basicVolId->Gpt.Signature = DMIO_ID_SIGNATURE;
857 basicVolId->Gpt.PartitionGuid = partExt->Gpt.PartitionId;
858 }
859 else
860 {
861 RtlCopyMemory(uniqueId->UniqueId,
862 InterfaceName->Buffer,
863 uniqueId->UniqueIdLength);
864 }
865
866 PartMgrReleaseLayoutLock(fdoExtension);
867
869 Irp->IoStatus.Information = headerSize + uniqueId->UniqueIdLength;
870 break;
871 }
872 default:
874 }
875
876 Irp->IoStatus.Status = status;
878 return status;
879}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
#define CODE_SEG(...)
unsigned char BOOLEAN
unsigned int UINT32
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS FASTCALL IoSetPartitionInformation(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG PartitionNumber, IN ULONG PartitionType)
Definition: ntoskrnl.c:46
#define ERR(fmt,...)
Definition: debug.h:113
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
#define IOCTL_DISK_VERIFY
Definition: cdrw_usr.h:170
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define swprintf
Definition: precomp.h:40
#define INFO
Definition: debug.h:89
#define ULONG_PTR
Definition: config.h:101
NTSTATUS PartitionHandleRemove(_In_ PPARTITION_EXTENSION PartExt, _In_ BOOLEAN FinalRemove)
Definition: partition.c:178
NTSTATUS PartitionHandleDeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partition.c:452
static NTSTATUS PartitionHandleQueryId(_In_ PPARTITION_EXTENSION PartExt, _In_ PIRP Irp)
Definition: partition.c:289
static NTSTATUS PartitionHandleDeviceRelations(_In_ PPARTITION_EXTENSION PartExt, _In_ PIRP Irp)
Definition: partition.c:250
static const WCHAR PartitionSymLinkFormat[]
Definition: partition.c:10
static NTSTATUS PartitionHandleStartDevice(_In_ PPARTITION_EXTENSION PartExt, _In_ PIRP Irp)
Definition: partition.c:94
NTSTATUS PartitionHandlePnp(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partition.c:388
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
static NTSTATUS PartitionHandleQueryCapabilities(_In_ PPARTITION_EXTENSION PartExt, _In_ PIRP Irp)
Definition: partition.c:367
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define PagedPool
Definition: env_spec_w32.h:308
#define IOCTL_DISK_GET_PARTITION_INFO_EX
Definition: ntddk_ex.h:206
NTSTATUS NTAPI IoSetPartitionInformationEx(IN PDEVICE_OBJECT DeviceObject, IN ULONG PartitionNumber, IN PSET_PARTITION_INFORMATION_EX PartitionInfo)
Definition: fstubex.c:2347
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
struct _PARTITION_INFORMATION_EX PARTITION_INFORMATION_EX
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
enum _PARTITION_STYLE PARTITION_STYLE
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:80
struct _PARTITION_INFORMATION_MBR PARTITION_INFORMATION_MBR
@ PARTITION_STYLE_GPT
Definition: imports.h:202
@ PARTITION_STYLE_MBR
Definition: imports.h:201
struct _PARTITION_INFORMATION_GPT PARTITION_INFORMATION_GPT
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define IOCTL_DISK_SET_PARTITION_INFO
Definition: ntdddisk.h:214
#define IOCTL_DISK_SET_PARTITION_INFO_EX
Definition: ntdddisk.h:217
struct _PARTITION_INFORMATION PARTITION_INFORMATION
#define IOCTL_DISK_GET_PARTITION_INFO
Definition: ntdddisk.h:106
#define IOCTL_DISK_UPDATE_PROPERTIES
Definition: ntdddisk.h:242
#define IOCTL_STORAGE_MEDIA_REMOVAL
Definition: ntddstor.h:104
#define IOCTL_VOLUME_QUERY_VOLUME_NUMBER
Definition: ntddvol.h:85
#define IOCTL_VOLUME_GET_GPT_ATTRIBUTES
Definition: ntddvol.h:133
struct _VOLUME_DISK_EXTENTS VOLUME_DISK_EXTENTS
#define IOCTL_VOLUME_ONLINE
Definition: ntddvol.h:63
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
Definition: ntddvol.h:44
#define IOCTL_VOLUME_IS_PARTITION
Definition: ntddvol.h:118
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:428
#define L(x)
Definition: ntvdm.h:50
#define TAG_PARTMGR
Definition: partmgr.h:23
union _BASIC_VOLUME_UNIQUE_ID * PBASIC_VOLUME_UNIQUE_ID
FORCEINLINE VOID PartMgrReleaseLayoutLock(_In_ PFDO_EXTENSION FDOExtension)
Definition: partmgr.h:212
FORCEINLINE VOID PartMgrAcquireLayoutLock(_In_ PFDO_EXTENSION FDOExtension)
Definition: partmgr.h:202
FORCEINLINE BOOLEAN VerifyIrpInBufferSize(_In_ PIRP Irp, _In_ SIZE_T Size)
Definition: partmgr.h:187
#define DMIO_ID_SIGNATURE
Definition: partmgr.h:55
FORCEINLINE BOOLEAN VerifyIrpOutBufferSize(_In_ PIRP Irp, _In_ SIZE_T Size)
Definition: partmgr.h:172
unsigned short USHORT
Definition: pedump.c:61
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:1772
#define FILE_DEVICE_DISK
Definition: winioctl.h:52
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
PDEVICE_OBJECT PhysicalDiskDO
Definition: partmgr.h:62
PDEVICE_OBJECT LowerDevice
Definition: partmgr.h:61
BOOLEAN LayoutValid
Definition: partmgr.h:65
BOOLEAN IsSuperFloppy
Definition: partmgr.h:70
UNICODE_STRING DiskInterfaceName
Definition: partmgr.h:86
struct _FDO_EXTENSION::@1323 DiskData
LARGE_INTEGER Length
Definition: imports.h:232
struct _IO_STACK_LOCATION::@3991::@4016 QueryDeviceRelations
struct _IO_STACK_LOCATION::@3991::@4018 DeviceCapabilities
struct _IO_STACK_LOCATION::@3991::@4022 QueryId
union _IO_STACK_LOCATION::@1573 Parameters
struct _IO_STACK_LOCATION::@1573::@1574 DeviceIoControl
USHORT UniqueIdLength
Definition: imports.h:138
UCHAR UniqueId[1]
Definition: imports.h:139
UNICODE_STRING VolumeInterfaceName
Definition: partmgr.h:124
UINT64 StartingOffset
Definition: partmgr.h:96
PDEVICE_OBJECT LowerDevice
Definition: partmgr.h:93
UINT32 DetectedNumber
Definition: partmgr.h:101
UNICODE_STRING DeviceName
Definition: partmgr.h:125
UINT64 PartitionLength
Definition: partmgr.h:97
BOOLEAN IsEnumerated
Definition: partmgr.h:103
struct _PARTITION_EXTENSION::@1328::@1331 Mbr
struct _PARTITION_EXTENSION::@1328::@1330 Gpt
PDEVICE_OBJECT DeviceObject
Definition: partmgr.h:92
LARGE_INTEGER StartingOffset
Definition: imports.h:221
PARTITION_INFORMATION_MBR Mbr
Definition: imports.h:226
PARTITION_INFORMATION_GPT Gpt
Definition: imports.h:227
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:656
ULONG NumberOfDiskExtents
Definition: ntddvol.h:54
WCHAR VolumeManagerName[8]
Definition: ntddvol.h:96
ULONG VolumeNumber
Definition: ntddvol.h:95
Definition: name.c:39
Definition: ps.c:97
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _BASIC_VOLUME_UNIQUE_ID::@1322 Gpt
struct _BASIC_VOLUME_UNIQUE_ID::@1321 Mbr
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IRP_MN_CANCEL_STOP_DEVICE
@ BusRelations
Definition: iotypes.h:2152
@ TargetDeviceRelation
Definition: iotypes.h:2156
enum _BUS_QUERY_ID_TYPE BUS_QUERY_ID_TYPE
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_START_DEVICE
#define IRP_MN_QUERY_ID
#define IRP_MN_REMOVE_DEVICE
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define IRP_MN_QUERY_STOP_DEVICE
#define IRP_MN_QUERY_CAPABILITIES
* PDEVICE_CAPABILITIES
Definition: iotypes.h:965
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IRP_MN_STOP_DEVICE
@ BusQueryInstanceID
Definition: iotypes.h:2939
@ BusQueryDeviceID
Definition: iotypes.h:2936
@ BusQueryHardwareIDs
Definition: iotypes.h:2937
enum _DEVICE_RELATION_TYPE DEVICE_RELATION_TYPE
#define IRP_MN_QUERY_REMOVE_DEVICE
#define ObReferenceObject
Definition: obfuncs.h:204
__wchar_t WCHAR
Definition: xmlstorage.h:180