VA_IAudioSessionControl2_GetProcessId hangs the script Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
uname
Posts: 23
Joined: 25 Oct 2013, 12:50

VA_IAudioSessionControl2_GetProcessId hangs the script

15 Jun 2020, 07:49

Recently I've noticed my main persistent script hangs sometimes, I've traced the issue to the VA_IAudioSessionControl2_GetProcessId call, the script below never show the Msgbox and can be closed by process termination only.

Code: Select all

IID_IAudioSessionManager2 := "{77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F}"

dev := VA_GetDevice()
VA_IMMDevice_Activate(dev, IID_IAudioSessionManager2, 7, 0, mgr)
ObjRelease(dev)
VA_IAudioSessionManager2_GetSessionEnumerator(mgr, enm)
ObjRelease(mgr)
VA_IAudioSessionEnumerator_GetSession(enm, 0, ssn)
VA_IAudioSessionControl2_GetProcessId(ssn, PID)
ObjRelease(ssn)
ObjRelease(enm)

MsgBox % PID
The code has worked flawlessly for last 8 years, something changed in my system and I can't find the problem myself
AHK 1.1.32.00 x64 and WIndows 10 x64 Pro 2004
User avatar
uname
Posts: 23
Joined: 25 Oct 2013, 12:50

Re: VA_IAudioSessionControl2_GetProcessId hangs the script

21 Jun 2020, 22:02

Can somebody test the code on Windows 10 2004 please.
lexikos
Posts: 9589
Joined: 30 Sep 2013, 04:07
Contact:

Re: VA_IAudioSessionControl2_GetProcessId hangs the script  Topic is solved

01 Jul 2020, 04:08

I have deleted the "duplicate" topic from Bug Reports. An issue in a user-defined function occurring after a Windows update is clearly not an AutoHotkey bug.

In this case, I'm fairly certain the issue is because you are making an invalid call. IAudioSessionEnumerator::GetSession() is documented as returning IAudioSessionControl, not IAudioSessionControl2. As the latter inherits from the former, you might get an IAudioSessionControl2 anyway, but it was never guaranteed. You must query for the correct interface with ComObjQuery.

On my system (Windows 2004) your script does not stall, but returns PID 0 for every session.
User avatar
uname
Posts: 23
Joined: 25 Oct 2013, 12:50

Re: VA_IAudioSessionControl2_GetProcessId hangs the script

01 Jul 2020, 16:36

Thank you!

So all this time my script was missing the lines

Code: Select all

VA_IAudioSessionEnumerator_GetSession(enm, 0, IAudioSessionControl)
ssn := ComObjQuery(IAudioSessionControl, "{BFB7FF88-7239-4FC9-8FA2-07C950BE9C6D}")
ObjRelease(IAudioSessionControl)
By the way, the source was posted here
Last edited by uname on 02 Jul 2020, 05:13, edited 1 time in total.
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: VA_IAudioSessionControl2_GetProcessId hangs the script

01 Jul 2020, 18:33

To get a reference to the IAudioSessionControl2 interface, the application must call IAudioSessionControl::QueryInterface to request the interface pointer from the stream object's IAudioSessionControl interface
https://docs.microsoft.com/en-us/windows/win32/api/audiopolicy/nn-audiopolicy-iaudiosessioncontrol2
It is not good that library va.ahk does not check errors.
lexikos
Posts: 9589
Joined: 30 Sep 2013, 04:07
Contact:

Re: VA_IAudioSessionControl2_GetProcessId hangs the script

03 Jul 2020, 21:33

@malcev, as with DllCall, if you pass invalid parameters, that's your problem. One can only check the type of an interface pointer if it is a valid interface pointer derived from IUnknown, which is the case here, but not for all invalid parameters. These functions are basic low level wrappers for interface methods. A higher level library is safer and has no need for interface type checks, because you do not deal with interface pointers - for instance, VA_GetMasterVolume("", "playback").

I don't know why you linked to IAudioSessionControl2. Anyone can find the documentation by searching.
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: VA_IAudioSessionControl2_GetProcessId hangs the script

05 Jul 2020, 19:38

lexikos wrote:
03 Jul 2020, 21:33
@malcev, as with DllCall, if you pass invalid parameters, that's your problem.
I do not agree with You.
If You add error checking then the topicstarter would get error, that will help him to understand that this error is not autohotkey bug, but error calling GetProcessId method.
ERROR_SXS_KEY_NOT_FOUND

Code: Select all

VA_IAudioSessionControl2_GetProcessId(this, ByRef pid)
{
   hr := DllCall(NumGet(NumGet(this+0)+14*A_PtrSize), "ptr", this, "uint*", pid)
   if hr or ErrorLevel
      msgbox % hr "`n" ErrorLevel "`n" A_LastError
}
lexikos
Posts: 9589
Joined: 30 Sep 2013, 04:07
Contact:

Re: VA_IAudioSessionControl2_GetProcessId hangs the script

06 Jul 2020, 05:10

There is no guarantee that calling an invalid virtual function will result in an error code return. You don't even know which function you're calling, or that there's even a function at that slot in the virtual function table. The added error checking would be a waste of space, because passing an invalid interface pointer still means that the program logic cannot be relied upon. Worse, it would mislead you into thinking the function will protect you from your own mistakes.

If you pass an invalid interface pointer, there is no guarantee that you will even be able to get far enough to attempt to call the function.
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: VA_IAudioSessionControl2_GetProcessId hangs the script

06 Jul 2020, 05:36

There is no guarantee, but there is a small chance that when You call invalid virtual function or You pass invalid parameters You will not get error code.
When I worked with complex Directx11 and Microsoft Media Foundation stuff, error checking helps me understand what I did wrong.
And there was situation when method`s return value was OK, but Errorlevel = 0xc0000005 (because of old videocard driver I think).
By the way if You think that error checking is waste of space why did You check each method for errors in Your directx wrapper?

Code: Select all

ERRq(....)
https://www.autohotkey.com/boards/viewtopic.php?t=28834
Rolz73
Posts: 1
Joined: 16 Aug 2020, 10:02

Re: VA_IAudioSessionControl2_GetProcessId hangs the script

16 Aug 2020, 10:08

Just to confirm if anyone else wondering, adding the following line (as described above) is what fixed a script of mine getting the PID of an audio player for the purpose of setting its volume AFTER I had updated to Windows 10 2004:

Code: Select all

ssn := ComObjQuery(IAudioSessionControl, "{BFB7FF88-7239-4FC9-8FA2-07C950BE9C6D}")
Thank you
lexikos
Posts: 9589
Joined: 30 Sep 2013, 04:07
Contact:

Re: VA_IAudioSessionControl2_GetProcessId hangs the script

16 Aug 2020, 23:07

malcev wrote:
06 Jul 2020, 05:36
By the way if You think that error checking is waste of space why did You check each method for errors in Your directx wrapper?

Code: Select all

ERRq(....)
https://www.autohotkey.com/boards/viewtopic.php?t=28834
You completely missed the point. Type checking via Query relies on the parameter being a valid COM interface pointer. It makes no sense to add a check for a specific subset of *invalid values* especially when that check carries the risk of crashing the script for some other subset of invalid values. In no way did I ever indicate that error checking *in general* is a waste of space.

ERRq checks for error codes which may be returned when the function is used correctly. It does not guard against violation of the basic requirements for using the method. Also, that code was written over ten years ago.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Google [Bot], OrangeCat and 298 guests