On 03/15/2019 01:19 PM, Jacek Caban wrote:
On 3/15/19 5:50 PM, Zebediah Figura wrote:
On 03/15/2019 09:58 AM, Jacek Caban wrote:
Long term, we may consider making interface between server and device manager more generic so that it could be used for messages other than IRPs.
Signed-off-by: Jacek Caban jacek@codeweavers.com
dlls/ntoskrnl.exe/ntoskrnl.c | 14 +++++++++++++- server/device.c | 15 +++++++++++++++ server/protocol.def | 6 ++++++ 3 files changed, 34 insertions(+), 1 deletion(-)
Sorry if this is a dumb question, but why do we need this (and then, by extension, the whole infrastructure involving server changes)?
Generally speaking, it's meant to allow kernel objects implementation. The main part in my consideration was ObReferenceObjectByHandle. Although we could have more hacks around it without server support, there are limitations to what's possible to hack. If we want to return exactly the same object for given actual object (implemented usually in server in Wine case), we need server involved in handle to object mapping.
Once we have that, there is another problem with object life time. Driver may release its reference to the object, but an other process may still have open handles. On Windows, those handles would keep object reference count of the object, but on Wine that count is in server, not ntoskrnl.exe. It means that only server knows when the object is actually destroyed. If we don't want to leak in ntoskrnl.exe, we need some mechanism to be notified about object being freed.
Also such kernel object reflecting a server object may be used as an argument for other functions, like KeSetEvent. Unlike events initialized with KeInitializeEvent, we don't have much control over such event. MRAC does that: it creates an event, passes it by handle in ioctl(), driver uses ObReferenceObjectByHandle and then KeSetEvent on this even. So we need a way to implement such functions on top of kernel object pointers. I tried storing handles on client side, but it had more problems as I noted in [1]. Instead, we may just get a handle whenever we need them and that's all we need to implement KeSetEvent on top of NtSetEvent.
Thanks, it was IRP_MJ_CLOSE that I had not considered. I guess there's indeed no way to hold a reference without handle, without introducing server changes.