ReactOS  0.4.14-dev-552-g2fad488
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 
32 extern LIST_ENTRY pdo_list;
36 extern bool shutting_down;
37 extern PDEVICE_OBJECT busobj;
39 extern ERESOURCE boot_lock;
40 
42 
44 
45 static bool fs_ignored(BTRFS_UUID* uuid) {
46  UNICODE_STRING path, ignoreus;
50  ULONG dispos, retlen, kvfilen, i, j;
51  HANDLE h;
52  bool ret = false;
53 
54  path.Length = path.MaximumLength = registry_path.Length + (37 * sizeof(WCHAR));
55 
57  if (!path.Buffer) {
58  ERR("out of memory\n");
59  return false;
60  }
61 
63 
64  i = registry_path.Length / sizeof(WCHAR);
65 
66  path.Buffer[i] = '\\';
67  i++;
68 
69  for (j = 0; j < 16; j++) {
70  path.Buffer[i] = hex_digit((uuid->uuid[j] & 0xF0) >> 4);
71  path.Buffer[i+1] = hex_digit(uuid->uuid[j] & 0xF);
72 
73  i += 2;
74 
75  if (j == 3 || j == 5 || j == 7 || j == 9) {
76  path.Buffer[i] = '-';
77  i++;
78  }
79  }
80 
82 
83  Status = ZwCreateKey(&h, KEY_QUERY_VALUE, &oa, 0, NULL, REG_OPTION_NON_VOLATILE, &dispos);
84 
85  if (!NT_SUCCESS(Status)) {
86  TRACE("ZwCreateKey returned %08x\n", Status);
87  ExFreePool(path.Buffer);
88  return false;
89  }
90 
91  RtlInitUnicodeString(&ignoreus, L"Ignore");
92 
93  kvfilen = (ULONG)offsetof(KEY_VALUE_FULL_INFORMATION, Name[0]) + (255 * sizeof(WCHAR));
94  kvfi = ExAllocatePoolWithTag(PagedPool, kvfilen, ALLOC_TAG);
95  if (!kvfi) {
96  ERR("out of memory\n");
97  ZwClose(h);
98  ExFreePool(path.Buffer);
99  return false;
100  }
101 
102  Status = ZwQueryValueKey(h, &ignoreus, KeyValueFullInformation, kvfi, kvfilen, &retlen);
103  if (NT_SUCCESS(Status)) {
104  if (kvfi->Type == REG_DWORD && kvfi->DataLength >= sizeof(uint32_t)) {
105  uint32_t* pr = (uint32_t*)((uint8_t*)kvfi + kvfi->DataOffset);
106 
107  ret = *pr;
108  }
109  }
110 
111  ZwClose(h);
112  ExFreePool(kvfi);
113  ExFreePool(path.Buffer);
114 
115  return ret;
116 }
117 
119  PUNICODE_STRING devpath, DWORD disk_num, DWORD part_num, uint64_t length) {
121  ULONG toread;
122  uint8_t* data = NULL;
124 
125  TRACE("%.*S\n", devpath->Length / sizeof(WCHAR), devpath->Buffer);
126 
127  sector_size = DeviceObject->SectorSize;
128 
129  if (sector_size == 0) {
130  DISK_GEOMETRY geometry;
132 
134  &geometry, sizeof(DISK_GEOMETRY), true, &iosb);
135 
136  if (!NT_SUCCESS(Status)) {
137  ERR("%.*S had a sector size of 0, and IOCTL_DISK_GET_DRIVE_GEOMETRY returned %08x\n",
138  devpath->Length / sizeof(WCHAR), devpath->Buffer, Status);
139  goto deref;
140  }
141 
142  if (iosb.Information < sizeof(DISK_GEOMETRY)) {
143  ERR("%.*S: IOCTL_DISK_GET_DRIVE_GEOMETRY returned %u bytes, expected %u\n",
144  devpath->Length / sizeof(WCHAR), devpath->Buffer, iosb.Information, sizeof(DISK_GEOMETRY));
145  }
146 
147  sector_size = geometry.BytesPerSector;
148 
149  if (sector_size == 0) {
150  ERR("%.*S had a sector size of 0\n", devpath->Length / sizeof(WCHAR), devpath->Buffer);
151  goto deref;
152  }
153  }
154 
155  toread = (ULONG)sector_align(sizeof(superblock), sector_size);
157  if (!data) {
158  ERR("out of memory\n");
159  goto deref;
160  }
161 
163 
164  if (NT_SUCCESS(Status) && ((superblock*)data)->magic == BTRFS_MAGIC) {
166  uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum));
167 
168  if (crc32 != *((uint32_t*)sb->checksum))
169  ERR("checksum error on superblock\n");
170  else {
171  TRACE("volume found\n");
172 
173  if (length >= superblock_addrs[1] + toread) {
174  ULONG i = 1;
175 
177  if (!sb2) {
178  ERR("out of memory\n");
179  goto deref;
180  }
181 
182  while (superblock_addrs[i] > 0 && length >= superblock_addrs[i] + toread) {
184 
185  if (NT_SUCCESS(Status) && sb2->magic == BTRFS_MAGIC) {
186  crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb2->uuid, (ULONG)sizeof(superblock) - sizeof(sb2->checksum));
187 
188  if (crc32 == *((uint32_t*)sb2->checksum) && sb2->generation > sb->generation)
189  RtlCopyMemory(sb, sb2, toread);
190  }
191 
192  i++;
193  }
194 
195  ExFreePool(sb2);
196  }
197 
198  if (!fs_ignored(&sb->uuid)) {
200  add_volume_device(sb, devpath, length, disk_num, part_num);
201  }
202  }
203  }
204 
205 deref:
206  if (data)
207  ExFreePool(data);
208 }
209 
213  ULONG mmpsize;
214  MOUNTMGR_MOUNT_POINTS mmps1, *mmps2;
215 
216  TRACE("removing drive letter\n");
217 
218  mmpsize = sizeof(MOUNTMGR_MOUNT_POINT) + devpath->Length;
219 
220  mmp = ExAllocatePoolWithTag(PagedPool, mmpsize, ALLOC_TAG);
221  if (!mmp) {
222  ERR("out of memory\n");
224  }
225 
226  RtlZeroMemory(mmp, mmpsize);
227 
228  mmp->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
229  mmp->DeviceNameLength = devpath->Length;
230  RtlCopyMemory(&mmp[1], devpath->Buffer, devpath->Length);
231 
232  Status = dev_ioctl(mountmgr, IOCTL_MOUNTMGR_DELETE_POINTS, mmp, mmpsize, &mmps1, sizeof(MOUNTMGR_MOUNT_POINTS), false, NULL);
233 
235  ERR("IOCTL_MOUNTMGR_DELETE_POINTS 1 returned %08x\n", Status);
236  ExFreePool(mmp);
237  return Status;
238  }
239 
240  if (Status != STATUS_BUFFER_OVERFLOW || mmps1.Size == 0) {
241  ExFreePool(mmp);
242  return STATUS_NOT_FOUND;
243  }
244 
246  if (!mmps2) {
247  ERR("out of memory\n");
248  ExFreePool(mmp);
250  }
251 
252  Status = dev_ioctl(mountmgr, IOCTL_MOUNTMGR_DELETE_POINTS, mmp, mmpsize, mmps2, mmps1.Size, false, NULL);
253 
254  if (!NT_SUCCESS(Status))
255  ERR("IOCTL_MOUNTMGR_DELETE_POINTS 2 returned %08x\n", Status);
256 
257  ExFreePool(mmps2);
258  ExFreePool(mmp);
259 
260  return Status;
261 }
262 
264  PFILE_OBJECT fileobj;
265  PDEVICE_OBJECT devobj;
268  ULONG dlisize;
272 
274 
276 
277  Status = IoGetDeviceObjectPointer(devpath, FILE_READ_ATTRIBUTES, &fileobj, &devobj);
278  if (!NT_SUCCESS(Status)) {
280  ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
281  return;
282  }
283 
284  dlisize = 0;
285 
286  do {
287  dlisize += 1024;
288 
289  if (dli)
290  ExFreePool(dli);
291 
292  dli = ExAllocatePoolWithTag(PagedPool, dlisize, ALLOC_TAG);
293  if (!dli) {
294  ERR("out of memory\n");
295  goto end;
296  }
297 
299  dli, dlisize, true, &iosb);
300  } while (Status == STATUS_BUFFER_TOO_SMALL);
301 
302  // only consider disk as a potential filesystem if it has no partitions
303  if (NT_SUCCESS(Status) && dli->PartitionCount > 0) {
304  ExFreePool(dli);
305  goto end;
306  }
307 
308  ExFreePool(dli);
309 
311  &gli, sizeof(gli), true, NULL);
312 
313  if (!NT_SUCCESS(Status)) {
314  ERR("error reading length information: %08x\n", Status);
315  goto end;
316  }
317 
319  &sdn, sizeof(STORAGE_DEVICE_NUMBER), true, NULL);
320  if (!NT_SUCCESS(Status)) {
321  TRACE("IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08x\n", Status);
322  sdn.DeviceNumber = 0xffffffff;
323  sdn.PartitionNumber = 0;
324  } else
325  TRACE("DeviceType = %u, DeviceNumber = %u, PartitionNumber = %u\n", sdn.DeviceType, sdn.DeviceNumber, sdn.PartitionNumber);
326 
327  test_vol(devobj, fileobj, devpath, sdn.DeviceNumber, sdn.PartitionNumber, gli.Length.QuadPart);
328 
329 end:
330  ObDereferenceObject(fileobj);
331 
333 }
334 
336  _In_ volume_child* vc, _In_ bool skip_dev) {
338  pdo_device_extension* pdode = vde->pdode;
339  device_extension* Vcb = vde->mounted_device ? vde->mounted_device->DeviceExtension : NULL;
340 
341  if (vc->notification_entry) {
343  fIoUnregisterPlugPlayNotificationEx(vc->notification_entry);
344  else
345  IoUnregisterPlugPlayNotification(vc->notification_entry);
346  }
347 
348  if (vde->mounted_device && (!Vcb || !Vcb->options.allow_degraded)) {
349  Status = pnp_surprise_removal(vde->mounted_device, NULL);
350  if (!NT_SUCCESS(Status))
351  ERR("pnp_surprise_removal returned %08x\n", Status);
352  }
353 
354  if (!Vcb || !Vcb->options.allow_degraded) {
355  Status = IoSetDeviceInterfaceState(&vde->bus_name, false);
356  if (!NT_SUCCESS(Status))
357  WARN("IoSetDeviceInterfaceState returned %08x\n", Status);
358  }
359 
360  if (pdode->children_loaded > 0) {
361  UNICODE_STRING mmdevpath;
364  LIST_ENTRY* le;
365 
366  if (!Vcb || !Vcb->options.allow_degraded) {
369  if (!NT_SUCCESS(Status))
370  ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
371  else {
372  le = pdode->children.Flink;
373 
374  while (le != &pdode->children) {
376 
377  if (vc2->had_drive_letter) { // re-add entry to mountmgr
378  MOUNTDEV_NAME mdn;
379 
382  ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08x\n", Status);
383  else {
384  MOUNTDEV_NAME* mdn2;
385  ULONG mdnsize = (ULONG)offsetof(MOUNTDEV_NAME, Name[0]) + mdn.NameLength;
386 
387  mdn2 = ExAllocatePoolWithTag(PagedPool, mdnsize, ALLOC_TAG);
388  if (!mdn2)
389  ERR("out of memory\n");
390  else {
391  Status = dev_ioctl(vc2->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, mdn2, mdnsize, true, NULL);
392  if (!NT_SUCCESS(Status))
393  ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08x\n", Status);
394  else {
396 
397  name.Buffer = mdn2->Name;
398  name.Length = name.MaximumLength = mdn2->NameLength;
399 
401  if (!NT_SUCCESS(Status))
402  WARN("mountmgr_add_drive_letter returned %08x\n", Status);
403  }
404 
405  ExFreePool(mdn2);
406  }
407  }
408  }
409 
410  le = le->Flink;
411  }
412 
414  }
415  } else if (!skip_dev) {
416  ExAcquireResourceExclusiveLite(&Vcb->tree_lock, true);
417 
418  le = Vcb->devices.Flink;
419  while (le != &Vcb->devices) {
421 
422  if (dev->devobj == vc->devobj) {
423  dev->devobj = NULL; // mark as missing
424  break;
425  }
426 
427  le = le->Flink;
428  }
429 
430  ExReleaseResourceLite(&Vcb->tree_lock);
431  }
432 
433  if (vde->device->Characteristics & FILE_REMOVABLE_MEDIA) {
434  vde->device->Characteristics &= ~FILE_REMOVABLE_MEDIA;
435 
436  le = pdode->children.Flink;
437  while (le != &pdode->children) {
439 
440  if (vc2 != vc && vc2->devobj->Characteristics & FILE_REMOVABLE_MEDIA) {
441  vde->device->Characteristics |= FILE_REMOVABLE_MEDIA;
442  break;
443  }
444 
445  le = le->Flink;
446  }
447  }
448  }
449 
450  ObDereferenceObject(vc->fileobj);
451  ExFreePool(vc->pnp_name.Buffer);
452  RemoveEntryList(&vc->list_entry);
453  ExFreePool(vc);
454 
455  pdode->children_loaded--;
456 
457  if (pdode->children_loaded == 0) { // remove volume device
458  bool remove = false;
459 
460  RemoveEntryList(&pdode->list_entry);
461 
462  vde->removing = true;
463 
464  Status = IoSetDeviceInterfaceState(&vde->bus_name, false);
465  if (!NT_SUCCESS(Status))
466  WARN("IoSetDeviceInterfaceState returned %08x\n", Status);
467 
468  if (vde->pdo->AttachedDevice)
469  IoDetachDevice(vde->pdo);
470 
471  if (vde->open_count == 0)
472  remove = true;
473 
475 
476  if (!no_pnp) {
478 
480  }
481 
482  if (remove) {
483  if (vde->name.Buffer)
484  ExFreePool(vde->name.Buffer);
485 
486  if (Vcb)
487  Vcb->vde = NULL;
488 
490 
491  IoDeleteDevice(vde->device);
492  }
493  } else
495 }
496 
499  PFILE_OBJECT fileobj;
500  PDEVICE_OBJECT devobj;
503 
504  TRACE("%.*S\n", devpath->Length / sizeof(WCHAR), devpath->Buffer);
505 
507 
508  Status = IoGetDeviceObjectPointer(devpath, FILE_READ_ATTRIBUTES, &fileobj, &devobj);
509  if (!NT_SUCCESS(Status)) {
511  ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
512  return;
513  }
514 
515  // make sure we're not processing devices we've created ourselves
516 
517  if (devobj->DriverObject == DriverObject)
518  goto end;
519 
520  Status = dev_ioctl(devobj, IOCTL_VOLUME_ONLINE, NULL, 0, NULL, 0, true, NULL);
521  if (!NT_SUCCESS(Status))
522  TRACE("IOCTL_VOLUME_ONLINE returned %08x\n", Status);
523 
524  Status = dev_ioctl(devobj, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &gli, sizeof(gli), true, NULL);
525  if (!NT_SUCCESS(Status)) {
526  ERR("IOCTL_DISK_GET_LENGTH_INFO returned %08x\n", Status);
527  goto end;
528  }
529 
531  &sdn, sizeof(STORAGE_DEVICE_NUMBER), true, NULL);
532  if (!NT_SUCCESS(Status)) {
533  TRACE("IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08x\n", Status);
534  sdn.DeviceNumber = 0xffffffff;
535  sdn.PartitionNumber = 0;
536  } else
537  TRACE("DeviceType = %u, DeviceNumber = %u, PartitionNumber = %u\n", sdn.DeviceType, sdn.DeviceNumber, sdn.PartitionNumber);
538 
539  // If we've just added a partition to a whole-disk filesystem, unmount it
540  if (sdn.DeviceNumber != 0xffffffff && sdn.PartitionNumber != 0) {
541  LIST_ENTRY* le;
542 
544 
545  le = pdo_list.Flink;
546  while (le != &pdo_list) {
548  LIST_ENTRY* le2;
549  bool changed = false;
550 
551  if (pdode->vde) {
553 
554  le2 = pdode->children.Flink;
555  while (le2 != &pdode->children) {
557  LIST_ENTRY* le3 = le2->Flink;
558 
559  if (vc->disk_num == sdn.DeviceNumber && vc->part_num == 0) {
560  TRACE("removing device\n");
561 
562  remove_volume_child(pdode->vde, vc, false);
563  changed = true;
564 
565  break;
566  }
567 
568  le2 = le3;
569  }
570 
571  if (!changed)
573  else
574  break;
575  }
576 
577  le = le->Flink;
578  }
579 
581  }
582 
583  test_vol(devobj, fileobj, devpath, sdn.DeviceNumber, sdn.PartitionNumber, gli.Length.QuadPart);
584 
585 end:
586  ObDereferenceObject(fileobj);
587 
589 }
590 
592  LIST_ENTRY* le;
593  UNICODE_STRING devpath2;
594 
595  TRACE("%.*S\n", devpath->Length / sizeof(WCHAR), devpath->Buffer);
596 
598 
599  devpath2 = *devpath;
600 
601  if (devpath->Length > 4 * sizeof(WCHAR) && devpath->Buffer[0] == '\\' && (devpath->Buffer[1] == '\\' || devpath->Buffer[1] == '?') &&
602  devpath->Buffer[2] == '?' && devpath->Buffer[3] == '\\') {
603  devpath2.Buffer = &devpath2.Buffer[3];
604  devpath2.Length -= 3 * sizeof(WCHAR);
605  devpath2.MaximumLength -= 3 * sizeof(WCHAR);
606  }
607 
609 
610  le = pdo_list.Flink;
611  while (le != &pdo_list) {
613  LIST_ENTRY* le2;
614  bool changed = false;
615 
616  if (pdode->vde) {
618 
619  le2 = pdode->children.Flink;
620  while (le2 != &pdode->children) {
622  LIST_ENTRY* le3 = le2->Flink;
623 
624  if (vc->pnp_name.Length == devpath2.Length && RtlCompareMemory(vc->pnp_name.Buffer, devpath2.Buffer, devpath2.Length) == devpath2.Length) {
625  TRACE("removing device\n");
626 
627  remove_volume_child(pdode->vde, vc, false);
628  changed = true;
629 
630  break;
631  }
632 
633  le2 = le3;
634  }
635 
636  if (!changed)
638  else
639  break;
640  }
641 
642  le = le->Flink;
643  }
644 
646 }
647 
648 typedef struct {
654 
655 _Function_class_(IO_WORKITEM_ROUTINE)
656 static void __stdcall do_pnp_callback(PDEVICE_OBJECT DeviceObject, PVOID con) {
658 
660 
661  context->func(context->DriverObject, &context->name);
662 
663  if (context->name.Buffer)
664  ExFreePool(context->name.Buffer);
665 
666  IoFreeWorkItem(context->work_item);
667 
669 }
670 
672  PIO_WORKITEM work_item;
674 
675  work_item = IoAllocateWorkItem(master_devobj);
676  if (!work_item) {
677  ERR("out of memory\n");
678  return;
679  }
680 
682 
683  if (!context) {
684  ERR("out of memory\n");
685  IoFreeWorkItem(work_item);
686  return;
687  }
688 
689  context->DriverObject = DriverObject;
690 
691  if (name->Length > 0) {
692  context->name.Buffer = ExAllocatePoolWithTag(PagedPool, name->Length, ALLOC_TAG);
693  if (!context->name.Buffer) {
694  ERR("out of memory\n");
696  IoFreeWorkItem(work_item);
697  return;
698  }
699 
700  RtlCopyMemory(context->name.Buffer, name->Buffer, name->Length);
701  context->name.Length = context->name.MaximumLength = name->Length;
702  } else {
703  context->name.Length = context->name.MaximumLength = 0;
704  context->name.Buffer = NULL;
705  }
706 
707  context->func = func;
708  context->work_item = work_item;
709 
710  IoQueueWorkItem(work_item, do_pnp_callback, DelayedWorkQueue, context);
711 }
712 
713 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE)
717 
718  if (RtlCompareMemory(&dicn->Event, &GUID_DEVICE_INTERFACE_ARRIVAL, sizeof(GUID)) == sizeof(GUID))
720  else if (RtlCompareMemory(&dicn->Event, &GUID_DEVICE_INTERFACE_REMOVAL, sizeof(GUID)) == sizeof(GUID))
722 
723  return STATUS_SUCCESS;
724 }
725 
726 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE)
730 
731  if (RtlCompareMemory(&dicn->Event, &GUID_DEVICE_INTERFACE_ARRIVAL, sizeof(GUID)) == sizeof(GUID))
733  else if (RtlCompareMemory(&dicn->Event, &GUID_DEVICE_INTERFACE_REMOVAL, sizeof(GUID)) == sizeof(GUID))
735 
736  return STATUS_SUCCESS;
737 }
738 
741  LIST_ENTRY* le;
742  bool need_remove = false;
743  volume_child* vc2 = NULL;
744 
746 
747  le = pdo_list.Flink;
748  while (le != &pdo_list) {
750  LIST_ENTRY* le2;
751 
753 
754  le2 = pdode->children.Flink;
755 
756  while (le2 != &pdode->children) {
758 
759  if (vc->devobj) {
760  MOUNTDEV_NAME mdn;
761 
764  ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08x\n", Status);
765  else {
766  MOUNTDEV_NAME* mdn2;
767  ULONG mdnsize = (ULONG)offsetof(MOUNTDEV_NAME, Name[0]) + mdn.NameLength;
768 
769  mdn2 = ExAllocatePoolWithTag(NonPagedPool, mdnsize, ALLOC_TAG);
770  if (!mdn2)
771  ERR("out of memory\n");
772  else {
773  Status = dev_ioctl(vc->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, mdn2, mdnsize, true, NULL);
774  if (!NT_SUCCESS(Status))
775  ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08x\n", Status);
776  else {
777  if (mdn2->NameLength == device_name->Length && RtlCompareMemory(mdn2->Name, device_name->Buffer, device_name->Length) == device_name->Length) {
778  vc2 = vc;
779  need_remove = true;
780  break;
781  }
782  }
783 
784  ExFreePool(mdn2);
785  }
786  }
787  }
788 
789  le2 = le2->Flink;
790  }
791 
793 
794  if (need_remove)
795  break;
796 
797  le = le->Flink;
798  }
799 
801 
802  if (need_remove) {
804  if (!NT_SUCCESS(Status))
805  ERR("remove_drive_letter returned %08x\n", Status);
806  else
807  vc2->had_drive_letter = true;
808  }
809 }
810 
812  ULONG i;
813 
814  static const WCHAR pref[] = L"\\DosDevices\\";
815 
816  for (i = 0; i < mmps->NumberOfMountPoints; i++) {
817  UNICODE_STRING symlink, device_name;
818 
819  if (mmps->MountPoints[i].SymbolicLinkNameOffset != 0) {
820  symlink.Buffer = (WCHAR*)(((uint8_t*)mmps) + mmps->MountPoints[i].SymbolicLinkNameOffset);
821  symlink.Length = symlink.MaximumLength = mmps->MountPoints[i].SymbolicLinkNameLength;
822  } else {
823  symlink.Buffer = NULL;
824  symlink.Length = symlink.MaximumLength = 0;
825  }
826 
827  if (mmps->MountPoints[i].DeviceNameOffset != 0) {
828  device_name.Buffer = (WCHAR*)(((uint8_t*)mmps) + mmps->MountPoints[i].DeviceNameOffset);
829  device_name.Length = device_name.MaximumLength = mmps->MountPoints[i].DeviceNameLength;
830  } else {
831  device_name.Buffer = NULL;
832  device_name.Length = device_name.MaximumLength = 0;
833  }
834 
835  if (symlink.Length > sizeof(pref) - sizeof(WCHAR) &&
836  RtlCompareMemory(symlink.Buffer, pref, sizeof(pref) - sizeof(WCHAR)) == sizeof(pref) - sizeof(WCHAR))
838  }
839 }
840 
841 _Function_class_(KSTART_ROUTINE)
842 void __stdcall mountmgr_thread(_In_ void* context) {
843  UNICODE_STRING mmdevpath;
848 
849  UNUSED(context);
850 
853  if (!NT_SUCCESS(Status)) {
854  ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
855  return;
856  }
857 
858  mcni.EpicNumber = 0;
859 
860  while (true) {
861  PIRP Irp;
865 
867 
869  &mcni, sizeof(MOUNTMGR_CHANGE_NOTIFY_INFO), false, &mountmgr_thread_event, &iosb);
870 
871  if (!Irp) {
872  ERR("out of memory\n");
873  break;
874  }
875 
877 
878  if (Status == STATUS_PENDING) {
880  Status = iosb.Status;
881  }
882 
883  if (shutting_down)
884  break;
885 
886  if (!NT_SUCCESS(Status)) {
887  ERR("IOCTL_MOUNTMGR_CHANGE_NOTIFY returned %08x\n", Status);
888  break;
889  }
890 
891  TRACE("mountmgr changed\n");
892 
893  RtlZeroMemory(&mmp, sizeof(MOUNTMGR_MOUNT_POINT));
894 
896  false, NULL);
897 
899  ERR("IOCTL_MOUNTMGR_QUERY_POINTS 1 returned %08x\n", Status);
900  else if (mmps.Size > 0) {
901  MOUNTMGR_MOUNT_POINTS* mmps2;
902 
904  if (!mmps2) {
905  ERR("out of memory\n");
906  break;
907  }
908 
910  false, NULL);
911  if (!NT_SUCCESS(Status))
912  ERR("IOCTL_MOUNTMGR_QUERY_POINTS returned %08x\n", Status);
913  else
914  mountmgr_updated(mountmgr, mmps2);
915 
916  ExFreePool(mmps2);
917  }
918  }
919 
921 
923 
925 }
DEVICE_TYPE DeviceType
Definition: ntddstor.h:232
void add_volume_device(superblock *sb, PUNICODE_STRING devpath, uint64_t length, ULONG disk_num, ULONG part_num)
Definition: volume.c:1149
GLenum func
Definition: glext.h:6028
_In_ PVOID NotificationStructure
Definition: iofuncs.h:1203
NTSTATUS NTAPI IoUnregisterPlugPlayNotification(IN PVOID NotificationEntry)
Definition: pnpnotify.c:371
#define hex_digit(c)
Definition: btrfs_drv.h:1725
static PIO_STATUS_BLOCK iosb
Definition: file.c:98
PDEVICE_OBJECT buspdo
Definition: btrfs_drv.h:824
UNICODE_STRING pnp_name
Definition: btrfs_drv.h:835
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
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:655
PDRIVER_OBJECT DriverObject
Definition: search.c:649
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: http.c:6597
_In_ PIRP Irp
Definition: csq.h:116
superblock * sb
Definition: btrfs.c:4137
GLsizei const GLchar ** path
Definition: glext.h:7234
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
struct _MOUNTMGR_MOUNT_POINT MOUNTMGR_MOUNT_POINT
unsigned char * PUCHAR
Definition: retypes.h:3
#define WARN(fmt,...)
Definition: debug.h:111
void(* pnp_callback)(PDRIVER_OBJECT DriverObject, PUNICODE_STRING devpath)
Definition: search.c:41
LONG NTSTATUS
Definition: precomp.h:26
static const WCHAR device_name[]
Definition: btrfs.c:61
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
LIST_ENTRY pdo_list
Definition: btrfs.c:107
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
uint32_t crc32
Definition: btrfs.c:4138
ULONG BytesPerSector
Definition: ntdddisk.h:381
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
GLuint GLuint end
Definition: gl.h:1545
ULONG part_num
Definition: btrfs_drv.h:841
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
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
bool shutting_down
Definition: btrfs.c:112
static uint32_t calc_crc32c(uint32_t seed, uint8_t *msg, ULONG msglen)
Definition: recv.cpp:134
#define MOUNTMGR_DEVICE_NAME
Definition: imports.h:76
NTSTATUS mountmgr_add_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
Definition: volume.c:904
static void mountmgr_updated(PDEVICE_OBJECT mountmgr, MOUNTMGR_MOUNT_POINTS *mmps)
Definition: search.c:811
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
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:91
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
uint8_t checksum[32]
Definition: btrfs.h:208
#define IOCTL_MOUNTMGR_QUERY_POINTS
Definition: mountmgr.h:30
NTSTATUS pnp_surprise_removal(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pnp.c:254
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
KEVENT mountmgr_thread_event
Definition: btrfs.c:111
Definition: devices.h:37
ERESOURCE boot_lock
Definition: btrfs.c:113
uint32_t no_pnp
Definition: btrfs.c:90
ERESOURCE pdo_list_lock
Definition: btrfs.c:106
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define offsetof(TYPE, MEMBER)
void disk_arrival(PDRIVER_OBJECT DriverObject, PUNICODE_STRING devpath)
Definition: search.c:263
PDEVICE_OBJECT devobj
Definition: btrfs_drv.h:833
#define IOCTL_VOLUME_ONLINE
Definition: ntddvol.h:62
PDEVICE_OBJECT master_devobj
Definition: btrfs.c:67
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:132
#define UNUSED(x)
Definition: btrfs_drv.h:86
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
_Requires_exclusive_lock_held_(Vcb->tree_lock) static NTSTATUS add_root(_Inout_ device_extension *Vcb
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
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
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
#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:335
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define STATUS_NOT_FOUND
Definition: shellext.h:72
uint64_t children_loaded
Definition: btrfs_drv.h:870
HANDLE mountmgr_thread_handle
Definition: btrfs.c:109
#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
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
NTSTATUS remove_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
Definition: search.c:210
NTSTATUS dev_ioctl(_In_ PDEVICE_OBJECT DeviceObject, _In_ ULONG ControlCode, _In_reads_bytes_opt_(InputBufferSize) PVOID InputBuffer, _In_ ULONG InputBufferSize, _Out_writes_bytes_opt_(OutputBufferSize) PVOID OutputBuffer, _In_ ULONG OutputBufferSize, _In_ bool Override, _Out_opt_ IO_STATUS_BLOCK *iosb)
Definition: btrfs.c:2813
bool had_drive_letter
Definition: btrfs_drv.h:838
#define Vcb
Definition: cdprocs.h:1425
LIST_ENTRY list_entry
Definition: btrfs_drv.h:874
unsigned long DWORD
Definition: ntddk_ex.h:95
static bool fs_ignored(BTRFS_UUID *uuid)
Definition: search.c:45
#define __stdcall
Definition: typedefs.h:25
#define _Inout_
Definition: no_sal2.h:244
ERESOURCE child_lock
Definition: btrfs_drv.h:871
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
tIoUnregisterPlugPlayNotificationEx fIoUnregisterPlugPlayNotificationEx
Definition: btrfs.c:98
* PFILE_OBJECT
Definition: iotypes.h:1955
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
ULONG disk_num
Definition: btrfs_drv.h:840
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
uint64_t generation
Definition: btrfs.h:213
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
int ret
void volume_removal(PDRIVER_OBJECT DriverObject, PUNICODE_STRING devpath)
Definition: search.c:591
static const WCHAR L[]
Definition: oid.c:1250
Definition: typedefs.h:117
#define _Releases_exclusive_lock_(a)
Definition: btrfs_drv.h:196
pnp_callback func
Definition: search.c:651
BYTE uint8_t
Definition: msvideo1.c:66
LARGE_INTEGER Length
Definition: winioctl.h:423
__u8 sector_size[2]
Definition: mkdosfs.c:361
static void mountmgr_process_drive(PDEVICE_OBJECT mountmgr, PUNICODE_STRING device_name)
Definition: search.c:739
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:2644
Status
Definition: gdiplustypes.h:24
MOUNTMGR_MOUNT_POINT MountPoints[1]
Definition: imports.h:177
#define ERR(fmt,...)
Definition: debug.h:109
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
#define _In_
Definition: no_sal2.h:204
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
NTSTATUS(__stdcall * tIoUnregisterPlugPlayNotificationEx)(PVOID NotificationEntry)
Definition: btrfs_drv.h:1834
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:5111
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
PIO_WORKITEM work_item
Definition: search.c:652
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
BTRFS_UUID uuid
Definition: btrfs.h:209
const GUID GUID_DEVICE_INTERFACE_REMOVAL
Definition: deviface.c:15
static void enqueue_pnp_callback(PDRIVER_OBJECT DriverObject, PUNICODE_STRING name, pnp_callback func)
Definition: search.c:671
NTSTATUS NTAPI PsTerminateSystemThread(IN NTSTATUS ExitStatus)
Definition: kill.c:1144
UNICODE_STRING registry_path
Definition: btrfs.c:92
Definition: list.h:27
static void test_vol(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, PUNICODE_STRING devpath, DWORD disk_num, DWORD part_num, uint64_t length)
Definition: search.c:118
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
USHORT NameLength
Definition: imports.h:143
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:864
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:13
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:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
LIST_ENTRY children
Definition: btrfs_drv.h:872
int remove
Definition: msacm.c:1365
return STATUS_SUCCESS
Definition: btrfs.c:2938
UNICODE_STRING name
Definition: search.c:650
#define REG_DWORD
Definition: sdbapi.c:596
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
static uint64_t __inline sector_align(uint64_t n, uint64_t a)
struct _DRIVER_OBJECT * PDRIVER_OBJECT
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define IOCTL_MOUNTMGR_DELETE_POINTS
Definition: imports.h:124
void volume_arrival(PDRIVER_OBJECT DriverObject, PUNICODE_STRING devpath)
Definition: search.c:497
LONGLONG QuadPart
Definition: typedefs.h:112
PDEVICE_OBJECT busobj
Definition: btrfs.c:67
#define BTRFS_MAGIC
Definition: btrfs.h:42
GLuint const GLchar * name
Definition: glext.h:6031