ReactOS 0.4.15-dev-7654-g6bc40d3
volume.c File Reference
#include "btrfs_drv.h"
#include <mountdev.h>
#include <ntddvol.h>
#include <ntddstor.h>
#include <ntdddisk.h>
#include <wdmguid.h>
Include dependency graph for volume.c:

Go to the source code of this file.

Classes

struct  vol_read_context
 
struct  drive_letter_removal
 

Macros

#define IOCTL_VOLUME_IS_DYNAMIC   CTL_CODE(IOCTL_VOLUME_BASE, 18, METHOD_BUFFERED, FILE_ANY_ACCESS)
 
#define IOCTL_VOLUME_POST_ONLINE   CTL_CODE(IOCTL_VOLUME_BASE, 25, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
 

Functions

NTSTATUS vol_create (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
void free_vol (volume_device_extension *vde)
 
NTSTATUS vol_close (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
 _Function_class_ (IO_COMPLETION_ROUTINE)
 
NTSTATUS vol_read (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS vol_write (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
static NTSTATUS vol_query_device_name (volume_device_extension *vde, PIRP Irp)
 
static NTSTATUS vol_query_unique_id (volume_device_extension *vde, PIRP Irp)
 
static NTSTATUS vol_is_dynamic (PIRP Irp)
 
static NTSTATUS vol_check_verify (volume_device_extension *vde)
 
static NTSTATUS vol_get_disk_extents (volume_device_extension *vde, PIRP Irp)
 
static NTSTATUS vol_is_writable (volume_device_extension *vde)
 
static NTSTATUS vol_get_length (volume_device_extension *vde, PIRP Irp)
 
static NTSTATUS vol_get_drive_geometry (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
static NTSTATUS vol_get_gpt_attributes (PIRP Irp)
 
static NTSTATUS vol_get_device_number (volume_device_extension *vde, PIRP Irp)
 
static NTSTATUS vol_ioctl_passthrough (volume_device_extension *vde, PIRP Irp)
 
static NTSTATUS vol_query_stable_guid (volume_device_extension *vde, PIRP Irp)
 
NTSTATUS vol_device_control (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS mountmgr_add_drive_letter (PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
 
 _Function_class_ (DRIVER_NOTIFICATION_CALLBACK_ROUTINE)
 
static bool allow_degraded_mount (BTRFS_UUID *uuid)
 
static void drive_letter_callback2 (pdo_device_extension *pdode, PDEVICE_OBJECT mountmgr)
 
 _Function_class_ (IO_WORKITEM_ROUTINE)
 
void add_volume_device (superblock *sb, PUNICODE_STRING devpath, uint64_t length, ULONG disk_num, ULONG part_num)
 

Variables

PDRIVER_OBJECT drvobj
 
PDEVICE_OBJECT master_devobj
 
PDEVICE_OBJECT busobj
 
ERESOURCE pdo_list_lock
 
LIST_ENTRY pdo_list
 
UNICODE_STRING registry_path
 
tIoUnregisterPlugPlayNotificationEx fIoUnregisterPlugPlayNotificationEx
 

Macro Definition Documentation

◆ IOCTL_VOLUME_IS_DYNAMIC

#define IOCTL_VOLUME_IS_DYNAMIC   CTL_CODE(IOCTL_VOLUME_BASE, 18, METHOD_BUFFERED, FILE_ANY_ACCESS)

Definition at line 25 of file volume.c.

◆ IOCTL_VOLUME_POST_ONLINE

Definition at line 26 of file volume.c.

Function Documentation

◆ _Function_class_() [1/3]

_Function_class_ ( DRIVER_NOTIFICATION_CALLBACK_ROUTINE  )

Definition at line 862 of file volume.c.

863 {
866
867 if (RtlCompareMemory(&tdrn->Event, &GUID_TARGET_DEVICE_QUERY_REMOVE, sizeof(GUID)) == sizeof(GUID)) {
868 TRACE("GUID_TARGET_DEVICE_QUERY_REMOVE\n");
869
870 if (pdode->vde && pdode->vde->mounted_device)
872 }
873
874 return STATUS_SUCCESS;
875}
NTSTATUS pnp_query_remove_device(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pnp.c:23
#define NULL
Definition: types.h:112
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE(s)
Definition: solgame.cpp:4
PDEVICE_OBJECT mounted_device
Definition: btrfs_drv.h:876
volume_device_extension * vde
Definition: btrfs_drv.h:889
_In_ PVOID NotificationStructure
Definition: iofuncs.h:1206

◆ _Function_class_() [2/3]

_Function_class_ ( IO_COMPLETION_ROUTINE  )

Definition at line 132 of file volume.c.

133 {
134 vol_read_context* context = conptr;
135
137
138 context->iosb = Irp->IoStatus;
139 KeSetEvent(&context->Event, 0, false);
140
142}
#define UNUSED(x)
Definition: btrfs_drv.h:82
_In_ PIRP Irp
Definition: csq.h:116
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
Definition: http.c:7252
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055

◆ _Function_class_() [3/3]

_Function_class_ ( IO_WORKITEM_ROUTINE  )

Definition at line 1058 of file volume.c.

1059 {
1061 UNICODE_STRING mmdevpath;
1063 PFILE_OBJECT mountmgrfo;
1064
1066 Status = IoGetDeviceObjectPointer(&mmdevpath, FILE_READ_ATTRIBUTES, &mountmgrfo, &mountmgr);
1067 if (!NT_SUCCESS(Status)) {
1068 ERR("IoGetDeviceObjectPointer returned %08lx\n", Status);
1069 return;
1070 }
1071
1073
1074 ObDereferenceObject(mountmgrfo);
1075}
LONG NTSTATUS
Definition: precomp.h:26
#define ERR(fmt,...)
Definition: debug.h:110
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static void drive_letter_callback2(pdo_device_extension *pdode, PDEVICE_OBJECT mountmgr)
Definition: volume.c:958
Status
Definition: gdiplustypes.h:25
#define MOUNTMGR_DEVICE_NAME
Definition: imports.h:76
#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
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ObDereferenceObject
Definition: obfuncs.h:203

◆ add_volume_device()

void add_volume_device ( superblock sb,
PUNICODE_STRING  devpath,
uint64_t  length,
ULONG  disk_num,
ULONG  part_num 
)

Definition at line 1077 of file volume.c.

1077 {
1079 LIST_ENTRY* le;
1081 volume_child* vc;
1083 UNICODE_STRING devpath2;
1084 bool inserted = false, new_pdo = false;
1085 pdo_device_extension* pdode = NULL;
1086 PDEVICE_OBJECT pdo = NULL;
1087 bool process_drive_letters = false;
1088
1089 if (devpath->Length == 0)
1090 return;
1091
1093
1094 le = pdo_list.Flink;
1095 while (le != &pdo_list) {
1097
1098 if (RtlCompareMemory(&pdode2->uuid, &sb->uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1099 pdode = pdode2;
1100 break;
1101 }
1102
1103 le = le->Flink;
1104 }
1105
1107 if (!NT_SUCCESS(Status)) {
1108 ERR("IoGetDeviceObjectPointer returned %08lx\n", Status);
1110 return;
1111 }
1112
1113 if (!pdode) {
1114 if (no_pnp) {
1115 Status = IoReportDetectedDevice(drvobj, InterfaceTypeUndefined, 0xFFFFFFFF, 0xFFFFFFFF, NULL, NULL, 0, &pdo);
1116
1117 if (!NT_SUCCESS(Status)) {
1118 ERR("IoReportDetectedDevice returned %08lx\n", Status);
1120 return;
1121 }
1122
1124
1125 if (!pdode) {
1126 ERR("out of memory\n");
1128 return;
1129 }
1130 } else {
1133 if (!NT_SUCCESS(Status)) {
1134 ERR("IoCreateDevice returned %08lx\n", Status);
1136 goto fail;
1137 }
1138
1140
1141 pdode = pdo->DeviceExtension;
1142 }
1143
1144 RtlZeroMemory(pdode, sizeof(pdo_device_extension));
1145
1146 pdode->type = VCB_TYPE_PDO;
1147 pdode->pdo = pdo;
1148 pdode->uuid = sb->uuid;
1149
1152 pdode->num_children = sb->num_devices;
1153 pdode->children_loaded = 0;
1154
1155 pdo->Flags &= ~DO_DEVICE_INITIALIZING;
1156 pdo->SectorSize = (USHORT)sb->sector_size;
1157
1159
1160 new_pdo = true;
1161 } else {
1164
1165 le = pdode->children.Flink;
1166 while (le != &pdode->children) {
1168
1169 if (RtlCompareMemory(&vc2->uuid, &sb->dev_item.device_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1170 // duplicate, ignore
1173 goto fail;
1174 }
1175
1176 le = le->Flink;
1177 }
1178 }
1179
1181 if (!vc) {
1182 ERR("out of memory\n");
1183
1186
1187 goto fail;
1188 }
1189
1190 vc->uuid = sb->dev_item.device_uuid;
1191 vc->devid = sb->dev_item.dev_id;
1192 vc->generation = sb->generation;
1194 vc->boot_volume = false;
1195
1197 drvobj, pnp_removal, pdode, &vc->notification_entry);
1198 if (!NT_SUCCESS(Status))
1199 WARN("IoRegisterPlugPlayNotification returned %08lx\n", Status);
1200
1201 vc->devobj = DeviceObject;
1202 vc->fileobj = FileObject;
1203
1204 devpath2 = *devpath;
1205
1206 // The PNP path sometimes begins \\?\ and sometimes \??\. We need to remove this prefix
1207 // so we can compare properly if the device is removed.
1208 if (devpath->Length > 4 * sizeof(WCHAR) && devpath->Buffer[0] == '\\' && (devpath->Buffer[1] == '\\' || devpath->Buffer[1] == '?') &&
1209 devpath->Buffer[2] == '?' && devpath->Buffer[3] == '\\') {
1210 devpath2.Buffer = &devpath2.Buffer[3];
1211 devpath2.Length -= 3 * sizeof(WCHAR);
1212 devpath2.MaximumLength -= 3 * sizeof(WCHAR);
1213 }
1214
1215 vc->pnp_name.Length = vc->pnp_name.MaximumLength = devpath2.Length;
1217
1218 if (vc->pnp_name.Buffer)
1219 RtlCopyMemory(vc->pnp_name.Buffer, devpath2.Buffer, devpath2.Length);
1220 else {
1221 ERR("out of memory\n");
1222 vc->pnp_name.Length = vc->pnp_name.MaximumLength = 0;
1223 }
1224
1225 vc->size = length;
1227 vc->disk_num = disk_num;
1228 vc->part_num = part_num;
1229 vc->had_drive_letter = false;
1230
1231 le = pdode->children.Flink;
1232 while (le != &pdode->children) {
1234
1235 if (vc2->generation < vc->generation) {
1236 if (le == pdode->children.Flink)
1237 pdode->num_children = sb->num_devices;
1238
1240 inserted = true;
1241 break;
1242 }
1243
1244 le = le->Flink;
1245 }
1246
1247 if (!inserted)
1248 InsertTailList(&pdode->children, &vc->list_entry);
1249
1250 pdode->children_loaded++;
1251
1252 if (pdode->vde && pdode->vde->mounted_device) {
1254
1255 ExAcquireResourceExclusiveLite(&Vcb->tree_lock, true);
1256
1257 le = Vcb->devices.Flink;
1258 while (le != &Vcb->devices) {
1260
1261 if (!dev->devobj && RtlCompareMemory(&dev->devitem.device_uuid, &sb->dev_item.device_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1262 dev->devobj = DeviceObject;
1263 dev->disk_num = disk_num;
1264 dev->part_num = part_num;
1265 init_device(Vcb, dev, false);
1266 break;
1267 }
1268
1269 le = le->Flink;
1270 }
1271
1272 ExReleaseResourceLite(&Vcb->tree_lock);
1273 }
1274
1275 if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
1276 pdode->removable = true;
1277
1278 if (pdode->vde && pdode->vde->device)
1279 pdode->vde->device->Characteristics |= FILE_REMOVABLE_MEDIA;
1280 }
1281
1282 if (pdode->num_children == pdode->children_loaded || (pdode->children_loaded == 1 && allow_degraded_mount(&sb->uuid))) {
1283 if ((!new_pdo || !no_pnp) && pdode->vde) {
1284 Status = IoSetDeviceInterfaceState(&pdode->vde->bus_name, true);
1285 if (!NT_SUCCESS(Status))
1286 WARN("IoSetDeviceInterfaceState returned %08lx\n", Status);
1287 }
1288
1289 process_drive_letters = true;
1290 }
1291
1293
1294 if (new_pdo)
1296
1298
1299 if (process_drive_letters)
1300 drive_letter_callback(pdode);
1301
1302 if (new_pdo) {
1303 if (RtlCompareMemory(&sb->uuid, &boot_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID))
1304 boot_add_device(pdo);
1305 else if (no_pnp)
1306 AddDevice(drvobj, pdo);
1307 else {
1310 }
1311 }
1312
1313 return;
1314
1315fail:
1317}
#define WARN(fmt,...)
Definition: debug.h:112
#define ALLOC_TAG
Definition: btrfs_drv.h:87
#define VCB_TYPE_PDO
Definition: btrfs_drv.h:690
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
BTRFS_UUID boot_uuid
Definition: boot.c:33
void boot_add_device(DEVICE_OBJECT *pdo)
Definition: boot.c:318
superblock * sb
Definition: btrfs.c:4261
void init_device(_In_ device_extension *Vcb, _Inout_ device *dev, _In_ bool get_nums)
Definition: btrfs.c:3416
uint32_t no_pnp
Definition: btrfs.c:87
#define BTRFS_SUPERBLOCK_FLAGS_SEEDING
Definition: btrfs.h:128
static bool allow_degraded_mount(BTRFS_UUID *uuid)
Definition: volume.c:877
PDRIVER_OBJECT drvobj
Definition: btrfs.c:65
LIST_ENTRY pdo_list
Definition: btrfs.c:104
ERESOURCE pdo_list_lock
Definition: btrfs.c:103
PDEVICE_OBJECT busobj
Definition: btrfs.c:66
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define ExConvertExclusiveToSharedLite(res)
Definition: env_spec_w32.h:652
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define PagedPool
Definition: env_spec_w32.h:308
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
@ InterfaceTypeUndefined
Definition: hwresource.cpp:136
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
DRIVER_ADD_DEVICE AddDevice
Definition: parport.h:72
unsigned short USHORT
Definition: pedump.c:61
#define Vcb
Definition: cdprocs.h:1415
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:1772
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
NTSTATUS NTAPI IoReportDetectedDevice(_In_ PDRIVER_OBJECT DriverObject, _In_ INTERFACE_TYPE LegacyBusType, _In_ ULONG BusNumber, _In_ ULONG SlotNumber, _In_opt_ PCM_RESOURCE_LIST ResourceList, _In_opt_ PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements, _In_ BOOLEAN ResourceAssigned, _Inout_ PDEVICE_OBJECT *DeviceObject)
Definition: pnpreport.c:148
#define FILE_DEVICE_DISK
Definition: winioctl.h:113
#define true
Definition: stdbool.h:36
BTRFS_UUID device_uuid
Definition: btrfs.h:190
uint64_t dev_id
Definition: btrfs.h:178
PVOID DeviceExtension
Definition: env_spec_w32.h:418
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT MaximumLength
Definition: env_spec_w32.h:370
PDEVICE_OBJECT device
Definition: btrfs_drv.h:875
UNICODE_STRING bus_name
Definition: btrfs_drv.h:879
PDEVICE_OBJECT buspdo
Definition: btrfs_drv.h:848
Definition: devices.h:37
Definition: list.h:27
ERESOURCE child_lock
Definition: btrfs_drv.h:896
PDEVICE_OBJECT pdo
Definition: btrfs_drv.h:890
uint64_t children_loaded
Definition: btrfs_drv.h:895
LIST_ENTRY children
Definition: btrfs_drv.h:897
uint64_t num_children
Definition: btrfs_drv.h:894
LIST_ENTRY list_entry
Definition: btrfs_drv.h:899
uint64_t flags
Definition: btrfs.h:227
uint32_t sector_size
Definition: btrfs.h:238
BTRFS_UUID uuid
Definition: btrfs.h:225
uint64_t generation
Definition: btrfs.h:229
uint64_t num_devices
Definition: btrfs.h:237
DEV_ITEM dev_item
Definition: btrfs.h:251
LIST_ENTRY list_entry
Definition: btrfs_drv.h:867
PFILE_OBJECT fileobj
Definition: btrfs_drv.h:858
uint64_t size
Definition: btrfs_drv.h:860
uint64_t devid
Definition: btrfs_drv.h:855
ULONG part_num
Definition: btrfs_drv.h:865
ULONG disk_num
Definition: btrfs_drv.h:864
void * notification_entry
Definition: btrfs_drv.h:863
bool seeding
Definition: btrfs_drv.h:861
bool boot_volume
Definition: btrfs_drv.h:866
UNICODE_STRING pnp_name
Definition: btrfs_drv.h:859
PDEVICE_OBJECT devobj
Definition: btrfs_drv.h:857
bool had_drive_letter
Definition: btrfs_drv.h:862
uint64_t generation
Definition: btrfs_drv.h:856
BTRFS_UUID uuid
Definition: btrfs_drv.h:854
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
@ BusRelations
Definition: iotypes.h:2152
#define DO_BUS_ENUMERATED_DEVICE
@ EventCategoryTargetDeviceChange
Definition: iotypes.h:1227
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by test_vol().

◆ allow_degraded_mount()

static bool allow_degraded_mount ( BTRFS_UUID uuid)
static

Definition at line 877 of file volume.c.

877 {
878 HANDLE h;
881 UNICODE_STRING path, adus;
883 ULONG i, j, kvfilen, retlen;
885
886 path.Length = path.MaximumLength = registry_path.Length + (37 * sizeof(WCHAR));
888
889 if (!path.Buffer) {
890 ERR("out of memory\n");
891 return false;
892 }
893
895 i = registry_path.Length / sizeof(WCHAR);
896
897 path.Buffer[i] = '\\';
898 i++;
899
900 for (j = 0; j < 16; j++) {
901 path.Buffer[i] = hex_digit((uuid->uuid[j] & 0xF0) >> 4);
902 path.Buffer[i+1] = hex_digit(uuid->uuid[j] & 0xF);
903
904 i += 2;
905
906 if (j == 3 || j == 5 || j == 7 || j == 9) {
907 path.Buffer[i] = '-';
908 i++;
909 }
910 }
911
913
914 kvfilen = (ULONG)offsetof(KEY_VALUE_FULL_INFORMATION, Name[0]) + (255 * sizeof(WCHAR));
915 kvfi = ExAllocatePoolWithTag(PagedPool, kvfilen, ALLOC_TAG);
916 if (!kvfi) {
917 ERR("out of memory\n");
918 ExFreePool(path.Buffer);
919 return false;
920 }
921
922 Status = ZwOpenKey(&h, KEY_QUERY_VALUE, &oa);
924 goto end;
925 else if (!NT_SUCCESS(Status)) {
926 ERR("ZwOpenKey returned %08lx\n", Status);
927 goto end;
928 }
929
930 adus.Buffer = L"AllowDegraded";
931 adus.Length = adus.MaximumLength = sizeof(adus.Buffer) - sizeof(WCHAR);
932
933 if (NT_SUCCESS(ZwQueryValueKey(h, &adus, KeyValueFullInformation, kvfi, kvfilen, &retlen))) {
934 if (kvfi->Type == REG_DWORD && kvfi->DataLength >= sizeof(uint32_t)) {
935 uint32_t* val = (uint32_t*)((uint8_t*)kvfi + kvfi->DataOffset);
936
937 degraded = *val;
938 }
939 }
940
941 ZwClose(h);
942
943end:
944 ExFreePool(kvfi);
945
946 ExFreePool(path.Buffer);
947
948 return degraded;
949}
#define hex_digit(c)
Definition: btrfs_drv.h:1748
UINT32 uint32_t
Definition: types.h:75
uint32_t mount_allow_degraded
Definition: btrfs.c:83
UNICODE_STRING registry_path
Definition: btrfs.c:89
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
GLuint GLuint end
Definition: gl.h:1545
GLuint GLfloat * val
Definition: glext.h:7180
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
BYTE uint8_t
Definition: msvideo1.c:66
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
@ KeyValueFullInformation
Definition: nt_native.h:1181
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define L(x)
Definition: ntvdm.h:50
#define REG_DWORD
Definition: sdbapi.c:596
#define offsetof(TYPE, MEMBER)
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149

Referenced by add_volume_device().

◆ drive_letter_callback2()

static void drive_letter_callback2 ( pdo_device_extension pdode,
PDEVICE_OBJECT  mountmgr 
)
static

Definition at line 958 of file volume.c.

958 {
959 LIST_ENTRY* le;
960 LIST_ENTRY dlrlist;
961
962 InitializeListHead(&dlrlist);
963
965
966 le = pdode->children.Flink;
967
968 while (le != &pdode->children) {
970
972
974 if (!dlr) {
975 ERR("out of memory\n");
976
977 while (!IsListEmpty(&dlrlist)) {
979
980 ExFreePool(dlr->name.Buffer);
981 ExFreePool(dlr);
982 }
983
985 return;
986 }
987
988 dlr->name.Length = dlr->name.MaximumLength = vc->pnp_name.Length + (3 * sizeof(WCHAR));
990
991 if (!dlr->name.Buffer) {
992 ERR("out of memory\n");
993
994 ExFreePool(dlr);
995
996 while (!IsListEmpty(&dlrlist)) {
998
999 ExFreePool(dlr->name.Buffer);
1000 ExFreePool(dlr);
1001 }
1002
1004 return;
1005 }
1006
1007 RtlCopyMemory(dlr->name.Buffer, L"\\??", 3 * sizeof(WCHAR));
1009
1010 dlr->uuid = vc->uuid;
1011
1012 InsertTailList(&dlrlist, &dlr->list_entry);
1013
1014 le = le->Flink;
1015 }
1016
1018
1019 le = dlrlist.Flink;
1020 while (le != &dlrlist) {
1022
1023 dlr->Status = remove_drive_letter(mountmgr, &dlr->name);
1024
1025 if (!NT_SUCCESS(dlr->Status) && dlr->Status != STATUS_NOT_FOUND)
1026 WARN("remove_drive_letter returned %08lx\n", dlr->Status);
1027
1028 le = le->Flink;
1029 }
1030
1031 // set vc->had_drive_letter
1032
1034
1035 while (!IsListEmpty(&dlrlist)) {
1037
1038 le = pdode->children.Flink;
1039
1040 while (le != &pdode->children) {
1042
1043 if (RtlCompareMemory(&vc->uuid, &dlr->uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1045 break;
1046 }
1047
1048 le = le->Flink;
1049 }
1050
1051 ExFreePool(dlr->name.Buffer);
1052 ExFreePool(dlr);
1053 }
1054
1056}
void void void NTSTATUS void NTSTATUS NTSTATUS remove_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
Definition: search.c:407
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define STATUS_NOT_FOUND
Definition: shellext.h:72
NTSTATUS Status
Definition: volume.c:954
LIST_ENTRY list_entry
Definition: volume.c:952
BTRFS_UUID uuid
Definition: volume.c:955
UNICODE_STRING name
Definition: volume.c:953

Referenced by _Function_class_().

◆ free_vol()

void free_vol ( volume_device_extension vde)

Definition at line 50 of file volume.c.

50 {
52
53 vde->dead = true;
54
55 if (vde->mounted_device) {
57
58 Vcb->vde = NULL;
59 }
60
61 if (vde->name.Buffer)
63
64 ExDeleteResourceLite(&vde->pdode->child_lock);
65
66 if (vde->pdo->AttachedDevice)
67 IoDetachDevice(vde->pdo);
68
69 while (!IsListEmpty(&vde->pdode->children)) {
71
72 if (vc->notification_entry) {
75 else
77 }
78
79 if (vc->pnp_name.Buffer)
81
82 ExFreePool(vc);
83 }
84
85 if (no_pnp)
86 ExFreePool(vde->pdode);
87
88 pdo = vde->pdo;
90
91 if (!no_pnp)
92 IoDeleteDevice(pdo);
93}
tIoUnregisterPlugPlayNotificationEx fIoUnregisterPlugPlayNotificationEx
Definition: btrfs.c:95
#define ExDeleteResourceLite(res)
Definition: env_spec_w32.h:647
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
NTSTATUS NTAPI IoUnregisterPlugPlayNotification(_In_ PVOID NotificationEntry)
Definition: pnpnotify.c:479
struct pdo_device_extension * pdode
Definition: btrfs_drv.h:878
UNICODE_STRING name
Definition: btrfs_drv.h:874
PDEVICE_OBJECT pdo
Definition: btrfs_drv.h:877

Referenced by do_shutdown(), and vol_close().

◆ mountmgr_add_drive_letter()

NTSTATUS mountmgr_add_drive_letter ( PDEVICE_OBJECT  mountmgr,
PUNICODE_STRING  devpath 
)

Definition at line 832 of file volume.c.

832 {
834 ULONG mmdltsize;
837
838 mmdltsize = (ULONG)offsetof(MOUNTMGR_DRIVE_LETTER_TARGET, DeviceName[0]) + devpath->Length;
839
840 mmdlt = ExAllocatePoolWithTag(NonPagedPool, mmdltsize, ALLOC_TAG);
841 if (!mmdlt) {
842 ERR("out of memory\n");
844 }
845
846 mmdlt->DeviceNameLength = devpath->Length;
847 RtlCopyMemory(&mmdlt->DeviceName, devpath->Buffer, devpath->Length);
848 TRACE("mmdlt = %.*S\n", (int)(mmdlt->DeviceNameLength / sizeof(WCHAR)), mmdlt->DeviceName);
849
851
852 if (!NT_SUCCESS(Status))
853 ERR("IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER returned %08lx\n", Status);
854 else
855 TRACE("DriveLetterWasAssigned = %u, CurrentDriveLetter = %c\n", mmdli.DriveLetterWasAssigned, mmdli.CurrentDriveLetter);
856
857 ExFreePool(mmdlt);
858
859 return Status;
860}
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 IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER
Definition: mountmgr.h:34
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275

Referenced by finish_removing_device(), and remove_volume_child().

◆ vol_check_verify()

static NTSTATUS vol_check_verify ( volume_device_extension vde)
static

Definition at line 379 of file volume.c.

379 {
380 pdo_device_extension* pdode = vde->pdode;
382 LIST_ENTRY* le;
383
385
386 le = pdode->children.Flink;
387 while (le != &pdode->children) {
389
391 if (!NT_SUCCESS(Status))
392 goto end;
393
394 le = le->Flink;
395 }
396
398
399end:
401
402 return Status;
403}
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
#define IOCTL_STORAGE_CHECK_VERIFY
Definition: ntddstor.h:98

Referenced by vol_device_control().

◆ vol_close()

NTSTATUS vol_close ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 95 of file volume.c.

95 {
96 volume_device_extension* vde = DeviceObject->DeviceExtension;
97 pdo_device_extension* pdode = vde->pdode;
98
99 TRACE("(%p, %p)\n", DeviceObject, Irp);
100
101 Irp->IoStatus.Information = 0;
102
103 if (vde->dead)
104 return STATUS_SUCCESS;
105
107
108 if (vde->dead) {
110 return STATUS_SUCCESS;
111 }
112
114
115 if (InterlockedDecrement(&vde->open_count) == 0 && vde->removing) {
117
118 free_vol(vde);
119 } else
121
123
124 return STATUS_SUCCESS;
125}
#define InterlockedDecrement
Definition: armddk.h:52
void free_vol(volume_device_extension *vde)
Definition: volume.c:50

Referenced by _Dispatch_type_().

◆ vol_create()

NTSTATUS vol_create ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 36 of file volume.c.

36 {
37 volume_device_extension* vde = DeviceObject->DeviceExtension;
38
39 TRACE("(%p, %p)\n", DeviceObject, Irp);
40
41 if (vde->removing)
43
44 Irp->IoStatus.Information = FILE_OPENED;
46
47 return STATUS_SUCCESS;
48}
#define InterlockedIncrement
Definition: armddk.h:53
#define FILE_OPENED
Definition: nt_native.h:769
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70

Referenced by _Dispatch_type_().

◆ vol_device_control()

NTSTATUS vol_device_control ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 755 of file volume.c.

755 {
756 volume_device_extension* vde = DeviceObject->DeviceExtension;
758
759 TRACE("(%p, %p)\n", DeviceObject, Irp);
760
761 Irp->IoStatus.Information = 0;
762
763 switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
765 return vol_query_device_name(vde, Irp);
766
768 return vol_query_unique_id(vde, Irp);
769
771 return vol_get_device_number(vde, Irp);
772
774 TRACE("unhandled control code IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME\n");
775 break;
776
778 return vol_query_stable_guid(vde, Irp);
779
781 TRACE("unhandled control code IOCTL_MOUNTDEV_LINK_CREATED\n");
782 break;
783
786
788 return vol_is_dynamic(Irp);
789
791 Irp->IoStatus.Information = 0;
792 return STATUS_SUCCESS;
793
795 Irp->IoStatus.Information = 0;
796 return STATUS_SUCCESS;
797
800
802 return vol_is_writable(vde);
803
805 return vol_get_length(vde, Irp);
806
809 return vol_check_verify(vde);
810
812 return vol_get_disk_extents(vde, Irp);
813
814 default: { // pass ioctl through if only one child device
816#ifdef _DEBUG
817 ULONG code = IrpSp->Parameters.DeviceIoControl.IoControlCode;
818
819 if (NT_SUCCESS(Status))
820 TRACE("passing through ioctl %lx (returning %08lx)\n", code, Status);
821 else
822 WARN("passing through ioctl %lx (returning %08lx)\n", code, Status);
823#endif
824
825 return Status;
826 }
827 }
828
830}
#define IOCTL_DISK_CHECK_VERIFY
Definition: cdrw_usr.h:175
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
#define IOCTL_DISK_IS_WRITABLE
Definition: cdrw_usr.h:172
static NTSTATUS vol_query_unique_id(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:333
static NTSTATUS vol_query_stable_guid(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:731
static NTSTATUS vol_check_verify(volume_device_extension *vde)
Definition: volume.c:379
static NTSTATUS vol_get_disk_extents(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:405
#define IOCTL_VOLUME_IS_DYNAMIC
Definition: volume.c:25
static NTSTATUS vol_get_length(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:526
static NTSTATUS vol_ioctl_passthrough(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:661
static NTSTATUS vol_get_gpt_attributes(PIRP Irp)
Definition: volume.c:595
#define IOCTL_VOLUME_POST_ONLINE
Definition: volume.c:26
static NTSTATUS vol_get_drive_geometry(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: volume.c:557
static NTSTATUS vol_is_writable(volume_device_extension *vde)
Definition: volume.c:495
static NTSTATUS vol_query_device_name(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:306
static NTSTATUS vol_get_device_number(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:611
static NTSTATUS vol_is_dynamic(PIRP Irp)
Definition: volume.c:363
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define IOCTL_MOUNTDEV_LINK_CREATED
Definition: imports.h:106
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
#define IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
Definition: imports.h:99
#define IOCTL_MOUNTDEV_QUERY_STABLE_GUID
Definition: imports.h:255
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:80
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:143
#define IOCTL_VOLUME_GET_GPT_ATTRIBUTES
Definition: ntddvol.h:56
#define IOCTL_VOLUME_ONLINE
Definition: ntddvol.h:62
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
Definition: ntddvol.h:41
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
Definition: inflate.c:139
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793

Referenced by _Dispatch_type_().

◆ vol_get_device_number()

static NTSTATUS vol_get_device_number ( volume_device_extension vde,
PIRP  Irp 
)
static

Definition at line 611 of file volume.c.

611 {
612 pdo_device_extension* pdode = vde->pdode;
614 volume_child* vc;
616
617 // If only one device, return its disk number. This is needed for ejection to work.
618
619 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_DEVICE_NUMBER))
621
623
624 if (IsListEmpty(&pdode->children) || pdode->num_children > 1) {
627 }
628
630
631 if (vc->disk_num == 0xffffffff) {
634 }
635
636 sdn = (STORAGE_DEVICE_NUMBER*)Irp->AssociatedIrp.SystemBuffer;
637
639 sdn->DeviceNumber = vc->disk_num;
640 sdn->PartitionNumber = vc->part_num;
641
643
644 Irp->IoStatus.Information = sizeof(STORAGE_DEVICE_NUMBER);
645
646 return STATUS_SUCCESS;
647}
struct _STORAGE_DEVICE_NUMBER STORAGE_DEVICE_NUMBER
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
DEVICE_TYPE DeviceType
Definition: ntddstor.h:324

Referenced by vol_device_control().

◆ vol_get_disk_extents()

static NTSTATUS vol_get_disk_extents ( volume_device_extension vde,
PIRP  Irp 
)
static

Definition at line 405 of file volume.c.

405 {
406 pdo_device_extension* pdode = vde->pdode;
408 LIST_ENTRY* le;
409 ULONG num_extents = 0, i, max_extents = 1;
412
413 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(VOLUME_DISK_EXTENTS))
415
417
418 le = pdode->children.Flink;
419 while (le != &pdode->children) {
422
425 ERR("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS returned %08lx\n", Status);
426 goto end;
427 }
428
429 num_extents += ext2.NumberOfDiskExtents;
430
431 if (ext2.NumberOfDiskExtents > max_extents)
432 max_extents = ext2.NumberOfDiskExtents;
433
434 le = le->Flink;
435 }
436
437 ext = Irp->AssociatedIrp.SystemBuffer;
438
439 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (num_extents * sizeof(DISK_EXTENT))) {
440 Irp->IoStatus.Information = offsetof(VOLUME_DISK_EXTENTS, Extents[0]);
441 ext->NumberOfDiskExtents = num_extents;
443 goto end;
444 }
445
446 ext3 = ExAllocatePoolWithTag(PagedPool, offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (max_extents * sizeof(DISK_EXTENT)), ALLOC_TAG);
447 if (!ext3) {
448 ERR("out of memory\n");
450 goto end;
451 }
452
453 i = 0;
454 ext->NumberOfDiskExtents = 0;
455
456 le = pdode->children.Flink;
457 while (le != &pdode->children) {
459
461 (ULONG)offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (max_extents * sizeof(DISK_EXTENT)), false, NULL);
462 if (!NT_SUCCESS(Status)) {
463 ERR("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS returned %08lx\n", Status);
465 goto end;
466 }
467
468 if (i + ext3->NumberOfDiskExtents > num_extents) {
469 Irp->IoStatus.Information = offsetof(VOLUME_DISK_EXTENTS, Extents[0]);
470 ext->NumberOfDiskExtents = i + ext3->NumberOfDiskExtents;
473 goto end;
474 }
475
476 RtlCopyMemory(&ext->Extents[i], ext3->Extents, sizeof(DISK_EXTENT) * ext3->NumberOfDiskExtents);
477 i += ext3->NumberOfDiskExtents;
478
479 le = le->Flink;
480 }
481
483
485
486 ext->NumberOfDiskExtents = i;
487 Irp->IoStatus.Information = offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (i * sizeof(DISK_EXTENT));
488
489end:
491
492 return Status;
493}
static const WCHAR *const ext[]
Definition: module.c:53
static const BYTE ext2[]
Definition: encode.c:2699
static const BYTE ext3[]
Definition: encode.c:2701
struct _DISK_EXTENT DISK_EXTENT
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66

Referenced by vol_device_control().

◆ vol_get_drive_geometry()

static NTSTATUS vol_get_drive_geometry ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)
static

Definition at line 557 of file volume.c.

557 {
558 volume_device_extension* vde = DeviceObject->DeviceExtension;
559 pdo_device_extension* pdode = vde->pdode;
561 DISK_GEOMETRY* geom;
563 LIST_ENTRY* le;
564
565 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY))
567
568 length = 0;
569
571
572 le = pdode->children.Flink;
573 while (le != &pdode->children) {
575
576 length += vc->size;
577
578 le = le->Flink;
579 }
580
582
583 geom = (DISK_GEOMETRY*)Irp->AssociatedIrp.SystemBuffer;
584 geom->BytesPerSector = DeviceObject->SectorSize == 0 ? 0x200 : DeviceObject->SectorSize;
585 geom->SectorsPerTrack = 0x3f;
586 geom->TracksPerCylinder = 0xff;
589
590 Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
591
592 return STATUS_SUCCESS;
593}
UINT64 uint64_t
Definition: types.h:77
#define UInt32x32To64(a, b)
Definition: intsafe.h:252
struct _DISK_GEOMETRY DISK_GEOMETRY
@ RemovableMedia
Definition: ntdddisk.h:387
@ FixedMedia
Definition: ntdddisk.h:388
MEDIA_TYPE MediaType
Definition: ntdddisk.h:406
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:405
ULONG TracksPerCylinder
Definition: ntdddisk.h:407
ULONG SectorsPerTrack
Definition: ntdddisk.h:408
ULONG BytesPerSector
Definition: ntdddisk.h:409
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by vol_device_control().

◆ vol_get_gpt_attributes()

static NTSTATUS vol_get_gpt_attributes ( PIRP  Irp)
static

Definition at line 595 of file volume.c.

595 {
598
599 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(VOLUME_GET_GPT_ATTRIBUTES_INFORMATION))
601
602 vggai = (VOLUME_GET_GPT_ATTRIBUTES_INFORMATION*)Irp->AssociatedIrp.SystemBuffer;
603
604 vggai->GptAttributes = 0;
605
606 Irp->IoStatus.Information = sizeof(VOLUME_GET_GPT_ATTRIBUTES_INFORMATION);
607
608 return STATUS_SUCCESS;
609}

Referenced by vol_device_control().

◆ vol_get_length()

static NTSTATUS vol_get_length ( volume_device_extension vde,
PIRP  Irp 
)
static

Definition at line 526 of file volume.c.

526 {
528 pdo_device_extension* pdode = vde->pdode;
530 LIST_ENTRY* le;
531
532 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GET_LENGTH_INFORMATION))
534
535 gli = (GET_LENGTH_INFORMATION*)Irp->AssociatedIrp.SystemBuffer;
536
537 gli->Length.QuadPart = 0;
538
540
541 le = pdode->children.Flink;
542 while (le != &pdode->children) {
544
545 gli->Length.QuadPart += vc->size;
546
547 le = le->Flink;
548 }
549
551
552 Irp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION);
553
554 return STATUS_SUCCESS;
555}
LARGE_INTEGER Length
Definition: winioctl.h:560

Referenced by vol_device_control().

◆ vol_ioctl_passthrough()

static NTSTATUS vol_ioctl_passthrough ( volume_device_extension vde,
PIRP  Irp 
)
static

Definition at line 661 of file volume.c.

661 {
663 volume_child* vc;
664 PIRP Irp2;
667 pdo_device_extension* pdode = vde->pdode;
668
669 TRACE("(%p, %p)\n", vde, Irp);
670
672
673 if (IsListEmpty(&pdode->children)) {
676 }
677
679
680 if (vc->list_entry.Flink != &pdode->children) { // more than one device
683 }
684
685 Irp2 = IoAllocateIrp(vc->devobj->StackSize, false);
686
687 if (!Irp2) {
688 ERR("IoAllocateIrp failed\n");
691 }
692
694 IrpSp2 = IoGetNextIrpStackLocation(Irp2);
695
698 IrpSp2->FileObject = vc->fileobj;
699
700 IrpSp2->Parameters.DeviceIoControl.OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
701 IrpSp2->Parameters.DeviceIoControl.InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
702 IrpSp2->Parameters.DeviceIoControl.IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
703 IrpSp2->Parameters.DeviceIoControl.Type3InputBuffer = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
704
705 Irp2->AssociatedIrp.SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
706 Irp2->MdlAddress = Irp->MdlAddress;
707 Irp2->UserBuffer = Irp->UserBuffer;
708 Irp2->Flags = Irp->Flags;
709
711
712 IoSetCompletionRoutine(Irp2, vol_ioctl_completion, &Event, true, true, true);
713
714 Status = IoCallDriver(vc->devobj, Irp2);
715
716 if (Status == STATUS_PENDING) {
718 Status = Irp2->IoStatus.Status;
719 }
720
721 Irp->IoStatus.Status = Irp2->IoStatus.Status;
722 Irp->IoStatus.Information = Irp2->IoStatus.Information;
723
725
726 IoFreeIrp(Irp2);
727
728 return Status;
729}
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
#define KernelMode
Definition: asm.h:34
@ NotificationEvent
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define STATUS_PENDING
Definition: ntstatus.h:82
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
IO_STATUS_BLOCK IoStatus
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
@ Executive
Definition: ketypes.h:415

Referenced by vol_device_control().

◆ vol_is_dynamic()

static NTSTATUS vol_is_dynamic ( PIRP  Irp)
static

Definition at line 363 of file volume.c.

363 {
365 uint8_t* buf;
366
367 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0 || !Irp->AssociatedIrp.SystemBuffer)
369
370 buf = (uint8_t*)Irp->AssociatedIrp.SystemBuffer;
371
372 *buf = 1;
373
374 Irp->IoStatus.Information = 1;
375
376 return STATUS_SUCCESS;
377}
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

Referenced by vol_device_control().

◆ vol_is_writable()

static NTSTATUS vol_is_writable ( volume_device_extension vde)
static

Definition at line 495 of file volume.c.

495 {
496 pdo_device_extension* pdode = vde->pdode;
498 LIST_ENTRY* le;
499 bool writable = false;
500
502
503 le = pdode->children.Flink;
504 while (le != &pdode->children) {
506
508
509 if (NT_SUCCESS(Status)) {
510 writable = true;
511 break;
513 goto end;
514
515 le = le->Flink;
516 }
517
519
520end:
522
523 return STATUS_SUCCESS;
524}
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161

Referenced by vol_device_control().

◆ vol_query_device_name()

static NTSTATUS vol_query_device_name ( volume_device_extension vde,
PIRP  Irp 
)
static

Definition at line 306 of file volume.c.

306 {
309
310 if (IrpSp->FileObject && IrpSp->FileObject->FsContext)
312
313 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_NAME)) {
314 Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
316 }
317
318 name = Irp->AssociatedIrp.SystemBuffer;
319 name->NameLength = vde->name.Length;
320
321 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < offsetof(MOUNTDEV_NAME, Name[0]) + name->NameLength) {
322 Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
324 }
325
326 RtlCopyMemory(name->Name, vde->name.Buffer, vde->name.Length);
327
328 Irp->IoStatus.Information = offsetof(MOUNTDEV_NAME, Name[0]) + name->NameLength;
329
330 return STATUS_SUCCESS;
331}
struct _MOUNTDEV_NAME MOUNTDEV_NAME
Definition: name.c:39

Referenced by vol_device_control().

◆ vol_query_stable_guid()

static NTSTATUS vol_query_stable_guid ( volume_device_extension vde,
PIRP  Irp 
)
static

Definition at line 731 of file volume.c.

731 {
735
736 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_STABLE_GUID)) {
737 Irp->IoStatus.Information = sizeof(MOUNTDEV_STABLE_GUID);
739 }
740
741 mdsg = Irp->AssociatedIrp.SystemBuffer;
742
743 if (!vde->pdo)
745
746 pdode = vde->pdode;
747
748 RtlCopyMemory(&mdsg->StableGuid, &pdode->uuid, sizeof(BTRFS_UUID));
749
750 Irp->IoStatus.Information = sizeof(MOUNTDEV_STABLE_GUID);
751
752 return STATUS_SUCCESS;
753}
struct _MOUNTDEV_STABLE_GUID MOUNTDEV_STABLE_GUID

Referenced by vol_device_control().

◆ vol_query_unique_id()

static NTSTATUS vol_query_unique_id ( volume_device_extension vde,
PIRP  Irp 
)
static

Definition at line 333 of file volume.c.

333 {
335 MOUNTDEV_UNIQUE_ID* mduid;
337
338 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_UNIQUE_ID)) {
339 Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
341 }
342
343 mduid = Irp->AssociatedIrp.SystemBuffer;
344 mduid->UniqueIdLength = sizeof(BTRFS_UUID);
345
346 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < offsetof(MOUNTDEV_UNIQUE_ID, UniqueId[0]) + mduid->UniqueIdLength) {
347 Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
349 }
350
351 if (!vde->pdo)
353
354 pdode = vde->pdode;
355
356 RtlCopyMemory(mduid->UniqueId, &pdode->uuid, sizeof(BTRFS_UUID));
357
358 Irp->IoStatus.Information = offsetof(MOUNTDEV_UNIQUE_ID, UniqueId[0]) + mduid->UniqueIdLength;
359
360 return STATUS_SUCCESS;
361}
struct _MOUNTDEV_UNIQUE_ID MOUNTDEV_UNIQUE_ID
USHORT UniqueIdLength
Definition: imports.h:138
UCHAR UniqueId[1]
Definition: imports.h:139

Referenced by vol_device_control().

◆ vol_read()

NTSTATUS vol_read ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 144 of file volume.c.

144 {
145 volume_device_extension* vde = DeviceObject->DeviceExtension;
146 pdo_device_extension* pdode = vde->pdode;
147 volume_child* vc;
149 PIRP Irp2;
152
153 TRACE("(%p, %p)\n", DeviceObject, Irp);
154
156
157 if (IsListEmpty(&pdode->children)) {
160 goto end;
161 }
162
164
165 // We can't use IoSkipCurrentIrpStackLocation as the device isn't in our stack
166
167 Irp2 = IoAllocateIrp(vc->devobj->StackSize, false);
168
169 if (!Irp2) {
170 ERR("IoAllocateIrp failed\n");
173 goto end;
174 }
175
177 IrpSp2 = IoGetNextIrpStackLocation(Irp2);
178
179 IrpSp2->MajorFunction = IRP_MJ_READ;
180 IrpSp2->FileObject = vc->fileobj;
181
182 if (vc->devobj->Flags & DO_BUFFERED_IO) {
183 Irp2->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool, IrpSp->Parameters.Read.Length, ALLOC_TAG);
184 if (!Irp2->AssociatedIrp.SystemBuffer) {
185 ERR("out of memory\n");
188 goto end;
189 }
190
192
193 Irp2->UserBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
194 } else if (vc->devobj->Flags & DO_DIRECT_IO)
195 Irp2->MdlAddress = Irp->MdlAddress;
196 else
197 Irp2->UserBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
198
199 IrpSp2->Parameters.Read.Length = IrpSp->Parameters.Read.Length;
200 IrpSp2->Parameters.Read.ByteOffset.QuadPart = IrpSp->Parameters.Read.ByteOffset.QuadPart;
201
203 Irp2->UserIosb = &context.iosb;
204
205 IoSetCompletionRoutine(Irp2, vol_read_completion, &context, true, true, true);
206
207 Status = IoCallDriver(vc->devobj, Irp2);
208
209 if (Status == STATUS_PENDING) {
211 Status = context.iosb.Status;
212 }
213
215
216 Irp->IoStatus.Information = context.iosb.Information;
217
218end:
219 Irp->IoStatus.Status = Status;
221
222 return Status;
223}
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
@ NormalPagePriority
Definition: imports.h:56
#define IoCompleteRequest
Definition: irp.c:1240
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_DEALLOCATE_BUFFER
#define IRP_INPUT_OPERATION
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_BUFFERED_IO
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)

Referenced by _Dispatch_type_().

◆ vol_write()

NTSTATUS vol_write ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 225 of file volume.c.

225 {
226 volume_device_extension* vde = DeviceObject->DeviceExtension;
227 pdo_device_extension* pdode = vde->pdode;
228 volume_child* vc;
230 PIRP Irp2;
233
234 TRACE("(%p, %p)\n", DeviceObject, Irp);
235
237
238 if (IsListEmpty(&pdode->children)) {
241 goto end;
242 }
243
245
246 if (vc->list_entry.Flink != &pdode->children) { // more than once device
249 goto end;
250 }
251
252 // We can't use IoSkipCurrentIrpStackLocation as the device isn't in our stack
253
254 Irp2 = IoAllocateIrp(vc->devobj->StackSize, false);
255
256 if (!Irp2) {
257 ERR("IoAllocateIrp failed\n");
260 goto end;
261 }
262
264 IrpSp2 = IoGetNextIrpStackLocation(Irp2);
265
266 IrpSp2->MajorFunction = IRP_MJ_WRITE;
267 IrpSp2->FileObject = vc->fileobj;
268
269 if (vc->devobj->Flags & DO_BUFFERED_IO) {
270 Irp2->AssociatedIrp.SystemBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
271
272 Irp2->Flags |= IRP_BUFFERED_IO;
273
274 Irp2->UserBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
275 } else if (vc->devobj->Flags & DO_DIRECT_IO)
276 Irp2->MdlAddress = Irp->MdlAddress;
277 else
278 Irp2->UserBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
279
280 IrpSp2->Parameters.Write.Length = IrpSp->Parameters.Write.Length;
281 IrpSp2->Parameters.Write.ByteOffset.QuadPart = IrpSp->Parameters.Write.ByteOffset.QuadPart;
282
284 Irp2->UserIosb = &context.iosb;
285
286 IoSetCompletionRoutine(Irp2, vol_read_completion, &context, true, true, true);
287
288 Status = IoCallDriver(vc->devobj, Irp2);
289
290 if (Status == STATUS_PENDING) {
292 Status = context.iosb.Status;
293 }
294
296
297 Irp->IoStatus.Information = context.iosb.Information;
298
299end:
300 Irp->IoStatus.Status = Status;
302
303 return Status;
304}
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145

Referenced by _Dispatch_type_().

Variable Documentation

◆ busobj

PDEVICE_OBJECT busobj
extern

Definition at line 66 of file btrfs.c.

Referenced by _Function_class_(), add_volume_device(), and do_shutdown().

◆ drvobj

PDRIVER_OBJECT drvobj
extern

Definition at line 65 of file btrfs.c.

Referenced by _Function_class_(), add_volume_device(), and mount_vol().

◆ fIoUnregisterPlugPlayNotificationEx

tIoUnregisterPlugPlayNotificationEx fIoUnregisterPlugPlayNotificationEx
extern

Definition at line 95 of file btrfs.c.

Referenced by _Function_class_(), do_shutdown(), and free_vol().

◆ master_devobj

PDEVICE_OBJECT master_devobj
extern

◆ pdo_list

LIST_ENTRY pdo_list
extern

Definition at line 104 of file btrfs.c.

Referenced by _Function_class_(), add_volume_device(), and mount_vol().

◆ pdo_list_lock

ERESOURCE pdo_list_lock
extern

Definition at line 103 of file btrfs.c.

Referenced by _Function_class_(), add_volume_device(), mount_vol(), and vol_close().

◆ registry_path