5/11/2016

Czur scanner, thoughts on device drivers

The Czur scanner (model ET16) is very intersting hardware. But I've long thought it would be much more interesting with an SDK "Software Development Kit" which basically shows you how to access the hardware through software on various operating systems. Since one is not available at this time from the manufacturer of the hardware. I've been looking at creating one by examining the hardware and software.

First, the Czur scanner can be used in one of three modes: HDMI live mode, PC scan mode, WiFi scan mode. These are not their official names, but serve as a convenient naming convention for the purposes of this blog post.

HDMI live mode and PC scan mode share a commonality in that they are invoked by the hardware depending on which cable is attached to the scanner. An HDMI cable causes the scanner to begin HDMI live mode. A USB cable causes the scanner to begin PC scan mode.

WiFi scan mode is the default mode when there is no cable attached to the scanner.

Obviously the only mode that makes sense for creating a software development kit, would be the PC scan mode.

As a USB device attached to a PC it must conform to the USB specifications, which are an object model view such that any USB device connected to a PC must offer up [device, interface and endpoints - with directions] The default device and interface can be queried using a standard request to determine information about the other device and interfaces, replies coming back as "descriptors" which can be though of as simple information strings.

So the first step is that a tool like usbview (part of the windows device driver kit) can be used to simply "view" the descriptors for all of the available devices, interfaces and endpoints that the hardware provides.

Windows uses this information to decide when a USB device is connected [which] device driver in its current inventory should be loaded into memory and executed to create software interfaces the operating system can use or expose for other application programs to use.

Windows has a long history, but in the past it had a signed device driver process where an INF file matched to the information in a USB descriptor and could either load a generic device driver, or a manufacturers specific custom device driver. The registation process was arduous and required optional WHQL certification and purchasing and maintaining a Software Signing Key and infrastructure which could cost thousands of dollars. With Vista and Windows 7 the signing became non-optional and "enforced" and difficult to defeat.

This was presented as a way to address quality standards and then as a way to prevent malware masquerading as drivers from compromising the operating system kernel. Poor documentation and few concrete examples of the process led to a high barrier of entry for causal programmers, custom home user written software and arguably jumpstarted a massive counter culture software revolution.

In any event a descriptor initated method of invoking a truly universal and generic WinUSB device driver and new USBClass of device driver came about and was backported to support even Windows XP.. as well as Windows 7, 8 and 10. The result of which is that the simpler way of looking at USB as a bus with raw access to the native methods of communicating with a device over the USB bus emerged.

Instead of looking at each hardware device on a USB port as a unique and standalone island, the WinUSB approach sees them as peers or equals on a single wired bus. The downside being WinUSB does not support the USB communications protocol or "type" called Isynchronous communications until after Windows 8.1 and logically only one process or program can communicate with a hardware device at a time.. overlapping or multithreaded communications with a single WinUSB supported device are not supported. (that is "shared, simultaneous" access to a single hardware device is not supported within the "kernel space" API) But these are usually not a detractor for the people who would actually use WinUSB.

Usually normal individuals are less concerned with theorectically supporting simultaneous "Time-Share" of a USB printer in a office scenario for example.. over the "simple" use case of printing a document to their personal printer at home. These strange, weird, obscure flights of fantasy are common on the windows platforms.

Concurrently efforts were being made in the Opensource world to address the lack of good documentation and examples in how to access USB devices on Linux, Mac OSX and Windows through efforts like USBdk and Libusbx and finally the re-unified and current Libusb projects.

Libusb is good across old operating system like XP up through Windows 10 and across platforms from Linux, OSX and Windows. And it does support the USB communications "type" of Isynchronous communications.

But it is a judgement call to decide which is more expedient to use, probably depending on the targeted platforms, versions of those platforms and likely software developer platform tools.. and their familarity with the patterns of development they are familiar.

Setting the choice aside, WinUSB or Libusb

There is still determining what the commands and usage model are for the hardware device.

USB is an open standard and it is relatively easy to insert a USB filter driver or device driver "bridge" for inspecting and collecting "copies" of the commands and response from the hardware as they fly back and forth across the USB bus within the Windows operating system.

We don't have to understand or write any of the low level details with regards to managing the USB bus, choosing a device driver or inserting it to handle traffic for a specific hardware device. Its easy enough to use tools to simply make sure the WinUSB or Libusb kernel device driver is forceably loaded and attached to the Czur scanner.

Determining the communications commands and protocol for setting up and initating a scan capture and retrival of an image would be the most challenging. But with things like USBSnoopy, USBRobot or more sophisticated tools this is almost trivial.

After that it remains to figure out.. how to present this.. as an add-on or standalone tool on each type of operating system? As a generic SDK kit? And how would this be used in a custom work flow.. assuming people use it rather than invest time in "learning" existing software that was good enough after a bit of study.

This is not meant as a tutorial.. just some thoughts.