mirror of
https://github.com/reactos/reactos.git
synced 2025-06-01 15:38:37 +00:00
[WINESYNC] msi: Add support for custom action type 7.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=44618 Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org> wine commit id 54ef6e5e3932a5ce747fca717c697b67f2bd3e24 by Hans Leidekker <hans@codeweavers.com>
This commit is contained in:
parent
be64b5c843
commit
373ffef2ef
1 changed files with 159 additions and 71 deletions
|
@ -965,13 +965,28 @@ static UINT HANDLE_CustomType19( MSIPACKAGE *package, const WCHAR *source, const
|
||||||
return ERROR_INSTALL_FAILURE;
|
return ERROR_INSTALL_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static WCHAR *build_msiexec_args( const WCHAR *filename, const WCHAR *params )
|
||||||
|
{
|
||||||
|
UINT len_filename = lstrlenW( filename ), len_params = lstrlenW( params );
|
||||||
|
UINT len = ARRAY_SIZE(L"/qb /i ") - 1;
|
||||||
|
WCHAR *ret;
|
||||||
|
|
||||||
|
if (!(ret = msi_alloc( (len + len_filename + len_params + 4) * sizeof(WCHAR) ))) return NULL;
|
||||||
|
memcpy( ret, L"/qb /i ", sizeof(L"/qb /i ") );
|
||||||
|
ret[len++] = '"';
|
||||||
|
memcpy( ret + len, filename, len_filename * sizeof(WCHAR) );
|
||||||
|
len += len_filename;
|
||||||
|
ret[len++] = '"';
|
||||||
|
ret[len++] = ' ';
|
||||||
|
lstrcpyW( ret + len, params );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static UINT HANDLE_CustomType23( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
|
static UINT HANDLE_CustomType23( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
|
||||||
INT type, const WCHAR *action )
|
INT type, const WCHAR *action )
|
||||||
{
|
{
|
||||||
static const WCHAR msiexecW[] = {'m','s','i','e','x','e','c',0};
|
WCHAR *dir, *filename, *args, *p;
|
||||||
static const WCHAR paramsW[] = {'/','q','b',' ','/','i',' '};
|
UINT len_dir, len_source = lstrlenW( source );
|
||||||
WCHAR *dir, *arg, *p;
|
|
||||||
UINT len_src, len_dir, len_tgt, len = ARRAY_SIZE( paramsW );
|
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
|
|
||||||
if (!(dir = msi_dup_property( package->db, szOriginalDatabase ))) return ERROR_OUTOFMEMORY;
|
if (!(dir = msi_dup_property( package->db, szOriginalDatabase ))) return ERROR_OUTOFMEMORY;
|
||||||
|
@ -982,33 +997,104 @@ static UINT HANDLE_CustomType23( MSIPACKAGE *package, const WCHAR *source, const
|
||||||
}
|
}
|
||||||
*p = 0;
|
*p = 0;
|
||||||
len_dir = p - dir;
|
len_dir = p - dir;
|
||||||
len_src = lstrlenW( source );
|
if (!(filename = msi_alloc( (len_dir + len_source + 2) * sizeof(WCHAR) )))
|
||||||
len_tgt = lstrlenW( target );
|
{
|
||||||
if (!(arg = msi_alloc( (len + len_dir + len_src + len_tgt + 5) * sizeof(WCHAR) )))
|
msi_free( dir );
|
||||||
|
return ERROR_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
memcpy( filename, dir, len_dir * sizeof(WCHAR) );
|
||||||
|
filename[len_dir++] = '\\';
|
||||||
|
memcpy( filename + len_dir, source, len_source * sizeof(WCHAR) );
|
||||||
|
filename[len_dir + len_source] = 0;
|
||||||
|
|
||||||
|
if (!(args = build_msiexec_args( filename, target )))
|
||||||
{
|
{
|
||||||
msi_free( dir );
|
msi_free( dir );
|
||||||
return ERROR_OUTOFMEMORY;
|
return ERROR_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
memcpy( arg, paramsW, sizeof(paramsW) );
|
|
||||||
arg[len++] = '"';
|
|
||||||
memcpy( arg + len, dir, len_dir * sizeof(WCHAR) );
|
|
||||||
len += len_dir;
|
|
||||||
arg[len++] = '\\';
|
|
||||||
memcpy( arg + len, source, len_src * sizeof(WCHAR) );
|
|
||||||
len += len_src;
|
|
||||||
arg[len++] = '"';
|
|
||||||
arg[len++] = ' ';
|
|
||||||
lstrcpyW( arg + len, target );
|
|
||||||
|
|
||||||
TRACE("installing %s concurrently\n", debugstr_w(source));
|
TRACE("installing %s concurrently\n", debugstr_w(source));
|
||||||
|
|
||||||
handle = execute_command( msiexecW, arg, dir );
|
handle = execute_command( L"msiexec", args, dir );
|
||||||
msi_free( dir );
|
msi_free( dir );
|
||||||
msi_free( arg );
|
msi_free( args );
|
||||||
if (handle == INVALID_HANDLE_VALUE) return ERROR_SUCCESS;
|
if (handle == INVALID_HANDLE_VALUE) return ERROR_SUCCESS;
|
||||||
return wait_process_handle( package, type, handle, action );
|
return wait_process_handle( package, type, handle, action );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT write_substorage_to_file( MSIPACKAGE *package, const WCHAR *source, const WCHAR *filename )
|
||||||
|
{
|
||||||
|
IStorage *src = NULL, *dst = NULL;
|
||||||
|
UINT r = ERROR_FUNCTION_FAILED;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = StgCreateDocfile( filename, STGM_CREATE|STGM_TRANSACTED|STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, &dst );
|
||||||
|
if (FAILED( hr ))
|
||||||
|
{
|
||||||
|
WARN( "can't open destination storage %s (%08x)\n", debugstr_w(filename), hr );
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = IStorage_OpenStorage( package->db->storage, source, NULL, STGM_SHARE_EXCLUSIVE, NULL, 0, &src );
|
||||||
|
if (FAILED( hr ))
|
||||||
|
{
|
||||||
|
WARN( "can't open source storage %s (%08x)\n", debugstr_w(source), hr );
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = IStorage_CopyTo( src, 0, NULL, NULL, dst );
|
||||||
|
if (FAILED( hr ))
|
||||||
|
{
|
||||||
|
ERR( "failed to copy storage %s (%08x)\n", debugstr_w(source), hr );
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = IStorage_Commit( dst, 0 );
|
||||||
|
if (FAILED( hr ))
|
||||||
|
ERR( "failed to commit storage (%08x)\n", hr );
|
||||||
|
else
|
||||||
|
r = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (src) IStorage_Release( src );
|
||||||
|
if (dst) IStorage_Release( dst );
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT HANDLE_CustomType7( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
|
||||||
|
INT type, const WCHAR *action )
|
||||||
|
{
|
||||||
|
WCHAR *tmpfile, *args;
|
||||||
|
MSIBINARY *binary = NULL;
|
||||||
|
HANDLE handle;
|
||||||
|
UINT r;
|
||||||
|
|
||||||
|
if (!(tmpfile = msi_create_temp_file( package->db ))) return ERROR_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
r = write_substorage_to_file( package, source, tmpfile );
|
||||||
|
if (r != ERROR_SUCCESS)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!(binary = msi_alloc( sizeof(*binary) ))) goto error;
|
||||||
|
binary->source = NULL;
|
||||||
|
binary->tmpfile = tmpfile;
|
||||||
|
list_add_tail( &package->binaries, &binary->entry );
|
||||||
|
|
||||||
|
if (!(args = build_msiexec_args( tmpfile, target ))) return ERROR_OUTOFMEMORY;
|
||||||
|
|
||||||
|
TRACE("installing %s concurrently\n", debugstr_w(source));
|
||||||
|
|
||||||
|
handle = execute_command( L"msiexec", args, L"C:\\" );
|
||||||
|
msi_free( args );
|
||||||
|
if (handle == INVALID_HANDLE_VALUE) return ERROR_SUCCESS;
|
||||||
|
return wait_process_handle( package, type, handle, action );
|
||||||
|
|
||||||
|
error:
|
||||||
|
DeleteFileW( tmpfile );
|
||||||
|
msi_free( tmpfile );
|
||||||
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
static UINT HANDLE_CustomType50( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
|
static UINT HANDLE_CustomType50( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
|
||||||
INT type, const WCHAR *action )
|
INT type, const WCHAR *action )
|
||||||
{
|
{
|
||||||
|
@ -1399,60 +1485,62 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, const WCHAR *action)
|
||||||
case 2: /* EXE file stored in a Binary table stream */
|
case 2: /* EXE file stored in a Binary table stream */
|
||||||
rc = HANDLE_CustomType2( package, source, target, type, action );
|
rc = HANDLE_CustomType2( package, source, target, type, action );
|
||||||
break;
|
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 7: /* Concurrent install from substorage */
|
||||||
|
deformat_string( package, target, &deformated );
|
||||||
|
rc = HANDLE_CustomType7( package, source, target, type, action );
|
||||||
|
msi_free( deformated );
|
||||||
|
break;
|
||||||
|
case 17:
|
||||||
|
rc = HANDLE_CustomType17( package, source, target, type, action );
|
||||||
|
break;
|
||||||
case 18: /* EXE file installed with package */
|
case 18: /* EXE file installed with package */
|
||||||
rc = HANDLE_CustomType18( package, source, target, type, action );
|
rc = HANDLE_CustomType18( package, source, target, type, action );
|
||||||
break;
|
break;
|
||||||
case 19: /* Error that halts install */
|
case 19: /* Error that halts install */
|
||||||
rc = HANDLE_CustomType19( package, source, target, type, action );
|
rc = HANDLE_CustomType19( package, source, target, type, action );
|
||||||
break;
|
break;
|
||||||
case 17:
|
case 21: /* JScript/VBScript file installed with the product */
|
||||||
rc = HANDLE_CustomType17(package,source,target,type,action);
|
case 22:
|
||||||
|
rc = HANDLE_CustomType21_22( package, source, target, type, action );
|
||||||
break;
|
break;
|
||||||
case 23: /* installs another package in the source tree */
|
case 23: /* Installs another package in the source tree */
|
||||||
deformat_string( package, target, &deformated );
|
deformat_string( package, target, &deformated );
|
||||||
rc = HANDLE_CustomType23( package, source, deformated, type, action );
|
rc = HANDLE_CustomType23( package, source, deformated, type, action );
|
||||||
msi_free( deformated );
|
msi_free( deformated );
|
||||||
break;
|
break;
|
||||||
case 50: /*EXE file specified by a property value */
|
|
||||||
rc = HANDLE_CustomType50(package,source,target,type,action);
|
|
||||||
break;
|
|
||||||
case 34: /* EXE to be run in specified directory */
|
case 34: /* EXE to be run in specified directory */
|
||||||
rc = HANDLE_CustomType34( package, source, target, type, action );
|
rc = HANDLE_CustomType34( package, source, target, type, action );
|
||||||
break;
|
break;
|
||||||
case 35: /* Directory set with formatted text. */
|
case 35: /* Directory set with formatted text */
|
||||||
deformat_string( package, target, &deformated );
|
deformat_string( package, target, &deformated );
|
||||||
MSI_SetTargetPathW( package, source, deformated );
|
MSI_SetTargetPathW( package, source, deformated );
|
||||||
msi_free( deformated );
|
msi_free( deformated );
|
||||||
break;
|
break;
|
||||||
case 51: /* Property set with formatted text. */
|
case 37: /* JScript/VBScript text stored in target column */
|
||||||
if (!source)
|
|
||||||
break;
|
|
||||||
|
|
||||||
len = deformat_string( package, target, &deformated );
|
|
||||||
rc = msi_set_property( package->db, source, deformated, len );
|
|
||||||
if (rc == ERROR_SUCCESS && !wcscmp( source, szSourceDir ))
|
|
||||||
msi_reset_source_folders( package );
|
|
||||||
msi_free(deformated);
|
|
||||||
break;
|
|
||||||
case 37: /* JScript/VBScript text stored in target column. */
|
|
||||||
case 38:
|
case 38:
|
||||||
rc = HANDLE_CustomType37_38( package, source, target, type, action );
|
rc = HANDLE_CustomType37_38( package, source, target, type, action );
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 50: /* EXE file specified by a property value */
|
||||||
case 6: /* JScript/VBScript file stored in a Binary table stream. */
|
rc = HANDLE_CustomType50( package, source, target, type, action );
|
||||||
rc = HANDLE_CustomType5_6(package,source,target,type,action);
|
|
||||||
break;
|
break;
|
||||||
case 21: /* JScript/VBScript file installed with the product. */
|
case 51: /* Property set with formatted text */
|
||||||
case 22:
|
if (!source) break;
|
||||||
rc = HANDLE_CustomType21_22(package,source,target,type,action);
|
len = deformat_string( package, target, &deformated );
|
||||||
|
rc = msi_set_property( package->db, source, deformated, len );
|
||||||
|
if (rc == ERROR_SUCCESS && !wcscmp( source, szSourceDir )) msi_reset_source_folders( package );
|
||||||
|
msi_free( deformated );
|
||||||
break;
|
break;
|
||||||
case 53: /* JScript/VBScript text specified by a property value. */
|
case 53: /* JScript/VBScript text specified by a property value */
|
||||||
case 54:
|
case 54:
|
||||||
rc = HANDLE_CustomType53_54( package, source, target, type, action );
|
rc = HANDLE_CustomType53_54( package, source, target, type, action );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
FIXME("unhandled action type %u (%s %s)\n", type & CUSTOM_ACTION_TYPE_MASK,
|
FIXME( "unhandled action type %u (%s %s)\n", type & CUSTOM_ACTION_TYPE_MASK, debugstr_w(source),
|
||||||
debugstr_w(source), debugstr_w(target));
|
debugstr_w(target) );
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
|
Loading…
Reference in a new issue