* Makefile.in (DLL_IMPORTS): Drop advapi32.dll.

* autoload.cc: Enable autoloading advapi32 functions.
	* environ.cc (regopt): Use wide char arguments in reg_key functions.
	* fhandler_console.cc (beep): Ditto.  Use WCHAR throughout.
	* registry.cc (reg_key): Rewrite reg_key class to use native NT registry
	functions.  Use WCHAR string parameters throughout.  Use PCWSTR rather
	than const WCHAR.  Drop multibyte char functionality.  Drop unused
	methods.
	(get_registry_hive_path): Use RtlQueryRegistryValues to fetch path from
	registry.
	(load_registry_hive): Drop useless check for user hive being available.
	Load hive using NtLoadKey.
	* registry.h: Accommodate above changes.
	* sched.cc (sched_rr_get_interval): Use wide char arguments in reg_key
	functions.
	* shared.cc (init_installation_root): Ditto.
	(shared_info::init_obcaseinsensitive): Use RtlQueryRegistryValues to
	fetch obcaseinsensitive value.
	(shared_info::heap_slop_size): Use wide char arguments in reg_key
	functions.
	(shared_info::heap_chunk_size): Ditto.
	* syscalls.cc (gethostid): Ditto.
	* winsup.h (__WIDE): Define.
	(_WIDE): Define.
	* libc/minires-os-if.c (get_registry_dns_items): Don't fetch values
	from registry.  Just extract them from given UNICODE_STRING parameter.
	(get_registry_dns): Fetch all registry values at once using
	RtlQueryRegistryValues.
This commit is contained in:
Corinna Vinschen 2011-04-19 10:02:06 +00:00
parent cbc26145e8
commit b18cb86be7
12 changed files with 322 additions and 299 deletions

View File

@ -1,3 +1,34 @@
2011-04-19 Corinna Vinschen <corinna@vinschen.de>
* Makefile.in (DLL_IMPORTS): Drop advapi32.dll.
* autoload.cc: Enable autoloading advapi32 functions.
* environ.cc (regopt): Use wide char arguments in reg_key functions.
* fhandler_console.cc (beep): Ditto. Use WCHAR throughout.
* registry.cc (reg_key): Rewrite reg_key class to use native NT registry
functions. Use WCHAR string parameters throughout. Use PCWSTR rather
than const WCHAR. Drop multibyte char functionality. Drop unused
methods.
(get_registry_hive_path): Use RtlQueryRegistryValues to fetch path from
registry.
(load_registry_hive): Drop useless check for user hive being available.
Load hive using NtLoadKey.
* registry.h: Accommodate above changes.
* sched.cc (sched_rr_get_interval): Use wide char arguments in reg_key
functions.
* shared.cc (init_installation_root): Ditto.
(shared_info::init_obcaseinsensitive): Use RtlQueryRegistryValues to
fetch obcaseinsensitive value.
(shared_info::heap_slop_size): Use wide char arguments in reg_key
functions.
(shared_info::heap_chunk_size): Ditto.
* syscalls.cc (gethostid): Ditto.
* winsup.h (__WIDE): Define.
(_WIDE): Define.
* libc/minires-os-if.c (get_registry_dns_items): Don't fetch values
from registry. Just extract them from given UNICODE_STRING parameter.
(get_registry_dns): Fetch all registry values at once using
RtlQueryRegistryValues.
2011-04-19 Corinna Vinschen <corinna@vinschen.de> 2011-04-19 Corinna Vinschen <corinna@vinschen.de>
* net.cc (get_ipv4fromreg_ipcnt): Rearrange to fetch all registry * net.cc (get_ipv4fromreg_ipcnt): Rearrange to fetch all registry

View File

@ -130,7 +130,7 @@ EXTRA_OFILES:=
MALLOC_OFILES:=@MALLOC_OFILES@ MALLOC_OFILES:=@MALLOC_OFILES@
DLL_IMPORTS:=$(w32api_lib)/libadvapi32.a $(w32api_lib)/libkernel32.a $(w32api_lib)/libntdll.a DLL_IMPORTS:=$(w32api_lib)/libkernel32.a $(w32api_lib)/libntdll.a
MT_SAFE_OBJECTS:= MT_SAFE_OBJECTS:=
# Please maintain this list in sorted order, with maximum files per 86 col line # Please maintain this list in sorted order, with maximum files per 86 col line

View File

@ -352,9 +352,6 @@ wsock_init ()
LoadDLLprime (ws2_32, _wsock_init, 0) LoadDLLprime (ws2_32, _wsock_init, 0)
#if 0
/* Don't enable until libadvapi32.a has been removed from DLL_IMPORTS,
otherwise mintty will stop working on pre-Vista for some reason. */
LoadDLLfunc (CreateProcessAsUserW, 44, advapi32) LoadDLLfunc (CreateProcessAsUserW, 44, advapi32)
LoadDLLfunc (CryptAcquireContextW, 20, advapi32) LoadDLLfunc (CryptAcquireContextW, 20, advapi32)
LoadDLLfunc (CryptGenRandom, 12, advapi32) LoadDLLfunc (CryptGenRandom, 12, advapi32)
@ -381,7 +378,6 @@ LoadDLLfunc (RegQueryInfoKeyW, 48, advapi32)
LoadDLLfunc (RegQueryValueExW, 24, advapi32) LoadDLLfunc (RegQueryValueExW, 24, advapi32)
LoadDLLfunc (RegisterEventSourceW, 8, advapi32) LoadDLLfunc (RegisterEventSourceW, 8, advapi32)
LoadDLLfunc (ReportEventW, 36, advapi32) LoadDLLfunc (ReportEventW, 36, advapi32)
#endif
LoadDLLfunc (DnsQuery_A, 24, dnsapi) LoadDLLfunc (DnsQuery_A, 24, dnsapi)
LoadDLLfunc (DnsRecordListFree, 8, dnsapi) LoadDLLfunc (DnsRecordListFree, 8, dnsapi)

View File

@ -2,7 +2,7 @@
process's environment. process's environment.
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007, 2008, 2009 Red Hat, Inc. 2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
This software is a copyrighted work licensed under the terms of the This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for Cygwin license. Please consult the file "CYGWIN_LICENSE" for
@ -710,7 +710,7 @@ regopt (const WCHAR *name, char *buf)
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
reg_key r (i, KEY_READ, CYGWIN_INFO_PROGRAM_OPTIONS_NAME, NULL); reg_key r (i, KEY_READ, _WIDE (CYGWIN_INFO_PROGRAM_OPTIONS_NAME), NULL);
if (r.get_string (lname.Buffer, (PWCHAR) buf, NT_MAX_PATH, L"") == ERROR_SUCCESS) if (r.get_string (lname.Buffer, (PWCHAR) buf, NT_MAX_PATH, L"") == ERROR_SUCCESS)
{ {

View File

@ -61,16 +61,17 @@ dev_console NO_COPY *fhandler_console::dev_state;
static void static void
beep () beep ()
{ {
reg_key r (HKEY_CURRENT_USER, KEY_ALL_ACCESS, "AppEvents", "Schemes", "Apps", const WCHAR ding[] = L"\\media\\ding.wav";
".Default", ".Default", ".Current", NULL); reg_key r (HKEY_CURRENT_USER, KEY_ALL_ACCESS, L"AppEvents", L"Schemes",
L"Apps", L".Default", L".Default", L".Current", NULL);
if (r.created ()) if (r.created ())
{ {
char *buf = NULL; PWCHAR buf = NULL;
UINT len = GetWindowsDirectory (buf, 0); UINT len = GetWindowsDirectoryW (buf, 0) * sizeof (WCHAR);
buf = (char *) alloca (len += sizeof ("\\media\\ding.wav")); buf = (PWCHAR) alloca (len += sizeof (ding));
UINT res = GetWindowsDirectory (buf, len); UINT res = GetWindowsDirectoryW (buf, len);
if (res && res <= len) if (res && res <= len)
r.set_string ("", strcat (buf, "\\media\\ding.wav")); r.set_string (L"", wcscat (buf, ding));
} }
MessageBeep (MB_OK); MessageBeep (MB_OK);
} }

View File

@ -1,6 +1,6 @@
/* minires-os-if.c. Stub synchronous resolver for Cygwin. /* minires-os-if.c. Stub synchronous resolver for Cygwin.
Copyright 2006, 2007, 2008, 2009 Red Hat, Inc. Copyright 2006, 2007, 2008, 2009, 2011 Red Hat, Inc.
Written by Pierre A. Humblet <Pierre.Humblet@ieee.org> Written by Pierre A. Humblet <Pierre.Humblet@ieee.org>
@ -27,6 +27,9 @@ details. */
#include <windows.h> #include <windows.h>
#include <iphlpapi.h> #include <iphlpapi.h>
#include <windns.h> #include <windns.h>
#include <ntdef.h>
#include "ntdll.h"
#include <wchar.h>
/*********************************************************************** /***********************************************************************
* write_record: Translates a Windows DNS record into a compressed record * write_record: Translates a Windows DNS record into a compressed record
@ -291,36 +294,25 @@ done:
* *
get_registry_items: returns dns items from the registry get_registry_items: returns dns items from the registry
kHey: Handle to registry key in: Unicode representation of registry value "value".
KeyValue: key value to read
what: 0 addresses ; 1 search list what: 0 addresses ; 1 search list
***********************************************************************/ ***********************************************************************/
static void get_registry_dns_items(HKEY hKey, LPCTSTR KeyValue, static void get_registry_dns_items(PUNICODE_STRING in, res_state statp,
res_state statp, int what) int what)
{ {
DWORD size = 0;
LONG res;
LPBYTE list;
int debug = statp->options & RES_DEBUG; int debug = statp->options & RES_DEBUG;
res = RegQueryValueEx( hKey, KeyValue, NULL, NULL, NULL, &size); if (in->Length) {
DPRINTF(debug, "value %s, error %lu (Windows), size %lu\n", char list[in->Length];
KeyValue, res, size); size_t size = wcstombs (list, in->Buffer, in->Length);
if ((res == ERROR_SUCCESS) && (size > 1)) { if (what == 0) { /* Get the addresses */
if (!(list = (LPBYTE) alloca(size))) { char *ap, *srch;
DPRINTF(debug, "alloca: %s\n", strerror(errno));
}
else if ((res = RegQueryValueEx( hKey, KeyValue, NULL, NULL, list,
&size )) != ERROR_SUCCESS) {
DPRINTF(debug, "RegQueryValueEx: error %lu (Windows)\n", res);
}
else if (what == 0) { /* Get the addresses */
BYTE *ap, *srch;
int numAddresses = 0; int numAddresses = 0;
for (ap = list; ap < list + size && *ap; ap = srch) { for (ap = list; ap < list + size && *ap; ap = srch) {
/* The separation character can be 0, ' ', or ','. */ /* The separation character can be 0, ' ', or ','. */
for (srch = ap; *srch && (isdigit(*srch) || *srch == '.' ); srch++); for (srch = ap; *srch && (isdigit((unsigned) *srch) || *srch == '.' );
srch++);
*srch++ = 0; *srch++ = 0;
if (numAddresses < DIM(statp->nsaddr_list)) { if (numAddresses < DIM(statp->nsaddr_list)) {
DPRINTF(debug, "server \"%s\"\n", ap); DPRINTF(debug, "server \"%s\"\n", ap);
@ -334,7 +326,7 @@ static void get_registry_dns_items(HKEY hKey, LPCTSTR KeyValue,
statp->nscount = numAddresses; statp->nscount = numAddresses;
} }
else /* Parse the search line */ else /* Parse the search line */
minires_get_search((char *) list, statp); minires_get_search(list, statp);
} }
return; return;
} }
@ -351,25 +343,52 @@ static void get_registry_dns_items(HKEY hKey, LPCTSTR KeyValue,
static void get_registry_dns(res_state statp) static void get_registry_dns(res_state statp)
{ {
HKEY hKey; NTSTATUS status;
DWORD res; const PCWSTR keyName = L"Tcpip\\Parameters";
const char *keyName = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters";
DPRINTF(statp->options & RES_DEBUG, "key %s\n", keyName); DPRINTF(statp->options & RES_DEBUG, "key %s\n", keyName);
if ((res = RegOpenKeyEx( HKEY_LOCAL_MACHINE, keyName, 0, status = RtlCheckRegistryKey (RTL_REGISTRY_SERVICES, keyName);
KEY_QUERY_VALUE | KEY_READ, &hKey)) != ERROR_SUCCESS) { if (!NT_SUCCESS (status))
DPRINTF(statp->options & RES_DEBUG, "RegOpenKeyEx: error %lu (Windows)\n", res); {
DPRINTF (statp->options & RES_DEBUG, "RtlCheckRegistryKey: status %p\n",
status);
return;
}
UNICODE_STRING uns = { 0, 0, NULL };
UNICODE_STRING udns = { 0, 0, NULL };
UNICODE_STRING usl = { 0, 0, NULL };
RTL_QUERY_REGISTRY_TABLE tab[4] = {
{ NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND,
L"NameServer", &uns, REG_NONE, NULL, 0 },
{ NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND,
L"DhcpNameServer", &udns, REG_NONE, NULL, 0 },
{ NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND,
L"SearchList", &usl, REG_NONE, NULL, 0 },
};
status = RtlQueryRegistryValues (RTL_REGISTRY_SERVICES, keyName, tab,
NULL, NULL);
if (!NT_SUCCESS (status))
{
DPRINTF (statp->options & RES_DEBUG,
"RtlQueryRegistryValues: status %p\n", status);
return; return;
} }
if (statp->nscount == 0) if (statp->nscount == 0)
get_registry_dns_items(hKey, "NameServer", statp, 0); get_registry_dns_items(&uns, statp, 0);
if (statp->nscount == 0) if (statp->nscount == 0)
get_registry_dns_items(hKey, "DhcpNameServer", statp, 0); get_registry_dns_items(&udns, statp, 0);
if (statp->dnsrch[0] == NULL) if (statp->dnsrch[0] == NULL)
get_registry_dns_items(hKey, "SearchList", statp, 1); get_registry_dns_items(&usl, statp, 1);
RegCloseKey(hKey); if (uns.Buffer)
RtlFreeUnicodeString (&uns);
if (udns.Buffer)
RtlFreeUnicodeString (&udns);
if (usl.Buffer)
RtlFreeUnicodeString (&usl);
return; return;
} }

View File

@ -1,7 +1,7 @@
/* registry.cc: registry interface /* registry.cc: registry interface
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009 Red Hat, Inc. 2005, 2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -17,7 +17,45 @@ details. */
#include "dtable.h" #include "dtable.h"
#include "cygheap.h" #include "cygheap.h"
#include "tls_pbuf.h" #include "tls_pbuf.h"
#include "ntdll.h"
#include <wchar.h> #include <wchar.h>
#include <alloca.h>
/* Opens a key under the appropriate Cygwin key.
Do not use HKCU per MS KB 199190 */
static NTSTATUS
top_key (bool isHKLM, REGSAM access, PHANDLE top)
{
WCHAR rbuf[PATH_MAX], *p;
UNICODE_STRING rpath;
OBJECT_ATTRIBUTES attr;
NTSTATUS status;
InitializeObjectAttributes (&attr, &rpath, OBJ_CASE_INSENSITIVE, NULL, NULL);
if (isHKLM)
{
wcpcpy (rbuf, L"\\Registry\\Machine");
RtlInitUnicodeString (&rpath, rbuf);
status = NtOpenKey (top, access, &attr);
}
else
{
WCHAR name[128];
PCWSTR names[2] = {cygheap->user.get_windows_id (name),
L".DEFAULT"};
p = wcpcpy (rbuf, L"\\Registry\\User\\");
for (int i = 0; i < 2; i++)
{
wcpcpy (p, names[i]);
RtlInitUnicodeString (&rpath, rbuf);
status = NtOpenKey (top, access, &attr);
if (NT_SUCCESS (status))
break;
}
}
return status;
}
reg_key::reg_key (HKEY top, REGSAM access, ...): _disposition (0) reg_key::reg_key (HKEY top, REGSAM access, ...): _disposition (0)
{ {
@ -27,75 +65,57 @@ reg_key::reg_key (HKEY top, REGSAM access, ...): _disposition (0)
va_end (av); va_end (av);
} }
/* Opens a key under the appropriate Cygwin key.
Do not use HKCU per MS KB 199190 */
reg_key::reg_key (bool isHKLM, REGSAM access, ...): _disposition (0) reg_key::reg_key (bool isHKLM, REGSAM access, ...): _disposition (0)
{ {
va_list av; va_list av;
HKEY top; HANDLE top;
if (isHKLM) key_is_invalid = top_key (isHKLM, access, &top);
top = HKEY_LOCAL_MACHINE; if (NT_SUCCESS (key_is_invalid))
else
{ {
char name[128]; new (this) reg_key ((HKEY) top, access, L"SOFTWARE",
const char *names[2] = {cygheap->user.get_windows_id (name), ".DEFAULT"}; _WIDE (CYGWIN_INFO_CYGWIN_REGISTRY_NAME), NULL);
for (int i = 0; i < 2; i++) NtClose (top);
{
key_is_invalid = RegOpenKeyEx (HKEY_USERS, names[i], 0, access, &top);
if (key_is_invalid == ERROR_SUCCESS)
goto OK;
debug_printf ("HKU\\%s failed, Win32 error %ld", names[i], key_is_invalid);
}
return;
}
OK:
new (this) reg_key (top, access, "SOFTWARE",
CYGWIN_INFO_CYGWIN_REGISTRY_NAME, NULL);
if (top != HKEY_LOCAL_MACHINE)
RegCloseKey (top);
if (key_is_invalid) if (key_is_invalid)
return; return;
top = key; top = key;
va_start (av, access); va_start (av, access);
build_reg (top, access, av); build_reg ((HKEY) top, access, av);
va_end (av); va_end (av);
if (top != key) if (top != key)
RegCloseKey (top); NtClose (top);
}
} }
void void
reg_key::build_reg (HKEY top, REGSAM access, va_list av) reg_key::build_reg (HKEY top, REGSAM access, va_list av)
{ {
char *name; PWCHAR name;
HKEY r = top; HANDLE r;
UNICODE_STRING uname;
OBJECT_ATTRIBUTES attr;
NTSTATUS status;
if (top != HKEY_LOCAL_MACHINE && top != HKEY_CURRENT_USER)
r = (HANDLE) top;
else if (!NT_SUCCESS (top_key (top == HKEY_LOCAL_MACHINE, access, &r)))
return;
key_is_invalid = 0; key_is_invalid = 0;
while ((name = va_arg (av, PWCHAR)) != NULL)
/* FIXME: Most of the time a valid mount area should exist. Perhaps
we should just try an open of the correct key first and only resort
to this method in the unlikely situation that it's the first time
the current mount areas are being used. */
while ((name = va_arg (av, char *)) != NULL)
{ {
int res = RegCreateKeyExA (r, RtlInitUnicodeString (&uname, name);
name, InitializeObjectAttributes (&attr, &uname,
0, OBJ_CASE_INSENSITIVE | OBJ_OPENIF, r, NULL);
NULL,
REG_OPTION_NON_VOLATILE, status = NtCreateKey (&key, access, &attr, 0, NULL,
access, REG_OPTION_NON_VOLATILE, &_disposition);
&sec_none_nih, if (r != (HANDLE) top)
&key, NtClose (r);
&_disposition);
if (r != top)
RegCloseKey (r);
r = key; r = key;
if (res != ERROR_SUCCESS) if (!NT_SUCCESS (status))
{ {
key_is_invalid = res; key_is_invalid = status;
debug_printf ("failed to create key %s in the registry", name); debug_printf ("failed to create key %S in the registry", uname);
break; break;
} }
} }
@ -105,209 +125,164 @@ reg_key::build_reg (HKEY top, REGSAM access, va_list av)
requested. Return def on failure. */ requested. Return def on failure. */
int int
reg_key::get_int (const char *name, int def) reg_key::get_int (PCWSTR name, int def)
{ {
DWORD type;
DWORD dst;
DWORD size = sizeof (dst);
if (key_is_invalid) if (key_is_invalid)
return def; return def;
LONG res = RegQueryValueExA (key, name, 0, &type, (LPBYTE) &dst, &size); NTSTATUS status;
UNICODE_STRING uname;
ULONG size = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + sizeof (DWORD);
ULONG rsize;
PKEY_VALUE_PARTIAL_INFORMATION vbuf = (PKEY_VALUE_PARTIAL_INFORMATION)
alloca (size);
if (type != REG_DWORD || res != ERROR_SUCCESS) RtlInitUnicodeString (&uname, name);
status = NtQueryValueKey (key, &uname, KeyValuePartialInformation, vbuf,
size, &rsize);
if (status != STATUS_SUCCESS || vbuf->Type != REG_DWORD)
return def; return def;
DWORD dst = *(DWORD *) vbuf->Data;
return dst; return (int) dst;
}
int
reg_key::get_int (const WCHAR *name, int def)
{
DWORD type;
DWORD dst;
DWORD size = sizeof (dst);
if (key_is_invalid)
return def;
LONG res = RegQueryValueExW (key, name, 0, &type, (LPBYTE) &dst, &size);
if (type != REG_DWORD || res != ERROR_SUCCESS)
return def;
return dst;
} }
/* Given the current registry key, set a specific int value. */ /* Given the current registry key, set a specific int value. */
int int
reg_key::set_int (const char *name, int val) reg_key::set_int (PCWSTR name, int val)
{ {
DWORD value = val;
if (key_is_invalid) if (key_is_invalid)
return key_is_invalid; return key_is_invalid;
return (int) RegSetValueExA (key, name, 0, REG_DWORD, DWORD value = (DWORD) val;
(const BYTE *) &value, sizeof (value)); UNICODE_STRING uname;
} RtlInitUnicodeString (&uname, name);
NTSTATUS status = NtSetValueKey (key, &uname, 0, REG_DWORD,
int &value, sizeof (value));
reg_key::set_int (const PWCHAR name, int val) return (int) status;
{
DWORD value = val;
if (key_is_invalid)
return key_is_invalid;
return (int) RegSetValueExW (key, name, 0, REG_DWORD,
(const BYTE *) &value, sizeof (value));
} }
/* Given the current registry key, return the specific string value /* Given the current registry key, return the specific string value
requested. Return zero on success, non-zero on failure. */ requested. Return zero on success, non-zero on failure. */
int int
reg_key::get_string (const char *name, char *dst, size_t max, const char *def) reg_key::get_string (PCWSTR name, PWCHAR dst, size_t max, PCWSTR def)
{ {
DWORD size = max; NTSTATUS status;
DWORD type;
LONG res;
if (key_is_invalid) if (key_is_invalid)
res = key_is_invalid; {
status = key_is_invalid;
if (def != NULL)
wcpncpy (dst, def, max);
}
else else
res = RegQueryValueExA (key, name, 0, &type, (LPBYTE) dst, &size); {
UNICODE_STRING uname;
ULONG size = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + max * sizeof (WCHAR);
ULONG rsize;
PKEY_VALUE_PARTIAL_INFORMATION vbuf = (PKEY_VALUE_PARTIAL_INFORMATION)
alloca (size);
if ((def != 0) && ((type != REG_SZ) || (res != ERROR_SUCCESS))) RtlInitUnicodeString (&uname, name);
strcpy (dst, def); status = NtQueryValueKey (key, &uname, KeyValuePartialInformation, vbuf,
return (int) res; size, &rsize);
} if (status != STATUS_SUCCESS || vbuf->Type != REG_SZ)
wcpncpy (dst, def, max);
int
reg_key::get_string (const WCHAR *name, PWCHAR dst, size_t max, const WCHAR *def)
{
DWORD size = max;
DWORD type;
LONG res;
if (key_is_invalid)
res = key_is_invalid;
else else
res = RegQueryValueExW (key, name, 0, &type, (LPBYTE) dst, &size); wcpncpy (dst, (PWCHAR) vbuf->Data, max);
if ((def != 0) && ((type != REG_SZ) || (res != ERROR_SUCCESS))) }
wcscpy (dst, def); return (int) status;
return (int) res;
} }
/* Given the current registry key, set a specific string value. */ /* Given the current registry key, set a specific string value. */
int int
reg_key::set_string (const char *name, const char *src) reg_key::set_string (PCWSTR name, PCWSTR src)
{ {
if (key_is_invalid) if (key_is_invalid)
return key_is_invalid; return key_is_invalid;
return (int) RegSetValueExA (key, name, 0, REG_SZ, (const BYTE*) src,
strlen (src) + 1);
}
int UNICODE_STRING uname;
reg_key::set_string (const PWCHAR name, const PWCHAR src) RtlInitUnicodeString (&uname, name);
{ NTSTATUS status = NtSetValueKey (key, &uname, 0, REG_SZ, (PVOID) src,
if (key_is_invalid)
return key_is_invalid;
return (int) RegSetValueExW (key, name, 0, REG_SZ, (const BYTE*) src,
(wcslen (src) + 1) * sizeof (WCHAR)); (wcslen (src) + 1) * sizeof (WCHAR));
} return (int) status;
/* Return the handle to key. */
HKEY
reg_key::get_key ()
{
return key;
}
/* Delete subkey of current key. Returns the error code from the
RegDeleteKeyA invocation. */
int
reg_key::kill (const char *name)
{
if (key_is_invalid)
return key_is_invalid;
return RegDeleteKeyA (key, name);
}
/* Delete the value specified by name of current key. Returns the error code
from the RegDeleteValueA invocation. */
int
reg_key::killvalue (const char *name)
{
if (key_is_invalid)
return key_is_invalid;
return RegDeleteValueA (key, name);
} }
reg_key::~reg_key () reg_key::~reg_key ()
{ {
if (!key_is_invalid) if (!key_is_invalid)
RegCloseKey (key); NtClose (key);
key_is_invalid = 1; key_is_invalid = 1;
} }
PWCHAR PWCHAR
get_registry_hive_path (const PWCHAR name, PWCHAR path) get_registry_hive_path (PCWSTR name, PWCHAR path)
{ {
WCHAR key[256], *kend;
HKEY hkey;
if (!name || !path) if (!name || !path)
return NULL; return NULL;
kend = wcpcpy (key, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
wcpcpy (kend, name);
if (!RegOpenKeyExW (HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hkey))
{
tmp_pathbuf tp;
PWCHAR buf = tp.w_get ();
DWORD type, siz;
path[0] = L'\0'; WCHAR key[256];
if (!RegQueryValueExW (hkey, L"ProfileImagePath", 0, &type, UNICODE_STRING buf;
(BYTE *)buf, (siz = NT_MAX_PATH, &siz))) tmp_pathbuf tp;
ExpandEnvironmentStringsW (buf, path, NT_MAX_PATH); tp.u_get (&buf);
RegCloseKey (hkey); NTSTATUS status;
if (path[0])
return path; RTL_QUERY_REGISTRY_TABLE tab[2] = {
} { NULL, RTL_QUERY_REGISTRY_NOEXPAND | RTL_QUERY_REGISTRY_DIRECT
debug_printf ("HKLM\\%W not found", key); | RTL_QUERY_REGISTRY_REQUIRED,
L"ProfileImagePath", &buf, REG_NONE, NULL, 0 },
{ NULL, 0, NULL, NULL, 0, NULL, 0 }
};
wcpcpy (wcpcpy (key, L"ProfileList\\"), name);
status = RtlQueryRegistryValues (RTL_REGISTRY_WINDOWS_NT, key, tab,
NULL, NULL);
if (!NT_SUCCESS (status) || buf.Length == 0)
{
system_printf ("ProfileImagePath for %W not found, status %p", name,
status);
return NULL; return NULL;
}
wcpcpy (path, L"\\??\\");
ExpandEnvironmentStringsW (buf.Buffer, path + 4, NT_MAX_PATH - 4);
system_printf ("ProfileImagePath for %W: %W", name, path);
return path;
} }
void void
load_registry_hive (const PWCHAR name) load_registry_hive (PCWSTR name)
{ {
tmp_pathbuf tp;
PWCHAR path = tp.w_get ();
HKEY hkey;
LONG ret;
if (!name) if (!name)
return; return;
/* Check if user hive is already loaded. */
if (!RegOpenKeyExW (HKEY_USERS, name, 0, KEY_READ, &hkey))
{
debug_printf ("User registry hive for %W already exists", name);
RegCloseKey (hkey);
return;
}
if (get_registry_hive_path (name, path))
{
wcscat (path, L"\\NTUSER.DAT");
if ((ret = RegLoadKeyW (HKEY_USERS, name, path)) != ERROR_SUCCESS)
debug_printf ("Loading user registry hive for %W failed: %d", name, ret);
}
}
/* Fetch the path. */
tmp_pathbuf tp;
PWCHAR path = tp.w_get ();
if (!get_registry_hive_path (name, path))
return;
WCHAR key[256];
UNICODE_STRING ukey, upath;
OBJECT_ATTRIBUTES key_attr, path_attr;
NTSTATUS status;
/* Create the object attributes for key and path. */
wcpcpy (wcpcpy (key, L"\\Registry\\User\\"), name);
RtlInitUnicodeString (&ukey, key);
InitializeObjectAttributes (&key_attr, &ukey, OBJ_CASE_INSENSITIVE,
NULL, NULL);
wcscat (path, L"\\NTUSER.DAT");
RtlInitUnicodeString (&upath, path);
InitializeObjectAttributes (&path_attr, &upath, OBJ_CASE_INSENSITIVE,
NULL, NULL);
/* Load file into key. */
status = NtLoadKey (&key_attr, &path_attr);
if (!NT_SUCCESS (status))
system_printf ("Loading user registry hive %S into %S failed: %p",
&upath, &ukey, status);
else
system_printf ("Loading user registry hive %S into %S SUCCEEDED: %p",
&upath, &ukey, status);
}

View File

@ -1,6 +1,7 @@
/* registry.h: shared info for cygwin /* registry.h: shared info for cygwin
Copyright 2000, 2001, 2004, 2006, 2008 Red Hat, Inc. Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
2010, 2011 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -12,8 +13,8 @@ class reg_key
{ {
private: private:
HKEY key; HANDLE key;
LONG key_is_invalid; NTSTATUS key_is_invalid;
DWORD _disposition; DWORD _disposition;
public: public:
@ -24,22 +25,13 @@ public:
void *operator new (size_t, void *p) {return p;} void *operator new (size_t, void *p) {return p;}
void build_reg (HKEY key, REGSAM access, va_list av); void build_reg (HKEY key, REGSAM access, va_list av);
int error () {return key == (HKEY) INVALID_HANDLE_VALUE;} int error () {return key == NULL;}
int kill (const char *child); int get_int (PCWSTR, int);
int killvalue (const char *name); int get_string (PCWSTR, PWCHAR, size_t, PCWSTR);
HKEY get_key (); int set_int (PCWSTR, int);
int set_string (PCWSTR, PCWSTR);
int get_int (const char *, int);
int get_int (const WCHAR *, int);
int get_string (const char *, char *, size_t, const char *);
int get_string (const WCHAR *, PWCHAR, size_t, const WCHAR *);
int set_int (const char *, int);
int set_int (const PWCHAR, int);
int set_string (const char *, const char *);
int set_string (const PWCHAR, const PWCHAR);
bool created () const {return _disposition & REG_CREATED_NEW_KEY;} bool created () const {return _disposition & REG_CREATED_NEW_KEY;}
@ -47,5 +39,5 @@ public:
}; };
/* Evaluates path to the directory of the local user registry hive */ /* Evaluates path to the directory of the local user registry hive */
PWCHAR __stdcall get_registry_hive_path (const PWCHAR name, PWCHAR path); PWCHAR __stdcall get_registry_hive_path (PCWSTR name, PWCHAR path);
void __stdcall load_registry_hive (const PWCHAR name); void __stdcall load_registry_hive (PCWSTR name);

View File

@ -1,6 +1,6 @@
/* sched.cc: scheduler interface for Cygwin /* sched.cc: scheduler interface for Cygwin
Copyright 2001, 2002, 2006, 2007 Red Hat, Inc. Copyright 2001, 2003, 2006, 2008, 2011 Red Hat, Inc.
Written by Robert Collins <rbtcollins@hotmail.com> Written by Robert Collins <rbtcollins@hotmail.com>
@ -271,14 +271,14 @@ sched_rr_get_interval (pid_t pid, struct timespec *interval)
else else
forprocid = 0; forprocid = 0;
reg_key reg (HKEY_LOCAL_MACHINE, KEY_READ, "SYSTEM", "CurrentControlSet", reg_key reg (HKEY_LOCAL_MACHINE, KEY_READ, L"SYSTEM", L"CurrentControlSet",
"Control", "PriorityControl", NULL); L"Control", L"PriorityControl", NULL);
if (reg.error ()) if (reg.error ())
{ {
set_errno (ESRCH); set_errno (ESRCH);
return -1; return -1;
} }
prisep = reg.get_int ("Win32PrioritySeparation", 2); prisep = reg.get_int (L"Win32PrioritySeparation", 2);
pinfo pi (pid ? pid : myself->pid); pinfo pi (pid ? pid : myself->pid);
if (!pi) if (!pi)
{ {

View File

@ -1,7 +1,7 @@
/* shared.cc: shared data area support. /* shared.cc: shared data area support.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007, 2008, 2009 Red Hat, Inc. 2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -109,7 +109,8 @@ init_installation_root ()
for (int i = 1; i >= 0; --i) for (int i = 1; i >= 0; --i)
{ {
reg_key r (i, KEY_WRITE, CYGWIN_INFO_INSTALLATIONS_NAME, NULL); reg_key r (i, KEY_WRITE, _WIDE (CYGWIN_INFO_INSTALLATIONS_NAME),
NULL);
if (r.set_string (installation_key_buf, installation_root) if (r.set_string (installation_key_buf, installation_root)
== ERROR_SUCCESS) == ERROR_SUCCESS)
break; break;
@ -370,19 +371,19 @@ shared_destroy ()
void void
shared_info::init_obcaseinsensitive () shared_info::init_obcaseinsensitive ()
{ {
HKEY key; NTSTATUS status;
DWORD size = sizeof (DWORD); DWORD def_obcaseinsensitive = 1;
obcaseinsensitive = 1; obcaseinsensitive = def_obcaseinsensitive;
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, RTL_QUERY_REGISTRY_TABLE tab[2] = {
"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\kernel", { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOSTRING,
0, KEY_READ, &key) == ERROR_SUCCESS) L"obcaseinsensitive", &obcaseinsensitive, REG_DWORD,
{ &def_obcaseinsensitive, sizeof (DWORD) },
RegQueryValueEx (key, "obcaseinsensitive", NULL, NULL, { NULL, 0, NULL, NULL, 0, NULL, 0 }
(LPBYTE) &obcaseinsensitive, &size); };
RegCloseKey (key); status = RtlQueryRegistryValues (RTL_REGISTRY_CONTROL,
} L"Session Manager\\kernel",
debug_printf ("obcaseinsensitive set to %d", obcaseinsensitive); tab, NULL, NULL);
} }
void inline void inline
@ -449,7 +450,7 @@ shared_info::heap_slop_size ()
{ {
reg_key reg (i, KEY_READ, NULL); reg_key reg (i, KEY_READ, NULL);
if ((heap_slop = reg.get_int ("heap_slop_in_mb", 0))) if ((heap_slop = reg.get_int (L"heap_slop_in_mb", 0)))
break; break;
heap_slop = wincap.heapslop (); heap_slop = wincap.heapslop ();
} }
@ -475,7 +476,7 @@ shared_info::heap_chunk_size ()
/* FIXME: We should not be restricted to a fixed size heap no matter /* FIXME: We should not be restricted to a fixed size heap no matter
what the fixed size is. */ what the fixed size is. */
if ((heap_chunk = reg.get_int ("heap_chunk_in_mb", 0))) if ((heap_chunk = reg.get_int (L"heap_chunk_in_mb", 0)))
break; break;
heap_chunk = 384; /* Default */ heap_chunk = 384; /* Default */
} }

View File

@ -3682,8 +3682,8 @@ updwtmpx (const char *wtmpx_file, const struct utmpx *utmpx)
updwtmp (wtmpx_file, (const struct utmp *) utmpx); updwtmp (wtmpx_file, (const struct utmp *) utmpx);
} }
extern "C" extern "C" long
long gethostid (void) gethostid (void)
{ {
unsigned data[13] = {0x92895012, unsigned data[13] = {0x92895012,
0x10293412, 0x10293412,
@ -3766,9 +3766,11 @@ long gethostid (void)
else else
debug_printf ("no Ethernet card installed"); debug_printf ("no Ethernet card installed");
reg_key key (HKEY_LOCAL_MACHINE, KEY_READ, "SOFTWARE", "Microsoft", WCHAR wdata[24];
"Windows NT", "CurrentVersion", NULL); reg_key key (HKEY_LOCAL_MACHINE, KEY_READ, L"SOFTWARE", L"Microsoft",
key.get_string ("ProductId", (char *)&data[6], 24, "00000-000-0000000-00000"); L"Windows NT", L"CurrentVersion", NULL);
key.get_string (L"ProductId", wdata, 24, L"00000-000-0000000-00000");
sys_wcstombs ((char *)&data[6], 24, wdata, 24);
debug_printf ("Windows Product ID: %s", (char *)&data[6]); debug_printf ("Windows Product ID: %s", (char *)&data[6]);
GetDiskFreeSpaceEx ("C:\\", NULL, (PULARGE_INTEGER) &data[11], NULL); GetDiskFreeSpaceEx ("C:\\", NULL, (PULARGE_INTEGER) &data[11], NULL);

View File

@ -70,6 +70,12 @@ int fcntl64 (int fd, int cmd, ...);
application provided path strings we handle. */ application provided path strings we handle. */
#define NT_MAX_PATH 32768 #define NT_MAX_PATH 32768
/* This definition allows to define wide char strings using macros as
parameters. See the definition of __CONCAT in newlib's sys/cdefs.h
and accompanying comment. */
#define __WIDE(a) L ## a
#define _WIDE(a) __WIDE(a)
#ifdef __cplusplus #ifdef __cplusplus
extern const char case_folded_lower[]; extern const char case_folded_lower[];