/// <summary> /// Parses an patch element. /// </summary> /// <param name="node">The element to parse.</param> private void ParsePatchElement(XElement node) { var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); string patchId = null; var codepage = 0; ////bool versionMismatches = false; ////bool productMismatches = false; var allowRemoval = false; string classification = null; string clientPatchId = null; string description = null; string displayName = null; string comments = null; string manufacturer = null; var minorUpdateTargetRTM = YesNoType.NotSet; string moreInfoUrl = null; var optimizeCA = CompilerConstants.IntegerNotSet; var optimizedInstallMode = YesNoType.NotSet; string targetProductName = null; // string replaceGuids = String.Empty; var apiPatchingSymbolFlags = 0; var optimizePatchSizeForLargeFiles = false; foreach (var attrib in node.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace) { switch (attrib.Name.LocalName) { case "Id": patchId = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, true); break; case "Codepage": codepage = this.Core.GetAttributeCodePageValue(sourceLineNumbers, attrib); break; case "AllowMajorVersionMismatches": ////versionMismatches = (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)); break; case "AllowProductCodeMismatches": ////productMismatches = (YesNoType.Yes == this.core.GetAttributeYesNoValue(sourceLineNumbers, attrib)); break; case "AllowRemoval": allowRemoval = (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)); break; case "Classification": classification = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "ClientPatchId": clientPatchId = 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 "Comments": comments = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "Manufacturer": manufacturer = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "MinorUpdateTargetRTM": minorUpdateTargetRTM = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); break; case "MoreInfoURL": moreInfoUrl = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "OptimizedInstallMode": optimizedInstallMode = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); break; case "TargetProductName": targetProductName = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "ApiPatchingSymbolNoImagehlpFlag": apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_NO_IMAGEHLP : 0; break; case "ApiPatchingSymbolNoFailuresFlag": apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_NO_FAILURES : 0; break; case "ApiPatchingSymbolUndecoratedTooFlag": apiPatchingSymbolFlags |= (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) ? (int)PatchSymbolFlagsType.PATCH_SYMBOL_UNDECORATED_TOO : 0; break; case "OptimizePatchSizeForLargeFiles": optimizePatchSizeForLargeFiles = (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)); break; default: this.Core.UnexpectedAttribute(node, attrib); break; } } else { this.Core.ParseExtensionAttribute(node, attrib); } } if (patchId == null || patchId == "*") { // auto-generate at compile time, since this value gets dispersed to several locations patchId = Common.GenerateGuid(); } this.activeName = patchId; if (null == this.activeName) { this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); } if (null == classification) { this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Classification")); } if (null == clientPatchId) { clientPatchId = String.Concat("_", new Guid(patchId).ToString("N", CultureInfo.InvariantCulture).ToUpper(CultureInfo.InvariantCulture)); } if (null == description) { this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Description")); } if (null == displayName) { this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DisplayName")); } if (null == manufacturer) { this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Manufacturer")); } this.Core.CreateActiveSection(this.activeName, SectionType.Patch, codepage, this.Context.CompilationId); foreach (var child in node.Elements()) { if (CompilerCore.WixNamespace == child.Name.Namespace) { switch (child.Name.LocalName) { case "PatchInformation": this.ParsePatchInformationElement(child); break; case "Media": this.ParseMediaElement(child, patchId); break; case "OptimizeCustomActions": optimizeCA = this.ParseOptimizeCustomActionsElement(child); break; case "PatchFamily": this.ParsePatchFamilyElement(child, ComplexReferenceParentType.Patch, patchId); break; case "PatchFamilyRef": this.ParsePatchFamilyRefElement(child, ComplexReferenceParentType.Patch, patchId); break; case "PatchFamilyGroup": this.ParsePatchFamilyGroupElement(child, ComplexReferenceParentType.Patch, patchId); break; case "PatchFamilyGroupRef": this.ParsePatchFamilyGroupRefElement(child, ComplexReferenceParentType.Patch, patchId); break; case "PatchProperty": this.ParsePatchPropertyElement(child, true); break; case "TargetProductCodes": this.ParseTargetProductCodesElement(child); break; default: this.Core.UnexpectedElement(node, child); break; } } else { this.Core.ParseExtensionElement(node, child); } } if (!this.Core.EncounteredError) { this.Core.AddSymbol(new WixPatchIdSymbol(sourceLineNumbers, new Identifier(AccessModifier.Global, patchId)) { ClientPatchId = clientPatchId, OptimizePatchSizeForLargeFiles = optimizePatchSizeForLargeFiles, ApiPatchingSymbolFlags = apiPatchingSymbolFlags, }); if (allowRemoval) { this.AddMsiPatchMetadata(sourceLineNumbers, null, "AllowRemoval", allowRemoval ? "1" : "0"); } if (null != classification) { this.AddMsiPatchMetadata(sourceLineNumbers, null, "Classification", classification); } // always generate the CreationTimeUTC { this.AddMsiPatchMetadata(sourceLineNumbers, null, "CreationTimeUTC", DateTime.UtcNow.ToString("MM-dd-yy HH:mm", CultureInfo.InvariantCulture)); } if (null != description) { this.AddMsiPatchMetadata(sourceLineNumbers, null, "Description", description); } if (null != displayName) { this.AddMsiPatchMetadata(sourceLineNumbers, null, "DisplayName", displayName); } if (null != manufacturer) { this.AddMsiPatchMetadata(sourceLineNumbers, null, "ManufacturerName", manufacturer); } if (YesNoType.NotSet != minorUpdateTargetRTM) { this.AddMsiPatchMetadata(sourceLineNumbers, null, "MinorUpdateTargetRTM", YesNoType.Yes == minorUpdateTargetRTM ? "1" : "0"); } if (null != moreInfoUrl) { this.AddMsiPatchMetadata(sourceLineNumbers, null, "MoreInfoURL", moreInfoUrl); } if (CompilerConstants.IntegerNotSet != optimizeCA) { this.AddMsiPatchMetadata(sourceLineNumbers, null, "OptimizeCA", optimizeCA.ToString(CultureInfo.InvariantCulture)); } if (YesNoType.NotSet != optimizedInstallMode) { this.AddMsiPatchMetadata(sourceLineNumbers, null, "OptimizedInstallMode", YesNoType.Yes == optimizedInstallMode ? "1" : "0"); } if (null != targetProductName) { this.AddMsiPatchMetadata(sourceLineNumbers, null, "TargetProductName", targetProductName); } if (null != comments) { this.AddMsiPatchMetadata(sourceLineNumbers, null, "Comments", comments); } } // TODO: do something with versionMismatches and productMismatches }