ReactOS 0.4.17-dev-1281-g065abb3
hubregistry.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS SuperSpeed USB Hub Driver
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: Per device and per hub registry state: errata, hardware keys, UXD and telemetry
5 * COPYRIGHT: Copyright 2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8#include "usbhub3.h"
9#include "hubregistry.h"
10
11#define NDEBUG
12#include <debug.h>
13
14static const WCHAR HubUsbflagsPath[] =
15 L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\usbflags";
16static const WCHAR HubVerifierPath[] =
17 L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\usb\\HardwareVerifier";
18static const WCHAR HubUxdDevicesPath[] =
19 L"\\registry\\machine\\system\\currentcontrolset\\services\\usbhub\\uxd_control\\devices";
20static const WCHAR HubUxdPnpPath[] =
21 L"\\registry\\machine\\system\\currentcontrolset\\services\\usbhub\\uxd_control\\pnp";
22static const WCHAR HubGlobalCeipPath[] =
23 L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Usb\\Ceip";
24static const WCHAR HubUsbControlPath[] =
25 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\USB";
26static const WCHAR HubUsbFnPath[] =
27 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\USBFN";
28static const WCHAR HubUsbFnDefaultPath[] =
29 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\USBFN\\Default";
30static const WCHAR HubUsbFnConfigPath[] =
31 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\USBFN\\Configurations\\";
32
33/* Function drivers opt in to D3cold under this subkey of the Hardware key */
34static const WCHAR HubD3ColdSubkey[] = L"e5b3b5ac-9725-4f78-963f-03dfb1d828c7";
36/* Port D3cold reconnect wait unless the hardware key says otherwise, in ms */
37#define HUB_D3COLD_RECONNECT_DEFAULT 1000
38
39/* Bits in the shim engine's per device flag words */
40#define KSE_SKIP_MS_OS 0
41#define KSE_DONT_SKIP_MS_OS 1
42#define KSE_KEEP_ON_SOFT_REMOVE 3
43#define KSE_LPM_OFF_FOR_CHAINED_HUBS 16
44#define KSE_LPM_OFF_DOWNSTREAM 26
45#define KSE_POLLING_TO_COMPLIANCE 35
46#define KSE_NO_U2_FOR_TUNNELED_DEVICES 48
47
48/* Dual role feature bits this machine may offer */
49#define HUB_DUAL_ROLE_MTP 0x00000002
50#define HUB_DUAL_ROLE_IP_OVER_USB 0x00000004
51#define HUB_DUAL_ROLE_VIDEO 0x00000008
52#define HUB_DUAL_ROLE_FUNCTIONS 0x0000000E
53#define HUB_DUAL_ROLE_UCM_PRESENT 0x80000000
54
55/* Shared primitives */
56
57VOID
62{
63 RtlStringCbPrintfA(Ids->Vendor, sizeof(Ids->Vendor), "%04X", Descriptor->idVendor);
64 RtlStringCbPrintfA(Ids->Product, sizeof(Ids->Product), "%04X", Descriptor->idProduct);
65 RtlStringCbPrintfA(Ids->Revision, sizeof(Ids->Revision), "%04X", Descriptor->bcdDevice);
66}
67
68/* Root hubs go by their controller; anything unknown gets the 7FFF placeholder */
69static
70VOID
75{
76 switch (Info->Type)
77 {
79 RtlStringCbPrintfA(Ids->Vendor, sizeof(Ids->Vendor), "%04X", Info->Pci.VendorId);
80 RtlStringCbPrintfA(Ids->Product, sizeof(Ids->Product), "%04X", Info->Pci.DeviceId);
81 RtlStringCbPrintfA(Ids->Revision, sizeof(Ids->Revision), "%04X", Info->Pci.RevisionId);
82 break;
83
85 RtlCopyMemory(Ids->Vendor, Info->Acpi.VendorId, sizeof(Ids->Vendor));
86 RtlCopyMemory(Ids->Product, Info->Acpi.DeviceId, sizeof(Ids->Product));
87 RtlCopyMemory(Ids->Revision, Info->Acpi.RevisionId, sizeof(Ids->Revision));
88 Ids->Vendor[sizeof(Ids->Vendor) - 1] = ANSI_NULL;
89 Ids->Product[sizeof(Ids->Product) - 1] = ANSI_NULL;
90 Ids->Revision[sizeof(Ids->Revision) - 1] = ANSI_NULL;
91 break;
92
93 default:
94 RtlStringCbPrintfA(Ids->Vendor, sizeof(Ids->Vendor), "%04X", MAXLONG);
95 RtlStringCbPrintfA(Ids->Product, sizeof(Ids->Product), "%04X", MAXLONG);
96 RtlStringCbPrintfA(Ids->Revision, sizeof(Ids->Revision), "%04X", 0);
97 break;
98 }
99}
100
103NTAPI
104HubRegReadValue(
105 _In_ WDFKEY Key,
109{
111
114
116}
117
120static
122NTAPI
123HubRegWalkDword(
124 _In_ WDFKEY Key,
129{
130 *Status = HubRegReadValue(Key, Name, sizeof(*Value), Value);
132
134 return TRUE;
135
136 return *Present;
137}
138
140static
142NTAPI
144 _In_opt_ WDFKEY Parent,
147 _Out_ WDFKEY* Key)
148{
150}
151
153static
155NTAPI
156HubRegOpenPath(
159 _Out_ WDFKEY* Key)
160{
162
165}
166
168static
170NTAPI
171HubRegOpenOrCreate(
172 _In_opt_ WDFKEY Parent,
176 _Out_ WDFKEY* Key)
177{
179
182 return Status;
183
185}
186
188static
190NTAPI
191HubOpenDeviceKey(
194 _Out_ WDFKEY* Key)
195{
196 *Key = NULL;
197
198 if (Child->m_Pdo == NULL || Child->m_Pdo->m_Device == NULL)
200
202}
203
205static
207NTAPI
208HubOpenHubKey(
209 _In_ HubFdo* Hub,
211 _Out_ WDFKEY* Key)
212{
214}
215
216/* Opens usbflags and its VVVVPPPPRRRR subkey, creating both even for a read since user mode tools expect them */
218static
220NTAPI
221HubOpenUsbflagsKeys(
222 _In_ const HubIdStrings* Ids,
224 _Out_ WDFKEY* RootKey,
226{
227 WCHAR Buffer[26];
229 WDFKEY Root;
231
232 *RootKey = NULL;
233 *DeviceKey = NULL;
234
236 Status = HubRegOpenOrCreate(NULL, &Name, Access, Access, &Root);
237 if (!NT_SUCCESS(Status))
238 return Status;
239
242 if (NT_SUCCESS(Status))
243 Status = HubRegOpenOrCreate(Root, &Name, Access, KEY_ALL_ACCESS, DeviceKey);
244
246 {
248 *DeviceKey = NULL;
249 return Status;
250 }
251
252 *RootKey = Root;
254}
255
256/*
257 * Two shim engine lookups, by VID+PID+REV and by VID+PID, merged into one
258 * word. Without the kernel routine, which is the ReactOS case, it stays 0.
259 */
261static
263NTAPI
264HubQueryKseDeviceFlags(
265 _In_ const HubIdStrings* Ids,
267{
268 PCWSTR Bus = RootHub ? L"ROOT_HUB" : L"USB";
269 WCHAR Key[50];
272
274 return 0;
275
278 L"USB:%ls\\VID_%hs&PID_%hs&REV_%hs",
279 Bus,
280 Ids->Vendor,
281 Ids->Product,
282 Ids->Revision)))
283 {
284 return 0;
285 }
286
287 Word = 0;
289 Flags |= Word;
290
293 L"USB:%ls\\VID_%hs&PID_%hs",
294 Bus,
295 Ids->Vendor,
296 Ids->Product)))
297 {
298 return Flags;
299 }
300
301 Word = 0;
303 return Flags | Word;
304}
305
308NTAPI
311 _In_ ULONG Bit)
312{
313 return (Flags & (1ULL << Bit)) != 0;
314}
315
316/* VIA VL810 hubs before revision 0x89 cannot run SuperSpeed; only the low revision byte counts */
317static
319NTAPI
322{
323 return Descriptor->idVendor == 0x2109 &&
324 Descriptor->idProduct == 0x0810 &&
325 (UCHAR)Descriptor->bcdDevice < 0x89;
326}
327
328/* Per device errata */
329
330/* Extra condition on a shim engine bit */
332{
333 None,
335 NotHub
336};
337
338/*
339 * One errata source. With a value name, a present value decides alone
340 * (nonzero sets) and the shim bit only counts when the value is absent.
341 */
343{
348};
349
351{
353 { L"UseWin8DescriptorValidation", 31, HubErrataGate::None, ChildHack::UseWin8DescriptorValidation },
356
358{
359 { L"RequestConfigDescOnReset", 4, HubErrataGate::None, ChildHack::RequestConfigDescOnReset },
360 { L"SkipContainerIdQuery", 5, HubErrataGate::None, ChildHack::SkipContainerIdQuery },
361 { L"DisableLPM", 12, HubErrataGate::None, ChildHack::DisableLpm },
369 { L"SkipBOSDescriptorQuery", 27, HubErrataGate::None, ChildHack::SkipBosQuery },
375};
376
378static
380NTAPI
381HubApplyDeviceErrata(
383 _In_ WDFKEY Key,
387{
388 ULONG Index;
389 ULONG Value;
392
393 for (Index = 0; Index < Count; Index++)
394 {
395 const HubDeviceErrata* Entry = &Table[Index];
396
397 Apply = HubKseBit(Kse, Entry->KseBit);
398
399 if (Entry->Value != NULL)
400 {
401 Status = HubRegReadValue(Key, Entry->Value, sizeof(Value), &Value);
402 if (NT_SUCCESS(Status))
403 Apply = (Value != 0);
405 return Status;
406 }
407 else if (Entry->Gate == HubErrataGate::BehindExternalHub)
408 {
409 Apply = Apply && !Child->m_Hub->IsRootHub();
410 }
411 else if (Entry->Gate == HubErrataGate::NotHub)
412 {
413 Apply = Apply && !Child->HasProperty(ChildProperty::IsHub);
414 }
415
416 if (Apply)
417 Child->m_Hacks |= (ULONG)Entry->Hack;
418 }
419
420 return STATUS_SUCCESS;
421}
422
423/* Pairs of (interface, alternate setting). An older filter is freed once a new one exists. */
425static
426VOID
427NTAPI
430 _In_ WDFKEY Key)
431{
432 DECLARE_CONST_UNICODE_STRING(Name, L"AlternateSettingFilter");
434 ULONG Size = 0;
436
438 return;
439
440 if (Size == 0 || (Size & 1) || Type != REG_BINARY)
441 return;
442
446 if (Filter == NULL)
447 return;
448
449 if (Child->m_AlternateSettingFilter != NULL)
450 ExFreePoolWithTag(Child->m_AlternateSettingFilter, HUB_TAG_DEVICE);
451 Child->m_AlternateSettingFilter = Filter;
452
454 {
456 Child->m_AlternateSettingFilter = NULL;
457 return;
458 }
459
460 Filter->Count = Size / sizeof(Filter->Entries[0]);
461}
462
463/*
464 * Bits only accumulate, except DisableOnSoftRemove, which is forced on and
465 * reread. A read error other than a missing value fails the attempt.
466 */
468static
470NTAPI
471HubQueryDeviceErrata(
474{
475 WCHAR NameBuffer[32];
477 WDFKEY Root;
478 WDFKEY Key;
479 ULONG64 Kse;
480 ULONG Value;
483
484 Status = HubOpenUsbflagsKeys(Ids, KEY_READ, &Root, &Key);
485 if (!NT_SUCCESS(Status))
486 return Status;
487
488 Kse = HubQueryKseDeviceFlags(Ids, FALSE);
489
490 /* Legacy per VID and PID serial number override in the usbflags root */
491 RtlInitEmptyUnicodeString(&Name, NameBuffer, sizeof(NameBuffer));
492 Status = RtlUnicodeStringPrintf(&Name, L"IgnoreHWSerNum%hs%hs", Ids->Vendor, Ids->Product);
493 if (!NT_SUCCESS(Status))
494 goto Done;
495
496 Value = 0;
499 {
500 if (Value != 0)
502 }
504 {
505 goto Done;
506 }
507
508 /* osvc: byte 1 is the vendor code; two zero bytes mean no MS OS descriptor */
509 Status = HubRegReadValue(Key, L"osvc", sizeof(USHORT), &Value);
510 if (NT_SUCCESS(Status))
511 {
512 if ((USHORT)Value != 0)
513 Child->m_MsOsVendorCode = (UCHAR)(Value >> 8);
514 else
516 }
518 {
523 }
524 else
525 {
526 goto Done;
527 }
528
529 Status = HubApplyDeviceErrata(Child,
530 Key,
531 Kse,
534 if (!NT_SUCCESS(Status))
535 goto Done;
536
537 /* On by default for every device; only an explicit zero or the shim turns it off */
539
540 Status = HubRegReadValue(Key, L"DisableOnSoftRemove", sizeof(Value), &Value);
541 if (NT_SUCCESS(Status))
542 {
543 if (Value == 0)
545 }
547 {
550 }
551 else
552 {
553 goto Done;
554 }
555
556 Status = HubApplyDeviceErrata(Child,
557 Key,
558 Kse,
561 if (!NT_SUCCESS(Status))
562 goto Done;
563
564 /* Set info cached by an earlier start: the alternate enumeration command can go out before the descriptors */
565 Status = HubRegReadValue(Key, L"MsOs20DescriptorSetInfo", sizeof(SetInfo), &SetInfo);
566 if (NT_SUCCESS(Status))
567 {
568 Child->m_AltEnumCached = TRUE;
569 Child->m_MsOs20.Flags |= HUB_MSOS20_ALT_ENUM;
570 Child->m_MsOsVendorCode = SetInfo.bVendorCode;
571 Child->m_MsOs20SetInfo = SetInfo;
572 }
574 {
575 goto Done;
576 }
577
578 if (HubIsBrokenVl810(&Child->m_DeviceDescriptor))
580
583
587 return Status;
588}
589
590/*
591 * HardwareVerifier<id><version><value>, trying VID+PID+REV, VID+PID and
592 * global in turn. Only a missing key or value moves on to the next try.
593 */
595static
597NTAPI
598HubQueryVerifierFlags(
600 _In_ const HubIdStrings* Ids,
603{
607 WDFKEY Root;
608 WDFKEY Key;
611
612 *Flags = 0;
613
614 /* bcdUSB 0 is treated as USB 3 */
615 if (Descriptor->bcdUSB == 0 || Descriptor->bcdUSB >= 0x0300)
616 Version = L"usb30";
617 else if (Descriptor->bcdUSB <= 0x0200)
618 Version = L"usbUpto20";
619 else
620 Version = L"usb2X";
621
622 Status = HubRegOpenPath(HubVerifierPath, KEY_READ, &Root);
623 if (!NT_SUCCESS(Status))
624 {
626 DPRINT1("Opening the hardware verifier key failed 0x%lx\n", Status);
627
628 return Status;
629 }
630
631 for (Try = 0; Try < 3; Try++)
632 {
634
635 if (Try == 0)
637 else if (Try == 1)
639 else
640 Status = RtlUnicodeStringPrintf(&Path, L"global\\%ls", Version);
641
642 if (!NT_SUCCESS(Status))
643 break;
644
646 if (NT_SUCCESS(Status))
647 {
648 Status = HubRegReadValue(Key, ValueName, sizeof(*Flags), Flags);
650 }
651
653 break;
654
655 *Flags = 0;
656 }
657
658 if (!NT_SUCCESS(Status))
659 {
661 DPRINT1("Hardware verifier %S flags unreadable 0x%lx\n", ValueName, Status);
662
663 *Flags = 0;
664 }
665
667 return Status;
668}
669
672{
675
677
678 Status = HubQueryDeviceErrata(m_Device, &Ids);
679 HubQueryVerifierFlags(&m_Device->m_DeviceDescriptor, &Ids, L"device", &m_Device->m_VerifierFlags);
680
681 if (!NT_SUCCESS(Status))
682 {
683 DPRINT1("Device %p usbflags query failed 0x%lx\n", m_Device, Status);
685 return FALSE;
686 }
687
688 return TRUE;
689}
690
691/* Hub errata */
692
693/* With a value name, a present value decides alone; the shim bit counts when it is absent */
695{
700};
701
703{
704 { L"ResetTTOnCancel", 8, HubFlag::ResetTtOnCancel, 0 },
705 { L"NoClearTTBufferOnCancel", 9, HubFlag::NoClearTtOnCancel, (ULONG)HubFlag::ResetTtOnCancel },
707 { L"DisableLPM", 12, HubFlag::DisableLpm, 0 },
708 { NULL, 13, HubFlag::DisableUsb20Lpm, 0 },
714};
715
717{
720};
721
723static
725NTAPI
727 _In_ HubFdo* Hub,
728 _In_ WDFKEY Key,
732{
733 ULONG Index;
734 ULONG Value;
737
738 for (Index = 0; Index < Count; Index++)
739 {
740 Apply = HubKseBit(Kse, Table[Index].KseBit);
741
742 if (Table[Index].Value != NULL)
743 {
744 Status = HubRegReadValue(Key, Table[Index].Value, sizeof(Value), &Value);
745 if (NT_SUCCESS(Status))
746 Apply = (Value != 0);
748 return Status;
749 }
750
751 if (!Apply)
752 continue;
753
754 if (Table[Index].Clear != 0)
757 }
758
759 return STATUS_SUCCESS;
760}
761
762/*
763 * A read error other than a missing value ends the query at once,
764 * skipping the DisableOnSoftRemove default and the report.
765 */
767static
769NTAPI
770HubQueryHubErrata(
771 _In_ HubFdo* Hub,
772 _In_ const HubIdStrings* Ids)
773{
774 WDFKEY Root;
775 WDFKEY Key;
776 ULONG64 Kse;
778
779 Status = HubOpenUsbflagsKeys(Ids, KEY_READ, &Root, &Key);
780 if (!NT_SUCCESS(Status))
781 return Status;
782
783 Kse = HubQueryKseDeviceFlags(Ids, Hub->IsRootHub());
784
786 if (!NT_SUCCESS(Status))
787 goto Done;
788
789 /* Either bit turns LPM off for the whole subtree below this hub */
791 {
794 }
795
798
800
804
807
810
813
815 HubSubmitLiveDump(Hub->m_Device, HUB_LIVEDUMP_SUPERSPEED_DISABLED, 0);
816
820 return Status;
821}
822
823/* The hub machine ignores the outcome */
824VOID
826{
829
830 if (m_Hub->IsRootHub())
832 else
834
835 HubQueryVerifierFlags(&m_Hub->m_ParentInfo.DeviceDescriptor, &Ids, L"hub", &m_Hub->m_VerifierFlags);
836
837 Status = HubQueryHubErrata(m_Hub, &Ids);
838 if (!NT_SUCCESS(Status))
839 DPRINT1("Hub %p usbflags query failed 0x%lx\n", m_Hub, Status);
840}
841
842/* Hub hardware key */
843
844/* Missing values are skipped; any other read error ends the reads */
846VOID
847NTAPI
848HubReadHubRegistryValues(
849 _In_ HubFdo* Hub)
850{
851 WDFKEY Key;
852 ULONG Value;
855
856 PAGED_CODE();
857
858 Status = HubOpenHubKey(Hub, KEY_READ, &Key);
859 if (!NT_SUCCESS(Status))
860 {
861 DPRINT1("Hub %p hardware key could not be opened 0x%lx\n", Hub, Status);
862 return;
863 }
864
865 if (!HubRegWalkDword(Key, L"WakeSystemOnConnect", &Value, &Present, &Status))
866 goto Done;
867 if (Present && Value != 0)
869
870 /* Lifetime count survives devnode restarts; it is a 16 bit count */
871 if (!HubRegWalkDword(Key, L"HardResetCount", &Value, &Present, &Status))
872 goto Done;
873 if (Present)
875
876 if (!HubRegWalkDword(Key, L"OvercurrentDetected", &Value, &Present, &Status))
877 goto Done;
878 if (Present)
879 {
880 if (Value & 1)
882 else
884 }
885
886 /* 1 asks for the USB4 router DROM read; a missing value leaves the last one */
887 if (!HubRegWalkDword(Key, L"HubFWUpdateProtocol", &Value, &Present, &Status))
888 goto Done;
889 if (Present)
891
892Done:
894 DPRINT1("Hub %p hardware key read failed 0x%lx\n", Hub, Status);
895
897}
898
905VOID
906NTAPI
907HubReadUsb4HostName(
908 _In_ HubFdo* Hub)
909{
912 WDFSTRING Name;
913 WDFKEY Key;
915
916 PAGED_CODE();
917
918 Status = HubOpenHubKey(Hub, KEY_READ, &Key);
919 if (!NT_SUCCESS(Status))
920 {
921 DPRINT1("Hub %p hardware key not opened for Usb4HostName 0x%lx\n", Hub, Status);
922 return;
923 }
924
926 Attributes.ParentObject = Hub->m_Device;
927
928 Status = WdfStringCreate(NULL, &Attributes, &Name);
929 if (!NT_SUCCESS(Status))
930 {
931 DPRINT1("Hub %p Usb4HostName string not created 0x%lx\n", Hub, Status);
932 goto Done;
933 }
934
935 Status = WdfRegistryQueryString(Key, &ValueName, Name);
936 if (!NT_SUCCESS(Status))
937 {
939 DPRINT1("Hub %p Usb4HostName read failed 0x%lx\n", Hub, Status);
941 goto Done;
942 }
943
945 DPRINT("Hub %p USB4 host name override present\n", Hub);
946
947Done:
949}
950
951static
952VOID
953NTAPI
955 _In_ WDFWORKITEM WorkItem)
956{
957 DECLARE_CONST_UNICODE_STRING(Name, L"OvercurrentDetected");
958 HubFdo* Hub = HubFdo::FromDevice((WDFDEVICE)WdfWorkItemGetParentObject(WorkItem));
959 ULONG Value;
960 WDFKEY Key;
962
964
965 Status = HubOpenHubKey(Hub, KEY_SET_VALUE, &Key);
966 if (NT_SUCCESS(Status))
967 {
968 Status = WdfRegistryAssignValue(Key, &Name, REG_DWORD, sizeof(Value), &Value);
970 }
971
972 if (!NT_SUCCESS(Status))
973 DPRINT1("Hub %p over current record not written 0x%lx\n", Hub, Status);
974
976}
977
978/*
979 * The flag is reloaded at every start and never cleared, so the value is
980 * written once per devnode. A failed work item is not retried.
981 */
983VOID
984NTAPI
985HubNoteHubOverCurrent(
986 _In_ HubFdo* Hub)
987{
990 WDFWORKITEM WorkItem;
992
994 return;
995
997 Config.AutomaticSerialization = TRUE;
998
1000 Attributes.ParentObject = Hub->m_Device;
1001
1002 Status = WdfWorkItemCreate(&Config, &Attributes, &WorkItem);
1003 if (!NT_SUCCESS(Status))
1004 {
1005 DPRINT1("Over current work item failed 0x%lx\n", Status);
1006 return;
1007 }
1008
1010}
1011
1012/* usbflags writes */
1013
1016NTAPI
1017HubWriteUsbflagsValue(
1021 _In_ ULONG Size)
1022{
1025 WDFKEY Root;
1026 WDFKEY Key;
1028
1029 HubFormatIdStrings(&Child->m_DeviceDescriptor, &Ids);
1030
1031 Status = HubOpenUsbflagsKeys(&Ids, KEY_SET_VALUE | KEY_CREATE_SUB_KEY, &Root, &Key);
1032 if (!NT_SUCCESS(Status))
1033 {
1034 DPRINT1("Device %p usbflags value %S: key not opened 0x%lx\n", Child, Name, Status);
1035 return Status;
1036 }
1037
1039 Status = WdfRegistryAssignValue(Key, &ValueName, REG_BINARY, Size, Data);
1040 if (!NT_SUCCESS(Status))
1041 DPRINT1("Device %p usbflags value %S not written 0x%lx\n", Child, Name, Status);
1042
1045 return Status;
1046}
1047
1048/* Read back as row MsOs20DescriptorSetInfo of the errata query on the next enumeration */
1050VOID
1051NTAPI
1054{
1055 if (!(Child->m_MsOs20.Flags & HUB_MSOS20_ALT_ENUM) || Child->m_AltEnumCached)
1056 return;
1057
1058 HubWriteUsbflagsValue(Child, L"MsOs20DescriptorSetInfo", &Child->m_MsOs20SetInfo, sizeof(Child->m_MsOs20SetInfo));
1059 Child->m_AltEnumCached = TRUE;
1060}
1061
1062/* Device hardware key */
1063
1066NTAPI
1070 _In_ ULONG Type,
1073{
1074 WDFKEY Key;
1076
1077 Status = HubOpenDeviceKey(Child, KEY_WRITE, &Key);
1078 if (!NT_SUCCESS(Status))
1079 {
1080 DPRINT1("Device %p value %wZ: hardware key not opened 0x%lx\n", Child, Name, Status);
1081 return Status;
1082 }
1083
1084 Status = WdfRegistryAssignValue(Key, Name, Type, Length, Data);
1085 if (!NT_SUCCESS(Status))
1086 DPRINT1("Device %p value %wZ not written 0x%lx\n", Child, Name, Status);
1087
1089 return Status;
1090}
1091
1094NTAPI
1095HubWriteDeviceString(
1098 _In_ WDFSTRING Value)
1099{
1100 WDFKEY Key;
1102
1103 Status = HubOpenDeviceKey(Child, KEY_WRITE, &Key);
1104 if (!NT_SUCCESS(Status))
1105 {
1106 DPRINT1("Device %p string %wZ: hardware key not opened 0x%lx\n", Child, Name, Status);
1107 return Status;
1108 }
1109
1110 Status = WdfRegistryAssignString(Key, Name, Value);
1111 if (!NT_SUCCESS(Status))
1112 DPRINT1("Device %p string %wZ not written 0x%lx\n", Child, Name, Status);
1113
1115 return Status;
1116}
1117
1119static
1120VOID
1121NTAPI
1122HubWriteDeviceDword(
1126{
1128
1131}
1132
1133/* Presence counts, not the value */
1135VOID
1136NTAPI
1137HubRefreshExtPropertiesInstalled(
1139{
1140 WDFKEY Key;
1141 ULONG Value;
1142
1143 if (!NT_SUCCESS(HubOpenDeviceKey(Child, KEY_READ, &Key)))
1144 return;
1145
1147
1148 if (NT_SUCCESS(HubRegReadValue(Key, L"ExtPropDescSemaphore", sizeof(Value), &Value)))
1150
1152}
1153
1154/* Counted copy without a NUL */
1156static
1158NTAPI
1159HubReadFriendlyName(
1161 _In_ WDFKEY Key,
1162 _In_ WDFSTRING String,
1164{
1165 DECLARE_CONST_UNICODE_STRING(Name, L"FriendlyName");
1169
1170 *Stop = FALSE;
1171
1172 Status = WdfRegistryQueryString(Key, &Name, String);
1174 return Status;
1175
1176 if (!NT_SUCCESS(Status))
1177 {
1178 *Stop = TRUE;
1179 return Status;
1180 }
1181
1183
1184 if (Child->m_FriendlyName != NULL)
1185 {
1186 ExFreePoolWithTag(Child->m_FriendlyName, HUB_TAG_DEVICE);
1187 Child->m_FriendlyName = NULL;
1188 Child->m_FriendlyNameLength = 0;
1189 }
1190
1191 if (Text.Length == 0)
1192 return STATUS_SUCCESS;
1193
1195 if (Copy == NULL)
1196 {
1197 /* The remaining reads are skipped, yet the caller sees success */
1198 DPRINT1("Device %p friendly name could not be allocated\n", Child);
1199 *Stop = TRUE;
1200 return STATUS_SUCCESS;
1201 }
1202
1204 Child->m_FriendlyName = Copy;
1205 Child->m_FriendlyNameLength = Text.Length;
1206
1207 return STATUS_SUCCESS;
1208}
1209
1210/*
1211 * A read error other than a missing value ends the reads, which also skips
1212 * the D3cold reconnect default, so the port keeps its previous timeout.
1213 */
1216NTAPI
1219{
1221 WDFSTRING String = NULL;
1222 WDFKEY Key;
1223 WDFKEY Subkey = NULL;
1224 ULONG Value;
1226 BOOLEAN Stop;
1228
1229 PAGED_CODE();
1230
1231 Status = HubOpenDeviceKey(Child, KEY_READ, &Key);
1232 if (!NT_SUCCESS(Status))
1233 {
1234 DPRINT1("Device %p hardware key could not be opened 0x%lx\n", Child, Status);
1235 return Status;
1236 }
1237
1238 if (!HubRegWalkDword(Key, L"DeviceSelectiveSuspended", &Value, &Present, &Status))
1239 goto Done;
1240 if (Present && Value != 0)
1242
1243 Status = WdfStringCreate(NULL, WDF_NO_OBJECT_ATTRIBUTES, &String);
1244 if (!NT_SUCCESS(Status))
1245 goto Done;
1246
1247 Status = HubReadFriendlyName(Child, Key, String, &Stop);
1248 if (Stop)
1249 goto Done;
1250
1252 Status = HubRegOpen(Key, &SubkeyName, KEY_READ, &Subkey);
1253 if (!NT_SUCCESS(Status))
1254 Subkey = NULL;
1255
1256 if (NT_SUCCESS(Status))
1257 {
1258 if (!HubRegWalkDword(Subkey, L"D3ColdSupported", &Value, &Present, &Status))
1259 goto Done;
1260 if (Present && Value != 0)
1262 }
1264 {
1265 goto Done;
1266 }
1267
1268 if (!HubRegWalkDword(Key, L"AllowIdleIrpInD3", &Value, &Present, &Status))
1269 goto Done;
1270 if (Present && Value != 0)
1272
1273 /* No range check; 0 is accepted */
1274 Child->m_Port->m_D3ColdReconnectTimeout = HUB_D3COLD_RECONNECT_DEFAULT;
1275
1276 if (!HubRegWalkDword(Key, L"D3ColdReconnectTimeout", &Value, &Present, &Status))
1277 goto Done;
1278 if (Present)
1279 Child->m_Port->m_D3ColdReconnectTimeout = Value;
1280
1282
1283Done:
1285 DPRINT1("Device %p hardware key read failed 0x%lx\n", Child, Status);
1286
1287 if (Subkey != NULL)
1288 WdfRegistryClose(Subkey);
1290 if (String != NULL)
1292
1293 return Status;
1294}
1295
1296/* Enumeration data written at PDO start; failures are ignored */
1298VOID
1299NTAPI
1302{
1303 PAGED_CODE();
1304
1305 if (Child->m_MsOs20.Flags & HUB_MSOS20_SET_INFO)
1306 HubWriteDeviceDword(Child, L"MsOs20Flags", Child->m_MsOs20.Flags);
1307
1308 HubWriteDeviceDword(Child, L"EnumerationRetryCount", Child->m_EnumRetryCount);
1309}
1310
1312VOID
1313NTAPI
1314HubWriteEnumerationFailureCode(
1316{
1317 PAGED_CODE();
1318
1319 HubWriteDeviceDword(Child, L"EnumerationFailureCode", Child->m_EnumMessageId);
1320}
1321
1322/* UXD (VM redirection) settings */
1323
1324/* uxd_port_NNN, at least three digits */
1326static
1328NTAPI
1329HubFormatUxdPortName(
1334{
1336 return RtlUnicodeStringPrintf(Name, L"uxd_port_%03u", PortNumber);
1337}
1338
1340static
1342NTAPI
1343HubFormatUxdDeviceName(
1348{
1349 const USB_DEVICE_DESCRIPTOR* Descriptor = &Child->m_DeviceDescriptor;
1350
1353 L"%04X%04X%04X",
1354 Descriptor->idVendor,
1355 Descriptor->idProduct,
1356 Descriptor->bcdDevice);
1357}
1358
1359/* Shorter data leaves the tail zero; longer data fails */
1361static
1363NTAPI
1364HubReadUxdRecord(
1365 _In_ WDFKEY Key,
1368{
1369 RtlZeroMemory(Record, sizeof(*Record));
1371}
1372
1373/*
1374 * Creating the uxd subkey reports success with an all zero record, which
1375 * reserves the device with a zero PnP GUID.
1376 */
1378static
1380NTAPI
1381HubReadUxdPortRecord(
1382 _In_ HubFdo* Hub,
1385{
1386 DECLARE_CONST_UNICODE_STRING(UxdName, L"uxd");
1387 WCHAR Buffer[24];
1389 WDFKEY HubKey;
1390 WDFKEY UxdKey;
1392
1394
1395 Status = HubOpenHubKey(Hub, KEY_READ | KEY_WRITE, &HubKey);
1396 if (!NT_SUCCESS(Status))
1397 return Status;
1398
1399 Status = HubRegOpen(HubKey, &UxdName, KEY_READ, &UxdKey);
1401 {
1403 if (NT_SUCCESS(Status))
1405
1407 return Status;
1408 }
1409
1410 if (NT_SUCCESS(Status))
1411 {
1412 Status = HubFormatUxdPortName(PortNumber, Buffer, RTL_NUMBER_OF(Buffer), &Name);
1413 if (NT_SUCCESS(Status))
1414 Status = HubReadUxdRecord(UxdKey, &Name, Record);
1415
1417 }
1418
1420 return Status;
1421}
1422
1424static
1426NTAPI
1427HubReadUxdDeviceRecord(
1430{
1431 WCHAR Buffer[16];
1433 WDFKEY Key;
1435
1436 RtlZeroMemory(Record, sizeof(*Record));
1437
1438 Status = HubRegOpenPath(HubUxdDevicesPath, KEY_READ, &Key);
1439 if (!NT_SUCCESS(Status))
1440 return Status;
1441
1442 Status = HubFormatUxdDeviceName(Child, Buffer, RTL_NUMBER_OF(Buffer), &Name);
1443 if (NT_SUCCESS(Status))
1444 Status = HubReadUxdRecord(Key, &Name, Record);
1445
1447 return Status;
1448}
1449
1450/*
1451 * The port record wins over the VID/PID/REV record. Without the policy key
1452 * the reserved flag is dropped but the old record stays.
1453 */
1456NTAPI
1458 _In_ HubFdo* Hub,
1461{
1465
1467
1468 if (UpdateRequired != NULL)
1470
1472 Previous = Child->m_Uxd;
1473
1475 return STATUS_SUCCESS;
1476
1478 return STATUS_SUCCESS;
1479
1480 Found = NT_SUCCESS(HubReadUxdPortRecord(Hub, Child->m_Port->Number(), &Current));
1481 if (!Found)
1482 Found = NT_SUCCESS(HubReadUxdDeviceRecord(Child, &Current));
1483
1485 {
1486 DPRINT("Device %p on port %u is reserved for a virtual machine\n", Child, Child->m_Port->Number());
1487 Child->SetProperty(ChildProperty::UxdReserved);
1489 }
1490 else
1491 {
1492 RtlZeroMemory(&Current, sizeof(Current));
1493 }
1494
1495 Child->m_Uxd = Current;
1496
1498 !RtlEqualMemory(&Current, &Previous, sizeof(Current)) &&
1499 !Child->HasProperty(ChildProperty::IsHub))
1500 {
1502 }
1503
1504 return STATUS_SUCCESS;
1505}
1506
1509NTAPI
1510HubPurgeUxdState(
1513{
1514 DECLARE_CONST_UNICODE_STRING(UxdName, L"uxd");
1515 WCHAR Buffer[24];
1517 WDFKEY HubKey;
1518 WDFKEY Key;
1521
1522 PAGED_CODE();
1523
1525
1526 /* DeleteOnReload must be exactly 1; DeleteOnDisconnect any nonzero value */
1528 Delete = Child->m_Uxd.DeleteOnReload == 1 || HubDriver.HasFlag(HubGlobal::UxdDeleteOnReload);
1529 else if (Event == HubUxdEvent::Disconnect)
1530 Delete = Child->m_Uxd.DeleteOnDisconnect != 0 || HubDriver.HasFlag(HubGlobal::UxdDeleteOnDisconnect);
1531 else
1532 Delete = FALSE;
1533
1534 if (!Delete)
1535 return STATUS_SUCCESS;
1536
1537 DPRINT("Device %p UXD records deleted on event %d\n", Child, (int)Event);
1538
1539 if (NT_SUCCESS(HubOpenHubKey(Child->m_Hub, KEY_ALL_ACCESS, &HubKey)))
1540 {
1541 Status = HubRegOpen(HubKey, &UxdName, KEY_ALL_ACCESS, &Key);
1543 {
1546 }
1547 else if (NT_SUCCESS(Status))
1548 {
1549 if (NT_SUCCESS(HubFormatUxdPortName(Child->m_Port->Number(), Buffer, RTL_NUMBER_OF(Buffer), &Name)))
1550 WdfRegistryRemoveValue(Key, &Name);
1552 }
1553
1555 }
1556
1558 {
1559 if (NT_SUCCESS(HubFormatUxdDeviceName(Child, Buffer, RTL_NUMBER_OF(Buffer), &Name)))
1560 WdfRegistryRemoveValue(Key, &Name);
1562 }
1563
1564 return STATUS_SUCCESS;
1565}
1566
1567/* A missing key or value leaves String empty and still succeeds */
1570NTAPI
1571HubQueryUxdDeviceValue(
1573 _In_ WDFSTRING String)
1574{
1576 WDFKEY Key;
1578
1579 PAGED_CODE();
1580
1581 Status = RtlStringFromGUID(Child->m_Uxd.PnpGuid, &GuidText);
1582 if (!NT_SUCCESS(Status))
1583 {
1584 DPRINT1("UXD GUID conversion failed 0x%lx\n", Status);
1585 return STATUS_SUCCESS;
1586 }
1587
1588 Status = HubRegOpenPath(HubUxdPnpPath, KEY_READ, &Key);
1589 if (NT_SUCCESS(Status))
1590 {
1591 Status = WdfRegistryQueryString(Key, &GuidText, String);
1592 if (!NT_SUCCESS(Status))
1593 DPRINT1("UXD PnP value missing 0x%lx\n", Status);
1595 }
1596
1598 return STATUS_SUCCESS;
1599}
1600
1601/*
1602 * Deletes every record marked for deletion at shutdown. Names are cut to 12
1603 * characters and a name over 15 ends the pass.
1604 */
1606static
1607VOID
1608NTAPI
1609HubPurgeUxdRecords(
1610 _In_ WDFKEY Key)
1611{
1612 union
1613 {
1616 } Entry;
1617 HANDLE Handle = WdfRegistryWdmGetHandle(Key);
1620 ULONG Index = 0;
1622
1623 for (;;)
1624 {
1625 RtlZeroMemory(&Entry, sizeof(Entry));
1626
1627 if (!NT_SUCCESS(ZwEnumerateValueKey(Handle, Index, KeyValueBasicInformation, &Entry, sizeof(Entry), &Returned)))
1628 break;
1629
1630 Index++;
1631
1632 if (Entry.Info.Type != REG_BINARY)
1633 continue;
1634
1635 Name.Buffer = Entry.Info.Name;
1636 Name.Length = (USHORT)min(Entry.Info.NameLength, 12 * sizeof(WCHAR));
1637 Name.MaximumLength = Name.Length;
1638
1639 if (!NT_SUCCESS(HubReadUxdRecord(Key, &Name, &Record)))
1640 break;
1641
1642 if (Record.DeleteOnShutdown != 1 && !HubDriver.HasFlag(HubGlobal::UxdDeleteOnShutdown))
1643 continue;
1644
1645 if (!NT_SUCCESS(WdfRegistryRemoveValue(Key, &Name)))
1646 {
1647 DPRINT1("UXD record %wZ could not be deleted at shutdown\n", &Name);
1648 break;
1649 }
1650
1651 /* The next value moved into this slot */
1652 Index--;
1653 }
1654}
1655
1656/* Each hub repeats the global pass; later passes find nothing left */
1658VOID
1659NTAPI
1660HubUxdShutdownCleanup(
1661 _In_ HubFdo* Hub)
1662{
1663 DECLARE_CONST_UNICODE_STRING(UxdName, L"uxd");
1664 WDFKEY HubKey;
1665 WDFKEY Key;
1667
1669
1670 if (NT_SUCCESS(HubRegOpenPath(HubUxdDevicesPath, KEY_ALL_ACCESS, &Key)))
1671 {
1672 HubPurgeUxdRecords(Key);
1674 }
1675
1676 if (!NT_SUCCESS(HubOpenHubKey(Hub, KEY_ALL_ACCESS, &HubKey)))
1677 return;
1678
1679 Status = HubRegOpen(HubKey, &UxdName, KEY_ALL_ACCESS, &Key);
1681 {
1684 }
1685 else if (NT_SUCCESS(Status))
1686 {
1687 HubPurgeUxdRecords(Key);
1689 }
1690
1692}
1693
1694/* Telemetry */
1695
1696/* DeviceInformation bits are only ever added. Validation words 0 to 6 are written; word 7 has no value name. */
1698VOID
1699NTAPI
1702{
1703 DECLARE_CONST_UNICODE_STRING(CeipName, L"Ceip");
1704 DECLARE_CONST_UNICODE_STRING(InformationName, L"DeviceInformation");
1705 DECLARE_CONST_UNICODE_STRING(InterconnectName, L"PortInterconnectType");
1706 WCHAR Buffer[32];
1708 WDFKEY Key;
1709 WDFKEY Ceip;
1711 ULONG Bits;
1712 ULONG Index;
1714
1715 PAGED_CODE();
1716
1717 Status = HubOpenDeviceKey(Child, KEY_READ | KEY_WRITE, &Key);
1718 if (!NT_SUCCESS(Status))
1719 {
1720 DPRINT1("Device %p telemetry: hardware key not opened 0x%lx\n", Child, Status);
1721 return;
1722 }
1723
1725 if (!NT_SUCCESS(Status))
1726 {
1727 DPRINT1("Device %p telemetry: Ceip key not created 0x%lx\n", Child, Status);
1728 goto CloseKey;
1729 }
1730
1731 Status = WdfRegistryQueryULong(Ceip, &InformationName, &Previous);
1733 Previous = 0;
1734 else if (!NT_SUCCESS(Status))
1735 goto CloseCeip;
1736
1737 Status = WdfRegistryAssignULong(Ceip,
1738 &InformationName,
1739 (ULONG)Child->m_SqmFlags | (ULONG)ChildSqm::IsOnXhci | Previous);
1740 if (!NT_SUCCESS(Status))
1741 goto CloseCeip;
1742
1743 Status = WdfRegistryAssignULong(Ceip, &InterconnectName, Child->m_Port->m_InterconnectType);
1744 if (!NT_SUCCESS(Status))
1745 goto CloseCeip;
1746
1747 Bits = 0;
1748 for (Index = 0; Index < RTL_NUMBER_OF(Child->m_ValidationBits); Index++)
1749 Bits |= Child->m_ValidationBits[Index];
1750
1751 if (Bits == 0)
1752 goto CloseCeip;
1753
1754 for (Index = 0; Index < 7; Index++)
1755 {
1757 if (!NT_SUCCESS(RtlUnicodeStringPrintf(&Name, L"DescriptorValidationInfo%lu", Index)))
1758 break;
1759
1760 if (!NT_SUCCESS(WdfRegistryAssignValue(Ceip,
1761 &Name,
1762 REG_DWORD,
1763 sizeof(Child->m_ValidationBits[Index]),
1764 &Child->m_ValidationBits[Index])))
1765 {
1766 DPRINT1("Device %p telemetry: %wZ not written\n", Child, &Name);
1767 break;
1768 }
1769 }
1770
1771CloseCeip:
1772 if (!NT_SUCCESS(Status))
1773 DPRINT1("Device %p telemetry not written 0x%lx\n", Child, Status);
1774
1775 WdfRegistryClose(Ceip);
1776CloseKey:
1778}
1779
1780static
1781VOID
1782NTAPI
1784 _In_ WDFWORKITEM WorkItem)
1785{
1786 HubPdo* Pdo = HubPdo::FromDevice((WDFDEVICE)WdfWorkItemGetParentObject(WorkItem));
1787 HubChild* Child = Pdo->m_Child;
1788
1789 /* The work item is left to its parent here */
1790 if (Child == NULL)
1791 {
1792 DPRINT("PDO %p lost its device before the selective suspend record\n", Pdo);
1793 return;
1794 }
1795
1796 HubWriteDeviceDword(Child,
1797 L"DeviceSelectiveSuspended",
1798 Child->HasProperty(ChildProperty::SupportsSelectiveSuspend) ? 1 : 0);
1799
1801}
1802
1803/* Once written, the device counts as selective suspend capable on every later start */
1805VOID
1806NTAPI
1807HubRecordSelectiveSuspend(
1809{
1812 WDFWORKITEM WorkItem;
1814
1815 if (Child->HasProperty(ChildProperty::SupportsSelectiveSuspend) || Child->m_Pdo == NULL)
1816 return;
1817
1819
1821 Config.AutomaticSerialization = TRUE;
1822
1824 Attributes.ParentObject = Child->m_Pdo->m_Device;
1825
1826 Status = WdfWorkItemCreate(&Config, &Attributes, &WorkItem);
1827 if (!NT_SUCCESS(Status))
1828 {
1829 DPRINT1("Selective suspend work item failed 0x%lx\n", Status);
1830 return;
1831 }
1832
1834}
1835
1836/* Two recoveries at once may lose an increment */
1838VOID
1839NTAPI
1840HubBumpBootSurpriseRemovalCount(VOID)
1841{
1842 DECLARE_CONST_UNICODE_STRING(CountName, L"BootPathSurpriseRemovalCount");
1844 WDFKEY Key;
1845 ULONG Count;
1847
1848 PAGED_CODE();
1849
1852 if (!NT_SUCCESS(Status))
1853 {
1854 DPRINT1("Opening the USB Ceip key failed 0x%lx\n", Status);
1855 return;
1856 }
1857
1858 Status = WdfRegistryQueryULong(Key, &CountName, &Count);
1860 {
1861 Count = 0;
1863 }
1864
1865 if (NT_SUCCESS(Status))
1866 Status = WdfRegistryAssignULong(Key, &CountName, Count + 1);
1867
1868 if (!NT_SUCCESS(Status))
1869 DPRINT1("Updating the boot path surprise removal count failed 0x%lx\n", Status);
1870
1872}
1873
1874/* Dual role features (plain Zw access, outside KMDF) */
1875
1877static
1879NTAPI
1880HubZwOpenKey(
1883{
1885
1889 NULL,
1890 NULL);
1891
1893}
1894
1895/* Succeeds only for exactly 4 bytes of data; the type is not checked */
1897static
1899NTAPI
1900HubZwReadULong(
1904{
1905 union
1906 {
1909 } Data;
1912 HANDLE Handle;
1915
1917 Status = HubZwOpenKey(&KeyPath, &Handle);
1918 if (!NT_SUCCESS(Status))
1919 return Status;
1920
1922 Status = ZwQueryValueKey(Handle, &ValueName, KeyValuePartialInformation, &Data, sizeof(Data), &Returned);
1924
1925 if (!NT_SUCCESS(Status) || Data.Info.DataLength != sizeof(ULONG))
1926 return STATUS_UNSUCCESSFUL;
1927
1929 return STATUS_SUCCESS;
1930}
1931
1932/* Whole value data in paged pool; the caller bounds every string walk by DataLength */
1934static
1936NTAPI
1937HubZwReadData(
1940{
1943 HANDLE Handle;
1944 ULONG Size = 0;
1946
1947 if (!NT_SUCCESS(HubZwOpenKey(Path, &Handle)))
1948 return NULL;
1949
1951
1952 Status = ZwQueryValueKey(Handle, &ValueName, KeyValuePartialInformation, NULL, 0, &Size);
1954 {
1956 if (Info != NULL &&
1958 {
1960 Info = NULL;
1961 }
1962 }
1963
1964 ZwClose(Handle);
1965 return Info;
1966}
1967
1968/* Characters of the string at Text before its NUL, never past Limit */
1969static
1970ULONG
1971NTAPI
1975{
1976 ULONG Length = 0;
1977
1978 while (Length < Limit && Text[Length] != UNICODE_NULL)
1979 Length++;
1980
1981 return Length;
1982}
1983
1984/* Function bits from the USB function configuration InterfaceList */
1986static
1987VOID
1988NTAPI
1989HubAddConfiguredFunctions(
1991{
1992 static const struct
1993 {
1994 PCWSTR Name;
1995 ULONG Bit;
1996 } Functions[] =
1997 {
1998 { L"MTP", HUB_DUAL_ROLE_MTP },
1999 { L"IpOverUsb", HUB_DUAL_ROLE_IP_OVER_USB },
2000 { L"VidStream", HUB_DUAL_ROLE_VIDEO }
2001 };
2007 UNICODE_STRING Match;
2008 PWCHAR PathBuffer;
2009 PCWSTR Chars;
2010 ULONG Count;
2012 ULONG Length;
2013 ULONG Index;
2014 USHORT PathSize;
2015
2017 Current = HubZwReadData(&Path, L"CurrentConfiguration");
2018 if (Current == NULL)
2019 return;
2020
2021 Chars = (PCWSTR)Current->Data;
2022 Text.Length = (USHORT)(HubBoundedLength(Chars, Current->DataLength / sizeof(WCHAR)) * sizeof(WCHAR));
2025
2026 PathSize = (USHORT)(sizeof(HubUsbFnConfigPath) + Text.Length);
2027 PathBuffer = (PWCHAR)ExAllocatePoolWithTag(PagedPool, PathSize, HUB_TAG_DEVICE);
2028 if (PathBuffer == NULL)
2029 goto FreeCurrent;
2030
2031 RtlInitEmptyUnicodeString(&Path, PathBuffer, PathSize);
2034
2035 List = HubZwReadData(&Path, L"InterfaceList");
2036 if (List == NULL)
2037 goto FreePath;
2038
2039 Chars = (PCWSTR)List->Data;
2040 Count = List->DataLength / sizeof(WCHAR);
2041 Position = 0;
2042
2043 while (Position < Count && Chars[Position] != UNICODE_NULL)
2044 {
2046
2047 Entry.Buffer = (PWCHAR)&Chars[Position];
2048 Entry.Length = (USHORT)(Length * sizeof(WCHAR));
2049 Entry.MaximumLength = Entry.Length;
2050
2051 for (Index = 0; Index < RTL_NUMBER_OF(Functions); Index++)
2052 {
2053 RtlInitUnicodeString(&Match, Functions[Index].Name);
2054 if (RtlEqualUnicodeString(&Entry, &Match, TRUE))
2055 *Features |= Functions[Index].Bit;
2056 }
2057
2059 break;
2060
2061 Position += Length + 1;
2062 }
2063
2065FreePath:
2066 ExFreePoolWithTag(PathBuffer, HUB_TAG_DEVICE);
2067FreeCurrent:
2069}
2070
2071/*
2072 * A test override replaces all but the UCM bit. Otherwise the USB function
2073 * list sets the function bits, unless the default configuration is included.
2074 */
2076VOID
2077NTAPI
2078HubQueryLocalDualRoleFeatures(
2080{
2081 ULONG IncludeDefault = 0;
2082 ULONG Value;
2083
2084 PAGED_CODE();
2085
2086 if (!NT_SUCCESS(HubZwReadULong(HubUsbControlPath, L"DualRoleFeaturesTestOverride", Features)))
2087 {
2088 *Features = 0;
2089 HubZwReadULong(HubUsbControlPath, L"DualRoleFeatures", Features);
2090
2091 HubZwReadULong(HubUsbFnDefaultPath, L"IncludeDefaultCfg", &IncludeDefault);
2092 if (NT_SUCCESS(HubZwReadULong(HubUsbFnPath, L"IncludeDefaultCfg", &Value)))
2093 IncludeDefault = Value;
2094
2095 if (IncludeDefault == 0)
2096 {
2097 *Features &= ~HUB_DUAL_ROLE_FUNCTIONS;
2098 HubAddConfiguredFunctions(Features);
2099 }
2100 }
2101
2102 if (NT_SUCCESS(HubZwReadULong(HubUsbControlPath, L"UcmIsPresent", &Value)))
2103 {
2104 if (Value != 0)
2106 else
2107 *Features &= ~HUB_DUAL_ROLE_UCM_PRESENT;
2108 }
2109}
2110
2111/* Device teardown */
2112
2113VOID
2114NTAPI
2117{
2118 if (Child->m_FriendlyName != NULL)
2119 {
2120 ExFreePoolWithTag(Child->m_FriendlyName, HUB_TAG_DEVICE);
2121 Child->m_FriendlyName = NULL;
2122 Child->m_FriendlyNameLength = 0;
2123 }
2124
2125 if (Child->m_MsOs20Set != NULL)
2126 {
2127 ExFreePoolWithTag(Child->m_MsOs20Set, HUB_TAG_DEVICE);
2128 Child->m_MsOs20Set = NULL;
2129 }
2130
2131 if (Child->m_ExtProperties != NULL)
2132 {
2133 ExFreePoolWithTag(Child->m_ExtProperties, HUB_TAG_DEVICE);
2134 Child->m_ExtProperties = NULL;
2135 }
2136}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
Type
Definition: Type.h:7
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
HubFdo * Hub
Definition: bootdev.cpp:261
_In_opt_ PWSTR SubkeyName
Definition: cdrom.h:960
HubWriteEnumerationData(Child)
HubCacheMsOs20SetInfo(Child)
HubReadDeviceHardwareValues(Child)
HubFlushSqmFlags(Child)
Definition: bufpool.h:45
BOOLEAN QueryRegistryValues()
HubChild * m_Device
Definition: devsm.h:1832
USB_DEVICE_DESCRIPTOR m_DeviceDescriptor
Definition: hubchild.h:386
ULONG m_EnumMessageId
Definition: hubchild.h:355
ULONG m_VerifierFlags
Definition: hubchild.h:332
Definition: fdo.h:132
UCXHUB_CONTROLLER_INFO_V2 m_ControllerInfo
Definition: fdo.h:371
WDFSTRING m_Usb4HostName
Definition: fdo.h:464
BOOLEAN m_TunneledDevicesSkipU2
Definition: fdo.h:470
WDFDEVICE m_Device
Definition: fdo.h:349
VOID ClearFlag(_In_ HubFlag Flag)
Definition: fdo.h:167
VOID SetFlag(_In_ HubFlag Flag)
Definition: fdo.h:160
ULONG m_LifetimeRecoveryCount
Definition: fdo.h:436
BOOLEAN HasFlag(_In_ HubFlag Flag) const
Definition: fdo.h:153
ULONG m_VerifierFlags
Definition: fdo.h:443
static HubFdo * FromDevice(_In_ WDFDEVICE Device)
Definition: fdo.cpp:37
ULONG m_FwUpdateProtocol
Definition: fdo.h:453
HubParentInfo m_ParentInfo
Definition: fdo.h:360
volatile LONG m_Flags
Definition: fdo.h:352
BOOLEAN IsRootHub() const
Definition: fdo.h:174
VOID QueryErrataFlags()
HubFdo * m_Hub
Definition: hubsm.h:574
static HubPdo * FromDevice(_In_ WDFDEVICE Device)
Definition: childpdo.cpp:180
PUCHAR Limit
Definition: desccheck.cpp:2230
#define HUB_MSOS20_ALT_ENUM
Definition: desccheck.h:490
#define HUB_MSOS20_SET_INFO
Definition: desccheck.h:488
_In_ BOOLEAN _In_ ULONG Features
Definition: devdesc.cpp:445
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
KEVENT Done
Definition: devreq.cpp:1162
_In_ ULONG Attributes
Definition: dispmprt.h:1077
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG Event
Definition: dispmprt.h:1287
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ ULONG _In_ ULONG Flags
Definition: dispmprt.h:245
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
MIXER_STATUS CloseKey(IN HANDLE hKey)
Definition: mmixer.c:97
#define L(x)
Definition: resources.c:13
#define _IRQL_requires_max_(irql)
Definition: driverspecs.h:230
#define _IRQL_requires_(irql)
Definition: driverspecs.h:229
return WdfRegistryOpenKey(NULL, &KeyName, Access, WDF_NO_OBJECT_ATTRIBUTES, Key)
HubDriverState HubDriver
Definition: entry.cpp:13
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define NonPagedPool
Definition: env_spec_w32.h:307
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define PagedPool
Definition: env_spec_w32.h:308
Status
Definition: gdiplustypes.h:24
ASMGENDATA Table[]
Definition: genincdata.c:61
@ D3ColdEnabledByDriver
ChildHack
Definition: hubchild.h:23
@ ResetAfterIdleResume
@ ResetAfterSystemResume
@ DisableRemoteWakeForUsb20Lpm
@ TolerateStalePipes
@ AlwaysSecondReset
@ UseWin8DescriptorValidation
@ DisableSerialNumber
@ IgnoreBosValidationFailure
@ RequestConfigDescOnReset
@ DisableOnSoftRemove
@ DisableSuperSpeed
@ SkipContainerIdQuery
@ NoExitLatencyRequest
@ NoIsochDelayRequest
@ SupportsSelectiveSuspend
@ DisableUxdSupport
@ UxdDeleteOnReload
@ UxdDeleteOnDisconnect
@ UxdDeleteOnShutdown
#define HUB_LIVEDUMP_SUPERSPEED_DISABLED
Definition: hubdriver.h:153
HubSaveUxdState(Child->m_Hub, Child, NULL)
_In_ PCUNICODE_STRING _In_ ACCESS_MASK Access
return HubRegOpen(NULL, &Name, Access, Key)
else Version
#define HUB_D3COLD_RECONNECT_DEFAULT
Definition: hubregistry.cpp:37
static const WCHAR HubVerifierPath[]
Definition: hubregistry.cpp:16
WdfStringGetUnicodeString(String, &Text)
UNICODE_STRING KeyPath
_In_ PCUNICODE_STRING _In_ ACCESS_MASK _In_ ACCESS_MASK CreateAccess
_Out_ PHANDLE Handle
Previous
static const WCHAR HubUsbControlPath[]
Definition: hubregistry.cpp:24
HubMsOs20SetInfo SetInfo
_In_ WDFKEY _In_ WDFSTRING _Out_ PBOOLEAN Stop
_In_ PCWSTR _In_ ULONG Size
_In_ const HubIdStrings * Ids
ULONG64 Flags
static const HubHubErrata HubHubErrataSecond[]
return RtlUnicodeStringPrintf(Name, L"uxd_port_%03u", PortNumber)
static const HubDeviceErrata HubDeviceErrataBeforeSoftRemove[]
PWCHAR Copy
#define KSE_LPM_OFF_DOWNSTREAM
Definition: hubregistry.cpp:44
WDFKEY Root
_In_ PCUNICODE_STRING _In_ ACCESS_MASK OpenAccess
VOID NTAPI HubFormatIdStrings(_In_ const USB_DEVICE_DESCRIPTOR *Descriptor, _Out_ HubIdStrings *Ids)
Definition: hubregistry.cpp:59
static const WCHAR HubUsbflagsPath[]
Definition: hubregistry.cpp:14
static const HubHubErrata HubHubErrataFirst[]
BOOLEAN Found
_In_ WDFKEY _In_ ULONG64 _In_ ULONG Count
BOOLEAN Apply
WDFKEY HubKey
return ZwOpenKey(Handle, KEY_READ, &Attributes)
ULONG Returned
static const HubDeviceErrata HubDeviceErrataAfterSoftRemove[]
_In_ ACCESS_MASK _Out_ WDFKEY _Out_ WDFKEY * DeviceKey
RtlInitEmptyUnicodeString(Name, Buffer,(USHORT)(Count *sizeof(WCHAR)))
HubAltSettingFilter * Filter
return WdfDeviceOpenRegistryKey(Child->m_Pdo->m_Device, PLUGPLAY_REGKEY_DEVICE, Access, WDF_NO_OBJECT_ATTRIBUTES, Key)
_In_ PCWSTR _Out_ PULONG _Out_ PBOOLEAN _Inout_ NTSTATUS * Status
#define KSE_NO_U2_FOR_TUNNELED_DEVICES
Definition: hubregistry.cpp:46
#define HUB_DUAL_ROLE_UCM_PRESENT
Definition: hubregistry.cpp:53
PAGED_CODE()
return Info
HubErrataGate
HubReadUxdPolicy()
#define HUB_DUAL_ROLE_MTP
Definition: hubregistry.cpp:49
ULONG Try
if Status return TRUE
return STATUS_SUCCESS
static const WCHAR HubUxdDevicesPath[]
Definition: hubregistry.cpp:18
HubWriteDeviceValue(Child, &ValueName, REG_DWORD, sizeof(Value), &Value)
_In_ const HubIdStrings _In_ PCWSTR ValueName
static const WCHAR HubUsbFnDefaultPath[]
Definition: hubregistry.cpp:28
#define HUB_DUAL_ROLE_IP_OVER_USB
Definition: hubregistry.cpp:50
UNICODE_STRING Text
static const WCHAR HubGlobalCeipPath[]
Definition: hubregistry.cpp:22
_In_ PCUNICODE_STRING _In_ ULONG _In_ ULONG Length
_In_ WDFKEY _In_ ULONG64 Kse
VOID NTAPI HubReleaseRegistryState(_In_ HubChild *Child)
WdfRegistryClose(Root)
static ULONG NTAPI HubBoundedLength(_In_reads_(Limit) PCWSTR Text, _In_ ULONG Limit)
#define KSE_DONT_SKIP_MS_OS
Definition: hubregistry.cpp:41
static VOID NTAPI HubEvtOverCurrentWorkItem(_In_ WDFWORKITEM WorkItem)
#define KSE_POLLING_TO_COMPLIANCE
Definition: hubregistry.cpp:45
ULONG64 Word
#define HUB_DUAL_ROLE_FUNCTIONS
Definition: hubregistry.cpp:52
_In_ PCWSTR _Out_ PULONG Value
BOOLEAN Delete
HubReadAlternateSettingFilter(Child, Key)
static VOID NTAPI HubFormatControllerIds(_In_ const UCXHUB_CONTROLLER_INFO_V2 *Info, _Out_ HubIdStrings *Ids)
Definition: hubregistry.cpp:72
#define KSE_SKIP_MS_OS
Definition: hubregistry.cpp:40
RtlFreeUnicodeString & GuidText
HubUxdSettings Current
HubApplyHubErrata(Hub, Key, Kse, HubHubErrataSecond, RTL_NUMBER_OF(HubHubErrataSecond))
_In_ HubChild _Out_opt_ PBOOLEAN UpdateRequired
FORCEINLINE BOOLEAN NTAPI HubKseBit(_In_ ULONG64 Flags, _In_ ULONG Bit)
static const WCHAR HubUsbFnPath[]
Definition: hubregistry.cpp:26
return WdfRegistryCreateKey(Parent, Name, CreateAccess, REG_OPTION_NON_VOLATILE, NULL, WDF_NO_OBJECT_ATTRIBUTES, Key)
static VOID NTAPI HubEvtSelectiveSuspendWorkItem(_In_ WDFWORKITEM WorkItem)
#define KSE_KEEP_ON_SOFT_REMOVE
Definition: hubregistry.cpp:42
_In_ ACCESS_MASK _Out_ WDFKEY * RootKey
_In_ PCWSTR Name
static const WCHAR HubUxdPnpPath[]
Definition: hubregistry.cpp:20
_In_ PCUNICODE_STRING _Out_ HubUxdSettings * Record
return WdfRegistryQueryValue(Key, Name, sizeof(*Record), Record, NULL, NULL)
WDFKEY UxdKey
#define HUB_DUAL_ROLE_VIDEO
Definition: hubregistry.cpp:51
#define KSE_LPM_OFF_FOR_CHAINED_HUBS
Definition: hubregistry.cpp:43
static const WCHAR HubUsbFnConfigPath[]
Definition: hubregistry.cpp:30
UNICODE_STRING Path
ZwClose(Handle)
static const WCHAR HubD3ColdSubkey[]
Definition: hubregistry.cpp:34
_In_ PCUNICODE_STRING _In_ ACCESS_MASK _Out_ WDFKEY * Key
static BOOLEAN NTAPI HubIsBrokenVl810(_In_ const USB_DEVICE_DESCRIPTOR *Descriptor)
_In_ PCWSTR _Out_ PULONG _Out_ PBOOLEAN Present
#define HUB_MSG_REGISTRY_FAILURE
Definition: hubregistry.h:11
HubUxdEvent
Definition: hubsvc.h:328
ULONG Chars
Definition: hubtunnel.cpp:833
WdfWorkItemEnqueue(WorkItem)
_In_opt_ PVOID _In_ PUCXHUB_WORKITEM WorkItem
Definition: hubucx.h:227
_In_ ULONG PortNumber
Definition: hubucx.h:272
_In_ UCXUSBDEVICE _In_ PDEVICE_OBJECT Pdo
Definition: hubucx.h:280
#define HUB_TAG_DEVICE
Definition: hubutil.h:13
#define InterlockedOr
Definition: interlocked.h:239
#define InterlockedAnd
Definition: interlocked.h:77
#define RtlEqualMemory(dst, src, len)
Definition: kdvm.h:18
_In_opt_ PVOID _Out_ BOOLEAN * Stop
Definition: ldrtypes.h:258
if(dx< 0)
Definition: linetemp.h:194
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
unsigned __int64 ULONG64
Definition: imports.h:198
static const ENTRY Entries[]
static PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
static void Clear(void)
Definition: treeview.c:388
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
#define min(a, b)
Definition: monoChain.cc:55
#define _In_reads_bytes_(s)
Definition: no_sal2.h:170
#define _In_reads_(s)
Definition: no_sal2.h:168
#define _Out_opt_
Definition: no_sal2.h:214
#define _Inout_
Definition: no_sal2.h:162
#define _Out_writes_(s)
Definition: no_sal2.h:176
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define _Out_writes_bytes_(s)
Definition: no_sal2.h:178
#define REG_BINARY
Definition: nt_native.h:1499
@ KeyValueBasicInformation
Definition: nt_native.h:1183
@ KeyValuePartialInformation
Definition: nt_native.h:1185
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define KEY_ALL_ACCESS
Definition: nt_native.h:1044
#define KEY_READ
Definition: nt_native.h:1026
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1021
ULONG ACCESS_MASK
Definition: nt_native.h:40
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1060
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define KEY_WRITE
Definition: nt_native.h:1034
#define REG_NONE
Definition: nt_native.h:1495
#define KEY_SET_VALUE
Definition: nt_native.h:1020
#define UNICODE_NULL
#define ANSI_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1148
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
static BOOL Set
Definition: pageheap.c:10
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
@ Raw
Definition: sacdrv.h:279
#define REG_DWORD
Definition: sdbapi.c:615
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define DPRINT
Definition: sndvol32.h:73
Data(int index, int value)
Definition: sort_test.cpp:78
struct HubAltSettingFilter::@1629 Entries[ANYSIZE_ARRAY]
HubErrataGate Gate
PFN_HUB_KSE_QUERY_DEVICE_FLAGS KseQueryDeviceFlags
Definition: hubdriver.h:111
BOOLEAN HasFlag(_In_ HubGlobal Flag) const
Definition: hubdriver.h:119
CHAR Revision[MAX_REVISION_ID_STRING_LENGTH]
Definition: hubregistry.h:18
CHAR Vendor[MAX_VENDOR_ID_STRING_LENGTH]
Definition: hubregistry.h:16
CHAR Product[MAX_DEVICE_ID_STRING_LENGTH]
Definition: hubregistry.h:17
USB_DEVICE_DESCRIPTOR DeviceDescriptor
Definition: fdo.h:89
ULONG Flags
Definition: fdo.h:100
USHORT MaximumLength
Definition: env_spec_w32.h:370
static COORD Position
Definition: mouse.c:34
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
unsigned char UCHAR
Definition: typedefs.h:53
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
int32_t * PLONG
Definition: typedefs.h:58
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
@ UcxControllerParentBusTypePci
Definition: ucxcontroller.h:17
@ UcxControllerParentBusTypeAcpi
Definition: ucxcontroller.h:18
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG Config
_Must_inspect_result_ _In_ UCXCONTROLLER _In_ PUCX_ROOTHUB_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ UCXROOTHUB * RootHub
Definition: ucxroothub.h:299
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define MAXLONG
Definition: umtypes.h:116
#define HUB_PARENT_DISABLE_LPM
Definition: fdo.h:106
HubFlag
Definition: fdo.h:12
@ OverCurrentDetected
@ PollingToComplianceOnStart
@ ToleratesU0WhileDetached
@ DelayAfterResetComplete
@ NoSelectiveSuspendIntegrated
@ DisableUsb20Lpm
@ ResetTtOnCancel
@ DisallowU2AcceptOnly
@ IgnoreEnabledInSsInactive
@ PowerOnPortsOnStart
@ DisableOnSoftRemove
@ NoClearTtOnCancel
@ WakeOnConnect
@ DisableSuperSpeed
@ DiscardEnableDuringReset
WdfObjectDelete(String)
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_In_ WDFCOLLECTION _In_ ULONG Index
#define DECLARE_CONST_UNICODE_STRING(_variablename, _string)
Definition: wdfcore.h:161
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2439
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE _In_ USHORT _In_ USHORT Version
Definition: wdffdo.h:469
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFDEVICE Child
Definition: wdffdo.h:536
FORCEINLINE VOID WDF_OBJECT_ATTRIBUTES_INIT(_Out_ PWDF_OBJECT_ATTRIBUTES Attributes)
Definition: wdfobject.h:147
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
#define FORCEINLINE
Definition: wdftypes.h:67
#define WDF_NO_OBJECT_ATTRIBUTES
Definition: wdftypes.h:105
FORCEINLINE VOID WDF_WORKITEM_CONFIG_INIT(_Out_ PWDF_WORKITEM_CONFIG Config, _In_ PFN_WDF_WORKITEM EvtWorkItemFunc)
Definition: wdfworkitem.h:85
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
#define PLUGPLAY_REGKEY_DEVICE
Definition: iofuncs.h:2812