* fhandler.h (fhandler_registry::value_name): Convert to wchar_t*.
* fhandler_registry.cc: Call UNICODE registry functions throughout and convert to multibyte using current locale's charset. Accommodate throughout. (must_encode): Take wchar_t. (encode_regname): Convert from wchar_t *. (decode_regname): Convert to wchar_t *.
This commit is contained in:
parent
70757043bf
commit
333a47d316
|
@ -1,3 +1,13 @@
|
||||||
|
2009-12-18 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* fhandler.h (fhandler_registry::value_name): Convert to wchar_t*.
|
||||||
|
* fhandler_registry.cc: Call UNICODE registry functions throughout
|
||||||
|
and convert to multibyte using current locale's charset. Accommodate
|
||||||
|
throughout.
|
||||||
|
(must_encode): Take wchar_t.
|
||||||
|
(encode_regname): Convert from wchar_t *.
|
||||||
|
(decode_regname): Convert to wchar_t *.
|
||||||
|
|
||||||
2009-12-18 Corinna Vinschen <corinna@vinschen.de>
|
2009-12-18 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* path.sgml (func-cygwin-conv-path): Clarify meaning of size parameter.
|
* path.sgml (func-cygwin-conv-path): Clarify meaning of size parameter.
|
||||||
|
|
|
@ -1349,7 +1349,7 @@ class fhandler_netdrive: public fhandler_virtual
|
||||||
class fhandler_registry: public fhandler_proc
|
class fhandler_registry: public fhandler_proc
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
char *value_name;
|
wchar_t *value_name;
|
||||||
DWORD wow64;
|
DWORD wow64;
|
||||||
int prefix_len;
|
int prefix_len;
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -96,16 +96,16 @@ static HKEY open_key (const char *name, REGSAM access, DWORD wow64, bool isValue
|
||||||
/* Return true if char must be encoded.
|
/* Return true if char must be encoded.
|
||||||
*/
|
*/
|
||||||
static inline bool
|
static inline bool
|
||||||
must_encode (char c)
|
must_encode (wchar_t c)
|
||||||
{
|
{
|
||||||
return (isdirsep (c) || c == ':' || c == '%');
|
return (iswdirsep (c) || c == L':' || c == L'%');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Encode special chars in registry key or value name.
|
/* Encode special chars in registry key or value name.
|
||||||
* Returns 0: success, -1: error.
|
* Returns 0: success, -1: error.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
encode_regname (char * dst, const char * src, bool add_val)
|
encode_regname (char *dst, const wchar_t *src, bool add_val)
|
||||||
{
|
{
|
||||||
int di = 0;
|
int di = 0;
|
||||||
if (!src[0])
|
if (!src[0])
|
||||||
|
@ -113,10 +113,11 @@ encode_regname (char * dst, const char * src, bool add_val)
|
||||||
else
|
else
|
||||||
for (int si = 0; src[si]; si++)
|
for (int si = 0; src[si]; si++)
|
||||||
{
|
{
|
||||||
char c = src[si];
|
wchar_t c = src[si];
|
||||||
if (must_encode (c) ||
|
if (must_encode (c) ||
|
||||||
(si == 0 && ((c == '.' && (!src[1] || (src[1] == '.' && !src[2]))) ||
|
(si == 0 && ((c == L'.'
|
||||||
(c == '@' && !src[1]))))
|
&& (!src[1] || (src[1] == L'.' && !src[2])))
|
||||||
|
|| (c == L'@' && !src[1]))))
|
||||||
{
|
{
|
||||||
if (di + 3 >= NAME_MAX + 1)
|
if (di + 3 >= NAME_MAX + 1)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -124,7 +125,7 @@ encode_regname (char * dst, const char * src, bool add_val)
|
||||||
di += 3;
|
di += 3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
dst[di++] = c;
|
di += sys_wcstombs (dst + di, NAME_MAX + 1 - di, &c, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (add_val)
|
if (add_val)
|
||||||
|
@ -143,12 +144,13 @@ encode_regname (char * dst, const char * src, bool add_val)
|
||||||
* Returns 0: success, 1: "%val" detected, -1: error.
|
* Returns 0: success, 1: "%val" detected, -1: error.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
decode_regname (char * dst, const char * src, int len = -1)
|
decode_regname (wchar_t *wdst, const char *src, int len = -1)
|
||||||
{
|
{
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
len = strlen (src);
|
len = strlen (src);
|
||||||
|
char dst[len + 1];
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
if (len > 4 && !memcmp (src + len - 4, "%val", 4))
|
if (len > 4 && !memcmp (src + len - 4, "%val", 4))
|
||||||
{
|
{
|
||||||
len -= 4;
|
len -= 4;
|
||||||
|
@ -169,7 +171,7 @@ decode_regname (char * dst, const char * src, int len = -1)
|
||||||
char s[] = {src[si+1], src[si+2], '\0'};
|
char s[] = {src[si+1], src[si+2], '\0'};
|
||||||
char *p;
|
char *p;
|
||||||
c = strtoul (s, &p, 16);
|
c = strtoul (s, &p, 16);
|
||||||
if (!(must_encode (c) ||
|
if (!(must_encode ((wchar_t) c) ||
|
||||||
(si == 0 && ((c == '.' && (len == 3 || (src[3] == '.' && len == 4))) ||
|
(si == 0 && ((c == '.' && (len == 3 || (src[3] == '.' && len == 4))) ||
|
||||||
(c == '@' && len == 3)))))
|
(c == '@' && len == 3)))))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -181,6 +183,7 @@ decode_regname (char * dst, const char * src, int len = -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
dst[di] = 0;
|
dst[di] = 0;
|
||||||
|
sys_mbstowcs (wdst, NAME_MAX + 1, dst);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,10 +219,10 @@ private:
|
||||||
/* Return true if subkey NAME exists in key PARENT.
|
/* Return true if subkey NAME exists in key PARENT.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
key_exists (HKEY parent, const char * name, DWORD wow64)
|
key_exists (HKEY parent, const wchar_t *name, DWORD wow64)
|
||||||
{
|
{
|
||||||
HKEY hKey = (HKEY) INVALID_HANDLE_VALUE;
|
HKEY hKey = (HKEY) INVALID_HANDLE_VALUE;
|
||||||
LONG error = RegOpenKeyEx (parent, name, 0, KEY_READ | wow64, &hKey);
|
LONG error = RegOpenKeyExW (parent, name, 0, KEY_READ | wow64, &hKey);
|
||||||
if (error == ERROR_SUCCESS)
|
if (error == ERROR_SUCCESS)
|
||||||
RegCloseKey (hKey);
|
RegCloseKey (hKey);
|
||||||
|
|
||||||
|
@ -239,7 +242,7 @@ fhandler_registry::exists ()
|
||||||
int file_type = 0, index = 0, pathlen;
|
int file_type = 0, index = 0, pathlen;
|
||||||
DWORD buf_size = NAME_MAX + 1;
|
DWORD buf_size = NAME_MAX + 1;
|
||||||
LONG error;
|
LONG error;
|
||||||
char buf[buf_size];
|
wchar_t buf[buf_size];
|
||||||
const char *file;
|
const char *file;
|
||||||
HKEY hKey = (HKEY) INVALID_HANDLE_VALUE;
|
HKEY hKey = (HKEY) INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
|
@ -273,7 +276,7 @@ fhandler_registry::exists ()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char dec_file[NAME_MAX + 1];
|
wchar_t dec_file[NAME_MAX + 1];
|
||||||
|
|
||||||
int val_only = decode_regname (dec_file, file);
|
int val_only = decode_regname (dec_file, file);
|
||||||
if (val_only < 0)
|
if (val_only < 0)
|
||||||
|
@ -310,11 +313,11 @@ fhandler_registry::exists ()
|
||||||
if (!val_only && dec_file[0])
|
if (!val_only && dec_file[0])
|
||||||
{
|
{
|
||||||
while (ERROR_SUCCESS ==
|
while (ERROR_SUCCESS ==
|
||||||
(error = RegEnumKeyEx (hKey, index++, buf, &buf_size,
|
(error = RegEnumKeyExW (hKey, index++, buf, &buf_size,
|
||||||
NULL, NULL, NULL, NULL))
|
NULL, NULL, NULL, NULL))
|
||||||
|| (error == ERROR_MORE_DATA))
|
|| (error == ERROR_MORE_DATA))
|
||||||
{
|
{
|
||||||
if (strcasematch (buf, dec_file))
|
if (!wcscasecmp (buf, dec_file))
|
||||||
{
|
{
|
||||||
file_type = 1;
|
file_type = 1;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -331,11 +334,11 @@ fhandler_registry::exists ()
|
||||||
}
|
}
|
||||||
|
|
||||||
while (ERROR_SUCCESS ==
|
while (ERROR_SUCCESS ==
|
||||||
(error = RegEnumValue (hKey, index++, buf, &buf_size, NULL, NULL,
|
(error = RegEnumValueW (hKey, index++, buf, &buf_size,
|
||||||
NULL, NULL))
|
NULL, NULL, NULL, NULL))
|
||||||
|| (error == ERROR_MORE_DATA))
|
|| (error == ERROR_MORE_DATA))
|
||||||
{
|
{
|
||||||
if (strcasematch (buf, dec_file))
|
if (!wcscasecmp (buf, dec_file))
|
||||||
{
|
{
|
||||||
file_type = -1;
|
file_type = -1;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -437,12 +440,28 @@ fhandler_registry::fstat (struct __stat64 *buf)
|
||||||
while (!isdirsep (*value_name))
|
while (!isdirsep (*value_name))
|
||||||
value_name--;
|
value_name--;
|
||||||
value_name++;
|
value_name++;
|
||||||
char dec_value_name[NAME_MAX + 1];
|
wchar_t dec_value_name[NAME_MAX + 1];
|
||||||
DWORD dwSize;
|
DWORD dwSize = 0;
|
||||||
if (decode_regname (dec_value_name, value_name) >= 0 &&
|
DWORD type;
|
||||||
ERROR_SUCCESS ==
|
if (decode_regname (dec_value_name, value_name) >= 0
|
||||||
RegQueryValueEx (hKey, dec_value_name, NULL, NULL, NULL,
|
&& RegQueryValueExW (hKey, dec_value_name, NULL, &type,
|
||||||
&dwSize))
|
NULL, &dwSize) == ERROR_SUCCESS
|
||||||
|
&& (type == REG_SZ || type == REG_EXPAND_SZ
|
||||||
|
|| type == REG_MULTI_SZ || type == REG_LINK))
|
||||||
|
{
|
||||||
|
PBYTE tmpbuf = (PBYTE) malloc (dwSize);
|
||||||
|
if (!tmpbuf
|
||||||
|
|| RegQueryValueExW (hKey, dec_value_name,
|
||||||
|
NULL, NULL, tmpbuf, &dwSize)
|
||||||
|
!= ERROR_SUCCESS)
|
||||||
|
buf->st_size = dwSize / sizeof (wchar_t);
|
||||||
|
else
|
||||||
|
buf->st_size = sys_wcstombs (NULL, 0,
|
||||||
|
(wchar_t *) tmpbuf,
|
||||||
|
dwSize / sizeof (wchar_t));
|
||||||
|
free (tmpbuf);
|
||||||
|
}
|
||||||
|
else
|
||||||
buf->st_size = dwSize;
|
buf->st_size = dwSize;
|
||||||
}
|
}
|
||||||
__uid32_t uid;
|
__uid32_t uid;
|
||||||
|
@ -481,7 +500,7 @@ int
|
||||||
fhandler_registry::readdir (DIR *dir, dirent *de)
|
fhandler_registry::readdir (DIR *dir, dirent *de)
|
||||||
{
|
{
|
||||||
DWORD buf_size = NAME_MAX + 1;
|
DWORD buf_size = NAME_MAX + 1;
|
||||||
char buf[buf_size];
|
wchar_t buf[buf_size];
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
const char *path = dir->__d_dirname + proc_len + 1 + prefix_len;
|
const char *path = dir->__d_dirname + proc_len + 1 + prefix_len;
|
||||||
LONG error;
|
LONG error;
|
||||||
|
@ -529,14 +548,14 @@ retry:
|
||||||
/* For the moment, the type of key is ignored here. when write access is added,
|
/* For the moment, the type of key is ignored here. when write access is added,
|
||||||
* maybe add an extension for the type of each value?
|
* maybe add an extension for the type of each value?
|
||||||
*/
|
*/
|
||||||
error = RegEnumValue ((HKEY) dir->__handle,
|
error = RegEnumValueW ((HKEY) dir->__handle,
|
||||||
(dir->__d_position & ~REG_ENUM_VALUES_MASK) >> 16,
|
(dir->__d_position & ~REG_ENUM_VALUES_MASK) >> 16,
|
||||||
buf, &buf_size, NULL, NULL, NULL, NULL);
|
buf, &buf_size, NULL, NULL, NULL, NULL);
|
||||||
else
|
else
|
||||||
error =
|
error =
|
||||||
RegEnumKeyEx ((HKEY) dir->__handle, dir->__d_position -
|
RegEnumKeyExW ((HKEY) dir->__handle, dir->__d_position -
|
||||||
SPECIAL_DOT_FILE_COUNT, buf, &buf_size, NULL, NULL, NULL,
|
SPECIAL_DOT_FILE_COUNT, buf, &buf_size,
|
||||||
NULL);
|
NULL, NULL, NULL, NULL);
|
||||||
if (error == ERROR_NO_MORE_ITEMS
|
if (error == ERROR_NO_MORE_ITEMS
|
||||||
&& (dir->__d_position & REG_ENUM_VALUES_MASK) == 0)
|
&& (dir->__d_position & REG_ENUM_VALUES_MASK) == 0)
|
||||||
{
|
{
|
||||||
|
@ -727,7 +746,7 @@ fhandler_registry::open (int flags, mode_t mode)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char dec_file[NAME_MAX + 1];
|
wchar_t dec_file[NAME_MAX + 1];
|
||||||
int val_only = decode_regname (dec_file, file);
|
int val_only = decode_regname (dec_file, file);
|
||||||
if (val_only < 0)
|
if (val_only < 0)
|
||||||
{
|
{
|
||||||
|
@ -752,7 +771,7 @@ fhandler_registry::open (int flags, mode_t mode)
|
||||||
flags |= O_DIROPEN;
|
flags |= O_DIROPEN;
|
||||||
|
|
||||||
set_io_handle (handle);
|
set_io_handle (handle);
|
||||||
value_name = cstrdup (dec_file);
|
value_name = cwcsdup (dec_file);
|
||||||
|
|
||||||
if (!(flags & O_DIROPEN) && !fill_filebuf ())
|
if (!(flags & O_DIROPEN) && !fill_filebuf ())
|
||||||
{
|
{
|
||||||
|
@ -809,7 +828,7 @@ fhandler_registry::fill_filebuf ()
|
||||||
|
|
||||||
if (handle != HKEY_PERFORMANCE_DATA)
|
if (handle != HKEY_PERFORMANCE_DATA)
|
||||||
{
|
{
|
||||||
error = RegQueryValueEx (handle, value_name, NULL, &type, NULL, &size);
|
error = RegQueryValueExW (handle, value_name, NULL, &type, NULL, &size);
|
||||||
if (error != ERROR_SUCCESS)
|
if (error != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
if (error != ERROR_FILE_NOT_FOUND)
|
if (error != ERROR_FILE_NOT_FOUND)
|
||||||
|
@ -819,17 +838,28 @@ fhandler_registry::fill_filebuf ()
|
||||||
}
|
}
|
||||||
goto value_not_found;
|
goto value_not_found;
|
||||||
}
|
}
|
||||||
bufalloc = size;
|
PBYTE tmpbuf = (PBYTE) cmalloc_abort (HEAP_BUF, size);
|
||||||
filebuf = (char *) cmalloc_abort (HEAP_BUF, bufalloc);
|
|
||||||
error =
|
error =
|
||||||
RegQueryValueEx (handle, value_name, NULL, NULL, (BYTE *) filebuf,
|
RegQueryValueExW (handle, value_name, NULL, NULL, tmpbuf, &size);
|
||||||
&size);
|
|
||||||
if (error != ERROR_SUCCESS)
|
if (error != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
seterrno_from_win_error (__FILE__, __LINE__, error);
|
seterrno_from_win_error (__FILE__, __LINE__, error);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
filesize = size;
|
if (type == REG_SZ || type == REG_EXPAND_SZ || type == REG_MULTI_SZ
|
||||||
|
|| type == REG_LINK)
|
||||||
|
bufalloc = sys_wcstombs (NULL, 0, (wchar_t *) tmpbuf,
|
||||||
|
size / sizeof (wchar_t));
|
||||||
|
else
|
||||||
|
bufalloc = size;
|
||||||
|
filebuf = (char *) cmalloc_abort (HEAP_BUF, bufalloc);
|
||||||
|
if (type == REG_SZ || type == REG_EXPAND_SZ || type == REG_MULTI_SZ
|
||||||
|
|| type == REG_LINK)
|
||||||
|
sys_wcstombs (filebuf, bufalloc, (wchar_t *) tmpbuf,
|
||||||
|
size / sizeof (wchar_t));
|
||||||
|
else
|
||||||
|
memcpy (filebuf, tmpbuf, bufalloc);
|
||||||
|
filesize = bufalloc;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -839,8 +869,8 @@ fhandler_registry::fill_filebuf ()
|
||||||
bufalloc += 16 * 1024;
|
bufalloc += 16 * 1024;
|
||||||
filebuf = (char *) crealloc_abort (filebuf, bufalloc);
|
filebuf = (char *) crealloc_abort (filebuf, bufalloc);
|
||||||
size = bufalloc;
|
size = bufalloc;
|
||||||
error = RegQueryValueEx (handle, value_name, NULL, &type,
|
error = RegQueryValueExW (handle, value_name, NULL, &type,
|
||||||
(BYTE *) filebuf, &size);
|
(PBYTE) filebuf, &size);
|
||||||
if (error != ERROR_SUCCESS && error != ERROR_MORE_DATA)
|
if (error != ERROR_SUCCESS && error != ERROR_MORE_DATA)
|
||||||
{
|
{
|
||||||
seterrno_from_win_error (__FILE__, __LINE__, error);
|
seterrno_from_win_error (__FILE__, __LINE__, error);
|
||||||
|
@ -855,13 +885,13 @@ fhandler_registry::fill_filebuf ()
|
||||||
return true;
|
return true;
|
||||||
value_not_found:
|
value_not_found:
|
||||||
DWORD buf_size = NAME_MAX + 1;
|
DWORD buf_size = NAME_MAX + 1;
|
||||||
char buf[buf_size];
|
wchar_t buf[buf_size];
|
||||||
int index = 0;
|
int index = 0;
|
||||||
while (ERROR_SUCCESS ==
|
while (ERROR_SUCCESS ==
|
||||||
(error = RegEnumKeyEx (handle, index++, buf, &buf_size, NULL, NULL,
|
(error = RegEnumKeyExW (handle, index++, buf, &buf_size, NULL, NULL,
|
||||||
NULL, NULL)) || (error == ERROR_MORE_DATA))
|
NULL, NULL)) || (error == ERROR_MORE_DATA))
|
||||||
{
|
{
|
||||||
if (strcasematch (buf, value_name))
|
if (!wcscasecmp (buf, value_name))
|
||||||
{
|
{
|
||||||
set_errno (EISDIR);
|
set_errno (EISDIR);
|
||||||
return false;
|
return false;
|
||||||
|
@ -884,7 +914,7 @@ open_key (const char *name, REGSAM access, DWORD wow64, bool isValue)
|
||||||
HKEY hKey = (HKEY) INVALID_HANDLE_VALUE;
|
HKEY hKey = (HKEY) INVALID_HANDLE_VALUE;
|
||||||
HKEY hParentKey = (HKEY) INVALID_HANDLE_VALUE;
|
HKEY hParentKey = (HKEY) INVALID_HANDLE_VALUE;
|
||||||
bool parentOpened = false;
|
bool parentOpened = false;
|
||||||
char component[NAME_MAX + 1];
|
wchar_t component[NAME_MAX + 1];
|
||||||
|
|
||||||
while (*name)
|
while (*name)
|
||||||
{
|
{
|
||||||
|
@ -919,13 +949,13 @@ open_key (const char *name, REGSAM access, DWORD wow64, bool isValue)
|
||||||
REGSAM effective_access = KEY_READ;
|
REGSAM effective_access = KEY_READ;
|
||||||
if ((strchr (name, '/') == NULL && isValue == true) || *name == 0)
|
if ((strchr (name, '/') == NULL && isValue == true) || *name == 0)
|
||||||
effective_access = access;
|
effective_access = access;
|
||||||
LONG error = RegOpenKeyEx (hParentKey, component, 0,
|
LONG error = RegOpenKeyExW (hParentKey, component, 0,
|
||||||
effective_access | wow64, &hKey);
|
effective_access | wow64, &hKey);
|
||||||
if (error == ERROR_ACCESS_DENIED) /* Try opening with backup intent */
|
if (error == ERROR_ACCESS_DENIED) /* Try opening with backup intent */
|
||||||
error = RegCreateKeyEx (hParentKey, component, 0, NULL,
|
error = RegCreateKeyExW (hParentKey, component, 0, NULL,
|
||||||
REG_OPTION_BACKUP_RESTORE,
|
REG_OPTION_BACKUP_RESTORE,
|
||||||
effective_access | wow64, NULL,
|
effective_access | wow64, NULL,
|
||||||
&hKey, NULL);
|
&hKey, NULL);
|
||||||
if (parentOpened)
|
if (parentOpened)
|
||||||
RegCloseKey (hParentKey);
|
RegCloseKey (hParentKey);
|
||||||
if (error != ERROR_SUCCESS)
|
if (error != ERROR_SUCCESS)
|
||||||
|
@ -940,7 +970,7 @@ open_key (const char *name, REGSAM access, DWORD wow64, bool isValue)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; registry_listing[i]; i++)
|
for (int i = 0; registry_listing[i]; i++)
|
||||||
if (strcasematch (component, registry_listing[i]))
|
if (strncasematch (anchor, registry_listing[i], name - anchor - 1))
|
||||||
hKey = registry_keys[i];
|
hKey = registry_keys[i];
|
||||||
if (hKey == (HKEY) INVALID_HANDLE_VALUE)
|
if (hKey == (HKEY) INVALID_HANDLE_VALUE)
|
||||||
return hKey;
|
return hKey;
|
||||||
|
|
Loading…
Reference in New Issue