msi: Add handlers for JScript/VBScript actions that call one
script function. [PATCH 2/3]
Misha Koshelev
mk144210 at bcm.tmc.edu
Sat Feb 24 00:29:19 CST 2007
The previous patch just contained the complete msiserver.idl. This patch
and the next one must be applied together before msi can be compiled. I
simply separated the two patches into one that modifies existing files
(this one), and one that adds new files (next one).
This specific patch implements all 4 (well 8, but each has one for
JScript and one for VBScript) script custom action types and a calling
framework that mimics the one currently used for DLL functions. All
actual script implementation is left (for the next patch) in the
call_script function.
Changelog:
* msi: Add handlers for JScript/VBScript actions that call one script
function.
-------------- next part --------------
From ddcb832a5526ae5116d3b1fbdc508907704e859b Mon Sep 17 00:00:00 2001
From: Misha Koshelev <mk144210 at bcm.tmc.edu>
Date: Fri, 23 Feb 2007 20:03:50 -0600
Subject: msi: Add handles for JScript/VBScript actions that call one script function.
---
dlls/msi/custom.c | 217 ++++++++++++++++++++++++++++++++++++++++++++++++++++
dlls/msi/msipriv.h | 1
2 files changed, 218 insertions(+), 0 deletions(-)
diff --git a/dlls/msi/custom.c b/dlls/msi/custom.c
index ba5c825..2da7e97 100644
--- a/dlls/msi/custom.c
+++ b/dlls/msi/custom.c
@@ -58,6 +58,14 @@ static UINT HANDLE_CustomType50(MSIPACKA
LPCWSTR target, const INT type, LPCWSTR action);
static UINT HANDLE_CustomType34(MSIPACKAGE *package, LPCWSTR source,
LPCWSTR target, const INT type, LPCWSTR action);
+static UINT HANDLE_CustomType37_38(MSIPACKAGE *package, LPCWSTR source,
+ LPCWSTR target, const INT type, LPCWSTR action);
+static UINT HANDLE_CustomType5_6(MSIPACKAGE *package, LPCWSTR source,
+ LPCWSTR target, const INT type, LPCWSTR action);
+static UINT HANDLE_CustomType21_22(MSIPACKAGE *package, LPCWSTR source,
+ LPCWSTR target, const INT type, LPCWSTR action);
+static UINT HANDLE_CustomType53_54(MSIPACKAGE *package, LPCWSTR source,
+ LPCWSTR target, const INT type, LPCWSTR action);
typedef UINT (WINAPI *MsiCustomActionEntryPoint)( MSIHANDLE );
@@ -266,6 +274,22 @@ UINT ACTION_CustomAction(MSIPACKAGE *pac
rc = MSI_SetPropertyW(package,source,deformated);
msi_free(deformated);
break;
+ case 37: /* JScript/VBScript text stored in target column. */
+ case 38:
+ rc = HANDLE_CustomType37_38(package,source,target,type,action);
+ break;
+ case 5:
+ case 6: /* JScript/VBScript file stored in a Binary table stream. */
+ rc = HANDLE_CustomType5_6(package,source,target,type,action);
+ break;
+ case 21: /* JScript/VBScript file installed with the product. */
+ case 22:
+ rc = HANDLE_CustomType21_22(package,source,target,type,action);
+ break;
+ case 53: /* JScript/VBScript text specified by a property value. */
+ case 54:
+ rc = HANDLE_CustomType53_54(package,source,target,type,action);
+ break;
default:
FIXME("UNHANDLED ACTION TYPE %i (%s %s)\n",
type & CUSTOM_ACTION_TYPE_MASK, debugstr_w(source),
@@ -855,6 +879,199 @@ static UINT HANDLE_CustomType34(MSIPACKA
return wait_process_handle(package, type, info.hProcess, action);
}
+static DWORD WINAPI ACTION_CallScript( const LPGUID guid )
+{
+ msi_custom_action_info *info;
+ MSIHANDLE hPackage;
+ UINT r = ERROR_FUNCTION_FAILED;
+
+ info = find_action_by_guid( guid );
+ if (!info)
+ {
+ ERR("failed to find action %s\n", debugstr_guid( guid) );
+ return r;
+ }
+
+ TRACE("%s %s\n", debugstr_w( info->dllname ), debugstr_w( info->function ) );
+
+ hPackage = alloc_msihandle( &info->package->hdr );
+ if (hPackage)
+ {
+ TRACE("calling %s\n", debugstr_w( info->function ) );
+ r = call_script( hPackage, info->type, info->dllname, info->function, info->action);
+ MsiCloseHandle( hPackage );
+ }
+ else
+ ERR("failed to create handle for %p\n", info->package );
+
+ return r;
+}
+
+static DWORD WINAPI ScriptThread( LPVOID arg )
+{
+ LPGUID guid = arg;
+ DWORD rc = 0;
+
+ TRACE("custom action (%x) started\n", GetCurrentThreadId() );
+
+ rc = ACTION_CallScript( guid );
+
+ TRACE("custom action (%x) returned %i\n", GetCurrentThreadId(), rc );
+
+ MsiCloseAllHandles();
+ return rc;
+}
+
+static msi_custom_action_info *do_msidbCustomActionTypeScript(
+ MSIPACKAGE *package, INT type, LPCWSTR dllname, LPCWSTR function, LPCWSTR action )
+{
+ msi_custom_action_info *info;
+
+ info = msi_alloc( sizeof *info );
+ if (!info)
+ return NULL;
+
+ msiobj_addref( &package->hdr );
+ info->package = package;
+ info->type = type;
+ info->function = strdupW( function );
+ info->dllname = strdupW( dllname );
+ info->action = strdupW( action );
+ CoCreateGuid( &info->guid );
+
+ EnterCriticalSection( &msi_custom_action_cs );
+ list_add_tail( &msi_pending_custom_actions, &info->entry );
+ LeaveCriticalSection( &msi_custom_action_cs );
+
+ info->handle = CreateThread( NULL, 0, ScriptThread, &info->guid, 0, NULL );
+ if (!info->handle)
+ {
+ free_custom_action_data( info );
+ return NULL;
+ }
+
+ return info;
+}
+
+static UINT HANDLE_CustomType37_38(MSIPACKAGE *package, LPCWSTR source,
+ LPCWSTR target, const INT type, LPCWSTR action)
+{
+ msi_custom_action_info *info;
+ WCHAR tmp_file[MAX_PATH];
+ WCHAR fmt[MAX_PATH];
+ static const WCHAR f1[] = {'m','s','i',0};
+ HANDLE file;
+ DWORD sz, write;
+
+ TRACE("%s %s\n", debugstr_w(source), debugstr_w(target));
+
+ if (MSI_GetPropertyW(package, cszTempFolder, fmt, &sz) != ERROR_SUCCESS)
+ GetTempPathW(MAX_PATH, fmt);
+
+ if (GetTempFileNameW(fmt, f1, 0, tmp_file) == 0)
+ {
+ TRACE("Unable to create file\n");
+ return ERROR_FUNCTION_FAILED;
+ }
+ track_tempfile(package, tmp_file);
+
+ /* Write out script from target field to file (a little roundabout but makes script code simpler) */
+ file = CreateFileW(tmp_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (file == INVALID_HANDLE_VALUE)
+ return ERROR_FUNCTION_FAILED;
+ else
+ {
+ WriteFile(file, target, sizeof(WCHAR)*(strlenW(target)+1), &write, NULL);
+ CloseHandle(file);
+ }
+
+ info = do_msidbCustomActionTypeScript( package, type, tmp_file, NULL, action );
+
+ return wait_thread_handle( info );
+}
+
+static UINT HANDLE_CustomType5_6(MSIPACKAGE *package, LPCWSTR source,
+ LPCWSTR target, const INT type, LPCWSTR action)
+{
+ msi_custom_action_info *info;
+ WCHAR tmp_file[MAX_PATH];
+ UINT r;
+
+ TRACE("%s %s\n", debugstr_w(source), debugstr_w(target));
+
+ r = store_binary_to_temp(package, source, tmp_file);
+ if (r != ERROR_SUCCESS)
+ return r;
+
+ info = do_msidbCustomActionTypeScript( package, type, tmp_file, target, action );
+
+ return wait_thread_handle( info );
+}
+
+static UINT HANDLE_CustomType21_22(MSIPACKAGE *package, LPCWSTR source,
+ LPCWSTR target, const INT type, LPCWSTR action)
+{
+ msi_custom_action_info *info;
+ MSIFILE *file;
+
+ TRACE("%s %s\n", debugstr_w(source), debugstr_w(target));
+
+ file = get_loaded_file(package,source);
+ if (!file)
+ {
+ ERR("invalid file key %s\n", debugstr_w(source));
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ info = do_msidbCustomActionTypeScript( package, type, file->TargetPath, target, action );
+
+ return wait_thread_handle( info );
+}
+
+static UINT HANDLE_CustomType53_54(MSIPACKAGE *package, LPCWSTR source,
+ LPCWSTR target, const INT type, LPCWSTR action)
+{
+ msi_custom_action_info *info;
+ WCHAR *prop;
+ WCHAR tmp_file[MAX_PATH];
+ WCHAR fmt[MAX_PATH];
+ static const WCHAR f1[] = {'m','s','i',0};
+ HANDLE file;
+ DWORD sz, write;
+
+ TRACE("%s %s\n", debugstr_w(source), debugstr_w(target));
+
+ prop = msi_dup_property(package,source);
+ if (!prop)
+ return ERROR_SUCCESS;
+
+ if (MSI_GetPropertyW(package, cszTempFolder, fmt, &sz) != ERROR_SUCCESS)
+ GetTempPathW(MAX_PATH, fmt);
+
+ if (GetTempFileNameW(fmt, f1, 0, tmp_file) == 0)
+ {
+ TRACE("Unable to create file\n");
+ return ERROR_FUNCTION_FAILED;
+ }
+ track_tempfile(package, tmp_file);
+
+ /* Write out script from target field to file (a little roundabout but makes script code simpler) */
+ file = CreateFileW(tmp_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (file == INVALID_HANDLE_VALUE)
+ return ERROR_FUNCTION_FAILED;
+ else
+ {
+ WriteFile(file, prop, sizeof(WCHAR)*(strlenW(prop)+1), &write, NULL);
+ CloseHandle(file);
+ }
+
+ info = do_msidbCustomActionTypeScript( package, type, tmp_file, NULL, action );
+
+ return wait_thread_handle( info );
+}
+
void ACTION_FinishCustomActions(MSIPACKAGE* package)
{
struct list *item;
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 971f71e..fb43b05 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -750,6 +750,7 @@ extern UINT ACTION_RegisterMIMEInfo(MSIP
extern UINT ACTION_RegisterFonts(MSIPACKAGE *package);
/* Helpers */
+extern DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR filename, LPCWSTR function, LPCWSTR action);
extern DWORD deformat_string(MSIPACKAGE *package, LPCWSTR ptr, WCHAR** data );
extern LPWSTR msi_dup_record_field(MSIRECORD *row, INT index);
extern LPWSTR msi_dup_property(MSIPACKAGE *package, LPCWSTR prop);
--
1.4.1
More information about the wine-patches
mailing list