การสร้างอุปกรณ์สำหรับ WebUSB

สร้างอุปกรณ์เพื่อใช้ประโยชน์จาก WebUSB API อย่างเต็มที่

Reilly Grant
Reilly Grant

บทความนี้จะอธิบายวิธีสร้างอุปกรณ์เพื่อใช้ประโยชน์จาก WebUSB API อย่างเต็มที่ สำหรับข้อมูลเบื้องต้นเกี่ยวกับ API โปรดดูเข้าถึงอุปกรณ์ USB บนเว็บ

ที่มา

Universal Serial Bus (USB) กลายเป็นอินเทอร์เฟซทางกายภาพที่ใช้กันมากที่สุดในการเชื่อมต่ออุปกรณ์ต่อพ่วงกับอุปกรณ์คอมพิวเตอร์เดสก์ท็อปและอุปกรณ์เคลื่อนที่ นอกจากการกำหนดลักษณะทางไฟฟ้าของรถบัสและรุ่นทั่วไปสำหรับการสื่อสารกับอุปกรณ์แล้ว ข้อมูลจำเพาะของ USB ยังมีชุดข้อกำหนดเฉพาะระดับอุปกรณ์ด้วย โมเดลเหล่านี้เป็นเวอร์ชันทั่วไปสำหรับอุปกรณ์บางประเภท เช่น พื้นที่เก็บข้อมูล เสียง วิดีโอ เครือข่าย และอื่นๆ ที่ผู้ผลิตอุปกรณ์สามารถนำมาใช้ได้ ข้อดีของข้อมูลจำเพาะของคลาสอุปกรณ์เหล่านี้คือ ผู้ให้บริการระบบปฏิบัติการสามารถใช้ไดรเวอร์ 1 ตัวโดยขึ้นอยู่กับข้อกำหนดของคลาส ("ไดรเวอร์คลาส") และจะมีการรองรับอุปกรณ์ที่ใช้คลาสดังกล่าว การทำเช่นนี้เป็นการปรับปรุงที่ยอดเยี่ยมกว่าผู้ผลิตทุกรายที่ต้องเขียนไดรเวอร์อุปกรณ์ของตนเอง

แต่อุปกรณ์บางเครื่องไม่เข้ากับหนึ่งในคลาสอุปกรณ์มาตรฐานเหล่านี้ ผู้ผลิตอาจเลือกติดป้ายกำกับอุปกรณ์ของตนว่าใช้คลาสเฉพาะผู้ให้บริการแทน ในกรณีนี้ ระบบปฏิบัติการจะเลือกไดรเวอร์อุปกรณ์ที่จะโหลดตามข้อมูลที่ให้ไว้ในแพ็กเกจไดรเวอร์ของผู้ให้บริการ โดยปกติแล้วจะเป็นชุดผู้ให้บริการและรหัสผลิตภัณฑ์ซึ่งเป็นที่ทราบว่าใช้โปรโตคอลเฉพาะผู้ให้บริการที่เจาะจง

ฟีเจอร์อีกอย่างของ USB คืออุปกรณ์อาจมีอินเทอร์เฟซที่หลากหลายกับโฮสต์ที่เชื่อมต่ออยู่ แต่ละอินเทอร์เฟซสามารถใช้คลาสมาตรฐานหรือจะใช้เฉพาะผู้ให้บริการก็ได้ เมื่อระบบปฏิบัติการเลือกไดรเวอร์ที่เหมาะสมในการจัดการกับอุปกรณ์ ไดรเวอร์ที่แตกต่างกันจะอ้างสิทธิ์อินเทอร์เฟซแต่ละรายการได้ เช่น เว็บแคม USB มักมีอินเทอร์เฟซ 2 แบบ แบบแรกใช้คลาสวิดีโอ USB (สำหรับกล้อง) และอีกแบบหนึ่งใช้คลาสเสียง USB (สำหรับไมโครโฟน) ระบบปฏิบัติการจะไม่โหลด "ไดรเวอร์เว็บแคม" ตัวเดียว แต่จะโหลดไดรเวอร์คลาสวิดีโอและคลาสเสียงแบบอิสระแทน ซึ่งมีหน้าที่การทำงานของอุปกรณ์แยกต่างหาก องค์ประกอบคลาสอินเทอร์เฟซนี้ให้ความยืดหยุ่นที่มากขึ้น

ข้อมูลเบื้องต้นเกี่ยวกับ API

คลาส USB มาตรฐานจำนวนมากมี API เว็บที่สอดคล้องกัน ตัวอย่างเช่น หน้าเว็บสามารถบันทึกวิดีโอจากอุปกรณ์คลาสวิดีโอโดยใช้ getUserMedia() หรือได้รับเหตุการณ์อินพุตจากอุปกรณ์คลาสของอินเทอร์เฟซมนุษย์ (HID) โดยการฟัง KeyboardEvents หรือ PointerEvents หรือใช้ Gamepad หรือ API WebHID อย่างไรก็ตาม อุปกรณ์บางรุ่นไม่มีการกำหนดคลาสที่เป็นมาตรฐาน อุปกรณ์บางรุ่นไม่มีฟีเจอร์ที่สอดคล้องกับ API ของแพลตฟอร์มเว็บที่มีอยู่ ในกรณีนี้ WebUSB API สามารถเติมเต็มช่องว่างดังกล่าวโดยให้เว็บไซต์ต่างๆ อ้างสิทธิ์อินเทอร์เฟซเฉพาะผู้ให้บริการและใช้การสนับสนุนสำหรับอินเทอร์เฟซนั้นจากภายในหน้าเว็บโดยตรง

ข้อกำหนดเฉพาะสำหรับอุปกรณ์เพื่อให้เข้าถึงผ่าน WebUSB ในแต่ละแพลตฟอร์มจะแตกต่างกันเล็กน้อยเนื่องจากระบบปฏิบัติการจัดการอุปกรณ์ USB แตกต่างกัน แต่ข้อกำหนดพื้นฐานคืออุปกรณ์ไม่ควรมีไดรเวอร์ที่อ้างสิทธิ์อินเทอร์เฟซที่หน้าเว็บต้องการควบคุมอยู่แล้ว ซึ่งอาจเป็นไดรเวอร์คลาสทั่วไปที่ผู้ให้บริการระบบปฏิบัติการมีให้ หรือไดรเวอร์อุปกรณ์ที่ผู้ให้บริการมีให้ก็ได้ เนื่องจากอุปกรณ์ USB สามารถให้อินเทอร์เฟซได้หลายแบบ ซึ่งแต่ละแบบอาจมีไดรเวอร์ของตัวเอง ดังนั้นจึงสามารถสร้างอุปกรณ์ที่ไดรเวอร์อ้างสิทธิ์อินเทอร์เฟซบางส่วน และอุปกรณ์อื่นๆ สามารถเข้าถึงได้โดยเบราว์เซอร์

เช่น แป้นพิมพ์ USB ระดับไฮเอนด์อาจมีอินเทอร์เฟซคลาส HID ซึ่งระบบจะอ้างสิทธิ์โดยระบบย่อยของระบบปฏิบัติการและอินเทอร์เฟซเฉพาะผู้ให้บริการ ซึ่งยังคงพร้อมใช้งานกับ WebUSB สำหรับให้เครื่องมือกำหนดค่าใช้งาน เครื่องมือนี้ใช้งานได้บนเว็บไซต์ของผู้ผลิต ซึ่งช่วยให้ผู้ใช้เปลี่ยนลักษณะการทํางานของอุปกรณ์ได้ เช่น มาโครคีย์และเอฟเฟกต์แสงโดยไม่ต้องติดตั้งซอฟต์แวร์เฉพาะแพลตฟอร์มใดๆ โดยข้อบ่งชี้การกำหนดค่าของอุปกรณ์จะมีลักษณะดังนี้

ค่า ฟิลด์ คำอธิบาย
ข้อบ่งชี้การกำหนดค่า
0x09 bLength ขนาดของข้อบ่งชี้นี้
0x02 bDescriptorType ข้อบ่งชี้การกำหนดค่า
0x0039 wTotalLength ความยาวรวมของชุดข้อบ่งชี้นี้
0x02 bNumInterfaces จำนวนอินเทอร์เฟซ
0x01 bConfigurationValue การกำหนดค่า 1
0x00 iConfiguration ชื่อการกําหนดค่า (ไม่มี)
0b1010000 bmAttributes อุปกรณ์แบบขับเคลื่อนด้วยตนเองพร้อมการปลุกระบบจากระยะไกล
0x32 bMaxPower กำลังสูงสุดจะแสดงทุกๆ 2 mA
ข้อบ่งชี้อินเทอร์เฟซ
0x09 bLength ขนาดของข้อบ่งชี้นี้
0x04 bDescriptorType ข้อบ่งชี้อินเทอร์เฟซ
0x00 bInterfaceNumber อินเทอร์เฟซ 0
0x00 bAlternateSetting การตั้งค่าอื่น 0 (ค่าเริ่มต้น)
0x01 bNumEndpoints 1 ปลายทาง
0x03 bInterfaceClass คลาสอินเทอร์เฟซ HID
0x01 bInterfaceSubClass คลาสย่อยอินเทอร์เฟซการเปิดเครื่อง
0x01 bInterfaceProtocol แป้นพิมพ์
0x00 iInterface ชื่ออินเทอร์เฟซ (ไม่มี)
ข้อบ่งชี้ HID
0x09 bLength ขนาดของข้อบ่งชี้นี้
0x21 bDescriptorType ข้อบ่งชี้ HID
0x0101 bcdHID HID เวอร์ชัน 1.1
0x00 bCountryCode ประเทศเป้าหมายของฮาร์ดแวร์
0x01 bNumDescriptors จำนวนข้อบ่งชี้คลาส HID ที่จะติดตาม
0x22 bDescriptorType ประเภทข้อบ่งชี้รายงาน
0x003F wDescriptorLength ความยาวรวมของข้อบ่งชี้รายงาน
ข้อบ่งชี้ปลายทาง
0x07 bLength ขนาดของข้อบ่งชี้นี้
0x05 bDescriptorType ข้อบ่งชี้ปลายทาง
0b10000001 bEndpointAddress ปลายทาง 1 (IN)
0b00000011 bmAttributes ขัดจังหวะ
0x0008 wMaxPacketSize แพ็กเก็ต 8 ไบต์
0x0A bInterval ช่วง 10 มิลลิวินาที
ข้อบ่งชี้อินเทอร์เฟซ
0x09 bLength ขนาดของข้อบ่งชี้นี้
0x04 bDescriptorType ข้อบ่งชี้อินเทอร์เฟซ
0x01 bInterfaceNumber อินเทอร์เฟซ 1
0x00 bAlternateSetting การตั้งค่าอื่น 0 (ค่าเริ่มต้น)
0x02 bNumEndpoints 2 ปลายทาง
0xFF bInterfaceClass คลาสอินเทอร์เฟซเฉพาะผู้ให้บริการ
0x00 bInterfaceSubClass
0x00 bInterfaceProtocol
0x00 iInterface ชื่ออินเทอร์เฟซ (ไม่มี)
ข้อบ่งชี้ปลายทาง
0x07 bLength ขนาดของข้อบ่งชี้นี้
0x05 bDescriptorType ข้อบ่งชี้ปลายทาง
0b10000010 bEndpointAddress ปลายทาง 1 (IN)
0b00000010 bmAttributes เป็นกลุ่ม
0x0040 wMaxPacketSize แพ็กเก็ต 64 ไบต์
0x00 bInterval ไม่มีสำหรับปลายทางจำนวนมาก
ข้อบ่งชี้ปลายทาง
0x07 bLength ขนาดของข้อบ่งชี้นี้
0x05 bDescriptorType ข้อบ่งชี้ปลายทาง
0b00000011 bEndpointAddress ปลายทาง 3 (OUT)
0b00000010 bmAttributes เป็นกลุ่ม
0x0040 wMaxPacketSize แพ็กเก็ต 64 ไบต์
0x00 bInterval ไม่มีสำหรับปลายทางจำนวนมาก

ข้อบ่งชี้การกำหนดค่าประกอบด้วยข้อบ่งชี้หลายตัวที่ต่อกัน แต่ละช่องจะเริ่มต้นด้วย bLength และ bDescriptorType เพื่อให้ระบุได้ อินเทอร์เฟซแรกคืออินเทอร์เฟซ HID ที่มีข้อบ่งชี้ HID ที่เกี่ยวข้อง และปลายทางเดียวที่ใช้ส่งเหตุการณ์อินพุตไปยังระบบปฏิบัติการ อินเทอร์เฟซที่ 2 เป็นอินเทอร์เฟซที่เจาะจงผู้ให้บริการซึ่งมีปลายทาง 2 จุดเพื่อใช้ส่งคำสั่งไปยังอุปกรณ์และรับการตอบกลับ

ข้อบ่งชี้ WebUSB

แม้ว่า WebUSB จะใช้งานได้กับอุปกรณ์มากมายโดยไม่ต้องดัดแปลงเฟิร์มแวร์ แต่คุณก็เปิดใช้ฟังก์ชันการทำงานเพิ่มเติมได้ด้วยการทำเครื่องหมายอุปกรณ์ด้วยข้อบ่งชี้เฉพาะที่บ่งชี้ว่ารองรับ WebUSB ตัวอย่างเช่น คุณระบุ URL ของหน้า Landing Page ที่เบราว์เซอร์จะนำผู้ใช้ไปได้เมื่อเสียบปลั๊กอุปกรณ์

ภาพหน้าจอของการแจ้งเตือน WebUSB ใน Chrome
การแจ้งเตือน WebUSB

อุปกรณ์ไบนารี Object Store (BOS) เป็นแนวคิดที่นำมาใช้ใน USB 3.0 แต่ยังมีการย้ายพอร์ตไปยังอุปกรณ์ USB 2.0 โดยเป็นส่วนหนึ่งของเวอร์ชัน 2.1 อีกด้วย การประกาศการรองรับ WebUSB เริ่มต้นด้วยการใส่ข้อบ่งชี้ความสามารถของแพลตฟอร์มต่อไปนี้ในข้อบ่งชี้ BOS

ค่า ฟิลด์ คำอธิบาย
ข้อบ่งชี้ที่เก็บออบเจ็กต์อุปกรณ์ไบนารี
0x05 bLength ขนาดของข้อบ่งชี้นี้
0x0F bDescriptorType ข้อบ่งชี้ที่เก็บออบเจ็กต์อุปกรณ์ไบนารี
0x001D wTotalLength ความยาวรวมของชุดข้อบ่งชี้นี้
0x01 bNumDeviceCaps จำนวนข้อบ่งชี้ความสามารถของอุปกรณ์ใน BOS
ข้อบ่งชี้ความสามารถของแพลตฟอร์ม WebUSB
0x18 bLength ขนาดของข้อบ่งชี้นี้
0x10 bDescriptorType ข้อบ่งชี้ความสามารถของอุปกรณ์
0x05 bDevCapabilityType ข้อบ่งชี้ความสามารถของแพลตฟอร์ม
0x00 bReserved
{0x38, 0xB6, 0x08, 0x34, 0xA9, 0x09, 0xA0, 0x47, 0x8B, 0xFD, 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65} PlatformCapablityUUID GUID ของข้อบ่งชี้ความสามารถของแพลตฟอร์ม WebUSB ในรูปแบบ Little End
0x0100 bcdVersion WebUSB ข้อบ่งชี้ เวอร์ชัน 1.0
0x01 bVendorCode ค่า bRequest สำหรับ WebUSB
0x01 iLandingPage URL สำหรับหน้า Landing Page

UUID ความสามารถของแพลตฟอร์มจะระบุว่าเป็นข้อบ่งชี้ความสามารถของแพลตฟอร์ม WebUSB ซึ่งให้ข้อมูลพื้นฐานเกี่ยวกับอุปกรณ์ หากต้องการให้เบราว์เซอร์ดึงข้อมูลเพิ่มเติมเกี่ยวกับอุปกรณ์ เบราว์เซอร์จะใช้ค่า bVendorCode ในการออกคำขอเพิ่มเติมไปยังอุปกรณ์ คำขอเดียวที่ระบุอยู่ในปัจจุบันคือ GET_URL ซึ่งแสดงผล ข้อบ่งชี้ URL ซึ่งคล้ายกับข้อบ่งชี้สตริง แต่ออกแบบมาเพื่อเข้ารหัส URL ในจำนวนไบต์น้อยที่สุด โดยข้อบ่งชี้ URL สำหรับ "https://google.com" จะมีลักษณะดังนี้

ค่า ฟิลด์ คำอธิบาย
ข้อบ่งชี้ URL
0x0D bLength ขนาดของข้อบ่งชี้นี้
0x03 bDescriptorType ข้อบ่งชี้ URL
0x01 bScheme https://
"google.com" URL เนื้อหา URL ที่เข้ารหัสแบบ UTF-8

เมื่อเสียบอุปกรณ์ในเบราว์เซอร์เป็นครั้งแรก จะอ่านข้อบ่งชี้ BOS ด้วยการออกการโอนการควบคุม GET_DESCRIPTOR แบบมาตรฐานนี้

bmRequestType bRequest wValue wIndex wLength ข้อมูล (คำตอบ)
0b10000000 0x06 0x0F00 0x0000 * ข้อบ่งชี้ BOS

คำขอนี้มักจะทำ 2 ครั้ง โดยครั้งแรกจะมี wLength ที่มากพอ เพื่อให้โฮสต์พบค่าของช่อง wTotalLength โดยไม่ต้องทำการโอนจำนวนมาก จากนั้นจะทำอีกครั้งเมื่อทราบความยาวของข้อบ่งชี้ทั้งหมดแล้ว

หากข้อบ่งชี้ความสามารถของแพลตฟอร์ม WebUSB ตั้งค่าช่อง iLandingPage เป็นค่าที่ไม่ใช่ 0 เบราว์เซอร์จะส่งคำขอ GET_URL สำหรับ WebUSB โดยเฉพาะด้วยการออกการโอนการควบคุมโดยตั้งค่า bRequest เป็นค่า bVendorCode จากข้อบ่งชี้ความสามารถของแพลตฟอร์มและตั้งค่า wValue เป็นค่า iLandingPage รหัสคำขอสำหรับ GET_URL (0x02) จะเข้าสู่ wIndex:

bmRequestType bRequest wValue wIndex wLength ข้อมูล (คำตอบ)
0b11000000 0x01 0x0001 0x0002 * ข้อบ่งชี้ URL

ขอย้ำอีกครั้งว่าอาจมีการออกคำขอนี้ 2 ครั้งเพื่อการตรวจสอบครั้งแรกสำหรับความยาวของข้อบ่งชี้ที่อ่านอยู่

ข้อควรพิจารณาเฉพาะแพลตฟอร์ม

แม้ว่า WebUSB API จะพยายามมอบอินเทอร์เฟซที่สอดคล้องกันสำหรับการเข้าถึงอุปกรณ์ USB นักพัฒนาซอฟต์แวร์ก็ควรตระหนักถึงข้อกำหนดที่บังคับใช้กับแอปพลิเคชันต่างๆ เช่น ข้อกำหนดของเว็บเบราว์เซอร์เพื่อเข้าถึงอุปกรณ์

macOS

ไม่จำเป็นต้องใช้อะไรเป็นพิเศษสำหรับ macOS เว็บไซต์ที่ใช้ WebUSB สามารถเชื่อมต่อกับอุปกรณ์และอ้างสิทธิ์อินเทอร์เฟซใดๆ ที่ไม่ได้อ้างสิทธิ์โดยไดรเวอร์ Kernel หรือแอปพลิเคชันอื่น

Linux

Linux ก็เหมือนกับ macOS แต่โดยค่าเริ่มต้นแล้ว Linux ส่วนใหญ่จะไม่ได้ตั้งค่าบัญชีผู้ใช้ที่มีสิทธิ์เปิดอุปกรณ์ USB Daemon ของระบบที่เรียกว่า udev มีหน้าที่ในการกำหนดผู้ใช้และกลุ่มที่อนุญาตให้เข้าถึงอุปกรณ์ กฎเช่นนี้จะมอบหมายการเป็นเจ้าของอุปกรณ์ที่ตรงกับผู้ให้บริการและรหัสผลิตภัณฑ์ที่กำหนดกับกลุ่ม plugdev ซึ่งเป็นกลุ่มทั่วไปสำหรับผู้ใช้ที่มีสิทธิ์เข้าถึงอุปกรณ์ต่อพ่วง

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

แทนที่ XXXX ด้วยผู้ให้บริการเลขฐาน 16 และรหัสผลิตภัณฑ์สำหรับอุปกรณ์ของคุณ เช่น ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e11" จะตรงกับโทรศัพท์ Nexus One ค่าเหล่านี้ต้องเขียนโดยไม่มี "0x" นำหน้า และตัวพิมพ์เล็กทั้งหมดจึงจะเข้าใจได้อย่างถูกต้อง หากต้องการค้นหารหัสของอุปกรณ์ ให้เรียกใช้เครื่องมือ บรรทัดคำสั่ง lsusb

ควรวางกฎนี้ไว้ในไฟล์ในไดเรกทอรี /etc/udev/rules.d และจะมีผลทันทีที่เสียบปลั๊กอุปกรณ์ คุณไม่จำเป็นต้องรีสตาร์ท udev

Android

แพลตฟอร์ม Android ทำงานบน Linux แต่ไม่จำเป็นต้องแก้ไขการกำหนดค่าของระบบ ตามค่าเริ่มต้นแล้ว อุปกรณ์ที่ไม่มีไดรเวอร์ในระบบปฏิบัติการจะสามารถใช้งานได้บนเบราว์เซอร์ อย่างไรก็ตาม นักพัฒนาซอฟต์แวร์ควรทราบแต่ว่าผู้ใช้จะพบขั้นตอนเพิ่มเติมเมื่อเชื่อมต่อกับอุปกรณ์ เมื่อผู้ใช้เลือกอุปกรณ์เพื่อตอบสนองต่อการเรียก requestDevice() Android จะแสดงข้อความแจ้งเพื่อถามว่าจะอนุญาตให้ Chrome เข้าถึงได้หรือไม่ ข้อความแจ้งนี้จะปรากฏขึ้นอีกครั้งหากผู้ใช้กลับไปยังเว็บไซต์ที่มีสิทธิ์เชื่อมต่ออุปกรณ์อยู่แล้วและเว็บไซต์เรียกใช้ open()

นอกจากนี้ อุปกรณ์ต่างๆ จะเข้าถึงได้ใน Android มากกว่า Linux บนเดสก์ท็อป เนื่องจากโดยค่าเริ่มต้นแล้วจะมีไดรเวอร์น้อยกว่า ความแตกต่างที่เห็นได้ชัดคือคลาส USB CDC-ACM ที่มักติดตั้งใช้งานโดยอะแดปเตอร์แปลง USB เป็นซีเรียล เนื่องจาก Android SDK ไม่มี API สำหรับสื่อสารกับอุปกรณ์ซีเรียล

ChromeOS

ChromeOS ก็ทำงานบน Linux เช่นกัน และไม่จำเป็นต้องแก้ไขการกำหนดค่าของระบบ บริการ permission_broker ควบคุมการเข้าถึงอุปกรณ์ USB และจะอนุญาตให้เบราว์เซอร์เข้าถึงได้ตราบใดที่มีอินเทอร์เฟซที่ไม่มีการอ้างสิทธิ์อย่างน้อย 1 รายการ

Windows

ไดรเวอร์ของรุ่น Windows มีข้อกำหนดเพิ่มเติม ความสามารถในการเปิดอุปกรณ์ USB จากแอปพลิเคชันของผู้ใช้จะแตกต่างจากแพลตฟอร์มอื่นๆ ที่เป็นค่าเริ่มต้น แม้จะไม่มีการโหลดไดรเวอร์ก็ตาม แต่จะต้องมีไดรเวอร์พิเศษ WinUSB ที่ต้องโหลดเพื่อให้แอปพลิเคชันอินเทอร์เฟซใช้ในการเข้าถึงอุปกรณ์ ซึ่งทำได้ด้วยไฟล์ข้อมูลไดรเวอร์ที่กำหนดเอง (INF) ที่ติดตั้งอยู่ในระบบ หรือโดยการแก้ไขเฟิร์มแวร์ของอุปกรณ์เพื่อระบุข้อบ่งชี้ความเข้ากันได้กับ Microsoft OS ในระหว่างการแจกแจง

ไฟล์ข้อมูลผู้ขับ (INF)

ไฟล์ข้อมูลไดรเวอร์จะบอก Windows ถึงสิ่งที่ต้องทำเมื่อพบอุปกรณ์เป็นครั้งแรก เนื่องจากระบบของผู้ใช้มีไดรเวอร์ WinUSB อยู่แล้ว สิ่งที่จำเป็นต้องใช้ก็คือให้ไฟล์ INF เชื่อมโยงผู้ให้บริการและรหัสผลิตภัณฑ์กับกฎการติดตั้งใหม่นี้ ไฟล์ด้านล่างเป็นตัวอย่างเบื้องต้น บันทึกไฟล์ลงในไฟล์ที่มีส่วนขยาย .inf เปลี่ยนส่วนที่มีเครื่องหมาย "X" จากนั้นคลิกขวาที่ส่วน แล้วเลือก "ติดตั้ง" จากเมนูบริบท

[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"

ส่วน [Dev_AddReg] จะกำหนดค่าชุด DeviceInterfaceGUID สำหรับอุปกรณ์ อินเทอร์เฟซอุปกรณ์ทุกเครื่องต้องมี GUID เพื่อให้แอปพลิเคชันค้นหาและเชื่อมต่อกับแอปพลิเคชันผ่าน Windows API ได้ ใช้ PowerShell cmdlet ของ New-Guid หรือเครื่องมือออนไลน์เพื่อสร้าง GUID แบบสุ่ม

เครื่องมือ Zadig มีอินเทอร์เฟซที่ใช้งานง่ายสำหรับแทนที่ไดรเวอร์ที่โหลดสำหรับอินเทอร์เฟซ USB ด้วยไดรเวอร์ WinUSB เพื่อจุดประสงค์ในการพัฒนา

ข้อบ่งชี้ความเข้ากันได้กับ Microsoft OS

ไฟล์ INF ข้างต้นค่อนข้างยุ่งยากเนื่องจากต้องกำหนดค่าเครื่องของผู้ใช้ทุกเครื่องล่วงหน้า Windows 8.1 ขึ้นไปจะมีทางเลือก ในการใช้ตัวบ่งชี้ USB ที่กำหนดเอง โดยข้อบ่งชี้เหล่านี้จะให้ข้อมูลแก่ระบบปฏิบัติการ Windows เมื่อเสียบปลั๊กอุปกรณ์เป็นครั้งแรก ซึ่งโดยปกติแล้วจะรวมอยู่ในไฟล์ INF

เมื่อตั้งค่าข้อบ่งชี้ WebUSB แล้ว คุณสามารถเพิ่มข้อบ่งชี้ความเข้ากันได้กับระบบปฏิบัติการของ Microsoft ได้ง่ายๆ ก่อนอื่นให้ขยายข้อบ่งชี้ BOS ด้วยข้อบ่งชี้ความสามารถของแพลตฟอร์มเพิ่มเติมนี้ อย่าลืมอัปเดต wTotalLength และ bNumDeviceCaps ให้สอดคล้องกับการเปลี่ยนแปลงนี้

ค่า ฟิลด์ คำอธิบาย
ข้อบ่งชี้ความสามารถของแพลตฟอร์ม Microsoft OS 2.0
0x1C bLength ขนาดของข้อบ่งชี้นี้
0x10 bDescriptorType ข้อบ่งชี้ความสามารถของอุปกรณ์
0x05 bDevCapabilityType ข้อบ่งชี้ความสามารถของแพลตฟอร์ม
0x00 bReserved
{0xDF, 0x60, 0xDD, 0xD8, 0x89, 0x45, 0xC7, 0x4C, 0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F} PlatformCapablityUUID GUID ของข้อบ่งชี้ความเข้ากันได้ของแพลตฟอร์ม Microsoft OS 2.0 ในรูปแบบ Little-endian
0x06030000 dwWindowsVersion เวอร์ชันต่ำสุดที่เข้ากันได้ของ Windows (Windows 8.1)
0x00B2 wMSOSDescriptorSetTotalLength ความยาวรวมของชุดข้อบ่งชี้
0x02 bMS_VendorCode ค่า bRequest สำหรับการเรียกข้อมูลข้อบ่งชี้ Microsoft เพิ่มเติม
0x00 bAltEnumCode อุปกรณ์ไม่รองรับการแจงนับสำรอง

เช่นเดียวกับข้อบ่งชี้ WebUSB คุณต้องเลือกค่า bRequest ที่จะใช้ในการโอนการควบคุมที่เกี่ยวข้องกับข้อบ่งชี้เหล่านี้ ในตัวอย่างนี้ ผมเลือก 0x02 0x07 ที่อยู่ในส่วน wIndex คือคำสั่งสำหรับเรียกชุดข้อบ่งชี้ Microsoft OS 2.0 จากอุปกรณ์

bmRequestType bRequest wValue wIndex wLength ข้อมูล (คำตอบ)
0b11000000 0x02 0x0000 0x0007 * ชุดข้อบ่งชี้ MS OS 2.0

อุปกรณ์ USB สามารถมีได้หลายฟังก์ชัน ดังนั้นส่วนแรกของชุดตัวบ่งชี้จะอธิบายถึงฟังก์ชันที่พร็อพเพอร์ตี้ต่อไปนี้เชื่อมโยงอยู่ ตัวอย่างด้านล่างกำหนดค่าอินเทอร์เฟซ 1 ของอุปกรณ์ผสม โดยข้อบ่งชี้จะให้ข้อมูลที่สำคัญ 2 อย่างเกี่ยวกับอินเทอร์เฟซนี้สำหรับระบบปฏิบัติการ โดยข้อบ่งชี้รหัสที่เข้ากันได้จะบอก Windows ว่าอุปกรณ์นี้เข้ากันได้กับไดรเวอร์ WinUSB ข้อบ่งชี้พร็อพเพอร์ตี้รีจิสทรีทำงานคล้ายกับส่วน [Dev_AddReg] ของตัวอย่าง INF ด้านบน โดยตั้งค่าพร็อพเพอร์ตี้รีจิสทรีเพื่อกำหนด GUID อินเทอร์เฟซอุปกรณ์ให้กับฟังก์ชันนี้

ค่า ฟิลด์ คำอธิบาย
ส่วนหัวชุดข้อบ่งชี้ Microsoft OS 2.0
0x000A wLength ขนาดของข้อบ่งชี้นี้
0x0000 wDescriptorType ข้อบ่งชี้ส่วนหัวของชุดข้อบ่งชี้
0x06030000 dwWindowsVersion เวอร์ชันต่ำสุดที่เข้ากันได้ของ Windows (Windows 8.1)
0x00B2 wTotalLength ความยาวรวมของชุดข้อบ่งชี้
ส่วนหัวย่อยของการกำหนดค่า Microsoft OS 2.0
0x0008 wLength ขนาดของข้อบ่งชี้นี้
0x0001 wDescriptorType คำอธิบายส่วนหัวของชุดย่อยการกำหนดค่า
0x00 bConfigurationValue ใช้กับการกําหนดค่า 1 (จัดทําดัชนีจาก 0 แม้ว่าจะมีการจัดทำดัชนีการกำหนดค่าตามปกติจาก 1)
0x00 bReserved ต้องตั้งค่าเป็น 0
0x00A8 wTotalLength ความยาวรวมของเซ็ตย่อยรวมถึงส่วนหัวนี้
ส่วนหัวย่อยของฟังก์ชัน Microsoft OS 2.0
0x0008 wLength ขนาดของข้อบ่งชี้นี้
0x0002 wDescriptorType ข้อบ่งชี้ส่วนหัวของฟังก์ชันย่อย
0x01 bFirstInterface อินเทอร์เฟซแรกของฟังก์ชัน
0x00 bReserved ต้องตั้งค่าเป็น 0
0x00A0 wSubsetLength ความยาวรวมของเซ็ตย่อยรวมถึงส่วนหัวนี้
ข้อบ่งชี้รหัสที่เข้ากันได้กับ Microsoft OS 2.0
0x0014 wLength ขนาดของข้อบ่งชี้นี้
0x0003 wDescriptorType ข้อบ่งชี้รหัสที่เข้ากันได้
"WINUSB\0\0" CompatibileID เพิ่มสตริง ASCII ไว้ที่ 8 ไบต์แล้ว
"\0\0\0\0\0\0\0\0" SubCompatibleID เพิ่มสตริง ASCII ไว้ที่ 8 ไบต์แล้ว
ข้อบ่งชี้พร็อพเพอร์ตี้รีจิสทรีของ Microsoft OS 2.0
0x0084 wLength ขนาดของข้อบ่งชี้นี้
0x0004 wDescriptorType ข้อบ่งชี้พร็อพเพอร์ตี้รีจิสทรี
0x0007 wPropertyDataType REG_MULTI_SZ
0x002A wPropertyNameLength ความยาวของชื่อพร็อพเพอร์ตี้
"DeviceInterfaceGUIDs\0" PropertyName ชื่อพร็อพเพอร์ตี้ที่มีตัวระบุค่า Null ซึ่งเข้ารหัสเป็น UTF-16LE
0x0050 wPropertyDataLength ความยาวของค่าพร็อพเพอร์ตี้
"{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}\0\0" PropertyData GUID บวกตัวระบุค่า Null 2 รายการที่เข้ารหัสในรูปแบบ UTF-16LE

Windows จะค้นหาข้อมูลนี้ในอุปกรณ์เพียงครั้งเดียว หากอุปกรณ์ไม่ตอบสนองด้วยข้อบ่งชี้ที่ถูกต้อง อุปกรณ์จะไม่ถามอีกในครั้งต่อไปที่เชื่อมต่ออุปกรณ์ Microsoft ได้ให้รายการ USB Device Registry ที่อธิบายรายการรีจิสทรีที่สร้างขึ้นเมื่อแจกแจงอุปกรณ์ เมื่อทดสอบ ให้ลบรายการที่สร้างขึ้นสำหรับอุปกรณ์เพื่อให้ Windows พยายามอ่านข้อบ่งชี้อีกครั้ง

ดูข้อมูลเพิ่มเติมได้ที่บล็อกโพสต์ของ Microsoft เกี่ยวกับวิธีใช้ข้อบ่งชี้เหล่านี้

ตัวอย่าง

ตัวอย่างโค้ดที่ใช้อุปกรณ์ที่รับรู้ถึง WebUSB ซึ่งมีทั้งข้อบ่งชี้ WebUSB และข้อบ่งชี้ Microsoft OS จะอยู่ในโปรเจ็กต์ต่อไปนี้