2010-09-11 13 views
5

saludos StackOverflowians,Gancho API en una función de objeto COM?

Como descubrió here, Windows 7 ofrece un fallo en el que el evento DISPID_BEFORENAVIGATE2 no se dispara para las instancias de Windows Explorer. Este evento permite que se notifiquen las extensiones de shell cuando está a punto de realizarse una navegación, y (lo que es más importante para mí) tenemos la oportunidad de cancelar la navegación. He estado buscando una solución por bastante tiempo, y creo que encontré una. Pero me gustaría obtener algunas opiniones sobre cuán seguro es.

He estado jugando con API enganchándose mucho últimamente, y ya lo estoy usando para conectar algunas funciones para mi extensión. Me di cuenta de que hay un function in IShellBrowser que controla la navegación. Al principio pensé que no podías enganchar algo así, pero al leer sobre el layout of a COM object me di cuenta que debería ser posible simplemente tomando el puntero de la función derecha del vtable de cualquier instancia activa. Efectivamente, funciona como un sueño. Después de establecer el enganche, todas las navegaciones en todas las ventanas del Explorador se ejecutan directamente a través de mi función de desvío, y puedo decidir si las rechazaré en función de su pidl de destino.

Entonces mi pregunta es, ¿hay alguna razón por la que NO deba hacer esto? Nunca escuché sobre el enganche API utilizado para enganchar funciones de objetos COM. ¿Hay circunstancias en las que no funcionaría? ¿Es peligroso? (Más que el enganche API regular, al menos)

El código relevante a continuación. Estoy usando MinHook, una biblioteca de enlaces minimalista que usa el método comprobado de funciones de trampolín.

typedef HRESULT (WINAPI *BROWSEOBJECT)(IShellBrowser*, PCUIDLIST_RELATIVE, UINT); 
HRESULT WINAPI DetourBrowseObject(IShellBrowser* _this, PCUIDLIST_RELATIVE pidl, UINT wFlags); 
BROWSEOBJECT fpBrowseObject = NULL; 
BROWSEOBJECT ShellBrowser_BrowseObject = NULL; 

bool Initialize() { 
    if(MH_Initialize() != MH_OK) { 
     return false; 
    } 

    // Get a reference to an existing IShellBrowser. Any instance will do. 
    // ShellBrowser enum code taken from The Old New Thing 
    IShellWindows *psw; 
    BOOL fFound = FALSE; 
    if (SUCCEEDED(CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_ALL, IID_IShellWindows, (void**)&psw))) { 
     VARIANT v; 
     V_VT(&v) = VT_I4; 
     IDispatch *pdisp; 
     for (V_I4(&v) = 0; !fFound && psw->Item(v, &pdisp) == S_OK; V_I4(&v)++) { 
      IWebBrowserApp *pwba; 
      if (SUCCEEDED(pdisp->QueryInterface(IID_IWebBrowserApp, (void**)&pwba))) { 
       IServiceProvider *psp; 
       if (SUCCEEDED(pwba->QueryInterface(IID_IServiceProvider, (void**)&psp))) { 
        IShellBrowser *psb; 
        if (SUCCEEDED(psp->QueryService(SID_STopLevelBrowser,IID_IShellBrowser, (void**)&psb))) { 
         fFound = true; 

         // Grab the 11th entry in the VTable, which is BrowseObject 
         void** vtable = (*(void***)(psb)); 
         ShellBrowser_BrowseObject = (BROWSEOBJECT)(vtable[11]); 
         psb->Release(); 
        } 
        psp->Release(); 
       } 
       pwba->Release(); 
      } 
      pdisp->Release(); 
     } 
     psw->Release(); 
    } 

    if(fFound) { 
     if(MH_CreateHook(ShellBrowser_BrowseObject, &DetourBrowseObject, reinterpret_cast<void**>(&fpBrowseObject)) != MH_OK) { 
      return false; 
     } 
     if(MH_EnableHook(ShellBrowser_BrowseObject) != MH_OK) { 
      return false; 
     } 
    } 
    return true; 
} 

HRESULT WINAPI DetourBrowseObject(IShellBrowser* _this, PCUIDLIST_RELATIVE pidl, UINT wFlags) { 
    if(NavigateIsOkay(pidl, wFlags)) { 
     return fpBrowseObject(_this, pidl, wFlags); 
    } 
    else { 
     return S_FALSE; 
    }  
} 

Respuesta

2

nunca he oído hablar de API de enganche para enganchar utiliza funciones de objeto COM.

Las funciones miembro de los objetos COM no son tan diferentes y pueden engancharse muy bien si se siguen las pautas habituales para enganchar. Hace unos años, tuve que conectar componentes COM de una solución de CRM patentada para conectarlo a un servidor de base de datos. La aplicación funcionó bien y se ha mantenido bastante estable durante varios años.

+0

Gracias por la tranquilidad. =) –

+1

Esta respuesta es incorrecta. ¡El enganche COM es muy especial, especialmente en Internet Explorer y no tiene nada en común con el enganche de API común! Un objeto COM puede ser envuelto en un objeto contenedor y finalmente solo engancha el contenedor. Lee los enlaces en este artículo: http://stackoverflow.com/questions/1505196/spying-on-com-objects – Elmue