From 17d7effd2af347da27e6cbcd322318add60a1c6b Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Fri, 2 Apr 2010 10:39:20 +0200 Subject: [PATCH] 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 4f1be9aaa34..25cd4fc1558 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 d6e88084cc1..744acfbf8d3 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 @@ -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 e81237c0a31..7ab1c87d613 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};