Tworzenie urządzenia na potrzeby WebUSB

Stwórz urządzenie, aby w pełni wykorzystać możliwości 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ą pamięci USB jest to, że urządzenia mogą udostępniać wiele interfejsów do hosta, 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 ma zwykle 2 interfejsy: jeden implementujący klasę wideo USB (dla kamery), a drugi (dla mikrofonu) – klasę audio USB. 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. Taka kompozycja klas interfejsu zapewnia większą elastyczność.

Podstawy interfejsu API

Wiele standardowych klas USB ma odpowiednie interfejsy API. 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 mieć interfejs klasy HID, do którego będzie stosowany podsystem wejściowy systemu operacyjnego, a interfejs specyficzny dla dostawcy, który pozostaje 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 uruchamiania
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 specyficzny dla dostawcy interfejs z 2 punktami końcowymi, które mogą służyć 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, na którą przeglądarka może przekierowywać użytkownika po podłączeniu urządzenia do zasilania.

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ć następujący 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 funkcji platformy WebUSB w formacie little-endian
0x0100 bcdVersion Deskryptor WebUSB w wersji 1.0
0x01 bVendorCode bWartość żądania dla WebUSB
0x01 iLandingPage URL strony docelowej

Identyfikator UUID funkcji platformy określa to jako deskryptor funkcji 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 zostały zaprojektowane do kodowania adresów URL w najmniejszej liczbie bajtów. Deskryptor adresu URL "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

Po pierwszym podłączeniu urządzenia przeglądarka odczytuje deskryptor BOS, wysyłając standardowy element sterujący GET_DESCRIPTOR:

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

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

Jeśli w pole iLandingPage w opisie możliwości platformy WebUSB wpisana jest wartość różna od zera, przeglądarka wykonuje żądanie GET_URL specyficzne dla WebUSB, przekazując transfer sterowania z polem bRequest ustawionym na wartość bVendorCode z opisu możliwości platformy i polem wValue ustawionym na wartość 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ść odczytanego 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 przypisanie użytkownika i grupy uprawnień do urządzenia odpowiada demon udev. Takie reguły przypisują własność urządzenia dopasowanego do danego identyfikatora dostawcy i identyfikatora 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 komputerach z systemem Linux, ponieważ domyślnie jest dołączona mniejsza liczba sterowników. Istotnym pominięciem jest na przykład klasa USB CDC-ACM często wdrażana przez adaptery USB-seryjne, ponieważ w pakiecie Android SDK nie ma interfejsu API umożliwiającego komunikowanie się z urządzeniem szeregowym.

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ść otwierania 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 zostać załadowany, 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 informacji o sterowniku informuje system Windows, co zrobić, gdy urządzenie po raz pierwszy zetknie się z urządzeniem. 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. Plik poniżej to podstawowy przykład. 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 urządzenia. Każdy interfejs urządzenia musi mieć identyfikator GUID, aby aplikacja mogła go znaleźć i połączyć się z nim za pomocą interfejsu API systemu Windows. Aby wygenerować losowy identyfikator GUID, użyj polecenia New-Guid w PowerShell lub narzędzia online.

W celu ułatwienia procesu tworzenia narzędzia 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 wykorzystaniem 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ć też opisy zgodności z systemem operacyjnym Microsoft. Najpierw dodaj deskryptor BOS o ten dodatkowy deskryptor możliwości platformy. Aby to uwzględnić, zaktualizuj 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ść 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. Zgodny deskryptor identyfikatora informuje system Windows, że to urządzenie jest zgodne ze sterownikiem 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 deskryptora
0x0000 wDescriptorType Deskryptor zestawu deskryptorów
0x06030000 dwWindowsVersion Minimalna zgodna wersja Windows (Windows 8.1)
0x00B2 wTotalLength Łączny rozmiar zestawu deskryptorów
Nagłówek podzbioru konfiguracji systemu Microsoft OS 2.0
0x0008 wLength Rozmiar tego deskryptora
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 Wartość musi wynosić 0
0x00A8 wTotalLength Łączna długość podzbioru, w tym tego nagłówka
Nagłówek podzbioru funkcji Microsoft OS 2.0
0x0008 wLength Rozmiar tego deskryptora
0x0002 wDescriptorType Deskryptor nagłówka podzbioru funkcji
0x01 bFirstInterface Pierwszy interfejs funkcji
0x00 bReserved Musi być ustawiona na 0
0x00A0 wSubsetLength Całkowita długość podzbioru razem z tym nagłówkiem
Opis identyfikatora zgodny z Microsoft OS 2.0
0x0014 wLength Rozmiar tego deskryptora
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 deskryptora
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ą te wpisy utworzone przy wyliczaniu urządzenia. Podczas testowania usuń wpisy utworzone dla urządzenia, aby zmusić system Windows do ponownego odczytania deskryptorów.

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

Przykłady

W tych projektach znajdziesz przykładowy kod implementujący urządzenia zgodne z WebUSB, który zawiera zarówno deskryptory WebUSB, jak i deskryptory systemu operacyjnego Microsoft: