ActivePatch Developer's Guide - Library Error Handling

Typically an error is indicated when an ActivePatch function either returns a value of zero or when an invalid handle value is returned. When an error occurs in the ActivePatch library, the GetLastError function can be used to obtain the error code. The GetLastError function is a standard Windows function that returns a 32-bit error value that is unique to each thread in a given application. ActivePatch error codes conform to the standard format used by Windows:

The S bitfield is used to refer to the severity of the error. A value of zero specifies success, while a value of one specifies an error condition.

The R bitfield is reserved for future use by Windows, and must be set to zero. Applications should not take any action based on the values of these two bits.

The Facility bitfield specifies which group of status codes the error belongs to. The ActivePatch library uses FACILITY_ITF, which is designated for use by third-party libraries.

The Code bitfield specifies the actual error code.

Each of the ActivePatch error codes has a matching constant, defined in the APERROR.H header file. These constants should always be used for comparison against the value returned by the GetLastError function.

For each error code, there is a matching description of the error which can be used by the application. Applications may choose to use these error descriptions when displaying a message box to a user or for internal logging purposes. To retrieve the description of the error, the FormatMessage function should be used. This is a standard Windows API function which is used to format error messages, both from the Windows system itself, as well as third-party libraries. Here's an example of a function which returns the last error and description of the error in C/C++:

HRESULT GetAPErrorDescription(LPTSTR lpszError, UINT cchError)
{
    HMODULE hModule;
    DWORD dwError;
    DWORD dwLength;
    LPVOID lpMessage;

    if (lpszError == NULL || cchError == 0)
        return GetLastError();

    if ((dwError = GetLastError()) == 0)
    {
        *lpszError = 0;
        return 0;
    }

    hModule = GetModuleHandle(_T("APATCH.DLL"));
    if (hModule == NULL)
    {
        *lpszError = 0;
        return dwError;
    }

    dwLength = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                             FORMAT_MESSAGE_FROM_HMODULE |
                             FORMAT_MESSAGE_FROM_SYSTEM |
                             FORMAT_MESSAGE_IGNORE_INSERTS,
                             hModule,
                             dwError,
                             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                             (LPTSTR)&lpMessage,
                             0,
                             NULL);

if (dwLength > 0) { lstrcpyn(lpszError, (LPTSTR)lpMessage, cchError); LocalFree(lpMessage); } else { TCHAR szUndefined[128]; wsprintf(szUndefined, _T("Undefined library error (0x%08lx)"), dwError); lstrcpyn(lpszError, szUndefined, cchError); } return dwError;

For more information on the GetLastError and FormatMessage functions, refer to the Microsoft Platform SDK documentation.