2013-04-01 5 views
0

J'ai un plugin NPAPI qui utilise SetWindowsHookEx sous le capot pour faire un grattage d'écran. Ce plugin semble fonctionner avec succès sur la plupart des machines que j'ai testées. Cependant, sur une machine (Windows 7 32 bits), lorsque j'exécute le plugin sous Chrome (26.0.1410.43m), l'appel à SetWindowsHookEx bloque le processus dans lequel le plugin est hébergé. Ce n'est pas que SetWindowsHookEx renvoie une erreur - il bloque simplement le processus. Et encore une fois, cela n'arrive que sur une seule machine: cela fonctionne bien sur tous les autres que nous avons testés.SetWindowsHookEx se bloque

Mais voici la chose étrange. Comme vous le savez, Chrome a plusieurs façons de localiser les plugins. Normalement, notre setup.exe crée des entrées de registre qui pointent vers le plug-in, comme si (de l'installateur NSIS):

WriteRegStr HKLM "Software\MozillaPlugins\@alanta.com/WinVncCtl\" "Path" "$INSTDIR\npWinVnc.dll" 
WriteRegStr HKLM "Software\MozillaPlugins\@alanta.com/WinVncCtl\" "ProductName" "Alanta Remote Desktop Server" 
WriteRegStr HKLM "Software\MozillaPlugins\@alanta.com/WinVncCtl\MimeTypes\application/x-alanta-vnc" "Description" "Alanta's VNC Server NPAPI Plugin" 

Lorsque Chrome charge le plug-in de cet endroit, il se bloque sur l'appel SetWindowsHookEx.

Cependant, si je désinstalle le plugin, alors copiez exactement la même DLL à %ProgramFiles%\Mozilla Firefox\Plugins\, puis Chrome charge et exécute le plugin très bien, et l'appel à SetWindowsHookEx() réussit.

Pour ce que ça vaut la peine, voici l'appel réel (assez tourbière standard):

// Add the CallWnd hook 
hCallWndHook = SetWindowsHookEx(
       WH_CALLWNDPROC,     // Hook in before msg reaches app 
       (HOOKPROC) CallWndProc,   // Hook procedure 
       hInstance,      // This DLL instance 
       0L        // Hook in to all apps 
       // GetCurrentThreadId()   // DEBUG : HOOK ONLY WinVNC 
       ); 

Le débogueur indique que tous les paramètres pointent vers des choses légitimes, valides.

Des suggestions pour le dépannage de ce? Quelqu'un at-il connaissance de bizarreries dans SetWindowsHookEx qui pourraient apparaître dans ce scénario?

EDIT: Le CallWndProc ressemble à ceci:

LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) 
{ 
    // Do we have to handle this message? 
    if (nCode == HC_ACTION) 
    { 
     // Process the hook if the WinVNC thread ID is valid 
     if (vnc_thread_id) 
     { 
      CWPSTRUCT *cwpStruct = (CWPSTRUCT *) lParam; 
      HookHandle(cwpStruct->message, cwpStruct->hwnd, cwpStruct->wParam, cwpStruct->lParam); 
     } 
    } 

    // Call the next handler in the chain 
    return CallNextHookEx (hCallWndHook, nCode, wParam, lParam); 
} 

points d'arrêt dans le CallWndProc ne semblent pas se faire frapper, alors je soupçonne que l'accident se produit lors de la mise du crochet plutôt que plus tard au cours de sa En traitement.

+0

Vous ne devriez pas avoir besoin de placer le pointeur sur votre fonction de rappel vers 'HOOKPROC'. Il devrait déjà avoir ce type. Si ce n'est pas le cas, le compilateur essaie de vous avertir d'un problème potentiel. Ne fermez pas simplement avec un plâtre. –

+0

@CodyGray - Bonne suggestion. Je ne sais pas pourquoi la distribution était là. Le 'CallWndProc' semble avoir la bonne signature, et tout compile bien sans la distribution.J'ai ajouté le code pour le CallWndProc à ma question. –

Répondre

0

Si la même DLL se comporte différemment lorsqu'elle est placée dans un répertoire différent, cela suggère que cela modifie l'ordre de chargement des plugins.

(Le répertoire une DLL se charge de n'affecte pas le chemin de recherche utilisé pour localiser et charger ses dépendances)

Je certainement jeter un oeil à d'autres plug-ins sont chargés sur le même système et voir si leur présence déclenche (ou peut-être même responsable de) votre accident. Ensuite, je suggère de désinstaller et de réinstaller Chrome, éventuellement dans un nouveau répertoire, au cas où l'un des fichiers binaires Chrome serait corrompu ou subverti.

+0

Merci pour les suggestions. J'ai essayé de désinstaller et de réinstaller Chrome, sans effet, sauf que maintenant, il se bloque lorsque je le charge de l'un ou l'autre emplacement. Bien sûr, il y a d'autres plugins installés, mais je ne pense pas qu'aucun d'entre eux ne soit chargé, parce que j'ai l'option '--plugin-startup-dialog', et ça montre seulement une boite de dialogue pour ce brancher. J'ai utilisé le SysInternals Process Monitor pour vérifier l'activité des fichiers, et j'ai vu que les seules DLL qui étaient chargées étaient celles que j'attendais. –

0

Il s'avère que c'était un programme de sécurité agressif. Apparemment, son heuristique permettait à certaines DLL de passer tout en ne permettant pas d'autres. Il était en train de tuer le processus d'hébergement dès qu'il a vu l'appel à SetWindowsHookEx(). Le remplacer par quelque chose de raisonnable a résolu le problème.

+0

Intéressant, heureux de voir que vous avez compris la cause. Je me demandais quand j'ai lu votre question pourquoi vous avez besoin d'installer un crochet * global * pour faire un grattage d'écran. L'installation d'un hook global * doit * activer un moniteur de sécurité. À tout le moins, c'est un comportement discutable pour un plug-in de navigateur Web. –

+0

Bonnes questions à tous. Je n'ai pas écrit cette partie du code - je viens d'adapter le serveur UltraVNC à nos propres usages - donc je ne suis pas sûr des autres façons de le faire. –