ReactOS  0.4.14-dev-49-gfb4591c
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 
27 #include <initguid.h>
28 #include <wdmguid.h>
29 
31 extern LIST_ENTRY pdo_list;
35 extern bool shutting_down;
36 extern PDEVICE_OBJECT busobj;
38 
40 
42 
43 static bool fs_ignored(BTRFS_UUID* uuid) {
44  UNICODE_STRING path, ignoreus;
48  ULONG dispos, retlen, kvfilen, i, j;
49  HANDLE h;
50  bool ret = false;
51 
52  path.Length = path.MaximumLength = registry_path.Length + (37 * sizeof(WCHAR));
53 
55  if (!path.Buffer) {
56  ERR("out of memory\n");
57  return false;
58  }
59 
61 
62  i = registry_path.Length / sizeof(WCHAR);
63 
64  path.Buffer[i] = '\\';
65  i++;
66 
67  for (j = 0; j < 16; j++) {
68  path.Buffer[i] = hex_digit((uuid->uuid[j] & 0xF0) >> 4);
69  path.Buffer[i+1] = hex_digit(uuid->uuid[j] & 0xF);
70 
71  i += 2;
72 
73  if (j == 3 || j == 5 || j == 7 || j == 9) {
74  path.Buffer[i] = '-';
75  i++;
76  }
77  }
78 
80 
81  Status = ZwCreateKey(&h, KEY_QUERY_VALUE, &oa, 0, NULL, REG_OPTION_NON_VOLATILE, &dispos);
82 
83  if (!NT_SUCCESS(Status)) {
84  TRACE("ZwCreateKey returned %08x\n", Status);
85  ExFreePool(path.Buffer);
86  return false;
87  }
88 
89  RtlInitUnicodeString(&ignoreus, L"Ignore");
90 
91  kvfilen = (ULONG)offsetof(KEY_VALUE_FULL_INFORMATION, Name[0]) + (255 * sizeof(WCHAR));
92  kvfi = ExAllocatePoolWithTag(PagedPool, kvfilen, ALLOC_TAG);
93  if (!kvfi) {
94  ERR("out of memory\n");
95  ZwClose(h);
96  ExFreePool(path.Buffer);
97  return false;
98  }
99 
100  Status = ZwQueryValueKey(h, &ignoreus, KeyValueFullInformation, kvfi, kvfilen, &retlen);
101  if (NT_SUCCESS(Status)) {
102  if (kvfi->Type == REG_DWORD && kvfi->DataLength >= sizeof(uint32_t)) {
103  uint32_t* pr = (uint32_t*)((uint8_t*)kvfi + kvfi->DataOffset);
104 
105  ret = *pr;
106  }
107  }
108 
109  ZwClose(h);
110  ExFreePool(kvfi);
111  ExFreePool(path.Buffer);
112 
113  return ret;
114 }
115 
117  PUNICODE_STRING devpath, DWORD disk_num, DWORD part_num, uint64_t length) {
119  ULONG toread;
120  uint8_t* data = NULL;
122 
123  TRACE("%.*S\n", devpath->Length / sizeof(WCHAR), devpath->Buffer);
124 
125  sector_size = DeviceObject->SectorSize;
126 
127  if (sector_size == 0) {
128  DISK_GEOMETRY geometry;
130 
132  &geometry, sizeof(DISK_GEOMETRY), true, &iosb);
133 
134  if (!NT_SUCCESS(Status)) {
135  ERR("%.*S had a sector size of 0, and IOCTL_DISK_GET_DRIVE_GEOMETRY returned %08x\n",
136  devpath->Length / sizeof(WCHAR), devpath->Buffer, Status);
137  goto deref;
138  }
139 
140  if (iosb.Information < sizeof(DISK_GEOMETRY)) {
141  ERR("%.*S: IOCTL_DISK_GET_DRIVE_GEOMETRY returned %u bytes, expected %u\n",
142  devpath->Length / sizeof(WCHAR), devpath->Buffer, iosb.Information, sizeof(DISK_GEOMETRY));
143  }
144 
145  sector_size = geometry.BytesPerSector;
146 
147  if (sector_size == 0) {
148  ERR("%.*S had a sector size of 0\n", devpath->Length / sizeof(WCHAR), devpath->Buffer);
149  goto deref;
150  }
151  }
152 
153  toread = (ULONG)sector_align(sizeof(superblock), sector_size);
155  if (!data) {
156  ERR("out of memory\n");
157  goto deref;
158  }
159 
161 
162  if (NT_SUCCESS(Status) && ((superblock*)data)->magic == BTRFS_MAGIC) {
164  uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum));
165 
166  if (crc32 != *((uint32_t*)sb->checksum))
167  ERR("checksum error on superblock\n");
168  else {
169  TRACE("volume found\n");
170 
171  if (length >= superblock_addrs[1] + toread) {
172  ULONG i = 1;
173 
175  if (!sb2) {
176  ERR("out of memory\n");
177  goto deref;
178  }
179 
180  while (superblock_addrs[i] > 0 && length >= superblock_addrs[i] + toread) {
182 
183  if (NT_SUCCESS(Status) && sb2->magic == BTRFS_MAGIC) {
184  crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb2->uuid, (ULONG)sizeof(superblock) - sizeof(sb2->checksum));
185 
186  if (crc32 == *((uint32_t*)sb2->checksum) && sb2->generation > sb->generation)
187  RtlCopyMemory(sb, sb2, toread);
188  }
189 
190  i++;
191  }
192 
193  ExFreePool(sb2);
194  }
195 
196  if (!fs_ignored(&sb->uuid)) {
198  add_volume_device(sb, devpath, length, disk_num, part_num);
199  }
200  }
201  }
202 
203 deref:
204  if (data)
205  ExFreePool(data);
206 }
207 
211  ULONG mmpsize;
212  MOUNTMGR_MOUNT_POINTS mmps1, *mmps2;
213 
214  TRACE("removing drive letter\n");
215 
216  mmpsize = sizeof(MOUNTMGR_MOUNT_POINT) + devpath->Length;
217 
218  mmp = ExAllocatePoolWithTag(PagedPool, mmpsize, ALLOC_TAG);
219  if (!mmp) {
220  ERR("out of memory\n");
222  }
223 
224  RtlZeroMemory(mmp, mmpsize);
225 
226  mmp->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
227  mmp->DeviceNameLength = devpath->Length;
228  RtlCopyMemory(&mmp[1], devpath->Buffer, devpath->Length);
229 
230  Status = dev_ioctl(mountmgr, IOCTL_MOUNTMGR_DELETE_POINTS, mmp, mmpsize, &mmps1, sizeof(MOUNTMGR_MOUNT_POINTS), false, NULL);
231 
233  ERR("IOCTL_MOUNTMGR_DELETE_POINTS 1 returned %08x\n", Status);
234  ExFreePool(mmp);
235  return Status;
236  }
237 
238  if (Status != STATUS_BUFFER_OVERFLOW || mmps1.Size == 0) {
239  ExFreePool(mmp);
240  return STATUS_NOT_FOUND;
241  }
242 
244  if (!mmps2) {
245  ERR("out of memory\n");
246  ExFreePool(mmp);
248  }
249 
250  Status = dev_ioctl(mountmgr, IOCTL_MOUNTMGR_DELETE_POINTS, mmp, mmpsize, mmps2, mmps1.Size, false, NULL);
251 
252  if (!NT_SUCCESS(Status))
253  ERR("IOCTL_MOUNTMGR_DELETE_POINTS 2 returned %08x\n", Status);
254 
255  ExFreePool(mmps2);
256  ExFreePool(mmp);
257 
258  return Status;
259 }
260 
262  PFILE_OBJECT fileobj;
263  PDEVICE_OBJECT devobj;
266  ULONG dlisize;
270 
272 
273  Status = IoGetDeviceObjectPointer(devpath, FILE_READ_ATTRIBUTES, &fileobj, &devobj);
274  if (!NT_SUCCESS(Status)) {
275  ERR("IoGetDeviceObjectPointer returned %08x\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: %08x\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 %08x\n", Status);
317  sdn.DeviceNumber = 0xffffffff;
318  sdn.PartitionNumber = 0;
319  } else
320  TRACE("DeviceType = %u, DeviceNumber = %u, PartitionNumber = %u\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 }
327 
329  _In_ volume_child* vc, _In_ bool skip_dev) {
331  pdo_device_extension* pdode = vde->pdode;
332  device_extension* Vcb = vde->mounted_device ? vde->mounted_device->DeviceExtension : NULL;
333 
334  if (vc->notification_entry) {
336  fIoUnregisterPlugPlayNotificationEx(vc->notification_entry);
337  else
338  IoUnregisterPlugPlayNotification(vc->notification_entry);
339  }
340 
341  if (vde->mounted_device && (!Vcb || !Vcb->options.allow_degraded)) {
342  Status = pnp_surprise_removal(vde->mounted_device, NULL);
343  if (!NT_SUCCESS(Status))
344  ERR("pnp_surprise_removal returned %08x\n", Status);
345  }
346 
347  if (!Vcb || !Vcb->options.allow_degraded) {
348  Status = IoSetDeviceInterfaceState(&vde->bus_name, false);
349  if (!NT_SUCCESS(Status))
350  WARN("IoSetDeviceInterfaceState returned %08x\n", Status);
351  }
352 
353  if (pdode->children_loaded > 0) {
354  UNICODE_STRING mmdevpath;
356  PDEVICE_OBJECT mountmgr;
357  LIST_ENTRY* le;
358 
359  if (!Vcb || !Vcb->options.allow_degraded) {
362  if (!NT_SUCCESS(Status))
363  ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
364  else {
365  le = pdode->children.Flink;
366 
367  while (le != &pdode->children) {
369 
370  if (vc2->had_drive_letter) { // re-add entry to mountmgr
371  MOUNTDEV_NAME mdn;
372 
375  ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08x\n", Status);
376  else {
377  MOUNTDEV_NAME* mdn2;
378  ULONG mdnsize = (ULONG)offsetof(MOUNTDEV_NAME, Name[0]) + mdn.NameLength;
379 
380  mdn2 = ExAllocatePoolWithTag(PagedPool, mdnsize, ALLOC_TAG);
381  if (!mdn2)
382  ERR("out of memory\n");
383  else {
384  Status = dev_ioctl(vc2->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, mdn2, mdnsize, true, NULL);
385  if (!NT_SUCCESS(Status))
386  ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08x\n", Status);
387  else {
389 
390  name.Buffer = mdn2->Name;
391  name.Length = name.MaximumLength = mdn2->NameLength;
392 
393  Status = mountmgr_add_drive_letter(mountmgr, &name);
394  if (!NT_SUCCESS(Status))
395  WARN("mountmgr_add_drive_letter returned %08x\n", Status);
396  }
397 
398  ExFreePool(mdn2);
399  }
400  }
401  }
402 
403  le = le->Flink;
404  }
405 
407  }
408  } else if (!skip_dev) {
409  ExAcquireResourceExclusiveLite(&Vcb->tree_lock, true);
410 
411  le = Vcb->devices.Flink;
412  while (le != &Vcb->devices) {
414 
415  if (dev->devobj == vc->devobj) {
416  dev->devobj = NULL; // mark as missing
417  break;
418  }
419 
420  le = le->Flink;
421  }
422 
423  ExReleaseResourceLite(&Vcb->tree_lock);
424  }
425 
426  if (vde->device->Characteristics & FILE_REMOVABLE_MEDIA) {
427  vde->device->Characteristics &= ~FILE_REMOVABLE_MEDIA;
428 
429  le = pdode->children.Flink;
430  while (le != &pdode->children) {
432 
433  if (vc2 != vc && vc2->devobj->Characteristics & FILE_REMOVABLE_MEDIA) {
434  vde->device->Characteristics |= FILE_REMOVABLE_MEDIA;
435  break;
436  }
437 
438  le = le->Flink;
439  }
440  }
441  }
442 
443  ObDereferenceObject(vc->fileobj);
444  ExFreePool(vc->pnp_name.Buffer);
445  RemoveEntryList(&vc->list_entry);
446  ExFreePool(vc);
447 
448  pdode->children_loaded--;
449 
450  if (pdode->children_loaded == 0) { // remove volume device
451  bool remove = false;
452 
453  RemoveEntryList(&pdode->list_entry);
454 
455  vde->removing = true;
456 
457  Status = IoSetDeviceInterfaceState(&vde->bus_name, false);
458  if (!NT_SUCCESS(Status))
459  WARN("IoSetDeviceInterfaceState returned %08x\n", Status);
460 
461  if (vde->pdo->AttachedDevice)
462  IoDetachDevice(vde->pdo);
463 
464  if (vde->open_count == 0)
465  remove = true;
466 
468 
469  if (!no_pnp) {
471 
473  }
474 
475  if (remove) {
476  if (vde->name.Buffer)
477  ExFreePool(vde->name.Buffer);
478 
479  if (Vcb)
480  Vcb->vde = NULL;
481 
483 
484  IoDeleteDevice(vde->device);
485  }
486  } else
488 }
489 
492  PFILE_OBJECT fileobj;
493  PDEVICE_OBJECT devobj;
496 
497  TRACE("%.*S\n", devpath->Length / sizeof(WCHAR), devpath->Buffer);
498 
499  Status = IoGetDeviceObjectPointer(devpath, FILE_READ_ATTRIBUTES, &fileobj, &devobj);
500  if (!NT_SUCCESS(Status)) {
501  ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
502  return;
503  }
504 
505  // make sure we're not processing devices we've created ourselves
506 
507  if (devobj->DriverObject == DriverObject)
508  goto end;
509 
510  Status = dev_ioctl(devobj, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &gli, sizeof(gli), true, NULL);
511  if (!NT_SUCCESS(Status)) {
512  ERR("IOCTL_DISK_GET_LENGTH_INFO returned %08x\n", Status);
513  goto end;
514  }
515 
517  &sdn, sizeof(STORAGE_DEVICE_NUMBER), true, NULL);
518  if (!NT_SUCCESS(Status)) {
519  TRACE("IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08x\n", Status);
520  sdn.DeviceNumber = 0xffffffff;
521  sdn.PartitionNumber = 0;
522  } else
523  TRACE("DeviceType = %u, DeviceNumber = %u, PartitionNumber = %u\n", sdn.DeviceType, sdn.DeviceNumber, sdn.PartitionNumber);
524 
525  // If we've just added a partition to a whole-disk filesystem, unmount it
526  if (sdn.DeviceNumber != 0xffffffff && sdn.PartitionNumber != 0) {
527  LIST_ENTRY* le;
528 
530 
531  le = pdo_list.Flink;
532  while (le != &pdo_list) {
534  LIST_ENTRY* le2;
535  bool changed = false;
536 
537  if (pdode->vde) {
539 
540  le2 = pdode->children.Flink;
541  while (le2 != &pdode->children) {
543  LIST_ENTRY* le3 = le2->Flink;
544 
545  if (vc->disk_num == sdn.DeviceNumber && vc->part_num == 0) {
546  TRACE("removing device\n");
547 
548  remove_volume_child(pdode->vde, vc, false);
549  changed = true;
550 
551  break;
552  }
553 
554  le2 = le3;
555  }
556 
557  if (!changed)
559  else
560  break;
561  }
562 
563  le = le->Flink;
564  }
565 
567  }
568 
569  test_vol(devobj, fileobj, devpath, sdn.DeviceNumber, sdn.PartitionNumber, gli.Length.QuadPart);
570 
571 end:
572  ObDereferenceObject(fileobj);
573 }
574 
576  LIST_ENTRY* le;
577  UNICODE_STRING devpath2;
578 
579  TRACE("%.*S\n", devpath->Length / sizeof(WCHAR), devpath->Buffer);
580 
582 
583  devpath2 = *devpath;
584 
585  if (devpath->Length > 4 * sizeof(WCHAR) && devpath->Buffer[0] == '\\' && (devpath->Buffer[1] == '\\' || devpath->Buffer[1] == '?') &&
586  devpath->Buffer[2] == '?' && devpath->Buffer[3] == '\\') {
587  devpath2.Buffer = &devpath2.Buffer[3];
588  devpath2.Length -= 3 * sizeof(WCHAR);
589  devpath2.MaximumLength -= 3 * sizeof(WCHAR);
590  }
591 
593 
594  le = pdo_list.Flink;
595  while (le != &pdo_list) {
597  LIST_ENTRY* le2;
598  bool changed = false;
599 
600  if (pdode->vde) {
602 
603  le2 = pdode->children.Flink;
604  while (le2 != &pdode->children) {
606  LIST_ENTRY* le3 = le2->Flink;
607 
608  if (vc->pnp_name.Length == devpath2.Length && RtlCompareMemory(vc->pnp_name.Buffer, devpath2.Buffer, devpath2.Length) == devpath2.Length) {
609  TRACE("removing device\n");
610 
611  remove_volume_child(pdode->vde, vc, false);
612  changed = true;
613 
614  break;
615  }
616 
617  le2 = le3;
618  }
619 
620  if (!changed)
622  else
623  break;
624  }
625 
626  le = le->Flink;
627  }
628 
630 }
631 
632 typedef struct {
638 
639 _Function_class_(IO_WORKITEM_ROUTINE)
640 static void __stdcall do_pnp_callback(PDEVICE_OBJECT DeviceObject, PVOID con) {
642 
644 
645  context->func(context->DriverObject, &context->name);
646 
647  if (context->name.Buffer)
648  ExFreePool(context->name.Buffer);
649 
650  IoFreeWorkItem(context->work_item);
651 }
652 
654  PIO_WORKITEM work_item;
656 
657  work_item = IoAllocateWorkItem(master_devobj);
658 
660 
661  if (!context) {
662  ERR("out of memory\n");
663  IoFreeWorkItem(work_item);
664  return;
665  }
666 
667  context->DriverObject = DriverObject;
668 
669  if (name->Length > 0) {
670  context->name.Buffer = ExAllocatePoolWithTag(PagedPool, name->Length, ALLOC_TAG);
671  if (!context->name.Buffer) {
672  ERR("out of memory\n");
674  IoFreeWorkItem(work_item);
675  return;
676  }
677 
678  RtlCopyMemory(context->name.Buffer, name->Buffer, name->Length);
679  context->name.Length = context->name.MaximumLength = name->Length;
680  } else {
681  context->name.Length = context->name.MaximumLength = 0;
682  context->name.Buffer = NULL;
683  }
684 
685  context->func = func;
686  context->work_item = work_item;
687 
688  IoQueueWorkItem(work_item, do_pnp_callback, DelayedWorkQueue, context);
689 }
690 
691 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE)
695 
696  if (RtlCompareMemory(&dicn->Event, &GUID_DEVICE_INTERFACE_ARRIVAL, sizeof(GUID)) == sizeof(GUID))
698  else if (RtlCompareMemory(&dicn->Event, &GUID_DEVICE_INTERFACE_REMOVAL, sizeof(GUID)) == sizeof(GUID))
700 
701  return STATUS_SUCCESS;
702 }
703 
704 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE)
708 
709  if (RtlCompareMemory(&dicn->Event, &GUID_DEVICE_INTERFACE_ARRIVAL, sizeof(GUID)) == sizeof(GUID))
711  else if (RtlCompareMemory(&dicn->Event, &GUID_DEVICE_INTERFACE_REMOVAL, sizeof(GUID)) == sizeof(GUID))
713 
714  return STATUS_SUCCESS;
715 }
716 
719  LIST_ENTRY* le;
720  bool need_remove = false;
721  volume_child* vc2 = NULL;
722 
724 
725  le = pdo_list.Flink;
726  while (le != &pdo_list) {
728  LIST_ENTRY* le2;
729 
731 
732  le2 = pdode->children.Flink;
733 
734  while (le2 != &pdode->children) {
736 
737  if (vc->devobj) {
738  MOUNTDEV_NAME mdn;
739 
742  ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08x\n", Status);
743  else {
744  MOUNTDEV_NAME* mdn2;
745  ULONG mdnsize = (ULONG)offsetof(MOUNTDEV_NAME, Name[0]) + mdn.NameLength;
746 
747  mdn2 = ExAllocatePoolWithTag(NonPagedPool, mdnsize, ALLOC_TAG);
748  if (!mdn2)
749  ERR("out of memory\n");
750  else {
751  Status = dev_ioctl(vc->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, mdn2, mdnsize, true, NULL);
752  if (!NT_SUCCESS(Status))
753  ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08x\n", Status);
754  else {
755  if (mdn2->NameLength == device_name->Length && RtlCompareMemory(mdn2->Name, device_name->Buffer, device_name->Length) == device_name->Length) {
756  vc2 = vc;
757  need_remove = true;
758  break;
759  }
760  }
761 
762  ExFreePool(mdn2);
763  }
764  }
765  }
766 
767  le2 = le2->Flink;
768  }
769 
771 
772  if (need_remove)
773  break;
774 
775  le = le->Flink;
776  }
777 
779 
780  if (need_remove) {
782  if (!NT_SUCCESS(Status))
783  ERR("remove_drive_letter returned %08x\n", Status);
784  else
785  vc2->had_drive_letter = true;
786  }
787 }
788 
790  ULONG i;
791 
792  static const WCHAR pref[] = L"\\DosDevices\\";
793 
794  for (i = 0; i < mmps->NumberOfMountPoints; i++) {
795  UNICODE_STRING symlink, device_name;
796 
797  if (mmps->MountPoints[i].SymbolicLinkNameOffset != 0) {
798  symlink.Buffer = (WCHAR*)(((uint8_t*)mmps) + mmps->MountPoints[i].SymbolicLinkNameOffset);
799  symlink.Length = symlink.MaximumLength = mmps->MountPoints[i].SymbolicLinkNameLength;
800  } else {
801  symlink.Buffer = NULL;
802  symlink.Length = symlink.MaximumLength = 0;
803  }
804 
805  if (mmps->MountPoints[i].DeviceNameOffset != 0) {
806  device_name.Buffer = (WCHAR*)(((uint8_t*)mmps) + mmps->MountPoints[i].DeviceNameOffset);
807  device_name.Length = device_name.MaximumLength = mmps->MountPoints[i].DeviceNameLength;
808  } else {
809  device_name.Buffer = NULL;
810  device_name.Length = device_name.MaximumLength = 0;
811  }
812 
813  if (symlink.Length > sizeof(pref) - sizeof(WCHAR) &&
814  RtlCompareMemory(symlink.Buffer, pref, sizeof(pref) - sizeof(WCHAR)) == sizeof(pref) - sizeof(WCHAR))
816  }
817 }
818 
819 _Function_class_(KSTART_ROUTINE)
820 void __stdcall mountmgr_thread(_In_ void* context) {
821  UNICODE_STRING mmdevpath;
824  PDEVICE_OBJECT mountmgr;
826 
827  UNUSED(context);
828 
831  if (!NT_SUCCESS(Status)) {
832  ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
833  return;
834  }
835 
836  mcni.EpicNumber = 0;
837 
838  while (true) {
839  PIRP Irp;
843 
845 
847  &mcni, sizeof(MOUNTMGR_CHANGE_NOTIFY_INFO), false, &mountmgr_thread_event, &iosb);
848 
849  if (!Irp) {
850  ERR("out of memory\n");
851  break;
852  }
853 
854  Status = IoCallDriver(mountmgr, Irp);
855 
856  if (Status == STATUS_PENDING) {
858  Status = iosb.Status;
859  }
860 
861  if (shutting_down)
862  break;
863 
864  if (!NT_SUCCESS(Status)) {
865  ERR("IOCTL_MOUNTMGR_CHANGE_NOTIFY returned %08x\n", Status);
866  break;
867  }
868 
869  TRACE("mountmgr changed\n");
870 
871  RtlZeroMemory(&mmp, sizeof(MOUNTMGR_MOUNT_POINT));
872 
874  false, NULL);
875 
877  ERR("IOCTL_MOUNTMGR_QUERY_POINTS 1 returned %08x\n", Status);
878  else if (mmps.Size > 0) {
879  MOUNTMGR_MOUNT_POINTS* mmps2;
880 
882  if (!mmps2) {
883  ERR("out of memory\n");
884  break;
885  }
886 
887  Status = dev_ioctl(mountmgr, IOCTL_MOUNTMGR_QUERY_POINTS, &mmp, sizeof(MOUNTMGR_MOUNT_POINTS), mmps2, mmps.Size,
888  false, NULL);
889  if (!NT_SUCCESS(Status))
890  ERR("IOCTL_MOUNTMGR_QUERY_POINTS returned %08x\n", Status);
891  else
892  mountmgr_updated(mountmgr, mmps2);
893 
894  ExFreePool(mmps2);
895  }
896  }
897 
899 
901 
903 }
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:1105
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:1656
static PIO_STATUS_BLOCK iosb
Definition: file.c:98
NTSTATUS(* tIoUnregisterPlugPlayNotificationEx)(PVOID NotificationEntry)
Definition: btrfs_drv.h:1765
PDEVICE_OBJECT buspdo
Definition: btrfs_drv.h:816
UNICODE_STRING pnp_name
Definition: btrfs_drv.h:827
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:639
PDRIVER_OBJECT DriverObject
Definition: search.c:633
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: http.c:6587
_In_ PIRP Irp
Definition: csq.h:116
superblock * sb
Definition: btrfs.c:4162
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:39
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: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
uint32_t crc32
Definition: btrfs.c:4163
ULONG BytesPerSector
Definition: ntdddisk.h:376
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
GLuint GLuint end
Definition: gl.h:1545
ULONG part_num
Definition: btrfs_drv.h:833
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:109
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:881
static void mountmgr_updated(PDEVICE_OBJECT mountmgr, MOUNTMGR_MOUNT_POINTS *mmps)
Definition: search.c:789
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
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:207
#define IOCTL_MOUNTMGR_QUERY_POINTS
Definition: mountmgr.h:30
NTSTATUS pnp_surprise_removal(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pnp.c:252
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:108
Definition: devices.h:37
uint32_t no_pnp
Definition: btrfs.c:89
ERESOURCE pdo_list_lock
Definition: btrfs.c:103
#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:261
PDEVICE_OBJECT devobj
Definition: btrfs_drv.h:825
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:328
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define STATUS_NOT_FOUND
Definition: shellext.h:67
uint64_t children_loaded
Definition: btrfs_drv.h:860
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
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
NTSTATUS remove_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
Definition: search.c:208
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:2841
bool had_drive_letter
Definition: btrfs_drv.h:830
#define Vcb
Definition: cdprocs.h:1425
LIST_ENTRY list_entry
Definition: btrfs_drv.h:864
unsigned long DWORD
Definition: ntddk_ex.h:95
static bool fs_ignored(BTRFS_UUID *uuid)
Definition: search.c:43
#define __stdcall
Definition: typedefs.h:25
#define _Inout_
Definition: no_sal2.h:244
ERESOURCE child_lock
Definition: btrfs_drv.h:861
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
tIoUnregisterPlugPlayNotificationEx fIoUnregisterPlugPlayNotificationEx
Definition: btrfs.c:97
* 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:832
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
uint64_t generation
Definition: btrfs.h:212
#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:575
static const WCHAR L[]
Definition: oid.c:1250
Definition: typedefs.h:117
#define _Releases_exclusive_lock_(a)
Definition: btrfs_drv.h:190
pnp_callback func
Definition: search.c:635
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:717
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:2672
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
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:5108
UINT64 uint64_t
Definition: types.h:77
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
#define IOCTL_DISK_GET_DRIVE_LAYOUT_EX
Definition: ntddk_ex.h:207
PIO_WORKITEM work_item
Definition: search.c:636
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
BTRFS_UUID uuid
Definition: btrfs.h:208
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:653
NTSTATUS NTAPI PsTerminateSystemThread(IN NTSTATUS ExitStatus)
Definition: kill.c:1144
Definition: services.c:325
UNICODE_STRING registry_path
Definition: btrfs.c:91
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:116
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:855
static ACCESS_MASK const OBJECT_ATTRIBUTES ULONG const UNICODE_STRING ULONG PULONG dispos
Definition: reg.c:130
Definition: name.c:36
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:862
int remove
Definition: msacm.c:1353
return STATUS_SUCCESS
Definition: btrfs.c:2966
UNICODE_STRING name
Definition: search.c:634
#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:490
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