Add wxMSWFormatMessage() and use it from other places

Don't duplicate calls to ::FormatMessage(), which is difficult to use
correctly, in wxCrashReport and wxWebRequestWinHTTP, but just reuse the
same code that was already present in wxSysErrorMsgStr() after
refactoring it into a reusable function allowing to specify the module
name to use for the error code lookup (before falling back to
interpreting it as system error code).

This fixes not trimming the trailing "\r\n" from the string in the other
places (wxWinHTTPErrorToString() had code to do it, but it was wrong,
while wxCrashContext::GetExceptionString() didn't do it at all) and
avoids duplication.
This commit is contained in:
Vadim Zeitlin
2021-01-09 17:41:49 +01:00
parent 2869e1ccd6
commit 5d256988be
4 changed files with 31 additions and 48 deletions

View File

@@ -972,6 +972,10 @@ enum wxWinVersion
WXDLLIMPEXP_BASE wxWinVersion wxGetWinVersion();
// This is similar to wxSysErrorMsgStr(), but takes an extra HMODULE parameter
// specific to wxMSW.
WXDLLIMPEXP_BASE wxString wxMSWFormatMessage(DWORD nErrCode, HMODULE hModule = 0);
#if wxUSE_GUI && defined(__WXMSW__)
// cursor stuff

View File

@@ -1056,19 +1056,22 @@ unsigned long wxSysErrorCode()
#endif //Win/Unix
}
wxString wxSysErrorMsgStr(unsigned long nErrCode)
{
if ( nErrCode == 0 )
nErrCode = wxSysErrorCode();
#if defined(__WINDOWS__)
wxString wxMSWFormatMessage(DWORD nErrCode, HMODULE hModule)
{
DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS;
if ( hModule )
flags |= FORMAT_MESSAGE_FROM_HMODULE;
// get error message from system
LPVOID lpMsgBuf;
if ( ::FormatMessage
(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
flags,
hModule,
nErrCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
@@ -1103,6 +1106,17 @@ wxString wxSysErrorMsgStr(unsigned long nErrCode)
}
return str;
}
#endif // __WINDOWS__
wxString wxSysErrorMsgStr(unsigned long nErrCode)
{
if ( nErrCode == 0 )
nErrCode = wxSysErrorCode();
#if defined(__WINDOWS__)
return wxMSWFormatMessage(nErrCode);
#else // !__WINDOWS__
char buffer[1024];
char *errorMsg = buffer;

View File

@@ -28,6 +28,7 @@
#include "wx/msw/debughlp.h"
#include "wx/msw/crashrpt.h"
#include "wx/msw/private.h"
// ----------------------------------------------------------------------------
// classes
@@ -356,20 +357,7 @@ wxString wxCrashContext::GetExceptionString() const
default:
// unknown exception, ask NTDLL for the name
if ( !::FormatMessage
(
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_HMODULE,
::GetModuleHandle(wxT("NTDLL.DLL")),
code,
0,
wxStringBuffer(s, 1024),
1024,
0
) )
{
s.Printf(wxT("UNKNOWN_EXCEPTION(%d)"), code);
}
s = wxMSWFormatMessage(code, ::GetModuleHandle(wxT("NTDLL.DLL")));
}
#undef CASE_EXCEPTION

View File

@@ -16,6 +16,7 @@
#include "wx/mstream.h"
#include "wx/uri.h"
#include "wx/msw/private.h"
#include "wx/msw/private/webrequest_winhttp.h"
#ifndef WX_PRECOMP
@@ -59,31 +60,6 @@
// Helper functions
static wxString wxWinHTTPErrorToString(DWORD errorCode)
{
wxString errorString;
LPVOID msgBuf;
if ( FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_HMODULE,
GetModuleHandle(TEXT("WINHTTP")),
errorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPWSTR)&msgBuf,
0, NULL) )
{
errorString.assign((LPWSTR)msgBuf);
LocalFree(msgBuf);
// Truncate trailing \n\r
if ( errorString.size() > 2 )
errorString.resize(errorString.size());
}
return errorString;
}
static wxString wxWinHTTPQueryHeaderString(HINTERNET hRequest, DWORD dwInfoLevel,
LPCWSTR pwszName = WINHTTP_HEADER_NAME_BY_INDEX)
{
@@ -254,7 +230,8 @@ void wxWebRequestWinHTTP::CreateResponse()
void wxWebRequestWinHTTP::SetFailed(DWORD errorCode)
{
wxString failMessage = wxWinHTTPErrorToString(errorCode);
wxString failMessage = wxMSWFormatMessage(errorCode,
GetModuleHandle(TEXT("WINHTTP")));
SetState(wxWebRequest::State_Failed, failMessage);
}