The Labs \ Source Viewer \ SSCLI \ System.IO \ __Error

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. /*============================================================
  16. **
  17. ** Class:  __Error
  18. **
  19. **
  20. ** Purpose: Centralized error methods for the IO package. 
  21. ** Mostly useful for translating Win32 HRESULTs into meaningful
  22. ** error strings & exceptions.
  23. **
  24. **
  25. ===========================================================*/
  26. using System;
  27. using System.Runtime.InteropServices;
  28. using Win32Native = Microsoft.Win32.Win32Native;
  29. using System.Text;
  30. using System.Globalization;
  31. using System.Security;
  32. using System.Security.Permissions;
  33. namespace System.IO
  34. {
  35.     // Only static data no need to serialize
  36.     static internal class __Error
  37.     {
  38.         static internal void EndOfFile()
  39.         {
  40.             throw new EndOfStreamException(Environment.GetResourceString("IO.EOF_ReadBeyondEOF"));
  41.         }
  42.        
  43.         static internal void FileNotOpen()
  44.         {
  45.             throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_FileClosed"));
  46.         }
  47.        
  48.         static internal void StreamIsClosed()
  49.         {
  50.             throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_StreamClosed"));
  51.         }
  52.        
  53.         static internal void MemoryStreamNotExpandable()
  54.         {
  55.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_MemStreamNotExpandable"));
  56.         }
  57.        
  58.         static internal void ReaderClosed()
  59.         {
  60.             throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_ReaderClosed"));
  61.         }
  62.        
  63.         static internal void ReadNotSupported()
  64.         {
  65.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnreadableStream"));
  66.         }
  67.        
  68.         static internal void SeekNotSupported()
  69.         {
  70.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnseekableStream"));
  71.         }
  72.        
  73.         static internal void WrongAsyncResult()
  74.         {
  75.             throw new ArgumentException(Environment.GetResourceString("Arg_WrongAsyncResult"));
  76.         }
  77.        
  78.         static internal void EndReadCalledTwice()
  79.         {
  80.             // Should ideally be InvalidOperationExc but we can't maitain parity with Stream and FileStream without some work
  81.             throw new ArgumentException(Environment.GetResourceString("InvalidOperation_EndReadCalledMultiple"));
  82.         }
  83.        
  84.         static internal void EndWriteCalledTwice()
  85.         {
  86.             // Should ideally be InvalidOperationExc but we can't maintain parity with Stream and FileStream without some work
  87.             throw new ArgumentException(Environment.GetResourceString("InvalidOperation_EndWriteCalledMultiple"));
  88.         }
  89.        
  90.         // Given a possible fully qualified path, ensure that we have path
  91.         // discovery permission to that path. If we do not, return just the
  92.         // file name. If we know it is a directory, then don't return the
  93.         // directory name.
  94.         static internal string GetDisplayablePath(string path, bool isInvalidPath)
  95.         {
  96.             if (String.IsNullOrEmpty(path))
  97.                 return path;
  98.            
  99.             // Is it a fully qualified path?
  100.             bool isFullyQualified = false;
  101.             if (path.Length < 2)
  102.                 return path;
  103.             if (Path.IsDirectorySeparator(path[0]) && Path.IsDirectorySeparator(path[1]))
  104.                 isFullyQualified = true;
  105.             else if (path[1] == Path.VolumeSeparatorChar) {
  106.                 isFullyQualified = true;
  107.             }
  108.            
  109.             if (!isFullyQualified && !isInvalidPath)
  110.                 return path;
  111.            
  112.             bool safeToReturn = false;
  113.             try {
  114.                 if (!isInvalidPath) {
  115.                     new FileIOPermission(FileIOPermissionAccess.PathDiscovery, new string[] {path}, false, false).Demand();
  116.                     safeToReturn = true;
  117.                 }
  118.             }
  119.             catch (ArgumentException) {
  120.                 // Needed for Win9x
  121.             }
  122.             catch (NotSupportedException) {
  123.                 // Needed for Win9x, which will sometimes return
  124.                 // ERROR_PATH_NOT_FOUND for invalid path names, but also
  125.                 // will leak the current working directory.
  126.             }
  127.             catch (SecurityException) {
  128.             }
  129.            
  130.             if (!safeToReturn) {
  131.                 if (Path.IsDirectorySeparator(path[path.Length - 1]))
  132.                     path = Environment.GetResourceString("IO.IO_NoPermissionToDirectoryName");
  133.                 else
  134.                     path = Path.GetFileName(path);
  135.             }
  136.            
  137.             return path;
  138.         }
  139.        
  140.         static internal void WinIOError()
  141.         {
  142.             int errorCode = Marshal.GetLastWin32Error();
  143.             WinIOError(errorCode, String.Empty);
  144.         }
  145.        
  146.         // After calling GetLastWin32Error(), it clears the last error field,
  147.         // so you must save the HResult and pass it to this method. This method
  148.         // will determine the appropriate exception to throw dependent on your
  149.         // error, and depending on the error, insert a string into the message
  150.         // gotten from the ResourceManager.
  151.         static internal void WinIOError(int errorCode, string maybeFullPath)
  152.         {
  153.             // This doesn't have to be perfect, but is a perf optimization.
  154.             bool isInvalidPath = errorCode == Win32Native.ERROR_INVALID_NAME || errorCode == Win32Native.ERROR_BAD_PATHNAME;
  155.             string str = GetDisplayablePath(maybeFullPath, isInvalidPath);
  156.            
  157.             switch (errorCode) {
  158.                 case Win32Native.ERROR_FILE_NOT_FOUND:
  159.                     if (str.Length == 0)
  160.                         throw new FileNotFoundException(Environment.GetResourceString("IO.FileNotFound"));
  161.                     else
  162.                         throw new FileNotFoundException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("IO.FileNotFound_FileName"), str), str);
  163.                     break;
  164.                 case Win32Native.ERROR_PATH_NOT_FOUND:
  165.                    
  166.                     if (str.Length == 0)
  167.                         throw new DirectoryNotFoundException(Environment.GetResourceString("IO.PathNotFound_NoPathName"));
  168.                     else
  169.                         throw new DirectoryNotFoundException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("IO.PathNotFound_Path"), str));
  170.                     break;
  171.                 case Win32Native.ERROR_ACCESS_DENIED:
  172.                    
  173.                     if (str.Length == 0)
  174.                         throw new UnauthorizedAccessException(Environment.GetResourceString("UnauthorizedAccess_IODenied_NoPathName"));
  175.                     else
  176.                         throw new UnauthorizedAccessException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("UnauthorizedAccess_IODenied_Path"), str));
  177.                     break;
  178.                 case Win32Native.ERROR_ALREADY_EXISTS:
  179.                    
  180.                     if (str.Length == 0)
  181.                         goto default;
  182.                     throw new IOException(Environment.GetResourceString("IO.IO_AlreadyExists_Name", str), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
  183.                     break;
  184.                 case Win32Native.ERROR_FILENAME_EXCED_RANGE:
  185.                    
  186.                     throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
  187.                     break;
  188.                 case Win32Native.ERROR_INVALID_DRIVE:
  189.                    
  190.                     throw new DriveNotFoundException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("IO.DriveNotFound_Drive"), str));
  191.                     break;
  192.                 case Win32Native.ERROR_INVALID_PARAMETER:
  193.                    
  194.                     throw new IOException(Win32Native.GetMessage(errorCode), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
  195.                     break;
  196.                 case Win32Native.ERROR_SHARING_VIOLATION:
  197.                    
  198.                     if (str.Length == 0)
  199.                         throw new IOException(Environment.GetResourceString("IO.IO_SharingViolation_NoFileName"), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
  200.                     else
  201.                         throw new IOException(Environment.GetResourceString("IO.IO_SharingViolation_File", str), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
  202.                     break;
  203.                 case Win32Native.ERROR_FILE_EXISTS:
  204.                    
  205.                     if (str.Length == 0)
  206.                         goto default;
  207.                     throw new IOException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("IO.IO_FileExists_Name"), str), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
  208.                     break;
  209.                 case Win32Native.ERROR_OPERATION_ABORTED:
  210.                    
  211.                     throw new OperationCanceledException();
  212.                     break;
  213.                 default:
  214.                    
  215.                     throw new IOException(Win32Native.GetMessage(errorCode), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
  216.                     break;
  217.             }
  218.         }
  219.        
  220.         // An alternative to WinIOError with friendlier messages for drives
  221.         static internal void WinIODriveError(string driveName)
  222.         {
  223.             int errorCode = Marshal.GetLastWin32Error();
  224.             WinIODriveError(driveName, errorCode);
  225.         }
  226.        
  227.         static internal void WinIODriveError(string driveName, int errorCode)
  228.         {
  229.             switch (errorCode) {
  230.                 case Win32Native.ERROR_PATH_NOT_FOUND:
  231.                 case Win32Native.ERROR_INVALID_DRIVE:
  232.                     throw new DriveNotFoundException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("IO.DriveNotFound_Drive"), driveName));
  233.                     break;
  234.                 default:
  235.                    
  236.                     WinIOError(errorCode, driveName);
  237.                     break;
  238.             }
  239.         }
  240.        
  241.         static internal void WriteNotSupported()
  242.         {
  243.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnwritableStream"));
  244.         }
  245.        
  246.         static internal void WriterClosed()
  247.         {
  248.             throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_WriterClosed"));
  249.         }
  250.        
  251.         // From WinError.h
  252.         internal const int ERROR_FILE_NOT_FOUND = Win32Native.ERROR_FILE_NOT_FOUND;
  253.         internal const int ERROR_PATH_NOT_FOUND = Win32Native.ERROR_PATH_NOT_FOUND;
  254.         internal const int ERROR_ACCESS_DENIED = Win32Native.ERROR_ACCESS_DENIED;
  255.         internal const int ERROR_INVALID_PARAMETER = Win32Native.ERROR_INVALID_PARAMETER;
  256.     }
  257. }

Developer Fusion