func TestCreateOpenDeleteKey(t *testing.T) { k, err := registry.OpenKey(registry.CURRENT_USER, "Software", registry.QUERY_VALUE) if err != nil { t.Fatal(err) } defer k.Close() testKName := randKeyName("TestCreateOpenDeleteKey_") testK, exist, err := registry.CreateKey(k, testKName, registry.CREATE_SUB_KEY) if err != nil { t.Fatal(err) } defer testK.Close() if exist { t.Fatalf("key %q already exists", testKName) } testKAgain, exist, err := registry.CreateKey(k, testKName, registry.CREATE_SUB_KEY) if err != nil { t.Fatal(err) } defer testKAgain.Close() if !exist { t.Fatalf("key %q should already exist", testKName) } testKOpened, err := registry.OpenKey(k, testKName, registry.ENUMERATE_SUB_KEYS) if err != nil { t.Fatal(err) } defer testKOpened.Close() err = registry.DeleteKey(k, testKName) if err != nil { t.Fatal(err) } testKOpenedAgain, err := registry.OpenKey(k, testKName, registry.ENUMERATE_SUB_KEYS) if err == nil { defer testKOpenedAgain.Close() t.Fatalf("key %q should already been deleted", testKName) } if err != registry.ErrNotExist { t.Fatalf(`unexpected error ("not exist" expected): %v`, err) } }
// matchZoneKey checks if stdname and dstname match the corresponding key // values "MUI_Std" and MUI_Dlt" or "Std" and "Dlt" (the latter down-level // from Vista) in the kname key stored under the open registry key zones. func matchZoneKey(zones registry.Key, kname string, stdname, dstname string) (matched bool, err2 error) { k, err := registry.OpenKey(zones, kname, registry.READ) if err != nil { return false, err } defer k.Close() var std, dlt string if err = registry.LoadRegLoadMUIString(); err == nil { // Try MUI_Std and MUI_Dlt first, fallback to Std and Dlt if *any* error occurs std, err = k.GetMUIStringValue("MUI_Std") if err == nil { dlt, err = k.GetMUIStringValue("MUI_Dlt") } } if err != nil { // Fallback to Std and Dlt if std, _, err = k.GetStringValue("Std"); err != nil { return false, err } if dlt, _, err = k.GetStringValue("Dlt"); err != nil { return false, err } } if std != stdname { return false, nil } if dlt != dstname && dstname != stdname { return false, nil } return true, nil }
func TestValues(t *testing.T) { softwareK, err := registry.OpenKey(registry.CURRENT_USER, "Software", registry.QUERY_VALUE) if err != nil { t.Fatal(err) } defer softwareK.Close() testKName := randKeyName("TestValues_") k, exist, err := registry.CreateKey(softwareK, testKName, registry.CREATE_SUB_KEY|registry.QUERY_VALUE|registry.SET_VALUE) if err != nil { t.Fatal(err) } defer k.Close() if exist { t.Fatalf("key %q already exists", testKName) } defer registry.DeleteKey(softwareK, testKName) setValues(t, k) enumerateValues(t, k) testValues(t, k) testStat(t, k) deleteValues(t, k) }
func TestToEnglishName(t *testing.T) { const want = "Central Europe Standard Time" k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\`+want, registry.READ) if err != nil { t.Fatalf("cannot open CEST time zone information from registry: %s", err) } defer k.Close() var std, dlt string if err = registry.LoadRegLoadMUIString(); err == nil { // Try MUI_Std and MUI_Dlt first, fallback to Std and Dlt if *any* error occurs std, err = k.GetMUIStringValue("MUI_Std") if err == nil { dlt, err = k.GetMUIStringValue("MUI_Dlt") } } if err != nil { // Fallback to Std and Dlt if std, _, err = k.GetStringValue("Std"); err != nil { t.Fatalf("cannot read CEST Std registry key: %s", err) } if dlt, _, err = k.GetStringValue("Dlt"); err != nil { t.Fatalf("cannot read CEST Dlt registry key: %s", err) } } name, err := ToEnglishName(std, dlt) if err != nil { t.Fatalf("toEnglishName failed: %s", err) } if name != want { t.Fatalf("english name: %q, want: %q", name, want) } }
func setConsoleDefaultPosition(pos uint64) error { key, err := registry.OpenKey(registry.CURRENT_USER, "Console", registry.SET_VALUE) if err != nil { return err } defer key.Close() return key.SetDWordValue("WindowPosition", uint32(pos)) }
func getCmdDefaultPosition() (uint64, error) { key, err := registry.OpenKey(registry.CURRENT_USER, `Console\%SystemRoot%_system32_cmd.exe`, registry.QUERY_VALUE) if err != nil { return 0, err } defer key.Close() v, _, err := key.GetIntegerValue("WindowPosition") return v, err }
// toEnglishName searches the registry for an English name of a time zone // whose zone names are stdname and dstname and returns the English name. func toEnglishName(stdname, dstname string) (string, error) { k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones`, registry.ENUMERATE_SUB_KEYS|registry.QUERY_VALUE) if err != nil { return "", err } defer k.Close() names, err := k.ReadSubKeyNames(-1) if err != nil { return "", err } for _, name := range names { matched, err := matchZoneKey(k, name, stdname, dstname) if err == nil && matched { return name, nil } } return "", errors.New(`English name for time zone "` + stdname + `" not found in registry`) }
func TestGetMUIStringValue(t *testing.T) { if err := registry.LoadRegLoadMUIString(); err != nil { t.Skip("regLoadMUIString not supported; skipping") } if err := procGetDynamicTimeZoneInformation.Find(); err != nil { t.Skipf("%s not supported; skipping", procGetDynamicTimeZoneInformation.Name) } var dtzi DynamicTimezoneinformation if _, err := GetDynamicTimeZoneInformation(&dtzi); err != nil { t.Fatal(err) } tzKeyName := syscall.UTF16ToString(dtzi.TimeZoneKeyName[:]) timezoneK, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\`+tzKeyName, registry.READ) if err != nil { t.Fatal(err) } defer timezoneK.Close() type testType struct { name string want string } var tests = []testType{ {"MUI_Std", syscall.UTF16ToString(dtzi.StandardName[:])}, } if dtzi.DynamicDaylightTimeDisabled == 0 { tests = append(tests, testType{"MUI_Dlt", syscall.UTF16ToString(dtzi.DaylightName[:])}) } for _, test := range tests { got, err := timezoneK.GetMUIStringValue(test.name) if err != nil { t.Error("GetMUIStringValue:", err) } if got != test.want { t.Errorf("GetMUIStringValue: %s: Got %q, want %q", test.name, got, test.want) } } }
func initMimeWindows() { names, err := registry.CLASSES_ROOT.ReadSubKeyNames(-1) if err != nil { return } for _, name := range names { if len(name) < 2 || name[0] != '.' { // looking for extensions only continue } k, err := registry.OpenKey(registry.CLASSES_ROOT, name, registry.READ) if err != nil { continue } v, _, err := k.GetStringValue("Content Type") k.Close() if err != nil { continue } setExtensionType(name, v) } }
func TestReadSubKeyNames(t *testing.T) { k, err := registry.OpenKey(registry.CLASSES_ROOT, "TypeLib", registry.ENUMERATE_SUB_KEYS|registry.QUERY_VALUE) if err != nil { t.Fatal(err) } defer k.Close() names, err := k.ReadSubKeyNames(-1) if err != nil { t.Fatal(err) } var foundStdOle bool for _, name := range names { // Every PC has "stdole 2.0 OLE Automation" library installed. if name == "{00020430-0000-0000-C000-000000000046}" { foundStdOle = true } } if !foundStdOle { t.Fatal("could not find stdole 2.0 OLE Automation") } }
// matchZoneKey checks if stdname and dstname match the corresponding "Std" // and "Dlt" key values in the kname key stored under the open registry key zones. func matchZoneKey(zones registry.Key, kname string, stdname, dstname string) (matched bool, err2 error) { k, err := registry.OpenKey(zones, kname, registry.READ) if err != nil { return false, err } defer k.Close() s, _, err := k.GetStringValue("Std") if err != nil { return false, err } if s != stdname { return false, nil } s, _, err = k.GetStringValue("Dlt") if err != nil { return false, err } if s != dstname && dstname != stdname { return false, nil } return true, nil }
func TestToEnglishName(t *testing.T) { const want = "Central Europe Standard Time" k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\`+want, registry.READ) if err != nil { t.Fatalf("cannot open CEST time zone information from registry: %s", err) } defer k.Close() std, _, err := k.GetStringValue("Std") if err != nil { t.Fatalf("cannot read CEST Std registry key: %s", err) } dlt, _, err := k.GetStringValue("Dlt") if err != nil { t.Fatalf("cannot read CEST Dlt registry key: %s", err) } name, err := ToEnglishName(std, dlt) if err != nil { t.Fatalf("toEnglishName failed: %s", err) } if name != want { t.Fatalf("english name: %q, want: %q", name, want) } }
func TestInvalidValues(t *testing.T) { softwareK, err := registry.OpenKey(registry.CURRENT_USER, "Software", registry.QUERY_VALUE) if err != nil { t.Fatal(err) } defer softwareK.Close() testKName := randKeyName("TestInvalidValues_") k, exist, err := registry.CreateKey(softwareK, testKName, registry.CREATE_SUB_KEY|registry.QUERY_VALUE|registry.SET_VALUE) if err != nil { t.Fatal(err) } defer k.Close() if exist { t.Fatalf("key %q already exists", testKName) } defer registry.DeleteKey(softwareK, testKName) var tests = []struct { Type uint32 Name string Data []byte }{ {registry.DWORD, "Dword1", nil}, {registry.DWORD, "Dword2", []byte{1, 2, 3}}, {registry.QWORD, "Qword1", nil}, {registry.QWORD, "Qword2", []byte{1, 2, 3}}, {registry.QWORD, "Qword3", []byte{1, 2, 3, 4, 5, 6, 7}}, {registry.MULTI_SZ, "MultiString1", nil}, {registry.MULTI_SZ, "MultiString2", []byte{0}}, {registry.MULTI_SZ, "MultiString3", []byte{'a', 'b', 0}}, {registry.MULTI_SZ, "MultiString4", []byte{'a', 0, 0, 'b', 0}}, {registry.MULTI_SZ, "MultiString5", []byte{'a', 0, 0}}, } for _, test := range tests { err := k.SetValue(test.Name, test.Type, test.Data) if err != nil { t.Fatalf("SetValue for %q failed: %v", test.Name, err) } } for _, test := range tests { switch test.Type { case registry.DWORD, registry.QWORD: value, valType, err := k.GetIntegerValue(test.Name) if err == nil { t.Errorf("GetIntegerValue(%q) succeeded. Returns type=%d value=%v", test.Name, valType, value) } case registry.MULTI_SZ: value, valType, err := k.GetStringsValue(test.Name) if err == nil { if len(value) != 0 { t.Errorf("GetStringsValue(%q) succeeded. Returns type=%d value=%v", test.Name, valType, value) } } default: t.Errorf("unsupported type %d for %s value", test.Type, test.Name) } } }
func walkKey(t *testing.T, k registry.Key, kname string) { names, err := k.ReadValueNames(-1) if err != nil { t.Fatalf("reading value names of %s failed: %v", kname, err) } for _, name := range names { _, valtype, err := k.GetValue(name, nil) if err != nil { t.Fatalf("reading value type of %s of %s failed: %v", name, kname, err) } switch valtype { case registry.NONE: case registry.SZ: _, _, err := k.GetStringValue(name) if err != nil { t.Error(err) } case registry.EXPAND_SZ: s, _, err := k.GetStringValue(name) if err != nil { t.Error(err) } _, err = registry.ExpandString(s) if err != nil { t.Error(err) } case registry.DWORD, registry.QWORD: _, _, err := k.GetIntegerValue(name) if err != nil { t.Error(err) } case registry.BINARY: _, _, err := k.GetBinaryValue(name) if err != nil { t.Error(err) } case registry.MULTI_SZ: _, _, err := k.GetStringsValue(name) if err != nil { t.Error(err) } case registry.FULL_RESOURCE_DESCRIPTOR, registry.RESOURCE_LIST, registry.RESOURCE_REQUIREMENTS_LIST: // TODO: not implemented default: t.Fatalf("value type %d of %s of %s failed: %v", valtype, name, kname, err) } } names, err = k.ReadSubKeyNames(-1) if err != nil { t.Fatalf("reading sub-keys of %s failed: %v", kname, err) } for _, name := range names { func() { subk, err := registry.OpenKey(k, name, registry.ENUMERATE_SUB_KEYS|registry.QUERY_VALUE) if err != nil { if err == syscall.ERROR_ACCESS_DENIED { // ignore error, if we are not allowed to access this key return } t.Fatalf("opening sub-keys %s of %s failed: %v", name, kname, err) } defer subk.Close() walkKey(t, subk, kname+`\`+name) }() } }