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
- RangeValueProviderWrapper.cs
- Item.cs
- ChildrenQuery.cs
- UnwrappedTypesXmlSerializerManager.cs
- FilteredDataSetHelper.cs
- IndicFontClient.cs
- TraceSection.cs
- XPathParser.cs
- DataViewManagerListItemTypeDescriptor.cs
- RightsManagementEncryptedStream.cs
- PointLightBase.cs
- ScriptControlDescriptor.cs
- UserUseLicenseDictionaryLoader.cs
- DesignerOptionService.cs
- AttributeEmitter.cs
- CurrencyManager.cs
- DataRecordObjectView.cs
- CodeTypeDeclaration.cs
- EFDataModelProvider.cs
- DataRowCollection.cs
- Bitmap.cs
- InvokeProviderWrapper.cs
- regiisutil.cs
- MessageLoggingFilterTraceRecord.cs
- CustomExpressionEventArgs.cs
- XsdDuration.cs
- BrushMappingModeValidation.cs
- TreeView.cs
- AccessKeyManager.cs
- _SingleItemRequestCache.cs
- WebControlAdapter.cs
- MatrixStack.cs
- EditorPartCollection.cs
- UrlMappingsSection.cs
- DataTable.cs
- MenuItemBindingCollection.cs
- WeakReferenceEnumerator.cs
- ItemList.cs
- CodeTypeDeclarationCollection.cs
- SettingsSavedEventArgs.cs
- CodeDirectionExpression.cs
- ParallelForEach.cs
- DesignerActionMethodItem.cs
- DrawingDrawingContext.cs
- PublisherIdentityPermission.cs
- XmlSchemaAnyAttribute.cs
- KeyMatchBuilder.cs
- InkPresenterAutomationPeer.cs
- StyleHelper.cs
- UidPropertyAttribute.cs
- ArrangedElement.cs
- DataGridToolTip.cs
- PageThemeBuildProvider.cs
- ListControlBuilder.cs
- KeyValuePairs.cs
- entityreference_tresulttype.cs
- CharacterString.cs
- SslStream.cs
- XPathNodeIterator.cs
- GeometryHitTestResult.cs
- CodeEntryPointMethod.cs
- SqlDataSourceView.cs
- DoubleMinMaxAggregationOperator.cs
- PropertyBuilder.cs
- NativeMethods.cs
- RestHandler.cs
- CompilerTypeWithParams.cs
- ViewLoader.cs
- FixedDSBuilder.cs
- CollectionBuilder.cs
- MenuItem.cs
- SafeLocalAllocation.cs
- DoubleLink.cs
- CssTextWriter.cs
- RangeBase.cs
- ArgumentException.cs
- SimpleExpression.cs
- NullableDoubleSumAggregationOperator.cs
- DataControlButton.cs
- DeferredRunTextReference.cs
- TypeGeneratedEventArgs.cs
- CodePageEncoding.cs
- OpCellTreeNode.cs
- XmlSchemaComplexContentRestriction.cs
- WS2007FederationHttpBinding.cs
- TypeConverterBase.cs
- DbConnectionOptions.cs
- DefaultValueTypeConverter.cs
- basenumberconverter.cs
- EntityConnectionStringBuilderItem.cs
- AssertFilter.cs
- Figure.cs
- IntSecurity.cs
- MailMessageEventArgs.cs
- ZoneButton.cs
- TextBoxAutoCompleteSourceConverter.cs
- DebugView.cs
- ISFTagAndGuidCache.cs
- PerformanceCounterPermission.cs