[Wine-patches] [eterhack 2/6] msi: Implement ACTION_RemoveFolders (eterbug #953).

Alexander Morozov amorozov на etersoft.ru
Пт Авг 14 16:21:45 MSD 2009


---
 dlls/msi/action.c |   86 +++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 80 insertions(+), 6 deletions(-)

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index ff57a99..df95bd4 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -1282,6 +1282,44 @@ UINT msi_remove_component_directories( MSIPACKAGE *package )
     return ERROR_SUCCESS;
 }
 
+static UINT ITERATE_RemoveFolders(MSIRECORD *row, LPVOID param)
+{
+    MSIPACKAGE *package = param;
+    LPCWSTR dir;
+    LPWSTR full_path;
+    MSIRECORD *uirow;
+    MSIFOLDER *folder;
+
+    dir = MSI_RecordGetString(row, 1);
+    if (!dir)
+    {
+        ERR("Unable to get folder id\n");
+        return ERROR_SUCCESS;
+    }
+
+    full_path = resolve_folder(package, dir, FALSE, FALSE, TRUE, &folder);
+    if (!full_path)
+    {
+        ERR("Unable to resolve folder id %s\n", debugstr_w(dir));
+        return ERROR_SUCCESS;
+    }
+
+    /* UI stuff */
+    uirow = MSI_CreateRecord(1);
+    MSI_RecordSetStringW(uirow, 1, full_path);
+    ui_actiondata(package, szRemoveFolders, uirow);
+    msiobj_release(&uirow->hdr);
+
+    if (RemoveDirectoryW(full_path))
+    {
+        folder->State = 0;
+        msi_remove_directory(package, folder->Parent);
+    }
+
+    msi_free(full_path);
+    return ERROR_SUCCESS;
+}
+
 /*
  * Also we cannot enable/disable components either, so for now I am just going 
  * to do all the directories for all the components.
@@ -1295,6 +1333,20 @@ static UINT ACTION_CreateFolders(MSIPACKAGE *package)
          '`','C','r','e','a','t','e','F','o','l','d','e','r','`',0 };
     UINT rc;
     MSIQUERY *view;
+    MSICOMPONENT *comp;
+    BOOL create = FALSE;
+
+    /* do not create folders if nothing should be installed */
+    LIST_FOR_EACH_ENTRY(comp, &package->components, MSICOMPONENT, entry)
+    {
+        if (comp->Action != INSTALLSTATE_ABSENT && comp->Action != INSTALLSTATE_UNKNOWN)
+        {
+            create = TRUE;
+            break;
+        }
+    }
+    if (!create)
+        return ERROR_SUCCESS;
 
     /* create all the empty folders specified in the CreateFolder table */
     rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view );
@@ -1309,6 +1361,34 @@ static UINT ACTION_CreateFolders(MSIPACKAGE *package)
     return rc;
 }
 
+static UINT ACTION_RemoveFolders( MSIPACKAGE *package )
+{
+    static const WCHAR ExecSeqQuery[] =
+        {'S','E','L','E','C','T',' ',
+         '`','D','i','r','e','c','t','o','r','y','_','`',
+         ' ','F','R','O','M',' ',
+         '`','C','r','e','a','t','e','F','o','l','d','e','r','`',0 };
+    UINT rc;
+    MSIQUERY *view;
+    MSICOMPONENT *comp;
+
+    /* for now we remove folders only if all components should be removed */
+    LIST_FOR_EACH_ENTRY(comp, &package->components, MSICOMPONENT, entry)
+    {
+        if (comp->Action != INSTALLSTATE_ABSENT && comp->Action != INSTALLSTATE_UNKNOWN)
+            return ERROR_SUCCESS;
+    }
+
+    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view );
+    if (rc != ERROR_SUCCESS)
+        return ERROR_SUCCESS;
+
+    rc = MSI_IterateRecords(view, NULL, ITERATE_RemoveFolders, package);
+    msiobj_release(&view->hdr);
+
+    return rc;
+}
+
 static UINT load_component( MSIRECORD *row, LPVOID param )
 {
     MSIPACKAGE *package = param;
@@ -6472,12 +6552,6 @@ static UINT ACTION_RemoveExistingProducts( MSIPACKAGE *package )
     return msi_unimplemented_action_stub( package, "RemoveExistingProducts", table );
 }
 
-static UINT ACTION_RemoveFolders( MSIPACKAGE *package )
-{
-    static const WCHAR table[] = { 'C','r','e','a','t','e','F','o','l','d','e','r',0 };
-    return msi_unimplemented_action_stub( package, "RemoveFolders", table );
-}
-
 static UINT ACTION_RemoveODBC( MSIPACKAGE *package )
 {
     static const WCHAR table[] = { 'O','D','B','C','D','r','i','v','e','r',0 };
-- 
1.6.3.3



Подробная информация о списке рассылки Wine-patches