[SOLVED] COM help!

Just starting out? Need help? Post your questions and find answers here.
AndyMK
Enthusiast
Enthusiast
Posts: 582
Joined: Wed Jul 12, 2006 4:38 pm
Location: UK

[SOLVED] COM help!

Post by AndyMK »

Hi. I am trying to Enumerate audio sessions on an audio device. The code below works fine until it gets to

Code: Select all

sessionMgr\GetSessionEnumerator(@sessionList)
Can anyone take a look?
Thanks

Code: Select all

EnableExplicit

#CLSCTX_ALL    = #CLSCTX_INPROC_SERVER | #CLSCTX_INPROC_HANDLER | #CLSCTX_LOCAL_SERVER | #CLSCTX_REMOTE_SERVER

Interface IMMDeviceEnumerator Extends IUnknown
  EnumAudioEndpoints(dataFlow, dwStateMask, ppDevices)
  GetDefaultAudioEndpoint(dataFlow, role, ppEndpoint)
  GetDevice(pwstrId, ppDevice)
  RegisterEndpointNotificationCallback(pClient)
  UnregisterEndpointNotificationCallback(pClient)
EndInterface

Interface IMMDevice Extends IUnknown
  Activate(iid, dwClsCtx, pActivationParams, ppInterface)
  OpenPropertyStore(stgmAccess, ppProperties)
  GetId(ppstrId)
  GetState(pdwState)
EndInterface

Interface IAudioSessionManager2 Extends IUnknown
  GetSessionEnumerator(SessionEnum)
  RegisterDuckNotification(sessionID, duckNotification)
  RegisterSessionNotification(Notification)
  UnregisterDuckNotification(duckNotification)
  UnregisterSessionNotification(Notification)
EndInterface

Interface IAudioSessionNotification Extends IUnknown
  OnSessionCreated(NewSession)
EndInterface

Interface IAudioSessionControl2 Extends IUnknown
  GetState(State)
  GetDisplayName(Name)
  SetDisplayName(Name, EventContext)
  GetIconPath(Path)
  SetIconPath(Path.p-unicode, EventContext)
  GetSessionIdentifier(Identifier)
  GetSessionInstanceIdentifier(Identifier)
  GetProcessId(pid)
  IsSystemSoundsSession()
  SetDuckingPreference(Preference)
EndInterface

Interface IAudioSessionEnumerator Extends IUnknown
  GetCount(count)
  GetSession(sessionCount, session)
EndInterface

Global deviceEnumerator.IMMDeviceEnumerator
Global defaultRender.IMMDevice
Global sessionMgr.IAudioSessionManager2
Global sessionList.IAudioSessionEnumerator
Global MyAudioSessionNotification.IAudioSessionNotification

Procedure CreateSessionManager()
  Protected hr
  
  hr = CoCreateInstance_(?uuidof_MMDeviceEnumerator, #Null, #CLSCTX_INPROC_SERVER, ?uuidof_IMMDeviceEnumerator, @deviceEnumerator)
  If hr <> #S_OK
    Debug "CoCreateInstance_(MMDeviceEnumerator) failed, hr=" + Hex(hr)
  EndIf
    
  hr = deviceEnumerator\GetDefaultAudioEndpoint(0, 0, @defaultRender)
  If hr <> #S_OK
    Debug "GetDefaultAudioEndpoint(eRender) failed, hr=" + Hex(hr)
  EndIf
  
  If defaultRender\Activate(?IID_IAudioSessionManager2, #CLSCTX_ALL, #Null, @sessionMgr) <> #S_OK
    Debug "Activate IAudioSessionManager2 failed"
  EndIf
  
  sessionMgr\AddRef()
  
  sessionMgr\Release()
  deviceEnumerator\Release()
  defaultRender\Release()
  
  ProcedureReturn hr
  
EndProcedure

Procedure MTAThread(val)
  Define count.l, session
  
  Protected hr = CoInitializeEx_(#Null, #COINIT_MULTITHREADED)
  If hr <> #S_OK And hr <> #RPC_E_CHANGED_MODE
    Debug "CoInitializeEx_ in new thread failed, hr=" + Hex(hr)
    ProcedureReturn
  EndIf
  
  If CreateSessionManager() = #S_OK
    If sessionMgr\GetSessionEnumerator(@sessionList) = #S_OK
      Debug sessionList; <--- 0??
    Else
      Debug "Get Session Enumerator failed"
    EndIf
  EndIf
  
; Main loop
;   Repeat
;     Delay(1000)
;   ForEver
  
  sessionList\Release()
  CoUninitialize_()
  End

EndProcedure

CreateThread(@MTAThread(), 0)

Repeat
  Delay(1000)
ForEver

DataSection
  uuidof_MMDeviceEnumerator:
  Data.l $BCDE0395
  Data.w $E52F, $467C
  Data.b $8E, $3D, $C4, $57, $92, $91, $69, $2E
  
  uuidof_IMMDeviceEnumerator:
  Data.l $A95664D2
  Data.w $9614, $4F35
  Data.b $A7, $46, $DE, $8D, $B6, $36, $17, $E6
  
  IID_IAudioSessionManager2:
  Data.l $77AA99A0
  Data.w $1BD6, $484F
  Data.b $8B, $C7, $2C, $65, $4C, $9A, $9B, $6F
  
  IID_IAudioSessionNotification:
  Data.l $641DD20B
  Data.w $4D41, $49CC
  Data.b $AB, $A3, $17, $4B, $94, $77, $BB, $08
  
  IID_IAudioSessionEnumerator:
  Data.l $E2F5BB11
  Data.w $0570, $40CA
  Data.b $AC, $DD, $3A, $A0, $12, $77, $DE, $E8
  
  IID_IAudioSessionControl:
  Data.l $F4B1A599
  Data.w $7266, $4319
  Data.b $A8, $CA, $E7, $0A, $CB, $11, $E8, $CD
  
  IID_IAudioSessionControl2:
  Data.l $BFB7FF88
  Data.w $7239, $4FC9
  Data.b $8D, $A2, $B2, $7C, $48, $D6, $9D, $5D
EndDataSection
Last edited by AndyMK on Wed Feb 05, 2025 12:47 pm, edited 1 time in total.
fryquez
Enthusiast
Enthusiast
Posts: 391
Joined: Mon Dec 21, 2015 8:12 pm

Re: COM help!

Post by fryquez »

The inferaces are wrong defined.

Code: Select all

Interface IAudioSessionManager2 Extends IUnknown
  GetSessionEnumerator(SessionEnum)
  RegisterDuckNotification(sessionID, duckNotification)
  RegisterSessionNotification(Notification)
  UnregisterDuckNotification(duckNotification)
  UnregisterSessionNotification(Notification)
EndInterface
Here you missing the 2 functions from IAudioSessionManager.
Also make sure you look at the header files (audiopolicy.h) for the correct vtable order.
Microsoft websites often have them in wrong order.
AndyMK
Enthusiast
Enthusiast
Posts: 582
Joined: Wed Jul 12, 2006 4:38 pm
Location: UK

Re: COM help!

Post by AndyMK »

Thanks, that was the problem. I didn't know Microsoft didn't include all the methods for an interface in the docs. damn!
*EDIT*
I see what i did. IAudioSessionManager2 inherits from IAudioSessionManager not IUnknown.
Post Reply