MSI: Standardize handling of type 1 actions

Aric Stewart aric at codeweavers.com
Thu Jan 6 13:06:46 CST 2005


Make all custom type 1 actions happen in a seperate thread and close all 
handles (requires mikes CloseAllHandles patch) for that thread when it 
exits.

honors the concept of temporary MSI handles for custom actions
-------------- next part --------------
Index: dlls/msi/action.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/action.c,v
retrieving revision 1.62
diff -u -r1.62 action.c
--- dlls/msi/action.c	5 Jan 2005 17:13:12 -0000	1.62
+++ dlls/msi/action.c	6 Jan 2005 19:06:16 -0000
@@ -1413,40 +1413,40 @@
         WCHAR *source;
 } thread_struct;
 
-static DWORD WINAPI DllThread(LPVOID info)
+static DWORD WINAPI ACTION_CallDllFunction(thread_struct *stuff)
 {
-    HANDLE DLL;
+    HANDLE hModule;
     LPSTR proc;
-    thread_struct *stuff;
     CustomEntry *fn;
-     
-    stuff = (thread_struct*)info;
 
-    TRACE("Asynchronous start (%s, %s) \n", debugstr_w(stuff->source),
+    TRACE("calling function (%s, %s) \n", debugstr_w(stuff->source),
           debugstr_w(stuff->target));
 
-    DLL = LoadLibraryW(stuff->source);
-    if (DLL)
+    hModule = LoadLibraryW(stuff->source);
+    if (hModule)
     {
         proc = strdupWtoA( stuff->target );
-        fn = (CustomEntry*)GetProcAddress(DLL,proc);
+        fn = (CustomEntry*)GetProcAddress(hModule,proc);
         if (fn)
         {
             MSIHANDLE hPackage;
             MSIPACKAGE *package = stuff->package;
 
-            TRACE("Calling function\n");
+            TRACE("Calling function %s\n", proc);
             hPackage = msiobj_findhandle( &package->hdr );
-            if( !hPackage )
+            if (hPackage )
+            {
+                fn(hPackage);
+                msiobj_release( &package->hdr );
+            }
+            else
                 ERR("Handle for object %p not found\n", package );
-            fn(hPackage);
-            msiobj_release( &package->hdr );
         }
         else
             ERR("Cannot load functon\n");
 
         HeapFree(GetProcessHeap(),0,proc);
-        FreeLibrary(DLL);
+        FreeLibrary(hModule);
     }
     else
         ERR("Unable to load library\n");
@@ -1457,13 +1457,30 @@
     return 0;
 }
 
+static DWORD WINAPI DllThread(LPVOID info)
+{
+    thread_struct *stuff;
+    DWORD rc = 0;
+  
+    TRACE("MSI Thread (0x%lx) started for custom action\n",
+                        GetCurrentThreadId());
+    
+    stuff = (thread_struct*)info;
+    rc = ACTION_CallDllFunction(stuff);
+
+    TRACE("MSI Thread (0x%lx) finished\n",GetCurrentThreadId());
+    /* clse all handles for this thread */
+    MsiCloseAllHandles();
+    return rc;
+}
+
 static UINT HANDLE_CustomType1(MSIPACKAGE *package, const LPWSTR source, 
                                 const LPWSTR target, const INT type)
 {
     WCHAR tmp_file[MAX_PATH];
-    CustomEntry *fn;
-    HANDLE DLL;
-    LPSTR proc;
+    thread_struct *info;
+    DWORD ThreadId;
+    HANDLE ThreadHandle;
 
     store_binary_to_temp(package, source, tmp_file);
 
@@ -1476,48 +1493,19 @@
         strcatW(tmp_file,dot);
     } 
 
-    if (type & 0xc0)
-    {
-        DWORD ThreadId;
-        HANDLE ThreadHandle;
-        thread_struct *info = HeapAlloc( GetProcessHeap(), 0, sizeof(*info) );
-
-        msiobj_addref( &package->hdr );
-        info->package = package;
-        info->target = dupstrW(target);
-        info->source = dupstrW(tmp_file);
-        TRACE("Start Asynchronous execution of dll\n");
-        ThreadHandle = CreateThread(NULL,0,DllThread,(LPVOID)info,0,&ThreadId);
-        CloseHandle(ThreadHandle);
-        /* FIXME: release the package if the CreateThread fails */
-        return ERROR_SUCCESS;
-    }
- 
-    DLL = LoadLibraryW(tmp_file);
-    if (DLL)
-    {
-        proc = strdupWtoA( target );
-        fn = (CustomEntry*)GetProcAddress(DLL,proc);
-        if (fn)
-        {
-            MSIHANDLE hPackage;
+    info = HeapAlloc( GetProcessHeap(), 0, sizeof(*info) );
+    msiobj_addref( &package->hdr );
+    info->package = package;
+    info->target = dupstrW(target);
+    info->source = dupstrW(tmp_file);
 
-            TRACE("Calling function\n");
-            hPackage = msiobj_findhandle( &package->hdr );
-            if( !hPackage )
-                ERR("Handle for object %p not found\n", package );
-            fn(hPackage);
-            msiobj_release( &package->hdr );
-        }
-        else
-            ERR("Cannot load functon\n");
+    ThreadHandle = CreateThread(NULL,0,DllThread,(LPVOID)info,0,&ThreadId);
 
-        HeapFree(GetProcessHeap(),0,proc);
-        FreeLibrary(DLL);
-    }
-    else
-        ERR("Unable to load library\n");
+    if (!(type & 0xc0))
+        WaitForSingleObject(ThreadHandle,INFINITE);
 
+    CloseHandle(ThreadHandle);
+ 
     return ERROR_SUCCESS;
 }
 


More information about the wine-patches mailing list