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