Hello,
The Problem:
There is a bug in MoveFileExA (files/file.c). MoveFileExA will (usually)
call rename() in libc to move a file. Unfortunately, this causes
problems because it does not update the sharing table. I will illustrate
with an example.
When the Office intaller tries to install Internet Explorer it sees that the file:
C:\Windows\System\UrlMon.dll
exists and moves it to:
C:\Windows\System\IE4Setup\UrlMon.dll
it then tries to create the file
C:\Windows\System\UrlMon.dll
but fails because of a "sharing violation". It believes
that a file already exists at c:\window\systems\urlmon.dll, because,
according to the shared table, one does. But on the disk, the file has
been moved.
The Half-a-fix:
It seems odd to me that MoveFileExA is directly renaming the file. The
other functions in the same file do their dirty work via wineserver. Does
it seem reasonable that I should have to add a new wineserver request
for "MoveFile" that will rename the file and update the share table? Or
am I missing something obvious?
Also of note:
I do not think this has been a "problem" until some recent changes in
MoveFileExA where these lines were removed:
/* check, if we are allowed to delete the source */
hFile = CreateFileA(full_name1.long_name, 0, 0, NULL,OPEN_EXISTING,0,0);
if(hFile == INVALID_HANDLE_VALUE) return FALSE;
CloseHandle(hFile);
If a file was being shared, this code would prevent it from being moved.
So, perhaps that was the right fix? Maybe you can't move a file that is
being "shared"? If that is the case, there does not seem to be code
in place anymore to prevent you from moving a shared filed.
Thanks for you help! I will send a patch in, as soon as I got one.
Jeremy Shaw.
Here is a trace of the bug in action:
Its shows the file being moved, a log file being updated, and then the CreateFileA failing.
** 080baec8:Call kernel32.MoveFileA(403d1e94 "C:\\WINDOWS\\SYSTEM\\URLMON.DLL",40556734 "C:\\WINDOWS\\SYSTEM\\IE4Setup\\URLMON.DLL") ret=500f6a98 retval=00000001
** trace:file:MoveFileA (C:\WINDOWS\SYSTEM\URLMON.DLL,C:\WINDOWS\SYSTEM\IE4Setup\URLMON.DLL)
** trace:file:MoveFileExA (C:\WINDOWS\SYSTEM\URLMON.DLL,C:\WINDOWS\SYSTEM\IE4Setup\URLMON.DLL,0002)
** 080baec8:Ret kernel32.MoveFileA() retval=00000001 ret=500f6a98
** 080baec8:CALL mssetup.87: FLogOpen() ret=500f78ff retval=00000001
** 080baec8:RET mssetup.87: FLogOpen() retval=00000001 ret=500f78ff
** 080baec8:Call kernel32.FormatMessageA(00000500,500f1be0,00000000,00000000,40556710,00000000,4055670c) ret=500f7927 retval=0000005a
** 080baec8:Ret kernel32.FormatMessageA() retval=0000005a ret=500f7927
** 080baec8:CALL mssetup.100: FWriteToLogFile(403d20a8,00000000) ret=500f7938 retval=00000001
*** 080baec8:Call kernel32.SetErrorMode(00000001) ret=5009df3c retval=00000000
*** 080baec8:Ret kernel32.SetErrorMode() retval=00000000 ret=5009df3c
*** 080baec8:Call kernel32.CreateFileA(4036a7e0 "C:\\WINDOWS\\IE Setup Log.Txt",c0000000,00000000,00000000,00000003,00000000,00000000) ret=5009df92 retval=0000008c
*** trace:file:CreateFileA C:\WINDOWS\IE Setup Log.Txt GENERIC_READ GENERIC_WRITE OPEN_EXISTING
*** 080baec8:Ret kernel32.CreateFileA() retval=0000008c ret=5009df92
*** 080baec8:Call kernel32.SetErrorMode(00000000) ret=5009dfdd retval=00000001
*** 080baec8:Ret kernel32.SetErrorMode() retval=00000001 ret=5009dfdd
*** 080baec8:Call kernel32.SetFilePointer(0000008c,00000000,00000000,00000002) ret=5009e199 retval=0000356a
*** trace:file:SetFilePointer handle 140 offset 0 high 0 origin 2
*** 080baec8:Ret kernel32.SetFilePointer() retval=0000356a ret=5009e199
*** 080baec8:Call kernel32.lstrlenA(403d20a8 "\tMoveFile succeeded: C:\\WINDOWS\\SYSTEM\\URLMON.DLL to C:\\WINDOWS\\SYSTEM\\IE4Setup\\"...) ret=5009e388 retval=0000005a
*** 080baec8:Ret kernel32.lstrlenA() retval=0000005a ret=5009e388
*** 080baec8:Call kernel32.WriteFile(0000008c,403d20a8,0000005a,405566c8,00000000) ret=5009e161 retval=00000001
*** trace:file:WriteFile 140 0x403d20a8 90 0x405566c8 (nil)
*** 080baec8:Ret kernel32.WriteFile() retval=00000001 ret=5009e161
*** 080baec8:Call kernel32.lstrlenA(500c68f4 "\r\n") ret=5009e388 retval=00000002
*** 080baec8:Ret kernel32.lstrlenA() retval=00000002 ret=5009e388
*** 080baec8:Call kernel32.WriteFile(0000008c,500c68f4,00000002,405566c8,00000000) ret=5009e161 retval=00000001
*** trace:file:WriteFile 140 0x500c68f4 2 0x405566c8 (nil)
*** 080baec8:Ret kernel32.WriteFile() retval=00000001 ret=5009e161
*** 080baec8:Call kernel32.CloseHandle(0000008c) ret=5009e0ef retval=00000001
*** 080baec8:Ret kernel32.CloseHandle() retval=00000001 ret=5009e0ef
** 080baec8:RET mssetup.100: FWriteToLogFile() retval=00000001 ret=500f7938
** 080baec8:Call kernel32.LocalFree(403d20a8) ret=500f7941 retval=00000000
** 080baec8:Ret kernel32.LocalFree() retval=00000000 ret=500f7941
** 080baec8:Call kernel32.CopyFileA(40556734 "C:\\WINDOWS\\SYSTEM\\IE4Setup\\URLMON.DLL",403d1e94 "C:\\WINDOWS\\SYSTEM\\URLMON.DLL",00000000) ret=500f6aca retval=00000000
** trace:file:_lopen ('C:\WINDOWS\SYSTEM\IE4Setup\URLMON.DLL',0000)
** trace:file:CreateFileA C:\WINDOWS\SYSTEM\IE4Setup\URLMON.DLL GENERIC_READ FILE_SHARE_READ FILE_SHARE_WRITE OPEN_EXISTING
** trace:file:CreateFileA C:\WINDOWS\SYSTEM\URLMON.DLL GENERIC_WRITE FILE_SHARE_READ FILE_SHARE_WRITE CREATE_ALWAYS
** 080baec8:Ret kernel32.CopyFileA() retval=00000000 ret=500f6aca