diff --git a/src/mscorlib/corefx/System/IO/FileStream.cs b/src/mscorlib/corefx/System/IO/FileStream.cs index fbee4eda9f1b..398f5a61626b 100644 --- a/src/mscorlib/corefx/System/IO/FileStream.cs +++ b/src/mscorlib/corefx/System/IO/FileStream.cs @@ -140,11 +140,11 @@ public FileStream(string path, FileMode mode, FileAccess access, FileShare share { } internal FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, string msgPath, bool bFromProxy) - : this(path, mode, access, share, bufferSize, options, msgPath, bFromProxy, useLongPath: false, checkHost: false) + : this(path, mode, access, share, bufferSize, options, msgPath, bFromProxy, useLongPath: false) { } - internal FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, string msgPath, bool bFromProxy, bool useLongPath, bool checkHost) + internal FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, string msgPath, bool bFromProxy, bool useLongPath) : this(path, mode, access, share, bufferSize, options) { // msgPath is the path that is handed back to untrusted code, CoreCLR is always full trust diff --git a/src/mscorlib/mscorlib.shared.sources.props b/src/mscorlib/mscorlib.shared.sources.props index 4761b8d175c8..3c4b1bce4afc 100644 --- a/src/mscorlib/mscorlib.shared.sources.props +++ b/src/mscorlib/mscorlib.shared.sources.props @@ -806,7 +806,6 @@ - @@ -836,8 +835,6 @@ - - diff --git a/src/mscorlib/src/System/IO/Directory.cs b/src/mscorlib/src/System/IO/Directory.cs index 5eb3fc842ade..d6b68222cd08 100644 --- a/src/mscorlib/src/System/IO/Directory.cs +++ b/src/mscorlib/src/System/IO/Directory.cs @@ -52,76 +52,22 @@ public static DirectoryInfo CreateDirectory(String path) { throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty")); Contract.EndContractBlock(); - return InternalCreateDirectoryHelper(path, true); + return InternalCreateDirectoryHelper(path); } - internal static DirectoryInfo UnsafeCreateDirectory(String path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty")); - Contract.EndContractBlock(); - - return InternalCreateDirectoryHelper(path, false); - } - - 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.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); - - if (checkHost) - { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, path, demandDir); - state.EnsureState(); // do the check on the AppDomainManager to make sure this is allowed - } - - InternalCreateDirectory(fullPath, path, null, checkHost); + InternalCreateDirectory(fullPath, path, null); return new DirectoryInfo(fullPath, false); } - // 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) - { - String demandPath; - - if (thisDirOnly) { - if (fullPath.EndsWith( Path.DirectorySeparatorChar ) - || fullPath.EndsWith( Path.AltDirectorySeparatorChar ) ) - demandPath = fullPath + "."; - else - demandPath = fullPath + Path.DirectorySeparatorChar + "."; - } - else { - if (!(fullPath.EndsWith( Path.DirectorySeparatorChar ) - || fullPath.EndsWith( Path.AltDirectorySeparatorChar )) ) - demandPath = fullPath + Path.DirectorySeparatorChar; - else - demandPath = fullPath; - } - return demandPath; - } - - internal static void InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj) - { - InternalCreateDirectory(fullPath, path, dirSecurityObj, false); - } - - - internal unsafe static void InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj, bool checkHost) + internal unsafe static void InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj) { int length = fullPath.Length; @@ -171,24 +117,6 @@ internal unsafe static void InternalCreateDirectory(String fullPath, String path int count = stackDir.Count; - if (stackDir.Count != 0) - { - 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 (checkHost) - { - foreach (String demandPath in securityList) - { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Write, String.Empty, demandPath); - state.EnsureState(); - } - } - } - // 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; @@ -217,18 +145,10 @@ internal unsafe static void InternalCreateDirectory(String fullPath, String path 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 (checkHost) - { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, GetDemandDir(name, true)); - state.EnsureState(); - } - errorString = name; - } - catch(SecurityException) {} + errorString = name; } } } @@ -260,15 +180,10 @@ internal unsafe static void InternalCreateDirectory(String fullPath, String path // public static bool Exists(String path) { - return InternalExistsHelper(path, true); + return InternalExistsHelper(path); } - internal static bool UnsafeExists(String path) - { - return InternalExistsHelper(path, false); - } - - internal static bool InternalExistsHelper(String path, bool checkHost) { + internal static bool InternalExistsHelper(String path) { try { if (path == null) @@ -276,18 +191,7 @@ internal static bool InternalExistsHelper(String path, bool checkHost) { if (path.Length == 0) return false; - // Get fully qualified file name ending in \* for security check - - String fullPath = Path.GetFullPath(path); - String demandPath = GetDemandDir(fullPath, true); - - if (checkHost) - { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, path, demandPath); - state.EnsureState(); - } - - return InternalExists(fullPath); + return InternalExists(Path.GetFullPath(path)); } catch (ArgumentException) { } catch (NotSupportedException) { } // Security can throw this on ":" @@ -521,7 +425,6 @@ private static String[] InternalGetFileSystemEntries(String path, String searchP 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 @@ -751,10 +654,6 @@ public static String GetDirectoryRoot(String path) { string fullPath = Path.GetFullPath(path); string root = fullPath.Substring(0, PathInternal.GetRootLength(fullPath)); - string demandPath = GetDemandDir(root, true); - - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, path, demandPath); - state.EnsureState(); return root; } @@ -772,29 +671,6 @@ internal static String InternalGetDirectoryRoot(String path) { **Exceptions: ==============================================================================*/ public static String GetCurrentDirectory() - { - return InternalGetCurrentDirectory(true); - } - - internal static String UnsafeGetCurrentDirectory() - { - return InternalGetCurrentDirectory(false); - } - - private static string InternalGetCurrentDirectory(bool checkHost) - { - string currentDirectory = NewGetCurrentDirectory(); - string demandPath = GetDemandDir(currentDirectory, true); - - if (checkHost) - { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandPath); - state.EnsureState(); - } - return currentDirectory; - } - - private static string NewGetCurrentDirectory() { // Start with a buffer the size of MAX_PATH using (StringBuffer buffer = new StringBuffer(260)) @@ -827,15 +703,8 @@ public static void SetCurrentDirectory(String path) 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.GetFullPath(path); @@ -850,44 +719,19 @@ public static void SetCurrentDirectory(String path) } } - public static void Move(String sourceDirName,String destDirName) { - InternalMove(sourceDirName, destDirName, true); - } - - internal static void UnsafeMove(String sourceDirName,String destDirName) { - InternalMove(sourceDirName, destDirName, false); - } - - private static void InternalMove(String sourceDirName,String destDirName,bool checkHost) { + public static void Move(String sourceDirName,String destDirName) + { if (sourceDirName==null) throw new ArgumentNullException(nameof(sourceDirName)); if (sourceDirName.Length==0) throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(sourceDirName)); - if (destDirName==null) throw new ArgumentNullException(nameof(destDirName)); if (destDirName.Length==0) throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destDirName)); - Contract.EndContractBlock(); - - String fullsourceDirName = Path.GetFullPath(sourceDirName); - String sourcePath = GetDemandDir(fullsourceDirName, false); - - if (PathInternal.IsDirectoryTooLong(sourcePath)) - throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong")); - - String fulldestDirName = Path.GetFullPath(destDirName); - String destPath = GetDemandDir(fulldestDirName, false); - if (PathInternal.IsDirectoryTooLong(destPath)) - throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong")); - - if (checkHost) { - FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Write | FileSecurityStateAccess.Read, sourceDirName, sourcePath); - FileSecurityState destState = new FileSecurityState(FileSecurityStateAccess.Write, destDirName, destPath); - sourceState.EnsureState(); - destState.EnsureState(); - } + 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")); @@ -903,7 +747,7 @@ private static void InternalMove(String sourceDirName,String destDirName,bool ch 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. @@ -915,37 +759,19 @@ private static void InternalMove(String sourceDirName,String destDirName,bool ch public static void Delete(String path) { String fullPath = Path.GetFullPath(path); - Delete(fullPath, path, false, true); + Delete(fullPath, path, false); } public static void Delete(String path, bool recursive) { String fullPath = Path.GetFullPath(path); - Delete(fullPath, path, recursive, true); + Delete(fullPath, path, recursive); } - internal static void UnsafeDelete(String path, bool recursive) - { - String fullPath = Path.GetFullPath(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. - 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 (checkHost) - { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Write, userPath, demandPath); - state.EnsureState(); - } - // 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. @@ -965,9 +791,7 @@ internal static void Delete(String fullPath, String userPath, bool recursive, bo 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. + // 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; @@ -1104,13 +928,6 @@ private static void DeleteHelper(String fullPath, String userPath, bool recursiv __Error.WinIOError(hr, fullPath); } } - - 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; } } diff --git a/src/mscorlib/src/System/IO/DirectoryInfo.cs b/src/mscorlib/src/System/IO/DirectoryInfo.cs index 22adc4f0f2c1..c4c350d2453f 100644 --- a/src/mscorlib/src/System/IO/DirectoryInfo.cs +++ b/src/mscorlib/src/System/IO/DirectoryInfo.cs @@ -15,15 +15,9 @@ ** ===========================================================*/ -using System; -using System.Collections; using System.Collections.Generic; -using System.Security; -using System.Security.Permissions; using Microsoft.Win32; -using System.Text; using System.Runtime.InteropServices; -using System.Globalization; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Diagnostics; @@ -35,36 +29,19 @@ namespace System.IO [ComVisible(true)] public sealed class DirectoryInfo : FileSystemInfo { - private String[] demandDir; - // Migrating InheritanceDemands requires this default ctor, so we can annotate it. -#if FEATURE_CORESYSTEM -#else -#endif //FEATURE_CORESYSTEM private DirectoryInfo(){} - - public static DirectoryInfo UnsafeCreateDirectoryInfo(String path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - Contract.EndContractBlock(); - - DirectoryInfo di = new DirectoryInfo(); - di.Init(path, false); - return di; - } - public DirectoryInfo(String path) { if (path==null) throw new ArgumentNullException(nameof(path)); Contract.EndContractBlock(); - Init(path, true); + Init(path); } - private void Init(String path, bool checkHost) + private void Init(String path) { // Special case ":" to point to "" instead if ((path.Length == 2) && (path[1] == ':')) @@ -76,23 +53,10 @@ private void Init(String path, bool checkHost) OriginalPath = path; } - // Must fully qualify the path for the security check - String fullPath = Path.GetFullPath(path); - - demandDir = new String[] {Directory.GetDemandDir(fullPath, true)}; - - if (checkHost) - { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, OriginalPath, fullPath); - state.EnsureState(); - } - - FullPath = fullPath; + FullPath = Path.GetFullPath(path); ; DisplayPath = GetDisplayName(OriginalPath, FullPath); } -#if FEATURE_CORESYSTEM -#endif //FEATURE_CORESYSTEM internal DirectoryInfo(String fullPath, bool junk) { Debug.Assert(PathInternal.GetRootLength(fullPath) > 0, "fullPath must be fully qualified!"); @@ -101,7 +65,6 @@ internal DirectoryInfo(String fullPath, bool junk) FullPath = fullPath; DisplayPath = GetDisplayName(OriginalPath, FullPath); - demandDir = new String[] {Directory.GetDemandDir(fullPath, true)}; } private DirectoryInfo(SerializationInfo info, StreamingContext context) : base(info, context) @@ -125,16 +88,12 @@ public DirectoryInfo Parent { // those cases, as well as avoiding mangling "c:\". String s = FullPath; if (s.Length > 3 && s.EndsWith(Path.DirectorySeparatorChar)) - s = FullPath.Substring(0, FullPath.Length - 1); + s = FullPath.Substring(0, FullPath.Length - 1); parentName = Path.GetDirectoryName(s); if (parentName==null) return null; - DirectoryInfo dir = new DirectoryInfo(parentName,false); - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery | FileSecurityStateAccess.Read, String.Empty, dir.demandDir[0]); - state.EnsureState(); - - return dir; + return new DirectoryInfo(parentName, false); } } @@ -167,11 +126,6 @@ private DirectoryInfo CreateSubdirectoryHelper(String path, Object directorySecu throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSubPath", path, displayPath)); } - // Ensure we have permission to create this subdirectory. - String demandDirForCreation = Directory.GetDemandDir(fullPath, true); - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Write, OriginalPath, demandDirForCreation); - state.EnsureState(); - Directory.InternalCreateDirectory(fullPath, path, directorySecurity); // Check for read permission to directory we hand back by calling this constructor. @@ -180,14 +134,10 @@ private DirectoryInfo CreateSubdirectoryHelper(String path, Object directorySecu public void Create() { - Directory.InternalCreateDirectory(FullPath, OriginalPath, null, true); + Directory.InternalCreateDirectory(FullPath, OriginalPath, null); } // Tests if the given path refers to an existing DirectoryInfo on disk. - // - // Your application must have Read permission to the directory's - // contents. - // public override bool Exists { get { @@ -197,7 +147,6 @@ public override bool Exists { Refresh(); if (_dataInitialised != 0) // Refresh was unable to initialise the data return false; - return _data.fileAttributes != -1 && (_data.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0; } catch @@ -435,7 +384,7 @@ private IEnumerable InternalEnumerateFileSystemInfos(String sear return FileSystemEnumerableFactory.CreateFileSystemInfoIterator(FullPath, OriginalPath, searchPattern, searchOption); } - + // Returns the root portion of the given path. The resulting string // consists of those rightmost characters of the path that constitute the // root of the path. Possible patterns for the resulting string are: An @@ -444,18 +393,11 @@ private IEnumerable InternalEnumerateFileSystemInfos(String sear // where X is the drive letter), "X:\" (an absolute path on a given drive), // and "\\server\share" (a UNC path for a given server and share name). // The resulting string is null if path is null. - // - public DirectoryInfo Root { get { - String demandPath; int rootLength = PathInternal.GetRootLength(FullPath); String rootPath = FullPath.Substring(0, rootLength); - demandPath = Directory.GetDemandDir(rootPath, true); - - FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandPath); - sourceState.EnsureState(); return new DirectoryInfo(rootPath); } @@ -468,25 +410,10 @@ public void MoveTo(String destDirName) { throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destDirName)); Contract.EndContractBlock(); - FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Write | FileSecurityStateAccess.Read, DisplayPath, Directory.GetDemandDir(FullPath, true)); - sourceState.EnsureState(); - String fullDestDirName = Path.GetFullPath(destDirName); - String demandPath; if (!fullDestDirName.EndsWith(Path.DirectorySeparatorChar)) fullDestDirName = fullDestDirName + Path.DirectorySeparatorChar; - demandPath = fullDestDirName + '.'; - - // Demand read & write permission to destination. The reason is - // we hand back a DirectoryInfo to the destination that would allow - // you to read a directory listing from that directory. Sure, you - // had the ability to read the file contents in the old location, - // but you technically also need read permissions to the new - // location as well, and write is not a true superset of read. - FileSecurityState destState = new FileSecurityState(FileSecurityStateAccess.Write, destDirName, demandPath); - destState.EnsureState(); - String fullSourcePath; if (FullPath.EndsWith(Path.DirectorySeparatorChar)) fullSourcePath = FullPath; @@ -519,7 +446,6 @@ public void MoveTo(String destDirName) { FullPath = fullDestDirName; OriginalPath = destDirName; DisplayPath = GetDisplayName(OriginalPath, FullPath); - demandDir = new String[] { Directory.GetDemandDir(FullPath, true) }; // Flush any cached information about the directory. _dataInitialised = -1; @@ -527,12 +453,12 @@ public void MoveTo(String destDirName) { public override void Delete() { - Directory.Delete(FullPath, OriginalPath, false, true); + Directory.Delete(FullPath, OriginalPath, false); } public void Delete(bool recursive) { - Directory.Delete(FullPath, OriginalPath, recursive, true); + Directory.Delete(FullPath, OriginalPath, recursive); } // Returns the fully qualified path @@ -580,7 +506,6 @@ private static String GetDirName(String fullPath) } return dirName; } - - } + } } diff --git a/src/mscorlib/src/System/IO/DriveInfo.cs b/src/mscorlib/src/System/IO/DriveInfo.cs deleted file mode 100644 index 174811d180b8..000000000000 --- a/src/mscorlib/src/System/IO/DriveInfo.cs +++ /dev/null @@ -1,270 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/*============================================================ -** -** -** -** -** -** Purpose: Exposes routines for exploring a drive. -** -** -===========================================================*/ - -using System; -using System.Text; -using System.Runtime.InteropServices; -using Microsoft.Win32; -using System.Security.Permissions; -using System.Runtime.Serialization; -using System.Runtime.Versioning; -using System.Diagnostics.Contracts; - -namespace System.IO -{ - // Matches Win32's DRIVE_XXX #defines from winbase.h - [Serializable] -[System.Runtime.InteropServices.ComVisible(true)] - public enum DriveType - { - Unknown = 0, - NoRootDirectory = 1, - Removable = 2, - Fixed = 3, - Network = 4, - CDRom = 5, - Ram = 6 - } - - // Ideally we'll get a better security permission, but possibly - // not for Whidbey. -#if FEATURE_SERIALIZATION - [Serializable] -#endif - [ComVisible(true)] - public sealed class DriveInfo -#if FEATURE_SERIALIZATION - : ISerializable -#endif - { - private String _name; - - private const String NameField = "_name"; // For serialization - - public DriveInfo(String driveName) - { - if (driveName == null) - throw new ArgumentNullException(nameof(driveName)); - Contract.EndContractBlock(); - if (driveName.Length == 1) - _name = driveName + ":\\"; - else { - // GetPathRoot does not check all invalid characters - PathInternal.CheckInvalidPathChars(driveName); - _name = Path.GetPathRoot(driveName); - // Disallow null or empty drive letters and UNC paths - if (_name == null || _name.Length == 0 || _name.StartsWith("\\\\", StringComparison.Ordinal)) - throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDriveLetterOrRootDir")); - } - // We want to normalize to have a trailing backslash so we don't have two equivalent forms and - // because some Win32 API don't work without it. - if (_name.Length == 2 && _name[1] == ':') { - _name = _name + "\\"; - } - - // Now verify that the drive letter could be a real drive name. - // On Windows this means it's between A and Z, ignoring case. - // On a Unix platform, perhaps this should be a device name with - // a partition like /dev/hdc0, or possibly a mount point. - char letter = driveName[0]; - if (!((letter >= 'A' && letter <= 'Z') || (letter >= 'a' && letter <= 'z'))) - throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDriveLetterOrRootDir")); - - // Now do a security check. - String demandPath = _name + '.'; - new FileIOPermission(FileIOPermissionAccess.PathDiscovery, demandPath).Demand(); - } - - private DriveInfo(SerializationInfo info, StreamingContext context) - { - // Need to add in a security check here once it has been spec'ed. - _name = (String) info.GetValue(NameField, typeof(String)); - - // Now do a security check. - String demandPath = _name + '.'; - new FileIOPermission(FileIOPermissionAccess.PathDiscovery, demandPath).Demand(); - } - - public String Name { - get { return _name; } - } - - public DriveType DriveType { - get { - // GetDriveType can't fail - return (DriveType) Win32Native.GetDriveType(Name); - } - } - - public String DriveFormat { - get { - const int volNameLen = 50; - StringBuilder volumeName = new StringBuilder(volNameLen); - const int fileSystemNameLen = 50; - StringBuilder fileSystemName = new StringBuilder(fileSystemNameLen); - int serialNumber, maxFileNameLen, fileSystemFlags; - - int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS); - try { - bool r = Win32Native.GetVolumeInformation(Name, volumeName, volNameLen, out serialNumber, out maxFileNameLen, out fileSystemFlags, fileSystemName, fileSystemNameLen); - if (!r) { - int errorCode = Marshal.GetLastWin32Error(); - __Error.WinIODriveError(Name, errorCode); - } - } - finally { - Win32Native.SetErrorMode(oldMode); - } - return fileSystemName.ToString(); - } - } - - public bool IsReady { - get { - return Directory.InternalExists(Name); - } - } - - public long AvailableFreeSpace { - get { - long userBytes, totalBytes, freeBytes; - int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS); - try { - bool r = Win32Native.GetDiskFreeSpaceEx(Name, out userBytes, out totalBytes, out freeBytes); - if (!r) - __Error.WinIODriveError(Name); - } - finally { - Win32Native.SetErrorMode(oldMode); - } - return userBytes; - } - } - - public long TotalFreeSpace { - get { - long userBytes, totalBytes, freeBytes; - int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS); - try { - bool r = Win32Native.GetDiskFreeSpaceEx(Name, out userBytes, out totalBytes, out freeBytes); - if (!r) - __Error.WinIODriveError(Name); - } - finally { - Win32Native.SetErrorMode(oldMode); - } - return freeBytes; - } - } - - public long TotalSize { - get { - // Don't cache this, to handle variable sized floppy drives - // or other various removable media drives. - long userBytes, totalBytes, freeBytes; - int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS); - try { - bool r = Win32Native.GetDiskFreeSpaceEx(Name, out userBytes, out totalBytes, out freeBytes); - if (!r) - __Error.WinIODriveError(Name); - } - finally { - Win32Native.SetErrorMode(oldMode); - } - return totalBytes; - } - } - - public static DriveInfo[] GetDrives() - { - // Directory.GetLogicalDrives demands unmanaged code permission - String[] drives = Directory.GetLogicalDrives(); - DriveInfo[] di = new DriveInfo[drives.Length]; - for(int i=0; i - void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) - { - // No need for an additional security check - everything is public. - info.AddValue(NameField, _name, typeof(String)); - } -#endif - - } -} diff --git a/src/mscorlib/src/System/IO/File.cs b/src/mscorlib/src/System/IO/File.cs index 826766df9641..9f89f81a91cd 100644 --- a/src/mscorlib/src/System/IO/File.cs +++ b/src/mscorlib/src/System/IO/File.cs @@ -31,10 +31,8 @@ namespace System.IO [ComVisible(true)] public static class File { + private const int ERROR_INVALID_PARAMETER = 87; internal const int GENERIC_READ = unchecked((int)0x80000000); - 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 GetFileExInfoStandard = 0; @@ -67,11 +65,6 @@ public static StreamWriter AppendText(String path) // destination file already exists. Use the // Copy(String, String, boolean) method to allow // overwriting an existing file. - // - // The caller must have certain FileIOPermissions. The caller must have - // Read permission to sourceFileName and Create - // and Write permissions to destFileName. - // public static void Copy(String sourceFileName, String destFileName) { if (sourceFileName == null) throw new ArgumentNullException(nameof(sourceFileName), Environment.GetResourceString("ArgumentNull_FileName")); @@ -83,18 +76,13 @@ public static void Copy(String sourceFileName, String destFileName) { throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName)); Contract.EndContractBlock(); - InternalCopy(sourceFileName, destFileName, false, true); + InternalCopy(sourceFileName, destFileName, false); } // Copies an existing file to a new file. If overwrite is // false, then an IOException is thrown if the destination file // already exists. If overwrite is true, the file is // overwritten. - // - // The caller must have certain FileIOPermissions. The caller must have - // Read permission to sourceFileName - // and Write permissions to destFileName. - // public static void Copy(String sourceFileName, String destFileName, bool overwrite) { if (sourceFileName == null) throw new ArgumentNullException(nameof(sourceFileName), Environment.GetResourceString("ArgumentNull_FileName")); @@ -106,27 +94,13 @@ public static void Copy(String sourceFileName, String destFileName, bool overwri throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName)); Contract.EndContractBlock(); - InternalCopy(sourceFileName, destFileName, overwrite, true); - } - - internal static void UnsafeCopy(String sourceFileName, String destFileName, bool overwrite) { - if (sourceFileName == null) - throw new ArgumentNullException(nameof(sourceFileName), Environment.GetResourceString("ArgumentNull_FileName")); - if (destFileName == null) - throw new ArgumentNullException(nameof(destFileName), Environment.GetResourceString("ArgumentNull_FileName")); - if (sourceFileName.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(sourceFileName)); - if (destFileName.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName)); - Contract.EndContractBlock(); - - InternalCopy(sourceFileName, destFileName, overwrite, false); + InternalCopy(sourceFileName, destFileName, overwrite); } /// /// Note: This returns the fully qualified name of the destination file. /// - internal static String InternalCopy(String sourceFileName, String destFileName, bool overwrite, bool checkHost) + internal static String InternalCopy(String sourceFileName, String destFileName, bool overwrite) { Contract.Requires(sourceFileName != null); Contract.Requires(destFileName != null); @@ -136,13 +110,6 @@ internal static String InternalCopy(String sourceFileName, String destFileName, String fullSourceFileName = Path.GetFullPath(sourceFileName); String fullDestFileName = Path.GetFullPath(destFileName); - if (checkHost) { - FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, sourceFileName, fullSourceFileName); - FileSecurityState destState = new FileSecurityState(FileSecurityStateAccess.Write, destFileName, fullDestFileName); - sourceState.EnsureState(); - destState.EnsureState(); - } - bool r = Win32Native.CopyFile(fullSourceFileName, fullDestFileName, !overwrite); if (!r) { // Save Win32 error because subsequent checks will overwrite this HRESULT. @@ -158,19 +125,14 @@ internal static String InternalCopy(String sourceFileName, String destFileName, __Error.WinIOError(errorCode, fileName); } - + return fullDestFileName; } - // Creates a file in a particular path. If the file exists, it is replaced. // The file is opened with ReadWrite accessand cannot be opened by another // application until it has been closed. An IOException is thrown if the // directory specified doesn't exist. - // - // Your application must have Create, Read, and Write permissions to - // the file. - // public static FileStream Create(String path) { return Create(path, FileStream.DefaultBufferSize); } @@ -179,10 +141,6 @@ public static FileStream Create(String path) { // The file is opened with ReadWrite access and cannot be opened by another // application until it has been closed. An IOException is thrown if the // directory specified doesn't exist. - // - // Your application must have Create, Read, and Write permissions to - // the file. - // public static FileStream Create(String path, int bufferSize) { return new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize); } @@ -198,36 +156,17 @@ public static FileStream Create(String path, int bufferSize, FileOptions options // // On NT, Delete will fail for a file that is open for normal I/O // or a file that is memory mapped. - // - // Your application must have Delete permission to the target file. - // public static void Delete(String path) { if (path == null) throw new ArgumentNullException(nameof(path)); Contract.EndContractBlock(); - - InternalDelete(path, true); - } - - internal static void UnsafeDelete(String path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - Contract.EndContractBlock(); - InternalDelete(path, false); + InternalDelete(path); } - internal static void InternalDelete(String path, bool checkHost) + internal static void InternalDelete(String path) { String fullPath = Path.GetFullPath(path); - - if (checkHost) - { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Write, path, fullPath); - state.EnsureState(); - } - bool r = Win32Native.DeleteFile(fullPath); if (!r) { int hr = Marshal.GetLastWin32Error(); @@ -238,71 +177,16 @@ internal static void InternalDelete(String path, bool checkHost) } } - - public static void Decrypt(String path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - Contract.EndContractBlock(); - - String fullPath = Path.GetFullPath(path); - FileIOPermission.QuickDemand(FileIOPermissionAccess.Read | FileIOPermissionAccess.Write, fullPath, false, false); - - bool r = Win32Native.DecryptFile(fullPath, 0); - if (!r) { - int errorCode = Marshal.GetLastWin32Error(); - if (errorCode == Win32Native.ERROR_ACCESS_DENIED) { - // Check to see if the file system is not NTFS. If so, - // throw a different exception. - DriveInfo di = new DriveInfo(Path.GetPathRoot(fullPath)); - if (!String.Equals("NTFS", di.DriveFormat)) - throw new NotSupportedException(Environment.GetResourceString("NotSupported_EncryptionNeedsNTFS")); - } - __Error.WinIOError(errorCode, fullPath); - } - } - - public static void Encrypt(String path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - Contract.EndContractBlock(); - - String fullPath = Path.GetFullPath(path); - FileIOPermission.QuickDemand(FileIOPermissionAccess.Read | FileIOPermissionAccess.Write, fullPath, false, false); - - bool r = Win32Native.EncryptFile(fullPath); - if (!r) { - int errorCode = Marshal.GetLastWin32Error(); - if (errorCode == Win32Native.ERROR_ACCESS_DENIED) { - // Check to see if the file system is not NTFS. If so, - // throw a different exception. - DriveInfo di = new DriveInfo(Path.GetPathRoot(fullPath)); - if (!String.Equals("NTFS", di.DriveFormat)) - throw new NotSupportedException(Environment.GetResourceString("NotSupported_EncryptionNeedsNTFS")); - } - __Error.WinIOError(errorCode, fullPath); - } - } - // Tests if a file exists. The result is true if the file // given by the specified path exists; otherwise, the result is // false. Note that if path describes a directory, // Exists will return true. - // - // Your application must have Read permission for the target directory. - // public static bool Exists(String path) { - return InternalExistsHelper(path, true); + return InternalExistsHelper(path); } - internal static bool UnsafeExists(String path) - { - return InternalExistsHelper(path, false); - } - - private static bool InternalExistsHelper(String path, bool checkHost) + private static bool InternalExistsHelper(String path) { try { @@ -312,6 +196,7 @@ private static bool InternalExistsHelper(String path, bool checkHost) return false; path = Path.GetFullPath(path); + // After normalizing, check whether path ends in directory separator. // Otherwise, FillAttributeInfo removes it and we may return a false positive. // GetFullPath should never return null @@ -321,12 +206,6 @@ private static bool InternalExistsHelper(String path, bool checkHost) return false; } - if (checkHost) - { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, path); - state.EnsureState(); - } - return InternalExists(path); } catch (ArgumentException) { } @@ -360,24 +239,18 @@ public static FileStream Open(String path, FileMode mode, FileAccess access, Fil public static DateTime GetCreationTime(String path) { - return InternalGetCreationTimeUtc(path, true).ToLocalTime(); + return InternalGetCreationTimeUtc(path).ToLocalTime(); } public static DateTime GetCreationTimeUtc(String path) { - return InternalGetCreationTimeUtc(path, false); // this API isn't exposed in Silverlight + return InternalGetCreationTimeUtc(path); // this API isn't exposed in Silverlight } - private static DateTime InternalGetCreationTimeUtc(String path, bool checkHost) + private static DateTime InternalGetCreationTimeUtc(String path) { String fullPath = Path.GetFullPath(path); - if (checkHost) - { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, path, fullPath); - state.EnsureState(); - } - Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); int dataInitialised = FillAttributeInfo(fullPath, ref data, false, false); if (dataInitialised != 0) @@ -389,24 +262,18 @@ private static DateTime InternalGetCreationTimeUtc(String path, bool checkHost) public static DateTime GetLastAccessTime(String path) { - return InternalGetLastAccessTimeUtc(path, true).ToLocalTime(); + return InternalGetLastAccessTimeUtc(path).ToLocalTime(); } public static DateTime GetLastAccessTimeUtc(String path) { - return InternalGetLastAccessTimeUtc(path, false); // this API isn't exposed in Silverlight + return InternalGetLastAccessTimeUtc(path); } - private static DateTime InternalGetLastAccessTimeUtc(String path, bool checkHost) + private static DateTime InternalGetLastAccessTimeUtc(String path) { String fullPath = Path.GetFullPath(path); - if (checkHost) - { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, path, fullPath); - state.EnsureState(); - } - Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); int dataInitialised = FillAttributeInfo(fullPath, ref data, false, false); if (dataInitialised != 0) @@ -418,24 +285,18 @@ private static DateTime InternalGetLastAccessTimeUtc(String path, bool checkHost public static DateTime GetLastWriteTime(String path) { - return InternalGetLastWriteTimeUtc(path, true).ToLocalTime(); + return InternalGetLastWriteTimeUtc(path).ToLocalTime(); } public static DateTime GetLastWriteTimeUtc(String path) { - return InternalGetLastWriteTimeUtc(path, false); // this API isn't exposed in Silverlight + return InternalGetLastWriteTimeUtc(path); } - private static DateTime InternalGetLastWriteTimeUtc(String path, bool checkHost) + private static DateTime InternalGetLastWriteTimeUtc(String path) { String fullPath = Path.GetFullPath(path); - if (checkHost) - { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, path, fullPath); - state.EnsureState(); - } - Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); int dataInitialised = FillAttributeInfo(fullPath, ref data, false, false); if (dataInitialised != 0) @@ -449,9 +310,6 @@ public static FileAttributes GetAttributes(String path) { String fullPath = Path.GetFullPath(path); - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, path, fullPath); - state.EnsureState(); - Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); int dataInitialised = FillAttributeInfo(fullPath, ref data, false, true); if (dataInitialised != 0) @@ -476,7 +334,6 @@ public static FileStream OpenRead(String path) { return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); } - public static FileStream OpenWrite(String path) { return new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None); @@ -490,7 +347,7 @@ public static String ReadAllText(String path) throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); Contract.EndContractBlock(); - return InternalReadAllText(path, Encoding.UTF8, true); + return InternalReadAllText(path, Encoding.UTF8); } public static String ReadAllText(String path, Encoding encoding) @@ -503,27 +360,16 @@ public static String ReadAllText(String path, Encoding encoding) throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); Contract.EndContractBlock(); - return InternalReadAllText(path, encoding, true); + return InternalReadAllText(path, encoding); } - internal static String UnsafeReadAllText(String path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); - Contract.EndContractBlock(); - - return InternalReadAllText(path, Encoding.UTF8, false); - } - - private static String InternalReadAllText(String path, Encoding encoding, bool checkHost) + private static String InternalReadAllText(String path, Encoding encoding) { Contract.Requires(path != null); Contract.Requires(encoding != null); Contract.Requires(path.Length > 0); - using (StreamReader sr = new StreamReader(path, encoding, true, StreamReader.DefaultBufferSize, checkHost)) + using (StreamReader sr = new StreamReader(path, encoding, true, StreamReader.DefaultBufferSize)) return sr.ReadToEnd(); } @@ -535,7 +381,7 @@ public static void WriteAllText(String path, String contents) throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); Contract.EndContractBlock(); - InternalWriteAllText(path, contents, StreamWriter.UTF8NoBOM, true); + InternalWriteAllText(path, contents, StreamWriter.UTF8NoBOM); } public static void WriteAllText(String path, String contents, Encoding encoding) @@ -548,46 +394,24 @@ public static void WriteAllText(String path, String contents, Encoding encoding) throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); Contract.EndContractBlock(); - InternalWriteAllText(path, contents, encoding, true); - } - - internal static void UnsafeWriteAllText(String path, String contents) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); - Contract.EndContractBlock(); - - InternalWriteAllText(path, contents, StreamWriter.UTF8NoBOM, false); + InternalWriteAllText(path, contents, encoding); } - private static void InternalWriteAllText(String path, String contents, Encoding encoding, bool checkHost) + private static void InternalWriteAllText(String path, String contents, Encoding encoding) { Contract.Requires(path != null); Contract.Requires(encoding != null); Contract.Requires(path.Length > 0); - using (StreamWriter sw = new StreamWriter(path, false, encoding, StreamWriter.DefaultBufferSize, checkHost)) + using (StreamWriter sw = new StreamWriter(path, false, encoding, StreamWriter.DefaultBufferSize)) sw.Write(contents); } public static byte[] ReadAllBytes(String path) - { - return InternalReadAllBytes(path, true); - } - - internal static byte[] UnsafeReadAllBytes(String path) - { - return InternalReadAllBytes(path, false); - } - - - private static byte[] InternalReadAllBytes(String path, bool checkHost) { byte[] bytes; using(FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, - FileStream.DefaultBufferSize, FileOptions.None, Path.GetFileName(path), false, false, checkHost)) { + FileStream.DefaultBufferSize, FileOptions.None, Path.GetFileName(path), false, false)) { // Do a blocking read int index = 0; long fileLength = fs.Length; @@ -616,30 +440,17 @@ public static void WriteAllBytes(String path, byte[] bytes) throw new ArgumentNullException(nameof(bytes)); Contract.EndContractBlock(); - InternalWriteAllBytes(path, bytes, true); + InternalWriteAllBytes(path, bytes); } - internal static void UnsafeWriteAllBytes(String path, byte[] bytes) - { - if (path == null) - throw new ArgumentNullException(nameof(path), Environment.GetResourceString("ArgumentNull_Path")); - if (path.Length == 0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); - if (bytes == null) - throw new ArgumentNullException(nameof(bytes)); - Contract.EndContractBlock(); - - InternalWriteAllBytes(path, bytes, false); - } - - private static void InternalWriteAllBytes(String path, byte[] bytes, bool checkHost) + private static void InternalWriteAllBytes(String path, byte[] bytes) { Contract.Requires(path != null); Contract.Requires(path.Length != 0); Contract.Requires(bytes != null); using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, - FileStream.DefaultBufferSize, FileOptions.None, Path.GetFileName(path), false, false, checkHost)) + FileStream.DefaultBufferSize, FileOptions.None, Path.GetFileName(path), false, false)) { fs.Write(bytes, 0, bytes.Length); } @@ -843,21 +654,11 @@ public static void AppendAllLines(String path, IEnumerable contents, Enc // Moves a specified file to a new location and potentially a new file name. // This method does work across volumes. - // - // The caller must have certain FileIOPermissions. The caller must - // have Read and Write permission to - // sourceFileName and Write - // permissions to destFileName. - // public static void Move(String sourceFileName, String destFileName) { - InternalMove(sourceFileName, destFileName, true); + InternalMove(sourceFileName, destFileName); } - internal static void UnsafeMove(String sourceFileName, String destFileName) { - InternalMove(sourceFileName, destFileName, false); - } - - private static void InternalMove(String sourceFileName, String destFileName, bool checkHost) { + private static void InternalMove(String sourceFileName, String destFileName) { if (sourceFileName == null) throw new ArgumentNullException(nameof(sourceFileName), Environment.GetResourceString("ArgumentNull_FileName")); if (destFileName == null) @@ -871,13 +672,6 @@ private static void InternalMove(String sourceFileName, String destFileName, boo String fullSourceFileName = Path.GetFullPath(sourceFileName); String fullDestFileName = Path.GetFullPath(destFileName); - if (checkHost) { - FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Write | FileSecurityStateAccess.Read, sourceFileName, fullSourceFileName); - FileSecurityState destState = new FileSecurityState(FileSecurityStateAccess.Write, destFileName, fullDestFileName); - sourceState.EnsureState(); - destState.EnsureState(); - } - if (!InternalExists(fullSourceFileName)) __Error.WinIOError(Win32Native.ERROR_FILE_NOT_FOUND, fullSourceFileName); @@ -915,21 +709,12 @@ private static void InternalReplace(String sourceFileName, String destinationFil Contract.Requires(sourceFileName != null); Contract.Requires(destinationFileName != null); - // Write permission to all three files, read permission to source - // and dest. String fullSrcPath = Path.GetFullPath(sourceFileName); String fullDestPath = Path.GetFullPath(destinationFileName); String fullBackupPath = null; if (destinationBackupFileName != null) fullBackupPath = Path.GetFullPath(destinationBackupFileName); - FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read | FileSecurityStateAccess.Write, sourceFileName, fullSrcPath); - FileSecurityState destState = new FileSecurityState(FileSecurityStateAccess.Read | FileSecurityStateAccess.Write, destinationFileName, fullDestPath); - FileSecurityState backupState = new FileSecurityState(FileSecurityStateAccess.Read | FileSecurityStateAccess.Write, destinationBackupFileName, fullBackupPath); - sourceState.EnsureState(); - destState.EnsureState(); - backupState.EnsureState(); - int flags = Win32Native.REPLACEFILE_WRITE_THROUGH; if (ignoreMetadataErrors) flags |= Win32Native.REPLACEFILE_IGNORE_MERGE_ERRORS; @@ -1002,7 +787,6 @@ internal static int FillAttributeInfo(String path, ref Win32Native.WIN32_FILE_AT } else { - // For floppy drives, normally the OS will pop up a dialog saying // there is no disk in drive A:, please insert one. We don't want that. // SetErrorMode will let us disable this, but we should set the error @@ -1037,9 +821,5 @@ internal static int FillAttributeInfo(String path, ref Win32Native.WIN32_FILE_AT return dataInitialised; } - - // Defined in WinError.h - private const int ERROR_INVALID_PARAMETER = 87; - private const int ERROR_ACCESS_DENIED = 0x5; } } diff --git a/src/mscorlib/src/System/IO/FileInfo.cs b/src/mscorlib/src/System/IO/FileInfo.cs index 7e00a805567f..32622c63a1ee 100644 --- a/src/mscorlib/src/System/IO/FileInfo.cs +++ b/src/mscorlib/src/System/IO/FileInfo.cs @@ -2,21 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -/*============================================================ -** -** -** -** -** -** Purpose: A collection of methods for manipulating Files. -** -** April 09,2000 (some design refactorization) -** -===========================================================*/ - -using System; -using System.Security.Permissions; -using PermissionSet = System.Security.PermissionSet; using Win32Native = Microsoft.Win32.Win32Native; using System.Runtime.InteropServices; using System.Text; @@ -37,45 +22,22 @@ public sealed class FileInfo: FileSystemInfo private String _name; // Migrating InheritanceDemands requires this default ctor, so we can annotate it. -#if FEATURE_CORESYSTEM -#else -#endif //FEATURE_CORESYSTEM private FileInfo(){} - public static FileInfo UnsafeCreateFileInfo(String fileName) - { - if (fileName == null) - throw new ArgumentNullException(nameof(fileName)); - Contract.EndContractBlock(); - - FileInfo fi = new FileInfo(); - fi.Init(fileName, false); - return fi; - } - public FileInfo(String fileName) { if (fileName == null) throw new ArgumentNullException(nameof(fileName)); Contract.EndContractBlock(); - Init(fileName, true); + Init(fileName); } - private void Init(String fileName, bool checkHost) + private void Init(String fileName) { OriginalPath = fileName; - // Must fully qualify the path for the security check - String fullPath = Path.GetFullPath(fileName); - - if (checkHost) - { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, fileName, fullPath); - state.EnsureState(); - } - _name = Path.GetFileName(fileName); - FullPath = fullPath; + FullPath = Path.GetFullPath(fileName); DisplayPath = GetDisplayPath(fileName); } @@ -90,8 +52,6 @@ private FileInfo(SerializationInfo info, StreamingContext context) : base(info, DisplayPath = GetDisplayPath(OriginalPath); } -#if FEATURE_CORESYSTEM -#endif //FEATURE_CORESYSTEM internal FileInfo(String fullPath, bool ignoreThis) { Debug.Assert(PathInternal.GetRootLength(fullPath) > 0, "fullPath must be fully qualified!"); @@ -125,13 +85,7 @@ public String DirectoryName { get { - String directoryName = Path.GetDirectoryName(FullPath); - if (directoryName != null) - { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, DisplayPath, FullPath); - state.EnsureState(); - } - return directoryName; + return Path.GetDirectoryName(FullPath); } } @@ -161,7 +115,7 @@ public bool IsReadOnly { public StreamReader OpenText() { - return new StreamReader(FullPath, Encoding.UTF8, true, StreamReader.DefaultBufferSize, false); + return new StreamReader(FullPath, Encoding.UTF8, true, StreamReader.DefaultBufferSize); } public StreamWriter CreateText() @@ -174,16 +128,10 @@ public StreamWriter AppendText() return new StreamWriter(FullPath,true); } - // Copies an existing file to a new file. An exception is raised if the // destination file already exists. Use the // Copy(String, String, boolean) method to allow // overwriting an existing file. - // - // The caller must have certain FileIOPermissions. The caller must have - // Read permission to sourceFileName - // and Write permissions to destFileName. - // public FileInfo CopyTo(String destFileName) { if (destFileName == null) throw new ArgumentNullException(nameof(destFileName), Environment.GetResourceString("ArgumentNull_FileName")); @@ -191,20 +139,14 @@ public FileInfo CopyTo(String destFileName) { throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName)); Contract.EndContractBlock(); - destFileName = File.InternalCopy(FullPath, destFileName, false, true); + destFileName = File.InternalCopy(FullPath, destFileName, false); return new FileInfo(destFileName, false); } - // Copies an existing file to a new file. If overwrite is // false, then an IOException is thrown if the destination file // already exists. If overwrite is true, the file is // overwritten. - // - // The caller must have certain FileIOPermissions. The caller must have - // Read permission to sourceFileName and Create - // and Write permissions to destFileName. - // public FileInfo CopyTo(String destFileName, bool overwrite) { if (destFileName == null) throw new ArgumentNullException(nameof(destFileName), Environment.GetResourceString("ArgumentNull_FileName")); @@ -212,7 +154,7 @@ public FileInfo CopyTo(String destFileName, bool overwrite) { throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName)); Contract.EndContractBlock(); - destFileName = File.InternalCopy(FullPath, destFileName, overwrite, true); + destFileName = File.InternalCopy(FullPath, destFileName, overwrite); return new FileInfo(destFileName, false); } @@ -225,16 +167,9 @@ public FileStream Create() { // an exception. // // On NT, Delete will fail for a file that is open for normal I/O - // or a file that is memory mapped. On Win95, the file will be - // deleted irregardless of whether the file is being used. - // - // Your application must have Delete permission to the target file. - // + // or a file that is memory mapped. public override void Delete() { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Write, DisplayPath, FullPath); - state.EnsureState(); - bool r = Win32Native.DeleteFile(FullPath); if (!r) { int hr = Marshal.GetLastWin32Error(); @@ -245,23 +180,9 @@ public override void Delete() } } - [ComVisible(false)] - public void Decrypt() - { - File.Decrypt(FullPath); - } - - [ComVisible(false)] - public void Encrypt() - { - File.Encrypt(FullPath); - } - // Tests if the given file exists. The result is true if the file // given by the specified path exists; otherwise, the result is // false. - // - // Your application must have Read permission for the target directory. public override bool Exists { get { try { @@ -308,12 +229,6 @@ public FileStream OpenWrite() { // Moves a given file to a new location and potentially a new file name. // This method does work across volumes. - // - // The caller must have certain FileIOPermissions. The caller must - // have Read and Write permission to - // sourceFileName and Write - // permissions to destFileName. - // public void MoveTo(String destFileName) { if (destFileName==null) throw new ArgumentNullException(nameof(destFileName)); @@ -323,11 +238,6 @@ public void MoveTo(String destFileName) { string fullDestFileName = Path.GetFullPath(destFileName); - FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Write | FileSecurityStateAccess.Read, DisplayPath, FullPath); - FileSecurityState destState = new FileSecurityState(FileSecurityStateAccess.Write, destFileName, fullDestFileName); - sourceState.EnsureState(); - destState.EnsureState(); - if (!Win32Native.MoveFile(FullPath, fullDestFileName)) __Error.WinIOError(); FullPath = fullDestFileName; diff --git a/src/mscorlib/src/System/IO/FileSecurityState.cs b/src/mscorlib/src/System/IO/FileSecurityState.cs deleted file mode 100644 index d10681fd2b5e..000000000000 --- a/src/mscorlib/src/System/IO/FileSecurityState.cs +++ /dev/null @@ -1,128 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/*============================================================ -** -** Enum: FileSecurityState -** -** -** -** -** Purpose: Determines whether file system access is safe -** -** -===========================================================*/ - -using System; -using System.Diagnostics.Contracts; -using System.IO; -using System.Security; -using System.Security.Permissions; - -namespace System.IO -{ - [System.Runtime.CompilerServices.FriendAccessAllowed] - internal class FileSecurityState : SecurityState - { -#if !PLATFORM_UNIX - private static readonly char[] m_illegalCharacters = { '?', '*' }; -#endif // !PLATFORM_UNIX - - private FileSecurityStateAccess m_access; - private String m_userPath; - private String m_canonicalizedPath; - - // default ctor needed for security rule consistency - private FileSecurityState() - { - } - - internal FileSecurityState(FileSecurityStateAccess access, String path) - { - if (path == null) - { - throw new ArgumentNullException(nameof(path)); - } - VerifyAccess(access); - m_access = access; - m_userPath = path; - if (path.Equals(String.Empty, StringComparison.OrdinalIgnoreCase)) - { - m_canonicalizedPath = String.Empty; - } - else - { - VerifyPath(path); - m_canonicalizedPath = IO.Path.GetFullPath(path); - } - } - - // slight perf savings for trusted internal callers - internal FileSecurityState(FileSecurityStateAccess access, String path, String canonicalizedPath) - { - VerifyAccess(access); - VerifyPath(path); - VerifyPath(canonicalizedPath); - - m_access = access; - m_userPath = path; - m_canonicalizedPath = canonicalizedPath; - } - - internal FileSecurityStateAccess Access - { - get - { - return m_access; - } - } - - public String Path { - [System.Runtime.CompilerServices.FriendAccessAllowed] - get - { - return m_canonicalizedPath; - } - } - - public override void EnsureState() - { - // this is the case for empty string machine name, etc - if (String.Empty.Equals(m_canonicalizedPath)) - return; - - if (!IsStateAvailable()) - { - throw new SecurityException(Environment.GetResourceString("FileSecurityState_OperationNotPermitted", (m_userPath == null) ? String.Empty : m_userPath)); - } - } - - internal static FileSecurityStateAccess ToFileSecurityState(FileIOPermissionAccess access) - { - Contract.Requires((access & ~FileIOPermissionAccess.AllAccess) == 0); - return (FileSecurityStateAccess)access; // flags are identical; just cast - } - - private static void VerifyAccess(FileSecurityStateAccess access) - { - if ((access & ~FileSecurityStateAccess.AllAccess) != 0) - throw new ArgumentOutOfRangeException(nameof(access), Environment.GetResourceString("Arg_EnumIllegalVal")); - } - - private static void VerifyPath(string path) - { - if (path != null) - { - path = path.Trim(); - -#if !PLATFORM_UNIX - if (!PathInternal.IsDevice(path) && PathInternal.HasInvalidVolumeSeparator(path)) - throw new ArgumentException(Environment.GetResourceString("Argument_PathFormatNotSupported")); -#endif - - PathInternal.CheckInvalidPathChars(path); - } - } - } -} diff --git a/src/mscorlib/src/System/IO/FileSecurityStateAccess.cs b/src/mscorlib/src/System/IO/FileSecurityStateAccess.cs deleted file mode 100644 index b6378c61426a..000000000000 --- a/src/mscorlib/src/System/IO/FileSecurityStateAccess.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/*============================================================ -** -** Enum: FileSecurityStateAccess -** -** -** -** -** Purpose: FileSecurityState enum -** -** -===========================================================*/ - -using System; - -namespace System.IO -{ - [Flags] - internal enum FileSecurityStateAccess - { - NoAccess = 0, - Read = 1, - Write = 2, - Append = 4, - PathDiscovery = 8, - AllAccess = 15 - } -} - diff --git a/src/mscorlib/src/System/IO/FileSystemEnumerable.cs b/src/mscorlib/src/System/IO/FileSystemEnumerable.cs index e3ad368a09b2..f861805ccfec 100644 --- a/src/mscorlib/src/System/IO/FileSystemEnumerable.cs +++ b/src/mscorlib/src/System/IO/FileSystemEnumerable.cs @@ -12,14 +12,10 @@ ** ===========================================================*/ -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; @@ -159,7 +155,6 @@ void IEnumerator.Reset() // For all the dirs/files returned, demands path discovery permission for their parent folders internal class FileSystemEnumerableIterator : Iterator { - private const int STATE_INIT = 1; private const int STATE_SEARCH_NEXT_DIR = 2; private const int STATE_FIND_NEXT_FILE = 3; @@ -170,7 +165,6 @@ internal class FileSystemEnumerableIterator : Iterator private Directory.SearchData searchData; private String searchCriteria; SafeFindHandle _hnd = null; - bool needsParentPathDiscoveryDemand; // empty means we know in advance that we won�t find any search results, which can happen if: // 1. we don�t have a search pattern @@ -185,7 +179,6 @@ internal class FileSystemEnumerableIterator : Iterator private String fullPath; private String normalizedSearchPath; private int oldMode; - private bool _checkHost; internal FileSystemEnumerableIterator(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler resultHandler, bool checkHost) { @@ -214,23 +207,6 @@ internal FileSystemEnumerableIterator(String path, String originalUserPath, Stri String fullSearchString = GetFullSearchString(fullPath, normalizedSearchPattern); normalizedSearchPath = Path.GetDirectoryName(fullSearchString); - // permission demands - String[] demandPaths = new String[2]; - // Any illegal chars such as *, ? will be caught by FileIOPermission.HasIllegalCharacters - demandPaths[0] = Directory.GetDemandDir(fullPath, true); - // For filters like foo\*.cs we need to verify if the directory foo is not denied access. - // Do a demand on the combined path so that we can fail early in case of deny - demandPaths[1] = Directory.GetDemandDir(normalizedSearchPath, true); - _checkHost = checkHost; - - if (checkHost) - { - FileSecurityState state1 = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandPaths[0]); - state1.EnsureState(); - FileSecurityState state2 = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandPaths[1]); - state2.EnsureState(); - } - // normalize search criteria searchCriteria = GetNormalizedSearchCriteria(fullSearchString, normalizedSearchPath); @@ -302,7 +278,7 @@ private void CommonInit() } } - private FileSystemEnumerableIterator(String fullPath, String normalizedSearchPath, String searchCriteria, String userPath, SearchOption searchOption, SearchResultHandler resultHandler, bool checkHost) + private FileSystemEnumerableIterator(String fullPath, String normalizedSearchPath, String searchCriteria, String userPath, SearchOption searchOption, SearchResultHandler resultHandler) { this.fullPath = fullPath; this.normalizedSearchPath = normalizedSearchPath; @@ -310,28 +286,11 @@ private FileSystemEnumerableIterator(String fullPath, String normalizedSearchPat this._resultHandler = resultHandler; this.userPath = userPath; this.searchOption = searchOption; - this._checkHost = checkHost; searchStack = new List(); if (searchCriteria != null) { - // permission demands - String[] demandPaths = new String[2]; - // Any illegal chars such as *, ? will be caught by FileIOPermission.HasIllegalCharacters - demandPaths[0] = Directory.GetDemandDir(fullPath, true); - // For filters like foo\*.cs we need to verify if the directory foo is not denied access. - // Do a demand on the combined path so that we can fail early in case of deny - demandPaths[1] = Directory.GetDemandDir(normalizedSearchPath, true); - - if (checkHost) - { - FileSecurityState state1 = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandPaths[0]); - state1.EnsureState(); - FileSecurityState state2 = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandPaths[1]); - state2.EnsureState(); - } - searchData = new Directory.SearchData(normalizedSearchPath, userPath, searchOption); CommonInit(); } @@ -343,7 +302,7 @@ private FileSystemEnumerableIterator(String fullPath, String normalizedSearchPat protected override Iterator Clone() { - return new FileSystemEnumerableIterator(fullPath, normalizedSearchPath, searchCriteria, userPath, searchOption, _resultHandler, _checkHost); + return new FileSystemEnumerableIterator(fullPath, normalizedSearchPath, searchCriteria, userPath, searchOption, _resultHandler); } protected override void Dispose(bool disposing) @@ -421,15 +380,9 @@ public override bool MoveNext() } state = STATE_FIND_NEXT_FILE; - needsParentPathDiscoveryDemand = true; SearchResult searchResult = CreateSearchResult(searchData, data); if (_resultHandler.IsResultIncluded(searchResult)) { - if (needsParentPathDiscoveryDemand) - { - DoDemand(searchData.fullPath); - needsParentPathDiscoveryDemand = false; - } current = _resultHandler.CreateObject(searchResult); return true; } @@ -451,11 +404,6 @@ public override bool MoveNext() SearchResult searchResult = CreateSearchResult(searchData, data); if (_resultHandler.IsResultIncluded(searchResult)) { - if (needsParentPathDiscoveryDemand) - { - DoDemand(searchData.fullPath); - needsParentPathDiscoveryDemand = false; - } current = _resultHandler.CreateObject(searchResult); return true; } @@ -565,15 +513,6 @@ private void AddSearchableDirsToStack(Directory.SearchData localSearchData) } } - internal void DoDemand(String fullPathToDemand) - { - if(_checkHost) { - String demandDir = Directory.GetDemandDir(fullPathToDemand, true); - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandDir); - state.EnsureState(); - } - } - private static String NormalizeSearchPattern(String searchPattern) { Contract.Requires(searchPattern != null); @@ -674,10 +613,6 @@ internal override bool IsResultIncluded(SearchResult result) internal override FileInfo CreateObject(SearchResult result) { String name = result.FullPath; - - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, name); - state.EnsureState(); - FileInfo fi = new FileInfo(name, false); fi.InitializeFrom(result.FindData); return fi; @@ -693,13 +628,7 @@ internal override bool IsResultIncluded(SearchResult result) internal override DirectoryInfo CreateObject(SearchResult result) { - String name = result.FullPath; - String permissionName = name + "\\."; - - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, permissionName); - state.EnsureState(); - - DirectoryInfo di = new DirectoryInfo(name, false); + DirectoryInfo di = new DirectoryInfo(result.FullPath, false); di.InitializeFrom(result.FindData); return di; } @@ -724,25 +653,14 @@ internal override FileSystemInfo CreateObject(SearchResult result) if (isDir) { - String name = result.FullPath; - String permissionName = name + "\\."; - - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, permissionName); - state.EnsureState(); - - DirectoryInfo di = new DirectoryInfo(name, false); + DirectoryInfo di = new DirectoryInfo(result.FullPath, false); di.InitializeFrom(result.FindData); return di; } else { - Debug.Assert(isFile); - String name = result.FullPath; - - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, name); - state.EnsureState(); - - FileInfo fi = new FileInfo(name, false); + Contract.Assert(isFile); + FileInfo fi = new FileInfo(result.FullPath, false); fi.InitializeFrom(result.FindData); return fi; } @@ -780,7 +698,6 @@ internal Win32Native.WIN32_FIND_DATA FindData { get { return findData; } } - } internal static class FileSystemEnumerableHelpers diff --git a/src/mscorlib/src/System/IO/FileSystemInfo.cs b/src/mscorlib/src/System/IO/FileSystemInfo.cs index be2189c5b6b4..94cd531b0784 100644 --- a/src/mscorlib/src/System/IO/FileSystemInfo.cs +++ b/src/mscorlib/src/System/IO/FileSystemInfo.cs @@ -2,15 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; -using System.Collections; -using System.Security; -using System.Security.Permissions; using Microsoft.Win32; -using System.Text; using System.Runtime.InteropServices; using System.Runtime.Serialization; -using System.Runtime.Versioning; using System.Diagnostics.Contracts; namespace System.IO @@ -33,9 +27,6 @@ public abstract class FileSystemInfo : MarshalByRefObject, ISerializable { protected String OriginalPath; // path passed in by the user private String _displayPath = ""; // path that can be displayed to the user -#if FEATURE_CORESYSTEM -#else -#endif //FEATURE_CORESYSTEM protected FileSystemInfo() { } @@ -66,27 +57,6 @@ internal void InitializeFrom(Win32Native.WIN32_FIND_DATA findData) public virtual String FullName { get { - String demandDir; - if (this is DirectoryInfo) - demandDir = Directory.GetDemandDir(FullPath, true); - else - demandDir = FullPath; - - FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandDir); - sourceState.EnsureState(); - return FullPath; - } - } - - internal virtual String UnsafeGetFullName - { - get - { - String demandDir; - if (this is DirectoryInfo) - demandDir = Directory.GetDemandDir(FullPath, true); - else - demandDir = FullPath; return FullPath; } } @@ -131,13 +101,9 @@ public DateTime CreationTime } } - [ComVisible(false)] + [ComVisible(false)] public DateTime CreationTimeUtc { get { - // get_CreationTime also depends on this security check - FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath); - sourceState.EnsureState(); - if (_dataInitialised == -1) { _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); Refresh(); @@ -166,10 +132,6 @@ public DateTime LastAccessTime [ComVisible(false)] public DateTime LastAccessTimeUtc { get { - // get_LastAccessTime also depends on this security check - FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath); - sourceState.EnsureState(); - if (_dataInitialised == -1) { _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); Refresh(); @@ -180,7 +142,6 @@ public DateTime LastAccessTimeUtc { long fileTime = ((long)_data.ftLastAccessTimeHigh << 32) | _data.ftLastAccessTimeLow; return DateTime.FromFileTimeUtc(fileTime); - } set { @@ -202,9 +163,6 @@ public DateTime LastWriteTime [ComVisible(false)] public DateTime LastWriteTimeUtc { get { - // get_LastWriteTime also depends on this security check - FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath); - sourceState.EnsureState(); if (_dataInitialised == -1) { _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); Refresh(); @@ -230,9 +188,6 @@ public void Refresh() public FileAttributes Attributes { get { - FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath); - sourceState.EnsureState(); - if (_dataInitialised == -1) { _data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA(); Refresh(); // Call refresh to intialise the data @@ -281,5 +236,5 @@ internal String DisplayPath _displayPath = value; } } - } + } } diff --git a/src/mscorlib/src/System/IO/StreamReader.cs b/src/mscorlib/src/System/IO/StreamReader.cs index 33cca92abe61..708db088e8c2 100644 --- a/src/mscorlib/src/System/IO/StreamReader.cs +++ b/src/mscorlib/src/System/IO/StreamReader.cs @@ -2,19 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -/*============================================================ -** -** -** -** -** -** Purpose: For reading text from streams in a particular -** encoding. -** -** -===========================================================*/ - -using System; using System.Text; using System.Runtime.InteropServices; using System.Runtime.Versioning; @@ -189,10 +176,6 @@ public StreamReader(String path, Encoding encoding, bool detectEncodingFromByteO } public StreamReader(String path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize) - : this(path, encoding, detectEncodingFromByteOrderMarks, bufferSize, true) { - } - - internal StreamReader(String path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool checkHost) { // Don't open a Stream before checking for invalid arguments, // or we'll create a FileStream on disk and we won't close it until @@ -205,7 +188,7 @@ internal StreamReader(String path, Encoding encoding, bool detectEncodingFromByt throw new ArgumentOutOfRangeException(nameof(bufferSize), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum")); Contract.EndContractBlock(); - Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize, FileOptions.SequentialScan, Path.GetFileName(path), false, false, checkHost); + Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize, FileOptions.SequentialScan, Path.GetFileName(path), false, false); Init(stream, encoding, detectEncodingFromByteOrderMarks, bufferSize, false); } diff --git a/src/mscorlib/src/System/IO/StreamWriter.cs b/src/mscorlib/src/System/IO/StreamWriter.cs index 49415d641e8d..22eba8260540 100644 --- a/src/mscorlib/src/System/IO/StreamWriter.cs +++ b/src/mscorlib/src/System/IO/StreamWriter.cs @@ -2,23 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -/*============================================================ -** -** -** -** -** -** Purpose: For writing text to streams in a particular -** encoding. -** -** -===========================================================*/ -using System; using System.Text; -using System.Threading; -using System.Globalization; using System.Runtime.CompilerServices; -using System.Runtime.Versioning; using System.Security.Permissions; using System.Runtime.Serialization; using System.Diagnostics; @@ -46,8 +31,6 @@ public class StreamWriter : TextWriter private const int DefaultFileStreamBufferSize = 4096; private const int MinBufferSize = 128; - private const Int32 DontCopyOnWriteLineThreshold = 512; - // Bit bucket - Null has no backing store. Non closable. public new static readonly StreamWriter Null = new StreamWriter(Stream.Null, UTF8NoBOM, MinBufferSize, true); @@ -62,12 +45,6 @@ public class StreamWriter : TextWriter private bool haveWrittenPreamble; private bool closable; -#if MDA_SUPPORTED - [NonSerialized] - // For StreamWriterBufferedDataLost MDA - private MdaHelper mdaHelper; -#endif - // We don't guarantee thread safety on StreamWriter, but we should at // least prevent users from trying to write anything while an Async // write from the same thread is in progress. @@ -144,12 +121,10 @@ public StreamWriter(String path, bool append, Encoding encoding) : this(path, append, encoding, DefaultBufferSize) { } - public StreamWriter(String path, bool append, Encoding encoding, int bufferSize): this(path, append, encoding, bufferSize, true) { - } - - internal StreamWriter(String path, bool append, Encoding encoding, int bufferSize, bool checkHost) + public StreamWriter(String path, bool append, Encoding encoding, int bufferSize) : base(null) - { // Ask for CurrentCulture all the time + { + // Ask for CurrentCulture all the time if (path == null) throw new ArgumentNullException(nameof(path)); if (encoding == null) @@ -159,7 +134,7 @@ internal StreamWriter(String path, bool append, Encoding encoding, int bufferSiz if (bufferSize <= 0) throw new ArgumentOutOfRangeException(nameof(bufferSize), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum")); Contract.EndContractBlock(); - Stream stream = CreateFile(path, append, checkHost); + Stream stream = CreateFile(path, append); Init(stream, encoding, bufferSize, false); } @@ -177,20 +152,12 @@ private void Init(Stream streamArg, Encoding encodingArg, int bufferSize, bool s if (stream.CanSeek && stream.Position > 0) haveWrittenPreamble = true; closable = !shouldLeaveOpen; -#if MDA_SUPPORTED - if (Mda.StreamWriterBufferedDataLost.Enabled) { - String callstack = null; - if (Mda.StreamWriterBufferedDataLost.CaptureAllocatedCallStack) - callstack = Environment.GetStackTrace(null, false); - mdaHelper = new MdaHelper(this, callstack); - } -#endif } - private static Stream CreateFile(String path, bool append, bool checkHost) { + private static Stream CreateFile(String path, bool append) { FileMode mode = append? FileMode.Append: FileMode.Create; FileStream f = new FileStream(path, mode, FileAccess.Write, FileShare.Read, - DefaultFileStreamBufferSize, FileOptions.SequentialScan, Path.GetFileName(path), false, false, checkHost); + DefaultFileStreamBufferSize, FileOptions.SequentialScan, Path.GetFileName(path), false, false); return f; } @@ -212,11 +179,6 @@ protected override void Dispose(bool disposing) { CheckAsyncTaskInProgress(); Flush(true, true); -#if MDA_SUPPORTED - // Disable buffered data loss mda - if (mdaHelper != null) - GC.SuppressFinalize(mdaHelper); -#endif } } } @@ -799,42 +761,5 @@ private static async Task FlushAsyncInternal(StreamWriter _this, bool flushStrea await stream.FlushAsync().ConfigureAwait(false); } #endregion - -#if MDA_SUPPORTED - // StreamWriterBufferedDataLost MDA - // Instead of adding a finalizer to StreamWriter for detecting buffered data loss - // (ie, when the user forgets to call Close/Flush on the StreamWriter), we will - // have a separate object with normal finalization semantics that maintains a - // back pointer to this StreamWriter and alerts about any data loss - private sealed class MdaHelper - { - private StreamWriter streamWriter; - private String allocatedCallstack; // captures the callstack when this streamwriter was allocated - - internal MdaHelper(StreamWriter sw, String cs) - { - streamWriter = sw; - allocatedCallstack = cs; - } - - // Finalizer - ~MdaHelper() - { - // Make sure people closed this StreamWriter, exclude StreamWriter::Null. - if (streamWriter.charPos != 0 && streamWriter.stream != null && streamWriter.stream != Stream.Null) { - String fileName = (streamWriter.stream is FileStream) ? ((FileStream)streamWriter.stream).NameInternal : ""; - String callStack = allocatedCallstack; - - if (callStack == null) - callStack = Environment.GetResourceString("IO_StreamWriterBufferedDataLostCaptureAllocatedFromCallstackNotEnabled"); - - String message = Environment.GetResourceString("IO_StreamWriterBufferedDataLost", streamWriter.stream.GetType().FullName, fileName, callStack); - - Mda.StreamWriterBufferedDataLost.ReportError(message); - } - } - } // class MdaHelper -#endif // MDA_SUPPORTED - } // class StreamWriter } // namespace diff --git a/src/mscorlib/src/System/IO/TextReader.cs b/src/mscorlib/src/System/IO/TextReader.cs index ca05fa4f2b42..6cbadfbce5c2 100644 --- a/src/mscorlib/src/System/IO/TextReader.cs +++ b/src/mscorlib/src/System/IO/TextReader.cs @@ -14,11 +14,9 @@ ** ===========================================================*/ -using System; using System.Text; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; -using System.Reflection; using System.Security.Permissions; using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; diff --git a/src/mscorlib/src/System/IO/TextWriter.cs b/src/mscorlib/src/System/IO/TextWriter.cs index 5b460a568390..131f69d35dbc 100644 --- a/src/mscorlib/src/System/IO/TextWriter.cs +++ b/src/mscorlib/src/System/IO/TextWriter.cs @@ -2,24 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -/*============================================================ -** -** -** -** -** -** Purpose: Abstract base class for Text-only Writers. -** Subclasses will include StreamWriter & StringWriter. -** -** -===========================================================*/ - -using System; using System.Text; using System.Threading; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Reflection; using System.Security.Permissions; using System.Globalization; using System.Diagnostics.CodeAnalysis;