diff options
author | Bob Arnson <bob@firegiant.com> | 2023-04-24 22:16:34 -0400 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2023-06-03 01:24:39 -0700 |
commit | 1da29b425658bf1ddc774154d9bccaf940d0bc66 (patch) | |
tree | dda1d3320b8d855b3840e49b37d84d542b6824b7 /src/libs/wcautil | |
parent | 29146461effb7798e054aa9933a88f612237df47 (diff) | |
download | wix-1da29b425658bf1ddc774154d9bccaf940d0bc66.tar.gz wix-1da29b425658bf1ddc774154d9bccaf940d0bc66.tar.bz2 wix-1da29b425658bf1ddc774154d9bccaf940d0bc66.zip |
Fix WcaErrorMessage `cArgs==-1` case.
- Count args before creating message record.
- Document terminating NULL requirement.
- Add terminating NULL in MessageExit* macros.
- Enhance tests for problems encountered fixing this nightmare.
Fixes https://github.com/wixtoolset/issues/issues/7422.
Fixes https://github.com/wixtoolset/issues/issues/7444.
Diffstat (limited to 'src/libs/wcautil')
-rw-r--r-- | src/libs/wcautil/WixToolset.WcaUtil/inc/wcautil.h | 6 | ||||
-rw-r--r-- | src/libs/wcautil/WixToolset.WcaUtil/wcawrap.cpp | 33 |
2 files changed, 23 insertions, 16 deletions
diff --git a/src/libs/wcautil/WixToolset.WcaUtil/inc/wcautil.h b/src/libs/wcautil/WixToolset.WcaUtil/inc/wcautil.h index 9b331b34..b72c8d3f 100644 --- a/src/libs/wcautil/WixToolset.WcaUtil/inc/wcautil.h +++ b/src/libs/wcautil/WixToolset.WcaUtil/inc/wcautil.h | |||
@@ -15,9 +15,9 @@ extern "C" { | |||
15 | 15 | ||
16 | #include "dutil.h" | 16 | #include "dutil.h" |
17 | 17 | ||
18 | #define MessageExitOnLastErrorSource(d, x, e, s, ...) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (FAILED(x)) { ExitTraceSource(d, x, s, __VA_ARGS__); WcaErrorMessage(e, x, MB_OK, -1, __VA_ARGS__); goto LExit; } } | 18 | #define MessageExitOnLastErrorSource(d, x, e, s, ...) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (FAILED(x)) { ExitTraceSource(d, x, s, __VA_ARGS__); WcaErrorMessage(e, x, MB_OK, -1, __VA_ARGS__, NULL); goto LExit; } } |
19 | #define MessageExitOnFailureSource(d, x, e, s, ...) if (FAILED(x)) { ExitTraceSource(d, x, s, __VA_ARGS__); WcaErrorMessage(e, x, INSTALLMESSAGE_ERROR | MB_OK, -1, __VA_ARGS__); goto LExit; } | 19 | #define MessageExitOnFailureSource(d, x, e, s, ...) if (FAILED(x)) { ExitTraceSource(d, x, s, __VA_ARGS__); WcaErrorMessage(e, x, INSTALLMESSAGE_ERROR | MB_OK, -1, __VA_ARGS__, NULL); goto LExit; } |
20 | #define MessageExitOnNullWithLastErrorSource(d, p, x, e, s, ...) if (NULL == p) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (!FAILED(x)) { x = E_FAIL; } ExitTraceSource(d, x, s, __VA_ARGS__); WcaErrorMessage(e, x, MB_OK, -1, __VA_ARGS__); goto LExit; } | 20 | #define MessageExitOnNullWithLastErrorSource(d, p, x, e, s, ...) if (NULL == p) { x = ::GetLastError(); x = HRESULT_FROM_WIN32(x); if (!FAILED(x)) { x = E_FAIL; } ExitTraceSource(d, x, s, __VA_ARGS__); WcaErrorMessage(e, x, MB_OK, -1, __VA_ARGS__, NULL); goto LExit; } |
21 | 21 | ||
22 | #define MessageExitOnLastError(x, e, s, ...) MessageExitOnLastErrorSource(DUTIL_SOURCE_DEFAULT, x, e, s, __VA_ARGS__) | 22 | #define MessageExitOnLastError(x, e, s, ...) MessageExitOnLastErrorSource(DUTIL_SOURCE_DEFAULT, x, e, s, __VA_ARGS__) |
23 | #define MessageExitOnFailure(x, e, s, ...) MessageExitOnFailureSource(DUTIL_SOURCE_DEFAULT, x, e, s, __VA_ARGS__) | 23 | #define MessageExitOnFailure(x, e, s, ...) MessageExitOnFailureSource(DUTIL_SOURCE_DEFAULT, x, e, s, __VA_ARGS__) |
diff --git a/src/libs/wcautil/WixToolset.WcaUtil/wcawrap.cpp b/src/libs/wcautil/WixToolset.WcaUtil/wcawrap.cpp index 86b7602e..9259e97a 100644 --- a/src/libs/wcautil/WixToolset.WcaUtil/wcawrap.cpp +++ b/src/libs/wcautil/WixToolset.WcaUtil/wcawrap.cpp | |||
@@ -27,7 +27,9 @@ WcaErrorMessage() - sends an error message from the CustomAction using | |||
27 | the Error table | 27 | the Error table |
28 | 28 | ||
29 | NOTE: Any and all var_args (...) must be WCHAR* | 29 | NOTE: Any and all var_args (...) must be WCHAR* |
30 | If you pass -1 to cArgs the count will be determined | 30 | If you pass -1 to cArgs, the count will be determined by |
31 | looking for a trailing NULL argment. If you omit a terminating | ||
32 | NULL, the results are undefined and probably crashy. | ||
31 | ********************************************************************/ | 33 | ********************************************************************/ |
32 | extern "C" UINT __cdecl WcaErrorMessage( | 34 | extern "C" UINT __cdecl WcaErrorMessage( |
33 | __in int iError, | 35 | __in int iError, |
@@ -41,6 +43,22 @@ extern "C" UINT __cdecl WcaErrorMessage( | |||
41 | MSIHANDLE hRec = NULL; | 43 | MSIHANDLE hRec = NULL; |
42 | va_list args = NULL; | 44 | va_list args = NULL; |
43 | 45 | ||
46 | if (-1 == cArgs) | ||
47 | { | ||
48 | LPCWSTR wzArg = NULL; | ||
49 | va_list iter = NULL; | ||
50 | |||
51 | va_start(iter, cArgs); | ||
52 | cArgs = 0; | ||
53 | |||
54 | while (NULL != (wzArg = va_arg(iter, WCHAR*)) && L'\0' != *wzArg) | ||
55 | { | ||
56 | ++cArgs; | ||
57 | } | ||
58 | |||
59 | va_end(iter); | ||
60 | } | ||
61 | |||
44 | uiType |= INSTALLMESSAGE_ERROR; // ensure error type is set | 62 | uiType |= INSTALLMESSAGE_ERROR; // ensure error type is set |
45 | hRec = ::MsiCreateRecord(cArgs + 2); | 63 | hRec = ::MsiCreateRecord(cArgs + 2); |
46 | if (!hRec) | 64 | if (!hRec) |
@@ -56,18 +74,6 @@ extern "C" UINT __cdecl WcaErrorMessage( | |||
56 | ExitOnFailure(HRESULT_FROM_WIN32(er), "failed to set hresult code into error message"); | 74 | ExitOnFailure(HRESULT_FROM_WIN32(er), "failed to set hresult code into error message"); |
57 | 75 | ||
58 | va_start(args, cArgs); | 76 | va_start(args, cArgs); |
59 | if (-1 == cArgs) | ||
60 | { | ||
61 | LPCWSTR wzArg = NULL; | ||
62 | va_list iter = args; | ||
63 | cArgs = 0; | ||
64 | |||
65 | while (NULL != (wzArg = va_arg(iter, WCHAR*)) && L'\0' != *wzArg) | ||
66 | { | ||
67 | ++cArgs; | ||
68 | } | ||
69 | } | ||
70 | |||
71 | for (INT i = 0; i < cArgs; i++) | 77 | for (INT i = 0; i < cArgs; i++) |
72 | { | 78 | { |
73 | er = ::MsiRecordSetStringW(hRec, i + 3, va_arg(args, WCHAR*)); | 79 | er = ::MsiRecordSetStringW(hRec, i + 3, va_arg(args, WCHAR*)); |
@@ -76,6 +82,7 @@ extern "C" UINT __cdecl WcaErrorMessage( | |||
76 | va_end(args); | 82 | va_end(args); |
77 | 83 | ||
78 | er = WcaProcessMessage(static_cast<INSTALLMESSAGE>(uiType), hRec); | 84 | er = WcaProcessMessage(static_cast<INSTALLMESSAGE>(uiType), hRec); |
85 | |||
79 | LExit: | 86 | LExit: |
80 | if (args) | 87 | if (args) |
81 | { | 88 | { |