How to obtain error message descriptions using the FormatMessage API (256348)



The information in this article applies to:

  • Microsoft Message Queue Server (MSMQ) 1.0
  • Microsoft Message Queuing 2.0

This article was previously published under Q256348

SUMMARY

The FormatMessage() API call may be used to obtain the description string associated with a Microsoft Message Queuing error code. The FORMAT_MESSAGE_FROM_HMODULE flag is used with the FormatMessage call and the module handle of Mqutil.dll to retrieve the message text.

MORE INFORMATION

The following sample code shows a simple function which will print the description of a Microsoft Message Queuing error message to standard output:
#include <windows.h>
#include <lmerr.h>
#include <tchar.h>

#define ERRMSGBUFFERSIZE 256

void fnDisplayError( DWORD dwErrorMsgId )
{
DWORD ret;        // Temp space to hold a return value.
HINSTANCE hInst;  // Instance handle for DLL.
HLOCAL pBuffer;   // Buffer to hold the textual error description.

if ( HRESULT_FACILITY(dwErrorMsgId) == FACILITY_MSMQ )
{ // MSMQ errors only (see winerror.h for facility info).
// Load the MSMQ library containing the error message strings.
	hInst = LoadLibrary( TEXT("MQUTIL.DLL") );
	if(hInst != 0)
	{ // hInst not NULL if the library was successfully loaded.
// Get the text string for a message definition
		ret = FormatMessage( 
				FORMAT_MESSAGE_ALLOCATE_BUFFER | // Function will handle memory allocation.
				FORMAT_MESSAGE_FROM_HMODULE | // Using a module's message table.
				FORMAT_MESSAGE_IGNORE_INSERTS, 
				hInst, // Handle to the DLL.
				dwErrorMsgId, // Message identifier.
				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language.
				(LPTSTR)&pBuffer, // Buffer that will hold the text string.
 				ERRMSGBUFFERSIZE, // Allocate at least this many chars for pBuffer.
				NULL // No insert values.
			        );
	} // hInst not NULL if the library was successfully loaded.

} // MSMQ errors only.

else if ( dwErrorMsgId >= NERR_BASE && dwErrorMsgId <= MAX_NERR )
{ // Could be a network error.
// Load the library containing network messages.
	hInst = LoadLibrary( TEXT("NETMSG.DLL") );
	if(hInst != 0)
	{ // Not NULL if successfully loaded.
// Get a text string for the message definition.
		ret = FormatMessage(  
				FORMAT_MESSAGE_ALLOCATE_BUFFER | // The function will allocate memory for the message.
				FORMAT_MESSAGE_FROM_HMODULE | // Message definition is in a module.
				FORMAT_MESSAGE_IGNORE_INSERTS,  // No inserts used.
				hInst, // Handle to the module containing the definition.
				dwErrorMsgId, // Message identifier.
				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language.
				(LPTSTR)&pBuffer, // Buffer to hold the text string.
				ERRMSGBUFFERSIZE, // Smallest size that will be allocated for pBuffer.
				NULL // No inserts.
			);
	} // Not NULL if successfully loaded.

} // Could be a network error.
else
{ // Unknown message source.
// Get the message string from the system.
	ret = FormatMessage(  
			FORMAT_MESSAGE_ALLOCATE_BUFFER | // The function will allocate space for pBuffer.
			FORMAT_MESSAGE_FROM_SYSTEM | // System wide message.
			FORMAT_MESSAGE_IGNORE_INSERTS, // No inserts.
			NULL, // Message is not in a module.
			dwErrorMsgId, // Message identifier.
			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language.
			(LPTSTR)&pBuffer, // Buffer to hold the text string.
			ERRMSGBUFFERSIZE, // The function will allocate at least this much for pBuffer.
			NULL // No inserts.
		);
}


// Display the string.

if( ret )
{
	_tprintf( _TEXT("\tERRORMESSAGE: %s\n"), (LPTSTR)pBuffer );
}
else
{
	_tprintf( _TEXT("\tERRORNUMBER: %d\n"), dwErrorMsgId );
}


// Free the buffer.
LocalFree( pBuffer );

}
				

Modification Type:MajorLast Reviewed:4/20/2005
Keywords:kbhowto KB256348