Utwórz urządzenie, by w pełni wykorzystać możliwości WebUSB API.
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.
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: