Join the discord

DirectMusic under Windows 2003

20 May, 2012 15:36
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.dllMicrosoft DirectMusic Band
dmcompos.dllMicrosoft DirectMusic Composer
dmime.dllMicrosoft DirectMusic Interactive Engine
dmloader.dllMicrosoft DirectMusic Loader
dmscript.dllMicrosoft DirectMusic Scripting
dmstyle.dllMicrosoft DirectMusic Style Engline
dmsynth.dllMicrosoft DirectMusic Software Synthesizer
dmusic.dllMicrosoft DirectMusic Core Services
dswave.dllMicrosoft 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!

Guest 09 Oct, 2021 22:03
This saved the day with BF 1942 on Server 2008 R2 which I have installed on 12 machines in the basement LAN. Before now everyone had to run in windowed mode to get the you are running Dirextx 600 error and go ignore and now the game starts fine. I just registered in sys32 and syswow64 folders. Note Win10 users don't have the issue as there is now a feature in programs and features called legacy and it allows direct play to be added properly.
© nullsecurity.org 2011-2024 | legal | terms & rules | contacts