﻿id	summary	reporter	owner	description	type	status	milestone	component	version	severity	resolution	keywords	cc
3159	ObjCreateInterface and BOOL type.	Valik	Jon	"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."	Bug	closed		AutoIt	3.3.14.0	None	Fixed		
