How Windows Sets the Default Audio Device


When a user right-clicks on the speaker icon in the Windows taskbar and selects say "Playback devices", the sound control panel starts up which comprises of entails running mmsys.cpl running under rundll32.exe with the following command line:

"C:\Windows\system32\rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,playback"

After this when the user selects a playback device iin the "Playback" property sheet and clicks "Set Default", the control panel plug-in DLL (MMsys.cpl) calls the function AUDIOSES!CPolicyConfigClient::SetDefaultEndpoint() to send an RPC/ALPC request to the Windows Audio Service to set the default device as selected by the user.

The Windows Audio Service is implemented in AudioSRV.dll which is hosted in the instance of SVCHost.exe running with the command line "svchost -k LocalServiceNetworkRestricted".

The RPC server side function AudioSRV!CPolicyConfig::SetDefaultEndpoint() calls the function MMDevAPI!CEndPointManager::SetDefaultEndpoint() which writes a timestamp to the values named "Role:0", "Role:1" and "Role:2" in the following registry key:

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\{GUID}

Where {GUID} represents an audio playback or capture device (endpoint) in the system and the numeric suffix to "Role" is a value from the enum ERole = {eConsole=0, eCommunications=1, eMultimedia=2}.

Each "Role" value contains the timestamp of when the device was last configured as the default device. This timestamp is retrieved by calling GetSystemTime() and is written out to the registry as the SYSTEMTIME structure. For example, the timestamp "DC 07 0C 00 03 00 05 00 0A 00 3A 00 15 00 43 03" can be interpreted as follows:

typedef struct _SYSTEMTIME {
  WORD wYear; // 07dc = 2012
  WORD wMonth; // 000c = 12 (December)
  WORD wDayOfWeek; //0003 = 3 (Wednesday)
  WORD wDay; // 0005 = 5
  WORD wHour; // 000a = 10 (Hour in UTC)
  WORD wMinute; // 003a = 58 
  WORD wSecond; // 0015 = 21
  WORD wMilliseconds; // 0343 = 835 
} SYSTEMTIME, *PSYSTEMTIME;

During audio playback the function MMDevAPI!CLocalEndpointEnumerator::GetDefaultEndpoint() picks the device (endpoint) with the latest timestamp as the default playback device.