…lines 1–9 unchanged (9 lines)
10using System.Management.Automation.Runspaces;
11using System.Reflection;
12using System.Runtime.InteropServices;
13using System.Security.AccessControl;
14using System.Security.Principal;
15#if CORECLR
16using System.Text.Json;
17#else
18using System.Web.Script.Serialization;
19#endif
20
21// System.Diagnostics.EventLog.dll reference different versioned dlls that are
22// loaded in PSCore, ignore CS1702 so the code will ignore this warning
23//NoWarn -Name CS1702 -CLR Core
24
25//AssemblyReference -Type System.Diagnostics.EventLog -CLR Core
26//AssemblyReference -Type System.Security.AccessControl.NativeObjectSecurity -CLR Core
27//AssemblyReference -Type System.Security.AccessControl.DirectorySecurity -CLR Core
28//AssemblyReference -Type System.Security.Principal.IdentityReference -CLR Core
29
30//AssemblyReference -Name System.Web.Extensions.dll -CLR Framework
…lines 31–154 unchanged (124 lines)
155 if (!Directory.Exists(baseDir))
156 {
157 string failedMsg = null;
158 try
159 {
160#if CORECLR
161 FileSystemAclExtensions.CreateDirectory(dirSecurity, baseDir);
162#else
163 Directory.CreateDirectory(baseDir, dirSecurity);
164#endif
165 }
166 catch (Exception e)
167 {
…lines 168–184 unchanged (17 lines)
185
186 string dateTime = DateTime.Now.ToFileTime().ToString();
187 string dirName = String.Format("ansible-moduletmp-{0}-{1}-{2}", dateTime, System.Diagnostics.Process.GetCurrentProcess().Id,
188 new Random().Next(0, int.MaxValue));
189 string newTmpdir = Path.Combine(baseDir, dirName);
190#if CORECLR
191 FileSystemAclExtensions.CreateDirectory(dirSecurity, newTmpdir);
192#else
193 Directory.CreateDirectory(newTmpdir, dirSecurity);
194#endif
195 tmpdir = newTmpdir;
196
197 if (!KeepRemoteFiles)
…lines 198–419 unchanged (222 lines)
420 }
421
422 public static object FromJson(string json) { return FromJson<object>(json); }
423 public static T FromJson<T>(string json)
424 {
425#if CORECLR
426 try
427 {
428 if (typeof(T) == typeof(object) || typeof(T) == typeof(Dictionary<string, object>))
429 {
430 using (JsonDocument doc = JsonDocument.Parse(json))
431 {
432 return (T)(object)ConvertJsonElement(doc.RootElement);
433 }
434 }
435 return JsonSerializer.Deserialize<T>(json);
436 }
437 catch (JsonException e)
438 {
439 // For backwards compatibility with JavaScriptSerializer, we
440 // use ArgumentException instead.
441 throw new ArgumentException(String.Format("Failed to parse JSON: {0}", e.Message), e);
442 }
443#else
444 JavaScriptSerializer jss = new JavaScriptSerializer();
445 jss.MaxJsonLength = int.MaxValue;
446 jss.RecursionLimit = int.MaxValue;
447 return jss.Deserialize<T>(json);
448#endif
449 }
450
451#if CORECLR
452 private static object ConvertJsonElement(JsonElement element)
453 {
454 switch (element.ValueKind)
455 {
456 case JsonValueKind.Object:
457 var dict = new Dictionary<string, object>();
458 foreach (JsonProperty prop in element.EnumerateObject())
459 {
460 dict[prop.Name] = ConvertJsonElement(prop.Value);
461 }
462 return dict;
463 case JsonValueKind.Array:
464 // We use ArrayList to copy JavaScriptSerializer behavior
465 var list = new ArrayList();
466 foreach (JsonElement item in element.EnumerateArray())
467 {
468 list.Add(ConvertJsonElement(item));
469 }
470 return list;
471 case JsonValueKind.String:
472 return element.GetString();
473 case JsonValueKind.Number:
474 if (element.TryGetInt32(out int i))
475 return i;
476 else if (element.TryGetInt64(out long l))
477 return l;
478 return element.GetDecimal();
479 case JsonValueKind.True:
480 return true;
481 case JsonValueKind.False:
482 return false;
483 case JsonValueKind.Null:
484 return null;
485 default:
486 throw new ArgumentException($"Unsupported JsonElement type: {element.ValueKind}");
487 }
488 }
489#endif
490
491 public static string ToJson(object obj)
492 {
493 // Using PowerShell to serialize the JSON is preferable over the native .NET libraries as it handles
494 // PS Objects a lot better than the alternatives. In case we are debugging in Visual Studio we have a
495 // fallback to the other libraries as we won't be dealing with PowerShell objects there.
496 if (Runspace.DefaultRunspace != null)
497 {
498 PSObject rawOut = ScriptBlock.Create("ConvertTo-Json -InputObject $args[0] -Depth 99 -Compress").Invoke(obj)[0];
499 return rawOut.BaseObject as string;
500 }
501 else
502 {
503#if CORECLR
504 return JsonSerializer.Serialize(obj);
505#else
506 JavaScriptSerializer jss = new JavaScriptSerializer();
507 jss.MaxJsonLength = int.MaxValue;
508 jss.RecursionLimit = int.MaxValue;
509 return jss.Serialize(obj);
510#endif
…lines 511–647 unchanged (137 lines)
648 else if (valueType == typeof(ArrayList))
649 return ((ArrayList)value).Cast<object>().ToList();
650 else if (valueType.IsArray)
651 return ((object[])value).ToList();
652 else if (valueType == typeof(string))
653 return ((string)value).Split(',').Select(s => s.Trim()).ToList<object>();
654 else if (valueType == typeof(int) || valueType == typeof(long))
655 return new List<object>() { value };
656 else
657 throw new ArgumentException(String.Format("{0} cannot be converted to a list", valueType.FullName));
658 }
659
660 public static string ParsePath(object value)
…lines 661–1119 unchanged (459 lines)
1120 foreach (string parameter in removedParameters)
1121 param.Remove(parameter);
1122
1123 if (unsupportedParameters.Count > 0 && !ignoreUnknownOpts)
1124 {
1125 legalInputs.RemoveAll(x => passVars.Keys.Contains(x.Replace("_ansible_", "")));
1126 IEnumerable<string> unsupportedSorted = unsupportedParameters.OrderBy(s => s, StringComparer.Ordinal);
1127 IEnumerable<string> legalInputsSorted = legalInputs.OrderBy(s => s, StringComparer.Ordinal);
1128 string msg = String.Format("Unsupported parameters for ({0}) module: {1}", ModuleName, String.Join(", ", unsupportedSorted));
1129 msg = String.Format("{0}. Supported parameters include: {1}", FormatOptionsContext(msg), String.Join(", ", legalInputsSorted));
1130 FailJson(msg);
1131 }
1132
1133 /*
1134 // Uncomment when we want to start warning users around options that are not a case sensitive match to the spec
1135 if (caseUnsupportedParameters.Count > 0)
…lines 1136–1600 unchanged (465 lines)
1601
1602 private const int ERROR_INVALID_PARAMETER = 0x00000057;
1603 private const int ERROR_DIR_NOT_EMPTY = 0x00000091;
1604
1605 private static bool? _supportsPosixDelete = null;
1606
1607 [StructLayout(LayoutKind.Sequential)]
1608 public struct IO_STATUS_BLOCK
1609 {
1610 public int Status;
1611 public IntPtr Information;
1612 }
1613
1614 [Flags()]
1615 public enum DispositionFlags : uint
1616 {
1617 FILE_DISPOSITION_DO_NOT_DELETE = 0x00000000,
1618 FILE_DISPOSITION_DELETE = 0x00000001,
…lines 1619–1664 unchanged (46 lines)
1665 return handle;
1666 }
1667
1668 [DllImport("Ntdll.dll")]
1669 private static extern int NtSetInformationFile(
1670 SafeFileHandle FileHandle,
1671 ref IO_STATUS_BLOCK IoStatusBlock,
1672 ref int FileInformation,
1673 int Length,
1674 int FileInformationClass);
1675
1676 [DllImport("Ntdll.dll")]
1677 private static extern int RtlNtStatusToDosError(
…lines 1678–1804 unchanged (127 lines)
1805 }
1806 }
1807 }
1808
1809 private static void SetInformationFile(SafeFileHandle handle, int infoClass, int value)
1810 {
1811 IO_STATUS_BLOCK ioStatusBlock = new IO_STATUS_BLOCK();
1812
1813 int ntStatus = NtSetInformationFile(handle, ref ioStatusBlock, ref value,
1814 Marshal.SizeOf(typeof(int)), infoClass);
1815
1816 if (ntStatus != 0)
1817 {
1818 int errCode = RtlNtStatusToDosError(ntStatus);
1819
…lines 1820–1842 unchanged (23 lines)