diff options
Diffstat (limited to 'test/integration/targets/setup_win_device/library/win_device.ps1')
-rw-r--r-- | test/integration/targets/setup_win_device/library/win_device.ps1 | 542 |
1 files changed, 0 insertions, 542 deletions
diff --git a/test/integration/targets/setup_win_device/library/win_device.ps1 b/test/integration/targets/setup_win_device/library/win_device.ps1 deleted file mode 100644 index e95d4c818c..0000000000 --- a/test/integration/targets/setup_win_device/library/win_device.ps1 +++ /dev/null @@ -1,542 +0,0 @@ -#!powershell - -#AnsibleRequires -CSharpUtil Ansible.Basic -#Requires -Module Ansible.ModuleUtils.AddType - -$spec = @{ - options = @{ - hardware_id = @{ type = "str" } - name = @{ type = "str" } - path = @{ type = "path" } - state = @{ type = "str"; choices = @("absent", "present"); default = "present" } - } - required_if = @( - @("state", "present", @("path", "hardware_id"), $true), - @("state", "absent", @(,"name")) - ) - supports_check_mode = $true -} - -$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec) - -$hardware_id = $module.Params.hardware_id -$name = $module.Params.name -$path = $module.Params.path -$state = $module.Params.state - -$module.Result.reboot_required = $false - -Add-CSharpType -References @' -using Microsoft.Win32.SafeHandles; -using System; -using System.ComponentModel; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; -using System.Text; - -namespace Ansible.Device -{ - public class NativeHelpers - { - [StructLayout(LayoutKind.Sequential)] - public class SP_DEVINFO_DATA - { - public UInt32 cbSize; - public Guid ClassGuid; - public UInt32 DevInst; - public IntPtr Reserved; - - public SP_DEVINFO_DATA() - { - this.cbSize = (UInt32)Marshal.SizeOf(this); - this.ClassGuid = Guid.Empty; - } - } - - [Flags] - public enum DeviceInfoCreationFlags : uint - { - DICD_GENERATE_ID = 0x00000001, - DICD_INHERIT_CLASSDRVS = 0x00000002, - } - - public enum DeviceProperty : uint - { - SPDRP_DEVICEDESC = 0x0000000, - SPDRP_HARDWAREID = 0x0000001, - SPDRP_COMPATIBLEIDS = 0x0000002, - SPDRP_UNUSED0 = 0x0000003, - SPDRP_SERVICE = 0x0000004, - SPDRP_UNUSED1 = 0x0000005, - SPDRP_UNUSED2 = 0x0000006, - SPDRP_CLASS = 0x0000007, // Read only - tied to ClassGUID - SPDRP_CLASSGUID = 0x0000008, - SPDRP_DRIVER = 0x0000009, - SPDRP_CONFIGFLAGS = 0x000000a, - SPDRP_MFG = 0x000000b, - SPDRP_FRIENDLYNAME = 0x000000c, - SPDRP_LOCATION_INFORMATION = 0x000000d, - SPDRP_PHYSICAL_DEVICE_OBJECT_NAME = 0x000000e, // Read only - SPDRP_CAPABILITIES = 0x000000f, // Read only - SPDRP_UI_NUMBER = 0x0000010, // Read only - SPDRP_UPPERFILTERS = 0x0000011, - SPDRP_LOWERFILTERS = 0x0000012, - SPDRP_BUSTYPEGUID = 0x0000013, // Read only - SPDRP_LEGACYBUSTYPE = 0x0000014, // Read only - SPDRP_BUSNUMBER = 0x0000015, // Read only - SPDRP_ENUMERATOR_NAME = 0x0000016, // Read only - SPDRP_SECURITY = 0x0000017, - SPDRP_SECURITY_SDS = 0x0000018, - SPDRP_DEVTYPE = 0x0000019, - SPDRP_EXCLUSIVE = 0x000001a, - SPDRP_CHARACTERISTICS = 0x000001b, - SPDRP_ADDRESS = 0x000001c, // Read only - SPDRP_UI_NUMBER_DESC_FORMAT = 0x000001d, - SPDRP_DEVICE_POWER_DATA = 0x000001e, // Read only - SPDRP_REMOVAL_POLICY = 0x000001f, // Read only - SPDRP_REMOVAL_POLICY_HW_DEFAULT = 0x0000020, // Read only - SPDRP_REMOVAL_POLICY_OVERRIDE = 0x0000021, - SPDRP_INSTALL_STATE = 0x0000022, // Read only - SPDRP_LOCATION_PATHS = 0x0000023, // Read only - SPDRP_BASE_CONTAINERID = 0x0000024, // Read only - } - - // https://docs.microsoft.com/en-us/previous-versions/ff549793%28v%3dvs.85%29 - public enum DifCodes : uint - { - DIF_SELECTDIVE = 0x00000001, - DIF_INSTALLDEVICE = 0x00000002, - DIF_ASSIGNRESOURCES = 0x00000003, - DIF_PROPERTIES = 0x00000004, - DIF_REMOVE = 0x00000005, - DIF_FIRSTTIMESETUP = 0x00000006, - DIF_FOUNDDEVICE = 0x00000007, - DIF_SELECTCLASSDRIVERS = 0x00000008, - DIF_VALIDATECLASSDRIVERS = 0x00000009, - DIF_INSTALLCLASSDRIVERS = 0x0000000a, - DIF_CALCDISKSPACE = 0x0000000b, - DIF_DESTROYPRIVATEDATA = 0x0000000c, - DIF_VALIDATEDRIVER = 0x0000000d, - DIF_DETECT = 0x0000000f, - DIF_INSTALLWIZARD = 0x00000010, - DIF_DESTROYWIZARDDATA = 0x00000011, - DIF_PROPERTYCHANGE = 0x00000012, - DIF_ENABLECLASS = 0x00000013, - DIF_DETECTVERIFY = 0x00000014, - DIF_INSTALLDEVICEFILES = 0x00000015, - DIF_UNREMOVE = 0x00000016, - DIF_SELECTBESTCOMPATDRV = 0x00000017, - DIF_ALLOW_INSTALL = 0x00000018, - DIF_REGISTERDEVICE = 0x00000019, - DIF_NEWDEVICEWIZARD_PRESELECT = 0x0000001a, - DIF_NEWDEVICEWIZARD_SELECT = 0x0000001b, - DIF_NEWDEVICEWIZARD_PREANALYZE = 0x0000001c, - DIF_NEWDEVICEWIZARD_POSTANALYZE = 0x0000001d, - DIF_NEWDEVICEWIZARD_FINISHINSTALL = 0x0000001e, - DIF_UNUSED1 = 0x0000001e, - DIF_INSTALLINTERFACES = 0x00000020, - DIF_DETECTCANCEL = 0x00000021, - DIF_REGISTER_COINSTALLERS = 0x00000022, - DIF_ADDPROPERTYPAGE_ADVANCED = 0x00000023, - DIF_ADDPROPERTYPAGE_BASIC = 0x00000024, - DIF_RESERVED1 = 0x00000025, - DIF_TROUBLESHOOTER = 0x00000026, - DIF_POWERMESSAGEWAKE = 0x00000027, - DIF_ADDREMOTEPROPERTYPAGE_ADVANCED = 0x00000028, - DIF_UPDATEDRIVER_UI = 0x00000029, - DIF_FINISHINSTALL_ACTION = 0x0000002a, - } - - [Flags] - public enum GetClassFlags : uint - { - DIGCF_DEFAULT = 0x00000001, - DIGCF_PRESENT = 0x00000002, - DIGCF_ALLCLASSES = 0x00000004, - DIGCF_PROFILE = 0x00000008, - DIGCF_DEVICEINTERFACE = 0x00000010, - } - - [Flags] - public enum InstallFlags : uint - { - INSTALLFLAG_FORCE = 0x00000001, - INSTALLFLAG_READONLY = 0x00000002, - INSTALLFLAG_NONINTERACTIVE = 0x00000004, - INSTALLFLAG_BITS = 0x00000007, - } - } - - public class NativeMethods - { - [DllImport("Setupapi.dll", SetLastError = true)] - public static extern bool SetupDiCallClassInstaller( - NativeHelpers.DifCodes InstallFunction, - SafeDeviceInfoSet DeviceInfoSet, - NativeHelpers.SP_DEVINFO_DATA DeviceInfoData); - - [DllImport("Setupapi.dll", SetLastError = true)] - public static extern SafeDeviceInfoSet SetupDiCreateDeviceInfoList( - Guid ClassGuid, - IntPtr hwndParent); - - [DllImport("Setupapi.dll", SetLastError = true)] - public static extern bool SetupDiCreateDeviceInfoW( - SafeDeviceInfoSet DeviceInfoSet, - [MarshalAs(UnmanagedType.LPWStr)] string DeviceName, - Guid ClassGuid, - [MarshalAs(UnmanagedType.LPWStr)] string DeviceDescription, - IntPtr hwndParent, - NativeHelpers.DeviceInfoCreationFlags CreationFlags, - NativeHelpers.SP_DEVINFO_DATA DeviceInfoData); - - [DllImport("Setupapi.dll", SetLastError = true)] - public static extern bool SetupDiDestroyDeviceInfoList( - IntPtr DeviceInfoSet); - - [DllImport("Setupapi.dll", SetLastError = true)] - public static extern bool SetupDiEnumDeviceInfo( - SafeDeviceInfoSet DeviceInfoSet, - UInt32 MemberIndex, - NativeHelpers.SP_DEVINFO_DATA DeviceInfoData); - - [DllImport("Setupapi.dll", SetLastError = true)] - public static extern SafeDeviceInfoSet SetupDiGetClassDevsW( - Guid ClassGuid, - [MarshalAs(UnmanagedType.LPWStr)] string Enumerator, - IntPtr hwndParent, - NativeHelpers.GetClassFlags Flags); - - [DllImport("Setupapi.dll", SetLastError = true)] - public static extern bool SetupDiGetDeviceRegistryPropertyW( - SafeDeviceInfoSet DeviceInfoSet, - NativeHelpers.SP_DEVINFO_DATA DeviceInfoData, - NativeHelpers.DeviceProperty Property, - out UInt32 PropertyRegDataType, - SafeMemoryBuffer PropertyBuffer, - UInt32 PropertyBufferSize, - ref UInt32 RequiredSize); - - [DllImport("Setupapi.dll", SetLastError = true)] - public static extern bool SetupDiGetINFClassW( - [MarshalAs(UnmanagedType.LPWStr)] string InfName, - ref Guid ClassGuid, - [MarshalAs(UnmanagedType.LPWStr)] StringBuilder ClassName, - UInt32 ClassNameSize, - ref UInt32 RequiredSize); - - [DllImport("Setupapi.dll", SetLastError = true)] - public static extern bool SetupDiSetDeviceRegistryPropertyW( - SafeDeviceInfoSet DeviceInfoSet, - NativeHelpers.SP_DEVINFO_DATA DeviceInfoData, - NativeHelpers.DeviceProperty Property, - SafeMemoryBuffer PropertyBuffer, - UInt32 PropertyBufferSize); - - [DllImport("Newdev.dll", SetLastError = true)] - public static extern bool UpdateDriverForPlugAndPlayDevicesW( - IntPtr hwndParent, - [MarshalAs(UnmanagedType.LPWStr)] string HardwareId, - [MarshalAs(UnmanagedType.LPWStr)] string FullInfPath, - NativeHelpers.InstallFlags InstallFlags, - ref bool bRebootRequired); - } - - public class SafeDeviceInfoSet : SafeHandleZeroOrMinusOneIsInvalid - { - public SafeDeviceInfoSet() : base(true) { } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - protected override bool ReleaseHandle() - { - return NativeMethods.SetupDiDestroyDeviceInfoList(handle); - } - } - - public class SafeMemoryBuffer : SafeHandleZeroOrMinusOneIsInvalid - { - public int Length = 0; - - public SafeMemoryBuffer() : base(true) { } - - public SafeMemoryBuffer(int cb) : base(true) - { - Length = cb; - base.SetHandle(Marshal.AllocHGlobal(cb)); - } - - public SafeMemoryBuffer(string sz) : base(true) - { - Length = sz.Length * sizeof(char); - base.SetHandle(Marshal.StringToHGlobalUni(sz)); - } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - protected override bool ReleaseHandle() - { - Marshal.FreeHGlobal(handle); - return true; - } - } - - public class DeviceUtil - { - public static string GetDeviceFriendlyName(SafeDeviceInfoSet devInfoSet, NativeHelpers.SP_DEVINFO_DATA devInfo) - { - string friendlyName = GetDeviceStringProp(devInfoSet, devInfo, NativeHelpers.DeviceProperty.SPDRP_FRIENDLYNAME); - - // Older Windows versions may not have a friendly name set. This seems to be the case when the device has - // a unique description so we fallback to that value. - if (null == friendlyName) - friendlyName = GetDeviceStringProp(devInfoSet, devInfo, NativeHelpers.DeviceProperty.SPDRP_DEVICEDESC); - - return friendlyName; - } - - public static void SetDeviceHardwareId(SafeDeviceInfoSet devInfoSet, NativeHelpers.SP_DEVINFO_DATA devInfo, - string hardwareId) - { - SetDeviceStringProp(devInfoSet, devInfo, NativeHelpers.DeviceProperty.SPDRP_HARDWAREID, hardwareId); - } - - private static string GetDeviceStringProp(SafeDeviceInfoSet devInfoSet, NativeHelpers.SP_DEVINFO_DATA devInfo, - NativeHelpers.DeviceProperty property) - { - using (SafeMemoryBuffer memBuf = GetDeviceProperty(devInfoSet, devInfo, property)) - { - if (memBuf.IsInvalid) // Property does not exist so just return null. - return null; - - return Marshal.PtrToStringUni(memBuf.DangerousGetHandle()); - } - } - - private static SafeMemoryBuffer GetDeviceProperty(SafeDeviceInfoSet devInfoSet, - NativeHelpers.SP_DEVINFO_DATA devInfo, NativeHelpers.DeviceProperty property) - { - UInt32 requiredSize = 0; - UInt32 regDataType = 0; - if (!NativeMethods.SetupDiGetDeviceRegistryPropertyW(devInfoSet, devInfo, property, - out regDataType, new SafeMemoryBuffer(0), 0, ref requiredSize)) - { - int errCode = Marshal.GetLastWin32Error(); - if (errCode == 0x0000000D) // ERROR_INVALID_DATA - return new SafeMemoryBuffer(); // The FRIENDLYNAME property does not exist - else if (errCode != 0x0000007A) // ERROR_INSUFFICIENT_BUFFER - throw new Win32Exception(errCode); - } - - SafeMemoryBuffer memBuf = new SafeMemoryBuffer((int)requiredSize); - if (!NativeMethods.SetupDiGetDeviceRegistryPropertyW(devInfoSet, devInfo, property, - out regDataType, memBuf, requiredSize, ref requiredSize)) - { - int errCode = Marshal.GetLastWin32Error(); - memBuf.Dispose(); - - throw new Win32Exception(errCode); - } - - return memBuf; - } - - private static void SetDeviceStringProp(SafeDeviceInfoSet devInfoSet, NativeHelpers.SP_DEVINFO_DATA devInfo, - NativeHelpers.DeviceProperty property, string value) - { - using (SafeMemoryBuffer buffer = new SafeMemoryBuffer(value)) - SetDeviceProperty(devInfoSet, devInfo, property, buffer); - } - - private static void SetDeviceProperty(SafeDeviceInfoSet devInfoSet, NativeHelpers.SP_DEVINFO_DATA devInfo, - NativeHelpers.DeviceProperty property, SafeMemoryBuffer buffer) - { - if (!NativeMethods.SetupDiSetDeviceRegistryPropertyW(devInfoSet, devInfo, property, buffer, - (UInt32)buffer.Length)) - { - throw new Win32Exception(Marshal.GetLastWin32Error()); - } - } - } -} -'@ - -Function Get-Win32ErrorMessage { - Param ([System.Int32]$ErrorCode) - - $exp = New-Object -TypeName System.ComponentModel.Win32Exception -ArgumentList $ErrorCode - return ("{0} (Win32 ErrorCode {1} - 0x{1:X8}" -f $exp.Message, $ErrorCode) -} - -# Determine if the device is already installed -$dev_info_set = [Ansible.Device.NativeMethods]::SetupDiGetClassDevsW( - [Guid]::Empty, - [NullString]::Value, - [System.IntPtr]::Zero, - [Ansible.Device.NativeHelpers+GetClassFlags]::DIGCF_ALLCLASSES -); $err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() - -try { - if ($dev_info_set.IsInvalid) { - $msg = Get-Win32ErrorMessage -ErrorCode $err - $module.FailJson("Failed to get device information set for installed devices: $msg") - } - - $dev_info = $null - if ($null -ne $name) { - # Loop through the set of all devices and compare the name - $idx = 0 - while ($true) { - $dev_info = New-Object -TypeName Ansible.Device.NativeHelpers+SP_DEVINFO_DATA - $res = [Ansible.Device.NativeMethods]::SetupDiEnumDeviceInfo( - $dev_info_set, - $idx, - $dev_info - ); $err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() - - if (-not $res) { - $dev_info = $null - if ($err -eq 0x00000103) { # ERROR_NO_MORE_ITEMS - break - } - - $msg = Get-Win32ErrorMessage -ErrorCode $err - $module.FailJson("Failed to enumerate device information set at index $($idx): $msg") - } - - $device_name = [Ansible.Device.DeviceUtil]::GetDeviceFriendlyName($dev_info_set, $dev_info) - if ($device_name -eq $name) { - break - } - - $dev_info = $null - $idx++ - } - } - - if ($state -eq "absent" -and $null -ne $dev_info) { - if (-not $module.CheckMode) { - $res = [Ansible.Device.NativeMethods]::SetupDiCallClassInstaller( - [Ansible.Device.NativeHelpers+DifCodes]::DIF_REMOVE, - $dev_info_set, - $dev_info - ); $err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() - - if (-not $res) { - $msg = Get-Win32ErrorMessage -ErrorCode $err - $module.FailJson("Failed to remove device $($name): $msg") - } - } - - $module.Result.changed = $true - } elseif ($state -eq "present" -and $null -eq $dev_info) { - # Populate the class guid and display name if the path to an inf file was set. - $class_id = [Guid]::Empty - $class_name = $null - if ($path) { - if (-not (Test-Path -LiteralPath $path)) { - $module.FailJson("Could not find the inf file specified at '$path'") - } - - $class_name_sb = New-Object -TypeName System.Text.StringBuilder -ArgumentList 32 # MAX_CLASS_NAME_LEN - $required_size = 0 - $res = [Ansible.Device.NativeMethods]::SetupDiGetINFClassW( - $path, - [ref]$class_id, - $class_name_sb, - $class_name_sb.Capacity, - [ref]$required_size - ); $err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() - - if (-not $res) { - $msg = Get-Win32ErrorMessage -ErrorCode $err - $module.FailJson("Failed to parse driver inf at '$path': $msg") - } - - $class_name = $class_name_sb.ToString() - } - - # When creating a new device we want to start with a blank device information set. - $dev_info_set.Dispose() - - $dev_info_set = [Ansible.Device.NativeMethods]::SetupDiCreateDeviceInfoList( - $class_id, - [System.IntPtr]::Zero - ); $err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() - - if ($dev_info_set.IsInvalid) { - $msg = Get-Win32ErrorMessage -ErrorCode $err - $module.FailJson("Failed to create device info set for the class $($class_id): $msg") - } - - # Create the new device element and add it to the device info set - $dev_info = New-Object -TypeName Ansible.Device.NativeHelpers+SP_DEVINFO_DATA - $res = [Ansible.Device.NativeMethods]::SetupDiCreateDeviceInfoW( - $dev_info_set, - $class_name, - $class_id, - $null, - [System.IntPtr]::Zero, - [Ansible.Device.NativeHelpers+DeviceInfoCreationFlags]::DICD_GENERATE_ID, - $dev_info - ); $err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() - - if (-not $res) { - $msg = Get-Win32ErrorMessage -ErrorCode $err - $module.FailJson("Failed to create new device element for class $($class_name): $msg") - } - - # Set the hardware id of the new device so we can load the proper driver. - [Ansible.Device.DeviceUtil]::SetDeviceHardwareId($dev_info_set, $dev_info, $hardware_id) - - if (-not $module.CheckMode) { - # Install the device - $res = [Ansible.Device.NativeMethods]::SetupDiCallClassInstaller( - [Ansible.Device.NativeHelpers+DifCodes]::DIF_REGISTERDEVICE, - $dev_info_set, - $dev_info - ); $err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() - - if (-not $res) { - $msg = Get-Win32ErrorMessage -ErrorCode $err - $module.FailJson("Failed to register new device for class $($class_name): $msg") - } - - # Load the drivers for the new device - $reboot_required = $false - $res = [Ansible.Device.NativeMethods]::UpdateDriverForPlugAndPlayDevicesW( - [System.IntPtr]::Zero, - $hardware_id, - $path, - [Ansible.Device.NativeHelpers+InstallFlags]'INSTALLFLAG_FORCE, INSTALLFLAG_NONINTERACTIVE', - [ref]$reboot_required - ); $err = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() - - if (-not $res) { - # On a failure make sure we cleanup the "installed" device - [Ansible.Device.NativeMethods]::SetupDiCallClassInstaller( - [Ansible.Device.NativeHelpers+DifCodes]::DIF_REMOVE, - $dev_info_set, - $dev_info - ) > $null - - $msg = Get-Win32ErrorMessage -ErrorCode $err - $module.FailJson("Failed to update device driver: $msg") - } - - $module.Result.reboot_required = $reboot_required - - # Now get the name of the newly created device which we return back to Ansible. - $name = [Ansible.Device.DeviceUtil]::GetDeviceFriendlyName($dev_info_set, $dev_info) - } else { - # Generate random name for check mode output - $name = "Check mode generated device for $($class_name)" - } - $module.Result.changed = $true - } -} finally { - $dev_info_set.Dispose() -} - -$module.Result.name = $name - -$module.ExitJson() - |