Matthew van Eerde's web log

  • Matthew van Eerde's web log

    More on IAudioSessionControl and IAudioSessionControl2, plus: how to log a GUID

    • 0 Comments

    A while back I blogged about using IAudioSessionControl and IAudioSessionControl2 to get a list of active sessions, and then using IAudioMeterInformation to see what the amplitude level of the audio being played from each session was.

    I decided to go back and push this a little further and see what information there was to dig out. Pseudocode:

    CoCreate(IMMDeviceEnumerator)
    MMDevice = IMMDeviceEnumerator::GetDefaultAudioEndpoint(...)
    AudioSessionManager2 = MMDevice::Activate(...)
    AudioSessionEnumerator = AudioSessionManager2::GetSessionEnumerator()

    for each session in AudioSessionEnumerator {
        AudioSessionControl = AudioSessionEnumerator::GetSession(...)
        if (AudioSessionStateActive != AudioSessionControl::GetState()) { continue; }

        AudioSessionControl::GetIconPath (usually blank)
        AudioSessionControl::GetDisplayName (usually blank)
        AudioSessionControl::GetGroupingParam

        AudioSessionControl2 = AudioSessionControl::QueryInterface(...)
        AudioSessionControl2::GetSessionIdentifier (treat this as an opaque string)
        AudioSessionControl2::GetSessionInstanceIdentifier (treat this as an opaque string)
        AudioSessionControl2::GetProcessId (some sessions span multiple processes)
        AudioSessionControl2::IsSystemSoundsSession

        AudioMeterInformation = AudioSessionControl::QueryInterface(...)
        AudioMeterInformation::GetPeakValue

        for each top level window in the process pointed to by AudioSessionControl2::GetProcessId {
            Use WM_GETTEXTLENGTH and WM_GETTEXT to get the window text, if any
        }
    }

    Here's the output of the new version of meters.exe.

    >meters.exe
    -- Active session #1 --
        Icon path:
        Display name:
        Grouping parameter: {a204c0ad-03c4-4754-8e8f-92843aacb1fa}
        Process ID: 11812 (single-process)
        Session identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|\Device\HarddiskVolume1\Windows\System32\WWAHost.exe%b{00000000-0000-0000-0000-000000000000}
        Session instance identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|\Device\HarddiskVolume1\Windows\System32\WWAHost.exe%b{00000000-0000-0000-0000-000000000000}|1%b11812
        System sounds session: no
        Peak value: 0.2837

    -- Active session #2 --
        Icon path:
        Display name:
        Grouping parameter: {a2e2e0f5-81bb-407e-b701-f4f3695f9dac}
        Process ID: 15148 (single-process)
        Session identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|\Device\HarddiskVolume1\Program Files (x86)\Internet Explorer\iexplore.exe%b{00000000-0000-0000-0000-000000000000}
        Session instance identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|\Device\HarddiskVolume1\Program Files (x86)\Internet Explorer\iexplore.exe%b{00000000-0000-0000-0000-000000000000}|1%b15148
        System sounds session: no
        Peak value: 0.428589
        HWND: 0x0000000001330B12
        HWND: 0x0000000000361CA2
        HWND: 0x00000000019A07A8
        HWND: 0x0000000001411BF2
        HWND: 0x0000000000B60706
        HWND: 0x000000000231165A
        HWND: 0x0000000002631472
        HWND: 0x0000000000441D94

    -- Active session #3 --
        Icon path:
        Display name:
        Grouping parameter: {e191c91d-dc24-468d-b542-0d5f12ce8c48}
        Process ID: 2324 (multi-process)
        Session identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|#%b{48FF2ED2-2CE8-40FB-AEF7-31FEFDBA7EF2}
        Session instance identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|#%b{48FF2ED2-2CE8-40FB-AEF7-31FEFDBA7EF2}|1%b#
        System sounds session: no
        Peak value: 0.294137
        HWND: 0x0000000002900C86 Windows Media Player

    -- Active session #4 --
        Icon path: @%SystemRoot%\System32\AudioSrv.Dll,-203
        Display name: @%SystemRoot%\System32\AudioSrv.Dll,-202
        Grouping parameter: {e7d6e107-ca03-4660-a067-1a1f3dc1619c}
        Process ID: 0 (multi-process)
        Session identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|#%b{A9EF3FD9-4240-455E-A4D5-F2B3301887B2}
        Session instance identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|#%b{A9EF3FD9-4240-455E-A4D5-F2B3301887B2}|1%b#
        System sounds session: yes
        Peak value: 0.0502903

    -- Active session #5 --
        Icon path:
        Display name:
        Grouping parameter: {2a3e30fb-2ded-471e-9c2f-cbd8572b2af2}
        Process ID: 15948 (single-process)
        Session identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|\Device\HarddiskVolume1\Program Files (x86)\VideoLAN\VLC\vlc.exe%b{00000000-0000-0000-0000-000000000000}
        Session instance identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|\Device\HarddiskVolume1\Program Files (x86)\VideoLAN\VLC\vlc.exe%b{00000000-0000-0000-0000-000000000000}|1%b15948
        System sounds session: no
        Peak value: 0.287567
        HWND: 0x0000000000C8160C Opening Ceremony - VLC media player

    Active sessions: 5

    Part of this was logging the grouping parameter, which is a GUID. I've seen a lot of code that converts the GUID to a string and logs it using %s. Another way is to use a couple of macros and let the format string do the conversion for you:

    #define GUID_FORMAT L"{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"
    #define GUID_VALUES(g) \
    g.Data1, g.Data2, g.Data3, \
    g.Data4[0], g.Data4[1], g.Data4[2], g.Data4[3], \
    g.Data4[4], g.Data4[5], g.Data4[6], g.Data4[7]

    ...

    GUID someGuid = ...;

    LOG(L"The value of someGuid is " GUID_FORMAT L".", GUID_VALUES(someGuid));

    Standard caveats about not using side effects inside a macro apply. For example, this would be a bug:

    for (GUID *p = ...) {
        LOG(L"p = " GUID_FORMAT L".", GUID_VALUES(*(p++)); // BUG!
    }

     Source, amd64 binaries, and x86 binaries attached.

     

  • Matthew van Eerde's web log

    Getting the package full name of a Windows Store app, given the process ID

    • 0 Comments

    Last time I talked about enumerating audio sessions and showed an example which listed several Desktop apps and one Windows Store app.

    Session instance identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|\Device\HarddiskVolume1\Windows\System32\WWAHost.exe%b{00000000-0000-0000-0000-000000000000}|1%b11812

    It's possible to guess that this is a Windows Store app by the presence of the WWAHost.exe string in the session instance identifier. Don't rely on this, though; the session identifiers are opaque strings, and their formula can change at any time.

    We were able to get some additional information on the Desktop apps by enumerating their top-level windows and reading the window text. But how do we get more information on the Windows Store app? And how do we even know it's a Windows Store app without cracking the session identifier?

    By using the Application Model APIs - for example, GetPackageFullName.

    Pseudocode:

    ... get a process ID...

    OpenProcess(PROCESS_QUERY_LIMITED_USER_INFORMATION, FALSE, pid);

    GetPackageFullName(...)

    if APPMODEL_ERROR_NO_PACKAGE then the process has no associated package and is therefore not a Windows Store app.

    Updated sample output:

    -- Active session #4 --
    Icon path:
    Display name:
    Grouping parameter: {8dbd87b0-9fce-4c27-b7ff-4b20b0dae1a3}
    Process ID: 11644 (single-process)
    Session identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|\Device\HarddiskVolume1\Windows\System32\WWAHost.exe%b{00000000-0000-0000-0000-000000000000}
    Session instance identifier: {0.0.0.00000000}.{125eeed2-3cd2-48cf-aac9-8ae0157564ad}|\Device\HarddiskVolume1\Windows\System32\WWAHost.exe%b{00000000-0000-0000-0000-000000000000}|1%b11644
    System sounds session: no
    Peak value: 0.395276
    Package full name: Microsoft.ZuneMusic_2.0.132.0_x64__8wekyb3d8bbwe

    Source and binaries attached.

Page 1 of 1 (2 items)

August, 2013