2

I have a proprietary USB device that has a flashing functionality over USB. I would like to replicate this flashing functionality from within the browser, but I am not certain what API to use.

Visiting chrome://usb-internals/ to inspect my device gives me the following information:

Description of USB device: class code 8, mass storage device

The device advertises itself with class code 8: mass storage. The device does not show up in my file system, e.g. it is not a normal USB pendrive. According to this StackOverflow answer, WebUSB is blocked from accessing mass storage devices due to security reasons, and I should use WebHID instead.

Using WebHID, however, still did not allow me to connect to my device. This is the sample code I used:

const filter = [
  {
    vendorId: 0xabcd, // correct VID:PID obtained via lsusb
    productId: 0x1234
  }
];

const [device] = await navigator.hid.requestDevice({ filter });

Furthermore, visiting chrome://device-log/ makes a distinct difference between USB and HID devices. When I plug in a mouse, for example, the Chrome device log shows that a USB HID device connected. When I plug in a USB pendrive, I get two lines in the debug log: one HID device, one mass storage device. When I plug in my proprietary drive, I get a single line: USB Mass Storage device.

How could I convince WebHID to make a connection to my proprietary mass storage device?

2 Answers2

1

Not possible without major changes:

USB mss storage uses bulk endpoints, HID is transferred via Control and Interrupt end points.

You can implement both Mass storage and HID on a single USB device (with an IAD), but the bootloader code for HID would look significantly different from the mass storage one.

USB pendrives don't usually support HID unless there is an LED or button present.

Turbo J
  • 7,563
  • 1
  • 23
  • 43
  • Does that mean that there does not exist an API in Google Chrome that could interface with this device? With WebDFU, WebUSB, WebHID, WebSerial, WebBluetooth, this seems like such a weird oversight from Google. This device does not get claimed by my actual operating system, it is not a normal file system. It merely uses bulk transfers to transfer data from a proprietary flasher. – Maurits van Altvorst Jul 11 '21 at 15:33
  • That is even worse from a security point of view. Being able to to access raw SCSI layer could brick the hardware, set Host protected area or issue a secure erase of the data. You really don't want a browser app to be able to do that... – Turbo J Jul 12 '21 at 07:48
  • Since the device advertises itself as a USB Mass Storage device Chrome has to assume that it actually is one. I don't know why the operating system doesn't recognizing it as a storage device. Maybe it does recognize it as a storage device but it doesn't have a supported file system. If it did then you could use the [File System Access API](https://web.dev/file-system-access/) to write files to it. Unfortunately there are limits to what we can do to support "unusual" devices without violating the security properties we've built into the design. – Reilly Grant Jul 12 '21 at 18:08
1

You could install a WinUSB driver for the device (Zadig makes it very easy) and then connect to the device using WebUSB.

In case you need to write your own SCSI layer, here's how we did it for a blood glucose meter that also mounts as a mass storage device to transfer data.

Gerrit
  • 852
  • 1
  • 9
  • 15
  • If the device only provides a USB Mass Storage interface then that interface will be blocked by WebUSB. – Reilly Grant Jul 12 '21 at 18:04
  • @ReillyGrant Is it not possible to replace the existing driver with a WinUSB driver for that interface? – Gerrit Jul 13 '21 at 19:54
  • Replacing the driver doesn't change the interface class. – Reilly Grant Jul 14 '21 at 17:24
  • That's unfortunate. Is there some kind of allowlist that we can apply for, as there seems to be a number of devices that use block mode access that won't be feasible with the File System Access API? – Gerrit Jul 20 '21 at 12:54
  • @ReillyGrant Looking at https://bugs.chromium.org/p/chromium/issues/detail?id=1056757 it appears that it will be possible to override the interface blocklist with an enterprise policy in future? – Gerrit Aug 04 '21 at 10:13
  • Hi @Gerrit , you know how connect my scanner via webusb or you know about libraries ? javascript, I have this when connect `endpoints: Array(4) 0: USBEndpoint {endpointNumber: 2, direction: 'in', type: 'bulk', packetSize: 512} 1: USBEndpoint {endpointNumber: 4, direction: 'in', type: 'bulk', packetSize: 512} 2: USBEndpoint {endpointNumber: 6, direction: 'in', type: 'bulk', packetSize: 512} 3: USBEndpoint {endpointNumber: 8, direction: 'out', type: 'bulk', packetSize: 512}` – Carlos Feb 10 '22 at 16:56