Invalid mem access when I use COM

Just starting out? Need help? Post your questions and find answers here.
clover
User
User
Posts: 14
Joined: Tue Dec 30, 2008 4:43 am

Invalid mem access when I use COM

Post by clover »

The OS is Windows 7, I wanna control the system's volume. So after referring to some demo code, I tried to edit my code as follows. But unfortunately, I encountered invalid memory access reported by the compiler. I don't know what was wrong with my code, so please help me.

Code: Select all

#CLSCTX_INPROC_SERVER  = $01
#CLSCTX_INPROC_HANDLER = $02
#CLSCTX_LOCAL_SERVER   = $04
#CLSCTX_REMOTE_SERVER  = $10

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


Macro FAILED(status)
    ((status) < 0)
EndMacro

Macro SUCCEEDED(status)
    ((status) >= 0)
EndMacro


Macro DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) 
    name.GUID
    name\Data1 = l
    name\Data2 = w1
    name\Data3 = w2
    name\Data4[0] = b1
    name\Data4[1] = b2
    name\Data4[2] = b3
    name\Data4[3] = b4
    name\Data4[4] = b5
    name\Data4[5] = b6
    name\Data4[6] = b7
    name\Data4[7] = b8
EndMacro


;EDataFlow
Enumeration
    #eRender = 0
    #eCapture = 1
    #eAll = 2
    #EDataFlow_enum_count = 3
EndEnumeration 


;ERole
Enumeration
    #eConsole = 0
    #eMultimedia = 1
    #eCommunications = 2
    #ERole_enum_count = 3
EndEnumeration 


Interface IMMDevice Extends IUnknown
    Activate.l(*iid.IID, dwClsCtx.l, *pActivationParams, *ppInterface)
    GetId.l(*pwstrId.String)
    GetState.l(*pdwState.l)
    ;OpenPropertyStore.l(stgmAccess.l, *ppProperties.IPropertyStore)
EndInterface


Interface IMMDeviceEnumerator Extends IUnknown
    ;EnumAudioEndpoints.l(dataFlow.l, dwStateMask.l, *ppDevices.IMMDeviceCollection)
    GetDefaultAudioEndpoint.l(dataFlow.l, role.l, *ppDevice.IMMDevice)
    GetDevice.l(pwstrId.l, *ppDevice.IMMDevice)
    ;RegisterEndpointNotificationCallback.l(*pNotify.IMMNotificationClient)
    ;UnregisterEndpointNotificationCallback.l(*pNotify.IMMNotificationClient)
EndInterface


Interface IAudioEndpointVolume Extends IUnknown
    GetChannelCount.l(*pnChannelCount.l)
    GetChannelVolumeLevel.l(nChannel.l, *pfLevelDB.f)
    GetChannelVolumeLevelScalar.l(nChannel.l, *pfLevel.f)
    GetMasterVolumeLevel.l(*pfLevelDB.f)
    GetMasterVolumeLevelScalar.l(*pfLevel.f)
    GetMute.l(*pbMute.l)
    GetVolumeRange.l(*pfLevelMinDB.f, *pfLevelMaxDB.f, *pfVolumeIncrementDB.f)
    GetVolumeStepInfo.l(*pnStep.l, *pnStepCount.l)
    QueryHardwareSupport.l(*pdwHardwareSupportMask.l)
    ;RegisterControlChangeNotify.l(*pNotify.IAudioEndpointVolumeCallback)
    SetChannelVolumeLevel.l(nChannel.l, fLevelDB.f, *pguidEventContext.GUID)
    SetChannelVolumeLevelScalar.l(nChannel.l, fLevel.f, *pguidEventContext.GUID)
    SetMasterVolumeLevel.l(fLevelDB.f, *pguidEventContext.GUID)
    SetMasterVolumeLevelScalar.l(fLevel.f, *pguidEventContext.GUID)
    SetMute.l(bMute.l, *pguidEventContext.GUID)
    ;UnregisterControlChangeNotify.l(*pNotify.IAudioEndpointVolumeCallback)
    VolumeStepDown.l(*pguidEventContext.GUID)
    VolumeStepUp.l(*pguidEventContext.GUID)
EndInterface



Procedure VolumeVista(delta.l)
    CoInitialize_(#Null)

    hRes.l
    *ide.IMMDeviceEnumerator
    DEFINE_GUID(CLSID_MMDeviceEnumerator, $BCDE0395, $E52F, $467C, $8E, $3D, $C4, $57, $92, $91, $69, $2E)
    DEFINE_GUID(IID_IMMDeviceEnumerator, $A95664D2, $9614, $4F35, $A7, $46, $DE, $8D, $B6, $36, $17, $E6)
    hRes = CoCreateInstance_(@CLSID_MMDeviceEnumerator, #Null, #CLSCTX_ALL, @IID_IMMDeviceEnumerator, @*ide)
    If SUCCEEDED(hRes)
        *immd.IMMDevice
        hRes = *ide\GetDefaultAudioEndpoint(#eRender, #eMultimedia, @*immd)
        If SUCCEEDED(hRes)
            *iaev.IAudioEndpointVolume
            DEFINE_GUID(IID_IAudioEndpointVolume, $5CDF2C82, $841E, $4546, $97, $22, $0C, $F7, $40, $78, $22, $9A)
            hRes = *immd\Activate(@IID_IAudioEndpointVolume, #CLSCTX_ALL, #Null, @*iaev)
            If SUCCEEDED(hRes)
                ;No matter what function of IAudioEndpointVolume is invoked here, error happened.
                
                *iaev\Release()
            EndIf
            *immd\Release()
        EndIf
        *ide\Release()
    EndIf
    
    CoUninitialize_()
EndProcedure
clover
User
User
Posts: 14
Joined: Tue Dec 30, 2008 4:43 am

Re: Invalid mem access when I use COM

Post by clover »

I've managed to resolve it. The methods of a interface must be declared in proper order. e.g.

Code: Select all

Interface IMMDevice Extends IUnknown
    Activate.l(*iid.IID, dwClsCtx.l, *pActivationParams, *ppInterface)
    OpenPropertyStore.l(stgmAccess.l, *ppProperties.IPropertyStore)
    GetId.l(*pwstrId.String)
    GetState.l(*pdwState.l)
EndInterface


Interface IMMDeviceEnumerator Extends IUnknown
    EnumAudioEndpoints.l(dataFlow.l, dwStateMask.l, *ppDevices.IMMDeviceCollection)
    GetDefaultAudioEndpoint.l(dataFlow.l, role.l, *ppDevice.IMMDevice)
    GetDevice.l(pwstrId.l, *ppDevice.IMMDevice)
    RegisterEndpointNotificationCallback.l(*pNotify.IMMNotificationClient)
    UnregisterEndpointNotificationCallback.l(*pNotify.IMMNotificationClient)
EndInterface


Interface IAudioEndpointVolume Extends IUnknown
    RegisterControlChangeNotify.l(*pNotify.IAudioEndpointVolumeCallback)
    UnregisterControlChangeNotify.l(*pNotify.IAudioEndpointVolumeCallback)
    GetChannelCount.l(*pnChannelCount.l)
    SetMasterVolumeLevel.l(fLevelDB.f, *pguidEventContext.GUID)
    SetMasterVolumeLevelScalar.l(fLevel.f, *pguidEventContext.GUID)
    GetMasterVolumeLevel.l(*pfLevelDB.f)
    GetMasterVolumeLevelScalar.l(*pfLevel.f)
    SetChannelVolumeLevel.l(nChannel.l, fLevelDB.f, *pguidEventContext.GUID)
    SetChannelVolumeLevelScalar.l(nChannel.l, fLevel.f, *pguidEventContext.GUID)
    GetChannelVolumeLevel.l(nChannel.l, *pfLevelDB.f)
    GetChannelVolumeLevelScalar.l(nChannel.l, *pfLevel.f)
    SetMute.l(bMute.l, *pguidEventContext.GUID)
    GetMute.l(*pbMute.l)
    GetVolumeStepInfo.l(*pnStep.l, *pnStepCount.l)
    VolumeStepUp.l(*pguidEventContext.GUID)
    VolumeStepDown.l(*pguidEventContext.GUID)
    QueryHardwareSupport.l(*pdwHardwareSupportMask.l)
    GetVolumeRange.l(*pfLevelMinDB.f, *pfLevelMaxDB.f, *pfVolumeIncrementDB.f)
EndInterface
Post Reply