Cygwin: strptime: add release note
[newlib-cygwin.git] / winsup / cygwin / registry.cc
blob273067143616b58fdfa06cae064f77dfe62a1719
1 /* registry.cc: registry interface
3 This file is part of Cygwin.
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
7 details. */
9 #include "winsup.h"
10 #include "registry.h"
11 #include "cygerrno.h"
12 #include "path.h"
13 #include "fhandler.h"
14 #include "dtable.h"
15 #include "cygheap.h"
16 #include "tls_pbuf.h"
17 #include "ntdll.h"
18 #include <wchar.h>
20 /* Opens a key under the appropriate Cygwin key.
21 Do not use HKCU per MS KB 199190 */
22 static NTSTATUS
23 top_key (bool isHKLM, REGSAM access, PHANDLE top)
25 WCHAR rbuf[PATH_MAX], *p;
26 UNICODE_STRING rpath;
27 OBJECT_ATTRIBUTES attr;
28 NTSTATUS status;
30 InitializeObjectAttributes (&attr, &rpath, OBJ_CASE_INSENSITIVE, NULL, NULL);
31 if (isHKLM)
33 wcpcpy (rbuf, L"\\Registry\\Machine");
34 RtlInitUnicodeString (&rpath, rbuf);
35 status = NtOpenKey (top, access, &attr);
37 else
39 WCHAR name[128];
40 PCWSTR names[2] = {cygheap->user.get_windows_id (name),
41 L".DEFAULT"};
43 p = wcpcpy (rbuf, L"\\Registry\\User\\");
44 for (int i = 0; i < 2; i++)
46 wcpcpy (p, names[i]);
47 RtlInitUnicodeString (&rpath, rbuf);
48 status = NtOpenKey (top, access, &attr);
49 if (NT_SUCCESS (status))
50 break;
53 return status;
56 reg_key::reg_key (HKEY top, REGSAM access, ...): _disposition (0)
58 va_list av;
59 va_start (av, access);
60 build_reg (top, access, av);
61 va_end (av);
64 reg_key::reg_key (bool isHKLM, REGSAM access, ...): _disposition (0)
66 va_list av;
67 HANDLE top;
69 key_is_invalid = top_key (isHKLM, access, &top);
70 if (NT_SUCCESS (key_is_invalid))
72 new (this) reg_key ((HKEY) top, access, L"SOFTWARE",
73 _WIDE (CYGWIN_INFO_CYGWIN_REGISTRY_NAME), NULL);
74 NtClose (top);
75 if (key_is_invalid)
76 return;
77 top = key;
78 va_start (av, access);
79 build_reg ((HKEY) top, access, av);
80 va_end (av);
81 if (top != key)
82 NtClose (top);
86 void
87 reg_key::build_reg (HKEY top, REGSAM access, va_list av)
89 PWCHAR name;
90 HANDLE r;
91 UNICODE_STRING uname;
92 OBJECT_ATTRIBUTES attr;
93 NTSTATUS status;
95 if (top != HKEY_LOCAL_MACHINE && top != HKEY_CURRENT_USER)
96 r = (HANDLE) top;
97 else if (!NT_SUCCESS (top_key (top == HKEY_LOCAL_MACHINE, access, &r)))
98 return;
99 key_is_invalid = 0;
100 while ((name = va_arg (av, PWCHAR)) != NULL)
102 RtlInitUnicodeString (&uname, name);
103 InitializeObjectAttributes (&attr, &uname,
104 OBJ_CASE_INSENSITIVE | OBJ_OPENIF, r, NULL);
106 status = NtCreateKey (&key, access, &attr, 0, NULL,
107 REG_OPTION_NON_VOLATILE, &_disposition);
108 if (r != (HANDLE) top)
109 NtClose (r);
110 r = key;
111 if (!NT_SUCCESS (status))
113 key_is_invalid = status;
114 debug_printf ("failed to create key %S in the registry", &uname);
115 break;
120 /* Given the current registry key, return the specific DWORD value
121 requested. Return def on failure. */
123 DWORD
124 reg_key::get_dword (PCWSTR name, DWORD def)
126 if (key_is_invalid)
127 return def;
129 NTSTATUS status;
130 UNICODE_STRING uname;
131 ULONG size = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + sizeof (DWORD);
132 ULONG rsize;
133 PKEY_VALUE_PARTIAL_INFORMATION vbuf = (PKEY_VALUE_PARTIAL_INFORMATION)
134 alloca (size);
136 RtlInitUnicodeString (&uname, name);
137 status = NtQueryValueKey (key, &uname, KeyValuePartialInformation, vbuf,
138 size, &rsize);
139 if (status != STATUS_SUCCESS || vbuf->Type != REG_DWORD)
140 return def;
141 DWORD *dst = (DWORD *) vbuf->Data;
142 return *dst;
145 /* Given the current registry key, set a specific DWORD value. */
147 NTSTATUS
148 reg_key::set_dword (PCWSTR name, DWORD val)
150 if (key_is_invalid)
151 return key_is_invalid;
153 DWORD value = (DWORD) val;
154 UNICODE_STRING uname;
155 RtlInitUnicodeString (&uname, name);
156 return NtSetValueKey (key, &uname, 0, REG_DWORD, &value, sizeof (value));
159 /* Given the current registry key, return the specific string value
160 requested. Return zero on success, non-zero on failure. */
162 NTSTATUS
163 reg_key::get_string (PCWSTR name, PWCHAR dst, size_t max, PCWSTR def)
165 NTSTATUS status;
167 if (key_is_invalid)
169 status = key_is_invalid;
170 if (def != NULL)
171 wcpncpy (dst, def, max);
173 else
175 UNICODE_STRING uname;
176 ULONG size = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + max * sizeof (WCHAR);
177 ULONG rsize;
178 PKEY_VALUE_PARTIAL_INFORMATION vbuf = (PKEY_VALUE_PARTIAL_INFORMATION)
179 alloca (size);
181 RtlInitUnicodeString (&uname, name);
182 status = NtQueryValueKey (key, &uname, KeyValuePartialInformation, vbuf,
183 size, &rsize);
184 if (status != STATUS_SUCCESS || vbuf->Type != REG_SZ)
185 wcpncpy (dst, def, max);
186 else
187 wcpncpy (dst, (PWCHAR) vbuf->Data, max);
189 return status;
192 /* Given the current registry key, set a specific string value. */
194 NTSTATUS
195 reg_key::set_string (PCWSTR name, PCWSTR src)
197 if (key_is_invalid)
198 return key_is_invalid;
200 UNICODE_STRING uname;
201 RtlInitUnicodeString (&uname, name);
202 return NtSetValueKey (key, &uname, 0, REG_SZ, (PVOID) src,
203 (wcslen (src) + 1) * sizeof (WCHAR));
206 reg_key::~reg_key ()
208 if (!key_is_invalid)
209 NtClose (key);
210 key_is_invalid = 1;