diff --git a/test/integration/targets/setup_win_device/handlers/main.yml b/test/integration/targets/setup_win_device/handlers/main.yml new file mode 100644 index 00000000000..5c01331ad72 --- /dev/null +++ b/test/integration/targets/setup_win_device/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: remove dummy network adapter device + win_device: + name: '{{ network_device_name_raw.name }}' + state: absent diff --git a/test/integration/targets/win_dns_client/library/win_device.ps1 b/test/integration/targets/setup_win_device/library/win_device.ps1 similarity index 100% rename from test/integration/targets/win_dns_client/library/win_device.ps1 rename to test/integration/targets/setup_win_device/library/win_device.ps1 diff --git a/test/integration/targets/setup_win_device/tasks/main.yml b/test/integration/targets/setup_win_device/tasks/main.yml new file mode 100644 index 00000000000..cbbb98700bf --- /dev/null +++ b/test/integration/targets/setup_win_device/tasks/main.yml @@ -0,0 +1,22 @@ +# Creates a network adapter device for testing purposes and registers the following vars +# network_device_name: The name of the network device +# network_adapter_name: The name of the network adapter +--- +- name: create dummy network adapter device + win_device: + path: '%WinDir%\Inf\netloop.inf' + hardware_id: '*msloop' + state: present + register: network_device_name_raw + notify: remove dummy network adapter device + +- set_fact: + network_device_name: '{{ network_device_name_raw.name }}' + +- name: get name of the dummy network adapter + win_shell: (Get-CimInstance -Class Win32_NetworkAdapter -Filter "Name='{{ network_device_name }}'").NetConnectionID + changed_when: False + register: network_adapter_name_raw + +- set_fact: + network_adapter_name: '{{ network_adapter_name_raw.stdout | trim }}' diff --git a/test/integration/targets/win_dns_client/meta/main.yml b/test/integration/targets/win_dns_client/meta/main.yml new file mode 100644 index 00000000000..012551418a3 --- /dev/null +++ b/test/integration/targets/win_dns_client/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: +- setup_win_device diff --git a/test/integration/targets/win_dns_client/tasks/main.yml b/test/integration/targets/win_dns_client/tasks/main.yml index 41660eefe6c..c9cdfe8f1b9 100644 --- a/test/integration/targets/win_dns_client/tasks/main.yml +++ b/test/integration/targets/win_dns_client/tasks/main.yml @@ -1,28 +1,178 @@ --- -- name: create dummy network adapter device - win_device: - path: '%WinDir%\Inf\netloop.inf' - hardware_id: '*msloop' - state: present - register: test_device_name - - set_fact: - test_device_name: '{{ test_device_name.name }}' + get_ip_script: | + $adapter = Get-CimInstance -ClassName Win32_NetworkAdapter -Filter "NetConnectionID='{{ network_adapter_name }}'" + $config = Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -Filter "Index=$($adapter.DeviceID)" + $ips = $config.DNSServerSearchOrder + if ($ips) { + $config.DNSServerSearchOrder[0] + $config.DNSServerSearchOrder[1] + } -- block: - - name: get name of the dummy network adapter - win_shell: (Get-CimInstance -Class Win32_NetworkAdapter -Filter "Name='{{ test_device_name }}'").NetConnectionID - changed_when: False - register: test_adapter +- name: set a single IPv4 address (check mode) + win_dns_client: + adapter_name: '{{ network_adapter_name }}' + ipv4_addresses: 192.168.34.5 + register: set_single_check + check_mode: yes - - set_fact: - test_adapter: '{{ test_adapter.stdout | trim }}' +- name: get result of set a single IPv4 address (check mode) + win_shell: '{{ get_ip_script }}' + changed_when: no + register: set_single_actual_check - - name: run tests - include_tasks: tests.yml +- name: assert set a single IPv4 address (check mode) + assert: + that: + - set_single_check is changed + - set_single_actual_check.stdout_lines == [] - always: - - name: remove dummy network adapter device - win_device: - name: '{{ test_device_name }}' - state: absent +- name: set a single IPv4 address + win_dns_client: + adapter_name: '{{ network_adapter_name }}' + ipv4_addresses: 192.168.34.5 + register: set_single + +- name: get result of set a single IPv4 address + win_shell: '{{ get_ip_script }}' + changed_when: no + register: set_single_actual + +- name: assert set a single IPv4 address + assert: + that: + - set_single is changed + - set_single_actual.stdout_lines == ["192.168.34.5"] + +- name: set a single IPv4 address (idempotent) + win_dns_client: + adapter_name: '{{ network_adapter_name }}' + ipv4_addresses: 192.168.34.5 + register: set_single_again + +- name: assert set a single IPv4 address (idempotent) + assert: + that: + - not set_single_again is changed + +- name: change IPv4 address to another value (check mode) + win_dns_client: + adapter_name: '{{ network_adapter_name }}' + ipv4_addresses: 192.168.34.6 + register: change_single_check + check_mode: yes + +- name: get result of change IPv4 address to another value (check mode) + win_shell: '{{ get_ip_script }}' + changed_when: no + register: check_single_actual_check + +- name: assert change IPv4 address to another value (check mode) + assert: + that: + - change_single_check is changed + - check_single_actual_check.stdout_lines == ["192.168.34.5"] + +- name: change IPv4 address to another value + win_dns_client: + adapter_name: '{{ network_adapter_name }}' + ipv4_addresses: 192.168.34.6 + register: change_single + +- name: get result of change IPv4 address to another value + win_shell: '{{ get_ip_script }}' + changed_when: no + register: check_single_actual + +- name: assert change IPv4 address to another value + assert: + that: + - change_single is changed + - check_single_actual.stdout_lines == ["192.168.34.6"] + +- name: set multiple IPv4 addresses (check mode) + win_dns_client: + adapter_name: '{{ network_adapter_name }}' + ipv4_addresses: + - 192.168.34.7 + - 192.168.34.8 + register: set_multiple_check + check_mode: yes + +- name: get result of set multiple IPv4 addresses (check mode) + win_shell: '{{ get_ip_script }}' + changed_when: no + register: set_multiple_actual_check + +- name: assert set multiple IPv4 addresses (check mode) + assert: + that: + - set_multiple_check is changed + - set_multiple_actual_check.stdout_lines == ["192.168.34.6"] + +- name: set multiple IPv4 addresses + win_dns_client: + adapter_name: '{{ network_adapter_name }}' + ipv4_addresses: + - 192.168.34.7 + - 192.168.34.8 + register: set_multiple + +- name: get result of set multiple IPv4 addresses + win_shell: '{{ get_ip_script }}' + changed_when: no + register: set_multiple_actual + +- name: assert set multiple IPv4 addresses + assert: + that: + - set_multiple is changed + - set_multiple_actual.stdout_lines == ["192.168.34.7", "192.168.34.8"] + +- name: set multiple IPv4 addresses (idempotent) + win_dns_client: + adapter_name: '{{ network_adapter_name }}' + ipv4_addresses: + - 192.168.34.7 + - 192.168.34.8 + register: set_multiple_again + +- name: assert set multiple IPv4 addresses (idempotent) + assert: + that: + - not set_multiple_again is changed + +- name: reset IPv4 DNS back to DHCP (check mode) + win_dns_client: + adapter_name: '{{ network_adapter_name }}' + ipv4_addresses: [] + register: set_dhcp_check + check_mode: yes + +- name: get result of reset IPv4 DNS back to DHCP (check mode) + win_shell: '{{ get_ip_script }}' + changed_when: no + register: set_dhcp_actual_check + +- name: assert reset IPv4 DNS back to DHCP (check mode) + assert: + that: + - set_dhcp_check is changed + - set_dhcp_actual_check.stdout_lines == ["192.168.34.7", "192.168.34.8"] + +- name: reset IPv4 DNS back to DHCP + win_dns_client: + adapter_name: '{{ network_adapter_name }}' + ipv4_addresses: [] + register: set_dhcp + +- name: get result of reset IPv4 DNS back to DHCP + win_shell: '{{ get_ip_script }}' + changed_when: no + register: set_dhcp_actual + +- name: assert reset IPv4 DNS back to DHCP + assert: + that: + - set_dhcp is changed + - set_dhcp_actual.stdout_lines == [] diff --git a/test/integration/targets/win_dns_client/tasks/tests.yml b/test/integration/targets/win_dns_client/tasks/tests.yml deleted file mode 100644 index 29cf0813bc0..00000000000 --- a/test/integration/targets/win_dns_client/tasks/tests.yml +++ /dev/null @@ -1,178 +0,0 @@ ---- -- set_fact: - get_ip_script: | - $adapter = Get-CimInstance -ClassName Win32_NetworkAdapter -Filter "NetConnectionID='{{ test_adapter }}'" - $config = Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -Filter "Index=$($adapter.DeviceID)" - $ips = $config.DNSServerSearchOrder - if ($ips) { - $config.DNSServerSearchOrder[0] - $config.DNSServerSearchOrder[1] - } - -- name: set a single IPv4 address (check mode) - win_dns_client: - adapter_name: '{{ test_adapter }}' - ipv4_addresses: 192.168.34.5 - register: set_single_check - check_mode: yes - -- name: get result of set a single IPv4 address (check mode) - win_shell: '{{ get_ip_script }}' - changed_when: no - register: set_single_actual_check - -- name: assert set a single IPv4 address (check mode) - assert: - that: - - set_single_check is changed - - set_single_actual_check.stdout_lines == [] - -- name: set a single IPv4 address - win_dns_client: - adapter_name: '{{ test_adapter }}' - ipv4_addresses: 192.168.34.5 - register: set_single - -- name: get result of set a single IPv4 address - win_shell: '{{ get_ip_script }}' - changed_when: no - register: set_single_actual - -- name: assert set a single IPv4 address - assert: - that: - - set_single is changed - - set_single_actual.stdout_lines == ["192.168.34.5"] - -- name: set a single IPv4 address (idempotent) - win_dns_client: - adapter_name: '{{ test_adapter }}' - ipv4_addresses: 192.168.34.5 - register: set_single_again - -- name: assert set a single IPv4 address (idempotent) - assert: - that: - - not set_single_again is changed - -- name: change IPv4 address to another value (check mode) - win_dns_client: - adapter_name: '{{ test_adapter }}' - ipv4_addresses: 192.168.34.6 - register: change_single_check - check_mode: yes - -- name: get result of change IPv4 address to another value (check mode) - win_shell: '{{ get_ip_script }}' - changed_when: no - register: check_single_actual_check - -- name: assert change IPv4 address to another value (check mode) - assert: - that: - - change_single_check is changed - - check_single_actual_check.stdout_lines == ["192.168.34.5"] - -- name: change IPv4 address to another value - win_dns_client: - adapter_name: '{{ test_adapter }}' - ipv4_addresses: 192.168.34.6 - register: change_single - -- name: get result of change IPv4 address to another value - win_shell: '{{ get_ip_script }}' - changed_when: no - register: check_single_actual - -- name: assert change IPv4 address to another value - assert: - that: - - change_single is changed - - check_single_actual.stdout_lines == ["192.168.34.6"] - -- name: set multiple IPv4 addresses (check mode) - win_dns_client: - adapter_name: '{{ test_adapter }}' - ipv4_addresses: - - 192.168.34.7 - - 192.168.34.8 - register: set_multiple_check - check_mode: yes - -- name: get result of set multiple IPv4 addresses (check mode) - win_shell: '{{ get_ip_script }}' - changed_when: no - register: set_multiple_actual_check - -- name: assert set multiple IPv4 addresses (check mode) - assert: - that: - - set_multiple_check is changed - - set_multiple_actual_check.stdout_lines == ["192.168.34.6"] - -- name: set multiple IPv4 addresses - win_dns_client: - adapter_name: '{{ test_adapter }}' - ipv4_addresses: - - 192.168.34.7 - - 192.168.34.8 - register: set_multiple - -- name: get result of set multiple IPv4 addresses - win_shell: '{{ get_ip_script }}' - changed_when: no - register: set_multiple_actual - -- name: assert set multiple IPv4 addresses - assert: - that: - - set_multiple is changed - - set_multiple_actual.stdout_lines == ["192.168.34.7", "192.168.34.8"] - -- name: set multiple IPv4 addresses (idempotent) - win_dns_client: - adapter_name: '{{ test_adapter }}' - ipv4_addresses: - - 192.168.34.7 - - 192.168.34.8 - register: set_multiple_again - -- name: assert set multiple IPv4 addresses (idempotent) - assert: - that: - - not set_multiple_again is changed - -- name: reset IPv4 DNS back to DHCP (check mode) - win_dns_client: - adapter_name: '{{ test_adapter }}' - ipv4_addresses: [] - register: set_dhcp_check - check_mode: yes - -- name: get result of reset IPv4 DNS back to DHCP (check mode) - win_shell: '{{ get_ip_script }}' - changed_when: no - register: set_dhcp_actual_check - -- name: assert reset IPv4 DNS back to DHCP (check mode) - assert: - that: - - set_dhcp_check is changed - - set_dhcp_actual_check.stdout_lines == ["192.168.34.7", "192.168.34.8"] - -- name: reset IPv4 DNS back to DHCP - win_dns_client: - adapter_name: '{{ test_adapter }}' - ipv4_addresses: [] - register: set_dhcp - -- name: get result of reset IPv4 DNS back to DHCP - win_shell: '{{ get_ip_script }}' - changed_when: no - register: set_dhcp_actual - -- name: assert reset IPv4 DNS back to DHCP - assert: - that: - - set_dhcp is changed - - set_dhcp_actual.stdout_lines == [] diff --git a/test/integration/targets/win_netbios/library/win_device.ps1 b/test/integration/targets/win_netbios/library/win_device.ps1 deleted file mode 100644 index 2b69bdbf6d4..00000000000 --- a/test/integration/targets/win_netbios/library/win_device.ps1 +++ /dev/null @@ -1,541 +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() diff --git a/test/integration/targets/win_netbios/meta/main.yml b/test/integration/targets/win_netbios/meta/main.yml new file mode 100644 index 00000000000..e7f499ee343 --- /dev/null +++ b/test/integration/targets/win_netbios/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: +- setup_win_device \ No newline at end of file diff --git a/test/integration/targets/win_netbios/tasks/main.yml b/test/integration/targets/win_netbios/tasks/main.yml index 01f5b435b4a..2f96287bb00 100644 --- a/test/integration/targets/win_netbios/tasks/main.yml +++ b/test/integration/targets/win_netbios/tasks/main.yml @@ -16,39 +16,15 @@ # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . - - name: ensure netbios is set to default to start with win_netbios: state: default -- name: create dummy network adapter device - win_device: - path: '%WinDir%\Inf\netloop.inf' - hardware_id: '*msloop' - state: present - register: test_device_name - -- set_fact: - test_device_name: '{{ test_device_name.name }}' - - block: - - name: get name of the dummy network adapter - win_shell: (Get-CimInstance -Class Win32_NetworkAdapter -Filter "Name='{{ test_device_name }}'").NetConnectionID - changed_when: False - register: test_adapter - - - set_fact: - test_adapter: '{{ test_adapter.stdout | trim }}' - - name: run tests include_tasks: tests.yml always: - - name: remove dummy network adapter device - win_device: - name: '{{ test_device_name }}' - state: absent - - name: set netbios back to default after tests win_netbios: state: default \ No newline at end of file diff --git a/test/integration/targets/win_netbios/tasks/tests.yml b/test/integration/targets/win_netbios/tasks/tests.yml index 9527ab691a4..961b91dc04d 100644 --- a/test/integration/targets/win_netbios/tasks/tests.yml +++ b/test/integration/targets/win_netbios/tasks/tests.yml @@ -18,13 +18,13 @@ - set_fact: get_netbios_script: | - $adapter = Get-CimInstance -ClassName Win32_NetworkAdapter -Filter "NetConnectionID='{{ test_adapter }}'" + $adapter = Get-CimInstance -ClassName Win32_NetworkAdapter -Filter "NetConnectionID='{{ network_adapter_name }}'" $config = Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -Filter "Index=$($adapter.DeviceID)" $config.TcpipNetbiosOptions - name: disable netbios single adapter (check mode) win_netbios: - adapter_names: '{{ test_adapter }}' + adapter_names: '{{ network_adapter_name }}' state: disabled register: set_single_check check_mode: yes @@ -42,7 +42,7 @@ - name: disable netbios single adapter win_netbios: - adapter_names: '{{ test_adapter }}' + adapter_names: '{{ network_adapter_name }}' state: disabled register: set_single