* 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;
}
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 );

View file

@ -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,

View file

@ -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;

View file

@ -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 );

View file

@ -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);

View file

@ -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;

View file

@ -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)

View file

@ -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 */

View file

@ -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 );

View file

@ -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;

View file

@ -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);

View file

@ -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;
}

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 r = ERROR_FUNCTION_FAILED;
DWORD i, j;
int i, j;
MSISUMMARYINFO *si;
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;
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;

View file

@ -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)

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/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