ReactOS 0.4.16-dev-336-gb667d82
partmgr.h File Reference
#include <ntifs.h>
#include <mountdev.h>
#include <ntddvol.h>
#include <ntdddisk.h>
#include <ndk/psfuncs.h>
#include <ndk/section_attribs.h>
#include <ioevent.h>
#include <stdio.h>
#include <debug/driverdbg.h>
#include "debug.h"
#include <pshpack1.h>
#include <poppack.h>
Include dependency graph for partmgr.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _DISK_GEOMETRY_EX_INTERNAL
 
union  _BASIC_VOLUME_UNIQUE_ID
 
struct  _FDO_EXTENSION
 
struct  _PARTITION_EXTENSION
 

Macros

#define TAG_PARTMGR   'MtrP'
 
#define DMIO_ID_SIGNATURE   (*(ULONGLONG*)"DMIO:ID:")
 

Typedefs

typedef struct _DISK_GEOMETRY_EX_INTERNAL DISK_GEOMETRY_EX_INTERNAL
 
typedef struct _DISK_GEOMETRY_EX_INTERNALPDISK_GEOMETRY_EX_INTERNAL
 
typedef union _BASIC_VOLUME_UNIQUE_ID BASIC_VOLUME_UNIQUE_ID
 
typedef union _BASIC_VOLUME_UNIQUE_IDPBASIC_VOLUME_UNIQUE_ID
 
typedef struct _FDO_EXTENSION FDO_EXTENSION
 
typedef struct _FDO_EXTENSIONPFDO_EXTENSION
 
typedef struct _PARTITION_EXTENSION PARTITION_EXTENSION
 
typedef struct _PARTITION_EXTENSIONPPARTITION_EXTENSION
 

Functions

 C_ASSERT (RTL_FIELD_SIZE(BASIC_VOLUME_UNIQUE_ID, Mbr)==0x0C)
 
 C_ASSERT (RTL_FIELD_SIZE(BASIC_VOLUME_UNIQUE_ID, Gpt)==0x18)
 
NTSTATUS PartitionCreateDevice (_In_ PDEVICE_OBJECT FDObject, _In_ PPARTITION_INFORMATION_EX PartitionEntry, _In_ UINT32 OnDiskNumber, _In_ PARTITION_STYLE PartitionStyle, _Out_ PDEVICE_OBJECT *PDO)
 
NTSTATUS PartitionHandleRemove (_In_ PPARTITION_EXTENSION PartExt, _In_ BOOLEAN FinalRemove)
 
NTSTATUS PartitionHandlePnp (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
 
NTSTATUS PartitionHandleDeviceControl (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
 
NTSTATUS NTAPI ForwardIrpAndForget (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
 
NTSTATUS IssueSyncIoControlRequest (_In_ UINT32 IoControlCode, _In_ PDEVICE_OBJECT DeviceObject, _In_ PVOID InputBuffer, _In_ ULONG InputBufferLength, _In_ PVOID OutputBuffer, _In_ ULONG OutputBufferLength, _In_ BOOLEAN InternalDeviceIoControl)
 
FORCEINLINE BOOLEAN VerifyIrpOutBufferSize (_In_ PIRP Irp, _In_ SIZE_T Size)
 
FORCEINLINE BOOLEAN VerifyIrpInBufferSize (_In_ PIRP Irp, _In_ SIZE_T Size)
 
FORCEINLINE VOID PartMgrAcquireLayoutLock (_In_ PFDO_EXTENSION FDOExtension)
 
FORCEINLINE VOID PartMgrReleaseLayoutLock (_In_ PFDO_EXTENSION FDOExtension)
 

Macro Definition Documentation

◆ DMIO_ID_SIGNATURE

#define DMIO_ID_SIGNATURE   (*(ULONGLONG*)"DMIO:ID:")

Definition at line 55 of file partmgr.h.

◆ TAG_PARTMGR

#define TAG_PARTMGR   'MtrP'

Definition at line 23 of file partmgr.h.

Typedef Documentation

◆ BASIC_VOLUME_UNIQUE_ID

◆ DISK_GEOMETRY_EX_INTERNAL

◆ FDO_EXTENSION

◆ PARTITION_EXTENSION

◆ PBASIC_VOLUME_UNIQUE_ID

◆ PDISK_GEOMETRY_EX_INTERNAL

◆ PFDO_EXTENSION

◆ PPARTITION_EXTENSION

Function Documentation

◆ C_ASSERT() [1/2]

C_ASSERT ( RTL_FIELD_SIZE(BASIC_VOLUME_UNIQUE_ID, Gpt)  = =0x18)

◆ C_ASSERT() [2/2]

C_ASSERT ( RTL_FIELD_SIZE(BASIC_VOLUME_UNIQUE_ID, Mbr)  = =0x0C)

◆ ForwardIrpAndForget()

NTSTATUS NTAPI ForwardIrpAndForget ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp 
)

Definition at line 5 of file utils.c.

8{
9 // this part of a structure is identical in both FDO and PDO
10 PDEVICE_OBJECT LowerDevice = ((PFDO_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
11
12 ASSERT(LowerDevice);
13
15 return IoCallDriver(LowerDevice, Irp);
16}
_In_ PIRP Irp
Definition: csq.h:116
#define ASSERT(a)
Definition: mode.c:44
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IoCallDriver
Definition: irp.c:1225
struct _FDO_EXTENSION * PFDO_EXTENSION
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055

◆ IssueSyncIoControlRequest()

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 at line 19 of file utils.c.

27{
28 PIRP Irp;
32 PAGED_CODE();
33
34 /* Allocate a non-paged event */
36 if (!Event)
37 {
39 }
40
41 /* Initialize it */
43
44 /* Build the IRP */
52 Event,
54 if (!Irp)
55 {
56 /* Fail, free the event */
59 }
60
61 /* Call the driver and check if it's pending */
64 {
65 /* Wait on the driver */
68 }
69
70 /* Free the event and return the Status */
72 return Status;
73}
#define PAGED_CODE()
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define NonPagedPool
Definition: env_spec_w32.h:307
Status
Definition: gdiplustypes.h:25
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define KernelMode
Definition: asm.h:34
@ NotificationEvent
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define TAG_PARTMGR
Definition: partmgr.h:23
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ WDFREQUEST _In_ size_t _In_ size_t _In_ ULONG IoControlCode
Definition: wdfio.h:325
_In_ WDFREQUEST _In_ size_t OutputBufferLength
Definition: wdfio.h:320
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
Definition: wdfio.h:322
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID _In_ ULONG _In_ BOOLEAN InternalDeviceIoControl
Definition: iofuncs.h:720
@ Executive
Definition: ketypes.h:415

Referenced by FdoHandleStartDevice(), FdoIoctlDiskGetDriveGeometryEx(), PartMgrRefreshDiskData(), and VolumeDeleteMountPoints().

◆ PartitionCreateDevice()

NTSTATUS PartitionCreateDevice ( _In_ PDEVICE_OBJECT  FDObject,
_In_ PPARTITION_INFORMATION_EX  PartitionEntry,
_In_ UINT32  OnDiskNumber,
_In_ PARTITION_STYLE  PartitionStyle,
_Out_ PDEVICE_OBJECT PDO 
)

Definition at line 15 of file partition.c.

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}
unsigned int UINT32
#define ERR(fmt,...)
Definition: precomp.h:57
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define swprintf
Definition: precomp.h:40
#define INFO
Definition: debug.h:89
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
@ PARTITION_STYLE_MBR
Definition: imports.h:201
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
#define L(x)
Definition: ntvdm.h:50
#define FILE_DEVICE_DISK
Definition: winioctl.h:52
PVOID DeviceExtension
Definition: env_spec_w32.h:418
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
struct _PARTITION_EXTENSION::@1336::@1338 Gpt
PDEVICE_OBJECT DeviceObject
Definition: partmgr.h:92
struct _PARTITION_EXTENSION::@1336::@1339 Mbr
Definition: ps.c:97
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by PartMgrUpdatePartitionDevices().

◆ PartitionHandleDeviceControl()

NTSTATUS PartitionHandleDeviceControl ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp 
)

Definition at line 563 of file partition.c.

566{
568 PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
569 PFDO_EXTENSION fdoExtension = partExt->LowerDevice->DeviceExtension;
571
572 ASSERT(!partExt->IsFDO);
573
574 if (!partExt->IsEnumerated)
575 {
576 Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
579 }
580
581 switch (ioStack->Parameters.DeviceIoControl.IoControlCode)
582 {
583 // disk stuff
585 {
587 {
589 break;
590 }
591
592 PartMgrAcquireLayoutLock(fdoExtension);
593
594 // not supported on anything other than MBR
595 if (fdoExtension->DiskData.PartitionStyle != PARTITION_STYLE_MBR)
596 {
598 PartMgrReleaseLayoutLock(fdoExtension);
599 break;
600 }
601
602 PPARTITION_INFORMATION partInfo = Irp->AssociatedIrp.SystemBuffer;
603
604 *partInfo = (PARTITION_INFORMATION){
605 .PartitionType = partExt->Mbr.PartitionType,
606 .StartingOffset.QuadPart = partExt->StartingOffset,
607 .PartitionLength.QuadPart = partExt->PartitionLength,
608 .HiddenSectors = partExt->Mbr.HiddenSectors,
609 .PartitionNumber = partExt->DetectedNumber,
610 .BootIndicator = partExt->Mbr.BootIndicator,
611 .RecognizedPartition = partExt->Mbr.RecognizedPartition,
612 .RewritePartition = FALSE,
613 };
614
615 PartMgrReleaseLayoutLock(fdoExtension);
616
617 Irp->IoStatus.Information = sizeof(*partInfo);
619 break;
620 }
622 {
624 {
626 break;
627 }
628
629 PPARTITION_INFORMATION_EX partInfoEx = Irp->AssociatedIrp.SystemBuffer;
630
631 PartMgrAcquireLayoutLock(fdoExtension);
632
633 *partInfoEx = (PARTITION_INFORMATION_EX){
635 .PartitionLength.QuadPart = partExt->PartitionLength,
636 .PartitionNumber = partExt->DetectedNumber,
637 .PartitionStyle = fdoExtension->DiskData.PartitionStyle,
638 .RewritePartition = FALSE,
639 };
640
641 if (fdoExtension->DiskData.PartitionStyle == PARTITION_STYLE_MBR)
642 {
643 partInfoEx->Mbr = (PARTITION_INFORMATION_MBR){
644 .PartitionType = partExt->Mbr.PartitionType,
645 .HiddenSectors = partExt->Mbr.HiddenSectors,
646 .BootIndicator = partExt->Mbr.BootIndicator,
647 .RecognizedPartition = partExt->Mbr.RecognizedPartition,
648 };
649 }
650 else
651 {
652 partInfoEx->Gpt = (PARTITION_INFORMATION_GPT){
653 .PartitionType = partExt->Gpt.PartitionType,
654 .PartitionId = partExt->Gpt.PartitionId,
655 .Attributes = partExt->Gpt.Attributes,
656 };
657
658 RtlCopyMemory(partInfoEx->Gpt.Name,
659 partExt->Gpt.Name,
660 sizeof(partInfoEx->Gpt.Name));
661 }
662
663 PartMgrReleaseLayoutLock(fdoExtension);
664
665 Irp->IoStatus.Information = sizeof(*partInfoEx);
667 break;
668 }
670 {
671 PSET_PARTITION_INFORMATION inputBuffer = Irp->AssociatedIrp.SystemBuffer;
672 if (!VerifyIrpInBufferSize(Irp, sizeof(*inputBuffer)))
673 {
675 break;
676 }
677
678 PartMgrAcquireLayoutLock(fdoExtension);
679
680 // these functions use on disk numbers, not detected ones
682 fdoExtension->DiskData.BytesPerSector,
683 partExt->OnDiskNumber,
684 inputBuffer->PartitionType);
685
686 if (NT_SUCCESS(status))
687 {
688 partExt->Mbr.PartitionType = inputBuffer->PartitionType;
689 }
690
691 PartMgrReleaseLayoutLock(fdoExtension);
692
693 Irp->IoStatus.Information = 0;
694 break;
695 }
697 {
698 PSET_PARTITION_INFORMATION_EX inputBuffer = Irp->AssociatedIrp.SystemBuffer;
699 if (!VerifyIrpInBufferSize(Irp, sizeof(*inputBuffer)))
700 {
702 break;
703 }
704
705 PartMgrAcquireLayoutLock(fdoExtension);
706
707 // these functions use on disk numbers, not detected ones
709 partExt->OnDiskNumber,
710 inputBuffer);
711
712 if (NT_SUCCESS(status))
713 {
714 if (fdoExtension->DiskData.PartitionStyle == PARTITION_STYLE_MBR)
715 {
716 partExt->Mbr.PartitionType = inputBuffer->Mbr.PartitionType;
717 }
718 else
719 {
720 partExt->Gpt.PartitionType = inputBuffer->Gpt.PartitionType;
721 partExt->Gpt.PartitionId = inputBuffer->Gpt.PartitionId;
722 partExt->Gpt.Attributes = inputBuffer->Gpt.Attributes;
723
724 RtlMoveMemory(partExt->Gpt.Name,
725 inputBuffer->Gpt.Name,
726 sizeof(partExt->Gpt.Name));
727 }
728 }
729
730 PartMgrReleaseLayoutLock(fdoExtension);
731
732 Irp->IoStatus.Information = 0;
733 break;
734 }
736 {
737 PGET_LENGTH_INFORMATION lengthInfo = Irp->AssociatedIrp.SystemBuffer;
738 if (!VerifyIrpOutBufferSize(Irp, sizeof(*lengthInfo)))
739 {
741 break;
742 }
743
744 PartMgrAcquireLayoutLock(fdoExtension);
745
746 lengthInfo->Length.QuadPart = partExt->PartitionLength;
747
748 PartMgrReleaseLayoutLock(fdoExtension);
749
751 Irp->IoStatus.Information = sizeof(*lengthInfo);
752 break;
753 }
755 {
756 PVERIFY_INFORMATION verifyInfo = Irp->AssociatedIrp.SystemBuffer;
757 if (!VerifyIrpInBufferSize(Irp, sizeof(*verifyInfo)))
758 {
760 break;
761 }
762
763 // Partition device should just adjust the starting offset
764 verifyInfo->StartingOffset.QuadPart += partExt->StartingOffset;
766 }
768 {
769 fdoExtension->LayoutValid = FALSE;
771
773 break;
774 }
776 {
778 }
779 // volume stuff (most of that should be in volmgr.sys once it is implemented)
781 {
782 PVOLUME_DISK_EXTENTS volExts = Irp->AssociatedIrp.SystemBuffer;
783
784 // we fill only one extent entry so sizeof(*volExts) is enough
785 if (!VerifyIrpOutBufferSize(Irp, sizeof(*volExts)))
786 {
788 break;
789 }
790
791 PartMgrAcquireLayoutLock(fdoExtension);
792
793 // the only type of volume we support right now is disk partition
794 // so this structure is simple
795
796 *volExts = (VOLUME_DISK_EXTENTS) {
798 .Extents = {{
799 .DiskNumber = fdoExtension->DiskData.DeviceNumber,
800 .StartingOffset.QuadPart = partExt->StartingOffset,
801 .ExtentLength.QuadPart = partExt->PartitionLength
802 }}
803 };
804
805 PartMgrReleaseLayoutLock(fdoExtension);
806
808 Irp->IoStatus.Information = sizeof(*volExts);
809 break;
810 }
812 {
813 PVOLUME_NUMBER volNum = Irp->AssociatedIrp.SystemBuffer;
814 if (!VerifyIrpOutBufferSize(Irp, sizeof(*volNum)))
815 {
817 break;
818 }
819
820 PartMgrAcquireLayoutLock(fdoExtension);
821
822 volNum->VolumeNumber = partExt->VolumeNumber;
824 L"VOLMGR ", // Must be 8 space-padded characters
825 sizeof(volNum->VolumeManagerName));
826
827 PartMgrReleaseLayoutLock(fdoExtension);
828
830 Irp->IoStatus.Information = sizeof(*volNum);
831 break;
832 }
834 {
835 // The only type of volume we support right now is disk partition
836 // so we just return success. A more robust algorithm would be
837 // to check whether the volume has only one single extent, that
838 // covers the whole partition on which it lies upon. If this is
839 // not the case, return STATUS_UNSUCCESSFUL instead.
841 break;
842 }
844 {
846 break;
847 }
849 {
850 PVOLUME_GET_GPT_ATTRIBUTES_INFORMATION gptAttrs = Irp->AssociatedIrp.SystemBuffer;
851 if (!VerifyIrpOutBufferSize(Irp, sizeof(*gptAttrs)))
852 {
854 break;
855 }
856
857 // not supported on anything other than GPT
858 if (fdoExtension->DiskData.PartitionStyle != PARTITION_STYLE_GPT)
859 {
861 break;
862 }
863
864 gptAttrs->GptAttributes = partExt->Gpt.Attributes;
865
867 Irp->IoStatus.Information = sizeof(*gptAttrs);
868 break;
869 }
870 // mountmgr notifications (these should be in volmgr.sys once it is implemented)
872 {
873 PMOUNTDEV_NAME name = Irp->AssociatedIrp.SystemBuffer;
874
875 if (!VerifyIrpOutBufferSize(Irp, sizeof(USHORT)))
876 {
878 break;
879 }
880
881 name->NameLength = partExt->DeviceName.Length;
882
883 // return NameLength back
884 if (!VerifyIrpOutBufferSize(Irp, sizeof(USHORT) + name->NameLength))
885 {
886 Irp->IoStatus.Information = sizeof(USHORT);
888 break;
889 }
890
891 RtlCopyMemory(name->Name, partExt->DeviceName.Buffer, name->NameLength);
892
894 Irp->IoStatus.Information = sizeof(USHORT) + name->NameLength;
895 break;
896 }
898 {
899 const SIZE_T headerSize = FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId);
900 PMOUNTDEV_UNIQUE_ID uniqueId = Irp->AssociatedIrp.SystemBuffer;
902 PUNICODE_STRING InterfaceName;
903
904 // Check whether the minimal header size was provided
905 if (!VerifyIrpOutBufferSize(Irp, headerSize))
906 {
908 break;
909 }
910
911 PartMgrAcquireLayoutLock(fdoExtension);
912
913 InterfaceName = &partExt->VolumeInterfaceName;
914 if (fdoExtension->IsSuperFloppy)
915 InterfaceName = &fdoExtension->DiskInterfaceName;
916
917 // Calculate and return the necessary data size
918 if ((fdoExtension->DiskData.PartitionStyle == PARTITION_STYLE_MBR) &&
919 !fdoExtension->IsSuperFloppy)
920 {
921 uniqueId->UniqueIdLength = sizeof(basicVolId->Mbr);
922 }
923 else if (fdoExtension->DiskData.PartitionStyle == PARTITION_STYLE_GPT)
924 {
925 uniqueId->UniqueIdLength = sizeof(basicVolId->Gpt);
926 }
927 else
928 {
929 if (!InterfaceName->Buffer || !InterfaceName->Length)
930 {
931 PartMgrReleaseLayoutLock(fdoExtension);
933 break;
934 }
935 uniqueId->UniqueIdLength = InterfaceName->Length;
936 }
937
938 // Return UniqueIdLength back
939 if (!VerifyIrpOutBufferSize(Irp, headerSize + uniqueId->UniqueIdLength))
940 {
941 PartMgrReleaseLayoutLock(fdoExtension);
942 Irp->IoStatus.Information = headerSize;
944 break;
945 }
946
947 //
948 // Write the UniqueId
949 //
950 // Format:
951 // - Basic volume on MBR disk: disk Mbr.Signature + partition StartingOffset (length: 0x0C)
952 // - Basic volume on GPT disk: "DMIO:ID:" + Gpt.PartitionGuid (length: 0x18)
953 // - Volume on Basic disk (NT <= 4): 8-byte FTDisk identifier (length: 0x08)
954 // - Volume on Dynamic disk (NT 5+): "DMIO:ID:" + dmio VolumeGuid (length: 0x18)
955 // - Super-floppy (single-partition with StartingOffset == 0),
956 // or Removable media: DiskInterfaceName.
957 // - As fallback, we use the VolumeInterfaceName.
958 //
959 if ((fdoExtension->DiskData.PartitionStyle == PARTITION_STYLE_MBR) &&
960 !fdoExtension->IsSuperFloppy)
961 {
962 basicVolId->Mbr.Signature = fdoExtension->DiskData.Mbr.Signature;
963 basicVolId->Mbr.StartingOffset = partExt->StartingOffset;
964 }
965 else if (fdoExtension->DiskData.PartitionStyle == PARTITION_STYLE_GPT)
966 {
967 basicVolId->Gpt.Signature = DMIO_ID_SIGNATURE;
968 basicVolId->Gpt.PartitionGuid = partExt->Gpt.PartitionId;
969 }
970 else
971 {
972 RtlCopyMemory(uniqueId->UniqueId,
973 InterfaceName->Buffer,
974 uniqueId->UniqueIdLength);
975 }
976
977 PartMgrReleaseLayoutLock(fdoExtension);
978
980 Irp->IoStatus.Information = headerSize + uniqueId->UniqueIdLength;
981 break;
982 }
986#if (NTDDI_VERSION >= NTDDI_WS03)
987 /* Deprecated Windows 2000/XP versions of IOCTL_MOUNTDEV_LINK_[CREATED|DELETED]
988 * without access protection, that were updated in Windows 2003 */
991#endif
994 {
995 WARN("Ignored MountMgr notification: 0x%lX\n",
996 ioStack->Parameters.DeviceIoControl.IoControlCode);
998 break;
999 }
1000 default:
1002 }
1003
1004 Irp->IoStatus.Status = status;
1006 return status;
1007}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define WARN(fmt,...)
Definition: precomp.h:61
NTSTATUS FASTCALL IoSetPartitionInformation(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG PartitionNumber, IN ULONG PartitionType)
Definition: ntoskrnl.c:50
#define IOCTL_DISK_VERIFY
Definition: cdrw_usr.h:170
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#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
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
if(dx< 0)
Definition: linetemp.h:194
#define IOCTL_MOUNTDEV_LINK_CREATED
Definition: imports.h:104
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:91
#define IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
Definition: imports.h:97
#define IOCTL_MOUNTDEV_QUERY_STABLE_GUID
Definition: imports.h:255
struct _PARTITION_INFORMATION_EX PARTITION_INFORMATION_EX
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
#define MOUNTDEVCONTROLTYPE
Definition: imports.h:76
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:78
#define IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY
Definition: imports.h:84
struct _PARTITION_INFORMATION_MBR PARTITION_INFORMATION_MBR
@ PARTITION_STYLE_GPT
Definition: imports.h:202
#define IOCTL_MOUNTDEV_LINK_DELETED
Definition: imports.h:110
struct _PARTITION_INFORMATION_GPT PARTITION_INFORMATION_GPT
#define CTL_CODE(DeviceType, Function, Method, Access)
Definition: nt_native.h:586
#define FILE_ANY_ACCESS
Definition: nt_native.h:609
#define METHOD_BUFFERED
Definition: nt_native.h:594
#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 IoCompleteRequest
Definition: irp.c:1240
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:428
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 STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
struct _FDO_EXTENSION::@1331 DiskData
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
LARGE_INTEGER Length
Definition: imports.h:232
union _IO_STACK_LOCATION::@1581 Parameters
struct _IO_STACK_LOCATION::@1581::@1582 DeviceIoControl
USHORT UniqueIdLength
Definition: imports.h:136
UCHAR UniqueId[1]
Definition: imports.h:137
UNICODE_STRING VolumeInterfaceName
Definition: partmgr.h:124
BOOLEAN IsEnumerated
Definition: partmgr.h:103
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:651
ULONG NumberOfDiskExtents
Definition: ntddvol.h:54
WCHAR VolumeManagerName[8]
Definition: ntddvol.h:96
ULONG VolumeNumber
Definition: ntddvol.h:95
Definition: name.c:39
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#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
struct _BASIC_VOLUME_UNIQUE_ID::@1330 Gpt
struct _BASIC_VOLUME_UNIQUE_ID::@1329 Mbr
LONGLONG QuadPart
Definition: typedefs.h:114
@ BusRelations
Definition: iotypes.h:2152
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by PartMgrDeviceControl().

◆ PartitionHandlePnp()

NTSTATUS PartitionHandlePnp ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp 
)

Definition at line 499 of file partition.c.

502{
503 PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
506
507 PAGED_CODE();
508
509 switch (ioStack->MinorFunction)
510 {
512 {
514 break;
515 }
517 {
519 break;
520 }
526 {
528 break;
529 }
531 {
533 break;
534 }
536 {
538 break;
539 }
540 case IRP_MN_QUERY_ID:
541 {
543 break;
544 }
546 {
548 break;
549 }
550 default:
551 {
552 Irp->IoStatus.Information = 0;
554 }
555 }
556
557 Irp->IoStatus.Status = status;
559 return status;
560}
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define TRUE
Definition: types.h:120
NTSTATUS PartitionHandleRemove(_In_ PPARTITION_EXTENSION PartExt, _In_ BOOLEAN FinalRemove)
Definition: partition.c:276
static NTSTATUS PartitionHandleQueryId(_In_ PPARTITION_EXTENSION PartExt, _In_ PIRP Irp)
Definition: partition.c:400
static NTSTATUS PartitionHandleDeviceRelations(_In_ PPARTITION_EXTENSION PartExt, _In_ PIRP Irp)
Definition: partition.c:361
static NTSTATUS PartitionHandleStartDevice(_In_ PPARTITION_EXTENSION PartExt, _In_ PIRP Irp)
Definition: partition.c:94
static NTSTATUS PartitionHandleQueryCapabilities(_In_ PPARTITION_EXTENSION PartExt, _In_ PIRP Irp)
Definition: partition.c:478
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
#define IRP_MN_CANCEL_STOP_DEVICE
#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
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IRP_MN_STOP_DEVICE
#define IRP_MN_QUERY_REMOVE_DEVICE

Referenced by PartMgrPnp().

◆ PartitionHandleRemove()

NTSTATUS PartitionHandleRemove ( _In_ PPARTITION_EXTENSION  PartExt,
_In_ BOOLEAN  FinalRemove 
)

Definition at line 276 of file partition.c.

279{
281
282 PAGED_CODE();
283
284 // remove the symbolic link
285 if (PartExt->SymlinkCreated)
286 {
287 WCHAR nameBuf[64];
288 UNICODE_STRING partitionSymlink;
289 PFDO_EXTENSION fdoExtension = PartExt->LowerDevice->DeviceExtension;
290
292 fdoExtension->DiskData.DeviceNumber, PartExt->DetectedNumber);
293
294 RtlInitUnicodeString(&partitionSymlink, nameBuf);
295
296 status = IoDeleteSymbolicLink(&partitionSymlink);
297
298 if (!NT_SUCCESS(status))
299 {
300 return status;
301 }
302 PartExt->SymlinkCreated = FALSE;
303
304 INFO("Symlink removed %wZ -> %wZ\n", &partitionSymlink, &PartExt->DeviceName);
305 }
306
307 // release device interfaces
308 if (PartExt->PartitionInterfaceName.Buffer)
309 {
310 status = IoSetDeviceInterfaceState(&PartExt->PartitionInterfaceName, FALSE);
311 if (!NT_SUCCESS(status))
312 {
313 return status;
314 }
315 RtlFreeUnicodeString(&PartExt->PartitionInterfaceName);
316 RtlInitUnicodeString(&PartExt->PartitionInterfaceName, NULL);
317 }
318
319 if (PartExt->VolumeInterfaceName.Buffer)
320 {
321 /* Notify MountMgr to delete all associated mount points.
322 * MountMgr does not automatically remove these in order to support
323 * drive letter persistence for online/offline volume transitions,
324 * or volumes arrival/removal on removable devices. */
326 if (!NT_SUCCESS(status))
327 {
328 ERR("VolumeDeleteMountPoints(%wZ) failed with status 0x%08lx\n",
329 &PartExt->DeviceName, status);
330 /* Failure isn't major, continue proceeding with volume removal */
331 }
332
333 /* Notify MountMgr of volume removal */
334 status = IoSetDeviceInterfaceState(&PartExt->VolumeInterfaceName, FALSE);
335 if (!NT_SUCCESS(status))
336 {
337 return status;
338 }
339 RtlFreeUnicodeString(&PartExt->VolumeInterfaceName);
340 RtlInitUnicodeString(&PartExt->VolumeInterfaceName, NULL);
341 }
342
343 if (FinalRemove)
344 {
345 ASSERT(PartExt->DeviceName.Buffer);
346 if (PartExt->DeviceName.Buffer)
347 {
348 INFO("Removed device %wZ\n", &PartExt->DeviceName);
349 RtlFreeUnicodeString(&PartExt->DeviceName);
350 }
351
352 IoDeleteDevice(PartExt->DeviceObject);
353 }
354
355 return STATUS_SUCCESS;
356}
static const WCHAR PartitionSymLinkFormat[]
Definition: partition.c:10
static NTSTATUS VolumeDeleteMountPoints(_In_ PPARTITION_EXTENSION PartExt)
Notifies MountMgr to delete all mount points associated with the given volume.
Definition: partition.c:185
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311

Referenced by FdoHandleSurpriseRemoval(), PartitionHandlePnp(), and PartMgrUpdatePartitionDevices().

◆ PartMgrAcquireLayoutLock()

◆ PartMgrReleaseLayoutLock()

◆ VerifyIrpInBufferSize()

FORCEINLINE BOOLEAN VerifyIrpInBufferSize ( _In_ PIRP  Irp,
_In_ SIZE_T  Size 
)

Definition at line 187 of file partmgr.h.

190{
192 if (ioStack->Parameters.DeviceIoControl.InputBufferLength < Size)
193 {
194 Irp->IoStatus.Information = Size;
195 return FALSE;
196 }
197 return TRUE;
198}
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533

Referenced by FdoIoctlDiskCreateDisk(), FdoIoctlDiskSetDriveLayout(), FdoIoctlDiskSetDriveLayoutEx(), PartitionHandleDeviceControl(), and ScsiPortDeviceControl().

◆ VerifyIrpOutBufferSize()

FORCEINLINE BOOLEAN VerifyIrpOutBufferSize ( _In_ PIRP  Irp,
_In_ SIZE_T  Size 
)

Definition at line 172 of file partmgr.h.

175{
177 if (ioStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
178 {
179 Irp->IoStatus.Information = Size;
180 return FALSE;
181 }
182 return TRUE;
183}

Referenced by FdoIoctlDiskGetDriveLayout(), FdoIoctlDiskGetDriveLayoutEx(), FdoIoctlDiskGetPartitionInfo(), FdoIoctlDiskGetPartitionInfoEx(), PartitionHandleDeviceControl(), and ScsiPortDeviceControl().