summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/IO/Directory.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/IO/Directory.cs')
-rw-r--r--src/mscorlib/src/System/IO/Directory.cs642
1 files changed, 93 insertions, 549 deletions
diff --git a/src/mscorlib/src/System/IO/Directory.cs b/src/mscorlib/src/System/IO/Directory.cs
index be74538d2d..d6b68222cd 100644
--- a/src/mscorlib/src/System/IO/Directory.cs
+++ b/src/mscorlib/src/System/IO/Directory.cs
@@ -15,168 +15,70 @@
**
===========================================================*/
-using System;
-using System.Collections;
using System.Collections.Generic;
using System.Security;
using System.Security.Permissions;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
-using System.Text;
using System.Runtime.InteropServices;
-using System.Globalization;
-using System.Runtime.Versioning;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
-using System.Threading;
-#if FEATURE_MACL
-using System.Security.AccessControl;
-#endif
-
-namespace System.IO {
+namespace System.IO
+{
[ComVisible(true)]
public static class Directory {
public static DirectoryInfo GetParent(String path)
{
if (path==null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (path.Length==0)
- throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"), "path");
+ throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"), nameof(path));
Contract.EndContractBlock();
- String fullPath = Path.GetFullPathInternal(path);
-
- String s = Path.GetDirectoryName(fullPath);
+ string fullPath = Path.GetFullPath(path);
+
+ string s = Path.GetDirectoryName(fullPath);
if (s==null)
return null;
return new DirectoryInfo(s);
}
- [System.Security.SecuritySafeCritical]
public static DirectoryInfo CreateDirectory(String path) {
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"));
Contract.EndContractBlock();
- return InternalCreateDirectoryHelper(path, true);
+ return InternalCreateDirectoryHelper(path);
}
- [System.Security.SecurityCritical]
- internal static DirectoryInfo UnsafeCreateDirectory(String path)
- {
- if (path == null)
- throw new ArgumentNullException("path");
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"));
- Contract.EndContractBlock();
-
- return InternalCreateDirectoryHelper(path, false);
- }
-
- [System.Security.SecurityCritical]
- internal static DirectoryInfo InternalCreateDirectoryHelper(String path, bool checkHost)
+ internal static DirectoryInfo InternalCreateDirectoryHelper(String path)
{
Contract.Requires(path != null);
Contract.Requires(path.Length != 0);
- String fullPath = Path.GetFullPathInternal(path);
-
- // You need read access to the directory to be returned back and write access to all the directories
- // that you need to create. If we fail any security checks we will not create any directories at all.
- // We attempt to create directories only after all the security checks have passed. This is avoid doing
- // a demand at every level.
- String demandDir = GetDemandDir(fullPath, true);
-
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, path, demandDir);
- state.EnsureState(); // do the check on the AppDomainManager to make sure this is allowed
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, demandDir, false, false);
-#endif
-
- InternalCreateDirectory(fullPath, path, null, checkHost);
-
- return new DirectoryInfo(fullPath, false);
- }
-
-#if FEATURE_MACL
- [System.Security.SecuritySafeCritical] // auto-generated
- public static DirectoryInfo CreateDirectory(String path, DirectorySecurity directorySecurity) {
- if (path==null)
- throw new ArgumentNullException("path");
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"));
- Contract.EndContractBlock();
-
- String fullPath = Path.GetFullPathInternal(path);
+ String fullPath = Path.GetFullPath(path);
- // You need read access to the directory to be returned back and write access to all the directories
- // that you need to create. If we fail any security checks we will not create any directories at all.
- // We attempt to create directories only after all the security checks have passed. This is avoid doing
- // a demand at every level.
- String demandDir = GetDemandDir(fullPath, true);
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, demandDir, false, false );
+ InternalCreateDirectory(fullPath, path, null);
- InternalCreateDirectory(fullPath, path, directorySecurity);
-
return new DirectoryInfo(fullPath, false);
}
-#endif // FEATURE_MACL
- // Input to this method should already be fullpath. This method will ensure that we append
- // the trailing slash only when appropriate and when thisDirOnly is specified append a "."
- // at the end of the path to indicate that the demand is only for the fullpath and not
- // everything underneath it.
- internal static String GetDemandDir(string fullPath, bool thisDirOnly)
+ internal unsafe static void InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj)
{
- String demandPath;
-
- if (thisDirOnly) {
- if (fullPath.EndsWith( Path.DirectorySeparatorChar )
- || fullPath.EndsWith( Path.AltDirectorySeparatorChar ) )
- demandPath = fullPath + ".";
- else
- demandPath = fullPath + Path.DirectorySeparatorCharAsString + ".";
- }
- else {
- if (!(fullPath.EndsWith( Path.DirectorySeparatorChar )
- || fullPath.EndsWith( Path.AltDirectorySeparatorChar )) )
- demandPath = fullPath + Path.DirectorySeparatorCharAsString;
- else
- demandPath = fullPath;
- }
- return demandPath;
- }
-
- internal static void InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj)
- {
- InternalCreateDirectory(fullPath, path, dirSecurityObj, false);
- }
-
-
- [System.Security.SecuritySafeCritical]
- internal unsafe static void InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj, bool checkHost)
- {
-#if FEATURE_MACL
- DirectorySecurity dirSecurity = (DirectorySecurity)dirSecurityObj;
-#endif // FEATURE_MACL
-
int length = fullPath.Length;
// We need to trim the trailing slash or the code will try to create 2 directories of the same name.
- if (length >= 2 && Path.IsDirectorySeparator(fullPath[length - 1]))
+ if (length >= 2 && PathInternal.IsDirectorySeparator(fullPath[length - 1]))
length--;
- int lengthRoot = Path.GetRootLength(fullPath);
+ int lengthRoot = PathInternal.GetRootLength(fullPath);
// For UNC paths that are only // or ///
- if (length == 2 && Path.IsDirectorySeparator(fullPath[1]))
+ if (length == 2 && PathInternal.IsDirectorySeparator(fullPath[1]))
throw new IOException(Environment.GetResourceString("IO.IO_CannotCreateDirectory", path));
// We can save a bunch of work if the directory we want to create already exists. This also
@@ -215,56 +117,9 @@ namespace System.IO {
int count = stackDir.Count;
- if (stackDir.Count != 0
-#if FEATURE_CAS_POLICY
- // All demands in full trust domains are no-ops, so skip
- //
- // The full path went through validity checks by being passed through FileIOPermissions already.
- // As a sub string of the full path can't fail the checks if the full path passes.
- && !CodeAccessSecurityEngine.QuickCheckForAllDemands()
-#endif
- )
- {
- String[] securityList = new String[stackDir.Count];
- stackDir.CopyTo(securityList, 0);
- for (int j = 0 ; j < securityList.Length; j++)
- securityList[j] += "\\."; // leaf will never have a slash at the end
-
- // Security check for all directories not present only.
-#if FEATURE_MACL
- AccessControlActions control = (dirSecurity == null) ? AccessControlActions.None : AccessControlActions.Change;
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, control, securityList, false, false);
-#else
-#if FEATURE_CORECLR
- if (checkHost)
- {
- foreach (String demandPath in securityList)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Write, String.Empty, demandPath);
- state.EnsureState();
- }
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, securityList, false, false);
-#endif
-#endif //FEATURE_MACL
- }
-
// If we were passed a DirectorySecurity, convert it to a security
// descriptor and set it in he call to CreateDirectory.
Win32Native.SECURITY_ATTRIBUTES secAttrs = null;
-#if FEATURE_MACL
- if (dirSecurity != null) {
- secAttrs = new Win32Native.SECURITY_ATTRIBUTES();
- secAttrs.nLength = (int)Marshal.SizeOf(secAttrs);
-
- // For ACL's, get the security descriptor from the FileSecurity.
- byte[] sd = dirSecurity.GetSecurityDescriptorBinaryForm();
- byte * bytesOnStack = stackalloc byte[sd.Length];
- Buffer.Memcpy(bytesOnStack, 0, sd, 0, sd.Length);
- secAttrs.pSecurityDescriptor = bytesOnStack;
- }
-#endif
bool r = true;
int firstError = 0;
@@ -290,22 +145,10 @@ namespace System.IO {
firstError = currentError;
else {
// If there's a file in this directory's place, or if we have ERROR_ACCESS_DENIED when checking if the directory already exists throw.
- if (File.InternalExists(name) || (!InternalExists(name, out currentError) && currentError == Win32Native.ERROR_ACCESS_DENIED)) {
+ if (File.InternalExists(name) || (!InternalExists(name, out currentError) && currentError == Win32Native.ERROR_ACCESS_DENIED))
+ {
firstError = currentError;
- // Give the user a nice error message, but don't leak path information.
- try {
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, GetDemandDir(name, true));
- state.EnsureState();
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, GetDemandDir(name, true));
-#endif // FEATURE_CORECLR
- errorString = name;
- }
- catch(SecurityException) {}
+ errorString = name;
}
}
}
@@ -335,20 +178,12 @@ namespace System.IO {
// Your application must have Read permission to the directory's
// contents.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public static bool Exists(String path)
{
- return InternalExistsHelper(path, true);
- }
-
- [System.Security.SecurityCritical]
- internal static bool UnsafeExists(String path)
- {
- return InternalExistsHelper(path, false);
+ return InternalExistsHelper(path);
}
- [System.Security.SecurityCritical]
- internal static bool InternalExistsHelper(String path, bool checkHost) {
+ internal static bool InternalExistsHelper(String path) {
try
{
if (path == null)
@@ -356,23 +191,7 @@ namespace System.IO {
if (path.Length == 0)
return false;
- // Get fully qualified file name ending in \* for security check
-
- String fullPath = Path.GetFullPathInternal(path);
- String demandPath = GetDemandDir(fullPath, true);
-
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, path, demandPath);
- state.EnsureState();
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, demandPath, false, false);
-#endif
-
-
- return InternalExists(fullPath);
+ return InternalExists(Path.GetFullPath(path));
}
catch (ArgumentException) { }
catch (NotSupportedException) { } // Security can throw this on ":"
@@ -380,14 +199,13 @@ namespace System.IO {
catch (IOException) { }
catch (UnauthorizedAccessException)
{
- Contract.Assert(false, "Ignore this assert and send a repro to Microsoft. This assert was tracking purposes only.");
+ Debug.Assert(false, "Ignore this assert and send a repro to Microsoft. This assert was tracking purposes only.");
}
return false;
}
// Determine whether path describes an existing directory
// on disk, avoiding security checks.
- [System.Security.SecurityCritical] // auto-generated
internal static bool InternalExists(String path) {
int lastError = Win32Native.ERROR_SUCCESS;
return InternalExists(path, out lastError);
@@ -395,7 +213,6 @@ namespace System.IO {
// Determine whether path describes an existing directory
// on disk, avoiding security checks.
- [System.Security.SecurityCritical] // auto-generated
internal static bool InternalExists(String path, out int lastError) {
Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
lastError = File.FillAttributeInfo(path, ref data, false, true);
@@ -404,25 +221,6 @@ namespace System.IO {
&& ((data.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0);
}
- public static void SetCreationTime(String path,DateTime creationTime)
- {
- SetCreationTimeUtc(path, creationTime.ToUniversalTime());
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public unsafe static void SetCreationTimeUtc(String path,DateTime creationTimeUtc)
- {
- using (SafeFileHandle handle = Directory.OpenHandle(path)) {
- Win32Native.FILE_TIME fileTime = new Win32Native.FILE_TIME(creationTimeUtc.ToFileTimeUtc());
- bool r = Win32Native.SetFileTime(handle, &fileTime, null, null);
- if (!r)
- {
- int errorCode = Marshal.GetLastWin32Error();
- __Error.WinIOError(errorCode, path);
- }
- }
- }
-
public static DateTime GetCreationTime(String path)
{
return File.GetCreationTime(path);
@@ -433,25 +231,6 @@ namespace System.IO {
return File.GetCreationTimeUtc(path);
}
- public static void SetLastWriteTime(String path,DateTime lastWriteTime)
- {
- SetLastWriteTimeUtc(path, lastWriteTime.ToUniversalTime());
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public unsafe static void SetLastWriteTimeUtc(String path,DateTime lastWriteTimeUtc)
- {
- using (SafeFileHandle handle = Directory.OpenHandle(path)) {
- Win32Native.FILE_TIME fileTime = new Win32Native.FILE_TIME(lastWriteTimeUtc.ToFileTimeUtc());
- bool r = Win32Native.SetFileTime(handle, null, null, &fileTime);
- if (!r)
- {
- int errorCode = Marshal.GetLastWin32Error();
- __Error.WinIOError(errorCode, path);
- }
- }
- }
-
public static DateTime GetLastWriteTime(String path)
{
return File.GetLastWriteTime(path);
@@ -462,25 +241,6 @@ namespace System.IO {
return File.GetLastWriteTimeUtc(path);
}
- public static void SetLastAccessTime(String path,DateTime lastAccessTime)
- {
- SetLastAccessTimeUtc(path, lastAccessTime.ToUniversalTime());
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public unsafe static void SetLastAccessTimeUtc(String path,DateTime lastAccessTimeUtc)
- {
- using (SafeFileHandle handle = Directory.OpenHandle(path)) {
- Win32Native.FILE_TIME fileTime = new Win32Native.FILE_TIME(lastAccessTimeUtc.ToFileTimeUtc());
- bool r = Win32Native.SetFileTime(handle, null, &fileTime, null);
- if (!r)
- {
- int errorCode = Marshal.GetLastWin32Error();
- __Error.WinIOError(errorCode, path);
- }
- }
- }
-
public static DateTime GetLastAccessTime(String path)
{
return File.GetLastAccessTime(path);
@@ -489,36 +249,13 @@ namespace System.IO {
public static DateTime GetLastAccessTimeUtc(String path)
{
return File.GetLastAccessTimeUtc(path);
- }
-
-#if FEATURE_MACL
- public static DirectorySecurity GetAccessControl(String path)
- {
- return new DirectorySecurity(path, AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group);
}
- public static DirectorySecurity GetAccessControl(String path, AccessControlSections includeSections)
- {
- return new DirectorySecurity(path, includeSections);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public static void SetAccessControl(String path, DirectorySecurity directorySecurity)
- {
- if (directorySecurity == null)
- throw new ArgumentNullException("directorySecurity");
- Contract.EndContractBlock();
-
- String fullPath = Path.GetFullPathInternal(path);
- directorySecurity.Persist(fullPath);
- }
-#endif
-
// Returns an array of filenames in the DirectoryInfo specified by path
public static String[] GetFiles(String path)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
@@ -530,9 +267,9 @@ namespace System.IO {
public static String[] GetFiles(String path, String searchPattern)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
@@ -544,11 +281,11 @@ namespace System.IO {
public static String[] GetFiles(String path, String searchPattern, SearchOption searchOption)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException("searchOption", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
@@ -566,7 +303,6 @@ namespace System.IO {
return InternalGetFileDirectoryNames(path, path, searchPattern, true, false, searchOption, true);
}
- [System.Security.SecurityCritical]
internal static String[] UnsafeGetFiles(String path, String searchPattern, SearchOption searchOption)
{
Contract.Requires(path != null);
@@ -580,7 +316,7 @@ namespace System.IO {
public static String[] GetDirectories(String path)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
@@ -592,9 +328,9 @@ namespace System.IO {
public static String[] GetDirectories(String path, String searchPattern)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
@@ -606,11 +342,11 @@ namespace System.IO {
public static String[] GetDirectories(String path, String searchPattern, SearchOption searchOption)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException("searchOption", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
@@ -629,7 +365,6 @@ namespace System.IO {
return InternalGetFileDirectoryNames(path, path, searchPattern, false, true, searchOption, true);
}
- [System.Security.SecurityCritical]
internal static String[] UnsafeGetDirectories(String path, String searchPattern, SearchOption searchOption)
{
Contract.Requires(path != null);
@@ -644,7 +379,7 @@ namespace System.IO {
public static String[] GetFileSystemEntries(String path)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
@@ -656,9 +391,9 @@ namespace System.IO {
public static String[] GetFileSystemEntries(String path, String searchPattern)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
@@ -670,11 +405,11 @@ namespace System.IO {
public static String[] GetFileSystemEntries(String path, String searchPattern, SearchOption searchOption)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException("searchOption", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
@@ -690,7 +425,6 @@ namespace System.IO {
return InternalGetFileDirectoryNames(path, path, searchPattern, true, true, searchOption, true);
}
-
// Private class that holds search data that is passed around
// in the heap based stack recursion
internal sealed class SearchData
@@ -734,7 +468,7 @@ namespace System.IO {
public static IEnumerable<String> EnumerateDirectories(String path)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.EndContractBlock();
return InternalEnumerateDirectories(path, "*", SearchOption.TopDirectoryOnly);
@@ -743,9 +477,9 @@ namespace System.IO {
public static IEnumerable<String> EnumerateDirectories(String path, String searchPattern)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
Contract.EndContractBlock();
return InternalEnumerateDirectories(path, searchPattern, SearchOption.TopDirectoryOnly);
@@ -754,11 +488,11 @@ namespace System.IO {
public static IEnumerable<String> EnumerateDirectories(String path, String searchPattern, SearchOption searchOption)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException("searchOption", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
Contract.EndContractBlock();
return InternalEnumerateDirectories(path, searchPattern, searchOption);
@@ -776,7 +510,7 @@ namespace System.IO {
public static IEnumerable<String> EnumerateFiles(String path)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.Ensures(Contract.Result<IEnumerable<String>>() != null);
Contract.EndContractBlock();
@@ -786,9 +520,9 @@ namespace System.IO {
public static IEnumerable<String> EnumerateFiles(String path, String searchPattern)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
Contract.Ensures(Contract.Result<IEnumerable<String>>() != null);
Contract.EndContractBlock();
@@ -798,11 +532,11 @@ namespace System.IO {
public static IEnumerable<String> EnumerateFiles(String path, String searchPattern, SearchOption searchOption)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException("searchOption", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
Contract.Ensures(Contract.Result<IEnumerable<String>>() != null);
Contract.EndContractBlock();
@@ -822,7 +556,7 @@ namespace System.IO {
public static IEnumerable<String> EnumerateFileSystemEntries(String path)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.Ensures(Contract.Result<IEnumerable<String>>() != null);
Contract.EndContractBlock();
@@ -832,9 +566,9 @@ namespace System.IO {
public static IEnumerable<String> EnumerateFileSystemEntries(String path, String searchPattern)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
Contract.Ensures(Contract.Result<IEnumerable<String>>() != null);
Contract.EndContractBlock();
@@ -844,11 +578,11 @@ namespace System.IO {
public static IEnumerable<String> EnumerateFileSystemEntries(String path, String searchPattern, SearchOption searchOption)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException("searchOption", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
Contract.Ensures(Contract.Result<IEnumerable<String>>() != null);
Contract.EndContractBlock();
@@ -882,7 +616,6 @@ namespace System.IO {
//
// Your application must have System Info permission.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public static String[] GetLogicalDrives()
{
Contract.Ensures(Contract.Result<String[]>() != null);
@@ -914,29 +647,20 @@ namespace System.IO {
return result;
}
- [System.Security.SecuritySafeCritical]
public static String GetDirectoryRoot(String path) {
if (path==null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.EndContractBlock();
-
- String fullPath = Path.GetFullPathInternal(path);
- String root = fullPath.Substring(0, Path.GetRootLength(fullPath));
- String demandPath = GetDemandDir(root, true);
-
-#if FEATURE_CORECLR
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, path, demandPath);
- state.EnsureState();
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, demandPath, false, false);
-#endif
-
+
+ string fullPath = Path.GetFullPath(path);
+ string root = fullPath.Substring(0, PathInternal.GetRootLength(fullPath));
+
return root;
}
internal static String InternalGetDirectoryRoot(String path) {
if (path == null) return null;
- return path.Substring(0, Path.GetRootLength(path));
+ return path.Substring(0, PathInternal.GetRootLength(path));
}
/*===============================CurrentDirectory===============================
@@ -946,77 +670,10 @@ namespace System.IO {
**Arguments: The current DirectoryInfo to which to switch to the setter.
**Exceptions:
==============================================================================*/
- [System.Security.SecuritySafeCritical]
public static String GetCurrentDirectory()
{
- return InternalGetCurrentDirectory(true);
- }
-
- [System.Security.SecurityCritical]
- internal static String UnsafeGetCurrentDirectory()
- {
- return InternalGetCurrentDirectory(false);
- }
-
- [System.Security.SecuritySafeCritical]
- private static string InternalGetCurrentDirectory(bool checkHost)
- {
- string currentDirectory = (
-#if FEATURE_PATHCOMPAT
- AppContextSwitches.UseLegacyPathHandling ? LegacyGetCurrentDirectory() :
-#endif
- NewGetCurrentDirectory());
-
- string demandPath = GetDemandDir(currentDirectory, true);
-
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandPath);
- state.EnsureState();
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, demandPath, false, false);
-#endif
- return currentDirectory;
- }
-
-#if FEATURE_PATHCOMPAT
- [System.Security.SecurityCritical]
- private static String LegacyGetCurrentDirectory()
- {
- StringBuilder sb = StringBuilderCache.Acquire(Path.MaxPath + 1);
- if (Win32Native.GetCurrentDirectory(sb.Capacity, sb) == 0)
- __Error.WinIOError();
- String currentDirectory = sb.ToString();
- // Note that if we have somehow put our command prompt into short
- // file name mode (ie, by running edlin or a DOS grep, etc), then
- // this will return a short file name.
- if (currentDirectory.IndexOf('~') >= 0) {
- int r = Win32Native.GetLongPathName(currentDirectory, sb, sb.Capacity);
- if (r == 0 || r >= Path.MaxPath) {
- int errorCode = Marshal.GetLastWin32Error();
- if (r >= Path.MaxPath)
- errorCode = Win32Native.ERROR_FILENAME_EXCED_RANGE;
- if (errorCode != Win32Native.ERROR_FILE_NOT_FOUND &&
- errorCode != Win32Native.ERROR_PATH_NOT_FOUND &&
- errorCode != Win32Native.ERROR_INVALID_FUNCTION && // by design - enough said.
- errorCode != Win32Native.ERROR_ACCESS_DENIED)
- __Error.WinIOError(errorCode, String.Empty);
- }
- currentDirectory = sb.ToString();
- }
- StringBuilderCache.Release(sb);
- String demandPath = GetDemandDir(currentDirectory, true);
-
- return currentDirectory;
- }
-#endif // FEATURE_PATHCOMPAT
-
- [System.Security.SecurityCritical]
- private static string NewGetCurrentDirectory()
- {
- using (StringBuffer buffer = new StringBuffer(PathInternal.MaxShortPath))
+ // Start with a buffer the size of MAX_PATH
+ using (StringBuffer buffer = new StringBuffer(260))
{
uint result = 0;
while ((result = Win32Native.GetCurrentDirectoryW(buffer.CharCapacity, buffer.GetHandle())) > buffer.CharCapacity)
@@ -1033,35 +690,23 @@ namespace System.IO {
#if !PLATFORM_UNIX
if (buffer.Contains('~'))
- return LongPathHelper.GetLongPathName(buffer);
+ return Path.GetFullPath(buffer.ToString());
#endif
return buffer.ToString();
}
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
public static void SetCurrentDirectory(String path)
{
if (path==null)
throw new ArgumentNullException("value");
if (path.Length==0)
throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"));
- Contract.EndContractBlock();
if (path.Length >= Path.MaxPath)
throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
-
- // This will have some large effects on the rest of the runtime
- // and other appdomains in this process. Demand unmanaged code.
-#pragma warning disable 618
- new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
-#pragma warning restore 618
- String fulldestDirName = Path.GetFullPathInternal(path);
+ String fulldestDirName = Path.GetFullPath(path);
if (!Win32Native.SetCurrentDirectory(fulldestDirName)) {
// If path doesn't exist, this sets last error to 2 (File
@@ -1074,52 +719,19 @@ namespace System.IO {
}
}
- [System.Security.SecuritySafeCritical]
- public static void Move(String sourceDirName,String destDirName) {
- InternalMove(sourceDirName, destDirName, true);
- }
-
- [System.Security.SecurityCritical]
- internal static void UnsafeMove(String sourceDirName,String destDirName) {
- InternalMove(sourceDirName, destDirName, false);
- }
-
- [System.Security.SecurityCritical]
- private static void InternalMove(String sourceDirName,String destDirName,bool checkHost) {
+ public static void Move(String sourceDirName,String destDirName)
+ {
if (sourceDirName==null)
- throw new ArgumentNullException("sourceDirName");
+ throw new ArgumentNullException(nameof(sourceDirName));
if (sourceDirName.Length==0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "sourceDirName");
-
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(sourceDirName));
if (destDirName==null)
- throw new ArgumentNullException("destDirName");
+ throw new ArgumentNullException(nameof(destDirName));
if (destDirName.Length==0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "destDirName");
- Contract.EndContractBlock();
-
- String fullsourceDirName = Path.GetFullPathInternal(sourceDirName);
- String sourcePath = GetDemandDir(fullsourceDirName, false);
-
- if (PathInternal.IsDirectoryTooLong(sourcePath))
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
-
- String fulldestDirName = Path.GetFullPathInternal(destDirName);
- String destPath = GetDemandDir(fulldestDirName, false);
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destDirName));
- if (PathInternal.IsDirectoryTooLong(destPath))
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
-
-#if FEATURE_CORECLR
- if (checkHost) {
- FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Write | FileSecurityStateAccess.Read, sourceDirName, sourcePath);
- FileSecurityState destState = new FileSecurityState(FileSecurityStateAccess.Write, destDirName, destPath);
- sourceState.EnsureState();
- destState.EnsureState();
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, sourcePath, false, false);
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, destPath, false, false);
-#endif
+ String sourcePath = Path.GetFullPath(sourceDirName);
+ String destPath = Path.GetFullPath(destDirName);
if (String.Compare(sourcePath, destPath, StringComparison.OrdinalIgnoreCase) == 0)
throw new IOException(Environment.GetResourceString("IO.IO_SourceDestMustBeDifferent"));
@@ -1135,7 +747,7 @@ namespace System.IO {
if (hr == Win32Native.ERROR_FILE_NOT_FOUND) // Source dir not found
{
hr = Win32Native.ERROR_PATH_NOT_FOUND;
- __Error.WinIOError(hr, fullsourceDirName);
+ __Error.WinIOError(hr, sourcePath);
}
// This check was originally put in for Win9x (unfortunately without special casing it to be for Win9x only). We can't change the NT codepath now for backcomp reasons.
if (hr == Win32Native.ERROR_ACCESS_DENIED) // WinNT throws IOException. This check is for Win9x. We can't change it for backcomp.
@@ -1144,49 +756,22 @@ namespace System.IO {
}
}
- [System.Security.SecuritySafeCritical]
public static void Delete(String path)
{
- String fullPath = Path.GetFullPathInternal(path);
- Delete(fullPath, path, false, true);
+ String fullPath = Path.GetFullPath(path);
+ Delete(fullPath, path, false);
}
- [System.Security.SecuritySafeCritical]
public static void Delete(String path, bool recursive)
{
- String fullPath = Path.GetFullPathInternal(path);
- Delete(fullPath, path, recursive, true);
+ String fullPath = Path.GetFullPath(path);
+ Delete(fullPath, path, recursive);
}
- [System.Security.SecurityCritical]
- internal static void UnsafeDelete(String path, bool recursive)
- {
- String fullPath = Path.GetFullPathInternal(path);
- Delete(fullPath, path, recursive, false);
- }
-
- // Called from DirectoryInfo as well. FullPath is fully qualified,
+ // Called from DirectoryInfo as well. FullPath is fully qualified,
// while the user path is used for feedback in exceptions.
- [System.Security.SecurityCritical] // auto-generated
- internal static void Delete(String fullPath, String userPath, bool recursive, bool checkHost)
+ internal static void Delete(String fullPath, String userPath, bool recursive)
{
- String demandPath;
-
- // If not recursive, do permission check only on this directory
- // else check for the whole directory structure rooted below
- demandPath = GetDemandDir(fullPath, !recursive);
-
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Write, userPath, demandPath);
- state.EnsureState();
- }
-#else
- // Make sure we have write permission to this directory
- new FileIOPermission(FileIOPermissionAccess.Write, new String[] { demandPath }, false, false ).Demand();
-#endif
-
// Do not recursively delete through reparse points. Perhaps in a
// future version we will add a new flag to control this behavior,
// but for now we're much safer if we err on the conservative side.
@@ -1206,10 +791,7 @@ namespace System.IO {
DeleteHelper(fullPath, userPath, recursive, true);
}
- // Note that fullPath is fully qualified, while userPath may be
- // relative. Use userPath for all exception messages to avoid leaking
- // fully qualified path information.
- [System.Security.SecurityCritical] // auto-generated
+ // Note that fullPath is fully qualified, while userPath may be relative.
private static void DeleteHelper(String fullPath, String userPath, bool recursive, bool throwOnTopLevelDirectoryNotFound)
{
bool r;
@@ -1229,12 +811,12 @@ namespace System.IO {
Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA();
// Open a Find handle
- using (SafeFindHandle hnd = Win32Native.FindFirstFile(fullPath+Path.DirectorySeparatorCharAsString+"*", data)) {
+ using (SafeFindHandle hnd = Win32Native.FindFirstFile(fullPath + Path.DirectorySeparatorChar + "*", data)) {
if (hnd.IsInvalid) {
hr = Marshal.GetLastWin32Error();
__Error.WinIOError(hr, fullPath);
}
-
+
do {
bool isDir = (0!=(data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY));
if (isDir) {
@@ -1248,8 +830,8 @@ namespace System.IO {
// itself.
bool shouldRecurse = (0 == (data.dwFileAttributes & (int) FileAttributes.ReparsePoint));
if (shouldRecurse) {
- String newFullPath = Path.InternalCombine(fullPath, data.cFileName);
- String newUserPath = Path.InternalCombine(userPath, data.cFileName);
+ String newFullPath = Path.Combine(fullPath, data.cFileName);
+ String newUserPath = Path.Combine(userPath, data.cFileName);
try {
DeleteHelper(newFullPath, newUserPath, recursive, false);
}
@@ -1264,7 +846,7 @@ namespace System.IO {
// unmount it.
if (data.dwReserved0 == Win32Native.IO_REPARSE_TAG_MOUNT_POINT) {
// Use full path plus a trailing '\'
- String mountPoint = Path.InternalCombine(fullPath, data.cFileName + Path.DirectorySeparatorChar);
+ String mountPoint = Path.Combine(fullPath, data.cFileName + Path.DirectorySeparatorChar);
r = Win32Native.DeleteVolumeMountPoint(mountPoint);
if (!r) {
hr = Marshal.GetLastWin32Error();
@@ -1283,7 +865,7 @@ namespace System.IO {
// RemoveDirectory on a symbolic link will
// remove the link itself.
- String reparsePoint = Path.InternalCombine(fullPath, data.cFileName);
+ String reparsePoint = Path.Combine(fullPath, data.cFileName);
r = Win32Native.RemoveDirectory(reparsePoint);
if (!r) {
hr = Marshal.GetLastWin32Error();
@@ -1301,7 +883,7 @@ namespace System.IO {
}
}
else {
- String fileName = Path.InternalCombine(fullPath, data.cFileName);
+ String fileName = Path.Combine(fullPath, data.cFileName);
r = Win32Native.DeleteFile(fileName);
if (!r) {
hr = Marshal.GetLastWin32Error();
@@ -1346,44 +928,6 @@ namespace System.IO {
__Error.WinIOError(hr, fullPath);
}
}
-
- // WinNT only. Win9x this code will not work.
- [System.Security.SecurityCritical] // auto-generated
- private static SafeFileHandle OpenHandle(String path)
- {
- String fullPath = Path.GetFullPathInternal(path);
- String root = Path.GetPathRoot(fullPath);
- if (root == fullPath && root[1] == Path.VolumeSeparatorChar)
- throw new ArgumentException(Environment.GetResourceString("Arg_PathIsVolume"));
-
-#if !FEATURE_CORECLR
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, GetDemandDir(fullPath, true), false, false);
-#endif
-
- SafeFileHandle handle = Win32Native.SafeCreateFile (
- fullPath,
- GENERIC_WRITE,
- (FileShare) (FILE_SHARE_WRITE|FILE_SHARE_DELETE),
- null,
- FileMode.Open,
- FILE_FLAG_BACKUP_SEMANTICS,
- IntPtr.Zero
- );
-
- if (handle.IsInvalid) {
- int hr = Marshal.GetLastWin32Error();
- __Error.WinIOError(hr, fullPath);
- }
- return handle;
- }
-
- private const int FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
- private const int GENERIC_WRITE = unchecked((int)0x40000000);
- private const int FILE_SHARE_WRITE = 0x00000002;
- private const int FILE_SHARE_DELETE = 0x00000004;
- private const int OPEN_EXISTING = 0x00000003;
- private const int FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
}
-
}