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