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
- ChainedAsyncResult.cs
- TextPointer.cs
- EntityContainerRelationshipSetEnd.cs
- DataSourceControl.cs
- TemplateParser.cs
- SymLanguageVendor.cs
- TerminateWorkflow.cs
- DataColumn.cs
- StackBuilderSink.cs
- BufferBuilder.cs
- DurationConverter.cs
- RuleSettings.cs
- Positioning.cs
- ServiceBusyException.cs
- TraceHwndHost.cs
- __FastResourceComparer.cs
- ListViewUpdateEventArgs.cs
- KeyValuePair.cs
- PropertyHelper.cs
- FtpCachePolicyElement.cs
- ScriptComponentDescriptor.cs
- PathSegment.cs
- TextCompositionManager.cs
- OdbcInfoMessageEvent.cs
- ADConnectionHelper.cs
- DynamicMethod.cs
- FixedHyperLink.cs
- BufferAllocator.cs
- ProfileSettingsCollection.cs
- IPEndPoint.cs
- SystemFonts.cs
- CompilationUnit.cs
- sortedlist.cs
- ResourcePermissionBaseEntry.cs
- SharedConnectionListener.cs
- TreeWalker.cs
- ImagingCache.cs
- ImageList.cs
- XmlHierarchicalDataSourceView.cs
- SkinIDTypeConverter.cs
- X509PeerCertificateAuthenticationElement.cs
- ProgressBar.cs
- RenderDataDrawingContext.cs
- OperandQuery.cs
- rsa.cs
- TransformedBitmap.cs
- StatusStrip.cs
- TreeWalkHelper.cs
- NodeFunctions.cs
- Scanner.cs
- DateTimeOffsetStorage.cs
- CardSpaceSelector.cs
- WebSysDefaultValueAttribute.cs
- DataGridViewButtonColumn.cs
- DataGridViewLinkCell.cs
- BinarySerializer.cs
- OutputChannelBinder.cs
- XmlEnumAttribute.cs
- BitmapImage.cs
- FileInfo.cs
- Double.cs
- InertiaTranslationBehavior.cs
- NavigationHelper.cs
- ZipIOLocalFileHeader.cs
- MarshalByRefObject.cs
- SamlAuthorizationDecisionClaimResource.cs
- TextViewBase.cs
- TemplateBamlRecordReader.cs
- NoPersistProperty.cs
- TemplateKey.cs
- ProgressBar.cs
- DataGridColumnCollectionEditor.cs
- InstanceNotReadyException.cs
- MenuAdapter.cs
- SignatureDescription.cs
- IDReferencePropertyAttribute.cs
- SmtpMail.cs
- DragDropHelper.cs
- _RequestCacheProtocol.cs
- WebPart.cs
- DelegatedStream.cs
- PeerEndPoint.cs
- CodeMethodReturnStatement.cs
- QualifiedCellIdBoolean.cs
- SqlClientFactory.cs
- ApplicationTrust.cs
- ConnectionProviderAttribute.cs
- ImageInfo.cs
- unsafenativemethodsother.cs
- RoutedEvent.cs
- Pen.cs
- IgnoreDataMemberAttribute.cs
- RangeBase.cs
- RegistrySecurity.cs
- ByteStack.cs
- AnnotationHelper.cs
- SignatureDescription.cs
- IndexedWhereQueryOperator.cs
- AudioStateChangedEventArgs.cs
- SatelliteContractVersionAttribute.cs