# Copyright © 2015, Microsoft Corporation. All rights reserved. # :: ======================================================= :: <# DESCRIPTION: CL_Utility is common library for audio troubleshooter. ARGUMENTS: None RETURNS: None FUNCTIONS: 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 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 { Register-AudioDiagnosticSnapIn $devices = @() Parse-List $deviceTypes | Foreach-Object { if(-not([String]::IsNullOrEmpty($deviceTypes))) { $devices += Get-AudioDevice -typename "$_" } } foreach($devs in $devices) { $devId = GetId $devs $devName = GetAdapterName $devs if($deviceName -contains $devName) { $deviceID = [string]$devId break } } } finally { Unregister-AudioDiagnosticSnapIn } 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("Speakers/Headphones/Headset Earphone" -eq $deviceType) { $deviceName = $localizationString.audioPlayback } if("microphone/Headset Microphone" -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 "Speakers/Headphones/Headset Earphone") { $deviceTypeName = $localizationString.speaker + ", " + $localizationString.headset + " " + $localizationString.or + " " + $localizationString.headphone } elseif ($deviceType -eq "microphone/Headset Microphone") { $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); 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); } } } '@ 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 {} } } Function Get-AudioSamplingRate() { <# DESCRIPTION: Load the module related to Audio EndPointCtrl and get and set the defalut 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-AudioEndPoints { <# 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() { <# .DESCRIPTION Function to get the device ID of HD audio driver .PARAMETER None .OUTPUTS Array of device ID #> try { $deviceTypes = "Speakers/Headphones/Headset Earphone" $devices = @() $devIds = @() $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 } } Register-AudioDiagnosticSnapIn Parse-List $deviceTypes | Foreach-Object { if(-not([String]::IsNullOrEmpty($deviceTypes))) { $devices += Get-AudioDevice -typename "$_" } } foreach($devs in $devices) { $devId = GetId $devs $deviceName = GetAdapterName $devs if($deviceName.Contains($devName)) { $devIds += $devId } } } finally { Unregister-AudioDiagnosticSnapIn } return $devIds } function Set-AudioEndpointProperty() { <# .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 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 { $errorMsg = $_.Exception.Message $errorMsg | ConvertTo-Xml | Update-DiagReport -Id "CL_Utility" -Name "CL_Utility" -Verbosity Debug } } } return $flag }