Dear wine developers,
I monitor from time to time Wine development state. I have significant interrest to use it for our open-source chromatography processing and control system CHROMuLAN http://pikron.com/pages/products/hplc/chromulan.html . It runs well under wine for years except for minor problem with excessive size of new analysis setup dialog, it is old Delphi 6 app. If somebody is willing to look at it I give more information or setup issue.
But uLAN driver access is required to control real devices and acquire data
Driver is available in source form from 1996 year and it has been developed and is maintained on GNU/Linux system but with CHROMuLAN windows build from the same sources is used from Windows NT 3.5 days.
I have idea in 2013 year to try implement proxy driver which allows to access native Linux kernel driver from Windows application. I have found at that time that Wine protocol is able to deliver data between wine server driver and application only for IOCTLs, read and write calls has not been implemented for device driver file handle type and I have documented problem on WineHQ list
https://www.winehq.org/pipermail/wine-devel/2013-July/thread.html#100409
But when I looked into latest Wine sources I have noticed, that it should not be problem anymore. So I have cleaned from the dust old experiment and updated it for actual Wine. Linux driver interaction has been separated from WDM proxy part and marked (ul_l_drv.c)
#if 0 #pragma makedep unix #endif
unix calls conversion has been added (ul_l_exports.c)
const unixlib_entry_t __wine_unix_call_funcs[] =
and real WDM has been used as base for the proxy driver (ul_drv.c, device.c). Both originally based on some Wine driver to emulate disk and other behavior. The code is available there
https://cmp.felk.cvut.cz/~pisa/ulan/wine/ul_drv.sys/
and it works with whole CHROMuLAN system. Yes, there is lot of space for cleanups, service is started in manual mode unconditionally etc..
[System\CurrentControlSet\Services\ul_drv] 1658091793 ... "Start"=dword:00000001
etc... There is one missing feature and it is wait for arrival of the new messages without periodic polling. It is easy on Linux side, select, poll, epoll can be used for ready for read.
In Windows world select does not work for device drivers so IOCTL is used which marks IoMarkIrpPending, then user can wait for associated overlapped event for example by WaitForSingleObject.
I have implemented logic in Wine proxy driver and IRP is marked by IoMarkIrpPending, cancellation and all other stuff seems to work. But I need somehow bind event on Linux native file descriptor which is maintained in makedep unix with some way to mark corresponding IRP in Windows driver part as complete
IoCompleteRequest(old_irp,IO_NO_INCREMENT);
What are the options? Should, can I can start service thread in makedep unix part and call IoCompleteRequest from there? In the fact I would prefer even more only register callback in the Wise server main loop which would be called when Linux device file descriptor is ready to read. Is there some example how to do something like that? What are locking requirements and limitations?
It is more for curiosity now, we experimental port to FPC/Lazarus which runs on Linux and Windows now, but on the other hand there are still some features missing in that build, Lazarus with Gtk does not implement MDI in really usable form etc... So there is still some potential for this and other applications using uLAN to be run under Wine.
Thanks for your time and best wishes,
Pavel
On 7/19/22 02:48, Pavel Pisa wrote:
What are the options? Should, can I can start service thread in makedep unix part and call IoCompleteRequest from there? In the fact I would prefer even more only register callback in the Wise server main loop which would be called when Linux device file descriptor is ready to read. Is there some example how to do something like that? What are locking requirements and limitations?
Probably, although it's a bit more awkward than that.
I don't think there are locking limitations besides what win32 imposes; the unix call transition doesn't require or perform any locking.
What *is* relevant, though, are two restrictions:
* You can't call almost all win32 functions from a POSIX thread (basically, anything that needs to access the TEB, because there isn't one. Since that includes Wine debug logging, that's pretty much everything.) That means that you probably want to start a thread on the win32 side rather than the unix side, and possibly have it call into a unixlib "main loop" sort of function.
* You can't directly call PE code from a unix library. This includes both Win32 functions like IoCompleteRequest, and also user-defined callbacks. [Note that anything starting with Nt* and exported from ntdll is okay, though.]
This does make IRP handling more annoying. winebus (which does HID I/O) can deal with this by wrapping poll() in a unixlib function which is then called in a loop; wineusb is less lucky and has to deal with libusb callbacks, so it uses an event queue. Without having looked at your requirements, it's probable you'll want to use one of these architectures.
ἔρρωσο, Zeb