Initialize stdout and stderr in a way that won't mangle UTF-8 string. Now we can use standard fprintf() to output UTF-8 string to the console -> console output workarounds removed.

This commit is contained in:
LoRd_MuldeR 2011-07-28 13:35:24 +02:00
parent 7127271652
commit 816e874c4c
2 changed files with 65 additions and 51 deletions

View File

@ -249,7 +249,7 @@ bool lamexp_version_demo(void)
{ {
char buffer[128]; char buffer[128];
bool releaseVersion = false; bool releaseVersion = false;
if(!strcpy_s(buffer, 128, g_lamexp_version.ver_release_name)) if(!strncpy_s(buffer, 128, g_lamexp_version.ver_release_name, _TRUNCATE))
{ {
char *context, *prefix = strtok_s(buffer, "-,; ", &context); char *context, *prefix = strtok_s(buffer, "-,; ", &context);
if(prefix) if(prefix)
@ -281,7 +281,7 @@ const QDate &lamexp_version_date(void)
char *this_token = NULL; char *this_token = NULL;
char *next_token = NULL; char *next_token = NULL;
strcpy_s(temp, 32, g_lamexp_version_raw_date); strncpy_s(temp, 32, g_lamexp_version_raw_date, _TRUNCATE);
this_token = strtok_s(temp, " ", &next_token); this_token = strtok_s(temp, " ", &next_token);
for(int i = 0; i < 3; i++) for(int i = 0; i < 3; i++)
@ -331,6 +331,9 @@ LONG WINAPI lamexp_exception_handler(__in struct _EXCEPTION_POINTERS *ExceptionI
return LONG_MAX; return LONG_MAX;
} }
/*
* Invalid parameters handler
*/
void lamexp_invalid_param_handler(const wchar_t*, const wchar_t*, const wchar_t*, unsigned int, uintptr_t) void lamexp_invalid_param_handler(const wchar_t*, const wchar_t*, const wchar_t*, unsigned int, uintptr_t)
{ {
if(GetCurrentThreadId() != g_main_thread_id) if(GetCurrentThreadId() != g_main_thread_id)
@ -344,39 +347,38 @@ void lamexp_invalid_param_handler(const wchar_t*, const wchar_t*, const wchar_t*
TerminateProcess(GetCurrentProcess(), -1); TerminateProcess(GetCurrentProcess(), -1);
} }
/*
* Change console text color
*/
static void lamexp_console_color(FILE* file, WORD attributes)
{
const HANDLE hConsole = (HANDLE)(_get_osfhandle(_fileno(file)));
if((hConsole != NULL) && (hConsole != INVALID_HANDLE_VALUE))
{
SetConsoleTextAttribute(hConsole, attributes);
}
}
/* /*
* Qt message handler * Qt message handler
*/ */
void lamexp_message_handler(QtMsgType type, const char *msg) void lamexp_message_handler(QtMsgType type, const char *msg)
{ {
static HANDLE hConsole = NULL;
static const char *GURU_MEDITATION = "\n\nGURU MEDITATION !!!\n\n"; static const char *GURU_MEDITATION = "\n\nGURU MEDITATION !!!\n\n";
const char *buffer = NULL, *text = msg;
char temp[1024]; const char *text = msg;
const char *buffer = NULL;
QMutexLocker lock(&g_lamexp_message_mutex); QMutexLocker lock(&g_lamexp_message_mutex);
if(!strncmp(msg, "@BASE64@", 8)) if((strlen(msg) > 8) && (_strnicmp(msg, "@BASE64@", 8) == 0))
{ {
buffer = _strdup(QByteArray::fromBase64(msg + 8).constData()); buffer = _strdup(QByteArray::fromBase64(msg + 8).constData());
if(buffer) text = buffer; if(buffer) text = buffer;
} }
if(!hConsole) if(g_lamexp_console_attached)
{ {
if(g_lamexp_console_attached)
{
hConsole = CreateFile(L"CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
if(hConsole == INVALID_HANDLE_VALUE) hConsole = NULL;
}
}
if(hConsole)
{
int len = sprintf_s(temp, 1024, "%s\n", text);
CONSOLE_SCREEN_BUFFER_INFO bufferInfo;
GetConsoleScreenBufferInfo(hConsole, &bufferInfo);
SetConsoleOutputCP(CP_UTF8); SetConsoleOutputCP(CP_UTF8);
switch(type) switch(type)
@ -385,43 +387,51 @@ void lamexp_message_handler(QtMsgType type, const char *msg)
case QtFatalMsg: case QtFatalMsg:
fflush(stdout); fflush(stdout);
fflush(stderr); fflush(stderr);
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY); lamexp_console_color(stderr, FOREGROUND_RED | FOREGROUND_INTENSITY);
WriteFile(hConsole, GURU_MEDITATION, strlen(GURU_MEDITATION), NULL, NULL); fprintf(stderr, GURU_MEDITATION);
WriteFile(hConsole, temp, len, NULL, NULL); fprintf(stderr, "%s\n", text);
FlushFileBuffers(hConsole); fflush(stderr);
break; break;
case QtWarningMsg: case QtWarningMsg:
SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY); lamexp_console_color(stderr, FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);
WriteFile(hConsole, temp, len, NULL, NULL); fprintf(stderr, "%s\n", text);
FlushFileBuffers(hConsole); fflush(stderr);
break; break;
default: default:
SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY); lamexp_console_color(stderr, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);
WriteFile(hConsole, temp, len, NULL, NULL); fprintf(stderr, "%s\n", text);
FlushFileBuffers(hConsole); fflush(stderr);
break; break;
} }
SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); lamexp_console_color(stderr, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
} }
else else
{ {
char temp[1024] = {'\0'};
switch(type) switch(type)
{ {
case QtCriticalMsg: case QtCriticalMsg:
case QtFatalMsg: case QtFatalMsg:
sprintf_s(temp, 1024, "[LameXP][C] %s", text); _snprintf_s(temp, 1024, _TRUNCATE, "[LameXP][C] %s", text);
break; break;
case QtWarningMsg: case QtWarningMsg:
sprintf_s(temp, 1024, "[LameXP][W] %s", text); _snprintf_s(temp, 1024, _TRUNCATE, "[LameXP][C] %s", text);
break; break;
default: default:
sprintf_s(temp, 1024, "[LameXP][I] %s", text); _snprintf_s(temp, 1024, _TRUNCATE, "[LameXP][C] %s", text);
break; break;
} }
while(char *ptr = strchr(temp, '\n')) *ptr = '\t'; char *ptr = strchr(temp, '\n');
strcat_s(temp, 1024, "\n"); while(ptr != NULL)
{
*ptr = '\t';
ptr = strchr(temp, '\n');
}
strncat_s(temp, 1024, "\n", _TRUNCATE);
OutputDebugStringA(temp); OutputDebugStringA(temp);
} }
@ -433,7 +443,7 @@ void lamexp_message_handler(QtMsgType type, const char *msg)
TerminateProcess(GetCurrentProcess(), -1); TerminateProcess(GetCurrentProcess(), -1);
} }
if(buffer) free((void*) buffer); LAMEXP_SAFE_FREE(buffer);
} }
/* /*
@ -462,7 +472,10 @@ void lamexp_init_console(int argc, char* argv[])
{ {
if(!g_lamexp_console_attached) if(!g_lamexp_console_attached)
{ {
g_lamexp_console_attached = AllocConsole(); if(AllocConsole() != FALSE)
{
g_lamexp_console_attached = true;
}
} }
if(g_lamexp_console_attached) if(g_lamexp_console_attached)
@ -470,17 +483,17 @@ void lamexp_init_console(int argc, char* argv[])
//------------------------------------------------------------------- //-------------------------------------------------------------------
//See: http://support.microsoft.com/default.aspx?scid=kb;en-us;105305 //See: http://support.microsoft.com/default.aspx?scid=kb;en-us;105305
//------------------------------------------------------------------- //-------------------------------------------------------------------
int hCrtStdOut = _open_osfhandle((long) GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT); int hCrtStdOut = _open_osfhandle((intptr_t) GetStdHandle(STD_OUTPUT_HANDLE), _O_BINARY);
int hCrtStdErr = _open_osfhandle((long) GetStdHandle(STD_ERROR_HANDLE), _O_TEXT); int hCrtStdErr = _open_osfhandle((intptr_t) GetStdHandle(STD_ERROR_HANDLE), _O_BINARY);
FILE *hfStdOut = _fdopen(hCrtStdOut, "w"); FILE *hfStdOut = _fdopen(hCrtStdOut, "w");
FILE *hfStderr = _fdopen(hCrtStdErr, "w"); FILE *hfStderr = _fdopen(hCrtStdErr, "w");
*stdout = *hfStdOut; if(hfStdOut) *stdout = *hfStdOut;
*stderr = *hfStderr; if(hfStderr) *stderr = *hfStderr;
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
} }
if(HWND hwndConsole = GetConsoleWindow()) HWND hwndConsole = GetConsoleWindow();
if((hwndConsole != NULL) && (hwndConsole != INVALID_HANDLE_VALUE))
{ {
HMENU hMenu = GetSystemMenu(hwndConsole, 0); HMENU hMenu = GetSystemMenu(hwndConsole, 0);
EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED); EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
@ -523,7 +536,7 @@ lamexp_cpu_t lamexp_detect_cpu_features(void)
memcpy(CPUIdentificationString + 4, &CPUInfo[3], sizeof(int)); memcpy(CPUIdentificationString + 4, &CPUInfo[3], sizeof(int));
memcpy(CPUIdentificationString + 8, &CPUInfo[2], sizeof(int)); memcpy(CPUIdentificationString + 8, &CPUInfo[2], sizeof(int));
features.intel = (_stricmp(CPUIdentificationString, "GenuineIntel") == 0); features.intel = (_stricmp(CPUIdentificationString, "GenuineIntel") == 0);
strcpy_s(features.vendor, 0x40, CPUIdentificationString); strncpy_s(features.vendor, 0x40, CPUIdentificationString, _TRUNCATE);
if(CPUInfo[0] >= 1) if(CPUInfo[0] >= 1)
{ {
@ -559,10 +572,10 @@ lamexp_cpu_t lamexp_detect_cpu_features(void)
} }
} }
strcpy_s(features.brand, 0x40, CPUBrandString); strncpy_s(features.brand, 0x40, CPUBrandString, _TRUNCATE);
if(strlen(features.brand) < 1) strcpy_s(features.brand, 0x40, "Unknown"); if(strlen(features.brand) < 1) strncpy_s(features.brand, 0x40, "Unknown", _TRUNCATE);
if(strlen(features.vendor) < 1) strcpy_s(features.vendor, 0x40, "Unknown"); if(strlen(features.vendor) < 1) strncpy_s(features.vendor, 0x40, "Unknown", _TRUNCATE);
#if !defined(_M_X64 ) && !defined(_M_IA64) #if !defined(_M_X64 ) && !defined(_M_IA64)
if(!IsWow64ProcessPtr || !GetNativeSystemInfoPtr) if(!IsWow64ProcessPtr || !GetNativeSystemInfoPtr)
@ -908,7 +921,7 @@ void lamexp_ipc_send(unsigned int command, const char* message)
lamexp_ipc->command = command; lamexp_ipc->command = command;
if(message) if(message)
{ {
strcpy_s(lamexp_ipc->parameter, 4096, message); strncpy_s(lamexp_ipc->parameter, 4096, message, _TRUNCATE);
} }
if(g_lamexp_ipc_ptr.semaphore_write->acquire()) if(g_lamexp_ipc_ptr.semaphore_write->acquire())
@ -944,7 +957,7 @@ void lamexp_ipc_read(unsigned int *command, char* message, size_t buffSize)
if(!(lamexp_ipc->reserved_1 || lamexp_ipc->reserved_2)) if(!(lamexp_ipc->reserved_1 || lamexp_ipc->reserved_2))
{ {
*command = lamexp_ipc->command; *command = lamexp_ipc->command;
strcpy_s(message, buffSize, lamexp_ipc->parameter); strncpy_s(message, buffSize, lamexp_ipc->parameter, _TRUNCATE);
} }
else else
{ {

View File

@ -126,6 +126,7 @@ SIZE_T lamexp_dbg_private_bytes(void);
//Helper macros //Helper macros
#define LAMEXP_DELETE(PTR) if(PTR) { delete PTR; PTR = NULL; } #define LAMEXP_DELETE(PTR) if(PTR) { delete PTR; PTR = NULL; }
#define LAMEXP_SAFE_FREE(PTR) if(PTR) { free((void*) PTR); PTR = NULL; }
#define LAMEXP_CLOSE(HANDLE) if(HANDLE != NULL && HANDLE != INVALID_HANDLE_VALUE) { CloseHandle(HANDLE); HANDLE = NULL; } #define LAMEXP_CLOSE(HANDLE) if(HANDLE != NULL && HANDLE != INVALID_HANDLE_VALUE) { CloseHandle(HANDLE); HANDLE = NULL; }
#define QWCHAR(STR) reinterpret_cast<const wchar_t*>(STR.utf16()) #define QWCHAR(STR) reinterpret_cast<const wchar_t*>(STR.utf16())
#define WCHAR2QSTR(STR) QString::fromUtf16(reinterpret_cast<const unsigned short*>(STR)) #define WCHAR2QSTR(STR) QString::fromUtf16(reinterpret_cast<const unsigned short*>(STR))