[PATCH 4/4] msi: Implement deferral for standard and custom actions.

Zebediah Figura z.figura12 at gmail.com
Wed Jun 6 00:59:23 CDT 2018


Fixes https://bugs.winehq.org/show_bug.cgi?id=34989.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
Tested for regressions against winetricks-test and Microsoft Office 2010.

 dlls/msi/action.c        | 89 ++++++++++++++++++++++++++++++++++++++++++++++--
 dlls/msi/assembly.c      |  6 ++++
 dlls/msi/classes.c       | 24 +++++++++++++
 dlls/msi/custom.c        |  1 +
 dlls/msi/files.c         | 18 ++++++++++
 dlls/msi/font.c          |  6 ++++
 dlls/msi/msipriv.h       |  1 +
 dlls/msi/tests/custom.c  | 70 +------------------------------------
 dlls/msi/tests/install.c |  1 -
 9 files changed, 143 insertions(+), 73 deletions(-)

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 7c71800..b22be7a 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -105,8 +105,6 @@ static const WCHAR szIsolateComponents[] =
     {'I','s','o','l','a','t','e','C','o','m','p','o','n','e','n','t','s',0};
 static const WCHAR szMigrateFeatureStates[] =
     {'M','i','g','r','a','t','e','F','e','a','t','u','r','e','S','t','a','t','e','s',0};
-static const WCHAR szMsiUnpublishAssemblies[] = 
-    {'M','s','i','U','n','p','u','b','l','i','s','h','A','s','s','e','m','b','l','i','e','s',0};
 static const WCHAR szInstallODBC[] = 
     {'I','n','s','t','a','l','l','O','D','B','C',0};
 static const WCHAR szInstallServices[] = 
@@ -824,6 +822,9 @@ static UINT ACTION_CreateFolders(MSIPACKAGE *package)
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szCreateFolders);
+
     rc = MSI_DatabaseOpenViewW( package->db, query, &view );
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -903,6 +904,9 @@ static UINT ACTION_RemoveFolders( MSIPACKAGE *package )
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szRemoveFolders);
+
     rc = MSI_DatabaseOpenViewW( package->db, query, &view );
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -2977,6 +2981,9 @@ static UINT ACTION_WriteRegistryValues(MSIPACKAGE *package)
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szWriteRegistryValues);
+
     rc = MSI_DatabaseOpenViewW(package->db, query, &view);
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -3211,6 +3218,9 @@ static UINT ACTION_RemoveRegistryValues( MSIPACKAGE *package )
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szRemoveRegistryValues);
+
     rc = MSI_DatabaseOpenViewW( package->db, registry_query, &view );
     if (rc == ERROR_SUCCESS)
     {
@@ -3529,9 +3539,13 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
 
     TRACE("\n");
 
-    squash_guid( package->ProductCode, squashed_pc );
     msi_set_sourcedir_props(package, FALSE);
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szProcessComponents);
+
+    squash_guid( package->ProductCode, squashed_pc );
+
     LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
     {
         MSIRECORD *uirow;
@@ -3805,6 +3819,9 @@ static UINT ACTION_RegisterTypeLibraries(MSIPACKAGE *package)
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szRegisterTypeLibraries);
+
     rc = MSI_DatabaseOpenViewW(package->db, query, &view);
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -3866,6 +3883,9 @@ static UINT ACTION_UnregisterTypeLibraries( MSIPACKAGE *package )
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szUnregisterTypeLibraries);
+
     rc = MSI_DatabaseOpenViewW( package->db, query, &view );
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -4050,6 +4070,9 @@ static UINT ACTION_CreateShortcuts(MSIPACKAGE *package)
     HRESULT res;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szCreateShortcuts);
+
     rc = MSI_DatabaseOpenViewW(package->db, query, &view);
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -4103,6 +4126,9 @@ static UINT ACTION_RemoveShortcuts( MSIPACKAGE *package )
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szRemoveShortcuts);
+
     rc = MSI_DatabaseOpenViewW( package->db, query, &view );
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -4474,6 +4500,9 @@ static UINT ACTION_PublishProduct(MSIPACKAGE *package)
     HKEY hukey = NULL, hudkey = NULL;
     MSIRECORD *uirow;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szPublishProduct);
+
     if (!list_empty(&package->patches))
     {
         rc = msi_publish_patches(package);
@@ -4636,6 +4665,9 @@ static UINT ACTION_WriteIniValues(MSIPACKAGE *package)
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szWriteIniValues);
+
     rc = MSI_DatabaseOpenViewW(package->db, query, &view);
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -4779,6 +4811,9 @@ static UINT ACTION_RemoveIniValues( MSIPACKAGE *package )
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szRemoveIniValues);
+
     rc = MSI_DatabaseOpenViewW( package->db, query, &view );
     if (rc == ERROR_SUCCESS)
     {
@@ -4864,6 +4899,9 @@ static UINT ACTION_SelfRegModules(MSIPACKAGE *package)
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szSelfRegModules);
+
     rc = MSI_DatabaseOpenViewW(package->db, query, &view);
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -4914,6 +4952,9 @@ static UINT ACTION_SelfUnregModules( MSIPACKAGE *package )
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szSelfUnregModules);
+
     rc = MSI_DatabaseOpenViewW( package->db, query, &view );
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -4929,6 +4970,9 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
     UINT rc;
     HKEY hkey = NULL, userdata = NULL;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szPublishFeatures);
+
     if (!msi_check_publish(package))
         return ERROR_SUCCESS;
 
@@ -5069,6 +5113,9 @@ static UINT ACTION_UnpublishFeatures(MSIPACKAGE *package)
 {
     MSIFEATURE *feature;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szUnpublishFeatures);
+
     if (!msi_check_unpublish(package))
         return ERROR_SUCCESS;
 
@@ -5221,6 +5268,9 @@ static UINT ACTION_RegisterProduct(MSIPACKAGE *package)
     HKEY hkey, props, upgrade_key;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szRegisterProduct);
+
     /* FIXME: also need to publish if the product is in advertise mode */
     if (!msi_check_publish(package))
         return ERROR_SUCCESS;
@@ -5538,6 +5588,9 @@ static UINT ACTION_RegisterUser(MSIPACKAGE *package)
         {0},
     };
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szRegisterUser);
+
     if (msi_check_unpublish(package))
     {
         MSIREG_DeleteUserDataProductKey(package->ProductCode, package->Context);
@@ -5860,6 +5913,9 @@ static UINT ACTION_PublishComponents(MSIPACKAGE *package)
     MSIQUERY *view;
     UINT rc;
     
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szPublishComponents);
+
     rc = MSI_DatabaseOpenViewW(package->db, query, &view);
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -5932,6 +5988,9 @@ static UINT ACTION_UnpublishComponents( MSIPACKAGE *package )
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szUnpublishComponents);
+
     rc = MSI_DatabaseOpenViewW( package->db, query, &view );
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -6080,6 +6139,9 @@ static UINT ACTION_InstallServices( MSIPACKAGE *package )
     MSIQUERY *view;
     UINT rc;
     
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szInstallServices);
+
     rc = MSI_DatabaseOpenViewW(package->db, query, &view);
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -6251,6 +6313,9 @@ static UINT ACTION_StartServices( MSIPACKAGE *package )
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szStartServices);
+
     rc = MSI_DatabaseOpenViewW(package->db, query, &view);
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -6414,6 +6479,9 @@ static UINT ACTION_StopServices( MSIPACKAGE *package )
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szStopServices);
+
     rc = MSI_DatabaseOpenViewW(package->db, query, &view);
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -6497,6 +6565,9 @@ static UINT ACTION_DeleteServices( MSIPACKAGE *package )
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szDeleteServices);
+
     rc = MSI_DatabaseOpenViewW( package->db, query, &view );
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -6767,6 +6838,9 @@ static UINT ACTION_InstallODBC( MSIPACKAGE *package )
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szInstallODBC);
+
     rc = MSI_DatabaseOpenViewW(package->db, driver_query, &view);
     if (rc == ERROR_SUCCESS)
     {
@@ -6945,6 +7019,9 @@ static UINT ACTION_RemoveODBC( MSIPACKAGE *package )
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szRemoveODBC);
+
     rc = MSI_DatabaseOpenViewW( package->db, driver_query, &view );
     if (rc == ERROR_SUCCESS)
     {
@@ -7291,6 +7368,9 @@ static UINT ACTION_WriteEnvironmentStrings( MSIPACKAGE *package )
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szWriteEnvironmentStrings);
+
     rc = MSI_DatabaseOpenViewW(package->db, query, &view);
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -7433,6 +7513,9 @@ static UINT ACTION_RemoveEnvironmentStrings( MSIPACKAGE *package )
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szRemoveEnvironmentStrings);
+
     rc = MSI_DatabaseOpenViewW( package->db, query, &view );
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
diff --git a/dlls/msi/assembly.c b/dlls/msi/assembly.c
index bccd114..59fd332 100644
--- a/dlls/msi/assembly.c
+++ b/dlls/msi/assembly.c
@@ -652,6 +652,9 @@ UINT ACTION_MsiPublishAssemblies( MSIPACKAGE *package )
 {
     MSICOMPONENT *comp;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szMsiPublishAssemblies);
+
     LIST_FOR_EACH_ENTRY(comp, &package->components, MSICOMPONENT, entry)
     {
         LONG res;
@@ -717,6 +720,9 @@ UINT ACTION_MsiUnpublishAssemblies( MSIPACKAGE *package )
 {
     MSICOMPONENT *comp;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szMsiUnpublishAssemblies);
+
     LIST_FOR_EACH_ENTRY(comp, &package->components, MSICOMPONENT, entry)
     {
         LONG res;
diff --git a/dlls/msi/classes.c b/dlls/msi/classes.c
index 60cc3c1..293aa10 100644
--- a/dlls/msi/classes.c
+++ b/dlls/msi/classes.c
@@ -753,6 +753,9 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
     MSICLASS *cls;
     UINT r;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szRegisterClassInfo);
+
     r = load_classes_and_such( package );
     if (r != ERROR_SUCCESS)
         return r;
@@ -918,6 +921,9 @@ UINT ACTION_UnregisterClassInfo( MSIPACKAGE *package )
     HKEY hkey, hkey2;
     UINT r;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szUnregisterClassInfo);
+
     r = load_classes_and_such( package );
     if (r != ERROR_SUCCESS)
         return r;
@@ -1083,6 +1089,9 @@ UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package)
     MSIRECORD *uirow;
     UINT r;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szRegisterProgIdInfo);
+
     r = load_classes_and_such( package );
     if (r != ERROR_SUCCESS)
         return r;
@@ -1143,6 +1152,9 @@ UINT ACTION_UnregisterProgIdInfo( MSIPACKAGE *package )
     LONG res;
     UINT r;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szUnregisterProgIdInfo);
+
     r = load_classes_and_such( package );
     if (r != ERROR_SUCCESS)
         return r;
@@ -1255,6 +1267,9 @@ UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package)
     LONG res;
     UINT r;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szRegisterExtensionInfo);
+
     r = load_classes_and_such( package );
     if (r != ERROR_SUCCESS)
         return r;
@@ -1363,6 +1378,9 @@ UINT ACTION_UnregisterExtensionInfo( MSIPACKAGE *package )
     LONG res;
     UINT r;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szUnregisterExtensionInfo);
+
     r = load_classes_and_such( package );
     if (r != ERROR_SUCCESS)
         return r;
@@ -1446,6 +1464,9 @@ UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package)
     MSIMIME *mt;
     UINT r;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szRegisterMIMEInfo);
+
     r = load_classes_and_such( package );
     if (r != ERROR_SUCCESS)
         return r;
@@ -1500,6 +1521,9 @@ UINT ACTION_UnregisterMIMEInfo( MSIPACKAGE *package )
     MSIMIME *mime;
     UINT r;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szUnregisterMIMEInfo);
+
     r = load_classes_and_such( package );
     if (r != ERROR_SUCCESS)
         return r;
diff --git a/dlls/msi/custom.c b/dlls/msi/custom.c
index 8deebe5..2d66409 100644
--- a/dlls/msi/custom.c
+++ b/dlls/msi/custom.c
@@ -1159,6 +1159,7 @@ static BOOL action_type_matches_script( UINT type, UINT script )
     switch (script)
     {
     case SCRIPT_NONE:
+        return FALSE;
     case SCRIPT_INSTALL:
         return !(type & msidbCustomActionTypeCommit) && !(type & msidbCustomActionTypeRollback);
     case SCRIPT_COMMIT:
diff --git a/dlls/msi/files.c b/dlls/msi/files.c
index f6cf3e7..5a88c14 100644
--- a/dlls/msi/files.c
+++ b/dlls/msi/files.c
@@ -359,6 +359,9 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
 
     msi_set_sourcedir_props(package, FALSE);
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szInstallFiles);
+
     schedule_install_files(package);
     mi = msi_alloc_zero( sizeof(MSIMEDIAINFO) );
 
@@ -584,6 +587,9 @@ UINT ACTION_PatchFiles( MSIPACKAGE *package )
 
     TRACE("%p\n", package);
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szPatchFiles);
+
     mi = msi_alloc_zero( sizeof(MSIMEDIAINFO) );
 
     TRACE("extracting files\n");
@@ -1002,6 +1008,9 @@ UINT ACTION_MoveFiles( MSIPACKAGE *package )
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szMoveFiles);
+
     rc = MSI_DatabaseOpenViewW(package->db, query, &view);
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -1134,6 +1143,9 @@ UINT ACTION_DuplicateFiles(MSIPACKAGE *package)
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szDuplicateFiles);
+
     rc = MSI_DatabaseOpenViewW(package->db, query, &view);
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -1210,6 +1222,9 @@ UINT ACTION_RemoveDuplicateFiles( MSIPACKAGE *package )
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szRemoveDuplicateFiles);
+
     rc = MSI_DatabaseOpenViewW( package->db, query, &view );
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -1350,6 +1365,9 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package )
     MSIFILE *file;
     UINT r;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szRemoveFiles);
+
     r = MSI_DatabaseOpenViewW(package->db, query, &view);
     if (r == ERROR_SUCCESS)
     {
diff --git a/dlls/msi/font.c b/dlls/msi/font.c
index 5c1e59d..fc05006 100644
--- a/dlls/msi/font.c
+++ b/dlls/msi/font.c
@@ -294,6 +294,9 @@ UINT ACTION_RegisterFonts(MSIPACKAGE *package)
     MSIQUERY *view;
     UINT rc;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szRegisterFonts);
+
     rc = MSI_DatabaseOpenViewW(package->db, query, &view);
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -374,6 +377,9 @@ UINT ACTION_UnregisterFonts( MSIPACKAGE *package )
     MSIQUERY *view;
     UINT r;
 
+    if (package->script == SCRIPT_NONE)
+        return msi_schedule_action(package, SCRIPT_INSTALL, szUnregisterFonts);
+
     r = MSI_DatabaseOpenViewW( package->db, query, &view );
     if (r != ERROR_SUCCESS)
         return ERROR_SUCCESS;
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 8acace3..93c4cea 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -1180,6 +1180,7 @@ static const WCHAR szWow6432NodeCLSID[] = {'W','o','w','6','4','3','2','N','o','
 static const WCHAR szStreams[] = {'_','S','t','r','e','a','m','s',0};
 static const WCHAR szStorages[] = {'_','S','t','o','r','a','g','e','s',0};
 static const WCHAR szMsiPublishAssemblies[] = {'M','s','i','P','u','b','l','i','s','h','A','s','s','e','m','b','l','i','e','s',0};
+static const WCHAR szMsiUnpublishAssemblies[] = {'M','s','i','U','n','p','u','b','l','i','s','h','A','s','s','e','m','b','l','i','e','s',0};
 static const WCHAR szCostingComplete[] = {'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0};
 static const WCHAR szTempFolder[] = {'T','e','m','p','F','o','l','d','e','r',0};
 static const WCHAR szDatabase[] = {'D','A','T','A','B','A','S','E',0};
diff --git a/dlls/msi/tests/custom.c b/dlls/msi/tests/custom.c
index 4d45c9e..cf1289e 100644
--- a/dlls/msi/tests/custom.c
+++ b/dlls/msi/tests/custom.c
@@ -1163,52 +1163,42 @@ static BOOL pf_exists(const char *file)
 
 UINT WINAPI cf_present(MSIHANDLE hinst)
 {
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     ok(hinst, pf_exists("msitest\\first"), "folder absent\n");
     ok(hinst, pf_exists("msitest\\second"), "folder absent\n");
     ok(hinst, pf_exists("msitest\\third"), "folder absent\n");
-}
     return ERROR_SUCCESS;
 }
 
 UINT WINAPI cf_absent(MSIHANDLE hinst)
 {
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     ok(hinst, !pf_exists("msitest\\first"), "folder present\n");
     ok(hinst, !pf_exists("msitest\\second"), "folder present\n");
     ok(hinst, !pf_exists("msitest\\third"), "folder present\n");
-}
     return ERROR_SUCCESS;
 }
 
 UINT WINAPI file_present(MSIHANDLE hinst)
 {
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     ok(hinst, pf_exists("msitest\\first\\one.txt"), "file absent\n");
     ok(hinst, pf_exists("msitest\\second\\two.txt"), "file absent\n");
-}
     return ERROR_SUCCESS;
 }
 
 UINT WINAPI file_absent(MSIHANDLE hinst)
 {
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     ok(hinst, !pf_exists("msitest\\first\\one.txt"), "file present\n");
     ok(hinst, !pf_exists("msitest\\second\\two.txt"), "file present\n");
-}
     return ERROR_SUCCESS;
 }
 
 UINT WINAPI crs_present(MSIHANDLE hinst)
 {
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED))
     ok(hinst, pf_exists("msitest\\shortcut.lnk"), "shortcut absent\n");
     return ERROR_SUCCESS;
 }
 
 UINT WINAPI crs_absent(MSIHANDLE hinst)
 {
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED))
     ok(hinst, !pf_exists("msitest\\shortcut.lnk"), "shortcut present\n");
     return ERROR_SUCCESS;
 }
@@ -1218,7 +1208,6 @@ UINT WINAPI sds_present(MSIHANDLE hinst)
     SC_HANDLE manager, service;
     manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
     service = OpenServiceA(manager, "TestService3", GENERIC_ALL);
-todo_wine
     ok(hinst, !!service, "service absent: %u\n", GetLastError());
     CloseServiceHandle(service);
     CloseServiceHandle(manager);
@@ -1252,7 +1241,6 @@ UINT WINAPI sis_absent(MSIHANDLE hinst)
     SC_HANDLE manager, service;
     manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
     service = OpenServiceA(manager, "TestService", GENERIC_ALL);
-todo_wine
     ok(hinst, !service, "service present\n");
     if (service) CloseServiceHandle(service);
     CloseServiceHandle(manager);
@@ -1269,7 +1257,6 @@ UINT WINAPI sss_started(MSIHANDLE hinst)
     service = OpenServiceA(manager, "Spooler", SC_MANAGER_ALL_ACCESS);
     ret = QueryServiceStatus(service, &status);
     ok(hinst, ret, "QueryServiceStatus failed: %u\n", GetLastError());
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED))
     ok(hinst, status.dwCurrentState == SERVICE_RUNNING, "got %u\n", status.dwCurrentState);
 
     CloseServiceHandle(service);
@@ -1296,10 +1283,8 @@ UINT WINAPI sss_stopped(MSIHANDLE hinst)
 
 UINT WINAPI rd_present(MSIHANDLE hinst)
 {
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     ok(hinst, pf_exists("msitest\\original2.txt"), "file absent\n");
     ok(hinst, pf_exists("msitest\\duplicate.txt"), "file absent\n");
-}
     ok(hinst, !pf_exists("msitest\\original3.txt"), "file present\n");
     ok(hinst, !pf_exists("msitest\\duplicate2.txt"), "file present\n");
     return ERROR_SUCCESS;
@@ -1307,10 +1292,8 @@ todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
 
 UINT WINAPI rd_absent(MSIHANDLE hinst)
 {
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     ok(hinst, !pf_exists("msitest\\original2.txt"), "file present\n");
     ok(hinst, !pf_exists("msitest\\duplicate.txt"), "file present\n");
-}
     ok(hinst, !pf_exists("msitest\\original3.txt"), "file present\n");
     ok(hinst, !pf_exists("msitest\\duplicate2.txt"), "file present\n");
     return ERROR_SUCCESS;
@@ -1333,10 +1316,8 @@ UINT WINAPI odbc_present(MSIHANDLE hinst)
         if (!strcmp(p, "ODBC test driver2"))
             gotdriver2 = 1;
     }
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     ok(hinst, gotdriver, "driver absent\n");
     ok(hinst, gotdriver2, "driver 2 absent\n");
-}
     return ERROR_SUCCESS;
 }
 
@@ -1357,10 +1338,8 @@ UINT WINAPI odbc_absent(MSIHANDLE hinst)
         if (!strcmp(p, "ODBC test driver2"))
             gotdriver2 = 1;
     }
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     ok(hinst, !gotdriver, "driver present\n");
     ok(hinst, !gotdriver2, "driver 2 present\n");
-}
     return ERROR_SUCCESS;
 }
 
@@ -1373,10 +1352,8 @@ UINT WINAPI mov_present(MSIHANDLE hinst)
 
 UINT WINAPI mov_absent(MSIHANDLE hinst)
 {
-todo_wine {
     ok(hinst, !pf_exists("msitest\\canada"), "file present\n");
     ok(hinst, !pf_exists("msitest\\dominica"), "file present\n");
-}
     return ERROR_SUCCESS;
 }
 
@@ -1410,9 +1387,7 @@ UINT WINAPI pa_present(MSIHANDLE hinst)
 
     res = RegOpenKeyA(HKEY_CURRENT_USER, path_dotnet, &key);
     ok(hinst, !res, "got %d\n", res);
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     check_reg_str(hinst, key, name_dotnet, "rcHQPHq?CA at Uv-XqMI1e>Z'q,T*76M@=YEg6My?~]");
-}
     RegCloseKey(key);
 
     return ERROR_SUCCESS;
@@ -1427,9 +1402,7 @@ UINT WINAPI pa_absent(MSIHANDLE hinst)
     ok(hinst, !res || res == ERROR_FILE_NOT_FOUND, "got %d\n", res);
     if (!res)
     {
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
         check_reg_str(hinst, key, name_dotnet, NULL);
-}
         RegCloseKey(key);
     }
     return ERROR_SUCCESS;
@@ -1462,7 +1435,6 @@ UINT WINAPI ppc_absent(MSIHANDLE hinst)
     UINT r;
 
     r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, ppc_key, 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &key);
-todo_wine
     ok(hinst, r == ERROR_FILE_NOT_FOUND, "got %u\n", r);
     return ERROR_SUCCESS;
 }
@@ -1474,12 +1446,10 @@ UINT WINAPI pub_present(MSIHANDLE hinst)
     HKEY key;
     LONG res;
 
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     res = RegOpenKeyA(HKEY_CURRENT_USER, pub_key, &key);
     ok(hinst, !res, "got %u\n", res);
     res = RegQueryValueExA(key, "english.txt", NULL, NULL, NULL, NULL);
     ok(hinst, !res, "got %u\n", res);
-}
     RegCloseKey(key);
     return ERROR_SUCCESS;
 }
@@ -1490,7 +1460,6 @@ UINT WINAPI pub_absent(MSIHANDLE hinst)
     LONG res;
 
     res = RegOpenKeyA(HKEY_CURRENT_USER, pub_key, &key);
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED))
     ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res);
     return ERROR_SUCCESS;
 }
@@ -1504,7 +1473,6 @@ UINT WINAPI pf_present(MSIHANDLE hinst)
     HKEY key;
     LONG res;
 
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, pf_classkey, 0, KEY_READ | KEY_WOW64_64KEY, &key);
     ok(hinst, !res, "got %u\n", res);
     check_reg_str(hinst, key, "feature", "");
@@ -1516,7 +1484,6 @@ todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     check_reg_str(hinst, key, "feature", "VGtfp^p+,?82 at JU1j_KE");
     check_reg_str(hinst, key, "montecristo", "VGtfp^p+,?82 at JU1j_KE");
     RegCloseKey(key);
-}
 
     return ERROR_SUCCESS;
 }
@@ -1527,11 +1494,9 @@ UINT WINAPI pf_absent(MSIHANDLE hinst)
     LONG res;
 
     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, pf_classkey, 0, KEY_READ | KEY_WOW64_64KEY, &key);
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED))
     ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res);
 
     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, pf_userkey, 0, KEY_READ | KEY_WOW64_64KEY, &key);
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED))
     ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res);
 
     return ERROR_SUCCESS;
@@ -1560,7 +1525,6 @@ UINT WINAPI pp_absent(MSIHANDLE hinst)
     LONG res;
 
     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, pp_prodkey, 0, KEY_READ | KEY_WOW64_64KEY, &key);
-todo_wine
     ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res);
 
     return ERROR_SUCCESS;
@@ -1571,7 +1535,6 @@ UINT WINAPI rci_present(MSIHANDLE hinst)
     HKEY key;
     LONG res;
 
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}",
         0, KEY_READ | KEY_WOW64_32KEY, &key);
     ok(hinst, !res, "got %u\n", res);
@@ -1584,7 +1547,6 @@ todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &key);
     ok(hinst, !res, "got %u\n", res);
     RegCloseKey(key);
-}
 
     return ERROR_SUCCESS;
 }
@@ -1594,7 +1556,6 @@ UINT WINAPI rci_absent(MSIHANDLE hinst)
     HKEY key;
     LONG res;
 
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}",
         0, KEY_READ | KEY_WOW64_32KEY, &key);
     ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res);
@@ -1604,7 +1565,6 @@ todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
 
     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "AppID\\{CFCC3B38-E683-497D-9AB4-CB40AAFE307F}", &key);
     ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res);
-}
 
     return ERROR_SUCCESS;
 }
@@ -1614,7 +1574,6 @@ UINT WINAPI rei_present(MSIHANDLE hinst)
     HKEY key;
     LONG res;
 
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &key);
     ok(hinst, !res, "got %u\n", res);
     RegCloseKey(key);
@@ -1622,7 +1581,6 @@ todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1\\shell\\Open\\command", &key);
     ok(hinst, !res, "got %u\n", res);
     RegCloseKey(key);
-}
 
     return ERROR_SUCCESS;
 }
@@ -1632,13 +1590,11 @@ UINT WINAPI rei_absent(MSIHANDLE hinst)
     HKEY key;
     LONG res;
 
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     res = RegOpenKeyA(HKEY_CLASSES_ROOT, ".extension", &key);
     ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res);
 
     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Prog.Id.1\\shell\\Open\\command", &key);
     ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res);
-}
 
     return ERROR_SUCCESS;
 }
@@ -1653,7 +1609,6 @@ UINT WINAPI font_present(MSIHANDLE hinst)
     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, font_key, 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &key);
     ok(hinst, !res, "got %u\n", res);
     res = RegQueryValueExA(key, "msi test font", NULL, NULL, NULL, NULL);
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED))
     ok(hinst, !res, "got %u\n", res);
     RegCloseKey(key);
 
@@ -1667,9 +1622,7 @@ UINT WINAPI font_absent(MSIHANDLE hinst)
 
     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, font_key, 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &key);
     ok(hinst, !res, "got %u\n", res);
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     check_reg_str(hinst, key, "msi test font", NULL);
-}
     RegCloseKey(key);
 
     return ERROR_SUCCESS;
@@ -1681,7 +1634,6 @@ UINT WINAPI rmi_present(MSIHANDLE hinst)
     LONG res;
 
     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &key);
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED))
     ok(hinst, !res, "got %u\n", res);
 
     return ERROR_SUCCESS;
@@ -1693,7 +1645,6 @@ UINT WINAPI rmi_absent(MSIHANDLE hinst)
     LONG res;
 
     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "MIME\\Database\\Content Type\\mime/type", &key);
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED))
     ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res);
 
     return ERROR_SUCCESS;
@@ -1721,7 +1672,6 @@ UINT WINAPI rp_absent(MSIHANDLE hinst)
     LONG res;
 
     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, rp_key, 0, KEY_READ | KEY_WOW64_32KEY, &key);
-todo_wine
     ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res);
 
     return ERROR_SUCCESS;
@@ -1732,7 +1682,6 @@ UINT WINAPI rpi_present(MSIHANDLE hinst)
     HKEY key;
     LONG res;
 
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}",
         0, KEY_READ | KEY_WOW64_32KEY, &key);
     ok(hinst, !res, "got %u\n", res);
@@ -1749,7 +1698,6 @@ todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Class.2", &key);
     ok(hinst, !res, "got %u\n", res);
     RegCloseKey(key);
-}
 
     return ERROR_SUCCESS;
 }
@@ -1759,7 +1707,6 @@ UINT WINAPI rpi_absent(MSIHANDLE hinst)
     HKEY key;
     LONG res;
 
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     res = RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID\\{110913E7-86D1-4BF3-9922-BA103FCDDDFA}",
         0, KEY_READ | KEY_WOW64_32KEY, &key);
     ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res);
@@ -1772,7 +1719,6 @@ todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
 
     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "Winetest.Class.2", &key);
     ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res);
-}
 
     return ERROR_SUCCESS;
 }
@@ -1799,7 +1745,6 @@ UINT WINAPI ru_absent(MSIHANDLE hinst)
     LONG res;
 
     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, ru_key, 0, KEY_READ | KEY_WOW64_64KEY, &key);
-todo_wine
     ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res);
 
     return ERROR_SUCCESS;
@@ -1814,10 +1759,8 @@ UINT WINAPI tl_present(MSIHANDLE hinst)
     HRESULT hr;
 
     hr = LoadRegTypeLib(&LIBID_register_test, 7, 1, 0, &tlb);
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED))
     ok(hinst, hr == S_OK, "got %#x\n", hr);
-    if (tlb)
-        ITypeLib_Release(tlb);
+    ITypeLib_Release(tlb);
 
     return ERROR_SUCCESS;
 }
@@ -1828,7 +1771,6 @@ UINT WINAPI tl_absent(MSIHANDLE hinst)
     HRESULT hr;
 
     hr = LoadRegTypeLib(&LIBID_register_test, 7, 1, 0, &tlb);
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED))
     ok(hinst, hr == TYPE_E_LIBNOTREGISTERED, "got %#x\n", hr);
 
     return ERROR_SUCCESS;
@@ -1840,7 +1782,6 @@ UINT WINAPI sr_present(MSIHANDLE hinst)
     LONG res;
 
     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "selfreg_test", &key);
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED))
     ok(hinst, !res, "got %u\n", res);
     RegCloseKey(key);
 
@@ -1853,7 +1794,6 @@ UINT WINAPI sr_absent(MSIHANDLE hinst)
     LONG res;
 
     res = RegOpenKeyA(HKEY_CLASSES_ROOT, "selfreg_test", &key);
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED))
     ok(hinst, res == ERROR_FILE_NOT_FOUND, "got %u\n", res);
 
     return ERROR_SUCCESS;
@@ -1866,10 +1806,8 @@ UINT WINAPI env_present(MSIHANDLE hinst)
 
     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
     ok(hinst, !res, "got %u\n", res);
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     check_reg_str(hinst, key, "MSITESTVAR3", "1");
     check_reg_str(hinst, key, "MSITESTVAR4", "1");
-}
     RegCloseKey(key);
 
     return ERROR_SUCCESS;
@@ -1882,10 +1820,8 @@ UINT WINAPI env_absent(MSIHANDLE hinst)
 
     res = RegOpenKeyA(HKEY_CURRENT_USER, "Environment", &key);
     ok(hinst, !res, "got %u\n", res);
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED)) {
     check_reg_str(hinst, key, "MSITESTVAR3", NULL);
     check_reg_str(hinst, key, "MSITESTVAR4", NULL);
-}
     RegCloseKey(key);
 
     return ERROR_SUCCESS;
@@ -1901,7 +1837,6 @@ UINT WINAPI ini_present(MSIHANDLE hinst)
     strcat(path, "\\msitest\\test.ini");
 
     len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), path);
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED))
     ok(hinst, len == 6, "got %u\n", len);
 
     return ERROR_SUCCESS;
@@ -1917,7 +1852,6 @@ UINT WINAPI ini_absent(MSIHANDLE hinst)
     strcat(path, "\\msitest\\test.ini");
 
     len = GetPrivateProfileStringA("section1", "key1", NULL, buf, sizeof(buf), path);
-todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED))
     ok(hinst, !len, "got %u\n", len);
 
     return ERROR_SUCCESS;
@@ -1930,7 +1864,6 @@ UINT WINAPI wrv_present(MSIHANDLE hinst)
 
     res = RegOpenKeyA(HKEY_CURRENT_USER, "msitest", &key);
     ok(hinst, !res, "got %u\n", res);
-    todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED))
     check_reg_str(hinst, key, "sz", "string");
     RegCloseKey(key);
 
@@ -1944,7 +1877,6 @@ UINT WINAPI wrv_absent(MSIHANDLE hinst)
 
     res = RegOpenKeyA(HKEY_CURRENT_USER, "msitest", &key);
     ok(hinst, !res, "got %u\n", res);
-    todo_wine_if(!MsiGetMode(hinst, MSIRUNMODE_SCHEDULED))
     check_reg_str(hinst, key, "sz", NULL);
     RegCloseKey(key);
 
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c
index 3eb6c80..d56a5ae 100644
--- a/dlls/msi/tests/install.c
+++ b/dlls/msi/tests/install.c
@@ -6077,7 +6077,6 @@ static void test_deferred_action(void)
     }
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
 
-todo_wine
     check_file_matches(file, "onetwo");
 
     ok(DeleteFileA(file), "Directory not created\n");
-- 
2.7.4




More information about the wine-devel mailing list