/// <summary> /// Loads a pdb from a path on disk. /// </summary> /// <param name="stream">Stream containing the pdb 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 pdb.</returns> /// <remarks>This method will set the Path and SourcePath properties to the appropriate values on successful load.</remarks> internal static Pdb Load(Stream stream, Uri uri, bool suppressVersionCheck, bool suppressSchema) { XmlReader reader = 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]; using (TempFileCollection tempFileCollection = new TempFileCollection()) { cabPath = tempFileCollection.AddExtension("cab", true); } // 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 ("wixPdb" != reader.LocalName) { throw new WixNotOutputException(WixErrors.InvalidDocumentElement(SourceLineNumber.CreateFromUri(reader.BaseURI), reader.Name, "pdb", "wixPdb")); } Pdb pdb = Parse(reader, suppressVersionCheck); if (null != cabPath) { if (pdb.Output.TempFiles == null) { pdb.Output.TempFiles = new TempFileCollection(); } pdb.Output.TempFiles.AddFile(cabPath, false); } return(pdb); } catch (XmlException xe) { throw new WixException(WixErrors.InvalidXml(SourceLineNumber.CreateFromUri(reader.BaseURI), "output", xe.Message)); } catch (XmlSchemaException xse) { throw new WixException(WixErrors.SchemaValidationFailed(SourceLineNumber.CreateFromUri(reader.BaseURI), xse.Message, xse.LineNumber, xse.LinePosition)); } 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(SourceLineNumber.CreateFromUri(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(SourceLineNumber.CreateFromUri(reader.BaseURI), "wixPdb", reader.Name)); } break; } } if (null != version) { if (0 != currentVersion.CompareTo(version)) { throw new WixException(WixErrors.VersionMismatch(SourceLineNumber.CreateFromUri(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(SourceLineNumber.CreateFromUri(reader.BaseURI), "wixPdb", reader.Name)); } break; case XmlNodeType.EndElement: done = true; break; } } if (!done) { throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumber.CreateFromUri(reader.BaseURI), "wixOutput")); } } return(pdb); }