ReactOS  0.4.13-dev-52-g0efcfec
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 
780 
781  TRACE("(%p, %p)\n", DeviceObject, Irp);
782 
783  Irp->IoStatus.Information = 0;
784 
785  switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
787  return vol_query_device_name(vde, Irp);
788 
790  return vol_query_unique_id(vde, Irp);
791 
793  return vol_get_device_number(vde, Irp);
794 
796  TRACE("unhandled control code IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME\n");
797  break;
798 
800  TRACE("unhandled control code IOCTL_MOUNTDEV_QUERY_STABLE_GUID\n");
801  break;
802 
804  TRACE("unhandled control code IOCTL_MOUNTDEV_LINK_CREATED\n");
805  break;
806 
808  return vol_get_gpt_attributes(Irp);
809 
811  return vol_is_dynamic(Irp);
812 
813  case IOCTL_VOLUME_ONLINE:
814  TRACE("unhandled control code IOCTL_VOLUME_ONLINE\n");
815  break;
816 
818  TRACE("unhandled control code IOCTL_VOLUME_POST_ONLINE\n");
819  break;
820 
823 
825  return vol_is_writable(vde);
826 
828  return vol_get_length(vde, Irp);
829 
832  return vol_check_verify(vde);
833 
835  return vol_get_disk_extents(vde, Irp);
836 
837  default: // pass ioctl through if only one child device
838  return vol_ioctl_passthrough(vde, Irp);
839  }
840 
842 }
843 
845  TRACE("(%p, %p)\n", DeviceObject, Irp);
846 
848 }
849 
851  TRACE("(%p, %p)\n", DeviceObject, Irp);
852 
854 }
855 
857  TRACE("(%p, %p)\n", DeviceObject, Irp);
858 
860 }
861 
865 
866  TRACE("(%p, %p)\n", DeviceObject, Irp);
867 
869  Irp->IoStatus.Status = STATUS_SUCCESS;
870 
871  Status = Irp->IoStatus.Status;
873 
874  return Status;
875 }
876 
879  ULONG mmdltsize;
882 
883  mmdltsize = (ULONG)offsetof(MOUNTMGR_DRIVE_LETTER_TARGET, DeviceName[0]) + devpath->Length;
884 
885  mmdlt = ExAllocatePoolWithTag(NonPagedPool, mmdltsize, ALLOC_TAG);
886  if (!mmdlt) {
887  ERR("out of memory\n");
889  }
890 
891  mmdlt->DeviceNameLength = devpath->Length;
892  RtlCopyMemory(&mmdlt->DeviceName, devpath->Buffer, devpath->Length);
893  TRACE("mmdlt = %.*S\n", mmdlt->DeviceNameLength / sizeof(WCHAR), mmdlt->DeviceName);
894 
895  Status = dev_ioctl(mountmgr, IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER, mmdlt, mmdltsize, &mmdli, sizeof(MOUNTMGR_DRIVE_LETTER_INFORMATION), FALSE, NULL);
896 
897  if (!NT_SUCCESS(Status))
898  ERR("IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER returned %08x\n", Status);
899  else
900  TRACE("DriveLetterWasAssigned = %u, CurrentDriveLetter = %c\n", mmdli.DriveLetterWasAssigned, mmdli.CurrentDriveLetter);
901 
902  ExFreePool(mmdlt);
903 
904  return Status;
905 }
906 
907 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE)
908 #ifdef __REACTOS__
910 #else
912 #endif
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 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)) {
984  UINT32* val = (UINT32*)((UINT8*)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 void add_volume_device(superblock* sb, PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath, UINT64 length, ULONG disk_num, ULONG part_num) {
1001  NTSTATUS Status;
1002  LIST_ENTRY* le;
1004  volume_child* vc;
1006  UNICODE_STRING devpath2;
1007  BOOL inserted = FALSE, new_pdo = FALSE;
1008  pdo_device_extension* pdode = NULL;
1009  PDEVICE_OBJECT pdo = NULL;
1010 
1011  if (devpath->Length == 0)
1012  return;
1013 
1015 
1016  le = pdo_list.Flink;
1017  while (le != &pdo_list) {
1019 
1020  if (RtlCompareMemory(&pdode2->uuid, &sb->uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1021  pdode = pdode2;
1022  break;
1023  }
1024 
1025  le = le->Flink;
1026  }
1027 
1029  if (!NT_SUCCESS(Status)) {
1030  ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
1032  return;
1033  }
1034 
1035  if (!pdode) {
1036  if (no_pnp) {
1037  Status = IoReportDetectedDevice(drvobj, InterfaceTypeUndefined, 0xFFFFFFFF, 0xFFFFFFFF, NULL, NULL, 0, &pdo);
1038 
1039  if (!NT_SUCCESS(Status)) {
1040  ERR("IoReportDetectedDevice returned %08x\n", Status);
1042  return;
1043  }
1044 
1046 
1047  if (!pdode) {
1048  ERR("out of memory\n");
1050  return;
1051  }
1052  } else {
1055  if (!NT_SUCCESS(Status)) {
1056  ERR("IoCreateDevice returned %08x\n", Status);
1058  goto fail;
1059  }
1060 
1062 
1063  pdode = pdo->DeviceExtension;
1064  }
1065 
1066  RtlZeroMemory(pdode, sizeof(pdo_device_extension));
1067 
1068  pdode->type = VCB_TYPE_PDO;
1069  pdode->pdo = pdo;
1070  pdode->uuid = sb->uuid;
1071 
1073  InitializeListHead(&pdode->children);
1074  pdode->num_children = sb->num_devices;
1075  pdode->children_loaded = 0;
1076 
1077  pdo->Flags &= ~DO_DEVICE_INITIALIZING;
1078  pdo->SectorSize = (USHORT)sb->sector_size;
1079 
1081 
1082  new_pdo = TRUE;
1083  } else {
1086 
1087  le = pdode->children.Flink;
1088  while (le != &pdode->children) {
1090 
1091  if (RtlCompareMemory(&vc2->uuid, &sb->dev_item.device_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1092  // duplicate, ignore
1095  goto fail;
1096  }
1097 
1098  le = le->Flink;
1099  }
1100  }
1101 
1103  if (!vc) {
1104  ERR("out of memory\n");
1105 
1108 
1109  goto fail;
1110  }
1111 
1112  vc->uuid = sb->dev_item.device_uuid;
1113  vc->devid = sb->dev_item.dev_id;
1114  vc->generation = sb->generation;
1115  vc->notification_entry = NULL;
1116 
1118  drvobj, pnp_removal, pdode, &vc->notification_entry);
1119  if (!NT_SUCCESS(Status))
1120  WARN("IoRegisterPlugPlayNotification returned %08x\n", Status);
1121 
1122  vc->devobj = DeviceObject;
1123  vc->fileobj = FileObject;
1124 
1125  devpath2 = *devpath;
1126 
1127  // The PNP path sometimes begins \\?\ and sometimes \??\. We need to remove this prefix
1128  // so we can compare properly if the device is removed.
1129  if (devpath->Length > 4 * sizeof(WCHAR) && devpath->Buffer[0] == '\\' && (devpath->Buffer[1] == '\\' || devpath->Buffer[1] == '?') &&
1130  devpath->Buffer[2] == '?' && devpath->Buffer[3] == '\\') {
1131  devpath2.Buffer = &devpath2.Buffer[3];
1132  devpath2.Length -= 3 * sizeof(WCHAR);
1133  devpath2.MaximumLength -= 3 * sizeof(WCHAR);
1134  }
1135 
1136  vc->pnp_name.Length = vc->pnp_name.MaximumLength = devpath2.Length;
1138 
1139  if (vc->pnp_name.Buffer)
1140  RtlCopyMemory(vc->pnp_name.Buffer, devpath2.Buffer, devpath2.Length);
1141  else {
1142  ERR("out of memory\n");
1143  vc->pnp_name.Length = vc->pnp_name.MaximumLength = 0;
1144  }
1145 
1146  vc->size = length;
1148  vc->disk_num = disk_num;
1149  vc->part_num = part_num;
1150  vc->had_drive_letter = FALSE;
1151 
1152  le = pdode->children.Flink;
1153  while (le != &pdode->children) {
1155 
1156  if (vc2->generation < vc->generation) {
1157  if (le == pdode->children.Flink)
1158  pdode->num_children = sb->num_devices;
1159 
1161  inserted = TRUE;
1162  break;
1163  }
1164 
1165  le = le->Flink;
1166  }
1167 
1168  if (!inserted)
1169  InsertTailList(&pdode->children, &vc->list_entry);
1170 
1171  pdode->children_loaded++;
1172 
1173  if (pdode->vde && pdode->vde->mounted_device) {
1175 
1176  ExAcquireResourceExclusiveLite(&Vcb->tree_lock, TRUE);
1177 
1178  le = Vcb->devices.Flink;
1179  while (le != &Vcb->devices) {
1181 
1182  if (!dev->devobj && RtlCompareMemory(&dev->devitem.device_uuid, &sb->dev_item.device_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1183  dev->devobj = DeviceObject;
1184  dev->disk_num = disk_num;
1185  dev->part_num = part_num;
1186  init_device(Vcb, dev, FALSE);
1187  break;
1188  }
1189 
1190  le = le->Flink;
1191  }
1192 
1193  ExReleaseResourceLite(&Vcb->tree_lock);
1194  }
1195 
1196  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
1197  pdode->removable = TRUE;
1198 
1199  if (pdode->vde && pdode->vde->device)
1200  pdode->vde->device->Characteristics |= FILE_REMOVABLE_MEDIA;
1201  }
1202 
1203  if (pdode->num_children == pdode->children_loaded || (pdode->children_loaded == 1 && allow_degraded_mount(&sb->uuid))) {
1204  if (pdode->num_children == 1) {
1205  Status = remove_drive_letter(mountmgr, devpath);
1207  WARN("remove_drive_letter returned %08x\n", Status);
1208 
1210  } else {
1211  le = pdode->children.Flink;
1212 
1213  while (le != &pdode->children) {
1215 
1217 
1218  name.Length = name.MaximumLength = vc->pnp_name.Length + (3 * sizeof(WCHAR));
1219  name.Buffer = ExAllocatePoolWithTag(PagedPool, name.Length, ALLOC_TAG);
1220 
1221  if (!name.Buffer) {
1222  ERR("out of memory\n");
1223 
1226 
1227  goto fail;
1228  }
1229 
1230  RtlCopyMemory(name.Buffer, L"\\??", 3 * sizeof(WCHAR));
1231  RtlCopyMemory(&name.Buffer[3], vc->pnp_name.Buffer, vc->pnp_name.Length);
1232 
1233  Status = remove_drive_letter(mountmgr, &name);
1234 
1236  WARN("remove_drive_letter returned %08x\n", Status);
1237 
1238  ExFreePool(name.Buffer);
1239 
1241 
1242  le = le->Flink;
1243  }
1244  }
1245 
1246  if ((!new_pdo || !no_pnp) && pdode->vde) {
1248  if (!NT_SUCCESS(Status))
1249  WARN("IoSetDeviceInterfaceState returned %08x\n", Status);
1250  }
1251  }
1252 
1254 
1255  if (new_pdo) {
1257 
1258  InsertTailList(&pdo_list, &pdode->list_entry);
1259 
1260  if (!no_pnp)
1262  }
1263 
1265 
1266  if (new_pdo && no_pnp)
1267  AddDevice(drvobj, pdo);
1268 
1269  return;
1270 
1271 fail:
1273 }
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:630
#define hex_digit(c)
Definition: btrfs_drv.h:1686
#define IN
Definition: typedefs.h:38
NTSTATUS vol_device_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:777
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:814
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:926
#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:114
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
_In_ PIRP Irp
Definition: csq.h:116
superblock * sb
Definition: btrfs.c:3876
UINT64 num_devices
Definition: btrfs.h:216
#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:3059
PDEVICE_OBJECT device
Definition: btrfs_drv.h:829
#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:831
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:157
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:820
#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:811
#define IOCTL_VOLUME_IS_DYNAMIC
Definition: volume.c:25
#define MOUNTMGR_DEVICE_NAME
Definition: imports.h:76
#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:809
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
BOOL had_drive_letter
Definition: btrfs_drv.h:817
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
UNICODE_STRING name
Definition: btrfs_drv.h:828
PDEVICE_OBJECT pdo
Definition: btrfs_drv.h:843
#define ALLOC_TAG
Definition: btrfs_drv.h:86
UNICODE_STRING bus_name
Definition: btrfs_drv.h:833
#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:2603
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:877
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:217
static NTSTATUS vol_get_drive_geometry(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: volume.c:602
PDEVICE_OBJECT devobj
Definition: btrfs_drv.h:812
#define IOCTL_VOLUME_ONLINE
Definition: ntddvol.h:62
#define IoCompleteRequest
Definition: irp.c:1240
DEV_ITEM dev_item
Definition: btrfs.h:230
#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:832
_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:862
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:169
#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:851
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:848
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
void * notification_entry
Definition: btrfs_drv.h:818
PDEVICE_OBJECT mounted_device
Definition: btrfs_drv.h:830
* PFILE_OBJECT
Definition: iotypes.h:1954
ULONG disk_num
Definition: btrfs_drv.h:819
#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:813
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:816
void add_volume_device(superblock *sb, PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath, UINT64 length, ULONG disk_num, ULONG part_num)
Definition: volume.c:1000
__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:810
#define ERR(fmt,...)
Definition: debug.h:109
NTSTATUS vol_query_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:850
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:5082
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:856
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:204
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
UINT64 generation
Definition: btrfs.h:208
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:842
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:821
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:849
static const BYTE ext3[]
Definition: encode.c:2701
UINT64 flags
Definition: btrfs.h:206
return STATUS_SUCCESS
Definition: btrfs.c:2725
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:803
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:844
UINT64 size
Definition: btrfs_drv.h:815
#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