aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-07-18 19:52:05 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-07-18 19:52:05 -0500
commit1bdf42c558d6923380b9f3ea409027816f972f98 (patch)
tree0c3c879e6ddf51e6771f88d0bd85d8d45cf66104
parentf3c96bcab560cb09355e9366eac3f4195479d95d (diff)
downloadwix-1bdf42c558d6923380b9f3ea409027816f972f98.tar.gz
wix-1bdf42c558d6923380b9f3ea409027816f972f98.tar.bz2
wix-1bdf42c558d6923380b9f3ea409027816f972f98.zip
Refactor butil while cleaning up other things.
-rw-r--r--src/CustomizedNativeRecommendedRules.ruleset (renamed from src/api/burn/CustomizedNativeRecommendedRules.ruleset)0
-rw-r--r--src/Directory.vcxproj.props2
-rw-r--r--src/burn/CustomizedNativeRecommendedRules.ruleset8
-rw-r--r--src/burn/engine/registration.cpp15
-rw-r--r--src/burn/test/BurnUnitTest/RegistrationTest.cpp80
-rw-r--r--src/ext/Bal/CustomizedNativeRecommendedRules.ruleset8
-rw-r--r--src/ext/NetFx/CustomizedNativeRecommendedRules.ruleset8
-rw-r--r--src/ext/Util/CustomizedNativeRecommendedRules.ruleset8
-rw-r--r--src/libs/dutil/CustomizedNativeRecommendedRules.ruleset8
-rw-r--r--src/libs/dutil/WixToolset.DUtil/butil.cpp192
-rw-r--r--src/libs/dutil/WixToolset.DUtil/inc/butil.h22
-rw-r--r--src/libs/dutil/WixToolset.DUtil/inc/regutil.h161
-rw-r--r--src/libs/dutil/WixToolset.DUtil/regutil.cpp180
13 files changed, 369 insertions, 323 deletions
diff --git a/src/api/burn/CustomizedNativeRecommendedRules.ruleset b/src/CustomizedNativeRecommendedRules.ruleset
index 142b141c..142b141c 100644
--- a/src/api/burn/CustomizedNativeRecommendedRules.ruleset
+++ b/src/CustomizedNativeRecommendedRules.ruleset
diff --git a/src/Directory.vcxproj.props b/src/Directory.vcxproj.props
index d150cc2e..d0953841 100644
--- a/src/Directory.vcxproj.props
+++ b/src/Directory.vcxproj.props
@@ -20,7 +20,7 @@
20 </PropertyGroup> 20 </PropertyGroup>
21 21
22 <PropertyGroup> 22 <PropertyGroup>
23 <CodeAnalysisRuleSet Condition=" Exists('$(MSBuildThisFileDirectory)CustomizedNativeRecommendedRules.ruleset') ">$(MSBuildThisFileDirectory)CustomizedNativeRecommendedRules.ruleset</CodeAnalysisRuleSet> 23 <CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)CustomizedNativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
24 </PropertyGroup> 24 </PropertyGroup>
25 25
26 <ItemDefinitionGroup> 26 <ItemDefinitionGroup>
diff --git a/src/burn/CustomizedNativeRecommendedRules.ruleset b/src/burn/CustomizedNativeRecommendedRules.ruleset
deleted file mode 100644
index 142b141c..00000000
--- a/src/burn/CustomizedNativeRecommendedRules.ruleset
+++ /dev/null
@@ -1,8 +0,0 @@
1<?xml version="1.0" encoding="utf-8"?>
2<RuleSet Name="Customized Microsoft Native Recommended Rules" Description="Microsoft Native Recommended Rules, -C26812" ToolsVersion="16.0">
3 <Include Path="nativerecommendedrules.ruleset" Action="Default" />
4 <Rules AnalyzerId="Microsoft.Analyzers.NativeCodeAnalysis" RuleNamespace="Microsoft.Rules.Native">
5 <!-- We need C style enums since we support BAs written in C -->
6 <Rule Id="C26812" Action="None" />
7 </Rules>
8</RuleSet> \ No newline at end of file
diff --git a/src/burn/engine/registration.cpp b/src/burn/engine/registration.cpp
index 4088004d..147865fa 100644
--- a/src/burn/engine/registration.cpp
+++ b/src/burn/engine/registration.cpp
@@ -910,7 +910,6 @@ extern "C" HRESULT RegistrationSessionEnd(
910{ 910{
911 HRESULT hr = S_OK; 911 HRESULT hr = S_OK;
912 LPWSTR sczRebootRequiredKey = NULL; 912 LPWSTR sczRebootRequiredKey = NULL;
913 LPWSTR sczVariableKey = NULL;
914 HKEY hkRebootRequired = NULL; 913 HKEY hkRebootRequired = NULL;
915 HKEY hkRegistration = NULL; 914 HKEY hkRegistration = NULL;
916 915
@@ -958,19 +957,8 @@ extern "C" HRESULT RegistrationSessionEnd(
958 957
959 RemoveSoftwareTags(pVariables, &pRegistration->softwareTags); 958 RemoveSoftwareTags(pVariables, &pRegistration->softwareTags);
960 959
961 // build variable registry key path
962 hr = StrAllocFormatted(&sczVariableKey, L"%s\\%s", pRegistration->sczRegistrationKey, REGISTRY_BUNDLE_VARIABLE_KEY);
963 ExitOnFailure(hr, "Failed to build variable registry key path.");
964
965 // Delete registration variable key.
966 hr = RegDelete(pRegistration->hkRoot, sczVariableKey, REG_KEY_DEFAULT, FALSE);
967 if (E_FILENOTFOUND != hr)
968 {
969 ExitOnFailure(hr, "Failed to delete registration variable key: %ls", sczVariableKey);
970 }
971
972 // Delete registration key. 960 // Delete registration key.
973 hr = RegDelete(pRegistration->hkRoot, pRegistration->sczRegistrationKey, REG_KEY_DEFAULT, FALSE); 961 hr = RegDelete(pRegistration->hkRoot, pRegistration->sczRegistrationKey, REG_KEY_DEFAULT, TRUE);
974 if (E_FILENOTFOUND != hr) 962 if (E_FILENOTFOUND != hr)
975 { 963 {
976 ExitOnFailure(hr, "Failed to delete registration key: %ls", pRegistration->sczRegistrationKey); 964 ExitOnFailure(hr, "Failed to delete registration key: %ls", pRegistration->sczRegistrationKey);
@@ -998,7 +986,6 @@ extern "C" HRESULT RegistrationSessionEnd(
998LExit: 986LExit:
999 ReleaseRegKey(hkRegistration); 987 ReleaseRegKey(hkRegistration);
1000 ReleaseRegKey(hkRebootRequired); 988 ReleaseRegKey(hkRebootRequired);
1001 ReleaseStr(sczVariableKey);
1002 ReleaseStr(sczRebootRequiredKey); 989 ReleaseStr(sczRebootRequiredKey);
1003 990
1004 return hr; 991 return hr;
diff --git a/src/burn/test/BurnUnitTest/RegistrationTest.cpp b/src/burn/test/BurnUnitTest/RegistrationTest.cpp
index 298d4631..a8319bb2 100644
--- a/src/burn/test/BurnUnitTest/RegistrationTest.cpp
+++ b/src/burn/test/BurnUnitTest/RegistrationTest.cpp
@@ -4,16 +4,16 @@
4 4
5 5
6#define ROOT_PATH L"SOFTWARE\\WiX_Burn_UnitTest" 6#define ROOT_PATH L"SOFTWARE\\WiX_Burn_UnitTest"
7#define HKLM_PATH L"SOFTWARE\\WiX_Burn_UnitTest\\HKLM" 7#define HKLM_PATH ROOT_PATH L"\\HKLM"
8#define HKCU_PATH L"SOFTWARE\\WiX_Burn_UnitTest\\HKCU" 8#define HKCU_PATH ROOT_PATH L"\\HKCU"
9#define REGISTRY_UNINSTALL_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" 9#define REGISTRY_UNINSTALL_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
10#define REGISTRY_RUN_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce" 10#define REGISTRY_RUN_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"
11#define TEST_BUNDLE_ID L"{D54F896D-1952-43e6-9C67-B5652240618C}" 11#define TEST_BUNDLE_ID L"{D54F896D-1952-43E6-9C67-B5652240618C}"
12#define TEST_BUNDLE_UPGRADE_CODE L"{89FDAE1F-8CC1-48B9-B930-3945E0D3E7F0}" 12#define TEST_BUNDLE_UPGRADE_CODE L"{89FDAE1F-8CC1-48B9-B930-3945E0D3E7F0}"
13 13
14#define TEST_UNINSTALL_KEY L"HKEY_CURRENT_USER\\" HKCU_PATH L"\\" REGISTRY_UNINSTALL_KEY L"\\{D54F896D-1952-43e6-9C67-B5652240618C}" 14#define TEST_UNINSTALL_KEY L"HKEY_CURRENT_USER\\" HKCU_PATH L"\\" REGISTRY_UNINSTALL_KEY L"\\" TEST_BUNDLE_ID
15#define TEST_RUN_KEY L"HKEY_CURRENT_USER\\" HKCU_PATH L"\\" REGISTRY_RUN_KEY 15#define TEST_RUN_KEY L"HKEY_CURRENT_USER\\" HKCU_PATH L"\\" REGISTRY_RUN_KEY
16#define TEST_VARIABLE_KEY L"HKEY_CURRENT_USER\\" HKCU_PATH L"\\" REGISTRY_UNINSTALL_KEY L"\\{D54F896D-1952-43e6-9C67-B5652240618C}\\variables" 16#define TEST_VARIABLE_KEY L"HKEY_CURRENT_USER\\" HKCU_PATH L"\\" REGISTRY_UNINSTALL_KEY L"\\" TEST_BUNDLE_ID L"\\variables"
17 17
18 18
19static LSTATUS APIENTRY RegistrationTest_RegCreateKeyExW( 19static LSTATUS APIENTRY RegistrationTest_RegCreateKeyExW(
@@ -75,7 +75,7 @@ namespace Bootstrapper
75 BURN_REGISTRATION registration = { }; 75 BURN_REGISTRATION registration = { };
76 BURN_LOGGING logging = { }; 76 BURN_LOGGING logging = { };
77 BURN_PACKAGES packages = { }; 77 BURN_PACKAGES packages = { };
78 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}")); 78 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
79 79
80 try 80 try
81 { 81 {
@@ -91,7 +91,7 @@ namespace Bootstrapper
91 L" <UX>" 91 L" <UX>"
92 L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />" 92 L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />"
93 L" </UX>" 93 L" </UX>"
94 L" <Registration Id='{D54F896D-1952-43e6-9C67-B5652240618C}' UpgradeCode='{D54F896D-1952-43e6-9C67-B5652240618C}' Tag='foo' ProviderKey='foo' Version='1.0.0.0' ExecutableName='setup.exe' PerMachine='no'>" 94 L" <Registration Id='{D54F896D-1952-43E6-9C67-B5652240618C}' UpgradeCode='{89FDAE1F-8CC1-48B9-B930-3945E0D3E7F0}' Tag='foo' ProviderKey='foo' Version='1.0.0.0' ExecutableName='setup.exe' PerMachine='no'>"
95 L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='RegisterBasicTest' DisplayVersion='1.0.0.0' />" 95 L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='RegisterBasicTest' DisplayVersion='1.0.0.0' />"
96 L" </Registration>" 96 L" </Registration>"
97 L"</Bundle>"; 97 L"</Bundle>";
@@ -123,7 +123,7 @@ namespace Bootstrapper
123 Assert::True(File::Exists(Path::Combine(cacheDirectory, gcnew String(L"setup.exe")))); 123 Assert::True(File::Exists(Path::Combine(cacheDirectory, gcnew String(L"setup.exe"))));
124 124
125 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 125 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
126 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)(Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr))); 126 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)(Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)));
127 127
128 // end session 128 // end session
129 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 129 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
@@ -133,7 +133,7 @@ namespace Bootstrapper
133 Assert::False(Directory::Exists(cacheDirectory)); 133 Assert::False(Directory::Exists(cacheDirectory));
134 134
135 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 135 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
136 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); 136 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
137 } 137 }
138 finally 138 finally
139 { 139 {
@@ -165,7 +165,7 @@ namespace Bootstrapper
165 BURN_REGISTRATION registration = { }; 165 BURN_REGISTRATION registration = { };
166 BURN_LOGGING logging = { }; 166 BURN_LOGGING logging = { };
167 BURN_PACKAGES packages = { }; 167 BURN_PACKAGES packages = { };
168 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}")); 168 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
169 try 169 try
170 { 170 {
171 // set mock API's 171 // set mock API's
@@ -180,7 +180,7 @@ namespace Bootstrapper
180 L" <UX>" 180 L" <UX>"
181 L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />" 181 L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />"
182 L" </UX>" 182 L" </UX>"
183 L" <Registration Id='{D54F896D-1952-43e6-9C67-B5652240618C}' UpgradeCode='{D54F896D-1952-43e6-9C67-B5652240618C}' Tag='foo' ProviderKey='foo' Version='1.0.0.0' ExecutableName='setup.exe' PerMachine='no'>" 183 L" <Registration Id='{D54F896D-1952-43E6-9C67-B5652240618C}' UpgradeCode='{89FDAE1F-8CC1-48B9-B930-3945E0D3E7F0}' Tag='foo' ProviderKey='foo' Version='1.0.0.0' ExecutableName='setup.exe' PerMachine='no'>"
184 L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='Product1' InProgressDisplayName='Product1 Installation' DisplayVersion='1.0.0.0' />" 184 L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='Product1' InProgressDisplayName='Product1 Installation' DisplayVersion='1.0.0.0' />"
185 L" </Registration>" 185 L" </Registration>"
186 L"</Bundle>"; 186 L"</Bundle>";
@@ -214,7 +214,7 @@ namespace Bootstrapper
214 // verify that registration was created 214 // verify that registration was created
215 Assert::Equal<String^>(gcnew String(L"Product1 Installation"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayName"), nullptr)); 215 Assert::Equal<String^>(gcnew String(L"Product1 Installation"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayName"), nullptr));
216 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 216 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
217 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); 217 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
218 218
219 // complete registration 219 // complete registration
220 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 220 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
@@ -223,7 +223,7 @@ namespace Bootstrapper
223 // verify that registration was updated 223 // verify that registration was updated
224 Assert::Equal(Int32(BURN_RESUME_MODE_ARP), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 224 Assert::Equal(Int32(BURN_RESUME_MODE_ARP), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
225 Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); 225 Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr));
226 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); 226 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
227 227
228 // 228 //
229 // uninstall 229 // uninstall
@@ -236,7 +236,7 @@ namespace Bootstrapper
236 // verify that registration was updated 236 // verify that registration was updated
237 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 237 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
238 Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); 238 Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr));
239 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); 239 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
240 240
241 // delete registration 241 // delete registration
242 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 242 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
@@ -245,7 +245,7 @@ namespace Bootstrapper
245 // verify that registration was removed 245 // verify that registration was removed
246 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 246 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
247 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); 247 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr));
248 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); 248 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
249 } 249 }
250 finally 250 finally
251 { 251 {
@@ -277,7 +277,7 @@ namespace Bootstrapper
277 BURN_REGISTRATION registration = { }; 277 BURN_REGISTRATION registration = { };
278 BURN_LOGGING logging = { }; 278 BURN_LOGGING logging = { };
279 BURN_PACKAGES packages = { }; 279 BURN_PACKAGES packages = { };
280 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}")); 280 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
281 try 281 try
282 { 282 {
283 // set mock API's 283 // set mock API's
@@ -292,7 +292,7 @@ namespace Bootstrapper
292 L" <UX>" 292 L" <UX>"
293 L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />" 293 L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />"
294 L" </UX>" 294 L" </UX>"
295 L" <Registration Id='{D54F896D-1952-43e6-9C67-B5652240618C}' UpgradeCode='{D54F896D-1952-43e6-9C67-B5652240618C}' Tag='foo' ProviderKey='bar' Version='1.0.0.0' ExecutableName='setup.exe' PerMachine='no'>" 295 L" <Registration Id='{D54F896D-1952-43E6-9C67-B5652240618C}' UpgradeCode='{89FDAE1F-8CC1-48B9-B930-3945E0D3E7F0}' Tag='foo' ProviderKey='bar' Version='1.0.0.0' ExecutableName='setup.exe' PerMachine='no'>"
296 L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='Product1' DisplayVersion='1.0.0.0' />" 296 L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='Product1' DisplayVersion='1.0.0.0' />"
297 L" </Registration>" 297 L" </Registration>"
298 L"</Bundle>"; 298 L"</Bundle>";
@@ -325,7 +325,7 @@ namespace Bootstrapper
325 325
326 // verify that registration was created 326 // verify that registration was created
327 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 327 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
328 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); 328 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
329 329
330 // complete registration 330 // complete registration
331 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL); 331 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL);
@@ -355,7 +355,7 @@ namespace Bootstrapper
355 // verify that registration was removed 355 // verify that registration was removed
356 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 356 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
357 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); 357 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr));
358 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); 358 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
359 } 359 }
360 finally 360 finally
361 { 361 {
@@ -387,7 +387,7 @@ namespace Bootstrapper
387 BURN_REGISTRATION registration = { }; 387 BURN_REGISTRATION registration = { };
388 BURN_LOGGING logging = { }; 388 BURN_LOGGING logging = { };
389 BURN_PACKAGES packages = { }; 389 BURN_PACKAGES packages = { };
390 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}")); 390 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
391 try 391 try
392 { 392 {
393 // set mock API's 393 // set mock API's
@@ -402,7 +402,7 @@ namespace Bootstrapper
402 L" <UX UxDllPayloadId='ux.dll'>" 402 L" <UX UxDllPayloadId='ux.dll'>"
403 L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />" 403 L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />"
404 L" </UX>" 404 L" </UX>"
405 L" <Registration Id='{D54F896D-1952-43e6-9C67-B5652240618C}' UpgradeCode='{D54F896D-1952-43e6-9C67-B5652240618C}' Tag='foo' ProviderKey='foo' Version='1.0.0.0' ExecutableName='setup.exe' PerMachine='no'>" 405 L" <Registration Id='{D54F896D-1952-43E6-9C67-B5652240618C}' UpgradeCode='{89FDAE1F-8CC1-48B9-B930-3945E0D3E7F0}' Tag='foo' ProviderKey='foo' Version='1.0.0.0' ExecutableName='setup.exe' PerMachine='no'>"
406 L" <Arp Register='yes' DisplayName='DisplayName1' DisplayVersion='1.2.3.4' Publisher='Publisher1' HelpLink='http://www.microsoft.com/help'" 406 L" <Arp Register='yes' DisplayName='DisplayName1' DisplayVersion='1.2.3.4' Publisher='Publisher1' HelpLink='http://www.microsoft.com/help'"
407 L" HelpTelephone='555-555-5555' AboutUrl='http://www.microsoft.com/about' UpdateUrl='http://www.microsoft.com/update'" 407 L" HelpTelephone='555-555-5555' AboutUrl='http://www.microsoft.com/about' UpdateUrl='http://www.microsoft.com/update'"
408 L" Comments='Comments1' Contact='Contact1' DisableModify='yes' DisableRemove='yes' />" 408 L" Comments='Comments1' Contact='Contact1' DisableModify='yes' DisableRemove='yes' />"
@@ -437,7 +437,7 @@ namespace Bootstrapper
437 437
438 // verify that registration was created 438 // verify that registration was created
439 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 439 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
440 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); 440 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
441 441
442 // finish registration 442 // finish registration
443 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL); 443 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL);
@@ -446,7 +446,7 @@ namespace Bootstrapper
446 // verify that registration was updated 446 // verify that registration was updated
447 Assert::Equal(Int32(BURN_RESUME_MODE_ARP), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 447 Assert::Equal(Int32(BURN_RESUME_MODE_ARP), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
448 Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); 448 Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr));
449 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); 449 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
450 450
451 Assert::Equal<String^>(gcnew String(L"DisplayName1"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayName"), nullptr)); 451 Assert::Equal<String^>(gcnew String(L"DisplayName1"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayName"), nullptr));
452 Assert::Equal<String^>(gcnew String(L"1.2.3.4"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayVersion"), nullptr)); 452 Assert::Equal<String^>(gcnew String(L"1.2.3.4"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayVersion"), nullptr));
@@ -470,7 +470,7 @@ namespace Bootstrapper
470 470
471 // verify that registration was updated 471 // verify that registration was updated
472 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 472 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
473 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); 473 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
474 474
475 // delete registration 475 // delete registration
476 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 476 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
@@ -479,7 +479,7 @@ namespace Bootstrapper
479 // verify that registration was removed 479 // verify that registration was removed
480 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 480 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
481 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); 481 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr));
482 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); 482 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
483 } 483 }
484 finally 484 finally
485 { 485 {
@@ -517,7 +517,7 @@ namespace Bootstrapper
517 BYTE* pbBuffer = NULL; 517 BYTE* pbBuffer = NULL;
518 SIZE_T cbBuffer = 0; 518 SIZE_T cbBuffer = 0;
519 519
520 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}")); 520 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
521 try 521 try
522 { 522 {
523 // set mock API's 523 // set mock API's
@@ -532,8 +532,8 @@ namespace Bootstrapper
532 L" <UX>" 532 L" <UX>"
533 L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />" 533 L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />"
534 L" </UX>" 534 L" </UX>"
535 L" <RelatedBundle Id='" TEST_BUNDLE_UPGRADE_CODE "' Action='Upgrade' />" 535 L" <RelatedBundle Id='" TEST_BUNDLE_UPGRADE_CODE L"' Action='Upgrade' />"
536 L" <Registration Id='" TEST_BUNDLE_ID "' Tag='foo' ProviderKey='" TEST_BUNDLE_ID "' Version='1.0.0.0' ExecutableName='setup.exe' PerMachine='no'>" 536 L" <Registration Id='" TEST_BUNDLE_ID L"' Tag='foo' ProviderKey='" TEST_BUNDLE_ID L"' Version='1.0.0.0' ExecutableName='setup.exe' PerMachine='no'>"
537 L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='RegisterBasicTest' DisplayVersion='1.0.0.0' />" 537 L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='RegisterBasicTest' DisplayVersion='1.0.0.0' />"
538 L" </Registration>" 538 L" </Registration>"
539 L" <Variable Id='MyBurnVariable1' Type='numeric' Value='0' Hidden='no' Persisted='yes' />" 539 L" <Variable Id='MyBurnVariable1' Type='numeric' Value='0' Hidden='no' Persisted='yes' />"
@@ -585,6 +585,7 @@ namespace Bootstrapper
585 585
586 ReleaseNullBuffer(pbBuffer); 586 ReleaseNullBuffer(pbBuffer);
587 cbBuffer = 0; 587 cbBuffer = 0;
588
588 // Verify the variables exist 589 // Verify the variables exist
589 Assert::Equal<String^>(gcnew String(L"42"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable1"), nullptr)); 590 Assert::Equal<String^>(gcnew String(L"42"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable1"), nullptr));
590 Assert::Equal<String^>(gcnew String(L"bar"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable2"), nullptr)); 591 Assert::Equal<String^>(gcnew String(L"bar"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable2"), nullptr));
@@ -596,12 +597,14 @@ namespace Bootstrapper
596 // Verify we can find ourself via the UpgradeCode 597 // Verify we can find ourself via the UpgradeCode
597 hr = BundleEnumRelatedBundle(TEST_BUNDLE_UPGRADE_CODE, BUNDLE_INSTALL_CONTEXT_USER, &dwRelatedBundleIndex, sczRelatedBundleId); 598 hr = BundleEnumRelatedBundle(TEST_BUNDLE_UPGRADE_CODE, BUNDLE_INSTALL_CONTEXT_USER, &dwRelatedBundleIndex, sczRelatedBundleId);
598 TestThrowOnFailure(hr, L"Failed to enumerate related bundle."); 599 TestThrowOnFailure(hr, L"Failed to enumerate related bundle.");
599 Assert::Equal<String^>(gcnew String(TEST_BUNDLE_ID), gcnew String(sczRelatedBundleId)); 600
601 NativeAssert::StringEqual(TEST_BUNDLE_ID, sczRelatedBundleId);
600 602
601 // Verify we can read the bundle variables via the API 603 // Verify we can read the bundle variables via the API
602 hr = BundleGetBundleVariable(TEST_BUNDLE_ID, L"MyBurnVariable1", &sczValue); 604 hr = BundleGetBundleVariable(TEST_BUNDLE_ID, L"MyBurnVariable1", &sczValue);
603 TestThrowOnFailure(hr, L"Failed to read MyBurnVariable1."); 605 TestThrowOnFailure(hr, L"Failed to read MyBurnVariable1.");
604 Assert::Equal<String^>(gcnew String(L"42"), gcnew String(sczValue)); 606
607 NativeAssert::StringEqual(L"42", sczValue);
605 608
606 // end session 609 // end session
607 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 610 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
@@ -626,7 +629,7 @@ namespace Bootstrapper
626 } 629 }
627 } 630 }
628 631
629 [Fact]//(Skip = "Currently fails")] 632 [Fact]
630 void ResumeTest() 633 void ResumeTest()
631 { 634 {
632 HRESULT hr = S_OK; 635 HRESULT hr = S_OK;
@@ -643,7 +646,7 @@ namespace Bootstrapper
643 BYTE* pbBuffer = NULL; 646 BYTE* pbBuffer = NULL;
644 SIZE_T cbBuffer = 0; 647 SIZE_T cbBuffer = 0;
645 SIZE_T piBuffer = 0; 648 SIZE_T piBuffer = 0;
646 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}")); 649 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
647 try 650 try
648 { 651 {
649 // set mock API's 652 // set mock API's
@@ -658,7 +661,7 @@ namespace Bootstrapper
658 L" <UX>" 661 L" <UX>"
659 L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />" 662 L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />"
660 L" </UX>" 663 L" </UX>"
661 L" <Registration Id='{D54F896D-1952-43e6-9C67-B5652240618C}' UpgradeCode='{D54F896D-1952-43e6-9C67-B5652240618C}' Tag='foo' ProviderKey='foo' Version='1.0.0.0' ExecutableName='setup.exe' PerMachine='no'>" 664 L" <Registration Id='{D54F896D-1952-43E6-9C67-B5652240618C}' UpgradeCode='{89FDAE1F-8CC1-48B9-B930-3945E0D3E7F0}' Tag='foo' ProviderKey='foo' Version='1.0.0.0' ExecutableName='setup.exe' PerMachine='no'>"
662 L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='RegisterBasicTest' DisplayVersion='1.0.0.0' />" 665 L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='RegisterBasicTest' DisplayVersion='1.0.0.0' />"
663 L" </Registration>" 666 L" </Registration>"
664 L" <Variable Id='MyBurnVariable1' Type='numeric' Value='0' Hidden='no' Persisted='yes' />" 667 L" <Variable Id='MyBurnVariable1' Type='numeric' Value='0' Hidden='no' Persisted='yes' />"
@@ -715,6 +718,7 @@ namespace Bootstrapper
715 718
716 ReleaseNullBuffer(pbBuffer); 719 ReleaseNullBuffer(pbBuffer);
717 cbBuffer = 0; 720 cbBuffer = 0;
721
718 // Verify the variables exist 722 // Verify the variables exist
719 Assert::Equal<String^>(gcnew String(L"42"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable1"), nullptr)); 723 Assert::Equal<String^>(gcnew String(L"42"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable1"), nullptr));
720 Assert::Equal<String^>(gcnew String(L"bar"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable2"), nullptr)); 724 Assert::Equal<String^>(gcnew String(L"bar"), (String^)Registry::GetValue(gcnew String(TEST_VARIABLE_KEY), gcnew String(L"MyBurnVariable2"), nullptr));
@@ -723,7 +727,8 @@ namespace Bootstrapper
723 727
724 hr = BundleGetBundleVariable(TEST_BUNDLE_ID, L"MyBurnVariable1", &sczValue); 728 hr = BundleGetBundleVariable(TEST_BUNDLE_ID, L"MyBurnVariable1", &sczValue);
725 TestThrowOnFailure(hr, L"Failed to read MyBurnVariable1."); 729 TestThrowOnFailure(hr, L"Failed to read MyBurnVariable1.");
726 Assert::Equal<String^>(gcnew String(L"42"), gcnew String(sczValue)); 730
731 NativeAssert::StringEqual(L"42", sczValue);
727 732
728 // read interrupted resume type 733 // read interrupted resume type
729 hr = RegistrationDetectResumeType(&registration, &resumeType); 734 hr = RegistrationDetectResumeType(&registration, &resumeType);
@@ -736,7 +741,7 @@ namespace Bootstrapper
736 TestThrowOnFailure(hr, L"Failed to suspend session."); 741 TestThrowOnFailure(hr, L"Failed to suspend session.");
737 742
738 // verify that run key was removed 743 // verify that run key was removed
739 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); 744 Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
740 745
741 // read suspend resume type 746 // read suspend resume type
742 hr = RegistrationDetectResumeType(&registration, &resumeType); 747 hr = RegistrationDetectResumeType(&registration, &resumeType);
@@ -751,15 +756,12 @@ namespace Bootstrapper
751 hr = VariableDeserialize(&variables, TRUE, pbBuffer, cbBuffer, &piBuffer); 756 hr = VariableDeserialize(&variables, TRUE, pbBuffer, cbBuffer, &piBuffer);
752 TestThrowOnFailure(hr, L"Failed to deserialize variables."); 757 TestThrowOnFailure(hr, L"Failed to deserialize variables.");
753 758
754 //Assert::Equal((SIZE_T)sizeof(rgbData), cbBuffer);
755 //Assert::True(0 == memcmp(pbBuffer, rgbData, sizeof(rgbData)));
756
757 // write active resume mode 759 // write active resume mode
758 hr = RegistrationSessionResume(&registration, &variables, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 760 hr = RegistrationSessionResume(&registration, &variables, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
759 TestThrowOnFailure(hr, L"Failed to write active resume mode."); 761 TestThrowOnFailure(hr, L"Failed to write active resume mode.");
760 762
761 // verify that run key was put back 763 // verify that run key was put back
762 Assert::NotEqual((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); 764 Assert::NotEqual((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
763 765
764 // end session 766 // end session
765 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 767 hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
diff --git a/src/ext/Bal/CustomizedNativeRecommendedRules.ruleset b/src/ext/Bal/CustomizedNativeRecommendedRules.ruleset
deleted file mode 100644
index 142b141c..00000000
--- a/src/ext/Bal/CustomizedNativeRecommendedRules.ruleset
+++ /dev/null
@@ -1,8 +0,0 @@
1<?xml version="1.0" encoding="utf-8"?>
2<RuleSet Name="Customized Microsoft Native Recommended Rules" Description="Microsoft Native Recommended Rules, -C26812" ToolsVersion="16.0">
3 <Include Path="nativerecommendedrules.ruleset" Action="Default" />
4 <Rules AnalyzerId="Microsoft.Analyzers.NativeCodeAnalysis" RuleNamespace="Microsoft.Rules.Native">
5 <!-- We need C style enums since we support BAs written in C -->
6 <Rule Id="C26812" Action="None" />
7 </Rules>
8</RuleSet> \ No newline at end of file
diff --git a/src/ext/NetFx/CustomizedNativeRecommendedRules.ruleset b/src/ext/NetFx/CustomizedNativeRecommendedRules.ruleset
deleted file mode 100644
index 142b141c..00000000
--- a/src/ext/NetFx/CustomizedNativeRecommendedRules.ruleset
+++ /dev/null
@@ -1,8 +0,0 @@
1<?xml version="1.0" encoding="utf-8"?>
2<RuleSet Name="Customized Microsoft Native Recommended Rules" Description="Microsoft Native Recommended Rules, -C26812" ToolsVersion="16.0">
3 <Include Path="nativerecommendedrules.ruleset" Action="Default" />
4 <Rules AnalyzerId="Microsoft.Analyzers.NativeCodeAnalysis" RuleNamespace="Microsoft.Rules.Native">
5 <!-- We need C style enums since we support BAs written in C -->
6 <Rule Id="C26812" Action="None" />
7 </Rules>
8</RuleSet> \ No newline at end of file
diff --git a/src/ext/Util/CustomizedNativeRecommendedRules.ruleset b/src/ext/Util/CustomizedNativeRecommendedRules.ruleset
deleted file mode 100644
index 142b141c..00000000
--- a/src/ext/Util/CustomizedNativeRecommendedRules.ruleset
+++ /dev/null
@@ -1,8 +0,0 @@
1<?xml version="1.0" encoding="utf-8"?>
2<RuleSet Name="Customized Microsoft Native Recommended Rules" Description="Microsoft Native Recommended Rules, -C26812" ToolsVersion="16.0">
3 <Include Path="nativerecommendedrules.ruleset" Action="Default" />
4 <Rules AnalyzerId="Microsoft.Analyzers.NativeCodeAnalysis" RuleNamespace="Microsoft.Rules.Native">
5 <!-- We need C style enums since we support BAs written in C -->
6 <Rule Id="C26812" Action="None" />
7 </Rules>
8</RuleSet> \ No newline at end of file
diff --git a/src/libs/dutil/CustomizedNativeRecommendedRules.ruleset b/src/libs/dutil/CustomizedNativeRecommendedRules.ruleset
deleted file mode 100644
index 142b141c..00000000
--- a/src/libs/dutil/CustomizedNativeRecommendedRules.ruleset
+++ /dev/null
@@ -1,8 +0,0 @@
1<?xml version="1.0" encoding="utf-8"?>
2<RuleSet Name="Customized Microsoft Native Recommended Rules" Description="Microsoft Native Recommended Rules, -C26812" ToolsVersion="16.0">
3 <Include Path="nativerecommendedrules.ruleset" Action="Default" />
4 <Rules AnalyzerId="Microsoft.Analyzers.NativeCodeAnalysis" RuleNamespace="Microsoft.Rules.Native">
5 <!-- We need C style enums since we support BAs written in C -->
6 <Rule Id="C26812" Action="None" />
7 </Rules>
8</RuleSet> \ No newline at end of file
diff --git a/src/libs/dutil/WixToolset.DUtil/butil.cpp b/src/libs/dutil/WixToolset.DUtil/butil.cpp
index cda2a658..ca73f0c3 100644
--- a/src/libs/dutil/WixToolset.DUtil/butil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/butil.cpp
@@ -8,6 +8,7 @@
8#define ButilExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_BUTIL, x, s, __VA_ARGS__) 8#define ButilExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_BUTIL, x, s, __VA_ARGS__)
9#define ButilExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_BUTIL, x, s, __VA_ARGS__) 9#define ButilExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_BUTIL, x, s, __VA_ARGS__)
10#define ButilExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_BUTIL, x, s, __VA_ARGS__) 10#define ButilExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_BUTIL, x, s, __VA_ARGS__)
11#define ButilExitWithRootFailure(x, e, s, ...) ExitWithRootFailureSource(DUTIL_SOURCE_BUTIL, x, e, s, __VA_ARGS__)
11#define ButilExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_BUTIL, x, s, __VA_ARGS__) 12#define ButilExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_BUTIL, x, s, __VA_ARGS__)
12#define ButilExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_BUTIL, p, x, e, s, __VA_ARGS__) 13#define ButilExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_BUTIL, p, x, e, s, __VA_ARGS__)
13#define ButilExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_BUTIL, p, x, s, __VA_ARGS__) 14#define ButilExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_BUTIL, p, x, s, __VA_ARGS__)
@@ -22,8 +23,30 @@ const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE = L"BundleUpgrade
22const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_BUNDLE_PROVIDER_KEY = L"BundleProviderKey"; 23const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_BUNDLE_PROVIDER_KEY = L"BundleProviderKey";
23const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_BUNDLE_VARIABLE_KEY = L"variables"; 24const LPCWSTR BUNDLE_REGISTRATION_REGISTRY_BUNDLE_VARIABLE_KEY = L"variables";
24 25
26enum INTERNAL_BUNDLE_STATUS
27{
28 INTERNAL_BUNDLE_STATUS_SUCCESS,
29 INTERNAL_BUNDLE_STATUS_UNKNOWN_BUNDLE,
30 INTERNAL_BUNDLE_STATUS_UNKNOWN_PROPERTY,
31};
32
25// Forward declarations. 33// Forward declarations.
26/******************************************************************** 34/********************************************************************
35LocateAndQueryBundleValue - Locates the requested key for the bundle,
36 then queries the registry type for requested value.
37
38NOTE: caller is responsible for closing key
39********************************************************************/
40static HRESULT LocateAndQueryBundleValue(
41 __in_z LPCWSTR wzBundleId,
42 __in_opt LPCWSTR wzSubKey,
43 __in LPCWSTR wzValueName,
44 __inout HKEY* phKey,
45 __inout DWORD* pdwType,
46 __out INTERNAL_BUNDLE_STATUS* pStatus
47 );
48
49/********************************************************************
27OpenBundleKey - Opens the bundle uninstallation key for a given bundle 50OpenBundleKey - Opens the bundle uninstallation key for a given bundle
28 51
29NOTE: caller is responsible for closing key 52NOTE: caller is responsible for closing key
@@ -31,43 +54,44 @@ NOTE: caller is responsible for closing key
31static HRESULT OpenBundleKey( 54static HRESULT OpenBundleKey(
32 __in_z LPCWSTR wzBundleId, 55 __in_z LPCWSTR wzBundleId,
33 __in BUNDLE_INSTALL_CONTEXT context, 56 __in BUNDLE_INSTALL_CONTEXT context,
34 __in_opt LPCWSTR szSubKey, 57 __in_opt LPCWSTR wzSubKey,
35 __inout HKEY* key); 58 __inout HKEY* phKey
59 );
36 60
37/******************************************************************** 61DAPI_(HRESULT) BundleGetBundleInfo(
38BundleGetBundleInfo - Read the registration data for a gven bundle 62 __in_z LPCWSTR wzBundleId,
39********************************************************************/ 63 __in_z LPCWSTR wzAttribute,
40extern "C" HRESULT DAPI BundleGetBundleInfo( 64 __out_ecount_opt(*pcchValueBuf) LPWSTR lpValueBuf,
41 __in_z LPCWSTR wzBundleId, 65 __inout_opt LPDWORD pcchValueBuf
42 __in_z LPCWSTR wzAttribute, 66 )
43 __out_ecount_opt(*pcchValueBuf) LPWSTR lpValueBuf,
44 __inout_opt LPDWORD pcchValueBuf
45 )
46{ 67{
47 Assert(wzBundleId && wzAttribute); 68 Assert(wzBundleId && wzAttribute);
48 69
49 HRESULT hr = S_OK; 70 HRESULT hr = S_OK;
50 LPWSTR sczValue = NULL; 71 LPWSTR sczValue = NULL;
51 HKEY hkBundle = NULL; 72 HKEY hkBundle = NULL;
73 INTERNAL_BUNDLE_STATUS status = INTERNAL_BUNDLE_STATUS_SUCCESS;
52 DWORD cchSource = 0; 74 DWORD cchSource = 0;
53 DWORD dwType = 0; 75 DWORD dwType = 0;
54 DWORD dwValue = 0; 76 DWORD dwValue = 0;
55 77
56 if ((lpValueBuf && !pcchValueBuf) || !wzBundleId || !wzAttribute) 78 if ((lpValueBuf && !pcchValueBuf) || !wzBundleId || !wzAttribute)
57 { 79 {
58 ButilExitOnFailure(hr = E_INVALIDARG, "An invalid parameter was passed to the function."); 80 ButilExitWithRootFailure(hr, E_INVALIDARG, "An invalid parameter was passed to the function.");
59 } 81 }
60 82
61 if (FAILED(hr = OpenBundleKey(wzBundleId, BUNDLE_INSTALL_CONTEXT_MACHINE, NULL, &hkBundle)) && 83 hr = LocateAndQueryBundleValue(wzBundleId, NULL, wzAttribute, &hkBundle, &dwType, &status);
62 FAILED(hr = OpenBundleKey(wzBundleId, BUNDLE_INSTALL_CONTEXT_USER, NULL, &hkBundle))) 84 ButilExitOnFailure(hr, "Failed to locate and query bundle attribute.");
85
86 switch (status)
63 { 87 {
64 ButilExitOnFailure(E_FILENOTFOUND == hr ? HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT) : hr, "Failed to locate bundle uninstall key path."); 88 case INTERNAL_BUNDLE_STATUS_UNKNOWN_BUNDLE:
89 ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT));
90 case INTERNAL_BUNDLE_STATUS_UNKNOWN_PROPERTY:
91 // If the bundle doesn't have the property defined, return ERROR_UNKNOWN_PROPERTY
92 ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY));
65 } 93 }
66 94
67 // If the bundle doesn't have the property defined, return ERROR_UNKNOWN_PROPERTY
68 hr = RegGetType(hkBundle, wzAttribute, &dwType);
69 ButilExitOnFailure(E_FILENOTFOUND == hr ? HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY) : hr, "Failed to locate bundle property.");
70
71 switch (dwType) 95 switch (dwType)
72 { 96 {
73 case REG_SZ: 97 case REG_SZ:
@@ -82,12 +106,11 @@ extern "C" HRESULT DAPI BundleGetBundleInfo(
82 ButilExitOnFailure(hr, "Failed to format dword property as string."); 106 ButilExitOnFailure(hr, "Failed to format dword property as string.");
83 break; 107 break;
84 default: 108 default:
85 ButilExitOnFailure(hr = E_NOTIMPL, "Reading bundle info of type 0x%x not implemented.", dwType); 109 ButilExitWithRootFailure(hr, E_NOTIMPL, "Reading bundle info of type 0x%x not implemented.", dwType);
86
87 } 110 }
88 111
89 hr = ::StringCchLengthW(sczValue, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchSource)); 112 hr = ::StringCchLengthW(sczValue, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchSource));
90 ButilExitOnFailure(hr, "Failed to calculate length of string"); 113 ButilExitOnRootFailure(hr, "Failed to calculate length of string.");
91 114
92 if (lpValueBuf) 115 if (lpValueBuf)
93 { 116 {
@@ -95,11 +118,11 @@ extern "C" HRESULT DAPI BundleGetBundleInfo(
95 if (*pcchValueBuf <= cchSource) 118 if (*pcchValueBuf <= cchSource)
96 { 119 {
97 *pcchValueBuf = ++cchSource; 120 *pcchValueBuf = ++cchSource;
98 ButilExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_MORE_DATA), "A buffer is too small to hold the requested data."); 121 ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_MORE_DATA));
99 } 122 }
100 123
101 hr = ::StringCchCatNExW(lpValueBuf, *pcchValueBuf, sczValue, cchSource, NULL, NULL, STRSAFE_FILL_BEHIND_NULL); 124 hr = ::StringCchCatNExW(lpValueBuf, *pcchValueBuf, sczValue, cchSource, NULL, NULL, STRSAFE_FILL_BEHIND_NULL);
102 ButilExitOnFailure(hr, "Failed to copy the property value to the output buffer."); 125 ButilExitOnRootFailure(hr, "Failed to copy the property value to the output buffer.");
103 126
104 *pcchValueBuf = cchSource++; 127 *pcchValueBuf = cchSource++;
105 } 128 }
@@ -111,10 +134,8 @@ LExit:
111 return hr; 134 return hr;
112} 135}
113 136
114/********************************************************************
115********************************************************************/
116 137
117extern "C" HRESULT DAPI BundleEnumRelatedBundle( 138DAPI_(HRESULT) BundleEnumRelatedBundle(
118 __in_z LPCWSTR wzUpgradeCode, 139 __in_z LPCWSTR wzUpgradeCode,
119 __in BUNDLE_INSTALL_CONTEXT context, 140 __in BUNDLE_INSTALL_CONTEXT context,
120 __inout PDWORD pdwStartIndex, 141 __inout PDWORD pdwStartIndex,
@@ -170,6 +191,7 @@ extern "C" HRESULT DAPI BundleEnumRelatedBundle(
170 case REG_SZ: 191 case REG_SZ:
171 hr = RegReadString(hkBundle, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE, &sczValue); 192 hr = RegReadString(hkBundle, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE, &sczValue);
172 ButilExitOnFailure(hr, "Failed to read BundleUpgradeCode string property."); 193 ButilExitOnFailure(hr, "Failed to read BundleUpgradeCode string property.");
194
173 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, sczValue, -1, wzUpgradeCode, -1)) 195 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, sczValue, -1, wzUpgradeCode, -1))
174 { 196 {
175 *pdwStartIndex = dwIndex; 197 *pdwStartIndex = dwIndex;
@@ -202,8 +224,7 @@ extern "C" HRESULT DAPI BundleEnumRelatedBundle(
202 break; 224 break;
203 225
204 default: 226 default:
205 ButilExitOnFailure(hr = E_NOTIMPL, "BundleUpgradeCode of type 0x%x not implemented.", dwType); 227 ButilExitWithRootFailure(hr, E_NOTIMPL, "BundleUpgradeCode of type 0x%x not implemented.", dwType);
206
207 } 228 }
208 229
209 if (fUpgradeCodeFound) 230 if (fUpgradeCodeFound)
@@ -211,10 +232,10 @@ extern "C" HRESULT DAPI BundleEnumRelatedBundle(
211 if (lpBundleIdBuf) 232 if (lpBundleIdBuf)
212 { 233 {
213 hr = ::StringCchLengthW(sczUninstallSubKey, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchUninstallSubKey)); 234 hr = ::StringCchLengthW(sczUninstallSubKey, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchUninstallSubKey));
214 ButilExitOnFailure(hr, "Failed to calculate length of string"); 235 ButilExitOnRootFailure(hr, "Failed to calculate length of string");
215 236
216 hr = ::StringCchCopyNExW(lpBundleIdBuf, MAX_GUID_CHARS + 1, sczUninstallSubKey, cchUninstallSubKey, NULL, NULL, STRSAFE_FILL_BEHIND_NULL); 237 hr = ::StringCchCopyNExW(lpBundleIdBuf, MAX_GUID_CHARS + 1, sczUninstallSubKey, cchUninstallSubKey, NULL, NULL, STRSAFE_FILL_BEHIND_NULL);
217 ButilExitOnFailure(hr, "Failed to copy the property value to the output buffer."); 238 ButilExitOnRootFailure(hr, "Failed to copy the property value to the output buffer.");
218 } 239 }
219 240
220 break; 241 break;
@@ -237,52 +258,37 @@ LExit:
237 return hr; 258 return hr;
238} 259}
239 260
240/********************************************************************
241BundleGetBundleVariable - Queries the bundle installation metadata for a given variable,
242the caller is expected to free the memory returned vis psczValue
243RETURNS:
244S_OK
245 Success, if the variable had a value, it's returned in psczValue
246E_INVALIDARG
247 An invalid parameter was passed to the function.
248HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT)
249 The bundle is not installed
250HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY)
251 The variable is unrecognized
252E_NOTIMPL:
253 Tried to read a bundle variable for a type which has not been implemented
254
255All other returns are unexpected returns from other dutil methods.
256********************************************************************/
257 261
258extern "C" HRESULT DAPI BundleGetBundleVariable( 262DAPI_(HRESULT) BundleGetBundleVariable(
259 __in_z LPCWSTR wzBundleId, 263 __in_z LPCWSTR wzBundleId,
260 __in_z LPCWSTR wzVariable, 264 __in_z LPCWSTR wzVariable,
261 __deref_out_z LPWSTR * psczValue 265 __deref_out_z LPWSTR* psczValue
262) 266 )
263{ 267{
264 Assert(wzBundleId && wzVariable); 268 Assert(wzBundleId && wzVariable);
265 269
266 HRESULT hr = S_OK; 270 HRESULT hr = S_OK;
267 BUNDLE_INSTALL_CONTEXT context = BUNDLE_INSTALL_CONTEXT_MACHINE;
268 HKEY hkBundle = NULL; 271 HKEY hkBundle = NULL;
272 INTERNAL_BUNDLE_STATUS status = INTERNAL_BUNDLE_STATUS_SUCCESS;
269 DWORD dwType = 0; 273 DWORD dwType = 0;
270 274
271 if (!wzBundleId || !wzVariable || !psczValue) 275 if (!wzBundleId || !wzVariable || !psczValue)
272 { 276 {
273 ButilExitOnFailure(hr = E_INVALIDARG, "An invalid parameter was passed to the function."); 277 ButilExitWithRootFailure(hr, E_INVALIDARG, "An invalid parameter was passed to the function.");
274 } 278 }
275 279
276 if (FAILED(hr = OpenBundleKey(wzBundleId, context = BUNDLE_INSTALL_CONTEXT_MACHINE, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_VARIABLE_KEY, &hkBundle)) && 280 hr = LocateAndQueryBundleValue(wzBundleId, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_VARIABLE_KEY, wzVariable, &hkBundle, &dwType, &status);
277 FAILED(hr = OpenBundleKey(wzBundleId, context = BUNDLE_INSTALL_CONTEXT_USER, BUNDLE_REGISTRATION_REGISTRY_BUNDLE_VARIABLE_KEY, &hkBundle))) 281 ButilExitOnFailure(hr, "Failed to locate and query bundle variable.");
282
283 switch (status)
278 { 284 {
279 ButilExitOnFailure(E_FILENOTFOUND == hr ? HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT) : hr, "Failed to locate bundle uninstall key variable path."); 285 case INTERNAL_BUNDLE_STATUS_UNKNOWN_BUNDLE:
286 ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT));
287 case INTERNAL_BUNDLE_STATUS_UNKNOWN_PROPERTY:
288 // If the bundle doesn't have the shared variable defined, return ERROR_UNKNOWN_PROPERTY
289 ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY));
280 } 290 }
281 291
282 // If the bundle doesn't have the shared variable defined, return ERROR_UNKNOWN_PROPERTY
283 hr = RegGetType(hkBundle, wzVariable, &dwType);
284 ButilExitOnFailure(E_FILENOTFOUND == hr ? HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY) : hr, "Failed to locate bundle variable.");
285
286 switch (dwType) 292 switch (dwType)
287 { 293 {
288 case REG_SZ: 294 case REG_SZ:
@@ -293,35 +299,74 @@ extern "C" HRESULT DAPI BundleGetBundleVariable(
293 hr = S_OK; 299 hr = S_OK;
294 break; 300 break;
295 default: 301 default:
296 ButilExitOnFailure(hr = E_NOTIMPL, "Reading bundle variable of type 0x%x not implemented.", dwType); 302 ButilExitWithRootFailure(hr, E_NOTIMPL, "Reading bundle variable of type 0x%x not implemented.", dwType);
297
298 } 303 }
299 304
300LExit: 305LExit:
301 ReleaseRegKey(hkBundle); 306 ReleaseRegKey(hkBundle);
302 307
303 return hr; 308 return hr;
309}
310
311static HRESULT LocateAndQueryBundleValue(
312 __in_z LPCWSTR wzBundleId,
313 __in_opt LPCWSTR wzSubKey,
314 __in LPCWSTR wzValueName,
315 __inout HKEY* phKey,
316 __inout DWORD* pdwType,
317 __out INTERNAL_BUNDLE_STATUS* pStatus
318 )
319{
320 HRESULT hr = S_OK;
321
322 *pStatus = INTERNAL_BUNDLE_STATUS_SUCCESS;
304 323
324 if (FAILED(hr = OpenBundleKey(wzBundleId, BUNDLE_INSTALL_CONTEXT_MACHINE, wzSubKey, phKey)) &&
325 FAILED(hr = OpenBundleKey(wzBundleId, BUNDLE_INSTALL_CONTEXT_USER, wzSubKey, phKey)))
326 {
327 if (E_FILENOTFOUND == hr)
328 {
329 *pStatus = INTERNAL_BUNDLE_STATUS_UNKNOWN_BUNDLE;
330 ExitFunction1(hr = S_OK);
331 }
332
333 ButilExitOnFailure(hr, "Failed to open bundle key.");
334 }
335
336 // If the bundle doesn't have the value defined, return ERROR_UNKNOWN_PROPERTY
337 hr = RegGetType(*phKey, wzValueName, pdwType);
338 if (FAILED(hr))
339 {
340 if (E_FILENOTFOUND == hr)
341 {
342 *pStatus = INTERNAL_BUNDLE_STATUS_UNKNOWN_PROPERTY;
343 ExitFunction1(hr = S_OK);
344 }
345
346 ButilExitOnFailure(hr, "Failed to read bundle value.");
347 }
348
349LExit:
350 return hr;
305} 351}
306/******************************************************************** 352
307* 353static HRESULT OpenBundleKey(
308********************************************************************/
309HRESULT OpenBundleKey(
310 __in_z LPCWSTR wzBundleId, 354 __in_z LPCWSTR wzBundleId,
311 __in BUNDLE_INSTALL_CONTEXT context, 355 __in BUNDLE_INSTALL_CONTEXT context,
312 __in_opt LPCWSTR szSubKey, 356 __in_opt LPCWSTR wzSubKey,
313 __inout HKEY* key) 357 __inout HKEY* phKey
358 )
314{ 359{
315 Assert(key && wzBundleId); 360 Assert(phKey && wzBundleId);
316 AssertSz(NULL == *key, "*key should be null"); 361 AssertSz(NULL == *phKey, "*key should be null");
317 362
318 HRESULT hr = S_OK; 363 HRESULT hr = S_OK;
319 HKEY hkRoot = BUNDLE_INSTALL_CONTEXT_USER == context ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; 364 HKEY hkRoot = BUNDLE_INSTALL_CONTEXT_USER == context ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
320 LPWSTR sczKeypath = NULL; 365 LPWSTR sczKeypath = NULL;
321 366
322 if (szSubKey) 367 if (wzSubKey)
323 { 368 {
324 hr = StrAllocFormatted(&sczKeypath, L"%ls\\%ls\\%ls", BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY, wzBundleId, szSubKey); 369 hr = StrAllocFormatted(&sczKeypath, L"%ls\\%ls\\%ls", BUNDLE_REGISTRATION_REGISTRY_UNINSTALL_KEY, wzBundleId, wzSubKey);
325 } 370 }
326 else 371 else
327 { 372 {
@@ -329,7 +374,7 @@ HRESULT OpenBundleKey(
329 } 374 }
330 ButilExitOnFailure(hr, "Failed to allocate bundle uninstall key path."); 375 ButilExitOnFailure(hr, "Failed to allocate bundle uninstall key path.");
331 376
332 hr = RegOpen(hkRoot, sczKeypath, KEY_READ, key); 377 hr = RegOpen(hkRoot, sczKeypath, KEY_READ, phKey);
333 ButilExitOnFailure(hr, "Failed to open bundle uninstall key path."); 378 ButilExitOnFailure(hr, "Failed to open bundle uninstall key path.");
334 379
335LExit: 380LExit:
@@ -337,4 +382,3 @@ LExit:
337 382
338 return hr; 383 return hr;
339} 384}
340
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/butil.h b/src/libs/dutil/WixToolset.DUtil/inc/butil.h
index d910c113..721d9ad6 100644
--- a/src/libs/dutil/WixToolset.DUtil/inc/butil.h
+++ b/src/libs/dutil/WixToolset.DUtil/inc/butil.h
@@ -6,7 +6,7 @@
6extern "C" { 6extern "C" {
7#endif 7#endif
8 8
9typedef enum BUNDLE_INSTALL_CONTEXT 9typedef enum _BUNDLE_INSTALL_CONTEXT
10{ 10{
11 BUNDLE_INSTALL_CONTEXT_MACHINE, 11 BUNDLE_INSTALL_CONTEXT_MACHINE,
12 BUNDLE_INSTALL_CONTEXT_USER, 12 BUNDLE_INSTALL_CONTEXT_USER,
@@ -55,11 +55,29 @@ HRESULT DAPI BundleEnumRelatedBundle(
55 __out_ecount(MAX_GUID_CHARS+1) LPWSTR lpBundleIdBuf 55 __out_ecount(MAX_GUID_CHARS+1) LPWSTR lpBundleIdBuf
56 ); 56 );
57 57
58/********************************************************************
59BundleGetBundleVariable - Queries the bundle installation metadata for a given variable,
60 the caller is expected to free the memory returned vis psczValue
61
62RETURNS:
63 S_OK
64 Success, if the variable had a value, it's returned in psczValue
65 E_INVALIDARG
66 An invalid parameter was passed to the function.
67 HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT)
68 The bundle is not installed
69 HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY)
70 The variable is unrecognized
71 E_NOTIMPL:
72 Tried to read a bundle variable for a type which has not been implemented
73
74 All other returns are unexpected returns from other dutil methods.
75********************************************************************/
58HRESULT DAPI BundleGetBundleVariable( 76HRESULT DAPI BundleGetBundleVariable(
59 __in_z LPCWSTR wzBundleId, 77 __in_z LPCWSTR wzBundleId,
60 __in_z LPCWSTR wzVariable, 78 __in_z LPCWSTR wzVariable,
61 __deref_out_z LPWSTR* psczValue 79 __deref_out_z LPWSTR* psczValue
62); 80 );
63 81
64 82
65#ifdef __cplusplus 83#ifdef __cplusplus
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/regutil.h b/src/libs/dutil/WixToolset.DUtil/inc/regutil.h
index fcf13054..ae47f75e 100644
--- a/src/libs/dutil/WixToolset.DUtil/inc/regutil.h
+++ b/src/libs/dutil/WixToolset.DUtil/inc/regutil.h
@@ -99,9 +99,23 @@ typedef LSTATUS (APIENTRY *PFN_REGDELETEVALUEW)(
99 __in_opt LPCWSTR lpValueName 99 __in_opt LPCWSTR lpValueName
100 ); 100 );
101 101
102/********************************************************************
103 RegInitialize - initializes regutil
104
105*********************************************************************/
102HRESULT DAPI RegInitialize(); 106HRESULT DAPI RegInitialize();
107
108/********************************************************************
109 RegUninitialize - uninitializes regutil
110
111*********************************************************************/
103void DAPI RegUninitialize(); 112void DAPI RegUninitialize();
104 113
114/********************************************************************
115 RegFunctionOverride - overrides the registry functions. Typically used
116 for unit testing.
117
118*********************************************************************/
105void DAPI RegFunctionOverride( 119void DAPI RegFunctionOverride(
106 __in_opt PFN_REGCREATEKEYEXW pfnRegCreateKeyExW, 120 __in_opt PFN_REGCREATEKEYEXW pfnRegCreateKeyExW,
107 __in_opt PFN_REGOPENKEYEXW pfnRegOpenKeyExW, 121 __in_opt PFN_REGOPENKEYEXW pfnRegOpenKeyExW,
@@ -113,12 +127,22 @@ void DAPI RegFunctionOverride(
113 __in_opt PFN_REGSETVALUEEXW pfnRegSetValueExW, 127 __in_opt PFN_REGSETVALUEEXW pfnRegSetValueExW,
114 __in_opt PFN_REGDELETEVALUEW pfnRegDeleteValueW 128 __in_opt PFN_REGDELETEVALUEW pfnRegDeleteValueW
115 ); 129 );
130
131/********************************************************************
132 RegCreate - creates a registry key.
133
134*********************************************************************/
116HRESULT DAPI RegCreate( 135HRESULT DAPI RegCreate(
117 __in HKEY hkRoot, 136 __in HKEY hkRoot,
118 __in_z LPCWSTR wzSubKey, 137 __in_z LPCWSTR wzSubKey,
119 __in DWORD dwAccess, 138 __in DWORD dwAccess,
120 __out HKEY* phk 139 __out HKEY* phk
121 ); 140 );
141
142/********************************************************************
143 RegCreateEx - creates a registry key with extra options.
144
145*********************************************************************/
122HRESULT DAPI RegCreateEx( 146HRESULT DAPI RegCreateEx(
123 __in HKEY hkRoot, 147 __in HKEY hkRoot,
124 __in_z LPCWSTR wzSubKey, 148 __in_z LPCWSTR wzSubKey,
@@ -128,112 +152,229 @@ HRESULT DAPI RegCreateEx(
128 __out HKEY* phk, 152 __out HKEY* phk,
129 __out_opt BOOL* pfCreated 153 __out_opt BOOL* pfCreated
130 ); 154 );
155
156/********************************************************************
157 RegOpen - opens a registry key.
158
159*********************************************************************/
131HRESULT DAPI RegOpen( 160HRESULT DAPI RegOpen(
132 __in HKEY hkRoot, 161 __in HKEY hkRoot,
133 __in_z LPCWSTR wzSubKey, 162 __in_z LPCWSTR wzSubKey,
134 __in DWORD dwAccess, 163 __in DWORD dwAccess,
135 __out HKEY* phk 164 __out HKEY* phk
136 ); 165 );
166
167/********************************************************************
168 RegDelete - deletes a registry key (and optionally it's whole tree).
169
170*********************************************************************/
137HRESULT DAPI RegDelete( 171HRESULT DAPI RegDelete(
138 __in HKEY hkRoot, 172 __in HKEY hkRoot,
139 __in_z LPCWSTR wzSubKey, 173 __in_z LPCWSTR wzSubKey,
140 __in REG_KEY_BITNESS kbKeyBitness, 174 __in REG_KEY_BITNESS kbKeyBitness,
141 __in BOOL fDeleteTree 175 __in BOOL fDeleteTree
142 ); 176 );
177
178/********************************************************************
179 RegKeyEnum - enumerates child registry keys.
180
181*********************************************************************/
143HRESULT DAPI RegKeyEnum( 182HRESULT DAPI RegKeyEnum(
144 __in HKEY hk, 183 __in HKEY hk,
145 __in DWORD dwIndex, 184 __in DWORD dwIndex,
146 __deref_out_z LPWSTR* psczKey 185 __deref_out_z LPWSTR* psczKey
147 ); 186 );
187
188/********************************************************************
189 RegValueEnum - enumerates registry values.
190
191*********************************************************************/
148HRESULT DAPI RegValueEnum( 192HRESULT DAPI RegValueEnum(
149 __in HKEY hk, 193 __in HKEY hk,
150 __in DWORD dwIndex, 194 __in DWORD dwIndex,
151 __deref_out_z LPWSTR* psczName, 195 __deref_out_z LPWSTR* psczName,
152 __out_opt DWORD *pdwType 196 __out_opt DWORD *pdwType
153 ); 197 );
198
199/********************************************************************
200 RegGetType - reads a registry key value type.
201 *********************************************************************/
154HRESULT DAPI RegGetType( 202HRESULT DAPI RegGetType(
155 __in HKEY hk, 203 __in HKEY hk,
156 __in_z_opt LPCWSTR wzName, 204 __in_z_opt LPCWSTR wzName,
157 __out DWORD *pdwType 205 __out DWORD *pdwType
158 ); 206 );
207
208/********************************************************************
209 RegReadBinary - reads a registry key binary value.
210 NOTE: caller is responsible for freeing *ppbBuffer
211*********************************************************************/
159HRESULT DAPI RegReadBinary( 212HRESULT DAPI RegReadBinary(
160 __in HKEY hk, 213 __in HKEY hk,
161 __in_z_opt LPCWSTR wzName, 214 __in_z_opt LPCWSTR wzName,
162 __deref_out_bcount_opt(*pcbBuffer) BYTE** ppbBuffer, 215 __deref_out_bcount_opt(*pcbBuffer) BYTE** ppbBuffer,
163 __out SIZE_T *pcbBuffer 216 __out SIZE_T *pcbBuffer
164 ); 217 );
218
219/********************************************************************
220 RegReadString - reads a registry key value as a string.
221
222*********************************************************************/
165HRESULT DAPI RegReadString( 223HRESULT DAPI RegReadString(
166 __in HKEY hk, 224 __in HKEY hk,
167 __in_z_opt LPCWSTR wzName, 225 __in_z_opt LPCWSTR wzName,
168 __deref_out_z LPWSTR* psczValue 226 __deref_out_z LPWSTR* psczValue
169 ); 227 );
228
229/********************************************************************
230 RegReadStringArray - reads a registry key value REG_MULTI_SZ value as a string array.
231
232*********************************************************************/
170HRESULT DAPI RegReadStringArray( 233HRESULT DAPI RegReadStringArray(
171 __in HKEY hk, 234 __in HKEY hk,
172 __in_z_opt LPCWSTR wzName, 235 __in_z_opt LPCWSTR wzName,
173 __deref_out_ecount_opt(*pcStrings) LPWSTR** prgsczStrings, 236 __deref_out_ecount_opt(*pcStrings) LPWSTR** prgsczStrings,
174 __out DWORD *pcStrings 237 __out DWORD *pcStrings
175 ); 238 );
239
240/********************************************************************
241 RegReadVersion - reads a registry key value as a version.
242
243*********************************************************************/
176HRESULT DAPI RegReadVersion( 244HRESULT DAPI RegReadVersion(
177 __in HKEY hk, 245 __in HKEY hk,
178 __in_z_opt LPCWSTR wzName, 246 __in_z_opt LPCWSTR wzName,
179 __out DWORD64* pdw64Version 247 __out DWORD64* pdw64Version
180 ); 248 );
249
250/********************************************************************
251 RegReadNone - reads a NONE registry key value.
252
253*********************************************************************/
181HRESULT DAPI RegReadNone( 254HRESULT DAPI RegReadNone(
182 __in HKEY hk, 255 __in HKEY hk,
183 __in_z_opt LPCWSTR wzName 256 __in_z_opt LPCWSTR wzName
184); 257 );
258
259/********************************************************************
260 RegReadNumber - reads a DWORD registry key value as a number.
261
262*********************************************************************/
185HRESULT DAPI RegReadNumber( 263HRESULT DAPI RegReadNumber(
186 __in HKEY hk, 264 __in HKEY hk,
187 __in_z_opt LPCWSTR wzName, 265 __in_z_opt LPCWSTR wzName,
188 __out DWORD* pdwValue 266 __out DWORD* pdwValue
189 ); 267 );
268
269/********************************************************************
270 RegReadQword - reads a QWORD registry key value as a number.
271
272*********************************************************************/
190HRESULT DAPI RegReadQword( 273HRESULT DAPI RegReadQword(
191 __in HKEY hk, 274 __in HKEY hk,
192 __in_z_opt LPCWSTR wzName, 275 __in_z_opt LPCWSTR wzName,
193 __out DWORD64* pqwValue 276 __out DWORD64* pqwValue
194 ); 277 );
278
279/********************************************************************
280 RegWriteBinary - writes a registry key value as a binary.
281
282*********************************************************************/
195HRESULT DAPI RegWriteBinary( 283HRESULT DAPI RegWriteBinary(
196 __in HKEY hk, 284 __in HKEY hk,
197 __in_z_opt LPCWSTR wzName, 285 __in_z_opt LPCWSTR wzName,
198 __in_bcount(cbBuffer) const BYTE *pbBuffer, 286 __in_bcount(cbBuffer) const BYTE *pbBuffer,
199 __in DWORD cbBuffer 287 __in DWORD cbBuffer
200 ); 288 );
201HRESULT DAPI RegWriteString( 289
290/********************************************************************
291RegWriteExpandString - writes a registry key value as an expand string.
292
293Note: if wzValue is NULL the value will be removed.
294*********************************************************************/
295HRESULT DAPI RegWriteExpandString(
202 __in HKEY hk, 296 __in HKEY hk,
203 __in_z_opt LPCWSTR wzName, 297 __in_z_opt LPCWSTR wzName,
204 __in_z_opt LPCWSTR wzValue 298 __in_z_opt LPCWSTR wzValue
205 ); 299 );
206HRESULT DAPI RegWriteStringArray( 300
301/********************************************************************
302 RegWriteString - writes a registry key value as a string.
303
304 Note: if wzValue is NULL the value will be removed.
305*********************************************************************/
306HRESULT DAPI RegWriteString(
207 __in HKEY hk, 307 __in HKEY hk,
208 __in_z_opt LPCWSTR wzName, 308 __in_z_opt LPCWSTR wzName,
209 __in_ecount(cStrings) LPWSTR *rgwzStrings, 309 __in_z_opt LPCWSTR wzValue
210 __in DWORD cStrings
211 ); 310 );
212HRESULT DAPI RegWriteStringFormatted( 311
312/********************************************************************
313 RegWriteStringFormatted - writes a registry key value as a formatted string.
314
315*********************************************************************/
316HRESULT DAPIV RegWriteStringFormatted(
213 __in HKEY hk, 317 __in HKEY hk,
214 __in_z_opt LPCWSTR wzName, 318 __in_z_opt LPCWSTR wzName,
215 __in __format_string LPCWSTR szFormat, 319 __in __format_string LPCWSTR szFormat,
216 ... 320 ...
217 ); 321 );
322
323/********************************************************************
324 RegWriteStringArray - writes an array of strings as a REG_MULTI_SZ value
325
326*********************************************************************/
327HRESULT DAPI RegWriteStringArray(
328 __in HKEY hk,
329 __in_z_opt LPCWSTR wzName,
330 __in_ecount(cStrings) LPWSTR* rgwzStrings,
331 __in DWORD cStrings
332 );
333
334/********************************************************************
335 RegWriteNone - writes a registry key value as none.
336
337*********************************************************************/
218HRESULT DAPI RegWriteNone( 338HRESULT DAPI RegWriteNone(
219 __in HKEY hk, 339 __in HKEY hk,
220 __in_z_opt LPCWSTR wzName 340 __in_z_opt LPCWSTR wzName
221); 341 );
342
343/********************************************************************
344 RegWriteNumber - writes a registry key value as a number.
345
346*********************************************************************/
222HRESULT DAPI RegWriteNumber( 347HRESULT DAPI RegWriteNumber(
223 __in HKEY hk, 348 __in HKEY hk,
224 __in_z_opt LPCWSTR wzName, 349 __in_z_opt LPCWSTR wzName,
225 __in DWORD dwValue 350 __in DWORD dwValue
226 ); 351 );
352
353/********************************************************************
354 RegWriteQword - writes a registry key value as a Qword.
355
356*********************************************************************/
227HRESULT DAPI RegWriteQword( 357HRESULT DAPI RegWriteQword(
228 __in HKEY hk, 358 __in HKEY hk,
229 __in_z_opt LPCWSTR wzName, 359 __in_z_opt LPCWSTR wzName,
230 __in DWORD64 qwValue 360 __in DWORD64 qwValue
231 ); 361 );
362
363/********************************************************************
364 RegQueryKey - queries the key for the number of subkeys and values.
365
366*********************************************************************/
232HRESULT DAPI RegQueryKey( 367HRESULT DAPI RegQueryKey(
233 __in HKEY hk, 368 __in HKEY hk,
234 __out_opt DWORD* pcSubKeys, 369 __out_opt DWORD* pcSubKeys,
235 __out_opt DWORD* pcValues 370 __out_opt DWORD* pcValues
236 ); 371 );
372
373/********************************************************************
374RegKeyReadNumber - reads a DWORD registry key value as a number from
375a specified subkey.
376
377*********************************************************************/
237HRESULT DAPI RegKeyReadNumber( 378HRESULT DAPI RegKeyReadNumber(
238 __in HKEY hk, 379 __in HKEY hk,
239 __in_z LPCWSTR wzSubKey, 380 __in_z LPCWSTR wzSubKey,
@@ -241,6 +382,12 @@ HRESULT DAPI RegKeyReadNumber(
241 __in BOOL f64Bit, 382 __in BOOL f64Bit,
242 __out DWORD* pdwValue 383 __out DWORD* pdwValue
243 ); 384 );
385
386/********************************************************************
387RegValueExists - determines whether a named value exists in a
388specified subkey.
389
390*********************************************************************/
244BOOL DAPI RegValueExists( 391BOOL DAPI RegValueExists(
245 __in HKEY hk, 392 __in HKEY hk,
246 __in_z LPCWSTR wzSubKey, 393 __in_z LPCWSTR wzSubKey,
diff --git a/src/libs/dutil/WixToolset.DUtil/regutil.cpp b/src/libs/dutil/WixToolset.DUtil/regutil.cpp
index 458d8586..57093f97 100644
--- a/src/libs/dutil/WixToolset.DUtil/regutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/regutil.cpp
@@ -37,14 +37,9 @@ static HRESULT WriteStringToRegistry(
37 __in_z_opt LPCWSTR wzName, 37 __in_z_opt LPCWSTR wzName,
38 __in_z_opt LPCWSTR wzValue, 38 __in_z_opt LPCWSTR wzValue,
39 __in DWORD dwType 39 __in DWORD dwType
40); 40 );
41 41
42/******************************************************************** 42DAPI_(HRESULT) RegInitialize()
43 RegInitialize - initializes regutil
44
45*********************************************************************/
46extern "C" HRESULT DAPI RegInitialize(
47 )
48{ 43{
49 HRESULT hr = S_OK; 44 HRESULT hr = S_OK;
50 45
@@ -66,12 +61,7 @@ LExit:
66} 61}
67 62
68 63
69/******************************************************************** 64DAPI_(void) RegUninitialize()
70 RegUninitialize - uninitializes regutil
71
72*********************************************************************/
73extern "C" void DAPI RegUninitialize(
74 )
75{ 65{
76 if (vhAdvApi32Dll) 66 if (vhAdvApi32Dll)
77 { 67 {
@@ -85,12 +75,7 @@ extern "C" void DAPI RegUninitialize(
85} 75}
86 76
87 77
88/******************************************************************** 78DAPI_(void) RegFunctionOverride(
89 RegFunctionOverride - overrides the registry functions. Typically used
90 for unit testing.
91
92*********************************************************************/
93extern "C" void DAPI RegFunctionOverride(
94 __in_opt PFN_REGCREATEKEYEXW pfnRegCreateKeyExW, 79 __in_opt PFN_REGCREATEKEYEXW pfnRegCreateKeyExW,
95 __in_opt PFN_REGOPENKEYEXW pfnRegOpenKeyExW, 80 __in_opt PFN_REGOPENKEYEXW pfnRegOpenKeyExW,
96 __in_opt PFN_REGDELETEKEYEXW pfnRegDeleteKeyExW, 81 __in_opt PFN_REGDELETEKEYEXW pfnRegDeleteKeyExW,
@@ -114,11 +99,7 @@ extern "C" void DAPI RegFunctionOverride(
114} 99}
115 100
116 101
117/******************************************************************** 102DAPI_(HRESULT) RegCreate(
118 RegCreate - creates a registry key.
119
120*********************************************************************/
121extern "C" HRESULT DAPI RegCreate(
122 __in HKEY hkRoot, 103 __in HKEY hkRoot,
123 __in_z LPCWSTR wzSubKey, 104 __in_z LPCWSTR wzSubKey,
124 __in DWORD dwAccess, 105 __in DWORD dwAccess,
@@ -136,11 +117,7 @@ LExit:
136} 117}
137 118
138 119
139/******************************************************************** 120DAPI_(HRESULT) RegCreateEx(
140 RegCreate - creates a registry key with extra options.
141
142*********************************************************************/
143HRESULT DAPI RegCreateEx(
144 __in HKEY hkRoot, 121 __in HKEY hkRoot,
145 __in_z LPCWSTR wzSubKey, 122 __in_z LPCWSTR wzSubKey,
146 __in DWORD dwAccess, 123 __in DWORD dwAccess,
@@ -167,11 +144,7 @@ LExit:
167} 144}
168 145
169 146
170/******************************************************************** 147DAPI_(HRESULT) RegOpen(
171 RegOpen - opens a registry key.
172
173*********************************************************************/
174extern "C" HRESULT DAPI RegOpen(
175 __in HKEY hkRoot, 148 __in HKEY hkRoot,
176 __in_z LPCWSTR wzSubKey, 149 __in_z LPCWSTR wzSubKey,
177 __in DWORD dwAccess, 150 __in DWORD dwAccess,
@@ -193,11 +166,7 @@ LExit:
193} 166}
194 167
195 168
196/******************************************************************** 169DAPI_(HRESULT) RegDelete(
197 RegDelete - deletes a registry key (and optionally it's whole tree).
198
199*********************************************************************/
200extern "C" HRESULT DAPI RegDelete(
201 __in HKEY hkRoot, 170 __in HKEY hkRoot,
202 __in_z LPCWSTR wzSubKey, 171 __in_z LPCWSTR wzSubKey,
203 __in REG_KEY_BITNESS kbKeyBitness, 172 __in REG_KEY_BITNESS kbKeyBitness,
@@ -282,11 +251,7 @@ LExit:
282} 251}
283 252
284 253
285/******************************************************************** 254DAPI_(HRESULT) RegKeyEnum(
286 RegKeyEnum - enumerates child registry keys.
287
288*********************************************************************/
289extern "C" HRESULT DAPI RegKeyEnum(
290 __in HKEY hk, 255 __in HKEY hk,
291 __in DWORD dwIndex, 256 __in DWORD dwIndex,
292 __deref_out_z LPWSTR* psczKey 257 __deref_out_z LPWSTR* psczKey
@@ -342,11 +307,7 @@ LExit:
342} 307}
343 308
344 309
345/******************************************************************** 310DAPI_(HRESULT) RegValueEnum(
346 RegValueEnum - enumerates registry values.
347
348*********************************************************************/
349HRESULT DAPI RegValueEnum(
350 __in HKEY hk, 311 __in HKEY hk,
351 __in DWORD dwIndex, 312 __in DWORD dwIndex,
352 __deref_out_z LPWSTR* psczName, 313 __deref_out_z LPWSTR* psczName,
@@ -377,10 +338,7 @@ LExit:
377 return hr; 338 return hr;
378} 339}
379 340
380/******************************************************************** 341DAPI_(HRESULT) RegGetType(
381 RegGetType - reads a registry key value type.
382 *********************************************************************/
383HRESULT DAPI RegGetType(
384 __in HKEY hk, 342 __in HKEY hk,
385 __in_z_opt LPCWSTR wzName, 343 __in_z_opt LPCWSTR wzName,
386 __out DWORD *pdwType 344 __out DWORD *pdwType
@@ -400,11 +358,7 @@ LExit:
400 return hr; 358 return hr;
401} 359}
402 360
403/******************************************************************** 361DAPI_(HRESULT) RegReadBinary(
404 RegReadBinary - reads a registry key binary value.
405 NOTE: caller is responsible for freeing *ppbBuffer
406*********************************************************************/
407HRESULT DAPI RegReadBinary(
408 __in HKEY hk, 362 __in HKEY hk,
409 __in_z_opt LPCWSTR wzName, 363 __in_z_opt LPCWSTR wzName,
410 __deref_out_bcount_opt(*pcbBuffer) BYTE** ppbBuffer, 364 __deref_out_bcount_opt(*pcbBuffer) BYTE** ppbBuffer,
@@ -453,11 +407,7 @@ LExit:
453} 407}
454 408
455 409
456/******************************************************************** 410DAPI_(HRESULT) RegReadString(
457 RegReadString - reads a registry key value as a string.
458
459*********************************************************************/
460extern "C" HRESULT DAPI RegReadString(
461 __in HKEY hk, 411 __in HKEY hk,
462 __in_z_opt LPCWSTR wzName, 412 __in_z_opt LPCWSTR wzName,
463 __deref_out_z LPWSTR* psczValue 413 __deref_out_z LPWSTR* psczValue
@@ -530,11 +480,7 @@ LExit:
530} 480}
531 481
532 482
533/******************************************************************** 483DAPI_(HRESULT) RegReadStringArray(
534 RegReadStringArray - reads a registry key value REG_MULTI_SZ value as a string array.
535
536*********************************************************************/
537HRESULT DAPI RegReadStringArray(
538 __in HKEY hk, 484 __in HKEY hk,
539 __in_z_opt LPCWSTR wzName, 485 __in_z_opt LPCWSTR wzName,
540 __deref_out_ecount_opt(*pcStrings) LPWSTR** prgsczStrings, 486 __deref_out_ecount_opt(*pcStrings) LPWSTR** prgsczStrings,
@@ -626,11 +572,7 @@ LExit:
626} 572}
627 573
628 574
629/******************************************************************** 575DAPI_(HRESULT) RegReadVersion(
630 RegReadVersion - reads a registry key value as a version.
631
632*********************************************************************/
633extern "C" HRESULT DAPI RegReadVersion(
634 __in HKEY hk, 576 __in HKEY hk,
635 __in_z_opt LPCWSTR wzName, 577 __in_z_opt LPCWSTR wzName,
636 __out DWORD64* pdw64Version 578 __out DWORD64* pdw64Version
@@ -672,13 +614,10 @@ LExit:
672 return hr; 614 return hr;
673} 615}
674 616
675/******************************************************************** 617DAPI_(HRESULT) RegReadNone(
676 RegReadNone - reads a NONE registry key value.
677
678*********************************************************************/
679extern "C" HRESULT DAPI RegReadNone(
680 __in HKEY hk, 618 __in HKEY hk,
681 __in_z_opt LPCWSTR wzName) 619 __in_z_opt LPCWSTR wzName
620 )
682{ 621{
683 HRESULT hr = S_OK; 622 HRESULT hr = S_OK;
684 DWORD er = ERROR_SUCCESS; 623 DWORD er = ERROR_SUCCESS;
@@ -694,18 +633,14 @@ extern "C" HRESULT DAPI RegReadNone(
694 if (REG_NONE != dwType) 633 if (REG_NONE != dwType)
695 { 634 {
696 hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE); 635 hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE);
697 RegExitOnRootFailure(hr, "Error reading version registry value due to unexpected data type: %u", dwType); 636 RegExitOnRootFailure(hr, "Error reading none registry value due to unexpected data type: %u", dwType);
698 } 637 }
699 638
700LExit: 639LExit:
701 return hr; 640 return hr;
702} 641}
703 642
704/******************************************************************** 643DAPI_(HRESULT) RegReadNumber(
705 RegReadNumber - reads a DWORD registry key value as a number.
706
707*********************************************************************/
708extern "C" HRESULT DAPI RegReadNumber(
709 __in HKEY hk, 644 __in HKEY hk,
710 __in_z_opt LPCWSTR wzName, 645 __in_z_opt LPCWSTR wzName,
711 __out DWORD* pdwValue 646 __out DWORD* pdwValue
@@ -734,11 +669,7 @@ LExit:
734} 669}
735 670
736 671
737/******************************************************************** 672DAPI_(HRESULT) RegReadQword(
738 RegReadQword - reads a QWORD registry key value as a number.
739
740*********************************************************************/
741extern "C" HRESULT DAPI RegReadQword(
742 __in HKEY hk, 673 __in HKEY hk,
743 __in_z_opt LPCWSTR wzName, 674 __in_z_opt LPCWSTR wzName,
744 __out DWORD64* pqwValue 675 __out DWORD64* pqwValue
@@ -767,11 +698,7 @@ LExit:
767} 698}
768 699
769 700
770/******************************************************************** 701DAPI_(HRESULT) RegWriteBinary(
771 RegWriteBinary - writes a registry key value as a binary.
772
773*********************************************************************/
774HRESULT DAPI RegWriteBinary(
775 __in HKEY hk, 702 __in HKEY hk,
776 __in_z_opt LPCWSTR wzName, 703 __in_z_opt LPCWSTR wzName,
777 __in_bcount(cbBuffer) const BYTE *pbBuffer, 704 __in_bcount(cbBuffer) const BYTE *pbBuffer,
@@ -789,27 +716,17 @@ LExit:
789} 716}
790 717
791 718
792/******************************************************************** 719DAPI_(HRESULT) RegWriteExpandString(
793RegWriteExpandString - writes a registry key value as an expand string.
794
795Note: if wzValue is NULL the value will be removed.
796*********************************************************************/
797extern "C" HRESULT DAPI RegWriteExpandString(
798 __in HKEY hk, 720 __in HKEY hk,
799 __in_z_opt LPCWSTR wzName, 721 __in_z_opt LPCWSTR wzName,
800 __in_z_opt LPCWSTR wzValue 722 __in_z_opt LPCWSTR wzValue
801) 723 )
802{ 724{
803 return WriteStringToRegistry(hk, wzName, wzValue, REG_EXPAND_SZ); 725 return WriteStringToRegistry(hk, wzName, wzValue, REG_EXPAND_SZ);
804} 726}
805 727
806 728
807/******************************************************************** 729DAPI_(HRESULT) RegWriteString(
808 RegWriteString - writes a registry key value as a string.
809
810 Note: if wzValue is NULL the value will be removed.
811*********************************************************************/
812extern "C" HRESULT DAPI RegWriteString(
813 __in HKEY hk, 730 __in HKEY hk,
814 __in_z_opt LPCWSTR wzName, 731 __in_z_opt LPCWSTR wzName,
815 __in_z_opt LPCWSTR wzValue 732 __in_z_opt LPCWSTR wzValue
@@ -819,11 +736,7 @@ extern "C" HRESULT DAPI RegWriteString(
819} 736}
820 737
821 738
822/******************************************************************** 739DAPIV_(HRESULT) RegWriteStringFormatted(
823 RegWriteStringFormatted - writes a registry key value as a formatted string.
824
825*********************************************************************/
826extern "C" HRESULT DAPI RegWriteStringFormatted(
827 __in HKEY hk, 740 __in HKEY hk,
828 __in_z_opt LPCWSTR wzName, 741 __in_z_opt LPCWSTR wzName,
829 __in __format_string LPCWSTR szFormat, 742 __in __format_string LPCWSTR szFormat,
@@ -848,11 +761,7 @@ LExit:
848} 761}
849 762
850 763
851/******************************************************************** 764DAPI_(HRESULT) RegWriteStringArray(
852 RegWriteStringArray - writes an array of strings as a REG_MULTI_SZ value
853
854*********************************************************************/
855HRESULT DAPI RegWriteStringArray(
856 __in HKEY hk, 765 __in HKEY hk,
857 __in_z_opt LPCWSTR wzName, 766 __in_z_opt LPCWSTR wzName,
858 __in_ecount(cValues) LPWSTR *rgwzValues, 767 __in_ecount(cValues) LPWSTR *rgwzValues,
@@ -913,14 +822,10 @@ LExit:
913 return hr; 822 return hr;
914} 823}
915 824
916/******************************************************************** 825DAPI_(HRESULT) RegWriteNone(
917 RegWriteNone - writes a registry key value as none.
918
919*********************************************************************/
920extern "C" HRESULT DAPI RegWriteNone(
921 __in HKEY hk, 826 __in HKEY hk,
922 __in_z_opt LPCWSTR wzName 827 __in_z_opt LPCWSTR wzName
923) 828 )
924{ 829{
925 HRESULT hr = S_OK; 830 HRESULT hr = S_OK;
926 DWORD er = ERROR_SUCCESS; 831 DWORD er = ERROR_SUCCESS;
@@ -932,11 +837,7 @@ LExit:
932 return hr; 837 return hr;
933} 838}
934 839
935/******************************************************************** 840DAPI_(HRESULT) RegWriteNumber(
936 RegWriteNumber - writes a registry key value as a number.
937
938*********************************************************************/
939extern "C" HRESULT DAPI RegWriteNumber(
940 __in HKEY hk, 841 __in HKEY hk,
941 __in_z_opt LPCWSTR wzName, 842 __in_z_opt LPCWSTR wzName,
942 __in DWORD dwValue 843 __in DWORD dwValue
@@ -952,11 +853,7 @@ LExit:
952 return hr; 853 return hr;
953} 854}
954 855
955/******************************************************************** 856DAPI_(HRESULT) RegWriteQword(
956 RegWriteQword - writes a registry key value as a Qword.
957
958*********************************************************************/
959extern "C" HRESULT DAPI RegWriteQword(
960 __in HKEY hk, 857 __in HKEY hk,
961 __in_z_opt LPCWSTR wzName, 858 __in_z_opt LPCWSTR wzName,
962 __in DWORD64 qwValue 859 __in DWORD64 qwValue
@@ -972,11 +869,7 @@ LExit:
972 return hr; 869 return hr;
973} 870}
974 871
975/******************************************************************** 872DAPI_(HRESULT) RegQueryKey(
976 RegQueryKey - queries the key for the number of subkeys and values.
977
978*********************************************************************/
979extern "C" HRESULT DAPI RegQueryKey(
980 __in HKEY hk, 873 __in HKEY hk,
981 __out_opt DWORD* pcSubKeys, 874 __out_opt DWORD* pcSubKeys,
982 __out_opt DWORD* pcValues 875 __out_opt DWORD* pcValues
@@ -992,12 +885,7 @@ LExit:
992 return hr; 885 return hr;
993} 886}
994 887
995/******************************************************************** 888DAPI_(HRESULT) RegKeyReadNumber(
996RegKeyReadNumber - reads a DWORD registry key value as a number from
997a specified subkey.
998
999*********************************************************************/
1000extern "C" HRESULT DAPI RegKeyReadNumber(
1001 __in HKEY hk, 889 __in HKEY hk,
1002 __in_z LPCWSTR wzSubKey, 890 __in_z LPCWSTR wzSubKey,
1003 __in_z_opt LPCWSTR wzName, 891 __in_z_opt LPCWSTR wzName,
@@ -1025,7 +913,7 @@ RegValueExists - determines whether a named value exists in a
1025specified subkey. 913specified subkey.
1026 914
1027*********************************************************************/ 915*********************************************************************/
1028extern "C" BOOL DAPI RegValueExists( 916DAPI_(BOOL) RegValueExists(
1029 __in HKEY hk, 917 __in HKEY hk,
1030 __in_z LPCWSTR wzSubKey, 918 __in_z LPCWSTR wzSubKey,
1031 __in_z_opt LPCWSTR wzName, 919 __in_z_opt LPCWSTR wzName,