Hans Leidekker : msi: Implement the UnregisterTypeLibraries standard action .

Alexandre Julliard julliard at winehq.org
Fri Feb 12 10:17:43 CST 2010


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

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Fri Feb 12 10:32:35 2010 +0100

msi: Implement the UnregisterTypeLibraries standard action.

---

 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);
 




More information about the wine-cvs mailing list