[msitools] wixl: implement stable UUID generation



commit 57007f5c1836aafdb51725e974c48e74551b93e7
Author: Paolo Bonzini <pbonzini redhat com>
Date:   Thu Jan 24 21:17:22 2013 +0100

    wixl: implement stable UUID generation
    
    Note that the UUIDs are *not* compatible with WiX!

 tests/data/wixl/ComponentGUID.wxs |   49 +++++++++++++++++++++++++++++++++++++
 tests/wixl.at                     |   13 ++++++++++
 tools/wixl/builder.vala           |   28 ++++++++++++++++++++-
 tools/wixl/wix.vala               |   14 ++++++++++
 4 files changed, 103 insertions(+), 1 deletions(-)
---
diff --git a/tests/data/wixl/ComponentGUID.wxs b/tests/data/wixl/ComponentGUID.wxs
new file mode 100644
index 0000000..6ffbe18
--- /dev/null
+++ b/tests/data/wixl/ComponentGUID.wxs
@@ -0,0 +1,49 @@
+<?xml version='1.0' encoding='windows-1252'?>
+<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
+  <Product Name='Foobar 1.0' Id='ABCDDCBA-86C7-4D14-AEC0-86416A69ABDE' UpgradeCode='ABCDDCBA-7349-453F-94F6-BCB5110BA4FD'
+    Language='1033' Codepage='1252' Version='1.0.0' Manufacturer='Acme Ltd.'>
+
+    <Package Id='*' Keywords='Installer' Description="Acme's Foobar 1.0 Installer"
+      Comments='Foobar is a registered trademark of Acme Ltd.' Manufacturer='Acme Ltd.'
+      InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252' />
+
+    <Media Id='1' Cabinet='Sample.cab' EmbedCab='yes' DiskPrompt="CD-ROM #1" />
+    <Property Id='DiskPrompt' Value="Acme's Foobar 1.0 Installation [1]" />
+
+    <Directory Id='TARGETDIR' Name='SourceDir'>
+      <Directory Id='ProgramFilesFolder' Name='PFiles'>
+        <Directory Id='Acme' Name='Acme'>
+          <Directory Id='INSTALLDIR' Name='Foobar 1.0'>
+            <Component Id='MainExecutable' Guid='*'>
+              <File Id='FoobarEXE' Name='FoobarAppl10.exe' DiskId='1' Source='FoobarAppl10.exe' KeyPath='yes'/>
+            </Component>
+          </Directory>
+        </Directory>
+      </Directory>
+
+      <Directory Id="ProgramMenuFolder" Name="Programs">
+        <Directory Id="ProgramMenuDir" Name="Foobar 1.0">
+          <Component Id="ProgramMenuDir" Guid="*">
+            <RemoveFolder Id='ProgramMenuDir' On='uninstall' />
+            <RegistryValue Root='HKCU' Key='Software\[Manufacturer]\[ProductName]' Type='string' Value='' KeyPath='yes' />
+          </Component>
+        </Directory>
+      </Directory>
+    </Directory>
+
+    <DirectoryRef Id='INSTALLDIR'>
+      <Component Id='Manual' Guid='*'>
+        <File Id='Manual' Name='Manual.pdf' DiskId='1' Source='Manual.pdf' KeyPath='yes'/>
+      </Component>
+    </DirectoryRef>
+
+    <Feature Id='Complete' Level='1'>
+      <ComponentRef Id='MainExecutable' />
+      <ComponentRef Id='Manual' />
+      <ComponentRef Id='ProgramMenuDir' />
+    </Feature>
+
+    <Icon Id="Foobar10.exe" SourceFile="FoobarAppl10.exe" />
+
+  </Product>
+</Wix>
diff --git a/tests/wixl.at b/tests/wixl.at
index 56edef9..c28cc78 100644
--- a/tests/wixl.at
+++ b/tests/wixl.at
@@ -28,6 +28,19 @@ AT_CHECK_WIXL([-o out.msi SampleFirst.wxs], [0], [ignore], [ignore])
 AT_CHECK([test -f out.msi], [0])
 AT_CLEANUP
 
+AT_SETUP([Stable component GUIDs])
+AT_WIXLDATA([ComponentGUID.wxs])
+AT_WIXLDATA([FoobarAppl10.exe])
+AT_WIXLDATA([Manual.pdf])
+AT_CHECK_WIXL([-o out.msi ComponentGUID.wxs], [0], [ignore], [ignore])
+# FIXME: add tons of tests on out.msi
+AT_CHECK([msiinfo export -s out.msi Component | sort | grep INSERT], [0],
+[INSERT INTO `Component` (`Component`, `ComponentId`, `Directory_`, `Attributes`, `KeyPath`) VALUES ('MainExecutable', '{8C320F7C-C521-5B19-A3C5-AF2B2ECEE71E}', 'INSTALLDIR', 0, 'FoobarEXE')
+INSERT INTO `Component` (`Component`, `ComponentId`, `Directory_`, `Attributes`, `KeyPath`) VALUES ('Manual', '{BAEE488E-70FF-566B-8A74-FE3107FDBDE2}', 'INSTALLDIR', 0, 'Manual')
+INSERT INTO `Component` (`Component`, `ComponentId`, `Directory_`, `Attributes`, `KeyPath`) VALUES ('ProgramMenuDir', '{F9F7F81C-5E64-5B7C-8018-FAF096969B88}', 'ProgramMenuDir', 4, 'reg5453B5C95074EA6F633E6D36318AFBF7')
+])
+AT_CLEANUP
+
 AT_SETUP([WiX tutorial SampleFragment])
 AT_WIXLDATA([SampleFragment.wxs])
 AT_WIXLDATA([Manual.wxs])
diff --git a/tools/wixl/builder.vala b/tools/wixl/builder.vala
index bb5510b..fc511d9 100644
--- a/tools/wixl/builder.vala
+++ b/tools/wixl/builder.vala
@@ -324,6 +324,26 @@ namespace Wixl {
             SHARED,
         }
 
+        /* Namespace UUID: {de73ba5a-ed96-4a66-ba1b-fbb44e659ad7} */
+        private static string uuid_namespace =
+            "\xde\x73\xba\x5a\xed\x96\x4a\x66\xba\x1b\xfb\xb4\x4e\x65\x9a\xd7";
+
+        private static string uuid_from_name(string s) {
+            var cs = new Checksum (ChecksumType.SHA1);
+            uint8 buffer[20];
+            size_t buflen = buffer.length;
+            
+            cs.update (uuid_namespace.data, 16);
+            cs.update (s.data, s.length);
+            cs.get_digest (buffer, ref buflen);
+
+            return "{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}".
+                printf(buffer[0], buffer[1], buffer[2], buffer[3],
+                        buffer[4], buffer[5], (buffer[6] & 15) | 0x50, buffer[7],
+                        (buffer[8] & 0x3F) | 0x80, buffer[9], buffer[10], buffer[11],
+                        buffer[12], buffer[13], buffer[14], buffer[15]);
+        }
+
         public override void visit_component (WixComponent comp) throws GLib.Error {
             var attr = 0;
 
@@ -331,8 +351,14 @@ namespace Wixl {
                 attr |= ComponentAttribute.REGISTRY_KEY_PATH;
 
             var parent = resolve<WixDirectory> (comp.parent);
+            string uuid;
+
             // FIXME: stable uuid generation based on ns/dir/path
-            var uuid = get_uuid (comp.Guid);
+            if (comp.Guid == "*")
+                uuid = uuid_from_name (comp.full_path (this));
+            else
+                uuid = get_uuid (comp.Guid);
+
             db.table_component.add (comp.Id, uuid, parent.Id, attr,
                                     comp.key != null ? comp.key.Id : null);
 
diff --git a/tools/wixl/wix.vala b/tools/wixl/wix.vala
index 205721b..c6897d8 100644
--- a/tools/wixl/wix.vala
+++ b/tools/wixl/wix.vala
@@ -147,6 +147,20 @@ namespace Wixl {
             return array;
         }
 
+        public string full_path (WixResolver r) throws GLib.Error {
+            WixDirectory dir = null;
+
+            if (parent != null && parent is WixDirectory)
+                dir = this.parent as WixDirectory;
+            else if (parent != null && parent is WixDirectoryRef)
+                dir = r.resolve<WixDirectory> (this.parent);
+
+            if (dir != null)
+                return dir.full_path (r) + "/" + this.Id;
+            else
+                return this.Id;
+        }
+
         public G[] get_elements<G> () {
             return add_elements<G> ({});
         }



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