1 /* registry.cc: registry interface
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
24 /* Opens a key under the appropriate Cygwin key.
25 Do not use HKCU per MS KB 199190 */
27 top_key (bool isHKLM, REGSAM access, PHANDLE top)
29 WCHAR rbuf[PATH_MAX], *p;
31 OBJECT_ATTRIBUTES attr;
34 InitializeObjectAttributes (&attr, &rpath, OBJ_CASE_INSENSITIVE, NULL, NULL);
37 wcpcpy (rbuf, L"\\Registry\\Machine");
38 RtlInitUnicodeString (&rpath, rbuf);
39 status = NtOpenKey (top, access, &attr);
44 PCWSTR names[2] = {cygheap->user.get_windows_id (name),
47 p = wcpcpy (rbuf, L"\\Registry\\User\\");
48 for (int i = 0; i < 2; i++)
51 RtlInitUnicodeString (&rpath, rbuf);
52 status = NtOpenKey (top, access, &attr);
53 if (NT_SUCCESS (status))
60 reg_key::reg_key (HKEY top, REGSAM access, ...): _disposition (0)
63 va_start (av, access);
64 build_reg (top, access, av);
68 reg_key::reg_key (bool isHKLM, REGSAM access, ...): _disposition (0)
73 key_is_invalid = top_key (isHKLM, access, &top);
74 if (NT_SUCCESS (key_is_invalid))
76 new (this) reg_key ((HKEY) top, access, L"SOFTWARE",
77 _WIDE (CYGWIN_INFO_CYGWIN_REGISTRY_NAME), NULL);
82 va_start (av, access);
83 build_reg ((HKEY) top, access, av);
91 reg_key::build_reg (HKEY top, REGSAM access, va_list av)
96 OBJECT_ATTRIBUTES attr;
99 if (top != HKEY_LOCAL_MACHINE && top != HKEY_CURRENT_USER)
101 else if (!NT_SUCCESS (top_key (top == HKEY_LOCAL_MACHINE, access, &r)))
104 while ((name = va_arg (av, PWCHAR)) != NULL)
106 RtlInitUnicodeString (&uname, name);
107 InitializeObjectAttributes (&attr, &uname,
108 OBJ_CASE_INSENSITIVE | OBJ_OPENIF, r, NULL);
110 status = NtCreateKey (&key, access, &attr, 0, NULL,
111 REG_OPTION_NON_VOLATILE, &_disposition);
112 if (r != (HANDLE) top)
115 if (!NT_SUCCESS (status))
117 key_is_invalid = status;
118 debug_printf ("failed to create key %S in the registry", uname);
124 /* Given the current registry key, return the specific DWORD value
125 requested. Return def on failure. */
128 reg_key::get_dword (PCWSTR name, DWORD def)
134 UNICODE_STRING uname;
135 ULONG size = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + sizeof (DWORD);
137 PKEY_VALUE_PARTIAL_INFORMATION vbuf = (PKEY_VALUE_PARTIAL_INFORMATION)
140 RtlInitUnicodeString (&uname, name);
141 status = NtQueryValueKey (key, &uname, KeyValuePartialInformation, vbuf,
143 if (status != STATUS_SUCCESS || vbuf->Type != REG_DWORD)
145 DWORD *dst = (DWORD *) vbuf->Data;
149 /* Given the current registry key, set a specific DWORD value. */
152 reg_key::set_dword (PCWSTR name, DWORD val)
155 return key_is_invalid;
157 DWORD value = (DWORD) val;
158 UNICODE_STRING uname;
159 RtlInitUnicodeString (&uname, name);
160 return NtSetValueKey (key, &uname, 0, REG_DWORD, &value, sizeof (value));
163 /* Given the current registry key, return the specific string value
164 requested. Return zero on success, non-zero on failure. */
167 reg_key::get_string (PCWSTR name, PWCHAR dst, size_t max, PCWSTR def)
173 status = key_is_invalid;
175 wcpncpy (dst, def, max);
179 UNICODE_STRING uname;
180 ULONG size = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + max * sizeof (WCHAR);
182 PKEY_VALUE_PARTIAL_INFORMATION vbuf = (PKEY_VALUE_PARTIAL_INFORMATION)
185 RtlInitUnicodeString (&uname, name);
186 status = NtQueryValueKey (key, &uname, KeyValuePartialInformation, vbuf,
188 if (status != STATUS_SUCCESS || vbuf->Type != REG_SZ)
189 wcpncpy (dst, def, max);
191 wcpncpy (dst, (PWCHAR) vbuf->Data, max);
196 /* Given the current registry key, set a specific string value. */
199 reg_key::set_string (PCWSTR name, PCWSTR src)
202 return key_is_invalid;
204 UNICODE_STRING uname;
205 RtlInitUnicodeString (&uname, name);
206 return NtSetValueKey (key, &uname, 0, REG_SZ, (PVOID) src,
207 (wcslen (src) + 1) * sizeof (WCHAR));
218 get_registry_hive_path (PCWSTR name, PWCHAR path)
229 RTL_QUERY_REGISTRY_TABLE tab[2] = {
230 { NULL, RTL_QUERY_REGISTRY_NOEXPAND | RTL_QUERY_REGISTRY_DIRECT
231 | RTL_QUERY_REGISTRY_REQUIRED,
232 L"ProfileImagePath", &buf, REG_NONE, NULL, 0 },
233 { NULL, 0, NULL, NULL, 0, NULL, 0 }
235 wcpcpy (wcpcpy (key, L"ProfileList\\"), name);
236 status = RtlQueryRegistryValues (RTL_REGISTRY_WINDOWS_NT, key, tab,
238 if (!NT_SUCCESS (status) || buf.Length == 0)
240 debug_printf ("ProfileImagePath for %W not found, status %p", name,
244 wcpcpy (path, L"\\??\\");
245 ExpandEnvironmentStringsW (buf.Buffer, path + 4, NT_MAX_PATH - 4);
246 debug_printf ("ProfileImagePath for %W: %W", name, path);
251 load_registry_hive (PCWSTR name)
256 /* Fetch the path. */
258 PWCHAR path = tp.w_get ();
259 if (!get_registry_hive_path (name, path))
263 UNICODE_STRING ukey, upath;
264 OBJECT_ATTRIBUTES key_attr, path_attr;
267 /* Create the object attributes for key and path. */
268 wcpcpy (wcpcpy (key, L"\\Registry\\User\\"), name);
269 RtlInitUnicodeString (&ukey, key);
270 InitializeObjectAttributes (&key_attr, &ukey, OBJ_CASE_INSENSITIVE,
272 wcscat (path, L"\\NTUSER.DAT");
273 RtlInitUnicodeString (&upath, path);
274 InitializeObjectAttributes (&path_attr, &upath, OBJ_CASE_INSENSITIVE,
276 /* Load file into key. */
277 status = NtLoadKey (&key_attr, &path_attr);
278 if (!NT_SUCCESS (status))
279 debug_printf ("Loading user registry hive %S into %S failed: %p",
280 &upath, &ukey, status);
282 debug_printf ("Loading user registry hive %S into %S SUCCEEDED: %p",
283 &upath, &ukey, status);