Hello,
I've been debugging a problem with an application which checks itself for consistency before it runs. It does this extremely simply and fails in a trivial way under wine, but for the life of me I do not know how to fix it, and I would appreciate any thoughts - its not everyday I delve into the loader and server logic!
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.
This whole area has me confused now! Can anyone shed some light on how its all supposed to work please?
Thanks, Jason