ParsePages() { Stream stream = _metroPart.GetStream(FileMode.Open); // // If the stream is empty there are no pages to parse // if (stream.Length > 0) { XmlTextReader reader = new XmlTextReader(stream); while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element && reader.Name == XpsS0Markup.PageContent) { string attribute = reader.GetAttribute(XmlTags.Source); if (attribute != null) { Uri relativeUri = new Uri(attribute, UriKind.Relative); AddPageToCache(PackUriHelper.ResolvePartUri(Uri, relativeUri)); } } } } }
static BaseUriHelper() { _baseUri = new SecurityCriticalDataForSet <Uri>(_packAppBaseUri); // Add an instance of the ResourceContainer to PreloadedPackages so that PackWebRequestFactory can find it // and mark it as thread-safe so PackWebResponse won't protect returned streams with a synchronizing wrapper PreloadedPackages.AddPackage(PackUriHelper.GetPackageUri(SiteOfOriginBaseUri), new SiteOfOriginContainer(), true); }
ParseDocuments() { Stream stream = _metroPart.GetStream(FileMode.Open); // // If the stream is empty there are no documents to parse // if (stream.Length > 0) { XmlTextReader reader = new XmlTextReader(stream); while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element && reader.Name == XpsS0Markup.DocumentReference) { string attribute = reader.GetAttribute(XmlTags.Source); if (attribute != null) { Uri relativeUri = new Uri(attribute, UriKind.Relative); //This routine properly adds DocumentReaderWriter to the _documentCache AddDocumentToCache(PackUriHelper.ResolvePartUri(Uri, relativeUri)); } } } } }
EnsureDoucmentStructure() { // if _xpsSignaturs is not null we have already initialized this // if (null != _documentStructure) { return; } PackageRelationship documentStructureRelationship = null; PackagePart documentStructurePart = null; foreach (PackageRelationship rel in _metroPart.GetRelationshipsByType(XpsS0Markup.StructureRelationshipName)) { if (documentStructureRelationship != null) { throw new InvalidDataException(SR.Get(SRID.ReachPackaging_MoreThanOneDocStructure)); } documentStructureRelationship = rel; } if (documentStructureRelationship != null) { Uri documentStructureUri = PackUriHelper.ResolvePartUri(documentStructureRelationship.SourceUri, documentStructureRelationship.TargetUri); if (CurrentXpsManager.MetroPackage.PartExists(documentStructureUri)) { documentStructurePart = CurrentXpsManager.MetroPackage.GetPart(documentStructureUri); _documentStructure = new XpsStructure(CurrentXpsManager, this, documentStructurePart); } } }
static internal Uri MakeRelativeToSiteOfOriginIfPossible(Uri sUri) { if (Uri.Compare(sUri, SiteOfOriginBaseUri, UriComponents.Scheme, UriFormat.UriEscaped, StringComparison.OrdinalIgnoreCase) == 0) { Uri packageUri = PackUriHelper.GetPackageUri(sUri); if (String.Compare(packageUri.GetComponents(UriComponents.AbsoluteUri, UriFormat.UriEscaped), _packageSiteOfOriginBaseUriEscaped, StringComparison.OrdinalIgnoreCase) == 0) { return((new Uri(sUri.GetComponents(UriComponents.SchemeAndServer, UriFormat.UriEscaped))).MakeRelativeUri(sUri)); } } return(sUri); }
/// <summary> /// Checks whether the input uri is in the "pack://application:,,," form /// </summary> internal static bool IsPackApplicationUri(Uri uri) { return // Is the "outer" URI absolute? (uri.IsAbsoluteUri && // Does the "outer" URI have the pack: scheme? SecurityHelper.AreStringTypesEqual(uri.Scheme, System.IO.Packaging.PackUriHelper.UriSchemePack) && // Does the "inner" URI have the application: scheme SecurityHelper.AreStringTypesEqual( PackUriHelper.GetPackageUri(uri).GetComponents(UriComponents.AbsoluteUri, UriFormat.UriEscaped), _packageApplicationBaseUriEscaped)); }
/// <summary> /// Constructs a ZipPackagePart for an atomic (i.e. non-interleaved) part. /// This is called from the ZipPackage class as a result of GetPartCore, /// GetPartsCore or CreatePartCore methods /// </summary> /// <param name="zipPackage"></param> /// <param name="zipArchive"></param> /// <param name="zipArchiveEntry"></param> /// <param name="zipStreamManager"></param> /// <param name="partUri"></param> /// <param name="compressionOption"></param> /// <param name="contentType"></param> internal ZipPackagePart(ZipPackage zipPackage, ZipArchive zipArchive, ZipArchiveEntry zipArchiveEntry, ZipStreamManager zipStreamManager, PackUriHelper.ValidatedPartUri partUri, string contentType, CompressionOption compressionOption) : base(zipPackage, partUri, contentType, compressionOption) { _zipPackage = zipPackage; _zipArchive = zipArchive; _zipStreamManager = zipStreamManager; _zipArchiveEntry = zipArchiveEntry; }
internal void UriHitHandler(int node, Uri uri) { if (_uniqueUriRef != null) { if (_uniqueUriRef.Contains(uri)) { if ((int)_uniqueUriRef[uri] != node) { throw new FileFormatException(SR.Get(SRID.XpsValidatingLoaderDuplicateReference)); } } else { _uniqueUriRef.Add(uri, node); } } Hashtable validResources = _validResources.Peek(); if (validResources != null) { if (!validResources.ContainsKey(uri)) { // The hashtable is case sensitive, packuris are not, so if we do not find in hashtable, // do true comparison and add when found for next time... bool found = false; foreach (Uri resUri in validResources.Keys) { if (PackUriHelper.ComparePackUri(resUri, uri) == 0) { validResources.Add(uri, validResources[resUri]); found = true; break; } } if (!found) { throw new FileFormatException(SR.Get(SRID.XpsValidatingLoaderUnlistedResource)); } } if (!(bool)validResources[uri]) { throw new FileFormatException(SR.Get(SRID.XpsValidatingLoaderUnsupportedMimeType)); } } }
/// <summary> /// This method is for custom implementation specific to the file format. /// This is the method that knows how to get the actual parts from the underlying /// zip archive. /// </summary> /// <remarks> /// <para> /// Some or all of the parts may be interleaved. The Part object for an interleaved part encapsulates /// the Uri of the proper part name and the ZipFileInfo of the initial piece. /// This function does not go through the extra work of checking piece naming validity /// throughout the package. /// </para> /// <para> /// This means that interleaved parts without an initial piece will be silently ignored. /// Other naming anomalies get caught at the Stream level when an I/O operation involves /// an anomalous or missing piece. /// </para> /// <para> /// This function reads directly from the underlying IO layer and is supposed to be called /// just once in the lifetime of a package (at init time). /// </para> /// </remarks> /// <returns>An array of ZipPackagePart.</returns> protected override PackagePart[] GetPartsCore() { List <PackagePart> parts = new List <PackagePart>(InitialPartListSize); // The list of files has to be searched linearly (1) to identify the content type // stream, and (2) to identify parts. System.Collections.ObjectModel.ReadOnlyCollection <ZipArchiveEntry> zipArchiveEntries = _zipArchive.Entries; // We have already identified the [ContentTypes].xml pieces if any are present during // the initialization of ZipPackage object // Record parts and ignored items. foreach (ZipArchiveEntry zipArchiveEntry in zipArchiveEntries) { //Returns false if - // a. its a content type item // b. items that have either a leading or trailing slash. if (IsZipItemValidOpcPartOrPiece(zipArchiveEntry.FullName)) { Uri partUri = new Uri(GetOpcNameFromZipItemName(zipArchiveEntry.FullName), UriKind.Relative); PackUriHelper.ValidatedPartUri validatedPartUri; if (PackUriHelper.TryValidatePartUri(partUri, out validatedPartUri)) { ContentType contentType = _contentTypeHelper.GetContentType(validatedPartUri); if (contentType != null) { // In case there was some redundancy between pieces and/or the atomic // part, it will be detected at this point because the part's Uri (which // is independent of interleaving) will already be in the dictionary. parts.Add(new ZipPackagePart(this, zipArchiveEntry.Archive, zipArchiveEntry, _zipStreamManager, validatedPartUri, contentType.ToString(), GetCompressionOptionFromZipFileInfo(zipArchiveEntry))); } } //If not valid part uri we can completely ignore this zip file item. Even if later someone adds //a new part, the corresponding zip item can never map to one of these items } // If IsZipItemValidOpcPartOrPiece returns false, it implies that either the zip file Item // starts or ends with a "/" and as such we can completely ignore this zip file item. Even if later // a new part gets added, its corresponding zip item cannot map to one of these items. } return(parts.ToArray()); }
/// <summary> /// Adds a uri, package pair to the package store. /// </summary> /// <param name="uri">key uri</param> /// <param name="package">package</param> /// <permission cref="EnvironmentPermission"></permission> /// <remarks> /// If a package with the uri is already in the store,it throws an exception. /// The package will not be automatically replaced within the store. /// </remarks> ///<SecurityNote> /// Demands EnvironmentPermission() if package is custom type of Package. /// This prevents Partially Trusted callers from performing this operation. However, Partially Trusted callers can still /// add well-known platform Package type (ZipPackage) to PackageStore. /// the application's PackageStore. ///</SecurityNote> public static void AddPackage(Uri uri, Package package) { // Allow well known platform Package to be added into PackageStore under Partial Trust. // Otherwise, demand Environment Permission to make sure only Full Trust app can add a custom Package DemandSecurityPermissionIfCustomPackage(package); ValidatePackageUri(uri); // There are well-known package types that are only for internal use (for resource loading) // (i.e. ResourceContainer - "application://" and SiteOriginContainer - "siteoforigin://" // Adding packages with such key uri will have no effect on PackWebRequest since // they cannot be overriden. So, calling this method with such key Uris should be prevented // However, uri.Equal cannot be used here since the key Uris are used as a pack Uri form and // only PackUriHelper.ComparePackUri can do the proper comparison of pack Uris. Uri packUri = PackUriHelper.Create(uri); if (PackUriHelper.ComparePackUri(packUri, BaseUriHelper.PackAppBaseUri) == 0 || PackUriHelper.ComparePackUri(packUri, BaseUriHelper.SiteOfOriginBaseUri) == 0) { throw new ArgumentException(SR.Get(SRID.NotAllowedPackageUri), nameof(uri)); } if (package == null) { throw new ArgumentNullException(nameof(package)); } lock (_globalLock) { if (_packages == null) { _packages = new HybridDictionary(2); } if (_packages.Contains(uri)) { throw new InvalidOperationException(SR.Get(SRID.PackageAlreadyExists)); } _packages.Add(uri, package); } }
GetFixedDocumentSequence( ) { CheckDisposed(); if (CurrentXpsManager == null) { throw new InvalidOperationException(SR.Get(SRID.ReachPackaging_DocumentWasClosed)); } if (!IsReader) { throw new XpsPackagingException(SR.Get(SRID.ReachPackaging_NotOpenForReading)); } if (null == Uri) { throw new XpsPackagingException(SR.Get(SRID.ReachPackaging_PackageUriNull)); } if (CurrentXpsManager.StartingPart == null) { return(null); } ContentType startPartType = CurrentXpsManager.StartingPart.ValidatedContentType(); if (!startPartType.AreTypeAndSubTypeEqual(XpsS0Markup.DocumentSequenceContentType)) { throw new XpsPackagingException(SR.Get(SRID.ReachPackaging_InvalidStartingPart)); } ParserContext parserContext = new ParserContext(); parserContext.BaseUri = PackUriHelper.Create(Uri, CurrentXpsManager.StartingPart.Uri); object fixedObject = XamlReader.Load(CurrentXpsManager.StartingPart.GetStream(), parserContext); if (!(fixedObject is FixedDocumentSequence)) { throw new XpsPackagingException(SR.Get(SRID.ReachPackaging_NotAFixedDocumentSequence)); } return(fixedObject as FixedDocumentSequence); }
//------------------------------------------------------ // // Public Constructors // //------------------------------------------------------ #region Public Constructor /// <summary> /// Constructor /// </summary> /// <param name="sourceUri">Source Uri of the PackagePart or PackageRoot ("/") that owns the relationship</param> /// <param name="selectorType">PackageRelationshipSelectorType enum representing the type of the selectionCriteria</param> /// <param name="selectionCriteria">The actual string that is used to select the relationships</param> /// <exception cref="ArgumentNullException">If sourceUri is null</exception> /// <exception cref="ArgumentNullException">If selectionCriteria is null</exception> /// <exception cref="ArgumentOutOfRangeException">If selectorType Enumeration does not have a valid value</exception> /// <exception cref="System.Xml.XmlException">If PackageRelationshipSelectorType.Id and selection criteria is not valid Xsd Id</exception> /// <exception cref="ArgumentException">If PackageRelationshipSelectorType.Type and selection criteria is not valid relationship type</exception> /// <exception cref="ArgumentException">If sourceUri is not "/" to indicate the PackageRoot, then it must conform to the /// valid PartUri syntax</exception> public PackageRelationshipSelector(Uri sourceUri, PackageRelationshipSelectorType selectorType, string selectionCriteria) { if (sourceUri == null) { throw new ArgumentNullException("sourceUri"); } if (selectionCriteria == null) { throw new ArgumentNullException("selectionCriteria"); } //If the sourceUri is not equal to "/", it must be a valid part name. if (Uri.Compare(sourceUri, PackUriHelper.PackageRootUri, UriComponents.SerializationInfoString, UriFormat.UriEscaped, StringComparison.Ordinal) != 0) { sourceUri = PackUriHelper.ValidatePartUri(sourceUri); } //selectionCriteria is tested here as per the value of the selectorType. //If selectionCriteria is empty string we will throw the appropriate error message. if (selectorType == PackageRelationshipSelectorType.Type) { InternalRelationshipCollection.ThrowIfInvalidRelationshipType(selectionCriteria); } else if (selectorType == PackageRelationshipSelectorType.Id) { InternalRelationshipCollection.ThrowIfInvalidXsdId(selectionCriteria); } else { throw new ArgumentOutOfRangeException("selectorType"); } _sourceUri = sourceUri; _selectionCriteria = selectionCriteria; _selectorType = selectorType; }
WebRequest IWebRequestCreate.Create(Uri uri) { if (uri == null) { throw new ArgumentNullException("uri"); } // Ensure uri is absolute - if we don't check now, the get_Scheme property will throw // InvalidOperationException which would be misleading to the caller. if (!uri.IsAbsoluteUri) { throw new ArgumentException(SR.Get(SRID.UriMustBeAbsolute), "uri"); } // Ensure uri is correct scheme because we can be called directly. Case sensitive // is fine because Uri.Scheme contract is to return in lower case only. if (String.Compare(uri.Scheme, PackUriHelper.UriSchemePack, StringComparison.Ordinal) != 0) { throw new ArgumentException(SR.Get(SRID.UriSchemeMismatch, PackUriHelper.UriSchemePack), "uri"); } #if DEBUG if (_traceSwitch.Enabled) { System.Diagnostics.Trace.TraceInformation( DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " + System.Threading.Thread.CurrentThread.ManagedThreadId + ": " + "PackWebRequestFactory - responding to uri: " + uri); } #endif // only inspect cache if part name is present because cache only contains an object, not // the stream it was derived from Uri packageUri; Uri partUri; PackUriHelper.ValidateAndGetPackUriComponents(uri, out packageUri, out partUri); if (partUri != null) { // Note: we look at PreloadedPackages first before we examine the PackageStore // This is to make sure that an app cannot override any predefine packages // match cached object by authority component only - ignore the local path (part name) // inspect local package cache and default to that if possible // All predefined packages such as a package activated by DocumentApplication, // ResourceContainer, and SiteOfOriginContainer are placed in PreloadedPackages bool cachedPackageIsThreadSafe; Package c = PreloadedPackages.GetPackage(packageUri, out cachedPackageIsThreadSafe); // If we don't find anything in the preloaded packages, look into the PackageStore bool cachedPackageIsFromPublicStore = false; if (c == null) { cachedPackageIsThreadSafe = false; // always assume PackageStore packages are not thread-safe cachedPackageIsFromPublicStore = true; // Try to get a package from the package store c = PackageStore.GetPackage(packageUri); } // do we have a package? if (c != null) { #if DEBUG if (_traceSwitch.Enabled) { System.Diagnostics.Trace.TraceInformation( DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " + System.Threading.Thread.CurrentThread.ManagedThreadId + ": " + "PackWebRequestFactory - cache hit - returning CachedPackWebRequest"); } #endif // use the cached object return(new PackWebRequest(uri, packageUri, partUri, c, cachedPackageIsFromPublicStore, cachedPackageIsThreadSafe)); } } #if DEBUG if (_traceSwitch.Enabled) { System.Diagnostics.Trace.TraceInformation( DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " + System.Threading.Thread.CurrentThread.ManagedThreadId + ": " + "PackWebRequestFactory - spawning regular PackWebRequest"); } #endif return(new PackWebRequest(uri, packageUri, partUri)); }
/// <summary> /// Constructs a ZipPackagePart for an interleaved part. This is called outside of streaming /// production when an interleaved part is encountered in the package. /// </summary> /// <param name="container"></param> /// <param name="zipArchive"></param> /// <param name="pieces"></param> /// <param name="partUri"></param> /// <param name="compressionOption"></param> /// <param name="contentType"></param> internal ZipPackagePart(ZipPackage container, ZipArchive zipArchive, List<PieceInfo> pieces, PackUriHelper.ValidatedPartUri partUri, string contentType, CompressionOption compressionOption) :base(container, partUri, contentType, compressionOption) { _zipArchive = zipArchive; _pieces = pieces; }
//------------------------------------------------------ // // Public Events // //------------------------------------------------------ // None //------------------------------------------------------ // // Internal Constructors // //------------------------------------------------------ #region Internal Constructors /// <summary> /// Constructs a ZipPackagePart for an atomic (i.e. non-interleaved) part. /// This is called from the ZipPackage class as a result of GetPartCore, /// GetPartsCore or CreatePartCore methods /// </summary> /// <param name="container"></param> /// <param name="zipFileInfo"></param> /// <param name="partUri"></param> /// <param name="compressionOption"></param> /// <param name="contentType"></param> internal ZipPackagePart(ZipPackage container, ZipFileInfo zipFileInfo, PackUriHelper.ValidatedPartUri partUri, string contentType, CompressionOption compressionOption) :base(container, partUri, contentType, compressionOption) { _zipArchive = zipFileInfo.ZipArchive; _zipFileInfo = zipFileInfo; }
//------------------------------------------------------ // // Internal Events // //------------------------------------------------------ // None //------------------------------------------------------ // // Private Methods // //------------------------------------------------------ #endregion Internal Methods #region Private Methods // This method is only when new part is added to the Package object. // This method will throw an exception if the name of the part being added is a // prefix of the name of an existing part. // Example - Say the following parts exist in the package // 1. /abc.xaml // 2. /xyz/pqr/a.jpg // As an example - Adding any of the following parts will throw an exception - // 1. /abc.xaml/new.xaml // 2. /xyz/pqr private void AddIfNoPrefixCollisionDetected(PackUriHelper.ValidatedPartUri partUri, PackagePart part) { //Add the Normalized Uri to the sorted _partList tentatively to see where it will get inserted _partList.Add(partUri, part); //Get the index of the entry at which this part was added int index = _partList.IndexOfKey(partUri); Debug.Assert(index >= 0, "Given uri must be present in the dictionary"); string normalizedPartName = partUri.NormalizedPartUriString; string precedingPartName = null; string followingPartName = null; if (index > 0) { precedingPartName = _partList.Keys[index - 1].NormalizedPartUriString; } if (index < _partList.Count - 1) { followingPartName = _partList.Keys[index + 1].NormalizedPartUriString; } if ((precedingPartName != null && normalizedPartName.StartsWith(precedingPartName, StringComparison.Ordinal) && normalizedPartName.Length > precedingPartName.Length && normalizedPartName[precedingPartName.Length] == PackUriHelper.ForwardSlashChar) || (followingPartName != null && followingPartName.StartsWith(normalizedPartName, StringComparison.Ordinal) && followingPartName.Length > normalizedPartName.Length && followingPartName[normalizedPartName.Length] == PackUriHelper.ForwardSlashChar)) { //Removing the invalid entry from the _partList. _partList.Remove(partUri); throw new InvalidOperationException(SR.PartNamePrefixExists); } }
/// <summary> /// Add new relationship to the Collection /// </summary> /// <param name="targetUri">target</param> /// <param name="targetMode">Enumeration indicating the base uri for the target uri</param> /// <param name="relationshipType">relationship type that uniquely defines the role of the relationship</param> /// <param name="id">String that conforms to the xsd:ID datatype. Unique across the source's relationships. /// Null OK (ID will be generated).</param> /// <param name="parsing">Indicates whether the add call is made while parsing existing relationships /// from a relationship part, or we are adding a new relationship</param> private PackageRelationship Add(Uri targetUri, TargetMode targetMode, string relationshipType, string id, bool parsing) { if (targetUri == null) { throw new ArgumentNullException("targetUri"); } if (relationshipType == null) { throw new ArgumentNullException("relationshipType"); } ThrowIfInvalidRelationshipType(relationshipType); //Verify if the Enum value is valid if (targetMode < TargetMode.Internal || targetMode > TargetMode.External) { throw new ArgumentOutOfRangeException("targetMode"); } // don't accept absolute Uri's if targetMode is Internal. if (targetMode == TargetMode.Internal && targetUri.IsAbsoluteUri) { throw new ArgumentException(SR.RelationshipTargetMustBeRelative, "targetUri"); } // don't allow relationships to relationships // This check should be made for following cases // 1. Uri is absolute and it is pack Uri // 2. Uri is NOT absolute and its target mode is internal (or NOT external) // Note: if the target is absolute uri and its not a pack scheme then we cannot determine if it is a rels part // Note: if the target is relative uri and target mode is external, we cannot determine if it is a rels part if ((!targetUri.IsAbsoluteUri && targetMode != TargetMode.External) || (targetUri.IsAbsoluteUri && targetUri.Scheme == PackUriHelper.UriSchemePack)) { Uri resolvedUri = GetResolvedTargetUri(targetUri, targetMode); //GetResolvedTargetUri returns a null if the target mode is external and the //target Uri is a packUri with no "part" component, so in that case we know that //its not a relationship part. if (resolvedUri != null) { if (PackUriHelper.IsRelationshipPartUri(resolvedUri)) { throw new ArgumentException(SR.RelationshipToRelationshipIllegal, "targetUri"); } } } // Generate an ID if id is null. Throw exception if neither null nor a valid unique xsd:ID. if (id == null) { id = GenerateUniqueRelationshipId(); } else { ValidateUniqueRelationshipId(id); } //Ensure the relationship part EnsureRelationshipPart(); // create and add PackageRelationship relationship = new PackageRelationship(_package, _sourcePart, targetUri, targetMode, relationshipType, id); _relationships.Add(relationship); //If we are adding relationships as a part of Parsing the underlying relationship part, we should not set //the dirty flag to false. _dirty = !parsing; return(relationship); }
/// <summary> /// rootElement == null: Load elements, validation of root element will occur in caller by checking object type or casting /// rootElement != null: Only perform validation, and expect rootElement at root of markup /// </summary> /// <param name="stream"></param> /// <param name="parentUri"></param> /// <param name="pc"></param> /// <param name="mimeType"></param> /// <param name="rootElement"></param> /// <returns></returns> private object Load(Stream stream, Uri parentUri, ParserContext pc, ContentType mimeType, string rootElement) { object obj = null; if (!DocumentMode) { // Loose XAML, just check against schema, don't check content type if (rootElement == null) { obj = XamlReader.Load(stream, pc); } } else { // inside an XPS Document. Perform maximum validation XpsSchema schema = XpsSchema.GetSchema(mimeType); Uri uri = pc.BaseUri; Uri packageUri = PackUriHelper.GetPackageUri(uri); Uri partUri = PackUriHelper.GetPartUri(uri); Package package = PreloadedPackages.GetPackage(packageUri); Uri parentPackageUri = null; if (parentUri != null) { parentPackageUri = PackUriHelper.GetPackageUri(parentUri); if (!parentPackageUri.Equals(packageUri)) { throw new FileFormatException(SR.Get(SRID.XpsValidatingLoaderUriNotInSamePackage)); } } schema.ValidateRelationships(new SecurityCriticalData <Package>(package), packageUri, partUri, mimeType); if (schema.AllowsMultipleReferencesToSameUri(mimeType)) { _uniqueUriRef = null; } else { _uniqueUriRef = new Hashtable(11); } Hashtable validResources = (_validResources.Count > 0 ? _validResources.Peek() : null); if (schema.HasRequiredResources(mimeType)) { validResources = new Hashtable(11); PackagePart part = package.GetPart(partUri); PackageRelationshipCollection requiredResources = part.GetRelationshipsByType(_requiredResourceRel); foreach (PackageRelationship relationShip in requiredResources) { Uri targetUri = PackUriHelper.ResolvePartUri(partUri, relationShip.TargetUri); Uri absTargetUri = PackUriHelper.Create(packageUri, targetUri); PackagePart targetPart = package.GetPart(targetUri); if (schema.IsValidRequiredResourceMimeType(targetPart.ValidatedContentType())) { if (!validResources.ContainsKey(absTargetUri)) { validResources.Add(absTargetUri, true); } } else { if (!validResources.ContainsKey(absTargetUri)) { validResources.Add(absTargetUri, false); } } } } XpsSchemaValidator xpsSchemaValidator = new XpsSchemaValidator(this, schema, mimeType, stream, packageUri, partUri); _validResources.Push(validResources); if (rootElement != null) { xpsSchemaValidator.XmlReader.MoveToContent(); if (!rootElement.Equals(xpsSchemaValidator.XmlReader.Name)) { throw new FileFormatException(SR.Get(SRID.XpsValidatingLoaderUnsupportedMimeType)); } while (xpsSchemaValidator.XmlReader.Read()) { ; } } else { obj = XamlReader.Load(xpsSchemaValidator.XmlReader, pc, XamlParseMode.Synchronous); } _validResources.Pop(); } return(obj); }