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