USB device support in wine
kuba at mareimbrium.org
Fri May 4 06:43:00 CDT 2007
> 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:
> 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
> > 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
More information about the wine-devel