# Copyright © 2015, Microsoft Corporation. All rights reserved. # :: ======================================================= :: <# DESCRIPTION: CL_Utility is common library for audio troubleshooter. ARGUMENTS: None RETURNS: None FUNCTIONS: Write-ExceptionTelemetry GetAdapterName GetAbsolutionPath Get-AudioDeviceCount Get-DeviceId Get-DeviceName Get-DeviceStateName Get-DeviceTypeName GetId GetRuntimePath GetSystemPath Parse-List RemoveDevice RescanAllDevices Set-DefaultEndpoint Get-AudioSamplingRate Start-AudioService Stop-AudioService Get-AudioDriverSource32 Get-AudioDriverSource PlaySound Get-HDAudioID Set-AudioEndpointProperty #> #==================================================================================== # Initialize #==================================================================================== Import-LocalizedData -BindingVariable localizationString -FileName CL_LocalizationData #==================================================================================== # Load Utilities #==================================================================================== . .\CL_AudioDiagnosticSnapIn.ps1 #==================================================================================== # Main #==================================================================================== function Pop-Msg { param([string]$msg ="message", [string]$ttl = "Title", [int]$type = 64) $popwin = new-object -comobject wscript.shell $null = $popwin.popup($msg,0,$ttl,$type) remove-variable popwin } Function Write-ExceptionTelemetry($FunctionName, [System.Management.Automation.ErrorRecord] $ex) { <# DESCRIPTION: Writes script error information into telemetry stream EXAMPLE: try { 0 / 0 } catch [System.Exception] { Write-ExceptionTelemetry "DivideByZeroTest" $_ } #> $ExceptionMessage = $ex.Exception.Message $ScriptFullPath = $ex.InvocationInfo.ScriptName $ExceptionScript = [System.IO.Path]::GetFileName($ScriptFullPath) $ExceptionScriptLine = $ex.InvocationInfo.ScriptLineNumber $ExceptionScriptColumn = $ex.InvocationInfo.OffsetInLine Write-DiagTelemetry "ScriptError" "$ExceptionScript\$FunctionName\$ExceptionScriptLine\$ExceptionScriptColumn\$ExceptionMessage" } function StartProcess([string]$deviceId) { $ExePath = [System.Environment]::SystemDirectory +"\" + "control.exe" Start-Process -FilePath $ExePath -ArgumentList "mmsys.cpl,,$deviceId,sysfx" } function GetAdapterName($deviceInfo=$("No device info is specified")) { return ($deviceInfo | Select-Object AdapterName).AdapterName } function GetAbsolutionPath([string]$fileName = $(throw "No file name is specified")) { if([string]::IsNullorEmpty($fileName)) { throw "Invalid file name" } return Join-Path (Get-Location).Path $fileName } function Get-AudioDeviceCount() { $audioDevices = Get-WmiObject Win32_SoundDevice [int]$deviceCount = ($audioDevices.Name).Count return $deviceCount } function Get-DeviceId([string]$deviceName, [string]$deviceTypes) { [string]$deviceID = [String]::Empty try { $devices = @() $EndPointListID = @() $AudioMethods = Get-AudioEndpoints $EndPointListID = $AudioMethods::GetAudioEndPointsbyType($deviceTypes) $devices += $EndPointListID.ForEach({[PSCustomObject]$_}) foreach($devs in $devices) { $devId = GetId $devs $devName = GetAdapterName $devs if($deviceName -contains $devName) { $deviceID = [string]$devId break } } } Catch [System.Exception] { Write-ExceptionTelemetry "GetDeviceId" $_ $errorMsg = $_.Exception.Message $errorMsg | ConvertTo-Xml | Update-DiagReport -Id "CL_Utility" -Name "CL_Utility" -Verbosity Debug } return $deviceID } # Function to get the localized device name function Get-DeviceName([string]$deviceType=$(throw "No device type is specified")) { [string]$deviceName = $localizationString.unknownAudioDevice if("Render" -eq $deviceType) { $deviceName = $localizationString.audioPlayback } if("Capture" -eq $deviceType) { $deviceName = $localizationString.audioRecording } return $deviceName } # Function to get the audio endpoint state name function Get-DeviceStateName([int]$stateCode=$(throw "No state code is specified")) { [string]$stateName = "" if(1 -eq $stateCode) { $stateName = $localizationString.stateEnabled } elseif (2 -eq $stateCode) { $stateName = $localizationString.stateDisabled } elseif (4 -eq $stateCode) { $stateName = $localizationString.stateNotPresent } elseif (8 -eq $stateCode) { $stateName = $localizationString.stateUnplugged } else { $stateName = $localizationString.stateUnknown } return $stateName } # Function to get the audio device type name function Get-DeviceTypeName([string]$deviceType = $(throw "No device type name is specified")) { [string]$deviceTypeName = "" if([String]::IsNullOrEmpty($deviceType)) { return $deviceTypeName } if($deviceType -eq "Render") { $deviceTypeName = $localizationString.speaker + ", " + $localizationString.headset + " " + $localizationString.or + " " + $localizationString.headphone } elseif ($deviceType -eq "Capture") { $deviceTypeName = $localizationString.microphone + " " + $localizationString.or + " " + $localizationString.headset } return $deviceTypeName } function GetId($deviceInfo=$("No device info is specified")) { return ($deviceInfo | Select-Object DeviceId).DeviceId } function GetRuntimePath([string]$fileName = $(throw "No file name is specified")) { if([string]::IsNullorEmpty($fileName)) { throw "Invalid file name" } [string]$runtimePath = [System.Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory() return Join-Path $runtimePath $fileName } function GetSystemPath([string]$fileName = $(throw "No file name is specified")) { if([string]::IsNullorEmpty($fileName)) { throw "Invalid file name" } [string]$systemPath = [System.Environment]::SystemDirectory return Join-Path $systemPath $fileName } # Function to import audio management types function Get-AudioManager { [string]$code = @' using System; using System.Runtime.InteropServices; namespace Microsoft.Windows.Diagnosis { public static class AudioConfigManager { [DllImport("AudioDiagnosticUtil.dll", CharSet = CharSet.Auto)] private static extern int AudioSetEndPointVisibility(string pszDeviceName, bool Status); [DllImport("AudioDiagnosticUtil.dll", CharSet = CharSet.Auto)] private static extern int AudioSetDefaultdevice(string pszDeviceName); [DllImport("AudioDiagnosticUtil.dll", CharSet = CharSet.Auto)] private static extern int SetAudioEndpointProperty(string pszDeviceName); [DllImport("AudioDiagnosticUtil.dll", CharSet = CharSet.Auto)] private static extern int IsEndpointDefault(string pszDeviceName, string pDataFlow, ref IntPtr IsDefault); [DllImport("AudioDiagnosticUtil.dll", CharSet = CharSet.Auto)] private static extern int GetDefaultEndpointID(string pDataFlow, ref IntPtr pDefaultId); [DllImport("AudioDiagnosticUtil.dll", CharSet = CharSet.Auto)] private static extern float GetMasterVolumeLevel(string dataflow, out float pLevel); [DllImport("AudioDiagnosticUtil.dll", CharSet = CharSet.Auto)] private static extern bool GetMute(string dataflow, ref bool pMute); [DllImport("AudioDiagnosticUtil.dll", CharSet = CharSet.Auto)] private static extern void SetMute(string dataflow, bool pMute); [DllImport("AudioDiagnosticUtil.dll", CharSet = CharSet.Auto)] private static extern void SetDeviceMute(string deviceId, bool pMute); [DllImport("AudioDiagnosticUtil.dll", CharSet = CharSet.Auto)] private static extern float GetDeviceMasterVolumeLevel(string deviceId, out float pLevel); [DllImport("AudioDiagnosticUtil.dll", CharSet = CharSet.Auto)] private static extern bool GetDeviceMute(string deviceId, ref bool pMute); public static string GetDefaultID(string dataFlow) { IntPtr pId = IntPtr.Zero; GetDefaultEndpointID(dataFlow, ref pId); string id = Marshal.PtrToStringAuto(pId); return id; } public static bool IsEndPointDefault(string deviceID, string dataFlow) { bool retBool = true; IntPtr pBool = IntPtr.Zero; IsEndpointDefault(deviceID, dataFlow, ref pBool); if (pBool.ToInt32() == 0) { retBool = false; } return retBool; } public static int SetAudioProperty(string pszDeviceName) { return AudioConfigManager.SetAudioEndpointProperty(pszDeviceName); } public static int EnableDevice(string pszDeviceName, bool Status) { return AudioConfigManager.AudioSetEndPointVisibility(pszDeviceName, Status); } public static int SetDefault(string pszDeviceName) { return AudioConfigManager.AudioSetDefaultdevice(pszDeviceName); } public static bool GetMuteStatus(string deviceId) { bool mute = false; AudioConfigManager.GetMute(deviceId,ref mute); return mute; } public static bool GetDeviceMuteStatus(string deviceId) { bool mute = false; AudioConfigManager.GetDeviceMute(deviceId,ref mute); return mute; } public static void SetMuteStatus(string deviceId, bool muteStatus) { AudioConfigManager.SetMute(deviceId, muteStatus); } public static void SetDeviceMuteStatus(string deviceID, bool muteStatus) { AudioConfigManager.SetDeviceMute(deviceID, muteStatus); } public static int GetVolume(string deviceId) { float retVal = 0.0f; AudioConfigManager.GetMasterVolumeLevel(deviceId, out retVal); return Convert.ToInt32(retVal * 100); } public static int GetDeviceVolume(string deviceId) { float retVal = 0.0f; AudioConfigManager.GetDeviceMasterVolumeLevel(deviceId, out retVal); return Convert.ToInt32(retVal * 100); } } } '@ Add-Type -TypeDefinition $code } # Function to parse the the list with delimiter "/" function Parse-List([string]$list = $(throw "No list is specified")) { if($list -eq $null) { return $null } return $list.Split("/", [StringSplitOptions]::RemoveEmptyEntries) } # Function to Reinstall any devices. function ReinstallDevice([string]$deviceID) { $ReinstallDeviceSource = @" using System; using System.Runtime.InteropServices; using System.Threading; namespace Microsoft.Windows.Diagnosis { public sealed class DeviceManagement_ReinstallSingleDevice { private DeviceManagement_ReinstallSingleDevice() { } public const UInt32 CR_SUCCESS = 0; public const UInt32 CM_REENUMERATE_SYNCHRONOUS = 1; public const UInt32 CM_REENUMERATE_RETRY_INSTALLATION = 2; public const UInt32 CM_LOCATE_DEVNODE_NORMAL = 0; public const UInt32 WAIT_OBJECT_0 = 0; public const UInt32 INFINITE = 0xFFFFFFFF; public const UInt32 CONFIGFLAG_REINSTALL = 32; public const UInt32 ERROR_CLASS_MISMATCH = 0xE0000203; public const UInt32 DEVPROP_TYPE_UINT32 = 0x00000007; public static DEVPROPKEY DEVPKEY_Device_ConfigFlags = new DEVPROPKEY(new Guid("a45c254e-df1c-4efd-8020-67d146a850e0"), 12); [DllImport("setupapi.dll", SetLastError = true, EntryPoint = "SetupDiGetDeviceProperty", CharSet = CharSet.Auto)] static extern UInt32 SetupDiGetDeviceProperty(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, ref DEVPROPKEY PropertyKey, ref UInt32 PropertyType, IntPtr PropertyBuffer, UInt32 PropertyBufferSize, ref UInt32 RequiredSize, UInt32 Flags); [DllImport("setupapi.dll", SetLastError = true, EntryPoint = "SetupDiSetDeviceProperty", CharSet = CharSet.Auto)] static extern UInt32 SetupDiSetDeviceProperty(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, ref DEVPROPKEY PropertyKey, UInt32 PropertyType, IntPtr PropertyBuffer, UInt32 PropertyBufferSize, UInt32 Flags); [DllImport("setupapi.dll", SetLastError = true, EntryPoint = "SetupDiOpenDeviceInfo", CharSet = CharSet.Auto)] static extern UInt32 SetupDiOpenDeviceInfo(IntPtr DeviceInfoSet, [MarshalAs(UnmanagedType.LPWStr)]string DeviceID, IntPtr Parent, UInt32 Flags, ref SP_DEVINFO_DATA DeviceInfoData); [DllImport("setupapi.dll", SetLastError = true, EntryPoint = "SetupDiCreateDeviceInfoList", CharSet = CharSet.Unicode)] static extern IntPtr SetupDiCreateDeviceInfoList(IntPtr ClassGuid, IntPtr Parent); [DllImport("setupapi.dll", SetLastError = true, EntryPoint = "SetupDiDestroyDeviceInfoList", CharSet = CharSet.Auto)] static extern UInt32 SetupDiDestroyDeviceInfoList(IntPtr DevInfo); [DllImport("cfgmgr32.dll", SetLastError = true, EntryPoint = "CM_Locate_DevNode_Ex", CharSet = CharSet.Auto)] static extern UInt32 CM_Locate_DevNode_Ex(ref UInt32 DevInst, [MarshalAs(UnmanagedType.LPWStr)]string DeviceID, UInt32 Flags, IntPtr Machine); [DllImport("cfgmgr32.dll", SetLastError = true, EntryPoint = "CM_Reenumerate_DevNode_Ex", CharSet = CharSet.Auto)] static extern UInt32 CM_Reenumerate_DevNode_Ex(UInt32 DevInst, UInt32 Flags, IntPtr Machine); [DllImport("cfgmgr32.dll", SetLastError = true, EntryPoint = "CMP_WaitNoPendingInstallEvents", CharSet = CharSet.Auto)] static extern UInt32 CMP_WaitNoPendingInstallEvents(UInt32 TimeOut); public struct DEVPROPKEY { public DEVPROPKEY(Guid InputId, UInt32 InputDevId) { DEVPROPGUID = InputId; DEVID = InputDevId; } public Guid DEVPROPGUID; public UInt32 DEVID; } [StructLayout(LayoutKind.Sequential)] public struct SP_DEVINFO_DATA { public UInt32 Size; public Guid ClassGuid; public UInt32 DevInst; public IntPtr Reserved; } public static UInt32 GetDeviceInformation(string DeviceID, ref IntPtr DevInfoSet, ref SP_DEVINFO_DATA DevInfo) { DevInfoSet = SetupDiCreateDeviceInfoList(IntPtr.Zero, IntPtr.Zero); if (DevInfoSet == IntPtr.Zero) { return (UInt32)Marshal.GetLastWin32Error(); } DevInfo.Size = (UInt32)Marshal.SizeOf(DevInfo); if(0 == SetupDiOpenDeviceInfo(DevInfoSet, DeviceID, IntPtr.Zero, 0, ref DevInfo)) { SetupDiDestroyDeviceInfoList(DevInfoSet); return ERROR_CLASS_MISMATCH; } return 0; } public static void ReleaseDeviceInfoSet(IntPtr DevInfoSet) { SetupDiDestroyDeviceInfoList(DevInfoSet); } public static UInt32 ReinstallDevice(string DeviceID) { UInt32 ResultCode = 0; IntPtr LocalMachineInstance = IntPtr.Zero; UInt32 DeviceInstance = 0; UInt32 PendingTime = INFINITE; UInt32 PendingTimeDetecting = 100; UInt32 MaxTimes = 100; IntPtr DeviceInfoSet = IntPtr.Zero; SP_DEVINFO_DATA DeviceInfoData = new SP_DEVINFO_DATA(); ResultCode = GetDeviceInformation(DeviceID, ref DeviceInfoSet, ref DeviceInfoData); if(0 != ResultCode) { return ResultCode; } UInt32 propertyType = 0; UInt32 bufferSize = 4; IntPtr propertyBuffer = Marshal.AllocHGlobal((int)bufferSize); if (0 != SetupDiGetDeviceProperty(DeviceInfoSet, ref DeviceInfoData, ref DEVPKEY_Device_ConfigFlags, ref propertyType, propertyBuffer, bufferSize, ref bufferSize, 0)) { if (propertyType == DEVPROP_TYPE_UINT32) { UInt32 propertyValue = (UInt32)Marshal.ReadInt32(propertyBuffer); propertyValue = propertyValue | CONFIGFLAG_REINSTALL; Marshal.WriteInt32(propertyBuffer, (int)propertyValue); if (0 == SetupDiSetDeviceProperty(DeviceInfoSet, ref DeviceInfoData, ref DEVPKEY_Device_ConfigFlags, propertyType, propertyBuffer, bufferSize, 0)) { ResultCode = (UInt32)Marshal.GetLastWin32Error(); } } } else { ResultCode = (UInt32)Marshal.GetLastWin32Error(); } if (IntPtr.Zero != propertyBuffer) { Marshal.FreeHGlobal(propertyBuffer); } ResultCode = CM_Locate_DevNode_Ex(ref DeviceInstance, DeviceID, CM_LOCATE_DEVNODE_NORMAL, LocalMachineInstance); if (CR_SUCCESS == ResultCode) { ResultCode = CM_Reenumerate_DevNode_Ex(DeviceInstance, CM_REENUMERATE_SYNCHRONOUS | CM_REENUMERATE_RETRY_INSTALLATION, LocalMachineInstance); if (CR_SUCCESS == ResultCode) { UInt32 Wait = 0; ResultCode = CMP_WaitNoPendingInstallEvents(PendingTimeDetecting); while (WAIT_OBJECT_0 == ResultCode) { Wait++; if (MaxTimes <= Wait) { break; } Thread.Sleep((int)PendingTimeDetecting); ResultCode = CMP_WaitNoPendingInstallEvents(PendingTimeDetecting); } ResultCode = CMP_WaitNoPendingInstallEvents(PendingTime); } } ReleaseDeviceInfoSet(DeviceInfoSet); return ResultCode; } } } "@ Add-Type -TypeDefinition $ReinstallDeviceSource $DeviceManager = [Microsoft.Windows.Diagnosis.DeviceManagement_ReinstallSingleDevice] $ErrorCode = $DeviceManager::ReinstallDevice($deviceID) return $ErrorCode } # Function to Remove any devices. function RemoveDevice([string]$deviceID) { $RemoveDeviceSource = @" using System; using System.Runtime.InteropServices; using System.Text; namespace Microsoft.Windows.Diagnosis { public sealed class DeviceManagement_Remove { public const UInt32 ERROR_CLASS_MISMATCH = 0xE0000203; [DllImport("setupapi.dll", SetLastError = true, EntryPoint = "SetupDiOpenDeviceInfo", CharSet = CharSet.Auto)] static extern UInt32 SetupDiOpenDeviceInfo(IntPtr DeviceInfoSet, [MarshalAs(UnmanagedType.LPWStr)]string DeviceID, IntPtr Parent, UInt32 Flags, ref SP_DEVINFO_DATA DeviceInfoData); [DllImport("setupapi.dll", SetLastError = true, EntryPoint = "SetupDiCreateDeviceInfoList", CharSet = CharSet.Unicode)] static extern IntPtr SetupDiCreateDeviceInfoList(IntPtr ClassGuid, IntPtr Parent); [DllImport("setupapi.dll", SetLastError = true, EntryPoint = "SetupDiDestroyDeviceInfoList", CharSet = CharSet.Unicode)] static extern UInt32 SetupDiDestroyDeviceInfoList(IntPtr DevInfo); [DllImport("setupapi.dll", SetLastError = true, EntryPoint = "SetupDiRemoveDevice", CharSet = CharSet.Auto)] public static extern int SetupDiRemoveDevice(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData); [StructLayout(LayoutKind.Sequential)] public struct SP_DEVINFO_DATA { public UInt32 Size; public Guid ClassGuid; public UInt32 DevInst; public IntPtr Reserved; } private DeviceManagement_Remove() { } public static UInt32 GetDeviceInformation(string DeviceID, ref IntPtr DevInfoSet, ref SP_DEVINFO_DATA DevInfo) { DevInfoSet = SetupDiCreateDeviceInfoList(IntPtr.Zero, IntPtr.Zero); if (DevInfoSet == IntPtr.Zero) { return (UInt32)Marshal.GetLastWin32Error(); } DevInfo.Size = (UInt32)Marshal.SizeOf(DevInfo); if(0 == SetupDiOpenDeviceInfo(DevInfoSet, DeviceID, IntPtr.Zero, 0, ref DevInfo)) { SetupDiDestroyDeviceInfoList(DevInfoSet); return ERROR_CLASS_MISMATCH; } return 0; } public static void ReleaseDeviceInfoSet(IntPtr DevInfoSet) { SetupDiDestroyDeviceInfoList(DevInfoSet); } public static UInt32 RemoveDevice(string DeviceID) { UInt32 ResultCode = 0; IntPtr DevInfoSet = IntPtr.Zero; SP_DEVINFO_DATA DevInfo = new SP_DEVINFO_DATA(); ResultCode = GetDeviceInformation(DeviceID, ref DevInfoSet, ref DevInfo); if (0 == ResultCode) { if (1 != SetupDiRemoveDevice(DevInfoSet, ref DevInfo)) { ResultCode = (UInt32)Marshal.GetLastWin32Error(); } ReleaseDeviceInfoSet(DevInfoSet); } return ResultCode; } } } "@ Add-Type -TypeDefinition $RemoveDeviceSource $DeviceManager = [Microsoft.Windows.Diagnosis.DeviceManagement_Remove] $ErrorCode = $DeviceManager::RemoveDevice($deviceID) return $ErrorCode } # Rescans the device changes function RescanAllDevices() { $RescanAllDevicesSource = @" using System; using System.Runtime.InteropServices; using System.Threading; namespace Microsoft.Windows.Diagnosis { public sealed class DeviceManagement_Rescan { private DeviceManagement_Rescan() { } public const UInt32 CR_SUCCESS = 0; public const UInt32 CM_REENUMERATE_SYNCHRONOUS = 1; public const UInt32 CM_LOCATE_DEVNODE_NORMAL = 0; public const UInt32 WAIT_OBJECT_0 = 0; public const UInt32 INFINITE = 0xFFFFFFFF; [DllImport("cfgmgr32.dll", SetLastError = true, EntryPoint = "CM_Locate_DevNode_Ex", CharSet = CharSet.Auto)] static extern UInt32 CM_Locate_DevNode_Ex(ref UInt32 DevInst, IntPtr DeviceID, UInt32 Flags, IntPtr Machine); [DllImport("cfgmgr32.dll", SetLastError = true, EntryPoint = "CM_Reenumerate_DevNode_Ex", CharSet = CharSet.Auto)] static extern UInt32 CM_Reenumerate_DevNode_Ex(UInt32 DevInst, UInt32 Flags, IntPtr Machine); [DllImport("cfgmgr32.dll", SetLastError = true, EntryPoint = "CMP_WaitNoPendingInstallEvents", CharSet = CharSet.Auto)] static extern UInt32 CMP_WaitNoPendingInstallEvents(UInt32 TimeOut); public static UInt32 RescanAllDevices() { //only connect to local device nodes UInt32 ResultCode = 0; IntPtr LocalMachineInstance = IntPtr.Zero; UInt32 DeviceInstance = 0; UInt32 PendingTime = INFINITE; UInt32 PendingTimeDetecting = 100; UInt32 MaxTimes = 100; ResultCode = CM_Locate_DevNode_Ex(ref DeviceInstance, IntPtr.Zero, CM_LOCATE_DEVNODE_NORMAL, LocalMachineInstance); if (CR_SUCCESS == ResultCode) { ResultCode = CM_Reenumerate_DevNode_Ex(DeviceInstance, CM_REENUMERATE_SYNCHRONOUS, LocalMachineInstance); UInt32 Wait = 0; ResultCode = CMP_WaitNoPendingInstallEvents(PendingTimeDetecting); while (WAIT_OBJECT_0 == ResultCode) { Wait++; if (MaxTimes <= Wait) { break; } Thread.Sleep((int)PendingTimeDetecting); ResultCode = CMP_WaitNoPendingInstallEvents(PendingTimeDetecting); } ResultCode = CMP_WaitNoPendingInstallEvents(PendingTime); } return ResultCode; } } } "@ Add-Type -TypeDefinition $RescanAllDevicesSource $DeviceManager = [Microsoft.Windows.Diagnosis.DeviceManagement_Rescan] $ErrorCode = $DeviceManager::RescanAllDevices() return $ErrorCode } function Set-DefaultEndpoint([string]$id = $(throw "No id is specified")) { if(!([String]::IsNullOrEmpty($id))) { try { Get-AudioManager [Microsoft.Windows.Diagnosis.AudioConfigManager]::SetDefault($id) } catch [System.Exception] { Write-ExceptionTelemetry "Set-DefaultEndpoint" $_ } } } #Function Get-AudioSamplingRate() #{ #<# # DESCRIPTION: # Load the module related to Audio EndPointCtrl and get and set the default sampling rate of specific the audio device . # ARGUMENTS: # None # RETURNS: # AudioResetDeviceFormats Type ##> # $audioSampleFormatSource = @" #using System; #using System.Collections.Generic; #using System.Text; #using System.Runtime.InteropServices; #using System.ComponentModel; #using System.Security.Permissions; #using System.Globalization; #namespace Microsoft.Windows.Diagnosis #{ # public static class AudioResetDeviceFormats # { # public enum EDataFlow # { # ERender, # ECapture, # EAll, # EDataFlowEnumCount # } # /// # /// Used by IMMDeviceEnumerator # /// # public enum ERole # { # EConsole, # EMultimedia, # ECommunications, # ERoleEnumCount # } # internal static class NativeMethods # { # [DllImport("ole32.Dll")] # internal static extern int CoCreateInstance(ref Guid guid, [MarshalAs(UnmanagedType.IUnknown)] object inner, uint context, ref Guid id, [MarshalAs(UnmanagedType.IUnknown)] out object pointer); # } # public class EndpointCtrl # { # #region Private internal vars # static object oEnumerator; # static IMMDeviceEnumerator iDeviceEnumerator; # static object oDevice; # static IMMDevice iDevice; # #endregion # #region Interface to COM objects # const int E_FAIL = 0x00000001; # static Guid CLSID_MMDeviceEnumerator = new Guid("BCDE0395-E52F-467C-8E3D-C4579291692E"); # static Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046"); # /// # /// interface IMMDevice # /// # [Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] # private interface IMMDevice # { # int Activate(ref Guid guid, uint context, IntPtr parameters, ref IntPtr pointer); # int OpenPropertyStore(uint access, ref IntPtr properties); # int GetId(ref IntPtr id); # int GetState(ref int state); # } # /// # /// interface IMMDeviceEnumerator # /// # [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] # interface IMMDeviceEnumerator # { # int EnumAudioEndpoints(EDataFlow dataflow, int mask, ref IntPtr devices); # int GetDefaultAudioEndpoint(EDataFlow dataflow, ERole role, ref IntPtr endpoint); # int GetDevice(string id, ref IntPtr device); # int RegisterEndpointNotificationCallback(IntPtr client); # int UnregisterEndpointNotificationCallback(IntPtr client); # } # private static bool comInitialized; # #endregion # /// # /// Constructor, initialize com interfaces # /// # internal EndpointCtrl() # { # int result = 0; # //1.to obtain IMMDeviceEnumerator # result = InitializedInstance(); # if (result != 0) # { # throw new Win32Exception("Can't obtain IMMDeviceEnumerator: " + result); # } # //2.to obtain IMMDevice by IMMDeviceEnumerator # //result = GetAudioDevice(deviceId); # if (result != 0) # { # throw new Win32Exception("Can't obtain IMMDevice: " + result); # } # } # /// # /// initialize com interfaces and get IMMDeviceEnumerator # /// # /// # private static int InitializedInstance() # { # if (comInitialized == true) # { # return 0; # } # const uint CLSCTX_INPROC_SERVER = 1; # //1.to obtain IMMDeviceEnumerator # int result = NativeMethods.CoCreateInstance(ref CLSID_MMDeviceEnumerator, null, CLSCTX_INPROC_SERVER, ref IID_IUnknown, out oEnumerator); # if (result != 0) # { # return result; # } # comInitialized = true; # if (oEnumerator == null) # { # return E_FAIL; # } # iDeviceEnumerator = oEnumerator as IMMDeviceEnumerator; # if (iDeviceEnumerator == null) # { # return E_FAIL; # } # return result; # } # /// # /// Get expected Audio Device # /// # /// # int GetAudioDevice(string deviceId) # { # IntPtr pDevice = IntPtr.Zero; # int result = 0; # if (iDeviceEnumerator == null) # return E_FAIL; # result = iDeviceEnumerator.GetDevice(deviceId, ref pDevice); # if (result != 0) # { # throw new Win32Exception("Can't obtain IMMDevice: " + result); # } # oDevice = Marshal.GetObjectForIUnknown(pDevice); # iDevice = oDevice as IMMDevice; # iDevice.GetState(ref state); # return result; # } # /// # /// Get default Audio Device # /// # /// # [EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)] # static string GetDefaultAudioDeviceId(string type, ERole role) # { # IntPtr pDefaultDevice = IntPtr.Zero; # IntPtr pID = IntPtr.Zero; # string id = ""; # int result = 0; # object oDefaultDevice; # IMMDevice iDefaultDevice; # if (iDeviceEnumerator == null) # return ""; # result = iDeviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.ERender, role, ref pDefaultDevice); # if (result != 0) # { # throw new Win32Exception("Can't obtain IMMDevice: " + result); # } # oDefaultDevice = Marshal.GetObjectForIUnknown(pDefaultDevice); # iDefaultDevice = oDefaultDevice as IMMDevice; # if (iDefaultDevice != null) # { # iDefaultDevice.GetId(ref pID); # } # id = Marshal.PtrToStringAuto(pID); # return id; # } # /// # /// Call this method to release all com objetcs # /// # [EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)] # public virtual void Dispose() # { # if (iDevice != null) # { # Marshal.ReleaseComObject(iDevice); # iDevice = null; # } # if (oDevice != null) # { # Marshal.ReleaseComObject(oDevice); # oDevice = null; # } # if (iDeviceEnumerator != null) # { # Marshal.ReleaseComObject(iDeviceEnumerator); # iDeviceEnumerator = null; # } # if (oEnumerator != null) # { # Marshal.ReleaseComObject(oEnumerator); # oEnumerator = null; # } # } # #region Public properties # /// # /// Get the default device state. # /// # int state; # public int State # { # get # { # return state; # } # } # [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] # public string EndpointId # { # get # { # IntPtr id = IntPtr.Zero; # if (iDevice != null) # { # iDevice.GetId(ref id); # } # return Marshal.PtrToStringAuto(id); # } # } # #endregion # #region Public Method # public string GetDefaultSpeakerEndpoint() # { # return GetDefaultAudioDeviceId("speakers", ERole.EConsole); # } # #endregion # } # [StructLayout(LayoutKind.Sequential)] # public class WAVEFORMATEX # { # public UInt16 wFormatTag; # public UInt16 nChannels; # public UInt32 nSamplesPerSec; # public UInt32 nAvgBytesPerSec; # public UInt16 nBlockAlign; # public UInt16 wBitsPerSample; # public UInt16 cbSize; # } # [ComImport, Guid("870AF99C-171D-4f9e-AF0D-E63DF40C2BC9")] # public class IPolicyConfigClass { } # public static class LoadDLL # { # [DllImport("AudioDiagnosticUtil.dll", EntryPoint = "AudioGetDeviceFormat", CharSet = CharSet.Auto)] # public static extern int AudioGetDeviceFormat(string pszDeviceName, bool bDefault, ref IntPtr ppFormat); # [DllImport("AudioDiagnosticUtil.dll", EntryPoint = "AudioSetDeviceFormat", CharSet = CharSet.Auto)] # public static extern int AudioSetDeviceFormat(string pszDeviceName, IntPtr pEndpointFormat, IntPtr MixFormat); # } # public class IPolicyConfigHelper # { # public Byte[] GetDeviceFormat(string pszDeviceName, bool bDefault, out WAVEFORMATEX retFormat) # { # IntPtr ptrToWaveFormat = new IntPtr(); # LoadDLL.AudioGetDeviceFormat(pszDeviceName, bDefault, ref ptrToWaveFormat); # WAVEFORMATEX format = (WAVEFORMATEX)Marshal.PtrToStructure(ptrToWaveFormat, typeof(WAVEFORMATEX)); # int formatSize = format.cbSize + Marshal.SizeOf(typeof(WAVEFORMATEX)); # Byte[] formatExtData = new Byte[format.cbSize + Marshal.SizeOf(typeof(WAVEFORMATEX))]; # Marshal.Copy(ptrToWaveFormat, formatExtData, 0, formatSize); # retFormat = format; # return formatExtData; # } # public int SetDeviceFormat(string pszDeviceName, Byte[] formatExtData, int formatSize) # { # IntPtr ptrToFormat = Marshal.AllocHGlobal(formatSize); # Marshal.Copy(formatExtData, 0, ptrToFormat, formatSize); # int rval = LoadDLL.AudioSetDeviceFormat(pszDeviceName, ptrToFormat, IntPtr.Zero); # Marshal.FreeHGlobal(ptrToFormat); # return rval; # } # } # public static bool verifySamplingRate(string deviceID) # { # EndpointCtrl control = new EndpointCtrl(); # bool result = false; # string defSpeakerEndpoint = deviceID; # IPolicyConfigHelper policyHelper = new IPolicyConfigHelper(); # WAVEFORMATEX defaultFormatEx = new WAVEFORMATEX(); # WAVEFORMATEX currentFormatEx = new WAVEFORMATEX(); # Byte[] defaultFormat = policyHelper.GetDeviceFormat(defSpeakerEndpoint, true, out defaultFormatEx); # Byte[] currentFormat = policyHelper.GetDeviceFormat(defSpeakerEndpoint, false, out currentFormatEx); # if (defaultFormatEx.nAvgBytesPerSec != currentFormatEx.nAvgBytesPerSec) # { # result = true; # } # return result; # } # public static bool resetSamplingRate(string deviceID) # { # EndpointCtrl control = new EndpointCtrl(); # string defSpeakerEndpoint = deviceID; # IPolicyConfigHelper policyHelper = new IPolicyConfigHelper(); # WAVEFORMATEX defaultFormatEx = new WAVEFORMATEX(); # WAVEFORMATEX currentFormatEx = new WAVEFORMATEX(); # Byte[] defaultFormat = policyHelper.GetDeviceFormat(defSpeakerEndpoint, true, out defaultFormatEx); # Byte[] currentFormat = policyHelper.GetDeviceFormat(defSpeakerEndpoint, false, out currentFormatEx); # policyHelper.SetDeviceFormat(defSpeakerEndpoint, defaultFormat, defaultFormat.Length); # WAVEFORMATEX currentFormatEx2 = new WAVEFORMATEX(); # Byte[] currentFormat2 = policyHelper.GetDeviceFormat(defSpeakerEndpoint, false, out currentFormatEx2); # control.Dispose(); # return true; # } # } #} #"@ # Add-Type -TypeDefinition $audioSampleFormatSource # $audioSampleFormat = [Microsoft.Windows.Diagnosis.AudioResetDeviceFormats] # return $audioSampleFormat #} Function Start-AudioService() { <# .DESCRIPTION Function to start Audio service forcefully .PARAMETER None .OUTPUTS None #> $audioService = (Get-WmiObject -query "select * from win32_baseService where Name='Audiosrv'") if($audioService.State -ne "Running") { Set-Service Audiosrv -StartupType Automatic Start-Service Audiosrv -PassThru -ErrorAction SilentlyContinue } } Function Stop-AudioService() { <# .DESCRIPTION Function to stop Audio service forcefully .PARAMETER None .OUTPUTS None #> $audioService = (Get-WmiObject -query "select * from win32_baseService where Name='Audiosrv'") if($audioService.State -eq "Running") { Stop-Service Audiosrv -PassThru -ErrorAction SilentlyContinue } } function Get-AudioEndPointsCount { <# FUNCTION DESCRIPTION: Enum audio active endpoints ARGUMENTS: None RETURNS: Total number of audio endpoints #> $audioEnumSource = @" using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.ComponentModel; using System.Security.Permissions; using System.Globalization; namespace Microsoft.Windows.Diagnosis { public static class AudioEnumEndPoints { public enum EDataFlow { ERender, ECapture, EAll, EDataFlowEnumCount } /// /// Used by IMMDeviceEnumerator /// public enum ERole { EConsole, EMultimedia, ECommunications, ERoleEnumCount } [Flags] enum DEVICE_STATE : uint { DEVICE_STATE_ACTIVE = 0x00000001, DEVICE_STATE_DISABLED = 0x00000002, DEVICE_STATE_NOTPRESENT = 0x00000004, DEVICE_STATE_UNPLUGGED = 0x00000008, DEVICE_STATEMASK_ALL = 0x0000000F } internal static class NativeMethods { [DllImport("ole32.Dll")] internal static extern int CoCreateInstance(ref Guid guid, [MarshalAs(UnmanagedType.IUnknown)] object inner, uint context, ref Guid id, [MarshalAs(UnmanagedType.IUnknown)] out object pointer); } #region Private internal vars static object oEnumerator; static IMMDeviceEnumerator iDeviceEnumerator; #endregion #region Interface to COM objects const int E_FAIL = 0x00000001; static Guid CLSID_MMDeviceEnumerator = new Guid("BCDE0395-E52F-467C-8E3D-C4579291692E"); static Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046"); /// /// interface IMMDeviceEnumerator /// [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IMMDeviceEnumerator { int EnumAudioEndpoints(EDataFlow dataflow, uint mask, ref IntPtr devices); int GetDefaultAudioEndpoint(EDataFlow dataflow, ERole role, ref IntPtr endpoint); int GetDevice(string id, ref IntPtr device); int RegisterEndpointNotificationCallback(IntPtr client); int UnregisterEndpointNotificationCallback(IntPtr client); } #endregion [Guid("0BD7A1BE-7A1A-44DB-8397-CC5392387B5E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IMMDeviceCollection { //HRESULT GetCount( // [out] UINT* pcDevices //); int GetCount(out int pcDevices); //HRESULT Item( // [in] UINT nDevice, // [out] IMMDevice** ppDevice //); int Item(uint nDevice, ref IntPtr ppDevice); } /// /// Get expected Audio Device /// /// public static int GetAudioEndPointsCount() { int result = 0; try { IntPtr ppDevices = IntPtr.Zero; object oDevices = null; IMMDeviceCollection endpointCollection = null; const uint CLSCTX_INPROC_SERVER = 1; //1.to obtain IMMDeviceEnumerator int result1 = NativeMethods.CoCreateInstance(ref CLSID_MMDeviceEnumerator, null, CLSCTX_INPROC_SERVER, ref IID_IUnknown, out oEnumerator); iDeviceEnumerator = oEnumerator as IMMDeviceEnumerator; int hr = iDeviceEnumerator.EnumAudioEndpoints(EDataFlow.EAll, (uint)DEVICE_STATE.DEVICE_STATE_ACTIVE, ref ppDevices); if (hr != 0) { throw new Exception("HResult from IMMDeviceEnumerator.EnumAudioEndpoints = " + hr); } else if (ppDevices == IntPtr.Zero) { throw new Exception("IMMDeviceEnumerator.EnumAudioEndpoints returned pointer was zero."); } oDevices = Marshal.GetObjectForIUnknown(ppDevices); endpointCollection = oDevices as IMMDeviceCollection; if (endpointCollection == null) { throw new Exception("Could not cast to IMMDeviceCollection"); } int deviceCount; hr = endpointCollection.GetCount(out deviceCount); if (hr != 0) { throw new Exception("HResult from IMMDeviceCollection.GetCount = " + hr); } Console.WriteLine(deviceCount.ToString()); result = deviceCount; } catch (InvalidCastException icex) { Console.WriteLine("Unexpected COM exception: " + icex.Message); } catch (Exception ex) { Console.WriteLine(ex.Message); } return result; } } } "@ Add-Type -TypeDefinition $audioEnumSource $audioEndpoints = [Microsoft.Windows.Diagnosis.AudioEnumEndPoints] # Call IAudioClient::Initialize on all the Active endpoints $result = $audioEndpoints::GetAudioEndPointsCount() return $result } Function Get-AudioDriverSource32 { <# .DESCRIPTION Function get driver resources of the specific audio device on 32 bit OS .PARAMETER None .OUTPUTS Returns data type of get driver resources #> $ChangeAudioDriverSource32 = @" using System; using System.Runtime.InteropServices; namespace Microsoft.Windows.Diagnosis { public static class ChangeAudioDriver32 { public enum DIOD { None = (0), CANCEL_REMOVE = (0x00000004), // If this flag is specified and the device had been marked for pending removal, the OS cancels the pending removal. INHERIT_CLASSDRVS = (0x00000002) //the resulting device information element inherits the class driver list, if any } public enum DICD { None = (0), GENERATE_ID = (0x00000001), // create unique device instance key INHERIT_CLASSDRVS = (0x00000002) // inherit class driver list } public enum SPDIT { None = (0), SPDIT_COMPATDRIVER = (0x00000002), // Build a list of compatible drivers SPDIT_CLASSDRIVER = (0x00000001) // Build a list of class drivers } public enum DI_FLAGS { DI_FLAGSEX_INSTALLEDDRIVER = (0x04000000), DI_FLAGSEX_ALLOWEXCLUDEDDRVS = (0x00000800) } [StructLayout(LayoutKind.Sequential)] public class SP_DEVINFO_DATA { /// /// Size of the structure, in bytes. /// public Int32 cbSize = Marshal.SizeOf(typeof(SP_DEVINFO_DATA)); /// /// GUID of the device interface class. /// public Guid ClassGuid; /// /// Handle to this device instance. /// public Int32 DevInst; /// /// Reserved; do not use. /// public IntPtr Reserved; } // 64 bit: Pack=4 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack=1)] public class SP_DRVINFO_DATA { public Int32 cbSize; public Int32 DriverType; public IntPtr Reserved; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public String Description; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public String MfgName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public String ProviderName; public System.Runtime.InteropServices.ComTypes.FILETIME DriverDate; public Int64 DriverVersion; } // 64 bit: Pack=8 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)] public class SP_DRVINFO_DETAIL_DATA { public Int32 cbSize; public System.Runtime.InteropServices.ComTypes.FILETIME InfDate; public Int32 CompatIDsOffset; public Int32 CompatIDsLength; public IntPtr Reserved; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string SectionName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string InfFileName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string DrvDescription; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)] public string HardwareID; } // 64 bit: Pack=8 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 4)] public class SP_DEVINSTALL_PARAMS { public Int32 cbSize; public Int32 Flags; public DI_FLAGS FlagsEx; public IntPtr hwndParent; public IntPtr InstallMsgHandler; public IntPtr InstallMsgHandlerContext; public IntPtr FileQueue; public UIntPtr ClassInstallReserved; public Int32 Reserved; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string DriverPath; } [DllImport("Setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool SetupDiOpenDeviceInfo( IntPtr DeviceInfoSet, string device, IntPtr handleToWindow, DIOD flag, SP_DEVINFO_DATA deviceInfoData ); [DllImport("Setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)] public extern static IntPtr SetupDiCreateDeviceInfoList ( IntPtr ClassGuid, IntPtr hwndParent ); [DllImport("Setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool SetupDiBuildDriverInfoList( IntPtr DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData, SPDIT DriverType ); [DllImport("Setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool SetupDiEnumDriverInfo( IntPtr DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData, SPDIT DriverType, int MemberIndex, [In, Out] SP_DRVINFO_DATA DriverInfoData ); [DllImport("Setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool SetupDiGetDriverInfoDetail( IntPtr DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData, SP_DRVINFO_DATA DriverInfoData, [In, Out] SP_DRVINFO_DETAIL_DATA DriverInfoDetailData, int DriverInfoDetailDataSize, out int RequiredSize ); [DllImport("Setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool SetupDiSetDeviceInstallParams( IntPtr DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData, SP_DEVINSTALL_PARAMS DeviceInstallParams ); [DllImport("Newdev.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool DiInstallDevice( IntPtr hwndParent, IntPtr DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData, SP_DRVINFO_DATA DriverInfoData, int Flags, out bool rebootRequired ); [DllImport("Newdev.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool DiInstallDriver ( [In] IntPtr hwndParent, [In] string FullInfPath, [In] uint Flags, [Out] bool NeedReboot ); public static int ForceInstallDriver(string deviceId, string infPath) { int error = 0; IntPtr hDevSet = SetupDiCreateDeviceInfoList(IntPtr.Zero, IntPtr.Zero); SP_DEVINFO_DATA deviceInfoData = new SP_DEVINFO_DATA(); bool bRet = SetupDiOpenDeviceInfo(hDevSet, deviceId, IntPtr.Zero, 0, deviceInfoData); if (bRet == false) { return Marshal.GetLastWin32Error(); } bRet = SetupDiBuildDriverInfoList(hDevSet, deviceInfoData, SPDIT.SPDIT_COMPATDRIVER); if (bRet == false) { return Marshal.GetLastWin32Error(); } int driverItr = 0; bool bResult = true; while (bResult) { SP_DRVINFO_DATA driverInfoData = new SP_DRVINFO_DATA(); driverInfoData.cbSize = Marshal.SizeOf(typeof(SP_DRVINFO_DATA)); bRet = SetupDiEnumDriverInfo(hDevSet, deviceInfoData, SPDIT.SPDIT_COMPATDRIVER, driverItr, driverInfoData); if (bRet == false) { return Marshal.GetLastWin32Error(); } int requiredSize = 0; SP_DRVINFO_DETAIL_DATA driverInfoDetailData = new SP_DRVINFO_DETAIL_DATA(); driverInfoDetailData.cbSize = Marshal.SizeOf(typeof(SP_DRVINFO_DETAIL_DATA)); int dataSize = Marshal.SizeOf(driverInfoDetailData); bRet = SetupDiGetDriverInfoDetail(hDevSet, deviceInfoData, driverInfoData, driverInfoDetailData, dataSize, out requiredSize); if (bRet == false) { error = Marshal.GetLastWin32Error(); //122 - ERROR_INSUFFICIENT_BUFFER, expected error if (error != 122) { Marshal.GetLastWin32Error(); } } if (driverInfoDetailData.InfFileName != null && driverInfoDetailData.InfFileName.Contains(infPath)) { bool bReboot = false; //bRet = DiInstallDevice(IntPtr.Zero, hDevSet, deviceInfoData, driverInfoData, 0, out bReboot); //DIIRFLAG_FORCE_INF = 0x00000002 to force windows to honor the driver installation bRet = DiInstallDriver(IntPtr.Zero, driverInfoDetailData.InfFileName, 2, bReboot); if (bRet == false) { error = Marshal.GetLastWin32Error(); driverItr++; continue; } else { return 0; } } driverItr++; } return -1; } public static int ForceInstallHDAudio(string deviceId) { return ForceInstallDriver(deviceId, "hdaudio.inf"); } public static string GetCurrentDriverINF(string deviceId) { string infPath = "ErrorFindingINF"; int error = 0; IntPtr hDevSet = SetupDiCreateDeviceInfoList(IntPtr.Zero, IntPtr.Zero); SP_DEVINFO_DATA deviceInfoData = new SP_DEVINFO_DATA(); bool bRet = SetupDiOpenDeviceInfo(hDevSet, deviceId, IntPtr.Zero, 0, deviceInfoData); if (bRet == false) { error = Marshal.GetLastWin32Error(); return infPath; } // Get Currently Installed Driver SP_DEVINSTALL_PARAMS deviceInstallParams = new SP_DEVINSTALL_PARAMS(); deviceInstallParams.cbSize = Marshal.SizeOf(typeof(SP_DEVINSTALL_PARAMS)); deviceInstallParams.FlagsEx = DI_FLAGS.DI_FLAGSEX_ALLOWEXCLUDEDDRVS | DI_FLAGS.DI_FLAGSEX_INSTALLEDDRIVER; bRet = SetupDiSetDeviceInstallParams(hDevSet, deviceInfoData, deviceInstallParams); if (bRet == false) { error = Marshal.GetLastWin32Error(); return infPath; } bRet = SetupDiBuildDriverInfoList(hDevSet, deviceInfoData, SPDIT.SPDIT_COMPATDRIVER); if (bRet == false) { error = Marshal.GetLastWin32Error(); return infPath; } int driverItr = 0; SP_DRVINFO_DATA driverInfoData = new SP_DRVINFO_DATA(); driverInfoData.cbSize = Marshal.SizeOf(typeof(SP_DRVINFO_DATA)); bRet = SetupDiEnumDriverInfo(hDevSet, deviceInfoData, SPDIT.SPDIT_COMPATDRIVER, driverItr, driverInfoData); if (bRet == false) { error = Marshal.GetLastWin32Error(); return infPath; } int requiredSize = 0; SP_DRVINFO_DETAIL_DATA driverInfoDetailData = new SP_DRVINFO_DETAIL_DATA(); driverInfoDetailData.cbSize = Marshal.SizeOf(typeof(SP_DRVINFO_DETAIL_DATA)); int dataSize = Marshal.SizeOf(driverInfoDetailData); // First get the required size bRet = SetupDiGetDriverInfoDetail(hDevSet, deviceInfoData, driverInfoData, driverInfoDetailData, dataSize, out requiredSize); if (bRet == false) { error = Marshal.GetLastWin32Error(); //122 - ERROR_INSUFFICIENT_BUFFER, expected error if (error != 122) { return infPath; } } if (driverInfoDetailData.InfFileName != null) { infPath = driverInfoDetailData.InfFileName; } return infPath; } } } "@ Add-Type -TypeDefinition $ChangeAudioDriverSource32 $driverSource = [Microsoft.Windows.Diagnosis.ChangeAudioDriver32] return $driverSource } Function Get-AudioDriverSource { <# .DESCRIPTION Function get driver resources of the specific audio device on 64 bit OS .PARAMETER None .OUTPUTS Returns data type of get driver resources #> $ChangeAudioDriverSource = @" using System; using System.Runtime.InteropServices; namespace Microsoft.Windows.Diagnosis { public static class ChangeAudioDriver { public enum DIOD { None = (0), CANCEL_REMOVE = (0x00000004), // If this flag is specified and the device had been marked for pending removal, the OS cancels the pending removal. INHERIT_CLASSDRVS = (0x00000002) //the resulting device information element inherits the class driver list, if any } public enum DICD { None = (0), GENERATE_ID = (0x00000001), // create unique device instance key INHERIT_CLASSDRVS = (0x00000002) // inherit class driver list } public enum SPDIT { None = (0), SPDIT_COMPATDRIVER = (0x00000002), // Build a list of compatible drivers SPDIT_CLASSDRIVER = (0x00000001) // Build a list of class drivers } public enum DI_FLAGS { DI_FLAGSEX_INSTALLEDDRIVER = (0x04000000), DI_FLAGSEX_ALLOWEXCLUDEDDRVS = (0x00000800) } [StructLayout(LayoutKind.Sequential)] public class SP_DEVINFO_DATA { /// /// Size of the structure, in bytes. /// public Int32 cbSize = Marshal.SizeOf(typeof(SP_DEVINFO_DATA)); /// /// GUID of the device interface class. /// public Guid ClassGuid; /// /// Handle to this device instance. /// public Int32 DevInst; /// /// Reserved; do not use. /// public IntPtr Reserved; } // 64 bit: Pack=4 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack=4)] public class SP_DRVINFO_DATA { public Int32 cbSize; public Int32 DriverType; public IntPtr Reserved; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public String Description; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public String MfgName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public String ProviderName; public System.Runtime.InteropServices.ComTypes.FILETIME DriverDate; public Int64 DriverVersion; } // 64 bit: Pack=8 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 8)] public class SP_DRVINFO_DETAIL_DATA { public Int32 cbSize; public System.Runtime.InteropServices.ComTypes.FILETIME InfDate; public Int32 CompatIDsOffset; public Int32 CompatIDsLength; public IntPtr Reserved; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string SectionName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string InfFileName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string DrvDescription; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)] public string HardwareID; } // 64 bit: Pack=8 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 8)] public class SP_DEVINSTALL_PARAMS { public Int32 cbSize; public Int32 Flags; public DI_FLAGS FlagsEx; public IntPtr hwndParent; public IntPtr InstallMsgHandler; public IntPtr InstallMsgHandlerContext; public IntPtr FileQueue; public UIntPtr ClassInstallReserved; public Int32 Reserved; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string DriverPath; } [DllImport("Setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool SetupDiOpenDeviceInfo( IntPtr DeviceInfoSet, string device, IntPtr handleToWindow, DIOD flag, SP_DEVINFO_DATA deviceInfoData ); [DllImport("Setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)] public extern static IntPtr SetupDiCreateDeviceInfoList ( IntPtr ClassGuid, IntPtr hwndParent ); [DllImport("Setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool SetupDiBuildDriverInfoList( IntPtr DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData, SPDIT DriverType ); [DllImport("Setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool SetupDiEnumDriverInfo( IntPtr DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData, SPDIT DriverType, int MemberIndex, [In, Out] SP_DRVINFO_DATA DriverInfoData ); [DllImport("Setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool SetupDiGetDriverInfoDetail( IntPtr DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData, SP_DRVINFO_DATA DriverInfoData, [In, Out] SP_DRVINFO_DETAIL_DATA DriverInfoDetailData, int DriverInfoDetailDataSize, out int RequiredSize ); [DllImport("Setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool SetupDiSetDeviceInstallParams( IntPtr DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData, SP_DEVINSTALL_PARAMS DeviceInstallParams ); [DllImport("Newdev.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool DiInstallDevice( IntPtr hwndParent, IntPtr DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData, SP_DRVINFO_DATA DriverInfoData, int Flags, out bool rebootRequired ); [DllImport("Newdev.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool DiInstallDriver ( [In] IntPtr hwndParent, [In] string FullInfPath, [In] uint Flags, [Out] bool NeedReboot ); public static int ForceInstallDriver(string deviceId, string infPath) { int error = 0; IntPtr hDevSet = SetupDiCreateDeviceInfoList(IntPtr.Zero, IntPtr.Zero); SP_DEVINFO_DATA deviceInfoData = new SP_DEVINFO_DATA(); bool bRet = SetupDiOpenDeviceInfo(hDevSet, deviceId, IntPtr.Zero, 0, deviceInfoData); if (bRet == false) { return Marshal.GetLastWin32Error(); } bRet = SetupDiBuildDriverInfoList(hDevSet, deviceInfoData, SPDIT.SPDIT_COMPATDRIVER); if (bRet == false) { return Marshal.GetLastWin32Error(); } int driverItr = 0; bool bResult = true; while (bResult) { SP_DRVINFO_DATA driverInfoData = new SP_DRVINFO_DATA(); driverInfoData.cbSize = Marshal.SizeOf(typeof(SP_DRVINFO_DATA)); bRet = SetupDiEnumDriverInfo(hDevSet, deviceInfoData, SPDIT.SPDIT_COMPATDRIVER, driverItr, driverInfoData); if (bRet == false) { return Marshal.GetLastWin32Error(); } int requiredSize = 0; SP_DRVINFO_DETAIL_DATA driverInfoDetailData = new SP_DRVINFO_DETAIL_DATA(); driverInfoDetailData.cbSize = Marshal.SizeOf(typeof(SP_DRVINFO_DETAIL_DATA)); int dataSize = Marshal.SizeOf(driverInfoDetailData); bRet = SetupDiGetDriverInfoDetail(hDevSet, deviceInfoData, driverInfoData, driverInfoDetailData, dataSize, out requiredSize); if (bRet == false) { error = Marshal.GetLastWin32Error(); //122 - ERROR_INSUFFICIENT_BUFFER, expected error if (error != 122) { Marshal.GetLastWin32Error(); } } if (driverInfoDetailData.InfFileName != null && driverInfoDetailData.InfFileName.Contains(infPath)) { bool bReboot = false; //bRet = DiInstallDevice(IntPtr.Zero, hDevSet, deviceInfoData, driverInfoData, 0, out bReboot); //DIIRFLAG_FORCE_INF = 0x00000002 to force windows to honor the driver installation bRet = DiInstallDriver(IntPtr.Zero, driverInfoDetailData.InfFileName, 2, bReboot); if (bRet == false) { error = Marshal.GetLastWin32Error(); driverItr++; continue; } else { return 0; } } driverItr++; } return -1; } public static int ForceInstallHDAudio(string deviceId) { return ForceInstallDriver(deviceId, "hdaudio.inf"); } public static string GetCurrentDriverINF(string deviceId) { string infPath = "ErrorFindingINF"; int error = 0; IntPtr hDevSet = SetupDiCreateDeviceInfoList(IntPtr.Zero, IntPtr.Zero); SP_DEVINFO_DATA deviceInfoData = new SP_DEVINFO_DATA(); bool bRet = SetupDiOpenDeviceInfo(hDevSet, deviceId, IntPtr.Zero, 0, deviceInfoData); if (bRet == false) { error = Marshal.GetLastWin32Error(); return infPath; } // Get Currently Installed Driver SP_DEVINSTALL_PARAMS deviceInstallParams = new SP_DEVINSTALL_PARAMS(); deviceInstallParams.cbSize = Marshal.SizeOf(typeof(SP_DEVINSTALL_PARAMS)); deviceInstallParams.FlagsEx = DI_FLAGS.DI_FLAGSEX_ALLOWEXCLUDEDDRVS | DI_FLAGS.DI_FLAGSEX_INSTALLEDDRIVER; bRet = SetupDiSetDeviceInstallParams(hDevSet, deviceInfoData, deviceInstallParams); if (bRet == false) { error = Marshal.GetLastWin32Error(); return infPath; } bRet = SetupDiBuildDriverInfoList(hDevSet, deviceInfoData, SPDIT.SPDIT_COMPATDRIVER); if (bRet == false) { error = Marshal.GetLastWin32Error(); return infPath; } int driverItr = 0; SP_DRVINFO_DATA driverInfoData = new SP_DRVINFO_DATA(); driverInfoData.cbSize = Marshal.SizeOf(typeof(SP_DRVINFO_DATA)); bRet = SetupDiEnumDriverInfo(hDevSet, deviceInfoData, SPDIT.SPDIT_COMPATDRIVER, driverItr, driverInfoData); if (bRet == false) { error = Marshal.GetLastWin32Error(); return infPath; } int requiredSize = 0; SP_DRVINFO_DETAIL_DATA driverInfoDetailData = new SP_DRVINFO_DETAIL_DATA(); driverInfoDetailData.cbSize = Marshal.SizeOf(typeof(SP_DRVINFO_DETAIL_DATA)); int dataSize = Marshal.SizeOf(driverInfoDetailData); // First get the required size bRet = SetupDiGetDriverInfoDetail(hDevSet, deviceInfoData, driverInfoData, driverInfoDetailData, dataSize, out requiredSize); if (bRet == false) { error = Marshal.GetLastWin32Error(); //122 - ERROR_INSUFFICIENT_BUFFER, expected error if (error != 122) { return infPath; } } if (driverInfoDetailData.InfFileName != null) { infPath = driverInfoDetailData.InfFileName; } return infPath; } } } "@ Add-Type -TypeDefinition $ChangeAudioDriverSource $driverSource = [Microsoft.Windows.Diagnosis.ChangeAudioDriver] return $driverSource } Function PlaySound() { <# .DESCRIPTION Function Play windows default sound file thrice .PARAMETER None .OUTPUTS None #> $count = 1 while($count -le 3) { $count++ $playSound = (new-object Media.SoundPlayer "$env:SystemDrive\Windows\Media\notify.wav").play() Start-Sleep 1 } } Function Get-HDAudioID($deviceTypes) { <# .DESCRIPTION Function to get the device ID of HD audio driver .PARAMETER None .OUTPUTS Array of device ID #> try { $devices = @() $devIds = @() [string]$deviceFlow = $endPointtype $audioDevices = Get-WmiObject Win32_SoundDevice foreach ($device in $audioDevices) { $pnpdevid = $device.PNPDeviceID $pnpSignedDriver = Get-WmiObject -Class Win32_PnPSignedDriver | Where-Object -FilterScript {$_.DeviceID -eq $pnpdevid} $infname = $pnpSignedDriver.InfName $infname = $infname.ToLower() if($infname.Contains("hdaudio")) { $devName = $pnpSignedDriver.DeviceName break } } $EndPointListID_HDAudioID = @() $AudioMethods_HDAudioID = Get-AudioEndpoints $EndPointListID_HDAudioID = $AudioMethods_HDAudioID::GetAudioEndPointsbyType($deviceTypes) $devices += $EndPointListID_HDAudioID.ForEach({[PSCustomObject]$_}) foreach($devs in $devices) { $devId = GetId $devs $deviceName = GetAdapterName $devs if($deviceName.Contains($devName)) { $devIds += $devId } } } catch { $errorMsg = $_.Exception.Message $errorMsg | ConvertTo-Xml | Update-DiagReport -Id "CL_Utility" -Name "CL_Utility" -Verbosity Debug } return $devIds } function Set-AudioEndpointProperty($deviceType) { <# .DESCRIPTION Function to set property related to audio MMdevice .PARAMETER None .OUTPUTS Bool value True if property is set else false #> $flag = $false $ids = @() $ids = Get-HDAudioID $deviceTypes Get-AudioManager foreach($id in $ids) { if(!([String]::IsNullOrEmpty($id))) { try { $returnValue = [Microsoft.Windows.Diagnosis.AudioConfigManager]::SetAudioProperty($id) if($returnValue -eq "0") { $flag = $true } } catch [System.Exception] { Write-ExceptionTelemetry "Set-AudioEndpointProperty" $_ $errorMsg = $_.Exception.Message $errorMsg | ConvertTo-Xml | Update-DiagReport -Id "CL_Utility" -Name "CL_Utility" -Verbosity Debug } } } return $flag } Function Get-AudioEndpoints() { <# DESCRIPTION: Load the module related to Audio EndPointCtrl and get and set the default sampling rate of specific the audio device . ARGUMENTS: None RETURNS: AudioResetDeviceFormats Type #> $AudioEndpointsSource = @" using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.ComponentModel; using System.Security.Permissions; using System.Globalization; namespace Microsoft.Windows.Diagnosis { public static class AudioResetDeviceFormats { /// /// Used by IMMDeviceEnumerator /// public enum EDataFlow { ERender, ECapture, EAll, EDataFlowEnumCount } public enum DeviceState { Active = 0x00000001, Disabled = 0x00000002, NotPresent = 0x00000004, Unplugged = 0x00000008, All = 0x0000000f } /// /// Used by IMMDeviceEnumerator /// public enum ERole { EConsole, EMultimedia, ECommunications, ERoleEnumCount } /// /// PROPVARIANT, Used by IMMDevice::OpenPropertyStore /// [StructLayout(LayoutKind.Explicit)] private struct UnionMembers { [FieldOffset(0)] public IntPtr deviceName; [FieldOffset(0)] public uint deviceTypeValue; } [StructLayout(LayoutKind.Sequential, Size = 32)] private struct PROPVARIANT { private ushort variantType; private short reserved1; private short reserved2; private short reserved3; private UnionMembers unionmembers; public string DeviceName { get { return Marshal.PtrToStringAuto(this.unionmembers.deviceName); } } public uint DeviceTypeValue { get { return this.unionmembers.deviceTypeValue; } } } internal static class NativeMethods { [DllImport("ole32.Dll")] internal static extern int CoCreateInstance(ref Guid guid, [MarshalAs(UnmanagedType.IUnknown)] object inner, uint context, ref Guid id, [MarshalAs(UnmanagedType.IUnknown)] out object pointer); } public class EndpointList { public EndpointList(string deviceDes, string deviceId, string adapterName, int jackInfo, bool isDefault,int State) { this.deviceDes = deviceDes; this.deviceId = deviceId; this.adapterName = adapterName; this.jackInfo = jackInfo; this.isDefault = isDefault; this.state = State; } private string adapterName; public string AdapterName { get { return adapterName; } } private string deviceDes; public string DeviceDes { get { return deviceDes; } } private string deviceId; public string DeviceId { get { return deviceId; } } private int jackInfo; public int JackInfo { get { return jackInfo; } } private bool isDefault; public bool IsDefault { get { return isDefault; } } private int state; public int State { get { return state; } } } public class EndpointCtrl { #region Private internal vars static object oEnumerator; static IMMDeviceEnumerator iDeviceEnumerator; static object oDevices; static IMMDevices iDeviceCollection; static object oDevice; static IMMDevice iDevice; static object oProperty; static IPropertyStore iProperty; #endregion #region Interface to COM objects const int E_FAIL = 0x00000001; const int STGM_READ = 0x00000000; const int STGM_WRITE = 0x00000001; const int STGM_READWRITE = 0x00000002; static Guid CLSID_MMDeviceEnumerator = new Guid("BCDE0395-E52F-467C-8E3D-C4579291692E"); static Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046"); static Guid IID_IDeviceTopology = new Guid("2A07407E-6497-4A18-9787-32F79BD0D98F"); static Guid IID_IPart = new Guid("AE2DE0E4-5BCA-4F2D-AA46-5D13F8FDB3A9"); static Guid IID_IKsJackDescription = new Guid("4509F757-2D46-4637-8E62-CE7DB944F57B"); static int jackErrorInfo = 0; static PropertyKey PKEY_Device_DeviceDesc = new PropertyKey(new Guid("A45C254E-DF1C-4EFD-8020-67D146A850E0"), 2); static PropertyKey PKEY_AudioEndpoint_FormFactor = new PropertyKey(new Guid("1DA5D803-D492-4EDD-8C23-E0C0FFEE7F0E"), 0); static PropertyKey PKEY_DeviceInterface_FriendlyName = new PropertyKey(new Guid("026e516e-b814-414b-83cd-856d6fef4822"), 2); /// /// Interface IPropertyStore /// [Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IPropertyStore { //virtual HRESULT STDMETHODCALLTYPE GetCount(/* [out] */ __RPC__out DWORD *cProps) = 0; int GetCount(ref uint props); //virtual HRESULT STDMETHODCALLTYPE GetAt( /* [in] */ DWORD iProp, /* [out] */ __RPC__out PROPERTYKEY *pkey) = 0; int GetAt(uint prop, ref PropertyKey key); //virtual HRESULT STDMETHODCALLTYPE GetValue(/* [in] */ __RPC__in REFPROPERTYKEY key, /* [out] */ __RPC__out PROPVARIANT *pv) = 0; int GetValue(ref PropertyKey key, ref PROPVARIANT variant); //int GetValue([MarshalAs(UnmanagedType.Struct)]ref PropertyKey key, [MarshalAs(UnmanagedType.Struct)]ref PROPVARIANT variant); //virtual HRESULT STDMETHODCALLTYPE SetValue(/* [in] */ __RPC__in REFPROPERTYKEY key, /* [in] */ __RPC__in REFPROPVARIANT propvar) = 0; int SetValue(ref PropertyKey key, ref PROPVARIANT variant); //virtual HRESULT STDMETHODCALLTYPE Commit( void) = 0; int Commit(); } /// /// interface IMMDevice /// [Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IMMDevice { int Activate(ref Guid guid, uint context, IntPtr parameters, ref IntPtr pointer); int OpenPropertyStore(uint access, ref IntPtr properties); int GetId(ref IntPtr id); int GetState(ref int state); } /// /// interface IMMDeviceCollection /// [Guid("0BD7A1BE-7A1A-44DB-8397-CC5392387B5E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IMMDevices { //HRESULT GetCount([out, annotation("__out")] UINT* pcDevices); int GetCount(ref uint pcDevices); //HRESULT Item([in, annotation("__in")]UINT nDevice, [out, annotation("__out")] IMMDevice** ppDevice); int Item(uint deviceId, ref IntPtr ppDevice); } /// /// interface IMMDeviceEnumerator /// [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IMMDeviceEnumerator { int EnumAudioEndpoints(EDataFlow dataflow, int mask, ref IntPtr devices); int GetDefaultAudioEndpoint(EDataFlow dataflow, ERole role, ref IntPtr endpoint); int GetDevice(string id, ref IntPtr device); int RegisterEndpointNotificationCallback(IntPtr client); int UnregisterEndpointNotificationCallback(IntPtr client); } [Guid("2A07407E-6497-4A18-9787-32F79BD0D98F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IDeviceTopology { int GetConnectorCount(ref uint pConnectorCount); int GetConnector(uint nIndex, ref IntPtr ppConnector); int GetSubunitCount(ref uint pCount); int GetSubunit(uint nIndex, ref IntPtr ppSubunit); int GetPartById(uint nId, ref IntPtr ppPart); int GetDeviceId(ref IntPtr ppwstrDeviceId); int GetSignalPath(IntPtr pIPartFrom, IntPtr pIPartTo, bool bRejectMixedPaths, ref IntPtr ppParts); } [Guid("9C2C4058-23F5-41DE-877A-DF3AF236A09E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IConnector { int GetType(ref int pType); int GetDataFlow(ref int pFlow); int ConnectTo(ref IntPtr pConnectTo); int Disconnect(); int IsConnected(ref bool pbConnected); int GetConnectedTo(ref IntPtr ppConTo); int GetConnectorIdConnectedTo(ref IntPtr ppwstrConnectorId); int GetDeviceIdConnectedTo(ref IntPtr ppwstrDeviceId); } [Guid("AE2DE0E4-5BCA-4F2D-AA46-5D13F8FDB3A9"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IPart { int GetName(ref string ppwstrName); int GetLocalId(ref uint pnId); int GetGlobalId(ref IntPtr ppwstrGlobalId); int GetPartType(IntPtr pPartType); int GetSubType(ref Guid pSubType); int GetControlInterfaceCount(ref uint pCount); int GetControlInterface(uint nIndex, ref IntPtr ppInterfaceDesc); int EnumPartsIncoming(ref IntPtr ppParts); int EnumPartsOutgoing(ref IntPtr ppParts); int GetTopologyObject(ref IntPtr ppTopology); int Activate(int dwClsContext, ref Guid refiid, ref IntPtr ppvObject); int RegisterControlChangeCallback(ref Guid riid, IntPtr pNotify); int UnregisterControlChangeCallback(IntPtr pNotify); } [Guid("4509F757-2D46-4637-8E62-CE7DB944F57B"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IKsJackDescription { int GetJackCount(ref uint pcJacks); int GetJackDescription(uint nJack, out KSJACK_DESCRIPTION pDescription); } [StructLayout(LayoutKind.Sequential)] internal struct KSJACK_DESCRIPTION { internal int ChannelMapping; internal int Color; internal uint ConnectionType; internal uint GeoLocation; internal uint GenLocation; internal uint PortConnection; internal bool IsConnected; } private struct PropertyKey { public PropertyKey(Guid initId, uint initPid) { id = initId; pid = initPid; } Guid id; uint pid; } private static bool comInitialized; #endregion /// /// Constructor, initialize com interfaces /// internal EndpointCtrl() { int result = 0; //1.to obtain IMMDeviceEnumerator result = InitializedInstance(); if (result != 0) { throw new Win32Exception("Can't obtain IMMDeviceEnumerator: " + result); } //2.to obtain IMMDevice by IMMDeviceEnumerator //result = GetAudioDevice(deviceId); if (result != 0) { throw new Win32Exception("Can't obtain IMMDevice: " + result); } } /// /// initialize com interfaces and get IMMDeviceEnumerator /// /// private static int InitializedInstance() { if (comInitialized == true) { return 0; } const uint CLSCTX_INPROC_SERVER = 1; //1.to obtain IMMDeviceEnumerator int result = NativeMethods.CoCreateInstance(ref CLSID_MMDeviceEnumerator, null, CLSCTX_INPROC_SERVER, ref IID_IUnknown, out oEnumerator); if (result != 0) { return result; } comInitialized = true; if (oEnumerator == null) { return E_FAIL; } iDeviceEnumerator = oEnumerator as IMMDeviceEnumerator; if (iDeviceEnumerator == null) { return E_FAIL; } return result; } /// /// Jack Info method /// /// /// private static int GetJackInfo(IMMDevice iDevice) { IDeviceTopology deviceTopology = null; IConnector connFrom = null; IConnector connTo = null; IPart part = null; IKsJackDescription jackDesc = null; IntPtr tempIntPtr = IntPtr.Zero; IntPtr pPart = IntPtr.Zero; object tempObject = null; uint nJacks = 0; const uint CLSCTX_ALL = 23; int result = 0; int jackInfo = -1; if (iDevice == null) { throw new Exception("No device is specified"); } result = iDevice.Activate(ref IID_IDeviceTopology, CLSCTX_ALL, IntPtr.Zero, ref tempIntPtr); if (result != 0 || tempIntPtr == IntPtr.Zero) { return jackErrorInfo; } tempObject = Marshal.GetObjectForIUnknown(tempIntPtr); deviceTopology = tempObject as IDeviceTopology; tempIntPtr = IntPtr.Zero; tempObject = null; result = deviceTopology.GetConnector(0, ref tempIntPtr); if (result != 0 || tempIntPtr == IntPtr.Zero) { return jackErrorInfo; } tempObject = Marshal.GetObjectForIUnknown(tempIntPtr); connFrom = tempObject as IConnector; tempIntPtr = IntPtr.Zero; tempObject = null; result = connFrom.GetConnectedTo(ref tempIntPtr); if (result != 0 || tempIntPtr == IntPtr.Zero) { return jackErrorInfo; } tempObject = Marshal.GetObjectForIUnknown(tempIntPtr); connTo = tempObject as IConnector; tempObject = null; result = Marshal.QueryInterface(tempIntPtr, ref IID_IPart, out pPart); if (result != 0 || pPart == IntPtr.Zero) { return jackErrorInfo; } tempObject = Marshal.GetObjectForIUnknown(pPart); part = tempObject as IPart; tempIntPtr = IntPtr.Zero; tempObject = null; try { result = part.Activate(1, ref IID_IKsJackDescription, ref tempIntPtr); } catch { return jackErrorInfo; } if (result != 0 || tempIntPtr == IntPtr.Zero) { return jackErrorInfo; } tempObject = Marshal.GetObjectForIUnknown(tempIntPtr); jackDesc = tempObject as IKsJackDescription; result = jackDesc.GetJackCount(ref nJacks); for (uint iJack = 0; iJack < nJacks; iJack++) { KSJACK_DESCRIPTION JackDescription = new KSJACK_DESCRIPTION(); result = jackDesc.GetJackDescription(iJack, out JackDescription); if (result != 0) { return jackErrorInfo; } jackInfo = (int)JackDescription.GeoLocation; } return jackInfo; } /// /// Get expected Audio Device /// /// int GetAudioDevice(string deviceId) { IntPtr pDevice = IntPtr.Zero; int result = 0; if (iDeviceEnumerator == null) return E_FAIL; result = iDeviceEnumerator.GetDevice(deviceId, ref pDevice); if (result != 0) { throw new Win32Exception("Can't obtain IMMDevice: " + result); } oDevice = Marshal.GetObjectForIUnknown(pDevice); iDevice = oDevice as IMMDevice; iDevice.GetState(ref state); return result; } /// /// Get default Audio Device /// /// [EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)] static string GetDefaultAudioDeviceId(string type, ERole role) { IntPtr pDefaultDevice = IntPtr.Zero; IntPtr pID = IntPtr.Zero; string id = ""; int result = 0; object oDefaultDevice; IMMDevice iDefaultDevice; EDataFlow enumDataFlow = EDataFlow.ECapture; if (iDeviceEnumerator == null) return ""; if (type == "Render") { enumDataFlow = EDataFlow.ERender; } try { result = iDeviceEnumerator.GetDefaultAudioEndpoint(enumDataFlow, role, ref pDefaultDevice); if (result != 0) { throw new Win32Exception("Can't obtain IMMDevice: " + result); } oDefaultDevice = Marshal.GetObjectForIUnknown(pDefaultDevice); iDefaultDevice = oDefaultDevice as IMMDevice; if (iDefaultDevice != null) { iDefaultDevice.GetId(ref pID); } id = Marshal.PtrToStringAuto(pID); //return id; } catch (Exception) { id = "error"; } //finally // { // id = "none"; // } return id; } [ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] internal class MMDeviceEnumerator { } /// /// Call this method to release all com objetcs /// [EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)] public virtual void Dispose() { if (iDevice != null) { Marshal.ReleaseComObject(iDevice); iDevice = null; } if (oDevice != null) { Marshal.ReleaseComObject(oDevice); oDevice = null; } if (iDeviceEnumerator != null) { Marshal.ReleaseComObject(iDeviceEnumerator); iDeviceEnumerator = null; } if (oEnumerator != null) { Marshal.ReleaseComObject(oEnumerator); oEnumerator = null; } } #region Public properties /// /// Get the default device state. /// int state; public int State { get { return state; } } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] public string EndpointId { get { IntPtr id = IntPtr.Zero; if (iDevice != null) { iDevice.GetId(ref id); } return Marshal.PtrToStringAuto(id); } } #endregion #region Public Method public string GetDefaultSpeakerEndpoint() { return GetDefaultAudioDeviceId("speakers", ERole.EConsole); } public EndpointList[] GetOutputDevicesByType(EDataFlow DataType) { List list = new List(); IntPtr pDevices = IntPtr.Zero; IntPtr pDevice = IntPtr.Zero; IntPtr ID = IntPtr.Zero; string deviceName = ""; string adapterName = ""; string id = ""; int state = 0; int result = 0; bool bIsDefault = false; string DatatypeString = "Render"; if (DataType == EDataFlow.ECapture) { DatatypeString = "Capture"; } result = InitializedInstance(); if (result != 0 || iDeviceEnumerator == null) { throw new Win32Exception("Can't obtain IMMDeviceEnumerator: " + result); } //2. Get audio device with certain type if (iDeviceEnumerator == null) return null; result = iDeviceEnumerator.EnumAudioEndpoints(DataType, (int)DeviceState.All, ref pDevices); if (result != 0) { return null; } if (pDevices == IntPtr.Zero) return null; oDevices = Marshal.GetObjectForIUnknown(pDevices); iDeviceCollection = oDevices as IMMDevices; uint deviceCount = 0; result = iDeviceCollection.GetCount(ref deviceCount); if (result != 0) { return null; } PROPVARIANT deviceProperty = new PROPVARIANT(); for (uint i = 0; i < deviceCount; i++) { // reset the isDefault bool value //bIsDefault = false; result = iDeviceCollection.Item(i, ref pDevice); if (result != 0 || pDevice == null) { return null; } oDevice = Marshal.GetObjectForIUnknown(pDevice); iDevice = oDevice as IMMDevice; result = iDevice.GetState(ref state); if (result != 0) { continue; } if ((state & (int)DeviceState.NotPresent) != 0) { continue; } IntPtr pProperty = IntPtr.Zero; result = iDevice.OpenPropertyStore(STGM_READ, ref pProperty); if (result != 0) { continue; } oProperty = Marshal.GetObjectForIUnknown(pProperty); iProperty = oProperty as IPropertyStore; result = iProperty.GetValue(ref PKEY_AudioEndpoint_FormFactor, ref deviceProperty); if (result != 0) { continue; } result = iProperty.GetValue(ref PKEY_Device_DeviceDesc, ref deviceProperty); if (result != 0) { continue; } deviceName = deviceProperty.DeviceName; result = iProperty.GetValue(ref PKEY_DeviceInterface_FriendlyName, ref deviceProperty); if (result != 0) { continue; } adapterName = deviceProperty.DeviceName; // Get the endpointID iDevice.GetId(ref ID); if (ID == IntPtr.Zero) { continue; } id = Marshal.PtrToStringAuto(ID); // Jack Info int jackInfo = -1; try { jackInfo = GetJackInfo(iDevice); } catch { jackInfo = jackErrorInfo; } // Get default Id string defaultID = GetDefaultAudioDeviceId(DatatypeString, ERole.EConsole); // Match the defaultID with the current ID //if (defaultID != "none") //{ // if (defaultID == id) // { // bIsDefault = true; // } // else { bIsDefault = false; } //} //else { bIsDefault = false; } if ((defaultID != "error") && (defaultID == id)) { bIsDefault = true; }else { bIsDefault = false; } list.Add(new EndpointList(deviceName, id, adapterName, jackInfo, bIsDefault,state)); } return list.ToArray(); } #endregion } [StructLayout(LayoutKind.Sequential)] public class WAVEFORMATEX { public UInt16 wFormatTag; public UInt16 nChannels; public UInt32 nSamplesPerSec; public UInt32 nAvgBytesPerSec; public UInt16 nBlockAlign; public UInt16 wBitsPerSample; public UInt16 cbSize; } [ComImport, Guid("870AF99C-171D-4f9e-AF0D-E63DF40C2BC9")] public class IPolicyConfigClass { } public static class LoadDLL { [DllImport("AudioDiagnosticUtil.dll", EntryPoint = "AudioGetDeviceFormat", CharSet = CharSet.Auto)] public static extern int AudioGetDeviceFormat(string pszDeviceName, bool bDefault, ref IntPtr ppFormat); [DllImport("AudioDiagnosticUtil.dll", EntryPoint = "AudioSetDeviceFormat", CharSet = CharSet.Auto)] public static extern int AudioSetDeviceFormat(string pszDeviceName, IntPtr pEndpointFormat, IntPtr MixFormat); } [Guid("6be54be8-a068-4875-a49d-0c2966473b11"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IPolicyConfig { int GetMixFormat(string pszDeviceName, ref IntPtr ppFormat); int GetDeviceFormat(string pszDeviceName, bool bDefault, ref IntPtr ppFormat); int ResetDeviceFormat(string pszDeviceName); int SetDeviceFormat(string pszDeviceName, IntPtr pEndpointFormat, IntPtr MixFormat); int GetProcessingPeriod(string pszDeviceName, bool bDefault, IntPtr pmftDefaultPeriod, IntPtr pmftMinimumPeriod); int SetProcessingPeriod(string pszDeviceName, IntPtr pmftPeriod); int GetShareMode(string pszDeviceName, IntPtr pMode); int SetShareMode(string pszDeviceName, IntPtr mode); int GetPropertyValue(string pszDeviceName, bool bFxStore, IntPtr key, IntPtr pv); int SetPropertyValue(string pszDeviceName, bool bFxStore, IntPtr key, IntPtr pv); int SetDefaultEndpoint(string pszDeviceName, ERole role); int SetEndpointVisibility(string pszDeviceName, bool bVisible); int SetScreenReaderState(bool bEnabled); int SetEndpointAbilityToBeDefault(string pszDeviceName, bool bEnable); int SetApplicationDefaultEndpoint(Int32 processId, ERole role, string pszInterfaceId); int ClearApplicationDefaultEndpoint(Int32 processId, ERole role, EDataFlow flow); int RegisterProxyAudioProcess(); int SetDuckingGainForId(string pszStr1, float floatVal); int SetLayoutGainForId(Int32 something1, float floatVal); } public class IPolicyConfigHelper { public Byte[] GetDeviceFormat(string pszDeviceName, bool bDefault, out WAVEFORMATEX retFormat) { IntPtr ptrToWaveFormat = new IntPtr(); LoadDLL.AudioGetDeviceFormat(pszDeviceName, bDefault, ref ptrToWaveFormat); WAVEFORMATEX format = (WAVEFORMATEX)Marshal.PtrToStructure(ptrToWaveFormat, typeof(WAVEFORMATEX)); int formatSize = format.cbSize + Marshal.SizeOf(typeof(WAVEFORMATEX)); Byte[] formatExtData = new Byte[format.cbSize + Marshal.SizeOf(typeof(WAVEFORMATEX))]; Marshal.Copy(ptrToWaveFormat, formatExtData, 0, formatSize); retFormat = format; return formatExtData; } public int SetDeviceFormat(string pszDeviceName, Byte[] formatExtData, int formatSize) { IntPtr ptrToFormat = Marshal.AllocHGlobal(formatSize); Marshal.Copy(formatExtData, 0, ptrToFormat, formatSize); int rval = LoadDLL.AudioSetDeviceFormat(pszDeviceName, ptrToFormat, IntPtr.Zero); Marshal.FreeHGlobal(ptrToFormat); return rval; } } public static bool verifySamplingRate(string deviceID) { EndpointCtrl control = new EndpointCtrl(); bool result = false; string defSpeakerEndpoint = deviceID; IPolicyConfigHelper policyHelper = new IPolicyConfigHelper(); WAVEFORMATEX defaultFormatEx = new WAVEFORMATEX(); WAVEFORMATEX currentFormatEx = new WAVEFORMATEX(); Byte[] defaultFormat = policyHelper.GetDeviceFormat(defSpeakerEndpoint, true, out defaultFormatEx); Byte[] currentFormat = policyHelper.GetDeviceFormat(defSpeakerEndpoint, false, out currentFormatEx); if (defaultFormatEx.nAvgBytesPerSec != currentFormatEx.nAvgBytesPerSec) { result = true; } return result; } public static bool resetSamplingRate(string deviceID) { EndpointCtrl control = new EndpointCtrl(); string defSpeakerEndpoint = deviceID; IPolicyConfigHelper policyHelper = new IPolicyConfigHelper(); WAVEFORMATEX defaultFormatEx = new WAVEFORMATEX(); WAVEFORMATEX currentFormatEx = new WAVEFORMATEX(); Byte[] defaultFormat = policyHelper.GetDeviceFormat(defSpeakerEndpoint, true, out defaultFormatEx); Byte[] currentFormat = policyHelper.GetDeviceFormat(defSpeakerEndpoint, false, out currentFormatEx); policyHelper.SetDeviceFormat(defSpeakerEndpoint, defaultFormat, defaultFormat.Length); WAVEFORMATEX currentFormatEx2 = new WAVEFORMATEX(); Byte[] currentFormat2 = policyHelper.GetDeviceFormat(defSpeakerEndpoint, false, out currentFormatEx2); control.Dispose(); return true; } public static EndpointList[] GetAudioEndPointsbyType(string type) { EDataFlow dataflowtype = new EDataFlow(); if (type == "Render") { dataflowtype = EDataFlow.ERender; } else { dataflowtype = EDataFlow.ECapture; } EndpointCtrl control = new EndpointCtrl(); EndpointList[] list = control.GetOutputDevicesByType(dataflowtype); return list; } } } "@ Add-Type -TypeDefinition $AudioEndpointsSource $AudioEndpoints = [Microsoft.Windows.Diagnosis.AudioResetDeviceFormats] return $AudioEndpoints } # Check whether TS_Main is running or Detecting Additional Problems on Windows 8.1 and above Function Test-PostBack { [CmdletBinding()] PARAM ( [Alias('S')] [Parameter(Position = 1, Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [string] $CurrentScriptName ) PROCESS { # Writing the trace to current directory $CurrentScriptName = ("{0}.temp" -f [System.IO.Path]::GetFileNameWithoutExtension($CurrentScriptName)) if(Test-Path($CurrentScriptName)) { return $true } 'Executed' >> $CurrentScriptName return $false } }