48DEFINE_GUID(GUID_IO_VOLUME_FVE_STATUS_CHANGE, 0x062998b2, 0xee1f, 0x4b6a, 0xb8, 0x57, 0xe7, 0x6c, 0xbb, 0xe9, 0xa6, 0xda);
78 ERR(
"out of memory\n");
86 path.Buffer[
i] =
'\\';
89 for (
j = 0;
j < 16;
j++) {
95 if (
j == 3 ||
j == 5 ||
j == 7 ||
j == 9) {
116 ERR(
"out of memory\n");
202 ERR(
"out of memory\n");
212 if (
d->devobj == devobj) {
218 ERR(
"out of memory\n");
224 ctx->devpath.Length =
ctx->devpath.MaximumLength =
d->devpath.Length;
228 ctx->devpath.Buffer =
ctx->buf;
231 ctx->devobj = devobj;
232 ctx->work_item = work_item;
257 ERR(
"out of memory\n");
261 d->devpath.Buffer =
d->buf;
262 d->devpath.Length =
d->devpath.MaximumLength = devpath->
Length;
271 if (d2->
devobj == devobj) {
283 devobj, &
d->notification_entry);
285 ERR(
"IoRegisterPlugPlayNotification returned %08lx\n",
Status);
295 if (d2->
devobj == devobj) {
332 ERR(
"%.*S had a sector size of 0, and IOCTL_DISK_GET_DRIVE_GEOMETRY returned %08lx\n",
338 ERR(
"%.*S: IOCTL_DISK_GET_DRIVE_GEOMETRY returned %Iu bytes, expected %Iu\n",
353 ERR(
"out of memory\n");
363 TRACE(
"volume found\n");
370 ERR(
"out of memory\n");
413 TRACE(
"removing drive letter\n");
419 ERR(
"out of memory\n");
432 ERR(
"IOCTL_MOUNTMGR_DELETE_POINTS 1 returned %08lx\n",
Status);
444 ERR(
"out of memory\n");
452 ERR(
"IOCTL_MOUNTMGR_DELETE_POINTS 2 returned %08lx\n",
Status);
466 DRIVE_LAYOUT_INFORMATION_EX* dli =
NULL;
475 ERR(
"IoGetDeviceObjectPointer returned %08lx\n",
Status);
489 ERR(
"out of memory\n");
494 dli, dlisize,
true, &
iosb);
506 &gli,
sizeof(gli),
true,
NULL);
509 ERR(
"error reading length information: %08lx\n",
Status);
516 TRACE(
"IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08lx\n",
Status);
537 if (vc->notification_entry) {
544 if (vde->mounted_device && (!
Vcb || !
Vcb->options.allow_degraded)) {
547 ERR(
"pnp_surprise_removal returned %08lx\n",
Status);
550 if (!
Vcb || !
Vcb->options.allow_degraded) {
553 WARN(
"IoSetDeviceInterfaceState returned %08lx\n",
Status);
562 if (!
Vcb || !
Vcb->options.allow_degraded) {
566 ERR(
"IoGetDeviceObjectPointer returned %08lx\n",
Status);
578 ERR(
"IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n",
Status);
585 ERR(
"out of memory\n");
589 ERR(
"IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n",
Status);
598 WARN(
"mountmgr_add_drive_letter returned %08lx\n",
Status);
611 }
else if (!skip_dev) {
614 le =
Vcb->devices.Flink;
615 while (le != &
Vcb->devices) {
618 if (
dev->devobj == vc->devobj) {
630 vde->device->Characteristics &= ~FILE_REMOVABLE_MEDIA;
658 vde->removing =
true;
662 WARN(
"IoSetDeviceInterfaceState returned %08lx\n",
Status);
664 if (vde->pdo->AttachedDevice)
667 if (vde->open_count == 0)
679 if (vde->name.Buffer)
708 ERR(
"IoGetDeviceObjectPointer returned %08lx\n",
Status);
714 if (devobj->DriverObject ==
drvobj)
719 TRACE(
"IOCTL_VOLUME_ONLINE returned %08lx\n",
Status);
723 ERR(
"IOCTL_DISK_GET_LENGTH_INFO returned %08lx\n",
Status);
730 TRACE(
"IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08lx\n",
Status);
746 bool changed =
false;
757 TRACE(
"removing device\n");
804 devpath->
Buffer[2] ==
'?' && devpath->
Buffer[3] ==
'\\') {
816 bool changed =
false;
827 TRACE(
"removing device\n");
880 ERR(
"out of memory\n");
887 ERR(
"out of memory\n");
892 if (
name->Length > 0) {
895 ERR(
"out of memory\n");
909 context->work_item = work_item;
945 bool need_remove =
false;
967 ERR(
"IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n",
Status);
974 ERR(
"out of memory\n");
978 ERR(
"IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n",
Status);
1008 ERR(
"remove_drive_letter returned %08lx\n",
Status);
1017 static const WCHAR pref[] =
L"\\DosDevices\\";
1023 symlink.
Buffer = (
WCHAR*)(((
uint8_t*)mmps) + mmps->MountPoints[
i].SymbolicLinkNameOffset);
1038 if (symlink.
Length >
sizeof(pref) -
sizeof(
WCHAR) &&
1057 ERR(
"IoGetDeviceObjectPointer returned %08lx\n",
Status);
1075 ERR(
"out of memory\n");
1090 ERR(
"IOCTL_MOUNTMGR_CHANGE_NOTIFY returned %08lx\n",
Status);
1094 TRACE(
"mountmgr changed\n");
1102 ERR(
"IOCTL_MOUNTMGR_QUERY_POINTS 1 returned %08lx\n",
Status);
1103 else if (mmps.
Size > 0) {
1108 ERR(
"out of memory\n");
1115 ERR(
"IOCTL_MOUNTMGR_QUERY_POINTS returned %08lx\n",
Status);
NTSTATUS pnp_surprise_removal(PDEVICE_OBJECT DeviceObject, PIRP Irp)
NTSTATUS(__stdcall * tIoUnregisterPlugPlayNotificationEx)(PVOID NotificationEntry)
NTSTATUS mountmgr_add_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
void add_volume_device(superblock *sb, PUNICODE_STRING devpath, uint64_t length, ULONG disk_num, ULONG part_num)
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
#define _Releases_exclusive_lock_(lock)
#define _Requires_exclusive_lock_held_(lock)
#define NT_SUCCESS(StatCode)
static const WCHAR device_name[]
bool check_superblock_checksum(superblock *sb)
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)
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)
static const uint64_t superblock_addrs[]
void disk_arrival(PUNICODE_STRING devpath)
static void register_fve_callback(PDEVICE_OBJECT devobj, PFILE_OBJECT fileobj, PUNICODE_STRING devpath)
HANDLE mountmgr_thread_handle
NTSTATUS remove_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
static void mountmgr_process_drive(PDEVICE_OBJECT mountmgr, PUNICODE_STRING device_name)
static void mountmgr_updated(PDEVICE_OBJECT mountmgr, MOUNTMGR_MOUNT_POINTS *mmps)
UNICODE_STRING registry_path
static LIST_ENTRY fve_data_list
KEVENT mountmgr_thread_event
void(* pnp_callback)(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)
PDEVICE_OBJECT master_devobj
void volume_removal(PUNICODE_STRING devpath)
tIoUnregisterPlugPlayNotificationEx fIoUnregisterPlugPlayNotificationEx
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 NTSTATUS __stdcall event_notification(PVOID NotificationStructure, PVOID Context)
static void enqueue_pnp_callback(PUNICODE_STRING name, pnp_callback func)
static bool fs_ignored(BTRFS_UUID *uuid)
static void volume_arrival2(PUNICODE_STRING devpath)
const GUID GUID_DEVICE_INTERFACE_ARRIVAL
const GUID GUID_DEVICE_INTERFACE_REMOVAL
#define RemoveEntryList(Entry)
#define InsertTailList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
#define RtlCompareMemory(s1, s2, l)
#define KeReleaseSpinLock(sl, irql)
#define KeAcquireSpinLock(sl, irql)
#define ExAcquireResourceExclusiveLite(res, wait)
#define ExDeleteResourceLite(res)
#define ExAcquireResourceSharedLite(res, wait)
VOID NTAPI KeClearEvent(IN PKEVENT Event)
#define IOCTL_DISK_GET_DRIVE_LAYOUT_EX
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLenum GLuint GLenum GLsizei const GLchar * buf
GLuint GLsizei GLsizei * length
GLfloat GLfloat GLfloat GLfloat h
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
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
#define OBJ_KERNEL_HANDLE
#define OBJ_CASE_INSENSITIVE
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
#define IOCTL_MOUNTMGR_DELETE_POINTS
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
#define IOCTL_DISK_GET_LENGTH_INFO
#define MOUNTMGR_DEVICE_NAME
struct _MOUNTMGR_MOUNT_POINT MOUNTMGR_MOUNT_POINT
static PIO_STATUS_BLOCK iosb
#define InitializeObjectAttributes(p, n, a, r, s)
static ACCESS_MASK const OBJECT_ATTRIBUTES ULONG const UNICODE_STRING ULONG PULONG dispos
#define IOCTL_MOUNTMGR_QUERY_POINTS
#define IOCTL_MOUNTMGR_CHANGE_NOTIFY
#define _Function_class_(x)
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
@ KeyValueFullInformation
#define FILE_READ_ATTRIBUTES
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define REG_OPTION_NON_VOLATILE
#define FILE_REMOVABLE_MEDIA
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
#define IOCTL_VOLUME_ONLINE
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
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)
NTSTATUS NTAPI PsTerminateSystemThread(IN NTSTATUS ExitStatus)
#define STATUS_FVE_LOCKED_VOLUME
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
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)
NTSTATUS NTAPI IoUnregisterPlugPlayNotification(_In_ PVOID NotificationEntry)
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
#define offsetof(TYPE, MEMBER)
#define STATUS_BUFFER_TOO_SMALL
#define STATUS_BUFFER_OVERFLOW
PUNICODE_STRING SymbolicLinkName
struct _LIST_ENTRY * Flink
MOUNTMGR_MOUNT_POINT MountPoints[1]
ULONG NumberOfMountPoints
ULONG SymbolicLinkNameOffset
struct _FILE_OBJECT * FileObject
void * notification_entry
volume_device_extension * vde
#define RtlCopyMemory(Destination, Source, Length)
#define RtlZeroMemory(Destination, Length)
#define CONTAINING_RECORD(address, type, field)
#define STATUS_INSUFFICIENT_RESOURCES
_In_ PDEVICE_OBJECT DeviceObject
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
_In_ PVOID NotificationStructure
@ EventCategoryTargetDeviceChange
#define ObDereferenceObject