📄 internalresources.cs
字号:
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*============================================================
**
** Class: InternalResources
**
** Purpose: Encapsulates and makes internal resources such as
** : Environment.GetResourceString and the internal Error class.
**
** Date: August 2002
**
===========================================================*/
using System.IO;
using System.Security;
using System.Resources;
using System.Globalization;
using System.Collections;
using System.Security.Permissions;
using System.Text;
using System.Configuration.Assemblies;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Diagnostics;
using Microsoft.Win32;
using System.Runtime.CompilerServices;
namespace System.IO.Ports
{
public class InternalResources
{
// static fields from Environment class.
internal static ResourceManager SystemResMgr;
internal static Object m_resMgrLockObject;
internal static bool m_loadingResource;
internal static String GetResourceString(String key)
{
if (SystemResMgr == null)
InitResourceManager();
String s;
// We unfortunately have a somewhat common potential for infinite
// loops with mscorlib's ResourceManager. If "potentially dangerous"
// code throws an exception, we will get into an infinite loop
// inside the ResourceManager and this "potentially dangerous" code.
// Potentially dangerous code includes the IO package, CultureInfo,
// parts of the loader, some parts of Reflection, Security (including
// custom user-written permissions that may parse an XML file at
// class load time), assembly load event handlers, etc. Essentially,
// this is not a bounded set of code, and we need to fix the problem.
// Fortunately, this is limited to mscorlib's error lookups and is NOT
// a general problem for all user code using the ResourceManager.
// The solution is to make sure only one thread at a time can call
// GetResourceString. If the same thread comes into GetResourceString
// twice before returning, we're going into an infinite loop and we
// should return a bogus string.
// @TODO: This is a quick & easy solution, but may not be optimal.
// Note: typeof(Environment) is used elsewhere - don't lock on it.
lock(m_resMgrLockObject)
{
if (m_loadingResource)
{
// This may be bad, depending on how it happens.
return "[Resource lookup failed - infinite recursion detected. Resource name: "+key+']';
}
m_loadingResource = true;
s = SystemResMgr.GetString(key, null);
m_loadingResource = false;
}
return s;
}
internal static String GetResourceString(String key, params Object[]values)
{
if (SystemResMgr == null)
InitResourceManager();
String s;
// We unfortunately have a somewhat common potential for infinite
// loops with mscorlib's ResourceManager. If "potentially dangerous"
// code throws an exception, we will get into an infinite loop
// inside the ResourceManager and this "potentially dangerous" code.
// Potentially dangerous code includes the IO package, CultureInfo,
// parts of the loader, some parts of Reflection, Security (including
// custom user-written permissions that may parse an XML file at
// class load time), assembly load event handlers, etc. Essentially,
// this is not a bounded set of code, and we need to fix the problem.
// Fortunately, this is limited to mscorlib's error lookups and is NOT
// a general problem for all user code using the ResourceManager.
// The solution is to make sure only one thread at a time can call
// GetResourceString. If the same thread comes into GetResourceString
// twice before returning, we're going into an infinite loop and we
// should return a bogus string.
// @TODO: This is a quick & easy solution, but may not be optimal.
// Note: typeof(Environment) is used elsewhere - don't lock on it.
lock(m_resMgrLockObject)
{
if (m_loadingResource)
return "[Resource lookup failed - infinite recursion detected. Resource name: "+key+']';
m_loadingResource = true;
s = SystemResMgr.GetString(key, null);
m_loadingResource = false;
}
return String.Format(s, values);
}
private static ResourceManager InitResourceManager()
{
if (SystemResMgr == null)
{
lock(typeof(Environment))
{
if (SystemResMgr == null)
{
// Do not reorder these two field assignments.
m_resMgrLockObject = new Object();
SystemResMgr = new ResourceManager("mscorlib", typeof(String).Assembly);
}
}
}
return SystemResMgr;
}
// Beginning of static Error methods
internal static void EndOfFile()
{
throw new EndOfStreamException(GetResourceString("IO.EOF_ReadBeyondEOF"));
}
private static String GetMessage(int errorCode)
{
StringBuilder sb = new StringBuilder(512);
int result = SafeNativeMethods.FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
NativeMethods.NULL, errorCode, 0, sb, sb.Capacity, NativeMethods.NULL);
if (result != 0)
{
// result is the # of characters copied to the StringBuilder on NT,
// but on Win9x, it appears to be the number of MBCS bytes.
// Just give up and return the String as-is...
String s = sb.ToString();
return s;
}
else
{
return GetResourceString("IO_UnknownError", errorCode);
}
}
internal static void FileNotOpen()
{
throw new ObjectDisposedException(null, GetResourceString("ObjectDisposed_FileClosed"));
}
internal static void StreamIsClosed()
{
throw new ObjectDisposedException(null, GetResourceString("ObjectDisposed_StreamClosed"));
}
internal static void MemoryStreamNotExpandable()
{
throw new NotSupportedException(GetResourceString("NotSupported_MemStreamNotExpandable"));
}
internal static void ReaderClosed()
{
throw new ObjectDisposedException(null, GetResourceString("ObjectDisposed_ReaderClosed"));
}
internal static void ReadNotSupported()
{
throw new NotSupportedException(GetResourceString("NotSupported_UnreadableStream"));
}
internal static void SeekNotSupported()
{
throw new NotSupportedException(GetResourceString("NotSupported_UnseekableStream"));
}
internal static void WrongAsyncResult()
{
throw new ArgumentException(GetResourceString("Arg_WrongAsyncResult"));
}
internal static void EndReadCalledTwice()
{
throw new InvalidOperationException(GetResourceString("InvalidOperation_EndReadCalledMultiple"));
}
internal static void EndWriteCalledTwice()
{
throw new InvalidOperationException(GetResourceString("InvalidOperation_EndWriteCalledMultiple"));
}
internal static void WinIOError()
{
int errorCode = Marshal.GetLastWin32Error();
WinIOError(errorCode, String.Empty);
}
// After calling GetLastWin32Error(), it clears the last error field,
// so you must save the HResult and pass it to this method. This method
// will determine the appropriate exception to throw dependent on your
// error, and depending on the error, insert a string into the message
// gotten from the ResourceManager.
internal static void WinIOError(int errorCode, String str)
{
switch (errorCode)
{
case NativeMethods.ERROR_FILE_NOT_FOUND:
if (str.Length == 0)
throw new FileNotFoundException(GetResourceString("IO.FileNotFound"));
else
throw new FileNotFoundException(String.Format(GetResourceString("IO.FileNotFound_FileName"), str), str);
case NativeMethods.ERROR_PATH_NOT_FOUND:
if (str.Length == 0)
throw new DirectoryNotFoundException(GetResourceString("IO.PathNotFound_NoPathName"));
else
throw new DirectoryNotFoundException(String.Format(GetResourceString("IO.PathNotFound_Path"), str));
case NativeMethods.ERROR_ACCESS_DENIED:
if (str.Length == 0)
throw new UnauthorizedAccessException(GetResourceString("UnauthorizedAccess_IODenied_NoPathName"));
else
throw new UnauthorizedAccessException(String.Format(GetResourceString("UnauthorizedAccess_IODenied_Path"), str));
case NativeMethods.ERROR_FILENAME_EXCED_RANGE:
throw new PathTooLongException(GetResourceString("IO.PathTooLong"));
case NativeMethods.ERROR_INVALID_PARAMETER:
throw new IOException(GetMessage(errorCode), SafeNativeMethods.MakeHRFromErrorCode(errorCode));
case NativeMethods.ERROR_SHARING_VIOLATION:
// error message.
if (str.Length == 0)
throw new IOException(GetResourceString("IO.IO_SharingViolation_NoFileName"));
else
throw new IOException(GetResourceString("IO.IO_SharingViolation_File", str));
case NativeMethods.ERROR_FILE_EXISTS:
if (str.Length == 0)
goto default;
throw new IOException(String.Format(GetResourceString("IO.IO_FileExists_Name"), str));
default:
throw new IOException(GetMessage(errorCode), SafeNativeMethods.MakeHRFromErrorCode(errorCode));
}
}
internal static void WriteNotSupported()
{
throw new NotSupportedException(GetResourceString("NotSupported_UnwritableStream"));
}
internal static void WriterClosed()
{
throw new ObjectDisposedException(null, GetResourceString("ObjectDisposed_WriterClosed"));
}
private const int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
private const int FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000;
// From WinError.h
internal const int ERROR_FILE_NOT_FOUND = NativeMethods.ERROR_FILE_NOT_FOUND;
internal const int ERROR_PATH_NOT_FOUND = NativeMethods.ERROR_PATH_NOT_FOUND;
internal const int ERROR_ACCESS_DENIED = NativeMethods.ERROR_ACCESS_DENIED;
internal const int ERROR_INVALID_PARAMETER = NativeMethods.ERROR_INVALID_PARAMETER;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -