aboutsummaryrefslogtreecommitdiff
path: root/src/libs
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-06-03 16:23:17 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-06-04 14:57:11 -0500
commit13482e726fd148eaa58eb95e358e13e390d63148 (patch)
tree087fb264038cb06922299c2e7aebdc98871e7124 /src/libs
parentaec32210e4be3b58a1271e0703ec23130cd9ebe3 (diff)
downloadwix-13482e726fd148eaa58eb95e358e13e390d63148.tar.gz
wix-13482e726fd148eaa58eb95e358e13e390d63148.tar.bz2
wix-13482e726fd148eaa58eb95e358e13e390d63148.zip
Require children of thmutil Billboard elements to be BillboardPanel.
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/dutil/WixToolset.DUtil/inc/dutil.h6
-rw-r--r--src/libs/dutil/WixToolset.DUtil/inc/memutil.h7
-rw-r--r--src/libs/dutil/WixToolset.DUtil/memutil.cpp23
-rw-r--r--src/libs/dutil/WixToolset.DUtil/thmutil.cpp245
-rw-r--r--src/libs/dutil/WixToolset.DUtil/verutil.cpp2
5 files changed, 180 insertions, 103 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/dutil.h b/src/libs/dutil/WixToolset.DUtil/inc/dutil.h
index 52da066c..618349da 100644
--- a/src/libs/dutil/WixToolset.DUtil/inc/dutil.h
+++ b/src/libs/dutil/WixToolset.DUtil/inc/dutil.h
@@ -121,24 +121,30 @@ void DAPI Dutil_RootFailure(__in_z LPCSTR szFile, __in int iLine, __in HRESULT h
121#define ExitWithLastErrorSource(d, x, s, ...) { DWORD Dutil_er = ::GetLastError(); x = HRESULT_FROM_WIN32(Dutil_er); if (!FAILED(x)) { x = E_FAIL; } Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceSource(d, x, s, __VA_ARGS__); goto LExit; } 121#define ExitWithLastErrorSource(d, x, s, ...) { DWORD Dutil_er = ::GetLastError(); x = HRESULT_FROM_WIN32(Dutil_er); if (!FAILED(x)) { x = E_FAIL; } Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceSource(d, x, s, __VA_ARGS__); goto LExit; }
122#define ExitOnFailureSource(d, x, s, ...) if (FAILED(x)) { ExitTraceSource(d, x, s, __VA_ARGS__); goto LExit; } 122#define ExitOnFailureSource(d, x, s, ...) if (FAILED(x)) { ExitTraceSource(d, x, s, __VA_ARGS__); goto LExit; }
123#define ExitOnRootFailureSource(d, x, s, ...) if (FAILED(x)) { Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceSource(d, x, s, __VA_ARGS__); goto LExit; } 123#define ExitOnRootFailureSource(d, x, s, ...) if (FAILED(x)) { Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceSource(d, x, s, __VA_ARGS__); goto LExit; }
124#define ExitWithRootFailureSource(d, x, e, s, ...) { x = FAILED(e) ? e : E_FAIL; Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceSource(d, x, s, __VA_ARGS__); goto LExit; }
124#define ExitOnFailureDebugTraceSource(d, x, s, ...) if (FAILED(x)) { ExitTraceDebugSource(d, x, s, __VA_ARGS__); goto LExit; } 125#define ExitOnFailureDebugTraceSource(d, x, s, ...) if (FAILED(x)) { ExitTraceDebugSource(d, x, s, __VA_ARGS__); goto LExit; }
125#define ExitOnNullSource(d, p, x, e, s, ...) if (NULL == p) { x = e; Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceSource(d, x, s, __VA_ARGS__); goto LExit; } 126#define ExitOnNullSource(d, p, x, e, s, ...) if (NULL == p) { x = e; Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceSource(d, x, s, __VA_ARGS__); goto LExit; }
126#define ExitOnNullWithLastErrorSource(d, p, x, s, ...) if (NULL == p) { DWORD Dutil_er = ::GetLastError(); x = HRESULT_FROM_WIN32(Dutil_er); if (!FAILED(x)) { x = E_FAIL; } Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceSource(d, x, s, __VA_ARGS__); goto LExit; } 127#define ExitOnNullWithLastErrorSource(d, p, x, s, ...) if (NULL == p) { DWORD Dutil_er = ::GetLastError(); x = HRESULT_FROM_WIN32(Dutil_er); if (!FAILED(x)) { x = E_FAIL; } Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceSource(d, x, s, __VA_ARGS__); goto LExit; }
127#define ExitOnNullDebugTraceSource(d, p, x, e, s, ...) if (NULL == p) { x = e; Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceDebugSource(d, x, s, __VA_ARGS__); goto LExit; } 128#define ExitOnNullDebugTraceSource(d, p, x, e, s, ...) if (NULL == p) { x = e; Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceDebugSource(d, x, s, __VA_ARGS__); goto LExit; }
128#define ExitOnInvalidHandleWithLastErrorSource(d, p, x, s, ...) if (INVALID_HANDLE_VALUE == p) { DWORD Dutil_er = ::GetLastError(); x = HRESULT_FROM_WIN32(Dutil_er); if (!FAILED(x)) { x = E_FAIL; } Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceSource(d, x, s, __VA_ARGS__); goto LExit; } 129#define ExitOnInvalidHandleWithLastErrorSource(d, p, x, s, ...) if (INVALID_HANDLE_VALUE == p) { DWORD Dutil_er = ::GetLastError(); x = HRESULT_FROM_WIN32(Dutil_er); if (!FAILED(x)) { x = E_FAIL; } Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceSource(d, x, s, __VA_ARGS__); goto LExit; }
129#define ExitOnWin32ErrorSource(d, e, x, s, ...) if (ERROR_SUCCESS != e) { x = HRESULT_FROM_WIN32(e); if (!FAILED(x)) { x = E_FAIL; } Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceSource(d, x, s, __VA_ARGS__); goto LExit; } 130#define ExitOnWin32ErrorSource(d, e, x, s, ...) if (ERROR_SUCCESS != e) { x = HRESULT_FROM_WIN32(e); if (!FAILED(x)) { x = E_FAIL; } Dutil_RootFailure(__FILE__, __LINE__, x); ExitTraceSource(d, x, s, __VA_ARGS__); goto LExit; }
131#define ExitOnOptionalXmlQueryFailureSource(d, x, b, s, ...) { { if (S_FALSE == x || E_NOTFOUND == x) { b = FALSE; x = S_OK; } else { b = SUCCEEDED(x); } }; ExitOnRootFailureSource(d, x, s, __VA_ARGS__); }
132#define ExitOnRequiredXmlQueryFailureSource(d, x, s, ...) { if (S_FALSE == x) { x = E_NOTFOUND; } ExitOnRootFailureSource(d, x, s, __VA_ARGS__); }
130 133
131#define ExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_DEFAULT, x, s, __VA_ARGS__) 134#define ExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_DEFAULT, x, s, __VA_ARGS__)
132#define ExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_DEFAULT, x, s, __VA_ARGS__) 135#define ExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_DEFAULT, x, s, __VA_ARGS__)
133#define ExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_DEFAULT, x, s, __VA_ARGS__) 136#define ExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_DEFAULT, x, s, __VA_ARGS__)
134#define ExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_DEFAULT, x, s, __VA_ARGS__) 137#define ExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_DEFAULT, x, s, __VA_ARGS__)
135#define ExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_DEFAULT, x, s, __VA_ARGS__) 138#define ExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_DEFAULT, x, s, __VA_ARGS__)
139#define ExitWithRootFailure(x, e, s, ...) ExitWithRootFailureSource(DUTIL_SOURCE_DEFAULT, x, e, s, __VA_ARGS__)
136#define ExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_DEFAULT, x, s, __VA_ARGS__) 140#define ExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_DEFAULT, x, s, __VA_ARGS__)
137#define ExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_DEFAULT, p, x, e, s, __VA_ARGS__) 141#define ExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_DEFAULT, p, x, e, s, __VA_ARGS__)
138#define ExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_DEFAULT, p, x, s, __VA_ARGS__) 142#define ExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_DEFAULT, p, x, s, __VA_ARGS__)
139#define ExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_DEFAULT, p, x, e, s, __VA_ARGS__) 143#define ExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_DEFAULT, p, x, e, s, __VA_ARGS__)
140#define ExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_DEFAULT, p, x, s, __VA_ARGS__) 144#define ExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_DEFAULT, p, x, s, __VA_ARGS__)
141#define ExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_DEFAULT, e, x, s, __VA_ARGS__) 145#define ExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_DEFAULT, e, x, s, __VA_ARGS__)
146#define ExitOnOptionalXmlQueryFailure(x, b, s, ...) ExitOnOptionalXmlQueryFailureSource(DUTIL_SOURCE_DEFAULT, x, b, s, __VA_ARGS__)
147#define ExitOnRequiredXmlQueryFailure(x, s, ...) ExitOnRequiredXmlQueryFailureSource(DUTIL_SOURCE_DEFAULT, x, s, __VA_ARGS__)
142 148
143// release macros 149// release macros
144#define ReleaseObject(x) if (x) { x->Release(); } 150#define ReleaseObject(x) if (x) { x->Release(); }
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/memutil.h b/src/libs/dutil/WixToolset.DUtil/inc/memutil.h
index 49f86e0a..b8269269 100644
--- a/src/libs/dutil/WixToolset.DUtil/inc/memutil.h
+++ b/src/libs/dutil/WixToolset.DUtil/inc/memutil.h
@@ -44,6 +44,13 @@ HRESULT DAPI MemEnsureArraySize(
44 __in SIZE_T cbArrayType, 44 __in SIZE_T cbArrayType,
45 __in DWORD dwGrowthCount 45 __in DWORD dwGrowthCount
46 ); 46 );
47HRESULT DAPI MemEnsureArraySizeForNewItems(
48 __inout LPVOID* ppvArray,
49 __in DWORD cArray,
50 __in DWORD cNewItems,
51 __in SIZE_T cbArrayType,
52 __in DWORD dwGrowthCount
53 );
47HRESULT DAPI MemInsertIntoArray( 54HRESULT DAPI MemInsertIntoArray(
48 __deref_inout_bcount((cExistingArray + cInsertItems) * cbArrayType) LPVOID* ppvArray, 55 __deref_inout_bcount((cExistingArray + cInsertItems) * cbArrayType) LPVOID* ppvArray,
49 __in DWORD dwInsertIndex, 56 __in DWORD dwInsertIndex,
diff --git a/src/libs/dutil/WixToolset.DUtil/memutil.cpp b/src/libs/dutil/WixToolset.DUtil/memutil.cpp
index c805a9c0..977c189e 100644
--- a/src/libs/dutil/WixToolset.DUtil/memutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/memutil.cpp
@@ -214,6 +214,27 @@ LExit:
214} 214}
215 215
216 216
217extern "C" HRESULT DAPI MemEnsureArraySizeForNewItems(
218 __inout LPVOID* ppvArray,
219 __in DWORD cArray,
220 __in DWORD cNewItems,
221 __in SIZE_T cbArrayType,
222 __in DWORD dwGrowthCount
223 )
224{
225 HRESULT hr = S_OK;
226 DWORD cNew = 0;
227
228 hr = ::DWordAdd(cArray, cNewItems, &cNew);
229 MemExitOnFailure(hr, "Integer overflow when calculating new element count.");
230
231 hr = MemEnsureArraySize(ppvArray, cNew, cbArrayType, dwGrowthCount);
232
233LExit:
234 return hr;
235}
236
237
217extern "C" HRESULT DAPI MemInsertIntoArray( 238extern "C" HRESULT DAPI MemInsertIntoArray(
218 __deref_inout_bcount((cExistingArray + cInsertItems) * cbArrayType) LPVOID* ppvArray, 239 __deref_inout_bcount((cExistingArray + cInsertItems) * cbArrayType) LPVOID* ppvArray,
219 __in DWORD dwInsertIndex, 240 __in DWORD dwInsertIndex,
@@ -232,7 +253,7 @@ extern "C" HRESULT DAPI MemInsertIntoArray(
232 ExitFunction1(hr = S_OK); 253 ExitFunction1(hr = S_OK);
233 } 254 }
234 255
235 hr = MemEnsureArraySize(ppvArray, cExistingArray + cInsertItems, cbArrayType, dwGrowthCount); 256 hr = MemEnsureArraySizeForNewItems(ppvArray, cExistingArray, cInsertItems, cbArrayType, dwGrowthCount);
236 MemExitOnFailure(hr, "Failed to resize array while inserting items"); 257 MemExitOnFailure(hr, "Failed to resize array while inserting items");
237 258
238 pbArray = reinterpret_cast<BYTE *>(*ppvArray); 259 pbArray = reinterpret_cast<BYTE *>(*ppvArray);
diff --git a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp
index d200a0ea..599021bf 100644
--- a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp
@@ -9,14 +9,18 @@
9#define ThmExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_THMUTIL, x, s, __VA_ARGS__) 9#define ThmExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_THMUTIL, x, s, __VA_ARGS__)
10#define ThmExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_THMUTIL, x, s, __VA_ARGS__) 10#define ThmExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_THMUTIL, x, s, __VA_ARGS__)
11#define ThmExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_THMUTIL, x, s, __VA_ARGS__) 11#define ThmExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_THMUTIL, x, s, __VA_ARGS__)
12#define ThmExitWithRootFailure(x, e, s, ...) ExitWithRootFailureSource(DUTIL_SOURCE_THMUTIL, x, e, s, __VA_ARGS__)
12#define ThmExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_THMUTIL, x, s, __VA_ARGS__) 13#define ThmExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_THMUTIL, x, s, __VA_ARGS__)
13#define ThmExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_THMUTIL, p, x, e, s, __VA_ARGS__) 14#define ThmExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_THMUTIL, p, x, e, s, __VA_ARGS__)
14#define ThmExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_THMUTIL, p, x, s, __VA_ARGS__) 15#define ThmExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_THMUTIL, p, x, s, __VA_ARGS__)
15#define ThmExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_THMUTIL, p, x, e, s, __VA_ARGS__) 16#define ThmExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_THMUTIL, p, x, e, s, __VA_ARGS__)
16#define ThmExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_THMUTIL, p, x, s, __VA_ARGS__) 17#define ThmExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_THMUTIL, p, x, s, __VA_ARGS__)
17#define ThmExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_THMUTIL, e, x, s, __VA_ARGS__) 18#define ThmExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_THMUTIL, e, x, s, __VA_ARGS__)
19#define ThmExitOnOptionalXmlQueryFailure(x, b, s, ...) ExitOnOptionalXmlQueryFailureSource(DUTIL_SOURCE_THMUTIL, x, b, s, __VA_ARGS__)
20#define ThmExitOnRequiredXmlQueryFailure(x, s, ...) ExitOnRequiredXmlQueryFailureSource(DUTIL_SOURCE_THMUTIL, x, s, __VA_ARGS__)
18#define ThmExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_THMUTIL, g, x, s, __VA_ARGS__) 21#define ThmExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_THMUTIL, g, x, s, __VA_ARGS__)
19 22
23
20// from CommCtrl.h 24// from CommCtrl.h
21#ifndef BS_COMMANDLINK 25#ifndef BS_COMMANDLINK
22#define BS_COMMANDLINK 0x0000000EL 26#define BS_COMMANDLINK 0x0000000EL
@@ -136,13 +140,23 @@ static HRESULT ParseControl(
136 __in IXMLDOMNode* pixn, 140 __in IXMLDOMNode* pixn,
137 __in THEME* pTheme, 141 __in THEME* pTheme,
138 __in THEME_CONTROL* pControl, 142 __in THEME_CONTROL* pControl,
139 __in BOOL fSkipDimensions,
140 __in_opt THEME_PAGE* pPage 143 __in_opt THEME_PAGE* pPage
141 ); 144 );
145static void InitializeThemeControl(
146 THEME_CONTROL* pControl
147 );
142static HRESULT ParseActions( 148static HRESULT ParseActions(
143 __in IXMLDOMNode* pixn, 149 __in IXMLDOMNode* pixn,
144 __in THEME_CONTROL* pControl 150 __in THEME_CONTROL* pControl
145 ); 151 );
152static HRESULT ParseBillboardPanels(
153 __in_opt HMODULE hModule,
154 __in_opt LPCWSTR wzRelativePath,
155 __in IXMLDOMNode* pElement,
156 __in THEME* pTheme,
157 __in THEME_CONTROL* pParentControl,
158 __in_opt THEME_PAGE* pPage
159 );
146static HRESULT ParseColumns( 160static HRESULT ParseColumns(
147 __in IXMLDOMNode* pixn, 161 __in IXMLDOMNode* pixn,
148 __in THEME_CONTROL* pControl 162 __in THEME_CONTROL* pControl
@@ -2366,9 +2380,13 @@ static HRESULT ParseImageLists(
2366 } 2380 }
2367 2381
2368 ++i; 2382 ++i;
2383 ReleaseNullObject(pixnImage);
2369 } 2384 }
2370 } 2385 }
2371 ++dwImageListIndex; 2386 ++dwImageListIndex;
2387
2388 ReleaseNullObject(pixnlImages);
2389 ReleaseNullObject(pixnImageList);
2372 } 2390 }
2373 2391
2374LExit: 2392LExit:
@@ -2438,7 +2456,6 @@ static HRESULT ParseControls(
2438 BSTR bstrType = NULL; 2456 BSTR bstrType = NULL;
2439 DWORD cNewControls = 0; 2457 DWORD cNewControls = 0;
2440 DWORD iControl = 0; 2458 DWORD iControl = 0;
2441 DWORD iPageControl = 0;
2442 DWORD* pcControls = NULL; 2459 DWORD* pcControls = NULL;
2443 THEME_CONTROL** prgControls = NULL; 2460 THEME_CONTROL** prgControls = NULL;
2444 2461
@@ -2458,14 +2475,13 @@ static HRESULT ParseControls(
2458 ExitFunction1(hr = S_OK); 2475 ExitFunction1(hr = S_OK);
2459 } 2476 }
2460 2477
2461 hr = MemReAllocArray(reinterpret_cast<LPVOID*>(prgControls), *pcControls, sizeof(THEME_CONTROL), cNewControls); 2478 hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgControls), *pcControls, cNewControls, sizeof(THEME_CONTROL), 0);
2462 ThmExitOnFailure(hr, "Failed to reallocate theme controls."); 2479 ThmExitOnFailure(hr, "Failed to reallocate theme controls.");
2463 2480
2464 cNewControls += *pcControls; 2481 cNewControls += *pcControls;
2465 2482
2466 if (pPage) 2483 if (pPage)
2467 { 2484 {
2468 iPageControl = pPage->cControlIndices;
2469 pPage->cControlIndices += cNewControls; 2485 pPage->cControlIndices += cNewControls;
2470 } 2486 }
2471 2487
@@ -2556,24 +2572,12 @@ static HRESULT ParseControls(
2556 THEME_CONTROL* pControl = *prgControls + iControl; 2572 THEME_CONTROL* pControl = *prgControls + iControl;
2557 pControl->type = type; 2573 pControl->type = type;
2558 2574
2559 // billboard children are always the size of the billboard 2575 hr = ParseControl(hModule, wzRelativePath, pixn, pTheme, pControl, pPage);
2560 BOOL fBillboardSizing = pParentControl && THEME_CONTROL_TYPE_BILLBOARD == pParentControl->type;
2561
2562 hr = ParseControl(hModule, wzRelativePath, pixn, pTheme, pControl, fBillboardSizing, pPage);
2563 ThmExitOnFailure(hr, "Failed to parse control."); 2576 ThmExitOnFailure(hr, "Failed to parse control.");
2564 2577
2565 if (fBillboardSizing)
2566 {
2567 pControl->nX = pControl->nDefaultDpiX = 0;
2568 pControl->nY = pControl->nDefaultDpiY = 0;
2569 pControl->nWidth = pControl->nDefaultDpiWidth = 0;
2570 pControl->nHeight = pControl->nDefaultDpiHeight = 0;
2571 }
2572
2573 if (pPage) 2578 if (pPage)
2574 { 2579 {
2575 pControl->wPageId = pPage->wId; 2580 pControl->wPageId = pPage->wId;
2576 ++iPageControl;
2577 } 2581 }
2578 2582
2579 ++iControl; 2583 ++iControl;
@@ -2606,16 +2610,19 @@ static HRESULT ParseControl(
2606 __in IXMLDOMNode* pixn, 2610 __in IXMLDOMNode* pixn,
2607 __in THEME* pTheme, 2611 __in THEME* pTheme,
2608 __in THEME_CONTROL* pControl, 2612 __in THEME_CONTROL* pControl,
2609 __in BOOL fSkipDimensions,
2610 __in_opt THEME_PAGE* pPage 2613 __in_opt THEME_PAGE* pPage
2611 ) 2614 )
2612{ 2615{
2613 HRESULT hr = S_OK; 2616 HRESULT hr = S_OK;
2617 BOOL fFound = FALSE;
2614 DWORD dwValue = 0; 2618 DWORD dwValue = 0;
2615 BOOL fValue = FALSE; 2619 BOOL fValue = FALSE;
2616 BSTR bstrText = NULL; 2620 BSTR bstrText = NULL;
2617 BOOL fAnyTextChildren = FALSE; 2621 BOOL fAnyTextChildren = FALSE;
2618 BOOL fAnyNoteChildren = FALSE; 2622 BOOL fAnyNoteChildren = FALSE;
2623 BOOL fSkipDimensions = FALSE;
2624
2625 InitializeThemeControl(pControl);
2619 2626
2620 hr = XmlGetAttributeEx(pixn, L"Name", &pControl->sczName); 2627 hr = XmlGetAttributeEx(pixn, L"Name", &pControl->sczName);
2621 if (E_NOTFOUND == hr) 2628 if (E_NOTFOUND == hr)
@@ -2682,24 +2689,12 @@ static HRESULT ParseControl(
2682 ThmExitOnFailure(hr, "Failed while parsing control image."); 2689 ThmExitOnFailure(hr, "Failed while parsing control image.");
2683 2690
2684 hr = XmlGetAttributeNumber(pixn, L"SourceX", reinterpret_cast<DWORD*>(&pControl->nSourceX)); 2691 hr = XmlGetAttributeNumber(pixn, L"SourceX", reinterpret_cast<DWORD*>(&pControl->nSourceX));
2685 if (S_FALSE == hr)
2686 {
2687 pControl->nSourceX = -1;
2688 }
2689 ThmExitOnFailure(hr, "Failed when querying control SourceX attribute."); 2692 ThmExitOnFailure(hr, "Failed when querying control SourceX attribute.");
2690 2693
2691 hr = XmlGetAttributeNumber(pixn, L"SourceY", reinterpret_cast<DWORD*>(&pControl->nSourceY)); 2694 hr = XmlGetAttributeNumber(pixn, L"SourceY", reinterpret_cast<DWORD*>(&pControl->nSourceY));
2692 if (S_FALSE == hr)
2693 {
2694 pControl->nSourceY = -1;
2695 }
2696 ThmExitOnFailure(hr, "Failed when querying control SourceY attribute."); 2695 ThmExitOnFailure(hr, "Failed when querying control SourceY attribute.");
2697 2696
2698 hr = XmlGetAttributeNumber(pixn, L"FontId", &pControl->dwFontId); 2697 hr = XmlGetAttributeNumber(pixn, L"FontId", &pControl->dwFontId);
2699 if (S_FALSE == hr)
2700 {
2701 pControl->dwFontId = THEME_INVALID_ID;
2702 }
2703 ThmExitOnFailure(hr, "Failed when querying control FontId attribute."); 2698 ThmExitOnFailure(hr, "Failed when querying control FontId attribute.");
2704 2699
2705 // Parse the optional window style. 2700 // Parse the optional window style.
@@ -2777,40 +2772,30 @@ static HRESULT ParseControl(
2777 ThmExitOnFailure(hr, "Failed to parse note text nodes of the control."); 2772 ThmExitOnFailure(hr, "Failed to parse note text nodes of the control.");
2778 } 2773 }
2779 2774
2780 if (fAnyTextChildren || fAnyNoteChildren) 2775 if (!fAnyTextChildren && !fAnyNoteChildren)
2781 { 2776 {
2782 pControl->uStringId = UINT_MAX; 2777 hr = XmlGetAttributeNumber(pixn, L"StringId", &dwValue);
2783 } 2778 ThmExitOnOptionalXmlQueryFailure(hr, fFound, "Failed when querying control StringId attribute.");
2784 else
2785 {
2786 hr = XmlGetAttributeNumber(pixn, L"StringId", reinterpret_cast<DWORD*>(&pControl->uStringId));
2787 ThmExitOnFailure(hr, "Failed when querying control StringId attribute.");
2788 2779
2789 if (S_FALSE == hr) 2780 if (fFound)
2790 { 2781 {
2791 pControl->uStringId = UINT_MAX; 2782 pControl->uStringId = dwValue;
2792 2783 }
2793 if (THEME_CONTROL_TYPE_BILLBOARD == pControl->type || THEME_CONTROL_TYPE_PANEL == pControl->type) 2784 else
2794 { 2785 {
2795 // Billboards and panels have child elements and we don't want to pick up child element text in the parents. 2786 // Billboards and panels have child elements and we don't want to pick up child element text in the parents.
2796 hr = S_OK; 2787 if (THEME_CONTROL_TYPE_BILLBOARD != pControl->type && THEME_CONTROL_TYPE_PANEL != pControl->type)
2797 }
2798 else
2799 { 2788 {
2800 hr = XmlGetText(pixn, &bstrText); 2789 hr = XmlGetText(pixn, &bstrText);
2801 ThmExitOnFailure(hr, "Failed to get control inner text."); 2790 ThmExitOnOptionalXmlQueryFailure(hr, fFound, "Failed to get control inner text.");
2802 2791
2803 if (S_OK == hr) 2792 if (fFound)
2804 { 2793 {
2805 hr = StrAllocString(&pControl->sczText, bstrText, 0); 2794 hr = StrAllocString(&pControl->sczText, bstrText, 0);
2806 ThmExitOnFailure(hr, "Failed to copy control text."); 2795 ThmExitOnFailure(hr, "Failed to copy control text.");
2807 2796
2808 ReleaseNullBSTR(bstrText); 2797 ReleaseNullBSTR(bstrText);
2809 } 2798 }
2810 else if (S_FALSE == hr)
2811 {
2812 hr = S_OK;
2813 }
2814 } 2799 }
2815 } 2800 }
2816 } 2801 }
@@ -2832,7 +2817,7 @@ static HRESULT ParseControl(
2832 } 2817 }
2833 ThmExitOnFailure(hr, "Failed when querying Billboard/@Interval attribute."); 2818 ThmExitOnFailure(hr, "Failed when querying Billboard/@Interval attribute.");
2834 2819
2835 hr = ParseControls(hModule, wzRelativePath, pixn, pTheme, pControl, pPage); 2820 hr = ParseBillboardPanels(hModule, wzRelativePath, pixn, pTheme, pControl, pPage);
2836 ThmExitOnFailure(hr, "Failed to parse billboard children."); 2821 ThmExitOnFailure(hr, "Failed to parse billboard children.");
2837 } 2822 }
2838 else if (THEME_CONTROL_TYPE_COMMANDLINK == pControl->type) 2823 else if (THEME_CONTROL_TYPE_COMMANDLINK == pControl->type)
@@ -2860,17 +2845,9 @@ static HRESULT ParseControl(
2860 else if (THEME_CONTROL_TYPE_HYPERLINK == pControl->type || THEME_CONTROL_TYPE_BUTTON == pControl->type) 2845 else if (THEME_CONTROL_TYPE_HYPERLINK == pControl->type || THEME_CONTROL_TYPE_BUTTON == pControl->type)
2861 { 2846 {
2862 hr = XmlGetAttributeNumber(pixn, L"HoverFontId", &pControl->dwFontHoverId); 2847 hr = XmlGetAttributeNumber(pixn, L"HoverFontId", &pControl->dwFontHoverId);
2863 if (S_FALSE == hr)
2864 {
2865 pControl->dwFontHoverId = THEME_INVALID_ID;
2866 }
2867 ThmExitOnFailure(hr, "Failed when querying control HoverFontId attribute."); 2848 ThmExitOnFailure(hr, "Failed when querying control HoverFontId attribute.");
2868 2849
2869 hr = XmlGetAttributeNumber(pixn, L"SelectedFontId", &pControl->dwFontSelectedId); 2850 hr = XmlGetAttributeNumber(pixn, L"SelectedFontId", &pControl->dwFontSelectedId);
2870 if (S_FALSE == hr)
2871 {
2872 pControl->dwFontSelectedId = THEME_INVALID_ID;
2873 }
2874 ThmExitOnFailure(hr, "Failed when querying control SelectedFontId attribute."); 2851 ThmExitOnFailure(hr, "Failed when querying control SelectedFontId attribute.");
2875 } 2852 }
2876 else if (THEME_CONTROL_TYPE_LABEL == pControl->type) 2853 else if (THEME_CONTROL_TYPE_LABEL == pControl->type)
@@ -3038,6 +3015,18 @@ LExit:
3038 return hr; 3015 return hr;
3039} 3016}
3040 3017
3018static void InitializeThemeControl(
3019 THEME_CONTROL* pControl
3020 )
3021{
3022 pControl->dwFontHoverId = THEME_INVALID_ID;
3023 pControl->dwFontId = THEME_INVALID_ID;
3024 pControl->dwFontSelectedId = THEME_INVALID_ID;
3025 pControl->nSourceX = -1;
3026 pControl->nSourceY = -1;
3027 pControl->uStringId = UINT_MAX;
3028}
3029
3041 3030
3042static HRESULT ParseActions( 3031static HRESULT ParseActions(
3043 __in IXMLDOMNode* pixn, 3032 __in IXMLDOMNode* pixn,
@@ -3134,6 +3123,61 @@ LExit:
3134} 3123}
3135 3124
3136 3125
3126static HRESULT ParseBillboardPanels(
3127 __in_opt HMODULE hModule,
3128 __in_opt LPCWSTR wzRelativePath,
3129 __in IXMLDOMNode* pElement,
3130 __in THEME* pTheme,
3131 __in THEME_CONTROL* pParentControl,
3132 __in_opt THEME_PAGE* pPage
3133 )
3134{
3135 HRESULT hr = S_OK;
3136 IXMLDOMNodeList* pixnl = NULL;
3137 IXMLDOMNode* pixnChild = NULL;
3138 DWORD dwValue = 0;
3139 THEME_CONTROL* pControl = NULL;
3140
3141 hr = XmlSelectNodes(pElement, L"BillboardPanel", &pixnl);
3142 ThmExitOnFailure(hr, "Failed to select child billboard panel nodes.");
3143
3144 hr = pixnl->get_length(reinterpret_cast<long*>(&dwValue));
3145 ThmExitOnFailure(hr, "Failed to count the number of billboard panel nodes.");
3146
3147 if (!dwValue)
3148 {
3149 ThmExitWithRootFailure(hr, E_INVALIDDATA, "Billboard must have at least one BillboardPanel.");
3150 }
3151
3152 hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(&pParentControl->rgControls), pParentControl->cControls, dwValue, sizeof(THEME_CONTROL), 0);
3153 ThmExitOnFailure(hr, "Failed to ensure theme control array size for BillboardPanels.");
3154
3155 while (S_OK == (hr = XmlNextElement(pixnl, &pixnChild, NULL)))
3156 {
3157 pControl = pParentControl->rgControls + pParentControl->cControls;
3158 pParentControl->cControls += 1;
3159 pControl->type = THEME_CONTROL_TYPE_PANEL;
3160 InitializeThemeControl(pControl);
3161
3162 if (pPage)
3163 {
3164 pControl->wPageId = pPage->wId;
3165 }
3166
3167 hr = ParseControls(hModule, wzRelativePath, pixnChild, pTheme, pControl, pPage);
3168 ThmExitOnFailure(hr, "Failed to parse control.");
3169
3170 ReleaseNullObject(pixnChild);
3171 }
3172
3173LExit:
3174 ReleaseObject(pixnl);
3175 ReleaseObject(pixnChild);
3176
3177 return hr;
3178}
3179
3180
3137static HRESULT ParseColumns( 3181static HRESULT ParseColumns(
3138 __in IXMLDOMNode* pixn, 3182 __in IXMLDOMNode* pixn,
3139 __in THEME_CONTROL* pControl 3183 __in THEME_CONTROL* pControl
@@ -3186,6 +3230,7 @@ static HRESULT ParseColumns(
3186 3230
3187 ++i; 3231 ++i;
3188 ReleaseNullBSTR(bstrText); 3232 ReleaseNullBSTR(bstrText);
3233 ReleaseNullObject(pixnChild);
3189 } 3234 }
3190 } 3235 }
3191 3236
@@ -3209,8 +3254,6 @@ static HRESULT ParseRadioButtons(
3209{ 3254{
3210 HRESULT hr = S_OK; 3255 HRESULT hr = S_OK;
3211 DWORD cRadioButtons = 0; 3256 DWORD cRadioButtons = 0;
3212 DWORD iControl = 0;
3213 DWORD iPageControl = 0;
3214 IXMLDOMNodeList* pixnlRadioButtons = NULL; 3257 IXMLDOMNodeList* pixnlRadioButtons = NULL;
3215 IXMLDOMNodeList* pixnl = NULL; 3258 IXMLDOMNodeList* pixnl = NULL;
3216 IXMLDOMNode* pixnRadioButtons = NULL; 3259 IXMLDOMNode* pixnRadioButtons = NULL;
@@ -3241,53 +3284,54 @@ static HRESULT ParseRadioButtons(
3241 hr = pixnl->get_length(reinterpret_cast<long*>(&cRadioButtons)); 3284 hr = pixnl->get_length(reinterpret_cast<long*>(&cRadioButtons));
3242 ThmExitOnFailure(hr, "Failed to count the number of RadioButton nodes."); 3285 ThmExitOnFailure(hr, "Failed to count the number of RadioButton nodes.");
3243 3286
3244 if (cRadioButtons) 3287 if (!cRadioButtons)
3245 { 3288 {
3246 if (pPage) 3289 ThmExitWithRootFailure(hr, E_INVALIDDATA, "RadioButtons must have at least one RadioButton.");
3247 { 3290 }
3248 iPageControl = pPage->cControlIndices;
3249 pPage->cControlIndices += cRadioButtons;
3250 }
3251
3252 hr = MemReAllocArray(reinterpret_cast<LPVOID*>(prgControls), *pcControls, sizeof(THEME_CONTROL), cRadioButtons);
3253 ThmExitOnFailure(hr, "Failed to reallocate theme controls.");
3254
3255 iControl = *pcControls;
3256 *pcControls += cRadioButtons;
3257
3258 fFirst = TRUE;
3259 3291
3260 while (S_OK == (hr = XmlNextElement(pixnl, &pixnChild, NULL))) 3292 if (pPage)
3261 { 3293 {
3262 pControl = *prgControls + iControl; 3294 pPage->cControlIndices += cRadioButtons;
3263 pControl->type = THEME_CONTROL_TYPE_RADIOBUTTON; 3295 }
3264 3296
3265 hr = ParseControl(hModule, wzRelativePath, pixnChild, pTheme, pControl, FALSE, pPage); 3297 hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgControls), *pcControls, cRadioButtons, sizeof(THEME_CONTROL), 0);
3266 ThmExitOnFailure(hr, "Failed to parse control."); 3298 ThmExitOnFailure(hr, "Failed to ensure theme control array size for RadioButtons.");
3267 3299
3268 if (fFirst) 3300 fFirst = TRUE;
3269 {
3270 pControl->dwStyle |= WS_GROUP;
3271 fFirst = FALSE;
3272 }
3273 3301
3274 hr = StrAllocString(&pControl->sczVariable, sczName, 0); 3302 while (S_OK == (hr = XmlNextElement(pixnl, &pixnChild, NULL)))
3275 ThmExitOnFailure(hr, "Failed to copy radio button variable."); 3303 {
3304 pControl = *prgControls + *pcControls;
3305 pControl->type = THEME_CONTROL_TYPE_RADIOBUTTON;
3306 *pcControls += 1;
3276 3307
3277 if (pPage) 3308 hr = ParseControl(hModule, wzRelativePath, pixnChild, pTheme, pControl, pPage);
3278 { 3309 ThmExitOnFailure(hr, "Failed to parse control.");
3279 pControl->wPageId = pPage->wId;
3280 ++iPageControl;
3281 }
3282 3310
3283 ++iControl; 3311 if (fFirst)
3312 {
3313 pControl->dwStyle |= WS_GROUP;
3314 fFirst = FALSE;
3284 } 3315 }
3285 3316
3286 if (!fFirst) 3317 hr = StrAllocString(&pControl->sczVariable, sczName, 0);
3318 ThmExitOnFailure(hr, "Failed to copy radio button variable.");
3319
3320 if (pPage)
3287 { 3321 {
3288 pControl->fLastRadioButton = TRUE; 3322 pControl->wPageId = pPage->wId;
3289 } 3323 }
3324
3325 ReleaseNullObject(pixnChild);
3290 } 3326 }
3327
3328 if (!fFirst)
3329 {
3330 pControl->fLastRadioButton = TRUE;
3331 }
3332
3333 ReleaseObject(pixnl);
3334 ReleaseObject(pixnRadioButtons);
3291 } 3335 }
3292 3336
3293LExit: 3337LExit:
@@ -3616,7 +3660,7 @@ static HRESULT EnsureFontInstance(
3616 } 3660 }
3617 } 3661 }
3618 3662
3619 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pFont->rgFontInstances), pFont->cFontInstances, sizeof(THEME_FONT_INSTANCE), GROW_FONT_INSTANCES); 3663 hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(&pFont->rgFontInstances), pFont->cFontInstances, 1, sizeof(THEME_FONT_INSTANCE), GROW_FONT_INSTANCES);
3620 ThmExitOnFailure(hr, "Failed to allocate memory for font instances."); 3664 ThmExitOnFailure(hr, "Failed to allocate memory for font instances.");
3621 3665
3622 pFontInstance = pFont->rgFontInstances + pFont->cFontInstances; 3666 pFontInstance = pFont->rgFontInstances + pFont->cFontInstances;
@@ -5017,8 +5061,7 @@ static HRESULT LoadControls(
5017 __fallthrough; 5061 __fallthrough;
5018 case THEME_CONTROL_TYPE_PANEL: 5062 case THEME_CONTROL_TYPE_PANEL:
5019 wzWindowClass = THEME_WC_PANEL; 5063 wzWindowClass = THEME_WC_PANEL;
5020 dwWindowBits |= WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; 5064 dwWindowExBits |= WS_EX_CONTROLPARENT;
5021 dwWindowExBits |= WS_EX_TRANSPARENT | WS_EX_CONTROLPARENT;
5022#ifdef DEBUG 5065#ifdef DEBUG
5023 StrAllocFormatted(&pControl->sczText, L"Panel '%ls', id: %d", pControl->sczName, pControl->wId); 5066 StrAllocFormatted(&pControl->sczText, L"Panel '%ls', id: %d", pControl->sczName, pControl->wId);
5024#endif 5067#endif
diff --git a/src/libs/dutil/WixToolset.DUtil/verutil.cpp b/src/libs/dutil/WixToolset.DUtil/verutil.cpp
index 21626f94..8881d7bc 100644
--- a/src/libs/dutil/WixToolset.DUtil/verutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/verutil.cpp
@@ -458,7 +458,7 @@ DAPI_(HRESULT) VerParseVersion(
458 break; 458 break;
459 } 459 }
460 460
461 hr = MemReAllocArray(reinterpret_cast<LPVOID*>(&pVersion->rgReleaseLabels), pVersion->cReleaseLabels, sizeof(VERUTIL_VERSION_RELEASE_LABEL), GROW_RELEASE_LABELS - (pVersion->cReleaseLabels % GROW_RELEASE_LABELS)); 461 hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(&pVersion->rgReleaseLabels), pVersion->cReleaseLabels, 1, sizeof(VERUTIL_VERSION_RELEASE_LABEL), GROW_RELEASE_LABELS);
462 VerExitOnFailure(hr, "Failed to allocate memory for Verutil version release labels '%ls'", wzVersion); 462 VerExitOnFailure(hr, "Failed to allocate memory for Verutil version release labels '%ls'", wzVersion);
463 463
464 VERUTIL_VERSION_RELEASE_LABEL* pReleaseLabel = pVersion->rgReleaseLabels + pVersion->cReleaseLabels; 464 VERUTIL_VERSION_RELEASE_LABEL* pReleaseLabel = pVersion->rgReleaseLabels + pVersion->cReleaseLabels;