Example: Error Processing
Program 1-2 showed some rudimentary error processing, obtaining the DWORD error number with the GetLastError function. A function call, rather than a global error number, such as the UNIX errno, ensures that system errors can be unique to the threads (Chapter 7) that share data storage.Stevens (1992, pp. 682ff). ReportError prints a message specified in the first argument and will terminate with an exit code or return, depending on the value of the second argument. The third argument determines whether the system error message should be displayed.Notice the arguments to FormatMessage. The value returned by GetLastError is used as one parameter, and a flag indicates that the message is to be generated by the system. The generated message is stored in a buffer allocated by the function, and the address is returned in a parameter. There are several other parameters with default values. The language for the message can be set at either compile time or run time. FormatMessage will not be used again in this book, so there is no further explanation in the text.ReportError can simplify error processing and will be used in nearly all subsequent examples. Chapter 4 modifies this function to generate exceptions.Program 2-1. It also defines commonly used functions, such as PrintMsg, PrintStrings, and ReportError itself. All subsequent examples will use this single include file, which is listed in Appendix A.Chapter 5.
Program 2-2. ReportError for Reporting System Call Errors
#include "EvryThng.h"
VOID ReportError (LPCTSTR UserMessage, DWORD ExitCode,
BOOL PrintErrorMsg)
/* General-purpose function for reporting system errors. */
{
DWORD eMsgLen, LastErr = GetLastError ();
LPTSTR lpvSysMsg;
HANDLE hStdErr = GetStdHandle (STD_ERROR_HANDLE);
PrintMsg (hStdErr, UserMessage);
if (PrintErrorMsg) {
eMsgLen = FormatMessage
(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM, NULL, LastErr,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpvSysMsg, 0, NULL);
PrintStrings (hStdErr, _T ("\n"), lpvSysMsg,
_T ("\n"), NULL);
/* Free the memory block containing the error message. */
HeapFree (GetProcessHeap (), 0, lpvSysMsg); /* See Ch. 5. */
}
if (ExitCode > 0)
ExitProcess (ExitCode);
else
return;
}