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 header 5 * COPYRIGHT: 2020 Victor Perevertkin (victor.perevertkin@reactos.org) 6 */ 7 8 #ifndef _PARTMGR_H_ 9 #define _PARTMGR_H_ 10 11 #include <ntifs.h> 12 #include <mountdev.h> 13 #include <ntddvol.h> 14 #include <ntdddisk.h> 15 #include <ndk/psfuncs.h> 16 #include <ndk/section_attribs.h> 17 #include <ioevent.h> 18 #include <stdio.h> 19 #include <debug/driverdbg.h> 20 21 #include "debug.h" 22 23 #define TAG_PARTMGR 'MtrP' 24 25 // from disk.sys 26 typedef struct _DISK_GEOMETRY_EX_INTERNAL 27 { 28 DISK_GEOMETRY Geometry; 29 INT64 DiskSize; 30 DISK_PARTITION_INFO Partition; 31 DISK_DETECTION_INFO Detection; 32 } DISK_GEOMETRY_EX_INTERNAL, *PDISK_GEOMETRY_EX_INTERNAL; 33 34 // Unique ID data for basic (disk partition-based) volumes. 35 // It is stored in the MOUNTDEV_UNIQUE_ID::UniqueId member 36 // as an array of bytes. 37 #include <pshpack1.h> 38 typedef union _BASIC_VOLUME_UNIQUE_ID 39 { 40 struct 41 { 42 ULONG Signature; 43 ULONGLONG StartingOffset; 44 } Mbr; 45 struct 46 { 47 ULONGLONG Signature; // UCHAR[8] // "DMIO:ID:" 48 GUID PartitionGuid; 49 } Gpt; 50 } BASIC_VOLUME_UNIQUE_ID, *PBASIC_VOLUME_UNIQUE_ID; 51 #include <poppack.h> 52 C_ASSERT(RTL_FIELD_SIZE(BASIC_VOLUME_UNIQUE_ID, Mbr) == 0x0C); 53 C_ASSERT(RTL_FIELD_SIZE(BASIC_VOLUME_UNIQUE_ID, Gpt) == 0x18); 54 55 #define DMIO_ID_SIGNATURE (*(ULONGLONG*)"DMIO:ID:") 56 57 typedef struct _FDO_EXTENSION 58 { 59 BOOLEAN IsFDO; 60 PDEVICE_OBJECT DeviceObject; 61 PDEVICE_OBJECT LowerDevice; 62 PDEVICE_OBJECT PhysicalDiskDO; 63 KEVENT SyncEvent; 64 65 BOOLEAN LayoutValid; 66 PDRIVE_LAYOUT_INFORMATION_EX LayoutCache; 67 68 SINGLE_LIST_ENTRY PartitionList; 69 UINT32 EnumeratedPartitionsTotal; 70 BOOLEAN IsSuperFloppy; 71 72 struct { 73 UINT64 DiskSize; 74 UINT32 DeviceNumber; 75 UINT32 BytesPerSector; 76 PARTITION_STYLE PartitionStyle; 77 union { 78 struct { 79 UINT32 Signature; 80 } Mbr; 81 struct { 82 GUID DiskId; 83 } Gpt; 84 }; 85 } DiskData; 86 UNICODE_STRING DiskInterfaceName; 87 } FDO_EXTENSION, *PFDO_EXTENSION; 88 89 typedef struct _PARTITION_EXTENSION 90 { 91 BOOLEAN IsFDO; 92 PDEVICE_OBJECT DeviceObject; 93 PDEVICE_OBJECT LowerDevice; 94 PDEVICE_OBJECT Part0Device; 95 96 UINT64 StartingOffset; 97 UINT64 PartitionLength; 98 SINGLE_LIST_ENTRY ListEntry; 99 100 UINT32 VolumeNumber; // Volume number in the "\Device\HarddiskVolumeN" device name 101 UINT32 DetectedNumber; 102 UINT32 OnDiskNumber; // partition number for issuing Io requests to the kernel 103 BOOLEAN IsEnumerated; // reported via IRP_MN_QUERY_DEVICE_RELATIONS 104 BOOLEAN SymlinkCreated; 105 BOOLEAN Attached; // attached to PartitionList of the FDO 106 union 107 { 108 struct 109 { 110 GUID PartitionType; 111 GUID PartitionId; 112 UINT64 Attributes; 113 WCHAR Name[36]; 114 } Gpt; 115 struct 116 { 117 UINT8 PartitionType; 118 BOOLEAN BootIndicator; 119 BOOLEAN RecognizedPartition; 120 UINT32 HiddenSectors; 121 } Mbr; 122 }; 123 UNICODE_STRING PartitionInterfaceName; 124 UNICODE_STRING VolumeInterfaceName; 125 UNICODE_STRING DeviceName; 126 } PARTITION_EXTENSION, *PPARTITION_EXTENSION; 127 128 CODE_SEG("PAGE") 129 NTSTATUS 130 PartitionCreateDevice( 131 _In_ PDEVICE_OBJECT FDObject, 132 _In_ PPARTITION_INFORMATION_EX PartitionEntry, 133 _In_ UINT32 OnDiskNumber, 134 _In_ PARTITION_STYLE PartitionStyle, 135 _Out_ PDEVICE_OBJECT *PDO); 136 137 CODE_SEG("PAGE") 138 NTSTATUS 139 PartitionHandleRemove( 140 _In_ PPARTITION_EXTENSION PartExt, 141 _In_ BOOLEAN FinalRemove); 142 143 CODE_SEG("PAGE") 144 NTSTATUS 145 PartitionHandlePnp( 146 _In_ PDEVICE_OBJECT DeviceObject, 147 _In_ PIRP Irp); 148 149 NTSTATUS 150 PartitionHandleDeviceControl( 151 _In_ PDEVICE_OBJECT DeviceObject, 152 _In_ PIRP Irp); 153 154 NTSTATUS 155 NTAPI 156 ForwardIrpAndForget( 157 _In_ PDEVICE_OBJECT DeviceObject, 158 _In_ PIRP Irp); 159 160 NTSTATUS 161 IssueSyncIoControlRequest( 162 _In_ UINT32 IoControlCode, 163 _In_ PDEVICE_OBJECT DeviceObject, 164 _In_ PVOID InputBuffer, 165 _In_ ULONG InputBufferLength, 166 _In_ PVOID OutputBuffer, 167 _In_ ULONG OutputBufferLength, 168 _In_ BOOLEAN InternalDeviceIoControl); 169 170 FORCEINLINE 171 BOOLEAN 172 VerifyIrpOutBufferSize( 173 _In_ PIRP Irp, 174 _In_ SIZE_T Size) 175 { 176 PIO_STACK_LOCATION ioStack = IoGetCurrentIrpStackLocation(Irp); 177 if (ioStack->Parameters.DeviceIoControl.OutputBufferLength < Size) 178 { 179 Irp->IoStatus.Information = Size; 180 return FALSE; 181 } 182 return TRUE; 183 } 184 185 FORCEINLINE 186 BOOLEAN 187 VerifyIrpInBufferSize( 188 _In_ PIRP Irp, 189 _In_ SIZE_T Size) 190 { 191 PIO_STACK_LOCATION ioStack = IoGetCurrentIrpStackLocation(Irp); 192 if (ioStack->Parameters.DeviceIoControl.InputBufferLength < Size) 193 { 194 Irp->IoStatus.Information = Size; 195 return FALSE; 196 } 197 return TRUE; 198 } 199 200 FORCEINLINE 201 VOID 202 PartMgrAcquireLayoutLock( 203 _In_ PFDO_EXTENSION FDOExtension) 204 { 205 PAGED_CODE(); 206 207 KeWaitForSingleObject(&FDOExtension->SyncEvent, Executive, KernelMode, FALSE, NULL); 208 } 209 210 FORCEINLINE 211 VOID 212 PartMgrReleaseLayoutLock( 213 _In_ PFDO_EXTENSION FDOExtension) 214 { 215 PAGED_CODE(); 216 217 KeSetEvent(&FDOExtension->SyncEvent, IO_NO_INCREMENT, FALSE); 218 } 219 220 #endif // _PARTMGR_H_ 221