From 30198dbcee79d3241f2b906a50fca00cc335ee47 Mon Sep 17 00:00:00 2001 From: Ben Boeckel <ben.boeckel@kitware.com> Date: Mon, 25 Mar 2019 09:35:04 -0400 Subject: [PATCH] DynamicLoader: fix error reporting on Windows Windows was reporting errors in `wchar_t` which was not reinterpreted as UTF-8 which is expected from kwsys errors. This basically made error messages appear as truncated since the UCS-2 byte array had embedded byte NUL characters. --- DynamicLoader.cxx | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/DynamicLoader.cxx b/DynamicLoader.cxx index a85690f7..17432f3c 100644 --- a/DynamicLoader.cxx +++ b/DynamicLoader.cxx @@ -247,24 +247,38 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( # endif } +# define DYNLOAD_ERROR_BUFFER_SIZE 1024 + const char* DynamicLoader::LastError() { - LPVOID lpMsgBuf = NULL; - - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR)&lpMsgBuf, 0, NULL); + wchar_t lpMsgBuf[DYNLOAD_ERROR_BUFFER_SIZE + 1]; + + DWORD error = GetLastError(); + DWORD length = FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + lpMsgBuf, DYNLOAD_ERROR_BUFFER_SIZE, NULL); + + static char str[DYNLOAD_ERROR_BUFFER_SIZE + 1]; + + if (length < 1) { + /* FormatMessage failed. Use a default message. */ + _snprintf(str, DYNLOAD_ERROR_BUFFER_SIZE, + "DynamicLoader encountered error 0x%X. " + "FormatMessage failed with error 0x%X", + error, GetLastError()); + return str; + } - if (!lpMsgBuf) { - return NULL; + if (!WideCharToMultiByte(CP_UTF8, 0, lpMsgBuf, -1, str, + DYNLOAD_ERROR_BUFFER_SIZE, NULL, NULL)) { + /* WideCharToMultiByte failed. Use a default message. */ + _snprintf(str, DYNLOAD_ERROR_BUFFER_SIZE, + "DynamicLoader encountered error 0x%X. " + "WideCharToMultiByte failed with error 0x%X", + error, GetLastError()); } - static char* str = 0; - delete[] str; - str = strcpy(new char[strlen((char*)lpMsgBuf) + 1], (char*)lpMsgBuf); - // Free the buffer. - LocalFree(lpMsgBuf); return str; } -- GitLab