You've already forked linux-packaging-mono
Imported Upstream version 4.8.0.309
Former-commit-id: 5f9c6ae75f295e057a7d2971f3a6df4656fa8850
This commit is contained in:
parent
ee1447783b
commit
94b2861243
@@ -79,29 +79,21 @@ namespace System.IO {
|
||||
[System.Security.SecurityCritical] // auto-generated
|
||||
internal static String GetDisplayablePath(String path, bool isInvalidPath)
|
||||
{
|
||||
|
||||
if (String.IsNullOrEmpty(path))
|
||||
return String.Empty;
|
||||
|
||||
// Is it a fully qualified path?
|
||||
bool isFullyQualified = false;
|
||||
if (path.Length < 2)
|
||||
return path;
|
||||
if (Path.IsDirectorySeparator(path[0]) && Path.IsDirectorySeparator(path[1]))
|
||||
isFullyQualified = true;
|
||||
else if (path[1] == Path.VolumeSeparatorChar) {
|
||||
isFullyQualified = true;
|
||||
}
|
||||
|
||||
if (!isFullyQualified && !isInvalidPath)
|
||||
// Return the path as is if we're relative (not fully qualified) and not a bad path
|
||||
if (PathInternal.IsPartiallyQualified(path) && !isInvalidPath)
|
||||
return path;
|
||||
|
||||
#if FEATURE_MONO_CAS
|
||||
bool safeToReturn = false;
|
||||
try {
|
||||
if (!isInvalidPath) {
|
||||
#if !FEATURE_CORECLR
|
||||
new FileIOPermission(FileIOPermissionAccess.PathDiscovery, new String[] { path }, false, false).Demand();
|
||||
#if !FEATURE_CORECLR && FEATURE_MONO_CAS
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, path, false, false);
|
||||
#endif
|
||||
safeToReturn = true;
|
||||
}
|
||||
@@ -117,9 +109,7 @@ namespace System.IO {
|
||||
// from Security.Util.StringExpressionSet.CanonicalizePath when ':' is found in the path
|
||||
// beyond string index position 1.
|
||||
}
|
||||
#else
|
||||
bool safeToReturn = !isInvalidPath;
|
||||
#endif // FEATURE_MONO_CAS
|
||||
|
||||
if (!safeToReturn) {
|
||||
if (Path.IsDirectorySeparator(path[path.Length - 1]))
|
||||
path = Environment.GetResourceString("IO.IO_NoPermissionToDirectoryName");
|
||||
|
||||
@@ -382,10 +382,23 @@ namespace System.IO {
|
||||
}
|
||||
|
||||
Contract.Assert(byteBuffer != null, "expected byteBuffer to be non-null");
|
||||
unsafe {
|
||||
fixed (byte* pBytes = byteBuffer)
|
||||
fixed (char* pChars = buffer) {
|
||||
charsRead = m_decoder.GetChars(pBytes + position, numBytes, pChars + index, charsRemaining, false);
|
||||
|
||||
checked {
|
||||
|
||||
if (position < 0 || numBytes < 0 || position + numBytes > byteBuffer.Length) {
|
||||
throw new ArgumentOutOfRangeException("byteCount");
|
||||
}
|
||||
|
||||
if (index < 0 || charsRemaining < 0 || index + charsRemaining > buffer.Length) {
|
||||
throw new ArgumentOutOfRangeException("charsRemaining");
|
||||
}
|
||||
|
||||
unsafe {
|
||||
fixed (byte* pBytes = byteBuffer) {
|
||||
fixed (char* pChars = buffer) {
|
||||
charsRead = m_decoder.GetChars(pBytes + position, numBytes, pChars + index, charsRemaining, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ namespace System.IO {
|
||||
Contract.Assert(_encoding.GetMaxByteCount(1) <= 16, "_encoding.GetMaxByteCount(1) <= 16)");
|
||||
int numBytes = 0;
|
||||
fixed(byte * pBytes = _buffer) {
|
||||
numBytes = _encoder.GetBytes(&ch, 1, pBytes, 16, true);
|
||||
numBytes = _encoder.GetBytes(&ch, 1, pBytes, _buffer.Length, true);
|
||||
}
|
||||
OutStream.Write(_buffer, 0, numBytes);
|
||||
}
|
||||
@@ -371,10 +371,10 @@ namespace System.IO {
|
||||
|
||||
if (_largeByteBuffer == null) {
|
||||
_largeByteBuffer = new byte[LargeByteBufferSize];
|
||||
_maxChars = LargeByteBufferSize / _encoding.GetMaxByteCount(1);
|
||||
_maxChars = _largeByteBuffer.Length / _encoding.GetMaxByteCount(1);
|
||||
}
|
||||
|
||||
if (len <= LargeByteBufferSize) {
|
||||
if (len <= _largeByteBuffer.Length) {
|
||||
//Contract.Assert(len == _encoding.GetBytes(chars, 0, chars.Length, _largeByteBuffer, 0), "encoding's GetByteCount & GetBytes gave different answers! encoding type: "+_encoding.GetType().Name);
|
||||
_encoding.GetBytes(value, 0, value.Length, _largeByteBuffer, 0);
|
||||
OutStream.Write(_largeByteBuffer, 0, len);
|
||||
@@ -393,14 +393,21 @@ namespace System.IO {
|
||||
// Figure out how many chars to process this round.
|
||||
int charCount = (numLeft > _maxChars) ? _maxChars : numLeft;
|
||||
int byteLen;
|
||||
fixed(char* pChars = value) {
|
||||
fixed(byte* pBytes = _largeByteBuffer) {
|
||||
byteLen = _encoder.GetBytes(pChars + charStart, charCount, pBytes, LargeByteBufferSize, charCount == numLeft);
|
||||
|
||||
checked {
|
||||
if (charStart < 0 || charCount < 0 || charStart + charCount > value.Length) {
|
||||
throw new ArgumentOutOfRangeException("charCount");
|
||||
}
|
||||
|
||||
fixed(char* pChars = value) {
|
||||
fixed(byte* pBytes = _largeByteBuffer) {
|
||||
byteLen = _encoder.GetBytes(pChars + charStart, charCount, pBytes, _largeByteBuffer.Length, charCount == numLeft);
|
||||
}
|
||||
}
|
||||
}
|
||||
#if _DEBUG
|
||||
totalBytes += byteLen;
|
||||
Contract.Assert (totalBytes <= len && byteLen <= LargeByteBufferSize, "BinaryWriter::Write(String) - More bytes encoded than expected!");
|
||||
Contract.Assert (totalBytes <= len && byteLen <= _largeByteBuffer.Length, "BinaryWriter::Write(String) - More bytes encoded than expected!");
|
||||
#endif
|
||||
OutStream.Write(_largeByteBuffer, 0, byteLen);
|
||||
charStart += charCount;
|
||||
|
||||
@@ -248,17 +248,25 @@ namespace System.IO {
|
||||
|
||||
int count = stackDir.Count;
|
||||
|
||||
if (stackDir.Count != 0)
|
||||
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];
|
||||
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_PAL && FEATURE_MACL
|
||||
#if !FEATURE_PAL && FEATURE_MACL
|
||||
AccessControlActions control = (dirSecurity == null) ? AccessControlActions.None : AccessControlActions.Change;
|
||||
new FileIOPermission(FileIOPermissionAccess.Write, control, securityList, false, false ).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, control, securityList, false, false);
|
||||
#else
|
||||
#if FEATURE_CORECLR
|
||||
if (checkHost)
|
||||
@@ -270,7 +278,7 @@ namespace System.IO {
|
||||
}
|
||||
}
|
||||
#else
|
||||
new FileIOPermission(FileIOPermissionAccess.Write, securityList, false, false ).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, securityList, false, false );
|
||||
#endif
|
||||
#endif //!FEATURE_PAL && FEATURE_MACL
|
||||
}
|
||||
@@ -298,8 +306,9 @@ namespace System.IO {
|
||||
while (stackDir.Count > 0) {
|
||||
String name = stackDir[stackDir.Count - 1];
|
||||
stackDir.RemoveAt(stackDir.Count - 1);
|
||||
if (name.Length >= Path.MAX_DIRECTORY_PATH)
|
||||
if (PathInternal.IsDirectoryTooLong(name))
|
||||
throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
|
||||
|
||||
r = Win32Native.CreateDirectory(name, secAttrs);
|
||||
if (!r && (firstError == 0)) {
|
||||
int currentError = Marshal.GetLastWin32Error();
|
||||
@@ -326,7 +335,7 @@ namespace System.IO {
|
||||
state.EnsureState();
|
||||
}
|
||||
#else
|
||||
new FileIOPermission(FileIOPermissionAccess.PathDiscovery, GetDemandDir(name, true)).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, GetDemandDir(name, true));
|
||||
#endif // FEATURE_CORECLR
|
||||
errorString = name;
|
||||
}
|
||||
@@ -1085,36 +1094,14 @@ namespace System.IO {
|
||||
return InternalGetCurrentDirectory(false);
|
||||
}
|
||||
|
||||
[System.Security.SecurityCritical]
|
||||
[System.Security.SecuritySafeCritical]
|
||||
[ResourceExposure(ResourceScope.Machine)]
|
||||
[ResourceConsumption(ResourceScope.Machine)]
|
||||
private static String InternalGetCurrentDirectory(bool checkHost)
|
||||
private static string InternalGetCurrentDirectory(bool checkHost)
|
||||
{
|
||||
StringBuilder sb = StringBuilderCache.Acquire(Path.MAX_PATH + 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.MAX_PATH) {
|
||||
int errorCode = Marshal.GetLastWin32Error();
|
||||
if (r >= Path.MAX_PATH)
|
||||
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);
|
||||
string currentDirectory = AppContextSwitches.UseLegacyPathHandling ? LegacyGetCurrentDirectory() : NewGetCurrentDirectory();
|
||||
string demandPath = GetDemandDir(currentDirectory, true);
|
||||
|
||||
|
||||
#if FEATURE_CORECLR
|
||||
if (checkHost)
|
||||
{
|
||||
@@ -1122,11 +1109,72 @@ namespace System.IO {
|
||||
state.EnsureState();
|
||||
}
|
||||
#else
|
||||
new FileIOPermission( FileIOPermissionAccess.PathDiscovery, new String[] { demandPath }, false, false ).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, demandPath, false, false);
|
||||
#endif
|
||||
return currentDirectory;
|
||||
}
|
||||
|
||||
[System.Security.SecurityCritical]
|
||||
[ResourceExposure(ResourceScope.Machine)]
|
||||
[ResourceConsumption(ResourceScope.Machine)]
|
||||
private static string LegacyGetCurrentDirectory()
|
||||
{
|
||||
StringBuilder sb = StringBuilderCache.Acquire(PathInternal.MaxShortPath + 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 >= PathInternal.MaxShortPath)
|
||||
{
|
||||
int errorCode = Marshal.GetLastWin32Error();
|
||||
if (r >= PathInternal.MaxShortPath)
|
||||
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);
|
||||
return currentDirectory;
|
||||
}
|
||||
|
||||
[System.Security.SecurityCritical]
|
||||
[ResourceExposure(ResourceScope.Machine)]
|
||||
[ResourceConsumption(ResourceScope.Machine)]
|
||||
private static string NewGetCurrentDirectory()
|
||||
{
|
||||
using (StringBuffer buffer = new StringBuffer(PathInternal.MaxShortPath))
|
||||
{
|
||||
uint result = 0;
|
||||
while ((result = Win32Native.GetCurrentDirectoryW(buffer.CharCapacity, buffer.GetHandle())) > buffer.CharCapacity)
|
||||
{
|
||||
// Reported size is greater than the buffer size. Increase the capacity.
|
||||
// The size returned includes the null only if more space is needed (this case).
|
||||
buffer.EnsureCharCapacity(result);
|
||||
}
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
__Error.WinIOError();
|
||||
}
|
||||
|
||||
buffer.Length = result;
|
||||
if (buffer.Contains('~'))
|
||||
{
|
||||
return LongPathHelper.GetLongPathName(buffer);
|
||||
}
|
||||
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
#if FEATURE_CORECLR
|
||||
[System.Security.SecurityCritical] // auto-generated
|
||||
@@ -1136,15 +1184,16 @@ namespace System.IO {
|
||||
[ResourceExposure(ResourceScope.Machine)]
|
||||
[ResourceConsumption(ResourceScope.Machine)]
|
||||
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.MAX_PATH)
|
||||
|
||||
if (PathInternal.IsPathTooLong(path))
|
||||
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
|
||||
@@ -1174,19 +1223,19 @@ namespace System.IO {
|
||||
[System.Security.SecurityCritical]
|
||||
[ResourceExposure(ResourceScope.Machine)]
|
||||
[ResourceConsumption(ResourceScope.Machine)]
|
||||
internal static void UnsafeMove(String sourceDirName,String destDirName) {
|
||||
internal static void UnsafeMove(String sourceDirName, String destDirName) {
|
||||
InternalMove(sourceDirName, destDirName, false);
|
||||
}
|
||||
|
||||
[System.Security.SecurityCritical]
|
||||
[ResourceExposure(ResourceScope.Machine)]
|
||||
[ResourceConsumption(ResourceScope.Machine)]
|
||||
private static void InternalMove(String sourceDirName,String destDirName,bool checkHost) {
|
||||
private static void InternalMove(String sourceDirName, String destDirName, bool checkHost) {
|
||||
if (sourceDirName==null)
|
||||
throw new ArgumentNullException("sourceDirName");
|
||||
if (sourceDirName.Length==0)
|
||||
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "sourceDirName");
|
||||
|
||||
|
||||
if (destDirName==null)
|
||||
throw new ArgumentNullException("destDirName");
|
||||
if (destDirName.Length==0)
|
||||
@@ -1195,16 +1244,16 @@ namespace System.IO {
|
||||
|
||||
String fullsourceDirName = Path.GetFullPathInternal(sourceDirName);
|
||||
String sourcePath = GetDemandDir(fullsourceDirName, false);
|
||||
|
||||
if (sourcePath.Length >= Path.MAX_DIRECTORY_PATH)
|
||||
|
||||
if (PathInternal.IsDirectoryTooLong(sourcePath))
|
||||
throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
|
||||
|
||||
String fulldestDirName = Path.GetFullPathInternal(destDirName);
|
||||
String destPath = GetDemandDir(fulldestDirName, false);
|
||||
|
||||
if (destPath.Length >= Path.MAX_DIRECTORY_PATH)
|
||||
if (PathInternal.IsDirectoryTooLong(sourcePath))
|
||||
throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
|
||||
|
||||
|
||||
#if FEATURE_CORECLR
|
||||
if (checkHost) {
|
||||
FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Write | FileSecurityStateAccess.Read, sourceDirName, sourcePath);
|
||||
@@ -1288,7 +1337,7 @@ namespace System.IO {
|
||||
}
|
||||
#else
|
||||
// Make sure we have write permission to this directory
|
||||
new FileIOPermission(FileIOPermissionAccess.Write, new String[] { demandPath }, false, false ).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, demandPath, false, false);
|
||||
#endif
|
||||
|
||||
// Do not recursively delete through reparse points. Perhaps in a
|
||||
|
||||
@@ -102,7 +102,7 @@ namespace System.IO {
|
||||
state.EnsureState();
|
||||
}
|
||||
#else
|
||||
new FileIOPermission(FileIOPermissionAccess.Read, demandDir, false, false ).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, demandDir, false, false);
|
||||
#endif
|
||||
|
||||
FullPath = fullPath;
|
||||
@@ -130,7 +130,7 @@ namespace System.IO {
|
||||
{
|
||||
#if !FEATURE_CORECLR
|
||||
demandDir = new String[] {Directory.GetDemandDir(FullPath, true)};
|
||||
new FileIOPermission(FileIOPermissionAccess.Read, demandDir, false, false ).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, demandDir, false, false );
|
||||
#endif
|
||||
DisplayPath = GetDisplayName(OriginalPath, FullPath);
|
||||
}
|
||||
@@ -169,7 +169,7 @@ namespace System.IO {
|
||||
FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery | FileSecurityStateAccess.Read, String.Empty, dir.demandDir[0]);
|
||||
state.EnsureState();
|
||||
#else
|
||||
new FileIOPermission(FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read, dir.demandDir, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read, dir.demandDir, false, false);
|
||||
#endif
|
||||
return dir;
|
||||
}
|
||||
@@ -234,7 +234,7 @@ namespace System.IO {
|
||||
FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Write, OriginalPath, demandDirForCreation);
|
||||
state.EnsureState();
|
||||
#else
|
||||
new FileIOPermission(FileIOPermissionAccess.Write, new String[] { demandDirForCreation }, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, demandDirForCreation, false, false);
|
||||
#endif
|
||||
|
||||
Directory.InternalCreateDirectory(fullPath, path, directorySecurity);
|
||||
@@ -609,7 +609,7 @@ namespace System.IO {
|
||||
FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandPath);
|
||||
sourceState.EnsureState();
|
||||
#else
|
||||
new FileIOPermission(FileIOPermissionAccess.PathDiscovery, new String[] { demandPath }, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, demandPath, false, false);
|
||||
#endif
|
||||
return new DirectoryInfo(rootPath);
|
||||
}
|
||||
@@ -629,7 +629,7 @@ namespace System.IO {
|
||||
FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Write | FileSecurityStateAccess.Read, DisplayPath, Directory.GetDemandDir(FullPath, true));
|
||||
sourceState.EnsureState();
|
||||
#else
|
||||
new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, demandDir, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, demandDir, false, false);
|
||||
#endif
|
||||
String fullDestDirName = Path.GetFullPathInternal(destDirName);
|
||||
String demandPath;
|
||||
@@ -648,9 +648,9 @@ namespace System.IO {
|
||||
FileSecurityState destState = new FileSecurityState(FileSecurityStateAccess.Write, destDirName, demandPath);
|
||||
destState.EnsureState();
|
||||
#else
|
||||
new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, demandPath).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, demandPath);
|
||||
#endif
|
||||
|
||||
|
||||
String fullSourcePath;
|
||||
if (FullPath.EndsWith(Path.DirectorySeparatorChar))
|
||||
fullSourcePath = FullPath;
|
||||
|
||||
@@ -1322,10 +1322,23 @@ namespace System.IO {
|
||||
destState.EnsureState();
|
||||
backupState.EnsureState();
|
||||
#else
|
||||
FileIOPermission perm = new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.Write, new String[] { fullSrcPath, fullDestPath});
|
||||
if (destinationBackupFileName != null)
|
||||
perm.AddPathList(FileIOPermissionAccess.Write, fullBackupPath);
|
||||
perm.Demand();
|
||||
#if FEATURE_CAS_POLICY
|
||||
// All demands in full trust domains are no-ops, just do additional checks
|
||||
if (CodeAccessSecurityEngine.QuickCheckForAllDemands())
|
||||
{
|
||||
FileIOPermission.EmulateFileIOPermissionChecks(fullSrcPath);
|
||||
FileIOPermission.EmulateFileIOPermissionChecks(fullDestPath);
|
||||
if (fullBackupPath != null)
|
||||
FileIOPermission.EmulateFileIOPermissionChecks(fullBackupPath);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
FileIOPermission perm = new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.Write, new String[] { fullSrcPath, fullDestPath });
|
||||
if (fullBackupPath != null)
|
||||
perm.AddPathList(FileIOPermissionAccess.Write, fullBackupPath);
|
||||
perm.Demand();
|
||||
}
|
||||
#endif
|
||||
|
||||
int flags = Win32Native.REPLACEFILE_WRITE_THROUGH;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
===========================================================*/
|
||||
|
||||
using System;
|
||||
#if FEATURE_MACL
|
||||
#if FEATURE_MACL || MONO
|
||||
using System.Security.AccessControl;
|
||||
#endif
|
||||
using System.Security.Permissions;
|
||||
@@ -132,7 +132,7 @@ namespace System.IO {
|
||||
{
|
||||
#if FEATURE_MONO_CAS
|
||||
#if !FEATURE_CORECLR
|
||||
new FileIOPermission(FileIOPermissionAccess.Read, new String[] { FullPath }, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, FullPath, false, false);
|
||||
#endif
|
||||
#endif
|
||||
_name = Path.GetFileName(OriginalPath);
|
||||
@@ -192,7 +192,7 @@ namespace System.IO {
|
||||
FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, DisplayPath, FullPath);
|
||||
state.EnsureState();
|
||||
#else
|
||||
new FileIOPermission(FileIOPermissionAccess.PathDiscovery, new String[] { directoryName }, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, directoryName, false, false);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
@@ -226,7 +226,7 @@ namespace System.IO {
|
||||
}
|
||||
}
|
||||
|
||||
#if FEATURE_MACL
|
||||
#if FEATURE_MACL || MONO
|
||||
[ResourceExposure(ResourceScope.None)]
|
||||
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
|
||||
public FileSecurity GetAccessControl()
|
||||
@@ -344,7 +344,7 @@ namespace System.IO {
|
||||
state.EnsureState();
|
||||
#else
|
||||
// For security check, path should be resolved to an absolute path.
|
||||
new FileIOPermission(FileIOPermissionAccess.Write, new String[] { FullPath }, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, FullPath, false, false);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -483,7 +483,7 @@ namespace System.IO {
|
||||
sourceState.EnsureState();
|
||||
destState.EnsureState();
|
||||
#else
|
||||
new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, new String[] { FullPath }, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, FullPath, false, false);
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, fullDestFileName, false, false);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1 +1 @@
|
||||
38b86735241ea07f3ab33268fed4980d92d915dd
|
||||
7e47b8bedeccb5022eb808e71cc10b40a7e730eb
|
||||
@@ -234,7 +234,7 @@ namespace System.IO
|
||||
state2.EnsureState();
|
||||
}
|
||||
#else
|
||||
new FileIOPermission(FileIOPermissionAccess.PathDiscovery, demandPaths, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, demandPaths, false, false);
|
||||
#endif
|
||||
|
||||
// normalize search criteria
|
||||
@@ -340,7 +340,7 @@ namespace System.IO
|
||||
state2.EnsureState();
|
||||
}
|
||||
#else
|
||||
new FileIOPermission(FileIOPermissionAccess.PathDiscovery, demandPaths, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, demandPaths, false, false);
|
||||
#endif
|
||||
searchData = new Directory.SearchData(normalizedSearchPath, userPath, searchOption);
|
||||
CommonInit();
|
||||
@@ -591,8 +591,7 @@ namespace System.IO
|
||||
}
|
||||
#else
|
||||
String demandDir = Directory.GetDemandDir(fullPathToDemand, true);
|
||||
String[] demandPaths = new String[] { demandDir };
|
||||
new FileIOPermission(FileIOPermissionAccess.PathDiscovery, demandPaths, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, demandDir, false, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -706,8 +705,7 @@ namespace System.IO
|
||||
FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, name);
|
||||
state.EnsureState();
|
||||
#else
|
||||
String[] names = new String[] { name };
|
||||
new FileIOPermission(FileIOPermissionAccess.Read, names, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, name, false, false);
|
||||
#endif
|
||||
FileInfo fi = new FileInfo(name, false);
|
||||
fi.InitializeFrom(result.FindData);
|
||||
@@ -733,8 +731,7 @@ namespace System.IO
|
||||
FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, permissionName);
|
||||
state.EnsureState();
|
||||
#else
|
||||
String[] permissionNames = new String[] { permissionName };
|
||||
new FileIOPermission(FileIOPermissionAccess.Read, permissionNames, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, permissionName, false, false);
|
||||
#endif
|
||||
DirectoryInfo di = new DirectoryInfo(name, false);
|
||||
di.InitializeFrom(result.FindData);
|
||||
@@ -770,8 +767,7 @@ namespace System.IO
|
||||
FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, permissionName);
|
||||
state.EnsureState();
|
||||
#else
|
||||
String[] permissionNames = new String[] { permissionName };
|
||||
new FileIOPermission(FileIOPermissionAccess.Read, permissionNames, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, permissionName, false, false);
|
||||
#endif
|
||||
DirectoryInfo di = new DirectoryInfo(name, false);
|
||||
di.InitializeFrom(result.FindData);
|
||||
@@ -786,8 +782,7 @@ namespace System.IO
|
||||
FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, name);
|
||||
state.EnsureState();
|
||||
#else
|
||||
String[] names = new String[] { name };
|
||||
new FileIOPermission(FileIOPermissionAccess.Read, names, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, name, false, false);
|
||||
#endif
|
||||
FileInfo fi = new FileInfo(name, false);
|
||||
fi.InitializeFrom(result.FindData);
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace System.IO {
|
||||
[FileIOPermissionAttribute(SecurityAction.InheritanceDemand,Unrestricted=true)]
|
||||
#endif
|
||||
[ComVisible(true)]
|
||||
#if FEATURE_REMOTING
|
||||
#if FEATURE_REMOTING || MONO
|
||||
public abstract class FileSystemInfo : MarshalByRefObject, ISerializable {
|
||||
#else // FEATURE_REMOTING
|
||||
public abstract class FileSystemInfo : ISerializable {
|
||||
@@ -107,7 +107,7 @@ namespace System.IO {
|
||||
FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandDir);
|
||||
sourceState.EnsureState();
|
||||
#else
|
||||
new FileIOPermission(FileIOPermissionAccess.PathDiscovery, demandDir).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, demandDir);
|
||||
#endif
|
||||
#endif
|
||||
return FullPath;
|
||||
@@ -126,7 +126,7 @@ namespace System.IO {
|
||||
demandDir = FullPath;
|
||||
#if FEATURE_MONO_CAS
|
||||
#if !FEATURE_CORECLR
|
||||
new FileIOPermission(FileIOPermissionAccess.PathDiscovery, demandDir).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, demandDir);
|
||||
#endif
|
||||
#endif
|
||||
return FullPath;
|
||||
@@ -353,7 +353,7 @@ namespace System.IO {
|
||||
set {
|
||||
#if FEATURE_MONO_CAS
|
||||
#if !FEATURE_CORECLR
|
||||
new FileIOPermission(FileIOPermissionAccess.Write, FullPath).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, FullPath);
|
||||
#endif
|
||||
#endif
|
||||
#if MONO
|
||||
@@ -386,7 +386,7 @@ namespace System.IO {
|
||||
{
|
||||
#if FEATURE_MONO_CAS
|
||||
#if !FEATURE_CORECLR
|
||||
new FileIOPermission(FileIOPermissionAccess.PathDiscovery, FullPath).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, FullPath);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -195,9 +195,9 @@ namespace System.IO {
|
||||
Contract.Requires(destFileName.Length > 0);
|
||||
|
||||
String fullSourceFileName = LongPath.NormalizePath(sourceFileName);
|
||||
new FileIOPermission(FileIOPermissionAccess.Read, new String[] { fullSourceFileName }, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, fullSourceFileName, false, false);
|
||||
String fullDestFileName = LongPath.NormalizePath(destFileName);
|
||||
new FileIOPermission(FileIOPermissionAccess.Write, new String[] { fullDestFileName }, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, fullDestFileName, false, false);
|
||||
|
||||
InternalCopy(fullSourceFileName, fullDestFileName, sourceFileName, destFileName, overwrite);
|
||||
}
|
||||
@@ -258,7 +258,7 @@ namespace System.IO {
|
||||
String fullPath = LongPath.NormalizePath(path);
|
||||
|
||||
// For security check, path should be resolved to an absolute path.
|
||||
new FileIOPermission(FileIOPermissionAccess.Write, new String[] { fullPath }, false, false ).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, fullPath, false, false);
|
||||
|
||||
String tempPath = Path.AddLongPathPrefix(fullPath);
|
||||
bool r = Win32Native.DeleteFile(tempPath);
|
||||
@@ -297,8 +297,8 @@ namespace System.IO {
|
||||
if (path.Length > 0 && Path.IsDirectorySeparator(path[path.Length - 1])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
new FileIOPermission(FileIOPermissionAccess.Read, new String[] { path }, false, false ).Demand();
|
||||
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, path, false, false );
|
||||
|
||||
return InternalExists(path);
|
||||
}
|
||||
@@ -326,7 +326,7 @@ namespace System.IO {
|
||||
Contract.Requires(path != null);
|
||||
|
||||
String fullPath = LongPath.NormalizePath(path);
|
||||
new FileIOPermission(FileIOPermissionAccess.Read, new String[] { fullPath }, false, false ).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, fullPath, false, false);
|
||||
|
||||
String tempPath = Path.AddLongPathPrefix(fullPath);
|
||||
|
||||
@@ -348,7 +348,7 @@ namespace System.IO {
|
||||
Contract.Requires(path != null);
|
||||
|
||||
String fullPath = LongPath.NormalizePath(path);
|
||||
new FileIOPermission(FileIOPermissionAccess.Read, new String[] { fullPath }, false, false ).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, fullPath, false, false);
|
||||
|
||||
String tempPath = Path.AddLongPathPrefix(fullPath);
|
||||
Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
|
||||
@@ -369,7 +369,7 @@ namespace System.IO {
|
||||
Contract.Requires(path != null);
|
||||
|
||||
String fullPath = LongPath.NormalizePath(path);
|
||||
new FileIOPermission(FileIOPermissionAccess.Read, new String[] { fullPath }, false, false ).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, fullPath, false, false);
|
||||
|
||||
String tempPath = Path.AddLongPathPrefix(fullPath);
|
||||
Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
|
||||
@@ -400,9 +400,9 @@ namespace System.IO {
|
||||
Contract.Requires(destFileName.Length > 0);
|
||||
|
||||
String fullSourceFileName = LongPath.NormalizePath(sourceFileName);
|
||||
new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, new String[] { fullSourceFileName }, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, fullSourceFileName, false, false);
|
||||
String fullDestFileName = LongPath.NormalizePath(destFileName);
|
||||
new FileIOPermission(FileIOPermissionAccess.Write, new String[] { fullDestFileName }, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, fullDestFileName, false, false);
|
||||
|
||||
if (!LongPathFile.InternalExists(fullSourceFileName))
|
||||
__Error.WinIOError(Win32Native.ERROR_FILE_NOT_FOUND, fullSourceFileName);
|
||||
@@ -423,7 +423,7 @@ namespace System.IO {
|
||||
Contract.Requires(path != null);
|
||||
|
||||
String fullPath = LongPath.NormalizePath(path);
|
||||
new FileIOPermission(FileIOPermissionAccess.Read, new String[] { fullPath }, false, false ).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, fullPath, false, false);
|
||||
|
||||
String tempPath = Path.AddLongPathPrefix(fullPath);
|
||||
Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
|
||||
@@ -435,7 +435,6 @@ namespace System.IO {
|
||||
__Error.WinIOError(Win32Native.ERROR_FILE_NOT_FOUND, path);
|
||||
|
||||
return ((long)data.fileSizeHigh) << 32 | ((long)data.fileSizeLow & 0xFFFFFFFFL);
|
||||
|
||||
}
|
||||
|
||||
// Defined in WinError.h
|
||||
@@ -460,7 +459,7 @@ namespace System.IO {
|
||||
// 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);
|
||||
new FileIOPermission(FileIOPermissionAccess.Read, new String[] { demandDir }, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, demandDir, false, false);
|
||||
|
||||
InternalCreateDirectory(fullPath, path, null);
|
||||
}
|
||||
@@ -514,7 +513,15 @@ namespace System.IO {
|
||||
|
||||
int count = stackDir.Count;
|
||||
|
||||
if (stackDir.Count != 0)
|
||||
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);
|
||||
@@ -524,9 +531,9 @@ namespace System.IO {
|
||||
// Security check for all directories not present only.
|
||||
#if !FEATURE_PAL && FEATURE_MACL
|
||||
AccessControlActions control = (dirSecurity == null) ? AccessControlActions.None : AccessControlActions.Change;
|
||||
new FileIOPermission(FileIOPermissionAccess.Write, control, securityList, false, false ).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, control, securityList, false, false);
|
||||
#else
|
||||
new FileIOPermission(FileIOPermissionAccess.Write, securityList, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, securityList, false, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -554,9 +561,11 @@ namespace System.IO {
|
||||
{
|
||||
String name = stackDir[stackDir.Count - 1];
|
||||
stackDir.RemoveAt(stackDir.Count - 1);
|
||||
|
||||
if (name.Length >= Path.MaxLongPath)
|
||||
throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
|
||||
r = Win32Native.CreateDirectory(Path.AddLongPathPrefix(name), secAttrs);
|
||||
|
||||
r = Win32Native.CreateDirectory(PathInternal.EnsureExtendedPrefix(name), secAttrs);
|
||||
if (!r && (firstError == 0))
|
||||
{
|
||||
int currentError = Marshal.GetLastWin32Error();
|
||||
@@ -579,7 +588,7 @@ namespace System.IO {
|
||||
// Give the user a nice error message, but don't leak path information.
|
||||
try
|
||||
{
|
||||
new FileIOPermission(FileIOPermissionAccess.PathDiscovery, new String[] { GetDemandDir(name, true) }, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, GetDemandDir(name, true), false, false);
|
||||
errorString = name;
|
||||
}
|
||||
catch (SecurityException) { }
|
||||
@@ -631,8 +640,8 @@ namespace System.IO {
|
||||
if (destPath.Length >= Path.MaxLongPath)
|
||||
throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
|
||||
|
||||
new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, new String[] { sourcePath }, false, false).Demand();
|
||||
new FileIOPermission(FileIOPermissionAccess.Write, new String[] { destPath }, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, sourcePath, false, false);
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, destPath, false, false);
|
||||
|
||||
if (String.Compare(sourcePath, destPath, StringComparison.OrdinalIgnoreCase) == 0)
|
||||
throw new IOException(Environment.GetResourceString("IO.IO_SourceDestMustBeDifferent"));
|
||||
@@ -643,8 +652,8 @@ namespace System.IO {
|
||||
throw new IOException(Environment.GetResourceString("IO.IO_SourceDestMustHaveSameRoot"));
|
||||
|
||||
|
||||
String tempSourceDirName = Path.AddLongPathPrefix(sourceDirName);
|
||||
String tempDestDirName = Path.AddLongPathPrefix(destDirName);
|
||||
String tempSourceDirName = PathInternal.EnsureExtendedPrefix(sourceDirName);
|
||||
String tempDestDirName = PathInternal.EnsureExtendedPrefix(destDirName);
|
||||
|
||||
if (!Win32Native.MoveFile(tempSourceDirName, tempDestDirName))
|
||||
{
|
||||
@@ -683,7 +692,7 @@ namespace System.IO {
|
||||
demandPath = GetDemandDir(fullPath, !recursive);
|
||||
|
||||
// Make sure we have write permission to this directory
|
||||
new FileIOPermission(FileIOPermissionAccess.Write, new String[] { demandPath }, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, demandPath, false, false);
|
||||
|
||||
String longPath = Path.AddLongPathPrefix(fullPath);
|
||||
// Do not recursively delete through reparse points. Perhaps in a
|
||||
@@ -904,7 +913,7 @@ namespace System.IO {
|
||||
String fullPath = LongPath.NormalizePath(path);
|
||||
String demandPath = GetDemandDir(fullPath, true);
|
||||
|
||||
new FileIOPermission(FileIOPermissionAccess.Read, new String[] { demandPath }, false, false).Demand();
|
||||
FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, demandPath, false, false);
|
||||
|
||||
return InternalExists(fullPath);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,7 +39,7 @@ namespace System.IO {
|
||||
#if CONTRACTS_FULL
|
||||
[ContractClass(typeof(StreamContract))]
|
||||
#endif
|
||||
#if FEATURE_REMOTING
|
||||
#if FEATURE_REMOTING || MONO
|
||||
public abstract class Stream : MarshalByRefObject, IDisposable {
|
||||
#else // FEATURE_REMOTING
|
||||
public abstract class Stream : IDisposable {
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace System.IO {
|
||||
// There are methods on the Stream class for reading bytes.
|
||||
[Serializable]
|
||||
[ComVisible(true)]
|
||||
#if FEATURE_REMOTING
|
||||
#if FEATURE_REMOTING || MONO
|
||||
public abstract class TextReader : MarshalByRefObject, IDisposable {
|
||||
#else // FEATURE_REMOTING
|
||||
public abstract class TextReader : IDisposable {
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace System.IO {
|
||||
// There are methods on the Stream class for writing bytes.
|
||||
[Serializable]
|
||||
[ComVisible(true)]
|
||||
#if FEATURE_REMOTING
|
||||
#if FEATURE_REMOTING || MONO
|
||||
public abstract class TextWriter : MarshalByRefObject, IDisposable {
|
||||
#else // FEATURE_REMOTING
|
||||
public abstract class TextWriter : IDisposable {
|
||||
|
||||
Reference in New Issue
Block a user