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