Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / 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
- ResXFileRef.cs
- NamedPipeAppDomainProtocolHandler.cs
- CodeTypeParameterCollection.cs
- Timer.cs
- XmlDataFileEditor.cs
- BinaryParser.cs
- StrokeNodeOperations.cs
- QuaternionKeyFrameCollection.cs
- WebReferenceCollection.cs
- AssociatedControlConverter.cs
- ConvertersCollection.cs
- EntryIndex.cs
- IntSecurity.cs
- XPathParser.cs
- ListItemParagraph.cs
- SendKeys.cs
- ByteAnimationUsingKeyFrames.cs
- Compiler.cs
- GcSettings.cs
- InternalCompensate.cs
- TypeName.cs
- DbResourceAllocator.cs
- DataColumnPropertyDescriptor.cs
- MailBnfHelper.cs
- sqlser.cs
- ExceptionUtil.cs
- SmiTypedGetterSetter.cs
- Matrix3D.cs
- SynchronizedInputHelper.cs
- ReadOnlyNameValueCollection.cs
- SafeNativeMethods.cs
- HtmlShim.cs
- COM2IDispatchConverter.cs
- StorageTypeMapping.cs
- SqlDataSourceView.cs
- GifBitmapEncoder.cs
- CodeLabeledStatement.cs
- ServerIdentity.cs
- PropertyCondition.cs
- SaveFileDialog.cs
- FirstMatchCodeGroup.cs
- ColumnCollection.cs
- SqlDependencyListener.cs
- TimeSpanStorage.cs
- GridViewRowEventArgs.cs
- EditorZone.cs
- VirtualDirectoryMappingCollection.cs
- TextSelectionProcessor.cs
- CngAlgorithm.cs
- Table.cs
- SystemInfo.cs
- DockAndAnchorLayout.cs
- MarkupObject.cs
- PropertyEmitterBase.cs
- CustomMenuItemCollection.cs
- InvalidPrinterException.cs
- CodeAttributeArgumentCollection.cs
- RuntimeConfig.cs
- peersecuritysettings.cs
- ProviderBase.cs
- Transform3DGroup.cs
- SystemParameters.cs
- FixedFlowMap.cs
- RMPublishingDialog.cs
- MarginsConverter.cs
- Char.cs
- XPathNavigatorKeyComparer.cs
- SerializationInfoEnumerator.cs
- SqlDependencyUtils.cs
- UnlockCardRequest.cs
- SystemIcons.cs
- VerticalAlignConverter.cs
- TemplateField.cs
- _ConnectionGroup.cs
- Compiler.cs
- NotifyParentPropertyAttribute.cs
- StreamInfo.cs
- JsonFormatGeneratorStatics.cs
- TextEncodedRawTextWriter.cs
- CreateUserWizardStep.cs
- HttpResponseHeader.cs
- ResourceBinder.cs
- DependencyPropertyChangedEventArgs.cs
- XDRSchema.cs
- OpCopier.cs
- TextLine.cs
- ImageMapEventArgs.cs
- RequiredFieldValidator.cs
- OpCodes.cs
- SqlConnectionString.cs
- SQLStringStorage.cs
- Transform.cs
- ReadOnlyHierarchicalDataSourceView.cs
- _ContextAwareResult.cs
- _DisconnectOverlappedAsyncResult.cs
- ReadOnlyMetadataCollection.cs
- TreeViewEvent.cs
- InvokeMethod.cs
- XamlTypeMapper.cs
- XmlSchemaType.cs