static UINT msi_check_transform_applicable( MSIPACKAGE *package, IStorage *patch )
{
- WCHAR szProductCode[] = { 'P','r','o','d','u','c','t','C','o','d','e',0 };
- LPWSTR prod_code, patch_product;
- UINT ret;
+ static const WCHAR szProductCode[] =
+ { 'P','r','o','d','u','c','t','C','o','d','e',0 };
+ static const WCHAR szSystemLanguageID[] =
+ { 'S','y','s','t','e','m','L','a','n','g','u','a','g','e','I','D',0 };
+
+ LPWSTR prod_code, patch_product, langid = NULL, template = NULL;
+ UINT ret = ERROR_FUNCTION_FAILED;
prod_code = msi_dup_property( package, szProductCode );
patch_product = msi_get_suminfo_product( patch );
TRACE("db = %s patch = %s\n", debugstr_w(prod_code), debugstr_w(patch_product));
if ( strstrW( patch_product, prod_code ) )
- ret = ERROR_SUCCESS;
- else
- ret = ERROR_FUNCTION_FAILED;
+ {
+ static const WCHAR zero[] = {'0',0};
+ MSISUMMARYINFO *si;
+ const WCHAR *p;
+
+ si = MSI_GetSummaryInformationW( patch, 0 );
+ if (!si)
+ {
+ ERR("no summary information!\n");
+ goto end;
+ }
+
+ template = msi_suminfo_dup_string( si, PID_TEMPLATE );
+ if (!template)
+ {
+ ERR("no template property!\n");
+ msiobj_release( &si->hdr );
+ goto end;
+ }
+
+ if (!template[0])
+ {
+ ret = ERROR_SUCCESS;
+ msiobj_release( &si->hdr );
+ goto end;
+ }
+
+ langid = msi_dup_property( package, szSystemLanguageID );
+ if (!langid)
+ {
+ msiobj_release( &si->hdr );
+ goto end;
+ }
+
+ p = strchrW( template, ';' );
+ if (p && (!strcmpW( p + 1, langid ) || !strcmpW( p + 1, zero )))
+ {
+ TRACE("applicable transform\n");
+ ret = ERROR_SUCCESS;
+ }
+
+ /* FIXME: check platform */
+
+ msiobj_release( &si->hdr );
+ }
+end:
msi_free( patch_product );
msi_free( prod_code );
+ msi_free( template );
+ msi_free( langid );
return ret;
}
return ERROR_SUCCESS;
}
-static UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si )
+UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si )
{
static const WCHAR szProdCode[] = { 'P','r','o','d','u','c','t','C','o','d','e',0 };
LPWSTR guid_list, *guids, product_code;
static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};
static const WCHAR szAction[] = {'A','C','T','I','O','N',0};
static const WCHAR szInstall[] = {'I','N','S','T','A','L','L',0};
+ static const WCHAR szReinstall[] = {'R','E','I','N','S','T','A','L','L',0};
+ static const WCHAR szInstalled[] = {'I','n','s','t','a','l','l','e','d',0};
+ static const WCHAR szAll[] = {'A','L','L',0};
MSI_SetPropertyW(package, szAction, szInstall);
msi_apply_transforms( package );
msi_apply_patches( package );
+ if (!szCommandLine && msi_get_property_int( package, szInstalled, 0 ))
+ {
+ TRACE("setting reinstall property\n");
+ MSI_SetPropertyW( package, szReinstall, szAll );
+ }
+
/* properties may have been added by a transform */
msi_clone_properties( package );
msi_set_context( package );
/* finish up running custom actions */
ACTION_FinishCustomActions(package);
+ if (rc == ERROR_SUCCESS && package->need_reboot)
+ return ERROR_SUCCESS_REBOOT_REQUIRED;
+
return rc;
}
static UINT ITERATE_Actions(MSIRECORD *row, LPVOID param)
{
- iterate_action_param *iap= (iterate_action_param*)param;
+ iterate_action_param *iap = param;
UINT rc;
LPCWSTR cond, action;
static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param)
{
- MSIPACKAGE *package = (MSIPACKAGE*)param;
+ MSIPACKAGE *package = param;
LPCWSTR dir;
LPWSTR full_path;
MSIRECORD *uirow;
static UINT iterate_load_featurecomponents(MSIRECORD *row, LPVOID param)
{
- _ilfs* ilfs= (_ilfs*)param;
+ _ilfs* ilfs = param;
LPCWSTR component;
MSICOMPONENT *comp;
static UINT load_feature(MSIRECORD * row, LPVOID param)
{
- MSIPACKAGE* package = (MSIPACKAGE*)param;
+ MSIPACKAGE* package = param;
MSIFEATURE* feature;
static const WCHAR Query1[] =
{'S','E','L','E','C','T',' ',
static UINT find_feature_children(MSIRECORD * row, LPVOID param)
{
- MSIPACKAGE* package = (MSIPACKAGE*)param;
+ MSIPACKAGE* package = param;
MSIFEATURE *parent, *child;
child = find_feature_by_name( package, MSI_RecordGetString( row, 1 ) );
static UINT load_file(MSIRECORD *row, LPVOID param)
{
- MSIPACKAGE* package = (MSIPACKAGE*)param;
+ MSIPACKAGE* package = param;
LPCWSTR component;
MSIFILE *file;
{
static const WCHAR all[]={'A','L','L',0};
static const WCHAR remove[] = {'R','E','M','O','V','E',0};
+ static const WCHAR reinstall[] = {'R','E','I','N','S','T','A','L','L',0};
LPWSTR override;
MSIFEATURE *feature;
(feature->Level <= 0 || feature->Level > level))
continue;
+ if (!strcmpW(property, reinstall)) state = feature->Installed;
+
if (strcmpiW(override,all)==0)
msi_feature_set_state(package, feature, state);
else
{'R','E','M','O','V','E',0};
static const WCHAR szReinstall[] =
{'R','E','I','N','S','T','A','L','L',0};
+ static const WCHAR szAdvertise[] =
+ {'A','D','V','E','R','T','I','S','E',0};
BOOL override = FALSE;
MSICOMPONENT* component;
MSIFEATURE *feature;
/* ok here is the _real_ rub
* all these activation/deactivation things happen in order and things
* later on the list override things earlier on the list.
- * 1) INSTALLLEVEL processing
- * 2) ADDLOCAL
- * 3) REMOVE
- * 4) ADDSOURCE
- * 5) ADDDEFAULT
- * 6) REINSTALL
+ * 0) INSTALLLEVEL processing
+ * 1) ADDLOCAL
+ * 2) REMOVE
+ * 3) ADDSOURCE
+ * 4) ADDDEFAULT
+ * 5) REINSTALL
+ * 6) ADVERTISE
* 7) COMPADDLOCAL
* 8) COMPADDSOURCE
* 9) FILEADDLOCAL
override |= process_state_property(package, level, szAddLocal, INSTALLSTATE_LOCAL);
override |= process_state_property(package, level, szRemove, INSTALLSTATE_ABSENT);
override |= process_state_property(package, level, szAddSource, INSTALLSTATE_SOURCE);
- override |= process_state_property(package, level, szReinstall, INSTALLSTATE_LOCAL);
+ override |= process_state_property(package, level, szReinstall, INSTALLSTATE_UNKNOWN);
+ override |= process_state_property(package, level, szAdvertise, INSTALLSTATE_ADVERTISED);
if (!override)
{
static UINT ITERATE_CostFinalizeDirectories(MSIRECORD *row, LPVOID param)
{
- MSIPACKAGE *package = (MSIPACKAGE*)param;
+ MSIPACKAGE *package = param;
LPCWSTR name;
LPWSTR path;
MSIFOLDER *f;
static UINT ITERATE_CostFinalizeConditions(MSIRECORD *row, LPVOID param)
{
- MSIPACKAGE *package = (MSIPACKAGE*)param;
+ MSIPACKAGE *package = param;
LPCWSTR name;
MSIFEATURE *feature;
static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
{
- MSIPACKAGE *package = (MSIPACKAGE*)param;
+ MSIPACKAGE *package = param;
static const WCHAR szHCR[] =
{'H','K','E','Y','_','C','L','A','S','S','E','S','_',
'R','O','O','T','\\',0};
static UINT ITERATE_LaunchConditions(MSIRECORD *row, LPVOID param)
{
- MSIPACKAGE* package = (MSIPACKAGE*)param;
+ MSIPACKAGE* package = param;
LPCWSTR cond = NULL;
LPCWSTR message = NULL;
UINT r;
static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param)
{
- MSIPACKAGE* package = (MSIPACKAGE*)param;
+ MSIPACKAGE* package = param;
LPCWSTR component;
MSICOMPONENT *comp;
MSIFILE *file;
static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param)
{
- MSIPACKAGE *package = (MSIPACKAGE*)param;
+ MSIPACKAGE *package = param;
LPWSTR target_file, target_folder, filename;
LPCWSTR buffer, extension;
MSICOMPONENT *comp;
return ERROR_SUCCESS;
res = CoInitialize( NULL );
- if (FAILED (res))
- {
- ERR("CoInitialize failed\n");
- return ERROR_FUNCTION_FAILED;
- }
rc = MSI_IterateRecords(view, NULL, ITERATE_CreateShortcuts, package);
msiobj_release(&view->hdr);
- CoUninitialize();
+ if (SUCCEEDED(res))
+ CoUninitialize();
return rc;
}
static UINT ITERATE_PublishIcon(MSIRECORD *row, LPVOID param)
{
- MSIPACKAGE* package = (MSIPACKAGE*)param;
+ MSIPACKAGE* package = param;
HANDLE the_file;
LPWSTR FilePath;
LPCWSTR FileName;
langid = msi_get_property_int(package, szProductLanguage, 0);
msi_reg_set_val_dword(hkey, INSTALLPROPERTY_LANGUAGEW, langid);
- ptr = strrchrW(package->PackagePath, '\\' ) + 1;
- msi_reg_set_val_str(hkey, INSTALLPROPERTY_PACKAGENAMEW, ptr);
-
/* FIXME */
msi_reg_set_val_dword(hkey, INSTALLPROPERTY_AUTHORIZED_LUA_APPW, 0);
if (!msi_check_publish(package))
return ERROR_SUCCESS;
- rc = MSIREG_OpenProductKey(package->ProductCode, package->Context,
+ rc = MSIREG_OpenProductKey(package->ProductCode, NULL, package->Context,
&hukey, TRUE);
if (rc != ERROR_SUCCESS)
goto end;
static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param)
{
- MSIPACKAGE *package = (MSIPACKAGE*)param;
+ MSIPACKAGE *package = param;
LPCWSTR component, section, key, value, identifier, dirproperty;
LPWSTR deformated_section, deformated_key, deformated_value;
LPWSTR folder, filename, fullname = NULL;
static UINT ITERATE_SelfRegModules(MSIRECORD *row, LPVOID param)
{
- MSIPACKAGE *package = (MSIPACKAGE*)param;
+ MSIPACKAGE *package = param;
LPCWSTR filename;
LPWSTR FullName;
MSIFILE *file;
static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param)
{
- MSIPACKAGE *package = (MSIPACKAGE*)param;
+ MSIPACKAGE *package = param;
LPCWSTR compgroupid=NULL;
LPCWSTR feature=NULL;
LPCWSTR text = NULL;
static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param)
{
- MSIPACKAGE *package = (MSIPACKAGE*)param;
+ MSIPACKAGE *package = param;
MSIRECORD *row;
MSIFILE *file;
SC_HANDLE hscm, service = NULL;
static UINT ITERATE_StartService(MSIRECORD *rec, LPVOID param)
{
- MSIPACKAGE *package = (MSIPACKAGE *)param;
+ MSIPACKAGE *package = param;
MSICOMPONENT *comp;
SC_HANDLE scm, service = NULL;
LPCWSTR name, *vector = NULL;
static UINT ITERATE_StopService(MSIRECORD *rec, LPVOID param)
{
- MSIPACKAGE *package = (MSIPACKAGE *)param;
+ MSIPACKAGE *package = param;
MSICOMPONENT *comp;
SERVICE_STATUS status;
SERVICE_STATUS_PROCESS ssp;
static UINT ITERATE_InstallODBCDriver( MSIRECORD *rec, LPVOID param )
{
- MSIPACKAGE *package = (MSIPACKAGE*)param;
+ MSIPACKAGE *package = param;
LPWSTR driver, driver_path, ptr;
WCHAR outpath[MAX_PATH];
MSIFILE *driver_file, *setup_file;
static UINT ITERATE_InstallODBCTranslator( MSIRECORD *rec, LPVOID param )
{
- MSIPACKAGE *package = (MSIPACKAGE*)param;
+ MSIPACKAGE *package = param;
LPWSTR translator, translator_path, ptr;
WCHAR outpath[MAX_PATH];
MSIFILE *translator_file, *setup_file;
}
}
- if (!*flags ||
- check_flag_combo(*flags, ENV_ACT_SETALWAYS | ENV_ACT_SETABSENT) ||
+ if (check_flag_combo(*flags, ENV_ACT_SETALWAYS | ENV_ACT_SETABSENT) ||
check_flag_combo(*flags, ENV_ACT_REMOVEMATCH | ENV_ACT_SETABSENT) ||
check_flag_combo(*flags, ENV_ACT_REMOVEMATCH | ENV_ACT_SETALWAYS) ||
check_flag_combo(*flags, ENV_ACT_SETABSENT | ENV_MOD_MASK))
return ERROR_FUNCTION_FAILED;
}
+ if (!*flags)
+ *flags = ENV_ACT_SETALWAYS | ENV_ACT_REMOVE;
+
return ERROR_SUCCESS;
}
name = MSI_RecordGetString(rec, 2);
value = MSI_RecordGetString(rec, 3);
+ TRACE("name %s value %s\n", debugstr_w(name), debugstr_w(value));
+
res = env_set_flags(&name, &value, &flags);
if (res != ERROR_SUCCESS)
goto done;
{
file = LIST_ENTRY(list_head(&files.entry), FILE_LIST, entry);
- msi_move_file((LPCWSTR)file->source, (LPCWSTR)file->dest, options);
+ msi_move_file(file->source, file->dest, options);
list_remove(&file->entry);
free_file_entry(file);
static UINT parse_assembly_name(MSIRECORD *rec, LPVOID param)
{
- ASSEMBLY_NAME *asmname = (ASSEMBLY_NAME *)param;
+ ASSEMBLY_NAME *asmname = param;
LPCWSTR name = MSI_RecordGetString(rec, 2);
LPWSTR val = msi_dup_record_field(rec, 3);
static const WCHAR PublicKeyToken[] = {
'P','u','b','l','i','c','K','e','y','T','o','k','e','n',0};
- if (!lstrcmpW(name, Name))
+ if (!strcmpiW(name, Name))
asmname->name = val;
- else if (!lstrcmpW(name, Version))
+ else if (!strcmpiW(name, Version))
asmname->version = val;
- else if (!lstrcmpW(name, Culture))
+ else if (!strcmpiW(name, Culture))
asmname->culture = val;
- else if (!lstrcmpW(name, PublicKeyToken))
+ else if (!strcmpiW(name, PublicKeyToken))
asmname->pubkeytoken = val;
else
msi_free(val);
found = (asminfo.dwAssemblyFlags == ASSEMBLYINFO_FLAG_INSTALLED);
done:
- msiobj_release(&view->hdr);
msi_free(disp);
msi_free(name.name);
msi_free(name.version);
static UINT load_assembly(MSIRECORD *rec, LPVOID param)
{
- ASSEMBLY_LIST *list = (ASSEMBLY_LIST *)param;
+ ASSEMBLY_LIST *list = param;
MSIASSEMBLY *assembly;
assembly = msi_alloc_zero(sizeof(MSIASSEMBLY));
assembly->manifest = strdupW(MSI_RecordGetString(rec, 3));
assembly->application = strdupW(MSI_RecordGetString(rec, 4));
assembly->attributes = MSI_RecordGetInteger(rec, 5);
- assembly->installed = check_assembly_installed(list->package->db,
- list->cache,
- assembly->component);
+
+ if (assembly->application)
+ {
+ WCHAR version[24];
+ DWORD size = sizeof(version)/sizeof(WCHAR);
+
+ /* FIXME: we should probably check the manifest file here */
+
+ if (!MsiGetFileVersionW(assembly->file->TargetPath, version, &size, NULL, NULL) &&
+ (!assembly->file->Version || strcmpW(version, assembly->file->Version) >= 0))
+ {
+ assembly->installed = TRUE;
+ }
+ }
+ else
+ assembly->installed = check_assembly_installed(list->package->db,
+ list->cache,
+ assembly->component);
list_add_head(list->assemblies, &assembly->entry);
return ERROR_SUCCESS;
{
MSIASSEMBLY *assembly;
WCHAR temppath[MAX_PATH];
- struct list *assemblies = (struct list *)user;
+ struct list *assemblies = user;
UINT r;
if (!find_assembly(assemblies, file, &assembly))