* 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…
	
		Reference in New Issue