summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@gmail.com>2013-01-05 00:04:46 +0100
committerMarc-André Lureau <marcandre.lureau@gmail.com>2013-01-06 16:38:26 +0100
commit8789300d31e3c9b4310254c2416473bfdfa4739a (patch)
tree8a37a7e0cf84426dd42ce64695f4fdd29096aef5 /src
parent978d1435f143591f5c51079cc3c85019b8e54d31 (diff)
downloadmsitools-8789300d31e3c9b4310254c2416473bfdfa4739a.tar.gz
msitools-8789300d31e3c9b4310254c2416473bfdfa4739a.tar.xz
msitools-8789300d31e3c9b4310254c2416473bfdfa4739a.zip
Populate File table, create cabinet for media "1"
Diffstat (limited to 'src')
-rw-r--r--src/builder.vala76
-rw-r--r--src/msi.vala65
-rw-r--r--src/wix.vala24
3 files changed, 157 insertions, 8 deletions
diff --git a/src/builder.vala b/src/builder.vala
index 780cb65..699be29 100644
--- a/src/builder.vala
+++ b/src/builder.vala
@@ -1,13 +1,16 @@
namespace Wixl {
class WixBuilder: WixElementVisitor {
- WixRoot root;
- MsiDatabase db;
public WixBuilder (WixRoot root) {
this.root = root;
}
+ WixRoot root;
+ MsiDatabase db;
+ List<WixFile> files;
+ List<WixMedia> medias;
+
delegate void AddSequence (string action, int sequence) throws GLib.Error;
void sequence_actions () throws GLib.Error {
@@ -59,6 +62,8 @@ namespace Wixl {
}
if (db.table_remove_file.records.length () > 0)
add ("RemoveFiles", 3500);
+ if (db.table_file.records.length () > 0)
+ add ("InstallFiles", 4000);
add ("RegisterUser", 6000);
add ("RegisterProduct", 6100);
add ("PublishFeatures", 6300);
@@ -75,10 +80,41 @@ namespace Wixl {
add ("ExecuteAction", 1300);
}
+ public void build_cabinet () throws GLib.Error {
+ var sequence = 0;
+
+ foreach (var m in medias) {
+ var folder = new GCab.Folder (GCab.Compression.MSZIP);
+
+ foreach (var f in files) {
+ if (f.DiskId != m.Id)
+ continue;
+
+ folder.add_file (new GCab.File.with_file (f.Id, File.new_for_path (f.Name)), false);
+ var rec = f.record;
+ sequence += 1;
+ MsiTableFile.set_sequence (rec, sequence);
+ }
+
+ var cab = new GCab.Cabinet ();
+ cab.add_folder (folder);
+ var output = new MemoryOutputStream (null, realloc, free);
+ cab.write (output, null, null, null);
+ var input = new MemoryInputStream.from_data (output.get_data ()[0:output.data_size], null);
+ if (parse_yesno (m.EmbedCab))
+ db.table_streams.add (m.Cabinet, input, output.data_size);
+
+ db.table_media.set_last_sequence (m.record, sequence);
+ }
+ }
+
public MsiDatabase build () throws GLib.Error {
db = new MsiDatabase ();
+
root.accept (this);
sequence_actions ();
+ build_cabinet ();
+
return db;
}
@@ -109,7 +145,14 @@ namespace Wixl {
}
public override void visit_media (WixMedia media) throws GLib.Error {
- db.table_media.add (media.Id, media.EmbedCab, media.DiskPrompt, "#" + media.Cabinet);
+ var cabinet = media.Cabinet;
+
+ medias.append (media);
+ if (parse_yesno (media.EmbedCab))
+ cabinet = "#" + cabinet;
+
+ var rec = db.table_media.add (media.Id, media.DiskPrompt, cabinet);
+ media.record = rec;
}
public override void visit_directory (WixDirectory dir) throws GLib.Error {
@@ -229,6 +272,33 @@ namespace Wixl {
visit_key_element (reg);
}
+
+ [Flags]
+ enum FileAttribute {
+ READ_ONLY = 1 << 0,
+ HIDDEN = 1 << 1,
+ SYSTEM = 1 << 2,
+ VITAL = 1 << 9,
+ CHECKSUM = 1 << 10,
+ PATCH_ADDED = 1 << 11,
+ NON_COMPRESSED = 1 << 12,
+ COMPRESSED = 1 << 13
+ }
+
+ public override void visit_file (WixFile file) throws GLib.Error {
+ return_if_fail (file.DiskId == "1");
+ files.append (file);
+
+ var comp = file.parent as WixComponent;
+ var gfile = File.new_for_path (file.Name);
+ var info = gfile.query_info ("standard::*", 0, null);
+ var attr = FileAttribute.VITAL;
+
+ var rec = db.table_file.add (file.Id, comp.Id, file.Name, (int)info.get_size (), attr);
+ file.record = rec;
+
+ visit_key_element (file);
+ }
}
} // Wixl
diff --git a/src/msi.vala b/src/msi.vala
index 4f21bef..027f44f 100644
--- a/src/msi.vala
+++ b/src/msi.vala
@@ -122,9 +122,33 @@ namespace Wixl {
name = "File";
}
+ public Libmsi.Record add (string File, string Component, string FileName, int FileSize, int Attributes, int Sequence = 0) throws GLib.Error {
+ var rec = new Libmsi.Record (6);
+
+ if (!rec.set_string (1, File) ||
+ !rec.set_string (2, Component) ||
+ !rec.set_string (3, FileName) ||
+ !rec.set_int (4, FileSize) ||
+ !rec.set_int (5, Attributes) ||
+ !rec.set_int (6, Sequence))
+ throw new Wixl.Error.FAILED ("failed to add record");
+
+ records.append (rec);
+
+ return rec;
+ }
+
+ public static bool set_sequence (Libmsi.Record rec, int Sequence) {
+ return rec.set_int (6, Sequence);
+ }
+
public override void create (Libmsi.Database db) throws GLib.Error {
var query = new Libmsi.Query (db, "CREATE TABLE `File` (`File` CHAR(72) NOT NULL, `Component_` CHAR(72) NOT NULL, `FileName` CHAR(255) NOT NULL LOCALIZABLE, `FileSize` LONG NOT NULL, `Version` CHAR(72), `Language` CHAR(20), `Attributes` INT, `Sequence` LONG NOT NULL PRIMARY KEY `File`)");
query.execute (null);
+
+ query = new Libmsi.Query (db, "INSERT INTO `File` (`File`, `Component_`, `FileName`, `FileSize`, `Attributes`, `Sequence`) VALUES (?, ?, ?, ?, ?, ?)");
+ foreach (var r in records)
+ query.execute (r);
}
}
@@ -184,17 +208,21 @@ namespace Wixl {
name = "Media";
}
- public void add (string DiskId, string LastSequence, string DiskPrompt, string Cabinet) throws GLib.Error {
+ public bool set_last_sequence (Libmsi.Record rec, int last_sequence) {
+ return rec.set_int (2, last_sequence);
+ }
+
+ public Libmsi.Record add (string DiskId, string DiskPrompt, string Cabinet) throws GLib.Error {
var rec = new Libmsi.Record (4);
if (!rec.set_int (1, int.parse (DiskId)) ||
- !rec.set_int (2, int.parse (LastSequence)) ||
+ !rec.set_int (2, 0) ||
!rec.set_string (3, DiskPrompt) ||
!rec.set_string (4, Cabinet))
throw new Wixl.Error.FAILED ("failed to add record");
records.append (rec);
-
+ return rec;
}
public override void create (Libmsi.Database db) throws GLib.Error {
@@ -386,7 +414,7 @@ namespace Wixl {
}
}
- class MsiTable_Validation: MsiTable {
+ class MsiTableValidation: MsiTable {
construct {
name = "_Validation";
}
@@ -395,6 +423,27 @@ namespace Wixl {
}
}
+ class MsiTableStreams: MsiTable {
+ construct {
+ name = "_Streams";
+ }
+
+ public void add (string name, GLib.InputStream input, size_t count) throws GLib.Error {
+ var rec = new Libmsi.Record (2);
+ if (!rec.set_string (1, name) ||
+ !rec.set_stream (2, input, count))
+ throw new Wixl.Error.FAILED ("failed to add record");
+
+ records.append (rec);
+ }
+
+ public override void create (Libmsi.Database db) throws GLib.Error {
+ var query = new Libmsi.Query (db, "INSERT INTO `_Streams` (`Name`, `Data`) VALUES (?, ?)");
+ foreach (var r in records)
+ query.execute (r);
+ }
+ }
+
class MsiSummaryInfo: Object {
public Libmsi.SummaryInfo properties;
@@ -457,11 +506,13 @@ namespace Wixl {
public MsiTableFeatureComponents table_feature_components;
public MsiTableRemoveFile table_remove_file;
public MsiTableRegistry table_registry;
+ public MsiTableFile table_file;
public MsiTableAdminExecuteSequence table_admin_execute_sequence;
public MsiTableAdminUISequence table_admin_ui_sequence;
public MsiTableAdvtExecuteSequence table_advt_execute_sequence;
public MsiTableInstallExecuteSequence table_install_execute_sequence;
public MsiTableInstallUISequence table_install_ui_sequence;
+ public MsiTableStreams table_streams;
HashTable<string, MsiTable> tables;
@@ -493,11 +544,13 @@ namespace Wixl {
table_feature_components = new MsiTableFeatureComponents ();
table_remove_file = new MsiTableRemoveFile ();
table_registry = new MsiTableRegistry ();
+ table_file = new MsiTableFile ();
table_admin_execute_sequence = new MsiTableAdminExecuteSequence ();
table_admin_ui_sequence = new MsiTableAdminUISequence ();
table_advt_execute_sequence = new MsiTableAdvtExecuteSequence ();
table_install_execute_sequence = new MsiTableInstallExecuteSequence ();
table_install_ui_sequence = new MsiTableInstallUISequence ();
+ table_streams = new MsiTableStreams ();
foreach (var t in new MsiTable[] {
table_admin_execute_sequence,
@@ -514,8 +567,10 @@ namespace Wixl {
table_feature_components,
table_remove_file,
table_registry,
+ table_file,
+ table_streams,
new MsiTableError (),
- new MsiTable_Validation ()
+ new MsiTableValidation ()
}) {
tables.insert (t.name, t);
}
diff --git a/src/wix.vala b/src/wix.vala
index aa6f0d4..f4dfeb2 100644
--- a/src/wix.vala
+++ b/src/wix.vala
@@ -12,6 +12,7 @@ namespace Wixl {
public abstract void visit_component_ref (WixComponentRef ref) throws GLib.Error;
public abstract void visit_remove_folder (WixRemoveFolder rm) throws GLib.Error;
public abstract void visit_registry_value (WixRegistryValue reg) throws GLib.Error;
+ public abstract void visit_file (WixFile reg) throws GLib.Error;
}
public abstract class WixElement: Object {
@@ -135,6 +136,22 @@ namespace Wixl {
public string KeyPath { get; set; }
}
+ public class WixFile: WixKeyElement {
+ static construct {
+ name = "File";
+ }
+
+ public string DiskId { get; set; }
+ public string Source { get; set; }
+ public string Name { get; set; }
+
+ public Libmsi.Record record;
+
+ public override void accept (WixElementVisitor visitor) throws GLib.Error {
+ visitor.visit_file (this);
+ }
+ }
+
public class WixRegistryValue: WixKeyElement {
static construct {
name = "RegistryValue";
@@ -285,6 +302,8 @@ namespace Wixl {
public string EmbedCab { get; set; }
public string DiskPrompt { get; set; }
+ public Libmsi.Record record;
+
public override void accept (WixElementVisitor visitor) throws GLib.Error {
visitor.visit_media (this);
}
@@ -318,6 +337,11 @@ namespace Wixl {
reg.load (child);
add_child (reg);
continue;
+ case "File":
+ var file = new WixFile ();
+ file.load (child);
+ add_child (file);
+ continue;
}
break;
}