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.

Janitorial work

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.

Getting msvc4 working

MSVC4.0 works fine in wine once installed, but its installer had troubles:

Sound lockup

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.)

Wordpad trouble; adding App Paths search to ShellExec

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
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]

[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"
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.

What, no 'explorer'?

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.

1995-era InstallShield woes

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.)

Installer woes, take 2

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.

Getting msvc6 working

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:
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.

What, no 'start'?

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.

Resource compiler compatibility

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.

Installshield 6 woes

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.

Named Pipe Woes

Three named pipe problems have come to light recently:
  1. pipes aren't listening for connections upon creation
  2. Wineserver can crash when reading from a closed pipe
  3. 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.

Abiword woes

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