On 5/4/07, Jon Burgess jkburges@gmail.com wrote:
I have found some talk of implementing USB device support in wine in
this
list some time ago (2005), but as far as I know, nothing ever came of
it.
I would perhaps be interested in getting this going again, as I have an application (Serato Scratch Live: http://www.rane.com/scratch.html) for which the
software
appears to run ok under wine (not that I am able to test much of its functionality on the other hand), but is utterly useless without support
for
its associated USB hardware device.
Any ideas, or anyone else who would be interested in helping me?
Does the software come with a .SYS file?
yes: the is a directory .../Serato/Drivers/ containing "MP4Usb.sys" and "MP4Usb.inf", although I seem to remember reading somewhere that the MP4 driver is for another Serato product (not Scratch live).
It probably doesn't refer to the MP4 music format.
That website doesn't much, please post lsusb -v output.
Bus 004 Device 002: ID 13e5:0001 Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.00 bDeviceClass 255 Vendor Specific Class bDeviceSubClass 255 Vendor Specific Subclass bDeviceProtocol 255 Vendor Specific Protocol
This there is no "standard" driver for your USB device (like for example there is just 1 driver for all USB flash disks, because they're all in the same device class). You have the use the vendor-supplied .SYS file.
Will it work on wine right now? Not even remotely. Will it ever? Read on...
There is no standard user-mode interface for accessing USB hardware - there is no equivalent of Linux's libusb on Windows (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:
1. 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.
2. 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.
3. 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.
4. 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