C++ 通过RegEnumKeyEx枚举的问题

问题描述:

这几天在做列举IE浏览器插件的问题,后来想到了用注册列表的方法做。

大体思路是从HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Ext\\Stats目录下获取所有的CLSID值,

然后从HKEY_CLASSES_ROOT\\CLSID下找到对应的值得到具体的信息

(网上有个老外写的软件:BrowserAddonsView可能做到)

问题出在通过CLSID找到具体信息这步上,发现使用RegEnumKeyEx枚举的信息总是和手动regedit进去看到对应键目录中值不一致,

有时会多,有时会少

问题代码:

BOOL GetRegListKey( HKEY iHeyIn, std::string sRegSubDir, std::vector &sKeyList )
{
	TCHAR *pRegSubDir = _bstr_t( sRegSubDir.c_str() );
	HKEY nKeyOut, nKeySubOut;
	DWORD iIndex = 0;
	TCHAR szSubKey[MAX_PATH] = _T("");
	DWORD dSize = MAX_PATH;
	if ( CheckHkeyType(iHeyIn) == FALSE )
	{
		std::cout << "Unknow HKEY type" << std::endl;
		return false;
	}
	LONG nLResult = RegOpenKeyEx(iHeyIn, pRegSubDir, 0, KEY_CREATE_LINK | KEY_WRITE | KEY_READ | KEY_NOTIFY, &nKeyOut);
	if( ERROR_SUCCESS != nLResult )
	{
		std::cout << "Open Registor Error: " << nLResult << std::endl;
		return false;
	}
	while( ( nLResult = RegEnumKeyEx( nKeyOut, iIndex, szSubKey, &dSize, NULL, NULL, NULL, NULL) ) == ERROR_SUCCESS  )
	{
		//std::wcout << pRegSubDir << "\\" << pBuffer << std::endl;
		sKeyList.push_back( std::string(_bstr_t(szSubKey)) );
		memset( szSubKey, 0, sizeof(szSubKey) );
		dSize = MAX_PATH;
		iIndex++;
	}
	cout << nLResult << endl;
	return true;
}


解决方法及其原因:

通过把HKEY_CLASSES_ROOT\CLSID下面没有出现的节点(而在程序中能够输出打印出来的节点)进行查找发现在Wow6432Node/CLSID下面。

原来Win7及其以上的系统中,在注册列表HKEY_CLASSES_ROOT根键下面,有个Wow6432Node这个子主键,这个主键从网上查找发现

是个映射虚拟节点,会根据本地主机是32位还是64位系统进行映射。所以通过RegEnumKeyEx得到的节点是映射过后的,

可以通过在Wow6432Node/CLISID下面进行对比。

解决方法:

将上面函数改为:

BOOL GetRegListKey( HKEY iHeyIn, std::string sRegSubDir, std::list &sKeyList )
{
	TCHAR *pRegSubDir = _bstr_t( sRegSubDir.c_str() );
	HKEY nKeyOut = NULL;
	DWORD iIndex = 1;
	TCHAR szSubKey[MAX_PATH] = _T("");
	DWORD dSize = MAX_PATH;
	if ( CheckHkeyType(iHeyIn) == FALSE )
	{
		std::cout << "Unknow HKEY type" << std::endl;
		return false;
	}
	LONG nLResult = RegOpenKeyEx(iHeyIn, pRegSubDir, 0, 
					/*KEY_CREATE_LINK | KEY_WRITE |*/ KEY_READ /*| KEY_NOTIFY*/ | KEY_WOW64_32KEY, &nKeyOut);
	switch ( nLResult )
	{
	case ERROR_SUCCESS:
		break;
	case ERROR_FILE_NOT_FOUND:
	case ERROR_PATH_NOT_FOUND:
		{
			if ( ( nLResult = RegOpenKeyEx(iHeyIn, pRegSubDir, 0, 
				KEY_CREATE_LINK | KEY_WRITE | KEY_READ | KEY_NOTIFY | KEY_WOW64_64KEY, &nKeyOut) ) == ERROR_SUCCESS )
			{
				break;
			}
		}
		break;
	case ERROR_ACCESS_DENIED:
		{
			std::cout << "请使用管理员身份运行"  << endl;
		}
		break;
	default:
		{
			std::cout << "出现错误: " << nLResult << endl;
		}
		break;
	}
	if( ERROR_SUCCESS != nLResult )
	{
		return false;
	}
	nLResult = RegEnumKeyEx( nKeyOut, iIndex, szSubKey, &dSize, NULL, NULL, NULL, NULL );
	while ( nLResult == ERROR_SUCCESS )
	{
		sKeyList.push_back( std::string(_bstr_t(szSubKey)) );
		memset( szSubKey, 0, sizeof(szSubKey) );
		dSize = MAX_PATH;
		iIndex++;
		nLResult = RegEnumKeyEx( nKeyOut, iIndex, szSubKey, &dSize, NULL, NULL, NULL, NULL) ;
	}
	RegCloseKey( nKeyOut );
	return true;
}


 
   
 
   
 
  

你可能感兴趣的:(Windows编程,C/C++,windows,IT)