[1/3] msi: Implement the UnregisterTypeLibraries standard action.
Hans Leidekker
hans at codeweavers.com
Fri Feb 12 03:32:35 CST 2010
---
dlls/msi/action.c | 70 ++++++++++++++++++++++++++++++++++----
dlls/msi/msipriv.h | 1 +
dlls/msi/tests/install.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 146 insertions(+), 8 deletions(-)
diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 31870bd..0f1877e 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -2862,8 +2862,6 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param)
HMODULE module;
HRESULT hr;
- static const WCHAR szTYPELIB[] = {'T','Y','P','E','L','I','B',0};
-
component = MSI_RecordGetString(row,3);
comp = get_loaded_component(package,component);
if (!comp)
@@ -2967,6 +2965,68 @@ static UINT ACTION_RegisterTypeLibraries(MSIPACKAGE *package)
return rc;
}
+static UINT ITERATE_UnregisterTypeLibraries( MSIRECORD *row, LPVOID param )
+{
+ MSIPACKAGE *package = param;
+ LPCWSTR component, guid;
+ MSICOMPONENT *comp;
+ GUID libid;
+ UINT version;
+ LCID language;
+ SYSKIND syskind;
+ HRESULT hr;
+
+ component = MSI_RecordGetString( row, 3 );
+ comp = get_loaded_component( package, component );
+ if (!comp)
+ return ERROR_SUCCESS;
+
+ if (!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_ABSENT ))
+ {
+ TRACE("Skipping, component is not scheduled for uninstall\n");
+
+ comp->Action = comp->Installed;
+ return ERROR_SUCCESS;
+ }
+ comp->Action = INSTALLSTATE_ABSENT;
+
+ guid = MSI_RecordGetString( row, 1 );
+ CLSIDFromString( (LPWSTR)guid, &libid );
+ version = MSI_RecordGetInteger( row, 4 );
+ language = MSI_RecordGetInteger( row, 2 );
+
+#ifdef _WIN64
+ syskind = SYS_WIN64;
+#else
+ syskind = SYS_WIN32;
+#endif
+
+ hr = UnRegisterTypeLib( &libid, (version >> 8) & 0xffff, version & 0xff, language, syskind );
+ if (FAILED(hr))
+ {
+ WARN("Failed to unregister typelib: %08x\n", hr);
+ }
+
+ return ERROR_SUCCESS;
+}
+
+static UINT ACTION_UnregisterTypeLibraries( MSIPACKAGE *package )
+{
+ UINT rc;
+ MSIQUERY *view;
+ static const WCHAR query[] =
+ {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+ '`','T','y','p','e','L','i','b','`',0};
+
+ rc = MSI_DatabaseOpenViewW( package->db, query, &view );
+ if (rc != ERROR_SUCCESS)
+ return ERROR_SUCCESS;
+
+ rc = MSI_IterateRecords( view, NULL, ITERATE_UnregisterTypeLibraries, package );
+ msiobj_release( &view->hdr );
+ return rc;
+}
+
static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param)
{
MSIPACKAGE *package = param;
@@ -6452,12 +6512,6 @@ static UINT ACTION_UnregisterProgIdInfo( MSIPACKAGE *package )
return msi_unimplemented_action_stub( package, "UnregisterProgIdInfo", table );
}
-static UINT ACTION_UnregisterTypeLibraries( MSIPACKAGE *package )
-{
- static const WCHAR table[] = { 'T','y','p','e','L','i','b',0 };
- return msi_unimplemented_action_stub( package, "UnregisterTypeLibraries", table );
-}
-
typedef UINT (*STANDARDACTIONHANDLER)(MSIPACKAGE*);
static const struct
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index f81184b..8022afc 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -1075,6 +1075,7 @@ static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};
static const WCHAR szProductID[] = {'P','r','o','d','u','c','t','I','D',0};
static const WCHAR szPIDTemplate[] = {'P','I','D','T','e','m','p','l','a','t','e',0};
static const WCHAR szPIDKEY[] = {'P','I','D','K','E','Y',0};
+static const WCHAR szTYPELIB[] = {'T','Y','P','E','L','I','B',0};
/* memory allocation macro functions */
static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1);
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c
index 96b5117..83e7220 100644
--- a/dlls/msi/tests/install.c
+++ b/dlls/msi/tests/install.c
@@ -1320,6 +1320,50 @@ static const CHAR odbc_media_dat[] = "DiskId\tLastSequence\tDiskPrompt\tCabinet\
"Media\tDiskId\n"
"1\t5\t\t\tDISK1\t\n";
+static const CHAR tl_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
+ "s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
+ "File\tFile\n"
+ "typelib.dll\ttypelib\ttypelib.dll\t1000\t\t\t8192\t1\n";
+
+static const CHAR tl_feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
+ "s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
+ "Feature\tFeature\n"
+ "typelib\t\t\ttypelib feature\t1\t2\tMSITESTDIR\t0\n";
+
+static const CHAR tl_feature_comp_dat[] = "Feature_\tComponent_\n"
+ "s38\ts72\n"
+ "FeatureComponents\tFeature_\tComponent_\n"
+ "typelib\ttypelib\n";
+
+static const CHAR tl_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
+ "s72\tS38\ts72\ti2\tS255\tS72\n"
+ "Component\tComponent\n"
+ "typelib\t{BB4C26FD-89D8-4E49-AF1C-DB4DCB5BF1B0}\tMSITESTDIR\t0\t\ttypelib.dll\n";
+
+static const CHAR tl_typelib_dat[] = "LibID\tLanguage\tComponent_\tVersion\tDescription\tDirectory_\tFeature_\tCost\n"
+ "s38\ti2\ts72\tI4\tL128\tS72\ts38\tI4\n"
+ "TypeLib\tLibID\tLanguage\tComponent_\n"
+ "{EAC5166A-9734-4D91-878F-1DD02304C66C}\t0\ttypelib\t1793\t\tMSITESTDIR\ttypelib\t\n";
+
+static const CHAR tl_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
+ "s72\tS255\tI2\n"
+ "InstallExecuteSequence\tAction\n"
+ "LaunchConditions\t\t100\n"
+ "CostInitialize\t\t800\n"
+ "FileCost\t\t900\n"
+ "CostFinalize\t\t1000\n"
+ "InstallValidate\t\t1400\n"
+ "InstallInitialize\t\t1500\n"
+ "ProcessComponents\t\t1600\n"
+ "RemoveFiles\t\t1700\n"
+ "InstallFiles\t\t2000\n"
+ "RegisterTypeLibraries\tREGISTER_TYPELIB=1\t3000\n"
+ "UnregisterTypeLibraries\t\t3100\n"
+ "RegisterProduct\t\t5100\n"
+ "PublishFeatures\t\t5200\n"
+ "PublishProduct\t\t5300\n"
+ "InstallFinalize\t\t6000\n";
+
typedef struct _msi_table
{
const CHAR *filename;
@@ -2131,6 +2175,19 @@ static const msi_table odbc_tables[] =
ADD_TABLE(property)
};
+static const msi_table tl_tables[] =
+{
+ ADD_TABLE(tl_component),
+ ADD_TABLE(directory),
+ ADD_TABLE(tl_feature),
+ ADD_TABLE(tl_feature_comp),
+ ADD_TABLE(tl_file),
+ ADD_TABLE(tl_typelib),
+ ADD_TABLE(tl_install_exec_seq),
+ ADD_TABLE(media),
+ ADD_TABLE(property)
+};
+
/* cabinet definitions */
/* make the max size large so there is only one cab file */
@@ -8022,6 +8079,31 @@ static void test_install_remove_odbc(void)
delete_test_files();
}
+static void test_register_typelib(void)
+{
+ UINT r;
+
+ create_test_files();
+ create_file("msitest\\typelib.dll", 1000);
+ create_database(msifile, tl_tables, sizeof(tl_tables) / sizeof(msi_table));
+
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+ r = MsiInstallProductA(msifile, "REGISTER_TYPELIB=1");
+ todo_wine ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
+
+ r = MsiInstallProductA(msifile, NULL);
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ r = MsiInstallProductA(msifile, "REMOVE=ALL");
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ ok(!delete_pf("msitest\\typelib.dll", TRUE), "file not removed\n");
+ todo_wine ok(!delete_pf("msitest", FALSE), "directory not removed\n");
+
+ delete_test_files();
+}
+
START_TEST(install)
{
DWORD len;
@@ -8121,6 +8203,7 @@ START_TEST(install)
test_register_font();
test_validate_product_id();
test_install_remove_odbc();
+ test_register_typelib();
DeleteFileA(log_file);
--
1.6.3.3
More information about the wine-patches
mailing list