Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Core / CSharp / MS / Internal / IO / Packaging / DeobfuscatingStream.cs / 1 / DeobfuscatingStream.cs
//------------------------------------------------------------------------------ // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // This class provides stream implementation that de-obfuscates the bytes that are obfuscated in accordance // with the section under Embbedded Font Obfuscation in the XPS spec. // // Recap of font obfuscation: // 1. Generate a 128-bit GUID (a 128-bit random number may be use instead) // 2. Generate a part name using the GUID // 3. XOR the first 32 bytes of the binary data of the font with the binary representation of the GUID // 4. in the step #3, start with the LSB of the binary GUID // // Notes: // The stream is read only // // History: // 05/23/05: YoungGK: Initial implementation. //----------------------------------------------------------------------------- using System; using System.IO; using System.IO.Packaging; using MS.Internal.PresentationCore; // for ExceptionStringTable namespace MS.Internal.IO.Packaging { //----------------------------------------------------- // // Internal Members // //----------------------------------------------------- ////// Wrapper stream that returns de-obfuscated bytes from obfuscated stream /// internal class DeobfuscatingStream : Stream { //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- #region Stream Methods ////// Read bytes from the stream /// /// destination buffer /// offset to read into that buffer /// how many bytes requested ///how many bytes were wread public override int Read(byte[] buffer, int offset, int count) { CheckDisposed(); long readPosition = _obfuscatedStream.Position; // Read in the raw data from the underlying stream int bytesRead = _obfuscatedStream.Read(buffer, offset, count); // Apply de-obfuscatation as necessary Deobfuscate(buffer, offset, bytesRead, readPosition); return bytesRead; } ///. /// Write /// ///This is a read-only stream; throw now supported exception public override void Write(byte[] buffer, int offset, int count) { CheckDisposed(); throw new NotSupportedException(SR.Get(SRID.WriteNotSupported)); } ////// Seek /// /// offset /// origin public override long Seek(long offset, SeekOrigin origin) { CheckDisposed(); return _obfuscatedStream.Seek(offset, origin); } ////// SetLength /// ///This is a read-only stream; throw now supported exception public override void SetLength(long newLength) { CheckDisposed(); throw new NotSupportedException(SR.Get(SRID.SetLengthNotSupported)); } ////// Flush /// public override void Flush() { CheckDisposed(); _obfuscatedStream.Flush(); } #endregion Stream Methods #region Stream Properties ////// Current position of the stream /// public override long Position { get { CheckDisposed(); return _obfuscatedStream.Position; } set { CheckDisposed(); _obfuscatedStream.Position = value; } } ////// Length /// public override long Length { get { return _obfuscatedStream.Length; } } ////// Is stream readable? /// ///returns false when called on disposed stream public override bool CanRead { get { // cannot read from a close stream, but don't throw if asked return (_obfuscatedStream != null) && _obfuscatedStream.CanRead; } } ////// Is stream seekable /// ///returns false when called on disposed stream public override bool CanSeek { get { // cannot seek on a close stream, but don't throw if asked return (_obfuscatedStream != null) && _obfuscatedStream.CanSeek; } } ////// Is stream writeable? /// ///returns false always since it is a read-only stream public override bool CanWrite { get { return false; } } #endregion #region Internal //------------------------------------------------------ // // Internal Constructors // //------------------------------------------------------ ////// Constructor /// /// stream that holds obfuscated resource /// the original Uri which is used to obtain obfuscatedStream; it holds /// the GUID information which is used to obfuscate the resources /// if it is false, obfuscatedStream will be also disposed when /// DeobfuscatingStream is disposed ///streamUri has to be a pack Uri internal DeobfuscatingStream(Stream obfuscatedStream, Uri streamUri, bool leaveOpen) { if (obfuscatedStream == null) { throw new ArgumentNullException("obfuscatedStream"); } // Make sure streamUri is in the correct form; getting partUri from it will do all necessary checks for error // conditions; We also have to make sure that it has a part name Uri partUri = PackUriHelper.GetPartUri(streamUri); if (partUri == null) { throw new InvalidOperationException(SR.Get(SRID.InvalidPartName)); } // Normally we should use PackUriHelper.GetStringForPartUri to get the string representation of part Uri // however, since we already made sure that streamUris is in the correct form (such as to check if it is an absolute Uri // and there is a correct authority (package)), it doesn't have to be fully validated again. // Get the escaped string for the part name as part names should have only ascii characters String guid = Path.GetFileNameWithoutExtension( streamUri.GetComponents(UriComponents.Path | UriComponents.KeepDelimiter, UriFormat.UriEscaped)); _guid = GetGuidByteArray(guid); _obfuscatedStream = obfuscatedStream; _ownObfuscatedStream = !leaveOpen; } #endregion //----------------------------------------------------- // // Protected Methods // //------------------------------------------------------ ////// Dispose(bool) /// /// ///We implement this because we want a consistent experience (essentially Flush our data) if the user chooses to /// call Dispose() instead of Close(). protected override void Dispose(bool disposing) { try { if (disposing) { // If this class owns the underlying steam, close it if (_obfuscatedStream != null && _ownObfuscatedStream) { _obfuscatedStream.Close(); } _obfuscatedStream = null; } } finally { base.Dispose(disposing); } } #region Private //----------------------------------------------------- // // Private Properties // //----------------------------------------------------- //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ ////// Call this before accepting any public API call (except some Stream calls that /// are allowed to respond even when Closed /// private void CheckDisposed() { if (_obfuscatedStream == null) throw new ObjectDisposedException(null, SR.Get(SRID.Media_StreamClosed)); } ////// Apply de-obfuscation as necessary (the first 32 bytes of the underlying stream are obfuscated /// private void Deobfuscate(byte[] buffer, int offset, int count, long readPosition) { // only the first 32 bytes of the underlying stream are obfuscated // if the read position is beyond offset 32, there is no need to do de-obfuscation if (readPosition >= ObfuscatedLength || count <= 0) return; // Find out how many bytes in the buffer are needed to be XORed // Note on casting: // count can be safely cast to long since it is int // We don't need to check for overflow of (readPosition + (long) count) since count is int and readPosition is less than // ObfuscatedLength // The result of (Math.Min(ObfuscatedLength, readPosition + (long) count) - readPosition) can be safely cast to int // since it cannot be bigger than ObfuscatedLength which is 32 int bytesToXor = (int) (Math.Min(ObfuscatedLength, unchecked (readPosition + (long) count)) - readPosition); int guidBytePosition = _guid.Length - ((int) readPosition % _guid.Length) - 1; for (int i = offset; bytesToXor > 0; --bytesToXor, ++i, --guidBytePosition) { // If we exhausted the Guid bytes, go back to the least significant byte if (guidBytePosition < 0) guidBytePosition = _guid.Length - 1; // XOR the obfuscated byte with the appropriate byte from the Guid byte array buffer[i] ^= _guid[guidBytePosition]; } } ////// Returns the byte representation of guidString /// ////// We cannot use Guid.GetByteArray directly due to little or big endian issues /// Guid is defined as below: /// typedef struct _GUID /// { /// DWORD Data1; /// WORD Data2; /// WORD Data3; /// BYTE Data4[8]; /// } GUID; /// So, Guid.GetByteArray returns a byte array where the first 8 bytes are ordered according to a specific endian format /// private static byte[] GetGuidByteArray(string guidString) { // Make sure we have at least on '-' since Guid constructor will take both dash'ed and non-dash'ed format of GUID string // while XPS spec requires dash'ed format of GUID if (guidString.IndexOf('-') == -1) { throw new ArgumentException(SR.Get(SRID.InvalidPartName)); } // Use Guid constructor to do error checking in parsing Guid guid = new Guid(guidString); // Convert the GUID into string in 32 digits format (xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) string wellFormedGuidString = guid.ToString("N"); // Now it is safe to do parsing of the well-formed GUID string byte[] guidBytes = new byte[16]; // We don't need to check the length of wellFormedGuidString since it is guaranteed to be 32 for (int i = 0; i < guidBytes.Length; i++) { guidBytes[i] = Convert.ToByte(wellFormedGuidString.Substring(i * 2, 2), 16); } return guidBytes; } //----------------------------------------------------- // // Private Variables // //------------------------------------------------------ private Stream _obfuscatedStream; // stream we ultimately decompress from and to in the container private byte[] _guid; private bool _ownObfuscatedStream; // Does this class own the underlying stream? // if it does, it should dispose the underlying stream when this class is disposed private const long ObfuscatedLength = 32; #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------ // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // This class provides stream implementation that de-obfuscates the bytes that are obfuscated in accordance // with the section under Embbedded Font Obfuscation in the XPS spec. // // Recap of font obfuscation: // 1. Generate a 128-bit GUID (a 128-bit random number may be use instead) // 2. Generate a part name using the GUID // 3. XOR the first 32 bytes of the binary data of the font with the binary representation of the GUID // 4. in the step #3, start with the LSB of the binary GUID // // Notes: // The stream is read only // // History: // 05/23/05: YoungGK: Initial implementation. //----------------------------------------------------------------------------- using System; using System.IO; using System.IO.Packaging; using MS.Internal.PresentationCore; // for ExceptionStringTable namespace MS.Internal.IO.Packaging { //----------------------------------------------------- // // Internal Members // //----------------------------------------------------- ////// Wrapper stream that returns de-obfuscated bytes from obfuscated stream /// internal class DeobfuscatingStream : Stream { //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- #region Stream Methods ////// Read bytes from the stream /// /// destination buffer /// offset to read into that buffer /// how many bytes requested ///how many bytes were wread public override int Read(byte[] buffer, int offset, int count) { CheckDisposed(); long readPosition = _obfuscatedStream.Position; // Read in the raw data from the underlying stream int bytesRead = _obfuscatedStream.Read(buffer, offset, count); // Apply de-obfuscatation as necessary Deobfuscate(buffer, offset, bytesRead, readPosition); return bytesRead; } ///. /// Write /// ///This is a read-only stream; throw now supported exception public override void Write(byte[] buffer, int offset, int count) { CheckDisposed(); throw new NotSupportedException(SR.Get(SRID.WriteNotSupported)); } ////// Seek /// /// offset /// origin public override long Seek(long offset, SeekOrigin origin) { CheckDisposed(); return _obfuscatedStream.Seek(offset, origin); } ////// SetLength /// ///This is a read-only stream; throw now supported exception public override void SetLength(long newLength) { CheckDisposed(); throw new NotSupportedException(SR.Get(SRID.SetLengthNotSupported)); } ////// Flush /// public override void Flush() { CheckDisposed(); _obfuscatedStream.Flush(); } #endregion Stream Methods #region Stream Properties ////// Current position of the stream /// public override long Position { get { CheckDisposed(); return _obfuscatedStream.Position; } set { CheckDisposed(); _obfuscatedStream.Position = value; } } ////// Length /// public override long Length { get { return _obfuscatedStream.Length; } } ////// Is stream readable? /// ///returns false when called on disposed stream public override bool CanRead { get { // cannot read from a close stream, but don't throw if asked return (_obfuscatedStream != null) && _obfuscatedStream.CanRead; } } ////// Is stream seekable /// ///returns false when called on disposed stream public override bool CanSeek { get { // cannot seek on a close stream, but don't throw if asked return (_obfuscatedStream != null) && _obfuscatedStream.CanSeek; } } ////// Is stream writeable? /// ///returns false always since it is a read-only stream public override bool CanWrite { get { return false; } } #endregion #region Internal //------------------------------------------------------ // // Internal Constructors // //------------------------------------------------------ ////// Constructor /// /// stream that holds obfuscated resource /// the original Uri which is used to obtain obfuscatedStream; it holds /// the GUID information which is used to obfuscate the resources /// if it is false, obfuscatedStream will be also disposed when /// DeobfuscatingStream is disposed ///streamUri has to be a pack Uri internal DeobfuscatingStream(Stream obfuscatedStream, Uri streamUri, bool leaveOpen) { if (obfuscatedStream == null) { throw new ArgumentNullException("obfuscatedStream"); } // Make sure streamUri is in the correct form; getting partUri from it will do all necessary checks for error // conditions; We also have to make sure that it has a part name Uri partUri = PackUriHelper.GetPartUri(streamUri); if (partUri == null) { throw new InvalidOperationException(SR.Get(SRID.InvalidPartName)); } // Normally we should use PackUriHelper.GetStringForPartUri to get the string representation of part Uri // however, since we already made sure that streamUris is in the correct form (such as to check if it is an absolute Uri // and there is a correct authority (package)), it doesn't have to be fully validated again. // Get the escaped string for the part name as part names should have only ascii characters String guid = Path.GetFileNameWithoutExtension( streamUri.GetComponents(UriComponents.Path | UriComponents.KeepDelimiter, UriFormat.UriEscaped)); _guid = GetGuidByteArray(guid); _obfuscatedStream = obfuscatedStream; _ownObfuscatedStream = !leaveOpen; } #endregion //----------------------------------------------------- // // Protected Methods // //------------------------------------------------------ ////// Dispose(bool) /// /// ///We implement this because we want a consistent experience (essentially Flush our data) if the user chooses to /// call Dispose() instead of Close(). protected override void Dispose(bool disposing) { try { if (disposing) { // If this class owns the underlying steam, close it if (_obfuscatedStream != null && _ownObfuscatedStream) { _obfuscatedStream.Close(); } _obfuscatedStream = null; } } finally { base.Dispose(disposing); } } #region Private //----------------------------------------------------- // // Private Properties // //----------------------------------------------------- //----------------------------------------------------- // // Private Methods // //------------------------------------------------------ ////// Call this before accepting any public API call (except some Stream calls that /// are allowed to respond even when Closed /// private void CheckDisposed() { if (_obfuscatedStream == null) throw new ObjectDisposedException(null, SR.Get(SRID.Media_StreamClosed)); } ////// Apply de-obfuscation as necessary (the first 32 bytes of the underlying stream are obfuscated /// private void Deobfuscate(byte[] buffer, int offset, int count, long readPosition) { // only the first 32 bytes of the underlying stream are obfuscated // if the read position is beyond offset 32, there is no need to do de-obfuscation if (readPosition >= ObfuscatedLength || count <= 0) return; // Find out how many bytes in the buffer are needed to be XORed // Note on casting: // count can be safely cast to long since it is int // We don't need to check for overflow of (readPosition + (long) count) since count is int and readPosition is less than // ObfuscatedLength // The result of (Math.Min(ObfuscatedLength, readPosition + (long) count) - readPosition) can be safely cast to int // since it cannot be bigger than ObfuscatedLength which is 32 int bytesToXor = (int) (Math.Min(ObfuscatedLength, unchecked (readPosition + (long) count)) - readPosition); int guidBytePosition = _guid.Length - ((int) readPosition % _guid.Length) - 1; for (int i = offset; bytesToXor > 0; --bytesToXor, ++i, --guidBytePosition) { // If we exhausted the Guid bytes, go back to the least significant byte if (guidBytePosition < 0) guidBytePosition = _guid.Length - 1; // XOR the obfuscated byte with the appropriate byte from the Guid byte array buffer[i] ^= _guid[guidBytePosition]; } } ////// Returns the byte representation of guidString /// ////// We cannot use Guid.GetByteArray directly due to little or big endian issues /// Guid is defined as below: /// typedef struct _GUID /// { /// DWORD Data1; /// WORD Data2; /// WORD Data3; /// BYTE Data4[8]; /// } GUID; /// So, Guid.GetByteArray returns a byte array where the first 8 bytes are ordered according to a specific endian format /// private static byte[] GetGuidByteArray(string guidString) { // Make sure we have at least on '-' since Guid constructor will take both dash'ed and non-dash'ed format of GUID string // while XPS spec requires dash'ed format of GUID if (guidString.IndexOf('-') == -1) { throw new ArgumentException(SR.Get(SRID.InvalidPartName)); } // Use Guid constructor to do error checking in parsing Guid guid = new Guid(guidString); // Convert the GUID into string in 32 digits format (xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) string wellFormedGuidString = guid.ToString("N"); // Now it is safe to do parsing of the well-formed GUID string byte[] guidBytes = new byte[16]; // We don't need to check the length of wellFormedGuidString since it is guaranteed to be 32 for (int i = 0; i < guidBytes.Length; i++) { guidBytes[i] = Convert.ToByte(wellFormedGuidString.Substring(i * 2, 2), 16); } return guidBytes; } //----------------------------------------------------- // // Private Variables // //------------------------------------------------------ private Stream _obfuscatedStream; // stream we ultimately decompress from and to in the container private byte[] _guid; private bool _ownObfuscatedStream; // Does this class own the underlying stream? // if it does, it should dispose the underlying stream when this class is disposed private const long ObfuscatedLength = 32; #endregion } } // 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
- XmlReflectionImporter.cs
- Section.cs
- TraceContextEventArgs.cs
- Types.cs
- TreeNodeClickEventArgs.cs
- PropertyChangedEventManager.cs
- OleStrCAMarshaler.cs
- ImageDrawing.cs
- StylusCaptureWithinProperty.cs
- WrapPanel.cs
- WindowsAuthenticationEventArgs.cs
- HttpPostServerProtocol.cs
- StickyNoteContentControl.cs
- TableItemProviderWrapper.cs
- FileSystemInfo.cs
- _Events.cs
- RequestCacheManager.cs
- SessionPageStateSection.cs
- CollectionBase.cs
- DesignerOptionService.cs
- ClientTargetSection.cs
- WebCategoryAttribute.cs
- DebuggerAttributes.cs
- FlatButtonAppearance.cs
- XmlBinaryWriterSession.cs
- MULTI_QI.cs
- WebPartRestoreVerb.cs
- MarshalByValueComponent.cs
- PageStatePersister.cs
- Inline.cs
- SQLMembershipProvider.cs
- DeviceFiltersSection.cs
- MSHTMLHost.cs
- ToolBar.cs
- DbResourceAllocator.cs
- VectorConverter.cs
- Margins.cs
- ZeroOpNode.cs
- HijriCalendar.cs
- ResourceReferenceExpressionConverter.cs
- StorageFunctionMapping.cs
- GeneralTransformGroup.cs
- CustomAssemblyResolver.cs
- OptimisticConcurrencyException.cs
- SpecialFolderEnumConverter.cs
- ListView.cs
- ContentControl.cs
- SystemIPGlobalStatistics.cs
- EntityDataSourceWrapperPropertyDescriptor.cs
- BindingWorker.cs
- MatrixAnimationUsingPath.cs
- ColumnResizeUndoUnit.cs
- DataGrid.cs
- RuleProcessor.cs
- ToolStripSplitButton.cs
- DelegateHelpers.Generated.cs
- DesignBindingConverter.cs
- SqlWebEventProvider.cs
- ExtentJoinTreeNode.cs
- SplineQuaternionKeyFrame.cs
- SvcMapFile.cs
- LinqDataSourceSelectEventArgs.cs
- StorageConditionPropertyMapping.cs
- StructureChangedEventArgs.cs
- TextTreeInsertElementUndoUnit.cs
- StreamWithDictionary.cs
- CheckBoxField.cs
- WebPartConnectionsCancelVerb.cs
- AuthenticationModulesSection.cs
- XamlStyleSerializer.cs
- AnnouncementEndpoint.cs
- HandleInitializationContext.cs
- WindowsRichEditRange.cs
- DataColumnMapping.cs
- CheckBox.cs
- DropShadowBitmapEffect.cs
- NameSpaceExtractor.cs
- RenderingEventArgs.cs
- DebuggerAttributes.cs
- FlowPosition.cs
- DrawingCollection.cs
- DrawListViewItemEventArgs.cs
- UIElement.cs
- RichTextBoxDesigner.cs
- DbProviderSpecificTypePropertyAttribute.cs
- SqlNotificationRequest.cs
- TemplateLookupAction.cs
- Cursors.cs
- UrlPropertyAttribute.cs
- PropertyDescriptorGridEntry.cs
- AppliedDeviceFiltersEditor.cs
- RectAnimationClockResource.cs
- ConfigurationElementCollection.cs
- ColorMap.cs
- JpegBitmapDecoder.cs
- FunctionCommandText.cs
- ToolboxItemCollection.cs
- ConfigurationElementCollection.cs
- SplineQuaternionKeyFrame.cs
- SqlDataSourceWizardForm.cs