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