Opened 10 years ago
Closed 3 years ago
#3159 closed Bug (Fixed)
ObjCreateInterface and BOOL type.
| Reported by: | Valik | Owned by: | Jon |
|---|---|---|---|
| Milestone: | Component: | AutoIt | |
| Version: | 3.3.14.0 | Severity: | None |
| Keywords: | Cc: |
Description
Apologies for the large script but this is the minimum I could get it down to to demonstrate the bug.
; Interface description for IMMDeviceEnumerator.
Global Const $__Audio_CLSID_MMDeviceEnumerator = "{BCDE0395-E52F-467C-8E3D-C4579291692E}"
Global Const $__Audio_IID_IMMDeviceEnumerator = "{A95664D2-9614-4F35-A746-DE8DB63617E6}"
Global Const $__Audio_tagIMMDeviceEnumerator = "EnumAudioEndpoints hresult(dword;dword;ptr*);" & _
"GetDefaultAudioEndpoint hresult(dword;dword;ptr*);" & _
"GetDevice hresult(wstr;ptr*);" & _
"RegisterEndpointNotificationCallback hresult(ptr);" & _
"UnregisterEndpointNotificationCallback hresult(ptr);"
; Interface description for IMMDevice.
Global Const $__Audio_IID_IMMDevice = "{D666063F-1587-4E43-81F1-B948E807363F}"
Global Const $__Audio_tagIMMDevice = "Activate hresult(clsid;dword;variant*;ptr*);" & _
"OpenPropertyStore hresult(dword;ptr*);" & _
"GetId hresult(ptr*);" & _
"GetState hresult(dword*);"
; Interface description for IAudioEndpointVolume
Global Const $__Audio_IID_IAudioEndpointVolume = "{5CDF2C82-841E-4546-9722-0CF74078229A}"
Global Const $__Audio_tagIAudioEndpointVolume = "RegisterControlChangeNotify hresult(ptr);" & _
"UnregisterControlChangeNotify hresult(ptr);" & _
"GetChannelCount hresult(UINT*);" & _
"SetMasterVolumeLevel hresult(float;ptr);" & _
"SetMasterVolumeLevelScalar hresult(float;ptr);" & _
"GetMasterVolumeLevel hresult(float*);" & _
"GetMasterVolumeLevelScalar hresult(float*);" & _
"SetChannelVolumeLevel hresult(UINT;float;ptr);" & _
"SetChannelVolumeLevelScalar hresult(UINT;float;ptr);" & _
"GetChannelVolumeLevel hresult(UINT;float*);" & _
"GetChannelVolumeLevelScalar hresult(UINT;float*);" & _
"SetMute hresult(BOOL;ptr);" & _ ; <--- This method doesn't work. Change "BOOL" to "int" and it suddenly works agian.
"GetMute hresult(BOOL*);" & _
"GetVolumeStepInfo hresult(UINT*;UINT*);" & _
"VolumeStepUp hresult(ptr);" & _
"VolumeStepDown hresult(ptr);" & _
"QueryHardwareSupport hresult(DWORD*);" & _
"GetVolumeRange hresult(float*;float*;float*);"
Global Const $__Audio_eRender = 0
Global Const $__Audio_eMultimedia = 1
Global Const $__AUDIO_CLSCTX_ALL = BitOR(0x1, 0x2, 0x4, 0x10) ; CLSCTX_INPROC_SERVER, CLSCTX_INPROC_HANDLER, CLSCTX_LOCAL_SERVER, CLSCTX_REMOTE_SERVER
Func Audio_GetDefaultAudioEndpoint()
Local $oEnumerator = ObjCreateInterface($__Audio_CLSID_MMDeviceEnumerator, $__Audio_IID_IMMDeviceEnumerator, $__Audio_tagIMMDeviceEnumerator)
Local $pEndpoint
$oEnumerator.GetDefaultAudioEndpoint($__Audio_eRender, $__Audio_eMultimedia, $pEndpoint)
Local $oEndpoint = ObjCreateInterface($pEndpoint, $__Audio_IID_IMMDevice, $__Audio_tagIMMDevice)
Local $pID, $sId
; Collect ID
$oEndpoint.GetId($pID)
$sId = DllStructGetData(DllStructCreate("wchar ID[" & __Audio_WinAPI_PtrStringLenW($pID) & "]", $pID), "ID")
__Audio_WinAPI_CoTaskMemFree($pID)
Return $sId
EndFunc ; Audio_GetDefaultAudioEndpoint()
Func Audio_SetDeviceMute($sDeviceID, $bMute)
; Create the IMMDeviceEnumerator object.
Local $oEnumerator = ObjCreateInterface($__Audio_CLSID_MMDeviceEnumerator, $__Audio_IID_IMMDeviceEnumerator, $__Audio_tagIMMDeviceEnumerator)
; Get device pointer.
Local $pDevice
$oEnumerator.GetDevice($sDeviceID, $pDevice)
; Convert the device pointer into an object.
Local $oDevice = ObjCreateInterface($pDevice, $__Audio_IID_IMMDevice, $__Audio_tagIMMDevice)
; Get the IAudioEndpointVolume pointer.
Local $pAudioEndpointVolume
$oDevice.Activate($__Audio_IID_IAudioEndpointVolume, $__AUDIO_CLSCTX_ALL, 0, $pAudioEndpointVolume)
; Convert the IAudioEndpointVolume pointer into an object.
Local $oAudioEndpointVolume = ObjCreateInterface($pAudioEndpointVolume, $__Audio_IID_IAudioEndpointVolume, $__Audio_tagIAudioEndpointVolume)
; Set the mute state.
$oAudioEndpointVolume.SetMute($bMute, 0)
EndFunc ; Audio_SetDeviceMute()
Func __Audio_WinAPI_CoTaskMemFree($pMem)
DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $pMem)
If @error Then Return SetError(1, 0, False)
Return True
EndFunc ; __Audio_WinAPI_CoTaskMemFree()
Func __Audio_WinAPI_PtrStringLenW($pString)
Local $aCall = DllCall("kernel32.dll", "dword", "lstrlenW", "ptr", $pString)
If @error Then Return SetError(1, 0, 0)
Return $aCall[0]
EndFunc ; __Audio_WinAPI_PtrStringLenW()
Audio_SetDeviceMute(Audio_GetDefaultAudioEndpoint(), 1)
The last line is a called to Audio_SetDeviceMute() to mute the currently active audio device. The call worked fine in 3.3.8.1. With 3.3.14.0 and later (including 3.3.15.0) it doesn't work when I declare SetMute() as a BOOL:
SetMute hresult(BOOL;ptr);
If I change BOOL to int it works. It seems somewhere along the way AutoIt's conversion to BOOL in this case is failing. Passing a 0 will correctly unmute a muted device. Passing a 1 (the value of TRUE in the Windows SDK) fails.
To reiterate, this is a regression. It used to work fine. With the latest versions of AutoIt, it does not. Unfortunately I jumped straight from 3.3.8.1 to 3.3.14.0 so if it broke somewhere earlier I missed the exact build. I'm running Windows 10 x64 but this isn't OS specific.
Attachments (0)
Change History (4)
comment:1 Changed 8 years ago by Jpm
- Owner set to Jon
- Status changed from new to assigned
comment:2 Changed 5 years ago by Jpm
comment:3 Changed 5 years ago by Jpm
it looks like Jon as change something in the way it produce the code.
When I try to reproduce without signing the code X64 is working fine.
I hope JON can find why. I am running under Windows 10 (2004) and use the Visual studio 2017 (community)
Edited: I can add that my test don't use the code optimisation (PGO)
comment:4 Changed 3 years ago by Jpm
- Resolution set to Fixed
- Status changed from assigned to closed
It was related with code optimisation (PGO).
It has been fixed since 3.3.15.1 when Jon fix the PGO process
Guidelines for posting comments:
- You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
- In-depth discussions should take place on the forum.
For more information see the full version of the ticket guidelines here.

not working in X64 only after 3.3.12.0