Ever tried to play old games on a nowadays machine without any problems?
Well yesterday I was bored and decided to play
"Battlefield 1942". After executing BF1942.exe the screen just blinked for a second and then... nothing happened. I'm using
Windows 2003 (with latest updates) as my desktop OS, so I tried running the game under
Windows XP (again, fully updated) over a
Virtual Machine and the game worked fine there (well, in a 640x680 screen because of the emulated video driver).
Both systems have
DirectX 9, so there was something fishy going on there.
First of all I loaded BF1942.exe in
OllyDbg and executed it. The screen blinked again and the game exited successfully without any exception, so that's not a bad sign. At least I won't have to handle nasty segmentation faults, buffer overflows and such.
So I took a look at Olly's "Log data", and here's what I got:
OllyDbg Log dataAddress Message
... blah-blah ...
77E4BEF7 Debug string: Couldn't create CLSID_DirectMusic
77E4BEF7 Debug string: (0): Error: : Your version of DirectX is 600, you need at least DirectX8.1
Thread 0000091C terminated, exit code FFFFFFFF (-1.)
Process terminated, exit code FFFFFFFF (-1.)
Luckily the guys from
"Digital Illusions" put some neat error reporting, and I can easily see that my DirectX is recognized as version 6 instead of version 9. I searched for the string "Your version of DirectX is" in the strings references in Olly, and the was only one place where it is used:
Obviously, thats a place I shouldn be in, so start scrolling up the code until here:
The result of
CALL BF1942.007BCF50 is compared to 0x801, and I already know that the minimum DirectX version that can run BF1942 is 8.1, so that call probably will take my current DirectX version.
And here's what I found inside that call:
The Direct Draw library is loaded, then
"DirectDrawCreate" function is called and so on, but I already know that the game doesn't have any Direct Draw problems, but it has with Direct Music since the first debug string is
"Couldn't create CLSID_DirectMusic", so I scroll down until here:
Looks like that
CoCreateInstance fails, and it fails exactly on
DirectMusic. That's not good, so I started DirectX's dxdiag control panel so see for any errors.
At first glance it looked OK, the Sound and Display tests went OK, but comparing dxdiag under both Windows versions:
Uh, "Music" tab? Where the *H* is the Music tab in Windows 2003?
Reinstalling DirectX wont fix it. Reinstalling the sound drivers either. Reinstalling Windows is not an option, since mine is installed back in 2009, and sorry Digital Illusions and Electronic Arts, but I won't reinstall it just because a 10 years old game won't work on it.
So, back to CoCreateInstance and it's parameters:
CoCreateInstance referenceHRESULT CoCreateInstance(
__in REFCLSID rclsid,
__in LPUNKNOWN pUnkOuter,
__in DWORD dwClsContext,
__in REFIID riid,
__out LPVOID *ppv
);
I was interested in rclsid only, so here is what BF1942.00B39AFC was holding:
00B39AFC 10 9F 6B 63 7D 0C D1 11 95 B2 00 20 AF DC 74 21
Now the class ID's are a little tricky to handle from memory dumps, so here's a little hint how to convert them as a string.
The simple rule is - one DWORD, two WORDS, two bytes as String and eight bytes as String, so using the memory dump from above,
10 9F 6B 63 7D 0C D1 11 95 B2 00 20 AF DC 74 21
split it like so:10 9F 6B 63 // DWORD
7D 0C // WORD
D1 11 // WORD
95 B2 // String
00 20 AF DC 74 21 // String
flip the DWORD and WORD values (because in the memory they are swapped):63 6B 9F 10 // DWORD
0C 7D // WORD
11 D1 // WORD
95 B2 // String
00 20 AF DC 74 21 // String
And finally concatenate them like this:
636B9F10-0C7D-11D1-95B2-0020AFDC7421
And that's the class ID that's unable to load.
A quick search through the Windows 2003 registry doesn't give any result. However in Windows XP there was one:
On my system, the file
dmusic.dll doesn't exist. On a freshly installed Windows 2003 with DirectX 9 either, so I take the file from the virtual XP one, place it in my
System32 and register it with
regsvr32.
And magically the "Music" tab in dxdiag panel appeared.
At this point "BF1942.exe" starts normally and I can play it, probably without any more problems.
However, if I try the DirectMusic test in dxdiag, it fails with message:
"Failure at step 3 (Creating the IDirectMusicPerformance object): HRESULT = 0x80040154 (Class not registered)"
So I had to "debug" dxdiag to make the god damn thing fully support DirectMusic.
Because I didn't want to get deeper into Microsoft's crap, I started the
Process Monitor from
Sysinternals.com, set the filter to include results from
dxdiag.exe only and hit the
"Test DirectSound" button.
Here's what I've got:
The key obviously doesn't exist here, so after searching in the donor XP I find it here:
Again, I copied the
dmime.dll to my System32, registered it and tried the DirectMusic test again:
"Failure at step 2 (Creating the IDirectMusicLoader object): HRESULT = 0x80040154 (Class not registered)"
Meh. Here's what Procmon catched now:
Which in Windows XP was:
After adding this one the DirectMusic test returned:
"Failure at step 12 (Having the IDirectMusicLoader load the music): HRESULT = 0x80040154 (Class not registered)"
Close enough. Procmon logged this:
Which in Windows XP was:
With the last one, so far I've registered four DLL's -
dmusic.dll,
dmime.dll,
dmloader.dll and
dmstyle.dll
After trying the DirectMusic test with these four files, the cheesy
MIDI started playing, and the result was:
"All tests were successful."
So, hooray? Well, sort of.
There are five more files that are part of the DirectMusic, so if you want to fully support DirectMusic under Windows 2003, you should probably register them too. Just in case.
Here's the list of all the DirectMusic libraries:
dmband.dll | Microsoft DirectMusic Band |
dmcompos.dll | Microsoft DirectMusic Composer |
dmime.dll | Microsoft DirectMusic Interactive Engine |
dmloader.dll | Microsoft DirectMusic Loader |
dmscript.dll | Microsoft DirectMusic Scripting |
dmstyle.dll | Microsoft DirectMusic Style Engline |
dmsynth.dll | Microsoft DirectMusic Software Synthesizer |
dmusic.dll | Microsoft DirectMusic Core Services |
dswave.dll | Microsoft DirectMusic Wave |
Using a Windows XP system as a donor for Windows 2003 is perfectly fine. Most of the time.
Just remember - Always take files from a system with the same architecture! Using
x86 libraries over
x64 machine may still work but it's a baaad, bad idea, so don't.
If you don't have a donor system, you may use the files provided from sites such as
http://www.dll-files.com/,
http://www.dlldump.com and so on.
Oh yeah, and you can fuck up your system pretty good, so always make backups, snapshots, etc. before doing anything.
Comments
* You have an opinion? Let us all hear it!