aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRaul Metsma <raul@metsma.ee>2025-05-26 10:52:16 +0300
committerRob Mensching <rob@firegiant.com>2025-12-13 14:23:15 -0800
commit56072818e7f18611ba7d5e717a6b3dafc952f440 (patch)
tree9ba670ef6085179f979d084dc2175cbb0d757adc /src
parent48b80e2d67c1f98ab5fe4aee28d849e36a1828d9 (diff)
downloadwix-56072818e7f18611ba7d5e717a6b3dafc952f440.tar.gz
wix-56072818e7f18611ba7d5e717a6b3dafc952f440.tar.bz2
wix-56072818e7f18611ba7d5e717a6b3dafc952f440.zip
Add exists option to ProductSearchResult for matching other search types
(e.g. FileSearch, DirectorySearch, RegistrySearch) Signed-off-by: Raul Metsma <raul@metsma.ee>
Diffstat (limited to 'src')
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixProductSearchSymbol.cs1
-rw-r--r--src/burn/engine/search.cpp13
-rw-r--r--src/burn/engine/search.h1
-rw-r--r--src/burn/test/BurnUnitTest/SearchTest.cpp4
-rw-r--r--src/ext/Util/wixext/UtilCompiler.cs5
-rw-r--r--src/wix/WixToolset.Core.Burn/Bind/LegacySearchFacade.cs3
-rw-r--r--src/xsd/util.xsd5
7 files changed, 31 insertions, 1 deletions
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixProductSearchSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixProductSearchSymbol.cs
index 99360da5..38f2af88 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixProductSearchSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixProductSearchSymbol.cs
@@ -46,6 +46,7 @@ namespace WixToolset.Data.Symbols
46 Language, 46 Language,
47 State, 47 State,
48 Assignment, 48 Assignment,
49 Exists,
49 } 50 }
50 51
51 public class WixProductSearchSymbol : IntermediateSymbol 52 public class WixProductSearchSymbol : IntermediateSymbol
diff --git a/src/burn/engine/search.cpp b/src/burn/engine/search.cpp
index b5218600..626ffb28 100644
--- a/src/burn/engine/search.cpp
+++ b/src/burn/engine/search.cpp
@@ -334,6 +334,10 @@ extern "C" HRESULT SearchesParseFromXml(
334 { 334 {
335 pSearch->MsiProductSearch.Type = BURN_MSI_PRODUCT_SEARCH_TYPE_ASSIGNMENT; 335 pSearch->MsiProductSearch.Type = BURN_MSI_PRODUCT_SEARCH_TYPE_ASSIGNMENT;
336 } 336 }
337 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"exists", -1))
338 {
339 pSearch->MsiProductSearch.Type = BURN_MSI_PRODUCT_SEARCH_TYPE_EXISTS;
340 }
337 else 341 else
338 { 342 {
339 ExitWithRootFailure(hr, E_INVALIDARG, "Invalid value for @Type: %ls", scz); 343 ExitWithRootFailure(hr, E_INVALIDARG, "Invalid value for @Type: %ls", scz);
@@ -1144,6 +1148,7 @@ static HRESULT MsiProductSearch(
1144 case BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE: 1148 case BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE:
1145 wzProperty = INSTALLPROPERTY_LANGUAGE; 1149 wzProperty = INSTALLPROPERTY_LANGUAGE;
1146 break; 1150 break;
1151 case BURN_MSI_PRODUCT_SEARCH_TYPE_EXISTS: __fallthrough;
1147 case BURN_MSI_PRODUCT_SEARCH_TYPE_STATE: 1152 case BURN_MSI_PRODUCT_SEARCH_TYPE_STATE:
1148 wzProperty = INSTALLPROPERTY_PRODUCTSTATE; 1153 wzProperty = INSTALLPROPERTY_PRODUCTSTATE;
1149 break; 1154 break;
@@ -1218,6 +1223,7 @@ static HRESULT MsiProductSearch(
1218 case BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE: 1223 case BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE:
1219 // is supposed to remain empty 1224 // is supposed to remain empty
1220 break; 1225 break;
1226 case BURN_MSI_PRODUCT_SEARCH_TYPE_EXISTS: __fallthrough;
1221 case BURN_MSI_PRODUCT_SEARCH_TYPE_STATE: 1227 case BURN_MSI_PRODUCT_SEARCH_TYPE_STATE:
1222 value.Type = BURN_VARIANT_TYPE_NUMERIC; 1228 value.Type = BURN_VARIANT_TYPE_NUMERIC;
1223 value.llValue = INSTALLSTATE_ABSENT; 1229 value.llValue = INSTALLSTATE_ABSENT;
@@ -1237,6 +1243,7 @@ static HRESULT MsiProductSearch(
1237 case BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE: 1243 case BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE:
1238 type = BURN_VARIANT_TYPE_STRING; 1244 type = BURN_VARIANT_TYPE_STRING;
1239 break; 1245 break;
1246 case BURN_MSI_PRODUCT_SEARCH_TYPE_EXISTS: __fallthrough;
1240 case BURN_MSI_PRODUCT_SEARCH_TYPE_STATE: __fallthrough; 1247 case BURN_MSI_PRODUCT_SEARCH_TYPE_STATE: __fallthrough;
1241 case BURN_MSI_PRODUCT_SEARCH_TYPE_ASSIGNMENT: 1248 case BURN_MSI_PRODUCT_SEARCH_TYPE_ASSIGNMENT:
1242 type = BURN_VARIANT_TYPE_NUMERIC; 1249 type = BURN_VARIANT_TYPE_NUMERIC;
@@ -1245,6 +1252,12 @@ static HRESULT MsiProductSearch(
1245 hr = BVariantChangeType(&value, type); 1252 hr = BVariantChangeType(&value, type);
1246 ExitOnFailure(hr, "Failed to change value type."); 1253 ExitOnFailure(hr, "Failed to change value type.");
1247 1254
1255 // Alter value here after value has changed to numberic type.
1256 if (BURN_MSI_PRODUCT_SEARCH_TYPE_EXISTS == pSearch->MsiProductSearch.Type)
1257 {
1258 value.llValue = (value.llValue == INSTALLSTATE_ABSENT) ? 0 : 1;
1259 }
1260
1248 // Set variable. 1261 // Set variable.
1249 hr = VariableSetVariant(pVariables, pSearch->sczVariable, &value); 1262 hr = VariableSetVariant(pVariables, pSearch->sczVariable, &value);
1250 ExitOnFailure(hr, "Failed to set variable."); 1263 ExitOnFailure(hr, "Failed to set variable.");
diff --git a/src/burn/engine/search.h b/src/burn/engine/search.h
index 341fe1aa..e70645c5 100644
--- a/src/burn/engine/search.h
+++ b/src/burn/engine/search.h
@@ -58,6 +58,7 @@ enum BURN_MSI_PRODUCT_SEARCH_TYPE
58 BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE, 58 BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE,
59 BURN_MSI_PRODUCT_SEARCH_TYPE_STATE, 59 BURN_MSI_PRODUCT_SEARCH_TYPE_STATE,
60 BURN_MSI_PRODUCT_SEARCH_TYPE_ASSIGNMENT, 60 BURN_MSI_PRODUCT_SEARCH_TYPE_ASSIGNMENT,
61 BURN_MSI_PRODUCT_SEARCH_TYPE_EXISTS,
61}; 62};
62 63
63enum BURN_MSI_PRODUCT_SEARCH_GUID_TYPE 64enum BURN_MSI_PRODUCT_SEARCH_GUID_TYPE
diff --git a/src/burn/test/BurnUnitTest/SearchTest.cpp b/src/burn/test/BurnUnitTest/SearchTest.cpp
index a8e397c2..e3c714cb 100644
--- a/src/burn/test/BurnUnitTest/SearchTest.cpp
+++ b/src/burn/test/BurnUnitTest/SearchTest.cpp
@@ -410,6 +410,8 @@ namespace Bootstrapper
410 L" <MsiProductSearch Id='Search4' Type='state' ProductCode='{600D0000-0000-0000-0000-000000000000}' Variable='Variable4' />" 410 L" <MsiProductSearch Id='Search4' Type='state' ProductCode='{600D0000-0000-0000-0000-000000000000}' Variable='Variable4' />"
411 L" <MsiProductSearch Id='Search5' Type='assignment' ProductCode='{600D0000-0000-0000-0000-000000000000}' Variable='Variable5' />" 411 L" <MsiProductSearch Id='Search5' Type='assignment' ProductCode='{600D0000-0000-0000-0000-000000000000}' Variable='Variable5' />"
412 L" <MsiProductSearch Id='Search6' Type='version' ProductCode='{600D0000-1000-0000-0000-000000000000}' Variable='Variable6' />" 412 L" <MsiProductSearch Id='Search6' Type='version' ProductCode='{600D0000-1000-0000-0000-000000000000}' Variable='Variable6' />"
413 L" <MsiProductSearch Id='Search7' Type='exists' ProductCode='{600D0000-0000-0000-0000-000000000000}' Variable='Variable7' />"
414 L" <MsiProductSearch Id='Search8' Type='exists' ProductCode='{BAD00000-0000-0000-0000-000000000000}' Variable='Variable8' />"
413 L"</Bundle>"; 415 L"</Bundle>";
414 416
415 // load XML document 417 // load XML document
@@ -429,6 +431,8 @@ namespace Bootstrapper
429 Assert::Equal(5ll, VariableGetNumericHelper(&variables, L"Variable4")); 431 Assert::Equal(5ll, VariableGetNumericHelper(&variables, L"Variable4"));
430 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable5")); 432 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable5"));
431 Assert::Equal<String^>(gcnew String(L"1.0.0.0"), VariableGetVersionHelper(&variables, L"Variable6")); 433 Assert::Equal<String^>(gcnew String(L"1.0.0.0"), VariableGetVersionHelper(&variables, L"Variable6"));
434 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable7"));
435 Assert::Equal(0ll, VariableGetNumericHelper(&variables, L"Variable8"));
432 } 436 }
433 finally 437 finally
434 { 438 {
diff --git a/src/ext/Util/wixext/UtilCompiler.cs b/src/ext/Util/wixext/UtilCompiler.cs
index 1ad27322..919cc49b 100644
--- a/src/ext/Util/wixext/UtilCompiler.cs
+++ b/src/ext/Util/wixext/UtilCompiler.cs
@@ -2736,8 +2736,11 @@ namespace WixToolset.Util
2736 case "assignment": 2736 case "assignment":
2737 type = WixProductSearchType.Assignment; 2737 type = WixProductSearchType.Assignment;
2738 break; 2738 break;
2739 case "exists":
2740 type = WixProductSearchType.Exists;
2741 break;
2739 default: 2742 default:
2740 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, attrib.Parent.Name.LocalName, attrib.Name.LocalName, result, "version", "language", "state", "assignment")); 2743 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, attrib.Parent.Name.LocalName, attrib.Name.LocalName, result, "version", "language", "state", "assignment", "exists"));
2741 break; 2744 break;
2742 } 2745 }
2743 break; 2746 break;
diff --git a/src/wix/WixToolset.Core.Burn/Bind/LegacySearchFacade.cs b/src/wix/WixToolset.Core.Burn/Bind/LegacySearchFacade.cs
index c9301fdc..885f307e 100644
--- a/src/wix/WixToolset.Core.Burn/Bind/LegacySearchFacade.cs
+++ b/src/wix/WixToolset.Core.Burn/Bind/LegacySearchFacade.cs
@@ -135,6 +135,9 @@ namespace WixToolset.Core.Burn
135 case WixProductSearchType.Assignment: 135 case WixProductSearchType.Assignment:
136 writer.WriteAttributeString("Type", "assignment"); 136 writer.WriteAttributeString("Type", "assignment");
137 break; 137 break;
138 case WixProductSearchType.Exists:
139 writer.WriteAttributeString("Type", "exists");
140 break;
138 default: 141 default:
139 throw new NotImplementedException(); 142 throw new NotImplementedException();
140 } 143 }
diff --git a/src/xsd/util.xsd b/src/xsd/util.xsd
index c0a9e44a..ef304762 100644
--- a/src/xsd/util.xsd
+++ b/src/xsd/util.xsd
@@ -1344,6 +1344,11 @@
1344 <xs:documentation>Saves the version of a matching product if found; 0.0.0.0 otherwise. This is the default.</xs:documentation> 1344 <xs:documentation>Saves the version of a matching product if found; 0.0.0.0 otherwise. This is the default.</xs:documentation>
1345 </xs:annotation> 1345 </xs:annotation>
1346 </xs:enumeration> 1346 </xs:enumeration>
1347 <xs:enumeration value="exists">
1348 <xs:annotation>
1349 <xs:documentation>Saves true if a matching product entry is found; false otherwise.</xs:documentation>
1350 </xs:annotation>
1351 </xs:enumeration>
1347 </xs:restriction> 1352 </xs:restriction>
1348 </xs:simpleType> 1353 </xs:simpleType>
1349 </xs:attribute> 1354 </xs:attribute>