Mike McCormack : msi: Store dll based custom actions in a separate
list.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Feb 12 09:24:03 CST 2007
Module: wine
Branch: master
Commit: 63e554994a8c6cabf13751d0e1f0f686fcd61bd3
URL: http://source.winehq.org/git/wine.git/?a=commit;h=63e554994a8c6cabf13751d0e1f0f686fcd61bd3
Author: Mike McCormack <mike at codeweavers.com>
Date: Mon Feb 12 11:31:41 2007 +0900
msi: Store dll based custom actions in a separate list.
---
dlls/msi/custom.c | 179 +++++++++++++++++++++++++++++----------------------
dlls/msi/msipriv.h | 1 +
dlls/msi/package.c | 1 +
3 files changed, 104 insertions(+), 77 deletions(-)
diff --git a/dlls/msi/custom.c b/dlls/msi/custom.c
index 4cb21fd..cca77b6 100644
--- a/dlls/msi/custom.c
+++ b/dlls/msi/custom.c
@@ -59,6 +59,7 @@ static UINT HANDLE_CustomType50(MSIPACKA
static UINT HANDLE_CustomType34(MSIPACKAGE *package, LPCWSTR source,
LPCWSTR target, const INT type, LPCWSTR action);
+typedef UINT (WINAPI *MsiCustomActionEntryPoint)( MSIHANDLE );
static BOOL check_execution_scheduling_options(MSIPACKAGE *package, LPCWSTR action, UINT options)
{
@@ -396,125 +397,143 @@ static UINT wait_process_handle(MSIPACKA
return rc;
}
-static UINT wait_thread_handle(MSIPACKAGE* package, UINT type,
- HANDLE ThreadHandle, LPCWSTR name)
+typedef struct _msi_custom_action_info {
+ struct list entry;
+ MSIPACKAGE *package;
+ LPWSTR dllname;
+ LPWSTR function;
+ HANDLE handle;
+ LPWSTR action;
+ INT type;
+} msi_custom_action_info;
+
+static void free_custom_action_data( msi_custom_action_info *info )
+{
+ list_remove( &info->entry );
+ if (info->handle)
+ CloseHandle( info->handle );
+ msi_free( info->action );
+ msi_free( info->dllname );
+ msi_free( info->function );
+ msiobj_release( &info->package->hdr );
+ msi_free( info );
+}
+
+static UINT wait_thread_handle( msi_custom_action_info *info )
{
UINT rc = ERROR_SUCCESS;
- if (!(type & msidbCustomActionTypeAsync))
+ if (!(info->type & msidbCustomActionTypeAsync))
{
- TRACE("waiting for %s\n", debugstr_w(name));
+ TRACE("waiting for %s\n", debugstr_w( info->action ));
- msi_dialog_check_messages(ThreadHandle);
+ msi_dialog_check_messages( info->handle );
- if (!(type & msidbCustomActionTypeContinue))
- rc = custom_get_thread_return(ThreadHandle);
+ if (!(info->type & msidbCustomActionTypeContinue))
+ rc = custom_get_thread_return( info->handle );
- CloseHandle(ThreadHandle);
+ free_custom_action_data( info );
}
else
{
- TRACE("%s running in background\n", debugstr_w(name));
+ TRACE("%s running in background\n", debugstr_w( info->action ));
- if (!(type & msidbCustomActionTypeContinue))
- file_running_action(package, ThreadHandle, FALSE, name);
- else
- CloseHandle(ThreadHandle);
+ if (info->type & msidbCustomActionTypeContinue)
+ free_custom_action_data( info );
}
return rc;
}
-typedef UINT __stdcall CustomEntry(MSIHANDLE);
-
-typedef struct
-{
- MSIPACKAGE *package;
- WCHAR *target;
- WCHAR *source;
-} thread_struct;
-
-static DWORD WINAPI ACTION_CallDllFunction(thread_struct *stuff)
+static DWORD WINAPI ACTION_CallDllFunction( msi_custom_action_info *info )
{
+ MsiCustomActionEntryPoint fn;
+ MSIHANDLE hPackage;
HANDLE hModule;
LPSTR proc;
- CustomEntry *fn;
- DWORD rc = ERROR_SUCCESS;
+ UINT r = ERROR_FUNCTION_FAILED;
- TRACE("calling function (%s, %s)\n", debugstr_w(stuff->source),
- debugstr_w(stuff->target));
+ TRACE("%s %s\n", debugstr_w( info->dllname ), debugstr_w( info->function ) );
- hModule = LoadLibraryW(stuff->source);
- if (hModule)
+ hModule = LoadLibraryW( info->dllname );
+ if (!hModule)
{
- proc = strdupWtoA( stuff->target );
- fn = (CustomEntry*)GetProcAddress(hModule,proc);
- if (fn)
- {
- MSIHANDLE hPackage;
- MSIPACKAGE *package = stuff->package;
+ ERR("failed to load dll %s\n", debugstr_w( info->dllname ) );
+ return r;
+ }
- TRACE("Calling function %s\n", proc);
- hPackage = alloc_msihandle( &package->hdr );
- if (hPackage)
- {
- rc = fn( hPackage );
- MsiCloseHandle( hPackage );
- }
- else
- ERR("Handle for object %p not found\n", package );
+ proc = strdupWtoA( info->function );
+ fn = (MsiCustomActionEntryPoint) GetProcAddress( hModule, proc );
+ msi_free( proc );
+ if (fn)
+ {
+ hPackage = alloc_msihandle( &info->package->hdr );
+ if (hPackage)
+ {
+ TRACE("calling %s\n", debugstr_w( info->function ) );
+ r = fn( hPackage );
+ MsiCloseHandle( hPackage );
}
else
- ERR("failed to resolve functon %s\n", debugstr_a(proc));
-
- msi_free(proc);
- FreeLibrary(hModule);
+ ERR("failed to create handle for %p\n", info->package );
}
else
- ERR("failed to load dll %s\n", debugstr_w(stuff->source));
- msiobj_release( &stuff->package->hdr );
- msi_free(stuff->source);
- msi_free(stuff->target);
- msi_free(stuff);
- return rc;
+ ERR("GetProcAddress(%s) failed\n", debugstr_w( info->function ) );
+
+ FreeLibrary(hModule);
+
+ return r;
}
-static DWORD WINAPI DllThread(LPVOID info)
+static DWORD WINAPI DllThread( LPVOID arg )
{
- thread_struct *stuff;
+ msi_custom_action_info *info = arg;
DWORD rc = 0;
- TRACE("MSI Thread (%x) started for custom action\n", GetCurrentThreadId());
+ TRACE("custom action (%x) started\n", GetCurrentThreadId() );
- stuff = (thread_struct*)info;
- rc = ACTION_CallDllFunction(stuff);
+ rc = ACTION_CallDllFunction( info );
+
+ TRACE("custom action (%x) returned %i\n", GetCurrentThreadId(), rc );
- TRACE("MSI Thread (%x) finished (rc %i)\n",GetCurrentThreadId(), rc);
- /* close all handles for this thread */
MsiCloseAllHandles();
return rc;
}
-static HANDLE do_msidbCustomActionTypeDll(MSIPACKAGE *package, LPCWSTR dll, LPCWSTR target)
+static msi_custom_action_info *do_msidbCustomActionTypeDll(
+ MSIPACKAGE *package, INT type, LPCWSTR dllname, LPCWSTR function, LPCWSTR action )
{
- thread_struct *info;
+ msi_custom_action_info *info;
+
+ info = msi_alloc( sizeof *info );
+ if (!info)
+ return NULL;
- info = msi_alloc( sizeof(*info) );
msiobj_addref( &package->hdr );
info->package = package;
- info->target = strdupW(target);
- info->source = strdupW(dll);
+ info->type = type;
+ info->function = strdupW( function );
+ info->dllname = strdupW( dllname );
+ info->action = strdupW( action );
+ list_add_tail( &package->pending_custom_actions, &info->entry );
+
+ info->handle = CreateThread( NULL, 0, DllThread, info, 0, NULL );
+ if (!info->handle)
+ {
+ free_custom_action_data( info );
+ return NULL;
+ }
- return CreateThread(NULL, 0, DllThread, info, 0, NULL);
+ return info;
}
static UINT HANDLE_CustomType1(MSIPACKAGE *package, LPCWSTR source,
LPCWSTR target, const INT type, LPCWSTR action)
{
+ msi_custom_action_info *info;
WCHAR tmp_file[MAX_PATH];
- UINT r = ERROR_SUCCESS;
- HANDLE ThreadHandle;
+ UINT r;
r = store_binary_to_temp(package, source, tmp_file);
if (r != ERROR_SUCCESS)
@@ -529,11 +548,9 @@ static UINT HANDLE_CustomType1(MSIPACKAG
strcatW(tmp_file,dot);
}
- ThreadHandle = do_msidbCustomActionTypeDll( package, tmp_file, target );
-
- r = wait_thread_handle( package, type, ThreadHandle, action );
+ info = do_msidbCustomActionTypeDll( package, type, tmp_file, target, action );
- return r;
+ return wait_thread_handle( info );
}
static UINT HANDLE_CustomType2(MSIPACKAGE *package, LPCWSTR source,
@@ -594,7 +611,7 @@ static UINT HANDLE_CustomType2(MSIPACKAG
static UINT HANDLE_CustomType17(MSIPACKAGE *package, LPCWSTR source,
LPCWSTR target, const INT type, LPCWSTR action)
{
- HANDLE hThread;
+ msi_custom_action_info *info;
MSIFILE *file;
TRACE("%s %s\n", debugstr_w(source), debugstr_w(target));
@@ -606,9 +623,9 @@ static UINT HANDLE_CustomType17(MSIPACKA
return ERROR_FUNCTION_FAILED;
}
- hThread = do_msidbCustomActionTypeDll( package, file->TargetPath, target );
+ info = do_msidbCustomActionTypeDll( package, type, file->TargetPath, target, action );
- return wait_thread_handle(package, type, hThread, action);
+ return wait_thread_handle( info );
}
static UINT HANDLE_CustomType18(MSIPACKAGE *package, LPCWSTR source,
@@ -735,7 +752,6 @@ static UINT HANDLE_CustomType50(MSIPACKA
rc = CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL,
c_collen, &si, &info);
-
if ( !rc )
{
ERR("Unable to execute command %s\n", debugstr_w(cmd));
@@ -806,4 +822,13 @@ void ACTION_FinishCustomActions(MSIPACKA
msi_free( action->name );
msi_free( action );
}
+
+ while ((item = list_head( &package->pending_custom_actions )))
+ {
+ msi_custom_action_info *info;
+
+ info = LIST_ENTRY( item, msi_custom_action_info, entry );
+ msi_dialog_check_messages( info->handle );
+ free_custom_action_data( info );
+ }
}
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index b01bb27..09a3e55 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -230,6 +230,7 @@ typedef struct tagMSIPACKAGE
struct tagMSISCRIPT *script;
struct list RunningActions;
+ struct list pending_custom_actions;
LPWSTR BaseURL;
LPWSTR PackagePath;
diff --git a/dlls/msi/package.c b/dlls/msi/package.c
index b78910d..f0163c4 100644
--- a/dlls/msi/package.c
+++ b/dlls/msi/package.c
@@ -490,6 +490,7 @@ static MSIPACKAGE *msi_alloc_package( vo
list_init( &package->extensions );
list_init( &package->progids );
list_init( &package->RunningActions );
+ list_init( &package->pending_custom_actions );
for (i=0; i<PROPERTY_HASH_SIZE; i++)
list_init( &package->props[i] );
More information about the wine-cvs
mailing list