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