ReactOS 0.4.17-dev-1281-g065abb3
devdesc.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: Checks and caching of the descriptors read from a child device
5 * COPYRIGHT: Copyright 2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8#include "usbhub3.h"
9#include "devreq.h"
10
11#define NDEBUG
12#include <debug.h>
13
14/* Bytes of the device descriptor the first read keeps */
15#define DESC_FIRST_READ_KEEP 8
16
17/* A flash drive that must not use fast enumeration */
18#define DESC_SLOW_ENUM_VENDOR 0x13FE
19#define DESC_SLOW_ENUM_PRODUCT 0x5200
20
21/* Interface association class codes of a composite device */
22#define DESC_CLASS_MISCELLANEOUS 0xEF
23#define DESC_SUBCLASS_COMMON 0x02
24#define DESC_PROTOCOL_IAD 0x01
25
26/* USB Attached SCSI interface */
27#define DESC_SUBCLASS_SCSI 0x06
28#define DESC_PROTOCOL_UAS 0x62
29
30/* Two configured bits per alternate mode in bmConfigured; 3 means configured */
31#define DESC_MODE_CONFIGURED 3
32
33VOID
38{
40 Child->m_DeviceDescriptor.bcdUSB,
41 Child->Speed(),
43 Child->m_Port->m_Info.SspIsochBurstCount,
44 Child->m_ValidationBits);
45
46 /* Only names the device in the validator's debug prints */
47 Context->LogContext = Child;
48}
49
50static
51VOID
56{
57 InterlockedOr(&Child->m_SqmFlags, (LONG)Flag);
58}
59
60/* Device descriptor */
61
62/*
63 * VID and PID stay from the last full read. QUIRK: the VID/PID errata match
64 * reads the scratch buffer even when fewer than 12 bytes came back.
65 */
68{
73
75 {
76 DPRINT1("Device %p first device descriptor read returned %lu bytes\n", Child, Bytes);
78 return FALSE;
79 }
80
83 {
84 Child->m_EnumMessageId = HUB_ENUM_BAD_DEVICE_DESCRIPTOR;
85 return FALSE;
86 }
87
88 Child->m_MaxPacketSize0 = Descriptor->bMaxPacketSize0;
89 RtlCopyMemory(&Child->m_DeviceDescriptor, Descriptor, DESC_FIRST_READ_KEEP);
90
91 if (Descriptor->idVendor == DESC_SLOW_ENUM_VENDOR && Descriptor->idProduct == DESC_SLOW_ENUM_PRODUCT)
92 Child->m_Hacks |= (ULONG)ChildHack::AlwaysSecondReset;
93
94 return TRUE;
95}
96
99{
103 BOOLEAN IsBillboard = FALSE;
105
106 if (Bytes != sizeof(*Descriptor))
107 {
108 DPRINT1("Device %p device descriptor read returned %lu bytes\n", Child, Bytes);
110 return FALSE;
111 }
112
114 if (!HubDescCheckDevice(&Context, Descriptor, Bytes, &IsBillboard))
115 {
116 Child->m_EnumMessageId = HUB_ENUM_BAD_DEVICE_DESCRIPTOR;
117 return FALSE;
118 }
119
120 RtlCopyMemory(&Child->m_DeviceDescriptor, Descriptor, sizeof(*Descriptor));
121
122 if (IsBillboard)
123 Child->SetProperty(ChildProperty::HasBillboard);
124
125 return TRUE;
126}
127
128/* Configuration descriptor */
129
132{
134
135 return Header->bDescriptorType == USB_CONFIGURATION_DESCRIPTOR_TYPE &&
136 HubDeviceBytesReturned(m_Device) < Header->wTotalLength;
137}
138
139static
141NTAPI
145{
146 if (Device->bNumConfigurations != 1 || Config->bNumInterfaces <= 1)
147 return FALSE;
148
149 if (Device->bDeviceClass == 0)
150 return TRUE;
151
152 return Device->bDeviceClass == DESC_CLASS_MISCELLANEOUS &&
153 Device->bDeviceSubClass == DESC_SUBCLASS_COMMON &&
154 Device->bDeviceProtocol == DESC_PROTOCOL_IAD;
155}
156
157/*
158 * Picks the interface for the compatible ids. A hub or a fast enough UAS device
159 * also gets a decorated serial number to keep its instance ids distinct.
160 */
161static
162VOID
163NTAPI
167{
170 USB_DEVICE_SPEED Speed = Child->Speed();
171 BOOLEAN FastEnough;
172
173 Interface = HubDescFindInterface(Config, Config, -1, -1, -1, -1, -1, NULL);
174 Child->m_CompatIdInterface = Interface;
175 if (Interface == NULL)
176 return;
177
178 if (Interface->bInterfaceClass == USB_DEVICE_CLASS_HUB)
179 {
180 Child->SetProperty(ChildProperty::IsHub);
182 return;
183 }
184
185 /* QUIRK: only UsbSuperSpeed qualifies, not a SuperSpeedPlus speed value */
186 FastEnough = (Speed == UsbSuperSpeed && Child->m_Hub->m_StreamsSupported) || Speed == UsbHighSpeed;
187
188 if (Child->HasProperty(ChildProperty::IsComposite) ||
189 Child->m_DeviceDescriptor.bcdUSB <= 0x0200 ||
190 Child->HasHack(ChildHack::DisableUasp) ||
191 !FastEnough)
192 {
193 return;
194 }
195
197 Config,
198 Interface->bInterfaceNumber,
199 -1,
203 NULL);
204 if (Uas != NULL)
205 {
207 Child->m_CompatIdInterface = Uas;
208 }
209}
210
211/* QUIRK: when the set fit in the first read the length check compares the header with itself */
214{
217 PUSB_CONFIGURATION_DESCRIPTOR Config = Child->m_ConfigDescriptor ? Child->m_ConfigDescriptor : Header;
219 BOOLEAN Streams = FALSE;
221
223
225 {
226 Child->m_EnumMessageId = HUB_ENUM_BAD_CONFIG_DESCRIPTOR;
227 return FALSE;
228 }
229
230 if (Config->wTotalLength != Header->wTotalLength)
231 {
232 HubDescLog(&Context, HubDescCode::ConfigTotalLengthTooLarge, FALSE);
233 Child->m_EnumMessageId = HUB_ENUM_BAD_CONFIG_DESCRIPTOR;
234 return FALSE;
235 }
236
237 Child->SetState(ChildState::ConfigurationValid);
238
239 if (Streams)
240 HubSetSqmFlag(Child, ChildSqm::SupportsStreams);
241 if (Child->m_DeviceDescriptor.bNumConfigurations > 1)
242 HubSetSqmFlag(Child, ChildSqm::MultipleConfigurations);
243
244 if (HubIsCompositeLayout(&Child->m_DeviceDescriptor, Config))
245 Child->SetProperty(ChildProperty::IsComposite);
246
247 if (Child->m_ConfigDescriptor == NULL)
248 {
249 /* A lax USB 2.0 device may report a wTotalLength shorter than the header; allocate at least a header */
250 ULONG Size = max((ULONG)Header->wTotalLength, (ULONG)sizeof(*Config));
251
253 if (Config == NULL)
254 {
255 DPRINT1("Device %p no memory for a %u byte configuration\n", Child, Header->wTotalLength);
256 return FALSE;
257 }
258
259 RtlCopyMemory(Config, Header, min(Size, (ULONG)sizeof(Child->m_ScratchBuffer)));
260 Child->m_ConfigDescriptor = Config;
261 }
262
264
265 /* Composite hubs are not supported; enumeration goes on anyway */
266 if (Child->HasProperty(ChildProperty::IsHub) && Child->HasProperty(ChildProperty::IsComposite))
267 DPRINT1("Device %p is a composite hub\n", Child);
268
269 if (Config->bmAttributes & USB_CONFIG_REMOTE_WAKEUP)
270 Child->SetProperty(ChildProperty::RemoteWakeCapable);
271
272 if (Child->HasHack(ChildHack::BlockedDevice))
273 {
274 DPRINT1("Device %p is marked incompatible, enumeration fails\n", Child);
275 Child->m_EnumMessageId = HUB_ENUM_INCOMPATIBLE;
276 return FALSE;
277 }
278
279 return TRUE;
280}
281
282/* BOS descriptor */
283
286{
287 return m_Device->HasHack(ChildHack::SkipBosQuery) || m_Device->m_DeviceDescriptor.bcdUSB <= 0x0200;
288}
289
290/* Optional descriptors only fail the enumeration of a device newer than USB 2.0 */
293{
294 return m_Device->m_DeviceDescriptor.bcdUSB <= 0x0200;
295}
296
299{
303
304 if (Bytes < sizeof(USB_BOS_DESCRIPTOR))
305 {
306 DPRINT1("Device %p BOS header read returned %lu bytes\n", Child, Bytes);
307 Child->m_EnumMessageId = HUB_ENUM_BAD_BOS;
308 return FALSE;
309 }
310
313 {
314 Child->m_EnumMessageId = HUB_ENUM_BAD_BOS;
315 return FALSE;
316 }
317
318 return TRUE;
319}
320
323{
325
326 return HubDeviceBytesReturned(m_Device) >= Header->wTotalLength;
327}
328
329/* Alternate modes that fit in the capability, whatever bNumberOfAlternateModes claims */
330static
331UCHAR
332NTAPI
335{
337 ULONG Room;
338
339 if (Caps->bLength <= First)
340 return 0;
341
342 Room = (Caps->bLength - First) / sizeof(Caps->AlternateMode[0]);
343 return (UCHAR)min(Room, (ULONG)Caps->bNumberOfAlternateModes);
344}
345
346VOID
347NTAPI
350{
351 HubBillboardInfo* Billboard = Child->m_Billboard;
352
353 if (Billboard == NULL)
354 return;
355
356 if (Billboard->Descriptor != NULL)
358
359 ExFreePoolWithTag(Billboard, HUB_TAG_HUB);
360 Child->m_Billboard = NULL;
361}
362
363/* An allocation failure leaves the device without billboard data; enumeration goes on */
364static
365VOID
366NTAPI
370{
371 HubBillboardInfo* Billboard;
372 ULONG Size;
373
375
376 Billboard = (HubBillboardInfo*)ExAllocatePoolZero(NonPagedPool, sizeof(*Billboard), HUB_TAG_HUB);
377 if (Billboard == NULL)
378 {
379 DPRINT1("Device %p no memory for the billboard record\n", Child);
380 return;
381 }
382
384
385 /* Readers walk every mode the descriptor claims, which may run past bLength */
387 Caps->bNumberOfAlternateModes * sizeof(Caps->AlternateMode[0]);
388 Size = max(Size, (ULONG)Caps->bLength);
389
391 Size,
393 if (Billboard->Descriptor == NULL)
394 {
395 DPRINT1("Device %p no memory for a %lu byte billboard copy\n", Child, Size);
396 ExFreePoolWithTag(Billboard, HUB_TAG_HUB);
397 return;
398 }
399
400 RtlCopyMemory(Billboard->Descriptor, Caps, Caps->bLength);
401 Child->m_Billboard = Billboard;
402}
403
404/* Cached once per device and never refreshed. The count is bounded by the capability length. */
405static
407NTAPI
411{
413 ULONG Count = Caps->bmAttributes.SublinkSpeedAttrCount + 1;
414 ULONG Room = (Caps->bLength > First) ? (Caps->bLength - First) / sizeof(Caps->bmSublinkSpeedAttr[0]) : 0;
415 ULONG Size;
416
417 Count = min(Count, Room);
418 if (Count == 0)
419 return TRUE;
420
421 Size = Count * sizeof(Caps->bmSublinkSpeedAttr[0]);
423 Size,
425 if (Child->m_SublinkSpeedAttr == NULL)
426 {
427 DPRINT1("Device %p no memory for %lu sublink speeds\n", Child, Count);
428 return FALSE;
429 }
430
431 RtlCopyMemory(Child->m_SublinkSpeedAttr, Caps->bmSublinkSpeedAttr, Size);
432 Child->m_SublinkSpeedAttrCount = Count;
433 return TRUE;
434}
435
436/* There is no partner notification yet, so this only logs */
438static
439VOID
440NTAPI
445{
446 DPRINT("Port %p dual role partner %u features 0x%lx\n", Port, Attached, Features);
447}
448
450static
451VOID
452NTAPI
453HubCacheDualRole(
456{
457 Child->SetProperty(ChildProperty::DualRole);
458 Child->m_DualRoleRequestCode = Features->VendorCommand;
459 HubQueryLocalDualRoleFeatures(&Child->m_DualRoleLocalFeatures);
460 Child->m_DualRolePartnerFeatures = Features->Features;
461 HubPublishDualRolePartner(Child->m_Port, TRUE, Child->m_DualRolePartnerFeatures);
462}
463
464/*
465 * The set info is cached once and survives the BOS reread after the alternate
466 * enumeration command. A command cached in usbflags is not requested again.
467 */
468static
469VOID
470NTAPI
474{
475 RtlCopyMemory(&Child->m_MsOs20SetInfo, SetInfo, sizeof(Child->m_MsOs20SetInfo));
476 Child->m_MsOs20.Flags |= HUB_MSOS20_SET_INFO;
477
478 if (Child->m_MsOs20SetInfo.bAltEnumCode != 0 && !Child->m_AltEnumCached)
479 {
480 Child->m_MsOsVendorCode = Child->m_MsOs20SetInfo.bVendorCode;
481 Child->m_MsOs20.Flags |= HUB_MSOS20_ALT_ENUM;
482 }
483}
484
485
486/* TRUE when Length bytes at Start lie inside the bytes the device returned */
487static
489NTAPI
491 _In_ const VOID* Start,
493 _In_ const UCHAR* End)
494{
495 return (const UCHAR*)Start + Length <= End;
496}
497
498/* The cache routines read each capability in full, so drop any that run past the buffer */
499static
500VOID
501NTAPI
504 _In_ const UCHAR* End)
505{
506 if (Info->SuperSpeedPlus != NULL &&
507 !HubBosSpanFits(Info->SuperSpeedPlus,
508 max((ULONG)Info->SuperSpeedPlus->bLength,
510 End))
511 {
512 DPRINT1("SuperSpeedPlus capability runs past the BOS, ignored\n");
513 Info->SuperSpeedPlus = NULL;
514 }
515
516 if (Info->Billboard != NULL &&
517 !HubBosSpanFits(Info->Billboard,
518 max((ULONG)Info->Billboard->bLength,
520 End))
521 {
522 DPRINT1("Billboard capability runs past the BOS, ignored\n");
523 Info->Billboard = NULL;
524 }
525
526 if (Info->ContainerId != NULL && !HubBosSpanFits(Info->ContainerId, sizeof(*Info->ContainerId), End))
527 {
528 DPRINT1("Container id capability runs past the BOS, ignored\n");
529 Info->ContainerId = NULL;
530 }
531
532 if (Info->PlatformFeatures != NULL && !HubBosSpanFits(Info->PlatformFeatures, sizeof(*Info->PlatformFeatures), End))
533 {
534 DPRINT1("Platform features capability runs past the BOS, ignored\n");
535 Info->PlatformFeatures = NULL;
536 }
537
538 if (Info->MsOs20SetInfo != NULL && !HubBosSpanFits(Info->MsOs20SetInfo, sizeof(*Info->MsOs20SetInfo), End))
539 {
540 DPRINT1("MS OS 2.0 set info runs past the BOS, ignored\n");
541 Info->MsOs20SetInfo = NULL;
542 }
543}
544
545/* QUIRK: with the ignore errata a failed walk still feeds its partial results */
548{
551 PUSB_BOS_DESCRIPTOR Bos = Child->m_Bos ? Child->m_Bos : Header;
552 BOOLEAN SetInfoKnown = (Child->m_MsOs20.Flags & HUB_MSOS20_SET_INFO) != 0;
556 BOOLEAN Ltm = FALSE;
557 ULONG Flags = 0;
559
560 PAGED_CODE();
561
562 RtlZeroMemory(&Lpm, sizeof(Lpm));
564
565 Valid = HubDescCheckBos(&Context,
566 Bos,
568 &Info,
569 &Child->m_U1ExitLatency,
570 &Child->m_U2ExitLatency,
571 &Ltm,
572 &Lpm,
573 &Flags);
574 if (!Valid && !Child->HasHack(ChildHack::IgnoreBosValidationFailure))
575 {
576 Child->m_EnumMessageId = HUB_ENUM_BAD_BOS;
577 return FALSE;
578 }
579
580 if (!Valid)
581 DPRINT1("Device %p BOS is invalid, kept because of its errata\n", Child);
582
584
585 if (Ltm)
586 Child->SetProperty(ChildProperty::LtmCapable);
587 if (Lpm.Capable)
588 Child->SetProperty(ChildProperty::Usb20LpmCapable);
589 if (Lpm.BeslAndAltHird)
590 Child->SetProperty(ChildProperty::BeslCapable);
592 Child->SetProperty(ChildProperty::ChargingPolicySupported);
593
594 if (Info.SuperSpeedPlus != NULL && Child->m_SublinkSpeedAttr == NULL)
595 {
596 if (!HubCacheSublinkSpeeds(Child, Info.SuperSpeedPlus))
597 return FALSE;
598 }
599
600 /* An MS OS container id wins over the BOS one */
601 if (Info.ContainerId != NULL)
602 {
603 Child->SetProperty(ChildProperty::ContainerIdFromBos);
604 if (!Child->HasProperty(ChildProperty::ContainerIdKnown))
605 RtlCopyMemory(&Child->m_ContainerId, Info.ContainerId->ContainerID, sizeof(Child->m_ContainerId));
606 }
607
608 if (Info.Billboard != NULL)
609 HubKeepBillboardData(Child, Info.Billboard);
610
611 if (Info.PlatformFeatures != NULL)
612 HubCacheDualRole(Child, Info.PlatformFeatures);
613
614 if (!SetInfoKnown && Info.MsOs20SetInfo != NULL)
616
617 if (Child->m_Bos == NULL)
618 {
620 if (Bos == NULL)
621 {
622 DPRINT1("Device %p no memory for a %u byte BOS\n", Child, Header->wTotalLength);
623 return FALSE;
624 }
625
626 RtlCopyMemory(Bos, Header, min(Header->wTotalLength, (ULONG)sizeof(Child->m_ScratchBuffer)));
627 Child->m_Bos = Bos;
628 }
629
631 HubSetSqmFlag(Child, ChildSqm::SuperSpeedCapable);
632 if (Valid)
633 HubSetSqmFlag(Child, ChildSqm::ValidBos);
634
635 return TRUE;
636}
637
638/* Billboard */
639
642{
643 return m_Device->m_Billboard != NULL;
644}
645
648{
650
651 if (Billboard == NULL)
652 return FALSE;
653
654 if (Billboard->Descriptor->iAddtionalInfoURL != 0)
655 return TRUE;
656
657 DPRINT("Device %p billboard has no URL string\n", m_Device);
658 return FALSE;
659}
660
663{
666
669 (PUSB_STRING_DESCRIPTOR)Child->m_ScratchBuffer,
671 NULL))
672 {
673 Child->m_EnumMessageId = HUB_ENUM_BAD_BILLBOARD_URL;
674 return FALSE;
675 }
676
677 DPRINT("Device %p billboard URL string read\n", Child);
678 return TRUE;
679}
680
681/* The PDO publishes whether any mode failed or succeeded to configure */
682static
683VOID
684NTAPI
686 _In_ HubBillboardInfo* Billboard)
687{
688 UCHAR Mode = Billboard->CurrentMode;
689 UCHAR Configured = (Billboard->Descriptor->bmConfigured[Mode / 4] >> ((Mode % 4) * 2)) & 3;
690
691 DPRINT("Billboard %p alternate mode %u configuration state %u\n", Billboard, Mode, Configured);
692
694 Billboard->ModeSuccess = TRUE;
695 else
696 Billboard->ModeError = TRUE;
697}
698
699/* Modes without a string are noted and skipped */
702{
704 UCHAR Count;
705
706 if (Billboard == NULL)
707 return FALSE;
708
710
711 if (Billboard->CurrentMode == HUB_BILLBOARD_NO_MODE)
712 Billboard->CurrentMode = 0;
713
714 while (Billboard->CurrentMode < Count &&
715 Billboard->Descriptor->AlternateMode[Billboard->CurrentMode].iAlternateModeSetting == 0)
716 {
717 HubNoteAltMode(Billboard);
718 Billboard->CurrentMode++;
719 }
720
721 if (Billboard->CurrentMode >= Count)
722 {
724 return FALSE;
725 }
726
727 return TRUE;
728}
729
730/* QUIRK: the walk moves to the next mode even when this string is bad */
733{
735 HubBillboardInfo* Billboard = Child->m_Billboard;
738
739 if (Billboard == NULL || Billboard->CurrentMode == HUB_BILLBOARD_NO_MODE)
740 {
741 DPRINT1("Device %p alternate mode string check without a current mode\n", Child);
742 return FALSE;
743 }
744
747 (PUSB_STRING_DESCRIPTOR)Child->m_ScratchBuffer,
749 NULL);
750 if (Valid)
751 HubNoteAltMode(Billboard);
752 else
753 Child->m_EnumMessageId = HUB_ENUM_BAD_ALT_MODE_STRING;
754
755 Billboard->CurrentMode++;
756 return Valid;
757}
758
759/* Strings */
760
761/* Copies the validated string out of the scratch buffer; allocation failure sets no reason */
762static
764NTAPI
767 _In_ ULONG BadReason,
769{
774
775 *Cache = NULL;
776
779 {
780 Child->m_EnumMessageId = BadReason;
781 return FALSE;
782 }
783
785 if (Copy == NULL)
786 {
787 DPRINT1("Device %p no memory for a %u byte string\n", Child, String->bLength);
788 return FALSE;
789 }
790
792 *Cache = Copy;
793 return TRUE;
794}
795
798{
800}
801
804{
806}
807
808/* The content is not checked; its presence alone marks a high speed capable device */
811{
813 {
814 DPRINT1("Device %p qualifier read returned %lu bytes\n", m_Device, HubDeviceBytesReturned(m_Device));
816 return FALSE;
817 }
818
819 m_Device->SetProperty(ChildProperty::HighSpeedCapable);
820 return TRUE;
821}
822
823/* MS OS 1.0 */
824
827{
830
831 if (HubDeviceBytesReturned(Child) != sizeof(Child->m_MsOsString))
832 {
833 DPRINT1("Device %p MS OS string read returned %lu bytes\n", Child, HubDeviceBytesReturned(Child));
834 return FALSE;
835 }
836
838 if (!HubDescCheckMsOsString(&Context, &Child->m_MsOsString))
839 return FALSE;
840
841 Child->m_MsOsVendorCode = Child->m_MsOsString.bVendorCode;
842 return TRUE;
843}
844
845/* Nothing is cached from the header */
848{
851
854 (const HubMsOsHeader*)Child->m_ScratchBuffer,
856 {
857 Child->m_EnumMessageId = HUB_ENUM_BAD_MSOS_CONTAINER_ID;
858 return FALSE;
859 }
860
861 return TRUE;
862}
863
866{
868 const HubMsOsContainerId* Descriptor = (const HubMsOsContainerId*)Child->m_ScratchBuffer;
870
873 return FALSE;
874
875 RtlCopyMemory(&Child->m_ContainerId, Descriptor->ContainerId, sizeof(Child->m_ContainerId));
876 Child->SetProperty(ChildProperty::ContainerIdKnown);
877 return TRUE;
878}
879
882{
885
888 (const HubMsOsExtConfigHeader*)Child->m_ScratchBuffer,
890 {
891 Child->m_EnumMessageId = HUB_ENUM_BAD_MSOS_EXT_CONFIG;
892 return FALSE;
893 }
894
895 return TRUE;
896}
897
898/* The header read is still in the scratch buffer; a bad descriptor is dropped */
901{
903 const HubMsOsExtConfigHeader* Header = (const HubMsOsExtConfigHeader*)Child->m_ScratchBuffer;
906
907 if (Child->m_MsOsExtConfig == NULL)
908 {
909 DPRINT1("Device %p has no extended configuration buffer\n", Child);
910 return FALSE;
911 }
912
914 if (Bytes == Header->dwLength && HubDescCheckMsOsExtConfig(&Context, Child->m_MsOsExtConfig, Bytes))
915 return TRUE;
916
917 if (Bytes != Header->dwLength)
918 DPRINT1("Device %p extended configuration read %lu of %lu bytes\n", Child, Bytes, Header->dwLength);
919
920 ExFreePoolWithTag(Child->m_MsOsExtConfig, HUB_TAG_DEVICE);
921 Child->m_MsOsExtConfig = NULL;
922 return FALSE;
923}
924
925/* MS OS 2.0 */
926
929{
932 HubMsOs20ResumeTime* Resume;
933
934 PAGED_CODE();
935
936 if (Child->m_MsOs20Set == NULL)
937 {
938 DPRINT1("Device %p has no MS OS 2.0 set buffer\n", Child);
939 return FALSE;
940 }
941
942 Child->m_MsOs20SetLength = HubDeviceBytesReturned(Child);
943
945 if (!HubDescCheckMsOs20Set(&Context,
946 Child->m_MsOs20Set,
947 Child->m_MsOs20SetLength,
948 &Child->m_MsOs20SetInfo,
949 &Child->m_MsOs20))
950 {
951 Child->m_EnumMessageId = HUB_ENUM_BAD_MSOS20_SET;
952 return FALSE;
953 }
954
955 if (Child->m_MsOs20.Flags & HUB_MSOS20_CCGP)
956 Child->SetProperty(ChildProperty::IsComposite);
957
958 Resume = Child->m_MsOs20.ResumeTime;
959 if (Resume != NULL)
960 {
961 Child->m_HasResumeRecoveryTime = TRUE;
962 Child->m_ResumeRecoveryTime = Resume->bResumeRecoveryTime;
963 Child->m_ResumeSignalingTime = Resume->bResumeSignalingTime;
964 }
965
966 return TRUE;
967}
968
969/* Teardown */
970
971VOID
972NTAPI
975{
977
978 if (Child->m_SublinkSpeedAttr != NULL)
979 {
980 ExFreePoolWithTag(Child->m_SublinkSpeedAttr, HUB_TAG_DEVICE);
981 Child->m_SublinkSpeedAttr = NULL;
982 Child->m_SublinkSpeedAttrCount = 0;
983 }
984
985 if (Child->m_MsOsExtConfig != NULL)
986 {
987 ExFreePoolWithTag(Child->m_MsOsExtConfig, HUB_TAG_DEVICE);
988 Child->m_MsOsExtConfig = NULL;
989 }
990}
#define PAGED_CODE()
WCHAR First[]
Definition: FormatMessage.c:11
static _Out_opt_ PULONGLONG Start
unsigned char BOOLEAN
Definition: actypes.h:127
#define DPRINT1
Definition: precomp.h:8
BOOLEAN BosQuerySkipped()
Definition: devdesc.cpp:285
HubChild * m_Device
Definition: devsm.h:1832
BOOLEAN MsOsDescriptorValid()
Definition: devdesc.cpp:826
BOOLEAN IgnoreDescriptorError()
Definition: devdesc.cpp:292
BOOLEAN ProductNameValid()
Definition: devdesc.cpp:803
BOOLEAN QualifierValid()
Definition: devdesc.cpp:810
BOOLEAN AltModeStringWanted()
Definition: devdesc.cpp:701
BOOLEAN BillboardStringWanted()
Definition: devdesc.cpp:647
BOOLEAN ContainerIdKnown()
Definition: devdesc.cpp:865
BOOLEAN ConfigLongerThanRead()
Definition: devdesc.cpp:131
BOOLEAN ContainerIdHeaderValid()
Definition: devdesc.cpp:847
BOOLEAN BosComplete()
Definition: devdesc.cpp:322
BOOLEAN BosHeaderValid()
Definition: devdesc.cpp:298
BOOLEAN ExtendedConfigHeaderValid()
Definition: devdesc.cpp:881
BOOLEAN MsOs20SetValid()
Definition: devdesc.cpp:928
BOOLEAN HasBillboard()
Definition: devdesc.cpp:641
BOOLEAN BillboardStringValid()
Definition: devdesc.cpp:662
BOOLEAN ExtendedConfigValid()
Definition: devdesc.cpp:900
BOOLEAN BosValid()
Definition: devdesc.cpp:547
BOOLEAN FirstDescriptorValid()
Definition: devdesc.cpp:67
BOOLEAN DeviceDescriptorValid()
Definition: devdesc.cpp:98
BOOLEAN AltModeStringValid()
Definition: devdesc.cpp:732
BOOLEAN LanguageIdsValid()
Definition: devdesc.cpp:797
BOOLEAN ConfigDescriptorValid()
Definition: devdesc.cpp:213
Definition: Header.h:9
PUSB_STRING_DESCRIPTOR m_LanguageIds
Definition: hubchild.h:390
USB_DEVICE_DESCRIPTOR m_DeviceDescriptor
Definition: hubchild.h:386
HubBillboardInfo * m_Billboard
Definition: hubchild.h:520
ULONG m_EnumMessageId
Definition: hubchild.h:355
VOID SetProperty(_In_ ChildProperty Flag)
Definition: hubchild.h:295
UCHAR m_ScratchBuffer[256]
Definition: hubchild.h:393
USB_DEVICE_QUALIFIER_DESCRIPTOR m_Qualifier
Definition: hubchild.h:387
PUSB_STRING_DESCRIPTOR m_ProductString
Definition: hubchild.h:391
BOOLEAN HasHack(_In_ ChildHack Flag) const
Definition: hubchild.h:281
BOOLEAN NTAPI HubDescCheckMsOsString(_In_ const HubDescContext *Context, _In_ const HubMsOsString *Descriptor)
Definition: desccheck.cpp:2490
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
BOOLEAN NTAPI HubDescCheckMsOsExtConfigHeader(_In_ const HubDescContext *Context, _In_reads_bytes_(Length) const HubMsOsExtConfigHeader *Descriptor, _In_ ULONG Length)
Definition: desccheck.cpp:2563
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
_In_ ULONG _In_ const HubMsOs20SetInfo * SetInfo
Definition: desccheck.cpp:3183
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
PUCHAR End
Definition: desccheck.cpp:2229
Walk Ltm
Definition: desccheck.cpp:2275
BOOLEAN NTAPI HubDescCheckMsOsContainerId(_In_ const HubDescContext *Context, _In_reads_bytes_(Length) const HubMsOsContainerId *Descriptor, _In_ ULONG Length)
Definition: desccheck.cpp:2541
BOOLEAN NTAPI HubDescCheckMsOsContainerIdHeader(_In_ const HubDescContext *Context, _In_reads_bytes_(Length) const HubMsOsHeader *Descriptor, _In_ ULONG Length)
Definition: desccheck.cpp:2505
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
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
BOOLEAN Valid
Definition: desccheck.cpp:2227
_In_ ULONG _Out_opt_ HubBosInfo _Out_opt_ PUSHORT _Out_opt_ PUSHORT _Inout_opt_ PBOOLEAN _Inout_opt_ HubLpmInfo * Lpm
Definition: desccheck.cpp:2221
BOOLEAN NTAPI HubDescCheckMsOsExtConfig(_In_ const HubDescContext *Context, _In_reads_bytes_(sizeof(HubMsOsExtConfig)) const HubMsOsExtConfig *Descriptor, _In_ ULONG Length)
Definition: desccheck.cpp:2606
BOOLEAN NTAPI HubDescCheckBosHeader(_In_ const HubDescContext *Context, _In_reads_bytes_opt_(Length) PUSB_BOS_DESCRIPTOR Descriptor, _In_ ULONG Length)
Definition: desccheck.cpp:2197
#define HUB_MSOS20_ALT_ENUM
Definition: desccheck.h:490
#define HUB_BOS_SUPERSPEED_CAPABLE
Definition: desccheck.h:316
#define HUB_BOS_CHARGING_POLICY
Definition: desccheck.h:318
#define HUB_MSOS20_CCGP
Definition: desccheck.h:497
#define HUB_MSOS20_SET_INFO
Definition: desccheck.h:488
static BOOLEAN NTAPI HubCacheSublinkSpeeds(_In_ HubChild *Child, _In_ PUSB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_USB_DESCRIPTOR Caps)
Definition: devdesc.cpp:408
#define DESC_CLASS_MISCELLANEOUS
Definition: devdesc.cpp:22
HubPublishDualRolePartner(Child->m_Port, TRUE, Child->m_DualRolePartnerFeatures)
VOID NTAPI HubDeviceDescContext(_In_ HubChild *Child, _Out_ HubDescContext *Context)
Definition: devdesc.cpp:35
static VOID NTAPI HubSetSqmFlag(_In_ HubChild *Child, _In_ ChildSqm Flag)
Definition: devdesc.cpp:53
_In_ BOOLEAN Attached
Definition: devdesc.cpp:443
VOID NTAPI HubReleaseTransferState(_In_ HubChild *Child)
Definition: devdesc.cpp:973
static VOID NTAPI HubDropCapsPastEnd(_Inout_ HubBosInfo *Info, _In_ const UCHAR *End)
Definition: devdesc.cpp:502
#define DESC_SUBCLASS_COMMON
Definition: devdesc.cpp:23
static VOID NTAPI HubPickCompatIdInterface(_In_ HubChild *Child, _In_ PUSB_CONFIGURATION_DESCRIPTOR Config)
Definition: devdesc.cpp:164
HubQueryLocalDualRoleFeatures & Child
Definition: devdesc.cpp:459
static VOID NTAPI HubNoteAltMode(_In_ HubBillboardInfo *Billboard)
Definition: devdesc.cpp:685
#define DESC_MODE_CONFIGURED
Definition: devdesc.cpp:31
#define DESC_SLOW_ENUM_PRODUCT
Definition: devdesc.cpp:19
VOID NTAPI HubFreeBillboardInfo(_In_ HubChild *Child)
Definition: devdesc.cpp:348
static BOOLEAN NTAPI HubBosSpanFits(_In_ const VOID *Start, _In_ ULONG Length, _In_ const UCHAR *End)
Definition: devdesc.cpp:490
static BOOLEAN NTAPI HubCacheString(_In_ HubChild *Child, _In_ ULONG BadReason, _Outptr_result_maybenull_ PUSB_STRING_DESCRIPTOR *Cache)
Definition: devdesc.cpp:765
#define DESC_PROTOCOL_UAS
Definition: devdesc.cpp:28
static BOOLEAN NTAPI HubIsCompositeLayout(_In_ const USB_DEVICE_DESCRIPTOR *Device, _In_ const USB_CONFIGURATION_DESCRIPTOR *Config)
Definition: devdesc.cpp:142
#define DESC_FIRST_READ_KEEP
Definition: devdesc.cpp:15
static VOID NTAPI HubKeepBillboardData(_In_ HubChild *Child, _In_ PUSB_DEVICE_CAPABILITY_BILLBOARD_DESCRIPTOR Caps)
Definition: devdesc.cpp:367
static UCHAR NTAPI HubBillboardModeCount(_In_ PUSB_DEVICE_CAPABILITY_BILLBOARD_DESCRIPTOR Caps)
Definition: devdesc.cpp:333
static VOID NTAPI HubCacheMsOs20SetInfoFromBos(_In_ HubChild *Child, _In_ const HubMsOs20SetInfo *SetInfo)
Definition: devdesc.cpp:471
#define DESC_PROTOCOL_IAD
Definition: devdesc.cpp:24
#define DESC_SLOW_ENUM_VENDOR
Definition: devdesc.cpp:18
#define DESC_SUBCLASS_SCSI
Definition: devdesc.cpp:27
_In_ BOOLEAN _In_ ULONG Features
Definition: devdesc.cpp:445
ULONG Copy
Definition: devhcd.cpp:1449
FORCEINLINE ULONG NTAPI HubDeviceBytesReturned(_In_ HubChild *Child)
Definition: devreq.h:37
_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 _IRQL_requires_(irql)
Definition: driverspecs.h:229
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define NonPagedPool
Definition: env_spec_w32.h:307
CPPORT Port[4]
Definition: headless.c:38
_In_ ULONG Mode
Definition: hubbusif.h:303
ChildSqm
Definition: hubchild.h:121
#define HUB_BILLBOARD_NO_MODE
Definition: hubchild.h:227
@ UseWin8DescriptorValidation
#define HUB_ENUM_BAD_LANGUAGE_IDS
Definition: hubid.h:27
#define HUB_ENUM_DEVICE_DESCRIPTOR_FAILED
Definition: hubid.h:11
#define HUB_ENUM_BAD_DEVICE_DESCRIPTOR
Definition: hubid.h:15
#define HUB_ENUM_INCOMPATIBLE
Definition: hubid.h:34
#define HUB_ENUM_BAD_MSOS_EXT_CONFIG
Definition: hubid.h:29
#define HUB_ENUM_BAD_BILLBOARD_URL
Definition: hubid.h:38
#define HUB_ENUM_BAD_CONFIG_DESCRIPTOR
Definition: hubid.h:14
#define HUB_ENUM_BAD_QUALIFIER
Definition: hubid.h:26
#define HUB_ENUM_BAD_MSOS_CONTAINER_ID
Definition: hubid.h:28
#define HUB_ENUM_BAD_PRODUCT_STRING
Definition: hubid.h:30
#define HUB_ENUM_BAD_BOS
Definition: hubid.h:25
#define HUB_ENUM_BAD_MSOS20_SET
Definition: hubid.h:36
#define HUB_ENUM_BAD_ALT_MODE_STRING
Definition: hubid.h:39
_Must_inspect_result_ _In_ PUCXHUB_DEVICE_CREATE_INFO _Out_ UCXUSBDEVICE * Device
Definition: hubucx.h:258
#define HUB_TAG_DEVICE
Definition: hubutil.h:13
#define HUB_TAG_HUB
Definition: hubutil.h:12
#define InterlockedOr
Definition: interlocked.h:239
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
_In_ UINT Bytes
Definition: mmcopy.h:9
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
#define min(a, b)
Definition: monoChain.cc:55
#define _Inout_
Definition: no_sal2.h:162
#define _Outptr_result_maybenull_
Definition: no_sal2.h:266
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
long LONG
Definition: pedump.c:60
#define DPRINT
Definition: sndvol32.h:73
Definition: xml2sdb.h:103
PUSB_DEVICE_CAPABILITY_BILLBOARD_DESCRIPTOR Descriptor
Definition: hubchild.h:232
UCHAR CurrentMode
Definition: hubchild.h:233
UCHAR bResumeSignalingTime
Definition: desccheck.h:391
UCHAR bResumeRecoveryTime
Definition: desccheck.h:390
struct _USB_DEVICE_CAPABILITY_BILLBOARD_DESCRIPTOR::@4127 AlternateMode[1]
#define max(a, b)
Definition: svc.c:63
unsigned char UCHAR
Definition: typedefs.h:53
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG Config
_In_ UCXUSBDEVICE _In_ ULONG Interface
Definition: ucxusbdevice.h:428
#define USB_DEVICE_CLASS_STORAGE
Definition: usb100.h:98
struct _USB_CONFIGURATION_DESCRIPTOR * PUSB_CONFIGURATION_DESCRIPTOR
#define USB_CONFIGURATION_DESCRIPTOR_TYPE
Definition: usb100.h:50
struct _USB_STRING_DESCRIPTOR * PUSB_STRING_DESCRIPTOR
#define USB_CONFIG_REMOTE_WAKEUP
Definition: usb100.h:71
struct _USB_DEVICE_DESCRIPTOR * PUSB_DEVICE_DESCRIPTOR
#define USB_DEVICE_CLASS_HUB
Definition: usb100.h:99
@ UsbSuperSpeed
Definition: usb200.h:45
@ UsbHighSpeed
Definition: usb200.h:44
enum _USB_DEVICE_SPEED USB_DEVICE_SPEED
struct _USB_DEVICE_CAPABILITY_BILLBOARD_DESCRIPTOR * PUSB_DEVICE_CAPABILITY_BILLBOARD_DESCRIPTOR
struct _USB_BOS_DESCRIPTOR * PUSB_BOS_DESCRIPTOR
union _USB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_SPEED * PUSB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_SPEED
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
_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_ WDFDEVICE Child
Definition: wdffdo.h:536
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342