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
- StreamInfo.cs
- DebugManager.cs
- OutputCacheProfile.cs
- DynamicDocumentPaginator.cs
- ClientTargetSection.cs
- Win32MouseDevice.cs
- CustomExpressionEventArgs.cs
- DesignerLoader.cs
- SmiSettersStream.cs
- FocusWithinProperty.cs
- Win32PrintDialog.cs
- RoleBoolean.cs
- TriggerAction.cs
- AxParameterData.cs
- WindowsUserNameSecurityTokenAuthenticator.cs
- PkcsMisc.cs
- AttributeProviderAttribute.cs
- MobileCategoryAttribute.cs
- OdbcConnectionOpen.cs
- HttpContextServiceHost.cs
- RenderingBiasValidation.cs
- SiteMapPath.cs
- InvalidPropValue.cs
- ClassDataContract.cs
- SystemDiagnosticsSection.cs
- StandardCommandToolStripMenuItem.cs
- TypeElementCollection.cs
- SyntaxCheck.cs
- XmlDataProvider.cs
- OutputCacheProfileCollection.cs
- XmlQueryTypeFactory.cs
- Cursors.cs
- BulletChrome.cs
- CodeTypeOfExpression.cs
- DataGridTableStyleMappingNameEditor.cs
- EventTrigger.cs
- FixedSOMTableCell.cs
- ToolStripDropTargetManager.cs
- FastPropertyAccessor.cs
- MonitorWrapper.cs
- MethodExpression.cs
- ConstNode.cs
- RPIdentityRequirement.cs
- GenericTextProperties.cs
- BufferModeSettings.cs
- ImageCollectionEditor.cs
- XmlMtomWriter.cs
- BufferBuilder.cs
- PropertyDescriptorGridEntry.cs
- ItemCollectionEditor.cs
- ISAPIApplicationHost.cs
- EmptyImpersonationContext.cs
- DigestTraceRecordHelper.cs
- EncryptedPackage.cs
- DSASignatureDeformatter.cs
- WebPartConnectionsCloseVerb.cs
- IndentTextWriter.cs
- RecipientInfo.cs
- SignatureDescription.cs
- NameSpaceExtractor.cs
- UserPreferenceChangedEventArgs.cs
- CustomErrorCollection.cs
- objectresult_tresulttype.cs
- LineUtil.cs
- SectionVisual.cs
- ContextMenu.cs
- HScrollBar.cs
- LexicalChunk.cs
- ContentTextAutomationPeer.cs
- MultiSelector.cs
- OperationContractGenerationContext.cs
- DataRelation.cs
- EmptyReadOnlyDictionaryInternal.cs
- WebAdminConfigurationHelper.cs
- CodeBlockBuilder.cs
- TargetParameterCountException.cs
- NativeMethods.cs
- XmlElementAttributes.cs
- StringWriter.cs
- Int16AnimationBase.cs
- XMLDiffLoader.cs
- WindowsButton.cs
- BamlWriter.cs
- TextServicesCompartmentContext.cs
- GetWinFXPath.cs
- PrintControllerWithStatusDialog.cs
- PeerPresenceInfo.cs
- InheritablePropertyChangeInfo.cs
- CompoundFileStorageReference.cs
- x509store.cs
- AnnotationResourceChangedEventArgs.cs
- XmlSchemaSimpleTypeList.cs
- SecurityTokenException.cs
- PropertyValueChangedEvent.cs
- DataGridViewRowStateChangedEventArgs.cs
- TypeConverterAttribute.cs
- TimeStampChecker.cs
- BitmapEffect.cs
- SqlExpressionNullability.cs
- XsdDateTime.cs