Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Core / System / Windows / Navigation / BaseUriHelper.cs / 3 / BaseUriHelper.cs
// Copyright (c) Microsoft Corporation, 2001 // // File: BaseUriHelper.cs // // // History: 06/21/05 - [....] - created // 07/20/05 - [....] - Move the place // Move the BaseUri helper from Framework // down to core. // 01/31/06: [....] - 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, true); 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
- ConfigurationLocation.cs
- DataListDesigner.cs
- PopOutPanel.cs
- TextProviderWrapper.cs
- Pointer.cs
- ConsoleTraceListener.cs
- TextViewElement.cs
- CallbackTimeoutsBehavior.cs
- ListControl.cs
- RegexParser.cs
- TableRowGroup.cs
- SqlBooleanMismatchVisitor.cs
- BasicBrowserDialog.designer.cs
- DataKeyArray.cs
- SqlTypeSystemProvider.cs
- HttpPostedFile.cs
- ReachObjectContext.cs
- OdbcCommandBuilder.cs
- HttpCachePolicyElement.cs
- TransformCollection.cs
- UICuesEvent.cs
- BamlLocalizabilityResolver.cs
- XhtmlBasicCommandAdapter.cs
- WrappingXamlSchemaContext.cs
- GcHandle.cs
- SmiRequestExecutor.cs
- FakeModelItemImpl.cs
- AlternateViewCollection.cs
- TextContainer.cs
- AuthorizationRule.cs
- ViewStateChangedEventArgs.cs
- ColorPalette.cs
- StreamingContext.cs
- DbBuffer.cs
- mediaeventargs.cs
- BitmapEffectOutputConnector.cs
- PhysicalOps.cs
- InfoCardRSAOAEPKeyExchangeDeformatter.cs
- DesignSurfaceManager.cs
- VisualStyleTypesAndProperties.cs
- XmlSchemaCollection.cs
- PolyLineSegment.cs
- basenumberconverter.cs
- dtdvalidator.cs
- ManagedIStream.cs
- TextDecorationUnitValidation.cs
- PerformanceCounterPermissionEntry.cs
- ErrorFormatter.cs
- RangeBaseAutomationPeer.cs
- EventItfInfo.cs
- SchemaMapping.cs
- FormViewInsertedEventArgs.cs
- ValueChangedEventManager.cs
- TreeNodeMouseHoverEvent.cs
- DataFormats.cs
- AssertFilter.cs
- StatusBar.cs
- SatelliteContractVersionAttribute.cs
- RSAProtectedConfigurationProvider.cs
- HTMLTagNameToTypeMapper.cs
- BuildManagerHost.cs
- TagMapCollection.cs
- CompressEmulationStream.cs
- StringHandle.cs
- EmptyWithCancelationCheckWorkItem.cs
- Validator.cs
- SynchronizedInputAdaptor.cs
- ParserOptions.cs
- MultiView.cs
- SimpleApplicationHost.cs
- DoubleAnimationUsingKeyFrames.cs
- ObjectAssociationEndMapping.cs
- SSmlParser.cs
- TypeSystem.cs
- SettingsAttributeDictionary.cs
- DbDataAdapter.cs
- DataGridViewCheckBoxCell.cs
- TextReturnReader.cs
- ModelMemberCollection.cs
- FontUnit.cs
- GeometryDrawing.cs
- QuinticEase.cs
- HandleCollector.cs
- WebBrowserHelper.cs
- DesignTimeVisibleAttribute.cs
- UnsafeNativeMethods.cs
- ContainerActivationHelper.cs
- XPathItem.cs
- DataGridViewCellCancelEventArgs.cs
- SimplePropertyEntry.cs
- CommandBindingCollection.cs
- PrintingPermissionAttribute.cs
- _DigestClient.cs
- FileFormatException.cs
- SafeLocalMemHandle.cs
- LineUtil.cs
- ChannelOptions.cs
- TripleDESCryptoServiceProvider.cs
- MonthCalendar.cs
- Converter.cs