[msitools] msiextract: external cab handling



commit 368ed6f02ed8ad9d34a862792b7cd647e58fc7d0
Author: Jean-Louis Charton <j_chrtn yahoo com>
Date:   Wed Oct 5 10:56:14 2016 +0400

    msiextract: external cab handling
    
    Improved version of Marc André proposed patch.
    This patch looks for the cab file (case insensitive search) in the folder the MSI file resides in.
    
    Tested with EnterpriseWW.msi from MS Office Enterprise 2007.
    
    Fixes:
    https://bugzilla.gnome.org/show_bug.cgi?id=764539
    
    Signed-off-by: Jean-Louis Charton <j_chrtn yahoo com>
    Signed-off-by: Marc-André Lureau <marcandre lureau gmail com>

 tools/msiextract.vala |   58 ++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 45 insertions(+), 13 deletions(-)
---
diff --git a/tools/msiextract.vala b/tools/msiextract.vala
index 18f1e5b..42c9293 100644
--- a/tools/msiextract.vala
+++ b/tools/msiextract.vala
@@ -22,28 +22,60 @@ public string get_long_name (string str) {
     return str;
 }
 
+// Look for a case insensitive match of cab in the directory dir.
+public string lookup_cab (string dir, string cab) throws GLib.Error
+{
+    var path = File.new_for_path (dir);
+    var children = path.enumerate_children ("standard::*", FileQueryInfoFlags.NONE);
+
+    string CAB = cab.up ();
+    FileInfo info = null;
+    while ((info = children.next_file ()) != null) {
+        if (info.get_file_type () == FileType.DIRECTORY)
+            continue;
+
+        if (info.get_name ().up () == CAB)
+            return path.get_child (info.get_name ()).get_path ();
+    }
+
+    return path.get_child (cab).get_path ();
+}
+
 public void extract_cab (Libmsi.Database db, string cab,
                          HashTable<string, string> cab_to_name) throws GLib.Error
 {
+    var cabinet = new GCab.Cabinet ();
+
     if (cab.has_prefix ("#")) {
         var name = cab.substring (1);
         var query = new Libmsi.Query (db, "SELECT `Data` FROM `_Streams` WHERE `Name` = '%s'".printf (name));
         query.execute ();
         var rec = query.fetch ();
-        var cabinet = new GCab.Cabinet ();
         cabinet.load (rec.get_stream (1));
-        var path = File.new_for_path (directory);
-        cabinet.extract_simple (path, (current) => {
-                var extname = cab_to_name.lookup (current.get_name ());
-                if (extname == null) {
-                    extname = current.get_name ();
-                    warning ("couldn't lookup MSI name, fallback on cab name %s", extname);
-                }
-                current.set_extract_name (extname);
-                GLib.stdout.printf ("%s\n", extname);
-                return true;
-            }, null);
     }
+    else {
+        // Look for the cab file in the directory the MSI file resides in.
+        var dbpath = File.new_for_path (db.path).get_parent ();
+        cab = lookup_cab (dbpath.get_path (), cab);
+
+        try {
+            cabinet.load (File.new_for_path (cab).read ());
+        } catch (GLib.Error err) {
+            throw new GLib.Error (err.domain, err.code, cab + ": " + err.message);
+        }
+    }
+
+    var path = File.new_for_path (directory);
+    cabinet.extract_simple (path, (current) => {
+            var extname = cab_to_name.lookup (current.get_name ());
+            if (extname == null) {
+                extname = current.get_name ();
+                warning ("couldn't lookup MSI name, fallback on cab name %s", extname);
+            }
+            current.set_extract_name (extname);
+            GLib.stdout.printf ("%s\n", extname);
+            return true;
+        }, null);
 }
 
 public string? get_directory_name (Libmsi.Record rec) throws GLib.Error {
@@ -154,7 +186,7 @@ public int main (string[] args) {
         foreach (var file in files)
             extract (file);
     } catch (GLib.Error error) {
-        GLib.stderr.printf (error.message);
+        GLib.stderr.printf ("%s\n", error.message);
         exit (1);
     }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]