James Hawkins : msi: Add support for continuous cabinets.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Nov 9 06:08:30 CST 2006
Module: wine
Branch: master
Commit: fa8fc1628a455928f36e5dc884f87ad22a717fb4
URL: http://source.winehq.org/git/wine.git/?a=commit;h=fa8fc1628a455928f36e5dc884f87ad22a717fb4
Author: James Hawkins <truiken at gmail.com>
Date: Wed Nov 8 14:07:53 2006 -0800
msi: Add support for continuous cabinets.
---
dlls/msi/files.c | 123 ++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 100 insertions(+), 23 deletions(-)
diff --git a/dlls/msi/files.c b/dlls/msi/files.c
index 151ba58..38b1f8f 100644
--- a/dlls/msi/files.c
+++ b/dlls/msi/files.c
@@ -67,6 +67,29 @@ struct media_info {
WCHAR source[MAX_PATH];
};
+static UINT msi_change_media( MSIPACKAGE *package, struct media_info *mi )
+{
+ LPWSTR error, error_dialog;
+ UINT r = ERROR_SUCCESS;
+
+ static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};
+ static const WCHAR error_prop[] = {'E','r','r','o','r','D','i','a','l','o','g',0};
+
+ if ( msi_get_property_int(package, szUILevel, 0) == INSTALLUILEVEL_NONE )
+ return ERROR_SUCCESS;
+
+ error = generate_error_string( package, 1302, 1, mi->disk_prompt );
+ error_dialog = msi_dup_property( package, error_prop );
+
+ while ( r == ERROR_SUCCESS && GetFileAttributesW( mi->source ) == INVALID_FILE_ATTRIBUTES )
+ r = msi_spawn_error_dialog( package, error_dialog, error );
+
+ msi_free( error );
+ msi_free( error_dialog );
+
+ return r;
+}
+
/*
* This is a helper function for handling embedded cabinet media
*/
@@ -210,10 +233,83 @@ static void msi_file_update_ui( MSIPACKA
ui_progress( package, 2, f->FileSize, 0, 0);
}
+static UINT msi_media_get_disk_info( CabData *data )
+{
+ MSIPACKAGE *package = data->package;
+ MSIRECORD *row;
+ LPWSTR ptr;
+
+ static const WCHAR query[] =
+ {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
+ '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ',
+ '`','D','i','s','k','I','d','`',' ','=',' ','%','i',0};
+
+ row = MSI_QueryGetRecord(package->db, query, data->mi->disk_id);
+ if (!row)
+ {
+ TRACE("Unable to query row\n");
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ data->mi->disk_prompt = strdupW(MSI_RecordGetString(row, 3));
+ data->mi->cabinet = strdupW(MSI_RecordGetString(row, 4));
+
+ ptr = strrchrW(data->mi->source, '\\') + 1;
+ lstrcpyW(ptr, data->mi->cabinet);
+
+ return ERROR_SUCCESS;
+}
+
static INT_PTR cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
{
+ TRACE("(%d)\n", fdint);
+
switch (fdint)
{
+ case fdintPARTIAL_FILE:
+ {
+ CabData *data = (CabData *)pfdin->pv;
+ data->mi->is_continuous = FALSE;
+ return 0;
+ }
+ case fdintNEXT_CABINET:
+ {
+ CabData *data = (CabData *)pfdin->pv;
+ struct media_info *mi = data->mi;
+ LPWSTR cab = strdupAtoW(pfdin->psz1);
+ UINT rc;
+
+ msi_free(mi->disk_prompt);
+
+ mi->disk_id++;
+ mi->is_continuous = TRUE;
+
+ rc = msi_media_get_disk_info(data);
+ if (rc != ERROR_SUCCESS)
+ {
+ ERR("Failed to get next cabinet information: %d\n", rc);
+ return -1;
+ }
+
+ if (lstrcmpiW(mi->cabinet, cab))
+ {
+ msi_free(cab);
+ ERR("Continuous cabinet does not match the next cabinet in the Media table\n");
+ return -1;
+ }
+
+ msi_free(cab);
+
+ TRACE("Searching for %s\n", debugstr_w(mi->source));
+
+ if (GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES)
+ rc = msi_change_media(data->package, mi);
+
+ if (rc != ERROR_SUCCESS)
+ return -1;
+
+ return 0;
+ }
case fdintCOPY_FILE:
{
CabData *data = (CabData*) pfdin->pv;
@@ -354,29 +450,6 @@ static void free_media_info( struct medi
msi_free( mi );
}
-static UINT msi_change_media( MSIPACKAGE *package, struct media_info *mi )
-{
- LPWSTR error, error_dialog;
- UINT r = ERROR_SUCCESS;
-
- static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};
- static const WCHAR error_prop[] = {'E','r','r','o','r','D','i','a','l','o','g',0};
-
- if ( msi_get_property_int(package, szUILevel, 0) == INSTALLUILEVEL_NONE )
- return ERROR_SUCCESS;
-
- error = generate_error_string( package, 1302, 1, mi->disk_prompt );
- error_dialog = msi_dup_property( package, error_prop );
-
- while ( r == ERROR_SUCCESS && GetFileAttributesW( mi->source ) == INVALID_FILE_ATTRIBUTES )
- r = msi_spawn_error_dialog( package, error_dialog, error );
-
- msi_free( error );
- msi_free( error_dialog );
-
- return r;
-}
-
static UINT download_remote_cabinet(MSIPACKAGE *package, struct media_info *mi)
{
WCHAR temppath[MAX_PATH];
@@ -472,6 +545,10 @@ static UINT ready_media(MSIPACKAGE *pack
UINT rc = ERROR_SUCCESS;
BOOL found = FALSE;
+ /* media info for continuous cabinet is already loaded */
+ if (mi->is_continuous)
+ return ERROR_SUCCESS;
+
rc = load_media_info(package, file, mi);
if (rc != ERROR_SUCCESS)
{
More information about the wine-cvs
mailing list