zoukankan      html  css  js  c++  java
  • 枚举COM指针所能查询的接口

    鄙人最近从事COM开发,基本上得到一COM接口就要QueryInterface另外一个接口,都能获取到哪些接口就要查文档了。如果有个函数传入一接口指针,能输出其支持的所有接口那就好了。接口的注册表项位于HKEY_CLASSES_ROOT\Interface中,每个子项的名称都是以接口IID命名,其默认值就是接口的字符串名称。

    先写个函数查注册表中接口IID对应的接口名称:

    /*
    * 获取COM接口的名称,返回获取成功与否
    * 接口名为GUID注册表项默认的值
    */
    template
    <int t_nSize>
    ATLINLINE BOOL GetInterfaceName( REFIID riid, TCHAR (
    &szName)[t_nSize] )
    {
        BOOL  bRet  
    =  FALSE;
    #ifdef   USER_ATL_
        
    //CRegKey版本
        CRegKey  regKey;
        OLECHAR szGuid[
    64];
        ::StringFromGUID2(riid, szGuid, 
    sizeof(szGuid)/sizeof(OLECHAR));
        TCHAR szSubKey[
    128];
        wsprintf( szSubKey, _T(
    "Interface\\%s"), COLE2T(szGuid) );
        
    if( ERROR_SUCCESS == regKey.Open( HKEY_CLASSES_ROOT, szSubKey,  KEY_QUERY_VALUE ) )
        {
            ULONG cb 
    = 127;
            
    if( ERROR_SUCCESS == regKey.QueryStringValue( NULL, szName, &cb) )
            {
                bRet  
    =  TRUE;
            }
            regKey.Close();
        }
    #else
        
    //API版本:
        OLECHAR szGuid[64];
        ::StringFromGUID2(riid, szGuid, 
    sizeof(szGuid)/sizeof(OLECHAR));
        TCHAR szSubKey[
    128];
        wsprintf( szSubKey, _T(
    "Interface\\%s"), COLE2T(szGuid) );

        HKEY hKey;
        
    if( ERROR_SUCCESS == ::RegOpenKeyEx( HKEY_CLASSES_ROOT, szSubKey, 0, KEY_QUERY_VALUE, &hKey) )
        {
            DWORD dwType;
            DWORD dwSize 
    = t_nSize * sizeof(TCHAR);
            
    if( ERROR_SUCCESS == ::RegQueryValueEx(hKey, NULL, NULL, &dwType, reinterpret_cast<LPBYTE>(szName), &dwSize) )
            {
                bRet  
    =  TRUE;
            }
            ::RegCloseKey(hKey);
        }
    #endif
        
    return bRet;
    }

    读注册表分别用了API版本和ATL的CRegKey版本(大家不要BS,鄙人一向信奉多练练手没害处)。

    之后遍历注册表项HKEY_CLASSES_ROOT\Interface,获取每个接口的IID,如果传入的COM接口QueryInterface这个接口成功,则支持该接口,输出其接口名称。

    /*
    * 枚举接口所有名称
    */
    ATLINLINE 
    void ScanInterface( IUnknown *pUnk )
    {
        
    if( pUnk==NULL ) return;

    #ifdef   USER_ATL_
        CRegKey  regKey;

        
    if( ERROR_SUCCESS == regKey.Open( HKEY_CLASSES_ROOT, _T("Interface"), KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS ) )
        {
            TCHAR szGuid[
    128];
            DWORD dwIndex 
    = 0;
            DWORD dwSize 
    = _countof(szGuid) * sizeof(TCHAR);
            
    while( ERROR_SUCCESS == regKey.EnumKey( dwIndex, szGuid, &dwSize ) ) 
            {
                IID iid;
                ::IIDFromString( CT2OLE(szGuid), 
    &iid );

                CComPtr
    <IUnknown> spUnk;
                
    if( SUCCEEDED( pUnk->QueryInterface( iid, (LPVOID*)&spUnk ) ) ) 
                {
                    TCHAR szName[
    128];
                    
    if( GetInterfaceName( iid, szName ) )
                    {
                        AtlTrace( _T(
    "%s\n"), szName );
                    }
                }
                dwSize 
    = _countof(szGuid) * sizeof(TCHAR);
                dwIndex
    ++;
            }

            regKey.Close();
        }
    #else
        HKEY hKey;
        
    if( ERROR_SUCCESS == ::RegOpenKeyEx( HKEY_CLASSES_ROOT, _T("Interface"), 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hKey) ) 
        {
            TCHAR   szGuid[
    128];
            DWORD   dwIndex 
    = 0;
            DWORD   dwSize 
    = _countof(szGuid) * sizeof(TCHAR);

            
    while( ERROR_SUCCESS == ::RegEnumKeyEx(hKey, dwIndex, szGuid, &dwSize, NULL, NULL,NULL, NULL ) ) 
            {
                IID iid;
                ::IIDFromString( CT2OLE(szGuid), 
    &iid);

                CComPtr
    <IUnknown> spUnk;
                
    if( SUCCEEDED( pUnk->QueryInterface( iid, (LPVOID*)&spUnk ) ) ) 
                {
                    TCHAR szName[
    128];
                    
    if( GetInterfaceName( iid, szName ) )
                    {
                        AtlTrace( _T(
    "%s\n"), szName );
                    }
                }

                dwSize 
    = _countof(szGuid) * sizeof(TCHAR);
                dwIndex
    ++;
            }
            ::RegCloseKey(hKey);
        }

    #endif
    }

    至此已经完成,当然这种方案缺点在于还有很多定制的接口并没有在注册表中注册,因此不够彻底。不过有胜于无了

  • 相关阅读:
    python+selenium框架
    django--form组件
    python +selenium上传文件
    python--UI---登录---验证码
    python+selenium button定位方法
    css-定位技术
    css-盒子模型
    css-元素分类
    序列化
    FileUploadController
  • 原文地址:https://www.cnblogs.com/fangkm/p/1599418.html
Copyright © 2011-2022 走看看