Reputation: 865
In my solution I've written the following:
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern unsafe bool CopyFileEx(string lpExistingFileName,
string lpNewFileName, CopyProgressRoutine lpProgressRoutine, IntPtr lpData,
Boolean* pbCancel, CopyFileFlags dwCopyFlags);
...
bool result;
unsafe{
result = CopyFileEx(sourceFile, targetFile, null, IntPtr.Zero,
null /* pointer */, 0);
}
if(!result)
Win32Exception exc = new Win32Exception(Marshal.GetLastWin32Error());
// parameter could be omitted according to Win32Exception constructor
// implementation
In the assumption that CopyFileEx was exported with SetLastError = true parameter of DllImport attribute, do I have a chance to get any unhalted exception here?
I'm specifically interested in non-CLR exceptions which are wrapped in RuntimeWrappedException instance. In C++ "throw 1" is a valid construct. So what exceptions should I expect from such P/Invoke calls and where I can obtain such information regarding exceptions (MSDN says nothing regarding exceptions from CopyFileEx)?
Upvotes: 6
Views: 2062
Reputation: 456637
If a DLL uses the Win32 structured exception handling system, then any exceptions thrown by the DLL will be translated to OutOfMemoryException
, AccessViolationException
, NullReferenceException
(rarely), or SEHException
.
RuntimeWrappedException
is only used when managed C++ throws a non-Exception
-derived object. It is not used for unmanaged DLLs. If you had a managed C++ DLL that did a throw 1
, then you could catch RuntimeWrappedException
.
SEHException
acts as a catch-all for the unmappable types of SEH exceptions from unmanaged DLLs. This would include any C++ class, or the throw 1
example. AFAIK, there is no way to pull the C++-specific exception info out of SEHException
, though I'm sure it's hackable if you try hard enough.
Note that there are a few DLLs that do not use the Win32 structured exception handling system. Most notably Cygwin DLLs. In that case, any C++ exception is likely to crash the process or at least your thread. Naturally, all the Windows DLLs (including the one defining CopyFileEx
) do use Win32 structured exception handling, as do any unmanaged DLLs created by Microsoft's C++ compiler.
Also note that the Win32 API (including CopyFileEx
) does not normally report errors using Win32 structured exceptions; they report them via GetLastError
. The only way to get most Win32 functions to throw a Win32 structured exception is to pass it wildly invalid arguments (such as asking it to write into the middle of ntdll.dll
).
Upvotes: 9