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 /src | |
| parent | 3f8e35223216ebbe7f6683a5031a5a97bbc66d5a (diff) | |
| download | wix-273c69f34311f4f4e5f6b5896e71d0788f12d96a.tar.gz wix-273c69f34311f4f4e5f6b5896e71d0788f12d96a.tar.bz2 wix-273c69f34311f4f4e5f6b5896e71d0788f12d96a.zip | |
WIXFEAT:6210 Change data type of versions to strings.
Diffstat (limited to 'src')
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> |
