# 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
}
}