Monday, June 07, 2004

Win32Exceptions capable of dealing with module error messages

For those who may be, like me, in need of an exception that properly deals with Win32 error codes (obtained from GetLastError()) that can come from the system or an specific module, the code below does the trick.
You can change the name "WINHTTP" (it's what I'm dealing right now) for any DLL name you have and go for it!

using System;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace WinHTTP
{
public class WinHTTPException : Win32Exception
{
[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
private static extern int FormatMessage(uint dwFlags, HandleRef lpSource, uint dwMessageId, uint dwLanguageId, StringBuilder lpBuffer, uint nSize, IntPtr arguments);

[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);

[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
private static extern bool CloseHandle(HandleRef handle);

private const uint FORMAT_MESSAGE_FROM_HMODULE = 0x00000800;
private const uint FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
private const uint FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
private const uint FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;

public WinHTTPException()
: base(Marshal.GetLastWin32Error())
{
}

public WinHTTPException(int NativeErrorCode)
: base(NativeErrorCode)
{
}

private string GetErrorMessage()
{
IntPtr hModule = IntPtr.Zero;
try
{
hModule = GetModuleHandle("WINHTTP");
int error = NativeErrorCode;
if (hModule == IntPtr.Zero)
return "Unknown error " + error.ToString("X");
StringBuilder sb = new StringBuilder(1024);
int res = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, new HandleRef(this, hModule), (uint)error, 0, sb, (uint)sb.Capacity, IntPtr.Zero);
if (res == 0)
return "Unknown error " + error.ToString("X");
else
return sb.ToString(0, res);
}
finally
{
if (hModule != IntPtr.Zero)
CloseHandle(new HandleRef(this, hModule));
}
}

public override string Message
{
get
{
return GetErrorMessage();
}
}

}
}



Comments: Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?