msi: resend, promp for disk change
Aric Stewart
aric at codeweavers.com
Wed Jun 29 07:48:36 CDT 2005
Handle installs off multiple volumes and properly pull the prompt string
from the error table.
-------------- next part --------------
Index: dlls/msi/helpers.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/helpers.c,v
retrieving revision 1.3
diff -u -r1.3 helpers.c
--- dlls/msi/helpers.c 28 Jun 2005 19:14:30 -0000 1.3
+++ dlls/msi/helpers.c 29 Jun 2005 12:46:25 -0000
@@ -912,3 +917,53 @@
component->Action, component->ActionRequest);
}
}
+
+WCHAR* generate_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;
+ MSIRECORD *row;
+ DWORD size = 0;
+ DWORD i;
+ va_list va;
+ LPCWSTR str;
+ LPWSTR data;
+
+ row = MSI_QueryGetRecord(package->db, query, error);
+ if (!row)
+ 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,LPCWSTR);
+ MSI_RecordSetStringW(rec,(i+2),str);
+ }
+ va_end(va);
+
+ MSI_FormatRecordW(package,rec,NULL,&size);
+ if (size >= 0)
+ {
+ size++;
+ data = HeapAlloc(GetProcessHeap(),0,size*sizeof(WCHAR));
+ if (size > 1)
+ MSI_FormatRecordW(package,rec,data,&size);
+ else
+ data[0] = 0;
+ msiobj_release( &rec->hdr );
+ return data;
+ }
+
+ msiobj_release( &rec->hdr );
+ data = NULL;
+ return data;
+}
+
Index: dlls/msi/action.h
===================================================================
RCS file: /home/wine/wine/dlls/msi/action.h,v
retrieving revision 1.20
diff -u -r1.20 action.h
--- dlls/msi/action.h 17 Jun 2005 20:56:55 -0000 1.20
+++ dlls/msi/action.h 29 Jun 2005 12:46:26 -0000
@@ -234,6 +242,7 @@
void reduce_to_shortfilename(WCHAR*);
LPWSTR create_component_advertise_string(MSIPACKAGE*, MSICOMPONENT*, LPCWSTR);
void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature);
+WCHAR* generate_error_string(MSIPACKAGE *, UINT, DWORD, ... );
/* control event stuff */
Index: dlls/msi/files.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/files.c,v
retrieving revision 1.4
diff -u -r1.4 files.c
--- dlls/msi/files.c 24 Jun 2005 12:14:35 -0000 1.4
+++ dlls/msi/files.c 29 Jun 2005 12:46:26 -0000
@@ -359,7 +359,78 @@
file->SourcePath = build_directory_name(2, path, file->File);
}
-static UINT ready_media_for_file(MSIPACKAGE *package, int fileindex,
+static BOOL check_volume(LPCWSTR path, LPCWSTR want_volume, LPWSTR volume)
+{
+ WCHAR drive[4];
+ WCHAR name[MAX_PATH];
+ UINT type;
+
+ if (!(path[0] && path[1] == ':'))
+ return TRUE;
+
+ drive[0] = path[0];
+ drive[1] = path[1];
+ drive[2] = '\\';
+ drive[3] = 0;
+ TRACE("Checking volume %s .. (%s)\n",debugstr_w(drive), debugstr_w(want_volume));
+ type = GetDriveTypeW(drive);
+ TRACE("drive is of type %x\n",type);
+
+ if (type == DRIVE_UNKNOWN || type == DRIVE_NO_ROOT_DIR ||
+ type == DRIVE_FIXED || type == DRIVE_RAMDISK)
+ return TRUE;
+
+ GetVolumeInformationW(drive, name, MAX_PATH, NULL, NULL, NULL, NULL, 0);
+ TRACE("Drive contains %s\n", debugstr_w(name));
+ volume = strdupW(name);
+ return (strcmpiW(want_volume,name)==0);
+}
+
+static BOOL check_for_sourcefile(LPCWSTR source)
+{
+ DWORD attrib = GetFileAttributesW(source);
+ return (!(attrib == INVALID_FILE_ATTRIBUTES));
+}
+
+static UINT ready_volume(MSIPACKAGE* package, LPCWSTR path, LPWSTR last_volume,
+ MSIRECORD *row)
+{
+ LPWSTR volume = NULL;
+ LPCWSTR want_volume = MSI_RecordGetString(row, 5);
+ BOOL ok = check_volume(path, want_volume, volume);
+
+ TRACE("Readying Volume for %s (%s, %s)\n",debugstr_w(path), debugstr_w(want_volume), debugstr_w(last_volume));
+
+ if (check_for_sourcefile(path) && !ok)
+ {
+ FIXME("Found the Sourcefile but not on the correct volume.(%s,%s,%s)\n",
+ debugstr_w(path),debugstr_w(want_volume), debugstr_w(volume));
+ return ERROR_SUCCESS;
+ }
+
+ while (!ok)
+ {
+ INT rc;
+ LPCWSTR prompt;
+ LPWSTR msg;
+
+ prompt = MSI_RecordGetString(row,3);
+ msg = generate_error_string(package, 1302, 1, prompt);
+ rc = MessageBoxW(NULL,msg,NULL,MB_OKCANCEL);
+ HeapFree(GetProcessHeap(),0,volume);
+ HeapFree(GetProcessHeap(),0,msg);
+ if (rc == IDOK)
+ ok = check_for_sourcefile(path);
+ else
+ return ERROR_INSTALL_USEREXIT;
+ }
+
+ HeapFree(GetProcessHeap(),0,last_volume);
+ last_volume = strdupW(volume);
+ return ERROR_SUCCESS;
+}
+
+static UINT ready_media_for_file(MSIPACKAGE *package, int fileindex,
MSICOMPONENT* comp)
{
UINT rc = ERROR_SUCCESS;
@@ -371,10 +442,11 @@
'`','L','a','s','t','S','e','q','u','e','n','c','e','`',' ','>','=',
' ','%', 'i',' ','O','R','D','E','R',' ','B','Y',' ',
'`','L','a','s','t','S','e','q','u','e','n','c','e','`',0};
- LPCWSTR cab;
+ LPCWSTR cab, volume;
DWORD sz;
INT seq;
static UINT last_sequence = 0;
+ static LPWSTR last_volume = NULL;
static LPWSTR last_path = NULL;
MSIFILE* file = NULL;
@@ -382,6 +454,7 @@
if (!package)
{
HeapFree(GetProcessHeap(),0,last_path);
+ HeapFree(GetProcessHeap(),0,last_volume);
return ERROR_SUCCESS;
}
@@ -404,6 +477,8 @@
seq = MSI_RecordGetInteger(row,2);
last_sequence = seq;
+ volume = MSI_RecordGetString(row, 5);
+
HeapFree(GetProcessHeap(),0,last_path);
last_path = NULL;
@@ -411,6 +486,7 @@
{
last_path = resolve_folder(package, comp->Directory, TRUE, FALSE, NULL);
set_file_source(package,file,comp,last_path);
+ rc = ready_volume(package, file->SourcePath, last_volume, row);
msiobj_release(&row->hdr);
return rc;
}
@@ -444,6 +520,7 @@
if (MSI_GetPropertyW(package, cszTempFolder,last_path, &sz)
!= ERROR_SUCCESS)
GetTempPathW(MAX_PATH,last_path);
+ rc = ready_volume(package, source, last_volume, row);
}
}
rc = !extract_cabinet_file(package, source, last_path);
@@ -456,6 +533,7 @@
last_path = HeapAlloc(GetProcessHeap(),0,MAX_PATH*sizeof(WCHAR));
MSI_GetPropertyW(package,cszSourceDir,source,&sz);
strcpyW(last_path,source);
+ rc = ready_volume(package, last_path, last_volume, row);
}
set_file_source(package, file, comp, last_path);
msiobj_release(&row->hdr);
More information about the wine-patches
mailing list