Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Win32 API: GetLastError() with FormatMessage() prints a junk

I'm just trying to get a text of the last error with this simple code:

#include <cstdio>
#include <string>
#include <windows.h>

int main(){
    char err[256];
    memset(err, 0, 256);
    FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
                   MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err, 255, NULL);
    wprintf(L"%s\n", err); // just for the safe case
    puts(err);
    return 0;
}

FormatMessage() tries probably to write something like No error, but instead I getting: ┬√яюыэхэю єёях°эю in WINE, and ╬яхЁрЎш  єёях°эю чртхЁ°хэр under WinXP in VirtualBox.

I checked every idea I've had: 1) in an example, for some reason, a wchar_t is used, so I tried creating a buffer of wchar_ts, and casting it for FormatMessage (otherwise build fails with cannot convert ‘wchar_t*’ to ‘LPSTR {aka char*}’ for argument ‘5’), 2) then I thought, perhaps encoding differs from the GNU/Linux one, so I installed WinXP into VirtualBox; but none of two functions gave anything readable, app keeps mumbling its own weird language.

OS: Ubuntu(WINE), WinXP(VirtualBox). Compiler: MinGW GCC

UPD: I found a working code!

#include <cstdio>
#include <string>
#include <windows.h>

int main(){
    wchar_t err[256];
    memset(err, 0, 256);
    FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err, 255, NULL);
    int msgboxID = MessageBoxW( NULL,
                                err,
                                (LPCWSTR)L"☠",
                                MB_OK );
    return 0;
}

Upon compiled with the -mwindows flag, it shows up a message box with readable text in both Ubuntu and WinXP. So, the problem looks to be terminal-only.

like image 215
Hi-Angel Avatar asked Dec 20 '22 12:12

Hi-Angel


2 Answers

Your terminal is set to the wrong code page, the sequence ┬√яюыэхэю in code page 866 is Выполнено in code page 1251 (i.e. the raw bytes c2 fb ef ee eb ed e5 ed ee), change your terminal code page by calling

chcp 1251

before you run your app and try again.

As to why your terminal code page does not match your system code page is anyone's guess, try resetting the cmd.exe settings for the local user by deleting the HKCU\Console registry key (make a registry backup first just in case).

like image 143
user657267 Avatar answered Dec 30 '22 11:12

user657267


It looks like you are mixing Unicode and multi-byte character sets, your code should be something like the following

int main() // unicode
{   wchar_t err[256];
    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err, 255, NULL);
    wprintf(L"%s\n", err);//just for the safe case
    _putws(err);
    return 0;
}

EDIT: added MBCS version

int main() // MBCS
{   char err[256];
    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err, 255, NULL);
    printf("%s\n", err);//just for the safe case
    puts(err);
    return 0;
}
like image 32
Edward Clements Avatar answered Dec 30 '22 09:12

Edward Clements