3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 /*============================================================
10 ** <OWNER>Microsoft</OWNER>
13 ** Purpose: Centralized error methods for the IO package.
14 ** Mostly useful for translating Win32 HRESULTs into meaningful
15 ** error strings & exceptions.
18 ===========================================================*/
21 using System.Runtime.InteropServices;
22 using Win32Native = Microsoft.Win32.Win32Native;
24 using System.Globalization;
25 using System.Security;
26 using System.Security.Permissions;
27 using System.Diagnostics.Contracts;
31 internal static class __Error
33 internal static void EndOfFile() {
34 throw new EndOfStreamException(Environment.GetResourceString("IO.EOF_ReadBeyondEOF"));
37 internal static void FileNotOpen() {
38 throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_FileClosed"));
41 internal static void StreamIsClosed() {
42 throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_StreamClosed"));
45 internal static void MemoryStreamNotExpandable() {
46 throw new NotSupportedException(Environment.GetResourceString("NotSupported_MemStreamNotExpandable"));
49 internal static void ReaderClosed() {
50 throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_ReaderClosed"));
53 internal static void ReadNotSupported() {
54 throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnreadableStream"));
57 internal static void SeekNotSupported() {
58 throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnseekableStream"));
61 internal static void WrongAsyncResult() {
62 throw new ArgumentException(Environment.GetResourceString("Arg_WrongAsyncResult"));
65 internal static void EndReadCalledTwice() {
66 // Should ideally be InvalidOperationExc but we can't maitain parity with Stream and FileStream without some work
67 throw new ArgumentException(Environment.GetResourceString("InvalidOperation_EndReadCalledMultiple"));
70 internal static void EndWriteCalledTwice() {
71 // Should ideally be InvalidOperationExc but we can't maintain parity with Stream and FileStream without some work
72 throw new ArgumentException(Environment.GetResourceString("InvalidOperation_EndWriteCalledMultiple"));
75 // Given a possible fully qualified path, ensure that we have path
76 // discovery permission to that path. If we do not, return just the
77 // file name. If we know it is a directory, then don't return the
79 [System.Security.SecurityCritical] // auto-generated
80 internal static String GetDisplayablePath(String path, bool isInvalidPath)
82 if (String.IsNullOrEmpty(path))
88 // Return the path as is if we're relative (not fully qualified) and not a bad path
89 if (PathInternal.IsPartiallyQualified(path) && !isInvalidPath)
92 bool safeToReturn = false;
95 #if !FEATURE_CORECLR && MONO_FEATURE_CAS
96 FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, path, false, false);
101 catch (SecurityException) {
103 catch (ArgumentException) {
104 // ? and * characters cause ArgumentException to be thrown from HasIllegalCharacters
105 // inside FileIOPermission.AddPathList
107 catch (NotSupportedException) {
108 // paths like "!Bogus\\dir:with/junk_.in it" can cause NotSupportedException to be thrown
109 // from Security.Util.StringExpressionSet.CanonicalizePath when ':' is found in the path
110 // beyond string index position 1.
114 if (Path.IsDirectorySeparator(path[path.Length - 1]))
115 path = Environment.GetResourceString("IO.IO_NoPermissionToDirectoryName");
117 path = Path.GetFileName(path);
123 [System.Security.SecuritySafeCritical] // auto-generated
124 internal static void WinIOError() {
125 int errorCode = Marshal.GetLastWin32Error();
126 WinIOError(errorCode, String.Empty);
129 // After calling GetLastWin32Error(), it clears the last error field,
130 // so you must save the HResult and pass it to this method. This method
131 // will determine the appropriate exception to throw dependent on your
132 // error, and depending on the error, insert a string into the message
133 // gotten from the ResourceManager.
134 [System.Security.SecurityCritical] // auto-generated
135 internal static void WinIOError(int errorCode, String maybeFullPath) {
136 // This doesn't have to be perfect, but is a perf optimization.
137 bool isInvalidPath = errorCode == Win32Native.ERROR_INVALID_NAME || errorCode == Win32Native.ERROR_BAD_PATHNAME;
138 String str = GetDisplayablePath(maybeFullPath, isInvalidPath);
141 case Win32Native.ERROR_FILE_NOT_FOUND:
143 throw new FileNotFoundException(Environment.GetResourceString("IO.FileNotFound"));
145 throw new FileNotFoundException(Environment.GetResourceString("IO.FileNotFound_FileName", str), str);
147 case Win32Native.ERROR_PATH_NOT_FOUND:
149 throw new DirectoryNotFoundException(Environment.GetResourceString("IO.PathNotFound_NoPathName"));
151 throw new DirectoryNotFoundException(Environment.GetResourceString("IO.PathNotFound_Path", str));
153 case Win32Native.ERROR_ACCESS_DENIED:
155 throw new UnauthorizedAccessException(Environment.GetResourceString("UnauthorizedAccess_IODenied_NoPathName"));
157 throw new UnauthorizedAccessException(Environment.GetResourceString("UnauthorizedAccess_IODenied_Path", str));
159 case Win32Native.ERROR_ALREADY_EXISTS:
162 throw new IOException(Environment.GetResourceString("IO.IO_AlreadyExists_Name", str), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
164 case Win32Native.ERROR_FILENAME_EXCED_RANGE:
165 throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
167 case Win32Native.ERROR_INVALID_DRIVE:
168 throw new DriveNotFoundException(Environment.GetResourceString("IO.DriveNotFound_Drive", str));
170 case Win32Native.ERROR_INVALID_PARAMETER:
171 throw new IOException(Win32Native.GetMessage(errorCode), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
173 case Win32Native.ERROR_SHARING_VIOLATION:
175 throw new IOException(Environment.GetResourceString("IO.IO_SharingViolation_NoFileName"), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
177 throw new IOException(Environment.GetResourceString("IO.IO_SharingViolation_File", str), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
179 case Win32Native.ERROR_FILE_EXISTS:
182 throw new IOException(Environment.GetResourceString("IO.IO_FileExists_Name", str), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
184 case Win32Native.ERROR_OPERATION_ABORTED:
185 throw new OperationCanceledException();
188 throw new IOException(Win32Native.GetMessage(errorCode), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
192 // An alternative to WinIOError with friendlier messages for drives
193 [System.Security.SecuritySafeCritical] // auto-generated
194 internal static void WinIODriveError(String driveName) {
195 int errorCode = Marshal.GetLastWin32Error();
196 WinIODriveError(driveName, errorCode);
199 [System.Security.SecurityCritical] // auto-generated
200 internal static void WinIODriveError(String driveName, int errorCode)
203 case Win32Native.ERROR_PATH_NOT_FOUND:
204 case Win32Native.ERROR_INVALID_DRIVE:
205 throw new DriveNotFoundException(Environment.GetResourceString("IO.DriveNotFound_Drive", driveName));
208 WinIOError(errorCode, driveName);
213 internal static void WriteNotSupported() {
214 throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnwritableStream"));
217 internal static void WriterClosed() {
218 throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_WriterClosed"));
222 internal const int ERROR_FILE_NOT_FOUND = Win32Native.ERROR_FILE_NOT_FOUND;
223 internal const int ERROR_PATH_NOT_FOUND = Win32Native.ERROR_PATH_NOT_FOUND;
224 internal const int ERROR_ACCESS_DENIED = Win32Native.ERROR_ACCESS_DENIED;
225 internal const int ERROR_INVALID_PARAMETER = Win32Native.ERROR_INVALID_PARAMETER;