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
VerifyIrpOutBufferSize(_In_ PIRP Irp,_In_ SIZE_T Size)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
VerifyIrpInBufferSize(_In_ PIRP Irp,_In_ SIZE_T Size)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
PartMgrAcquireLayoutLock(_In_ PFDO_EXTENSION FDOExtension)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
PartMgrReleaseLayoutLock(_In_ PFDO_EXTENSION FDOExtension)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