There is no standard user-mode interface for accessing USB hardware - there is no equivalent of Linux's libusb on Windows
But there is, just that most vendors don't use it.
(there is apparently some user-space USB stuff in mingw's headers, but I couldn't find any official docs on it, and it's not enough to write a user-space driver because there is no bulk/interrupt/isochronous pipe support, so I doubt anybody actually uses it). There is only kernel-mode interfaces for talking to USB - and different kernel mode drivers will export different user-mode interfaces (if any).
So user-space software uses a kernel-mode driver. If that driver is documented, like USBSCAN.SYS and USBPRINT.SYS, its interface can be done in wine, and wine can be connected to USB in a number of ways (which I'll discuss later). If that driver is undocumented, either you have to document it by reverse-engineering (very hard) and continue with the first way, or (the second way:) make wine's not-yet-existing NTOSKRNL.EXE load that driver, *and* provide NTOSKRNL.EXE with all the USB interfaces that Windows has.
CONNECTING WINE TO USB: A HOW-TO GUIDE
There is 4 ways to do it:
- Make a kernel module in your OS (eg. a Linux kernel module) that
exports the same interface that the software expects and works the same way as the Windows driver. Using USBSCAN.SYS as an example, reading does a USB bulk read, writing does a USB bulk write, and 13 or so i/o control codes do various other things, among them USB control and interrupt tranfers. Change kernel32's CreateFileW() to open the /dev device node used by the kernel module and send it to the wine server using wine_server_fd_to_handle(), then reading and writing will go to your kernel module, where you can implement them by doing USB reads and writes. Change ntdll's file.c's NtDeviceIoControlFile to capture i/o control codes used by your device, call wine_server_handle_to_fd(), and do an ioctl() on that fd to send that i/o control call to the kernel module, which then reacts appropriately. This way has been tested by me, it works and it's fast, but it's non-portable (eg. Linux-only, and Linux's USB interface keep changing so an out-of-tree module will only work on some versions, the usual problems...), difficult (kernel-mode code is hard to write), and generally a royal PITA.
- Like (1) but use a framework like FUSD (the xiph.org version works
on 2.6 kernels) to write the driver in user-space and then do USB I/O using libusb. I'm currently testing this approach, I suspect it's slow (how significantly remains to be seen), but at least it's more portable between Linux versions and easier to write and maintain.
- Integrate your device into wine directly the way eg. serial ports
have been done. This is hard, and requires introducing a new FD_TYPE, changing ntdll's file.c's NtReadFile, NtWriteFile, and NtDeviceIoControlFile (and asynchronous versions of those) to use special behavior for that FD_TYPE, and managing global device state (eg. i/o timeouts) in wineserver (look at server/serial.c). With a lot of time, and some changes to both wine and libusb, you could get it to work properly. This should IMO only be done for generally useful drivers, not drivers for just 1 type of device.
- Integrate NTOSKRNL.EXE into wine, add USB infrastructure to
NTOSKRNL.EXE so that kernel-mode drivers can access USB (probably through libusb), and modify ntdll to forward the appropriate reads, writes, and i/o control requests to NTOSKRNL.EXE so that the .SYS file can handle them. This is the only way that works with .SYS files out-of-the-box, the others all require a rewrite of the .SYS driver's functionality. Architecturally, this is the best way, you wouldn't need to change any code in wine to add a new driver.
Way 4 is probably the best and I hope it works at some stage, but it's still a long way off seeing as how NTOSKRNL.EXE itself still isn't in wine.
In the mean time, looks like I have some reading to do regarding USB spec, dbus and hal :-)
There is only 1 or 2 chapters you need from the USB spec. DBus is just an RPC framework, and HAL just lists devices and their properties, so they won't help much.
Thanks for the help so far.
Regards, Jono
Damjan