Commit 791fe136 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

msi: Remove directories after removing all files.

parent 12a55d91
...@@ -878,7 +878,7 @@ static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param) ...@@ -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) ...@@ -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 ) ...@@ -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: ...@@ -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[] = {
'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 )) LIST_FOR_EACH_ENTRY( fl, &folder->children, FolderList, entry )
{
if (!MSI_ViewExecute( view, NULL ))
{
MSIRECORD *rec;
if (!(r = MSI_ViewFetch( view, &rec )))
{ {
TRACE("directory %s is persistent\n", debugstr_w(comp->Directory)); remove_folder( fl->folder );
msiobj_release( &rec->hdr );
} }
if (!folder->persistent && folder->State != FOLDER_STATE_REMOVED)
{
if (RemoveDirectoryW( folder->ResolvedTarget )) folder->State = FOLDER_STATE_REMOVED;
} }
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 ) ...@@ -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 ) ...@@ -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 ) ...@@ -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 ...@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment