Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / MS / Internal / IO / Packaging / DeobfuscatingStream.cs / 1305600 / 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: [....]: 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
- DataGridViewCellContextMenuStripNeededEventArgs.cs
- CqlGenerator.cs
- AuthenticationSection.cs
- TransformedBitmap.cs
- HttpStaticObjectsCollectionWrapper.cs
- XmlUrlResolver.cs
- ComponentResourceKeyConverter.cs
- PermissionAttributes.cs
- MenuRenderer.cs
- Byte.cs
- BitmapCodecInfoInternal.cs
- ClosureBinding.cs
- BitSet.cs
- ProfileModule.cs
- ServiceModelConfiguration.cs
- _HeaderInfoTable.cs
- UnhandledExceptionEventArgs.cs
- TextBoxBase.cs
- RegexCaptureCollection.cs
- EFTableProvider.cs
- InputQueue.cs
- SoapExtensionTypeElement.cs
- ProvidePropertyAttribute.cs
- EncryptedReference.cs
- AmbientValueAttribute.cs
- XMLSchema.cs
- ProviderMetadataCachedInformation.cs
- SqlDataSourceSelectingEventArgs.cs
- MoveSizeWinEventHandler.cs
- HScrollProperties.cs
- MetadataItemCollectionFactory.cs
- BaseDataListDesigner.cs
- ProxyElement.cs
- StylusButtonEventArgs.cs
- DecimalStorage.cs
- DefaultProfileManager.cs
- RequestStatusBarUpdateEventArgs.cs
- UserPersonalizationStateInfo.cs
- LocalizedNameDescriptionPair.cs
- InvokeHandlers.cs
- GlyphingCache.cs
- HwndSourceKeyboardInputSite.cs
- PropertyGridEditorPart.cs
- DBPropSet.cs
- MonthChangedEventArgs.cs
- SolidColorBrush.cs
- ChineseLunisolarCalendar.cs
- _ListenerResponseStream.cs
- _BasicClient.cs
- RemotingConfiguration.cs
- XmlSchemaSequence.cs
- WinFormsSecurity.cs
- EmptyImpersonationContext.cs
- SystemColors.cs
- METAHEADER.cs
- PolicyValidationException.cs
- UnhandledExceptionEventArgs.cs
- XDeferredAxisSource.cs
- ParallelTimeline.cs
- DuplicateWaitObjectException.cs
- Debugger.cs
- DispatcherEventArgs.cs
- EventProxy.cs
- SafeCoTaskMem.cs
- HierarchicalDataSourceControl.cs
- DataObject.cs
- SafeRightsManagementPubHandle.cs
- SourceElementsCollection.cs
- WebBrowserEvent.cs
- SupportsEventValidationAttribute.cs
- ILGenerator.cs
- SizeFConverter.cs
- NamedPipeTransportSecurity.cs
- DataBindingHandlerAttribute.cs
- PaintEvent.cs
- AppDomainAttributes.cs
- InheritablePropertyChangeInfo.cs
- FastEncoder.cs
- TextRunProperties.cs
- URI.cs
- GenericPrincipal.cs
- CalculatedColumn.cs
- DoubleLinkListEnumerator.cs
- SafeNativeMethods.cs
- WindowsGraphics.cs
- ParameterRefs.cs
- DbException.cs
- SamlSerializer.cs
- ConfigurationElementCollection.cs
- updateconfighost.cs
- SqlAliasesReferenced.cs
- VirtualPathUtility.cs
- TypeCollectionDesigner.xaml.cs
- CodeDomSerializationProvider.cs
- RecognizedPhrase.cs
- FixUpCollection.cs
- RepeaterItemEventArgs.cs
- Timer.cs
- WebPartAuthorizationEventArgs.cs
- UdpDiscoveryEndpointElement.cs