From 20f9af53481ba97c6759e2febe449428618936ad Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 19 Oct 2006 10:01:03 +0000 Subject: [PATCH] * fhandler.h (fhandler_base::set_name): Make virtual. (class fhandler_registry): Add wow64 and prefix_len members. Declare set_name method. * fhandler_proc.cc (PROC_REGISTRY32): Define. (PROC_REGISTRY64): Define. (proc_listing): Add "registry32" and "registry64" elements. (proc_fhandlers): Add corresponding FH_REGISTRY values. * fhandler_registry.cc (registry_len): Drop static value in favor of class member prefix_len. Use preifx_len instead of registry_len throughout. (fhandler_registry::set_name): Define. Set wow64 and prefix_len according to directory prefix. (fhandler_registry::fhandler_registry): Set wow64 and prefix_len to default values. (open_key): Add wow64 argument. Handle wow64 in call to RegOpenKeyEx. Use fhandler_registry member wow64 in this place throughout. --- winsup/cygwin/ChangeLog | 19 ++++++++++++ winsup/cygwin/fhandler.h | 5 +++- winsup/cygwin/fhandler_proc.cc | 24 ++++++++++------ winsup/cygwin/fhandler_registry.cc | 46 +++++++++++++++++++++--------- 4 files changed, 70 insertions(+), 24 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 449849100..5a4491547 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,22 @@ +2006-10-19 Corinna Vinschen + + * fhandler.h (fhandler_base::set_name): Make virtual. + (class fhandler_registry): Add wow64 and prefix_len members. + Declare set_name method. + * fhandler_proc.cc (PROC_REGISTRY32): Define. + (PROC_REGISTRY64): Define. + (proc_listing): Add "registry32" and "registry64" elements. + (proc_fhandlers): Add corresponding FH_REGISTRY values. + * fhandler_registry.cc (registry_len): Drop static value in favor of + class member prefix_len. Use preifx_len instead of registry_len + throughout. + (fhandler_registry::set_name): Define. Set wow64 and prefix_len + according to directory prefix. + (fhandler_registry::fhandler_registry): Set wow64 and prefix_len to + default values. + (open_key): Add wow64 argument. Handle wow64 in call to RegOpenKeyEx. + Use fhandler_registry member wow64 in this place throughout. + 2006-10-19 Corinna Vinschen * fhandler_proc.cc: Drop superfluous definition of _WIN32_WINNT. diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 6103b432c..c740ecee9 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -139,7 +139,7 @@ class fhandler_base class fhandler_base *archetype; int usecount; - void set_name (path_conv &pc); + virtual void set_name (path_conv &pc); int error () const {return pc.error;} void set_error (int error) {pc.error = error;} bool exists () const {return pc.exists ();} @@ -1266,8 +1266,11 @@ class fhandler_registry: public fhandler_proc { private: char *value_name; + DWORD wow64; + int prefix_len; public: fhandler_registry (); + void set_name (path_conv &pc); int exists(); int readdir (DIR *, dirent *) __attribute__ ((regparm (3))); _off64_t telldir (DIR *); diff --git a/winsup/cygwin/fhandler_proc.cc b/winsup/cygwin/fhandler_proc.cc index dd706743d..e1bc4d1f3 100644 --- a/winsup/cygwin/fhandler_proc.cc +++ b/winsup/cygwin/fhandler_proc.cc @@ -33,15 +33,17 @@ details. */ #include /* offsets in proc_listing */ -static const int PROC_LOADAVG = 2; // /proc/loadavg -static const int PROC_MEMINFO = 3; // /proc/meminfo -static const int PROC_REGISTRY = 4; // /proc/registry -static const int PROC_STAT = 5; // /proc/stat -static const int PROC_VERSION = 6; // /proc/version -static const int PROC_UPTIME = 7; // /proc/uptime -static const int PROC_CPUINFO = 8; // /proc/cpuinfo -static const int PROC_PARTITIONS = 9; // /proc/partitions -static const int PROC_SELF = 10; // /proc/self +static const int PROC_LOADAVG = 2; // /proc/loadavg +static const int PROC_MEMINFO = 3; // /proc/meminfo +static const int PROC_REGISTRY = 4; // /proc/registry +static const int PROC_STAT = 5; // /proc/stat +static const int PROC_VERSION = 6; // /proc/version +static const int PROC_UPTIME = 7; // /proc/uptime +static const int PROC_CPUINFO = 8; // /proc/cpuinfo +static const int PROC_PARTITIONS = 9; // /proc/partitions +static const int PROC_SELF = 10; // /proc/self +static const int PROC_REGISTRY32 = 11; // /proc/registry32 +static const int PROC_REGISTRY64 = 12; // /proc/registry64 /* names of objects in /proc */ static const char *proc_listing[] = { @@ -56,6 +58,8 @@ static const char *proc_listing[] = { "cpuinfo", "partitions", "self", + "registry32", + "registry64", NULL }; @@ -76,6 +80,8 @@ static const DWORD proc_fhandlers[PROC_LINK_COUNT] = { FH_PROC, FH_PROC, FH_PROC, + FH_REGISTRY, + FH_REGISTRY, }; /* name of the /proc filesystem */ diff --git a/winsup/cygwin/fhandler_registry.cc b/winsup/cygwin/fhandler_registry.cc index 0982755d9..97974b246 100644 --- a/winsup/cygwin/fhandler_registry.cc +++ b/winsup/cygwin/fhandler_registry.cc @@ -25,7 +25,6 @@ details. */ #define _COMPILING_NEWLIB #include -static const int registry_len = sizeof ("registry") - 1; /* If this bit is set in __d_position then we are enumerating values, * else sub-keys. keeping track of where we are is horribly messy * the bottom 16 bits are the absolute position and the top 15 bits @@ -84,7 +83,7 @@ static const int SPECIAL_DOT_FILE_COUNT = /* Name given to default values */ static const char *DEFAULT_VALUE_NAME = "@"; -static HKEY open_key (const char *name, REGSAM access, bool isValue); +static HKEY open_key (const char *name, REGSAM access, DWORD wow64, bool isValue); /* Returns 0 if path doesn't exist, >0 if path is a directory, * <0 if path is a file. @@ -105,7 +104,7 @@ fhandler_registry::exists () const char *path = get_name (); debug_printf ("exists (%s)", path); - path += proc_len + registry_len + 1; + path += proc_len + prefix_len + 1; if (*path) path++; else @@ -133,12 +132,12 @@ fhandler_registry::exists () goto out; } - hKey = open_key (path, KEY_READ, false); + hKey = open_key (path, KEY_READ, wow64, false); if (hKey != (HKEY) INVALID_HANDLE_VALUE) file_type = 1; else { - hKey = open_key (path, KEY_READ, true); + hKey = open_key (path, KEY_READ, wow64, true); if (hKey == (HKEY) INVALID_HANDLE_VALUE) return 0; @@ -186,9 +185,27 @@ out: return file_type; } +void +fhandler_registry::set_name (path_conv &in_pc) +{ + if (strncasematch (in_pc.normalized_path, "/proc/registry32", 16)) + { + wow64 = KEY_WOW64_32KEY; + prefix_len += 2; + } + else if (strncasematch (in_pc.normalized_path, "/proc/registry64", 16)) + { + wow64 = KEY_WOW64_64KEY; + prefix_len += 2; + } + fhandler_base::set_name (in_pc); +} + fhandler_registry::fhandler_registry (): fhandler_proc () { + wow64 = 0; + prefix_len = sizeof ("registry") - 1; } int @@ -218,9 +235,9 @@ fhandler_registry::fstat (struct __stat64 *buf) if (file_type != 0 && file_type != 2) { HKEY hKey; - const char *path = get_name () + proc_len + registry_len + 2; + const char *path = get_name () + proc_len + prefix_len + 2; hKey = - open_key (path, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE, + open_key (path, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE, wow64, (file_type < 0) ? true : false); if (hKey != (HKEY) INVALID_HANDLE_VALUE) @@ -279,7 +296,7 @@ fhandler_registry::readdir (DIR *dir, dirent *de) DWORD buf_size = CYG_MAX_PATH; char buf[buf_size]; HANDLE handle; - const char *path = dir->__d_dirname + proc_len + 1 + registry_len; + const char *path = dir->__d_dirname + proc_len + 1 + prefix_len; LONG error; int res = ENMFILE; @@ -294,7 +311,7 @@ fhandler_registry::readdir (DIR *dir, dirent *de) } if (dir->__handle == INVALID_HANDLE_VALUE && dir->__d_position == 0) { - handle = open_key (path + 1, KEY_READ, false); + handle = open_key (path + 1, KEY_READ, wow64, false); dir->__handle = handle; } if (dir->__handle == INVALID_HANDLE_VALUE) @@ -406,7 +423,7 @@ fhandler_registry::open (int flags, mode_t mode) goto out; const char *path; - path = get_name () + proc_len + 1 + registry_len; + path = get_name () + proc_len + 1 + prefix_len; if (!*path) { if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) @@ -482,10 +499,10 @@ fhandler_registry::open (int flags, mode_t mode) goto out; } - handle = open_key (path, KEY_READ, false); + handle = open_key (path, KEY_READ, wow64, false); if (handle == (HKEY) INVALID_HANDLE_VALUE) { - handle = open_key (path, KEY_READ, true); + handle = open_key (path, KEY_READ, wow64, true); if (handle == (HKEY) INVALID_HANDLE_VALUE) { res = 0; @@ -626,7 +643,7 @@ value_not_found: /* Auxillary member function to open registry keys. */ static HKEY -open_key (const char *name, REGSAM access, bool isValue) +open_key (const char *name, REGSAM access, DWORD wow64, bool isValue) { HKEY hKey = (HKEY) INVALID_HANDLE_VALUE; HKEY hParentKey = (HKEY) INVALID_HANDLE_VALUE; @@ -652,7 +669,8 @@ open_key (const char *name, REGSAM access, bool isValue) effective_access = access; LONG error = - RegOpenKeyEx (hParentKey, component, 0, effective_access, &hKey); + RegOpenKeyEx (hParentKey, component, 0, effective_access | wow64, + &hKey); if (error != ERROR_SUCCESS) { hKey = (HKEY) INVALID_HANDLE_VALUE;