[Bug 36838] TOCA Touring Car Championship: installer copies one file from CD and then shows an error

wine-bugs at winehq.org wine-bugs at winehq.org
Thu Jul 3 06:32:17 CDT 2014


http://bugs.winehq.org/show_bug.cgi?id=36838

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |download
             Status|UNCONFIRMED                 |NEW
                 CC|                            |focht at gmx.net
          Component|-unknown                    |shell32
     Ever confirmed|0                           |1

--- Comment #3 from Anastasius Focht <focht at gmx.net> ---
Hello folks,

confirming.

--- snip ---
$ WINEDEBUG=+tid,+seh,+relay,+server wine ./SETUP.EXE >>log.txt 2>&1
...
0009:Call shell32.SHFileOperationA(0033e984) ret=004029f5 
...
0009:Call KERNEL32.CopyFileW(0013f258
L"Z:\\home\\focht\\Downloads\\install\\tourcars.exe",00151758
L"c:\\Codemast\\TourCar\\tourcars.exe",00000000) ret=7e8fcc89
0009:Ret  KERNEL32.CopyFileW() retval=00000001 ret=7e8fcc89 
...
0009:Call shlwapi.SHFreeShared(00000000,00000008) ret=7e8d3f1f
0009:Call
KERNEL32.DuplicateHandle(ffffffff,00000000,ffffffff,0033e35c,000f001f,00000000,00000003)
ret=7e817e1f
0009: dup_handle( src_process=ffffffff, src_handle=0000, dst_process=ffffffff,
access=000f001f, attributes=00000000, options=00000003 )
0009: dup_handle() = INVALID_HANDLE { handle=0000, self=1, closed=0 }
0009:Ret  KERNEL32.DuplicateHandle() retval=00000000 ret=7e817e1f
0009:Call KERNEL32.CloseHandle(00000000) ret=7e818289
0009: close_handle( handle=0000 )
0009: close_handle() = INVALID_HANDLE
0009:Ret  KERNEL32.CloseHandle() retval=00000000 ret=7e818289
0009:Ret  shlwapi.SHFreeShared() retval=00000000 ret=7e8d3f1f 
...
0009:Ret  shell32.SHFileOperationA() retval=00000000 ret=004029f5
0009:Call KERNEL32.GetLastError() ret=004029fb
0009:Ret  KERNEL32.GetLastError() retval=00000006 ret=004029fb
0009:Call user32.MessageBoxA(0001004a,0040a268 "There was an error whilst
trying to install files\n\tPress OK to quit",00407808 "TOCA Touring Car
Championship Demo Setup",00002030) ret=00401578 
--- snip ---

The installer doesn't like the lasterror code 0x6 (ERROR_INVALID_HANDLE) from
'SHFileOperationA' (0x12 would be acceptable, if any):

--- snip ---
004029C1  |83C4 0C           |ADD ESP,0C
004029C4  |8D4424 1C         |LEA EAX,DWORD PTR SS:[ESP+1C]
004029C8  |8D8C24 5C010000   |LEA ECX,DWORD PTR SS:[ESP+15C]
004029CF  |8D5424 58         |LEA EDX,DWORD PTR SS:[ESP+58]
004029D3  |50                |PUSH EAX
004029D4  |895C24 20         |MOV DWORD PTR SS:[ESP+20],EBX
004029D8  |C74424 24 02000000|MOV DWORD PTR SS:[ESP+24],2
004029E0  |894C24 28         |MOV DWORD PTR SS:[ESP+28],ECX
004029E4  |895424 2C         |MOV DWORD PTR SS:[ESP+2C],EDX
004029E8  |66:C74424 30 1502 |MOV WORD PTR SS:[ESP+30],215
004029EF  |FF15 C4F34000     |CALL DWORD PTR DS:[<&SHELL32.SHFileOperationA>]
004029F5  |FF15 C8F24000     |CALL DWORD PTR DS:[<&KERNEL32.GetLastError>]
004029FB  |25 FFFF0000       |AND EAX,0FFFF
00402A00  |74 09             |JE SHORT SETUP.00402A0B
00402A02  |83F8 12           |CMP EAX,12
00402A05  |0F85 CB000000     |JNZ SETUP.00402AD6
00402A0B  |8D4C24 58         |LEA ECX,DWORD PTR SS:[ESP+58]
00402A0F  |68 80000000       |PUSH 80            ; FileAttributes = NORMAL
00402A14  |51                |PUSH ECX           ; FileName
00402A15  |FF15 C4F24000     |CALL DWORD PTR
DS:[<&KERNEL32.SetFileAttributesA>]
--- snip ---

The previous trace log was already done with +server to show where it
originates from.

--- snip ---
Wine-dbg>bt

Backtrace:
=>0 0x7e8ede7f SHFreeShared(hShared=0x0(nil), dwProcId=0x22)
[/home/focht/projects/wine/wine.repo/src/dlls/shell32/shellord.c:1459] in
shell32 (0x0033e5c8)

  1 0x7e916cb8
SHNotifyCopyFileW+0x115(src="Z:\home\focht\Downloads\install\tourcars.exe",
dest="c:\Codemast\TourCar\tourcars.exe", bFailIfExists=0)
[/home/focht/projects/wine/wine.repo/src/dlls/shell32/shlfileop.c:640] in
shell32 (0x0033e638)

  2 0x7e917f29 copy_file_to_file+0x8b(op=0x33e8fc,
szFrom="Z:\home\focht\Downloads\install\tourcars.exe",
szTo="c:\Codemast\TourCar\tourcars.exe")
[/home/focht/projects/wine/wine.repo/src/dlls/shell32/shlfileop.c:1143] in
shell32 (0x0033e658)

  3 0x7e9185db copy_files+0x4fa(op=0x33e8fc, flFrom=0x33e8e4, flTo=0x33e8cc)
[/home/focht/projects/wine/wine.repo/src/dlls/shell32/shlfileop.c:1291] in
shell32 (0x0033e8a8)

  4 0x7e919015 SHFileOperationW+0x141(lpFileOp=0x33e942)
[/home/focht/projects/wine/wine.repo/src/dlls/shell32/shlfileop.c:1571] in
shell32 (0x0033e918)

  5 0x7e9173bd SHFileOperationA+0x14a(lpFileOp=<couldn't compute location>)
[/home/focht/projects/wine/wine.repo/src/dlls/shell32/shlfileop.c:887] in
shell32 (0x0033e998)

  6 0x004029f5 in setup (+0x29f4) (0x7b8759b1)
--- snip ---

The corresponding source:
http://source.winehq.org/git/wine.git/blob/0f64ffd91ff2fab97d9c52335478ff2fb4114947:/dlls/shell32/changenotify.c#l260

--- snip ---
260 void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1,
LPCVOID dwItem2)
261 {
...
269     HANDLE shared_data = NULL;
270     LPITEMIDLIST Pidls[2];
271     LPNOTIFICATIONLIST ptr;
272     struct list recipients;
...
414     SHFreeShared(shared_data, GetCurrentProcessId());
415     SHFree(Pidls[0]);
416     SHFree(Pidls[1]);
...
424 }
--- snip ---

'shared_data' is NULL (no notifiers) hence the call to 'SHFreeShared' is
unnecessary and avoids that lasterror leaking.

After fixing that part it still fails:

--- snip ---
...
0009:Ret  shell32.SHFileOperationA() retval=00000000 ret=004029f5
0009:Call KERNEL32.GetLastError() ret=004029fb
0009:Ret  KERNEL32.GetLastError() retval=00000001 ret=004029fb 
--- snip ---

To see where this lasterror code 0x1 originates from we need to unmask all
internal relay calls (remove keys in registry):

--- snip ---
[HKEY_CURRENT_USER\Software\Wine\Debug]
"RelayExclude"="ntdll.RtlEnterCriticalSection;ntdll.RtlLeaveCriticalSection;kernel32.48;kernel32.49;kernel32.94;kernel32.95;kernel32.96;kernel32.97;kernel32.98;kernel32.TlsGetValue;kernel32.TlsSetValue;kernel32.FlsGetValue;kernel32.FlsSetValue;kernel32.SetLastError"
"RelayFromExclude"="winex11.drv;winemac.drv;user32;gdi32;advapi32;kernel32"
--- snip ---

Voila - grepping through the full relay trace log yields:

--- snip ---
0009:Call KERNEL32.Wow64DisableWow64FsRedirection(0033a800) ret=7e8ed691
0009:Call ntdll.RtlWow64EnableFsRedirectionEx(00000001,0033a800) ret=7b860f0c
0009:Ret  ntdll.RtlWow64EnableFsRedirectionEx() retval=c0000002 ret=7b860f0c
0009:Call ntdll.RtlNtStatusToDosError(c0000002) ret=7b860f23
0009:Ret  ntdll.RtlNtStatusToDosError() retval=00000001 ret=7b860f23
0009:Ret  KERNEL32.Wow64DisableWow64FsRedirection() retval=00000000
ret=7e8ed691
--- snip --- 

Debugger:

--- snip --- 
Wine-dbg>bt
Backtrace:

=>0 0x7b860ee7 Wow64DisableWow64FsRedirection(old_value=0x33a880)
[/home/focht/projects/wine/wine.repo/src/dlls/kernel32/path.c:1850] in kernel32
(0x0033cad8)

  1 0x7e8ede8c UNIXFS_path_to_pidl+0xce(pUnixFolder=0x141a28, pbc=0x1373e0,
path="c:\Codemast\TourCar\tourcars.exe", ppidl=0x33dea4)
[/home/focht/projects/wine/wine.repo/src/dlls/shell32/shfldr_unixfs.c:629] in
shell32 (0x0033ddc8)

  2 0x7e8eef31 ShellFolder2_ParseDisplayName+0xd1(iface=<couldn't compute
location>, hwndOwner=<couldn't compute location>, pbc=<couldn't compute
location>, display_name=<couldn't compute location>, pchEaten=<couldn't compute
location>, ppidl=<couldn't compute location>, attrs=<couldn't compute
location>)
[/home/focht/projects/wine/wine.repo/src/dlls/shell32/shfldr_unixfs.c:948] in
shell32 (0x0033de68)
...

Wine-dbg>n
1851        NTSTATUS status = RtlWow64EnableFsRedirectionEx( TRUE, (ULONG
*)old_value );
Wine-dbg>n
1852        if (status) SetLastError( RtlNtStatusToDosError(status) );
Wine-dbg>p status
=> 2
0xc0000002
--- snip --- 

I saved/restored the last error around the Wow64 filesystem redirection calls.
And it still failed ... more code paths leaked lasterror codes too :|

--- snip ---
0009:Ret  shell32.SHFileOperationA() retval=00000000 ret=004029f5
0009:Call KERNEL32.GetLastError() ret=004029fb
0009:Ret  KERNEL32.GetLastError() retval=000000b7 ret=004029fb 
--- snip ---

That thing wasn't really visible so another debugging session revealed it's
'CopyFileExW' -> 'CreateFileW' -> 'SetLastError(ERROR_ALREADY_EXISTS)' if the
destination file exists (re-run of installer).

I got fed up with all the lasterror codes leaking from various code paths (by
design) and reset the lasterror in 'SHNotifyCopyFileW' if the copy operation
succeeded.
There might be a better place but this worked for me.

Source:
http://source.winehq.org/git/wine.git/blob/2ba9ee018bce4953feb728595f4a4a6e47b186a1:/dlls/shell32/shlfileop.c#l625

--- snip ---
625 static DWORD SHNotifyCopyFileW(LPCWSTR src, LPCWSTR dest, BOOL
bFailIfExists)
626 {
627     BOOL ret;
628     DWORD attribs;
...
632     /* Destination file may already exist with read only attribute */
633     attribs = GetFileAttributesW(dest);
634     if (IsAttrib(attribs, FILE_ATTRIBUTE_READONLY))
635         SetFileAttributesW(dest, attribs & ~FILE_ATTRIBUTE_READONLY);
636
637     ret = CopyFileW(src, dest, bFailIfExists);
638     if (ret)
639     {
640         SHChangeNotify(SHCNE_CREATE, SHCNF_PATHW, dest, NULL);
641         return ERROR_SUCCESS;
642     }
643
644     return GetLastError();
645 }
--- snip ---

With that part fixed the installer succeeds.
IMHO part 1, avoid NULL 'shared_data' cleanup call should be fixed too.

$ sha1sum tocademo_JeuxVideo.com_413.zip 
3c7a4d0d8bc7e6f5095358b3d3ff005e53e44d4b  tocademo_JeuxVideo.com_413.zip

$ du -sh tocademo_JeuxVideo.com_413.zip 
6.8M    tocademo_JeuxVideo.com_413.zip

$ wine --version
wine-1.7.21-41-g5af3b8c

Regards

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list