* 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.
This commit is contained in:
parent
292c99741d
commit
887eb76fca
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user