Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2008-12-19 17:31:40 +0300
committerCorinna Vinschen <corinna@vinschen.de>2008-12-19 17:31:40 +0300
commit887eb76fca6231e6d6b9a5058a95cba28dcc46b6 (patch)
tree7a7d0e603280b14389c1fdb3a60f82cdb4207504
parent292c99741d563765d5c09e70aa60bb6f0968c498 (diff)
* fhandler_registry.cc (perf_data_files): New table.
(PERF_DATA_FILE_COUNT): New constant. (fhandler_registry::exists): Add check for HKEY_PERFORMANCE_DATA value names. (fhandler_registry::fstat): For HKEY_PERFORMANCE_DATA, return default values only. (fhandler_registry::readdir): For HKEY_PERFORMANCE_DATA, list names from perf_data_files only. (fhandler_registry::fill_filebuf): Use larger buffer to speed up access to HKEY_PERFORMANCE_DATA values. Remove check for possible subkey. Add RegCloseKey (). (open_key): Replace goto by break, remove label. Do not try to open subkey of HKEY_PERFORMANCE_DATA. Add missing RegCloseKey () after open subkey error.
-rw-r--r--winsup/cygwin/ChangeLog17
-rw-r--r--winsup/cygwin/fhandler_registry.cc73
2 files changed, 77 insertions, 13 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 2b18c7d89..3ee453fb3 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,20 @@
+2008-12-19 Christian Franke <franke@computer.org>
+
+ * fhandler_registry.cc (perf_data_files): New table.
+ (PERF_DATA_FILE_COUNT): New constant.
+ (fhandler_registry::exists): Add check for HKEY_PERFORMANCE_DATA
+ value names.
+ (fhandler_registry::fstat): For HKEY_PERFORMANCE_DATA, return
+ default values only.
+ (fhandler_registry::readdir): For HKEY_PERFORMANCE_DATA, list
+ names from perf_data_files only.
+ (fhandler_registry::fill_filebuf): Use larger buffer to speed up
+ access to HKEY_PERFORMANCE_DATA values. Remove check for possible
+ subkey. Add RegCloseKey ().
+ (open_key): Replace goto by break, remove label. Do not try to
+ open subkey of HKEY_PERFORMANCE_DATA. Add missing RegCloseKey ()
+ after open subkey error.
+
2008-12-19 Corinna Vinschen <corinna@vinschen.de>
* path.cc (path_conv::check): Handle incoming DOS paths non-POSIXy,
diff --git a/winsup/cygwin/fhandler_registry.cc b/winsup/cygwin/fhandler_registry.cc
index 9efb2d146..c3c226474 100644
--- a/winsup/cygwin/fhandler_registry.cc
+++ b/winsup/cygwin/fhandler_registry.cc
@@ -75,6 +75,22 @@ static const char *special_dot_files[] =
static const int SPECIAL_DOT_FILE_COUNT =
(sizeof (special_dot_files) / sizeof (const char *)) - 1;
+/* Value names for HKEY_PERFORMANCE_DATA.
+ *
+ * CAUTION: Never call RegQueryValueEx (HKEY_PERFORMANCE_DATA, "Add", ...).
+ * It WRITES data and may destroy the perfc009.dat file. Same applies to
+ * name prefixes "Ad" and "A".
+ */
+static const char * const perf_data_files[] =
+{
+ "@",
+ "Costly",
+ "Global"
+};
+
+static const int PERF_DATA_FILE_COUNT =
+ sizeof (perf_data_files) / sizeof (perf_data_files[0]);
+
static HKEY open_key (const char *name, REGSAM access, DWORD wow64, bool isValue);
/* Return true if char must be encoded.
@@ -273,6 +289,24 @@ fhandler_registry::exists ()
if (hKey == (HKEY) INVALID_HANDLE_VALUE)
return 0;
+ if (hKey == HKEY_PERFORMANCE_DATA)
+ {
+ /* RegEnumValue () returns garbage for this key.
+ RegQueryValueEx () returns a PERF_DATA_BLOCK even
+ if a value does not contain any counter objects.
+ So allow access to the generic names and to
+ (blank separated) lists of counter numbers.
+ Never allow access to "Add", see above comment. */
+ for (int i = 0; i < PERF_DATA_FILE_COUNT && file_type == 0; i++)
+ {
+ if (strcasematch (perf_data_files[i], file))
+ file_type = -1;
+ }
+ if (file_type == 0 && !file[strspn (file, " 0123456789")])
+ file_type = -1;
+ goto out;
+ }
+
if (!val_only && dec_file[0])
{
while (ERROR_SUCCESS ==
@@ -376,7 +410,11 @@ fhandler_registry::fstat (struct __stat64 *buf)
open_key (path, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE, wow64,
(file_type < 0) ? true : false);
- if (hKey != (HKEY) INVALID_HANDLE_VALUE)
+ if (hKey == HKEY_PERFORMANCE_DATA)
+ /* RegQueryInfoKey () always returns write time 0,
+ RegQueryValueEx () does not return required buffer size. */
+ ;
+ else if (hKey != (HKEY) INVALID_HANDLE_VALUE)
{
FILETIME ftLastWriteTime;
DWORD subkey_count;
@@ -474,6 +512,18 @@ fhandler_registry::readdir (DIR *dir, dirent *de)
res = 0;
goto out;
}
+ if ((HKEY) dir->__handle == HKEY_PERFORMANCE_DATA)
+ {
+ /* RegEnumValue () returns garbage for this key,
+ simulate only a minimal listing of the generic names. */
+ if (dir->__d_position >= SPECIAL_DOT_FILE_COUNT + PERF_DATA_FILE_COUNT)
+ goto out;
+ strcpy (de->d_name, perf_data_files[dir->__d_position - SPECIAL_DOT_FILE_COUNT]);
+ dir->__d_position++;
+ res = 0;
+ goto out;
+ }
+
retry:
if (dir->__d_position & REG_ENUM_VALUES_MASK)
/* For the moment, the type of key is ignored here. when write access is added,
@@ -782,23 +832,21 @@ fhandler_registry::fill_filebuf ()
bufalloc = 0;
do
{
- bufalloc += 1000;
+ bufalloc += 16 * 1024;
filebuf = (char *) crealloc_abort (filebuf, bufalloc);
size = bufalloc;
error = RegQueryValueEx (handle, value_name, NULL, &type,
(BYTE *) filebuf, &size);
if (error != ERROR_SUCCESS && error != ERROR_MORE_DATA)
{
- if (error != ERROR_FILE_NOT_FOUND)
- {
- seterrno_from_win_error (__FILE__, __LINE__, error);
- return true;
- }
- goto value_not_found;
+ seterrno_from_win_error (__FILE__, __LINE__, error);
+ return false;
}
}
while (error == ERROR_MORE_DATA);
filesize = size;
+ /* RegQueryValueEx () opens HKEY_PERFORMANCE_DATA. */
+ RegCloseKey (handle);
}
return true;
value_not_found:
@@ -851,9 +899,9 @@ open_key (const char *name, REGSAM access, DWORD wow64, bool isValue)
if (*name)
name++;
if (*name == 0 && isValue == true)
- goto out;
+ break;
- if (val_only || !component[0])
+ if (val_only || !component[0] || hKey == HKEY_PERFORMANCE_DATA)
{
set_errno (ENOENT);
if (parentOpened)
@@ -874,14 +922,14 @@ open_key (const char *name, REGSAM access, DWORD wow64, bool isValue)
REG_OPTION_BACKUP_RESTORE,
effective_access | wow64, NULL,
&hKey, NULL);
+ if (parentOpened)
+ RegCloseKey (hParentKey);
if (error != ERROR_SUCCESS)
{
hKey = (HKEY) INVALID_HANDLE_VALUE;
seterrno_from_win_error (__FILE__, __LINE__, error);
return hKey;
}
- if (parentOpened)
- RegCloseKey (hParentKey);
hParentKey = hKey;
parentOpened = true;
}
@@ -895,7 +943,6 @@ open_key (const char *name, REGSAM access, DWORD wow64, bool isValue)
hParentKey = hKey;
}
}
-out:
return hKey;
}