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.
7 // Package registry provides access to the Windows registry.
9 // Here is a simple example, opening a registry key and reading a string value from it.
11 // k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
17 // s, _, err := k.GetStringValue("SystemRoot")
21 // fmt.Printf("Windows system root is %q\n", s)
23 // NOTE: This package is a copy of golang.org/x/sys/windows/registry
24 // with KeyInfo.ModTime removed to prevent dependency cycles.
34 // Registry key security and access rights.
35 // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms724878.aspx
39 CREATE_SUB_KEY
= 0x00004
40 ENUMERATE_SUB_KEYS
= 0x00008
51 // Key is a handle to an open Windows registry key.
52 // Keys can be obtained by calling OpenKey; there are
53 // also some predefined root keys such as CURRENT_USER.
54 // Keys can be used directly in the Windows API.
55 type Key syscall
.Handle
58 // Windows defines some predefined root keys that are always open.
59 // An application can use these keys as entry points to the registry.
60 // Normally these keys are used in OpenKey to open new keys,
61 // but they can also be used anywhere a Key is required.
62 CLASSES_ROOT
= Key(syscall
.HKEY_CLASSES_ROOT
)
63 CURRENT_USER
= Key(syscall
.HKEY_CURRENT_USER
)
64 LOCAL_MACHINE
= Key(syscall
.HKEY_LOCAL_MACHINE
)
65 USERS
= Key(syscall
.HKEY_USERS
)
66 CURRENT_CONFIG
= Key(syscall
.HKEY_CURRENT_CONFIG
)
69 // Close closes open key k.
70 func (k Key
) Close() error
{
71 return syscall
.RegCloseKey(syscall
.Handle(k
))
74 // OpenKey opens a new key with path name relative to key k.
75 // It accepts any open key, including CURRENT_USER and others,
76 // and returns the new key and an error.
77 // The access parameter specifies desired access rights to the
79 func OpenKey(k Key
, path
string, access
uint32) (Key
, error
) {
80 p
, err
:= syscall
.UTF16PtrFromString(path
)
84 var subkey syscall
.Handle
85 err
= syscall
.RegOpenKeyEx(syscall
.Handle(k
), p
, 0, access
, &subkey
)
89 return Key(subkey
), nil
92 // ReadSubKeyNames returns the names of subkeys of key k.
93 // The parameter n controls the number of returned names,
94 // analogous to the way os.File.Readdirnames works.
95 func (k Key
) ReadSubKeyNames(n
int) ([]string, error
) {
96 names
:= make([]string, 0)
97 // Registry key size limit is 255 bytes and described there:
98 // https://msdn.microsoft.com/library/windows/desktop/ms724872.aspx
99 buf
:= make([]uint16, 256) //plus extra room for terminating zero byte
101 for i
:= uint32(0); ; i
++ {
107 l
:= uint32(len(buf
))
109 err
:= syscall
.RegEnumKeyEx(syscall
.Handle(k
), i
, &buf
[0], &l
, nil, nil, nil, nil)
113 if err
== syscall
.ERROR_MORE_DATA
{
114 // Double buffer size and try again.
115 l
= uint32(2 * len(buf
))
116 buf
= make([]uint16, l
)
119 if err
== _ERROR_NO_MORE_ITEMS
{
124 names
= append(names
, syscall
.UTF16ToString(buf
[:l
]))
132 // CreateKey creates a key named path under open key k.
133 // CreateKey returns the new key and a boolean flag that reports
134 // whether the key already existed.
135 // The access parameter specifies the access rights for the key
137 func CreateKey(k Key
, path
string, access
uint32) (newk Key
, openedExisting
bool, err error
) {
140 err
= regCreateKeyEx(syscall
.Handle(k
), syscall
.StringToUTF16Ptr(path
),
141 0, nil, _REG_OPTION_NON_VOLATILE
, access
, nil, &h
, &d
)
145 return Key(h
), d
== _REG_OPENED_EXISTING_KEY
, nil
148 // DeleteKey deletes the subkey path of key k and its values.
149 func DeleteKey(k Key
, path
string) error
{
150 return regDeleteKey(syscall
.Handle(k
), syscall
.StringToUTF16Ptr(path
))
153 // A KeyInfo describes the statistics of a key. It is returned by Stat.
154 type KeyInfo
struct {
156 MaxSubKeyLen
uint32 // size of the key's subkey with the longest name, in Unicode characters, not including the terminating zero byte
158 MaxValueNameLen
uint32 // size of the key's longest value name, in Unicode characters, not including the terminating zero byte
159 MaxValueLen
uint32 // longest data component among the key's values, in bytes
160 lastWriteTime syscall
.Filetime
163 // Stat retrieves information about the open key k.
164 func (k Key
) Stat() (*KeyInfo
, error
) {
166 err
:= syscall
.RegQueryInfoKey(syscall
.Handle(k
), nil, nil, nil,
167 &ki
.SubKeyCount
, &ki
.MaxSubKeyLen
, nil, &ki
.ValueCount
,
168 &ki
.MaxValueNameLen
, &ki
.MaxValueLen
, nil, &ki
.lastWriteTime
)