Tworzenie urządzenia na potrzeby WebUSB

Utwórz urządzenie, by w pełni wykorzystać możliwości WebUSB API.

Reilly Grant
Reilly Grant

Z tego artykułu dowiesz się, jak utworzyć urządzenie, by w pełni wykorzystać możliwości WebUSB API. Krótkie omówienie interfejsu API znajdziesz w artykule Dostęp do urządzeń USB w internecie.

Wprowadzenie

Uniwersalna magistrala szeregowa (USB) stała się najpopularniejszym interfejsem fizycznym służącym do podłączania urządzeń peryferyjnych do komputerów i urządzeń mobilnych. Oprócz określenia właściwości elektrycznych magistrali i ogólnego modelu komunikacji z urządzeniem specyfikacja USB obejmuje zestaw specyfikacji klasy urządzenia. Są to ogólne modele dla określonych klas urządzeń, takich jak pamięć masowa, audio, wideo, sieciowe itp., które mogą wdrożyć producenci urządzeń. Zaletą tych specyfikacji klas urządzenia jest to, że dostawca systemu operacyjnego może wdrożyć 1 sterownik na podstawie specyfikacji klasy („sterownik klasy”) i obsługiwane będzie każde urządzenie, w którym ta klasa jest obsługiwana. To znacznie lepsze rozwiązanie niż każdy producent musiał pisać własne sterowniki urządzenia.

Niektóre urządzenia nie należą jednak do żadnej z tych ustandaryzowanych klas urządzeń. Zamiast tego producent może oznaczyć swoje urządzenie jako implementujące klasę danego dostawcy. W takim przypadku system operacyjny wybiera sterownik urządzenia do załadowania na podstawie informacji podanych w pakiecie sterownika dostawcy. Zwykle jest to zestaw identyfikatorów dostawcy i produktu, o których wiadomo, że implementują określony protokół dla konkretnego dostawcy.

Inną cechą USB jest to, że urządzenia mogą mieć wiele interfejsów z hostem, do którego są podłączone. Każdy interfejs może implementować ustandaryzowaną klasę lub być specyficzną dla dostawcy. Po wybraniu przez system operacyjny odpowiednich sterowników do obsługi urządzenia każdy interfejs może zostać zarezerwowany przez innego sterownika. Na przykład kamera internetowa USB ma zwykle dwa interfejsy: jeden z klasą wideo USB (do obsługi kamery), a drugi – z klasą audio USB (dla mikrofonu). System operacyjny nie wczytuje pojedynczego „sterownika kamery internetowej”, ale wczytuje niezależne sterowniki klas wideo i audio, które odpowiadają za oddzielne funkcje urządzenia. Taki układ klas interfejsu zapewnia większą elastyczność.

Podstawowe informacje o interfejsie API

Wiele standardowych klas USB ma odpowiadające im internetowe interfejsy API. Strona może na przykład przechwytywać film z urządzenia klasy wideo za pomocą getUserMedia() lub otrzymywać zdarzenia wejściowe z urządzenia klasy HID przez nasłuchiwanie zdarzeń KeyboardEvents lub PointerEvents albo za pomocą interfejsu Gamepad lub interfejsu API WebHID. Nie wszystkie urządzenia mają ustandaryzowaną definicję klas, tak samo jak nie wszystkie urządzenia mają funkcje odpowiadające istniejącym interfejsom API platform internetowych. W takim przypadku interfejs WebUSB API może wypełnić tę lukę, umożliwiając witrynom zgłoszenie prawa do interfejsu określonego dostawcy i wdrożenie jego obsługi bezpośrednio na stronie.

Konkretne wymagania dotyczące dostępności urządzenia przez WebUSB różnią się w zależności od platformy ze względu na różnice w sposobie zarządzania urządzeniami USB przez systemy operacyjne. Podstawowym wymogiem jest to, aby urządzenie nie miało już sterownika deklarującego interfejs, którym strona ma sterować. Może to być ogólny sterownik klasy udostępniany przez dostawcę systemu operacyjnego lub sterownik urządzenia udostępniony przez dostawcę. Urządzenia USB mogą mieć wiele interfejsów, z których każdy może mieć własny sterownik. Możesz więc zbudować urządzenie, na którym niektóre interfejsy są zarezerwowane przez sterownik, a pozostałe – dostępne dla przeglądarki.

Na przykład klawiatura wysokiej klasy USB może oferować interfejs klasy HID, do którego podsystem operacyjny systemu operacyjnego ma dostęp, oraz interfejs specyficzny dla danego dostawcy, który pozostaje dostępny dla WebUSB do użytku przez narzędzie konfiguracyjne. Narzędzie to można udostępnić na stronie producenta, co pozwoli użytkownikowi zmieniać aspekty działania urządzenia, np. klawisze makro czy efekty świetlne, bez konieczności instalowania dodatkowego oprogramowania przeznaczonego na daną platformę. Deskryptor konfiguracji urządzenia wyglądałby tak:

Wartość Pole Opis
Deskryptor konfiguracji
0x09 bLength Rozmiar tego deskryptora
0x02 bDescriptorType Deskryptor konfiguracji
0x0039 wTotalLength Całkowita długość tej serii deskryptorów
0x02 bNumInterfaces Liczba interfejsów
0x01 bConfigurationValue Configuration 1
0x00 iConfiguration Nazwa konfiguracji (brak)
0b1010000 bmAttributes Urządzenie własne ze zdalnym wybudzaniem
0x32 bMaxPower Maksymalna moc jest wyrażona w przyrostach co 2 mA
Deskryptor interfejsu
0x09 bLength Rozmiar tego deskryptora
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 rozruchowego
0x01 bInterfaceProtocol Klawiatura
0x00 iInterface Nazwa interfejsu (brak)
Deskryptor HID
0x09 bLength Rozmiar tego deskryptora
0x21 bDescriptorType Deskryptor HID
0x0101 bcdHID HID w wersji 1.1
0x00 bCountryCode Kraj docelowy sprzętu
0x01 bNumDescriptors Liczba deskryptorów klas HID do śledzenia
0x22 bDescriptorType Typ deskryptora raportu
0x003F wDescriptorLength Całkowita długość deskryptora raportu
Deskryptor punktu końcowego
0x07 bLength Rozmiar tego deskryptora
0x05 bDescriptorType Deskryptor punktu końcowego
0b10000001 bEndpointAddress Punkt końcowy 1 (IN)
0b00000011 bmAttributes Przerwij
0x0008 wMaxPacketSize Pakiety 8-bajtowe
0x0A bInterval Odstęp 10 ms
Deskryptor interfejsu
0x09 bLength Rozmiar tego deskryptora
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 dla konkretnego dostawcy
0x00 bInterfaceSubClass
0x00 bInterfaceProtocol
0x00 iInterface Nazwa interfejsu (brak)
Deskryptor punktu końcowego
0x07 bLength Rozmiar tego deskryptora
0x05 bDescriptorType Deskryptor punktu końcowego
0b10000010 bEndpointAddress Punkt końcowy 1 (IN)
0b00000010 bmAttributes Sprzedaż hurtowa
0x0040 wMaxPacketSize Pakiety 64-bajtowe
0x00 bInterval Nie dotyczy zbiorczych punktów końcowych
Deskryptor punktu końcowego
0x07 bLength Rozmiar tego deskryptora
0x05 bDescriptorType Deskryptor punktu końcowego
0b00000011 bEndpointAddress Punkt końcowy 3 (OUT)
0b00000010 bmAttributes Sprzedaż hurtowa
0x0040 wMaxPacketSize Pakiety 64-bajtowe
0x00 bInterval Nie dotyczy zbiorczych punktów końcowych

Deskryptor konfiguracji składa się z wielu połączonych ze sobą deskryptorów. Każdy zaczyna się od pól bLength i bDescriptorType, aby można je było zidentyfikować. Pierwszy interfejs to interfejs HID z powiązanym deskryptorem HID i pojedynczym punktem końcowym służącym do dostarczania zdarzeń wejściowych do systemu operacyjnego. Drugi interfejs to specyficzny dla dostawcy interfejs z 2 punktami końcowymi, które można wykorzystać do wysyłania poleceń na urządzenie i odbierania odpowiedzi.

Deskryptory WebUSB

WebUSB może działać z wieloma urządzeniami bez wprowadzania modyfikacji w oprogramowaniu, ale włączenie dodatkowych funkcji jest możliwe przez oznaczenie urządzenia określonymi deskryptorami wskazującymi na obsługę WebUSB. Możesz np. podać URL strony docelowej, na którą przeglądarka może skierować użytkownika, gdy zostanie podłączone do urządzenia.

Zrzut ekranu z powiadomieniem WebUSB w Chrome
Powiadomienie WebUSB.

Pojęcie „BOS Object Store” (magazyn obiektów binarnych) to pojęcie wprowadzone w USB 3.0, ale w wersji 2.1 zostało też przeniesione wstecznie do urządzeń ze złączem USB 2.0. Deklaracja obsługi WebUSB zaczyna się od umieszczenia w deskryptorze BOS tego deskryptora możliwości platformy:

Wartość Pole Opis
Deskryptor magazynu obiektów urządzeń binarnych
0x05 bLength Rozmiar tego deskryptora
0x0F bDescriptorType Deskryptor magazynu obiektów urządzeń binarnych
0x001D wTotalLength Całkowita długość tej serii deskryptorów
0x01 bNumDeviceCaps Liczba deskryptorów możliwości urządzenia w BOS
Deskryptor możliwości platformy WebUSB
0x18 bLength Rozmiar tego deskryptora
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 platformy WebUSB w formacie little-endian
0x0100 bcdVersion Deskryptor WebUSB w wersji 1.0
0x01 bVendorCode Wartość bRequest dla WebUSB
0x01 iLandingPage URL strony docelowej

Identyfikator UUID funkcji platformy identyfikuje go jako deskryptor funkcji platformy WebUSB, który dostarcza podstawowe informacje o urządzeniu. Aby przeglądarka mogła pobrać więcej informacji o urządzeniu, używa wartości bVendorCode do wysyłania dodatkowych żądań do urządzenia. Obecnie określone jest tylko żądanie GET_URL, które zwraca deskryptor adresu URL. Są one podobne do deskryptorów ciągów znaków, ale są przeznaczone do kodowania adresów URL w jak najmniejszej liczbie bajtów. Deskryptor adresu URL "https://google.com" wyglądałby tak:

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

Przy pierwszym podłączeniu urządzenia przeglądarka odczytuje deskryptor BOS, uruchamiając standardowy transfer sterowania GET_DESCRIPTOR:

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

To żądanie jest zwykle wysyłane dwukrotnie. Za pierwszym razem z wystarczającą dużą wartością wLength, aby host znalazł wartość pola wTotalLength bez konieczności przeprowadzenia dużego transferu. Potem ponownie, gdy pełna długość deskryptora jest znana.

Jeśli deskryptor funkcji WebUSB ma w polu iLandingPage wartość inną niż 0, przeglądarka wykonuje żądanie GET_URL związane z WebUSB, przesyłając żądanie kontroli z parametrem bRequest ustawionym na wartość bVendorCode z deskryptora możliwości platformy, a wValue na wartość iLandingPage. Kod żądania dla użytkownika GET_URL (0x02) należy wpisać w wIndex:

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

Żądanie to może być wysyłane dwukrotnie, aby w pierwszej kolejności sprawdzić długość odczytywanego deskryptora.

Uwagi na temat platformy

WebUSB API stara się zapewnić spójny interfejs do uzyskiwania dostępu do urządzeń USB, ale deweloperzy powinni znać wymagania związane z dostępem do urządzeń, takie jak wymagania dotyczące przeglądarek.

macOS

W systemie macOS nie trzeba nic specjalnego. Witryna korzystająca z WebUSB może połączyć się z urządzeniem i zgłosić prawa do interfejsów, które nie są zarezerwowane przez sterownik jądra ani inną aplikację.

Linux

Linux jest jak macOS, ale domyślnie większość dystrybucji nie konfiguruje kont użytkowników z uprawnieniami do otwierania urządzeń USB. Demon systemowy o nazwie udev odpowiada za przypisanie użytkowników i grup mających dostęp do urządzenia. Taka reguła przypisze własność urządzenia pasującego do podanych identyfikatorów dostawcy i produktu do grupy plugdev, która jest wspólną grupą użytkowników z dostępem do urządzeń peryferyjnych:

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

Zastąp XXXX szesnastkowym identyfikatorem dostawcy i produktu Twojego urządzenia, np. ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e11" pasuje do telefonu Nexus One. Muszą one być napisane bez zwykłego prefiksu „0x”, a małe litery powinny być prawidłowo rozpoznane. Aby znaleźć identyfikatory urządzenia, uruchom narzędzie wiersza poleceń lsusb.

Tę regułę należy umieścić w pliku w katalogu /etc/udev/rules.d. Zaczną obowiązywać, gdy tylko urządzenie zostanie podłączone. Nie trzeba ponownie uruchamiać udev.

Android

Platforma Android działa w oparciu o Linuksa, ale nie wymaga żadnych zmian w konfiguracji systemu. Domyślnie przeglądarka ma dostęp do każdego urządzenia bez wbudowanego sterownika systemu operacyjnego. Deweloperzy powinni pamiętać, że podczas łączenia się z urządzeniem użytkownicy będą musieli wykonać dodatkową czynność. Gdy użytkownik wybierze urządzenie w odpowiedzi na wywołanie metody requestDevice(), Android wyświetli pytanie, czy zezwolić Chrome na dostęp do niego. Ten komunikat pojawi się też ponownie, gdy użytkownik wróci na stronę, która ma już uprawnienia do łączenia się z urządzeniem, a witryna wywoła metodę open().

Ponadto na urządzeniach z Androidem dostępnych jest więcej urządzeń niż na komputerach z systemem Linux, ponieważ domyślnie jest dostępnych mniej sterowników. Istotnym ominięciem jest na przykład klasa USB CDC-ACM często implementowana za pomocą przejściówek USB na USB, ponieważ w pakiecie Android SDK nie ma interfejsu API do komunikacji z urządzeniem szeregowym.

ChromeOS

ChromeOS działa w oparciu o Linuksa i nie wymaga modyfikacji konfiguracji systemu. Usługa IAM_broker kontroluje dostęp do urządzeń USB i umożliwia przeglądarce dostęp do nich, o ile istnieje co najmniej jeden niezarezerwowany interfejs.

Windows

Model sterownika Windows wprowadza dodatkowe wymaganie. W przeciwieństwie do platform, które oferują powyżej możliwość otwierania urządzenia USB z poziomu aplikacji użytkownika, nie są domyślne, nawet jeśli nie załadowano sterownika. Zamiast tego jest specjalny sterownik o nazwie WinUSB, który należy załadować, aby udostępnić interfejs, z którego aplikacje korzystają do uzyskiwania dostępu do urządzenia. Aby to zrobić, użyj niestandardowego pliku informacji o sterowniku (INF) zainstalowanego w systemie lub modyfikując oprogramowanie urządzenia, tak by podczas obliczeń podawać deskryptory zgodności systemu operacyjnego Microsoft.

Plik INF (Driver Information File)

Plik z informacjami o kierowcy informuje system Windows, co zrobić, gdy po raz pierwszy napotkasz urządzenie. System użytkownika zawiera już sterownik WinUSB. Wystarczy, że plik INF będzie wiązać dostawcę i identyfikator produktu z nową regułą instalacji. Poniższy plik to podstawowy przykład. Zapisz go w pliku z rozszerzeniem .inf, zmień sekcje oznaczone symbolem „X”, kliknij go prawym przyciskiem myszy i z menu kontekstowego 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. Każdy interfejs urządzenia musi mieć identyfikator GUID, aby aplikacja mogła go znaleźć i połączyć się z nim przez interfejs Windows API. Użyj polecenia cmdlet New-Guid PowerShell lub narzędzia online, aby wygenerować losowy identyfikator GUID.

Do celów programistycznych narzędzie Zadig udostępnia prosty interfejs umożliwiający zastąpienie sterownika USB wczytanego sterownika WinUSB.

Deskryptory zgodności z systemem operacyjnym Microsoft

Powyższe podejście do pliku INF jest uciążliwe, ponieważ wymaga wcześniejszego skonfigurowania komputera każdego użytkownika. Windows 8.1 i nowsze wersje oferują alternatywę przez zastosowanie niestandardowych deskryptorów USB. Te deskryptory przekazują do systemu operacyjnego Windows informacje, które zwykle znajdują się w pliku INF przy pierwszym podłączeniu urządzenia.

Po skonfigurowaniu deskryptorów WebUSB możesz też łatwo dodać deskryptory zgodności systemu operacyjnego Microsoft. Zacznij od rozszerzenia deskryptora 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 deskryptora
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 platformy Microsoft OS 2.0 w formacie little-endian
0x06030000 dwWindowsVersion Najmniejsza zgodna wersja systemu Windows (Windows 8.1)
0x00B2 wMSOSDescriptorSetTotalLength Całkowita długość zestawu deskryptora
0x02 bMS_VendorCode Wartość bRequest umożliwiająca pobranie kolejnych deskryptorów Microsoft
0x00 bAltEnumCode Urządzenie nie obsługuje alternatywnego wyliczenia

Podobnie jak w przypadku deskryptorów WebUSB, musisz wybrać wartość bRequest, która będzie używana przez przenoszenie kontroli związanych z tymi deskryptorami. W tym przykładzie jest to 0x02. 0x07 umieszczana w wIndex to polecenie pobierające zestaw deskryptorów systemu Microsoft OS 2.0 z urządzenia.

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

Urządzenie USB może mieć wiele funkcji, więc pierwsza część deskryptora opisuje funkcję, z którą powiązane są poniższe właściwości. W przykładzie poniżej skonfigurowano interfejs 1 urządzenia złożonego. Deskryptor zawiera 2 ważne informacje o interfejsie systemu operacyjnego. Zgodny deskryptor identyfikatora informuje system Windows, że urządzenie jest zgodne ze sterownikiem WinUSB. Deskryptor właściwości rejestru działa podobnie do sekcji [Dev_AddReg] w przykładzie powyżej INF, ustawiając właściwość rejestru, która przypisze tej funkcji identyfikator GUID interfejsu urządzenia.

Wartość Pole Opis
Nagłówek zestawu deskryptora systemu Microsoft OS 2.0
0x000A wLength Rozmiar tego deskryptora
0x0000 wDescriptorType Deskryptor nagłówka zestawu deskryptorów
0x06030000 dwWindowsVersion Najmniejsza zgodna wersja systemu Windows (Windows 8.1)
0x00B2 wTotalLength Całkowita długość zestawu deskryptora
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 (zindeksowano od 0 pomimo konfiguracji, które zwykle są indeksowane od 1)
0x00 bReserved Wartość musi mieć wartość 0.
0x00A8 wTotalLength Całkowita długość podzbioru włącznie z tym nagłówkiem
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 Wartość musi mieć wartość 0.
0x00A0 wSubsetLength Całkowita długość podzbioru włącznie z tym nagłówkiem
Deskryptor identyfikatora zgodny z systemem Microsoft OS 2.0
0x0014 wLength Rozmiar tego deskryptora
0x0003 wDescriptorType Zgodny deskryptor identyfikatora
"WINUSB\0\0" CompatibileID Ciąg ASCII dopełniony do 8 bajtów
"\0\0\0\0\0\0\0\0" SubCompatibleID Ciąg ASCII dopeł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 właściwości z zakończeniem o wartości null zakodowanym w formacie UTF-16LE
0x0050 wPropertyDataLength Długość wartości właściwości
"{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}\0\0" PropertyData Identyfikator GUID oraz dwa puste terminatory zakodowane w UTF-16LE

Windows wyśle do urządzenia zapytanie o te informacje tylko raz. Jeśli urządzenie nie odpowiada z prawidłowymi deskryptorami, nie będzie pytać ponownie przy następnym połączeniu. Firma Microsoft udostępniła listę wpisów w rejestrze urządzeń USB opisujących wpisy rejestru utworzone podczas numerowania urządzenia. Podczas testowania usuń wpisy utworzone dla urządzenia, aby zmusić system Windows do ponownej próby odczytu deskryptorów.

Więcej informacji o korzystaniu z tych deskryptorów znajdziesz w poście na blogu Microsoftu.

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: