http://bugs.winehq.org/show_bug.cgi?id=27971
--- Comment #2 from Hin-Tak Leung htl10@users.sourceforge.net 2011-08-04 20:01:39 CDT --- (In reply to comment #1)
Please attach a +msi trace. Make sure you have debug symbols in your backtrace.
Thanks for the +msi tips. So I did the WINEDEBUG=+msi , and the relevant info is below:
-------------------- trace:msi:msi_get_property property L"SourceDir" not found Backtrace: =>0 0x6838dfe8 msi_load_media_info+0x2c8() in msi (0x001e80c4) 1 0x6837f0e3 ACTION_InstallFiles+0x1d2() in msi (0x001e80a0) 2 0x68345bbd ACTION_HandleStandardAction+0xcc() in msi (0x6837ef10) 3 0x68355db3 ACTION_PerformAction+0x42() in msi (0x00196bd8) 4 0x6835655b ITERATE_Actions+0xaa() in msi (0x00196bd8) 5 0x6839f2a9 MSI_IterateRecords+0x68() in msi (0x683564b0) 6 0x68345035 ACTION_ProcessExecSequence+0x114() in msi (0x00175546) 7 0x68356b26 MSI_InstallPackage+0x315() in msi (0x00175546) 8 0x68391786 MsiInstallProductW+0xf5() in msi (0x00000000) 0x6838dfe8 msi_load_media_info+0x2c8 in msi: movzwl 0x0(%edx,%eax,1),%ecx -------------------
I then ran 'objdump -f -d msi.dll.so' and found that the crash was lstrcpyW() trying to copy NULL from a previous 'msi_dup_property(.., szSourceDir)' result. So I made this patch:
---------------------- diff --git a/dlls/msi/media.c b/dlls/msi/media.c index c879af1..316c72a 100644 --- a/dlls/msi/media.c +++ b/dlls/msi/media.c @@ -681,6 +681,7 @@ UINT msi_load_media_info(MSIPACKAGE *package, UINT Sequence, MSIMEDIAINFO *mi) 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','M','e','d','i','a','`',' ', 'W','H','E','R','E',' ','`','L','a','s','t','S','e','q','u','e','n','c','e','`',' ', '>','=',' ','%','i',' ','O','R','D','E','R',' ','B','Y',' ','`','D','i','s','k','I','d','`',0}; + static const WCHAR empty_dir[] = {0}; MSIRECORD *row; LPWSTR source_dir, source; DWORD options; @@ -711,6 +712,8 @@ UINT msi_load_media_info(MSIPACKAGE *package, UINT Sequence, MSIMEDIAINFO *mi)
msi_set_sourcedir_props(package, FALSE); source_dir = msi_dup_property(package->db, szSourceDir); + if (!source_dir) + source_dir = strdupW(empty_dir); lstrcpyW(mi->sourcedir, source_dir); PathAddBackslashW(mi->sourcedir); mi->type = get_drive_type(source_dir); ---------------
This patch puts a empty wide string into source_dir if source_dir is NULL. After applying this patch, it is somewhat curious that /qb works if I run it TWICE in a row!
It is as if the first time fails but copy the msi somewhere anyway (%WINDOWS%/Installer/ ? ) to allow the 2nd time to find it at some default location?
So the patch is a step in the right direction but not yet completely correct - any comments on improvements?