Fun with Wine
Around December 2002, I noticed this old copy of Microsoft Visual C++ 4.0
laying around that I'd bought at a garage sale for $5 a few years back,
and, being bored, decided to try running it under Wine.
After all, it's been seven years since MSVC4 was released, Wine ought to be
able to handle it by now, right? Little did I know that would be the start
of quite a fun little ride to debugging-land. After I decided
I wanted this to work, I started figuring out how to get good logs
out of Wine and Windows, and fixing buglets became an obsession.
Thanks to the Wine developer community for their excellent attitude and
quick respnses.
Here's a roughly chronological log of what I ran into, earliest first.
A call went out for a perl hacker to do a tiny fix to many files,
so I raised my hand.
Result accepted into Wine tree on Jan 8th.
MSVC4.0 works fine in wine once installed, but its installer had troubles:
First, it locked up when it tried to play a sound.
This worked in wine six months ago, so I grabbed the
CVS archives, and did a binary search for the exact patch
that broke it. This enabled the maintainers to fix
the lockup;
here's their fix.
Current Drive/Directory must be right
Second, the Install button didn't work.
That turned out to be the setup program's fault. I was running setup like this:
$ wine d:setup
Turns out msvc4 is picky; you need to do
$ wine d:\\setup
in wine, or
C:\> d:\setup
in windows to get it to work. (I mistakenly posted a patch
that fixed this in wine by making argv[0] always an absolute
path, until I realized Windows no longer does that... I may be
remembering old MS-DOS behavior there.)
Third, the "STL" button didn't work.
That was interesting. The best way to see what was going on
was to run "Debugging Tools for Windows" from Microsoft on my XP system
and/or get a log with "wine --debugmsg +exec,+shell,+proc d:\\setup > log 2>&1"
That showed that setup was calling
ShellExec(..."wordpad.exe", "d:\stl\readme.wri", ...)
but I didn't have wordpad installed. I did that by copying the
files wordpad.exe, mfc42.dll, and riched20.dll from a real windows system,
and verifying that wordpad ran.
But Setup *still* couldn't find wordpad, so I searched the
registry for "wordpad.exe", and deleted the instances one by one
until I found the one Windows was using to launch wordpad.
I then added code to Wine to search that registry key. Voila, the "STL" button
launched wordpad on the file! My patch
was accepted into the tree.
Even with that, the STL button still doesn't work *well*; readme.wri looks
awful under Wine (it just shows raw bytes). A little tracing reveals that wordpad seems to
look up a text converter in the registry to figure out how to import .wri format files.
Copying that registry entry, the file it points at, and msconv97.dll,
makes the .wri file load properly in wordpad.
In summary, here are the files that seem to be used by WordPad to read .wri files:
Program Files/Common Files/Microsoft Shared/TextConv/write32.wpc
Program Files/Common Files/Microsoft Shared/TextConv/msconv97.dll
Program Files/Accessories/wordpad.exe
windows/system/msvcrt40.dll
windows/system/mfc42.dll
windows/system/riched20.dll
And here are the registry entries that seem to be involved in "start wordpad foo.wri":
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\WORDPAD.EXE]
@="C:\\Progra~1\\Access~1\\WORDPAD.EXE"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Text Converters\Import\MSWinWrite.wpc]
"Name"="Windows Write"
"Path"="C:\\Program Files\\Common Files\\Microsoft Shared\\TextConv\\write32.wpc"
"Extensions"="wri"
You can test all this with the Linux commandline
$ wine start wordpad.exe foo.wri
where foo.wri is any document saved by the MS-Windows 3.1 program "write.exe" in Write format,
and "start" is my implementation of the MS-Windows start.exe program (see below).
If that works, then the STL button on msvc4's setup.exe should work.
Fourth, the "Explore the CD" button doesn't work. Logging shows
it's calling ShellExecute(..., "EXPLORER.EXE", ".", ...)
So it looks like we need a wrapper around WinFile to make it
look like Explorer... I've written a trivial one and
posted it to
wine-devel for comment.
All the installshield stuff in the msvc4 installer seems to work --
except the Data Access Objects installer. When you run it, you
get to the first screen with a big blue background, but the foreground
window never shows up. It's probably there, but invisible, or something.
Alt-tab doesn't help, and the blue background is full-screen, so you
can't try moving it out of the way.
It turns out this is a longstanding bug in wine.
There are two workarounds: switch to managed="N", or tell Wine to use a small desktop.
One of the Wine developers immediately suggested
patching the default .wine/config file,
which works wonderfully.
This patch was committed to the Wine tree on Jan 20. (Hopefully we'll fix the real problem some day, too.)
The MFCkit installer fails:
$ wine d:\\mfckit\\disk1\\setup.exe
Could not load 'RBHEAP.DLL' required by 'WBRUN20', error= 2
It turns out that this is a flaw in Wine's implementation of cabinet.dll; you can work
around it by copying the cabinet.dll from your Microsoft Windows directory,
and telling Wine to use it, e.g. (assuming /dos/c is where your MS-Windows is installed,
and c/ is where your fake windows is installed):
$ cp /dos/c/windows/system/cabinet.dll c/windows/system
$ wine --dll cabinet=native d:\\mfckit\\disk1\\setup.exe
Once past this hurdle, the installer works fine until it tries to add icons,
when it fails with "Cannot establish DDE connection with Program Manager".
A determined user could use it without icons, probably, but that's still something
that we should fix up...
More info on DDE here.
I haven't played with this much yet, but I did notice that
when trying to install msvc6 under Wine (emulating XP), setup
created lots of little cmd processes running this batch file and eating
lots of CPU time:
:Repeat
del "E:\vs60wiz.exe"
if exist "E:\vs60wiz.exe" goto Repeat
del "C:\WINDOWS\DEL4056.BAT"
Turns out this is a bug in wine's implementation of cmd
that Uwe Bonnes already knew about.
The bug was finally fixed in Wine's tree on Jan 15th.
Believe it or not, Wine until now didn't have a "start.exe",
a handy little program that essentially lets you do the equivalent
of double-clicking on something in a batch file or from the DOS prompt.
So I wrote one, and
submitted it to wine-patches after discussing it a bit first on wine-devel.
It was accepted into the wine tree on 21 Jan
in two pieces.
While writing my implementation of 'start.exe', I noticed that
the Wine resource compiler diverged a bit from the msvc6 one,
and posted a patch to fix it.
(I'm no expert on Flex, the lexical analyzer wrc uses, so this was
a bit intimidating to fix. The key is to not let Flex know you're scared :-)
This patch was accepted into the Wine tree on Jan 20th.
As it turns out, start is builting on WinXP and later, so perhaps this will need to be revisited.
At least in Wine as of early 2003, Installshield 6 installers won't work
unless you copy stdole32.tlb from your Windows partition.
I ran into this, and as a result of my question,
Marcus Meissner added a hard-to-ignore warning
if that file is missing. Also, it looks like Robert Shearman is
creating a version of stdole32.tlb that can be included in wine.
While trying to run an I.S.6 installer, I ran into the error
"Error Number: 0x80040706
Description: Object reference not set
Setup will now terminate."
Markus Meissner said he'd run
into that before, and had tried to fix it.
Fortunately, running wine with --debugmsg +ole > /tmp/log 2>&1 (you must redirect
to a file; nothing else seemed to do) works around this error for me.
(April 2003) Now to get this to run, I have to do --debugmsg +server > /tmp/log 2>1.
No idea what's causing this.
Three named pipe problems have come to light recently:
- pipes aren't listening for connections upon creation
- Wineserver can crash when reading from a closed pipe
- FlushFileBuffers() does nothing, which means that pipe clients might lose the last bunch of bytes from the server
I've posted a patch
which tries to address these issues. No idea if it's correct, but it did pass my little tests.
(April 2003) A win32 app I care about uses LVS_OWNERDATA in a very large listview control,
but even though Wine's listview has been improved lately, it still doesn't handle
this quite right. In particular, if you compile and run this test app,
and pick "View/Capture View" from the menu, it will display properly on Windows, but show
a blank window on Wine. See Wine Bug 1404.
At a demo in front of our LUG, I ran Abiword 0.99 win32 on wine. It really impressed
the crowd until I tried to load a file, at which point the horribly
smeared and splayed text quickly brought the audience back to earth.
I tried again with Abiword 1.05 on Wine-200304xx. No improvement.
See
my writeup on wine-devel.
Last update: 21 Apr 2003