예제 #1
0
        /// <summary>
        /// Parse ignore modularization data from the xml.
        /// </summary>
        /// <param name="intermediate">Intermediate to populate with persisted data.</param>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="section">Section to populate with persisted data.</param>
        private static void ParseIgnoreModularization(Intermediate intermediate, XmlReader reader, Section section)
        {
            bool   empty = reader.IsEmptyElement;
            string name  = null;
            string type  = null;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "name":
                    name = reader.Value;
                    break;

                case "type":
                    type = reader.Value;
                    break;
                }
            }
            if (null == name)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Reference missing required attribute: 'name'");
            }
            if (null == type)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Reference missing required attribute: 'type'");
            }

            if (!empty && reader.Read() && XmlNodeType.EndElement != reader.MoveToContent())
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Unexpected content while processing 'ignoreModularization': {0}", reader.NodeType.ToString()));
            }

            section.IgnoreModularizations.Add(new IgnoreModularization(name, type));
        }
예제 #2
0
        /// <summary>
        /// Parse a reference from the xml.
        /// </summary>
        /// <param name="intermediate">Intermediate to populate with persisted data.</param>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="section">Section to populate with persisted data.</param>
        private static void ParseReference(Intermediate intermediate, XmlReader reader, Section section)
        {
            bool   empty = reader.IsEmptyElement;
            string id    = null;
            string table = null;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "symbol":
                    id = reader.Value;
                    break;

                case "table":
                    table = reader.Value;
                    break;
                }
            }
            if (null == table)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Reference missing required attribute: 'table'");
            }
            if (null == id)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Reference missing required attribute: 'id'");
            }

            if (!empty && reader.Read() && XmlNodeType.EndElement != reader.MoveToContent())
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Unexpected content while processing 'reference': {0}", reader.NodeType.ToString()));
            }

            section.References.Add(new Reference(table, id));
        }
예제 #3
0
        /// <summary>
        /// Loads an intermediate from a XmlReader in memory.
        /// </summary>
        /// <param name="reader">XmlReader with intermediate persisted as Xml.</param>
        /// <param name="path">Path to intermediate file saved on disk.</param>
        /// <param name="tableDefinitions">Collection containing TableDefinitions to use when reconstituting the intermediate.</param>
        /// <param name="suppressVersionCheck">Suppresses wix.dll version mismatch check.</param>
        /// <returns>Returns the loaded intermediate.</returns>
        /// <remarks>This method will set the SourcePath property to the appropriate values on successful load, but will not update the Path property.</remarks>
        public static Intermediate Load(XmlReader reader, string path, TableDefinitionCollection tableDefinitions, bool suppressVersionCheck)
        {
            Intermediate intermediate = new Intermediate();

            intermediate.path = path;

            ParseIntermediate(intermediate, reader, tableDefinitions, suppressVersionCheck);
            return(intermediate);
        }
예제 #4
0
        /// <summary>
        /// Parse a table from the xml.
        /// </summary>
        /// <param name="intermediate">Intermediate to populate with persisted data.</param>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="section">Section to populate with persisted data.</param>
        /// <param name="tableDefinitions">TableDefinitions to use in the intermediate.</param>
        private static void ParseTable(Intermediate intermediate, XmlReader reader, Section section, TableDefinitionCollection tableDefinitions)
        {
            bool   empty = reader.IsEmptyElement;
            string name  = null;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "name":
                    name = reader.Value;
                    break;
                }
            }
            if (null == name)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Table missing required attribute: 'name'");
            }

            if (!empty)
            {
                bool done = false;

                // loop through all the rows (tuples) in a table
                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        switch (reader.LocalName)
                        {
                        case "tuple":
                            ParseTuple(intermediate, reader, section, tableDefinitions[name]);
                            break;

                        default:
                            throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Unexpected element while processing 'table': '{0}'", reader.LocalName));
                        }
                        break;

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!done)
                {
                    throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Missing end element while processing 'table'."));
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Parse a tuple from the xml.
        /// </summary>
        /// <param name="intermediate">Intermediate to populate with persisted data.</param>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="section">Section to populate with persisted data.</param>
        /// <param name="tableDef">Table definition of the tuple to parse.</param>
        private static void ParseTuple(Intermediate intermediate, XmlReader reader, Section section, TableDefinition tableDef)
        {
            bool empty = reader.IsEmptyElement;
            SourceLineNumberCollection sourceLineNumbers = null;
            int field = 0;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "sourceLineNumber":
                    sourceLineNumbers = new SourceLineNumberCollection(reader.Value);
                    break;
                }
            }

            Row row = Common.CreateRowInSection(sourceLineNumbers, section, tableDef);

            if (!empty)
            {
                bool done = false;

                // loop through all the fields in a row
                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        switch (reader.LocalName)
                        {
                        case "field":
                            row[field] = Field.Parse(reader);
                            ++field;
                            break;

                        default:
                            throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Unexpected element while processing 'tuple': '{0}'", reader.LocalName));
                        }
                        break;

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!done)
                {
                    throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Missing end element while processing 'tuple'."));
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Creates a new section as part of an intermediate.
        /// </summary>
        /// <param name="intermediate">Parent intermediate.</param>
        /// <param name="id">Identifier for section.</param>
        /// <param name="type">Type of section.</param>
        /// <param name="codepage">Codepage for resulting database.</param>
        public Section(Intermediate intermediate, string id, SectionType type, int codepage)
        {
            this.intermediate = intermediate;
            this.id           = id;
            this.type         = type;
            this.codepage     = codepage;

            this.tables                = new TableCollection();
            this.references            = new ReferenceCollection();
            this.ignoreModularizations = new IgnoreModularizationCollection();
            this.complexReferences     = new ComplexReferenceCollection();
            this.featureBacklinks      = new FeatureBacklinkCollection();
        }
예제 #7
0
        /// <summary>
        /// Creates a new section as part of an intermediate.
        /// </summary>
        /// <param name="intermediate">Parent intermediate.</param>
        /// <param name="id">Identifier for section.</param>
        /// <param name="type">Type of section.</param>
        /// <param name="codepage">Codepage for resulting database.</param>
        public Section(Intermediate intermediate, string id, SectionType type, int codepage)
        {
            this.intermediate = intermediate;
            this.id = id;
            this.type = type;
            this.codepage = codepage;

            this.tables = new TableCollection();
            this.references = new ReferenceCollection();
            this.ignoreModularizations = new IgnoreModularizationCollection();
            this.complexReferences = new ComplexReferenceCollection();
            this.featureBacklinks = new FeatureBacklinkCollection();
        }
예제 #8
0
        /// <summary>
        /// Parse the root library element.
        /// </summary>
        /// <param name="library">Library to read from disk.</param>
        /// <param name="reader">XmlReader with library persisted as Xml.</param>
        /// <param name="tableDefinitions">Collection containing TableDefinitions to use when reconstituting the intermediates.</param>
        /// <param name="suppressVersionCheck">Suppresses check for wix.dll version mismatch.</param>
        private static void ParseLibrary(Library library, XmlReader reader, TableDefinitionCollection tableDefinitions, bool suppressVersionCheck)
        {
            // read the document root
            reader.MoveToContent();
            if ("wixLibrary" != reader.LocalName)
            {
                throw new WixNotLibraryException(SourceLineNumberCollection.FromFileName(library.Path), String.Format("Invalid root element: '{0}', expected 'wixLibrary'", reader.LocalName));
            }

            Version objVersion = null;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "version":
                    objVersion = new Version(reader.Value);
                    break;
                }
            }

            if (null != objVersion && !suppressVersionCheck)
            {
                Version currentVersion = Common.LibraryFormatVersion;
                if (0 != currentVersion.CompareTo(objVersion))
                {
                    throw new WixVersionMismatchException(currentVersion, objVersion, "Library", library.Path);
                }
            }

            // loop through the rest of the xml building up the SectionCollection
            while (reader.Read())
            {
                if (0 == reader.Depth)
                {
                    break;
                }
                else if (1 != reader.Depth)
                {
                    // throw exception since we should only be processing tables
                    throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(library.Path), "Unexpected depth while processing element: 'wixLibrary'");
                }

                if (XmlNodeType.Element == reader.NodeType && "wixObject" == reader.LocalName)
                {
                    Intermediate intermediate = Intermediate.Load(reader, library.Path, tableDefinitions, suppressVersionCheck);

                    library.intermediates.Add(intermediate);
                }
            }
        }
예제 #9
0
        public override void InspectIntermediate(Intermediate output)
        {
            foreach (Section section in output.Sections)
            {
                Table fileTable = section.Tables["File"];
                if (null != fileTable && 0 < fileTable.Rows.Count)
                {
                    Row fileRow = fileTable.Rows[0];
                    this.Core.OnMessage(ValidationWarnings.ExampleWarning(fileRow.SourceLineNumbers));

                    return;
                }
            }

            this.Core.OnMessage(ValidationErrors.ExampleError());
        }
예제 #10
0
        /// <summary>
        /// Get the schemas required to validate a library.
        /// </summary>
        /// <returns>The schemas required to validate a library.</returns>
        internal static XmlSchemaCollection GetSchemas()
        {
            if (null == schemas)
            {
                Assembly assembly = Assembly.GetExecutingAssembly();

                using (Stream librarySchemaStream = assembly.GetManifestResourceStream("Microsoft.Tools.WindowsInstallerXml.Xsd.libraries.xsd"))
                {
                    schemas = new XmlSchemaCollection();
                    schemas.Add(Intermediate.GetSchemas());
                    schemas.Add(Localization.GetSchemas());
                    XmlSchema librarySchema = XmlSchema.Read(librarySchemaStream, null);
                    schemas.Add(librarySchema);
                }
            }

            return(schemas);
        }
예제 #11
0
        /// <summary>
        /// Get the schemas required to validate an object.
        /// </summary>
        /// <returns>The schemas required to validate an object.</returns>
        internal static XmlSchemaCollection GetSchemas()
        {
            lock (lockObject)
            {
                if (null == schemas)
                {
                    Assembly assembly = Assembly.GetExecutingAssembly();

                    using (Stream outputSchemaStream = assembly.GetManifestResourceStream("Microsoft.Tools.WindowsInstallerXml.Xsd.outputs.xsd"))
                    {
                        schemas = new XmlSchemaCollection();
                        schemas.Add(Intermediate.GetSchemas());
                        schemas.Add(TableDefinitionCollection.GetSchemas());
                        XmlSchema outputSchema = XmlSchema.Read(outputSchemaStream, null);
                        schemas.Add(outputSchema);
                    }
                }
            }

            return(schemas);
        }
예제 #12
0
        /// <summary>
        /// Loads an intermediate from a path on disk.
        /// </summary>
        /// <param name="path">Path to intermediate file saved on disk.</param>
        /// <param name="tableDefinitions">Collection containing TableDefinitions to use when reconstituting the intermediate.</param>
        /// <param name="suppressVersionCheck">Suppress checking for wix.dll version mismatches.</param>
        /// <returns>Returns the loaded intermediate.</returns>
        /// <remarks>This method will set the Path and SourcePath properties to the appropriate values on successful load.</remarks>
        public static Intermediate Load(string path, TableDefinitionCollection tableDefinitions, bool suppressVersionCheck)
        {
            Intermediate intermediate = new Intermediate();

            intermediate.Path = path;

            XmlTextReader reader = null;

            try
            {
                reader = new XmlTextReader(path);
                ParseIntermediate(intermediate, reader, tableDefinitions, suppressVersionCheck);
            }
            finally
            {
                if (null != reader)
                {
                    reader.Close();
                }
            }

            return(intermediate);
        }
 /// <summary>
 /// Inspect the compiled output.
 /// </summary>
 /// <param name="output">The compiled output.</param>
 public virtual void InspectIntermediate(Intermediate output)
 {
 }
예제 #14
0
        /// <summary>
        /// Parse an intermediate from an XML format.
        /// </summary>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="tableDefinitions">TableDefinitions to use in the intermediate.</param>
        /// <param name="suppressVersionCheck">Suppress checking for wix.dll version mismatch.</param>
        /// <returns>The parsed Intermediate.</returns>
        internal static Intermediate Parse(XmlReader reader, TableDefinitionCollection tableDefinitions, bool suppressVersionCheck)
        {
            Debug.Assert("wixObject" == reader.LocalName);

            bool    empty      = reader.IsEmptyElement;
            Version objVersion = null;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "version":
                    objVersion = new Version(reader.Value);
                    break;

                default:
                    if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal))
                    {
                        throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixObject", reader.Name));
                    }
                    break;
                }
            }

            if (null != objVersion && !suppressVersionCheck)
            {
                if (0 != currentVersion.CompareTo(objVersion))
                {
                    throw new WixException(WixErrors.VersionMismatch(SourceLineNumberCollection.FromUri(reader.BaseURI), "object", objVersion.ToString(), currentVersion.ToString()));
                }
            }

            Intermediate intermediate = new Intermediate();

            // loop through the rest of the xml building up the SectionCollection
            if (!empty)
            {
                bool done = false;

                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        switch (reader.LocalName)
                        {
                        case "section":
                            intermediate.sections.Add(Section.Parse(reader, tableDefinitions));
                            break;

                        default:
                            throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixObject", reader.Name));
                        }
                        break;

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!done)
                {
                    throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixObject"));
                }
            }

            return(intermediate);
        }
예제 #15
0
        /// <summary>
        /// Parse a tuple from the xml.
        /// </summary>
        /// <param name="intermediate">Intermediate to populate with persisted data.</param>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="section">Section to populate with persisted data.</param>
        /// <param name="tableDef">Table definition of the tuple to parse.</param>
        private static void ParseTuple(Intermediate intermediate, XmlReader reader, Section section, TableDefinition tableDef)
        {
            bool empty = reader.IsEmptyElement;
            SourceLineNumberCollection sourceLineNumbers = null;
            int field = 0;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                    case "sourceLineNumber":
                        sourceLineNumbers = new SourceLineNumberCollection(reader.Value);
                        break;
                }
            }

            Row row = Common.CreateRowInSection(sourceLineNumbers, section, tableDef);

            if (!empty)
            {
                bool done = false;

                // loop through all the fields in a row
                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            switch (reader.LocalName)
                            {
                                case "field":
                                    row[field] = Field.Parse(reader);
                                    ++field;
                                    break;
                                default:
                                    throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Unexpected element while processing 'tuple': '{0}'", reader.LocalName));
                            }
                            break;
                        case XmlNodeType.EndElement:
                            done = true;
                            break;
                    }
                }

                if (!done)
                {
                    throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Missing end element while processing 'tuple'."));
                }
            }
        }
예제 #16
0
        /// <summary>
        /// Processes an XmlReader and builds up the output object.
        /// </summary>
        /// <param name="reader">Reader to get data from.</param>
        /// <param name="suppressVersionCheck">Suppresses wix.dll version mismatch check.</param>
        /// <param name="path">The path to display in an error message.</param>
        /// <returns>The Output represented by the Xml.</returns>
        private static Output Parse(XmlReader reader, bool suppressVersionCheck, string path)
        {
            Debug.Assert("wixOutput" == reader.LocalName);

            Output output = new Output();

            output.path = path;
            string      entrySectionId = null;
            SectionType sectionType    = SectionType.Unknown;
            Version     objVersion     = null;
            bool        empty          = reader.IsEmptyElement;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "type":
                    switch (reader.Value)
                    {
                    case "Module":
                        output.type = OutputType.Module;
                        sectionType = SectionType.Module;
                        break;

                    case "Product":
                        output.type = OutputType.Product;
                        sectionType = SectionType.Product;
                        break;

                    case "PatchCreation":
                        output.type = OutputType.PatchCreation;
                        sectionType = SectionType.PatchCreation;
                        break;

                    default:
                        throw new WixParseException(String.Format("The wixOutput/@type attribute contains an unexpected value '{0}'.", reader.Value));
                    }
                    break;

                case "codepage":
                    output.codepage = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture.NumberFormat);
                    break;

                case "compressed":
                    output.compressed = Common.IsYes(reader.Value, null, "wixOutput", reader.Name, null);
                    break;

                case "longFileNames":
                    output.longFileNames = Common.IsYes(reader.Value, null, "wixOutput", reader.Name, null);
                    break;

                case "entrySectionId":
                    entrySectionId = reader.Value;
                    break;

                case "moduleGuid":
                    output.moduleGuid = reader.Value;
                    break;

                case "output":
                    output.path = reader.Value;
                    break;

                case "suppressAdminSequence":
                    output.suppressAdminSequence = Common.IsYes(reader.Value, null, "wixOutput", reader.Name, null);
                    break;

                case "suppressAdvertiseSequence":
                    output.suppressAdvertiseSequence = Common.IsYes(reader.Value, null, "wixOutput", reader.Name, null);
                    break;

                case "suppressUISequence":
                    output.suppressUISequence = Common.IsYes(reader.Value, null, "wixOutput", reader.Name, null);
                    break;

                case "version":
                    objVersion = new Version(reader.Value);
                    break;

                case "xmlns":
                    break;

                default:
                    throw new WixParseException(String.Format("The wixOutput element contains an unexpected attribute {0}.", reader.Name));
                }
            }
            if (null == entrySectionId)
            {
                throw new WixParseException("The wixOutput/@entrySectionId attribute was not found; it is required.");
            }
            if (null != objVersion && !suppressVersionCheck)
            {
                Version currentVersion = Common.OutputFormatVersion;
                if (0 != currentVersion.CompareTo(objVersion))
                {
                    throw new WixVersionMismatchException(currentVersion, objVersion, "Output", output.Path);
                }
            }

            // create a section for all the rows to belong to
            Intermediate intermediate = new Intermediate();

            output.entrySection = new Section(intermediate, entrySectionId, sectionType, output.codepage);

            // loop through the rest of the xml building up the Output object
            if (!empty)
            {
                bool done = false;

                // loop through all the fields in a row
                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        switch (reader.LocalName)
                        {
                        case "outputTable":
                            output.outputTables.Add(OutputTable.Parse(reader, output.entrySection));
                            break;

                        case "importStream":
                            output.importStreams.Add(ImportStream.Parse(reader));
                            break;

                        case "componentsToFeatures":
                        case "featuresToFeatures":
                        case "modulesToFeatures":
                            ParseConnectToFeatures(output, reader);
                            break;

                        case "merge":
                            ParseMerge(output, reader);
                            break;

                        case "fileMediaInformation":
                            output.fileMediaInfoCollection.Add(FileMediaInformation.Parse(reader));
                            break;

                        case "media":
                            ParseMedia(output, reader);
                            break;

                        default:
                            throw new WixParseException(String.Format("The wixOutput element contains an unexpected child element {0}.", reader.Name));
                        }
                        break;

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!done)
                {
                    throw new WixParseException("Missing end element while processing the wixOutput element.");
                }
            }

            return(output);
        }
예제 #17
0
        /// <summary>
        /// Parse a feature backlink from the xml.
        /// </summary>
        /// <param name="intermediate">Intermediate to populate with persisted data.</param>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="section">Section to populate with persisted data.</param>
        private static void ParseFeatureBacklink(Intermediate intermediate, XmlReader reader, Section section)
        {
            bool   empty             = reader.IsEmptyElement;
            string targetSymbol      = null;
            string component         = null;
            FeatureBacklinkType type = FeatureBacklinkType.Unknown;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "targetSymbol":
                    targetSymbol = reader.Value;
                    break;

                case "component":
                    component = reader.Value;
                    break;

                case "type":
                    switch (reader.Value)
                    {
                    case "Class":
                        type = FeatureBacklinkType.Class;
                        break;

                    case "Extension":
                        type = FeatureBacklinkType.Extension;
                        break;

                    case "Shortcut":
                        type = FeatureBacklinkType.Shortcut;
                        break;

                    case "PublishComponent":
                        type = FeatureBacklinkType.PublishComponent;
                        break;

                    case "TypeLib":
                        type = FeatureBacklinkType.TypeLib;
                        break;

                    default:
                        throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Invalid FeatureBacklinkType");
                    }
                    break;
                }
            }
            if (FeatureBacklinkType.Unknown == type)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Unknown FeatureBackLink type");
            }
            if (null == component)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "FeatureBackLink missing required attribute: 'component'");
            }
            if (null == targetSymbol)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "FeatureBackLink missing required attribute: 'targetSymbol'");
            }

            if (!empty && reader.Read() && XmlNodeType.EndElement != reader.MoveToContent())
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Unexpected content while processing 'featureBacklink': {0}", reader.NodeType.ToString()));
            }

            section.FeatureBacklinks.Add(new FeatureBacklink(component, type, targetSymbol));
        }
예제 #18
0
        /// <summary>
        /// Loads an intermediate from a XmlReader in memory.
        /// </summary>
        /// <param name="reader">XmlReader with intermediate persisted as Xml.</param>
        /// <param name="path">Path to intermediate file saved on disk.</param>
        /// <param name="tableDefinitions">Collection containing TableDefinitions to use when reconstituting the intermediate.</param>
        /// <param name="suppressVersionCheck">Suppresses wix.dll version mismatch check.</param>
        /// <returns>Returns the loaded intermediate.</returns>
        /// <remarks>This method will set the SourcePath property to the appropriate values on successful load, but will not update the Path property.</remarks>
        public static Intermediate Load(XmlReader reader, string path, TableDefinitionCollection tableDefinitions, bool suppressVersionCheck)
        {
            Intermediate intermediate = new Intermediate();
            intermediate.path = path;

            ParseIntermediate(intermediate, reader, tableDefinitions, suppressVersionCheck);
            return intermediate;
        }
예제 #19
0
        /// <summary>
        /// Parse a feature backlink from the xml.
        /// </summary>
        /// <param name="intermediate">Intermediate to populate with persisted data.</param>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="section">Section to populate with persisted data.</param>
        private static void ParseFeatureBacklink(Intermediate intermediate, XmlReader reader, Section section)
        {
            bool empty = reader.IsEmptyElement;
            string targetSymbol = null;
            string component = null;
            FeatureBacklinkType type = FeatureBacklinkType.Unknown;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                    case "targetSymbol":
                        targetSymbol = reader.Value;
                        break;
                    case "component":
                        component = reader.Value;
                        break;
                    case "type":
                        switch (reader.Value)
                        {
                            case "Class":
                                type = FeatureBacklinkType.Class;
                                break;
                            case "Extension":
                                type = FeatureBacklinkType.Extension;
                                break;
                            case "Shortcut":
                                type = FeatureBacklinkType.Shortcut;
                                break;
                            case "PublishComponent":
                                type = FeatureBacklinkType.PublishComponent;
                                break;
                            case "TypeLib":
                                type = FeatureBacklinkType.TypeLib;
                                break;
                            default:
                                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Invalid FeatureBacklinkType");
                        }
                        break;
                }
            }
            if (FeatureBacklinkType.Unknown == type)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Unknown FeatureBackLink type");
            }
            if (null == component)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "FeatureBackLink missing required attribute: 'component'");
            }
            if (null == targetSymbol)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "FeatureBackLink missing required attribute: 'targetSymbol'");
            }

            if (!empty && reader.Read() && XmlNodeType.EndElement != reader.MoveToContent())
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Unexpected content while processing 'featureBacklink': {0}", reader.NodeType.ToString()));
            }

            section.FeatureBacklinks.Add(new FeatureBacklink(component, type, targetSymbol));
        }
예제 #20
0
        /// <summary>
        /// Parse a section from the xml.
        /// </summary>
        /// <param name="intermediate">Intermediate to populate with persisted data.</param>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="tableDefinitions">TableDefinitions to use in the intermediate.</param>
        private static void ParseSection(Intermediate intermediate, XmlReader reader, TableDefinitionCollection tableDefinitions)
        {
            Section     section  = null;
            string      id       = null;
            SectionType type     = SectionType.Unknown;
            int         codepage = 0;
            bool        empty    = reader.IsEmptyElement;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.Name)
                {
                case "id":
                    id = reader.Value;
                    break;

                case "type":
                    switch (reader.Value)
                    {
                    case "fragment":
                        type = SectionType.Fragment;
                        break;

                    case "module":
                        type = SectionType.Module;
                        break;

                    case "product":
                        type = SectionType.Product;
                        break;

                    case "patchCreation":
                        type = SectionType.PatchCreation;
                        break;
                    }
                    break;

                case "codepage":
                    codepage = Convert.ToInt32(reader.Value);
                    break;
                }
            }
            if (SectionType.Unknown == type)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Unknown section type");
            }
            if (null == id && SectionType.Fragment != type)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Section missing required attribute: 'id'");
            }

            section = new Section(intermediate, id, type, codepage);

            if (!empty)
            {
                bool done = false;

                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        switch (reader.LocalName)
                        {
                        case "reference":
                            ParseReference(intermediate, reader, section);
                            break;

                        case "complexReference":
                            ParseComplexReference(intermediate, reader, section);
                            break;

                        case "featureBacklink":
                            ParseFeatureBacklink(intermediate, reader, section);
                            break;

                        case "table":
                            ParseTable(intermediate, reader, section, tableDefinitions);
                            break;

                        case "ignoreModularization":
                            ParseIgnoreModularization(intermediate, reader, section);
                            break;

                        default:
                            throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Unexpected element while processing 'section': '{0}'", reader.LocalName));
                        }
                        break;

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!done)
                {
                    throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Missing end element while processing 'section'."));
                }
            }

            intermediate.Sections.Add(section);
        }
예제 #21
0
        /// <summary>
        /// Parse an intermediate from an XML format.
        /// </summary>
        /// <param name="intermediate">Intermediate to populate with persisted data.</param>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="tableDefinitions">TableDefinitions to use in the intermediate.</param>
        /// <param name="suppressVersionCheck">Suppress checking for wix.dll version mismatch.</param>
        private static void ParseIntermediate(Intermediate intermediate, XmlReader reader, TableDefinitionCollection tableDefinitions, bool suppressVersionCheck)
        {
            // read the document root
            reader.MoveToContent();
            if ("wixObject" != reader.LocalName)
            {
                throw new WixNotIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Invalid root element: '{0}', expected 'wixObject'", reader.LocalName));
            }

            bool empty = reader.IsEmptyElement;

            Version objVersion = null;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                    case "src":
                        intermediate.SourcePath = reader.Value;
                        break;
                    case "version":
                        objVersion = new Version(reader.Value);
                        break;
                }
            }

            if (null != objVersion && !suppressVersionCheck)
            {
                Version currentVersion = Common.IntermediateFormatVersion;
                if (0 != currentVersion.CompareTo(objVersion))
                {
                    throw new WixVersionMismatchException(currentVersion, objVersion, "Intermediate", intermediate.Path);
                }
            }

            // loop through the rest of the xml building up the SectionCollection
            if (!empty)
            {
                bool done = false;

                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            switch (reader.LocalName)
                            {
                                case "section":
                                    ParseSection(intermediate, reader, tableDefinitions);
                                    break;
                                default:
                                    throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Unexpected element while processing 'wixObject': '{0}'", reader.LocalName));
                            }
                            break;
                        case XmlNodeType.EndElement:
                            done = true;
                            break;
                    }
                }

                if (!done)
                {
                    throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Missing end element while processing 'wixObject'."));
                }
            }
        }
예제 #22
0
        /// <summary>
        /// Loads an intermediate from a path on disk.
        /// </summary>
        /// <param name="path">Path to intermediate file saved on disk.</param>
        /// <param name="tableDefinitions">Collection containing TableDefinitions to use when reconstituting the intermediate.</param>
        /// <param name="suppressVersionCheck">Suppress checking for wix.dll version mismatches.</param>
        /// <returns>Returns the loaded intermediate.</returns>
        /// <remarks>This method will set the Path and SourcePath properties to the appropriate values on successful load.</remarks>
        public static Intermediate Load(string path, TableDefinitionCollection tableDefinitions, bool suppressVersionCheck)
        {
            Intermediate intermediate = new Intermediate();
            intermediate.Path = path;

            XmlTextReader reader = null;
            try
            {
                reader = new XmlTextReader(path);
                ParseIntermediate(intermediate, reader, tableDefinitions, suppressVersionCheck);
            }
            finally
            {
                if (null != reader)
                {
                    reader.Close();
                }
            }

            return intermediate;
        }
예제 #23
0
 /// <summary>
 /// Constructor for all compiler core.
 /// </summary>
 /// <param name="intermediate">The Intermediate object representing compiled source document.</param>
 /// <param name="tableDefinitions">The loaded table definition collection.</param>
 /// <param name="extensions">The WiX extensions collection.</param>
 /// <param name="messageHandler">The message handler.</param>
 internal CompilerCore(Intermediate intermediate, TableDefinitionCollection tableDefinitions, Hashtable extensions, MessageEventHandler messageHandler, XmlSchema schema)
 {
     this.tableDefinitions = tableDefinitions;
     this.extensions = extensions;
     this.intermediate = intermediate;
     this.MessageHandler = messageHandler;
     this.schema = schema;
 }
예제 #24
0
        /// <summary>
        /// Parse a reference from the xml.
        /// </summary>
        /// <param name="intermediate">Intermediate to populate with persisted data.</param>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="section">Section to populate with persisted data.</param>
        private static void ParseReference(Intermediate intermediate, XmlReader reader, Section section)
        {
            bool empty = reader.IsEmptyElement;
            string id = null;
            string table = null;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                    case "symbol":
                        id = reader.Value;
                        break;
                    case "table":
                        table = reader.Value;
                        break;
                }
            }
            if (null == table)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Reference missing required attribute: 'table'");
            }
            if (null == id)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Reference missing required attribute: 'id'");
            }

            if (!empty && reader.Read() && XmlNodeType.EndElement != reader.MoveToContent())
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Unexpected content while processing 'reference': {0}", reader.NodeType.ToString()));
            }

            section.References.Add(new Reference(table, id));
        }
예제 #25
0
        /// <summary>
        /// Finds the entry section and loads the symbols from an array of intermediates.
        /// </summary>
        /// <param name="intermediates">Array of intermediates to load symbols for and find entry section.</param>
        /// <param name="allowIdenticalRows">Flag specifying whether identical rows are allowed or not.</param>
        /// <param name="messageHandler">Message handler object to route all errors through.</param>
        /// <param name="entrySection">Located entry section.</param>
        /// <param name="allSymbols">Collection of symbols loaded.</param>
        internal static void FindEntrySectionAndLoadSymbols(
			Intermediate[] intermediates,
			bool allowIdenticalRows,
			IMessageHandler messageHandler,
			out Section entrySection,
			out SymbolCollection allSymbols)
        {
            entrySection = null;
            allSymbols = new SymbolCollection();

            for (int i = 0; i < intermediates.Length; ++i)
            {
                foreach (Section section in intermediates[i].Sections)
                {
                    if (SectionType.Product == section.Type || SectionType.Module == section.Type || SectionType.PatchCreation == section.Type)
                    {
                        if (null == entrySection)
                        {
                            entrySection = section;
                        }
                        else
                        {
                            messageHandler.OnMessage(WixErrors.MultipleEntrySections(SourceLineNumberCollection.FromFileName(entrySection.Intermediate.SourcePath), entrySection.Id, section.Id));
                            messageHandler.OnMessage(WixErrors.MultipleEntrySections2(SourceLineNumberCollection.FromFileName(section.Intermediate.SourcePath)));
                        }
                    }

                    foreach (Symbol symbol in section.GetSymbols(messageHandler))
                    {
                        try
                        {
                            Symbol existingSymbol = allSymbols[symbol.Name];
                            if (null == existingSymbol)
                            {
                                allSymbols.Add(symbol);
                            }
                            else if (allowIdenticalRows && existingSymbol.Row.IsIdentical(symbol.Row))
                            {
                                messageHandler.OnMessage(WixWarnings.IdenticalRowWarning(symbol.Row.SourceLineNumbers, existingSymbol.Name));
                                messageHandler.OnMessage(WixWarnings.IdenticalRowWarning2(existingSymbol.Row.SourceLineNumbers));
                            }
                            else
                            {
                                allSymbols.AddDuplicate(symbol);
                            }
                        }
                        catch (DuplicateSymbolsException)
                        {
                            // if there is already a duplicate symbol, just
                            // another to the list, don't bother trying to
                            // see if there are any identical symbols
                            allSymbols.AddDuplicate(symbol);
                        }
                    }
                }
            }
        }
예제 #26
0
        /// <summary>
        /// Parse a section from the xml.
        /// </summary>
        /// <param name="intermediate">Intermediate to populate with persisted data.</param>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="tableDefinitions">TableDefinitions to use in the intermediate.</param>
        private static void ParseSection(Intermediate intermediate, XmlReader reader, TableDefinitionCollection tableDefinitions)
        {
            Section section = null;
            string id = null;
            SectionType type = SectionType.Unknown;
            int codepage = 0;
            bool empty = reader.IsEmptyElement;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.Name)
                {
                    case "id":
                        id = reader.Value;
                        break;
                    case "type":
                        switch (reader.Value)
                        {
                            case "fragment":
                                type = SectionType.Fragment;
                                break;
                            case "module":
                                type = SectionType.Module;
                                break;
                            case "product":
                                type = SectionType.Product;
                                break;
                            case "patchCreation":
                                type = SectionType.PatchCreation;
                                break;
                        }
                        break;
                    case "codepage":
                        codepage = Convert.ToInt32(reader.Value);
                        break;
                }
            }
            if (SectionType.Unknown == type)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Unknown section type");
            }
            if (null == id && SectionType.Fragment != type)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Section missing required attribute: 'id'");
            }

            section = new Section(intermediate, id, type, codepage);

            if (!empty)
            {
                bool done = false;

                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                        switch (reader.LocalName)
                        {
                            case "reference":
                                ParseReference(intermediate, reader, section);
                                break;
                            case "complexReference":
                                ParseComplexReference(intermediate, reader, section);
                                break;
                            case "featureBacklink":
                                ParseFeatureBacklink(intermediate, reader, section);
                                break;
                            case "table":
                                ParseTable(intermediate, reader, section, tableDefinitions);
                                break;
                            case "ignoreModularization":
                                ParseIgnoreModularization(intermediate, reader, section);
                                break;
                            default:
                                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Unexpected element while processing 'section': '{0}'", reader.LocalName));
                        }
                            break;
                        case XmlNodeType.EndElement:
                            done = true;
                            break;
                    }
                }

                if (!done)
                {
                    throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Missing end element while processing 'section'."));
                }
            }

            intermediate.Sections.Add(section);
        }
예제 #27
0
        /// <summary>
        /// Compiles the provided Xml document into an intermediate object
        /// </summary>
        /// <param name="source">Source xml document to compile.</param>
        /// <param name="sourcePath">Optional original path to xml document on disk.</param>
        /// <returns>Intermediate object representing compiled source document.</returns>
        /// <remarks>This method is not thread-safe.</remarks>
        public Intermediate Compile(XmlDocument source, string sourcePath)
        {
            if (null == source)
            {
                throw new ArgumentNullException("source");
            }

            bool encounteredError = true; // assume we'll hit an error

            // create the intermediate
            Intermediate target = new Intermediate();
            target.SourcePath = sourcePath;

            // try to compile it
            try
            {
                this.core = new CompilerCore(target, this.tableDefinitions, this.Message);
                this.core.PedanticLevel = this.pedanticLevel;
                this.extensionMessages = new ExtensionMessages(this.core);

                foreach (CompilerExtension extension in this.extensions.Values)
                {
                    extension.Core = this.core;
                    extension.Messages = this.extensionMessages;
                    extension.InitializeCompile();
                }

                // parse the document
                if ("Wix" == source.DocumentElement.LocalName)
                {
                    this.ParseWixElement(source.DocumentElement);
                }
                else
                {
                    this.core.OnMessage(WixErrors.InvalidDocumentElement(null, source.DocumentElement.Name, "source", "Wix"));
                }

                // perform schema validation if there were no errors and validation isn't suppressed
                if (!this.core.EncounteredError && !this.suppressValidation)
                {
                    this.ValidateDocument(source);
                }
            }
            finally
            {
                encounteredError = this.core.EncounteredError;

                foreach (CompilerExtension extension in this.extensions.Values)
                {
                    extension.FinalizeCompile();
                    extension.Core = null;
                }
                this.core = null;
            }

            // return the compiled intermediate only if it completed successfully
            return (encounteredError ? null : target);
        }
예제 #28
0
        /// <summary>
        /// Create a library by combining several intermediates (objects).
        /// </summary>
        /// <param name="intermediates">Intermediates to combine.</param>
        /// <returns>Returns the new library.</returns>
        public Library Combine(Intermediate[] intermediates)
        {
            Library library = new Library();

            foreach (Intermediate intermediate in intermediates)
            {
                library.Intermediates.Add(intermediate);
            }

            // check for multiple entry sections and duplicate symbols
            this.Validate(this, library);

            return (this.foundError ? null : library);
        }
예제 #29
0
        /// <summary>
        /// Processes an XmlReader and builds up the output object.
        /// </summary>
        /// <param name="reader">Reader to get data from.</param>
        /// <param name="suppressVersionCheck">Suppresses wix.dll version mismatch check.</param>
        /// <param name="path">The path to display in an error message.</param>
        /// <returns>The Output represented by the Xml.</returns>
        private static Output Parse(XmlReader reader, bool suppressVersionCheck, string path)
        {
            Debug.Assert("wixOutput" == reader.LocalName);

            Output output = new Output();
            output.path = path;
            string entrySectionId = null;
            SectionType sectionType = SectionType.Unknown;
            Version objVersion = null;
            bool empty = reader.IsEmptyElement;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                    case "type":
                        switch (reader.Value)
                        {
                            case "Module":
                                output.type = OutputType.Module;
                                sectionType = SectionType.Module;
                                break;
                            case "Product":
                                output.type = OutputType.Product;
                                sectionType = SectionType.Product;
                                break;
                            case "PatchCreation":
                                output.type = OutputType.PatchCreation;
                                sectionType = SectionType.PatchCreation;
                                break;
                            default:
                                throw new WixParseException(String.Format("The wixOutput/@type attribute contains an unexpected value '{0}'.", reader.Value));
                        }
                        break;
                    case "codepage":
                        output.codepage = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture.NumberFormat);
                        break;
                    case "compressed":
                        output.compressed = Common.IsYes(reader.Value, null, "wixOutput", reader.Name, null);
                        break;
                    case "longFileNames":
                        output.longFileNames = Common.IsYes(reader.Value, null, "wixOutput", reader.Name, null);
                        break;
                    case "entrySectionId":
                        entrySectionId = reader.Value;
                        break;
                    case "moduleGuid":
                        output.moduleGuid = reader.Value;
                        break;
                    case "output":
                        output.path = reader.Value;
                        break;
                    case "suppressAdminSequence":
                        output.suppressAdminSequence = Common.IsYes(reader.Value, null, "wixOutput", reader.Name, null);
                        break;
                    case "suppressAdvertiseSequence":
                        output.suppressAdvertiseSequence = Common.IsYes(reader.Value, null, "wixOutput", reader.Name, null);
                        break;
                    case "suppressUISequence":
                        output.suppressUISequence = Common.IsYes(reader.Value, null, "wixOutput", reader.Name, null);
                        break;
                    case "version":
                        objVersion = new Version(reader.Value);
                        break;
                    case "xmlns":
                        break;
                    default:
                        throw new WixParseException(String.Format("The wixOutput element contains an unexpected attribute {0}.", reader.Name));
                }
            }
            if (null == entrySectionId)
            {
                throw new WixParseException("The wixOutput/@entrySectionId attribute was not found; it is required.");
            }
            if (null != objVersion && !suppressVersionCheck)
            {
                Version currentVersion = Common.OutputFormatVersion;
                if (0 != currentVersion.CompareTo(objVersion))
                {
                    throw new WixVersionMismatchException(currentVersion, objVersion, "Output", output.Path);
                }
            }

            // create a section for all the rows to belong to
            Intermediate intermediate = new Intermediate();
            output.entrySection = new Section(intermediate, entrySectionId, sectionType, output.codepage);

            // loop through the rest of the xml building up the Output object
            if (!empty)
            {
                bool done = false;

                // loop through all the fields in a row
                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            switch (reader.LocalName)
                            {
                                case "outputTable":
                                    output.outputTables.Add(OutputTable.Parse(reader, output.entrySection));
                                    break;
                                case "importStream":
                                    output.importStreams.Add(ImportStream.Parse(reader));
                                    break;
                                case "componentsToFeatures":
                                case "featuresToFeatures":
                                case "modulesToFeatures":
                                    ParseConnectToFeatures(output, reader);
                                    break;
                                case "merge":
                                    ParseMerge(output, reader);
                                    break;
                                case "fileMediaInformation":
                                    output.fileMediaInfoCollection.Add(FileMediaInformation.Parse(reader));
                                    break;
                                case "media":
                                    ParseMedia(output, reader);
                                    break;
                                default:
                                    throw new WixParseException(String.Format("The wixOutput element contains an unexpected child element {0}.", reader.Name));
                            }
                            break;
                        case XmlNodeType.EndElement:
                            done = true;
                            break;
                    }
                }

                if (!done)
                {
                    throw new WixParseException("Missing end element while processing the wixOutput element.");
                }
            }

            return output;
        }
예제 #30
0
        /// <summary>
        /// Parse an intermediate from an XML format.
        /// </summary>
        /// <param name="intermediate">Intermediate to populate with persisted data.</param>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="tableDefinitions">TableDefinitions to use in the intermediate.</param>
        /// <param name="suppressVersionCheck">Suppress checking for wix.dll version mismatch.</param>
        private static void ParseIntermediate(Intermediate intermediate, XmlReader reader, TableDefinitionCollection tableDefinitions, bool suppressVersionCheck)
        {
            // read the document root
            reader.MoveToContent();
            if ("wixObject" != reader.LocalName)
            {
                throw new WixNotIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Invalid root element: '{0}', expected 'wixObject'", reader.LocalName));
            }

            bool empty = reader.IsEmptyElement;

            Version objVersion = null;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "src":
                    intermediate.SourcePath = reader.Value;
                    break;

                case "version":
                    objVersion = new Version(reader.Value);
                    break;
                }
            }

            if (null != objVersion && !suppressVersionCheck)
            {
                Version currentVersion = Common.IntermediateFormatVersion;
                if (0 != currentVersion.CompareTo(objVersion))
                {
                    throw new WixVersionMismatchException(currentVersion, objVersion, "Intermediate", intermediate.Path);
                }
            }

            // loop through the rest of the xml building up the SectionCollection
            if (!empty)
            {
                bool done = false;

                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        switch (reader.LocalName)
                        {
                        case "section":
                            ParseSection(intermediate, reader, tableDefinitions);
                            break;

                        default:
                            throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Unexpected element while processing 'wixObject': '{0}'", reader.LocalName));
                        }
                        break;

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!done)
                {
                    throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Missing end element while processing 'wixObject'."));
                }
            }
        }
예제 #31
0
 /// <summary>
 /// Constructor for all compiler core.
 /// </summary>
 /// <param name="intermediate">The Intermediate object representing compiled source document.</param>
 /// <param name="tableDefinitions">The loaded table definition collection.</param>
 /// <param name="messageHandler">The message handler.</param>
 internal CompilerCore(Intermediate intermediate, TableDefinitionCollection tableDefinitions, MessageEventHandler messageHandler)
 {
     this.tableDefinitions = tableDefinitions;
     this.intermediate     = intermediate;
     this.MessageHandler   = messageHandler;
 }
예제 #32
0
        /// <summary>
        /// Parse a complex reference from the xml.
        /// </summary>
        /// <param name="intermediate">Intermediate to populate with persisted data.</param>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="section">Section to populate with persisted data.</param>
        private static void ParseComplexReference(Intermediate intermediate, XmlReader reader, Section section)
        {
            bool empty = reader.IsEmptyElement;
            ComplexReferenceParentType parentType = ComplexReferenceParentType.Unknown;
            string parentId = null;
            string parentLanguage = null;
            ComplexReferenceChildType childType = ComplexReferenceChildType.Unknown;
            string childId = null;
            bool primary = false;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                    case "parent":
                        parentId = reader.Value;
                        break;
                    case "parentLanguage":
                        parentLanguage = reader.Value;
                        break;
                    case "parentType":
                        switch (reader.Value)
                        {
                            case "componentGroup":
                                parentType = ComplexReferenceParentType.ComponentGroup;
                                break;
                            case "feature":
                                parentType = ComplexReferenceParentType.Feature;
                                break;
                            case "module":
                                parentType = ComplexReferenceParentType.Module;
                                break;
                        }
                        break;
                    case "child":
                        childId = reader.Value;
                        break;
                    case "childType":
                        switch (reader.Value)
                        {
                            case "component":
                                childType = ComplexReferenceChildType.Component;
                                break;
                            case "componentGroup":
                                childType = ComplexReferenceChildType.ComponentGroup;
                                break;
                            case "feature":
                                childType = ComplexReferenceChildType.Feature;
                                break;
                            case "fragment":
                                childType = ComplexReferenceChildType.Fragment;
                                break;
                            case "module":
                                childType = ComplexReferenceChildType.Module;
                                break;
                        }
                        break;
                    case "primary":
                        primary = Common.IsYes(reader.Value, SourceLineNumberCollection.FromFileName(intermediate.Path), "complexReference", "primary", parentId);
                        break;
                }
            }
            if (ComplexReferenceParentType.Unknown == parentType)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Unknown ComplexReferenceParentType type");
            }
            if (null == parentId)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "ComplexReference missing required attribute: 'parentId'");
            }
            if (ComplexReferenceChildType.Unknown == childType)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Unknown ComplexReferenceChildType type");
            }
            if (null == childId)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "ComplexReference missing required attribute: 'childId'");
            }

            if (!empty && reader.Read() && XmlNodeType.EndElement != reader.MoveToContent())
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Unexpected content while processing 'complexReference': {0}", reader.NodeType.ToString()));
            }

            section.ComplexReferences.Add(new ComplexReference(parentType, parentId, parentLanguage, childType, childId, primary));
        }
예제 #33
0
        /// <summary>
        /// Parse an intermediate from an XML format.
        /// </summary>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="tableDefinitions">TableDefinitions to use in the intermediate.</param>
        /// <param name="suppressVersionCheck">Suppress checking for wix.dll version mismatch.</param>
        /// <returns>The parsed Intermediate.</returns>
        internal static Intermediate Parse(XmlReader reader, TableDefinitionCollection tableDefinitions, bool suppressVersionCheck)
        {
            Debug.Assert("wixObject" == reader.LocalName);

            bool empty = reader.IsEmptyElement;
            Version objVersion = null;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                    case "version":
                        objVersion = new Version(reader.Value);
                        break;
                    default:
                        if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal))
                        {
                            throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixObject", reader.Name));
                        }
                        break;
                }
            }

            if (null != objVersion && !suppressVersionCheck)
            {
                if (0 != currentVersion.CompareTo(objVersion))
                {
                    throw new WixException(WixErrors.VersionMismatch(SourceLineNumberCollection.FromUri(reader.BaseURI), "object", objVersion.ToString(), currentVersion.ToString()));
                }
            }

            Intermediate intermediate = new Intermediate();

            // loop through the rest of the xml building up the SectionCollection
            if (!empty)
            {
                bool done = false;

                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            switch (reader.LocalName)
                            {
                                case "section":
                                    intermediate.sections.Add(Section.Parse(reader, tableDefinitions));
                                    break;
                                default:
                                    throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixObject", reader.Name));
                            }
                            break;
                        case XmlNodeType.EndElement:
                            done = true;
                            break;
                    }
                }

                if (!done)
                {
                    throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixObject"));
                }
            }

            return intermediate;
        }
예제 #34
0
        /// <summary>
        /// Parse a complex reference from the xml.
        /// </summary>
        /// <param name="intermediate">Intermediate to populate with persisted data.</param>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="section">Section to populate with persisted data.</param>
        private static void ParseComplexReference(Intermediate intermediate, XmlReader reader, Section section)
        {
            bool empty = reader.IsEmptyElement;
            ComplexReferenceParentType parentType = ComplexReferenceParentType.Unknown;
            string parentId       = null;
            string parentLanguage = null;
            ComplexReferenceChildType childType = ComplexReferenceChildType.Unknown;
            string childId = null;
            bool   primary = false;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "parent":
                    parentId = reader.Value;
                    break;

                case "parentLanguage":
                    parentLanguage = reader.Value;
                    break;

                case "parentType":
                    switch (reader.Value)
                    {
                    case "componentGroup":
                        parentType = ComplexReferenceParentType.ComponentGroup;
                        break;

                    case "feature":
                        parentType = ComplexReferenceParentType.Feature;
                        break;

                    case "module":
                        parentType = ComplexReferenceParentType.Module;
                        break;
                    }
                    break;

                case "child":
                    childId = reader.Value;
                    break;

                case "childType":
                    switch (reader.Value)
                    {
                    case "component":
                        childType = ComplexReferenceChildType.Component;
                        break;

                    case "componentGroup":
                        childType = ComplexReferenceChildType.ComponentGroup;
                        break;

                    case "feature":
                        childType = ComplexReferenceChildType.Feature;
                        break;

                    case "fragment":
                        childType = ComplexReferenceChildType.Fragment;
                        break;

                    case "module":
                        childType = ComplexReferenceChildType.Module;
                        break;
                    }
                    break;

                case "primary":
                    primary = Common.IsYes(reader.Value, SourceLineNumberCollection.FromFileName(intermediate.Path), "complexReference", "primary", parentId);
                    break;
                }
            }
            if (ComplexReferenceParentType.Unknown == parentType)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Unknown ComplexReferenceParentType type");
            }
            if (null == parentId)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "ComplexReference missing required attribute: 'parentId'");
            }
            if (ComplexReferenceChildType.Unknown == childType)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Unknown ComplexReferenceChildType type");
            }
            if (null == childId)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "ComplexReference missing required attribute: 'childId'");
            }

            if (!empty && reader.Read() && XmlNodeType.EndElement != reader.MoveToContent())
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Unexpected content while processing 'complexReference': {0}", reader.NodeType.ToString()));
            }

            section.ComplexReferences.Add(new ComplexReference(parentType, parentId, parentLanguage, childType, childId, primary));
        }
예제 #35
0
        /// <summary>
        /// Parse ignore modularization data from the xml.
        /// </summary>
        /// <param name="intermediate">Intermediate to populate with persisted data.</param>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="section">Section to populate with persisted data.</param>
        private static void ParseIgnoreModularization(Intermediate intermediate, XmlReader reader, Section section)
        {
            bool empty = reader.IsEmptyElement;
            string name = null;
            string type = null;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                    case "name":
                        name = reader.Value;
                        break;
                    case "type":
                        type = reader.Value;
                        break;
                }
            }
            if (null == name)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Reference missing required attribute: 'name'");
            }
            if (null == type)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Reference missing required attribute: 'type'");
            }

            if (!empty && reader.Read() && XmlNodeType.EndElement != reader.MoveToContent())
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Unexpected content while processing 'ignoreModularization': {0}", reader.NodeType.ToString()));
            }

            section.IgnoreModularizations.Add(new IgnoreModularization(name, type));
        }
예제 #36
0
 /// <summary>
 /// Inspect the compiled output.
 /// </summary>
 /// <param name="output">The compiled output.</param>
 public virtual void InspectIntermediate(Intermediate output)
 {
 }
예제 #37
0
        /// <summary>
        /// Parse a table from the xml.
        /// </summary>
        /// <param name="intermediate">Intermediate to populate with persisted data.</param>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="section">Section to populate with persisted data.</param>
        /// <param name="tableDefinitions">TableDefinitions to use in the intermediate.</param>
        private static void ParseTable(Intermediate intermediate, XmlReader reader, Section section, TableDefinitionCollection tableDefinitions)
        {
            bool empty = reader.IsEmptyElement;
            string name = null;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                    case "name":
                        name = reader.Value;
                        break;
                }
            }
            if (null == name)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Table missing required attribute: 'name'");
            }

            if (!empty)
            {
                bool done = false;

                // loop through all the rows (tuples) in a table
                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            switch (reader.LocalName)
                            {
                                case "tuple":
                                    ParseTuple(intermediate, reader, section, tableDefinitions[name]);
                                    break;
                                default:
                                    throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Unexpected element while processing 'table': '{0}'", reader.LocalName));
                            }
                            break;
                        case XmlNodeType.EndElement:
                            done = true;
                            break;
                    }
                }

                if (!done)
                {
                    throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Missing end element while processing 'table'."));
                }
            }
        }
예제 #38
0
파일: Compiler.cs 프로젝트: Jeremiahf/wix3
        public Intermediate Compile(XmlDocument source)
        {
            if (null == source)
            {
                throw new ArgumentNullException("source");
            }

            bool encounteredError = false;

            // create the intermediate
            Intermediate target = new Intermediate();

            // try to compile it
            try
            {
                this.core = new CompilerCore(target, this.tableDefinitions, this.extensions, this.Message, this.schema);
                this.core.ShowPedanticMessages = this.showPedanticMessages;
                this.core.CurrentPlatform = this.currentPlatform;
                this.core.FipsCompliant = this.fipsCompliant;

                foreach (CompilerExtension extension in this.extensions.Values)
                {
                    extension.Core = this.core;
                    extension.InitializeCompile();
                }

                // parse the document
                SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(source.DocumentElement);
                if ("Wix" == source.DocumentElement.LocalName)
                {
                    if (this.schema.TargetNamespace == source.DocumentElement.NamespaceURI)
                    {
                        this.ParseWixElement(source.DocumentElement);
                    }
                    else // invalid or missing namespace
                    {
                        if (0 == source.DocumentElement.NamespaceURI.Length)
                        {
                            this.core.OnMessage(WixErrors.InvalidWixXmlNamespace(sourceLineNumbers, "Wix", this.schema.TargetNamespace));
                        }
                        else
                        {
                            this.core.OnMessage(WixErrors.InvalidWixXmlNamespace(sourceLineNumbers, "Wix", source.DocumentElement.NamespaceURI, this.schema.TargetNamespace));
                        }
                    }
                }
                else
                {
                    this.core.OnMessage(WixErrors.InvalidDocumentElement(sourceLineNumbers, source.DocumentElement.Name, "source", "Wix"));
                }

                // perform schema validation if there were no errors and validation isn't suppressed
                if (!this.core.EncounteredError && !this.suppressValidation)
                {
                    this.ValidateDocument(source);
                }

                // inspect the document
                InspectorCore inspectorCore = new InspectorCore(this.Message);
                foreach (InspectorExtension inspectorExtension in this.inspectorExtensions)
                {
                    inspectorExtension.Core = inspectorCore;
                    inspectorExtension.InspectIntermediate(target);

                    // reset
                    inspectorExtension.Core = null;
                }

                if (inspectorCore.EncounteredError)
                {
                    encounteredError = true;
                }
            }
            finally
            {
                if (this.core.EncounteredError)
                {
                    encounteredError = true;
                }

                foreach (CompilerExtension extension in this.extensions.Values)
                {
                    extension.FinalizeCompile();
                    extension.Core = null;
                }
                this.core = null;
            }

            // return the compiled intermediate only if it completed successfully
            return (encounteredError ? null : target);
        }
 /// <summary>
 /// Add a new intermediate to the collection.
 /// </summary>
 /// <param name="intermediate">Intermediate to add to the collection.</param>
 public void Add(Intermediate intermediate)
 {
     collection.Add(intermediate);
 }
예제 #40
0
        /// <summary>
        /// Links an array of intermediates into an output.
        /// </summary>
        /// <param name="intermediates">Array of intermediates to link together.</param>
        /// <returns>Output object from the linking.</returns>
        public Output Link(Intermediate[] intermediates)
        {
            Output output = null;

            try
            {
                SymbolCollection allSymbols;
                Section entrySection;
                bool containsModuleSubstitution = false;
                bool containsModuleConfiguration = false;

                StringCollection referencedSymbols = new StringCollection();
                ArrayList unresolvedReferences = new ArrayList();

                ConnectToFeatureCollection componentGroupsToFeatures = new ConnectToFeatureCollection();
                ConnectToModuleCollection componentGroupsToModules = new ConnectToModuleCollection();
                ComplexReferenceCollection componentsToComponentGroupsComplexReferences = new ComplexReferenceCollection();
                ConnectToFeatureCollection componentsToFeatures = new ConnectToFeatureCollection();
                ConnectToFeatureCollection featuresToFeatures = new ConnectToFeatureCollection();

                this.activeOutput = null;
                this.foundError = false;

                SortedList adminProperties = new SortedList();
                SortedList secureProperties = new SortedList();
                SortedList hiddenProperties = new SortedList();

                ActionTable requiredActions = new ActionTable();
                RowCollection suppressActionRows = new RowCollection();
                TableDefinitionCollection customTableDefinitions = new TableDefinitionCollection();
                RowCollection customRows = new RowCollection();

                foreach (SchemaExtension extension in this.extensions.Values)
                {
                    extension.Messages = this.extensionMessages;
                }

                // first find the entry section and create the symbols hash for all
                // the sections in all the intermediates
                Common.FindEntrySectionAndLoadSymbols(intermediates, this.allowIdenticalRows, this, out entrySection, out allSymbols);

                // should have found an entry section by now
                if (null == entrySection)
                {
                    this.OnMessage(WixErrors.MissingEntrySection());
                    return null;
                }

                // add the standard action symbols to the entry section's symbol table
                this.LoadStandardActionSymbols(allSymbols, entrySection, this.standardActions);

                // now that we know where we're starting from, create the output object
                output = new Output(entrySection); // Note: this entry section will get added to the output section collection later
                if (null != this.localizer && -1 != this.localizer.Codepage)
                {
                    output.Codepage = this.localizer.Codepage;
                }
                this.activeOutput = output;

                // resolve the symbol references to find the set of sections we
                // care about then resolve complex references in those sections
                Common.ResolveReferences(output.Type, output.Sections, output.EntrySection, allSymbols, referencedSymbols, unresolvedReferences, this);
                this.ProcessComplexReferences(output, output.Sections, referencedSymbols, componentsToComponentGroupsComplexReferences, componentGroupsToFeatures, componentGroupsToModules, componentsToFeatures, featuresToFeatures);
                for (int i = 0; i < unresolvedReferences.Count; ++i)
                {
                    Common.ReferenceSection referenceSection = (Common.ReferenceSection)unresolvedReferences[i];
                    if (this.allowUnresolvedReferences)
                    {
                        this.OnMessage(WixWarnings.UnresolvedReferenceWarning(SourceLineNumberCollection.FromFileName(referenceSection.section.Intermediate.SourcePath), referenceSection.section.Type.ToString(), referenceSection.section.Id, referenceSection.reference.SymbolicName));
                    }
                    else
                    {
                        this.OnMessage(WixErrors.UnresolvedReference(SourceLineNumberCollection.FromFileName(referenceSection.section.Intermediate.SourcePath), referenceSection.section.Type.ToString(), referenceSection.section.Id, referenceSection.reference.SymbolicName));
                    }
                }

                if (this.foundError)
                {
                    return null;
                }

                this.ResolveComponentGroups(output, referencedSymbols, componentsToComponentGroupsComplexReferences, componentGroupsToFeatures, componentGroupsToModules, componentsToFeatures);
                this.FindOrphanedSymbols(referencedSymbols);

                // resolve the feature backlink for each section then update the feature to feature connects
                this.ResolveFeatureBacklinks(output, componentsToFeatures, allSymbols, referencedSymbols, unresolvedReferences);
                this.ResolveFeatureToFeatureConnects(featuresToFeatures, allSymbols, referencedSymbols, unresolvedReferences);

                // create a Hashtable of all the suppressed sequence types
                Hashtable suppressedSequenceTypes = new Hashtable();
                // create a Hashtable of all the suppressed standard actions
                Hashtable suppressedStandardActions = new Hashtable();

                if (this.suppressAdminSequence)
                {
                    suppressedSequenceTypes[SequenceType.adminExecute] = null;
                    suppressedSequenceTypes[SequenceType.adminUI] = null;
                }
                if (this.suppressAdvertiseSequence)
                {
                    suppressedSequenceTypes[SequenceType.advertiseExecute] = null;
                }
                if (this.suppressUISequence)
                {
                    suppressedSequenceTypes[SequenceType.adminUI] = null;
                    suppressedSequenceTypes[SequenceType.installUI] = null;
                }

                // start generating OutputTables and OutputRows for all the sections in the output
                RowCollection ensureTableRows = new RowCollection();
                foreach (Section section in this.activeOutput.Sections)
                {
                    // add this sections list of identifiers to ignore modularization
                    this.activeOutput.IgnoreModularizations.Add(section.IgnoreModularizations);

                    foreach (Table table in section.Tables)
                    {
                        bool copyRows = !table.Definition.IsUnreal; // by default, copy rows if the table is not unreal

                        // handle special tables
                        switch (table.Name)
                        {
                            case "Actions":
                                foreach (Row row in table.Rows)
                                {
                                    SequenceType sequenceType;
                                    string seqType = (string)row[0];
                                    string id = (string)row[1];
                                    int sequence = null == row[3] ? 0 : Convert.ToInt32(row[3]);
                                    bool suppress = 1 == Convert.ToInt32(row[6]);

                                    switch (seqType)
                                    {
                                        case "AdminUISequence":
                                            sequenceType = SequenceType.adminUI;
                                            break;
                                        case "AdminExecuteSequence":
                                            sequenceType = SequenceType.adminExecute;
                                            break;
                                        case "AdvertiseExecuteSequence":
                                            sequenceType = SequenceType.advertiseExecute;
                                            break;
                                        case "InstallExecuteSequence":
                                            sequenceType = SequenceType.installExecute;
                                            break;
                                        case "InstallUISequence":
                                            sequenceType = SequenceType.installUI;
                                            break;
                                        default:
                                            throw new WixInvalidSequenceTypeException(null, seqType);
                                    }

                                    if (suppressedSequenceTypes.Contains(sequenceType))
                                    {
                                        this.OnMessage(WixWarnings.SuppressAction(id, Action.SequenceTypeToString(sequenceType)));
                                        continue;
                                    }

                                    // create a SuppressAction row to allow suppressing the action from a merge module
                                    if (suppress)
                                    {
                                        Row suppressActionRow = new Row(row.SourceLineNumbers, this.tableDefinitions["SuppressAction"]);
                                        if ("AdvertiseExecuteSequence" == (string)row[0])
                                        {
                                            suppressActionRow[0] = "AdvtExecuteSequence";
                                        }
                                        else
                                        {
                                            suppressActionRow[0] = row[0];
                                        }
                                        suppressActionRow[1] = row[1];

                                        suppressActionRows.Add(suppressActionRow);
                                    }

                                    Action action = this.standardActions[sequenceType, id];
                                    string beforeAction = (string)row[4];
                                    string afterAction = (string)row[5];

                                    // if this is not a standard action or there is a before or after action specified
                                    if (null == action || null != beforeAction || null != afterAction)
                                    {
                                        action = new Action(sequenceType, id, (string)row[2], sequence, beforeAction, afterAction);
                                        requiredActions.Add(action, true); // add the action and overwrite even if it already exists since this is a customization

                                        // if the parent action is a standard action add it to the required list
                                        string parentActionName = null != beforeAction ? beforeAction : afterAction;
                                        Action parentAction = this.standardActions[sequenceType, parentActionName];
                                        if (null != parentAction)
                                        {
                                            requiredActions.Add(parentAction);
                                        }
                                    }
                                    else if (!suppress) // must have a standard action that is being overriden (when not suppressed)
                                    {
                                        action.Condition = (string)row[2];
                                        if (0 != sequence) // if the user specified a sequence number, override the default
                                        {
                                            action.SequenceNumber = sequence;
                                        }

                                        requiredActions.Add(action, true); // ensure this action is in the required list
                                    }

                                    // action was suppressed by user
                                    if (suppress && null != action)
                                    {
                                        suppressedStandardActions[String.Concat(action.SequenceType.ToString(), id)] = action;
                                    }
                                }
                                break;

                            case "AppSearch":
                                Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["Signature"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "AppSearch"]);
                                requiredActions.Add(this.standardActions[SequenceType.installUI, "AppSearch"]);
                                break;

                            case "Binary":
                            case "Icon":
                            case "MsiDigitalCertificate":
                                foreach (Row row in table.Rows)
                                {
                                    ImportStreamType importStreamType = ImportStreamType.Unknown;
                                    switch (table.Name)
                                    {
                                        case "Binary":
                                            importStreamType = ImportStreamType.Binary;
                                            break;
                                        case "Icon":
                                            importStreamType = ImportStreamType.Icon;
                                            break;
                                        case "MsiDigitalCertificate":
                                            importStreamType = ImportStreamType.DigitalCertificate;
                                            break;
                                    }

                                    ImportStream importStream = new ImportStream(importStreamType, row[0].ToString(), row[1].ToString());
                                    if (this.activeOutput.ImportStreams.Contains(importStream.Name))
                                    {
                                        this.OnMessage(WixErrors.DuplicateSymbol(row.SourceLineNumbers, String.Format("{0} element with Id='{1}' is defined multiple times.", table.Name, row.Symbol.Name)));
                                    }

                                    this.activeOutput.ImportStreams.Add(importStream);
                                }
                                Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions[table.Name]);
                                copyRows = false;
                                break;

                            case "BindImage":
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "BindImage"]);
                                break;

                            case "CCPSearch":
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "AppSearch"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "CCPSearch"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "RMCCPSearch"]);
                                requiredActions.Add(this.standardActions[SequenceType.installUI, "AppSearch"]);
                                requiredActions.Add(this.standardActions[SequenceType.installUI, "CCPSearch"]);
                                requiredActions.Add(this.standardActions[SequenceType.installUI, "RMCCPSearch"]);
                                break;

                            case "Class":
                                requiredActions.Add(this.standardActions[SequenceType.advertiseExecute, "RegisterClassInfo"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "RegisterClassInfo"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "UnregisterClassInfo"]);
                                break;

                            case "Complus":
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "RegisterComPlus"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "UnregisterComPlus"]);
                                break;

                            case "CreateFolder":
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "CreateFolders"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "RemoveFolders"]);
                                break;

                            case "CustomAction":
                                if (OutputType.Module == this.activeOutput.Type)
                                {
                                    Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["AdminExecuteSequence"]);
                                    Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["AdminUISequence"]);
                                    Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["AdvtExecuteSequence"]);
                                    Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["InstallExecuteSequence"]);
                                    Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["InstallUISequence"]);
                                }
                                break;

                            case "CustomTables":
                                foreach (Row row in table.Rows)
                                {
                                    TableDefinition customTable = new TableDefinition((string)row[0], false);

                                    if (null == row[4])
                                    {
                                        this.OnMessage(WixErrors.ExpectedAttribute(row.SourceLineNumbers, "CustomTable/Column", "PrimaryKey"));
                                    }

                                    string[] columnNames = row[2].ToString().Split(tabCharacter);
                                    string[] columnTypes = row[3].ToString().Split(tabCharacter);
                                    string[] primaryKeys = row[4].ToString().Split(tabCharacter);
                                    string[] minValues = row[5] == null ? null : row[5].ToString().Split(tabCharacter);
                                    string[] maxValues = row[6] == null ? null : row[6].ToString().Split(tabCharacter);
                                    string[] keyTables = row[7] == null ? null : row[7].ToString().Split(tabCharacter);
                                    string[] keyColumns = row[8] == null ? null : row[8].ToString().Split(tabCharacter);
                                    string[] categories = row[9] == null ? null : row[9].ToString().Split(tabCharacter);
                                    string[] sets = row[10] == null ? null : row[10].ToString().Split(tabCharacter);
                                    string[] descriptions = row[11] == null ? null : row[11].ToString().Split(tabCharacter);
                                    string[] modularizations = row[12] == null ? null : row[12].ToString().Split(tabCharacter);

                                    int currentPrimaryKey = 0;

                                    for (int i = 0; i < columnNames.Length; ++i)
                                    {
                                        string name = columnNames[i];
                                        ColumnType type = ColumnType.Unknown;
                                        switch (columnTypes[i].Substring(0, 1).ToLower(CultureInfo.InvariantCulture))
                                        {
                                            case "s":
                                                type = ColumnType.String;
                                                break;
                                            case "l":
                                                type = ColumnType.Localized;
                                                break;
                                            case "i":
                                                type = ColumnType.Number;
                                                break;
                                            case "g":
                                                type = ColumnType.Object;
                                                break;
                                            default:
                                                throw new ApplicationException(String.Format("Unknown custom table column type: {0}", columnTypes[i]));
                                        }
                                        bool nullable = columnTypes[i].Substring(0, 1) == columnTypes[i].Substring(0, 1).ToUpper(CultureInfo.InvariantCulture);
                                        int length = Convert.ToInt32(columnTypes[i].Substring(1));

                                        bool primaryKey = false;
                                        if (currentPrimaryKey < primaryKeys.Length && primaryKeys[currentPrimaryKey] == columnNames[i])
                                        {
                                            primaryKey = true;
                                            currentPrimaryKey++;
                                        }

                                        bool minValSet = null != minValues && null != minValues[i] && 0 < minValues[i].Length;
                                        int minValue = 0;
                                        if (minValSet)
                                        {
                                            minValue = Convert.ToInt32(minValues[i]);
                                        }

                                        bool maxValSet = null != maxValues && null != maxValues[i] && 0 < maxValues[i].Length;
                                        int maxValue = 0;
                                        if (maxValSet)
                                        {
                                            maxValue = Convert.ToInt32(maxValues[i]);
                                        }

                                        bool keyColumnSet = null != keyColumns && null != keyColumns[i] && 0 < keyColumns[i].Length;
                                        int keyColumn = 0;
                                        if (keyColumnSet)
                                        {
                                            keyColumn = Convert.ToInt32(keyColumns[i]);
                                        }

                                        ColumnCategory category = ColumnCategory.Unknown;
                                        if (null != categories && null != categories[i] && 0 < categories[i].Length)
                                        {
                                            switch (categories[i])
                                            {
                                                case "Text":
                                                    category = ColumnCategory.Text;
                                                    break;
                                                case "UpperCase":
                                                    category = ColumnCategory.UpperCase;
                                                    break;
                                                case "LowerCase":
                                                    category = ColumnCategory.LowerCase;
                                                    break;
                                                case "Integer":
                                                    category = ColumnCategory.Integer;
                                                    break;
                                                case "DoubleInteger":
                                                    category = ColumnCategory.DoubleInteger;
                                                    break;
                                                case "TimeDate":
                                                    category = ColumnCategory.TimeDate;
                                                    break;
                                                case "Identifier":
                                                    category = ColumnCategory.Identifier;
                                                    break;
                                                case "Property":
                                                    category = ColumnCategory.Property;
                                                    break;
                                                case "Filename":
                                                    category = ColumnCategory.Filename;
                                                    break;
                                                case "WildCardFilename":
                                                    category = ColumnCategory.WildCardFilename;
                                                    break;
                                                case "Path":
                                                    category = ColumnCategory.Path;
                                                    break;
                                                case "Paths":
                                                    category = ColumnCategory.Paths;
                                                    break;
                                                case "AnyPath":
                                                    category = ColumnCategory.AnyPath;
                                                    break;
                                                case "DefaultDir":
                                                    category = ColumnCategory.DefaultDir;
                                                    break;
                                                case "RegPath":
                                                    category = ColumnCategory.RegPath;
                                                    break;
                                                case "Formatted":
                                                    category = ColumnCategory.Formatted;
                                                    break;
                                                case "Template":
                                                    category = ColumnCategory.Template;
                                                    break;
                                                case "Condition":
                                                    category = ColumnCategory.Condition;
                                                    break;
                                                case "Guid":
                                                    category = ColumnCategory.Guid;
                                                    break;
                                                case "Version":
                                                    category = ColumnCategory.Version;
                                                    break;
                                                case "Language":
                                                    category = ColumnCategory.Language;
                                                    break;
                                                case "Binary":
                                                    category = ColumnCategory.Binary;
                                                    break;
                                                case "CustomSource":
                                                    category = ColumnCategory.CustomSource;
                                                    break;
                                                case "Cabinet":
                                                    category = ColumnCategory.Cabinet;
                                                    break;
                                                case "Shortcut":
                                                    category = ColumnCategory.Shortcut;
                                                    break;
                                                default:
                                                    break;
                                            }
                                        }

                                        string keyTable = keyTables != null ? keyTables[i] : null;
                                        string setValue = sets != null ? sets[i] : null;
                                        string description = descriptions != null ? descriptions[i] : null;
                                        string modString = modularizations != null ? modularizations[i] : null;
                                        ColumnModularizeType modularization = ColumnModularizeType.None;
                                        if (modString != null)
                                        {
                                            switch (modString)
                                            {
                                                case "None":
                                                    modularization = ColumnModularizeType.None;
                                                    break;
                                                case "Column":
                                                    modularization = ColumnModularizeType.Column;
                                                    break;
                                                case "Property":
                                                    modularization = ColumnModularizeType.Property;
                                                    break;
                                                case "Condition":
                                                    modularization = ColumnModularizeType.Condition;
                                                    break;
                                                case "CompanionFile":
                                                    modularization = ColumnModularizeType.CompanionFile;
                                                    break;
                                                case "SemicolonDelimited":
                                                    modularization = ColumnModularizeType.SemicolonDelimited;
                                                    break;
                                            }
                                        }

                                        ColumnDefinition columnDefinition = new ColumnDefinition(name, type, length, primaryKey, false, nullable, modularization, false, ColumnType.Localized == type, minValSet, minValue, maxValSet, maxValue, keyTable, keyColumnSet, keyColumn, category, setValue, description, true, true);
                                        customTable.Columns.Add(columnDefinition);
                                    }

                                    customTableDefinitions.Add(customTable);
                                }

                                copyRows = false; // we've created table definitions from these rows, no need to process them any longer
                                break;

                            case "RowData":
                                foreach (Row row in table.Rows)
                                {
                                    customRows.Add(row);
                                }

                                copyRows = false;
                                break;

                            case "Dialog":
                                Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["ListBox"]);
                                break;

                            case "Directory":
                                foreach (Row row in table.Rows)
                                {
                                    if (OutputType.Module == this.activeOutput.Type && Common.IsStandardDirectory(row[0].ToString()))
                                    {
                                        // if the directory table contains references to standard windows folders
                                        // mergemod.dll will add customactions to set the MSM directory to
                                        // the same directory as the standard windows folder and will add references to
                                        // custom action to all the standard sequence tables.  A problem will occur
                                        // if the MSI does not have these tables as mergemod.dll does not add these
                                        // tables to the MSI if absent.  This code adds the tables in case mergemod.dll
                                        // needs them.
                                        Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["CustomAction"]);
                                        Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["AdminExecuteSequence"]);
                                        Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["AdminUISequence"]);
                                        Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["AdvtExecuteSequence"]);
                                        Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["InstallExecuteSequence"]);
                                        Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["InstallUISequence"]);
                                        break; // no need to look here any more, we already found all that we needed to
                                    }
                                }
                                break;

                            case "DuplicateFile":
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "DuplicateFiles"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "RemoveDuplicateFiles"]);
                                break;

                            case "EnsureTables":
                                foreach (Row row in table.Rows)
                                {
                                    ensureTableRows.Add(row);
                                }
                                break;

                            case "Environment":
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "WriteEnvironmentStrings"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "RemoveEnvironmentStrings"]);
                                break;

                            case "Extension":
                                requiredActions.Add(this.standardActions[SequenceType.advertiseExecute, "RegisterExtensionInfo"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "RegisterExtensionInfo"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "UnregisterExtensionInfo"]);
                                break;

                            case "File":
                                foreach (FileRow row in table.Rows)
                                {
                                    // DiskId is not valid when creating a module, so set it to
                                    // 0 for all files to ensure proper sorting in the binder
                                    if (OutputType.Module == this.activeOutput.Type)
                                    {
                                        row.DiskId = 0;
                                    }

                                    // if we have an assembly, insert the MsiAssembly row and assembly actions
                                    if (FileAssemblyType.NotAnAssembly != row.AssemblyType)
                                    {
                                        string feature;
                                        if (OutputType.Module == output.Type)
                                        {
                                            feature = Guid.Empty.ToString("B");
                                        }
                                        else
                                        {
                                            ConnectToFeature connect = componentsToFeatures[row.Component];
                                            if (null == connect)
                                            {
                                                throw new WixMissingFeatureException(row.SourceLineNumbers, new FeatureBacklink(row.Component, FeatureBacklinkType.Assembly, row.File));
                                            }
                                            feature = connect.PrimaryFeature;
                                        }

                                        OutputTable assemblyOutputTable = Common.EnsureOutputTable(output, this.tableDefinitions["MsiAssembly"]);
                                        Row assemblyRow = new Row(assemblyOutputTable.TableDefinition);
                                        assemblyRow[0] = row.Component;
                                        assemblyRow[1] = feature;
                                        assemblyRow[2] = row.AssemblyManifest;
                                        assemblyRow[3] = row.AssemblyApplication;
                                        assemblyRow[4] = Convert.ToInt32(row.AssemblyType);
                                        assemblyOutputTable.OutputRows.Add(new OutputRow(assemblyRow, this.sectionIdOnTuples ? section.Id : null));

                                        requiredActions.Add(this.standardActions[SequenceType.advertiseExecute, "MsiPublishAssemblies"]);
                                        requiredActions.Add(this.standardActions[SequenceType.installExecute, "MsiPublishAssemblies"]);
                                        requiredActions.Add(this.standardActions[SequenceType.installExecute, "MsiUnpublishAssemblies"]);
                                    }

                                    if (null == row.Source) // source to the file must be provided
                                    {
                                        this.OnMessage(WixErrors.FileSourceRequired(row.SourceLineNumbers, row.File));
                                    }
                                    this.activeOutput.FileMediaInformationCollection.Add(new FileMediaInformation(row));
                                }
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "InstallFiles"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "RemoveFiles"]);
                                break;

                            case "Font":
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "RegisterFonts"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "UnregisterFonts"]);
                                break;

                            case "IniFile":
                            case "RemoveIniFile":
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "WriteIniValues"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "RemoveIniValues"]);
                                break;

                            case "IsolatedComponent":
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "IsolateComponents"]);
                                break;

                            case "LaunchCondition":
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "LaunchConditions"]);
                                requiredActions.Add(this.standardActions[SequenceType.installUI, "LaunchConditions"]);
                                break;

                            case "Media":
                                foreach (MediaRow row in table.Rows)
                                {
                                    this.activeOutput.MediaRows.Add(row);
                                }
                                copyRows = false;
                                break;

                            case "Merge":
                                // just copy the rows to the output
                                copyRows = true;
                                break;

                            case "MIME":
                                requiredActions.Add(this.standardActions[SequenceType.advertiseExecute, "RegisterMIMEInfo"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "RegisterMIMEInfo"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "UnregisterMIMEInfo"]);
                                break;

                            case "ModuleSignature":
                                if (OutputType.Module == this.activeOutput.Type)
                                {
                                    foreach (Row row in table.Rows)
                                    {
                                        if (null != this.activeOutput.ModularizationGuid)
                                        {
                                            throw new ArgumentOutOfRangeException("Unexpected number of rows found in table", "ModuleSignature");
                                        }

                                        this.activeOutput.ModularizationGuid = row[3].ToString();
                                    }
                                }
                                break;

                            case "ModuleSubstitution":
                                containsModuleSubstitution = true;
                                break;

                            case "ModuleConfiguration":
                                containsModuleConfiguration = true;
                                break;

                            case "MoveFile":
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "MoveFiles"]);
                                break;

                            case "MsiAssembly":
                                requiredActions.Add(this.standardActions[SequenceType.advertiseExecute, "MsiPublishAssemblies"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "MsiPublishAssemblies"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "MsiUnpublishAssemblies"]);
                                break;

                            case "ODBCDataSource":
                            case "ODBCTranslator":
                            case "ODBCDriver":
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "SetODBCFolders"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "InstallODBC"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "RemoveODBC"]);
                                break;

                            case "ProgId":
                                requiredActions.Add(this.standardActions[SequenceType.advertiseExecute, "RegisterProgIdInfo"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "RegisterProgIdInfo"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "UnregisterProgIdInfo"]);
                                Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["Extension"]); // Extension table is required with a ProgId table
                                break;

                            case "Property":
                                foreach (PropertyRow row in table.Rows)
                                {
                                    // if there is no value in the property, then it must be virtual
                                    if (null == row.Value || 0 == row.Value.Length)
                                    {
                                        row.IsUnreal = true;
                                    }

                                    if (row.Admin)
                                    {
                                        adminProperties[row.Id] = null;
                                    }

                                    if (row.Secure)
                                    {
                                        secureProperties[row.Id] = null;
                                    }

                                    if (row.Hidden)
                                    {
                                        hiddenProperties[row.Id] = null;
                                    }
                                }
                                break;

                            case "PublishComponent":
                                requiredActions.Add(this.standardActions[SequenceType.advertiseExecute, "PublishComponents"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "PublishComponents"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "UnpublishComponents"]);
                                break;

                            case "Registry":
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "WriteRegistryValues"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "RemoveRegistryValues"]);
                                break;

                            case "RemoveFile":
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "RemoveFiles"]);
                                break;

                            case "SelfReg":
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "SelfRegModules"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "SelfUnregModules"]);
                                break;

                            case "ServiceControl":
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "StartServices"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "StopServices"]);
                                break;

                            case "ServiceInstall":
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "InstallServices"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "DeleteServices"]);
                                break;

                            case "Shortcut":
                                requiredActions.Add(this.standardActions[SequenceType.advertiseExecute, "CreateShortcuts"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "CreateShortcuts"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "RemoveShortcuts"]);
                                break;

                            case "TypeLib":
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "RegisterTypeLibraries"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "UnregisterTypeLibraries"]);
                                break;

                            case "Upgrade":
                            {
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "FindRelatedProducts"]);
                                requiredActions.Add(this.standardActions[SequenceType.installExecute, "MigrateFeatureStates"]);
                                requiredActions.Add(this.standardActions[SequenceType.installUI, "FindRelatedProducts"]);
                                requiredActions.Add(this.standardActions[SequenceType.installUI, "MigrateFeatureStates"]);

                                foreach (UpgradeRow row in table.Rows)
                                {
                                    // this should never happen because candle will make sure that all UpgradeVersion(s) have an ActionProperty...but still don't let it slide
                                    if (null == row.ActionProperty)
                                    {
                                        this.OnMessage(WixErrors.ExpectedAttribute(row.SourceLineNumbers, "UpgradeVersion", "ActionProperty"));
                                    }

                                    secureProperties[row.ActionProperty] = null;
                                }

                                break;
                            }

                            case "_SummaryInformation":
                                // if we are processing a product, reach into the summary
                                // information and pull out the bits that say if the layout
                                // image is supposed to have long file names and is compressed
                                if (OutputType.Product == output.Type)
                                {
                                    foreach (Row row in table.Rows)
                                    {
                                        // we're looking for the "Word Count" property which happens to
                                        // be number 15 (and I thought the answer to the universe was 42, heh).
                                        if ("15" == row[0].ToString())
                                        {
                                            output.LongFileNames = (0 == (Convert.ToInt32(row[1]) & 1));
                                            output.Compressed = (2 == (Convert.ToInt32(row[1]) & 2));

                                            break; // we're done looking for what we came looking for
                                        }
                                    }
                                }
                                break;
                        }

                        if (copyRows)
                        {
                            OutputTable outputTable = Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions[table.Name]);
                            this.CopyTableRowsToOutputTable(table, outputTable, section.Id);
                        }
                    }
                }

                if (0 < ensureTableRows.Count)
                {
                    foreach (Row row in ensureTableRows)
                    {
                        string tableId = (string)row[0];
                        TableDefinition tableDef = null;

                        try
                        {
                            tableDef = this.tableDefinitions[tableId];
                        }
                        catch (WixMissingTableDefinitionException)
                        {
                            tableDef = customTableDefinitions[tableId];
                        }

                        Common.EnsureOutputTable(this.activeOutput, tableDef);
                    }
                }

                // copy all the suppress action rows to the output to suppress actions from merge modules
                if (0 < suppressActionRows.Count)
                {
                    OutputTable suppressActionOutputTable = new OutputTable(this.tableDefinitions["SuppressAction"]);
                    this.activeOutput.OutputTables.Add(suppressActionOutputTable);
                    foreach (Row suppressActionRow in suppressActionRows)
                    {
                        suppressActionOutputTable.OutputRows.Add(new OutputRow(suppressActionRow));
                    }
                }

                foreach (Action suppressedAction in suppressedStandardActions.Values)
                {
                    if (requiredActions.Contains(suppressedAction))
                    {
                        // We thought they really ought to have a standard action
                        // that they wanted to suppress, so warn them and remove it
                        this.OnMessage(WixWarnings.SuppressAction(suppressedAction.Id, Action.SequenceTypeToString(suppressedAction.SequenceType)));
                        requiredActions.Remove(suppressedAction);
                    }
                }

                // check for missing table and add them or display an error as appropriate
                switch (this.activeOutput.Type)
                {
                    case OutputType.Module:
                        Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["Component"]);
                        Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["Directory"]);
                        Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["FeatureComponents"]);
                        Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["File"]);
                        Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["ModuleComponents"]);
                        Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["ModuleSignature"]);
                        break;
                    case OutputType.PatchCreation:
                        OutputTable imageFamiliesTable = this.activeOutput.OutputTables["ImageFamilies"];
                        OutputTable targetImagesTable = this.activeOutput.OutputTables["TargetImages"];
                        OutputTable upgradedImagesTable = this.activeOutput.OutputTables["UpgradedImages"];

                        if (null == imageFamiliesTable || 1 > imageFamiliesTable.OutputRows.Count)
                        {
                            this.OnMessage(WixErrors.ExpectedRowInPatchCreationPackage("ImageFamilies"));
                        }

                        if (null == targetImagesTable || 1 > targetImagesTable.OutputRows.Count)
                        {
                            this.OnMessage(WixErrors.ExpectedRowInPatchCreationPackage("TargetImages"));
                        }

                        if (null == upgradedImagesTable || 1 > upgradedImagesTable.OutputRows.Count)
                        {
                            this.OnMessage(WixErrors.ExpectedRowInPatchCreationPackage("UpgradedImages"));
                        }

                        Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["Properties"]);
                        break;
                    case OutputType.Product:
                        // AdminExecuteSequence Table
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminExecute, "CostInitialize"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminExecute, "CostInitialize"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminExecute, "FileCost"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminExecute, "CostFinalize"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminExecute, "InstallValidate"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminExecute, "InstallInitialize"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminExecute, "InstallFiles"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminExecute, "InstallAdminPackage"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminExecute, "InstallFinalize"]);

                        // AdminUISequence Table
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminUI, "CostInitialize"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminUI, "FileCost"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminUI, "CostFinalize"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.adminUI, "ExecuteAction"]);

                        // AdvtExecuteSequence Table
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.advertiseExecute, "CostInitialize"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.advertiseExecute, "CostFinalize"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.advertiseExecute, "InstallValidate"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.advertiseExecute, "InstallInitialize"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.advertiseExecute, "PublishFeatures"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.advertiseExecute, "PublishProduct"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.advertiseExecute, "InstallFinalize"]);

                        // InstallExecuteSequence Table
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "ValidateProductID"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "CostInitialize"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "FileCost"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "CostFinalize"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "InstallValidate"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "InstallInitialize"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "ProcessComponents"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "UnpublishFeatures"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "CostInitialize"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "RegisterUser"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "RegisterProduct"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "PublishFeatures"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "PublishProduct"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installExecute, "InstallFinalize"]);

                        // InstallUISequence Table
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installUI, "ValidateProductID"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installUI, "CostInitialize"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installUI, "FileCost"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installUI, "CostFinalize"]);
                        this.AddIfNotSuppressed(requiredActions, suppressedStandardActions, this.standardActions[SequenceType.installUI, "ExecuteAction"]);

                        Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["File"]);
                        Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["Media"]);
                        break;
                }

                // check for illegal tables
                foreach (OutputTable table in this.activeOutput.OutputTables)
                {
                    switch (this.activeOutput.Type)
                    {
                        case OutputType.Module:
                            if ("BBControl" == table.Name ||
                                "Billboard" == table.Name ||
                                "CCPSearch" == table.Name ||
                                "Feature" == table.Name ||
                                "LaunchCondition" == table.Name ||
                                "Media" == table.Name ||
                                "Merge" == table.Name ||
                                "Patch" == table.Name ||
                                "Upgrade" == table.Name)
                            {
                                foreach (OutputRow outputRow in table.OutputRows)
                                {
                                    this.OnMessage(WixErrors.UnexpectedTableInMergeModule(outputRow.Row.SourceLineNumbers, table.Name));
                                }
                            }
                            else if ("Error" == table.Name)
                            {
                                foreach (OutputRow outputRow in table.OutputRows)
                                {
                                    this.OnMessage(WixWarnings.DangerousTableInMergeModule(outputRow.Row.SourceLineNumbers, table.Name));
                                }
                            }
                            break;
                        case OutputType.PatchCreation:
                            if ("_SummaryInformation" != table.Name &&
                                "ExternalFiles" != table.Name &&
                                "FamilyFileRanges" != table.Name &&
                                "ImageFamilies" != table.Name &&
                                "PatchMetadata" != table.Name &&
                                "PatchSequence" != table.Name &&
                                "Properties" != table.Name &&
                                "TargetFiles_OptionalData" != table.Name &&
                                "TargetImages" != table.Name &&
                                "UpgradedFiles_OptionalData" != table.Name &&
                                "UpgradedFilesToIgnore" != table.Name &&
                                "UpgradedImages" != table.Name)
                            {
                                foreach (OutputRow outputRow in table.OutputRows)
                                {
                                    this.OnMessage(WixErrors.UnexpectedTableInPatchCreationPackage(outputRow.Row.SourceLineNumbers, table.Name));
                                }
                            }
                            break;
                        case OutputType.Product:
                            if ("ModuleAdminExecuteSequence" == table.Name ||
                                "ModuleAdminUISequence" == table.Name ||
                                "ModuleAdvtExecuteSequence" == table.Name ||
                                "ModuleAdvtUISequence" == table.Name ||
                                "ModuleComponents" == table.Name ||
                                "ModuleConfiguration" == table.Name ||
                                "ModuleDependency" == table.Name ||
                                "ModuleExclusion" == table.Name ||
                                "ModuleIgnoreTable" == table.Name ||
                                "ModuleInstallExecuteSequence" == table.Name ||
                                "ModuleInstallUISequence" == table.Name ||
                                "ModuleSignature" == table.Name ||
                                "ModuleSubstitution" == table.Name)
                            {
                                foreach (OutputRow outputRow in table.OutputRows)
                                {
                                    this.OnMessage(WixWarnings.UnexpectedTableInProduct(outputRow.Row.SourceLineNumbers, table.Name));
                                }
                            }
                            break;
                    }
                }

                // add the custom row data
                foreach (Row row in customRows)
                {
                    TableDefinition customTable = (TableDefinition)customTableDefinitions[row[0].ToString()];

                    string[] data = row[2].ToString().Split(tabCharacter);

                    Row customRow = new Row(customTable);
                    for (int i = 0; i < data.Length; ++i)
                    {
                        string[] item = data[i].Split(colonCharacter, 2);
                        customRow.SetData(item[0], item[1]);
                    }

                    bool dataErrors = false;
                    for (int i = 0; i < customTable.Columns.Count; ++i)
                    {
                        if (!customTable.Columns[i].IsNullable && customRow.IsColumnEmpty(i))
                        {
                            this.OnMessage(WixErrors.NoDataForColumn(row.SourceLineNumbers, customTable.Columns[i].Name, customTable.Name));
                            dataErrors = true;
                        }
                    }

                    if (!dataErrors)
                    {
                        OutputTable outputTable = Common.EnsureOutputTable(this.activeOutput, customTable);
                        outputTable.OutputRows.Add(new OutputRow(customRow));
                    }
                }

                // update the special properties
                if (0 < adminProperties.Count)
                {
                    Row newRow = new Row(this.tableDefinitions["Property"]);
                    newRow[0] = "AdminProperties";
                    newRow[1] = GetPropertyListString(adminProperties);

                    OutputTable outputTable = Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["Property"]);
                    outputTable.OutputRows.Add(new OutputRow(newRow));
                }
                if (0 < secureProperties.Count)
                {
                    Row newRow = new Row(this.tableDefinitions["Property"]);
                    newRow[0] = "SecureCustomProperties";
                    newRow[1] = GetPropertyListString(secureProperties);

                    OutputTable outputTable = Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["Property"]);
                    outputTable.OutputRows.Add(new OutputRow(newRow));
                }
                if (0 < hiddenProperties.Count)
                {
                    Row newRow = new Row(this.tableDefinitions["Property"]);
                    newRow[0] = "MsiHiddenProperties";
                    newRow[1] = GetPropertyListString(hiddenProperties);

                    OutputTable outputTable = Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["Property"]);
                    outputTable.OutputRows.Add(new OutputRow(newRow));
                }

                if (containsModuleSubstitution)
                {
                    Row newRow = new Row(this.tableDefinitions["ModuleIgnoreTable"]);
                    newRow[0] = "ModuleSubstitution";

                    OutputTable outputTable = Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["ModuleIgnoreTable"]);
                    outputTable.OutputRows.Add(new OutputRow(newRow));
                }

                if (containsModuleConfiguration)
                {
                    Row newRow = new Row(this.tableDefinitions["ModuleIgnoreTable"]);
                    newRow[0] = "ModuleConfiguration";

                    OutputTable outputTable = Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["ModuleIgnoreTable"]);
                    outputTable.OutputRows.Add(new OutputRow(newRow));
                }

                // process the actions
                foreach (Action action in requiredActions)
                {
                    // skip actions in suppressed sequences
                    if (suppressedSequenceTypes.Contains(action.SequenceType))
                    {
                        continue;
                    }

                    if (OutputType.Product == this.activeOutput.Type)
                    {
                        this.ResolveActionSequence(action, requiredActions);
                    }

                    TableDefinition sequenceTableDef = null;
                    bool module = OutputType.Module == this.activeOutput.Type;
                    switch (action.SequenceType)
                    {
                        case SequenceType.adminExecute:
                            if (module)
                            {
                                Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["AdminExecuteSequence"]);
                                sequenceTableDef = this.tableDefinitions["ModuleAdminExecuteSequence"];
                            }
                            else
                            {
                                sequenceTableDef = this.tableDefinitions["AdminExecuteSequence"];
                            }
                            break;
                        case SequenceType.adminUI:
                            if (module)
                            {
                                Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["AdminUISequence"]);
                                sequenceTableDef = this.tableDefinitions["ModuleAdminUISequence"];
                            }
                            else
                            {
                                sequenceTableDef = this.tableDefinitions["AdminUISequence"];
                            }
                            break;
                        case SequenceType.advertiseExecute:
                            if (module)
                            {
                                Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["AdvtExecuteSequence"]);
                                sequenceTableDef = this.tableDefinitions["ModuleAdvtExecuteSequence"];
                            }
                            else
                            {
                                sequenceTableDef = this.tableDefinitions["AdvtExecuteSequence"];
                            }
                            break;
                        case SequenceType.installExecute:
                            if (module)
                            {
                                Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["InstallExecuteSequence"]);
                                sequenceTableDef = this.tableDefinitions["ModuleInstallExecuteSequence"];
                            }
                            else
                            {
                                sequenceTableDef = this.tableDefinitions["InstallExecuteSequence"];
                            }
                            break;
                        case SequenceType.installUI:
                            if (module)
                            {
                                Common.EnsureOutputTable(this.activeOutput, this.tableDefinitions["InstallUISequence"]);
                                sequenceTableDef = this.tableDefinitions["ModuleInstallUISequence"];
                            }
                            else
                            {
                                sequenceTableDef = this.tableDefinitions["InstallUISequence"];
                            }
                            break;
                    }

                    Row row = new Row(sequenceTableDef);
                    if (module)
                    {
                        row[0] = action.Id;
                        if (0 != action.SequenceNumber)
                        {
                            row[1] = action.SequenceNumber;
                        }
                        else
                        {
                            bool after = null == action.Before;
                            row[2] = after ? action.After : action.Before;
                            row[3] = after ? 1 : 0;
                        }
                        row[4] = action.Condition;
                    }
                    else // add the row to the sequence table
                    {
                        row[0] = action.Id;
                        row[1] = action.Condition;
                        row[2] = action.SequenceNumber;
                    }

                    OutputTable outputTable = Common.EnsureOutputTable(this.activeOutput, sequenceTableDef);
                    outputTable.OutputRows.Add(new OutputRow(row));
                }

                // set the suppressed action sequences
                if (this.suppressAdminSequence)
                {
                    this.activeOutput.SuppressAdminSequence = true;
                }
                if (this.suppressAdvertiseSequence)
                {
                    this.activeOutput.SuppressAdvertiseSequence = true;
                }
                if (this.suppressUISequence)
                {
                    this.activeOutput.SuppressUISequence = true;
                }
            }
            finally
            {
                this.activeOutput = null;
            }

            return (this.foundError ? null : output);
        }
예제 #41
0
 /// <summary>
 /// Constructor for all compiler core.
 /// </summary>
 /// <param name="intermediate">The Intermediate object representing compiled source document.</param>
 /// <param name="tableDefinitions">The loaded table definition collection.</param>
 /// <param name="messageHandler">The message handler.</param>
 internal CompilerCore(Intermediate intermediate, TableDefinitionCollection tableDefinitions, MessageEventHandler messageHandler)
 {
     this.tableDefinitions = tableDefinitions;
     this.intermediate = intermediate;
     this.MessageHandler = messageHandler;
 }