Question

I'm have written a C++ application that is running as a Windows service to limit the volume of a Windows 7 computer. The user can specify different rules for different days and times and the service will smoothly change the volume. To implement this I use the IAudioEndpointVolume interface. In general it works like intended...

However, there exists a strange behavior I cannot explain yet. When switching users the volume suddenly drops but it does not generate a notification as one would expect. What is also strange is that the sliders in the SndVol.exe show the correct value for the volume. Because of the missing notification my program cannot react to this change and as a result it cannot perform its intend anymore. I have discovered that the volume will switch back to its correct volume again if I move the volume slider a bit. Of course this generates a notification that will be handled by my service. My service will then force the correct volume.

I don't understand why the volume changes without being visible in SndVol.exe and without creating a notification. Switching back to the first user account does not solve the problem. Even after logging out the volume is still at the wrong level.

As far as I have seen the documentation about the IAudioEndpointVolume interface does not mention anything about different user session.

Any ideas on what might cause this problem or what I could try to fix it?

Was it helpful?

Solution 2

Well, after some time I am now quite confident that the volume change is caused by the 3rd party driver we are using. This driver has it's own volume control mechanism. I do not experience the change anymore after just starting the drivers' control GUI. Even after a restart the problem seems to be fixed. However, after some time it gets broken again for a reason I cannot figure out. But this only happened because some security settings prevented the drivers' control GUI to start when logged in as non admin. I fixed this now and expect everything to work now.

Furthermore it looks like that all user sessions share the same volume control. That means if I change the volume with SndVol in one user session the same change happens in the other user session. My service receives notifications for all these changes. So it looks like that I did not receive a notification when switching between users because the change was caused by the driver's control GUI starting when logging in as administrator. But this change happened in the driver, a lower layer, so that Windows is not aware of the change.

The driver we are using is the kX Audio Driver.

OTHER TIPS

Your service runs in session 0, the isolated session that prevents malware from exercising shatter attacks. The user's desktop runs in another session, there can be multiple. The WASAPI documentation is silent about exactly how an audio session gets mapped across Windows sessions. You have a very strong hint that it doesn't from the way it behaves.

There are ominous words in the section that talks about grouping parameters. A construct that primarily exists to allow Sndvol to identify processes that share the same volume control. It quotes Explorer as an example, a process that can be started more than once but still has a single volume control. A process that doesn't want to share uses session identifier GUID_NULL to select the default session in IAudioSessionControl::SetGroupingParam() or simply omits the call altogether since that's the default.

And the behavior of Sndvol, it only displays volume controls for the processes that run in the desktop session. You can't see the processes in another desktop session. Giving a very strong hint that audio session GUID_NULL is specific to the session in which it got created.

So quite unlikely that you can find a workaround for it as long as you do this with a service.

Instead, consider running your program as a normal windowless process that runs in the user's desktop session. Getting started by the Run registry key or a Startup folder shortcut or the task scheduler.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top