ReactOS 0.4.17-dev-1281-g065abb3
desccheck.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: Descriptor validation for devices and hubs
5 * COPYRIGHT: Copyright 2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8#include "usbhub3.h"
9
10#define NDEBUG
11#include <debug.h>
12
13/* Outcome of one descriptor check */
14enum class Verdict : UCHAR
15{
16 Ok,
17 Failed,
18 Fatal
19};
20
21/* When a finding fails the descriptor; it is always logged */
22enum class Gate : UCHAR
23{
24 Always,
25 Legacy,
26 NewRule,
28 Cap20,
29 CapSs,
30 CapSsp,
32 LogOnly,
34};
35
36/* Newest dwWindowsVersion an MS OS 2.0 descriptor set may target: the one the hub reports */
37#define HUB_MSOS20_NEWEST_VERSION NTDDI_WIN11_GE
38
39/* MS OS 2.0 subsets never nest this deep in a sane device */
40#define HUB_MSOS20_MAX_DEPTH 8
41
43 { 0xD8DD60DF, 0x4589, 0x4CC7, { 0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F } };
44
46 { 0xA6C10D69, 0x5E2F, 0x480D, { 0xA5, 0x23, 0x52, 0xC0, 0x56, 0xFA, 0xD4, 0xB4 } };
47
48/* Walk state for one configuration descriptor set */
50{
72};
73
74/* Walk state for one BOS descriptor set */
75struct BosWalk
76{
85};
86
87/* Context and logging */
88
89VOID
93 _In_ USHORT BcdUsb,
95 _In_ BOOLEAN Win8Behavior,
96 _In_ ULONG SspIsochBurstCount,
98{
99 RtlZeroMemory(Context, sizeof(*Context));
100 Context->BcdUsb = BcdUsb;
101 Context->Speed = Speed;
105 Context->Win8Behavior = Win8Behavior;
106 Context->SspIsochBurstCount = SspIsochBurstCount;
107 Context->Bitmap = Bitmap;
108}
109
110VOID
111NTAPI
114 _In_ USHORT BcdUsb,
116{
117 RtlZeroMemory(Context, sizeof(*Context));
118 Context->BcdUsb = BcdUsb;
119 Context->Speed = Speed;
120 Context->ForHub = TRUE;
121}
122
123/* Name of a validation code for the debug log */
124#define HUB_DESC_NAME(Code) case HubDescCode::Code: return #Code
125
126PCSTR
127NTAPI
130{
131 switch (Code)
132 {
373
374 default:
375 return "Unknown";
376 }
377}
378
379#undef HUB_DESC_NAME
380
381VOID
382NTAPI
387{
388 ULONG Bit = (ULONG)Code;
389
390 /* Warnings set the same bit as errors */
391 if (Context->Bitmap != NULL && Bit < HUB_DESC_BITMAP_ULONGS * 32)
392 Context->Bitmap[Bit / 32] |= 1UL << (Bit % 32);
393
394 if (Context->Log != NULL)
395 {
396 Context->Log(Context->LogContext, Code, Warning);
397 return;
398 }
399
400 /* Warning also covers findings whose gate does not apply to this device */
401 if (Warning)
402 {
403 DPRINT("%s %p descriptor check %s (%lu) ignored\n",
404 Context->ForHub ? "Hub" : "Device", Context->LogContext, HubDescCodeName(Code), Bit);
405 }
406 else
407 {
408 DPRINT1("%s %p descriptor check %s (%lu) failed\n",
409 Context->ForHub ? "Hub" : "Device", Context->LogContext, HubDescCodeName(Code), Bit);
410 }
411}
412
413/* Shared helpers */
414
415static
417NTAPI
419 _In_ const HubDescContext* Ctx,
420 _In_ Gate Kind)
421{
422 USHORT Bcd = Ctx->BcdUsb;
423 BOOLEAN Newer = Ctx->Strictest || Bcd > 0x0200;
424
425 switch (Kind)
426 {
427 case Gate::Always:
428 return TRUE;
429
430 case Gate::Legacy:
431 return Newer || Ctx->LegacyStrict;
432
433 case Gate::NewRule:
434 return Newer;
435
436 case Gate::Versioned:
437 return Ctx->Strictest ||
438 (Bcd >= 0x0201 && Bcd <= 0x0210) ||
439 (Bcd >= 0x0300 && Bcd <= 0x0310);
440
441 /* QUIRK: 0x0210 itself is excluded for the USB 2.0 extension */
442 case Gate::Cap20:
443 return Ctx->Strictest || (Bcd >= 0x0201 && Bcd < 0x0210);
444
445 case Gate::CapSs:
446 return Ctx->Strictest || (Bcd >= 0x0300 && Bcd <= 0x0310);
447
448 case Gate::CapSsp:
449 return Ctx->Strictest || Bcd == 0x0310;
450
451 case Gate::Reserved:
452 return Ctx->ReservedFields;
453
454 default:
455 return FALSE;
456 }
457}
458
460static
461VOID
462NTAPI
464 _In_ const HubDescContext* Ctx,
467 _In_ Gate Kind)
468{
469 BOOLEAN Enforced = GateApplies(Ctx, Kind);
470
471 /* Only an enforced finding prints as an error */
472 HubDescLog(Ctx, Code, !Enforced);
473 if (Enforced)
475}
476
478static
479VOID
480NTAPI
482 _In_ const HubDescContext* Ctx,
485{
488}
489
491static
492VOID
493NTAPI
495 _In_ const HubDescContext* Ctx,
497{
498 if (Ctx->Win8Behavior)
500}
501
503static
505NTAPI
507 _In_ const HubDescContext* Ctx,
510 _In_ Gate Kind,
512 _In_ ULONG Left,
514{
515 Note(Ctx, Result, Code, Kind);
516 if (Size > Left)
517 {
519 return FALSE;
520 }
521
522 *Advance = Size;
523 return TRUE;
524}
525
526static
528NTAPI
530 _In_reads_(8) const ULONG* Bits,
532{
533 return (Bits[Index / 32] & (1UL << (Index % 32))) != 0;
534}
535
536static
537VOID
538NTAPI
540 _Inout_updates_(8) PULONG Bits,
542{
543 Bits[Index / 32] |= 1UL << (Index % 32);
544}
545
546static
548NTAPI
552{
553 const UCHAR* Bytes = (const UCHAR*)Buffer;
554 ULONG i;
555
556 for (i = 0; i < Length; i++)
557 {
558 if (Bytes[i] != 0)
559 return FALSE;
560 }
561
562 return TRUE;
563}
564
566static
568NTAPI
571{
572 return Size == 8 || Size == 16 || Size == 32 || Size == 64;
573}
574
576static
577ULONG
578NTAPI
582 _In_ const VOID* Descriptor)
583{
584 return BufferLength - (ULONG)((const UCHAR*)Descriptor - Base);
585}
586
587/* Common header of every descriptor inside a configuration or BOS set */
588static
589VOID
590NTAPI
592 _In_ const HubDescContext* Ctx,
599{
600 ULONG Left = BytesLeft(Base, BufferLength, Desc);
601
603 if (Left < sizeof(*Desc))
604 {
605 *Advance = 0;
607 return;
608 }
609
610 *Advance = Desc->bLength;
611 if (Desc->bLength > Left)
612 {
614 *Advance = Left;
615 }
616
617 if (Desc->bLength > (ULONG)(End - (PUCHAR)Desc))
619
620 if (Desc->bLength < sizeof(*Desc))
622
623 if (Desc->bLength == 0)
624 {
628 }
629}
630
631/* Configuration descriptor set */
632
633static
634VOID
635NTAPI
639{
640 const HubDescContext* Ctx = Walk->Ctx;
642 ULONG Needed;
643
644 /* A short or mistyped header is Fatal, but a later finding can still make it Failed */
645 if (Config->bLength < sizeof(*Config))
647
648 if (Config->bLength > sizeof(*Config))
650
651 if (Config->bDescriptorType != USB_CONFIGURATION_DESCRIPTOR_TYPE)
653
654 if (Walk->BufferLength < sizeof(*Config))
655 {
657 return;
658 }
659
660 Needed = sizeof(*Config) + Config->bNumInterfaces * sizeof(USB_INTERFACE_DESCRIPTOR);
661 if (Needed > Walk->BufferLength)
663
664 Walk->End = Walk->Base + Config->wTotalLength;
665 if (Config->wTotalLength > Walk->BufferLength)
666 {
668 Walk->End = Walk->Base + Walk->BufferLength;
669 }
670
671 if (Config->wTotalLength < Needed)
672 {
674 Walk->End = Walk->Base + Walk->BufferLength;
675 }
676}
677
679static
680VOID
681NTAPI
685{
686 const HubDescContext* Ctx = Walk->Ctx;
687
689 if (!Walk->HadEndpoint)
690 {
691 Walk->HadEndpoint = TRUE;
692 }
693 else if (Ctx->Speed == UsbSuperSpeed)
694 {
695 if (!Walk->GotCompanion)
697
698 if (Walk->WantSspCompanion && !Walk->GotSspCompanion)
700 }
701
702 Walk->GotCompanion = FALSE;
703 Walk->WantCompanion = FALSE;
704 Walk->GotSspCompanion = FALSE;
705 Walk->WantSspCompanion = FALSE;
706}
707
709static
710VOID
711NTAPI
715{
717 if (!Walk->HadInterface)
718 {
719 Walk->HadInterface = TRUE;
720 return;
721 }
722
724 if (*Result == Verdict::Fatal)
725 return;
726
727 /* QUIRK: one code for too few and too many endpoints */
728 if (Walk->EndpointsCounted != Walk->EndpointsDeclared)
730}
731
732static
733VOID
734NTAPI
740{
741 const HubDescContext* Ctx = Walk->Ctx;
742 ULONG Left = BytesLeft(Walk->Base, Walk->BufferLength, Desc);
744 BOOLEAN NewNumber;
746 UCHAR Alternate;
747
749 *Advance = Desc->bLength;
750
751 if (Desc->bLength < sizeof(*Desc) &&
753 {
754 return;
755 }
756
757 if (Desc->bLength > sizeof(*Desc))
759
760 if (*Advance > Left)
761 {
763 return;
764 }
765
766 Number = Desc->bInterfaceNumber;
767 Alternate = Desc->bAlternateSetting;
768 First = !Walk->HadInterface;
769 NewNumber = First || Number != Walk->Interface;
770
771 /* In compatibility mode this forgives the length findings above */
773 if (*Result == Verdict::Fatal)
774 return;
775
776 if (NewNumber)
777 {
778 if (BitIsSet(Walk->InterfaceSeen, Number))
780
781 if (!First && Walk->Interface > Number)
783
784 if (Alternate != 0)
786
787 RtlZeroMemory(Walk->AlternateSeen, sizeof(Walk->AlternateSeen));
788 BitSet(Walk->InterfaceSeen, Number);
789 Walk->InterfacesFound++;
790 Walk->Interface = Number;
791 }
792 else
793 {
794 if (BitIsSet(Walk->AlternateSeen, Alternate))
796
797 if (Walk->Alternate >= Alternate)
799 }
800
801 RtlZeroMemory(Walk->EndpointSeen, sizeof(Walk->EndpointSeen));
802 Walk->EndpointsCounted = 0;
803 Walk->EndpointsDeclared = Desc->bNumEndpoints;
804 Walk->HadEndpoint = FALSE;
805 BitSet(Walk->AlternateSeen, Alternate);
806 Walk->Alternate = Alternate;
807}
808
809/* Packet size, interval and attribute rules per transfer type and speed */
810static
811VOID
812NTAPI
817{
818 const HubDescContext* Ctx = Walk->Ctx;
819 USB_DEVICE_SPEED Speed = Ctx->Speed;
820 ULONG Packet = Desc->wMaxPacketSize;
821 ULONG Size = Packet & 0x7FF;
822 ULONG Mult = (Packet >> 11) & 0x3;
823 ULONG Spare = Packet >> 13;
824 UCHAR Extra = Desc->bmAttributes & ~USB_ENDPOINT_TYPE_MASK;
825 BOOLEAN BadInterval = Desc->bInterval == 0 || Desc->bInterval > 16;
826
827 switch (Desc->bmAttributes & USB_ENDPOINT_TYPE_MASK)
828 {
830 if (Extra != 0)
832
833 if (Speed == UsbLowSpeed && Packet != 8)
834 {
836 (Packet > 8 || Packet == 0) ? Gate::Always : Gate::Versioned);
837 }
838 else if (Speed == UsbFullSpeed && !IsSmallPacket(Packet))
839 {
841 }
842 else if ((Speed == UsbHighSpeed && Packet != 64) || (Speed == UsbSuperSpeed && Packet != 512))
843 {
845 }
846 break;
847
849 /* SuperSpeed interrupt attribute bits are not looked at */
850 if (Speed != UsbSuperSpeed && Extra != 0)
852
853 if (Speed == UsbLowSpeed)
854 {
855 if (Packet > 8)
857
858 if (Packet == 0)
860 }
861 else if (Speed == UsbFullSpeed)
862 {
863 if (Packet > 64)
865 }
866 else if (Speed == UsbHighSpeed)
867 {
868 if (Size > 1024)
870
871 if (Spare != 0)
873
874 if (Mult == 3)
876 }
877 else if (Speed == UsbSuperSpeed && Packet > 1024)
878 {
880 }
881
882 /* High speed intervals are not looked at */
883 if ((Speed == UsbLowSpeed || Speed == UsbFullSpeed) && Desc->bInterval == 0)
885 break;
886
888 if (Extra != 0)
890
891 if (Speed == UsbLowSpeed)
893 else if (Speed == UsbFullSpeed && !IsSmallPacket(Packet))
895 else if ((Speed == UsbHighSpeed && Packet != 512) || (Speed == UsbSuperSpeed && Packet != 1024))
897 break;
898
900 /* Logged, never enforced */
901 if (Walk->Alternate == 0 && Packet > 0)
903
904 if (Speed == UsbLowSpeed)
905 {
907 break;
908 }
909
910 if (Speed == UsbFullSpeed)
911 {
912 if (Packet > 1023)
914 }
915 else if (Speed == UsbHighSpeed)
916 {
917 if (Size > 1024)
919
920 if (Spare != 0)
922
923 if (Mult == 3)
925 }
926 else if (Speed == UsbSuperSpeed)
927 {
928 if (Packet > 1024)
930 }
931 else
932 {
933 break;
934 }
935
936 if (BadInterval)
938 break;
939 }
940}
941
942static
943VOID
944NTAPI
950{
951 const HubDescContext* Ctx = Walk->Ctx;
952 ULONG Left = BytesLeft(Walk->Base, Walk->BufferLength, Desc);
953
955 *Advance = Desc->bLength;
956
958 if (*Result == Verdict::Fatal)
959 return;
960
961 if (Desc->bLength < sizeof(*Desc) &&
963 {
964 return;
965 }
966
967 /* Audio class endpoints are 9 bytes long */
968 if (Desc->bLength > sizeof(*Desc))
970
971 if (*Advance > Left)
972 {
974 return;
975 }
976
977 if (!Walk->HadInterface)
978 {
980 return;
981 }
982
983 if ((Desc->bEndpointAddress & 0x0F) == 0)
985
986 if (Desc->bEndpointAddress & 0x70)
988
989 if (Desc->bmAttributes & 0xC0)
991
993
994 if (BitIsSet(Walk->EndpointSeen, Desc->bEndpointAddress))
996
997 BitSet(Walk->EndpointSeen, Desc->bEndpointAddress);
998 Walk->EndpointsCounted++;
999 Walk->GotCompanion = FALSE;
1000 Walk->WantCompanion = TRUE;
1001 Walk->LastEndpoint = Desc;
1002}
1003
1004static
1005VOID
1006NTAPI
1012{
1013 const HubDescContext* Ctx = Walk->Ctx;
1014 ULONG Left = BytesLeft(Walk->Base, Walk->BufferLength, Desc);
1016 ULONG Packet;
1017 ULONG Burst;
1019 ULONG Mult;
1020 ULONG Ceiling;
1021 BOOLEAN SspFollows;
1022
1024 *Advance = Desc->bLength;
1025
1026 /* QUIRK: so the output only reflects the last companion in the set */
1027 if (Walk->SupportsStreams != NULL)
1028 *Walk->SupportsStreams = FALSE;
1029
1030 /* USB 2.0 PHDC class descriptors share this type */
1031 if (Ctx->Speed != UsbSuperSpeed)
1032 {
1034 return;
1035 }
1036
1037 if (Desc->bLength < sizeof(*Desc) &&
1039 {
1040 return;
1041 }
1042
1043 if (Desc->bLength > sizeof(*Desc))
1045
1046 if (!Walk->WantCompanion)
1047 {
1049 return;
1050 }
1051
1052 Walk->GotCompanion = TRUE;
1053 Walk->WantCompanion = FALSE;
1054
1055 if (*Advance > Left)
1056 {
1058 return;
1059 }
1060
1061 Endpoint = Walk->LastEndpoint;
1062 Packet = Endpoint->wMaxPacketSize;
1063 Burst = Desc->bMaxBurst;
1064 Attributes = Desc->bmAttributes.AsUchar;
1065 Mult = Attributes & 0x3;
1066 Ceiling = Packet * (Burst + 1) * (Mult + 1);
1067
1068 switch (Endpoint->bmAttributes & USB_ENDPOINT_TYPE_MASK)
1069 {
1071 if (Burst != 0)
1073
1074 if (Attributes != 0)
1076
1077 if (Desc->wBytesPerInterval != 0)
1079 break;
1080
1082 if (Burst > 15)
1084
1085 if ((Attributes & 0x1F) != 0 && Walk->SupportsStreams != NULL)
1086 *Walk->SupportsStreams = TRUE;
1087
1088 if ((Attributes & 0x1F) > 16)
1090
1091 if (Attributes & 0xE0)
1093
1094 if (Desc->wBytesPerInterval != 0)
1096 break;
1097
1099 if (Burst > 15)
1101
1102 if (Burst != 0 && Packet != 1024)
1104
1105 if (Attributes != 0)
1107
1108 if (Desc->wBytesPerInterval > Ceiling)
1110 break;
1111
1113 SspFollows = (Attributes & 0x80) != 0;
1114 Walk->GotSspCompanion = FALSE;
1115 Walk->WantSspCompanion = SspFollows;
1116
1117 if (Burst > 15)
1119
1120 if (Burst != 0 && Packet != 1024)
1122
1123 if (!SspFollows && Mult > 2)
1125
1126 if (Attributes & 0x7C)
1128
1129 if (!SspFollows && Desc->wBytesPerInterval > Ceiling)
1131
1132 if (SspFollows && Desc->wBytesPerInterval != 1)
1134 break;
1135 }
1136}
1137
1138static
1139VOID
1140NTAPI
1146{
1147 const HubDescContext* Ctx = Walk->Ctx;
1148 ULONG Left = BytesLeft(Walk->Base, Walk->BufferLength, Desc);
1149
1151 *Advance = Desc->bLength;
1152
1153 if (Ctx->Speed != UsbSuperSpeed || Ctx->SspIsochBurstCount == 0)
1154 {
1156 return;
1157 }
1158
1159 if (Desc->bLength < sizeof(*Desc) &&
1161 {
1162 return;
1163 }
1164
1165 if (Desc->bLength > sizeof(*Desc))
1167
1168 if (!Walk->WantSspCompanion)
1169 {
1171 return;
1172 }
1173
1174 Walk->GotSspCompanion = TRUE;
1175 Walk->WantSspCompanion = FALSE;
1176
1177 if (*Advance > Left)
1178 {
1180 return;
1181 }
1182
1183 if (Desc->wReserved != 0)
1185
1186 if (Desc->dwBytesPerInterval < 0xC001 || Desc->dwBytesPerInterval > 0xFFFFFF)
1188}
1189
1190static
1191VOID
1192NTAPI
1198{
1199 const HubDescContext* Ctx = Walk->Ctx;
1200 ULONG Left = BytesLeft(Walk->Base, Walk->BufferLength, Desc);
1201 ULONG Declared = Walk->Config->bNumInterfaces;
1202
1204 *Advance = Desc->bLength;
1205
1206 if (Desc->bLength < sizeof(*Desc) &&
1208 {
1209 return;
1210 }
1211
1212 if (Desc->bLength > sizeof(*Desc))
1214
1215 if (*Advance > Left)
1216 {
1218 return;
1219 }
1220
1221 if ((ULONG)Desc->bFirstInterface + Desc->bInterfaceCount > 256)
1223
1224 if (Desc->bInterfaceCount > Declared)
1226
1227 /* Same test USBCCGP makes */
1228 if (Desc->bInterfaceCount + Walk->InterfacesFound > Declared)
1230
1231 if (Desc->bInterfaceCount == 0)
1233}
1234
1235BOOLEAN
1236NTAPI
1242{
1245 BOOLEAN Valid = TRUE;
1246 PUCHAR Cursor;
1247
1248 if (SupportsStreams != NULL)
1250
1251 if (Descriptor == NULL)
1252 {
1254 return FALSE;
1255 }
1256
1257 if (Length < sizeof(*Descriptor))
1258 {
1260 return FALSE;
1261 }
1262
1263 RtlZeroMemory(&Walk, sizeof(Walk));
1264 Walk.Ctx = Context;
1267 Walk.End = Walk.Base + Length;
1268 Walk.Config = Descriptor;
1269 Walk.SupportsStreams = SupportsStreams;
1270
1273 if (Result == Verdict::Fatal)
1274 return FALSE;
1275
1276 if (Result != Verdict::Ok)
1277 Valid = FALSE;
1278
1279 /* QUIRK: the walk starts after the 9 fixed bytes even when bLength is larger */
1280 Cursor = Walk.Base + sizeof(*Descriptor);
1281 while (Cursor < Walk.End)
1282 {
1284 ULONG Advance;
1285
1288 if (Result == Verdict::Fatal)
1289 return FALSE;
1290
1291 /* Compatibility mode lets header findings pass here (a Cypress mouse needs it) */
1292 if (Result == Verdict::Failed && !Context->Win8Behavior)
1293 Valid = FALSE;
1294
1296 switch (Desc->bDescriptorType)
1297 {
1299 Walk.WantCompanion = FALSE;
1300 Walk.WantSspCompanion = FALSE;
1302 break;
1303
1305 Walk.WantSspCompanion = FALSE;
1307 break;
1308
1310 Walk.WantSspCompanion = FALSE;
1312 break;
1313
1317 &Advance,
1318 &Result);
1319 break;
1320
1322 Walk.WantCompanion = FALSE;
1323 Walk.WantSspCompanion = FALSE;
1325 break;
1326
1327 default:
1328 Walk.WantCompanion = FALSE;
1329 Walk.WantSspCompanion = FALSE;
1330 break;
1331 }
1332
1333 if (Result == Verdict::Fatal)
1334 return FALSE;
1335
1336 if (Result == Verdict::Failed)
1337 Valid = FALSE;
1338
1339 /* Zero padding at the end of the set is tolerated */
1340 if (Desc->bLength == 0)
1341 break;
1342
1343 Cursor += Advance;
1344 }
1345
1348 if (Result != Verdict::Ok)
1349 Valid = FALSE;
1350
1351 /* No validation code for this one */
1352 if (Walk.InterfacesFound != Descriptor->bNumInterfaces && GateApplies(Context, Gate::Legacy))
1353 {
1354 DPRINT1("%s %p configuration has %lu interfaces, bNumInterfaces %u\n",
1355 Context->ForHub ? "Hub" : "Device", Context->LogContext,
1356 Walk.InterfacesFound, Descriptor->bNumInterfaces);
1357 Valid = FALSE;
1358 }
1359
1360 return Valid;
1361}
1362
1363/* Device descriptor */
1364
1365BOOLEAN
1366NTAPI
1371 _Inout_opt_ PBOOLEAN IsBillboard)
1372{
1375 ULONG Packet0;
1376 ULONG i;
1377
1378 if (Descriptor == NULL)
1379 {
1381 return FALSE;
1382 }
1383
1384 if (Length < sizeof(USB_COMMON_DESCRIPTOR))
1385 {
1387 return FALSE;
1388 }
1389
1390 if (Descriptor->bLength < sizeof(*Descriptor))
1392
1393 if (Descriptor->bDescriptorType != USB_DEVICE_DESCRIPTOR_TYPE)
1395
1396 if (Length < 8)
1397 {
1399 return FALSE;
1400 }
1401
1402 /* Skipped on the 8 byte read, where these bytes are stale */
1404 {
1405 for (i = 0; i < 16; i += 4)
1406 {
1407 if (((Descriptor->bcdDevice >> i) & 0xF) > 9)
1408 {
1410 break;
1411 }
1412 }
1413 }
1414
1415 /* The gates use the context version; this one is the descriptor's own */
1416 Version = Descriptor->bcdUSB;
1417 if (Descriptor->bDeviceClass == USB_DEVICE_CLASS_BILLBOARD &&
1418 Descriptor->bDeviceSubClass == 0 &&
1419 Descriptor->bDeviceProtocol == 0)
1420 {
1421 if (Version > 0x0200 && Version < 0x0300)
1422 {
1423 if (IsBillboard != NULL)
1424 *IsBillboard = TRUE;
1425 }
1426 else
1427 {
1428 /* QUIRK: a USB 3.x Billboard device fails enumeration */
1430 }
1431 }
1432
1433 Packet0 = Descriptor->bMaxPacketSize0;
1434 switch (Context->Speed)
1435 {
1436 /* QUIRK: low and high speed can log the code twice */
1437 case UsbLowSpeed:
1438 case UsbHighSpeed:
1439 if (Packet0 != (Context->Speed == UsbLowSpeed ? 8UL : 64UL))
1440 {
1442 if (!IsSmallPacket(Packet0))
1444 }
1445 break;
1446
1447 case UsbFullSpeed:
1448 if (!IsSmallPacket(Packet0))
1450 break;
1451
1452 case UsbSuperSpeed:
1453 if (Packet0 != 9)
1455 break;
1456 }
1457
1458 return Result == Verdict::Ok;
1459}
1460
1461/* BOS descriptor set */
1462
1463static
1464VOID
1465NTAPI
1467 _In_ const HubDescContext* Ctx,
1470 _Out_ PUCHAR* End,
1473{
1474 ULONG Minimum;
1475
1477 *Advance = sizeof(*Bos);
1478 *End = NULL;
1479
1480 if (Bos == NULL)
1481 {
1483 return;
1484 }
1485
1486 /* Every caller supplies 5 bytes, so this never fails in practice */
1487 if (Length < sizeof(*Bos))
1488 {
1490 return;
1491 }
1492
1493 if (Bos->bDescriptorType != USB_BOS_DESCRIPTOR_TYPE)
1495
1496 if (Bos->bLength < sizeof(*Bos))
1498
1499 *End = (PUCHAR)Bos + Bos->wTotalLength;
1500 if (Bos->bLength > sizeof(*Bos))
1501 {
1503 *Advance = Bos->bLength;
1504 }
1505
1506 Minimum = Bos->bLength + Bos->bNumDeviceCaps * sizeof(USB_COMMON_DESCRIPTOR);
1507 if (Bos->wTotalLength < sizeof(*Bos))
1508 {
1510 *End = (PUCHAR)Bos + Length;
1511 }
1512
1513 if (Bos->wTotalLength < Minimum)
1514 {
1516 *End = (PUCHAR)Bos + Length;
1517 }
1518
1519 /* QUIRK: reuses the wTotalLength code */
1520 if (Bos->bNumDeviceCaps == 0)
1522}
1523
1524static
1525VOID
1526NTAPI
1532{
1533 const HubDescContext* Ctx = Walk->Ctx;
1534 ULONG Left = BytesLeft(Walk->Base, Walk->BufferLength, Cap);
1535 HubLpmInfo* Lpm = Walk->Lpm;
1537 UCHAR Baseline;
1538 UCHAR Deep;
1539
1541 if (Cap->bLength < sizeof(*Cap) &&
1543 {
1544 return;
1545 }
1546
1547 if (Cap->bLength > sizeof(*Cap))
1549
1550 if (*Advance > Left)
1551 {
1553 return;
1554 }
1555
1556 Attributes = Cap->bmAttributes.AsUlong;
1559
1560 if (!Cap->bmAttributes.LPMCapable)
1561 {
1562 if (Cap->bmAttributes.BESLAndAlternateHIRDSupported)
1564 return;
1565 }
1566
1567 /* QUIRK: written even for a duplicate capability, and never cleared */
1568 if (Lpm != NULL)
1569 {
1570 Lpm->Capable = TRUE;
1571 if (Cap->bmAttributes.BESLAndAlternateHIRDSupported)
1572 Lpm->BeslAndAltHird = TRUE;
1573 }
1574
1575 Baseline = (UCHAR)Cap->bmAttributes.BaselineBESL;
1576 Deep = (UCHAR)Cap->bmAttributes.DeepBESL;
1577
1578 if (Cap->bmAttributes.BaselineBESLValid)
1579 {
1580 if (Baseline == 0)
1581 {
1583 }
1584 else if (Lpm != NULL)
1585 {
1586 Lpm->BaselineValid = TRUE;
1587 Lpm->Baseline = Baseline;
1588 }
1589 }
1590
1591 if (!Cap->bmAttributes.DeepBESLValid)
1592 return;
1593
1594 if (Cap->bmAttributes.BaselineBESLValid && Deep <= Baseline)
1595 {
1597 }
1598 else if (Deep == 0)
1599 {
1601 }
1602 else if (Lpm != NULL)
1603 {
1604 Lpm->DeepValid = TRUE;
1605 Lpm->Deep = Deep;
1606 }
1607}
1608
1609static
1610VOID
1611NTAPI
1617{
1618 const HubDescContext* Ctx = Walk->Ctx;
1619 ULONG Left = BytesLeft(Walk->Base, Walk->BufferLength, Cap);
1620 ULONG Speeds;
1621
1623
1624 /* QUIRK: the LTM output is cleared and never set, so the BOS never makes a device LTM capable */
1625 if (Walk->Ltm != NULL)
1626 *Walk->Ltm = FALSE;
1627
1628 if (Cap->bLength < sizeof(*Cap) &&
1630 {
1631 return;
1632 }
1633
1634 if (Cap->bLength > sizeof(*Cap))
1636
1637 if (*Advance > Left)
1638 {
1640 return;
1641 }
1642
1645
1646 Speeds = Cap->wSpeedsSupported;
1649
1650 if (Speeds == 0)
1652
1653 if (Cap->bFunctionalitySupport > 3)
1655 else if ((Speeds & (1UL << Cap->bFunctionalitySupport)) == 0)
1657
1660 else if (Walk->U1 != NULL)
1661 *Walk->U1 = Cap->bU1DevExitLat;
1662
1665 else if (Walk->U2 != NULL)
1666 *Walk->U2 = Cap->wU2DevExitLat;
1667}
1668
1670static
1671VOID
1672NTAPI
1674 _In_ const HubDescContext* Ctx,
1678{
1679 ULONG Last = Cap->bmAttributes.SublinkSpeedAttrCount;
1680 ULONG MinimumId = Cap->wFunctionalitySupport.SublinkSpeedAttrID;
1681 BOOLEAN Symmetric;
1682 BOOLEAN MinimumFound = FALSE;
1683 ULONG SeenIds = 0;
1684 ULONG Unique = 0;
1685 ULONG i;
1686
1687 for (i = 0; i <= Last; i += 2)
1688 {
1689 /* Stop at the last entry bLength covers */
1690 if (i >= Present)
1691 return;
1692
1693 if (Cap->bmSublinkSpeedAttr[i].SublinkTypeDir != USB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_SPEED_DIR_RX)
1694 {
1696 return;
1697 }
1698
1699 if (i == Last)
1700 {
1702 return;
1703 }
1704
1705 if (i + 1 >= Present)
1706 return;
1707
1708 if (Cap->bmSublinkSpeedAttr[i + 1].SublinkTypeDir != USB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_SPEED_DIR_TX)
1709 {
1711 return;
1712 }
1713
1714 if (Cap->bmSublinkSpeedAttr[i].SublinkSpeedAttrID != Cap->bmSublinkSpeedAttr[i + 1].SublinkSpeedAttrID ||
1715 Cap->bmSublinkSpeedAttr[i].SublinkTypeMode != Cap->bmSublinkSpeedAttr[i + 1].SublinkTypeMode ||
1716 Cap->bmSublinkSpeedAttr[i].LinkProtocol != Cap->bmSublinkSpeedAttr[i + 1].LinkProtocol)
1717 {
1719 }
1720
1721 Symmetric = Cap->bmSublinkSpeedAttr[i].SublinkTypeMode == USB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_SPEED_MODE_SYMMETRIC;
1722 if (Symmetric &&
1723 (Cap->bmSublinkSpeedAttr[i].LaneSpeedExponent != Cap->bmSublinkSpeedAttr[i + 1].LaneSpeedExponent ||
1724 Cap->bmSublinkSpeedAttr[i].LaneSpeedMantissa != Cap->bmSublinkSpeedAttr[i + 1].LaneSpeedMantissa))
1725 {
1727 }
1728
1729 if (Cap->bmSublinkSpeedAttr[i].SublinkSpeedAttrID == MinimumId)
1730 {
1731 MinimumFound = TRUE;
1732 if (Symmetric &&
1733 Cap->wFunctionalitySupport.MinRxLaneCount != Cap->wFunctionalitySupport.MinTxLaneCount)
1734 {
1736 }
1737 }
1738
1739 if (SeenIds & (1UL << Cap->bmSublinkSpeedAttr[i].SublinkSpeedAttrID))
1740 {
1742 }
1743 else
1744 {
1745 SeenIds |= 1UL << Cap->bmSublinkSpeedAttr[i].SublinkSpeedAttrID;
1746 Unique++;
1747 }
1748 }
1749
1750 if (Cap->bmAttributes.SublinkSpeedIDCount + 1UL != Unique)
1752
1753 if (!MinimumFound)
1755}
1756
1757static
1758VOID
1759NTAPI
1765{
1766 const HubDescContext* Ctx = Walk->Ctx;
1767 ULONG Left = BytesLeft(Walk->Base, Walk->BufferLength, Cap);
1769 ULONG Entry = sizeof(Cap->bmSublinkSpeedAttr[0]);
1770
1772 if (Cap->bLength < sizeof(*Cap) &&
1774 {
1775 return;
1776 }
1777
1778 if (Cap->bLength != sizeof(*Cap) + Entry * Cap->bmAttributes.SublinkSpeedAttrCount)
1780
1781 if (*Advance > Left)
1782 {
1784 return;
1785 }
1786
1787 if (Cap->bmAttributes.Reserved != 0)
1789
1790 if (Cap->wFunctionalitySupport.Reserved != 0)
1792
1793 if (Cap->bReserved != 0)
1795
1796 if (Cap->wReserved != 0)
1798
1799 CheckSublinkSpeeds(Ctx, Cap, (*Advance - Fixed) / Entry, Result);
1800}
1801
1802static
1803VOID
1804NTAPI
1810{
1811 const HubDescContext* Ctx = Walk->Ctx;
1812 ULONG Left = BytesLeft(Walk->Base, Walk->BufferLength, Cap);
1813
1815 if (Cap->bLength < sizeof(*Cap) &&
1817 {
1818 return;
1819 }
1820
1821 if (Cap->bLength > sizeof(*Cap))
1823
1824 if (*Advance > Left)
1825 {
1827 return;
1828 }
1829
1830 if (Cap->bReserved != 0)
1832
1833 /* These devices still enumerate; only the ID is dropped */
1834 if (IsAllZero(Cap->ContainerID, sizeof(Cap->ContainerID)))
1835 {
1838 }
1839}
1840
1842static
1843BOOLEAN
1844NTAPI
1847{
1849}
1850
1851static
1852VOID
1853NTAPI
1858{
1859 const HubDescContext* Ctx = Walk->Ctx;
1861 HubMsOs20SetInfo* Sets = (HubMsOs20SetInfo*)((PUCHAR)Cap + Fixed);
1862 ULONG Count;
1863 ULONG Best = 0;
1864 ULONG i, j;
1865
1866 if (Walk->Info->MsOs20SetInfo != NULL)
1867 {
1869 return;
1870 }
1871
1872 if (Cap->bLength < Fixed + sizeof(*Sets) || (Cap->bLength - Fixed) % sizeof(*Sets) != 0)
1873 {
1875 return;
1876 }
1877
1878 Count = (Cap->bLength - Fixed) / sizeof(*Sets);
1879
1880 /* Logged once per equal pair */
1881 for (i = 0; i < Count; i++)
1882 {
1883 for (j = i + 1; j < Count; j++)
1884 {
1885 if (Sets[i].dwWindowsVersion == Sets[j].dwWindowsVersion)
1887 }
1888 }
1889
1890 /* Newest set this OS can use */
1891 for (i = 0; i < Count; i++)
1892 {
1893 if (Sets[i].dwWindowsVersion > Best && MsOs20VersionUsable(Sets[i].dwWindowsVersion))
1894 {
1895 Best = Sets[i].dwWindowsVersion;
1896 Walk->Info->MsOs20SetInfo = &Sets[i];
1897 }
1898 }
1899
1900 if (Best == 0)
1902}
1903
1904static
1905VOID
1906NTAPI
1911{
1912 const HubDescContext* Ctx = Walk->Ctx;
1913
1914 if (Cap->bLength < sizeof(*Cap))
1915 {
1917 return;
1918 }
1919
1920 /* Later versions may be longer */
1921 if (Cap->Version == 1 && Cap->bLength != sizeof(*Cap))
1922 {
1924 return;
1925 }
1926
1927 if (Cap->Version == 0)
1928 {
1930 return;
1931 }
1932
1933 if (Walk->Info->PlatformFeatures != NULL)
1934 {
1936 return;
1937 }
1938
1939 Walk->Info->PlatformFeatures = Cap;
1940}
1941
1942static
1943VOID
1944NTAPI
1950{
1951 const HubDescContext* Ctx = Walk->Ctx;
1952 ULONG Left = BytesLeft(Walk->Base, Walk->BufferLength, Cap);
1955
1957 if (Cap->bLength < Fixed &&
1959 {
1960 return;
1961 }
1962
1963 if (*Advance > Left)
1964 {
1966 return;
1967 }
1968
1969 if (Cap->bReserved != 0)
1971
1972 if (IsAllZero(Uuid, sizeof(GUID)))
1973 {
1975 return;
1976 }
1977
1978 /* Other platform UUIDs are accepted as they are */
1981 else if (IsEqualGUID(*(const GUID*)Uuid, HubPlatformFeaturesUuid))
1983}
1984
1985static
1986VOID
1987NTAPI
1993{
1994 const HubDescContext* Ctx = Walk->Ctx;
1995 ULONG Left = BytesLeft(Walk->Base, Walk->BufferLength, Cap);
1996
1998 if (Cap->bLength < sizeof(*Cap) &&
2000 {
2001 return;
2002 }
2003
2004 if (Cap->bLength > sizeof(*Cap))
2006
2007 if (*Advance > Left)
2008 {
2010 return;
2011 }
2012
2013 if (Cap->bReserved != 0 ||
2014 Cap->bmAttributes.Reserved1 != 0 ||
2015 Cap->bmAttributes.Reserved2 != 0 ||
2016 Cap->bmAttributes.Reserved3 != 0)
2017 {
2019 }
2020
2021 if (Cap->bmAttributes.ChargingPolicy)
2023}
2024
2025static
2026VOID
2027NTAPI
2033{
2034 const HubDescContext* Ctx = Walk->Ctx;
2035 ULONG Left = BytesLeft(Walk->Base, Walk->BufferLength, Cap);
2036 ULONG Mode = sizeof(Cap->AlternateMode[0]);
2037 ULONG Modes = Cap->bNumberOfAlternateModes;
2039 BOOLEAN Repaired;
2040
2042 if (Left < sizeof(*Cap))
2043 {
2045 return;
2046 }
2047
2048 /* The structure holds one mode; zero modes gives 44 */
2049 Expected = sizeof(*Cap) - Mode + Modes * Mode;
2050 if (Cap->bLength != Expected)
2051 {
2052 /* QUIRK: the walk moves by the computed length from here on */
2053 *Advance = Expected;
2054 Repaired = (Cap->bLength == 40 || Cap->bLength == 44);
2056
2057 /* QUIRK: early spec revisions gave the base length; repair it in the caller's buffer */
2058 if (Repaired)
2059 Cap->bLength = (UCHAR)Expected;
2060 else if (GateApplies(Ctx, Gate::CapSsp))
2062 }
2063
2064 if (*Advance > Left)
2065 {
2067 return;
2068 }
2069
2070 if (Modes == 0)
2071 {
2073 return;
2074 }
2075
2076 if (Modes > 128)
2077 {
2079 return;
2080 }
2081
2082 /* QUIRK: an index equal to the mode count passes */
2083 if (Cap->bPreferredAlternateMode > Modes)
2085}
2086
2088static
2089VOID
2090NTAPI
2096{
2097 const HubDescContext* Ctx = Walk->Ctx;
2099 ULONG Left = BytesLeft(Walk->Base, Walk->BufferLength, Cap);
2100
2102
2103 /* QUIRK: latencies survive only when the SuperSpeed capability comes last */
2104 if (Walk->U1 != NULL)
2105 *Walk->U1 = 0;
2106
2107 if (Walk->U2 != NULL)
2108 *Walk->U2 = 0;
2109
2110 *Advance = Cap->bLength;
2111 if (Cap->bLength < sizeof(*Cap) &&
2113 {
2114 return;
2115 }
2116
2117 if (sizeof(*Cap) > Left)
2118 {
2120 return;
2121 }
2122
2123 /* QUIRK: in compatibility mode the specific checks below start over */
2124 switch (Cap->bDevCapabilityType)
2125 {
2128 if (*Result == Verdict::Fatal)
2129 return;
2130
2131 if (Info->Usb20 != NULL)
2133 else
2135 break;
2136
2139 if (*Result == Verdict::Fatal)
2140 return;
2141
2142 if (Info->SuperSpeed != NULL)
2144 else
2146 break;
2147
2150 if (*Result == Verdict::Fatal)
2151 return;
2152
2153 if (Info->SuperSpeedPlus != NULL)
2155 else
2157 break;
2158
2161 if (*Result == Verdict::Fatal)
2162 return;
2163
2164 if (Info->ContainerId != NULL)
2166 else if (!Info->DiscardContainerId)
2168 break;
2169
2172 break;
2173
2176 break;
2177
2180 if (*Result == Verdict::Fatal)
2181 return;
2182
2183 if (Info->Billboard != NULL)
2185 else
2187 break;
2188
2189 /* Wireless USB, battery, PD ports, PTM, firmware status and unknown types */
2190 default:
2191 break;
2192 }
2193}
2194
2195BOOLEAN
2196NTAPI
2201{
2203 PUCHAR End;
2204 ULONG Advance;
2205
2207 return Result == Verdict::Ok;
2208}
2209
2211BOOLEAN
2212NTAPI
2213HubDescCheckBos(
2223{
2224 HubBosInfo LocalInfo;
2233
2234 if (Info == NULL)
2235 Info = &LocalInfo;
2236
2238 *U1ExitLatency = 0;
2239
2241 *U2ExitLatency = 0;
2242
2244
2245 if (Length < sizeof(*Descriptor))
2246 {
2248 return FALSE;
2249 }
2250
2254 return FALSE;
2255
2257 Valid = FALSE;
2258
2259 if (Length < Descriptor->wTotalLength)
2260 {
2262 Valid = FALSE;
2263 }
2264
2265 /* A Genesys 2.1 hub returns more than wTotalLength */
2266 if (Length > Descriptor->wTotalLength)
2268
2272 Walk.Info = Info;
2276 Walk.Lpm = Lpm;
2277
2278 /* Stop at the buffer end even when wTotalLength runs past it */
2279 Limit = Walk.Base + Length;
2280
2281 Cursor = Walk.Base + Advance;
2282 while (Cursor < End)
2283 {
2285
2286 /* Code 23 was logged above when wTotalLength overran the buffer */
2287 if (Cursor >= Limit)
2288 return FALSE;
2289
2292 if (Result == Verdict::Fatal)
2293 return FALSE;
2294
2295 if (Result != Verdict::Ok)
2296 Valid = FALSE;
2297
2301 else
2303
2304 if (Result == Verdict::Fatal)
2305 return FALSE;
2306
2307 if (Result != Verdict::Ok)
2308 Valid = FALSE;
2309
2310 /* QUIRK: every descriptor counts toward bNumDeviceCaps, whatever its type */
2311 Found++;
2312
2313 /* A zero length descriptor would otherwise loop forever */
2314 if (Advance == 0)
2315 break;
2316
2317 Cursor += Advance;
2318 }
2319
2320 if (Found != Descriptor->bNumDeviceCaps)
2321 {
2323 Valid = FALSE;
2324 }
2325
2326 if (Info->SuperSpeed != NULL)
2327 {
2328 if (DeviceFlags != NULL)
2330 }
2331 else if (Context->Speed == UsbSuperSpeed)
2332 {
2334 Valid = FALSE;
2335 }
2336
2338 {
2339 if (Info->SuperSpeedPlus != NULL)
2341
2342 if (Info->ChargingPolicy)
2344 }
2345
2346 return Valid;
2347}
2348
2349/* Strings */
2350
2351static
2352Verdict
2353NTAPI
2355 _In_ const HubDescContext* Ctx,
2358 _Out_ PULONG Adjusted)
2359{
2361
2362 if (Length < sizeof(USB_COMMON_DESCRIPTOR))
2363 {
2364 *Adjusted = 0;
2366 return Result;
2367 }
2368
2369 *Adjusted = Desc->bLength;
2370 if (Desc->bLength > Length)
2371 {
2373 *Adjusted = Length;
2374 }
2375
2376 /* No characters at all */
2377 if (Desc->bLength <= sizeof(USB_COMMON_DESCRIPTOR))
2378 {
2380 *Adjusted = Length;
2381 }
2382
2383 if (Desc->bDescriptorType != USB_STRING_DESCRIPTOR_TYPE)
2385
2386 if (Desc->bLength & 1)
2387 {
2389 *Adjusted &= ~1UL;
2390 }
2391
2392 if (Desc->bLength != Length)
2394
2395 return Result;
2396}
2397
2398BOOLEAN
2399NTAPI
2404 _Out_opt_ PULONG AdjustedLength)
2405{
2406 ULONG Adjusted;
2408
2410 if (AdjustedLength != NULL)
2411 *AdjustedLength = Adjusted;
2412
2413 return Result == Verdict::Ok;
2414}
2415
2416BOOLEAN
2417NTAPI
2422{
2423 ULONG Adjusted;
2424 ULONG Chars;
2425 ULONG i;
2426 BOOLEAN Valid = TRUE;
2427
2428 if (CheckStringCore(Context, Descriptor, *Length, &Adjusted) != Verdict::Ok)
2429 return FALSE;
2430
2431 *Length = Descriptor->bLength - sizeof(USB_COMMON_DESCRIPTOR);
2432 Chars = *Length / sizeof(WCHAR);
2433 for (i = 0; i < Chars; i++)
2434 {
2435 WCHAR Ch = Descriptor->bString[i];
2436
2437 if (Ch == 0)
2438 break;
2439
2440 /* Printable ASCII only, and no comma since it separates instance ID parts */
2441 if (Ch < L' ' || Ch > 0x7F || Ch == L',')
2442 {
2444 Valid = FALSE;
2445 }
2446 }
2447
2448 if (!Valid)
2449 return FALSE;
2450
2451 /* Room for a terminating NUL */
2452 *Length += sizeof(WCHAR);
2453 return TRUE;
2454}
2455
2456/* MS OS 1.0 descriptors */
2457
2459static
2460BOOLEAN
2461NTAPI
2463 _In_ UCHAR Ch)
2464{
2465 return (Ch >= 'A' && Ch <= 'Z') || (Ch >= '0' && Ch <= '9') || Ch == '_';
2466}
2467
2468static
2469BOOLEAN
2470NTAPI
2472 _In_reads_(8) const UCHAR* Id)
2473{
2474 BOOLEAN Ended = FALSE;
2475 ULONG i;
2476
2477 for (i = 0; i < 8; i++)
2478 {
2479 if (Id[i] == 0)
2480 Ended = TRUE;
2481 else if (Ended || !IsMsOsIdChar(Id[i]))
2482 return FALSE;
2483 }
2484
2485 return TRUE;
2486}
2487
2488BOOLEAN
2489NTAPI
2493{
2494 static const WCHAR Expected[7] = { 'M', 'S', 'F', 'T', '1', '0', '0' };
2495
2496 if (RtlEqualMemory(Descriptor->Signature, Expected, sizeof(Expected)))
2497 return TRUE;
2498
2499 DPRINT1("Device %p MS OS string has the wrong signature\n", Context->LogContext);
2500 return FALSE;
2501}
2502
2503BOOLEAN
2504NTAPI
2509{
2510 BOOLEAN Valid = TRUE;
2511
2512 if (Length != sizeof(*Descriptor))
2513 {
2515 return FALSE;
2516 }
2517
2518 if (Descriptor->bcdVersion != 0x0100)
2519 {
2521 Valid = FALSE;
2522 }
2523
2524 if (Descriptor->wIndex != 6)
2525 {
2527 Valid = FALSE;
2528 }
2529
2530 if (Descriptor->dwLength != sizeof(HubMsOsContainerId))
2531 {
2533 Valid = FALSE;
2534 }
2535
2536 return Valid;
2537}
2538
2539BOOLEAN
2540NTAPI
2545{
2546 if (Length != sizeof(*Descriptor))
2547 {
2549 return FALSE;
2550 }
2551
2552 if (IsAllZero(Descriptor->ContainerId, sizeof(Descriptor->ContainerId)))
2553 {
2555 return FALSE;
2556 }
2557
2558 return TRUE;
2559}
2560
2561BOOLEAN
2562NTAPI
2567{
2568 BOOLEAN Valid = TRUE;
2569
2570 if (Length != sizeof(*Descriptor))
2571 {
2573 return FALSE;
2574 }
2575
2576 if (Descriptor->bcdVersion != 0x0100)
2577 {
2579 Valid = FALSE;
2580 }
2581
2582 if (Descriptor->wIndex != 4)
2583 {
2585 Valid = FALSE;
2586 }
2587
2588 /* Only single function devices are supported */
2589 if (Descriptor->bCount != 1)
2590 {
2592 return FALSE;
2593 }
2594
2595 if (Descriptor->dwLength != sizeof(*Descriptor) + Descriptor->bCount * sizeof(HubMsOsExtConfigFunction))
2596 {
2598 return FALSE;
2599 }
2600
2601 return Valid;
2602}
2603
2604BOOLEAN
2605NTAPI
2610{
2611 const HubMsOsExtConfigFunction* Function = &Descriptor->Function[0];
2613
2614 if (Length != Descriptor->Header.dwLength)
2616
2617 /* Interface numbers are not compared with the configuration */
2618 if (!IsMsOs10IdValid(Function->CompatibleId))
2619 {
2621 return FALSE;
2622 }
2623
2624 if (!IsMsOs10IdValid(Function->SubCompatibleId))
2625 {
2627 return FALSE;
2628 }
2629
2630 return Result == Verdict::Ok;
2631}
2632
2633/* MS OS 2.0 descriptor set */
2634
2635/* wDescriptorType values */
2636#define HUB_MSOS20_TYPE_SET_HEADER 0
2637#define HUB_MSOS20_TYPE_CONFIG_SUBSET 1
2638#define HUB_MSOS20_TYPE_FUNCTION_SUBSET 2
2639#define HUB_MSOS20_TYPE_COMPATIBLE_ID 3
2640#define HUB_MSOS20_TYPE_REGISTRY 4
2641#define HUB_MSOS20_TYPE_RESUME_TIME 5
2642#define HUB_MSOS20_TYPE_MODEL_ID 6
2643#define HUB_MSOS20_TYPE_CCGP 7
2644
2645BOOLEAN
2646NTAPI
2648 _In_ PUCHAR End,
2650{
2651 HubMsOs20Common* Desc = *Current;
2652 PUCHAR At = (PUCHAR)Desc;
2653 PUCHAR Next;
2654
2655 *Current = NULL;
2656
2657 /* The current descriptor must itself fit before End */
2658 if (At + Desc->wLength > End)
2659 return FALSE;
2660
2663 {
2664 HubMsOs20Subset* Subset = (HubMsOs20Subset*)Desc;
2665
2666 if (Subset->wLength < sizeof(*Subset) || Subset->wTotalLength < sizeof(*Subset) + sizeof(*Desc))
2667 return FALSE;
2668
2669 Next = At + Subset->wTotalLength;
2670 }
2671 else
2672 {
2673 if (Desc->wLength < sizeof(*Desc))
2674 return FALSE;
2675
2676 Next = At + Desc->wLength;
2677 }
2678
2679 if (Next == End)
2680 return TRUE;
2681
2682 if (Next > End || Next + sizeof(*Desc) > End)
2683 return FALSE;
2684
2685 if (Next + ((HubMsOs20Common*)Next)->wLength > End)
2686 return FALSE;
2687
2689 return TRUE;
2690}
2691
2692static
2693BOOLEAN
2694NTAPI
2696 _In_ const HubDescContext* Ctx,
2698 _In_ HubMsOs20Common* Desc,
2699 _In_ PUCHAR End,
2700 _In_ ULONG Depth);
2701
2702static
2703BOOLEAN
2704NTAPI
2706 _In_ const HubDescContext* Ctx,
2708 _In_ HubMsOs20Common* Desc)
2709{
2710 BOOLEAN Valid = TRUE;
2711
2712 if (Info->Flags & HUB_MSOS20_SET_HEADER)
2713 {
2715 Valid = FALSE;
2716 }
2717
2718 if (Desc->wLength != sizeof(HubMsOs20SetHeader))
2719 {
2721 Valid = FALSE;
2722 }
2723
2724 if (Valid)
2725 Info->Flags |= HUB_MSOS20_SET_HEADER;
2726
2727 return Valid;
2728}
2729
2731static
2732BOOLEAN
2733NTAPI
2736 _In_ ULONG Type)
2737{
2739 return TRUE;
2740
2742}
2743
2744static
2745BOOLEAN
2746NTAPI
2748 _In_ const HubDescContext* Ctx,
2750 _In_ HubMsOs20Common* Desc,
2751 _In_ PUCHAR End,
2753{
2754 HubMsOs20Subset* Subset = (HubMsOs20Subset*)Desc;
2755 BOOLEAN Function = Desc->wDescriptorType == HUB_MSOS20_TYPE_FUNCTION_SUBSET;
2760 HubMsOs20Info Private;
2762 PUCHAR SubsetEnd;
2763 BOOLEAN Valid = TRUE;
2764
2765 if (Subset->wLength != sizeof(*Subset))
2766 {
2767 HubDescLog(Ctx, LengthCode, FALSE);
2768 return FALSE;
2769 }
2770
2771 if (Subset->wTotalLength < sizeof(*Subset) + sizeof(*Desc))
2772 {
2773 HubDescLog(Ctx, SmallCode, FALSE);
2774 return FALSE;
2775 }
2776
2777 SubsetEnd = (PUCHAR)Subset + Subset->wTotalLength;
2778 if (SubsetEnd > End)
2779 {
2780 HubDescLog(Ctx, LargeCode, FALSE);
2781 return FALSE;
2782 }
2783
2784 /* Nested configuration subsets would otherwise recurse without bound */
2786 {
2787 HubDescLog(Ctx, StepCode, FALSE);
2788 return FALSE;
2789 }
2790
2791 /* QUIRK: what a subset holds is checked into a private record, then dropped */
2792 RtlZeroMemory(&Private, sizeof(Private));
2793
2794 Cursor = (HubMsOs20Common*)((PUCHAR)Subset + sizeof(*Subset));
2795 while (Cursor != NULL)
2796 {
2797 ULONG Type = Cursor->wDescriptorType;
2798
2800 {
2802 {
2803 if (Function)
2804 {
2806 Valid = FALSE;
2807 }
2808 else
2809 {
2811 }
2812 }
2813
2814 /* Skip a first entry that runs past the subset; the step below fails it */
2815 if ((PUCHAR)Cursor + Cursor->wLength <= SubsetEnd &&
2816 !CheckMsOs20Feature(Ctx, &Private, Cursor, SubsetEnd, Depth + 1))
2817 {
2818 Valid = FALSE;
2819 }
2820 }
2821
2822 if (!HubDescNextMsOs20(SubsetEnd, &Cursor))
2823 {
2824 HubDescLog(Ctx, StepCode, FALSE);
2825 return FALSE;
2826 }
2827 }
2828
2829 if (Valid)
2831
2832 return Valid;
2833}
2834
2836static
2837BOOLEAN
2838NTAPI
2840 _In_ const HubDescContext* Ctx,
2841 _In_reads_(8) const UCHAR* Id)
2842{
2843 BOOLEAN Ended = FALSE;
2844 ULONG i;
2845
2846 for (i = 0; i < 8; i++)
2847 {
2848 if (Ended && Id[i] != 0)
2849 {
2851 return FALSE;
2852 }
2853
2854 if (Id[i] == 0)
2855 {
2856 Ended = TRUE;
2857 }
2858 else if (!IsMsOsIdChar(Id[i]))
2859 {
2861 return FALSE;
2862 }
2863 }
2864
2865 return TRUE;
2866}
2867
2868static
2869BOOLEAN
2870NTAPI
2872 _In_ const HubDescContext* Ctx,
2874 _In_ HubMsOs20Common* Desc)
2875{
2877 BOOLEAN Valid = TRUE;
2878
2879 if (Info->Flags & HUB_MSOS20_COMPATIBLE_ID)
2880 {
2882 Valid = FALSE;
2883 }
2884
2885 if (Id->wLength != sizeof(*Id))
2886 {
2888 return FALSE;
2889 }
2890
2891 if (!CheckMsOs20Id(Ctx, Id->CompatibleId) || !CheckMsOs20Id(Ctx, Id->SubCompatibleId))
2892 return FALSE;
2893
2894 if (Valid)
2895 {
2896 Info->CompatibleId = Id;
2898 }
2899
2900 return Valid;
2901}
2902
2903static
2904BOOLEAN
2905NTAPI
2907 _In_ const HubDescContext* Ctx,
2909 _In_ HubMsOs20Common* Desc)
2910{
2912 ULONG Total = Reg->wLength;
2915
2916 /* Header, a one character name, the data length and one data byte */
2917 if (Total < sizeof(*Reg) + sizeof(WCHAR) + sizeof(USHORT) + 1)
2918 {
2920 return FALSE;
2921 }
2922
2924 if (Total < sizeof(*Reg) + NameLength + sizeof(USHORT) + 1)
2925 {
2927 return FALSE;
2928 }
2929
2930 if (NameLength == 0 || (NameLength % sizeof(WCHAR)) != 0)
2931 {
2933 return FALSE;
2934 }
2935
2936 RtlCopyMemory(&DataLength, (PUCHAR)Reg + sizeof(*Reg) + NameLength, sizeof(DataLength));
2937 if (Total < sizeof(*Reg) + NameLength + sizeof(USHORT) + DataLength)
2938 {
2940 return FALSE;
2941 }
2942
2943 if (DataLength == 0)
2944 {
2946 return FALSE;
2947 }
2948
2950 {
2952 return FALSE;
2953 }
2954
2955 /* Any number of registry properties is fine */
2956 Info->Flags |= HUB_MSOS20_REGISTRY;
2957 return TRUE;
2958}
2959
2960static
2961BOOLEAN
2962NTAPI
2964 _In_ const HubDescContext* Ctx,
2966 _In_ HubMsOs20Common* Desc)
2967{
2969 BOOLEAN Valid = TRUE;
2970
2971 if (Info->Flags & HUB_MSOS20_RESUME_TIME)
2972 {
2974 Valid = FALSE;
2975 }
2976
2977 if (Resume->wLength != sizeof(*Resume))
2978 {
2980 return FALSE;
2981 }
2982
2983 if (Resume->bResumeRecoveryTime > 10)
2984 {
2986 Valid = FALSE;
2987 }
2988
2989 /* The hub drives resume signaling for at most 20 ms */
2990 if (Resume->bResumeSignalingTime == 0 || Resume->bResumeSignalingTime > 20)
2992
2993 if (Valid)
2994 {
2995 Info->ResumeTime = Resume;
2996 Info->Flags |= HUB_MSOS20_RESUME_TIME;
2997 }
2998
2999 return Valid;
3000}
3001
3002static
3003BOOLEAN
3004NTAPI
3006 _In_ const HubDescContext* Ctx,
3008 _In_ HubMsOs20Common* Desc)
3009{
3010 HubMsOs20ModelId* Model = (HubMsOs20ModelId*)Desc;
3011
3012 if (Info->Flags & HUB_MSOS20_MODEL_ID)
3013 {
3015 return FALSE;
3016 }
3017
3018 if (Model->wLength != sizeof(*Model))
3019 {
3021 return FALSE;
3022 }
3023
3024 if (IsAllZero(Model->ModelId, sizeof(Model->ModelId)))
3025 {
3027 return FALSE;
3028 }
3029
3030 Info->ModelId = Model;
3031 Info->Flags |= HUB_MSOS20_MODEL_ID;
3032 return TRUE;
3033}
3034
3035static
3036BOOLEAN
3037NTAPI
3039 _In_ const HubDescContext* Ctx,
3041 _In_ HubMsOs20Common* Desc)
3042{
3043 if (Info->Flags & HUB_MSOS20_CCGP)
3044 {
3046 return FALSE;
3047 }
3048
3049 if (Desc->wLength != sizeof(HubMsOs20Ccgp))
3050 {
3052 return FALSE;
3053 }
3054
3055 Info->Ccgp = (HubMsOs20Ccgp*)Desc;
3056 Info->Flags |= HUB_MSOS20_CCGP;
3057 return TRUE;
3058}
3059
3060static
3061BOOLEAN
3062NTAPI
3064 _In_ const HubDescContext* Ctx,
3066 _In_ HubMsOs20Common* Desc,
3067 _In_ PUCHAR End,
3069{
3070 switch (Desc->wDescriptorType)
3071 {
3073 return CheckMsOs20SetHeader(Ctx, Info, Desc);
3074
3077 return CheckMsOs20Subset(Ctx, Info, Desc, End, Depth);
3078
3080 return CheckMsOs20CompatibleId(Ctx, Info, Desc);
3081
3083 return CheckMsOs20Registry(Ctx, Info, Desc);
3084
3086 return CheckMsOs20ResumeTime(Ctx, Info, Desc);
3087
3089 return CheckMsOs20ModelId(Ctx, Info, Desc);
3090
3092 return CheckMsOs20Ccgp(Ctx, Info, Desc);
3093
3094 default:
3095 return TRUE;
3096 }
3097}
3098
3099static
3100BOOLEAN
3101NTAPI
3103 _In_ const HubDescContext* Ctx,
3108{
3111 PUCHAR End;
3112 BOOLEAN Valid = TRUE;
3113
3114 if (Length != SetInfo->wLength)
3115 {
3117 return FALSE;
3118 }
3119
3120 if (Length < sizeof(*Header))
3121 {
3123 return FALSE;
3124 }
3125
3126 if (Header->wLength != sizeof(*Header))
3127 {
3129 return FALSE;
3130 }
3131
3132 if (Header->wTotalLength != SetInfo->wLength)
3133 {
3135 return FALSE;
3136 }
3137
3138 if (Header->dwWindowsVersion > SetInfo->dwWindowsVersion)
3139 {
3141 return FALSE;
3142 }
3143
3144 /* The walk starts at the set header itself */
3145 End = (PUCHAR)Header + Header->wTotalLength;
3147 while (Cursor != NULL)
3148 {
3149 ULONG Type = Cursor->wDescriptorType;
3150
3152 {
3153 if (!CheckMsOs20Feature(Ctx, Info, Cursor, End, 0))
3154 Valid = FALSE;
3155
3156 /* Top level features must come before any subset */
3160 {
3162 Valid = FALSE;
3163 }
3164 }
3165
3167 {
3169 return FALSE;
3170 }
3171 }
3172
3173 return Valid;
3174}
3175
3177BOOLEAN
3178NTAPI
3179HubDescCheckMsOs20Set(
3185{
3187 return TRUE;
3188
3189 /* QUIRK: this also drops the set info and alternate enumeration bits from the BOS */
3190 Info->Flags = 0;
3191 return FALSE;
3192}
3193
3194/* Hub descriptors */
3195
3196BOOLEAN
3197NTAPI
3202{
3204 ULONG Fixed = FIELD_OFFSET(USB_HUB_DESCRIPTOR, bRemoveAndPowerMask);
3205 ULONG Ports;
3206 ULONG RemovableBytes;
3207 ULONG PowerBytes;
3209 ULONG Used;
3210 UCHAR Spare;
3211 ULONG i;
3212
3213 if (Descriptor == NULL)
3214 {
3216 return FALSE;
3217 }
3218
3219 if (Length < Fixed)
3220 {
3222 return FALSE;
3223 }
3224
3225 Ports = Descriptor->bNumberOfPorts;
3226 if (Ports == 0)
3228
3229 /* DeviceRemovable has a reserved bit 0 plus one bit per port; the power mask is legacy */
3230 RemovableBytes = (Ports + 8) / 8;
3231 PowerBytes = (Ports + 7) / 8;
3232 Expected = Fixed + RemovableBytes + PowerBytes;
3233
3234 if (Descriptor->bDescriptorLength < Expected)
3236
3237 if (Descriptor->bDescriptorLength > Expected)
3239
3240 if (Descriptor->bDescriptorType != USB_20_HUB_DESCRIPTOR_TYPE)
3242
3243 if (Descriptor->wHubCharacteristics & 0x0002)
3245
3246 if (Descriptor->wHubCharacteristics & 0xFF00)
3248
3249 if (Descriptor->bRemoveAndPowerMask[0] & 0x01)
3251
3252 /* Bits past the last port in the last DeviceRemovable byte */
3253 Used = (Ports + 1) % 8;
3254 if (Used != 0)
3255 {
3256 Spare = (UCHAR)(0xFF << Used);
3257 if (Descriptor->bRemoveAndPowerMask[RemovableBytes - 1] & Spare)
3259 }
3260
3261 for (i = 0; i < PowerBytes; i++)
3262 {
3263 if (Descriptor->bRemoveAndPowerMask[RemovableBytes + i] != 0xFF)
3265 }
3266
3267 return Result == Verdict::Ok;
3268}
3269
3270BOOLEAN
3271NTAPI
3276{
3278 ULONG Ports;
3279 ULONG Spare;
3280
3281 if (Descriptor == NULL)
3282 {
3283 DPRINT1("Hub %p has no SuperSpeed hub descriptor\n", Context->LogContext);
3284 return FALSE;
3285 }
3286
3287 if (Length < sizeof(USB_COMMON_DESCRIPTOR))
3288 {
3290 return FALSE;
3291 }
3292
3293 if (Descriptor->bLength < sizeof(*Descriptor))
3295
3296 if (Descriptor->bLength > sizeof(*Descriptor))
3298
3299 if (Descriptor->bDescriptorType != USB_30_HUB_DESCRIPTOR_TYPE)
3301
3302 Ports = Descriptor->bNumberOfPorts;
3303 if (Ports > 15)
3305
3306 if (Ports == 0)
3308
3309 if (Descriptor->wHubCharacteristics & 0x0002)
3311
3312 if (Descriptor->wHubCharacteristics & 0xFFE0)
3314
3315 if (Descriptor->bHubHdrDecLat >= 11)
3317
3318 if (Descriptor->DeviceRemovable & 0x0001)
3320
3321 /* Bits above the last port; with 15 or more ports none are left */
3322 Spare = (Ports + 1 < 16) ? (0xFFFFUL << (Ports + 1)) & 0xFFFF : 0;
3323 if (Descriptor->DeviceRemovable & Spare)
3325
3326 return Result == Verdict::Ok;
3327}
3328
3329/* Search helpers */
3330
3332NTAPI
3337 _In_ UCHAR Type)
3338{
3340 PUCHAR At = (PUCHAR)Position;
3341
3342 /* bLength is trusted; only the two header bytes are kept inside the buffer */
3343 while (At + sizeof(USB_COMMON_DESCRIPTOR) <= End)
3344 {
3346
3347 if (Desc->bLength == 0)
3348 return NULL;
3349
3350 if (Desc->bDescriptorType == Type)
3351 return Desc;
3352
3353 At += Desc->bLength;
3354 }
3355
3356 return NULL;
3357}
3358
3359static
3360BOOLEAN
3361NTAPI
3365{
3366 return Wanted == -1 || Wanted == (LONG)Actual;
3367}
3368
3370NTAPI
3375 _In_ LONG Alternate,
3376 _In_ LONG Class,
3377 _In_ LONG SubClass,
3379 _Out_opt_ PBOOLEAN HasAlternates)
3380{
3383 ULONG SameNumber = 0;
3384 PUCHAR At = (PUCHAR)Position;
3385
3386 if (HasAlternates != NULL)
3387 *HasAlternates = FALSE;
3388
3389 if (Config->bLength < sizeof(*Config) ||
3390 Config->bDescriptorType != USB_CONFIGURATION_DESCRIPTOR_TYPE ||
3391 Config->wTotalLength < sizeof(*Config))
3392 {
3393 return NULL;
3394 }
3395
3396 for (;;)
3397 {
3399 if (Match == NULL)
3400 return NULL;
3401
3402 /* Only the 2 byte header is known to be inside wTotalLength */
3403 if ((PUCHAR)Match + sizeof(*Match) > (PUCHAR)Config + Config->wTotalLength)
3404 return NULL;
3405
3406 At = (PUCHAR)Match + Match->bLength;
3407
3408 /* Every interface with the requested number counts, matching or not */
3409 if (Number != -1 && Match->bInterfaceNumber == Number)
3410 SameNumber++;
3411
3412 if (FieldMatches(Number, Match->bInterfaceNumber) &&
3413 FieldMatches(Alternate, Match->bAlternateSetting) &&
3415 FieldMatches(SubClass, Match->bInterfaceSubClass) &&
3417 {
3418 break;
3419 }
3420 }
3421
3422 if (HasAlternates == NULL)
3423 return Match;
3424
3425 /* QUIRK: only the very next interface is looked at, and never for a wildcard number */
3426 if (SameNumber <= 1)
3427 {
3429 if (Next != NULL && Number != -1 &&
3430 (PUCHAR)Next + sizeof(*Next) <= (PUCHAR)Config + Config->wTotalLength &&
3431 Next->bInterfaceNumber == Number)
3432 SameNumber++;
3433 }
3434
3435 if (SameNumber > 1)
3436 *HasAlternates = TRUE;
3437
3438 return Match;
3439}
DWORD Id
WCHAR First[]
Definition: FormatMessage.c:11
BOOLEAN Expected
Type
Definition: Type.h:7
unsigned char BOOLEAN
Definition: actypes.h:127
#define REG_SZ
Definition: layer.c:22
#define DPRINT1
Definition: precomp.h:8
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
Definition: bufpool.h:45
Definition: Header.h:9
UINT Depth
Definition: d3d12.idl:4644
static VOID NTAPI CheckPreviousEndpoint(_Inout_ ConfigWalk *Walk, _Inout_ Verdict *Result)
Definition: desccheck.cpp:682
#define HUB_MSOS20_TYPE_COMPATIBLE_ID
Definition: desccheck.cpp:2639
#define HUB_MSOS20_TYPE_SET_HEADER
Definition: desccheck.cpp:2636
Verdict
Definition: desccheck.cpp:15
Gate
Definition: desccheck.cpp:23
@ Versioned
@ Legacy
@ Warning
@ CapSsp
@ LogOnly
@ NewRule
@ Always
@ Reserved
#define HUB_MSOS20_TYPE_FUNCTION_SUBSET
Definition: desccheck.cpp:2638
static VOID NTAPI CheckMsOs20Platform(_Inout_ BosWalk *Walk, _In_ PUSB_DEVICE_CAPABILITY_PLATFORM_DESCRIPTOR Cap, _Inout_ Verdict *Result)
Definition: desccheck.cpp:1854
static BOOLEAN NTAPI WalkMsOs20Set(_In_ const HubDescContext *Ctx, _In_reads_bytes_(Length) PVOID Set, _In_ ULONG Length, _In_ const HubMsOs20SetInfo *SetInfo, _Inout_ HubMsOs20Info *Info)
Definition: desccheck.cpp:3102
VOID NTAPI HubDescInitHubContext(_Out_ HubDescContext *Context, _In_ USHORT BcdUsb, _In_ USB_DEVICE_SPEED Speed)
Definition: desccheck.cpp:112
ULONG Found
Definition: desccheck.cpp:2232
static VOID NTAPI CheckIad(_Inout_ ConfigWalk *Walk, _In_ PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR Desc, _Out_ PULONG Advance, _Inout_ Verdict *Result)
Definition: desccheck.cpp:1193
_In_ ULONG _Out_opt_ HubBosInfo * Info
Definition: desccheck.cpp:2217
static VOID NTAPI CheckSuperSpeedCap(_Inout_ BosWalk *Walk, _In_ PUSB_DEVICE_CAPABILITY_SUPERSPEED_USB_DESCRIPTOR Cap, _Inout_ PULONG Advance, _Inout_ Verdict *Result)
Definition: desccheck.cpp:1612
static BOOLEAN NTAPI CheckMsOs20ModelId(_In_ const HubDescContext *Ctx, _Inout_ HubMsOs20Info *Info, _In_ HubMsOs20Common *Desc)
Definition: desccheck.cpp:3005
Verdict Result
Definition: desccheck.cpp:2226
static VOID NTAPI CheckInterface(_Inout_ ConfigWalk *Walk, _In_ PUSB_INTERFACE_DESCRIPTOR Desc, _Out_ PULONG Advance, _Inout_ Verdict *Result)
Definition: desccheck.cpp:735
BOOLEAN NTAPI HubDescNextMsOs20(_In_ PUCHAR End, _Inout_ HubMsOs20Common **Current)
Definition: desccheck.cpp:2647
BOOLEAN NTAPI HubDescCheckMsOsString(_In_ const HubDescContext *Context, _In_ const HubMsOsString *Descriptor)
Definition: desccheck.cpp:2490
BOOLEAN NTAPI HubDescCheck30Hub(_In_ const HubDescContext *Context, _In_reads_bytes_opt_(Length) PUSB_30_HUB_DESCRIPTOR Descriptor, _In_ ULONG Length)
Definition: desccheck.cpp:3272
#define HUB_MSOS20_MAX_DEPTH
Definition: desccheck.cpp:40
static BOOLEAN NTAPI CheckMsOs20ResumeTime(_In_ const HubDescContext *Ctx, _Inout_ HubMsOs20Info *Info, _In_ HubMsOs20Common *Desc)
Definition: desccheck.cpp:2963
static BOOLEAN NTAPI CheckMsOs20CompatibleId(_In_ const HubDescContext *Ctx, _Inout_ HubMsOs20Info *Info, _In_ HubMsOs20Common *Desc)
Definition: desccheck.cpp:2871
BOOLEAN NTAPI HubDescCheckConfiguration(_In_ const HubDescContext *Context, _In_reads_bytes_opt_(Length) PUSB_CONFIGURATION_DESCRIPTOR Descriptor, _In_ ULONG Length, _Out_opt_ PBOOLEAN SupportsStreams)
Definition: desccheck.cpp:1237
VOID NTAPI HubDescLog(_In_ const HubDescContext *Context, _In_ HubDescCode Code, _In_ BOOLEAN Warning)
Definition: desccheck.cpp:383
static VOID NTAPI CheckBillboardCap(_Inout_ BosWalk *Walk, _Inout_ PUSB_DEVICE_CAPABILITY_BILLBOARD_DESCRIPTOR Cap, _Inout_ PULONG Advance, _Inout_ Verdict *Result)
Definition: desccheck.cpp:2028
static VOID NTAPI CheckPlatformFeatures(_Inout_ BosWalk *Walk, _In_ HubPlatformFeatures *Cap, _Inout_ Verdict *Result)
Definition: desccheck.cpp:1907
_In_ ULONG _Out_opt_ HubBosInfo _Out_opt_ PUSHORT _Out_opt_ PUSHORT _Inout_opt_ PBOOLEAN LtmCapable
Definition: desccheck.cpp:2220
static BOOLEAN NTAPI CheckMsOs20SetHeader(_In_ const HubDescContext *Ctx, _Inout_ HubMsOs20Info *Info, _In_ HubMsOs20Common *Desc)
Definition: desccheck.cpp:2705
BOOLEAN NTAPI HubDescCheckMsOsExtConfigHeader(_In_ const HubDescContext *Context, _In_reads_bytes_(Length) const HubMsOsExtConfigHeader *Descriptor, _In_ ULONG Length)
Definition: desccheck.cpp:2563
if(Length< sizeof(*Descriptor))
Definition: desccheck.cpp:2245
static VOID NTAPI CheckConfigFixedPart(_Inout_ ConfigWalk *Walk, _Inout_ Verdict *Result)
Definition: desccheck.cpp:636
BOOLEAN NTAPI HubDescCheckDevice(_In_ const HubDescContext *Context, _In_reads_bytes_opt_(Length) PUSB_DEVICE_DESCRIPTOR Descriptor, _In_ ULONG Length, _Inout_opt_ PBOOLEAN IsBillboard)
Definition: desccheck.cpp:1367
static BOOLEAN NTAPI CheckMsOs20Registry(_In_ const HubDescContext *Ctx, _Inout_ HubMsOs20Info *Info, _In_ HubMsOs20Common *Desc)
Definition: desccheck.cpp:2906
static VOID NTAPI CheckSspCompanion(_Inout_ ConfigWalk *Walk, _In_ PUSB_SUPERSPEEDPLUS_ISOCH_ENDPOINT_COMPANION_DESCRIPTOR Desc, _Out_ PULONG Advance, _Inout_ Verdict *Result)
Definition: desccheck.cpp:1141
#define HUB_MSOS20_TYPE_RESUME_TIME
Definition: desccheck.cpp:2641
#define HUB_MSOS20_TYPE_REGISTRY
Definition: desccheck.cpp:2640
_In_ ULONG _In_ const HubMsOs20SetInfo * SetInfo
Definition: desccheck.cpp:3183
static VOID NTAPI CheckHeader(_In_ const HubDescContext *Ctx, _In_ PUCHAR Base, _In_ ULONG BufferLength, _In_ PUCHAR End, _In_ PUSB_COMMON_DESCRIPTOR Desc, _Out_ PULONG Advance, _Inout_ Verdict *Result)
Definition: desccheck.cpp:591
PUCHAR Limit
Definition: desccheck.cpp:2230
static BOOLEAN NTAPI GateApplies(_In_ const HubDescContext *Ctx, _In_ Gate Kind)
Definition: desccheck.cpp:418
static BOOLEAN NTAPI IsMsOsIdChar(_In_ UCHAR Ch)
Definition: desccheck.cpp:2462
TRUE
Definition: desccheck.cpp:2267
static VOID NTAPI CheckPowerDeliveryCap(_Inout_ BosWalk *Walk, _In_ PUSB_DEVICE_CAPABILITY_POWER_DELIVERY_DESCRIPTOR Cap, _Inout_ PULONG Advance, _Inout_ Verdict *Result)
Definition: desccheck.cpp:1988
static VOID NTAPI NoteFatal(_In_ const HubDescContext *Ctx, _Inout_ Verdict *Result, _In_ HubDescCode Code)
Definition: desccheck.cpp:481
VOID NTAPI HubDescInitDeviceContext(_Out_ HubDescContext *Context, _In_ USHORT BcdUsb, _In_ USB_DEVICE_SPEED Speed, _In_ BOOLEAN Win8Behavior, _In_ ULONG SspIsochBurstCount, _In_opt_ PULONG Bitmap)
Definition: desccheck.cpp:91
Walk Base
Definition: desccheck.cpp:2270
BOOLEAN NTAPI HubDescCheck20Hub(_In_ const HubDescContext *Context, _In_reads_bytes_opt_(Length) PUSB_HUB_DESCRIPTOR Descriptor, _In_ ULONG Length)
Definition: desccheck.cpp:3198
static Verdict NTAPI CheckStringCore(_In_ const HubDescContext *Ctx, _In_reads_bytes_(Length) PUSB_STRING_DESCRIPTOR Desc, _In_ ULONG Length, _Out_ PULONG Adjusted)
Definition: desccheck.cpp:2354
static BOOLEAN NTAPI FieldMatches(_In_ LONG Wanted, _In_ UCHAR Actual)
Definition: desccheck.cpp:3362
_In_ ULONG _Out_opt_ HubBosInfo _Out_opt_ PUSHORT U1ExitLatency
Definition: desccheck.cpp:2218
#define HUB_MSOS20_TYPE_MODEL_ID
Definition: desccheck.cpp:2642
static BOOLEAN NTAPI MsOs20VersionUsable(_In_ ULONG Version)
Definition: desccheck.cpp:1845
BOOLEAN NTAPI HubDescCheckSerialNumber(_In_ const HubDescContext *Context, _In_reads_bytes_(*Length) PUSB_STRING_DESCRIPTOR Descriptor, _Inout_ PULONG Length)
Definition: desccheck.cpp:2418
static VOID NTAPI CheckSublinkSpeeds(_In_ const HubDescContext *Ctx, _In_ PUSB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_USB_DESCRIPTOR Cap, _In_ ULONG Present, _Inout_ Verdict *Result)
Definition: desccheck.cpp:1673
PUCHAR End
Definition: desccheck.cpp:2229
static BOOLEAN NTAPI BitIsSet(_In_reads_(8) const ULONG *Bits, _In_ UCHAR Index)
Definition: desccheck.cpp:529
_In_ ULONG _Out_opt_ HubBosInfo _Out_opt_ PUSHORT _Out_opt_ PUSHORT U2ExitLatency
Definition: desccheck.cpp:2219
#define HUB_MSOS20_TYPE_CCGP
Definition: desccheck.cpp:2643
static VOID NTAPI CheckContainerIdCap(_Inout_ BosWalk *Walk, _In_ PUSB_DEVICE_CAPABILITY_CONTAINER_ID_DESCRIPTOR Cap, _Inout_ PULONG Advance, _Inout_ Verdict *Result)
Definition: desccheck.cpp:1805
static VOID NTAPI CheckCompanion(_Inout_ ConfigWalk *Walk, _In_ PUSB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR Desc, _Out_ PULONG Advance, _Inout_ Verdict *Result)
Definition: desccheck.cpp:1007
static VOID NTAPI CheckBosFixedPart(_In_ const HubDescContext *Ctx, _In_opt_ PUSB_BOS_DESCRIPTOR Bos, _In_ ULONG Length, _Out_ PUCHAR *End, _Out_ PULONG Advance, _Inout_ Verdict *Result)
Definition: desccheck.cpp:1466
static BOOLEAN NTAPI CheckMsOs20Feature(_In_ const HubDescContext *Ctx, _Inout_ HubMsOs20Info *Info, _In_ HubMsOs20Common *Desc, _In_ PUCHAR End, _In_ ULONG Depth)
Definition: desccheck.cpp:3063
static VOID NTAPI StartCheck(_In_ const HubDescContext *Ctx, _Inout_ Verdict *Result)
Definition: desccheck.cpp:494
PUSB_COMMON_DESCRIPTOR NTAPI HubDescFind(_In_reads_bytes_(TotalLength) PVOID Buffer, _In_ ULONG TotalLength, _In_ PVOID Position, _In_ UCHAR Type)
Definition: desccheck.cpp:3333
BOOLEAN NTAPI HubDescCheckMsOsContainerId(_In_ const HubDescContext *Context, _In_reads_bytes_(Length) const HubMsOsContainerId *Descriptor, _In_ ULONG Length)
Definition: desccheck.cpp:2541
Walk Ctx
Definition: desccheck.cpp:2269
static BOOLEAN NTAPI AssumeSize(_In_ const HubDescContext *Ctx, _Inout_ Verdict *Result, _In_ HubDescCode Code, _In_ Gate Kind, _In_ ULONG Size, _In_ ULONG Left, _Inout_ PULONG Advance)
Definition: desccheck.cpp:506
static BOOLEAN NTAPI CheckMsOs20Id(_In_ const HubDescContext *Ctx, _In_reads_(8) const UCHAR *Id)
Definition: desccheck.cpp:2839
BOOLEAN NTAPI HubDescCheckMsOsContainerIdHeader(_In_ const HubDescContext *Context, _In_reads_bytes_(Length) const HubMsOsHeader *Descriptor, _In_ ULONG Length)
Definition: desccheck.cpp:2505
static VOID NTAPI CheckUsb20Cap(_Inout_ BosWalk *Walk, _In_ PUSB_DEVICE_CAPABILITY_USB20_EXTENSION_DESCRIPTOR Cap, _Inout_ PULONG Advance, _Inout_ Verdict *Result)
Definition: desccheck.cpp:1527
static BOOLEAN NTAPI IsAllZero(_In_reads_bytes_(Length) const VOID *Buffer, _In_ ULONG Length)
Definition: desccheck.cpp:549
static ULONG NTAPI BytesLeft(_In_ PUCHAR Base, _In_ ULONG BufferLength, _In_ const VOID *Descriptor)
Definition: desccheck.cpp:579
static VOID NTAPI CheckEndpointType(_In_ ConfigWalk *Walk, _In_ PUSB_ENDPOINT_DESCRIPTOR Desc, _Inout_ Verdict *Result)
Definition: desccheck.cpp:813
BOOLEAN NTAPI HubDescCheckString(_In_ const HubDescContext *Context, _In_reads_bytes_(Length) PUSB_STRING_DESCRIPTOR Descriptor, _In_ ULONG Length, _Out_opt_ PULONG AdjustedLength)
Definition: desccheck.cpp:2400
_In_ ULONG Length
Definition: desccheck.cpp:2216
static BOOLEAN NTAPI IsSmallPacket(_In_ ULONG Size)
Definition: desccheck.cpp:569
PUSB_INTERFACE_DESCRIPTOR NTAPI HubDescFindInterface(_In_ PUSB_CONFIGURATION_DESCRIPTOR Config, _In_ PVOID Position, _In_ LONG Number, _In_ LONG Alternate, _In_ LONG Class, _In_ LONG SubClass, _In_ LONG Protocol, _Out_opt_ PBOOLEAN HasAlternates)
Definition: desccheck.cpp:3371
return FALSE
Definition: desccheck.cpp:3191
static BOOLEAN NTAPI CheckMsOs20Subset(_In_ const HubDescContext *Ctx, _Inout_ HubMsOs20Info *Info, _In_ HubMsOs20Common *Desc, _In_ PUCHAR End, _In_ ULONG Depth)
Definition: desccheck.cpp:2747
PCSTR NTAPI HubDescCodeName(_In_ HubDescCode Code)
Definition: desccheck.cpp:128
PUCHAR Cursor
Definition: desccheck.cpp:2228
static BOOLEAN NTAPI MsOs20AllowedIn(_In_ BOOLEAN Function, _In_ ULONG Type)
Definition: desccheck.cpp:2734
_In_ ULONG _Out_opt_ HubBosInfo _Out_opt_ PUSHORT _Out_opt_ PUSHORT _Inout_opt_ PBOOLEAN _Inout_opt_ HubLpmInfo _Inout_opt_ PULONG DeviceFlags
Definition: desccheck.cpp:2223
static VOID NTAPI CheckSuperSpeedPlusCap(_Inout_ BosWalk *Walk, _In_ PUSB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_USB_DESCRIPTOR Cap, _Inout_ PULONG Advance, _Inout_ Verdict *Result)
Definition: desccheck.cpp:1760
static VOID NTAPI CheckPreviousInterface(_Inout_ ConfigWalk *Walk, _Inout_ Verdict *Result)
Definition: desccheck.cpp:712
static BOOLEAN NTAPI CheckMsOs20Ccgp(_In_ const HubDescContext *Ctx, _Inout_ HubMsOs20Info *Info, _In_ HubMsOs20Common *Desc)
Definition: desccheck.cpp:3038
BosWalk Walk
Definition: desccheck.cpp:2225
BOOLEAN Valid
Definition: desccheck.cpp:2227
static VOID NTAPI BitSet(_Inout_updates_(8) PULONG Bits, _In_ UCHAR Index)
Definition: desccheck.cpp:539
static const GUID HubPlatformFeaturesUuid
Definition: desccheck.cpp:45
_In_ ULONG _Out_opt_ HubBosInfo _Out_opt_ PUSHORT _Out_opt_ PUSHORT _Inout_opt_ PBOOLEAN _Inout_opt_ HubLpmInfo * Lpm
Definition: desccheck.cpp:2221
static VOID NTAPI CheckEndpoint(_Inout_ ConfigWalk *Walk, _In_ PUSB_ENDPOINT_DESCRIPTOR Desc, _Out_ PULONG Advance, _Inout_ Verdict *Result)
Definition: desccheck.cpp:945
#define HUB_DESC_NAME(Code)
Definition: desccheck.cpp:124
ULONG Advance
Definition: desccheck.cpp:2231
#define HUB_MSOS20_TYPE_CONFIG_SUBSET
Definition: desccheck.cpp:2637
BOOLEAN NTAPI HubDescCheckMsOsExtConfig(_In_ const HubDescContext *Context, _In_reads_bytes_(sizeof(HubMsOsExtConfig)) const HubMsOsExtConfig *Descriptor, _In_ ULONG Length)
Definition: desccheck.cpp:2606
static BOOLEAN NTAPI IsMsOs10IdValid(_In_reads_(8) const UCHAR *Id)
Definition: desccheck.cpp:2471
#define HUB_MSOS20_NEWEST_VERSION
Definition: desccheck.cpp:37
static VOID NTAPI CheckPlatformCap(_Inout_ BosWalk *Walk, _In_ PUSB_DEVICE_CAPABILITY_PLATFORM_DESCRIPTOR Cap, _Inout_ PULONG Advance, _Inout_ Verdict *Result)
Definition: desccheck.cpp:1945
static VOID NTAPI CheckCapability(_Inout_ BosWalk *Walk, _Inout_ PUSB_DEVICE_CAPABILITY_DESCRIPTOR Cap, _Out_ PULONG Advance, _Inout_ Verdict *Result)
Definition: desccheck.cpp:2091
BOOLEAN NTAPI HubDescCheckBosHeader(_In_ const HubDescContext *Context, _In_reads_bytes_opt_(Length) PUSB_BOS_DESCRIPTOR Descriptor, _In_ ULONG Length)
Definition: desccheck.cpp:2197
static const GUID HubMsOs20PlatformUuid
Definition: desccheck.cpp:42
static VOID NTAPI Note(_In_ const HubDescContext *Ctx, _Inout_ Verdict *Result, _In_ HubDescCode Code, _In_ Gate Kind)
Definition: desccheck.cpp:463
#define HUB_MSOS20_COMPATIBLE_ID
Definition: desccheck.h:493
#define HUB_MSOS20_REGISTRY
Definition: desccheck.h:494
#define HUB_BOS_SUPERSPEED_CAPABLE
Definition: desccheck.h:316
#define HUB_MSOS20_CONFIG_SUBSET
Definition: desccheck.h:491
#define HUB_MSOS20_RESUME_TIME
Definition: desccheck.h:495
#define HUB_MSOS20_FUNCTION_SUBSET
Definition: desccheck.h:492
#define HUB_DESC_BITMAP_ULONGS
Definition: desccheck.h:263
HubDescCode
Definition: desccheck.h:15
@ MsOs20PlatformLength
@ ConfigBufferTooSmall
@ PlatformBufferTooSmall
@ SspCapAttributesReserved
@ ConfigTotalLengthTooLarge
@ FunctionSubsetLength
@ CompanionControlBytesPerInterval
@ PlatformFeaturesVersion
@ MsOs20ResumeTimeLength
@ MsOs20MultiplePlatform
@ CapMultipleBillboard
@ InterfaceBufferTooSmall
@ SspCompanionLengthTooSmall
@ BillboardPreferredInvalid
@ Hub20RemovableReserved
@ MsOsContainerIdIndex
@ MsOs20MultipleResumeTime
@ IadFirstInterfaceTooLarge
@ ConfigLengthTooSmall
@ Hub20RemovableMissingPort
@ MsOsExtConfigBufferSize
@ FunctionSubsetMisplacedFeature
@ FirstAlternateNotZero
@ BosBufferLargerThanTotal
@ DeviceBufferTooSmall
@ SsCapAttributesReserved
@ EndpointCountMismatch
@ MsOsExtConfigCompatibleId
@ SspCompanionBytesRange
@ MsOs20RegistryNameTooLarge
@ ConfigSubsetMisplacedFeature
@ FunctionSubsetTotalTooLarge
@ CompanionBulkReserved
@ MsOsExtConfigFirstInterface
@ SspCompanionNotSuperSpeed
@ PlatformFeaturesTooSmall
@ BosTotalLengthTooSmall
@ MsOs20RegistryDataTooLarge
@ Hub30RemovableMissingPort
@ MsOs20RegistryTooSmall
@ MsOsContainerIdVersion
@ DeepBeslNotAboveBaseline
@ ConfigMissingCompanion
@ BillboardDeviceVersion
@ ConfigLengthTooLarge
@ CompanionIsochReserved
@ MsOs20BytesVsSetInfo
@ MsOs20NoVersionMatch
@ CompanionInterruptBurst
@ SspCapBufferTooSmall
@ EndpointBeforeInterface
@ EndpointAddressReserved
@ FunctionSubsetFeatureLength
@ SsCapFunctionalityReserved
@ BillboardTooManyModes
@ BillboardBufferTooSmall
@ ContainerIdLengthTooLarge
@ CompanionInterruptBytesPerInterval
@ CompanionInterruptAttributes
@ IsochPacketInAlternate0
@ CapMultipleContainerId
@ CompanionIsochBytesPerInterval
@ MsOs20ResumeSignaling
@ BulkAttributesReserved
@ FunctionSubsetTotalTooSmall
@ SspCompanionLengthTooLarge
@ MsOs20CompatibleIdAfterNull
@ MsOs20CompatibleIdLength
@ PlatformLengthTooSmall
@ EndpointAttributesReserved
@ CompanionLengthTooSmall
@ CompanionControlBurst
@ DeviceLengthTooSmall
@ MsOsExtConfigBufferVsLength
@ MsOs20RegistryNameOddOrZero
@ SspCapFunctionalityReserved
@ InterfaceLengthTooLarge
@ InterfaceLengthTooSmall
@ MsOsExtConfigSubCompatibleId
@ InterruptAttributesReserved
@ PlatformFeaturesLength
@ CompanionControlAttributes
@ SsCapFunctionalityNotInSpeeds
@ MsOsContainerIdBufferSize
@ HeaderPastTotalLength
@ ConfigSubsetFeatureLength
@ Usb20CapBufferTooSmall
@ MsOs20SetHeaderLength
@ Hub30CharacteristicsReserved
@ SspCompanionBufferTooSmall
@ StringLengthTooSmall
@ ConfigTotalLengthTooSmall
@ MsOs20MultipleSetHeaders
@ MsOs20FeatureOutOfOrder
@ CompanionLengthTooLarge
@ MsOsExtConfigLengthVsCount
@ CompanionBulkStreams
@ MsOsContainerIdLength
@ SspCompanionUnexpected
@ EndpointLengthTooLarge
@ BillboardLengthInvalid
@ ContainerIdBufferTooSmall
@ CompanionBufferTooSmall
@ PlatformFeaturesMultiple
@ Usb20CapLengthTooSmall
@ DuplicateSerialNumber
@ ContainerIdLengthTooSmall
@ CompanionInterruptBurstPacket
@ Usb20CapLengthTooLarge
@ CompanionBulkBytesPerInterval
@ Hub30RemovableReserved
@ BillboardLengthTooSmall
@ StringLengthTooLarge
@ ConfigSubsetTotalTooSmall
@ ConfigSubsetTotalTooLarge
@ HeaderLengthTooSmall
@ CompanionIsochBurstPacket
@ ConfigMissingSspCompanion
@ StringBufferTooSmall
@ MsOs20RegistryDataZero
@ EndpointLengthTooSmall
@ MsOs20ResumeRecovery
@ MsOs20TotalLengthMismatch
@ MsOs20MultipleModelId
@ SerialNumberBadCharacter
@ ControlAttributesReserved
@ HeaderBufferTooSmall
@ Hub30DecodeLatencyReserved
@ Hub20PowerMaskNotOnes
@ CompanionNotSuperSpeed
@ SspCompanionReserved
@ Hub20CharacteristicsReserved
@ MsOsExtConfigVersion
@ CapMultipleSuperSpeedPlus
@ SspAttrSymmetricMismatch
@ CapMultipleSuperSpeed
@ MsOs20MultipleCompatibleId
@ MsOs20VersionMismatch
@ EndpointBufferTooSmall
@ CompanionIsochBytesNotOne
@ SspCapLengthTooSmall
@ ConfigBufferTooSmallForInterfaces
@ MsOs20DuplicateVersion
#define HUB_MSOS20_MODEL_ID
Definition: desccheck.h:496
#define HUB_BOS_ENHANCED_SUPERSPEED_CAPABLE
Definition: desccheck.h:317
#define HUB_BOS_CHARGING_POLICY
Definition: desccheck.h:318
#define HUB_MSOS20_SET_HEADER
Definition: desccheck.h:489
#define HUB_MSOS20_CCGP
Definition: desccheck.h:497
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
ULONG Actual
Definition: devhcd.cpp:1400
_In_ ULONG Attributes
Definition: dispmprt.h:1077
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ ULONG _In_ ULONG DataLength
Definition: dispmprt.h:233
#define NULL
Definition: types.h:112
#define L(x)
Definition: resources.c:13
#define _IRQL_requires_(irql)
Definition: driverspecs.h:229
HubDriverState HubDriver
Definition: entry.cpp:13
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
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
_In_ ULONG Mode
Definition: hubbusif.h:303
@ StrictDescriptorChecks
@ EnableExtendedValidation
@ CheckReservedFields
HubUxdSettings Current
_In_ PCWSTR _Out_ PULONG _Out_ PBOOLEAN Present
ULONG Chars
Definition: hubtunnel.cpp:833
_In_ UCXHUB_DEVICE_CONTEXT _In_ UCXENDPOINT Endpoint
Definition: hubucx.h:238
ULONG Total
Definition: hubwmi.cpp:548
_In_ ULONG Wanted
Definition: intr.cpp:782
#define RtlEqualMemory(dst, src, len)
Definition: kdvm.h:18
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
_In_ UINT Bytes
Definition: mmcopy.h:9
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1549
_In_ ULONG Number
Definition: haltypes.h:1940
#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_updates_(s)
Definition: no_sal2.h:182
#define _Inout_
Definition: no_sal2.h:162
#define _Inout_opt_
Definition: no_sal2.h:216
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define _Inout_updates_bytes_(s)
Definition: no_sal2.h:184
#define _In_reads_bytes_opt_(s)
Definition: no_sal2.h:224
#define REG_MULTI_SZ
Definition: nt_native.h:1504
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:684
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
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
Input NameLength
Definition: portacpi.cpp:298
static PS2_PORT Ports[PS2_PORTS]
Definition: ps2.c:52
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
PACPI_METHOD_ARGUMENT Next
Definition: slotdev.cpp:96
_In_ const GUID * Uuid
Definition: slotdev.cpp:84
#define DPRINT
Definition: sndvol32.h:73
PUCHAR Base
Definition: desccheck.cpp:78
const HubDescContext * Ctx
Definition: desccheck.cpp:77
PBOOLEAN Ltm
Definition: desccheck.cpp:83
PUSHORT U1
Definition: desccheck.cpp:81
HubLpmInfo * Lpm
Definition: desccheck.cpp:84
HubBosInfo * Info
Definition: desccheck.cpp:80
ULONG BufferLength
Definition: desccheck.cpp:79
PUSHORT U2
Definition: desccheck.cpp:82
BOOLEAN HadInterface
Definition: desccheck.cpp:66
const HubDescContext * Ctx
Definition: desccheck.cpp:51
BOOLEAN WantSspCompanion
Definition: desccheck.cpp:69
PUSB_CONFIGURATION_DESCRIPTOR Config
Definition: desccheck.cpp:55
ULONG InterfacesFound
Definition: desccheck.cpp:61
BOOLEAN GotCompanion
Definition: desccheck.cpp:70
ULONG EndpointsCounted
Definition: desccheck.cpp:63
ULONG BufferLength
Definition: desccheck.cpp:53
ULONG EndpointSeen[8]
Definition: desccheck.cpp:60
PUCHAR End
Definition: desccheck.cpp:54
UCHAR Alternate
Definition: desccheck.cpp:65
ULONG InterfaceSeen[8]
Definition: desccheck.cpp:58
UCHAR Interface
Definition: desccheck.cpp:64
BOOLEAN HadEndpoint
Definition: desccheck.cpp:67
PUCHAR Base
Definition: desccheck.cpp:52
ULONG EndpointsDeclared
Definition: desccheck.cpp:62
BOOLEAN GotSspCompanion
Definition: desccheck.cpp:71
BOOLEAN WantCompanion
Definition: desccheck.cpp:68
PUSB_ENDPOINT_DESCRIPTOR LastEndpoint
Definition: desccheck.cpp:57
ULONG AlternateSeen[8]
Definition: desccheck.cpp:59
PBOOLEAN SupportsStreams
Definition: desccheck.cpp:56
HubPlatformFeatures * PlatformFeatures
Definition: desccheck.h:481
BOOLEAN ChargingPolicy
Definition: desccheck.h:484
HubMsOs20SetInfo * MsOs20SetInfo
Definition: desccheck.h:479
BOOLEAN DiscardContainerId
Definition: desccheck.h:483
BOOLEAN HasFlag(_In_ HubGlobal Flag) const
Definition: hubdriver.h:119
USHORT wLength
Definition: desccheck.h:347
USHORT wDescriptorType
Definition: desccheck.h:348
UCHAR ModelId[16]
Definition: desccheck.h:398
USHORT wPropertyDataType
Definition: desccheck.h:382
USHORT wPropertyNameLength
Definition: desccheck.h:383
UCHAR bResumeSignalingTime
Definition: desccheck.h:391
UCHAR bResumeRecoveryTime
Definition: desccheck.h:390
ULONG dwWindowsVersion
Definition: desccheck.h:325
USHORT wTotalLength
Definition: desccheck.h:366
USHORT wLength
Definition: desccheck.h:362
static const VBE_MODE Modes[VBE_MODE_COUNT]
Definition: vbe.c:189
static COORD Position
Definition: mouse.c:34
uint32_t * PULONG
Definition: typedefs.h:59
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
uint16_t * PUSHORT
Definition: typedefs.h:56
const char * PCSTR
Definition: typedefs.h:52
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG Config
#define USB_ENDPOINT_TYPE_INTERRUPT
Definition: usb100.h:65
#define USB_CONFIGURATION_DESCRIPTOR_TYPE
Definition: usb100.h:50
#define USB_ENDPOINT_DESCRIPTOR_TYPE
Definition: usb100.h:53
struct _USB_INTERFACE_DESCRIPTOR * PUSB_INTERFACE_DESCRIPTOR
#define USB_ENDPOINT_TYPE_CONTROL
Definition: usb100.h:62
#define USB_DEVICE_DESCRIPTOR_TYPE
Definition: usb100.h:49
#define USB_STRING_DESCRIPTOR_TYPE
Definition: usb100.h:51
#define USB_ENDPOINT_TYPE_ISOCHRONOUS
Definition: usb100.h:63
struct _USB_COMMON_DESCRIPTOR * PUSB_COMMON_DESCRIPTOR
struct _USB_INTERFACE_DESCRIPTOR USB_INTERFACE_DESCRIPTOR
#define USB_ENDPOINT_TYPE_MASK
Definition: usb100.h:61
#define USB_INTERFACE_DESCRIPTOR_TYPE
Definition: usb100.h:52
struct _USB_COMMON_DESCRIPTOR USB_COMMON_DESCRIPTOR
#define USB_ENDPOINT_TYPE_BULK
Definition: usb100.h:64
@ UsbSuperSpeed
Definition: usb200.h:45
@ UsbHighSpeed
Definition: usb200.h:44
@ UsbLowSpeed
Definition: usb200.h:42
@ UsbFullSpeed
Definition: usb200.h:43
#define USB_DEVICE_CLASS_BILLBOARD
Definition: usb200.h:308
enum _USB_DEVICE_SPEED USB_DEVICE_SPEED
#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE
Definition: usb200.h:118
#define USB_20_HUB_DESCRIPTOR_TYPE
Definition: usb200.h:280
#define USB_30_HUB_DESCRIPTOR_TYPE
Definition: usb200.h:281
#define USB_DEVICE_CAPABILITY_CONTAINER_ID
Definition: usb300.h:28
#define USB_DEVICE_CAPABILITY_SUPERSPEED_SPEEDS_SUPPORTED_RESERVED_MASK
Definition: usb300.h:43
#define USB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_SPEED_MODE_SYMMETRIC
Definition: usb300.h:57
#define USB_DEVICE_CAPABILITY_SUPERSPEED_USB
Definition: usb300.h:27
struct _USB_DEVICE_CAPABILITY_USB20_EXTENSION_DESCRIPTOR * PUSB_DEVICE_CAPABILITY_USB20_EXTENSION_DESCRIPTOR
#define USB_BOS_DESCRIPTOR_TYPE
Definition: usb300.h:17
#define USB_DEVICE_CAPABILITY_SUPERSPEED_U2_DEVICE_EXIT_MAX_VALUE
Definition: usb300.h:49
struct _USB_DEVICE_CAPABILITY_BILLBOARD_DESCRIPTOR * PUSB_DEVICE_CAPABILITY_BILLBOARD_DESCRIPTOR
#define USB_DEVICE_CAPABILITY_PLATFORM
Definition: usb300.h:29
#define USB_DEVICE_CAPABILITY_BILLBOARD
Definition: usb300.h:36
struct _USB_DEVICE_CAPABILITY_CONTAINER_ID_DESCRIPTOR * PUSB_DEVICE_CAPABILITY_CONTAINER_ID_DESCRIPTOR
struct _USB_DEVICE_CAPABILITY_SUPERSPEED_USB_DESCRIPTOR * PUSB_DEVICE_CAPABILITY_SUPERSPEED_USB_DESCRIPTOR
#define USB_DEVICE_CAPABILITY_SUPERSPEED_U1_DEVICE_EXIT_MAX_VALUE
Definition: usb300.h:48
#define USB_SUPERSPEEDPLUS_ISOCH_ENDPOINT_COMPANION_DESCRIPTOR_TYPE
Definition: usb300.h:20
#define USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR_TYPE
Definition: usb300.h:19
#define USB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_USB
Definition: usb300.h:34
#define USB_DEVICE_CAPABILITY_POWER_DELIVERY
Definition: usb300.h:30
#define USB_DEVICE_CAPABILITY_USB20_EXTENSION_BMATTRIBUTES_RESERVED_MASK
Definition: usb300.h:39
#define USB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_SPEED_DIR_RX
Definition: usb300.h:59
#define USB_DEVICE_CAPABILITY_SUPERSPEED_BMATTRIBUTES_RESERVED_MASK
Definition: usb300.h:41
#define USB_DEVICE_CAPABILITY_DESCRIPTOR_TYPE
Definition: usb300.h:18
#define USB_DEVICE_CAPABILITY_USB20_EXTENSION
Definition: usb300.h:26
struct _USB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_USB_DESCRIPTOR * PUSB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_USB_DESCRIPTOR
#define USB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_SPEED_DIR_TX
Definition: usb300.h:60
_In_ ULONG TotalLength
Definition: usbdlib.h:185
USHORT Count
Definition: userreq.cpp:200
_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
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_In_ UCHAR _In_ UCHAR _In_ ULONG Code
Definition: wdfdevice.h:1707
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3777
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE _In_ USHORT _In_ USHORT Version
Definition: wdffdo.h:469
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342