ReactOS  0.4.14-dev-114-gc8cbd56
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;
34 
37 
38  TRACE("(%p, %p)\n", DeviceObject, Irp);
39 
40  if (vde->removing)
42 
43  Irp->IoStatus.Information = FILE_OPENED;
45 
46  return STATUS_SUCCESS;
47 }
48 
51  pdo_device_extension* pdode = vde->pdode;
52 
53  TRACE("(%p, %p)\n", DeviceObject, Irp);
54 
55  Irp->IoStatus.Information = 0;
56 
58 
60 
61  if (InterlockedDecrement(&vde->open_count) == 0 && vde->removing) {
63  UNICODE_STRING mmdevpath;
64  PDEVICE_OBJECT mountmgr;
65  PFILE_OBJECT mountmgrfo;
66  PDEVICE_OBJECT pdo;
67 
69  Status = IoGetDeviceObjectPointer(&mmdevpath, FILE_READ_ATTRIBUTES, &mountmgrfo, &mountmgr);
70  if (!NT_SUCCESS(Status))
71  ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
72  else {
73  remove_drive_letter(mountmgr, &vde->name);
74 
75  ObDereferenceObject(mountmgrfo);
76  }
77 
78  if (vde->mounted_device) {
80 
81  Vcb->vde = NULL;
82  }
83 
84  if (vde->name.Buffer)
85  ExFreePool(vde->name.Buffer);
86 
89 
90  if (vde->pdo->AttachedDevice)
91  IoDetachDevice(vde->pdo);
92 
93  pdo = vde->pdo;
94  IoDeleteDevice(vde->device);
95 
96  if (!no_pnp)
97  IoDeleteDevice(pdo);
98  } else
100 
102 
103  return STATUS_SUCCESS;
104 }
105 
106 typedef struct {
110 
111 _Function_class_(IO_COMPLETION_ROUTINE)
112 static NTSTATUS __stdcall vol_read_completion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID conptr) {
113  vol_read_context* context = conptr;
114 
116 
117  context->iosb = Irp->IoStatus;
118  KeSetEvent(&context->Event, 0, false);
119 
121 }
122 
125  pdo_device_extension* pdode = vde->pdode;
126  volume_child* vc;
128  PIRP Irp2;
130  PIO_STACK_LOCATION IrpSp, IrpSp2;
131 
132  TRACE("(%p, %p)\n", DeviceObject, Irp);
133 
135 
136  if (IsListEmpty(&pdode->children)) {
139  goto end;
140  }
141 
143 
144  // We can't use IoSkipCurrentIrpStackLocation as the device isn't in our stack
145 
146  Irp2 = IoAllocateIrp(vc->devobj->StackSize, false);
147 
148  if (!Irp2) {
149  ERR("IoAllocateIrp failed\n");
152  goto end;
153  }
154 
156  IrpSp2 = IoGetNextIrpStackLocation(Irp2);
157 
158  IrpSp2->MajorFunction = IRP_MJ_READ;
159  IrpSp2->FileObject = vc->fileobj;
160 
161  if (vc->devobj->Flags & DO_BUFFERED_IO) {
162  Irp2->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool, IrpSp->Parameters.Read.Length, ALLOC_TAG);
163  if (!Irp2->AssociatedIrp.SystemBuffer) {
164  ERR("out of memory\n");
167  goto end;
168  }
169 
171 
172  Irp2->UserBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
173  } else if (vc->devobj->Flags & DO_DIRECT_IO)
174  Irp2->MdlAddress = Irp->MdlAddress;
175  else
176  Irp2->UserBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
177 
178  IrpSp2->Parameters.Read.Length = IrpSp->Parameters.Read.Length;
179  IrpSp2->Parameters.Read.ByteOffset.QuadPart = IrpSp->Parameters.Read.ByteOffset.QuadPart;
180 
182  Irp2->UserIosb = &context.iosb;
183 
184  IoSetCompletionRoutine(Irp2, vol_read_completion, &context, true, true, true);
185 
186  Status = IoCallDriver(vc->devobj, Irp2);
187 
188  if (Status == STATUS_PENDING) {
190  Status = context.iosb.Status;
191  }
192 
194 
195  Irp->IoStatus.Information = context.iosb.Information;
196 
197 end:
198  Irp->IoStatus.Status = Status;
200 
201  return Status;
202 }
203 
206  pdo_device_extension* pdode = vde->pdode;
207  volume_child* vc;
209  PIRP Irp2;
211  PIO_STACK_LOCATION IrpSp, IrpSp2;
212 
213  TRACE("(%p, %p)\n", DeviceObject, Irp);
214 
216 
217  if (IsListEmpty(&pdode->children)) {
220  goto end;
221  }
222 
224 
225  if (vc->list_entry.Flink != &pdode->children) { // more than once device
228  goto end;
229  }
230 
231  // We can't use IoSkipCurrentIrpStackLocation as the device isn't in our stack
232 
233  Irp2 = IoAllocateIrp(vc->devobj->StackSize, false);
234 
235  if (!Irp2) {
236  ERR("IoAllocateIrp failed\n");
239  goto end;
240  }
241 
243  IrpSp2 = IoGetNextIrpStackLocation(Irp2);
244 
245  IrpSp2->MajorFunction = IRP_MJ_WRITE;
246  IrpSp2->FileObject = vc->fileobj;
247 
248  if (vc->devobj->Flags & DO_BUFFERED_IO) {
249  Irp2->AssociatedIrp.SystemBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
250 
251  Irp2->Flags |= IRP_BUFFERED_IO;
252 
253  Irp2->UserBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
254  } else if (vc->devobj->Flags & DO_DIRECT_IO)
255  Irp2->MdlAddress = Irp->MdlAddress;
256  else
257  Irp2->UserBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
258 
259  IrpSp2->Parameters.Write.Length = IrpSp->Parameters.Write.Length;
260  IrpSp2->Parameters.Write.ByteOffset.QuadPart = IrpSp->Parameters.Write.ByteOffset.QuadPart;
261 
263  Irp2->UserIosb = &context.iosb;
264 
265  IoSetCompletionRoutine(Irp2, vol_read_completion, &context, true, true, true);
266 
267  Status = IoCallDriver(vc->devobj, Irp2);
268 
269  if (Status == STATUS_PENDING) {
271  Status = context.iosb.Status;
272  }
273 
275 
276  Irp->IoStatus.Information = context.iosb.Information;
277 
278 end:
279  Irp->IoStatus.Status = Status;
281 
282  return Status;
283 }
284 
286  TRACE("(%p, %p)\n", DeviceObject, Irp);
287 
289 }
290 
292  TRACE("(%p, %p)\n", DeviceObject, Irp);
293 
295 }
296 
298  TRACE("(%p, %p)\n", DeviceObject, Irp);
299 
301 }
302 
304  TRACE("(%p, %p)\n", DeviceObject, Irp);
305 
307 }
308 
310  TRACE("(%p, %p)\n", DeviceObject, Irp);
311 
312  return STATUS_SUCCESS;
313 }
314 
316  TRACE("(%p, %p)\n", DeviceObject, Irp);
317 
319 }
320 
322  TRACE("(%p, %p)\n", DeviceObject, Irp);
323 
325 }
326 
328  TRACE("(%p, %p)\n", DeviceObject, Irp);
329 
330  Irp->IoStatus.Information = 0;
331 
332  return STATUS_SUCCESS;
333 }
334 
336  TRACE("(%p, %p)\n", DeviceObject, Irp);
337 
339 }
340 
342  TRACE("(%p, %p)\n", DeviceObject, Irp);
343 
345 }
346 
348  TRACE("(%p, %p)\n", DeviceObject, Irp);
349 
351 }
352 
356 
357  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_NAME)) {
358  Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
360  }
361 
362  name = Irp->AssociatedIrp.SystemBuffer;
363  name->NameLength = vde->name.Length;
364 
365  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < offsetof(MOUNTDEV_NAME, Name[0]) + name->NameLength) {
366  Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
367  return STATUS_BUFFER_OVERFLOW;
368  }
369 
370  RtlCopyMemory(name->Name, vde->name.Buffer, vde->name.Length);
371 
372  Irp->IoStatus.Information = offsetof(MOUNTDEV_NAME, Name[0]) + name->NameLength;
373 
374  return STATUS_SUCCESS;
375 }
376 
379  MOUNTDEV_UNIQUE_ID* mduid;
380  pdo_device_extension* pdode;
381 
382  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_UNIQUE_ID)) {
383  Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
385  }
386 
387  mduid = Irp->AssociatedIrp.SystemBuffer;
388  mduid->UniqueIdLength = sizeof(BTRFS_UUID);
389 
390  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < offsetof(MOUNTDEV_UNIQUE_ID, UniqueId[0]) + mduid->UniqueIdLength) {
391  Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
392  return STATUS_BUFFER_OVERFLOW;
393  }
394 
395  if (!vde->pdo)
397 
398  pdode = vde->pdode;
399 
400  RtlCopyMemory(mduid->UniqueId, &pdode->uuid, sizeof(BTRFS_UUID));
401 
402  Irp->IoStatus.Information = offsetof(MOUNTDEV_UNIQUE_ID, UniqueId[0]) + mduid->UniqueIdLength;
403 
404  return STATUS_SUCCESS;
405 }
406 
409  uint8_t* buf;
410 
411  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0 || !Irp->AssociatedIrp.SystemBuffer)
413 
414  buf = (uint8_t*)Irp->AssociatedIrp.SystemBuffer;
415 
416  *buf = 1;
417 
418  Irp->IoStatus.Information = 1;
419 
420  return STATUS_SUCCESS;
421 }
422 
424  pdo_device_extension* pdode = vde->pdode;
426  LIST_ENTRY* le;
427 
429 
430  le = pdode->children.Flink;
431  while (le != &pdode->children) {
433 
435  if (!NT_SUCCESS(Status))
436  goto end;
437 
438  le = le->Flink;
439  }
440 
442 
443 end:
445 
446  return Status;
447 }
448 
450  pdo_device_extension* pdode = vde->pdode;
452  LIST_ENTRY* le;
453  ULONG num_extents = 0, i, max_extents = 1;
456 
457  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(VOLUME_DISK_EXTENTS))
459 
461 
462  le = pdode->children.Flink;
463  while (le != &pdode->children) {
466 
469  ERR("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS returned %08x\n", Status);
470  goto end;
471  }
472 
473  num_extents += ext2.NumberOfDiskExtents;
474 
475  if (ext2.NumberOfDiskExtents > max_extents)
476  max_extents = ext2.NumberOfDiskExtents;
477 
478  le = le->Flink;
479  }
480 
481  ext = Irp->AssociatedIrp.SystemBuffer;
482 
483  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (num_extents * sizeof(DISK_EXTENT))) {
484  Irp->IoStatus.Information = offsetof(VOLUME_DISK_EXTENTS, Extents[0]);
485  ext->NumberOfDiskExtents = num_extents;
487  goto end;
488  }
489 
490  ext3 = ExAllocatePoolWithTag(PagedPool, offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (max_extents * sizeof(DISK_EXTENT)), ALLOC_TAG);
491  if (!ext3) {
492  ERR("out of memory\n");
494  goto end;
495  }
496 
497  i = 0;
498  ext->NumberOfDiskExtents = 0;
499 
500  le = pdode->children.Flink;
501  while (le != &pdode->children) {
503 
505  (ULONG)offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (max_extents * sizeof(DISK_EXTENT)), false, NULL);
506  if (!NT_SUCCESS(Status)) {
507  ERR("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS returned %08x\n", Status);
508  ExFreePool(ext3);
509  goto end;
510  }
511 
512  if (i + ext3->NumberOfDiskExtents > num_extents) {
513  Irp->IoStatus.Information = offsetof(VOLUME_DISK_EXTENTS, Extents[0]);
514  ext->NumberOfDiskExtents = i + ext3->NumberOfDiskExtents;
516  ExFreePool(ext3);
517  goto end;
518  }
519 
520  RtlCopyMemory(&ext->Extents[i], ext3->Extents, sizeof(DISK_EXTENT) * ext3->NumberOfDiskExtents);
521  i += ext3->NumberOfDiskExtents;
522 
523  le = le->Flink;
524  }
525 
526  ExFreePool(ext3);
527 
529 
530  ext->NumberOfDiskExtents = i;
531  Irp->IoStatus.Information = offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (i * sizeof(DISK_EXTENT));
532 
533 end:
535 
536  return Status;
537 }
538 
540  pdo_device_extension* pdode = vde->pdode;
542  LIST_ENTRY* le;
543  bool writable = false;
544 
546 
547  le = pdode->children.Flink;
548  while (le != &pdode->children) {
550 
551  Status = dev_ioctl(vc->devobj, IOCTL_DISK_IS_WRITABLE, NULL, 0, NULL, 0, true, NULL);
552 
553  if (NT_SUCCESS(Status)) {
554  writable = true;
555  break;
556  } else if (Status != STATUS_MEDIA_WRITE_PROTECTED)
557  goto end;
558 
559  le = le->Flink;
560  }
561 
563 
564 end:
566 
567  return STATUS_SUCCESS;
568 }
569 
572  pdo_device_extension* pdode = vde->pdode;
574  LIST_ENTRY* le;
575 
576  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GET_LENGTH_INFORMATION))
578 
579  gli = (GET_LENGTH_INFORMATION*)Irp->AssociatedIrp.SystemBuffer;
580 
581  gli->Length.QuadPart = 0;
582 
584 
585  le = pdode->children.Flink;
586  while (le != &pdode->children) {
588 
589  gli->Length.QuadPart += vc->size;
590 
591  le = le->Flink;
592  }
593 
595 
596  Irp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION);
597 
598  return STATUS_SUCCESS;
599 }
600 
603  pdo_device_extension* pdode = vde->pdode;
605  DISK_GEOMETRY* geom;
607  LIST_ENTRY* le;
608 
609  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY))
611 
612  length = 0;
613 
615 
616  le = pdode->children.Flink;
617  while (le != &pdode->children) {
619 
620  length += vc->size;
621 
622  le = le->Flink;
623  }
624 
626 
627  geom = (DISK_GEOMETRY*)Irp->AssociatedIrp.SystemBuffer;
628  geom->BytesPerSector = DeviceObject->SectorSize == 0 ? 0x200 : DeviceObject->SectorSize;
629  geom->SectorsPerTrack = 0x3f;
630  geom->TracksPerCylinder = 0xff;
633 
634  Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
635 
636  return STATUS_SUCCESS;
637 }
638 
642 
643  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(VOLUME_GET_GPT_ATTRIBUTES_INFORMATION))
645 
646  vggai = (VOLUME_GET_GPT_ATTRIBUTES_INFORMATION*)Irp->AssociatedIrp.SystemBuffer;
647 
648  vggai->GptAttributes = 0;
649 
650  Irp->IoStatus.Information = sizeof(VOLUME_GET_GPT_ATTRIBUTES_INFORMATION);
651 
652  return STATUS_SUCCESS;
653 }
654 
656  pdo_device_extension* pdode = vde->pdode;
658  volume_child* vc;
660 
661  // If only one device, return its disk number. This is needed for ejection to work.
662 
663  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_DEVICE_NUMBER))
665 
667 
668  if (IsListEmpty(&pdode->children) || pdode->num_children > 1) {
671  }
672 
674 
675  if (vc->disk_num == 0xffffffff) {
678  }
679 
680  sdn = (STORAGE_DEVICE_NUMBER*)Irp->AssociatedIrp.SystemBuffer;
681 
683  sdn->DeviceNumber = vc->disk_num;
684  sdn->PartitionNumber = vc->part_num;
685 
687 
688  Irp->IoStatus.Information = sizeof(STORAGE_DEVICE_NUMBER);
689 
690  return STATUS_SUCCESS;
691 }
692 
693 _Function_class_(IO_COMPLETION_ROUTINE)
694 static NTSTATUS __stdcall vol_ioctl_completion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID conptr) {
695  KEVENT* event = conptr;
696 
698  UNUSED(Irp);
699 
700  KeSetEvent(event, 0, false);
701 
703 }
704 
707  volume_child* vc;
708  PIRP Irp2;
709  PIO_STACK_LOCATION IrpSp, IrpSp2;
710  KEVENT Event;
711  pdo_device_extension* pdode = vde->pdode;
712 
713  TRACE("(%p, %p)\n", vde, Irp);
714 
716 
717  if (IsListEmpty(&pdode->children)) {
720  }
721 
723 
724  if (vc->list_entry.Flink != &pdode->children) { // more than one device
727  }
728 
729  Irp2 = IoAllocateIrp(vc->devobj->StackSize, false);
730 
731  if (!Irp2) {
732  ERR("IoAllocateIrp failed\n");
735  }
736 
738  IrpSp2 = IoGetNextIrpStackLocation(Irp2);
739 
740  IrpSp2->MajorFunction = IrpSp->MajorFunction;
741  IrpSp2->MinorFunction = IrpSp->MinorFunction;
742  IrpSp2->FileObject = vc->fileobj;
743 
744  IrpSp2->Parameters.DeviceIoControl.OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
745  IrpSp2->Parameters.DeviceIoControl.InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
746  IrpSp2->Parameters.DeviceIoControl.IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
747  IrpSp2->Parameters.DeviceIoControl.Type3InputBuffer = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
748 
749  Irp2->AssociatedIrp.SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
750  Irp2->MdlAddress = Irp->MdlAddress;
751  Irp2->UserBuffer = Irp->UserBuffer;
752  Irp2->Flags = Irp->Flags;
753 
755 
756  IoSetCompletionRoutine(Irp2, vol_ioctl_completion, &Event, true, true, true);
757 
758  Status = IoCallDriver(vc->devobj, Irp2);
759 
760  if (Status == STATUS_PENDING) {
762  Status = Irp2->IoStatus.Status;
763  }
764 
765  Irp->IoStatus.Status = Irp2->IoStatus.Status;
766  Irp->IoStatus.Information = Irp2->IoStatus.Information;
767 
769 
770  return Status;
771 }
772 
775  MOUNTDEV_STABLE_GUID* mdsg;
776  pdo_device_extension* pdode;
777 
778  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_STABLE_GUID)) {
779  Irp->IoStatus.Information = sizeof(MOUNTDEV_STABLE_GUID);
781  }
782 
783  mdsg = Irp->AssociatedIrp.SystemBuffer;
784 
785  if (!vde->pdo)
787 
788  pdode = vde->pdode;
789 
790  RtlCopyMemory(&mdsg->StableGuid, &pdode->uuid, sizeof(BTRFS_UUID));
791 
792  Irp->IoStatus.Information = sizeof(MOUNTDEV_STABLE_GUID);
793 
794  return STATUS_SUCCESS;
795 }
796 
800 
801  TRACE("(%p, %p)\n", DeviceObject, Irp);
802 
803  Irp->IoStatus.Information = 0;
804 
805  switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
807  return vol_query_device_name(vde, Irp);
808 
810  return vol_query_unique_id(vde, Irp);
811 
813  return vol_get_device_number(vde, Irp);
814 
816  TRACE("unhandled control code IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME\n");
817  break;
818 
820  return vol_query_stable_guid(vde, Irp);
821 
823  TRACE("unhandled control code IOCTL_MOUNTDEV_LINK_CREATED\n");
824  break;
825 
827  return vol_get_gpt_attributes(Irp);
828 
830  return vol_is_dynamic(Irp);
831 
832  case IOCTL_VOLUME_ONLINE:
833  Irp->IoStatus.Information = 0;
834  return STATUS_SUCCESS;
835 
837  Irp->IoStatus.Information = 0;
838  return STATUS_SUCCESS;
839 
842 
844  return vol_is_writable(vde);
845 
847  return vol_get_length(vde, Irp);
848 
851  return vol_check_verify(vde);
852 
854  return vol_get_disk_extents(vde, Irp);
855 
856  default: // pass ioctl through if only one child device
857  return vol_ioctl_passthrough(vde, Irp);
858  }
859 
861 }
862 
864  TRACE("(%p, %p)\n", DeviceObject, Irp);
865 
867 }
868 
870  TRACE("(%p, %p)\n", DeviceObject, Irp);
871 
873 }
874 
876  TRACE("(%p, %p)\n", DeviceObject, Irp);
877 
879 }
880 
883  ULONG mmdltsize;
886 
887  mmdltsize = (ULONG)offsetof(MOUNTMGR_DRIVE_LETTER_TARGET, DeviceName[0]) + devpath->Length;
888 
889  mmdlt = ExAllocatePoolWithTag(NonPagedPool, mmdltsize, ALLOC_TAG);
890  if (!mmdlt) {
891  ERR("out of memory\n");
893  }
894 
895  mmdlt->DeviceNameLength = devpath->Length;
896  RtlCopyMemory(&mmdlt->DeviceName, devpath->Buffer, devpath->Length);
897  TRACE("mmdlt = %.*S\n", mmdlt->DeviceNameLength / sizeof(WCHAR), mmdlt->DeviceName);
898 
899  Status = dev_ioctl(mountmgr, IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER, mmdlt, mmdltsize, &mmdli, sizeof(MOUNTMGR_DRIVE_LETTER_INFORMATION), false, NULL);
900 
901  if (!NT_SUCCESS(Status))
902  ERR("IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER returned %08x\n", Status);
903  else
904  TRACE("DriveLetterWasAssigned = %u, CurrentDriveLetter = %c\n", mmdli.DriveLetterWasAssigned, mmdli.CurrentDriveLetter);
905 
906  ExFreePool(mmdlt);
907 
908  return Status;
909 }
910 
911 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE)
915 
916  if (RtlCompareMemory(&tdrn->Event, &GUID_TARGET_DEVICE_QUERY_REMOVE, sizeof(GUID)) == sizeof(GUID)) {
917  TRACE("GUID_TARGET_DEVICE_QUERY_REMOVE\n");
918 
919  if (pdode->vde && pdode->vde->mounted_device)
921  }
922 
923  return STATUS_SUCCESS;
924 }
925 
927  HANDLE h;
930  UNICODE_STRING path, adus;
931  uint32_t degraded = mount_allow_degraded;
932  ULONG i, j, kvfilen, retlen;
934 
935  path.Length = path.MaximumLength = registry_path.Length + (37 * sizeof(WCHAR));
937 
938  if (!path.Buffer) {
939  ERR("out of memory\n");
940  return false;
941  }
942 
944  i = registry_path.Length / sizeof(WCHAR);
945 
946  path.Buffer[i] = '\\';
947  i++;
948 
949  for (j = 0; j < 16; j++) {
950  path.Buffer[i] = hex_digit((uuid->uuid[j] & 0xF0) >> 4);
951  path.Buffer[i+1] = hex_digit(uuid->uuid[j] & 0xF);
952 
953  i += 2;
954 
955  if (j == 3 || j == 5 || j == 7 || j == 9) {
956  path.Buffer[i] = '-';
957  i++;
958  }
959  }
960 
962 
963  kvfilen = (ULONG)offsetof(KEY_VALUE_FULL_INFORMATION, Name[0]) + (255 * sizeof(WCHAR));
964  kvfi = ExAllocatePoolWithTag(PagedPool, kvfilen, ALLOC_TAG);
965  if (!kvfi) {
966  ERR("out of memory\n");
967  ExFreePool(path.Buffer);
968  return false;
969  }
970 
971  Status = ZwOpenKey(&h, KEY_QUERY_VALUE, &oa);
973  goto end;
974  else if (!NT_SUCCESS(Status)) {
975  ERR("ZwOpenKey returned %08x\n", Status);
976  goto end;
977  }
978 
979  adus.Buffer = L"AllowDegraded";
980  adus.Length = adus.MaximumLength = sizeof(adus.Buffer) - sizeof(WCHAR);
981 
982  if (NT_SUCCESS(ZwQueryValueKey(h, &adus, KeyValueFullInformation, kvfi, kvfilen, &retlen))) {
983  if (kvfi->Type == REG_DWORD && kvfi->DataLength >= sizeof(uint32_t)) {
984  uint32_t* val = (uint32_t*)((uint8_t*)kvfi + kvfi->DataOffset);
985 
986  degraded = *val;
987  }
988  }
989 
990  ZwClose(h);
991 
992 end:
993  ExFreePool(kvfi);
994 
995  ExFreePool(path.Buffer);
996 
997  return degraded;
998 }
999 
1000 typedef struct {
1004 
1005 _Function_class_(IO_WORKITEM_ROUTINE)
1006 static void __stdcall drive_letter_callback(PDEVICE_OBJECT DeviceObject, PVOID con) {
1008  NTSTATUS Status;
1009  UNICODE_STRING mmdevpath;
1010  PDEVICE_OBJECT mountmgr;
1011  PFILE_OBJECT mountmgrfo;
1012  LIST_ENTRY* le;
1013 
1015 
1017  Status = IoGetDeviceObjectPointer(&mmdevpath, FILE_READ_ATTRIBUTES, &mountmgrfo, &mountmgr);
1018  if (!NT_SUCCESS(Status)) {
1019  ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
1020  return;
1021  }
1022 
1024 
1025  le = pdo_list.Flink;
1026  while (le != &pdo_list) {
1028 
1029  if (pdode == context->pdode) {
1030  LIST_ENTRY* le2;
1031 
1033 
1034  le2 = pdode->children.Flink;
1035 
1036  while (le2 != &pdode->children) {
1038 
1040 
1041  name.Length = name.MaximumLength = vc->pnp_name.Length + (3 * sizeof(WCHAR));
1042  name.Buffer = ExAllocatePoolWithTag(PagedPool, name.Length, ALLOC_TAG);
1043 
1044  if (!name.Buffer) {
1045  ERR("out of memory\n");
1046 
1049  ObDereferenceObject(mountmgrfo);
1050  IoFreeWorkItem(context->work_item);
1051  return;
1052  }
1053 
1054  RtlCopyMemory(name.Buffer, L"\\??", 3 * sizeof(WCHAR));
1055  RtlCopyMemory(&name.Buffer[3], vc->pnp_name.Buffer, vc->pnp_name.Length);
1056 
1057  Status = remove_drive_letter(mountmgr, &name);
1058 
1060  WARN("remove_drive_letter returned %08x\n", Status);
1061 
1062  ExFreePool(name.Buffer);
1063 
1065 
1066  le2 = le2->Flink;
1067  }
1068 
1071  ObDereferenceObject(mountmgrfo);
1072  IoFreeWorkItem(context->work_item);
1073  return;
1074  }
1075 
1076  le = le->Flink;
1077  }
1078 
1080 
1081  ObDereferenceObject(mountmgrfo);
1082  IoFreeWorkItem(context->work_item);
1083 }
1084 
1086  PIO_WORKITEM work_item;
1088 
1089  work_item = IoAllocateWorkItem(master_devobj);
1090 
1092 
1093  if (!context) {
1094  ERR("out of memory\n");
1095  IoFreeWorkItem(work_item);
1096  return;
1097  }
1098 
1099  context->work_item = work_item;
1100  context->pdode = pdode;
1101 
1102  IoQueueWorkItem(work_item, drive_letter_callback, DelayedWorkQueue, context);
1103 }
1104 
1106  NTSTATUS Status;
1107  LIST_ENTRY* le;
1109  volume_child* vc;
1111  UNICODE_STRING devpath2;
1112  bool inserted = false, new_pdo = false;
1113  pdo_device_extension* pdode = NULL;
1114  PDEVICE_OBJECT pdo = NULL;
1115 
1116  if (devpath->Length == 0)
1117  return;
1118 
1120 
1121  le = pdo_list.Flink;
1122  while (le != &pdo_list) {
1124 
1125  if (RtlCompareMemory(&pdode2->uuid, &sb->uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1126  pdode = pdode2;
1127  break;
1128  }
1129 
1130  le = le->Flink;
1131  }
1132 
1134  if (!NT_SUCCESS(Status)) {
1135  ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
1137  return;
1138  }
1139 
1140  if (!pdode) {
1141  if (no_pnp) {
1142  Status = IoReportDetectedDevice(drvobj, InterfaceTypeUndefined, 0xFFFFFFFF, 0xFFFFFFFF, NULL, NULL, 0, &pdo);
1143 
1144  if (!NT_SUCCESS(Status)) {
1145  ERR("IoReportDetectedDevice returned %08x\n", Status);
1147  return;
1148  }
1149 
1151 
1152  if (!pdode) {
1153  ERR("out of memory\n");
1155  return;
1156  }
1157  } else {
1160  if (!NT_SUCCESS(Status)) {
1161  ERR("IoCreateDevice returned %08x\n", Status);
1163  goto fail;
1164  }
1165 
1167 
1168  pdode = pdo->DeviceExtension;
1169  }
1170 
1171  RtlZeroMemory(pdode, sizeof(pdo_device_extension));
1172 
1173  pdode->type = VCB_TYPE_PDO;
1174  pdode->pdo = pdo;
1175  pdode->uuid = sb->uuid;
1176 
1178  InitializeListHead(&pdode->children);
1179  pdode->num_children = sb->num_devices;
1180  pdode->children_loaded = 0;
1181 
1182  pdo->Flags &= ~DO_DEVICE_INITIALIZING;
1183  pdo->SectorSize = (USHORT)sb->sector_size;
1184 
1186 
1187  new_pdo = true;
1188  } else {
1191 
1192  le = pdode->children.Flink;
1193  while (le != &pdode->children) {
1195 
1196  if (RtlCompareMemory(&vc2->uuid, &sb->dev_item.device_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1197  // duplicate, ignore
1200  goto fail;
1201  }
1202 
1203  le = le->Flink;
1204  }
1205  }
1206 
1208  if (!vc) {
1209  ERR("out of memory\n");
1210 
1213 
1214  goto fail;
1215  }
1216 
1217  vc->uuid = sb->dev_item.device_uuid;
1218  vc->devid = sb->dev_item.dev_id;
1219  vc->generation = sb->generation;
1220  vc->notification_entry = NULL;
1221 
1223  drvobj, pnp_removal, pdode, &vc->notification_entry);
1224  if (!NT_SUCCESS(Status))
1225  WARN("IoRegisterPlugPlayNotification returned %08x\n", Status);
1226 
1227  vc->devobj = DeviceObject;
1228  vc->fileobj = FileObject;
1229 
1230  devpath2 = *devpath;
1231 
1232  // The PNP path sometimes begins \\?\ and sometimes \??\. We need to remove this prefix
1233  // so we can compare properly if the device is removed.
1234  if (devpath->Length > 4 * sizeof(WCHAR) && devpath->Buffer[0] == '\\' && (devpath->Buffer[1] == '\\' || devpath->Buffer[1] == '?') &&
1235  devpath->Buffer[2] == '?' && devpath->Buffer[3] == '\\') {
1236  devpath2.Buffer = &devpath2.Buffer[3];
1237  devpath2.Length -= 3 * sizeof(WCHAR);
1238  devpath2.MaximumLength -= 3 * sizeof(WCHAR);
1239  }
1240 
1241  vc->pnp_name.Length = vc->pnp_name.MaximumLength = devpath2.Length;
1243 
1244  if (vc->pnp_name.Buffer)
1245  RtlCopyMemory(vc->pnp_name.Buffer, devpath2.Buffer, devpath2.Length);
1246  else {
1247  ERR("out of memory\n");
1248  vc->pnp_name.Length = vc->pnp_name.MaximumLength = 0;
1249  }
1250 
1251  vc->size = length;
1252  vc->seeding = sb->flags & BTRFS_SUPERBLOCK_FLAGS_SEEDING ? true : false;
1253  vc->disk_num = disk_num;
1254  vc->part_num = part_num;
1255  vc->had_drive_letter = false;
1256 
1257  le = pdode->children.Flink;
1258  while (le != &pdode->children) {
1260 
1261  if (vc2->generation < vc->generation) {
1262  if (le == pdode->children.Flink)
1263  pdode->num_children = sb->num_devices;
1264 
1266  inserted = true;
1267  break;
1268  }
1269 
1270  le = le->Flink;
1271  }
1272 
1273  if (!inserted)
1274  InsertTailList(&pdode->children, &vc->list_entry);
1275 
1276  pdode->children_loaded++;
1277 
1278  if (pdode->vde && pdode->vde->mounted_device) {
1280 
1281  ExAcquireResourceExclusiveLite(&Vcb->tree_lock, true);
1282 
1283  le = Vcb->devices.Flink;
1284  while (le != &Vcb->devices) {
1286 
1287  if (!dev->devobj && RtlCompareMemory(&dev->devitem.device_uuid, &sb->dev_item.device_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1288  dev->devobj = DeviceObject;
1289  dev->disk_num = disk_num;
1290  dev->part_num = part_num;
1291  init_device(Vcb, dev, false);
1292  break;
1293  }
1294 
1295  le = le->Flink;
1296  }
1297 
1298  ExReleaseResourceLite(&Vcb->tree_lock);
1299  }
1300 
1301  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
1302  pdode->removable = true;
1303 
1304  if (pdode->vde && pdode->vde->device)
1305  pdode->vde->device->Characteristics |= FILE_REMOVABLE_MEDIA;
1306  }
1307 
1308  if (pdode->num_children == pdode->children_loaded || (pdode->children_loaded == 1 && allow_degraded_mount(&sb->uuid))) {
1309  if ((!new_pdo || !no_pnp) && pdode->vde) {
1310  Status = IoSetDeviceInterfaceState(&pdode->vde->bus_name, true);
1311  if (!NT_SUCCESS(Status))
1312  WARN("IoSetDeviceInterfaceState returned %08x\n", Status);
1313  }
1314 
1316  }
1317 
1319 
1320  if (new_pdo)
1321  InsertTailList(&pdo_list, &pdode->list_entry);
1322 
1324 
1325  if (new_pdo) {
1326  if (no_pnp)
1327  AddDevice(drvobj, pdo);
1328  else {
1331  }
1332  }
1333 
1334  return;
1335 
1336 fail:
1338 }
DEVICE_TYPE DeviceType
Definition: ntddstor.h:232
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
_In_ PVOID NotificationStructure
Definition: iofuncs.h:1203
#define VCB_TYPE_PDO
Definition: btrfs_drv.h:660
static NTSTATUS vol_query_stable_guid(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:773
#define hex_digit(c)
Definition: btrfs_drv.h:1656
#define IN
Definition: typedefs.h:38
PDEVICE_OBJECT buspdo
Definition: btrfs_drv.h:816
NTSTATUS vol_device_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:797
static NTSTATUS vol_get_length(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:570
#define FILE_DEVICE_DISK
Definition: winioctl.h:112
UNICODE_STRING pnp_name
Definition: btrfs_drv.h:827
static NTSTATUS vol_query_device_name(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:353
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:347
#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:63
Definition: http.c:6587
#define BTRFS_SUPERBLOCK_FLAGS_SEEDING
Definition: btrfs.h:116
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
_In_ PIRP Irp
Definition: csq.h:116
superblock * sb
Definition: btrfs.c:4162
#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:842
#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:926
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:285
#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:204
#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:844
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:449
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:376
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
GLuint GLuint end
Definition: gl.h:1545
ULONG TracksPerCylinder
Definition: ntdddisk.h:374
WCHAR DeviceName[]
Definition: adapter.cpp:21
ULONG part_num
Definition: btrfs_drv.h:833
#define InsertTailList(ListHead, Entry)
KEVENT Event
Definition: volume.c:108
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
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
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
_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:3301
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
BTRFS_UUID uuid
Definition: btrfs_drv.h:822
#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:841
PDEVICE_OBJECT pdo
Definition: btrfs_drv.h:856
uint64_t num_children
Definition: btrfs_drv.h:859
#define ALLOC_TAG
Definition: btrfs_drv.h:91
UNICODE_STRING bus_name
Definition: btrfs_drv.h:846
#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:824
#define IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER
Definition: mountmgr.h:34
NTSTATUS mountmgr_add_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
Definition: volume.c:881
Definition: devices.h:37
uint32_t no_pnp
Definition: btrfs.c:89
uint64_t num_devices
Definition: btrfs.h:220
IO_STATUS_BLOCK iosb
Definition: volume.c:107
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
bool seeding
Definition: btrfs_drv.h:829
_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:601
PDEVICE_OBJECT devobj
Definition: btrfs_drv.h:825
#define IOCTL_VOLUME_ONLINE
Definition: ntddvol.h:62
#define IoCompleteRequest
Definition: irp.c:1240
DEV_ITEM dev_item
Definition: btrfs.h:234
#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:845
_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:111
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:173
#define IOCTL_STORAGE_CHECK_VERIFY
Definition: ntddstor.h:87
uint64_t flags
Definition: btrfs.h:210
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define STATUS_NOT_FOUND
Definition: shellext.h:67
uint64_t children_loaded
Definition: btrfs_drv.h:860
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:341
NTSTATUS vol_query_ea(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:297
NTSTATUS vol_flush_buffers(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:309
__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:372
static NTSTATUS vol_is_dynamic(PIRP Irp)
Definition: volume.c:407
#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:2841
ULONG SectorsPerTrack
Definition: ntdddisk.h:375
bool had_drive_letter
Definition: btrfs_drv.h:830
#define Vcb
Definition: cdprocs.h:1425
NTSTATUS vol_read(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:123
LIST_ENTRY list_entry
Definition: btrfs_drv.h:864
static NTSTATUS vol_ioctl_passthrough(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:705
MEDIA_TYPE MediaType
Definition: ntdddisk.h:373
#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:655
ERESOURCE child_lock
Definition: btrfs_drv.h:861
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
void * notification_entry
Definition: btrfs_drv.h:831
pdo_device_extension * pdode
Definition: volume.c:1002
PDEVICE_OBJECT mounted_device
Definition: btrfs_drv.h:843
* PFILE_OBJECT
Definition: iotypes.h:1955
ULONG disk_num
Definition: btrfs_drv.h:832
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
uint64_t generation
Definition: btrfs.h:212
#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:826
PDEVICE_OBJECT master_devobj
Definition: btrfs.c:67
NTSTATUS vol_close(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:49
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:161
void add_volume_device(superblock *sb, PUNICODE_STRING devpath, uint64_t length, ULONG disk_num, ULONG part_num)
Definition: volume.c:1105
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:335
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:315
#define ERR(fmt,...)
Definition: debug.h:109
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
NTSTATUS vol_query_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:869
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:291
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:5108
ERESOURCE pdo_list_lock
Definition: btrfs.c:103
LIST_ENTRY pdo_list
Definition: btrfs.c:104
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
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
NTSTATUS vol_set_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:875
unsigned short USHORT
Definition: pedump.c:61
static void add_drive_letter_work_item(pdo_device_extension *pdode)
Definition: volume.c:1085
#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:208
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
Definition: services.c:325
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:91
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:539
NTSTATUS vol_set_volume_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:321
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_DEALLOCATE_BUFFER
volume_device_extension * vde
Definition: btrfs_drv.h:855
NTSTATUS vol_cleanup(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:327
uint64_t size
Definition: btrfs_drv.h:828
Definition: name.c:36
ULONG ERESOURCE
Definition: env_spec_w32.h:594
NTSTATUS vol_create(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:35
LIST_ENTRY list_entry
Definition: btrfs_drv.h:834
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:208
#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:303
uint64_t devid
Definition: btrfs_drv.h:823
static NTSTATUS vol_check_verify(volume_device_extension *vde)
Definition: volume.c:423
uint32_t sector_size
Definition: btrfs.h:221
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
LIST_ENTRY children
Definition: btrfs_drv.h:862
static const BYTE ext3[]
Definition: encode.c:2701
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define REG_DWORD
Definition: sdbapi.c:596
static NTSTATUS vol_query_unique_id(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:377
#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:639
NTSTATUS vol_shutdown(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:863
#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
LONGLONG QuadPart
Definition: typedefs.h:112
struct _DISK_EXTENT DISK_EXTENT
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:65
GLuint const GLchar * name
Definition: glext.h:6031