1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace System.IO
{
/// <summary>
/// Provides static methods for converting from Win32 errors codes to exceptions, HRESULTS and error messages.
/// </summary>
internal static class Win32Marshal
{
/// <summary>
/// Converts, resetting it, the last Win32 error into a corresponding <see cref="Exception"/> object.
/// </summary>
internal static Exception GetExceptionForLastWin32Error()
{
int errorCode = Marshal.GetLastWin32Error();
return GetExceptionForWin32Error(errorCode, string.Empty);
}
/// <summary>
/// Converts the specified Win32 error into a corresponding <see cref="Exception"/> object.
/// </summary>
internal static Exception GetExceptionForWin32Error(int errorCode)
{
return GetExceptionForWin32Error(errorCode, string.Empty);
}
/// <summary>
/// Converts the specified Win32 error into a corresponding <see cref="Exception"/> object, optionally
/// including the specified path in the error message.
/// </summary>
internal static Exception GetExceptionForWin32Error(int errorCode, string path)
{
switch (errorCode)
{
case Interop.Errors.ERROR_FILE_NOT_FOUND:
if (path.Length == 0)
return new FileNotFoundException(SR.IO_FileNotFound);
else
return new FileNotFoundException(SR.Format(SR.IO_FileNotFound_FileName, path), path);
case Interop.Errors.ERROR_PATH_NOT_FOUND:
if (path.Length == 0)
return new DirectoryNotFoundException(SR.IO_PathNotFound_NoPathName);
else
return new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, path));
case Interop.Errors.ERROR_ACCESS_DENIED:
if (path.Length == 0)
return new UnauthorizedAccessException(SR.UnauthorizedAccess_IODenied_NoPathName);
else
return new UnauthorizedAccessException(SR.Format(SR.UnauthorizedAccess_IODenied_Path, path));
case Interop.Errors.ERROR_ALREADY_EXISTS:
if (path.Length == 0)
goto default;
return new IOException(SR.Format(SR.IO_AlreadyExists_Name, path), MakeHRFromErrorCode(errorCode));
case Interop.Errors.ERROR_FILENAME_EXCED_RANGE:
return new PathTooLongException(SR.IO_PathTooLong);
case Interop.Errors.ERROR_INVALID_PARAMETER:
return new IOException(GetMessage(errorCode), MakeHRFromErrorCode(errorCode));
case Interop.Errors.ERROR_SHARING_VIOLATION:
if (path.Length == 0)
return new IOException(SR.IO_SharingViolation_NoFileName, MakeHRFromErrorCode(errorCode));
else
return new IOException(SR.Format(SR.IO_SharingViolation_File, path), MakeHRFromErrorCode(errorCode));
case Interop.Errors.ERROR_FILE_EXISTS:
if (path.Length == 0)
goto default;
return new IOException(SR.Format(SR.IO_FileExists_Name, path), MakeHRFromErrorCode(errorCode));
case Interop.Errors.ERROR_OPERATION_ABORTED:
return new OperationCanceledException();
default:
return new IOException(GetMessage(errorCode), MakeHRFromErrorCode(errorCode));
}
}
/// <summary>
/// Returns a HRESULT for the specified Win32 error code.
/// </summary>
internal static int MakeHRFromErrorCode(int errorCode)
{
Debug.Assert((0xFFFF0000 & errorCode) == 0, "This is an HRESULT, not an error code!");
return unchecked(((int)0x80070000) | errorCode);
}
/// <summary>
/// Returns a string message for the specified Win32 error code.
/// </summary>
internal static string GetMessage(int errorCode)
{
return Interop.Kernel32.GetMessage(errorCode);
}
}
}
|