/// <summary> /// Processes an XmlReader and builds up the output object. /// </summary> /// <param name="reader">Reader to get data from.</param> /// <param name="suppressVersionCheck">Suppresses wix.dll version mismatch check.</param> /// <returns>The Output represented by the Xml.</returns> internal static Output Parse(XmlReader reader, bool suppressVersionCheck) { Debug.Assert("wixOutput" == reader.LocalName); bool empty = reader.IsEmptyElement; Output output = new Output(SourceLineNumberCollection.FromUri(reader.BaseURI)); SectionType sectionType = SectionType.Unknown; Version version = null; while (reader.MoveToNextAttribute()) { switch (reader.LocalName) { case "codepage": output.codepage = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture.NumberFormat); break; case "type": switch (reader.Value) { case "Module": output.type = OutputType.Module; sectionType = SectionType.Module; break; case "Patch": output.type = OutputType.Patch; break; case "PatchCreation": output.type = OutputType.PatchCreation; sectionType = SectionType.PatchCreation; break; case "Product": output.type = OutputType.Product; sectionType = SectionType.Product; break; case "Transform": output.type = OutputType.Transform; break; default: throw new WixException(WixErrors.IllegalAttributeValue(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixOutput", reader.Name, reader.Value, "Module", "Patch", "PatchCreation", "Product", "Transform")); } break; case "version": version = new Version(reader.Value); break; default: if (!reader.NamespaceURI.StartsWith("http://www.w3.org/")) { throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixOutput", reader.Name)); } break; } } if (null != version && !suppressVersionCheck) { if (0 != currentVersion.CompareTo(version)) { throw new WixException(WixErrors.VersionMismatch(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixOutput", version.ToString(), currentVersion.ToString())); } } // create a section for all the rows to belong to output.entrySection = new Section(null, sectionType, output.codepage); TableDefinitionCollection tableDefinitions = null; // loop through the rest of the xml building up the Output object if (!empty) { bool done = false; // loop through all the fields in a row while (!done && reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: switch (reader.LocalName) { case "subStorage": output.SubStorages.Add(SubStorage.Parse(reader)); break; case "table": if (null == tableDefinitions) { throw new WixException(WixErrors.ExpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixOutput", "tableDefinitions")); } output.Tables.Add(Table.Parse(reader, output.entrySection, tableDefinitions)); break; case "tableDefinitions": tableDefinitions = TableDefinitionCollection.Parse(reader); break; default: throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixOutput", reader.Name)); } break; case XmlNodeType.EndElement: done = true; break; } } if (!done) { throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixOutput")); } } return(output); }
/// <summary> /// Parse a field from the xml. /// </summary> /// <param name="reader">XmlReader where the intermediate is persisted.</param> internal override void Parse(XmlReader reader) { Debug.Assert("field" == reader.LocalName); bool empty = reader.IsEmptyElement; this.baseUri = reader.BaseURI; while (reader.MoveToNextAttribute()) { switch (reader.LocalName) { case "cabinetFileId": this.cabinetFileId = reader.Value; break; case "modified": this.Modified = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "field", reader.Name, reader.Value); break; case "previousData": this.previousData = reader.Value; break; default: if (!reader.NamespaceURI.StartsWith("http://www.w3.org/")) { throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "field", reader.Name)); } break; } } if (!empty) { bool done = false; while (!done && reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "field", reader.Name)); case XmlNodeType.CDATA: case XmlNodeType.Text: if (0 < reader.Value.Length) { this.Data = reader.Value; } break; case XmlNodeType.EndElement: done = true; break; } } if (!done) { throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "field")); } } }
/// <summary> /// Parse a field from the xml. /// </summary> /// <param name="reader">XmlReader where the intermediate is persisted.</param> internal virtual void Parse(XmlReader reader) { Debug.Assert("field" == reader.LocalName); bool empty = reader.IsEmptyElement; while (reader.MoveToNextAttribute()) { switch (reader.LocalName) { case "modified": this.modified = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "field", reader.Name, reader.Value); break; case "previousData": this.previousData = reader.Value; break; default: if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal)) { throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "field", reader.Name)); } break; } } if (!empty) { bool done = false; while (!done && reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "field", reader.Name)); case XmlNodeType.CDATA: case XmlNodeType.Text: case XmlNodeType.SignificantWhitespace: if (0 < reader.Value.Length) { if (ColumnType.Number == this.columnDefinition.Type && !this.columnDefinition.IsLocalizable) { // older wix files could persist data as a long value (which would overflow an int) // since the Convert class always throws exceptions for overflows, read in integral // values as a long to avoid the overflow, then cast it to an int (this operation can // overflow without throwing an exception inside an unchecked block) this.data = unchecked ((int)Convert.ToInt64(reader.Value, CultureInfo.InvariantCulture)); } else { this.data = reader.Value; } } break; case XmlNodeType.EndElement: done = true; break; } } if (!done) { throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "field")); } } }
/// <summary> /// Loads an output from a path on disk. /// </summary> /// <param name="stream">Stream containing the output file.</param> /// <param name="uri">Uri for finding this stream.</param> /// <param name="suppressVersionCheck">Suppresses wix.dll version mismatch check.</param> /// <param name="suppressSchema">Suppress xml schema validation while loading.</param> /// <returns>Returns the loaded output.</returns> /// <remarks>This method will set the Path and SourcePath properties to the appropriate values on successful load.</remarks> internal static Output Load(Stream stream, Uri uri, bool suppressVersionCheck, bool suppressSchema) { XmlReader reader = null; TempFileCollection tempFileCollection = null; string cabPath = null; // look for the Microsoft cabinet file header and save the cabinet data if found if ('M' == stream.ReadByte() && 'S' == stream.ReadByte() && 'C' == stream.ReadByte() && 'F' == stream.ReadByte()) { long cabFileSize = 0; byte[] offsetBuffer = new byte[4]; tempFileCollection = new TempFileCollection(); cabPath = tempFileCollection.AddExtension("cab", false); // skip the header checksum stream.Seek(4, SeekOrigin.Current); // get the cabinet file size stream.Read(offsetBuffer, 0, 4); cabFileSize = BitConverter.ToInt32(offsetBuffer, 0); stream.Seek(0, SeekOrigin.Begin); // Create the cab file from stream using (FileStream fs = File.Create(cabPath)) { for (int i = 0; i < cabFileSize; i++) { fs.WriteByte((byte)stream.ReadByte()); } } } else // plain xml file - start reading xml at the beginning of the stream { stream.Seek(0, SeekOrigin.Begin); } // read the xml try { reader = new XmlTextReader(uri.AbsoluteUri, stream); if (!suppressSchema) { reader = new XmlValidatingReader(reader); ((XmlValidatingReader)reader).Schemas.Add(GetSchemas()); } reader.MoveToContent(); if ("wixOutput" != reader.LocalName) { throw new WixNotOutputException(WixErrors.InvalidDocumentElement(SourceLineNumberCollection.FromUri(reader.BaseURI), reader.Name, "output", "wixOutput")); } Output output = Parse(reader, suppressVersionCheck); output.tempFileCollection = tempFileCollection; output.cabPath = cabPath; return(output); } catch (XmlException xe) { throw new WixException(WixErrors.InvalidXml(SourceLineNumberCollection.FromUri(reader.BaseURI), "output", xe.Message)); } catch (XmlSchemaException xse) { throw new WixException(WixErrors.SchemaValidationFailed(SourceLineNumberCollection.FromUri(reader.BaseURI), xse.Message)); } finally { if (null != reader) { reader.Close(); } } }
/// <summary> /// Loads a localization file from a stream. /// </summary> /// <param name="stream">Stream containing the localization file.</param> /// <param name="uri">Uri for finding this stream.</param> /// <param name="tableDefinitions">Collection containing TableDefinitions to use when loading the localization file.</param> /// <param name="suppressSchema">Suppress xml schema validation while loading.</param> /// <returns>Returns the loaded localization file.</returns> internal static Localization Load(Stream stream, Uri uri, TableDefinitionCollection tableDefinitions, bool suppressSchema) { XmlReader reader = null; try { reader = new XmlTextReader(uri.AbsoluteUri, stream); if (!suppressSchema) { reader = new XmlValidatingReader(reader); ((XmlValidatingReader)reader).Schemas.Add(GetSchemas()); } reader.MoveToContent(); if ("WixLocalization" != reader.LocalName) { throw new WixNotIntermediateException(WixErrors.InvalidDocumentElement(SourceLineNumberCollection.FromUri(reader.BaseURI), reader.Name, "localization", "WixLocalization")); } return(Parse(reader, tableDefinitions)); } catch (XmlException xe) { throw new WixException(WixErrors.InvalidXml(SourceLineNumberCollection.FromUri(reader.BaseURI), "localization", xe.Message)); } catch (XmlSchemaException xse) { throw new WixException(WixErrors.SchemaValidationFailed(SourceLineNumberCollection.FromUri(reader.BaseURI), xse.Message)); } finally { if (null != reader) { reader.Close(); } } }
/// <summary> /// Parse the root library element. /// </summary> /// <param name="reader">XmlReader with library persisted as Xml.</param> /// <param name="tableDefinitions">Collection containing TableDefinitions to use when reconstituting the intermediates.</param> /// <param name="suppressVersionCheck">Suppresses check for wix.dll version mismatch.</param> /// <returns>The parsed Library.</returns> private static Library Parse(XmlReader reader, TableDefinitionCollection tableDefinitions, bool suppressVersionCheck) { Debug.Assert("wixLibrary" == reader.LocalName); bool empty = reader.IsEmptyElement; Library library = new Library(); Version version = null; while (reader.MoveToNextAttribute()) { switch (reader.LocalName) { case "version": version = new Version(reader.Value); break; default: if (!reader.NamespaceURI.StartsWith("http://www.w3.org/")) { throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixLibrary", reader.Name)); } break; } } if (null != version && !suppressVersionCheck) { if (0 != currentVersion.CompareTo(version)) { throw new WixException(WixErrors.VersionMismatch(SourceLineNumberCollection.FromUri(reader.BaseURI), "library", version.ToString(), currentVersion.ToString())); } } if (!empty) { bool done = false; // loop through all the fields in a row while (!done && reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: switch (reader.LocalName) { case "section": library.sections.Add(Section.Parse(reader, tableDefinitions)); break; case "WixLocalization": Localization localization = Localization.Parse(reader, tableDefinitions); library.localizations.Add(localization.Culture, localization); break; default: throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixLibrary", reader.Name)); } break; case XmlNodeType.EndElement: done = true; break; } } if (!done) { throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixLibrary")); } } return(library); }
/// <summary> /// Parses table definition from xml reader. /// </summary> /// <param name="reader">Reader to get data from.</param> /// <returns>The TableDefintion represented by the Xml.</returns> internal static TableDefinition Parse(XmlReader reader) { Debug.Assert("tableDefinition" == reader.LocalName); bool empty = reader.IsEmptyElement; bool createSymbols = false; bool hasPrimaryKeyColumn = false; string name = null; bool unreal = false; bool bootstrapperApplicationData = false; while (reader.MoveToNextAttribute()) { switch (reader.LocalName) { case "createSymbols": createSymbols = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "createSymbols", reader.Name, reader.Value); break; case "name": name = reader.Value; break; case "unreal": unreal = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "tableDefinition", reader.Name, reader.Value); break; case "bootstrapperApplicationData": bootstrapperApplicationData = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "tableDefinition", reader.Name, reader.Value); break; default: if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal)) { throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "tableDefinition", reader.Name)); } break; } } if (null == name) { throw new WixException(WixErrors.ExpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "tableDefinition", "name")); } TableDefinition tableDefinition = new TableDefinition(name, createSymbols, unreal, bootstrapperApplicationData); // parse the child elements if (!empty) { bool done = false; while (!done && reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: switch (reader.LocalName) { case "columnDefinition": ColumnDefinition columnDefinition = ColumnDefinition.Parse(reader); tableDefinition.columns.Add(columnDefinition); if (columnDefinition.IsLocalizable) { tableDefinition.localizable = true; } if (columnDefinition.IsPrimaryKey) { hasPrimaryKeyColumn = true; } break; default: throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "tableDefinition", reader.Name)); } break; case XmlNodeType.EndElement: done = true; break; } } if (!unreal && !bootstrapperApplicationData && !hasPrimaryKeyColumn) { throw new WixException(WixErrors.RealTableMissingPrimaryKeyColumn(SourceLineNumberCollection.FromUri(reader.BaseURI), name)); } if (!done) { throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "tableDefinition")); } } return(tableDefinition); }
/// <summary> /// Loads an intermediate from a path on disk. /// </summary> /// <param name="path">Path to intermediate file saved on disk.</param> /// <param name="tableDefinitions">Collection containing TableDefinitions to use when reconstituting the intermediate.</param> /// <param name="suppressVersionCheck">Suppress checking for wix.dll version mismatches.</param> /// <param name="suppressSchema">Suppress xml schema validation while loading.</param> /// <returns>Returns the loaded intermediate.</returns> public static Intermediate Load(string path, TableDefinitionCollection tableDefinitions, bool suppressVersionCheck, bool suppressSchema) { XmlReader reader = null; try { reader = new XmlTextReader(path); if (!suppressSchema) { reader = new XmlValidatingReader(reader); ((XmlValidatingReader)reader).Schemas.Add(GetSchemas()); } reader.MoveToContent(); if ("wixObject" != reader.LocalName) { throw new WixNotIntermediateException(WixErrors.InvalidDocumentElement(SourceLineNumberCollection.FromUri(reader.BaseURI), reader.Name, "object", "wixObject")); } return(Parse(reader, tableDefinitions, suppressVersionCheck)); } catch (XmlException xe) { throw new WixNotIntermediateException(WixErrors.InvalidXml(SourceLineNumberCollection.FromUri(reader.BaseURI), "object", xe.Message)); } catch (XmlSchemaException xse) { throw new WixNotIntermediateException(WixErrors.SchemaValidationFailed(SourceLineNumberCollection.FromUri(reader.BaseURI), xse.Message, xse.LineNumber, xse.LinePosition)); } finally { if (null != reader) { reader.Close(); } } }
/// <summary> /// Parse a section from the xml. /// </summary> /// <param name="reader">XmlReader where the intermediate is persisted.</param> /// <param name="tableDefinitions">TableDefinitions to use in the intermediate.</param> /// <returns>The parsed Section.</returns> internal static Section Parse(XmlReader reader, TableDefinitionCollection tableDefinitions) { Debug.Assert("section" == reader.LocalName); int codepage = 0; bool empty = reader.IsEmptyElement; string id = null; Section section = null; SectionType type = SectionType.Unknown; while (reader.MoveToNextAttribute()) { switch (reader.Name) { case "codepage": codepage = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture); break; case "id": id = reader.Value; break; case "type": switch (reader.Value) { case "fragment": type = SectionType.Fragment; break; case "module": type = SectionType.Module; break; case "patchCreation": type = SectionType.PatchCreation; break; case "product": type = SectionType.Product; break; case "patch": type = SectionType.Patch; break; default: throw new WixException(WixErrors.IllegalAttributeValue(SourceLineNumberCollection.FromUri(reader.BaseURI), "section", reader.Name, reader.Value, "fragment", "module", "patchCreation", "product", "patch")); } break; default: if (!reader.NamespaceURI.StartsWith("http://www.w3.org/")) { throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "section", reader.Name)); } break; } } if (null == id && (SectionType.Unknown != type && SectionType.Fragment != type)) { throw new WixException(WixErrors.ExpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "section", "id", "type", type.ToString())); } if (SectionType.Unknown == type) { throw new WixException(WixErrors.ExpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "section", "type")); } section = new Section(id, type, codepage); section.sourceLineNumbers = SourceLineNumberCollection.FromUri(reader.BaseURI); if (!empty) { bool done = false; while (!done && reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: switch (reader.LocalName) { case "table": section.Tables.Add(Table.Parse(reader, section, tableDefinitions)); break; default: throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "section", reader.Name)); } break; case XmlNodeType.EndElement: done = true; break; } } if (!done) { throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "section")); } } return(section); }
/// <summary> /// Parses ActionRows from the Xml reader. /// </summary> /// <param name="reader">Xml reader that contains serialized ActionRows.</param> /// <returns>The parsed ActionRows.</returns> internal static WixActionRow[] Parse(XmlReader reader) { Debug.Assert("action" == reader.LocalName); string id = null; string condition = null; bool empty = reader.IsEmptyElement; int sequence = int.MinValue; int sequenceCount = 0; SequenceTable[] sequenceTables = new SequenceTable[Enum.GetValues(typeof(SequenceTable)).Length]; while (reader.MoveToNextAttribute()) { switch (reader.Name) { case "name": id = reader.Value; break; case "AdminExecuteSequence": if (Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.Name, reader.Value)) { sequenceTables[sequenceCount] = SequenceTable.AdminExecuteSequence; ++sequenceCount; } break; case "AdminUISequence": if (Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.Name, reader.Value)) { sequenceTables[sequenceCount] = SequenceTable.AdminUISequence; ++sequenceCount; } break; case "AdvtExecuteSequence": if (Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.Name, reader.Value)) { sequenceTables[sequenceCount] = SequenceTable.AdvtExecuteSequence; ++sequenceCount; } break; case "condition": condition = reader.Value; break; case "InstallExecuteSequence": if (Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.Name, reader.Value)) { sequenceTables[sequenceCount] = SequenceTable.InstallExecuteSequence; ++sequenceCount; } break; case "InstallUISequence": if (Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.Name, reader.Value)) { sequenceTables[sequenceCount] = SequenceTable.InstallUISequence; ++sequenceCount; } break; case "sequence": sequence = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture); break; default: if (!reader.NamespaceURI.StartsWith("http://www.w3.org/")) { throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.Name)); } break; } } if (null == id) { throw new WixException(WixErrors.ExpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", "name")); } if (int.MinValue == sequence) { throw new WixException(WixErrors.ExpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", "sequence")); } else if (1 > sequence) { throw new WixException(WixErrors.IntegralValueOutOfRange(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", "sequence", sequence, 1, int.MaxValue)); } if (0 == sequenceCount) { throw new WixException(WixErrors.ExpectedAttributes(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", "AdminExecuteSequence", "AdminUISequence", "AdvtExecuteSequence", "InstallExecuteSequence", "InstallUISequence")); } if (!empty && reader.Read() && XmlNodeType.EndElement != reader.MoveToContent()) { throw new WixException(WixErrors.UnexpectedContentNode(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.NodeType.ToString())); } // create the actions WixActionRow[] actionRows = new WixActionRow[sequenceCount]; for (int i = 0; i < sequenceCount; i++) { WixActionRow actionRow = new WixActionRow(sequenceTables[i], id, condition, sequence); actionRows[i] = actionRow; } return(actionRows); }
/// <summary> /// Creates a Row from the XmlReader. /// </summary> /// <param name="reader">Reader to get data from.</param> /// <param name="table">Table for this row.</param> /// <returns>New row object.</returns> internal static Row Parse(XmlReader reader, Table table) { Debug.Assert("row" == reader.LocalName); bool empty = reader.IsEmptyElement; RowOperation operation = RowOperation.None; string sectionId = null; SourceLineNumberCollection sourceLineNumbers = null; while (reader.MoveToNextAttribute()) { switch (reader.LocalName) { case "op": switch (reader.Value) { case "add": operation = RowOperation.Add; break; case "delete": operation = RowOperation.Delete; break; case "modify": operation = RowOperation.Modify; break; default: throw new WixException(WixErrors.IllegalAttributeValue(SourceLineNumberCollection.FromUri(reader.BaseURI), "row", reader.Name, reader.Value, "Add", "Delete", "Modify")); } break; case "sectionId": sectionId = reader.Value; break; case "sourceLineNumber": sourceLineNumbers = new SourceLineNumberCollection(reader.Value); break; default: if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal)) { throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "row", reader.Name)); } break; } } Row row = table.CreateRow(sourceLineNumbers); row.Operation = operation; row.SectionId = sectionId; // loop through all the fields in a row if (!empty) { bool done = false; int field = 0; // loop through all the fields in a row while (!done && reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: switch (reader.LocalName) { case "field": if (row.Fields.Length <= field) { if (!reader.IsEmptyElement) { throw new WixException(WixErrors.UnexpectedColumnCount(SourceLineNumberCollection.FromUri(reader.BaseURI), table.Name)); } } else { row.fields[field].Parse(reader); } ++field; break; default: throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "row", reader.Name)); } break; case XmlNodeType.EndElement: done = true; break; } } if (!done) { throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "row")); } } return(row); }
/// <summary> /// Parse a localization string. /// </summary> /// <param name="reader">XmlReader where the localization file is persisted.</param> /// <param name="tableDefinitions">Collection containing TableDefinitions to use when loading the localization file.</param> /// <param name="localization">The localization being parsed.</param> private static void ParseString(XmlReader reader, TableDefinitionCollection tableDefinitions, Localization localization) { Debug.Assert("String" == reader.LocalName); bool empty = reader.IsEmptyElement; SourceLineNumberCollection sourceLineNumbers = SourceLineNumberCollection.FromUri(reader.BaseURI); string id = null; bool overridable = false; string value = String.Empty; // default this value to the empty string while (reader.MoveToNextAttribute()) { switch (reader.LocalName) { case "Id": id = reader.Value; break; case "Overridable": overridable = Common.IsYes(sourceLineNumbers, "String", reader.Name, reader.Value); break; default: if (!reader.NamespaceURI.StartsWith("http://www.w3.org/")) { throw new WixException(WixErrors.UnexpectedAttribute(sourceLineNumbers, "String", reader.Name)); } break; } } if (!empty) { bool done = false; while (!done && reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: throw new WixException(WixErrors.UnexpectedElement(sourceLineNumbers, "String", reader.Name)); case XmlNodeType.CDATA: case XmlNodeType.Text: if (0 < reader.Value.Length) { value = reader.Value; } break; case XmlNodeType.EndElement: done = true; break; } } if (!done) { throw new WixException(WixErrors.ExpectedEndElement(sourceLineNumbers, "String")); } } if (null == id) { throw new WixException(WixErrors.ExpectedAttribute(sourceLineNumbers, "String", "Id")); } WixVariableRow wixVariableRow = new WixVariableRow(sourceLineNumbers, tableDefinitions["WixVariable"]); wixVariableRow.Id = id; wixVariableRow.Overridable = overridable; wixVariableRow.Value = value; WixVariableRow existingWixVariableRow = (WixVariableRow)localization.variables[id]; if (null == existingWixVariableRow || (existingWixVariableRow.Overridable && !overridable)) { localization.variables.Add(id, wixVariableRow); } else if (!overridable) { throw new WixException(WixErrors.DuplicateLocalizationIdentifier(sourceLineNumbers, id)); } }
/// <summary> /// Parse a localization file from an XML format. /// </summary> /// <param name="reader">XmlReader where the localization file is persisted.</param> /// <param name="tableDefinitions">Collection containing TableDefinitions to use when parsing the localization file.</param> /// <returns>The parsed localization.</returns> internal static Localization Parse(XmlReader reader, TableDefinitionCollection tableDefinitions) { Debug.Assert("WixLocalization" == reader.LocalName); bool empty = reader.IsEmptyElement; int codepage = -1; string culture = null; while (reader.MoveToNextAttribute()) { switch (reader.LocalName) { case "Codepage": try { codepage = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture.NumberFormat); } catch (FormatException) { throw new WixException(WixErrors.IllegalIntegerValue(SourceLineNumberCollection.FromUri(reader.BaseURI), "WixLocalization", reader.Name, reader.Value)); } catch (OverflowException) { throw new WixException(WixErrors.IllegalIntegerValue(SourceLineNumberCollection.FromUri(reader.BaseURI), "WixLocalization", reader.Name, reader.Value)); } break; case "Culture": culture = reader.Value; break; default: if (!reader.NamespaceURI.StartsWith("http://www.w3.org/")) { throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "WixLocalization", reader.Name)); } break; } } if (null == culture) { throw new WixException(WixErrors.ExpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "WixLocalization", "Culture")); } Localization localization = new Localization(codepage, culture); if (!empty) { bool done = false; while (!done && reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: switch (reader.LocalName) { case "String": ParseString(reader, tableDefinitions, localization); break; default: throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "WixLocalization", reader.Name)); } break; case XmlNodeType.EndElement: done = true; break; } } if (!done) { throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "WixLocalization")); } } return(localization); }
/// <summary> /// Parses a column definition in a table definition. /// </summary> /// <param name="reader">Reader to get data from.</param> /// <returns>The ColumnDefintion represented by the Xml.</returns> internal static ColumnDefinition Parse(XmlReader reader) { Debug.Assert("columnDefinition" == reader.LocalName); bool added = false; ColumnCategory category = ColumnCategory.Unknown; string description = null; bool empty = reader.IsEmptyElement; bool escapeIdtCharacters = false; int keyColumn = -1; bool keyColumnSet = false; string keyTable = null; int length = -1; bool localizable = false; int maxValue = 0; bool maxValueSet = false; int minValue = 0; bool minValueSet = false; ColumnModularizeType modularize = ColumnModularizeType.None; string name = null; bool nullable = false; string possibilities = null; bool primaryKey = false; ColumnType type = ColumnType.Unknown; bool useCData = false; // parse the attributes while (reader.MoveToNextAttribute()) { switch (reader.LocalName) { case "added": added = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value); break; case "category": switch (reader.Value) { case "anyPath": category = ColumnCategory.AnyPath; break; case "binary": category = ColumnCategory.Binary; break; case "cabinet": category = ColumnCategory.Cabinet; break; case "condition": category = ColumnCategory.Condition; break; case "customSource": category = ColumnCategory.CustomSource; break; case "defaultDir": category = ColumnCategory.DefaultDir; break; case "doubleInteger": category = ColumnCategory.DoubleInteger; break; case "filename": category = ColumnCategory.Filename; break; case "formatted": category = ColumnCategory.Formatted; break; case "formattedSddl": category = ColumnCategory.FormattedSDDLText; break; case "guid": category = ColumnCategory.Guid; break; case "identifier": category = ColumnCategory.Identifier; break; case "integer": category = ColumnCategory.Integer; break; case "language": category = ColumnCategory.Language; break; case "lowerCase": category = ColumnCategory.LowerCase; break; case "path": category = ColumnCategory.Path; break; case "paths": category = ColumnCategory.Paths; break; case "property": category = ColumnCategory.Property; break; case "regPath": category = ColumnCategory.RegPath; break; case "shortcut": category = ColumnCategory.Shortcut; break; case "template": category = ColumnCategory.Template; break; case "text": category = ColumnCategory.Text; break; case "timeDate": category = ColumnCategory.TimeDate; break; case "upperCase": category = ColumnCategory.UpperCase; break; case "version": category = ColumnCategory.Version; break; case "wildCardFilename": category = ColumnCategory.WildCardFilename; break; default: throw new WixException(WixErrors.IllegalAttributeValue(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value, "anyPath", "binary", "cabinet", "condition", "customSource", "defaultDir", "doubleInteger", "filename", "formatted", "formattedSddl", "guid", "identifier", "integer", "language", "lowerCase", "path", "paths", "property", "regPath", "shortcut", "template", "text", "timeDate", "upperCase", "version", "wildCardFilename")); } break; case "description": description = reader.Value; break; case "escapeIdtCharacters": escapeIdtCharacters = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value); break; case "keyColumn": keyColumnSet = true; keyColumn = Convert.ToInt32(reader.Value, 10); break; case "keyTable": keyTable = reader.Value; break; case "length": length = Convert.ToInt32(reader.Value, 10); break; case "localizable": localizable = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value); break; case "maxValue": maxValueSet = true; maxValue = Convert.ToInt32(reader.Value, 10); break; case "minValue": minValueSet = true; minValue = Convert.ToInt32(reader.Value, 10); break; case "modularize": switch (reader.Value) { case "column": modularize = ColumnModularizeType.Column; break; case "companionFile": modularize = ColumnModularizeType.CompanionFile; break; case "condition": modularize = ColumnModularizeType.Condition; break; case "controlEventArgument": modularize = ColumnModularizeType.ControlEventArgument; break; case "controlText": modularize = ColumnModularizeType.ControlText; break; case "icon": modularize = ColumnModularizeType.Icon; break; case "none": modularize = ColumnModularizeType.None; break; case "property": modularize = ColumnModularizeType.Property; break; case "semicolonDelimited": modularize = ColumnModularizeType.SemicolonDelimited; break; default: throw new WixException(WixErrors.IllegalAttributeValue(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value, "column", "companionFile", "condition", "controlEventArgument", "controlText", "icon", "property", "semicolonDelimited")); } break; case "name": switch (reader.Value) { case "CREATE": case "DELETE": case "DROP": case "INSERT": throw new WixException(WixErrors.IllegalColumnName(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value)); default: name = reader.Value; break; } break; case "nullable": nullable = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value); break; case "primaryKey": primaryKey = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value); break; case "set": possibilities = reader.Value; break; case "type": switch (reader.Value) { case "localized": type = ColumnType.Localized; break; case "number": type = ColumnType.Number; break; case "object": type = ColumnType.Object; break; case "string": type = ColumnType.String; break; case "preserved": type = ColumnType.Preserved; break; default: throw new WixException(WixErrors.IllegalAttributeValue(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value, "localized", "number", "object", "string")); } break; case "useCData": useCData = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value); break; default: if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal)) { throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name)); } break; } } // parse the child elements (there should be none) if (!empty) { bool done = false; while (!done && reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name)); case XmlNodeType.EndElement: done = true; break; } } if (!done) { throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition")); } } ColumnDefinition columnDefinition = new ColumnDefinition(name, type, length, primaryKey, nullable, modularize, localizable, minValueSet, minValue, maxValueSet, maxValue, keyTable, keyColumnSet, keyColumn, category, possibilities, description, escapeIdtCharacters, useCData); columnDefinition.Added = added; return(columnDefinition); }
/// <summary> /// Parse a table from the xml. /// </summary> /// <param name="reader">XmlReader where the intermediate is persisted.</param> /// <param name="section">Section to populate with persisted data.</param> /// <param name="tableDefinitions">TableDefinitions to use in the intermediate.</param> /// <returns>The parsed table.</returns> internal static Table Parse(XmlReader reader, Section section, TableDefinitionCollection tableDefinitions) { Debug.Assert("table" == reader.LocalName); bool empty = reader.IsEmptyElement; TableOperation operation = TableOperation.None; string name = null; while (reader.MoveToNextAttribute()) { switch (reader.LocalName) { case "name": name = reader.Value; break; case "op": switch (reader.Value) { case "add": operation = TableOperation.Add; break; case "drop": operation = TableOperation.Drop; break; default: throw new WixException(WixErrors.IllegalAttributeValue(SourceLineNumberCollection.FromUri(reader.BaseURI), "table", reader.Name, reader.Value, "Add", "Drop")); } break; default: if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal)) { throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "table", reader.Name)); } break; } } if (null == name) { throw new WixException(WixErrors.ExpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "table", "name")); } TableDefinition tableDefinition = tableDefinitions[name]; Table table = new Table(section, tableDefinition); table.Operation = operation; if (!empty) { bool done = false; // loop through all the rows in a table while (!done && reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: switch (reader.LocalName) { case "row": Row.Parse(reader, table); break; default: throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "table", reader.Name)); } break; case XmlNodeType.EndElement: done = true; break; } } if (!done) { throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "table")); } } return(table); }
/// <summary> /// Parse an intermediate from an XML format. /// </summary> /// <param name="reader">XmlReader where the intermediate is persisted.</param> /// <param name="tableDefinitions">TableDefinitions to use in the intermediate.</param> /// <param name="suppressVersionCheck">Suppress checking for wix.dll version mismatch.</param> /// <returns>The parsed Intermediate.</returns> internal static Intermediate Parse(XmlReader reader, TableDefinitionCollection tableDefinitions, bool suppressVersionCheck) { Debug.Assert("wixObject" == reader.LocalName); bool empty = reader.IsEmptyElement; Version objVersion = null; while (reader.MoveToNextAttribute()) { switch (reader.LocalName) { case "version": objVersion = new Version(reader.Value); break; default: if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal)) { throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixObject", reader.Name)); } break; } } if (null != objVersion && !suppressVersionCheck) { if (0 != currentVersion.CompareTo(objVersion)) { throw new WixException(WixErrors.VersionMismatch(SourceLineNumberCollection.FromUri(reader.BaseURI), "object", objVersion.ToString(), currentVersion.ToString())); } } Intermediate intermediate = new Intermediate(); // loop through the rest of the xml building up the SectionCollection if (!empty) { bool done = false; while (!done && reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: switch (reader.LocalName) { case "section": intermediate.sections.Add(Section.Parse(reader, tableDefinitions)); break; default: throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixObject", reader.Name)); } break; case XmlNodeType.EndElement: done = true; break; } } if (!done) { throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixObject")); } } return(intermediate); }
/// <summary> /// Loads a library from a path on disk. /// </summary> /// <param name="stream">Stream containing the library file.</param> /// <param name="uri">Uri for finding this stream.</param> /// <param name="tableDefinitions">Collection containing TableDefinitions to use when reconstituting the intermediates.</param> /// <param name="suppressVersionCheck">Suppresses wix.dll version mismatch check.</param> /// <param name="suppressSchema">Suppress xml schema validation while loading.</param> /// <returns>Returns the loaded library.</returns> /// <remarks>This method will set the Path and SourcePath properties to the appropriate values on successful load.</remarks> internal static Library Load(Stream stream, Uri uri, TableDefinitionCollection tableDefinitions, bool suppressVersionCheck, bool suppressSchema) { XmlReader reader = null; // look for the Microsoft cabinet file header and skip past the cabinet data if found if ('M' == stream.ReadByte() && 'S' == stream.ReadByte() && 'C' == stream.ReadByte() && 'F' == stream.ReadByte()) { long offset = 0; byte[] offsetBuffer = new byte[4]; // skip the header checksum stream.Seek(4, SeekOrigin.Current); // read the cabinet file size stream.Read(offsetBuffer, 0, 4); offset = BitConverter.ToInt32(offsetBuffer, 0); // seek past the cabinet file to the xml stream.Seek(offset, SeekOrigin.Begin); } else // plain xml file - start reading xml at the beginning of the stream { stream.Seek(0, SeekOrigin.Begin); } // read the xml try { reader = new XmlTextReader(uri.AbsoluteUri, stream); if (!suppressSchema) { reader = new XmlValidatingReader(reader); ((XmlValidatingReader)reader).Schemas.Add(GetSchemas()); } reader.MoveToContent(); if ("wixLibrary" != reader.LocalName) { throw new WixNotLibraryException(WixErrors.InvalidDocumentElement(SourceLineNumberCollection.FromUri(reader.BaseURI), reader.Name, "library", "wixLibrary")); } return(Parse(reader, tableDefinitions, suppressVersionCheck)); } catch (XmlException xe) { throw new WixException(WixErrors.InvalidXml(SourceLineNumberCollection.FromUri(reader.BaseURI), "object", xe.Message)); } catch (XmlSchemaException xse) { throw new WixException(WixErrors.SchemaValidationFailed(SourceLineNumberCollection.FromUri(reader.BaseURI), xse.Message)); } finally { if (null != reader) { reader.Close(); } } }
/// <summary> /// Processes an XmlReader and builds up the pdb object. /// </summary> /// <param name="reader">Reader to get data from.</param> /// <param name="suppressVersionCheck">Suppresses wix.dll version mismatch check.</param> /// <returns>The Pdb represented by the Xml.</returns> internal static Pdb Parse(XmlReader reader, bool suppressVersionCheck) { Debug.Assert("wixPdb" == reader.LocalName); bool empty = reader.IsEmptyElement; Pdb pdb = new Pdb(SourceLineNumberCollection.FromUri(reader.BaseURI)); Version version = null; while (reader.MoveToNextAttribute()) { switch (reader.LocalName) { case "version": version = new Version(reader.Value); break; default: if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal)) { throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixPdb", reader.Name)); } break; } } if (null != version) { if (0 != currentVersion.CompareTo(version)) { throw new WixException(WixErrors.VersionMismatch(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixPdb", version.ToString(), currentVersion.ToString())); } } // loop through the rest of the pdb building up the Output object if (!empty) { bool done = false; // loop through all the fields in a row while (!done && reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: switch (reader.LocalName) { case "wixOutput": pdb.output = Output.Parse(reader, suppressVersionCheck); break; default: throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixPdb", reader.Name)); } break; case XmlNodeType.EndElement: done = true; break; } } if (!done) { throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "wixOutput")); } } return(pdb); }
/// <summary> /// Creates a SubStorage from the XmlReader. /// </summary> /// <param name="reader">Reader to get data from.</param> /// <returns>New SubStorage object.</returns> internal static SubStorage Parse(XmlReader reader) { Debug.Assert("subStorage" == reader.LocalName); Output data = null; bool empty = reader.IsEmptyElement; string name = null; while (reader.MoveToNextAttribute()) { switch (reader.LocalName) { case "name": name = reader.Value; break; default: if (!reader.NamespaceURI.StartsWith("http://www.w3.org/")) { throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "row", reader.Name)); } break; } } // loop through all the fields in a row if (!empty) { bool done = false; // loop through all the fields in a row while (!done && reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: switch (reader.LocalName) { case "wixOutput": data = Output.Parse(reader, true); break; default: throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "row", reader.Name)); } break; case XmlNodeType.EndElement: done = true; break; } } if (!done) { throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "row")); } } return(new SubStorage(name, data)); }