OLD | NEW |
| (Empty) |
1 // Copyright 2003-2009 Google Inc. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 // ======================================================================== | |
15 | |
16 #include "omaha/base/reg_key.h" | |
17 #include "omaha/base/debug.h" | |
18 #include "omaha/base/utils.h" | |
19 #include "omaha/testing/unit_test.h" | |
20 | |
21 namespace omaha { | |
22 | |
23 #define kStTestRkeyRelativeBase _T("Software\\") SHORT_COMPANY_NAME _T("\\") P
RODUCT_NAME _T("\\UnitTest") | |
24 #define kStTestRkeyBase _T("HKCU\\") kStTestRkeyRelativeBase | |
25 #define kStRkey1Name _T("TEST") | |
26 #define kStRkey1 kStTestRkeyBase _T("\\") kStRkey1Name | |
27 #define kRkey1 kStTestRkeyRelativeBase _T("\\") kStRkey1Name | |
28 #define kStRkey2 kStTestRkeyBase _T("\\TEST2") | |
29 #define kStRkey3 kStTestRkeyBase _T("\\TEST3") | |
30 #define kRkey1SubkeyName _T("subkey_test") | |
31 #define kRkey1Subkey kRkey1 _T("\\") kRkey1SubkeyName | |
32 #define kStRkey1Subkey kStRkey1 _T("\\") kRkey1SubkeyName | |
33 | |
34 // NON - STATIC | |
35 | |
36 #define kValNameInt _T("Int32 Value") | |
37 #define kRenameValNameInt _T("Renamed Int32 Value") | |
38 #define kIntVal (DWORD)20 | |
39 #define kIntVal2 (DWORD)30 | |
40 | |
41 #define kValNameInt64 _T("Int64 Value") | |
42 #define kIntVal64 (DWORD64)40 | |
43 #define kIntVal642 (DWORD64)50 | |
44 | |
45 #define kValNameStr _T("Str Value") | |
46 #define kStrVal _T("Some string data 1") | |
47 #define kStrVal2 _T("Some string data 2") | |
48 | |
49 #define kValNameBinary _T("Binary Value") | |
50 #define kBinaryVal "Some binary data abcdefghi 1" | |
51 #define kBinaryVal2 "Some binary data abcdefghi 2" | |
52 | |
53 // STATIC | |
54 | |
55 #define kStValNameInt _T("Static Int32 Value") | |
56 #define kStIntVal (DWORD)60 | |
57 | |
58 #define kStValNameInt64 _T("Static Int64 Value") | |
59 #define kStIntVal64 (DWORD64)80 | |
60 | |
61 #define kStValNameFloat _T("Static Float Value") | |
62 #define kStFloatVal (static_cast<float>(12.3456789)) | |
63 | |
64 #define kStValNameDouble _T("Static Double Value") | |
65 #define kStDoubleVal (static_cast<double>(98.7654321)) | |
66 | |
67 #define kStValNameStr _T("Static Str Value") | |
68 #define kRenameStValNameStr _T("Renamed Static Str Value") | |
69 #define kStStrVal _T("Some static string data 2") | |
70 | |
71 #define kStValNameBinary _T("Static Binary Value") | |
72 #define kStBinaryVal "Some static binary data abcdefghi 2" | |
73 | |
74 // Test the private member functions of RegKey | |
75 class RegKeyTestClass : public testing::Test { | |
76 protected: | |
77 static const HKEY GetHKey(const RegKey& reg) { | |
78 return reg.h_key_; | |
79 } | |
80 | |
81 static CString GetParentKeyInfo(CString* key_name) { | |
82 return RegKey::GetParentKeyInfo(key_name); | |
83 } | |
84 }; | |
85 | |
86 class RegKeyCleanupTestKeyTest : public testing::Test { | |
87 protected: | |
88 virtual void SetUp() { | |
89 EXPECT_SUCCEEDED(RegKey::DeleteKey(kStTestRkeyBase)); | |
90 } | |
91 | |
92 virtual void TearDown() { | |
93 EXPECT_SUCCEEDED(RegKey::DeleteKey(kStTestRkeyBase)); | |
94 } | |
95 | |
96 RegKey key_; | |
97 }; | |
98 | |
99 // Make sure the RegKey is nice and clean when we first initialize it | |
100 TEST_F(RegKeyTestClass, Init) { | |
101 // Make a new RegKey object so we can test its pristine state | |
102 RegKey reg; | |
103 | |
104 ASSERT_TRUE(GetHKey(reg) == NULL); | |
105 } | |
106 | |
107 // Make sure the helper functions work | |
108 TEST_F(RegKeyTestClass, Helper) { | |
109 // Dud items cause NULL | |
110 CString temp_key; | |
111 | |
112 // RegKey::GetRootKeyInfo turns a string into the HKEY and subtree value | |
113 | |
114 // Try out some dud values | |
115 temp_key = _T(""); | |
116 ASSERT_TRUE(RegKey::GetRootKeyInfo(&temp_key) == NULL); | |
117 ASSERT_STREQ(temp_key, _T("")); | |
118 | |
119 temp_key = _T("a"); | |
120 ASSERT_TRUE(RegKey::GetRootKeyInfo(&temp_key) == NULL); | |
121 ASSERT_STREQ(temp_key, _T("")); | |
122 | |
123 // The basics | |
124 temp_key = _T("HKLM\\a"); | |
125 ASSERT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_LOCAL_MACHINE); | |
126 ASSERT_STREQ(temp_key, _T("a")); | |
127 | |
128 temp_key = _T("HKEY_LOCAL_MACHINE\\a"); | |
129 ASSERT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_LOCAL_MACHINE); | |
130 ASSERT_STREQ(temp_key, _T("a")); | |
131 | |
132 temp_key = _T("HKCU\\a"); | |
133 ASSERT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CURRENT_USER); | |
134 ASSERT_STREQ(temp_key, _T("a")); | |
135 | |
136 temp_key = _T("HKEY_CURRENT_USER\\a"); | |
137 ASSERT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CURRENT_USER); | |
138 ASSERT_STREQ(temp_key, _T("a")); | |
139 | |
140 temp_key = _T("HKU\\a"); | |
141 ASSERT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_USERS); | |
142 ASSERT_STREQ(temp_key, _T("a")); | |
143 | |
144 temp_key = _T("HKEY_USERS\\a"); | |
145 ASSERT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_USERS); | |
146 ASSERT_STREQ(temp_key, _T("a")); | |
147 | |
148 temp_key = _T("HKCR\\a"); | |
149 ASSERT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT); | |
150 ASSERT_STREQ(temp_key, _T("a")); | |
151 | |
152 temp_key = _T("HKEY_CLASSES_ROOT\\a"); | |
153 ASSERT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT); | |
154 ASSERT_STREQ(temp_key, _T("a")); | |
155 | |
156 // Make sure it is case insensitive | |
157 temp_key = _T("hkcr\\a"); | |
158 ASSERT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT); | |
159 ASSERT_STREQ(temp_key, _T("a")); | |
160 | |
161 temp_key = _T("hkey_CLASSES_ROOT\\a"); | |
162 ASSERT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT); | |
163 ASSERT_STREQ(temp_key, _T("a")); | |
164 | |
165 // Test out temp_GetParentKeyInfo | |
166 | |
167 // dud cases | |
168 temp_key = _T(""); | |
169 ASSERT_STREQ(GetParentKeyInfo(&temp_key), _T("")); | |
170 ASSERT_STREQ(temp_key, _T("")); | |
171 | |
172 temp_key = _T("a"); | |
173 ASSERT_STREQ(GetParentKeyInfo(&temp_key), _T("")); | |
174 ASSERT_STREQ(temp_key, _T("a")); | |
175 | |
176 temp_key = _T("a\\b"); | |
177 ASSERT_STREQ(GetParentKeyInfo(&temp_key), _T("a")); | |
178 ASSERT_STREQ(temp_key, _T("b")); | |
179 | |
180 temp_key = _T("\\b"); | |
181 ASSERT_STREQ(GetParentKeyInfo(&temp_key), _T("")); | |
182 ASSERT_STREQ(temp_key, _T("b")); | |
183 | |
184 | |
185 // Some regular cases | |
186 temp_key = _T("HKEY_CLASSES_ROOT\\moon"); | |
187 ASSERT_STREQ(GetParentKeyInfo(&temp_key), _T("HKEY_CLASSES_ROOT")); | |
188 ASSERT_STREQ(temp_key, _T("moon")); | |
189 | |
190 temp_key = _T("HKEY_CLASSES_ROOT\\moon\\doggy"); | |
191 ASSERT_STREQ(GetParentKeyInfo(&temp_key), | |
192 _T("HKEY_CLASSES_ROOT\\moon")); | |
193 ASSERT_STREQ(temp_key, _T("doggy")); | |
194 } | |
195 | |
196 | |
197 TEST(RegKeyTest, RegKey) { | |
198 // | |
199 // PRIVATE MEMBER WHITE BOX TESTS | |
200 // | |
201 RegKeyWithChangeEvent r_key; | |
202 bool bool_res = false; | |
203 HRESULT hr = E_FAIL; | |
204 DWORD int_val = 0; | |
205 DWORD64 int64_val = 0; | |
206 time64 t = 0; | |
207 float float_val = 0; | |
208 double double_val = 0; | |
209 TCHAR * str_val = NULL; | |
210 byte * binary_val = NULL; | |
211 DWORD byte_count = 0; | |
212 | |
213 // Just in case... | |
214 // make sure the no test key residue is left from previous aborted runs | |
215 hr = RegKey::DeleteKey(kStTestRkeyBase); | |
216 | |
217 // first test the non-static version | |
218 | |
219 // create a reg key | |
220 hr = r_key.Create(HKEY_CURRENT_USER, kRkey1); | |
221 ASSERT_SUCCEEDED(hr); | |
222 | |
223 // do the create twice - it should return the already created one | |
224 hr = r_key.Create(HKEY_CURRENT_USER, kRkey1); | |
225 ASSERT_SUCCEEDED(hr); | |
226 | |
227 // now do an open - should work just fine | |
228 hr = r_key.Open(HKEY_CURRENT_USER, kRkey1); | |
229 ASSERT_SUCCEEDED(hr); | |
230 | |
231 // get an in-existent value | |
232 hr = r_key.GetValue(kValNameInt, &int_val); | |
233 ASSERT_EQ(hr, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)); | |
234 | |
235 // get an in-existent value type | |
236 DWORD value_type = REG_NONE; | |
237 hr = r_key.GetValueType(kValNameInt, &value_type); | |
238 ASSERT_EQ(hr, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)); | |
239 | |
240 // set-up an event to watch for changes | |
241 hr = r_key.SetupEvent(TRUE, | |
242 REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET); | |
243 ASSERT_SUCCEEDED(hr); | |
244 HANDLE change_event = r_key.change_event(); | |
245 ASSERT_EQ(::WaitForSingleObject(change_event, 0), WAIT_TIMEOUT); | |
246 | |
247 // set and get some values and verify that the handle gets signaled | |
248 | |
249 // set an INT 32 | |
250 hr = r_key.SetValue(kValNameInt, kIntVal); | |
251 ASSERT_SUCCEEDED(hr); | |
252 | |
253 hr = r_key.GetValueType(kValNameInt, &value_type); | |
254 ASSERT_SUCCEEDED(hr); | |
255 ASSERT_EQ(REG_DWORD, value_type); | |
256 hr = RegKey::GetValueType(kStRkey1, kValNameInt, &value_type); | |
257 ASSERT_SUCCEEDED(hr); | |
258 ASSERT_EQ(REG_DWORD, value_type); | |
259 | |
260 // verify that we got the change and that the event got reset appropriately | |
261 // and set-up the notification again (use the actual event this time) | |
262 ASSERT_EQ(::WaitForSingleObject(change_event, 0), WAIT_OBJECT_0); | |
263 hr = r_key.SetupEvent(TRUE, | |
264 REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET); | |
265 ASSERT_SUCCEEDED(hr); | |
266 ASSERT_FALSE(r_key.HasChangeOccurred()); | |
267 | |
268 // check that the value exists | |
269 bool_res = r_key.HasValue(kValNameInt); | |
270 ASSERT_TRUE(bool_res); | |
271 // No change expected on a read | |
272 ASSERT_FALSE(r_key.HasChangeOccurred()); | |
273 | |
274 // read it back | |
275 hr = r_key.GetValue(kValNameInt, &int_val); | |
276 ASSERT_SUCCEEDED(hr); | |
277 ASSERT_EQ(int_val, kIntVal); | |
278 // No change expected on a read | |
279 ASSERT_FALSE(r_key.HasChangeOccurred()); | |
280 | |
281 // set it again! | |
282 hr = r_key.SetValue(kValNameInt, kIntVal2); | |
283 ASSERT_SUCCEEDED(hr); | |
284 // verify that we got the change and that the event got reset appropriately | |
285 // and set-up the notification again | |
286 ASSERT_TRUE(r_key.HasChangeOccurred()); | |
287 hr = r_key.SetupEvent(TRUE, | |
288 REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET); | |
289 ASSERT_SUCCEEDED(hr); | |
290 ASSERT_FALSE(r_key.HasChangeOccurred()); | |
291 | |
292 // read it again | |
293 hr = r_key.GetValue(kValNameInt, &int_val); | |
294 ASSERT_SUCCEEDED(hr); | |
295 ASSERT_EQ(int_val, kIntVal2); | |
296 // No change expected on a read | |
297 ASSERT_FALSE(r_key.HasChangeOccurred()); | |
298 | |
299 // delete the value | |
300 hr = r_key.DeleteValue(kValNameInt); | |
301 ASSERT_SUCCEEDED(hr); | |
302 // verify that we got the change | |
303 ASSERT_TRUE(r_key.HasChangeOccurred()); | |
304 | |
305 // check that the value is gone | |
306 bool_res = r_key.HasValue(kValNameInt); | |
307 ASSERT_FALSE(bool_res); | |
308 | |
309 // set an INT 64 | |
310 hr = r_key.SetValue(kValNameInt64, kIntVal64); | |
311 ASSERT_SUCCEEDED(hr); | |
312 | |
313 // check that the value exists | |
314 bool_res = r_key.HasValue(kValNameInt64); | |
315 ASSERT_TRUE(bool_res); | |
316 | |
317 // read it back | |
318 hr = r_key.GetValue(kValNameInt64, &int64_val); | |
319 ASSERT_SUCCEEDED(hr); | |
320 ASSERT_EQ(int64_val, kIntVal64); | |
321 | |
322 // delete the value | |
323 hr = r_key.DeleteValue(kValNameInt64); | |
324 ASSERT_SUCCEEDED(hr); | |
325 | |
326 // check that the value is gone | |
327 bool_res = r_key.HasValue(kValNameInt64); | |
328 ASSERT_FALSE(bool_res); | |
329 | |
330 // set a string | |
331 hr = r_key.SetValue(kValNameStr, kStrVal); | |
332 ASSERT_SUCCEEDED(hr); | |
333 | |
334 // check that the value exists | |
335 bool_res = r_key.HasValue(kValNameStr); | |
336 ASSERT_TRUE(bool_res); | |
337 | |
338 // read it back | |
339 hr = r_key.GetValue(kValNameStr, &str_val); | |
340 ASSERT_SUCCEEDED(hr); | |
341 ASSERT_STREQ(str_val, kStrVal); | |
342 delete [] str_val; | |
343 | |
344 // set it again | |
345 hr = r_key.SetValue(kValNameStr, kStrVal2); | |
346 ASSERT_SUCCEEDED(hr); | |
347 | |
348 // read it again | |
349 hr = r_key.GetValue(kValNameStr, &str_val); | |
350 ASSERT_SUCCEEDED(hr); | |
351 ASSERT_STREQ(str_val, kStrVal2); | |
352 delete [] str_val; | |
353 | |
354 // delete the value | |
355 hr = r_key.DeleteValue(kValNameStr); | |
356 ASSERT_SUCCEEDED(hr); | |
357 | |
358 // check that the value is gone | |
359 bool_res = r_key.HasValue(kValNameInt); | |
360 ASSERT_FALSE(bool_res); | |
361 | |
362 // set a binary value | |
363 hr = r_key.SetValue(kValNameBinary, (const byte *)kBinaryVal, | |
364 sizeof(kBinaryVal)-1); | |
365 ASSERT_SUCCEEDED(hr); | |
366 | |
367 // check that the value exists | |
368 bool_res = r_key.HasValue(kValNameBinary); | |
369 ASSERT_TRUE(bool_res); | |
370 | |
371 // read it back | |
372 hr = r_key.GetValue(kValNameBinary, &binary_val, &byte_count); | |
373 ASSERT_SUCCEEDED(hr); | |
374 ASSERT_EQ(0, memcmp(binary_val, kBinaryVal, sizeof(kBinaryVal)-1)); | |
375 delete [] binary_val; | |
376 | |
377 // set it again | |
378 hr = r_key.SetValue(kValNameBinary, (const byte *)kBinaryVal2, | |
379 sizeof(kBinaryVal)-1); | |
380 ASSERT_SUCCEEDED(hr); | |
381 | |
382 // read it again | |
383 hr = r_key.GetValue(kValNameBinary, &binary_val, &byte_count); | |
384 ASSERT_SUCCEEDED(hr); | |
385 ASSERT_EQ(0, memcmp(binary_val, kBinaryVal2, sizeof(kBinaryVal2)-1)); | |
386 delete [] binary_val; | |
387 | |
388 // delete the value | |
389 hr = r_key.DeleteValue(kValNameBinary); | |
390 ASSERT_SUCCEEDED(hr); | |
391 | |
392 // check that the value is gone | |
393 bool_res = r_key.HasValue(kValNameBinary); | |
394 ASSERT_FALSE(bool_res); | |
395 | |
396 // set some values and check the total count | |
397 | |
398 // set an INT 32 | |
399 hr = r_key.SetValue(kValNameInt, kIntVal); | |
400 ASSERT_SUCCEEDED(hr); | |
401 | |
402 // set an INT 64 | |
403 hr = r_key.SetValue(kValNameInt64, kIntVal64); | |
404 ASSERT_SUCCEEDED(hr); | |
405 | |
406 // set a string | |
407 hr = r_key.SetValue(kValNameStr, kStrVal); | |
408 ASSERT_SUCCEEDED(hr); | |
409 | |
410 hr = r_key.GetValueType(kValNameStr, &value_type); | |
411 ASSERT_SUCCEEDED(hr); | |
412 ASSERT_EQ(REG_SZ, value_type); | |
413 hr = RegKey::GetValueType(kStRkey1, kValNameStr, &value_type); | |
414 ASSERT_SUCCEEDED(hr); | |
415 ASSERT_EQ(REG_SZ, value_type); | |
416 | |
417 // set a binary value | |
418 hr = r_key.SetValue(kValNameBinary, (const byte *)kBinaryVal, | |
419 sizeof(kBinaryVal)-1); | |
420 ASSERT_SUCCEEDED(hr); | |
421 | |
422 // get the value count | |
423 uint32 value_count = r_key.GetValueCount(); | |
424 ASSERT_EQ(value_count, 4); | |
425 | |
426 // check the value names | |
427 CString value_name; | |
428 DWORD type; | |
429 | |
430 hr = r_key.GetValueNameAt(0, &value_name, &type); | |
431 ASSERT_SUCCEEDED(hr); | |
432 ASSERT_EQ(value_name, kValNameInt); | |
433 ASSERT_EQ(type, REG_DWORD); | |
434 | |
435 hr = r_key.GetValueNameAt(1, &value_name, &type); | |
436 ASSERT_SUCCEEDED(hr); | |
437 ASSERT_EQ(value_name, kValNameInt64); | |
438 ASSERT_EQ(type, REG_QWORD); | |
439 | |
440 hr = r_key.GetValueNameAt(2, &value_name, &type); | |
441 ASSERT_SUCCEEDED(hr); | |
442 ASSERT_EQ(value_name, kValNameStr); | |
443 ASSERT_EQ(type, REG_SZ); | |
444 | |
445 hr = r_key.GetValueNameAt(3, &value_name, &type); | |
446 ASSERT_SUCCEEDED(hr); | |
447 ASSERT_EQ(value_name, kValNameBinary); | |
448 ASSERT_EQ(type, REG_BINARY); | |
449 | |
450 // check that there are no more values | |
451 hr = r_key.GetValueNameAt(4, &value_name, &type); | |
452 ASSERT_FAILED(hr); | |
453 | |
454 uint32 subkey_count = r_key.GetSubkeyCount(); | |
455 ASSERT_EQ(subkey_count, 0); | |
456 | |
457 RegKey temp_key; | |
458 | |
459 // now create a subkey and make sure we can get the name | |
460 hr = temp_key.Create(HKEY_CURRENT_USER, kRkey1Subkey); | |
461 ASSERT_SUCCEEDED(hr); | |
462 | |
463 // check the subkey exists | |
464 bool_res = r_key.HasSubkey(kRkey1SubkeyName); | |
465 ASSERT_TRUE(bool_res); | |
466 | |
467 // check the name | |
468 subkey_count = r_key.GetSubkeyCount(); | |
469 ASSERT_EQ(subkey_count, 1); | |
470 | |
471 CString subkey_name; | |
472 hr = r_key.GetSubkeyNameAt(0, &subkey_name); | |
473 ASSERT_EQ(subkey_name, kRkey1SubkeyName); | |
474 | |
475 // verify that the event handle remained the same throughout everything | |
476 ASSERT_EQ(change_event, r_key.change_event()); | |
477 | |
478 // close this key | |
479 r_key.Close(); | |
480 | |
481 // whack the whole key | |
482 hr = RegKey::DeleteKey(kStTestRkeyBase); | |
483 ASSERT_SUCCEEDED(hr); | |
484 | |
485 // STATIC | |
486 // now set a different value using the static versions | |
487 | |
488 // get an in-existent value from an un-existent key | |
489 hr = RegKey::GetValue(kStRkey1, kStValNameInt, &int_val); | |
490 ASSERT_EQ(hr, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)); | |
491 | |
492 // set int32 | |
493 hr = RegKey::SetValue(kStRkey1, kStValNameInt, kStIntVal); | |
494 ASSERT_SUCCEEDED(hr); | |
495 | |
496 // check that the value exists | |
497 bool_res = RegKey::HasValue(kStRkey1, kStValNameInt); | |
498 ASSERT_TRUE(bool_res); | |
499 | |
500 // get an in-existent value from an existent key | |
501 hr = RegKey::GetValue(kStRkey1, _T("bogus"), &int_val); | |
502 ASSERT_EQ(hr, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)); | |
503 | |
504 // read it back | |
505 hr = RegKey::GetValue(kStRkey1, kStValNameInt, &int_val); | |
506 ASSERT_SUCCEEDED(hr); | |
507 ASSERT_EQ(int_val, kStIntVal); | |
508 | |
509 // delete the value | |
510 hr = RegKey::DeleteValue(kStRkey1, kStValNameInt); | |
511 ASSERT_SUCCEEDED(hr); | |
512 | |
513 // check that the value is gone | |
514 bool_res = RegKey::HasValue(kStRkey1, kStValNameInt); | |
515 ASSERT_FALSE(bool_res); | |
516 | |
517 | |
518 // set int64 | |
519 hr = RegKey::SetValue(kStRkey1, kStValNameInt64, kStIntVal64); | |
520 ASSERT_SUCCEEDED(hr); | |
521 | |
522 // check that the value exists | |
523 bool_res = RegKey::HasValue(kStRkey1, kStValNameInt64); | |
524 ASSERT_TRUE(bool_res); | |
525 | |
526 // read it back | |
527 hr = RegKey::GetValue(kStRkey1, kStValNameInt64, &int64_val); | |
528 ASSERT_SUCCEEDED(hr); | |
529 ASSERT_EQ(int64_val, kStIntVal64); | |
530 | |
531 // read it back to test time64 | |
532 bool limited_value; | |
533 hr = GetLimitedTimeValue(kStRkey1, kStValNameInt64, kStIntVal64 + 10, &t, | |
534 &limited_value); | |
535 ASSERT_SUCCEEDED(hr); | |
536 EXPECT_FALSE(limited_value); | |
537 ASSERT_EQ(t, kStIntVal64); | |
538 hr = GetLimitedTimeValue(kStRkey1, kStValNameInt64, kStIntVal64 - 10, &t, | |
539 &limited_value); | |
540 EXPECT_TRUE(limited_value); | |
541 ASSERT_SUCCEEDED(hr); | |
542 ASSERT_EQ(t, kStIntVal64 - 10); | |
543 // Verify that the GetValue permanently made the value lower | |
544 hr = GetLimitedTimeValue(kStRkey1, kStValNameInt64, kStIntVal64, &t, | |
545 &limited_value); | |
546 EXPECT_FALSE(limited_value); | |
547 ASSERT_SUCCEEDED(hr); | |
548 ASSERT_EQ(t, kStIntVal64 - 10); | |
549 | |
550 // delete the value | |
551 hr = RegKey::DeleteValue(kStRkey1, kStValNameInt64); | |
552 ASSERT_SUCCEEDED(hr); | |
553 | |
554 // check that the value is gone | |
555 bool_res = RegKey::HasValue(kStRkey1, kStValNameInt64); | |
556 ASSERT_FALSE(bool_res); | |
557 | |
558 // set float | |
559 hr = RegKey::SetValue(kStRkey1, kStValNameFloat, kStFloatVal); | |
560 ASSERT_SUCCEEDED(hr); | |
561 | |
562 // check that the value exists | |
563 bool_res = RegKey::HasValue(kStRkey1, kStValNameFloat); | |
564 ASSERT_TRUE(bool_res); | |
565 | |
566 // read it back | |
567 hr = RegKey::GetValue(kStRkey1, kStValNameFloat, &float_val); | |
568 ASSERT_SUCCEEDED(hr); | |
569 ASSERT_EQ(float_val, kStFloatVal); | |
570 | |
571 // delete the value | |
572 hr = RegKey::DeleteValue(kStRkey1, kStValNameFloat); | |
573 ASSERT_SUCCEEDED(hr); | |
574 | |
575 // check that the value is gone | |
576 bool_res = RegKey::HasValue(kStRkey1, kStValNameFloat); | |
577 ASSERT_FALSE(bool_res); | |
578 hr = RegKey::GetValue(kStRkey1, kStValNameFloat, &float_val); | |
579 ASSERT_FAILED(hr); | |
580 | |
581 | |
582 // set double | |
583 hr = RegKey::SetValue(kStRkey1, kStValNameDouble, kStDoubleVal); | |
584 ASSERT_SUCCEEDED(hr); | |
585 | |
586 // check that the value exists | |
587 bool_res = RegKey::HasValue(kStRkey1, kStValNameDouble); | |
588 ASSERT_TRUE(bool_res); | |
589 | |
590 // read it back | |
591 hr = RegKey::GetValue(kStRkey1, kStValNameDouble, &double_val); | |
592 ASSERT_SUCCEEDED(hr); | |
593 ASSERT_EQ(double_val, kStDoubleVal); | |
594 | |
595 // delete the value | |
596 hr = RegKey::DeleteValue(kStRkey1, kStValNameDouble); | |
597 ASSERT_SUCCEEDED(hr); | |
598 | |
599 // check that the value is gone | |
600 bool_res = RegKey::HasValue(kStRkey1, kStValNameDouble); | |
601 ASSERT_FALSE(bool_res); | |
602 hr = RegKey::GetValue(kStRkey1, kStValNameDouble, &double_val); | |
603 ASSERT_FAILED(hr); | |
604 | |
605 // set string | |
606 hr = RegKey::SetValue(kStRkey1, kStValNameStr, kStStrVal); | |
607 ASSERT_SUCCEEDED(hr); | |
608 | |
609 // check that the value exists | |
610 bool_res = RegKey::HasValue(kStRkey1, kStValNameStr); | |
611 ASSERT_TRUE(bool_res); | |
612 | |
613 // read it back | |
614 hr = RegKey::GetValue(kStRkey1, kStValNameStr, &str_val); | |
615 ASSERT_SUCCEEDED(hr); | |
616 ASSERT_STREQ(str_val, kStStrVal); | |
617 delete [] str_val; | |
618 | |
619 // get an in-existent value from an existent key | |
620 hr = RegKey::GetValue(kStRkey1, _T("bogus"), &str_val); | |
621 ASSERT_EQ(hr, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)); | |
622 | |
623 // delete the value | |
624 hr = RegKey::DeleteValue(kStRkey1, kStValNameStr); | |
625 ASSERT_SUCCEEDED(hr); | |
626 | |
627 // check that the value is gone | |
628 bool_res = RegKey::HasValue(kStRkey1, kStValNameStr); | |
629 ASSERT_FALSE(bool_res); | |
630 | |
631 // set binary | |
632 hr = RegKey::SetValue(kStRkey1, kStValNameBinary, (const byte *)kStBinaryVal, | |
633 sizeof(kStBinaryVal)-1); | |
634 ASSERT_SUCCEEDED(hr); | |
635 | |
636 // check that the value exists | |
637 bool_res = RegKey::HasValue(kStRkey1, kStValNameBinary); | |
638 ASSERT_TRUE(bool_res); | |
639 | |
640 // read it back | |
641 hr = RegKey::GetValue(kStRkey1, kStValNameBinary, &binary_val, &byte_count); | |
642 ASSERT_SUCCEEDED(hr); | |
643 ASSERT_EQ(0, memcmp(binary_val, kStBinaryVal, sizeof(kStBinaryVal)-1)); | |
644 delete [] binary_val; | |
645 | |
646 // delete the value | |
647 hr = RegKey::DeleteValue(kStRkey1, kStValNameBinary); | |
648 ASSERT_SUCCEEDED(hr); | |
649 | |
650 // check that the value is gone | |
651 bool_res = RegKey::HasValue(kStRkey1, kStValNameBinary); | |
652 ASSERT_FALSE(bool_res); | |
653 | |
654 // special case - set a binary value with length 0 | |
655 hr = RegKey::SetValue(kStRkey1, kStValNameBinary, | |
656 (const byte *)kStBinaryVal, 0); | |
657 ASSERT_SUCCEEDED(hr); | |
658 | |
659 // check that the value exists | |
660 bool_res = RegKey::HasValue(kStRkey1, kStValNameBinary); | |
661 ASSERT_TRUE(bool_res); | |
662 | |
663 // read it back | |
664 hr = RegKey::GetValue(kStRkey1, kStValNameBinary, &binary_val, &byte_count); | |
665 ASSERT_SUCCEEDED(hr); | |
666 ASSERT_EQ(byte_count, 0); | |
667 ASSERT_TRUE(binary_val == NULL); | |
668 delete [] binary_val; | |
669 | |
670 // delete the value | |
671 hr = RegKey::DeleteValue(kStRkey1, kStValNameBinary); | |
672 ASSERT_SUCCEEDED(hr); | |
673 | |
674 // check that the value is gone | |
675 bool_res = RegKey::HasValue(kStRkey1, kStValNameBinary); | |
676 ASSERT_FALSE(bool_res); | |
677 | |
678 // special case - set a NULL binary value | |
679 hr = RegKey::SetValue(kStRkey1, kStValNameBinary, NULL, 100); | |
680 ASSERT_SUCCEEDED(hr); | |
681 | |
682 // check that the value exists | |
683 bool_res = RegKey::HasValue(kStRkey1, kStValNameBinary); | |
684 ASSERT_TRUE(bool_res); | |
685 | |
686 // read it back | |
687 hr = RegKey::GetValue(kStRkey1, kStValNameBinary, &binary_val, &byte_count); | |
688 ASSERT_SUCCEEDED(hr); | |
689 ASSERT_EQ(byte_count, 0); | |
690 ASSERT_TRUE(binary_val == NULL); | |
691 delete [] binary_val; | |
692 | |
693 // delete the value | |
694 hr = RegKey::DeleteValue(kStRkey1, kStValNameBinary); | |
695 ASSERT_SUCCEEDED(hr); | |
696 | |
697 // check that the value is gone | |
698 bool_res = RegKey::HasValue(kStRkey1, kStValNameBinary); | |
699 ASSERT_FALSE(bool_res); | |
700 | |
701 // whack the whole key | |
702 | |
703 hr = RegKey::DeleteKey(kStTestRkeyBase); | |
704 ASSERT_SUCCEEDED(hr); | |
705 } | |
706 | |
707 // RegKey::GetValue changes the output CString when errors occur. | |
708 TEST_F(RegKeyTestClass, ChangesStringOnErrors) { | |
709 CString string_val = _T("foo"); | |
710 EXPECT_FAILED(RegKey::GetValue(_T("HCKU"), _T("no_such_value"), &string_val)); | |
711 ASSERT_TRUE(string_val.IsEmpty()); | |
712 } | |
713 | |
714 TEST_F(RegKeyCleanupTestKeyTest, CreateKeys) { | |
715 // 3 keys specified but the count is two. | |
716 const TCHAR* keys[] = {kStRkey1, kStRkey2, kStRkey3}; | |
717 ASSERT_SUCCEEDED(RegKey::CreateKeys(keys, 2)); | |
718 | |
719 EXPECT_TRUE(RegKey::HasKey(kStRkey1)); | |
720 EXPECT_TRUE(RegKey::HasKey(kStRkey2)); | |
721 EXPECT_FALSE(RegKey::HasKey(kStRkey3)); | |
722 } | |
723 | |
724 TEST_F(RegKeyCleanupTestKeyTest, CreateKey) { | |
725 ASSERT_SUCCEEDED(RegKey::CreateKey(kStRkey1)); | |
726 | |
727 EXPECT_TRUE(RegKey::HasKey(kStRkey1)); | |
728 } | |
729 | |
730 TEST_F(RegKeyCleanupTestKeyTest, RenameValue) { | |
731 RegKey reg_key; | |
732 ASSERT_SUCCEEDED(reg_key.Create(HKEY_CURRENT_USER, kRkey1)); | |
733 ASSERT_SUCCEEDED(reg_key.SetValue(kValNameInt, kIntVal)); | |
734 ASSERT_TRUE(reg_key.HasValue(kValNameInt)); | |
735 | |
736 ASSERT_SUCCEEDED(reg_key.RenameValue(kValNameInt, kRenameValNameInt)); | |
737 ASSERT_FALSE(reg_key.HasValue(kValNameInt)); | |
738 | |
739 DWORD int_val = 0; | |
740 EXPECT_SUCCEEDED(reg_key.GetValue(kRenameValNameInt, &int_val)); | |
741 EXPECT_EQ(kIntVal, int_val); | |
742 | |
743 EXPECT_SUCCEEDED(reg_key.Close()); | |
744 } | |
745 | |
746 TEST_F(RegKeyCleanupTestKeyTest, RenameValueStatic) { | |
747 ASSERT_SUCCEEDED(RegKey::SetValue(kStRkey1, kStValNameStr, kStStrVal)); | |
748 ASSERT_TRUE(RegKey::HasValue(kStRkey1, kStValNameStr)); | |
749 | |
750 RegKey::RenameValue(kStRkey1, kStValNameStr, kRenameStValNameStr); | |
751 ASSERT_FALSE(RegKey::HasValue(kStRkey1, kStValNameStr)); | |
752 | |
753 CString str_val; | |
754 EXPECT_SUCCEEDED(RegKey::GetValue(kStRkey1, kRenameStValNameStr, &str_val)); | |
755 EXPECT_STREQ(kStStrVal, str_val); | |
756 } | |
757 | |
758 TEST_F(RegKeyCleanupTestKeyTest, CopyValue) { | |
759 EXPECT_SUCCEEDED(RegKey::SetValue(kStRkey1, kStValNameStr, kStStrVal)); | |
760 EXPECT_SUCCEEDED(RegKey::SetValue(kStRkey1, NULL, kStStrVal)); | |
761 EXPECT_TRUE(RegKey::HasValue(kStRkey1, kStValNameStr)); | |
762 | |
763 // Test that CopyValue fails when the to_key does not exist. | |
764 EXPECT_FALSE(RegKey::HasKey(kStRkey2)); | |
765 EXPECT_FAILED(RegKey::CopyValue(kStRkey1, kStRkey2, kStValNameStr)); | |
766 EXPECT_FALSE(RegKey::HasKey(kStRkey2)); | |
767 | |
768 EXPECT_SUCCEEDED(RegKey::CreateKey(kStRkey2)); | |
769 // Test CopyValue(full_from_key_name, full_to_key_name, value_name). | |
770 EXPECT_FALSE(RegKey::HasValue(kStRkey2, kStValNameStr)); | |
771 RegKey::CopyValue(kStRkey1, kStRkey2, kStValNameStr); | |
772 CString str_val; | |
773 EXPECT_SUCCEEDED(RegKey::GetValue(kStRkey2, kStValNameStr, &str_val)); | |
774 EXPECT_STREQ(kStStrVal, str_val); | |
775 | |
776 // Test CopyValue to a (Default) value. | |
777 EXPECT_FALSE(RegKey::HasValue(kStRkey2, NULL)); | |
778 RegKey::CopyValue(kStRkey1, kStRkey2, NULL); | |
779 str_val.Empty(); | |
780 EXPECT_SUCCEEDED(RegKey::GetValue(kStRkey2, NULL, &str_val)); | |
781 EXPECT_STREQ(kStStrVal, str_val); | |
782 | |
783 // Test CopyValue(full_from_key_name, from_value_name, full_to_key_name, | |
784 // to_value_name). | |
785 EXPECT_FALSE(RegKey::HasValue(kStRkey2, kRenameStValNameStr)); | |
786 RegKey::CopyValue(kStRkey1, kStValNameStr, kStRkey2, kRenameStValNameStr); | |
787 str_val.Empty(); | |
788 EXPECT_SUCCEEDED(RegKey::GetValue(kStRkey2, kRenameStValNameStr, &str_val)); | |
789 EXPECT_STREQ(kStStrVal, str_val); | |
790 } | |
791 | |
792 // Delete a key that does not have children. | |
793 | |
794 TEST_F(RegKeyCleanupTestKeyTest, DeleteKey_NoChildren_Recursively) { | |
795 EXPECT_SUCCEEDED(RegKey::CreateKey(kStRkey1)); | |
796 | |
797 EXPECT_EQ(S_OK, RegKey::DeleteKey(kStRkey1, true)); | |
798 EXPECT_FALSE(RegKey::HasKey(kStRkey1)); | |
799 } | |
800 | |
801 TEST_F(RegKeyCleanupTestKeyTest, DeleteKey_NoChildren_NotRecursively) { | |
802 EXPECT_SUCCEEDED(RegKey::CreateKey(kStRkey1)); | |
803 | |
804 EXPECT_EQ(S_OK, RegKey::DeleteKey(kStRkey1, false)); | |
805 EXPECT_FALSE(RegKey::HasKey(kStRkey1)); | |
806 } | |
807 | |
808 TEST_F(RegKeyCleanupTestKeyTest, RecurseDeleteSubKey_NoChildren) { | |
809 EXPECT_SUCCEEDED(RegKey::CreateKey(kStRkey1)); | |
810 EXPECT_SUCCEEDED(key_.Open(kStTestRkeyBase)); | |
811 | |
812 EXPECT_EQ(S_OK, key_.RecurseDeleteSubKey(kStRkey1Name)); | |
813 EXPECT_FALSE(RegKey::HasKey(kStRkey1)); | |
814 } | |
815 | |
816 TEST_F(RegKeyCleanupTestKeyTest, DeleteSubKey_NoChildren) { | |
817 EXPECT_SUCCEEDED(RegKey::CreateKey(kStRkey1)); | |
818 EXPECT_SUCCEEDED(key_.Open(kStTestRkeyBase)); | |
819 | |
820 EXPECT_EQ(S_OK, key_.DeleteSubKey(kStRkey1Name)); | |
821 EXPECT_FALSE(RegKey::HasKey(kStRkey1)); | |
822 } | |
823 | |
824 // Delete a key that has a child. | |
825 | |
826 TEST_F(RegKeyCleanupTestKeyTest, DeleteKey_WithChild_Recursively) { | |
827 EXPECT_SUCCEEDED(RegKey::CreateKey(kStRkey1Subkey)); | |
828 | |
829 EXPECT_EQ(S_OK, RegKey::DeleteKey(kStRkey1, true)); | |
830 EXPECT_FALSE(RegKey::HasKey(kStRkey1)); | |
831 EXPECT_FALSE(RegKey::HasKey(kStRkey1Subkey)); | |
832 } | |
833 | |
834 // Deleting a key with children present results in ERROR_ACCESS_DENIED. | |
835 TEST_F(RegKeyCleanupTestKeyTest, DeleteKey_WithChild_NotRecursively) { | |
836 EXPECT_SUCCEEDED(RegKey::CreateKey(kStRkey1Subkey)); | |
837 | |
838 EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED), | |
839 RegKey::DeleteKey(kStRkey1, false)); | |
840 EXPECT_TRUE(RegKey::HasKey(kStRkey1)); | |
841 EXPECT_TRUE(RegKey::HasKey(kStRkey1Subkey)); | |
842 } | |
843 | |
844 TEST_F(RegKeyCleanupTestKeyTest, RecurseDeleteSubKey_WithChild) { | |
845 EXPECT_SUCCEEDED(RegKey::CreateKey(kStRkey1Subkey)); | |
846 EXPECT_SUCCEEDED(key_.Open(kStTestRkeyBase)); | |
847 | |
848 EXPECT_EQ(S_OK, key_.RecurseDeleteSubKey(kStRkey1Name)); | |
849 EXPECT_FALSE(RegKey::HasKey(kStRkey1)); | |
850 EXPECT_FALSE(RegKey::HasKey(kStRkey1Subkey)); | |
851 } | |
852 | |
853 // Deleting a key with children present results in ERROR_ACCESS_DENIED. | |
854 TEST_F(RegKeyCleanupTestKeyTest, DeleteSubKey_WithChild) { | |
855 EXPECT_SUCCEEDED(RegKey::CreateKey(kStRkey1Subkey)); | |
856 EXPECT_SUCCEEDED(key_.Open(kStTestRkeyBase)); | |
857 | |
858 EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED), | |
859 key_.DeleteSubKey(kStRkey1Name)); | |
860 EXPECT_TRUE(RegKey::HasKey(kStRkey1)); | |
861 EXPECT_TRUE(RegKey::HasKey(kStRkey1Subkey)); | |
862 } | |
863 | |
864 // Delete a key that does not exist. | |
865 | |
866 TEST_F(RegKeyCleanupTestKeyTest, DeleteKey_KeyDoesNotExist_Recursively) { | |
867 EXPECT_SUCCEEDED(RegKey::CreateKey(kStRkey1)); | |
868 EXPECT_FALSE(RegKey::HasKey(kStRkey1Subkey)); | |
869 | |
870 EXPECT_EQ(S_FALSE, RegKey::DeleteKey(kStRkey1Subkey, true)); | |
871 EXPECT_FALSE(RegKey::HasKey(kStRkey1Subkey)); | |
872 } | |
873 | |
874 TEST_F(RegKeyCleanupTestKeyTest, DeleteKey_KeyDoesNotExist_NotRecursively) { | |
875 EXPECT_SUCCEEDED(RegKey::CreateKey(kStRkey1)); | |
876 EXPECT_FALSE(RegKey::HasKey(kStRkey1Subkey)); | |
877 | |
878 EXPECT_EQ(S_FALSE, RegKey::DeleteKey(kStRkey1Subkey, false)); | |
879 EXPECT_FALSE(RegKey::HasKey(kStRkey1Subkey)); | |
880 } | |
881 | |
882 TEST_F(RegKeyCleanupTestKeyTest, RecurseDeleteSubKey_KeyDoesNotExist) { | |
883 EXPECT_SUCCEEDED(RegKey::CreateKey(kStRkey1)); | |
884 EXPECT_SUCCEEDED(key_.Open(kStRkey1)); | |
885 EXPECT_FALSE(RegKey::HasKey(kStRkey1Subkey)); | |
886 | |
887 EXPECT_EQ(S_FALSE, key_.RecurseDeleteSubKey(kRkey1SubkeyName)); | |
888 EXPECT_FALSE(RegKey::HasKey(kStRkey1Subkey)); | |
889 } | |
890 | |
891 TEST_F(RegKeyCleanupTestKeyTest, DeleteSubKey_KeyDoesNotExist) { | |
892 EXPECT_SUCCEEDED(RegKey::CreateKey(kStRkey1)); | |
893 EXPECT_SUCCEEDED(key_.Open(kStRkey1)); | |
894 EXPECT_FALSE(RegKey::HasKey(kStRkey1Subkey)); | |
895 | |
896 EXPECT_EQ(S_FALSE, key_.DeleteSubKey(kRkey1SubkeyName)); | |
897 EXPECT_FALSE(RegKey::HasKey(kStRkey1Subkey)); | |
898 } | |
899 | |
900 // Delete a key whose parent does not exist. | |
901 // There is no equivalent test for RecurseDeleteSubKey and DeleteSubKey. | |
902 | |
903 TEST_F(RegKeyCleanupTestKeyTest, DeleteKey_ParentKeyDoesNotExist_Recursively) { | |
904 EXPECT_FALSE(RegKey::HasKey(kStRkey1)); | |
905 | |
906 EXPECT_EQ(S_FALSE, RegKey::DeleteKey(kStRkey1Subkey, true)); | |
907 EXPECT_FALSE(RegKey::HasKey(kStRkey1Subkey)); | |
908 } | |
909 | |
910 TEST_F(RegKeyCleanupTestKeyTest, | |
911 DeleteKey_ParentKeyDoesNotExist_NotRecursively) { | |
912 EXPECT_FALSE(RegKey::HasKey(kStRkey1)); | |
913 | |
914 EXPECT_EQ(S_FALSE, RegKey::DeleteKey(kStRkey1Subkey, false)); | |
915 EXPECT_FALSE(RegKey::HasKey(kStRkey1Subkey)); | |
916 } | |
917 | |
918 } // namespace omaha | |
OLD | NEW |