A number of people have asked for me to write up my experiences debugging a problem. The thing is that it’s hard to do that explicitly without disclosing internals of functions that probably shouldn’t be disclosed (because they relate to features that haven’t been announced, etc). However, I debugged a problem the other day that fits the bill perfectly.
We had an internal helpdesk request come in that a user had lost audio shortly after installing XP SP2. It turns out that while I didn’t have a huge impact on SP2 (mostly doing code reviews), there were a couple of things I added to the system. The biggest feature I added was the ability to stop the Windows Audio service.
And it turns out that this could have caused the problems the user was seeing.
So I asked for (and was granted) RDP (remote desktop) access to the machine. Looking at the machine, there were no MME (MultiMedia Extensions, our term for the waveXxx, mixerXxx, midiXxx APIs) devices enumerated. Well, it looked like I needed to break out the debugger.
Since the windows audio service runs in the same process as the networking services, and since the XP SP2 symbols are available over the network, the first thing I needed to do was to split the windows audio service into its own process. I made the necessary registry modifications to make it run in its own process (no, I’m not going to document them, nobody needs to know them), and then I stopped the windows audio service.
C:\>net stop “windows audio”
The requested pause or stop is not valid for this service.
More help is available by typing NET HELPMSG 2191.
Huh? Wait a second. Why isn’t windows audio stoppable?
Time to pull the service debuggers bag-o-tricks. One of the utilities bundled with XP is a diagnostic tool known as sc.exe, it’s a general purpose service control API utility. To do this, I need to use the short name for the windows audio service, audiosrv.
C:\>sc query audiosrv
TYPE : 20 WIN32_SHARE_PROCESS
STATE : 4 RUNNING
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0
Hold on. I mentioned above that the biggest change I made for XP SP2 was to make the windows audio service stoppable. What’s going on here?
I know that windows audio is stoppable in SP2 installations, I’ve verified that. The thing is that a service tells the service controller its capabilities when it first calls SetServiceStatus. Well, windows audio’s call capabilities are hard coded, the only way that it would not be marked as stoppable is if something went wrong with the registration.
I wonder if somehow the DLL that holds the windows audio service didn’t get updated with the SP2 installation. So I start explorer up on c:\windows\system32 and look at the windows audio DLL. It’s got a file version of 6.0.4017. That’s wrong; it should have a version of 5.1.2600.2180. 6.0.4017 is a Longhorn version number.
So I asked the person having the problem if he’d done anything that might have caused a longhorn version of audiosrv to be put on his machine. It turns out that he’d run an internal install script that copied over an interim Longhorn build of this DLL onto his machine.
And, since SP2’s install didn’t replace the file (because the file version on the file on his machine was newer than the SP2 version of the file), he was running a Longhorn version of the windows audio service on his XP SP2 machine.
We deleted the DLL, SFP copied back the right version and his machine had audio again!
Edit: Fixed screwy text.