{
MSIPATCHINFO *pi;
UINT r = ERROR_SUCCESS;
+ WCHAR *p;
pi = msi_alloc_zero( sizeof(MSIPATCHINFO) );
if (!pi)
return ERROR_OUTOFMEMORY;
}
+ p = pi->patchcode;
+ if (*p != '{')
+ {
+ msi_free( pi->patchcode );
+ msi_free( pi );
+ return ERROR_PATCH_PACKAGE_INVALID;
+ }
+
+ p = strchrW( p + 1, '}' );
+ if (!p)
+ {
+ msi_free( pi->patchcode );
+ msi_free( pi );
+ return ERROR_PATCH_PACKAGE_INVALID;
+ }
+
+ if (p[1])
+ {
+ FIXME("patch obsoletes %s\n", debugstr_w(p + 1));
+ p[1] = 0;
+ }
+
+ TRACE("patch code %s\n", debugstr_w(pi->patchcode));
+
pi->transforms = msi_suminfo_dup_string( si, PID_LASTAUTHOR );
if (!pi->transforms)
{
*/
append_storage_to_db( package->db, patch_db->storage );
+ patch->state = MSIPATCHSTATE_APPLIED;
list_add_tail( &package->patches, &patch->entry );
return ERROR_SUCCESS;
}
return FALSE;
}
-static UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace)
+UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace)
{
LPWSTR source, check;
if (needs_ui_sequence(package))
rc = ACTION_PerformUIAction(package, action, -1);
else
- rc = ACTION_PerformAction(package, action, -1, FALSE);
+ rc = ACTION_PerformAction(package, action, -1);
msi_dialog_check_messages( NULL );
{
TRACE("Running the actions\n");
+ msi_set_property(package->db, cszSourceDir, NULL);
+
rc = MSI_IterateRecords(view, NULL, ITERATE_Actions, package);
msiobj_release(&view->hdr);
}
if (!comp)
return ERROR_SUCCESS;
+ if (!comp->Enabled)
+ {
+ TRACE("component is disabled\n");
+ return ERROR_SUCCESS;
+ }
+
if (comp->ActionRequest != INSTALLSTATE_LOCAL)
{
TRACE("Component not scheduled for installation: %s\n", debugstr_w(component));
return ERROR_SUCCESS;
}
-/* FIXME: probably should merge this with the above function */
-static UINT msi_create_directory( MSIPACKAGE* package, LPCWSTR dir )
-{
- UINT rc = ERROR_SUCCESS;
- MSIFOLDER *folder;
- LPWSTR install_path;
-
- install_path = resolve_folder(package, dir, FALSE, FALSE, TRUE, &folder);
- if (!install_path)
- return ERROR_FUNCTION_FAILED;
-
- /* create the path */
- if (folder->State == 0)
- {
- create_full_pathW(install_path);
- folder->State = 2;
- }
- msi_free(install_path);
-
- return rc;
-}
-
-UINT msi_create_component_directories( MSIPACKAGE *package )
-{
- MSICOMPONENT *comp;
-
- /* create all the folders required by the components are going to install */
- LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
- {
- if (comp->ActionRequest != INSTALLSTATE_LOCAL)
- continue;
- msi_create_directory( package, comp->Directory );
- }
-
- return ERROR_SUCCESS;
-}
-
static UINT ACTION_CreateFolders(MSIPACKAGE *package)
{
static const WCHAR ExecSeqQuery[] =
if (!comp)
return ERROR_SUCCESS;
+ if (!comp->Enabled)
+ {
+ TRACE("component is disabled\n");
+ return ERROR_SUCCESS;
+ }
+
if (comp->ActionRequest != INSTALLSTATE_ABSENT)
{
TRACE("Component not scheduled for removal: %s\n", debugstr_w(component));
TRACE("folder is %s\n", debugstr_w(full_path));
uirow = MSI_CreateRecord( 1 );
- MSI_RecordSetStringW( uirow, 1, full_path );
+ MSI_RecordSetStringW( uirow, 1, dir );
ui_actiondata( package, szRemoveFolders, uirow );
msiobj_release( &uirow->hdr );
action = package->script->Actions[script][i];
ui_actionstart(package, action);
TRACE("Executing Action (%s)\n",debugstr_w(action));
- rc = ACTION_PerformAction(package, action, script, TRUE);
+ rc = ACTION_PerformAction(package, action, script);
if (rc != ERROR_SUCCESS)
break;
}
BOOL feature_state = ((feature->Level > 0) &&
(feature->Level <= level));
- if ((feature_state) && (feature->Action == INSTALLSTATE_UNKNOWN))
+ if (feature_state && feature->ActionRequest == INSTALLSTATE_UNKNOWN)
{
if (feature->Attributes & msidbFeatureAttributesFavorSource)
msi_feature_set_state(package, feature, INSTALLSTATE_SOURCE);
msi_feature_set_state(package, fl->feature, INSTALLSTATE_UNKNOWN);
}
}
+ else
+ {
+ LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
+ {
+ BOOL selected = feature->Level > 0 && feature->Level <= level;
+
+ if (selected && feature->ActionRequest == INSTALLSTATE_UNKNOWN)
+ {
+ msi_feature_set_state(package, feature, feature->Installed);
+ }
+ }
+ }
/*
- * now we want to enable or disable components base on feature
+ * now we want to enable or disable components based on feature
*/
-
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
ComponentList *cl;
- TRACE("Examining Feature %s (Level %i, Installed %i, Action %i)\n",
- debugstr_w(feature->Feature), feature->Level, feature->Installed, feature->Action);
+ TRACE("Examining Feature %s (Level %d Installed %d Request %d Action %d)\n",
+ debugstr_w(feature->Feature), feature->Level, feature->Installed,
+ feature->ActionRequest, feature->Action);
if (!feature->Level)
continue;
/* features with components that have compressed files are made local */
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
{
- if (cl->component->Enabled &&
- cl->component->ForceLocalState &&
- feature->Action == INSTALLSTATE_SOURCE)
+ if (cl->component->ForceLocalState &&
+ feature->ActionRequest == INSTALLSTATE_SOURCE)
{
msi_feature_set_state(package, feature, INSTALLSTATE_LOCAL);
break;
{
component = cl->component;
- if (!component->Enabled)
- continue;
-
- switch (feature->Action)
+ switch (feature->ActionRequest)
{
case INSTALLSTATE_ABSENT:
component->anyAbsent = 1;
LIST_FOR_EACH_ENTRY( component, &package->components, MSICOMPONENT, entry )
{
- /* if the component isn't enabled, leave it alone */
- if (!component->Enabled)
- continue;
-
/* check if it's local or source */
if (!(component->Attributes & msidbComponentAttributesOptional) &&
(component->hasLocalFeature || component->hasSourceFeature))
LIST_FOR_EACH_ENTRY( component, &package->components, MSICOMPONENT, entry )
{
- if (component->Action == INSTALLSTATE_DEFAULT)
+ if (component->ActionRequest == INSTALLSTATE_DEFAULT)
{
TRACE("%s was default, setting to local\n", debugstr_w(component->Component));
msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
}
- TRACE("Result: Component %s (Installed %i, Action %i)\n",
- debugstr_w(component->Component), component->Installed, component->Action);
+ TRACE("Result: Component %s (Installed %d Request %d Action %d)\n",
+ debugstr_w(component->Component), component->Installed, component->ActionRequest, component->Action);
}
-
return ERROR_SUCCESS;
}
return ERROR_SUCCESS;
}
-static LPWSTR get_disk_file_version( LPCWSTR filename )
+VS_FIXEDFILEINFO *msi_get_disk_file_version( LPCWSTR filename )
{
- static const WCHAR name_fmt[] =
- {'%','u','.','%','u','.','%','u','.','%','u',0};
static const WCHAR name[] = {'\\',0};
- VS_FIXEDFILEINFO *lpVer;
- WCHAR filever[0x100];
+ VS_FIXEDFILEINFO *ptr, *ret;
LPVOID version;
- DWORD versize;
- DWORD handle;
+ DWORD versize, handle;
UINT sz;
TRACE("%s\n", debugstr_w(filename));
return NULL;
version = msi_alloc( versize );
+ if (!version)
+ return NULL;
+
GetFileVersionInfoW( filename, 0, versize, version );
- if (!VerQueryValueW( version, name, (LPVOID*)&lpVer, &sz ))
+ if (!VerQueryValueW( version, name, (LPVOID *)&ptr, &sz ))
{
msi_free( version );
return NULL;
}
- sprintfW( filever, name_fmt,
- HIWORD(lpVer->dwFileVersionMS),
- LOWORD(lpVer->dwFileVersionMS),
- HIWORD(lpVer->dwFileVersionLS),
- LOWORD(lpVer->dwFileVersionLS));
+ ret = msi_alloc( sz );
+ memcpy( ret, ptr, sz );
msi_free( version );
+ return ret;
+}
+
+int msi_compare_file_versions( VS_FIXEDFILEINFO *fi, const WCHAR *version )
+{
+ DWORD ms, ls;
+
+ msi_parse_version_string( version, &ms, &ls );
- return strdupW( filever );
+ if (fi->dwFileVersionMS > ms) return 1;
+ else if (fi->dwFileVersionMS < ms) return -1;
+ else if (fi->dwFileVersionLS > ls) return 1;
+ else if (fi->dwFileVersionLS < ls) return -1;
+ return 0;
}
static DWORD get_disk_file_size( LPCWSTR filename )
static UINT set_file_install_states( MSIPACKAGE *package )
{
- LPWSTR file_version;
+ VS_FIXEDFILEINFO *file_version;
MSIFILE *file;
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
/* calculate target */
p = resolve_folder(package, comp->Directory, FALSE, FALSE, TRUE, NULL);
-
msi_free(file->TargetPath);
- TRACE("file %s is named %s\n",
- debugstr_w(file->File), debugstr_w(file->FileName));
+ TRACE("file %s is named %s\n", debugstr_w(file->File), debugstr_w(file->FileName));
file->TargetPath = build_directory_name(2, p, file->FileName);
-
msi_free(p);
- TRACE("file %s resolves to %s\n",
- debugstr_w(file->File), debugstr_w(file->TargetPath));
+ TRACE("file %s resolves to %s\n", debugstr_w(file->File), debugstr_w(file->TargetPath));
if (GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES)
{
comp->Cost += file->FileSize;
continue;
}
- if (file->Version && (file_version = get_disk_file_version( file->TargetPath )))
+ if (file->Version && (file_version = msi_get_disk_file_version( file->TargetPath )))
{
- TRACE("new %s old %s\n", debugstr_w(file->Version), debugstr_w(file_version));
+ TRACE("new %s old %u.%u.%u.%u\n", debugstr_w(file->Version),
+ HIWORD(file_version->dwFileVersionMS),
+ LOWORD(file_version->dwFileVersionMS),
+ HIWORD(file_version->dwFileVersionLS),
+ LOWORD(file_version->dwFileVersionLS));
- if (strcmpiW(file_version, file->Version) < 0)
+ if (msi_compare_file_versions( file_version, file->Version ) < 0)
{
file->state = msifs_overwrite;
comp->Cost += file->FileSize;
return ret;
}
+static WCHAR *get_keypath( MSIPACKAGE *package, HKEY root, const WCHAR *path )
+{
+ static const WCHAR prefixW[] = {'S','O','F','T','W','A','R','E','\\'};
+ static const UINT len = sizeof(prefixW) / sizeof(prefixW[0]);
+
+ if (is_64bit && package->platform == PLATFORM_INTEL &&
+ root == HKEY_LOCAL_MACHINE && !strncmpiW( path, prefixW, len ))
+ {
+ UINT size;
+ WCHAR *path_32node;
+
+ size = (strlenW( path ) + strlenW( szWow6432Node ) + 1) * sizeof(WCHAR);
+ path_32node = msi_alloc( size );
+ if (!path_32node)
+ return NULL;
+
+ memcpy( path_32node, path, len * sizeof(WCHAR) );
+ path_32node[len] = 0;
+ strcatW( path_32node, szWow6432Node );
+ strcatW( path_32node, szBackSlash );
+ strcatW( path_32node, path + len );
+ return path_32node;
+ }
+
+ return strdupW( path );
+}
+
static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
{
MSIPACKAGE *package = param;
LPSTR value_data = NULL;
HKEY root_key, hkey;
DWORD type,size;
- LPWSTR deformated;
+ LPWSTR deformated, uikey, keypath;
LPCWSTR szRoot, component, name, key, value;
MSICOMPONENT *comp;
MSIRECORD * uirow;
- LPWSTR uikey;
INT root;
BOOL check_first = FALSE;
UINT rc;
ui_progress(package,2,0,0,0);
- value = NULL;
- key = NULL;
- uikey = NULL;
- name = NULL;
-
component = MSI_RecordGetString(row, 6);
comp = get_loaded_component(package,component);
if (!comp)
return ERROR_SUCCESS;
+ if (!comp->Enabled)
+ {
+ TRACE("component is disabled\n");
+ return ERROR_SUCCESS;
+ }
+
if (comp->ActionRequest != INSTALLSTATE_LOCAL)
{
TRACE("Component not scheduled for installation: %s\n", debugstr_w(component));
strcpyW(uikey,szRoot);
strcatW(uikey,deformated);
- if (RegCreateKeyW( root_key, deformated, &hkey))
+ keypath = get_keypath( package, root_key, deformated );
+ msi_free( deformated );
+ if (RegCreateKeyW( root_key, keypath, &hkey ))
{
- ERR("Could not create key %s\n",debugstr_w(deformated));
- msi_free(deformated);
+ ERR("Could not create key %s\n", debugstr_w(keypath));
msi_free(uikey);
return ERROR_SUCCESS;
}
- msi_free(deformated);
value = MSI_RecordGetString(row,5);
if (value)
{
MSIPACKAGE *package = param;
LPCWSTR component, name, key_str, root_key_str;
- LPWSTR deformated_key, deformated_name, ui_key_str;
+ LPWSTR deformated_key, deformated_name, ui_key_str, keypath;
MSICOMPONENT *comp;
MSIRECORD *uirow;
BOOL delete_key = FALSE;
if (!comp)
return ERROR_SUCCESS;
+ if (!comp->Enabled)
+ {
+ TRACE("component is disabled\n");
+ return ERROR_SUCCESS;
+ }
+
if (comp->ActionRequest != INSTALLSTATE_ABSENT)
{
TRACE("Component not scheduled for removal: %s\n", debugstr_w(component));
deformat_string( package, name, &deformated_name );
- delete_reg_key_or_value( hkey_root, deformated_key, deformated_name, delete_key );
+ keypath = get_keypath( package, hkey_root, deformated_key );
msi_free( deformated_key );
+ delete_reg_key_or_value( hkey_root, keypath, deformated_name, delete_key );
+ msi_free( keypath );
uirow = MSI_CreateRecord( 2 );
MSI_RecordSetStringW( uirow, 1, ui_key_str );
{
MSIPACKAGE *package = param;
LPCWSTR component, name, key_str, root_key_str;
- LPWSTR deformated_key, deformated_name, ui_key_str;
+ LPWSTR deformated_key, deformated_name, ui_key_str, keypath;
MSICOMPONENT *comp;
MSIRECORD *uirow;
BOOL delete_key = FALSE;
if (!comp)
return ERROR_SUCCESS;
+ if (!comp->Enabled)
+ {
+ TRACE("component is disabled\n");
+ return ERROR_SUCCESS;
+ }
+
if (comp->ActionRequest != INSTALLSTATE_LOCAL)
{
TRACE("Component not scheduled for installation: %s\n", debugstr_w(component));
deformat_string( package, name, &deformated_name );
- delete_reg_key_or_value( hkey_root, deformated_key, deformated_name, delete_key );
+ keypath = get_keypath( package, hkey_root, deformated_key );
msi_free( deformated_key );
+ delete_reg_key_or_value( hkey_root, keypath, deformated_name, delete_key );
+ msi_free( keypath );
uirow = MSI_CreateRecord( 2 );
MSI_RecordSetStringW( uirow, 1, ui_key_str );
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
- TRACE("Feature: %s; Installed: %i; Action %i; Request %i\n",
- debugstr_w(feature->Feature), feature->Installed, feature->Action,
- feature->ActionRequest);
+ TRACE("Feature: %s Installed %d Request %d Action %d\n",
+ debugstr_w(feature->Feature), feature->Installed,
+ feature->ActionRequest, feature->Action);
}
return ERROR_SUCCESS;
squash_guid(package->ProductCode,squished_pc);
ui_progress(package,1,COMPONENT_PROGRESS_VALUE,1,0);
+ msi_set_sourcedir_props(package, FALSE);
+
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
{
MSIRECORD * uirow;
ACTION_RefCountComponent( package, comp );
- TRACE("Component %s (%s), Keypath=%s, RefCount=%i\n",
+ TRACE("Component %s (%s), Keypath=%s, RefCount=%i Request=%u\n",
debugstr_w(comp->Component),
debugstr_w(squished_cc),
debugstr_w(comp->FullKeypath),
- comp->RefCount);
+ comp->RefCount,
+ comp->ActionRequest);
if (comp->ActionRequest == INSTALLSTATE_LOCAL ||
comp->ActionRequest == INSTALLSTATE_SOURCE)
msi_reg_set_val_str(hkey, szPermKey, comp->FullKeypath);
}
- if (comp->Action == INSTALLSTATE_LOCAL)
+ if (comp->ActionRequest == INSTALLSTATE_LOCAL)
msi_reg_set_val_str(hkey, squished_pc, comp->FullKeypath);
else
{
if (!comp)
return ERROR_SUCCESS;
+ if (!comp->Enabled)
+ {
+ TRACE("component is disabled\n");
+ return ERROR_SUCCESS;
+ }
+
if (comp->ActionRequest != INSTALLSTATE_LOCAL)
{
TRACE("Component not scheduled for installation: %s\n", debugstr_w(component));
if (!comp)
return ERROR_SUCCESS;
+ if (!comp->Enabled)
+ {
+ TRACE("component is disabled\n");
+ return ERROR_SUCCESS;
+ }
+
if (comp->ActionRequest != INSTALLSTATE_ABSENT)
{
TRACE("Component not scheduled for removal %s\n", debugstr_w(component));
if (!comp)
return ERROR_SUCCESS;
+ if (!comp->Enabled)
+ {
+ TRACE("component is disabled\n");
+ return ERROR_SUCCESS;
+ }
+
if (comp->ActionRequest != INSTALLSTATE_LOCAL)
{
TRACE("Component not scheduled for installation %s\n", debugstr_w(component));
if (!comp)
return ERROR_SUCCESS;
+ if (!comp->Enabled)
+ {
+ TRACE("component is disabled\n");
+ return ERROR_SUCCESS;
+ }
+
if (comp->ActionRequest != INSTALLSTATE_ABSENT)
{
TRACE("Component not scheduled for removal %s\n", debugstr_w(component));
LPWSTR upgrade;
WCHAR squashed_pc[SQUISH_GUID_SIZE];
- static const WCHAR szUpgradeCode[] =
- {'U','p','g','r','a','d','e','C','o','d','e',0};
-
upgrade = msi_dup_property(package->db, szUpgradeCode);
if (!upgrade)
return ERROR_SUCCESS;
return TRUE;
}
-static UINT msi_publish_patches( MSIPACKAGE *package, HKEY prodkey )
+static UINT msi_publish_patches( MSIPACKAGE *package )
{
static const WCHAR szAllPatches[] = {'A','l','l','P','a','t','c','h','e','s',0};
WCHAR patch_squashed[GUID_SIZE];
- HKEY patches_key = NULL, product_patches_key;
+ HKEY patches_key = NULL, product_patches_key = NULL, product_key;
LONG res;
MSIPATCHINFO *patch;
UINT r;
WCHAR *p, *all_patches = NULL;
DWORD len = 0;
- res = RegCreateKeyExW( prodkey, szPatches, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &patches_key, NULL );
- if (res != ERROR_SUCCESS)
+ r = MSIREG_OpenProductKey( package->ProductCode, NULL, package->Context, &product_key, TRUE );
+ if (r != ERROR_SUCCESS)
return ERROR_FUNCTION_FAILED;
+ res = RegCreateKeyExW( product_key, szPatches, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &patches_key, NULL );
+ if (res != ERROR_SUCCESS)
+ {
+ r = ERROR_FUNCTION_FAILED;
+ goto done;
+ }
+
r = MSIREG_OpenUserDataProductPatchesKey( package->ProductCode, package->Context, &product_patches_key, TRUE );
if (r != ERROR_SUCCESS)
goto done;
goto done;
res = RegCreateKeyExW( product_patches_key, patch_squashed, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &patch_key, NULL );
+ if (res != ERROR_SUCCESS)
+ goto done;
+
+ res = RegSetValueExW( patch_key, szState, 0, REG_DWORD, (const BYTE *)&patch->state, sizeof(patch->state) );
RegCloseKey( patch_key );
if (res != ERROR_SUCCESS)
goto done;
done:
RegCloseKey( product_patches_key );
RegCloseKey( patches_key );
+ RegCloseKey( product_key );
msi_free( all_patches );
return r;
}
HKEY hukey = NULL, hudkey = NULL;
MSIRECORD *uirow;
+ if (!list_empty(&package->patches))
+ {
+ rc = msi_publish_patches(package);
+ if (rc != ERROR_SUCCESS)
+ goto end;
+ }
+
/* FIXME: also need to publish if the product is in advertise mode */
if (!msi_check_publish(package))
return ERROR_SUCCESS;
if (rc != ERROR_SUCCESS)
goto end;
- if (!list_empty(&package->patches))
- {
- rc = msi_publish_patches(package, hukey);
- if (rc != ERROR_SUCCESS)
- goto end;
- }
-
rc = msi_publish_product_properties(package, hukey);
if (rc != ERROR_SUCCESS)
goto end;
if (!comp)
return ERROR_SUCCESS;
+ if (!comp->Enabled)
+ {
+ TRACE("component is disabled\n");
+ return ERROR_SUCCESS;
+ }
+
if (comp->ActionRequest != INSTALLSTATE_LOCAL)
{
TRACE("Component not scheduled for installation %s\n", debugstr_w(component));
if (!comp)
return ERROR_SUCCESS;
+ if (!comp->Enabled)
+ {
+ TRACE("component is disabled\n");
+ return ERROR_SUCCESS;
+ }
+
if (comp->ActionRequest != INSTALLSTATE_ABSENT)
{
TRACE("Component not scheduled for removal %s\n", debugstr_w(component));
if (!comp)
return ERROR_SUCCESS;
+ if (!comp->Enabled)
+ {
+ TRACE("component is disabled\n");
+ return ERROR_SUCCESS;
+ }
+
if (comp->ActionRequest != INSTALLSTATE_LOCAL)
{
TRACE("Component not scheduled for installation %s\n", debugstr_w(component));
return ERROR_SUCCESS;
}
+static void register_dll( const WCHAR *dll, BOOL unregister )
+{
+ HMODULE hmod;
+
+ hmod = LoadLibraryExW( dll, 0, LOAD_WITH_ALTERED_SEARCH_PATH );
+ if (hmod)
+ {
+ HRESULT (WINAPI *func_ptr)( void );
+ const char *func = unregister ? "DllUnregisterServer" : "DllRegisterServer";
+
+ func_ptr = (void *)GetProcAddress( hmod, func );
+ if (func_ptr)
+ {
+ HRESULT hr = func_ptr();
+ if (FAILED( hr ))
+ WARN("failed to register dll 0x%08x\n", hr);
+ }
+ else
+ WARN("entry point %s not found\n", func);
+ FreeLibrary( hmod );
+ return;
+ }
+ WARN("failed to load library %u\n", GetLastError());
+}
+
static UINT ITERATE_SelfRegModules(MSIRECORD *row, LPVOID param)
{
MSIPACKAGE *package = param;
LPCWSTR filename;
- LPWSTR FullName;
MSIFILE *file;
- DWORD len;
- static const WCHAR ExeStr[] =
- {'r','e','g','s','v','r','3','2','.','e','x','e',' ',' /',' s',' ','\"',0};
- static const WCHAR close[] = {'\"',0};
- STARTUPINFOW si;
- PROCESS_INFORMATION info;
- BOOL brc;
MSIRECORD *uirow;
- LPWSTR uipath, p;
-
- memset(&si,0,sizeof(STARTUPINFOW));
filename = MSI_RecordGetString(row,1);
file = get_loaded_file( package, filename );
return ERROR_SUCCESS;
}
- len = strlenW(ExeStr) + strlenW( file->TargetPath ) + 2;
-
- FullName = msi_alloc(len*sizeof(WCHAR));
- strcpyW(FullName,ExeStr);
- strcatW( FullName, file->TargetPath );
- strcatW(FullName,close);
-
- TRACE("Registering %s\n",debugstr_w(FullName));
- brc = CreateProcessW(NULL, FullName, NULL, NULL, FALSE, 0, NULL, c_colon,
- &si, &info);
+ TRACE("Registering %s\n", debugstr_w( file->TargetPath ));
- if (brc)
- {
- CloseHandle(info.hThread);
- msi_dialog_check_messages(info.hProcess);
- CloseHandle(info.hProcess);
- }
+ register_dll( file->TargetPath, FALSE );
uirow = MSI_CreateRecord( 2 );
MSI_RecordSetStringW( uirow, 1, filename );
- uipath = strdupW( file->TargetPath );
- if ((p = strrchrW( uipath,'\\' ))) *p = 0;
- MSI_RecordSetStringW( uirow, 2, uipath );
+ MSI_RecordSetStringW( uirow, 2, file->Component->Directory );
ui_actiondata( package, szSelfRegModules, uirow );
msiobj_release( &uirow->hdr );
- msi_free( FullName );
- msi_free( uipath );
return ERROR_SUCCESS;
}
static UINT ITERATE_SelfUnregModules( MSIRECORD *row, LPVOID param )
{
- static const WCHAR regsvr32[] =
- {'r','e','g','s','v','r','3','2','.','e','x','e',' ','/','u',' ','/','s',' ','\"',0};
- static const WCHAR close[] = {'\"',0};
MSIPACKAGE *package = param;
LPCWSTR filename;
- LPWSTR cmdline;
MSIFILE *file;
- DWORD len;
- STARTUPINFOW si;
- PROCESS_INFORMATION pi;
- BOOL ret;
MSIRECORD *uirow;
- LPWSTR uipath, p;
-
- memset( &si, 0, sizeof(STARTUPINFOW) );
filename = MSI_RecordGetString( row, 1 );
file = get_loaded_file( package, filename );
return ERROR_SUCCESS;
}
- len = strlenW( regsvr32 ) + strlenW( file->TargetPath ) + 2;
+ TRACE("Unregistering %s\n", debugstr_w( file->TargetPath ));
- cmdline = msi_alloc( len * sizeof(WCHAR) );
- strcpyW( cmdline, regsvr32 );
- strcatW( cmdline, file->TargetPath );
- strcatW( cmdline, close );
-
- TRACE("Unregistering %s\n", debugstr_w(cmdline));
-
- ret = CreateProcessW( NULL, cmdline, NULL, NULL, FALSE, 0, NULL, c_colon, &si, &pi );
- if (ret)
- {
- CloseHandle( pi.hThread );
- msi_dialog_check_messages( pi.hProcess );
- CloseHandle( pi.hProcess );
- }
+ register_dll( file->TargetPath, TRUE );
uirow = MSI_CreateRecord( 2 );
MSI_RecordSetStringW( uirow, 1, filename );
- uipath = strdupW( file->TargetPath );
- if ((p = strrchrW( uipath,'\\' ))) *p = 0;
- MSI_RecordSetStringW( uirow, 2, uipath );
+ MSI_RecordSetStringW( uirow, 2, file->Component->Directory );
ui_actiondata( package, szSelfUnregModules, uirow );
msiobj_release( &uirow->hdr );
- msi_free( cmdline );
- msi_free( uipath );
return ERROR_SUCCESS;
}
HKEY upgrade;
UINT rc;
- static const WCHAR szUpgradeCode[] = {
- 'U','p','g','r','a','d','e','C','o','d','e',0};
-
/* FIXME: also need to publish if the product is in advertise mode */
if (!msi_check_publish(package))
return ERROR_SUCCESS;
- rc = MSIREG_OpenUninstallKey(package->ProductCode, &hkey, TRUE);
+ rc = MSIREG_OpenUninstallKey(package, &hkey, TRUE);
if (rc != ERROR_SUCCESS)
return rc;
return execute_script(package,INSTALL_SCRIPT);
}
-static UINT msi_unpublish_product(MSIPACKAGE *package)
+static UINT msi_unpublish_product(MSIPACKAGE *package, WCHAR *remove)
{
- LPWSTR upgrade;
- LPWSTR remove = NULL;
- LPWSTR *features = NULL;
+ WCHAR *upgrade, **features;
BOOL full_uninstall = TRUE;
MSIFEATURE *feature;
MSIPATCHINFO *patch;
static const WCHAR szUpgradeCode[] =
{'U','p','g','r','a','d','e','C','o','d','e',0};
- remove = msi_dup_property(package->db, szRemove);
- if (!remove)
- return ERROR_SUCCESS;
-
features = msi_split_string(remove, ',');
if (!features)
{
- msi_free(remove);
ERR("REMOVE feature list is empty!\n");
return ERROR_FUNCTION_FAILED;
}
full_uninstall = FALSE;
}
}
+ msi_free(features);
if (!full_uninstall)
- goto done;
+ return ERROR_SUCCESS;
MSIREG_DeleteProductKey(package->ProductCode);
MSIREG_DeleteUserDataProductKey(package->ProductCode);
- MSIREG_DeleteUninstallKey(package->ProductCode);
+ MSIREG_DeleteUninstallKey(package);
if (package->Context == MSIINSTALLCONTEXT_MACHINE)
{
MSIREG_DeleteUserDataPatchKey(patch->patchcode, package->Context);
}
-done:
- msi_free(remove);
- msi_free(features);
return ERROR_SUCCESS;
}
static UINT ACTION_InstallFinalize(MSIPACKAGE *package)
{
UINT rc;
-
- rc = msi_unpublish_product(package);
- if (rc != ERROR_SUCCESS)
- return rc;
+ WCHAR *remove;
/* turn off scheduling */
package->script->CurrentlyScripting= FALSE;
/* then handle Commit Actions */
rc = execute_script(package,COMMIT_SCRIPT);
+ if (rc != ERROR_SUCCESS)
+ return rc;
+
+ remove = msi_dup_property(package->db, szRemove);
+ if (remove)
+ rc = msi_unpublish_product(package, remove);
+ msi_free(remove);
return rc;
}
if (!comp)
return ERROR_SUCCESS;
+ if (!comp->Enabled)
+ {
+ TRACE("component is disabled\n");
+ return ERROR_SUCCESS;
+ }
+
if (comp->ActionRequest != INSTALLSTATE_LOCAL)
{
TRACE("Component not scheduled for installation: %s\n", debugstr_w(component));
if (!comp)
return ERROR_SUCCESS;
+ if (!comp->Enabled)
+ {
+ TRACE("component is disabled\n");
+ return ERROR_SUCCESS;
+ }
+
if (comp->ActionRequest != INSTALLSTATE_ABSENT)
{
TRACE("Component not scheduled for removal: %s\n", debugstr_w(component));
if (!comp)
return ERROR_SUCCESS;
+ if (!comp->Enabled)
+ {
+ TRACE("component is disabled\n");
+ return ERROR_SUCCESS;
+ }
+
if (comp->ActionRequest != INSTALLSTATE_ABSENT)
{
TRACE("Component not scheduled for removal: %s\n", debugstr_w(component));
uirow = MSI_CreateRecord( 5 );
MSI_RecordSetStringW( uirow, 1, desc );
MSI_RecordSetStringW( uirow, 2, MSI_RecordGetString(rec, 2) );
- MSI_RecordSetStringW( uirow, 3, driver_path );
+ MSI_RecordSetStringW( uirow, 3, driver_file->Component->Directory );
ui_actiondata( package, szInstallODBC, uirow );
msiobj_release( &uirow->hdr );
uirow = MSI_CreateRecord( 5 );
MSI_RecordSetStringW( uirow, 1, desc );
MSI_RecordSetStringW( uirow, 2, MSI_RecordGetString(rec, 2) );
- MSI_RecordSetStringW( uirow, 3, translator_path );
+ MSI_RecordSetStringW( uirow, 3, translator_file->Component->Directory );
ui_actiondata( package, szInstallODBC, uirow );
msiobj_release( &uirow->hdr );
if (!comp)
return ERROR_SUCCESS;
+ if (!comp->Enabled)
+ {
+ TRACE("component is disabled\n");
+ return ERROR_SUCCESS;
+ }
+
if (comp->ActionRequest != INSTALLSTATE_LOCAL)
{
TRACE("Component not scheduled for installation: %s\n", debugstr_w(component));
if (!comp)
return ERROR_SUCCESS;
+ if (!comp->Enabled)
+ {
+ TRACE("component is disabled\n");
+ return ERROR_SUCCESS;
+ }
+
if (comp->ActionRequest != INSTALLSTATE_ABSENT)
{
TRACE("Component not scheduled for removal: %s\n", debugstr_w(component));
if (assembly->installed && !mi->is_continuous)
continue;
- if (assembly->file->Sequence > mi->last_sequence || mi->is_continuous ||
- (assembly->file->IsCompressed && !mi->is_extracted))
+ if (assembly->file->IsCompressed)
{
- MSICABDATA data;
-
- r = ready_media(package, assembly->file, mi);
- if (r != ERROR_SUCCESS)
+ if (assembly->file->disk_id != mi->disk_id || mi->is_continuous)
{
- ERR("Failed to ready media\n");
- break;
- }
+ MSICABDATA data;
- data.mi = mi;
- data.package = package;
- data.cb = installassembly_cb;
- data.user = &assemblies;
+ r = ready_media(package, assembly->file, mi);
+ if (r != ERROR_SUCCESS)
+ {
+ ERR("Failed to ready media\n");
+ break;
+ }
- if (assembly->file->IsCompressed &&
- !msi_cabextract(package, mi, &data))
- {
- ERR("Failed to extract cabinet: %s\n", debugstr_w(mi->cabinet));
- r = ERROR_FUNCTION_FAILED;
- break;
+ data.mi = mi;
+ data.package = package;
+ data.cb = installassembly_cb;
+ data.user = &assemblies;
+
+ if (!msi_cabextract(package, mi, &data))
+ {
+ ERR("Failed to extract cabinet: %s\n", debugstr_w(mi->cabinet));
+ r = ERROR_FUNCTION_FAILED;
+ break;
+ }
}
}
-
- if (!assembly->file->IsCompressed)
+ else
{
LPWSTR source = resolve_file_source(package, assembly->file);
{ NULL, NULL },
};
-static BOOL ACTION_HandleStandardAction(MSIPACKAGE *package, LPCWSTR action,
- UINT* rc, BOOL force )
+static BOOL ACTION_HandleStandardAction( MSIPACKAGE *package, LPCWSTR action, UINT *rc )
{
BOOL ret = FALSE;
- BOOL run = force;
- int i;
-
- if (!run && !package->script->CurrentlyScripting)
- run = TRUE;
-
- if (!run)
- {
- if (strcmpW(action,szInstallFinalize) == 0 ||
- strcmpW(action,szInstallExecute) == 0 ||
- strcmpW(action,szInstallExecuteAgain) == 0)
- run = TRUE;
- }
+ UINT i;
i = 0;
while (StandardActions[i].action != NULL)
{
- if (strcmpW(StandardActions[i].action, action)==0)
+ if (!strcmpW( StandardActions[i].action, action ))
{
- if (!run)
+ ui_actionstart( package, action );
+ if (StandardActions[i].handler)
{
- ui_actioninfo(package, action, TRUE, 0);
- *rc = schedule_action(package,INSTALL_SCRIPT,action);
- ui_actioninfo(package, action, FALSE, *rc);
+ ui_actioninfo( package, action, TRUE, 0 );
+ *rc = StandardActions[i].handler( package );
+ ui_actioninfo( package, action, FALSE, *rc );
}
else
{
- ui_actionstart(package, action);
- if (StandardActions[i].handler)
- {
- *rc = StandardActions[i].handler(package);
- }
- else
- {
- FIXME("unhandled standard action %s\n",debugstr_w(action));
- *rc = ERROR_SUCCESS;
- }
+ FIXME("unhandled standard action %s\n", debugstr_w(action));
+ *rc = ERROR_SUCCESS;
}
ret = TRUE;
break;
return ret;
}
-UINT ACTION_PerformAction(MSIPACKAGE *package, const WCHAR *action, UINT script, BOOL force)
+UINT ACTION_PerformAction(MSIPACKAGE *package, const WCHAR *action, UINT script)
{
UINT rc = ERROR_SUCCESS;
BOOL handled;
TRACE("Performing action (%s)\n", debugstr_w(action));
- handled = ACTION_HandleStandardAction(package, action, &rc, force);
+ handled = ACTION_HandleStandardAction(package, action, &rc);
if (!handled)
- handled = ACTION_HandleCustomAction(package, action, &rc, script, force);
+ handled = ACTION_HandleCustomAction(package, action, &rc, script, TRUE);
if (!handled)
{
TRACE("Performing action (%s)\n", debugstr_w(action));
- handled = ACTION_HandleStandardAction(package, action, &rc,TRUE);
+ handled = ACTION_HandleStandardAction(package, action, &rc);
if (!handled)
handled = ACTION_HandleCustomAction(package, action, &rc, script, FALSE);
if (needs_ui_sequence(package))
rc = ACTION_PerformUIAction(package, action, -1);
else
- rc = ACTION_PerformAction(package, action, -1, FALSE);
+ rc = ACTION_PerformAction(package, action, -1);
msiobj_release(&row->hdr);
}
/* properties may have been added by a transform */
msi_clone_properties( package );
+
+ msi_parse_command_line( package, szCommandLine, FALSE );
+ msi_adjust_privilege_properties( package );
msi_set_context( package );
if (needs_ui_sequence( package))