diff options
author | Rob Mensching <rob@firegiant.com> | 2021-04-22 17:06:54 -0700 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2021-04-29 16:36:06 -0700 |
commit | af10c45d7b3a44af0b461a557847fe03263dcc10 (patch) | |
tree | 6a5c1532304782c36ffe4200b38f3afb76789a43 /src/burn/test/BurnUnitTest/RegistrationTest.cpp | |
parent | 9c2aed97299fb96aeee3f1471ce40225437aaecf (diff) | |
download | wix-af10c45d7b3a44af0b461a557847fe03263dcc10.tar.gz wix-af10c45d7b3a44af0b461a557847fe03263dcc10.tar.bz2 wix-af10c45d7b3a44af0b461a557847fe03263dcc10.zip |
Move burn into burn
Diffstat (limited to 'src/burn/test/BurnUnitTest/RegistrationTest.cpp')
-rw-r--r-- | src/burn/test/BurnUnitTest/RegistrationTest.cpp | 772 |
1 files changed, 772 insertions, 0 deletions
diff --git a/src/burn/test/BurnUnitTest/RegistrationTest.cpp b/src/burn/test/BurnUnitTest/RegistrationTest.cpp new file mode 100644 index 00000000..7b126f61 --- /dev/null +++ b/src/burn/test/BurnUnitTest/RegistrationTest.cpp | |||
@@ -0,0 +1,772 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | #include "precomp.h" | ||
4 | |||
5 | |||
6 | #define ROOT_PATH L"SOFTWARE\\WiX_Burn_UnitTest" | ||
7 | #define HKLM_PATH L"SOFTWARE\\WiX_Burn_UnitTest\\HKLM" | ||
8 | #define HKCU_PATH L"SOFTWARE\\WiX_Burn_UnitTest\\HKCU" | ||
9 | #define REGISTRY_UNINSTALL_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" | ||
10 | #define REGISTRY_RUN_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce" | ||
11 | |||
12 | #define TEST_UNINSTALL_KEY L"HKEY_CURRENT_USER\\" HKCU_PATH L"\\" REGISTRY_UNINSTALL_KEY L"\\{D54F896D-1952-43e6-9C67-B5652240618C}" | ||
13 | #define TEST_RUN_KEY L"HKEY_CURRENT_USER\\" HKCU_PATH L"\\" REGISTRY_RUN_KEY | ||
14 | |||
15 | |||
16 | static LSTATUS APIENTRY RegistrationTest_RegCreateKeyExW( | ||
17 | __in HKEY hKey, | ||
18 | __in LPCWSTR lpSubKey, | ||
19 | __reserved DWORD Reserved, | ||
20 | __in_opt LPWSTR lpClass, | ||
21 | __in DWORD dwOptions, | ||
22 | __in REGSAM samDesired, | ||
23 | __in_opt CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, | ||
24 | __out PHKEY phkResult, | ||
25 | __out_opt LPDWORD lpdwDisposition | ||
26 | ); | ||
27 | static LSTATUS APIENTRY RegistrationTest_RegOpenKeyExW( | ||
28 | __in HKEY hKey, | ||
29 | __in_opt LPCWSTR lpSubKey, | ||
30 | __reserved DWORD ulOptions, | ||
31 | __in REGSAM samDesired, | ||
32 | __out PHKEY phkResult | ||
33 | ); | ||
34 | static LSTATUS APIENTRY RegistrationTest_RegDeleteKeyExW( | ||
35 | __in HKEY hKey, | ||
36 | __in LPCWSTR lpSubKey, | ||
37 | __in REGSAM samDesired, | ||
38 | __reserved DWORD Reserved | ||
39 | ); | ||
40 | |||
41 | namespace Microsoft | ||
42 | { | ||
43 | namespace Tools | ||
44 | { | ||
45 | namespace WindowsInstallerXml | ||
46 | { | ||
47 | namespace Test | ||
48 | { | ||
49 | namespace Bootstrapper | ||
50 | { | ||
51 | using namespace Microsoft::Win32; | ||
52 | using namespace System; | ||
53 | using namespace System::IO; | ||
54 | using namespace Xunit; | ||
55 | |||
56 | public ref class RegistrationTest : BurnUnitTest | ||
57 | { | ||
58 | public: | ||
59 | RegistrationTest(BurnTestFixture^ fixture) : BurnUnitTest(fixture) | ||
60 | { | ||
61 | } | ||
62 | |||
63 | [Fact] | ||
64 | void RegisterBasicTest() | ||
65 | { | ||
66 | HRESULT hr = S_OK; | ||
67 | IXMLDOMElement* pixeBundle = NULL; | ||
68 | LPWSTR sczCurrentProcess = NULL; | ||
69 | BURN_VARIABLES variables = { }; | ||
70 | BURN_USER_EXPERIENCE userExperience = { }; | ||
71 | BOOTSTRAPPER_COMMAND command = { }; | ||
72 | BURN_REGISTRATION registration = { }; | ||
73 | BURN_LOGGING logging = { }; | ||
74 | BURN_PACKAGES packages = { }; | ||
75 | String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}")); | ||
76 | |||
77 | try | ||
78 | { | ||
79 | // set mock API's | ||
80 | RegFunctionOverride(RegistrationTest_RegCreateKeyExW, RegistrationTest_RegOpenKeyExW, RegistrationTest_RegDeleteKeyExW, NULL, NULL, NULL, NULL, NULL, NULL); | ||
81 | |||
82 | Registry::CurrentUser->CreateSubKey(gcnew String(HKCU_PATH)); | ||
83 | |||
84 | logging.sczPath = L"BurnUnitTest.txt"; | ||
85 | |||
86 | LPCWSTR wzDocument = | ||
87 | L"<Bundle>" | ||
88 | L" <UX>" | ||
89 | L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />" | ||
90 | L" </UX>" | ||
91 | 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'>" | ||
92 | L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='RegisterBasicTest' DisplayVersion='1.0.0.0' />" | ||
93 | L" </Registration>" | ||
94 | L"</Bundle>"; | ||
95 | |||
96 | // load XML document | ||
97 | LoadBundleXmlHelper(wzDocument, &pixeBundle); | ||
98 | |||
99 | hr = VariableInitialize(&variables); | ||
100 | TestThrowOnFailure(hr, L"Failed to initialize variables."); | ||
101 | |||
102 | hr = UserExperienceParseFromXml(&userExperience, pixeBundle); | ||
103 | TestThrowOnFailure(hr, L"Failed to parse UX from XML."); | ||
104 | |||
105 | hr = RegistrationParseFromXml(®istration, pixeBundle); | ||
106 | TestThrowOnFailure(hr, L"Failed to parse registration from XML."); | ||
107 | |||
108 | hr = PlanSetResumeCommand(®istration, BOOTSTRAPPER_ACTION_INSTALL, &command, &logging); | ||
109 | TestThrowOnFailure(hr, L"Failed to set registration resume command."); | ||
110 | |||
111 | hr = PathForCurrentProcess(&sczCurrentProcess, NULL); | ||
112 | TestThrowOnFailure(hr, L"Failed to get current process path."); | ||
113 | |||
114 | // write registration | ||
115 | hr = RegistrationSessionBegin(sczCurrentProcess, ®istration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE | BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0); | ||
116 | TestThrowOnFailure(hr, L"Failed to register bundle."); | ||
117 | |||
118 | // verify that registration was created | ||
119 | Assert::True(Directory::Exists(cacheDirectory)); | ||
120 | Assert::True(File::Exists(Path::Combine(cacheDirectory, gcnew String(L"setup.exe")))); | ||
121 | |||
122 | Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); | ||
123 | 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))); | ||
124 | |||
125 | // end session | ||
126 | hr = RegistrationSessionEnd(®istration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER); | ||
127 | TestThrowOnFailure(hr, L"Failed to unregister bundle."); | ||
128 | |||
129 | // verify that registration was removed | ||
130 | Assert::False(Directory::Exists(cacheDirectory)); | ||
131 | |||
132 | Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); | ||
133 | Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); | ||
134 | } | ||
135 | finally | ||
136 | { | ||
137 | ReleaseStr(sczCurrentProcess); | ||
138 | ReleaseObject(pixeBundle); | ||
139 | UserExperienceUninitialize(&userExperience); | ||
140 | RegistrationUninitialize(®istration); | ||
141 | VariablesUninitialize(&variables); | ||
142 | |||
143 | Registry::CurrentUser->DeleteSubKeyTree(gcnew String(ROOT_PATH)); | ||
144 | if (Directory::Exists(cacheDirectory)) | ||
145 | { | ||
146 | Directory::Delete(cacheDirectory, true); | ||
147 | } | ||
148 | |||
149 | RegFunctionOverride(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); | ||
150 | } | ||
151 | } | ||
152 | |||
153 | [Fact] | ||
154 | void RegisterArpMinimumTest() | ||
155 | { | ||
156 | HRESULT hr = S_OK; | ||
157 | IXMLDOMElement* pixeBundle = NULL; | ||
158 | LPWSTR sczCurrentProcess = NULL; | ||
159 | BURN_VARIABLES variables = { }; | ||
160 | BURN_USER_EXPERIENCE userExperience = { }; | ||
161 | BOOTSTRAPPER_COMMAND command = { }; | ||
162 | BURN_REGISTRATION registration = { }; | ||
163 | BURN_LOGGING logging = { }; | ||
164 | BURN_PACKAGES packages = { }; | ||
165 | String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}")); | ||
166 | try | ||
167 | { | ||
168 | // set mock API's | ||
169 | RegFunctionOverride(RegistrationTest_RegCreateKeyExW, RegistrationTest_RegOpenKeyExW, RegistrationTest_RegDeleteKeyExW, NULL, NULL, NULL, NULL, NULL, NULL); | ||
170 | |||
171 | Registry::CurrentUser->CreateSubKey(gcnew String(HKCU_PATH)); | ||
172 | |||
173 | logging.sczPath = L"BurnUnitTest.txt"; | ||
174 | |||
175 | LPCWSTR wzDocument = | ||
176 | L"<Bundle>" | ||
177 | L" <UX>" | ||
178 | L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />" | ||
179 | L" </UX>" | ||
180 | 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'>" | ||
181 | L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='Product1' DisplayVersion='1.0.0.0' />" | ||
182 | L" </Registration>" | ||
183 | L"</Bundle>"; | ||
184 | |||
185 | // load XML document | ||
186 | LoadBundleXmlHelper(wzDocument, &pixeBundle); | ||
187 | |||
188 | hr = VariableInitialize(&variables); | ||
189 | TestThrowOnFailure(hr, L"Failed to initialize variables."); | ||
190 | |||
191 | hr = UserExperienceParseFromXml(&userExperience, pixeBundle); | ||
192 | TestThrowOnFailure(hr, L"Failed to parse UX from XML."); | ||
193 | |||
194 | hr = RegistrationParseFromXml(®istration, pixeBundle); | ||
195 | TestThrowOnFailure(hr, L"Failed to parse registration from XML."); | ||
196 | |||
197 | hr = PlanSetResumeCommand(®istration, BOOTSTRAPPER_ACTION_INSTALL, &command, &logging); | ||
198 | TestThrowOnFailure(hr, L"Failed to set registration resume command."); | ||
199 | |||
200 | hr = PathForCurrentProcess(&sczCurrentProcess, NULL); | ||
201 | TestThrowOnFailure(hr, L"Failed to get current process path."); | ||
202 | |||
203 | // | ||
204 | // install | ||
205 | // | ||
206 | |||
207 | // write registration | ||
208 | hr = RegistrationSessionBegin(sczCurrentProcess, ®istration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0); | ||
209 | TestThrowOnFailure(hr, L"Failed to register bundle."); | ||
210 | |||
211 | // verify that registration was created | ||
212 | Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); | ||
213 | 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)); | ||
214 | |||
215 | // complete registration | ||
216 | hr = RegistrationSessionEnd(®istration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER); | ||
217 | TestThrowOnFailure(hr, L"Failed to unregister bundle."); | ||
218 | |||
219 | // verify that registration was updated | ||
220 | Assert::Equal(Int32(BURN_RESUME_MODE_ARP), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); | ||
221 | Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); | ||
222 | Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); | ||
223 | |||
224 | // | ||
225 | // uninstall | ||
226 | // | ||
227 | |||
228 | // write registration | ||
229 | hr = RegistrationSessionBegin(sczCurrentProcess, ®istration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, 0); | ||
230 | TestThrowOnFailure(hr, L"Failed to register bundle."); | ||
231 | |||
232 | // verify that registration was updated | ||
233 | Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); | ||
234 | Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); | ||
235 | 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)); | ||
236 | |||
237 | // delete registration | ||
238 | hr = RegistrationSessionEnd(®istration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER); | ||
239 | TestThrowOnFailure(hr, L"Failed to unregister bundle."); | ||
240 | |||
241 | // verify that registration was removed | ||
242 | Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); | ||
243 | Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); | ||
244 | Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); | ||
245 | } | ||
246 | finally | ||
247 | { | ||
248 | ReleaseStr(sczCurrentProcess); | ||
249 | ReleaseObject(pixeBundle); | ||
250 | UserExperienceUninitialize(&userExperience); | ||
251 | RegistrationUninitialize(®istration); | ||
252 | VariablesUninitialize(&variables); | ||
253 | |||
254 | Registry::CurrentUser->DeleteSubKeyTree(gcnew String(ROOT_PATH)); | ||
255 | if (Directory::Exists(cacheDirectory)) | ||
256 | { | ||
257 | Directory::Delete(cacheDirectory, true); | ||
258 | } | ||
259 | |||
260 | RegFunctionOverride(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); | ||
261 | } | ||
262 | } | ||
263 | |||
264 | [Fact] | ||
265 | void RegisterVariablesTest() | ||
266 | { | ||
267 | HRESULT hr = S_OK; | ||
268 | IXMLDOMElement* pixeBundle = NULL; | ||
269 | LPWSTR sczCurrentProcess = NULL; | ||
270 | BURN_VARIABLES variables = { }; | ||
271 | BURN_USER_EXPERIENCE userExperience = { }; | ||
272 | BOOTSTRAPPER_COMMAND command = { }; | ||
273 | BURN_REGISTRATION registration = { }; | ||
274 | BURN_LOGGING logging = { }; | ||
275 | BURN_PACKAGES packages = { }; | ||
276 | String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}")); | ||
277 | try | ||
278 | { | ||
279 | // set mock API's | ||
280 | RegFunctionOverride(RegistrationTest_RegCreateKeyExW, RegistrationTest_RegOpenKeyExW, RegistrationTest_RegDeleteKeyExW, NULL, NULL, NULL, NULL, NULL, NULL); | ||
281 | |||
282 | Registry::CurrentUser->CreateSubKey(gcnew String(HKCU_PATH)); | ||
283 | |||
284 | logging.sczPath = L"BurnUnitTest.txt"; | ||
285 | |||
286 | LPCWSTR wzDocument = | ||
287 | L"<Bundle>" | ||
288 | L" <UX>" | ||
289 | L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />" | ||
290 | L" </UX>" | ||
291 | 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'>" | ||
292 | L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='Product1' DisplayVersion='1.0.0.0' />" | ||
293 | L" </Registration>" | ||
294 | L"</Bundle>"; | ||
295 | |||
296 | // load XML document | ||
297 | LoadBundleXmlHelper(wzDocument, &pixeBundle); | ||
298 | |||
299 | hr = VariableInitialize(&variables); | ||
300 | TestThrowOnFailure(hr, L"Failed to initialize variables."); | ||
301 | |||
302 | hr = UserExperienceParseFromXml(&userExperience, pixeBundle); | ||
303 | TestThrowOnFailure(hr, L"Failed to parse UX from XML."); | ||
304 | |||
305 | hr = RegistrationParseFromXml(®istration, pixeBundle); | ||
306 | TestThrowOnFailure(hr, L"Failed to parse registration from XML."); | ||
307 | |||
308 | hr = PlanSetResumeCommand(®istration, BOOTSTRAPPER_ACTION_INSTALL, &command, &logging); | ||
309 | TestThrowOnFailure(hr, L"Failed to set registration resume command."); | ||
310 | |||
311 | hr = PathForCurrentProcess(&sczCurrentProcess, NULL); | ||
312 | TestThrowOnFailure(hr, L"Failed to get current process path."); | ||
313 | |||
314 | // | ||
315 | // install | ||
316 | // | ||
317 | |||
318 | // write registration | ||
319 | hr = RegistrationSessionBegin(sczCurrentProcess, ®istration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0); | ||
320 | TestThrowOnFailure(hr, L"Failed to register bundle."); | ||
321 | |||
322 | // verify that registration was created | ||
323 | Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); | ||
324 | 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)); | ||
325 | |||
326 | // complete registration | ||
327 | hr = RegistrationSessionEnd(®istration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER); | ||
328 | TestThrowOnFailure(hr, L"Failed to unregister bundle."); | ||
329 | |||
330 | // verify that registration variables were updated | ||
331 | registration.fInstalled = TRUE; | ||
332 | |||
333 | hr = RegistrationSetVariables(®istration, &variables); | ||
334 | TestThrowOnFailure(hr, L"Failed to set registration variables."); | ||
335 | |||
336 | Assert::Equal(1ll, VariableGetNumericHelper(&variables, BURN_BUNDLE_INSTALLED)); | ||
337 | Assert::Equal(1ll, VariableGetNumericHelper(&variables, BURN_REBOOT_PENDING)); | ||
338 | Assert::Equal<String^>(gcnew String(L"foo"), VariableGetStringHelper(&variables, BURN_BUNDLE_TAG)); | ||
339 | Assert::Equal<String^>(gcnew String(L"bar"), VariableGetStringHelper(&variables, BURN_BUNDLE_PROVIDER_KEY)); | ||
340 | Assert::Equal<String^>(gcnew String(L"1.0.0.0"), VariableGetVersionHelper(&variables, BURN_BUNDLE_VERSION)); | ||
341 | |||
342 | // | ||
343 | // uninstall | ||
344 | // | ||
345 | |||
346 | // delete registration | ||
347 | hr = RegistrationSessionEnd(®istration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER); | ||
348 | TestThrowOnFailure(hr, L"Failed to unregister bundle."); | ||
349 | |||
350 | // verify that registration was removed | ||
351 | Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); | ||
352 | Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); | ||
353 | Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); | ||
354 | } | ||
355 | finally | ||
356 | { | ||
357 | ReleaseStr(sczCurrentProcess); | ||
358 | ReleaseObject(pixeBundle); | ||
359 | UserExperienceUninitialize(&userExperience); | ||
360 | RegistrationUninitialize(®istration); | ||
361 | VariablesUninitialize(&variables); | ||
362 | |||
363 | Registry::CurrentUser->DeleteSubKeyTree(gcnew String(ROOT_PATH)); | ||
364 | if (Directory::Exists(cacheDirectory)) | ||
365 | { | ||
366 | Directory::Delete(cacheDirectory, true); | ||
367 | } | ||
368 | |||
369 | RegFunctionOverride(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); | ||
370 | } | ||
371 | } | ||
372 | |||
373 | [Fact] | ||
374 | void RegisterArpFullTest() | ||
375 | { | ||
376 | HRESULT hr = S_OK; | ||
377 | IXMLDOMElement* pixeBundle = NULL; | ||
378 | LPWSTR sczCurrentProcess = NULL; | ||
379 | BURN_VARIABLES variables = { }; | ||
380 | BURN_USER_EXPERIENCE userExperience = { }; | ||
381 | BOOTSTRAPPER_COMMAND command = { }; | ||
382 | BURN_REGISTRATION registration = { }; | ||
383 | BURN_LOGGING logging = { }; | ||
384 | BURN_PACKAGES packages = { }; | ||
385 | String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}")); | ||
386 | try | ||
387 | { | ||
388 | // set mock API's | ||
389 | RegFunctionOverride(RegistrationTest_RegCreateKeyExW, RegistrationTest_RegOpenKeyExW, RegistrationTest_RegDeleteKeyExW, NULL, NULL, NULL, NULL, NULL, NULL); | ||
390 | |||
391 | Registry::CurrentUser->CreateSubKey(gcnew String(HKCU_PATH)); | ||
392 | |||
393 | logging.sczPath = L"BurnUnitTest.txt"; | ||
394 | |||
395 | LPCWSTR wzDocument = | ||
396 | L"<Bundle>" | ||
397 | L" <UX UxDllPayloadId='ux.dll'>" | ||
398 | L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />" | ||
399 | L" </UX>" | ||
400 | 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'>" | ||
401 | L" <Arp Register='yes' DisplayName='DisplayName1' DisplayVersion='1.2.3.4' Publisher='Publisher1' HelpLink='http://www.microsoft.com/help'" | ||
402 | L" HelpTelephone='555-555-5555' AboutUrl='http://www.microsoft.com/about' UpdateUrl='http://www.microsoft.com/update'" | ||
403 | L" Comments='Comments1' Contact='Contact1' DisableModify='yes' DisableRemove='yes' />" | ||
404 | L" </Registration>" | ||
405 | L"</Bundle>"; | ||
406 | |||
407 | // load XML document | ||
408 | LoadBundleXmlHelper(wzDocument, &pixeBundle); | ||
409 | |||
410 | hr = VariableInitialize(&variables); | ||
411 | TestThrowOnFailure(hr, L"Failed to initialize variables."); | ||
412 | |||
413 | hr = UserExperienceParseFromXml(&userExperience, pixeBundle); | ||
414 | TestThrowOnFailure(hr, L"Failed to parse UX from XML."); | ||
415 | |||
416 | hr = RegistrationParseFromXml(®istration, pixeBundle); | ||
417 | TestThrowOnFailure(hr, L"Failed to parse registration from XML."); | ||
418 | |||
419 | hr = PlanSetResumeCommand(®istration, BOOTSTRAPPER_ACTION_INSTALL, &command, &logging); | ||
420 | TestThrowOnFailure(hr, L"Failed to set registration resume command."); | ||
421 | |||
422 | hr = PathForCurrentProcess(&sczCurrentProcess, NULL); | ||
423 | TestThrowOnFailure(hr, L"Failed to get current process path."); | ||
424 | |||
425 | // | ||
426 | // install | ||
427 | // | ||
428 | |||
429 | // write registration | ||
430 | hr = RegistrationSessionBegin(sczCurrentProcess, ®istration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0); | ||
431 | TestThrowOnFailure(hr, L"Failed to register bundle."); | ||
432 | |||
433 | // verify that registration was created | ||
434 | Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); | ||
435 | 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)); | ||
436 | |||
437 | // finish registration | ||
438 | hr = RegistrationSessionEnd(®istration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER); | ||
439 | TestThrowOnFailure(hr, L"Failed to register bundle."); | ||
440 | |||
441 | // verify that registration was updated | ||
442 | Assert::Equal(Int32(BURN_RESUME_MODE_ARP), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); | ||
443 | Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); | ||
444 | Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); | ||
445 | |||
446 | Assert::Equal<String^>(gcnew String(L"DisplayName1"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayName"), nullptr)); | ||
447 | Assert::Equal<String^>(gcnew String(L"1.2.3.4"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayVersion"), nullptr)); | ||
448 | Assert::Equal<String^>(gcnew String(L"Publisher1"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Publisher"), nullptr)); | ||
449 | Assert::Equal<String^>(gcnew String(L"http://www.microsoft.com/help"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"HelpLink"), nullptr)); | ||
450 | Assert::Equal<String^>(gcnew String(L"555-555-5555"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"HelpTelephone"), nullptr)); | ||
451 | Assert::Equal<String^>(gcnew String(L"http://www.microsoft.com/about"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"URLInfoAbout"), nullptr)); | ||
452 | Assert::Equal<String^>(gcnew String(L"http://www.microsoft.com/update"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"URLUpdateInfo"), nullptr)); | ||
453 | Assert::Equal<String^>(gcnew String(L"Comments1"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Comments"), nullptr)); | ||
454 | Assert::Equal<String^>(gcnew String(L"Contact1"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Contact"), nullptr)); | ||
455 | Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"NoModify"), nullptr)); | ||
456 | Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"NoRemove"), nullptr)); | ||
457 | |||
458 | // | ||
459 | // uninstall | ||
460 | // | ||
461 | |||
462 | // write registration | ||
463 | hr = RegistrationSessionBegin(sczCurrentProcess, ®istration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, 0); | ||
464 | TestThrowOnFailure(hr, L"Failed to register bundle."); | ||
465 | |||
466 | // verify that registration was updated | ||
467 | Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); | ||
468 | 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)); | ||
469 | |||
470 | // delete registration | ||
471 | hr = RegistrationSessionEnd(®istration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER); | ||
472 | TestThrowOnFailure(hr, L"Failed to unregister bundle."); | ||
473 | |||
474 | // verify that registration was removed | ||
475 | Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); | ||
476 | Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); | ||
477 | Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); | ||
478 | } | ||
479 | finally | ||
480 | { | ||
481 | ReleaseStr(sczCurrentProcess); | ||
482 | ReleaseObject(pixeBundle); | ||
483 | UserExperienceUninitialize(&userExperience); | ||
484 | RegistrationUninitialize(®istration); | ||
485 | VariablesUninitialize(&variables); | ||
486 | |||
487 | Registry::CurrentUser->DeleteSubKeyTree(gcnew String(ROOT_PATH)); | ||
488 | if (Directory::Exists(cacheDirectory)) | ||
489 | { | ||
490 | Directory::Delete(cacheDirectory, true); | ||
491 | } | ||
492 | |||
493 | RegFunctionOverride(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); | ||
494 | } | ||
495 | } | ||
496 | |||
497 | [Fact(Skip = "Currently fails")] | ||
498 | void ResumeTest() | ||
499 | { | ||
500 | HRESULT hr = S_OK; | ||
501 | IXMLDOMElement* pixeBundle = NULL; | ||
502 | LPWSTR sczCurrentProcess = NULL; | ||
503 | BURN_VARIABLES variables = { }; | ||
504 | BURN_USER_EXPERIENCE userExperience = { }; | ||
505 | BOOTSTRAPPER_COMMAND command = { }; | ||
506 | BURN_REGISTRATION registration = { }; | ||
507 | BURN_LOGGING logging = { }; | ||
508 | BURN_PACKAGES packages = { }; | ||
509 | BYTE rgbData[256] = { }; | ||
510 | BOOTSTRAPPER_RESUME_TYPE resumeType = BOOTSTRAPPER_RESUME_TYPE_NONE; | ||
511 | BYTE* pbBuffer = NULL; | ||
512 | SIZE_T cbBuffer = 0; | ||
513 | String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}")); | ||
514 | try | ||
515 | { | ||
516 | for (DWORD i = 0; i < 256; ++i) | ||
517 | { | ||
518 | rgbData[i] = (BYTE)i; | ||
519 | } | ||
520 | |||
521 | // set mock API's | ||
522 | RegFunctionOverride(RegistrationTest_RegCreateKeyExW, RegistrationTest_RegOpenKeyExW, RegistrationTest_RegDeleteKeyExW, NULL, NULL, NULL, NULL, NULL, NULL); | ||
523 | |||
524 | Registry::CurrentUser->CreateSubKey(gcnew String(HKCU_PATH)); | ||
525 | |||
526 | logging.sczPath = L"BurnUnitTest.txt"; | ||
527 | |||
528 | LPCWSTR wzDocument = | ||
529 | L"<Bundle>" | ||
530 | L" <UX>" | ||
531 | L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />" | ||
532 | L" </UX>" | ||
533 | 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'>" | ||
534 | L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='RegisterBasicTest' DisplayVersion='1.0.0.0' />" | ||
535 | L" </Registration>" | ||
536 | L"</Bundle>"; | ||
537 | |||
538 | // load XML document | ||
539 | LoadBundleXmlHelper(wzDocument, &pixeBundle); | ||
540 | |||
541 | hr = VariableInitialize(&variables); | ||
542 | TestThrowOnFailure(hr, L"Failed to initialize variables."); | ||
543 | |||
544 | hr = UserExperienceParseFromXml(&userExperience, pixeBundle); | ||
545 | TestThrowOnFailure(hr, L"Failed to parse UX from XML."); | ||
546 | |||
547 | hr = RegistrationParseFromXml(®istration, pixeBundle); | ||
548 | TestThrowOnFailure(hr, L"Failed to parse registration from XML."); | ||
549 | |||
550 | hr = PlanSetResumeCommand(®istration, BOOTSTRAPPER_ACTION_INSTALL, &command, &logging); | ||
551 | TestThrowOnFailure(hr, L"Failed to set registration resume command."); | ||
552 | |||
553 | hr = PathForCurrentProcess(&sczCurrentProcess, NULL); | ||
554 | TestThrowOnFailure(hr, L"Failed to get current process path."); | ||
555 | |||
556 | // read resume type before session | ||
557 | hr = RegistrationDetectResumeType(®istration, &resumeType); | ||
558 | TestThrowOnFailure(hr, L"Failed to read resume type."); | ||
559 | |||
560 | Assert::Equal((int)BOOTSTRAPPER_RESUME_TYPE_NONE, (int)resumeType); | ||
561 | |||
562 | // begin session | ||
563 | hr = RegistrationSessionBegin(sczCurrentProcess, ®istration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0); | ||
564 | TestThrowOnFailure(hr, L"Failed to register bundle."); | ||
565 | |||
566 | hr = RegistrationSaveState(®istration, rgbData, sizeof(rgbData)); | ||
567 | TestThrowOnFailure(hr, L"Failed to save state."); | ||
568 | |||
569 | // read interrupted resume type | ||
570 | hr = RegistrationDetectResumeType(®istration, &resumeType); | ||
571 | TestThrowOnFailure(hr, L"Failed to read interrupted resume type."); | ||
572 | |||
573 | Assert::Equal((int)BOOTSTRAPPER_RESUME_TYPE_INTERRUPTED, (int)resumeType); | ||
574 | |||
575 | // suspend session | ||
576 | hr = RegistrationSessionEnd(®istration, &variables, &packages, BURN_RESUME_MODE_SUSPEND, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER); | ||
577 | TestThrowOnFailure(hr, L"Failed to suspend session."); | ||
578 | |||
579 | // verify that run key was removed | ||
580 | Assert::Equal((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); | ||
581 | |||
582 | // read suspend resume type | ||
583 | hr = RegistrationDetectResumeType(®istration, &resumeType); | ||
584 | TestThrowOnFailure(hr, L"Failed to read suspend resume type."); | ||
585 | |||
586 | Assert::Equal((int)BOOTSTRAPPER_RESUME_TYPE_SUSPEND, (int)resumeType); | ||
587 | |||
588 | // read state back | ||
589 | hr = RegistrationLoadState(®istration, &pbBuffer, &cbBuffer); | ||
590 | TestThrowOnFailure(hr, L"Failed to load state."); | ||
591 | |||
592 | Assert::Equal((SIZE_T)sizeof(rgbData), cbBuffer); | ||
593 | Assert::True(0 == memcmp(pbBuffer, rgbData, sizeof(rgbData))); | ||
594 | |||
595 | // write active resume mode | ||
596 | hr = RegistrationSessionResume(®istration, &variables); | ||
597 | TestThrowOnFailure(hr, L"Failed to write active resume mode."); | ||
598 | |||
599 | // verify that run key was put back | ||
600 | Assert::NotEqual((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)); | ||
601 | |||
602 | // end session | ||
603 | hr = RegistrationSessionEnd(®istration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER); | ||
604 | TestThrowOnFailure(hr, L"Failed to unregister bundle."); | ||
605 | |||
606 | // read resume type after session | ||
607 | hr = RegistrationDetectResumeType(®istration, &resumeType); | ||
608 | TestThrowOnFailure(hr, L"Failed to read resume type."); | ||
609 | |||
610 | Assert::Equal((int)BOOTSTRAPPER_RESUME_TYPE_NONE, (int)resumeType); | ||
611 | } | ||
612 | finally | ||
613 | { | ||
614 | ReleaseStr(sczCurrentProcess); | ||
615 | ReleaseObject(pixeBundle); | ||
616 | UserExperienceUninitialize(&userExperience); | ||
617 | RegistrationUninitialize(®istration); | ||
618 | VariablesUninitialize(&variables); | ||
619 | |||
620 | Registry::CurrentUser->DeleteSubKeyTree(gcnew String(ROOT_PATH)); | ||
621 | if (Directory::Exists(cacheDirectory)) | ||
622 | { | ||
623 | Directory::Delete(cacheDirectory, true); | ||
624 | } | ||
625 | |||
626 | RegFunctionOverride(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); | ||
627 | } | ||
628 | } | ||
629 | |||
630 | //BOOTSTRAPPER_RESUME_TYPE_NONE, | ||
631 | //BOOTSTRAPPER_RESUME_TYPE_INVALID, // resume information is present but invalid | ||
632 | //BOOTSTRAPPER_RESUME_TYPE_UNEXPECTED, // relaunched after an unexpected interruption | ||
633 | //BOOTSTRAPPER_RESUME_TYPE_REBOOT_PENDING, // reboot has not taken place yet | ||
634 | //BOOTSTRAPPER_RESUME_TYPE_REBOOT, // relaunched after reboot | ||
635 | //BOOTSTRAPPER_RESUME_TYPE_SUSPEND, // relaunched after suspend | ||
636 | //BOOTSTRAPPER_RESUME_TYPE_ARP, // launched from ARP | ||
637 | }; | ||
638 | } | ||
639 | } | ||
640 | } | ||
641 | } | ||
642 | } | ||
643 | |||
644 | |||
645 | static LSTATUS APIENTRY RegistrationTest_RegCreateKeyExW( | ||
646 | __in HKEY hKey, | ||
647 | __in LPCWSTR lpSubKey, | ||
648 | __reserved DWORD Reserved, | ||
649 | __in_opt LPWSTR lpClass, | ||
650 | __in DWORD dwOptions, | ||
651 | __in REGSAM samDesired, | ||
652 | __in_opt CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, | ||
653 | __out PHKEY phkResult, | ||
654 | __out_opt LPDWORD lpdwDisposition | ||
655 | ) | ||
656 | { | ||
657 | LSTATUS ls = ERROR_SUCCESS; | ||
658 | LPCWSTR wzRoot = NULL; | ||
659 | HKEY hkRoot = NULL; | ||
660 | |||
661 | if (HKEY_LOCAL_MACHINE == hKey) | ||
662 | { | ||
663 | wzRoot = HKLM_PATH; | ||
664 | } | ||
665 | else if (HKEY_CURRENT_USER == hKey) | ||
666 | { | ||
667 | wzRoot = HKCU_PATH; | ||
668 | } | ||
669 | else | ||
670 | { | ||
671 | hkRoot = hKey; | ||
672 | } | ||
673 | |||
674 | if (wzRoot) | ||
675 | { | ||
676 | ls = ::RegOpenKeyExW(HKEY_CURRENT_USER, wzRoot, 0, KEY_WRITE, &hkRoot); | ||
677 | if (ERROR_SUCCESS != ls) | ||
678 | { | ||
679 | ExitFunction(); | ||
680 | } | ||
681 | } | ||
682 | |||
683 | ls = ::RegCreateKeyExW(hkRoot, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition); | ||
684 | |||
685 | LExit: | ||
686 | ReleaseRegKey(hkRoot); | ||
687 | |||
688 | return ls; | ||
689 | } | ||
690 | |||
691 | static LSTATUS APIENTRY RegistrationTest_RegOpenKeyExW( | ||
692 | __in HKEY hKey, | ||
693 | __in_opt LPCWSTR lpSubKey, | ||
694 | __reserved DWORD ulOptions, | ||
695 | __in REGSAM samDesired, | ||
696 | __out PHKEY phkResult | ||
697 | ) | ||
698 | { | ||
699 | LSTATUS ls = ERROR_SUCCESS; | ||
700 | LPCWSTR wzRoot = NULL; | ||
701 | HKEY hkRoot = NULL; | ||
702 | |||
703 | if (HKEY_LOCAL_MACHINE == hKey) | ||
704 | { | ||
705 | wzRoot = HKLM_PATH; | ||
706 | } | ||
707 | else if (HKEY_CURRENT_USER == hKey) | ||
708 | { | ||
709 | wzRoot = HKCU_PATH; | ||
710 | } | ||
711 | else | ||
712 | { | ||
713 | hkRoot = hKey; | ||
714 | } | ||
715 | |||
716 | if (wzRoot) | ||
717 | { | ||
718 | ls = ::RegOpenKeyExW(HKEY_CURRENT_USER, wzRoot, 0, KEY_WRITE, &hkRoot); | ||
719 | if (ERROR_SUCCESS != ls) | ||
720 | { | ||
721 | ExitFunction(); | ||
722 | } | ||
723 | } | ||
724 | |||
725 | ls = ::RegOpenKeyExW(hkRoot, lpSubKey, ulOptions, samDesired, phkResult); | ||
726 | |||
727 | LExit: | ||
728 | ReleaseRegKey(hkRoot); | ||
729 | |||
730 | return ls; | ||
731 | } | ||
732 | |||
733 | static LSTATUS APIENTRY RegistrationTest_RegDeleteKeyExW( | ||
734 | __in HKEY hKey, | ||
735 | __in LPCWSTR lpSubKey, | ||
736 | __in REGSAM samDesired, | ||
737 | __reserved DWORD Reserved | ||
738 | ) | ||
739 | { | ||
740 | LSTATUS ls = ERROR_SUCCESS; | ||
741 | LPCWSTR wzRoot = NULL; | ||
742 | HKEY hkRoot = NULL; | ||
743 | |||
744 | if (HKEY_LOCAL_MACHINE == hKey) | ||
745 | { | ||
746 | wzRoot = HKLM_PATH; | ||
747 | } | ||
748 | else if (HKEY_CURRENT_USER == hKey) | ||
749 | { | ||
750 | wzRoot = HKCU_PATH; | ||
751 | } | ||
752 | else | ||
753 | { | ||
754 | hkRoot = hKey; | ||
755 | } | ||
756 | |||
757 | if (wzRoot) | ||
758 | { | ||
759 | ls = ::RegOpenKeyExW(HKEY_CURRENT_USER, wzRoot, 0, KEY_WRITE | samDesired, &hkRoot); | ||
760 | if (ERROR_SUCCESS != ls) | ||
761 | { | ||
762 | ExitFunction(); | ||
763 | } | ||
764 | } | ||
765 | |||
766 | ls = ::RegDeleteKeyExW(hkRoot, lpSubKey, samDesired, Reserved); | ||
767 | |||
768 | LExit: | ||
769 | ReleaseRegKey(hkRoot); | ||
770 | |||
771 | return ls; | ||
772 | } | ||