* Sync with Wine 1.5.26.

svn path=/trunk/; revision=58665
This commit is contained in:
Amine Khaldi 2013-04-03 21:58:03 +00:00
parent 27a7122a84
commit 0b598500b3
16 changed files with 329 additions and 308 deletions

View file

@ -688,18 +688,6 @@ MSIFILE *msi_get_loaded_file( MSIPACKAGE *package, const WCHAR *key )
return NULL; return NULL;
} }
MSIFILEPATCH *msi_get_loaded_filepatch( MSIPACKAGE *package, const WCHAR *key )
{
MSIFILEPATCH *patch;
/* FIXME: There might be more than one patch */
LIST_FOR_EACH_ENTRY( patch, &package->filepatches, MSIFILEPATCH, entry )
{
if (!strcmpW( key, patch->File->File )) return patch;
}
return NULL;
}
MSIFOLDER *msi_get_loaded_folder( MSIPACKAGE *package, const WCHAR *dir ) MSIFOLDER *msi_get_loaded_folder( MSIPACKAGE *package, const WCHAR *dir )
{ {
MSIFOLDER *folder; MSIFOLDER *folder;
@ -1788,7 +1776,7 @@ static BOOL process_overrides( MSIPACKAGE *package, int level )
ret |= process_state_property( package, level, szReinstall, INSTALLSTATE_UNKNOWN ); ret |= process_state_property( package, level, szReinstall, INSTALLSTATE_UNKNOWN );
ret |= process_state_property( package, level, szAdvertise, INSTALLSTATE_ADVERTISED ); ret |= process_state_property( package, level, szAdvertise, INSTALLSTATE_ADVERTISED );
if (ret) if (ret && !package->full_reinstall)
msi_set_property( package->db, szPreselected, szOne, -1 ); msi_set_property( package->db, szPreselected, szOne, -1 );
return ret; return ret;
@ -4856,12 +4844,12 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
if (!msi_check_publish(package)) if (!msi_check_publish(package))
return ERROR_SUCCESS; return ERROR_SUCCESS;
rc = MSIREG_OpenFeaturesKey(package->ProductCode, package->Context, rc = MSIREG_OpenFeaturesKey(package->ProductCode, NULL, package->Context,
&hkey, TRUE); &hkey, TRUE);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
goto end; goto end;
rc = MSIREG_OpenUserDataFeaturesKey(package->ProductCode, package->Context, rc = MSIREG_OpenUserDataFeaturesKey(package->ProductCode, NULL, package->Context,
&userdata, TRUE); &userdata, TRUE);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
goto end; goto end;
@ -4961,7 +4949,7 @@ static UINT msi_unpublish_feature(MSIPACKAGE *package, MSIFEATURE *feature)
TRACE("unpublishing feature %s\n", debugstr_w(feature->Feature)); TRACE("unpublishing feature %s\n", debugstr_w(feature->Feature));
r = MSIREG_OpenFeaturesKey(package->ProductCode, package->Context, r = MSIREG_OpenFeaturesKey(package->ProductCode, NULL, package->Context,
&hkey, FALSE); &hkey, FALSE);
if (r == ERROR_SUCCESS) if (r == ERROR_SUCCESS)
{ {
@ -4969,7 +4957,7 @@ static UINT msi_unpublish_feature(MSIPACKAGE *package, MSIFEATURE *feature)
RegCloseKey(hkey); RegCloseKey(hkey);
} }
r = MSIREG_OpenUserDataFeaturesKey(package->ProductCode, package->Context, r = MSIREG_OpenUserDataFeaturesKey(package->ProductCode, NULL, package->Context,
&hkey, FALSE); &hkey, FALSE);
if (r == ERROR_SUCCESS) if (r == ERROR_SUCCESS)
{ {
@ -7264,12 +7252,14 @@ static UINT ITERATE_RemoveExistingProducts( MSIRECORD *rec, LPVOID param )
{'m','s','i','e','x','e','c',' ','/','i',' ','%','s',' ','R','E','M','O','V','E','=','%','s',0}; {'m','s','i','e','x','e','c',' ','/','i',' ','%','s',' ','R','E','M','O','V','E','=','%','s',0};
MSIPACKAGE *package = param; MSIPACKAGE *package = param;
const WCHAR *property = MSI_RecordGetString( rec, 7 ); const WCHAR *property = MSI_RecordGetString( rec, 7 );
int attrs = MSI_RecordGetInteger( rec, 5 );
UINT len = sizeof(fmtW)/sizeof(fmtW[0]); UINT len = sizeof(fmtW)/sizeof(fmtW[0]);
WCHAR *product, *features, *cmd; WCHAR *product, *features, *cmd;
STARTUPINFOW si; STARTUPINFOW si;
PROCESS_INFORMATION info; PROCESS_INFORMATION info;
BOOL ret; BOOL ret;
if (attrs & msidbUpgradeAttributesOnlyDetect) return ERROR_SUCCESS;
if (!(product = msi_dup_property( package->db, property ))) return ERROR_SUCCESS; if (!(product = msi_dup_property( package->db, property ))) return ERROR_SUCCESS;
deformat_string( package, MSI_RecordGetString( rec, 6 ), &features ); deformat_string( package, MSI_RecordGetString( rec, 6 ), &features );
@ -7789,10 +7779,12 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
{ {
TRACE("setting REINSTALL property to ALL\n"); TRACE("setting REINSTALL property to ALL\n");
msi_set_property( package->db, szReinstall, szAll, -1 ); msi_set_property( package->db, szReinstall, szAll, -1 );
package->full_reinstall = 1;
} }
/* properties may have been added by a transform */ /* properties may have been added by a transform */
msi_clone_properties( package ); msi_clone_properties( package );
msi_set_original_database_property( package->db, szPackagePath );
msi_parse_command_line( package, szCommandLine, FALSE ); msi_parse_command_line( package, szCommandLine, FALSE );
msi_adjust_privilege_properties( package ); msi_adjust_privilege_properties( package );

View file

@ -1207,11 +1207,7 @@ static HRESULT view_invoke(
V_VT(pVarResult) = VT_DISPATCH; V_VT(pVarResult) = VT_DISPATCH;
if ((ret = MsiViewFetch(This->msiHandle, &msiHandle)) == ERROR_SUCCESS) if ((ret = MsiViewFetch(This->msiHandle, &msiHandle)) == ERROR_SUCCESS)
{ {
IDispatch *dispatch = NULL; if (FAILED(hr = create_record(msiHandle, &V_DISPATCH(pVarResult))))
if (SUCCEEDED(hr = create_record(msiHandle, &dispatch)))
V_DISPATCH(pVarResult) = dispatch;
else
ERR("Failed to create Record object, hresult 0x%08x\n", hr); ERR("Failed to create Record object, hresult 0x%08x\n", hr);
} }
else if (ret == ERROR_NO_MORE_ITEMS) else if (ret == ERROR_NO_MORE_ITEMS)
@ -1620,7 +1616,7 @@ static HRESULT session_invoke(
static void variant_from_registry_value(VARIANT *pVarResult, DWORD dwType, LPBYTE lpData, DWORD dwSize) static void variant_from_registry_value(VARIANT *pVarResult, DWORD dwType, LPBYTE lpData, DWORD dwSize)
{ {
static const WCHAR szREG_BINARY[] = { '(','R','E','G','_','B','I','N','A','R','Y',')',0 }; static const WCHAR szREG_BINARY[] = { '(','R','E','G','_','B','I','N','A','R','Y',')',0 };
static const WCHAR szREG_[] = { '(','R','E','G','_',']',0 }; static const WCHAR szREG_[] = { '(','R','E','G','_','?','?',')',0 };
WCHAR *szString = (WCHAR *)lpData; WCHAR *szString = (WCHAR *)lpData;
LPWSTR szNewString = NULL; LPWSTR szNewString = NULL;
DWORD dwNewSize = 0; DWORD dwNewSize = 0;
@ -1688,7 +1684,6 @@ static HRESULT InstallerImpl_CreateRecord(WORD wFlags,
HRESULT hr; HRESULT hr;
VARIANTARG varg0; VARIANTARG varg0;
MSIHANDLE hrec; MSIHANDLE hrec;
IDispatch* dispatch;
if (!(wFlags & DISPATCH_METHOD)) if (!(wFlags & DISPATCH_METHOD))
return DISP_E_MEMBERNOTFOUND; return DISP_E_MEMBERNOTFOUND;
@ -1704,11 +1699,7 @@ static HRESULT InstallerImpl_CreateRecord(WORD wFlags,
if (!hrec) if (!hrec)
return DISP_E_EXCEPTION; return DISP_E_EXCEPTION;
hr = create_record(hrec, &dispatch); return create_record(hrec, &V_DISPATCH(pVarResult));
if (SUCCEEDED(hr))
V_DISPATCH(pVarResult) = dispatch;
return hr;
} }
static HRESULT InstallerImpl_OpenPackage(AutomationObject* This, static HRESULT InstallerImpl_OpenPackage(AutomationObject* This,

View file

@ -622,43 +622,6 @@ static DWORD WINAPI DllThread( LPVOID arg )
return rc; return rc;
} }
static DWORD ACTION_CAInstallPackage(const GUID *guid)
{
msi_custom_action_info *info;
UINT r = ERROR_FUNCTION_FAILED;
INSTALLUILEVEL old_level;
info = find_action_by_guid(guid);
if (!info)
{
ERR("failed to find action %s\n", debugstr_guid(guid));
return r;
}
old_level = MsiSetInternalUI(INSTALLUILEVEL_BASIC, NULL);
r = MsiInstallProductW(info->source, info->target);
MsiSetInternalUI(old_level, NULL);
release_custom_action_data(info);
return r;
}
static DWORD WINAPI ConcurrentInstallThread(LPVOID arg)
{
LPGUID guid = arg;
DWORD rc;
TRACE("concurrent installation (%x) started\n", GetCurrentThreadId());
rc = ACTION_CAInstallPackage(guid);
TRACE("concurrent installation (%x) returned %i\n", GetCurrentThreadId(), rc);
MsiCloseAllHandles();
return rc;
}
static msi_custom_action_info *do_msidbCustomActionTypeDll( static msi_custom_action_info *do_msidbCustomActionTypeDll(
MSIPACKAGE *package, INT type, LPCWSTR source, LPCWSTR target, LPCWSTR action ) MSIPACKAGE *package, INT type, LPCWSTR source, LPCWSTR target, LPCWSTR action )
{ {
@ -693,60 +656,8 @@ static msi_custom_action_info *do_msidbCustomActionTypeDll(
return info; return info;
} }
static msi_custom_action_info *do_msidbCAConcurrentInstall( static UINT HANDLE_CustomType1( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
MSIPACKAGE *package, INT type, LPCWSTR source, LPCWSTR target, LPCWSTR action) INT type, const WCHAR *action )
{
msi_custom_action_info *info;
info = msi_alloc( sizeof *info );
if (!info)
return NULL;
msiobj_addref( &package->hdr );
info->refs = 2; /* 1 for our caller and 1 for thread we created */
info->package = package;
info->type = type;
info->target = strdupW( target );
info->source = strdupW( source );
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, ConcurrentInstallThread, &info->guid, 0, NULL );
if (!info->handle)
{
/* release both references */
release_custom_action_data( info );
release_custom_action_data( info );
return NULL;
}
return info;
}
static UINT HANDLE_CustomType23(MSIPACKAGE *package, LPCWSTR source,
LPCWSTR target, const INT type, LPCWSTR action)
{
msi_custom_action_info *info;
WCHAR package_path[MAX_PATH];
DWORD size;
size = MAX_PATH;
msi_get_property(package->db, szSourceDir, package_path, &size);
lstrcatW(package_path, szBackSlash);
lstrcatW(package_path, source);
TRACE("Installing package %s concurrently\n", debugstr_w(package_path));
info = do_msidbCAConcurrentInstall(package, type, package_path, target, action);
return wait_thread_handle(info);
}
static UINT HANDLE_CustomType1(MSIPACKAGE *package, LPCWSTR source,
LPCWSTR target, const INT type, LPCWSTR action)
{ {
msi_custom_action_info *info; msi_custom_action_info *info;
MSIBINARY *binary; MSIBINARY *binary;
@ -828,8 +739,8 @@ static HANDLE execute_command( const WCHAR *app, WCHAR *arg, const WCHAR *dir )
return info.hProcess; return info.hProcess;
} }
static UINT HANDLE_CustomType2(MSIPACKAGE *package, LPCWSTR source, static UINT HANDLE_CustomType2( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
LPCWSTR target, const INT type, LPCWSTR action) INT type, const WCHAR *action )
{ {
MSIBINARY *binary; MSIBINARY *binary;
HANDLE handle; HANDLE handle;
@ -846,8 +757,8 @@ static UINT HANDLE_CustomType2(MSIPACKAGE *package, LPCWSTR source,
return wait_process_handle( package, type, handle, action ); return wait_process_handle( package, type, handle, action );
} }
static UINT HANDLE_CustomType17(MSIPACKAGE *package, LPCWSTR source, static UINT HANDLE_CustomType17( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
LPCWSTR target, const INT type, LPCWSTR action) INT type, const WCHAR *action )
{ {
msi_custom_action_info *info; msi_custom_action_info *info;
MSIFILE *file; MSIFILE *file;
@ -865,8 +776,8 @@ static UINT HANDLE_CustomType17(MSIPACKAGE *package, LPCWSTR source,
return wait_thread_handle( info ); return wait_thread_handle( info );
} }
static UINT HANDLE_CustomType18(MSIPACKAGE *package, LPCWSTR source, static UINT HANDLE_CustomType18( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
LPCWSTR target, const INT type, LPCWSTR action) INT type, const WCHAR *action )
{ {
MSIFILE *file; MSIFILE *file;
HANDLE handle; HANDLE handle;
@ -883,8 +794,8 @@ static UINT HANDLE_CustomType18(MSIPACKAGE *package, LPCWSTR source,
return wait_process_handle( package, type, handle, action ); return wait_process_handle( package, type, handle, action );
} }
static UINT HANDLE_CustomType19(MSIPACKAGE *package, LPCWSTR source, static UINT HANDLE_CustomType19( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
LPCWSTR target, const INT type, LPCWSTR action) INT type, const WCHAR *action )
{ {
static const WCHAR query[] = { static const WCHAR query[] = {
'S','E','L','E','C','T',' ','`','M','e','s','s','a','g','e','`',' ', 'S','E','L','E','C','T',' ','`','M','e','s','s','a','g','e','`',' ',
@ -914,8 +825,52 @@ static UINT HANDLE_CustomType19(MSIPACKAGE *package, LPCWSTR source,
return ERROR_INSTALL_FAILURE; return ERROR_INSTALL_FAILURE;
} }
static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source, static UINT HANDLE_CustomType23( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
LPCWSTR target, const INT type, LPCWSTR action) INT type, const WCHAR *action )
{
static const WCHAR msiexecW[] = {'m','s','i','e','x','e','c',0};
static const WCHAR paramsW[] = {'/','q','b',' ','/','i',' '};
WCHAR *dir, *arg, *p;
UINT len_src, len_dir, len_tgt, len = sizeof(paramsW)/sizeof(paramsW[0]);
HANDLE handle;
if (!(dir = msi_dup_property( package->db, szOriginalDatabase ))) return ERROR_OUTOFMEMORY;
if (!(p = strrchrW( dir, '\\' )) && !(p = strrchrW( dir, '/' )))
{
msi_free( dir );
return ERROR_FUNCTION_FAILED;
}
*p = 0;
len_dir = p - dir;
len_src = strlenW( source );
len_tgt = strlenW( target );
if (!(arg = msi_alloc( (len + len_dir + len_src + len_tgt + 5) * sizeof(WCHAR) )))
{
msi_free( dir );
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++] = ' ';
strcpyW( arg + len, target );
TRACE("installing %s concurrently\n", debugstr_w(source));
handle = execute_command( msiexecW, arg, dir );
msi_free( dir );
msi_free( arg );
if (handle == INVALID_HANDLE_VALUE) return ERROR_SUCCESS;
return wait_process_handle( package, type, handle, action );
}
static UINT HANDLE_CustomType50( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
INT type, const WCHAR *action )
{ {
WCHAR *exe, *arg; WCHAR *exe, *arg;
HANDLE handle; HANDLE handle;
@ -931,8 +886,8 @@ static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source,
return wait_process_handle( package, type, handle, action ); return wait_process_handle( package, type, handle, action );
} }
static UINT HANDLE_CustomType34(MSIPACKAGE *package, LPCWSTR source, static UINT HANDLE_CustomType34( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
LPCWSTR target, const INT type, LPCWSTR action) INT type, const WCHAR *action )
{ {
const WCHAR *workingdir = NULL; const WCHAR *workingdir = NULL;
HANDLE handle; HANDLE handle;
@ -1032,8 +987,8 @@ static msi_custom_action_info *do_msidbCustomActionTypeScript(
return info; return info;
} }
static UINT HANDLE_CustomType37_38(MSIPACKAGE *package, LPCWSTR source, static UINT HANDLE_CustomType37_38( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
LPCWSTR target, const INT type, LPCWSTR action) INT type, const WCHAR *action )
{ {
msi_custom_action_info *info; msi_custom_action_info *info;
@ -1043,8 +998,8 @@ static UINT HANDLE_CustomType37_38(MSIPACKAGE *package, LPCWSTR source,
return wait_thread_handle( info ); return wait_thread_handle( info );
} }
static UINT HANDLE_CustomType5_6(MSIPACKAGE *package, LPCWSTR source, static UINT HANDLE_CustomType5_6( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
LPCWSTR target, const INT type, LPCWSTR action) INT type, const WCHAR *action )
{ {
static const WCHAR query[] = { static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
@ -1090,8 +1045,8 @@ done:
return r; return r;
} }
static UINT HANDLE_CustomType21_22(MSIPACKAGE *package, LPCWSTR source, static UINT HANDLE_CustomType21_22( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
LPCWSTR target, const INT type, LPCWSTR action) INT type, const WCHAR *action )
{ {
msi_custom_action_info *info; msi_custom_action_info *info;
MSIFILE *file; MSIFILE *file;
@ -1149,8 +1104,8 @@ done:
return r; return r;
} }
static UINT HANDLE_CustomType53_54(MSIPACKAGE *package, LPCWSTR source, static UINT HANDLE_CustomType53_54( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
LPCWSTR target, const INT type, LPCWSTR action) INT type, const WCHAR *action )
{ {
msi_custom_action_info *info; msi_custom_action_info *info;
WCHAR *prop; WCHAR *prop;

View file

@ -696,7 +696,7 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control,
else if ( !strcmpW( attribute, szProperty ) ) else if ( !strcmpW( attribute, szProperty ) )
{ {
MSIFEATURE *feature = msi_seltree_get_selected_feature( ctrl ); MSIFEATURE *feature = msi_seltree_get_selected_feature( ctrl );
msi_dialog_set_property( dialog->package, ctrl->property, feature->Directory ); if (feature) msi_dialog_set_property( dialog->package, ctrl->property, feature->Directory );
} }
else if ( !strcmpW( attribute, szSelectionPath ) ) else if ( !strcmpW( attribute, szSelectionPath ) )
{ {
@ -1139,7 +1139,7 @@ static UINT msi_dialog_line_control( msi_dialog *dialog, MSIRECORD *rec )
msi_dialog_map_events(dialog, name); msi_dialog_map_events(dialog, name);
control = msi_alloc( sizeof(*control) + strlenW(name) * sizeof(WCHAR) ); control = msi_alloc( FIELD_OFFSET(msi_control, name[strlenW( name ) + 1] ));
if (!control) if (!control)
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
@ -1808,7 +1808,6 @@ static void msi_mask_control_change( struct msi_maskedit_info *info )
if( i == info->num_groups ) if( i == info->num_groups )
{ {
TRACE("Set property %s to %s\n", debugstr_w(info->prop), debugstr_w(val)); TRACE("Set property %s to %s\n", debugstr_w(info->prop), debugstr_w(val));
CharUpperBuffW( val, info->num_chars );
msi_dialog_set_property( info->dialog->package, info->prop, val ); msi_dialog_set_property( info->dialog->package, info->prop, val );
msi_dialog_evaluate_control_conditions( info->dialog ); msi_dialog_evaluate_control_conditions( info->dialog );
} }
@ -3739,7 +3738,7 @@ msi_dialog *msi_dialog_create( MSIPACKAGE* package,
msi_dialog_register_class(); msi_dialog_register_class();
/* allocate the structure for the dialog to use */ /* allocate the structure for the dialog to use */
dialog = msi_alloc_zero( sizeof *dialog + sizeof(WCHAR)*strlenW(szDialogName) ); dialog = msi_alloc_zero( FIELD_OFFSET( msi_dialog, name[strlenW( szDialogName ) + 1] ));
if( !dialog ) if( !dialog )
return NULL; return NULL;
strcpyW( dialog->name, szDialogName ); strcpyW( dialog->name, szDialogName );

View file

@ -447,6 +447,17 @@ static void unload_mspatch(void)
FreeLibrary(hmspatcha); FreeLibrary(hmspatcha);
} }
static MSIFILEPATCH *get_next_filepatch( MSIPACKAGE *package, const WCHAR *key )
{
MSIFILEPATCH *patch;
LIST_FOR_EACH_ENTRY( patch, &package->filepatches, MSIFILEPATCH, entry )
{
if (!patch->IsApplied && !strcmpW( key, patch->File->File )) return patch;
}
return NULL;
}
static BOOL patchfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action, static BOOL patchfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action,
LPWSTR *path, DWORD *attrs, PVOID user) LPWSTR *path, DWORD *attrs, PVOID user)
{ {
@ -459,12 +470,9 @@ static BOOL patchfiles_cb(MSIPACKAGE *package, LPCWSTR file, DWORD action,
if (temp_folder[0] == '\0') if (temp_folder[0] == '\0')
GetTempPathW(MAX_PATH, temp_folder); GetTempPathW(MAX_PATH, temp_folder);
p = msi_get_loaded_filepatch(package, file); if (!(p = get_next_filepatch(package, file)) || !p->File->Component->Enabled)
if (!p)
{
TRACE("unknown file in cabinet (%s)\n", debugstr_w(file));
return FALSE; return FALSE;
}
GetTempFileNameW(temp_folder, NULL, 0, patch_path); GetTempFileNameW(temp_folder, NULL, 0, patch_path);
*path = strdupW(patch_path); *path = strdupW(patch_path);

View file

@ -2922,6 +2922,123 @@ end:
return r; return r;
} }
static UINT query_feature_state( const WCHAR *product, const WCHAR *squashed, const WCHAR *usersid,
MSIINSTALLCONTEXT ctx, const WCHAR *feature, INSTALLSTATE *state )
{
UINT r;
HKEY hkey;
WCHAR *parent, *components, *path;
const WCHAR *p;
BOOL missing = FALSE, source = FALSE;
WCHAR comp[GUID_SIZE];
GUID guid;
if (ctx != MSIINSTALLCONTEXT_MACHINE) SetLastError( ERROR_SUCCESS );
if (MSIREG_OpenFeaturesKey( product, usersid, ctx, &hkey, FALSE )) return ERROR_UNKNOWN_PRODUCT;
parent = msi_reg_get_val_str( hkey, feature );
RegCloseKey( hkey );
if (!parent) return ERROR_UNKNOWN_FEATURE;
*state = (parent[0] == 6) ? INSTALLSTATE_ABSENT : INSTALLSTATE_LOCAL;
msi_free( parent );
if (*state == INSTALLSTATE_ABSENT)
return ERROR_SUCCESS;
r = MSIREG_OpenUserDataFeaturesKey( product, usersid, ctx, &hkey, FALSE );
if (r != ERROR_SUCCESS)
{
*state = INSTALLSTATE_ADVERTISED;
return ERROR_SUCCESS;
}
components = msi_reg_get_val_str( hkey, feature );
RegCloseKey( hkey );
TRACE("buffer = %s\n", debugstr_w(components));
if (!components)
{
*state = INSTALLSTATE_ADVERTISED;
return ERROR_SUCCESS;
}
for (p = components; *p && *p != 2 ; p += 20)
{
if (!decode_base85_guid( p, &guid ))
{
if (p != components) break;
msi_free( components );
*state = INSTALLSTATE_BADCONFIG;
return ERROR_BAD_CONFIGURATION;
}
StringFromGUID2( &guid, comp, GUID_SIZE );
if (ctx == MSIINSTALLCONTEXT_MACHINE)
r = MSIREG_OpenUserDataComponentKey( comp, szLocalSid, &hkey, FALSE );
else
r = MSIREG_OpenUserDataComponentKey( comp, usersid, &hkey, FALSE );
if (r != ERROR_SUCCESS)
{
msi_free( components );
*state = INSTALLSTATE_ADVERTISED;
return ERROR_SUCCESS;
}
path = msi_reg_get_val_str( hkey, squashed );
if (!path) missing = TRUE;
else if (strlenW( path ) > 2 &&
path[0] >= '0' && path[0] <= '9' &&
path[1] >= '0' && path[1] <= '9')
{
source = TRUE;
}
msi_free( path );
}
msi_free( components );
if (missing)
*state = INSTALLSTATE_ADVERTISED;
else if (source)
*state = INSTALLSTATE_SOURCE;
else
*state = INSTALLSTATE_LOCAL;
TRACE("returning state %d\n", *state);
return ERROR_SUCCESS;
}
UINT WINAPI MsiQueryFeatureStateExA( LPCSTR product, LPCSTR usersid, MSIINSTALLCONTEXT ctx,
LPCSTR feature, INSTALLSTATE *state )
{
UINT r;
WCHAR *productW = NULL, *usersidW = NULL, *featureW = NULL;
if (product && !(productW = strdupAtoW( product ))) return ERROR_OUTOFMEMORY;
if (usersid && !(usersidW = strdupAtoW( usersid )))
{
msi_free( productW );
return ERROR_OUTOFMEMORY;
}
if (feature && !(featureW = strdupAtoW( feature )))
{
msi_free( productW );
msi_free( usersidW );
return ERROR_OUTOFMEMORY;
}
r = MsiQueryFeatureStateExW( productW, usersidW, ctx, featureW, state );
msi_free( productW );
msi_free( usersidW );
msi_free( featureW );
return r;
}
UINT WINAPI MsiQueryFeatureStateExW( LPCWSTR product, LPCWSTR usersid, MSIINSTALLCONTEXT ctx,
LPCWSTR feature, INSTALLSTATE *state )
{
WCHAR squashed[33];
if (!squash_guid( product, squashed )) return ERROR_INVALID_PARAMETER;
return query_feature_state( product, squashed, usersid, ctx, feature, state );
}
/****************************************************************** /******************************************************************
* MsiQueryFeatureStateA [MSI.@] * MsiQueryFeatureStateA [MSI.@]
*/ */
@ -2966,117 +3083,25 @@ end:
*/ */
INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature) INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
{ {
WCHAR squishProduct[33], comp[GUID_SIZE]; UINT r;
GUID guid; INSTALLSTATE state;
LPWSTR components, p, parent_feature, path; WCHAR squashed[33];
UINT rc;
HKEY hkey;
INSTALLSTATE r;
BOOL missing = FALSE;
BOOL machine = FALSE;
BOOL source = FALSE;
TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature)); TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
if (!szProduct || !szFeature) if (!szProduct || !szFeature || !squash_guid( szProduct, squashed ))
return INSTALLSTATE_INVALIDARG; return INSTALLSTATE_INVALIDARG;
if (!squash_guid( szProduct, squishProduct )) r = query_feature_state( szProduct, squashed, NULL, MSIINSTALLCONTEXT_USERMANAGED, szFeature, &state );
return INSTALLSTATE_INVALIDARG; if (r == ERROR_SUCCESS || r == ERROR_BAD_CONFIGURATION) return state;
SetLastError( ERROR_SUCCESS ); r = query_feature_state( szProduct, squashed, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, szFeature, &state );
if (r == ERROR_SUCCESS || r == ERROR_BAD_CONFIGURATION) return state;
if (MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED, r = query_feature_state( szProduct, squashed, NULL, MSIINSTALLCONTEXT_MACHINE, szFeature, &state );
&hkey, FALSE) != ERROR_SUCCESS && if (r == ERROR_SUCCESS || r == ERROR_BAD_CONFIGURATION) return state;
MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
&hkey, FALSE) != ERROR_SUCCESS)
{
rc = MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
&hkey, FALSE);
if (rc != ERROR_SUCCESS)
return INSTALLSTATE_UNKNOWN;
machine = TRUE; return INSTALLSTATE_UNKNOWN;
}
parent_feature = msi_reg_get_val_str( hkey, szFeature );
RegCloseKey(hkey);
if (!parent_feature)
return INSTALLSTATE_UNKNOWN;
r = (parent_feature[0] == 6) ? INSTALLSTATE_ABSENT : INSTALLSTATE_LOCAL;
msi_free(parent_feature);
if (r == INSTALLSTATE_ABSENT)
return r;
if (machine)
rc = MSIREG_OpenUserDataFeaturesKey(szProduct,
MSIINSTALLCONTEXT_MACHINE,
&hkey, FALSE);
else
rc = MSIREG_OpenUserDataFeaturesKey(szProduct,
MSIINSTALLCONTEXT_USERUNMANAGED,
&hkey, FALSE);
if (rc != ERROR_SUCCESS)
return INSTALLSTATE_ADVERTISED;
components = msi_reg_get_val_str( hkey, szFeature );
RegCloseKey(hkey);
TRACE("rc = %d buffer = %s\n", rc, debugstr_w(components));
if (!components)
return INSTALLSTATE_ADVERTISED;
for( p = components; *p && *p != 2 ; p += 20)
{
if (!decode_base85_guid( p, &guid ))
{
if (p != components)
break;
msi_free(components);
return INSTALLSTATE_BADCONFIG;
}
StringFromGUID2(&guid, comp, GUID_SIZE);
if (machine)
rc = MSIREG_OpenUserDataComponentKey(comp, szLocalSid, &hkey, FALSE);
else
rc = MSIREG_OpenUserDataComponentKey(comp, NULL, &hkey, FALSE);
if (rc != ERROR_SUCCESS)
{
msi_free(components);
return INSTALLSTATE_ADVERTISED;
}
path = msi_reg_get_val_str(hkey, squishProduct);
if (!path)
missing = TRUE;
else if (lstrlenW(path) > 2 &&
path[0] >= '0' && path[0] <= '9' &&
path[1] >= '0' && path[1] <= '9')
{
source = TRUE;
}
msi_free(path);
}
msi_free(components);
if (missing)
r = INSTALLSTATE_ADVERTISED;
else if (source)
r = INSTALLSTATE_SOURCE;
else
r = INSTALLSTATE_LOCAL;
TRACE("-> %d\n", r);
return r;
} }
/****************************************************************** /******************************************************************
@ -3137,7 +3162,7 @@ static UINT get_file_version( const WCHAR *path, WCHAR *verbuf, DWORD *verlen,
static const WCHAR szVersionResource[] = {'\\',0}; static const WCHAR szVersionResource[] = {'\\',0};
static const WCHAR szVersionFormat[] = {'%','d','.','%','d','.','%','d','.','%','d',0}; static const WCHAR szVersionFormat[] = {'%','d','.','%','d','.','%','d','.','%','d',0};
static const WCHAR szLangFormat[] = {'%','d',0}; static const WCHAR szLangFormat[] = {'%','d',0};
UINT ret = ERROR_SUCCESS; UINT ret = ERROR_MORE_DATA;
DWORD len, error; DWORD len, error;
LPVOID version; LPVOID version;
VS_FIXEDFILEINFO *ffi; VS_FIXEDFILEINFO *ffi;
@ -3148,6 +3173,7 @@ static UINT get_file_version( const WCHAR *path, WCHAR *verbuf, DWORD *verlen,
{ {
error = GetLastError(); error = GetLastError();
if (error == ERROR_BAD_PATHNAME) return ERROR_FILE_NOT_FOUND; if (error == ERROR_BAD_PATHNAME) return ERROR_FILE_NOT_FOUND;
if (error == ERROR_RESOURCE_DATA_NOT_FOUND) return ERROR_FILE_INVALID;
return error; return error;
} }
if (!(version = msi_alloc( len ))) return ERROR_OUTOFMEMORY; if (!(version = msi_alloc( len ))) return ERROR_OUTOFMEMORY;
@ -3156,6 +3182,11 @@ static UINT get_file_version( const WCHAR *path, WCHAR *verbuf, DWORD *verlen,
msi_free( version ); msi_free( version );
return GetLastError(); return GetLastError();
} }
if (!verbuf && !verlen && !langbuf && !langlen)
{
msi_free( version );
return ERROR_SUCCESS;
}
if (verlen) if (verlen)
{ {
if (VerQueryValueW( version, szVersionResource, (LPVOID *)&ffi, &len ) && len > 0) if (VerQueryValueW( version, szVersionResource, (LPVOID *)&ffi, &len ) && len > 0)
@ -3165,7 +3196,7 @@ static UINT get_file_version( const WCHAR *path, WCHAR *verbuf, DWORD *verlen,
HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS) ); HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS) );
if (verbuf) lstrcpynW( verbuf, tmp, *verlen ); if (verbuf) lstrcpynW( verbuf, tmp, *verlen );
len = strlenW( tmp ); len = strlenW( tmp );
if (len >= *verlen) ret = ERROR_MORE_DATA; if (*verlen > len) ret = ERROR_SUCCESS;
*verlen = len; *verlen = len;
} }
else else
@ -3181,7 +3212,7 @@ static UINT get_file_version( const WCHAR *path, WCHAR *verbuf, DWORD *verlen,
sprintfW( tmp, szLangFormat, *lang ); sprintfW( tmp, szLangFormat, *lang );
if (langbuf) lstrcpynW( langbuf, tmp, *langlen ); if (langbuf) lstrcpynW( langbuf, tmp, *langlen );
len = strlenW( tmp ); len = strlenW( tmp );
if (len >= *langlen) ret = ERROR_MORE_DATA; if (*langlen > len) ret = ERROR_SUCCESS;
*langlen = len; *langlen = len;
} }
else else
@ -3789,7 +3820,7 @@ UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
lstrcatW(path, installerW); lstrcatW(path, installerW);
if (!CreateDirectoryW(path, NULL)) if (!CreateDirectoryW(path, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
return ERROR_SUCCESS; return ERROR_SUCCESS;

View file

@ -244,8 +244,8 @@
248 stdcall MsiGetProductInfoExW(wstr wstr long wstr ptr ptr) 248 stdcall MsiGetProductInfoExW(wstr wstr long wstr ptr ptr)
249 stdcall MsiQueryComponentStateA(str str long str ptr) 249 stdcall MsiQueryComponentStateA(str str long str ptr)
250 stdcall MsiQueryComponentStateW(wstr wstr long wstr ptr) 250 stdcall MsiQueryComponentStateW(wstr wstr long wstr ptr)
251 stub MsiQueryFeatureStateExA 251 stdcall MsiQueryFeatureStateExA(str str long str ptr)
252 stub MsiQueryFeatureStateExW 252 stdcall MsiQueryFeatureStateExW(wstr wstr long wstr ptr)
253 stdcall MsiDeterminePatchSequenceA(str str long long ptr) 253 stdcall MsiDeterminePatchSequenceA(str str long long ptr)
254 stdcall MsiDeterminePatchSequenceW(wstr wstr long long ptr) 254 stdcall MsiDeterminePatchSequenceW(wstr wstr long long ptr)
255 stdcall MsiSourceListAddSourceExA(str str long long str long) 255 stdcall MsiSourceListAddSourceExA(str str long long str long)

View file

@ -338,6 +338,7 @@ typedef struct msi_dialog_tag msi_dialog;
enum platform enum platform
{ {
PLATFORM_UNKNOWN,
PLATFORM_INTEL, PLATFORM_INTEL,
PLATFORM_INTEL64, PLATFORM_INTEL64,
PLATFORM_X64, PLATFORM_X64,
@ -414,6 +415,7 @@ typedef struct tagMSIPACKAGE
unsigned char need_reboot_at_end : 1; unsigned char need_reboot_at_end : 1;
unsigned char need_reboot_now : 1; unsigned char need_reboot_now : 1;
unsigned char need_rollback : 1; unsigned char need_rollback : 1;
unsigned char full_reinstall : 1;
} MSIPACKAGE; } MSIPACKAGE;
typedef struct tagMSIPREVIEW typedef struct tagMSIPREVIEW
@ -884,10 +886,10 @@ extern UINT MSIREG_OpenUninstallKey(const WCHAR *, enum platform, HKEY *, BOOL)
extern UINT MSIREG_DeleteUninstallKey(const WCHAR *, enum platform) DECLSPEC_HIDDEN; extern UINT MSIREG_DeleteUninstallKey(const WCHAR *, enum platform) DECLSPEC_HIDDEN;
extern UINT MSIREG_OpenProductKey(LPCWSTR szProduct, LPCWSTR szUserSid, extern UINT MSIREG_OpenProductKey(LPCWSTR szProduct, LPCWSTR szUserSid,
MSIINSTALLCONTEXT context, HKEY* key, BOOL create) DECLSPEC_HIDDEN; MSIINSTALLCONTEXT context, HKEY* key, BOOL create) DECLSPEC_HIDDEN;
extern UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, MSIINSTALLCONTEXT context, extern UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, LPCWSTR szUserSid, MSIINSTALLCONTEXT context,
HKEY *key, BOOL create) DECLSPEC_HIDDEN; HKEY *key, BOOL create) DECLSPEC_HIDDEN;
extern UINT MSIREG_OpenUserPatchesKey(LPCWSTR szPatch, HKEY* key, BOOL create) DECLSPEC_HIDDEN; extern UINT MSIREG_OpenUserPatchesKey(LPCWSTR szPatch, HKEY* key, BOOL create) DECLSPEC_HIDDEN;
UINT MSIREG_OpenUserDataFeaturesKey(LPCWSTR szProduct, MSIINSTALLCONTEXT context, UINT MSIREG_OpenUserDataFeaturesKey(LPCWSTR szProduct, LPCWSTR szUserSid, MSIINSTALLCONTEXT context,
HKEY *key, BOOL create) DECLSPEC_HIDDEN; HKEY *key, BOOL create) DECLSPEC_HIDDEN;
extern UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create) DECLSPEC_HIDDEN; extern UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create) DECLSPEC_HIDDEN;
extern UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid, extern UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid,
@ -1016,7 +1018,6 @@ extern void msi_reset_folders( MSIPACKAGE *package, BOOL source ) DECLSPEC_HIDDE
extern MSICOMPONENT *msi_get_loaded_component(MSIPACKAGE *package, const WCHAR *Component) DECLSPEC_HIDDEN; extern MSICOMPONENT *msi_get_loaded_component(MSIPACKAGE *package, const WCHAR *Component) DECLSPEC_HIDDEN;
extern MSIFEATURE *msi_get_loaded_feature(MSIPACKAGE *package, const WCHAR *Feature) DECLSPEC_HIDDEN; extern MSIFEATURE *msi_get_loaded_feature(MSIPACKAGE *package, const WCHAR *Feature) DECLSPEC_HIDDEN;
extern MSIFILE *msi_get_loaded_file(MSIPACKAGE *package, const WCHAR *file) DECLSPEC_HIDDEN; extern MSIFILE *msi_get_loaded_file(MSIPACKAGE *package, const WCHAR *file) DECLSPEC_HIDDEN;
extern MSIFILEPATCH *msi_get_loaded_filepatch(MSIPACKAGE* package, const WCHAR *key) DECLSPEC_HIDDEN;
extern MSIFOLDER *msi_get_loaded_folder(MSIPACKAGE *package, const WCHAR *dir) DECLSPEC_HIDDEN; extern MSIFOLDER *msi_get_loaded_folder(MSIPACKAGE *package, const WCHAR *dir) DECLSPEC_HIDDEN;
extern int msi_track_tempfile(MSIPACKAGE *package, const WCHAR *path) DECLSPEC_HIDDEN; extern int msi_track_tempfile(MSIPACKAGE *package, const WCHAR *path) DECLSPEC_HIDDEN;
extern void msi_free_action_script(MSIPACKAGE *package, UINT script) DECLSPEC_HIDDEN; extern void msi_free_action_script(MSIPACKAGE *package, UINT script) DECLSPEC_HIDDEN;
@ -1040,6 +1041,7 @@ extern BOOL msi_init_assembly_caches(MSIPACKAGE *) DECLSPEC_HIDDEN;
extern void msi_destroy_assembly_caches(MSIPACKAGE *) DECLSPEC_HIDDEN; extern void msi_destroy_assembly_caches(MSIPACKAGE *) DECLSPEC_HIDDEN;
extern WCHAR *msi_font_version_from_file(const WCHAR *) DECLSPEC_HIDDEN; extern WCHAR *msi_font_version_from_file(const WCHAR *) DECLSPEC_HIDDEN;
extern WCHAR **msi_split_string(const WCHAR *, WCHAR) DECLSPEC_HIDDEN; extern WCHAR **msi_split_string(const WCHAR *, WCHAR) DECLSPEC_HIDDEN;
extern UINT msi_set_original_database_property(MSIDATABASE *, const WCHAR *) DECLSPEC_HIDDEN;
/* media */ /* media */

View file

@ -158,7 +158,6 @@ void msi_free_action_script( MSIPACKAGE *package, UINT script )
static void free_package_structures( MSIPACKAGE *package ) static void free_package_structures( MSIPACKAGE *package )
{ {
INT i;
struct list *item, *cursor; struct list *item, *cursor;
LIST_FOR_EACH_SAFE( item, cursor, &package->features ) LIST_FOR_EACH_SAFE( item, cursor, &package->features )
@ -287,11 +286,14 @@ static void free_package_structures( MSIPACKAGE *package )
if (package->script) if (package->script)
{ {
INT i;
UINT j;
for (i = 0; i < SCRIPT_MAX; i++) for (i = 0; i < SCRIPT_MAX; i++)
msi_free_action_script( package, i ); msi_free_action_script( package, i );
for (i = 0; i < package->script->UniqueActionsCount; i++) for (j = 0; j < package->script->UniqueActionsCount; j++)
msi_free( package->script->UniqueActions[i] ); msi_free( package->script->UniqueActions[j] );
msi_free( package->script->UniqueActions ); msi_free( package->script->UniqueActions );
msi_free( package->script ); msi_free( package->script );
@ -753,6 +755,8 @@ static VOID set_installer_properties(MSIPACKAGE *package)
static const WCHAR szPrintHoodFolder[] = {'P','r','i','n','t','H','o','o','d','F','o','l','d','e','r',0}; static const WCHAR szPrintHoodFolder[] = {'P','r','i','n','t','H','o','o','d','F','o','l','d','e','r',0};
static const WCHAR szRecentFolder[] = {'R','e','c','e','n','t','F','o','l','d','e','r',0}; static const WCHAR szRecentFolder[] = {'R','e','c','e','n','t','F','o','l','d','e','r',0};
static const WCHAR szComputerName[] = {'C','o','m','p','u','t','e','r','N','a','m','e',0}; static const WCHAR szComputerName[] = {'C','o','m','p','u','t','e','r','N','a','m','e',0};
static const WCHAR szBrowseProperty[] = {'_','B','r','o','w','s','e','P','r','o','p','e','r','t','y',0};
static const WCHAR szInstallDir[] = {'I','N','S','T','A','L','L','D','I','R',0};
/* /*
* Other things that probably should be set: * Other things that probably should be set:
@ -1024,6 +1028,7 @@ static VOID set_installer_properties(MSIPACKAGE *package)
msi_free( computername ); msi_free( computername );
} }
} }
msi_set_property( package->db, szBrowseProperty, szInstallDir, -1 );
} }
static UINT msi_load_summary_properties( MSIPACKAGE *package ) static UINT msi_load_summary_properties( MSIPACKAGE *package )
@ -1270,9 +1275,18 @@ UINT msi_create_empty_local_file( LPWSTR path, LPCWSTR suffix )
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static enum platform parse_platform( WCHAR *str )
{
if (!str[0] || !strcmpW( str, szIntel )) return PLATFORM_INTEL;
else if (!strcmpW( str, szIntel64 )) return PLATFORM_INTEL64;
else if (!strcmpW( str, szX64 ) || !strcmpW( str, szAMD64 )) return PLATFORM_X64;
else if (!strcmpW( str, szARM )) return PLATFORM_ARM;
return PLATFORM_UNKNOWN;
}
static UINT msi_parse_summary( MSISUMMARYINFO *si, MSIPACKAGE *package ) static UINT msi_parse_summary( MSISUMMARYINFO *si, MSIPACKAGE *package )
{ {
WCHAR *template, *p, *q; WCHAR *template, *p, *q, *platform;
DWORD i, count; DWORD i, count;
package->version = msi_suminfo_get_int32( si, PID_PAGECOUNT ); package->version = msi_suminfo_get_int32( si, PID_PAGECOUNT );
@ -1292,16 +1306,16 @@ static UINT msi_parse_summary( MSISUMMARYINFO *si, MSIPACKAGE *package )
return ERROR_PATCH_PACKAGE_INVALID; return ERROR_PATCH_PACKAGE_INVALID;
} }
*p = 0; *p = 0;
if ((q = strchrW( template, ',' ))) *q = 0; platform = template;
if (!template[0] || !strcmpW( template, szIntel )) if ((q = strchrW( platform, ',' ))) *q = 0;
package->platform = PLATFORM_INTEL; package->platform = parse_platform( platform );
else if (!strcmpW( template, szIntel64 )) while (package->platform == PLATFORM_UNKNOWN && q)
package->platform = PLATFORM_INTEL64; {
else if (!strcmpW( template, szX64 ) || !strcmpW( template, szAMD64 )) platform = q + 1;
package->platform = PLATFORM_X64; if ((q = strchrW( platform, ',' ))) *q = 0;
else if (!strcmpW( template, szARM )) package->platform = parse_platform( platform );
package->platform = PLATFORM_ARM; }
else if (package->platform == PLATFORM_UNKNOWN)
{ {
WARN("unknown platform %s\n", debugstr_w(template)); WARN("unknown platform %s\n", debugstr_w(template));
msi_free( template ); msi_free( template );
@ -1514,6 +1528,28 @@ static UINT get_local_package( const WCHAR *filename, WCHAR *localfile )
return r; return r;
} }
UINT msi_set_original_database_property( MSIDATABASE *db, const WCHAR *package )
{
UINT r;
if (UrlIsW( package, URLIS_URL ))
r = msi_set_property( db, szOriginalDatabase, package, -1 );
else if (package[0] == '#')
r = msi_set_property( db, szOriginalDatabase, db->path, -1 );
else
{
DWORD len;
WCHAR *path;
if (!(len = GetFullPathNameW( package, 0, NULL, NULL ))) return GetLastError();
if (!(path = msi_alloc( len * sizeof(WCHAR) ))) return ERROR_OUTOFMEMORY;
len = GetFullPathNameW( package, len, path, NULL );
r = msi_set_property( db, szOriginalDatabase, path, len );
msi_free( path );
}
return r;
}
UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
{ {
static const WCHAR dotmsi[] = {'.','m','s','i',0}; static const WCHAR dotmsi[] = {'.','m','s','i',0};
@ -1623,17 +1659,6 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
return r; return r;
} }
msi_set_property( package->db, szDatabase, db->path, -1 ); msi_set_property( package->db, szDatabase, db->path, -1 );
if( UrlIsW( szPackage, URLIS_URL ) )
msi_set_property( package->db, szOriginalDatabase, szPackage, -1 );
else if( szPackage[0] == '#' )
msi_set_property( package->db, szOriginalDatabase, db->path, -1 );
else
{
WCHAR fullpath[MAX_PATH];
DWORD len = GetFullPathNameW( szPackage, MAX_PATH, fullpath, NULL );
msi_set_property( package->db, szOriginalDatabase, fullpath, len );
}
msi_set_context( package ); msi_set_context( package );
while (1) while (1)
@ -1660,6 +1685,12 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
msi_clone_properties( package ); msi_clone_properties( package );
msi_adjust_privilege_properties( package ); msi_adjust_privilege_properties( package );
} }
r = msi_set_original_database_property( package->db, szPackage );
if (r != ERROR_SUCCESS)
{
msiobj_release( &package->hdr );
return r;
}
if (gszLogFile) if (gszLogFile)
package->log_file = CreateFileW( gszLogFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, package->log_file = CreateFileW( gszLogFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );

View file

@ -83,15 +83,14 @@ void MSI_CloseRecord( MSIOBJECTHDR *arg )
MSIRECORD *MSI_CreateRecord( UINT cParams ) MSIRECORD *MSI_CreateRecord( UINT cParams )
{ {
MSIRECORD *rec; MSIRECORD *rec;
UINT len;
TRACE("%d\n", cParams); TRACE("%d\n", cParams);
if( cParams>65535 ) if( cParams>65535 )
return NULL; return NULL;
len = sizeof (MSIRECORD) + sizeof (MSIFIELD)*cParams; rec = alloc_msiobject( MSIHANDLETYPE_RECORD, FIELD_OFFSET(MSIRECORD, fields[cParams + 1]),
rec = alloc_msiobject( MSIHANDLETYPE_RECORD, len, MSI_CloseRecord ); MSI_CloseRecord );
if( rec ) if( rec )
rec->count = cParams; rec->count = cParams;
return rec; return rec;

View file

@ -566,12 +566,12 @@ UINT MSIREG_OpenUserPatchesKey(LPCWSTR szPatch, HKEY *key, BOOL create)
return RegOpenKeyW(HKEY_CURRENT_USER, keypath, key); return RegOpenKeyW(HKEY_CURRENT_USER, keypath, key);
} }
UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, MSIINSTALLCONTEXT context, HKEY *key, BOOL create) UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, LPCWSTR szUserSid, MSIINSTALLCONTEXT context,
HKEY *key, BOOL create)
{ {
LPWSTR usersid;
HKEY root = HKEY_LOCAL_MACHINE; HKEY root = HKEY_LOCAL_MACHINE;
REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS; REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
WCHAR squished_pc[GUID_SIZE], keypath[MAX_PATH]; WCHAR squished_pc[GUID_SIZE], keypath[MAX_PATH], *usersid = NULL;
if (!squash_guid(szProduct, squished_pc)) return ERROR_FUNCTION_FAILED; if (!squash_guid(szProduct, squished_pc)) return ERROR_FUNCTION_FAILED;
TRACE("%s squished %s\n", debugstr_w(szProduct), debugstr_w(squished_pc)); TRACE("%s squished %s\n", debugstr_w(szProduct), debugstr_w(squished_pc));
@ -589,12 +589,16 @@ UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, MSIINSTALLCONTEXT context, HKEY *
} }
else else
{ {
if (!(usersid = get_user_sid())) if (!szUserSid)
{ {
ERR("Failed to retrieve user SID\n"); if (!(usersid = get_user_sid()))
return ERROR_FUNCTION_FAILED; {
ERR("Failed to retrieve user SID\n");
return ERROR_FUNCTION_FAILED;
}
szUserSid = usersid;
} }
sprintfW(keypath, szInstaller_LocalManagedFeat_fmt, usersid, squished_pc); sprintfW(keypath, szInstaller_LocalManagedFeat_fmt, szUserSid, squished_pc);
LocalFree(usersid); LocalFree(usersid);
} }
if (create) return RegCreateKeyExW(root, keypath, 0, NULL, 0, access, NULL, key, NULL); if (create) return RegCreateKeyExW(root, keypath, 0, NULL, 0, access, NULL, key, NULL);
@ -628,11 +632,11 @@ static UINT MSIREG_OpenInstallerFeaturesKey(LPCWSTR szProduct, HKEY *key, BOOL c
return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key); return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
} }
UINT MSIREG_OpenUserDataFeaturesKey(LPCWSTR szProduct, MSIINSTALLCONTEXT context, HKEY *key, BOOL create) UINT MSIREG_OpenUserDataFeaturesKey(LPCWSTR szProduct, LPCWSTR szUserSid, MSIINSTALLCONTEXT context,
HKEY *key, BOOL create)
{ {
LPWSTR usersid;
REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS; REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
WCHAR squished_pc[GUID_SIZE], keypath[0x200]; WCHAR squished_pc[GUID_SIZE], keypath[0x200], *usersid = NULL;
if (!squash_guid(szProduct, squished_pc)) return ERROR_FUNCTION_FAILED; if (!squash_guid(szProduct, squished_pc)) return ERROR_FUNCTION_FAILED;
TRACE("%s squished %s\n", debugstr_w(szProduct), debugstr_w(squished_pc)); TRACE("%s squished %s\n", debugstr_w(szProduct), debugstr_w(squished_pc));
@ -643,12 +647,16 @@ UINT MSIREG_OpenUserDataFeaturesKey(LPCWSTR szProduct, MSIINSTALLCONTEXT context
} }
else else
{ {
if (!(usersid = get_user_sid())) if (!szUserSid)
{ {
ERR("Failed to retrieve user SID\n"); if (!(usersid = get_user_sid()))
return ERROR_FUNCTION_FAILED; {
ERR("Failed to retrieve user SID\n");
return ERROR_FUNCTION_FAILED;
}
szUserSid = usersid;
} }
sprintfW(keypath, szUserDataFeatures_fmt, usersid, squished_pc); sprintfW(keypath, szUserDataFeatures_fmt, szUserSid, squished_pc);
LocalFree(usersid); LocalFree(usersid);
} }
if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL); if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);

View file

@ -204,6 +204,7 @@ static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, U
if (FAILED(hr)) if (FAILED(hr))
{ {
WARN("failed to open stream: %08x\n", hr); WARN("failed to open stream: %08x\n", hr);
msi_free(stream);
goto done; goto done;
} }

View file

@ -928,7 +928,7 @@ static UINT parse_prop( LPCWSTR prop, LPCWSTR value, UINT *pid, INT *int_value,
UINT msi_add_suminfo( MSIDATABASE *db, LPWSTR **records, int num_records, int num_columns ) UINT msi_add_suminfo( MSIDATABASE *db, LPWSTR **records, int num_records, int num_columns )
{ {
UINT r = ERROR_FUNCTION_FAILED; UINT r = ERROR_FUNCTION_FAILED;
DWORD i, j; int i, j;
MSISUMMARYINFO *si; MSISUMMARYINFO *si;
si = MSI_GetSummaryInformationW( db->storage, num_records * (num_columns / 2) ); si = MSI_GetSummaryInformationW( db->storage, num_records * (num_columns / 2) );

View file

@ -774,7 +774,7 @@ static UINT WHERE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
JOINTABLE *table = wv->tables; JOINTABLE *table = wv->tables;
UINT *rows; UINT *rows;
JOINTABLE **ordered_tables; JOINTABLE **ordered_tables;
int i = 0; UINT i = 0;
TRACE("%p %p\n", wv, record); TRACE("%p %p\n", wv, record);
@ -1056,7 +1056,7 @@ static UINT WHERE_sort(struct tagMSIVIEW *view, column_info *columns)
column_info *column = columns; column_info *column = columns;
MSIORDERINFO *orderinfo; MSIORDERINFO *orderinfo;
UINT r, count = 0; UINT r, count = 0;
int i; UINT i;
TRACE("%p %p\n", view, columns); TRACE("%p %p\n", view, columns);
@ -1072,7 +1072,7 @@ static UINT WHERE_sort(struct tagMSIVIEW *view, column_info *columns)
if (count == 0) if (count == 0)
return ERROR_SUCCESS; return ERROR_SUCCESS;
orderinfo = msi_alloc(sizeof(MSIORDERINFO) + (count - 1) * sizeof(union ext_column)); orderinfo = msi_alloc(FIELD_OFFSET(MSIORDERINFO, columns[count]));
if (!orderinfo) if (!orderinfo)
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;

View file

@ -539,6 +539,10 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR, LPCSTR);
INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR, LPCWSTR); INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR, LPCWSTR);
#define MsiQueryFeatureState WINELIB_NAME_AW(MsiQueryFeatureState) #define MsiQueryFeatureState WINELIB_NAME_AW(MsiQueryFeatureState)
UINT WINAPI MsiQueryFeatureStateExA(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
UINT WINAPI MsiQueryFeatureStateExW(LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, LPCWSTR, INSTALLSTATE*);
#define MsiQueryFeatureStateEx WINELIB_NAME_AW(MsiQueryFeatureStateEx)
UINT WINAPI MsiGetFeatureInfoA(MSIHANDLE, LPCSTR, LPDWORD, LPSTR, LPDWORD, LPSTR, LPDWORD); UINT WINAPI MsiGetFeatureInfoA(MSIHANDLE, LPCSTR, LPDWORD, LPSTR, LPDWORD, LPSTR, LPDWORD);
UINT WINAPI MsiGetFeatureInfoW(MSIHANDLE, LPCWSTR, LPDWORD, LPWSTR, LPDWORD, LPWSTR, LPDWORD); UINT WINAPI MsiGetFeatureInfoW(MSIHANDLE, LPCWSTR, LPDWORD, LPWSTR, LPDWORD, LPWSTR, LPDWORD);
#define MsiGetFeatureInfo WINELIB_NAME_AW(MsiGetFeatureInfo) #define MsiGetFeatureInfo WINELIB_NAME_AW(MsiGetFeatureInfo)

View file

@ -104,7 +104,7 @@ reactos/dll/win32/msg711.acm # Synced to Wine-1.5.19
reactos/dll/win32/msgsm32.acm # Synced to Wine-1.5.4 reactos/dll/win32/msgsm32.acm # Synced to Wine-1.5.4
reactos/dll/win32/mshtml # Autosync reactos/dll/win32/mshtml # Autosync
reactos/dll/win32/mshtml.tlb # Synced to Wine-1.5.19 reactos/dll/win32/mshtml.tlb # Synced to Wine-1.5.19
reactos/dll/win32/msi # Synced to Wine-1.5.19 reactos/dll/win32/msi # Synced to Wine-1.5.26
reactos/dll/win32/msimg32 # Synced to Wine-1.5.19 reactos/dll/win32/msimg32 # Synced to Wine-1.5.19
reactos/dll/win32/msimtf # Synced to Wine-1.5.19 reactos/dll/win32/msimtf # Synced to Wine-1.5.19
reactos/dll/win32/msisip # Synced to Wine-1.5.19 reactos/dll/win32/msisip # Synced to Wine-1.5.19