msi: Add a basic internal UI implementation.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2017-07-05 23:31:52 -05:00 committed by Alexandre Julliard
parent c83b8e0a16
commit 48237e249b
5 changed files with 136 additions and 54 deletions

View File

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

View File

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

View File

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

View File

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

View File

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