ReactOS  0.4.13-dev-455-g28ed234
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;
31 extern LIST_ENTRY pdo_list;
33 
36 
37  TRACE("(%p, %p)\n", DeviceObject, Irp);
38 
39  if (vde->removing)
41 
42  Irp->IoStatus.Information = FILE_OPENED;
44 
45  return STATUS_SUCCESS;
46 }
47 
50  pdo_device_extension* pdode = vde->pdode;
51 
52  TRACE("(%p, %p)\n", DeviceObject, Irp);
53 
54  Irp->IoStatus.Information = 0;
55 
57 
59 
60  if (InterlockedDecrement(&vde->open_count) == 0 && vde->removing) {
62  UNICODE_STRING mmdevpath;
63  PDEVICE_OBJECT mountmgr;
64  PFILE_OBJECT mountmgrfo;
65  PDEVICE_OBJECT pdo;
66 
68  Status = IoGetDeviceObjectPointer(&mmdevpath, FILE_READ_ATTRIBUTES, &mountmgrfo, &mountmgr);
69  if (!NT_SUCCESS(Status))
70  ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
71  else {
72  remove_drive_letter(mountmgr, &vde->name);
73 
74  ObDereferenceObject(mountmgrfo);
75  }
76 
77  if (vde->mounted_device) {
79 
80  Vcb->vde = NULL;
81  }
82 
83  if (vde->name.Buffer)
84  ExFreePool(vde->name.Buffer);
85 
88 
89  if (vde->pdo->AttachedDevice)
90  IoDetachDevice(vde->pdo);
91 
92  pdo = vde->pdo;
93  IoDeleteDevice(vde->device);
94 
95  if (!no_pnp)
96  IoDeleteDevice(pdo);
97  } else
99 
101 
102  return STATUS_SUCCESS;
103 }
104 
105 typedef struct {
109 
110 _Function_class_(IO_COMPLETION_ROUTINE)
111 #ifdef __REACTOS__
112 static NTSTATUS NTAPI vol_read_completion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID conptr) {
113 #else
114 static NTSTATUS vol_read_completion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID conptr) {
115 #endif
116  vol_read_context* context = conptr;
117 
119 
120  context->iosb = Irp->IoStatus;
121  KeSetEvent(&context->Event, 0, FALSE);
122 
124 }
125 
128  pdo_device_extension* pdode = vde->pdode;
129  volume_child* vc;
131  PIRP Irp2;
133  PIO_STACK_LOCATION IrpSp, IrpSp2;
134 
135  TRACE("(%p, %p)\n", DeviceObject, Irp);
136 
138 
139  if (IsListEmpty(&pdode->children)) {
142  goto end;
143  }
144 
146 
147  // We can't use IoSkipCurrentIrpStackLocation as the device isn't in our stack
148 
149  Irp2 = IoAllocateIrp(vc->devobj->StackSize, FALSE);
150 
151  if (!Irp2) {
152  ERR("IoAllocateIrp failed\n");
155  goto end;
156  }
157 
159  IrpSp2 = IoGetNextIrpStackLocation(Irp2);
160 
161  IrpSp2->MajorFunction = IRP_MJ_READ;
162 
163  if (vc->devobj->Flags & DO_BUFFERED_IO) {
164  Irp2->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool, IrpSp->Parameters.Read.Length, ALLOC_TAG);
165  if (!Irp2->AssociatedIrp.SystemBuffer) {
166  ERR("out of memory\n");
169  goto end;
170  }
171 
173 
174  Irp2->UserBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
175  } else if (vc->devobj->Flags & DO_DIRECT_IO)
176  Irp2->MdlAddress = Irp->MdlAddress;
177  else
178  Irp2->UserBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
179 
180  IrpSp2->Parameters.Read.Length = IrpSp->Parameters.Read.Length;
181  IrpSp2->Parameters.Read.ByteOffset.QuadPart = IrpSp->Parameters.Read.ByteOffset.QuadPart;
182 
184  Irp2->UserIosb = &context.iosb;
185 
186  IoSetCompletionRoutine(Irp2, vol_read_completion, &context, TRUE, TRUE, TRUE);
187 
188  Status = IoCallDriver(vc->devobj, Irp2);
189 
190  if (Status == STATUS_PENDING) {
192  Status = context.iosb.Status;
193  }
194 
196 
197  Irp->IoStatus.Information = context.iosb.Information;
198 
199 end:
200  Irp->IoStatus.Status = Status;
202 
203  return Status;
204 }
205 
208  pdo_device_extension* pdode = vde->pdode;
209  volume_child* vc;
211  PIRP Irp2;
213  PIO_STACK_LOCATION IrpSp, IrpSp2;
214 
215  TRACE("(%p, %p)\n", DeviceObject, Irp);
216 
218 
219  if (IsListEmpty(&pdode->children)) {
222  goto end;
223  }
224 
226 
227  if (vc->list_entry.Flink != &pdode->children) { // more than once device
230  goto end;
231  }
232 
233  // We can't use IoSkipCurrentIrpStackLocation as the device isn't in our stack
234 
235  Irp2 = IoAllocateIrp(vc->devobj->StackSize, FALSE);
236 
237  if (!Irp2) {
238  ERR("IoAllocateIrp failed\n");
241  goto end;
242  }
243 
245  IrpSp2 = IoGetNextIrpStackLocation(Irp2);
246 
247  IrpSp2->MajorFunction = IRP_MJ_WRITE;
248 
249  if (vc->devobj->Flags & DO_BUFFERED_IO) {
250  Irp2->AssociatedIrp.SystemBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
251 
252  Irp2->Flags |= IRP_BUFFERED_IO;
253 
254  Irp2->UserBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
255  } else if (vc->devobj->Flags & DO_DIRECT_IO)
256  Irp2->MdlAddress = Irp->MdlAddress;
257  else
258  Irp2->UserBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
259 
260  IrpSp2->Parameters.Write.Length = IrpSp->Parameters.Write.Length;
261  IrpSp2->Parameters.Write.ByteOffset.QuadPart = IrpSp->Parameters.Write.ByteOffset.QuadPart;
262 
264  Irp2->UserIosb = &context.iosb;
265 
266  IoSetCompletionRoutine(Irp2, vol_read_completion, &context, TRUE, TRUE, TRUE);
267 
268  Status = IoCallDriver(vc->devobj, Irp2);
269 
270  if (Status == STATUS_PENDING) {
272  Status = context.iosb.Status;
273  }
274 
276 
277  Irp->IoStatus.Information = context.iosb.Information;
278 
279 end:
280  Irp->IoStatus.Status = Status;
282 
283  return Status;
284 }
285 
287  TRACE("(%p, %p)\n", DeviceObject, Irp);
288 
290 }
291 
293  TRACE("(%p, %p)\n", DeviceObject, Irp);
294 
296 }
297 
299  TRACE("(%p, %p)\n", DeviceObject, Irp);
300 
302 }
303 
305  TRACE("(%p, %p)\n", DeviceObject, Irp);
306 
308 }
309 
311  TRACE("(%p, %p)\n", DeviceObject, Irp);
312 
314 }
315 
317  TRACE("(%p, %p)\n", DeviceObject, Irp);
318 
320 }
321 
323  TRACE("(%p, %p)\n", DeviceObject, Irp);
324 
326 }
327 
329  TRACE("(%p, %p)\n", DeviceObject, Irp);
330 
331  Irp->IoStatus.Information = 0;
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 
352 }
353 
357 
358  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_NAME)) {
359  Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
361  }
362 
363  name = Irp->AssociatedIrp.SystemBuffer;
364  name->NameLength = vde->name.Length;
365 
366  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < offsetof(MOUNTDEV_NAME, Name[0]) + name->NameLength) {
367  Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
368  return STATUS_BUFFER_OVERFLOW;
369  }
370 
371  RtlCopyMemory(name->Name, vde->name.Buffer, vde->name.Length);
372 
373  Irp->IoStatus.Information = offsetof(MOUNTDEV_NAME, Name[0]) + name->NameLength;
374 
375  return STATUS_SUCCESS;
376 }
377 
380  MOUNTDEV_UNIQUE_ID* mduid;
381  pdo_device_extension* pdode;
382 
383  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_UNIQUE_ID)) {
384  Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
386  }
387 
388  mduid = Irp->AssociatedIrp.SystemBuffer;
389  mduid->UniqueIdLength = sizeof(BTRFS_UUID);
390 
391  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < offsetof(MOUNTDEV_UNIQUE_ID, UniqueId[0]) + mduid->UniqueIdLength) {
392  Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
393  return STATUS_BUFFER_OVERFLOW;
394  }
395 
396  if (!vde->pdo)
398 
399  pdode = vde->pdode;
400 
401  RtlCopyMemory(mduid->UniqueId, &pdode->uuid, sizeof(BTRFS_UUID));
402 
403  Irp->IoStatus.Information = offsetof(MOUNTDEV_UNIQUE_ID, UniqueId[0]) + mduid->UniqueIdLength;
404 
405  return STATUS_SUCCESS;
406 }
407 
410  UINT8* buf;
411 
412  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0 || !Irp->AssociatedIrp.SystemBuffer)
414 
415  buf = (UINT8*)Irp->AssociatedIrp.SystemBuffer;
416 
417  *buf = 1;
418 
419  Irp->IoStatus.Information = 1;
420 
421  return STATUS_SUCCESS;
422 }
423 
425  pdo_device_extension* pdode = vde->pdode;
427  LIST_ENTRY* le;
428 
430 
431  le = pdode->children.Flink;
432  while (le != &pdode->children) {
434 
436  if (!NT_SUCCESS(Status))
437  goto end;
438 
439  le = le->Flink;
440  }
441 
443 
444 end:
446 
447  return Status;
448 }
449 
451  pdo_device_extension* pdode = vde->pdode;
453  LIST_ENTRY* le;
454  ULONG num_extents = 0, i, max_extents = 1;
457 
458  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(VOLUME_DISK_EXTENTS))
460 
462 
463  le = pdode->children.Flink;
464  while (le != &pdode->children) {
467 
470  ERR("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS returned %08x\n", Status);
471  goto end;
472  }
473 
474  num_extents += ext2.NumberOfDiskExtents;
475 
476  if (ext2.NumberOfDiskExtents > max_extents)
477  max_extents = ext2.NumberOfDiskExtents;
478 
479  le = le->Flink;
480  }
481 
482  ext = Irp->AssociatedIrp.SystemBuffer;
483 
484  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (num_extents * sizeof(DISK_EXTENT))) {
485  Irp->IoStatus.Information = offsetof(VOLUME_DISK_EXTENTS, Extents[0]);
486  ext->NumberOfDiskExtents = num_extents;
488  goto end;
489  }
490 
491  ext3 = ExAllocatePoolWithTag(PagedPool, offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (max_extents * sizeof(DISK_EXTENT)), ALLOC_TAG);
492  if (!ext3) {
493  ERR("out of memory\n");
495  goto end;
496  }
497 
498  i = 0;
499  ext->NumberOfDiskExtents = 0;
500 
501  le = pdode->children.Flink;
502  while (le != &pdode->children) {
504 
506  (ULONG)offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (max_extents * sizeof(DISK_EXTENT)), FALSE, NULL);
507  if (!NT_SUCCESS(Status)) {
508  ERR("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS returned %08x\n", Status);
509  ExFreePool(ext3);
510  goto end;
511  }
512 
513  if (i + ext3->NumberOfDiskExtents > num_extents) {
514  Irp->IoStatus.Information = offsetof(VOLUME_DISK_EXTENTS, Extents[0]);
515  ext->NumberOfDiskExtents = i + ext3->NumberOfDiskExtents;
517  ExFreePool(ext3);
518  goto end;
519  }
520 
521  RtlCopyMemory(&ext->Extents[i], ext3->Extents, sizeof(DISK_EXTENT) * ext3->NumberOfDiskExtents);
522  i += ext3->NumberOfDiskExtents;
523 
524  le = le->Flink;
525  }
526 
527  ExFreePool(ext3);
528 
530 
531  ext->NumberOfDiskExtents = i;
532  Irp->IoStatus.Information = offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (i * sizeof(DISK_EXTENT));
533 
534 end:
536 
537  return Status;
538 }
539 
541  pdo_device_extension* pdode = vde->pdode;
543  LIST_ENTRY* le;
544  BOOL writable = FALSE;
545 
547 
548  le = pdode->children.Flink;
549  while (le != &pdode->children) {
551 
553 
554  if (NT_SUCCESS(Status)) {
555  writable = TRUE;
556  break;
557  } else if (Status != STATUS_MEDIA_WRITE_PROTECTED)
558  goto end;
559 
560  le = le->Flink;
561  }
562 
564 
565 end:
567 
568  return STATUS_SUCCESS;
569 }
570 
573  pdo_device_extension* pdode = vde->pdode;
575  LIST_ENTRY* le;
576 
577  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GET_LENGTH_INFORMATION))
579 
580  gli = (GET_LENGTH_INFORMATION*)Irp->AssociatedIrp.SystemBuffer;
581 
582  gli->Length.QuadPart = 0;
583 
585 
586  le = pdode->children.Flink;
587  while (le != &pdode->children) {
589 
590  gli->Length.QuadPart += vc->size;
591 
592  le = le->Flink;
593  }
594 
596 
597  Irp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION);
598 
599  return STATUS_SUCCESS;
600 }
601 
604  pdo_device_extension* pdode = vde->pdode;
606  DISK_GEOMETRY* geom;
607  UINT64 length;
608  LIST_ENTRY* le;
609 
610  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY))
612 
613  length = 0;
614 
616 
617  le = pdode->children.Flink;
618  while (le != &pdode->children) {
620 
621  length += vc->size;
622 
623  le = le->Flink;
624  }
625 
627 
628  geom = (DISK_GEOMETRY*)Irp->AssociatedIrp.SystemBuffer;
629  geom->BytesPerSector = DeviceObject->SectorSize == 0 ? 0x200 : DeviceObject->SectorSize;
630  geom->SectorsPerTrack = 0x3f;
631  geom->TracksPerCylinder = 0xff;
634 
635  Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
636 
637  return STATUS_SUCCESS;
638 }
639 
643 
644  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(VOLUME_GET_GPT_ATTRIBUTES_INFORMATION))
646 
647  vggai = (VOLUME_GET_GPT_ATTRIBUTES_INFORMATION*)Irp->AssociatedIrp.SystemBuffer;
648 
649  vggai->GptAttributes = 0;
650 
651  Irp->IoStatus.Information = sizeof(VOLUME_GET_GPT_ATTRIBUTES_INFORMATION);
652 
653  return STATUS_SUCCESS;
654 }
655 
657  pdo_device_extension* pdode = vde->pdode;
659  volume_child* vc;
661 
662  // If only one device, return its disk number. This is needed for ejection to work.
663 
664  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_DEVICE_NUMBER))
666 
668 
669  if (IsListEmpty(&pdode->children) || pdode->num_children > 1) {
672  }
673 
675 
676  if (vc->disk_num == 0xffffffff) {
679  }
680 
681  sdn = (STORAGE_DEVICE_NUMBER*)Irp->AssociatedIrp.SystemBuffer;
682 
684  sdn->DeviceNumber = vc->disk_num;
685  sdn->PartitionNumber = vc->part_num;
686 
688 
689  Irp->IoStatus.Information = sizeof(STORAGE_DEVICE_NUMBER);
690 
691  return STATUS_SUCCESS;
692 }
693 
694 _Function_class_(IO_COMPLETION_ROUTINE)
695 #ifdef __REACTOS__
696 static NTSTATUS NTAPI vol_ioctl_completion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID conptr) {
697 #else
698 static NTSTATUS vol_ioctl_completion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID conptr) {
699 #endif
700  KEVENT* event = conptr;
701 
703  UNUSED(Irp);
704 
705  KeSetEvent(event, 0, FALSE);
706 
708 }
709 
712  volume_child* vc;
713  PIRP Irp2;
714  PIO_STACK_LOCATION IrpSp, IrpSp2;
715  KEVENT Event;
716  pdo_device_extension* pdode = vde->pdode;
717 
718  TRACE("(%p, %p)\n", vde, Irp);
719 
721 
722  if (IsListEmpty(&pdode->children)) {
725  }
726 
728 
729  if (vc->list_entry.Flink != &pdode->children) { // more than one device
732  }
733 
734  Irp2 = IoAllocateIrp(vc->devobj->StackSize, FALSE);
735 
736  if (!Irp2) {
737  ERR("IoAllocateIrp failed\n");
740  }
741 
743  IrpSp2 = IoGetNextIrpStackLocation(Irp2);
744 
745  IrpSp2->MajorFunction = IrpSp->MajorFunction;
746  IrpSp2->MinorFunction = IrpSp->MinorFunction;
747 
748  IrpSp2->Parameters.DeviceIoControl.OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
749  IrpSp2->Parameters.DeviceIoControl.InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
750  IrpSp2->Parameters.DeviceIoControl.IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
751  IrpSp2->Parameters.DeviceIoControl.Type3InputBuffer = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
752 
753  Irp2->AssociatedIrp.SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
754  Irp2->MdlAddress = Irp->MdlAddress;
755  Irp2->UserBuffer = Irp->UserBuffer;
756  Irp2->Flags = Irp->Flags;
757 
759 
760  IoSetCompletionRoutine(Irp2, vol_ioctl_completion, &Event, TRUE, TRUE, TRUE);
761 
762  Status = IoCallDriver(vc->devobj, Irp2);
763 
764  if (Status == STATUS_PENDING) {
766  Status = Irp2->IoStatus.Status;
767  }
768 
769  Irp->IoStatus.Status = Irp2->IoStatus.Status;
770  Irp->IoStatus.Information = Irp2->IoStatus.Information;
771 
773 
774  return Status;
775 }
776 
779  MOUNTDEV_STABLE_GUID* mdsg;
780  pdo_device_extension* pdode;
781 
782  if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_STABLE_GUID)) {
783  Irp->IoStatus.Information = sizeof(MOUNTDEV_STABLE_GUID);
785  }
786 
787  mdsg = Irp->AssociatedIrp.SystemBuffer;
788 
789  if (!vde->pdo)
791 
792  pdode = vde->pdode;
793 
794  RtlCopyMemory(&mdsg->StableGuid, &pdode->uuid, sizeof(BTRFS_UUID));
795 
796  Irp->IoStatus.Information = sizeof(MOUNTDEV_STABLE_GUID);
797 
798  return STATUS_SUCCESS;
799 }
800 
804 
805  TRACE("(%p, %p)\n", DeviceObject, Irp);
806 
807  Irp->IoStatus.Information = 0;
808 
809  switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
811  return vol_query_device_name(vde, Irp);
812 
814  return vol_query_unique_id(vde, Irp);
815 
817  return vol_get_device_number(vde, Irp);
818 
820  TRACE("unhandled control code IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME\n");
821  break;
822 
824  return vol_query_stable_guid(vde, Irp);
825 
827  TRACE("unhandled control code IOCTL_MOUNTDEV_LINK_CREATED\n");
828  break;
829 
831  return vol_get_gpt_attributes(Irp);
832 
834  return vol_is_dynamic(Irp);
835 
836  case IOCTL_VOLUME_ONLINE:
837  Irp->IoStatus.Information = 0;
838  return STATUS_SUCCESS;
839 
841  Irp->IoStatus.Information = 0;
842  return STATUS_SUCCESS;
843 
846 
848  return vol_is_writable(vde);
849 
851  return vol_get_length(vde, Irp);
852 
855  return vol_check_verify(vde);
856 
858  return vol_get_disk_extents(vde, Irp);
859 
860  default: // pass ioctl through if only one child device
861  return vol_ioctl_passthrough(vde, Irp);
862  }
863 
865 }
866 
868  TRACE("(%p, %p)\n", DeviceObject, Irp);
869 
871 }
872 
874  TRACE("(%p, %p)\n", DeviceObject, Irp);
875 
877 }
878 
880  TRACE("(%p, %p)\n", DeviceObject, Irp);
881 
883 }
884 
888 
889  TRACE("(%p, %p)\n", DeviceObject, Irp);
890 
892  Irp->IoStatus.Status = STATUS_SUCCESS;
893 
894  Status = Irp->IoStatus.Status;
896 
897  return Status;
898 }
899 
902  ULONG mmdltsize;
905 
906  mmdltsize = (ULONG)offsetof(MOUNTMGR_DRIVE_LETTER_TARGET, DeviceName[0]) + devpath->Length;
907 
908  mmdlt = ExAllocatePoolWithTag(NonPagedPool, mmdltsize, ALLOC_TAG);
909  if (!mmdlt) {
910  ERR("out of memory\n");
912  }
913 
914  mmdlt->DeviceNameLength = devpath->Length;
915  RtlCopyMemory(&mmdlt->DeviceName, devpath->Buffer, devpath->Length);
916  TRACE("mmdlt = %.*S\n", mmdlt->DeviceNameLength / sizeof(WCHAR), mmdlt->DeviceName);
917 
918  Status = dev_ioctl(mountmgr, IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER, mmdlt, mmdltsize, &mmdli, sizeof(MOUNTMGR_DRIVE_LETTER_INFORMATION), FALSE, NULL);
919 
920  if (!NT_SUCCESS(Status))
921  ERR("IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER returned %08x\n", Status);
922  else
923  TRACE("DriveLetterWasAssigned = %u, CurrentDriveLetter = %c\n", mmdli.DriveLetterWasAssigned, mmdli.CurrentDriveLetter);
924 
925  ExFreePool(mmdlt);
926 
927  return Status;
928 }
929 
930 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE)
931 #ifdef __REACTOS__
933 #else
935 #endif
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 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)) {
1007  UINT32* val = (UINT32*)((UINT8*)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 void add_volume_device(superblock* sb, PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath, UINT64 length, ULONG disk_num, ULONG part_num) {
1024  NTSTATUS Status;
1025  LIST_ENTRY* le;
1027  volume_child* vc;
1029  UNICODE_STRING devpath2;
1030  BOOL inserted = FALSE, new_pdo = FALSE;
1031  pdo_device_extension* pdode = NULL;
1032  PDEVICE_OBJECT pdo = NULL;
1033 
1034  if (devpath->Length == 0)
1035  return;
1036 
1038 
1039  le = pdo_list.Flink;
1040  while (le != &pdo_list) {
1042 
1043  if (RtlCompareMemory(&pdode2->uuid, &sb->uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1044  pdode = pdode2;
1045  break;
1046  }
1047 
1048  le = le->Flink;
1049  }
1050 
1052  if (!NT_SUCCESS(Status)) {
1053  ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
1055  return;
1056  }
1057 
1058  if (!pdode) {
1059  if (no_pnp) {
1060  Status = IoReportDetectedDevice(drvobj, InterfaceTypeUndefined, 0xFFFFFFFF, 0xFFFFFFFF, NULL, NULL, 0, &pdo);
1061 
1062  if (!NT_SUCCESS(Status)) {
1063  ERR("IoReportDetectedDevice returned %08x\n", Status);
1065  return;
1066  }
1067 
1069 
1070  if (!pdode) {
1071  ERR("out of memory\n");
1073  return;
1074  }
1075  } else {
1078  if (!NT_SUCCESS(Status)) {
1079  ERR("IoCreateDevice returned %08x\n", Status);
1081  goto fail;
1082  }
1083 
1085 
1086  pdode = pdo->DeviceExtension;
1087  }
1088 
1089  RtlZeroMemory(pdode, sizeof(pdo_device_extension));
1090 
1091  pdode->type = VCB_TYPE_PDO;
1092  pdode->pdo = pdo;
1093  pdode->uuid = sb->uuid;
1094 
1096  InitializeListHead(&pdode->children);
1097  pdode->num_children = sb->num_devices;
1098  pdode->children_loaded = 0;
1099 
1100  pdo->Flags &= ~DO_DEVICE_INITIALIZING;
1101  pdo->SectorSize = (USHORT)sb->sector_size;
1102 
1104 
1105  new_pdo = TRUE;
1106  } else {
1109 
1110  le = pdode->children.Flink;
1111  while (le != &pdode->children) {
1113 
1114  if (RtlCompareMemory(&vc2->uuid, &sb->dev_item.device_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1115  // duplicate, ignore
1118  goto fail;
1119  }
1120 
1121  le = le->Flink;
1122  }
1123  }
1124 
1126  if (!vc) {
1127  ERR("out of memory\n");
1128 
1131 
1132  goto fail;
1133  }
1134 
1135  vc->uuid = sb->dev_item.device_uuid;
1136  vc->devid = sb->dev_item.dev_id;
1137  vc->generation = sb->generation;
1138  vc->notification_entry = NULL;
1139 
1141  drvobj, pnp_removal, pdode, &vc->notification_entry);
1142  if (!NT_SUCCESS(Status))
1143  WARN("IoRegisterPlugPlayNotification returned %08x\n", Status);
1144 
1145  vc->devobj = DeviceObject;
1146  vc->fileobj = FileObject;
1147 
1148  devpath2 = *devpath;
1149 
1150  // The PNP path sometimes begins \\?\ and sometimes \??\. We need to remove this prefix
1151  // so we can compare properly if the device is removed.
1152  if (devpath->Length > 4 * sizeof(WCHAR) && devpath->Buffer[0] == '\\' && (devpath->Buffer[1] == '\\' || devpath->Buffer[1] == '?') &&
1153  devpath->Buffer[2] == '?' && devpath->Buffer[3] == '\\') {
1154  devpath2.Buffer = &devpath2.Buffer[3];
1155  devpath2.Length -= 3 * sizeof(WCHAR);
1156  devpath2.MaximumLength -= 3 * sizeof(WCHAR);
1157  }
1158 
1159  vc->pnp_name.Length = vc->pnp_name.MaximumLength = devpath2.Length;
1161 
1162  if (vc->pnp_name.Buffer)
1163  RtlCopyMemory(vc->pnp_name.Buffer, devpath2.Buffer, devpath2.Length);
1164  else {
1165  ERR("out of memory\n");
1166  vc->pnp_name.Length = vc->pnp_name.MaximumLength = 0;
1167  }
1168 
1169  vc->size = length;
1171  vc->disk_num = disk_num;
1172  vc->part_num = part_num;
1173  vc->had_drive_letter = FALSE;
1174 
1175  le = pdode->children.Flink;
1176  while (le != &pdode->children) {
1178 
1179  if (vc2->generation < vc->generation) {
1180  if (le == pdode->children.Flink)
1181  pdode->num_children = sb->num_devices;
1182 
1184  inserted = TRUE;
1185  break;
1186  }
1187 
1188  le = le->Flink;
1189  }
1190 
1191  if (!inserted)
1192  InsertTailList(&pdode->children, &vc->list_entry);
1193 
1194  pdode->children_loaded++;
1195 
1196  if (pdode->vde && pdode->vde->mounted_device) {
1198 
1199  ExAcquireResourceExclusiveLite(&Vcb->tree_lock, TRUE);
1200 
1201  le = Vcb->devices.Flink;
1202  while (le != &Vcb->devices) {
1204 
1205  if (!dev->devobj && RtlCompareMemory(&dev->devitem.device_uuid, &sb->dev_item.device_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1206  dev->devobj = DeviceObject;
1207  dev->disk_num = disk_num;
1208  dev->part_num = part_num;
1209  init_device(Vcb, dev, FALSE);
1210  break;
1211  }
1212 
1213  le = le->Flink;
1214  }
1215 
1216  ExReleaseResourceLite(&Vcb->tree_lock);
1217  }
1218 
1219  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
1220  pdode->removable = TRUE;
1221 
1222  if (pdode->vde && pdode->vde->device)
1223  pdode->vde->device->Characteristics |= FILE_REMOVABLE_MEDIA;
1224  }
1225 
1226  if (pdode->num_children == pdode->children_loaded || (pdode->children_loaded == 1 && allow_degraded_mount(&sb->uuid))) {
1227  if (pdode->num_children == 1) {
1228  Status = remove_drive_letter(mountmgr, devpath);
1230  WARN("remove_drive_letter returned %08x\n", Status);
1231 
1233  } else {
1234  le = pdode->children.Flink;
1235 
1236  while (le != &pdode->children) {
1238 
1240 
1241  name.Length = name.MaximumLength = vc->pnp_name.Length + (3 * sizeof(WCHAR));
1242  name.Buffer = ExAllocatePoolWithTag(PagedPool, name.Length, ALLOC_TAG);
1243 
1244  if (!name.Buffer) {
1245  ERR("out of memory\n");
1246 
1249 
1250  goto fail;
1251  }
1252 
1253  RtlCopyMemory(name.Buffer, L"\\??", 3 * sizeof(WCHAR));
1254  RtlCopyMemory(&name.Buffer[3], vc->pnp_name.Buffer, vc->pnp_name.Length);
1255 
1256  Status = remove_drive_letter(mountmgr, &name);
1257 
1259  WARN("remove_drive_letter returned %08x\n", Status);
1260 
1261  ExFreePool(name.Buffer);
1262 
1264 
1265  le = le->Flink;
1266  }
1267  }
1268 
1269  if ((!new_pdo || !no_pnp) && pdode->vde) {
1271  if (!NT_SUCCESS(Status))
1272  WARN("IoSetDeviceInterfaceState returned %08x\n", Status);
1273  }
1274  }
1275 
1277 
1278  if (new_pdo) {
1280 
1281  InsertTailList(&pdo_list, &pdode->list_entry);
1282 
1283  if (!no_pnp)
1285  }
1286 
1288 
1289  if (new_pdo && no_pnp)
1290  AddDevice(drvobj, pdo);
1291 
1292  return;
1293 
1294 fail:
1296 }
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:653
static NTSTATUS vol_query_stable_guid(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:777
#define hex_digit(c)
Definition: btrfs_drv.h:1716
#define IN
Definition: typedefs.h:38
NTSTATUS vol_device_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:801
static NTSTATUS vol_get_length(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:571
#define FILE_DEVICE_DISK
Definition: winioctl.h:112
UNICODE_STRING pnp_name
Definition: btrfs_drv.h:839
static NTSTATUS vol_query_device_name(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:354
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSTATUS vol_lock_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:348
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static BOOL allow_degraded_mount(BTRFS_UUID *uuid)
Definition: volume.c:949
#define IRP_MN_QUERY_POWER
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:115
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
_In_ PIRP Irp
Definition: csq.h:116
superblock * sb
Definition: btrfs.c:3952
UINT64 num_devices
Definition: btrfs.h:219
#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
void init_device(_In_ device_extension *Vcb, _Inout_ device *dev, _In_ BOOL get_nums)
Definition: btrfs.c:3111
PDEVICE_OBJECT device
Definition: btrfs_drv.h:854
#define WARN(fmt,...)
Definition: debug.h:111
VOID NTAPI ExConvertExclusiveToSharedLite(IN PERESOURCE Resource)
Definition: resource.c:1402
LONG NTSTATUS
Definition: precomp.h:26
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:286
UINT32 no_pnp
Definition: btrfs.c:83
#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:206
#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:856
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1295
static NTSTATUS vol_get_disk_extents(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:450
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1434
UINT64 dev_id
Definition: btrfs.h:160
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:845
#define InsertTailList(ListHead, Entry)
KEVENT Event
Definition: volume.c:107
#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
UINT64 generation
Definition: btrfs_drv.h:836
#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
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:834
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
BOOL had_drive_letter
Definition: btrfs_drv.h:842
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
UNICODE_STRING name
Definition: btrfs_drv.h:853
PDEVICE_OBJECT pdo
Definition: btrfs_drv.h:868
#define ALLOC_TAG
Definition: btrfs_drv.h:86
UNICODE_STRING bus_name
Definition: btrfs_drv.h:858
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
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_ BOOLEAN Override, _Out_opt_ IO_STATUS_BLOCK *iosb)
Definition: btrfs.c:2652
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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
unsigned int UINT32
#define IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER
Definition: mountmgr.h:34
NTSTATUS mountmgr_add_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
Definition: volume.c:900
unsigned int BOOL
Definition: ntddk_ex.h:94
Definition: devices.h:37
IO_STATUS_BLOCK iosb
Definition: volume.c:106
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
UINT32 mount_allow_degraded
Definition: btrfs.c:81
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:434
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
UINT32 sector_size
Definition: btrfs.h:220
static NTSTATUS vol_get_drive_geometry(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: volume.c:602
PDEVICE_OBJECT devobj
Definition: btrfs_drv.h:837
#define IOCTL_VOLUME_ONLINE
Definition: ntddvol.h:62
#define IoCompleteRequest
Definition: irp.c:1240
DEV_ITEM dev_item
Definition: btrfs.h:233
#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:81
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
struct pdo_device_extension * pdode
Definition: btrfs_drv.h:857
_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
NTSTATUS vol_power(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:885
GLuint GLfloat * val
Definition: glext.h:7180
_Function_class_(IO_COMPLETION_ROUTINE)
Definition: volume.c:110
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:60
BTRFS_UUID device_uuid
Definition: btrfs.h:172
#define IOCTL_STORAGE_CHECK_VERIFY
Definition: ntddstor.h:87
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define STATUS_NOT_FOUND
Definition: shellext.h:67
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:342
NTSTATUS vol_query_ea(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:298
NTSTATUS vol_flush_buffers(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:310
__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:408
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
ULONG SectorsPerTrack
Definition: ntdddisk.h:375
#define Vcb
Definition: cdprocs.h:1425
NTSTATUS vol_read(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:126
LIST_ENTRY list_entry
Definition: btrfs_drv.h:876
static NTSTATUS vol_ioctl_passthrough(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:710
MEDIA_TYPE MediaType
Definition: ntdddisk.h:373
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
static NTSTATUS vol_get_device_number(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:656
ERESOURCE child_lock
Definition: btrfs_drv.h:873
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
void * notification_entry
Definition: btrfs_drv.h:843
PDEVICE_OBJECT mounted_device
Definition: btrfs_drv.h:855
* PFILE_OBJECT
Definition: iotypes.h:1954
ULONG disk_num
Definition: btrfs_drv.h:844
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#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:838
PDEVICE_OBJECT master_devobj
Definition: btrfs.c:61
NTSTATUS vol_close(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:48
static const WCHAR L[]
Definition: oid.c:1250
#define InterlockedDecrement
Definition: armddk.h:52
struct _STORAGE_DEVICE_NUMBER STORAGE_DEVICE_NUMBER
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:250
#define IRP_MN_SET_POWER
#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:336
struct _cl_event * event
Definition: glext.h:7739
BOOL seeding
Definition: btrfs_drv.h:841
void add_volume_device(superblock *sb, PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath, UINT64 length, ULONG disk_num, ULONG part_num)
Definition: volume.c:1023
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
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:316
UINT64 devid
Definition: btrfs_drv.h:835
#define ERR(fmt,...)
Definition: debug.h:109
NTSTATUS vol_query_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:873
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:1250
struct _DISK_GEOMETRY DISK_GEOMETRY
NTSTATUS vol_set_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:292
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:5090
ERESOURCE pdo_list_lock
Definition: btrfs.c:93
LIST_ENTRY pdo_list
Definition: btrfs.c:94
#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
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:626
NTSTATUS vol_set_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:879
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:207
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
UINT64 generation
Definition: btrfs.h:211
Definition: services.c:325
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:85
static NTSTATUS vol_is_writable(volume_device_extension *vde)
Definition: volume.c:540
NTSTATUS vol_set_volume_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:322
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:867
NTSTATUS vol_cleanup(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:328
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:34
LIST_ENTRY list_entry
Definition: btrfs_drv.h:846
Definition: msctf.idl:510
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS pnp_query_remove_device(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pnp.c:184
#define IO_NO_INCREMENT
Definition: iotypes.h:565
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:304
static NTSTATUS vol_check_verify(volume_device_extension *vde)
Definition: volume.c:424
unsigned long long UINT64
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
LIST_ENTRY children
Definition: btrfs_drv.h:874
static const BYTE ext3[]
Definition: encode.c:2701
UINT64 flags
Definition: btrfs.h:209
return STATUS_SUCCESS
Definition: btrfs.c:2777
unsigned char UINT8
#define REG_DWORD
Definition: sdbapi.c:596
static NTSTATUS vol_query_unique_id(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:378
#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
PDEVICE_OBJECT buspdo
Definition: btrfs_drv.h:828
static NTSTATUS vol_get_gpt_attributes(PIRP Irp)
Definition: volume.c:640
NTSTATUS vol_shutdown(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:867
UINT64 size
Definition: btrfs_drv.h:840
#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