xlviewer install cmdline passed from CreateProcessA to msiexec looks wrong

Darragh Bailey felix at compsoc.nuigalway.ie
Fri Nov 23 20:50:12 CST 2007


OK, long time lurker, only recently decided to try my hand at coding for
wine.

Picked a bug 9628 and decided to have a bash.

Bug occured because a patch to the msiexec command line parsing was
reverted due to regressions in the xlviewer installer and other apps. I
don't know about the other apps, I can't find a corresponding bug and
only gleaned this bit of info from the changelog and in the cvs mailing
list that tracks commits.
http://www.winehq.org/pipermail/wine-cvs/2007-March/031339.html


After some digging I found that problem was that with current git the
command line being sent to msiexec when installing "RPG Maker" was
missing the msiexec executable. So the msiexec command line parsing
would result in "/i" as being the first element of the arguments array
to be processed. The main loop, expected that msiexec should always be
argv[0], and so will always start from the second element.

Then comparing of what used to happen when msiexec used the call to 
CommandLineToArgvW suggested that use of CommandLineToArgvW was more
correct given the main loop design. If the program name is absent as the
first argument, msiexec would just get back an empty string as the first
element and the arguments to msiexec would start at the second element.


Since this appears more correct, I looked at the behaviour of xlviewer
(free download from microsoft) installer, to see what the differences
were.

I had to add some extra traces to the start of the main function in
msiexec to get an idea of what was going on. Basically they would just
dump out the contents of argv, one per line, so that I could see what it
was getting as the command line.

Added the following to the top of the main function:
	for( i=0; i<argc; i++) {
		WINE_TRACE("bug 9628: argv[%d] = \"%s\"\n", i, argv[i]);
	}

using the newly build wine tree, and just pointing wine at the exe.
The command line msiexec would get on installing xlviewer was

trace:msiexec:main bug 9628: argv[0] = "c:\windows\system32\msiexec.exe"
trace:msiexec:main bug 9628: argv[1] = "/I"
trace:msiexec:main bug 9628: argv[2] =
"C:\windows\temp\IXP001.TMP\XLVIEW.MSI"
trace:msiexec:main bug 9628: argv[3] = "CDCACHE=2"
trace:msiexec:main bug 9628: argv[4] = "LAUNCHEDFROMSETUP=1"
trace:msiexec:main bug 9628: argv[5] =
"SETUPEXEPATH=C:\windows\temp\IXP001.TMP" SETUPEXENAME=SETUP.EXE
/lpiwaeo
C:\windows\temp\Microsoft"
trace:msiexec:main bug 9628: argv[6] = "Office"
trace:msiexec:main bug 9628: argv[7] = "Excel"
trace:msiexec:main bug 9628: argv[8] = "Viewer"
trace:msiexec:main bug 9628: argv[9] = "2003"
trace:msiexec:main bug 9628: argv[10] = "Setup(0004)_Task(0001).txt
CDCACHE=0
DWSETUPLOGFILE=C:\windows\temp\Microsoft"
trace:msiexec:main bug 9628: argv[11] = "Office"
trace:msiexec:main bug 9628: argv[12] = "Excel"
trace:msiexec:main bug 9628: argv[13] = "Viewer"
trace:msiexec:main bug 9628: argv[14] = "2003"
trace:msiexec:main bug 9628: argv[15] = "Setup(0004).txt
DWMSILOGFILE=C:\windows\temp\Microsoft"
trace:msiexec:main bug 9628: argv[16] = "Office"
trace:msiexec:main bug 9628: argv[17] = "Excel"
trace:msiexec:main bug 9628: argv[18] = "Viewer"
trace:msiexec:main bug 9628: argv[19] = "2003"
trace:msiexec:main bug 9628: argv[20] = "Setup(0004)_Task(0001).txt"

Now this looks wrong to me. It looks like there is a bug in how the
command line is being passed to msiexec. The existing code that
parses this command line, is in fact working around this bug.


Adding +process to the WINEDEBUG variable I got to see what
CreateProcessA was calling msiexec with[1]:

L"\"c:\\windows\\system32\\msiexec.exe\"  /I
C:\\windows\\temp\\IXP008.TMP\\XLVIEW.MSI CDCACHE=\"2\"
LAUNCHEDFROMSETUP=\"1\" SETUPEXEPATH=\"C:\\windows\\temp\\IXP008.TMP\\\"
SETUPEXENAME=\"SETUP.EXE\"   /lpiwaeo \"C:\\windows\\temp\\Microsoft
Office Excel Viewer 2003 Setup(0014)_Task(0001).txt\" CDCACHE=\"0\"
DWSETUPLOGFILE=\"C:\\windows\\temp\\Microsoft Office Excel Viewer 2003
Setup(0014).txt\" DWMSILOGFILE=\"C:\\windows\\temp\\Microsoft Office
Excel Viewer 2003 Setup(0014)_Task(0001).txt\""

1. I also have to increase the debug str length in debug.c otherwise the 
end of the string would get dropped.


Now when I run msiexec with the following command line
msiexec /I C:\\windows\\temp\\IXP008.TMP\\XLVIEW.MSI CDCACHE="2"
LAUNCHEDFROMSETUP="1" SETUPEXEPATH="C:\\windows\\temp\\IXP008.TMP\\"
SETUPEXENAME="SETUP.EXE"    /lpiwaeo "C:\\windows\\temp\\Microsoft
Office Excel Viewer 2003 Setup(0014)_Task(0001).txt" CDCACHE="0"
DWSETUPLOGFILE="C:\\windows\\temp\\Microsoft Office Excel Viewer 2003
Setup(0014).txt" DWMSILOGFILE="C:\\windows\\temp\\Microsoft Office Excel
Viewer 2003 Setup(0014)_Task(0001).txt"

I see the following appear in the traces from msiexec:
trace:msiexec:main bug 9628: argv[0] = "programs/msiexec/msiexec.exe.so"
trace:msiexec:main bug 9628: argv[1] = "/I"
trace:msiexec:main bug 9628: argv[2] =
"C:\windows\temp\IXP002.TMP\XLVIEW.MSI"
trace:msiexec:main bug 9628: argv[3] = "CDCACHE=2"
trace:msiexec:main bug 9628: argv[4] = "LAUNCHEDFROMSETUP=1"
trace:msiexec:main bug 9628: argv[5] =
"SETUPEXEPATH=C:\windows\temp\IXP002.TMP\"
trace:msiexec:main bug 9628: argv[6] = "SETUPEXENAME=SETUP.EXE"
trace:msiexec:main bug 9628: argv[7] = "/lpiwaeo"
trace:msiexec:main bug 9628: argv[8] = "C:\windows\temp\Microsoft Office
Excel Viewer 2003 Setup(0003)_Task(0001).txt"
trace:msiexec:main bug 9628: argv[9] = "CDCACHE=0"
trace:msiexec:main bug 9628: argv[10] =
"DWSETUPLOGFILE=C:\windows\temp\Microsoft Office Excel Viewer 2003
Setup(0003).txt"
trace:msiexec:main bug 9628: argv[11] =
"DWMSILOGFILE=C:\windows\temp\Microsoft Office Excel Viewer 2003
Setup(0003)_Task(0001).txt"

Which seems bang on with what msiexec should be getting as its
commandline arguments.

In fact the only way I could pass in the command line to msiexec and get
the same output near the top was with the following:

msiexec /I C:\\windows\\temp\\IXP002.TMP\\XLVIEW.MSI CDCACHE="2"
LAUNCHEDFROMSETUP="1" SETUPEXEPATH="C:\\windows\\temp\\IXP002.TMP\"
SETUPEXENAME="SETUP.EXE"   /lpiwaeo "C:\\windows\\temp\\Microsoft Office
Excel Viewer 2003 Setup\(0003\)_Task\(0001\).txt" CDCACHE="0"
DWSETUPLOGFILE="C:\\windows\\temp\\Microsoft Office Excel Viewer 2003
Setup\(0003\).txt" DWMSILOGFILE="C:\\windows\\temp\\Microsoft Office
Excel Viewer 2003 Setup\(0003\)_Task\(0001\).txt""

Notice the difference between the following:
SETUPEXEPATH="C:\\windows\\temp\\IXP008.TMP\\" = correct command line
SETUPEXEPATH="C:\\windows\\temp\\IXP002.TMP\" = broken

It seems to me that current command line parsing in msiexec is a hack to
work around a bug somewhere between CreateProcessA and where the
executable actually gets run, when you have a directory path ending in a
slash and also enclosed by quotes. It appears that one of the double
slashes at the end gets substituted before its time.


So basically, I'm wondering if I'm actually on the right track here. Is
this a bug in the behaviour of how the command line is sent to the new
process? I've yet to log a bug since I'm still trying to understand what
exactly is happening and if this is in fact a bug.

At the moment I trying to work out how to get more information on what's
happening to the commandline in the create_process function, so I've yet
to work out why the command line is altered by the time it reaches the
msiexec program. Any suggestions are welcome. :)


-- 
Darragh

"Nothing is foolproof to a sufficiently talented fool."



More information about the wine-devel mailing list