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

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

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

ข้อมูลเบื้องต้น

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

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

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

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

คลาส USB มาตรฐานหลายคลาสมี Web API ที่สอดคล้องกัน ตัวอย่างเช่น หน้าเว็บสามารถจับภาพวิดีโอจากอุปกรณ์คลาสวิดีโอได้โดยใช้ getUserMedia() หรือรับเหตุการณ์อินพุตจากอุปกรณ์คลาสอินเทอร์เฟซที่โต้ตอบกับมนุษย์ (HID) โดยการฟัง KeyboardEvents หรือ PointerEvents หรือใช้ Gamepad หรือ WebHID API เช่นเดียวกับอุปกรณ์บางประเภทที่ใช้คำจำกัดความคลาสมาตรฐาน ไม่ใช่อุปกรณ์บางเครื่องเท่านั้นที่ใช้ฟีเจอร์ที่สอดคล้องกับ 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

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

ค่า ช่อง คำอธิบาย
ข้อบ่งชี้ที่เก็บออบเจ็กต์ของอุปกรณ์แบบไบนารี
0x05 bLength ขนาดของข้อบ่งชี้นี้
0x0F bDescriptorType ข้อบ่งชี้ Object Store ของอุปกรณ์ไบนารี
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-endian
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 สามารถเชื่อมต่อกับอุปกรณ์และอ้างสิทธิ์อินเทอร์เฟซที่ไม่ได้อ้างสิทธิ์โดยไดรเวอร์เคอร์เนลหรือแอปพลิเคชันอื่น

Linux

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

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

แทนที่ XXXX ด้วยผู้ให้บริการฐานสิบหกและรหัสผลิตภัณฑ์สำหรับอุปกรณ์ของคุณ เช่น 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 เป็นอนุกรม เนื่องจากไม่มี API ใน Android SDK สําหรับการสื่อสารกับอุปกรณ์ซีเรียล

ChromeOS

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

Windows

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

ไฟล์ข้อมูลไดรเวอร์ (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 ได้ ใช้ New-Guid PowerShell cmdlet หรือเครื่องมือออนไลน์เพื่อสร้าง 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 ซึ่งอธิบายรายการรีจิสทรีที่สร้างเมื่อระบุอุปกรณ์ เมื่อทดสอบ ให้ลบรายการที่สร้างสำหรับอุปกรณ์เพื่อบังคับให้ Windows พยายามอ่านตัวบ่งชี้อีกครั้ง

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

ตัวอย่าง

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