OSDN Git Service

Hopefully stop crashes in apps when they exit on XP (#2254).
authorMichael Curran <mick@kulgan.net>
Fri, 20 Apr 2012 17:06:08 +0000 (03:06 +1000)
committerMichael Curran <mick@kulgan.net>
Fri, 20 Apr 2012 17:06:08 +0000 (03:06 +1000)
Specific changes to nvdaHelperRemote:
* Declare isProcessExiting extern in dllmain.h and use it in apiHooks_terminate to return early to stop freeing libraries if the process is exiting -- its dangerous to call LoadLibrary or FreeLibrary when dllmain is being run.
* dllmain: If the process is exiting, also unregister any in-context winEvent hooks. Seems that winEvents kept being fired on process shutdown trying to install IA2 support over and over again -- until the whole thing fell over due to it trying to log an error via a freed rpc binding handle.
* dllmain: only free nvdaController and nvdaControllerInternal binding handles if the process isn't exiting. If it is the OS will clean it up anyway and we want logging to work for as long as possible.

nvdaHelper/remote/apiHook.cpp
nvdaHelper/remote/dllmain.h
nvdaHelper/remote/injection.cpp

index 4f946cf..ee76afc 100644 (file)
@@ -90,6 +90,8 @@ bool apiHook_terminate() {
        Sleep(250);\r
        res=MH_Uninitialize();\r
        nhAssert(res==MH_OK);\r
+       //If the process is exiting do not free any dlls as the OS should do this itself correctly\r
+       if(isProcessExiting) return true;\r
        for(moduleSet_t::iterator i=g_hookedModules.begin();i!=g_hookedModules.end();++i) {\r
                FreeLibrary(*i);\r
        }\r
index 0aa1de2..98c204e 100644 (file)
@@ -20,5 +20,6 @@ http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 \r
 extern HINSTANCE dllHandle;\r
 extern wchar_t dllDirectory[MAX_PATH];\r
+extern bool isProcessExiting;\r
 \r
 #endif\r
index c4418bd..1581323 100644 (file)
@@ -153,11 +153,6 @@ if(isSecureModeNVDAProcess) real_OpenClipboard=apiHook_hookFunction_safe("USER32
        apiHook_terminate();\r
        //Terminate all in-process subsystems.\r
        inProcess_terminate();\r
-       //Unregister winEvents for this process\r
-       if(inprocWinEventHookID) { \r
-               UnhookWinEvent(inprocWinEventHookID);\r
-               inprocWinEventHookID=0;\r
-       }\r
        //Unregister any windows hooks registered so far\r
        killRunningWindowsHooks();\r
        //Release and close the thread mutex\r
@@ -316,9 +311,6 @@ BOOL WINAPI DllMain(HINSTANCE hModule,DWORD reason,LPVOID lpReserved) {
                #ifndef NDEBUG\r
                Beep(1760,75);\r
                #endif\r
-       //cleanup some RPC binding handles\r
-       RpcBindingFree(&nvdaControllerBindingHandle);\r
-       RpcBindingFree(&nvdaControllerInternalBindingHandle);\r
                if(lpReserved) { // process is terminating\r
                        isProcessExiting=true;\r
                        //If the inproc manager thread was killed off due to process termination then at least unregister hooks\r
@@ -330,9 +322,17 @@ BOOL WINAPI DllMain(HINSTANCE hModule,DWORD reason,LPVOID lpReserved) {
                                apiHook_terminate();\r
                                //Unregister any current windows hooks\r
                                killRunningWindowsHooks();\r
+                               //Unregister winEvents for this process\r
+                               if(inprocWinEventHookID) { \r
+                                       UnhookWinEvent(inprocWinEventHookID);\r
+                                       inprocWinEventHookID=0;\r
+                               }\r
                        }\r
                } else { //The dll is being unloaded from this process\r
                        TlsFree(tlsIndex_inThreadInjectionID);\r
+                       //cleanup some RPC binding handles\r
+                       RpcBindingFree(&nvdaControllerBindingHandle);\r
+                       RpcBindingFree(&nvdaControllerInternalBindingHandle);\r
                }\r
        }\r
        return TRUE;\r