Exemple #1
0
        /// <summary>
        /// Finds all items under a parent group type and creates new WixGroup data for them.
        /// </summary>
        /// <param name="parentType">The type of the parent group to flatten.</param>
        /// <param name="removeUsedRows">Whether to remove used group rows before returning.</param>
        public void FlattenAndRewriteGroups(ComplexReferenceParentType parentType, bool removeUsedRows)
        {
            var parentTypeString = parentType.ToString();

            Debug.Assert(this.groupTypes.Contains(parentTypeString));

            this.LoadFlattenOrderGroups();
            if (this.Messaging.EncounteredError)
            {
                return;
            }

            foreach (Item item in this.items)
            {
                if (parentTypeString == item.Type)
                {
                    this.CreateOrderedList(item.Type, item.Id, out var orderedItems);
                    this.CreateNewGroupRows(item.Type, item.Id, orderedItems);
                }
            }

            if (removeUsedRows)
            {
                this.RemoveUsedGroupRows();
            }
        }
Exemple #2
0
        /// <summary>
        /// Creates a new complex reference.
        /// </summary>
        /// <param name="parentType">Parent type of complex reference.</param>
        /// <param name="parentId">Identifier for parent of complex reference.</param>
        /// <param name="parentLanguage">Language for parent of complex reference (only valid when parent is Module).</param>
        /// <param name="childType">Child type of complex reference.</param>
        /// <param name="childId">Identifier for child of complex reference.</param>
        /// <param name="primary">Flag if complex reference is the primary for advertised goop.</param>
        public ComplexReference(ComplexReferenceParentType parentType, string parentId, string parentLanguage, ComplexReferenceChildType childType, string childId, bool primary)
        {
            if (ComplexReferenceParentType.Module != this.parentType && null != this.parentLanguage)
            {
                throw new ArgumentException("ParentLanguage cannot be specified unless the parent is a Module.");
            }

            this.parentType     = parentType;
            this.parentId       = parentId;
            this.parentLanguage = parentLanguage;
            this.childType      = childType;
            this.childId        = childId;
            this.primary        = primary;

            this.section = null;
        }
Exemple #3
0
        public WixBundlePayloadSymbol CreatePayloadSymbol(ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType previousType = ComplexReferenceChildType.Unknown, string previousId = null)
        {
            WixBundlePayloadSymbol symbol = null;

            if (parentType == ComplexReferenceParentType.Container && parentId == BurnConstants.BurnUXContainerName)
            {
                if (this.Compressed == YesNoDefaultType.No)
                {
                    this.Core.Write(WarningMessages.UxPayloadsOnlySupportEmbedding(this.SourceLineNumbers, this.SourceFile));
                }

                if (!String.IsNullOrEmpty(this.DownloadUrl))
                {
                    this.Core.Write(WarningMessages.DownloadUrlNotSupportedForBAPayloads(this.SourceLineNumbers, this.Id.Id));
                }

                this.Compressed  = YesNoDefaultType.Yes;
                this.DownloadUrl = null;
            }

            if (!this.Core.EncounteredError)
            {
                symbol = this.Core.AddSymbol(new WixBundlePayloadSymbol(this.SourceLineNumbers, this.Id)
                {
                    Name       = String.IsNullOrEmpty(this.Name) ? Path.GetFileName(this.SourceFile) : this.Name,
                    SourceFile = new IntermediateFieldPathValue {
                        Path = this.SourceFile
                    },
                    DownloadUrl          = this.DownloadUrl,
                    Compressed           = (this.Compressed == YesNoDefaultType.Yes) ? true : (this.Compressed == YesNoDefaultType.No) ? (bool?)false : null,
                    UnresolvedSourceFile = this.SourceFile, // duplicate of sourceFile but in a string column so it won't get resolved to a full path during binding.
                    DisplayName          = this.ProductName,
                    Description          = this.Description,
                    Hash     = this.Hash,
                    FileSize = this.Size,
                    Version  = this.Version,
                });

                this.Core.CreateGroupAndOrderingRows(this.SourceLineNumbers, parentType, parentId, ComplexReferenceChildType.Payload, symbol.Id.Id, previousType, previousId);
            }

            return(symbol);
        }
Exemple #4
0
        /// <summary>
        /// Finds all nested items under a parent group and creates new WixGroup data for them.
        /// </summary>
        /// <param name="parentType">The group type for the parent group to flatten.</param>
        /// <param name="parentId">The identifier of the parent group to flatten.</param>
        /// <param name="removeUsedRows">Whether to remove used group rows before returning.</param>
        public void FlattenAndRewriteRows(ComplexReferenceParentType parentType, string parentId, bool removeUsedRows)
        {
            var parentTypeString = parentType.ToString();

            Debug.Assert(this.groupTypes.Contains(parentTypeString));

            this.CreateOrderedList(parentTypeString, parentId, out var orderedItems);
            if (this.Messaging.EncounteredError)
            {
                return;
            }

            this.CreateNewGroupRows(parentTypeString, parentId, orderedItems);

            if (removeUsedRows)
            {
                this.RemoveUsedGroupRows();
            }
        }
Exemple #5
0
        /// <summary>
        /// Parses a PatchFamilyGroup reference element.
        /// </summary>
        /// <param name="node">Element to parse.</param>
        /// <param name="parentType">The type of parent.</param>
        /// <param name="parentId">Identifier of parent element.</param>
        private void ParsePatchFamilyGroupRefElement(XElement node, ComplexReferenceParentType parentType, string parentId)
        {
            Debug.Assert(ComplexReferenceParentType.PatchFamilyGroup == parentType || ComplexReferenceParentType.Patch == parentType);

            var    sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string id = null;

            foreach (var attrib in node.Attributes())
            {
                if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
                {
                    switch (attrib.Name.LocalName)
                    {
                    case "Id":
                        id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                        this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.WixPatchFamilyGroup, id);
                        break;

                    default:
                        this.Core.UnexpectedAttribute(node, attrib);
                        break;
                    }
                }
                else
                {
                    this.Core.ParseExtensionAttribute(node, attrib);
                }
            }

            if (null == id)
            {
                this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
            }

            this.Core.ParseForExtensionElements(node);

            if (!this.Core.EncounteredError)
            {
                this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.PatchFamilyGroup, id, true);
            }
        }
Exemple #6
0
        /// <summary>
        /// Parses a merge reference element.
        /// </summary>
        /// <param name="node">Element to parse.</param>
        /// <param name="parentType">Parents complex reference type.</param>
        /// <param name="parentId">Identifier for parent feature or feature group.</param>
        private void ParseMergeRefElement(XmlNode node, ComplexReferenceParentType parentType, string parentId)
        {
            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string id = null;
            YesNoType primary = YesNoType.NotSet;

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace)
                {
                    switch (attrib.LocalName)
                    {
                        case "Id":
                            id = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            this.core.CreateWixSimpleReferenceRow(sourceLineNumbers, "WixMerge", id);
                            break;
                        case "Primary":
                            primary = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                            break;
                        default:
                            this.core.UnexpectedAttribute(sourceLineNumbers, attrib);
                            break;
                    }
                }
                else
                {
                    this.core.ParseExtensionAttribute(sourceLineNumbers, (XmlElement)node, attrib);
                }
            }

            if (null == id)
            {
                this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Id"));
            }

            foreach (XmlNode child in node.ChildNodes)
            {
                if (XmlNodeType.Element == child.NodeType)
                {
                    if (child.NamespaceURI == this.schema.TargetNamespace)
                    {
                        this.core.UnexpectedElement(node, child);
                    }
                    else
                    {
                        this.core.UnsupportedExtensionElement(node, child);
                    }
                }
            }

            this.core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.Module, id, (YesNoType.Yes == primary));
        }
Exemple #7
0
        private void ParseFeatureElement(XmlNode node, ComplexReferenceParentType parentType, string parentId, ref int lastDisplay)
        {
            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string id = null;
            string allowAdvertise = null;
            int bits = 0;
            string configurableDirectory = null;
            string description = null;
            string display = "collapse";
            YesNoType followParent = YesNoType.NotSet;
            string installDefault = null;
            int level = 1;
            string title = null;
            string typicalDefault = null;

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace)
                {
                    switch (attrib.LocalName)
                    {
                        case "Id":
                            id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                            break;
                        case "Absent":
                            string absent = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            if (0 < absent.Length)
                            {
                                Wix.Feature.AbsentType absentType = Wix.Feature.ParseAbsentType(absent);
                                switch (absentType)
                                {
                                    case Wix.Feature.AbsentType.allow: // this is the default
                                        break;
                                    case Wix.Feature.AbsentType.disallow:
                                        bits = bits | MsiInterop.MsidbFeatureAttributesUIDisallowAbsent;
                                        break;
                                    default:
                                        this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name, attrib.Name, absent, "allow", "disallow"));
                                        break;
                                }
                            }
                            break;
                        case "AllowAdvertise":
                            allowAdvertise = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            if (0 < allowAdvertise.Length)
                            {
                                Wix.Feature.AllowAdvertiseType allowAdvertiseType = Wix.Feature.ParseAllowAdvertiseType(allowAdvertise);
                                switch (allowAdvertiseType)
                                {
                                    case Wix.Feature.AllowAdvertiseType.no:
                                        bits |= MsiInterop.MsidbFeatureAttributesDisallowAdvertise;
                                        break;
                                    case Wix.Feature.AllowAdvertiseType.system:
                                        bits |= MsiInterop.MsidbFeatureAttributesNoUnsupportedAdvertise;
                                        break;
                                    case Wix.Feature.AllowAdvertiseType.yes: // this is the default
                                        break;
                                    default:
                                        this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name, attrib.Name, allowAdvertise, "no", "system", "yes"));
                                        break;
                                }
                            }
                            break;
                        case "ConfigurableDirectory":
                            configurableDirectory = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                            this.core.CreateWixSimpleReferenceRow(sourceLineNumbers, "Directory", configurableDirectory);
                            break;
                        case "Description":
                            description = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            break;
                        case "Display":
                            display = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            break;
                        case "InstallDefault":
                            installDefault = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            if (0 < installDefault.Length)
                            {
                                Wix.Feature.InstallDefaultType installDefaultType = Wix.Feature.ParseInstallDefaultType(installDefault);
                                switch (installDefaultType)
                                {
                                    case Wix.Feature.InstallDefaultType.followParent:
                                        if (ComplexReferenceParentType.Product == parentType)
                                        {
                                            this.core.OnMessage(WixErrors.RootFeatureCannotFollowParent(sourceLineNumbers));
                                        }
                                        bits = bits | MsiInterop.MsidbFeatureAttributesFollowParent;
                                        break;
                                    case Wix.Feature.InstallDefaultType.local: // this is the default
                                        break;
                                    case Wix.Feature.InstallDefaultType.source:
                                        bits = bits | MsiInterop.MsidbFeatureAttributesFavorSource;
                                        break;
                                    default:
                                        this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name, attrib.Name, installDefault, "followParent", "local", "source"));
                                        break;
                                }
                            }
                            break;
                        case "Level":
                            level = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
                            break;
                        case "Title":
                            title = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            if ("PUT-FEATURE-TITLE-HERE" == title)
                            {
                                this.core.OnMessage(WixWarnings.PlaceholderValue(sourceLineNumbers, node.Name, attrib.Name, title));
                            }
                            break;
                        case "TypicalDefault":
                            typicalDefault = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            if (0 < typicalDefault.Length)
                            {
                                Wix.Feature.TypicalDefaultType typicalDefaultType = Wix.Feature.ParseTypicalDefaultType(typicalDefault);
                                switch (typicalDefaultType)
                                {
                                    case Wix.Feature.TypicalDefaultType.advertise:
                                        bits = bits | MsiInterop.MsidbFeatureAttributesFavorAdvertise;
                                        break;
                                    case Wix.Feature.TypicalDefaultType.install: // this is the default
                                        break;
                                    default:
                                        this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name, attrib.Name, typicalDefault, "advertise", "install"));
                                        break;
                                }
                            }
                            break;
                        default:
                            this.core.UnexpectedAttribute(sourceLineNumbers, attrib);
                            break;
                    }
                }
                else
                {
                    this.core.ParseExtensionAttribute(sourceLineNumbers, (XmlElement)node, attrib);
                }
            }

            if (null == id)
            {
                this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Id"));
            }
            else if (38 < id.Length)
            {
                this.core.OnMessage(WixErrors.FeatureNameTooLong(sourceLineNumbers, node.Name, "Id", id));
            }

            if (null != configurableDirectory && configurableDirectory.ToUpper(CultureInfo.InvariantCulture) != configurableDirectory)
            {
                this.core.OnMessage(WixErrors.FeatureConfigurableDirectoryNotUppercase(sourceLineNumbers, node.Name, "ConfigurableDirectory", configurableDirectory));
            }

            if ("advertise" == typicalDefault && "no" == allowAdvertise)
            {
                this.core.OnMessage(WixErrors.FeatureCannotFavorAndDisallowAdvertise(sourceLineNumbers, node.Name, "TypicalDefault", typicalDefault, "AllowAdvertise", allowAdvertise));
            }

            if (YesNoType.Yes == followParent && ("local" == installDefault || "source" == installDefault))
            {
                this.core.OnMessage(WixErrors.FeatureCannotFollowParentAndFavorLocalOrSource(sourceLineNumbers, node.Name, "InstallDefault", "FollowParent", "yes"));
            }

            int childDisplay = 0;
            foreach (XmlNode child in node.ChildNodes)
            {
                if (XmlNodeType.Element == child.NodeType)
                {
                    if (child.NamespaceURI == this.schema.TargetNamespace)
                    {
                        switch (child.LocalName)
                        {
                            case "ComponentGroupRef":
                                this.ParseComponentGroupRefElement(child, ComplexReferenceParentType.Feature, id, null);
                                break;
                            case "ComponentRef":
                                this.ParseComponentRefElement(child, ComplexReferenceParentType.Feature, id, null);
                                break;
                            case "Component":
                                this.ParseComponentElement(child, ComplexReferenceParentType.Feature, id, null, CompilerCore.IntegerNotSet, null, null);
                                break;
                            case "Condition":
                                this.ParseConditionElement(child, node.LocalName, id, null);
                                break;
                            case "Feature":
                                this.ParseFeatureElement(child, ComplexReferenceParentType.Feature, id, ref childDisplay);
                                break;
                            case "FeatureGroupRef":
                                this.ParseFeatureGroupRefElement(child, ComplexReferenceParentType.Feature, id);
                                break;
                            case "FeatureRef":
                                this.ParseFeatureRefElement(child, ComplexReferenceParentType.Feature, id);
                                break;
                            case "MergeRef":
                                this.ParseMergeRefElement(child, ComplexReferenceParentType.Feature, id);
                                break;
                            default:
                                this.core.UnexpectedElement(node, child);
                                break;
                        }
                    }
                    else
                    {
                        this.core.ParseExtensionElement(sourceLineNumbers, (XmlElement)node, (XmlElement)child);
                    }
                }
            }

            if (!this.core.EncounteredError)
            {
                Row row = this.core.CreateRow(sourceLineNumbers, "Feature");
                row[0] = id;
                row[1] = null; // this column is set in the linker
                row[2] = title;
                row[3] = description;
                if (0 < display.Length)
                {
                    switch (display)
                    {
                        case "collapse":
                            lastDisplay = (lastDisplay | 1) + 1;
                            row[4] = lastDisplay;
                            break;
                        case "expand":
                            lastDisplay = (lastDisplay + 1) | 1;
                            row[4] = lastDisplay;
                            break;
                        case "hidden":
                            row[4] = 0;
                            break;
                        default:
                            int value;
                            if (!Int32.TryParse(display, NumberStyles.Integer, CultureInfo.InvariantCulture, out value))
                            {
                                this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name, "Display", display, "collapse", "expand", "hidden"));
                            }
                            else
                            {
                                row[4] = value;
                                // save the display value of this row (if its not hidden) for subsequent rows
                                if (0 != (int)row[4])
                                {
                                    lastDisplay = (int)row[4];
                                }
                            }
                            break;
                    }
                }
                row[5] = level;
                row[6] = configurableDirectory;
                row[7] = bits;

                if (ComplexReferenceParentType.Unknown != parentType)
                {
                    this.core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.Feature, id, false);
                }
            }
        }
Exemple #8
0
        /// <summary>
        /// Parses a PatchFamilyRef element.
        /// </summary>
        /// <param name="node">Element to parse.</param>
        /// <param name="parentType">The parent type.</param>
        /// <param name="parentId">The ID of the parent.</param>
        /// <returns>Id of the referenced element.</returns>
        private void ParsePatchFamilyRefElement(XmlNode node, ComplexReferenceParentType parentType, string parentId)
        {
            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string[] primaryKeys = new string[2];

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace)
                {
                    switch (attrib.LocalName)
                    {
                        case "Id":
                            primaryKeys[0] = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                            break;
                        case "ProductCode":
                            primaryKeys[1] = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                            break;
                        default:
                            this.core.UnexpectedAttribute(sourceLineNumbers, attrib);
                            break;
                    }
                }
                else
                {
                    this.core.ParseExtensionAttribute(sourceLineNumbers, (XmlElement)node, attrib);
                }
            }

            if (null == primaryKeys[0])
            {
                this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Id"));
            }

            this.core.CreateWixSimpleReferenceRow(sourceLineNumbers, "MsiPatchSequence", primaryKeys);

            foreach (XmlNode child in node.ChildNodes)
            {
                if (XmlNodeType.Element == child.NodeType)
                {
                    if (child.NamespaceURI == this.schema.TargetNamespace)
                    {
                        this.core.UnexpectedElement(node, child);
                    }
                    else
                    {
                        this.core.UnsupportedExtensionElement(node, child);
                    }
                }
            }

            if (!this.core.EncounteredError)
            {
                this.core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.PatchFamily, primaryKeys[0], true);
            }
        }
Exemple #9
0
 /// <summary>
 /// Creates a WiX complex reference in the active section.
 /// </summary>
 /// <param name="sourceLineNumbers">Source line information.</param>
 /// <param name="parentType">The parent type.</param>
 /// <param name="parentId">The parent id.</param>
 /// <param name="parentLanguage">The parent language.</param>
 /// <param name="childType">The child type.</param>
 /// <param name="childId">The child id.</param>
 /// <param name="isPrimary">Whether the child is primary.</param>
 internal void CreateWixComplexReferenceRow(SourceLineNumberCollection sourceLineNumbers, ComplexReferenceParentType parentType, string parentId, string parentLanguage, ComplexReferenceChildType childType, string childId, bool isPrimary)
 {
     if (!this.EncounteredError)
     {
         WixComplexReferenceRow wixComplexReferenceRow = (WixComplexReferenceRow)this.CreateRow(sourceLineNumbers, "WixComplexReference");
         wixComplexReferenceRow.ParentId = parentId;
         wixComplexReferenceRow.ParentType = parentType;
         wixComplexReferenceRow.ParentLanguage = parentLanguage;
         wixComplexReferenceRow.ChildId = childId;
         wixComplexReferenceRow.ChildType = childType;
         wixComplexReferenceRow.IsPrimary = isPrimary;
     }
 }
Exemple #10
0
 /// <summary>
 /// Parses a package group reference element.
 /// </summary>
 /// <param name="node">Element to parse.</param>
 /// <param name="parentType">ComplexReferenceParentType of parent element (Unknown or PackageGroup).</param>
 /// <param name="parentId">Identifier of parent element.</param>
 /// <returns>Identifier for package group element.</rereturns>
 private string ParsePackageGroupRefElement(XmlNode node, ComplexReferenceParentType parentType, string parentId)
 {
     return ParsePackageGroupRefElement(node, parentType, parentId, ComplexReferenceChildType.PackageGroup, null);
 }
Exemple #11
0
        /// <summary>
        /// Parse RollbackBoundary element
        /// </summary>
        /// <param name="node">Element to parse</param>
        /// <param name="parentType">Type of parent group, if known.</param>
        /// <param name="parentId">Identifier of parent group, if known.</param>
        /// <param name="previousType">Type of previous item, if known.</param>
        /// <param name="previousId">Identifier of previous item, if known</param>
        /// <returns>Identifier for package element.</returns>
        private string ParseRollbackBoundaryElement(XmlNode node, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType previousType, string previousId)
        {
            Debug.Assert(ComplexReferenceParentType.PackageGroup == parentType);
            Debug.Assert(ComplexReferenceChildType.Unknown == previousType || ComplexReferenceChildType.PackageGroup == previousType || ComplexReferenceChildType.Package == previousType);

            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string id = null;
            YesNoType vital = YesNoType.Yes;

            // This crazy list lets us evaluate extension attributes *after* all core attributes
            // have been parsed and dealt with, regardless of authoring order.
            List<KeyValuePair<SourceLineNumberCollection, XmlAttribute>> extensionAttributes =
                new List<KeyValuePair<SourceLineNumberCollection, XmlAttribute>>();

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace)
                {
                    bool allowed = true;
                    switch (attrib.LocalName)
                    {
                        case "Id":
                            id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                            break;
                        case "Vital":
                            vital = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                            break;
                        default:
                            allowed = false;
                            break;
                    }

                    if (!allowed)
                    {
                        this.core.UnexpectedAttribute(sourceLineNumbers, attrib);
                    }
                }
                else
                {
                    // Save the extension attributes for later...
                    extensionAttributes.Add(new KeyValuePair<SourceLineNumberCollection, XmlAttribute>(sourceLineNumbers, attrib));
                }
            }

            if (String.IsNullOrEmpty(id))
            {
                if (!String.IsNullOrEmpty(previousId))
                {
                    id = this.core.GenerateIdentifier("rba", previousId);
                }

                if (null == id)
                {
                    this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Id"));
                }
                else if (!CompilerCore.IsIdentifier(id))
                {
                    this.core.OnMessage(WixErrors.IllegalIdentifier(sourceLineNumbers, node.Name, "Id", id));
                }
            }

            // Now that the package ID is known, we can parse the extension attributes...
            Dictionary<string, string> contextValues = new Dictionary<string, string>();
            contextValues["RollbackBoundaryId"] = id;
            foreach (KeyValuePair<SourceLineNumberCollection, XmlAttribute> pair in extensionAttributes)
            {
                this.core.ParseExtensionAttribute(pair.Key, (XmlElement)node, pair.Value, contextValues);
            }

            foreach (XmlNode child in node.ChildNodes)
            {
                if (XmlNodeType.Element == child.NodeType)
                {
                    if (child.NamespaceURI == this.schema.TargetNamespace)
                    {
                        this.core.UnexpectedElement(node, child);
                    }
                    else
                    {
                        this.core.ParseExtensionElement(sourceLineNumbers, (XmlElement)node, (XmlElement)child, id);
                    }
                }
            }

            if (!this.core.EncounteredError)
            {
                Row row = this.core.CreateRow(sourceLineNumbers, "ChainPackage");
                row[0] = id;
                row[1] = ChainPackageType.RollbackBoundary.ToString();

                if (YesNoType.NotSet != vital)
                {
                    row[10] = (YesNoType.Yes == vital) ? 1 : 0;
                }

                this.CreateChainPackageMetaRows(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.Package, id, previousType, previousId, null);
            }

            return id;
        }
Exemple #12
0
        /// <summary>
        /// Creates group and ordering information.
        /// </summary>
        /// <param name="sourceLineNumbers">Source line numbers.</param>
        /// <param name="parentType">Type of parent group, if known.</param>
        /// <param name="parentId">Identifier of parent group, if known.</param>
        /// <param name="type">Type of this item.</param>
        /// <param name="id">Identifier for this item.</param>
        /// <param name="previousType">Type of previous item, if known.</param>
        /// <param name="previousId">Identifier of previous item, if known</param>
        private void CreateGroupAndOrderingRows(SourceLineNumberCollection sourceLineNumbers,
            ComplexReferenceParentType parentType, string parentId,
            ComplexReferenceChildType type, string id,
            ComplexReferenceChildType previousType, string previousId)
        {
            if (ComplexReferenceParentType.Unknown != parentType && null != parentId)
            {
                this.core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, type, id);
            }

            if (ComplexReferenceChildType.Unknown != previousType && null != previousId)
            {
                this.CreateWixOrderingRow(sourceLineNumbers, type, id, previousType, previousId);
            }
        }
Exemple #13
0
        /// <summary>
        /// Creates the row for a Payload.
        /// </summary>
        /// <param name="node">Element to parse</param>
        /// <param name="parentType">ComplexReferenceParentType of parent element</param>
        /// <param name="parentId">Identifier of parent element.</param>
        private void CreatePayloadRow(SourceLineNumberCollection sourceLineNumbers, string id, string name, string sourceFile, string downloadUrl, ComplexReferenceParentType parentType,
            string parentId, ComplexReferenceChildType previousType, string previousId, YesNoDefaultType compressed, YesNoType suppressSignatureVerification, string displayName, string description)
        {
            if (!this.core.EncounteredError)
            {
                Row row = this.core.CreateRow(sourceLineNumbers, "Payload");
                row[0] = id;
                row[1] = String.IsNullOrEmpty(name) ? Path.GetFileName(sourceFile) : name;
                row[2] = sourceFile;
                row[3] = downloadUrl;
                if (YesNoDefaultType.Default != compressed)
                {
                    row[4] = (YesNoDefaultType.Yes == compressed) ? 1 : 0;
                }
                row[5] = sourceFile; // duplicate of sourceFile but in a string column so it won't get resolved to a full path during binding.
                row[6] = (YesNoType.Yes == suppressSignatureVerification) ? 1 : 0;

                if (!String.IsNullOrEmpty(description) || !String.IsNullOrEmpty(displayName))
                {
                    Row rowDisplay = this.core.CreateRow(sourceLineNumbers, "PayloadDisplayInformation");
                    rowDisplay[0] = id;
                    rowDisplay[1] = displayName;
                    rowDisplay[2] = description;
                }

                this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.Payload, id, previousType, previousId);
            }
        }
        /// <summary>
        /// Creates a new complex reference.
        /// </summary>
        /// <param name="parentType">Parent type of complex reference.</param>
        /// <param name="parentId">Identifier for parent of complex reference.</param>
        /// <param name="parentLanguage">Language for parent of complex reference (only valid when parent is Module).</param>
        /// <param name="childType">Child type of complex reference.</param>
        /// <param name="childId">Identifier for child of complex reference.</param>
        /// <param name="primary">Flag if complex reference is the primary for advertised goop.</param>
        public ComplexReference(ComplexReferenceParentType parentType, string parentId, string parentLanguage, ComplexReferenceChildType childType, string childId, bool primary)
        {
            if (ComplexReferenceParentType.Module != this.parentType && null != this.parentLanguage)
            {
                throw new ArgumentException("ParentLanguage cannot be specified unless the parent is a Module.");
            }

            this.parentType = parentType;
            this.parentId = parentId;
            this.parentLanguage = parentLanguage;
            this.childType = childType;
            this.childId = childId;
            this.primary = primary;

            this.section = null;
        }
Exemple #15
0
        /// <summary>
        /// Parses a PatchFamilyGroup element.
        /// </summary>
        /// <param name="node">Element to parse.</param>
        /// <param name="parentType"></param>
        /// <param name="parentId"></param>
        private void ParsePatchFamilyGroupElement(XElement node, ComplexReferenceParentType parentType, string parentId)
        {
            var        sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            Identifier id = null;

            foreach (var attrib in node.Attributes())
            {
                if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
                {
                    switch (attrib.Name.LocalName)
                    {
                    case "Id":
                        id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
                        break;

                    default:
                        this.Core.UnexpectedAttribute(node, attrib);
                        break;
                    }
                }
                else
                {
                    this.Core.ParseExtensionAttribute(node, attrib);
                }
            }

            if (null == id)
            {
                this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
                id = Identifier.Invalid;
            }

            foreach (var child in node.Elements())
            {
                if (CompilerCore.WixNamespace == child.Name.Namespace)
                {
                    switch (child.Name.LocalName)
                    {
                    case "PatchFamily":
                        this.ParsePatchFamilyElement(child, ComplexReferenceParentType.PatchFamilyGroup, id.Id);
                        break;

                    case "PatchFamilyRef":
                        this.ParsePatchFamilyRefElement(child, ComplexReferenceParentType.PatchFamilyGroup, id.Id);
                        break;

                    case "PatchFamilyGroupRef":
                        this.ParsePatchFamilyGroupRefElement(child, ComplexReferenceParentType.PatchFamilyGroup, id.Id);
                        break;

                    default:
                        this.Core.UnexpectedElement(node, child);
                        break;
                    }
                }
                else
                {
                    this.Core.ParseExtensionElement(node, child);
                }
            }

            if (!this.Core.EncounteredError)
            {
                this.Core.AddSymbol(new WixPatchFamilyGroupSymbol(sourceLineNumbers, id));

                //Add this PatchFamilyGroup and its parent in WixGroup.
                this.Core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.PatchFamilyGroup, id.Id);
            }
        }
Exemple #16
0
        /// <summary>
        /// Parses a PatchFamily element.
        /// </summary>
        /// <param name="node">The element to parse.</param>
        /// <param name="parentType"></param>
        /// <param name="parentId"></param>
        private void ParsePatchFamilyElement(XElement node, ComplexReferenceParentType parentType, string parentId)
        {
            var        sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            Identifier id          = null;
            string     productCode = null;
            string     version     = null;
            var        attributes  = 0;

            foreach (var attrib in node.Attributes())
            {
                if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
                {
                    switch (attrib.Name.LocalName)
                    {
                    case "Id":
                        id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
                        break;

                    case "ProductCode":
                        productCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
                        break;

                    case "Version":
                        version = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
                        break;

                    case "Supersede":
                        if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
                        {
                            attributes |= 0x1;
                        }
                        break;

                    default:
                        this.Core.UnexpectedAttribute(node, attrib);
                        break;
                    }
                }
                else
                {
                    this.Core.ParseExtensionAttribute(node, attrib);
                }
            }

            if (null == id)
            {
                this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
                id = Identifier.Invalid;
            }

            if (String.IsNullOrEmpty(version))
            {
                this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version"));
            }
            else if (!CompilerCore.IsValidProductVersion(version))
            {
                this.Core.Write(ErrorMessages.InvalidProductVersion(sourceLineNumbers, version));
            }

            // find unexpected child elements
            foreach (var child in node.Elements())
            {
                if (CompilerCore.WixNamespace == child.Name.Namespace)
                {
                    switch (child.Name.LocalName)
                    {
                    case "All":
                        this.ParseAllElement(child);
                        break;

                    case "BinaryRef":
                        this.ParsePatchChildRefElement(child, "Binary");
                        break;

                    case "ComponentRef":
                        this.ParsePatchChildRefElement(child, "Component");
                        break;

                    case "CustomActionRef":
                        this.ParsePatchChildRefElement(child, "CustomAction");
                        break;

                    case "DirectoryRef":
                        this.ParsePatchChildRefElement(child, "Directory");
                        break;

                    case "DigitalCertificateRef":
                        this.ParsePatchChildRefElement(child, "MsiDigitalCertificate");
                        break;

                    case "FeatureRef":
                        this.ParsePatchChildRefElement(child, "Feature");
                        break;

                    case "IconRef":
                        this.ParsePatchChildRefElement(child, "Icon");
                        break;

                    case "PropertyRef":
                        this.ParsePatchChildRefElement(child, "Property");
                        break;

                    case "SoftwareTagRef":
                        this.ParseTagRefElement(child);
                        break;

                    case "UIRef":
                        this.ParsePatchChildRefElement(child, "WixUI");
                        break;

                    default:
                        this.Core.UnexpectedElement(node, child);
                        break;
                    }
                }
                else
                {
                    this.Core.ParseExtensionElement(node, child);
                }
            }


            if (!this.Core.EncounteredError)
            {
                this.Core.AddSymbol(new MsiPatchSequenceSymbol(sourceLineNumbers)
                {
                    PatchFamily = id.Id,
                    ProductCode = productCode,
                    Sequence    = version,
                    Attributes  = attributes
                });

                if (ComplexReferenceParentType.Unknown != parentType)
                {
                    this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.PatchFamily, id.Id, ComplexReferenceParentType.Patch == parentType);
                }
            }
        }
        /// <summary>
        /// Changes all of the parent references to point to the passed in parent reference.
        /// </summary>
        /// <param name="parent">New parent complex reference.</param>
        internal void Reparent(WixComplexReferenceRow parent)
        {
            this.ParentId = parent.ParentId;
            this.ParentLanguage = parent.ParentLanguage;
            this.ParentType = parent.ParentType;

            if (!this.IsPrimary)
            {
                this.IsPrimary = parent.IsPrimary;
            }
        }
Exemple #18
0
        /// <summary>
        /// A row in the WixGroup table is added for this child node and its parent node.
        /// </summary>
        /// <param name="sourceLineNumbers">Source line information for the row.</param>
        /// <param name="parentType">Type of child's complex reference parent.</param>
        /// <param name="parentId">Id of the parenet node.</param>
        /// <param name="childType">Complex reference type of child</param>
        /// <param name="childId">Id of the Child Node.</param>
        public void CreateWixGroupRow(SourceLineNumberCollection sourceLineNumbers, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType childType, string childId)
        {
            if (!this.EncounteredError)
            {
                if (null == parentId || ComplexReferenceParentType.Unknown == parentType)
                {
                    return;
                }

                if (null == childId)
                {
                    throw new ArgumentNullException("childId");
                }

                Row WixGroupRow = this.CreateRow(sourceLineNumbers, "WixGroup");
                WixGroupRow[0] = parentId;
                WixGroupRow[1] = Enum.GetName(typeof(ComplexReferenceParentType), parentType);
                WixGroupRow[2] = childId;
                WixGroupRow[3] = Enum.GetName(typeof(ComplexReferenceChildType), childType);
           }
        }
Exemple #19
0
 /// <summary>
 /// Creates WixComplexReference and WixGroup rows in the active section.
 /// </summary>
 /// <param name="sourceLineNumbers">Source line information.</param>
 /// <param name="parentType">The parent type.</param>
 /// <param name="parentId">The parent id.</param>
 /// <param name="parentLanguage">The parent language.</param>
 /// <param name="childType">The child type.</param>
 /// <param name="childId">The child id.</param>
 /// <param name="isPrimary">Whether the child is primary.</param>
 public void CreateComplexReference(SourceLineNumberCollection sourceLineNumbers, ComplexReferenceParentType parentType, string parentId, string parentLanguage, ComplexReferenceChildType childType, string childId, bool isPrimary)
 {
     this.CreateWixComplexReferenceRow(sourceLineNumbers, parentType, parentId, parentLanguage, childType, childId, isPrimary);
     this.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, childType, childId);
 }
Exemple #20
0
        /// <summary>
        /// Parse the attributes of the Payload element.
        /// </summary>
        /// <param name="node">Element to parse</param>
        /// <param name="parentType">ComplexReferenceParentType of parent element.</param>
        /// <param name="parentId">Identifier of parent element.</param>
        private string ParsePayloadElementContent(XmlNode node, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType previousType, string previousId, bool required)
        {
            Debug.Assert(ComplexReferenceParentType.PayloadGroup == parentType || ComplexReferenceParentType.Package == parentType || ComplexReferenceParentType.Container == parentType);

            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            YesNoDefaultType compressed = YesNoDefaultType.Default;
            YesNoType suppressSignatureVerification = YesNoType.NotSet;
            string id = null;
            string name = null;
            string sourceFile = null;
            string downloadUrl = null;
            PayloadInfoRow remotePayload = null;

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace)
                {
                    switch (attrib.LocalName)
                    {
                        case "Id":
                            id = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            break;
                        case "Compressed":
                            compressed = this.core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib);
                            break;
                        case "Name":
                            name = this.core.GetAttributeLongFilename(sourceLineNumbers, attrib, false, true);
                            break;
                        case "SourceFile":
                            sourceFile = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            break;
                        case "DownloadUrl":
                            downloadUrl = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            break;
                        case "SuppressSignatureVerification":
                            suppressSignatureVerification = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                            break;
                        default:
                            this.core.UnexpectedAttribute(sourceLineNumbers, attrib);
                            break;
                    }
                }
                else
                {
                    this.core.UnsupportedExtensionAttribute(sourceLineNumbers, attrib);
                }
            }

            if (!required && null == sourceFile)
            {
                // Nothing left to do!
                return null;
            }

            foreach (XmlNode child in node.ChildNodes)
            {
                // We only handle the elements we care about.  Let caller handle other children.
                if ((XmlNodeType.Element == child.NodeType) && (child.NamespaceURI == this.schema.TargetNamespace) && (child.LocalName == "RemotePayload"))
                {
                    SourceLineNumberCollection childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child);

                    if (node.NamespaceURI == this.schema.TargetNamespace && node.LocalName != "ExePackage")
                    {
                        this.core.OnMessage(WixErrors.RemotePayloadUnsupported(childSourceLineNumbers));
                        continue;
                    }

                    if (null != remotePayload)
                    {
                        this.core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name, child.LocalName));
                    }

                    remotePayload = this.ParseRemotePayloadElement(child, id);
                }
            }

            if (null != sourceFile && null != remotePayload)
            {
                this.core.OnMessage(WixErrors.UnexpectedElementWithAttribute(sourceLineNumbers, node.Name, "RemotePayload", "SourceFile"));
            }
            else if (null == sourceFile && null == remotePayload)
            {
                this.core.OnMessage(WixErrors.ExpectedAttributeOrElement(sourceLineNumbers, node.Name, "SourceFile", "RemotePayload"));
            }
            else if (null == sourceFile)
            {
                sourceFile = String.Empty;
            }

            if (null == downloadUrl && null != remotePayload)
            {
                this.core.OnMessage(WixErrors.ExpectedAttributeWithElement(sourceLineNumbers, node.Name, "DownloadUrl", "RemotePayload"));
            }

            if (Compiler.BurnUXContainerId == parentId)
            {
                if (compressed == YesNoDefaultType.No)
                {
                    core.OnMessage(WixWarnings.UxPayloadsOnlySupportEmbedding(sourceLineNumbers, sourceFile));
                }

                compressed = YesNoDefaultType.Yes;
            }

            if (String.IsNullOrEmpty(id))
            {
                id = this.core.GenerateIdentifier("pay", (null != sourceFile) ? sourceFile.ToUpperInvariant() : String.Empty);
            }

            if (null != remotePayload)
            {
                remotePayload.Id = id;
            }

            this.CreatePayloadRow(sourceLineNumbers, id, name, sourceFile, downloadUrl, parentType, parentId, previousType, previousId, compressed, suppressSignatureVerification, null, null);

            return id;
        }
Exemple #21
0
 private string CombineTypeAndId(ComplexReferenceParentType type, string id)
 {
     return String.Format("{0}:{1}", type.ToString(), id);
 }
Exemple #22
0
        /// <summary>
        /// Parse PayloadGroup element.
        /// </summary>
        /// <param name="node">Element to parse</param>
        /// <param name="parentType">Optional ComplexReferenceParentType of parent element. (typically another PayloadGroup)</param>
        /// <param name="parentId">Identifier of parent element.</param>
        private void ParsePayloadGroupElement(XmlNode node, ComplexReferenceParentType parentType, string parentId)
        {
            Debug.Assert(ComplexReferenceParentType.Unknown == parentType || ComplexReferenceParentType.Layout == parentType || ComplexReferenceParentType.PayloadGroup == parentType);

            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string id = null;

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace)
                {
                    switch (attrib.LocalName)
                    {
                        case "Id":
                            id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                            break;
                        default:
                            this.core.UnexpectedAttribute(sourceLineNumbers, attrib);
                            break;
                    }
                }
                else
                {
                    this.core.UnsupportedExtensionAttribute(sourceLineNumbers, attrib);
                }
            }

            if (null == id)
            {
                this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Id"));
            }

            ComplexReferenceChildType previousType = ComplexReferenceChildType.Unknown;
            string previousId = null;
            foreach (XmlNode child in node.ChildNodes)
            {
                if (XmlNodeType.Element == child.NodeType)
                {
                    if (child.NamespaceURI == this.schema.TargetNamespace)
                    {
                        switch (child.LocalName)
                        {
                            case "Payload":
                                previousId = this.ParsePayloadElement(child, ComplexReferenceParentType.PayloadGroup, id, previousType, previousId);
                                previousType = ComplexReferenceChildType.Payload;
                                break;
                            case "PayloadGroupRef":
                                previousId = this.ParsePayloadGroupRefElement(child, ComplexReferenceParentType.PayloadGroup, id, previousType, previousId);
                                previousType = ComplexReferenceChildType.PayloadGroup;
                                break;
                            default:
                                this.core.UnexpectedElement(node, child);
                                break;
                        }
                    }
                    else
                    {
                        this.core.UnsupportedExtensionElement(node, child);
                    }
                }
            }

            if (!this.core.EncounteredError)
            {
                Row row = this.core.CreateRow(sourceLineNumbers, "PayloadGroup");
                row[0] = id;

                this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.PayloadGroup, id, ComplexReferenceChildType.Unknown, null);
            }
        }
Exemple #23
0
        public void CreateWixGroupRow(IntermediateSection section, SourceLineNumber sourceLineNumbers, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType childType, string childId)
        {
            if (null == parentId || ComplexReferenceParentType.Unknown == parentType)
            {
                return;
            }

            if (null == childId)
            {
                throw new ArgumentNullException("childId");
            }

            var row = (WixGroupTuple)this.CreateRow(section, sourceLineNumbers, TupleDefinitionType.WixGroup);

            row.ParentId   = parentId;
            row.ParentType = parentType;
            row.ChildId    = childId;
            row.ChildType  = childType;
        }
Exemple #24
0
 /// <summary>
 /// Parse ExePackage element
 /// </summary>
 /// <param name="node">Element to parse</param>
 /// <param name="parentType">Type of parent group, if known.</param>
 /// <param name="parentId">Identifier of parent group, if known.</param>
 /// <param name="previousType">Type of previous item, if known.</param>
 /// <param name="previousId">Identifier of previous item, if known</param>
 /// <returns>Identifier for package element.</returns>
 private string ParseExePackageElement(XmlNode node, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType previousType, string previousId)
 {
     return ParseChainPackage(node, ChainPackageType.Exe, parentType, parentId, previousType, previousId);
 }
Exemple #25
0
        public void CreateComplexReference(IntermediateSection section, SourceLineNumber sourceLineNumbers, ComplexReferenceParentType parentType, string parentId, string parentLanguage, ComplexReferenceChildType childType, string childId, bool isPrimary)
        {
            var wixComplexReferenceRow = (WixComplexReferenceTuple)this.CreateRow(section, sourceLineNumbers, TupleDefinitionType.WixComplexReference);

            wixComplexReferenceRow.Parent         = parentId;
            wixComplexReferenceRow.ParentType     = parentType;
            wixComplexReferenceRow.ParentLanguage = parentLanguage;
            wixComplexReferenceRow.Child          = childId;
            wixComplexReferenceRow.ChildType      = childType;
            wixComplexReferenceRow.IsPrimary      = isPrimary;

            this.CreateWixGroupRow(section, sourceLineNumbers, parentType, parentId, childType, childId);
        }
Exemple #26
0
        /// <summary>
        /// Parses one of the ChainPackage elements
        /// </summary>
        /// <param name="node">Element to parse</param>
        /// <param name="packageType">Type of package to parse</param>
        /// <param name="parentType">Type of parent group, if known.</param>
        /// <param name="parentId">Identifier of parent group, if known.</param>
        /// <param name="previousType">Type of previous item, if known.</param>
        /// <param name="previousId">Identifier of previous item, if known</param>
        /// <returns>Identifier for package element.</returns>
        /// <remarks>This method contains the shared logic for parsing all of the ChainPackage
        /// types, as there is more in common between them than different.</remarks>
        private string ParseChainPackage(XmlNode node, ChainPackageType packageType, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType previousType, string previousId)
        {
            Debug.Assert(ComplexReferenceParentType.PackageGroup == parentType);
            Debug.Assert(ComplexReferenceChildType.Unknown == previousType || ComplexReferenceChildType.PackageGroup == previousType || ComplexReferenceChildType.Package == previousType);

            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string name = null;
            string sourceFile = null;
            string downloadUrl = null;
            string id = null;
            string after = null;
            string installCondition = null;
            YesNoType cache = YesNoType.NotSet;
            string cacheId = null;
            string description = null;
            string displayName = null;
            string logPathVariable = (packageType == ChainPackageType.Msu) ? String.Empty : null;
            string rollbackPathVariable = (packageType == ChainPackageType.Msu) ? String.Empty : null;
            YesNoType permanent = YesNoType.NotSet;
            YesNoType visible = YesNoType.NotSet;
            YesNoType vital = YesNoType.Yes;
            string installCommand = null;
            string repairCommand = null;
            YesNoType repairable = YesNoType.NotSet;
            string uninstallCommand = null;
            YesNoDefaultType perMachine = YesNoDefaultType.NotSet;
            string detectCondition = null;
            string protocol = null;
            int installSize = CompilerCore.IntegerNotSet;
            string msuKB = null;
            YesNoType suppressLooseFilePayloadGeneration = YesNoType.NotSet;
            YesNoType suppressSignatureVerification = YesNoType.NotSet;
            YesNoDefaultType compressed = YesNoDefaultType.Default;
            YesNoType displayInternalUI = YesNoType.NotSet;
            YesNoType enableFeatureSelection = YesNoType.NotSet;
            YesNoType forcePerMachine = YesNoType.NotSet;
            BundlePackageAttributes attributes = BundlePackageAttributes.None;
            PayloadInfoRow remotePayload = null;
            YesNoType slipstream = YesNoType.NotSet;

            string[] expectedNetFx4Args = new string[] { "/q", "/norestart", "/chainingpackage" };

            // This crazy list lets us evaluate extension attributes *after* all core attributes
            // have been parsed and dealt with, regardless of authoring order.
            List<KeyValuePair<SourceLineNumberCollection, XmlAttribute>> extensionAttributes =
                new List<KeyValuePair<SourceLineNumberCollection, XmlAttribute>>();

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace)
                {
                    bool allowed = true;
                    switch (attrib.LocalName)
                    {
                        case "Name":
                            name = this.core.GetAttributeLongFilename(sourceLineNumbers, attrib, false, true);
                            if (!CompilerCore.IsValidLongFilename(name, false, true))
                            {
                                this.core.OnMessage(WixErrors.IllegalLongFilename(sourceLineNumbers, node.Name, "Name", name));
                            }
                            break;
                        case "SourceFile":
                            sourceFile = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            break;
                        case "DownloadUrl":
                            downloadUrl = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            break;
                        case "Id":
                            id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                            break;
                        case "After":
                            after = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            break;
                        case "InstallCondition":
                            installCondition = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            break;
                        case "Cache":
                            cache = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                            break;
                        case "CacheId":
                            cacheId = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            break;
                        case "Description":
                            description = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            break;
                        case "DisplayName":
                            displayName = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            break;
                        case "DisplayInternalUI":
                            displayInternalUI = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                            allowed = (packageType == ChainPackageType.Msi || packageType == ChainPackageType.Msp);
                            break;
                        case "EnableFeatureSelection":
                            enableFeatureSelection = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                            allowed = (packageType == ChainPackageType.Msi);
                            break;
                        case "ForcePerMachine":
                            forcePerMachine = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                            allowed = (packageType == ChainPackageType.Msi);
                            break;
                        case "LogPathVariable":
                            logPathVariable = this.core.GetAttributeValue(sourceLineNumbers, attrib, true);
                            break;
                        case "RollbackLogPathVariable":
                            rollbackPathVariable = this.core.GetAttributeValue(sourceLineNumbers, attrib, true);
                            break;
                        case "Permanent":
                            permanent = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                            break;
                        case "Visible":
                            visible = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                            allowed = (packageType == ChainPackageType.Msi);
                            break;
                        case "Vital":
                            vital = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                            break;
                        case "InstallCommand":
                            installCommand = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            allowed = (packageType == ChainPackageType.Exe);
                            break;
                        case "RepairCommand":
                            repairCommand = this.core.GetAttributeValue(sourceLineNumbers, attrib, true);
                            repairable = YesNoType.Yes;
                            allowed = (packageType == ChainPackageType.Exe);
                            break;
                        case "UninstallCommand":
                            uninstallCommand = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            allowed = (packageType == ChainPackageType.Exe);
                            break;
                        case "PerMachine":
                            perMachine = this.core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib);
                            allowed = (packageType == ChainPackageType.Exe || packageType == ChainPackageType.Msp);
                            break;
                        case "DetectCondition":
                            detectCondition = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            allowed = (packageType == ChainPackageType.Exe || packageType == ChainPackageType.Msu);
                            break;
                        case "Protocol":
                            protocol = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            allowed = (packageType == ChainPackageType.Exe);
                            break;
                        case "InstallSize":
                            installSize = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
                            break;
                        case "KB":
                            msuKB = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            allowed = (packageType == ChainPackageType.Msu);
                            break;
                        case "Compressed":
                            compressed = this.core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib);
                            break;
                        case "SuppressLooseFilePayloadGeneration":
                            this.core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name, attrib.Name));
                            suppressLooseFilePayloadGeneration = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                            allowed = (packageType == ChainPackageType.Msi);
                            break;
                        case "SuppressSignatureVerification":
                            suppressSignatureVerification = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                            break;
                        case "Slipstream":
                            slipstream = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                            allowed = (packageType == ChainPackageType.Msp);
                            break;
                        default:
                            allowed = false;
                            break;
                    }

                    if (!allowed)
                    {
                        this.core.UnexpectedAttribute(sourceLineNumbers, attrib);
                    }
                }
                else
                {
                    // Save the extension attributes for later...
                    extensionAttributes.Add(new KeyValuePair<SourceLineNumberCollection, XmlAttribute>(sourceLineNumbers, attrib));
                }
            }

            foreach (XmlNode child in node.ChildNodes)
            {
                // We need to handle RemotePayload up front because it effects value of sourceFile which is used in Id generation.  Id is needed by other child elements.
                if ((XmlNodeType.Element == child.NodeType) && (child.NamespaceURI == this.schema.TargetNamespace) && (child.LocalName == "RemotePayload"))
                {
                    SourceLineNumberCollection childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child);

                    if (node.NamespaceURI == this.schema.TargetNamespace && node.LocalName != "ExePackage")
                    {
                        this.core.OnMessage(WixErrors.RemotePayloadUnsupported(childSourceLineNumbers));
                        continue;
                    }

                    if (null != remotePayload)
                    {
                        this.core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name, child.LocalName));
                    }

                    remotePayload = this.ParseRemotePayloadElement(child, id);
                }
            }

            if (String.IsNullOrEmpty(sourceFile))
            {
                if (String.IsNullOrEmpty(name))
                {
                    this.core.OnMessage(WixErrors.ExpectedAttributesWithOtherAttribute(sourceLineNumbers, node.Name, "Name", "SourceFile"));
                }
                else if (null == remotePayload)
                {
                    sourceFile = Path.Combine("SourceDir", name);
                }
                else
                {
                    sourceFile = String.Empty;  // SourceFile is required it cannot be null.
                }
            }
            else if (null != remotePayload)
            {
                this.core.OnMessage(WixErrors.UnexpectedElementWithAttribute(sourceLineNumbers, node.Name, "RemotePayload", "SourceFile"));
            }
            else if (sourceFile.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
            {
                if (String.IsNullOrEmpty(name))
                {
                    this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Name", "SourceFile", sourceFile));
                }
                else
                {
                    sourceFile = Path.Combine(sourceFile, Path.GetFileName(name));
                }
            }

            if (null == downloadUrl && null != remotePayload)
            {
                this.core.OnMessage(WixErrors.ExpectedAttributeWithElement(sourceLineNumbers, node.Name, "DownloadUrl", "RemotePayload"));
            }

            if (String.IsNullOrEmpty(id))
            {
                if (!String.IsNullOrEmpty(name))
                {
                    id = CompilerCore.GetIdentifierFromName(Path.GetFileName(name));
                }
                else if (!String.IsNullOrEmpty(sourceFile))
                {
                    id = CompilerCore.GetIdentifierFromName(Path.GetFileName(sourceFile));
                }

                if (null == id)
                {
                    this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Id"));
                }
                else if (!CompilerCore.IsIdentifier(id))
                {
                    this.core.OnMessage(WixErrors.IllegalIdentifier(sourceLineNumbers, node.Name, "Id", id));
                }
            }

            if (null != remotePayload)
            {
                remotePayload.Id = id;
            }

            if (null == logPathVariable)
            {
                logPathVariable = String.Concat("WixBundleLog_", id);
            }

            if (null == rollbackPathVariable)
            {
                rollbackPathVariable = String.Concat("WixBundleRollbackLog_", id);
            }

            if (!String.IsNullOrEmpty(protocol) && !protocol.Equals("burn", StringComparison.Ordinal) && !protocol.Equals("netfx4", StringComparison.Ordinal) && !protocol.Equals("none", StringComparison.Ordinal))
            {
                this.core.OnMessage(WixErrors.IllegalAttributeValueWithLegalList(sourceLineNumbers, node.Name, "Protocol", protocol, "none, burn, netfx4"));
            }

            if (!String.IsNullOrEmpty(protocol) && protocol.Equals("netfx4", StringComparison.Ordinal))
            {
                foreach (string expectedArgument in expectedNetFx4Args)
                {
                    if (null == installCommand || -1 == installCommand.IndexOf(expectedArgument, StringComparison.OrdinalIgnoreCase))
                    {
                        this.core.OnMessage(WixWarnings.AttributeShouldContain(sourceLineNumbers, node.Name, "InstallCommand", installCommand, expectedArgument, "Protocol", "netfx4"));
                    }

                    if (null == repairCommand || -1 == repairCommand.IndexOf(expectedArgument, StringComparison.OrdinalIgnoreCase))
                    {
                        this.core.OnMessage(WixWarnings.AttributeShouldContain(sourceLineNumbers, node.Name, "RepairCommand", repairCommand, expectedArgument, "Protocol", "netfx4"));
                    }

                    if (null == uninstallCommand || -1 == uninstallCommand.IndexOf(expectedArgument, StringComparison.OrdinalIgnoreCase))
                    {
                        this.core.OnMessage(WixWarnings.AttributeShouldContain(sourceLineNumbers, node.Name, "UninstallCommand", uninstallCommand, expectedArgument, "Protocol", "netfx4"));
                    }
                }
            }

            // Only set default scope for EXEs and MSPs if not already set.
            if ((ChainPackageType.Exe == packageType || ChainPackageType.Msp == packageType) && YesNoDefaultType.NotSet == perMachine)
            {
                perMachine = YesNoDefaultType.Default;
            }

            // Now that the package ID is known, we can parse the extension attributes...
            Dictionary<string, string> contextValues = new Dictionary<string, string>();
            contextValues["PackageId"] = id;
            foreach (KeyValuePair<SourceLineNumberCollection, XmlAttribute> pair in extensionAttributes)
            {
                this.core.ParseExtensionAttribute(pair.Key, (XmlElement)node, pair.Value, contextValues);
            }

            foreach (XmlNode child in node.ChildNodes)
            {
                if (XmlNodeType.Element == child.NodeType)
                {
                    if (child.NamespaceURI == this.schema.TargetNamespace)
                    {
                        bool allowed = true;
                        switch (child.LocalName)
                        {
                            case "SlipstreamMsp":
                                allowed = (packageType == ChainPackageType.Msi);
                                if (allowed)
                                {
                                    this.ParseSlipstreamMspElement(child, id);
                                }
                                break;
                            case "MsiProperty":
                                allowed = (packageType == ChainPackageType.Msi || packageType == ChainPackageType.Msp);
                                if (allowed)
                                {
                                    this.ParseMsiPropertyElement(child, id);
                                }
                                break;
                            case "Payload":
                                this.ParsePayloadElement(child, ComplexReferenceParentType.Package, id, ComplexReferenceChildType.Unknown, null);
                                break;
                            case "PayloadGroupRef":
                                this.ParsePayloadGroupRefElement(child, ComplexReferenceParentType.Package, id, ComplexReferenceChildType.Unknown, null);
                                break;
                            case "ExitCode":
                                allowed = (packageType == ChainPackageType.Exe);
                                if (allowed)
                                {
                                    this.ParseExitCodeElement(child, id);
                                }
                                break;
                            case "RemotePayload":
                                // Handled previously
                                break;
                            default:
                                allowed = false;
                                break;
                        }

                        if (!allowed)
                        {
                            this.core.UnexpectedElement(node, child);
                        }
                    }
                    else
                    {
                        this.core.ParseExtensionElement(sourceLineNumbers, (XmlElement)node, (XmlElement)child, id);
                    }
                }
            }

            if (!this.core.EncounteredError)
            {
                if (YesNoType.Yes == permanent)
                {
                    attributes |= BundlePackageAttributes.Permanent;
                }

                if (YesNoType.Yes == visible)
                {
                    attributes |= BundlePackageAttributes.Visible;
                }

                if (YesNoType.Yes == slipstream)
                {
                    attributes |= BundlePackageAttributes.Slipstream;
                }

                // We create the package contents as a payload with this package as the parent
                this.CreatePayloadRow(sourceLineNumbers, id, name, sourceFile, downloadUrl, ComplexReferenceParentType.Package, id,
                    ComplexReferenceChildType.Unknown, null, compressed, suppressSignatureVerification, displayName, description);

                Row row = this.core.CreateRow(sourceLineNumbers, "ChainPackage");
                row[0] = id;
                row[1] = packageType.ToString();
                row[2] = id;
                row[3] = installCondition;
                row[4] = installCommand;
                row[5] = repairCommand;
                row[6] = uninstallCommand;

                if (YesNoType.NotSet != cache)
                {
                    row[7] = (YesNoType.Yes == cache) ? 1 : 0;
                }

                row[8] = cacheId;

                row[9] = (int)attributes;

                if (YesNoType.NotSet != vital)
                {
                    row[10] = (YesNoType.Yes == vital) ? 1 : 0;
                }

                switch (perMachine)
                {
                    case YesNoDefaultType.No:
                        row[11] = 0;
                        break;
                    case YesNoDefaultType.Yes:
                        row[11] = 1;
                        break;
                    case YesNoDefaultType.Default:
                        row[11] = 2;
                        break;
                }

                row[12] = detectCondition;
                row[13] = msuKB;

                if (YesNoType.NotSet != repairable)
                {
                    row[14] = (YesNoType.Yes == repairable) ? 1 : 0;
                }

                row[15] = logPathVariable;
                row[16] = rollbackPathVariable;
                row[17] = protocol;
                row[18] = installSize;
                if (YesNoType.NotSet != suppressLooseFilePayloadGeneration)
                {
                    row[19] = (YesNoType.Yes == suppressLooseFilePayloadGeneration) ? 1 : 0;
                }

                if (YesNoType.NotSet != enableFeatureSelection)
                {
                    row[20] = (YesNoType.Yes == enableFeatureSelection) ? 1 : 0;
                }

                if (YesNoType.NotSet != forcePerMachine)
                {
                    row[21] = (YesNoType.Yes == forcePerMachine) ? 1 : 0;
                }

                if (YesNoType.NotSet != displayInternalUI)
                {
                    row[22] = (YesNoType.Yes == displayInternalUI) ? 1 : 0;
                }

                this.CreateChainPackageMetaRows(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.Package, id, previousType, previousId, after);
            }
            return id;
        }
Exemple #27
0
        /// <summary>
        /// Creates group and ordering information for packages
        /// </summary>
        /// <param name="sourceLineNumbers">Source line numbers.</param>
        /// <param name="parentType">Type of parent group, if known.</param>
        /// <param name="parentId">Identifier of parent group, if known.</param>
        /// <param name="type">Type of this item.</param>
        /// <param name="id">Identifier for this item.</param>
        /// <param name="previousType">Type of previous item, if known.</param>
        /// <param name="previousId">Identifier of previous item, if known</param>
        /// <param name="afterId">Identifier of explicit 'After' attribute, if given.</param>
        private void CreateChainPackageMetaRows(SourceLineNumberCollection sourceLineNumbers,
            ComplexReferenceParentType parentType, string parentId,
            ComplexReferenceChildType type, string id,
            ComplexReferenceChildType previousType, string previousId, string afterId)
        {
            // If there's an explicit 'After' attribute, it overrides the inferred previous item.
            if (null != afterId)
            {
                previousType = ComplexReferenceChildType.Package;
                previousId = afterId;
            }

            this.CreateGroupAndOrderingRows(sourceLineNumbers, parentType, parentId, type, id, previousType, previousId);
        }
Exemple #28
0
        /// <summary>
        /// Parses a package group reference element.
        /// </summary>
        /// <param name="node">Element to parse.</param>
        /// <param name="parentType">ComplexReferenceParentType of parent element (Unknown or PackageGroup).</param>
        /// <param name="parentId">Identifier of parent element.</param>
        /// <param name="parentType">ComplexReferenceParentType of previous element (Unknown, Package, or PackageGroup).</param>
        /// <param name="parentId">Identifier of parent element.</param>
        /// <returns>Identifier for package group element.</rereturns>
        private string ParsePackageGroupRefElement(XmlNode node, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType previousType, string previousId)
        {
            Debug.Assert(ComplexReferenceParentType.Unknown == parentType || ComplexReferenceParentType.PackageGroup == parentType || ComplexReferenceParentType.Container == parentType);
            Debug.Assert(ComplexReferenceChildType.Unknown == previousType || ComplexReferenceChildType.PackageGroup == previousType || ComplexReferenceChildType.Package == previousType);

            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string id = null;
            string after = null;

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace)
                {
                    switch (attrib.LocalName)
                    {
                        case "Id":
                            id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                            this.core.CreateWixSimpleReferenceRow(sourceLineNumbers, "ChainPackageGroup", id);
                            break;
                        case "After":
                            after = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            break;
                        default:
                            this.core.UnexpectedAttribute(sourceLineNumbers, attrib);
                            break;
                    }
                }
                else
                {
                    this.core.UnsupportedExtensionAttribute(sourceLineNumbers, attrib);
                }
            }

            if (null == id)
            {
                this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Id"));
            }

            if (null != after && ComplexReferenceParentType.Container == parentType)
            {
                this.core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name, "After", parentId));
            }

            foreach (XmlNode child in node.ChildNodes)
            {
                if (XmlNodeType.Element == child.NodeType)
                {
                    if (child.NamespaceURI == this.schema.TargetNamespace)
                    {
                        this.core.UnexpectedElement(node, child);
                    }
                    else
                    {
                        this.core.UnsupportedExtensionElement(node, child);
                    }
                }
            }

            if (ComplexReferenceParentType.Container == parentType)
            {
                this.core.CreateWixGroupRow(sourceLineNumbers, ComplexReferenceParentType.Container, parentId, ComplexReferenceChildType.PackageGroup, id);
            }
            else
            {
                this.CreateChainPackageMetaRows(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.PackageGroup, id, previousType, previousId, after);
            }

            return id;
        }
Exemple #29
0
        private void ParseComponentGroupElement(XmlNode node, ComplexReferenceParentType parentType, string parentId)
        {
            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string id = null;
            string directoryId = null;
            string source = null;

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace)
                {
                    switch (attrib.LocalName)
                    {
                        case "Id":
                            id = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            if (!CompilerCore.IsIdentifier(id))
                            {
                                this.core.OnMessage(WixWarnings.DeprecatedComponentGroupId(sourceLineNumbers, node.LocalName));
                            }

                            break;
                        case "Directory":
                            directoryId = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                            this.core.CreateWixSimpleReferenceRow(sourceLineNumbers, "Directory", directoryId);
                            break;
                        case "Source":
                            source = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            break;
                        default:
                            this.core.UnexpectedAttribute(sourceLineNumbers, attrib);
                            break;
                    }
                }
                else
                {
                    this.core.ParseExtensionAttribute(sourceLineNumbers, (XmlElement)node, attrib);
                }
            }

            if (null == id)
            {
                this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Id"));
            }

            if (!String.IsNullOrEmpty(source) && !source.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
            {
                source = String.Concat(source, Path.DirectorySeparatorChar);
            }

            foreach (XmlNode child in node.ChildNodes)
            {
                if (XmlNodeType.Element == child.NodeType)
                {
                    if (child.NamespaceURI == this.schema.TargetNamespace)
                    {
                        switch (child.LocalName)
                        {
                            case "ComponentGroupRef":
                                this.ParseComponentGroupRefElement(child, ComplexReferenceParentType.ComponentGroup, id, null);
                                break;
                            case "ComponentRef":
                                this.ParseComponentRefElement(child, ComplexReferenceParentType.ComponentGroup, id, null);
                                break;
                            case "Component":
                                this.ParseComponentElement(child, ComplexReferenceParentType.ComponentGroup, id, null, CompilerCore.IntegerNotSet, directoryId, source);
                                break;
                            default:
                                this.core.UnexpectedElement(node, child);
                                break;
                        }
                    }
                    else
                    {
                        this.core.ParseExtensionElement(sourceLineNumbers, (XmlElement)node, (XmlElement)child);
                    }
                }
            }

            if (!this.core.EncounteredError)
            {
                Row row = this.core.CreateRow(sourceLineNumbers, "WixComponentGroup");
                row[0] = id;

                //Add this componentGroup and its parent in WixGroup.
                this.core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.ComponentGroup, id);
            }
        }
Exemple #30
0
        private string ParseComponentElement(XmlNode node, ComplexReferenceParentType parentType, string parentId, string parentLanguage, int diskId, string directoryId, string srcPath)
        {
            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);

            int bits = 0;
            int comPlusBits = CompilerCore.IntegerNotSet;
            string condition = null;
            bool encounteredODBCDataSource = false;
            bool explicitWin64 = false;
            int files = 0;
            string guid = "*";
            string autoId = Compiler.DefaultComponentIdPlaceholder; // placeholder id for defaulting Component/@Id to keypath id.
            string id = Compiler.DefaultComponentIdPlaceholderWixVariable;
            int keyBits = 0;
            bool keyFound = false;
            string keyPath = null;
            bool shouldAddCreateFolder = false;
            bool win64 = false;
            bool multiInstance = false;
            string symbols = null;
            string feature = null;

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace)
                {
                    switch (attrib.LocalName)
                    {
                        case "Id":
                            id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                            break;
                        case "ComPlusFlags":
                            comPlusBits = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
                            break;
                        case "DisableRegistryReflection":
                            if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
                            {
                                bits |= MsiInterop.MsidbComponentAttributesDisableRegistryReflection;
                            }
                            break;
                        case "Directory":
                            if (null != directoryId)
                            {
                                this.core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name, attrib.Name, "Directory"));
                            }
                            directoryId = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                            this.core.CreateWixSimpleReferenceRow(sourceLineNumbers, "Directory", directoryId);
                            break;
                        case "DiskId":
                            diskId = this.core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue);
                            break;
                        case "Feature":
                            feature = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                            break;
                        case "Guid":
                            guid = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, true, true);
                            break;
                        case "KeyPath":
                            if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
                            {
                                keyFound = true;
                                keyPath = null;
                                keyBits = 0;
                                shouldAddCreateFolder = true;
                            }
                            break;
                        case "Location":
                            string location = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            if (0 < location.Length)
                            {
                                Wix.Component.LocationType locationType = Wix.Component.ParseLocationType(location);
                                switch (locationType)
                                {
                                    case Wix.Component.LocationType.either:
                                        bits |= MsiInterop.MsidbComponentAttributesOptional;
                                        break;
                                    case Wix.Component.LocationType.local: // this is the default
                                        break;
                                    case Wix.Component.LocationType.source:
                                        bits |= MsiInterop.MsidbComponentAttributesSourceOnly;
                                        break;
                                    default:
                                        this.core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.Name, attrib.Name, "either", "local", "source"));
                                        break;
                                }
                            }
                            break;
                        case "MultiInstance":
                            multiInstance = YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                            break;
                        case "NeverOverwrite":
                            if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
                            {
                                bits |= MsiInterop.MsidbComponentAttributesNeverOverwrite;
                            }
                            break;
                        case "Permanent":
                            if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
                            {
                                bits |= MsiInterop.MsidbComponentAttributesPermanent;
                            }
                            break;
                        case "Shared":
                            if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
                            {
                                bits |= MsiInterop.MsidbComponentAttributesShared;
                            }
                            break;
                        case "SharedDllRefCount":
                            if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
                            {
                                bits |= MsiInterop.MsidbComponentAttributesSharedDllRefCount;
                            }
                            break;
                        case "Transitive":
                            if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
                            {
                                bits |= MsiInterop.MsidbComponentAttributesTransitive;
                            }
                            break;
                        case "UninstallWhenSuperseded":
                            if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
                            {
                                bits |= MsiInterop.MsidbComponentAttributesUninstallOnSupersedence;
                            }
                            break;
                        case "Win64":
                            explicitWin64 = true;
                            if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
                            {
                                bits |= MsiInterop.MsidbComponentAttributes64bit;
                                win64 = true;
                            }
                            break;
                        default:
                            this.core.UnexpectedAttribute(sourceLineNumbers, attrib);
                            break;
                    }
                }
                else
                {
                    this.core.ParseExtensionAttribute(sourceLineNumbers, (XmlElement)node, attrib);
                }
            }

            if (!explicitWin64 && (Platform.IA64 == CurrentPlatform || Platform.X64 == CurrentPlatform))
            {
                bits |= MsiInterop.MsidbComponentAttributes64bit;
                win64 = true;
            }

            if (null == directoryId)
            {
                this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Directory"));
            }

            if (String.IsNullOrEmpty(guid) && MsiInterop.MsidbComponentAttributesShared == (bits & MsiInterop.MsidbComponentAttributesShared))
            {
                this.core.OnMessage(WixErrors.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name, "Shared", "yes", "Guid", ""));
            }

            if (String.IsNullOrEmpty(guid) && MsiInterop.MsidbComponentAttributesPermanent == (bits & MsiInterop.MsidbComponentAttributesPermanent))
            {
                this.core.OnMessage(WixErrors.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name, "Permanent", "yes", "Guid", ""));
            }

            if (null != feature)
            {
                if (this.compilingModule)
                {
                    this.core.OnMessage(WixErrors.IllegalAttributeInMergeModule(sourceLineNumbers, node.Name, "Feature"));
                }
                else
                {
                    if (ComplexReferenceParentType.Feature == parentType || ComplexReferenceParentType.FeatureGroup == parentType)
                    {
                        this.core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name, "Feature", node.ParentNode.LocalName));
                    }
                    else
                    {
                        this.core.CreateComplexReference(sourceLineNumbers, ComplexReferenceParentType.Feature, feature, null, ComplexReferenceChildType.Component, id, true);
                    }
                }
            }

            foreach (XmlNode child in node.ChildNodes)
            {
                if (XmlNodeType.Element == child.NodeType)
                {
                    YesNoType keyPathSet = YesNoType.NotSet;
                    string keyPossible = null;
                    int keyBit = 0;

                    if (child.NamespaceURI == this.schema.TargetNamespace)
                    {
                        switch (child.LocalName)
                        {
                            case "AppId":
                                this.ParseAppIdElement(child, id, YesNoType.NotSet, null, null, null);
                                break;
                            case "Category":
                                this.ParseCategoryElement(child, id);
                                break;
                            case "Class":
                                this.ParseClassElement(child, id, YesNoType.NotSet, null, null, null, null);
                                break;
                            case "Condition":
                                if (null != condition)
                                {
                                    SourceLineNumberCollection childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
                                    this.core.OnMessage(WixErrors.TooManyChildren(childSourceLineNumbers, node.Name, child.Name));
                                }
                                condition = this.ParseConditionElement(child, node.LocalName, null, null);
                                break;
                            case "CopyFile":
                                this.ParseCopyFileElement(child, id, null);
                                break;
                            case "CreateFolder":
                                string createdFolder = this.ParseCreateFolderElement(child, id, directoryId, win64);
                                if (directoryId == createdFolder)
                                {
                                    shouldAddCreateFolder = false;
                                }
                                break;
                            case "Environment":
                                this.ParseEnvironmentElement(child, id);
                                break;
                            case "Extension":
                                this.ParseExtensionElement(child, id, YesNoType.NotSet, null);
                                break;
                            case "File":
                                keyPathSet = this.ParseFileElement(child, id, directoryId, diskId, srcPath, out keyPossible, win64, guid);
                                if (null != keyPossible)
                                {
                                    keyBit = 0;
                                }
                                files++;
                                break;
                            case "IniFile":
                                this.ParseIniFileElement(child, id);
                                break;
                            case "Interface":
                                this.ParseInterfaceElement(child, id, null, null, null, null);
                                break;
                            case "IsolateComponent":
                                this.ParseIsolateComponentElement(child, id);
                                break;
                            case "ODBCDataSource":
                                keyPathSet = this.ParseODBCDataSource(child, id, null, out keyPossible);
                                keyBit = MsiInterop.MsidbComponentAttributesODBCDataSource;
                                encounteredODBCDataSource = true;
                                break;
                            case "ODBCDriver":
                                this.ParseODBCDriverOrTranslator(child, id, null, this.tableDefinitions["ODBCDriver"]);
                                break;
                            case "ODBCTranslator":
                                this.ParseODBCDriverOrTranslator(child, id, null, this.tableDefinitions["ODBCTranslator"]);
                                break;
                            case "ProgId":
                                bool foundExtension = false;
                                this.ParseProgIdElement(child, id, YesNoType.NotSet, null, null, null, ref foundExtension, YesNoType.NotSet);
                                break;
                            case "Registry":
                                keyPathSet = this.ParseRegistryElement(child, id, CompilerCore.IntegerNotSet, null, win64, out keyPossible);
                                keyBit = MsiInterop.MsidbComponentAttributesRegistryKeyPath;
                                break;
                            case "RegistryKey":
                                keyPathSet = this.ParseRegistryKeyElement(child, id, CompilerCore.IntegerNotSet, null, win64, out keyPossible);
                                keyBit = MsiInterop.MsidbComponentAttributesRegistryKeyPath;
                                break;
                            case "RegistryValue":
                                keyPathSet = this.ParseRegistryValueElement(child, id, CompilerCore.IntegerNotSet, null, win64, out keyPossible);
                                keyBit = MsiInterop.MsidbComponentAttributesRegistryKeyPath;
                                break;
                            case "RemoveFile":
                                this.ParseRemoveFileElement(child, id, directoryId);
                                break;
                            case "RemoveFolder":
                                this.ParseRemoveFolderElement(child, id, directoryId);
                                break;
                            case "RemoveRegistryKey":
                                this.ParseRemoveRegistryKeyElement(child, id);
                                break;
                            case "RemoveRegistryValue":
                                this.ParseRemoveRegistryValueElement(child, id);
                                break;
                            case "ReserveCost":
                                this.ParseReserveCostElement(child, id, directoryId);
                                break;
                            case "ServiceConfig":
                                this.ParseServiceConfigElement(child, id, null);
                                break;
                            case "ServiceConfigFailureActions":
                                this.ParseServiceConfigFailureActionsElement(child, id, null);
                                break;
                            case "ServiceControl":
                                this.ParseServiceControlElement(child, id);
                                break;
                            case "ServiceInstall":
                                this.ParseServiceInstallElement(child, id, win64);
                                break;
                            case "Shortcut":
                                this.ParseShortcutElement(child, id, node.LocalName, directoryId, YesNoType.No);
                                break;
                            case "SymbolPath":
                                if (null != symbols)
                                {
                                    symbols += ";" + this.ParseSymbolPathElement(child);
                                }
                                else
                                {
                                    symbols = this.ParseSymbolPathElement(child);
                                }
                                break;
                            case "TypeLib":
                                this.ParseTypeLibElement(child, id, null, win64);
                                break;
                            default:
                                this.core.UnexpectedElement(node, child);
                                break;
                        }
                    }
                    else
                    {
                        CompilerExtension.ComponentKeypathType keyType = this.core.ParseExtensionElement(sourceLineNumbers, (XmlElement)node, (XmlElement)child, ref keyPossible, id, directoryId, win64.ToString());

                        // CompilerExtension must return a key path type, so the component key path is either set or not (no automatic selection).
                        keyPathSet = CompilerExtension.ComponentKeypathType.None != keyType ? YesNoType.Yes : YesNoType.No;

                        if (CompilerExtension.ComponentKeypathType.Registry == keyType || CompilerExtension.ComponentKeypathType.RegistryFormatted == keyType)
                        {
                            keyBit = MsiInterop.MsidbComponentAttributesRegistryKeyPath;
                        }
                    }

                    // Verify that either the key path is not set, or it is set along with a key path ID.
                    Debug.Assert(YesNoType.Yes != keyPathSet || (YesNoType.Yes == keyPathSet && null != keyPossible));

                    if (keyFound && YesNoType.Yes == keyPathSet)
                    {
                        this.core.OnMessage(WixErrors.ComponentMultipleKeyPaths(sourceLineNumbers, node.Name, "KeyPath", "yes", "File", "RegistryValue", "ODBCDataSource"));
                    }

                    // if a possible KeyPath has been found and that value was explicitly set as
                    // the KeyPath of the component, set it now.  Alternatively, if a possible
                    // KeyPath has been found and no KeyPath has been previously set, use this
                    // value as the default KeyPath of the component
                    if (null != keyPossible && (YesNoType.Yes == keyPathSet || (YesNoType.NotSet == keyPathSet && null == keyPath && !keyFound)))
                    {
                        keyFound = YesNoType.Yes == keyPathSet;
                        keyPath = keyPossible;
                        keyBits = keyBit;
                    }
                }
            }

            if (shouldAddCreateFolder)
            {
                Row row = this.core.CreateRow(sourceLineNumbers, "CreateFolder");
                row[0] = directoryId;
                row[1] = id;
            }

            // check for conditions that exclude this component from using generated guids
            bool isGeneratableGuidOk = "*" == guid;
            if (isGeneratableGuidOk)
            {
                if (encounteredODBCDataSource)
                {
                    this.core.OnMessage(WixErrors.IllegalComponentWithAutoGeneratedGuid(sourceLineNumbers));
                    isGeneratableGuidOk = false;
                }

                if (0 != files && MsiInterop.MsidbComponentAttributesRegistryKeyPath == keyBits)
                {
                    this.core.OnMessage(WixErrors.IllegalComponentWithAutoGeneratedGuid(sourceLineNumbers, true));
                    isGeneratableGuidOk = false;
                }
            }

            // check for implicit KeyPath which can easily be accidentally changed
            if (this.showPedanticMessages && !keyFound && !isGeneratableGuidOk)
            {
                this.core.OnMessage(WixErrors.ImplicitComponentKeyPath(sourceLineNumbers, id));
            }

            // if there isn't an @Id attribute value, replace the placeholder with the id of the keypath.
            // either an explicit KeyPath="yes" attribute must be specified or requirements for 
            // generatable guid must be met.
            if (Compiler.DefaultComponentIdPlaceholderWixVariable == id)
            {
                if (isGeneratableGuidOk || keyFound && !String.IsNullOrEmpty(keyPath))
                {
                    id = keyPath;
                    WixVariableResolver resolver = new WixVariableResolver();
                    resolver.AddVariable(autoId, keyPath);
                    foreach (Table table in this.core.ActiveSection.Tables)
                    {
                        foreach (Row row in table.Rows)
                        {
                            foreach (Field field in row.Fields)
                            {
                                if (field.Data is string)
                                {
                                    bool isDefault = false;
                                    bool delayedResolve = false;
                                    field.Data = resolver.ResolveVariables(row.SourceLineNumbers, (string)field.Data, false, false, ref isDefault, ref delayedResolve);
                                }
                            }
                        }
                    }
                }
                else
                {
                    this.core.OnMessage(WixErrors.CannotDefaultComponentId(sourceLineNumbers));
                }
            }

            // If an id was not determined by now, we have to error.
            if (null == id)
            {
                this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Id"));
            }

            // finally add the Component table row
            if (!this.core.EncounteredError)
            {
                Row row = this.core.CreateRow(sourceLineNumbers, "Component");
                row[0] = id;
                row[1] = guid;
                row[2] = directoryId;
                row[3] = bits | keyBits;
                row[4] = condition;
                row[5] = keyPath;

                if (multiInstance)
                {
                    Row instanceComponentRow = this.core.CreateRow(sourceLineNumbers, "WixInstanceComponent");
                    instanceComponentRow[0] = id;
                }

                if (null != symbols)
                {
                    Row symbolRow = this.core.CreateRow(sourceLineNumbers, "WixPatchSymbolPaths");
                    symbolRow[0] = "Component";
                    symbolRow[1] = id;
                    symbolRow[2] = symbols;
                }

                // Complus
                if (CompilerCore.IntegerNotSet != comPlusBits)
                {
                    row = this.core.CreateRow(sourceLineNumbers, "Complus");
                    row[0] = id;
                    row[1] = comPlusBits;
                }

                // if this is a module, automatically add this component to the references to ensure it gets in the ModuleComponents table
                if (this.compilingModule)
                {
                    this.core.CreateComplexReference(sourceLineNumbers, ComplexReferenceParentType.Module, this.activeName, this.activeLanguage, ComplexReferenceChildType.Component, id, false);
                }
                else if (ComplexReferenceParentType.Unknown != parentType && null != parentId) // if parent was provided, add a complex reference to that.
                {
                    // If the Component is defined directly under a feature, then mark the complex reference primary.
                    this.core.CreateComplexReference(sourceLineNumbers, parentType, parentId, parentLanguage, ComplexReferenceChildType.Component, id, ComplexReferenceParentType.Feature == parentType);
                }
            }

            return id;
        }
        /// <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));
        }
Exemple #32
0
        /// <summary>
        /// Parses a component group reference element.
        /// </summary>
        /// <param name="node">Element to parse.</param>
        /// <param name="parentType">ComplexReferenceParentType of parent element.</param>
        /// <param name="parentId">Identifier of parent element (usually a Feature or Module).</param>
        /// <param name="parentLanguage">Optional language of parent (only useful for Modules).</param>
        private void ParseComponentGroupRefElement(XmlNode node, ComplexReferenceParentType parentType, string parentId, string parentLanguage)
        {
            Debug.Assert(ComplexReferenceParentType.ComponentGroup == parentType || ComplexReferenceParentType.FeatureGroup == parentType || ComplexReferenceParentType.Feature == parentType || ComplexReferenceParentType.Module == parentType);

            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string id = null;
            YesNoType primary = YesNoType.NotSet;

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace)
                {
                    switch (attrib.LocalName)
                    {
                        case "Id":
                            id = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            if (!CompilerCore.IsIdentifier(id))
                            {
                                this.core.OnMessage(WixWarnings.DeprecatedComponentGroupId(sourceLineNumbers, node.LocalName));
                            }

                            this.core.CreateWixSimpleReferenceRow(sourceLineNumbers, "WixComponentGroup", id);
                            break;
                        case "Primary":
                            primary = this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                            break;
                        default:
                            this.core.UnexpectedAttribute(sourceLineNumbers, attrib);
                            break;
                    }
                }
                else
                {
                    this.core.ParseExtensionAttribute(sourceLineNumbers, (XmlElement)node, attrib);
                }
            }

            if (null == id)
            {
                this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Id"));
            }

            foreach (XmlNode child in node.ChildNodes)
            {
                if (XmlNodeType.Element == child.NodeType)
                {
                    if (child.NamespaceURI == this.schema.TargetNamespace)
                    {
                        this.core.UnexpectedElement(node, child);
                    }
                    else
                    {
                        this.core.UnsupportedExtensionElement(node, child);
                    }
                }
            }

            this.core.CreateComplexReference(sourceLineNumbers, parentType, parentId, parentLanguage, ComplexReferenceChildType.ComponentGroup, id, (YesNoType.Yes == primary));
        }
Exemple #33
0
        public void CreateWixGroupSymbol(IntermediateSection section, SourceLineNumber sourceLineNumbers, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType childType, string childId)
        {
            if (null == parentId || ComplexReferenceParentType.Unknown == parentType)
            {
                return;
            }

            if (null == childId)
            {
                throw new ArgumentNullException(nameof(childId));
            }

            section.AddSymbol(new WixGroupSymbol(sourceLineNumbers)
            {
                ParentId   = parentId,
                ParentType = parentType,
                ChildId    = childId,
                ChildType  = childType,
            });
        }
Exemple #34
0
        /// <summary>
        /// Parses a PatchFamilyGroup reference element.
        /// </summary>
        /// <param name="node">Element to parse.</param>
        /// <param name="parentType">The type of parent.</param>
        /// <param name="parentId">Identifier of parent element.</param>
        private void ParsePatchFamilyGroupRefElement(XmlNode node, ComplexReferenceParentType parentType, string parentId)
        {
            Debug.Assert(ComplexReferenceParentType.PatchFamilyGroup == parentType || ComplexReferenceParentType.Patch == parentType);

            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string id = null;

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace)
                {
                    switch (attrib.LocalName)
                    {
                        case "Id":
                            id = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            this.core.CreateWixSimpleReferenceRow(sourceLineNumbers, "WixPatchFamilyGroup", id);
                            break;
                        default:
                            this.core.UnexpectedAttribute(sourceLineNumbers, attrib);
                            break;
                    }
                }
                else
                {
                    this.core.ParseExtensionAttribute(sourceLineNumbers, (XmlElement)node, attrib);
                }
            }

            if (null == id)
            {
                this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Id"));
            }

            foreach (XmlNode child in node.ChildNodes)
            {
                if (XmlNodeType.Element == child.NodeType)
                {
                    if (child.NamespaceURI == this.schema.TargetNamespace)
                    {
                        this.core.UnexpectedElement(node, child);
                    }
                    else
                    {
                        this.core.UnsupportedExtensionElement(node, child);
                    }
                }
            }

            if (!this.core.EncounteredError)
            {
                this.core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.PatchFamilyGroup, id, true);
            }
        }
Exemple #35
0
        public void CreateComplexReference(IntermediateSection section, SourceLineNumber sourceLineNumbers, ComplexReferenceParentType parentType, string parentId, string parentLanguage, ComplexReferenceChildType childType, string childId, bool isPrimary)
        {
            section.AddSymbol(new WixComplexReferenceSymbol(sourceLineNumbers)
            {
                Parent         = parentId,
                ParentType     = parentType,
                ParentLanguage = parentLanguage,
                Child          = childId,
                ChildType      = childType,
                IsPrimary      = isPrimary
            });

            this.CreateWixGroupSymbol(section, sourceLineNumbers, parentType, parentId, childType, childId);
        }
Exemple #36
0
        private void ParseFeatureGroupElement(XmlNode node, ComplexReferenceParentType parentType, string parentId)
        {
            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string id = null;

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace)
                {
                    switch (attrib.LocalName)
                    {
                        case "Id":
                            id = this.core.GetAttributeValue(sourceLineNumbers, attrib);
                            break;
                        default:
                            this.core.UnexpectedAttribute(sourceLineNumbers, attrib);
                            break;
                    }
                }
                else
                {
                    this.core.ParseExtensionAttribute(sourceLineNumbers, (XmlElement)node, attrib);
                }
            }

            if (null == id)
            {
                this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Id"));
            }

            int lastDisplay = 0;
            foreach (XmlNode child in node.ChildNodes)
            {
                if (XmlNodeType.Element == child.NodeType)
                {
                    if (child.NamespaceURI == this.schema.TargetNamespace)
                    {
                        switch (child.LocalName)
                        {
                            case "ComponentGroupRef":
                                this.ParseComponentGroupRefElement(child, ComplexReferenceParentType.FeatureGroup, id, null);
                                break;
                            case "ComponentRef":
                                this.ParseComponentRefElement(child, ComplexReferenceParentType.FeatureGroup, id, null);
                                break;
                            case "Component":
                                this.ParseComponentElement(child, ComplexReferenceParentType.FeatureGroup, id, null, CompilerCore.IntegerNotSet, null, null);
                                break;
                            case "Feature":
                                this.ParseFeatureElement(child, ComplexReferenceParentType.FeatureGroup, id, ref lastDisplay);
                                break;
                            case "FeatureGroupRef":
                                this.ParseFeatureGroupRefElement(child, ComplexReferenceParentType.FeatureGroup, id);
                                break;
                            case "FeatureRef":
                                this.ParseFeatureRefElement(child, ComplexReferenceParentType.FeatureGroup, id);
                                break;
                            case "MergeRef":
                                this.ParseMergeRefElement(child, ComplexReferenceParentType.FeatureGroup, id);
                                break;
                            default:
                                this.core.UnexpectedElement(node, child);
                                break;
                        }
                    }
                    else
                    {
                        this.core.ParseExtensionElement(sourceLineNumbers, (XmlElement)node, (XmlElement)child);
                    }
                }
            }

            if (!this.core.EncounteredError)
            {
                Row row = this.core.CreateRow(sourceLineNumbers, "WixFeatureGroup");
                row[0] = id;

                //Add this FeatureGroup and its parent in WixGroup.
                this.core.CreateWixGroupRow(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.FeatureGroup, id);
            }
        }
Exemple #37
0
        /// <summary>
        /// Parses a PatchFamily element.
        /// </summary>
        /// <param name="node">The element to parse.</param>
        private void ParsePatchFamilyElement(XmlNode node, ComplexReferenceParentType parentType, string parentId)
        {
            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string id = null;
            string productCode = null;
            string version = null;
            int attributes = 0;

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace)
                {
                    switch (attrib.LocalName)
                    {
                        case "Id":
                            id = this.core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                            break;
                        case "ProductCode":
                            productCode = this.core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
                            break;
                        case "Version":
                            version = this.core.GetAttributeVersionValue(sourceLineNumbers, attrib, false);
                            break;
                        case "Supersede":
                            if (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
                            {
                                attributes |= 0x1;
                            }
                            break;
                        default:
                            this.core.UnexpectedAttribute(sourceLineNumbers, attrib);
                            break;
                    }
                }
                else
                {
                    this.core.UnsupportedExtensionAttribute(sourceLineNumbers, attrib);
                }
            }

            if (null == id)
            {
                this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Id"));
            }

            if (String.IsNullOrEmpty(version))
            {
                this.core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Version"));
            }
            else if (!CompilerCore.IsValidProductVersion(version))
            {
                this.core.OnMessage(WixErrors.InvalidProductVersion(sourceLineNumbers, version));
            }

            // find unexpected child elements
            foreach (XmlNode child in node.ChildNodes)
            {
                if (XmlNodeType.Element == child.NodeType)
                {
                    if (child.NamespaceURI == this.schema.TargetNamespace)
                    {
                        switch (child.LocalName)
                        {
                            case "BinaryRef":
                                this.ParsePatchChildRefElement(child, "Binary");
                                break;
                            case "ComponentRef":
                                this.ParsePatchChildRefElement(child, "Component");
                                break;
                            case "CustomActionRef":
                                this.ParsePatchChildRefElement(child, "CustomAction");
                                break;
                            case "DirectoryRef":
                                this.ParsePatchChildRefElement(child, "Directory");
                                break;
                            case "DigitalCertificateRef":
                                this.ParsePatchChildRefElement(child, "MsiDigitalCertificate");
                                break;
                            case "FeatureRef":
                                this.ParsePatchChildRefElement(child, "Feature");
                                break;
                            case "IconRef":
                                this.ParsePatchChildRefElement(child, "Icon");
                                break;
                            case "PropertyRef":
                                this.ParsePatchChildRefElement(child, "Property");
                                break;
                            case "UIRef":
                                this.ParsePatchChildRefElement(child, "WixUI");
                                break;
                            default:
                                this.core.UnexpectedElement(node, child);
                                break;
                        }
                    }
                    else
                    {
                        this.core.ParseExtensionElement(sourceLineNumbers, (XmlElement)node, (XmlElement)child);
                    }
                }
            }

            if (!this.core.EncounteredError)
            {
                Row row = this.core.CreateRow(sourceLineNumbers, "MsiPatchSequence");
                row[0] = id;
                row[1] = productCode;
                row[2] = version;
                row[3] = attributes;

                if (ComplexReferenceParentType.Unknown != parentType)
                {
                    this.core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.PatchFamily, id, ComplexReferenceParentType.Patch == parentType);
                }
            }
        }
Exemple #38
0
        /// <summary>
        /// Parse Payload element.
        /// </summary>
        /// <param name="node">Element to parse</param>
        /// <param name="parentType">ComplexReferenceParentType of parent element. (BA or PayloadGroup)</param>
        /// <param name="parentId">Identifier of parent element.</param>
        private string ParsePayloadElement(XmlNode node, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType previousType, string previousId)
        {
            Debug.Assert(ComplexReferenceParentType.PayloadGroup == parentType || ComplexReferenceParentType.Package == parentType || ComplexReferenceParentType.Container == parentType);
            Debug.Assert(ComplexReferenceChildType.Unknown == previousType || ComplexReferenceChildType.PayloadGroup == previousType || ComplexReferenceChildType.Payload == previousType);

            string id = ParsePayloadElementContent(node, parentType, parentId, previousType, previousId, true);

            foreach (XmlNode child in node.ChildNodes)
            {
                if (XmlNodeType.Element == child.NodeType)
                {
                    if (child.NamespaceURI == this.schema.TargetNamespace)
                    {
                        switch (child.LocalName)
                        {
                            default:
                                this.core.UnexpectedElement(node, child);
                                break;
                        }
                    }
                    else
                    {
                        this.core.UnsupportedExtensionElement(node, child);
                    }
                }
            }

            return id;
        }
Exemple #39
0
 public void CreateWixGroupRow(IntermediateSection section, SourceLineNumber sourceLineNumbers, ComplexReferenceParentType parentType, string parentId, ComplexReferenceChildType childType, string childId)
 {
     this.CreateWixGroupSymbol(section, sourceLineNumbers, parentType, parentId, childType, childId);
 }