ReactOS 0.4.15-dev-7788-g1ad9096
volume.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#include <mountdev.h>
20#include <ntddvol.h>
21#include <ntddstor.h>
22#include <ntdddisk.h>
23#include <wdmguid.h>
24
25#define IOCTL_VOLUME_IS_DYNAMIC CTL_CODE(IOCTL_VOLUME_BASE, 18, METHOD_BUFFERED, FILE_ANY_ACCESS)
26#define IOCTL_VOLUME_POST_ONLINE CTL_CODE(IOCTL_VOLUME_BASE, 25, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
27
32extern LIST_ENTRY pdo_list;
35
37 volume_device_extension* vde = DeviceObject->DeviceExtension;
38
39 TRACE("(%p, %p)\n", DeviceObject, Irp);
40
41 if (vde->removing)
43
44 Irp->IoStatus.Information = FILE_OPENED;
46
47 return STATUS_SUCCESS;
48}
49
52
53 vde->dead = true;
54
55 if (vde->mounted_device) {
57
58 Vcb->vde = NULL;
59 }
60
61 if (vde->name.Buffer)
63
64 ExDeleteResourceLite(&vde->pdode->child_lock);
65
66 if (vde->pdo->AttachedDevice)
67 IoDetachDevice(vde->pdo);
68
69 while (!IsListEmpty(&vde->pdode->children)) {
71
72 if (vc->notification_entry) {
75 else
77 }
78
79 if (vc->pnp_name.Buffer)
81
82 ExFreePool(vc);
83 }
84
85 if (no_pnp)
86 ExFreePool(vde->pdode);
87
88 pdo = vde->pdo;
90
91 if (!no_pnp)
92 IoDeleteDevice(pdo);
93}
94
96 volume_device_extension* vde = DeviceObject->DeviceExtension;
97 pdo_device_extension* pdode = vde->pdode;
98
99 TRACE("(%p, %p)\n", DeviceObject, Irp);
100
101 Irp->IoStatus.Information = 0;
102
103 if (vde->dead)
104 return STATUS_SUCCESS;
105
107
108 if (vde->dead) {
110 return STATUS_SUCCESS;
111 }
112
114
115 if (InterlockedDecrement(&vde->open_count) == 0 && vde->removing) {
117
118 free_vol(vde);
119 } else
121
123
124 return STATUS_SUCCESS;
125}
126
127typedef struct {
131
132_Function_class_(IO_COMPLETION_ROUTINE)
133static NTSTATUS __stdcall vol_read_completion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID conptr) {
134 vol_read_context* context = conptr;
135
137
138 context->iosb = Irp->IoStatus;
139 KeSetEvent(&context->Event, 0, false);
140
142}
143
145 volume_device_extension* vde = DeviceObject->DeviceExtension;
146 pdo_device_extension* pdode = vde->pdode;
147 volume_child* vc;
149 PIRP Irp2;
152
153 TRACE("(%p, %p)\n", DeviceObject, Irp);
154
156
157 if (IsListEmpty(&pdode->children)) {
160 goto end;
161 }
162
164
165 // We can't use IoSkipCurrentIrpStackLocation as the device isn't in our stack
166
167 Irp2 = IoAllocateIrp(vc->devobj->StackSize, false);
168
169 if (!Irp2) {
170 ERR("IoAllocateIrp failed\n");
173 goto end;
174 }
175
177 IrpSp2 = IoGetNextIrpStackLocation(Irp2);
178
179 IrpSp2->MajorFunction = IRP_MJ_READ;
180 IrpSp2->FileObject = vc->fileobj;
181
182 if (vc->devobj->Flags & DO_BUFFERED_IO) {
183 Irp2->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool, IrpSp->Parameters.Read.Length, ALLOC_TAG);
184 if (!Irp2->AssociatedIrp.SystemBuffer) {
185 ERR("out of memory\n");
188 goto end;
189 }
190
192
193 Irp2->UserBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
194 } else if (vc->devobj->Flags & DO_DIRECT_IO)
195 Irp2->MdlAddress = Irp->MdlAddress;
196 else
197 Irp2->UserBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
198
199 IrpSp2->Parameters.Read.Length = IrpSp->Parameters.Read.Length;
200 IrpSp2->Parameters.Read.ByteOffset.QuadPart = IrpSp->Parameters.Read.ByteOffset.QuadPart;
201
203 Irp2->UserIosb = &context.iosb;
204
205 IoSetCompletionRoutine(Irp2, vol_read_completion, &context, true, true, true);
206
207 Status = IoCallDriver(vc->devobj, Irp2);
208
209 if (Status == STATUS_PENDING) {
211 Status = context.iosb.Status;
212 }
213
215
216 Irp->IoStatus.Information = context.iosb.Information;
217
218end:
219 Irp->IoStatus.Status = Status;
221
222 return Status;
223}
224
226 volume_device_extension* vde = DeviceObject->DeviceExtension;
227 pdo_device_extension* pdode = vde->pdode;
228 volume_child* vc;
230 PIRP Irp2;
233
234 TRACE("(%p, %p)\n", DeviceObject, Irp);
235
237
238 if (IsListEmpty(&pdode->children)) {
241 goto end;
242 }
243
245
246 if (vc->list_entry.Flink != &pdode->children) { // more than once device
249 goto end;
250 }
251
252 // We can't use IoSkipCurrentIrpStackLocation as the device isn't in our stack
253
254 Irp2 = IoAllocateIrp(vc->devobj->StackSize, false);
255
256 if (!Irp2) {
257 ERR("IoAllocateIrp failed\n");
260 goto end;
261 }
262
264 IrpSp2 = IoGetNextIrpStackLocation(Irp2);
265
266 IrpSp2->MajorFunction = IRP_MJ_WRITE;
267 IrpSp2->FileObject = vc->fileobj;
268
269 if (vc->devobj->Flags & DO_BUFFERED_IO) {
270 Irp2->AssociatedIrp.SystemBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
271
272 Irp2->Flags |= IRP_BUFFERED_IO;
273
274 Irp2->UserBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
275 } else if (vc->devobj->Flags & DO_DIRECT_IO)
276 Irp2->MdlAddress = Irp->MdlAddress;
277 else
278 Irp2->UserBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
279
280 IrpSp2->Parameters.Write.Length = IrpSp->Parameters.Write.Length;
281 IrpSp2->Parameters.Write.ByteOffset.QuadPart = IrpSp->Parameters.Write.ByteOffset.QuadPart;
282
284 Irp2->UserIosb = &context.iosb;
285
286 IoSetCompletionRoutine(Irp2, vol_read_completion, &context, true, true, true);
287
288 Status = IoCallDriver(vc->devobj, Irp2);
289
290 if (Status == STATUS_PENDING) {
292 Status = context.iosb.Status;
293 }
294
296
297 Irp->IoStatus.Information = context.iosb.Information;
298
299end:
300 Irp->IoStatus.Status = Status;
302
303 return Status;
304}
305
309
310 if (IrpSp->FileObject && IrpSp->FileObject->FsContext)
312
313 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_NAME)) {
314 Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
316 }
317
318 name = Irp->AssociatedIrp.SystemBuffer;
319 name->NameLength = vde->name.Length;
320
321 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < offsetof(MOUNTDEV_NAME, Name[0]) + name->NameLength) {
322 Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
324 }
325
326 RtlCopyMemory(name->Name, vde->name.Buffer, vde->name.Length);
327
328 Irp->IoStatus.Information = offsetof(MOUNTDEV_NAME, Name[0]) + name->NameLength;
329
330 return STATUS_SUCCESS;
331}
332
335 MOUNTDEV_UNIQUE_ID* mduid;
337
338 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_UNIQUE_ID)) {
339 Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
341 }
342
343 mduid = Irp->AssociatedIrp.SystemBuffer;
344 mduid->UniqueIdLength = sizeof(BTRFS_UUID);
345
346 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < offsetof(MOUNTDEV_UNIQUE_ID, UniqueId[0]) + mduid->UniqueIdLength) {
347 Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
349 }
350
351 if (!vde->pdo)
353
354 pdode = vde->pdode;
355
356 RtlCopyMemory(mduid->UniqueId, &pdode->uuid, sizeof(BTRFS_UUID));
357
358 Irp->IoStatus.Information = offsetof(MOUNTDEV_UNIQUE_ID, UniqueId[0]) + mduid->UniqueIdLength;
359
360 return STATUS_SUCCESS;
361}
362
365 uint8_t* buf;
366
367 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0 || !Irp->AssociatedIrp.SystemBuffer)
369
370 buf = (uint8_t*)Irp->AssociatedIrp.SystemBuffer;
371
372 *buf = 1;
373
374 Irp->IoStatus.Information = 1;
375
376 return STATUS_SUCCESS;
377}
378
380 pdo_device_extension* pdode = vde->pdode;
382 LIST_ENTRY* le;
383
385
386 le = pdode->children.Flink;
387 while (le != &pdode->children) {
389
391 if (!NT_SUCCESS(Status))
392 goto end;
393
394 le = le->Flink;
395 }
396
398
399end:
401
402 return Status;
403}
404
406 pdo_device_extension* pdode = vde->pdode;
408 LIST_ENTRY* le;
409 ULONG num_extents = 0, i, max_extents = 1;
412
413 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(VOLUME_DISK_EXTENTS))
415
417
418 le = pdode->children.Flink;
419 while (le != &pdode->children) {
422
425 ERR("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS returned %08lx\n", Status);
426 goto end;
427 }
428
429 num_extents += ext2.NumberOfDiskExtents;
430
431 if (ext2.NumberOfDiskExtents > max_extents)
432 max_extents = ext2.NumberOfDiskExtents;
433
434 le = le->Flink;
435 }
436
437 ext = Irp->AssociatedIrp.SystemBuffer;
438
439 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (num_extents * sizeof(DISK_EXTENT))) {
440 Irp->IoStatus.Information = offsetof(VOLUME_DISK_EXTENTS, Extents[0]);
441 ext->NumberOfDiskExtents = num_extents;
443 goto end;
444 }
445
446 ext3 = ExAllocatePoolWithTag(PagedPool, offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (max_extents * sizeof(DISK_EXTENT)), ALLOC_TAG);
447 if (!ext3) {
448 ERR("out of memory\n");
450 goto end;
451 }
452
453 i = 0;
454 ext->NumberOfDiskExtents = 0;
455
456 le = pdode->children.Flink;
457 while (le != &pdode->children) {
459
461 (ULONG)offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (max_extents * sizeof(DISK_EXTENT)), false, NULL);
462 if (!NT_SUCCESS(Status)) {
463 ERR("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS returned %08lx\n", Status);
465 goto end;
466 }
467
468 if (i + ext3->NumberOfDiskExtents > num_extents) {
469 Irp->IoStatus.Information = offsetof(VOLUME_DISK_EXTENTS, Extents[0]);
470 ext->NumberOfDiskExtents = i + ext3->NumberOfDiskExtents;
473 goto end;
474 }
475
476 RtlCopyMemory(&ext->Extents[i], ext3->Extents, sizeof(DISK_EXTENT) * ext3->NumberOfDiskExtents);
477 i += ext3->NumberOfDiskExtents;
478
479 le = le->Flink;
480 }
481
483
485
486 ext->NumberOfDiskExtents = i;
487 Irp->IoStatus.Information = offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (i * sizeof(DISK_EXTENT));
488
489end:
491
492 return Status;
493}
494
496 pdo_device_extension* pdode = vde->pdode;
498 LIST_ENTRY* le;
499 bool writable = false;
500
502
503 le = pdode->children.Flink;
504 while (le != &pdode->children) {
506
508
509 if (NT_SUCCESS(Status)) {
510 writable = true;
511 break;
513 goto end;
514
515 le = le->Flink;
516 }
517
519
520end:
522
523 return STATUS_SUCCESS;
524}
525
528 pdo_device_extension* pdode = vde->pdode;
530 LIST_ENTRY* le;
531
532 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GET_LENGTH_INFORMATION))
534
535 gli = (GET_LENGTH_INFORMATION*)Irp->AssociatedIrp.SystemBuffer;
536
537 gli->Length.QuadPart = 0;
538
540
541 le = pdode->children.Flink;
542 while (le != &pdode->children) {
544
545 gli->Length.QuadPart += vc->size;
546
547 le = le->Flink;
548 }
549
551
552 Irp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION);
553
554 return STATUS_SUCCESS;
555}
556
558 volume_device_extension* vde = DeviceObject->DeviceExtension;
559 pdo_device_extension* pdode = vde->pdode;
561 DISK_GEOMETRY* geom;
563 LIST_ENTRY* le;
564
565 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY))
567
568 length = 0;
569
571
572 le = pdode->children.Flink;
573 while (le != &pdode->children) {
575
576 length += vc->size;
577
578 le = le->Flink;
579 }
580
582
583 geom = (DISK_GEOMETRY*)Irp->AssociatedIrp.SystemBuffer;
584 geom->BytesPerSector = DeviceObject->SectorSize == 0 ? 0x200 : DeviceObject->SectorSize;
585 geom->SectorsPerTrack = 0x3f;
586 geom->TracksPerCylinder = 0xff;
589
590 Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
591
592 return STATUS_SUCCESS;
593}
594
598
599 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(VOLUME_GET_GPT_ATTRIBUTES_INFORMATION))
601
602 vggai = (VOLUME_GET_GPT_ATTRIBUTES_INFORMATION*)Irp->AssociatedIrp.SystemBuffer;
603
604 vggai->GptAttributes = 0;
605
606 Irp->IoStatus.Information = sizeof(VOLUME_GET_GPT_ATTRIBUTES_INFORMATION);
607
608 return STATUS_SUCCESS;
609}
610
612 pdo_device_extension* pdode = vde->pdode;
614 volume_child* vc;
616
617 // If only one device, return its disk number. This is needed for ejection to work.
618
619 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_DEVICE_NUMBER))
621
623
624 if (IsListEmpty(&pdode->children) || pdode->num_children > 1) {
627 }
628
630
631 if (vc->disk_num == 0xffffffff) {
634 }
635
636 sdn = (STORAGE_DEVICE_NUMBER*)Irp->AssociatedIrp.SystemBuffer;
637
639 sdn->DeviceNumber = vc->disk_num;
640 sdn->PartitionNumber = vc->part_num;
641
643
644 Irp->IoStatus.Information = sizeof(STORAGE_DEVICE_NUMBER);
645
646 return STATUS_SUCCESS;
647}
648
649_Function_class_(IO_COMPLETION_ROUTINE)
650static NTSTATUS __stdcall vol_ioctl_completion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID conptr) {
651 KEVENT* event = conptr;
652
654 UNUSED(Irp);
655
656 KeSetEvent(event, 0, false);
657
659}
660
663 volume_child* vc;
664 PIRP Irp2;
667 pdo_device_extension* pdode = vde->pdode;
668
669 TRACE("(%p, %p)\n", vde, Irp);
670
672
673 if (IsListEmpty(&pdode->children)) {
676 }
677
679
680 if (vc->list_entry.Flink != &pdode->children) { // more than one device
683 }
684
685 Irp2 = IoAllocateIrp(vc->devobj->StackSize, false);
686
687 if (!Irp2) {
688 ERR("IoAllocateIrp failed\n");
691 }
692
694 IrpSp2 = IoGetNextIrpStackLocation(Irp2);
695
698 IrpSp2->FileObject = vc->fileobj;
699
700 IrpSp2->Parameters.DeviceIoControl.OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
701 IrpSp2->Parameters.DeviceIoControl.InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
702 IrpSp2->Parameters.DeviceIoControl.IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
703 IrpSp2->Parameters.DeviceIoControl.Type3InputBuffer = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
704
705 Irp2->AssociatedIrp.SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
706 Irp2->MdlAddress = Irp->MdlAddress;
707 Irp2->UserBuffer = Irp->UserBuffer;
708 Irp2->Flags = Irp->Flags;
709
711
712 IoSetCompletionRoutine(Irp2, vol_ioctl_completion, &Event, true, true, true);
713
714 Status = IoCallDriver(vc->devobj, Irp2);
715
716 if (Status == STATUS_PENDING) {
718 Status = Irp2->IoStatus.Status;
719 }
720
721 Irp->IoStatus.Status = Irp2->IoStatus.Status;
722 Irp->IoStatus.Information = Irp2->IoStatus.Information;
723
725
726 IoFreeIrp(Irp2);
727
728 return Status;
729}
730
735
736 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_STABLE_GUID)) {
737 Irp->IoStatus.Information = sizeof(MOUNTDEV_STABLE_GUID);
739 }
740
741 mdsg = Irp->AssociatedIrp.SystemBuffer;
742
743 if (!vde->pdo)
745
746 pdode = vde->pdode;
747
748 RtlCopyMemory(&mdsg->StableGuid, &pdode->uuid, sizeof(BTRFS_UUID));
749
750 Irp->IoStatus.Information = sizeof(MOUNTDEV_STABLE_GUID);
751
752 return STATUS_SUCCESS;
753}
754
756 volume_device_extension* vde = DeviceObject->DeviceExtension;
758
759 TRACE("(%p, %p)\n", DeviceObject, Irp);
760
761 Irp->IoStatus.Information = 0;
762
763 switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
765 return vol_query_device_name(vde, Irp);
766
768 return vol_query_unique_id(vde, Irp);
769
771 return vol_get_device_number(vde, Irp);
772
774 TRACE("unhandled control code IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME\n");
775 break;
776
778 return vol_query_stable_guid(vde, Irp);
779
781 TRACE("unhandled control code IOCTL_MOUNTDEV_LINK_CREATED\n");
782 break;
783
786
788 return vol_is_dynamic(Irp);
789
791 Irp->IoStatus.Information = 0;
792 return STATUS_SUCCESS;
793
795 Irp->IoStatus.Information = 0;
796 return STATUS_SUCCESS;
797
800
802 return vol_is_writable(vde);
803
805 return vol_get_length(vde, Irp);
806
809 return vol_check_verify(vde);
810
812 return vol_get_disk_extents(vde, Irp);
813
814 default: { // pass ioctl through if only one child device
816#ifdef _DEBUG
817 ULONG code = IrpSp->Parameters.DeviceIoControl.IoControlCode;
818
819 if (NT_SUCCESS(Status))
820 TRACE("passing through ioctl %lx (returning %08lx)\n", code, Status);
821 else
822 WARN("passing through ioctl %lx (returning %08lx)\n", code, Status);
823#endif
824
825 return Status;
826 }
827 }
828
830}
831
834 ULONG mmdltsize;
837
838 mmdltsize = (ULONG)offsetof(MOUNTMGR_DRIVE_LETTER_TARGET, DeviceName[0]) + devpath->Length;
839
840 mmdlt = ExAllocatePoolWithTag(NonPagedPool, mmdltsize, ALLOC_TAG);
841 if (!mmdlt) {
842 ERR("out of memory\n");
844 }
845
846 mmdlt->DeviceNameLength = devpath->Length;
847 RtlCopyMemory(&mmdlt->DeviceName, devpath->Buffer, devpath->Length);
848 TRACE("mmdlt = %.*S\n", (int)(mmdlt->DeviceNameLength / sizeof(WCHAR)), mmdlt->DeviceName);
849
851
852 if (!NT_SUCCESS(Status))
853 ERR("IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER returned %08lx\n", Status);
854 else
855 TRACE("DriveLetterWasAssigned = %u, CurrentDriveLetter = %c\n", mmdli.DriveLetterWasAssigned, mmdli.CurrentDriveLetter);
856
857 ExFreePool(mmdlt);
858
859 return Status;
860}
861
862_Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE)
866
867 if (RtlCompareMemory(&tdrn->Event, &GUID_TARGET_DEVICE_QUERY_REMOVE, sizeof(GUID)) == sizeof(GUID)) {
868 TRACE("GUID_TARGET_DEVICE_QUERY_REMOVE\n");
869
870 if (pdode->vde && pdode->vde->mounted_device)
872 }
873
874 return STATUS_SUCCESS;
875}
876
878 HANDLE h;
881 UNICODE_STRING path, adus;
883 ULONG i, j, kvfilen, retlen;
885
886 path.Length = path.MaximumLength = registry_path.Length + (37 * sizeof(WCHAR));
888
889 if (!path.Buffer) {
890 ERR("out of memory\n");
891 return false;
892 }
893
895 i = registry_path.Length / sizeof(WCHAR);
896
897 path.Buffer[i] = '\\';
898 i++;
899
900 for (j = 0; j < 16; j++) {
901 path.Buffer[i] = hex_digit((uuid->uuid[j] & 0xF0) >> 4);
902 path.Buffer[i+1] = hex_digit(uuid->uuid[j] & 0xF);
903
904 i += 2;
905
906 if (j == 3 || j == 5 || j == 7 || j == 9) {
907 path.Buffer[i] = '-';
908 i++;
909 }
910 }
911
913
914 kvfilen = (ULONG)offsetof(KEY_VALUE_FULL_INFORMATION, Name[0]) + (255 * sizeof(WCHAR));
915 kvfi = ExAllocatePoolWithTag(PagedPool, kvfilen, ALLOC_TAG);
916 if (!kvfi) {
917 ERR("out of memory\n");
918 ExFreePool(path.Buffer);
919 return false;
920 }
921
922 Status = ZwOpenKey(&h, KEY_QUERY_VALUE, &oa);
924 goto end;
925 else if (!NT_SUCCESS(Status)) {
926 ERR("ZwOpenKey returned %08lx\n", Status);
927 goto end;
928 }
929
930 adus.Buffer = L"AllowDegraded";
931 adus.Length = adus.MaximumLength = sizeof(adus.Buffer) - sizeof(WCHAR);
932
933 if (NT_SUCCESS(ZwQueryValueKey(h, &adus, KeyValueFullInformation, kvfi, kvfilen, &retlen))) {
934 if (kvfi->Type == REG_DWORD && kvfi->DataLength >= sizeof(uint32_t)) {
935 uint32_t* val = (uint32_t*)((uint8_t*)kvfi + kvfi->DataOffset);
936
937 degraded = *val;
938 }
939 }
940
941 ZwClose(h);
942
943end:
944 ExFreePool(kvfi);
945
946 ExFreePool(path.Buffer);
947
948 return degraded;
949}
950
951typedef struct {
957
959 LIST_ENTRY* le;
960 LIST_ENTRY dlrlist;
961
962 InitializeListHead(&dlrlist);
963
965
966 le = pdode->children.Flink;
967
968 while (le != &pdode->children) {
970
972
974 if (!dlr) {
975 ERR("out of memory\n");
976
977 while (!IsListEmpty(&dlrlist)) {
979
980 ExFreePool(dlr->name.Buffer);
981 ExFreePool(dlr);
982 }
983
985 return;
986 }
987
988 dlr->name.Length = dlr->name.MaximumLength = vc->pnp_name.Length + (3 * sizeof(WCHAR));
990
991 if (!dlr->name.Buffer) {
992 ERR("out of memory\n");
993
994 ExFreePool(dlr);
995
996 while (!IsListEmpty(&dlrlist)) {
998
999 ExFreePool(dlr->name.Buffer);
1000 ExFreePool(dlr);
1001 }
1002
1004 return;
1005 }
1006
1007 RtlCopyMemory(dlr->name.Buffer, L"\\??", 3 * sizeof(WCHAR));
1009
1010 dlr->uuid = vc->uuid;
1011
1012 InsertTailList(&dlrlist, &dlr->list_entry);
1013
1014 le = le->Flink;
1015 }
1016
1018
1019 le = dlrlist.Flink;
1020 while (le != &dlrlist) {
1022
1023 dlr->Status = remove_drive_letter(mountmgr, &dlr->name);
1024
1025 if (!NT_SUCCESS(dlr->Status) && dlr->Status != STATUS_NOT_FOUND)
1026 WARN("remove_drive_letter returned %08lx\n", dlr->Status);
1027
1028 le = le->Flink;
1029 }
1030
1031 // set vc->had_drive_letter
1032
1034
1035 while (!IsListEmpty(&dlrlist)) {
1037
1038 le = pdode->children.Flink;
1039
1040 while (le != &pdode->children) {
1042
1043 if (RtlCompareMemory(&vc->uuid, &dlr->uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1045 break;
1046 }
1047
1048 le = le->Flink;
1049 }
1050
1051 ExFreePool(dlr->name.Buffer);
1052 ExFreePool(dlr);
1053 }
1054
1056}
1057
1058_Function_class_(IO_WORKITEM_ROUTINE)
1059static void __stdcall drive_letter_callback(pdo_device_extension* pdode) {
1061 UNICODE_STRING mmdevpath;
1063 PFILE_OBJECT mountmgrfo;
1064
1066 Status = IoGetDeviceObjectPointer(&mmdevpath, FILE_READ_ATTRIBUTES, &mountmgrfo, &mountmgr);
1067 if (!NT_SUCCESS(Status)) {
1068 ERR("IoGetDeviceObjectPointer returned %08lx\n", Status);
1069 return;
1070 }
1071
1073
1074 ObDereferenceObject(mountmgrfo);
1075}
1076
1079 LIST_ENTRY* le;
1081 volume_child* vc;
1083 UNICODE_STRING devpath2;
1084 bool inserted = false, new_pdo = false;
1085 pdo_device_extension* pdode = NULL;
1086 PDEVICE_OBJECT pdo = NULL;
1087 bool process_drive_letters = false;
1088
1089 if (devpath->Length == 0)
1090 return;
1091
1093
1094 le = pdo_list.Flink;
1095 while (le != &pdo_list) {
1097
1098 if (RtlCompareMemory(&pdode2->uuid, &sb->uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1099 pdode = pdode2;
1100 break;
1101 }
1102
1103 le = le->Flink;
1104 }
1105
1107 if (!NT_SUCCESS(Status)) {
1108 ERR("IoGetDeviceObjectPointer returned %08lx\n", Status);
1110 return;
1111 }
1112
1113 if (!pdode) {
1114 if (no_pnp) {
1115 Status = IoReportDetectedDevice(drvobj, InterfaceTypeUndefined, 0xFFFFFFFF, 0xFFFFFFFF, NULL, NULL, 0, &pdo);
1116
1117 if (!NT_SUCCESS(Status)) {
1118 ERR("IoReportDetectedDevice returned %08lx\n", Status);
1120 return;
1121 }
1122
1124
1125 if (!pdode) {
1126 ERR("out of memory\n");
1128 return;
1129 }
1130 } else {
1133 if (!NT_SUCCESS(Status)) {
1134 ERR("IoCreateDevice returned %08lx\n", Status);
1136 goto fail;
1137 }
1138
1140
1141 pdode = pdo->DeviceExtension;
1142 }
1143
1144 RtlZeroMemory(pdode, sizeof(pdo_device_extension));
1145
1146 pdode->type = VCB_TYPE_PDO;
1147 pdode->pdo = pdo;
1148 pdode->uuid = sb->uuid;
1149
1152 pdode->num_children = sb->num_devices;
1153 pdode->children_loaded = 0;
1154
1155 pdo->Flags &= ~DO_DEVICE_INITIALIZING;
1156 pdo->SectorSize = (USHORT)sb->sector_size;
1157
1159
1160 new_pdo = true;
1161 } else {
1164
1165 le = pdode->children.Flink;
1166 while (le != &pdode->children) {
1168
1169 if (RtlCompareMemory(&vc2->uuid, &sb->dev_item.device_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1170 // duplicate, ignore
1173 goto fail;
1174 }
1175
1176 le = le->Flink;
1177 }
1178 }
1179
1181 if (!vc) {
1182 ERR("out of memory\n");
1183
1186
1187 goto fail;
1188 }
1189
1190 vc->uuid = sb->dev_item.device_uuid;
1191 vc->devid = sb->dev_item.dev_id;
1192 vc->generation = sb->generation;
1194 vc->boot_volume = false;
1195
1197 drvobj, pnp_removal, pdode, &vc->notification_entry);
1198 if (!NT_SUCCESS(Status))
1199 WARN("IoRegisterPlugPlayNotification returned %08lx\n", Status);
1200
1201 vc->devobj = DeviceObject;
1202 vc->fileobj = FileObject;
1203
1204 devpath2 = *devpath;
1205
1206 // The PNP path sometimes begins \\?\ and sometimes \??\. We need to remove this prefix
1207 // so we can compare properly if the device is removed.
1208 if (devpath->Length > 4 * sizeof(WCHAR) && devpath->Buffer[0] == '\\' && (devpath->Buffer[1] == '\\' || devpath->Buffer[1] == '?') &&
1209 devpath->Buffer[2] == '?' && devpath->Buffer[3] == '\\') {
1210 devpath2.Buffer = &devpath2.Buffer[3];
1211 devpath2.Length -= 3 * sizeof(WCHAR);
1212 devpath2.MaximumLength -= 3 * sizeof(WCHAR);
1213 }
1214
1215 vc->pnp_name.Length = vc->pnp_name.MaximumLength = devpath2.Length;
1217
1218 if (vc->pnp_name.Buffer)
1219 RtlCopyMemory(vc->pnp_name.Buffer, devpath2.Buffer, devpath2.Length);
1220 else {
1221 ERR("out of memory\n");
1222 vc->pnp_name.Length = vc->pnp_name.MaximumLength = 0;
1223 }
1224
1225 vc->size = length;
1227 vc->disk_num = disk_num;
1228 vc->part_num = part_num;
1229 vc->had_drive_letter = false;
1230
1231 le = pdode->children.Flink;
1232 while (le != &pdode->children) {
1234
1235 if (vc2->generation < vc->generation) {
1236 if (le == pdode->children.Flink)
1237 pdode->num_children = sb->num_devices;
1238
1240 inserted = true;
1241 break;
1242 }
1243
1244 le = le->Flink;
1245 }
1246
1247 if (!inserted)
1248 InsertTailList(&pdode->children, &vc->list_entry);
1249
1250 pdode->children_loaded++;
1251
1252 if (pdode->vde && pdode->vde->mounted_device) {
1254
1255 ExAcquireResourceExclusiveLite(&Vcb->tree_lock, true);
1256
1257 le = Vcb->devices.Flink;
1258 while (le != &Vcb->devices) {
1260
1261 if (!dev->devobj && RtlCompareMemory(&dev->devitem.device_uuid, &sb->dev_item.device_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1262 dev->devobj = DeviceObject;
1263 dev->disk_num = disk_num;
1264 dev->part_num = part_num;
1265 init_device(Vcb, dev, false);
1266 break;
1267 }
1268
1269 le = le->Flink;
1270 }
1271
1272 ExReleaseResourceLite(&Vcb->tree_lock);
1273 }
1274
1275 if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
1276 pdode->removable = true;
1277
1278 if (pdode->vde && pdode->vde->device)
1279 pdode->vde->device->Characteristics |= FILE_REMOVABLE_MEDIA;
1280 }
1281
1282 if (pdode->num_children == pdode->children_loaded || (pdode->children_loaded == 1 && allow_degraded_mount(&sb->uuid))) {
1283 if ((!new_pdo || !no_pnp) && pdode->vde) {
1284 Status = IoSetDeviceInterfaceState(&pdode->vde->bus_name, true);
1285 if (!NT_SUCCESS(Status))
1286 WARN("IoSetDeviceInterfaceState returned %08lx\n", Status);
1287 }
1288
1289 process_drive_letters = true;
1290 }
1291
1293
1294 if (new_pdo)
1296
1298
1299 if (process_drive_letters)
1300 drive_letter_callback(pdode);
1301
1302 if (new_pdo) {
1303 if (RtlCompareMemory(&sb->uuid, &boot_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID))
1304 boot_add_device(pdo);
1305 else if (no_pnp)
1306 AddDevice(drvobj, pdo);
1307 else {
1310 }
1311 }
1312
1313 return;
1314
1315fail:
1317}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
NTSTATUS(__stdcall * tIoUnregisterPlugPlayNotificationEx)(PVOID NotificationEntry)
Definition: btrfs_drv.h:1857
void void void NTSTATUS void NTSTATUS NTSTATUS remove_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
Definition: search.c:407
#define ALLOC_TAG
Definition: btrfs_drv.h:87
#define hex_digit(c)
Definition: btrfs_drv.h:1748
NTSTATUS pnp_query_remove_device(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pnp.c:23
#define UNUSED(x)
Definition: btrfs_drv.h:82
#define VCB_TYPE_PDO
Definition: btrfs_drv.h:690
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
#define IOCTL_DISK_CHECK_VERIFY
Definition: cdrw_usr.h:175
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
#define IOCTL_DISK_IS_WRITABLE
Definition: cdrw_usr.h:172
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
UINT64 uint64_t
Definition: types.h:77
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR *const ext[]
Definition: module.c:53
BTRFS_UUID boot_uuid
Definition: boot.c:33
void boot_add_device(DEVICE_OBJECT *pdo)
Definition: boot.c:318
superblock * sb
Definition: btrfs.c:4261
uint32_t mount_allow_degraded
Definition: btrfs.c:83
void init_device(_In_ device_extension *Vcb, _Inout_ device *dev, _In_ bool get_nums)
Definition: btrfs.c:3416
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
#define BTRFS_SUPERBLOCK_FLAGS_SEEDING
Definition: btrfs.h:128
static void drive_letter_callback2(pdo_device_extension *pdode, PDEVICE_OBJECT mountmgr)
Definition: volume.c:958
static NTSTATUS vol_query_unique_id(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:333
static NTSTATUS vol_query_stable_guid(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:731
static bool allow_degraded_mount(BTRFS_UUID *uuid)
Definition: volume.c:877
static NTSTATUS vol_check_verify(volume_device_extension *vde)
Definition: volume.c:379
NTSTATUS mountmgr_add_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
Definition: volume.c:832
UNICODE_STRING registry_path
Definition: btrfs.c:89
PDRIVER_OBJECT drvobj
Definition: btrfs.c:65
static NTSTATUS vol_get_disk_extents(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:405
NTSTATUS vol_read(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:144
#define IOCTL_VOLUME_IS_DYNAMIC
Definition: volume.c:25
NTSTATUS vol_close(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:95
LIST_ENTRY pdo_list
Definition: btrfs.c:104
static NTSTATUS vol_get_length(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:526
static NTSTATUS vol_ioctl_passthrough(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:661
void free_vol(volume_device_extension *vde)
Definition: volume.c:50
ERESOURCE pdo_list_lock
Definition: btrfs.c:103
static NTSTATUS vol_get_gpt_attributes(PIRP Irp)
Definition: volume.c:595
PDEVICE_OBJECT master_devobj
Definition: btrfs.c:66
#define IOCTL_VOLUME_POST_ONLINE
Definition: volume.c:26
NTSTATUS vol_device_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:755
static NTSTATUS vol_get_drive_geometry(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: volume.c:557
tIoUnregisterPlugPlayNotificationEx fIoUnregisterPlugPlayNotificationEx
Definition: btrfs.c:95
static NTSTATUS vol_is_writable(volume_device_extension *vde)
Definition: volume.c:495
PDEVICE_OBJECT busobj
Definition: btrfs.c:66
NTSTATUS vol_write(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:225
static NTSTATUS vol_query_device_name(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:306
static NTSTATUS vol_get_device_number(volume_device_extension *vde, PIRP Irp)
Definition: volume.c:611
NTSTATUS vol_create(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:36
static NTSTATUS vol_is_dynamic(PIRP Irp)
Definition: volume.c:363
void add_volume_device(superblock *sb, PUNICODE_STRING devpath, uint64_t length, ULONG disk_num, ULONG part_num)
Definition: volume.c:1077
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#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 KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define ExConvertExclusiveToSharedLite(res)
Definition: env_spec_w32.h:652
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#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 RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define NonPagedPool
Definition: env_spec_w32.h:307
ULONG ERESOURCE
Definition: env_spec_w32.h:594
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
#define PagedPool
Definition: env_spec_w32.h:308
Status
Definition: gdiplustypes.h:25
GLuint GLuint end
Definition: gl.h:1545
struct _cl_event * event
Definition: glext.h:7739
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint GLfloat * val
Definition: glext.h:7180
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
@ InterfaceTypeUndefined
Definition: hwresource.cpp:136
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
Definition: msctf.idl:550
#define UInt32x32To64(a, b)
Definition: intsafe.h:252
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
struct _MOUNTDEV_NAME MOUNTDEV_NAME
struct _MOUNTDEV_UNIQUE_ID MOUNTDEV_UNIQUE_ID
#define IOCTL_MOUNTDEV_LINK_CREATED
Definition: imports.h:106
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
#define IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
Definition: imports.h:99
#define IOCTL_MOUNTDEV_QUERY_STABLE_GUID
Definition: imports.h:255
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:80
#define MOUNTMGR_DEVICE_NAME
Definition: imports.h:76
@ NormalPagePriority
Definition: imports.h:56
struct _MOUNTDEV_STABLE_GUID MOUNTDEV_STABLE_GUID
static const BYTE ext2[]
Definition: encode.c:2699
static const BYTE ext3[]
Definition: encode.c:2701
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER
Definition: mountmgr.h:34
#define _Function_class_(x)
Definition: ms_sal.h:2946
BYTE uint8_t
Definition: msvideo1.c:66
#define KernelMode
Definition: asm.h:34
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
@ 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 KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define FILE_OPENED
Definition: nt_native.h:769
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
struct _DISK_GEOMETRY DISK_GEOMETRY
@ RemovableMedia
Definition: ntdddisk.h:387
@ FixedMedia
Definition: ntdddisk.h:388
struct _STORAGE_DEVICE_NUMBER STORAGE_DEVICE_NUMBER
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:143
#define IOCTL_STORAGE_CHECK_VERIFY
Definition: ntddstor.h:98
#define IOCTL_VOLUME_GET_GPT_ATTRIBUTES
Definition: ntddvol.h:56
struct _DISK_EXTENT DISK_EXTENT
#define IOCTL_VOLUME_ONLINE
Definition: ntddvol.h:62
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
Definition: ntddvol.h:41
@ NotificationEvent
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
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
#define IoCompleteRequest
Definition: irp.c:1240
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define STATUS_PENDING
Definition: ntstatus.h:82
#define L(x)
Definition: ntvdm.h:50
DRIVER_ADD_DEVICE AddDevice
Definition: parport.h:72
unsigned short USHORT
Definition: pedump.c:61
#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
NTSTATUS NTAPI IoReportDetectedDevice(_In_ PDRIVER_OBJECT DriverObject, _In_ INTERFACE_TYPE LegacyBusType, _In_ ULONG BusNumber, _In_ ULONG SlotNumber, _In_opt_ PCM_RESOURCE_LIST ResourceList, _In_opt_ PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements, _In_ BOOLEAN ResourceAssigned, _Inout_ PDEVICE_OBJECT *DeviceObject)
Definition: pnpreport.c:148
#define FILE_DEVICE_DISK
Definition: winioctl.h:113
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define REG_DWORD
Definition: sdbapi.c:596
#define offsetof(TYPE, MEMBER)
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#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
#define true
Definition: stdbool.h:36
BTRFS_UUID device_uuid
Definition: btrfs.h:190
uint64_t dev_id
Definition: btrfs.h:178
LARGE_INTEGER Length
Definition: winioctl.h:560
PVOID DeviceExtension
Definition: env_spec_w32.h:418
MEDIA_TYPE MediaType
Definition: ntdddisk.h:406
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:405
ULONG TracksPerCylinder
Definition: ntdddisk.h:407
ULONG SectorsPerTrack
Definition: ntdddisk.h:408
ULONG BytesPerSector
Definition: ntdddisk.h:409
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
IO_STATUS_BLOCK IoStatus
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT UniqueIdLength
Definition: imports.h:138
UCHAR UniqueId[1]
Definition: imports.h:139
DEVICE_TYPE DeviceType
Definition: ntddstor.h:324
USHORT MaximumLength
Definition: env_spec_w32.h:370
struct pdo_device_extension * pdode
Definition: btrfs_drv.h:878
PDEVICE_OBJECT device
Definition: btrfs_drv.h:875
UNICODE_STRING name
Definition: btrfs_drv.h:874
UNICODE_STRING bus_name
Definition: btrfs_drv.h:879
PDEVICE_OBJECT mounted_device
Definition: btrfs_drv.h:876
PDEVICE_OBJECT pdo
Definition: btrfs_drv.h:877
PDEVICE_OBJECT buspdo
Definition: btrfs_drv.h:848
Definition: inflate.c:139
Definition: http.c:7252
Definition: devices.h:37
NTSTATUS Status
Definition: volume.c:954
LIST_ENTRY list_entry
Definition: volume.c:952
BTRFS_UUID uuid
Definition: volume.c:955
UNICODE_STRING name
Definition: volume.c:953
Definition: list.h:27
Definition: name.c:39
ERESOURCE child_lock
Definition: btrfs_drv.h:896
PDEVICE_OBJECT pdo
Definition: btrfs_drv.h:890
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
uint64_t num_children
Definition: btrfs_drv.h:894
LIST_ENTRY list_entry
Definition: btrfs_drv.h:899
uint64_t flags
Definition: btrfs.h:227
uint32_t sector_size
Definition: btrfs.h:238
BTRFS_UUID uuid
Definition: btrfs.h:225
uint64_t generation
Definition: btrfs.h:229
uint64_t num_devices
Definition: btrfs.h:237
DEV_ITEM dev_item
Definition: btrfs.h:251
KEVENT Event
Definition: volume.c:129
IO_STATUS_BLOCK iosb
Definition: volume.c:128
LIST_ENTRY list_entry
Definition: btrfs_drv.h:867
PFILE_OBJECT fileobj
Definition: btrfs_drv.h:858
uint64_t size
Definition: btrfs_drv.h:860
uint64_t devid
Definition: btrfs_drv.h:855
ULONG part_num
Definition: btrfs_drv.h:865
ULONG disk_num
Definition: btrfs_drv.h:864
void * notification_entry
Definition: btrfs_drv.h:863
bool seeding
Definition: btrfs_drv.h:861
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
uint64_t generation
Definition: btrfs_drv.h:856
BTRFS_UUID uuid
Definition: btrfs_drv.h:854
#define __stdcall
Definition: typedefs.h:25
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
_In_ PVOID NotificationStructure
Definition: iofuncs.h:1206
@ BusRelations
Definition: iotypes.h:2152
#define IRP_DEALLOCATE_BUFFER
#define IRP_INPUT_OPERATION
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define DO_BUS_ENUMERATED_DEVICE
@ EventCategoryTargetDeviceChange
Definition: iotypes.h:1227
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IRP_BUFFERED_IO
@ Executive
Definition: ketypes.h:415
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
#define ObDereferenceObject
Definition: obfuncs.h:203
__wchar_t WCHAR
Definition: xmlstorage.h:180