ReactOS  0.4.14-dev-838-g99f979d
volume.c
Go to the documentation of this file.
1 /* Copyright (c) Mark Harmstone 2016-17
2  *
3  * This file is part of WinBtrfs.
4  *
5  * WinBtrfs is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public Licence as published by
7  * the Free Software Foundation, either version 3 of the Licence, or
8  * (at your option) any later version.
9  *
10  * WinBtrfs is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public Licence for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public Licence
16  * along with WinBtrfs. If not, see <http://www.gnu.org/licenses/>. */
17 
18 #include "btrfs_drv.h"
19 #include <mountdev.h>
20 #include <ntddvol.h>
21 #include <ntddstor.h>
22 #include <ntdddisk.h>
23 #include <wdmguid.h>
24 
25 #define IOCTL_VOLUME_IS_DYNAMIC CTL_CODE(IOCTL_VOLUME_BASE, 18, METHOD_BUFFERED, FILE_ANY_ACCESS)
26 #define IOCTL_VOLUME_POST_ONLINE CTL_CODE(IOCTL_VOLUME_BASE, 25, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
27 
28 extern PDRIVER_OBJECT drvobj;
30 extern PDEVICE_OBJECT busobj;
32 extern LIST_ENTRY pdo_list;
35 
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 }
49 
51  PDEVICE_OBJECT pdo;
52 
53  vde->dead = true;
54 
55  if (vde->mounted_device) {
57 
58  Vcb->vde = NULL;
59  }
60 
61  if (vde->name.Buffer)
62  ExFreePool(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;
89  IoDeleteDevice(vde->device);
90 
91  if (!no_pnp)
92  IoDeleteDevice(pdo);
93 }
94 
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 }
126 
127 typedef struct {
131 
132 _Function_class_(IO_COMPLETION_ROUTINE)
133 static NTSTATUS __stdcall vol_read_completion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID conptr) {
134  vol_read_context* context = conptr;
135 
137 
138  context->iosb = Irp->IoStatus;
139  KeSetEvent(&context->Event, 0, false);
140 
142 }
143 
146  pdo_device_extension* pdode = vde->pdode;
147  volume_child* vc;
149  PIRP Irp2;
151  PIO_STACK_LOCATION IrpSp, IrpSp2;
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 
218 end:
219  Irp->IoStatus.Status = Status;
221 
222  return Status;
223 }
224 
227  pdo_device_extension* pdode = vde->pdode;
228  volume_child* vc;
230  PIRP Irp2;
232  PIO_STACK_LOCATION IrpSp, IrpSp2;
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 
299 end:
300  Irp->IoStatus.Status = Status;
302 
303  return Status;
304 }
305 
307  TRACE("(%p, %p)\n", DeviceObject, Irp);
308 
310 }
311 
313  TRACE("(%p, %p)\n", DeviceObject, Irp);
314 
316 }
317 
319  TRACE("(%p, %p)\n", DeviceObject, Irp);
320 
322 }
323 
325  TRACE("(%p, %p)\n", DeviceObject, Irp);
326 
328 }
329 
331  TRACE("(%p, %p)\n", DeviceObject, Irp);
332 
333  return STATUS_SUCCESS;
334 }
335 
337  TRACE("(%p, %p)\n", DeviceObject, Irp);
338 
340 }
341 
343  TRACE("(%p, %p)\n", DeviceObject, Irp);
344 
346 }
347 
349  TRACE("(%p, %p)\n", DeviceObject, Irp);
350 
351  Irp->IoStatus.Information = 0;
352 
353  return STATUS_SUCCESS;
354 }
355 
357  TRACE("(%p, %p)\n", DeviceObject, Irp);
358 
360 }
361 
363  TRACE("(%p, %p)\n", DeviceObject, Irp);
364 
366 }
367 
369  TRACE("(%p, %p)\n", DeviceObject, Irp);
370 
372 }
373 
377 
378  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_NAME)) {
379  Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
381  }
382 
383  name = Irp->AssociatedIrp.SystemBuffer;
384  name->NameLength = vde->name.Length;
385 
386  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < offsetof(MOUNTDEV_NAME, Name[0]) + name->NameLength) {
387  Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
388  return STATUS_BUFFER_OVERFLOW;
389  }
390 
391  RtlCopyMemory(name->Name, vde->name.Buffer, vde->name.Length);
392 
393  Irp->IoStatus.Information = offsetof(MOUNTDEV_NAME, Name[0]) + name->NameLength;
394 
395  return STATUS_SUCCESS;
396 }
397 
400  MOUNTDEV_UNIQUE_ID* mduid;
401  pdo_device_extension* pdode;
402 
403  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_UNIQUE_ID)) {
404  Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
406  }
407 
408  mduid = Irp->AssociatedIrp.SystemBuffer;
409  mduid->UniqueIdLength = sizeof(BTRFS_UUID);
410 
411  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < offsetof(MOUNTDEV_UNIQUE_ID, UniqueId[0]) + mduid->UniqueIdLength) {
412  Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
413  return STATUS_BUFFER_OVERFLOW;
414  }
415 
416  if (!vde->pdo)
418 
419  pdode = vde->pdode;
420 
421  RtlCopyMemory(mduid->UniqueId, &pdode->uuid, sizeof(BTRFS_UUID));
422 
423  Irp->IoStatus.Information = offsetof(MOUNTDEV_UNIQUE_ID, UniqueId[0]) + mduid->UniqueIdLength;
424 
425  return STATUS_SUCCESS;
426 }
427 
430  uint8_t* buf;
431 
432  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0 || !Irp->AssociatedIrp.SystemBuffer)
434 
435  buf = (uint8_t*)Irp->AssociatedIrp.SystemBuffer;
436 
437  *buf = 1;
438 
439  Irp->IoStatus.Information = 1;
440 
441  return STATUS_SUCCESS;
442 }
443 
445  pdo_device_extension* pdode = vde->pdode;
447  LIST_ENTRY* le;
448 
450 
451  le = pdode->children.Flink;
452  while (le != &pdode->children) {
454 
456  if (!NT_SUCCESS(Status))
457  goto end;
458 
459  le = le->Flink;
460  }
461 
463 
464 end:
466 
467  return Status;
468 }
469 
471  pdo_device_extension* pdode = vde->pdode;
473  LIST_ENTRY* le;
474  ULONG num_extents = 0, i, max_extents = 1;
477 
478  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(VOLUME_DISK_EXTENTS))
480 
482 
483  le = pdode->children.Flink;
484  while (le != &pdode->children) {
487 
490  ERR("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS returned %08x\n", Status);
491  goto end;
492  }
493 
494  num_extents += ext2.NumberOfDiskExtents;
495 
496  if (ext2.NumberOfDiskExtents > max_extents)
497  max_extents = ext2.NumberOfDiskExtents;
498 
499  le = le->Flink;
500  }
501 
502  ext = Irp->AssociatedIrp.SystemBuffer;
503 
504  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (num_extents * sizeof(DISK_EXTENT))) {
505  Irp->IoStatus.Information = offsetof(VOLUME_DISK_EXTENTS, Extents[0]);
506  ext->NumberOfDiskExtents = num_extents;
508  goto end;
509  }
510 
511  ext3 = ExAllocatePoolWithTag(PagedPool, offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (max_extents * sizeof(DISK_EXTENT)), ALLOC_TAG);
512  if (!ext3) {
513  ERR("out of memory\n");
515  goto end;
516  }
517 
518  i = 0;
519  ext->NumberOfDiskExtents = 0;
520 
521  le = pdode->children.Flink;
522  while (le != &pdode->children) {
524 
526  (ULONG)offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (max_extents * sizeof(DISK_EXTENT)), false, NULL);
527  if (!NT_SUCCESS(Status)) {
528  ERR("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS returned %08x\n", Status);
529  ExFreePool(ext3);
530  goto end;
531  }
532 
533  if (i + ext3->NumberOfDiskExtents > num_extents) {
534  Irp->IoStatus.Information = offsetof(VOLUME_DISK_EXTENTS, Extents[0]);
535  ext->NumberOfDiskExtents = i + ext3->NumberOfDiskExtents;
537  ExFreePool(ext3);
538  goto end;
539  }
540 
541  RtlCopyMemory(&ext->Extents[i], ext3->Extents, sizeof(DISK_EXTENT) * ext3->NumberOfDiskExtents);
542  i += ext3->NumberOfDiskExtents;
543 
544  le = le->Flink;
545  }
546 
547  ExFreePool(ext3);
548 
550 
551  ext->NumberOfDiskExtents = i;
552  Irp->IoStatus.Information = offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (i * sizeof(DISK_EXTENT));
553 
554 end:
556 
557  return Status;
558 }
559 
561  pdo_device_extension* pdode = vde->pdode;
563  LIST_ENTRY* le;
564  bool writable = false;
565 
567 
568  le = pdode->children.Flink;
569  while (le != &pdode->children) {
571 
572  Status = dev_ioctl(vc->devobj, IOCTL_DISK_IS_WRITABLE, NULL, 0, NULL, 0, true, NULL);
573 
574  if (NT_SUCCESS(Status)) {
575  writable = true;
576  break;
577  } else if (Status != STATUS_MEDIA_WRITE_PROTECTED)
578  goto end;
579 
580  le = le->Flink;
581  }
582 
584 
585 end:
587 
588  return STATUS_SUCCESS;
589 }
590 
593  pdo_device_extension* pdode = vde->pdode;
595  LIST_ENTRY* le;
596 
597  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GET_LENGTH_INFORMATION))
599 
600  gli = (GET_LENGTH_INFORMATION*)Irp->AssociatedIrp.SystemBuffer;
601 
602  gli->Length.QuadPart = 0;
603 
605 
606  le = pdode->children.Flink;
607  while (le != &pdode->children) {
609 
610  gli->Length.QuadPart += vc->size;
611 
612  le = le->Flink;
613  }
614 
616 
617  Irp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION);
618 
619  return STATUS_SUCCESS;
620 }
621 
624  pdo_device_extension* pdode = vde->pdode;
626  DISK_GEOMETRY* geom;
628  LIST_ENTRY* le;
629 
630  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY))
632 
633  length = 0;
634 
636 
637  le = pdode->children.Flink;
638  while (le != &pdode->children) {
640 
641  length += vc->size;
642 
643  le = le->Flink;
644  }
645 
647 
648  geom = (DISK_GEOMETRY*)Irp->AssociatedIrp.SystemBuffer;
649  geom->BytesPerSector = DeviceObject->SectorSize == 0 ? 0x200 : DeviceObject->SectorSize;
650  geom->SectorsPerTrack = 0x3f;
651  geom->TracksPerCylinder = 0xff;
654 
655  Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
656 
657  return STATUS_SUCCESS;
658 }
659 
663 
664  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(VOLUME_GET_GPT_ATTRIBUTES_INFORMATION))
666 
667  vggai = (VOLUME_GET_GPT_ATTRIBUTES_INFORMATION*)Irp->AssociatedIrp.SystemBuffer;
668 
669  vggai->GptAttributes = 0;
670 
671  Irp->IoStatus.Information = sizeof(VOLUME_GET_GPT_ATTRIBUTES_INFORMATION);
672 
673  return STATUS_SUCCESS;
674 }
675 
677  pdo_device_extension* pdode = vde->pdode;
679  volume_child* vc;
681 
682  // If only one device, return its disk number. This is needed for ejection to work.
683 
684  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_DEVICE_NUMBER))
686 
688 
689  if (IsListEmpty(&pdode->children) || pdode->num_children > 1) {
692  }
693 
695 
696  if (vc->disk_num == 0xffffffff) {
699  }
700 
701  sdn = (STORAGE_DEVICE_NUMBER*)Irp->AssociatedIrp.SystemBuffer;
702 
704  sdn->DeviceNumber = vc->disk_num;
705  sdn->PartitionNumber = vc->part_num;
706 
708 
709  Irp->IoStatus.Information = sizeof(STORAGE_DEVICE_NUMBER);
710 
711  return STATUS_SUCCESS;
712 }
713 
714 _Function_class_(IO_COMPLETION_ROUTINE)
715 static NTSTATUS __stdcall vol_ioctl_completion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID conptr) {
716  KEVENT* event = conptr;
717 
719  UNUSED(Irp);
720 
721  KeSetEvent(event, 0, false);
722 
724 }
725 
728  volume_child* vc;
729  PIRP Irp2;
730  PIO_STACK_LOCATION IrpSp, IrpSp2;
731  KEVENT Event;
732  pdo_device_extension* pdode = vde->pdode;
733 
734  TRACE("(%p, %p)\n", vde, Irp);
735 
737 
738  if (IsListEmpty(&pdode->children)) {
741  }
742 
744 
745  if (vc->list_entry.Flink != &pdode->children) { // more than one device
748  }
749 
750  Irp2 = IoAllocateIrp(vc->devobj->StackSize, false);
751 
752  if (!Irp2) {
753  ERR("IoAllocateIrp failed\n");
756  }
757 
759  IrpSp2 = IoGetNextIrpStackLocation(Irp2);
760 
761  IrpSp2->MajorFunction = IrpSp->MajorFunction;
762  IrpSp2->MinorFunction = IrpSp->MinorFunction;
763  IrpSp2->FileObject = vc->fileobj;
764 
765  IrpSp2->Parameters.DeviceIoControl.OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
766  IrpSp2->Parameters.DeviceIoControl.InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
767  IrpSp2->Parameters.DeviceIoControl.IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
768  IrpSp2->Parameters.DeviceIoControl.Type3InputBuffer = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
769 
770  Irp2->AssociatedIrp.SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
771  Irp2->MdlAddress = Irp->MdlAddress;
772  Irp2->UserBuffer = Irp->UserBuffer;
773  Irp2->Flags = Irp->Flags;
774 
776 
777  IoSetCompletionRoutine(Irp2, vol_ioctl_completion, &Event, true, true, true);
778 
779  Status = IoCallDriver(vc->devobj, Irp2);
780 
781  if (Status == STATUS_PENDING) {
783  Status = Irp2->IoStatus.Status;
784  }
785 
786  Irp->IoStatus.Status = Irp2->IoStatus.Status;
787  Irp->IoStatus.Information = Irp2->IoStatus.Information;
788 
790 
791  IoFreeIrp(Irp2);
792 
793  return Status;
794 }
795 
798  MOUNTDEV_STABLE_GUID* mdsg;
799  pdo_device_extension* pdode;
800 
801  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_STABLE_GUID)) {
802  Irp->IoStatus.Information = sizeof(MOUNTDEV_STABLE_GUID);
804  }
805 
806  mdsg = Irp->AssociatedIrp.SystemBuffer;
807 
808  if (!vde->pdo)
810 
811  pdode = vde->pdode;
812 
813  RtlCopyMemory(&mdsg->StableGuid, &pdode->uuid, sizeof(BTRFS_UUID));
814 
815  Irp->IoStatus.Information = sizeof(MOUNTDEV_STABLE_GUID);
816 
817  return STATUS_SUCCESS;
818 }
819 
823 
824  TRACE("(%p, %p)\n", DeviceObject, Irp);
825 
826  Irp->IoStatus.Information = 0;
827 
828  switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
830  return vol_query_device_name(vde, Irp);
831 
833  return vol_query_unique_id(vde, Irp);
834 
836  return vol_get_device_number(vde, Irp);
837 
839  TRACE("unhandled control code IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME\n");
840  break;
841 
843  return vol_query_stable_guid(vde, Irp);
844 
846  TRACE("unhandled control code IOCTL_MOUNTDEV_LINK_CREATED\n");
847  break;
848 
850  return vol_get_gpt_attributes(Irp);
851 
853  return vol_is_dynamic(Irp);
854 
855  case IOCTL_VOLUME_ONLINE:
856  Irp->IoStatus.Information = 0;
857  return STATUS_SUCCESS;
858 
860  Irp->IoStatus.Information = 0;
861  return STATUS_SUCCESS;
862 
865 
867  return vol_is_writable(vde);
868 
870  return vol_get_length(vde, Irp);
871 
874  return vol_check_verify(vde);
875 
877  return vol_get_disk_extents(vde, Irp);
878 
879  default: // pass ioctl through if only one child device
880  return vol_ioctl_passthrough(vde, Irp);
881  }
882 
884 }
885 
887  TRACE("(%p, %p)\n", DeviceObject, Irp);
888 
890 }
891 
893  TRACE("(%p, %p)\n", DeviceObject, Irp);
894 
896 }
897 
899  TRACE("(%p, %p)\n", DeviceObject, Irp);
900 
902 }
903 
906  ULONG mmdltsize;
909 
910  mmdltsize = (ULONG)offsetof(MOUNTMGR_DRIVE_LETTER_TARGET, DeviceName[0]) + devpath->Length;
911 
912  mmdlt = ExAllocatePoolWithTag(NonPagedPool, mmdltsize, ALLOC_TAG);
913  if (!mmdlt) {
914  ERR("out of memory\n");
916  }
917 
918  mmdlt->DeviceNameLength = devpath->Length;
919  RtlCopyMemory(&mmdlt->DeviceName, devpath->Buffer, devpath->Length);
920  TRACE("mmdlt = %.*S\n", mmdlt->DeviceNameLength / sizeof(WCHAR), mmdlt->DeviceName);
921 
923 
924  if (!NT_SUCCESS(Status))
925  ERR("IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER returned %08x\n", Status);
926  else
927  TRACE("DriveLetterWasAssigned = %u, CurrentDriveLetter = %c\n", mmdli.DriveLetterWasAssigned, mmdli.CurrentDriveLetter);
928 
929  ExFreePool(mmdlt);
930 
931  return Status;
932 }
933 
934 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE)
938 
939  if (RtlCompareMemory(&tdrn->Event, &GUID_TARGET_DEVICE_QUERY_REMOVE, sizeof(GUID)) == sizeof(GUID)) {
940  TRACE("GUID_TARGET_DEVICE_QUERY_REMOVE\n");
941 
942  if (pdode->vde && pdode->vde->mounted_device)
944  }
945 
946  return STATUS_SUCCESS;
947 }
948 
950  HANDLE h;
953  UNICODE_STRING path, adus;
954  uint32_t degraded = mount_allow_degraded;
955  ULONG i, j, kvfilen, retlen;
957 
958  path.Length = path.MaximumLength = registry_path.Length + (37 * sizeof(WCHAR));
960 
961  if (!path.Buffer) {
962  ERR("out of memory\n");
963  return false;
964  }
965 
967  i = registry_path.Length / sizeof(WCHAR);
968 
969  path.Buffer[i] = '\\';
970  i++;
971 
972  for (j = 0; j < 16; j++) {
973  path.Buffer[i] = hex_digit((uuid->uuid[j] & 0xF0) >> 4);
974  path.Buffer[i+1] = hex_digit(uuid->uuid[j] & 0xF);
975 
976  i += 2;
977 
978  if (j == 3 || j == 5 || j == 7 || j == 9) {
979  path.Buffer[i] = '-';
980  i++;
981  }
982  }
983 
985 
986  kvfilen = (ULONG)offsetof(KEY_VALUE_FULL_INFORMATION, Name[0]) + (255 * sizeof(WCHAR));
987  kvfi = ExAllocatePoolWithTag(PagedPool, kvfilen, ALLOC_TAG);
988  if (!kvfi) {
989  ERR("out of memory\n");
990  ExFreePool(path.Buffer);
991  return false;
992  }
993 
994  Status = ZwOpenKey(&h, KEY_QUERY_VALUE, &oa);
996  goto end;
997  else if (!NT_SUCCESS(Status)) {
998  ERR("ZwOpenKey returned %08x\n", Status);
999  goto end;
1000  }
1001 
1002  adus.Buffer = L"AllowDegraded";
1003  adus.Length = adus.MaximumLength = sizeof(adus.Buffer) - sizeof(WCHAR);
1004 
1005  if (NT_SUCCESS(ZwQueryValueKey(h, &adus, KeyValueFullInformation, kvfi, kvfilen, &retlen))) {
1006  if (kvfi->Type == REG_DWORD && kvfi->DataLength >= sizeof(uint32_t)) {
1007  uint32_t* val = (uint32_t*)((uint8_t*)kvfi + kvfi->DataOffset);
1008 
1009  degraded = *val;
1010  }
1011  }
1012 
1013  ZwClose(h);
1014 
1015 end:
1016  ExFreePool(kvfi);
1017 
1018  ExFreePool(path.Buffer);
1019 
1020  return degraded;
1021 }
1022 
1023 typedef struct {
1029 
1031  LIST_ENTRY* le;
1032  LIST_ENTRY dlrlist;
1033 
1034  InitializeListHead(&dlrlist);
1035 
1037 
1038  le = pdode->children.Flink;
1039 
1040  while (le != &pdode->children) {
1041  drive_letter_removal* dlr;
1042 
1044 
1046  if (!dlr) {
1047  ERR("out of memory\n");
1048 
1049  while (!IsListEmpty(&dlrlist)) {
1051 
1052  ExFreePool(dlr->name.Buffer);
1053  ExFreePool(dlr);
1054  }
1055 
1057  return;
1058  }
1059 
1060  dlr->name.Length = dlr->name.MaximumLength = vc->pnp_name.Length + (3 * sizeof(WCHAR));
1062 
1063  if (!dlr->name.Buffer) {
1064  ERR("out of memory\n");
1065 
1066  ExFreePool(dlr);
1067 
1068  while (!IsListEmpty(&dlrlist)) {
1070 
1071  ExFreePool(dlr->name.Buffer);
1072  ExFreePool(dlr);
1073  }
1074 
1076  return;
1077  }
1078 
1079  RtlCopyMemory(dlr->name.Buffer, L"\\??", 3 * sizeof(WCHAR));
1080  RtlCopyMemory(&dlr->name.Buffer[3], vc->pnp_name.Buffer, vc->pnp_name.Length);
1081 
1082  dlr->uuid = vc->uuid;
1083 
1084  InsertTailList(&dlrlist, &dlr->list_entry);
1085 
1086  le = le->Flink;
1087  }
1088 
1090 
1091  le = dlrlist.Flink;
1092  while (le != &dlrlist) {
1094 
1095  dlr->Status = remove_drive_letter(mountmgr, &dlr->name);
1096 
1097  if (!NT_SUCCESS(dlr->Status) && dlr->Status != STATUS_NOT_FOUND)
1098  WARN("remove_drive_letter returned %08x\n", dlr->Status);
1099 
1100  le = le->Flink;
1101  }
1102 
1103  // set vc->had_drive_letter
1104 
1106 
1107  while (!IsListEmpty(&dlrlist)) {
1109 
1110  le = pdode->children.Flink;
1111 
1112  while (le != &pdode->children) {
1114 
1115  if (RtlCompareMemory(&vc->uuid, &dlr->uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1116  vc->had_drive_letter = NT_SUCCESS(dlr->Status);
1117  break;
1118  }
1119 
1120  le = le->Flink;
1121  }
1122 
1123  ExFreePool(dlr->name.Buffer);
1124  ExFreePool(dlr);
1125  }
1126 
1128 }
1129 
1130 _Function_class_(IO_WORKITEM_ROUTINE)
1131 static void __stdcall drive_letter_callback(pdo_device_extension* pdode) {
1132  NTSTATUS Status;
1133  UNICODE_STRING mmdevpath;
1135  PFILE_OBJECT mountmgrfo;
1136 
1138  Status = IoGetDeviceObjectPointer(&mmdevpath, FILE_READ_ATTRIBUTES, &mountmgrfo, &mountmgr);
1139  if (!NT_SUCCESS(Status)) {
1140  ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
1141  return;
1142  }
1143 
1145 
1146  ObDereferenceObject(mountmgrfo);
1147 }
1148 
1150  NTSTATUS Status;
1151  LIST_ENTRY* le;
1153  volume_child* vc;
1155  UNICODE_STRING devpath2;
1156  bool inserted = false, new_pdo = false;
1157  pdo_device_extension* pdode = NULL;
1158  PDEVICE_OBJECT pdo = NULL;
1159  bool process_drive_letters = false;
1160 
1161  if (devpath->Length == 0)
1162  return;
1163 
1165 
1166  le = pdo_list.Flink;
1167  while (le != &pdo_list) {
1169 
1170  if (RtlCompareMemory(&pdode2->uuid, &sb->uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1171  pdode = pdode2;
1172  break;
1173  }
1174 
1175  le = le->Flink;
1176  }
1177 
1179  if (!NT_SUCCESS(Status)) {
1180  ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
1182  return;
1183  }
1184 
1185  if (!pdode) {
1186  if (no_pnp) {
1187  Status = IoReportDetectedDevice(drvobj, InterfaceTypeUndefined, 0xFFFFFFFF, 0xFFFFFFFF, NULL, NULL, 0, &pdo);
1188 
1189  if (!NT_SUCCESS(Status)) {
1190  ERR("IoReportDetectedDevice returned %08x\n", Status);
1192  return;
1193  }
1194 
1196 
1197  if (!pdode) {
1198  ERR("out of memory\n");
1200  return;
1201  }
1202  } else {
1205  if (!NT_SUCCESS(Status)) {
1206  ERR("IoCreateDevice returned %08x\n", Status);
1208  goto fail;
1209  }
1210 
1212 
1213  pdode = pdo->DeviceExtension;
1214  }
1215 
1216  RtlZeroMemory(pdode, sizeof(pdo_device_extension));
1217 
1218  pdode->type = VCB_TYPE_PDO;
1219  pdode->pdo = pdo;
1220  pdode->uuid = sb->uuid;
1221 
1223  InitializeListHead(&pdode->children);
1224  pdode->num_children = sb->num_devices;
1225  pdode->children_loaded = 0;
1226 
1227  pdo->Flags &= ~DO_DEVICE_INITIALIZING;
1228  pdo->SectorSize = (USHORT)sb->sector_size;
1229 
1231 
1232  new_pdo = true;
1233  } else {
1236 
1237  le = pdode->children.Flink;
1238  while (le != &pdode->children) {
1240 
1241  if (RtlCompareMemory(&vc2->uuid, &sb->dev_item.device_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1242  // duplicate, ignore
1245  goto fail;
1246  }
1247 
1248  le = le->Flink;
1249  }
1250  }
1251 
1253  if (!vc) {
1254  ERR("out of memory\n");
1255 
1258 
1259  goto fail;
1260  }
1261 
1262  vc->uuid = sb->dev_item.device_uuid;
1263  vc->devid = sb->dev_item.dev_id;
1264  vc->generation = sb->generation;
1265  vc->notification_entry = NULL;
1266 
1268  drvobj, pnp_removal, pdode, &vc->notification_entry);
1269  if (!NT_SUCCESS(Status))
1270  WARN("IoRegisterPlugPlayNotification returned %08x\n", Status);
1271 
1272  vc->devobj = DeviceObject;
1273  vc->fileobj = FileObject;
1274 
1275  devpath2 = *devpath;
1276 
1277  // The PNP path sometimes begins \\?\ and sometimes \??\. We need to remove this prefix
1278  // so we can compare properly if the device is removed.
1279  if (devpath->Length > 4 * sizeof(WCHAR) && devpath->Buffer[0] == '\\' && (devpath->Buffer[1] == '\\' || devpath->Buffer[1] == '?') &&
1280  devpath->Buffer[2] == '?' && devpath->Buffer[3] == '\\') {
1281  devpath2.Buffer = &devpath2.Buffer[3];
1282  devpath2.Length -= 3 * sizeof(WCHAR);
1283  devpath2.MaximumLength -= 3 * sizeof(WCHAR);
1284  }
1285 
1286  vc->pnp_name.Length = vc->pnp_name.MaximumLength = devpath2.Length;
1288 
1289  if (vc->pnp_name.Buffer)
1290  RtlCopyMemory(vc->pnp_name.Buffer, devpath2.Buffer, devpath2.Length);
1291  else {
1292  ERR("out of memory\n");
1293  vc->pnp_name.Length = vc->pnp_name.MaximumLength = 0;
1294  }
1295 
1296  vc->size = length;
1297  vc->seeding = sb->flags & BTRFS_SUPERBLOCK_FLAGS_SEEDING ? true : false;
1298  vc->disk_num = disk_num;
1299  vc->part_num = part_num;
1300  vc->had_drive_letter = false;
1301 
1302  le = pdode->children.Flink;
1303  while (le != &pdode->children) {
1305 
1306  if (vc2->generation < vc->generation) {
1307  if (le == pdode->children.Flink)
1308  pdode->num_children = sb->num_devices;
1309 
1311  inserted = true;
1312  break;
1313  }
1314 
1315  le = le->Flink;
1316  }
1317 
1318  if (!inserted)
1319  InsertTailList(&pdode->children, &vc->list_entry);
1320 
1321  pdode->children_loaded++;
1322 
1323  if (pdode->vde && pdode->vde->mounted_device) {
1325 
1326  ExAcquireResourceExclusiveLite(&Vcb->tree_lock, true);
1327 
1328  le = Vcb->devices.Flink;
1329  while (le != &Vcb->devices) {
1331 
1332  if (!dev->devobj && RtlCompareMemory(&dev->devitem.device_uuid, &sb->dev_item.device_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1333  dev->devobj = DeviceObject;
1334  dev->disk_num = disk_num;
1335  dev->part_num = part_num;
1336  init_device(Vcb, dev, false);
1337  break;
1338  }
1339 
1340  le = le->Flink;
1341  }
1342 
1343  ExReleaseResourceLite(&Vcb->tree_lock);
1344  }
1345 
1346  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
1347  pdode->removable = true;
1348 
1349  if (pdode->vde && pdode->vde->device)
1350  pdode->vde->device->Characteristics |= FILE_REMOVABLE_MEDIA;
1351  }
1352 
1353  if (pdode->num_children == pdode->children_loaded || (pdode->children_loaded == 1 && allow_degraded_mount(&sb->uuid))) {
1354  if ((!new_pdo || !no_pnp) && pdode->vde) {
1355  Status = IoSetDeviceInterfaceState(&pdode->vde->bus_name, true);
1356  if (!NT_SUCCESS(Status))
1357  WARN("IoSetDeviceInterfaceState returned %08x\n", Status);
1358  }
1359 
1360  process_drive_letters = true;
1361  }
1362 
1364 
1365  if (new_pdo)
1366  InsertTailList(&pdo_list, &pdode->list_entry);
1367 
1369 
1370  if (process_drive_letters)
1371  drive_letter_callback(pdode);
1372 
1373  if (new_pdo) {
1374  if (no_pnp)
1375  AddDevice(drvobj, pdo);
1376  else {
1379  }
1380  }
1381 
1382  return;
1383 
1384 fail:
1386 }
DEVICE_TYPE DeviceType
Definition: ntddstor.h:232
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
_In_ PVOID NotificationStructure
Definition: iofuncs.h:1203
NTSTATUS NTAPI IoUnregisterPlugPlayNotification(IN PVOID NotificationEntry)
Definition: pnpnotify.c:371
#define VCB_TYPE_PDO
Definition: btrfs_drv.h:667
static NTSTATUS vol_query_stable_guid(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:796
#define hex_digit(c)
Definition: btrfs_drv.h:1725
#define IN
Definition: typedefs.h:38
PDEVICE_OBJECT buspdo
Definition: btrfs_drv.h:824
NTSTATUS vol_device_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:820
static NTSTATUS vol_get_length(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:591
#define FILE_DEVICE_DISK
Definition: winioctl.h:112
tIoUnregisterPlugPlayNotificationEx fIoUnregisterPlugPlayNotificationEx
Definition: btrfs.c:98
UNICODE_STRING pnp_name
Definition: btrfs_drv.h:835
static NTSTATUS vol_query_device_name(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:374
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define true
Definition: stdbool.h:37
NTSTATUS vol_lock_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:368
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
Definition: http.c:7094
#define BTRFS_SUPERBLOCK_FLAGS_SEEDING
Definition: btrfs.h:117
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
_In_ PIRP Irp
Definition: csq.h:116
superblock * sb
Definition: btrfs.c:4137
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
GLsizei const GLchar ** path
Definition: glext.h:7234
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
DRIVER_ADD_DEVICE AddDevice
Definition: parport.h:72
PDEVICE_OBJECT device
Definition: btrfs_drv.h:850
#define WARN(fmt,...)
Definition: debug.h:111
VOID NTAPI ExConvertExclusiveToSharedLite(IN PERESOURCE Resource)
Definition: resource.c:1402
LONG NTSTATUS
Definition: precomp.h:26
static bool allow_degraded_mount(BTRFS_UUID *uuid)
Definition: volume.c:949
USHORT UniqueIdLength
Definition: imports.h:138
#define IOCTL_DISK_CHECK_VERIFY
Definition: cdrw_usr.h:175
NTSTATUS vol_query_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:306
#define FILE_OPENED
Definition: nt_native.h:769
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
NTSTATUS NTAPI ExDeleteResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1456
NTSTATUS vol_write(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:225
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define IOCTL_DISK_IS_WRITABLE
Definition: cdrw_usr.h:172
PDEVICE_OBJECT pdo
Definition: btrfs_drv.h:852
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
static NTSTATUS vol_get_disk_extents(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:470
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
ULONG BytesPerSector
Definition: ntdddisk.h:381
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
GLuint GLuint end
Definition: gl.h:1545
ULONG TracksPerCylinder
Definition: ntdddisk.h:379
WCHAR DeviceName[]
Definition: adapter.cpp:21
ULONG part_num
Definition: btrfs_drv.h:841
#define InsertTailList(ListHead, Entry)
KEVENT Event
Definition: volume.c:129
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define IOCTL_VOLUME_IS_DYNAMIC
Definition: volume.c:25
#define MOUNTMGR_DEVICE_NAME
Definition: imports.h:76
struct _MOUNTDEV_STABLE_GUID MOUNTDEV_STABLE_GUID
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
void init_device(_In_ device_extension *Vcb, _Inout_ device *dev, _In_ bool get_nums)
Definition: btrfs.c:3273
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
BTRFS_UUID uuid
Definition: btrfs_drv.h:830
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
UNICODE_STRING name
Definition: btrfs_drv.h:849
PDEVICE_OBJECT pdo
Definition: btrfs_drv.h:865
uint64_t num_children
Definition: btrfs_drv.h:869
#define ALLOC_TAG
Definition: btrfs_drv.h:91
UNICODE_STRING bus_name
Definition: btrfs_drv.h:854
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
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
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:80
NTSTATUS NTAPI IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, IN INTERFACE_TYPE LegacyBusType, IN ULONG BusNumber, IN ULONG SlotNumber, IN PCM_RESOURCE_LIST ResourceList, IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements OPTIONAL, IN BOOLEAN ResourceAssigned, IN OUT PDEVICE_OBJECT *DeviceObject OPTIONAL)
Definition: pnpreport.c:162
uint64_t generation
Definition: btrfs_drv.h:832
#define IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER
Definition: mountmgr.h:34
NTSTATUS mountmgr_add_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
Definition: volume.c:904
Definition: devices.h:37
uint32_t no_pnp
Definition: btrfs.c:90
uint64_t num_devices
Definition: btrfs.h:221
IO_STATUS_BLOCK iosb
Definition: volume.c:128
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
bool seeding
Definition: btrfs_drv.h:837
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
struct _GET_LENGTH_INFORMATION GET_LENGTH_INFORMATION
struct _MOUNTDEV_NAME MOUNTDEV_NAME
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define DO_BUS_ENUMERATED_DEVICE
#define offsetof(TYPE, MEMBER)
char ext[3]
Definition: mkdosfs.c:358
static NTSTATUS vol_get_drive_geometry(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: volume.c:622
PDEVICE_OBJECT devobj
Definition: btrfs_drv.h:833
#define IOCTL_VOLUME_ONLINE
Definition: ntddvol.h:62
#define IoCompleteRequest
Definition: irp.c:1240
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
DEV_ITEM dev_item
Definition: btrfs.h:235
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:132
#define UNUSED(x)
Definition: btrfs_drv.h:86
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
struct pdo_device_extension * pdode
Definition: btrfs_drv.h:853
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
GLuint GLfloat * val
Definition: glext.h:7180
_Function_class_(IO_COMPLETION_ROUTINE)
Definition: volume.c:132
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 IOCTL_MOUNTDEV_QUERY_STABLE_GUID
Definition: imports.h:255
PDRIVER_OBJECT drvobj
Definition: btrfs.c:66
BTRFS_UUID device_uuid
Definition: btrfs.h:174
#define IOCTL_STORAGE_CHECK_VERIFY
Definition: ntddstor.h:87
uint64_t flags
Definition: btrfs.h:211
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define STATUS_NOT_FOUND
Definition: shellext.h:72
uint64_t children_loaded
Definition: btrfs_drv.h:870
struct _MOUNTDEV_UNIQUE_ID MOUNTDEV_UNIQUE_ID
#define TRACE(s)
Definition: solgame.cpp:4
NTSTATUS vol_file_system_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:362
NTSTATUS vol_query_ea(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:318
NTSTATUS vol_flush_buffers(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:330
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define IOCTL_VOLUME_POST_ONLINE
Definition: volume.c:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:377
static NTSTATUS vol_is_dynamic(PIRP Irp)
Definition: volume.c:428
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
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:2813
ULONG SectorsPerTrack
Definition: ntdddisk.h:380
bool had_drive_letter
Definition: btrfs_drv.h:838
#define Vcb
Definition: cdprocs.h:1425
NTSTATUS vol_read(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:144
LIST_ENTRY list_entry
Definition: btrfs_drv.h:874
static NTSTATUS vol_ioctl_passthrough(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:726
MEDIA_TYPE MediaType
Definition: ntdddisk.h:378
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define __stdcall
Definition: typedefs.h:25
static NTSTATUS vol_get_device_number(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:676
ERESOURCE child_lock
Definition: btrfs_drv.h:871
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
void * notification_entry
Definition: btrfs_drv.h:839
PDEVICE_OBJECT mounted_device
Definition: btrfs_drv.h:851
* PFILE_OBJECT
Definition: iotypes.h:1955
ULONG disk_num
Definition: btrfs_drv.h:840
LIST_ENTRY list_entry
Definition: volume.c:1024
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
uint64_t generation
Definition: btrfs.h:213
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const BYTE ext2[]
Definition: encode.c:2699
PFILE_OBJECT fileobj
Definition: btrfs_drv.h:834
PDEVICE_OBJECT master_devobj
Definition: btrfs.c:67
NTSTATUS vol_close(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:95
static const WCHAR L[]
Definition: oid.c:1250
#define InterlockedDecrement
Definition: armddk.h:52
struct _STORAGE_DEVICE_NUMBER STORAGE_DEVICE_NUMBER
uint64_t dev_id
Definition: btrfs.h:162
void add_volume_device(superblock *sb, PUNICODE_STRING devpath, uint64_t length, ULONG disk_num, ULONG part_num)
Definition: volume.c:1149
NTSTATUS NTAPI IoRegisterPlugPlayNotification(IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory, IN ULONG EventCategoryFlags, IN PVOID EventCategoryData OPTIONAL, IN PDRIVER_OBJECT DriverObject, IN PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine, IN PVOID Context, OUT PVOID *NotificationEntry)
Definition: pnpnotify.c:249
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
Definition: ntddvol.h:41
Definition: typedefs.h:117
NTSTATUS vol_directory_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:356
struct _cl_event * event
Definition: glext.h:7739
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
BYTE uint8_t
Definition: msvideo1.c:66
LARGE_INTEGER Length
Definition: winioctl.h:423
Status
Definition: gdiplustypes.h:24
NTSTATUS vol_query_volume_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:336
#define ERR(fmt,...)
Definition: debug.h:109
void free_vol(volume_device_extension *vde)
Definition: volume.c:50
NTSTATUS vol_query_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:892
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
struct _DISK_GEOMETRY DISK_GEOMETRY
NTSTATUS vol_set_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:312
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
NTSTATUS(__stdcall * tIoUnregisterPlugPlayNotificationEx)(PVOID NotificationEntry)
Definition: btrfs_drv.h:1834
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:5111
ERESOURCE pdo_list_lock
Definition: btrfs.c:106
LIST_ENTRY pdo_list
Definition: btrfs.c:107
UINT64 uint64_t
Definition: types.h:77
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define IRP_INPUT_OPERATION
#define IRP_BUFFERED_IO
#define InterlockedIncrement
Definition: armddk.h:53
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
BTRFS_UUID uuid
Definition: volume.c:1027
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
NTSTATUS vol_set_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:898
unsigned short USHORT
Definition: pedump.c:61
#define IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
Definition: imports.h:99
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
BTRFS_UUID uuid
Definition: btrfs.h:209
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
PDEVICE_OBJECT busobj
Definition: btrfs.c:67
Definition: list.h:27
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
UNICODE_STRING registry_path
Definition: btrfs.c:92
uint32_t mount_allow_degraded
Definition: btrfs.c:87
UINT32 uint32_t
Definition: types.h:75
static NTSTATUS vol_is_writable(volume_device_extension *vde)
Definition: volume.c:560
NTSTATUS vol_set_volume_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:342
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
static void drive_letter_callback2(pdo_device_extension *pdode, PDEVICE_OBJECT mountmgr)
Definition: volume.c:1030
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_DEALLOCATE_BUFFER
volume_device_extension * vde
Definition: btrfs_drv.h:864
NTSTATUS vol_cleanup(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:348
uint64_t size
Definition: btrfs_drv.h:836
Definition: name.c:38
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
ULONG ERESOURCE
Definition: env_spec_w32.h:594
NTSTATUS vol_create(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:36
LIST_ENTRY list_entry
Definition: btrfs_drv.h:842
Definition: msctf.idl:510
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS pnp_query_remove_device(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pnp.c:181
#define IO_NO_INCREMENT
Definition: iotypes.h:566
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
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS remove_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
Definition: search.c:210
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
NTSTATUS vol_set_ea(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:324
uint64_t devid
Definition: btrfs_drv.h:831
static NTSTATUS vol_check_verify(volume_device_extension *vde)
Definition: volume.c:444
uint32_t sector_size
Definition: btrfs.h:222
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
LIST_ENTRY children
Definition: btrfs_drv.h:872
static const BYTE ext3[]
Definition: encode.c:2701
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define REG_DWORD
Definition: sdbapi.c:596
static NTSTATUS vol_query_unique_id(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:398
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define IOCTL_VOLUME_GET_GPT_ATTRIBUTES
Definition: ntddvol.h:56
#define UInt32x32To64(a, b)
Definition: intsafe.h:258
UCHAR UniqueId[1]
Definition: imports.h:139
static NTSTATUS vol_get_gpt_attributes(PIRP Irp)
Definition: volume.c:660
NTSTATUS vol_shutdown(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:886
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
#define IOCTL_MOUNTDEV_LINK_CREATED
Definition: imports.h:106
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
UNICODE_STRING name
Definition: volume.c:1025
LONGLONG QuadPart
Definition: typedefs.h:112
struct _DISK_EXTENT DISK_EXTENT
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
GLuint const GLchar * name
Definition: glext.h:6031