From bfde4dd7c028bf9e708d12b92a8e8439cb3358f1 Mon Sep 17 00:00:00 2001 From: Misha Koshelev Date: Sun, 25 Feb 2007 22:19:22 -0600 Subject: msi: Added handlers for JScript/VBScript actions that call one script function. --- dlls/msi/custom.c | 252 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 252 insertions(+), 0 deletions(-) diff --git a/dlls/msi/custom.c b/dlls/msi/custom.c index ba5c825..7cbbf40 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,234 @@ 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; + } + + FIXME("function %s, script %s\n", debugstr_w( info->function ), debugstr_w( info->dllname ) ); + + hPackage = alloc_msihandle( &info->package->hdr ); + if (hPackage) + { + r = S_OK; + 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 script, 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( script ); + 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; + + TRACE("%s %s\n", debugstr_w(source), debugstr_w(target)); + + info = do_msidbCustomActionTypeScript( package, type, target, NULL, action ); + + return wait_thread_handle( info ); +} + +static UINT HANDLE_CustomType5_6(MSIPACKAGE *package, LPCWSTR source, + LPCWSTR target, const INT type, LPCWSTR action) +{ + static const WCHAR query[] = { + 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + '`','B','i' ,'n','a','r','y','`',' ','W','H','E','R','E',' ', + '`','N','a','m','e','`',' ','=',' ','\'','%','s','\'',0}; + MSIRECORD *row = 0; + msi_custom_action_info *info; + CHAR *buffer = NULL; + WCHAR *bufferw = NULL; + DWORD sz = 0, szw = 0; + UINT r; + + TRACE("%s %s\n", debugstr_w(source), debugstr_w(target)); + + row = MSI_QueryGetRecord(package->db, query, source); + if (!row) + return ERROR_FUNCTION_FAILED; + + r = MSI_RecordReadStream(row, 2, NULL, &sz); + if (r != ERROR_SUCCESS) + return r; + + buffer = msi_alloc(sizeof(CHAR)*(sz+1)); + if (!buffer) + return ERROR_FUNCTION_FAILED; + + r = MSI_RecordReadStream(row, 2, buffer, &sz); + if (r != ERROR_SUCCESS) + { + msi_free(buffer); + return r; + } + + buffer[sz] = 0; + szw = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, buffer, -1, bufferw, 0); + bufferw = msi_alloc(sizeof(WCHAR)*szw); + if (!szw) + { + msi_free(bufferw); + return ERROR_FUNCTION_FAILED; + } + + r = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, buffer, -1, bufferw, szw); + msi_free(buffer); + if (!r) + { + msi_free(bufferw); + return ERROR_FUNCTION_FAILED; + } + + info = do_msidbCustomActionTypeScript( package, type, bufferw, target, action ); + msi_free(bufferw); + 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; + HANDLE hFile; + DWORD sz, szw, szHighWord = 0, read; + CHAR *buffer=NULL; + WCHAR *bufferw=NULL; + BOOL bRet; + UINT r; + + 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; + } + + hFile = CreateFileW(file->TargetPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) + return ERROR_FUNCTION_FAILED; + + sz = GetFileSize(hFile, &szHighWord); + if (sz == INVALID_FILE_SIZE || szHighWord != 0) + { + CloseHandle(hFile); + return ERROR_FUNCTION_FAILED; + } + + buffer = msi_alloc(sizeof(CHAR)*(sz+1)); + if (!buffer) + { + CloseHandle(hFile); + return ERROR_FUNCTION_FAILED; + } + + bRet = ReadFile(hFile, (LPVOID)buffer, sz, &read, NULL); + CloseHandle(hFile); + if (!bRet); + { + msi_free(buffer); + return ERROR_FUNCTION_FAILED; + } + + buffer[read] = 0; + szw = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, buffer, -1, bufferw, 0); + bufferw = msi_alloc(sizeof(WCHAR)*szw); + if (!szw) + { + msi_free(bufferw); + return ERROR_FUNCTION_FAILED; + } + + r = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, buffer, -1, bufferw, szw); + msi_free(buffer); + if (!r) + { + msi_free(bufferw); + return ERROR_FUNCTION_FAILED; + } + + info = do_msidbCustomActionTypeScript( package, type, bufferw, target, action ); + msi_free(bufferw); + 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; + + TRACE("%s %s\n", debugstr_w(source), debugstr_w(target)); + + prop = msi_dup_property(package,source); + if (!prop) + return ERROR_SUCCESS; + + info = do_msidbCustomActionTypeScript( package, type, prop, NULL, action ); + msi_free(prop); + return wait_thread_handle( info ); +} + void ACTION_FinishCustomActions(MSIPACKAGE* package) { struct list *item; -- 1.4.1