Hans Leidekker : msi: Remove directories after removing all files.

Alexandre Julliard julliard at winehq.org
Fri Jul 1 14:11:04 CDT 2011


Module: wine
Branch: master
Commit: 791fe136a9b7becfe0946ff06cfc35c3b2e4338f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=791fe136a9b7becfe0946ff06cfc35c3b2e4338f

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Thu Jun 30 12:15:19 2011 +0200

msi: Remove directories after removing all files.

---

 dlls/msi/action.c  |   30 ++++++++++++++++++++++-
 dlls/msi/files.c   |   66 +++++++++++++++++++++++----------------------------
 dlls/msi/msipriv.h |    2 +-
 3 files changed, 60 insertions(+), 38 deletions(-)

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 8fe1221..4671f3e 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -878,7 +878,7 @@ static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param)
 
     folder = msi_get_loaded_folder( package, dir );
     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;
 }
 
@@ -1438,6 +1438,32 @@ static UINT load_all_patches(MSIPACKAGE *package)
     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 )
 {
     MSIPACKAGE *package = param;
@@ -1488,6 +1514,8 @@ static UINT load_folder( MSIRECORD *row, LPVOID param )
     TRACE("SourceLong = %s\n", debugstr_w( folder->SourceLongPath ));
     TRACE("SourceShort = %s\n", debugstr_w( folder->SourceShortPath ));
 
+    load_folder_persistence( package, folder );
+
     list_add_tail( &package->folders, &folder->entry );
     return ERROR_SUCCESS;
 }
diff --git a/dlls/msi/files.c b/dlls/msi/files.c
index 69f6b68..5749c69 100644
--- a/dlls/msi/files.c
+++ b/dlls/msi/files.c
@@ -1212,43 +1212,30 @@ done:
     return ret;
 }
 
-static BOOL has_persistent_dir( MSIPACKAGE *package, MSICOMPONENT *comp )
+static void remove_folder( MSIFOLDER *folder )
 {
-    MSIQUERY *view;
-    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};
+    FolderList *fl;
 
-    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));
-                msiobj_release( &rec->hdr );
-            }
-        }
-        msiobj_release( &view->hdr );
+        remove_folder( fl->folder );
+    }
+    if (!folder->persistent && folder->State != FOLDER_STATE_REMOVED)
+    {
+        if (RemoveDirectoryW( folder->ResolvedTarget )) folder->State = FOLDER_STATE_REMOVED;
     }
-    return (r == ERROR_SUCCESS);
 }
 
 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;
+    MSICOMPONENT *comp;
     MSIFILE *file;
     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);
     if (r == ERROR_SUCCESS)
     {
@@ -1259,10 +1246,9 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package )
     LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
     {
         MSIRECORD *uirow;
-        LPWSTR dir, p;
         VS_FIXEDFILEINFO *ver;
-        MSICOMPONENT *comp = file->Component;
 
+        comp = file->Component;
         msi_file_update_ui( package, file, szRemoveFiles );
 
         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());
         }
-        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;
 
         uirow = MSI_CreateRecord( 9 );
@@ -1317,5 +1294,22 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package )
         msi_ui_actiondata( package, szRemoveFiles, uirow );
         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;
 }
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 09468c4..e2fb03e 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -508,10 +508,10 @@ typedef struct tagMSIFOLDER
     LPWSTR TargetDefault;
     LPWSTR SourceLongPath;
     LPWSTR SourceShortPath;
-
     LPWSTR ResolvedTarget;
     LPWSTR ResolvedSource;
     enum folder_state State;
+    BOOL persistent;
     INT Cost;
     INT Space;
 } MSIFOLDER;




More information about the wine-cvs mailing list