ReactOS 0.4.15-dev-6073-g59e7458
devctrl.c File Reference
#include "btrfs_drv.h"
#include <ntdddisk.h>
#include <mountdev.h>
#include <diskguid.h>
Include dependency graph for devctrl.c:

Go to the source code of this file.

Functions

static NTSTATUS mountdev_query_stable_guid (device_extension *Vcb, PIRP Irp)
 
static NTSTATUS is_writable (device_extension *Vcb)
 
static NTSTATUS query_filesystems (void *data, ULONG length)
 
static NTSTATUS probe_volume (void *data, ULONG length, KPROCESSOR_MODE processor_mode)
 
static NTSTATUS ioctl_unload (PIRP Irp)
 
static NTSTATUS control_ioctl (PIRP Irp)
 
 _Dispatch_type_ (IRP_MJ_DEVICE_CONTROL)
 

Variables

PDRIVER_OBJECT drvobj
 
LIST_ENTRY VcbList
 
ERESOURCE global_loading_lock
 

Function Documentation

◆ _Dispatch_type_()

_Dispatch_type_ ( IRP_MJ_DEVICE_CONTROL  )

Definition at line 252 of file devctrl.c.

254 {
257 device_extension* Vcb = DeviceObject->DeviceExtension;
258 bool top_level;
259
261
262 top_level = is_top_level(Irp);
263
264 Irp->IoStatus.Information = 0;
265
266 if (Vcb) {
267 if (Vcb->type == VCB_TYPE_CONTROL) {
269 goto end;
270 } else if (Vcb->type == VCB_TYPE_VOLUME) {
272 goto end;
273 } else if (Vcb->type != VCB_TYPE_FS) {
275 goto end;
276 }
277 } else {
279 goto end;
280 }
281
282 switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
285 goto end;
286
289 goto end;
290
291 default:
292 TRACE("unhandled control code %lx\n", IrpSp->Parameters.DeviceIoControl.IoControlCode);
293 break;
294 }
295
297
298 Status = IoCallDriver(Vcb->Vpb->RealDevice, Irp);
299
300 goto end2;
301
302end:
303 Irp->IoStatus.Status = Status;
304
305 if (Status != STATUS_PENDING)
307
308end2:
309 TRACE("returning %08lx\n", Status);
310
311 if (top_level)
313
315
316 return Status;
317}
LONG NTSTATUS
Definition: precomp.h:26
#define VCB_TYPE_VOLUME
Definition: btrfs_drv.h:689
#define VCB_TYPE_CONTROL
Definition: btrfs_drv.h:688
#define VCB_TYPE_FS
Definition: btrfs_drv.h:687
NTSTATUS vol_device_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:755
#define IOCTL_DISK_IS_WRITABLE
Definition: cdrw_usr.h:172
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
bool is_top_level(_In_ PIRP Irp)
Definition: btrfs.c:278
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
static NTSTATUS is_writable(device_extension *Vcb)
Definition: devctrl.c:43
static NTSTATUS control_ioctl(PIRP Irp)
Definition: devctrl.c:226
static NTSTATUS mountdev_query_stable_guid(device_extension *Vcb, PIRP Irp)
Definition: devctrl.c:27
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
Status
Definition: gdiplustypes.h:25
GLuint GLuint end
Definition: gl.h:1545
#define IOCTL_MOUNTDEV_QUERY_STABLE_GUID
Definition: imports.h:255
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IoCompleteRequest
Definition: irp.c:1240
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define STATUS_PENDING
Definition: ntstatus.h:82
#define Vcb
Definition: cdprocs.h:1415
#define TRACE(s)
Definition: solgame.cpp:4
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define IO_NO_INCREMENT
Definition: iotypes.h:598

◆ control_ioctl()

static NTSTATUS control_ioctl ( PIRP  Irp)
static

Definition at line 226 of file devctrl.c.

226 {
229
230 switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
232 Status = query_filesystems(map_user_buffer(Irp, NormalPagePriority), IrpSp->Parameters.FileSystemControl.OutputBufferLength);
233 break;
234
236 Status = probe_volume(Irp->AssociatedIrp.SystemBuffer, IrpSp->Parameters.FileSystemControl.InputBufferLength, Irp->RequestorMode);
237 break;
238
241 break;
242
243 default:
244 TRACE("unhandled ioctl %lx\n", IrpSp->Parameters.DeviceIoControl.IoControlCode);
246 break;
247 }
248
249 return Status;
250}
static __inline void * map_user_buffer(PIRP Irp, ULONG priority)
Definition: btrfs_drv.h:977
#define IOCTL_BTRFS_QUERY_FILESYSTEMS
Definition: btrfsioctl.h:21
#define IOCTL_BTRFS_UNLOAD
Definition: btrfsioctl.h:39
#define IOCTL_BTRFS_PROBE_VOLUME
Definition: btrfsioctl.h:28
static NTSTATUS probe_volume(void *data, ULONG length, KPROCESSOR_MODE processor_mode)
Definition: devctrl.c:162
static NTSTATUS query_filesystems(void *data, ULONG length)
Definition: devctrl.c:49
static NTSTATUS ioctl_unload(PIRP Irp)
Definition: devctrl.c:215
@ NormalPagePriority
Definition: imports.h:56
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239

Referenced by _Dispatch_type_().

◆ ioctl_unload()

static NTSTATUS ioctl_unload ( PIRP  Irp)
static

Definition at line 215 of file devctrl.c.

215 {
216 if (!SeSinglePrivilegeCheck(RtlConvertLongToLuid(SE_LOAD_DRIVER_PRIVILEGE), Irp->RequestorMode)) {
217 ERR("insufficient privileges\n");
219 }
220
222
223 return STATUS_SUCCESS;
224}
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
#define ERR(fmt,...)
Definition: debug.h:110
void do_shutdown(PIRP Irp)
Definition: btrfs.c:5392
#define SE_LOAD_DRIVER_PRIVILEGE
Definition: security.c:664
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
Definition: priv.c:744
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by control_ioctl().

◆ is_writable()

static NTSTATUS is_writable ( device_extension Vcb)
static

Definition at line 43 of file devctrl.c.

43 {
44 TRACE("IOCTL_DISK_IS_WRITABLE\n");
45
47}
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161

Referenced by _Dispatch_type_().

◆ mountdev_query_stable_guid()

static NTSTATUS mountdev_query_stable_guid ( device_extension Vcb,
PIRP  Irp 
)
static

Definition at line 27 of file devctrl.c.

27 {
28 MOUNTDEV_STABLE_GUID* msg = Irp->UserBuffer;
30
31 TRACE("IOCTL_MOUNTDEV_QUERY_STABLE_GUID\n");
32
33 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_STABLE_GUID))
35
36 RtlCopyMemory(&msg->StableGuid, &Vcb->superblock.uuid, sizeof(GUID));
37
38 Irp->IoStatus.Information = sizeof(MOUNTDEV_STABLE_GUID);
39
40 return STATUS_SUCCESS;
41}
#define msg(x)
Definition: auth_time.c:54
struct _MOUNTDEV_STABLE_GUID MOUNTDEV_STABLE_GUID
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by _Dispatch_type_().

◆ probe_volume()

static NTSTATUS probe_volume ( void data,
ULONG  length,
KPROCESSOR_MODE  processor_mode 
)
static

Definition at line 162 of file devctrl.c.

162 {
164 UNICODE_STRING path, pnp_name;
168 const GUID* guid;
169
170 if (length < sizeof(MOUNTDEV_NAME))
172
173 if (length < offsetof(MOUNTDEV_NAME, Name[0]) + mdn->NameLength)
175
176 TRACE("%.*S\n", (int)(mdn->NameLength / sizeof(WCHAR)), mdn->Name);
177
178 if (!SeSinglePrivilegeCheck(RtlConvertLongToLuid(SE_MANAGE_VOLUME_PRIVILEGE), processor_mode))
180
181 path.Buffer = mdn->Name;
182 path.Length = path.MaximumLength = mdn->NameLength;
183
185 if (!NT_SUCCESS(Status)) {
186 ERR("IoGetDeviceObjectPointer returned %08lx\n", Status);
187 return Status;
188 }
189
191 if (!NT_SUCCESS(Status)) {
192 ERR("get_device_pnp_name returned %08lx\n", Status);
194 return Status;
195 }
196
197 if (RtlCompareMemory(guid, &GUID_DEVINTERFACE_DISK, sizeof(GUID)) == sizeof(GUID)) {
199 if (!NT_SUCCESS(Status))
200 WARN("IOCTL_DISK_UPDATE_PROPERTIES returned %08lx\n", Status);
201 }
202
204
205 volume_removal(&pnp_name);
206
207 if (RtlCompareMemory(guid, &GUID_DEVINTERFACE_DISK, sizeof(GUID)) == sizeof(GUID))
208 disk_arrival(&pnp_name);
209 else
210 volume_arrival(&pnp_name, false);
211
212 return STATUS_SUCCESS;
213}
#define WARN(fmt,...)
Definition: debug.h:112
void disk_arrival(PUNICODE_STRING devpath)
Definition: search.c:460
void volume_removal(PUNICODE_STRING devpath)
Definition: search.c:795
bool volume_arrival(PUNICODE_STRING devpath, bool fve_callback)
Definition: search.c:693
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS get_device_pnp_name(_In_ PDEVICE_OBJECT DeviceObject, _Out_ PUNICODE_STRING pnp_name, _Out_ const GUID **guid)
Definition: btrfs.c:4233
NTSTATUS dev_ioctl(_In_ PDEVICE_OBJECT DeviceObject, _In_ ULONG ControlCode, _In_reads_bytes_opt_(InputBufferSize) PVOID InputBuffer, _In_ ULONG InputBufferSize, _Out_writes_bytes_opt_(OutputBufferSize) PVOID OutputBuffer, _In_ ULONG OutputBufferSize, _In_ bool Override, _Out_opt_ IO_STATUS_BLOCK *iosb)
Definition: btrfs.c:2954
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
const GUID * guid
#define SE_MANAGE_VOLUME_PRIVILEGE
Definition: security.c:682
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define IOCTL_DISK_UPDATE_PROPERTIES
Definition: ntdddisk.h:242
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
#define offsetof(TYPE, MEMBER)
USHORT NameLength
Definition: imports.h:143
WCHAR Name[1]
Definition: imports.h:144
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ObDereferenceObject
Definition: obfuncs.h:203
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by control_ioctl().

◆ query_filesystems()

static NTSTATUS query_filesystems ( void data,
ULONG  length 
)
static

Definition at line 49 of file devctrl.c.

49 {
51 LIST_ENTRY *le, *le2;
53 ULONG itemsize;
54
56
57 if (IsListEmpty(&VcbList)) {
58 if (length < sizeof(btrfs_filesystem)) {
60 goto end;
61 } else {
64 goto end;
65 }
66 }
67
68 le = VcbList.Flink;
69
70 while (le != &VcbList) {
73
74 if (bfs) {
75 bfs->next_entry = itemsize;
76 bfs = (btrfs_filesystem*)((uint8_t*)bfs + itemsize);
77 } else
78 bfs = data;
79
82 goto end;
83 }
84
85 itemsize = offsetof(btrfs_filesystem, device);
87
88 bfs->next_entry = 0;
89 RtlCopyMemory(&bfs->uuid, &Vcb->superblock.uuid, sizeof(BTRFS_UUID));
90
91 ExAcquireResourceSharedLite(&Vcb->tree_lock, true);
92
93 bfs->num_devices = (uint32_t)Vcb->superblock.num_devices;
94
95 bfd = NULL;
96
97 le2 = Vcb->devices.Flink;
98 while (le2 != &Vcb->devices) {
100 MOUNTDEV_NAME mdn;
101
102 if (bfd)
104 else
105 bfd = &bfs->device;
106
108 ExReleaseResourceLite(&Vcb->tree_lock);
110 goto end;
111 }
112
113 itemsize += (ULONG)offsetof(btrfs_filesystem_device, name[0]);
115
116 RtlCopyMemory(&bfd->uuid, &dev->devitem.device_uuid, sizeof(BTRFS_UUID));
117
118 if (dev->devobj) {
119 Status = dev_ioctl(dev->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, &mdn, sizeof(MOUNTDEV_NAME), true, NULL);
121 ExReleaseResourceLite(&Vcb->tree_lock);
122 ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status);
123 goto end;
124 }
125
126 if (mdn.NameLength > length) {
127 ExReleaseResourceLite(&Vcb->tree_lock);
129 goto end;
130 }
131
132 Status = dev_ioctl(dev->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, &bfd->name_length, (ULONG)offsetof(MOUNTDEV_NAME, Name[0]) + mdn.NameLength, true, NULL);
134 ExReleaseResourceLite(&Vcb->tree_lock);
135 ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status);
136 goto end;
137 }
138
139 itemsize += bfd->name_length;
140 length -= bfd->name_length;
141 } else {
142 bfd->missing = true;
143 bfd->name_length = 0;
144 }
145
146 le2 = le2->Flink;
147 }
148
149 ExReleaseResourceLite(&Vcb->tree_lock);
150
151 le = le->Flink;
152 }
153
155
156end:
158
159 return Status;
160}
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
LIST_ENTRY VcbList
Definition: btrfs.c:69
ERESOURCE global_loading_lock
Definition: btrfs.c:70
void * bfd
Definition: i386-dis.c:27
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
BYTE uint8_t
Definition: msvideo1.c:66
#define uint32_t
Definition: nsiface.idl:61
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
uint8_t uuid[16]
Definition: btrfsioctl.h:190
uint32_t next_entry
Definition: btrfsioctl.h:189
uint32_t num_devices
Definition: btrfsioctl.h:191
btrfs_filesystem_device device
Definition: btrfsioctl.h:192
Definition: devices.h:37
Definition: list.h:27
Definition: name.c:39
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59

Referenced by control_ioctl().

Variable Documentation

◆ drvobj

PDRIVER_OBJECT drvobj
extern

Definition at line 65 of file btrfs.c.

◆ global_loading_lock

ERESOURCE global_loading_lock
extern

Definition at line 70 of file btrfs.c.

Referenced by query_filesystems().

◆ VcbList

LIST_ENTRY VcbList
extern

Definition at line 69 of file btrfs.c.

Referenced by query_filesystems().