msi: multidisc install support

Aric Stewart aric at codeweavers.com
Fri Jun 24 08:58:32 CDT 2005


Add functionality to files.c to prompt for volume changes to allow for 
multi disc installers.
-------------- next part --------------
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	24 Jun 2005 13:55:32 -0000
@@ -359,7 +359,75 @@
         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(LPCWSTR path, LPCWSTR want_volume, LPWSTR last_volume)
+{
+    LPWSTR volume = NULL; 
+    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;
+        static const WCHAR message_fmt[] = {'F','i','l','e',' ','%','s',' ','n','o','t',' ','f','o','u','n','d',' ','o','n',' ','i','n','s','e','r','t','e','d',' ','v','o','l','u','m','e','.',' ','P','l','e','a','s','e',' ','I','n','s','e','r','t',' ','%','s','.',0};
+        static const WCHAR title[] = {'W','i','n','e',' ','I','n','s','t','a','l','l','e','r',0};
+        WCHAR msg[0x100];
+        
+        sprintfW(msg,message_fmt,path,want_volume);
+        rc = MessageBoxW(NULL,msg,title,MB_OKCANCEL);
+        HeapFree(GetProcessHeap(),0,volume);
+        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 +439,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 +451,7 @@
     if (!package)
     {
         HeapFree(GetProcessHeap(),0,last_path);
+        HeapFree(GetProcessHeap(),0,last_volume);
         return ERROR_SUCCESS;
     }
 
@@ -404,6 +474,8 @@
     seq = MSI_RecordGetInteger(row,2);
     last_sequence = seq;
 
+    volume = MSI_RecordGetString(row, 5);
+
     HeapFree(GetProcessHeap(),0,last_path);
     last_path = NULL;
 
@@ -411,6 +483,7 @@
     {
         last_path = resolve_folder(package, comp->Directory, TRUE, FALSE, NULL);
         set_file_source(package,file,comp,last_path);
+        rc = ready_volume(file->SourcePath, volume, last_volume);
         msiobj_release(&row->hdr);
         return rc;
     }
@@ -444,6 +517,7 @@
                 if (MSI_GetPropertyW(package, cszTempFolder,last_path, &sz) 
                                     != ERROR_SUCCESS)
                     GetTempPathW(MAX_PATH,last_path);
+                rc = ready_volume(source, volume, last_volume);
             }
         }
         rc = !extract_cabinet_file(package, source, last_path);
@@ -456,6 +530,7 @@
         last_path = HeapAlloc(GetProcessHeap(),0,MAX_PATH*sizeof(WCHAR));
         MSI_GetPropertyW(package,cszSourceDir,source,&sz);
         strcpyW(last_path,source);
+        rc = ready_volume(last_path, volume, last_volume);
     }
     set_file_source(package, file, comp, last_path);
     msiobj_release(&row->hdr);


More information about the wine-patches mailing list