You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

NativeError.cs 7.1 KiB

8 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
  2. *
  3. * Permission is hereby granted, free of charge, to any person obtaining a copy
  4. * of this software and associated documentation files (the "Software"), to deal
  5. * in the Software without restriction, including without limitation the rights
  6. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. * copies of the Software, and to permit persons to whom the Software is
  8. * furnished to do so, subject to the following conditions:
  9. *
  10. * The above copyright notice and this permission notice shall be included in
  11. * all copies or substantial portions of the Software.
  12. *
  13. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. * THE SOFTWARE.
  20. */
  21. using Alphaleonis.Win32.Filesystem;
  22. using System;
  23. using System.ComponentModel;
  24. using System.Diagnostics.CodeAnalysis;
  25. using System.Globalization;
  26. using System.IO;
  27. using System.Runtime.InteropServices;
  28. using System.Security.Policy;
  29. namespace Alphaleonis.Win32
  30. {
  31. internal static class NativeError
  32. {
  33. internal static void ThrowException()
  34. {
  35. ThrowException((uint)Marshal.GetLastWin32Error(), null, null);
  36. }
  37. public static void ThrowException(int errorCode)
  38. {
  39. ThrowException((uint)errorCode, null, null);
  40. }
  41. public static void ThrowException(int errorCode, string readPath)
  42. {
  43. ThrowException((uint)errorCode, readPath, null);
  44. }
  45. public static void ThrowException(int errorCode, string readPath, string writePath)
  46. {
  47. ThrowException((uint)errorCode, readPath, writePath);
  48. }
  49. public static void ThrowException(uint errorCode, string readPath)
  50. {
  51. ThrowException(errorCode, readPath, null);
  52. }
  53. [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
  54. public static void ThrowException(uint errorCode, string readPath, string writePath)
  55. {
  56. string errorMessage = string.Format(CultureInfo.CurrentCulture, "({0}) {1}.", errorCode, new Win32Exception((int)errorCode).Message);
  57. if (!Utils.IsNullOrWhiteSpace(readPath))
  58. errorMessage = string.Format(CultureInfo.CurrentCulture, "{0}: [{1}]", errorMessage.TrimEnd('.'), readPath);
  59. if (!Utils.IsNullOrWhiteSpace(writePath))
  60. errorMessage = string.Format(CultureInfo.CurrentCulture, "{0}: [{1}]", errorMessage.TrimEnd('.'), writePath);
  61. switch (errorCode)
  62. {
  63. case Win32Errors.ERROR_INVALID_DRIVE:
  64. throw new DriveNotFoundException(errorMessage);
  65. case Win32Errors.ERROR_OPERATION_ABORTED:
  66. throw new OperationCanceledException(errorMessage);
  67. case Win32Errors.ERROR_FILE_NOT_FOUND:
  68. throw new FileNotFoundException(errorMessage);
  69. case Win32Errors.ERROR_PATH_NOT_FOUND:
  70. throw new DirectoryNotFoundException(errorMessage);
  71. case Win32Errors.ERROR_BAD_RECOVERY_POLICY:
  72. throw new PolicyException(errorMessage);
  73. case Win32Errors.ERROR_FILE_READ_ONLY:
  74. case Win32Errors.ERROR_ACCESS_DENIED:
  75. case Win32Errors.ERROR_NETWORK_ACCESS_DENIED:
  76. throw new UnauthorizedAccessException(errorMessage);
  77. case Win32Errors.ERROR_ALREADY_EXISTS:
  78. case Win32Errors.ERROR_FILE_EXISTS:
  79. throw new AlreadyExistsException(errorMessage);
  80. case Win32Errors.ERROR_DIR_NOT_EMPTY:
  81. throw new DirectoryNotEmptyException(errorMessage);
  82. case Win32Errors.ERROR_NOT_READY:
  83. throw new DeviceNotReadyException(errorMessage);
  84. #region Transactional
  85. case Win32Errors.ERROR_INVALID_TRANSACTION:
  86. throw new InvalidTransactionException(Resources.Transaction_Invalid, Marshal.GetExceptionForHR(Win32Errors.GetHrFromWin32Error(errorCode)));
  87. case Win32Errors.ERROR_TRANSACTION_ALREADY_COMMITTED:
  88. throw new TransactionAlreadyCommittedException(Resources.Transaction_Already_Committed, Marshal.GetExceptionForHR(Win32Errors.GetHrFromWin32Error(errorCode)));
  89. case Win32Errors.ERROR_TRANSACTION_ALREADY_ABORTED:
  90. throw new TransactionAlreadyAbortedException(Resources.Transaction_Already_Aborted, Marshal.GetExceptionForHR(Win32Errors.GetHrFromWin32Error(errorCode)));
  91. case Win32Errors.ERROR_TRANSACTIONAL_CONFLICT:
  92. throw new TransactionalConflictException(Resources.Transactional_Conflict, Marshal.GetExceptionForHR(Win32Errors.GetHrFromWin32Error(errorCode)));
  93. case Win32Errors.ERROR_TRANSACTION_NOT_ACTIVE:
  94. throw new TransactionException(Resources.Transaction_Not_Active, Marshal.GetExceptionForHR(Win32Errors.GetHrFromWin32Error(errorCode)));
  95. case Win32Errors.ERROR_TRANSACTION_NOT_REQUESTED:
  96. throw new TransactionException(Resources.Transaction_Not_Requested, Marshal.GetExceptionForHR(Win32Errors.GetHrFromWin32Error(errorCode)));
  97. case Win32Errors.ERROR_TRANSACTION_REQUEST_NOT_VALID:
  98. throw new TransactionException(Resources.Invalid_Transaction_Request, Marshal.GetExceptionForHR(Win32Errors.GetHrFromWin32Error(errorCode)));
  99. case Win32Errors.ERROR_TRANSACTIONS_UNSUPPORTED_REMOTE:
  100. throw new UnsupportedRemoteTransactionException(Resources.Invalid_Transaction_Request, Marshal.GetExceptionForHR(Win32Errors.GetHrFromWin32Error(errorCode)));
  101. case Win32Errors.ERROR_NOT_A_REPARSE_POINT:
  102. throw new NotAReparsePointException(Resources.Not_A_Reparse_Point, Marshal.GetExceptionForHR(Win32Errors.GetHrFromWin32Error(errorCode)));
  103. #endregion // Transacted
  104. case Win32Errors.ERROR_SUCCESS:
  105. case Win32Errors.ERROR_SUCCESS_REBOOT_INITIATED:
  106. case Win32Errors.ERROR_SUCCESS_REBOOT_REQUIRED:
  107. case Win32Errors.ERROR_SUCCESS_RESTART_REQUIRED:
  108. // We should really never get here, throwing an exception for a successful operation.
  109. throw new NotImplementedException(string.Format(CultureInfo.CurrentCulture, "{0} {1}", Resources.Exception_From_Successful_Operation, errorMessage));
  110. default:
  111. // We don't have a specific exception to generate for this error.
  112. throw new IOException(errorMessage, Win32Errors.GetHrFromWin32Error(errorCode));
  113. }
  114. }
  115. public static void ThrowException(string readPath)
  116. {
  117. ThrowException((uint)Marshal.GetLastWin32Error(), readPath, null);
  118. }
  119. public static void ThrowException(string readPath, string writePath)
  120. {
  121. ThrowException((uint)Marshal.GetLastWin32Error(), readPath, writePath);
  122. }
  123. }
  124. }