From 027366c3e742f8368522bbc85f1bdf1483c64721 Mon Sep 17 00:00:00 2001 From: Misha Koshelev Date: Mon, 19 Feb 2007 17:29:15 -0600 Subject: msi: Added initial JScript/VBScript support functions. --- dlls/msi/Makefile.in | 1 dlls/msi/custom.c | 217 ++++++++++++++++++++++++++++++++++++++++++++++++++ dlls/msi/msipriv.h | 1 3 files changed, 219 insertions(+), 0 deletions(-) diff --git a/dlls/msi/Makefile.in b/dlls/msi/Makefile.in index 5fb0941..3f6fd87 100644 --- a/dlls/msi/Makefile.in +++ b/dlls/msi/Makefile.in @@ -37,6 +37,7 @@ C_SRCS = \ record.c \ registry.c \ regsvr.c \ + script.c \ select.c \ source.c \ string.c \ diff --git a/dlls/msi/custom.c b/dlls/msi/custom.c index ba5c825..8b5401e 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( info->package, 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), &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), &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 b01bb27..b00dc11 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(MSIPACKAGE *package, 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