Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I set the Arguments parameter when using FormatMessage to retrieve Windows API error messages? [duplicate]

I am attempting to get the error message that relates to the GetLastError Windows API function.

I have followed the examples given here relating to the FormatMessage function:

How to get the error message from the error code returned by GetLastError()?

https://msdn.microsoft.com/en-us/library/windows/desktop/ms680582%28v=vs.85%29.aspx

My implementation is returning a string but noticed through testing that some error messages are including text such as "%1". For example, for the error code 574:

{Application Error} The exception %s (0x%08lx) occurred in the application at location 0x%08lx.

I assume that this is resolved by setting the Arguments parameter in the FormatMessage function. However, I cannot find a suitable tutorial/example for setting this parameter on system error messages. The links I have provided set this parameter to NULL.

Is this because ANY Windows API call that sets the last error message via SetLastError never uses a code that corresponds to a message that uses the Arguments parameter?

Otherwise, how do I create such a va_list for system error messages?

like image 463
Class Skeleton Avatar asked Jul 02 '26 05:07

Class Skeleton


1 Answers

Sorry, this should ideally be a comment except for the by-design lack of support for technical comments here on SO. So, I'll gladly delete this shortly. But, for now, info: Microsoft's headers contain the following informative comment:

//====== ShellMessageBox ================================================

// If lpcTitle is NULL, the title is taken from hWnd
// If lpcText is NULL, this is assumed to be an Out Of Memory message
// If the selector of lpcTitle or lpcText is NULL, the offset should be a
//     string resource ID
// The variable arguments must all be 32-bit values (even if fewer bits
//     are actually used)
// lpcText (or whatever string resource it causes to be loaded) should
//     be a formatting string similar to wsprintf except that only the
//     following formats are available:
//         %%              formats to a single '%'
//         %nn%s           the nn-th arg is a string which is inserted
//         %nn%ld          the nn-th arg is a DWORD, and formatted decimal
//         %nn%lx          the nn-th arg is a DWORD, and formatted hex
//     note that lengths are allowed on the %s, %ld, and %lx, just
//                         like wsprintf
//

I would not be surprised if this applies to FormatMessage.

Also, I would check documentation around the message compiler and message resources.

Also note from the documentation of FormatMessage,

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 DWORD_PTR values; those values are input to the message formatted as the insert values. Each insert must have a corresponding element in the array.

like image 155
Cheers and hth. - Alf Avatar answered Jul 04 '26 01:07

Cheers and hth. - Alf