| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756 | // Copyright 2015 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.// +build windowspackage registry_testimport (	"bytes"	"crypto/rand"	"os"	"syscall"	"testing"	"time"	"unsafe"	"golang.org/x/sys/windows/registry")func randKeyName(prefix string) string {	const numbers = "0123456789"	buf := make([]byte, 10)	rand.Read(buf)	for i, b := range buf {		buf[i] = numbers[b%byte(len(numbers))]	}	return prefix + string(buf)}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")	}}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)	}}func equalStringSlice(a, b []string) bool {	if len(a) != len(b) {		return false	}	if a == nil {		return true	}	for i := range a {		if a[i] != b[i] {			return false		}	}	return true}type ValueTest struct {	Type     uint32	Name     string	Value    interface{}	WillFail bool}var ValueTests = []ValueTest{	{Type: registry.SZ, Name: "String1", Value: ""},	{Type: registry.SZ, Name: "String2", Value: "\000", WillFail: true},	{Type: registry.SZ, Name: "String3", Value: "Hello World"},	{Type: registry.SZ, Name: "String4", Value: "Hello World\000", WillFail: true},	{Type: registry.EXPAND_SZ, Name: "ExpString1", Value: ""},	{Type: registry.EXPAND_SZ, Name: "ExpString2", Value: "\000", WillFail: true},	{Type: registry.EXPAND_SZ, Name: "ExpString3", Value: "Hello World"},	{Type: registry.EXPAND_SZ, Name: "ExpString4", Value: "Hello\000World", WillFail: true},	{Type: registry.EXPAND_SZ, Name: "ExpString5", Value: "%PATH%"},	{Type: registry.EXPAND_SZ, Name: "ExpString6", Value: "%NO_SUCH_VARIABLE%"},	{Type: registry.EXPAND_SZ, Name: "ExpString7", Value: "%PATH%;."},	{Type: registry.BINARY, Name: "Binary1", Value: []byte{}},	{Type: registry.BINARY, Name: "Binary2", Value: []byte{1, 2, 3}},	{Type: registry.BINARY, Name: "Binary3", Value: []byte{3, 2, 1, 0, 1, 2, 3}},	{Type: registry.DWORD, Name: "Dword1", Value: uint64(0)},	{Type: registry.DWORD, Name: "Dword2", Value: uint64(1)},	{Type: registry.DWORD, Name: "Dword3", Value: uint64(0xff)},	{Type: registry.DWORD, Name: "Dword4", Value: uint64(0xffff)},	{Type: registry.QWORD, Name: "Qword1", Value: uint64(0)},	{Type: registry.QWORD, Name: "Qword2", Value: uint64(1)},	{Type: registry.QWORD, Name: "Qword3", Value: uint64(0xff)},	{Type: registry.QWORD, Name: "Qword4", Value: uint64(0xffff)},	{Type: registry.QWORD, Name: "Qword5", Value: uint64(0xffffff)},	{Type: registry.QWORD, Name: "Qword6", Value: uint64(0xffffffff)},	{Type: registry.MULTI_SZ, Name: "MultiString1", Value: []string{"a", "b", "c"}},	{Type: registry.MULTI_SZ, Name: "MultiString2", Value: []string{"abc", "", "cba"}},	{Type: registry.MULTI_SZ, Name: "MultiString3", Value: []string{""}},	{Type: registry.MULTI_SZ, Name: "MultiString4", Value: []string{"abcdef"}},	{Type: registry.MULTI_SZ, Name: "MultiString5", Value: []string{"\000"}, WillFail: true},	{Type: registry.MULTI_SZ, Name: "MultiString6", Value: []string{"a\000b"}, WillFail: true},	{Type: registry.MULTI_SZ, Name: "MultiString7", Value: []string{"ab", "\000", "cd"}, WillFail: true},	{Type: registry.MULTI_SZ, Name: "MultiString8", Value: []string{"\000", "cd"}, WillFail: true},	{Type: registry.MULTI_SZ, Name: "MultiString9", Value: []string{"ab", "\000"}, WillFail: true},}func setValues(t *testing.T, k registry.Key) {	for _, test := range ValueTests {		var err error		switch test.Type {		case registry.SZ:			err = k.SetStringValue(test.Name, test.Value.(string))		case registry.EXPAND_SZ:			err = k.SetExpandStringValue(test.Name, test.Value.(string))		case registry.MULTI_SZ:			err = k.SetStringsValue(test.Name, test.Value.([]string))		case registry.BINARY:			err = k.SetBinaryValue(test.Name, test.Value.([]byte))		case registry.DWORD:			err = k.SetDWordValue(test.Name, uint32(test.Value.(uint64)))		case registry.QWORD:			err = k.SetQWordValue(test.Name, test.Value.(uint64))		default:			t.Fatalf("unsupported type %d for %s value", test.Type, test.Name)		}		if test.WillFail {			if err == nil {				t.Fatalf("setting %s value %q should fail, but succeeded", test.Name, test.Value)			}		} else {			if err != nil {				t.Fatal(err)			}		}	}}func enumerateValues(t *testing.T, k registry.Key) {	names, err := k.ReadValueNames(-1)	if err != nil {		t.Error(err)		return	}	haveNames := make(map[string]bool)	for _, n := range names {		haveNames[n] = false	}	for _, test := range ValueTests {		wantFound := !test.WillFail		_, haveFound := haveNames[test.Name]		if wantFound && !haveFound {			t.Errorf("value %s is not found while enumerating", test.Name)		}		if haveFound && !wantFound {			t.Errorf("value %s is found while enumerating, but expected to fail", test.Name)		}		if haveFound {			delete(haveNames, test.Name)		}	}	for n, v := range haveNames {		t.Errorf("value %s (%v) is found while enumerating, but has not been cretaed", n, v)	}}func testErrNotExist(t *testing.T, name string, err error) {	if err == nil {		t.Errorf("%s value should not exist", name)		return	}	if err != registry.ErrNotExist {		t.Errorf("reading %s value should return 'not exist' error, but got: %s", name, err)		return	}}func testErrUnexpectedType(t *testing.T, test ValueTest, gottype uint32, err error) {	if err == nil {		t.Errorf("GetXValue(%q) should not succeed", test.Name)		return	}	if err != registry.ErrUnexpectedType {		t.Errorf("reading %s value should return 'unexpected key value type' error, but got: %s", test.Name, err)		return	}	if gottype != test.Type {		t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)		return	}}func testGetStringValue(t *testing.T, k registry.Key, test ValueTest) {	got, gottype, err := k.GetStringValue(test.Name)	if err != nil {		t.Errorf("GetStringValue(%s) failed: %v", test.Name, err)		return	}	if got != test.Value {		t.Errorf("want %s value %q, got %q", test.Name, test.Value, got)		return	}	if gottype != test.Type {		t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)		return	}	if gottype == registry.EXPAND_SZ {		_, err = registry.ExpandString(got)		if err != nil {			t.Errorf("ExpandString(%s) failed: %v", got, err)			return		}	}}func testGetIntegerValue(t *testing.T, k registry.Key, test ValueTest) {	got, gottype, err := k.GetIntegerValue(test.Name)	if err != nil {		t.Errorf("GetIntegerValue(%s) failed: %v", test.Name, err)		return	}	if got != test.Value.(uint64) {		t.Errorf("want %s value %v, got %v", test.Name, test.Value, got)		return	}	if gottype != test.Type {		t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)		return	}}func testGetBinaryValue(t *testing.T, k registry.Key, test ValueTest) {	got, gottype, err := k.GetBinaryValue(test.Name)	if err != nil {		t.Errorf("GetBinaryValue(%s) failed: %v", test.Name, err)		return	}	if !bytes.Equal(got, test.Value.([]byte)) {		t.Errorf("want %s value %v, got %v", test.Name, test.Value, got)		return	}	if gottype != test.Type {		t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)		return	}}func testGetStringsValue(t *testing.T, k registry.Key, test ValueTest) {	got, gottype, err := k.GetStringsValue(test.Name)	if err != nil {		t.Errorf("GetStringsValue(%s) failed: %v", test.Name, err)		return	}	if !equalStringSlice(got, test.Value.([]string)) {		t.Errorf("want %s value %#v, got %#v", test.Name, test.Value, got)		return	}	if gottype != test.Type {		t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)		return	}}func testGetValue(t *testing.T, k registry.Key, test ValueTest, size int) {	if size <= 0 {		return	}	// read data with no buffer	gotsize, gottype, err := k.GetValue(test.Name, nil)	if err != nil {		t.Errorf("GetValue(%s, [%d]byte) failed: %v", test.Name, size, err)		return	}	if gotsize != size {		t.Errorf("want %s value size of %d, got %v", test.Name, size, gotsize)		return	}	if gottype != test.Type {		t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)		return	}	// read data with short buffer	gotsize, gottype, err = k.GetValue(test.Name, make([]byte, size-1))	if err == nil {		t.Errorf("GetValue(%s, [%d]byte) should fail, but suceeded", test.Name, size-1)		return	}	if err != registry.ErrShortBuffer {		t.Errorf("reading %s value should return 'short buffer' error, but got: %s", test.Name, err)		return	}	if gotsize != size {		t.Errorf("want %s value size of %d, got %v", test.Name, size, gotsize)		return	}	if gottype != test.Type {		t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)		return	}	// read full data	gotsize, gottype, err = k.GetValue(test.Name, make([]byte, size))	if err != nil {		t.Errorf("GetValue(%s, [%d]byte) failed: %v", test.Name, size, err)		return	}	if gotsize != size {		t.Errorf("want %s value size of %d, got %v", test.Name, size, gotsize)		return	}	if gottype != test.Type {		t.Errorf("want %s value type %v, got %v", test.Name, test.Type, gottype)		return	}	// check GetValue returns ErrNotExist as required	_, _, err = k.GetValue(test.Name+"_not_there", make([]byte, size))	if err == nil {		t.Errorf("GetValue(%q) should not succeed", test.Name)		return	}	if err != registry.ErrNotExist {		t.Errorf("GetValue(%q) should return 'not exist' error, but got: %s", test.Name, err)		return	}}func testValues(t *testing.T, k registry.Key) {	for _, test := range ValueTests {		switch test.Type {		case registry.SZ, registry.EXPAND_SZ:			if test.WillFail {				_, _, err := k.GetStringValue(test.Name)				testErrNotExist(t, test.Name, err)			} else {				testGetStringValue(t, k, test)				_, gottype, err := k.GetIntegerValue(test.Name)				testErrUnexpectedType(t, test, gottype, err)				// Size of utf16 string in bytes is not perfect,				// but correct for current test values.				// Size also includes terminating 0.				testGetValue(t, k, test, (len(test.Value.(string))+1)*2)			}			_, _, err := k.GetStringValue(test.Name + "_string_not_created")			testErrNotExist(t, test.Name+"_string_not_created", err)		case registry.DWORD, registry.QWORD:			testGetIntegerValue(t, k, test)			_, gottype, err := k.GetBinaryValue(test.Name)			testErrUnexpectedType(t, test, gottype, err)			_, _, err = k.GetIntegerValue(test.Name + "_int_not_created")			testErrNotExist(t, test.Name+"_int_not_created", err)			size := 8			if test.Type == registry.DWORD {				size = 4			}			testGetValue(t, k, test, size)		case registry.BINARY:			testGetBinaryValue(t, k, test)			_, gottype, err := k.GetStringsValue(test.Name)			testErrUnexpectedType(t, test, gottype, err)			_, _, err = k.GetBinaryValue(test.Name + "_byte_not_created")			testErrNotExist(t, test.Name+"_byte_not_created", err)			testGetValue(t, k, test, len(test.Value.([]byte)))		case registry.MULTI_SZ:			if test.WillFail {				_, _, err := k.GetStringsValue(test.Name)				testErrNotExist(t, test.Name, err)			} else {				testGetStringsValue(t, k, test)				_, gottype, err := k.GetStringValue(test.Name)				testErrUnexpectedType(t, test, gottype, err)				size := 0				for _, s := range test.Value.([]string) {					size += len(s) + 1 // nil terminated				}				size += 1 // extra nil at the end				size *= 2 // count bytes, not uint16				testGetValue(t, k, test, size)			}			_, _, err := k.GetStringsValue(test.Name + "_strings_not_created")			testErrNotExist(t, test.Name+"_strings_not_created", err)		default:			t.Errorf("unsupported type %d for %s value", test.Type, test.Name)			continue		}	}}func testStat(t *testing.T, k registry.Key) {	subk, _, err := registry.CreateKey(k, "subkey", registry.CREATE_SUB_KEY)	if err != nil {		t.Error(err)		return	}	defer subk.Close()	defer registry.DeleteKey(k, "subkey")	ki, err := k.Stat()	if err != nil {		t.Error(err)		return	}	if ki.SubKeyCount != 1 {		t.Error("key must have 1 subkey")	}	if ki.MaxSubKeyLen != 6 {		t.Error("key max subkey name length must be 6")	}	if ki.ValueCount != 24 {		t.Errorf("key must have 24 values, but is %d", ki.ValueCount)	}	if ki.MaxValueNameLen != 12 {		t.Errorf("key max value name length must be 10, but is %d", ki.MaxValueNameLen)	}	if ki.MaxValueLen != 38 {		t.Errorf("key max value length must be 38, but is %d", ki.MaxValueLen)	}	if mt, ct := ki.ModTime(), time.Now(); ct.Sub(mt) > 100*time.Millisecond {		t.Errorf("key mod time is not close to current time: mtime=%v current=%v delta=%v", mt, ct, ct.Sub(mt))	}}func deleteValues(t *testing.T, k registry.Key) {	for _, test := range ValueTests {		if test.WillFail {			continue		}		err := k.DeleteValue(test.Name)		if err != nil {			t.Error(err)			continue		}	}	names, err := k.ReadValueNames(-1)	if err != nil {		t.Error(err)		return	}	if len(names) != 0 {		t.Errorf("some values remain after deletion: %v", names)	}}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 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)		}()	}}func TestWalkFullRegistry(t *testing.T) {	if testing.Short() {		t.Skip("skipping long running test in short mode")	}	walkKey(t, registry.CLASSES_ROOT, "CLASSES_ROOT")	walkKey(t, registry.CURRENT_USER, "CURRENT_USER")	walkKey(t, registry.LOCAL_MACHINE, "LOCAL_MACHINE")	walkKey(t, registry.USERS, "USERS")	walkKey(t, registry.CURRENT_CONFIG, "CURRENT_CONFIG")}func TestExpandString(t *testing.T) {	got, err := registry.ExpandString("%PATH%")	if err != nil {		t.Fatal(err)	}	want := os.Getenv("PATH")	if got != want {		t.Errorf("want %q string expanded, got %q", want, got)	}}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 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)		}	}}type DynamicTimezoneinformation struct {	Bias                        int32	StandardName                [32]uint16	StandardDate                syscall.Systemtime	StandardBias                int32	DaylightName                [32]uint16	DaylightDate                syscall.Systemtime	DaylightBias                int32	TimeZoneKeyName             [128]uint16	DynamicDaylightTimeDisabled uint8}var (	kernel32DLL = syscall.NewLazyDLL("kernel32")	procGetDynamicTimeZoneInformation = kernel32DLL.NewProc("GetDynamicTimeZoneInformation"))func GetDynamicTimeZoneInformation(dtzi *DynamicTimezoneinformation) (rc uint32, err error) {	r0, _, e1 := syscall.Syscall(procGetDynamicTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(dtzi)), 0, 0)	rc = uint32(r0)	if rc == 0xffffffff {		if e1 != 0 {			err = error(e1)		} else {			err = syscall.EINVAL		}	}	return}
 |