Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I deal with placeholders for Win32 error messages?

Tags:

winapi

I would like to present meaningful error messages when my program encounters Win32 errors. I call GetLastError, and then FormatMessage. But some of the error messages contain placeholders. For instance, ERROR_BAD_EXE_FORMAT has the text:

%1 is not a valid Win32 application.

Presumably, the %1 is meant to be replaced by the name of the module which is not valid. How can I effect that replacement?

Note that I would ideally like a general solution because I note that there are many errors with placeholders. I can see the following messages in the documentation:

  • The wrong diskette is in the drive. Insert %2 (Volume Serial Number: %3) into drive %1.
  • The operating system cannot run %1.
  • This version of %1 is not compatible with the version of Windows you're running. Check your computer's system information and then contact the software publisher.
  • The image file %1 is signed, unable to modify.
  • The system cannot find message text for message number 0x%1 in the message file for %2.
  • ... and so on.
like image 566
David Heffernan Avatar asked Jan 22 '14 11:01

David Heffernan


People also ask

What does Win32 error mean?

This error can be generated by a file that is a virus, worm, trojan, or another malware file. Often, this is caused because the virus scanner installed in the computer does not allow the file to be installed or run. Try scanning the file to verify it is not a virus or infected with a virus.


2 Answers

I think Raymond Chen effectively answers the question in a comment on his blog where he writes:

It bugs me too that system error messages contain %1 insertions that you just have to "know" on a case-by-case basis.

like image 189
David Heffernan Avatar answered Oct 19 '22 09:10

David Heffernan


ERROR_BAD_EXE_FORMAT contains an insertion %1. You can replace that by using last parameter of FormatMessage(). This code a little sample.

LPWSTR pMessage = L"%1";
DWORD_PTR pArgs[] = {(DWORD_PTR)L"My_Test_App.exe" }; 

TCHAR buffer[1024];
DWORD dwError = ERROR_BAD_EXE_FORMAT;
DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY;
DWORD dwResult = FormatMessage(dwFlags, pMessage, dwError, 0, buffer, 1024,  (va_list*)pArgs);
if (dwResult) 
{
    //now, 'buffer' contains below message.

    //
    //My_Test_App.exe is not a valid Win32 application.
    //
}

I know that some sytem error codes have insertion. I think we can't supply relevant argument for all of them. So, if I were you, I would like to use just system error code, not FormatMessage(). Or, support argument list and FormatMessage()for only some frequently system error code.

like image 23
hyun Avatar answered Oct 19 '22 07:10

hyun