From 59611b8b378238e5a589a87061d06fe4f337d1a0 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Thu, 26 Nov 2015 00:34:30 +0100 Subject: Windows: solve crash caused by system function FormatMessage failure on rare cases. --- src/Common/Dlgcode.c | 18 ++++++++++++++---- src/Common/Dlgcode.h | 2 +- src/Setup/Setup.c | 17 +++++++++++++---- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index 48dc1dd2..73957fec 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -570,6 +570,8 @@ DWORD handleWin32Error (HWND hwndDlg, const char* srcPos) { PWSTR lpMsgBuf; DWORD dwError = GetLastError (); + wchar_t szErrorValue[32]; + wchar_t* pszDesc; if (Silent || dwError == 0 || dwError == ERROR_INVALID_WINDOW_HANDLE) return dwError; @@ -583,7 +585,7 @@ DWORD handleWin32Error (HWND hwndDlg, const char* srcPos) } FormatMessageW ( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwError, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ @@ -592,8 +594,16 @@ DWORD handleWin32Error (HWND hwndDlg, const char* srcPos) NULL ); - MessageBoxW (hwndDlg, AppendSrcPos (lpMsgBuf, srcPos).c_str (), lpszTitle, ICON_HAND); - LocalFree (lpMsgBuf); + if (lpMsgBuf) + pszDesc = (wchar_t*) lpMsgBuf; + else + { + StringCbPrintfW (szErrorValue, sizeof (szErrorValue), L"Error 0x%.8X", dwError); + pszDesc = szErrorValue; + } + + MessageBoxW (hwndDlg, AppendSrcPos (pszDesc, srcPos).c_str (), lpszTitle, ICON_HAND); + if (lpMsgBuf) LocalFree (lpMsgBuf); // User-friendly hardware error explanation if (IsDiskError (dwError)) @@ -612,7 +622,7 @@ BOOL translateWin32Error (wchar_t *lpszMsgBuf, int nWSizeOfBuf) { DWORD dwError = GetLastError (); - if (FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, + if (FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwError, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ lpszMsgBuf, nWSizeOfBuf, NULL)) { diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h index 2b6aee18..af983a63 100644 --- a/src/Common/Dlgcode.h +++ b/src/Common/Dlgcode.h @@ -562,7 +562,7 @@ std::string IntToString (int val); std::wstring IntToWideString (int val); inline std::wstring AppendSrcPos (const wchar_t* msg, const char* srcPos) { - return std::wstring (msg) + L"\n\nSource: " + SingleStringToWide (srcPos); + return std::wstring (msg? msg : L"") + L"\n\nSource: " + SingleStringToWide (srcPos); } // Display a wait dialog while calling the provided callback with the given parameter diff --git a/src/Setup/Setup.c b/src/Setup/Setup.c index fd6d8912..828de703 100644 --- a/src/Setup/Setup.c +++ b/src/Setup/Setup.c @@ -941,9 +941,11 @@ err: LPVOID lpMsgBuf; DWORD dwError = GetLastError (); wchar_t szTmp2[700]; + wchar_t szErrorValue[16]; + wchar_t* pszDesc; FormatMessage ( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwError, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ @@ -952,13 +954,20 @@ err: NULL ); + if (lpMsgBuf) + pszDesc = (wchar_t*) lpMsgBuf; + else + { + StringCbPrintfW (szErrorValue, sizeof (szErrorValue), L"0x%.8X", dwError); + pszDesc = szErrorValue; + } if (bUninstall == FALSE) - StringCbPrintfW (szTmp2, sizeof(szTmp2), GetString ("INSTALL_OF_FAILED"), szTmp, lpMsgBuf); + StringCbPrintfW (szTmp2, sizeof(szTmp2), GetString ("INSTALL_OF_FAILED"), szTmp, pszDesc); else - StringCbPrintfW (szTmp2, sizeof(szTmp2), GetString ("UNINSTALL_OF_FAILED"), szTmp, lpMsgBuf); + StringCbPrintfW (szTmp2, sizeof(szTmp2), GetString ("UNINSTALL_OF_FAILED"), szTmp, pszDesc); - LocalFree (lpMsgBuf); + if (lpMsgBuf) LocalFree (lpMsgBuf); if (!Silent && MessageBoxW (hwndDlg, szTmp2, lpszTitle, MB_YESNO | MB_ICONHAND) != IDYES) return FALSE; -- cgit v1.2.3