diff options
author | Marc-André Lureau <marcandre.lureau@gmail.com> | 2013-01-18 01:04:28 +0100 |
---|---|---|
committer | Marc-André Lureau <marcandre.lureau@gmail.com> | 2013-01-18 01:04:28 +0100 |
commit | 75dcee9e8f66c18c25326fc636d98cf99b95f6d1 (patch) | |
tree | 6a36935a09aaee5bf04b50c0c6a709602a9bbfd0 | |
parent | bc9616a0a2abbaf379814524665a8a2c3db804e0 (diff) | |
download | msitools-75dcee9e8f66c18c25326fc636d98cf99b95f6d1.tar.gz msitools-75dcee9e8f66c18c25326fc636d98cf99b95f6d1.tar.xz msitools-75dcee9e8f66c18c25326fc636d98cf99b95f6d1.zip |
msiextract: can now extract files with gcab >= 0.1.10
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | tools/msiextract.vala | 51 |
2 files changed, 40 insertions, 13 deletions
diff --git a/configure.ac b/configure.ac index 0d32618..23ed150 100644 --- a/configure.ac +++ b/configure.ac @@ -35,7 +35,7 @@ AS_IF([test $win32 = no], [WIXL_UNIX="gio-unix-2.0"]) PKG_CHECK_MODULES([WIXL], [gio-2.0 >= 0.23.0 - libgcab-1.0 + libgcab-1.0 >= 0.1.10 uuid >= 1.41.3 libxml-2.0 >= 2.7 $WIXL_UNIX]) diff --git a/tools/msiextract.vala b/tools/msiextract.vala index 1f71499..465497b 100644 --- a/tools/msiextract.vala +++ b/tools/msiextract.vala @@ -4,10 +4,12 @@ static bool version; static bool list_only; [CCode (array_length = false, array_null_terminated = true)] static string[] files; +static string? directory = null; private const OptionEntry[] options = { { "version", 0, 0, OptionArg.NONE, ref version, N_("Display version number"), null }, - { "list", 0, 0, OptionArg.NONE, ref list_only, N_("List files only"), null }, + { "directory", 'C', 0, OptionArg.FILENAME, ref directory, N_("Extract to directory"), null }, + { "list", 'l', 0, OptionArg.NONE, ref list_only, N_("List files only"), null }, { "", 0, 0, OptionArg.FILENAME_ARRAY, ref files, null, N_("MSI_FILE...") }, { null } }; @@ -30,12 +32,36 @@ public void extract_cab (Libmsi.Database db, string cab, 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); + return true; + }, null); } } +public string? get_directory_name (Libmsi.Record rec) throws GLib.Error { + var name = get_long_name (rec.get_string (3)); + + // only by intuition... + if (rec.get_string (1) == "ProgramFilesFolder") + return "Program Files"; + else if (name == ".") + return ""; + else if (name == "SourceDir") + return null; + + return name; +} + public void extract (string filename) throws GLib.Error { Libmsi.Record? rec; - var db = new Libmsi.Database (files[0], Libmsi.DbFlags.READONLY, null); + var db = new Libmsi.Database (filename, Libmsi.DbFlags.READONLY, null); var directories = new HashTable<string, Libmsi.Record> (str_hash, str_equal); var query = new Libmsi.Query (db, "SELECT * FROM `Directory`"); @@ -49,21 +75,19 @@ public void extract (string filename) throws GLib.Error { while ((rec = query.fetch ()) != null) { var dir_id = rec.get_string (3); var dir_rec = directories.lookup (dir_id); - var dir = get_long_name (dir_rec.get_string (3)); + var dir = get_directory_name (dir_rec); do { var parent = dir_rec.get_string (2); dir_rec = directories.lookup (parent); if (dir_rec == null) break; - parent = get_long_name (dir_rec.get_string (3)); - // only by intuition... - if (dir_rec.get_string (1) == "ProgramFilesFolder") - parent = "Program Files"; - else if (parent == ".") - continue; - else if (parent == "SourceDir") + parent = get_directory_name (dir_rec); + if (parent == null) break; + if (parent == "") + continue; + dir = Path.build_filename (parent, dir); } while (true); @@ -84,7 +108,6 @@ public void extract (string filename) throws GLib.Error { if (list_only) exit (0); - message ("FIXME: gcab doesn't support extraction yet!"); query = new Libmsi.Query (db, "SELECT * FROM `Media`"); query.execute (); while ((rec = query.fetch ()) != null) { @@ -123,8 +146,12 @@ public int main (string[] args) { exit (1); } + if (directory == null) + directory = Environment.get_current_dir (); + try { - extract (files[0]); + foreach (var file in files) + extract (file); } catch (GLib.Error error) { GLib.stderr.printf (error.message); exit (1); |