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