您的位置:首页 > 编程语言 > C语言/C++

C++ 通过RegEnumKeyEx枚举的问题

2016-05-25 16:43 507 查看

问题描述:

这几天在做列举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<std::string> &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<std::string> &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 IT