mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 06:02:07 +00:00
[MSI]
* Sync with Wine 1.5.26. svn path=/trunk/; revision=58665
This commit is contained in:
parent
27a7122a84
commit
0b598500b3
16 changed files with 329 additions and 308 deletions
|
@ -688,18 +688,6 @@ MSIFILE *msi_get_loaded_file( MSIPACKAGE *package, const WCHAR *key )
|
|||
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 *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, szAdvertise, INSTALLSTATE_ADVERTISED );
|
||||
|
||||
if (ret)
|
||||
if (ret && !package->full_reinstall)
|
||||
msi_set_property( package->db, szPreselected, szOne, -1 );
|
||||
|
||||
return ret;
|
||||
|
@ -4856,12 +4844,12 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
|
|||
if (!msi_check_publish(package))
|
||||
return ERROR_SUCCESS;
|
||||
|
||||
rc = MSIREG_OpenFeaturesKey(package->ProductCode, package->Context,
|
||||
rc = MSIREG_OpenFeaturesKey(package->ProductCode, NULL, package->Context,
|
||||
&hkey, TRUE);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
goto end;
|
||||
|
||||
rc = MSIREG_OpenUserDataFeaturesKey(package->ProductCode, package->Context,
|
||||
rc = MSIREG_OpenUserDataFeaturesKey(package->ProductCode, NULL, package->Context,
|
||||
&userdata, TRUE);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
goto end;
|
||||
|
@ -4961,7 +4949,7 @@ static UINT msi_unpublish_feature(MSIPACKAGE *package, MSIFEATURE *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);
|
||||
if (r == ERROR_SUCCESS)
|
||||
{
|
||||
|
@ -4969,7 +4957,7 @@ static UINT msi_unpublish_feature(MSIPACKAGE *package, MSIFEATURE *feature)
|
|||
RegCloseKey(hkey);
|
||||
}
|
||||
|
||||
r = MSIREG_OpenUserDataFeaturesKey(package->ProductCode, package->Context,
|
||||
r = MSIREG_OpenUserDataFeaturesKey(package->ProductCode, NULL, package->Context,
|
||||
&hkey, FALSE);
|
||||
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};
|
||||
MSIPACKAGE *package = param;
|
||||
const WCHAR *property = MSI_RecordGetString( rec, 7 );
|
||||
int attrs = MSI_RecordGetInteger( rec, 5 );
|
||||
UINT len = sizeof(fmtW)/sizeof(fmtW[0]);
|
||||
WCHAR *product, *features, *cmd;
|
||||
STARTUPINFOW si;
|
||||
PROCESS_INFORMATION info;
|
||||
BOOL ret;
|
||||
|
||||
if (attrs & msidbUpgradeAttributesOnlyDetect) return ERROR_SUCCESS;
|
||||
if (!(product = msi_dup_property( package->db, property ))) return ERROR_SUCCESS;
|
||||
|
||||
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");
|
||||
msi_set_property( package->db, szReinstall, szAll, -1 );
|
||||
package->full_reinstall = 1;
|
||||
}
|
||||
|
||||
/* properties may have been added by a transform */
|
||||
msi_clone_properties( package );
|
||||
msi_set_original_database_property( package->db, szPackagePath );
|
||||
|
||||
msi_parse_command_line( package, szCommandLine, FALSE );
|
||||
msi_adjust_privilege_properties( package );
|
||||
|
|
|
@ -1207,11 +1207,7 @@ static HRESULT view_invoke(
|
|||
V_VT(pVarResult) = VT_DISPATCH;
|
||||
if ((ret = MsiViewFetch(This->msiHandle, &msiHandle)) == ERROR_SUCCESS)
|
||||
{
|
||||
IDispatch *dispatch = NULL;
|
||||
|
||||
if (SUCCEEDED(hr = create_record(msiHandle, &dispatch)))
|
||||
V_DISPATCH(pVarResult) = dispatch;
|
||||
else
|
||||
if (FAILED(hr = create_record(msiHandle, &V_DISPATCH(pVarResult))))
|
||||
ERR("Failed to create Record object, hresult 0x%08x\n", hr);
|
||||
}
|
||||
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 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;
|
||||
LPWSTR szNewString = NULL;
|
||||
DWORD dwNewSize = 0;
|
||||
|
@ -1688,7 +1684,6 @@ static HRESULT InstallerImpl_CreateRecord(WORD wFlags,
|
|||
HRESULT hr;
|
||||
VARIANTARG varg0;
|
||||
MSIHANDLE hrec;
|
||||
IDispatch* dispatch;
|
||||
|
||||
if (!(wFlags & DISPATCH_METHOD))
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
|
@ -1704,11 +1699,7 @@ static HRESULT InstallerImpl_CreateRecord(WORD wFlags,
|
|||
if (!hrec)
|
||||
return DISP_E_EXCEPTION;
|
||||
|
||||
hr = create_record(hrec, &dispatch);
|
||||
if (SUCCEEDED(hr))
|
||||
V_DISPATCH(pVarResult) = dispatch;
|
||||
|
||||
return hr;
|
||||
return create_record(hrec, &V_DISPATCH(pVarResult));
|
||||
}
|
||||
|
||||
static HRESULT InstallerImpl_OpenPackage(AutomationObject* This,
|
||||
|
|
|
@ -622,43 +622,6 @@ static DWORD WINAPI DllThread( LPVOID arg )
|
|||
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(
|
||||
MSIPACKAGE *package, INT type, LPCWSTR source, LPCWSTR target, LPCWSTR action )
|
||||
{
|
||||
|
@ -693,60 +656,8 @@ static msi_custom_action_info *do_msidbCustomActionTypeDll(
|
|||
return info;
|
||||
}
|
||||
|
||||
static msi_custom_action_info *do_msidbCAConcurrentInstall(
|
||||
MSIPACKAGE *package, INT type, LPCWSTR source, LPCWSTR target, LPCWSTR 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)
|
||||
static UINT HANDLE_CustomType1( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
|
||||
INT type, const WCHAR *action )
|
||||
{
|
||||
msi_custom_action_info *info;
|
||||
MSIBINARY *binary;
|
||||
|
@ -828,8 +739,8 @@ static HANDLE execute_command( const WCHAR *app, WCHAR *arg, const WCHAR *dir )
|
|||
return info.hProcess;
|
||||
}
|
||||
|
||||
static UINT HANDLE_CustomType2(MSIPACKAGE *package, LPCWSTR source,
|
||||
LPCWSTR target, const INT type, LPCWSTR action)
|
||||
static UINT HANDLE_CustomType2( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
|
||||
INT type, const WCHAR *action )
|
||||
{
|
||||
MSIBINARY *binary;
|
||||
HANDLE handle;
|
||||
|
@ -846,8 +757,8 @@ static UINT HANDLE_CustomType2(MSIPACKAGE *package, LPCWSTR source,
|
|||
return wait_process_handle( package, type, handle, action );
|
||||
}
|
||||
|
||||
static UINT HANDLE_CustomType17(MSIPACKAGE *package, LPCWSTR source,
|
||||
LPCWSTR target, const INT type, LPCWSTR action)
|
||||
static UINT HANDLE_CustomType17( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
|
||||
INT type, const WCHAR *action )
|
||||
{
|
||||
msi_custom_action_info *info;
|
||||
MSIFILE *file;
|
||||
|
@ -865,8 +776,8 @@ static UINT HANDLE_CustomType17(MSIPACKAGE *package, LPCWSTR source,
|
|||
return wait_thread_handle( info );
|
||||
}
|
||||
|
||||
static UINT HANDLE_CustomType18(MSIPACKAGE *package, LPCWSTR source,
|
||||
LPCWSTR target, const INT type, LPCWSTR action)
|
||||
static UINT HANDLE_CustomType18( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
|
||||
INT type, const WCHAR *action )
|
||||
{
|
||||
MSIFILE *file;
|
||||
HANDLE handle;
|
||||
|
@ -883,8 +794,8 @@ static UINT HANDLE_CustomType18(MSIPACKAGE *package, LPCWSTR source,
|
|||
return wait_process_handle( package, type, handle, action );
|
||||
}
|
||||
|
||||
static UINT HANDLE_CustomType19(MSIPACKAGE *package, LPCWSTR source,
|
||||
LPCWSTR target, const INT type, LPCWSTR action)
|
||||
static UINT HANDLE_CustomType19( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
|
||||
INT type, const WCHAR *action )
|
||||
{
|
||||
static const WCHAR query[] = {
|
||||
'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;
|
||||
}
|
||||
|
||||
static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source,
|
||||
LPCWSTR target, const INT type, LPCWSTR action)
|
||||
static UINT HANDLE_CustomType23( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
|
||||
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;
|
||||
HANDLE handle;
|
||||
|
@ -931,8 +886,8 @@ static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source,
|
|||
return wait_process_handle( package, type, handle, action );
|
||||
}
|
||||
|
||||
static UINT HANDLE_CustomType34(MSIPACKAGE *package, LPCWSTR source,
|
||||
LPCWSTR target, const INT type, LPCWSTR action)
|
||||
static UINT HANDLE_CustomType34( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
|
||||
INT type, const WCHAR *action )
|
||||
{
|
||||
const WCHAR *workingdir = NULL;
|
||||
HANDLE handle;
|
||||
|
@ -1032,8 +987,8 @@ static msi_custom_action_info *do_msidbCustomActionTypeScript(
|
|||
return info;
|
||||
}
|
||||
|
||||
static UINT HANDLE_CustomType37_38(MSIPACKAGE *package, LPCWSTR source,
|
||||
LPCWSTR target, const INT type, LPCWSTR action)
|
||||
static UINT HANDLE_CustomType37_38( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
|
||||
INT type, const WCHAR *action )
|
||||
{
|
||||
msi_custom_action_info *info;
|
||||
|
||||
|
@ -1043,8 +998,8 @@ static UINT HANDLE_CustomType37_38(MSIPACKAGE *package, LPCWSTR source,
|
|||
return wait_thread_handle( info );
|
||||
}
|
||||
|
||||
static UINT HANDLE_CustomType5_6(MSIPACKAGE *package, LPCWSTR source,
|
||||
LPCWSTR target, const INT type, LPCWSTR action)
|
||||
static UINT HANDLE_CustomType5_6( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
|
||||
INT type, const WCHAR *action )
|
||||
{
|
||||
static const WCHAR query[] = {
|
||||
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||
|
@ -1090,8 +1045,8 @@ done:
|
|||
return r;
|
||||
}
|
||||
|
||||
static UINT HANDLE_CustomType21_22(MSIPACKAGE *package, LPCWSTR source,
|
||||
LPCWSTR target, const INT type, LPCWSTR action)
|
||||
static UINT HANDLE_CustomType21_22( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
|
||||
INT type, const WCHAR *action )
|
||||
{
|
||||
msi_custom_action_info *info;
|
||||
MSIFILE *file;
|
||||
|
@ -1149,8 +1104,8 @@ done:
|
|||
return r;
|
||||
}
|
||||
|
||||
static UINT HANDLE_CustomType53_54(MSIPACKAGE *package, LPCWSTR source,
|
||||
LPCWSTR target, const INT type, LPCWSTR action)
|
||||
static UINT HANDLE_CustomType53_54( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
|
||||
INT type, const WCHAR *action )
|
||||
{
|
||||
msi_custom_action_info *info;
|
||||
WCHAR *prop;
|
||||
|
|
|
@ -696,7 +696,7 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control,
|
|||
else if ( !strcmpW( attribute, szProperty ) )
|
||||
{
|
||||
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 ) )
|
||||
{
|
||||
|
@ -1139,7 +1139,7 @@ static UINT msi_dialog_line_control( msi_dialog *dialog, MSIRECORD *rec )
|
|||
|
||||
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)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
|
@ -1808,7 +1808,6 @@ static void msi_mask_control_change( struct msi_maskedit_info *info )
|
|||
if( i == info->num_groups )
|
||||
{
|
||||
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_evaluate_control_conditions( info->dialog );
|
||||
}
|
||||
|
@ -3739,7 +3738,7 @@ msi_dialog *msi_dialog_create( MSIPACKAGE* package,
|
|||
msi_dialog_register_class();
|
||||
|
||||
/* 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 )
|
||||
return NULL;
|
||||
strcpyW( dialog->name, szDialogName );
|
||||
|
|
|
@ -447,6 +447,17 @@ static void unload_mspatch(void)
|
|||
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,
|
||||
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')
|
||||
GetTempPathW(MAX_PATH, temp_folder);
|
||||
|
||||
p = msi_get_loaded_filepatch(package, file);
|
||||
if (!p)
|
||||
{
|
||||
TRACE("unknown file in cabinet (%s)\n", debugstr_w(file));
|
||||
if (!(p = get_next_filepatch(package, file)) || !p->File->Component->Enabled)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GetTempFileNameW(temp_folder, NULL, 0, patch_path);
|
||||
|
||||
*path = strdupW(patch_path);
|
||||
|
|
|
@ -2922,6 +2922,123 @@ end:
|
|||
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.@]
|
||||
*/
|
||||
|
@ -2966,117 +3083,25 @@ end:
|
|||
*/
|
||||
INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
|
||||
{
|
||||
WCHAR squishProduct[33], comp[GUID_SIZE];
|
||||
GUID guid;
|
||||
LPWSTR components, p, parent_feature, path;
|
||||
UINT rc;
|
||||
HKEY hkey;
|
||||
INSTALLSTATE r;
|
||||
BOOL missing = FALSE;
|
||||
BOOL machine = FALSE;
|
||||
BOOL source = FALSE;
|
||||
UINT r;
|
||||
INSTALLSTATE state;
|
||||
WCHAR squashed[33];
|
||||
|
||||
TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
|
||||
|
||||
if (!szProduct || !szFeature)
|
||||
if (!szProduct || !szFeature || !squash_guid( szProduct, squashed ))
|
||||
return INSTALLSTATE_INVALIDARG;
|
||||
|
||||
if (!squash_guid( szProduct, squishProduct ))
|
||||
return INSTALLSTATE_INVALIDARG;
|
||||
r = query_feature_state( szProduct, squashed, NULL, MSIINSTALLCONTEXT_USERMANAGED, szFeature, &state );
|
||||
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,
|
||||
&hkey, FALSE) != ERROR_SUCCESS &&
|
||||
MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
|
||||
&hkey, FALSE) != ERROR_SUCCESS)
|
||||
{
|
||||
rc = MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
|
||||
&hkey, FALSE);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
return INSTALLSTATE_UNKNOWN;
|
||||
r = query_feature_state( szProduct, squashed, NULL, MSIINSTALLCONTEXT_MACHINE, szFeature, &state );
|
||||
if (r == ERROR_SUCCESS || r == ERROR_BAD_CONFIGURATION) return state;
|
||||
|
||||
machine = TRUE;
|
||||
}
|
||||
|
||||
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;
|
||||
return INSTALLSTATE_UNKNOWN;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
|
@ -3137,7 +3162,7 @@ static UINT get_file_version( const WCHAR *path, WCHAR *verbuf, DWORD *verlen,
|
|||
static const WCHAR szVersionResource[] = {'\\',0};
|
||||
static const WCHAR szVersionFormat[] = {'%','d','.','%','d','.','%','d','.','%','d',0};
|
||||
static const WCHAR szLangFormat[] = {'%','d',0};
|
||||
UINT ret = ERROR_SUCCESS;
|
||||
UINT ret = ERROR_MORE_DATA;
|
||||
DWORD len, error;
|
||||
LPVOID version;
|
||||
VS_FIXEDFILEINFO *ffi;
|
||||
|
@ -3148,6 +3173,7 @@ static UINT get_file_version( const WCHAR *path, WCHAR *verbuf, DWORD *verlen,
|
|||
{
|
||||
error = GetLastError();
|
||||
if (error == ERROR_BAD_PATHNAME) return ERROR_FILE_NOT_FOUND;
|
||||
if (error == ERROR_RESOURCE_DATA_NOT_FOUND) return ERROR_FILE_INVALID;
|
||||
return error;
|
||||
}
|
||||
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 );
|
||||
return GetLastError();
|
||||
}
|
||||
if (!verbuf && !verlen && !langbuf && !langlen)
|
||||
{
|
||||
msi_free( version );
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
if (verlen)
|
||||
{
|
||||
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) );
|
||||
if (verbuf) lstrcpynW( verbuf, tmp, *verlen );
|
||||
len = strlenW( tmp );
|
||||
if (len >= *verlen) ret = ERROR_MORE_DATA;
|
||||
if (*verlen > len) ret = ERROR_SUCCESS;
|
||||
*verlen = len;
|
||||
}
|
||||
else
|
||||
|
@ -3181,7 +3212,7 @@ static UINT get_file_version( const WCHAR *path, WCHAR *verbuf, DWORD *verlen,
|
|||
sprintfW( tmp, szLangFormat, *lang );
|
||||
if (langbuf) lstrcpynW( langbuf, tmp, *langlen );
|
||||
len = strlenW( tmp );
|
||||
if (len >= *langlen) ret = ERROR_MORE_DATA;
|
||||
if (*langlen > len) ret = ERROR_SUCCESS;
|
||||
*langlen = len;
|
||||
}
|
||||
else
|
||||
|
@ -3789,7 +3820,7 @@ UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
|
|||
|
||||
lstrcatW(path, installerW);
|
||||
|
||||
if (!CreateDirectoryW(path, NULL))
|
||||
if (!CreateDirectoryW(path, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
|
|
|
@ -244,8 +244,8 @@
|
|||
248 stdcall MsiGetProductInfoExW(wstr wstr long wstr ptr ptr)
|
||||
249 stdcall MsiQueryComponentStateA(str str long str ptr)
|
||||
250 stdcall MsiQueryComponentStateW(wstr wstr long wstr ptr)
|
||||
251 stub MsiQueryFeatureStateExA
|
||||
252 stub MsiQueryFeatureStateExW
|
||||
251 stdcall MsiQueryFeatureStateExA(str str long str ptr)
|
||||
252 stdcall MsiQueryFeatureStateExW(wstr wstr long wstr ptr)
|
||||
253 stdcall MsiDeterminePatchSequenceA(str str long long ptr)
|
||||
254 stdcall MsiDeterminePatchSequenceW(wstr wstr long long ptr)
|
||||
255 stdcall MsiSourceListAddSourceExA(str str long long str long)
|
||||
|
|
|
@ -338,6 +338,7 @@ typedef struct msi_dialog_tag msi_dialog;
|
|||
|
||||
enum platform
|
||||
{
|
||||
PLATFORM_UNKNOWN,
|
||||
PLATFORM_INTEL,
|
||||
PLATFORM_INTEL64,
|
||||
PLATFORM_X64,
|
||||
|
@ -414,6 +415,7 @@ typedef struct tagMSIPACKAGE
|
|||
unsigned char need_reboot_at_end : 1;
|
||||
unsigned char need_reboot_now : 1;
|
||||
unsigned char need_rollback : 1;
|
||||
unsigned char full_reinstall : 1;
|
||||
} MSIPACKAGE;
|
||||
|
||||
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_OpenProductKey(LPCWSTR szProduct, LPCWSTR szUserSid,
|
||||
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;
|
||||
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;
|
||||
extern UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create) DECLSPEC_HIDDEN;
|
||||
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 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 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 int msi_track_tempfile(MSIPACKAGE *package, const WCHAR *path) 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 WCHAR *msi_font_version_from_file(const 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 */
|
||||
|
||||
|
|
|
@ -158,7 +158,6 @@ void msi_free_action_script( MSIPACKAGE *package, UINT script )
|
|||
|
||||
static void free_package_structures( MSIPACKAGE *package )
|
||||
{
|
||||
INT i;
|
||||
struct list *item, *cursor;
|
||||
|
||||
LIST_FOR_EACH_SAFE( item, cursor, &package->features )
|
||||
|
@ -287,11 +286,14 @@ static void free_package_structures( MSIPACKAGE *package )
|
|||
|
||||
if (package->script)
|
||||
{
|
||||
INT i;
|
||||
UINT j;
|
||||
|
||||
for (i = 0; i < SCRIPT_MAX; i++)
|
||||
msi_free_action_script( package, i );
|
||||
|
||||
for (i = 0; i < package->script->UniqueActionsCount; i++)
|
||||
msi_free( package->script->UniqueActions[i] );
|
||||
for (j = 0; j < package->script->UniqueActionsCount; j++)
|
||||
msi_free( package->script->UniqueActions[j] );
|
||||
|
||||
msi_free( package->script->UniqueActions );
|
||||
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 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 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:
|
||||
|
@ -1024,6 +1028,7 @@ static VOID set_installer_properties(MSIPACKAGE *package)
|
|||
msi_free( computername );
|
||||
}
|
||||
}
|
||||
msi_set_property( package->db, szBrowseProperty, szInstallDir, -1 );
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
WCHAR *template, *p, *q;
|
||||
WCHAR *template, *p, *q, *platform;
|
||||
DWORD i, count;
|
||||
|
||||
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;
|
||||
}
|
||||
*p = 0;
|
||||
if ((q = strchrW( template, ',' ))) *q = 0;
|
||||
if (!template[0] || !strcmpW( template, szIntel ))
|
||||
package->platform = PLATFORM_INTEL;
|
||||
else if (!strcmpW( template, szIntel64 ))
|
||||
package->platform = PLATFORM_INTEL64;
|
||||
else if (!strcmpW( template, szX64 ) || !strcmpW( template, szAMD64 ))
|
||||
package->platform = PLATFORM_X64;
|
||||
else if (!strcmpW( template, szARM ))
|
||||
package->platform = PLATFORM_ARM;
|
||||
else
|
||||
platform = template;
|
||||
if ((q = strchrW( platform, ',' ))) *q = 0;
|
||||
package->platform = parse_platform( platform );
|
||||
while (package->platform == PLATFORM_UNKNOWN && q)
|
||||
{
|
||||
platform = q + 1;
|
||||
if ((q = strchrW( platform, ',' ))) *q = 0;
|
||||
package->platform = parse_platform( platform );
|
||||
}
|
||||
if (package->platform == PLATFORM_UNKNOWN)
|
||||
{
|
||||
WARN("unknown platform %s\n", debugstr_w(template));
|
||||
msi_free( template );
|
||||
|
@ -1514,6 +1528,28 @@ static UINT get_local_package( const WCHAR *filename, WCHAR *localfile )
|
|||
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)
|
||||
{
|
||||
static const WCHAR dotmsi[] = {'.','m','s','i',0};
|
||||
|
@ -1623,17 +1659,6 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
|
|||
return r;
|
||||
}
|
||||
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 );
|
||||
|
||||
while (1)
|
||||
|
@ -1660,6 +1685,12 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
|
|||
msi_clone_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)
|
||||
package->log_file = CreateFileW( gszLogFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||
|
|
|
@ -83,15 +83,14 @@ void MSI_CloseRecord( MSIOBJECTHDR *arg )
|
|||
MSIRECORD *MSI_CreateRecord( UINT cParams )
|
||||
{
|
||||
MSIRECORD *rec;
|
||||
UINT len;
|
||||
|
||||
TRACE("%d\n", cParams);
|
||||
|
||||
if( cParams>65535 )
|
||||
return NULL;
|
||||
|
||||
len = sizeof (MSIRECORD) + sizeof (MSIFIELD)*cParams;
|
||||
rec = alloc_msiobject( MSIHANDLETYPE_RECORD, len, MSI_CloseRecord );
|
||||
rec = alloc_msiobject( MSIHANDLETYPE_RECORD, FIELD_OFFSET(MSIRECORD, fields[cParams + 1]),
|
||||
MSI_CloseRecord );
|
||||
if( rec )
|
||||
rec->count = cParams;
|
||||
return rec;
|
||||
|
|
|
@ -566,12 +566,12 @@ UINT MSIREG_OpenUserPatchesKey(LPCWSTR szPatch, HKEY *key, BOOL create)
|
|||
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;
|
||||
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;
|
||||
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
|
||||
{
|
||||
if (!(usersid = get_user_sid()))
|
||||
if (!szUserSid)
|
||||
{
|
||||
ERR("Failed to retrieve user SID\n");
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
if (!(usersid = get_user_sid()))
|
||||
{
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
TRACE("%s squished %s\n", debugstr_w(szProduct), debugstr_w(squished_pc));
|
||||
|
@ -643,12 +647,16 @@ UINT MSIREG_OpenUserDataFeaturesKey(LPCWSTR szProduct, MSIINSTALLCONTEXT context
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!(usersid = get_user_sid()))
|
||||
if (!szUserSid)
|
||||
{
|
||||
ERR("Failed to retrieve user SID\n");
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
if (!(usersid = get_user_sid()))
|
||||
{
|
||||
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);
|
||||
}
|
||||
if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
|
||||
|
|
|
@ -204,6 +204,7 @@ static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, U
|
|||
if (FAILED(hr))
|
||||
{
|
||||
WARN("failed to open stream: %08x\n", hr);
|
||||
msi_free(stream);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 r = ERROR_FUNCTION_FAILED;
|
||||
DWORD i, j;
|
||||
int i, j;
|
||||
MSISUMMARYINFO *si;
|
||||
|
||||
si = MSI_GetSummaryInformationW( db->storage, num_records * (num_columns / 2) );
|
||||
|
|
|
@ -774,7 +774,7 @@ static UINT WHERE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
|
|||
JOINTABLE *table = wv->tables;
|
||||
UINT *rows;
|
||||
JOINTABLE **ordered_tables;
|
||||
int i = 0;
|
||||
UINT i = 0;
|
||||
|
||||
TRACE("%p %p\n", wv, record);
|
||||
|
||||
|
@ -1056,7 +1056,7 @@ static UINT WHERE_sort(struct tagMSIVIEW *view, column_info *columns)
|
|||
column_info *column = columns;
|
||||
MSIORDERINFO *orderinfo;
|
||||
UINT r, count = 0;
|
||||
int i;
|
||||
UINT i;
|
||||
|
||||
TRACE("%p %p\n", view, columns);
|
||||
|
||||
|
@ -1072,7 +1072,7 @@ static UINT WHERE_sort(struct tagMSIVIEW *view, column_info *columns)
|
|||
if (count == 0)
|
||||
return ERROR_SUCCESS;
|
||||
|
||||
orderinfo = msi_alloc(sizeof(MSIORDERINFO) + (count - 1) * sizeof(union ext_column));
|
||||
orderinfo = msi_alloc(FIELD_OFFSET(MSIORDERINFO, columns[count]));
|
||||
if (!orderinfo)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
|
|
|
@ -539,6 +539,10 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR, LPCSTR);
|
|||
INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR, LPCWSTR);
|
||||
#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 MsiGetFeatureInfoW(MSIHANDLE, LPCWSTR, LPDWORD, LPWSTR, LPDWORD, LPWSTR, LPDWORD);
|
||||
#define MsiGetFeatureInfo WINELIB_NAME_AW(MsiGetFeatureInfo)
|
||||
|
|
|
@ -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/mshtml # Autosync
|
||||
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/msimtf # Synced to Wine-1.5.19
|
||||
reactos/dll/win32/msisip # Synced to Wine-1.5.19
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue