@joebigelow / wix / commits / 13482e72

Require children of thmutil Billboard elements to be BillboardPanel.

Sean Hall committed Jun 3, 2021 at 16:23 UTC 13482e726fd148eaa58eb95e358e13e390d63148
5 files changed +180 -103
src/libs/dutil/WixToolset.DUtil/inc/dutil.h
+6
@@ -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; }
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; }
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; }
125 #define ExitOnFailureDebugTraceSource(d, x, s, ...) if (FAILED(x)) { ExitTraceDebugSource(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; }
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; }
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; }
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; }
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__); }
133
134 #define ExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_DEFAULT, x, s, __VA_ARGS__)
135 #define ExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_DEFAULT, x, s, __VA_ARGS__)
136 #define ExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_DEFAULT, x, s, __VA_ARGS__)
137 #define ExitOnFailure(x, s, ...) ExitOnFailureSource(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__)
140 #define ExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_DEFAULT, x, s, __VA_ARGS__)
141 #define ExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_DEFAULT, p, x, e, s, __VA_ARGS__)
142 #define ExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_DEFAULT, p, x, s, __VA_ARGS__)
143 #define ExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_DEFAULT, p, x, e, s, __VA_ARGS__)
144 #define ExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_DEFAULT, p, 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__)
148
149 // release macros
150 #define ReleaseObject(x) if (x) { x->Release(); }
src/libs/dutil/WixToolset.DUtil/inc/memutil.h
+7
@@ -44,6 +44,13 @@ HRESULT DAPI MemEnsureArraySize(
44 __in SIZE_T cbArrayType,
45 __in DWORD dwGrowthCount
46 );
47 +HRESULT DAPI MemEnsureArraySizeForNewItems(
48 + __inout LPVOID* ppvArray,
49 + __in DWORD cArray,
50 + __in DWORD cNewItems,
51 + __in SIZE_T cbArrayType,
52 + __in DWORD dwGrowthCount
53 + );
54 HRESULT DAPI MemInsertIntoArray(
55 __deref_inout_bcount((cExistingArray + cInsertItems) * cbArrayType) LPVOID* ppvArray,
56 __in DWORD dwInsertIndex,
src/libs/dutil/WixToolset.DUtil/memutil.cpp
+22 -1
@@ -214,6 +214,27 @@ LExit:
214 }
215
216
217 +extern "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 +
233 +LExit:
234 + return hr;
235 +}
236 +
237 +
238 extern "C" HRESULT DAPI MemInsertIntoArray(
239 __deref_inout_bcount((cExistingArray + cInsertItems) * cbArrayType) LPVOID* ppvArray,
240 __in DWORD dwInsertIndex,
@@ -232,7 +253,7 @@ extern "C" HRESULT DAPI MemInsertIntoArray(
253 ExitFunction1(hr = S_OK);
254 }
255
235 - hr = MemEnsureArraySize(ppvArray, cExistingArray + cInsertItems, cbArrayType, dwGrowthCount);
256 + hr = MemEnsureArraySizeForNewItems(ppvArray, cExistingArray, cInsertItems, cbArrayType, dwGrowthCount);
257 MemExitOnFailure(hr, "Failed to resize array while inserting items");
258
259 pbArray = reinterpret_cast<BYTE *>(*ppvArray);
src/libs/dutil/WixToolset.DUtil/thmutil.cpp
+144 -101
@@ -9,14 +9,18 @@
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__)
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__)
13 #define ThmExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_THMUTIL, x, s, __VA_ARGS__)
14 #define ThmExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_THMUTIL, p, x, e, s, __VA_ARGS__)
15 #define ThmExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_THMUTIL, p, x, s, __VA_ARGS__)
16 #define ThmExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_THMUTIL, p, x, e, s, __VA_ARGS__)
17 #define ThmExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_THMUTIL, p, 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__)
21 #define ThmExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_THMUTIL, g, x, s, __VA_ARGS__)
22
23 +
24 // from CommCtrl.h
25 #ifndef BS_COMMANDLINK
26 #define BS_COMMANDLINK 0x0000000EL
@@ -136,13 +140,23 @@ static HRESULT ParseControl(
140 __in IXMLDOMNode* pixn,
141 __in THEME* pTheme,
142 __in THEME_CONTROL* pControl,
139 - __in BOOL fSkipDimensions,
143 __in_opt THEME_PAGE* pPage
144 );
145 +static void InitializeThemeControl(
146 + THEME_CONTROL* pControl
147 + );
148 static HRESULT ParseActions(
149 __in IXMLDOMNode* pixn,
150 __in THEME_CONTROL* pControl
151 );
152 +static 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 + );
160 static HRESULT ParseColumns(
161 __in IXMLDOMNode* pixn,
162 __in THEME_CONTROL* pControl
@@ -2366,9 +2380,13 @@ static HRESULT ParseImageLists(
2380 }
2381
2382 ++i;
2383 + ReleaseNullObject(pixnImage);
2384 }
2385 }
2386 ++dwImageListIndex;
2387 +
2388 + ReleaseNullObject(pixnlImages);
2389 + ReleaseNullObject(pixnImageList);
2390 }
2391
2392 LExit:
@@ -2438,7 +2456,6 @@ static HRESULT ParseControls(
2456 BSTR bstrType = NULL;
2457 DWORD cNewControls = 0;
2458 DWORD iControl = 0;
2441 - DWORD iPageControl = 0;
2459 DWORD* pcControls = NULL;
2460 THEME_CONTROL** prgControls = NULL;
2461
@@ -2458,14 +2475,13 @@ static HRESULT ParseControls(
2475 ExitFunction1(hr = S_OK);
2476 }
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);
2479 ThmExitOnFailure(hr, "Failed to reallocate theme controls.");
2480
2481 cNewControls += *pcControls;
2482
2483 if (pPage)
2484 {
2468 - iPageControl = pPage->cControlIndices;
2485 pPage->cControlIndices += cNewControls;
2486 }
2487
@@ -2556,24 +2572,12 @@ static HRESULT ParseControls(
2572 THEME_CONTROL* pControl = *prgControls + iControl;
2573 pControl->type = type;
2574
2559 - // billboard children are always the size of the billboard
2560 - BOOL fBillboardSizing = pParentControl && THEME_CONTROL_TYPE_BILLBOARD == pParentControl->type;
2561 -
2562 - hr = ParseControl(hModule, wzRelativePath, pixn, pTheme, pControl, fBillboardSizing, pPage);
2575 + hr = ParseControl(hModule, wzRelativePath, pixn, pTheme, pControl, pPage);
2576 ThmExitOnFailure(hr, "Failed to parse control.");
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 -
2578 if (pPage)
2579 {
2580 pControl->wPageId = pPage->wId;
2576 - ++iPageControl;
2581 }
2582
2583 ++iControl;
@@ -2606,16 +2610,19 @@ static HRESULT ParseControl(
2610 __in IXMLDOMNode* pixn,
2611 __in THEME* pTheme,
2612 __in THEME_CONTROL* pControl,
2609 - __in BOOL fSkipDimensions,
2613 __in_opt THEME_PAGE* pPage
2614 )
2615 {
2616 HRESULT hr = S_OK;
2617 + BOOL fFound = FALSE;
2618 DWORD dwValue = 0;
2619 BOOL fValue = FALSE;
2620 BSTR bstrText = NULL;
2621 BOOL fAnyTextChildren = FALSE;
2622 BOOL fAnyNoteChildren = FALSE;
2623 + BOOL fSkipDimensions = FALSE;
2624 +
2625 + InitializeThemeControl(pControl);
2626
2627 hr = XmlGetAttributeEx(pixn, L"Name", &pControl->sczName);
2628 if (E_NOTFOUND == hr)
@@ -2682,24 +2689,12 @@ static HRESULT ParseControl(
2689 ThmExitOnFailure(hr, "Failed while parsing control image.");
2690
2691 hr = XmlGetAttributeNumber(pixn, L"SourceX", reinterpret_cast<DWORD*>(&pControl->nSourceX));
2685 - if (S_FALSE == hr)
2686 - {
2687 - pControl->nSourceX = -1;
2688 - }
2692 ThmExitOnFailure(hr, "Failed when querying control SourceX attribute.");
2693
2694 hr = XmlGetAttributeNumber(pixn, L"SourceY", reinterpret_cast<DWORD*>(&pControl->nSourceY));
2692 - if (S_FALSE == hr)
2693 - {
2694 - pControl->nSourceY = -1;
2695 - }
2695 ThmExitOnFailure(hr, "Failed when querying control SourceY attribute.");
2696
2697 hr = XmlGetAttributeNumber(pixn, L"FontId", &pControl->dwFontId);
2699 - if (S_FALSE == hr)
2700 - {
2701 - pControl->dwFontId = THEME_INVALID_ID;
2702 - }
2698 ThmExitOnFailure(hr, "Failed when querying control FontId attribute.");
2699
2700 // Parse the optional window style.
@@ -2777,40 +2772,30 @@ static HRESULT ParseControl(
2772 ThmExitOnFailure(hr, "Failed to parse note text nodes of the control.");
2773 }
2774
2780 - if (fAnyTextChildren || fAnyNoteChildren)
2775 + if (!fAnyTextChildren && !fAnyNoteChildren)
2776 {
2782 - pControl->uStringId = UINT_MAX;
2783 - }
2784 - else
2785 - {
2786 - hr = XmlGetAttributeNumber(pixn, L"StringId", reinterpret_cast<DWORD*>(&pControl->uStringId));
2787 - ThmExitOnFailure(hr, "Failed when querying control StringId attribute.");
2777 + hr = XmlGetAttributeNumber(pixn, L"StringId", &dwValue);
2778 + ThmExitOnOptionalXmlQueryFailure(hr, fFound, "Failed when querying control StringId attribute.");
2779
2789 - if (S_FALSE == hr)
2780 + if (fFound)
2781 {
2791 - pControl->uStringId = UINT_MAX;
2792 -
2793 - if (THEME_CONTROL_TYPE_BILLBOARD == pControl->type || THEME_CONTROL_TYPE_PANEL == pControl->type)
2794 - {
2795 - // Billboards and panels have child elements and we don't want to pick up child element text in the parents.
2796 - hr = S_OK;
2797 - }
2798 - else
2782 + pControl->uStringId = dwValue;
2783 + }
2784 + else
2785 + {
2786 + // Billboards and panels have child elements and we don't want to pick up child element text in the parents.
2787 + if (THEME_CONTROL_TYPE_BILLBOARD != pControl->type && THEME_CONTROL_TYPE_PANEL != pControl->type)
2788 {
2789 hr = XmlGetText(pixn, &bstrText);
2801 - ThmExitOnFailure(hr, "Failed to get control inner text.");
2790 + ThmExitOnOptionalXmlQueryFailure(hr, fFound, "Failed to get control inner text.");
2791
2803 - if (S_OK == hr)
2792 + if (fFound)
2793 {
2794 hr = StrAllocString(&pControl->sczText, bstrText, 0);
2795 ThmExitOnFailure(hr, "Failed to copy control text.");
2796
2797 ReleaseNullBSTR(bstrText);
2798 }
2810 - else if (S_FALSE == hr)
2811 - {
2812 - hr = S_OK;
2813 - }
2799 }
2800 }
2801 }
@@ -2832,7 +2817,7 @@ static HRESULT ParseControl(
2817 }
2818 ThmExitOnFailure(hr, "Failed when querying Billboard/@Interval attribute.");
2819
2835 - hr = ParseControls(hModule, wzRelativePath, pixn, pTheme, pControl, pPage);
2820 + hr = ParseBillboardPanels(hModule, wzRelativePath, pixn, pTheme, pControl, pPage);
2821 ThmExitOnFailure(hr, "Failed to parse billboard children.");
2822 }
2823 else if (THEME_CONTROL_TYPE_COMMANDLINK == pControl->type)
@@ -2860,17 +2845,9 @@ static HRESULT ParseControl(
2845 else if (THEME_CONTROL_TYPE_HYPERLINK == pControl->type || THEME_CONTROL_TYPE_BUTTON == pControl->type)
2846 {
2847 hr = XmlGetAttributeNumber(pixn, L"HoverFontId", &pControl->dwFontHoverId);
2863 - if (S_FALSE == hr)
2864 - {
2865 - pControl->dwFontHoverId = THEME_INVALID_ID;
2866 - }
2848 ThmExitOnFailure(hr, "Failed when querying control HoverFontId attribute.");
2849
2850 hr = XmlGetAttributeNumber(pixn, L"SelectedFontId", &pControl->dwFontSelectedId);
2870 - if (S_FALSE == hr)
2871 - {
2872 - pControl->dwFontSelectedId = THEME_INVALID_ID;
2873 - }
2851 ThmExitOnFailure(hr, "Failed when querying control SelectedFontId attribute.");
2852 }
2853 else if (THEME_CONTROL_TYPE_LABEL == pControl->type)
@@ -3038,6 +3015,18 @@ LExit:
3015 return hr;
3016 }
3017
3018 +static 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 +
3030
3031 static HRESULT ParseActions(
3032 __in IXMLDOMNode* pixn,
@@ -3134,6 +3123,61 @@ LExit:
3123 }
3124
3125
3126 +static 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 +
3173 +LExit:
3174 + ReleaseObject(pixnl);
3175 + ReleaseObject(pixnChild);
3176 +
3177 + return hr;
3178 +}
3179 +
3180 +
3181 static HRESULT ParseColumns(
3182 __in IXMLDOMNode* pixn,
3183 __in THEME_CONTROL* pControl
@@ -3186,6 +3230,7 @@ static HRESULT ParseColumns(
3230
3231 ++i;
3232 ReleaseNullBSTR(bstrText);
3233 + ReleaseNullObject(pixnChild);
3234 }
3235 }
3236
@@ -3209,8 +3254,6 @@ static HRESULT ParseRadioButtons(
3254 {
3255 HRESULT hr = S_OK;
3256 DWORD cRadioButtons = 0;
3212 - DWORD iControl = 0;
3213 - DWORD iPageControl = 0;
3257 IXMLDOMNodeList* pixnlRadioButtons = NULL;
3258 IXMLDOMNodeList* pixnl = NULL;
3259 IXMLDOMNode* pixnRadioButtons = NULL;
@@ -3241,53 +3284,54 @@ static HRESULT ParseRadioButtons(
3284 hr = pixnl->get_length(reinterpret_cast<long*>(&cRadioButtons));
3285 ThmExitOnFailure(hr, "Failed to count the number of RadioButton nodes.");
3286
3244 - if (cRadioButtons)
3287 + if (!cRadioButtons)
3288 {
3246 - if (pPage)
3247 - {
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;
3289 + ThmExitWithRootFailure(hr, E_INVALIDDATA, "RadioButtons must have at least one RadioButton.");
3290 + }
3291
3260 - while (S_OK == (hr = XmlNextElement(pixnl, &pixnChild, NULL)))
3261 - {
3262 - pControl = *prgControls + iControl;
3263 - pControl->type = THEME_CONTROL_TYPE_RADIOBUTTON;
3292 + if (pPage)
3293 + {
3294 + pPage->cControlIndices += cRadioButtons;
3295 + }
3296
3265 - hr = ParseControl(hModule, wzRelativePath, pixnChild, pTheme, pControl, FALSE, pPage);
3266 - ThmExitOnFailure(hr, "Failed to parse control.");
3297 + hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgControls), *pcControls, cRadioButtons, sizeof(THEME_CONTROL), 0);
3298 + ThmExitOnFailure(hr, "Failed to ensure theme control array size for RadioButtons.");
3299
3268 - if (fFirst)
3269 - {
3270 - pControl->dwStyle |= WS_GROUP;
3271 - fFirst = FALSE;
3272 - }
3300 + fFirst = TRUE;
3301
3274 - hr = StrAllocString(&pControl->sczVariable, sczName, 0);
3275 - ThmExitOnFailure(hr, "Failed to copy radio button variable.");
3302 + while (S_OK == (hr = XmlNextElement(pixnl, &pixnChild, NULL)))
3303 + {
3304 + pControl = *prgControls + *pcControls;
3305 + pControl->type = THEME_CONTROL_TYPE_RADIOBUTTON;
3306 + *pcControls += 1;
3307
3277 - if (pPage)
3278 - {
3279 - pControl->wPageId = pPage->wId;
3280 - ++iPageControl;
3281 - }
3308 + hr = ParseControl(hModule, wzRelativePath, pixnChild, pTheme, pControl, pPage);
3309 + ThmExitOnFailure(hr, "Failed to parse control.");
3310
3283 - ++iControl;
3311 + if (fFirst)
3312 + {
3313 + pControl->dwStyle |= WS_GROUP;
3314 + fFirst = FALSE;
3315 }
3316
3286 - if (!fFirst)
3317 + hr = StrAllocString(&pControl->sczVariable, sczName, 0);
3318 + ThmExitOnFailure(hr, "Failed to copy radio button variable.");
3319 +
3320 + if (pPage)
3321 {
3288 - pControl->fLastRadioButton = TRUE;
3322 + pControl->wPageId = pPage->wId;
3323 }
3324 +
3325 + ReleaseNullObject(pixnChild);
3326 }
3327 +
3328 + if (!fFirst)
3329 + {
3330 + pControl->fLastRadioButton = TRUE;
3331 + }
3332 +
3333 + ReleaseObject(pixnl);
3334 + ReleaseObject(pixnRadioButtons);
3335 }
3336
3337 LExit:
@@ -3616,7 +3660,7 @@ static HRESULT EnsureFontInstance(
3660 }
3661 }
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);
3664 ThmExitOnFailure(hr, "Failed to allocate memory for font instances.");
3665
3666 pFontInstance = pFont->rgFontInstances + pFont->cFontInstances;
@@ -5017,8 +5061,7 @@ static HRESULT LoadControls(
5061 __fallthrough;
5062 case THEME_CONTROL_TYPE_PANEL:
5063 wzWindowClass = THEME_WC_PANEL;
5020 - dwWindowBits |= WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
5021 - dwWindowExBits |= WS_EX_TRANSPARENT | WS_EX_CONTROLPARENT;
5064 + dwWindowExBits |= WS_EX_CONTROLPARENT;
5065 #ifdef DEBUG
5066 StrAllocFormatted(&pControl->sczText, L"Panel '%ls', id: %d", pControl->sczName, pControl->wId);
5067 #endif
src/libs/dutil/WixToolset.DUtil/verutil.cpp
+1 -1
@@ -458,7 +458,7 @@ DAPI_(HRESULT) VerParseVersion(
458 break;
459 }
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);
463
464 VERUTIL_VERSION_RELEASE_LABEL* pReleaseLabel = pVersion->rgReleaseLabels + pVersion->cReleaseLabels;