msi: More fully implement the ExecuteAction action.
Major changes are adding several new UI messages (many of obscure purpose), and executing the action given in the EXECUTEACTION property rather than always running the InstallExecuteSequence table. 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:
parent
52672282b8
commit
5c39852c1e
|
@ -157,6 +157,8 @@ static const WCHAR szValidateProductID[] =
|
||||||
{'V','a','l','i','d','a','t','e','P','r','o','d','u','c','t','I','D',0};
|
{'V','a','l','i','d','a','t','e','P','r','o','d','u','c','t','I','D',0};
|
||||||
static const WCHAR szWriteEnvironmentStrings[] =
|
static const WCHAR szWriteEnvironmentStrings[] =
|
||||||
{'W','r','i','t','e','E','n','v','i','r','o','n','m','e','n','t','S','t','r','i','n','g','s',0};
|
{'W','r','i','t','e','E','n','v','i','r','o','n','m','e','n','t','S','t','r','i','n','g','s',0};
|
||||||
|
static const WCHAR szINSTALL[] =
|
||||||
|
{'I','N','S','T','A','L','L',0};
|
||||||
|
|
||||||
static INT ui_actionstart(MSIPACKAGE *package, LPCWSTR action, LPCWSTR description, LPCWSTR template)
|
static INT ui_actionstart(MSIPACKAGE *package, LPCWSTR action, LPCWSTR description, LPCWSTR template)
|
||||||
{
|
{
|
||||||
|
@ -5560,13 +5562,122 @@ end:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT iterate_properties(MSIRECORD *record, void *param)
|
||||||
|
{
|
||||||
|
static const WCHAR prop_template[] =
|
||||||
|
{'P','r','o','p','e','r','t','y','(','S',')',':',' ','[','1',']',' ','=',' ','[','2',']',0};
|
||||||
|
MSIRECORD *uirow;
|
||||||
|
|
||||||
|
uirow = MSI_CloneRecord(record);
|
||||||
|
if (!uirow) return ERROR_OUTOFMEMORY;
|
||||||
|
MSI_RecordSetStringW(uirow, 0, prop_template);
|
||||||
|
MSI_ProcessMessage(param, INSTALLMESSAGE_INFO|MB_ICONHAND, uirow);
|
||||||
|
msiobj_release(&uirow->hdr);
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static UINT ACTION_ExecuteAction(MSIPACKAGE *package)
|
static UINT ACTION_ExecuteAction(MSIPACKAGE *package)
|
||||||
{
|
{
|
||||||
|
static const WCHAR prop_query[] =
|
||||||
|
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','_','P','r','o','p','e','r','t','y','`',0};
|
||||||
|
WCHAR *productname;
|
||||||
|
WCHAR *action;
|
||||||
|
MSIQUERY *view;
|
||||||
|
MSIRECORD *uirow;
|
||||||
UINT rc;
|
UINT rc;
|
||||||
|
|
||||||
|
/* Send COMMONDATA and INFO messages. */
|
||||||
|
/* FIXME: when should these messages be sent? [see also MsiOpenPackage()] */
|
||||||
|
uirow = MSI_CreateRecord(3);
|
||||||
|
if (!uirow) return ERROR_OUTOFMEMORY;
|
||||||
|
MSI_RecordSetStringW(uirow, 0, NULL);
|
||||||
|
MSI_RecordSetInteger(uirow, 1, 0);
|
||||||
|
MSI_RecordSetInteger(uirow, 2, package->num_langids ? package->langids[0] : 0);
|
||||||
|
MSI_RecordSetInteger(uirow, 3, msi_get_string_table_codepage(package->db->strings));
|
||||||
|
MSI_ProcessMessageVerbatim(package, INSTALLMESSAGE_COMMONDATA, uirow);
|
||||||
|
/* FIXME: send INSTALLMESSAGE_PROGRESS */
|
||||||
|
MSI_ProcessMessageVerbatim(package, INSTALLMESSAGE_COMMONDATA, uirow);
|
||||||
|
MSI_ProcessMessage(package, INSTALLMESSAGE_COMMONDATA, uirow);
|
||||||
|
|
||||||
|
productname = msi_dup_property(package->db, INSTALLPROPERTY_PRODUCTNAMEW);
|
||||||
|
MSI_RecordSetInteger(uirow, 1, 1);
|
||||||
|
MSI_RecordSetStringW(uirow, 2, productname);
|
||||||
|
MSI_RecordSetStringW(uirow, 3, NULL);
|
||||||
|
MSI_ProcessMessage(package, INSTALLMESSAGE_COMMONDATA, uirow);
|
||||||
|
msiobj_release(&uirow->hdr);
|
||||||
|
|
||||||
|
package->LastActionResult = MSI_NULL_INTEGER;
|
||||||
|
|
||||||
|
action = msi_dup_property(package->db, szEXECUTEACTION);
|
||||||
|
if (!action) action = msi_strdupW(szINSTALL, strlenW(szINSTALL));
|
||||||
|
|
||||||
|
/* Perform the action. Top-level actions trigger a sequence. */
|
||||||
|
if (!strcmpW(action, szINSTALL))
|
||||||
|
{
|
||||||
|
/* Send ACTIONSTART/INFO and INSTALLSTART. */
|
||||||
|
ui_actionstart(package, szINSTALL, NULL, NULL);
|
||||||
|
ui_actioninfo(package, szINSTALL, TRUE, 0);
|
||||||
|
uirow = MSI_CreateRecord(2);
|
||||||
|
if (!uirow)
|
||||||
|
{
|
||||||
|
rc = ERROR_OUTOFMEMORY;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
MSI_RecordSetStringW(uirow, 0, NULL);
|
||||||
|
MSI_RecordSetStringW(uirow, 1, productname);
|
||||||
|
MSI_RecordSetStringW(uirow, 2, package->ProductCode);
|
||||||
|
MSI_ProcessMessage(package, INSTALLMESSAGE_INSTALLSTART, uirow);
|
||||||
|
msiobj_release(&uirow->hdr);
|
||||||
|
|
||||||
|
/* Perform the installation. Always use the ExecuteSequence. */
|
||||||
package->script->InWhatSequence |= SEQUENCE_EXEC;
|
package->script->InWhatSequence |= SEQUENCE_EXEC;
|
||||||
rc = ACTION_ProcessExecSequence(package,FALSE);
|
rc = ACTION_ProcessExecSequence(package, FALSE);
|
||||||
|
|
||||||
|
/* Send return value and INSTALLEND. */
|
||||||
|
ui_actioninfo(package, szINSTALL, FALSE, !rc);
|
||||||
|
uirow = MSI_CreateRecord(3);
|
||||||
|
if (!uirow)
|
||||||
|
{
|
||||||
|
rc = ERROR_OUTOFMEMORY;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
MSI_RecordSetStringW(uirow, 0, NULL);
|
||||||
|
MSI_RecordSetStringW(uirow, 1, productname);
|
||||||
|
MSI_RecordSetStringW(uirow, 2, package->ProductCode);
|
||||||
|
MSI_RecordSetInteger(uirow, 3, !rc);
|
||||||
|
MSI_ProcessMessage(package, INSTALLMESSAGE_INSTALLEND, uirow);
|
||||||
|
msiobj_release(&uirow->hdr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rc = ACTION_PerformAction(package, action, SCRIPT_NONE);
|
||||||
|
|
||||||
|
/* Send all set properties. */
|
||||||
|
if (!MSI_OpenQuery(package->db, &view, prop_query))
|
||||||
|
{
|
||||||
|
MSI_IterateRecords(view, NULL, iterate_properties, package);
|
||||||
|
msiobj_release(&view->hdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* And finally, toggle the cancel off and on. */
|
||||||
|
uirow = MSI_CreateRecord(2);
|
||||||
|
if (!uirow)
|
||||||
|
{
|
||||||
|
rc = ERROR_OUTOFMEMORY;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
MSI_RecordSetStringW(uirow, 0, NULL);
|
||||||
|
MSI_RecordSetInteger(uirow, 1, 2);
|
||||||
|
MSI_RecordSetInteger(uirow, 2, 0);
|
||||||
|
MSI_ProcessMessageVerbatim(package, INSTALLMESSAGE_COMMONDATA, uirow);
|
||||||
|
MSI_RecordSetInteger(uirow, 2, 1);
|
||||||
|
MSI_ProcessMessageVerbatim(package, INSTALLMESSAGE_COMMONDATA, uirow);
|
||||||
|
msiobj_release(&uirow->hdr);
|
||||||
|
|
||||||
|
end:
|
||||||
|
msi_free(productname);
|
||||||
|
msi_free(action);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1203,6 +1203,7 @@ static const WCHAR szLangResource[] = {'\\','V','a','r','F','i','l','e','I','n',
|
||||||
static const WCHAR szInstallLocation[] = {'I','n','s','t','a','l','l','L','o','c','a','t','i','o','n',0};
|
static const WCHAR szInstallLocation[] = {'I','n','s','t','a','l','l','L','o','c','a','t','i','o','n',0};
|
||||||
static const WCHAR szProperty[] = {'P','r','o','p','e','r','t','y',0};
|
static const WCHAR szProperty[] = {'P','r','o','p','e','r','t','y',0};
|
||||||
static const WCHAR szUninstallable[] = {'U','n','i','n','s','t','a','l','l','a','b','l','e',0};
|
static const WCHAR szUninstallable[] = {'U','n','i','n','s','t','a','l','l','a','b','l','e',0};
|
||||||
|
static const WCHAR szEXECUTEACTION[] = {'E','X','E','C','U','T','E','A','C','T','I','O','N',0};
|
||||||
|
|
||||||
/* memory allocation macro functions */
|
/* memory allocation macro functions */
|
||||||
static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1);
|
static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1);
|
||||||
|
|
|
@ -1763,6 +1763,8 @@ static INT internal_ui_handler(MSIPACKAGE *package, INSTALLMESSAGE eMessageType,
|
||||||
case INSTALLMESSAGE_INFO:
|
case INSTALLMESSAGE_INFO:
|
||||||
case INSTALLMESSAGE_INITIALIZE:
|
case INSTALLMESSAGE_INITIALIZE:
|
||||||
case INSTALLMESSAGE_TERMINATE:
|
case INSTALLMESSAGE_TERMINATE:
|
||||||
|
case INSTALLMESSAGE_INSTALLSTART:
|
||||||
|
case INSTALLMESSAGE_INSTALLEND:
|
||||||
return 0;
|
return 0;
|
||||||
case INSTALLMESSAGE_SHOWDIALOG:
|
case INSTALLMESSAGE_SHOWDIALOG:
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue