Retrieving Status Message Information via WBEM/Win32

Goto the SMS Home Page

 

I am trying to read information of the SMS Status system. My problem is extracting the full text description field. (That is what you can read from the SMS Status system). From what I can gather I need to use the FormatMessage API call - however I cannot find what and how to pass the parameters to this function.

Extract: from:

http://msdn.microsoft.com/library/en-us/sms/hh/sms/usingsms_2sz7.asp

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);

===============================================================

Question is on this -- how do I populate apInsertStrings?  Does anybody have any ideas on this - or even some sample code.

Contributed By: Russ Wilson [MS]
The app insert strings are the argument values that will replace the substitution parameters in the fixed string from the resource dll.  So the string from the dll will read something like 'error in package ID %s' and the value for the string will be in the apInsertStrings.  You probably knew that.  So the insertion strings are stored in a different class (table) which is in the query as SMS_StatMsgInsStrings .  The trouble is you need to get the results into a string array.  So each instance from the returned query below will have D.InsStrValue as a single string value.  You need to collect these together for each unique record ID and put them into a string array then pass that in as apInsertStrings.

Something like

WCHAR* apInsertStrings[3];

apInsertStrings[0] = first instance string apInsertStrings[1] = second string apInsertStrings[2]  = NULL;

Arguments
[in] Pointer to an array of 32-bit values that are used as insert values in the formatted message. A %1 in the format string indicates the first value in the Arguments array; a %2 indicates the second argument; and so on.

The interpretation of each 32-bit value depends on the formatting information associated with the insert in the message definition. The default is to treat each value as a pointer to a null-terminated string.

By default, the Arguments parameter is of type va_list*, which is a language- and implementation-specific data type for describing a variable number of arguments. If you do not have a pointer of type va_list*, then specify the FORMAT_MESSAGE_ARGUMENT_ARRAY flag and pass a pointer to an array of 32-bit values; those values are input to the message formatted as the insert values. Each insert must have a corresponding element in the array.

Full description of FormatMessage on MSDN:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcesdk40/htm/cerefformatmessage.asp
 

© FAQShop.com 2003 - 2008

Goto the SMS Home Page

Email the Author