1 /*
2 * Copyright 2003 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 // Unittest for registry access API
12
13 #include "webrtc/base/arraysize.h"
14 #include "webrtc/base/gunit.h"
15 #include "webrtc/base/common.h"
16 #include "webrtc/base/win32regkey.h"
17
18 namespace rtc {
19
20 #ifndef EXPECT_SUCCEEDED
21 #define EXPECT_SUCCEEDED(x) EXPECT_TRUE(SUCCEEDED(x))
22 #endif
23
24 #ifndef EXPECT_FAILED
25 #define EXPECT_FAILED(x) EXPECT_TRUE(FAILED(x))
26 #endif
27
28 #define kBaseKey L"Software\\Google\\__TEST"
29 #define kSubkeyName L"subkey_test"
30
31 const wchar_t kRkey1[] = kBaseKey;
32 const wchar_t kRkey1SubkeyName[] = kSubkeyName;
33 const wchar_t kRkey1Subkey[] = kBaseKey L"\\" kSubkeyName;
34 const wchar_t kFullRkey1[] = L"HKCU\\" kBaseKey;
35 const wchar_t kFullRkey1Subkey[] = L"HKCU\\" kBaseKey L"\\" kSubkeyName;
36
37 const wchar_t kValNameInt[] = L"Int32 Value";
38 const DWORD kIntVal = 20;
39 const DWORD kIntVal2 = 30;
40
41 const wchar_t kValNameInt64[] = L"Int64 Value";
42 const DWORD64 kIntVal64 = 119600064000000000uI64;
43
44 const wchar_t kValNameFloat[] = L"Float Value";
45 const float kFloatVal = 12.3456789f;
46
47 const wchar_t kValNameDouble[] = L"Double Value";
48 const double kDoubleVal = 98.7654321;
49
50 const wchar_t kValNameStr[] = L"Str Value";
51 const wchar_t kStrVal[] = L"Some string data 1";
52 const wchar_t kStrVal2[] = L"Some string data 2";
53
54 const wchar_t kValNameBinary[] = L"Binary Value";
55 const char kBinaryVal[] = "Some binary data abcdefghi 1";
56 const char kBinaryVal2[] = "Some binary data abcdefghi 2";
57
58 const wchar_t kValNameMultiStr[] = L"MultiStr Value";
59 const wchar_t kMultiSZ[] = L"abc\0def\0P12345\0";
60 const wchar_t kEmptyMultiSZ[] = L"";
61 const wchar_t kInvalidMultiSZ[] = {L'6', L'7', L'8'};
62
63 // friend function of RegKey
RegKeyHelperFunctionsTest()64 void RegKeyHelperFunctionsTest() {
65 // Try out some dud values
66 std::wstring temp_key = L"";
67 EXPECT_TRUE(RegKey::GetRootKeyInfo(&temp_key) == NULL);
68 EXPECT_STREQ(temp_key.c_str(), L"");
69
70 temp_key = L"a";
71 EXPECT_TRUE(RegKey::GetRootKeyInfo(&temp_key) == NULL);
72 EXPECT_STREQ(temp_key.c_str(), L"");
73
74 // The basics
75 temp_key = L"HKLM\\a";
76 EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_LOCAL_MACHINE);
77 EXPECT_STREQ(temp_key.c_str(), L"a");
78
79 temp_key = L"HKEY_LOCAL_MACHINE\\a";
80 EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_LOCAL_MACHINE);
81 EXPECT_STREQ(temp_key.c_str(), L"a");
82
83 temp_key = L"HKCU\\a";
84 EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CURRENT_USER);
85 EXPECT_STREQ(temp_key.c_str(), L"a");
86
87 temp_key = L"HKEY_CURRENT_USER\\a";
88 EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CURRENT_USER);
89 EXPECT_STREQ(temp_key.c_str(), L"a");
90
91 temp_key = L"HKU\\a";
92 EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_USERS);
93 EXPECT_STREQ(temp_key.c_str(), L"a");
94
95 temp_key = L"HKEY_USERS\\a";
96 EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_USERS);
97 EXPECT_STREQ(temp_key.c_str(), L"a");
98
99 temp_key = L"HKCR\\a";
100 EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT);
101 EXPECT_STREQ(temp_key.c_str(), L"a");
102
103 temp_key = L"HKEY_CLASSES_ROOT\\a";
104 EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT);
105 EXPECT_STREQ(temp_key.c_str(), L"a");
106
107 // Make sure it is case insensitive
108 temp_key = L"hkcr\\a";
109 EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT);
110 EXPECT_STREQ(temp_key.c_str(), L"a");
111
112 temp_key = L"hkey_CLASSES_ROOT\\a";
113 EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT);
114 EXPECT_STREQ(temp_key.c_str(), L"a");
115
116 //
117 // Test RegKey::GetParentKeyInfo
118 //
119
120 // dud cases
121 temp_key = L"";
122 EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(), L"");
123 EXPECT_STREQ(temp_key.c_str(), L"");
124
125 temp_key = L"a";
126 EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(), L"");
127 EXPECT_STREQ(temp_key.c_str(), L"a");
128
129 temp_key = L"a\\b";
130 EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(), L"a");
131 EXPECT_STREQ(temp_key.c_str(), L"b");
132
133 temp_key = L"\\b";
134 EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(), L"");
135 EXPECT_STREQ(temp_key.c_str(), L"b");
136
137 // Some regular cases
138 temp_key = L"HKEY_CLASSES_ROOT\\moon";
139 EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(),
140 L"HKEY_CLASSES_ROOT");
141 EXPECT_STREQ(temp_key.c_str(), L"moon");
142
143 temp_key = L"HKEY_CLASSES_ROOT\\moon\\doggy";
144 EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(),
145 L"HKEY_CLASSES_ROOT\\moon");
146 EXPECT_STREQ(temp_key.c_str(), L"doggy");
147
148 //
149 // Test MultiSZBytesToStringArray
150 //
151
152 std::vector<std::wstring> result;
153 EXPECT_SUCCEEDED(RegKey::MultiSZBytesToStringArray(
154 reinterpret_cast<const uint8_t*>(kMultiSZ), sizeof(kMultiSZ), &result));
155 EXPECT_EQ(result.size(), 3);
156 EXPECT_STREQ(result[0].c_str(), L"abc");
157 EXPECT_STREQ(result[1].c_str(), L"def");
158 EXPECT_STREQ(result[2].c_str(), L"P12345");
159
160 EXPECT_SUCCEEDED(RegKey::MultiSZBytesToStringArray(
161 reinterpret_cast<const uint8_t*>(kEmptyMultiSZ), sizeof(kEmptyMultiSZ),
162 &result));
163 EXPECT_EQ(result.size(), 0);
164 EXPECT_FALSE(SUCCEEDED(RegKey::MultiSZBytesToStringArray(
165 reinterpret_cast<const uint8_t*>(kInvalidMultiSZ),
166 sizeof(kInvalidMultiSZ), &result)));
167 }
168
TEST(RegKeyTest,RegKeyHelperFunctionsTest)169 TEST(RegKeyTest, RegKeyHelperFunctionsTest) {
170 RegKeyHelperFunctionsTest();
171 }
172
RegKeyNonStaticFunctionsTest()173 void RegKeyNonStaticFunctionsTest() {
174 DWORD int_val = 0;
175 DWORD64 int64_val = 0;
176 wchar_t* str_val = NULL;
177 uint8_t* binary_val = NULL;
178 DWORD uint8_count = 0;
179
180 // Just in case...
181 // make sure the no test key residue is left from previous aborted runs
182 RegKey::DeleteKey(kFullRkey1);
183
184 // initial state
185 RegKey r_key;
186 EXPECT_TRUE(r_key.key() == NULL);
187
188 // create a reg key
189 EXPECT_SUCCEEDED(r_key.Create(HKEY_CURRENT_USER, kRkey1));
190
191 // do the create twice - it should return the already created one
192 EXPECT_SUCCEEDED(r_key.Create(HKEY_CURRENT_USER, kRkey1));
193
194 // now do an open - should work just fine
195 EXPECT_SUCCEEDED(r_key.Open(HKEY_CURRENT_USER, kRkey1));
196
197 // get an in-existent value
198 EXPECT_EQ(r_key.GetValue(kValNameInt, &int_val),
199 HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
200
201 // set and get some values
202
203 // set an INT 32
204 EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt, kIntVal));
205
206 // check that the value exists
207 EXPECT_TRUE(r_key.HasValue(kValNameInt));
208
209 // read it back
210 EXPECT_SUCCEEDED(r_key.GetValue(kValNameInt, &int_val));
211 EXPECT_EQ(int_val, kIntVal);
212
213 // set it again!
214 EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt, kIntVal2));
215
216 // read it again
217 EXPECT_SUCCEEDED(r_key.GetValue(kValNameInt, &int_val));
218 EXPECT_EQ(int_val, kIntVal2);
219
220 // delete the value
221 EXPECT_SUCCEEDED(r_key.DeleteValue(kValNameInt));
222
223 // check that the value is gone
224 EXPECT_FALSE(r_key.HasValue(kValNameInt));
225
226 // set an INT 64
227 EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt64, kIntVal64));
228
229 // check that the value exists
230 EXPECT_TRUE(r_key.HasValue(kValNameInt64));
231
232 // read it back
233 EXPECT_SUCCEEDED(r_key.GetValue(kValNameInt64, &int64_val));
234 EXPECT_EQ(int64_val, kIntVal64);
235
236 // delete the value
237 EXPECT_SUCCEEDED(r_key.DeleteValue(kValNameInt64));
238
239 // check that the value is gone
240 EXPECT_FALSE(r_key.HasValue(kValNameInt64));
241
242 // set a string
243 EXPECT_SUCCEEDED(r_key.SetValue(kValNameStr, kStrVal));
244
245 // check that the value exists
246 EXPECT_TRUE(r_key.HasValue(kValNameStr));
247
248 // read it back
249 EXPECT_SUCCEEDED(r_key.GetValue(kValNameStr, &str_val));
250 EXPECT_TRUE(lstrcmp(str_val, kStrVal) == 0);
251 delete[] str_val;
252
253 // set it again
254 EXPECT_SUCCEEDED(r_key.SetValue(kValNameStr, kStrVal2));
255
256 // read it again
257 EXPECT_SUCCEEDED(r_key.GetValue(kValNameStr, &str_val));
258 EXPECT_TRUE(lstrcmp(str_val, kStrVal2) == 0);
259 delete[] str_val;
260
261 // delete the value
262 EXPECT_SUCCEEDED(r_key.DeleteValue(kValNameStr));
263
264 // check that the value is gone
265 EXPECT_FALSE(r_key.HasValue(kValNameInt));
266
267 // set a binary value
268 EXPECT_SUCCEEDED(r_key.SetValue(kValNameBinary,
269 reinterpret_cast<const uint8_t*>(kBinaryVal),
270 sizeof(kBinaryVal) - 1));
271
272 // check that the value exists
273 EXPECT_TRUE(r_key.HasValue(kValNameBinary));
274
275 // read it back
276 EXPECT_SUCCEEDED(r_key.GetValue(kValNameBinary, &binary_val, &uint8_count));
277 EXPECT_TRUE(memcmp(binary_val, kBinaryVal, sizeof(kBinaryVal) - 1) == 0);
278 delete[] binary_val;
279
280 // set it again
281 EXPECT_SUCCEEDED(r_key.SetValue(kValNameBinary,
282 reinterpret_cast<const uint8_t*>(kBinaryVal2),
283 sizeof(kBinaryVal) - 1));
284
285 // read it again
286 EXPECT_SUCCEEDED(r_key.GetValue(kValNameBinary, &binary_val, &uint8_count));
287 EXPECT_TRUE(memcmp(binary_val, kBinaryVal2, sizeof(kBinaryVal2) - 1) == 0);
288 delete[] binary_val;
289
290 // delete the value
291 EXPECT_SUCCEEDED(r_key.DeleteValue(kValNameBinary));
292
293 // check that the value is gone
294 EXPECT_FALSE(r_key.HasValue(kValNameBinary));
295
296 // set some values and check the total count
297
298 // set an INT 32
299 EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt, kIntVal));
300
301 // set an INT 64
302 EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt64, kIntVal64));
303
304 // set a string
305 EXPECT_SUCCEEDED(r_key.SetValue(kValNameStr, kStrVal));
306
307 // set a binary value
308 EXPECT_SUCCEEDED(r_key.SetValue(kValNameBinary,
309 reinterpret_cast<const uint8_t*>(kBinaryVal),
310 sizeof(kBinaryVal) - 1));
311
312 // get the value count
313 uint32_t value_count = r_key.GetValueCount();
314 EXPECT_EQ(value_count, 4);
315
316 // check the value names
317 std::wstring value_name;
318 DWORD type = 0;
319
320 EXPECT_SUCCEEDED(r_key.GetValueNameAt(0, &value_name, &type));
321 EXPECT_STREQ(value_name.c_str(), kValNameInt);
322 EXPECT_EQ(type, REG_DWORD);
323
324 EXPECT_SUCCEEDED(r_key.GetValueNameAt(1, &value_name, &type));
325 EXPECT_STREQ(value_name.c_str(), kValNameInt64);
326 EXPECT_EQ(type, REG_QWORD);
327
328 EXPECT_SUCCEEDED(r_key.GetValueNameAt(2, &value_name, &type));
329 EXPECT_STREQ(value_name.c_str(), kValNameStr);
330 EXPECT_EQ(type, REG_SZ);
331
332 EXPECT_SUCCEEDED(r_key.GetValueNameAt(3, &value_name, &type));
333 EXPECT_STREQ(value_name.c_str(), kValNameBinary);
334 EXPECT_EQ(type, REG_BINARY);
335
336 // check that there are no more values
337 EXPECT_FAILED(r_key.GetValueNameAt(4, &value_name, &type));
338
339 uint32_t subkey_count = r_key.GetSubkeyCount();
340 EXPECT_EQ(subkey_count, 0);
341
342 // now create a subkey and make sure we can get the name
343 RegKey temp_key;
344 EXPECT_SUCCEEDED(temp_key.Create(HKEY_CURRENT_USER, kRkey1Subkey));
345
346 // check the subkey exists
347 EXPECT_TRUE(r_key.HasSubkey(kRkey1SubkeyName));
348
349 // check the name
350 EXPECT_EQ(r_key.GetSubkeyCount(), 1);
351
352 std::wstring subkey_name;
353 EXPECT_SUCCEEDED(r_key.GetSubkeyNameAt(0, &subkey_name));
354 EXPECT_STREQ(subkey_name.c_str(), kRkey1SubkeyName);
355
356 // delete the key
357 EXPECT_SUCCEEDED(r_key.DeleteSubKey(kRkey1));
358
359 // close this key
360 EXPECT_SUCCEEDED(r_key.Close());
361
362 // whack the whole key
363 EXPECT_SUCCEEDED(RegKey::DeleteKey(kFullRkey1));
364 }
365
RegKeyStaticFunctionsTest()366 void RegKeyStaticFunctionsTest() {
367 DWORD int_val = 0;
368 DWORD64 int64_val = 0;
369 float float_val = 0;
370 double double_val = 0;
371 wchar_t* str_val = NULL;
372 std::wstring wstr_val;
373 uint8_t* binary_val = NULL;
374 DWORD uint8_count = 0;
375
376 // Just in case...
377 // make sure the no test key residue is left from previous aborted runs
378 RegKey::DeleteKey(kFullRkey1);
379
380 // get an in-existent value from an un-existent key
381 EXPECT_EQ(RegKey::GetValue(kFullRkey1, kValNameInt, &int_val),
382 HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
383
384 // set int32_t
385 EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameInt, kIntVal));
386
387 // check that the value exists
388 EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameInt));
389
390 // get an in-existent value from an existent key
391 EXPECT_EQ(RegKey::GetValue(kFullRkey1, L"bogus", &int_val),
392 HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
393
394 // read it back
395 EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameInt, &int_val));
396 EXPECT_EQ(int_val, kIntVal);
397
398 // delete the value
399 EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameInt));
400
401 // check that the value is gone
402 EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameInt));
403
404 // set int64_t
405 EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameInt64, kIntVal64));
406
407 // check that the value exists
408 EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameInt64));
409
410 // read it back
411 EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameInt64, &int64_val));
412 EXPECT_EQ(int64_val, kIntVal64);
413
414 // delete the value
415 EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameInt64));
416
417 // check that the value is gone
418 EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameInt64));
419
420 // set float
421 EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameFloat, kFloatVal));
422
423 // check that the value exists
424 EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameFloat));
425
426 // read it back
427 EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameFloat, &float_val));
428 EXPECT_EQ(float_val, kFloatVal);
429
430 // delete the value
431 EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameFloat));
432
433 // check that the value is gone
434 EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameFloat));
435 EXPECT_FAILED(RegKey::GetValue(kFullRkey1, kValNameFloat, &float_val));
436
437 // set double
438 EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameDouble, kDoubleVal));
439
440 // check that the value exists
441 EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameDouble));
442
443 // read it back
444 EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameDouble, &double_val));
445 EXPECT_EQ(double_val, kDoubleVal);
446
447 // delete the value
448 EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameDouble));
449
450 // check that the value is gone
451 EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameDouble));
452 EXPECT_FAILED(RegKey::GetValue(kFullRkey1, kValNameDouble, &double_val));
453
454 // set string
455 EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameStr, kStrVal));
456
457 // check that the value exists
458 EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameStr));
459
460 // read it back
461 EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameStr, &str_val));
462 EXPECT_TRUE(lstrcmp(str_val, kStrVal) == 0);
463 delete[] str_val;
464
465 // read it back in std::wstring
466 EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameStr, &wstr_val));
467 EXPECT_STREQ(wstr_val.c_str(), kStrVal);
468
469 // get an in-existent value from an existent key
470 EXPECT_EQ(RegKey::GetValue(kFullRkey1, L"bogus", &str_val),
471 HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
472
473 // delete the value
474 EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameStr));
475
476 // check that the value is gone
477 EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameStr));
478
479 // set binary
480 EXPECT_SUCCEEDED(RegKey::SetValue(
481 kFullRkey1, kValNameBinary, reinterpret_cast<const uint8_t*>(kBinaryVal),
482 sizeof(kBinaryVal) - 1));
483
484 // check that the value exists
485 EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameBinary));
486
487 // read it back
488 EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameBinary,
489 &binary_val, &uint8_count));
490 EXPECT_TRUE(memcmp(binary_val, kBinaryVal, sizeof(kBinaryVal)-1) == 0);
491 delete[] binary_val;
492
493 // delete the value
494 EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameBinary));
495
496 // check that the value is gone
497 EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameBinary));
498
499 // special case - set a binary value with length 0
500 EXPECT_SUCCEEDED(
501 RegKey::SetValue(kFullRkey1, kValNameBinary,
502 reinterpret_cast<const uint8_t*>(kBinaryVal), 0));
503
504 // check that the value exists
505 EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameBinary));
506
507 // read it back
508 EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameBinary,
509 &binary_val, &uint8_count));
510 EXPECT_EQ(uint8_count, 0);
511 EXPECT_TRUE(binary_val == NULL);
512 delete[] binary_val;
513
514 // delete the value
515 EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameBinary));
516
517 // check that the value is gone
518 EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameBinary));
519
520 // special case - set a NULL binary value
521 EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameBinary, NULL, 100));
522
523 // check that the value exists
524 EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameBinary));
525
526 // read it back
527 EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameBinary,
528 &binary_val, &uint8_count));
529 EXPECT_EQ(uint8_count, 0);
530 EXPECT_TRUE(binary_val == NULL);
531 delete[] binary_val;
532
533 // delete the value
534 EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameBinary));
535
536 // check that the value is gone
537 EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameBinary));
538
539 // test read/write REG_MULTI_SZ value
540 std::vector<std::wstring> result;
541 EXPECT_SUCCEEDED(RegKey::SetValueMultiSZ(
542 kFullRkey1, kValNameMultiStr, reinterpret_cast<const uint8_t*>(kMultiSZ),
543 sizeof(kMultiSZ)));
544 EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameMultiStr, &result));
545 EXPECT_EQ(result.size(), 3);
546 EXPECT_STREQ(result[0].c_str(), L"abc");
547 EXPECT_STREQ(result[1].c_str(), L"def");
548 EXPECT_STREQ(result[2].c_str(), L"P12345");
549 EXPECT_SUCCEEDED(RegKey::SetValueMultiSZ(
550 kFullRkey1, kValNameMultiStr,
551 reinterpret_cast<const uint8_t*>(kEmptyMultiSZ), sizeof(kEmptyMultiSZ)));
552 EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameMultiStr, &result));
553 EXPECT_EQ(result.size(), 0);
554 // writing REG_MULTI_SZ value will automatically add ending null characters
555 EXPECT_SUCCEEDED(
556 RegKey::SetValueMultiSZ(kFullRkey1, kValNameMultiStr,
557 reinterpret_cast<const uint8_t*>(kInvalidMultiSZ),
558 sizeof(kInvalidMultiSZ)));
559 EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameMultiStr, &result));
560 EXPECT_EQ(result.size(), 1);
561 EXPECT_STREQ(result[0].c_str(), L"678");
562
563 // Run the following test only in dev machine
564 // This is because the build machine might not have admin privilege
565 #ifdef IS_PRIVATE_BUILD
566 // get a temp file name
567 wchar_t temp_path[MAX_PATH] = {0};
568 EXPECT_LT(::GetTempPath(arraysize(temp_path), temp_path),
569 static_cast<DWORD>(arraysize(temp_path)));
570 wchar_t temp_file[MAX_PATH] = {0};
571 EXPECT_NE(::GetTempFileName(temp_path, L"rkut_",
572 ::GetTickCount(), temp_file), 0);
573
574 // test save
575 EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1Subkey, kValNameInt, kIntVal));
576 EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1Subkey, kValNameInt64, kIntVal64));
577 EXPECT_SUCCEEDED(RegKey::Save(kFullRkey1Subkey, temp_file));
578 EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1Subkey, kValNameInt));
579 EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1Subkey, kValNameInt64));
580
581 // test restore
582 EXPECT_SUCCEEDED(RegKey::Restore(kFullRkey1Subkey, temp_file));
583 int_val = 0;
584 EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1Subkey, kValNameInt, &int_val));
585 EXPECT_EQ(int_val, kIntVal);
586 int64_val = 0;
587 EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1Subkey,
588 kValNameInt64,
589 &int64_val));
590 EXPECT_EQ(int64_val, kIntVal64);
591
592 // delete the temp file
593 EXPECT_EQ(TRUE, ::DeleteFile(temp_file));
594 #endif
595
596 // whack the whole key
597 EXPECT_SUCCEEDED(RegKey::DeleteKey(kFullRkey1));
598 }
599
600 // Run both tests under the same test target. Because they access (read and
601 // write) the same registry keys they can't run in parallel with eachother.
TEST(RegKeyTest,RegKeyFunctionsTest)602 TEST(RegKeyTest, RegKeyFunctionsTest) {
603 RegKeyNonStaticFunctionsTest();
604 RegKeyStaticFunctionsTest();
605 }
606
607 } // namespace rtc
608