Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Base / MS / Internal / IO / Zip / ZipIOZip64EndOfCentralDirectoryLocatorBlock.cs / 1 / 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; 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; 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
- TreeIterator.cs
- KerberosTokenFactoryCredential.cs
- PersistenceException.cs
- CompilerCollection.cs
- And.cs
- RuntimeWrappedException.cs
- Activator.cs
- ProviderMetadata.cs
- HybridDictionary.cs
- XmlMembersMapping.cs
- FieldNameLookup.cs
- ErrorRuntimeConfig.cs
- AccessControlEntry.cs
- RuntimeHandles.cs
- CollectionEditVerbManager.cs
- SqlClientMetaDataCollectionNames.cs
- UdpConstants.cs
- BinaryWriter.cs
- Translator.cs
- ZoomPercentageConverter.cs
- UndoManager.cs
- CredentialCache.cs
- Window.cs
- MediaTimeline.cs
- DbDataSourceEnumerator.cs
- WindowsGraphics2.cs
- FlowDocumentReader.cs
- XmlDataSource.cs
- BinaryReader.cs
- StringPropertyBuilder.cs
- sqlstateclientmanager.cs
- ConfigurationManagerHelper.cs
- IteratorDescriptor.cs
- HtmlShim.cs
- TextParentUndoUnit.cs
- DateTimeSerializationSection.cs
- PersianCalendar.cs
- QilReference.cs
- OutputWindow.cs
- ArrayHelper.cs
- WSSecurityJan2004.cs
- TypeTypeConverter.cs
- BitmapPalettes.cs
- ListSortDescriptionCollection.cs
- Validator.cs
- LineVisual.cs
- CollectionBuilder.cs
- WizardSideBarListControlItemEventArgs.cs
- ProgressiveCrcCalculatingStream.cs
- NativeMethods.cs
- EmptyImpersonationContext.cs
- SplineQuaternionKeyFrame.cs
- ColorDialog.cs
- ApplicationTrust.cs
- PropertyToken.cs
- CriticalHandle.cs
- SemanticTag.cs
- AssertFilter.cs
- IndexedString.cs
- EncoderFallback.cs
- ColorTranslator.cs
- InvalidCastException.cs
- ScopelessEnumAttribute.cs
- QualificationDataItem.cs
- ResourceContainer.cs
- DrawListViewColumnHeaderEventArgs.cs
- VersionPair.cs
- IMembershipProvider.cs
- CookielessHelper.cs
- SizeAnimationUsingKeyFrames.cs
- embossbitmapeffect.cs
- ValidationError.cs
- EnumerableRowCollection.cs
- RewritingValidator.cs
- InternalTypeHelper.cs
- RectangleGeometry.cs
- EntitySetDataBindingList.cs
- GridErrorDlg.cs
- BinaryFormatterWriter.cs
- GlobalDataBindingHandler.cs
- ToolStrip.cs
- HttpBufferlessInputStream.cs
- CroppedBitmap.cs
- Pair.cs
- RequestQueue.cs
- ConnectionManagementElementCollection.cs
- CatalogPartCollection.cs
- UrlPath.cs
- RtfNavigator.cs
- DataPagerFieldItem.cs
- TaiwanLunisolarCalendar.cs
- SaveFileDialog.cs
- FileStream.cs
- VirtualPathUtility.cs
- ListBase.cs
- Message.cs
- ConnectionStringSettingsCollection.cs
- WindowsFont.cs
- PhysicalAddress.cs
- TimelineGroup.cs