1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build windows 6 7 package registry_test 8 9 import ( 10 "bytes" 11 "crypto/rand" 12 "os" 13 "syscall" 14 "testing" 15 16 "internal/syscall/windows/registry" 17 ) 18 19 func randKeyName(prefix string) string { 20 const numbers = "0123456789" 21 buf := make([]byte, 10) 22 rand.Read(buf) 23 for i, b := range buf { 24 buf[i] = numbers[b%byte(len(numbers))] 25 } 26 return prefix + string(buf) 27 } 28 29 func TestReadSubKeyNames(t *testing.T) { 30 k, err := registry.OpenKey(registry.CLASSES_ROOT, "TypeLib", registry.ENUMERATE_SUB_KEYS|registry.QUERY_VALUE) 31 if err != nil { 32 t.Fatal(err) 33 } 34 defer k.Close() 35 36 names, err := k.ReadSubKeyNames(-1) 37 if err != nil { 38 t.Fatal(err) 39 } 40 var foundStdOle bool 41 for _, name := range names { 42 // Every PC has "stdole 2.0 OLE Automation" library installed. 43 if name == "{00020430-0000-0000-C000-000000000046}" { 44 foundStdOle = true 45 } 46 } 47 if !foundStdOle { 48 t.Fatal("could not find stdole 2.0 OLE Automation") 49 } 50 } 51 52 func TestCreateOpenDeleteKey(t *testing.T) { 53 k, err := registry.OpenKey(registry.CURRENT_USER, "Software", registry.QUERY_VALUE) 54 if err != nil { 55 t.Fatal(err) 56 } 57 defer k.Close() 58 59 testKName := randKeyName("TestCreateOpenDeleteKey_") 60 61 testK, exist, err := registry.CreateKey(k, testKName, registry.CREATE_SUB_KEY) 62 if err != nil { 63 t.Fatal(err) 64 } 65 defer testK.Close() 66 67 if exist { 68 t.Fatalf("key %q already exists", testKName) 69 } 70 71 testKAgain, exist, err := registry.CreateKey(k, testKName, registry.CREATE_SUB_KEY) 72 if err != nil { 73 t.Fatal(err) 74 } 75 defer testKAgain.Close() 76 77 if !exist { 78 t.Fatalf("key %q should already exist", testKName) 79 } 80 81 testKOpened, err := registry.OpenKey(k, testKName, registry.ENUMERATE_SUB_KEYS) 82 if err != nil { 83 t.Fatal(err) 84 } 85 defer testKOpened.Close() 86 87 err = registry.DeleteKey(k, testKName) 88 if err != nil { 89 t.Fatal(err) 90 } 91 92 testKOpenedAgain, err := registry.OpenKey(k, testKName, registry.ENUMERATE_SUB_KEYS) 93 if err == nil { 94 defer testKOpenedAgain.Close() 95 t.Fatalf("key %q should already been deleted", testKName) 96 } 97 if err != registry.ErrNotExist { 98 t.Fatalf(`unexpected error ("not exist" expected): %v`, err) 99 } 100 } 101 102 func equalStringSlice(a, b []string) bool { 103 if len(a) != len(b) { 104 return false 105 } 106 if a == nil { 107 return true 108 } 109 for i := range a { 110 if a[i] != b[i] { 111 return false 112 } 113 } 114 return true 115 } 116 117 type ValueTest struct { 118 Type uint32 119 Name string 120 Value interface{} 121 WillFail bool 122 } 123 124 var ValueTests = []ValueTest{ 125 {Type: registry.SZ, Name: "String1", Value: ""}, 126 {Type: registry.SZ, Name: "String2", Value: "\000", WillFail: true}, 127 {Type: registry.SZ, Name: "String3", Value: "Hello World"}, 128 {Type: registry.SZ, Name: "String4", Value: "Hello World\000", WillFail: true}, 129 {Type: registry.EXPAND_SZ, Name: "ExpString1", Value: ""}, 130 {Type: registry.EXPAND_SZ, Name: "ExpString2", Value: "\000", WillFail: true}, 131 {Type: registry.EXPAND_SZ, Name: "ExpString3", Value: "Hello World"}, 132 {Type: registry.EXPAND_SZ, Name: "ExpString4", Value: "Hello\000World", WillFail: true}, 133 {Type: registry.EXPAND_SZ, Name: "ExpString5", Value: "%PATH%"}, 134 {Type: registry.EXPAND_SZ, Name: "ExpString6", Value: "%NO_SUCH_VARIABLE%"}, 135 {Type: registry.EXPAND_SZ, Name: "ExpString7", Value: "%PATH%;."}, 136 {Type: registry.BINARY, Name: "Binary1", Value: []byte{}}, 137 {Type: registry.BINARY, Name: "Binary2", Value: []byte{1, 2, 3}}, 138 {Type: registry.BINARY, Name: "Binary3", Value: []byte{3, 2, 1, 0, 1, 2, 3}}, 139 {Type: registry.DWORD, Name: "Dword1", Value: uint64(0)}, 140 {Type: registry.DWORD, Name: "Dword2", Value: uint64(1)}, 141 {Type: registry.DWORD, Name: "Dword3", Value: uint64(0xff)}, 142 {Type: registry.DWORD, Name: "Dword4", Value: uint64(0xffff)}, 143 {Type: registry.QWORD, Name: "Qword1", Value: uint64(0)}, 144 {Type: registry.QWORD, Name: "Qword2", Value: uint64(1)}, 145 {Type: registry.QWORD, Name: "Qword3", Value: uint64(0xff)}, 146 {Type: registry.QWORD, Name: "Qword4", Value: uint64(0xffff)}, 147 {Type: registry.QWORD, Name: "Qword5", Value: uint64(0xffffff)}, 148 {Type: registry.QWORD, Name: "Qword6", Value: uint64(0xffffffff)}, 149 {Type: registry.MULTI_SZ, Name: "MultiString1", Value: []string{"a", "b", "c"}}, 150 {Type: registry.MULTI_SZ, Name: "MultiString2", Value: []string{"abc", "", "cba"}}, 151 {Type: registry.MULTI_SZ, Name: "MultiString3", Value: []string{""}}, 152 {Type: registry.MULTI_SZ, Name: "MultiString4", Value: []string{"abcdef"}}, 153 {Type: registry.MULTI_SZ, Name: "MultiString5", Value: []string{"\000"}, WillFail: true}, 154 {Type: registry.MULTI_SZ, Name: "MultiString6", Value: []string{"a\000b"}, WillFail: true}, 155 {Type: registry.MULTI_SZ, Name: "MultiString7", Value: []string{"ab", "\000", "cd"}, WillFail: true}, 156 {Type: registry.MULTI_SZ, Name: "MultiString8", Value: []string{"\000", "cd"}, WillFail: true}, 157 {Type: registry.MULTI_SZ, Name: "MultiString9", Value: []string{"ab", "\000"}, WillFail: true}, 158 } 159 160 func setValues(t *testing.T, k registry.Key) { 161 for _, test := range ValueTests { 162 var err error 163 switch test.Type { 164 case registry.SZ: 165 err = k.SetStringValue(test.Name, test.Value.(string)) 166 case registry.EXPAND_SZ: 167 err = k.SetExpandStringValue(test.Name, test.Value.(string)) 168 case registry.MULTI_SZ: 169 err = k.SetStringsValue(test.Name, test.Value.([]string)) 170 case registry.BINARY: 171 err = k.SetBinaryValue(test.Name, test.Value.([]byte)) 172 case registry.DWORD: 173 err = k.SetDWordValue(test.Name, uint32(test.Value.(uint64))) 174 case registry.QWORD: 175 err = k.SetQWordValue(test.Name, test.Value.(uint64)) 176 default: 177 t.Fatalf("unsupported type %d for %s value", test.Type, test.Name) 178 } 179 if test.WillFail { 180 if err == nil { 181 t.Fatalf("setting %s value %q should fail, but succeeded", test.Name, test.Value) 182 } 183 } else { 184 if err != nil { 185 t.Fatal(err) 186 } 187 } 188 } 189 } 190 191 func enumerateValues(t *testing.T, k registry.Key) { 192 names, err := k.ReadValueNames(-1) 193 if err != nil { 194 t.Error(err) 195 return 196 } 197 haveNames := make(map[string]bool) 198 for _, n := range names { 199 haveNames[n] = false 200 } 201 for _, test := range ValueTests { 202 wantFound := !test.WillFail 203 _, haveFound := haveNames[test.Name] 204 if wantFound && !haveFound { 205 t.Errorf("value %s is not found while enumerating", test.Name) 206 } 207 if haveFound && !wantFound { 208 t.Errorf("value %s is found while enumerating, but expected to fail", test.Name) 209 } 210 if haveFound { 211 delete(haveNames, test.Name) 212 } 213 } 214 for n, v := range haveNames { 215 t.Errorf("value %s (%v) is found while enumerating, but has not been cretaed", n, v) 216 } 217 } 218 219 func testErrNotExist(t *testing.T, name string, err error) { 220 if err == nil { 221 t.Errorf("%s value should not exist", name) 222 return 223 } 224 if err != registry.ErrNotExist { 225 t.Errorf("reading %s value should return 'not exist' error, but got: %s", name, err) 226 return 227 } 228 } 229 230 func testErrUnexpectedType(t *testing.T, test ValueTest, gottype uint32, err error) { 231 if err == nil { 232 t.Errorf("GetXValue(%q) should not succeed", test.Name) 233 return 234 } 235 if err != registry.ErrUnexpectedType { 236 t.Errorf("reading %s value should return 'unexpected key value type' error, but got: %s", test.Name, err) 237 return 238 } 239 if gottype != test.Type { 240 t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype) 241 return 242 } 243 } 244 245 func testGetStringValue(t *testing.T, k registry.Key, test ValueTest) { 246 got, gottype, err := k.GetStringValue(test.Name) 247 if err != nil { 248 t.Errorf("GetStringValue(%s) failed: %v", test.Name, err) 249 return 250 } 251 if got != test.Value { 252 t.Errorf("want %s value %q, got %q", test.Name, test.Value, got) 253 return 254 } 255 if gottype != test.Type { 256 t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype) 257 return 258 } 259 if gottype == registry.EXPAND_SZ { 260 _, err = registry.ExpandString(got) 261 if err != nil { 262 t.Errorf("ExpandString(%s) failed: %v", got, err) 263 return 264 } 265 } 266 } 267 268 func testGetIntegerValue(t *testing.T, k registry.Key, test ValueTest) { 269 got, gottype, err := k.GetIntegerValue(test.Name) 270 if err != nil { 271 t.Errorf("GetIntegerValue(%s) failed: %v", test.Name, err) 272 return 273 } 274 if got != test.Value.(uint64) { 275 t.Errorf("want %s value %v, got %v", test.Name, test.Value, got) 276 return 277 } 278 if gottype != test.Type { 279 t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype) 280 return 281 } 282 } 283 284 func testGetBinaryValue(t *testing.T, k registry.Key, test ValueTest) { 285 got, gottype, err := k.GetBinaryValue(test.Name) 286 if err != nil { 287 t.Errorf("GetBinaryValue(%s) failed: %v", test.Name, err) 288 return 289 } 290 if !bytes.Equal(got, test.Value.([]byte)) { 291 t.Errorf("want %s value %v, got %v", test.Name, test.Value, got) 292 return 293 } 294 if gottype != test.Type { 295 t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype) 296 return 297 } 298 } 299 300 func testGetStringsValue(t *testing.T, k registry.Key, test ValueTest) { 301 got, gottype, err := k.GetStringsValue(test.Name) 302 if err != nil { 303 t.Errorf("GetStringsValue(%s) failed: %v", test.Name, err) 304 return 305 } 306 if !equalStringSlice(got, test.Value.([]string)) { 307 t.Errorf("want %s value %#v, got %#v", test.Name, test.Value, got) 308 return 309 } 310 if gottype != test.Type { 311 t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype) 312 return 313 } 314 } 315 316 func testGetValue(t *testing.T, k registry.Key, test ValueTest, size int) { 317 if size <= 0 { 318 return 319 } 320 // read data with no buffer 321 gotsize, gottype, err := k.GetValue(test.Name, nil) 322 if err != nil { 323 t.Errorf("GetValue(%s, [%d]byte) failed: %v", test.Name, size, err) 324 return 325 } 326 if gotsize != size { 327 t.Errorf("want %s value size of %d, got %v", test.Name, size, gotsize) 328 return 329 } 330 if gottype != test.Type { 331 t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype) 332 return 333 } 334 // read data with short buffer 335 gotsize, gottype, err = k.GetValue(test.Name, make([]byte, size-1)) 336 if err == nil { 337 t.Errorf("GetValue(%s, [%d]byte) should fail, but suceeded", test.Name, size-1) 338 return 339 } 340 if err != registry.ErrShortBuffer { 341 t.Errorf("reading %s value should return 'short buffer' error, but got: %s", test.Name, err) 342 return 343 } 344 if gotsize != size { 345 t.Errorf("want %s value size of %d, got %v", test.Name, size, gotsize) 346 return 347 } 348 if gottype != test.Type { 349 t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype) 350 return 351 } 352 // read full data 353 gotsize, gottype, err = k.GetValue(test.Name, make([]byte, size)) 354 if err != nil { 355 t.Errorf("GetValue(%s, [%d]byte) failed: %v", test.Name, size, err) 356 return 357 } 358 if gotsize != size { 359 t.Errorf("want %s value size of %d, got %v", test.Name, size, gotsize) 360 return 361 } 362 if gottype != test.Type { 363 t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype) 364 return 365 } 366 // check GetValue returns ErrNotExist as required 367 _, _, err = k.GetValue(test.Name+"_not_there", make([]byte, size)) 368 if err == nil { 369 t.Errorf("GetValue(%q) should not succeed", test.Name) 370 return 371 } 372 if err != registry.ErrNotExist { 373 t.Errorf("GetValue(%q) should return 'not exist' error, but got: %s", test.Name, err) 374 return 375 } 376 } 377 378 func testValues(t *testing.T, k registry.Key) { 379 for _, test := range ValueTests { 380 switch test.Type { 381 case registry.SZ, registry.EXPAND_SZ: 382 if test.WillFail { 383 _, _, err := k.GetStringValue(test.Name) 384 testErrNotExist(t, test.Name, err) 385 } else { 386 testGetStringValue(t, k, test) 387 _, gottype, err := k.GetIntegerValue(test.Name) 388 testErrUnexpectedType(t, test, gottype, err) 389 // Size of utf16 string in bytes is not perfect, 390 // but correct for current test values. 391 // Size also includes terminating 0. 392 testGetValue(t, k, test, (len(test.Value.(string))+1)*2) 393 } 394 _, _, err := k.GetStringValue(test.Name + "_string_not_created") 395 testErrNotExist(t, test.Name+"_string_not_created", err) 396 case registry.DWORD, registry.QWORD: 397 testGetIntegerValue(t, k, test) 398 _, gottype, err := k.GetBinaryValue(test.Name) 399 testErrUnexpectedType(t, test, gottype, err) 400 _, _, err = k.GetIntegerValue(test.Name + "_int_not_created") 401 testErrNotExist(t, test.Name+"_int_not_created", err) 402 size := 8 403 if test.Type == registry.DWORD { 404 size = 4 405 } 406 testGetValue(t, k, test, size) 407 case registry.BINARY: 408 testGetBinaryValue(t, k, test) 409 _, gottype, err := k.GetStringsValue(test.Name) 410 testErrUnexpectedType(t, test, gottype, err) 411 _, _, err = k.GetBinaryValue(test.Name + "_byte_not_created") 412 testErrNotExist(t, test.Name+"_byte_not_created", err) 413 testGetValue(t, k, test, len(test.Value.([]byte))) 414 case registry.MULTI_SZ: 415 if test.WillFail { 416 _, _, err := k.GetStringsValue(test.Name) 417 testErrNotExist(t, test.Name, err) 418 } else { 419 testGetStringsValue(t, k, test) 420 _, gottype, err := k.GetStringValue(test.Name) 421 testErrUnexpectedType(t, test, gottype, err) 422 size := 0 423 for _, s := range test.Value.([]string) { 424 size += len(s) + 1 // nil terminated 425 } 426 size += 1 // extra nil at the end 427 size *= 2 // count bytes, not uint16 428 testGetValue(t, k, test, size) 429 } 430 _, _, err := k.GetStringsValue(test.Name + "_strings_not_created") 431 testErrNotExist(t, test.Name+"_strings_not_created", err) 432 default: 433 t.Errorf("unsupported type %d for %s value", test.Type, test.Name) 434 continue 435 } 436 } 437 } 438 439 func testStat(t *testing.T, k registry.Key) { 440 subk, _, err := registry.CreateKey(k, "subkey", registry.CREATE_SUB_KEY) 441 if err != nil { 442 t.Error(err) 443 return 444 } 445 defer subk.Close() 446 447 defer registry.DeleteKey(k, "subkey") 448 449 ki, err := k.Stat() 450 if err != nil { 451 t.Error(err) 452 return 453 } 454 if ki.SubKeyCount != 1 { 455 t.Error("key must have 1 subkey") 456 } 457 if ki.MaxSubKeyLen != 6 { 458 t.Error("key max subkey name length must be 6") 459 } 460 if ki.ValueCount != 24 { 461 t.Errorf("key must have 24 values, but is %d", ki.ValueCount) 462 } 463 if ki.MaxValueNameLen != 12 { 464 t.Errorf("key max value name length must be 10, but is %d", ki.MaxValueNameLen) 465 } 466 if ki.MaxValueLen != 38 { 467 t.Errorf("key max value length must be 38, but is %d", ki.MaxValueLen) 468 } 469 } 470 471 func deleteValues(t *testing.T, k registry.Key) { 472 for _, test := range ValueTests { 473 if test.WillFail { 474 continue 475 } 476 err := k.DeleteValue(test.Name) 477 if err != nil { 478 t.Error(err) 479 continue 480 } 481 } 482 names, err := k.ReadValueNames(-1) 483 if err != nil { 484 t.Error(err) 485 return 486 } 487 if len(names) != 0 { 488 t.Errorf("some values remain after deletion: %v", names) 489 } 490 } 491 492 func TestValues(t *testing.T) { 493 softwareK, err := registry.OpenKey(registry.CURRENT_USER, "Software", registry.QUERY_VALUE) 494 if err != nil { 495 t.Fatal(err) 496 } 497 defer softwareK.Close() 498 499 testKName := randKeyName("TestValues_") 500 501 k, exist, err := registry.CreateKey(softwareK, testKName, registry.CREATE_SUB_KEY|registry.QUERY_VALUE|registry.SET_VALUE) 502 if err != nil { 503 t.Fatal(err) 504 } 505 defer k.Close() 506 507 if exist { 508 t.Fatalf("key %q already exists", testKName) 509 } 510 511 defer registry.DeleteKey(softwareK, testKName) 512 513 setValues(t, k) 514 515 enumerateValues(t, k) 516 517 testValues(t, k) 518 519 testStat(t, k) 520 521 deleteValues(t, k) 522 } 523 524 func walkKey(t *testing.T, k registry.Key, kname string) { 525 names, err := k.ReadValueNames(-1) 526 if err != nil { 527 t.Fatalf("reading value names of %s failed: %v", kname, err) 528 } 529 for _, name := range names { 530 _, valtype, err := k.GetValue(name, nil) 531 if err != nil { 532 t.Fatalf("reading value type of %s of %s failed: %v", name, kname, err) 533 } 534 switch valtype { 535 case registry.NONE: 536 case registry.SZ: 537 _, _, err := k.GetStringValue(name) 538 if err != nil { 539 t.Error(err) 540 } 541 case registry.EXPAND_SZ: 542 s, _, err := k.GetStringValue(name) 543 if err != nil { 544 t.Error(err) 545 } 546 _, err = registry.ExpandString(s) 547 if err != nil { 548 t.Error(err) 549 } 550 case registry.DWORD, registry.QWORD: 551 _, _, err := k.GetIntegerValue(name) 552 if err != nil { 553 t.Error(err) 554 } 555 case registry.BINARY: 556 _, _, err := k.GetBinaryValue(name) 557 if err != nil { 558 t.Error(err) 559 } 560 case registry.MULTI_SZ: 561 _, _, err := k.GetStringsValue(name) 562 if err != nil { 563 t.Error(err) 564 } 565 case registry.FULL_RESOURCE_DESCRIPTOR, registry.RESOURCE_LIST, registry.RESOURCE_REQUIREMENTS_LIST: 566 // TODO: not implemented 567 default: 568 t.Fatalf("value type %d of %s of %s failed: %v", valtype, name, kname, err) 569 } 570 } 571 572 names, err = k.ReadSubKeyNames(-1) 573 if err != nil { 574 t.Fatalf("reading sub-keys of %s failed: %v", kname, err) 575 } 576 for _, name := range names { 577 func() { 578 subk, err := registry.OpenKey(k, name, registry.ENUMERATE_SUB_KEYS|registry.QUERY_VALUE) 579 if err != nil { 580 if err == syscall.ERROR_ACCESS_DENIED { 581 // ignore error, if we are not allowed to access this key 582 return 583 } 584 t.Fatalf("opening sub-keys %s of %s failed: %v", name, kname, err) 585 } 586 defer subk.Close() 587 588 walkKey(t, subk, kname+`\`+name) 589 }() 590 } 591 } 592 593 func TestWalkFullRegistry(t *testing.T) { 594 if testing.Short() { 595 t.Skip("skipping long running test in short mode") 596 } 597 walkKey(t, registry.CLASSES_ROOT, "CLASSES_ROOT") 598 walkKey(t, registry.CURRENT_USER, "CURRENT_USER") 599 walkKey(t, registry.LOCAL_MACHINE, "LOCAL_MACHINE") 600 walkKey(t, registry.USERS, "USERS") 601 walkKey(t, registry.CURRENT_CONFIG, "CURRENT_CONFIG") 602 } 603 604 func TestExpandString(t *testing.T) { 605 got, err := registry.ExpandString("%PATH%") 606 if err != nil { 607 t.Fatal(err) 608 } 609 want := os.Getenv("PATH") 610 if got != want { 611 t.Errorf("want %q string expanded, got %q", want, got) 612 } 613 } 614 615 func TestInvalidValues(t *testing.T) { 616 softwareK, err := registry.OpenKey(registry.CURRENT_USER, "Software", registry.QUERY_VALUE) 617 if err != nil { 618 t.Fatal(err) 619 } 620 defer softwareK.Close() 621 622 testKName := randKeyName("TestInvalidValues_") 623 624 k, exist, err := registry.CreateKey(softwareK, testKName, registry.CREATE_SUB_KEY|registry.QUERY_VALUE|registry.SET_VALUE) 625 if err != nil { 626 t.Fatal(err) 627 } 628 defer k.Close() 629 630 if exist { 631 t.Fatalf("key %q already exists", testKName) 632 } 633 634 defer registry.DeleteKey(softwareK, testKName) 635 636 var tests = []struct { 637 Type uint32 638 Name string 639 Data []byte 640 }{ 641 {registry.DWORD, "Dword1", nil}, 642 {registry.DWORD, "Dword2", []byte{1, 2, 3}}, 643 {registry.QWORD, "Qword1", nil}, 644 {registry.QWORD, "Qword2", []byte{1, 2, 3}}, 645 {registry.QWORD, "Qword3", []byte{1, 2, 3, 4, 5, 6, 7}}, 646 {registry.MULTI_SZ, "MultiString1", nil}, 647 {registry.MULTI_SZ, "MultiString2", []byte{0}}, 648 {registry.MULTI_SZ, "MultiString3", []byte{'a', 'b', 0}}, 649 {registry.MULTI_SZ, "MultiString4", []byte{'a', 0, 0, 'b', 0}}, 650 {registry.MULTI_SZ, "MultiString5", []byte{'a', 0, 0}}, 651 } 652 653 for _, test := range tests { 654 err := k.SetValue(test.Name, test.Type, test.Data) 655 if err != nil { 656 t.Fatalf("SetValue for %q failed: %v", test.Name, err) 657 } 658 } 659 660 for _, test := range tests { 661 switch test.Type { 662 case registry.DWORD, registry.QWORD: 663 value, valType, err := k.GetIntegerValue(test.Name) 664 if err == nil { 665 t.Errorf("GetIntegerValue(%q) succeeded. Returns type=%d value=%v", test.Name, valType, value) 666 } 667 case registry.MULTI_SZ: 668 value, valType, err := k.GetStringsValue(test.Name) 669 if err == nil { 670 if len(value) != 0 { 671 t.Errorf("GetStringsValue(%q) succeeded. Returns type=%d value=%v", test.Name, valType, value) 672 } 673 } 674 default: 675 t.Errorf("unsupported type %d for %s value", test.Type, test.Name) 676 } 677 } 678 } 679