Implement SetVariable.
Sean Hall committed
Mar 30, 2020 at 21:05 UTC
7e79c6be038f3703e53fa5ff04c4e2ad865541c1
4 files changed
+89
-1
src/engine/search.cpp
+70
-1
@@ -48,6 +48,10 @@ static HRESULT MsiFeatureSearch(
48
static HRESULT PerformExtensionSearch(
49
__in BURN_SEARCH* pSearch
50
);
51
+static HRESULT PerformSetVariable(
52
+ __in BURN_SEARCH* pSearch,
53
+ __in BURN_VARIABLES* pVariables
54
+);
55
56
57
// function definitions
@@ -64,9 +68,10 @@ extern "C" HRESULT SearchesParseFromXml(
68
DWORD cNodes = 0;
69
BSTR bstrNodeName = NULL;
70
LPWSTR scz = NULL;
71
+ BURN_VARIANT_TYPE valueType = BURN_VARIANT_TYPE_NONE;
72
73
// select search nodes
69
- hr = XmlSelectNodes(pixnBundle, L"DirectorySearch|FileSearch|RegistrySearch|MsiComponentSearch|MsiProductSearch|MsiFeatureSearch|ExtensionSearch", &pixnNodes);
74
+ hr = XmlSelectNodes(pixnBundle, L"DirectorySearch|FileSearch|RegistrySearch|MsiComponentSearch|MsiProductSearch|MsiFeatureSearch|ExtensionSearch|SetVariable", &pixnNodes);
75
ExitOnFailure(hr, "Failed to select search nodes.");
76
77
// get search node count
@@ -388,6 +393,50 @@ extern "C" HRESULT SearchesParseFromXml(
393
hr = BurnExtensionFindById(pBurnExtensions, scz, &pSearch->ExtensionSearch.pExtension);
394
ExitOnFailure(hr, "Failed to find extension '%ls' for search '%ls'", scz, pSearch->sczKey);
395
}
396
+ else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"SetVariable", -1))
397
+ {
398
+ pSearch->Type = BURN_SEARCH_TYPE_SET_VARIABLE;
399
+
400
+ // @Value
401
+ hr = XmlGetAttributeEx(pixnNode, L"Value", &scz);
402
+ if (E_NOTFOUND != hr)
403
+ {
404
+ ExitOnFailure(hr, "Failed to get @Value.");
405
+
406
+ hr = BVariantSetString(&pSearch->SetVariable.value, scz, 0);
407
+ ExitOnFailure(hr, "Failed to set variant value.");
408
+
409
+ // @Type
410
+ hr = XmlGetAttributeEx(pixnNode, L"Type", &scz);
411
+ ExitOnFailure(hr, "Failed to get @Type.");
412
+
413
+ if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"numeric", -1))
414
+ {
415
+ valueType = BURN_VARIANT_TYPE_NUMERIC;
416
+ }
417
+ else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"string", -1))
418
+ {
419
+ valueType = BURN_VARIANT_TYPE_STRING;
420
+ }
421
+ else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"version", -1))
422
+ {
423
+ valueType = BURN_VARIANT_TYPE_VERSION;
424
+ }
425
+ else
426
+ {
427
+ hr = E_INVALIDARG;
428
+ ExitOnFailure(hr, "Invalid value for @Type: %ls", scz);
429
+ }
430
+ }
431
+ else
432
+ {
433
+ valueType = BURN_VARIANT_TYPE_NONE;
434
+ }
435
+
436
+ // change value variant to correct type
437
+ hr = BVariantChangeType(&pSearch->SetVariable.value, valueType);
438
+ ExitOnFailure(hr, "Failed to change variant type.");
439
+ }
440
else
441
{
442
hr = E_UNEXPECTED;
@@ -495,6 +544,9 @@ extern "C" HRESULT SearchesExecute(
544
case BURN_SEARCH_TYPE_EXTENSION:
545
hr = PerformExtensionSearch(pSearch);
546
break;
547
+ case BURN_SEARCH_TYPE_SET_VARIABLE:
548
+ hr = PerformSetVariable(pSearch, pVariables);
549
+ break;
550
default:
551
hr = E_UNEXPECTED;
552
}
@@ -549,6 +601,9 @@ extern "C" void SearchesUninitialize(
601
ReleaseStr(pSearch->MsiFeatureSearch.sczProductCode);
602
ReleaseStr(pSearch->MsiFeatureSearch.sczFeatureId);
603
break;
604
+ case BURN_SEARCH_TYPE_SET_VARIABLE:
605
+ BVariantUninitialize(&pSearch->SetVariable.value);
606
+ break;
607
}
608
}
609
MemFree(pSearches->rgSearches);
@@ -1222,3 +1277,17 @@ static HRESULT PerformExtensionSearch(
1277
1278
return hr;
1279
}
1280
+
1281
+static HRESULT PerformSetVariable(
1282
+ __in BURN_SEARCH* pSearch,
1283
+ __in BURN_VARIABLES* pVariables
1284
+ )
1285
+{
1286
+ HRESULT hr = S_OK;
1287
+
1288
+ hr = VariableSetVariant(pVariables, pSearch->sczVariable, &pSearch->SetVariable.value);
1289
+ ExitOnFailure(hr, "Failed to set variable: %ls", pSearch->sczVariable);
1290
+
1291
+LExit:
1292
+ return hr;
1293
+}
src/engine/search.h
+5
@@ -19,6 +19,7 @@ enum BURN_SEARCH_TYPE
19
BURN_SEARCH_TYPE_MSI_PRODUCT,
20
BURN_SEARCH_TYPE_MSI_FEATURE,
21
BURN_SEARCH_TYPE_EXTENSION,
22
+ BURN_SEARCH_TYPE_SET_VARIABLE,
23
};
24
25
enum BURN_DIRECTORY_SEARCH_TYPE
@@ -127,6 +128,10 @@ typedef struct _BURN_SEARCH
128
{
129
BURN_EXTENSION* pExtension;
130
} ExtensionSearch;
131
+ struct
132
+ {
133
+ BURN_VARIANT value;
134
+ } SetVariable;
135
};
136
} BURN_SEARCH;
137
src/engine/variable.cpp
+9
@@ -732,6 +732,15 @@ extern "C" HRESULT VariableSetLiteralVariant(
732
return SetVariableValue(pVariables, wzVariable, pVariant, TRUE, SET_VARIABLE_NOT_BUILTIN, TRUE);
733
}
734
735
+extern "C" HRESULT VariableSetVariant(
736
+ __in BURN_VARIABLES * pVariables,
737
+ __in_z LPCWSTR wzVariable,
738
+ __in BURN_VARIANT * pVariant
739
+ )
740
+{
741
+ return SetVariableValue(pVariables, wzVariable, pVariant, FALSE, SET_VARIABLE_NOT_BUILTIN, TRUE);
742
+}
743
+
744
// The contents of psczOut may be sensitive, should keep encrypted and SecureZeroFree
745
extern "C" HRESULT VariableFormatString(
746
__in BURN_VARIABLES* pVariables,
src/engine/variable.h
+5
@@ -127,6 +127,11 @@ HRESULT VariableSetLiteralVariant(
127
__in_z LPCWSTR wzVariable,
128
__in BURN_VARIANT* pVariant
129
);
130
+HRESULT VariableSetVariant(
131
+ __in BURN_VARIABLES* pVariables,
132
+ __in_z LPCWSTR wzVariable,
133
+ __in BURN_VARIANT* pVariant
134
+ );
135
HRESULT VariableFormatString(
136
__in BURN_VARIABLES* pVariables,
137
__in_z LPCWSTR wzIn,