ReactOS  0.4.15-dev-1367-g07cc0b5
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 %08lx\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", (int)(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 %08lx\n",
138  (int)(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 %Iu bytes, expected %Iu\n",
144  (int)(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", (int)(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 
168  TRACE("volume found\n");
169 
170  if (length >= superblock_addrs[1] + toread) {
171  ULONG i = 1;
172 
174  if (!sb2) {
175  ERR("out of memory\n");
176  goto deref;
177  }
178 
179  while (superblock_addrs[i] > 0 && length >= superblock_addrs[i] + toread) {
181 
182  if (NT_SUCCESS(Status) && sb2->magic == BTRFS_MAGIC) {
183  if (check_superblock_checksum(sb2) && sb2->generation > sb->generation)
184  RtlCopyMemory(sb, sb2, toread);
185  }
186 
187  i++;
188  }
189 
190  ExFreePool(sb2);
191  }
192 
193  if (!fs_ignored(&sb->uuid)) {
194  DeviceObject->Flags &= ~DO_VERIFY_VOLUME;
195  add_volume_device(sb, devpath, length, disk_num, part_num);
196  }
197  }
198  }
199 
200 deref:
201  if (data)
202  ExFreePool(data);
203 }
204 
208  ULONG mmpsize;
209  MOUNTMGR_MOUNT_POINTS mmps1, *mmps2;
210 
211  TRACE("removing drive letter\n");
212 
213  mmpsize = sizeof(MOUNTMGR_MOUNT_POINT) + devpath->Length;
214 
215  mmp = ExAllocatePoolWithTag(PagedPool, mmpsize, ALLOC_TAG);
216  if (!mmp) {
217  ERR("out of memory\n");
219  }
220 
221  RtlZeroMemory(mmp, mmpsize);
222 
223  mmp->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
224  mmp->DeviceNameLength = devpath->Length;
225  RtlCopyMemory(&mmp[1], devpath->Buffer, devpath->Length);
226 
227  Status = dev_ioctl(mountmgr, IOCTL_MOUNTMGR_DELETE_POINTS, mmp, mmpsize, &mmps1, sizeof(MOUNTMGR_MOUNT_POINTS), false, NULL);
228 
230  ERR("IOCTL_MOUNTMGR_DELETE_POINTS 1 returned %08lx\n", Status);
231  ExFreePool(mmp);
232  return Status;
233  }
234 
235  if (Status != STATUS_BUFFER_OVERFLOW || mmps1.Size == 0) {
236  ExFreePool(mmp);
237  return STATUS_NOT_FOUND;
238  }
239 
241  if (!mmps2) {
242  ERR("out of memory\n");
243  ExFreePool(mmp);
245  }
246 
247  Status = dev_ioctl(mountmgr, IOCTL_MOUNTMGR_DELETE_POINTS, mmp, mmpsize, mmps2, mmps1.Size, false, NULL);
248 
249  if (!NT_SUCCESS(Status))
250  ERR("IOCTL_MOUNTMGR_DELETE_POINTS 2 returned %08lx\n", Status);
251 
252  ExFreePool(mmps2);
253  ExFreePool(mmp);
254 
255  return Status;
256 }
257 
259  PFILE_OBJECT fileobj;
260  PDEVICE_OBJECT devobj;
263  ULONG dlisize;
267 
269 
271 
272  Status = IoGetDeviceObjectPointer(devpath, FILE_READ_ATTRIBUTES, &fileobj, &devobj);
273  if (!NT_SUCCESS(Status)) {
275  ERR("IoGetDeviceObjectPointer returned %08lx\n", Status);
276  return;
277  }
278 
279  dlisize = 0;
280 
281  do {
282  dlisize += 1024;
283 
284  if (dli)
285  ExFreePool(dli);
286 
287  dli = ExAllocatePoolWithTag(PagedPool, dlisize, ALLOC_TAG);
288  if (!dli) {
289  ERR("out of memory\n");
290  goto end;
291  }
292 
294  dli, dlisize, true, &iosb);
295  } while (Status == STATUS_BUFFER_TOO_SMALL);
296 
297  // only consider disk as a potential filesystem if it has no partitions
298  if (NT_SUCCESS(Status) && dli->PartitionCount > 0) {
299  ExFreePool(dli);
300  goto end;
301  }
302 
303  ExFreePool(dli);
304 
306  &gli, sizeof(gli), true, NULL);
307 
308  if (!NT_SUCCESS(Status)) {
309  ERR("error reading length information: %08lx\n", Status);
310  goto end;
311  }
312 
314  &sdn, sizeof(STORAGE_DEVICE_NUMBER), true, NULL);
315  if (!NT_SUCCESS(Status)) {
316  TRACE("IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08lx\n", Status);
317  sdn.DeviceNumber = 0xffffffff;
318  sdn.PartitionNumber = 0;
319  } else
320  TRACE("DeviceType = %lu, DeviceNumber = %lu, PartitionNumber = %lu\n", sdn.DeviceType, sdn.DeviceNumber, sdn.PartitionNumber);
321 
322  test_vol(devobj, fileobj, devpath, sdn.DeviceNumber, sdn.PartitionNumber, gli.Length.QuadPart);
323 
324 end:
325  ObDereferenceObject(fileobj);
326 
328 }
329 
331  _In_ volume_child* vc, _In_ bool skip_dev) {
333  pdo_device_extension* pdode = vde->pdode;
334  device_extension* Vcb = vde->mounted_device ? vde->mounted_device->DeviceExtension : NULL;
335 
336  if (vc->notification_entry) {
338  fIoUnregisterPlugPlayNotificationEx(vc->notification_entry);
339  else
340  IoUnregisterPlugPlayNotification(vc->notification_entry);
341  }
342 
343  if (vde->mounted_device && (!Vcb || !Vcb->options.allow_degraded)) {
344  Status = pnp_surprise_removal(vde->mounted_device, NULL);
345  if (!NT_SUCCESS(Status))
346  ERR("pnp_surprise_removal returned %08lx\n", Status);
347  }
348 
349  if (!Vcb || !Vcb->options.allow_degraded) {
350  Status = IoSetDeviceInterfaceState(&vde->bus_name, false);
351  if (!NT_SUCCESS(Status))
352  WARN("IoSetDeviceInterfaceState returned %08lx\n", Status);
353  }
354 
355  if (pdode->children_loaded > 0) {
356  UNICODE_STRING mmdevpath;
359  LIST_ENTRY* le;
360 
361  if (!Vcb || !Vcb->options.allow_degraded) {
364  if (!NT_SUCCESS(Status))
365  ERR("IoGetDeviceObjectPointer returned %08lx\n", Status);
366  else {
367  le = pdode->children.Flink;
368 
369  while (le != &pdode->children) {
371 
372  if (vc2->had_drive_letter) { // re-add entry to mountmgr
373  MOUNTDEV_NAME mdn;
374 
377  ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status);
378  else {
379  MOUNTDEV_NAME* mdn2;
380  ULONG mdnsize = (ULONG)offsetof(MOUNTDEV_NAME, Name[0]) + mdn.NameLength;
381 
382  mdn2 = ExAllocatePoolWithTag(PagedPool, mdnsize, ALLOC_TAG);
383  if (!mdn2)
384  ERR("out of memory\n");
385  else {
386  Status = dev_ioctl(vc2->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, mdn2, mdnsize, true, NULL);
387  if (!NT_SUCCESS(Status))
388  ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status);
389  else {
391 
392  name.Buffer = mdn2->Name;
393  name.Length = name.MaximumLength = mdn2->NameLength;
394 
396  if (!NT_SUCCESS(Status))
397  WARN("mountmgr_add_drive_letter returned %08lx\n", Status);
398  }
399 
400  ExFreePool(mdn2);
401  }
402  }
403  }
404 
405  le = le->Flink;
406  }
407 
409  }
410  } else if (!skip_dev) {
411  ExAcquireResourceExclusiveLite(&Vcb->tree_lock, true);
412 
413  le = Vcb->devices.Flink;
414  while (le != &Vcb->devices) {
416 
417  if (dev->devobj == vc->devobj) {
418  dev->devobj = NULL; // mark as missing
419  break;
420  }
421 
422  le = le->Flink;
423  }
424 
425  ExReleaseResourceLite(&Vcb->tree_lock);
426  }
427 
428  if (vde->device->Characteristics & FILE_REMOVABLE_MEDIA) {
429  vde->device->Characteristics &= ~FILE_REMOVABLE_MEDIA;
430 
431  le = pdode->children.Flink;
432  while (le != &pdode->children) {
434 
435  if (vc2 != vc && vc2->devobj->Characteristics & FILE_REMOVABLE_MEDIA) {
436  vde->device->Characteristics |= FILE_REMOVABLE_MEDIA;
437  break;
438  }
439 
440  le = le->Flink;
441  }
442  }
443  }
444 
445  ObDereferenceObject(vc->fileobj);
446  ExFreePool(vc->pnp_name.Buffer);
447  RemoveEntryList(&vc->list_entry);
448  ExFreePool(vc);
449 
450  pdode->children_loaded--;
451 
452  if (pdode->children_loaded == 0) { // remove volume device
453  bool remove = false;
454 
455  RemoveEntryList(&pdode->list_entry);
456 
457  vde->removing = true;
458 
459  Status = IoSetDeviceInterfaceState(&vde->bus_name, false);
460  if (!NT_SUCCESS(Status))
461  WARN("IoSetDeviceInterfaceState returned %08lx\n", Status);
462 
463  if (vde->pdo->AttachedDevice)
464  IoDetachDevice(vde->pdo);
465 
466  if (vde->open_count == 0)
467  remove = true;
468 
470 
471  if (!no_pnp) {
473 
475  }
476 
477  if (remove) {
478  if (vde->name.Buffer)
479  ExFreePool(vde->name.Buffer);
480 
481  if (Vcb)
482  Vcb->vde = NULL;
483 
485 
486  IoDeleteDevice(vde->device);
487  }
488  } else
490 }
491 
494  PFILE_OBJECT fileobj;
495  PDEVICE_OBJECT devobj;
498 
499  TRACE("%.*S\n", (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer);
500 
502 
503  Status = IoGetDeviceObjectPointer(devpath, FILE_READ_ATTRIBUTES, &fileobj, &devobj);
504  if (!NT_SUCCESS(Status)) {
506  ERR("IoGetDeviceObjectPointer returned %08lx\n", Status);
507  return;
508  }
509 
510  // make sure we're not processing devices we've created ourselves
511 
512  if (devobj->DriverObject == DriverObject)
513  goto end;
514 
515  Status = dev_ioctl(devobj, IOCTL_VOLUME_ONLINE, NULL, 0, NULL, 0, true, NULL);
516  if (!NT_SUCCESS(Status))
517  TRACE("IOCTL_VOLUME_ONLINE returned %08lx\n", Status);
518 
519  Status = dev_ioctl(devobj, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &gli, sizeof(gli), true, NULL);
520  if (!NT_SUCCESS(Status)) {
521  ERR("IOCTL_DISK_GET_LENGTH_INFO returned %08lx\n", Status);
522  goto end;
523  }
524 
526  &sdn, sizeof(STORAGE_DEVICE_NUMBER), true, NULL);
527  if (!NT_SUCCESS(Status)) {
528  TRACE("IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08lx\n", Status);
529  sdn.DeviceNumber = 0xffffffff;
530  sdn.PartitionNumber = 0;
531  } else
532  TRACE("DeviceType = %lu, DeviceNumber = %lu, PartitionNumber = %lu\n", sdn.DeviceType, sdn.DeviceNumber, sdn.PartitionNumber);
533 
534  // If we've just added a partition to a whole-disk filesystem, unmount it
535  if (sdn.DeviceNumber != 0xffffffff && sdn.PartitionNumber != 0) {
536  LIST_ENTRY* le;
537 
539 
540  le = pdo_list.Flink;
541  while (le != &pdo_list) {
543  LIST_ENTRY* le2;
544  bool changed = false;
545 
546  if (pdode->vde) {
548 
549  le2 = pdode->children.Flink;
550  while (le2 != &pdode->children) {
552  LIST_ENTRY* le3 = le2->Flink;
553 
554  if (vc->disk_num == sdn.DeviceNumber && vc->part_num == 0) {
555  TRACE("removing device\n");
556 
557  remove_volume_child(pdode->vde, vc, false);
558  changed = true;
559 
560  break;
561  }
562 
563  le2 = le3;
564  }
565 
566  if (!changed)
568  else
569  break;
570  }
571 
572  le = le->Flink;
573  }
574 
576  }
577 
578  test_vol(devobj, fileobj, devpath, sdn.DeviceNumber, sdn.PartitionNumber, gli.Length.QuadPart);
579 
580 end:
581  ObDereferenceObject(fileobj);
582 
584 }
585 
587  LIST_ENTRY* le;
588  UNICODE_STRING devpath2;
589 
590  TRACE("%.*S\n", (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer);
591 
593 
594  devpath2 = *devpath;
595 
596  if (devpath->Length > 4 * sizeof(WCHAR) && devpath->Buffer[0] == '\\' && (devpath->Buffer[1] == '\\' || devpath->Buffer[1] == '?') &&
597  devpath->Buffer[2] == '?' && devpath->Buffer[3] == '\\') {
598  devpath2.Buffer = &devpath2.Buffer[3];
599  devpath2.Length -= 3 * sizeof(WCHAR);
600  devpath2.MaximumLength -= 3 * sizeof(WCHAR);
601  }
602 
604 
605  le = pdo_list.Flink;
606  while (le != &pdo_list) {
608  LIST_ENTRY* le2;
609  bool changed = false;
610 
611  if (pdode->vde) {
613 
614  le2 = pdode->children.Flink;
615  while (le2 != &pdode->children) {
617  LIST_ENTRY* le3 = le2->Flink;
618 
619  if (vc->pnp_name.Length == devpath2.Length && RtlCompareMemory(vc->pnp_name.Buffer, devpath2.Buffer, devpath2.Length) == devpath2.Length) {
620  TRACE("removing device\n");
621 
622  if (!vc->boot_volume) {
623  remove_volume_child(pdode->vde, vc, false);
624  changed = true;
625  }
626 
627  break;
628  }
629 
630  le2 = le3;
631  }
632 
633  if (!changed)
635  else
636  break;
637  }
638 
639  le = le->Flink;
640  }
641 
643 }
644 
645 typedef struct {
651 
652 _Function_class_(IO_WORKITEM_ROUTINE)
653 static void __stdcall do_pnp_callback(PDEVICE_OBJECT DeviceObject, PVOID con) {
655 
657 
658  context->func(context->DriverObject, &context->name);
659 
660  if (context->name.Buffer)
661  ExFreePool(context->name.Buffer);
662 
663  IoFreeWorkItem(context->work_item);
664 
666 }
667 
669  PIO_WORKITEM work_item;
671 
672  work_item = IoAllocateWorkItem(master_devobj);
673  if (!work_item) {
674  ERR("out of memory\n");
675  return;
676  }
677 
679 
680  if (!context) {
681  ERR("out of memory\n");
682  IoFreeWorkItem(work_item);
683  return;
684  }
685 
686  context->DriverObject = DriverObject;
687 
688  if (name->Length > 0) {
689  context->name.Buffer = ExAllocatePoolWithTag(PagedPool, name->Length, ALLOC_TAG);
690  if (!context->name.Buffer) {
691  ERR("out of memory\n");
693  IoFreeWorkItem(work_item);
694  return;
695  }
696 
697  RtlCopyMemory(context->name.Buffer, name->Buffer, name->Length);
698  context->name.Length = context->name.MaximumLength = name->Length;
699  } else {
700  context->name.Length = context->name.MaximumLength = 0;
701  context->name.Buffer = NULL;
702  }
703 
704  context->func = func;
705  context->work_item = work_item;
706 
707  IoQueueWorkItem(work_item, do_pnp_callback, DelayedWorkQueue, context);
708 }
709 
710 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE)
714 
715  if (RtlCompareMemory(&dicn->Event, &GUID_DEVICE_INTERFACE_ARRIVAL, sizeof(GUID)) == sizeof(GUID))
717  else if (RtlCompareMemory(&dicn->Event, &GUID_DEVICE_INTERFACE_REMOVAL, sizeof(GUID)) == sizeof(GUID))
719 
720  return STATUS_SUCCESS;
721 }
722 
723 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE)
727 
728  if (RtlCompareMemory(&dicn->Event, &GUID_DEVICE_INTERFACE_ARRIVAL, sizeof(GUID)) == sizeof(GUID))
730  else if (RtlCompareMemory(&dicn->Event, &GUID_DEVICE_INTERFACE_REMOVAL, sizeof(GUID)) == sizeof(GUID))
732 
733  return STATUS_SUCCESS;
734 }
735 
738  LIST_ENTRY* le;
739  bool need_remove = false;
740  volume_child* vc2 = NULL;
741 
743 
744  le = pdo_list.Flink;
745  while (le != &pdo_list) {
747  LIST_ENTRY* le2;
748 
750 
751  le2 = pdode->children.Flink;
752 
753  while (le2 != &pdode->children) {
755 
756  if (vc->devobj) {
757  MOUNTDEV_NAME mdn;
758 
761  ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status);
762  else {
763  MOUNTDEV_NAME* mdn2;
764  ULONG mdnsize = (ULONG)offsetof(MOUNTDEV_NAME, Name[0]) + mdn.NameLength;
765 
766  mdn2 = ExAllocatePoolWithTag(NonPagedPool, mdnsize, ALLOC_TAG);
767  if (!mdn2)
768  ERR("out of memory\n");
769  else {
770  Status = dev_ioctl(vc->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, mdn2, mdnsize, true, NULL);
771  if (!NT_SUCCESS(Status))
772  ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status);
773  else {
774  if (mdn2->NameLength == device_name->Length && RtlCompareMemory(mdn2->Name, device_name->Buffer, device_name->Length) == device_name->Length) {
775  vc2 = vc;
776  need_remove = true;
777  break;
778  }
779  }
780 
781  ExFreePool(mdn2);
782  }
783  }
784  }
785 
786  le2 = le2->Flink;
787  }
788 
790 
791  if (need_remove)
792  break;
793 
794  le = le->Flink;
795  }
796 
798 
799  if (need_remove) {
801  if (!NT_SUCCESS(Status))
802  ERR("remove_drive_letter returned %08lx\n", Status);
803  else
804  vc2->had_drive_letter = true;
805  }
806 }
807 
809  ULONG i;
810 
811  static const WCHAR pref[] = L"\\DosDevices\\";
812 
813  for (i = 0; i < mmps->NumberOfMountPoints; i++) {
814  UNICODE_STRING symlink, device_name;
815 
816  if (mmps->MountPoints[i].SymbolicLinkNameOffset != 0) {
817  symlink.Buffer = (WCHAR*)(((uint8_t*)mmps) + mmps->MountPoints[i].SymbolicLinkNameOffset);
818  symlink.Length = symlink.MaximumLength = mmps->MountPoints[i].SymbolicLinkNameLength;
819  } else {
820  symlink.Buffer = NULL;
821  symlink.Length = symlink.MaximumLength = 0;
822  }
823 
824  if (mmps->MountPoints[i].DeviceNameOffset != 0) {
825  device_name.Buffer = (WCHAR*)(((uint8_t*)mmps) + mmps->MountPoints[i].DeviceNameOffset);
826  device_name.Length = device_name.MaximumLength = mmps->MountPoints[i].DeviceNameLength;
827  } else {
828  device_name.Buffer = NULL;
829  device_name.Length = device_name.MaximumLength = 0;
830  }
831 
832  if (symlink.Length > sizeof(pref) - sizeof(WCHAR) &&
833  RtlCompareMemory(symlink.Buffer, pref, sizeof(pref) - sizeof(WCHAR)) == sizeof(pref) - sizeof(WCHAR))
835  }
836 }
837 
838 _Function_class_(KSTART_ROUTINE)
839 void __stdcall mountmgr_thread(_In_ void* context) {
840  UNICODE_STRING mmdevpath;
845 
846  UNUSED(context);
847 
850  if (!NT_SUCCESS(Status)) {
851  ERR("IoGetDeviceObjectPointer returned %08lx\n", Status);
852  return;
853  }
854 
855  mcni.EpicNumber = 0;
856 
857  while (true) {
858  PIRP Irp;
862 
864 
866  &mcni, sizeof(MOUNTMGR_CHANGE_NOTIFY_INFO), false, &mountmgr_thread_event, &iosb);
867 
868  if (!Irp) {
869  ERR("out of memory\n");
870  break;
871  }
872 
874 
875  if (Status == STATUS_PENDING) {
877  Status = iosb.Status;
878  }
879 
880  if (shutting_down)
881  break;
882 
883  if (!NT_SUCCESS(Status)) {
884  ERR("IOCTL_MOUNTMGR_CHANGE_NOTIFY returned %08lx\n", Status);
885  break;
886  }
887 
888  TRACE("mountmgr changed\n");
889 
890  RtlZeroMemory(&mmp, sizeof(MOUNTMGR_MOUNT_POINT));
891 
893  false, NULL);
894 
896  ERR("IOCTL_MOUNTMGR_QUERY_POINTS 1 returned %08lx\n", Status);
897  else if (mmps.Size > 0) {
898  MOUNTMGR_MOUNT_POINTS* mmps2;
899 
901  if (!mmps2) {
902  ERR("out of memory\n");
903  break;
904  }
905 
907  false, NULL);
908  if (!NT_SUCCESS(Status))
909  ERR("IOCTL_MOUNTMGR_QUERY_POINTS returned %08lx\n", Status);
910  else
911  mountmgr_updated(mountmgr, mmps2);
912 
913  ExFreePool(mmps2);
914  }
915  }
916 
918 
920 
922 }
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:1162
GLenum func
Definition: glext.h:6028
_In_ PVOID NotificationStructure
Definition: iofuncs.h:1203
NTSTATUS NTAPI IoUnregisterPlugPlayNotification(IN PVOID NotificationEntry)
Definition: pnpnotify.c:371
bool boot_volume
Definition: btrfs_drv.h:874
#define hex_digit(c)
Definition: btrfs_drv.h:1794
static PIO_STATUS_BLOCK iosb
Definition: file.c:98
PDEVICE_OBJECT buspdo
Definition: btrfs_drv.h:856
UNICODE_STRING pnp_name
Definition: btrfs_drv.h:867
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:652
PDRIVER_OBJECT DriverObject
Definition: search.c:646
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: http.c:7094
#define TRUE
Definition: types.h:120
superblock * sb
Definition: btrfs.c:4220
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:112
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:63
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
LIST_ENTRY pdo_list
Definition: btrfs.c:109
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
ULONG BytesPerSector
Definition: ntdddisk.h:442
ULONG part_num
Definition: btrfs_drv.h:873
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:114
#define MOUNTMGR_DEVICE_NAME
Definition: imports.h:76
NTSTATUS mountmgr_add_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
Definition: volume.c:917
static void mountmgr_updated(PDEVICE_OBJECT mountmgr, MOUNTMGR_MOUNT_POINTS *mmps)
Definition: search.c:808
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
bool check_superblock_checksum(superblock *sb)
Definition: btrfs.c:2761
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
_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:254
KEVENT mountmgr_thread_event
Definition: btrfs.c:113
_In_ PIRP Irp
Definition: csq.h:116
Definition: devices.h:37
ERESOURCE boot_lock
Definition: btrfs.c:115
uint32_t no_pnp
Definition: btrfs.c:92
ERESOURCE pdo_list_lock
Definition: btrfs.c:108
#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)
void disk_arrival(PDRIVER_OBJECT DriverObject, PUNICODE_STRING devpath)
Definition: search.c:258
PDEVICE_OBJECT devobj
Definition: btrfs_drv.h:865
#define IOCTL_VOLUME_ONLINE
Definition: ntddvol.h:62
PDEVICE_OBJECT master_devobj
Definition: btrfs.c:69
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:143
#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
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
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#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:330
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define STATUS_NOT_FOUND
Definition: shellext.h:72
uint64_t children_loaded
Definition: btrfs_drv.h:903
HANDLE mountmgr_thread_handle
Definition: btrfs.c:111
#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:205
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:2888
bool had_drive_letter
Definition: btrfs_drv.h:870
#define Vcb
Definition: cdprocs.h:1415
#define ObDereferenceObject
Definition: obfuncs.h:203
LIST_ENTRY list_entry
Definition: btrfs_drv.h:907
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:162
ERESOURCE child_lock
Definition: btrfs_drv.h:904
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
tIoUnregisterPlugPlayNotificationEx fIoUnregisterPlugPlayNotificationEx
Definition: btrfs.c:100
* PFILE_OBJECT
Definition: iotypes.h:1978
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
ULONG disk_num
Definition: btrfs_drv.h:872
_In_opt_ PVOID _In_ ULONG _In_ PVOID context
Definition: wdfdriver.h:113
uint64_t generation
Definition: btrfs.h:222
#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
int ret
void volume_removal(PDRIVER_OBJECT DriverObject, PUNICODE_STRING devpath)
Definition: search.c:586
static const WCHAR L[]
Definition: oid.c:1250
Definition: typedefs.h:119
#define _Releases_exclusive_lock_(a)
Definition: btrfs_drv.h:209
pnp_callback func
Definition: search.c:648
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:736
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:2668
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
#define _In_
Definition: no_sal2.h:158
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
NTSTATUS(__stdcall * tIoUnregisterPlugPlayNotificationEx)(PVOID NotificationEntry)
Definition: btrfs_drv.h:1903
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:2486
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:649
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
BTRFS_UUID uuid
Definition: btrfs.h:218
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:668
NTSTATUS NTAPI PsTerminateSystemThread(IN NTSTATUS ExitStatus)
Definition: kill.c:1144
UNICODE_STRING registry_path
Definition: btrfs.c:94
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
#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
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:897
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:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
LIST_ENTRY children
Definition: btrfs_drv.h:905
int remove
Definition: msacm.c:1365
UNICODE_STRING name
Definition: search.c:647
#define REG_DWORD
Definition: sdbapi.c:596
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:492
LONGLONG QuadPart
Definition: typedefs.h:114
PDEVICE_OBJECT busobj
Definition: btrfs.c:69
#define BTRFS_MAGIC
Definition: btrfs.h:42
GLuint const GLchar * name
Definition: glext.h:6031