From 7e79c6be038f3703e53fa5ff04c4e2ad865541c1 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Mon, 30 Mar 2020 21:05:11 +1000 Subject: Implement SetVariable. --- src/engine/search.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++++++++- src/engine/search.h | 5 ++++ src/engine/variable.cpp | 9 +++++++ src/engine/variable.h | 5 ++++ 4 files changed, 89 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/engine/search.cpp b/src/engine/search.cpp index 763286fd..16f8e459 100644 --- a/src/engine/search.cpp +++ b/src/engine/search.cpp @@ -48,6 +48,10 @@ static HRESULT MsiFeatureSearch( static HRESULT PerformExtensionSearch( __in BURN_SEARCH* pSearch ); +static HRESULT PerformSetVariable( + __in BURN_SEARCH* pSearch, + __in BURN_VARIABLES* pVariables +); // function definitions @@ -64,9 +68,10 @@ extern "C" HRESULT SearchesParseFromXml( DWORD cNodes = 0; BSTR bstrNodeName = NULL; LPWSTR scz = NULL; + BURN_VARIANT_TYPE valueType = BURN_VARIANT_TYPE_NONE; // select search nodes - hr = XmlSelectNodes(pixnBundle, L"DirectorySearch|FileSearch|RegistrySearch|MsiComponentSearch|MsiProductSearch|MsiFeatureSearch|ExtensionSearch", &pixnNodes); + hr = XmlSelectNodes(pixnBundle, L"DirectorySearch|FileSearch|RegistrySearch|MsiComponentSearch|MsiProductSearch|MsiFeatureSearch|ExtensionSearch|SetVariable", &pixnNodes); ExitOnFailure(hr, "Failed to select search nodes."); // get search node count @@ -388,6 +393,50 @@ extern "C" HRESULT SearchesParseFromXml( hr = BurnExtensionFindById(pBurnExtensions, scz, &pSearch->ExtensionSearch.pExtension); ExitOnFailure(hr, "Failed to find extension '%ls' for search '%ls'", scz, pSearch->sczKey); } + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"SetVariable", -1)) + { + pSearch->Type = BURN_SEARCH_TYPE_SET_VARIABLE; + + // @Value + hr = XmlGetAttributeEx(pixnNode, L"Value", &scz); + if (E_NOTFOUND != hr) + { + ExitOnFailure(hr, "Failed to get @Value."); + + hr = BVariantSetString(&pSearch->SetVariable.value, scz, 0); + ExitOnFailure(hr, "Failed to set variant value."); + + // @Type + hr = XmlGetAttributeEx(pixnNode, L"Type", &scz); + ExitOnFailure(hr, "Failed to get @Type."); + + if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"numeric", -1)) + { + valueType = BURN_VARIANT_TYPE_NUMERIC; + } + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"string", -1)) + { + valueType = BURN_VARIANT_TYPE_STRING; + } + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"version", -1)) + { + valueType = BURN_VARIANT_TYPE_VERSION; + } + else + { + hr = E_INVALIDARG; + ExitOnFailure(hr, "Invalid value for @Type: %ls", scz); + } + } + else + { + valueType = BURN_VARIANT_TYPE_NONE; + } + + // change value variant to correct type + hr = BVariantChangeType(&pSearch->SetVariable.value, valueType); + ExitOnFailure(hr, "Failed to change variant type."); + } else { hr = E_UNEXPECTED; @@ -495,6 +544,9 @@ extern "C" HRESULT SearchesExecute( case BURN_SEARCH_TYPE_EXTENSION: hr = PerformExtensionSearch(pSearch); break; + case BURN_SEARCH_TYPE_SET_VARIABLE: + hr = PerformSetVariable(pSearch, pVariables); + break; default: hr = E_UNEXPECTED; } @@ -549,6 +601,9 @@ extern "C" void SearchesUninitialize( ReleaseStr(pSearch->MsiFeatureSearch.sczProductCode); ReleaseStr(pSearch->MsiFeatureSearch.sczFeatureId); break; + case BURN_SEARCH_TYPE_SET_VARIABLE: + BVariantUninitialize(&pSearch->SetVariable.value); + break; } } MemFree(pSearches->rgSearches); @@ -1222,3 +1277,17 @@ static HRESULT PerformExtensionSearch( return hr; } + +static HRESULT PerformSetVariable( + __in BURN_SEARCH* pSearch, + __in BURN_VARIABLES* pVariables + ) +{ + HRESULT hr = S_OK; + + hr = VariableSetVariant(pVariables, pSearch->sczVariable, &pSearch->SetVariable.value); + ExitOnFailure(hr, "Failed to set variable: %ls", pSearch->sczVariable); + +LExit: + return hr; +} diff --git a/src/engine/search.h b/src/engine/search.h index d6b2586e..c699c97c 100644 --- a/src/engine/search.h +++ b/src/engine/search.h @@ -19,6 +19,7 @@ enum BURN_SEARCH_TYPE BURN_SEARCH_TYPE_MSI_PRODUCT, BURN_SEARCH_TYPE_MSI_FEATURE, BURN_SEARCH_TYPE_EXTENSION, + BURN_SEARCH_TYPE_SET_VARIABLE, }; enum BURN_DIRECTORY_SEARCH_TYPE @@ -127,6 +128,10 @@ typedef struct _BURN_SEARCH { BURN_EXTENSION* pExtension; } ExtensionSearch; + struct + { + BURN_VARIANT value; + } SetVariable; }; } BURN_SEARCH; diff --git a/src/engine/variable.cpp b/src/engine/variable.cpp index 8b1fd279..dc5a569a 100644 --- a/src/engine/variable.cpp +++ b/src/engine/variable.cpp @@ -732,6 +732,15 @@ extern "C" HRESULT VariableSetLiteralVariant( return SetVariableValue(pVariables, wzVariable, pVariant, TRUE, SET_VARIABLE_NOT_BUILTIN, TRUE); } +extern "C" HRESULT VariableSetVariant( + __in BURN_VARIABLES * pVariables, + __in_z LPCWSTR wzVariable, + __in BURN_VARIANT * pVariant + ) +{ + return SetVariableValue(pVariables, wzVariable, pVariant, FALSE, SET_VARIABLE_NOT_BUILTIN, TRUE); +} + // The contents of psczOut may be sensitive, should keep encrypted and SecureZeroFree extern "C" HRESULT VariableFormatString( __in BURN_VARIABLES* pVariables, diff --git a/src/engine/variable.h b/src/engine/variable.h index c48e0160..63f12cdf 100644 --- a/src/engine/variable.h +++ b/src/engine/variable.h @@ -127,6 +127,11 @@ HRESULT VariableSetLiteralVariant( __in_z LPCWSTR wzVariable, __in BURN_VARIANT* pVariant ); +HRESULT VariableSetVariant( + __in BURN_VARIABLES* pVariables, + __in_z LPCWSTR wzVariable, + __in BURN_VARIANT* pVariant + ); HRESULT VariableFormatString( __in BURN_VARIABLES* pVariables, __in_z LPCWSTR wzIn, -- cgit v1.2.3-55-g6feb