Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Base / MS / Internal / IO / Zip / ZipIOExtraField.cs / 1 / ZipIOExtraField.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 is used to implement parsing and // of the extra field optionally present in the fileHeader and Central Dir // // History: // 05/16/2005: IgorBel: Initial creation. // 03/23/2006: YoungGK: Added support for Padding Extra Field // //----------------------------------------------------------------------------- using System; using System.IO; using System.Diagnostics; using System.Collections; using System.Globalization; using System.Runtime.Serialization; using System.Windows; namespace MS.Internal.IO.Zip { internal class ZipIOExtraField { internal static ZipIOExtraField CreateNew(bool createPadding) { // we have been asked to create a new record, current zip io implementation will add at most one Zip64 block ZipIOExtraField extraField = new ZipIOExtraField(); extraField._zip64Element = ZipIOExtraFieldZip64Element.CreateNew(); if (createPadding) { extraField._paddingElement = ZipIOExtraFieldPaddingElement.CreateNew(); } return extraField; } internal static ZipIOExtraField ParseRecord(BinaryReader reader, ZipIOZip64ExtraFieldUsage zip64extraFieldUsage, ushort expectedExtraFieldSize) { // most of the files are not ZIP 64, and instead of trying to parse it we should create new empty record if (expectedExtraFieldSize == 0) { if (zip64extraFieldUsage != ZipIOZip64ExtraFieldUsage.None) { // in case there is an expectation by the caller for a non empty record we should throw throw new FileFormatException(SR.Get(SRID.CorruptedData)); } // We are creating Extra Fields for the existing Local File Header, // so no need to create a new padding field return CreateNew(false); } ZipIOExtraField extraField = new ZipIOExtraField(); // Parse all Extra elements from Extra Field while (expectedExtraFieldSize > 0) { if (expectedExtraFieldSize < ZipIOExtraFieldElement.MinimumSize) { throw new FileFormatException(SR.Get(SRID.CorruptedData)); } ZipIOExtraFieldElement newElement = ZipIOExtraFieldElement.Parse(reader, zip64extraFieldUsage); ZipIOExtraFieldZip64Element zip64Element = newElement as ZipIOExtraFieldZip64Element; ZipIOExtraFieldPaddingElement paddingElement = newElement as ZipIOExtraFieldPaddingElement; // if we have found the Zip 64 record. let's remember it if (zip64Element != null) { if (extraField._zip64Element != null) { // multiple ZIP 64 extra fields are not allowed throw new FileFormatException(SR.Get(SRID.CorruptedData)); } extraField._zip64Element = zip64Element; } else if (paddingElement != null) { if (extraField._paddingElement != null) { // multiple padding extra fields are not allowed throw new FileFormatException(SR.Get(SRID.CorruptedData)); } extraField._paddingElement = paddingElement; } else { if (extraField._extraFieldElements == null) extraField._extraFieldElements = new ArrayList(3); // we expect to see a few records there, as it sould have been produced by other authoring systems. // any other instances of extra fields with the same id are allowed extraField._extraFieldElements.Add(newElement); } checked { expectedExtraFieldSize -= newElement.Size; } } // if we didn't end up at the exact expected position, we are treating this as a corrupted file if (expectedExtraFieldSize != 0) { throw new FileFormatException(SR.Get(SRID.CorruptedData)); } // As we treat the ZIP 64 extra field as optional for all version >= 4.5 // we need to explicitly consider a case when it is missing if (extraField._zip64Element == null) { extraField._zip64Element = ZipIOExtraFieldZip64Element.CreateNew(); } ///////////////////////////////////////////////////////////////////// // extraField.Validate(); // an instance Validate function is removed to fix FxCop violation, please add it back // if extra validation steps are required // // we are checking for uniqueness of the Zip 64 header ID in the Parse function. // Although it might be a good idea to check for record id uniqueness in general, // we are treating the rest of the field as a bag of bits, so it is probably not worth it to // search for other duplicate ID especially as appnote considers ID duplication a possibility // and even suggest a work around for file producers. ///////////////////////////////////////////////////////////////////// return extraField; } internal void Save(BinaryWriter writer) { // write Out the Zip 64 extra field first if (_zip64Element.SizeField > 0) { _zip64Element.Save(writer); } // write Out the padding field if (_paddingElement != null) { _paddingElement.Save(writer); } if (_extraFieldElements != null) { foreach (ZipIOExtraFieldElement extraFieldElement in _extraFieldElements) { extraFieldElement.Save(writer); } } } // Add or remove padding for the given size change internal void UpdatePadding(long size) { // If the local file header changed more than 100 bytes, it means // there are some logical errors Debug.Assert(Math.Abs(size) <= 100); // The header size change should be no more than what we can hold in UInt16 if (Math.Abs(size) > UInt16.MaxValue) return; // Header size increased; need to remove padding if there is an existing padding structure if (size > 0 && _paddingElement != null) { // There is enough padding left over to do size adjustment // No need to use checked{} since _paddingElement.PaddingSize >= size if (_paddingElement.PaddingSize >= size) _paddingElement.PaddingSize -= (UInt16) size; // The size of the whole padding structure exactly matches the size change else if (_paddingElement.Size == size) { // Then the padding structure can be completely removed // to accommodate the size change _paddingElement = null; } return; } // Header size decreased; need to add padding if (size < 0) { // Padding structure is not there but, the size change is big enough for one // to be created if (_paddingElement == null) { // No need to use checked{} since size is long type // and size < 0 // and (ZipIOExtraFieldPaddingElement.MinimumFieldDataSize + ZipIOExtraFieldElement.MinimumSize) // is small number that can not cause the overflow size += (ZipIOExtraFieldPaddingElement.MinimumFieldDataSize + ZipIOExtraFieldElement.MinimumSize); if (size >= 0) { _paddingElement = new ZipIOExtraFieldPaddingElement(); // No need to use checked{} since size > 0 and less than UInt16.MaxValue _paddingElement.PaddingSize = (UInt16) size; } } else { // Check if we hit the max padding allowed if ((_paddingElement.PaddingSize - size) > UInt16.MaxValue) return; // No need to use checked{} since we already check the overflow _paddingElement.PaddingSize = (UInt16) (_paddingElement.PaddingSize - size); } } } internal UInt16 Size { get { UInt16 size = 0; if (_extraFieldElements != null) { foreach (ZipIOExtraFieldElement extraFieldElement in _extraFieldElements) { checked{size += extraFieldElement.Size;} } } checked{size += _zip64Element.Size;} if (_paddingElement != null) { checked { size += _paddingElement.Size; } } return size; } } internal ZipIOZip64ExtraFieldUsage Zip64ExtraFieldUsage { get { return _zip64Element.Zip64ExtraFieldUsage; } set { _zip64Element.Zip64ExtraFieldUsage = value; } } internal UInt32 DiskNumberOfFileStart { get { return _zip64Element.DiskNumber; } } internal long OffsetOfLocalHeader { get { return _zip64Element.OffsetOfLocalHeader; } set { _zip64Element.OffsetOfLocalHeader = value; } } internal long CompressedSize { get { return _zip64Element.CompressedSize; } set { _zip64Element.CompressedSize = value; } } internal long UncompressedSize { get { return _zip64Element.UncompressedSize; } set { _zip64Element.UncompressedSize = value; } } private ZipIOExtraField() { } private ArrayList _extraFieldElements; private ZipIOExtraFieldZip64Element _zip64Element; private ZipIOExtraFieldPaddingElement _paddingElement; } } // 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 is used to implement parsing and // of the extra field optionally present in the fileHeader and Central Dir // // History: // 05/16/2005: IgorBel: Initial creation. // 03/23/2006: YoungGK: Added support for Padding Extra Field // //----------------------------------------------------------------------------- using System; using System.IO; using System.Diagnostics; using System.Collections; using System.Globalization; using System.Runtime.Serialization; using System.Windows; namespace MS.Internal.IO.Zip { internal class ZipIOExtraField { internal static ZipIOExtraField CreateNew(bool createPadding) { // we have been asked to create a new record, current zip io implementation will add at most one Zip64 block ZipIOExtraField extraField = new ZipIOExtraField(); extraField._zip64Element = ZipIOExtraFieldZip64Element.CreateNew(); if (createPadding) { extraField._paddingElement = ZipIOExtraFieldPaddingElement.CreateNew(); } return extraField; } internal static ZipIOExtraField ParseRecord(BinaryReader reader, ZipIOZip64ExtraFieldUsage zip64extraFieldUsage, ushort expectedExtraFieldSize) { // most of the files are not ZIP 64, and instead of trying to parse it we should create new empty record if (expectedExtraFieldSize == 0) { if (zip64extraFieldUsage != ZipIOZip64ExtraFieldUsage.None) { // in case there is an expectation by the caller for a non empty record we should throw throw new FileFormatException(SR.Get(SRID.CorruptedData)); } // We are creating Extra Fields for the existing Local File Header, // so no need to create a new padding field return CreateNew(false); } ZipIOExtraField extraField = new ZipIOExtraField(); // Parse all Extra elements from Extra Field while (expectedExtraFieldSize > 0) { if (expectedExtraFieldSize < ZipIOExtraFieldElement.MinimumSize) { throw new FileFormatException(SR.Get(SRID.CorruptedData)); } ZipIOExtraFieldElement newElement = ZipIOExtraFieldElement.Parse(reader, zip64extraFieldUsage); ZipIOExtraFieldZip64Element zip64Element = newElement as ZipIOExtraFieldZip64Element; ZipIOExtraFieldPaddingElement paddingElement = newElement as ZipIOExtraFieldPaddingElement; // if we have found the Zip 64 record. let's remember it if (zip64Element != null) { if (extraField._zip64Element != null) { // multiple ZIP 64 extra fields are not allowed throw new FileFormatException(SR.Get(SRID.CorruptedData)); } extraField._zip64Element = zip64Element; } else if (paddingElement != null) { if (extraField._paddingElement != null) { // multiple padding extra fields are not allowed throw new FileFormatException(SR.Get(SRID.CorruptedData)); } extraField._paddingElement = paddingElement; } else { if (extraField._extraFieldElements == null) extraField._extraFieldElements = new ArrayList(3); // we expect to see a few records there, as it sould have been produced by other authoring systems. // any other instances of extra fields with the same id are allowed extraField._extraFieldElements.Add(newElement); } checked { expectedExtraFieldSize -= newElement.Size; } } // if we didn't end up at the exact expected position, we are treating this as a corrupted file if (expectedExtraFieldSize != 0) { throw new FileFormatException(SR.Get(SRID.CorruptedData)); } // As we treat the ZIP 64 extra field as optional for all version >= 4.5 // we need to explicitly consider a case when it is missing if (extraField._zip64Element == null) { extraField._zip64Element = ZipIOExtraFieldZip64Element.CreateNew(); } ///////////////////////////////////////////////////////////////////// // extraField.Validate(); // an instance Validate function is removed to fix FxCop violation, please add it back // if extra validation steps are required // // we are checking for uniqueness of the Zip 64 header ID in the Parse function. // Although it might be a good idea to check for record id uniqueness in general, // we are treating the rest of the field as a bag of bits, so it is probably not worth it to // search for other duplicate ID especially as appnote considers ID duplication a possibility // and even suggest a work around for file producers. ///////////////////////////////////////////////////////////////////// return extraField; } internal void Save(BinaryWriter writer) { // write Out the Zip 64 extra field first if (_zip64Element.SizeField > 0) { _zip64Element.Save(writer); } // write Out the padding field if (_paddingElement != null) { _paddingElement.Save(writer); } if (_extraFieldElements != null) { foreach (ZipIOExtraFieldElement extraFieldElement in _extraFieldElements) { extraFieldElement.Save(writer); } } } // Add or remove padding for the given size change internal void UpdatePadding(long size) { // If the local file header changed more than 100 bytes, it means // there are some logical errors Debug.Assert(Math.Abs(size) <= 100); // The header size change should be no more than what we can hold in UInt16 if (Math.Abs(size) > UInt16.MaxValue) return; // Header size increased; need to remove padding if there is an existing padding structure if (size > 0 && _paddingElement != null) { // There is enough padding left over to do size adjustment // No need to use checked{} since _paddingElement.PaddingSize >= size if (_paddingElement.PaddingSize >= size) _paddingElement.PaddingSize -= (UInt16) size; // The size of the whole padding structure exactly matches the size change else if (_paddingElement.Size == size) { // Then the padding structure can be completely removed // to accommodate the size change _paddingElement = null; } return; } // Header size decreased; need to add padding if (size < 0) { // Padding structure is not there but, the size change is big enough for one // to be created if (_paddingElement == null) { // No need to use checked{} since size is long type // and size < 0 // and (ZipIOExtraFieldPaddingElement.MinimumFieldDataSize + ZipIOExtraFieldElement.MinimumSize) // is small number that can not cause the overflow size += (ZipIOExtraFieldPaddingElement.MinimumFieldDataSize + ZipIOExtraFieldElement.MinimumSize); if (size >= 0) { _paddingElement = new ZipIOExtraFieldPaddingElement(); // No need to use checked{} since size > 0 and less than UInt16.MaxValue _paddingElement.PaddingSize = (UInt16) size; } } else { // Check if we hit the max padding allowed if ((_paddingElement.PaddingSize - size) > UInt16.MaxValue) return; // No need to use checked{} since we already check the overflow _paddingElement.PaddingSize = (UInt16) (_paddingElement.PaddingSize - size); } } } internal UInt16 Size { get { UInt16 size = 0; if (_extraFieldElements != null) { foreach (ZipIOExtraFieldElement extraFieldElement in _extraFieldElements) { checked{size += extraFieldElement.Size;} } } checked{size += _zip64Element.Size;} if (_paddingElement != null) { checked { size += _paddingElement.Size; } } return size; } } internal ZipIOZip64ExtraFieldUsage Zip64ExtraFieldUsage { get { return _zip64Element.Zip64ExtraFieldUsage; } set { _zip64Element.Zip64ExtraFieldUsage = value; } } internal UInt32 DiskNumberOfFileStart { get { return _zip64Element.DiskNumber; } } internal long OffsetOfLocalHeader { get { return _zip64Element.OffsetOfLocalHeader; } set { _zip64Element.OffsetOfLocalHeader = value; } } internal long CompressedSize { get { return _zip64Element.CompressedSize; } set { _zip64Element.CompressedSize = value; } } internal long UncompressedSize { get { return _zip64Element.UncompressedSize; } set { _zip64Element.UncompressedSize = value; } } private ZipIOExtraField() { } private ArrayList _extraFieldElements; private ZipIOExtraFieldZip64Element _zip64Element; private ZipIOExtraFieldPaddingElement _paddingElement; } } // 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
- SingleConverter.cs
- ListViewInsertEventArgs.cs
- DataGridViewRowErrorTextNeededEventArgs.cs
- wgx_render.cs
- safex509handles.cs
- ExpanderAutomationPeer.cs
- _FixedSizeReader.cs
- ClientFormsIdentity.cs
- PageThemeParser.cs
- ExternalDataExchangeService.cs
- ToolStripArrowRenderEventArgs.cs
- SByteStorage.cs
- HybridDictionary.cs
- ButtonBase.cs
- MessageHeaders.cs
- SQLInt16Storage.cs
- DataGridViewComboBoxEditingControl.cs
- WebCategoryAttribute.cs
- DocumentViewerBase.cs
- CodeArrayCreateExpression.cs
- StylusSystemGestureEventArgs.cs
- DataBindingCollection.cs
- Activity.cs
- DataRowChangeEvent.cs
- TransactedBatchContext.cs
- UTF7Encoding.cs
- KnowledgeBase.cs
- CompositionDesigner.cs
- TCEAdapterGenerator.cs
- KeyToListMap.cs
- UnsafeNativeMethodsPenimc.cs
- ActivationServices.cs
- SqlGatherConsumedAliases.cs
- _ShellExpression.cs
- CachedFontFamily.cs
- GPStream.cs
- Parser.cs
- ExternalDataExchangeService.cs
- GorillaCodec.cs
- RequestCacheManager.cs
- NetStream.cs
- EntityDataReader.cs
- DataBindingHandlerAttribute.cs
- RSAOAEPKeyExchangeDeformatter.cs
- DocumentStream.cs
- CultureInfoConverter.cs
- InputScopeNameConverter.cs
- TemplateControl.cs
- Bidi.cs
- ExtensionsSection.cs
- MarshalDirectiveException.cs
- SpeechRecognitionEngine.cs
- ProfilePropertyMetadata.cs
- WebPartMenu.cs
- RoleGroupCollection.cs
- GeometryHitTestResult.cs
- ConfigurationStrings.cs
- AnimationClock.cs
- BitmapEffectState.cs
- SatelliteContractVersionAttribute.cs
- ButtonChrome.cs
- CqlParser.cs
- PageOutputQuality.cs
- CharUnicodeInfo.cs
- RC2CryptoServiceProvider.cs
- SafeCancelMibChangeNotify.cs
- EntityDataSourceReferenceGroup.cs
- RecordsAffectedEventArgs.cs
- SqlUdtInfo.cs
- TimeZoneInfo.cs
- SrgsElementFactory.cs
- PositiveTimeSpanValidatorAttribute.cs
- xmlsaver.cs
- ContentElement.cs
- AnnotationResource.cs
- BitHelper.cs
- Point3DCollectionValueSerializer.cs
- DBDataPermission.cs
- SchemaElementLookUpTableEnumerator.cs
- HwndSubclass.cs
- ListenerElementsCollection.cs
- EventLogPermission.cs
- CriticalExceptions.cs
- RtfControls.cs
- Formatter.cs
- HierarchicalDataSourceControl.cs
- GridSplitter.cs
- RequestChannel.cs
- EntitySetBase.cs
- ProfileManager.cs
- CheckPair.cs
- WorkflowQueuingService.cs
- MessageSmuggler.cs
- SQlBooleanStorage.cs
- TransportListener.cs
- CompositeFontParser.cs
- ResXDataNode.cs
- DataGridViewComboBoxEditingControl.cs
- ContentPresenter.cs
- __ConsoleStream.cs