From ddcb832a5526ae5116d3b1fbdc508907704e859b Mon Sep 17 00:00:00 2001 From: Misha Koshelev 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