@joebigelow / wix / commits / 273c69f3

WIXFEAT:6210 Change data type of versions to strings.

Sean Hall committed Oct 17, 2020 at 19:12 UTC 273c69f34311f4f4e5f6b5896e71d0788f12d96a
38 files changed +505 -429
src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
+6 -6
@@ -416,7 +416,7 @@ struct BA_ONDETECTCOMPATIBLEMSIPACKAGE_ARGS
416 DWORD cbSize;
417 LPCWSTR wzPackageId;
418 LPCWSTR wzCompatiblePackageId;
419 - DWORD64 dw64CompatiblePackageVersion;
419 + LPCWSTR wzCompatiblePackageVersion;
420 };
421
422 struct BA_ONDETECTCOMPATIBLEMSIPACKAGE_RESULTS
@@ -443,7 +443,7 @@ struct BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_ARGS
443 BOOTSTRAPPER_RELATION_TYPE relationType;
444 LPCWSTR wzBundleTag;
445 BOOL fPerMachine;
446 - DWORD64 dw64Version;
446 + LPCWSTR wzVersion;
447 };
448
449 struct BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_RESULTS
@@ -499,7 +499,7 @@ struct BA_ONDETECTRELATEDBUNDLE_ARGS
499 BOOTSTRAPPER_RELATION_TYPE relationType;
500 LPCWSTR wzBundleTag;
501 BOOL fPerMachine;
502 - DWORD64 dw64Version;
502 + LPCWSTR wzVersion;
503 BOOTSTRAPPER_RELATED_OPERATION operation;
504 };
505
@@ -516,7 +516,7 @@ struct BA_ONDETECTRELATEDMSIPACKAGE_ARGS
516 LPCWSTR wzUpgradeCode;
517 LPCWSTR wzProductCode;
518 BOOL fPerMachine;
519 - DWORD64 dw64Version;
519 + LPCWSTR wzVersion;
520 BOOTSTRAPPER_RELATED_OPERATION operation;
521 };
522
@@ -545,7 +545,7 @@ struct BA_ONDETECTUPDATE_ARGS
545 DWORD cbSize;
546 LPCWSTR wzUpdateLocation;
547 DWORD64 dw64Size;
548 - DWORD64 dw64Version;
548 + LPCWSTR wzVersion;
549 LPCWSTR wzTitle;
550 LPCWSTR wzSummary;
551 LPCWSTR wzContentType;
@@ -781,7 +781,7 @@ struct BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_ARGS
781 DWORD cbSize;
782 LPCWSTR wzPackageId;
783 LPCWSTR wzCompatiblePackageId;
784 - DWORD64 dw64CompatiblePackageVersion;
784 + LPCWSTR wzCompatiblePackageVersion;
785 BOOTSTRAPPER_REQUEST_STATE recommendedState;
786 };
787
src/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h
+5 -3
@@ -258,8 +258,10 @@ typedef struct _BAENGINE_GETVARIABLEVERSION_ARGS
258 typedef struct _BAENGINE_GETVARIABLEVERSION_RESULTS
259 {
260 DWORD cbSize;
261 - // The contents of qwValue may be sensitive, if variable is hidden should keep value encrypted and SecureZeroMemory.
262 - DWORD64 qwValue;
261 + // The contents of wzValue may be sensitive, if variable is hidden should keep value encrypted and SecureZeroFree.
262 + LPWSTR wzValue;
263 + // Should be initialized to the size of wzValue.
264 + DWORD cchValue;
265 } BAENGINE_GETVARIABLEVERSION_RESULTS;
266
267 typedef struct _BAENGINE_LAUNCHAPPROVEDEXE_ARGS
@@ -410,7 +412,7 @@ typedef struct _BAENGINE_SETVARIABLEVERSION_ARGS
412 {
413 DWORD cbSize;
414 LPCWSTR wzVariable;
413 - DWORD64 qwValue;
415 + LPCWSTR wzValue;
416 } BAENGINE_SETVARIABLEVERSION_ARGS;
417
418 typedef struct _BAENGINE_SETVARIABLEVERSION_RESULTS
src/WixToolset.BootstrapperCore.Native/inc/BundleExtensionEngine.h
+5 -3
@@ -107,8 +107,10 @@ typedef struct _BUNDLE_EXTENSION_ENGINE_GETVARIABLEVERSION_ARGS
107 typedef struct _BUNDLE_EXTENSION_ENGINE_GETVARIABLEVERSION_RESULTS
108 {
109 DWORD cbSize;
110 - // The contents of qwValue may be sensitive, if variable is hidden should keep value encrypted and SecureZeroMemory.
111 - DWORD64 qwValue;
110 + // The contents of wzValue may be sensitive, if variable is hidden should keep value encrypted and SecureZeroFree.
111 + LPWSTR wzValue;
112 + // Should be initialized to the size of wzValue.
113 + DWORD cchValue;
114 } BUNDLE_EXTENSION_ENGINE_GETVARIABLEVERSION_RESULTS;
115
116 typedef struct _BUNDLE_EXTENSION_ENGINE_LOG_ARGS
@@ -152,7 +154,7 @@ typedef struct _BUNDLE_EXTENSION_ENGINE_SETVARIABLEVERSION_ARGS
154 {
155 DWORD cbSize;
156 LPCWSTR wzVariable;
155 - DWORD64 qwValue;
157 + LPCWSTR wzValue;
158 } BUNDLE_EXTENSION_ENGINE_SETVARIABLEVERSION_ARGS;
159
160 typedef struct _BUNDLE_EXTENSION_ENGINE_SETVARIABLEVERSION_RESULTS
src/engine/EngineForApplication.cpp
+60 -58
@@ -2,6 +2,13 @@
2
3 #include "precomp.h"
4
5 +
6 +static HRESULT CopyStringToBA(
7 + __in LPWSTR wzValue,
8 + __in LPWSTR wzBuffer,
9 + __inout DWORD* pcchBuffer
10 + );
11 +
12 static HRESULT BAEngineGetPackageCount(
13 __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext,
14 __in BAENGINE_GETPACKAGECOUNT_ARGS* /*pArgs*/,
@@ -46,7 +53,6 @@ static HRESULT BAEngineGetVariableString(
53 {
54 HRESULT hr = S_OK;
55 LPWSTR sczValue = NULL;
49 - size_t cchRemaining = 0;
56 LPCWSTR wzVariable = pArgs->wzVariable;
57 LPWSTR wzValue = pResults->wzValue;
58 DWORD* pcchValue = &pResults->cchValue;
@@ -56,24 +62,7 @@ static HRESULT BAEngineGetVariableString(
62 hr = VariableGetString(&pContext->pEngineState->variables, wzVariable, &sczValue);
63 if (SUCCEEDED(hr))
64 {
59 - if (wzValue)
60 - {
61 - hr = ::StringCchCopyExW(wzValue, *pcchValue, sczValue, NULL, &cchRemaining, STRSAFE_FILL_BEHIND_NULL);
62 - if (STRSAFE_E_INSUFFICIENT_BUFFER == hr)
63 - {
64 - hr = E_MOREDATA;
65 -
66 - ::StringCchLengthW(sczValue, STRSAFE_MAX_CCH, &cchRemaining);
67 - *pcchValue = cchRemaining + 1;
68 - }
69 - }
70 - else
71 - {
72 - hr = E_MOREDATA;
73 -
74 - ::StringCchLengthW(sczValue, STRSAFE_MAX_CCH, &cchRemaining);
75 - *pcchValue = cchRemaining + 1;
76 - }
65 + hr = CopyStringToBA(sczValue, wzValue, pcchValue);
66 }
67 }
68 else
@@ -92,18 +81,26 @@ static HRESULT BAEngineGetVariableVersion(
81 )
82 {
83 HRESULT hr = S_OK;
84 + VERUTIL_VERSION* pVersion = NULL;
85 LPCWSTR wzVariable = pArgs->wzVariable;
96 - DWORD64* pqwValue = &pResults->qwValue;
86 + LPWSTR wzValue = pResults->wzValue;
87 + DWORD* pcchValue = &pResults->cchValue;
88
89 if (wzVariable && *wzVariable)
90 {
100 - hr = VariableGetVersion(&pContext->pEngineState->variables, wzVariable, pqwValue);
91 + hr = VariableGetVersion(&pContext->pEngineState->variables, wzVariable, &pVersion);
92 + if (SUCCEEDED(hr))
93 + {
94 + hr = CopyStringToBA(pVersion->sczVersion, wzValue, pcchValue);
95 + }
96 }
97 else
98 {
99 hr = E_INVALIDARG;
100 }
101
102 + ReleaseVerutilVersion(pVersion);
103 +
104 return hr;
105 }
106
@@ -115,33 +112,16 @@ static HRESULT BAEngineFormatString(
112 {
113 HRESULT hr = S_OK;
114 LPWSTR sczValue = NULL;
118 - DWORD cchValue = 0;
115 LPCWSTR wzIn = pArgs->wzIn;
116 LPWSTR wzOut = pResults->wzOut;
117 DWORD* pcchOut = &pResults->cchOut;
118
119 if (wzIn && *wzIn)
120 {
125 - hr = VariableFormatString(&pContext->pEngineState->variables, wzIn, &sczValue, &cchValue);
121 + hr = VariableFormatString(&pContext->pEngineState->variables, wzIn, &sczValue, NULL);
122 if (SUCCEEDED(hr))
123 {
128 - if (wzOut)
129 - {
130 - hr = ::StringCchCopyExW(wzOut, *pcchOut, sczValue, NULL, NULL, STRSAFE_FILL_BEHIND_NULL);
131 - if (FAILED(hr))
132 - {
133 - *pcchOut = cchValue;
134 - if (STRSAFE_E_INSUFFICIENT_BUFFER == hr)
135 - {
136 - hr = E_MOREDATA;
137 - }
138 - }
139 - }
140 - else
141 - {
142 - hr = E_MOREDATA;
143 - *pcchOut = cchValue;
144 - }
124 + hr = CopyStringToBA(sczValue, wzOut, pcchOut);
125 }
126 }
127 else
@@ -161,7 +141,6 @@ static HRESULT BAEngineEscapeString(
141 {
142 HRESULT hr = S_OK;
143 LPWSTR sczValue = NULL;
164 - size_t cchRemaining = 0;
144 LPCWSTR wzIn = pArgs->wzIn;
145 LPWSTR wzOut = pResults->wzOut;
146 DWORD* pcchOut = &pResults->cchOut;
@@ -171,21 +150,7 @@ static HRESULT BAEngineEscapeString(
150 hr = VariableEscapeString(wzIn, &sczValue);
151 if (SUCCEEDED(hr))
152 {
174 - if (wzOut)
175 - {
176 - hr = ::StringCchCopyExW(wzOut, *pcchOut, sczValue, NULL, &cchRemaining, STRSAFE_FILL_BEHIND_NULL);
177 - if (STRSAFE_E_INSUFFICIENT_BUFFER == hr)
178 - {
179 - hr = E_MOREDATA;
180 - ::StringCchLengthW(sczValue, STRSAFE_MAX_CCH, &cchRemaining);
181 - *pcchOut = cchRemaining;
182 - }
183 - }
184 - else
185 - {
186 - ::StringCchLengthW(sczValue, STRSAFE_MAX_CCH, &cchRemaining);
187 - *pcchOut = cchRemaining;
188 - }
153 + hr = CopyStringToBA(sczValue, wzOut, pcchOut);
154 }
155 }
156 else
@@ -613,11 +578,15 @@ static HRESULT BAEngineSetVariableVersion(
578 {
579 HRESULT hr = S_OK;
580 LPCWSTR wzVariable = pArgs->wzVariable;
616 - DWORD64 qwValue = pArgs->qwValue;
581 + LPCWSTR wzValue = pArgs->wzValue;
582 + VERUTIL_VERSION* pVersion = NULL;
583
584 if (wzVariable && *wzVariable)
585 {
620 - hr = VariableSetVersion(&pContext->pEngineState->variables, wzVariable, qwValue, FALSE);
586 + hr = VerParseVersion(wzValue, 0, FALSE, &pVersion);
587 + ExitOnFailure(hr, "Failed to parse new version value.");
588 +
589 + hr = VariableSetVersion(&pContext->pEngineState->variables, wzVariable, pVersion, FALSE);
590 ExitOnFailure(hr, "Failed to set version variable.");
591 }
592 else
@@ -627,6 +596,8 @@ static HRESULT BAEngineSetVariableVersion(
596 }
597
598 LExit:
599 + ReleaseVerutilVersion(pVersion);
600 +
601 return hr;
602 }
603
@@ -898,3 +869,34 @@ HRESULT WINAPI EngineForApplicationProc(
869 LExit:
870 return hr;
871 }
872 +
873 +static HRESULT CopyStringToBA(
874 + __in LPWSTR wzValue,
875 + __in LPWSTR wzBuffer,
876 + __inout DWORD* pcchBuffer
877 + )
878 +{
879 + HRESULT hr = S_OK;
880 + BOOL fTooSmall = !wzBuffer;
881 +
882 + if (!fTooSmall)
883 + {
884 + hr = ::StringCchCopyExW(wzBuffer, *pcchBuffer, wzValue, NULL, NULL, STRSAFE_FILL_BEHIND_NULL);
885 + if (STRSAFE_E_INSUFFICIENT_BUFFER == hr)
886 + {
887 + fTooSmall = TRUE;
888 + }
889 + }
890 +
891 + if (fTooSmall)
892 + {
893 + hr = ::StringCchLengthW(wzValue, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(pcchBuffer));
894 + if (SUCCEEDED(hr))
895 + {
896 + hr = E_MOREDATA;
897 + *pcchBuffer += 1; // null terminator.
898 + }
899 + }
900 +
901 + return hr;
902 +}
src/engine/EngineForExtension.cpp
+60 -58
@@ -2,6 +2,13 @@
2
3 #include "precomp.h"
4
5 +
6 +static HRESULT CopyStringToBE(
7 + __in LPWSTR wzValue,
8 + __in LPWSTR wzBuffer,
9 + __inout DWORD* pcchBuffer
10 + );
11 +
12 static HRESULT BEEngineEscapeString(
13 __in BURN_EXTENSION_ENGINE_CONTEXT* /*pContext*/,
14 __in BUNDLE_EXTENSION_ENGINE_ESCAPESTRING_ARGS* pArgs,
@@ -10,7 +17,6 @@ static HRESULT BEEngineEscapeString(
17 {
18 HRESULT hr = S_OK;
19 LPWSTR sczValue = NULL;
13 - size_t cchRemaining = 0;
20 LPCWSTR wzIn = pArgs->wzIn;
21 LPWSTR wzOut = pResults->wzOut;
22 DWORD* pcchOut = &pResults->cchOut;
@@ -20,21 +26,7 @@ static HRESULT BEEngineEscapeString(
26 hr = VariableEscapeString(wzIn, &sczValue);
27 if (SUCCEEDED(hr))
28 {
23 - if (wzOut)
24 - {
25 - hr = ::StringCchCopyExW(wzOut, *pcchOut, sczValue, NULL, &cchRemaining, STRSAFE_FILL_BEHIND_NULL);
26 - if (STRSAFE_E_INSUFFICIENT_BUFFER == hr)
27 - {
28 - hr = E_MOREDATA;
29 - ::StringCchLengthW(sczValue, STRSAFE_MAX_CCH, &cchRemaining);
30 - *pcchOut = cchRemaining;
31 - }
32 - }
33 - else
34 - {
35 - ::StringCchLengthW(sczValue, STRSAFE_MAX_CCH, &cchRemaining);
36 - *pcchOut = cchRemaining;
37 - }
29 + hr = CopyStringToBE(sczValue, wzOut, pcchOut);
30 }
31 }
32 else
@@ -76,33 +68,16 @@ static HRESULT BEEngineFormatString(
68 {
69 HRESULT hr = S_OK;
70 LPWSTR sczValue = NULL;
79 - DWORD cchValue = 0;
71 LPCWSTR wzIn = pArgs->wzIn;
72 LPWSTR wzOut = pResults->wzOut;
73 DWORD* pcchOut = &pResults->cchOut;
74
75 if (wzIn && *wzIn)
76 {
86 - hr = VariableFormatString(&pContext->pEngineState->variables, wzIn, &sczValue, &cchValue);
77 + hr = VariableFormatString(&pContext->pEngineState->variables, wzIn, &sczValue, NULL);
78 if (SUCCEEDED(hr))
79 {
89 - if (wzOut)
90 - {
91 - hr = ::StringCchCopyExW(wzOut, *pcchOut, sczValue, NULL, NULL, STRSAFE_FILL_BEHIND_NULL);
92 - if (FAILED(hr))
93 - {
94 - *pcchOut = cchValue;
95 - if (STRSAFE_E_INSUFFICIENT_BUFFER == hr)
96 - {
97 - hr = E_MOREDATA;
98 - }
99 - }
100 - }
101 - else
102 - {
103 - hr = E_MOREDATA;
104 - *pcchOut = cchValue;
105 - }
80 + hr = CopyStringToBE(sczValue, wzOut, pcchOut);
81 }
82 }
83 else
@@ -144,7 +119,6 @@ static HRESULT BEEngineGetVariableString(
119 {
120 HRESULT hr = S_OK;
121 LPWSTR sczValue = NULL;
147 - size_t cchRemaining = 0;
122 LPCWSTR wzVariable = pArgs->wzVariable;
123 LPWSTR wzValue = pResults->wzValue;
124 DWORD* pcchValue = &pResults->cchValue;
@@ -154,24 +128,7 @@ static HRESULT BEEngineGetVariableString(
128 hr = VariableGetString(&pContext->pEngineState->variables, wzVariable, &sczValue);
129 if (SUCCEEDED(hr))
130 {
157 - if (wzValue)
158 - {
159 - hr = ::StringCchCopyExW(wzValue, *pcchValue, sczValue, NULL, &cchRemaining, STRSAFE_FILL_BEHIND_NULL);
160 - if (STRSAFE_E_INSUFFICIENT_BUFFER == hr)
161 - {
162 - hr = E_MOREDATA;
163 -
164 - ::StringCchLengthW(sczValue, STRSAFE_MAX_CCH, &cchRemaining);
165 - *pcchValue = cchRemaining + 1;
166 - }
167 - }
168 - else
169 - {
170 - hr = E_MOREDATA;
171 -
172 - ::StringCchLengthW(sczValue, STRSAFE_MAX_CCH, &cchRemaining);
173 - *pcchValue = cchRemaining + 1;
174 - }
131 + hr = CopyStringToBE(sczValue, wzValue, pcchValue);
132 }
133 }
134 else
@@ -190,18 +147,26 @@ static HRESULT BEEngineGetVariableVersion(
147 )
148 {
149 HRESULT hr = S_OK;
150 + VERUTIL_VERSION* pVersion = NULL;
151 LPCWSTR wzVariable = pArgs->wzVariable;
194 - DWORD64* pqwValue = &pResults->qwValue;
152 + LPWSTR wzValue = pResults->wzValue;
153 + DWORD* pcchValue = &pResults->cchValue;
154
155 if (wzVariable && *wzVariable)
156 {
198 - hr = VariableGetVersion(&pContext->pEngineState->variables, wzVariable, pqwValue);
157 + hr = VariableGetVersion(&pContext->pEngineState->variables, wzVariable, &pVersion);
158 + if (SUCCEEDED(hr))
159 + {
160 + hr = CopyStringToBE(pVersion->sczVersion, wzValue, pcchValue);
161 + }
162 }
163 else
164 {
165 hr = E_INVALIDARG;
166 }
167
168 + ReleaseVerutilVersion(pVersion);
169 +
170 return hr;
171 }
172
@@ -303,11 +268,15 @@ static HRESULT BEEngineSetVariableVersion(
268 {
269 HRESULT hr = S_OK;
270 LPCWSTR wzVariable = pArgs->wzVariable;
306 - DWORD64 qwValue = pArgs->qwValue;
271 + LPCWSTR wzValue = pArgs->wzValue;
272 + VERUTIL_VERSION* pVersion = NULL;
273
274 if (wzVariable && *wzVariable)
275 {
310 - hr = VariableSetVersion(&pContext->pEngineState->variables, wzVariable, qwValue, FALSE);
276 + hr = VerParseVersion(wzValue, 0, FALSE, &pVersion);
277 + ExitOnFailure(hr, "Failed to parse new version value.");
278 +
279 + hr = VariableSetVersion(&pContext->pEngineState->variables, wzVariable, pVersion, FALSE);
280 ExitOnFailure(hr, "Failed to set version variable.");
281 }
282 else
@@ -317,6 +286,8 @@ static HRESULT BEEngineSetVariableVersion(
286 }
287
288 LExit:
289 + ReleaseVerutilVersion(pVersion);
290 +
291 return hr;
292 }
293
@@ -375,3 +346,34 @@ HRESULT WINAPI EngineForExtensionProc(
346 LExit:
347 return hr;
348 }
349 +
350 +static HRESULT CopyStringToBE(
351 + __in LPWSTR wzValue,
352 + __in LPWSTR wzBuffer,
353 + __inout DWORD* pcchBuffer
354 + )
355 +{
356 + HRESULT hr = S_OK;
357 + BOOL fTooSmall = !wzBuffer;
358 +
359 + if (!fTooSmall)
360 + {
361 + hr = ::StringCchCopyExW(wzBuffer, *pcchBuffer, wzValue, NULL, NULL, STRSAFE_FILL_BEHIND_NULL);
362 + if (STRSAFE_E_INSUFFICIENT_BUFFER == hr)
363 + {
364 + fTooSmall = TRUE;
365 + }
366 + }
367 +
368 + if (fTooSmall)
369 + {
370 + hr = ::StringCchLengthW(wzValue, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(pcchBuffer));
371 + if (SUCCEEDED(hr))
372 + {
373 + hr = E_MOREDATA;
374 + *pcchBuffer += 1; // null terminator.
375 + }
376 + }
377 +
378 + return hr;
379 +}
src/engine/condition.cpp
+35 -53
@@ -123,8 +123,8 @@ static HRESULT CompareIntegerValues(
123 );
124 static HRESULT CompareVersionValues(
125 __in BURN_SYMBOL_TYPE comparison,
126 - __in DWORD64 qwLeftOperand,
127 - __in DWORD64 qwRightOperand,
126 + __in VERUTIL_VERSION* pLeftOperand,
127 + __in VERUTIL_VERSION* pRightOperand,
128 __out BOOL* pfResult
129 );
130
@@ -379,7 +379,7 @@ static HRESULT ParseTerm(
379 {
380 LONGLONG llValue = 0;
381 LPWSTR sczValue = NULL;
382 - DWORD64 qwValue = 0;
382 + VERUTIL_VERSION* pVersion = NULL;
383 switch (firstValue.Type)
384 {
385 case BURN_VARIANT_TYPE_NONE:
@@ -402,12 +402,12 @@ static HRESULT ParseTerm(
402 SecureZeroMemory(&llValue, sizeof(llValue));
403 break;
404 case BURN_VARIANT_TYPE_VERSION:
405 - hr = BVariantGetVersion(&firstValue, &qwValue);
405 + hr = BVariantGetVersion(&firstValue, &pVersion);
406 if (SUCCEEDED(hr))
407 {
408 - *pf = 0 != qwValue;
408 + *pf = 0 != *pVersion->sczVersion;
409 }
410 - SecureZeroMemory(&llValue, sizeof(qwValue));
410 + ReleaseVerutilVersion(pVersion);
411 break;
412 default:
413 ExitFunction1(hr = E_UNEXPECTED);
@@ -689,33 +689,14 @@ static HRESULT NextSymbol(
689 if (L'v' == pContext->wzRead[0] && C1_DIGIT & charType)
690 {
691 // version
692 - DWORD cParts = 1;
693 - for (;;)
692 + do
693 {
694 ++n;
696 - if (L'.' == pContext->wzRead[n])
697 - {
698 - ++cParts;
699 - if (4 < cParts)
700 - {
701 - // error, too many parts in version
702 - pContext->fError = TRUE;
703 - hr = E_INVALIDDATA;
704 - ExitOnRootFailure(hr, "Failed to parse condition \"%ls\". Version can have a maximum of 4 parts, at position %d.", pContext->wzCondition, iPosition);
705 - }
706 - }
707 - else
708 - {
709 - ::GetStringTypeW(CT_CTYPE1, &pContext->wzRead[n], 1, &charType);
710 - if (C1_DIGIT != (C1_DIGIT & charType))
711 - {
712 - break;
713 - }
714 - }
715 - }
695 + ::GetStringTypeW(CT_CTYPE1, &pContext->wzRead[n], 1, &charType);
696 + } while (L'\0' != pContext->wzRead[n] && C1_BLANK != (C1_BLANK & charType));
697
698 // Symbols don't encrypt their value, so can access the value directly.
718 - hr = FileVersionFromStringEx(&pContext->wzRead[1], n - 1, &pContext->NextSymbol.Value.qwValue);
699 + hr = VerParseVersion(&pContext->wzRead[1], n - 1, FALSE, &pContext->NextSymbol.Value.pValue);
700 if (FAILED(hr))
701 {
702 pContext->fError = TRUE;
@@ -785,10 +766,10 @@ static HRESULT CompareValues(
766 {
767 HRESULT hr = S_OK;
768 LONGLONG llLeft = 0;
788 - DWORD64 qwLeft = 0;
769 + VERUTIL_VERSION* pVersionLeft = 0;
770 LPWSTR sczLeft = NULL;
771 LONGLONG llRight = 0;
791 - DWORD64 qwRight = 0;
772 + VERUTIL_VERSION* pVersionRight = 0;
773 LPWSTR sczRight = NULL;
774
775 // get values to compare based on type
@@ -810,17 +791,17 @@ static HRESULT CompareValues(
791 }
792 else if (BURN_VARIANT_TYPE_VERSION == leftOperand.Type && BURN_VARIANT_TYPE_VERSION == rightOperand.Type)
793 {
813 - hr = BVariantGetVersion(&leftOperand, &qwLeft);
794 + hr = BVariantGetVersion(&leftOperand, &pVersionLeft);
795 ExitOnFailure(hr, "Failed to get the left version");
815 - hr = BVariantGetVersion(&rightOperand, &qwRight);
796 + hr = BVariantGetVersion(&rightOperand, &pVersionRight);
797 ExitOnFailure(hr, "Failed to get the right version");
817 - hr = CompareVersionValues(comparison, qwLeft, qwRight, pfResult);
798 + hr = CompareVersionValues(comparison, pVersionLeft, pVersionRight, pfResult);
799 }
800 else if (BURN_VARIANT_TYPE_VERSION == leftOperand.Type && BURN_VARIANT_TYPE_STRING == rightOperand.Type)
801 {
821 - hr = BVariantGetVersion(&leftOperand, &qwLeft);
802 + hr = BVariantGetVersion(&leftOperand, &pVersionLeft);
803 ExitOnFailure(hr, "Failed to get the left version");
823 - hr = BVariantGetVersion(&rightOperand, &qwRight);
804 + hr = BVariantGetVersion(&rightOperand, &pVersionRight);
805 if (FAILED(hr))
806 {
807 if (DISP_E_TYPEMISMATCH != hr)
@@ -832,14 +813,14 @@ static HRESULT CompareValues(
813 }
814 else
815 {
835 - hr = CompareVersionValues(comparison, qwLeft, qwRight, pfResult);
816 + hr = CompareVersionValues(comparison, pVersionLeft, pVersionRight, pfResult);
817 }
818 }
819 else if (BURN_VARIANT_TYPE_STRING == leftOperand.Type && BURN_VARIANT_TYPE_VERSION == rightOperand.Type)
820 {
840 - hr = BVariantGetVersion(&rightOperand, &qwRight);
821 + hr = BVariantGetVersion(&rightOperand, &pVersionRight);
822 ExitOnFailure(hr, "Failed to get the right version");
842 - hr = BVariantGetVersion(&leftOperand, &qwLeft);
823 + hr = BVariantGetVersion(&leftOperand, &pVersionLeft);
824 if (FAILED(hr))
825 {
826 if (DISP_E_TYPEMISMATCH != hr)
@@ -851,7 +832,7 @@ static HRESULT CompareValues(
832 }
833 else
834 {
854 - hr = CompareVersionValues(comparison, qwLeft, qwRight, pfResult);
835 + hr = CompareVersionValues(comparison, pVersionLeft, pVersionRight, pfResult);
836 }
837 }
838 else if (BURN_VARIANT_TYPE_NUMERIC == leftOperand.Type && BURN_VARIANT_TYPE_STRING == rightOperand.Type)
@@ -899,10 +880,10 @@ static HRESULT CompareValues(
880 }
881
882 LExit:
902 - SecureZeroMemory(&qwLeft, sizeof(DWORD64));
883 + ReleaseVerutilVersion(pVersionLeft);
884 SecureZeroMemory(&llLeft, sizeof(LONGLONG));
885 StrSecureZeroFreeString(sczLeft);
905 - SecureZeroMemory(&qwRight, sizeof(DWORD64));
886 + ReleaseVerutilVersion(pVersionRight);
887 SecureZeroMemory(&llRight, sizeof(LONGLONG));
888 StrSecureZeroFreeString(sczRight);
889
@@ -1010,24 +991,25 @@ LExit:
991 //
992 static HRESULT CompareVersionValues(
993 __in BURN_SYMBOL_TYPE comparison,
1013 - __in DWORD64 qwLeftOperand,
1014 - __in DWORD64 qwRightOperand,
994 + __in VERUTIL_VERSION* pLeftOperand,
995 + __in VERUTIL_VERSION* pRightOperand,
996 __out BOOL* pfResult
997 )
998 {
999 HRESULT hr = S_OK;
1000 + int nResult = 0;
1001 +
1002 + hr = VerCompareParsedVersions(pLeftOperand, pRightOperand, &nResult);
1003 + ExitOnFailure(hr, "Failed to compare condition versions: '%ls', '%ls'", pLeftOperand->sczVersion, pRightOperand->sczVersion);
1004
1005 switch (comparison)
1006 {
1022 - case BURN_SYMBOL_TYPE_LT: *pfResult = qwLeftOperand < qwRightOperand; break;
1023 - case BURN_SYMBOL_TYPE_GT: *pfResult = qwLeftOperand > qwRightOperand; break;
1024 - case BURN_SYMBOL_TYPE_LE: *pfResult = qwLeftOperand <= qwRightOperand; break;
1025 - case BURN_SYMBOL_TYPE_GE: *pfResult = qwLeftOperand >= qwRightOperand; break;
1026 - case BURN_SYMBOL_TYPE_EQ: *pfResult = qwLeftOperand == qwRightOperand; break;
1027 - case BURN_SYMBOL_TYPE_NE: *pfResult = qwLeftOperand != qwRightOperand; break;
1028 - case BURN_SYMBOL_TYPE_BAND: *pfResult = (qwLeftOperand & qwRightOperand) ? TRUE : FALSE; break;
1029 - case BURN_SYMBOL_TYPE_HIEQ: *pfResult = ((qwLeftOperand >> 16) & 0xFFFF) == qwRightOperand; break;
1030 - case BURN_SYMBOL_TYPE_LOEQ: *pfResult = (qwLeftOperand & 0xFFFF) == qwRightOperand; break;
1007 + case BURN_SYMBOL_TYPE_LT: *pfResult = nResult < 0; break;
1008 + case BURN_SYMBOL_TYPE_GT: *pfResult = nResult > 0; break;
1009 + case BURN_SYMBOL_TYPE_LE: *pfResult = nResult <= 0; break;
1010 + case BURN_SYMBOL_TYPE_GE: *pfResult = nResult >= 0; break;
1011 + case BURN_SYMBOL_TYPE_EQ: *pfResult = nResult == 0; break;
1012 + case BURN_SYMBOL_TYPE_NE: *pfResult = nResult != 0; break;
1013 default:
1014 ExitFunction1(hr = E_INVALIDARG);
1015 }
src/engine/dependency.cpp
+2 -8
@@ -593,20 +593,14 @@ extern "C" HRESULT DependencyRegisterBundle(
593 )
594 {
595 HRESULT hr = S_OK;
596 - LPWSTR sczVersion = NULL;
596
598 - hr = FileVersionToStringEx(pRegistration->qwVersion, &sczVersion);
599 - ExitOnFailure(hr, "Failed to format the registration version string.");
600 -
601 - LogId(REPORT_VERBOSE, MSG_DEPENDENCY_BUNDLE_REGISTER, pRegistration->sczProviderKey, sczVersion);
597 + LogId(REPORT_VERBOSE, MSG_DEPENDENCY_BUNDLE_REGISTER, pRegistration->sczProviderKey, pRegistration->pVersion->sczVersion);
598
599 // Register the bundle provider key.
604 - hr = DepRegisterDependency(pRegistration->hkRoot, pRegistration->sczProviderKey, sczVersion, pRegistration->sczDisplayName, pRegistration->sczId, 0);
600 + hr = DepRegisterDependency(pRegistration->hkRoot, pRegistration->sczProviderKey, pRegistration->pVersion->sczVersion, pRegistration->sczDisplayName, pRegistration->sczId, 0);
601 ExitOnFailure(hr, "Failed to register the bundle dependency provider.");
602
603 LExit:
608 - ReleaseStr(sczVersion);
609 -
604 return hr;
605 }
606
src/engine/detect.cpp
+25 -15
@@ -90,6 +90,7 @@ extern "C" HRESULT DetectForwardCompatibleBundle(
90 HRESULT hr = S_OK;
91 BOOL fRecommendIgnore = TRUE;
92 BOOL fIgnoreBundle = FALSE;
93 + int nCompareResult = 0;
94
95 if (pRegistration->sczDetectedProviderKeyBundleId &&
96 CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->sczDetectedProviderKeyBundleId, -1, pRegistration->sczId, -1))
@@ -122,22 +123,27 @@ extern "C" HRESULT DetectForwardCompatibleBundle(
123 fIgnoreBundle = fRecommendIgnore;
124
125 if (BOOTSTRAPPER_RELATION_UPGRADE == pRelatedBundle->relationType &&
125 - pRegistration->qwVersion <= pRelatedBundle->qwVersion &&
126 CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->sczDetectedProviderKeyBundleId, -1, pRelatedBundle->package.sczId, -1))
127 {
128 - hr = UserExperienceOnDetectForwardCompatibleBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->relationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->qwVersion, &fIgnoreBundle);
129 - ExitOnRootFailure(hr, "BA aborted detect forward compatible bundle.");
128 + hr = VerCompareParsedVersions(pRegistration->pVersion, pRelatedBundle->pVersion, &nCompareResult);
129 + ExitOnFailure(hr, "Failed to compare bundle version '%ls' to related bundle version '%ls'", pRegistration->pVersion->sczVersion, pRelatedBundle->pVersion->sczVersion);
130
131 - if (!fIgnoreBundle)
131 + if (nCompareResult <= 0)
132 {
133 - hr = PseudoBundleInitializePassthrough(&pRegistration->forwardCompatibleBundle, pCommand, NULL, pRegistration->sczActiveParent, pRegistration->sczAncestors, &pRelatedBundle->package);
134 - ExitOnFailure(hr, "Failed to initialize update bundle.");
133 + hr = UserExperienceOnDetectForwardCompatibleBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->relationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->pVersion, &fIgnoreBundle);
134 + ExitOnRootFailure(hr, "BA aborted detect forward compatible bundle.");
135
136 - pRegistration->fEnabledForwardCompatibleBundle = TRUE;
137 - }
136 + if (!fIgnoreBundle)
137 + {
138 + hr = PseudoBundleInitializePassthrough(&pRegistration->forwardCompatibleBundle, pCommand, NULL, pRegistration->sczActiveParent, pRegistration->sczAncestors, &pRelatedBundle->package);
139 + ExitOnFailure(hr, "Failed to initialize update bundle.");
140
139 - LogId(REPORT_STANDARD, MSG_DETECTED_FORWARD_COMPATIBLE_BUNDLE, pRelatedBundle->package.sczId, LoggingRelationTypeToString(pRelatedBundle->relationType), LoggingPerMachineToString(pRelatedBundle->package.fPerMachine), LoggingVersionToString(pRelatedBundle->qwVersion), LoggingBoolToString(pRegistration->fEnabledForwardCompatibleBundle));
140 - break;
141 + pRegistration->fEnabledForwardCompatibleBundle = TRUE;
142 + }
143 +
144 + LogId(REPORT_STANDARD, MSG_DETECTED_FORWARD_COMPATIBLE_BUNDLE, pRelatedBundle->package.sczId, LoggingRelationTypeToString(pRelatedBundle->relationType), LoggingPerMachineToString(pRelatedBundle->package.fPerMachine), pRelatedBundle->pVersion->sczVersion, LoggingBoolToString(pRegistration->fEnabledForwardCompatibleBundle));
145 + break;
146 + }
147 }
148 }
149 }
@@ -154,6 +160,7 @@ extern "C" HRESULT DetectReportRelatedBundles(
160 )
161 {
162 HRESULT hr = S_OK;
163 + int nCompareResult = 0;
164
165 for (DWORD iRelatedBundle = 0; iRelatedBundle < pRegistration->relatedBundles.cRelatedBundles; ++iRelatedBundle)
166 {
@@ -165,11 +172,14 @@ extern "C" HRESULT DetectReportRelatedBundles(
172 case BOOTSTRAPPER_RELATION_UPGRADE:
173 if (BOOTSTRAPPER_RELATION_UPGRADE != relationType && BOOTSTRAPPER_ACTION_UNINSTALL < action)
174 {
168 - if (pRegistration->qwVersion > pRelatedBundle->qwVersion)
175 + hr = VerCompareParsedVersions(pRegistration->pVersion, pRelatedBundle->pVersion, &nCompareResult);
176 + ExitOnFailure(hr, "Failed to compare bundle version '%ls' to related bundle version '%ls'", pRegistration->pVersion, pRelatedBundle->pVersion);
177 +
178 + if (nCompareResult > 0)
179 {
180 operation = BOOTSTRAPPER_RELATED_OPERATION_MAJOR_UPGRADE;
181 }
172 - else if (pRegistration->qwVersion < pRelatedBundle->qwVersion)
182 + else if (nCompareResult < 0)
183 {
184 operation = BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE;
185 }
@@ -202,9 +212,9 @@ extern "C" HRESULT DetectReportRelatedBundles(
212 break;
213 }
214
205 - LogId(REPORT_STANDARD, MSG_DETECTED_RELATED_BUNDLE, pRelatedBundle->package.sczId, LoggingRelationTypeToString(pRelatedBundle->relationType), LoggingPerMachineToString(pRelatedBundle->package.fPerMachine), LoggingVersionToString(pRelatedBundle->qwVersion), LoggingRelatedOperationToString(operation));
215 + LogId(REPORT_STANDARD, MSG_DETECTED_RELATED_BUNDLE, pRelatedBundle->package.sczId, LoggingRelationTypeToString(pRelatedBundle->relationType), LoggingPerMachineToString(pRelatedBundle->package.fPerMachine), pRelatedBundle->pVersion->sczVersion, LoggingRelatedOperationToString(operation));
216
207 - hr = UserExperienceOnDetectRelatedBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->relationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->qwVersion, operation);
217 + hr = UserExperienceOnDetectRelatedBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->relationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->pVersion, operation);
218 ExitOnRootFailure(hr, "BA aborted detect related bundle.");
219 }
220
@@ -405,7 +415,7 @@ static HRESULT DetectAtomFeedUpdate(
415
416 hr = UserExperienceOnDetectUpdate(pUX, pAppUpdateEntry->rgEnclosures ? pAppUpdateEntry->rgEnclosures->wzUrl : NULL,
417 pAppUpdateEntry->rgEnclosures ? pAppUpdateEntry->rgEnclosures->dw64Size : 0,
408 - pAppUpdateEntry->dw64Version, pAppUpdateEntry->wzTitle,
418 + pAppUpdateEntry->pVersion, pAppUpdateEntry->wzTitle,
419 pAppUpdateEntry->wzSummary, pAppUpdateEntry->wzContentType, pAppUpdateEntry->wzContent, &fStopProcessingUpdates);
420 ExitOnRootFailure(hr, "BA aborted detect update.");
421
src/engine/elevation.cpp
+8 -3
@@ -1087,7 +1087,7 @@ extern "C" HRESULT ElevationLoadCompatiblePackageAction(
1087 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->compatiblePackage.sczInstalledProductCode);
1088 ExitOnFailure(hr, "Failed to write installed ProductCode to message buffer.");
1089
1090 - hr = BuffWriteNumber64(&pbData, &cbData, pExecuteAction->compatiblePackage.qwInstalledVersion);
1090 + hr = BuffWriteString(&pbData, &cbData, pExecuteAction->compatiblePackage.pInstalledVersion->sczVersion);
1091 ExitOnFailure(hr, "Failed to write installed version to message buffer.");
1092
1093 // Send the message.
@@ -2566,6 +2566,7 @@ static HRESULT OnLoadCompatiblePackage(
2566 HRESULT hr = S_OK;
2567 SIZE_T iData = 0;
2568 LPWSTR sczPackage = NULL;
2569 + LPWSTR sczVersion = NULL;
2570 BURN_EXECUTE_ACTION executeAction = { };
2571
2572 executeAction.type = BURN_EXECUTE_ACTION_TYPE_COMPATIBLE_PACKAGE;
@@ -2581,20 +2582,24 @@ static HRESULT OnLoadCompatiblePackage(
2582 hr = BuffReadString(pbData, cbData, &iData, &executeAction.compatiblePackage.sczInstalledProductCode);
2583 ExitOnFailure(hr, "Failed to read installed ProductCode from message buffer.");
2584
2584 - hr = BuffReadNumber64(pbData, cbData, &iData, &executeAction.compatiblePackage.qwInstalledVersion);
2585 + hr = BuffReadString(pbData, cbData, &iData, &sczVersion);
2586 ExitOnFailure(hr, "Failed to read installed version from message buffer.");
2587
2588 + hr = VerParseVersion(sczVersion, 0, FALSE, &executeAction.compatiblePackage.pInstalledVersion);
2589 + ExitOnFailure(hr, "Failed to parse installed version from compatible package.");
2590 +
2591 // Copy the installed data to the reference package.
2592 hr = StrAllocString(&executeAction.compatiblePackage.pReferencePackage->Msi.sczInstalledProductCode, executeAction.compatiblePackage.sczInstalledProductCode, 0);
2593 ExitOnFailure(hr, "Failed to copy installed ProductCode.");
2594
2591 - executeAction.compatiblePackage.pReferencePackage->Msi.qwInstalledVersion = executeAction.compatiblePackage.qwInstalledVersion;
2595 + executeAction.compatiblePackage.pReferencePackage->Msi.pInstalledVersion = executeAction.compatiblePackage.pInstalledVersion;
2596
2597 // Load the compatible package and add it to the list.
2598 hr = MsiEngineAddCompatiblePackage(pPackages, executeAction.compatiblePackage.pReferencePackage, NULL);
2599 ExitOnFailure(hr, "Failed to load compatible package.");
2600
2601 LExit:
2602 + ReleaseStr(sczVersion);
2603 ReleaseStr(sczPackage);
2604 PlanUninitializeExecuteAction(&executeAction);
2605
src/engine/engine.vcxproj
+2 -2
@@ -2,7 +2,7 @@
2 <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3
4 <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
5 - <Import Project="..\..\packages\WixToolset.DUtil.4.0.49\build\WixToolset.DUtil.props" Condition="Exists('..\..\packages\WixToolset.DUtil.4.0.49\build\WixToolset.DUtil.props')" />
5 + <Import Project="..\..\packages\WixToolset.DUtil.4.0.55\build\WixToolset.DUtil.props" Condition="Exists('..\..\packages\WixToolset.DUtil.4.0.55\build\WixToolset.DUtil.props')" />
6
7 <ItemGroup Label="ProjectConfigurations">
8 <ProjectConfiguration Include="Debug|Win32">
@@ -165,7 +165,7 @@ rc.exe -fo "$(OutDir)engine.res" "$(IntDir)engine.messages.rc"</Command>
165 <PropertyGroup>
166 <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
167 </PropertyGroup>
168 - <Error Condition="!Exists('..\..\packages\WixToolset.DUtil.4.0.49\build\WixToolset.DUtil.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixToolset.DUtil.4.0.49\build\WixToolset.DUtil.props'))" />
168 + <Error Condition="!Exists('..\..\packages\WixToolset.DUtil.4.0.55\build\WixToolset.DUtil.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixToolset.DUtil.4.0.55\build\WixToolset.DUtil.props'))" />
169 <Error Condition="!Exists('..\..\packages\Nerdbank.GitVersioning.3.1.91\build\Nerdbank.GitVersioning.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Nerdbank.GitVersioning.3.1.91\build\Nerdbank.GitVersioning.targets'))" />
170 </Target>
171 </Project>
src/engine/logging.cpp
-17
@@ -583,23 +583,6 @@ extern "C" LPWSTR LoggingStringOrUnknownIfNull(
583 return wz ? wz : L"Unknown";
584 }
585
586 -// Note: this function is not thread safe.
587 -extern "C" LPCSTR LoggingVersionToString(
588 - __in DWORD64 dw64Version
589 - )
590 -{
591 - static CHAR szVersion[40] = { 0 };
592 - HRESULT hr = S_OK;
593 -
594 - hr = ::StringCchPrintfA(szVersion, countof(szVersion), "%I64u.%I64u.%I64u.%I64u", dw64Version >> 48 & 0xFFFF, dw64Version >> 32 & 0xFFFF, dw64Version >> 16 & 0xFFFF, dw64Version & 0xFFFF);
595 - if (FAILED(hr))
596 - {
597 - memset(szVersion, 0, sizeof(szVersion));
598 - }
599 -
600 - return szVersion;
601 -}
602 -
586
587 // internal function declarations
588
src/engine/logging.h
-5
@@ -133,11 +133,6 @@ LPWSTR LoggingStringOrUnknownIfNull(
133 __in LPCWSTR wz
134 );
135
136 -// Note: this function is not thread safe.
137 -LPCSTR LoggingVersionToString(
138 - __in DWORD64 dw64Version
139 - );
140 -
136
137 #if defined(__cplusplus)
138 }
src/engine/msiengine.cpp
+59 -35
@@ -79,7 +79,7 @@ extern "C" HRESULT MsiEngineParsePackageFromXml(
79 hr = XmlGetAttributeEx(pixnMsiPackage, L"Version", &scz);
80 ExitOnFailure(hr, "Failed to get @Version.");
81
82 - hr = FileVersionFromStringEx(scz, 0, &pPackage->Msi.qwVersion);
82 + hr = VerParseVersion(scz, 0, FALSE, &pPackage->Msi.pVersion);
83 ExitOnFailure(hr, "Failed to parse @Version: %ls", scz);
84
85 // @UpgradeCode
@@ -399,6 +399,7 @@ extern "C" HRESULT MsiEngineDetectPackage(
399 Trace(REPORT_STANDARD, "Detecting MSI package 0x%p", pPackage);
400
401 HRESULT hr = S_OK;
402 + int nCompareResult = 0;
403 LPWSTR sczInstalledVersion = NULL;
404 LPWSTR sczInstalledLanguage = NULL;
405 LPWSTR sczInstalledProductCode = NULL;
@@ -407,7 +408,7 @@ extern "C" HRESULT MsiEngineDetectPackage(
408 BOOTSTRAPPER_RELATED_OPERATION operation = BOOTSTRAPPER_RELATED_OPERATION_NONE;
409 BOOTSTRAPPER_RELATED_OPERATION relatedMsiOperation = BOOTSTRAPPER_RELATED_OPERATION_NONE;
410 WCHAR wzProductCode[MAX_GUID_CHARS + 1] = { };
410 - DWORD64 qwVersion = 0;
411 + VERUTIL_VERSION* pVersion = NULL;
412 UINT uLcid = 0;
413 BOOL fPerMachine = FALSE;
414
@@ -416,18 +417,21 @@ extern "C" HRESULT MsiEngineDetectPackage(
417 hr = WiuGetProductInfoEx(pPackage->Msi.sczProductCode, NULL, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion);
418 if (SUCCEEDED(hr))
419 {
419 - hr = FileVersionFromStringEx(sczInstalledVersion, 0, &pPackage->Msi.qwInstalledVersion);
420 - ExitOnFailure(hr, "Failed to convert version: %ls to DWORD64 for ProductCode: %ls", sczInstalledVersion, pPackage->Msi.sczProductCode);
420 + hr = VerParseVersion(sczInstalledVersion, 0, FALSE, &pPackage->Msi.pInstalledVersion);
421 + ExitOnFailure(hr, "Failed to parse installed version: '%ls' for ProductCode: %ls", sczInstalledVersion, pPackage->Msi.sczProductCode);
422
423 // compare versions
423 - if (pPackage->Msi.qwVersion < pPackage->Msi.qwInstalledVersion)
424 + hr = VerCompareParsedVersions(pPackage->Msi.pVersion, pPackage->Msi.pInstalledVersion, &nCompareResult);
425 + ExitOnFailure(hr, "Failed to compare version '%ls' to installed version: '%ls'", pPackage->Msi.pVersion->sczVersion, pPackage->Msi.pInstalledVersion->sczVersion);
426 +
427 + if (nCompareResult < 0)
428 {
429 operation = BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE;
430 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED;
431 }
432 else
433 {
430 - if (pPackage->Msi.qwVersion > pPackage->Msi.qwInstalledVersion)
434 + if (nCompareResult > 0)
435 {
436 operation = BOOTSTRAPPER_RELATED_OPERATION_MINOR_UPDATE;
437 }
@@ -438,9 +442,9 @@ extern "C" HRESULT MsiEngineDetectPackage(
442 // Report related MSI package to BA.
443 if (BOOTSTRAPPER_RELATED_OPERATION_NONE != operation)
444 {
441 - LogId(REPORT_STANDARD, MSG_DETECTED_RELATED_PACKAGE, pPackage->Msi.sczProductCode, LoggingPerMachineToString(pPackage->fPerMachine), LoggingVersionToString(pPackage->Msi.qwInstalledVersion), pPackage->Msi.dwLanguage, LoggingRelatedOperationToString(operation));
445 + LogId(REPORT_STANDARD, MSG_DETECTED_RELATED_PACKAGE, pPackage->Msi.sczProductCode, LoggingPerMachineToString(pPackage->fPerMachine), pPackage->Msi.pInstalledVersion->sczVersion, pPackage->Msi.dwLanguage, LoggingRelatedOperationToString(operation));
446
443 - hr = UserExperienceOnDetectRelatedMsiPackage(pUserExperience, pPackage->sczId, pPackage->Msi.sczUpgradeCode, pPackage->Msi.sczProductCode, pPackage->fPerMachine, pPackage->Msi.qwInstalledVersion, operation);
447 + hr = UserExperienceOnDetectRelatedMsiPackage(pUserExperience, pPackage->sczId, pPackage->Msi.sczUpgradeCode, pPackage->Msi.sczProductCode, pPackage->fPerMachine, pPackage->Msi.pInstalledVersion, operation);
448 ExitOnRootFailure(hr, "BA aborted detect related MSI package.");
449 }
450 }
@@ -453,21 +457,26 @@ extern "C" HRESULT MsiEngineDetectPackage(
457 hr = WiuGetProductInfoEx(sczInstalledProductCode, NULL, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion);
458 if (SUCCEEDED(hr))
459 {
456 - hr = FileVersionFromStringEx(sczInstalledVersion, 0, &qwVersion);
457 - ExitOnFailure(hr, "Failed to convert version: %ls to DWORD64 for ProductCode: %ls", sczInstalledVersion, sczInstalledProductCode);
460 + hr = VerParseVersion(sczInstalledVersion, 0, FALSE, &pVersion);
461 + ExitOnFailure(hr, "Failed to parse dependency version: '%ls' for ProductCode: %ls", sczInstalledVersion, sczInstalledProductCode);
462 +
463 + // compare versions
464 + hr = VerCompareParsedVersions(pPackage->Msi.pVersion, pVersion, &nCompareResult);
465 + ExitOnFailure(hr, "Failed to compare version '%ls' to dependency version: '%ls'", pPackage->Msi.pVersion->sczVersion, pVersion->sczVersion);
466
459 - if (pPackage->Msi.qwVersion < qwVersion)
467 + if (nCompareResult < 0)
468 {
469 LogId(REPORT_STANDARD, MSG_DETECTED_COMPATIBLE_PACKAGE_FROM_PROVIDER, pPackage->sczId, sczInstalledProviderKey, sczInstalledProductCode, sczInstalledVersion, pPackage->Msi.sczProductCode);
470
463 - hr = UserExperienceOnDetectCompatibleMsiPackage(pUserExperience, pPackage->sczId, sczInstalledProductCode, qwVersion);
471 + hr = UserExperienceOnDetectCompatibleMsiPackage(pUserExperience, pPackage->sczId, sczInstalledProductCode, pVersion);
472 ExitOnRootFailure(hr, "BA aborted detect compatible MSI package.");
473
474 hr = StrAllocString(&pPackage->Msi.sczInstalledProductCode, sczInstalledProductCode, 0);
475 ExitOnFailure(hr, "Failed to copy the installed ProductCode to the package.");
476
469 - pPackage->Msi.qwInstalledVersion = qwVersion;
477 + pPackage->Msi.pInstalledVersion = pVersion;
478 pPackage->Msi.fCompatibleInstalled = TRUE;
479 + pVersion = NULL;
480 }
481 }
482 }
@@ -524,18 +533,30 @@ extern "C" HRESULT MsiEngineDetectPackage(
533 }
534 }
535
527 - hr = FileVersionFromStringEx(sczInstalledVersion, 0, &qwVersion);
528 - ExitOnFailure(hr, "Failed to convert version: %ls to DWORD64 for ProductCode: %ls", sczInstalledVersion, wzProductCode);
536 + hr = VerParseVersion(sczInstalledVersion, 0, FALSE, &pVersion);
537 + ExitOnFailure(hr, "Failed to parse related installed version: '%ls' for ProductCode: %ls", sczInstalledVersion, wzProductCode);
538
539 // compare versions
531 - if (pRelatedMsi->fMinProvided && (pRelatedMsi->fMinInclusive ? (qwVersion < pRelatedMsi->qwMinVersion) : (qwVersion <= pRelatedMsi->qwMinVersion)))
540 + if (pRelatedMsi->fMinProvided)
541 {
533 - continue;
542 + hr = VerCompareParsedVersions(pVersion, pRelatedMsi->pMinVersion, &nCompareResult);
543 + ExitOnFailure(hr, "Failed to compare related installed version '%ls' to related min version: '%ls'", pVersion->sczVersion, pRelatedMsi->pMinVersion->sczVersion);
544 +
545 + if (pRelatedMsi->fMinInclusive ? (nCompareResult < 0) : (nCompareResult <= 0))
546 + {
547 + continue;
548 + }
549 }
550
536 - if (pRelatedMsi->fMaxProvided && (pRelatedMsi->fMaxInclusive ? (qwVersion > pRelatedMsi->qwMaxVersion) : (qwVersion >= pRelatedMsi->qwMaxVersion)))
551 + if (pRelatedMsi->fMaxProvided)
552 {
538 - continue;
553 + hr = VerCompareParsedVersions(pVersion, pRelatedMsi->pMaxVersion, &nCompareResult);
554 + ExitOnFailure(hr, "Failed to compare related installed version '%ls' to related max version: '%ls'", pVersion->sczVersion, pRelatedMsi->pMaxVersion->sczVersion);
555 +
556 + if (pRelatedMsi->fMaxInclusive ? (nCompareResult > 0) : (nCompareResult >= 0))
557 + {
558 + continue;
559 + }
560 }
561
562 // Filter by language if necessary.
@@ -605,10 +626,10 @@ extern "C" HRESULT MsiEngineDetectPackage(
626 operation = BOOTSTRAPPER_RELATED_OPERATION_MAJOR_UPGRADE;
627 }
628
608 - LogId(REPORT_STANDARD, MSG_DETECTED_RELATED_PACKAGE, wzProductCode, LoggingPerMachineToString(fPerMachine), LoggingVersionToString(qwVersion), uLcid, LoggingRelatedOperationToString(relatedMsiOperation));
629 + LogId(REPORT_STANDARD, MSG_DETECTED_RELATED_PACKAGE, wzProductCode, LoggingPerMachineToString(fPerMachine), pVersion->sczVersion, uLcid, LoggingRelatedOperationToString(relatedMsiOperation));
630
631 // Pass to BA.
611 - hr = UserExperienceOnDetectRelatedMsiPackage(pUserExperience, pPackage->sczId, pRelatedMsi->sczUpgradeCode, wzProductCode, fPerMachine, qwVersion, relatedMsiOperation);
632 + hr = UserExperienceOnDetectRelatedMsiPackage(pUserExperience, pPackage->sczId, pRelatedMsi->sczUpgradeCode, wzProductCode, fPerMachine, pVersion, relatedMsiOperation);
633 ExitOnRootFailure(hr, "BA aborted detect related MSI package.");
634 }
635 }
@@ -667,6 +688,7 @@ LExit:
688 ReleaseStr(sczInstalledProductCode);
689 ReleaseStr(sczInstalledLanguage);
690 ReleaseStr(sczInstalledVersion);
691 + ReleaseVerutilVersion(pVersion);
692
693 return hr;
694 }
@@ -684,8 +706,9 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
706 Trace(REPORT_STANDARD, "Planning MSI package 0x%p", pPackage);
707
708 HRESULT hr = S_OK;
687 - DWORD64 qwVersion = pPackage->Msi.qwVersion;
688 - DWORD64 qwInstalledVersion = pPackage->Msi.qwInstalledVersion;
709 + VERUTIL_VERSION* pVersion = pPackage->Msi.pVersion;
710 + VERUTIL_VERSION* pInstalledVersion = pPackage->Msi.pInstalledVersion;
711 + int nCompareResult = 0;
712 BOOTSTRAPPER_ACTION_STATE execute = BOOTSTRAPPER_ACTION_STATE_NONE;
713 BOOTSTRAPPER_ACTION_STATE rollback = BOOTSTRAPPER_ACTION_STATE_NONE;
714 BOOL fFeatureActionDelta = FALSE;
@@ -739,10 +762,13 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
762 case BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED:
763 if (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested || BOOTSTRAPPER_REQUEST_STATE_REPAIR == pPackage->requested)
764 {
765 + hr = VerCompareParsedVersions(pVersion, pInstalledVersion, &nCompareResult);
766 + ExitOnFailure(hr, "Failed to compare '%ls' to '%ls' for planning.", pVersion->sczVersion, pInstalledVersion->sczVersion);
767 +
768 // Take a look at the version and determine if this is a potential
769 // minor upgrade (same ProductCode newer ProductVersion), otherwise,
770 // there is a newer version so no work necessary.
745 - if (qwVersion > qwInstalledVersion)
771 + if (nCompareResult > 0)
772 {
773 execute = BOOTSTRAPPER_ACTION_STATE_MINOR_UPGRADE;
774 }
@@ -1014,20 +1040,18 @@ extern "C" HRESULT MsiEngineAddCompatiblePackage(
1040 }
1041
1042 // Read in the compatible ProductVersion if not already available.
1017 - if (pPackage->Msi.qwInstalledVersion)
1043 + if (pPackage->Msi.pInstalledVersion)
1044 {
1019 - pCompatiblePackage->Msi.qwVersion = pPackage->Msi.qwInstalledVersion;
1020 -
1021 - hr = FileVersionToStringEx(pCompatiblePackage->Msi.qwVersion, &sczInstalledVersion);
1022 - ExitOnFailure(hr, "Failed to format version number string.");
1045 + hr = VerCopyVersion(pPackage->Msi.pInstalledVersion, &pCompatiblePackage->Msi.pVersion);
1046 + ExitOnFailure(hr, "Failed to copy version for compatible package.");
1047 }
1048 else
1049 {
1050 hr = WiuGetProductInfoEx(pCompatiblePackage->Msi.sczProductCode, NULL, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion);
1051 ExitOnFailure(hr, "Failed to read version from compatible package.");
1052
1029 - hr = FileVersionFromStringEx(sczInstalledVersion, 0, &pCompatiblePackage->Msi.qwVersion);
1030 - ExitOnFailure(hr, "Failed to convert version: %ls to DWORD64 for ProductCode: %ls", sczInstalledVersion, pCompatiblePackage->Msi.sczProductCode);
1053 + hr = VerParseVersion(sczInstalledVersion, 0, FALSE, &pCompatiblePackage->Msi.pVersion);
1054 + ExitOnFailure(hr, "Failed to parse version: '%ls' for ProductCode: %ls", sczInstalledVersion, pCompatiblePackage->Msi.sczProductCode);
1055 }
1056
1057 // For now, copy enough information to support uninstalling the newer, compatible package.
@@ -1046,7 +1070,7 @@ extern "C" HRESULT MsiEngineAddCompatiblePackage(
1070 ExitOnFailure(hr, "Failed to format log path variable for compatible package.");
1071
1072 // Use the default cache ID generation from the binder.
1049 - hr = StrAllocFormatted(&pCompatiblePackage->sczCacheId, L"%lsv%ls", pCompatiblePackage->sczId, sczInstalledVersion);
1073 + hr = StrAllocFormatted(&pCompatiblePackage->sczCacheId, L"%lsv%ls", pCompatiblePackage->sczId, pCompatiblePackage->Msi.pVersion->sczVersion);
1074 ExitOnFailure(hr, "Failed to format cache ID for compatible package.");
1075
1076 pCompatiblePackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_PRESENT;
@@ -1068,7 +1092,7 @@ extern "C" HRESULT MsiEngineAddCompatiblePackage(
1092 ExitOnFailure(hr, "Failed to copy the compatible provider key.");
1093
1094 // Assume the package version is the same as the provider version.
1071 - hr = StrAllocString(&pCompatibleProvider->sczVersion, sczInstalledVersion, 0);
1095 + hr = StrAllocString(&pCompatibleProvider->sczVersion, pCompatiblePackage->Msi.pVersion->sczVersion, 0);
1096 ExitOnFailure(hr, "Failed to copy the compatible provider version.");
1097
1098 // Assume provider keys are similarly authored for this package.
@@ -1479,7 +1503,7 @@ static HRESULT ParseRelatedMsiFromXml(
1503 {
1504 ExitOnFailure(hr, "Failed to get @MinVersion.");
1505
1482 - hr = FileVersionFromStringEx(scz, 0, &pRelatedMsi->qwMinVersion);
1506 + hr = VerParseVersion(scz, 0, FALSE, &pRelatedMsi->pMinVersion);
1507 ExitOnFailure(hr, "Failed to parse @MinVersion: %ls", scz);
1508
1509 // flag that we have a min version
@@ -1496,7 +1520,7 @@ static HRESULT ParseRelatedMsiFromXml(
1520 {
1521 ExitOnFailure(hr, "Failed to get @MaxVersion.");
1522
1499 - hr = FileVersionFromStringEx(scz, 0, &pRelatedMsi->qwMaxVersion);
1523 + hr = VerParseVersion(scz, 0, FALSE, &pRelatedMsi->pMaxVersion);
1524 ExitOnFailure(hr, "Failed to parse @MaxVersion: %ls", scz);
1525
1526 // flag that we have a max version
src/engine/package.h
+4 -4
@@ -123,8 +123,8 @@ typedef struct _BURN_MSIFEATURE
123 typedef struct _BURN_RELATED_MSI
124 {
125 LPWSTR sczUpgradeCode;
126 - DWORD64 qwMinVersion;
127 - DWORD64 qwMaxVersion;
126 + VERUTIL_VERSION* pMinVersion;
127 + VERUTIL_VERSION* pMaxVersion;
128 BOOL fMinProvided;
129 BOOL fMaxProvided;
130 BOOL fMinInclusive;
@@ -236,9 +236,9 @@ typedef struct _BURN_PACKAGE
236 {
237 LPWSTR sczProductCode;
238 DWORD dwLanguage;
239 - DWORD64 qwVersion;
239 + VERUTIL_VERSION* pVersion;
240 LPWSTR sczInstalledProductCode;
241 - DWORD64 qwInstalledVersion;
241 + VERUTIL_VERSION* pInstalledVersion;
242 LPWSTR sczUpgradeCode;
243
244 BURN_MSIPROPERTY* rgProperties;
src/engine/packages.config
+1 -1
@@ -1,5 +1,5 @@
1 <?xml version="1.0" encoding="utf-8"?>
2 <packages>
3 <package id="Nerdbank.GitVersioning" version="3.1.91" targetFramework="native" developmentDependency="true" />
4 - <package id="WixToolset.DUtil" version="4.0.49" targetFramework="native" />
4 + <package id="WixToolset.DUtil" version="4.0.55" targetFramework="native" />
5 </packages>
\ No newline at end of file
src/engine/plan.cpp
+7 -3
@@ -530,7 +530,7 @@ extern "C" HRESULT PlanPackages(
530
531 pAction->type = BURN_EXECUTE_ACTION_TYPE_COMPATIBLE_PACKAGE;
532 pAction->compatiblePackage.pReferencePackage = pPackage;
533 - pAction->compatiblePackage.qwInstalledVersion = pCompatiblePackage->Msi.qwVersion;
533 + pAction->compatiblePackage.pInstalledVersion = pCompatiblePackage->Msi.pVersion;
534
535 hr = StrAllocString(&pAction->compatiblePackage.sczInstalledProductCode, pCompatiblePackage->Msi.sczProductCode, 0);
536 ExitOnFailure(hr, "Failed to copy installed ProductCode");
@@ -880,7 +880,7 @@ static HRESULT ProcessPackage(
880 {
881 AssertSz(BURN_PACKAGE_TYPE_MSI == pPackage->type, "Currently only MSI packages have compatible packages.");
882
883 - hr = UserExperienceOnPlanCompatibleMsiPackageBegin(pUX, pCompatiblePackageParent->sczId, pPackage->sczId, pPackage->Msi.qwVersion, &pPackage->requested);
883 + hr = UserExperienceOnPlanCompatibleMsiPackageBegin(pUX, pCompatiblePackageParent->sczId, pPackage->sczId, pPackage->Msi.pVersion, &pPackage->requested);
884 ExitOnRootFailure(hr, "BA aborted plan compatible MSI package begin.");
885 }
886 else
@@ -1207,6 +1207,7 @@ extern "C" HRESULT PlanRelatedBundlesBegin(
1207 LPWSTR* rgsczAncestors = NULL;
1208 UINT cAncestors = 0;
1209 STRINGDICT_HANDLE sdAncestors = NULL;
1210 + int nCompareResult = 0;
1211
1212 if (pRegistration->sczAncestors)
1213 {
@@ -1261,7 +1262,10 @@ extern "C" HRESULT PlanRelatedBundlesBegin(
1262 case BOOTSTRAPPER_RELATION_UPGRADE:
1263 if (BOOTSTRAPPER_RELATION_UPGRADE != relationType && BOOTSTRAPPER_ACTION_UNINSTALL < pPlan->action)
1264 {
1264 - pRelatedBundle->package.requested = (pRegistration->qwVersion > pRelatedBundle->qwVersion) ? BOOTSTRAPPER_REQUEST_STATE_ABSENT : BOOTSTRAPPER_REQUEST_STATE_NONE;
1265 + hr = VerCompareParsedVersions(pRegistration->pVersion, pRelatedBundle->pVersion, &nCompareResult);
1266 + ExitOnFailure(hr, "Failed to compare bundle version '%ls' to related bundle version '%ls'", pRegistration->pVersion, pRelatedBundle->pVersion);
1267 +
1268 + pRelatedBundle->package.requested = (nCompareResult > 0) ? BOOTSTRAPPER_REQUEST_STATE_ABSENT : BOOTSTRAPPER_REQUEST_STATE_NONE;
1269 }
1270 break;
1271 case BOOTSTRAPPER_RELATION_PATCH: __fallthrough;
src/engine/plan.h
+1 -1
@@ -305,7 +305,7 @@ typedef struct _BURN_EXECUTE_ACTION
305 {
306 BURN_PACKAGE* pReferencePackage;
307 LPWSTR sczInstalledProductCode;
308 - DWORD64 qwInstalledVersion;
308 + VERUTIL_VERSION* pInstalledVersion;
309 } compatiblePackage;
310 };
311 } BURN_EXECUTE_ACTION;
src/engine/precomp.h
+1
@@ -24,6 +24,7 @@
24 #define DUTIL_SOURCE_DEFAULT DUTIL_SOURCE_EXTERNAL
25
26 #include <dutil.h>
27 +#include <verutil.h>
28 #include <aclutil.h>
29 #include <apputil.h>
30 #include <buffutil.h>
src/engine/registration.cpp
+5 -7
@@ -133,7 +133,7 @@ extern "C" HRESULT RegistrationParseFromXml(
133 hr = XmlGetAttributeEx(pixnRegistrationNode, L"Version", &scz);
134 ExitOnFailure(hr, "Failed to get @Version.");
135
136 - hr = FileVersionFromStringEx(scz, 0, &pRegistration->qwVersion);
136 + hr = VerParseVersion(scz, 0, FALSE, &pRegistration->pVersion);
137 ExitOnFailure(hr, "Failed to parse @Version: %ls", scz);
138
139 // @ProviderKey
@@ -436,7 +436,7 @@ extern "C" HRESULT RegistrationSetVariables(
436 hr = VariableSetString(pVariables, BURN_BUNDLE_TAG, pRegistration->sczTag, TRUE, FALSE);
437 ExitOnFailure(hr, "Failed to overwrite the bundle tag built-in variable.");
438
439 - hr = VariableSetVersion(pVariables, BURN_BUNDLE_VERSION, pRegistration->qwVersion, TRUE);
439 + hr = VariableSetVersion(pVariables, BURN_BUNDLE_VERSION, pRegistration->pVersion, TRUE);
440 ExitOnFailure(hr, "Failed to overwrite the bundle tag built-in variable.");
441
442 LExit:
@@ -630,15 +630,13 @@ extern "C" HRESULT RegistrationSessionBegin(
630 hr = RegWriteStringArray(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_PATCH_CODE, pRegistration->rgsczPatchCodes, pRegistration->cPatchCodes);
631 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_PATCH_CODE);
632
633 - hr = RegWriteStringFormatted(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_VERSION, L"%hu.%hu.%hu.%hu",
634 - static_cast<WORD>(pRegistration->qwVersion >> 48), static_cast<WORD>(pRegistration->qwVersion >> 32),
635 - static_cast<WORD>(pRegistration->qwVersion >> 16), static_cast<WORD>(pRegistration->qwVersion));
633 + hr = RegWriteString(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_VERSION, pRegistration->pVersion->sczVersion);
634 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_VERSION);
635
638 - hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_VERSION_MAJOR, static_cast<WORD>(pRegistration->qwVersion >> 48));
636 + hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_VERSION_MAJOR, pRegistration->pVersion->dwMajor);
637 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_VERSION_MAJOR);
638
641 - hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_VERSION_MINOR, static_cast<WORD>(pRegistration->qwVersion >> 32));
639 + hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_VERSION_MINOR, pRegistration->pVersion->dwMinor);
640 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_VERSION_MINOR);
641
642 if (pRegistration->sczProviderKey)
src/engine/registration.h
+2 -2
@@ -59,7 +59,7 @@ typedef struct _BURN_RELATED_BUNDLE
59 {
60 BOOTSTRAPPER_RELATION_TYPE relationType;
61
62 - DWORD64 qwVersion;
62 + VERUTIL_VERSION* pVersion;
63 LPWSTR sczTag;
64
65 BURN_PACKAGE package;
@@ -105,7 +105,7 @@ typedef struct _BURN_REGISTRATION
105 LPWSTR *rgsczPatchCodes;
106 DWORD cPatchCodes;
107
108 - DWORD64 qwVersion;
108 + VERUTIL_VERSION* pVersion;
109 LPWSTR sczActiveParent;
110 LPWSTR sczProviderKey;
111 LPWSTR sczExecutableName;
src/engine/relatedbundle.cpp
+7 -2
@@ -396,6 +396,7 @@ static HRESULT LoadRelatedBundleFromKey(
396 {
397 HRESULT hr = S_OK;
398 DWORD64 qwEngineVersion = 0;
399 + LPWSTR sczBundleVersion = NULL;
400 LPWSTR sczCachePath = NULL;
401 DWORD64 qwFileSize = 0;
402 BURN_DEPENDENCY_PROVIDER dependencyProvider = { };
@@ -407,9 +408,12 @@ static HRESULT LoadRelatedBundleFromKey(
408 hr = S_OK;
409 }
410
410 - hr = RegReadVersion(hkBundleId, BURN_REGISTRATION_REGISTRY_BUNDLE_VERSION, &pRelatedBundle->qwVersion);
411 + hr = RegReadString(hkBundleId, BURN_REGISTRATION_REGISTRY_BUNDLE_VERSION, &sczBundleVersion);
412 ExitOnFailure(hr, "Failed to read version from registry for bundle: %ls", wzRelatedBundleId);
413
414 + hr = VerParseVersion(sczBundleVersion, 0, FALSE, &pRelatedBundle->pVersion);
415 + ExitOnFailure(hr, "Failed to parse pseudo bundle version: %ls", sczBundleVersion);
416 +
417 hr = RegReadString(hkBundleId, BURN_REGISTRATION_REGISTRY_BUNDLE_CACHE_PATH, &sczCachePath);
418 ExitOnFailure(hr, "Failed to read cache path from registry for bundle: %ls", wzRelatedBundleId);
419
@@ -423,7 +427,7 @@ static HRESULT LoadRelatedBundleFromKey(
427
428 dependencyProvider.fImported = TRUE;
429
426 - hr = FileVersionToStringEx(pRelatedBundle->qwVersion, &dependencyProvider.sczVersion);
430 + hr = StrAllocString(&dependencyProvider.sczVersion, pRelatedBundle->pVersion->sczVersion, 0);
431 ExitOnFailure(hr, "Failed to copy version for bundle: %ls", wzRelatedBundleId);
432
433 hr = RegReadString(hkBundleId, BURN_REGISTRATION_REGISTRY_BUNDLE_DISPLAY_NAME, &dependencyProvider.sczDisplayName);
@@ -452,6 +456,7 @@ static HRESULT LoadRelatedBundleFromKey(
456 LExit:
457 DependencyUninitialize(&dependencyProvider);
458 ReleaseStr(sczCachePath);
459 + ReleaseStr(sczBundleVersion);
460
461 return hr;
462 }
src/engine/search.cpp
+7 -2
@@ -754,6 +754,7 @@ static HRESULT FileSearchVersion(
754 HRESULT hr = S_OK;
755 ULARGE_INTEGER uliVersion = { };
756 LPWSTR sczPath = NULL;
757 + VERUTIL_VERSION* pVersion = NULL;
758
759 // format path
760 hr = VariableFormatString(pVariables, pSearch->FileSearch.sczPath, &sczPath, NULL);
@@ -767,14 +768,18 @@ static HRESULT FileSearchVersion(
768 LogStringLine(REPORT_STANDARD, "File search: %ls, did not find path: %ls", pSearch->sczKey, sczPath);
769 ExitFunction1(hr = S_OK);
770 }
770 - ExitOnFailure(hr, "Failed get file version.");
771 + ExitOnFailure(hr, "Failed to get file version.");
772 +
773 + hr = VerVersionFromQword(uliVersion.QuadPart, &pVersion);
774 + ExitOnFailure(hr, "Failed to create version from file version.");
775
776 // set variable
773 - hr = VariableSetVersion(pVariables, pSearch->sczVariable, uliVersion.QuadPart, FALSE);
777 + hr = VariableSetVersion(pVariables, pSearch->sczVariable, pVersion, FALSE);
778 ExitOnFailure(hr, "Failed to set variable.");
779
780 LExit:
781 StrSecureZeroFreeString(sczPath);
782 + ReleaseVerutilVersion(pVersion);
783 return hr;
784 }
785
src/engine/userexperience.cpp
+12 -12
@@ -646,7 +646,7 @@ EXTERN_C BAAPI UserExperienceOnDetectCompatibleMsiPackage(
646 __in BURN_USER_EXPERIENCE* pUserExperience,
647 __in_z LPCWSTR wzPackageId,
648 __in_z LPCWSTR wzCompatiblePackageId,
649 - __in DWORD64 dw64CompatiblePackageVersion
649 + __in VERUTIL_VERSION* pCompatiblePackageVersion
650 )
651 {
652 HRESULT hr = S_OK;
@@ -656,7 +656,7 @@ EXTERN_C BAAPI UserExperienceOnDetectCompatibleMsiPackage(
656 args.cbSize = sizeof(args);
657 args.wzPackageId = wzPackageId;
658 args.wzCompatiblePackageId = wzCompatiblePackageId;
659 - args.dw64CompatiblePackageVersion = dw64CompatiblePackageVersion;
659 + args.wzCompatiblePackageVersion = pCompatiblePackageVersion->sczVersion;
660
661 results.cbSize = sizeof(results);
662
@@ -699,7 +699,7 @@ EXTERN_C BAAPI UserExperienceOnDetectForwardCompatibleBundle(
699 __in BOOTSTRAPPER_RELATION_TYPE relationType,
700 __in_z LPCWSTR wzBundleTag,
701 __in BOOL fPerMachine,
702 - __in DWORD64 dw64Version,
702 + __in VERUTIL_VERSION* pVersion,
703 __inout BOOL* pfIgnoreBundle
704 )
705 {
@@ -712,7 +712,7 @@ EXTERN_C BAAPI UserExperienceOnDetectForwardCompatibleBundle(
712 args.relationType = relationType;
713 args.wzBundleTag = wzBundleTag;
714 args.fPerMachine = fPerMachine;
715 - args.dw64Version = dw64Version;
715 + args.wzVersion = pVersion->sczVersion;
716
717 results.cbSize = sizeof(results);
718 results.fIgnoreBundle = *pfIgnoreBundle;
@@ -817,7 +817,7 @@ EXTERN_C BAAPI UserExperienceOnDetectRelatedBundle(
817 __in BOOTSTRAPPER_RELATION_TYPE relationType,
818 __in_z LPCWSTR wzBundleTag,
819 __in BOOL fPerMachine,
820 - __in DWORD64 dw64Version,
820 + __in VERUTIL_VERSION* pVersion,
821 __in BOOTSTRAPPER_RELATED_OPERATION operation
822 )
823 {
@@ -830,7 +830,7 @@ EXTERN_C BAAPI UserExperienceOnDetectRelatedBundle(
830 args.relationType = relationType;
831 args.wzBundleTag = wzBundleTag;
832 args.fPerMachine = fPerMachine;
833 - args.dw64Version = dw64Version;
833 + args.wzVersion = pVersion->sczVersion;
834 args.operation = operation;
835
836 results.cbSize = sizeof(results);
@@ -853,7 +853,7 @@ EXTERN_C BAAPI UserExperienceOnDetectRelatedMsiPackage(
853 __in_z LPCWSTR wzUpgradeCode,
854 __in_z LPCWSTR wzProductCode,
855 __in BOOL fPerMachine,
856 - __in DWORD64 dw64Version,
856 + __in VERUTIL_VERSION* pVersion,
857 __in BOOTSTRAPPER_RELATED_OPERATION operation
858 )
859 {
@@ -866,7 +866,7 @@ EXTERN_C BAAPI UserExperienceOnDetectRelatedMsiPackage(
866 args.wzUpgradeCode = wzUpgradeCode;
867 args.wzProductCode = wzProductCode;
868 args.fPerMachine = fPerMachine;
869 - args.dw64Version = dw64Version;
869 + args.wzVersion = pVersion->sczVersion;
870 args.operation = operation;
871
872 results.cbSize = sizeof(results);
@@ -917,7 +917,7 @@ EXTERN_C BAAPI UserExperienceOnDetectUpdate(
917 __in BURN_USER_EXPERIENCE* pUserExperience,
918 __in_z LPCWSTR wzUpdateLocation,
919 __in DWORD64 dw64Size,
920 - __in DWORD64 dw64Version,
920 + __in VERUTIL_VERSION* pVersion,
921 __in_z_opt LPCWSTR wzTitle,
922 __in_z_opt LPCWSTR wzSummary,
923 __in_z_opt LPCWSTR wzContentType,
@@ -932,7 +932,7 @@ EXTERN_C BAAPI UserExperienceOnDetectUpdate(
932 args.cbSize = sizeof(args);
933 args.wzUpdateLocation = wzUpdateLocation;
934 args.dw64Size = dw64Size;
935 - args.dw64Version = dw64Version;
935 + args.wzVersion = pVersion->sczVersion;
936 args.wzTitle = wzTitle;
937 args.wzSummary = wzSummary;
938 args.wzContentType = wzContentType;
@@ -1414,7 +1414,7 @@ EXTERN_C BAAPI UserExperienceOnPlanCompatibleMsiPackageBegin(
1414 __in BURN_USER_EXPERIENCE* pUserExperience,
1415 __in_z LPCWSTR wzPackageId,
1416 __in_z LPCWSTR wzCompatiblePackageId,
1417 - __in DWORD64 dw64CompatiblePackageVersion,
1417 + __in VERUTIL_VERSION* pCompatiblePackageVersion,
1418 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState
1419 )
1420 {
@@ -1425,7 +1425,7 @@ EXTERN_C BAAPI UserExperienceOnPlanCompatibleMsiPackageBegin(
1425 args.cbSize = sizeof(args);
1426 args.wzPackageId = wzPackageId;
1427 args.wzCompatiblePackageId = wzCompatiblePackageId;
1428 - args.dw64CompatiblePackageVersion = dw64CompatiblePackageVersion;
1428 + args.wzCompatiblePackageVersion = pCompatiblePackageVersion->sczVersion;
1429 args.recommendedState = *pRequestedState;
1430
1431 results.cbSize = sizeof(results);
src/engine/userexperience.h
+6 -6
@@ -171,7 +171,7 @@ BAAPI UserExperienceOnDetectCompatibleMsiPackage(
171 __in BURN_USER_EXPERIENCE* pUserExperience,
172 __in_z LPCWSTR wzPackageId,
173 __in_z LPCWSTR wzCompatiblePackageId,
174 - __in DWORD64 dw64CompatiblePackageVersion
174 + __in VERUTIL_VERSION* pCompatiblePackageVersion
175 );
176 BAAPI UserExperienceOnDetectComplete(
177 __in BURN_USER_EXPERIENCE* pUserExperience,
@@ -183,7 +183,7 @@ BAAPI UserExperienceOnDetectForwardCompatibleBundle(
183 __in BOOTSTRAPPER_RELATION_TYPE relationType,
184 __in_z LPCWSTR wzBundleTag,
185 __in BOOL fPerMachine,
186 - __in DWORD64 dw64Version,
186 + __in VERUTIL_VERSION* pVersion,
187 __inout BOOL* pfIgnoreBundle
188 );
189 BAAPI UserExperienceOnDetectMsiFeature(
@@ -208,7 +208,7 @@ BAAPI UserExperienceOnDetectRelatedBundle(
208 __in BOOTSTRAPPER_RELATION_TYPE relationType,
209 __in_z LPCWSTR wzBundleTag,
210 __in BOOL fPerMachine,
211 - __in DWORD64 dw64Version,
211 + __in VERUTIL_VERSION* pVersion,
212 __in BOOTSTRAPPER_RELATED_OPERATION operation
213 );
214 BAAPI UserExperienceOnDetectRelatedMsiPackage(
@@ -217,7 +217,7 @@ BAAPI UserExperienceOnDetectRelatedMsiPackage(
217 __in_z LPCWSTR wzUpgradeCode,
218 __in_z LPCWSTR wzProductCode,
219 __in BOOL fPerMachine,
220 - __in DWORD64 dw64Version,
220 + __in VERUTIL_VERSION* pVersion,
221 __in BOOTSTRAPPER_RELATED_OPERATION operation
222 );
223 BAAPI UserExperienceOnDetectTargetMsiPackage(
@@ -230,7 +230,7 @@ BAAPI UserExperienceOnDetectUpdate(
230 __in BURN_USER_EXPERIENCE* pUserExperience,
231 __in_z LPCWSTR wzUpdateLocation,
232 __in DWORD64 dw64Size,
233 - __in DWORD64 dw64Version,
233 + __in VERUTIL_VERSION* pVersion,
234 __in_z_opt LPCWSTR wzTitle,
235 __in_z_opt LPCWSTR wzSummary,
236 __in_z_opt LPCWSTR wzContentType,
@@ -333,7 +333,7 @@ BAAPI UserExperienceOnPlanCompatibleMsiPackageBegin(
333 __in BURN_USER_EXPERIENCE* pUserExperience,
334 __in_z LPCWSTR wzPackageId,
335 __in_z LPCWSTR wzCompatiblePackageId,
336 - __in DWORD64 dw64CompatiblePackageVersion,
336 + __in VERUTIL_VERSION* pCompatiblePackageVersion,
337 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState
338 );
339 BAAPI UserExperienceOnPlanCompatibleMsiPackageComplete(
src/engine/variable.cpp
+45 -30
@@ -268,7 +268,7 @@ extern "C" HRESULT VariableInitialize(
268 {BURN_BUNDLE_SOURCE_PROCESS_FOLDER, InitializeVariableString, NULL, FALSE, TRUE},
269 {BURN_BUNDLE_TAG, InitializeVariableString, (DWORD_PTR)L"", FALSE, TRUE},
270 {BURN_BUNDLE_UILEVEL, InitializeVariableNumeric, 0, FALSE, TRUE},
271 - {BURN_BUNDLE_VERSION, InitializeVariableVersion, 0, FALSE, TRUE},
271 + {BURN_BUNDLE_VERSION, InitializeVariableVersion, (DWORD_PTR)L"0", FALSE, TRUE},
272 };
273
274 for (DWORD i = 0; i < countof(vrgBuiltInVariables); ++i)
@@ -561,11 +561,11 @@ LExit:
561 return hr;
562 }
563
564 -// The contents of pqwValue may be sensitive, if variable is hidden should keep value encrypted and SecureZeroMemory.
564 +// The contents of ppValue may be sensitive, if variable is hidden should keep value encrypted and SecureZeroMemory.
565 extern "C" HRESULT VariableGetVersion(
566 __in BURN_VARIABLES* pVariables,
567 __in_z LPCWSTR wzVariable,
568 - __in DWORD64* pqwValue
568 + __in VERUTIL_VERSION** ppValue
569 )
570 {
571 HRESULT hr = S_OK;
@@ -584,7 +584,7 @@ extern "C" HRESULT VariableGetVersion(
584 }
585 ExitOnFailure(hr, "Failed to get value of variable: %ls", wzVariable);
586
587 - hr = BVariantGetVersion(&pVariable->Value, pqwValue);
587 + hr = BVariantGetVersion(&pVariable->Value, ppValue);
588 ExitOnFailure(hr, "Failed to get value as version for variable: %ls", wzVariable);
589
590 LExit:
@@ -701,14 +701,14 @@ extern "C" HRESULT VariableSetString(
701 extern "C" HRESULT VariableSetVersion(
702 __in BURN_VARIABLES* pVariables,
703 __in_z LPCWSTR wzVariable,
704 - __in DWORD64 qwValue,
704 + __in VERUTIL_VERSION* pValue,
705 __in BOOL fOverwriteBuiltIn
706 )
707 {
708 BURN_VARIANT variant = { };
709
710 // We're not going to encrypt this value, so can access the value directly.
711 - variant.qwValue = qwValue;
711 + variant.pValue = pValue;
712 variant.Type = BURN_VARIANT_TYPE_VERSION;
713
714 return SetVariableValue(pVariables, wzVariable, &variant, fOverwriteBuiltIn ? SET_VARIABLE_OVERRIDE_BUILTIN : SET_VARIABLE_NOT_BUILTIN, TRUE);
@@ -810,7 +810,6 @@ extern "C" HRESULT VariableSerialize(
810 BOOL fIncluded = FALSE;
811 LONGLONG ll = 0;
812 LPWSTR scz = NULL;
813 - DWORD64 qw = 0;
813
814 ::EnterCriticalSection(&pVariables->csAccess);
815
@@ -859,15 +858,7 @@ extern "C" HRESULT VariableSerialize(
858
859 SecureZeroMemory(&ll, sizeof(ll));
860 break;
862 - case BURN_VARIANT_TYPE_VERSION:
863 - hr = BVariantGetVersion(&pVariable->Value, &qw);
864 - ExitOnFailure(hr, "Failed to get version.");
865 -
866 - hr = BuffWriteNumber64(ppbBuffer, piBuffer, qw);
867 - ExitOnFailure(hr, "Failed to write variable value as number.");
868 -
869 - SecureZeroMemory(&qw, sizeof(qw));
870 - break;
861 + case BURN_VARIANT_TYPE_VERSION: __fallthrough;
862 case BURN_VARIANT_TYPE_FORMATTED: __fallthrough;
863 case BURN_VARIANT_TYPE_STRING:
864 hr = BVariantGetString(&pVariable->Value, &scz);
@@ -887,7 +878,6 @@ extern "C" HRESULT VariableSerialize(
878 LExit:
879 ::LeaveCriticalSection(&pVariables->csAccess);
880 SecureZeroMemory(&ll, sizeof(ll));
890 - SecureZeroMemory(&qw, sizeof(qw));
881 StrSecureZeroFreeString(scz);
882
883 return hr;
@@ -908,6 +898,7 @@ extern "C" HRESULT VariableDeserialize(
898 BURN_VARIANT value = { };
899 LPWSTR scz = NULL;
900 DWORD64 qw = 0;
901 + VERUTIL_VERSION* pVersion = NULL;
902
903 ::EnterCriticalSection(&pVariables->csAccess);
904
@@ -950,10 +941,13 @@ extern "C" HRESULT VariableDeserialize(
941 SecureZeroMemory(&qw, sizeof(qw));
942 break;
943 case BURN_VARIANT_TYPE_VERSION:
953 - hr = BuffReadNumber64(pbBuffer, cbBuffer, piBuffer, &qw);
954 - ExitOnFailure(hr, "Failed to read variable value as number.");
944 + hr = BuffReadString(pbBuffer, cbBuffer, piBuffer, &scz);
945 + ExitOnFailure(hr, "Failed to read variable value as string.");
946 +
947 + hr = VerParseVersion(scz, 0, FALSE, &pVersion);
948 + ExitOnFailure(hr, "Failed to parse variable value as version.");
949
956 - hr = BVariantSetVersion(&value, qw);
950 + hr = BVariantSetVersion(&value, pVersion);
951 ExitOnFailure(hr, "Failed to set variable value.");
952
953 SecureZeroMemory(&qw, sizeof(qw));
@@ -984,6 +978,7 @@ extern "C" HRESULT VariableDeserialize(
978 LExit:
979 ::LeaveCriticalSection(&pVariables->csAccess);
980
981 + ReleaseVerutilVersion(pVersion);
982 ReleaseStr(sczName);
983 BVariantUninitialize(&value);
984 SecureZeroMemory(&qw, sizeof(qw));
@@ -1572,7 +1567,7 @@ static HRESULT SetVariableValue(
1567 break;
1568
1569 case BURN_VARIANT_TYPE_VERSION:
1575 - LogStringLine(REPORT_STANDARD, "Setting version variable '%ls' to value '%hu.%hu.%hu.%hu'", wzVariable, (WORD)(pVariant->qwValue >> 48), (WORD)(pVariant->qwValue >> 32), (WORD)(pVariant->qwValue >> 16), (WORD)(pVariant->qwValue));
1570 + LogStringLine(REPORT_STANDARD, "Setting version variable '%ls' to value '%ls'", wzVariable, pVariant->pValue->sczVersion);
1571 break;
1572
1573 default:
@@ -1609,6 +1604,7 @@ static HRESULT InitializeVariableVersionNT(
1604 RTL_GET_VERSION rtlGetVersion = NULL;
1605 RTL_OSVERSIONINFOEXW ovix = { };
1606 BURN_VARIANT value = { };
1607 + VERUTIL_VERSION* pVersion = NULL;
1608
1609 if (!::GetModuleHandleExW(0, L"ntdll", &ntdll))
1610 {
@@ -1630,12 +1626,15 @@ static HRESULT InitializeVariableVersionNT(
1626 case OS_INFO_VARIABLE_ServicePackLevel:
1627 if (0 != ovix.wServicePackMajor)
1628 {
1633 - value.qwValue = static_cast<DWORD64>(ovix.wServicePackMajor);
1629 + value.llValue = static_cast<LONGLONG>(ovix.wServicePackMajor);
1630 value.Type = BURN_VARIANT_TYPE_NUMERIC;
1631 }
1632 break;
1633 case OS_INFO_VARIABLE_VersionNT:
1638 - value.qwValue = MAKEQWORDVERSION(ovix.dwMajorVersion, ovix.dwMinorVersion, 0, 0);
1634 + hr = VerVersionFromQword(MAKEQWORDVERSION(ovix.dwMajorVersion, ovix.dwMinorVersion, 0, 0), &pVersion);
1635 + ExitOnFailure(hr, "Failed to create VersionNT from QWORD.");
1636 +
1637 + value.pValue = pVersion;
1638 value.Type = BURN_VARIANT_TYPE_VERSION;
1639 break;
1640 case OS_INFO_VARIABLE_VersionNT64:
@@ -1647,13 +1646,16 @@ static HRESULT InitializeVariableVersionNT(
1646 if (fIsWow64)
1647 #endif
1648 {
1650 - value.qwValue = MAKEQWORDVERSION(ovix.dwMajorVersion, ovix.dwMinorVersion, 0, 0);
1649 + hr = VerVersionFromQword(MAKEQWORDVERSION(ovix.dwMajorVersion, ovix.dwMinorVersion, 0, 0), &pVersion);
1650 + ExitOnFailure(hr, "Failed to create VersionNT64 from QWORD.");
1651 +
1652 + value.pValue = pVersion;
1653 value.Type = BURN_VARIANT_TYPE_VERSION;
1654 }
1655 }
1656 break;
1657 case OS_INFO_VARIABLE_WindowsBuildNumber:
1656 - value.qwValue = static_cast<DWORD64>(ovix.dwBuildNumber);
1658 + value.llValue = static_cast<LONGLONG>(ovix.dwBuildNumber);
1659 value.Type = BURN_VARIANT_TYPE_NUMERIC;
1660 default:
1661 AssertSz(FALSE, "Unknown OS info type.");
@@ -1669,6 +1671,8 @@ LExit:
1671 FreeLibrary(ntdll);
1672 }
1673
1674 + ReleaseVerutilVersion(pVersion);
1675 +
1676 return hr;
1677 }
1678
@@ -1805,15 +1809,14 @@ LExit:
1809 }
1810
1811 static HRESULT InitializeVariableVersionMsi(
1808 - __in DWORD_PTR dwpData,
1812 + __in DWORD_PTR /*dwpData*/,
1813 __inout BURN_VARIANT* pValue
1814 )
1815 {
1812 - UNREFERENCED_PARAMETER(dwpData);
1813 -
1816 HRESULT hr = S_OK;
1817 DLLGETVERSIONPROC pfnMsiDllGetVersion = NULL;
1818 DLLVERSIONINFO msiVersionInfo = { };
1819 + VERUTIL_VERSION* pVersion = NULL;
1820
1821 // get DllGetVersion proc address
1822 pfnMsiDllGetVersion = (DLLGETVERSIONPROC)::GetProcAddress(::GetModuleHandleW(L"msi"), "DllGetVersion");
@@ -1824,10 +1827,15 @@ static HRESULT InitializeVariableVersionMsi(
1827 hr = pfnMsiDllGetVersion(&msiVersionInfo);
1828 ExitOnFailure(hr, "Failed to get msi.dll version info.");
1829
1827 - hr = BVariantSetVersion(pValue, MAKEQWORDVERSION(msiVersionInfo.dwMajorVersion, msiVersionInfo.dwMinorVersion, 0, 0));
1830 + hr = VerVersionFromQword(MAKEQWORDVERSION(msiVersionInfo.dwMajorVersion, msiVersionInfo.dwMinorVersion, 0, 0), &pVersion);
1831 + ExitOnFailure(hr, "Failed to create msi.dll version from QWORD.");
1832 +
1833 + hr = BVariantSetVersion(pValue, pVersion);
1834 ExitOnFailure(hr, "Failed to set variant value.");
1835
1836 LExit:
1837 + ReleaseVerutilVersion(pVersion);
1838 +
1839 return hr;
1840 }
1841
@@ -2270,12 +2278,19 @@ static HRESULT InitializeVariableVersion(
2278 )
2279 {
2280 HRESULT hr = S_OK;
2281 + LPCWSTR wzValue = (LPCWSTR)dwpData;
2282 + VERUTIL_VERSION* pVersion = NULL;
2283 +
2284 + hr = VerParseVersion(wzValue, 0, FALSE, &pVersion);
2285 + ExitOnFailure(hr, "Failed to initialize version.");
2286
2287 // set value
2275 - hr = BVariantSetVersion(pValue, static_cast<DWORD64>(dwpData));
2288 + hr = BVariantSetVersion(pValue, pVersion);
2289 ExitOnFailure(hr, "Failed to set variant value.");
2290
2291 LExit:
2292 + ReleaseVerutilVersion(pVersion);
2293 +
2294 return hr;
2295 }
2296
src/engine/variable.h
+2 -2
@@ -85,7 +85,7 @@ HRESULT VariableGetString(
85 HRESULT VariableGetVersion(
86 __in BURN_VARIABLES* pVariables,
87 __in_z LPCWSTR wzVariable,
88 - __in DWORD64* pqwValue
88 + __in VERUTIL_VERSION** ppValue
89 );
90 HRESULT VariableGetVariant(
91 __in BURN_VARIABLES* pVariables,
@@ -113,7 +113,7 @@ HRESULT VariableSetString(
113 HRESULT VariableSetVersion(
114 __in BURN_VARIABLES* pVariables,
115 __in_z LPCWSTR wzVariable,
116 - __in DWORD64 qwValue,
116 + __in VERUTIL_VERSION* pValue,
117 __in BOOL fOverwriteBuiltIn
118 );
119 HRESULT VariableSetVariant(
src/engine/variant.cpp
+37 -34
@@ -23,7 +23,7 @@ static HRESULT BVariantRetrieveDecryptedString(
23
24 static void BVariantRetrieveVersion(
25 __in BURN_VARIANT* pVariant,
26 - __out DWORD64* pqwValue
26 + __out VERUTIL_VERSION** ppValue
27 );
28
29 // function definitions
@@ -48,6 +48,7 @@ extern "C" HRESULT BVariantGetNumeric(
48 {
49 HRESULT hr = S_OK;
50 LPWSTR sczValue = NULL;
51 + VERUTIL_VERSION* pVersionValue = NULL;
52
53 switch (pVariant->Type)
54 {
@@ -68,7 +69,13 @@ extern "C" HRESULT BVariantGetNumeric(
69 StrSecureZeroFreeString(sczValue);
70 break;
71 case BURN_VARIANT_TYPE_VERSION:
71 - BVariantRetrieveVersion(pVariant, (DWORD64*)pllValue);
72 + BVariantRetrieveVersion(pVariant, &pVersionValue);
73 +
74 + hr = StrStringToInt64(pVersionValue->sczVersion, 0, pllValue);
75 + if (FAILED(hr))
76 + {
77 + hr = DISP_E_TYPEMISMATCH;
78 + }
79 break;
80 default:
81 hr = E_INVALIDARG;
@@ -86,7 +93,7 @@ extern "C" HRESULT BVariantGetString(
93 {
94 HRESULT hr = S_OK;
95 LONGLONG llValue = 0;
89 - DWORD64 qwValue = 0;
96 + VERUTIL_VERSION* pVersionValue = NULL;
97
98 switch (pVariant->Type)
99 {
@@ -104,17 +111,9 @@ extern "C" HRESULT BVariantGetString(
111 hr = BVariantRetrieveDecryptedString(pVariant, psczValue);
112 break;
113 case BURN_VARIANT_TYPE_VERSION:
107 - BVariantRetrieveVersion(pVariant, &qwValue);
108 - if (SUCCEEDED(hr))
109 - {
110 - hr = StrAllocFormattedSecure(psczValue, L"%hu.%hu.%hu.%hu",
111 - (WORD)(qwValue >> 48),
112 - (WORD)(qwValue >> 32),
113 - (WORD)(qwValue >> 16),
114 - (WORD)qwValue);
115 - ExitOnFailure(hr, "Failed to convert version to string.");
116 - }
117 - SecureZeroMemory(&qwValue, sizeof(qwValue));
114 + BVariantRetrieveVersion(pVariant, &pVersionValue);
115 +
116 + hr = StrAllocStringSecure(psczValue, pVersionValue->sczVersion, 0);
117 break;
118 default:
119 hr = E_INVALIDARG;
@@ -125,26 +124,30 @@ LExit:
124 return hr;
125 }
126
128 -// The contents of pqwValue may be sensitive, should keep encrypted and SecureZeroMemory.
127 +// The contents of ppValue may be sensitive, should keep encrypted and SecureZeroMemory.
128 extern "C" HRESULT BVariantGetVersion(
129 __in BURN_VARIANT* pVariant,
131 - __out DWORD64* pqwValue
130 + __out VERUTIL_VERSION** ppValue
131 )
132 {
133 HRESULT hr = S_OK;
134 + LONGLONG llValue = 0;
135 LPWSTR sczValue = NULL;
136 + VERUTIL_VERSION* pValue = NULL;
137
138 switch (pVariant->Type)
139 {
140 case BURN_VARIANT_TYPE_NUMERIC:
140 - BVariantRetrieveNumeric(pVariant, (LONGLONG*)pqwValue);
141 + BVariantRetrieveNumeric(pVariant, &llValue);
142 +
143 + hr = VerVersionFromQword(llValue, ppValue);
144 break;
145 case BURN_VARIANT_TYPE_FORMATTED: __fallthrough;
146 case BURN_VARIANT_TYPE_STRING:
147 hr = BVariantRetrieveDecryptedString(pVariant, &sczValue);
148 if (SUCCEEDED(hr))
149 {
147 - hr = FileVersionFromStringEx(sczValue, 0, pqwValue);
150 + hr = VerParseVersion(sczValue, 0, FALSE, ppValue);
151 if (FAILED(hr))
152 {
153 hr = DISP_E_TYPEMISMATCH;
@@ -153,7 +156,9 @@ extern "C" HRESULT BVariantGetVersion(
156 StrSecureZeroFreeString(sczValue);
157 break;
158 case BURN_VARIANT_TYPE_VERSION:
156 - BVariantRetrieveVersion(pVariant, pqwValue);
159 + BVariantRetrieveVersion(pVariant, &pValue);
160 +
161 + hr = VerCopyVersion(pValue, ppValue);
162 break;
163 default:
164 hr = E_INVALIDARG;
@@ -224,7 +229,7 @@ LExit:
229
230 extern "C" HRESULT BVariantSetVersion(
231 __in BURN_VARIANT* pVariant,
227 - __in DWORD64 qwValue
232 + __in VERUTIL_VERSION* pValue
233 )
234 {
235 HRESULT hr = S_OK;
@@ -236,7 +241,7 @@ extern "C" HRESULT BVariantSetVersion(
241 StrSecureZeroFreeString(pVariant->sczValue);
242 }
243 memset(pVariant, 0, sizeof(BURN_VARIANT));
239 - pVariant->qwValue = qwValue;
244 + hr = VerCopyVersion(pValue, &pVariant->pValue);
245 pVariant->Type = BURN_VARIANT_TYPE_VERSION;
246 BVariantSetEncryption(pVariant, fEncryptValue);
247
@@ -251,7 +256,7 @@ extern "C" HRESULT BVariantSetValue(
256 HRESULT hr = S_OK;
257 LONGLONG llValue = 0;
258 LPWSTR sczValue = NULL;
254 - DWORD64 qwValue = 0;
259 + VERUTIL_VERSION* pVersionValue = NULL;
260 BOOL fEncrypt = pVariant->fEncryptString;
261
262 switch (pValue->Type)
@@ -277,12 +282,11 @@ extern "C" HRESULT BVariantSetValue(
282 StrSecureZeroFreeString(sczValue);
283 break;
284 case BURN_VARIANT_TYPE_VERSION:
280 - hr = BVariantGetVersion(pValue, &qwValue);
285 + hr = BVariantGetVersion(pValue, &pVersionValue);
286 if (SUCCEEDED(hr))
287 {
283 - hr = BVariantSetVersion(pVariant, qwValue);
288 + hr = BVariantSetVersion(pVariant, pVersionValue);
289 }
285 - SecureZeroMemory(&qwValue, sizeof(qwValue));
290 break;
291 default:
292 hr = E_INVALIDARG;
@@ -303,7 +307,7 @@ extern "C" HRESULT BVariantCopy(
307 HRESULT hr = S_OK;
308 LONGLONG llValue = 0;
309 LPWSTR sczValue = NULL;
306 - DWORD64 qwValue = 0;
310 + VERUTIL_VERSION* pVersionValue = 0;
311
312 BVariantUninitialize(pTarget);
313
@@ -329,12 +333,11 @@ extern "C" HRESULT BVariantCopy(
333 StrSecureZeroFreeString(sczValue);
334 break;
335 case BURN_VARIANT_TYPE_VERSION:
332 - hr = BVariantGetVersion(pSource, &qwValue);
336 + hr = BVariantGetVersion(pSource, &pVersionValue);
337 if (SUCCEEDED(hr))
338 {
335 - hr = BVariantSetVersion(pTarget, qwValue);
339 + hr = BVariantSetVersion(pTarget, pVersionValue);
340 }
337 - SecureZeroMemory(&qwValue, sizeof(qwValue));
341 break;
342 default:
343 hr = E_INVALIDARG;
@@ -380,13 +383,13 @@ extern "C" HRESULT BVariantChangeType(
383 hr = BVariantGetString(pVariant, &variant.sczValue);
384 break;
385 case BURN_VARIANT_TYPE_VERSION:
383 - hr = BVariantGetVersion(pVariant, &variant.qwValue);
386 + hr = BVariantGetVersion(pVariant, &variant.pValue);
387 break;
388 default:
389 ExitFunction1(hr = E_INVALIDARG);
390 }
388 - ExitOnFailure(hr, "Failed to copy variant value.");
391 variant.Type = type;
392 + ExitOnFailure(hr, "Failed to copy variant value.");
393
394 BVariantUninitialize(pVariant);
395 memcpy_s(pVariant, sizeof(BURN_VARIANT), &variant, sizeof(BURN_VARIANT));
@@ -524,10 +527,10 @@ LExit:
527
528 static void BVariantRetrieveVersion(
529 __in BURN_VARIANT* pVariant,
527 - __out DWORD64* pqwValue
530 + __out VERUTIL_VERSION** ppValue
531 )
532 {
530 - Assert(NULL != pqwValue);
533 + Assert(ppValue);
534
532 - *pqwValue = pVariant->qwValue;
535 + *ppValue = pVariant->pValue;
536 }
src/engine/variant.h
+3 -3
@@ -26,7 +26,7 @@ typedef struct _BURN_VARIANT
26 union
27 {
28 LONGLONG llValue;
29 - DWORD64 qwValue;
29 + VERUTIL_VERSION* pValue;
30 LPWSTR sczValue;
31 };
32 BURN_VARIANT_TYPE Type;
@@ -49,7 +49,7 @@ HRESULT BVariantGetString(
49 );
50 HRESULT BVariantGetVersion(
51 __in BURN_VARIANT* pVariant,
52 - __out DWORD64* pqwValue
52 + __out VERUTIL_VERSION** ppValue
53 );
54 HRESULT BVariantSetNumeric(
55 __in BURN_VARIANT* pVariant,
@@ -63,7 +63,7 @@ HRESULT BVariantSetString(
63 );
64 HRESULT BVariantSetVersion(
65 __in BURN_VARIANT* pVariant,
66 - __in DWORD64 qwValue
66 + __in VERUTIL_VERSION* pValue
67 );
68 /********************************************************************
69 BVariantSetValue - Convenience function that calls BVariantUninitialize,
src/stub/packages.config
+1 -1
@@ -4,5 +4,5 @@
4 <package id="Microsoft.SourceLink.Common" version="1.0.0" targetFramework="native" developmentDependency="true" />
5 <package id="Microsoft.SourceLink.GitHub" version="1.0.0" targetFramework="native" developmentDependency="true" />
6 <package id="Nerdbank.GitVersioning" version="3.1.91" targetFramework="native" developmentDependency="true" />
7 - <package id="WixToolset.DUtil" version="4.0.49" targetFramework="native" />
7 + <package id="WixToolset.DUtil" version="4.0.55" targetFramework="native" />
8 </packages>
\ No newline at end of file
src/stub/stub.vcxproj
+2 -2
@@ -5,7 +5,7 @@
5 <Import Project="..\..\packages\Microsoft.SourceLink.GitHub.1.0.0\build\Microsoft.SourceLink.GitHub.props" Condition="Exists('..\..\packages\Microsoft.SourceLink.GitHub.1.0.0\build\Microsoft.SourceLink.GitHub.props')" />
6 <Import Project="..\..\packages\Microsoft.SourceLink.Common.1.0.0\build\Microsoft.SourceLink.Common.props" Condition="Exists('..\..\packages\Microsoft.SourceLink.Common.1.0.0\build\Microsoft.SourceLink.Common.props')" />
7 <Import Project="..\..\packages\Microsoft.Build.Tasks.Git.1.0.0\build\Microsoft.Build.Tasks.Git.props" Condition="Exists('..\..\packages\Microsoft.Build.Tasks.Git.1.0.0\build\Microsoft.Build.Tasks.Git.props')" />
8 - <Import Project="..\..\packages\WixToolset.DUtil.4.0.49\build\WixToolset.DUtil.props" Condition="Exists('..\..\packages\WixToolset.DUtil.4.0.49\build\WixToolset.DUtil.props')" />
8 + <Import Project="..\..\packages\WixToolset.DUtil.4.0.55\build\WixToolset.DUtil.props" Condition="Exists('..\..\packages\WixToolset.DUtil.4.0.55\build\WixToolset.DUtil.props')" />
9
10 <ItemGroup Label="ProjectConfigurations">
11 <ProjectConfiguration Include="Debug|Win32">
@@ -107,6 +107,6 @@
107 <Error Condition="!Exists('..\..\packages\Microsoft.SourceLink.GitHub.1.0.0\build\Microsoft.SourceLink.GitHub.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.SourceLink.GitHub.1.0.0\build\Microsoft.SourceLink.GitHub.props'))" />
108 <Error Condition="!Exists('..\..\packages\Microsoft.SourceLink.GitHub.1.0.0\build\Microsoft.SourceLink.GitHub.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.SourceLink.GitHub.1.0.0\build\Microsoft.SourceLink.GitHub.targets'))" />
109 <Error Condition="!Exists('..\..\packages\Nerdbank.GitVersioning.3.1.91\build\Nerdbank.GitVersioning.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Nerdbank.GitVersioning.3.1.91\build\Nerdbank.GitVersioning.targets'))" />
110 - <Error Condition="!Exists('..\..\packages\WixToolset.DUtil.4.0.49\build\WixToolset.DUtil.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixToolset.DUtil.4.0.49\build\WixToolset.DUtil.props'))" />
110 + <Error Condition="!Exists('..\..\packages\WixToolset.DUtil.4.0.55\build\WixToolset.DUtil.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixToolset.DUtil.4.0.55\build\WixToolset.DUtil.props'))" />
111 </Target>
112 </Project>
\ No newline at end of file
src/test/BurnUnitTest/BurnUnitTest.vcxproj
+2 -2
@@ -4,7 +4,7 @@
4
5 <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
6 <Import Project="..\..\..\packages\WixBuildTools.TestSupport.Native.4.0.40\build\WixBuildTools.TestSupport.Native.props" Condition="Exists('..\..\..\packages\WixBuildTools.TestSupport.Native.4.0.40\build\WixBuildTools.TestSupport.Native.props')" />
7 - <Import Project="..\..\..\packages\WixToolset.DUtil.4.0.49\build\WixToolset.DUtil.props" Condition="Exists('..\..\..\packages\WixToolset.DUtil.4.0.49\build\WixToolset.DUtil.props')" />
7 + <Import Project="..\..\..\packages\WixToolset.DUtil.4.0.55\build\WixToolset.DUtil.props" Condition="Exists('..\..\..\packages\WixToolset.DUtil.4.0.55\build\WixToolset.DUtil.props')" />
8 <ItemGroup Label="ProjectConfigurations">
9 <ProjectConfiguration Include="Debug|Win32">
10 <Configuration>Debug</Configuration>
@@ -80,6 +80,6 @@
80 </PropertyGroup>
81 <Error Condition="!Exists('..\..\..\packages\WixBuildTools.TestSupport.Native.4.0.40\build\WixBuildTools.TestSupport.Native.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\WixBuildTools.TestSupport.Native.4.0.40\build\WixBuildTools.TestSupport.Native.props'))" />
82 <Error Condition="!Exists('..\..\..\packages\WixBuildTools.TestSupport.Native.4.0.40\build\WixBuildTools.TestSupport.Native.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\WixBuildTools.TestSupport.Native.4.0.40\build\WixBuildTools.TestSupport.Native.targets'))" />
83 - <Error Condition="!Exists('..\..\..\packages\WixToolset.DUtil.4.0.49\build\WixToolset.DUtil.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\WixToolset.DUtil.4.0.49\build\WixToolset.DUtil.props'))" />
83 + <Error Condition="!Exists('..\..\..\packages\WixToolset.DUtil.4.0.55\build\WixToolset.DUtil.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\WixToolset.DUtil.4.0.55\build\WixToolset.DUtil.props'))" />
84 </Target>
85 </Project>
src/test/BurnUnitTest/SearchTest.cpp
+11 -6
@@ -106,6 +106,7 @@ namespace Bootstrapper
106 BURN_SEARCHES searches = { };
107 BURN_EXTENSIONS burnExtensions = { };
108 ULARGE_INTEGER uliVersion = { };
109 + VERUTIL_VERSION* pVersion = NULL;
110 try
111 {
112 hr = VariableInitialize(&variables);
@@ -117,6 +118,9 @@ namespace Bootstrapper
118 hr = FileVersion(wzFile2, &uliVersion.HighPart, &uliVersion.LowPart);
119 TestThrowOnFailure(hr, L"Failed to get DLL version.");
120
121 + hr = VerVersionFromQword(uliVersion.QuadPart, &pVersion);
122 + NativeAssert::Succeeded(hr, "Failed to create version.");
123 +
124 VariableSetStringHelper(&variables, L"File1", wzFile1, FALSE);
125 VariableSetStringHelper(&variables, L"File2", wzFile2, FALSE);
126
@@ -140,10 +144,11 @@ namespace Bootstrapper
144 // check variable values
145 Assert::Equal(0ll, VariableGetNumericHelper(&variables, L"Variable1"));
146 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable2"));
143 - Assert::Equal(uliVersion.QuadPart, VariableGetVersionHelper(&variables, L"Variable3"));
147 + Assert::Equal<String^>(gcnew String(pVersion->sczVersion), VariableGetVersionHelper(&variables, L"Variable3"));
148 }
149 finally
150 {
151 + ReleaseVerutilVersion(pVersion);
152 ReleaseObject(pixeBundle);
153 VariablesUninitialize(&variables);
154 SearchesUninitialize(&searches);
@@ -247,8 +252,8 @@ namespace Bootstrapper
252 Assert::NotEqual(gcnew String(L"String1 %TEMP%"), VariableGetStringHelper(&variables, L"Variable10"));
253 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable11"));
254 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable12"));
250 - Assert::Equal(MAKEQWORDVERSION(1,1,1,1), VariableGetVersionHelper(&variables, L"Variable13"));
251 - Assert::Equal(MAKEQWORDVERSION(1,1,1,1), VariableGetVersionHelper(&variables, L"Variable14"));
255 + Assert::Equal<String^>(gcnew String(L"1.1.1.1"), VariableGetVersionHelper(&variables, L"Variable13"));
256 + Assert::Equal<String^>(gcnew String(L"1.1.1.1"), VariableGetVersionHelper(&variables, L"Variable14"));
257 Assert::Equal<String^>(gcnew String(L"String1"), VariableGetStringHelper(&variables, L"Variable15"));
258 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable16"));
259 Assert::False(VariableExistsHelper(&variables, L"Variable17"));
@@ -401,11 +406,11 @@ namespace Bootstrapper
406
407 // check variable values
408 Assert::Equal(2ll, VariableGetNumericHelper(&variables, L"Variable1"));
404 - Assert::Equal(MAKEQWORDVERSION(1,0,0,0), VariableGetVersionHelper(&variables, L"Variable2"));
409 + Assert::Equal<String^>(gcnew String(L"1.0.0.0"), VariableGetVersionHelper(&variables, L"Variable2"));
410 Assert::Equal(1033ll, VariableGetNumericHelper(&variables, L"Variable3"));
411 Assert::Equal(5ll, VariableGetNumericHelper(&variables, L"Variable4"));
412 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable5"));
408 - Assert::Equal(MAKEQWORDVERSION(1,0,0,0), VariableGetVersionHelper(&variables, L"Variable6"));
413 + Assert::Equal<String^>(gcnew String(L"1.0.0.0"), VariableGetVersionHelper(&variables, L"Variable6"));
414 }
415 finally
416 {
@@ -581,7 +586,7 @@ namespace Bootstrapper
586 Assert::Equal<String^>(gcnew String(L"VAL5"), VariableGetStringHelper(&variables, L"PROP5"));
587 Assert::Equal<String^>(gcnew String(L"VAL6"), VariableGetStringHelper(&variables, L"PROP6"));
588 Assert::Equal(7ll, VariableGetNumericHelper(&variables, L"PROP7"));
584 - Assert::Equal(MAKEQWORDVERSION(1, 1, 0, 0), VariableGetVersionHelper(&variables, L"PROP8"));
589 + Assert::Equal<String^>(gcnew String(L"1.1.0.0"), VariableGetVersionHelper(&variables, L"PROP8"));
590 Assert::Equal<String^>(gcnew String(L"1.1.0.0"), VariableGetStringHelper(&variables, L"PROP8"));
591 Assert::Equal<String^>(gcnew String(L"[VAL9]"), VariableGetStringHelper(&variables, L"PROP9"));
592
src/test/BurnUnitTest/VariableHelpers.cpp
+26 -8
@@ -33,12 +33,23 @@ namespace Bootstrapper
33 TestThrowOnFailure2(hr, L"Failed to set %s to: %I64d", wzVariable, llValue);
34 }
35
36 - void VariableSetVersionHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable, DWORD64 qwValue)
36 + void VariableSetVersionHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable, LPCWSTR wzValue)
37 {
38 HRESULT hr = S_OK;
39 + VERUTIL_VERSION* pVersion = NULL;
40
40 - hr = VariableSetVersion(pVariables, wzVariable, qwValue, FALSE);
41 - TestThrowOnFailure2(hr, L"Failed to set %s to: 0x%016I64x", wzVariable, qwValue);
41 + try
42 + {
43 + hr = VerParseVersion(wzValue, 0, FALSE, &pVersion);
44 + TestThrowOnFailure1(hr, L"Failed to parse version '%ls'", wzValue);
45 +
46 + hr = VariableSetVersion(pVariables, wzVariable, pVersion, FALSE);
47 + TestThrowOnFailure2(hr, L"Failed to set %s to: '%ls'", wzVariable, wzValue);
48 + }
49 + finally
50 + {
51 + ReleaseVerutilVersion(pVersion);
52 + }
53 }
54
55 String^ VariableGetStringHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable)
@@ -69,15 +80,22 @@ namespace Bootstrapper
80 return llValue;
81 }
82
72 - unsigned __int64 VariableGetVersionHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable)
83 + String^ VariableGetVersionHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable)
84 {
85 HRESULT hr = S_OK;
75 - DWORD64 qwValue = 0;
86 + VERUTIL_VERSION* pValue = NULL;
87
77 - hr = VariableGetVersion(pVariables, wzVariable, &qwValue);
78 - TestThrowOnFailure1(hr, L"Failed to get: %s", wzVariable);
88 + try
89 + {
90 + hr = VariableGetVersion(pVariables, wzVariable, &pValue);
91 + TestThrowOnFailure1(hr, L"Failed to get: %s", wzVariable);
92
80 - return qwValue;
93 + return gcnew String(pValue->sczVersion);
94 + }
95 + finally
96 + {
97 + ReleaseVerutilVersion(pValue);
98 + }
99 }
100
101 String^ VariableGetFormattedHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable)
src/test/BurnUnitTest/VariableHelpers.h
+2 -2
@@ -16,10 +16,10 @@ namespace Bootstrapper
16
17 void VariableSetStringHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable, LPCWSTR wzValue, BOOL fFormatted);
18 void VariableSetNumericHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable, LONGLONG llValue);
19 -void VariableSetVersionHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable, DWORD64 qwValue);
19 +void VariableSetVersionHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable, LPCWSTR wzValue);
20 System::String^ VariableGetStringHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable);
21 __int64 VariableGetNumericHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable);
22 -unsigned __int64 VariableGetVersionHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable);
22 +System::String^ VariableGetVersionHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable);
23 System::String^ VariableGetFormattedHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable);
24 System::String^ VariableFormatStringHelper(BURN_VARIABLES* pVariables, LPCWSTR wzIn);
25 System::String^ VariableEscapeStringHelper(LPCWSTR wzIn);
src/test/BurnUnitTest/VariableTest.cpp
+16 -16
@@ -42,7 +42,7 @@ namespace Bootstrapper
42 VariableSetStringHelper(&variables, L"PROP4", L"VAL4", FALSE);
43 VariableSetStringHelper(&variables, L"PROP6", L"VAL6", FALSE);
44 VariableSetStringHelper(&variables, L"PROP7", L"7", FALSE);
45 - VariableSetVersionHelper(&variables, L"PROP8", MAKEQWORDVERSION(1,1,0,0));
45 + VariableSetVersionHelper(&variables, L"PROP8", L"1.1.0.0");
46 VariableSetStringHelper(&variables, L"PROP9", L"[VAL9]", TRUE);
47
48 // set overwritten variables
@@ -61,7 +61,7 @@ namespace Bootstrapper
61 Assert::Equal<String^>(gcnew String(L"VAL5"), VariableGetStringHelper(&variables, L"PROP5"));
62 Assert::Equal<String^>(gcnew String(L"VAL6"), VariableGetStringHelper(&variables, L"PROP6"));
63 Assert::Equal(7ll, VariableGetNumericHelper(&variables, L"PROP7"));
64 - Assert::Equal(MAKEQWORDVERSION(1,1,0,0), VariableGetVersionHelper(&variables, L"PROP8"));
64 + Assert::Equal<String^>(gcnew String(L"1.1.0.0"), VariableGetVersionHelper(&variables, L"PROP8"));
65 Assert::Equal<String^>(gcnew String(L"1.1.0.0"), VariableGetStringHelper(&variables, L"PROP8"));
66 Assert::Equal<String^>(gcnew String(L"[VAL9]"), VariableGetStringHelper(&variables, L"PROP9"));
67
@@ -110,7 +110,7 @@ namespace Bootstrapper
110
111 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Var1"));
112 Assert::Equal<String^>(gcnew String(L"String value."), VariableGetStringHelper(&variables, L"Var2"));
113 - Assert::Equal(MAKEQWORDVERSION(1,2,3,4), VariableGetVersionHelper(&variables, L"Var3"));
113 + Assert::Equal<String^>(gcnew String(L"1.2.3.4"), VariableGetVersionHelper(&variables, L"Var3"));
114 Assert::Equal<String^>(gcnew String(L"[Formatted]"), VariableGetStringHelper(&variables, L"Var6"));
115 }
116 finally
@@ -214,13 +214,13 @@ namespace Bootstrapper
214 VariableSetNumericHelper(&variables, L"PROP13", 0x00010000);
215 VariableSetNumericHelper(&variables, L"PROP14", 0x00000001);
216 VariableSetNumericHelper(&variables, L"PROP15", 0x00010001);
217 - VariableSetVersionHelper(&variables, L"PROP16", MAKEQWORDVERSION(0,0,0,0));
218 - VariableSetVersionHelper(&variables, L"PROP17", MAKEQWORDVERSION(1,0,0,0));
219 - VariableSetVersionHelper(&variables, L"PROP18", MAKEQWORDVERSION(1,1,0,0));
220 - VariableSetVersionHelper(&variables, L"PROP19", MAKEQWORDVERSION(1,1,1,0));
221 - VariableSetVersionHelper(&variables, L"PROP20", MAKEQWORDVERSION(1,1,1,1));
217 + VariableSetVersionHelper(&variables, L"PROP16", L"0.0.0.0");
218 + VariableSetVersionHelper(&variables, L"PROP17", L"1.0.0.0");
219 + VariableSetVersionHelper(&variables, L"PROP18", L"1.1.0.0");
220 + VariableSetVersionHelper(&variables, L"PROP19", L"1.1.1.0");
221 + VariableSetVersionHelper(&variables, L"PROP20", L"1.1.1.1");
222 VariableSetNumericHelper(&variables, L"vPROP21", 1);
223 - VariableSetVersionHelper(&variables, L"PROP22", MAKEQWORDVERSION(65535,65535,65535,65535));
223 + VariableSetVersionHelper(&variables, L"PROP22", L"65535.65535.65535.65535");
224 VariableSetStringHelper(&variables, L"PROP23", L"1.1.1", FALSE);
225 VariableSetStringHelper(&variables, L"PROP24", L"[PROP1]", TRUE);
226 VariableSetStringHelper(&variables, L"PROP25", L"[PROP7]", TRUE);
@@ -233,7 +233,7 @@ namespace Bootstrapper
233 Assert::False(EvaluateConditionHelper(&variables, L"PROP7"));
234 Assert::False(EvaluateConditionHelper(&variables, L"PROP8"));
235 Assert::True(EvaluateConditionHelper(&variables, L"_PROP9"));
236 - Assert::False(EvaluateConditionHelper(&variables, L"PROP16"));
236 + Assert::True(EvaluateConditionHelper(&variables, L"PROP16"));
237 Assert::True(EvaluateConditionHelper(&variables, L"PROP17"));
238 Assert::True(EvaluateConditionHelper(&variables, L"PROP24"));
239 Assert::True(EvaluateConditionHelper(&variables, L"PROP25"));
@@ -268,8 +268,8 @@ namespace Bootstrapper
268 Assert::True(EvaluateConditionHelper(&variables, L"PROP18 = v1.1"));
269 Assert::True(EvaluateConditionHelper(&variables, L"PROP19 = v1.1.1"));
270 Assert::True(EvaluateConditionHelper(&variables, L"PROP20 = v1.1.1.1"));
271 - Assert::True(EvaluateFailureConditionHelper(&variables, L"PROP20 = v1.1.1.1.0"));
272 - Assert::True(EvaluateFailureConditionHelper(&variables, L"PROP20 = v1.1.1.1.1"));
271 + Assert::True(EvaluateConditionHelper(&variables, L"PROP20 > v1.1.1.1.0"));
272 + Assert::True(EvaluateConditionHelper(&variables, L"PROP20 > v1.1.1.1.1"));
273 Assert::True(EvaluateConditionHelper(&variables, L"vPROP21 = 1"));
274 Assert::True(EvaluateConditionHelper(&variables, L"PROP23 = v1.1.1"));
275 Assert::True(EvaluateConditionHelper(&variables, L"v1.1.1 = PROP23"));
@@ -287,8 +287,8 @@ namespace Bootstrapper
287 Assert::True(EvaluateFailureConditionHelper(&variables, L"PROP12 = -92233720368547758080000"));
288
289 Assert::True(EvaluateConditionHelper(&variables, L"PROP22 = v65535.65535.65535.65535"));
290 - Assert::True(EvaluateFailureConditionHelper(&variables, L"PROP22 = v65536.65535.65535.65535"));
291 - Assert::True(EvaluateFailureConditionHelper(&variables, L"PROP22 = v65535.655350000.65535.65535"));
290 + Assert::True(EvaluateConditionHelper(&variables, L"PROP22 < v65536.65535.65535.65535"));
291 + Assert::True(EvaluateConditionHelper(&variables, L"PROP22 < v65535.655350000.65535.65535"));
292
293 Assert::True(EvaluateConditionHelper(&variables, L"PROP5 < 6"));
294 Assert::False(EvaluateConditionHelper(&variables, L"PROP5 < 5"));
@@ -388,7 +388,7 @@ namespace Bootstrapper
388
389 VariableSetStringHelper(&variables1, L"PROP1", L"VAL1", FALSE);
390 VariableSetNumericHelper(&variables1, L"PROP2", 2);
391 - VariableSetVersionHelper(&variables1, L"PROP3", MAKEQWORDVERSION(1,1,1,1));
391 + VariableSetVersionHelper(&variables1, L"PROP3", L"1.1.1.1");
392 VariableSetStringHelper(&variables1, L"PROP4", L"VAL4", FALSE);
393 VariableSetStringHelper(&variables1, L"PROP5", L"[PROP1]", TRUE);
394
@@ -404,7 +404,7 @@ namespace Bootstrapper
404
405 Assert::Equal<String^>(gcnew String(L"VAL1"), VariableGetStringHelper(&variables2, L"PROP1"));
406 Assert::Equal(2ll, VariableGetNumericHelper(&variables2, L"PROP2"));
407 - Assert::Equal(MAKEQWORDVERSION(1,1,1,1), VariableGetVersionHelper(&variables2, L"PROP3"));
407 + Assert::Equal<String^>(gcnew String(L"1.1.1.1"), VariableGetVersionHelper(&variables2, L"PROP3"));
408 Assert::Equal<String^>(gcnew String(L"VAL4"), VariableGetStringHelper(&variables2, L"PROP4"));
409 Assert::Equal<String^>(gcnew String(L"[PROP1]"), VariableGetStringHelper(&variables2, L"PROP5"));
410
src/test/BurnUnitTest/VariantTest.cpp
+36 -16
@@ -37,10 +37,10 @@ namespace Bootstrapper
37 {
38 InitNumericValue(expectedVariants + 0, 2, FALSE, L"PROP1", actualVariants + 0);
39 InitStringValue(expectedVariants + 1, L"VAL2", FALSE, L"PROP2", actualVariants + 1);
40 - InitVersionValue(expectedVariants + 2, MAKEQWORDVERSION(1, 1, 0, 0), FALSE, L"PROP3", actualVariants + 2);
40 + InitVersionValue(expectedVariants + 2, L"1.1.0.0", FALSE, L"PROP3", actualVariants + 2);
41 InitNoneValue(expectedVariants + 3, FALSE, L"PROP4", actualVariants + 3);
42 InitNoneValue(expectedVariants + 4, TRUE, L"PROP5", actualVariants + 4);
43 - InitVersionValue(expectedVariants + 5, MAKEQWORDVERSION(1, 1, 1, 0), TRUE, L"PROP6", actualVariants + 5);
43 + InitVersionValue(expectedVariants + 5, L"1.1.1.0", TRUE, L"PROP6", actualVariants + 5);
44 InitStringValue(expectedVariants + 6, L"7", TRUE, L"PROP7", actualVariants + 6);
45 InitNumericValue(expectedVariants + 7, 11, TRUE, L"PROP8", actualVariants + 7);
46 InitFormattedValue(expectedVariants + 8, L"VAL9", FALSE, L"PROP9", actualVariants + 8);
@@ -143,21 +143,34 @@ namespace Bootstrapper
143 }
144 }
145
146 - void InitVersionValue(BURN_VARIANT* pValue, DWORD64 qwValue, BOOL fHidden, LPCWSTR wz, BURN_VARIANT* pActualValue)
146 + void InitVersionValue(BURN_VARIANT* pValue, LPCWSTR wzValue, BOOL fHidden, LPCWSTR wz, BURN_VARIANT* pActualValue)
147 {
148 HRESULT hr = S_OK;
149 - pValue->Type = BURN_VARIANT_TYPE_VERSION;
150 - pValue->qwValue = qwValue;
149 + VERUTIL_VERSION* pVersion = NULL;
150
152 - hr = BVariantCopy(pValue, pActualValue);
153 - NativeAssert::Succeeded(hr, "Failed to copy variant {0}", wz);
154 -
155 - if (fHidden)
151 + try
152 {
157 - hr = BVariantSetEncryption(pActualValue, TRUE);
158 - NativeAssert::Succeeded(hr, "Failed to encrypt variant {0}", wz);
153 + hr = VerParseVersion(wzValue, 0, FALSE, &pVersion);
154 + NativeAssert::Succeeded(hr, "Failed to parse version {0}", wzValue);
155
160 - NativeAssert::True(pActualValue->fEncryptString);
156 + pValue->Type = BURN_VARIANT_TYPE_VERSION;
157 + pValue->pValue = pVersion;
158 + pVersion = NULL;
159 +
160 + hr = BVariantCopy(pValue, pActualValue);
161 + NativeAssert::Succeeded(hr, "Failed to copy variant {0}", wz);
162 +
163 + if (fHidden)
164 + {
165 + hr = BVariantSetEncryption(pActualValue, TRUE);
166 + NativeAssert::Succeeded(hr, "Failed to encrypt variant {0}", wz);
167 +
168 + NativeAssert::True(pActualValue->fEncryptString);
169 + }
170 + }
171 + finally
172 + {
173 + ReleaseVerutilVersion(pVersion);
174 }
175 }
176
@@ -224,14 +237,21 @@ namespace Bootstrapper
237 void VerifyVersionValue(BURN_VARIANT* pExpectedValue, BURN_VARIANT* pActualValue)
238 {
239 HRESULT hr = S_OK;
227 - DWORD64 qwValue = 0;
240 + VERUTIL_VERSION* pValue = NULL;
241 NativeAssert::Equal<DWORD>(BURN_VARIANT_TYPE_VERSION, pExpectedValue->Type);
242 NativeAssert::Equal<DWORD>(BURN_VARIANT_TYPE_VERSION, pActualValue->Type);
243
231 - hr = BVariantGetVersion(pActualValue, &qwValue);
232 - NativeAssert::Succeeded(hr, "Failed to get version value");
244 + try
245 + {
246 + hr = BVariantGetVersion(pActualValue, &pValue);
247 + NativeAssert::Succeeded(hr, "Failed to get version value");
248
234 - NativeAssert::Equal<DWORD64>(pExpectedValue->qwValue, qwValue);
249 + NativeAssert::StringEqual(pExpectedValue->pValue->sczVersion, pActualValue->pValue->sczVersion);
250 + }
251 + finally
252 + {
253 + ReleaseVerutilVersion(pValue);
254 + }
255 }
256 };
257 }
src/test/BurnUnitTest/packages.config
+1 -1
@@ -9,5 +9,5 @@
9 <package id="xunit.runner.visualstudio" version="2.4.1" />
10 <package id="WixBuildTools.TestSupport" version="4.0.40" />
11 <package id="WixBuildTools.TestSupport.Native" version="4.0.40" />
12 - <package id="WixToolset.DUtil" version="4.0.49" targetFramework="native" />
12 + <package id="WixToolset.DUtil" version="4.0.55" targetFramework="native" />
13 </packages>
\ No newline at end of file
src/test/BurnUnitTest/precomp.h
+1
@@ -13,6 +13,7 @@
13 #include "wininet.h"
14
15 #include <dutil.h>
16 +#include <verutil.h>
17 #include <cryputil.h>
18 #include <dlutil.h>
19 #include <buffutil.h>