summaryrefslogtreecommitdiff
path: root/lib/ansible/module_utils/powershell
diff options
context:
space:
mode:
authorJordan Borean <jborean93@gmail.com>2018-04-06 07:59:51 +1000
committerMatt Davis <nitzmahone@users.noreply.github.com>2018-04-05 14:59:51 -0700
commit71e8527d7cc5ac9110ac6b440e6c389de4a09763 (patch)
tree3392efa7377c5fde3dd73fe64eb9287188c35728 /lib/ansible/module_utils/powershell
parentfd4d264253f6faba2fb30b4a3c469e13d411d0fc (diff)
downloadansible-71e8527d7cc5ac9110ac6b440e6c389de4a09763.tar.gz
powershell: display non-ascii characters in command outputs (#37229)
Diffstat (limited to 'lib/ansible/module_utils/powershell')
-rw-r--r--lib/ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm183
1 files changed, 17 insertions, 66 deletions
diff --git a/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 b/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1
index 9b85f4934f..ce94827dbc 100644
--- a/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1
+++ b/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1
@@ -2,6 +2,7 @@
# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
$process_util = @"
+using Microsoft.Win32.SafeHandles;
using System;
using System.Collections;
using System.IO;
@@ -42,9 +43,9 @@ namespace Ansible
public Int16 wShowWindow;
public Int16 cbReserved2;
public IntPtr lpReserved2;
- public IntPtr hStdInput;
- public IntPtr hStdOutput;
- public IntPtr hStdError;
+ public SafeFileHandle hStdInput;
+ public SafeFileHandle hStdOutput;
+ public SafeFileHandle hStdError;
public STARTUPINFO()
{
cb = Marshal.SizeOf(this);
@@ -88,7 +89,7 @@ namespace Ansible
{
public NativeWaitHandle(IntPtr handle)
{
- this.Handle = handle;
+ this.SafeWaitHandle = new SafeWaitHandle(handle, false);
}
}
@@ -110,7 +111,6 @@ namespace Ansible
public class CommandUtil
{
private static UInt32 CREATE_UNICODE_ENVIRONMENT = 0x000000400;
- private static UInt32 CREATE_NEW_CONSOLE = 0x00000010;
private static UInt32 EXTENDED_STARTUPINFO_PRESENT = 0x00080000;
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)]
@@ -130,43 +130,22 @@ namespace Ansible
[DllImport("kernel32.dll")]
public static extern bool CreatePipe(
- out IntPtr hReadPipe,
- out IntPtr hWritePipe,
+ out SafeFileHandle hReadPipe,
+ out SafeFileHandle hWritePipe,
SECURITY_ATTRIBUTES lpPipeAttributes,
uint nSize);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetHandleInformation(
- IntPtr hObject,
+ SafeFileHandle hObject,
HandleFlags dwMask,
int dwFlags);
[DllImport("kernel32.dll", SetLastError = true)]
- public static extern bool InitializeProcThreadAttributeList(
- IntPtr lpAttributeList,
- int dwAttributeCount,
- int dwFlags,
- ref int lpSize);
-
- [DllImport("kernel32.dll", SetLastError = true)]
- public static extern bool UpdateProcThreadAttribute(
- IntPtr lpAttributeList,
- uint dwFlags,
- IntPtr Attribute,
- IntPtr lpValue,
- IntPtr cbSize,
- IntPtr lpPreviousValue,
- IntPtr lpReturnSize);
-
- [DllImport("kernel32.dll", SetLastError = true)]
private static extern bool GetExitCodeProcess(
IntPtr hProcess,
out uint lpExitCode);
- [DllImport("kernel32.dll", SetLastError = true)]
- public static extern bool CloseHandle(
- IntPtr hObject);
-
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint SearchPath(
string lpPath,
@@ -220,7 +199,7 @@ namespace Ansible
public static CommandResult RunCommand(string lpApplicationName, string lpCommandLine, string lpCurrentDirectory, string stdinInput, IDictionary environment)
{
- UInt32 startup_flags = CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE | EXTENDED_STARTUPINFO_PRESENT;
+ UInt32 startup_flags = CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT;
STARTUPINFOEX si = new STARTUPINFOEX();
si.startupInfo.dwFlags = (int)StartupInfoFlags.USESTDHANDLES;
@@ -228,7 +207,7 @@ namespace Ansible
pipesec.bInheritHandle = true;
// Create the stdout, stderr and stdin pipes used in the process and add to the startupInfo
- IntPtr stdout_read, stdout_write, stderr_read, stderr_write, stdin_read, stdin_write = IntPtr.Zero;
+ SafeFileHandle stdout_read, stdout_write, stderr_read, stderr_write, stdin_read, stdin_write;
if (!CreatePipe(out stdout_read, out stdout_write, pipesec, 0))
throw new Win32Exception("STDOUT pipe setup failed");
if (!SetHandleInformation(stdout_read, HandleFlags.INHERIT, 0))
@@ -248,37 +227,9 @@ namespace Ansible
si.startupInfo.hStdError = stderr_write;
si.startupInfo.hStdInput = stdin_read;
- // Handle the inheritance for the pipes so the process can access them
- Int32 buf_sz = 0;
- if (!InitializeProcThreadAttributeList(IntPtr.Zero, 1, 0, ref buf_sz))
- {
- int last_err = Marshal.GetLastWin32Error();
- if (last_err != 122) // ERROR_INSUFFICIENT_BUFFER
- throw new Win32Exception(last_err, "Attribute list size query failed");
- }
- si.lpAttributeList = Marshal.AllocHGlobal(buf_sz);
- if (!InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, ref buf_sz))
- throw new Win32Exception("Attribute list init failed");
-
-
- IntPtr[] handles_to_inherit = new IntPtr[3];
- handles_to_inherit[0] = stdin_read;
- handles_to_inherit[1] = stdout_write;
- handles_to_inherit[2] = stderr_write;
- GCHandle pinned_handles = GCHandle.Alloc(handles_to_inherit, GCHandleType.Pinned);
-
- if (!UpdateProcThreadAttribute(si.lpAttributeList, 0,
- (IntPtr)0x20002, // PROC_THREAD_ATTRIBUTE_HANDLE_LIST
- pinned_handles.AddrOfPinnedObject(),
- (IntPtr)(Marshal.SizeOf(typeof(IntPtr)) * handles_to_inherit.Length),
- IntPtr.Zero, IntPtr.Zero))
- {
- throw new Win32Exception("Attribute list update failed");
- }
-
// Setup the stdin buffer
UTF8Encoding utf8_encoding = new UTF8Encoding(false);
- FileStream stdin_fs = new FileStream(stdin_write, FileAccess.Write, true, 32768);
+ FileStream stdin_fs = new FileStream(stdin_write, FileAccess.Write, 32768);
StreamWriter stdin = new StreamWriter(stdin_fs, utf8_encoding, 32768);
// If lpCurrentDirectory is set to null in PS it will be an empty
@@ -288,7 +239,7 @@ namespace Ansible
StringBuilder environmentString = null;
- if(environment != null && environment.Count > 0)
+ if (environment != null && environment.Count > 0)
{
environmentString = new StringBuilder();
foreach (DictionaryEntry kv in environment)
@@ -320,12 +271,12 @@ namespace Ansible
}
// Setup the output buffers and get stdout/stderr
- FileStream stdout_fs = new FileStream(stdout_read, FileAccess.Read, true, 4096);
+ FileStream stdout_fs = new FileStream(stdout_read, FileAccess.Read, 4096);
StreamReader stdout = new StreamReader(stdout_fs, utf8_encoding, true, 4096);
- FileStream stderr_fs = new FileStream(stderr_read, FileAccess.Read, true, 4096);
+ stdout_write.Close();
+ FileStream stderr_fs = new FileStream(stderr_read, FileAccess.Read, 4096);
StreamReader stderr = new StreamReader(stderr_fs, utf8_encoding, true, 4096);
- CloseHandle(stdout_write);
- CloseHandle(stderr_write);
+ stderr_write.Close();
stdin.WriteLine(stdinInput);
stdin.Close();
@@ -384,7 +335,7 @@ Function Load-CommandUtils {
# [Ansible.CommandUtil]::RunCommand(string lpApplicationName, string lpCommandLine, string lpCurrentDirectory, string stdinInput, string environmentBlock)
#
# there are also numerous P/Invoke methods that can be called if you are feeling adventurous
- Add-Type -TypeDefinition $process_util -IgnoreWarnings -Debug:$false
+ Add-Type -TypeDefinition $process_util
}
Function Get-ExecutablePath($executable, $directory) {