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

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

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

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

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

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

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

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

วิธีการไฟล์ 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 อยู่ในโปรเจ็กต์เหล่านี้