Alexandre Julliard : setupapi: Delay freeing registered dlls until they have all been processed.

Alexandre Julliard julliard at winehq.org
Fri Aug 26 10:40:52 CDT 2011


Module: wine
Branch: master
Commit: a192b707f2d102374771ed90e6c94ea40e79a08a
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=a192b707f2d102374771ed90e6c94ea40e79a08a

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Aug 26 13:12:26 2011 +0200

setupapi: Delay freeing registered dlls until they have all been processed.

---

 dlls/setupapi/install.c |   49 ++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 40 insertions(+), 9 deletions(-)

diff --git a/dlls/setupapi/install.c b/dlls/setupapi/install.c
index 8f52a58..6ecc288 100644
--- a/dlls/setupapi/install.c
+++ b/dlls/setupapi/install.c
@@ -63,6 +63,9 @@ struct register_dll_info
     PSP_FILE_CALLBACK_W callback;
     PVOID               callback_context;
     BOOL                unregister;
+    int                 modules_size;
+    int                 modules_count;
+    HMODULE            *modules;
 };
 
 typedef BOOL (*iterate_fields_func)( HINF hinf, PCWSTR field, void *arg );
@@ -492,7 +495,7 @@ static BOOL registry_callback( HINF hinf, PCWSTR field, void *arg )
  *
  * Register or unregister a dll.
  */
-static BOOL do_register_dll( const struct register_dll_info *info, const WCHAR *path,
+static BOOL do_register_dll( struct register_dll_info *info, const WCHAR *path,
                              INT flags, INT timeout, const WCHAR *args )
 {
     HMODULE module;
@@ -616,7 +619,23 @@ static BOOL do_register_dll( const struct register_dll_info *info, const WCHAR *
     }
 
 done:
-    if (module) FreeLibrary( module );
+    if (module)
+    {
+        if (info->modules_count >= info->modules_size)
+        {
+            int new_size = max( 32, info->modules_size * 2 );
+            HMODULE *new = info->modules ?
+                HeapReAlloc( GetProcessHeap(), 0, info->modules, new_size * sizeof(*new) ) :
+                HeapAlloc( GetProcessHeap(), 0, new_size * sizeof(*new) );
+            if (new)
+            {
+                info->modules_size = new_size;
+                info->modules = new;
+            }
+        }
+        if (info->modules_count < info->modules_size) info->modules[info->modules_count++] = module;
+        else FreeLibrary( module );
+    }
     if (info->callback) info->callback( info->callback_context, SPFILENOTIFY_ENDREGISTRATION,
                                         (UINT_PTR)&status, !info->unregister );
     return TRUE;
@@ -1047,11 +1066,13 @@ BOOL WINAPI SetupInstallFromInfSectionW( HWND owner, HINF hinf, PCWSTR section,
                                          PSP_FILE_CALLBACK_W callback, PVOID context,
                                          HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data )
 {
+    BOOL ret;
+    int i;
+
     if (flags & SPINST_FILES)
     {
         struct files_callback_info info;
         HSPFILEQ queue;
-        BOOL ret;
 
         if (!(queue = SetupOpenFileQueue())) return FALSE;
         info.queue      = queue;
@@ -1086,7 +1107,10 @@ BOOL WINAPI SetupInstallFromInfSectionW( HWND owner, HINF hinf, PCWSTR section,
     {
         struct register_dll_info info;
 
-        info.unregister = FALSE;
+        info.unregister    = FALSE;
+        info.modules_size  = 0;
+        info.modules_count = 0;
+        info.modules       = NULL;
         if (flags & SPINST_REGISTERCALLBACKAWARE)
         {
             info.callback         = callback;
@@ -1099,14 +1123,19 @@ BOOL WINAPI SetupInstallFromInfSectionW( HWND owner, HINF hinf, PCWSTR section,
         else
             return FALSE;
 
-        if (!iterate_section_fields( hinf, section, RegisterDlls, register_dlls_callback, &info ))
-            return FALSE;
+        ret = iterate_section_fields( hinf, section, RegisterDlls, register_dlls_callback, &info );
+        for (i = 0; i < info.modules_count; i++) FreeLibrary( info.modules[i] );
+        HeapFree( GetProcessHeap(), 0, info.modules );
+        if (!ret) return FALSE;
     }
     if (flags & SPINST_UNREGSVR)
     {
         struct register_dll_info info;
 
-        info.unregister = TRUE;
+        info.unregister    = TRUE;
+        info.modules_size  = 0;
+        info.modules_count = 0;
+        info.modules       = NULL;
         if (flags & SPINST_REGISTERCALLBACKAWARE)
         {
             info.callback         = callback;
@@ -1114,8 +1143,10 @@ BOOL WINAPI SetupInstallFromInfSectionW( HWND owner, HINF hinf, PCWSTR section,
         }
         else info.callback = NULL;
 
-        if (!iterate_section_fields( hinf, section, UnregisterDlls, register_dlls_callback, &info ))
-            return FALSE;
+        ret = iterate_section_fields( hinf, section, UnregisterDlls, register_dlls_callback, &info );
+        for (i = 0; i < info.modules_count; i++) FreeLibrary( info.modules[i] );
+        HeapFree( GetProcessHeap(), 0, info.modules );
+        if (!ret) return FALSE;
     }
     if (flags & SPINST_REGISTRY)
     {




More information about the wine-cvs mailing list