Hans Leidekker : msi: Implement the UnregisterExtensionInfo standard action .

Alexandre Julliard julliard at winehq.org
Fri Apr 2 10:17:12 CDT 2010


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

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Fri Apr  2 10:39:20 2010 +0200

msi: Implement the UnregisterExtensionInfo standard action.

---

 dlls/msi/action.c  |    8 ----
 dlls/msi/classes.c |  114 +++++++++++++++++++++++++++++++++++++++++++++++-----
 dlls/msi/msipriv.h |    2 +
 3 files changed, 105 insertions(+), 19 deletions(-)

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 4f1be9a..25cd4fc 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -158,8 +158,6 @@ static const WCHAR szUnpublishFeatures[] =
     {'U','n','p','u','b','l','i','s','h','F','e','a','t','u','r','e','s',0};
 static const WCHAR szUnregisterComPlus[] =
     {'U','n','r','e','g','i','s','t','e','r','C','o','m','P','l','u','s',0};
-static const WCHAR szUnregisterExtensionInfo[] =
-    {'U','n','r','e','g','i','s','t','e','r','E','x','t','e','n','s','i','o','n','I','n','f','o',0};
 static const WCHAR szUnregisterMIMEInfo[] =
     {'U','n','r','e','g','i','s','t','e','r','M','I','M','E','I','n','f','o',0};
 static const WCHAR szUnregisterTypeLibraries[] =
@@ -6949,12 +6947,6 @@ static UINT ACTION_RemoveExistingProducts( MSIPACKAGE *package )
     return msi_unimplemented_action_stub( package, "RemoveExistingProducts", table );
 }
 
-static UINT ACTION_UnregisterExtensionInfo( MSIPACKAGE *package )
-{
-    static const WCHAR table[] = { 'E','x','t','e','n','s','i','o','n',0 };
-    return msi_unimplemented_action_stub( package, "UnregisterExtensionInfo", table );
-}
-
 static UINT ACTION_UnregisterMIMEInfo( MSIPACKAGE *package )
 {
     static const WCHAR table[] = { 'M','I','M','E',0 };
diff --git a/dlls/msi/classes.c b/dlls/msi/classes.c
index d6e8808..744acfb 100644
--- a/dlls/msi/classes.c
+++ b/dlls/msi/classes.c
@@ -24,10 +24,10 @@
  * RegisterProgIdInfo
  * RegisterExtensionInfo
  * RegisterMIMEInfo
- * UnRegisterClassInfo
- * UnRegisterProgIdInfo
- * UnRegisterExtensionInfo (TODO)
- * UnRegisterMIMEInfo (TODO)
+ * UnregisterClassInfo
+ * UnregisterProgIdInfo
+ * UnregisterExtensionInfo
+ * UnregisterMIMEInfo (TODO)
  */
 
 #include <stdarg.h>
@@ -747,6 +747,13 @@ static void mark_mime_for_install( MSIMIME *mime )
     mime->InstallMe = TRUE;
 }
 
+static void mark_mime_for_uninstall( MSIMIME *mime )
+{
+    if (!mime)
+        return;
+    mime->InstallMe = FALSE;
+}
+
 static UINT register_appid(const MSIAPPID *appid, LPCWSTR app )
 {
     static const WCHAR szRemoteServerName[] =
@@ -1221,10 +1228,11 @@ UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package)
 {
     static const WCHAR szContentType[] = 
         {'C','o','n','t','e','n','t',' ','T','y','p','e',0 };
-    HKEY hkey;
+    HKEY hkey = NULL;
     MSIEXTENSION *ext;
     MSIRECORD *uirow;
     BOOL install_on_demand = TRUE;
+    LONG res;
 
     load_classes_and_such(package);
 
@@ -1270,12 +1278,16 @@ UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package)
 
         mark_mime_for_install(ext->Mime);
 
-        extension = msi_alloc( (lstrlenW( ext->Extension ) + 2)*sizeof(WCHAR) );
-        extension[0] = '.';
-        lstrcpyW(extension+1,ext->Extension);
-
-        RegCreateKeyW(HKEY_CLASSES_ROOT,extension,&hkey);
-        msi_free( extension );
+        extension = msi_alloc( (strlenW( ext->Extension ) + 2) * sizeof(WCHAR) );
+        if (extension)
+        {
+            extension[0] = '.';
+            strcpyW( extension + 1, ext->Extension );
+            res = RegCreateKeyW( HKEY_CLASSES_ROOT, extension, &hkey );
+            msi_free( extension );
+            if (res != ERROR_SUCCESS)
+                WARN("Failed to create extension key %d\n", res);
+        }
 
         if (ext->Mime)
             msi_reg_set_val_str( hkey, szContentType, ext->Mime->ContentType );
@@ -1325,6 +1337,86 @@ UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package)
     return ERROR_SUCCESS;
 }
 
+UINT ACTION_UnregisterExtensionInfo( MSIPACKAGE *package )
+{
+    MSIEXTENSION *ext;
+    MSIRECORD *uirow;
+    LONG res;
+
+    load_classes_and_such( package );
+
+    LIST_FOR_EACH_ENTRY( ext, &package->extensions, MSIEXTENSION, entry )
+    {
+        LPWSTR extension;
+        MSIFEATURE *feature;
+
+        if (!ext->Component)
+            continue;
+
+        feature = ext->Feature;
+        if (!feature)
+            continue;
+
+        if (feature->ActionRequest != INSTALLSTATE_ABSENT)
+        {
+            TRACE("Feature %s not scheduled for removal, skipping unregistration of extension %s\n",
+                   debugstr_w(feature->Feature), debugstr_w(ext->Extension));
+            continue;
+        }
+
+        TRACE("Unregistering extension %s\n", debugstr_w(ext->Extension));
+
+        ext->Installed = FALSE;
+
+        if (ext->ProgID && !list_empty( &ext->verbs ))
+            mark_progid_for_uninstall( package, ext->ProgID );
+
+        mark_mime_for_uninstall( ext->Mime );
+
+        extension = msi_alloc( (strlenW( ext->Extension ) + 2) * sizeof(WCHAR) );
+        if (extension)
+        {
+            extension[0] = '.';
+            strcpyW( extension + 1, ext->Extension );
+            res = RegDeleteTreeW( HKEY_CLASSES_ROOT, extension );
+            msi_free( extension );
+            if (res != ERROR_SUCCESS)
+                WARN("Failed to delete extension key %d\n", res);
+        }
+
+        if (ext->ProgID || ext->ProgIDText)
+        {
+            static const WCHAR shellW[] = {'\\','s','h','e','l','l',0};
+            LPCWSTR progid;
+            LPWSTR progid_shell;
+
+            if (ext->ProgID)
+                progid = ext->ProgID->ProgID;
+            else
+                progid = ext->ProgIDText;
+
+            progid_shell = msi_alloc( (strlenW( progid ) + strlenW( shellW ) + 1) * sizeof(WCHAR) );
+            if (progid_shell)
+            {
+                strcpyW( progid_shell, progid );
+                strcatW( progid_shell, shellW );
+                res = RegDeleteTreeW( HKEY_CLASSES_ROOT, progid_shell );
+                msi_free( progid_shell );
+                if (res != ERROR_SUCCESS)
+                    WARN("Failed to delete shell key %d\n", res);
+                RegDeleteKeyW( HKEY_CLASSES_ROOT, progid );
+            }
+        }
+
+        uirow = MSI_CreateRecord( 1 );
+        MSI_RecordSetStringW( uirow, 1, ext->Extension );
+        ui_actiondata( package, szUnregisterExtensionInfo, uirow );
+        msiobj_release( &uirow->hdr );
+    }
+
+    return ERROR_SUCCESS;
+}
+
 UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package)
 {
     static const WCHAR szExten[] = 
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index e81237c..7ab1c87 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -963,6 +963,7 @@ extern UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package);
 extern UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package);
 extern UINT ACTION_RegisterFonts(MSIPACKAGE *package);
 extern UINT ACTION_UnregisterClassInfo(MSIPACKAGE *package);
+extern UINT ACTION_UnregisterExtensionInfo(MSIPACKAGE *package);
 extern UINT ACTION_UnregisterFonts(MSIPACKAGE *package);
 extern UINT ACTION_UnregisterProgIdInfo(MSIPACKAGE *package);
 
@@ -1087,6 +1088,7 @@ static const WCHAR szAppSearch[] = {'A','p','p','S','e','a','r','c','h',0};
 static const WCHAR szMoveFiles[] = {'M','o','v','e','F','i','l','e','s',0};
 static const WCHAR szCCPSearch[] = {'C','C','P','S','e','a','r','c','h',0};
 static const WCHAR szUnregisterClassInfo[] = {'U','n','r','e','g','i','s','t','e','r','C','l','a','s','s','I','n','f','o',0};
+static const WCHAR szUnregisterExtensionInfo[] = {'U','n','r','e','g','i','s','t','e','r','E','x','t','e','n','s','i','o','n','I','n','f','o',0};
 static const WCHAR szUnregisterProgIdInfo[] = {'U','n','r','e','g','i','s','t','e','r','P','r','o','g','I','d','I','n','f','o',0};
 static const WCHAR szRegisterFonts[] = {'R','e','g','i','s','t','e','r','F','o','n','t','s',0};
 static const WCHAR szUnregisterFonts[] = {'U','n','r','e','g','i','s','t','e','r','F','o','n','t','s',0};




More information about the wine-cvs mailing list