Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Navigation / BaseUriHelper.cs / 1305600 / BaseUriHelper.cs
// Copyright (c) Microsoft Corporation, 2001 // // File: BaseUriHelper.cs // // // History: 06/21/05 - [....] - created // 07/20/05 - weibz - Move the place // Move the BaseUri helper from Framework // down to core. // 01/31/06: brucemac - Change PreloadedPackages.AddPackage() to pass a boolean indicating // that SiteOfOriginContainer is thread-safe // //------------------------------------------------------------------------------ using System; using System.Diagnostics; using System.IO.Packaging; using System.Globalization; using System.Net; using System.Security; using System.Windows; using System.Windows.Markup; using System.Windows.Media; using System.Reflection; using System.IO; using MS.Internal; using MS.Internal.AppModel; using MS.Internal.IO.Packaging; using MS.Internal.PresentationCore; // In order to avoid generating warnings about unknown message numbers and // unknown pragmas when compiling your C# source code with the actual C# compiler, // you need to disable warnings 1634 and 1691. (Presharp Documentation) #pragma warning disable 1634, 1691 namespace System.Windows.Navigation { ////// BaseUriHelper class provides BaseUri related property, methods. /// public static class BaseUriHelper { private const string SOOBASE = "SiteOfOrigin://"; private static readonly Uri _siteOfOriginBaseUri = PackUriHelper.Create(new Uri(SOOBASE)); private const string APPBASE = "application://"; private static readonly Uri _packAppBaseUri = PackUriHelper.Create(new Uri(APPBASE)); private static SecurityCriticalDataForSet_baseUri; // Cached result of calling // PackUriHelper.GetPackageUri(BaseUriHelper.PackAppBaseUri).GetComponents( // UriComponents.AbsoluteUri, // UriFormat.UriEscaped); private const string _packageApplicationBaseUriEscaped = "application:///"; private const string _packageSiteOfOriginBaseUriEscaped = "siteoforigin:///"; /// /// Critical: because it sets critical data. /// Adds SiteOfOriginContainer to PreloadedPackages. /// TreatAsSafe: because it is the static ctor, and the data doesn't go anywhere. /// SiteOfOriginContainer is a well-known package and allowed to be added /// to PreloadedPackages. Also, the package is not going to be handed out /// from this API surface and as such will be protected /// [SecurityCritical, SecurityTreatAsSafe] static BaseUriHelper() { _baseUri = new SecurityCriticalDataForSet(_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); } #region public property and method /// /// The DependencyProperty for BaseUri of current Element. /// /// Flags: None /// Default Value: null. /// public static readonly DependencyProperty BaseUriProperty = DependencyProperty.RegisterAttached( "BaseUri", typeof(Uri), typeof(BaseUriHelper), new PropertyMetadata((object)null)); ////// Get BaseUri for a dependency object inside a tree. /// /// /// Dependency Object ///BaseUri for the element ////// Callers must have FileIOPermission(FileIOPermissionAccess.PathDiscovery) for the given Uri to call this API. /// ////// Critical: as it access the BaseUri, which is critcal /// PublicOK: calls GetBaseUriCore that does a demand /// Not available from the Internet zone /// [SecurityCritical] public static Uri GetBaseUri(DependencyObject element) { Uri baseUri = GetBaseUriCore(element); // // Manipulate BaseUri after tree searching is done. // if (baseUri == null) { // If no BaseUri information is found from the current tree, // just take the Application's BaseUri. // Application's BaseUri must be an absolute Uri. baseUri = BaseUriHelper.BaseUri; } else { if (baseUri.IsAbsoluteUri == false) { // Most likely the BaseUriDP in element or IUriContext.BaseUri // is set to a relative Uri programmatically in user's code. // For this case, we should resolve this relative Uri to PackAppBase // to generate an absolute Uri. // // BamlRecordReader now always sets absolute Uri for UriContext // element when the tree is generated from baml/xaml stream, this // code path would not run for parser-loaded tree. // baseUri = new Uri(BaseUriHelper.BaseUri, baseUri); } } return baseUri; } #endregion public property and method #region internal properties and methods static internal Uri SiteOfOriginBaseUri { [FriendAccessAllowed] get { return _siteOfOriginBaseUri; } } static internal Uri PackAppBaseUri { [FriendAccessAllowed] get { return _packAppBaseUri; } } ////// Checks whether the input uri is in the "pack://application:,,," form /// 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, PackUriHelper.UriSchemePack) && // Does the "inner" URI have the application: scheme SecurityHelper.AreStringTypesEqual( PackUriHelper.GetPackageUri(uri).GetComponents(UriComponents.AbsoluteUri, UriFormat.UriEscaped), _packageApplicationBaseUriEscaped); } // The method accepts a relative or absolute Uri and returns the appropriate assembly. // // For absolute Uri, it accepts only "pack://application:,,,/...", throw exception for // any other absolute Uri. // // If the first segment of that Uri contains ";component", returns the assembly whose // assembly name matches the text string in the first segment. otherwise, this method // would return EntryAssembly in the AppDomain. // [FriendAccessAllowed] internal static void GetAssemblyAndPartNameFromPackAppUri(Uri uri, out Assembly assembly, out string partName) { // The input Uri is assumed to be a valid absolute pack application Uri. // The caller should guarantee that. // Perform a sanity check to make sure the assumption stays. Debug.Assert(uri != null && uri.IsAbsoluteUri && SecurityHelper.AreStringTypesEqual(uri.Scheme, PackUriHelper.UriSchemePack) && IsPackApplicationUri(uri)); // Generate a relative Uri which gets rid of the pack://application:,,, authority part. Uri partUri = new Uri(uri.AbsolutePath, UriKind.Relative); string assemblyName; string assemblyVersion; string assemblyKey; GetAssemblyNameAndPart(partUri, out partName, out assemblyName, out assemblyVersion, out assemblyKey); if (String.IsNullOrEmpty(assemblyName)) { // The uri doesn't contain ";component". it should map to the enty application assembly. assembly = ResourceAssembly; // The partName returned from GetAssemblyNameAndPart should be escaped. Debug.Assert(String.Compare(partName, uri.GetComponents(UriComponents.Path, UriFormat.UriEscaped), StringComparison.OrdinalIgnoreCase) == 0); } else { assembly = GetLoadedAssembly(assemblyName, assemblyVersion, assemblyKey); } } // // [FriendAccessAllowed] internal static Assembly GetLoadedAssembly(string assemblyName, string assemblyVersion, string assemblyKey) { Assembly assembly; AssemblyName asmName = new AssemblyName(assemblyName); // We always use the primary assembly (culture neutral) for resource manager. // if the required resource lives in satellite assembly, ResourceManager can find // the right satellite assembly later. asmName.CultureInfo = new CultureInfo(String.Empty); if (!String.IsNullOrEmpty(assemblyVersion)) { asmName.Version = new Version(assemblyVersion); } if (!String.IsNullOrEmpty(assemblyKey)) { int byteCount = assemblyKey.Length / 2; byte[] keyToken = new byte[byteCount]; for (int i = 0; i < byteCount; i++) { string byteString = assemblyKey.Substring(i * 2, 2); keyToken[i] = byte.Parse(byteString, NumberStyles.HexNumber, CultureInfo.InvariantCulture); } asmName.SetPublicKeyToken(keyToken); } assembly = SafeSecurityHelper.GetLoadedAssembly(asmName); if (assembly == null) { // The assembly is not yet loaded to the AppDomain, try to load it with information specified in resource Uri. assembly = Assembly.Load(asmName); } return assembly; } // // Return assembly Name, Version, Key and package Part from a relative Uri. // [FriendAccessAllowed] internal static void GetAssemblyNameAndPart(Uri uri, out string partName, out string assemblyName, out string assemblyVersion, out string assemblyKey) { Invariant.Assert(uri != null && uri.IsAbsoluteUri == false, "This method accepts relative uri only."); string original = uri.ToString(); // only relative Uri here (enforced by Package) // Start and end points for the first segment in the Uri. int start = 0; int end; if (original[0] == '/') { start = 1; } partName = original.Substring(start); assemblyName = string.Empty; assemblyVersion = string.Empty; assemblyKey = string.Empty; end = original.IndexOf('/', start); string firstSegment = String.Empty; bool fHasComponent = false; if (end > 0) { // get the first section firstSegment = original.Substring(start, end - start); // The resource comes from dll if (firstSegment.EndsWith(COMPONENT, StringComparison.OrdinalIgnoreCase)) { partName = original.Substring(end + 1); fHasComponent = true; } } if (fHasComponent) { string[] assemblyInfo = firstSegment.Split(new char[] { COMPONENT_DELIMITER }); int count = assemblyInfo.Length; if ((count > 4) || (count < 2)) { throw new UriFormatException(SR.Get(SRID.WrongFirstSegment)); } // // if the uri contains escaping character, // Convert it back to normal unicode string // so that the string as assembly name can be // recognized by Assembly.Load later. // assemblyName = Uri.UnescapeDataString(assemblyInfo[0]); for (int i = 1; i < count - 1; i++) { if (assemblyInfo[i].StartsWith(VERSION, StringComparison.OrdinalIgnoreCase)) { if (string.IsNullOrEmpty(assemblyVersion)) { assemblyVersion = assemblyInfo[i].Substring(1); // Get rid of the leading "v" } else { throw new UriFormatException(SR.Get(SRID.WrongFirstSegment)); } } else { if (string.IsNullOrEmpty(assemblyKey)) { assemblyKey = assemblyInfo[i]; } else { throw new UriFormatException(SR.Get(SRID.WrongFirstSegment)); } } } // end of for loop } // end of if fHasComponent } [FriendAccessAllowed] static internal bool IsComponentEntryAssembly(string component) { if (component.EndsWith(COMPONENT, StringComparison.OrdinalIgnoreCase)) { string[] assemblyInfo = component.Split(new Char[] { COMPONENT_DELIMITER }); // Check whether the assembly name is the same as the EntryAssembly. int count = assemblyInfo.Length; if ((count >= 2) && (count <= 4)) { string assemblyName = Uri.UnescapeDataString(assemblyInfo[0]); Assembly assembly = ResourceAssembly; if (assembly != null) { return (String.Compare(SafeSecurityHelper.GetAssemblyPartialName(assembly), assemblyName, StringComparison.OrdinalIgnoreCase) == 0); } else { return false; } } } return false; } [FriendAccessAllowed] static internal Uri GetResolvedUri(Uri baseUri, Uri orgUri) { return new Uri(baseUri, orgUri); } [FriendAccessAllowed] static internal Uri MakeRelativeToSiteOfOriginIfPossible(Uri sUri) { if (Uri.Compare(sUri, SiteOfOriginBaseUri, UriComponents.Scheme, UriFormat.UriEscaped, StringComparison.OrdinalIgnoreCase) == 0) { Uri packageUri; Uri partUri; PackUriHelper.ValidateAndGetPackUriComponents(sUri, out packageUri, out partUri); 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; } [FriendAccessAllowed] static internal Uri ConvertPackUriToAbsoluteExternallyVisibleUri(Uri packUri) { Invariant.Assert(packUri.IsAbsoluteUri && SecurityHelper.AreStringTypesEqual(packUri.Scheme, PackAppBaseUri.Scheme)); Uri relative = MakeRelativeToSiteOfOriginIfPossible(packUri); if (! relative.IsAbsoluteUri) { return new Uri(SiteOfOriginContainer.SiteOfOrigin, relative); } else { throw new InvalidOperationException(SR.Get(SRID.CannotNavigateToApplicationResourcesInWebBrowser, packUri)); } } // If a Uri is constructed with a legacy path such as c:\foo\bar then the Uri // object will not correctly resolve relative Uris in some cases. This method // detects and fixes this by constructing a new Uri with an original string // that contains the scheme file://. [FriendAccessAllowed] static internal Uri FixFileUri(Uri uri) { if (uri != null && uri.IsAbsoluteUri && SecurityHelper.AreStringTypesEqual(uri.Scheme, Uri.UriSchemeFile) && string.Compare(uri.OriginalString, 0, Uri.UriSchemeFile, 0, Uri.UriSchemeFile.Length, StringComparison.OrdinalIgnoreCase) != 0) { return new Uri(uri.AbsoluteUri); } return uri; } ////// Critical: as it sets the baseUri /// static internal Uri BaseUri { [FriendAccessAllowed] get { return _baseUri.Value; } [FriendAccessAllowed] [SecurityCritical] set { // This setter should only be called from Framework through // BindUriHelper.set_BaseUri. _baseUri.Value = value; } } static internal Assembly ResourceAssembly { get { if (_resourceAssembly == null) { _resourceAssembly = Assembly.GetEntryAssembly(); } return _resourceAssembly; } [FriendAccessAllowed] set { // This should only be called from Framework through Application.ResourceAssembly setter. _resourceAssembly = value; } } #endregion internal properties and methods #region private methods ////// Get BaseUri for a dependency object inside a tree. /// /// /// Dependency Object ///BaseUri for the element ////// Callers must have FileIOPermission(FileIOPermissionAccess.PathDiscovery) for the given Uri to call this API. /// ////// Critical: as it access the BaseUri, which is critcal /// TreatAsSafe: since it demands File read write and path dicovery permission. /// [SecurityCritical, SecurityTreatAsSafe] internal static Uri GetBaseUriCore(DependencyObject element) { Uri baseUri = null; DependencyObject doCurrent; if (element == null) { throw new ArgumentNullException("element"); } try { // // Search the tree to find the closest parent which implements // IUriContext or have set value for BaseUri property. // doCurrent = element; while (doCurrent != null) { // Try to get BaseUri property value from current node. baseUri = doCurrent.GetValue(BaseUriProperty) as Uri; if (baseUri != null) { // Got the right node which is the closest to original element. // Stop searching here. break; } IUriContext uriContext = doCurrent as IUriContext; if (uriContext != null) { // If the element implements IUriContext, and if the BaseUri // is not null, just take the BaseUri from there. // and stop the search loop. baseUri = uriContext.BaseUri; if (baseUri != null) break; } // // The current node doesn't contain BaseUri value, // try its parent node in the tree. UIElement uie = doCurrent as UIElement; if (uie != null) { // Do the tree walk up doCurrent = uie.GetUIParent(true); } else { ContentElement ce = doCurrent as ContentElement; if (ce != null) { doCurrent = ce.Parent; } else { Visual vis = doCurrent as Visual; if (vis != null) { // Try the Visual tree search doCurrent = VisualTreeHelper.GetParent(vis); } else { // Not a Visual. // Stop here for the tree searching to aviod an infinite loop. break; } } } } } finally { // // Putting the permission demand in finally block can prevent from exposing a bogus // and dangerous uri to the code in upper frame. // if (baseUri != null) { SecurityHelper.DemandUriDiscoveryPermission(baseUri); } } return baseUri; } #endregion private const string COMPONENT = ";component"; private const string VERSION = "v"; private const char COMPONENT_DELIMITER = ';'; private static Assembly _resourceAssembly; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation, 2001 // // File: BaseUriHelper.cs // // // History: 06/21/05 - [....] - created // 07/20/05 - weibz - Move the place // Move the BaseUri helper from Framework // down to core. // 01/31/06: brucemac - Change PreloadedPackages.AddPackage() to pass a boolean indicating // that SiteOfOriginContainer is thread-safe // //------------------------------------------------------------------------------ using System; using System.Diagnostics; using System.IO.Packaging; using System.Globalization; using System.Net; using System.Security; using System.Windows; using System.Windows.Markup; using System.Windows.Media; using System.Reflection; using System.IO; using MS.Internal; using MS.Internal.AppModel; using MS.Internal.IO.Packaging; using MS.Internal.PresentationCore; // In order to avoid generating warnings about unknown message numbers and // unknown pragmas when compiling your C# source code with the actual C# compiler, // you need to disable warnings 1634 and 1691. (Presharp Documentation) #pragma warning disable 1634, 1691 namespace System.Windows.Navigation { ////// BaseUriHelper class provides BaseUri related property, methods. /// public static class BaseUriHelper { private const string SOOBASE = "SiteOfOrigin://"; private static readonly Uri _siteOfOriginBaseUri = PackUriHelper.Create(new Uri(SOOBASE)); private const string APPBASE = "application://"; private static readonly Uri _packAppBaseUri = PackUriHelper.Create(new Uri(APPBASE)); private static SecurityCriticalDataForSet_baseUri; // Cached result of calling // PackUriHelper.GetPackageUri(BaseUriHelper.PackAppBaseUri).GetComponents( // UriComponents.AbsoluteUri, // UriFormat.UriEscaped); private const string _packageApplicationBaseUriEscaped = "application:///"; private const string _packageSiteOfOriginBaseUriEscaped = "siteoforigin:///"; /// /// Critical: because it sets critical data. /// Adds SiteOfOriginContainer to PreloadedPackages. /// TreatAsSafe: because it is the static ctor, and the data doesn't go anywhere. /// SiteOfOriginContainer is a well-known package and allowed to be added /// to PreloadedPackages. Also, the package is not going to be handed out /// from this API surface and as such will be protected /// [SecurityCritical, SecurityTreatAsSafe] static BaseUriHelper() { _baseUri = new SecurityCriticalDataForSet(_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); } #region public property and method /// /// The DependencyProperty for BaseUri of current Element. /// /// Flags: None /// Default Value: null. /// public static readonly DependencyProperty BaseUriProperty = DependencyProperty.RegisterAttached( "BaseUri", typeof(Uri), typeof(BaseUriHelper), new PropertyMetadata((object)null)); ////// Get BaseUri for a dependency object inside a tree. /// /// /// Dependency Object ///BaseUri for the element ////// Callers must have FileIOPermission(FileIOPermissionAccess.PathDiscovery) for the given Uri to call this API. /// ////// Critical: as it access the BaseUri, which is critcal /// PublicOK: calls GetBaseUriCore that does a demand /// Not available from the Internet zone /// [SecurityCritical] public static Uri GetBaseUri(DependencyObject element) { Uri baseUri = GetBaseUriCore(element); // // Manipulate BaseUri after tree searching is done. // if (baseUri == null) { // If no BaseUri information is found from the current tree, // just take the Application's BaseUri. // Application's BaseUri must be an absolute Uri. baseUri = BaseUriHelper.BaseUri; } else { if (baseUri.IsAbsoluteUri == false) { // Most likely the BaseUriDP in element or IUriContext.BaseUri // is set to a relative Uri programmatically in user's code. // For this case, we should resolve this relative Uri to PackAppBase // to generate an absolute Uri. // // BamlRecordReader now always sets absolute Uri for UriContext // element when the tree is generated from baml/xaml stream, this // code path would not run for parser-loaded tree. // baseUri = new Uri(BaseUriHelper.BaseUri, baseUri); } } return baseUri; } #endregion public property and method #region internal properties and methods static internal Uri SiteOfOriginBaseUri { [FriendAccessAllowed] get { return _siteOfOriginBaseUri; } } static internal Uri PackAppBaseUri { [FriendAccessAllowed] get { return _packAppBaseUri; } } ////// Checks whether the input uri is in the "pack://application:,,," form /// 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, PackUriHelper.UriSchemePack) && // Does the "inner" URI have the application: scheme SecurityHelper.AreStringTypesEqual( PackUriHelper.GetPackageUri(uri).GetComponents(UriComponents.AbsoluteUri, UriFormat.UriEscaped), _packageApplicationBaseUriEscaped); } // The method accepts a relative or absolute Uri and returns the appropriate assembly. // // For absolute Uri, it accepts only "pack://application:,,,/...", throw exception for // any other absolute Uri. // // If the first segment of that Uri contains ";component", returns the assembly whose // assembly name matches the text string in the first segment. otherwise, this method // would return EntryAssembly in the AppDomain. // [FriendAccessAllowed] internal static void GetAssemblyAndPartNameFromPackAppUri(Uri uri, out Assembly assembly, out string partName) { // The input Uri is assumed to be a valid absolute pack application Uri. // The caller should guarantee that. // Perform a sanity check to make sure the assumption stays. Debug.Assert(uri != null && uri.IsAbsoluteUri && SecurityHelper.AreStringTypesEqual(uri.Scheme, PackUriHelper.UriSchemePack) && IsPackApplicationUri(uri)); // Generate a relative Uri which gets rid of the pack://application:,,, authority part. Uri partUri = new Uri(uri.AbsolutePath, UriKind.Relative); string assemblyName; string assemblyVersion; string assemblyKey; GetAssemblyNameAndPart(partUri, out partName, out assemblyName, out assemblyVersion, out assemblyKey); if (String.IsNullOrEmpty(assemblyName)) { // The uri doesn't contain ";component". it should map to the enty application assembly. assembly = ResourceAssembly; // The partName returned from GetAssemblyNameAndPart should be escaped. Debug.Assert(String.Compare(partName, uri.GetComponents(UriComponents.Path, UriFormat.UriEscaped), StringComparison.OrdinalIgnoreCase) == 0); } else { assembly = GetLoadedAssembly(assemblyName, assemblyVersion, assemblyKey); } } // // [FriendAccessAllowed] internal static Assembly GetLoadedAssembly(string assemblyName, string assemblyVersion, string assemblyKey) { Assembly assembly; AssemblyName asmName = new AssemblyName(assemblyName); // We always use the primary assembly (culture neutral) for resource manager. // if the required resource lives in satellite assembly, ResourceManager can find // the right satellite assembly later. asmName.CultureInfo = new CultureInfo(String.Empty); if (!String.IsNullOrEmpty(assemblyVersion)) { asmName.Version = new Version(assemblyVersion); } if (!String.IsNullOrEmpty(assemblyKey)) { int byteCount = assemblyKey.Length / 2; byte[] keyToken = new byte[byteCount]; for (int i = 0; i < byteCount; i++) { string byteString = assemblyKey.Substring(i * 2, 2); keyToken[i] = byte.Parse(byteString, NumberStyles.HexNumber, CultureInfo.InvariantCulture); } asmName.SetPublicKeyToken(keyToken); } assembly = SafeSecurityHelper.GetLoadedAssembly(asmName); if (assembly == null) { // The assembly is not yet loaded to the AppDomain, try to load it with information specified in resource Uri. assembly = Assembly.Load(asmName); } return assembly; } // // Return assembly Name, Version, Key and package Part from a relative Uri. // [FriendAccessAllowed] internal static void GetAssemblyNameAndPart(Uri uri, out string partName, out string assemblyName, out string assemblyVersion, out string assemblyKey) { Invariant.Assert(uri != null && uri.IsAbsoluteUri == false, "This method accepts relative uri only."); string original = uri.ToString(); // only relative Uri here (enforced by Package) // Start and end points for the first segment in the Uri. int start = 0; int end; if (original[0] == '/') { start = 1; } partName = original.Substring(start); assemblyName = string.Empty; assemblyVersion = string.Empty; assemblyKey = string.Empty; end = original.IndexOf('/', start); string firstSegment = String.Empty; bool fHasComponent = false; if (end > 0) { // get the first section firstSegment = original.Substring(start, end - start); // The resource comes from dll if (firstSegment.EndsWith(COMPONENT, StringComparison.OrdinalIgnoreCase)) { partName = original.Substring(end + 1); fHasComponent = true; } } if (fHasComponent) { string[] assemblyInfo = firstSegment.Split(new char[] { COMPONENT_DELIMITER }); int count = assemblyInfo.Length; if ((count > 4) || (count < 2)) { throw new UriFormatException(SR.Get(SRID.WrongFirstSegment)); } // // if the uri contains escaping character, // Convert it back to normal unicode string // so that the string as assembly name can be // recognized by Assembly.Load later. // assemblyName = Uri.UnescapeDataString(assemblyInfo[0]); for (int i = 1; i < count - 1; i++) { if (assemblyInfo[i].StartsWith(VERSION, StringComparison.OrdinalIgnoreCase)) { if (string.IsNullOrEmpty(assemblyVersion)) { assemblyVersion = assemblyInfo[i].Substring(1); // Get rid of the leading "v" } else { throw new UriFormatException(SR.Get(SRID.WrongFirstSegment)); } } else { if (string.IsNullOrEmpty(assemblyKey)) { assemblyKey = assemblyInfo[i]; } else { throw new UriFormatException(SR.Get(SRID.WrongFirstSegment)); } } } // end of for loop } // end of if fHasComponent } [FriendAccessAllowed] static internal bool IsComponentEntryAssembly(string component) { if (component.EndsWith(COMPONENT, StringComparison.OrdinalIgnoreCase)) { string[] assemblyInfo = component.Split(new Char[] { COMPONENT_DELIMITER }); // Check whether the assembly name is the same as the EntryAssembly. int count = assemblyInfo.Length; if ((count >= 2) && (count <= 4)) { string assemblyName = Uri.UnescapeDataString(assemblyInfo[0]); Assembly assembly = ResourceAssembly; if (assembly != null) { return (String.Compare(SafeSecurityHelper.GetAssemblyPartialName(assembly), assemblyName, StringComparison.OrdinalIgnoreCase) == 0); } else { return false; } } } return false; } [FriendAccessAllowed] static internal Uri GetResolvedUri(Uri baseUri, Uri orgUri) { return new Uri(baseUri, orgUri); } [FriendAccessAllowed] static internal Uri MakeRelativeToSiteOfOriginIfPossible(Uri sUri) { if (Uri.Compare(sUri, SiteOfOriginBaseUri, UriComponents.Scheme, UriFormat.UriEscaped, StringComparison.OrdinalIgnoreCase) == 0) { Uri packageUri; Uri partUri; PackUriHelper.ValidateAndGetPackUriComponents(sUri, out packageUri, out partUri); 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; } [FriendAccessAllowed] static internal Uri ConvertPackUriToAbsoluteExternallyVisibleUri(Uri packUri) { Invariant.Assert(packUri.IsAbsoluteUri && SecurityHelper.AreStringTypesEqual(packUri.Scheme, PackAppBaseUri.Scheme)); Uri relative = MakeRelativeToSiteOfOriginIfPossible(packUri); if (! relative.IsAbsoluteUri) { return new Uri(SiteOfOriginContainer.SiteOfOrigin, relative); } else { throw new InvalidOperationException(SR.Get(SRID.CannotNavigateToApplicationResourcesInWebBrowser, packUri)); } } // If a Uri is constructed with a legacy path such as c:\foo\bar then the Uri // object will not correctly resolve relative Uris in some cases. This method // detects and fixes this by constructing a new Uri with an original string // that contains the scheme file://. [FriendAccessAllowed] static internal Uri FixFileUri(Uri uri) { if (uri != null && uri.IsAbsoluteUri && SecurityHelper.AreStringTypesEqual(uri.Scheme, Uri.UriSchemeFile) && string.Compare(uri.OriginalString, 0, Uri.UriSchemeFile, 0, Uri.UriSchemeFile.Length, StringComparison.OrdinalIgnoreCase) != 0) { return new Uri(uri.AbsoluteUri); } return uri; } ////// Critical: as it sets the baseUri /// static internal Uri BaseUri { [FriendAccessAllowed] get { return _baseUri.Value; } [FriendAccessAllowed] [SecurityCritical] set { // This setter should only be called from Framework through // BindUriHelper.set_BaseUri. _baseUri.Value = value; } } static internal Assembly ResourceAssembly { get { if (_resourceAssembly == null) { _resourceAssembly = Assembly.GetEntryAssembly(); } return _resourceAssembly; } [FriendAccessAllowed] set { // This should only be called from Framework through Application.ResourceAssembly setter. _resourceAssembly = value; } } #endregion internal properties and methods #region private methods ////// Get BaseUri for a dependency object inside a tree. /// /// /// Dependency Object ///BaseUri for the element ////// Callers must have FileIOPermission(FileIOPermissionAccess.PathDiscovery) for the given Uri to call this API. /// ////// Critical: as it access the BaseUri, which is critcal /// TreatAsSafe: since it demands File read write and path dicovery permission. /// [SecurityCritical, SecurityTreatAsSafe] internal static Uri GetBaseUriCore(DependencyObject element) { Uri baseUri = null; DependencyObject doCurrent; if (element == null) { throw new ArgumentNullException("element"); } try { // // Search the tree to find the closest parent which implements // IUriContext or have set value for BaseUri property. // doCurrent = element; while (doCurrent != null) { // Try to get BaseUri property value from current node. baseUri = doCurrent.GetValue(BaseUriProperty) as Uri; if (baseUri != null) { // Got the right node which is the closest to original element. // Stop searching here. break; } IUriContext uriContext = doCurrent as IUriContext; if (uriContext != null) { // If the element implements IUriContext, and if the BaseUri // is not null, just take the BaseUri from there. // and stop the search loop. baseUri = uriContext.BaseUri; if (baseUri != null) break; } // // The current node doesn't contain BaseUri value, // try its parent node in the tree. UIElement uie = doCurrent as UIElement; if (uie != null) { // Do the tree walk up doCurrent = uie.GetUIParent(true); } else { ContentElement ce = doCurrent as ContentElement; if (ce != null) { doCurrent = ce.Parent; } else { Visual vis = doCurrent as Visual; if (vis != null) { // Try the Visual tree search doCurrent = VisualTreeHelper.GetParent(vis); } else { // Not a Visual. // Stop here for the tree searching to aviod an infinite loop. break; } } } } } finally { // // Putting the permission demand in finally block can prevent from exposing a bogus // and dangerous uri to the code in upper frame. // if (baseUri != null) { SecurityHelper.DemandUriDiscoveryPermission(baseUri); } } return baseUri; } #endregion private const string COMPONENT = ";component"; private const string VERSION = "v"; private const char COMPONENT_DELIMITER = ';'; private static Assembly _resourceAssembly; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- CellParaClient.cs
- EditorAttribute.cs
- DataGridViewUtilities.cs
- FontFamilyIdentifier.cs
- RegionInfo.cs
- Matrix3D.cs
- ObjectAnimationBase.cs
- TypedDataSetSchemaImporterExtensionFx35.cs
- SyndicationPerson.cs
- ReflectionTypeLoadException.cs
- DbConnectionPoolIdentity.cs
- UTF32Encoding.cs
- _AuthenticationState.cs
- IPAddress.cs
- MultiByteCodec.cs
- RuleSettings.cs
- UICuesEvent.cs
- CommandExpr.cs
- BitConverter.cs
- CodeDirectionExpression.cs
- HtmlTable.cs
- HMACSHA1.cs
- AsyncOperationContext.cs
- BitmapEffect.cs
- ToolStripRendererSwitcher.cs
- TypefaceMap.cs
- DeclarativeCatalogPartDesigner.cs
- PartialTrustVisibleAssemblyCollection.cs
- CallbackValidatorAttribute.cs
- PixelFormat.cs
- X509Utils.cs
- IsolatedStoragePermission.cs
- SyndicationLink.cs
- ConstructorBuilder.cs
- SqlMethodCallConverter.cs
- LeaseManager.cs
- ListBox.cs
- ToolboxItemAttribute.cs
- UICuesEvent.cs
- UnsafeNativeMethodsTablet.cs
- HwndStylusInputProvider.cs
- TableParaClient.cs
- GeneralTransform3DCollection.cs
- ObjectQueryState.cs
- Msec.cs
- DrawingContextDrawingContextWalker.cs
- NamespaceDecl.cs
- ParenthesizePropertyNameAttribute.cs
- EditCommandColumn.cs
- RecordConverter.cs
- DocumentGridContextMenu.cs
- odbcmetadatacolumnnames.cs
- MailWebEventProvider.cs
- TemplatedEditableDesignerRegion.cs
- ColumnProvider.cs
- SortDescription.cs
- ExpressionBuilderContext.cs
- OdbcDataAdapter.cs
- FormatVersion.cs
- X509SecurityToken.cs
- ACL.cs
- TagMapCollection.cs
- ZipIOLocalFileBlock.cs
- updatecommandorderer.cs
- WebService.cs
- EventProviderClassic.cs
- ApplicationSecurityManager.cs
- SystemIcmpV4Statistics.cs
- RangeContentEnumerator.cs
- SQLCharsStorage.cs
- Parser.cs
- Relationship.cs
- SecurityAlgorithmSuite.cs
- ValueProviderWrapper.cs
- ItemCheckEvent.cs
- FormsIdentity.cs
- EraserBehavior.cs
- LiteralSubsegment.cs
- VectorCollection.cs
- DataGridViewDataErrorEventArgs.cs
- BStrWrapper.cs
- DependencyPropertyValueSerializer.cs
- OutputCacheSettings.cs
- DynamicHyperLink.cs
- X509ChainPolicy.cs
- MapPathBasedVirtualPathProvider.cs
- PagesSection.cs
- XNameConverter.cs
- ImmComposition.cs
- SecurityContext.cs
- DataColumnMappingCollection.cs
- StrokeNodeData.cs
- OleServicesContext.cs
- VisualStateChangedEventArgs.cs
- LongValidatorAttribute.cs
- AppDomain.cs
- ExecutionScope.cs
- SafeRegistryHandle.cs
- RijndaelManagedTransform.cs
- BinaryReader.cs