Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Base / MS / Internal / IO / Zip / ZipIOZip64EndOfCentralDirectoryLocatorBlock.cs / 1305600 / ZipIOZip64EndOfCentralDirectoryLocatorBlock.cs
//------------------------------------------------------------------------------
//------------- *** WARNING ***
//------------- This file is part of a legally monitored development project.
//------------- Do not check in changes to this project. Do not raid bugs on this
//------------- code in the main PS database. Do not contact the owner of this
//------------- code directly. Contact the legal team at ‘ZSLegal’ for assistance.
//------------- *** WARNING ***
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
// Description:
// This is an internal class that enables interactions with Zip archives
// for OPC scenarios (Zip 64 bit support)
//
// History:
// 01/26/2005: IgorBel: Initial creation.
//
//-----------------------------------------------------------------------------
using System;
using System.IO;
using System.Diagnostics;
using System.Runtime.Serialization;
using System.Windows;
using MS.Internal.WindowsBase;
namespace MS.Internal.IO.Zip
{
internal class ZipIOZip64EndOfCentralDirectoryLocatorBlock : IZipIOBlock
{
// standard IZipIOBlock functionality
public long Offset
{
get
{
return _offset;
}
}
public long Size
{
get
{
return _size;
}
}
// This property will only return reliable result if Update is called prior
public bool GetDirtyFlag(bool closingFlag)
{
return _dirtyFlag;
}
public void Move(long shiftSize)
{
if (shiftSize != 0)
{
checked{_offset +=shiftSize;}
if (_size > 0)
{
_dirtyFlag = true;
}
Debug.Assert(_offset >=0);
}
}
public void Save()
{
if (GetDirtyFlag(true) && (Size > 0))
{
BinaryWriter writer = _blockManager.BinaryWriter;
if (_blockManager.Stream.Position != _offset)
{
// we need to seek
_blockManager.Stream.Seek(_offset, SeekOrigin.Begin);
// in non seekable streams we are expected to be at the right position, no seeking required
// if this assumption is ever violated. Seek will throw on non-seekable stream, which would provide us
// with a detection mechanism for such problems
}
writer.Write(_signatureConstant);
writer.Write(_numberOfTheDiskWithTheStartOfZip64EndOfCentralDirectory);
writer.Write(_offsetOfStartOfZip64EndOfCentralDirectoryRecord);
writer.Write(_totalNumberOfDisks);
writer.Flush();
}
_dirtyFlag = false;
}
public void UpdateReferences(bool closingFlag)
{
checked
{
// check whether Central directory is loaded and update references accordingly
// if one or more of the following conditions are true
// 1. Central Directory is dirty
// 2. Zip64 End of Central Directory is dirty
// 3. streaming mode
// if Central Directory isn't loded or none of the relevant structure is dirty,
// there is nothing to update for Zip64 End Of Central directory record
if ((_blockManager.IsCentralDirectoryBlockLoaded
&& (_blockManager.Streaming
|| _blockManager.CentralDirectoryBlock.GetDirtyFlag(closingFlag))
|| _blockManager.Zip64EndOfCentralDirectoryBlock.GetDirtyFlag(closingFlag)))
{
if (_blockManager.CentralDirectoryBlock.IsZip64BitRequiredForStoring)
{
UInt64 offsetOfStartOfZip64EndOfCentralDirectoryRecord =
(UInt64)_blockManager.Zip64EndOfCentralDirectoryBlock.Offset;
// update value and mark record dirty if either it is already dirty or there is a mismatch
if ((_dirtyFlag) ||
(offsetOfStartOfZip64EndOfCentralDirectoryRecord != _offsetOfStartOfZip64EndOfCentralDirectoryRecord) ||
(_fixedMinimalRecordSize != _size))
{
_offsetOfStartOfZip64EndOfCentralDirectoryRecord = offsetOfStartOfZip64EndOfCentralDirectoryRecord;
_size = _fixedMinimalRecordSize;
_dirtyFlag = true;
}
}
else
{
// we do not need zip 64 structures
if (_size != 0)
{
_size = 0;
_dirtyFlag = true;
}
}
}
}
}
public PreSaveNotificationScanControlInstruction PreSaveNotification(long offset, long size)
{
// we can safely ignore this notification as we do not keep any data
// after parsing on disk. Everything is in memory, it is ok to override
// original End of Central directory without any additional backups
// we can also safely state that there is no need to continue the PreSafeNotification loop
// as the only blocks after the Zip64 EOCD (EOCD) doesn't have
// data that is buffered on disk
return PreSaveNotificationScanControlInstruction.Stop;
}
internal static ZipIOZip64EndOfCentralDirectoryLocatorBlock SeekableLoad (ZipIOBlockManager blockManager)
{
// This Debug assert is a secondary check in debug builds, callers are responcible for verifying condition
// in both retail and debug builds
Debug.Assert(SniffTheBlockSignature(blockManager));
long blockPosition = checked(blockManager.EndOfCentralDirectoryBlock.Offset - _fixedMinimalRecordSize);
blockManager.Stream.Seek(blockPosition, SeekOrigin.Begin);
ZipIOZip64EndOfCentralDirectoryLocatorBlock block = new ZipIOZip64EndOfCentralDirectoryLocatorBlock(blockManager);
block.ParseRecord(blockManager.BinaryReader, blockPosition);
return block;
}
internal static ZipIOZip64EndOfCentralDirectoryLocatorBlock CreateNew(ZipIOBlockManager blockManager)
{
// This Debug assert is a secondary check in debug builds, callers are responcible for verifying condition
// in both retail and debug builds
Debug.Assert(!SniffTheBlockSignature(blockManager));
ZipIOZip64EndOfCentralDirectoryLocatorBlock block = new ZipIOZip64EndOfCentralDirectoryLocatorBlock(blockManager);
block._offset = 0;
block._size = 0;
block._dirtyFlag = false;
return block;
}
internal static bool SniffTheBlockSignature(ZipIOBlockManager blockManager)
{
long suspectPos = checked(blockManager.EndOfCentralDirectoryBlock.Offset - _fixedMinimalRecordSize);
// let's check that EndOfCentralDirectoryBlock.Offset is not too close to the start of the stream
// for the record to fit there
// the second check isn't required, strictily speaking, as we are stepping back from the EOCD.offset
// however in some theoretical cases EOCD might not be trustable so to ensure that ReadUInt32
// isn't going to throw we do additional check
if ((suspectPos < 0) ||
(checked(suspectPos + sizeof(UInt32)) > blockManager.Stream.Length))
{
return false;
}
blockManager.Stream.Seek(suspectPos, SeekOrigin.Begin);
UInt32 signature = blockManager.BinaryReader.ReadUInt32();
return (signature == _signatureConstant);
}
internal long OffsetOfZip64EndOfCentralDirectoryRecord
{
get
{
return (long)_offsetOfStartOfZip64EndOfCentralDirectoryRecord;
}
}
private ZipIOZip64EndOfCentralDirectoryLocatorBlock(ZipIOBlockManager blockManager)
{
Debug.Assert(blockManager != null);
_blockManager= blockManager;
}
private void ParseRecord (BinaryReader reader, long position)
{
_signature = reader.ReadUInt32();
_numberOfTheDiskWithTheStartOfZip64EndOfCentralDirectory = reader.ReadUInt32();
_offsetOfStartOfZip64EndOfCentralDirectoryRecord = reader.ReadUInt64();
_totalNumberOfDisks = reader.ReadUInt32();
_offset = position;
_size = _fixedMinimalRecordSize;
_dirtyFlag = false;
Validate();
}
private void Validate()
{
if (_offsetOfStartOfZip64EndOfCentralDirectoryRecord > Int64.MaxValue) // C# does proper upcasting to ULONG of both operands
{
// although we are trying to support 64 bit structures
// we are limited by the CLR model for streams down to 63
// bit size for all the Uint64 fields
throw new NotSupportedException(SR.Get(SRID.Zip64StructuresTooLarge));
}
if (_signature != _signatureConstant)
{
throw new FileFormatException(SR.Get(SRID.CorruptedData));
}
if ((_totalNumberOfDisks != 1) ||
(_numberOfTheDiskWithTheStartOfZip64EndOfCentralDirectory != 0))
{
throw new NotSupportedException(SR.Get(SRID.NotSupportedMultiDisk));
}
// The offset of the ZIP 64 EOCD must preceed the location of the ZIP64 EOCD locator
if ((UInt64)_offset <= _offsetOfStartOfZip64EndOfCentralDirectoryRecord) // we assume that _offset >=0
{
throw new FileFormatException(SR.Get(SRID.CorruptedData));
}
// this record is optional size must be either 0 or _fixedMinimalRecordSize
if ((_size != _fixedMinimalRecordSize) && (_size != 0))
{
throw new FileFormatException(SR.Get(SRID.CorruptedData));
}
}
private ZipIOBlockManager _blockManager;
private long _offset;
private long _size;
private bool _dirtyFlag;
private const UInt32 _signatureConstant = 0x07064b50;
private const int _fixedMinimalRecordSize = 20;
// data persisted on disk
private UInt32 _signature = _signatureConstant;
private UInt32 _numberOfTheDiskWithTheStartOfZip64EndOfCentralDirectory;
private UInt64 _offsetOfStartOfZip64EndOfCentralDirectoryRecord;
private UInt32 _totalNumberOfDisks = 1;
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
//------------- *** WARNING ***
//------------- This file is part of a legally monitored development project.
//------------- Do not check in changes to this project. Do not raid bugs on this
//------------- code in the main PS database. Do not contact the owner of this
//------------- code directly. Contact the legal team at ‘ZSLegal’ for assistance.
//------------- *** WARNING ***
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
// Description:
// This is an internal class that enables interactions with Zip archives
// for OPC scenarios (Zip 64 bit support)
//
// History:
// 01/26/2005: IgorBel: Initial creation.
//
//-----------------------------------------------------------------------------
using System;
using System.IO;
using System.Diagnostics;
using System.Runtime.Serialization;
using System.Windows;
using MS.Internal.WindowsBase;
namespace MS.Internal.IO.Zip
{
internal class ZipIOZip64EndOfCentralDirectoryLocatorBlock : IZipIOBlock
{
// standard IZipIOBlock functionality
public long Offset
{
get
{
return _offset;
}
}
public long Size
{
get
{
return _size;
}
}
// This property will only return reliable result if Update is called prior
public bool GetDirtyFlag(bool closingFlag)
{
return _dirtyFlag;
}
public void Move(long shiftSize)
{
if (shiftSize != 0)
{
checked{_offset +=shiftSize;}
if (_size > 0)
{
_dirtyFlag = true;
}
Debug.Assert(_offset >=0);
}
}
public void Save()
{
if (GetDirtyFlag(true) && (Size > 0))
{
BinaryWriter writer = _blockManager.BinaryWriter;
if (_blockManager.Stream.Position != _offset)
{
// we need to seek
_blockManager.Stream.Seek(_offset, SeekOrigin.Begin);
// in non seekable streams we are expected to be at the right position, no seeking required
// if this assumption is ever violated. Seek will throw on non-seekable stream, which would provide us
// with a detection mechanism for such problems
}
writer.Write(_signatureConstant);
writer.Write(_numberOfTheDiskWithTheStartOfZip64EndOfCentralDirectory);
writer.Write(_offsetOfStartOfZip64EndOfCentralDirectoryRecord);
writer.Write(_totalNumberOfDisks);
writer.Flush();
}
_dirtyFlag = false;
}
public void UpdateReferences(bool closingFlag)
{
checked
{
// check whether Central directory is loaded and update references accordingly
// if one or more of the following conditions are true
// 1. Central Directory is dirty
// 2. Zip64 End of Central Directory is dirty
// 3. streaming mode
// if Central Directory isn't loded or none of the relevant structure is dirty,
// there is nothing to update for Zip64 End Of Central directory record
if ((_blockManager.IsCentralDirectoryBlockLoaded
&& (_blockManager.Streaming
|| _blockManager.CentralDirectoryBlock.GetDirtyFlag(closingFlag))
|| _blockManager.Zip64EndOfCentralDirectoryBlock.GetDirtyFlag(closingFlag)))
{
if (_blockManager.CentralDirectoryBlock.IsZip64BitRequiredForStoring)
{
UInt64 offsetOfStartOfZip64EndOfCentralDirectoryRecord =
(UInt64)_blockManager.Zip64EndOfCentralDirectoryBlock.Offset;
// update value and mark record dirty if either it is already dirty or there is a mismatch
if ((_dirtyFlag) ||
(offsetOfStartOfZip64EndOfCentralDirectoryRecord != _offsetOfStartOfZip64EndOfCentralDirectoryRecord) ||
(_fixedMinimalRecordSize != _size))
{
_offsetOfStartOfZip64EndOfCentralDirectoryRecord = offsetOfStartOfZip64EndOfCentralDirectoryRecord;
_size = _fixedMinimalRecordSize;
_dirtyFlag = true;
}
}
else
{
// we do not need zip 64 structures
if (_size != 0)
{
_size = 0;
_dirtyFlag = true;
}
}
}
}
}
public PreSaveNotificationScanControlInstruction PreSaveNotification(long offset, long size)
{
// we can safely ignore this notification as we do not keep any data
// after parsing on disk. Everything is in memory, it is ok to override
// original End of Central directory without any additional backups
// we can also safely state that there is no need to continue the PreSafeNotification loop
// as the only blocks after the Zip64 EOCD (EOCD) doesn't have
// data that is buffered on disk
return PreSaveNotificationScanControlInstruction.Stop;
}
internal static ZipIOZip64EndOfCentralDirectoryLocatorBlock SeekableLoad (ZipIOBlockManager blockManager)
{
// This Debug assert is a secondary check in debug builds, callers are responcible for verifying condition
// in both retail and debug builds
Debug.Assert(SniffTheBlockSignature(blockManager));
long blockPosition = checked(blockManager.EndOfCentralDirectoryBlock.Offset - _fixedMinimalRecordSize);
blockManager.Stream.Seek(blockPosition, SeekOrigin.Begin);
ZipIOZip64EndOfCentralDirectoryLocatorBlock block = new ZipIOZip64EndOfCentralDirectoryLocatorBlock(blockManager);
block.ParseRecord(blockManager.BinaryReader, blockPosition);
return block;
}
internal static ZipIOZip64EndOfCentralDirectoryLocatorBlock CreateNew(ZipIOBlockManager blockManager)
{
// This Debug assert is a secondary check in debug builds, callers are responcible for verifying condition
// in both retail and debug builds
Debug.Assert(!SniffTheBlockSignature(blockManager));
ZipIOZip64EndOfCentralDirectoryLocatorBlock block = new ZipIOZip64EndOfCentralDirectoryLocatorBlock(blockManager);
block._offset = 0;
block._size = 0;
block._dirtyFlag = false;
return block;
}
internal static bool SniffTheBlockSignature(ZipIOBlockManager blockManager)
{
long suspectPos = checked(blockManager.EndOfCentralDirectoryBlock.Offset - _fixedMinimalRecordSize);
// let's check that EndOfCentralDirectoryBlock.Offset is not too close to the start of the stream
// for the record to fit there
// the second check isn't required, strictily speaking, as we are stepping back from the EOCD.offset
// however in some theoretical cases EOCD might not be trustable so to ensure that ReadUInt32
// isn't going to throw we do additional check
if ((suspectPos < 0) ||
(checked(suspectPos + sizeof(UInt32)) > blockManager.Stream.Length))
{
return false;
}
blockManager.Stream.Seek(suspectPos, SeekOrigin.Begin);
UInt32 signature = blockManager.BinaryReader.ReadUInt32();
return (signature == _signatureConstant);
}
internal long OffsetOfZip64EndOfCentralDirectoryRecord
{
get
{
return (long)_offsetOfStartOfZip64EndOfCentralDirectoryRecord;
}
}
private ZipIOZip64EndOfCentralDirectoryLocatorBlock(ZipIOBlockManager blockManager)
{
Debug.Assert(blockManager != null);
_blockManager= blockManager;
}
private void ParseRecord (BinaryReader reader, long position)
{
_signature = reader.ReadUInt32();
_numberOfTheDiskWithTheStartOfZip64EndOfCentralDirectory = reader.ReadUInt32();
_offsetOfStartOfZip64EndOfCentralDirectoryRecord = reader.ReadUInt64();
_totalNumberOfDisks = reader.ReadUInt32();
_offset = position;
_size = _fixedMinimalRecordSize;
_dirtyFlag = false;
Validate();
}
private void Validate()
{
if (_offsetOfStartOfZip64EndOfCentralDirectoryRecord > Int64.MaxValue) // C# does proper upcasting to ULONG of both operands
{
// although we are trying to support 64 bit structures
// we are limited by the CLR model for streams down to 63
// bit size for all the Uint64 fields
throw new NotSupportedException(SR.Get(SRID.Zip64StructuresTooLarge));
}
if (_signature != _signatureConstant)
{
throw new FileFormatException(SR.Get(SRID.CorruptedData));
}
if ((_totalNumberOfDisks != 1) ||
(_numberOfTheDiskWithTheStartOfZip64EndOfCentralDirectory != 0))
{
throw new NotSupportedException(SR.Get(SRID.NotSupportedMultiDisk));
}
// The offset of the ZIP 64 EOCD must preceed the location of the ZIP64 EOCD locator
if ((UInt64)_offset <= _offsetOfStartOfZip64EndOfCentralDirectoryRecord) // we assume that _offset >=0
{
throw new FileFormatException(SR.Get(SRID.CorruptedData));
}
// this record is optional size must be either 0 or _fixedMinimalRecordSize
if ((_size != _fixedMinimalRecordSize) && (_size != 0))
{
throw new FileFormatException(SR.Get(SRID.CorruptedData));
}
}
private ZipIOBlockManager _blockManager;
private long _offset;
private long _size;
private bool _dirtyFlag;
private const UInt32 _signatureConstant = 0x07064b50;
private const int _fixedMinimalRecordSize = 20;
// data persisted on disk
private UInt32 _signature = _signatureConstant;
private UInt32 _numberOfTheDiskWithTheStartOfZip64EndOfCentralDirectory;
private UInt64 _offsetOfStartOfZip64EndOfCentralDirectoryRecord;
private UInt32 _totalNumberOfDisks = 1;
}
}
// 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
- WorkflowPersistenceContext.cs
- InputLanguageEventArgs.cs
- XsdDateTime.cs
- versioninfo.cs
- GridViewSelectEventArgs.cs
- HttpRuntimeSection.cs
- TargetPerspective.cs
- DbParameterCollectionHelper.cs
- Profiler.cs
- AuthStoreRoleProvider.cs
- CommonDialog.cs
- WindowsRichEdit.cs
- QueryResponse.cs
- MetadataItemSerializer.cs
- ObjectKeyFrameCollection.cs
- DesignerActionMethodItem.cs
- RtfToXamlLexer.cs
- TemplateAction.cs
- BlurEffect.cs
- DriveNotFoundException.cs
- ToolStripMenuItem.cs
- ItemsControl.cs
- Line.cs
- ProxySimple.cs
- TextTreeUndoUnit.cs
- ContentWrapperAttribute.cs
- Wizard.cs
- AuthenticationModuleElement.cs
- ConfigurationLoader.cs
- PrinterResolution.cs
- MemoryMappedView.cs
- TranslateTransform3D.cs
- GridViewCommandEventArgs.cs
- ObjRef.cs
- Site.cs
- AssemblyHash.cs
- MissingSatelliteAssemblyException.cs
- BlurEffect.cs
- MobileSysDescriptionAttribute.cs
- XPathSingletonIterator.cs
- WSDualHttpBinding.cs
- ResourceReferenceExpression.cs
- SplitContainerDesigner.cs
- FontInfo.cs
- CompilationLock.cs
- SqlStream.cs
- ColorConvertedBitmap.cs
- DiscoveryProxy.cs
- Int64Storage.cs
- CursorConverter.cs
- TextEndOfParagraph.cs
- InternalControlCollection.cs
- NullToBooleanConverter.cs
- RegexBoyerMoore.cs
- RoleService.cs
- TextTabProperties.cs
- InputBinding.cs
- WindowsSlider.cs
- MinimizableAttributeTypeConverter.cs
- WindowShowOrOpenTracker.cs
- BufferedOutputStream.cs
- DataGridViewRowPrePaintEventArgs.cs
- IndexerNameAttribute.cs
- OAVariantLib.cs
- SystemParameters.cs
- SafeMILHandle.cs
- Missing.cs
- SslStream.cs
- OrderByQueryOptionExpression.cs
- OpCopier.cs
- ArgumentException.cs
- BaseAddressElement.cs
- UnlockInstanceAsyncResult.cs
- InheritanceContextHelper.cs
- ResolveInfo.cs
- _NetworkingPerfCounters.cs
- PropertyEmitter.cs
- IDQuery.cs
- AttributeCollection.cs
- GradientBrush.cs
- HttpCookieCollection.cs
- TextEvent.cs
- FlowNode.cs
- BinHexDecoder.cs
- SparseMemoryStream.cs
- ApplicationSettingsBase.cs
- ForceCopyBuildProvider.cs
- safelinkcollection.cs
- _Win32.cs
- ValueQuery.cs
- LinkTarget.cs
- Dynamic.cs
- BufferedGraphicsManager.cs
- GeneralTransform3D.cs
- ITreeGenerator.cs
- MdiWindowListItemConverter.cs
- ReaderOutput.cs
- CopyCodeAction.cs
- StrokeSerializer.cs
- SapiRecoInterop.cs