Discussion:
How do I process arguments with FormatMessage and FORMAT_MESSAGE_FROM_SYSTEM?
(too old to reply)
michael_h
2005-02-16 12:06:41 UTC
Permalink
I would like to call FormatMessage to get a text description of a
system error code as returned from GetLastError like this:

FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL);

However, looking through the list of potential error codes on MSDN,
some of them contain escape codes for replaceable parameters such as
error code 106 (ERROR_SEM_USER_LIMIT):

Insert the diskette for drive %1.

As I don't know in advance the error codes I am likely to need to
handle (as they aren't often documented, such as with MoveFileEx for
example), how do I cope with any message description that might be
returned containing these escape codes?

Thanks in advance.

michael_h.
Jeff Henkels
2005-02-16 12:29:26 UTC
Permalink
I can think of two approaches:

1. Take your FormatMessage call as written, then post-process the lpMsgBuf
string, looking for format specifiers (such as %1) and removing/replacing
them.

2. Call FormatMessage without FORMAT_MESSAGE_IGNORE_INSERTS, and pass an
array of empty strings. I'd guess that an array of 10 empty strings would
be big enough to handle any case you're likely to run across -- if the
array's bigger than the # of format specifiers, that's OK. This might be a
problem if you run across a non-string format specifier such as %!1!d!, but
those seem to be very, very rare.
Post by michael_h
I would like to call FormatMessage to get a text description of a
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL);
However, looking through the list of potential error codes on MSDN,
some of them contain escape codes for replaceable parameters such as
Insert the diskette for drive %1.
As I don't know in advance the error codes I am likely to need to
handle (as they aren't often documented, such as with MoveFileEx for
example), how do I cope with any message description that might be
returned containing these escape codes?
Thanks in advance.
michael_h.
michael_h
2005-02-16 16:08:30 UTC
Permalink
Thanks Jeff,

I had already considered the options you mentioned but they don't
really address the issue I am having - I hope its best described with
an example:
1. Call MoveFileEx
2. It returns 0 to indicate failure.
3. Call GetLastError to retreive the error code.
4. Call FormatMessage (with FORMAT_MESSAGE_FROM_SYSTEM) to retrieve the
error description to present to the user and add to the application
log.

Now, because MoveFileEx doesn't document errors that can potentially be
returned, I don't know the subset of errors that are likely to be
returned from the 100's that can potentially occur. So in order to
'fill-in the blanks' for the messages that contain escape sequences
(%1 etc), I would need to have a something like a huge switch statement
containing all the errors so that the specific arguments necessary for
each of the messages containing escape sequences can be provided. The
clearly seems to defeat the purpose of calling FormatMessage in the
first place to retreive a system error description from an error
code...

Hopefully this makes some kind of sense or have I missed something
basic!! 8-)

michael_h

Loading...