ReactOS 0.4.15-dev-7958-gcd0bb1a
search.c File Reference
#include "btrfs_drv.h"
#include <ntddk.h>
#include <ntifs.h>
#include <mountmgr.h>
#include <windef.h>
#include <ntddstor.h>
#include <ntdddisk.h>
#include <ntddvol.h>
#include <initguid.h>
#include <wdmguid.h>
#include <ioevent.h>
Include dependency graph for search.c:

Go to the source code of this file.

Classes

struct  fve_data
 
struct  fve_callback_context
 
struct  pnp_callback_context
 

Typedefs

typedef void(* pnp_callback) (PUNICODE_STRING devpath)
 

Functions

 DEFINE_GUID (GUID_IO_VOLUME_FVE_STATUS_CHANGE, 0x062998b2, 0xee1f, 0x4b6a, 0xb8, 0x57, 0xe7, 0x6c, 0xbb, 0xe9, 0xa6, 0xda)
 
static bool fs_ignored (BTRFS_UUID *uuid)
 
 _Function_class_ (IO_WORKITEM_ROUTINE)
 
static NTSTATUS __stdcall event_notification (PVOID NotificationStructure, PVOID Context)
 
static void register_fve_callback (PDEVICE_OBJECT devobj, PFILE_OBJECT fileobj, PUNICODE_STRING devpath)
 
static bool test_vol (PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, PUNICODE_STRING devpath, DWORD disk_num, DWORD part_num, uint64_t length, bool fve_callback)
 
NTSTATUS remove_drive_letter (PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
 
void disk_arrival (PUNICODE_STRING devpath)
 
void remove_volume_child (_Inout_ _Requires_exclusive_lock_held_(_Curr_->child_lock) _Releases_exclusive_lock_(_Curr_->child_lock) _In_ volume_device_extension *vde, _In_ volume_child *vc, _In_ bool skip_dev)
 
bool volume_arrival (PUNICODE_STRING devpath, bool fve_callback)
 
static void volume_arrival2 (PUNICODE_STRING devpath)
 
void volume_removal (PUNICODE_STRING devpath)
 
static void enqueue_pnp_callback (PUNICODE_STRING name, pnp_callback func)
 
 _Function_class_ (DRIVER_NOTIFICATION_CALLBACK_ROUTINE)
 
static void mountmgr_process_drive (PDEVICE_OBJECT mountmgr, PUNICODE_STRING device_name)
 
static void mountmgr_updated (PDEVICE_OBJECT mountmgr, MOUNTMGR_MOUNT_POINTS *mmps)
 
 _Function_class_ (KSTART_ROUTINE)
 

Variables

ERESOURCE pdo_list_lock
 
LIST_ENTRY pdo_list
 
UNICODE_STRING registry_path
 
KEVENT mountmgr_thread_event
 
HANDLE mountmgr_thread_handle
 
bool shutting_down
 
PDEVICE_OBJECT busobj
 
tIoUnregisterPlugPlayNotificationEx fIoUnregisterPlugPlayNotificationEx
 
ERESOURCE boot_lock
 
PDRIVER_OBJECT drvobj
 
PDEVICE_OBJECT master_devobj
 
static LIST_ENTRY fve_data_list = { &fve_data_list, &fve_data_list }
 
KSPIN_LOCK fve_data_lock
 

Typedef Documentation

◆ pnp_callback

typedef void(* pnp_callback) (PUNICODE_STRING devpath)

Definition at line 43 of file search.c.

Function Documentation

◆ _Function_class_() [1/3]

_Function_class_ ( DRIVER_NOTIFICATION_CALLBACK_ROUTINE  )

Definition at line 914 of file search.c.

915 {
917
919
920 if (RtlCompareMemory(&dicn->Event, &GUID_DEVICE_INTERFACE_ARRIVAL, sizeof(GUID)) == sizeof(GUID))
922 else if (RtlCompareMemory(&dicn->Event, &GUID_DEVICE_INTERFACE_REMOVAL, sizeof(GUID)) == sizeof(GUID))
924
925 return STATUS_SUCCESS;
926}
#define UNUSED(x)
Definition: btrfs_drv.h:82
void volume_removal(PUNICODE_STRING devpath)
Definition: search.c:795
static void enqueue_pnp_callback(PUNICODE_STRING name, pnp_callback func)
Definition: search.c:874
static void volume_arrival2(PUNICODE_STRING devpath)
Definition: search.c:791
const GUID GUID_DEVICE_INTERFACE_ARRIVAL
Definition: deviface.c:14
const GUID GUID_DEVICE_INTERFACE_REMOVAL
Definition: deviface.c:15
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ PVOID NotificationStructure
Definition: iofuncs.h:1206

◆ _Function_class_() [2/3]

_Function_class_ ( IO_WORKITEM_ROUTINE  )

Definition at line 146 of file search.c.

147 {
149
151
152 if (volume_arrival(&ctx->devpath, true)) {
153 KIRQL irql;
154 LIST_ENTRY* le;
155 fve_data* d = NULL;
156
157 // volume no longer locked - unregister notification
158
160
161 le = fve_data_list.Flink;
162 while (le != &fve_data_list) {
164
165 if (d2->devobj == ctx->devobj) {
167 d = d2;
168 break;
169 }
170
171 le = le->Flink;
172 }
173
175
176 if (d) {
177 IoUnregisterPlugPlayNotification(d->notification_entry);
178 ExFreePool(d);
179 }
180 }
181
182 IoFreeWorkItem(ctx->work_item);
184}
#define NULL
Definition: types.h:112
KSPIN_LOCK fve_data_lock
Definition: search.c:63
static LIST_ENTRY fve_data_list
Definition: search.c:62
bool volume_arrival(PUNICODE_STRING devpath, bool fve_callback)
Definition: search.c:693
KIRQL irql
Definition: wave.h:1
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
#define d
Definition: ke_i.h:81
NTSTATUS NTAPI IoUnregisterPlugPlayNotification(_In_ PVOID NotificationEntry)
Definition: pnpnotify.c:479
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY list_entry
Definition: search.c:55
PDEVICE_OBJECT devobj
Definition: search.c:56
Definition: list.h:27
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055

◆ _Function_class_() [3/3]

_Function_class_ ( KSTART_ROUTINE  )

Definition at line 1044 of file search.c.

1045 {
1046 UNICODE_STRING mmdevpath;
1051
1052 UNUSED(context);
1053
1056 if (!NT_SUCCESS(Status)) {
1057 ERR("IoGetDeviceObjectPointer returned %08lx\n", Status);
1058 return;
1059 }
1060
1061 mcni.EpicNumber = 0;
1062
1063 while (true) {
1064 PIRP Irp;
1068
1070
1072 &mcni, sizeof(MOUNTMGR_CHANGE_NOTIFY_INFO), false, &mountmgr_thread_event, &iosb);
1073
1074 if (!Irp) {
1075 ERR("out of memory\n");
1076 break;
1077 }
1078
1080
1081 if (Status == STATUS_PENDING) {
1083 Status = iosb.Status;
1084 }
1085
1086 if (shutting_down)
1087 break;
1088
1089 if (!NT_SUCCESS(Status)) {
1090 ERR("IOCTL_MOUNTMGR_CHANGE_NOTIFY returned %08lx\n", Status);
1091 break;
1092 }
1093
1094 TRACE("mountmgr changed\n");
1095
1096 RtlZeroMemory(&mmp, sizeof(MOUNTMGR_MOUNT_POINT));
1097
1099 false, NULL);
1100
1102 ERR("IOCTL_MOUNTMGR_QUERY_POINTS 1 returned %08lx\n", Status);
1103 else if (mmps.Size > 0) {
1104 MOUNTMGR_MOUNT_POINTS* mmps2;
1105
1107 if (!mmps2) {
1108 ERR("out of memory\n");
1109 break;
1110 }
1111
1113 false, NULL);
1114 if (!NT_SUCCESS(Status))
1115 ERR("IOCTL_MOUNTMGR_QUERY_POINTS returned %08lx\n", Status);
1116 else
1117 mountmgr_updated(mountmgr, mmps2);
1118
1119 ExFreePool(mmps2);
1120 }
1121 }
1122
1124
1126
1128}
LONG NTSTATUS
Definition: precomp.h:26
#define ERR(fmt,...)
Definition: debug.h:110
#define ALLOC_TAG
Definition: btrfs_drv.h:87
_In_ PIRP Irp
Definition: csq.h:116
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
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
bool shutting_down
Definition: btrfs.c:109
HANDLE mountmgr_thread_handle
Definition: btrfs.c:106
static void mountmgr_updated(PDEVICE_OBJECT mountmgr, MOUNTMGR_MOUNT_POINTS *mmps)
Definition: search.c:1014
KEVENT mountmgr_thread_event
Definition: btrfs.c:108
#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 NonPagedPool
Definition: env_spec_w32.h:307
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
Status
Definition: gdiplustypes.h:25
#define MOUNTMGR_DEVICE_NAME
Definition: imports.h:76
static PIO_STATUS_BLOCK iosb
Definition: file.c:98
#define IOCTL_MOUNTMGR_QUERY_POINTS
Definition: mountmgr.h:30
#define IOCTL_MOUNTMGR_CHANGE_NOTIFY
Definition: mountmgr.h:42
#define KernelMode
Definition: asm.h:34
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
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 IoCallDriver
Definition: irp.c:1225
NTSTATUS NTAPI PsTerminateSystemThread(IN NTSTATUS ExitStatus)
Definition: kill.c:1145
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define TRACE(s)
Definition: solgame.cpp:4
Definition: http.c:7252
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
* PFILE_OBJECT
Definition: iotypes.h:1998
@ Executive
Definition: ketypes.h:415
#define ObDereferenceObject
Definition: obfuncs.h:203

◆ DEFINE_GUID()

DEFINE_GUID ( GUID_IO_VOLUME_FVE_STATUS_CHANGE  ,
0x062998b2  ,
0xee1f  ,
0x4b6a  ,
0xb8  ,
0x57  ,
0xe7  ,
0x6c  ,
0xbb  ,
0xe9  ,
0xa6  ,
0xda   
)

◆ disk_arrival()

void disk_arrival ( PUNICODE_STRING  devpath)

Definition at line 460 of file search.c.

460 {
461 PFILE_OBJECT fileobj;
462 PDEVICE_OBJECT devobj;
465 ULONG dlisize;
466 DRIVE_LAYOUT_INFORMATION_EX* dli = NULL;
469
471
472 Status = IoGetDeviceObjectPointer(devpath, FILE_READ_ATTRIBUTES, &fileobj, &devobj);
473 if (!NT_SUCCESS(Status)) {
475 ERR("IoGetDeviceObjectPointer returned %08lx\n", Status);
476 return;
477 }
478
479 dlisize = 0;
480
481 do {
482 dlisize += 1024;
483
484 if (dli)
485 ExFreePool(dli);
486
488 if (!dli) {
489 ERR("out of memory\n");
490 goto end;
491 }
492
494 dli, dlisize, true, &iosb);
495 } while (Status == STATUS_BUFFER_TOO_SMALL);
496
497 // only consider disk as a potential filesystem if it has no partitions
498 if (NT_SUCCESS(Status) && dli->PartitionCount > 0) {
499 ExFreePool(dli);
500 goto end;
501 }
502
503 ExFreePool(dli);
504
506 &gli, sizeof(gli), true, NULL);
507
508 if (!NT_SUCCESS(Status)) {
509 ERR("error reading length information: %08lx\n", Status);
510 goto end;
511 }
512
514 &sdn, sizeof(STORAGE_DEVICE_NUMBER), true, NULL);
515 if (!NT_SUCCESS(Status)) {
516 TRACE("IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08lx\n", Status);
517 sdn.DeviceNumber = 0xffffffff;
518 sdn.PartitionNumber = 0;
519 } else
520 TRACE("DeviceType = %lu, DeviceNumber = %lu, PartitionNumber = %lu\n", sdn.DeviceType, sdn.DeviceNumber, sdn.PartitionNumber);
521
522 test_vol(devobj, fileobj, devpath, sdn.DeviceNumber, sdn.PartitionNumber,
523 gli.Length.QuadPart, false);
524
525end:
526 ObDereferenceObject(fileobj);
527
529}
#define TRUE
Definition: types.h:120
static bool test_vol(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, PUNICODE_STRING devpath, DWORD disk_num, DWORD part_num, uint64_t length, bool fve_callback)
Definition: search.c:311
ERESOURCE boot_lock
Definition: btrfs.c:110
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
#define PagedPool
Definition: env_spec_w32.h:308
#define IOCTL_DISK_GET_DRIVE_LAYOUT_EX
Definition: ntddk_ex.h:207
GLuint GLuint end
Definition: gl.h:1545
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:143
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
LARGE_INTEGER Length
Definition: winioctl.h:560
DEVICE_TYPE DeviceType
Definition: ntddstor.h:324
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by probe_volume().

◆ enqueue_pnp_callback()

static void enqueue_pnp_callback ( PUNICODE_STRING  name,
pnp_callback  func 
)
static

Definition at line 874 of file search.c.

874 {
875 PIO_WORKITEM work_item;
877
879 if (!work_item) {
880 ERR("out of memory\n");
881 return;
882 }
883
885
886 if (!context) {
887 ERR("out of memory\n");
888 IoFreeWorkItem(work_item);
889 return;
890 }
891
892 if (name->Length > 0) {
893 context->name.Buffer = ExAllocatePoolWithTag(PagedPool, name->Length, ALLOC_TAG);
894 if (!context->name.Buffer) {
895 ERR("out of memory\n");
897 IoFreeWorkItem(work_item);
898 return;
899 }
900
901 RtlCopyMemory(context->name.Buffer, name->Buffer, name->Length);
902 context->name.Length = context->name.MaximumLength = name->Length;
903 } else {
904 context->name.Length = context->name.MaximumLength = 0;
905 context->name.Buffer = NULL;
906 }
907
908 context->func = func;
909 context->work_item = work_item;
910
911 IoQueueWorkItem(work_item, do_pnp_callback, DelayedWorkQueue, context);
912}
PDEVICE_OBJECT master_devobj
Definition: btrfs.c:66
GLenum func
Definition: glext.h:6028
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
Definition: name.c:39
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
@ DelayedWorkQueue
Definition: extypes.h:190

Referenced by _Function_class_().

◆ event_notification()

static NTSTATUS __stdcall event_notification ( PVOID  NotificationStructure,
PVOID  Context 
)
static

Definition at line 186 of file search.c.

186 {
188 PDEVICE_OBJECT devobj = Context;
189 PIO_WORKITEM work_item;
191 LIST_ENTRY* le;
192 KIRQL irql;
193
194 if (RtlCompareMemory(&tdrn->Event, &GUID_IO_VOLUME_FVE_STATUS_CHANGE, sizeof(GUID)) != sizeof(GUID))
195 return STATUS_SUCCESS;
196
197 /* The FVE event has trailing data, presumably telling us whether the volume has
198 * been unlocked or whatever, but unfortunately it's undocumented! */
199
201 if (!work_item) {
202 ERR("out of memory\n");
203 return STATUS_SUCCESS;
204 }
205
207
208 le = fve_data_list.Flink;
209 while (le != &fve_data_list) {
211
212 if (d->devobj == devobj) {
214 ALLOC_TAG);
215
216 if (!ctx) {
218 ERR("out of memory\n");
219 IoFreeWorkItem(work_item);
220 return STATUS_SUCCESS;
221 }
222
223 RtlCopyMemory(ctx->buf, d->devpath.Buffer, d->devpath.Length);
224 ctx->devpath.Length = ctx->devpath.MaximumLength = d->devpath.Length;
225
227
228 ctx->devpath.Buffer = ctx->buf;
229
230 ctx->fileobj = tdrn->FileObject;
231 ctx->devobj = devobj;
232 ctx->work_item = work_item;
233
234 IoQueueWorkItem(work_item, fve_callback, DelayedWorkQueue, ctx);
235
236 return STATUS_SUCCESS;
237 }
238
239 le = le->Flink;
240 }
241
243
244 IoFreeWorkItem(work_item);
245
246 return STATUS_SUCCESS;
247}
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define offsetof(TYPE, MEMBER)
struct _FILE_OBJECT * FileObject
Definition: iotypes.h:1021

Referenced by register_fve_callback().

◆ fs_ignored()

static bool fs_ignored ( BTRFS_UUID uuid)
static

Definition at line 65 of file search.c.

65 {
66 UNICODE_STRING path, ignoreus;
70 ULONG dispos, retlen, kvfilen, i, j;
71 HANDLE h;
72 bool ret = false;
73
74 path.Length = path.MaximumLength = registry_path.Length + (37 * sizeof(WCHAR));
75
77 if (!path.Buffer) {
78 ERR("out of memory\n");
79 return false;
80 }
81
83
84 i = registry_path.Length / sizeof(WCHAR);
85
86 path.Buffer[i] = '\\';
87 i++;
88
89 for (j = 0; j < 16; j++) {
90 path.Buffer[i] = hex_digit((uuid->uuid[j] & 0xF0) >> 4);
91 path.Buffer[i+1] = hex_digit(uuid->uuid[j] & 0xF);
92
93 i += 2;
94
95 if (j == 3 || j == 5 || j == 7 || j == 9) {
96 path.Buffer[i] = '-';
97 i++;
98 }
99 }
100
102
103 Status = ZwCreateKey(&h, KEY_QUERY_VALUE, &oa, 0, NULL, REG_OPTION_NON_VOLATILE, &dispos);
104
105 if (!NT_SUCCESS(Status)) {
106 TRACE("ZwCreateKey returned %08lx\n", Status);
107 ExFreePool(path.Buffer);
108 return false;
109 }
110
111 RtlInitUnicodeString(&ignoreus, L"Ignore");
112
113 kvfilen = (ULONG)offsetof(KEY_VALUE_FULL_INFORMATION, Name[0]) + (255 * sizeof(WCHAR));
114 kvfi = ExAllocatePoolWithTag(PagedPool, kvfilen, ALLOC_TAG);
115 if (!kvfi) {
116 ERR("out of memory\n");
117 ZwClose(h);
118 ExFreePool(path.Buffer);
119 return false;
120 }
121
122 Status = ZwQueryValueKey(h, &ignoreus, KeyValueFullInformation, kvfi, kvfilen, &retlen);
123 if (NT_SUCCESS(Status)) {
124 if (kvfi->Type == REG_DWORD && kvfi->DataLength >= sizeof(uint32_t)) {
125 uint32_t* pr = (uint32_t*)((uint8_t*)kvfi + kvfi->DataOffset);
126
127 ret = *pr;
128 }
129 }
130
131 ZwClose(h);
132 ExFreePool(kvfi);
133 ExFreePool(path.Buffer);
134
135 return ret;
136}
#define hex_digit(c)
Definition: btrfs_drv.h:1748
UINT32 uint32_t
Definition: types.h:75
UNICODE_STRING registry_path
Definition: btrfs.c:89
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
Definition: msctf.idl:550
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
static ACCESS_MASK const OBJECT_ATTRIBUTES ULONG const UNICODE_STRING ULONG PULONG dispos
Definition: reg.c:132
BYTE uint8_t
Definition: msvideo1.c:66
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
@ KeyValueFullInformation
Definition: nt_native.h:1181
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define L(x)
Definition: ntvdm.h:50
#define REG_DWORD
Definition: sdbapi.c:596
int ret
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by test_vol().

◆ mountmgr_process_drive()

static void mountmgr_process_drive ( PDEVICE_OBJECT  mountmgr,
PUNICODE_STRING  device_name 
)
static

Definition at line 942 of file search.c.

942 {
944 LIST_ENTRY* le;
945 bool need_remove = false;
946 volume_child* vc2 = NULL;
947
949
950 le = pdo_list.Flink;
951 while (le != &pdo_list) {
953 LIST_ENTRY* le2;
954
956
957 le2 = pdode->children.Flink;
958
959 while (le2 != &pdode->children) {
961
962 if (vc->devobj) {
963 MOUNTDEV_NAME mdn;
964
967 ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status);
968 else {
969 MOUNTDEV_NAME* mdn2;
970 ULONG mdnsize = (ULONG)offsetof(MOUNTDEV_NAME, Name[0]) + mdn.NameLength;
971
973 if (!mdn2)
974 ERR("out of memory\n");
975 else {
976 Status = dev_ioctl(vc->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, mdn2, mdnsize, true, NULL);
977 if (!NT_SUCCESS(Status))
978 ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status);
979 else {
980 if (mdn2->NameLength == device_name->Length && RtlCompareMemory(mdn2->Name, device_name->Buffer, device_name->Length) == device_name->Length) {
981 vc2 = vc;
982 need_remove = true;
983 break;
984 }
985 }
986
987 ExFreePool(mdn2);
988 }
989 }
990 }
991
992 le2 = le2->Flink;
993 }
994
996
997 if (need_remove)
998 break;
999
1000 le = le->Flink;
1001 }
1002
1004
1005 if (need_remove) {
1007 if (!NT_SUCCESS(Status))
1008 ERR("remove_drive_letter returned %08lx\n", Status);
1009 else
1010 vc2->had_drive_letter = true;
1011 }
1012}
static const WCHAR device_name[]
Definition: btrfs.c:60
NTSTATUS remove_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
Definition: search.c:407
LIST_ENTRY pdo_list
Definition: btrfs.c:104
ERESOURCE pdo_list_lock
Definition: btrfs.c:103
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
USHORT NameLength
Definition: imports.h:143
WCHAR Name[1]
Definition: imports.h:144
ERESOURCE child_lock
Definition: btrfs_drv.h:896
LIST_ENTRY children
Definition: btrfs_drv.h:897
PDEVICE_OBJECT devobj
Definition: btrfs_drv.h:857
bool had_drive_letter
Definition: btrfs_drv.h:862

Referenced by mountmgr_updated().

◆ mountmgr_updated()

static void mountmgr_updated ( PDEVICE_OBJECT  mountmgr,
MOUNTMGR_MOUNT_POINTS mmps 
)
static

Definition at line 1014 of file search.c.

1014 {
1015 ULONG i;
1016
1017 static const WCHAR pref[] = L"\\DosDevices\\";
1018
1019 for (i = 0; i < mmps->NumberOfMountPoints; i++) {
1020 UNICODE_STRING symlink, device_name;
1021
1022 if (mmps->MountPoints[i].SymbolicLinkNameOffset != 0) {
1023 symlink.Buffer = (WCHAR*)(((uint8_t*)mmps) + mmps->MountPoints[i].SymbolicLinkNameOffset);
1024 symlink.Length = symlink.MaximumLength = mmps->MountPoints[i].SymbolicLinkNameLength;
1025 } else {
1026 symlink.Buffer = NULL;
1027 symlink.Length = symlink.MaximumLength = 0;
1028 }
1029
1030 if (mmps->MountPoints[i].DeviceNameOffset != 0) {
1031 device_name.Buffer = (WCHAR*)(((uint8_t*)mmps) + mmps->MountPoints[i].DeviceNameOffset);
1032 device_name.Length = device_name.MaximumLength = mmps->MountPoints[i].DeviceNameLength;
1033 } else {
1034 device_name.Buffer = NULL;
1035 device_name.Length = device_name.MaximumLength = 0;
1036 }
1037
1038 if (symlink.Length > sizeof(pref) - sizeof(WCHAR) &&
1039 RtlCompareMemory(symlink.Buffer, pref, sizeof(pref) - sizeof(WCHAR)) == sizeof(pref) - sizeof(WCHAR))
1041 }
1042}
static void mountmgr_process_drive(PDEVICE_OBJECT mountmgr, PUNICODE_STRING device_name)
Definition: search.c:942
MOUNTMGR_MOUNT_POINT MountPoints[1]
Definition: imports.h:177
USHORT DeviceNameLength
Definition: imports.h:171
ULONG SymbolicLinkNameOffset
Definition: imports.h:166
USHORT MaximumLength
Definition: env_spec_w32.h:370

Referenced by _Function_class_().

◆ register_fve_callback()

static void register_fve_callback ( PDEVICE_OBJECT  devobj,
PFILE_OBJECT  fileobj,
PUNICODE_STRING  devpath 
)
static

Definition at line 249 of file search.c.

250 {
252 KIRQL irql;
253 LIST_ENTRY* le;
254
256 if (!d) {
257 ERR("out of memory\n");
258 return;
259 }
260
261 d->devpath.Buffer = d->buf;
262 d->devpath.Length = d->devpath.MaximumLength = devpath->Length;
263 RtlCopyMemory(d->devpath.Buffer, devpath->Buffer, devpath->Length);
264
266
267 le = fve_data_list.Flink;
268 while (le != &fve_data_list) {
270
271 if (d2->devobj == devobj) {
273 ExFreePool(d);
274 return;
275 }
276
277 le = le->Flink;
278 }
279
281
283 devobj, &d->notification_entry);
284 if (!NT_SUCCESS(Status)) {
285 ERR("IoRegisterPlugPlayNotification returned %08lx\n", Status);
286 return;
287 }
288
290
291 le = fve_data_list.Flink;
292 while (le != &fve_data_list) {
294
295 if (d2->devobj == devobj) {
297 IoUnregisterPlugPlayNotification(d->notification_entry);
298 ExFreePool(d);
299 return;
300 }
301
302 le = le->Flink;
303 }
304
305 d->devobj = devobj;
306 InsertTailList(&fve_data_list, &d->list_entry);
307
309}
PDRIVER_OBJECT drvobj
Definition: btrfs.c:65
static NTSTATUS __stdcall event_notification(PVOID NotificationStructure, PVOID Context)
Definition: search.c:186
#define InsertTailList(ListHead, Entry)
NTSTATUS NTAPI IoRegisterPlugPlayNotification(_In_ IO_NOTIFICATION_EVENT_CATEGORY EventCategory, _In_ ULONG EventCategoryFlags, _In_opt_ PVOID EventCategoryData, _In_ PDRIVER_OBJECT DriverObject, _In_ PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine, _Inout_opt_ PVOID Context, _Out_ PVOID *NotificationEntry)
Definition: pnpnotify.c:345
@ EventCategoryTargetDeviceChange
Definition: iotypes.h:1227

Referenced by test_vol().

◆ remove_drive_letter()

NTSTATUS remove_drive_letter ( PDEVICE_OBJECT  mountmgr,
PUNICODE_STRING  devpath 
)

Definition at line 407 of file search.c.

407 {
410 ULONG mmpsize;
411 MOUNTMGR_MOUNT_POINTS mmps1, *mmps2;
412
413 TRACE("removing drive letter\n");
414
415 mmpsize = sizeof(MOUNTMGR_MOUNT_POINT) + devpath->Length;
416
418 if (!mmp) {
419 ERR("out of memory\n");
421 }
422
423 RtlZeroMemory(mmp, mmpsize);
424
426 mmp->DeviceNameLength = devpath->Length;
427 RtlCopyMemory(&mmp[1], devpath->Buffer, devpath->Length);
428
429 Status = dev_ioctl(mountmgr, IOCTL_MOUNTMGR_DELETE_POINTS, mmp, mmpsize, &mmps1, sizeof(MOUNTMGR_MOUNT_POINTS), false, NULL);
430
432 ERR("IOCTL_MOUNTMGR_DELETE_POINTS 1 returned %08lx\n", Status);
433 ExFreePool(mmp);
434 return Status;
435 }
436
437 if (Status != STATUS_BUFFER_OVERFLOW || mmps1.Size == 0) {
438 ExFreePool(mmp);
439 return STATUS_NOT_FOUND;
440 }
441
443 if (!mmps2) {
444 ERR("out of memory\n");
445 ExFreePool(mmp);
447 }
448
449 Status = dev_ioctl(mountmgr, IOCTL_MOUNTMGR_DELETE_POINTS, mmp, mmpsize, mmps2, mmps1.Size, false, NULL);
450
451 if (!NT_SUCCESS(Status))
452 ERR("IOCTL_MOUNTMGR_DELETE_POINTS 2 returned %08lx\n", Status);
453
454 ExFreePool(mmps2);
455 ExFreePool(mmp);
456
457 return Status;
458}
#define IOCTL_MOUNTMGR_DELETE_POINTS
Definition: imports.h:124
struct _MOUNTMGR_MOUNT_POINT MOUNTMGR_MOUNT_POINT
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158

Referenced by add_device(), do_shutdown(), drive_letter_callback2(), and mountmgr_process_drive().

◆ remove_volume_child()

void remove_volume_child ( _Inout_ _Requires_exclusive_lock_held_(_Curr_->child_lock) _Releases_exclusive_lock_(_Curr_->child_lock) _In_ volume_device_extension vde,
_In_ volume_child vc,
_In_ bool  skip_dev 
)

Definition at line 531 of file search.c.

532 {
534 pdo_device_extension* pdode = vde->pdode;
535 device_extension* Vcb = vde->mounted_device ? vde->mounted_device->DeviceExtension : NULL;
536
537 if (vc->notification_entry) {
539 fIoUnregisterPlugPlayNotificationEx(vc->notification_entry);
540 else
541 IoUnregisterPlugPlayNotification(vc->notification_entry);
542 }
543
544 if (vde->mounted_device && (!Vcb || !Vcb->options.allow_degraded)) {
545 Status = pnp_surprise_removal(vde->mounted_device, NULL);
546 if (!NT_SUCCESS(Status))
547 ERR("pnp_surprise_removal returned %08lx\n", Status);
548 }
549
550 if (!Vcb || !Vcb->options.allow_degraded) {
551 Status = IoSetDeviceInterfaceState(&vde->bus_name, false);
552 if (!NT_SUCCESS(Status))
553 WARN("IoSetDeviceInterfaceState returned %08lx\n", Status);
554 }
555
556 if (pdode->children_loaded > 0) {
557 UNICODE_STRING mmdevpath;
560 LIST_ENTRY* le;
561
562 if (!Vcb || !Vcb->options.allow_degraded) {
565 if (!NT_SUCCESS(Status))
566 ERR("IoGetDeviceObjectPointer returned %08lx\n", Status);
567 else {
568 le = pdode->children.Flink;
569
570 while (le != &pdode->children) {
572
573 if (vc2->had_drive_letter) { // re-add entry to mountmgr
574 MOUNTDEV_NAME mdn;
575
578 ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status);
579 else {
580 MOUNTDEV_NAME* mdn2;
581 ULONG mdnsize = (ULONG)offsetof(MOUNTDEV_NAME, Name[0]) + mdn.NameLength;
582
583 mdn2 = ExAllocatePoolWithTag(PagedPool, mdnsize, ALLOC_TAG);
584 if (!mdn2)
585 ERR("out of memory\n");
586 else {
587 Status = dev_ioctl(vc2->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, mdn2, mdnsize, true, NULL);
588 if (!NT_SUCCESS(Status))
589 ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status);
590 else {
592
593 name.Buffer = mdn2->Name;
594 name.Length = name.MaximumLength = mdn2->NameLength;
595
597 if (!NT_SUCCESS(Status))
598 WARN("mountmgr_add_drive_letter returned %08lx\n", Status);
599 }
600
601 ExFreePool(mdn2);
602 }
603 }
604 }
605
606 le = le->Flink;
607 }
608
610 }
611 } else if (!skip_dev) {
612 ExAcquireResourceExclusiveLite(&Vcb->tree_lock, true);
613
614 le = Vcb->devices.Flink;
615 while (le != &Vcb->devices) {
617
618 if (dev->devobj == vc->devobj) {
619 dev->devobj = NULL; // mark as missing
620 break;
621 }
622
623 le = le->Flink;
624 }
625
626 ExReleaseResourceLite(&Vcb->tree_lock);
627 }
628
629 if (vde->device->Characteristics & FILE_REMOVABLE_MEDIA) {
630 vde->device->Characteristics &= ~FILE_REMOVABLE_MEDIA;
631
632 le = pdode->children.Flink;
633 while (le != &pdode->children) {
635
636 if (vc2 != vc && vc2->devobj->Characteristics & FILE_REMOVABLE_MEDIA) {
637 vde->device->Characteristics |= FILE_REMOVABLE_MEDIA;
638 break;
639 }
640
641 le = le->Flink;
642 }
643 }
644 }
645
646 ObDereferenceObject(vc->fileobj);
647 ExFreePool(vc->pnp_name.Buffer);
648 RemoveEntryList(&vc->list_entry);
649 ExFreePool(vc);
650
651 pdode->children_loaded--;
652
653 if (pdode->children_loaded == 0) { // remove volume device
654 bool remove = false;
655
657
658 vde->removing = true;
659
660 Status = IoSetDeviceInterfaceState(&vde->bus_name, false);
661 if (!NT_SUCCESS(Status))
662 WARN("IoSetDeviceInterfaceState returned %08lx\n", Status);
663
664 if (vde->pdo->AttachedDevice)
665 IoDetachDevice(vde->pdo);
666
667 if (vde->open_count == 0)
668 remove = true;
669
671
672 if (!no_pnp) {
674
676 }
677
678 if (remove) {
679 if (vde->name.Buffer)
680 ExFreePool(vde->name.Buffer);
681
682 if (Vcb)
683 Vcb->vde = NULL;
684
686
687 IoDeleteDevice(vde->device);
688 }
689 } else
691}
#define WARN(fmt,...)
Definition: debug.h:112
NTSTATUS pnp_surprise_removal(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pnp.c:77
NTSTATUS mountmgr_add_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
Definition: volume.c:832
uint32_t no_pnp
Definition: btrfs.c:87
tIoUnregisterPlugPlayNotificationEx fIoUnregisterPlugPlayNotificationEx
Definition: btrfs.c:95
PDEVICE_OBJECT busobj
Definition: btrfs.c:66
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define ExDeleteResourceLite(res)
Definition: env_spec_w32.h:647
int remove
Definition: msacm.c:1366
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
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
#define Vcb
Definition: cdprocs.h:1415
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:1772
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PDEVICE_OBJECT buspdo
Definition: btrfs_drv.h:848
Definition: devices.h:37
uint64_t children_loaded
Definition: btrfs_drv.h:895
LIST_ENTRY list_entry
Definition: btrfs_drv.h:899
@ BusRelations
Definition: iotypes.h:2152

Referenced by mount_vol(), verify_device(), volume_arrival(), and volume_removal().

◆ test_vol()

static bool test_vol ( PDEVICE_OBJECT  DeviceObject,
PFILE_OBJECT  FileObject,
PUNICODE_STRING  devpath,
DWORD  disk_num,
DWORD  part_num,
uint64_t  length,
bool  fve_callback 
)
static

Definition at line 311 of file search.c.

313 {
315 ULONG toread;
316 uint8_t* data = NULL;
318 bool ret = true;
319
320 TRACE("%.*S\n", (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer);
321
322 sector_size = DeviceObject->SectorSize;
323
324 if (sector_size == 0) {
325 DISK_GEOMETRY geometry;
327
329 &geometry, sizeof(DISK_GEOMETRY), true, &iosb);
330
331 if (!NT_SUCCESS(Status)) {
332 ERR("%.*S had a sector size of 0, and IOCTL_DISK_GET_DRIVE_GEOMETRY returned %08lx\n",
333 (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer, Status);
334 goto deref;
335 }
336
337 if (iosb.Information < sizeof(DISK_GEOMETRY)) {
338 ERR("%.*S: IOCTL_DISK_GET_DRIVE_GEOMETRY returned %Iu bytes, expected %Iu\n",
339 (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer, iosb.Information, sizeof(DISK_GEOMETRY));
340 }
341
342 sector_size = geometry.BytesPerSector;
343
344 if (sector_size == 0) {
345 ERR("%.*S had a sector size of 0\n", (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer);
346 goto deref;
347 }
348 }
349
350 toread = (ULONG)sector_align(sizeof(superblock), sector_size);
352 if (!data) {
353 ERR("out of memory\n");
354 goto deref;
355 }
356
358
361
363 TRACE("volume found\n");
364
365 if (length >= superblock_addrs[1] + toread) {
366 ULONG i = 1;
367
369 if (!sb2) {
370 ERR("out of memory\n");
371 goto deref;
372 }
373
374 while (superblock_addrs[i] > 0 && length >= superblock_addrs[i] + toread) {
376
377 if (NT_SUCCESS(Status) && sb2->magic == BTRFS_MAGIC) {
379 RtlCopyMemory(sb, sb2, toread);
380 }
381
382 i++;
383 }
384
385 ExFreePool(sb2);
386 }
387
388 if (!fs_ignored(&sb->uuid)) {
389 DeviceObject->Flags &= ~DO_VERIFY_VOLUME;
390 add_volume_device(sb, devpath, length, disk_num, part_num);
391 }
392 }
393 } else if (Status == STATUS_FVE_LOCKED_VOLUME) {
394 if (fve_callback)
395 ret = false;
396 else
398 }
399
400deref:
401 if (data)
403
404 return ret;
405}
#define BTRFS_MAGIC
Definition: btrfs.h:42
void add_volume_device(superblock *sb, PUNICODE_STRING devpath, uint64_t length, ULONG disk_num, ULONG part_num)
Definition: volume.c:1077
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
static uint64_t __inline sector_align(uint64_t n, uint64_t a)
superblock * sb
Definition: btrfs.c:4261
bool check_superblock_checksum(superblock *sb)
Definition: btrfs.c:2825
NTSTATUS sync_read_phys(_In_ PDEVICE_OBJECT DeviceObject, _In_ PFILE_OBJECT FileObject, _In_ uint64_t StartingOffset, _In_ ULONG Length, _Out_writes_bytes_(Length) PUCHAR Buffer, _In_ bool override)
Definition: btrfs.c:2732
static const uint64_t superblock_addrs[]
Definition: btrfs.h:16
static void register_fve_callback(PDEVICE_OBJECT devobj, PFILE_OBJECT fileobj, PUNICODE_STRING devpath)
Definition: search.c:249
static bool fs_ignored(BTRFS_UUID *uuid)
Definition: search.c:65
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
__u8 sector_size[2]
Definition: mkdosfs.c:3
u32_t magic(void)
#define STATUS_FVE_LOCKED_VOLUME
Definition: ntstatus.h:1454
ULONG BytesPerSector
Definition: ntdddisk.h:409
BTRFS_UUID uuid
Definition: btrfs.h:225
uint64_t magic
Definition: btrfs.h:228
uint64_t generation
Definition: btrfs.h:229
unsigned char * PUCHAR
Definition: typedefs.h:53

Referenced by disk_arrival(), and volume_arrival().

◆ volume_arrival()

bool volume_arrival ( PUNICODE_STRING  devpath,
bool  fve_callback 
)

Definition at line 693 of file search.c.

693 {
695 PFILE_OBJECT fileobj;
696 PDEVICE_OBJECT devobj;
699 bool ret = true;
700
701 TRACE("%.*S\n", (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer);
702
704
705 Status = IoGetDeviceObjectPointer(devpath, FILE_READ_ATTRIBUTES, &fileobj, &devobj);
706 if (!NT_SUCCESS(Status)) {
708 ERR("IoGetDeviceObjectPointer returned %08lx\n", Status);
709 return false;
710 }
711
712 // make sure we're not processing devices we've created ourselves
713
714 if (devobj->DriverObject == drvobj)
715 goto end;
716
717 Status = dev_ioctl(devobj, IOCTL_VOLUME_ONLINE, NULL, 0, NULL, 0, true, NULL);
718 if (!NT_SUCCESS(Status))
719 TRACE("IOCTL_VOLUME_ONLINE returned %08lx\n", Status);
720
721 Status = dev_ioctl(devobj, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &gli, sizeof(gli), true, NULL);
722 if (!NT_SUCCESS(Status)) {
723 ERR("IOCTL_DISK_GET_LENGTH_INFO returned %08lx\n", Status);
724 goto end;
725 }
726
728 &sdn, sizeof(STORAGE_DEVICE_NUMBER), true, NULL);
729 if (!NT_SUCCESS(Status)) {
730 TRACE("IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08lx\n", Status);
731 sdn.DeviceNumber = 0xffffffff;
732 sdn.PartitionNumber = 0;
733 } else
734 TRACE("DeviceType = %lu, DeviceNumber = %lu, PartitionNumber = %lu\n", sdn.DeviceType, sdn.DeviceNumber, sdn.PartitionNumber);
735
736 // If we've just added a partition to a whole-disk filesystem, unmount it
737 if (sdn.DeviceNumber != 0xffffffff && sdn.PartitionNumber != 0) {
738 LIST_ENTRY* le;
739
741
742 le = pdo_list.Flink;
743 while (le != &pdo_list) {
745 LIST_ENTRY* le2;
746 bool changed = false;
747
748 if (pdode->vde) {
750
751 le2 = pdode->children.Flink;
752 while (le2 != &pdode->children) {
754 LIST_ENTRY* le3 = le2->Flink;
755
756 if (vc->disk_num == sdn.DeviceNumber && vc->part_num == 0) {
757 TRACE("removing device\n");
758
759 remove_volume_child(pdode->vde, vc, false);
760 changed = true;
761
762 break;
763 }
764
765 le2 = le3;
766 }
767
768 if (!changed)
770 else
771 break;
772 }
773
774 le = le->Flink;
775 }
776
778 }
779
780 ret = test_vol(devobj, fileobj, devpath, sdn.DeviceNumber, sdn.PartitionNumber,
781 gli.Length.QuadPart, fve_callback);
782
783end:
784 ObDereferenceObject(fileobj);
785
787
788 return ret;
789}
void remove_volume_child(_Inout_ _Requires_exclusive_lock_held_(_Curr_->child_lock) _Releases_exclusive_lock_(_Curr_->child_lock) _In_ volume_device_extension *vde, _In_ volume_child *vc, _In_ bool skip_dev)
Definition: search.c:531
#define IOCTL_VOLUME_ONLINE
Definition: ntddvol.h:62
volume_device_extension * vde
Definition: btrfs_drv.h:889
ULONG part_num
Definition: btrfs_drv.h:865
ULONG disk_num
Definition: btrfs_drv.h:864

Referenced by _Function_class_(), probe_volume(), and volume_arrival2().

◆ volume_arrival2()

static void volume_arrival2 ( PUNICODE_STRING  devpath)
static

Definition at line 791 of file search.c.

791 {
792 volume_arrival(devpath, false);
793}

Referenced by _Function_class_().

◆ volume_removal()

void volume_removal ( PUNICODE_STRING  devpath)

Definition at line 795 of file search.c.

795 {
796 LIST_ENTRY* le;
797 UNICODE_STRING devpath2;
798
799 TRACE("%.*S\n", (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer);
800
801 devpath2 = *devpath;
802
803 if (devpath->Length > 4 * sizeof(WCHAR) && devpath->Buffer[0] == '\\' && (devpath->Buffer[1] == '\\' || devpath->Buffer[1] == '?') &&
804 devpath->Buffer[2] == '?' && devpath->Buffer[3] == '\\') {
805 devpath2.Buffer = &devpath2.Buffer[3];
806 devpath2.Length -= 3 * sizeof(WCHAR);
807 devpath2.MaximumLength -= 3 * sizeof(WCHAR);
808 }
809
811
812 le = pdo_list.Flink;
813 while (le != &pdo_list) {
815 LIST_ENTRY* le2;
816 bool changed = false;
817
818 if (pdode->vde) {
820
821 le2 = pdode->children.Flink;
822 while (le2 != &pdode->children) {
824 LIST_ENTRY* le3 = le2->Flink;
825
826 if (vc->pnp_name.Length == devpath2.Length && RtlCompareMemory(vc->pnp_name.Buffer, devpath2.Buffer, devpath2.Length) == devpath2.Length) {
827 TRACE("removing device\n");
828
829 if (!vc->boot_volume) {
830 remove_volume_child(pdode->vde, vc, false);
831 changed = true;
832 }
833
834 break;
835 }
836
837 le2 = le3;
838 }
839
840 if (!changed)
842 else
843 break;
844 }
845
846 le = le->Flink;
847 }
848
850}
bool boot_volume
Definition: btrfs_drv.h:866
UNICODE_STRING pnp_name
Definition: btrfs_drv.h:859

Referenced by _Function_class_(), add_device(), and probe_volume().

Variable Documentation

◆ boot_lock

ERESOURCE boot_lock
extern

Definition at line 110 of file btrfs.c.

Referenced by _Function_class_(), disk_arrival(), and volume_arrival().

◆ busobj

PDEVICE_OBJECT busobj
extern

Definition at line 66 of file btrfs.c.

Referenced by remove_volume_child().

◆ drvobj

PDRIVER_OBJECT drvobj
extern

Definition at line 65 of file btrfs.c.

Referenced by register_fve_callback(), and volume_arrival().

◆ fIoUnregisterPlugPlayNotificationEx

tIoUnregisterPlugPlayNotificationEx fIoUnregisterPlugPlayNotificationEx
extern

Definition at line 95 of file btrfs.c.

Referenced by remove_volume_child().

◆ fve_data_list

LIST_ENTRY fve_data_list = { &fve_data_list, &fve_data_list }
static

Definition at line 62 of file search.c.

Referenced by _Function_class_(), event_notification(), and register_fve_callback().

◆ fve_data_lock

KSPIN_LOCK fve_data_lock

Definition at line 63 of file search.c.

Referenced by _Function_class_(), event_notification(), and register_fve_callback().

◆ master_devobj

PDEVICE_OBJECT master_devobj
extern

Definition at line 66 of file btrfs.c.

Referenced by enqueue_pnp_callback(), and event_notification().

◆ mountmgr_thread_event

KEVENT mountmgr_thread_event
extern

Definition at line 108 of file btrfs.c.

Referenced by _Function_class_(), and do_shutdown().

◆ mountmgr_thread_handle

HANDLE mountmgr_thread_handle
extern

Definition at line 106 of file btrfs.c.

Referenced by _Function_class_().

◆ pdo_list

LIST_ENTRY pdo_list
extern

Definition at line 104 of file btrfs.c.

Referenced by mountmgr_process_drive(), volume_arrival(), and volume_removal().

◆ pdo_list_lock

ERESOURCE pdo_list_lock
extern

Definition at line 103 of file btrfs.c.

Referenced by mountmgr_process_drive(), volume_arrival(), and volume_removal().

◆ registry_path

UNICODE_STRING registry_path
extern

Definition at line 89 of file btrfs.c.

Referenced by fs_ignored().

◆ shutting_down

bool shutting_down
extern

Definition at line 109 of file btrfs.c.

Referenced by _Function_class_(), and do_shutdown().