[1/9] msi: Implement the UnregisterClassInfo standard action.
Hans Leidekker
hans at codeweavers.com
Fri Apr 2 03:37:50 CDT 2010
---
dlls/msi/action.c | 8 ---
dlls/msi/classes.c | 167 ++++++++++++++++++++++++++++++++++++----------------
dlls/msi/msipriv.h | 9 +++
3 files changed, 124 insertions(+), 60 deletions(-)
diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index a7a9596..2b729ec 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -158,8 +158,6 @@ static const WCHAR szUnpublishComponents[] =
{'U','n','p','u','b','l','i','s','h', 'C','o','m','p','o','n','e','n','t','s',0};
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 szUnregisterClassInfo[] =
- {'U','n','r','e','g','i','s','t','e','r','C','l','a','s','s','I','n','f','o',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[] =
@@ -6957,12 +6955,6 @@ static UINT ACTION_RemoveExistingProducts( MSIPACKAGE *package )
return msi_unimplemented_action_stub( package, "RemoveExistingProducts", table );
}
-static UINT ACTION_UnregisterClassInfo( MSIPACKAGE *package )
-{
- static const WCHAR table[] = { 'A','p','p','I','d',0 };
- return msi_unimplemented_action_stub( package, "UnregisterClassInfo", table );
-}
-
static UINT ACTION_UnregisterExtensionInfo( MSIPACKAGE *package )
{
static const WCHAR table[] = { 'E','x','t','e','n','s','i','o','n',0 };
diff --git a/dlls/msi/classes.c b/dlls/msi/classes.c
index acd8429..53ed70f 100644
--- a/dlls/msi/classes.c
+++ b/dlls/msi/classes.c
@@ -18,12 +18,13 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-/* actions handled in this module
+/* Actions handled in this module:
+ *
* RegisterClassInfo
* RegisterProgIdInfo
* RegisterExtensionInfo
* RegisterMIMEInfo
- * UnRegisterClassInfo (TODO)
+ * UnRegisterClassInfo
* UnRegisterProgIdInfo (TODO)
* UnRegisterExtensionInfo (TODO)
* UnRegisterMIMEInfo (TODO)
@@ -720,6 +721,25 @@ static void mark_progid_for_install( MSIPACKAGE* package, MSIPROGID *progid )
}
}
+static void mark_progid_for_uninstall( MSIPACKAGE *package, MSIPROGID *progid )
+{
+ MSIPROGID *child;
+
+ if (!progid)
+ return;
+
+ if (!progid->InstallMe)
+ return;
+
+ progid->InstallMe = FALSE;
+
+ LIST_FOR_EACH_ENTRY( child, &package->progids, MSIPROGID, entry )
+ {
+ if (child->Parent == progid)
+ mark_progid_for_uninstall( package, child );
+ }
+}
+
static void mark_mime_for_install( MSIMIME *mime )
{
if (!mime)
@@ -729,7 +749,6 @@ static void mark_mime_for_install( MSIMIME *mime )
static UINT register_appid(const MSIAPPID *appid, LPCWSTR app )
{
- static const WCHAR szAppID[] = { 'A','p','p','I','D',0 };
static const WCHAR szRemoteServerName[] =
{'R','e','m','o','t','e','S','e','r','v','e','r','N','a','m','e',0};
static const WCHAR szLocalService[] =
@@ -776,24 +795,13 @@ static UINT register_appid(const MSIAPPID *appid, LPCWSTR app )
UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
{
- /*
- * Again I am assuming the words, "Whose key file represents" when referring
- * to a Component as to meaning that Components KeyPath file
- */
-
- UINT rc;
- MSIRECORD *uirow;
- static const WCHAR szCLSID[] = { 'C','L','S','I','D',0 };
- static const WCHAR szProgID[] = { 'P','r','o','g','I','D',0 };
- static const WCHAR szVIProgID[] = { 'V','e','r','s','i','o','n','I','n','d','e','p','e','n','d','e','n','t','P','r','o','g','I','D',0 };
- static const WCHAR szAppID[] = { 'A','p','p','I','D',0 };
static const WCHAR szFileType_fmt[] = {'F','i','l','e','T','y','p','e','\\','%','s','\\','%','i',0};
+ MSIRECORD *uirow;
HKEY hkey,hkey2,hkey3;
MSICLASS *cls;
load_classes_and_such(package);
- rc = RegCreateKeyW(HKEY_CLASSES_ROOT,szCLSID,&hkey);
- if (rc != ERROR_SUCCESS)
+ if (RegCreateKeyW(HKEY_CLASSES_ROOT, szCLSID, &hkey) != ERROR_SUCCESS)
return ERROR_FUNCTION_FAILED;
LIST_FOR_EACH_ENTRY( cls, &package->classes, MSICLASS, entry )
@@ -812,17 +820,21 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
if (!feature)
continue;
- /*
- * MSDN says that these are based on Feature not on Component.
- */
if (feature->ActionRequest != INSTALLSTATE_LOCAL &&
feature->ActionRequest != INSTALLSTATE_ADVERTISED )
{
- TRACE("Feature %s not scheduled for installation, skipping regstration of class %s\n",
+ TRACE("Feature %s not scheduled for installation, skipping registration of class %s\n",
debugstr_w(feature->Feature), debugstr_w(cls->clsid));
continue;
}
+ file = get_loaded_file( package, comp->KeyPath );
+ if (!file)
+ {
+ TRACE("COM server not provided, skipping class %s\n", debugstr_w(cls->clsid));
+ continue;
+ }
+
TRACE("Registering class %s (%p)\n", debugstr_w(cls->clsid), cls);
cls->Installed = TRUE;
@@ -834,12 +846,6 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
msi_reg_set_val_str( hkey2, NULL, cls->Description );
RegCreateKeyW( hkey2, cls->Context, &hkey3 );
- file = get_loaded_file( package, comp->KeyPath );
- if (!file)
- {
- TRACE("COM server not provided, skipping class %s\n", debugstr_w(cls->clsid));
- continue;
- }
/*
* FIXME: Implement install on demand (advertised components).
@@ -887,35 +893,18 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
if (cls->AppID)
{
MSIAPPID *appid = cls->AppID;
-
msi_reg_set_val_str( hkey2, szAppID, appid->AppID );
-
register_appid( appid, cls->Description );
}
if (cls->IconPath)
- {
- static const WCHAR szDefaultIcon[] =
- {'D','e','f','a','u','l','t','I','c','o','n',0};
-
msi_reg_set_subkey_val( hkey2, szDefaultIcon, NULL, cls->IconPath );
- }
if (cls->DefInprocHandler)
- {
- static const WCHAR szInproc[] =
- {'I','n','p','r','o','c','H','a','n','d','l','e','r',0};
-
- msi_reg_set_subkey_val( hkey2, szInproc, NULL, cls->DefInprocHandler );
- }
+ msi_reg_set_subkey_val( hkey2, szInprocHandler, NULL, cls->DefInprocHandler );
if (cls->DefInprocHandler32)
- {
- static const WCHAR szInproc32[] =
- {'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',0};
-
- msi_reg_set_subkey_val( hkey2, szInproc32, NULL, cls->DefInprocHandler32 );
- }
+ msi_reg_set_subkey_val( hkey2, szInprocHandler32, NULL, cls->DefInprocHandler32 );
RegCloseKey(hkey2);
@@ -947,14 +936,92 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
}
uirow = MSI_CreateRecord(1);
-
MSI_RecordSetStringW( uirow, 1, cls->clsid );
ui_actiondata(package,szRegisterClassInfo,uirow);
msiobj_release(&uirow->hdr);
}
RegCloseKey(hkey);
- return rc;
+ return ERROR_SUCCESS;
+}
+
+UINT ACTION_UnregisterClassInfo( MSIPACKAGE *package )
+{
+ static const WCHAR szFileType[] = {'F','i','l','e','T','y','p','e','\\',0};
+ MSIRECORD *uirow;
+ MSICLASS *cls;
+ HKEY hkey, hkey2;
+
+ load_classes_and_such( package );
+ if (RegOpenKeyW( HKEY_CLASSES_ROOT, szCLSID, &hkey ) != ERROR_SUCCESS)
+ return ERROR_SUCCESS;
+
+ LIST_FOR_EACH_ENTRY( cls, &package->classes, MSICLASS, entry )
+ {
+ MSIFEATURE *feature;
+ MSICOMPONENT *comp;
+ LPWSTR filetype;
+ LONG res;
+
+ comp = cls->Component;
+ if (!comp)
+ continue;
+
+ feature = cls->Feature;
+ if (!feature)
+ continue;
+
+ if (feature->ActionRequest != INSTALLSTATE_ABSENT)
+ {
+ TRACE("Feature %s not scheduled for removal, skipping unregistration of class %s\n",
+ debugstr_w(feature->Feature), debugstr_w(cls->clsid));
+ continue;
+ }
+ feature->Action = feature->ActionRequest;
+
+ TRACE("Unregistering class %s (%p)\n", debugstr_w(cls->clsid), cls);
+
+ cls->Installed = FALSE;
+ mark_progid_for_uninstall( package, cls->ProgID );
+
+ res = RegDeleteTreeW( hkey, cls->clsid );
+ if (res != ERROR_SUCCESS)
+ WARN("Failed to delete class key %d\n", res);
+
+ if (cls->AppID)
+ {
+ res = RegOpenKeyW( HKEY_CLASSES_ROOT, szAppID, &hkey2 );
+ if (res == ERROR_SUCCESS)
+ {
+ res = RegDeleteKeyW( hkey2, cls->AppID->AppID );
+ if (res != ERROR_SUCCESS)
+ WARN("Failed to delete appid key %d\n", res);
+ RegCloseKey( hkey2 );
+ }
+ }
+ if (cls->FileTypeMask)
+ {
+ filetype = msi_alloc( (strlenW( szFileType ) + strlenW( cls->clsid ) + 1) * sizeof(WCHAR) );
+ if (filetype)
+ {
+ strcpyW( filetype, szFileType );
+ strcatW( filetype, cls->clsid );
+ res = RegDeleteTreeW( HKEY_CLASSES_ROOT, filetype );
+ msi_free( filetype );
+
+ if (res != ERROR_SUCCESS)
+ WARN("Failed to delete file type %d\n", res);
+ }
+ }
+
+ uirow = MSI_CreateRecord( 1 );
+ MSI_RecordSetStringW( uirow, 1, cls->clsid );
+ ui_actiondata( package, szUnregisterClassInfo, uirow );
+ msiobj_release( &uirow->hdr );
+ }
+
+ RegCloseKey( hkey );
+ return ERROR_SUCCESS;
}
static LPCWSTR get_clsid_of_progid( const MSIPROGID *progid )
@@ -972,11 +1039,7 @@ static LPCWSTR get_clsid_of_progid( const MSIPROGID *progid )
static UINT register_progid( const MSIPROGID* progid )
{
- static const WCHAR szCLSID[] = { 'C','L','S','I','D',0 };
- static const WCHAR szDefaultIcon[] =
- {'D','e','f','a','u','l','t','I','c','o','n',0};
- static const WCHAR szCurVer[] =
- {'C','u','r','V','e','r',0};
+ static const WCHAR szCurVer[] = {'C','u','r','V','e','r',0};
HKEY hkey = 0;
UINT rc;
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index f13f5b9..d5a81a4 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -962,6 +962,7 @@ extern UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package);
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_UnregisterFonts(MSIPACKAGE *package);
/* Helpers */
@@ -1084,6 +1085,14 @@ static const WCHAR szWindowsFolder[] = {'W','i','n','d','o','w','s','F','o','l',
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 szCLSID[] = {'C','L','S','I','D',0};
+static const WCHAR szProgID[] = {'P','r','o','g','I','D',0};
+static const WCHAR szVIProgID[] = {'V','e','r','s','i','o','n','I','n','d','e','p','e','n','d','e','n','t','P','r','o','g','I','D',0};
+static const WCHAR szAppID[] = {'A','p','p','I','D',0};
+static const WCHAR szDefaultIcon[] = {'D','e','f','a','u','l','t','I','c','o','n',0};
+static const WCHAR szInprocHandler[] = {'I','n','p','r','o','c','H','a','n','d','l','e','r',0};
+static const WCHAR szInprocHandler32[] = {'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',0};
/* memory allocation macro functions */
static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1);
--
1.7.0
More information about the wine-patches
mailing list