[PATCH 1/4] msi: Add a basic internal UI implementation.

Zebediah Figura z.figura12 at gmail.com
Mon Jul 3 00:34:52 CDT 2017


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/msi/msi.c          |  11 +++-
 dlls/msi/msi_main.c     |   2 +-
 dlls/msi/package.c      | 139 ++++++++++++++++++++++++++++++++----------------
 dlls/msi/tests/format.c |  20 +++++--
 dlls/msi/tests/msi.c    |  18 +++++++
 5 files changed, 136 insertions(+), 54 deletions(-)

diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c
index ce8a7be..38f7ad2 100644
--- a/dlls/msi/msi.c
+++ b/dlls/msi/msi.c
@@ -2317,7 +2317,16 @@ INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
 
     TRACE("%08x %p\n", dwUILevel, phWnd);
 
-    gUILevel = dwUILevel;
+    if (dwUILevel & ~(INSTALLUILEVEL_MASK|INSTALLUILEVEL_HIDECANCEL|INSTALLUILEVEL_PROGRESSONLY|
+                      INSTALLUILEVEL_ENDDIALOG|INSTALLUILEVEL_SOURCERESONLY))
+    {
+        FIXME("Unrecognized flags %08x\n", dwUILevel);
+        return INSTALLUILEVEL_NOCHANGE;
+    }
+
+    if (dwUILevel != INSTALLUILEVEL_NOCHANGE)
+        gUILevel = dwUILevel;
+
     if (phWnd)
     {
         gUIhwnd = *phWnd;
diff --git a/dlls/msi/msi_main.c b/dlls/msi/msi_main.c
index 11cbf41..3143118 100644
--- a/dlls/msi/msi_main.c
+++ b/dlls/msi/msi_main.c
@@ -38,7 +38,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
 static LONG dll_count;
 
 /* the UI level */
-INSTALLUILEVEL           gUILevel         = INSTALLUILEVEL_BASIC;
+INSTALLUILEVEL           gUILevel         = INSTALLUILEVEL_DEFAULT;
 HWND                     gUIhwnd          = 0;
 INSTALLUI_HANDLERA       gUIHandlerA      = NULL;
 INSTALLUI_HANDLERW       gUIHandlerW      = NULL;
diff --git a/dlls/msi/package.c b/dlls/msi/package.c
index 3a75a1c..e762f62 100644
--- a/dlls/msi/package.c
+++ b/dlls/msi/package.c
@@ -1752,13 +1752,97 @@ MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE hInstall)
     return handle;
 }
 
-INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIRECORD *record )
+static INT internal_ui_handler(MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIRECORD *record, LPCWSTR message)
 {
     static const WCHAR szActionData[] = {'A','c','t','i','o','n','D','a','t','a',0};
-    static const WCHAR szSetProgress[] = {'S','e','t','P','r','o','g','r','e','s','s',0};
     static const WCHAR szActionText[] = {'A','c','t','i','o','n','T','e','x','t',0};
-    MSIRECORD *uirow;
-    LPWSTR deformated, message = {0};
+    static const WCHAR szSetProgress[] = {'S','e','t','P','r','o','g','r','e','s','s',0};
+    static const WCHAR szWindows_Installer[] =
+        {'W','i','n','d','o','w','s',' ','I','n','s','t','a','l','l','e','r',0};
+
+    if (!package || (package->ui_level & INSTALLUILEVEL_MASK) == INSTALLUILEVEL_NONE)
+        return 0;
+
+    /* todo: check if message needs additional styles (topmost/foreground/modality?) */
+
+    switch (eMessageType & 0xff000000)
+    {
+    case INSTALLMESSAGE_FATALEXIT:
+    case INSTALLMESSAGE_ERROR:
+    case INSTALLMESSAGE_OUTOFDISKSPACE:
+        if (package->ui_level & INSTALLUILEVEL_PROGRESSONLY) return 0;
+        if (!(eMessageType & MB_ICONMASK))
+            eMessageType |= MB_ICONEXCLAMATION;
+        return MessageBoxW(gUIhwnd, message, szWindows_Installer, eMessageType & 0x00ffffff);
+    case INSTALLMESSAGE_WARNING:
+        if (package->ui_level & INSTALLUILEVEL_PROGRESSONLY) return 0;
+        if (!(eMessageType & MB_ICONMASK))
+            eMessageType |= MB_ICONASTERISK;
+        return MessageBoxW(gUIhwnd, message, szWindows_Installer, eMessageType & 0x00ffffff);
+    case INSTALLMESSAGE_USER:
+        if (package->ui_level & INSTALLUILEVEL_PROGRESSONLY) return 0;
+        if (!(eMessageType & MB_ICONMASK))
+            eMessageType |= MB_USERICON;
+        return MessageBoxW(gUIhwnd, message, szWindows_Installer, eMessageType & 0x00ffffff);
+    case INSTALLMESSAGE_INFO:
+    case INSTALLMESSAGE_INITIALIZE:
+    case INSTALLMESSAGE_TERMINATE:
+        return 0;
+    case INSTALLMESSAGE_ACTIONSTART:
+    {
+        LPWSTR deformatted;
+        MSIRECORD *uirow = MSI_CreateRecord(1);
+        if (!uirow) return -1;
+        deformat_string(package, MSI_RecordGetString(record, 2), &deformatted);
+        MSI_RecordSetStringW(uirow, 1, deformatted);
+        msi_event_fire(package, szActionText, uirow);
+
+        msi_free(deformatted);
+        msiobj_release(&uirow->hdr);
+        return 1;
+    }
+    case INSTALLMESSAGE_ACTIONDATA:
+    {
+        MSIRECORD *uirow = MSI_CreateRecord(1);
+        if (!uirow) return -1;
+        MSI_RecordSetStringW(uirow, 1, message);
+        msi_event_fire(package, szActionData, uirow);
+        msiobj_release(&uirow->hdr);
+
+        if (package->action_progress_increment)
+        {
+            uirow = MSI_CreateRecord(2);
+            if (!uirow) return -1;
+            MSI_RecordSetInteger(uirow, 1, 2);
+            MSI_RecordSetInteger(uirow, 2, package->action_progress_increment);
+            msi_event_fire(package, szSetProgress, uirow);
+            msiobj_release(&uirow->hdr);
+        }
+        return 1;
+    }
+    case INSTALLMESSAGE_PROGRESS:
+        msi_event_fire(package, szSetProgress, record);
+        return 1;
+    case INSTALLMESSAGE_COMMONDATA:
+        switch (MSI_RecordGetInteger(record, 1))
+        {
+        case 0:
+        case 1:
+            /* do nothing */
+            return 0;
+        default:
+            /* fall through */
+            ;
+        }
+    default:
+        FIXME("internal UI not implemented for message 0x%08x (UI level = %x)", eMessageType, package->ui_level);
+        return 0;
+    }
+}
+
+INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIRECORD *record )
+{
+    LPWSTR message = {0};
     DWORD len, log_type = 0;
     UINT res;
     INT rc = 0;
@@ -1879,6 +1963,9 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIREC
         rc = gUIHandlerA( gUIContext, eMessageType, msg );
     }
 
+    if (!rc)
+        rc = internal_ui_handler(package, eMessageType, record, message);
+
     if (!rc && package && package->log_file != INVALID_HANDLE_VALUE &&
         (eMessageType & 0xff000000) != INSTALLMESSAGE_PROGRESS)
     {
@@ -1889,48 +1976,6 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIREC
     msi_free( msg );
     msi_free( message );
 
-    switch (eMessageType & 0xff000000)
-    {
-    case INSTALLMESSAGE_ACTIONDATA:
-        deformat_string(package, MSI_RecordGetString(record, 2), &deformated);
-        uirow = MSI_CreateRecord(1);
-        MSI_RecordSetStringW(uirow, 1, deformated);
-        msi_free(deformated);
-
-        msi_event_fire( package, szActionData, uirow );
-        msiobj_release(&uirow->hdr);
-
-        if (package->action_progress_increment)
-        {
-            uirow = MSI_CreateRecord(2);
-            MSI_RecordSetInteger(uirow, 1, 2);
-            MSI_RecordSetInteger(uirow, 2, package->action_progress_increment);
-            msi_event_fire( package, szSetProgress, uirow );
-            msiobj_release(&uirow->hdr);
-        }
-        break;
-
-    case INSTALLMESSAGE_ACTIONSTART:
-        deformat_string(package, MSI_RecordGetString(record, 2), &deformated);
-        uirow = MSI_CreateRecord(1);
-        MSI_RecordSetStringW(uirow, 1, deformated);
-        msi_free(deformated);
-
-        msi_event_fire( package, szActionText, uirow );
-
-        msiobj_release(&uirow->hdr);
-        break;
-
-    case INSTALLMESSAGE_PROGRESS:
-        msi_event_fire( package, szSetProgress, record );
-        break;
-    }
-
-    if (package && (package->ui_level & INSTALLUILEVEL_MASK) != INSTALLUILEVEL_NONE)
-    {
-        FIXME("Internal UI not yet handled (UILevel == %x)\n", package->ui_level);
-    }
-
     return rc;
 }
 
@@ -1945,7 +1990,7 @@ INT WINAPI MsiProcessMessage( MSIHANDLE hInstall, INSTALLMESSAGE eMessageType,
         (eMessageType & 0xff000000) == INSTALLMESSAGE_TERMINATE)
         return -1;
 
-    if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ACTIONDATA &&
+    if ((eMessageType & 0xff000000) == INSTALLMESSAGE_COMMONDATA &&
         MsiRecordGetInteger(hRecord, 1) != 2)
         return -1;
 
diff --git a/dlls/msi/tests/format.c b/dlls/msi/tests/format.c
index a9a60cd..6209399 100644
--- a/dlls/msi/tests/format.c
+++ b/dlls/msi/tests/format.c
@@ -2775,13 +2775,14 @@ static void test_processmessage(void)
     ok( r == ERROR_SUCCESS, "set string failed\n");
 
     r = MsiProcessMessage(package, INSTALLMESSAGE_ACTIONSTART, hrec);
-    todo_wine
     ok( r == IDOK, "expected IDOK, got %i\n", r);
 
     r = MsiProcessMessage(package, INSTALLMESSAGE_PROGRESS, hrec);
-    todo_wine
     ok( r == IDOK, "expected IDOK, got %i\n", r);
 
+    r = MsiProcessMessage(package, INSTALLMESSAGE_INFO, hrec);
+    ok( r == 0, "expected 0, got %i\n", r);
+
     r = MsiProcessMessage(package, INSTALLMESSAGE_INITIALIZE, hrec);
     ok( r == -1, "expected -1, got %i\n", r);
 
@@ -2795,14 +2796,23 @@ static void test_processmessage(void)
 
     r = MsiRecordSetInteger(hrec, 2, 2);
     ok( r == ERROR_SUCCESS, "set integer failed\n");
-    r = MsiProcessMessage(package, INSTALLMESSAGE_INITIALIZE, hrec);
-    ok( r == -1, "expected -1, got %i\n", r);
+    r = MsiProcessMessage(package, INSTALLMESSAGE_COMMONDATA, hrec);
+    todo_wine
+    ok( r == IDOK, "expected IDOK, got %i\n", r);
 
     r = MsiRecordSetInteger(hrec, 1, 1);
     ok( r == ERROR_SUCCESS, "set integer failed\n");
-    r = MsiProcessMessage(package, INSTALLMESSAGE_INITIALIZE, hrec);
+    r = MsiProcessMessage(package, INSTALLMESSAGE_COMMONDATA, hrec);
     ok( r == -1, "expected -1, got %i\n", r);
 
+    MsiCloseHandle(package);
+
+    MsiSetInternalUI(INSTALLUILEVEL_BASIC|INSTALLUILEVEL_PROGRESSONLY, NULL);
+    helper_createpackage(msifile, &package);
+
+    r = MsiProcessMessage(package, INSTALLMESSAGE_ERROR, hrec);
+    ok( r == 0, "expected 0, got %i\n", r);
+
     MsiCloseHandle(hrec);
     MsiCloseHandle(package);
 
diff --git a/dlls/msi/tests/msi.c b/dlls/msi/tests/msi.c
index fb939ff..85ab7ba 100644
--- a/dlls/msi/tests/msi.c
+++ b/dlls/msi/tests/msi.c
@@ -14350,6 +14350,23 @@ static INT CALLBACK handler_record(LPVOID context, UINT type, MSIHANDLE record)
     return IDOK;
 }
 
+static void test_MsiSetInternalUI(void)
+{
+    INSTALLUILEVEL level;
+
+    level = MsiSetInternalUI(INSTALLUILEVEL_FULL, NULL);
+    ok(level == INSTALLUILEVEL_DEFAULT, "expected INSTALLUILEVEL_DEFAULT, got %d\n", level);
+
+    level = MsiSetInternalUI(INSTALLUILEVEL_DEFAULT, NULL);
+    ok(level == INSTALLUILEVEL_FULL, "expected INSTALLUILEVEL_FULL, got %d\n", level);
+
+    level = MsiSetInternalUI(INSTALLUILEVEL_NOCHANGE, NULL);
+    ok(level == INSTALLUILEVEL_DEFAULT, "expected INSTALLUILEVEL_DEFAULT, got %d\n", level);
+
+    level = MsiSetInternalUI(0xdeadbeef, NULL);
+    ok(level == INSTALLUILEVEL_NOCHANGE, "expected INSTALLUILEVEL_NOCHANGE, got %d\n", level);
+}
+
 static void test_MsiSetExternalUI(void)
 {
     INSTALLUI_HANDLERA ret_a;
@@ -14885,6 +14902,7 @@ START_TEST(msi)
     test_null();
     test_getcomponentpath();
     test_MsiGetFileHash();
+    test_MsiSetInternalUI();
 
     if (!pConvertSidToStringSidA)
         win_skip("ConvertSidToStringSidA not implemented\n");
-- 
2.7.4




More information about the wine-patches mailing list