OSDN Git Service

* fhandler.h (fhandler_registry::value_name): Convert to wchar_t*.
authorcorinna <corinna>
Sat, 19 Dec 2009 02:14:19 +0000 (02:14 +0000)
committercorinna <corinna>
Sat, 19 Dec 2009 02:14:19 +0000 (02:14 +0000)
* 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 *.

winsup/cygwin/ChangeLog
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_registry.cc

index 8445b7d..4aff742 100644 (file)
@@ -1,5 +1,15 @@
 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>
+
        * path.sgml (func-cygwin-conv-path): Clarify meaning of size parameter.
        (func-cygwin-conv-path-list): Fix typo.
        (func-cygwin-posix-path-list-p): Ditto.
index 7da3aa6..db439f2 100644 (file)
@@ -1349,7 +1349,7 @@ class fhandler_netdrive: public fhandler_virtual
 class fhandler_registry: public fhandler_proc
 {
  private:
-  char *value_name;
+  wchar_t *value_name;
   DWORD wow64;
   int prefix_len;
  public:
index bb0ea04..e8f4e68 100644 (file)
@@ -96,16 +96,16 @@ static HKEY open_key (const char *name, REGSAM access, DWORD wow64, bool isValue
 /* Return true if char must be encoded.
  */
 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.
  * Returns 0: success, -1: error.
  */
 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;
   if (!src[0])
@@ -113,10 +113,11 @@ encode_regname (char * dst, const char * src, bool add_val)
   else
     for (int si = 0; src[si]; si++)
       {
-       char c = src[si];
+       wchar_t c = src[si];
        if (must_encode (c) ||
-           (si == 0 && ((c == '.' && (!src[1] || (src[1] == '.' && !src[2]))) ||
-                       (c == '@' && !src[1]))))
+           (si == 0 && ((c == L'.'
+                         && (!src[1] || (src[1] == L'.' && !src[2])))
+                        || (c == L'@' && !src[1]))))
          {
            if (di + 3 >= NAME_MAX + 1)
              return -1;
@@ -124,7 +125,7 @@ encode_regname (char * dst, const char * src, bool add_val)
            di += 3;
          }
        else
-         dst[di++] = c;
+         di += sys_wcstombs (dst + di, NAME_MAX + 1 - di, &c, 1);
       }
 
   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.
  */
 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)
     len = strlen (src);
-
+  char dst[len + 1];
   int res = 0;
+
   if (len > 4 && !memcmp (src + len - 4, "%val", 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 *p;
            c = strtoul (s, &p, 16);
-           if (!(must_encode (c) ||
+           if (!(must_encode ((wchar_t) c) ||
                  (si == 0 && ((c == '.' && (len == 3 || (src[3] == '.' && len == 4))) ||
                               (c == '@' && len == 3)))))
              return -1;
@@ -181,6 +183,7 @@ decode_regname (char * dst, const char * src, int len = -1)
       }
 
   dst[di] = 0;
+  sys_mbstowcs (wdst, NAME_MAX + 1, dst);
   return res;
 }
 
@@ -216,10 +219,10 @@ private:
 /* Return true if subkey NAME exists in key PARENT.
  */
 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;
-  LONG error = RegOpenKeyEx (parent, name, 0, KEY_READ | wow64, &hKey);
+  LONG error = RegOpenKeyExW (parent, name, 0, KEY_READ | wow64, &hKey);
   if (error == ERROR_SUCCESS)
     RegCloseKey (hKey);
 
@@ -239,7 +242,7 @@ fhandler_registry::exists ()
   int file_type = 0, index = 0, pathlen;
   DWORD buf_size = NAME_MAX + 1;
   LONG error;
-  char buf[buf_size];
+  wchar_t buf[buf_size];
   const char *file;
   HKEY hKey = (HKEY) INVALID_HANDLE_VALUE;
 
@@ -273,7 +276,7 @@ fhandler_registry::exists ()
     }
   else
     {
-      char dec_file[NAME_MAX + 1];
+      wchar_t dec_file[NAME_MAX + 1];
 
       int val_only = decode_regname (dec_file, file);
       if (val_only < 0)
@@ -310,11 +313,11 @@ fhandler_registry::exists ()
          if (!val_only && dec_file[0])
            {
              while (ERROR_SUCCESS ==
-                    (error = RegEnumKeyEx (hKey, index++, buf, &buf_size,
-                                           NULL, NULL, NULL, NULL))
+                    (error = RegEnumKeyExW (hKey, index++, buf, &buf_size,
+                                            NULL, NULL, NULL, NULL))
                     || (error == ERROR_MORE_DATA))
                {
-                 if (strcasematch (buf, dec_file))
+                 if (!wcscasecmp (buf, dec_file))
                    {
                      file_type = 1;
                      goto out;
@@ -331,11 +334,11 @@ fhandler_registry::exists ()
            }
 
          while (ERROR_SUCCESS ==
-                (error = RegEnumValue (hKey, index++, buf, &buf_size, NULL, NULL,
-                                       NULL, NULL))
+                (error = RegEnumValueW (hKey, index++, buf, &buf_size,
+                                        NULL, NULL, NULL, NULL))
                 || (error == ERROR_MORE_DATA))
            {
-             if (strcasematch (buf, dec_file))
+             if (!wcscasecmp (buf, dec_file))
                {
                  file_type = -1;
                  goto out;
@@ -437,12 +440,28 @@ fhandler_registry::fstat (struct __stat64 *buf)
                  while (!isdirsep (*value_name))
                    value_name--;
                  value_name++;
-                 char dec_value_name[NAME_MAX + 1];
-                 DWORD dwSize;
-                 if (decode_regname (dec_value_name, value_name) >= 0 &&
-                     ERROR_SUCCESS ==
-                     RegQueryValueEx (hKey, dec_value_name, NULL, NULL, NULL,
-                                      &dwSize))
+                 wchar_t dec_value_name[NAME_MAX + 1];
+                 DWORD dwSize = 0;
+                 DWORD type;
+                 if (decode_regname (dec_value_name, value_name) >= 0
+                     && RegQueryValueExW (hKey, dec_value_name, NULL, &type,
+                                          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;
                }
              __uid32_t uid;
@@ -481,7 +500,7 @@ int
 fhandler_registry::readdir (DIR *dir, dirent *de)
 {
   DWORD buf_size = NAME_MAX + 1;
-  char buf[buf_size];
+  wchar_t buf[buf_size];
   HANDLE handle;
   const char *path = dir->__d_dirname + proc_len + 1 + prefix_len;
   LONG error;
@@ -529,14 +548,14 @@ retry:
     /* 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?
      */
-    error = RegEnumValue ((HKEY) dir->__handle,
-                         (dir->__d_position & ~REG_ENUM_VALUES_MASK) >> 16,
-                         buf, &buf_size, NULL, NULL, NULL, NULL);
+    error = RegEnumValueW ((HKEY) dir->__handle,
+                          (dir->__d_position & ~REG_ENUM_VALUES_MASK) >> 16,
+                          buf, &buf_size, NULL, NULL, NULL, NULL);
   else
     error =
-      RegEnumKeyEx ((HKEY) dir->__handle, dir->__d_position -
-                   SPECIAL_DOT_FILE_COUNT, buf, &buf_size, NULL, NULL, NULL,
-                   NULL);
+      RegEnumKeyExW ((HKEY) dir->__handle, dir->__d_position -
+                    SPECIAL_DOT_FILE_COUNT, buf, &buf_size,
+                    NULL, NULL, NULL, NULL);
   if (error == ERROR_NO_MORE_ITEMS
       && (dir->__d_position & REG_ENUM_VALUES_MASK) == 0)
     {
@@ -727,7 +746,7 @@ fhandler_registry::open (int flags, mode_t mode)
     }
   else
     {
-      char dec_file[NAME_MAX + 1];
+      wchar_t dec_file[NAME_MAX + 1];
       int val_only = decode_regname (dec_file, file);
       if (val_only < 0)
        {
@@ -752,7 +771,7 @@ fhandler_registry::open (int flags, mode_t mode)
        flags |= O_DIROPEN;
 
       set_io_handle (handle);
-      value_name = cstrdup (dec_file);
+      value_name = cwcsdup (dec_file);
 
       if (!(flags & O_DIROPEN) && !fill_filebuf ())
        {
@@ -809,7 +828,7 @@ fhandler_registry::fill_filebuf ()
 
   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_FILE_NOT_FOUND)
@@ -819,17 +838,28 @@ fhandler_registry::fill_filebuf ()
            }
          goto value_not_found;
        }
-      bufalloc = size;
-      filebuf = (char *) cmalloc_abort (HEAP_BUF, bufalloc);
+      PBYTE tmpbuf = (PBYTE) cmalloc_abort (HEAP_BUF, size);
       error =
-       RegQueryValueEx (handle, value_name, NULL, NULL, (BYTE *) filebuf,
-                        &size);
+       RegQueryValueExW (handle, value_name, NULL, NULL, tmpbuf, &size);
       if (error != ERROR_SUCCESS)
        {
          seterrno_from_win_error (__FILE__, __LINE__, error);
          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
     {
@@ -839,8 +869,8 @@ fhandler_registry::fill_filebuf ()
          bufalloc += 16 * 1024;
          filebuf = (char *) crealloc_abort (filebuf, bufalloc);
          size = bufalloc;
-         error = RegQueryValueEx (handle, value_name, NULL, &type,
-                                  (BYTE *) filebuf, &size);
+         error = RegQueryValueExW (handle, value_name, NULL, &type,
+                                   (PBYTE) filebuf, &size);
          if (error != ERROR_SUCCESS && error != ERROR_MORE_DATA)
            {
              seterrno_from_win_error (__FILE__, __LINE__, error);
@@ -855,13 +885,13 @@ fhandler_registry::fill_filebuf ()
   return true;
 value_not_found:
   DWORD buf_size = NAME_MAX + 1;
-  char buf[buf_size];
+  wchar_t buf[buf_size];
   int index = 0;
   while (ERROR_SUCCESS ==
-        (error = RegEnumKeyEx (handle, index++, buf, &buf_size, NULL, NULL,
-                               NULL, NULL)) || (error == ERROR_MORE_DATA))
+        (error = RegEnumKeyExW (handle, index++, buf, &buf_size, NULL, NULL,
+                                NULL, NULL)) || (error == ERROR_MORE_DATA))
     {
-      if (strcasematch (buf, value_name))
+      if (!wcscasecmp (buf, value_name))
        {
          set_errno (EISDIR);
          return false;
@@ -884,7 +914,7 @@ open_key (const char *name, REGSAM access, DWORD wow64, bool isValue)
   HKEY hKey = (HKEY) INVALID_HANDLE_VALUE;
   HKEY hParentKey = (HKEY) INVALID_HANDLE_VALUE;
   bool parentOpened = false;
-  char component[NAME_MAX + 1];
+  wchar_t component[NAME_MAX + 1];
 
   while (*name)
     {
@@ -919,13 +949,13 @@ open_key (const char *name, REGSAM access, DWORD wow64, bool isValue)
          REGSAM effective_access = KEY_READ;
          if ((strchr (name, '/') == NULL && isValue == true) || *name == 0)
            effective_access = access;
-         LONG error = RegOpenKeyEx (hParentKey, component, 0,
-                                    effective_access | wow64, &hKey);
+         LONG error = RegOpenKeyExW (hParentKey, component, 0,
+                                     effective_access | wow64, &hKey);
          if (error == ERROR_ACCESS_DENIED) /* Try opening with backup intent */
-           error = RegCreateKeyEx (hParentKey, component, 0, NULL,
-                                   REG_OPTION_BACKUP_RESTORE,
-                                   effective_access | wow64, NULL,
-                                   &hKey, NULL);
+           error = RegCreateKeyExW (hParentKey, component, 0, NULL,
+                                    REG_OPTION_BACKUP_RESTORE,
+                                    effective_access | wow64, NULL,
+                                    &hKey, NULL);
          if (parentOpened)
            RegCloseKey (hParentKey);
          if (error != ERROR_SUCCESS)
@@ -940,7 +970,7 @@ open_key (const char *name, REGSAM access, DWORD wow64, bool isValue)
       else
        {
          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];
          if (hKey == (HKEY) INVALID_HANDLE_VALUE)
            return hKey;