Reading Raw Messages
The message text for both the SMS components and the raw user-defined messages is contained in message DLLs. The SMS_StatMsgInsStrings class contains the insertion strings for those messages that use insertion strings. To read the SMS component and raw user-defined messages, you must know the message DLL that contains the message text.
You can get the DLL name from the SMS_StatMsgModuleNames class. The SMS_StatMsgModuleNames class contains the ModuleName and the MsgDLLName properties. You can use ModuleName to join the SMS_StatMsgModuleNames class with the SMS_StatusMessage class, as the following example shows.
// Note that this query returns all the instances found in the SMS_Status_Message // class. This query can return several thousand instances. If you test this // query, you should add a where clause to limit its scope, or set the // InstanceCount context qualifier to limit the number of instances returned. SELECT B.Severity, B.MessageID, B.MessageType, B.Win32Error, B.SiteCode, B.MachineName, B.Component, C.MsgDLLName, D.InsStrValue FROM SMS_StatusMessage AS B INNER JOIN SMS_StatMsgModuleNames AS C ON B.ModuleName = C.ModuleName LEFT OUTER JOIN SMS_StatMsgInsStrings AS D ON B.RecordID = D.RecordID ORDER BY B.Sitecode, B.RecordID, B.MessageID, D.InsStrIndex
The Microsoft BackOffice Resource Kit contains the list of SMS component-generated messages. You can use the MessageID and Component names from the list to limit your status message query. For example, you can add a WHERE clause to limit the status messages to the SMS_Distribution_Manager component.
After you have the DLL name, you can use the Microsoft® Win32® API function FormatMessage to retrieve the message text from the component's message DLL. This requires you to get the module handle for the DLL using the Win32 API function, GetModuleHandle. The dwMessageId parameter is the OR'd result of the MessageID and the Severity properties. You should set the FORMAT_MESSAGE_ARGUMENT_ARRAY flag and pass the insertion strings as an array.
The following code fragment shows you how to call FormatMessage to retrieve the message text from a DLL.
// Get the module handle for the component's message DLL. This assumes the // message DLL is loaded. If the DLL is not loaded, then load the DLL using // the Win32 API LoadLibrary. hmodMessageDLL = GetModuleHandle(MsgDLLName); // The flags tell FormatMessage to allocate the memory needed for the message, // to get the message text from a message DLL, and that the insertion strings are // stored in an array, instead of a variable length argument list. The last // parameter, apInsertStrings, is the array of insertion strings returned by the // query. dwMsgLen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ARGUMENT_ARRAY, hmodMessageDLL, Severity | MessageID, 0, lpBuffer, nSize, apInsertStrings); // Free the memory after you use the message text. LocalFree(lpBuffer);