Today, I just might ruffle a few feathers by doing so, but I figured I’d go through and demonstrate the process of reversing some incompletely documented stuff in Windows in order to fix a problem that was causing me some personal pain.
Specifically, I’m going to talk about sound schemes in Windows 7. With Windows Vista, we had only 1 sound scheme (unless you bought Ultimate, in which case the additional sound schemes were provided as Ultimate Extras). With Windows 7, you get multiple sound schemes.
And for a while, I was terrified of using any of them other than the one I had originally selected.
You see, every time I would change the sound scheme, I would lose sounds in a number of my other programs. Pretty much anything that wasn’t Windows. I like my computer making little beeps and boops all the time (seriously – I still add in the Office 97 sounds, because I like the audio feedback I get when deleting, moving copying – it feels bizarre not to have it after more than a decade of always hearing it).
When we released a whole bunch of new themes for Windows 7 on the day we reached General Availability, I had reached the last straw. The themes all changed my sound scheme, and I don’t want to lose the sound from my other programs thank you very much. So, I set out to figure out how to fix that.
Here’s a blog post that described how to set up the sounds:
Put sounds in .current, eh? Well, time to go spelunking. For the sounds that do switch around, I notice more in the registry than just .Current. I notice that each event not only has a .current subkey, it also has a subkey with the name of each of the sound schemes. So, it seems likely that everyone who adds a new set of application sounds would only affect the current sound scheme, and as soon as you changed it, those settings would go away!
A quick check with process monitor would confirm that:
8:08:59.2736148 PM rundll32.exe 4796 RegOpenKey HKCU\AppEvents\Schemes\Apps\Communicator\COMMUNICATOR_appinvite\Delta SUCCESS Desired Access: Maximum Allowed, Granted Access: All Access
8:08:59.2736558 PM rundll32.exe 4796 RegQueryValue HKCU\AppEvents\Schemes\Apps\Communicator\COMMUNICATOR_appinvite\Delta\(Default) BUFFER OVERFLOW Length: 144
8:08:59.2737043 PM rundll32.exe 4796 RegQueryValue HKCU\AppEvents\Schemes\Apps\Communicator\COMMUNICATOR_appinvite\Delta\(Default) SUCCESS Type: REG_SZ, Length: 172, Data: C:\Program Files (x86)\Microsoft Office Communicator\Media\COMMUNICATOR_appinvite.wav
8:08:59.2741839 PM rundll32.exe 4796 RegCloseKey HKCU\AppEvents\Schemes\Apps\Communicator\COMMUNICATOR_appinvite\Delta SUCCESS
8:09:00.4227580 PM rundll32.exe 4796 RegOpenKey HKCU\AppEvents\Schemes\Apps\Communicator\COMMUNICATOR_appinvite SUCCESS Desired Access: Maximum Allowed, Granted Access: All Access
8:09:00.4227946 PM rundll32.exe 4796 RegQueryKey HKCU\AppEvents\Schemes\Apps\Communicator\COMMUNICATOR_appinvite SUCCESS Query: HandleTags, HandleTags: 0x0
8:09:00.4228254 PM rundll32.exe 4796 RegCreateKey HKCU\AppEvents\Schemes\Apps\Communicator\COMMUNICATOR_appinvite\Delta SUCCESS Desired Access: Set Value
8:09:00.4228632 PM rundll32.exe 4796 RegSetValue HKCU\AppEvents\Schemes\Apps\Communicator\COMMUNICATOR_appinvite\Delta\(Default) SUCCESS Type: REG_SZ, Length: 172, Data: C:\Program Files (x86)\Microsoft Office Communicator\Media\COMMUNICATOR_appinvite.wav
8:09:00.4229075 PM rundll32.exe 4796 RegCloseKey HKCU\AppEvents\Schemes\Apps\Communicator\COMMUNICATOR_appinvite\Delta SUCCESS
8:09:00.4229383 PM rundll32.exe 4796 RegQueryKey HKCU\AppEvents\Schemes\Apps\Communicator\COMMUNICATOR_appinvite SUCCESS Query: HandleTags, HandleTags: 0x0
8:09:00.4229707 PM rundll32.exe 4796 RegCreateKey HKCU\AppEvents\Schemes\Apps\Communicator\COMMUNICATOR_appinvite\.current SUCCESS Desired Access: Set Value
8:09:00.4230081 PM rundll32.exe 4796 RegSetValue HKCU\AppEvents\Schemes\Apps\Communicator\COMMUNICATOR_appinvite\.Current\(Default) SUCCESS Type: REG_SZ, Length: 172, Data: C:\Program Files (x86)\Microsoft Office Communicator\Media\COMMUNICATOR_appinvite.wav
8:09:00.4230401 PM rundll32.exe 4796 RegCloseKey HKCU\AppEvents\Schemes\Apps\Communicator\COMMUNICATOR_appinvite\.Current SUCCESS
Yes, indeed – when you change the sound scheme, you copy the values over from the subkey with the new scheme name into the .current key. And none of the program sounds from external programs contained subkeys for each (or any) of the schemes!
So, I’m thinking I’ve reversed the secret to carrying my program sounds over from scheme to scheme – could it be that simple? Only one way to find out – populate them! But, if there were so few that I could do so easily by hand, then I wouldn’t be reversing this stuff in the first place. So, it looks like it’s time for a PowerShell Script! Here’s what I wrote:
foreach ($app in Get-ChildItem -Path “HKCU:\AppEvents\Schemes\Apps”)
if (($app.PSChildName -ne “.Default”) -and ($app.PSChildName -ne “Explorer”) -and ($app.PSChildName -ne “sapisvr”))
foreach ($events in Get-ChildItem -Path $app.PSPath)
$event = $events.PSPath
foreach ($soundSchemes in Get-ChildItem -Path “HKCU:\AppEvents\Schemes\Names”)
$soundScheme = $soundSchemes.PSChildName
if (($soundScheme -ne “.Default”) -and ($soundScheme -ne “.None”))
$defaultPath = $event + “\.current”
$newPath = $event + “\” + $soundScheme
if (Test-Path $newPath)
Remove-Item -Path $newPath
Copy-Item -Path $defaultPath -Destination $newPath
I ran this script, and tried changing my sound scheme. Sure enough, it worked! I was able to swap out my sound schemes, and the other applications which extend the sound scheme mechanism in Windows still generate the sounds which makes their use so much more satisfying! (Or, in the case of Communicator, it’s downright critical to the way I use the application.) Hooray!
Now, this is kind of a klugy workaround, which depends on my reversing and guessing correctly on a couple of things. What could we do differently? Well, ideally the application developer would have enumerated the schemes, which is something they wouldn’t have had to do with Windows Vista (except in the case of Ultimate Extras), and added their sound events to each of the schemes. But, it’s a little bit late for that now – these apps already exist. The sound schemes already exit, and there is no API we can intercept – the apps are just writing to the registry. So, if we wanted to do something about this within Windows, we’d have to do something proactive to mitigate the issue with other programs in response to a sound scheme change event. That’s getting a little bit harder to argue for in a service pack, but you never know. It’s worth a try at least.
For now, you can use my workaround, and carry your sounds around with you from scheme to scheme. Happy dinging!