ReactOS 0.4.17-dev-1281-g065abb3
hubid.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: PnP ids, container id, device text and the cached serial number
5 * COPYRIGHT: Copyright 2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8#include "usbhub3.h"
9#include "hubid.h"
10
11#define NDEBUG
12#include <debug.h>
13
14/* Every formatted id fits in this many characters */
15#define HUB_ID_MAX_CHARS 128
16
17/* Room for a decimal ULONG port number */
18#define HUB_INSTANCE_ID_CHARS 28
19
20/* sizeof(L"Port_#nnnn.Hub_#nnnn") */
21#define HUB_LOCATION_TEXT_BYTES 42
22
23#define HUB_DEFAULT_LANGUAGE 0x0409
24
25/* Name space of generated container ids {4B06FD46-C84E-4664-9C65-0C86D9047A0C} */
27 { 0x4B06FD46, 0xC84E, 0x4664, { 0x9C, 0x65, 0x0C, 0x86, 0xD9, 0x04, 0x7A, 0x0C } };
28
29/* Ids for a device that failed enumeration; the NUL stays in the counted length, which PnP never sees */
31{
36};
37
38#define HUB_FAILURE_ID(Reason, Pid, Text) { (Reason), (Pid), Text, sizeof(Text) }
39
41{
42 HUB_FAILURE_ID(HUB_ENUM_DEVICE_DESCRIPTOR_FAILED, 0x0002, L"USB\\DEVICE_DESCRIPTOR_FAILURE"),
43 HUB_FAILURE_ID(HUB_ENUM_SET_ADDRESS_FAILED, 0x0004, L"USB\\SET_ADDRESS_FAILURE"),
44 HUB_FAILURE_ID(HUB_ENUM_PORT_RESET_FAILED, 0x0001, L"USB\\RESET_FAILURE"),
45 HUB_FAILURE_ID(HUB_ENUM_BAD_CONFIG_DESCRIPTOR, 0x0006, L"USB\\CONFIGURATION_DESCRIPTOR_VALIDATION_FAILURE"),
46 HUB_FAILURE_ID(HUB_ENUM_BAD_DEVICE_DESCRIPTOR, 0x0005, L"USB\\DEVICE_DESCRIPTOR_VALIDATION_FAILURE"),
47 HUB_FAILURE_ID(HUB_ENUM_CONFIG_DESCRIPTOR_FAILED, 0x0003, L"USB\\CONFIG_DESCRIPTOR_FAILURE"),
48 HUB_FAILURE_ID(HUB_ENUM_LINK_SS_INACTIVE, 0x0007, L"USB\\PORT_LINK_SSINACTIVE"),
49 HUB_FAILURE_ID(HUB_ENUM_LINK_COMPLIANCE, 0x0008, L"USB\\PORT_LINK_COMPLIANCE_MODE"),
50};
51
53 HUB_FAILURE_ID(0, 0x0000, L"USB\\UNKNOWN_DEVICE");
54
55/* A billboard gets one class id with a counted NUL, like the failure ids */
56static const WCHAR HubBillboardId[] = L"USB\\Class_11&SubClass_00&Prot_00";
57
58static
59const HubFailureId*
63{
65
67 {
68 if (HubFailureIds[Index].Reason == Child->m_EnumMessageId)
69 return &HubFailureIds[Index];
70 }
71
72 return &HubUnknownDeviceId;
73}
74
75/* ID LISTS ******************************************************************/
76
77/* Where a builder sends each id it makes */
78enum class HubIdKind
79{
80 Device,
84};
85
87{
90 PUSB_ID_STRING List;
91};
92
95{
98
99 VOID
102 ...)
103 {
105
108 va_end(Args);
109 }
110
111 VOID
114 {
116 }
117
118 VOID
121 {
122 if (NT_SUCCESS(Status))
124 }
125};
126
127static
129NTAPI
131 _Inout_ PUSB_ID_STRING List,
133{
134 ULONG Kept = (List->Buffer != NULL) ? List->LengthInBytes - sizeof(WCHAR) : 0;
135 ULONG Total = Kept + Id->Length + 2 * sizeof(WCHAR);
137
139 if (Buffer == NULL)
140 {
141 DPRINT1("Id list of %lu bytes could not be allocated\n", Total);
143 }
144
145 if (Kept != 0)
146 RtlCopyMemory(Buffer, List->Buffer, Kept);
148
149 if (List->Buffer != NULL)
151
152 List->Buffer = Buffer;
153 List->LengthInBytes = Total;
154 return STATUS_SUCCESS;
155}
156
157VOID
158NTAPI
160 _Inout_ PUSB_ID_STRING Ids)
161{
162 if (Ids->Buffer == NULL)
163 return;
164
166 Ids->Buffer = NULL;
167 Ids->LengthInBytes = 0;
168}
169
170/* On allocation failure the copy keeps the source's language and length with no buffer */
172NTAPI
174 _Out_ PUSB_ID_STRING Destination,
175 _In_ const USB_ID_STRING* Source)
176{
178
179 if (Source->Buffer == NULL || Source->LengthInBytes == 0)
180 return STATUS_SUCCESS;
181
184 if (Destination->Buffer == NULL)
185 {
186 DPRINT1("Id list copy of %lu bytes could not be allocated\n", Source->LengthInBytes);
188 }
189
190 RtlCopyMemory(Destination->Buffer, Source->Buffer, Source->LengthInBytes);
191 return STATUS_SUCCESS;
192}
193
194/* The PDO init gets the id first; the list is only touched when that worked */
195static
197NTAPI
199 _In_ const HubIdSink* Sink,
201{
203
204 if (Sink->Init != NULL)
205 {
206 switch (Sink->Kind)
207 {
209 Status = WdfPdoInitAssignDeviceID(Sink->Init, Id);
210 break;
211
213 Status = WdfPdoInitAddHardwareID(Sink->Init, Id);
214 break;
215
217 Status = WdfPdoInitAddCompatibleID(Sink->Init, Id);
218 break;
219
221 Status = WdfPdoInitAssignContainerID(Sink->Init, Id);
222 break;
223 }
224
225 if (!NT_SUCCESS(Status))
226 {
227 DPRINT1("Assigning id %wZ (kind %d) failed 0x%lx\n", Id, (int)Sink->Kind, Status);
228 return Status;
229 }
230 }
231
232 if (Sink->List != NULL)
233 Status = HubIdListAppend(Sink->List, Id);
234
235 return Status;
236}
237
238static
240NTAPI
242 _In_ const HubIdSink* Sink,
243 _In_ const HubIdText* Text)
244{
246
247 if (!NT_SUCCESS(Text->Status))
248 {
249 DPRINT1("Formatting an id failed 0x%lx\n", Text->Status);
250 return Text->Status;
251 }
252
253 RtlInitUnicodeString(&Id, Text->Buffer);
254 return HubIdEmit(Sink, &Id);
255}
256
258static
260NTAPI
262 _In_ const HubIdSink* Sink,
263 _In_reads_bytes_(IdBytes) PCWSTR Id,
264 _In_ USHORT IdBytes)
265{
267
268 String.Buffer = (PWCH)Id;
269 String.Length = IdBytes;
270 String.MaximumLength = IdBytes;
271 return HubIdEmit(Sink, &String);
272}
273
274/* DEVICE PROPERTIES THE IDS DEPEND ON ****************************************/
275
276static
278NTAPI
281{
282 return Child->HasState(ChildState::WorkingDevice);
283}
284
285/* Neither a working device nor one with a usable configuration */
286static
288NTAPI
291{
293}
294
295static
297NTAPI
300{
301 return Child->HasProperty(ChildProperty::UxdReserved) &&
302 !Child->HasProperty(ChildProperty::IsHub);
303}
304
305/* bcdDevice as four characters; up to USB 2.0 each nibble is added to '0', so A to F become ':' to '?' */
306static
307VOID
308NTAPI
310 _In_ USHORT BcdUsb,
311 _In_ USHORT BcdDevice,
313{
314 static const WCHAR HexDigits[] = L"0123456789ABCDEF";
315 ULONG Index;
316 ULONG Nibble;
317
318 for (Index = 0; Index < 4; Index++)
319 {
320 Nibble = (BcdDevice >> (12 - Index * 4)) & 0xF;
321 Text[Index] = (BcdUsb > 0x0200) ? HexDigits[Nibble] : (WCHAR)(L'0' + Nibble);
322 }
323
324 Text[4] = UNICODE_NULL;
325}
326
327/* An 8 byte ANSI field of an MS OS descriptor, up to its first zero byte */
328static
329VOID
330NTAPI
332 _In_reads_(8) const UCHAR* Field,
334{
335 ULONG Index;
336
337 for (Index = 0; Index < 8 && Field[Index] != 0; Index++)
338 Text[Index] = Field[Index];
339
341}
342
343/* DEVICE ID *****************************************************************/
344
345static
347NTAPI
351{
354 USHORT VendorId = Child->m_DeviceDescriptor.idVendor;
355 USHORT ProductId = Child->m_DeviceDescriptor.idProduct;
356
358 return HubIdEmit(&Sink, &Child->m_VmReservedId);
359
361 {
362 VendorId = 0;
363 ProductId = HubFailureIdFor(Child)->ProductId;
364 }
365
366 Text.Format(L"USB\\VID_%04X&PID_%04X", VendorId, ProductId);
367 if (Child->HasHack(ChildHack::NonFunctional))
368 Text.Append(L"_NON_FUNCTIONAL");
369
370 return HubIdEmitText(&Sink, &Text);
371}
372
373/* HARDWARE IDS **************************************************************/
374
375/*
376 * The VM reserved id only replaces the hardware ids of a PDO being created;
377 * a list built for GET_DEVICE_CONFIG_INFO keeps the VID and PID ids.
378 */
380NTAPI
384 _Out_opt_ PUSB_ID_STRING Ids)
385{
387 const USB_DEVICE_DESCRIPTOR* Descriptor = &Child->m_DeviceDescriptor;
389 WCHAR Revision[5];
391
392 if (Ids != NULL)
393 RtlZeroMemory(Ids, sizeof(*Ids));
394
396 {
397 const HubFailureId* Failure = HubFailureIdFor(Child);
398 return HubIdEmitCounted(&Sink, Failure->Id, Failure->IdBytes);
399 }
400
402 return HubIdEmit(&Sink, &Child->m_VmReservedId);
403
404 HubIdRevisionText(Descriptor->bcdUSB, Descriptor->bcdDevice, Revision);
405
406 Text.Format(L"USB\\VID_%04X&PID_%04X&REV_", Descriptor->idVendor, Descriptor->idProduct);
407 Text.Append(Revision);
409 if (!NT_SUCCESS(Status))
410 return Status;
411
412 Text.Format(L"USB\\VID_%04X&PID_%04X", Descriptor->idVendor, Descriptor->idProduct);
413 return HubIdEmitText(&Sink, &Text);
414}
415
416/* COMPATIBLE IDS ************************************************************/
417
418/* The COMPAT_VID forms go in front of the DevClass forms */
419static
421NTAPI
424 _In_ const HubIdSink* Sink)
425{
426 static PCWSTR const Plain[] =
427 {
428 L"USB\\DevClass_00&SubClass_00&Prot_00",
429 L"USB\\DevClass_00&SubClass_00",
430 L"USB\\DevClass_00",
431 L"USB\\COMPOSITE"
432 };
433 USHORT VendorId = Child->m_DeviceDescriptor.idVendor;
436 ULONG Index;
437
438 /* "Prot00" without the underscore is intentional */
439 Text.Format(L"USB\\COMPAT_VID_%04X&DevClass_00&SubClass_00&Prot00", VendorId);
441 if (!NT_SUCCESS(Status))
442 return Status;
443
444 Text.Format(L"USB\\COMPAT_VID_%04X&DevClass_00&SubClass_00", VendorId);
446 if (!NT_SUCCESS(Status))
447 return Status;
448
449 Text.Format(L"USB\\COMPAT_VID_%04X&DevClass_00", VendorId);
451 if (!NT_SUCCESS(Status))
452 return Status;
453
454 for (Index = 0; Index < RTL_NUMBER_OF(Plain); Index++)
455 {
456 Text.Set(Plain[Index]);
458 if (!NT_SUCCESS(Status))
459 return Status;
460 }
461
462 return STATUS_SUCCESS;
463}
464
465static
467NTAPI
469 _In_ const HubIdSink* Sink,
470 _In_reads_(8) const UCHAR* CompatibleId,
471 _In_reads_opt_(8) const UCHAR* SubCompatibleId)
472{
474 WCHAR Field[9];
475
476 HubIdWidenMsOsField(CompatibleId, Field);
477 Text.Set(L"USB\\MS_COMP_");
478 Text.Append(Field);
479
480 if (SubCompatibleId != NULL)
481 {
482 HubIdWidenMsOsField(SubCompatibleId, Field);
483 Text.Append(L"&MS_SUBCOMP_");
484 Text.Append(Field);
485 }
486
487 return HubIdEmitText(Sink, &Text);
488}
489
490/* MS OS 2.0 wins over MS OS 1.0; only the first 1.0 function counts */
491static
493NTAPI
496 _In_ const HubIdSink* Sink)
497{
498 const UCHAR* CompatibleId;
499 const UCHAR* SubCompatibleId;
501
502 if ((Child->m_MsOs20.Flags & HUB_MSOS20_COMPATIBLE_ID) && Child->m_MsOs20.CompatibleId != NULL)
503 {
504 CompatibleId = Child->m_MsOs20.CompatibleId->CompatibleId;
505 SubCompatibleId = Child->m_MsOs20.CompatibleId->SubCompatibleId;
506
507 if (SubCompatibleId[0] != 0 && CompatibleId[0] != 0)
508 {
509 Status = HubIdEmitMsComp(Sink, CompatibleId, SubCompatibleId);
510 if (!NT_SUCCESS(Status))
511 return Status;
512 }
513 }
514 else if (Child->m_MsOsExtConfig != NULL)
515 {
516 CompatibleId = Child->m_MsOsExtConfig->Function[0].CompatibleId;
517 SubCompatibleId = Child->m_MsOsExtConfig->Function[0].SubCompatibleId;
518
519 /* Only the sub compatible id is checked, so the compatible id can come out empty */
520 if (SubCompatibleId[0] != 0)
521 {
522 Status = HubIdEmitMsComp(Sink, CompatibleId, SubCompatibleId);
523 if (!NT_SUCCESS(Status))
524 return Status;
525 }
526 }
527 else
528 {
529 return STATUS_SUCCESS;
530 }
531
532 if (CompatibleId[0] != 0)
533 return HubIdEmitMsComp(Sink, CompatibleId, NULL);
534
535 return STATUS_SUCCESS;
536}
537
538static
540NTAPI
543 _In_ const HubIdSink* Sink)
544{
545 const USB_INTERFACE_DESCRIPTOR* Interface = Child->m_CompatIdInterface;
546 USHORT VendorId = Child->m_DeviceDescriptor.idVendor;
547 UCHAR Class = 0;
548 UCHAR SubClass = 0;
549 UCHAR Protocol = 0;
552
553 if (Interface != NULL)
554 {
555 Class = Interface->bInterfaceClass;
556 SubClass = Interface->bInterfaceSubClass;
557 Protocol = Interface->bInterfaceProtocol;
558 }
559
561 if (!NT_SUCCESS(Status))
562 return Status;
563
564 /* COMPAT_VID class ids, between the MS OS ids and the plain class ids */
565 Text.Format(L"USB\\COMPAT_VID_%04X&Class_%02X&SubClass_%02X&Prot_%02X", VendorId, Class, SubClass, Protocol);
567 if (!NT_SUCCESS(Status))
568 return Status;
569
570 Text.Format(L"USB\\COMPAT_VID_%04X&Class_%02X&SubClass_%02X", VendorId, Class, SubClass);
572 if (!NT_SUCCESS(Status))
573 return Status;
574
575 Text.Format(L"USB\\COMPAT_VID_%04X&Class_%02X", VendorId, Class);
577 if (!NT_SUCCESS(Status))
578 return Status;
579
580 Text.Format(L"USB\\Class_%02X&SubClass_%02X&Prot_%02X", Class, SubClass, Protocol);
582 if (!NT_SUCCESS(Status))
583 return Status;
584
585 Text.Format(L"USB\\Class_%02X&SubClass_%02X", Class, SubClass);
587 if (!NT_SUCCESS(Status))
588 return Status;
589
590 Text.Format(L"USB\\Class_%02X", Class);
591 return HubIdEmitText(Sink, &Text);
592}
593
594/* A composite hub gets the composite ids, and a low speed hub gets none */
596NTAPI
600 _Out_opt_ PUSB_ID_STRING Ids)
601{
604
605 if (Ids != NULL)
606 RtlZeroMemory(Ids, sizeof(*Ids));
607
609 {
610 const HubFailureId* Failure = HubFailureIdFor(Child);
611 return HubIdEmitCounted(&Sink, Failure->Id, Failure->IdBytes);
612 }
613
614 if (Child->HasProperty(ChildProperty::IsComposite))
616
617 if (Child->HasProperty(ChildProperty::IsHub))
618 {
619 switch (Child->Speed())
620 {
621 case UsbHighSpeed:
622 case UsbFullSpeed:
623 Text.Set(L"USB\\USB20_HUB");
624 return HubIdEmitText(&Sink, &Text);
625
626 case UsbSuperSpeed:
627 Text.Set(L"USB\\USB30_HUB");
628 return HubIdEmitText(&Sink, &Text);
629
630 default:
631 return STATUS_SUCCESS;
632 }
633 }
634
635 if (Child->HasProperty(ChildProperty::HasBillboard))
637
638 return HubIdBuildClassIds(Child, &Sink);
639}
640
641/* CONTAINER ID **************************************************************/
642
643/* Name based id from VID, PID, revision and serial; the raw digest bytes make it not an RFC 4122 v5 UUID */
644static
645VOID
646NTAPI
649{
650 const USB_DEVICE_DESCRIPTOR* Descriptor = &Child->m_DeviceDescriptor;
651 ULONG NameBytes = Child->m_SerialNumberLength + 28;
653 WCHAR Revision[5];
654 HubSha1 Sha;
655 PWCHAR Name;
656 size_t NameLength;
658
660 if (Name == NULL)
661 {
662 DPRINT1("Container id name for device %p could not be allocated\n", Child);
663 return;
664 }
665
666 if (Descriptor->bcdUSB > 0x0200)
667 {
668 /* bcdUSB, not bcdDevice, and space padded */
669 Status = RtlStringCbPrintfW(Name, NameBytes, L"%04X%04X.%4X",
670 Descriptor->idVendor, Descriptor->idProduct, Descriptor->bcdUSB);
671 }
672 else
673 {
674 HubIdRevisionText(Descriptor->bcdUSB, Descriptor->bcdDevice, Revision);
675 Status = RtlStringCbPrintfW(Name, NameBytes, L"%04X%04X", Descriptor->idVendor, Descriptor->idProduct);
676 if (NT_SUCCESS(Status))
677 Status = RtlStringCbCatW(Name, NameBytes, Revision);
678 }
679
680 if (NT_SUCCESS(Status))
681 Status = RtlStringCbCatW(Name, NameBytes, Child->m_SerialNumber + Child->m_SerialPrefixLength / sizeof(WCHAR));
682
683 if (NT_SUCCESS(Status))
685
686 if (!NT_SUCCESS(Status))
687 {
688 DPRINT1("Container id name for device %p failed: 0x%lx\n", Child, Status);
690 return;
691 }
692
693 HubSha1Init(&Sha);
696 HubSha1Final(&Sha, Digest);
698
699 RtlCopyMemory(&Child->m_ContainerId, Digest, sizeof(Child->m_ContainerId));
700 Child->m_ContainerId.Data3 = (Child->m_ContainerId.Data3 & 0x0FFF) | 0x5000;
701 Child->m_ContainerId.Data4[0] = (Child->m_ContainerId.Data4[0] & 0x3F) | 0x80;
703}
704
705static
707NTAPI
710{
711 return Child->HasProperty(ChildProperty::ContainerIdKnown) ||
713}
714
715/* Never fails the PDO; a fixed device takes its container from its parent */
716static
717VOID
718NTAPI
722{
724 const GUID* Id = &Child->m_ContainerId;
727
728 if (Child->HasProperty(ChildProperty::NotRemovable))
729 return;
730
731 if (!HubIdHasContainerId(Child) && Child->m_SerialNumber != NULL)
733
735 return;
736
737 Text.Format(L"{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
738 Id->Data1, Id->Data2, Id->Data3,
739 Id->Data4[0], Id->Data4[1], Id->Data4[2], Id->Data4[3],
740 Id->Data4[4], Id->Data4[5], Id->Data4[6], Id->Data4[7]);
741
743 if (!NT_SUCCESS(Status))
744 DPRINT1("Container id for device %p not assigned: 0x%lx\n", Child, Status);
745}
746
748NTAPI
752{
754
756 return FALSE;
757
758 *ContainerId = Child->m_ContainerId;
759 return TRUE;
760}
761
762/* VM RESERVED ID ************************************************************/
763
764/* The value's WDFSTRING is deleted here; if the copy fails the id stays empty and the PDO is not created */
766static
768NTAPI
769HubIdLoadVmReservedId(
771{
773 WDFSTRING String;
776
777 PAGED_CODE();
778
779 if (Child->m_VmReservedId.Buffer != NULL)
780 ExFreePoolWithTag(Child->m_VmReservedId.Buffer, HUB_TAG_DEVICE);
781 RtlZeroMemory(&Child->m_VmReservedId, sizeof(Child->m_VmReservedId));
782
783 Status = WdfStringCreate(NULL, WDF_NO_OBJECT_ATTRIBUTES, &String);
784 if (!NT_SUCCESS(Status))
785 {
786 DPRINT1("VM reserved id string for device %p failed 0x%lx\n", Child, Status);
787 return Status;
788 }
789
790 HubQueryUxdDeviceValue(Child, String);
792
794 if (Buffer == NULL)
795 {
796 DPRINT1("VM reserved id for device %p could not be allocated\n", Child);
799 }
800
801 RtlCopyMemory(Buffer, Value.Buffer, Value.Length);
802
803 Child->m_VmReservedId.Buffer = Buffer;
804 Child->m_VmReservedId.Length = Value.Length + sizeof(WCHAR);
805 Child->m_VmReservedId.MaximumLength = Child->m_VmReservedId.Length;
806
808 return STATUS_SUCCESS;
809}
810
811VOID
812NTAPI
815{
816 if (Child->m_VmReservedId.Buffer != NULL)
817 ExFreePoolWithTag(Child->m_VmReservedId.Buffer, HUB_TAG_DEVICE);
818
819 RtlZeroMemory(&Child->m_VmReservedId, sizeof(Child->m_VmReservedId));
820}
821
822/* PDO IDS *******************************************************************/
823
824/* The serial number is never truncated, whatever its length */
826static
828NTAPI
832{
833 HubPort* Port = Child->m_Port;
838
839 if (Child->m_SerialNumber != NULL)
840 {
841 RtlInitUnicodeString(&Id, Child->m_SerialNumber);
842 Status = WdfPdoInitAssignInstanceID(DeviceInit, &Id);
843 if (!NT_SUCCESS(Status))
844 DPRINT1("Instance id %wZ for device %p failed 0x%lx\n", &Id, Child, Status);
845
846 return Status;
847 }
848
849 Number = Port->Number();
851 Port->m_InstancePortNumber != 0 &&
853 {
854 Number = Port->m_InstancePortNumber;
855 }
856
858
860 if (NT_SUCCESS(Status))
861 Status = WdfPdoInitAssignInstanceID(DeviceInit, &Id);
862
863 if (!NT_SUCCESS(Status))
864 DPRINT1("Instance id from port %lu for device %p failed 0x%lx\n", Number, Child, Status);
865
866 return Status;
867}
868
871NTAPI
872HubIdAssignPdoIds(
875{
877
879
881
883 {
884 Status = HubIdLoadVmReservedId(Child);
885 if (!NT_SUCCESS(Status))
886 return Status;
887 }
888
890 if (!NT_SUCCESS(Status))
891 return Status;
892
894 if (!NT_SUCCESS(Status))
895 return Status;
896
898 if (!NT_SUCCESS(Status))
899 return Status;
900
902
904}
905
906/* DEVICE TEXT ***************************************************************/
907
908/* A zero entry ends the device's language list */
910NTAPI
913 _In_ USHORT Language)
914{
915 const USB_STRING_DESCRIPTOR* List = Child->m_LanguageIds;
916 ULONG Count;
917 ULONG Index;
918
919 if (List == NULL || List->bLength <= 2)
920 return FALSE;
921
922 Count = (List->bLength - 2) / sizeof(WCHAR);
923 for (Index = 0; Index < Count && List->bString[Index] != 0; Index++)
924 {
925 if (List->bString[Index] == Language)
926 return TRUE;
927 }
928
929 return FALSE;
930}
931
932/* The device machine reads the product string in m_LanguageId and signals */
934static
935VOID
936NTAPI
937HubIdReadProductString(
939{
940 KeClearEvent(&Child->m_QueryTextEvent);
942 HubWaitForPnpEvent(&Child->m_QueryTextEvent, "device text query", Child->m_Object);
943}
944
946static
948NTAPI
949HubIdLocationText(
952{
953 PWCHAR Text;
955
957 if (Text == NULL)
958 {
959 DPRINT1("Location text for device %p could not be allocated\n", Child);
961 }
962
963 Status = RtlStringCbPrintfW(Text, HUB_LOCATION_TEXT_BYTES, L"Port_#%04d.Hub_#%04d",
964 Child->m_Port->Number(), Child->m_Hub->m_HubNumber);
966 {
967 DPRINT1("Location text for device %p failed 0x%lx\n", Child, Status);
969 return Status;
970 }
971
972 Irp->IoStatus.Information = (ULONG_PTR)Text;
974}
975
976/*
977 * The "disable serial number" errata also hides the product string. A
978 * language the device lacks, or a failed read, falls back to US English.
979 */
981static
983NTAPI
984HubIdDescriptionText(
988{
989 USHORT Language = LANGIDFROMLCID(Locale);
992 PWCHAR Text;
993
994 if (Child->m_DeviceDescriptor.iProduct == 0 || Child->HasHack(ChildHack::DisableSerialNumber))
996
997 Irp->IoStatus.Information = 0;
998
999 if (Language == 0 || !HubIdLanguageSupported(Child, Language))
1000 Language = HUB_DEFAULT_LANGUAGE;
1001
1002 if (Language != Child->m_LanguageId)
1003 {
1004 Child->m_LanguageId = Language;
1005 if (Child->m_ProductString != NULL)
1006 {
1007 ExFreePoolWithTag(Child->m_ProductString, HUB_TAG_DEVICE);
1008 Child->m_ProductString = NULL;
1009 }
1010
1011 HubIdReadProductString(Child);
1012 }
1013
1014 if (Child->m_ProductString == NULL)
1015 {
1016 if (Language == HUB_DEFAULT_LANGUAGE)
1017 {
1018 DPRINT("Device %p has no product string\n", Child);
1019 return STATUS_NOT_SUPPORTED;
1020 }
1021
1022 Child->m_LanguageId = HUB_DEFAULT_LANGUAGE;
1023 HubIdReadProductString(Child);
1024
1025 if (Child->m_ProductString == NULL)
1026 {
1027 DPRINT("Device %p has no product string\n", Child);
1028 return STATUS_NOT_SUPPORTED;
1029 }
1030 }
1031
1032 Product = Child->m_ProductString;
1033 Characters = (Product->bLength - 2) / sizeof(WCHAR) + 1;
1034
1036 if (Text == NULL)
1037 {
1038 DPRINT1("Description text for device %p could not be allocated\n", Child);
1040 }
1041
1044
1045 Irp->IoStatus.Information = (ULONG_PTR)Text;
1046 return STATUS_SUCCESS;
1047}
1048
1051NTAPI
1052HubIdQueryDeviceText(
1055{
1058
1059 PAGED_CODE();
1060
1061 switch (Stack->Parameters.QueryDeviceText.DeviceTextType)
1062 {
1064 Status = HubIdLocationText(Child, Irp);
1065 break;
1066
1068 Status = HubIdDescriptionText(Child, Irp, Stack->Parameters.QueryDeviceText.LocaleId);
1069 break;
1070
1071 default:
1073 break;
1074 }
1075
1076 Irp->IoStatus.Status = Status;
1078 return Status;
1079}
1080
1081/* SERIAL NUMBER *************************************************************/
1082
1083/* Bytes the last control transfer of the device returned into the scratch buffer */
1084static
1085ULONG
1086NTAPI
1089{
1090 return min(Child->m_Control.Urb.TransferBufferLength, (ULONG)sizeof(Child->m_ScratchBuffer));
1091}
1092
1093/* Serial number prefix for the instance id, so the two halves of a USB 3 hub, and UAS and BOT, never share one */
1094static
1095PCWSTR
1096NTAPI
1099{
1100 if (Child->HasProperty(ChildProperty::IsHub))
1101 return (Child->m_DeviceDescriptor.bcdUSB >= 0x0300) ? L"MSFT30" : L"MSFT20";
1102
1103 if (Child->HasState(ChildState::PrefixedSerial))
1104 return L"MSFT30";
1105
1106 return NULL;
1107}
1108
1109BOOLEAN
1110NTAPI
1115{
1116 *Text = NULL;
1117 *Length = 0;
1118
1119 if (Child->m_SerialNumber == NULL ||
1120 Child->m_SerialNumberLength < Child->m_SerialPrefixLength + sizeof(WCHAR))
1121 {
1122 return FALSE;
1123 }
1124
1125 *Text = Child->m_SerialNumber + Child->m_SerialPrefixLength / sizeof(WCHAR);
1126 *Length = Child->m_SerialNumberLength - Child->m_SerialPrefixLength - sizeof(WCHAR);
1127 return TRUE;
1128}
1129
1130BOOLEAN
1132{
1133 return m_Device->HasHack(ChildHack::DisableSerialNumber);
1134}
1135
1136BOOLEAN
1138{
1140}
1141
1142/* Sized from the transfer length and the decoration written, not bLength, so a zeroed tail ends the string */
1143BOOLEAN
1145{
1151 PCWSTR Prefix;
1152 ULONG PrefixBytes;
1153 PWCHAR Buffer;
1154
1156 Child->m_DeviceDescriptor.bcdUSB,
1157 Child->Speed(),
1158 Child->HasHack(ChildHack::UseWin8DescriptorValidation),
1159 Child->m_Port->m_Info.SspIsochBurstCount,
1160 Child->m_ValidationBits);
1161
1163 {
1164 DPRINT1("Device %p serial number string is invalid (%lu bytes)\n", Child, Returned);
1165 Child->m_EnumMessageId = HUB_ENUM_BAD_SERIAL_NUMBER;
1166 return FALSE;
1167 }
1168
1169 if (Child->m_SerialNumber != NULL)
1170 {
1171 ExFreePoolWithTag(Child->m_SerialNumber, HUB_TAG_DEVICE);
1172 Child->m_SerialNumber = NULL;
1173 }
1174
1176 PrefixBytes = (Prefix != NULL) ? HUB_SERIAL_PREFIX_BYTES : 0;
1177
1179 if (Buffer == NULL)
1180 {
1181 DPRINT1("Device %p serial number could not be allocated\n", Child);
1182 return FALSE;
1183 }
1184
1185 if (Prefix != NULL)
1186 RtlCopyMemory(Buffer, Prefix, PrefixBytes);
1187
1188 /* Length is bLength now: the string bytes plus room for the NUL */
1189 RtlCopyMemory((PUCHAR)Buffer + PrefixBytes, Descriptor->bString, Length - sizeof(WCHAR));
1190
1191 Child->m_SerialNumber = Buffer;
1192 Child->m_SerialNumberLength = Returned + PrefixBytes;
1193 Child->m_SerialPrefixLength = PrefixBytes;
1194 return TRUE;
1195}
1196
1197VOID
1199{
1201 return;
1202
1205}
1206
1207BOOLEAN
1209{
1211 return FALSE;
1212
1213 return m_Device->m_DeviceDescriptor.bcdUSB > 0x0200 || IsBootDevice();
1214}
1215
1216/* Lengths come from transfers, so different padding between reads or a short length does not match */
1217BOOLEAN
1219{
1223 PCWSTR Stored;
1224 ULONG StoredLength;
1225
1226 if (!HubIdGetSerialNumberText(Child, &Stored, &StoredLength) || Returned < 2)
1227 return FALSE;
1228
1229 if (StoredLength == Returned - 2 &&
1230 RtlEqualMemory(Descriptor->bString, Stored, StoredLength))
1231 {
1232 return TRUE;
1233 }
1234
1235 DPRINT1("Device %p came back with a different serial number\n", Child);
1236 return FALSE;
1237}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
char ** Args
Definition: acdebug.h:353
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
RtlInitEmptyUnicodeString(SymbolicLinkName, NULL, 0)
Definition: bufpool.h:45
HubChild * m_Device
Definition: devsm.h:1832
BOOLEAN SerialNumberValid()
Definition: hubid.cpp:1144
BOOLEAN SerialNumberIndexZero()
Definition: hubid.cpp:1137
VOID DropSerialNumber()
Definition: hubid.cpp:1198
BOOLEAN SerialNumberCompared()
Definition: hubid.cpp:1208
BOOLEAN SameSerialNumber()
Definition: hubid.cpp:1218
BOOLEAN IgnoreSerialNumber()
Definition: hubid.cpp:1131
BOOLEAN IsBootDevice()
Definition: childpdo.cpp:4128
USB_DEVICE_DESCRIPTOR m_DeviceDescriptor
Definition: hubchild.h:386
PWCHAR m_SerialNumber
Definition: hubchild.h:400
BOOLEAN HasHack(_In_ ChildHack Flag) const
Definition: hubchild.h:281
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
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
BOOLEAN NTAPI HubDescCheckSerialNumber(_In_ const HubDescContext *Context, _In_reads_bytes_(*Length) PUSB_STRING_DESCRIPTOR Descriptor, _Inout_ PULONG Length)
Definition: desccheck.cpp:2418
#define HUB_MSOS20_COMPATIBLE_ID
Definition: desccheck.h:493
LPWSTR Name
Definition: desk.c:124
@ DeviceTextQuery
_Check_return_ _In_ ULONG _Inout_ PDXGK_CHILD_CONTAINER_ID ContainerId
Definition: dispmprt.h:1484
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define va_end(v)
Definition: stdarg.h:28
#define va_start(v, l)
Definition: stdarg.h:26
char * va_list
Definition: vadefs.h:50
#define L(x)
Definition: resources.c:13
#define ULONG_PTR
Definition: config.h:101
#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
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
Status
Definition: gdiplustypes.h:24
CPPORT Port[4]
Definition: headless.c:38
@ ConfigurationValid
@ DisableSerialNumber
static const HubFailureId HubUnknownDeviceId
Definition: hubid.cpp:52
static BOOLEAN NTAPI HubIdUsesFailureId(_In_ HubChild *Child)
Definition: hubid.cpp:289
#define HUB_DEFAULT_LANGUAGE
Definition: hubid.cpp:23
static PCWSTR NTAPI HubIdSerialPrefix(_In_ HubChild *Child)
Definition: hubid.cpp:1097
static NTSTATUS NTAPI HubIdEmit(_In_ const HubIdSink *Sink, _In_ PCUNICODE_STRING Id)
Definition: hubid.cpp:198
static BOOLEAN NTAPI HubIdHasContainerId(_In_ HubChild *Child)
Definition: hubid.cpp:708
static const WCHAR HubBillboardId[]
Definition: hubid.cpp:56
BOOLEAN NTAPI HubIdLanguageSupported(_In_ HubChild *Child, _In_ USHORT Language)
Definition: hubid.cpp:911
static NTSTATUS NTAPI HubIdBuildCompositeIds(_In_ HubChild *Child, _In_ const HubIdSink *Sink)
Definition: hubid.cpp:422
HubIdKind
Definition: hubid.cpp:79
static const GUID HubContainerIdNamespace
Definition: hubid.cpp:26
NTSTATUS NTAPI HubIdBuildCompatibleIds(_In_ HubChild *Child, _In_opt_ PWDFDEVICE_INIT DeviceInit, _Out_opt_ PUSB_ID_STRING Ids)
Definition: hubid.cpp:597
NTSTATUS NTAPI HubIdBuildHardwareIds(_In_ HubChild *Child, _In_opt_ PWDFDEVICE_INIT DeviceInit, _Out_opt_ PUSB_ID_STRING Ids)
Definition: hubid.cpp:381
_Inout_ PIRP _In_ LCID Locale
Definition: hubid.cpp:988
static const HubFailureId *NTAPI HubFailureIdFor(_In_ HubChild *Child)
Definition: hubid.cpp:61
static NTSTATUS NTAPI HubIdListAppend(_Inout_ PUSB_ID_STRING List, _In_ PCUNICODE_STRING Id)
Definition: hubid.cpp:130
static NTSTATUS NTAPI HubIdBuildClassIds(_In_ HubChild *Child, _In_ const HubIdSink *Sink)
Definition: hubid.cpp:541
PUSB_STRING_DESCRIPTOR Product
Definition: hubid.cpp:990
#define HUB_ID_MAX_CHARS
Definition: hubid.cpp:15
static VOID NTAPI HubIdBuildContainerId(_In_ HubChild *Child, _In_ PWDFDEVICE_INIT DeviceInit)
Definition: hubid.cpp:719
PAGED_CODE()
static NTSTATUS NTAPI HubIdEmitCounted(_In_ const HubIdSink *Sink, _In_reads_bytes_(IdBytes) PCWSTR Id, _In_ USHORT IdBytes)
Definition: hubid.cpp:261
return STATUS_SUCCESS
Definition: hubid.cpp:973
static NTSTATUS NTAPI HubIdBuildMsOsIds(_In_ HubChild *Child, _In_ const HubIdSink *Sink)
Definition: hubid.cpp:494
VOID NTAPI HubIdListFree(_Inout_ PUSB_ID_STRING Ids)
Definition: hubid.cpp:159
UNICODE_STRING Id
Definition: hubid.cpp:835
HubSaveUxdState(Child->m_Hub, Child, NULL)
#define HUB_LOCATION_TEXT_BYTES
Definition: hubid.cpp:21
#define HUB_FAILURE_ID(Reason, Pid, Text)
Definition: hubid.cpp:38
VOID NTAPI HubIdFreeDeviceIds(_In_ HubChild *Child)
Definition: hubid.cpp:813
WCHAR Digits[HUB_INSTANCE_ID_CHARS]
Definition: hubid.cpp:834
static NTSTATUS NTAPI HubIdBuildDeviceId(_In_ HubChild *Child, _In_ PWDFDEVICE_INIT DeviceInit)
Definition: hubid.cpp:348
return HubIdAssignInstanceId(Child, DeviceInit)
Text
Definition: hubid.cpp:956
static VOID NTAPI HubIdGenerateContainerId(_In_ HubChild *Child)
Definition: hubid.cpp:647
static BOOLEAN NTAPI HubIdIsKnown(_In_ HubChild *Child)
Definition: hubid.cpp:279
#define HUB_INSTANCE_ID_CHARS
Definition: hubid.cpp:18
static NTSTATUS NTAPI HubIdEmitMsComp(_In_ const HubIdSink *Sink, _In_reads_(8) const UCHAR *CompatibleId, _In_reads_opt_(8) const UCHAR *SubCompatibleId)
Definition: hubid.cpp:468
static VOID NTAPI HubIdWidenMsOsField(_In_reads_(8) const UCHAR *Field, _Out_writes_(9) PWCHAR Text)
Definition: hubid.cpp:331
ULONG Number
Definition: hubid.cpp:836
BOOLEAN NTAPI HubIdGetContainerId(_In_ HubChild *Child, _Out_ GUID *ContainerId)
Definition: hubid.cpp:749
static BOOLEAN NTAPI HubIdIsVmReserved(_In_ HubChild *Child)
Definition: hubid.cpp:298
static ULONG NTAPI HubIdBytesReturned(_In_ HubChild *Child)
Definition: hubid.cpp:1087
_In_ PWDFDEVICE_INIT DeviceInit
Definition: hubid.cpp:832
static NTSTATUS NTAPI HubIdEmitText(_In_ const HubIdSink *Sink, _In_ const HubIdText *Text)
Definition: hubid.cpp:241
NTSTATUS Status
Definition: hubid.cpp:837
static const HubFailureId HubFailureIds[]
Definition: hubid.cpp:40
NTSTATUS NTAPI HubIdListCopy(_Out_ PUSB_ID_STRING Destination, _In_ const USB_ID_STRING *Source)
Definition: hubid.cpp:173
BOOLEAN NTAPI HubIdGetSerialNumberText(_In_ HubChild *Child, _Outptr_result_bytebuffer_(*Length) PCWSTR *Text, _Out_ PULONG Length)
Definition: hubid.cpp:1111
ULONG Characters
Definition: hubid.cpp:991
static VOID NTAPI HubIdRevisionText(_In_ USHORT BcdUsb, _In_ USHORT BcdDevice, _Out_writes_(5) PWCHAR Text)
Definition: hubid.cpp:309
#define HUB_ENUM_DEVICE_DESCRIPTOR_FAILED
Definition: hubid.h:11
#define HUB_ENUM_BAD_DEVICE_DESCRIPTOR
Definition: hubid.h:15
#define HUB_ENUM_BAD_SERIAL_NUMBER
Definition: hubid.h:31
#define HUB_ENUM_SET_ADDRESS_FAILED
Definition: hubid.h:12
#define HUB_SERIAL_PREFIX_BYTES
Definition: hubid.h:42
#define HUB_ENUM_BAD_CONFIG_DESCRIPTOR
Definition: hubid.h:14
VOID NTAPI HubSha1Init(_Out_ HubSha1 *Context)
Definition: hubsha1.cpp:90
VOID NTAPI HubSha1Update(_Inout_ HubSha1 *Context, _In_reads_bytes_(Length) const VOID *Data, _In_ SIZE_T Length)
Definition: hubsha1.cpp:103
VOID NTAPI HubSha1Final(_Inout_ HubSha1 *Context, _Out_writes_bytes_all_(HUB_SHA1_DIGEST_BYTES) PUCHAR Digest)
Definition: hubsha1.cpp:132
#define HUB_ENUM_PORT_RESET_FAILED
Definition: hubid.h:13
#define HUB_ENUM_LINK_COMPLIANCE
Definition: hubid.h:33
#define HUB_ENUM_CONFIG_DESCRIPTOR_FAILED
Definition: hubid.h:16
#define HUB_SHA1_DIGEST_BYTES
Definition: hubid.h:53
#define HUB_ENUM_LINK_SS_INACTIVE
Definition: hubid.h:32
_In_ const HubIdStrings * Ids
ULONG Returned
#define HUB_TAG_DEVICE
Definition: hubutil.h:13
ULONG Total
Definition: hubwmi.cpp:548
#define RtlEqualMemory(dst, src, len)
Definition: kdvm.h:18
_In_ PIRP Irp
Definition: kse.h:79
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
PVOID PVOID PWCHAR PVOID USHORT PULONG Reason
Definition: env.c:47
static PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
#define min(a, b)
Definition: monoChain.cc:55
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
_In_ ULONG Number
Definition: haltypes.h:1940
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3051
#define _In_reads_bytes_(s)
Definition: no_sal2.h:170
#define _In_reads_(s)
Definition: no_sal2.h:168
#define _Outptr_result_bytebuffer_(s)
Definition: no_sal2.h:288
#define _Out_opt_
Definition: no_sal2.h:214
#define _Inout_
Definition: no_sal2.h:162
#define _In_z_
Definition: no_sal2.h:164
#define _Out_writes_(s)
Definition: no_sal2.h:176
#define _Out_
Definition: no_sal2.h:160
#define _In_reads_opt_(s)
Definition: no_sal2.h:222
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define _Printf_format_string_
Definition: no_sal2.h:356
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI NTSTATUS NTAPI RtlIntegerToUnicodeString(ULONG Value, ULONG Base, PUNICODE_STRING String)
WCHAR * PWCH
Definition: ntbasedef.h:422
#define UNICODE_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define IoCompleteRequest
Definition: irp.c:1272
NTSTRSAFEAPI RtlStringCbCopyW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:174
NTSTRSAFEAPI RtlStringCbCatW(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:636
_Must_inspect_result_ NTSTRSAFEAPI RtlStringCbLengthW(_In_reads_or_z_(cbMax/sizeof(wchar_t)) STRSAFE_LPCWSTR psz, _In_ _In_range_(1, NTSTRSAFE_MAX_CCH *sizeof(wchar_t)) size_t cbMax, _Out_opt_ _Deref_out_range_(<, cbMax - 1) size_t *pcbLength)
Definition: ntstrsafe.h:1641
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
NTSTRSAFEAPI RtlStringCbVPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat, _In_ va_list argList)
Definition: ntstrsafe.h:1052
short WCHAR
Definition: pedump.c:58
unsigned short USHORT
Definition: pedump.c:61
Input NameLength
Definition: portacpi.cpp:298
#define LANGIDFROMLCID(l)
Definition: nls.h:18
DWORD LCID
Definition: nls.h:13
_In_ const GUID _In_ ULONG Revision
Definition: slotdev.cpp:85
#define DPRINT
Definition: sndvol32.h:73
USHORT ProductId
Definition: hubid.cpp:33
PCWSTR Id
Definition: hubid.cpp:34
ULONG Reason
Definition: hubid.cpp:32
USHORT IdBytes
Definition: hubid.cpp:35
PUSB_ID_STRING List
Definition: hubid.cpp:90
HubIdKind Kind
Definition: hubid.cpp:88
PWDFDEVICE_INIT Init
Definition: hubid.cpp:89
NTSTATUS Status
Definition: hubid.cpp:97
VOID Append(_In_z_ PCWSTR Text)
Definition: hubid.cpp:119
VOID Format(_In_z_ _Printf_format_string_ PCWSTR Format,...)
Definition: hubid.cpp:100
VOID Set(_In_z_ PCWSTR Text)
Definition: hubid.cpp:112
Definition: hubid.h:46
Definition: precomp.h:83
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
unsigned char UCHAR
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint16_t * PWCHAR
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
_In_ UCXUSBDEVICE _In_ ULONG Interface
Definition: ucxusbdevice.h:428
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _USB_STRING_DESCRIPTOR * PUSB_STRING_DESCRIPTOR
@ UsbSuperSpeed
Definition: usb200.h:45
@ UsbHighSpeed
Definition: usb200.h:44
@ UsbFullSpeed
Definition: usb200.h:43
USHORT Count
Definition: userreq.cpp:200
WdfObjectDelete(String)
WdfStringGetUnicodeString(Original, &Name)
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ PWDFDEVICE_INIT DeviceInit
Definition: wdfcontrol.h:113
_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_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
#define WDF_NO_OBJECT_ATTRIBUTES
Definition: wdftypes.h:105
#define IO_NO_INCREMENT
Definition: iotypes.h:598
@ DeviceTextLocationInformation
Definition: iotypes.h:2961
@ DeviceTextDescription
Definition: iotypes.h:2960
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1647