diff --git a/src/System.Management.Automation/CoreCLR/CorePsExtensions.cs b/src/System.Management.Automation/CoreCLR/CorePsExtensions.cs index 5674327cd..59a864d01 100644 --- a/src/System.Management.Automation/CoreCLR/CorePsExtensions.cs +++ b/src/System.Management.Automation/CoreCLR/CorePsExtensions.cs @@ -893,13 +893,10 @@ namespace System.Management.Automation return GetEnvironmentVariables(); } - if (!Platform.HasRegistrySupport()) - { - // Porting note: Does not throw a PlatformUnsupported because - // GetEnvironmentVariable cannot throw, and we want the same interface. - return null; - } - +#if LINUX + return null; +#else + if( target == EnvironmentVariableTarget.Machine) { using (RegistryKey environmentKey = @@ -916,6 +913,7 @@ namespace System.Management.Automation return GetRegistryKeyNameValuePairs(environmentKey); } } +#endif } /// @@ -956,13 +954,9 @@ namespace System.Management.Automation return System.Environment.GetEnvironmentVariable(variable); } - if (!Platform.HasRegistrySupport()) - { - // Porting note: This cannot throw since it would otherwise throw while - // creating a runspace. Returning null is appropriate to signal that there - // is no value for a registry key with no registry. - return null; - } +#if LINUX + return null; +#else if (target == EnvironmentVariableTarget.Machine) { @@ -985,6 +979,7 @@ namespace System.Management.Automation return value; } } +#endif } #endregion EnvironmentVariable_Extensions diff --git a/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs b/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs index eb9d3b262..e4a8701b6 100644 --- a/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs +++ b/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs @@ -143,12 +143,12 @@ namespace System.Management.Automation //the user has set XDG_DATA_HOME corresponding to module path if (String.IsNullOrEmpty(xdgdatahome)){ - // create the xdg folder if needed - if (!Directory.Exists(xdgDataHomeDefault)) - { - Directory.CreateDirectory(xdgDataHomeDefault); - } - return xdgDataHomeDefault; + // create the xdg folder if needed + if (!Directory.Exists(xdgDataHomeDefault)) + { + Directory.CreateDirectory(xdgDataHomeDefault); + } + return xdgDataHomeDefault; } else { @@ -159,12 +159,12 @@ namespace System.Management.Automation //the user has set XDG_DATA_HOME corresponding to module path if (String.IsNullOrEmpty(xdgdatahome)){ - //xdg values have not been set - if (!Directory.Exists(xdgModuleDefault)) //module folder not always guaranteed to exist - { - Directory.CreateDirectory(xdgModuleDefault); - } - return xdgModuleDefault; + //xdg values have not been set + if (!Directory.Exists(xdgModuleDefault)) //module folder not always guaranteed to exist + { + Directory.CreateDirectory(xdgModuleDefault); + } + return xdgModuleDefault; } else { @@ -175,7 +175,7 @@ namespace System.Management.Automation //the user has set XDG_CACHE_HOME if (String.IsNullOrEmpty(xdgcachehome)) { - //xdg values have not been set + //xdg values have not been set if (!Directory.Exists(xdgCacheDefault)) //module folder not always guaranteed to exist { Directory.CreateDirectory(xdgCacheDefault); @@ -217,90 +217,6 @@ namespace System.Management.Automation } - // ComObjectType is null on CoreCLR for Linux since there is - // no COM support on Linux - internal static bool HasCom() - { - // TODO: catch exception from Type.IsComObject - return IsWindows; - } - - // The Antimalware Scan Interface is not supported on Linux - internal static bool HasAmsi() - { - return IsWindows; - } - - // This is mainly with respect to the auto-mounting of - // disconnected network drives on Windows - internal static bool HasDriveAutoMounting() - { - return IsWindows; - } - - // Linux does not have a registry - internal static bool HasRegistrySupport() - { - return IsWindows; - } - - // Linux does not have PowerShell execution policies - internal static bool HasExecutionPolicy() - { - return IsWindows; - } - - // Linux has a single rooted file system - internal static bool HasSingleRootFilesystem() - { - return !IsWindows; - } - - // Linux has no notion of file shares. It has mount points - // instead, which are subdirectories of its single-root - // filesystem. - internal static bool HasFileShares() - { - return !HasSingleRootFilesystem(); - } - - // Linux has no support for UNC, just mounts in a single rooted hierarchy - // the UNC equivalent of a "network drive" aka mount would be the mount itself - internal static bool HasUNCSupport() - { - return IsWindows; - } - - // Linux uses .net to query file attributes - internal static bool UseDotNetToQueryFileAttributes() - { - return true; - } - - // Linux does not have group policy support - internal static bool HasGroupPolicySupport() - { - return IsWindows; - } - - // non-windows does not have network drive support - internal static bool HasNetworkDriveSupport() - { - return IsWindows; - } - - // non-windows does not have reparse points - internal static bool SupportsReparsePoints() - { - return IsWindows; - } - - // non-windows does not support removing drives - internal static bool SupportsRemoveDrive() - { - return IsWindows; - } - // Platform methods prefixed NonWindows are: // - non-windows by the definition of the IsWindows method above // - here, because porting to Linux and other operating systems @@ -313,27 +229,17 @@ namespace System.Management.Automation internal static bool NonWindowsIsHardLink(ref IntPtr handle) { - return LinuxPlatform.IsHardLink(ref handle); + return Unix.IsHardLink(ref handle); } internal static bool NonWindowsIsHardLink(FileSystemInfo fileInfo) { - if (!IsWindows) - { - return LinuxPlatform.IsHardLink(fileInfo); - } - - throw new PlatformNotSupportedException(); + return Unix.IsHardLink(fileInfo); } internal static bool NonWindowsIsSymLink(FileSystemInfo fileInfo) { - if (!IsWindows) - { - return LinuxPlatform.IsSymLink(fileInfo); - } - - throw new PlatformNotSupportedException(); + return Unix.NativeMethods.IsSymLink(fileInfo.FullName); } internal static string NonWindowsInternalGetTarget(SafeFileHandle handle) @@ -344,166 +250,101 @@ namespace System.Management.Automation internal static string NonWindowsInternalGetTarget(string path) { - if (!IsWindows) - { - return LinuxPlatform.FollowSymLink(path); - } - else - { - throw new PlatformNotSupportedException(); - } + return Unix.NativeMethods.FollowSymLink(path); } internal static string NonWindowsGetUserFromPid(int path) { - if (!IsWindows) - { - return LinuxPlatform.GetUserFromPid(path); - } - else - { - throw new PlatformNotSupportedException(); - } + return Unix.NativeMethods.GetUserFromPid(path); } -#if CORECLR + #if CORECLR internal static string NonWindowsGetFolderPath(SpecialFolder folder) { - if (!IsWindows) - { - return LinuxPlatform.GetFolderPath(folder); - } - else - { - throw new PlatformNotSupportedException(); - } + return Unix.GetFolderPath(folder); } -#endif + #endif internal static string NonWindowsInternalGetLinkType(FileSystemInfo fileInfo) { - if (!IsWindows) + if (NonWindowsIsSymLink(fileInfo)) { - if (NonWindowsIsSymLink(fileInfo)) - { - return "SymbolicLink"; - } - if (NonWindowsIsHardLink(fileInfo)) - { - return "HardLink"; - } - return null; - } - else - { - throw new PlatformNotSupportedException(); + return "SymbolicLink"; } + if (NonWindowsIsHardLink(fileInfo)) + { + return "HardLink"; + } + + return null; } - internal static bool NonWindowsCreateSymbolicLink(string path, string strTargetPath, bool isDirectory) + internal static bool NonWindowsCreateSymbolicLink(string path, string target) { - if (!IsWindows) - { - // Linux doesn't care if target is a directory or not - return LinuxPlatform.CreateSymbolicLink(path, strTargetPath); - } - else - { - throw new PlatformNotSupportedException(); - } + // Linux doesn't care if target is a directory or not + return Unix.NativeMethods.CreateSymLink(path, target); } internal static bool NonWindowsCreateHardLink(string path, string strTargetPath) { - if (!IsWindows) - { - return LinuxPlatform.CreateHardLink(path, strTargetPath); - } - else - { - throw new PlatformNotSupportedException(); - } + return Unix.CreateHardLink(path, strTargetPath); } internal static void NonWindowsSetDate(DateTime dateToUse) { - if (!IsWindows) - { - LinuxPlatform.SetDateInfoInternal date = new LinuxPlatform.SetDateInfoInternal(dateToUse); - LinuxPlatform.SetDate(date); - } - else - { - throw new PlatformNotSupportedException(); - } + Unix.SetDateInfoInternal date = new Unix.SetDateInfoInternal(dateToUse); + Unix.SetDate(date); } internal static string NonWindowsGetDomainName() { - if (!IsWindows) + string fullyQualifiedName = Unix.NativeMethods.GetFullyQualifiedName(); + if (string.IsNullOrEmpty(fullyQualifiedName)) { - string fullyQualifiedName = LinuxPlatform.Native.GetFullyQualifiedName(); - if (string.IsNullOrEmpty(fullyQualifiedName)) - { - int lastError = Marshal.GetLastWin32Error(); - throw new InvalidOperationException("LinuxPlatform.NonWindowsGetDomainName error: " + lastError); - } - - int index = fullyQualifiedName.IndexOf('.'); - if (index >= 0) - { - return fullyQualifiedName.Substring(index + 1); - } - - return ""; + int lastError = Marshal.GetLastWin32Error(); + throw new InvalidOperationException("Unix.NonWindowsGetDomainName error: " + lastError); } - else + + int index = fullyQualifiedName.IndexOf('.'); + if (index >= 0) { - throw new PlatformNotSupportedException(); + return fullyQualifiedName.Substring(index + 1); } + + return ""; } internal static string NonWindowsGetUserName() { - if (!IsWindows) - { - return LinuxPlatform.UserName; - } - else - { - throw new PlatformNotSupportedException(); - } + return Unix.UserName; } // Hostname in this context seems to be the FQDN internal static string NonWindowsGetHostName() { - if (!IsWindows) + string hostName = Unix.NativeMethods.GetFullyQualifiedName(); + if (string.IsNullOrEmpty(hostName)) { - string hostName = LinuxPlatform.Native.GetFullyQualifiedName(); - if (string.IsNullOrEmpty(hostName)) - { - int lastError = Marshal.GetLastWin32Error(); - throw new InvalidOperationException("LinuxPlatform.NonWindowsHostName error: " + lastError); - } - return hostName; + int lastError = Marshal.GetLastWin32Error(); + throw new InvalidOperationException("Unix.NonWindowsHostName error: " + lastError); + } + return hostName; + } - } - else - { - throw new PlatformNotSupportedException(); - } + internal static bool NonWindowsIsFile(string path) + { + return Unix.NativeMethods.IsFile(path); + } + + internal static bool NonWindowsIsDirectory(string path) + { + return Unix.NativeMethods.IsDirectory(path); } internal static bool NonWindowsIsExecutable(string path) { - if (!IsWindows) - { - return LinuxPlatform.IsExecutable(path); - } - - throw new PlatformNotSupportedException(); + return Unix.NativeMethods.IsExecutable(path); } internal static uint NonWindowsGetThreadId() @@ -512,15 +353,6 @@ namespace System.Management.Automation return 0; } - /// - /// This exception is meant to be thrown if a code path is not supported due - /// to platform restrictions - /// - internal class PlatformNotSupportedException : System.Exception - { - public PlatformNotSupportedException() : base() {} - } - /// /// This models the native call CommandLineToArgvW in managed code. /// @@ -581,7 +413,7 @@ namespace System.Management.Automation } } - internal static class LinuxPlatform + internal static class Unix { private static string _userName; public static string UserName @@ -590,11 +422,11 @@ namespace System.Management.Automation { if (string.IsNullOrEmpty(_userName)) { - _userName = Native.GetUserName(); + _userName = NativeMethods.GetUserName(); if (string.IsNullOrEmpty(_userName)) { int lastError = Marshal.GetLastWin32Error(); - throw new InvalidOperationException("LinuxPlatform.UserName error: " + lastError); + throw new InvalidOperationException("Unix.UserName error: " + lastError); } } return _userName; @@ -620,40 +452,40 @@ namespace System.Management.Automation } } -#if CORECLR + #if CORECLR public static string GetFolderPath(SpecialFolder folder) { string s = null; switch (folder) { - case SpecialFolder.ProgramFiles: - s = "/bin"; - break; - case SpecialFolder.ProgramFilesX86: - s = "/usr/bin"; - break; - case SpecialFolder.System: - s = "/sbin"; - break; - case SpecialFolder.SystemX86: - s = "/sbin"; - break; - case SpecialFolder.Personal: - s = System.Environment.GetEnvironmentVariable("HOME"); - break; - case SpecialFolder.LocalApplicationData: - s = System.IO.Path.Combine(System.Environment.GetEnvironmentVariable("HOME"), ".config"); - if (!System.IO.Directory.Exists(s)) - { - System.IO.Directory.CreateDirectory(s); - } - break; - default: - throw new NotSupportedException(); + case SpecialFolder.ProgramFiles: + s = "/bin"; + break; + case SpecialFolder.ProgramFilesX86: + s = "/usr/bin"; + break; + case SpecialFolder.System: + s = "/sbin"; + break; + case SpecialFolder.SystemX86: + s = "/sbin"; + break; + case SpecialFolder.Personal: + s = System.Environment.GetEnvironmentVariable("HOME"); + break; + case SpecialFolder.LocalApplicationData: + s = System.IO.Path.Combine(System.Environment.GetEnvironmentVariable("HOME"), ".config"); + if (!System.IO.Directory.Exists(s)) + { + System.IO.Directory.CreateDirectory(s); + } + break; + default: + throw new NotSupportedException(); } return s; } -#endif + #endif public static bool IsHardLink(ref IntPtr handle) { @@ -671,7 +503,7 @@ namespace System.Management.Automation int count; string filePath = fs.FullName; - int ret = Native.GetLinkCount(filePath, out count); + int ret = NativeMethods.GetLinkCount(filePath, out count); if (ret == 1) { return count > 1; @@ -679,84 +511,27 @@ namespace System.Management.Automation else { int lastError = Marshal.GetLastWin32Error(); - throw new InvalidOperationException("LinuxPlatform.IsHardLink error: " + lastError); + throw new InvalidOperationException("Unix.IsHardLink error: " + lastError); } } - public static bool IsSymLink(FileSystemInfo fs) - { - if (!fs.Exists) - { - return false; - } - - string filePath = fs.FullName; - int ret = Native.IsSymLink(filePath); - switch(ret) - { - case 1: - return true; - case 0: - return false; - default: - int lastError = Marshal.GetLastWin32Error(); - throw new InvalidOperationException("LinuxPlatform.IsSymLink error: " + lastError); - } - } - - public static bool IsExecutable(string filePath) - { - if (!File.Exists(filePath)) - { - return false; - } - - int ret = Native.IsExecutable(filePath); - switch(ret) - { - case 1: - return true; - case 0: - return false; - default: - int lastError = Marshal.GetLastWin32Error(); - throw new InvalidOperationException("LinuxPlatform.IsExecutable error: " + lastError); - } - } - public static void SetDate(SetDateInfoInternal info) { - int ret = Native.SetDate(info); + int ret = NativeMethods.SetDate(info); if (ret == -1) { int lastError = Marshal.GetLastWin32Error(); - throw new InvalidOperationException("LinuxPlatform.NonWindowsSetDate error: " + lastError); + throw new InvalidOperationException("Unix.NonWindowsSetDate error: " + lastError); } } - public static bool CreateSymbolicLink(string path, string strTargetPath) - { - int ret = Native.CreateSymLink(path, strTargetPath); - return ret == 1 ? true : false; - } - public static bool CreateHardLink(string path, string strTargetPath) { - int ret = Native.CreateHardLink(path, strTargetPath); + int ret = NativeMethods.CreateHardLink(path, strTargetPath); return ret == 1 ? true : false; } - public static string FollowSymLink(string path) - { - return Native.FollowSymLink(path); - } - - public static string GetUserFromPid(int pid) - { - return Native.GetUserFromPid(pid); - } - [StructLayout(LayoutKind.Sequential)] internal class SetDateInfoInternal { @@ -788,12 +563,14 @@ namespace System.Management.Automation } } - internal static class Native + internal static class NativeMethods { const string psLib = "libpsl-native"; // Ansi is a misnomer, it is hardcoded to UTF-8 on Linux and OS X + // C bools are 1 byte and so must be marshaled as I1 + [DllImport(psLib, CharSet = CharSet.Ansi, SetLastError = true)] [return: MarshalAs(UnmanagedType.LPStr)] internal static extern string GetUserName(); @@ -802,10 +579,12 @@ namespace System.Management.Automation internal static extern int GetLinkCount([MarshalAs(UnmanagedType.LPStr)]string filePath, out int linkCount); [DllImport(psLib, CharSet = CharSet.Ansi, SetLastError = true)] - internal static extern int IsSymLink([MarshalAs(UnmanagedType.LPStr)]string filePath); + [return: MarshalAs(UnmanagedType.I1)] + internal static extern bool IsSymLink([MarshalAs(UnmanagedType.LPStr)]string filePath); [DllImport(psLib, CharSet = CharSet.Ansi, SetLastError = true)] - internal static extern int IsExecutable([MarshalAs(UnmanagedType.LPStr)]string filePath); + [return: MarshalAs(UnmanagedType.I1)] + internal static extern bool IsExecutable([MarshalAs(UnmanagedType.LPStr)]string filePath); [DllImport(psLib, CharSet = CharSet.Ansi, SetLastError = true)] [return: MarshalAs(UnmanagedType.LPStr)] @@ -815,7 +594,8 @@ namespace System.Management.Automation internal static extern int SetDate(SetDateInfoInternal info); [DllImport(psLib, CharSet = CharSet.Ansi, SetLastError = true)] - internal static extern int CreateSymLink([MarshalAs(UnmanagedType.LPStr)]string filePath, + [return: MarshalAs(UnmanagedType.I1)] + internal static extern bool CreateSymLink([MarshalAs(UnmanagedType.LPStr)]string filePath, [MarshalAs(UnmanagedType.LPStr)]string target); [DllImport(psLib, CharSet = CharSet.Ansi, SetLastError = true)] @@ -829,6 +609,15 @@ namespace System.Management.Automation [DllImport(psLib, CharSet = CharSet.Ansi, SetLastError = true)] [return: MarshalAs(UnmanagedType.LPStr)] internal static extern string GetUserFromPid(int pid); + + [DllImport(psLib, CharSet = CharSet.Ansi, SetLastError = true)] + [return: MarshalAs(UnmanagedType.I1)] + internal static extern bool IsFile([MarshalAs(UnmanagedType.LPStr)]string filePath); + + [DllImport(psLib, CharSet = CharSet.Ansi, SetLastError = true)] + [return: MarshalAs(UnmanagedType.I1)] + internal static extern bool IsDirectory([MarshalAs(UnmanagedType.LPStr)]string filePath); + } } diff --git a/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs b/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs index 8c3eb882b..d3fba6c14 100644 --- a/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs +++ b/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs @@ -4464,12 +4464,9 @@ namespace System.Management.Automation internal static List GetFileShares(string machine, bool ignoreHidden) { - // Platform notes: don't throw an exception since this is being used in auto-completion - if (!Platform.HasFileShares()) - { - return new List(); - } - +#if LINUX + return new List(); +#else IntPtr shBuf; uint numEntries; uint totalEntries; @@ -4495,6 +4492,7 @@ namespace System.Management.Automation } } return shares; +#endif } private static bool CheckFileExtension(string path, HashSet extension) diff --git a/src/System.Management.Automation/engine/CommandDiscovery.cs b/src/System.Management.Automation/engine/CommandDiscovery.cs index 2d0e2e917..23c95b432 100644 --- a/src/System.Management.Automation/engine/CommandDiscovery.cs +++ b/src/System.Management.Automation/engine/CommandDiscovery.cs @@ -1903,13 +1903,9 @@ namespace System.Management.Automation /// internal static string GetShellPathFromRegistry(string shellID) { - if (!Platform.HasRegistrySupport()) - { - return null; - } - string result = null; +#if !LINUX try { RegistryKey shellKey = Registry.LocalMachine.OpenSubKey(Utils.GetRegistryConfigurationPath(shellID)); @@ -1935,6 +1931,7 @@ namespace System.Management.Automation catch (ArgumentException) { } +#endif return result; } diff --git a/src/System.Management.Automation/engine/PSVersionInfo.cs b/src/System.Management.Automation/engine/PSVersionInfo.cs index d500e7e85..92aaee14e 100644 --- a/src/System.Management.Automation/engine/PSVersionInfo.cs +++ b/src/System.Management.Automation/engine/PSVersionInfo.cs @@ -103,13 +103,9 @@ namespace System.Management.Automation // Gets the current WSMan stack version from the registry. private static Version GetWSManStackVersion() { - if (!Platform.HasRegistrySupport()) - { - return new Version(1, 0); - } - Version version = null; +#if !LINUX try { using (RegistryKey wsManStackVersionKey = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\WSMAN")) @@ -133,6 +129,7 @@ namespace System.Management.Automation catch (FormatException) { } catch (OverflowException) { } catch (InvalidCastException) { } +#endif return version ?? System.Management.Automation.Remoting.Client.WSManNativeApi.WSMAN_STACK_VERSION; } diff --git a/src/System.Management.Automation/engine/SessionStateDriveAPIs.cs b/src/System.Management.Automation/engine/SessionStateDriveAPIs.cs index d7e0f8e38..6de20eee2 100644 --- a/src/System.Management.Automation/engine/SessionStateDriveAPIs.cs +++ b/src/System.Management.Automation/engine/SessionStateDriveAPIs.cs @@ -1469,11 +1469,12 @@ namespace System.Management.Automation bool driveIsValid = true; // If the drive is auto-mounted, ensure that it still exists, or remove the drive. - // note: not all platforms support drive auto-mounting - if (Platform.HasDriveAutoMounting() && (drive.IsAutoMounted || IsAStaleVhdMountedDrive(drive))) +#if !LINUX + if (drive.IsAutoMounted || IsAStaleVhdMountedDrive(drive)) { driveIsValid = ValidateOrRemoveAutoMountedDrive(drive, lookupScope); } +#endif if(drive.Name.Length == 1) { if(!(driveNames.Contains(drive.Name))) diff --git a/src/System.Management.Automation/engine/Utils.cs b/src/System.Management.Automation/engine/Utils.cs index 8dd8f96be..d5b29ad01 100644 --- a/src/System.Management.Automation/engine/Utils.cs +++ b/src/System.Management.Automation/engine/Utils.cs @@ -62,15 +62,6 @@ namespace System.Management.Automation return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6, h7, h8)); } - /// - /// IsWinPEHost indicates if the machine on which PowerShell is hosted is WinPE or not. - /// This is a helper variable used to kep track if the IsWinPE() helper method has - /// already checked for the WinPE specific registry key or not. - /// If the WinPE specific registry key has not yet been checked even - /// once then this variable will point to null. - /// - internal static bool? isWinPEHost = null; - /// /// The existence of the following registry confirms that the host machine is a WinPE /// HKLM\System\CurrentControlSet\Control\MiniNT @@ -368,58 +359,31 @@ namespace System.Management.Automation /// internal static bool IsWinPEHost() { - if (Platform.HasRegistrySupport()) - { - return WinIsWinPEHost(); - } - else - { - return false; - } - } - - internal static bool WinIsWinPEHost() - { +#if !LINUX RegistryKey winPEKey = null; - if (!isWinPEHost.HasValue) + try { - try - { - // The existence of the following registry confirms that the host machine is a WinPE - // HKLM\System\CurrentControlSet\Control\MiniNT - winPEKey = Registry.LocalMachine.OpenSubKey(WinPEIdentificationRegKey); + // The existence of the following registry confirms that the host machine is a WinPE + // HKLM\System\CurrentControlSet\Control\MiniNT + winPEKey = Registry.LocalMachine.OpenSubKey(WinPEIdentificationRegKey); - if (null != winPEKey) - { - isWinPEHost = true; - } - else - { - isWinPEHost = false; - } - } - catch (ArgumentException) { } - catch (SecurityException) { } - catch (ObjectDisposedException) { } - finally + return winPEKey != null; + } + catch (ArgumentException) { } + catch (SecurityException) { } + catch (ObjectDisposedException) { } + finally + { + if (winPEKey != null) { - if (winPEKey != null) - { - winPEKey.Dispose(); - } + winPEKey.Dispose(); } } +#endif + return false; + } - if (isWinPEHost.HasValue) - { - return (bool)isWinPEHost; - } - else - { - return false; - } - } #region Versioning related methods @@ -652,13 +616,9 @@ namespace System.Management.Automation internal static Dictionary GetGroupPolicySetting(string groupPolicyBase, string settingName, RegistryKey[] preferenceOrder) { - if (!Platform.HasGroupPolicySupport()) - { - // Porting note: No group policy support means we have an empty set of - // policies. - return _emptyDictionary; - } - +#if LINUX + return _emptyDictionary; +#else lock (cachedGroupPolicySettings) { // Return cached information, if we have it @@ -733,6 +693,7 @@ namespace System.Management.Automation return settings; } +#endif } static ConcurrentDictionary> cachedGroupPolicySettings = new ConcurrentDictionary>(); @@ -984,38 +945,9 @@ namespace System.Management.Automation return NativeItemExists(path, out unusedIsDirectory, out unusedException); } + // This is done through P/Invoke since File.Exists and Directory.Exists pay 13% performance degradation + // through the CAS checks, and are terribly slow for network paths. internal static bool NativeItemExists(string path, out bool isDirectory, out Exception exception) - { - if (Platform.UseDotNetToQueryFileAttributes()) - { - // TODO:PSL replace by System.IO.File.GetAttributes - exception = null; - if (NativeDirectoryExists(path)) - { - isDirectory = true; - return true; - } - else if (NativeFileExists(path)) - { - isDirectory = false; - return true; - } - else - { - isDirectory = false; - return false; - } - } - else - { - // This is done through P/Invoke since File.Exists and Directory.Exists - // pay 13% performance degradation through the CAS checks, and are - // terribly slow for network paths. - return WinNativeItemExists(path,out isDirectory,out exception); - } - } - - internal static bool WinNativeItemExists(string path, out bool isDirectory, out Exception exception) { exception = null; @@ -1024,6 +956,10 @@ namespace System.Management.Automation isDirectory = false; return false; } +#if LINUX + isDirectory = Platform.NonWindowsIsDirectory(path); + return Platform.NonWindowsIsFile(path); +#else if (IsReservedDeviceName(path)) { @@ -1057,23 +993,12 @@ namespace System.Management.Automation ((int)NativeMethods.FileAttributes.Directory); return true; +#endif } + // This is done through P/Invoke since we pay 13% performance degradation + // through the CAS checks required by File.Exists and Directory.Exists internal static bool NativeFileExists(string path) - { - if (Platform.UseDotNetToQueryFileAttributes()) - { - return System.IO.File.Exists(path); - } - else - { - // This is done through P/Invoke since we pay 13% performance degradation - // through the CAS checks required by File.Exists and Directory.Exists - return WinNativeFileExists(path); - } - } - - internal static bool WinNativeFileExists(string path) { bool isDirectory; Exception ioException; @@ -1090,18 +1015,6 @@ namespace System.Management.Automation // This is done through P/Invoke since we pay 13% performance degradation // through the CAS checks required by File.Exists and Directory.Exists internal static bool NativeDirectoryExists(string path) - { - if (Platform.UseDotNetToQueryFileAttributes()) - { - return System.IO.Directory.Exists(path); - } - else - { - return WinNativeDirectoryExists(path); - } - } - - internal static bool WinNativeDirectoryExists(string path) { bool isDirectory; Exception ioException; @@ -1116,31 +1029,6 @@ namespace System.Management.Automation } internal static void NativeEnumerateDirectory(string directory, out List directories, out List files) - { - if (Platform.UseDotNetToQueryFileAttributes()) - { - IEnumerable fileEnum = System.IO.Directory.EnumerateFiles(directory); - IEnumerable dirEnum = System.IO.Directory.EnumerateDirectories(directory); - - files = new List(); - directories = new List(); - - foreach (string entry in fileEnum) - { - files.Add(directory + "/" + entry); - } - foreach (string entry in dirEnum) - { - directories.Add(directory + "/" + entry); - } - } - else - { - WinNativeEnumerateDirectory(directory, out directories, out files); - } - } - - internal static void WinNativeEnumerateDirectory(string directory, out List directories, out List files) { IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1); NativeMethods.WIN32_FIND_DATA findData; @@ -1205,12 +1093,12 @@ namespace System.Management.Automation internal static bool PathIsUnc(string path) { - if (!Platform.HasUNCSupport()) - { - return false; - } +#if LINUX + return false; +#else Uri uri; return !string.IsNullOrEmpty(path) && Uri.TryCreate(path, UriKind.Absolute, out uri) && uri.IsUnc; +#endif } internal class NativeMethods diff --git a/src/System.Management.Automation/engine/remoting/commands/remotingcommandutil.cs b/src/System.Management.Automation/engine/remoting/commands/remotingcommandutil.cs index 2f0fa35d5..c3e9cc006 100644 --- a/src/System.Management.Automation/engine/remoting/commands/remotingcommandutil.cs +++ b/src/System.Management.Automation/engine/remoting/commands/remotingcommandutil.cs @@ -96,12 +96,10 @@ namespace Microsoft.PowerShell.Commands /// internal static void CheckRemotingCmdletPrerequisites() { - //If the operating system (ie Linux) does not support the registry, simply return to avoid calls to the Windows registry. - if (!Platform.HasRegistrySupport()) - { - return; - } - +#if LINUX + // TODO: check that PSRP requirements are installed + return; +#else bool notSupported = true; String WSManKeyPath = "Software\\Microsoft\\Windows\\CurrentVersion\\WSMAN\\"; @@ -155,6 +153,7 @@ namespace Microsoft.PowerShell.Commands throw new InvalidOperationException( "Windows PowerShell remoting features are not enabled or not supported on this machine.\nThis may be because you do not have the correct version of WS-Management installed or this version of Windows does not support remoting currently.\n For more information, type 'get-help about_remote_requirements'."); } +#endif } /// diff --git a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs index 50592a4e4..8d598b13b 100644 --- a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs +++ b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs @@ -677,14 +677,11 @@ namespace System.Management.Automation.Language private static TypeInfo GetComObjectType() { - if (Platform.HasCom()) - { - return typeof(object).GetTypeInfo().Assembly.GetType("System.__ComObject").GetTypeInfo(); - } - else - { - return null; - } +#if LINUX + return null; +#else + return typeof(object).GetTypeInfo().Assembly.GetType("System.__ComObject").GetTypeInfo(); +#endif } internal static bool IsComObject(object obj) diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index 39c60e005..225caeffc 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -496,7 +496,7 @@ namespace Microsoft.PowerShell.Commands } else { - throw new Platform.PlatformNotSupportedException(); + throw new PlatformNotSupportedException(); } } @@ -607,15 +607,11 @@ namespace Microsoft.PowerShell.Commands /// protected override PSDriveInfo RemoveDrive(PSDriveInfo drive) { - // if removing the drive is not supported, just return the drive - if (Platform.SupportsRemoveDrive()) - { - return WinRemoveDrive(drive); - } - else - { - return drive; - } +#if LINUX + return drive; +#else + return WinRemoveDrive(drive); +#endif } private PSDriveInfo WinRemoveDrive(PSDriveInfo drive) @@ -685,15 +681,11 @@ namespace Microsoft.PowerShell.Commands /// internal static string GetUNCForNetworkDrive(string driveName) { - // Porting note: on systems that do not support UNC paths, the UNC equivalent is the path itself - if (Platform.HasUNCSupport()) - { - return WinGetUNCForNetworkDrive(driveName); - } - else - { - return driveName; - } +#if LINUX + return driveName; +#else + return WinGetUNCForNetworkDrive(driveName); +#endif } private static string WinGetUNCForNetworkDrive(string driveName) @@ -747,14 +739,11 @@ namespace Microsoft.PowerShell.Commands /// internal static string GetSubstitutedPathForNetworkDosDevice(string driveName) { - if (Platform.HasNetworkDriveSupport()) - { - return WinGetSubstitutedPathForNetworkDosDevice(driveName); - } - else - { - throw new Platform.PlatformNotSupportedException(); - } +#if LINUX + throw new PlatformNotSupportedException(); +#else + return WinGetSubstitutedPathForNetworkDosDevice(driveName); +#endif } private static string WinGetSubstitutedPathForNetworkDosDevice(string driveName) @@ -926,15 +915,15 @@ namespace Microsoft.PowerShell.Commands if (newDrive.DriveType == DriveType.Network) { // Platform notes: This is important because certain mount - // points on non-Windows are enumerated as drives by .net, but + // points on non-Windows are enumerated as drives by .NET, but // the platform itself then has no real network drive support // as required by this context. Solution: check for network // drive support before using it. - if (!Platform.HasNetworkDriveSupport()) - { - continue; - } +#if LINUX + continue; +#else displayRoot = GetRootPathForNetworkDriveOrDosDevice(newDrive); +#endif } if (newDrive.DriveType == DriveType.Fixed) @@ -947,12 +936,14 @@ namespace Microsoft.PowerShell.Commands root = newDrive.RootDirectory.FullName; } +#if LINUX // Porting notes: On platforms with single root filesystems, only // add the filesystem with the root "/" to the initial drive list, // otherwise path handling will not work correctly because there // is no : available to separate the filesystems from each other - if (Platform.HasSingleRootFilesystem() && root != StringLiterals.DefaultPathSeparatorString) + if (root != StringLiterals.DefaultPathSeparatorString) continue; +#endif // Porting notes: On non-windows platforms .net can report two // drives with the same root, make sure to only add one of those @@ -2229,7 +2220,7 @@ namespace Microsoft.PowerShell.Commands } else { - success = Platform.NonWindowsCreateSymbolicLink(path,strTargetPath,isDirectory); + success = Platform.NonWindowsCreateSymbolicLink(path,strTargetPath); } } else if(itemType == ItemType.HardLink) @@ -6971,48 +6962,47 @@ namespace Microsoft.PowerShell.Commands internal static int SafeGetFileAttributes(string path) { - if (Platform.UseDotNetToQueryFileAttributes()) - { - System.IO.FileAttributes attr = System.IO.File.GetAttributes(path); +#if LINUX + System.IO.FileAttributes attr = System.IO.File.GetAttributes(path); - int result = 0; - if ((attr & FileAttributes.Archive) == FileAttributes.Archive) - result |= 0x20; - if ((attr & FileAttributes.Compressed) == FileAttributes.Compressed) - result |= 0x800; - if ((attr & FileAttributes.Device) == FileAttributes.Device) - result |= 0x40; - if ((attr & FileAttributes.Directory) == FileAttributes.Directory) - result |= 0x10; - if ((attr & FileAttributes.Encrypted) == FileAttributes.Encrypted) - result |= 0x4000; - if ((attr & FileAttributes.Hidden) == FileAttributes.Hidden) - result |= 0x2; - if ((attr & FileAttributes.IntegrityStream) == FileAttributes.IntegrityStream) - result |= 0x8000; - if ((attr & FileAttributes.Normal) == FileAttributes.Normal) - result |= 0x80; - if ((attr & FileAttributes.NoScrubData) == FileAttributes.NoScrubData) - result |= 0x20000; - if ((attr & FileAttributes.NotContentIndexed) == FileAttributes.NotContentIndexed) - result |= 0x2000; - if ((attr & FileAttributes.Offline) == FileAttributes.Offline) - result |= 0x1000; - if ((attr & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) - result |= 0x1; - if ((attr & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint) - result |= 0x400; - if ((attr & FileAttributes.SparseFile) == FileAttributes.SparseFile) - result |= 0x200; - if ((attr & FileAttributes.System) == FileAttributes.System) - result |= 0x4; - if ((attr & FileAttributes.Temporary) == FileAttributes.Temporary) - result |= 0x100; + int result = 0; + if ((attr & FileAttributes.Archive) == FileAttributes.Archive) + result |= 0x20; + if ((attr & FileAttributes.Compressed) == FileAttributes.Compressed) + result |= 0x800; + if ((attr & FileAttributes.Device) == FileAttributes.Device) + result |= 0x40; + if ((attr & FileAttributes.Directory) == FileAttributes.Directory) + result |= 0x10; + if ((attr & FileAttributes.Encrypted) == FileAttributes.Encrypted) + result |= 0x4000; + if ((attr & FileAttributes.Hidden) == FileAttributes.Hidden) + result |= 0x2; + if ((attr & FileAttributes.IntegrityStream) == FileAttributes.IntegrityStream) + result |= 0x8000; + if ((attr & FileAttributes.Normal) == FileAttributes.Normal) + result |= 0x80; + if ((attr & FileAttributes.NoScrubData) == FileAttributes.NoScrubData) + result |= 0x20000; + if ((attr & FileAttributes.NotContentIndexed) == FileAttributes.NotContentIndexed) + result |= 0x2000; + if ((attr & FileAttributes.Offline) == FileAttributes.Offline) + result |= 0x1000; + if ((attr & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) + result |= 0x1; + if ((attr & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint) + result |= 0x400; + if ((attr & FileAttributes.SparseFile) == FileAttributes.SparseFile) + result |= 0x200; + if ((attr & FileAttributes.System) == FileAttributes.System) + result |= 0x4; + if ((attr & FileAttributes.Temporary) == FileAttributes.Temporary) + result |= 0x100; - return result; - } - else - return WinSafeGetFileAttributes(path); + return result; +#else + return WinSafeGetFileAttributes(path); +#endif } internal static int WinSafeGetFileAttributes(string path) @@ -7074,11 +7064,11 @@ namespace Microsoft.PowerShell.Commands /// internal static bool PathIsNetworkPath(string path) { - // no other logic possible for now on linux - if (Platform.HasNetworkDriveSupport()) - return WinPathIsNetworkPath(path); - else - return false; +#if LINUX + return false; +#else + return WinPathIsNetworkPath(path); +#endif } internal static bool WinPathIsNetworkPath(string path) @@ -8202,7 +8192,7 @@ namespace Microsoft.PowerShell.Commands { if (!Platform.IsWindows) { - throw new Platform.PlatformNotSupportedException(); + throw new PlatformNotSupportedException(); } using (SafeFileHandle handle = OpenReparsePoint(filePath, FileDesiredAccess.GenericRead)) @@ -8595,14 +8585,11 @@ namespace Microsoft.PowerShell.Commands private static SafeFileHandle OpenReparsePoint(string reparsePoint, FileDesiredAccess accessMode) { - if (Platform.SupportsReparsePoints()) - { - return WinOpenReparsePoint(reparsePoint,accessMode); - } - else - { - throw new Platform.PlatformNotSupportedException(); - } +#if LINUX + throw new PlatformNotSupportedException(); +#else + return WinOpenReparsePoint(reparsePoint,accessMode); +#endif } private static SafeFileHandle WinOpenReparsePoint(string reparsePoint, FileDesiredAccess accessMode) diff --git a/src/System.Management.Automation/namespaces/LocationGlobber.cs b/src/System.Management.Automation/namespaces/LocationGlobber.cs index 313e9e0e6..c150dd717 100644 --- a/src/System.Management.Automation/namespaces/LocationGlobber.cs +++ b/src/System.Management.Automation/namespaces/LocationGlobber.cs @@ -1589,9 +1589,12 @@ namespace System.Management.Automation /// internal static bool IsSingleFileSystemAbsolutePath(string path) { - return Platform.HasSingleRootFilesystem() && - (path.StartsWith(StringLiterals.DefaultPathSeparatorString, StringComparison.Ordinal) || - path.StartsWith(StringLiterals.AlternatePathSeparatorString, StringComparison.Ordinal)); +#if LINUX + return path.StartsWith(StringLiterals.DefaultPathSeparatorString, StringComparison.Ordinal) + || path.StartsWith(StringLiterals.AlternatePathSeparatorString, StringComparison.Ordinal); +#else + return false; +#endif } // IsSingleFileSystemAbsolutePath /// diff --git a/src/System.Management.Automation/namespaces/RegistryProvider.cs b/src/System.Management.Automation/namespaces/RegistryProvider.cs index 1951f59ee..9a168ff7f 100644 --- a/src/System.Management.Automation/namespaces/RegistryProvider.cs +++ b/src/System.Management.Automation/namespaces/RegistryProvider.cs @@ -136,11 +136,7 @@ namespace Microsoft.PowerShell.Commands { Collection drives = new Collection(); - if (!Platform.HasRegistrySupport()) - { - return drives; - } - +#if !LINUX drives.Add( new PSDriveInfo( "HKLM", @@ -156,6 +152,7 @@ namespace Microsoft.PowerShell.Commands "HKEY_CURRENT_USER", RegistryProviderStrings.HKCUDriveDescription, null)); +#endif return drives; } // InitializeDefaultDrives diff --git a/src/System.Management.Automation/namespaces/SafeRegistryHandle.cs b/src/System.Management.Automation/namespaces/SafeRegistryHandle.cs index 1e817966b..80120a702 100644 --- a/src/System.Management.Automation/namespaces/SafeRegistryHandle.cs +++ b/src/System.Management.Automation/namespaces/SafeRegistryHandle.cs @@ -58,13 +58,13 @@ namespace Microsoft.PowerShell.Commands.Internal override protected bool ReleaseHandle() { - if (!Platform.HasRegistrySupport()) - { - return true; - } +#if LINUX + return true; +#else // Returns a Win32 error code, 0 for success int r = RegCloseKey(handle); return r == 0; +#endif } } } diff --git a/src/System.Management.Automation/security/SecuritySupport.cs b/src/System.Management.Automation/security/SecuritySupport.cs index 05ae9f77d..8d3fc91f2 100644 --- a/src/System.Management.Automation/security/SecuritySupport.cs +++ b/src/System.Management.Automation/security/SecuritySupport.cs @@ -138,11 +138,9 @@ namespace System.Management.Automation internal static void SetExecutionPolicy(ExecutionPolicyScope scope, ExecutionPolicy policy, string shellId) { - if (!Platform.HasExecutionPolicy()) - { - throw new PlatformNotSupportedException(); - } - +#if LINUX + throw new PlatformNotSupportedException(); +#else string executionPolicy = "Restricted"; string preferenceKey = Utils.GetRegistryConfigurationPath(shellId); const string PolicyKeyValueName = "ExecutionPolicy"; @@ -227,6 +225,7 @@ namespace System.Management.Automation break; } } +#endif } // Clean up the parents of a registry key as long as they @@ -283,11 +282,9 @@ namespace System.Management.Automation internal static ExecutionPolicy GetExecutionPolicy(string shellId, ExecutionPolicyScope scope) { - if (!Platform.HasExecutionPolicy()) - { - throw new PlatformNotSupportedException(); - } - +#if LINUX + return ExecutionPolicy.Unrestricted; +#else switch (scope) { case ExecutionPolicyScope.Process: @@ -368,6 +365,7 @@ namespace System.Management.Automation } return ExecutionPolicy.Restricted; +#endif } internal static ExecutionPolicy ParseExecutionPolicy(string policy) @@ -1633,14 +1631,11 @@ namespace System.Management.Automation /// AMSI_RESULT_DETECTED if malware was detected in the sample. internal static AmsiNativeMethods.AMSI_RESULT ScanContent(string content, string sourceMetadata) { - if (Platform.HasAmsi()) - { - return WinScanContent(content,sourceMetadata); - } - else - { - return AmsiNativeMethods.AMSI_RESULT.AMSI_RESULT_NOT_DETECTED; - } +#if LINUX + return AmsiNativeMethods.AMSI_RESULT.AMSI_RESULT_NOT_DETECTED; +#else + return WinScanContent(content,sourceMetadata); +#endif } internal static AmsiNativeMethods.AMSI_RESULT WinScanContent(string content, string sourceMetadata) @@ -1730,14 +1725,9 @@ namespace System.Management.Automation internal static void CurrentDomain_ProcessExit(object sender, EventArgs e) { - if (Platform.HasAmsi()) - { - VerifyAmsiUninitializeCalled(); - } - else - { - throw new PlatformNotSupportedException(); - } +#if !LINUX + VerifyAmsiUninitializeCalled(); +#endif } [SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")] @@ -1753,16 +1743,9 @@ namespace System.Management.Automation /// internal static void CloseSession() { - if (Platform.HasAmsi()) - { - WinCloseSession(); - } - else - { - // Porting note: cannot throw here because this is called whether or not - // AMSI was initialized in the first place - return; - } +#if !LINUX + WinCloseSession(); +#endif } internal static void WinCloseSession() @@ -1789,16 +1772,9 @@ namespace System.Management.Automation /// internal static void Uninitialize() { - if (Platform.HasAmsi()) - { - WinUninitialize(); - } - else - { - // Porting note: cannot throw here because this is called whether or not - // AMSI was initialized in the first place - return; - } +#if !LINUX + WinUninitialize(); +#endif } internal static void WinUninitialize() diff --git a/src/System.Management.Automation/utils/ExtensionMethods.cs b/src/System.Management.Automation/utils/ExtensionMethods.cs index 0e58cc55f..1c1c76f19 100644 --- a/src/System.Management.Automation/utils/ExtensionMethods.cs +++ b/src/System.Management.Automation/utils/ExtensionMethods.cs @@ -130,12 +130,9 @@ namespace System.Management.Automation [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool IsComObject(this Type type) { - if (!Platform.HasCom()) - { - return false; - } - -#if CORECLR // Type.IsComObject(Type) is not in CoreCLR +#if LINUX + return false; +#elif CORECLR // Type.IsComObject(Type) is not in CoreCLR return ComObjectType.IsAssignableFrom(type); #else return type.IsCOMObject; diff --git a/src/libpsl-native/src/CMakeLists.txt b/src/libpsl-native/src/CMakeLists.txt index 8b3d0f19a..5d4c432b4 100644 --- a/src/libpsl-native/src/CMakeLists.txt +++ b/src/libpsl-native/src/CMakeLists.txt @@ -1,5 +1,6 @@ add_library(psl-native SHARED getstat.cpp + getlstat.cpp getpwuid.cpp getuserfrompid.cpp getfileowner.cpp @@ -8,6 +9,8 @@ add_library(psl-native SHARED getcomputername.cpp getlinkcount.cpp getfullyqualifiedname.cpp + isfile.cpp + isdirectory.cpp issymlink.cpp isexecutable.cpp setdate.cpp diff --git a/src/libpsl-native/src/createsymlink.cpp b/src/libpsl-native/src/createsymlink.cpp index 4ea8d6fd9..b9ce2b18d 100644 --- a/src/libpsl-native/src/createsymlink.cpp +++ b/src/libpsl-native/src/createsymlink.cpp @@ -39,26 +39,25 @@ //! - ERROR_INVALID_FUNCTION: incorrect function //! - ERROR_BAD_PATH_NAME: pathname is too long, or contains invalid characters //! -//! @retval 1 if creation is successful -//! @retval 0 if createion failed +//! @retval boolean successful //! -int32_t CreateSymLink(const char *link, const char *target) +bool CreateSymLink(const char *link, const char *target) { - errno = 0; + errno = 0; // Check parameters if (!link || !target) { errno = ERROR_INVALID_PARAMETER; - return 0; + return false; } - int returnCode = symlink(target, link); + int ret = symlink(target, link); - if (returnCode == 0) + if (ret == 0) { - return 1; + return true; } switch(errno) @@ -102,5 +101,6 @@ int32_t CreateSymLink(const char *link, const char *target) default: errno = ERROR_INVALID_FUNCTION; } - return 0; + + return false; } diff --git a/src/libpsl-native/src/createsymlink.h b/src/libpsl-native/src/createsymlink.h index e47bce3fa..45da92890 100644 --- a/src/libpsl-native/src/createsymlink.h +++ b/src/libpsl-native/src/createsymlink.h @@ -1,9 +1,10 @@ #pragma once #include "pal.h" +#include PAL_BEGIN_EXTERNC -int32_t CreateSymLink(const char *link, const char *target); +bool CreateSymLink(const char *link, const char *target); PAL_END_EXTERNC diff --git a/src/libpsl-native/src/getlstat.cpp b/src/libpsl-native/src/getlstat.cpp new file mode 100644 index 000000000..d2fcb6969 --- /dev/null +++ b/src/libpsl-native/src/getlstat.cpp @@ -0,0 +1,95 @@ +//! @file getlstat.cpp +//! @author Andrew Schwartzmeyer +//! @brief returns the lstat of a file + +#include +#include +#include +#include +#include +#include +#include "getlstat.h" + +//! @brief GetLStat returns the lstat of a file. This simply delegates to the +//! lstat() system call and maps errno to the expected values for GetLastError. +//! +//! GetLstat +//! +//! @param[in] path +//! @parblock +//! A pointer to the buffer that contains the file name +//! +//! char* is marshaled as an LPStr, which on Linux is UTF-8. +//! @endparblock +//! +//! @param[in] lstat +//! @parblock +//! A pointer to the buffer in which to place the lstat information +//! @endparblock +//! +//! @exception errno Passes these errors via errno to GetLastError: +//! - ERROR_INVALID_PARAMETER: parameter is not valid +//! - ERROR_FILE_NOT_FOUND: file does not exist +//! - ERROR_ACCESS_DENIED: access is denied +//! - ERROR_INVALID_ADDRESS: attempt to access invalid address +//! - ERROR_STOPPED_ON_SYMLINK: too many symbolic links +//! - ERROR_GEN_FAILURE: I/O error occurred +//! - ERROR_INVALID_NAME: file provided is not a symbolic link +//! - ERROR_INVALID_FUNCTION: incorrect function +//! - ERROR_BAD_PATH_NAME: pathname is too long +//! - ERROR_OUTOFMEMORY insufficient kernel memory +//! +//! @retval 0 if successful +//! @retval -1 if failed +//! + +int32_t GetLStat(const char* path, struct stat* buf) +{ + errno = 0; + + if (!path) + { + errno = ERROR_INVALID_PARAMETER; + return -1; + } + + int32_t ret = lstat(path, buf); + + if (ret != 0) + { + switch(errno) + { + case EACCES: + errno = ERROR_ACCESS_DENIED; + break; + case EBADF: + errno = ERROR_FILE_NOT_FOUND; + break; + case EFAULT: + errno = ERROR_INVALID_ADDRESS; + break; + case ELOOP: + errno = ERROR_STOPPED_ON_SYMLINK; + break; + case ENAMETOOLONG: + errno = ERROR_GEN_FAILURE; + break; + case ENOENT: + errno = ERROR_FILE_NOT_FOUND; + break; + case ENOMEM: + errno = ERROR_NO_SUCH_USER; + break; + case ENOTDIR: + errno = ERROR_INVALID_NAME; + break; + case EOVERFLOW: + errno = ERROR_BUFFER_OVERFLOW; + break; + default: + errno = ERROR_INVALID_FUNCTION; + } + } + + return ret; +} diff --git a/src/libpsl-native/src/getlstat.h b/src/libpsl-native/src/getlstat.h new file mode 100644 index 000000000..ba746dd35 --- /dev/null +++ b/src/libpsl-native/src/getlstat.h @@ -0,0 +1,10 @@ +#pragma once + +#include +#include "pal.h" + +PAL_BEGIN_EXTERNC + +int32_t GetLStat(const char* path, struct stat* buf); + +PAL_END_EXTERNC diff --git a/src/libpsl-native/src/getstat.cpp b/src/libpsl-native/src/getstat.cpp index 3e89d1a6e..8fd666221 100644 --- a/src/libpsl-native/src/getstat.cpp +++ b/src/libpsl-native/src/getstat.cpp @@ -89,8 +89,7 @@ int32_t GetStat(const char* path, struct stat* buf) default: errno = ERROR_INVALID_FUNCTION; } - return -1; } - return 0; + return ret; } diff --git a/src/libpsl-native/src/isdirectory.cpp b/src/libpsl-native/src/isdirectory.cpp new file mode 100644 index 000000000..f8b6bfe74 --- /dev/null +++ b/src/libpsl-native/src/isdirectory.cpp @@ -0,0 +1,50 @@ +//! @file isdirectory.cpp +//! @author Andrew Schwartzmeyer +//! @brief returns if the path is a directory + +#include +#include +#include +#include +#include +#include +#include "getstat.h" +#include "getpwuid.h" +#include "getfileowner.h" +#include "isdirectory.h" + +//! @brief returns if the path is a directory; uses stat and so follows symlinks +//! +//! IsDirectory +//! +//! @param[in] path +//! @parblock +//! A pointer to the buffer that contains the file name +//! +//! char* is marshaled as an LPStr, which on Linux is UTF-8. +//! @endparblock +//! +//! @exception errno Passes this error via errno to GetLastError: +//! - ERROR_INVALID_PARAMETER: parameter is not valid +//! +//! @retval true if directory, false otherwise +//! +bool IsDirectory(const char* path) +{ + errno = 0; + + if (!path) + { + errno = ERROR_INVALID_PARAMETER; + return false; + } + + struct stat buf; + int32_t ret = GetStat(path, &buf); + if (ret != 0) + { + return false; + } + + return S_ISDIR(buf.st_mode); +} diff --git a/src/libpsl-native/src/isdirectory.h b/src/libpsl-native/src/isdirectory.h new file mode 100644 index 000000000..746d1c579 --- /dev/null +++ b/src/libpsl-native/src/isdirectory.h @@ -0,0 +1,10 @@ +#pragma once + +#include "pal.h" +#include + +PAL_BEGIN_EXTERNC + +bool IsDirectory(const char* path); + +PAL_END_EXTERNC diff --git a/src/libpsl-native/src/isexecutable.cpp b/src/libpsl-native/src/isexecutable.cpp index 38f6ad184..a06fab57a 100644 --- a/src/libpsl-native/src/isexecutable.cpp +++ b/src/libpsl-native/src/isexecutable.cpp @@ -1,5 +1,5 @@ -//! @file isExecutable.cpp -//! @author George FLeming +//! @file isexecutable.cpp +//! @author George Fleming //! @brief returns whether a file is executable #include @@ -11,7 +11,7 @@ //! //! IsExecutable //! -//! @param[in] fileName +//! @param[in] path //! @parblock //! A pointer to the buffer that contains the file name //! @@ -19,63 +19,21 @@ //! @endparblock //! //! @exception errno Passes these errors via errno to GetLastError: -//! - ERROR_FILE_NOT_FOUND: the system cannot find the file specified //! - ERROR_INVALID_ADDRESS: attempt to access invalid address -//! - ERROR_GEN_FAILURE: device attached to the system is not functioning -//! - ERROR_INVALID_NAME: filename, directory name, or volume label syntax is incorrect -//! - ERROR_INVALID_FUNCTION: incorrect function -//! - ERROR_INVALID_PARAMETER: parameter to access(2) call is incorrect //! -//! @retval 1 if path is an executable -//! @retval 0 if path is not a executable -//! @retval -1 If the function fails.. To get extended error information, call GetLastError. +//! @retval true if path is an executable, false otherwise //! -int32_t IsExecutable(const char* fileName) +bool IsExecutable(const char* path) { errno = 0; // Check parameters - if (!fileName) + if (!path) { errno = ERROR_INVALID_PARAMETER; - return -1; + return false; } - int returnCode = access(fileName, X_OK); - - if (returnCode == 0) - { - return 1; - } - - switch(errno) - { - case EACCES: - return 0; - case EBADF: - case ENOENT: - errno = ERROR_FILE_NOT_FOUND; - break; - case EFAULT: - errno = ERROR_INVALID_ADDRESS; - break; - case ELOOP: - errno = ERROR_STOPPED_ON_SYMLINK; - break; - case EIO: - case ENOMEM: - errno = ERROR_GEN_FAILURE; - break; - case ENOTDIR: - case ENAMETOOLONG: - errno = ERROR_INVALID_NAME; - break; - case EINVAL: - errno = ERROR_INVALID_PARAMETER; - break; - default: - errno = ERROR_INVALID_FUNCTION; - } - return -1; + return access(path, X_OK) != -1; } diff --git a/src/libpsl-native/src/isexecutable.h b/src/libpsl-native/src/isexecutable.h index da4e9f8f3..f4278b954 100644 --- a/src/libpsl-native/src/isexecutable.h +++ b/src/libpsl-native/src/isexecutable.h @@ -1,9 +1,10 @@ #pragma once #include "pal.h" +#include PAL_BEGIN_EXTERNC -int32_t IsExecutable(const char* fileName); +bool IsExecutable(const char* path); PAL_END_EXTERNC diff --git a/src/libpsl-native/src/isfile.cpp b/src/libpsl-native/src/isfile.cpp new file mode 100644 index 000000000..1f6d0c59e --- /dev/null +++ b/src/libpsl-native/src/isfile.cpp @@ -0,0 +1,43 @@ +//! @file isfile.cpp +//! @author Andrew Schwartzmeyer +//! @brief returns if the path exists + +#include +#include +#include +#include +#include +#include +#include +#include "getlstat.h" +#include "isfile.h" + +//! @brief returns if the path is a file or directory +//! +//! IsFile +//! +//! @param[in] path +//! @parblock +//! A pointer to the buffer that contains the file name +//! +//! char* is marshaled as an LPStr, which on Linux is UTF-8. +//! @endparblock +//! +//! @exception errno Passes this error via errno to GetLastError: +//! - ERROR_INVALID_PARAMETER: parameter is not valid +//! +//! @retval true if path exists, false otherwise +//! +bool IsFile(const char* path) +{ + errno = 0; + + if (!path) + { + errno = ERROR_INVALID_PARAMETER; + return false; + } + + struct stat buf; + return GetLStat(path, &buf) == 0; +} diff --git a/src/libpsl-native/src/isfile.h b/src/libpsl-native/src/isfile.h new file mode 100644 index 000000000..53a15f97d --- /dev/null +++ b/src/libpsl-native/src/isfile.h @@ -0,0 +1,10 @@ +#pragma once + +#include "pal.h" +#include + +PAL_BEGIN_EXTERNC + +bool IsFile(const char* path); + +PAL_END_EXTERNC diff --git a/src/libpsl-native/src/issymlink.cpp b/src/libpsl-native/src/issymlink.cpp index d4ce011cb..87a8a2e8d 100644 --- a/src/libpsl-native/src/issymlink.cpp +++ b/src/libpsl-native/src/issymlink.cpp @@ -7,13 +7,14 @@ #include #include #include +#include "getlstat.h" #include "issymlink.h" -//! @brief IsSymLink determines if path is a symbolic link +//! @brief IsSymlink determines if path is a symbolic link //! -//! IsSymLink +//! IsSymlink //! -//! @param[in] fileName +//! @param[in] path //! @parblock //! A pointer to the buffer that contains the file name //! @@ -34,63 +35,26 @@ //! - ERROR_INVALID_FUNCTION: incorrect function //! - ERROR_BAD_PATH_NAME: pathname is too long, or contains invalid characters //! -//! @retval 1 if path is a symbolic link -//! @retval 0 if path is not a symbolic link -//! @retval -1 If the function fails.. To get extended error information, call GetLastError. +//! @retval true if path is a symbolic link, false otherwise //! -int32_t IsSymLink(const char* fileName) +bool IsSymLink(const char* path) { - - errno = 0; + errno = 0; // Check parameters - if (!fileName) + if (!path) { errno = ERROR_INVALID_PARAMETER; - return -1; + return false; } - struct stat statBuf; - - int returnCode = lstat(fileName, &statBuf); - - if (returnCode != 0) + struct stat buf; + int32_t ret = GetLStat(path, &buf); + if (ret != 0) { - switch(errno) - { - case EACCES: - errno = ERROR_ACCESS_DENIED; - break; - case EBADF: - errno = ERROR_FILE_NOT_FOUND; - break; - case EFAULT: - errno = ERROR_INVALID_ADDRESS; - break; - case ELOOP: - errno = ERROR_STOPPED_ON_SYMLINK; - break; - case ENAMETOOLONG: - errno = ERROR_GEN_FAILURE; - break; - case ENOENT: - errno = ERROR_FILE_NOT_FOUND; - break; - case ENOMEM: - errno = ERROR_NO_SUCH_USER; - break; - case ENOTDIR: - errno = ERROR_INVALID_NAME; - break; - case EOVERFLOW: - errno = ERROR_BUFFER_OVERFLOW; - break; - default: - errno = ERROR_INVALID_FUNCTION; - } - return -1; + return false; } - return S_ISLNK(statBuf.st_mode) ? 1 : 0; + return S_ISLNK(buf.st_mode); } diff --git a/src/libpsl-native/src/issymlink.h b/src/libpsl-native/src/issymlink.h index 066a4060c..ebe3733c5 100644 --- a/src/libpsl-native/src/issymlink.h +++ b/src/libpsl-native/src/issymlink.h @@ -1,9 +1,10 @@ #pragma once #include "pal.h" +#include PAL_BEGIN_EXTERNC -int32_t IsSymLink(const char* fileName); +bool IsSymLink(const char* path); PAL_END_EXTERNC diff --git a/src/libpsl-native/test/CMakeLists.txt b/src/libpsl-native/test/CMakeLists.txt index ed4440d2a..2f57741b0 100644 --- a/src/libpsl-native/test/CMakeLists.txt +++ b/src/libpsl-native/test/CMakeLists.txt @@ -9,6 +9,8 @@ add_executable(psl-native-test test-getcomputername.cpp test-getlinkcount.cpp test-getfullyqualifiedname.cpp + test-isdirectory.cpp + test-isfile.cpp test-issymlink.cpp test-isexecutable.cpp test-createsymlink.cpp diff --git a/src/libpsl-native/test/test-createsymlink.cpp b/src/libpsl-native/test/test-createsymlink.cpp index 7bb9997b3..1aab3379a 100644 --- a/src/libpsl-native/test/test-createsymlink.cpp +++ b/src/libpsl-native/test/test-createsymlink.cpp @@ -39,36 +39,36 @@ protected: EXPECT_TRUE(dir != NULL); // Create symbolic link to file - int ret1 = CreateSymLink(fileSymLink.c_str(), file); - EXPECT_EQ(ret1, 1); + bool ret1 = CreateSymLink(fileSymLink.c_str(), file); + EXPECT_TRUE(ret1); // Create symbolic link to directory - int ret2 = CreateSymLink(dirSymLink.c_str(), dir); - EXPECT_EQ(ret2, 1); + bool ret2 = CreateSymLink(dirSymLink.c_str(), dir); + EXPECT_TRUE(ret2); } ~CreateSymLinkTest() { - int ret; + bool ret; ret = unlink(fileSymLink.c_str()); - EXPECT_EQ(0, ret); + EXPECT_FALSE(ret); ret = unlink(dirSymLink.c_str()); - EXPECT_EQ(0, ret); + EXPECT_FALSE(ret); ret = unlink(file); - EXPECT_EQ(0, ret); + EXPECT_FALSE(ret); ret = rmdir(dir); - EXPECT_EQ(0, ret); + EXPECT_FALSE(ret); } }; TEST_F(CreateSymLinkTest, FilePathNameIsNull) { - int retVal = CreateSymLink(NULL, NULL); - EXPECT_EQ(retVal, 0); + bool retVal = CreateSymLink(NULL, NULL); + EXPECT_FALSE(retVal); EXPECT_EQ(ERROR_INVALID_PARAMETER, errno); } @@ -82,8 +82,8 @@ TEST_F(CreateSymLinkTest, FilePathNameDoesNotExist) unlink(invalidLink.c_str()); // Linux allows creation of symbolic link that points to an invalid file - int retVal = CreateSymLink(invalidLink.c_str(), invalidFile.c_str()); - EXPECT_EQ(retVal, 1); + bool retVal = CreateSymLink(invalidLink.c_str(), invalidFile.c_str()); + EXPECT_TRUE(retVal); std::string target = FollowSymLink(invalidLink.c_str()); EXPECT_EQ(target, invalidFile); @@ -93,8 +93,8 @@ TEST_F(CreateSymLinkTest, FilePathNameDoesNotExist) TEST_F(CreateSymLinkTest, SymLinkToFile) { - int retVal = IsSymLink(fileSymLink.c_str()); - EXPECT_EQ(1, retVal); + bool retVal = IsSymLink(fileSymLink.c_str()); + EXPECT_TRUE(retVal); std::string target = FollowSymLink(fileSymLink.c_str()); char buffer[PATH_MAX]; @@ -104,8 +104,8 @@ TEST_F(CreateSymLinkTest, SymLinkToFile) TEST_F(CreateSymLinkTest, SymLinkToDirectory) { - int retVal = IsSymLink(dirSymLink.c_str()); - EXPECT_EQ(1, retVal); + bool retVal = IsSymLink(dirSymLink.c_str()); + EXPECT_TRUE(retVal); std::string target = FollowSymLink(dirSymLink.c_str()); char buffer[PATH_MAX]; @@ -115,7 +115,7 @@ TEST_F(CreateSymLinkTest, SymLinkToDirectory) TEST_F(CreateSymLinkTest, SymLinkAgain) { - int retVal = CreateSymLink(fileSymLink.c_str(), file); - EXPECT_EQ(0, retVal); + bool retVal = CreateSymLink(fileSymLink.c_str(), file); + EXPECT_FALSE(retVal); EXPECT_EQ(ERROR_FILE_EXISTS, errno); } diff --git a/src/libpsl-native/test/test-isdirectory.cpp b/src/libpsl-native/test/test-isdirectory.cpp new file mode 100644 index 000000000..27c840cba --- /dev/null +++ b/src/libpsl-native/test/test-isdirectory.cpp @@ -0,0 +1,31 @@ +//! @file test-isdirectory.cpp +//! @author Andrew Schwartzmeyer +//! @brief Tests IsDirectory + +#include +#include +#include +#include "isdirectory.h" + +TEST(IsDirectoryTest, RootIsDirectory) +{ + EXPECT_TRUE(IsDirectory("/")); +} + +TEST(IsDirectoryTest, BinLsIsNotDirectory) +{ + EXPECT_FALSE(IsDirectory("/bin/ls")); +} + + +TEST(IsDirectoryTest, ReturnsFalseForFakeDirectory) +{ + EXPECT_FALSE(IsDirectory("SomeMadeUpFileNameThatDoesNotExist")); + EXPECT_EQ(errno, ERROR_FILE_NOT_FOUND); +} + +TEST(IsDirectoryTest, ReturnsFalseForNullInput) +{ + EXPECT_FALSE(IsDirectory(NULL)); + EXPECT_EQ(errno, ERROR_INVALID_PARAMETER); +} diff --git a/src/libpsl-native/test/test-isexecutable.cpp b/src/libpsl-native/test/test-isexecutable.cpp index 36955912f..d97d7d315 100644 --- a/src/libpsl-native/test/test-isexecutable.cpp +++ b/src/libpsl-native/test/test-isexecutable.cpp @@ -33,62 +33,52 @@ protected: // First create a file int fd = mkstemp(fileTemplateBuf); EXPECT_TRUE(fd != -1); - file = fileTemplateBuf; + file = fileTemplateBuf; } ~IsExecutableTest() { - int ret; - - ret = unlink(file); - EXPECT_EQ(0, ret); + EXPECT_FALSE(unlink(file)); } void ChangeFilePermission(const char* file, mode_t mode) { - int ret = chmod(file, mode); - EXPECT_EQ(ret, 0); + EXPECT_FALSE(chmod(file, mode)); } }; TEST_F(IsExecutableTest, FilePathNameIsNull) { - int32_t retVal = IsExecutable(NULL); - EXPECT_EQ(retVal, -1); + EXPECT_FALSE(IsExecutable(NULL)); EXPECT_EQ(ERROR_INVALID_PARAMETER, errno); } TEST_F(IsExecutableTest, FilePathNameDoesNotExist) { std::string invalidFile = "/tmp/isexecutabletest_invalidFile"; - int32_t retVal = IsExecutable(invalidFile.c_str()); - EXPECT_EQ(retVal, -1); + EXPECT_FALSE(IsExecutable(invalidFile.c_str())); EXPECT_EQ(ERROR_FILE_NOT_FOUND, errno); } TEST_F(IsExecutableTest, NormalFileIsNotIsexecutable) { - int32_t retVal = IsExecutable(file); - EXPECT_EQ(0, retVal); - + EXPECT_FALSE(IsExecutable(file)); + ChangeFilePermission(file, mode_444); - retVal = IsExecutable(file); - EXPECT_EQ(0, retVal); + EXPECT_FALSE(IsExecutable(file)); } TEST_F(IsExecutableTest, FilePermission_700) { ChangeFilePermission(file, mode_700); - int32_t retVal = IsExecutable(file); - EXPECT_EQ(1, retVal); + EXPECT_TRUE(IsExecutable(file)); } TEST_F(IsExecutableTest, FilePermission_777) { ChangeFilePermission(file, mode_777); - int32_t retVal = IsExecutable(file); - EXPECT_EQ(1, retVal); + EXPECT_TRUE(IsExecutable(file)); } diff --git a/src/libpsl-native/test/test-isfile.cpp b/src/libpsl-native/test/test-isfile.cpp new file mode 100644 index 000000000..09d72f5bf --- /dev/null +++ b/src/libpsl-native/test/test-isfile.cpp @@ -0,0 +1,30 @@ +//! @file test-isfile.cpp +//! @author Andrew Schwartzmeyer +//! @brief Tests Isfile + +#include +#include +#include +#include "isfile.h" + +TEST(IsFileTest, RootIsFile) +{ + EXPECT_TRUE(IsFile("/")); +} + +TEST(IsFileTest, BinLsIsFile) +{ + EXPECT_TRUE(IsFile("/bin/ls")); +} + +TEST(IsFileTest, CannotGetOwnerOfFakeFile) +{ + EXPECT_FALSE(IsFile("SomeMadeUpFileNameThatDoesNotExist")); + EXPECT_EQ(errno, ERROR_FILE_NOT_FOUND); +} + +TEST(IsFileTest, ReturnsFalseForNullInput) +{ + EXPECT_FALSE(IsFile(NULL)); + EXPECT_EQ(errno, ERROR_INVALID_PARAMETER); +} diff --git a/src/libpsl-native/test/test-issymlink.cpp b/src/libpsl-native/test/test-issymlink.cpp index 4aaa3eb54..512a4053a 100644 --- a/src/libpsl-native/test/test-issymlink.cpp +++ b/src/libpsl-native/test/test-issymlink.cpp @@ -30,75 +30,60 @@ protected: // First create a file int fd = mkstemp(fileTemplateBuf); EXPECT_TRUE(fd != -1); - file = fileTemplateBuf; + file = fileTemplateBuf; - // Create a temp directory - dir = mkdtemp(dirTemplateBuf); + // Create a temp directory + dir = mkdtemp(dirTemplateBuf); EXPECT_TRUE(dir != NULL); // Create symbolic link to file - int ret1 = symlink(file, fileSymLink.c_str()); - EXPECT_EQ(ret1, 0); - + EXPECT_FALSE(symlink(file, fileSymLink.c_str())); + // Create symbolic link to directory - int ret2 = symlink(dir, dirSymLink.c_str()); - EXPECT_EQ(ret2, 0); + EXPECT_FALSE(symlink(dir, dirSymLink.c_str())); } ~isSymLinkTest() { - int ret; + EXPECT_FALSE(unlink(fileSymLink.c_str())); - ret = unlink(fileSymLink.c_str()); - EXPECT_EQ(0, ret); + EXPECT_FALSE(unlink(dirSymLink.c_str())); - ret = unlink(dirSymLink.c_str()); - EXPECT_EQ(0, ret); + EXPECT_FALSE(unlink(file)); - ret = unlink(file); - EXPECT_EQ(0, ret); - - ret = rmdir(dir); - EXPECT_EQ(0, ret); + EXPECT_FALSE(rmdir(dir)); } }; TEST_F(isSymLinkTest, FilePathNameIsNull) { - int retVal = IsSymLink(NULL); - EXPECT_EQ(retVal, -1); + EXPECT_FALSE(IsSymLink(NULL)); EXPECT_EQ(ERROR_INVALID_PARAMETER, errno); } TEST_F(isSymLinkTest, FilePathNameDoesNotExist) { std::string invalidFile = "/tmp/symlinktest_invalidFile"; - int retVal = IsSymLink(invalidFile.c_str()); - EXPECT_EQ(retVal, -1); + EXPECT_FALSE(IsSymLink(invalidFile.c_str())); EXPECT_EQ(ERROR_FILE_NOT_FOUND, errno); } TEST_F(isSymLinkTest, NormalFileIsNotSymLink) { - int retVal = IsSymLink(file); - EXPECT_EQ(0, retVal); + EXPECT_FALSE(IsSymLink(file)); } TEST_F(isSymLinkTest, SymLinkToFile) { - int retVal = IsSymLink(fileSymLink.c_str()); - EXPECT_EQ(1, retVal); + EXPECT_TRUE(IsSymLink(fileSymLink.c_str())); } TEST_F(isSymLinkTest, NormalDirectoryIsNotSymbLink) { - int retVal = IsSymLink(dir); - EXPECT_EQ(0, retVal); + EXPECT_FALSE(IsSymLink(dir)); } TEST_F(isSymLinkTest, SymLinkToDirectory) { - int retVal = IsSymLink(dirSymLink.c_str()); - EXPECT_EQ(1, retVal); + EXPECT_TRUE(IsSymLink(dirSymLink.c_str())); } - diff --git a/test/csharp/test_CorePsPlatform.cs b/test/csharp/test_CorePsPlatform.cs index d0132b121..80d387891 100644 --- a/test/csharp/test_CorePsPlatform.cs +++ b/test/csharp/test_CorePsPlatform.cs @@ -15,30 +15,6 @@ namespace PSTests Assert.True(Platform.IsCore); } - [Fact] - public static void TestHasCom() - { - Assert.False(Platform.HasCom()); - } - - [Fact] - public static void TestHasAmsi() - { - Assert.False(Platform.HasAmsi()); - } - - [Fact] - public static void TestHasDriveAutoMounting() - { - Assert.False(Platform.HasDriveAutoMounting()); - } - - [Fact] - public static void TestHasRegistrySupport() - { - Assert.False(Platform.HasRegistrySupport()); - } - [Fact] public static void TestGetUserName() { diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 index 593f892ad..155f2226f 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/New-Item.Tests.ps1 @@ -2,17 +2,17 @@ function Clean-State { if (Test-Path $FullyQualifiedLink) { - Remove-Item $FullyQualifiedLink -Force + Remove-Item $FullyQualifiedLink -Force } if (Test-Path $FullyQualifiedFile) { - Remove-Item $FullyQualifiedFile -Force + Remove-Item $FullyQualifiedFile -Force } if (Test-Path $FullyQualifiedFolder) { - Remove-Item $FullyQualifiedFolder -Force + Remove-Item $FullyQualifiedFolder -Force } } @@ -26,17 +26,17 @@ Describe "New-Item" { $FullyQualifiedLink = Join-Path -Path $tmpDirectory -ChildPath $testlink BeforeEach { - Clean-State + Clean-State } It "should call the function without error" { - { New-Item -Name $testfile -Path $tmpDirectory -ItemType file } | Should Not Throw + { New-Item -Name $testfile -Path $tmpDirectory -ItemType file } | Should Not Throw } It "Should create a file without error" { - New-Item -Name $testfile -Path $tmpDirectory -ItemType file + New-Item -Name $testfile -Path $tmpDirectory -ItemType file - Test-Path $FullyQualifiedFile | Should Be $true + Test-Path $FullyQualifiedFile | Should Be $true $fileInfo = Get-ChildItem $FullyQualifiedFile $fileInfo.Target | Should Be $null @@ -44,72 +44,72 @@ Describe "New-Item" { } It "Should create a folder without an error" { - New-Item -Name newDirectory -Path $tmpDirectory -ItemType directory + New-Item -Name newDirectory -Path $tmpDirectory -ItemType directory - Test-Path $FullyQualifiedFolder | Should Be $true + Test-Path $FullyQualifiedFolder | Should Be $true } It "Should create a file using the ni alias" { - ni -Name $testfile -Path $tmpDirectory -ItemType file + ni -Name $testfile -Path $tmpDirectory -ItemType file - Test-Path $FullyQualifiedFile | Should Be $true + Test-Path $FullyQualifiedFile | Should Be $true } It "Should create a file using the Type alias instead of ItemType" { - New-Item -Name $testfile -Path $tmpDirectory -Type file + New-Item -Name $testfile -Path $tmpDirectory -Type file - Test-Path $FullyQualifiedFile | Should Be $true + Test-Path $FullyQualifiedFile | Should Be $true } It "Should create a file with sample text inside the file using the Value switch" { - $expected = "This is test string" - New-Item -Name $testfile -Path $tmpDirectory -ItemType file -Value $expected + $expected = "This is test string" + New-Item -Name $testfile -Path $tmpDirectory -ItemType file -Value $expected - Test-Path $FullyQualifiedFile | Should Be $true + Test-Path $FullyQualifiedFile | Should Be $true - Get-Content $FullyQualifiedFile | Should Be $expected + Get-Content $FullyQualifiedFile | Should Be $expected } It "Should not create a file when the Name switch is not used and only a directory specified" { - #errorAction used because permissions issue in Windows - New-Item -Path $tmpDirectory -ItemType file -ErrorAction SilentlyContinue + #errorAction used because permissions issue in Windows + New-Item -Path $tmpDirectory -ItemType file -ErrorAction SilentlyContinue - Test-Path $FullyQualifiedFile | Should Be $false + Test-Path $FullyQualifiedFile | Should Be $false } It "Should create a file when the Name switch is not used but a fully qualified path is specified" { - New-Item -Path $FullyQualifiedFile -ItemType file + New-Item -Path $FullyQualifiedFile -ItemType file - Test-Path $FullyQualifiedFile | Should Be $true + Test-Path $FullyQualifiedFile | Should Be $true } It "Should be able to create a multiple items in different directories" { - $FullyQualifiedFile2 = Join-Path -Path $tmpDirectory -ChildPath test2.txt - New-Item -ItemType file -Path $FullyQualifiedFile, $FullyQualifiedFile2 + $FullyQualifiedFile2 = Join-Path -Path $tmpDirectory -ChildPath test2.txt + New-Item -ItemType file -Path $FullyQualifiedFile, $FullyQualifiedFile2 - Test-Path $FullyQualifiedFile | Should Be $true - Test-Path $FullyQualifiedFile2 | Should Be $true + Test-Path $FullyQualifiedFile | Should Be $true + Test-Path $FullyQualifiedFile2 | Should Be $true - Remove-Item $FullyQualifiedFile2 + Remove-Item $FullyQualifiedFile2 } It "Should be able to call the whatif switch without error" { - { New-Item -Name testfile.txt -Path $tmpDirectory -ItemType file -WhatIf } | Should Not Throw + { New-Item -Name testfile.txt -Path $tmpDirectory -ItemType file -WhatIf } | Should Not Throw } It "Should not create a new file when the whatif switch is used" { - New-Item -Name $testfile -Path $tmpDirectory -ItemType file -WhatIf + New-Item -Name $testfile -Path $tmpDirectory -ItemType file -WhatIf - Test-Path $FullyQualifiedFile | Should Be $false + Test-Path $FullyQualifiedFile | Should Be $false } It "Should create a symbolic link of a file without error" { - New-Item -Name $testfile -Path $tmpDirectory -ItemType file - Test-Path $FullyQualifiedFile | Should Be $true + New-Item -Name $testfile -Path $tmpDirectory -ItemType file + Test-Path $FullyQualifiedFile | Should Be $true - New-Item -ItemType SymbolicLink -Target $FullyQualifiedFile -Name $testlink -Path $tmpDirectory - Test-Path $FullyQualifiedLink | Should Be $true + New-Item -ItemType SymbolicLink -Target $FullyQualifiedFile -Name $testlink -Path $tmpDirectory + Test-Path $FullyQualifiedLink | Should Be $true $fileInfo = Get-ChildItem $FullyQualifiedLink $fileInfo.Target | Should Match ([regex]::Escape($FullyQualifiedFile)) @@ -128,18 +128,18 @@ Describe "New-Item" { } It "Should create a symbolic link from directory without error" { - New-Item -Name $testFolder -Path $tmpDirectory -ItemType directory - Test-Path $FullyQualifiedFolder | Should Be $true + New-Item -Name $testFolder -Path $tmpDirectory -ItemType directory + Test-Path $FullyQualifiedFolder | Should Be $true - New-Item -ItemType SymbolicLink -Target $FullyQualifiedFolder -Name $testlink -Path $tmpDirectory - Test-Path $FullyQualifiedLink | Should Be $true + New-Item -ItemType SymbolicLink -Target $FullyQualifiedFolder -Name $testlink -Path $tmpDirectory + Test-Path $FullyQualifiedLink | Should Be $true $fileInfo = Get-ChildItem $FullyQualifiedLink $fileInfo.Target | Should Match ([regex]::Escape($FullyQualifiedFolder)) $fileInfo.LinkType | Should Be "SymbolicLink" - # Remove the link explicitly to avoid broken symlink issue - Remove-Item $FullyQualifiedLink -Force + # Remove the link explicitly to avoid broken symlink issue + Remove-Item $FullyQualifiedLink -Force } It "Should create a hard link of a file without error" { diff --git a/test/powershell/Modules/Microsoft.PowerShell.Security/ExecutionPolicy.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Security/ExecutionPolicy.Tests.ps1 index b5631218d..cdc5a239c 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Security/ExecutionPolicy.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Security/ExecutionPolicy.Tests.ps1 @@ -1,24 +1,24 @@ Describe "ExecutionPolicy" { Context "Check Get-ExecutionPolicy behavior" { - It "Should throw PlatformNotSupported when not on Windows" -Skip:$IsWindows { - { Get-ExecutionPolicy } | Should Throw "Operation is not supported on this platform." - } + It "Should unrestricted when not on Windows" -Skip:$IsWindows { + Get-ExecutionPolicy | Should Be Unrestricted + } - It "Should return Microsoft.Powershell.ExecutionPolicy PSObject on Windows" -Skip:($IsLinux -Or $IsOSX) { - (Get-ExecutionPolicy).GetType() | Should Be Microsoft.Powershell.ExecutionPolicy - } + It "Should return Microsoft.Powershell.ExecutionPolicy PSObject on Windows" -Skip:($IsLinux -Or $IsOSX) { + (Get-ExecutionPolicy).GetType() | Should Be Microsoft.Powershell.ExecutionPolicy + } } Context "Check Set-ExecutionPolicy behavior" { - It "Should throw PlatformNotSupported when not on Windows" -Skip:$IsWindows { - { Set-ExecutionPolicy Unrestricted } | Should Throw "Operation is not supported on this platform." - } + It "Should throw PlatformNotSupported when not on Windows" -Skip:$IsWindows { + { Set-ExecutionPolicy Unrestricted } | Should Throw "Operation is not supported on this platform." + } - It "Should succeed on Windows" -Skip:($IsLinux -Or $IsOSX) { - # We use the Process scope to avoid affecting the system - # Unrestricted is assumed "safe", otherwise these tests would not be running - { Set-ExecutionPolicy -Force -Scope Process -ExecutionPolicy Unrestricted } | Should Not Throw - } + It "Should succeed on Windows" -Skip:($IsLinux -Or $IsOSX) { + # We use the Process scope to avoid affecting the system + # Unrestricted is assumed "safe", otherwise these tests would not be running + { Set-ExecutionPolicy -Force -Scope Process -ExecutionPolicy Unrestricted } | Should Not Throw + } } }