}
else if (type & msidbCustomActionTypeRollback)
{
- FIXME("Deferring rollback only action... rollbacks not supported yet\n");
+ FIXME("Deferring rollback only action\n");
schedule_action(package, ROLLBACK_SCRIPT, deferred);
}
else
msi_free(actiondata);
}
+ if (type & msidbCustomActionTypeRollback)
+ {
+ FIXME("Rollbacks not supported yet\n");
+ rc = ERROR_SUCCESS;
+ goto end;
+ }
}
else if (!check_execution_scheduling_options(package,action,type))
{
return rc;
}
-
-static UINT store_binary_to_temp(MSIPACKAGE *package, LPCWSTR source,
- LPWSTR tmp_file)
+static MSIBINARY *create_temp_binary( MSIPACKAGE *package, LPCWSTR source, BOOL dll )
{
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;
+ MSIRECORD *row;
+ MSIBINARY *binary;
HANDLE file;
CHAR buffer[1024];
- WCHAR fmt[MAX_PATH];
- DWORD sz = MAX_PATH;
+ WCHAR fmt[MAX_PATH], tmpfile[MAX_PATH];
+ DWORD sz = MAX_PATH, write;
UINT r;
if (msi_get_property(package->db, cszTempFolder, fmt, &sz) != ERROR_SUCCESS)
GetTempPathW(MAX_PATH, fmt);
- if (GetTempFileNameW(fmt, szMsi, 0, tmp_file) == 0)
+ if (!GetTempFileNameW( fmt, szMsi, 0, tmpfile ))
{
- TRACE("Unable to create file\n");
- return ERROR_FUNCTION_FAILED;
+ TRACE("unable to create temp file %s (%u)\n", debugstr_w(tmpfile), GetLastError());
+ return NULL;
}
- track_tempfile(package, tmp_file);
row = MSI_QueryGetRecord(package->db, query, source);
if (!row)
- return ERROR_FUNCTION_FAILED;
+ return NULL;
- /* write out the file */
- file = CreateFileW(tmp_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, NULL);
+ if (!(binary = msi_alloc_zero( sizeof(MSIBINARY) )))
+ {
+ msiobj_release( &row->hdr );
+ return NULL;
+ }
+ file = CreateFileW( tmpfile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if (file == INVALID_HANDLE_VALUE)
- r = ERROR_FUNCTION_FAILED;
- else
{
- do
+ msiobj_release( &row->hdr );
+ msi_free( binary );
+ return NULL;
+ }
+ do
+ {
+ sz = sizeof(buffer);
+ r = MSI_RecordReadStream( row, 2, buffer, &sz );
+ if (r != ERROR_SUCCESS)
{
- DWORD write;
- sz = sizeof buffer;
- r = MSI_RecordReadStream(row, 2, buffer, &sz);
- if (r != ERROR_SUCCESS)
- {
- ERR("Failed to get stream\n");
- break;
- }
- WriteFile(file, buffer, sz, &write, NULL);
- } while (sz == sizeof buffer);
- CloseHandle(file);
+ ERR("Failed to get stream\n");
+ break;
+ }
+ WriteFile( file, buffer, sz, &write, NULL );
+ } while (sz == sizeof buffer);
+
+ CloseHandle( file );
+ msiobj_release( &row->hdr );
+ if (r != ERROR_SUCCESS)
+ {
+ DeleteFileW( tmpfile );
+ msi_free( binary );
+ return NULL;
}
- msiobj_release(&row->hdr);
+ /* keep a reference to prevent the dll from being unloaded */
+ if (dll && !(binary->module = LoadLibraryW( tmpfile )))
+ {
+ WARN( "failed to load dll %s (%u)\n", debugstr_w( tmpfile ), GetLastError() );
+ }
+ binary->source = strdupW( source );
+ binary->tmpfile = strdupW( tmpfile );
+ list_add_tail( &package->binaries, &binary->entry );
+ return binary;
+}
- return r;
+static MSIBINARY *get_temp_binary( MSIPACKAGE *package, LPCWSTR source, BOOL dll )
+{
+ MSIBINARY *binary;
+
+ LIST_FOR_EACH_ENTRY( binary, &package->binaries, MSIBINARY, entry )
+ {
+ if (!strcmpW( binary->source, source ))
+ return binary;
+ }
+
+ return create_temp_binary( package, source, dll );
}
static void file_running_action(MSIPACKAGE* package, HANDLE Handle,
if( !GetEnvironmentVariableW( MsiBreak, val, MAX_PATH ))
return;
- if( lstrcmpiW( val, target ))
+ if( strcmpiW( val, target ))
return;
msg = msi_alloc( (lstrlenW(format) + 10) * sizeof(WCHAR) );
IWineMsiRemoteCustomAction *rca = NULL;
HRESULT r;
- r = DllGetClassObject( &CLSID_IWineMsiRemoteCustomAction,
+ r = DllGetClassObject( &CLSID_WineMsiRemoteCustomAction,
&IID_IClassFactory, (LPVOID *)&cf );
if (FAILED(r))
{
hModule = LoadLibraryW( dll );
if (!hModule)
{
- ERR("failed to load dll %s (%u)\n", debugstr_w( dll ), GetLastError() );
- return r;
+ WARN( "failed to load dll %s (%u)\n", debugstr_w( dll ), GetLastError() );
+ return ERROR_SUCCESS;
}
proc = strdupWtoA( function );
LPCWSTR target, const INT type, LPCWSTR action)
{
msi_custom_action_info *info;
- WCHAR tmp_file[MAX_PATH];
+ MSIBINARY *binary;
UINT r;
- r = store_binary_to_temp(package, source, tmp_file);
- if (r != ERROR_SUCCESS)
- return r;
-
- TRACE("Calling function %s from %s\n",debugstr_w(target),
- debugstr_w(tmp_file));
+ if (!(binary = get_temp_binary( package, source, TRUE )))
+ return ERROR_FUNCTION_FAILED;
- if (!strchrW(tmp_file,'.'))
- strcatW(tmp_file, szDot);
+ TRACE("Calling function %s from %s\n", debugstr_w(target), debugstr_w(binary->tmpfile));
- info = do_msidbCustomActionTypeDll( package, type, tmp_file, target, action );
+ info = do_msidbCustomActionTypeDll( package, type, binary->tmpfile, target, action );
r = wait_thread_handle( info );
release_custom_action_data( info );
static UINT HANDLE_CustomType2(MSIPACKAGE *package, LPCWSTR source,
LPCWSTR target, const INT type, LPCWSTR action)
{
- WCHAR tmp_file[MAX_PATH];
STARTUPINFOW si;
PROCESS_INFORMATION info;
BOOL rc;
WCHAR *deformated = NULL;
WCHAR *cmd;
static const WCHAR spc[] = {' ',0};
+ MSIBINARY *binary;
UINT r;
memset(&si,0,sizeof(STARTUPINFOW));
- r = store_binary_to_temp(package, source, tmp_file);
- if (r != ERROR_SUCCESS)
- return r;
+ if (!(binary = get_temp_binary( package, source, FALSE )))
+ return ERROR_FUNCTION_FAILED;
deformat_string(package,target,&deformated);
- len = strlenW(tmp_file)+2;
-
+ len = strlenW( binary->tmpfile ) + 2;
if (deformated)
len += strlenW(deformated);
cmd = msi_alloc(sizeof(WCHAR)*len);
- strcpyW(cmd,tmp_file);
+ strcpyW( cmd, binary->tmpfile );
if (deformated)
{
strcatW(cmd,spc);
strcatW(cmd,deformated);
-
msi_free(deformated);
}
memset(&si, 0, sizeof(STARTUPINFOW));
- workingdir = resolve_folder(package, source, FALSE, FALSE, TRUE, NULL);
-
+ workingdir = resolve_target_folder( package, source, FALSE, TRUE, NULL );
if (!workingdir)
return ERROR_FUNCTION_FAILED;
{
msi_custom_action_info *info;
MSIHANDLE hPackage;
- UINT r = ERROR_FUNCTION_FAILED;
+ UINT r;
info = find_action_by_guid( guid );
if (!info)
{
ERR("failed to find action %s\n", debugstr_guid( guid) );
- return r;
+ return ERROR_FUNCTION_FAILED;
}
TRACE("function %s, script %s\n", debugstr_w( info->target ), debugstr_w( info->source ) );
if (hPackage)
{
r = call_script( hPackage, info->type, info->source, info->target, info->action );
+ TRACE("script returned %u\n", r);
MsiCloseHandle( hPackage );
}
else
ERR("failed to create handle for %p\n", info->package );
release_custom_action_data( info );
-
return S_OK;
}
}
typedef struct _msi_custom_remote_impl {
- const IWineMsiRemoteCustomActionVtbl *lpVtbl;
+ IWineMsiRemoteCustomAction IWineMsiRemoteCustomAction_iface;
LONG refs;
} msi_custom_remote_impl;
-static inline msi_custom_remote_impl* mcr_from_IWineMsiRemoteCustomAction( IWineMsiRemoteCustomAction* iface )
+static inline msi_custom_remote_impl *impl_from_IWineMsiRemoteCustomAction( IWineMsiRemoteCustomAction *iface )
{
- return (msi_custom_remote_impl*) iface;
+ return CONTAINING_RECORD(iface, msi_custom_remote_impl, IWineMsiRemoteCustomAction_iface);
}
static HRESULT WINAPI mcr_QueryInterface( IWineMsiRemoteCustomAction *iface,
static ULONG WINAPI mcr_AddRef( IWineMsiRemoteCustomAction *iface )
{
- msi_custom_remote_impl* This = mcr_from_IWineMsiRemoteCustomAction( iface );
+ msi_custom_remote_impl* This = impl_from_IWineMsiRemoteCustomAction( iface );
return InterlockedIncrement( &This->refs );
}
static ULONG WINAPI mcr_Release( IWineMsiRemoteCustomAction *iface )
{
- msi_custom_remote_impl* This = mcr_from_IWineMsiRemoteCustomAction( iface );
+ msi_custom_remote_impl* This = impl_from_IWineMsiRemoteCustomAction( iface );
ULONG r;
r = InterlockedDecrement( &This->refs );
if (!This)
return E_OUTOFMEMORY;
- This->lpVtbl = &msi_custom_remote_vtbl;
+ This->IWineMsiRemoteCustomAction_iface.lpVtbl = &msi_custom_remote_vtbl;
This->refs = 1;
*ppObj = This;