Code:
/ 4.0 / 4.0 / untmp / 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.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- GeometryCombineModeValidation.cs
- StructureChangedEventArgs.cs
- IisTraceWebEventProvider.cs
- StateMachineDesignerPaint.cs
- CacheManager.cs
- XMLUtil.cs
- DocumentSequenceHighlightLayer.cs
- Translator.cs
- WpfWebRequestHelper.cs
- DataGridViewToolTip.cs
- DataGridTextColumn.cs
- Substitution.cs
- _AcceptOverlappedAsyncResult.cs
- Int32Rect.cs
- HttpWriter.cs
- CodeMemberMethod.cs
- DynamicDataExtensions.cs
- WebPartVerbCollection.cs
- IItemProperties.cs
- TableDetailsRow.cs
- AssociationSet.cs
- CircleHotSpot.cs
- UInt16.cs
- ToolStripItemRenderEventArgs.cs
- DependencyObjectType.cs
- ConsoleCancelEventArgs.cs
- ResXBuildProvider.cs
- ParallelEnumerable.cs
- FontUnit.cs
- MissingSatelliteAssemblyException.cs
- CharAnimationUsingKeyFrames.cs
- Matrix3D.cs
- PopupControlService.cs
- EntitySqlQueryState.cs
- PositiveTimeSpanValidator.cs
- WebPartZone.cs
- SystemIcmpV4Statistics.cs
- _ShellExpression.cs
- DoubleAnimation.cs
- EventLogEntry.cs
- SystemColorTracker.cs
- _WinHttpWebProxyDataBuilder.cs
- ObjectDesignerDataSourceView.cs
- FileDialogCustomPlacesCollection.cs
- ProtocolsInstallComponent.cs
- StorageAssociationTypeMapping.cs
- ConfigurationManagerInternalFactory.cs
- XmlUTF8TextReader.cs
- ContainerUIElement3D.cs
- EntityProviderFactory.cs
- Accessors.cs
- QuerySettings.cs
- URLIdentityPermission.cs
- FilterQuery.cs
- ConfigUtil.cs
- SortKey.cs
- NavigationWindowAutomationPeer.cs
- WindowsMenu.cs
- PositiveTimeSpanValidator.cs
- DefaultObjectMappingItemCollection.cs
- AccessControlList.cs
- PlacementWorkspace.cs
- FileDialog.cs
- Enumerable.cs
- MenuCommand.cs
- ConfigurationValidatorBase.cs
- HttpListenerResponse.cs
- BitmapEffect.cs
- SecurityException.cs
- FixedHyperLink.cs
- FontNameConverter.cs
- MSG.cs
- ApplicationGesture.cs
- EncoderReplacementFallback.cs
- SoapFault.cs
- DirectoryObjectSecurity.cs
- InstallerTypeAttribute.cs
- ErrorEventArgs.cs
- LinqExpressionNormalizer.cs
- DialogResultConverter.cs
- TypeUtil.cs
- TemplatedControlDesigner.cs
- TextSpanModifier.cs
- StylusButtonEventArgs.cs
- MetadataHelper.cs
- loginstatus.cs
- DateRangeEvent.cs
- WebPartsPersonalizationAuthorization.cs
- MergePropertyDescriptor.cs
- NameValuePermission.cs
- WebProxyScriptElement.cs
- BinaryFormatterWriter.cs
- ResolveMatchesMessage11.cs
- DebugViewWriter.cs
- RadialGradientBrush.cs
- CoreSwitches.cs
- AttributeCollection.cs
- GridViewPageEventArgs.cs
- URLIdentityPermission.cs
- FullTrustAssemblyCollection.cs