diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/IO/Packaging/DeobfuscatingStream.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/IO/Packaging/DeobfuscatingStream.cs
index 82c11c88ee9..0018d4048dd 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/IO/Packaging/DeobfuscatingStream.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/IO/Packaging/DeobfuscatingStream.cs
@@ -203,7 +203,7 @@ internal DeobfuscatingStream(Stream obfuscatedStream, Uri streamUri, bool leaveO
// Make sure streamUri is in the correct form; getting partUri from it will do all necessary checks for error
// conditions; We also have to make sure that it has a part name
- Uri partUri = PackUriHelper.GetPartUri(streamUri);
+ Uri partUri = System.IO.Packaging.PackUriHelper.GetPartUri(streamUri);
if (partUri == null)
{
throw new InvalidOperationException(SR.Get(SRID.InvalidPartName));
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/IO/Packaging/PackWebRequestFactory.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/IO/Packaging/PackWebRequestFactory.cs
index cb84202eaa5..8dc9d028bb1 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/IO/Packaging/PackWebRequestFactory.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/IO/Packaging/PackWebRequestFactory.cs
@@ -74,9 +74,8 @@ WebRequest IWebRequestCreate.Create(Uri uri)
#endif
// only inspect cache if part name is present because cache only contains an object, not
// the stream it was derived from
- Uri packageUri;
- Uri partUri;
- MS.Internal.IO.Packaging.PackUriHelper.ValidateAndGetPackUriComponents(uri, out packageUri, out partUri);
+ Uri packageUri = System.IO.Packaging.PackUriHelper.GetPackageUri(uri);
+ Uri partUri = System.IO.Packaging.PackUriHelper.GetPartUri(uri);
if (partUri != null)
{
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/AppModel/AppModelKnownContentFactory.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/AppModel/AppModelKnownContentFactory.cs
index 7161454fb33..d81ce14f2b2 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/AppModel/AppModelKnownContentFactory.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/AppModel/AppModelKnownContentFactory.cs
@@ -25,8 +25,6 @@
using System.ComponentModel;
using System.Windows.Controls;
-using PackUriHelper = MS.Internal.IO.Packaging.PackUriHelper;
-
namespace MS.Internal.AppModel
{
// !!!! Note: Those methods are registered as MimeObjectFactory.StreamToObjectFactoryDelegate. The caller expects the
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Application.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Application.cs
index a813ca85d47..191b943c75e 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Application.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Application.cs
@@ -692,11 +692,8 @@ public static StreamResourceInfo GetRemoteStream(Uri uriRemote)
Uri resolvedUri = BindUriHelper.GetResolvedUri(BaseUriHelper.SiteOfOriginBaseUri, uriRemote);
- // Using PackUriHelper.ValidateAndGetPackUriComponents internal method
- // to get Package and Part Uri in one step
- Uri packageUri;
- Uri partUri;
- MS.Internal.IO.Packaging.PackUriHelper.ValidateAndGetPackUriComponents(resolvedUri, out packageUri, out partUri);
+ Uri packageUri = PackUriHelper.GetPackageUri(resolvedUri);
+ Uri partUri = PackUriHelper.GetPartUri(resolvedUri);
//
// SiteOfOriginContainer must have been added into the package cache, the code should just
@@ -2012,12 +2009,9 @@ private static PackagePart GetResourceOrContentPart(Uri uri)
Uri packAppUri = BaseUriHelper.PackAppBaseUri;
Uri resolvedUri = BindUriHelper.GetResolvedUri(packAppUri, uri);
- // Using PackUriHelper.ValidateAndGetPackUriComponents internal method
- // to get Package and Part Uri in one step
- Uri packageUri;
- Uri partUri;
- MS.Internal.IO.Packaging.PackUriHelper.ValidateAndGetPackUriComponents(resolvedUri, out packageUri, out partUri);
-
+ Uri packageUri = PackUriHelper.GetPackageUri(resolvedUri);
+ Uri partUri = PackUriHelper.GetPartUri(resolvedUri);
+
//
// ResourceContainer must have been added into the package cache, the code should just
// take use of that ResourceContainer instance, instead of creating a new instance here.
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/FixedDocument.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/FixedDocument.cs
index 24cb576f8a6..862802861b7 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/FixedDocument.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/FixedDocument.cs
@@ -995,7 +995,7 @@ static private Uri GetStructureUriFromRelationship(Uri contentUri, string relati
Uri absTargetUri = null;
if (contentUri != null && relationshipName != null)
{
- Uri partUri = MS.Internal.IO.Packaging.PackUriHelper.GetPartUri(contentUri);
+ Uri partUri = PackUriHelper.GetPartUri(contentUri);
if (partUri != null)
{
Uri packageUri = PackUriHelper.GetPackageUri(contentUri);
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/XamlToRtfWriter.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/XamlToRtfWriter.cs
index a9ba108fa97..c7c6447751a 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/XamlToRtfWriter.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/XamlToRtfWriter.cs
@@ -2023,8 +2023,14 @@ private void WriteImage(DocumentNode documentNode)
// Get image type to be added to rtf content
RtfImageFormat imageFormat = GetImageFormatFromImageSourceName(documentNode.FormatState.ImageSource);
- // Write the shape image like as "\pngblip" or "\jpegblip" rtf control
- WriteShapeImage(documentNode, imageStream, imageFormat);
+ // Write the shape image like as "\pngblip" or "\jpegblip" rtf control. We wrap the stream that comes
+ // from the package because we require the stream to be seekable.
+ Debug.Assert(!imageStream.CanSeek);
+ using (var seekableStream = new MemoryStream((int)imageStream.Length))
+ {
+ imageStream.CopyTo(seekableStream);
+ WriteShapeImage(documentNode, seekableStream, imageFormat);
+ }
#if WindowsMetaFile
// This block is disabled because of performance.
diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/XpsS0ValidatingLoader.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/XpsS0ValidatingLoader.cs
index 746f0121a22..d3c0af4ec0d 100644
--- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/XpsS0ValidatingLoader.cs
+++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/XpsS0ValidatingLoader.cs
@@ -73,12 +73,9 @@ private object Load(Stream stream, Uri parentUri, ParserContext pc, ContentType
XpsSchema schema = XpsSchema.GetSchema(mimeType);
Uri uri = pc.BaseUri;
- // Using PackUriHelper.ValidateAndGetPackUriComponents internal method
- // to get Package and Part Uri in one step
- Uri packageUri;
- Uri partUri;
- InternalPackUriHelper.ValidateAndGetPackUriComponents(uri, out packageUri, out partUri);
-
+ Uri packageUri = PackUriHelper.GetPackageUri(uri);
+ Uri partUri = PackUriHelper.GetPartUri(uri);
+
Package package = PreloadedPackages.GetPackage(packageUri);
Uri parentPackageUri = null;
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompressStream.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompressStream.cs
deleted file mode 100644
index 3732ddad140..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompressStream.cs
+++ /dev/null
@@ -1,825 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-//
-//
-// Description:
-// Emulates a fully functional stream that persists using the Deflate compression algorithm
-//
-// This class provides a fully functional Stream on a restricted functionality compression
-// stream (System.IO.Compression.DeflateStream).
-//
-// CompressStream operates in "transparent" mode (ReadThrough or WriteThrough) as long as possible for efficiency,
-// reverting to full emulation mode as required to satisfy Stream requests that would violate the capabilities
-// of the DeflateStream that actually does the reading or writing (decompress or compress). Emulation
-// mode is implemented by class CompressEmulationStream.
-//
-// Note that the reason we need these modes is that DeflateStream is entirely modal in nature once
-// constructed. If it is created in "compress" mode, it can only be used for compression. If it is
-// opened in "decompress" mode, it can only be used for decompression. This means that Reading is only
-// natively support in decompress mode, and writing is only natively supported in compress mode.
-//
-// Notes:
-// If baseStream is non-seekable and non-readable it is not possible to enter Emulation mode. In this case
-// we need to throw appropriate exception.
-//
-//
-//
-
-using System;
-using System.IO;
-using System.IO.Compression; // for DeflateStream
-using System.Diagnostics;
-
-using System.IO.Packaging;
-using MS.Internal.IO.Zip;
-
-using System.Windows;
-using MS.Internal.WindowsBase;
-
-namespace MS.Internal.IO.Packaging
-{
- //------------------------------------------------------
- //
- // Internal Members
- //
- //------------------------------------------------------
- ///
- /// Emulates a fully functional stream that persists using the Deflate compression algorithm
- ///
- /// Attempts to provide ReadThrough or WriteThrough functionality as possible. If not possible,
- /// a CompressEmulationStream is created and work is delegated to that class.
- internal class CompressStream : Stream
- {
- //------------------------------------------------------
- //
- // Public Methods
- //
- //------------------------------------------------------
- #region Stream Methods
- ///
- /// Return the bytes requested from the container
- ///
- /// destination buffer
- /// offset to write into that buffer
- /// how many bytes requested
- /// how many bytes were written into .
- ///
- /// The underlying stream, expected to be a DeflateStream or a CompressEmulationStream,
- /// is in charge of leaving the IO position unchanged in case of an exception.
- ///
- public override int Read(byte[] buffer, int offset, int count)
- {
- CheckDisposed();
-
- PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count);
-
- // no-op
- if (count == 0)
- return 0;
-
- checked // catch any integer overflows
- {
- switch (_mode)
- {
- case Mode.Start:
- {
- // skip to the correct logical position if necessary (DeflateStream starts at position zero)
- if (_position == 0)
- {
- // enter ReadPassThrough mode if it is efficient
- ChangeMode(Mode.ReadPassThrough);
- }
- else
- ChangeMode(Mode.Emulation);
-
- break;
- }
-
- case Mode.ReadPassThrough: // continue in ReadPassThrough mode
- case Mode.Emulation: // continue to read from existing emulation stream
- {
- break;
- }
-
- case Mode.WritePassThrough: // enter Emulation mode
- {
- // optimization - if they are trying to jump back to the start to read, simply jump to ReadPassThrough mode
- if (_position == 0)
- ChangeMode(Mode.ReadPassThrough);
- else
- ChangeMode(Mode.Emulation);
- break;
- }
- default: Debug.Assert(false, "Illegal state for CompressStream - logic error"); break;
- }
-
- // we might be in Start mode now if we are beyond the end of stream - just return zero
- if (_current == null)
- return 0;
-
- int bytesRead = _current.Read(buffer, offset, count);
-
- // optimization for ReadPassThrough mode - we actually know the length because we ran out of bytes
- if (_mode == Mode.ReadPassThrough && bytesRead == 0)
- {
- // possible first chance to set and verify length from header against real data length
- UpdateUncompressedDataLength(_position);
-
- // since we've exhausted the deflateStream, discard it to reduce working set
- ChangeMode(Mode.Start);
- }
-
- // Stream contract - don't update position until we are certain that no exceptions have occurred
- _position += bytesRead;
-
- return bytesRead;
- }
- }
-
- ///
- /// Write
- ///
- /// Note that zero length write to deflate stream actually results in a stream containing 2 bytes. This is
- /// required to maintain compatibility with the standard.
- public override void Write(byte[] buffer, int offset, int count)
- {
- CheckDisposed();
-
- PackagingUtilities.VerifyStreamWriteArgs(this, buffer, offset, count);
-
- // no-op
- if (count == 0)
- return;
-
- checked
- {
- switch (_mode)
- {
- case Mode.Start: // enter WritePassThrough mode if possible
- {
- // Special case: If stream has existing content, we need to go straight
- // to Emulation mode otherwise we'll potentially destroy existing data.
- // Don't bother entering WritePassThroughMode if position is non-zero because
- // we'll just enter emulation later.
- if (_position == 0 && IsDeflateStreamEmpty(_baseStream))
- ChangeMode(Mode.WritePassThrough);
- else
- ChangeMode(Mode.Emulation);
- break;
- }
- case Mode.WritePassThrough: // continue in Write mode
- case Mode.Emulation: // continue to read from existing emulation stream
- {
- break;
- }
- case Mode.ReadPassThrough: // enter Emulation mode
- {
- ChangeMode(Mode.Emulation); break;
- }
- default: Debug.Assert(false, "Illegal state for CompressStream - logic error"); break;
- }
-
- _current.Write(buffer, offset, count);
-
- _position += count;
- }
-
- // keep track of the current length in case someone asks for it
- if (_mode == Mode.WritePassThrough)
- CachedLength = _position;
-
- _dirtyForFlushing= true;
- _dirtyForClosing= true;
- }
-
- ///
- /// Seek
- ///
- /// offset
- /// origin
- /// zero
- public override long Seek(long offset, SeekOrigin origin)
- {
- CheckDisposed();
-
- if (!CanSeek)
- throw new NotSupportedException(SR.Get(SRID.SeekNotSupported));
-
- checked
- {
- // Calculate newPos
- // If origin is Begin or Current newPos can be calculated without knowing
- // the stream length. If origin is End, switch to Emulation immediately.
- long newPos = -1;
- switch (origin)
- {
- case SeekOrigin.Begin: newPos = offset; break;
- case SeekOrigin.Current: newPos = _position + offset; break;
- case SeekOrigin.End:
- ChangeMode(Mode.Emulation); // has no effect if already in Emulation mode
- newPos = Length + offset; // Length is now legal to call
- break;
- }
-
- // we have a reliable newPos now - throw if its illegal
- if (newPos < 0)
- throw new ArgumentException(SR.Get(SRID.SeekNegative));
-
- // is the new position any different than the current position?
- long delta = newPos - _position;
- if (delta == 0)
- return _position;
-
- // We optimize for very restricted case - short seek forward in read-only mode.
- // This prevents the expense of entering Emulation mode when a stream reader is
- // skipping a few bytes while parsing binary data structures (for example).
- if ((delta > 0) && (delta < _readPassThroughModeSeekThreshold)
- && (_mode == Mode.ReadPassThrough))
- {
- // We're able to fake the seek by reading in this one corner case.
- // We cannot be in ReadPassThroughMode if currently beyond end of physical
- // data so it is safe to assume that the value returned from
- // this call represents real data.
- long bytesNotRead = ReadPassThroughModeSeek(delta);
- if (bytesNotRead > 0)
- {
- // Stream was exhausted - seek was beyond end of physical
- // stream so we need to update our cachedLength and
- // move to Start mode.
- UpdateUncompressedDataLength(newPos - bytesNotRead);
- ChangeMode(Mode.Start);
- }
- }
- else
- {
- // Enter Emulation for efficiency
- ChangeMode(Mode.Emulation); // No-op if already in Emulation
- _current.Position = newPos; // Update to new value
- }
-
- // update logical position
- _position = newPos;
- }
-
- return _position;
- }
-
- ///
- /// SetLength
- ///
- public override void SetLength(long newLength)
- {
- CheckDisposed();
-
- if (!CanSeek)
- throw new NotSupportedException(SR.Get(SRID.SetLengthNotSupported));
-
- _lengthVerified = true; // no longer need to verify our length against our constructor value
- switch (_mode)
- {
- case Mode.Start:
- case Mode.WritePassThrough:
- case Mode.ReadPassThrough:
- {
- // optimize for "clear the whole stream" - no need to enter emulation
- if (newLength == 0)
- {
- ChangeMode(Mode.Start); // discard any existing deflate stream
- _baseStream.SetLength(0); // clear the underlying stream
- UpdateUncompressedDataLength(newLength);
- }
- else
- ChangeMode(Mode.Emulation);
-
- break;
- }
-
- case Mode.Emulation: break;
-
- default: Debug.Assert(false, "Illegal state for CompressStream - logic error"); break;
- }
-
- if (_mode == Mode.Emulation)
- _current.SetLength(newLength);
-
- // position seek pointer appropriately
- if (newLength < _position)
- Seek(newLength, SeekOrigin.Begin);
-
- // still need to mark ourselves dirty so that our caller can get the correct result
- // when they query the IsDirty property
- _dirtyForFlushing= true;
- _dirtyForClosing= true;
- }
-
- ///
- /// Flush
- ///
- /// Flushes to stream (if necessary)
- public override void Flush()
- {
- CheckDisposed();
-
- // Always pass through to subordinates because they may be caching things (ignore _dirty flag here).
-
- // Current must be non-null if changes have been made.
- if (_current != null)
- {
- _current.Flush();
- _dirtyForFlushing = false; // extra flushes after this will not produce more data
-
- // avoid clearing flag when we are empty because it would prevent generation
- // of the 2-byte sequence on dispose
- if ((_mode == Mode.Emulation) && (Length != 0))
- {
- _dirtyForClosing = false; // if it is ReadThrough or Start (it shouldn't be dirty in the first place)
- // if it is WriteThrough it is going to be dirty untill it is closed
- }
- }
- _baseStream.Flush();
- }
- #endregion Stream Methods
-
- #region Stream Properties
- ///
- /// Current logical position within the stream
- ///
- public override long Position
- {
- get
- {
- CheckDisposed();
- return _position;
- }
- set
- {
- CheckDisposed();
-
- // convert to a Seek so we don't have to replicate the Seek logic here
- Seek(checked(value - _position), SeekOrigin.Current);
- }
- }
-
- ///
- /// Length
- ///
- public override long Length
- {
- get
- {
- CheckDisposed();
-
-// if (!CanSeek)
-// throw new NotSupportedException(SR.Get(SRID.LengthNotSupported));
-
- switch (_mode)
- {
- case Mode.Start:
- case Mode.WritePassThrough:
- case Mode.ReadPassThrough:
- {
- // use cached length if possible
- if (CachedLength >= 0)
- return CachedLength;
- else
- {
- // Special optimization for new/empty streams - avoid entering Emulation as long as possible.
- if (_position == 0 && IsDeflateStreamEmpty(_baseStream))
- return 0;
-
- ChangeMode(Mode.Emulation);
- }
- break;
- }
-
- case Mode.Emulation: break;
-
- default: Debug.Assert(false, "Illegal state for CompressStream - logic error"); break;
- }
-
- // must be in Emulation mode to get here
- // possible first chance to verify length from header against real data length
- UpdateUncompressedDataLength(_current.Length);
- return _current.Length;
- }
- }
-
- ///
- /// Is stream readable?
- ///
- /// returns false when called on disposed stream
- public override bool CanRead
- {
- get
- {
- // cannot read from a close stream, but don't throw if asked
- return (_mode != Mode.Disposed) && _baseStream.CanRead;
- }
- }
-
- ///
- /// Is stream seekable - should be handled by our owner
- ///
- /// returns false when called on disposed stream
- public override bool CanSeek
- {
- get
- {
- // cannot seek on a close stream, but don't throw if asked
- return (_mode != Mode.Disposed) && _baseStream.CanSeek;
- }
- }
-
- ///
- /// Is stream writeable?
- ///
- /// returns false when called on disposed stream
- public override bool CanWrite
- {
- get
- {
- // cannot write to a close stream, but don't throw if asked
- return (_mode != Mode.Disposed) && _baseStream.CanWrite;
- }
- }
- #endregion
-
- #region Internal
- //------------------------------------------------------
- //
- // Internal Constructors
- //
- //------------------------------------------------------
- ///
- /// Constructor
- ///
- /// uncompressed length if known, or -1 if not known
- /// part stream
- internal CompressStream(Stream baseStream, long length) : this (baseStream, length, false)
- {
- }
-
- ///
- /// Constructor
- ///
- /// part stream
- /// new stream or not?
- /// uncompressed length if known, or -1 if not known
- internal CompressStream(Stream baseStream, long length, bool creating)
- {
- if (baseStream == null)
- throw new ArgumentNullException("baseStream");
-
- if (length < -1)
- throw new ArgumentOutOfRangeException("length");
-
- _baseStream = baseStream;
- _cachedLength = length;
-
- Debug.Assert(_baseStream.Position == 0,
- "Our logic assumes position zero and we don't seek because sometimes it's not supported");
-
- // we need to be dirty if this is a new stream because an empty deflate
- // stream actually causes a write (this happens only on close ); therefore
- // we are dirty for close (in case of creation) and not dirty for flush
- _dirtyForFlushing= false;
- _dirtyForClosing= creating;
- }
-
- //------------------------------------------------------
- //
- // Internal Properties
- //
- //------------------------------------------------------
- ///
- /// IsDirty
- ///
- ///
- internal bool IsDirty(bool closingFlag)
- {
- return closingFlag ? _dirtyForClosing : _dirtyForFlushing;
- }
-
- ///
- /// IsDisposed
- ///
- ///
- internal bool IsDisposed
- {
- get
- {
- return (_mode == Mode.Disposed);
- }
- }
-
- #endregion
-
- #region Protected
- //------------------------------------------------------
- //
- // Protected Methods
- //
- //------------------------------------------------------
- ///
- /// Dispose(bool)
- ///
- ///
- /// We implement this because we want a consistent experience (essentially Flush our data) if the user chooses to
- /// call Dispose() instead of Close().
- protected override void Dispose(bool disposing)
- {
- try
- {
- if (disposing)
- {
- if (_mode != Mode.Disposed)
- {
- Flush();
-
- if (_current != null)
- {
- _current.Close(); // call Dispose()
- _current = null;
- }
-
- // Special handling for "empty" deflated streams - they actually persist
- // a 2 byte sequence.
-
- // Three separate cases (assuming the stream is dirty):
- // 1) Stream is seekable - check Length and write the 2-byte sequence
- // if the stream is empty.
- // 2) Stream is non-seekable and negative CachedLength - this means we were created
- // (not opened) and there have been no writes so we need the 2-byte sequence.
- // 3) Stream is non-seekable and zero CachedLength - this means we are
- // really zero-bytes long which indicates we need the 2-byte sequence.
- if (_dirtyForClosing && ((_baseStream.CanSeek && _baseStream.Length == 0) ||
- (_cachedLength <= 0)))
- {
- _baseStream.Write(_emptyDeflateStreamConstant, 0, 2);
- _baseStream.Flush();
- }
-
- // _baseStream.Close(); // never close a stream we do not own
- _baseStream = null;
-
- ChangeMode(Mode.Disposed);
- _dirtyForClosing = false;
- _dirtyForFlushing = false;
- }
- }
- }
- finally
- {
- base.Dispose(disposing);
- }
- }
- #endregion
-
- // Changed the mode from Emulation to Start
- internal void Reset()
- {
- CheckDisposed();
-
- ChangeMode(Mode.Start);
- }
-
- #region Private
- //------------------------------------------------------
- //
- // Private Properties
- //
- //------------------------------------------------------
- //------------------------------------------------------
- //
- // Private Methods
- //
- //------------------------------------------------------
-
- ///
- /// Verify Uncompressed length from data against what we were given in the constructor
- ///
- ///
- /// verify length from header against real data length
- private void UpdateUncompressedDataLength(long dataLength)
- {
- Debug.Assert(dataLength >= 0);
-
- // only compare if we have a value
- if (_cachedLength >= 0)
- {
- if (!_lengthVerified)
- {
- if (_cachedLength != dataLength)
- throw new FileFormatException(SR.Get(SRID.CompressLengthMismatch));
-
- _lengthVerified = true;
- }
- }
-
- _cachedLength = dataLength; // always set
- }
-
- ///
- /// Helper method to reduce complexity in the public Seek method
- ///
- ///
- /// bytes remaining - will be non-zero if stream was exhausted
- /// Attempts to "seek" by reading an discarding bytes using the current
- /// Decompressing DeflateStream.
- /// _position is updated by our caller - this function does not change it
- private long ReadPassThroughModeSeek(long bytesToSeek)
- {
- checked
- {
- Debug.Assert(bytesToSeek > 0, "Logic Error - bytesToSeek should be positive");
-
- // allocate buffer just big enough for the seek, maximum of 4k
- byte[] buf = new byte[Math.Min(0x1000, bytesToSeek)];
-
- // read to simulate Seek
- while (bytesToSeek > 0)
- {
- // don't exceed the buffer size
- long n = Math.Min(bytesToSeek, buf.Length);
- n = _current.Read(buf, 0, (int)n);
-
- // seek beyond end of stream is legal
- if (n == 0)
- {
- break; // just exit
- }
-
- bytesToSeek -= n;
- }
-
- // return bytes not read
- return bytesToSeek;
- }
- }
-
- ///
- /// Call this before accepting any public API call (except some Stream calls that
- /// are allowed to respond even when Closed
- ///
- private void CheckDisposed()
- {
- if (IsDisposed)
- throw new ObjectDisposedException(null, SR.Get(SRID.StreamObjectDisposed));
- }
-
- ///
- /// ChangeMode
- ///
- ///
- /// Does not update Position of _current for change to ReadPassThroughMode.
- private void ChangeMode(Mode newMode)
- {
- // ignore redundant calls (allowing these actually simplifies the logic in SetLength)
- if (newMode == _mode)
- return;
-
- // every state change requires this logic
- if (_current != null)
- {
- _current.Close();
- _dirtyForClosing = false;
- _dirtyForFlushing = false;
- }
-
- // set the new mode - must be done before the call to Seek
- _mode = newMode;
-
- switch (newMode)
- {
- case Mode.Start:
- {
- _current = null;
- _baseStream.Position = 0;
- break;
- }
-
- case Mode.ReadPassThrough:
- case Mode.WritePassThrough:
- {
- Debug.Assert(_baseStream.Position == 0);
-
- // create the appropriate DeflateStream
- _current = new DeflateStream(_baseStream,
- newMode == Mode.WritePassThrough ? CompressionMode.Compress : CompressionMode.Decompress,
- true);
-
- break;
- }
- case Mode.Emulation:
- {
- // Create emulation stream. Use a MemoryStream for local caching.
- // Do not change this logic for RM cases because the data is "in the clear" and must
- // not be persisted in a vulnerable location.
-
- SparseMemoryStream memStream = new SparseMemoryStream(_lowWaterMark, _highWaterMark);
- _current = new CompressEmulationStream(_baseStream, memStream, _position, new DeflateEmulationTransform());
-
- // verify and set length
- UpdateUncompressedDataLength(_current.Length);
- break;
- }
- case Mode.Disposed: break;
- default:
- Debug.Assert(false, "Illegal state for CompressStream - logic error"); break;
- }
- }
-
- ///
- /// Call this to determine if a deflate stream is empty - pass the actual compressed stream
- ///
- ///
- /// true if empty
- private static bool IsDeflateStreamEmpty(Stream s)
- {
- bool empty = false;
-
- // Special case: If stream has existing content, we need to go straight
- // to Emulation mode otherwise we'll potentially destroy existing data.
- // This will not be possible if the base stream is write-only and non-seekable.
- // The minimal length of a persisted DeflateStream is 2 so if the length
- // is 2, we can safely overwrite. We explicitly call Deflate on a stream of length
- // 1 so that we can get a consistent exception because this will be an illegally
- // compressed stream.
- if (s.CanSeek && s.CanRead)
- {
- Debug.Assert(s.Position == 0);
-
- // read the two bytes and commpare to the known 2 bytes that represent
- // and empty deflate stream
- byte[] buf = new byte[2];
- int bytesRead = s.Read(buf, 0, 2);
- empty = ((bytesRead == 0) ||
- (buf[0] == _emptyDeflateStreamConstant[0] && buf[1] == _emptyDeflateStreamConstant[1]));
-
- s.Position = 0; // restore position
- }
- else
- empty = true; // if write-time-streaming we're going to destroy what's there anyway
-
- return empty;
- }
-
- private long CachedLength
- {
- get
- {
- // only maintained when NOT in Emulation mode
- Debug.Assert(_mode != Mode.Emulation, "Logic error: CachedLength not maintained in Emulation mode - illegal Get");
- return _cachedLength;
- }
- set
- {
- // only maintained when NOT in Emulation mode
- Debug.Assert(_mode != Mode.Emulation, "Logic error: CachedLength not maintained in Emulation mode - illegal Set");
- Debug.Assert(value >= 0, "Length cannot be negative - logic error?");
- _cachedLength = value;
- }
- }
-
- //------------------------------------------------------
- //
- // Private Variables
- //
- //------------------------------------------------------
-
- // Add explicit values to these enum variables because we do some arithmetic with them and don't want to
- // rely on the default behavior.
- private enum Mode
- {
- Start = 0, // we have no outstanding memory in use - state on construction
- ReadPassThrough = 1, // we are able to read from the current position
- WritePassThrough = 2, // we are able to write to the current position
- Emulation = 3, // we have moved all data to a memory stream and all operations are supported
- Disposed = 4 // we are disposed
- };
- private Mode _mode; // current stream mode
- private Int64 _position; // current logical position - only copy - shared with all helpers
- private Stream _baseStream; // stream we ultimately decompress from and to in the container
- private Stream _current; // current stream object
-
- private bool _dirtyForFlushing; // are we dirty, these 2 flags are going to differ in the case of the FLushed Write Through mode
- private bool _dirtyForClosing; // _dirtyForFlushing will be false (meaning that there is no data to be flushed) while
- // _dirtyForClosing will be true as there might be some data that need to be added for closing
- // Note: DirtyForFlushing can never be true when DirtyForClosing is false.
-
- private bool _lengthVerified; // true if we have successfully compared the length given in our constructor against that obtained from
- // actually decompressing the data
- private long _cachedLength; // cached value prevents us from entering Emulation to obtain length after ReadPassThrough reads all bytes
- // -1 means not set
- // this is what is persisted when a deflate stream is of length zero
- private static byte[] _emptyDeflateStreamConstant = new byte[] { 0x03, 0x00 };
-
- private const long _lowWaterMark = 0x19000; // we definately would like to keep everythuing under 100 KB in memory
- private const long _highWaterMark = 0xA00000; // we would like to keep everything over 10 MB on disk
- private const long _readPassThroughModeSeekThreshold = 0x40; // amount we can seek in a reasonable amount of time while decompressing
-
- #endregion
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/PackUriHelper.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/PackUriHelper.cs
index 1600c0d4892..a838840b5fd 100644
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/PackUriHelper.cs
+++ b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/PackUriHelper.cs
@@ -34,31 +34,7 @@ namespace MS.Internal.IO.Packaging
internal static class PackUriHelper
{
#region Public Methods
- ///
- /// This method parses the pack uri and returns the absolute
- /// path of the URI. This corresponds to the part within the
- /// package. This corresponds to the absolute path component in
- /// the Uri. If there is no part component present, this method
- /// returns a null
- ///
- /// Returns a relative Uri that represents the
- /// part within the package. If the pack Uri points to the entire
- /// package then we return a null
- /// Returns a relative URI with an absolute path that points to a part within a package
- /// If packUri parameter is null
- /// If packUri parameter is not an absolute Uri
- /// If packUri parameter does not have "pack://" scheme
- /// If partUri extracted from packUri does not conform to the valid partUri syntax
- public static Uri GetPartUri(Uri packUri)
- {
- Uri packageUri;
- Uri partUri;
- //Parameter Validation is done in the follwoing method
- ValidateAndGetPackUriComponents(packUri, out packageUri, out partUri);
-
- return partUri;
- }
#endregion Public Methods
@@ -85,31 +61,7 @@ internal static Uri PackageRootUri
internal static bool IsPackUri(Uri uri)
{
return uri != null &&
- string.Compare(uri.Scheme, UriSchemePack, StringComparison.OrdinalIgnoreCase) == 0;
- }
-
- internal static bool TryValidatePartUri(Uri partUri, out ValidatedPartUri validatedPartUri)
- {
- if (partUri is ValidatedPartUri)
- {
- validatedPartUri = (ValidatedPartUri)partUri;
- return true;
- }
- else
- {
- string partUriString;
- Exception exception = GetExceptionIfPartUriInvalid(partUri, out partUriString);
- if (exception != null)
- {
- validatedPartUri = null;
- return false;
- }
- else
- {
- validatedPartUri = new ValidatedPartUri(partUriString);
- return true;
- }
- }
+ string.Compare(uri.Scheme, System.IO.Packaging.PackUriHelper.UriSchemePack, StringComparison.OrdinalIgnoreCase) == 0;
}
///
@@ -153,18 +105,7 @@ internal static string GetStringForPartUri(Uri partUri)
if (!(partUri is ValidatedPartUri))
partUri = ValidatePartUri(partUri);
- return ((ValidatedPartUri)partUri).PartUriString;
- }
-
- //This method validates the packUri and returns its two components if they are valid-
- //1. Package Uri
- //2. Part Uri
- internal static void ValidateAndGetPackUriComponents(Uri packUri, out Uri packageUri, out Uri partUri)
- {
- //Validate if its not null and is an absolute Uri, has pack:// Scheme.
- packUri = ValidatePackUri(packUri);
- packageUri = GetPackageUriComponent(packUri);
- partUri = GetPartUriComponent(packUri);
+ return ((ValidatedPartUri)partUri).PartUriString;
}
#endregion Internal Methods
@@ -186,7 +127,7 @@ internal static void ValidateAndGetPackUriComponents(Uri packUri, out Uri packag
static PackUriHelper()
{
// indicate that we want "basic" parsing
- if (!UriParser.IsKnownScheme(UriSchemePack))
+ if (!UriParser.IsKnownScheme(System.IO.Packaging.PackUriHelper.UriSchemePack))
{
try
{
@@ -194,7 +135,7 @@ static PackUriHelper()
permobj.Assert(); //BlessedAssert:
// Indicate that we want a default hierarchical parser with a registry based authority
- UriParser.Register(new GenericUriParser(GenericUriParserOptions.GenericAuthority), UriSchemePack, -1);
+ UriParser.Register(new GenericUriParser(GenericUriParserOptions.GenericAuthority), System.IO.Packaging.PackUriHelper.UriSchemePack, -1);
}
finally
{
@@ -212,60 +153,6 @@ static PackUriHelper()
//------------------------------------------------------
#region Private Methods
-
- ///
- /// This method is used to validate the package uri
- ///
- ///
- ///
- private static Uri ValidatePackageUri(Uri packageUri)
- {
- if (packageUri == null)
- throw new ArgumentNullException("packageUri");
-
- if (!packageUri.IsAbsoluteUri)
- throw new ArgumentException(SR.Get(SRID.UriShouldBeAbsolute));
-
- return packageUri;
- }
-
- //validates is a given uri has pack:// scheme
- private static Uri ValidatePackUri(Uri packUri)
- {
- if (packUri == null)
- throw new ArgumentNullException("packUri");
-
- if (!packUri.IsAbsoluteUri)
- throw new ArgumentException(SR.Get(SRID.UriShouldBeAbsolute));
-
- if (packUri.Scheme != PackUriHelper.UriSchemePack)
- throw new ArgumentException(SR.Get(SRID.UriShouldBePackScheme));
-
- return packUri;
-}
-
- ///
- /// Escapes - %', '@', ',', '?' in the package URI
- /// This method modifies the string in a culture safe and case safe manner.
- ///
- ///
- ///
- private static string EscapeSpecialCharacters(string path)
- {
- string characterString;
-
- // Escaping for the following - '%'; '@'; ',' and '?'
- // !!Important!! - The order is important - The '%' sign should be escaped first.
- // This is currently enforced by the order of characters in the _specialCharacters array
- foreach (char c in _specialCharacters)
- {
- characterString = c.ToString();
- if (path.Contains(characterString))
- path = path.Replace(characterString, Uri.HexEscape(c));
- }
-
- return path;
- }
private static Exception GetExceptionIfPartUriInvalid(Uri partUri, out string partUriString)
{
@@ -327,13 +214,6 @@ private static Exception GetExceptionIfPartUriInvalid(Uri partUri, out string pa
return null;
}
- private static void ThrowIfAbsoluteUri(Uri uri)
- {
- Exception exception = GetExceptionIfAbsoluteUri(uri);
- if (exception != null)
- throw exception;
- }
-
private static ArgumentException GetExceptionIfAbsoluteUri(Uri uri)
{
if (uri.IsAbsoluteUri)
@@ -342,13 +222,6 @@ private static ArgumentException GetExceptionIfAbsoluteUri(Uri uri)
return null;
}
- private static void ThrowIfFragmentPresent(string partName)
- {
- Exception exception = GetExceptionIfFragmentPresent(partName);
- if (exception != null)
- throw exception;
- }
-
private static ArgumentException GetExceptionIfFragmentPresent(string partName)
{
if (partName.Contains("#"))
@@ -357,13 +230,6 @@ private static ArgumentException GetExceptionIfFragmentPresent(string partName)
return null;
}
- private static void ThrowIfPartNameEndsWithSlash(string partName)
- {
- Exception exception = GetExceptionIfPartNameEndsWithSlash(partName);
- if (exception != null)
- throw exception;
- }
-
private static ArgumentException GetExceptionIfPartNameEndsWithSlash(string partName)
{
if (partName.Length > 0)
@@ -374,13 +240,6 @@ private static ArgumentException GetExceptionIfPartNameEndsWithSlash(string part
return null;
}
- private static void ThrowIfPartNameStartsWithTwoSlashes(string partName)
- {
- Exception exception = GetExceptionIfPartNameStartsWithTwoSlashes(partName);
- if (exception != null)
- throw exception;
- }
-
// A relative reference that begins with two slash characters is termed
// a network-path reference; such references are rarely used.
// However, when they are resolved they represent the authority part of the URI
@@ -397,19 +256,6 @@ private static ArgumentException GetExceptionIfPartNameStartsWithTwoSlashes(stri
return null;
}
- //Calling System.Uri.Compare method
- //This method minimizes the false positives that we might get as a result
- //of comparing two URIs.
- //Also, we exclude the Fragment component while comparing.
- private static int CompareUsingSystemUri(Uri firstUri, Uri secondUri)
- {
- return Uri.Compare(
- firstUri,
- secondUri,
- UriComponents.AbsoluteUri & ~UriComponents.Fragment,
- UriFormat.UriEscaped,
- StringComparison.Ordinal);
- }
//Returns the part name in its escaped string form from an Absolute [must be pack://] or a Relative URI
private static string GetStringForPartUriFromAnyUri(Uri partUri)
@@ -459,39 +305,6 @@ private static bool IsPartNameEmpty(string partName)
else
return false;
}
-
- //This method validates and returns the PackageUri component
- private static Uri GetPackageUriComponent(Uri packUri)
- {
- Debug.Assert(packUri != null, "packUri parameter cannot be null");
-
- //Step 1 - Get the authority part of the URI. This section represents that package URI
- String hostAndPort = packUri.GetComponents(UriComponents.HostAndPort, UriFormat.UriEscaped);
-
- //Step 2 - Replace the ',' with '/' to reconstruct the package URI
- hostAndPort = hostAndPort.Replace(',', '/');
-
- //Step 3 - Unescape the special characters that we had escaped to construct the packUri
- Uri packageUri = new Uri(Uri.UnescapeDataString(hostAndPort));
-
- if (packageUri.Fragment != String.Empty)
- throw new ArgumentException(SR.Get(SRID.InnerPackageUriHasFragment));
-
- return packageUri;
- }
-
- //This method validates and returns the PartUri component.
- private static PackUriHelper.ValidatedPartUri GetPartUriComponent(Uri packUri)
- {
- Debug.Assert(packUri != null, "packUri parameter cannot be null");
-
- string partName = GetStringForPartUriFromAnyUri(packUri);
-
- if (partName == String.Empty)
- return null;
- else
- return ValidatePartUri(new Uri(partName, UriKind.Relative));
- }
#endregion Private Methods
@@ -509,19 +322,9 @@ private static PackUriHelper.ValidatedPartUri GetPartUriComponent(Uri packUri)
//we use this dummy Uri to represent the root of the container.
private static readonly Uri _packageRootUri = new Uri("/", UriKind.Relative);
- // We need to perform Escaping for the following - '%'; '@'; ',' and '?'
- // !!Important!! - The order is important - The '%' sign should be escaped first.
- // If any more characters need to be added to the array below they should be added at the end.
- private static readonly char[] _specialCharacters = { '%', '@', ',', '?' };
-
//Rels segment and extension
private static readonly string _relationshipPartExtensionName = ".rels";
- ///
- /// pack scheme name
- ///
- public static readonly string UriSchemePack = "pack";
-
#endregion Private Members
#region Private Class
@@ -602,24 +405,6 @@ internal string PartUriString
}
}
- internal string PartUriExtension
- {
- get
- {
- if (_partUriExtension == null)
- {
- _partUriExtension = Path.GetExtension(_partUriString);
-
- //If extension is absent just return the empty string
- //else remove the leading "." from the returned extension
- //string
- if (_partUriExtension.Length > 0)
- _partUriExtension = _partUriExtension.Substring(1);
- }
- return _partUriExtension;
- }
- }
-
//Returns the normalized string for the part uri.
internal string NormalizedPartUriString
{
@@ -801,7 +586,6 @@ private int Compare(ValidatedPartUri otherPartUri)
private ValidatedPartUri _normalizedPartUri;
private string _partUriString;
private string _normalizedPartUriString;
- private string _partUriExtension;
private bool _isNormalized;
private bool _isRelationshipPartUri;
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/PackagingExtensions.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/PackagingExtensions.cs
index c57cf53116f..7dae5028b03 100644
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/PackagingExtensions.cs
+++ b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/PackagingExtensions.cs
@@ -27,19 +27,4 @@ internal class PackageRelationship
public static Uri ContainerRelationshipPartName => System.IO.Packaging.PackUriHelper.CreatePartUri(new Uri("/_rels/.rels", UriKind.Relative));
}
- internal static class ZipPackage
- {
- private const string ForwardSlashString = "/"; //Required for creating a part name from a zip item name
-
- public static string GetZipItemNameFromOpcName(string opcName)
- {
- System.Diagnostics.Debug.Assert(opcName != null && opcName.Length > 0);
- return opcName.Substring(1);
- }
-
- public static string GetOpcNameFromZipItemName(string zipItemName)
- {
- return String.Concat(ForwardSlashString, zipItemName);
- }
- }
}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/PieceNameHelper.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/PieceNameHelper.cs
deleted file mode 100644
index 14f7173b39d..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/PieceNameHelper.cs
+++ /dev/null
@@ -1,472 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-//
-//
-// Description: The static class PieceNameHelper contains utilities to parse
-// and create piece names in an adaptor-independent way.
-// This file also contains PieceNameInfo, a structured representation
-// of a piece name, and its subclass PieceInfo, which provides
-// piece name and zip file info for a piece.
-//
-
-using System;
-using System.IO;
-using System.IO.Packaging; // For ZipPackagePart, etc.
-using System.Windows; // for ExceptionStringTable
-using System.Globalization; // For CultureInfo
-using System.Collections.Generic; // IEqualityComparer
-
-using MS.Internal; // For Invariant
-using MS.Internal.IO.Zip; // For ZipFileInfo
-using System.Diagnostics; // For Debug.Assert
-
-using ZipPackage = MS.Internal.IO.Packaging.Extensions.ZipPackage;
-
-namespace MS.Internal.IO.Packaging
-{
- #region class PieceInfo
-
- ///
- /// A piece descriptor, made up of a ZipFileInfo and a PieceNameInfo.
- ///
- ///
- /// PieceNameHelper implements IComparable in such a way as to enforce
- /// case-insensitive lexicographical order on <name, number, isLast> triples.
- ///
- internal class PieceInfo
- {
- //------------------------------------------------------
- //
- // Constructors
- //
- //------------------------------------------------------
-
- #region Constructors
-
- internal PieceInfo(ZipFileInfo zipFileInfo, PackUriHelper.ValidatedPartUri partUri, string prefixName, int pieceNumber, bool isLastPiece)
- {
- Debug.Assert(zipFileInfo != null);
- Debug.Assert(prefixName != null && prefixName != String.Empty);
- Debug.Assert(pieceNumber >= 0);
-
- _zipFileInfo = zipFileInfo;
-
- // partUri can be null to indicate that the prefixname is not a valid part name
- _partUri = partUri;
- _prefixName = prefixName;
- _pieceNumber = pieceNumber;
- _isLastPiece = isLastPiece;
-
- // Currently as per the book, the prefix names/ logical names should be
- // compared in a case-insensitive manner.
- _normalizedPieceNamePrefix = _prefixName.ToUpperInvariant();
- }
-
- #endregion Constructors
-
- //------------------------------------------------------
- //
- // public methods
- //
- //------------------------------------------------------
- // None
- //------------------------------------------------------
- //
- // Internal properties
- //
- //------------------------------------------------------
-
- #region Internal properties
-
- internal string NormalizedPrefixName
- {
- get
- {
- return _normalizedPieceNamePrefix;
- }
- }
-
- internal string PrefixName
- {
- get
- {
- return _prefixName;
- }
- }
-
- internal int PieceNumber
- {
- get
- {
- return _pieceNumber;
- }
- }
-
- internal bool IsLastPiece
- {
- get
- {
- return _isLastPiece;
- }
- }
-
- internal System.Uri PartUri
- {
- get
- {
- return _partUri;
- }
- }
-
- internal ZipFileInfo ZipFileInfo
- {
- get
- {
- return _zipFileInfo;
- }
- }
-
- #endregion Internal properties
-
- //------------------------------------------------------
- //
- // Private members
- //
- //------------------------------------------------------
-
- #region Private members
-
- private PackUriHelper.ValidatedPartUri _partUri;
- private string _prefixName;
- private int _pieceNumber;
- private bool _isLastPiece;
- private ZipFileInfo _zipFileInfo;
- private string _normalizedPieceNamePrefix;
-
- #endregion Private members
- }
-
- #endregion class PieceInfo
-
- #region class PieceNameHelper
-
- ///
- /// The static class PieceNameHelper contains utilities to parse and create piece names
- /// in an adaptor-independent way.
- ///
- internal static class PieceNameHelper
- {
- #region Internal Properties
-
- internal static PieceNameComparer PieceNameComparer
- {
- get
- {
- return _pieceNameComparer;
- }
- }
-
- #endregion Internal Properties
-
- #region Internal Methods
-
- ///
- /// Build a piece name from its constituents: part name, piece number
- /// and terminal status.
- /// The linearized result obeys the piece name syntax:
- /// piece_name = prefix_name "/" "[" 1*digit "]" [".last"] ".piece"
- ///
- /// A part name or the zip item name corresponding to a part name.
- /// The 0-based order number of the piece.
- /// Whether the piece is last in the part.
- /// A Metro piece name.
- /// If partName is a piece uri.
- /// If pieceNumber is negative.
- internal static string CreatePieceName(string partName, int pieceNumber, bool isLastPiece)
- {
- Invariant.Assert(pieceNumber >= 0, "Negative piece number.");
-
- return string.Format(CultureInfo.InvariantCulture, "{0}/[{1:D}]{2}.piece",
- partName,
- pieceNumber,
- isLastPiece ? ".last" : "");
- }
-
- ///
- /// Return true and create a PieceInfo if the name in the input ZipFileInfo parses
- /// as a piece name.
- ///
- ///
- /// No Uri validation is carried out at this level. All that is checked is valid piece
- /// syntax. So the _prefixName returned as part of the PieceInfo will not necessarily
- /// a part name. For example, it could be the name of the content type stream.
- ///
- internal static bool TryCreatePieceInfo(ZipFileInfo zipFileInfo, out PieceInfo pieceInfo)
- {
- Invariant.Assert(zipFileInfo != null);
-
- pieceInfo = null;
-
- // Try to parse as a piece name.
- PieceNameInfo pieceNameConstituents;
- bool result = PieceNameHelper.TryParseAsPieceName(zipFileInfo.Name,
- out pieceNameConstituents);
-
- // Return the result and the output parameter.
- if(result)
- pieceInfo = new PieceInfo(zipFileInfo,
- pieceNameConstituents.PartUri,
- pieceNameConstituents.PrefixName,
- pieceNameConstituents.PieceNumber,
- pieceNameConstituents.IsLastPiece);
-
- return result;
- }
-
- #endregion Internal Methods
-
- #region Private Methods
-
- //------------------------------------------------------
- //
- // Private Methods
- //
- //------------------------------------------------------
-
- #region Scan Steps
-
- // The functions in this region conform to the delegate type ScanStepDelegate
- // and implement the following automaton for scanning a piece name from right to left:
-
- // state transition new state
- // ----- ---------- ---------
- // FindPieceExtension ".piece" FindIsLast
- // FindIsLast "].last" FindPieceNumber
- // FindIsLast "]" FindPieceNumber
- // FindPieceNumber "/[" 1*digit FindPartName (terminal state)
-
- // On entering the step, position is at the beginning of the last portion that was recognized.
- // So left-to-right scanning starts at position - 1 in each step.
- private delegate bool ScanStepDelegate(
- string path, ref int position, ref ScanStepDelegate nextStep, ref PieceNameInfo parseResults);
-
- // Look for ".piece".
- private static bool FindPieceExtension(string path, ref int position, ref ScanStepDelegate nextStep,
- ref PieceNameInfo parseResults)
- {
- if (!FindString(path, ref position, ".piece"))
- return false;
-
- nextStep = FindIsLast;
- return true;
- }
-
- // Look for "]" or "].last".
- private static bool FindIsLast(string path, ref int position, ref ScanStepDelegate nextStep,
- ref PieceNameInfo parseResults)
- {
- // Case of no ".last" member:
- if (path[position - 1] == ']')
- {
- parseResults.IsLastPiece = false;
- --position;
- nextStep = FindPieceNumber;
- return true;
- }
-
- // There has to be "].last".
- if (!FindString(path, ref position, "].last"))
- return false;
-
- parseResults.IsLastPiece = true;
- nextStep = FindPieceNumber;
- return true;
- }
-
- // Look for "/[" followed by decimal digits.
- private static bool FindPieceNumber(string path, ref int position, ref ScanStepDelegate nextStep,
- ref PieceNameInfo parseResults)
- {
- if (!char.IsDigit(path[position - 1]))
- return false;
-
- int pieceNumber = 0;
- int multiplier = 1; // rightmost digit is for units
- --position;
- do
- {
- pieceNumber += multiplier * (int)char.GetNumericValue(path[position]);
- multiplier *= 10;
- } while (char.IsDigit(path[--position]));
-
- // Point to the last digit found.
- ++position;
-
- //If we have a leading 0, then its not correct piecename syntax
- if (multiplier > 10 && (int)char.GetNumericValue(path[position]) == 0)
- return false;
-
- if (!FindString(path, ref position, "/["))
- return false;
-
- parseResults.PieceNumber = pieceNumber;
- nextStep = FindPartName;
- return true;
- }
-
- // Retrieve part name. The position points to the slash past the part name.
- // So simply return the prefix up to that slash.
- private static bool FindPartName(string path, ref int position, ref ScanStepDelegate nextStep,
- ref PieceNameInfo parseResults)
- {
- parseResults.PrefixName = path.Substring(0, position);
-
- // Subtract the length of the part name from position.
- position = 0;
-
- if (parseResults.PrefixName.Length == 0)
- return false;
-
- Uri partUri = new Uri(ZipPackage.GetOpcNameFromZipItemName(parseResults.PrefixName), UriKind.Relative);
- PackUriHelper.TryValidatePartUri(partUri, out parseResults.PartUri);
- return true;
- }
-
- #endregion Scan Steps
-
- ///
- /// Attempts to parse a name as a piece name. Returns true and places the
- /// output in pieceNameConstituents. Otherwise, returns false and returns
- /// the default constituent values pieceName, 0, and false.
- ///
- /// The input string.
- /// An object containing the prefix name (i.e. generally the part name), the 0-based order number of the piece, and whether the piece is last in the part.
- /// True for parse success.
- ///
- /// Syntax of a piece name:
- /// piece_name = part_name "/" "[" 1*digit "]" [".last"] ".piece"
- ///
- private static bool TryParseAsPieceName(string path, out PieceNameInfo parseResults)
- {
- parseResults = new PieceNameInfo(); // initialize to CLR default values
-
- // Start from the end and look for ".piece".
- int position = path.Length;
- ScanStepDelegate nextStep = new ScanStepDelegate(FindPieceExtension);
-
- // Scan backward until the whole path has been scanned.
- while (position > 0)
- {
- if (!nextStep.Invoke(path, ref position, ref nextStep, ref parseResults))
- {
- // Scan step failed. Return false.
- parseResults.IsLastPiece = false;
- parseResults.PieceNumber = 0;
- parseResults.PrefixName = path;
- parseResults.PartUri = null;
- return false;
- }
- }
-
- return true;
- }
-
- ///
- /// Look for 'query' backward in 'input' starting at 'position'.
- ///
- private static bool FindString(string input, ref int position, string query)
- {
- int queryPosition = query.Length;
-
- //The input string should have length that is greater than or equal to the
- //length of the query string.
- if (position < queryPosition)
- return false;
-
- while (--queryPosition >= 0)
- {
- --position;
- if (Char.ToUpperInvariant(input[position]) != Char.ToUpperInvariant(query[queryPosition]))
- return false;
- }
- return true;
- }
-
- #endregion Private Methods
-
- #region Private Member Variables
-
- //------------------------------------------------------
- //
- // Private Variables
- //
- //------------------------------------------------------
-
- private static PieceNameComparer _pieceNameComparer = new PieceNameComparer();
-
- #endregion Private Member Variables
-
- #region Private Struct : PieceNameInfo
-
- ///
- /// The result of parsing a piece name as returned by the parsing methods of PieceNameHelper.
- ///
- ///
- /// /// The first member, _prefixName, will be a part name if the input to parse begins with
- /// a part name, and a zip item name if it starts with a zip item name.
- ///
- ///
- /// In other words, all that precedes the suffixes is returned unanalyzed as an "prefix name"
- /// by the parse functions of the PieceNameHelper.
- ///
- ///
- private struct PieceNameInfo
- {
- internal PackUriHelper.ValidatedPartUri PartUri;
- internal string PrefixName;
- internal int PieceNumber;
- internal bool IsLastPiece;
- }
-
- #endregion Private Struct : PieceNameInfo
- }
-
- #endregion class PieceNameHelper
-
- #region class PieceNameComparer
-
- internal sealed class PieceNameComparer : IComparer
- {
- //For comparing the piece names we consider the prefix name and piece numbers
- //Pieces that are terminal and non terminal with the same number and same prefix
- //number will be treated as equivalent.
- //For example - /partA/[number].piece and /partA[number].last.piece will be treated
- //to be equivalent, as in a well-formed package either one of them can be present,
- //not both.
- int IComparer.Compare(PieceInfo pieceInfoA, PieceInfo pieceInfoB)
- {
- //Even though most comparers allow for comparisons with null, we assert here, as
- //this is an internal class and we are sure that pieceInfoA and pieceInfoB passed
- //in here should be non-null, else it would be a logical error.
- Invariant.Assert(pieceInfoA != null);
- Invariant.Assert(pieceInfoB != null);
-
- int result = string.Compare(
- pieceInfoA.NormalizedPrefixName,
- pieceInfoB.NormalizedPrefixName,
- StringComparison.Ordinal);
-
- if (result != 0)
- return result;
-
- result = pieceInfoA.PieceNumber - pieceInfoB.PieceNumber;
-
- return result;
- }
- }
-
- #endregion class PieceNameComparer
-}
-
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/streamingZipPartStream.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/streamingZipPartStream.cs
deleted file mode 100644
index 05c755436b7..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/streamingZipPartStream.cs
+++ /dev/null
@@ -1,361 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-//
-//
-// Description: The class StreamingZipPartStream is used to create a sequence of
-// piece streams in order to implement streaming production of packages.
-//
-
-using System;
-using System.IO;
-using System.IO.Packaging; // For ZipPackagePart, etc.
-using MS.Internal.IO.Zip; // For ZipFileInfo.
-using System.Windows; // for ExceptionStringTable
-
-using MS.Internal; // for Invariant
-using MS.Internal.WindowsBase;
-
-using ZipPackage = MS.Internal.IO.Packaging.Extensions.ZipPackage;
-
-namespace MS.Internal.IO.Packaging
-{
- ///
- /// The class StreamingZipPartStream is used to create a sequence of
- /// piece streams in order to implement streaming production of packages.
- ///
- ///
- /// This class is defined for the benefit of ZipPackage, ZipPackagePart and
- /// InternalRelationshipCollection.
- /// Although it is quite specialized, it would hardly make sense to nest its definition in any
- /// of these clases.
- ///
- internal class StreamingZipPartStream : Stream
- {
- #region Constructors
-
- //------------------------------------------------------
- //
- // Constructors
- //
- //------------------------------------------------------
-
- ///
- /// Build a System.IO.Stream to create a multi-piece (i.e. interleaved) part.
- /// Does not require a part, but a proper part name (not a piece name), and a ZipArchive.
- ///
- internal StreamingZipPartStream(
- string partName,
- ZipArchive zipArchive,
- CompressionMethodEnum compressionMethod,
- DeflateOptionEnum deflateOption,
- FileMode mode,
- FileAccess access)
- {
- // Right now, only production is supported in streaming mode.
- if (!( (mode == FileMode.Create || mode == FileMode.CreateNew)
- && access == FileAccess.Write) )
- {
- throw new NotSupportedException(SR.Get(SRID.OnlyStreamingProductionIsSupported));
- }
-
- _partName = partName;
- _archive = zipArchive;
- _compressionMethod = compressionMethod;
- _deflateOption = deflateOption;
- _mode = mode;
- _access = access;
- }
-
- #endregion Constructors
-
- //------------------------------------------------------
- //
- // Public Methods
- //
- //------------------------------------------------------
-
- ///
- /// Return the bytes requested.
- ///
- /// Destination buffer.
- ///
- /// The zero-based byte offset in buffer at which to begin storing the data read
- /// from the current stream.
- ///
- /// How many bytes requested.
- /// How many bytes were written into buffer.
- public override int Read(byte[] buffer, int offset, int count)
- {
- throw new NotSupportedException(SR.Get(SRID.OnlyWriteOperationsAreSupportedInStreamingCreation));
- }
-
- ///
- /// Seek
- ///
- /// Offset in byte.
- /// Offset origin (start, current, or end).
- public override long Seek(long offset, SeekOrigin origin)
- {
- throw new NotSupportedException(SR.Get(SRID.OnlyWriteOperationsAreSupportedInStreamingCreation));
- }
-
- ///
- /// SetLength
- ///
- public override void SetLength(long newLength)
- {
- throw new InvalidOperationException(SR.Get(SRID.OperationViolatesWriteOnceSemantics, "SetLength"));
- }
-
- ///
- /// Write. Delegate to the current piece stream.
- /// Lazily create the Zip item since we do not know what name to create it
- /// under until a write or a close occurs.
- ///
- public override void Write(byte[] buffer, int offset, int count)
- {
- CheckClosed();
-
- // We now know we're creating a non-empty piece, so it's OK to give
- // it a non-terminal name.
- EnsurePieceStream(false /* not last piece */);
- _pieceStream.Write(buffer, offset, count);
- }
-
- ///
- /// Close the current piece stream and increment the piece number
- /// to allow on-demand creation of the next piece stream in Write
- /// or Close.
- ///
- /// Pass through the Flush calls because there is no need to
- /// generate a new Piece if we are writing to a single, enormouse stream.
- public override void Flush()
- {
- CheckClosed();
-
- // _pieceStream will be null if there's been no write since the last flush.
- if (_pieceStream != null)
- {
- // If CanWrite is false, we know that our underlying stream was closed by ZipIO layer
- // as a part of its logic. Therefore, we need a new Piece.
- if (_pieceStream.CanWrite)
- _pieceStream.Flush();
- }
- }
-
- //------------------------------------------------------
- //
- // Public Properties
- //
- //------------------------------------------------------
-
- #region Public Properties
-
- ///
- /// Is stream readable?
- ///
- ///
- /// Here, the assumption, as in all capability tests, is that the status of
- /// the current piece reflects the status of all pieces for the part.
- /// This is justified by the fact that (i) all piece streams are opened with the same
- /// parameters against the same archive and (ii) the current piece stream cannot get
- /// closed unless the whole part stream is closed.
- ///
- public override bool CanRead
- {
- get
- {
- return false;
- }
- }
-
- ///
- /// Is stream seekable?
- ///
- ///
- /// Here, the assumption, as in all capability tests, is that the status of
- /// the current piece reflects the status of all pieces for the part.
- /// This is justified by the fact that (i) all piece streams are opened with the same
- /// parameters against the same archive and (ii) the current piece stream cannot get
- /// closed unless the whole part stream is closed.
- ///
- public override bool CanSeek
- {
- get
- {
- return false;
- }
- }
-
- ///
- /// Is stream writable?
- ///
- ///
- /// Here, the assumption, as in all capability tests, is that the status of
- /// the current piece reflects the status of all pieces for the part.
- /// This is justified by the fact that (i) all piece streams are opened with the same
- /// parameters against the same archive and (ii) the current piece stream cannot get
- /// closed unless the whole part stream is closed.
- ///
- public override bool CanWrite
- {
- get
- {
- return !_closed;
- }
- }
-
- ///
- /// Logical byte position in this stream.
- ///
- public override long Position
- {
- get
- {
- return -1;
- }
- set
- {
- throw new InvalidOperationException(SR.Get(SRID.OperationViolatesWriteOnceSemantics, "set_Position"));
- }
- }
-
- ///
- /// Length.
- ///
- public override long Length
- {
- get
- {
- return -1;
- }
- }
-
- #endregion Public Properties
-
- //------------------------------------------------------
- //
- // Protected Methods
- //
- //------------------------------------------------------
-
- #region Protected Methods
-
- ///
- /// Dispose(bool)
- ///
- ///
- ///
- /// An instance of streams' peculiar dispose pattern, whereby
- /// the inherited abstract Stream class implements Close by calling
- /// this virtual protected function.
- /// In turn, each implementation is responsible for calling back
- /// its base's implementation.
- ///
- protected override void Dispose(bool disposing)
- {
- try
- {
- if (disposing)
- {
- if (!_closed)
- {
- // Flush pending changes into a piece, if any.
- Flush();
-
- // Create an empty last piece.
- EnsurePieceStream(true /* last piece */);
- _pieceStream.Close();
- }
- }
- }
- finally
- {
- _closed = true;
- base.Dispose(disposing);
- }
- }
-
- #endregion Protected Methods
-
- //------------------------------------------------------
- //
- // Private Methods
- //
- //------------------------------------------------------
-
- private void EnsurePieceStream(bool isLastPiece)
- {
- if (_pieceStream != null)
- {
- // Normally, the pieces are actually closed automatically for us by the
- // underlying ZipIO logic, but in the case of the last piece (when we
- // are called by our own Dispose(bool) method) we must close it explicitly.
- if (isLastPiece)
- _pieceStream.Close();
-
- // We detect that the stream has been closed by inspecting the CanWrite property
- // since this is guaranteed not to throw even when the stream is disposed.
- if (!_pieceStream.CanWrite)
- {
- // increment our piece number so we can generate the correct
- // one below
- checked { ++_currentPieceNumber; }
-
- // release it to trigger the new piece creation below
- _pieceStream = null;
- }
- }
-
- if (_pieceStream == null)
- {
- string pieceName = PieceNameHelper.CreatePieceName(
- _partName,
- _currentPieceNumber,
- isLastPiece);
- string pieceZipName = ZipPackage.GetZipItemNameFromOpcName(pieceName);
-
- ZipFileInfo zipFileInfo = _archive.AddFile(pieceZipName, _compressionMethod, _deflateOption);
- // We've just created the file, so the mode can only be Create, not CreateNew.
- // (At least, this is part of ZipFileInfo's belief system.)
- _pieceStream = zipFileInfo.GetStream(FileMode.Create, _access);
- }
- }
-
- private void CheckClosed()
- {
- if (_closed)
- throw new ObjectDisposedException(null, SR.Get(SRID.StreamObjectDisposed));
- }
-
- //------------------------------------------------------
- //
- // Private Properties
- //
- //------------------------------------------------------
- // None
-
- #region Private Fields
-
- //------------------------------------------------------
- //
- // Private Fields
- //
- //------------------------------------------------------
-
- private Stream _pieceStream; // write-only stream on the current piece
- private string _partName; // part name used to generate correct piece names
- private ZipArchive _archive;
- private int _currentPieceNumber = 0; // incremented with each piece Close() cycle
- private CompressionMethodEnum _compressionMethod;
- private DeflateOptionEnum _deflateOption;
- private FileMode _mode;
- private FileAccess _access;
- private bool _closed = false;
-
- #endregion Private Fields
- }
-}
-
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/CompressionMethodEnum.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/CompressionMethodEnum.cs
deleted file mode 100644
index aa37eb19c83..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/CompressionMethodEnum.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that enables interactions with Zip archives
-// for OPC scenarios
-//
-//
-//
-//
-
-using System;
-
-namespace MS.Internal.IO.Zip
-{
- ///
- /// CompressionMethodEnum is used to express a required compression on ZipArchive.AddPart calls.
- /// Values in the enumeration correspond to the binary format of the ZipArchive's Compression Method field
- ///
- internal enum CompressionMethodEnum : ushort // takes 2 bytes in data structure
- {
- Stored = 0,
- Deflated = 8
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/Crc32.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/Crc32.cs
deleted file mode 100644
index 3e576de3d2c..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/Crc32.cs
+++ /dev/null
@@ -1,238 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is a CRC32 calculator, originally built for ZIP IO for OPC scenarios.
-// This particular piece of code generic, and doest have ane ZIP or OPC specific
-// features
-//
-//
-//
-//
-
-using System;
-using System.IO;
-using System.Diagnostics;
-
-namespace MS.Internal.IO.Zip
-{
- internal class Crc32Calculator
- {
- ///
- /// We need to initialize table once per all intstances of this class
- /// Instead of using static constructor, we are using lock to do this so that
- /// we don't get into a threading issue
- ///
- internal Crc32Calculator()
- {
- lock (_globalSync)
- {
- if (_Crc32Table == null)
- {
- PrepareTable();
- }
- }
- }
-
- // Calculate CRC from the current position to the end of the stream
- // CRC is calculated accumulatively on to the current residue
- internal UInt32 CalculateStreamCrc(Stream stream)
- {
- byte[] buffer = new byte[0x1000];
-
- Debug.Assert(stream != null);
-
- for(;;)
- {
- int bytesRead = stream.Read(buffer,0,buffer.Length);
- if (bytesRead > 0)
- {
- Accumulate(buffer, 0, bytesRead);
- }
- else
- {
- break;
- }
- }
-
- return Crc;
- }
-
- internal void Accumulate(byte[] buffer, int offset, int count)
- {
- Debug.Assert((offset >=0) && (count >=0) && (offset+count <= buffer.Length));
-
- for(int i =offset; i> 8) & 0x00FFFFFF)
- ^
- _Crc32Table[((_residue ^ buffer[i]) & 0x000000FF)];
- }
- }
-
- internal UInt32 Crc
- {
- get
- {
- return ~_residue;
- }
- }
-
- // set the residue to the intial value so that we can recalculate CRC
- internal void ClearCrc()
- {
- _residue = _InitialResidueValue;
- }
-
- static private void PrepareTable()
- {
- _Crc32Table = new UInt32[256];
-
- for(uint tablePosition=0; tablePosition < _Crc32Table.Length; tablePosition++)
- {
- for(byte bitPosition=0; bitPosition < 32; bitPosition++)
- {
- bool bitValue = false;
- foreach(byte maskingBit in _maskingBitTable[bitPosition])
- {
- bitValue ^= GetBit(maskingBit, tablePosition);
- }
- SetBit(bitPosition, ref (_Crc32Table[tablePosition]), bitValue);
- }
- }
-}
-
- private static bool GetBit(byte bitOrdinal, UInt32 data)
- {
- Debug.Assert(bitOrdinal < 32);
-
- return ((data >> bitOrdinal) & 0x1) == 1;
- }
-
- // only valid in this context (the bit in to is always 0)
- private static void SetBit(byte bitOrdinal, ref UInt32 data, bool value)
- {
- Debug.Assert(bitOrdinal < 32);
-
- if (value)
- {
- data |= ((UInt32)0x1 << bitOrdinal);
- }
- }
-
- private const UInt32 _InitialResidueValue = 0xFFFFFFFF;
- private UInt32 _residue = _InitialResidueValue;
-
- private static Object _globalSync = new Object();
-
- // static CRC table , which is calculated in the stqatic constructor
- private static UInt32[] _Crc32Table;
-
- // static bit mask table that is used to calculate _Crc32Table
- private static byte[][] _maskingBitTable =
- {new byte[] {2},
- new byte[] {0,3},
- new byte[] {0,1,4},
- new byte[] {1,2,5},
- new byte[] {0,2,3,6},
- new byte[] {1,3,4,7},
- new byte[] {4,5},
- new byte[] {0,5,6},
- new byte[] {1,6,7},
- new byte[] {7},
- new byte[] {2},
- new byte[] {3},
- new byte[] {0,4},
- new byte[] {0,1,5},
- new byte[] {1,2,6},
- new byte[] {2,3,7},
- new byte[] {0,2,3,4},
- new byte[] {0,1,3,4,5},
- new byte[] {0,1,2,4,5,6},
- new byte[] {1,2,3,5,6,7},
- new byte[] {3,4,6,7},
- new byte[] {2,4,5,7},
- new byte[] {2,3,5,6},
- new byte[] {3,4,6,7},
- new byte[] {0,2,4,5,7},
- new byte[] {0,1,2,3,5,6},
- new byte[] {0,1,2,3,4,6,7},
- new byte[] {1,3,4,5,7},
- new byte[] {0,4,5,6},
- new byte[] {0,1,5,6,7},
- new byte[] {0,1,6,7},
- new byte[] {1,7}};
-
-// _Crc32Table should contain the following :
-// --CRC32 Table--
-// 0000000000 - 0000000000 0x77073096 0xee0e612c 0x990951ba
-// 0x00000004 - 0x076dc419 0x706af48f 0xe963a535 0x9e6495a3
-// 0x00000008 - 0x0edb8832 0x79dcb8a4 0xe0d5e91e 0x97d2d988
-// 0x0000000c - 0x09b64c2b 0x7eb17cbd 0xe7b82d07 0x90bf1d91
-// 0x00000010 - 0x1db71064 0x6ab020f2 0xf3b97148 0x84be41de
-// 0x00000014 - 0x1adad47d 0x6ddde4eb 0xf4d4b551 0x83d385c7
-// 0x00000018 - 0x136c9856 0x646ba8c0 0xfd62f97a 0x8a65c9ec
-// 0x0000001c - 0x14015c4f 0x63066cd9 0xfa0f3d63 0x8d080df5
-// 0x00000020 - 0x3b6e20c8 0x4c69105e 0xd56041e4 0xa2677172
-// 0x00000024 - 0x3c03e4d1 0x4b04d447 0xd20d85fd 0xa50ab56b
-// 0x00000028 - 0x35b5a8fa 0x42b2986c 0xdbbbc9d6 0xacbcf940
-// 0x0000002c - 0x32d86ce3 0x45df5c75 0xdcd60dcf 0xabd13d59
-// 0x00000030 - 0x26d930ac 0x51de003a 0xc8d75180 0xbfd06116
-// 0x00000034 - 0x21b4f4b5 0x56b3c423 0xcfba9599 0xb8bda50f
-// 0x00000038 - 0x2802b89e 0x5f058808 0xc60cd9b2 0xb10be924
-// 0x0000003c - 0x2f6f7c87 0x58684c11 0xc1611dab 0xb6662d3d
-// 0x00000040 - 0x76dc4190 0x01db7106 0x98d220bc 0xefd5102a
-// 0x00000044 - 0x71b18589 0x06b6b51f 0x9fbfe4a5 0xe8b8d433
-// 0x00000048 - 0x7807c9a2 0x0f00f934 0x9609a88e 0xe10e9818
-// 0x0000004c - 0x7f6a0dbb 0x086d3d2d 0x91646c97 0xe6635c01
-// 0x00000050 - 0x6b6b51f4 0x1c6c6162 0x856530d8 0xf262004e
-// 0x00000054 - 0x6c0695ed 0x1b01a57b 0x8208f4c1 0xf50fc457
-// 0x00000058 - 0x65b0d9c6 0x12b7e950 0x8bbeb8ea 0xfcb9887c
-// 0x0000005c - 0x62dd1ddf 0x15da2d49 0x8cd37cf3 0xfbd44c65
-// 0x00000060 - 0x4db26158 0x3ab551ce 0xa3bc0074 0xd4bb30e2
-// 0x00000064 - 0x4adfa541 0x3dd895d7 0xa4d1c46d 0xd3d6f4fb
-// 0x00000068 - 0x4369e96a 0x346ed9fc 0xad678846 0xda60b8d0
-// 0x0000006c - 0x44042d73 0x33031de5 0xaa0a4c5f 0xdd0d7cc9
-// 0x00000070 - 0x5005713c 0x270241aa 0xbe0b1010 0xc90c2086
-// 0x00000074 - 0x5768b525 0x206f85b3 0xb966d409 0xce61e49f
-// 0x00000078 - 0x5edef90e 0x29d9c998 0xb0d09822 0xc7d7a8b4
-// 0x0000007c - 0x59b33d17 0x2eb40d81 0xb7bd5c3b 0xc0ba6cad
-// 0x00000080 - 0xedb88320 0x9abfb3b6 0x03b6e20c 0x74b1d29a
-// 0x00000084 - 0xead54739 0x9dd277af 0x04db2615 0x73dc1683
-// 0x00000088 - 0xe3630b12 0x94643b84 0x0d6d6a3e 0x7a6a5aa8
-// 0x0000008c - 0xe40ecf0b 0x9309ff9d 0x0a00ae27 0x7d079eb1
-// 0x00000090 - 0xf00f9344 0x8708a3d2 0x1e01f268 0x6906c2fe
-// 0x00000094 - 0xf762575d 0x806567cb 0x196c3671 0x6e6b06e7
-// 0x00000098 - 0xfed41b76 0x89d32be0 0x10da7a5a 0x67dd4acc
-// 0x0000009c - 0xf9b9df6f 0x8ebeeff9 0x17b7be43 0x60b08ed5
-// 0x000000a0 - 0xd6d6a3e8 0xa1d1937e 0x38d8c2c4 0x4fdff252
-// 0x000000a4 - 0xd1bb67f1 0xa6bc5767 0x3fb506dd 0x48b2364b
-// 0x000000a8 - 0xd80d2bda 0xaf0a1b4c 0x36034af6 0x41047a60
-// 0x000000ac - 0xdf60efc3 0xa867df55 0x316e8eef 0x4669be79
-// 0x000000b0 - 0xcb61b38c 0xbc66831a 0x256fd2a0 0x5268e236
-// 0x000000b4 - 0xcc0c7795 0xbb0b4703 0x220216b9 0x5505262f
-// 0x000000b8 - 0xc5ba3bbe 0xb2bd0b28 0x2bb45a92 0x5cb36a04
-// 0x000000bc - 0xc2d7ffa7 0xb5d0cf31 0x2cd99e8b 0x5bdeae1d
-// 0x000000c0 - 0x9b64c2b0 0xec63f226 0x756aa39c 0x026d930a
-// 0x000000c4 - 0x9c0906a9 0xeb0e363f 0x72076785 0x05005713
-// 0x000000c8 - 0x95bf4a82 0xe2b87a14 0x7bb12bae 0x0cb61b38
-// 0x000000cc - 0x92d28e9b 0xe5d5be0d 0x7cdcefb7 0x0bdbdf21
-// 0x000000d0 - 0x86d3d2d4 0xf1d4e242 0x68ddb3f8 0x1fda836e
-// 0x000000d4 - 0x81be16cd 0xf6b9265b 0x6fb077e1 0x18b74777
-// 0x000000d8 - 0x88085ae6 0xff0f6a70 0x66063bca 0x11010b5c
-// 0x000000dc - 0x8f659eff 0xf862ae69 0x616bffd3 0x166ccf45
-// 0x000000e0 - 0xa00ae278 0xd70dd2ee 0x4e048354 0x3903b3c2
-// 0x000000e4 - 0xa7672661 0xd06016f7 0x4969474d 0x3e6e77db
-// 0x000000e8 - 0xaed16a4a 0xd9d65adc 0x40df0b66 0x37d83bf0
-// 0x000000ec - 0xa9bcae53 0xdebb9ec5 0x47b2cf7f 0x30b5ffe9
-// 0x000000f0 - 0xbdbdf21c 0xcabac28a 0x53b39330 0x24b4a3a6
-// 0x000000f4 - 0xbad03605 0xcdd70693 0x54de5729 0x23d967bf
-// 0x000000f8 - 0xb3667a2e 0xc4614ab8 0x5d681b02 0x2a6f2b94
-// 0x000000fc - 0xb40bbe37 0xc30c8ea1 0x5a05df1b 0x2d02ef8d
- }
-}
-
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/DeflateOptionEnum.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/DeflateOptionEnum.cs
deleted file mode 100644
index 63738c290de..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/DeflateOptionEnum.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that enables interactions with Zip archives
-// for OPC scenarios
-//
-//
-//
-//
-
-using System;
-
-namespace MS.Internal.IO.Zip
-{
- ///
- /// DeflateOptionEnum is used to express a required compression on ZipArchive.AddPart calls
- /// Values in the enumeration (except None 0xFF) correspond to the binary format of the
- /// ZipArchive's General Purpose Bit flags (bits 1 and 2). In order to match this value with the
- /// General Purpose Bit flags, DeflateOptionEnum must be masked by the value 0x06
- /// 0xFF is a special value that is used to indicate "not applicable" for cases when data isn't deflated.
- ///
- internal enum DeflateOptionEnum : byte // takes 2 bits in the data structure
- {
- Normal = 0, //values are selected based on their position in the General purpose bit flag
- Maximum = 2, // bits 1 and 2
- Fast = 4,
- SuperFast = 6,
- None = 0xFF
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/IZipIOBlock.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/IZipIOBlock.cs
deleted file mode 100644
index 44ffad3cbd5..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/IZipIOBlock.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that enables interactions with Zip archives
-// for OPC scenarios
-//
-//
-//
-//
-
-using System;
-using System.IO;
-
-namespace MS.Internal.IO.Zip
-{
- internal enum PreSaveNotificationScanControlInstruction : int
- {
- Continue = 0, // instruction to continue Pre Save Notification on the following block
- Stop = 1, // instruction to stop Pre Save Notification loop
- }
-
- ///
- /// IZipIOBlock - this interface is used to enable polymorphism across all
- /// supported Zip IO records. This enables ZipIOBlockManager to manipulate all blocks in a uniform way
- ///
- internal interface IZipIOBlock
- {
- ///
- /// This is the current offset of the block relative to the start of the archive stream.
- /// It might not necessarily correspond to the current location
- /// of the block on disk. It is rather the Offset that will be used by the Save function to write data out.
- /// If Block Manager needs to insert a new block it should call Move which in Turn will mark those blocks
- /// dirty and will change the offset.
- ///
- long Offset{get;}
-
- ///
- /// This is the current size of the block, it might not neccessarily correspond to the current size of the
- /// block on disk. It is rather the Size that will be used up if Save function is called. Block Manager
- /// doesn't have any direct control over this size. It is changeble only by Block Specific operations
- /// (stream operations with ZipIOLocalFileBlock, add/remove files with the CentralDirectoryBlock and so on)
- ///
- long Size{get;}
-
- ///
- /// This is the current state of block, if block is marked dirty it means that it was either moved from the
- /// original location of load, or it was changed by the external APIs. Block Manager
- /// doesn't have any direct control over this flag. It can be affected by calls to Move,
- /// Save, UpdateReferences and Block Specific operations (like stream operations with ZipIOLocalFileBlock,
- /// add/remove files with the CentralDirectoryBlock and so on)
- /// closingFlag parameter indicates whether we querying the Dirty state for purposes of flushing or closing.
- /// The only case where it makes a difference is the compressed stream. Which in the Write Through mode
- /// will be Dirty for close but not Dirty for flush.
- ///
- bool GetDirtyFlag(bool closingFlag);
-
- ///
- /// This function is used by the ZipIOBlockManager to adjust positions of the block in the archive, it's mostly
- /// used for adding/deleting new file item blocks. Call to this function with a parameter not equal to 0 must
- /// mark the block as dirty.
- ///
- void Move(long shiftSize);
-
- ///
- /// This function is used by the ZipIOBlockManager to Save given block into it's current Offset position.
- /// Call to this function will result in making DirtyFlag = false;
- ///
- void Save();
-
- ///
- /// This function is used by the ZipIOBlockManager to prepare block for Saving. If called on a block this function
- /// is ultimately responsible for marking this block dirty for any reason including changes in other blocks. For example
- /// during normal operation of the ZipIoBlock Manager EndOfCentralDirectoryBlock isn't updated with the location
- /// and size of the Central Directory on every single operation that might affect it. Only just before saving
- /// EndOfCentralDirectoryBlock is notified using update references call that it needs to check its' local record against
- /// the position and size of the CentralDirectory. If there is a mismatch EndOfCentralDirectory will update it's local informtion
- /// and mark itself dirty.
- /// Similar things happen when CentralDirectoryBlock is called to UpdateReferences; it walks through all RawDataBlocks
- /// and FileItemBlocks, and updates Central Directory records accordingly.
- /// closingFlag parameter indicates that we should be closing streams not just flushing them. It makes a huge
- /// difference for deflate scenarios where Flush is NOP and Close is actually always writing out extra data.
- ///
- void UpdateReferences(bool closingFlag);
-
- ///
- /// This function is used by the ZipIOBlockManager to notify blocks that some area of the file is about to to be overwritten.
- /// Depending on the caching policy of each block type (or particular block instance), it might choose to ignore this notification.
- /// For Example EndOfCentralDirectoryBlock and CentralDirectoryBlocks are always fully cached (have complete snapshot of
- /// the latest data in memory). Which means, that they do not care whether the area of the file where this data has originated
- /// is overwritten or not.
- /// In contrast RawDataBlock and LocalFileBlock by default do not cache everything in memory, so they need to implement
- /// PreSaveNotification call. These types of blocks need to at least load data that they might need from disk, and make sure that the
- /// area described by the parameters doesn't have any data that needs to be preserved.
- ///
- /// Block can also return a value indicating whether PreSaveNotification should be extended to the blocks that are positioned after
- /// it in the Block List. For example, if block has completely handled PreSaveNotification in a way that it cached the whole area that
- /// was in danger (of being overwritten) it means that no blocks need to worry about this anymore. After all, no 2 blocks should have
- /// overlapping disk buffers. Another scenario is when a block can determine that the area in danger is positioned before the block's on-disk
- /// buffers; this means that all blocks that are positioned later in the block list do not need to worry about this PreSaveNotification
- /// as their buffers should be positioned even further along in the file.
- ///
- PreSaveNotificationScanControlInstruction PreSaveNotification(long offset, long size);
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ProgressiveCrcCalculatingStream.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ProgressiveCrcCalculatingStream.cs
deleted file mode 100644
index 65a53fe5aff..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ProgressiveCrcCalculatingStream.cs
+++ /dev/null
@@ -1,353 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal stream class that calcuates CRC values progressively
-// if possible
-//
-
-
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Windows; // For Exception strings - SRID
-
-using MS.Internal.IO.Zip;
-using MS.Internal.WindowsBase;
-
-namespace MS.Internal.IO.Zip
-{
- internal class ProgressiveCrcCalculatingStream: Stream
- {
- ////////////////////////////////////
- // Stream section
- /////////////////////////////////
- override public bool CanRead
- {
- get
- {
- return (_underlyingStream != null && _underlyingStream.CanRead);
- }
- }
-
- override public bool CanSeek
- {
- get
- {
- return (_underlyingStream != null && _underlyingStream.CanSeek);
- }
- }
-
- override public bool CanWrite
- {
- get
- {
- return (_underlyingStream != null && _underlyingStream.CanWrite);
- }
- }
-
- override public long Length
- {
- get
- {
- CheckDisposed();
-
- return _underlyingStream.Length;
- }
- }
-
- override public long Position
- {
- get
- {
- CheckDisposed();
-
- return _underlyingStream.Position;
- }
-
- set
- {
- CheckDisposed();
-
- _underlyingStream.Position = value;
- }
- }
-
- public override void SetLength(long newLength)
- {
- CheckDisposed();
-
- if (newLength < 0)
- {
- throw new ArgumentOutOfRangeException("newLength");
- }
-
- if (newLength < _highWaterMark)
- {
- _highWaterMark = -1;
- }
-
- // We don't do any check if newLength == current length here
- // this normally should result in no-op, but this will complicate
- // the logic due to the need of caching the underlying stream length
- // Not doing this check here might result in CRC check being skipped
-
- _underlyingStream.SetLength(newLength);
- // Setting a new length is the same as write operation
- // CRC cannot be checked against the to-be-validated CRC anymore
- _validateCrcWithExpectedCrc = false;
-
- // mark the global dirty flag
- _blockManager.DirtyFlag = true;
- }
-
- override public long Seek(long offset, SeekOrigin origin)
- {
- CheckDisposed();
-
- return _underlyingStream.Seek(offset, origin);
- }
-
- override public int Read(byte[] buffer, int offset, int count)
- {
- CheckDisposed();
-
- int readCount = 0;
-
- // We should calculate CRC accumulatively for the following conditions
- // 1. Seek is not supported by the underlying stream: this will be the case for
- // writing stream in streaming mode
- // 2. This write request is consequtive to the highwater mark of the CRC calculation
- // 3. This write request is at 0 offset and the CRC hasn't been calculated yet
- if (!_underlyingStream.CanSeek) // Case #1
- {
- readCount = _underlyingStream.Read(buffer, offset, count);
- CrcCalculator.Accumulate(buffer, offset, readCount);
- }
- else
- {
- long originalPosition = _underlyingStream.Position;
-
- readCount = _underlyingStream.Read(buffer, offset, count);
-
- // This operation needs to be done after Read since read can throw an exception; in that case
- // we want to preserve the original CRC
- if (originalPosition == 0 && _highWaterMark == -1)
- {
- _highWaterMark = 0;
- CrcCalculator.ClearCrc();
- }
-
- if (originalPosition == _highWaterMark)
- {
- CrcCalculator.Accumulate(buffer, offset, readCount);
- _highWaterMark = _underlyingStream.Position;
- }
-
- if (_validateCrcWithExpectedCrc && CanValidateCrcWithoutRead())
- {
- if (CrcCalculator.Crc != _expectedCrc)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
- }
- }
-
- return readCount;
- }
-
- override public void Write(byte[] buffer, int offset, int count)
- {
- CheckDisposed();
-
- // We should calculate CRC accumulatively for the following conditions
- // 1. Seek is not supported by the underlying stream: this will be the case for
- // writing stream in streaming mode
- // 2. This write request is consequtive to the highwater mark of the CRC calculation
- // 3. This write request is at 0 offset and the CRC hasn't been calculated yet
- if (!_underlyingStream.CanSeek) // Case #1
- {
- _underlyingStream.Write(buffer, offset, count);
- CrcCalculator.Accumulate(buffer, offset, count);
- }
- else
- {
- long originalPosition = _underlyingStream.Position;
-
- // If we ever fail to Write below _highWaterMark, we want CRC to be recalculated in case
- // if a caller decides to recover from the error
- if (originalPosition < _highWaterMark)
- {
- _highWaterMark = -1;
- }
-
- _underlyingStream.Write(buffer, offset, count);
-
- if (originalPosition == 0)
- {
- _highWaterMark = 0;
- CrcCalculator.ClearCrc();
-}
-
- if (originalPosition == _highWaterMark)
- {
- CrcCalculator.Accumulate(buffer, offset, count);
- _highWaterMark = _underlyingStream.Position;
- }
- }
-
- // CRC cannot be checked against the to-be-validated CRC anymore
- _validateCrcWithExpectedCrc = false;
-
- // mark the global dirty flag
- _blockManager.DirtyFlag = true;
- }
-
- override public void Flush()
- {
- CheckDisposed();
-
- _underlyingStream.Flush();
- }
-
- /////////////////////////////
- // Internal Constructor
- /////////////////////////////
- internal ProgressiveCrcCalculatingStream(ZipIOBlockManager blockManager, Stream underlyingStream) :
- this(blockManager, underlyingStream, 0)
- {
- _validateCrcWithExpectedCrc = false;
- }
-
- internal ProgressiveCrcCalculatingStream(ZipIOBlockManager blockManager, Stream underlyingStream, UInt32 expectedCrc)
- {
- Debug.Assert(underlyingStream != null);
- Debug.Assert(blockManager != null);
-
- _blockManager = blockManager;
- _underlyingStream = underlyingStream;
- _validateCrcWithExpectedCrc = true;
- _expectedCrc = expectedCrc;
- _highWaterMark = -1;
- }
-
- //------------------------------------------------------
- //
- // Protected Methods
- //
- //------------------------------------------------------
- ///
- /// Dispose(bool)
- ///
- ///
- /// We implement this because we want a consistent experience (essentially Flush our data) if the user chooses to
- /// call Dispose() instead of Close().
- protected override void Dispose(bool disposing)
- {
- try
- {
- if (disposing)
- {
- //streams wrapping this stream shouldn't pass Dipose calls through
- // it is responsibility of the BlockManager or LocalFileBlock (in case of Remove) to call
- // this dispose as appropriate (that is the reason why Flush isn't called here)
-
- // multiple calls are fine - just ignore them
- // and we shouldn't be closing a stream which we do not own
- _underlyingStream = null;
- }
- }
- finally
- {
- base.Dispose(disposing);
- }
- }
-
- /////////////////////////////
- // Internal Methods
- /////////////////////////////
-
-
- // !!!!!!!!!!!!!!!!IMPORTANT !!!!!!!!!!!!!!!!
- // This method doesn't preserve the seek position of the underlying stream.
- // It (non-preservation of the seek pointer) is mostly done for compression
- // scenarios in which seeking back in the compressed streams will result in
- // switching to the expensive simulation stream. This method is only called
- // from scenarios during Flush Close of the package where position of the
- // Compressed stream is insignificant
- internal UInt32 CalculateCrc()
- {
- CheckDisposed();
-
- if (_underlyingStream.CanSeek)
- {
- long originalPosition = _underlyingStream.Position;
-
- if (_highWaterMark == -1)
- {
- CrcCalculator.ClearCrc();
- _highWaterMark = 0;
- }
-
- if (_highWaterMark < _underlyingStream.Length)
- {
- _underlyingStream.Position = _highWaterMark;
- CrcCalculator.CalculateStreamCrc(_underlyingStream);
- _highWaterMark = _underlyingStream.Length;
- }
- }
-
- return CrcCalculator.Crc;
- }
-
- /////////////////////////////
- // Private Methods
- /////////////////////////////
-
- private void CheckDisposed()
- {
- if (_underlyingStream == null)
- {
- throw new ObjectDisposedException(null, SR.Get(SRID.StreamObjectDisposed));
- }
- }
-
- private Crc32Calculator CrcCalculator
- {
- get
- {
- if (_crcCalculator == null)
- {
- _crcCalculator = new Crc32Calculator();
- }
- return _crcCalculator;
- }
- }
-
- private bool CanValidateCrcWithoutRead()
- {
- if (_underlyingStream.CanSeek && _highWaterMark == _underlyingStream.Length)
- {
- return true;
- }
-
- return false;
- }
-
- // this is only used to switch the dirty flag in case of Write or SetLength
- // no other communication is done with the BlockManager from this class
- private ZipIOBlockManager _blockManager;
-
- private long _highWaterMark;
- private Crc32Calculator _crcCalculator;
- private bool _validateCrcWithExpectedCrc;
- private UInt32 _expectedCrc;
-
- private Stream _underlyingStream;
- }
-}
-
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/WriteTimeStream.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/WriteTimeStream.cs
deleted file mode 100644
index 1234b278c99..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/WriteTimeStream.cs
+++ /dev/null
@@ -1,169 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-//
-//
-// Description:
-// WriteTimeStream - wraps the ArchiveStream in Streaming generation scenarios so that we
-// can determine current archive stream offset even when working on a stream that is non-seekable
-// because the Position property is unusable on such streams.
-//
-//
-//
-//
-
-using System;
-using System.IO;
-using System.Windows;
-using MS.Internal.WindowsBase;
-
-namespace MS.Internal.IO.Zip
-{
- internal class WriteTimeStream : Stream
- {
- //------------------------------------------------------
- //
- // Public Properties
- //
- //------------------------------------------------------
- ///
- /// CanRead - never
- ///
- override public bool CanRead { get { return false; } }
-
- ///
- /// CanSeek - never
- ///
- override public bool CanSeek{ get { return false; } }
-
- ///
- /// CanWrite - only if we are not disposed
- ///
- override public bool CanWrite { get { return (_baseStream != null); } }
-
- ///
- /// Same as Position
- ///
- override public long Length
- {
- get
- {
- CheckDisposed();
- return _position;
- }
- }
-
- ///
- /// Get is supported even on Write-only stream
- ///
- override public long Position
- {
- get
- {
- CheckDisposed();
- return _position;
- }
- set
- {
- CheckDisposed();
- IllegalAccess(); // throw exception
- }
- }
-
- //------------------------------------------------------
- //
- // Public Methods
- //
- //------------------------------------------------------
- public override void SetLength(long newLength)
- {
- IllegalAccess(); // throw exception
- }
-
- override public long Seek(long offset, SeekOrigin origin)
- {
- IllegalAccess(); // throw exception
- return -1; // keep compiler happy
- }
-
- override public int Read(byte[] buffer, int offset, int count)
- {
- IllegalAccess(); // throw exception
- return -1; // keep compiler happy
- }
-
- override public void Write(byte[] buffer, int offset, int count)
- {
- CheckDisposed();
- _baseStream.Write(buffer, offset, count);
- checked{_position += count;}
- }
-
- override public void Flush()
- {
- CheckDisposed();
- _baseStream.Flush();
- }
-
- //------------------------------------------------------
- //
- // Internal Methods
- //
- //------------------------------------------------------
- internal WriteTimeStream(Stream baseStream)
- {
- if (baseStream == null)
- {
- throw new ArgumentNullException("baseStream");
- }
-
- _baseStream = baseStream;
-
- // must be based on writable stream
- if (!_baseStream.CanWrite)
- throw new ArgumentException(SR.Get(SRID.WriteNotSupported), "baseStream");
- }
-
- //------------------------------------------------------
- //
- // Protected Methods
- //
- //------------------------------------------------------
- protected override void Dispose(bool disposing)
- {
- try
- {
- if (disposing && (_baseStream != null))
- {
- _baseStream.Close();
- }
- }
- finally
- {
- _baseStream = null;
- base.Dispose(disposing);
- }
- }
-
- //------------------------------------------------------
- //
- // Private Methods
- //
- //------------------------------------------------------
- private static void IllegalAccess()
- {
- throw new NotSupportedException(SR.Get(SRID.WriteOnlyStream));
- }
-
- private void CheckDisposed()
- {
- if (_baseStream == null)
- throw new ObjectDisposedException("Stream");
- }
-
- // _baseStream doubles as our disposed indicator - it's null if we are disposed
- private Stream _baseStream; // stream we wrap - needs to only support Write
- private long _position; // current position
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipArchive.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipArchive.cs
deleted file mode 100644
index f6898297423..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipArchive.cs
+++ /dev/null
@@ -1,700 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that enables interactions with Zip archives
-// for OPC scenarios
-//
-//
-//
-//
-
-using System;
-using System.IO;
-using System.Diagnostics;
-using System.Collections;
-using System.Globalization;
-using System.Runtime.Serialization;
-using System.Windows;
-using MS.Internal.WindowsBase;
-
-namespace MS.Internal.IO.Zip
-{
- ///
- /// This is the main clas of the ZIP IO internal APIs. It has 2 stsatic constructors
- /// OpenOnFile and OpenOnStream. It provides client app with ability to manipulate
- /// a Zip Archive (create, open, open/add/delete file items).
- ///
- internal sealed class ZipArchive : IDisposable
- {
- //------------------------------------------------------
- //
- // Public Members
- //
- //------------------------------------------------------
- // None
-
- //------------------------------------------------------
- //
- // Internal Constructors
- //
- //------------------------------------------------------
- // None
-
- //------------------------------------------------------
- //
- // Internal API Methods (although these methods are marked as
- // Internal, they are part of the internal ZIP IO API surface
- //
- //------------------------------------------------------
- ///
- /// Static constructor File based constructor. all parameteres are obvious.
- /// This constructor wil open the file in requested mode, and it will not do any futher parsing.
- ///
- /// In the case of Create/CreateNew, it will also prebuild in cached in-memory
- /// EndOfCentralDirectoryRecord (which is a minimal zip file requirement), so that if user
- /// chooses to close right after he will get a file with just EndOfCentralDirectoryRecord.
- ///
- internal static ZipArchive OpenOnFile(string path, FileMode mode, FileAccess access, FileShare share, bool streaming)
- {
- if (mode == FileMode.OpenOrCreate || mode == FileMode.Open)
- {
- // for OpenOrCreate cases we need to check whether it is an exisiting file of size 0.
- // Files of size 0 are onsidered invalid ZipArchives. If we skip this check here, later we wouldn't be able to distinguish
- // between brand new file being created as a result of OpenOrCreate mode, or old 0 length file being open as a result of
- // OpenOrCreate mode.
- FileInfo fileInfo = new FileInfo(path);
-
- if (fileInfo.Exists && fileInfo.Length == 0 && (fileInfo.Attributes & FileAttributes.ReparsePoint) == 0)
- {
- throw new FileFormatException(SR.Get(SRID.ZipZeroSizeFileIsNotValidArchive));
- }
- }
-
- ZipArchive archive = null;
- FileStream archiveStream = null;
-
- // We would like to run initialization after openning stream in try/catch block
- // so that if anything goes wrong we can close the stream (release file handler)
- try
- {
- archiveStream = new FileStream(path, mode, access, share, 4096, streaming);
-
- ValidateModeAccessShareStreaming(archiveStream, mode, access, share, streaming);
-
- archive = new ZipArchive(archiveStream, mode, access, streaming, true);
- }
- catch
- {
- if (archive != null)
- {
- archive.Close();
- }
-
- if(archiveStream != null)
- {
- archiveStream.Close();
- }
-
- throw;
- }
-
- return archive;
- }
-
- ///
- /// Static constructor Stream based constructor. all parameteres are obvious.
- /// This constructor wil not do any futher parsing.
- ///
- /// In the case of Create/CreateNew, it will also prebuild in cached in-memory
- /// EndOfCentralDirectoryRecord (which is a minimal zip file requirement), so that if user
- /// chooses to close right after he will get a file with just EndOfCentralDirectoryRecord.
- ///
- internal static ZipArchive OpenOnStream(Stream stream, FileMode mode, FileAccess access, bool streaming)
- {
- // we can assume FileShare.None, as there is absolutely nothing we can do
- // about other people working with the underlying storage
- ValidateModeAccessShareStreaming(stream, mode, access, FileShare.None, streaming);
-
- if (stream.CanSeek)
- {
- bool emptyStream = (stream.Length == 0);
-
- switch (mode)
- {
- // for Open cases we need to check whether it is an existing file of size 0.
- // Streams of size 0 are considered invalid ZipArchives.
- case FileMode.Open:
- if (emptyStream)
- {
- throw new FileFormatException(SR.Get(SRID.ZipZeroSizeFileIsNotValidArchive));
- }
- break;
-
- // for Create cases, we need to check if the stream is empty or not
- case FileMode.CreateNew:
- if (!emptyStream)
- {
- throw new IOException(SR.Get(SRID.CreateNewOnNonEmptyStream));
- }
- break;
- case FileMode.Create:
- if (!emptyStream)
- {
- // discard existing data
- stream.SetLength(0);
- }
- break;
- }
- }
-
- return new ZipArchive(stream, mode, access, streaming, false);
- }
-
-
- ///
- /// This method will result in a complete parsing of the EndOfCentralDirectory
- /// and CentralDirectory records (if it hasn't been done yet).
- /// After that (assuming no duplicates were found). It will create in appropriate
- /// in memory Local FileHeaders and Central Directory Headers.
- ///
- internal ZipFileInfo AddFile(string zipFileName, CompressionMethodEnum compressionMethod, DeflateOptionEnum deflateOption)
- {
- CheckDisposed();
-
- if (_openAccess == FileAccess.Read)
- {
- throw new InvalidOperationException(SR.Get(SRID.CanNotWriteInReadOnlyMode));
- }
-
- // Validate parameteres
- zipFileName = ZipIOBlockManager.ValidateNormalizeFileName(zipFileName);
-
- if ((compressionMethod != CompressionMethodEnum.Stored) &&
- (compressionMethod != CompressionMethodEnum.Deflated))
- {
- throw new ArgumentOutOfRangeException("compressionMethod");
- }
-
- // non-contiguous range requires more complex test
- if (deflateOption < DeflateOptionEnum.Normal || (
- deflateOption > DeflateOptionEnum.SuperFast && deflateOption != DeflateOptionEnum.None))
- {
- throw new ArgumentOutOfRangeException("deflateOption");
- }
-
- // Check for duplicates ,
- if (FileExists(zipFileName))
- {
- throw new System.InvalidOperationException(SR.Get(SRID.AttemptedToCreateDuplicateFileName));
- }
-
- // Create Local File Block through Block Manager
- ZipIOLocalFileBlock fileBlock = _blockManager.CreateLocalFileBlock(zipFileName, compressionMethod, deflateOption);
-
- //build new ZipFileInfo and add reference to the collection, so we can keep track of the instances of the ZipFileInfo,
- // that were given out and invalidate any collection that was returned on GetFiles calls
- ZipFileInfo zipFileInfo = new ZipFileInfo(this, fileBlock);
- ZipFileInfoDictionary.Add(zipFileInfo.Name, zipFileInfo);
-
- return zipFileInfo;
- }
-
- ///
- /// This method will result in a complete parsing of the EndOfCentralDirectory
- /// and CentralDirectory records (if it hasn't been done yet).
- /// After that (assuming the file was found). It will parse the apropriate local file block
- /// header and data descriptor (if present).
- ///
- internal ZipFileInfo GetFile(string zipFileName)
- {
- CheckDisposed();
-
- if (_openAccess == FileAccess.Write)
- {
- throw new InvalidOperationException(SR.Get(SRID.CanNotReadInWriteOnlyMode));
- }
-
- // Validate parameteres
- zipFileName = ZipIOBlockManager.ValidateNormalizeFileName(zipFileName);
-
- // try to get it from the ZipFileInfo dictionary
- if (ZipFileInfoDictionary.Contains(zipFileName))
- {
- // this ZipFileInfo was already built through AddFile or GetFile(s)
- // we have this cached
- return (ZipFileInfo)(ZipFileInfoDictionary[zipFileName]);
- }
- else
- {
- // we need to check whether it is present in the central directory
- if (!FileExists(zipFileName))
- {
- throw new InvalidOperationException(SR.Get(SRID.FileDoesNotExists));
- }
-
- // Load Local File Block through Block Manager
- ZipIOLocalFileBlock fileBlock = _blockManager.LoadLocalFileBlock(zipFileName);
-
- // build new ZipFileInfo and add reference to the collection, so we can keep track of the instances of the ZipFileInfo,
- // that were given out and invalidate any collection that was returned on GetFiles calls
- ZipFileInfo zipFileInfo = new ZipFileInfo(this, fileBlock);
-
- //this should invalidate any outstanding collections
- ZipFileInfoDictionary.Add(zipFileInfo.Name, zipFileInfo);
-
- return zipFileInfo;
- }
- }
-
- ///
- /// This method will result in a complete parsing of the EndOfCentralDirectory
- /// and CentralDirectory records (if it hasn't been done yet).
- /// After that it will check whether central directory contains the file.
- /// It will not attempt the parsing of the local file headers / descriptors.
- ///
- internal bool FileExists (string zipFileName)
- {
- CheckDisposed();
-
- // Validate parameteres
- zipFileName = ZipIOBlockManager.ValidateNormalizeFileName(zipFileName);
-
- return _blockManager.CentralDirectoryBlock.FileExists(zipFileName);
- }
-
-
- ///
- /// This method will result in a complete parsing of the EndOfCentralDirectory
- /// and CentralDirectory records (if it hasn't been done yet).
- /// After that it will check whether central directory contains the file.
- /// If it is present it will parse local fileheader, and remove their in memory
- /// representation
- ///
- internal void DeleteFile (string zipFileName)
- {
- CheckDisposed();
-
- if (_openAccess == FileAccess.Read)
- {
- throw new InvalidOperationException(SR.Get(SRID.CanNotWriteInReadOnlyMode));
- }
-
- // Validate parameteres
- zipFileName = ZipIOBlockManager.ValidateNormalizeFileName(zipFileName);
-
- if (FileExists(zipFileName)) // is it in central Directory ?
- {
- ZipFileInfo fileInfoToBeDeleted = GetFile(zipFileName);
-
- //this should invalidate any outstanding collections
- // and update central directory status as appropriate
- ZipFileInfoDictionary.Remove(zipFileName);
-
- //this should remove the local file block
- // from the blockManager's collection
- _blockManager.RemoveLocalFileBlock(fileInfoToBeDeleted.LocalFileBlock);
- }
- }
-
- ///
- /// This method will result in a complete parsing of the EndOfCentralDirectory
- /// and CentralDirectory records (if it hasn't been done yet).
- /// After that it will go through allfiles in the central directory and parse their
- /// local headers and desciptors one by one.
- ///
- internal ZipFileInfoCollection GetFiles()
- {
- CheckDisposed();
-
- if (_openAccess == FileAccess.Write)
- {
- throw new InvalidOperationException(SR.Get(SRID.CanNotReadInWriteOnlyMode));
- }
-
- // We need to scan through the central Directory, and for each file
- // call GetFile(fileName), which will result in adding missing (not loaded)
- // information to the ZipFileInfoDictionary.
- foreach(string fileName in _blockManager.CentralDirectoryBlock.GetFileNamesCollection())
- {
- GetFile(fileName); // fileName must be validated and normalized at this
- // point by the central directory parsing routine
- }
- return new ZipFileInfoCollection(ZipFileInfoDictionary.Values);
- }
-
- ///
- /// This method will result in a complete Flushing of any outstanding data in buffers and
- /// any streams ever returned by the GetStream calls.This call results in Archive file that
- /// has a completely valid state. If application were to crash right afte the Flush is complete,
- /// the resulting files would be a "valid" Zip archive
- ///
- internal void Flush()
- {
- CheckDisposed();
- _blockManager.Save(false);
- }
-
- ///
- /// Results in a complete Flush of all the outstanding buffers and closing/disposing all of the objects
- /// ZipFileInfo, Streams ZipArchive.
- ///
- internal void Close()
- {
- Dispose();
- }
-
- ///
- /// Results in a complete Flush of all the outstanding buffers and closing/disposing all of the objects
- /// ZipFileInfo, Streams ZipArchive.
- ///
- public void Dispose()
- {
- Dispose(true);
- // GC.SuppressFinalize(this); // Because this class is sealed and there is no Finalizer,
- // there is no need for this call. Leaving it in case we decide to unseal it
- }
-
- ///
- /// Throw if version needed to extract is not supported
- ///
- /// version to inspect
- static internal void VerifyVersionNeededToExtract(UInt16 version)
- {
- // strictly enforce this list
- switch (version)
- {
- case (UInt16)ZipIOVersionNeededToExtract.StoredData: break;
- case (UInt16)ZipIOVersionNeededToExtract.VolumeLabel: break;
- case (UInt16)ZipIOVersionNeededToExtract.DeflatedData: break;
- case (UInt16)ZipIOVersionNeededToExtract.Zip64FileFormat: break;
- default:
- throw new NotSupportedException(SR.Get(SRID.NotSupportedVersionNeededToExtract));
- }
- }
-
- //------------------------------------------------------
- //
- // Internal Properties
- //
- //------------------------------------------------------
- ///
- /// Read only property, that returns the value of FileAccess that
- /// was passed into the OpenOnFile or OpenOnStream call
- ///
- internal FileAccess OpenAccess
- {
- get
- {
- CheckDisposed();
- return _openAccess;
- }
- }
-
-// This functionality commented out in order to comply with FX Cop rule
-// AvoidUncalledPrivateCode. However, because of a chance that this functionality
-// might eventually get public exposure we would like to keep this code around
-#if ZIP_IO_PUBLIC
-
- ///
- /// Returns Comment field from the End Of Central Directory Record.
- /// Therefore, call to this property might result in some parsing.
- /// If the End Of Central Directory isn't parsed yet, it will be as a
- /// result of querying this property.
- ///
- internal string Comment
- {
- get
- {
- CheckDisposed();
- return _blockManager.EndOfCentralDirectoryBlock.Comment;
- }
- }
-#endif
-
-
- //------------------------------------------------------
- //
- // Internal NON API Methods (these methods are marked as
- // Internal, and they are trully internal and not the part of the
- // internal ZIP IO API surface
- //
- //------------------------------------------------------
-
- //------------------------------------------------------
- //
- // Private Constructors
- //
- //------------------------------------------------------
- ///
- /// This private constructor isonly supposed to be called by the
- /// OpenOnFile and OpenOnStream static members.
- ///
- ///
- ///
- ///
- ///
- /// true if this class is responsible for closing the archiveStream
- private ZipArchive(Stream archiveStream, FileMode mode, FileAccess access, bool streaming, bool ownStream)
- {
- // as this contructor is only called from the static member
- // all checks should have been done before
-
- _blockManager = new ZipIOBlockManager(archiveStream, streaming, ownStream);
-
- _openMode = mode;
- _openAccess = access;
-
- // In case of "create" we also need to create at least an end of Central Directory Record.
- // For FileMode OpenOrCreate we use stream Length to distinguish open and create scenarios.
- // Implications of this decision is that existing file of size 0 opened in OpenOrCreate Mode
- // will be treated as a newly/created file.
- if ((_openMode == FileMode.CreateNew) ||
- (_openMode == FileMode.Create) ||
- ((_openMode == FileMode.OpenOrCreate) && archiveStream.Length == 0))
- {
- _blockManager.CreateEndOfCentralDirectoryBlock();
- }
- else
- {
- _blockManager.LoadEndOfCentralDirectoryBlock();
- }
- }
-
- //------------------------------------------------------
- //
- // Private Methods
- //
- //------------------------------------------------------
-
- ///
- /// Dispose(bool)
- ///
- ///
- private void Dispose(bool disposing)
- {
- if (disposing)
- {
- if (!_disposedFlag)
- {
- try
- {
- if (_blockManager != null)
- {
- // allow this in Debug mode to catch any place where we accidentally
- // make something dirty when we are read-only
-#if !DEBUG
- if (_openAccess == FileAccess.ReadWrite || _openAccess == FileAccess.Write)
-#endif
- {
- _blockManager.Save(true);
- }
-
- ((IDisposable)_blockManager).Dispose();
- }
- }
- finally
- {
- _disposedFlag = true;
- }
- }
- }
- }
-
- ///
- /// This is function is called by the OpenOnFile and OpenOnStream in order
- /// to validate parameteresgiven to those functions. The combinations of valid
- /// parameters is quite complex and not obvious, so after basic range checks,
- /// it is actually using a lookup table to answer the question whether the given
- /// parameter combination is valid or not.
- ///
- static private void ValidateModeAccessShareStreaming(Stream stream, FileMode mode, FileAccess access, FileShare share, bool streaming)
- {
- if (stream == null)
- {
- throw new ArgumentNullException("stream");
- }
-
- ////////////
- // filter out values that are out of enum ranges first
- ////////////
- ValidateModeAccessShareValidEnums(mode, access, share);
-
- ////////////
- // filter out values that are not supported regardless of other parameters
- // but still validate enum members
- ////////////
- ValidateModeAccessShareSupportedEnums(mode, share);
-
- ////////////
- // let's makes sure that given stream is capable of supporting required functionality
- ////////////
- ValidateModeAccessStreamStreamingCombinations(stream, access, streaming);
-
- ////////////
- //let's make sure that comnbintaion of mode, access,share,,streaming
- // parameters is supported
- ////////////
- int intMode = Convert.ToInt32(mode, CultureInfo.InvariantCulture);
- int intAccess = Convert.ToInt32(access, CultureInfo.InvariantCulture);
- int intShare = Convert.ToInt32(share, CultureInfo.InvariantCulture);
- int intStreaming = Convert.ToInt32(streaming, CultureInfo.InvariantCulture);
- for(int i=0; i<_validOpenParameters.GetLength(0); i++)
- {
- if ((_validOpenParameters [i,0] == intMode) &&
- (_validOpenParameters [i,1] == intAccess) &&
- (_validOpenParameters [i,2] == intShare) &&
- (_validOpenParameters [i,3] == intStreaming))
- {
- return;
- }
- }
-
- throw new ArgumentException(SR.Get(SRID.UnsupportedCombinationOfModeAccessShareStreaming));
- }
-
- static private void ValidateModeAccessStreamStreamingCombinations(Stream stream, FileAccess access, bool streaming)
- {
- ////////////
- // let's makes sure that given stream is capable of supporting required functionality
- ////////////
- if ((access== FileAccess.Read || access == FileAccess.ReadWrite) && !stream.CanRead)
- {
- throw new ArgumentException(SR.Get(SRID.CanNotReadDataFromStreamWhichDoesNotSupportReading));
- }
-
- // if user want to be able to write stream needs to support it
- if ((access == FileAccess.Write || access == FileAccess.ReadWrite) && !stream.CanWrite)
- {
- throw new ArgumentException(SR.Get(SRID.CanNotWriteDataToStreamWhichDoesNotSupportWriting));
- }
-
- // if user works in non-streaming mode we need to Seek on underlying stream
- if (! streaming && !stream.CanSeek)
- {
- throw new ArgumentException(SR.Get(SRID.CanNotOperateOnStreamWhichDoesNotSupportSeeking));
- }
- }
-
- static private void ValidateModeAccessShareSupportedEnums(FileMode mode, FileShare share)
- {
- ////////////
- // filter out values that are not supported regardless of other parameters
- // but still validate enum members
- ////////////
- if (mode == FileMode.Append || mode == FileMode.Truncate)
- {
- throw new NotSupportedException(SR.Get(SRID.TruncateAppendModesNotSupported));
- }
- else if (share != FileShare.Read && share != FileShare.None)
- {
- // later as we get to streaming other FileShare values will be supported too
- throw new NotSupportedException (SR.Get(SRID.OnlyFileShareReadAndFileShareNoneSupported));
- }
- }
-
- static private void ValidateModeAccessShareValidEnums(FileMode mode, FileAccess access, FileShare share)
- {
- ////////////
- // filter out values that are out of enum ranges first
- ////////////
- if ((mode != FileMode.Append) && (mode != FileMode.Create) && (mode != FileMode.CreateNew) && (mode != FileMode.Open)
- && (mode != FileMode.OpenOrCreate) && (mode != FileMode.Truncate))
- {
- throw new ArgumentOutOfRangeException("mode");
- }
- else if ((access != FileAccess.Read) && (access != FileAccess.ReadWrite) && (access != FileAccess.Write))
- {
- throw new ArgumentOutOfRangeException("access");
- }
- else if ((share != FileShare.Delete) && (share != FileShare.Inheritable) && (share != FileShare.None) &&
- (share != FileShare.Read) && (share != FileShare.ReadWrite) && (share != FileShare.Write))
- {
- throw new ArgumentOutOfRangeException("share");
- }
- }
-
- ///
- /// Throws exception if object already Disposed/Closed.
- ///
- private void CheckDisposed()
- {
- if (_disposedFlag)
- {
- throw new ObjectDisposedException(null, SR.Get(SRID.ZipArchiveDisposed));
- }
- }
-
- //------------------------------------------------------
- //
- // Private Properties
- //
- //------------------------------------------------------
- ///
- /// This private property is used as a mean to achieve lazy memory allocation for the
- /// hashtable that maintains a cahce of the returned instrances of ZipFileInfo(s).
- /// This hashtable uses file names as keys in the case insensitive and culture invariant fashion
- ///
- private IDictionary ZipFileInfoDictionary
- {
- get
- {
- if (_zipFileInfoDictionary == null)
- {
- // ordinal case sensitive comparison
- _zipFileInfoDictionary = new Hashtable(_zipFileInfoDictionaryInitialSize, StringComparer.Ordinal);
- }
- return _zipFileInfoDictionary;
- }
- }
-
- //------------------------------------------------------
- //
- // Private Fields
- //
- //------------------------------------------------------
-
- // This 2 dimensional table is used by the ValidateModeAccessShareStreaming
- // function as a set of valid parameter combinations
- static private int[,] _validOpenParameters = new int[,]
- { // FileMode // FileAccess / FileShare // streaming
- {(int)FileMode.Create, (int)FileAccess.Write, (int)FileShare.None, 1},
- {(int)FileMode.Create, (int)FileAccess.Write, (int)FileShare.Read, 1},
- {(int)FileMode.Create, (int)FileAccess.ReadWrite, (int)FileShare.None, 0},
- {(int)FileMode.CreateNew, (int)FileAccess.Write, (int)FileShare.None, 1},
- {(int)FileMode.CreateNew, (int)FileAccess.Write, (int)FileShare.Read, 1},
- {(int)FileMode.CreateNew, (int)FileAccess.ReadWrite, (int)FileShare.None, 0},
- {(int)FileMode.Open, (int)FileAccess.Read, (int)FileShare.None, 1},
- {(int)FileMode.Open, (int)FileAccess.Read, (int)FileShare.None, 0},
- {(int)FileMode.Open, (int)FileAccess.Read, (int)FileShare.Read, 1},
- {(int)FileMode.Open, (int)FileAccess.Read, (int)FileShare.Read, 0},
- {(int)FileMode.Open, (int)FileAccess.Read, (int)FileShare.Write, 1},
- {(int)FileMode.Open, (int)FileAccess.Read, (int)FileShare.ReadWrite, 1},
- {(int)FileMode.Open, (int)FileAccess.ReadWrite, (int)FileShare.None, 0},
- {(int)FileMode.OpenOrCreate, (int)FileAccess.ReadWrite, (int)FileShare.None, 0}
- };
-
- // modes that were used for openning (OpenOnStream or OpenOnFile),
- // there is no way to change these values after class is constructed
- private FileMode _openMode;
- private FileAccess _openAccess;
-
- private bool _disposedFlag;
-
- // reference to the ZipIOBlockManager, this reference is instantiated as
- // a part of the OpenOnFile/OpenOnStream contruction
- private ZipIOBlockManager _blockManager;
-
- // this is a Dictionary of all the ZipFileInfos that were given out.
- // It uses file name as key in case insensitive and culture invariant fashion.
- // all members of the class are supposed to use this field indirectly through
- // ZipFileInfoDictionary property, as ZipFileInfoDictionary is respnsible
- // for lazy allocation of the hashtable.
- private IDictionary _zipFileInfoDictionary;
- private const int _zipFileInfoDictionaryInitialSize = 50;
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipFileInfo.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipFileInfo.cs
deleted file mode 100644
index dc815593f07..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipFileInfo.cs
+++ /dev/null
@@ -1,198 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that enables interactions with Zip archives
-// for OPC scenarios
-//
-//
-//
-//
-
-using System;
-using System.IO;
-using System.Diagnostics;
-
-namespace MS.Internal.IO.Zip
-{
- internal sealed class ZipFileInfo
- {
- //------------------------------------------------------
- //
- // Public Members
- //
- //------------------------------------------------------
- // None
-
- //------------------------------------------------------
- //
- // Internal Constructors
- //
- //------------------------------------------------------
- // None
-
- //------------------------------------------------------
- //
- // Internal API Methods (although these methods are marked as
- // Internal they are part of the internal ZIP IO API surface
- //
- //------------------------------------------------------
- internal Stream GetStream(FileMode mode, FileAccess access)
- {
- CheckDisposed();
- return _fileBlock.GetStream(mode, access);
- }
-
- //------------------------------------------------------
- //
- // Internal Properties
- //
- //------------------------------------------------------
- internal string Name
- {
- get
- {
- CheckDisposed();
- return _fileBlock.FileName;
- }
- }
-
- internal ZipArchive ZipArchive
- {
- get
- {
- CheckDisposed();
- return _zipArchive;
- }
- }
-
- internal CompressionMethodEnum CompressionMethod
- {
- get
- {
- CheckDisposed();
- return _fileBlock.CompressionMethod;
- }
- }
-
- internal DateTime LastModFileDateTime
- {
- get
- {
- CheckDisposed();
- return ZipIOBlockManager.FromMsDosDateTime(_fileBlock.LastModFileDateTime);
- }
- }
-
-#if false
- internal bool EncryptedFlag
- {
- get
- {
- CheckDisposed();
- return _fileBlock.EncryptedFlag;
- }
- }
-#endif
-
- internal DeflateOptionEnum DeflateOption
- {
- get
- {
- CheckDisposed();
- return _fileBlock.DeflateOption;
- }
- }
-#if false
- internal bool StreamingCreationFlag
- {
- get
- {
- CheckDisposed();
- return _fileBlock.StreamingCreationFlag;
- }
- }
-#endif
- // This ia Directory flag based on the informtion from the central directory
- // at the moment we have only provide reliable value for the files authored in MS-DOS
- // The upper byte of version made by indicating (OS) must be == 0 (MS-DOS)
- // for the other cases (OSes) we will return false
- internal bool FolderFlag
- {
- get
- {
- CheckDisposed();
- return _fileBlock.FolderFlag;
- }
- }
-
- // This ia Directory flag based on the informtion from the central directory
- // at the moment we have only provide reliable value for the files authored in MS-DOS
- // The upper byte of version made by indicating (OS) must be == 0 (MS-DOS)
- // for the other cases (OSes) we will return false
- internal bool VolumeLabelFlag
- {
- get
- {
- CheckDisposed();
- return _fileBlock.VolumeLabelFlag;
- }
- }
-
- //------------------------------------------------------
- // Internal NON API Constructor (this constructor is marked as internal
- // and isNOT part of the ZIP IO API surface)
- // It supposed to be called only by the ZipArchive class
- //------------------------------------------------------
- internal ZipFileInfo(ZipArchive zipArchive, ZipIOLocalFileBlock fileBlock)
- {
- Debug.Assert((fileBlock != null) && (zipArchive != null));
- _fileBlock = fileBlock;
- _zipArchive = zipArchive;
-#if DEBUG
- // validate that date time is legal
- DateTime dt = LastModFileDateTime;
-#endif
- }
-
- //------------------------------------------------------
- // Internal NON API property to be used to map FileInfo back to a block that needs to be deleted
- // (this prperty is marked as internal and isNOT part of the ZIP IO API surface)
- // It supposed to be called only by the ZipArchive class
- //------------------------------------------------------
- internal ZipIOLocalFileBlock LocalFileBlock
- {
- get
- {
- return _fileBlock;
- }
- }
- //------------------------------------------------------
- //
- // Private Methods
- //
- //------------------------------------------------------
- private void CheckDisposed()
- {
- _fileBlock.CheckDisposed();
- }
-
- //------------------------------------------------------
- //
- // Private Properties
- //
- //------------------------------------------------------
-
- //------------------------------------------------------
- //
- // Private Fields
- //
- //------------------------------------------------------
- private ZipIOLocalFileBlock _fileBlock;
- private ZipArchive _zipArchive;
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipFileInfoCollection.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipFileInfoCollection.cs
deleted file mode 100644
index d1b711b03c6..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipFileInfoCollection.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that enables interactions with Zip archives
-// for OPC scenarios
-//
-//
-//
-//
-
-using System;
-using System.Collections.Generic;
-using System.Collections;
-
-namespace MS.Internal.IO.Zip
-{
- ///
- /// The only reason for existence of this class is to restrict operations that caller of the
- /// ZipArchive.GetFiles is allowed to perform. We want to prevent any modifications to the
- /// actual collection of the FileItems as it is supposed to be a read-only data structure.
- /// Although this is an internal API it seems that the safeguards are warranted.
- ///
- internal class ZipFileInfoCollection : IEnumerable
- {
- //------------------------------------------------------
- //
- // Internal NON API Constructor (this constructor is marked as internal
- // and isNOT part of the ZIP IO API surface
- //
- //------------------------------------------------------
- internal ZipFileInfoCollection(ICollection zipFileInfoCollection)
- {
- _zipFileInfoCollection = zipFileInfoCollection;
- }
-
- //------------------------------------------------------
- //
- // Internal API Methods (although these methods are marked as
- // Internal they are part of the internal ZIP IO API surface
- //
- //------------------------------------------------------
- IEnumerator IEnumerable.GetEnumerator()
- {
- return _zipFileInfoCollection.GetEnumerator();
- }
-
- //------------------------------------------------------
- //
- // Private Fields
- //
- //------------------------------------------------------
- private ICollection _zipFileInfoCollection;
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOBlockManager.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOBlockManager.cs
deleted file mode 100644
index 2ee775f6e69..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOBlockManager.cs
+++ /dev/null
@@ -1,1258 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that enables interactions with Zip archives
-// for OPC scenarios
-//
-//
-//
-//
-//
-
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Text;
-using System.Collections;
-using System.Globalization;
-using System.Runtime.Serialization;
-using System.Windows;
-using MS.Internal.IO.Packaging; // for PackagingUtilities
-using MS.Internal.WindowsBase;
-
-namespace MS.Internal.IO.Zip
-{
- ///
- /// This is the main class of the actual ZIP IO implementation. It is primary responsibility
- /// is to maintain the map and status of the parsed and loaded areas(blocks) of the file.
- /// It is also supports manipulating this map (adding and deleting blocks)
- ///
- internal class ZipIOBlockManager : IDisposable, IEnumerable
- {
- //------------------------------------------------------
- //
- // Public Methods
- //
- //------------------------------------------------------
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- CheckDisposed();
-
- return _blockList.GetEnumerator();
- }
-
- //------------------------------------------------------
- //
- // Internal Properties
- //
- //------------------------------------------------------
- ///
- /// This property returns the status of whether Central directory is loaded or not.
- /// This property is rarely used, as most clients will just ask for CentralDirectoryBlock
- /// and oif it isn't loaded it will be.
- /// The only reason to use IsCentralDirectoryBlockLoaded property is to differentiate
- /// scenarios in which some optimization is possible, if central directory isn't loaded yet.
- ///
- internal bool IsCentralDirectoryBlockLoaded
- {
- get
- {
- CheckDisposed();
- return (_centralDirectoryBlock != null);
- }
- }
-
- ///
- /// This property returns the CentralDirectoryBlock and provides lazy load
- /// fuinctionality. This isthe only way other classes can access information
- /// from the Central Directory Block
- ///
- internal ZipIOCentralDirectoryBlock CentralDirectoryBlock
- {
- get
- {
- CheckDisposed();
- if (_centralDirectoryBlock == null)
- {
- // figure out if we are in ZIP64 mode or not
- if (Zip64EndOfCentralDirectoryBlock.TotalNumberOfEntriesInTheCentralDirectory > 0)
- {
- LoadCentralDirectoryBlock();
- }
- else
- {
- // We need to be aware of the special case of empty Zip Archive
- // with a single record : End Of Central directory
- //In such cases we should create new CentralDirectoryBlock
- CreateCentralDirectoryBlock();
- }
- }
-
- return _centralDirectoryBlock;
- }
- }
-
- ///
- /// This property returns the Zip64EndOfCentralDirectoryBlock and provides lazy load
- /// fuinctionality. This is the only way other classes can access information
- /// from the Zip64EndOfCentralDirectoryBlock
- ///
- internal ZipIOZip64EndOfCentralDirectoryBlock Zip64EndOfCentralDirectoryBlock
- {
- get
- {
- CheckDisposed();
-
- if (_zip64EndOfCentralDirectoryBlock == null)
- {
- CreateLoadZip64Blocks();
- }
-
- return _zip64EndOfCentralDirectoryBlock;
- }
- }
-
- ///
- /// This property returns the Zip64EndOfCentralDirectoryLocatorBlock and provides lazy load
- /// fuinctionality. This is the only way other classes can access information
- /// from the Zip64EndOfCentralDirectoryLocator Block
- ///
- internal ZipIOZip64EndOfCentralDirectoryLocatorBlock Zip64EndOfCentralDirectoryLocatorBlock
- {
- get
- {
- CheckDisposed();
-
- if (_zip64EndOfCentralDirectoryLocatorBlock == null)
- {
- CreateLoadZip64Blocks();
- }
-
- return _zip64EndOfCentralDirectoryLocatorBlock;
- }
- }
-
- ///
- /// This property returns the CentralDirectoryBlock and provides lazy load
- /// fuinctionality. This is the only way other classes can access information
- /// from the Central Directory Block
- ///
- internal ZipIOEndOfCentralDirectoryBlock EndOfCentralDirectoryBlock
- {
- get
- {
- CheckDisposed();
- if (_endOfCentralDirectoryBlock == null)
- {
- LoadEndOfCentralDirectoryBlock();
- }
-
- return _endOfCentralDirectoryBlock;
- }
- }
-
- internal Stream Stream
- {
- get
- {
- CheckDisposed();
- return _archiveStream;
- }
- }
-
- internal bool Streaming
- {
- get
- {
- CheckDisposed();
- return _openStreaming;
- }
- }
-
- internal BinaryReader BinaryReader
- {
- get
- {
- CheckDisposed();
- Debug.Assert(!_openStreaming, "Not legal in Streaming mode");
-
- if (_binaryReader == null)
- {
- _binaryReader = new BinaryReader(Stream, Encoding);
- }
- return _binaryReader;
- }
- }
-
- internal BinaryWriter BinaryWriter
- {
- get
- {
- CheckDisposed();
- if (_binaryWriter == null)
- {
- _binaryWriter = new BinaryWriter(Stream, Encoding);
- }
- return _binaryWriter;
- }
- }
-
- internal Encoding Encoding
- {
- get
- {
- CheckDisposed();
- return _encoding;
- }
- }
-
- internal bool DirtyFlag
- {
- set
- {
- CheckDisposed();
- _dirtyFlag = value;
- }
- get
- {
- CheckDisposed();
- return _dirtyFlag;
- }
- }
-
- static internal int MaxFileNameSize
- {
- get
- {
- return UInt16.MaxValue;
- }
- }
-
- //------------------------------------------------------
- //
- // Internal Methods
- //
- //------------------------------------------------------
-
- internal void CreateEndOfCentralDirectoryBlock()
- {
- CheckDisposed();
-
- // Prevent accidental call if underlying stream is non-empty since
- // any legal zip archive contains an EOCD block.
- Debug.Assert(_openStreaming || _archiveStream.Length == 0);
-
- // Disallow multiple calls.
- Debug.Assert(_endOfCentralDirectoryBlock == null);
-
- // construct Block find it and parse it
- long blockOffset = 0; // this will be updated later
- _endOfCentralDirectoryBlock = ZipIOEndOfCentralDirectoryBlock.CreateNew(this, blockOffset);
-
- // this will add a block to the tail
- AppendBlock(_endOfCentralDirectoryBlock);
- DirtyFlag = true;
- }
-
- internal void LoadEndOfCentralDirectoryBlock()
- {
- Debug.Assert(_endOfCentralDirectoryBlock == null);
- Debug.Assert(!_openStreaming, "Not legal in Streaming mode");
-
- // construct Block find it and parse it
- _endOfCentralDirectoryBlock = ZipIOEndOfCentralDirectoryBlock.SeekableLoad(this);
-
- //ask block manager to MAP this block
- MapBlock(_endOfCentralDirectoryBlock);
- }
-
- internal ZipIOLocalFileBlock CreateLocalFileBlock(string zipFileName, CompressionMethodEnum compressionMethod, DeflateOptionEnum deflateOption)
- {
- CheckDisposed();
-
- // we are guaranteed uniqueness at this point , so let's just add a
- // block at the end of the file, just before the central directory
- // construct Block find it and parse it
-
- // STREAMING Mode:
- // NOTE: _blockList is NOT in offset order except the last four blocks
- // (CD, Zip64 EOCD, Zip64 EOCD Locator, and EOCD)
-
- ZipIOLocalFileBlock localFileBlock = ZipIOLocalFileBlock.CreateNew(this,
- zipFileName,
- compressionMethod,
- deflateOption);
-
- InsertBlock(CentralDirectoryBlockIndex, localFileBlock);
-
- CentralDirectoryBlock.AddFileBlock(localFileBlock);
-
- DirtyFlag = true;
-
- return localFileBlock;
- }
-
- internal ZipIOLocalFileBlock LoadLocalFileBlock(string zipFileName)
- {
- CheckDisposed();
-
- Debug.Assert(!_openStreaming, "Not legal in Streaming mode");
- Debug.Assert(CentralDirectoryBlock.FileExists(zipFileName)); // it must be in the central directory
-
- // construct Block find it and parse it
- ZipIOLocalFileBlock localFileBlock = ZipIOLocalFileBlock.SeekableLoad(this, zipFileName);
-
- MapBlock(localFileBlock);
- return localFileBlock;
- }
-
- internal void RemoveLocalFileBlock(ZipIOLocalFileBlock localFileBlock)
- {
- CheckDisposed();
-
- Debug.Assert(!_openStreaming, "Not legal in Streaming mode");
-
- Debug.Assert(localFileBlock != null, " At this point local File block must be preloaded");
- Debug.Assert(CentralDirectoryBlock.FileExists(localFileBlock.FileName),
- " At this point local File block must be mapped in central directory");
-
-
- // remove it from our list
- _blockList.Remove(localFileBlock);
-
- // remove this from Central Directory
- CentralDirectoryBlock.RemoveFileBlock(localFileBlock.FileName);
- DirtyFlag = true;
-
- // at this point we can Dispose it to make sure that any calls
- // to this file block through outstanding indirect references will result in object Disposed exception
- localFileBlock.Dispose();
- }
-
- internal void MoveData(long moveBlockSourceOffset, long moveBlockTargetOffset, long moveBlockSize)
- {
- Debug.Assert(moveBlockSize >=0);
- Debug.Assert(!_openStreaming, "Not legal in Streaming mode");
-
- if ((moveBlockSize ==0) || (moveBlockSourceOffset == moveBlockTargetOffset))
- {
- //trivial empty move case
- return;
- }
-
- checked
- {
- byte[] tempBuffer = new byte [Math.Min(moveBlockSize,0x100000)]; // min(1mb, requested block size)
- long bytesMoved = 0;
- while(bytesMoved < moveBlockSize)
- {
- long subBlockSourceOffset;
- long subBlockTargetOffset;
- int subBlockSize = (int)Math.Min((long)tempBuffer.Length, moveBlockSize - bytesMoved);
-
- if (moveBlockSourceOffset > moveBlockTargetOffset)
- {
- subBlockSourceOffset = moveBlockSourceOffset + bytesMoved;
- subBlockTargetOffset = moveBlockTargetOffset + bytesMoved;
- }
- else
- {
- subBlockSourceOffset = moveBlockSourceOffset + moveBlockSize - bytesMoved - subBlockSize;
- subBlockTargetOffset = moveBlockTargetOffset + moveBlockSize - bytesMoved - subBlockSize;
- }
-
- _archiveStream.Seek(subBlockSourceOffset, SeekOrigin.Begin);
- int bytesRead = PackagingUtilities.ReliableRead(_archiveStream, tempBuffer, 0, subBlockSize);
-
- if (bytesRead != subBlockSize)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- _archiveStream.Seek(subBlockTargetOffset, SeekOrigin.Begin);
- _archiveStream.Write(tempBuffer, 0, subBlockSize);
-
- checked{bytesMoved += subBlockSize;}
- }
- }
- }
-
- ///
- /// Save - stream level
- ///
- ///
- /// closing or flushing
- internal void SaveStream(ZipIOLocalFileBlock blockRequestingFlush, bool closingFlag)
- {
- // Prevent recursion when propagating Flush or Disposed to our minions
- // because ZipIOFileItemStream.Flush calls us.
- if (_propagatingFlushDisposed)
- return;
- else
- _propagatingFlushDisposed = true; // enter first time
-
- try
- {
- // redirect depending on our mode
- if (_openStreaming)
- {
- StreamingSaveStream(blockRequestingFlush, closingFlag);
- }
- else
- SaveContainer(false);
- }
- finally
- {
- // all done so restore state
- _propagatingFlushDisposed = false;
- }
- }
-
- ///
- /// Save - container level
- ///
- /// true if closing, false if flushing
- internal void Save(bool closingFlag)
- {
- CheckDisposed();
-
- // Prevent recursion when propagating Flush or Disposed to our minions
- // because ZipIOFileItemStream.Flush calls us.
- if (_propagatingFlushDisposed)
- return;
- else
- _propagatingFlushDisposed = true; // enter first time
-
- try
- {
- // redirect depending on our mode
- if (_openStreaming)
- {
- StreamingSaveContainer(closingFlag);
- }
- else
- SaveContainer(closingFlag);
- }
- finally
- {
- // all done so restore state
- _propagatingFlushDisposed = false;
- }
- }
-
- ///
- /// Constructor
- ///
- /// stream we operate on
- ///
- /// true if we own the stream and are expected to close it when we are disposed
- internal ZipIOBlockManager(Stream archiveStream, bool streaming, bool ownStream)
- {
- Debug.Assert(archiveStream != null);
-
- _archiveStream = archiveStream;
- _openStreaming = streaming;
- _ownStream = ownStream;
-
- if (streaming)
- {
- // wrap the archive stream in a WriteTimeStream which keeps track of current position
- _archiveStream = new WriteTimeStream(_archiveStream);
- }
- else if (archiveStream.Length > 0)
- {
- // for non-empty stream we need to map the whole stream into a raw data block
- // which helps keep track of shifts and dirty areas
- ZipIORawDataFileBlock rawBlock = ZipIORawDataFileBlock.Assign(this, 0, archiveStream.Length);
-
- _blockList.Add(rawBlock);
- }
- }
-
- internal static UInt32 ToMsDosDateTime(DateTime dateTime)
- {
- UInt32 result = 0;
-
- result |= (((UInt32)dateTime.Second) /2) & 0x1F; // seconds need to be divided by 2
- // as they stored in 5 bits
- result |= (((UInt32)dateTime.Minute) & 0x3F) << 5;
- result |= (((UInt32)dateTime.Hour) & 0x1F) << 11;
-
- result |= (((UInt32)dateTime.Day) & 0x1F) << 16;
- result |= (((UInt32)dateTime.Month) & 0xF) << 21;
- result |= (((UInt32)(dateTime.Year - 1980)) & 0x7F) << 25;
-
- return result;
- }
-
- internal static DateTime FromMsDosDateTime(UInt32 dosDateTime)
- {
- int seconds = (int)((dosDateTime & 0x1F) << 1); // seconds need to be multiplied by 2
- // as they stored in 5 bits
- int minutes = (int)((dosDateTime >> 5) & 0x3F);
- int hours = (int)((dosDateTime >> 11) & 0x1F);
-
- int day = (int)((dosDateTime >> 16) & 0x1F);
- int month =(int)((dosDateTime >> 21) & 0xF);
- int year = (int)(1980 + ((dosDateTime >> 25) & 0x7F));
-
- //this will throw if parameters are out of range
- return new DateTime(year, month,day,hours,minutes,seconds);
- }
-
- ///
- /// This is standard way to normalize Zip File Item names. At this point we only
- /// getting rid of the spaces. The Exists calls are responsible or making sure
- /// that they check for uniqueness in a case insensitive manner. It is up to the
- /// higher levels to add stricter restrictions like URI character set, and so on.
- ///
- static internal string ValidateNormalizeFileName(string zipFileName)
- {
- // Validate parameteres
- if (zipFileName == null)
- {
- throw new ArgumentNullException("zipFileName");
- }
-
- if (zipFileName.Length > ZipIOBlockManager.MaxFileNameSize)
- {
- throw new ArgumentOutOfRangeException("zipFileName");
- }
-
- zipFileName = zipFileName.Trim();
-
- if (zipFileName.Length < 1)//it must be at least one character
- {
- throw new ArgumentOutOfRangeException("zipFileName");
- }
-
- //Based on the Appnote :
- // << The path stored should not contain a drive or device letter, or a leading slash. >>
-
- return zipFileName;
- }
-
- //------------------------------------------------------
- // Internal helper CopyBytes functions for storing data into a byte[]
- // it is a similar to a BinaryWriter , but not for streams but ratrher
- // for byte[]
- // These functiona used in the Extra field parsing, as that functionality is buit
- // in terms of byte[] not streams
- //------------------------------------------------------
- internal static int CopyBytes(Int16 value, byte[] buffer, int offset)
- {
- Debug.Assert(checked(buffer.Length-offset) >= sizeof(Int16));
-
- byte[] tempBuffer = BitConverter.GetBytes(value);
- Array.Copy(tempBuffer, 0, buffer, offset, tempBuffer.Length);
-
- return offset + tempBuffer.Length;
- }
-
- internal static int CopyBytes(Int32 value, byte[] buffer, int offset)
- {
- Debug.Assert(checked(buffer.Length-offset) >= sizeof(Int32));
-
- byte[] tempBuffer = BitConverter.GetBytes(value);
- Array.Copy(tempBuffer, 0, buffer, offset, tempBuffer.Length);
-
- return offset + tempBuffer.Length;
- }
-
- internal static int CopyBytes(Int64 value, byte[] buffer, int offset)
- {
- Debug.Assert(checked(buffer.Length-offset) >= sizeof(Int64));
-
- byte[] tempBuffer = BitConverter.GetBytes(value);
- Array.Copy(tempBuffer, 0, buffer, offset, tempBuffer.Length);
-
- return offset + tempBuffer.Length;
- }
-
- internal static int CopyBytes(UInt16 value, byte[] buffer, int offset)
- {
- Debug.Assert(checked(buffer.Length-offset) >= sizeof(UInt16));
-
- byte[] tempBuffer = BitConverter.GetBytes(value);
- Array.Copy(tempBuffer, 0, buffer, offset, tempBuffer.Length);
-
- return offset + tempBuffer.Length;
- }
-
- internal static int CopyBytes(UInt32 value, byte[] buffer, int offset)
- {
- Debug.Assert(checked(buffer.Length-offset) >= sizeof(UInt32));
-
- byte[] tempBuffer = BitConverter.GetBytes(value);
- Array.Copy(tempBuffer, 0, buffer, offset, tempBuffer.Length);
-
- return offset + tempBuffer.Length;
- }
-
- internal static int CopyBytes(UInt64 value, byte[] buffer, int offset)
- {
- Debug.Assert(checked(buffer.Length-offset) >= sizeof(UInt64));
-
- byte[] tempBuffer = BitConverter.GetBytes(value);
- Array.Copy(tempBuffer, 0, buffer, offset, tempBuffer.Length);
-
- return offset + tempBuffer.Length;
- }
-
- internal static UInt64 ConvertToUInt64(UInt32 loverAddressValue, UInt32 higherAddressValue)
- {
- return checked((UInt64)loverAddressValue + (((UInt64)higherAddressValue) << 32));
- }
-
- internal static ZipIOVersionNeededToExtract CalcVersionNeededToExtractFromCompression
- (CompressionMethodEnum compression)
- {
- switch (compression)
- {
- case CompressionMethodEnum.Stored:
- return ZipIOVersionNeededToExtract.StoredData;
- case CompressionMethodEnum.Deflated:
- return ZipIOVersionNeededToExtract.DeflatedData;
- default:
- throw new NotSupportedException(); // Deflated64 this is OFF
- }
- }
-
-
- ///
- /// This is the common Pre Save notiofication handler for
- /// RawDataFile Block and File Item Stream
- /// It makes assumption that the overlap generally start coming in at the beginning of a
- /// large disk image, so we should only try to cache cache overlaped data in the prefix
- /// of the disk block
- /// Block can also return a value indicating whether PreSaveNotification should be extended to the blocks that are positioned after
- /// it in the Block List. For example, if block has completely handled PreSaveNotification in a way that it cached the whole area that
- /// was in danger (of being overwritten) it means that no blocks need to worry about this anymore. After all no 2 blocks should have
- /// share on disk buffers. Another scenario is when block can determine that area in danger is positioned before the block's on disk
- /// buffers; this means that all blocks that are positioned later in the block list do not need to worry about this PreSaveNotification
- /// as their buffers should be positioned even further alone in the file.
- ///
- internal static PreSaveNotificationScanControlInstruction CommonPreSaveNotificationHandler(
- Stream stream,
- long offset, long size,
- long onDiskOffset, long onDiskSize,
- ref SparseMemoryStream cachePrefixStream)
- {
- checked
- {
- Debug.Assert(size >=0);
- Debug.Assert(offset >=0);
- Debug.Assert(onDiskSize >=0);
- Debug.Assert(onDiskOffset >=0);
-
- // trivial request
- if (size == 0)
- {
- // The area being overwritten is of size 0 so there is no need to notify any blocks about this.
- return PreSaveNotificationScanControlInstruction.Stop;
- }
-
- if (cachePrefixStream != null)
- {
- // if we have something in cache prefix buffer we only should check whatever tail data isn't cached
- checked{onDiskOffset += cachePrefixStream.Length;}
- checked{onDiskSize -= cachePrefixStream.Length;}
- Debug.Assert(onDiskSize >=0);
- }
-
- if (onDiskSize == 0)
- {
- // the raw data block happened to be fully cached
- // in this case (onDiskSize==0) can not be used as a reliable indicator of the position of the
- // on disk buffer relative to the other; it is just an indicator of an empty buffer which might have a meaningless offset
- // that shouldn't be driving any decisions
- return PreSaveNotificationScanControlInstruction.Continue;
- }
-
- // we need to first find out if the raw data that isn't cached yet overlaps with any disk space
- // that is about to be overriden
- long overlapBlockOffset;
- long overlapBlockSize;
-
- PackagingUtilities.CalculateOverlap(onDiskOffset, onDiskSize,
- offset, size ,
- out overlapBlockOffset, out overlapBlockSize);
- if (overlapBlockSize <= 0)
- {
- // No overlap , we can ignore this message.
- // In addition to that, if (onDiskOffset > offset) it means that, given the fact that all blocks after
- // the current one will have even larger offsets, they couldn't possibly overlap with (offset ,size ) chunk .
- return (onDiskOffset > offset) ?
- PreSaveNotificationScanControlInstruction.Stop :
- PreSaveNotificationScanControlInstruction.Continue;
- }
-
- // at this point we have an overlap, we need to read the data that is overlapped
- // and merge it with whatever we already have in cache
- // let's figure out the part that isn't cached yet, and needs to be
- long blockSizeToCache;
- checked
- {
- blockSizeToCache = overlapBlockOffset + overlapBlockSize - onDiskOffset;
- }
- Debug.Assert(blockSizeToCache >0); // there must be a non empty block at this point that needs to be cached
-
- // We need to ensure that we do have a place to store this data
- if (cachePrefixStream == null)
- {
- cachePrefixStream = new SparseMemoryStream(_lowWaterMark, _highWaterMark);
- }
- else
- {
- // if we already have some cached prefix data we have to make sure we are
- // appending new data tro the tail of the already cached chunk
- cachePrefixStream.Seek(0, SeekOrigin.End);
- }
-
- stream.Seek(onDiskOffset, SeekOrigin.Begin);
- long bytesCopied = PackagingUtilities.CopyStream(stream, cachePrefixStream, blockSizeToCache, 4096);
-
- if (bytesCopied != blockSizeToCache)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- // if the contdition below is true it means that, given the fact that all blocks after
- // the current one will have even larger offsets, they couldn't possibly overlap with (offset ,size ) chunk
- return ((onDiskOffset + onDiskSize) >= (offset + size)) ?
- PreSaveNotificationScanControlInstruction.Stop :
- PreSaveNotificationScanControlInstruction.Continue;
- }
- }
-
- //------------------------------------------------------
- //
- // Protected Methods
- //
- //------------------------------------------------------
- protected void Dispose(bool disposing)
- {
- if (disposing)
- {
- // multiple calls are fine - just ignore them
- if (!_disposedFlag)
- {
- // Prevent recursion into Save() when propagating Flush or Disposed to our minions
- // because ZipIOFileItemStream.Flush calls us.
- if (_propagatingFlushDisposed)
- return;
- else
- _propagatingFlushDisposed = true; // enter first time
-
- try
- {
- try
- {
- if (_blockList != null)
- {
- foreach (IZipIOBlock block in _blockList)
- {
- IDisposable disposableBlock = block as IDisposable;
- if (disposableBlock != null)
- {
- // only some Blocks are disposable, most are not
- disposableBlock.Dispose();
- }
- }
- }
- }
- finally
- {
- // If we own the stream, we should close it.
- // If not, we cannot even close the binary reader or writer as these close the
- // underlying stream on us.
- if (_ownStream)
- {
- if (_binaryReader != null)
- { // this one might be null of we have been only writing
- _binaryReader.Close();
- }
-
- if (_binaryWriter != null)
- { // this one might be null of we have been only reading
- _binaryWriter.Close();
- }
-
- if (_archiveStream != null)
- {
- _archiveStream.Close();
- }
- }
- }
- }
- finally
- {
- _blockList = null;
- _encoding = null;
- _endOfCentralDirectoryBlock = null;
- _centralDirectoryBlock = null;
-
- _disposedFlag = true;
- _propagatingFlushDisposed = false; // reset
- }
- }
- }
- }
-
- //------------------------------------------------------
- //
- // Private Properties
- //
- //------------------------------------------------------
- ///
- /// This property returns the index of CentralDirectoryBlock within _blockList
- ///
- private int CentralDirectoryBlockIndex
- {
- get
- {
- Invariant.Assert(_blockList.Count >= _requiredBlockCount);
- Debug.Assert(_centralDirectoryBlock != null
- && _endOfCentralDirectoryBlock != null
- && _zip64EndOfCentralDirectoryBlock != null
- && _zip64EndOfCentralDirectoryLocatorBlock != null);
-
- // We always have following blocks at the end of the block lists:
- // CD, Zip64 EOCD, Zip64 EOCD Locator, and EOCD
- // Thus the index of CD can be calculated from the total number of blocks
- // and _requiredBlockCount which is 4
- return _blockList.Count - _requiredBlockCount;
- }
- }
-
-
- //------------------------------------------------------
- //
- // Private Methods
- //
- //------------------------------------------------------
- ///
- /// Throwes exception if object already Disposed/Closed.
- ///
- private void CheckDisposed()
- {
- if (_disposedFlag)
- {
- throw new ObjectDisposedException(null, SR.Get(SRID.ZipArchiveDisposed));
- }
- }
-
- ///
- /// Save - container level
- ///
- /// true if closing, false if flushing
- private void SaveContainer(bool closingFlag)
- {
- CheckDisposed();
- Debug.Assert(!_openStreaming, "Not legal in Streaming mode");
-
-
- if (!closingFlag && !DirtyFlag)
- {
- // we are trying to save some cycles in the case of the subsequent Flush calls
- // that do not close the container
- // if it is being closed DirtyFlag isn't reliable as the Compressed streams carry
- // some extra bytes after flushing and only write them out on closing.
- return;
- }
-
- // We need a separate cycle to update all the cross block references prior to saving blocks
- // specifically the central directory needs "dirty" information from blocks in order to properly
- // update it's references, otherwise (if we call UpdateReferences and Save in the same loop)
- // information about block shifts will be lost by the time we ask central directory to update it's
- // references
-
- // offset of the first block
- long currentOffset = 0; // ZIP64 review type here
- foreach (IZipIOBlock currentBlock in _blockList)
- {
- // move block so it is positioned right after the previous block
- currentBlock.Move(currentOffset - currentBlock.Offset);
-
- // this will update references and as well as other internal structures (size)
- // specifically for the FileItemBlock it will flush buffers of
- // all the outstanding streams
- currentBlock.UpdateReferences(closingFlag);
-
- //advance current stream position according to the size of the block
- checked{currentOffset += currentBlock.Size;}
- }
-
- // save dirty blocks
- bool dirtyBlockFound = false;
-
- int blockListCount = _blockList.Count;
- for (int i = 0; i < blockListCount ; i++)
- {
- IZipIOBlock currentBlock = (IZipIOBlock)_blockList[i];
-
- if (currentBlock.GetDirtyFlag(closingFlag))
- {
- dirtyBlockFound = true;
-
- long currentBlockOffset = currentBlock.Offset;
- long currentBlockSize = currentBlock.Size;
-
- if (currentBlockSize > 0)
- {
- // before saving we need to warn all the blocks that have still some data on disk
- // that might be overriden
- // second loop must start at the current position of the extrrnal loop
- // as all the items before have been saved
- for (int j = i + 1; j < blockListCount; j++)
- {
- // This is an optimization which enabled us to stop going through the
- // tail blocks as soon as we find a block that returns a status indicating
- // that it took care of the tail of the target area or is positioned after the
- // target area.
- if (((IZipIOBlock)_blockList[j]).PreSaveNotification(currentBlockOffset, currentBlockSize) ==
- PreSaveNotificationScanControlInstruction.Stop )
- {
- break;
- }
- }
- }
-
- currentBlock.Save(); // Even if currentBlockSize == 0, call Save to clear DirtyFlag
- }
- }
-
- // originally we have had an assert for the case when no changes were made to the file
- // but calculated size didn't match the actual stream size.
- // As a result of the XPS Viewer dynamically switching streams underneath ZIP IO, we
- // need to treat this case as a normal non-dirty scenario. So if nothing changed and
- // nothing was written out we shouldn't even validate whether stream underneath
- // was modified in any way or not (even such simple modifications as an unexpected
- // Stream.Length change). If it was modified by someone we assume that the stream
- // owner was aware of it's action.
- if (dirtyBlockFound && (Stream.Length > currentOffset))
- {
- Stream.SetLength(currentOffset);
- }
-
- Stream.Flush();
- DirtyFlag = false;
- }
-
- ///
- /// Streaming version of Save routine
- ///
- /// true if closing the package
- private void StreamingSaveContainer(bool closingFlag)
- {
- // STREAMING Mode:
- // NOTE: _blockList is NOT in offset order except the last four blocks
- // (CD, Zip64 EOCD, Zip64 EOCD Locator, and EOCD)
-
- try
- {
- // save dirty blocks
- long currentOffset = 0;
- for (int i = 0; i < _blockList.Count; i++)
- {
- IZipIOBlock currentBlock = (IZipIOBlock)_blockList[i];
- ZipIOLocalFileBlock localFileBlock = currentBlock as ZipIOLocalFileBlock;
-
- if (localFileBlock == null)
- {
- if (closingFlag)
- {
- // Move block so it is positioned right after the previous block.
- // No need for nested loops like in SaveContainer because none of these
- // calls can cause a block to move in the Streaming case.
- currentBlock.Move(currentOffset - currentBlock.Offset);
- currentBlock.UpdateReferences(closingFlag);
- if (currentBlock.GetDirtyFlag(closingFlag))
- {
- currentBlock.Save();
- }
- }
- }
- else if (currentBlock.GetDirtyFlag(closingFlag))
- {
- // no need to call UpdateReferences in streaming mode for regular
- // local file blocks because
- // we manually emit the local file header and the local file descriptor
- localFileBlock.SaveStreaming(closingFlag);
- }
- checked{currentOffset += currentBlock.Size;}
- }
-
- Stream.Flush();
- }
- finally
- {
- // all done so restore state
- _propagatingFlushDisposed = false;
- }
- }
-
- ///
- /// Flush was called on a ZipIOFileItemStream
- ///
- /// block that owns the stream that Flush was called on
- /// close or dispose
- private void StreamingSaveStream(ZipIOLocalFileBlock blockRequestingFlush, bool closingFlag)
- {
- // STREAMING MODE:
- // Flush will do one of two things, depending on the currently open stream:
- // 1) If the currently open stream matches the one passed (or none is currently opened)
- // then write will occur to the open stream.
- // 2) Otherwise, the currently opened stream will be flushed and closed, and the
- // given stream will become the currently opened stream
- // NOTE: _blockList is NOT in offset order except the last four blocks
- // (CD, Zip64 EOCD, Zip64 EOCD Locator, and EOCD)
-
- // different stream?
- if (_streamingCurrentlyOpenStreamBlock != blockRequestingFlush)
- {
- // need to close the currently opened stream
- // unless its our first time through
- if (_streamingCurrentlyOpenStreamBlock != null)
- {
- _streamingCurrentlyOpenStreamBlock.SaveStreaming(true);
- }
-
- // Now make the given stream the new "currently opened stream".
- _streamingCurrentlyOpenStreamBlock = blockRequestingFlush;
- }
-
- // this should now be flushable/closable
- _streamingCurrentlyOpenStreamBlock.SaveStreaming(closingFlag);
-
- // if closing - discard the stream because it is now closed
- if (closingFlag)
- _streamingCurrentlyOpenStreamBlock = null;
- }
-
- private void CreateCentralDirectoryBlock()
- {
- CheckDisposed();
- Debug.Assert(_zip64EndOfCentralDirectoryBlock != null);
-
- // It must not be loaded yet
- Debug.Assert(!IsCentralDirectoryBlockLoaded);
-
- // The proper position is just before the Zip64EndOfCentralDirectoryRecord
- // Zip64EndOfCentralDirectoryRecord - might be of size 0 (if file is small enough)
- int blockPosition = _blockList.IndexOf(Zip64EndOfCentralDirectoryBlock);
- Debug.Assert(blockPosition >= 0);
-
- // construct Block find it and parse it
- _centralDirectoryBlock = ZipIOCentralDirectoryBlock.CreateNew(this);
-
- //ask block manager to insert this this block
- InsertBlock(blockPosition , _centralDirectoryBlock);
- }
-
- private void LoadCentralDirectoryBlock()
- {
- Debug.Assert(_centralDirectoryBlock == null);
- Debug.Assert(!_openStreaming, "Not legal in Streaming mode");
-
- // construct Block find it and parse it
- _centralDirectoryBlock = ZipIOCentralDirectoryBlock.SeekableLoad(this);
-
- //ask block manager to MAP this block
- MapBlock(_centralDirectoryBlock);
- }
-
- private void CreateLoadZip64Blocks()
- {
- CheckDisposed();
-
- Debug.Assert ((_zip64EndOfCentralDirectoryBlock == null) &&
- (_zip64EndOfCentralDirectoryLocatorBlock == null));
-
- // determine whether we want to create it or load it
- // this check doesn't provide us with a 100% guarantee.
- // After discussion we have agreed that this should be sufficient
- if (!Streaming && EndOfCentralDirectoryBlock.ContainValuesHintingToPossibilityOfZip64 &&
- ZipIOZip64EndOfCentralDirectoryLocatorBlock.SniffTheBlockSignature(this))
- {
- // attempt to sniff the header of the
- LoadZip64EndOfCentralDirectoryLocatorBlock();
- LoadZip64EndOfCentralDirectoryBlock();
- }
- else
- {
- // We delayed validation of some values in End of Central Directory that can give possible
- // hints for Zip64; Since there is no Zip64 structure, we need to validate them here
- _endOfCentralDirectoryBlock.ValidateZip64TriggerValues();
-
- CreateZip64EndOfCentralDirectoryLocatorBlock();
- CreateZip64EndOfCentralDirectoryBlock();
- }
- }
-
- private void CreateZip64EndOfCentralDirectoryBlock()
- {
- Debug.Assert(_zip64EndOfCentralDirectoryBlock == null);
-
- // The proper position is just before the Zip64EndOfCentralDirectoryRecordLocator
- // Zip64EndOfCentralDirectoryRecord - might be of size 0 (if file is small enough)
- int blockPosition = _blockList.IndexOf(Zip64EndOfCentralDirectoryLocatorBlock);
-
- // construct Block find it and parse it
- _zip64EndOfCentralDirectoryBlock = ZipIOZip64EndOfCentralDirectoryBlock.CreateNew(this);
-
- //ask block manager to insert this this block
- InsertBlock(blockPosition, _zip64EndOfCentralDirectoryBlock);
- }
-
- private void LoadZip64EndOfCentralDirectoryBlock()
- {
- Debug.Assert(_zip64EndOfCentralDirectoryBlock == null);
- Debug.Assert(!_openStreaming, "Not legal in Streaming mode");
-
- // construct Block find it and parse it
- _zip64EndOfCentralDirectoryBlock = ZipIOZip64EndOfCentralDirectoryBlock.SeekableLoad(this);
-
- //ask block manager to insert this this block
- MapBlock(_zip64EndOfCentralDirectoryBlock);
- }
-
- private void CreateZip64EndOfCentralDirectoryLocatorBlock()
- {
- Debug.Assert(_zip64EndOfCentralDirectoryLocatorBlock == null);
-
- // The proper position is just before the EOCD
- int blockPosition = _blockList.IndexOf(EndOfCentralDirectoryBlock);
-
- // construct Block find it and parse it
- _zip64EndOfCentralDirectoryLocatorBlock = ZipIOZip64EndOfCentralDirectoryLocatorBlock.CreateNew(this);
-
- //ask block manager to MAP this block
- InsertBlock(blockPosition, _zip64EndOfCentralDirectoryLocatorBlock);
- }
-
- private void LoadZip64EndOfCentralDirectoryLocatorBlock()
- {
- Debug.Assert(_zip64EndOfCentralDirectoryLocatorBlock == null);
- Debug.Assert(!_openStreaming, "Not legal in Streaming mode");
-
- // construct Block find it and parse it
- _zip64EndOfCentralDirectoryLocatorBlock = ZipIOZip64EndOfCentralDirectoryLocatorBlock.SeekableLoad(this);
-
- //ask block manager to MAP this block
- MapBlock(_zip64EndOfCentralDirectoryLocatorBlock);
- }
-
- private void MapBlock(IZipIOBlock block)
- {
- // as we map a block to existing file space it must be not dirty.
- Debug.Assert(!block.GetDirtyFlag(true)); // closingFlag==true used as a more conservative option
- Debug.Assert(!_openStreaming, "Not legal in Streaming mode");
-
- for (int blockIndex = _blockList.Count - 1; blockIndex >= 0; --blockIndex)
- {
- // if we need to find a RawDataBlock that maps to the target area
- ZipIORawDataFileBlock rawBlock = _blockList[blockIndex] as ZipIORawDataFileBlock;
-
- //check the original loaded RawBlock size / offset against the new block
- if ((rawBlock != null) && rawBlock.DiskImageContains(block))
- {
- ZipIORawDataFileBlock prefixBlock, suffixBlock;
-
- //split raw block into prefixRawBlock, SuffixRawBlock
- rawBlock.SplitIntoPrefixSuffix(block, out prefixBlock, out suffixBlock);
-
- _blockList.RemoveAt(blockIndex); // remove the old big raw data block
-
- // add suffix Raw data block
- if (suffixBlock != null)
- {
- _blockList.Insert(blockIndex, suffixBlock);
- }
-
- // add new mapped block
- _blockList.Insert(blockIndex, block);
-
- // add prefix Raw data block
- if (prefixBlock != null)
- {
- _blockList.Insert(blockIndex, prefixBlock);
- }
-
- return;
- }
- }
-
- // we couldn't find a raw data block for mapping this, we can only throw
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- private void InsertBlock(int blockPosition, IZipIOBlock block)
- {
- // as we are adding a new block it must be dirty unless its size is 0
- Debug.Assert(block.GetDirtyFlag(true) || // closingFlag==true used as a more conservative option
- block.Size == 0);
-
- _blockList.Insert(blockPosition, block);
- }
-
- private void AppendBlock(IZipIOBlock block)
- {
- // as we are adding a new block it must be dirty unless its size is 0
- Debug.Assert(block.GetDirtyFlag(true) || // closingFlag==true used as a more conservative option
- block.Size == 0);
-
- // CentralDirectory persistence logic relies on the fact that we always add headers in a fashion that
- // matches the order of the corresponding file items in the physical archive (currently to the end of the list).
- // If this invariant is violated, the corresponding central directory persistence logic must be updated.
- _blockList.Add(block);
- }
-
- // this flag is used for Perf reasons, it doesn't carry any additional information that isn't stored somewhere
- // else. In order to prevent complex dirty calculations on the sequential flush calls, we are going to keep
- // this flag which will be set to true at the end of the flush (or close). This flag will be set from the ZipArchive
- // and CrcCalculating entry points that can potentially make our structure dirty.
- // This flag is only used for non-streaming cases. In streaming cases we do not believe there is a perf
- // penalty of that nature.
- private bool _dirtyFlag = false;
-
- private bool _disposedFlag;
- private bool _propagatingFlushDisposed; // if true, we ignore calls back to Save to prevent recursion
- private Stream _archiveStream;
- private bool _openStreaming;
- private bool _ownStream; // true if we own the archive stream
-
- // Streaming Mode Only: stream that is currently able to write without interfering with other streams
- private ZipIOLocalFileBlock _streamingCurrentlyOpenStreamBlock;
-
- private BinaryReader _binaryReader;
- private BinaryWriter _binaryWriter;
-
- private const int _initialBlockListSize = 50;
- private ArrayList _blockList = new ArrayList(_initialBlockListSize);
-
- private ASCIIEncoding _encoding = new ASCIIEncoding();
-
- ZipIOZip64EndOfCentralDirectoryBlock _zip64EndOfCentralDirectoryBlock;
- ZipIOZip64EndOfCentralDirectoryLocatorBlock _zip64EndOfCentralDirectoryLocatorBlock;
- ZipIOEndOfCentralDirectoryBlock _endOfCentralDirectoryBlock;
- ZipIOCentralDirectoryBlock _centralDirectoryBlock;
-
- private const long _lowWaterMark = 0x19000; // we definately would like to keep everythuing under 100 KB in memory
- private const long _highWaterMark = 0xA00000; // we would like to keep everything over 10 MB on disk
- private const int _requiredBlockCount = 4; // We always have following blocks: CD, Zip64 EOCD, Zip64 EOCD Locator, and EOCD
- // This value is used to calculate the index of CD within _blockList
- }
-}
-
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOCentralDirectoryBlock.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOCentralDirectoryBlock.cs
deleted file mode 100644
index 291ae7d4b34..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOCentralDirectoryBlock.cs
+++ /dev/null
@@ -1,559 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that enables interactions with Zip archives
-// for OPC scenarios
-//
-//
-//
-//
-
-using System;
-using System.IO;
-using System.Diagnostics;
-using System.Text;
-using System.Collections;
-using System.Collections.Specialized; // OrderedDictionary
-using System.Globalization;
-using System.Windows;
-using MS.Internal.WindowsBase;
-
-namespace MS.Internal.IO.Zip
-{
- internal class ZipIOCentralDirectoryBlock : IZipIOBlock
- {
- //------------------------------------------------------
- //
- // Public Properties
- //
- //------------------------------------------------------
- // standard IZipIOBlock functionality
- public long Offset
- {
- get
- {
- return _offset;
- }
- }
-
- public long Size
- {
- get
- {
- long result = 0;
- if (CentralDirectoryDictionary.Count > 0)
- {
- foreach(ZipIOCentralDirectoryFileHeader fileHeader in CentralDirectoryDictionary.Values)
- {
- checked{result += fileHeader.Size;}
- }
-
-// disable creation/parsing of zip archive digital signatures
-#if ArchiveSignaturesEnabled
- if (_centralDirectoryDigitalSignature != null)
- {
- checked{result += _centralDirectoryDigitalSignature.Size;}
- }
-#endif
- }
- return result;
- }
- }
-
- // This property will only return reliable result if Update is called prior
- public bool GetDirtyFlag(bool closingFlag)
- {
- return _dirtyFlag;
- }
-
- //------------------------------------------------------
- //
- // Public Methods
- //
- //------------------------------------------------------
- public void Move(long shiftSize)
- {
- if (shiftSize != 0)
- {
- checked{_offset +=shiftSize;}
- _dirtyFlag = true;
- Debug.Assert(_offset >=0);
- }
- }
-
- public void Save()
- {
- if (_dirtyFlag)
- {
- // Central directory is an optional component of the ZIP Archive
- // we need to save it if it isn't empty
- if (CentralDirectoryDictionary.Count > 0)
- {
- BinaryWriter writer = _blockManager.BinaryWriter;
-
- // Emit entries in the same order as the corresponding file items as this
- // improves interoperability with tools that expect this convention.
-
- // Streaming mode must be handled differently
- if (_blockManager.Streaming)
- {
- // In Streaming mode we cannot rely on the order that entries were inserted via AddFiles()
- // as files can be closed in different order than they are added.
-
- // NOTE: Neither ZipIOBlockManager._blockList nor CentralDirectoryDicstionry
- // are NOT in offset order
-
-#if DEBUG
- long lastOffset = -1;
-#endif
-
- // collect all file headers in central directory into a local list for sorting
- SortedList blockList = new SortedList(CentralDirectoryDictionary.Count);
-
- // We know that in Streaming mode there can be no RawDataFile blocks in
- // the block list. Therefore, we can emit our headers in the order that they
- // appear in the block list.
- foreach (ZipIOCentralDirectoryFileHeader header in CentralDirectoryDictionary.Values)
- {
- blockList.Add(header.OffsetOfLocalHeader, header);
- }
-
- // then write out the files headers for central directory in sorted order
- foreach (ZipIOCentralDirectoryFileHeader header in blockList.Values)
- {
- header.Save(writer);
-#if DEBUG
- Debug.Assert(lastOffset < header.OffsetOfLocalHeader, "Sort order violated");
- lastOffset = header.OffsetOfLocalHeader;
-#endif
- }
- }
- else
- {
- // Non-streaming mode - CentralDirectoryDictionary has correct order.
- // Assume correct location if streaming - otherwise explicitly seek.
- if (_blockManager.Stream.Position != _offset)
- {
- // we need to seek
- _blockManager.Stream.Seek(_offset, SeekOrigin.Begin);
- }
-
- // Save the headers in the order they were added as this matches the physical offsets
- foreach (ZipIOCentralDirectoryFileHeader fileHeader in CentralDirectoryDictionary.Values)
- {
- fileHeader.Save(writer);
- }
-}
-
- // disable creation/parsing of zip archive digital signatures
-#if ArchiveSignaturesEnabled
- //central directory dig sig is optional
- if (_centralDirectoryDigitalSignature != null)
- {
- _centralDirectoryDigitalSignature.Save(writer);
- }
-#endif
- writer.Flush();
- }
-
- _dirtyFlag = false;
- }
- }
-
- public void UpdateReferences(bool closingFlag)
- {
- // we just need to ask Block Manager for the new Values for each header
- // there are 2 distinct cases here
- // 1. local file data is mapped . loaded and might have been changed in size and position
- // 2. local file data is not loaded and might have been changed only in position (not in size)
-
- foreach(IZipIOBlock block in _blockManager)
- {
- ZipIOLocalFileBlock localFileBlock = block as ZipIOLocalFileBlock;
- ZipIORawDataFileBlock rawDataFileBlock = block as ZipIORawDataFileBlock;
-
- if (localFileBlock != null)
- {
- // this is case 1 data is mapped and loaded, so we only need to find the matching
- // Centraldirectory record and update it
- Debug.Assert(CentralDirectoryDictionary.Contains(localFileBlock.FileName));
-
- ZipIOCentralDirectoryFileHeader centralDirFileHeader =
- (ZipIOCentralDirectoryFileHeader)CentralDirectoryDictionary[localFileBlock.FileName];
-
- if (centralDirFileHeader.UpdateIfNeeded(localFileBlock))
- {
- //update was required let's mark ourselves as dirty
- _dirtyFlag = true;
- }
- }
- //check whether we deal with raw data block and it was moved
- else if (rawDataFileBlock != null)
- {
- long diskImageShift = rawDataFileBlock.DiskImageShift;
- if (diskImageShift != 0)
- {
- //this is case #2 data isn't loaded based on the shift in the RawData Block
- // we need to move all overlapping central directory references
- foreach (ZipIOCentralDirectoryFileHeader centralDirFileHeader in CentralDirectoryDictionary.Values)
- {
- // check whether central dir header points into the region of a moved RawDataBlock
- if (rawDataFileBlock.DiskImageContains(centralDirFileHeader.OffsetOfLocalHeader))
- {
- centralDirFileHeader.MoveReference(diskImageShift);
- _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 Central directory without any additional backups
-
- // we can also safely state that there is no need to continue the PreSafeNotification loop
- // as all the blocks after the central directory (EOCD, Zip64 ....) do not have
- // data that is buffered on disk
- return PreSaveNotificationScanControlInstruction.Stop;
- }
-
- //------------------------------------------------------
- //
- // Internal Properties
- //
- //------------------------------------------------------
- // although Zip 64 supports 64 bit counter for the number of
- // entries in the central directory, we have chossen to not
- // support those scenarios and stick wit the basic CLR type
- // int Collections.Count {get;}
- internal int Count
- {
- get
- {
- return CentralDirectoryDictionary.Count;
- }
- }
-
- //------------------------------------------------------
- //
- // Internal Methods
- //
- //------------------------------------------------------
- internal static ZipIOCentralDirectoryBlock SeekableLoad(ZipIOBlockManager blockManager)
- {
- // get proper values from zip 64 records request will be redirected to the
- // regular EOCD if ZIP 64 record wasn't originated from the parsing
-
- ZipIOZip64EndOfCentralDirectoryBlock zip64EOCD = blockManager.Zip64EndOfCentralDirectoryBlock;
-
- blockManager.Stream.Seek(zip64EOCD.OffsetOfStartOfCentralDirectory, SeekOrigin.Begin);
-
- ZipIOCentralDirectoryBlock block = new ZipIOCentralDirectoryBlock(blockManager);
-
- block.ParseRecord(blockManager.BinaryReader,
- zip64EOCD.OffsetOfStartOfCentralDirectory,
- zip64EOCD.TotalNumberOfEntriesInTheCentralDirectory,
- zip64EOCD.SizeOfCentralDirectory);
-
- return block;
- }
-
- internal static ZipIOCentralDirectoryBlock CreateNew(ZipIOBlockManager blockManager)
- {
- ZipIOCentralDirectoryBlock block = new ZipIOCentralDirectoryBlock(blockManager);
-
- block._offset = 0; // it just an initial value, that will be adjusted later
- // it doesn't matter whether this offset overlaps anything or not
-
- block._dirtyFlag = true;
-
- // this dig sig is optional if we ever wanted to make this record, we would need to call
- // ZipIOCentralDirectoryDigitalSignature.CreateNew();
- block._centralDirectoryDigitalSignature = null;
-
- return block;
- }
-
- // This properrty returns current snapsot which might be out of date
- // if there were changes after parsing or last UpdateReferences call
- internal bool IsZip64BitRequiredForStoring
- {
- get
- {
- // These values are duplicated the EndOfCentralDirectory record
- // and if any of them are to big we need to introduce
- // Zip64 end of central directory record
- // Zip64 end of central directory locator
- return (Count >= UInt16.MaxValue) ||
- (Offset >= UInt32.MaxValue) ||
- (Size >= UInt32.MaxValue);
- }
- }
-
- internal void AddFileBlock(ZipIOLocalFileBlock fileBlock)
- {
- _dirtyFlag = true;
-
- ZipIOCentralDirectoryFileHeader fileHeader =
- ZipIOCentralDirectoryFileHeader.CreateNew
- (_blockManager.Encoding, fileBlock);
-
- CentralDirectoryDictionary.Add(fileHeader.FileName, fileHeader);
- }
-
- ///
- ///
- ///
- ///
- /// precondition: caller must ensure that fileName exists
- internal void RemoveFileBlock(string fileName)
- {
- _dirtyFlag = true;
-
- CentralDirectoryDictionary.Remove(fileName);
-
- if (CentralDirectoryDictionary.Count == 0)
- {
- // in case of the the last one ,we also need to drop the signature record
- _centralDirectoryDigitalSignature = null;
- }
- }
-
- internal bool FileExists(string fileName)
- {
- return CentralDirectoryDictionary.Contains(fileName);
- }
-
- // this function should be used carefully as it returns reference to an object
- // that is owned by CentralDirectoryBlock, and should be used by other classes only
- // for querying information not for updating it.
- internal ZipIOCentralDirectoryFileHeader GetCentralDirectoryFileHeader (string fileName)
- {
- return ((ZipIOCentralDirectoryFileHeader)CentralDirectoryDictionary[fileName]);
- }
-
- internal ICollection GetFileNamesCollection()
- {
- return CentralDirectoryDictionary.Keys;
- }
-
- //------------------------------------------------------
- //
- // Private Methods
- //
- //------------------------------------------------------
- private ZipIOCentralDirectoryBlock(ZipIOBlockManager blockManager)
- {
- _blockManager = blockManager;
- }
-
- ///
- /// Compare FileOffsets for LocalFileHeaders - used by Sort() routine in ParseRecord
- ///
- private class HeaderFileOffsetComparer : IComparer
- {
- int IComparer.Compare(object o1, object o2)
- {
- ZipIOCentralDirectoryFileHeader h1 = o1 as ZipIOCentralDirectoryFileHeader;
- ZipIOCentralDirectoryFileHeader h2 = o2 as ZipIOCentralDirectoryFileHeader;
- Debug.Assert(h1 != null && h2 != null, "HeaderFileOffsetComparer: Comparing the wrong data types");
-
- // avoid boxing - don't cast long value to (IComparable)
- if (h1.OffsetOfLocalHeader > h2.OffsetOfLocalHeader)
- return 1;
- else if (h1.OffsetOfLocalHeader < h2.OffsetOfLocalHeader)
- return -1;
- else
- return 0;
- }
- }
-
- private void ParseRecord (BinaryReader reader,
- long centralDirectoryOffset,
- int centralDirectoryCount,
- long expectedCentralDirectorySize)
- {
- if (centralDirectoryCount > 0)
- {
- // collect all headers into a local array list for sorting
- SortedList headerList = new SortedList(centralDirectoryCount);
- ZipIOCentralDirectoryFileHeader header;
- for (int i = 0; i < centralDirectoryCount; i++)
- {
- header = ZipIOCentralDirectoryFileHeader.ParseRecord(reader, _blockManager.Encoding);
- headerList.Add(header.OffsetOfLocalHeader, header);
- }
-
- if (reader.BaseStream.Position - centralDirectoryOffset > expectedCentralDirectorySize)
- { // it looks like a corrupted file, as we have parsed more than central directory supposed to contain
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- // then add to the ordered dictionary in sorted order
- foreach (ZipIOCentralDirectoryFileHeader fileHeader in headerList.Values)
- {
- // at this point fileHeader.FileName is normalized using
- // the ZipIOBlockManager.ValidateNormalizeFileName
- CentralDirectoryDictionary.Add(fileHeader.FileName, fileHeader);
- }
-
- //load central directory [digital signature] - this has nothing to
- // do with OPC digital signing
- // this record is optional, and the function might return null
- _centralDirectoryDigitalSignature = ZipIOCentralDirectoryDigitalSignature.ParseRecord(reader);
- }
-
- _offset = centralDirectoryOffset;
- _dirtyFlag = false;
-
- Validate(expectedCentralDirectorySize);
- }
-
- private void Validate(long expectedCentralDirectorySize)
- {
- checked
- {
- // We only have information about the Compressed data size and the offset of the
- // local headers. We do not have information about the size of the local header
- // which varies depending on the file name and the extra field records size.
- // (Although we do know the expected size of the file name, there is no way to
- // predict the extra field size, for example it might have a padding record that we use
- // optimize Disk IO for ZIP 64 scenarios).
- // We are going to make sure that Blocks do not overlap each other and do not
- // overlap Central Directory
-
- long checkedMark = 0;
-
- foreach (ZipIOCentralDirectoryFileHeader fileHeader in CentralDirectoryDictionary.Values)
- {
- if ((checkedMark == 0) && (fileHeader.OffsetOfLocalHeader != 0))
- {
- // first block doesn't start at 0
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
- else if (fileHeader.OffsetOfLocalHeader < checkedMark)
- {
- // the current block overlaps the previously analyzed block
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- // we move the checked mark up by the sum of the compressed size file name size
- // and the fixed minimal Local file header size
- checkedMark += fileHeader.CompressedSize +
- ZipIOLocalFileHeader.FixedMinimalRecordSize +
- fileHeader.FileName.Length;
- }
-
- // now we can ensure that that checked mark didn't reach over the start of the Central directory
- if (_offset < checkedMark)
- {
- // the central directory block overlaps the last file block
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- //check the total parsed size of the central directory against value declared in EOCd or ZIP64 EOCD records
- if (Size != expectedCentralDirectorySize)
- {
- // the central directory block overlaps the last file block
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- // we should also check ofr presence of gaps between
- // Central Directory
- // ZIP64 EOCD
- // ZIP 64 EOCD locator
- // EOCD
- // Zip64Eocd and Zip64EocdLocator must be either present or absent together
- Debug.Assert(! (_blockManager.Zip64EndOfCentralDirectoryBlock.Size==0)
- ^
- (_blockManager.Zip64EndOfCentralDirectoryLocatorBlock.Size==0));
-
- if (_blockManager.Zip64EndOfCentralDirectoryBlock.Size==0)
- {
- // no ZIP 64 record
- if (_offset + expectedCentralDirectorySize != _blockManager.EndOfCentralDirectoryBlock.Offset)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
- }
- else
- {
- // ZIP 64 records present
- if ((_offset + expectedCentralDirectorySize
- != _blockManager.Zip64EndOfCentralDirectoryBlock.Offset) ||
-
- (_blockManager.Zip64EndOfCentralDirectoryBlock.Offset + _blockManager.Zip64EndOfCentralDirectoryBlock.Size
- != _blockManager.Zip64EndOfCentralDirectoryLocatorBlock.Offset) ||
-
- (_blockManager.Zip64EndOfCentralDirectoryLocatorBlock.Offset + _blockManager.Zip64EndOfCentralDirectoryLocatorBlock.Size
- != _blockManager.EndOfCentralDirectoryBlock.Offset))
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
- }
- }
- }
-
- //------------------------------------------------------
- //
- // Private Properties
- //
- //------------------------------------------------------
- private IDictionary CentralDirectoryDictionary
- {
- get
- {
- if (_centralDirectoryDictionary == null)
- {
- // StringComparer.Ordinal guarantees ordinal, case-sensitive comparison for both cases.
-
- // if streaming - order is unimportant for us and we can use the cheaper Hashtable
- if (_blockManager.Streaming)
- {
- // We take our order during Save() from the physical order of the elements of the
- // block table in BlockManager.
- _centralDirectoryDictionary = new Hashtable(_centralDirectoryDictionaryInitialSize, StringComparer.Ordinal);
- }
- else
- {
- // This ordered dictionary serves two purposes. It allows hash-table lookup by file name
- // and it also maintains the physical order of the blocks on disk. Like any OrderedDictionary,
- // any of the enumerator, or integer indexer will return the items in the order that they were added.
- _centralDirectoryDictionary = new OrderedDictionary(_centralDirectoryDictionaryInitialSize, StringComparer.Ordinal);
- }
- }
- return _centralDirectoryDictionary;
- }
- }
-
- //------------------------------------------------------
- //
- // Private Members
- //
- //------------------------------------------------------
- private const int _centralDirectoryDictionaryInitialSize = 50;
-
- // used in Parse
- private static IComparer _headerOffsetComparer = new HeaderFileOffsetComparer();
-
- // This may be a HashTable (Streaming case) or an OrderedDictionary - see private property
- // for explanation.
- private IDictionary _centralDirectoryDictionary;
-
- private ZipIOCentralDirectoryDigitalSignature _centralDirectoryDigitalSignature;
-
- private ZipIOBlockManager _blockManager;
-
- private long _offset;
- private bool _dirtyFlag;
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOCentralDirectoryDigitalSignature.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOCentralDirectoryDigitalSignature.cs
deleted file mode 100644
index 6e352f4e7be..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOCentralDirectoryDigitalSignature.cs
+++ /dev/null
@@ -1,128 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that enables interactions with Zip archives
-// for OPC scenarios
-//
-// Hisotrical Note:
-// Disable creation of signatures and throw on parse if signature found:
-// If we encounter archive with encrypted and /or signed data we consider those as
-// �invalid OPC packages�. Even in case when client application has never requested
-// read/write operations with the encrypted and/or signed area of the archive. Motivations include:
-// 1. Security based
-// 2. It is inappropriate to silently ignore digital signatures because this may lead to users
-// assuming that the signature has been validated when in fact it has not.
-//
-
-using System;
-using System.IO;
-using System.Diagnostics;
-using System.Collections;
-using System.Runtime.Serialization;
-using System.Windows;
-using MS.Internal.WindowsBase;
-
-namespace MS.Internal.IO.Zip
-{
- internal class ZipIOCentralDirectoryDigitalSignature
- {
-#if false
- internal static ZipIOCentralDirectoryDigitalSignature CreateNew()
- {
- ZipIOCentralDirectoryDigitalSignature record = new ZipIOCentralDirectoryDigitalSignature ();
-
- return record;
- }
-#endif
- internal static ZipIOCentralDirectoryDigitalSignature ParseRecord(BinaryReader reader)
- {
- // this record is optional, so let's check for presence of signature rightaway
-
- //let's ensure we have at least enough data to cover _fixedMinimalRecordSize bytes of signature
- if ((reader.BaseStream.Length - reader.BaseStream.Position) < _fixedMinimalRecordSize)
- {
- return null;
- }
-
- UInt32 signatureValue = reader.ReadUInt32();
- if (signatureValue != _signatureConstant)
- {
- return null;
- }
-
- //at this point we can assume that Digital Signature Record is there
- // Convention is to throw
- throw new NotSupportedException(SR.Get(SRID.ZipNotSupportedSignedArchive));
-
-// disable creation/parsing of zip archive digital signatures
-#if ArchiveSignaturesEnabled
- ZipIOCentralDirectoryDigitalSignature record = new ZipIOCentralDirectoryDigitalSignature ();
-
- record._signature = signatureValue;
- record._sizeOfData = reader.ReadUInt16();
- record._signatureData = reader.ReadBytes(record._sizeOfData );
-
- record.Validate();
-
- return record;
-#endif
- }
-
-// disable creation/parsing of zip archive digital signatures
-#if ArchiveSignaturesEnabled
- internal void Save(BinaryWriter writer)
- {
- writer.Write(_signatureConstant);
- writer.Write(_sizeOfData);
- if (_sizeOfData > 0)
- {
- writer.Write(_signatureData , 0, _sizeOfData);
- }
-
- writer.Flush();
- }
- internal long Size
- {
- get
- {
- return _fixedMinimalRecordSize + _sizeOfData;
- }
- }
-#endif
-
- private ZipIOCentralDirectoryDigitalSignature()
- {
- }
-
-// disable creation/parsing of zip archive digital signatures
-#if ArchiveSignaturesEnabled
- private void Validate ()
- {
- if (_signature != _signatureConstant)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- if (_sizeOfData != _signatureData.Length)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
- }
-#endif
- private const long _fixedMinimalRecordSize = 6;
-
- private const UInt32 _signatureConstant = 0x05054b50;
-
-// disable creation/parsing of zip archive digital signatures
-#if ArchiveSignaturesEnabled
- private UInt16 _sizeOfData;
- private UInt32 _signature = _signatureConstant;
- private byte[] _signatureData = null;
-#endif
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOCentralDirectoryFileHeader.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOCentralDirectoryFileHeader.cs
deleted file mode 100644
index 1b5fa1d2b0e..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOCentralDirectoryFileHeader.cs
+++ /dev/null
@@ -1,532 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that enables interactions with Zip archives
-// for OPC scenarios
-//
-//
-//
-//
-
-using System;
-using System.IO;
-using System.Diagnostics;
-using System.Text;
-using System.Collections;
-using System.Runtime.Serialization;
-using System.Windows;
-using MS.Internal.WindowsBase;
-
-namespace MS.Internal.IO.Zip
-{
- internal class ZipIOCentralDirectoryFileHeader
- {
- internal static ZipIOCentralDirectoryFileHeader CreateNew(Encoding encoding, ZipIOLocalFileBlock fileBlock)
- {
- ZipIOCentralDirectoryFileHeader header = new ZipIOCentralDirectoryFileHeader(encoding);
-
- // initialize fields that are not duplicated in the local file block(header)
- header._fileCommentLength =0;
- header._fileComment = null;
- header._diskNumberStart = 0;
- header._internalFileAttributes = 0;
- header._externalFileAttributes = 0;
- header._versionMadeBy = (ushort)ZipIOVersionNeededToExtract.Zip64FileFormat;
- header._extraField = ZipIOExtraField.CreateNew(false /* no padding */);
-
- // update the rest of the fields based on the local file header
- header.UpdateFromLocalFileBlock(fileBlock);
-
- return header;
- }
-
- internal static ZipIOCentralDirectoryFileHeader ParseRecord(BinaryReader reader, Encoding encoding)
- {
- ZipIOCentralDirectoryFileHeader header = new ZipIOCentralDirectoryFileHeader(encoding);
-
- header._signature = reader.ReadUInt32();
- header._versionMadeBy = reader.ReadUInt16();
- header._versionNeededToExtract = reader.ReadUInt16();
- header._generalPurposeBitFlag = reader.ReadUInt16();
- header._compressionMethod = reader.ReadUInt16();
- header._lastModFileDateTime = reader.ReadUInt32();
- header._crc32 = reader.ReadUInt32();
- header._compressedSize = reader.ReadUInt32();
- header._uncompressedSize = reader.ReadUInt32();
- header._fileNameLength = reader.ReadUInt16();
- header._extraFieldLength = reader.ReadUInt16();
- header._fileCommentLength = reader.ReadUInt16();
- header._diskNumberStart = reader.ReadUInt16();
- header._internalFileAttributes = reader.ReadUInt16();
- header._externalFileAttributes = reader.ReadUInt32();
- header._relativeOffsetOfLocalHeader = reader.ReadUInt32();
-
- header._fileName = reader.ReadBytes(header._fileNameLength);
-
- // check for the ZIP 64 version and escaped values
- ZipIOZip64ExtraFieldUsage zip64extraFieldUsage = ZipIOZip64ExtraFieldUsage.None;
- if (header._versionNeededToExtract >= (ushort)ZipIOVersionNeededToExtract.Zip64FileFormat)
- {
- if (header._compressedSize == UInt32.MaxValue)
- {
- zip64extraFieldUsage |= ZipIOZip64ExtraFieldUsage.CompressedSize;
- }
- if (header._uncompressedSize == UInt32.MaxValue)
- {
- zip64extraFieldUsage |= ZipIOZip64ExtraFieldUsage.UncompressedSize;
- }
- if (header._relativeOffsetOfLocalHeader == UInt32.MaxValue)
- {
- zip64extraFieldUsage |= ZipIOZip64ExtraFieldUsage.OffsetOfLocalHeader;
- }
- if (header._diskNumberStart == UInt16.MaxValue)
- {
- zip64extraFieldUsage |= ZipIOZip64ExtraFieldUsage.DiskNumber;
- }
- }
-
- // if the ZIP 64 record is missing the zip64extraFieldUsage value will be ignored
- header._extraField = ZipIOExtraField.ParseRecord(reader,
- zip64extraFieldUsage,
- header._extraFieldLength);
-
- header._fileComment = reader.ReadBytes(header._fileCommentLength);
-
- //populate frequently used field with user friendly data representations
- header._stringFileName = ZipIOBlockManager.ValidateNormalizeFileName(encoding.GetString(header._fileName));
-
- header.Validate();
-
- return header;
- }
-
- internal void Save(BinaryWriter writer)
- {
- writer.Write(_signatureConstant);
- writer.Write(_versionMadeBy);
- writer.Write(_versionNeededToExtract);
- writer.Write(_generalPurposeBitFlag);
- writer.Write(_compressionMethod);
- writer.Write(_lastModFileDateTime);
- writer.Write(_crc32);
- writer.Write(_compressedSize);
- writer.Write(_uncompressedSize);
- writer.Write(_fileNameLength);
- writer.Write(_extraField.Size);
- writer.Write(_fileCommentLength);
- writer.Write(_diskNumberStart);
- writer.Write(_internalFileAttributes);
- writer.Write(_externalFileAttributes);
- writer.Write(_relativeOffsetOfLocalHeader);
-
-
- Debug.Assert(_fileNameLength > 0); // we validate this for both parsing and API entry points
- writer.Write(_fileName, 0, _fileNameLength);
-
- _extraField.Save(writer);
-
- if (_fileCommentLength > 0)
- {
- writer.Write(_fileComment , 0, _fileCommentLength);
- }
- }
-
- internal bool UpdateIfNeeded(ZipIOLocalFileBlock fileBlock)
- {
- if (CheckIfUpdateNeeded(fileBlock))
- {
- UpdateFromLocalFileBlock(fileBlock);
- return true;
- }
- else
- {
- return false;
- }
- }
-
- internal string FileName
- {
- get
- {
- return _stringFileName;
- }
- // set method if needed will have to update both the _stringFileName and
- // _fileName
- }
-
- internal UInt16 VersionNeededToExtract
- {
- get
- {
- return _versionNeededToExtract;
- }
- }
-
- internal UInt16 GeneralPurposeBitFlag
- {
- get
- {
- return _generalPurposeBitFlag;
- }
- }
-
- internal CompressionMethodEnum CompressionMethod
- {
- get
- {
- // cast is safe because the value is validated in Validate()
- return (CompressionMethodEnum)_compressionMethod;
- }
- }
-
- internal long Size
- {
- get
- {
- return checked(_fixedMinimalRecordSize + _fileNameLength + _extraField.Size + _fileCommentLength);
- }
- }
-
- internal long OffsetOfLocalHeader
- {
- get
- {
- if ((_extraField.Zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.OffsetOfLocalHeader) != 0)
- {
- // zip 64 extra field is there
- return _extraField.OffsetOfLocalHeader;
- }
- else
- {
- // 32 bit case
- return _relativeOffsetOfLocalHeader;
- }
- }
- }
-
- internal long CompressedSize
- {
- get
- {
- if ((_extraField.Zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.CompressedSize) != 0)
- {
- // zip 64 extra field is there
- return _extraField.CompressedSize;
- }
- else
- {
- // 32 bit case
- return _compressedSize;
- }
- }
- }
-
- internal long UncompressedSize
- {
- get
- {
- if ((_extraField.Zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.UncompressedSize) != 0)
- {
- // zip 64 extra field is there
- return _extraField.UncompressedSize;
- }
- else
- {
- // 32 bit case
- return _uncompressedSize;
- }
- }
- }
-
- internal UInt32 Crc32
- {
- get
- {
- return _crc32;
- }
- }
-
- internal UInt32 DiskNumberStart
- {
- get
- {
- if ((_extraField.Zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.DiskNumber) != 0)
- {
- // zip 64 extra field is there (32 bit value returned)
- return _extraField.DiskNumberOfFileStart;
- }
- else
- {
- // 16 bit case
- return _diskNumberStart;;
- }
- }
- }
-
- internal bool FolderFlag
- {
- get
- {
- // The upper byte of version made by indicates the compatibility of the file attribute information.
- // If the external file attributes are compatible with MS-DOS then this value
- // will be zero.
-
- // lower byte of the external file attribute is the the MS-DOS directory attribute byte
- //
- // 0x20 5 file has been changed since last backup
- // 0x10 4 entry represents a subdirectory XXXXXXXXX
- // 0x08 3 entry represents a volume label
- // 0x04 2 system file
- // 0x02 1 hidden file
- // 0x01 0 read-only
-
- return ((_versionMadeBy & 0xFF00) == _constantUpperVersionMadeByMsDos)
- &&
- ((_externalFileAttributes & 0x10) != 0);
- }
- }
-
- internal bool VolumeLabelFlag
- {
- get
- {
- // The upper byte of version made by indicates the compatibility of the file attribute information.
- // If the external file attributes are compatible with MS-DOS then this value
- // will be zero.
-
- // lower byte of the external file attribute is the the MS-DOS directory attribute byte
- //
- // 0x20 5 file has been changed since last backup
- // 0x10 4 entry represents a subdirectory
- // 0x08 3 entry represents a volume label XXXXXXXXX
- // 0x04 2 system file
- // 0x02 1 hidden file
- // 0x01 0 read-only
-
- return ((_versionMadeBy & 0xFF00) == _constantUpperVersionMadeByMsDos)
- &&
- ((_externalFileAttributes & 0x08) != 0);
- }
- }
-
- // this function is called by the Central Dir in order to notify us that
- // the appropriate file item was shifted (as detected by the shift in the Raw Data Block)
- // holding given file item.
- // for us it means that although all the size characteristics are preserved (local file header
- // wasn't even parsed if it still in the Raw). But the offset could have changed which
- // might result in Zip64 struicture.
- internal void MoveReference(long shiftSize)
- {
- UpdateZip64Structures(CompressedSize,
- UncompressedSize,
- checked(OffsetOfLocalHeader +shiftSize));
- }
-
- // this function is sets the sizes into the either 64 or 32 bit structures based on values of the fields
- // It used in 2 places by the MoveReference and by the UpdateFromLocalFileBlock
- private void UpdateZip64Structures
- (long compressedSize, long uncompressedSize, long offset)
- {
- Debug.Assert((compressedSize >= 0) && (uncompressedSize>=0) && (offset >=0));
-
- // according to the appnote central directory extra field might be a mix of any values based on escaping
- // we will fully (without disk number) use it every time we are building a ZIP 64 arhichive
- // we also trying to stay on the safe side and treeat the boundary case of 32 escape values
- // as a zip 64 scenrio
- if ((compressedSize >= UInt32.MaxValue) ||
- (uncompressedSize >= UInt32.MaxValue) ||
- (offset >= UInt32.MaxValue))
- {
- // Zip 64 case
- _extraField.CompressedSize = compressedSize;
- _extraField.UncompressedSize = uncompressedSize;
- _extraField.OffsetOfLocalHeader = offset;
-
- //set proper escape values
- _compressedSize = UInt32.MaxValue;
- _uncompressedSize = UInt32.MaxValue;
- _relativeOffsetOfLocalHeader = UInt32.MaxValue;
-
- // update version needed to extract to 4.5
- _versionNeededToExtract = (UInt16)ZipIOVersionNeededToExtract.Zip64FileFormat;
- }
- else
- {
- // 32 bit case
- _compressedSize = checked((UInt32)compressedSize);
- _uncompressedSize = checked((UInt32)uncompressedSize);
- _relativeOffsetOfLocalHeader = checked((UInt32)offset);
-
- // reset the extra ZIP 64 field to empty
- _extraField.Zip64ExtraFieldUsage = ZipIOZip64ExtraFieldUsage.None;
-
- // version needed to extract needs to be recalculated from scratch based on compression
- _versionNeededToExtract = (UInt16)ZipIOBlockManager.CalcVersionNeededToExtractFromCompression
- ((CompressionMethodEnum)_compressionMethod);
- }
- }
-
- private void UpdateFromLocalFileBlock(ZipIOLocalFileBlock fileBlock)
- {
- Debug.Assert(DiskNumberStart == 0);
-
- _signature = _signatureConstant;
- _generalPurposeBitFlag = fileBlock.GeneralPurposeBitFlag;
- _compressionMethod = (UInt16)fileBlock.CompressionMethod;
- _lastModFileDateTime = fileBlock.LastModFileDateTime;
- _crc32 = fileBlock.Crc32;
-
- // file name is easy to copy
- _fileNameLength = (UInt16)fileBlock.FileName.Length; // this is safe cast as file name is always validate for size
- _fileName = _encoding.GetBytes(fileBlock.FileName);
- _stringFileName = fileBlock.FileName;
-
- // this will properly update the 32 or zip 64 fields
- UpdateZip64Structures(fileBlock.CompressedSize,
- fileBlock.UncompressedSize,
- fileBlock.Offset);
-
- // Previous instruction may determine that we don't really need 4.5, but we
- // want to ensure that the version is identical with what is stored in the local file header.
- Debug.Assert(_versionNeededToExtract <= fileBlock.VersionNeededToExtract, "Should never be making this smaller");
-
- _versionNeededToExtract = fileBlock.VersionNeededToExtract;
-
- // These fields are intentionally ignored, as they are not present in the local header
- //_fileCommentLength;
- //_fileComment;
- //_diskNumberStart;
- //_internalFileAttributes;
- //_externalFileAttributes;
- }
-
- private bool CheckIfUpdateNeeded(ZipIOLocalFileBlock fileBlock)
- {
- // there is a special case for the _generalPurposeBitFlag.Bit #3
- // it could be set in the local file header indicating streaming
- // creation, while it doesn't need to be set in the Central directory
- // so having
- // (fileBlock.GeneralPurposeBitFlag == 8 && and _generalPurposeBitFlag == 0)
- // is a valid case when update is not required
-
- // let's compare the 3rd bit of the general purpose bit flag
- bool localFileHeaderStreamingFlag = (0 != (fileBlock.GeneralPurposeBitFlag & _streamingBitMask));
- bool centralDirStreamingFlag = (0 != (_generalPurposeBitFlag & _streamingBitMask));
-
- if (!localFileHeaderStreamingFlag && centralDirStreamingFlag)
- {
- // the mismatch if local file header in non streaming but the central directory is in streaming mode
- // all the other combinations do not require an update and valid as is
- // this includes scenario when local file header is in streaming and central dir is not
- return true;
- }
-
- Debug.Assert(String.CompareOrdinal(_stringFileName, fileBlock.FileName) == 0);
-
- return
- (_signature != _signatureConstant) ||
- (_versionNeededToExtract != fileBlock.VersionNeededToExtract) ||
- (_generalPurposeBitFlag != fileBlock.GeneralPurposeBitFlag) ||
- (_compressionMethod != (UInt16)fileBlock.CompressionMethod) ||
- (_crc32 != fileBlock.Crc32) ||
- (CompressedSize != fileBlock.CompressedSize) ||
- (UncompressedSize != fileBlock.UncompressedSize) ||
- (OffsetOfLocalHeader != fileBlock.Offset);
-
- // These fields are intentionally ignored, as they are not present in the local header
- //_fileCommentLength;
- //_fileComment;
- //_diskNumberStart;
- //_internalFileAttributes;
- //_externalFileAttributes;
- }
-
-
- private ZipIOCentralDirectoryFileHeader(Encoding encoding)
- {
- _encoding = encoding;
- }
-
- private void Validate ()
- {
- if (_signature != _signatureConstant)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- if (DiskNumberStart != 0)
- {
- throw new NotSupportedException(SR.Get(SRID.NotSupportedMultiDisk));
- }
-
- if (_fileNameLength != _fileName.Length)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- if (_extraFieldLength != _extraField.Size)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- ZipArchive.VerifyVersionNeededToExtract(_versionNeededToExtract);
-
- // if verson is below 4.5 make sure that ZIP 64 extra filed isn't present
- // if it is it might be a security concern
- if ((_versionNeededToExtract < (UInt16)ZipIOVersionNeededToExtract.Zip64FileFormat) &&
- (_extraField.Zip64ExtraFieldUsage != ZipIOZip64ExtraFieldUsage.None))
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- if (_fileCommentLength != _fileComment.Length)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- if ((_compressionMethod != (UInt16)CompressionMethodEnum.Stored) &&
- (_compressionMethod != (UInt16)CompressionMethodEnum.Deflated))
- {
- throw new NotSupportedException(SR.Get(SRID.ZipNotSupportedCompressionMethod));
- }
- }
-
- private Encoding _encoding;
- private const int _fixedMinimalRecordSize = 46;
-
- private const byte _constantUpperVersionMadeByMsDos = 0x0;
-
- private const UInt16 _streamingBitMask = 0x08; // bit #3
-
- private const UInt32 _signatureConstant = 0x02014b50;
- private UInt32 _signature = _signatureConstant;
-
- // we expect all variables to be initialized to 0
- private UInt16 _versionMadeBy;
- private UInt16 _versionNeededToExtract;
- private UInt16 _generalPurposeBitFlag;
- private UInt16 _compressionMethod;
- private UInt32 _lastModFileDateTime;
- private UInt32 _crc32;
- private UInt32 _compressedSize;
- private UInt32 _uncompressedSize;
- private UInt16 _fileNameLength;
- private UInt16 _extraFieldLength;
- private UInt16 _fileCommentLength;
- private UInt16 _diskNumberStart;
- private UInt16 _internalFileAttributes;
- private UInt32 _externalFileAttributes;
- private UInt32 _relativeOffsetOfLocalHeader;
- private byte[] _fileName;
- private ZipIOExtraField _extraField;
- private byte[] _fileComment;
-
- //duplicate dat for fast access
- private string _stringFileName;
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOEndOfCentralDirectoryBlock.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOEndOfCentralDirectoryBlock.cs
deleted file mode 100644
index 9fcb170e4fa..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOEndOfCentralDirectoryBlock.cs
+++ /dev/null
@@ -1,443 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that enables interactions with Zip archives
-// for OPC scenarios
-//
-//
-//
-//
-
-using System;
-using System.IO;
-using System.Diagnostics;
-using System.Runtime.Serialization;
-using System.Windows;
-using MS.Internal.IO.Packaging; // for PackagingUtilities
-using MS.Internal.WindowsBase;
-
-namespace MS.Internal.IO.Zip
-{
- internal class ZipIOEndOfCentralDirectoryBlock : IZipIOBlock
- {
- //------------------------------------------------------
- //
- // Public Properties
- //
- //------------------------------------------------------
- // standard IZipIOBlock functionality
- public long Offset
- {
- get
- {
- return _offset;
- }
- }
-
- public long Size
- {
- get
- {
- return _fixedMinimalRecordSize + _zipFileCommentLength;
- }
- }
-
- public bool GetDirtyFlag(bool closingFlag)
- {
- return _dirtyFlag;
- }
-
- //------------------------------------------------------
- //
- // Public Methods
- //
- //------------------------------------------------------
- public void Move(long shiftSize)
- {
- if (shiftSize != 0)
- {
- checked{_offset +=shiftSize;}
- _dirtyFlag = true;
- Debug.Assert(_offset >=0);
- }
- }
-
- public void Save()
- {
- if (GetDirtyFlag(true))
- {
- BinaryWriter writer = _blockManager.BinaryWriter;
-
- // never seek in streaming mode
- if (!_blockManager.Streaming && _blockManager.Stream.Position != _offset)
- {
- // we need to seek
- _blockManager.Stream.Seek(_offset, SeekOrigin.Begin);
- }
-
- writer.Write(_signatureConstant);
- writer.Write(_numberOfThisDisk);
- writer.Write(_numberOfTheDiskWithTheStartOfTheCentralDirectory);
- writer.Write(_totalNumberOfEntriesInTheCentralDirectoryOnThisDisk);
- writer.Write(_totalNumberOfEntriesInTheCentralDirectory);
- writer.Write(_sizeOfTheCentralDirectory);
- writer.Write(_offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber);
- writer.Write(_zipFileCommentLength);
- if (_zipFileCommentLength > 0)
- {
- writer.Write(_zipFileComment, 0, _zipFileCommentLength);
- }
- writer.Flush();
-
- _dirtyFlag = false;
- }
- }
-
- public void UpdateReferences(bool closingFlag)
- {
- // 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. Zip64 End of Central Directory Locator is dirty
- // 4. streaming mode
- // if Central Directory isn't loded or none of the relevant structure is dirty,
- // there is nothing to update for End Of Central directory record
- if (_blockManager.IsCentralDirectoryBlockLoaded
- && (_blockManager.Streaming
- || _blockManager.CentralDirectoryBlock.GetDirtyFlag(closingFlag)
- || _blockManager.Zip64EndOfCentralDirectoryBlock.GetDirtyFlag(closingFlag)
- || _blockManager.Zip64EndOfCentralDirectoryLocatorBlock.GetDirtyFlag(closingFlag)))
- {
- // intialize them to zIP64 case, and update them if needed
- UInt16 centralDirCount = UInt16.MaxValue;
- UInt32 centralDirBlockSize = UInt32.MaxValue;
- UInt32 centralDirOffset = UInt32.MaxValue;
- UInt16 numberOfTheDiskWithTheStartOfTheCentralDirectory = 0;
- UInt16 numberOfThisDisk = 0;
-
-
- // If we don't need Zip 64 struture
- if (!_blockManager.CentralDirectoryBlock.IsZip64BitRequiredForStoring)
- {
- // if it isn't zip 64 let's get the data out
- centralDirCount = (UInt16)_blockManager.CentralDirectoryBlock.Count;
- centralDirBlockSize = (UInt32)_blockManager.CentralDirectoryBlock.Size;
- centralDirOffset = (UInt32)_blockManager.CentralDirectoryBlock.Offset;
- }
-
- // update value and mark record dirty if either it is already dirty or there is a mismatch
- if ((_dirtyFlag) ||
- (_totalNumberOfEntriesInTheCentralDirectoryOnThisDisk != centralDirCount) ||
- (_totalNumberOfEntriesInTheCentralDirectory != centralDirCount ) ||
- (_sizeOfTheCentralDirectory != centralDirBlockSize) ||
- (_offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber != centralDirOffset) ||
- (_numberOfTheDiskWithTheStartOfTheCentralDirectory != numberOfTheDiskWithTheStartOfTheCentralDirectory) ||
- (_numberOfThisDisk != numberOfThisDisk))
- {
- _totalNumberOfEntriesInTheCentralDirectoryOnThisDisk = centralDirCount;
- _totalNumberOfEntriesInTheCentralDirectory = centralDirCount;
- _sizeOfTheCentralDirectory = centralDirBlockSize;
- _offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber = centralDirOffset;
- _numberOfTheDiskWithTheStartOfTheCentralDirectory = numberOfTheDiskWithTheStartOfTheCentralDirectory;
- _numberOfThisDisk = numberOfThisDisk;
-
- _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 there shouldn't be any blocks after the EOCD
- return PreSaveNotificationScanControlInstruction.Stop;
- }
-
- //------------------------------------------------------
- //
- // Internal Methods
- //
- //------------------------------------------------------
- internal static ZipIOEndOfCentralDirectoryBlock SeekableLoad (ZipIOBlockManager blockManager)
- {
- // perform custom serach for record
- long blockPosition = FindPosition(blockManager.Stream);
- blockManager.Stream.Seek(blockPosition, SeekOrigin.Begin);
-
- ZipIOEndOfCentralDirectoryBlock block = new ZipIOEndOfCentralDirectoryBlock(blockManager);
-
- block.ParseRecord(blockManager.BinaryReader, blockPosition);
- return block;
- }
-
- internal static ZipIOEndOfCentralDirectoryBlock CreateNew(ZipIOBlockManager blockManager, long offset)
- {
- ZipIOEndOfCentralDirectoryBlock block = new ZipIOEndOfCentralDirectoryBlock(blockManager);
-
- block._offset = offset;
- block._dirtyFlag = true;
-
- return block;
- }
-
- internal void ValidateZip64TriggerValues()
- {
- if ((_offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber > _offset)
- ||
- ((_offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber == _offset) &&
- (_totalNumberOfEntriesInTheCentralDirectoryOnThisDisk > 0)))
- {
- // central directory must start prior to the offset of the end of central directory.
- // the only exception is when size of the central directory is 0
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- if ((_numberOfThisDisk != 0) ||
- (_numberOfTheDiskWithTheStartOfTheCentralDirectory != 0) ||
- (_totalNumberOfEntriesInTheCentralDirectoryOnThisDisk !=
- _totalNumberOfEntriesInTheCentralDirectory))
- {
- throw new NotSupportedException(SR.Get(SRID.NotSupportedMultiDisk));
- }
- }
-
- internal uint NumberOfThisDisk
- {
- get
- {
- return _numberOfThisDisk;
- }
- }
-
- internal uint NumberOfTheDiskWithTheStartOfTheCentralDirectory
- {
- get
- {
- return _numberOfTheDiskWithTheStartOfTheCentralDirectory;
- }
- }
-
- internal uint TotalNumberOfEntriesInTheCentralDirectoryOnThisDisk
- {
- get
- {
- return _totalNumberOfEntriesInTheCentralDirectoryOnThisDisk ;
- }
- }
-
- internal uint TotalNumberOfEntriesInTheCentralDirectory
- {
- get
- {
- return _totalNumberOfEntriesInTheCentralDirectory;
- }
- }
-
- internal uint SizeOfTheCentralDirectory
- {
- get
- {
- return _sizeOfTheCentralDirectory;
- }
- }
-
- internal uint OffsetOfStartOfCentralDirectory
- {
- get
- {
- return _offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber;
- }
- }
-#if false
- internal string Comment
- {
- get
- {
- return _stringZipFileComment;
- }
- }
-#endif
-
- internal bool ContainValuesHintingToPossibilityOfZip64
- {
- get
- {
- return ((_numberOfThisDisk == UInt16.MaxValue) ||
- (_numberOfTheDiskWithTheStartOfTheCentralDirectory == UInt16.MaxValue) ||
- (_totalNumberOfEntriesInTheCentralDirectoryOnThisDisk == UInt16.MaxValue) ||
- (_totalNumberOfEntriesInTheCentralDirectory == UInt16.MaxValue) ||
- (_sizeOfTheCentralDirectory == UInt32.MaxValue) ||
- (_offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber == UInt32.MaxValue));
- }
- }
-
- //------------------------------------------------------
- //
- // Private Methods
- //
- //------------------------------------------------------
- private ZipIOEndOfCentralDirectoryBlock(ZipIOBlockManager blockManager)
- {
- Debug.Assert(blockManager != null);
- _blockManager= blockManager;
- }
-
- private static long FindPosition(Stream archiveStream)
- {
- Debug.Assert(archiveStream.CanSeek);
- byte [] buffer = new byte[_scanBlockSize + _fixedMinimalRecordSize];
- long streamLength = archiveStream.Length;
-
- for(long endPos = streamLength; endPos > 0; endPos -= _scanBlockSize)
- {
- // calculate offset position of the block to be read based on the end
- // Position loop variable
- long beginPos = Math.Max(0, endPos -_scanBlockSize);
-
- //read the block
- archiveStream.Seek(beginPos, SeekOrigin.Begin);
-
- // the reads that we do actually overlap each other by the size == _fixedMinimalRecordSize
- // this is done in order to simplify our searching logic, this way we do not need to specially
- // process matches that cross buffer boundaries, as we are guaranteed that if match is present
- // it falls completely inside one of the buffers, as a result of overlapping in the read requests
- int bytesRead = PackagingUtilities.ReliableRead(archiveStream, buffer, 0, buffer.Length);
-
- // We need to pass this parameter into the function, so it knows
- // the relative positon of the buffer in regard to the end of the stream;
- // it needs this info in order to checke whether the candidate record
- // has length of Comment field consistent with the postion of the record
- long distanceFromStartOfBufferToTheEndOfStream = streamLength -beginPos;
- for(int i = bytesRead - _fixedMinimalRecordSize; i>=0; i--)
- {
- if (IsPositionMatched(i, buffer, distanceFromStartOfBufferToTheEndOfStream))
- {
- return beginPos + i;
- }
- }
- }
-
- // At this point we have finished scanning the file and haven't find anything
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
-
- private static bool IsPositionMatched (int pos, byte[] buffer, long bufferOffsetFromEndOfStream)
- {
- Debug.Assert(buffer != null);
-
- Debug.Assert(buffer.Length >= _fixedMinimalRecordSize); // the end of central directory record must fit in there
-
- Debug.Assert(pos <= buffer.Length - _fixedMinimalRecordSize); // enough space to fit the record after pos
-
- Debug.Assert(bufferOffsetFromEndOfStream >= _fixedMinimalRecordSize); // there is no reason to start searching for the record
- // after less than 22 byrtes left till the end of stream
-
- for(int i = 0; i<_signatureBuffer.Length; i++)
- {
- if (_signatureBuffer[i] != buffer[pos+i])
- {
- //signature mismatch
- return false;
- }
- }
-
- //we got signature matching, let's see if we can get comment length to match
- // to handle little endian order of the bytes in the 16 bit length
- long commentLengthFromRecord = buffer[pos + _fixedMinimalRecordSize-2] +
- (buffer[pos + _fixedMinimalRecordSize-1] << 8);
-
- long commentLengthFromPos = bufferOffsetFromEndOfStream - pos - _fixedMinimalRecordSize;
- if (commentLengthFromPos != commentLengthFromRecord)
- {
- return false;
- }
-
- return true;
- }
-
- private void ParseRecord (BinaryReader reader, long position)
- {
- _signature = reader.ReadUInt32();
- _numberOfThisDisk = reader.ReadUInt16();
- _numberOfTheDiskWithTheStartOfTheCentralDirectory = reader.ReadUInt16();
- _totalNumberOfEntriesInTheCentralDirectoryOnThisDisk = reader.ReadUInt16();
- _totalNumberOfEntriesInTheCentralDirectory = reader.ReadUInt16();
- _sizeOfTheCentralDirectory = reader.ReadUInt32();
- _offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber = reader.ReadUInt32();
- _zipFileCommentLength = reader.ReadUInt16();
- _zipFileComment = reader.ReadBytes(_zipFileCommentLength);
-
- _stringZipFileComment = _blockManager.Encoding.GetString(_zipFileComment);
-
- _offset = position;
-
- _dirtyFlag = false;
-
- Validate();
- }
-
- // Do minimum validatation here
- // The rest of validation on the fields that can indicate the possiblity of Zip64 will be validated later
- // If there is the zip64 End of Central Directory, thoses values will be valided
- // by ZipIO64EndOfCentralDirectoryBlock
- // Otherwise it will be validated in ZipIoBlockManager when it tries load ZipIO64EndOfCentralDirectoryBlock
- // In all of the supported scenarios we always try to load ZipIO64EndOfCentralDirectoryBlock immediately
- // after it loads ZipIOEndOfCentralDirectoryBlock; so there is not much difference in the timing of
- // the validation
- private void Validate()
- {
- if (_signature != _signatureConstant)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- if (_zipFileCommentLength != _zipFileComment.Length)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
- }
-
- //------------------------------------------------------
- //
- // Private Members
- //
- //------------------------------------------------------
- // constant that is used for locating EndOf record signature
- private static byte [] _signatureBuffer = new byte[] {0x50, 0x4b, 0x05, 0x06};
-
- // this blocks size is used to read data thro the tail of stream block by block
- private static int _scanBlockSize = 0x01000;
-
- private ZipIOBlockManager _blockManager;
-
- private long _offset;
- private bool _dirtyFlag;
-
- private const UInt32 _signatureConstant = 0x06054b50;
- private const int _fixedMinimalRecordSize = 22;
-
- // data persisted on disk
- private UInt32 _signature = _signatureConstant;
- private UInt16 _numberOfThisDisk;
- private UInt16 _numberOfTheDiskWithTheStartOfTheCentralDirectory;
- private UInt16 _totalNumberOfEntriesInTheCentralDirectoryOnThisDisk;
- private UInt16 _totalNumberOfEntriesInTheCentralDirectory;
- private UInt32 _sizeOfTheCentralDirectory;
- private UInt32 _offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber;
- private UInt16 _zipFileCommentLength;
- private byte[] _zipFileComment;
- private string _stringZipFileComment;
- }
-}
-
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOExtraField.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOExtraField.cs
deleted file mode 100644
index ca199534b68..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOExtraField.cs
+++ /dev/null
@@ -1,307 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// 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
-//
-
-using System;
-using System.IO;
-using System.Diagnostics;
-using System.Collections;
-using System.Globalization;
-using System.Runtime.Serialization;
-using System.Windows;
-using MS.Internal.WindowsBase;
-
-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;
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOExtraFieldElement.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOExtraFieldElement.cs
deleted file mode 100644
index e5ed8f799de..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOExtraFieldElement.cs
+++ /dev/null
@@ -1,199 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that is used to implement parsing and editing of a generic extra field structure.
-// It doesn't contain informaton about any specific (like Zip64) extra fields that are supported by
-// this implementation. In order to isolate this from IO and streams, it deals with the data in the Byte[] form
-
-
-using System;
-using System.IO;
-using System.Diagnostics;
-using System.Collections;
-using System.Globalization;
-using System.Runtime.Serialization;
-using System.Windows;
-
-using MS.Internal.IO.Packaging;
-using MS.Internal.WindowsBase;
-
-namespace MS.Internal.IO.Zip
-{
- ///
- /// This is an internal class that is used to implement parsing and editing of generic extra field structures.
- /// It doesn't contain informaton about any specific (like Zip64) extra fields that are supported by
- /// this implementation. In order to isolate this from IO and streams, it deals with the data in the Byte[] form
- ///
- internal class ZipIOExtraFieldElement
- {
- internal static ZipIOExtraFieldElement Parse(BinaryReader reader, ZipIOZip64ExtraFieldUsage zip64extraFieldUsage)
- {
- // we can safely parse the Id and Size here
- // since the minimum size is checked from the caller (ZipIoExtraField)
- UInt16 id = reader.ReadUInt16();
- UInt16 size = reader.ReadUInt16();
-
- ZipIOExtraFieldElement newElement;
-
- if (id == ZipIOExtraFieldZip64Element.ConstantFieldId) // Found Zip64 Extra Field element
- {
- newElement = new ZipIOExtraFieldZip64Element();
- ((ZipIOExtraFieldZip64Element) newElement).Zip64ExtraFieldUsage = zip64extraFieldUsage;
- }
- else if (id == ZipIOExtraFieldPaddingElement.ConstantFieldId) // Found potential Padding Extra Field element
- {
- // Even if the id matches Padding Extra Element id, we cannot be sure if it is Microsoft defined one
- // until its signature is verified
-
- // This extra field matches Padding Extra Element id, but it is not big enough to be ours
- if (size < ZipIOExtraFieldPaddingElement.MinimumFieldDataSize)
- {
- // Treat it as an unknown Extra Field element
- newElement = new ZipIOExtraFieldElement(id);
- }
- else
- {
- // Sniff bytes to check it it matches our Padding extra field signature
- byte[] sniffedBytes = reader.ReadBytes(ZipIOExtraFieldPaddingElement.SignatureSize);
- if (ZipIOExtraFieldPaddingElement.MatchesPaddingSignature(sniffedBytes))
- {
- // Signature matches the Padding Extra Field signature
- newElement = new ZipIOExtraFieldPaddingElement();
- }
- else
- {
- // Signature doesn't match; treat it a an unknown Extra Field element
- newElement = new ZipIOExtraFieldElement(id, sniffedBytes);
- }
- }
- }
- else
- {
- newElement = new ZipIOExtraFieldElement(id);
- }
-
- // Parse the data field of the Extra Field element
- newElement.ParseDataField(reader, size);
-
- return newElement;
- }
-
- internal virtual void ParseDataField(BinaryReader reader, UInt16 size)
- {
- if (_data == null)
- {
- _data = reader.ReadBytes(size);
-
- //vaiadte that we didn't reach the end of stream too early
- if (_data.Length != size)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
- }
- else // There were some data we sniffed already
- {
- Byte[] tempBuffer = _data;
- _data = new Byte[size];
-
- Array.Copy(tempBuffer, _data, _size); // _size contains the size of data in _data
-
- checked
- {
- Debug.Assert(size >= _size);
-
- if ((PackagingUtilities.ReliableRead(reader, _data, _size, size - _size) + _size) != size)
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
- }
- _size = size;
- }
-
- internal virtual void Save(BinaryWriter writer)
- {
- Debug.Assert(_size == _data.Length);
-
- writer.Write(_id);
- writer.Write(_size);
- writer.Write(_data);
- }
-
- // This property calculates the value of the size record whch holds the size without the Id and without the size itself.
- // we are alkways guranteed that Size == SizeField + 2 * sizeof(UInt16))
- internal virtual UInt16 SizeField
- {
- get
- {
- return _size;
- }
- }
-
- // this fiels needs to be used very carefully as it retuns a writeble array
- // element of which could be potentially modifyed by the caller
- internal virtual byte[] DataField
- {
- get
- {
- return _data;
- }
- }
-
- // This property calculates size of the field on disk (how many bytes need to be allocated on the disk)
- internal virtual UInt16 Size
- {
- get
- {
- return checked((UInt16) (_size + _minimumSize)); // the real field size has 2 UInt16 fields for Id and size
- }
- }
-
- // Minimum size of any type of Extra Field Element
- // UInt16 id
- // UInt16 size
- internal static UInt16 MinimumSize
- {
- get
- {
- return _minimumSize;
- }
- }
-
- //------------------------------------------------------
- //
- // Private Constructor
- //
- //------------------------------------------------------
- internal ZipIOExtraFieldElement(UInt16 id)
- {
- _id = id;
- }
-
- // data: sniffied data field
- private ZipIOExtraFieldElement(UInt16 id, byte[] data)
- {
- Debug.Assert(data != null);
-
- _id = id;
- _data = data;
- _size = checked((UInt16) data.Length);
- }
-
- //------------------------------------------------------
- //
- // Private fields
- //
- //------------------------------------------------------
- private UInt16 _id;
- private UInt16 _size;
- private byte[] _data;
-
- // UInt16 id: 2
- // UInt16 size: 2
- private static readonly UInt16 _minimumSize = (UInt16) (2 * sizeof(UInt16));
- }
-}
-
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOExtraFieldPaddingElement.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOExtraFieldPaddingElement.cs
deleted file mode 100644
index d5e78e67f64..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOExtraFieldPaddingElement.cs
+++ /dev/null
@@ -1,192 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that is used to implement parsing and editing of a padding extra field
-// structure. This extra field is used to optimize the performance dealing with Zip64 extra field.
-// When we need to create Zip64 extra field the extra padding bytes are used to create such
-// structure so that the subsequent bytes don't have to be moved.
-
-
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Windows;
-
-namespace MS.Internal.IO.Zip
-{
- ///
- /// This class is used to represent and parse the Padding Extra Field
- ///
- /// The Padding Extra Field is defined as:
- /// Header ID UInt16 (2 bytes) 0xA220
- /// Length of the field UInt16 (2 bytes)
- /// Signature UInt16 (2 bytes) 0xA028 (for verification)
- /// Padding Initial Value UInt16 (2 bytes) Padding size originally requested by the caller
- /// Padding ? bytes Padding respresented by null characters
- ///
- internal class ZipIOExtraFieldPaddingElement : ZipIOExtraFieldElement
- {
- // creates a brand new empty Padding extra field element
- internal static ZipIOExtraFieldPaddingElement CreateNew()
- {
- ZipIOExtraFieldPaddingElement newElement = new ZipIOExtraFieldPaddingElement();
-
- return newElement;
- }
-
- // parse Padding extra field element
- internal override void ParseDataField(BinaryReader reader, UInt16 size)
- {
- // The signature is already read and validated
- Debug.Assert(size >= MinimumSize);
-
- // It is guaranteed that there is enough bytes to read in UInt16
- // since it is already checked from ZipIOExtraFieldElement.Parse()
- _initialRequestedPaddingSize = reader.ReadUInt16();
-
- // need to subtract the size of the signature and size fields
- // We don't need to use checked{} since size is guaranteed to be bigger than
- // MinimumFieldDataSize by the called (ZipIOExtraFieldElement.Parse)
- size -= _minimumFieldDataSize;
-
- _paddingSize = size;
-
- // Skip the padding
- if (_paddingSize != 0)
- {
- reader.BaseStream.Seek(size, SeekOrigin.Current);
- }
- }
-
- internal static bool MatchesPaddingSignature(byte[] sniffiedBytes)
- {
- if (sniffiedBytes.Length < _signatureSize)
- {
- return false;
- }
-
- Debug.Assert(sniffiedBytes.Length == _signatureSize);
-
- if (BitConverter.ToUInt16(sniffiedBytes, 0) != _signature)
- {
- return false;
- }
-
- return true;
- }
-
- internal override void Save(BinaryWriter writer)
- {
- writer.Write(_constantFieldId);
- writer.Write(SizeField);
- writer.Write(_signature);
- writer.Write(_initialRequestedPaddingSize);
-
- for (int i = 0; i < _paddingSize; ++i)
- {
- writer.Write((byte) 0);
- }
- }
-
- // This property calculates size of the field on disk (how many bytes need to be allocated on the disk)
- // id + size field + data field (SizeField)
- internal override UInt16 Size
- {
- get
- {
- return checked((UInt16) (SizeField + MinimumSize));
- }
- }
-
- // This property calculates the value of the size record whch holds the size without the Id and without the size itself.
- // we are always guranteed that Size == SizeField + 2 * sizeof(UInt16))
- internal override UInt16 SizeField
- {
- get
- {
- return checked((UInt16) (_minimumFieldDataSize + _paddingSize));
- }
- }
-
- static internal UInt16 ConstantFieldId
- {
- get
- {
- return _constantFieldId;
- }
- }
-
- static internal UInt16 MinimumFieldDataSize
- {
- get
- {
- return _minimumFieldDataSize;
- }
- }
-
- static internal UInt16 SignatureSize
- {
- get
- {
- return _signatureSize;
- }
- }
-
- internal UInt16 PaddingSize
- {
- get
- {
- return _paddingSize;
- }
- set
- {
- _paddingSize = value;
- }
- }
-
- //------------------------------------------------------
- //
- // Private Constructor
- //
- //------------------------------------------------------
- internal ZipIOExtraFieldPaddingElement() : base(_constantFieldId)
- {
- _initialRequestedPaddingSize = _newInitialPaddingSize;
- _paddingSize = _initialRequestedPaddingSize;
- }
-
- //------------------------------------------------------
- //
- // Private Methods
- //
- //------------------------------------------------------
-
- //------------------------------------------------------
- //
- // Private fields
- //
- //------------------------------------------------------
- private const UInt16 _constantFieldId = 0xA220;
- private const UInt16 _signature = 0xA028;
- // 20 is the maximum size of Zip64 Extra Field element we can use for Local File Header
- // (Id, Size, Compressed and UnCompressed Sizes; 2 + 2 + 8 + 8 = 20)
- // DiskNumber and Relative Offset of Local File Header is not counted since we don't use
- // it in Local File Header
- private const UInt16 _newInitialPaddingSize = 20;
-
- // UInt16 signature
- // UInt16 initial requested padding size
- private static readonly UInt16 _minimumFieldDataSize = 2 * sizeof(UInt16);
- private static readonly UInt16 _signatureSize = sizeof(UInt16);
-
- private UInt16 _paddingSize;
- private UInt16 _initialRequestedPaddingSize;
- }
-}
-
-
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOExtraFieldZip64Element.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOExtraFieldZip64Element.cs
deleted file mode 100644
index be37b8ac579..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOExtraFieldZip64Element.cs
+++ /dev/null
@@ -1,338 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that helps managing/parsing the
-// ZIP64 Extended Information Extra Field (0x0001): for OPC scenarios
-// In order to isolate this from IO and streams, it deals with the data in the Byte[] form
-//
-//
-//
-//
-
-using System;
-using System.IO;
-using System.Diagnostics;
-using System.Windows;
-using MS.Internal.WindowsBase;
-
-namespace MS.Internal.IO.Zip
-{
- internal enum ZipIOZip64ExtraFieldUsage
- {
- None = 0,
- UncompressedSize = 1,
- CompressedSize = 2,
- OffsetOfLocalHeader = 4,
- DiskNumber = 8,
- }
-
- ///
- /// This class is used to represent and parse the the
- /// ZIP64 Extended Information Extra Field (0x0001)
- /// In order to isolate this from IO and streams it deals with the data in the Byte[] form
- ///
- internal class ZipIOExtraFieldZip64Element : ZipIOExtraFieldElement
- {
- // creates brand new empty ZIP 64 extra field element
- internal static ZipIOExtraFieldZip64Element CreateNew()
- {
- ZipIOExtraFieldZip64Element newElement = new ZipIOExtraFieldZip64Element();
-
- return newElement;
- }
-
- // extracts ZIP 64 extra field element from a given byte array
- internal override void ParseDataField(BinaryReader reader, UInt16 size)
- {
- Debug.Assert(reader != null);
-
- if ((_zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.UncompressedSize) != 0)
- {
- _uncompressedSize = reader.ReadUInt64();
-
- if (size < sizeof(UInt64))
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- size -= sizeof(UInt64);
- }
-
- if ((_zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.CompressedSize) != 0)
- {
- _compressedSize = reader.ReadUInt64();
-
- if (size < sizeof(UInt64))
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- size -= sizeof(UInt64);
- }
-
- if ((_zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.OffsetOfLocalHeader) != 0)
- {
- _offsetOfLocalHeader = reader.ReadUInt64();
-
- if (size < sizeof(UInt64))
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- size -= sizeof(UInt64);
- }
-
- if ((_zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.DiskNumber) != 0)
- {
- _diskNumber = reader.ReadUInt32();
-
- if (size < sizeof(UInt32))
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- size -= sizeof(UInt32);
- }
-
- // There is an extra field that is not used and must be ignored.
- // The reader must also advance past the unused bytes.
- if (_zip64ExtraFieldUsage == ZipIOZip64ExtraFieldUsage.None)
- {
- reader.BaseStream.Seek(size, SeekOrigin.Current);
- _ignoredFieldSize = size;
- size = 0;
- }
-
- if (size != 0)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- Validate();
- }
-
- internal override void Save(BinaryWriter writer)
- {
- // if it is == 0 we shouldn't be persisting this
- Debug.Assert(SizeField > 0);
-
- writer.Write(_constantFieldId);
- writer.Write(SizeField);
-
- if ((_zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.UncompressedSize) != 0)
- {
- writer.Write(_uncompressedSize);
- }
-
- if ((_zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.CompressedSize) != 0)
- {
- writer.Write(_compressedSize);
- }
-
- if ((_zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.OffsetOfLocalHeader) != 0)
- {
- writer.Write(_offsetOfLocalHeader);
- }
-
- if ((_zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.DiskNumber) != 0)
- {
- writer.Write(_diskNumber);
- }
- }
-
- // This property calculates size of the field on disk (how many bytes need to be allocated on the disk)
- internal override UInt16 Size
- {
- get
- {
- if (SizeField == 0) // we do not need to save this, if it is empty
- {
- return 0;
- }
- else
- {
- return checked((UInt16)(SizeField + MinimumSize));
- }
- }
- }
-
- // This property calculates the value of the size record whch holds the size without the Id and without the size itself.
- // we are always guranteed that Size == SizeField + 2 * sizeof(UInt16))
- internal override UInt16 SizeField
- {
- get
- {
- UInt16 size = 0;
-
- if ((_zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.UncompressedSize) != 0)
- {
- size += sizeof(UInt64);
- }
-
- if ((_zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.CompressedSize) != 0)
- {
- size += sizeof(UInt64);
- }
-
- if ((_zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.OffsetOfLocalHeader) != 0)
- {
- size += sizeof(UInt64);
- }
-
- if ((_zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.DiskNumber) != 0)
- {
- size += sizeof(UInt32);
- }
-
- // If the file contains a blank extra field, we need to correctly indicate that
- // we skipped the data in this field so that the sizes match up in the end.
- if (_ignoredFieldSize.HasValue)
- {
- size += _ignoredFieldSize.Value;
- }
-
- return size;
- }
- }
-
- static internal UInt16 ConstantFieldId
- {
- get
- {
- return _constantFieldId;
- }
- }
-
- internal long UncompressedSize
- {
- get
- {
- // we should never be asked to provide such value, if we do not have it
- Debug.Assert((_zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.UncompressedSize) != 0);
- return (long)_uncompressedSize;
- }
- set
- {
- Debug.Assert(value >= 0);
-
- _zip64ExtraFieldUsage |= ZipIOZip64ExtraFieldUsage.UncompressedSize;
- _uncompressedSize = (UInt64)value;
- }
- }
-
- internal long CompressedSize
- {
- get
- {
- // we should never be asked to provide such value, if we do not have it
- Debug.Assert((_zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.CompressedSize) != 0);
- return (long)_compressedSize;
- }
- set
- {
- Debug.Assert(value >= 0);
-
- _zip64ExtraFieldUsage |= ZipIOZip64ExtraFieldUsage.CompressedSize;
- _compressedSize = (UInt64)value;
- }
- }
-
- internal long OffsetOfLocalHeader
- {
- get
- {
- // we should never be asked to provide such value, if we do not have it
- Debug.Assert((_zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.OffsetOfLocalHeader) != 0);
- return (long)_offsetOfLocalHeader;
- }
- set
- {
- Debug.Assert(value >= 0);
-
- _zip64ExtraFieldUsage |= ZipIOZip64ExtraFieldUsage.OffsetOfLocalHeader;
- _offsetOfLocalHeader = (UInt64)value;
- }
- }
-
- internal UInt32 DiskNumber
- {
- get
- {
- // we should never be asked to provide such value, if we do not have it
- Debug.Assert((_zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.DiskNumber) != 0);
- return _diskNumber;
- }
- // set{} for now we do not need to support set on this property
- // the only reason to set is an attempt to produce multi disk archives
- }
-
- internal ZipIOZip64ExtraFieldUsage Zip64ExtraFieldUsage
- {
- get
- {
- return _zip64ExtraFieldUsage;
- }
- set
- {
- _zip64ExtraFieldUsage = value;
- }
- }
-
- //------------------------------------------------------
- //
- // Private Constructor
- //
- //------------------------------------------------------
- internal ZipIOExtraFieldZip64Element()
- : base(_constantFieldId)
- {
- _zip64ExtraFieldUsage = ZipIOZip64ExtraFieldUsage.None;
- }
-
- //------------------------------------------------------
- //
- // Private Methods
- //
- //------------------------------------------------------
- private void Validate()
- {
- // throw if we got any negative values
- if ((_compressedSize >= Int64.MaxValue) ||
- (_uncompressedSize >= Int64.MaxValue) ||
- (_offsetOfLocalHeader >= Int64.MaxValue))
- {
- throw new NotSupportedException(SR.Get(SRID.Zip64StructuresTooLarge));
- }
-
- // throw if disk number isn't == 0
- if (_diskNumber != 0)
- {
- throw new NotSupportedException(SR.Get(SRID.NotSupportedMultiDisk));
- }
- }
-
- //------------------------------------------------------
- //
- // Private fields
- //
- //------------------------------------------------------
- private const UInt16 _constantFieldId = 0x01;
-
- private UInt64 _uncompressedSize;
- private UInt64 _compressedSize;
- private UInt64 _offsetOfLocalHeader;
- private UInt32 _diskNumber;
-
- // Used for indicating there is an ignored extra field
- private UInt16? _ignoredFieldSize;
-
- private ZipIOZip64ExtraFieldUsage _zip64ExtraFieldUsage;
- }
-}
-
-
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOFileItemStream.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOFileItemStream.cs
deleted file mode 100644
index 98c11634c49..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOFileItemStream.cs
+++ /dev/null
@@ -1,594 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that enables interactions with Zip archives
-// for OPC scenarios
-//
-//
-//
-//
-
-using System;
-using System.IO;
-using System.Diagnostics;
-using System.Text;
-using System.Collections;
-using System.Runtime.Serialization;
-using System.Windows;
-using MS.Internal.IO.Packaging; // for PackagingUtilities
-using MS.Internal.WindowsBase;
-
-namespace MS.Internal.IO.Zip
-{
- internal class ZipIOFileItemStream : Stream
- {
- ////////////////////////////////////
- // Stream section
- /////////////////////////////////
- override public bool CanRead
- {
- get
- {
- return (!_disposedFlag) && (_blockManager.Stream.CanRead);
- }
- }
-
- override public bool CanSeek
- {
- get
- {
- return (!_disposedFlag) && (_blockManager.Stream.CanSeek);
- }
- }
-
- override public bool CanWrite
- {
- get
- {
- return (!_disposedFlag) && (_blockManager.Stream.CanWrite);
- }
- }
-
- override public long Length
- {
- get
- {
- CheckDisposed();
-
- return _currentStreamLength;
- }
- }
-
- override public long Position
- {
- get
- {
- CheckDisposed();
- return _currentStreamPosition;
- }
- set
- {
- CheckDisposed();
- Seek(value, SeekOrigin.Begin);
- }
- }
-
- public override void SetLength(long newLength)
- {
- CheckDisposed();
-
- Debug.Assert(_cachePrefixStream == null); // we only expect this thing to be not null during Archive Save execution
- // that would between PreSaveNotofication call and Save SaveStreaming
-
- if (newLength < 0)
- {
- throw new ArgumentOutOfRangeException("newLength");
- }
-
- if (_currentStreamLength != newLength)
- {
- _dirtyFlag = true;
- _dataChanged = true;
-
- if (newLength <= _persistedSize)
- {
- // the stream becomes smaller than our disk block, which means that
- // we can drop the in-memory-sparse-suffix
- if (_sparseMemoryStreamSuffix != null)
- {
- _sparseMemoryStreamSuffix.Close();
- _sparseMemoryStreamSuffix = null;
- }
- }
- else
- {
- // we need to construct Sparse Memory stream if we do not have one yet
- if (_sparseMemoryStreamSuffix == null)
- {
- _sparseMemoryStreamSuffix = new SparseMemoryStream(_lowWaterMark, _highWaterMark);
- }
-
- // set size on the Sparse Memory Stream
- _sparseMemoryStreamSuffix.SetLength(newLength - _persistedSize); // no need for checked as it was verified above
- }
-
- _currentStreamLength = newLength;
-
- // if stream was truncated to the point that our current position is beyond the end of the stream,
- // we need to reset position so it is at the end of the stream
- if (_currentStreamLength < _currentStreamPosition)
- Seek(_currentStreamLength, SeekOrigin.Begin);
- }
- }
-
- override public long Seek(long offset, SeekOrigin origin)
- {
- CheckDisposed();
-
- Debug.Assert(_cachePrefixStream == null); // we only expect this thing to be not null during Archive Save execution
- // that would between PreSaveNotofication call and Save SaveStreaming
-
- long newStreamPosition = _currentStreamPosition;
-
- if (origin ==SeekOrigin.Begin)
- {
- newStreamPosition = offset;
- }
- else if (origin == SeekOrigin.Current)
- {
- checked{newStreamPosition += offset;}
- }
- else if (origin == SeekOrigin.End)
- {
- checked{newStreamPosition = _currentStreamLength + offset;}
- }
- else
- {
- throw new ArgumentOutOfRangeException("origin");
- }
-
- if (newStreamPosition < 0)
- {
- throw new ArgumentException(SR.Get(SRID.SeekNegative));
- }
- _currentStreamPosition = newStreamPosition;
-
- return _currentStreamPosition;
- }
-
- override public int Read(byte[] buffer, int offset, int count)
- {
- CheckDisposed();
-
- PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count);
-
- Debug.Assert(_cachePrefixStream == null); // we only expect this thing to be not null during Archive Save execution
- // that would between PreSaveNotofication call and Save SaveStreaming
-
- Debug.Assert(_currentStreamPosition >= 0);
-
- if (count == 0)
- {
- return 0;
- }
-
- if (_currentStreamLength <= _currentStreamPosition)
- {
- // we are past the end of the stream so let's just return 0
- return 0;
- }
-
- int totalBytesRead;
- int diskBytesRead = 0;
- int diskBytesToRead = 0;
- long persistedTailSize = 0;
-
- int memoryBytesRead = 0;
- long newStreamPosition = _currentStreamPosition;
-
- checked
- {
- // Try to satisfy request with the Read from the Disk
- if (newStreamPosition < _persistedSize)
- {
- // we have at least partial overlap between request and the data on disk
-
- //first let's get min between size of the stream's tail and the tail of the persisted chunk
- // in some cases stream might be smaller
- // e.g. _currentStreamLength < _persistedSize, if let's say stream was truncated
- persistedTailSize = Math.Min(_currentStreamLength, _persistedSize) - newStreamPosition;
- Debug.Assert(persistedTailSize > 0);
-
- // we also do not want to read more data than was requested by the user
- diskBytesToRead = (int)Math.Min((long)count, persistedTailSize); // this is a safe cast as count has int type
- Debug.Assert(diskBytesToRead > 0);
-
- // and now we can actually read it
- _blockManager.Stream.Seek(_persistedOffset + newStreamPosition, SeekOrigin.Begin);
-
- // we are ready for getting fewer bytes than reqested
- diskBytesRead = _blockManager.Stream.Read(buffer, offset, diskBytesToRead);
-
- newStreamPosition += diskBytesRead;
- count -= diskBytesRead;
- offset +=diskBytesRead;
-
- if (diskBytesRead < diskBytesToRead)
- {
- // we didn't everything that we hae asked for. In such case we shouldn't
- // try to get data from the _sparseMemoryStreamSuffix
- _currentStreamPosition = newStreamPosition;
-
- return diskBytesRead;
- }
- }
-
- // check whether we need to get data from the memory Stream;
- if ((_sparseMemoryStreamSuffix != null) && (newStreamPosition + count > _persistedSize))
- {
- // we are either trying to finish the request partially satisfied by the
- // on disk data or the read is entirely within the suffix
- _sparseMemoryStreamSuffix.Seek(newStreamPosition - _persistedSize, SeekOrigin.Begin);
- memoryBytesRead = _sparseMemoryStreamSuffix.Read(buffer, offset, count);
-
- newStreamPosition += memoryBytesRead;
- }
-
- totalBytesRead = diskBytesRead + memoryBytesRead;
- }
-
- _currentStreamPosition = newStreamPosition;
- return totalBytesRead ;
- }
-
- ///
- /// Write
- ///
- ///
- ///
- ///
- /// In streaming mode, write should accumulate data into the SparseMemoryStream.
- override public void Write(byte[] buffer, int offset, int count)
- {
- CheckDisposed();
-
- PackagingUtilities.VerifyStreamWriteArgs(this, buffer, offset, count);
-
- Debug.Assert(_cachePrefixStream == null); // we only expect this thing to be not null during Archive Save execution
- // that would between PreSaveNotofication call and Save SaveStreaming
-
- Debug.Assert(_currentStreamPosition >= 0);
-
- if (count == 0)
- {
- return;
- }
-
- int diskBytesToWrite = 0;
-
- _dirtyFlag = true;
- _dataChanged = true;
- long newStreamPosition = _currentStreamPosition;
- checked
- {
- // Try to satisfy request with the Write to the Disk
- if (newStreamPosition < _persistedSize)
- {
- Debug.Assert(!_blockManager.Streaming);
-
- // we have at least partial overlap between request and the data on disk
- _blockManager.Stream.Seek(_persistedOffset + newStreamPosition, SeekOrigin.Begin);
- // Note on casting:
- // It is safe to cast the result of Math.Min(count, _persistedSize - newStreamPosition))
- // from long to int since it cannot be bigger than count and count is int type
- diskBytesToWrite = (int) (Math.Min(count, _persistedSize - newStreamPosition)); // this is a safe cast as count has int type
-
- _blockManager.Stream.Write(buffer, offset, diskBytesToWrite);
- newStreamPosition += diskBytesToWrite;
- count -= diskBytesToWrite;
- offset += diskBytesToWrite;
- }
-
- // check whether we need to save data to the memory Stream;
- if (newStreamPosition + count > _persistedSize)
- {
- if (_sparseMemoryStreamSuffix == null)
- {
- _sparseMemoryStreamSuffix = new SparseMemoryStream(_lowWaterMark, _highWaterMark);
- }
-
- _sparseMemoryStreamSuffix.Seek(newStreamPosition - _persistedSize, SeekOrigin.Begin);
-
- _sparseMemoryStreamSuffix.Write(buffer, offset, count);
- newStreamPosition += count;
- }
-
- _currentStreamPosition = newStreamPosition;
- _currentStreamLength = Math.Max(_currentStreamLength, _currentStreamPosition);
- }
- return;
- }
-
- override public void Flush()
- {
- CheckDisposed();
-
- // tell the BlockManager that the caller called Flush on us. Block manager will process this
- // and possibly call us back on Save or SaveStreaming
- _blockManager.SaveStream(_block, false); // second parameter is a closing indicator
- }
-
- /////////////////////////////
- // Internal Constructor
- /////////////////////////////
- internal ZipIOFileItemStream(ZipIOBlockManager blockManager, // blockManager is only needed
- // to pass through to it Flush requests
- ZipIOLocalFileBlock block, // our owning block - needed for Streaming scenarios
- long persistedOffset, // to map to the stream
- long persistedSize) // to map to the stream )
- {
- Debug.Assert(blockManager != null);
- Debug.Assert(persistedOffset >=0);
- Debug.Assert(persistedSize >= 0);
- Debug.Assert(block != null);
-
- _persistedOffset = persistedOffset;
- _offset = persistedOffset;
- _persistedSize = persistedSize;
-
- _blockManager = blockManager;
- _block = block;
-
- _currentStreamLength = persistedSize;
- }
-
- /////////////////////////////
- // Internal Methods for the LocalFileBlock to call in order to know Dirty status and the new size
- /////////////////////////////
- internal PreSaveNotificationScanControlInstruction PreSaveNotification(long offset, long size)
- {
- return ZipIOBlockManager.CommonPreSaveNotificationHandler(
- _blockManager.Stream,
- offset,
- size,
- _persistedOffset,
- Math.Min(_persistedSize, _currentStreamLength), // in case the stream is smaller then our persisted block on
- // disk, there is no need to preserve the meaningless persisted suffix
- ref _cachePrefixStream);
- }
-
- internal bool DirtyFlag
- {
- get
- {
- return _dirtyFlag;
- }
- }
-
- internal bool DataChanged
- {
- get
- {
- return _dataChanged;
- }
- }
-
- internal long Offset
- {
- get
- {
- return _offset;
- }
- }
-
- internal void Move(long shiftSize)
- {
- CheckDisposed();
- if (shiftSize != 0)
- {
- checked{_offset +=shiftSize;}
- _dirtyFlag = true;
- Debug.Assert(_offset >=0);
- }
- }
-
- ///
- /// Streaming-specific variant of Save()
- ///
- /// Writes current data to the underlying stream.
- /// Assumes the stream is in the correct place.
- internal void SaveStreaming()
- {
- CheckDisposed();
-
- Debug.Assert(_cachePrefixStream == null); // _cachePrefixStream must not be used in streaming cases at all
-
- Debug.Assert(_blockManager.Streaming);
-
- if (_dirtyFlag)
- {
- // in streaming cases all the data collected in the _sparseMemoryStreamSuffix
- // and now we can save the SparseMemoryStream
- if (_sparseMemoryStreamSuffix != null)
- {
- _sparseMemoryStreamSuffix.WriteToStream(_blockManager.Stream);
-
- // update so that subsequent MemoryStreams will know where they begin
- checked{_persistedSize += _sparseMemoryStreamSuffix.Length;}
- _sparseMemoryStreamSuffix.Close();
- _sparseMemoryStreamSuffix = null;
- }
-
- _dirtyFlag = false;
- _dataChanged = false;
- }
- }
-
- ///
- /// Save - called by the BlockManager to cause us to Flush to the underlying stream
- ///
- internal void Save()
- {
- CheckDisposed();
- Debug.Assert(!_blockManager.Streaming);
-
- if(_dirtyFlag)
- {
- // we need to move the whole persisted block to the new position
- long moveBlockSourceOffset = _persistedOffset;
-
- // in case the stream is smaller then our persisted block on disk there is
- // no need to move meaningless persisted suffix
- long moveBlockSize = Math.Min(_persistedSize, _currentStreamLength);
-
- long moveBlockTargetOffset = _offset;
-
- long newPersistedSize = 0;
-
- if (_cachePrefixStream != null)
- {
- // if we have something in cache we only should move whatever isn't cached
- checked{moveBlockSourceOffset += _cachePrefixStream.Length;}
- checked{moveBlockTargetOffset += _cachePrefixStream.Length;}
- checked{moveBlockSize -= _cachePrefixStream.Length;}
- Debug.Assert(moveBlockSize >=0);
- }
-
- _blockManager.MoveData(moveBlockSourceOffset, moveBlockTargetOffset, moveBlockSize);
- checked{newPersistedSize += moveBlockSize;}
-
- // only after data on disk was moved it is safe to flush the cached prefix buffer
- if (_cachePrefixStream != null)
- {
- // we need to seek and it is safe to do as we are not in the streaming mode
- _blockManager.Stream.Seek(_offset, SeekOrigin.Begin);
-
- Debug.Assert(_cachePrefixStream.Length > 0); // should be taken care of by the constructor
- // and PreSaveNotification
-
- _cachePrefixStream.WriteToStream(_blockManager.Stream);
- checked{newPersistedSize += _cachePrefixStream.Length;}
-
- // we can free the memory
- _cachePrefixStream.Close();
- _cachePrefixStream = null;
- }
-
-
- // and now we can save the SparseMemoryStream
- if (_sparseMemoryStreamSuffix != null)
- {
- if (_blockManager.Stream.Position != checked (_offset + _persistedSize))
- {
- // we need to seek
- _blockManager.Stream.Seek(_offset + _persistedSize, SeekOrigin.Begin);
- }
- _sparseMemoryStreamSuffix.WriteToStream(_blockManager.Stream);
- checked{newPersistedSize += _sparseMemoryStreamSuffix.Length;}
-
- _sparseMemoryStreamSuffix.Close();
- _sparseMemoryStreamSuffix = null;
- }
-
- _blockManager.Stream.Flush();
-
- // we are not shifted between on disk image and in memory image any more
- _persistedOffset = _offset;
- _persistedSize = newPersistedSize;
-
- Debug.Assert(newPersistedSize == _currentStreamLength);
-
- Debug.Assert(_cachePrefixStream == null); // we only expect this thing to be not null during Archive Save execution
- // after we are saved this field must be clear
-
- _dirtyFlag = false;
- _dataChanged = false;
- }
- }
-
- //------------------------------------------------------
- //
- // Protected Methods
- //
- //------------------------------------------------------
- ///
- /// Dispose(bool)
- ///
- ///
- /// We implement this because we want a consistent experience (essentially Flush our data) if the user chooses to
- /// call Dispose() instead of Close().
- protected override void Dispose(bool disposing)
- {
- try
- {
- if (disposing)
- {
- //streams wrapping this stream shouldn't pass Dispose calls through
- // it is responsibility of the BlockManager or LocalFileBlock (in case of Remove) to call
- // this dispose as appropriate (that is the reason why Flush isn't called here)
-
- // multiple calls are fine - just ignore them
- if (!_disposedFlag)
- {
- if (_sparseMemoryStreamSuffix != null)
- {
- _sparseMemoryStreamSuffix.Close();
- }
-
- if (_cachePrefixStream != null)
- {
- _cachePrefixStream.Close();
- }
- }
- }
- }
- finally
- {
- _sparseMemoryStreamSuffix = null;
- _cachePrefixStream = null;
- _disposedFlag = true;
-
- base.Dispose(disposing);
- }
- }
-
- /////////////////////////////
- // Private Methods
- /////////////////////////////
- private void CheckDisposed()
- {
- if (_disposedFlag)
- {
- throw new ObjectDisposedException(null, SR.Get(SRID.ZipFileItemDisposed));
- }
- }
-
- private ZipIOBlockManager _blockManager;
- private ZipIOLocalFileBlock _block; // our owning block
-
- private long _offset;
- private long _persistedOffset;
- private long _persistedSize;
-
- private SparseMemoryStream _cachePrefixStream;
-
- private bool _dirtyFlag;
- private bool _dataChanged;
-
- //support for Stream methods
- private bool _disposedFlag;
-
- private long _currentStreamLength;
- private long _currentStreamPosition;
-
- private SparseMemoryStream _sparseMemoryStreamSuffix;
-
- private const long _lowWaterMark = 0x19000; // we definately would like to keep everythuing under 100 KB in memory
- private const long _highWaterMark = 0xA00000; // we would like to keep everything over 10 MB on disk
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOLocalFileBlock.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOLocalFileBlock.cs
deleted file mode 100644
index beb08555006..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOLocalFileBlock.cs
+++ /dev/null
@@ -1,921 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that enables interactions with Zip archives
-// for OPC scenarios
-//
-//
-//
-//
-//
-
-using System;
-using System.IO;
-using System.Diagnostics;
-using System.Text;
-using System.Collections;
-using System.Runtime.Serialization;
-using System.Globalization;
-using System.Windows;
-
-using MS.Internal.IO.Packaging; // For CompressStream
-using MS.Internal.WindowsBase;
-
-namespace MS.Internal.IO.Zip
-{
- internal class ZipIOLocalFileBlock : IZipIOBlock, IDisposable
- {
- //------------------------------------------------------
- //
- // Public Properties
- //
- //------------------------------------------------------
- // standard IZipIOBlock functionality
- public long Offset
- {
- get
- {
- CheckDisposed();
- return _offset;
- }
- }
-
- public long Size
- {
- get
- {
- CheckDisposed();
-
- checked
- {
- long size = _localFileHeader.Size + _fileItemStream.Length;
-
- if (_localFileDataDescriptor != null)
- {
- // we only account for the data descriptor
- // if it is there and data wasn't changed yet ,
- // because we will discard it as a part of saving
- size += _localFileDataDescriptor.Size;
- }
-
- return size;
- }
- }
- }
-
- public bool GetDirtyFlag(bool closingFlag)
- {
- CheckDisposed();
-
- bool deflateStreamDirty = false;
- if (_deflateStream != null)
- deflateStreamDirty = ((CompressStream) _deflateStream).IsDirty(closingFlag);
-
- // !!! ATTENTION !!!!
- // We know for a fact that ZipIoModeEnforcingStream doesn't perform any buffering and is never "dirty".
- // In the past we had Dirty flag on the ZipIoModeEnforcing stream that was always false. Enumerating
- // those flags had significant perf cost (allocating all the Enumerator classes). We are removing Dirty flag
- // from the ZipIoModeEnforcingStream and all the processing code associated with that.
- //If at any point we choose to add some buffering to the ZipIoModeEnforcingStream we will have to
- // reintroduce Dirty state/flag and properly account for this value in the ZipIoLocalFileBlock.DirtyFlag.
- return _dirtyFlag || _fileItemStream.DirtyFlag || deflateStreamDirty;
- }
-
- //------------------------------------------------------
- //
- // Public Methods
- //
- //------------------------------------------------------
- public void Move(long shiftSize)
- {
- CheckDisposed();
- Debug.Assert(!_blockManager.Streaming, "Not legal in Streaming mode");
-
- if (shiftSize != 0)
- {
- checked{_offset +=shiftSize;}
- _fileItemStream.Move(shiftSize);
- _dirtyFlag = true;
- Debug.Assert(_offset >=0);
- }
- }
-
- ///
- /// Streaming-specific variant of Save()
- ///
- ///
- internal void SaveStreaming(bool closingFlag)
- {
- CheckDisposed();
-
- Debug.Assert(_blockManager.Streaming, "Only legal in Streaming mode");
-
- if (GetDirtyFlag(closingFlag))
- {
- BinaryWriter writer = _blockManager.BinaryWriter;
-
- // write the local file header if not already done so
- if (!_localFileHeaderSaved)
- {
- // our first access to the ArchiveStream - note our offset
- _offset = _blockManager.Stream.Position;
- _localFileHeader.Save(writer);
- _localFileHeaderSaved = true;
- }
-
- FlushExposedStreams();
-
- //this will cause the actual write to disk, and it safe to do so,
- // because all we're in streaming mode and there is
- // no data in the way
- _fileItemStream.SaveStreaming();
-
- // Data Descriptor required for streaming mode
- if (closingFlag)
- {
- // now prior to possibly closing streams we need to preserve uncompressed Size
- // otherwise Length function will fail to give it to us later after closing
- _localFileDataDescriptor.UncompressedSize = _crcCalculatingStream.Length;
-
- // calculate CRC prior to closing
- _localFileDataDescriptor.Crc32 = _crcCalculatingStream.CalculateCrc();
-
- // If we are closing we can do extra things , calculate CRC , close deflate stream
- // it is particularly important to close the deflate stream as it might hold some extra bytes
- // even after Flush()
-
- // close outstanding streams to signal that we need new pieces if more data comes
- CloseExposedStreams();
-
- // in order to get proper compressed size we have to close the deflate stream
- if (_deflateStream != null)
- {
- _deflateStream.Close();
- _fileItemStream.SaveStreaming(); // get the extra bytes emitted by the DeflateStream
- }
-
- _localFileDataDescriptor.CompressedSize = _fileItemStream.Length;
-
- _localFileDataDescriptor.Save(writer);
- _dirtyFlag = false;
- }
- }
- }
- ///
- /// Save()
- ///
- public void Save()
- {
- CheckDisposed();
- Debug.Assert(!_blockManager.Streaming, "Not legal in Streaming mode");
-
- // Note: This triggers a call to UpdateReferences() which will
- // discard any _localFileDataDescriptor.
- if (GetDirtyFlag(true)) // if we do not have closingFlag value (we should be using closingFlag=true as a more conservative approach)
- {
- // We need to notify the _fileItemStream that we about to save our FileHeader;
- // otherwise we might be overriding some of the FileItemStream data with the
- // FileHeader. Specifically we are concerned about scenario when a previous
- // block become large by just a couple of bytes, so that the PreSaveNotification
- // issued prior to saving the previous block didn�t trigger caching of our FileItemStream,
- // but we still need to make sure that the current FileHeader will not override any data
- // in our FileItemStream.
- _fileItemStream.PreSaveNotification(_offset, _localFileHeader.Size);
-
- //position the stream
- BinaryWriter writer = _blockManager.BinaryWriter;
- if (_blockManager.Stream.Position != _offset)
- {
- // we need to seek
- _blockManager.Stream.Seek(_offset, SeekOrigin.Begin);
- }
-
- _localFileHeader.Save(writer);
-
- //this will cause the actual write to disk, and it safe to do so,
- // because all overlapping data was moved out of the way
- // by the calling BlockManager
- _fileItemStream.Save();
-
- _dirtyFlag = false;
- }
- }
-
-
- // !!! ATTENTION !!!! This function is only supposed to be called by
- // Block Manager.Save which has proper protection to ensure no stack overflow will happen
- // as a result of Stream.Flush calls which in turn result in BlockManager.Save calls
- public void UpdateReferences(bool closingFlag)
- {
- Invariant.Assert(!_blockManager.Streaming);
-
- long uncompressedSize;
- long compressedSize;
-
- CheckDisposed();
-
- if (closingFlag)
- {
- CloseExposedStreams();
- }
- else
- {
- FlushExposedStreams();
- }
-
- // At this point we can update Local Headers with the proper CRC Value
- // We can also update other Local File Header Values (compressed/uncompressed size)
- // we rely on our DirtyFlag property to properly account for all possbile modifications within streams
- if (GetDirtyFlag(closingFlag))
- {
- // Remember the size of the header before update
- long headerSizeBeforeUpdate = _localFileHeader.Size;
-
- // now prior to possibly closing streams we need to preserve uncompressed Size
- // otherwise Length function will fail to give it to us later after closing
- uncompressedSize = _crcCalculatingStream.Length;
-
- // calculate CRC prior to closing
- _localFileHeader.Crc32 = _crcCalculatingStream.CalculateCrc();
-
- // If we are closing we can do extra things , calculate CRC , close deflate stream
- // it is particularly important to close the deflate stream as it might hold some extra bytes
- // even after Flush()
- if (closingFlag)
- {
- // we have got the CRC so we can close the stream
- _crcCalculatingStream.Close();
-
- // in order to get proper compressed size we have to close the deflate stream
- if (_deflateStream != null)
- {
- _deflateStream.Close();
- }
- }
-
- if (_fileItemStream.DataChanged)
- {
- _localFileHeader.LastModFileDateTime = ZipIOBlockManager.ToMsDosDateTime(DateTime.Now);
- }
-
- // get compressed size after possible closing Deflated stream
- // as a result of some ineffeciencies in CRC calculation it might result in Seek in compressed stream
- // and there fore switching mode and flushing extra compressed bytes
- compressedSize = _fileItemStream.Length;
-
- // this will properly (taking into account ZIP64 scenario) update local file header
- // Offset is passed in to determine whether ZIP 64 is required for small files that
- // happened to be located required 32 bit offset in the archive
- _localFileHeader.UpdateZip64Structures(compressedSize, uncompressedSize, Offset);
-
- // Add/remove padding to compensate the header size change
- // NOTE: Padding needs to be updated only after updating all the header fields
- // that can affect the header size
- _localFileHeader.UpdatePadding(_localFileHeader.Size - headerSizeBeforeUpdate);
-
- // We always save File Items in Non-streaming mode unless it wasn't touched
- //in which case we leave them alone
- _localFileHeader.StreamingCreationFlag = false;
- _localFileDataDescriptor = null;
-
- // in some cases UpdateZip64Structures call might result in creation/removal
- // of extra field if such thing happened we need to move FileItemStream appropriatel
- _fileItemStream.Move(checked(Offset + _localFileHeader.Size - _fileItemStream.Offset));
-
- _dirtyFlag = true;
- }
-#if FALSE
- // we would like to take this oppportunity and validate basic asumption
- // that our GetDirtyFlag method is a reliable way to finding changes
- // there is no scenario in which change will happened, affecting sizes
- // and will not be registered by the GetDirtyFlag
- // ???????????????????????
- else
- {
- // we even willing to recalculate CRC just in case for verification purposes
-
- UInt32 calculatedCRC32 = CalculateCrc32();
- if (!_localFileHeader.StreamingCreationFlag)
- {
- Debug.Assert(_localFileHeader.Crc32 == calculatedCRC32);
- Debug.Assert(_localFileHeader.CompressedSize == CompressedSize);
- Debug.Assert(_localFileHeader.UncompressedSize == UncompressedSize);
- }
- else
- {
- Debug.Assert(_localFileDataDescriptor.Crc32 == calculatedCRC32);
- Debug.Assert(_localFileDataDescriptor.CompressedSize == CompressedSize);
- Debug.Assert(_localFileDataDescriptor.UncompressedSize == UncompressedSize);
- }
-
-///////////////////////////////////////////////////////////////////////
-
- // we do not have an initialized value for the compressed size in this case
- compressedSize = _fileItemStream.Length;
-
- Debug.Assert(CompressedSize == compressedSize);
- Debug.Assert(UncompressedSize == uncompressedSize);
- }
-#endif
- }
-
- public PreSaveNotificationScanControlInstruction PreSaveNotification(long offset, long size)
- {
- CheckDisposed();
-
- // local file header and data descryptor are completely cached
- // we only need to worry about the actual data
- return _fileItemStream.PreSaveNotification(offset, size);
- }
-
- ///
- /// Dispose pattern - required implementation for classes that introduce IDisposable
- ///
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this); // not strictly necessary, but if we ever have a subclass with a finalizer, this will be more efficient
- }
-
- //------------------------------------------------------
- //
- // Internal Methods
- //
- //------------------------------------------------------
- internal static ZipIOLocalFileBlock SeekableLoad (ZipIOBlockManager blockManager,
- string fileName)
- {
- Debug.Assert(!blockManager.Streaming);
- Debug.Assert(blockManager.CentralDirectoryBlock.FileExists(fileName));
-
- // Get info from the central directory
- ZipIOCentralDirectoryBlock centralDir = blockManager.CentralDirectoryBlock;
- ZipIOCentralDirectoryFileHeader centralDirFileHeader = centralDir.GetCentralDirectoryFileHeader(fileName);
-
- long localHeaderOffset = centralDirFileHeader.OffsetOfLocalHeader;
- bool folderFlag = centralDirFileHeader.FolderFlag;
- bool volumeLabelFlag = centralDirFileHeader.VolumeLabelFlag;
-
- blockManager.Stream.Seek(localHeaderOffset, SeekOrigin.Begin);
-
- ZipIOLocalFileBlock block = new ZipIOLocalFileBlock(blockManager, folderFlag, volumeLabelFlag);
-
- block.ParseRecord(
- blockManager.BinaryReader,
- fileName,
- localHeaderOffset,
- centralDir,
- centralDirFileHeader);
-
- return block;
- }
-
- internal static ZipIOLocalFileBlock CreateNew(ZipIOBlockManager blockManager,
- string fileName,
- CompressionMethodEnum compressionMethod,
- DeflateOptionEnum deflateOption)
- {
- //this should be ensured by the higher levels
- Debug.Assert(Enum.IsDefined(typeof(CompressionMethodEnum), compressionMethod));
- Debug.Assert(Enum.IsDefined(typeof(DeflateOptionEnum), deflateOption));
-
- ZipIOLocalFileBlock block = new ZipIOLocalFileBlock(blockManager, false, false);
-
- block._localFileHeader = ZipIOLocalFileHeader.CreateNew
- (fileName,
- blockManager.Encoding,
- compressionMethod,
- deflateOption, blockManager.Streaming);
-
- // if in streaming mode - force to Zip64 mode in case the streams get large
- if (blockManager.Streaming)
- {
- block._localFileDataDescriptor = ZipIOLocalFileDataDescriptor.CreateNew();
- }
-
- block._offset = 0; // intial value, that is not too important for the brand new File item
- block._dirtyFlag = true;
-
- block._fileItemStream = new ZipIOFileItemStream(blockManager,
- block,
- block._offset + block._localFileHeader.Size,
- 0);
-
- // create deflate wrapper if necessary
- if (compressionMethod == CompressionMethodEnum.Deflated)
- {
- Debug.Assert(block._fileItemStream.Position == 0, "CompressStream assumes base stream is at position zero");
- // Pass bool to indicate that this stream is "new" and must be dirty so that
- // the valid empty deflate stream is emitted (2-byte sequence - see CompressStream for details).
- block._deflateStream = new CompressStream(block._fileItemStream, 0, true);
-
- block._crcCalculatingStream = new ProgressiveCrcCalculatingStream(blockManager, block._deflateStream);
- }
- else
- {
- block._crcCalculatingStream = new ProgressiveCrcCalculatingStream(blockManager, block._fileItemStream);
- }
-
- return block;
- }
-
- internal Stream GetStream(FileMode mode, FileAccess access)
- {
- CheckDisposed();
-
- // the main stream held by block Manager must be compatible with the request
- CheckFileAccessParameter(_blockManager.Stream, access);
-
- // validate mode and Access
- switch(mode)
- {
- case FileMode.Create:
- // Check to make sure that stream isn't read only
- if (!_blockManager.Stream.CanWrite)
- {
- throw new InvalidOperationException(SR.Get(SRID.CanNotWriteInReadOnlyMode));
- }
-
- if (_crcCalculatingStream != null && !_blockManager.Streaming)
- {
- _crcCalculatingStream.SetLength(0);
- }
- break;
- case FileMode.Open:
- break;
- case FileMode.OpenOrCreate:
- break;
- case FileMode.CreateNew:
- // because we deal with the GetStream call CreateNew is a really strange
- // request, as the FileInfo is already there
- throw new ArgumentException(SR.Get(SRID.FileModeUnsupported, "CreateNew"));
- case FileMode.Append:
- throw new ArgumentException(SR.Get(SRID.FileModeUnsupported, "Append"));
- case FileMode.Truncate:
- throw new ArgumentException(SR.Get(SRID.FileModeUnsupported, "Truncate"));
- default:
- throw new ArgumentOutOfRangeException("mode");
- }
-
- // Streaming mode: always return the same stream (if it exists already)
- Stream exposedStream;
- if (_blockManager.Streaming && _exposedPublicStreams != null && _exposedPublicStreams.Count > 0)
- {
- Debug.Assert(_exposedPublicStreams.Count == 1, "Should only be one stream returned in streaming mode");
- exposedStream = (Stream)_exposedPublicStreams[0];
- }
- else
- {
- Debug.Assert((!_blockManager.Streaming) || (_exposedPublicStreams == null),
- "Should be first and only stream returned in streaming mode");
-
- exposedStream = new ZipIOModeEnforcingStream(_crcCalculatingStream, access, _blockManager, this);
-
- RegisterExposedStream(exposedStream);
- }
-
-
- return exposedStream;
- }
-
-
- // NOTE: This method should NOT be called anywhere else except from ZipIOModeEnforcingStream.Dispose(bool)
- // This is not designed to be the part of the cyclic process of flushing
- internal void DeregisterExposedStream(Stream exposedStream)
- {
- Debug.Assert(_exposedPublicStreams != null);
-
- _exposedPublicStreams.Remove(exposedStream);
- }
-
- ///
- /// Throwes exception if object already Disposed/Closed. This is the only internal
- /// (and not private CheckDisposed method). It ismade internal for ZipFileInfo to call
- ///
- internal void CheckDisposed()
- {
- if (_disposedFlag)
- {
- throw new ObjectDisposedException(null, SR.Get(SRID.ZipFileItemDisposed));
- }
- }
-
- //------------------------------------------------------
- //
- // Internal Properties
- //
- //------------------------------------------------------
- internal UInt16 VersionNeededToExtract
- {
- get
- {
- CheckDisposed();
-
- return _localFileHeader.VersionNeededToExtract;
- }
- }
-
- internal UInt16 GeneralPurposeBitFlag
- {
- get
- {
- CheckDisposed();
-
- return _localFileHeader.GeneralPurposeBitFlag;
- }
- }
-
- internal CompressionMethodEnum CompressionMethod
- {
- get
- {
- CheckDisposed();
-
- return _localFileHeader.CompressionMethod;
- }
- }
-
- internal UInt32 LastModFileDateTime
- {
- get
- {
- CheckDisposed();
-
- return _localFileHeader.LastModFileDateTime;
- }
- }
-
- ///
- /// Return stale CRC value stored in the header.
- /// This property doesn't flush streams nor does it recalculates CRC BY DESIGN
- /// all updates and revcalculations should be made as a part of the UpdateReferences function
- /// which is called by the BlockManager.Save
- ///
- internal UInt32 Crc32
- {
- get
- {
- CheckDisposed();
-
- if (_localFileHeader.StreamingCreationFlag)
- {
- Invariant.Assert(_localFileDataDescriptor != null);
- return _localFileDataDescriptor.Crc32;
- }
- else
- {
- return _localFileHeader.Crc32;
- }
- }
- }
-
- ///
- /// Return stale Compressed Size based on the local file header
- /// This property doesn't flush streams, so it is possible that
- /// this value will be out of date if Updatereferences isn't
- /// called before getting this property
- ///
- internal long CompressedSize
- {
- get
- {
- CheckDisposed();
-
- if (_localFileHeader.StreamingCreationFlag)
- {
- Invariant.Assert(_localFileDataDescriptor != null);
- return _localFileDataDescriptor.CompressedSize;
- }
- else
- {
- return _localFileHeader.CompressedSize;
- }
- }
- }
-
- ///
- /// Return possibly stale Uncompressed Size based on the local file header
- /// This property doesn't flush streams, so it is possible that
- /// this value will be out of date if Updatereferences isn't
- /// called before getting this property
- ///
- internal long UncompressedSize
- {
- get
- {
- CheckDisposed();
-
- if (_localFileHeader.StreamingCreationFlag)
- {
- Invariant.Assert(_localFileDataDescriptor != null);
- return _localFileDataDescriptor.UncompressedSize;
- }
- else
- {
- return _localFileHeader.UncompressedSize;
- }
- }
- }
-
- internal DeflateOptionEnum DeflateOption
- {
- get
- {
- CheckDisposed();
- return _localFileHeader.DeflateOption;
- }
- }
-
- internal string FileName
- {
- get
- {
- CheckDisposed();
- return _localFileHeader.FileName;
- }
- }
-
- internal bool FolderFlag
- {
- get
- {
- CheckDisposed();
- return _folderFlag;
- }
- }
-
- internal bool VolumeLabelFlag
- {
- get
- {
- CheckDisposed();
- return _volumeLabelFlag;
- }
- }
-
- //------------------------------------------------------
- //
- // Protected Methods
- //
- //------------------------------------------------------
- ///
- /// Dispose(bool)
- ///
- ///
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- // multiple calls are fine - just ignore them
- if (!_disposedFlag)
- {
- try
- {
- // close all the public streams that have been exposed
- CloseExposedStreams();
-
- _crcCalculatingStream.Close();
-
- if (_deflateStream != null)
- _deflateStream.Close();
-
- _fileItemStream.Close();
- }
- finally
- {
- _disposedFlag = true;
- _crcCalculatingStream = null;
- _deflateStream = null;
- _fileItemStream = null;
- }
- }
- }
- }
-
- //------------------------------------------------------
- //
- // Private Methods
- //
- //------------------------------------------------------
- private ZipIOLocalFileBlock(ZipIOBlockManager blockManager,
- bool folderFlag,
- bool volumeLabelFlag)
- {
- _blockManager = blockManager;
- _folderFlag = folderFlag;
- _volumeLabelFlag = volumeLabelFlag;
- }
-
- private void ParseRecord (BinaryReader reader,
- string fileName,
- long position,
- ZipIOCentralDirectoryBlock centralDir,
- ZipIOCentralDirectoryFileHeader centralDirFileHeader)
- {
- CheckDisposed();
- Debug.Assert(!_blockManager.Streaming, "Not legal in Streaming mode");
-
- _localFileHeader = ZipIOLocalFileHeader.ParseRecord(reader, _blockManager.Encoding);
-
- // Let's find out whether local file descriptor is there or not
- if (_localFileHeader.StreamingCreationFlag)
- {
- // seek forward by the uncompressed size
- _blockManager.Stream.Seek(centralDirFileHeader.CompressedSize, SeekOrigin.Current);
- _localFileDataDescriptor = ZipIOLocalFileDataDescriptor.ParseRecord(reader,
- centralDirFileHeader.CompressedSize,
- centralDirFileHeader.UncompressedSize,
- centralDirFileHeader.Crc32,
- _localFileHeader.VersionNeededToExtract);
- }
- else
- {
- _localFileDataDescriptor = null;
- }
-
- _offset = position;
- _dirtyFlag = false;
-
- checked
- {
- _fileItemStream = new ZipIOFileItemStream(_blockManager,
- this,
- position + _localFileHeader.Size,
- centralDirFileHeader.CompressedSize);
- }
-
- // init deflate stream if necessary
- if ((CompressionMethodEnum)_localFileHeader.CompressionMethod == CompressionMethodEnum.Deflated)
- {
- Debug.Assert(_fileItemStream.Position == 0, "CompressStream assumes base stream is at position zero");
- _deflateStream = new CompressStream(_fileItemStream, centralDirFileHeader.UncompressedSize);
-
- _crcCalculatingStream = new ProgressiveCrcCalculatingStream(_blockManager, _deflateStream, Crc32);
- }
- else if ((CompressionMethodEnum)_localFileHeader.CompressionMethod == CompressionMethodEnum.Stored)
- {
- _crcCalculatingStream = new ProgressiveCrcCalculatingStream(_blockManager, _fileItemStream, Crc32);
- }
- else
- {
- throw new NotSupportedException(SR.Get(SRID.ZipNotSupportedCompressionMethod));
- }
-
- Validate(fileName, centralDir, centralDirFileHeader);
-}
-
- ///
- /// Validate
- ///
- /// pre-trimmed and normalized filename (see ValidateNormalizeFileName)
- /// central directory block
- /// file header from central directory
- private void Validate(string fileName,
- ZipIOCentralDirectoryBlock centralDir,
- ZipIOCentralDirectoryFileHeader centralDirFileHeader)
- {
- // check that name matches parameter in a case sensitive culture neutral way
- if (0 != String.CompareOrdinal(_localFileHeader.FileName, fileName))
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- // compare compressed and uncompressed sizes, crc from central directory
- if ((VersionNeededToExtract != centralDirFileHeader.VersionNeededToExtract) ||
- (GeneralPurposeBitFlag != centralDirFileHeader.GeneralPurposeBitFlag) ||
- (CompressedSize != centralDirFileHeader.CompressedSize) ||
- (UncompressedSize != centralDirFileHeader.UncompressedSize) ||
- (CompressionMethod != centralDirFileHeader.CompressionMethod) ||
- (Crc32 != centralDirFileHeader.Crc32))
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- // check for read into central directory (which would indicate file corruption)
- if (Offset + Size > centralDir.Offset)
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
-
- // No CRC check here
- // delay validating the actual CRC until it is possible to do so without additional read operations
- // This is only for non-streaming mode (at this point we only support creation not consumption)
- // This is to avoid the forced reading of entire stream just for CRC check
- // CRC check is delegated to ProgressiveCrcCalculatingStream and CRC is only validated
- // once calculated CRC is available. This implies that CRC check operation is not
- // guaranteed to be performed
- }
-
- static private void CheckFileAccessParameter(Stream stream, FileAccess access)
- {
- switch(access)
- {
- case FileAccess.Read:
- if (!stream.CanRead)
- {
- throw new ArgumentException (SR.Get(SRID.CanNotReadInWriteOnlyMode));
- }
- break;
- case FileAccess.Write:
- if (!stream.CanWrite)
- {
- throw new ArgumentException (SR.Get(SRID.CanNotWriteInReadOnlyMode));
- }
- break;
- case FileAccess.ReadWrite:
- if (!stream.CanRead || !stream.CanWrite)
- {
- throw new ArgumentException (SR.Get(SRID.CanNotReadWriteInReadOnlyWriteOnlyMode));
- }
- break;
- default:
- throw new ArgumentOutOfRangeException ("access");
- }
- }
-
- private void RegisterExposedStream(Stream exposedStream)
- {
- if (_exposedPublicStreams == null)
- {
- _exposedPublicStreams = new ArrayList(_initialExposedPublicStreamsCollectionSize);
- }
- _exposedPublicStreams.Add(exposedStream);
- }
-
- private void CloseExposedStreams()
- {
- if (_exposedPublicStreams != null)
- {
- for (int i = _exposedPublicStreams.Count - 1; i >= 0; i--)
- {
- ZipIOModeEnforcingStream exposedStream =
- (ZipIOModeEnforcingStream)_exposedPublicStreams[i];
-
- exposedStream.Close();
- }
- }
- }
-
- private void FlushExposedStreams()
- {
- // !!! ATTENTION !!!!
- // We know for a fact that ZipIoModeEnforcingStream doesn't perform any buffering and is never "dirty";
- // therefore, there is no need to flush them. Enumerating and flashing those streams has some non-trivial
- // perf costs. Instead, it is much cheaper to flush the CrcCalculatingStream.
- // If at any point we choose to add some buffering to the ZipIoModeEnforcingStream we will have to flush
- // all of the _exposedPublicStreams in this method.
- _crcCalculatingStream.Flush();
-
-
- // We are going to walk through the exposed streams and if we can not find any stream that isn't Disposed yet
- // we will switch deflate stream into Start Mode, by doing this we will achieve 2 goals:
- // 1. Relieve Memory Pressure in the Sparse Memory Stream
- // 2. Close Deflate stream in the write through mode and get the tail bytes (we can only get them if
- // we close Deflate stream). This way we can make the disk layout of the File Items that are closed final.
- if ((_deflateStream != null) &&
- (!_localFileHeader.StreamingCreationFlag))
- {
- if ((_exposedPublicStreams == null) ||(_exposedPublicStreams.Count == 0))
- {
- ((CompressStream)_deflateStream).Reset();
- }
- }
- }
-
- private const int _initialExposedPublicStreamsCollectionSize= 5;
-
- private ZipIOFileItemStream _fileItemStream;
- private Stream _deflateStream; // may be null - only used if stream is Deflated
- // _crcCalculatingStream is used to do optimal CRC calcuation when it is possible.
- // This stream can wrap either _fileItemStream or _deflateStream
- // For CRC to be calculated correctly, all regualar stream operations have to
- // go through this stream. This means file item streams we hand out to a client
- // need to be wrapped as ProgressiveCrcCalculatingStream.
- // Any other operations specific to ZipIOFileItemStream or DeflateStream should
- // be directed to those streams.
- private ProgressiveCrcCalculatingStream _crcCalculatingStream;
- private ArrayList _exposedPublicStreams;
-
- private ZipIOLocalFileHeader _localFileHeader = null;
- private bool _localFileHeaderSaved; // only used in Streaming mode
- private ZipIOLocalFileDataDescriptor _localFileDataDescriptor = null;
-
- private ZipIOBlockManager _blockManager;
-
- private long _offset;
-
- // This is a shallow dirtyFlag which doesn't account for the substructures
- // (ModeEnforcing Streams, compression stream FileItem Stream )
- // GetDirtyFlag method is supposed to be used everywhere where a
- // complete (deep ; non-shallow) check for "dirty" is required;
- private bool _dirtyFlag;
-
- private bool _disposedFlag = false;
-
- private bool _folderFlag = false;
- private bool _volumeLabelFlag = false;
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOLocalFileDataDescriptor.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOLocalFileDataDescriptor.cs
deleted file mode 100644
index a8f6c860ea0..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOLocalFileDataDescriptor.cs
+++ /dev/null
@@ -1,249 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that enables interactions with Zip archives
-// for OPC scenarios
-//
-//
-//
-//
-
-using System;
-using System.IO;
-using System.Diagnostics;
-using System.Text;
-using System.Collections;
-using System.Windows;
-using MS.Internal.WindowsBase;
-
-namespace MS.Internal.IO.Zip
-{
- internal class ZipIOLocalFileDataDescriptor
- {
- // used in streaming case
- internal static ZipIOLocalFileDataDescriptor CreateNew()
- {
- ZipIOLocalFileDataDescriptor descriptor = new ZipIOLocalFileDataDescriptor();
- descriptor._size = _fixedMinimalRecordSizeWithSignatureZip64;
-
- return descriptor;
- }
-
- internal static ZipIOLocalFileDataDescriptor ParseRecord(BinaryReader reader,
- long compressedSizeFromCentralDir,
- long uncompressedSizeFromCentralDir,
- UInt32 crc32FromCentralDir,
- UInt16 versionNeededToExtract)
- {
- ZipIOLocalFileDataDescriptor descriptor = new ZipIOLocalFileDataDescriptor();
-
- // There are 4 distinct scenario we would like to support
- // 1.based on the appnote it seems that the structure of this record is following:
- // crc-32 4 bytes
- // compressed size 4 bytes (scenario 1.a has 8 bytes)
- // uncompressed size 4 bytes (scenario 1.a has 8 bytes)
- //
- // 2.based on files that we have been able to examine
- // data descriptor signature 4 bytes (0x08074b50)
- // crc-32 4 bytes
- // compressed size 4 bytes (scenario 2.a has 8 bytes)
- // uncompressed size 4 bytes (scenario 2.a has 8 bytes)
- //
- // we can safely assume that this record is not the last one in the file, so let's just
- // read the max Bytes required to store the largest structure , and compare results
-
- // at most we are looking at 6 * 4 = 24 bytes
- UInt32[] buffer = new UInt32[6];
-
- // let's try to match the smallest possible structure (3 x 4) 32 bit without signature
- buffer[0] = reader.ReadUInt32();
- buffer[1] = reader.ReadUInt32();
- buffer[2] = reader.ReadUInt32();
-
- if (descriptor.TestMatch(_signatureConstant,
- crc32FromCentralDir,
- compressedSizeFromCentralDir,
- uncompressedSizeFromCentralDir,
- _signatureConstant,
- buffer[0],
- buffer[1],
- buffer[2]))
- {
- descriptor._size = _fixedMinimalRecordSizeWithoutSignature;
- return descriptor;
- }
-
- // let's try to match the next record size (4 x 4) 32 bit with signature
- buffer[3] = reader.ReadUInt32();
- if (descriptor.TestMatch(_signatureConstant,
- crc32FromCentralDir,
- compressedSizeFromCentralDir,
- uncompressedSizeFromCentralDir,
- buffer[0],
- buffer[1],
- buffer[2],
- buffer[3]))
- {
- descriptor._size = _fixedMinimalRecordSizeWithSignature;
- return descriptor;
- }
-
- // At this point prior to trying to match 64 bit structures we need to make sure that version is high enough
- if (versionNeededToExtract < (UInt16)ZipIOVersionNeededToExtract.Zip64FileFormat)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- //let's try to match the 64 bit structures 64 bit without signature
- buffer[4] = reader.ReadUInt32();
- if (descriptor.TestMatch(_signatureConstant,
- crc32FromCentralDir,
- compressedSizeFromCentralDir,
- uncompressedSizeFromCentralDir,
- _signatureConstant,
- buffer[0],
- ZipIOBlockManager.ConvertToUInt64(buffer[1], buffer[2]),
- ZipIOBlockManager.ConvertToUInt64(buffer[3], buffer[4])))
- {
- descriptor._size = _fixedMinimalRecordSizeWithoutSignatureZip64;
- return descriptor;
- }
-
- //let's try to match the 64 bit structures 64 bit with signature
- buffer[5] = reader.ReadUInt32();
- if (descriptor.TestMatch(_signatureConstant,
- crc32FromCentralDir,
- compressedSizeFromCentralDir,
- uncompressedSizeFromCentralDir,
- buffer[0],
- buffer[1],
- ZipIOBlockManager.ConvertToUInt64(buffer[2], buffer[3]),
- ZipIOBlockManager.ConvertToUInt64(buffer[4], buffer[5])))
- {
- descriptor._size = _fixedMinimalRecordSizeWithSignatureZip64;
- return descriptor;
- }
-
- // we couldn't match anything at this point we need to fail
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- ///
- /// Save - persist to given binary writer
- ///
- ///
- internal void Save(BinaryWriter writer)
- {
- // we only supposed to be saving a brand new record which is created with signature in Zip64 Mode
- // this only supported for streaming publishing cases.
- // For editing scenarios we never save them (not even preserve them), as any editing (even trivial moving of record around)
- // will result in switching File Item to a non-streaming mode without data desciptor
- Invariant.Assert(_size == _fixedMinimalRecordSizeWithSignatureZip64);
-
- // always persist Zip64 version signature
- writer.Write(_signatureConstant); // this is apparently optional, but omitting it causes wzzip to complain
- writer.Write(_crc32);
- writer.Write((UInt64)_compressedSize); // 8 bytes
- writer.Write((UInt64)_uncompressedSize); // 8 bytes
- }
-
- internal long Size
- {
- get
- {
- return _size;
- }
- }
-
- internal UInt32 Crc32
- {
- get
- {
- return _crc32;
- }
- set
- {
- _crc32 = value;
- }
- }
-
- internal long CompressedSize
- {
- get
- {
- return _compressedSize;
- }
- set
- {
- Invariant.Assert((value >= 0), "CompressedSize must be non-negative");
-
- _compressedSize = value;
- }
- }
-
- internal long UncompressedSize
- {
- get
- {
- return _uncompressedSize;
- }
- set
- {
- Invariant.Assert((value >= 0), "UncompressedSize must be non-negative");
-
- _uncompressedSize = value;
- }
- }
-
-
- private bool TestMatch(UInt32 signature,
- UInt32 crc32FromCentralDir,
- long compressedSizeFromCentralDir,
- long uncompressedSizeFromCentralDir,
- UInt32 suspectSignature,
- UInt32 suspectCrc32,
- UInt64 suspectCompressedSize,
- UInt64 suspectUncompressedSize)
- {
- checked
- {
- // Don't compare compressedSize and uncompressedSize as long since the sniffed
- // bytes might not be the actual match and can be bigger than Int64.MaxValue
- // Convert them as long only if it is a match
- if ((signature == suspectSignature) &&
- ((UInt64) compressedSizeFromCentralDir == suspectCompressedSize) &&
- ((UInt64) uncompressedSizeFromCentralDir == suspectUncompressedSize) &&
- (crc32FromCentralDir == suspectCrc32))
- {
- _signature = suspectSignature;
- _compressedSize = (long) suspectCompressedSize;
- _uncompressedSize = (long) suspectUncompressedSize;
- _crc32 = suspectCrc32;
- return true;
- }
- else
- {
- return false;
- }
- }
- }
-
- private const UInt32 _signatureConstant = 0x08074b50;
- private const int _fixedMinimalRecordSizeWithoutSignature = 12;
- private const int _fixedMinimalRecordSizeWithSignature = 16;
- private const int _fixedMinimalRecordSizeWithoutSignatureZip64 = 20;
- private const int _fixedMinimalRecordSizeWithSignatureZip64 = 24;
-
- private int _size;
-
- private UInt32 _signature = _signatureConstant;
- private UInt32 _crc32;
- private long _compressedSize = 0;
- private long _uncompressedSize = 0;
-}
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOLocalFileHeader.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOLocalFileHeader.cs
deleted file mode 100644
index 45d297b7277..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOLocalFileHeader.cs
+++ /dev/null
@@ -1,434 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that enables interactions with Zip archives
-// for OPC scenarios
-//
-//
-//
-//
-
-using System;
-using System.IO;
-using System.Diagnostics;
-using System.Text;
-using System.Collections;
-using System.Runtime.Serialization;
-using System.Windows;
-using MS.Internal.WindowsBase;
-
-namespace MS.Internal.IO.Zip
-{
- internal class ZipIOLocalFileHeader
- {
- ///
- /// Create a new LocalFileHeader
- ///
- ///
- ///
- ///
- ///
- /// true if in streaming mode
- ///
- internal static ZipIOLocalFileHeader CreateNew(string fileName, Encoding encoding,
- CompressionMethodEnum compressionMethod, DeflateOptionEnum deflateOption, bool streaming)
- {
- //this should be ensured by the higher levels
- Debug.Assert(Enum.IsDefined(typeof(CompressionMethodEnum), compressionMethod));
- Debug.Assert(Enum.IsDefined(typeof(DeflateOptionEnum), deflateOption));
-
- byte[] asciiName = encoding.GetBytes(fileName);
- if (asciiName.Length > ZipIOBlockManager.MaxFileNameSize)
- {
- throw new ArgumentOutOfRangeException("fileName");
- }
-
- ZipIOLocalFileHeader header = new ZipIOLocalFileHeader();
- header._signature = ZipIOLocalFileHeader._signatureConstant;
- header._compressionMethod = (ushort)compressionMethod;
-
- if (streaming)
- header._versionNeededToExtract = (UInt16)ZipIOVersionNeededToExtract.Zip64FileFormat;
- else
- {
- header._versionNeededToExtract = (UInt16)ZipIOBlockManager.CalcVersionNeededToExtractFromCompression(
- compressionMethod);
- }
-
- if (compressionMethod != CompressionMethodEnum.Stored)
- {
- Debug.Assert(deflateOption != DeflateOptionEnum.None); //this should be ensured by the higher levels
- header.DeflateOption = deflateOption;
- }
-
- if (streaming)
- {
- // set bit 3
- header.StreamingCreationFlag = true;
- }
-
- header._lastModFileDateTime = ZipIOBlockManager.ToMsDosDateTime(DateTime.Now);
-
- header._fileNameLength = (UInt16)asciiName.Length;
-
- header._fileName = asciiName;
- header._extraField = ZipIOExtraField.CreateNew(!streaming /* creating padding if it is not in streaming creation mode */);
- header._extraFieldLength = header._extraField.Size;
-
- //populate frequently used field with user friendly data representations
- header._stringFileName = fileName;
-
- return header;
- }
-
- internal static ZipIOLocalFileHeader ParseRecord(BinaryReader reader, Encoding encoding)
- {
- ZipIOLocalFileHeader header = new ZipIOLocalFileHeader();
-
- header._signature = reader.ReadUInt32();
- header._versionNeededToExtract = reader.ReadUInt16();
- header._generalPurposeBitFlag = reader.ReadUInt16();
- header._compressionMethod = reader.ReadUInt16();
- header._lastModFileDateTime = reader.ReadUInt32();
- header._crc32 = reader.ReadUInt32();
- header._compressedSize = reader.ReadUInt32();
- header._uncompressedSize = reader.ReadUInt32();
- header._fileNameLength = reader.ReadUInt16();
- header._extraFieldLength = reader.ReadUInt16();
-
- header._fileName = reader.ReadBytes(header._fileNameLength);
-
- // check for the ZIP 64 version and escaped values
- ZipIOZip64ExtraFieldUsage zip64extraFieldUsage = ZipIOZip64ExtraFieldUsage.None;
- if (header._versionNeededToExtract >= (ushort)ZipIOVersionNeededToExtract.Zip64FileFormat)
- {
- if (header._compressedSize == UInt32.MaxValue)
- {
- zip64extraFieldUsage |= ZipIOZip64ExtraFieldUsage.CompressedSize;
- }
- if (header._uncompressedSize == UInt32.MaxValue)
- {
- zip64extraFieldUsage |= ZipIOZip64ExtraFieldUsage.UncompressedSize;
- }
- }
-
- // if the ZIP 64 record is missing from the Extra Field then the zip64extraFieldUsage
- // value will be ignored and default ZipIOZip64ExtraFieldUsage.None value will be used/assumed
- header._extraField = ZipIOExtraField.ParseRecord(reader,
- zip64extraFieldUsage,
- header._extraFieldLength);
-
- //populate frequently used field with user friendly data representations
- header._stringFileName = ZipIOBlockManager.ValidateNormalizeFileName(encoding.GetString(header._fileName));
-
- header.Validate();
-
- return header;
- }
-
- internal void Save(BinaryWriter writer)
- {
- writer.Write(_signatureConstant);
- writer.Write(_versionNeededToExtract);
- writer.Write(_generalPurposeBitFlag);
- writer.Write(_compressionMethod);
- writer.Write(_lastModFileDateTime);
- writer.Write(_crc32);
- writer.Write(_compressedSize);
- writer.Write(_uncompressedSize);
- writer.Write(_fileNameLength);
- writer.Write(_extraField.Size);
-
- if (_fileNameLength > 0)
- {
- writer.Write(_fileName, 0, _fileNameLength);
- }
-
- _extraField.Save(writer);
-
- writer.Flush();
- }
-
- internal UInt16 VersionNeededToExtract
- {
- get
- {
- return _versionNeededToExtract;
- }
- }
-
- internal UInt16 GeneralPurposeBitFlag
- {
- get
- {
- return _generalPurposeBitFlag;
- }
- }
-
- internal CompressionMethodEnum CompressionMethod
- {
- get
- {
- return (CompressionMethodEnum)_compressionMethod;
- }
- }
-
- internal UInt32 LastModFileDateTime
- {
- get
- {
- return _lastModFileDateTime;
- }
- set
- {
- _lastModFileDateTime = value;
- }
- }
-
- internal UInt32 Crc32
- {
- get
- {
- return _crc32;
- }
- set
- {
- _crc32 = value;
- }
- }
-
- internal long CompressedSize
- {
- get
- {
- if ((_extraField.Zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.CompressedSize) != 0)
- {
- // zip 64 extra field is there
- return _extraField.CompressedSize;
- }
- else
- {
- // 32 bit case
- return _compressedSize;
- }
- }
- }
-
- internal long UncompressedSize
- {
- get
- {
- if ((_extraField.Zip64ExtraFieldUsage & ZipIOZip64ExtraFieldUsage.UncompressedSize) != 0)
- {
- // zip 64 extra field is there
- return _extraField.UncompressedSize;
- }
- else
- {
- // 32 bit case
- return _uncompressedSize;
- }
- }
- }
-
- ///
- /// FileName - already scrubbed via ValidateNormalizeFileName()
- ///
- internal string FileName
- {
- get
- {
- return _stringFileName;
- }
- }
-
- internal long Size
- {
- get
- {
- return checked(_fixedMinimalRecordSize + _fileNameLength + _extraField.Size);
- }
- }
-
- internal bool StreamingCreationFlag
- {
- get
- {
- return ((_generalPurposeBitFlag & 0x8) != 0x0);
- }
- set
- {
- if (value)
- {
- _generalPurposeBitFlag |= 0x8; //set bit #3
- }
- else
- {
- _generalPurposeBitFlag &= 0xFFF7; //clear bit #3
- }
- }
- }
-
- internal DeflateOptionEnum DeflateOption
- {
- get
- {
- if (CompressionMethod == CompressionMethodEnum.Deflated)
- {
- return (DeflateOptionEnum)(_generalPurposeBitFlag & 0x6);
- }
- else
- {
- // defalte option is validated to be one of the 2 (deflated or stored)
- return DeflateOptionEnum.None;
- }
- }
- set
- {
- // this checks must be done in the levels above
- Debug.Assert(Enum.IsDefined(typeof(DeflateOptionEnum), value));
- Debug.Assert(value != DeflateOptionEnum.None);
-
- // clean the value (bits 1 and 2)
- _generalPurposeBitFlag &= 0xFFF9;
- _generalPurposeBitFlag |= (UInt16)value; // safe cast because of the enum validation
- }
- }
-
- static internal int FixedMinimalRecordSize
- {
- get
- {
- return _fixedMinimalRecordSize;
- }
- }
-
- private bool EncryptedFlag
- {
- get
- {
- return ((_generalPurposeBitFlag & 0x1) == 0x1);
- }
- }
-
- internal void UpdateZip64Structures(long compressedSize,
- long uncompressedSize,
- long offset)
- {
- // according to the appnote local file header ZIP 64 extra field if used must contain both
- // compressed and uncompressed size
- // we also trying to stay on the safe side and treeat the boundary case of 32 escape values
- // as a zip 64 scenario
- // we will also make this ZIP64 file if it is small but positioned beyond Uint32.MaxValue offset
- if ((compressedSize >= UInt32.MaxValue) ||
- (uncompressedSize >= UInt32.MaxValue) ||
- (offset >= UInt32.MaxValue))
- {
- // Zip 64 case
- _extraField.CompressedSize = compressedSize;
- _extraField.UncompressedSize = uncompressedSize;
-
- //set proper escape values
- _compressedSize = UInt32.MaxValue;
- _uncompressedSize = UInt32.MaxValue;
-
- // update version needed to extract to 4.5
- _versionNeededToExtract = (UInt16)ZipIOVersionNeededToExtract.Zip64FileFormat;
- }
- else
- {
- // 32 bit case
- _compressedSize = (UInt32)compressedSize; // checked{} isn't required because of the checks above
- _uncompressedSize = (UInt32)uncompressedSize;
-
- // reset the extra ZIP 64 field to empty
- _extraField.Zip64ExtraFieldUsage = ZipIOZip64ExtraFieldUsage.None;
-
- // version needed to extract needs to be recalculated from scratch based on compression
- _versionNeededToExtract =
- (UInt16)ZipIOBlockManager.CalcVersionNeededToExtractFromCompression(CompressionMethod);
- }
- }
-
- internal void UpdatePadding(long headerSizeChange)
- {
- _extraField.UpdatePadding(headerSizeChange);
- }
-
- private ZipIOLocalFileHeader()
- {
- }
-
- private void Validate ()
- {
- if (_signature != _signatureConstant)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- if (_fileNameLength != _fileName.Length)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- ZipArchive.VerifyVersionNeededToExtract(_versionNeededToExtract);
-
- // encryption is not supported
- if (EncryptedFlag)
- throw new NotSupportedException(SR.Get(SRID.ZipNotSupportedEncryptedArchive));
-
- // if verson is below 4.5 make sure that ZIP 64 extra filed isn't present
- // if it is it might be a security concern
- if ((_versionNeededToExtract < (UInt16)ZipIOVersionNeededToExtract.Zip64FileFormat) &&
- (_extraField.Zip64ExtraFieldUsage != ZipIOZip64ExtraFieldUsage.None))
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- // ZIP 64 validation; if extra field is present it
- // must have both compressed and uncompressed size in the local file header
- // according to the appnote
- if ((_extraField.Zip64ExtraFieldUsage != ZipIOZip64ExtraFieldUsage.None) &&
- (_extraField.Zip64ExtraFieldUsage !=
- (ZipIOZip64ExtraFieldUsage.CompressedSize |
- ZipIOZip64ExtraFieldUsage.UncompressedSize)))
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- if (_extraFieldLength != _extraField.Size)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- if ((CompressionMethod != CompressionMethodEnum.Stored) &&
- (CompressionMethod != CompressionMethodEnum.Deflated))
- {
- throw new NotSupportedException(SR.Get(SRID.ZipNotSupportedCompressionMethod));
- }
- }
-
- private const int _fixedMinimalRecordSize = 30;
-
- private const UInt32 _signatureConstant = 0x04034b50;
- private UInt32 _signature = _signatureConstant;
- private UInt16 _versionNeededToExtract;
- private UInt16 _generalPurposeBitFlag;
- private UInt16 _compressionMethod;
- private UInt32 _lastModFileDateTime;
- private UInt32 _crc32;
- private UInt32 _compressedSize;
- private UInt32 _uncompressedSize;
- private UInt16 _fileNameLength;
- private UInt16 _extraFieldLength;
- private byte[] _fileName;
- private ZipIOExtraField _extraField;
-
- private string _stringFileName;
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOModeEnforcingStream.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOModeEnforcingStream.cs
deleted file mode 100644
index 9304631a5c9..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOModeEnforcingStream.cs
+++ /dev/null
@@ -1,320 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that enables interactions with Zip archives
-// for OPC scenarios
-//
-//
-//
-//
-
-using System;
-using System.IO;
-using System.Diagnostics;
-using System.Text;
-using System.Collections;
-using System.Windows;
-using MS.Internal.WindowsBase;
-
-namespace MS.Internal.IO.Zip
-{
- internal class ZipIOModeEnforcingStream: Stream, IDisposable
- {
- // !!!!!!!!! Attention !!!!!!!!!!!!
- // This stream is NOT doing any data buffering by design
- // All data buffering is done underneath, by either
- // FileItemStream or Compression Stream
- // This assumption is used through the code of the
- // FileItemBlock to calculate up to data CompressedSize UncompressedSize DirtyFlag and others
- // !!!!!!!!! Attention !!!!!!!!!!!!
-
- ////////////////////////////////////
- // Stream section
- /////////////////////////////////
- override public bool CanRead
- {
- get
- {
- return (!_disposedFlag &&
- _baseStream.CanRead &&
- ((_access == FileAccess.Read) || (_access == FileAccess.ReadWrite)));
- }
- }
-
- override public bool CanSeek
- {
- get
- {
- return (!_disposedFlag) && (_baseStream.CanSeek);
- }
- }
-
- override public bool CanWrite
- {
- get
- {
- return (!_disposedFlag &&
- _baseStream.CanWrite &&
- ((_access == FileAccess.Write) || (_access == FileAccess.ReadWrite)));
- }
- }
-
- override public long Length
- {
- get
- {
- CheckDisposed();
- long result = _baseStream.Length;
-
- // This can definetly lead to consuming more memory Compression stream
- // might sitch to Emulation mode
- // disabling auto flushing functionality As a part of implementing Isolated storage fallback in the Sparse MemoryStream
- //_trackingMemoryStreamFactory.ReportTransactionComplete();
-
- return result;
- }
- }
-
- override public long Position
- {
- get
- {
- CheckDisposed();
- return _currentStreamPosition;
- }
- set
- {
- CheckDisposed();
- Seek(value, SeekOrigin.Begin);
- }
- }
-
- public override void SetLength(long newLength)
- {
- CheckDisposed();
-
- if (!CanWrite)
- {
- throw new NotSupportedException(SR.Get(SRID.SetLengthNotSupported));
- }
-
- _baseStream.SetLength(newLength);
-
- if (newLength < _currentStreamPosition)
- _currentStreamPosition = newLength;
-
- // This can definetly lead to consuming more memory
- // disabling auto flushing functionality As a part of implementing Isolated storage fallback in the Sparse MemoryStream
- //_trackingMemoryStreamFactory.ReportTransactionComplete();
- }
-
- override public long Seek(long offset, SeekOrigin origin)
- {
- CheckDisposed();
- long newStreamPosition = _currentStreamPosition;
-
- if (origin ==SeekOrigin.Begin)
- {
- newStreamPosition = offset;
- }
- else if (origin == SeekOrigin.Current)
- {
- checked{newStreamPosition += offset;}
- }
- else if (origin == SeekOrigin.End)
- {
- checked{newStreamPosition = Length + offset;}
- }
- else
- {
- throw new ArgumentOutOfRangeException("origin");
- }
-
- if (newStreamPosition < 0)
- {
- throw new ArgumentException(SR.Get(SRID.SeekNegative));
- }
- _currentStreamPosition = newStreamPosition;
-
- return _currentStreamPosition;
- }
-
- override public int Read(byte[] buffer, int offset, int count)
- {
- CheckDisposed();
-
- if (!CanRead)
- {
- throw new NotSupportedException(SR.Get(SRID.ReadNotSupported));
- }
-
- long originalStreamPosition = _currentStreamPosition;
- int readResult;
-
- try
- {
- _baseStream.Seek(_currentStreamPosition, SeekOrigin.Begin);
- readResult = _baseStream.Read(buffer, offset, count);
- checked{_currentStreamPosition += readResult;}
- }
- catch
- {
- // when an exception is thrown, the stream position should remain unchanged
- _currentStreamPosition = originalStreamPosition;
-
- throw;
- }
-
- // This can definetly lead to consuming more memory (compression emulation mode)
- // disabling auto flushing functionality As a part of implementing Isolated storage fallback in the Sparse MemoryStream
- //_trackingMemoryStreamFactory.ReportTransactionComplete();
-
- return readResult;
- }
-
- override public void Write(byte[] buffer, int offset, int count)
- {
- CheckDisposed();
-
- if (!CanWrite)
- {
- throw new NotSupportedException(SR.Get(SRID.WriteNotSupported));
- }
-
- if (_baseStream.CanSeek)
- _baseStream.Seek(_currentStreamPosition, SeekOrigin.Begin);
- // if CanSeek() is false, we are already in the correct position by default
-
- _baseStream.Write(buffer, offset, count);
- checked{_currentStreamPosition += count;}
-
- // This can definetly lead to consuming more memory (compression emulation mode)
- // disabling auto flushing functionality As a part of implementing Isolated storage fallback in the Sparse MemoryStream
- //_trackingMemoryStreamFactory.ReportTransactionComplete();
- }
-
- override public void Flush()
- {
- CheckDisposed();
- _baseStream.Flush(); // we must be calling flush on underlying stream
- // we can not do something like _blockManager.SaveStream here
- // as it will make impossible to push data through the stream stack
- }
-
- //------------------------------------------------------
- //
- // Internal Properties
- //
- //------------------------------------------------------
- internal bool Disposed
- {
- get
- {
- return _disposedFlag;
- }
- }
-
- //------------------------------------------------------
- //
- // Protected Methods
- //
- //------------------------------------------------------
- ///
- /// Dispose(bool)
- ///
- ///
- protected override void Dispose(bool disposing)
- {
- try
- {
- if (disposing)
- {
- // multiple calls are fine - just ignore them
- if (!_disposedFlag)
- {
- // we do that so that the block Manager and Local File Block can make a decision whether
- // there are any more open streams or not
- _disposedFlag = true;
-
- // This will enable us to make accurate decisions in regard to the number of currently opened streams
- _block.DeregisterExposedStream(this);
-
- // we must NOT Dispose underlying stream, as it canbe used by other opened
- // ZipIOModeEnforcingStream(s) and even if there no other open
- // ZipIOModeEnforcingStream(s) at the moment, Cleint app can ask for more later;
- // we can only Dispose underlying stream as a part of the Container Close/Dispose calls
-#if !DEBUG
- // Don't call Flush() in retail builds but do in debug builds to catch any
- // logic errors.
- if (_access == FileAccess.ReadWrite || _access == FileAccess.Write)
-#endif
- {
- // Tell the block manager that we want to be closed
- // the second parameter is ignored in the non-streaming cases , and it will result
- // in a non-streaming container level flush
- _blockManager.SaveStream(_block, true);
- }
- }
- }
- }
- finally
- {
- _baseStream = null;
- base.Dispose(disposing);
- }
- }
-
- //------------------------------------------------------
- //
- // Private Methods
- //
- //------------------------------------------------------
-
- ///
- /// Constructor - streaming and non-streaming mode
- ///
- ///
- ///
- /// block manager
- /// associated block
- internal ZipIOModeEnforcingStream(Stream baseStream, FileAccess access,
- ZipIOBlockManager blockManager,
- ZipIOLocalFileBlock block)
- {
- Debug.Assert(baseStream != null);
-
- _baseStream = baseStream;
- _access = access;
- _blockManager = blockManager;
- _block = block;
- }
-
- private void CheckDisposed()
- {
- if (_disposedFlag)
- {
- throw new ObjectDisposedException(null, SR.Get(SRID.StreamObjectDisposed));
- }
- }
-
- //------------------------------------------------------
- //
- // Private Members
- //
- //------------------------------------------------------
- private Stream _baseStream;
- private FileAccess _access;
-
- private bool _disposedFlag;
- private long _currentStreamPosition;
-
- // Streaming Mode only
- private ZipIOLocalFileBlock _block; // null if not in streaming mode
- private ZipIOBlockManager _blockManager; // null if not in streaming mode
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIORawDataFileBlock.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIORawDataFileBlock.cs
deleted file mode 100644
index a68b2b7db6f..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIORawDataFileBlock.cs
+++ /dev/null
@@ -1,256 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that enables interactions with Zip archives
-// for OPC scenarios
-//
-//
-//
-//
-
-using System;
-using System.IO;
-using System.Diagnostics;
-using System.Collections;
-using System.Runtime.Serialization;
-using System.Windows;
-using MS.Internal.IO.Packaging; // for PackagingUtilities
-
-namespace MS.Internal.IO.Zip
-{
- internal class ZipIORawDataFileBlock : IZipIOBlock
- {
- //------------------------------------------------------
- //
- // Public Properties
- //
- //------------------------------------------------------
- // standard IZipIOBlock functionality
- public long Offset
- {
- get
- {
- return _offset;
- }
- }
-
- public long Size
- {
- get
- {
- return _size;
- }
- }
-
- public bool GetDirtyFlag(bool closingFlag)
- {
- return _dirtyFlag;
- }
-
- //------------------------------------------------------
- //
- // Public Methods
- //
- //------------------------------------------------------
- public void Move(long shiftSize)
- {
- if (shiftSize != 0)
- {
- checked{_offset +=shiftSize;}
- _dirtyFlag = true;
- Debug.Assert(_offset >=0);
- }
- }
-
- public void Save()
- {
- if(GetDirtyFlag(true)) // in case we do not know whether we are closing or not we should think we are closing as a more conservative approach
- {
- // we need to move the whole block to the new position
- long moveBlockSourceOffset = _persistedOffset;
- long moveBlockSize = _size;
- long moveBlockTargetOffset = _offset;
-
- if (_cachePrefixStream != null)
- {
- // if we have something in cache we only should move whatever isn't cached
- checked{moveBlockSourceOffset += _cachePrefixStream.Length;}
- checked{moveBlockTargetOffset += _cachePrefixStream.Length;}
- checked{moveBlockSize -= _cachePrefixStream.Length;}
- Debug.Assert(moveBlockSize >=0);
- }
-
- _blockManager.MoveData(moveBlockSourceOffset, moveBlockTargetOffset, moveBlockSize);
-
- // only after data on disk was moved it is safe to flush the cached prefix buffer
- if (_cachePrefixStream != null)
- {
- if (_blockManager.Stream.Position != _offset)
- {
- // we need to seek
- _blockManager.Stream.Seek(_offset, SeekOrigin.Begin);
- }
-
- Debug.Assert(_cachePrefixStream.Length > 0); // should be taken care of by the constructor
- // and PreSaveNotification
-
- // we do not need to flush here because Block Manager is responsible for flushing
- // this in it's Save method
- _cachePrefixStream.WriteToStream(_blockManager.Stream);
-
- // we can free the memory
- _cachePrefixStream.Close();
- _cachePrefixStream = null;
- }
-
- // we are not shifted between on disk image and in memory image any more
- _persistedOffset = _offset;
-
- _dirtyFlag = false;
- }
- }
-
- public void UpdateReferences(bool closingFlag)
- {
- // this block doesn't have external references so there is nothing we need to do here
- }
-
- public PreSaveNotificationScanControlInstruction PreSaveNotification(long offset, long size)
- {
- return ZipIOBlockManager.CommonPreSaveNotificationHandler(
- _blockManager.Stream,
- offset, size,
- _persistedOffset, _size,
- ref _cachePrefixStream);
- }
-
- //------------------------------------------------------
- //
- // Internal Properties
- //
- //------------------------------------------------------
- internal long DiskImageShift
- {
- get
- {
- return _offset - _persistedOffset;
- }
- }
-
- //------------------------------------------------------
- //
- // Internal Methods
- //
- //------------------------------------------------------
- internal static ZipIORawDataFileBlock Assign(ZipIOBlockManager blockManager, long offset, long size)
- {
- if (size <= 0)
- {
- throw new ArgumentOutOfRangeException ("size");
- }
-
- if (offset < 0)
- {
- throw new ArgumentOutOfRangeException ("offset");
- }
-
- ZipIORawDataFileBlock block = new ZipIORawDataFileBlock(blockManager);
- block._persistedOffset = offset;
- block._offset = offset;
- block._size = size;
-
- return block;
- }
-
- internal bool DiskImageContains(IZipIOBlock block)
- {
- checked
- {
- Debug.Assert(block != null);
- Debug.Assert(block.Offset >=0);
- Debug.Assert(block.Size > 0);
-
- return (_persistedOffset <= block.Offset) &&
- (_persistedOffset + _size >= block.Offset +block.Size);
- }
- }
-
- internal bool DiskImageContains(long offset)
- {
- checked
- {
- Debug.Assert(offset >=0);
-
- return (_persistedOffset <= offset) && (_persistedOffset + _size > offset);
- }
- }
-
- internal void SplitIntoPrefixSuffix(IZipIOBlock block,
- out ZipIORawDataFileBlock prefixBlock, out ZipIORawDataFileBlock suffixBlock)
- {
- // assert that current's block cache isn't loaded, if it is
- // we probably missed an opportunity to used this cache in order to parse the new block
- // and it might be based on the overriden data on disk
- // This block can only be in cached state as a part of single BlockManager.Save execution.
- // It can NOT be in cached state prior to BlockManager.Save function entry or after
- // BlockManager.Save execution completed
- Debug.Assert(_cachePrefixStream == null);
-
- // Assert that block is containe inside the current raw block
- Debug.Assert(DiskImageContains(block));
-
- checked
- {
- prefixBlock = null;
- suffixBlock = null;
- if (block.Offset > _persistedOffset)
- {
- // we have a new non empty prefix;
- long newBlockOffset = _persistedOffset;
- long newBlockSize = block.Offset - _persistedOffset;
-
- prefixBlock = Assign(_blockManager, newBlockOffset , newBlockSize);
- }
-
- if (block.Offset + block.Size < _persistedOffset + _size)
- {
- // we have a new non empty suffix;
- long newBlockOffset = block.Offset + block.Size;
- long newBlockSize = _persistedOffset + _size - newBlockOffset;
-
- suffixBlock = Assign(_blockManager, newBlockOffset, newBlockSize);
- }
- }
- }
-
- //------------------------------------------------------
- //
- // Private Methods
- //
- //------------------------------------------------------
- private ZipIORawDataFileBlock(ZipIOBlockManager blockManager)
- {
- _blockManager = blockManager;
- }
-
- //------------------------------------------------------
- //
- // Private Members
- //
- //------------------------------------------------------
- private SparseMemoryStream _cachePrefixStream = null;
-
- private ZipIOBlockManager _blockManager;
-
- private long _persistedOffset;
-
- private long _offset;
- private long _size;
- private bool _dirtyFlag;
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOVersionNeededToExtract.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOVersionNeededToExtract.cs
deleted file mode 100644
index f3929516aad..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOVersionNeededToExtract.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal enumeration that maintains version needed to extract values
-// for OPC scenarios
-//
-//
-//
-//
-
-
-namespace MS.Internal.IO.Zip
-{
- internal enum ZipIOVersionNeededToExtract : ushort
- {
- StoredData = 10,
- VolumeLabel = 11,
- DeflatedData = 20,
- Zip64FileFormat = 45,
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOZip64EndOfCentralDirectoryBlock.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOZip64EndOfCentralDirectoryBlock.cs
deleted file mode 100644
index 4183f62355c..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOZip64EndOfCentralDirectoryBlock.cs
+++ /dev/null
@@ -1,436 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that enables interactions with Zip archives
-// for OPC scenarios (Zip 64 bit support)
-//
-//
-//
-//
-
-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 ZipIOZip64EndOfCentralDirectoryBlock : IZipIOBlock
- {
- // standard IZipIOBlock functionality
- public long Offset
- {
- get
- {
- return _offset;
- }
- }
-
- public long Size
- {
- get
- {
- return _size;
- }
- }
-
- // This property will only return reliable result if UpdateReferences 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()
- {
- // this record is optional and shouldn't be saved if size is 0
- if (GetDirtyFlag(true) && (Size > 0))
- {
- BinaryWriter writer = _blockManager.BinaryWriter;
- if (_blockManager.Stream.Position != _offset)
- {
- // we need to seek , as current position isn't accurate
- _blockManager.Stream.Seek(_offset, SeekOrigin.Begin);
- }
-
- writer.Write(_signatureConstant);
- writer.Write(_sizeOfZip64EndOfCentralDirectory);
- writer.Write(_versionMadeBy);
- writer.Write(_versionNeededToExtract);
- writer.Write(_numberOfThisDisk);
- writer.Write(_numberOfTheDiskWithTheStartOfTheCentralDirectory);
- writer.Write(_totalNumberOfEntriesInTheCentralDirectoryOnThisDisk);
- writer.Write(_totalNumberOfEntriesInTheCentralDirectory);
- writer.Write(_sizeOfTheCentralDirectory);
- writer.Write(_offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber);
-
- if (_sizeOfZip64EndOfCentralDirectory > _fixedMinimalValueOfSizeOfZip64EOCD)
- {
- Debug.Assert(_zip64ExtensibleDataSector != null);
- Debug.Assert(_zip64ExtensibleDataSector.Length ==
- checked((int)(_sizeOfZip64EndOfCentralDirectory -_fixedMinimalValueOfSizeOfZip64EOCD)));
-
- writer.Write(_zip64ExtensibleDataSector,
- 0,
- checked((int)(_sizeOfZip64EndOfCentralDirectory -_fixedMinimalValueOfSizeOfZip64EOCD)));
- }
-
- 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. streaming mode
- // if Central Directory isn't loaded 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)))
- {
- if (_blockManager.CentralDirectoryBlock.IsZip64BitRequiredForStoring)
- {
- UInt64 centralDirCount = (UInt64)_blockManager.CentralDirectoryBlock.Count;
- UInt64 centralDirBlockSize = (UInt64)_blockManager.CentralDirectoryBlock.Size;
- UInt64 centralDirOffset = (UInt64)_blockManager.CentralDirectoryBlock.Offset;
-
- // Here is a diagram of the record
- //----------------------------------------------------------------------------------------------------------------------
- //|SignatureConst (4 bytes)|sizeOfZip64Eocd (8 bytes)|misc fixed fields (44 bytes)|Variable Size Extensible Data sector|
- //A------------------------B-------------------------C----------------------------D------------------------------------E
- //
- // in order to calculate the actual record size we subtract _fixedMinimalValueOfSizeOfZip64EOCD (This is a chunk marked
- // (C,D) in thre diagram above) from _fixedMinimalRecordSize (This is a chunk marked (A,D) in the diagram above).
- // Then we add the resulting value (which would be chunked marked (A,C) to the value of sizeOfZip64Eocd field which
- // contains the size of the record starting at point (C) and going to the end (E). So we get the total size as
- // (A,C) + (C,E) = (A,E)
- //
-
- long size = checked((long)(
- // value that was either parsed from a file or initialized to the _fixedMinimalValueOfSizeOfZip64EOCD
- _sizeOfZip64EndOfCentralDirectory +
- // const (value indicating minimal whole record size, how many bytes on disk it needs) 56
- _fixedMinimalRecordSize -
- // const (value indicating minimal value for the SizeOfZip64EOCD field as it is contains
- // the whole size without record signature(4), and the itself (8) it is 56 - 12 = 44
- _fixedMinimalValueOfSizeOfZip64EOCD));
-
- // update value and mark record dirty if either it is already dirty or there is a mismatch
- if ((_dirtyFlag) ||
- (_totalNumberOfEntriesInTheCentralDirectoryOnThisDisk != centralDirCount) ||
- (_totalNumberOfEntriesInTheCentralDirectory != centralDirCount ) ||
- (_sizeOfTheCentralDirectory != centralDirBlockSize) ||
- (_offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber != centralDirOffset) ||
- (_size != size))
- {
- _versionMadeBy = (ushort)ZipIOVersionNeededToExtract.Zip64FileFormat;
- _versionNeededToExtract = (ushort)ZipIOVersionNeededToExtract.Zip64FileFormat;
-
- _numberOfThisDisk = 0;
- _numberOfTheDiskWithTheStartOfTheCentralDirectory = 0;
-
- _totalNumberOfEntriesInTheCentralDirectoryOnThisDisk = centralDirCount;
- _totalNumberOfEntriesInTheCentralDirectory = centralDirCount;
- _sizeOfTheCentralDirectory = centralDirBlockSize;
- _offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber = centralDirOffset;
-
- _size = size;
-
- _dirtyFlag = true;
- }
- }
- else
- {
- // we do not need zip 64 structures
- if (_size != 0)
- {
- _dirtyFlag = true;
- _size = 0;
- }
- }
- }
- }
- }
-
- public PreSaveNotificationScanControlInstruction PreSaveNotification(long offset, long size)
- {
- // we can safely ignore this notification as we do not keep any data on disk
- // after parsing on disk. Everything is in memory, it is ok to override
- // original Zip64 EndOf Central Directory Block without any additional backups
-
- // we can also safely state that there is no need to continue the PreSafeNotification loop
- // as the blocks after the Zip64 Eocd (EOCD, Zip64 locator ) do not have
- // data that is buffered on disk
- return PreSaveNotificationScanControlInstruction.Stop;
- }
-
- internal static ZipIOZip64EndOfCentralDirectoryBlock SeekableLoad (ZipIOBlockManager blockManager)
- {
- ZipIOZip64EndOfCentralDirectoryLocatorBlock zip64endOfCentralDirectoryLocator =
- blockManager.Zip64EndOfCentralDirectoryLocatorBlock;
-
- long zip64EndOfCentralDirectoryOffset =
- zip64endOfCentralDirectoryLocator.OffsetOfZip64EndOfCentralDirectoryRecord;
-
- ZipIOZip64EndOfCentralDirectoryBlock block = new ZipIOZip64EndOfCentralDirectoryBlock(blockManager);
-
- blockManager.Stream.Seek(zip64EndOfCentralDirectoryOffset, SeekOrigin.Begin);
-
- block.ParseRecord(blockManager.BinaryReader, zip64EndOfCentralDirectoryOffset);
-
- return block;
- }
-
- internal static ZipIOZip64EndOfCentralDirectoryBlock CreateNew(ZipIOBlockManager blockManager)
- {
- ZipIOZip64EndOfCentralDirectoryBlock block = new ZipIOZip64EndOfCentralDirectoryBlock(blockManager);
-
- block._size = 0; // brand new created records are optional by definition untill UpdateReferences is called, so size must be 0
- block._offset = 0;
- block._dirtyFlag = false;
-
- // initialize fields with ythe data from the EOCD
- block.InitializeFromEndOfCentralDirectory(blockManager.EndOfCentralDirectoryBlock);
-
- return block;
- }
-
- internal long OffsetOfStartOfCentralDirectory
- {
- get
- {
- return (long)_offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber;
- }
- }
-
- internal int TotalNumberOfEntriesInTheCentralDirectory
- {
- get
- {
- return (int)_totalNumberOfEntriesInTheCentralDirectory; // checked isn't required as we do validation during parsing
- }
- }
-
- internal long SizeOfCentralDirectory
- {
- get
- {
- return (long)_sizeOfTheCentralDirectory;
- }
- }
-
- private ZipIOZip64EndOfCentralDirectoryBlock(ZipIOBlockManager blockManager)
- {
- Debug.Assert(blockManager != null);
- _blockManager= blockManager;
- }
-
- private void ParseRecord (BinaryReader reader, long position)
- {
- _signature = reader.ReadUInt32();
- _sizeOfZip64EndOfCentralDirectory = reader.ReadUInt64();
- _versionMadeBy = reader.ReadUInt16();
- _versionNeededToExtract = reader.ReadUInt16();
- _numberOfThisDisk = reader.ReadUInt32();
- _numberOfTheDiskWithTheStartOfTheCentralDirectory = reader.ReadUInt32();
- _totalNumberOfEntriesInTheCentralDirectoryOnThisDisk = reader.ReadUInt64();
- _totalNumberOfEntriesInTheCentralDirectory = reader.ReadUInt64();
- _sizeOfTheCentralDirectory = reader.ReadUInt64();
- _offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber = reader.ReadUInt64();
-
- // pre validate before reading data based on parsed values
- if ((_sizeOfZip64EndOfCentralDirectory < _fixedMinimalValueOfSizeOfZip64EOCD) ||
- // we are refusing to buffer large extended areas
- (_sizeOfZip64EndOfCentralDirectory > UInt16.MaxValue))
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- if (_sizeOfZip64EndOfCentralDirectory > _fixedMinimalValueOfSizeOfZip64EOCD)
- {
- _zip64ExtensibleDataSector = reader.ReadBytes((int)(_sizeOfZip64EndOfCentralDirectory -_fixedMinimalValueOfSizeOfZip64EOCD));
- }
-
- // override some numbers bvased on the EOCD data according to the apnote
- // even in presence of Zip64Eocd we still need to use the regular EOCD data
- OverrideValuesBasedOnEndOfCentralDirectory(_blockManager.EndOfCentralDirectoryBlock);
-
- _size = checked((long)( // value that was either parsed from a file or initialized to the _fixedMinimalValueOfSizeOfZip64EOCD
- _sizeOfZip64EndOfCentralDirectory +
- // const (value indicating minimal whole record size, how many bytes on disk it needs) 56
- _fixedMinimalRecordSize -
- // const (value indicating minimal value for the SizeOfZip64EOCD field as it is contains
- // the whole size without record signature(4), and the itself (8) it is 56 - 12 = 44
- _fixedMinimalValueOfSizeOfZip64EOCD));
- Debug.Assert(_size >= _fixedMinimalRecordSize);
-
- _offset = position;
- _dirtyFlag = false;
-
- Validate();
- }
-
- ///
- /// This function is called from the Create New routine. The purpose of this exercise , is to copy data from 32 bit EOCD into this record,
- /// for scenarios when ZIP64 EOCD wasn't parsed from a file, but was just made up.
- /// This is done so that Central Dir parsing code can ask the ZIP64 EOCD for this data, and regardless of whether it is real zip 64 file or
- /// not a zip 64 file it will get the right CD offset , size and so on
- ///
- private void InitializeFromEndOfCentralDirectory(ZipIOEndOfCentralDirectoryBlock zipIoEocd)
- {
- _numberOfThisDisk = zipIoEocd.NumberOfThisDisk;
- _numberOfTheDiskWithTheStartOfTheCentralDirectory = zipIoEocd.NumberOfTheDiskWithTheStartOfTheCentralDirectory;
- _totalNumberOfEntriesInTheCentralDirectoryOnThisDisk = zipIoEocd.TotalNumberOfEntriesInTheCentralDirectoryOnThisDisk;
- _totalNumberOfEntriesInTheCentralDirectory = zipIoEocd.TotalNumberOfEntriesInTheCentralDirectory;
- _sizeOfTheCentralDirectory = zipIoEocd.SizeOfTheCentralDirectory;
- _offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber = zipIoEocd.OffsetOfStartOfCentralDirectory;
- }
-
- ///
- /// This function is called from the Parse routine. The purpose of this exercise , is to figure out the escape
- /// values in the regular 32 bit EOCD. We shouldn't be using values from the 64 bit structure if it wasn't
- /// escaped in the 32 bit structure.
- ///
- private void OverrideValuesBasedOnEndOfCentralDirectory(ZipIOEndOfCentralDirectoryBlock zipIoEocd)
- {
- // 16 bit numbers
- if (zipIoEocd.NumberOfThisDisk < UInt16.MaxValue)
- {_numberOfThisDisk = zipIoEocd.NumberOfThisDisk;}
-
- if (zipIoEocd.NumberOfTheDiskWithTheStartOfTheCentralDirectory < UInt16.MaxValue)
- {_numberOfTheDiskWithTheStartOfTheCentralDirectory = zipIoEocd.NumberOfTheDiskWithTheStartOfTheCentralDirectory;}
-
- if (zipIoEocd.TotalNumberOfEntriesInTheCentralDirectoryOnThisDisk < UInt16.MaxValue)
- {_totalNumberOfEntriesInTheCentralDirectoryOnThisDisk = zipIoEocd.TotalNumberOfEntriesInTheCentralDirectoryOnThisDisk;}
-
- if (zipIoEocd.TotalNumberOfEntriesInTheCentralDirectory < UInt16.MaxValue)
- {_totalNumberOfEntriesInTheCentralDirectory = zipIoEocd.TotalNumberOfEntriesInTheCentralDirectory;}
-
- // 32 bit numbers
- if (zipIoEocd.SizeOfTheCentralDirectory < UInt32.MaxValue)
- {_sizeOfTheCentralDirectory = zipIoEocd.SizeOfTheCentralDirectory;}
-
- if (zipIoEocd.OffsetOfStartOfCentralDirectory < UInt32.MaxValue)
- {_offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber = zipIoEocd.OffsetOfStartOfCentralDirectory;}
-}
-
- private void Validate()
- {
- if (_signature != _signatureConstant)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- if ((_numberOfThisDisk != 0) ||
- (_numberOfTheDiskWithTheStartOfTheCentralDirectory != 0) ||
- (_totalNumberOfEntriesInTheCentralDirectoryOnThisDisk !=
- _totalNumberOfEntriesInTheCentralDirectory))
- {
- throw new NotSupportedException(SR.Get(SRID.NotSupportedMultiDisk));
- }
-
- // this will throw an unsupported version exception if we see a version that we do not support
- ZipArchive.VerifyVersionNeededToExtract(_versionNeededToExtract);
-
- // if it is one of the supported version but it isn't a ZIP64, it is an indication of a corrupted file
- if (_versionNeededToExtract != (UInt16)ZipIOVersionNeededToExtract.Zip64FileFormat)
- {
- // if version isn't equal to the 4.5 it is a corrupted file (as we)
- // as appnote explicitly states that
- // When using ZIP64 extensions, the corresponding value in the
- // Zip64 end of central directory record should also be set.
- // This field currently supports only the value 45 to indicate
- // ZIP64 extensions are present.
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- if ((_totalNumberOfEntriesInTheCentralDirectoryOnThisDisk > Int32.MaxValue) ||
- (_totalNumberOfEntriesInTheCentralDirectory > Int32.MaxValue) ||
- (_sizeOfTheCentralDirectory > Int64.MaxValue) ||
- (_offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber > Int64.MaxValue))
- {
- // although we are trying to support 64 bit structures
- // we are limited by the CLR model for collections (down to 32 bit collection size for
- // _totalNumberOfEntriesInTheCentralDirectoryOnThisDisk )
- // and streams (down to 63 bit size) for all the outher Uint64 fields
-
- throw new NotSupportedException(SR.Get(SRID.Zip64StructuresTooLarge));
- }
-
- ulong sizeOfZip64ExtensibleDataSector = 0;
- if (_zip64ExtensibleDataSector != null)
- {
- sizeOfZip64ExtensibleDataSector = (ulong)_zip64ExtensibleDataSector.Length;
- }
-
- // the subtraction below doesn't need to be checked as we have validation in the parse logic
- // if (_sizeOfZip64EndOfCentralDirectory < _fixedMinimalValueOfSizeOfZip64EOCD) { throw .. }
- if (_sizeOfZip64EndOfCentralDirectory - _fixedMinimalValueOfSizeOfZip64EOCD != sizeOfZip64ExtensibleDataSector)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
-
- //calculated record size must be larger than the min value
- // it could be 0 for newly created from scratch records, but we do not pass those records through validation
- // we only validate parsed data
- if (_size < _fixedMinimalRecordSize)
- {
- throw new FileFormatException(SR.Get(SRID.CorruptedData));
- }
- }
-
-
- private ZipIOBlockManager _blockManager;
-
- private long _offset;
- private long _size;
-
- private bool _dirtyFlag;
-
- private const UInt32 _signatureConstant = 0x06064b50;
- private const uint _fixedMinimalRecordSize = 56;
- private const uint _fixedMinimalValueOfSizeOfZip64EOCD = 44; // doesn't include the signature and the size itself
-
- // data persisted on disk
- private UInt32 _signature = _signatureConstant;
-
- private UInt64 _sizeOfZip64EndOfCentralDirectory = _fixedMinimalValueOfSizeOfZip64EOCD;
- private UInt16 _versionMadeBy = (ushort)ZipIOVersionNeededToExtract.Zip64FileFormat;
- private UInt16 _versionNeededToExtract = (ushort)ZipIOVersionNeededToExtract.Zip64FileFormat;
- private UInt32 _numberOfThisDisk;
- private UInt32 _numberOfTheDiskWithTheStartOfTheCentralDirectory;
- private UInt64 _totalNumberOfEntriesInTheCentralDirectoryOnThisDisk; // all int64s declared as signed values
- private UInt64 _totalNumberOfEntriesInTheCentralDirectory; // as we can not suport true unsigned 64 bit sizes
- private UInt64 _sizeOfTheCentralDirectory; // as a result of limitations in Stream interface
- private UInt64 _offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber;
- private byte[] _zip64ExtensibleDataSector;
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOZip64EndOfCentralDirectoryLocatorBlock.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOZip64EndOfCentralDirectoryLocatorBlock.cs
deleted file mode 100644
index 1cbb008084c..00000000000
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Zip/ZipIOZip64EndOfCentralDirectoryLocatorBlock.cs
+++ /dev/null
@@ -1,279 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-//
-//
-// Description:
-// This is an internal class that enables interactions with Zip archives
-// for OPC scenarios (Zip 64 bit support)
-//
-//
-//
-//
-
-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;
- }
-}
diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/WindowsBase.csproj b/src/Microsoft.DotNet.Wpf/src/WindowsBase/WindowsBase.csproj
index b35ba34cc3a..fac3b7ae23e 100644
--- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/WindowsBase.csproj
+++ b/src/Microsoft.DotNet.Wpf/src/WindowsBase/WindowsBase.csproj
@@ -119,16 +119,13 @@
-
-
-
@@ -328,36 +325,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Common\System\IO\Compression\DeflateZLib\ZLibNative.cs