ReactOS  0.4.15-dev-5462-g4d0d22a
search.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 
20 #include <ntddk.h>
21 #include <ntifs.h>
22 #include <mountmgr.h>
23 #include <windef.h>
24 #include <ntddstor.h>
25 #include <ntdddisk.h>
26 #include <ntddvol.h>
27 
28 #include <initguid.h>
29 #include <wdmguid.h>
30 #include <ioevent.h>
31 
33 extern LIST_ENTRY pdo_list;
37 extern bool shutting_down;
38 extern PDEVICE_OBJECT busobj;
40 extern ERESOURCE boot_lock;
41 extern PDRIVER_OBJECT drvobj;
42 
43 typedef void (*pnp_callback)(PUNICODE_STRING devpath);
44 
45 #ifndef __REACTOS__
46 // not in mingw yet
47 #ifndef _MSC_VER
48 DEFINE_GUID(GUID_IO_VOLUME_FVE_STATUS_CHANGE, 0x062998b2, 0xee1f, 0x4b6a, 0xb8, 0x57, 0xe7, 0x6c, 0xbb, 0xe9, 0xa6, 0xda);
49 #endif
50 #endif // __REACTOS__
51 
53 
54 typedef struct {
59  WCHAR buf[1];
60 } fve_data;
61 
64 
65 static bool fs_ignored(BTRFS_UUID* uuid) {
66  UNICODE_STRING path, ignoreus;
70  ULONG dispos, retlen, kvfilen, i, j;
71  HANDLE h;
72  bool ret = false;
73 
74  path.Length = path.MaximumLength = registry_path.Length + (37 * sizeof(WCHAR));
75 
77  if (!path.Buffer) {
78  ERR("out of memory\n");
79  return false;
80  }
81 
83 
84  i = registry_path.Length / sizeof(WCHAR);
85 
86  path.Buffer[i] = '\\';
87  i++;
88 
89  for (j = 0; j < 16; j++) {
90  path.Buffer[i] = hex_digit((uuid->uuid[j] & 0xF0) >> 4);
91  path.Buffer[i+1] = hex_digit(uuid->uuid[j] & 0xF);
92 
93  i += 2;
94 
95  if (j == 3 || j == 5 || j == 7 || j == 9) {
96  path.Buffer[i] = '-';
97  i++;
98  }
99  }
100 
102 
103  Status = ZwCreateKey(&h, KEY_QUERY_VALUE, &oa, 0, NULL, REG_OPTION_NON_VOLATILE, &dispos);
104 
105  if (!NT_SUCCESS(Status)) {
106  TRACE("ZwCreateKey returned %08lx\n", Status);
107  ExFreePool(path.Buffer);
108  return false;
109  }
110 
111  RtlInitUnicodeString(&ignoreus, L"Ignore");
112 
113  kvfilen = (ULONG)offsetof(KEY_VALUE_FULL_INFORMATION, Name[0]) + (255 * sizeof(WCHAR));
114  kvfi = ExAllocatePoolWithTag(PagedPool, kvfilen, ALLOC_TAG);
115  if (!kvfi) {
116  ERR("out of memory\n");
117  ZwClose(h);
118  ExFreePool(path.Buffer);
119  return false;
120  }
121 
122  Status = ZwQueryValueKey(h, &ignoreus, KeyValueFullInformation, kvfi, kvfilen, &retlen);
123  if (NT_SUCCESS(Status)) {
124  if (kvfi->Type == REG_DWORD && kvfi->DataLength >= sizeof(uint32_t)) {
125  uint32_t* pr = (uint32_t*)((uint8_t*)kvfi + kvfi->DataOffset);
126 
127  ret = *pr;
128  }
129  }
130 
131  ZwClose(h);
132  ExFreePool(kvfi);
133  ExFreePool(path.Buffer);
134 
135  return ret;
136 }
137 
138 typedef struct {
143  WCHAR buf[1];
145 
146 _Function_class_(IO_WORKITEM_ROUTINE)
147 static void __stdcall fve_callback(PDEVICE_OBJECT DeviceObject, PVOID con) {
148  fve_callback_context* ctx = con;
149 
151 
152  if (volume_arrival(&ctx->devpath, true)) {
153  KIRQL irql;
154  LIST_ENTRY* le;
155  fve_data* d = NULL;
156 
157  // volume no longer locked - unregister notification
158 
160 
161  le = fve_data_list.Flink;
162  while (le != &fve_data_list) {
164 
165  if (d2->devobj == ctx->devobj) {
167  d = d2;
168  break;
169  }
170 
171  le = le->Flink;
172  }
173 
175 
176  if (d) {
177  IoUnregisterPlugPlayNotification(d->notification_entry);
178  ExFreePool(d);
179  }
180  }
181 
182  IoFreeWorkItem(ctx->work_item);
183  ExFreePool(ctx);
184 }
185 
188  PDEVICE_OBJECT devobj = Context;
189  PIO_WORKITEM work_item;
191  LIST_ENTRY* le;
192  KIRQL irql;
193 
194  if (RtlCompareMemory(&tdrn->Event, &GUID_IO_VOLUME_FVE_STATUS_CHANGE, sizeof(GUID)) != sizeof(GUID))
195  return STATUS_SUCCESS;
196 
197  /* The FVE event has trailing data, presumably telling us whether the volume has
198  * been unlocked or whatever, but unfortunately it's undocumented! */
199 
200  work_item = IoAllocateWorkItem(master_devobj);
201  if (!work_item) {
202  ERR("out of memory\n");
203  return STATUS_SUCCESS;
204  }
205 
207 
208  le = fve_data_list.Flink;
209  while (le != &fve_data_list) {
211 
212  if (d->devobj == devobj) {
214  ALLOC_TAG);
215 
216  if (!ctx) {
218  ERR("out of memory\n");
219  IoFreeWorkItem(work_item);
220  return STATUS_SUCCESS;
221  }
222 
223  RtlCopyMemory(ctx->buf, d->devpath.Buffer, d->devpath.Length);
224  ctx->devpath.Length = ctx->devpath.MaximumLength = d->devpath.Length;
225 
227 
228  ctx->devpath.Buffer = ctx->buf;
229 
230  ctx->fileobj = tdrn->FileObject;
231  ctx->devobj = devobj;
232  ctx->work_item = work_item;
233 
234  IoQueueWorkItem(work_item, fve_callback, DelayedWorkQueue, ctx);
235 
236  return STATUS_SUCCESS;
237  }
238 
239  le = le->Flink;
240  }
241 
243 
244  IoFreeWorkItem(work_item);
245 
246  return STATUS_SUCCESS;
247 }
248 
250  PUNICODE_STRING devpath) {
252  KIRQL irql;
253  LIST_ENTRY* le;
254 
256  if (!d) {
257  ERR("out of memory\n");
258  return;
259  }
260 
261  d->devpath.Buffer = d->buf;
262  d->devpath.Length = d->devpath.MaximumLength = devpath->Length;
263  RtlCopyMemory(d->devpath.Buffer, devpath->Buffer, devpath->Length);
264 
266 
267  le = fve_data_list.Flink;
268  while (le != &fve_data_list) {
270 
271  if (d2->devobj == devobj) {
273  ExFreePool(d);
274  return;
275  }
276 
277  le = le->Flink;
278  }
279 
281 
283  devobj, &d->notification_entry);
284  if (!NT_SUCCESS(Status)) {
285  ERR("IoRegisterPlugPlayNotification returned %08lx\n", Status);
286  return;
287  }
288 
290 
291  le = fve_data_list.Flink;
292  while (le != &fve_data_list) {
294 
295  if (d2->devobj == devobj) {
297  IoUnregisterPlugPlayNotification(d->notification_entry);
298  ExFreePool(d);
299  return;
300  }
301 
302  le = le->Flink;
303  }
304 
305  d->devobj = devobj;
306  InsertTailList(&fve_data_list, &d->list_entry);
307 
309 }
310 
312  PUNICODE_STRING devpath, DWORD disk_num, DWORD part_num, uint64_t length,
313  bool fve_callback) {
315  ULONG toread;
316  uint8_t* data = NULL;
318  bool ret = true;
319 
320  TRACE("%.*S\n", (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer);
321 
322  sector_size = DeviceObject->SectorSize;
323 
324  if (sector_size == 0) {
325  DISK_GEOMETRY geometry;
327 
329  &geometry, sizeof(DISK_GEOMETRY), true, &iosb);
330 
331  if (!NT_SUCCESS(Status)) {
332  ERR("%.*S had a sector size of 0, and IOCTL_DISK_GET_DRIVE_GEOMETRY returned %08lx\n",
333  (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer, Status);
334  goto deref;
335  }
336 
337  if (iosb.Information < sizeof(DISK_GEOMETRY)) {
338  ERR("%.*S: IOCTL_DISK_GET_DRIVE_GEOMETRY returned %Iu bytes, expected %Iu\n",
339  (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer, iosb.Information, sizeof(DISK_GEOMETRY));
340  }
341 
342  sector_size = geometry.BytesPerSector;
343 
344  if (sector_size == 0) {
345  ERR("%.*S had a sector size of 0\n", (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer);
346  goto deref;
347  }
348  }
349 
350  toread = (ULONG)sector_align(sizeof(superblock), sector_size);
352  if (!data) {
353  ERR("out of memory\n");
354  goto deref;
355  }
356 
358 
359  if (NT_SUCCESS(Status) && ((superblock*)data)->magic == BTRFS_MAGIC) {
361 
363  TRACE("volume found\n");
364 
365  if (length >= superblock_addrs[1] + toread) {
366  ULONG i = 1;
367 
369  if (!sb2) {
370  ERR("out of memory\n");
371  goto deref;
372  }
373 
374  while (superblock_addrs[i] > 0 && length >= superblock_addrs[i] + toread) {
376 
377  if (NT_SUCCESS(Status) && sb2->magic == BTRFS_MAGIC) {
378  if (check_superblock_checksum(sb2) && sb2->generation > sb->generation)
379  RtlCopyMemory(sb, sb2, toread);
380  }
381 
382  i++;
383  }
384 
385  ExFreePool(sb2);
386  }
387 
388  if (!fs_ignored(&sb->uuid)) {
389  DeviceObject->Flags &= ~DO_VERIFY_VOLUME;
390  add_volume_device(sb, devpath, length, disk_num, part_num);
391  }
392  }
393  } else if (Status == STATUS_FVE_LOCKED_VOLUME) {
394  if (fve_callback)
395  ret = false;
396  else
398  }
399 
400 deref:
401  if (data)
402  ExFreePool(data);
403 
404  return ret;
405 }
406 
410  ULONG mmpsize;
411  MOUNTMGR_MOUNT_POINTS mmps1, *mmps2;
412 
413  TRACE("removing drive letter\n");
414 
415  mmpsize = sizeof(MOUNTMGR_MOUNT_POINT) + devpath->Length;
416 
417  mmp = ExAllocatePoolWithTag(PagedPool, mmpsize, ALLOC_TAG);
418  if (!mmp) {
419  ERR("out of memory\n");
421  }
422 
423  RtlZeroMemory(mmp, mmpsize);
424 
425  mmp->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
426  mmp->DeviceNameLength = devpath->Length;
427  RtlCopyMemory(&mmp[1], devpath->Buffer, devpath->Length);
428 
429  Status = dev_ioctl(mountmgr, IOCTL_MOUNTMGR_DELETE_POINTS, mmp, mmpsize, &mmps1, sizeof(MOUNTMGR_MOUNT_POINTS), false, NULL);
430 
432  ERR("IOCTL_MOUNTMGR_DELETE_POINTS 1 returned %08lx\n", Status);
433  ExFreePool(mmp);
434  return Status;
435  }
436 
437  if (Status != STATUS_BUFFER_OVERFLOW || mmps1.Size == 0) {
438  ExFreePool(mmp);
439  return STATUS_NOT_FOUND;
440  }
441 
443  if (!mmps2) {
444  ERR("out of memory\n");
445  ExFreePool(mmp);
447  }
448 
449  Status = dev_ioctl(mountmgr, IOCTL_MOUNTMGR_DELETE_POINTS, mmp, mmpsize, mmps2, mmps1.Size, false, NULL);
450 
451  if (!NT_SUCCESS(Status))
452  ERR("IOCTL_MOUNTMGR_DELETE_POINTS 2 returned %08lx\n", Status);
453 
454  ExFreePool(mmps2);
455  ExFreePool(mmp);
456 
457  return Status;
458 }
459 
461  PFILE_OBJECT fileobj;
462  PDEVICE_OBJECT devobj;
465  ULONG dlisize;
466  DRIVE_LAYOUT_INFORMATION_EX* dli = NULL;
469 
471 
472  Status = IoGetDeviceObjectPointer(devpath, FILE_READ_ATTRIBUTES, &fileobj, &devobj);
473  if (!NT_SUCCESS(Status)) {
475  ERR("IoGetDeviceObjectPointer returned %08lx\n", Status);
476  return;
477  }
478 
479  dlisize = 0;
480 
481  do {
482  dlisize += 1024;
483 
484  if (dli)
485  ExFreePool(dli);
486 
487  dli = ExAllocatePoolWithTag(PagedPool, dlisize, ALLOC_TAG);
488  if (!dli) {
489  ERR("out of memory\n");
490  goto end;
491  }
492 
494  dli, dlisize, true, &iosb);
495  } while (Status == STATUS_BUFFER_TOO_SMALL);
496 
497  // only consider disk as a potential filesystem if it has no partitions
498  if (NT_SUCCESS(Status) && dli->PartitionCount > 0) {
499  ExFreePool(dli);
500  goto end;
501  }
502 
503  ExFreePool(dli);
504 
506  &gli, sizeof(gli), true, NULL);
507 
508  if (!NT_SUCCESS(Status)) {
509  ERR("error reading length information: %08lx\n", Status);
510  goto end;
511  }
512 
514  &sdn, sizeof(STORAGE_DEVICE_NUMBER), true, NULL);
515  if (!NT_SUCCESS(Status)) {
516  TRACE("IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08lx\n", Status);
517  sdn.DeviceNumber = 0xffffffff;
518  sdn.PartitionNumber = 0;
519  } else
520  TRACE("DeviceType = %lu, DeviceNumber = %lu, PartitionNumber = %lu\n", sdn.DeviceType, sdn.DeviceNumber, sdn.PartitionNumber);
521 
522  test_vol(devobj, fileobj, devpath, sdn.DeviceNumber, sdn.PartitionNumber,
523  gli.Length.QuadPart, false);
524 
525 end:
526  ObDereferenceObject(fileobj);
527 
529 }
530 
532  _In_ volume_child* vc, _In_ bool skip_dev) {
534  pdo_device_extension* pdode = vde->pdode;
535  device_extension* Vcb = vde->mounted_device ? vde->mounted_device->DeviceExtension : NULL;
536 
537  if (vc->notification_entry) {
539  fIoUnregisterPlugPlayNotificationEx(vc->notification_entry);
540  else
541  IoUnregisterPlugPlayNotification(vc->notification_entry);
542  }
543 
544  if (vde->mounted_device && (!Vcb || !Vcb->options.allow_degraded)) {
545  Status = pnp_surprise_removal(vde->mounted_device, NULL);
546  if (!NT_SUCCESS(Status))
547  ERR("pnp_surprise_removal returned %08lx\n", Status);
548  }
549 
550  if (!Vcb || !Vcb->options.allow_degraded) {
551  Status = IoSetDeviceInterfaceState(&vde->bus_name, false);
552  if (!NT_SUCCESS(Status))
553  WARN("IoSetDeviceInterfaceState returned %08lx\n", Status);
554  }
555 
556  if (pdode->children_loaded > 0) {
557  UNICODE_STRING mmdevpath;
560  LIST_ENTRY* le;
561 
562  if (!Vcb || !Vcb->options.allow_degraded) {
565  if (!NT_SUCCESS(Status))
566  ERR("IoGetDeviceObjectPointer returned %08lx\n", Status);
567  else {
568  le = pdode->children.Flink;
569 
570  while (le != &pdode->children) {
572 
573  if (vc2->had_drive_letter) { // re-add entry to mountmgr
574  MOUNTDEV_NAME mdn;
575 
578  ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status);
579  else {
580  MOUNTDEV_NAME* mdn2;
581  ULONG mdnsize = (ULONG)offsetof(MOUNTDEV_NAME, Name[0]) + mdn.NameLength;
582 
583  mdn2 = ExAllocatePoolWithTag(PagedPool, mdnsize, ALLOC_TAG);
584  if (!mdn2)
585  ERR("out of memory\n");
586  else {
587  Status = dev_ioctl(vc2->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, mdn2, mdnsize, true, NULL);
588  if (!NT_SUCCESS(Status))
589  ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status);
590  else {
592 
593  name.Buffer = mdn2->Name;
594  name.Length = name.MaximumLength = mdn2->NameLength;
595 
597  if (!NT_SUCCESS(Status))
598  WARN("mountmgr_add_drive_letter returned %08lx\n", Status);
599  }
600 
601  ExFreePool(mdn2);
602  }
603  }
604  }
605 
606  le = le->Flink;
607  }
608 
610  }
611  } else if (!skip_dev) {
612  ExAcquireResourceExclusiveLite(&Vcb->tree_lock, true);
613 
614  le = Vcb->devices.Flink;
615  while (le != &Vcb->devices) {
617 
618  if (dev->devobj == vc->devobj) {
619  dev->devobj = NULL; // mark as missing
620  break;
621  }
622 
623  le = le->Flink;
624  }
625 
626  ExReleaseResourceLite(&Vcb->tree_lock);
627  }
628 
629  if (vde->device->Characteristics & FILE_REMOVABLE_MEDIA) {
630  vde->device->Characteristics &= ~FILE_REMOVABLE_MEDIA;
631 
632  le = pdode->children.Flink;
633  while (le != &pdode->children) {
635 
636  if (vc2 != vc && vc2->devobj->Characteristics & FILE_REMOVABLE_MEDIA) {
637  vde->device->Characteristics |= FILE_REMOVABLE_MEDIA;
638  break;
639  }
640 
641  le = le->Flink;
642  }
643  }
644  }
645 
646  ObDereferenceObject(vc->fileobj);
647  ExFreePool(vc->pnp_name.Buffer);
648  RemoveEntryList(&vc->list_entry);
649  ExFreePool(vc);
650 
651  pdode->children_loaded--;
652 
653  if (pdode->children_loaded == 0) { // remove volume device
654  bool remove = false;
655 
656  RemoveEntryList(&pdode->list_entry);
657 
658  vde->removing = true;
659 
660  Status = IoSetDeviceInterfaceState(&vde->bus_name, false);
661  if (!NT_SUCCESS(Status))
662  WARN("IoSetDeviceInterfaceState returned %08lx\n", Status);
663 
664  if (vde->pdo->AttachedDevice)
665  IoDetachDevice(vde->pdo);
666 
667  if (vde->open_count == 0)
668  remove = true;
669 
671 
672  if (!no_pnp) {
674 
676  }
677 
678  if (remove) {
679  if (vde->name.Buffer)
680  ExFreePool(vde->name.Buffer);
681 
682  if (Vcb)
683  Vcb->vde = NULL;
684 
686 
687  IoDeleteDevice(vde->device);
688  }
689  } else
691 }
692 
693 bool volume_arrival(PUNICODE_STRING devpath, bool fve_callback) {
695  PFILE_OBJECT fileobj;
696  PDEVICE_OBJECT devobj;
699  bool ret = true;
700 
701  TRACE("%.*S\n", (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer);
702 
704 
705  Status = IoGetDeviceObjectPointer(devpath, FILE_READ_ATTRIBUTES, &fileobj, &devobj);
706  if (!NT_SUCCESS(Status)) {
708  ERR("IoGetDeviceObjectPointer returned %08lx\n", Status);
709  return false;
710  }
711 
712  // make sure we're not processing devices we've created ourselves
713 
714  if (devobj->DriverObject == drvobj)
715  goto end;
716 
717  Status = dev_ioctl(devobj, IOCTL_VOLUME_ONLINE, NULL, 0, NULL, 0, true, NULL);
718  if (!NT_SUCCESS(Status))
719  TRACE("IOCTL_VOLUME_ONLINE returned %08lx\n", Status);
720 
721  Status = dev_ioctl(devobj, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &gli, sizeof(gli), true, NULL);
722  if (!NT_SUCCESS(Status)) {
723  ERR("IOCTL_DISK_GET_LENGTH_INFO returned %08lx\n", Status);
724  goto end;
725  }
726 
728  &sdn, sizeof(STORAGE_DEVICE_NUMBER), true, NULL);
729  if (!NT_SUCCESS(Status)) {
730  TRACE("IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08lx\n", Status);
731  sdn.DeviceNumber = 0xffffffff;
732  sdn.PartitionNumber = 0;
733  } else
734  TRACE("DeviceType = %lu, DeviceNumber = %lu, PartitionNumber = %lu\n", sdn.DeviceType, sdn.DeviceNumber, sdn.PartitionNumber);
735 
736  // If we've just added a partition to a whole-disk filesystem, unmount it
737  if (sdn.DeviceNumber != 0xffffffff && sdn.PartitionNumber != 0) {
738  LIST_ENTRY* le;
739 
741 
742  le = pdo_list.Flink;
743  while (le != &pdo_list) {
745  LIST_ENTRY* le2;
746  bool changed = false;
747 
748  if (pdode->vde) {
750 
751  le2 = pdode->children.Flink;
752  while (le2 != &pdode->children) {
754  LIST_ENTRY* le3 = le2->Flink;
755 
756  if (vc->disk_num == sdn.DeviceNumber && vc->part_num == 0) {
757  TRACE("removing device\n");
758 
759  remove_volume_child(pdode->vde, vc, false);
760  changed = true;
761 
762  break;
763  }
764 
765  le2 = le3;
766  }
767 
768  if (!changed)
770  else
771  break;
772  }
773 
774  le = le->Flink;
775  }
776 
778  }
779 
780  ret = test_vol(devobj, fileobj, devpath, sdn.DeviceNumber, sdn.PartitionNumber,
781  gli.Length.QuadPart, fve_callback);
782 
783 end:
784  ObDereferenceObject(fileobj);
785 
787 
788  return ret;
789 }
790 
791 static void volume_arrival2(PUNICODE_STRING devpath) {
792  volume_arrival(devpath, false);
793 }
794 
796  LIST_ENTRY* le;
797  UNICODE_STRING devpath2;
798 
799  TRACE("%.*S\n", (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer);
800 
801  devpath2 = *devpath;
802 
803  if (devpath->Length > 4 * sizeof(WCHAR) && devpath->Buffer[0] == '\\' && (devpath->Buffer[1] == '\\' || devpath->Buffer[1] == '?') &&
804  devpath->Buffer[2] == '?' && devpath->Buffer[3] == '\\') {
805  devpath2.Buffer = &devpath2.Buffer[3];
806  devpath2.Length -= 3 * sizeof(WCHAR);
807  devpath2.MaximumLength -= 3 * sizeof(WCHAR);
808  }
809 
811 
812  le = pdo_list.Flink;
813  while (le != &pdo_list) {
815  LIST_ENTRY* le2;
816  bool changed = false;
817 
818  if (pdode->vde) {
820 
821  le2 = pdode->children.Flink;
822  while (le2 != &pdode->children) {
824  LIST_ENTRY* le3 = le2->Flink;
825 
826  if (vc->pnp_name.Length == devpath2.Length && RtlCompareMemory(vc->pnp_name.Buffer, devpath2.Buffer, devpath2.Length) == devpath2.Length) {
827  TRACE("removing device\n");
828 
829  if (!vc->boot_volume) {
830  remove_volume_child(pdode->vde, vc, false);
831  changed = true;
832  }
833 
834  break;
835  }
836 
837  le2 = le3;
838  }
839 
840  if (!changed)
842  else
843  break;
844  }
845 
846  le = le->Flink;
847  }
848 
850 }
851 
852 typedef struct {
857 
858 _Function_class_(IO_WORKITEM_ROUTINE)
859 static void __stdcall do_pnp_callback(PDEVICE_OBJECT DeviceObject, PVOID con) {
861 
863 
864  context->func(&context->name);
865 
866  if (context->name.Buffer)
867  ExFreePool(context->name.Buffer);
868 
869  IoFreeWorkItem(context->work_item);
870 
872 }
873 
875  PIO_WORKITEM work_item;
877 
878  work_item = IoAllocateWorkItem(master_devobj);
879  if (!work_item) {
880  ERR("out of memory\n");
881  return;
882  }
883 
885 
886  if (!context) {
887  ERR("out of memory\n");
888  IoFreeWorkItem(work_item);
889  return;
890  }
891 
892  if (name->Length > 0) {
893  context->name.Buffer = ExAllocatePoolWithTag(PagedPool, name->Length, ALLOC_TAG);
894  if (!context->name.Buffer) {
895  ERR("out of memory\n");
897  IoFreeWorkItem(work_item);
898  return;
899  }
900 
901  RtlCopyMemory(context->name.Buffer, name->Buffer, name->Length);
902  context->name.Length = context->name.MaximumLength = name->Length;
903  } else {
904  context->name.Length = context->name.MaximumLength = 0;
905  context->name.Buffer = NULL;
906  }
907 
908  context->func = func;
909  context->work_item = work_item;
910 
911  IoQueueWorkItem(work_item, do_pnp_callback, DelayedWorkQueue, context);
912 }
913 
914 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE)
917 
918  UNUSED(Context);
919 
920  if (RtlCompareMemory(&dicn->Event, &GUID_DEVICE_INTERFACE_ARRIVAL, sizeof(GUID)) == sizeof(GUID))
922  else if (RtlCompareMemory(&dicn->Event, &GUID_DEVICE_INTERFACE_REMOVAL, sizeof(GUID)) == sizeof(GUID))
924 
925  return STATUS_SUCCESS;
926 }
927 
928 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE)
931 
932  UNUSED(Context);
933 
934  if (RtlCompareMemory(&dicn->Event, &GUID_DEVICE_INTERFACE_ARRIVAL, sizeof(GUID)) == sizeof(GUID))
936  else if (RtlCompareMemory(&dicn->Event, &GUID_DEVICE_INTERFACE_REMOVAL, sizeof(GUID)) == sizeof(GUID))
938 
939  return STATUS_SUCCESS;
940 }
941 
944  LIST_ENTRY* le;
945  bool need_remove = false;
946  volume_child* vc2 = NULL;
947 
949 
950  le = pdo_list.Flink;
951  while (le != &pdo_list) {
953  LIST_ENTRY* le2;
954 
956 
957  le2 = pdode->children.Flink;
958 
959  while (le2 != &pdode->children) {
961 
962  if (vc->devobj) {
963  MOUNTDEV_NAME mdn;
964 
967  ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status);
968  else {
969  MOUNTDEV_NAME* mdn2;
970  ULONG mdnsize = (ULONG)offsetof(MOUNTDEV_NAME, Name[0]) + mdn.NameLength;
971 
972  mdn2 = ExAllocatePoolWithTag(NonPagedPool, mdnsize, ALLOC_TAG);
973  if (!mdn2)
974  ERR("out of memory\n");
975  else {
976  Status = dev_ioctl(vc->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, mdn2, mdnsize, true, NULL);
977  if (!NT_SUCCESS(Status))
978  ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status);
979  else {
980  if (mdn2->NameLength == device_name->Length && RtlCompareMemory(mdn2->Name, device_name->Buffer, device_name->Length) == device_name->Length) {
981  vc2 = vc;
982  need_remove = true;
983  break;
984  }
985  }
986 
987  ExFreePool(mdn2);
988  }
989  }
990  }
991 
992  le2 = le2->Flink;
993  }
994 
996 
997  if (need_remove)
998  break;
999 
1000  le = le->Flink;
1001  }
1002 
1004 
1005  if (need_remove) {
1007  if (!NT_SUCCESS(Status))
1008  ERR("remove_drive_letter returned %08lx\n", Status);
1009  else
1010  vc2->had_drive_letter = true;
1011  }
1012 }
1013 
1015  ULONG i;
1016 
1017  static const WCHAR pref[] = L"\\DosDevices\\";
1018 
1019  for (i = 0; i < mmps->NumberOfMountPoints; i++) {
1020  UNICODE_STRING symlink, device_name;
1021 
1022  if (mmps->MountPoints[i].SymbolicLinkNameOffset != 0) {
1023  symlink.Buffer = (WCHAR*)(((uint8_t*)mmps) + mmps->MountPoints[i].SymbolicLinkNameOffset);
1024  symlink.Length = symlink.MaximumLength = mmps->MountPoints[i].SymbolicLinkNameLength;
1025  } else {
1026  symlink.Buffer = NULL;
1027  symlink.Length = symlink.MaximumLength = 0;
1028  }
1029 
1030  if (mmps->MountPoints[i].DeviceNameOffset != 0) {
1031  device_name.Buffer = (WCHAR*)(((uint8_t*)mmps) + mmps->MountPoints[i].DeviceNameOffset);
1032  device_name.Length = device_name.MaximumLength = mmps->MountPoints[i].DeviceNameLength;
1033  } else {
1034  device_name.Buffer = NULL;
1035  device_name.Length = device_name.MaximumLength = 0;
1036  }
1037 
1038  if (symlink.Length > sizeof(pref) - sizeof(WCHAR) &&
1039  RtlCompareMemory(symlink.Buffer, pref, sizeof(pref) - sizeof(WCHAR)) == sizeof(pref) - sizeof(WCHAR))
1041  }
1042 }
1043 
1044 _Function_class_(KSTART_ROUTINE)
1045 void __stdcall mountmgr_thread(_In_ void* context) {
1046  UNICODE_STRING mmdevpath;
1047  NTSTATUS Status;
1051 
1052  UNUSED(context);
1053 
1056  if (!NT_SUCCESS(Status)) {
1057  ERR("IoGetDeviceObjectPointer returned %08lx\n", Status);
1058  return;
1059  }
1060 
1061  mcni.EpicNumber = 0;
1062 
1063  while (true) {
1064  PIRP Irp;
1066  MOUNTMGR_MOUNT_POINTS mmps;
1068 
1070 
1072  &mcni, sizeof(MOUNTMGR_CHANGE_NOTIFY_INFO), false, &mountmgr_thread_event, &iosb);
1073 
1074  if (!Irp) {
1075  ERR("out of memory\n");
1076  break;
1077  }
1078 
1080 
1081  if (Status == STATUS_PENDING) {
1083  Status = iosb.Status;
1084  }
1085 
1086  if (shutting_down)
1087  break;
1088 
1089  if (!NT_SUCCESS(Status)) {
1090  ERR("IOCTL_MOUNTMGR_CHANGE_NOTIFY returned %08lx\n", Status);
1091  break;
1092  }
1093 
1094  TRACE("mountmgr changed\n");
1095 
1096  RtlZeroMemory(&mmp, sizeof(MOUNTMGR_MOUNT_POINT));
1097 
1099  false, NULL);
1100 
1102  ERR("IOCTL_MOUNTMGR_QUERY_POINTS 1 returned %08lx\n", Status);
1103  else if (mmps.Size > 0) {
1104  MOUNTMGR_MOUNT_POINTS* mmps2;
1105 
1107  if (!mmps2) {
1108  ERR("out of memory\n");
1109  break;
1110  }
1111 
1113  false, NULL);
1114  if (!NT_SUCCESS(Status))
1115  ERR("IOCTL_MOUNTMGR_QUERY_POINTS returned %08lx\n", Status);
1116  else
1117  mountmgr_updated(mountmgr, mmps2);
1118 
1119  ExFreePool(mmps2);
1120  }
1121  }
1122 
1124 
1126 
1128 }
DEVICE_TYPE DeviceType
Definition: ntddstor.h:324
void add_volume_device(superblock *sb, PUNICODE_STRING devpath, uint64_t length, ULONG disk_num, ULONG part_num)
Definition: volume.c:1077
GLenum func
Definition: glext.h:6028
_In_ PVOID NotificationStructure
Definition: iofuncs.h:1206
bool boot_volume
Definition: btrfs_drv.h:866
#define hex_digit(c)
Definition: btrfs_drv.h:1748
static PIO_STATUS_BLOCK iosb
Definition: file.c:98
PDEVICE_OBJECT buspdo
Definition: btrfs_drv.h:848
UNICODE_STRING pnp_name
Definition: btrfs_drv.h:859
const GUID GUID_DEVICE_INTERFACE_ARRIVAL
Definition: deviface.c:14
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
_Function_class_(IO_WORKITEM_ROUTINE)
Definition: search.c:146
static bool test_vol(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, PUNICODE_STRING devpath, DWORD disk_num, DWORD part_num, uint64_t length, bool fve_callback)
Definition: search.c:311
#define _Inout_
Definition: ms_sal.h:378
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
PDEVICE_OBJECT devobj
Definition: search.c:56
struct _FILE_OBJECT * FileObject
Definition: iotypes.h:1021
USHORT MaximumLength
Definition: env_spec_w32.h:370
LIST_ENTRY list_entry
Definition: search.c:55
Definition: http.c:7251
#define TRUE
Definition: types.h:120
superblock * sb
Definition: btrfs.c:4261
GLsizei const GLchar ** path
Definition: glext.h:7234
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
struct _MOUNTMGR_MOUNT_POINT MOUNTMGR_MOUNT_POINT
void volume_removal(PUNICODE_STRING devpath)
Definition: search.c:795
static void volume_arrival2(PUNICODE_STRING devpath)
Definition: search.c:791
unsigned char * PUCHAR
Definition: retypes.h:3
static void enqueue_pnp_callback(PUNICODE_STRING name, pnp_callback func)
Definition: search.c:874
#define WARN(fmt,...)
Definition: debug.h:112
LONG NTSTATUS
Definition: precomp.h:26
static const WCHAR device_name[]
Definition: btrfs.c:60
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
LIST_ENTRY pdo_list
Definition: btrfs.c:104
u32_t magic(void)
NTSTATUS NTAPI ExDeleteResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1456
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
KIRQL irql
Definition: wave.h:1
ULONG BytesPerSector
Definition: ntdddisk.h:409
ULONG part_num
Definition: btrfs_drv.h:865
#define InsertTailList(ListHead, Entry)
#define _Requires_exclusive_lock_held_(lock)
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
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
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
bool shutting_down
Definition: btrfs.c:109
#define MOUNTMGR_DEVICE_NAME
Definition: imports.h:76
UNICODE_STRING devpath
Definition: search.c:58
NTSTATUS mountmgr_add_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
Definition: volume.c:832
static void mountmgr_updated(PDEVICE_OBJECT mountmgr, MOUNTMGR_MOUNT_POINTS *mmps)
Definition: search.c:1014
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
#define _Releases_exclusive_lock_(lock)
bool check_superblock_checksum(superblock *sb)
Definition: btrfs.c:2825
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define ALLOC_TAG
Definition: btrfs_drv.h:87
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IOCTL_MOUNTMGR_QUERY_POINTS
Definition: mountmgr.h:30
NTSTATUS pnp_surprise_removal(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pnp.c:77
#define L(x)
Definition: ntvdm.h:50
KEVENT mountmgr_thread_event
Definition: btrfs.c:108
_In_ PIRP Irp
Definition: csq.h:116
Definition: devices.h:37
PIO_WORKITEM work_item
Definition: search.c:139
ERESOURCE boot_lock
Definition: btrfs.c:110
uint32_t no_pnp
Definition: btrfs.c:87
ERESOURCE pdo_list_lock
Definition: btrfs.c:103
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define offsetof(TYPE, MEMBER)
PDEVICE_OBJECT devobj
Definition: btrfs_drv.h:857
#define IOCTL_VOLUME_ONLINE
Definition: ntddvol.h:62
PDEVICE_OBJECT master_devobj
Definition: btrfs.c:66
#define _In_
Definition: ms_sal.h:308
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:143
#define UNUSED(x)
Definition: btrfs_drv.h:82
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
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
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
USHORT DeviceNameLength
Definition: imports.h:171
#define IOCTL_MOUNTMGR_CHANGE_NOTIFY
Definition: mountmgr.h:42
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
Status
Definition: gdiplustypes.h:24
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
void remove_volume_child(_Inout_ _Requires_exclusive_lock_held_(_Curr_->child_lock) _Releases_exclusive_lock_(_Curr_->child_lock) _In_ volume_device_extension *vde, _In_ volume_child *vc, _In_ bool skip_dev)
Definition: search.c:531
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define STATUS_NOT_FOUND
Definition: shellext.h:72
void * notification_entry
Definition: search.c:57
uint64_t children_loaded
Definition: btrfs_drv.h:895
HANDLE mountmgr_thread_handle
Definition: btrfs.c:106
#define TRACE(s)
Definition: solgame.cpp:4
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR Name[1]
Definition: imports.h:144
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
NTSTATUS remove_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
Definition: search.c:407
PFILE_OBJECT fileobj
Definition: search.c:140
NTSTATUS dev_ioctl(_In_ PDEVICE_OBJECT DeviceObject, _In_ ULONG ControlCode, _In_reads_bytes_opt_(InputBufferSize) PVOID InputBuffer, _In_ ULONG InputBufferSize, _Out_writes_bytes_opt_(OutputBufferSize) PVOID OutputBuffer, _In_ ULONG OutputBufferSize, _In_ bool Override, _Out_opt_ IO_STATUS_BLOCK *iosb)
Definition: btrfs.c:2954
bool had_drive_letter
Definition: btrfs_drv.h:862
#define Vcb
Definition: cdprocs.h:1415
#define ObDereferenceObject
Definition: obfuncs.h:203
LIST_ENTRY list_entry
Definition: btrfs_drv.h:899
static LIST_ENTRY fve_data_list
Definition: search.c:62
unsigned long DWORD
Definition: ntddk_ex.h:95
static bool fs_ignored(BTRFS_UUID *uuid)
Definition: search.c:65
#define __stdcall
Definition: typedefs.h:25
ERESOURCE child_lock
Definition: btrfs_drv.h:896
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
tIoUnregisterPlugPlayNotificationEx fIoUnregisterPlugPlayNotificationEx
Definition: btrfs.c:95
* PFILE_OBJECT
Definition: iotypes.h:1998
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
ULONG disk_num
Definition: btrfs_drv.h:864
_In_opt_ PVOID _In_ ULONG _In_ PVOID context
Definition: wdfdriver.h:113
uint64_t generation
Definition: btrfs.h:229
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
GLuint GLuint end
Definition: gl.h:1545
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS NTAPI IoUnregisterPlugPlayNotification(_In_ PVOID NotificationEntry)
Definition: pnpnotify.c:479
int ret
static void register_fve_callback(PDEVICE_OBJECT devobj, PFILE_OBJECT fileobj, PUNICODE_STRING devpath)
Definition: search.c:249
static NTSTATUS __stdcall event_notification(PVOID NotificationStructure, PVOID Context)
Definition: search.c:186
Definition: typedefs.h:119
bool volume_arrival(PUNICODE_STRING devpath, bool fve_callback)
Definition: search.c:693
pnp_callback func
Definition: search.c:854
BYTE uint8_t
Definition: msvideo1.c:66
UNICODE_STRING devpath
Definition: search.c:142
LARGE_INTEGER Length
Definition: winioctl.h:560
__u8 sector_size[2]
Definition: mkdosfs.c:361
static void mountmgr_process_drive(PDEVICE_OBJECT mountmgr, PUNICODE_STRING device_name)
Definition: search.c:942
NTSTATUS sync_read_phys(_In_ PDEVICE_OBJECT DeviceObject, _In_ PFILE_OBJECT FileObject, _In_ uint64_t StartingOffset, _In_ ULONG Length, _Out_writes_bytes_(Length) PUCHAR Buffer, _In_ bool override)
Definition: btrfs.c:2732
MOUNTMGR_MOUNT_POINT MountPoints[1]
Definition: imports.h:177
#define ERR(fmt,...)
Definition: debug.h:110
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
NTSTATUS(__stdcall * tIoUnregisterPlugPlayNotificationEx)(PVOID NotificationEntry)
Definition: btrfs_drv.h:1857
DEFINE_GUID(GUID_IO_VOLUME_FVE_STATUS_CHANGE, 0x062998b2, 0xee1f, 0x4b6a, 0xb8, 0x57, 0xe7, 0x6c, 0xbb, 0xe9, 0xa6, 0xda)
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:2342
UINT64 uint64_t
Definition: types.h:77
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define IOCTL_DISK_GET_DRIVE_LAYOUT_EX
Definition: ntddk_ex.h:207
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
PIO_WORKITEM work_item
Definition: search.c:855
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
BTRFS_UUID uuid
Definition: btrfs.h:225
const GUID GUID_DEVICE_INTERFACE_REMOVAL
Definition: deviface.c:15
void disk_arrival(PUNICODE_STRING devpath)
Definition: search.c:460
KSPIN_LOCK fve_data_lock
Definition: search.c:63
NTSTATUS NTAPI PsTerminateSystemThread(IN NTSTATUS ExitStatus)
Definition: kill.c:1148
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
UNICODE_STRING registry_path
Definition: btrfs.c:89
Definition: list.h:27
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
USHORT NameLength
Definition: imports.h:143
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
UINT32 uint32_t
Definition: types.h:75
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
volume_device_extension * vde
Definition: btrfs_drv.h:889
static ACCESS_MASK const OBJECT_ATTRIBUTES ULONG const UNICODE_STRING ULONG PULONG dispos
Definition: reg.c:130
Definition: name.c:38
static const uint64_t superblock_addrs[]
Definition: btrfs.h:16
struct tagContext Context
Definition: acpixf.h:1038
ULONG SymbolicLinkNameOffset
Definition: imports.h:166
ULONG ERESOURCE
Definition: env_spec_w32.h:594
Definition: msctf.idl:510
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSTATUS NTAPI IoRegisterPlugPlayNotification(_In_ IO_NOTIFICATION_EVENT_CATEGORY EventCategory, _In_ ULONG EventCategoryFlags, _In_opt_ PVOID EventCategoryData, _In_ PDRIVER_OBJECT DriverObject, _In_ PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine, _Inout_opt_ PVOID Context, _Out_ PVOID *NotificationEntry)
Definition: pnpnotify.c:345
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
PDEVICE_OBJECT devobj
Definition: search.c:141
PDRIVER_OBJECT drvobj
Definition: btrfs.c:65
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
LIST_ENTRY children
Definition: btrfs_drv.h:897
int remove
Definition: msacm.c:1365
UNICODE_STRING name
Definition: search.c:853
#define REG_DWORD
Definition: sdbapi.c:596
static uint64_t __inline sector_align(uint64_t n, uint64_t a)
void(* pnp_callback)(PUNICODE_STRING devpath)
Definition: search.c:43
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
#define d
Definition: ke_i.h:81
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define IOCTL_MOUNTMGR_DELETE_POINTS
Definition: imports.h:124
LONGLONG QuadPart
Definition: typedefs.h:114
PDEVICE_OBJECT busobj
Definition: btrfs.c:66
#define STATUS_FVE_LOCKED_VOLUME
Definition: ntstatus.h:1454
#define BTRFS_MAGIC
Definition: btrfs.h:42
GLuint const GLchar * name
Definition: glext.h:6031