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>