http://bugs.winehq.org/show_bug.cgi?id=21751
Summary: Wine locks the initial executable Product: Wine Version: 1.1.38 Platform: x86 OS/Version: Linux Status: NEW Severity: normal Priority: P2 Component: -unknown AssignedTo: wine-bugs@winehq.org ReportedBy: us@edmeades.me.uk
When wine first loads the main executable it leaves a 'shared read' lock against the executable. A (deliberatly unnamed) application I was debugging does a consistency check by opening itself using SHARE_NONE in the CreateFile API. This works on windows but fails under wine. I've cut the problem down to a simple testcase, where test (1) shows the failure.
The problem is I (a) dont know how to fix it and (b) cant add tests to wine itself for it as it has to be a native executable (as thats where the bug lies).
I reported it on wine-devel: -------------------------------------------------------- I have cut this down to a 2 line test program, which basically fails because a native executable called eg. test.exe subsequently calls CreateFile(".\test.exe", GENERIC_READ, 0 /* no share*/ - ie it's opening itself for read access and non-shared access. It suffers a sharing violation on wine whereas it works fine on windows
Diagnosing the wine side, we are in trouble here - the act of loading a module ends up in load_dll which call find_dll_file which in turn calls NtOpenFile for GENERIC_READ access. This returns a file handle which is then used to create the in memory file mapping for the executable code, and the handle returned from the NtOpenFile is then closed.
However, when we come along to the application code and try the open we end up checking the sharing and there are 3 things on the inode->open chain: The original open, with access of read The mapping, with access of mapping The open in progress (which is ignored for sharing checks) which does not want to SHARE_READ,and hence the sharing violation occurs. For reference we are failing in the 3rd (last) case of check_sharing returning STATUS_SHARING_VIOLATION, ie existing access if for read purposes, but the requested sharing doesnt allow this.
What I dont understand is why the NtClose for the handle does not remove it from the 'open' list - I think from my reading of the fd_destroy code it will put it onto the closed list if there are other references to the same inode, although thats where my debugging will head next. --------------------------------------------------------
Alexander replied:
Loading a dll keeps a reference to the file object, because it needs to be returned in debug events. Probably it would be possible to reference the mapping object instead and reopen the file from it.
--------------------------------------------------------
I've got stuck and am out of my depth so leaving this for someone as a bug report.