[PATCH 1/5] msi: Use MsiProcessMessage() to send error messages.
Zebediah Figura
z.figura12 at gmail.com
Sun Jul 23 15:50:53 CDT 2017
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
dlls/msi/action.c | 51 +++------------------
dlls/msi/dialog.c | 112 -----------------------------------------------
dlls/msi/media.c | 41 +++++------------
dlls/msi/msi.rc | 12 +++--
dlls/msi/msipriv.h | 2 -
dlls/msi/package.c | 112 +++++++++++++++++++++++++++++++++++++++--------
dlls/msi/resource.h | 23 +++++++---
dlls/msi/tests/package.c | 41 +++++++++++++++++
8 files changed, 173 insertions(+), 221 deletions(-)
diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 2d05ba1..55a16d9 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -5448,43 +5448,6 @@ UINT ACTION_ForceReboot(MSIPACKAGE *package)
return ERROR_INSTALL_SUSPEND;
}
-WCHAR *msi_build_error_string( MSIPACKAGE *package, UINT error, DWORD count, ... )
-{
- static const WCHAR query[] =
- {'S','E','L','E','C','T',' ','`','M','e','s','s','a','g','e','`',' ',
- 'F','R','O','M',' ','`','E','r','r','o','r','`',' ','W','H','E','R','E',' ',
- '`','E','r','r','o','r','`',' ','=',' ','%','i',0};
- MSIRECORD *rec, *row;
- DWORD i, size = 0;
- va_list va;
- const WCHAR *str;
- WCHAR *data;
-
- if (!(row = MSI_QueryGetRecord( package->db, query, error ))) return 0;
-
- rec = MSI_CreateRecord( count + 2 );
- str = MSI_RecordGetString( row, 1 );
- MSI_RecordSetStringW( rec, 0, str );
- msiobj_release( &row->hdr );
- MSI_RecordSetInteger( rec, 1, error );
-
- va_start( va, count );
- for (i = 0; i < count; i++)
- {
- str = va_arg( va, const WCHAR *);
- MSI_RecordSetStringW( rec, i + 2, str );
- }
- va_end( va );
-
- MSI_FormatRecordW( package, rec, NULL, &size );
- size++;
- data = msi_alloc( size * sizeof(WCHAR) );
- if (size > 1) MSI_FormatRecordW( package, rec, data, &size );
- else data[0] = 0;
- msiobj_release( &rec->hdr );
- return data;
-}
-
static UINT ACTION_ResolveSource(MSIPACKAGE* package)
{
DWORD attrib;
@@ -5502,7 +5465,8 @@ static UINT ACTION_ResolveSource(MSIPACKAGE* package)
attrib = GetFileAttributesW(package->db->path);
if (attrib == INVALID_FILE_ATTRIBUTES)
{
- LPWSTR prompt, msg;
+ MSIRECORD *record;
+ LPWSTR prompt;
DWORD size = 0;
rc = MsiSourceListGetInfoW(package->ProductCode, NULL,
@@ -5518,19 +5482,18 @@ static UINT ACTION_ResolveSource(MSIPACKAGE* package)
else
prompt = strdupW(package->db->path);
- msg = msi_build_error_string(package, 1302, 1, prompt);
+ record = MSI_CreateRecord(2);
+ MSI_RecordSetInteger(record, 1, MSIERR_INSERTDISK);
+ MSI_RecordSetStringW(record, 2, prompt);
msi_free(prompt);
while(attrib == INVALID_FILE_ATTRIBUTES)
{
- rc = MessageBoxW(NULL, msg, NULL, MB_OKCANCEL);
+ MSI_RecordSetStringW(record, 0, NULL);
+ rc = MSI_ProcessMessage(package, INSTALLMESSAGE_ERROR, record);
if (rc == IDCANCEL)
- {
- msi_free(msg);
return ERROR_INSTALL_USEREXIT;
- }
attrib = GetFileAttributesW(package->db->path);
}
- msi_free(msg);
rc = ERROR_SUCCESS;
}
else
diff --git a/dlls/msi/dialog.c b/dlls/msi/dialog.c
index c4a94f1..0c46efd 100644
--- a/dlls/msi/dialog.c
+++ b/dlls/msi/dialog.c
@@ -4101,109 +4101,6 @@ void msi_event_cleanup_all_subscriptions( MSIPACKAGE *package )
}
}
-static UINT error_dialog_handler( msi_dialog *dialog, const WCHAR *event, const WCHAR *argument )
-{
- static const WCHAR end_dialog[] = {'E','n','d','D','i','a','l','o','g',0};
- static const WCHAR error_abort[] = {'E','r','r','o','r','A','b','o','r','t',0};
- static const WCHAR error_cancel[] = {'E','r','r','o','r','C','a','n','c','e','l',0};
- static const WCHAR error_no[] = {'E','r','r','o','r','N','o',0};
- static const WCHAR result_prop[] = {
- 'M','S','I','E','r','r','o','r','D','i','a','l','o','g','R','e','s','u','l','t',0
- };
-
- if ( strcmpW( event, end_dialog ) )
- return ERROR_SUCCESS;
-
- if ( !strcmpW( argument, error_abort ) || !strcmpW( argument, error_cancel ) ||
- !strcmpW( argument, error_no ) )
- {
- msi_set_property( dialog->package->db, result_prop, error_abort, -1 );
- }
-
- msi_event_cleanup_all_subscriptions( dialog->package );
- msi_dialog_end_dialog( dialog );
-
- return ERROR_SUCCESS;
-}
-
-static UINT msi_error_dialog_set_error( MSIPACKAGE *package, LPWSTR error_dialog, LPWSTR error )
-{
- MSIRECORD * row;
-
- static const WCHAR update[] =
- {'U','P','D','A','T','E',' ','`','C','o','n','t','r','o','l','`',' ',
- 'S','E','T',' ','`','T','e','x','t','`',' ','=',' ','\'','%','s','\'',' ',
- 'W','H','E','R','E', ' ','`','D','i','a','l','o','g','_','`',' ','=',' ','\'','%','s','\'',' ',
- 'A','N','D',' ','`','C','o','n','t','r','o','l','`',' ','=',' ',
- '\'','E','r','r','o','r','T','e','x','t','\'',0};
-
- row = MSI_QueryGetRecord( package->db, update, error, error_dialog );
- if (!row)
- return ERROR_FUNCTION_FAILED;
-
- msiobj_release(&row->hdr);
- return ERROR_SUCCESS;
-}
-
-UINT msi_spawn_error_dialog( MSIPACKAGE *package, LPWSTR error_dialog, LPWSTR error )
-{
- msi_dialog *dialog;
- WCHAR result[MAX_PATH];
- UINT r = ERROR_SUCCESS;
- DWORD size = MAX_PATH;
- int res;
-
- static const WCHAR pn_prop[] = {'P','r','o','d','u','c','t','N','a','m','e',0};
- static const WCHAR title_fmt[] = {'%','s',' ','W','a','r','n','i','n','g',0};
- static const WCHAR error_abort[] = {'E','r','r','o','r','A','b','o','r','t',0};
- static const WCHAR result_prop[] = {
- 'M','S','I','E','r','r','o','r','D','i','a','l','o','g','R','e','s','u','l','t',0
- };
-
- if ((package->ui_level & INSTALLUILEVEL_MASK) == INSTALLUILEVEL_NONE) return ERROR_SUCCESS;
-
- if ( !error_dialog )
- {
- LPWSTR product_name = msi_dup_property( package->db, pn_prop );
- WCHAR title[MAX_PATH];
-
- sprintfW( title, title_fmt, product_name );
- res = MessageBoxW( NULL, error, title, MB_OKCANCEL | MB_ICONWARNING );
-
- msi_free( product_name );
-
- if ( res == IDOK )
- return ERROR_SUCCESS;
- else
- return ERROR_FUNCTION_FAILED;
- }
-
- r = msi_error_dialog_set_error( package, error_dialog, error );
- if ( r != ERROR_SUCCESS )
- return r;
-
- dialog = dialog_create( package, error_dialog, package->dialog, error_dialog_handler );
- if ( !dialog )
- return ERROR_FUNCTION_FAILED;
-
- dialog->finished = FALSE;
- r = dialog_run_message_loop( dialog );
- if ( r != ERROR_SUCCESS )
- goto done;
-
- r = msi_get_property( package->db, result_prop, result, &size );
- if ( r != ERROR_SUCCESS)
- r = ERROR_SUCCESS;
-
- if ( !strcmpW( result, error_abort ) )
- r = ERROR_FUNCTION_FAILED;
-
-done:
- msi_dialog_destroy( dialog );
-
- return r;
-}
-
static void MSI_ClosePreview( MSIOBJECTHDR *arg )
{
MSIPREVIEW *preview = (MSIPREVIEW *)arg;
@@ -4564,19 +4461,10 @@ INT ACTION_ShowDialog( MSIPACKAGE *package, const WCHAR *dialog )
if (!rc)
{
- static const WCHAR szActionNotFound[] =
- {'D','E','B','U','G',':',' ','E','r','r','o','r',' ','[','1',']',':',' ',' ',
- 'A','c','t','i','o','n',' ','n','o','t',' ','f','o','u','n','d',':',' ','[','2',']',0};
- WCHAR template[1024];
MSIRECORD *row = MSI_CreateRecord(2);
if (!row) return -1;
- MSI_RecordSetStringW(row, 0, szActionNotFound);
MSI_RecordSetInteger(row, 1, 2726);
MSI_RecordSetStringW(row, 2, dialog);
- MSI_ProcessMessageVerbatim(package, INSTALLMESSAGE_INFO, row);
-
- LoadStringW(msi_hInstance, IDS_INSTALLERROR, template, 1024);
- MSI_RecordSetStringW(row, 0, template);
MSI_ProcessMessage(package, INSTALLMESSAGE_INFO, row);
msiobj_release(&row->hdr);
diff --git a/dlls/msi/media.c b/dlls/msi/media.c
index bbfdd6f..0bb883b 100644
--- a/dlls/msi/media.c
+++ b/dlls/msi/media.c
@@ -32,6 +32,7 @@
#include "shlwapi.h"
#include "objidl.h"
#include "wine/unicode.h"
+#include "resource.h"
WINE_DEFAULT_DEBUG_CHANNEL(msi);
@@ -78,44 +79,22 @@ static BOOL source_matches_volume(MSIMEDIAINFO *mi, LPCWSTR source_root)
static UINT msi_change_media(MSIPACKAGE *package, MSIMEDIAINFO *mi)
{
- LPWSTR error, error_dialog;
+ MSIRECORD *record;
LPWSTR source_dir;
- UINT r = ERROR_SUCCESS;
+ UINT r = IDRETRY;
- static const WCHAR error_prop[] = {'E','r','r','o','r','D','i','a','l','o','g',0};
-
- if ((package->ui_level & INSTALLUILEVEL_MASK) == INSTALLUILEVEL_NONE &&
- !gUIHandlerA && !gUIHandlerW && !gUIHandlerRecord) return ERROR_SUCCESS;
-
- error = msi_build_error_string(package, 1302, 1, mi->disk_prompt);
- error_dialog = msi_dup_property(package->db, error_prop);
source_dir = msi_dup_property(package->db, szSourceDir);
+ record = MSI_CreateRecord(2);
- while (r == ERROR_SUCCESS && !source_matches_volume(mi, source_dir))
+ while (r == IDRETRY && !source_matches_volume(mi, source_dir))
{
- r = msi_spawn_error_dialog(package, error_dialog, error);
-
- if (gUIHandlerW)
- {
- gUIHandlerW(gUIContext, MB_RETRYCANCEL | INSTALLMESSAGE_ERROR, error);
- }
- else if (gUIHandlerA)
- {
- char *msg = strdupWtoA(error);
- gUIHandlerA(gUIContext, MB_RETRYCANCEL | INSTALLMESSAGE_ERROR, msg);
- msi_free(msg);
- }
- else if (gUIHandlerRecord)
- {
- MSIHANDLE rec = MsiCreateRecord(1);
- MsiRecordSetStringW(rec, 0, error);
- gUIHandlerRecord(gUIContextRecord, MB_RETRYCANCEL | INSTALLMESSAGE_ERROR, rec);
- MsiCloseHandle(rec);
- }
+ MSI_RecordSetStringW(record, 0, NULL);
+ MSI_RecordSetInteger(record, 1, MSIERR_CABNOTFOUND);
+ MSI_RecordSetStringW(record, 2, mi->disk_prompt);
+ r = MSI_ProcessMessage(package, INSTALLMESSAGE_ERROR | MB_RETRYCANCEL, record);
}
- msi_free(error);
- msi_free(error_dialog);
+ msiobj_release(&record->hdr);
msi_free(source_dir);
return r;
diff --git a/dlls/msi/msi.rc b/dlls/msi/msi.rc
index 73a600a..357bc5a 100644
--- a/dlls/msi/msi.rc
+++ b/dlls/msi/msi.rc
@@ -64,25 +64,23 @@ STRINGTABLE
15 "choose which folder contains %s"
}
-/* Install message format strings */
+/* Error messages */
STRINGTABLE
{
IDS_FATALEXIT "{{Fatal error: }}"
IDS_ERROR "{{Error [1]. }}"
IDS_WARNING "Warning [1]."
IDS_INFO "Info [1]."
+ IDS_INSTALLERROR "The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is [1]. {{The arguments are: [2], [3], [4]}}"
IDS_OUTOFDISKSPACE "{{Disk full: }}"
IDS_ACTIONSTART "Action %s: [1]. [2]"
IDS_COMMONDATA "Message type: [1], Argument: [2]{, [3]}"
-}
-
-/* Install message template strings */
-STRINGTABLE
-{
IDS_INFO_ACTIONSTART "Action start %s: [1]."
IDS_INFO_ACTIONENDED "Action ended %s: [1]. Return value [2]."
IDS_INFO_LOGGINGSTART "=== Logging started: %s %s ==="
- IDS_INSTALLERROR "The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is [1]. {{The arguments are: [2], [3], [4]}}"
+
+ IDS_ERR_INSERTDISK "Please insert the disk: [2]"
+ IDS_ERR_CABNOTFOUND "Source file not found{{(cabinet)}}: [2]. Verify that the file exists and that you can access it."
}
/* Standard action description strings */
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 84e53ff..91c614e 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -952,7 +952,6 @@ extern LONG msi_reg_set_subkey_val( HKEY hkey, LPCWSTR path, LPCWSTR name, LPCWS
extern void msi_dialog_check_messages( HANDLE ) DECLSPEC_HIDDEN;
extern void msi_dialog_destroy( msi_dialog* ) DECLSPEC_HIDDEN;
extern void msi_dialog_unregister_class( void ) DECLSPEC_HIDDEN;
-extern UINT msi_spawn_error_dialog( MSIPACKAGE*, LPWSTR, LPWSTR ) DECLSPEC_HIDDEN;
/* summary information */
extern UINT msi_get_suminfo( IStorage *stg, UINT uiUpdateCount, MSISUMMARYINFO **si ) DECLSPEC_HIDDEN;
@@ -1039,7 +1038,6 @@ extern WCHAR *msi_create_component_advertise_string(MSIPACKAGE *, MSICOMPONENT *
extern void ACTION_UpdateComponentStates(MSIPACKAGE *package, MSIFEATURE *feature) DECLSPEC_HIDDEN;
extern UINT msi_register_unique_action(MSIPACKAGE *, const WCHAR *) DECLSPEC_HIDDEN;
extern BOOL msi_action_is_unique(const MSIPACKAGE *, const WCHAR *) DECLSPEC_HIDDEN;
-extern WCHAR *msi_build_error_string(MSIPACKAGE *, UINT, DWORD, ...) DECLSPEC_HIDDEN;
extern UINT msi_set_last_used_source(LPCWSTR product, LPCWSTR usersid,
MSIINSTALLCONTEXT context, DWORD options, LPCWSTR value) DECLSPEC_HIDDEN;
extern UINT msi_create_empty_local_file(LPWSTR path, LPCWSTR suffix) DECLSPEC_HIDDEN;
diff --git a/dlls/msi/package.c b/dlls/msi/package.c
index 4c44a84..c3b4f5f 100644
--- a/dlls/msi/package.c
+++ b/dlls/msi/package.c
@@ -1848,6 +1848,64 @@ static INT internal_ui_handler(MSIPACKAGE *package, INSTALLMESSAGE eMessageType,
}
}
+static const WCHAR szActionNotFound[] = {'D','E','B','U','G',':',' ','E','r','r','o','r',' ','[','1',']',':',' ',' ','A','c','t','i','o','n',' ','n','o','t',' ','f','o','u','n','d',':',' ','[','2',']',0};
+
+static const struct
+{
+ int id;
+ const WCHAR *text;
+}
+internal_errors[] =
+{
+ {2726, szActionNotFound},
+ {0}
+};
+
+static LPCWSTR get_internal_error_message(int error)
+{
+ int i = 0;
+
+ while (internal_errors[i].id != 0)
+ {
+ if (internal_errors[i].id == error)
+ return internal_errors[i].text;
+ i++;
+ }
+
+ FIXME("missing error message %d\n", error);
+ return NULL;
+}
+
+/* Returned string must be freed */
+static LPWSTR msi_get_error_message(MSIDATABASE *db, int error)
+{
+ static const WCHAR query[] =
+ {'S','E','L','E','C','T',' ','`','M','e','s','s','a','g','e','`',' ',
+ 'F','R','O','M',' ','`','E','r','r','o','r','`',' ','W','H','E','R','E',' ',
+ '`','E','r','r','o','r','`',' ','=',' ','%','i',0};
+ MSIRECORD *record;
+ LPWSTR ret = NULL;
+
+ if ((record = MSI_QueryGetRecord(db, query, error)))
+ {
+ ret = msi_dup_record_field(record, 1);
+ msiobj_release(&record->hdr);
+ }
+ else if (error < 2000)
+ {
+ int len = LoadStringW(msi_hInstance, IDS_ERROR_BASE + error, (LPWSTR) &ret, 0);
+ if (len)
+ {
+ ret = msi_alloc((len + 1) * sizeof(WCHAR));
+ LoadStringW(msi_hInstance, IDS_ERROR_BASE + error, ret, len + 1);
+ }
+ else
+ ret = NULL;
+ }
+
+ return ret;
+}
+
INT MSI_ProcessMessageVerbatim(MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIRECORD *record)
{
LPWSTR message = {0};
@@ -1954,34 +2012,49 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIREC
case INSTALLMESSAGE_OUTOFDISKSPACE:
if (MSI_RecordGetInteger(record, 1) != MSI_NULL_INTEGER)
{
- WCHAR template_prefix[1024];
- WCHAR *template_rec, *template;
- UINT prefix_id = 0;
+ /* error message */
+
+ LPWSTR template;
+ LPWSTR template_rec = NULL, template_prefix = NULL;
+ int error = MSI_RecordGetInteger(record, 1);
if (MSI_RecordIsNull(record, 0))
{
- LoadStringW(msi_hInstance, IDS_INSTALLERROR, template_prefix, 1024);
- MSI_RecordSetStringW(record, 0, template_prefix);
- break;
+ if (error >= 32)
+ {
+ template_rec = msi_get_error_message(package->db, error);
+
+ if (!template_rec && error >= 2000)
+ {
+ /* internal error, not localized */
+ if ((template_rec = (LPWSTR) get_internal_error_message(error)))
+ {
+ MSI_RecordSetStringW(record, 0, template_rec);
+ MSI_ProcessMessageVerbatim(package, INSTALLMESSAGE_INFO, record);
+ }
+ template_rec = msi_get_error_message(package->db, MSIERR_INSTALLERROR);
+ MSI_RecordSetStringW(record, 0, template_rec);
+ MSI_ProcessMessageVerbatim(package, eMessageType, record);
+ msi_free(template_rec);
+ return 0;
+ }
+ }
}
+ else
+ template_rec = msi_dup_record_field(record, 0);
- if ((eMessageType & 0xff000000) == INSTALLMESSAGE_USER)
- break;
+ template_prefix = msi_get_error_message(package->db, eMessageType >> 24);
+ if (!template_prefix) template_prefix = strdupW(szEmpty);
- switch(eMessageType & 0xff000000)
+ if (!template_rec)
{
- case INSTALLMESSAGE_FATALEXIT: prefix_id = IDS_FATALEXIT; break;
- case INSTALLMESSAGE_ERROR: prefix_id = IDS_ERROR; break;
- case INSTALLMESSAGE_WARNING: prefix_id = IDS_WARNING; break;
- case INSTALLMESSAGE_INFO: prefix_id = IDS_INFO; break;
- case INSTALLMESSAGE_OUTOFDISKSPACE: prefix_id = IDS_OUTOFDISKSPACE; break;
+ /* always returns 0 */
+ MSI_RecordSetStringW(record, 0, template_prefix);
+ MSI_ProcessMessageVerbatim(package, eMessageType, record);
+ msi_free(template_prefix);
+ return 0;
}
- LoadStringW(msi_hInstance, prefix_id, template_prefix, 1024);
-
- template_rec = msi_dup_record_field(record, 0);
- if (!template_rec) return ERROR_OUTOFMEMORY;
-
template = msi_alloc((strlenW(template_rec) + strlenW(template_prefix) + 1) * sizeof(WCHAR));
if (!template) return ERROR_OUTOFMEMORY;
@@ -1989,6 +2062,7 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIREC
strcatW(template, template_rec);
MSI_RecordSetStringW(record, 0, template);
+ msi_free(template_prefix);
msi_free(template_rec);
msi_free(template);
}
diff --git a/dlls/msi/resource.h b/dlls/msi/resource.h
index 77c0aa1..88d4e3e 100644
--- a/dlls/msi/resource.h
+++ b/dlls/msi/resource.h
@@ -16,18 +16,29 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#define IDS_FATALEXIT 1000
-#define IDS_ERROR 1001
-#define IDS_WARNING 1002
-#define IDS_INFO 1004
-#define IDS_OUTOFDISKSPACE 1007
+#define MSIERR_INSTALLERROR 5
+
+#define MSIERR_INSERTDISK 1302
+#define MSIERR_CABNOTFOUND 1311
+
+#define IDS_ERROR_BASE 10000
+
+#define IDS_FATALEXIT (IDS_ERROR_BASE)
+#define IDS_ERROR (IDS_ERROR_BASE + 1)
+#define IDS_WARNING (IDS_ERROR_BASE + 2)
+#define IDS_INFO (IDS_ERROR_BASE + 4)
+#define IDS_INSTALLERROR (IDS_ERROR_BASE + MSIERR_INSTALLERROR)
+#define IDS_OUTOFDISKSPACE (IDS_ERROR_BASE + 7)
+
+#define IDS_ERR_INSERTDISK (IDS_ERROR_BASE + MSIERR_INSERTDISK)
+#define IDS_ERR_CABNOTFOUND (IDS_ERROR_BASE + MSIERR_CABNOTFOUND)
+
#define IDS_ACTIONSTART 1008
#define IDS_COMMONDATA 1011
#define IDS_INFO_ACTIONSTART 1050
#define IDS_INFO_ACTIONENDED 1051
#define IDS_INFO_LOGGINGSTART 1052
-#define IDS_INSTALLERROR 1053
#define IDS_DESC_ALLOCATEREGISTRYSPACE 1100
#define IDS_DESC_APPSEARCH 1101
diff --git a/dlls/msi/tests/package.c b/dlls/msi/tests/package.c
index d978286..4e2d63c 100644
--- a/dlls/msi/tests/package.c
+++ b/dlls/msi/tests/package.c
@@ -9377,6 +9377,22 @@ static const struct externalui_message processmessage_actiondata_sequence[] = {
{0}
};
+static const struct externalui_message processmessage_error_sequence[] = {
+ {INSTALLMESSAGE_USER, 3, {"", "1311", "banana", "guava"}, {0, 1, 1, 1}},
+ {0}
+};
+
+static const struct externalui_message processmessage_internal_error_sequence[] = {
+ {INSTALLMESSAGE_INFO, 3, {"DEBUG: Error [1]: Action not found: [2]", "2726", "banana", "guava"}, {1, 1, 1, 1}},
+ {INSTALLMESSAGE_USER, 3, {"internal error", "2726", "banana", "guava"}, {1, 1, 1, 1}},
+ {0}
+};
+
+static const struct externalui_message processmessage_error_format_sequence[] = {
+ {INSTALLMESSAGE_USER, 3, {"", "2726", "banana", "guava"}, {0, 1, 1, 1}},
+ {0}
+};
+
static const struct externalui_message doaction_costinitialize_sequence[] = {
{INSTALLMESSAGE_ACTIONSTART, 3, {"", "CostInitialize", "", ""}, {0, 1, 0, 1}},
{INSTALLMESSAGE_INFO, 2, {"", "CostInitialize", ""}, {0, 1, 1}},
@@ -9519,6 +9535,11 @@ static void test_externalui_message(void)
r = MsiDatabaseImportA(hdb, CURR_DIR, "forcecodepage.idt");
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ r = run_query(hdb, "CREATE TABLE `Error` (`Error` SHORT NOT NULL, `Message` CHAR(0) PRIMARY KEY `Error`)");
+ ok(r == ERROR_SUCCESS, "Failed to create Error table: %u\n", r);
+ r = run_query(hdb, "INSERT INTO `Error` (`Error`, `Message`) VALUES (5, 'internal error')");
+ ok(r == ERROR_SUCCESS, "Failed to insert into Error table: %u\n", r);
+
r = MsiOpenPackageA(NULL, &hpkg);
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
ok_sequence(empty_sequence, "MsiOpenPackage with NULL db", FALSE);
@@ -9564,6 +9585,26 @@ static void test_externalui_message(void)
ok(r == 1, "Expected 1, got %d\n", r);
ok_sequence(processmessage_actiondata_sequence, "MsiProcessMessage(INSTALLMESSAGE_ACTIONDATA)", FALSE);
+ /* non-internal error */
+ MsiRecordSetStringA(hrecord, 0, NULL);
+ MsiRecordSetInteger(hrecord, 1, 1311);
+ r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
+ ok(r == 1, "Expected 1, got %d\n", r);
+ ok_sequence(processmessage_error_sequence, "MsiProcessMessage non-internal error", FALSE);
+
+ /* internal error */
+ MsiRecordSetStringA(hrecord, 0, NULL);
+ MsiRecordSetInteger(hrecord, 1, 2726);
+ r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
+ ok(r == 0, "Expected 0, got %d\n", r);
+ ok_sequence(processmessage_internal_error_sequence, "MsiProcessMessage internal error", FALSE);
+
+ /* with format field */
+ MsiRecordSetStringA(hrecord, 0, "starfruit");
+ r = MsiProcessMessage(hpkg, INSTALLMESSAGE_USER, hrecord);
+ ok(r == 1, "Expected 1, got %d\n", r);
+ ok_sequence(processmessage_error_format_sequence, "MsiProcessMessage error", FALSE);
+
/* Test a standard action */
r = MsiDoActionA(hpkg, "CostInitialize");
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
--
2.7.4
More information about the wine-patches
mailing list