Tworzenie urządzenia na potrzeby WebUSB

Utwórz urządzenie, aby w pełni korzystać z interfejsu WebUSB API.

Z tego artykułu dowiesz się, jak zbudować urządzenie, aby w pełni korzystać z interfejsu WebUSB API. Krótkie wprowadzenie do interfejsu API znajdziesz w artykule Dostęp do urządzeń USB w przeglądarce.

Tło

Uniwersalny interfejs szeregowy (USB) stał się najpopularniejszym interfejsem fizycznym do podłączania urządzeń peryferyjnych do komputerów stacjonarnych i przenośnych. Oprócz definiowania właściwości elektrycznych magistrali i ogólnego modelu komunikacji z urządzeniem specyfikacje USB zawierają zestaw specyfikacji klasy urządzenia. Są to ogólne modele dla poszczególnych klas urządzeń, takich jak pamięć masowa, dźwięk, wideo, sieci itp., które mogą wdrażać producenci urządzeń. Zaletą tych specyfikacji jest to, że dostawca systemu operacyjnego może wdrożyć jeden sterownik na podstawie specyfikacji klasy (tzw. sterownik klasy), a dowolne urządzenie obsługujące tę klasę będzie obsługiwane. To było ogromne ulepszenie w porównaniu z tym, że każdy producent musiał pisać własne sterowniki urządzeń.

Niektóre urządzenia nie pasują do żadnej ze standardowych klas urządzeń. Producent może zamiast tego oznaczyć urządzenie jako implementujące klasę specyficzną dla dostawcy. W tym przypadku system operacyjny wybiera sterownik urządzenia do załadowania na podstawie informacji zawartych w pakiecie sterownika dostawcy, czyli zazwyczaj zestawu identyfikatorów dostawcy i produktu, które implementują określony protokół dostawcy.

Inną cechą USB jest to, że urządzenia mogą udostępniać wiele interfejsów hostowi, z którym są połączone. Każdy interfejs może implementować standardową klasę lub być specyficzny dla danego dostawcy. Gdy system operacyjny wybiera odpowiednie sterowniki do obsługi urządzenia, każdy interfejs może być przypisany do innego sterownika. Na przykład kamera internetowa USB zwykle udostępnia 2 interfejsy: jeden implementujący klasę wideo USB (dla kamery) i drugi implementujący klasę audio USB (dla mikrofonu). System operacyjny nie wczytuje jednego „sterownika kamery internetowej”, lecz niezależne sterowniki klasy wideo i dźwięku, które odpowiadają za poszczególne funkcje urządzenia. Ta kompozycja klas interfejsu zapewnia większą elastyczność.

Podstawy interfejsu API

Wiele standardowych klas USB ma odpowiadające im interfejsy API internetowe. Na przykład strona może rejestrować filmy z urządzenia z klasy wideo za pomocą getUserMedia() lub odbierać zdarzenia wejścia z urządzenia z klasy interfejsu człowieka (HID), nasłuchując KeyboardEvents lub PointerEvents albo używając interfejsu Gamepad lub interfejsu WebHID API. Podobnie jak nie wszystkie urządzenia implementują standardową definicję klasy, tak nie wszystkie urządzenia implementują funkcje odpowiadające istniejącym interfejsom API platformy internetowej. W takim przypadku interfejs WebUSB API może wypełnić tę lukę, zapewniając witrynom możliwość korzystania z interfejsu konkretnego dostawcy i wdrożenia obsługi bezpośrednio na stronie.

Wymagania dotyczące dostępu do urządzenia przez WebUSB różnią się nieznacznie w zależności od platformy z powodu różnic w sposobie zarządzania urządzeniami USB przez systemy operacyjne. Podstawowym wymaganiem jest jednak to, aby urządzenie nie miało już sterownika, który obsługuje interfejs, którym strona chce sterować. Może to być sterownik ogólny klasy dostarczony przez dostawcę systemu operacyjnego lub sterownik urządzenia dostarczony przez producenta. Urządzenia USB mogą mieć wiele interfejsów, z których każdy może mieć własny sterownik. Dzięki temu można tworzyć urządzenia, w których przypadku niektóre interfejsy są obsługiwane przez sterownik, a inne są dostępne dla przeglądarki.

Na przykład zaawansowana klawiatura USB może udostępniać interfejs klasy HID, który będzie używany przez podsystem wejściowy systemu operacyjnego, oraz interfejs dostawcy, który będzie dostępny dla WebUSB do użycia przez narzędzie konfiguracyjne. To narzędzie może być dostępne na stronie internetowej producenta, co pozwala użytkownikowi zmieniać aspekty działania urządzenia, takie jak klawisze makro i efekty świetlne, bez instalowania oprogramowania związanego z konkretną platformą. Deskryptor konfiguracji takiego urządzenia wyglądałby mniej więcej tak:

Wartość Pole Opis
Deskryptor konfiguracji
0x09 bLength Rozmiar tego opisu
0x02 bDescriptorType Deskryptor konfiguracji
0x0039 wTotalLength Łączny czas trwania tej serii opisu
0x02 bNumInterfaces Liczba interfejsów
0x01 bConfigurationValue Configuration 1
0x00 iConfiguration Nazwa konfiguracji (brak)
0b1010000 bmAttributes autonomiczne urządzenie z możliwością zdalnego budzenia;
0x32 bMaxPower Maksymalna moc jest wyrażana w przyrostach co 2 mA.
Deskryptor interfejsu
0x09 bLength Rozmiar tego opisu
0x04 bDescriptorType Deskryptor interfejsu
0x00 bInterfaceNumber Interfejs 0
0x00 bAlternateSetting Ustawienie alternatywne 0 (domyślnie)
0x01 bNumEndpoints 1 punkt końcowy
0x03 bInterfaceClass Klasa interfejsu HID
0x01 bInterfaceSubClass Podklasa interfejsu rozruchu
0x01 bInterfaceProtocol Klawiatura
0x00 iInterface Nazwa interfejsu (brak)
Deskryptor HID
0x09 bLength Rozmiar tego opisu
0x21 bDescriptorType Deskryptor HID
0x0101 bcdHID HID w wersji 1.1
0x00 bCountryCode Kraj docelowy sprzętu
0x01 bNumDescriptors Liczba opisów klas HID do wyświetlenia
0x22 bDescriptorType Typ opisu raportu
0x003F wDescriptorLength Łączna długość deskryptora raportu
Deskryptor punktu końcowego
0x07 bLength Rozmiar tego opisu
0x05 bDescriptorType Deskryptor punktu końcowego
0b10000001 bEndpointAddress Punkt końcowy 1 (IN)
0b00000011 bmAttributes Przerwij
0x0008 wMaxPacketSize Pakiety 8-bajtowe
0x0A bInterval Interwał 10 ms
Deskryptor interfejsu
0x09 bLength Rozmiar tego opisu
0x04 bDescriptorType Deskryptor interfejsu
0x01 bInterfaceNumber Interfejs 1
0x00 bAlternateSetting Ustawienie alternatywne 0 (domyślnie)
0x02 bNumEndpoints 2 punkty końcowe
0xFF bInterfaceClass Klasa interfejsu specyficzna dla dostawcy
0x00 bInterfaceSubClass
0x00 bInterfaceProtocol
0x00 iInterface Nazwa interfejsu (brak)
Deskryptor punktu końcowego
0x07 bLength Rozmiar tego opisu
0x05 bDescriptorType Deskryptor punktu końcowego
0b10000010 bEndpointAddress Punkt końcowy 1 (IN)
0b00000010 bmAttributes Zbiorczy
0x0040 wMaxPacketSize Pakiety 64-bajtowe
0x00 bInterval Nie dotyczy punktów końcowych zbiorczych
Deskryptor punktu końcowego
0x07 bLength Rozmiar tego opisu
0x05 bDescriptorType Deskryptor punktu końcowego
0b00000011 bEndpointAddress Punkt końcowy 3 (OUT)
0b00000010 bmAttributes Zbiorczy
0x0040 wMaxPacketSize Pakiety 64-bajtowe
0x00 bInterval Nie dotyczy punktów końcowych zbiorczych

Deskryptor konfiguracji składa się z kilku powiązanych ze sobą deskryptorów. Każdy z nich zaczyna się od pól bLengthbDescriptorType, dzięki czemu można je zidentyfikować. Pierwszy interfejs to interfejs HID z powiązanym deskryptorem HID i jednym punktem końcowym służącym do przesyłania zdarzeń wejściowych do systemu operacyjnego. Drugi interfejs to interfejs dostawcy z 2 punktami końcowymi, które można wykorzystać do wysyłania poleceń do urządzenia i odbierania odpowiedzi.

Deskryptory WebUSB

WebUSB może działać na wielu urządzeniach bez modyfikacji oprogramowania układowego, ale dodatkowe funkcje są dostępne po oznaczeniu urządzenia za pomocą określonych deskryptorów wskazujących obsługę WebUSB. Możesz na przykład określić adres URL strony docelowej, do której przeglądarka może przekierować użytkownika, gdy urządzenie jest podłączone.

Zrzut ekranu przedstawiający powiadomienie WebUSB w Chrome
Powiadomienie WebUSB

Binary device Object Store (BOS) to koncepcja wprowadzona w USB 3.0, ale została ona również zaimplementowana wstecznie na urządzeniach USB 2.0 w ramach wersji 2.1. Aby zadeklarować obsługę WebUSB, w descryptor BOS należy dodać ten opis platformy:

Wartość Pole Opis
Deskryptor obiektu pamięci obiektowej urządzenia binarnego
0x05 bLength Rozmiar tego opisu
0x0F bDescriptorType Deskryptor obiektu pamięci obiektowej urządzenia binarnego
0x001D wTotalLength Łączny czas trwania tej serii opisu
0x01 bNumDeviceCaps Liczba opisów możliwości urządzenia w pliku BOS
Deskryptor możliwości platformy WebUSB
0x18 bLength Rozmiar tego opisu
0x10 bDescriptorType Deskryptor możliwości urządzenia
0x05 bDevCapabilityType Deskryptor możliwości platformy
0x00 bReserved
{0x38, 0xB6, 0x08, 0x34, 0xA9, 0x09, 0xA0, 0x47, 0x8B, 0xFD, 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65} PlatformCapablityUUID Identyfikator GUID deskryptora możliwości platformy WebUSB w formacie little-endian
0x0100 bcdVersion Deskryptor WebUSB w wersji 1.0
0x01 bVendorCode bWartość żądania dla WebUSB
0x01 iLandingPage Adres URL strony docelowej

Identyfikator UUID platformy wskazuje, że jest to deskryptor platformy WebUSB, który zawiera podstawowe informacje o urządzeniu. Aby uzyskać więcej informacji o urządzeniu, przeglądarka używa wartości bVendorCode do wysyłania dodatkowych żądań do urządzenia. Obecnie jedynym określonym żądaniem jest GET_URL, które zwraca deskryptor adresu URL. Są one podobne do opisów ciągu znaków, ale służą do kodowania adresów URL w najmniejszej liczbie bajtów. Adres URL z indeksem "https://google.com" wygląda tak:

Wartość Pole Opis
Deskryptor adresu URL
0x0D bLength Rozmiar tego opisu
0x03 bDescriptorType Deskryptor adresu URL
0x01 bScheme https://
"google.com" URL Treść adresu URL zakodowana w UTF-8

Gdy urządzenie zostanie po raz pierwszy podłączone, przeglądarka odczyta opis BOS, stosując standardową GET_DESCRIPTORprzekaz kontroli:

bmRequestType bRequest wValue wIndex wLength Dane (odpowiedź)
0b10000000 0x06 0x0F00 0x0000 * Deskryptor BOS

Prośba ta jest zwykle wysyłana dwukrotnie: pierwszy raz z wystarczająco dużym wLength, aby host mógł poznać wartość pola wTotalLength bez angażowania dużych zasobów, a potem ponownie, gdy znana jest pełna długość deskryptora.

Jeśli w przypadku deskryptora platformy WebUSB w polu iLandingPage jest ustawiona wartość różna od zera, przeglądarka wykonuje żądanie GET_URL specyficzne dla WebUSB, przekazując transfer sterowania z wartością bRequest = bVendorCode z deskryptora platformy i wartością wValue = iLandingPage. Kod zapytania GET_URL (0x02) znajduje się w wIndex:

bmRequestType bRequest wValue wIndex wLength Dane (odpowiedź)
0b11000000 0x01 0x0001 0x0002 * Opis adresu URL

Ponownie, to żądanie może zostać wysłane dwukrotnie, aby najpierw sprawdzić długość odczytywanego opisu.

Uwagi dotyczące poszczególnych platform

Chociaż interfejs WebUSB API stara się zapewniać spójny interfejs dostępu do urządzeń USB, deweloperzy powinni być świadomi wymagań nakładanych na aplikacje, takich jak wymagania przeglądarek internetowych, aby uzyskać dostęp do urządzeń.

macOS

W przypadku macOS nie trzeba nic specjalnego robić. Witryna korzystająca z WebUSB może połączyć się z urządzeniem i zarezerwować wszystkie interfejsy, które nie są zarezerwowane przez sterownik jądra ani inną aplikację.

Linux

Linux jest podobny do macOS, ale domyślnie większość dystrybucji nie konfiguruje kont użytkowników z dostępem do urządzeń USB. Za przypisywanie użytkownika i grupy, które mają dostęp do urządzenia, odpowiada demon systemowy o nazwie udev. Takie reguły przypisują własność urządzenia dopasowanego do podanych identyfikatorów dostawcy i produktu do grupy plugdev, która jest wspólną grupą dla użytkowników z dostępem do urządzeń peryferyjnych:

SUBSYSTEM=="usb", ATTR{idVendor}=="XXXX", ATTR{idProduct}=="XXXX", GROUP="plugdev"

Zastąp XXXX szesnastkowymi identyfikatorami dostawcy i produktu urządzenia, np. ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e11" odpowiada telefonom Nexus One. Aby były prawidłowo rozpoznawane, muszą być zapisane bez zwykłego prefiksu „0x” i w pełni małymi literami. Aby znaleźć identyfikatory urządzenia, uruchom narzędzie wiersza poleceń lsusb.

Ta reguła powinna znajdować się w pliku w katalogu /etc/udev/rules.d i zacznie obowiązywać, gdy tylko podłączysz urządzenie. Nie musisz ponownie uruchamiać udev.

Android

Platforma Android opiera się na Linuksie, ale nie wymaga żadnych zmian w konfiguracji systemu. Domyślnie przeglądarka może korzystać z dowolnego urządzenia, które nie ma sterownika wbudowanego w system operacyjny. Deweloperzy powinni jednak pamiętać, że użytkownicy będą musieli wykonać dodatkowy krok podczas łączenia się z urządzeniem. Gdy użytkownik wybierze urządzenie w odpowiedzi na prośbę o dostęp, requestDevice() Android wyświetli prośbę o pozwolenie na dostęp do tego urządzenia. Ten komunikat wyświetla się też, gdy użytkownik wraca do witryny, która ma już uprawnienia do łączenia się z urządzeniem, i która wywołuje funkcję open().

Ponadto na Androidzie będzie można korzystać z większej liczby urządzeń niż na Linuksie na komputery, ponieważ domyślnie jest dołączona mniejsza liczba sterowników. Ważnym pominięciem jest np. klasa USB CDC-ACM, która jest często implementowana przez adaptery USB-RS-232, ponieważ w pakiecie Android SDK nie ma interfejsu API do komunikacji z urządzeniem RS-232.

ChromeOS

ChromeOS jest również oparty na Linuksie i nie wymaga żadnych modyfikacji konfiguracji systemu. Usługa permission_broker kontroluje dostęp do urządzeń USB i pozwala przeglądarce na dostęp do nich, o ile istnieje co najmniej 1 niewykorzystany interfejs.

Windows

Model sterownika systemu Windows wprowadza dodatkowy wymóg. W odróżnieniu od platform wymienionych powyżej możliwość otwarcia urządzenia USB z aplikacji użytkownika nie jest domyślnie dostępna, nawet jeśli nie ma załadowanego sterownika. Zamiast tego istnieje specjalny sterownik WinUSB, który musi być wczytany, aby zapewnić interfejs, którego aplikacje używają do uzyskiwania dostępu do urządzenia. Można to zrobić za pomocą niestandardowego pliku informacji o sterowniku (INF) zainstalowanego w systemie lub przez zmodyfikowanie oprogramowania sprzętowego urządzenia w celu zapewnienia opisów zgodności systemu operacyjnego Microsoft podczas enumeracji.

Plik z informacjami o sterowniku (INF)

Plik z informacjami o sterowniku mówi systemowi Windows, co ma zrobić, gdy po raz pierwszy wykryje urządzenie. Ponieważ sterownik WinUSB jest już dostępny w systemie użytkownika, wystarczy, że plik INF powiąże identyfikator dostawcy i produktu z nową regułą instalacji. Poniżej znajduje się podstawowy przykład pliku. Zapisz go w pliku z rozszerzeniem .inf, zmień sekcje oznaczone symbolem „X”, a potem kliknij prawym przyciskiem myszy i w menu kontekstowym wybierz „Zainstaluj”.

[Version]
Signature   = "$Windows NT$"
Class       = USBDevice
ClassGUID   = {88BAE032-5A81-49f0-BC3D-A4FF138216D6}
Provider    = %ManufacturerName%
CatalogFile = WinUSBInstallation.cat
DriverVer   = 09/04/2012,13.54.20.543

; ========== Manufacturer/Models sections ===========

[Manufacturer]
%ManufacturerName% = Standard,NTx86,NTia64,NTamd64

[Standard.NTx86]
%USB\MyCustomDevice.DeviceDesc% = USB_Install,USB\VID_XXXX&PID_XXXX

[Standard.NTia64]
%USB\MyCustomDevice.DeviceDesc% = USB_Install,USB\VID_XXXX&PID_XXXX

[Standard.NTamd64]
%USB\MyCustomDevice.DeviceDesc% = USB_Install,USB\VID_XXXX&PID_XXXX

; ========== Class definition ===========

[ClassInstall32]
AddReg = ClassInstall_AddReg

[ClassInstall_AddReg]
HKR,,,,%ClassName%
HKR,,NoInstallClass,,1
HKR,,IconPath,%REG_MULTI_SZ%,"%systemroot%\system32\setupapi.dll,-20"
HKR,,LowerLogoVersion,,5.2

; =================== Installation ===================

[USB_Install]
Include = winusb.inf
Needs   = WINUSB.NT

[USB_Install.Services]
Include = winusb.inf
Needs   = WINUSB.NT.Services

[USB_Install.HW]
AddReg = Dev_AddReg

[Dev_AddReg]
HKR,,DeviceInterfaceGUIDs,0x10000,"{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"

; =================== Strings ===================

[Strings]
ManufacturerName              = "Your Company Name Here"
ClassName                     = "Your Company Devices"
USB\MyCustomDevice.DeviceDesc = "Your Device Name Here"

Sekcja [Dev_AddReg] konfiguruje zestaw identyfikatorów DeviceInterfaceGUID dla urządzenia. Aby aplikacja mogła znaleźć interfejs urządzenia i połączyć się z nim za pomocą interfejsu API Windows, musi on mieć identyfikator GUID. Aby wygenerować losowy identyfikator GUID, użyj polecenia New-Guid w PowerShell lub narzędzia online.

Na potrzeby programowania narzędzie Zadig udostępnia prosty interfejs do zastępowania sterownika wczytanego dla interfejsu USB sterownikiem WinUSB.

Deskryptory zgodności systemu operacyjnego Microsoft

Powyższe podejście z użyciem pliku INF jest kłopotliwe, ponieważ wymaga wcześniejszego skonfigurowania komputera każdego użytkownika. Systemy Windows 8.1 i nowsze oferują alternatywę w postaci niestandardowych opisów USB. Te deskryptory przekazują systemowi operacyjnemu Windows informacje, które normalnie znajdują się w pliku INF, gdy urządzenie jest podłączane po raz pierwszy.

Po skonfigurowaniu opisów WebUSB możesz łatwo dodać również opisy zgodności z systemem operacyjnym Microsoft. Najpierw rozszerz opis BOS o ten dodatkowy opis możliwości platformy. Pamiętaj, aby zaktualizować wartości wTotalLength i bNumDeviceCaps.

Wartość Pole Opis
Deskryptor możliwości platformy Microsoft OS 2.0
0x1C bLength Rozmiar tego opisu
0x10 bDescriptorType Deskryptor możliwości urządzenia
0x05 bDevCapabilityType Deskryptor możliwości platformy
0x00 bReserved
{0xDF, 0x60, 0xDD, 0xD8, 0x89, 0x45, 0xC7, 0x4C, 0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F} PlatformCapablityUUID Identyfikator GUID deskryptora zgodności z platformą Microsoft OS 2.0 w formacie little-endian
0x06030000 dwWindowsVersion Minimalna zgodna wersja systemu Windows (Windows 8.1)
0x00B2 wMSOSDescriptorSetTotalLength Łączny rozmiar zestawu deskryptorów
0x02 bMS_VendorCode bRequest – wartość służąca do pobierania kolejnych deskryptorów Microsoft
0x00 bAltEnumCode Urządzenie nie obsługuje alternatywnej numeracji

Podobnie jak w przypadku deskryptorów WebUSB, musisz wybrać wartość bRequest, która będzie używana przez transfery kontrolne związane z tymi deskryptorami. W tym przykładzie wybrano 0x02. 0x07 w nawiasach kwadratowych wIndex to polecenie służące do pobrania z urządzenia zbioru opisów Microsoft OS 2.0.

bmRequestType bRequest wValue wIndex wLength Dane (odpowiedź)
0b11000000 0x02 0x0000 0x0007 * Zbiór deskryptorów MS OS 2.0

Urządzenie USB może mieć wiele funkcji, dlatego pierwsza część zestawu deskryptorów opisuje, z którą z nich powiązane są kolejne właściwości. Przykład poniżej konfiguruje interfejs 1 urządzenia złożonego. Descriptor przekazuje systemowi operacyjnemu 2 ważne informacje o tym interfejsie. Opis identyfikatora zgodności informuje system Windows, że urządzenie jest zgodne z sterownikami WinUSB. Deskryptor właściwości rejestru działa podobnie do sekcji [Dev_AddReg] w przykładzie pliku INF powyżej, ustawiając właściwość rejestru w celu przypisania tej funkcji identyfikatora GUID interfejsu urządzenia.

Wartość Pole Opis
Nagłówek zestawu deskryptorów Microsoft OS 2.0
0x000A wLength Rozmiar tego opisu
0x0000 wDescriptorType Deskryptor nagłówka zestawu deskryptorów
0x06030000 dwWindowsVersion Minimalna zgodna wersja systemu Windows (Windows 8.1)
0x00B2 wTotalLength Łączny rozmiar zestawu deskryptorów
Nagłówek podzbioru konfiguracji Microsoft OS 2.0
0x0008 wLength Rozmiar tego opisu
0x0001 wDescriptorType Opis nagłówka podzbioru konfiguracji
0x00 bConfigurationValue Ma zastosowanie do konfiguracji 1 (indeksy od 0, mimo że konfiguracje są zwykle indeksowane od 1).
0x00 bReserved Musi być ustawiona na 0
0x00A8 wTotalLength Łączna długość podzbioru, w tym nagłówka
Nagłówek podzbioru funkcji Microsoft OS 2.0
0x0008 wLength Rozmiar tego opisu
0x0002 wDescriptorType Deskryptor nagłówka podzbioru funkcji
0x01 bFirstInterface Pierwszy interfejs funkcji
0x00 bReserved Musi być ustawiona na 0
0x00A0 wSubsetLength Łączna długość podzbioru, w tym nagłówka
Opis identyfikatora zgodny z Microsoft OS 2.0
0x0014 wLength Rozmiar tego opisu
0x0003 wDescriptorType Deskryptor identyfikatora zgodności
"WINUSB\0\0" CompatibileID ciąg znaków ASCII uzupełniony do 8 bajtów
"\0\0\0\0\0\0\0\0" SubCompatibleID ciąg znaków ASCII uzupełniony do 8 bajtów
Deskryptor właściwości rejestru Microsoft OS 2.0
0x0084 wLength Rozmiar tego opisu
0x0004 wDescriptorType Deskryptor właściwości rejestru
0x0007 wPropertyDataType REG_MULTI_SZ
0x002A wPropertyNameLength Długość nazwy właściwości
"DeviceInterfaceGUIDs\0" PropertyName Nazwa usługi z znakiem końca null zakodowanym w UTF-16LE
0x0050 wPropertyDataLength Długość wartości właściwości
"{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}\0\0" PropertyData identyfikator GUID oraz 2 terminatory null zakodowane w UTF-16LE.

Windows poprosi urządzenie o te informacje tylko raz. Jeśli urządzenie nie odpowie odpowiednimi deskryptorami, nie zapyta ponownie, gdy następnym razem zostanie podłączone. Firma Microsoft udostępniła listę wpisów w rejestrze urządzeń USB, które opisują wpisy rejestru utworzone podczas liczenia urządzeń. Podczas testowania usuń wpisy utworzone dla urządzenia, aby zmusić system Windows do ponownego odczytania opisów.

Więcej informacji o sposobie korzystania z tych wskaźników znajdziesz w poście na blogu firmy Microsoft.

Przykłady

Przykładowy kod implementujący urządzenia obsługujące WebUSB, które zawierają zarówno deskryptory WebUSB, jak i deskryptory systemu operacyjnego Microsoft, można znaleźć w tych projektach: