Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Shared / MS / Internal / IO / Packaging / PackagingUtilities.cs / 1 / PackagingUtilities.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // // History: // 05/13/2004: [....] Creation // //--------------------------------------------------------------------------- using System; using System.IO; using System.IO.IsolatedStorage; using MS.Internal.WindowsBase; // FriendAccessAllowed using System.Xml; // For XmlReader using System.Diagnostics; // For Debug.Assert using System.Text; // For Encoding using System.Windows; // For Exception strings - SRID using System.Security; // for SecurityCritical using System.Security.Permissions; // for permissions using Microsoft.Win32; // for Registry classes using MS.Internal; namespace MS.Internal.IO.Packaging { [FriendAccessAllowed] // Built into Base, used by Framework and Core internal static class PackagingUtilities { //----------------------------------------------------- // // Internal Fields // //----------------------------------------------------- internal static readonly string RelationshipNamespaceUri = "http://schemas.openxmlformats.org/package/2006/relationships"; internal static readonly ContentType RelationshipPartContentType = new ContentType("application/vnd.openxmlformats-package.relationships+xml"); internal const string ContainerFileExtension = "xps"; internal const string XamlFileExtension = "xaml"; //------------------------------------------------------ // // Internal Properties // //----------------------------------------------------- //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods ////// This method is used to determine if we support a given Encoding as per the /// OPC and XPS specs. Currently the only two encodings supported are UTF-8 and /// UTF-16 (Little Endian and Big Endian) /// /// XmlTextReader ///throws an exception if the encoding is not UTF-8 or UTF-16 internal static void PerformInitailReadAndVerifyEncoding(XmlTextReader reader) { Invariant.Assert(reader != null && reader.ReadState == ReadState.Initial); //If the first node is XmlDeclaration we check to see if the encoding attribute is present if (reader.Read() && reader.NodeType == XmlNodeType.XmlDeclaration && reader.Depth == 0) { string encoding; encoding = reader.GetAttribute(_encodingAttribute); if (encoding != null && encoding.Length > 0) { encoding = encoding.ToUpperInvariant(); //If a non-empty encoding attribute is present [for example - ] //we check to see if the value is either "utf-8" or utf-16. Only these two values are supported //Note: For Byte order markings that require additional information to be specified in //the encoding attribute in XmlDeclaration have already been ruled out by this check as we allow for //only two valid values. if (String.CompareOrdinal(encoding, _webNameUTF8) == 0 || String.CompareOrdinal(encoding, _webNameUnicode) == 0) return; else //if the encoding attribute has any other value we throw an exception throw new FileFormatException(SR.Get(SRID.EncodingNotSupported)); } } //if the XmlDeclaration is not present, or encoding attribute is not present, we //base our decision on byte order marking. reader.Encoding will take that into account //and return the correct value. //Note: For Byte order markings that require additional information to be specified in //the encoding attribute in XmlDeclaration have already been ruled out by the check above. //Note: If not encoding attribute is present or no byte order marking is present the //encoding default to UTF8 if (!(reader.Encoding is UnicodeEncoding || reader.Encoding is UTF8Encoding)) throw new FileFormatException(SR.Get(SRID.EncodingNotSupported)); } ////// VerifyStreamReadArgs /// /// stream /// buffer /// offset /// count ///Common argument verification for Stream.Read() static internal void VerifyStreamReadArgs(Stream s, byte[] buffer, int offset, int count) { if (!s.CanRead) throw new NotSupportedException(SR.Get(SRID.ReadNotSupported)); if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset", SR.Get(SRID.OffsetNegative)); } if (count < 0) { throw new ArgumentOutOfRangeException("count", SR.Get(SRID.ReadCountNegative)); } checked // catch any integer overflows { if (offset + count > buffer.Length) { throw new ArgumentException(SR.Get(SRID.ReadBufferTooSmall), "buffer"); } } } ////// VerifyStreamWriteArgs /// /// /// /// /// ///common argument verification for Stream.Write static internal void VerifyStreamWriteArgs(Stream s, byte[] buffer, int offset, int count) { if (!s.CanWrite) throw new NotSupportedException(SR.Get(SRID.WriteNotSupported)); if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset", SR.Get(SRID.OffsetNegative)); } if (count < 0) { throw new ArgumentOutOfRangeException("count", SR.Get(SRID.WriteCountNegative)); } checked { if (offset + count > buffer.Length) throw new ArgumentException(SR.Get(SRID.WriteBufferTooSmall), "buffer"); } } ////// Read utility that is guaranteed to return the number of bytes requested /// if they are available. /// /// stream to read from /// buffer to read into /// offset in buffer to write to /// bytes to read ///bytes read ///Normal Stream.Read does not guarantee how many bytes it will /// return. This one does. internal static int ReliableRead(Stream stream, byte[] buffer, int offset, int count) { return ReliableRead(stream, buffer, offset, count, count); } ////// Read utility that is guaranteed to return the number of bytes requested /// if they are available. /// /// stream to read from /// buffer to read into /// offset in buffer to write to /// count of bytes that we would like to read (max read size to try) /// minimal count of bytes that we would like to read (min read size to achieve) ///bytes read ///Normal Stream.Read does not guarantee how many bytes it will /// return. This one does. internal static int ReliableRead(Stream stream, byte[] buffer, int offset, int requestedCount, int requiredCount) { Invariant.Assert(stream != null); Invariant.Assert(buffer != null); Invariant.Assert(buffer.Length > 0); Invariant.Assert(offset >= 0); Invariant.Assert(requestedCount >= 0); Invariant.Assert(requiredCount >= 0); Invariant.Assert(checked(offset + requestedCount <= buffer.Length)); Invariant.Assert(requiredCount <= requestedCount); // let's read the whole block into our buffer int totalBytesRead = 0; while (totalBytesRead < requiredCount) { int bytesRead = stream.Read(buffer, offset + totalBytesRead, requestedCount - totalBytesRead); if (bytesRead == 0) { break; } totalBytesRead += bytesRead; } return totalBytesRead; } ////// Read utility that is guaranteed to return the number of bytes requested /// if they are available. /// /// BinaryReader to read from /// buffer to read into /// offset in buffer to write to /// bytes to read ///bytes read ///Normal Stream.Read does not guarantee how many bytes it will /// return. This one does. internal static int ReliableRead(BinaryReader reader, byte[] buffer, int offset, int count) { return ReliableRead(reader, buffer, offset, count, count); } ////// Read utility that is guaranteed to return the number of bytes requested /// if they are available. /// /// BinaryReader to read from /// buffer to read into /// offset in buffer to write to /// count of bytes that we would like to read (max read size to try) /// minimal count of bytes that we would like to read (min read size to achieve) ///bytes read ///Normal Stream.Read does not guarantee how many bytes it will /// return. This one does. internal static int ReliableRead(BinaryReader reader, byte[] buffer, int offset, int requestedCount, int requiredCount) { Invariant.Assert(reader != null); Invariant.Assert(buffer != null); Invariant.Assert(buffer.Length > 0); Invariant.Assert(offset >= 0); Invariant.Assert(requestedCount >= 0); Invariant.Assert(requiredCount >= 0); Invariant.Assert(checked(offset + requestedCount <= buffer.Length)); Invariant.Assert(requiredCount <= requestedCount); // let's read the whole block into our buffer int totalBytesRead = 0; while (totalBytesRead < requiredCount) { int bytesRead = reader.Read(buffer, offset + totalBytesRead, requestedCount - totalBytesRead); if (bytesRead == 0) { break; } totalBytesRead += bytesRead; } return totalBytesRead; } ////// CopyStream utility that is guaranteed to return the number of bytes copied (may be less then requested, /// if source stream doesn't have enough data) /// /// stream to read from /// stream to write to /// number of bytes to be copied(use Int64.MaxValue if the whole stream needs to be copied) /// number of bytes to be copied (usually it is 4K for scenarios where we expect a lot of data /// like in SparseMemoryStream case it could be larger ///bytes copied (might be less than requested if source stream is too short ///Neither source nor target stream are seeked; it is up to the caller to make sure that their positions are properly set. /// Target stream isn't truncated even if it has more data past the area that was copied. internal static long CopyStream(Stream sourceStream, Stream targetStream, long bytesToCopy, int bufferSize) { Invariant.Assert(sourceStream != null); Invariant.Assert(targetStream != null); Invariant.Assert(bytesToCopy >= 0); Invariant.Assert(bufferSize > 0); byte[] buffer = new byte[bufferSize]; // let's read the whole block into our buffer long bytesLeftToCopy = bytesToCopy; while (bytesLeftToCopy > 0) { int bytesRead = sourceStream.Read(buffer, 0, (int)Math.Min(bytesLeftToCopy, (long)bufferSize)); if (bytesRead == 0) { targetStream.Flush(); return bytesToCopy - bytesLeftToCopy; } targetStream.Write(buffer, 0, bytesRead); bytesLeftToCopy -= bytesRead; } // It must not be negative Debug.Assert(bytesLeftToCopy == 0); targetStream.Flush(); return bytesToCopy; } ////// Create a User-Domain Scoped IsolatedStorage file (or Machine-Domain scoped file if current user has no profile) /// /// returns the created file name /// number of times to retry in case of name collision (legal values between 0 and 100) ///the created stream ///retryCount was exceeded ///This function locks on IsoStoreSyncRoot and is thread-safe internal static Stream CreateUserScopedIsolatedStorageFileStreamWithRandomName(int retryCount, out String fileName) { // negative is illegal and place an upper limit of 100 if (retryCount < 0 || retryCount > 100) throw new ArgumentOutOfRangeException("retryCount"); Stream s = null; fileName = null; // GetRandomFileName returns a very random name, but collisions are still possible so we // retry if we encounter one. while (true) { try { // This function returns a highly-random name in 8.3 format. fileName = Path.GetRandomFileName(); lock (IsoStoreSyncRoot) { s = GetDefaultIsolatedStorageFile().GetStream(fileName); } // if we get to here we have a success condition so we can safely exit break; } catch (IOException) { // assume it is a name collision and ignore if we have not exhausted our retry count if (--retryCount < 0) throw; } } return s; } ////// Calculate overlap between two blocks, returning the offset and length of the overlap /// /// /// /// /// /// /// internal static void CalculateOverlap(long block1Offset, long block1Size, long block2Offset, long block2Size, out long overlapBlockOffset, out long overlapBlockSize) { checked { overlapBlockOffset = Math.Max(block1Offset, block2Offset); overlapBlockSize = Math.Min(block1Offset + block1Size, block2Offset + block2Size) - overlapBlockOffset; if (overlapBlockSize <= 0) { overlapBlockSize = 0; } } } ////// This method returns the count of xml attributes other than: /// 1. xmlns="namespace" /// 2. xmlns:someprefix="namespace" /// Reader should be positioned at the Element whose attributes /// are to be counted. /// /// ///An integer indicating the number of non-xmlns attributes internal static int GetNonXmlnsAttributeCount(XmlReader reader) { Debug.Assert(reader != null, "xmlReader should not be null"); Debug.Assert(reader.NodeType == XmlNodeType.Element, "XmlReader should be positioned at an Element"); int readerCount = 0; //If true, reader moves to the attribute //If false, there are no more attributes (or none) //and in that case the position of the reader is unchanged. //First time through, since the reader will be positioned at an Element, //MoveToNextAttribute is the same as MoveToFirstAttribute. while (reader.MoveToNextAttribute()) { if (String.CompareOrdinal(reader.Name, XmlNamespace) != 0 && String.CompareOrdinal(reader.Prefix, XmlNamespace) != 0) readerCount++; } //re-position the reader to the element reader.MoveToElement(); return readerCount; } ////// Any usage of IsolatedStorage static properties should lock on this for thread-safety /// internal static Object IsoStoreSyncRoot { get { return _isoStoreSyncObject; } } #endregion Internal Methods //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ ////// Delete file created using CreateUserScopedIsolatedStorageFileStreamWithRandomName() /// /// ///Correctly handles temp/isostore differences private static void DeleteIsolatedStorageFile(String fileName) { lock (IsoStoreSyncRoot) { GetDefaultIsolatedStorageFile().IsoFile.DeleteFile(fileName); } } ////// Returns the IsolatedStorageFile scoped to Assembly, Domain and User /// ///Callers must lock on IsoStoreSyncRoot before calling this for thread-safety. /// For example: /// /// lock (IsoStoreSyncRoot) /// { /// // do something with the returned IsolatedStorageFile /// PackagingUtilities.DefaultIsolatedStorageFile.DeleteFile(_isolatedStorageStreamFileName); /// } /// /// private static ReliableIsolatedStorageFileFolder GetDefaultIsolatedStorageFile() { // Cache and re-use the same object for multiple requests - resurrect if disposed if (_defaultFile == null || _defaultFile.IsDisposed()) { _defaultFile = new ReliableIsolatedStorageFileFolder(); } return _defaultFile; } ////// Determine if current user has a User Profile so we can determine the appropriate /// scope to use for IsolatedStorage functionality. /// ////// Critical - Asserts read registry permission... /// - Asserts ControlPrincipal to access current user identity /// TAS - only returns a bool /// [SecurityCritical, SecurityTreatAsSafe] private static bool UserHasProfile() { // Acquire permissions to read the one key we care about from the registry // Acquite permission to query the current user identity PermissionSet permissionSet = new PermissionSet(PermissionState.None); permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.ControlPrincipal)); permissionSet.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, _fullProfileListKeyName)); permissionSet.Assert(); bool userHasProfile = false; RegistryKey userProfileKey = null; try { // inspect registry and look for user profile via SID string userSid = System.Security.Principal.WindowsIdentity.GetCurrent().User.Value; userProfileKey = Registry.LocalMachine.OpenSubKey(_profileListKeyName + @"\" + userSid); userHasProfile = userProfileKey != null; } finally { if (userProfileKey != null) userProfileKey.Close(); CodeAccessPermission.RevertAssert(); } return userHasProfile; } //------------------------------------------------------ // // Private Classes // //------------------------------------------------------ ////// This class extends IsolatedStorageFileStream by adding a finalizer to ensure that /// the underlying file is deleted when the stream is closed. /// private class SafeIsolatedStorageFileStream : IsolatedStorageFileStream { //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ internal SafeIsolatedStorageFileStream( string path, FileMode mode, FileAccess access, FileShare share, ReliableIsolatedStorageFileFolder folder) : base(path, mode, access, share, folder.IsoFile) { if (path == null) throw new ArgumentNullException("path"); _path = path; _folder = folder; _folder.AddRef(); } //------------------------------------------------------ // // Protected Methods // //------------------------------------------------------ protected override void Dispose(bool disposing) { if (!_disposed) { if (disposing) { // Non-standard pattern - call base.Dispose() first. // This is required because the base class is a stream and we cannot // delete the underlying file storage before it has a chance to close // and release it. base.Dispose(disposing); if (_path != null) { PackagingUtilities.DeleteIsolatedStorageFile(_path); _path = null; } //Decrement the count of files _folder.DecRef(); _folder = null; GC.SuppressFinalize(this); } _disposed = true; } } //------------------------------------------------------ // // Private Fields // //------------------------------------------------------ private string _path; private ReliableIsolatedStorageFileFolder _folder; private bool _disposed; } ////// This class extends IsolatedStorageFileStream by adding a finalizer to ensure that /// the underlying file is deleted when the stream is closed. /// private class ReliableIsolatedStorageFileFolder : IDisposable { //------------------------------------------------------ // // Internal Properties // //------------------------------------------------------ internal IsolatedStorageFile IsoFile { get { CheckDisposed(); return _file; } } ////// Call this when a new file is created in the isoFolder /// internal void AddRef() { lock (IsoStoreSyncRoot) { CheckDisposed(); checked { ++_refCount; } } } ////// Call this when a new file is deleted from the isoFolder /// internal void DecRef() { lock (IsoStoreSyncRoot) { CheckDisposed(); checked { --_refCount; } if (_refCount <= 0) { Dispose(); } } } ////// Only used within a lock statement /// ///internal bool IsDisposed() { return _disposed; } //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ internal ReliableIsolatedStorageFileFolder() { _userHasProfile = UserHasProfile(); _file = GetCurrentStore(); } /// /// This triggers AddRef because SafeIsoStream does this in its constructor /// /// ///internal Stream GetStream(String fileName) { CheckDisposed(); // This constructor uses a scope that isolates by AppDomain and User // We cannot include Assembly scope because it prevents sharing between Base and Core dll's return new SafeIsolatedStorageFileStream( fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.None, this); } /// /// IDisposable.Dispose() /// public void Dispose() { Dispose(true); } //------------------------------------------------------ // // Protected Methods // //------------------------------------------------------ protected virtual void Dispose(bool disposing) { try { // only lock if we are disposing if (disposing) { lock (IsoStoreSyncRoot) { if (!_disposed) { using (_file) { _file.Remove(); } _disposed = true; } _file = null; } GC.SuppressFinalize(this); } else { // We cannot rely on other managed objects in our finalizer // so we allocate a fresh object to help us delete our temp folder. using (IsolatedStorageFile file = GetCurrentStore()) { file.Remove(); } } } catch (IsolatedStorageException) { // IsolatedStorageException can be thrown if the files that are being deleted, are // currently in use. These files will not get cleaned up. } } //------------------------------------------------------ // // Private Methods // //------------------------------------------------------ ////// Call this sparingly as it allocates resources /// ///private IsolatedStorageFile GetCurrentStore() { if (_userHasProfile) { return IsolatedStorageFile.GetUserStoreForDomain(); } else { return IsolatedStorageFile.GetMachineStoreForDomain(); } } ~ReliableIsolatedStorageFileFolder() { Dispose(false); } void CheckDisposed() { if (_disposed) throw new ObjectDisposedException("ReliableIsolatedStorageFileFolder"); } //------------------------------------------------------ // // Private Fields // //------------------------------------------------------ private static IsolatedStorageFile _file; private static bool _userHasProfile; private int _refCount; // number of outstanding "streams" private bool _disposed; } //------------------------------------------------------ // // Private Fields // //------------------------------------------------------ /// /// Synchronize access to IsolatedStorage methods that can step on each-other /// ///See PS 1468964 for details. private static Object _isoStoreSyncObject = new Object(); private static ReliableIsolatedStorageFileFolder _defaultFile; private const string XmlNamespace = "xmlns"; private const string _encodingAttribute = "encoding"; private static readonly string _webNameUTF8 = Encoding.UTF8.WebName.ToUpperInvariant(); private static readonly string _webNameUnicode = Encoding.Unicode.WebName.ToUpperInvariant(); ////// ProfileListKeyName /// ////// _profileListKeyName must remain readonly for security reasons /// private const string _profileListKeyName = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"; private const string _fullProfileListKeyName = @"HKEY_LOCAL_MACHINE\" + _profileListKeyName; } } // 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
- PolygonHotSpot.cs
- CharEnumerator.cs
- FormViewPagerRow.cs
- DefaultTextStoreTextComposition.cs
- ToolTipAutomationPeer.cs
- DbParameterCollectionHelper.cs
- JsonFormatWriterGenerator.cs
- Splitter.cs
- LookupNode.cs
- SystemFonts.cs
- Misc.cs
- HtmlInputFile.cs
- RegionData.cs
- FixedSchema.cs
- StdValidatorsAndConverters.cs
- HtmlDocument.cs
- SystemColors.cs
- CompensatableSequenceActivity.cs
- FontDifferentiator.cs
- XamlTreeBuilderBamlRecordWriter.cs
- GlyphInfoList.cs
- SqlReorderer.cs
- ZipIOBlockManager.cs
- BamlRecordReader.cs
- VisualState.cs
- FixedSchema.cs
- SoapMessage.cs
- ScrollChangedEventArgs.cs
- PrivateFontCollection.cs
- XmlNodeList.cs
- RepeatBehavior.cs
- StringResourceManager.cs
- XmlNamespaceManager.cs
- ParameterCollection.cs
- WebPartTransformer.cs
- ProjectionRewriter.cs
- PerformanceCounterLib.cs
- TreeViewImageIndexConverter.cs
- DataSourceConverter.cs
- DataGridViewComboBoxColumnDesigner.cs
- NativeConfigurationLoader.cs
- Subtract.cs
- CompositeScriptReferenceEventArgs.cs
- HttpRequest.cs
- TableDetailsCollection.cs
- MenuItemStyle.cs
- _SslSessionsCache.cs
- CurrentChangingEventManager.cs
- CornerRadius.cs
- WindowsTokenRoleProvider.cs
- XmlPropertyBag.cs
- Validator.cs
- XmlWrappingWriter.cs
- DataGridCellEditEndingEventArgs.cs
- _NestedSingleAsyncResult.cs
- XhtmlBasicLinkAdapter.cs
- JsonFormatReaderGenerator.cs
- DesignerActionMethodItem.cs
- WinFormsComponentEditor.cs
- ResourcesBuildProvider.cs
- SynchronizedMessageSource.cs
- UInt64.cs
- DataBindEngine.cs
- DataGridViewBindingCompleteEventArgs.cs
- RestClientProxyHandler.cs
- COSERVERINFO.cs
- XmlBinaryReader.cs
- StaticTextPointer.cs
- DataTableReaderListener.cs
- TypeNameConverter.cs
- WebPartHeaderCloseVerb.cs
- ProtectedProviderSettings.cs
- ECDiffieHellmanPublicKey.cs
- BamlReader.cs
- IssuanceLicense.cs
- CompilerScope.cs
- PersonalizableAttribute.cs
- ListControlConvertEventArgs.cs
- SqlCacheDependency.cs
- HttpConfigurationContext.cs
- ExecutionEngineException.cs
- SelectionPatternIdentifiers.cs
- StateItem.cs
- PTConverter.cs
- CodeExpressionRuleDeclaration.cs
- EventKeyword.cs
- TextEmbeddedObject.cs
- ListParagraph.cs
- WebPartConnection.cs
- QilBinary.cs
- StreamWriter.cs
- wgx_sdk_version.cs
- PrimitiveSchema.cs
- ErrorProvider.cs
- NullableConverter.cs
- DirectionalLight.cs
- EndpointAddress10.cs
- DataTemplate.cs
- DataGridViewCellMouseEventArgs.cs
- QueryExpr.cs