mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-01 07:31:42 +00:00
msi: Remove directories after removing all files.
This commit is contained in:
parent
12a55d9190
commit
791fe136a9
|
@ -878,7 +878,7 @@ static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param)
|
||||||
|
|
||||||
folder = msi_get_loaded_folder( package, dir );
|
folder = msi_get_loaded_folder( package, dir );
|
||||||
if (folder->State == FOLDER_STATE_UNINITIALIZED) msi_create_full_path( full_path );
|
if (folder->State == FOLDER_STATE_UNINITIALIZED) msi_create_full_path( full_path );
|
||||||
folder->State = FOLDER_STATE_CREATED_PERSISTENT;
|
folder->State = FOLDER_STATE_CREATED;
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1438,6 +1438,32 @@ static UINT load_all_patches(MSIPACKAGE *package)
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT load_folder_persistence( MSIPACKAGE *package, MSIFOLDER *folder )
|
||||||
|
{
|
||||||
|
static const WCHAR query[] = {
|
||||||
|
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||||
|
'`','C','r','e','a','t','e','F','o','l','d','e','r','`',' ','W','H','E','R','E',' ',
|
||||||
|
'`','D','i','r','e','c','t','o','r','y','_','`',' ','=','\'','%','s','\'',0};
|
||||||
|
MSIQUERY *view;
|
||||||
|
|
||||||
|
folder->persistent = FALSE;
|
||||||
|
if (!MSI_OpenQuery( package->db, &view, query, folder->Directory ))
|
||||||
|
{
|
||||||
|
if (!MSI_ViewExecute( view, NULL ))
|
||||||
|
{
|
||||||
|
MSIRECORD *rec;
|
||||||
|
if (!MSI_ViewFetch( view, &rec ))
|
||||||
|
{
|
||||||
|
TRACE("directory %s is persistent\n", debugstr_w(folder->Directory));
|
||||||
|
folder->persistent = TRUE;
|
||||||
|
msiobj_release( &rec->hdr );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msiobj_release( &view->hdr );
|
||||||
|
}
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static UINT load_folder( MSIRECORD *row, LPVOID param )
|
static UINT load_folder( MSIRECORD *row, LPVOID param )
|
||||||
{
|
{
|
||||||
MSIPACKAGE *package = param;
|
MSIPACKAGE *package = param;
|
||||||
|
@ -1488,6 +1514,8 @@ static UINT load_folder( MSIRECORD *row, LPVOID param )
|
||||||
TRACE("SourceLong = %s\n", debugstr_w( folder->SourceLongPath ));
|
TRACE("SourceLong = %s\n", debugstr_w( folder->SourceLongPath ));
|
||||||
TRACE("SourceShort = %s\n", debugstr_w( folder->SourceShortPath ));
|
TRACE("SourceShort = %s\n", debugstr_w( folder->SourceShortPath ));
|
||||||
|
|
||||||
|
load_folder_persistence( package, folder );
|
||||||
|
|
||||||
list_add_tail( &package->folders, &folder->entry );
|
list_add_tail( &package->folders, &folder->entry );
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1212,43 +1212,30 @@ done:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL has_persistent_dir( MSIPACKAGE *package, MSICOMPONENT *comp )
|
static void remove_folder( MSIFOLDER *folder )
|
||||||
{
|
{
|
||||||
MSIQUERY *view;
|
FolderList *fl;
|
||||||
UINT r = ERROR_FUNCTION_FAILED;
|
|
||||||
|
|
||||||
static const WCHAR query[] = {
|
LIST_FOR_EACH_ENTRY( fl, &folder->children, FolderList, entry )
|
||||||
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
|
||||||
'`','C','r','e','a','t','e','F','o','l','d','e','r','`',' ','W','H','E','R','E',' ',
|
|
||||||
'`','C','o','m','p','o','n','e','n','t','_','`',' ','=','\'','%','s','\'',' ','A','N','D',' ',
|
|
||||||
'`','D','i','r','e','c','t','o','r','y','_','`',' ','=','\'','%','s','\'',0};
|
|
||||||
|
|
||||||
if (!MSI_OpenQuery( package->db, &view, query, comp->Component, comp->Directory ))
|
|
||||||
{
|
{
|
||||||
if (!MSI_ViewExecute( view, NULL ))
|
remove_folder( fl->folder );
|
||||||
{
|
}
|
||||||
MSIRECORD *rec;
|
if (!folder->persistent && folder->State != FOLDER_STATE_REMOVED)
|
||||||
if (!(r = MSI_ViewFetch( view, &rec )))
|
{
|
||||||
{
|
if (RemoveDirectoryW( folder->ResolvedTarget )) folder->State = FOLDER_STATE_REMOVED;
|
||||||
TRACE("directory %s is persistent\n", debugstr_w(comp->Directory));
|
|
||||||
msiobj_release( &rec->hdr );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
msiobj_release( &view->hdr );
|
|
||||||
}
|
}
|
||||||
return (r == ERROR_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT ACTION_RemoveFiles( MSIPACKAGE *package )
|
UINT ACTION_RemoveFiles( MSIPACKAGE *package )
|
||||||
{
|
{
|
||||||
|
static const WCHAR query[] =
|
||||||
|
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||||
|
'`','R','e','m','o','v','e','F','i','l','e','`',0};
|
||||||
MSIQUERY *view;
|
MSIQUERY *view;
|
||||||
|
MSICOMPONENT *comp;
|
||||||
MSIFILE *file;
|
MSIFILE *file;
|
||||||
UINT r;
|
UINT r;
|
||||||
|
|
||||||
static const WCHAR query[] = {
|
|
||||||
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
|
||||||
'`','R','e','m','o','v','e','F','i','l','e','`',0};
|
|
||||||
|
|
||||||
r = MSI_DatabaseOpenViewW(package->db, query, &view);
|
r = MSI_DatabaseOpenViewW(package->db, query, &view);
|
||||||
if (r == ERROR_SUCCESS)
|
if (r == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -1259,10 +1246,9 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package )
|
||||||
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
|
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
|
||||||
{
|
{
|
||||||
MSIRECORD *uirow;
|
MSIRECORD *uirow;
|
||||||
LPWSTR dir, p;
|
|
||||||
VS_FIXEDFILEINFO *ver;
|
VS_FIXEDFILEINFO *ver;
|
||||||
MSICOMPONENT *comp = file->Component;
|
|
||||||
|
|
||||||
|
comp = file->Component;
|
||||||
msi_file_update_ui( package, file, szRemoveFiles );
|
msi_file_update_ui( package, file, szRemoveFiles );
|
||||||
|
|
||||||
comp->Action = msi_get_component_action( package, comp );
|
comp->Action = msi_get_component_action( package, comp );
|
||||||
|
@ -1300,15 +1286,6 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package )
|
||||||
{
|
{
|
||||||
WARN("failed to delete %s (%u)\n", debugstr_w(file->TargetPath), GetLastError());
|
WARN("failed to delete %s (%u)\n", debugstr_w(file->TargetPath), GetLastError());
|
||||||
}
|
}
|
||||||
else if (!has_persistent_dir( package, comp ))
|
|
||||||
{
|
|
||||||
if ((dir = strdupW( file->TargetPath )))
|
|
||||||
{
|
|
||||||
if ((p = strrchrW( dir, '\\' ))) *p = 0;
|
|
||||||
RemoveDirectoryW( dir );
|
|
||||||
msi_free( dir );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file->state = msifs_missing;
|
file->state = msifs_missing;
|
||||||
|
|
||||||
uirow = MSI_CreateRecord( 9 );
|
uirow = MSI_CreateRecord( 9 );
|
||||||
|
@ -1317,5 +1294,22 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package )
|
||||||
msi_ui_actiondata( package, szRemoveFiles, uirow );
|
msi_ui_actiondata( package, szRemoveFiles, uirow );
|
||||||
msiobj_release( &uirow->hdr );
|
msiobj_release( &uirow->hdr );
|
||||||
}
|
}
|
||||||
|
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
|
||||||
|
{
|
||||||
|
MSIFOLDER *folder;
|
||||||
|
|
||||||
|
comp->Action = msi_get_component_action( package, comp );
|
||||||
|
if (comp->Action != INSTALLSTATE_ABSENT) continue;
|
||||||
|
|
||||||
|
if (comp->assembly && !comp->assembly->application) continue;
|
||||||
|
|
||||||
|
if (comp->Attributes & msidbComponentAttributesPermanent)
|
||||||
|
{
|
||||||
|
TRACE("permanent component, not removing directory\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
folder = msi_get_loaded_folder( package, comp->Directory );
|
||||||
|
remove_folder( folder );
|
||||||
|
}
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -508,10 +508,10 @@ typedef struct tagMSIFOLDER
|
||||||
LPWSTR TargetDefault;
|
LPWSTR TargetDefault;
|
||||||
LPWSTR SourceLongPath;
|
LPWSTR SourceLongPath;
|
||||||
LPWSTR SourceShortPath;
|
LPWSTR SourceShortPath;
|
||||||
|
|
||||||
LPWSTR ResolvedTarget;
|
LPWSTR ResolvedTarget;
|
||||||
LPWSTR ResolvedSource;
|
LPWSTR ResolvedSource;
|
||||||
enum folder_state State;
|
enum folder_state State;
|
||||||
|
BOOL persistent;
|
||||||
INT Cost;
|
INT Cost;
|
||||||
INT Space;
|
INT Space;
|
||||||
} MSIFOLDER;
|
} MSIFOLDER;
|
||||||
|
|
Loading…
Reference in a new issue