internal static ZipArchiveFile ReadHeader(FileStream stream)
        {
            BinaryReader binaryReader = new BinaryReader(stream);
            uint num = binaryReader.ReadUInt32();
            if (num != 67324752u)
            {
                return null;
            }

            ZipArchiveFile zipArchiveFile = new ZipArchiveFile();
            binaryReader.ReadUInt16();
            binaryReader.ReadUInt16();
            zipArchiveFile.compressMethod = binaryReader.ReadUInt16();
            binaryReader.ReadUInt16();
            binaryReader.ReadUInt16();
            binaryReader.ReadUInt32();
            uint num2 = binaryReader.ReadUInt32();
            binaryReader.ReadUInt32();
            ushort num3 = binaryReader.ReadUInt16();
            ushort count = binaryReader.ReadUInt16();
            byte[] array = new byte[(int)num3];
            binaryReader.Read(array, 0, (int)num3);
            zipArchiveFile.Name = Encoding.UTF8.GetString(array);
            binaryReader.ReadBytes((int)count);
            zipArchiveFile.dataPosition = binaryReader.BaseStream.Position;
            binaryReader.BaseStream.Seek((long)((ulong)num2), SeekOrigin.Current);
            return zipArchiveFile;
        }
Exemple #2
0
 /// <summary>
 /// Copyies 'sourceFilePath from the textStream system to the archive as 'targetArchivePath'
 /// It will overwrite any existing textStream.
 /// </summary>
 public void CopyFromFile(string sourceFilePath, string targetArchivePath)
 {
     using (Stream inFile = new FileStream(sourceFilePath, FileMode.Open, FileAccess.Read))
         using (Stream outFile = Create(targetArchivePath))
             ZipArchiveFile.CopyStream(inFile, outFile);
     this[targetArchivePath].LastWriteTime = File.GetLastWriteTime(sourceFilePath);
 }
Exemple #3
0
 /// <summary>
 /// Fetch a archiveFile by name.  'archivePath' is the full path name of the archiveFile in the archive.
 /// It returns null if the name does not exist (and e
 /// </summary>
 public ZipArchiveFile this[string archivePath]
 {
     get
     {
         ZipArchiveFile ret = null;
         entries.TryGetValue(archivePath, out ret);
         return(ret);
     }
 }
Exemple #4
0
    /// <summary>
    /// Overwrites the archive textStream 'archivePath' with the text in 'data'
    /// </summary>
    public void WriteAllText(string archivePath, string data)
    {
        ZipArchiveFile newEntry;

        if (!entries.TryGetValue(archivePath, out newEntry))
        {
            newEntry = new ZipArchiveFile(this, archivePath);
        }
        newEntry.WriteAllText(data);
    }
Exemple #5
0
    /// <summary>
    /// Opens a textStream in the archive for writing as a text textStream.  Returns the resulting TextWriter.
    /// </summary>
    public TextWriter CreateText(string archivePath)
    {
        ZipArchiveFile newEntry;

        if (!entries.TryGetValue(archivePath, out newEntry))
        {
            newEntry = new ZipArchiveFile(this, archivePath);
        }
        return(newEntry.CreateText());
    }
Exemple #6
0
 private void Read(Stream archiveStream)
 {
     // TODO for seekable streams, seek to the end of the stream, and use the archive directory there
     // to avoid reading most of the file.
     for (; ;)
     {
         ZipArchiveFile entry = ZipArchiveFile.Read(this);
         if (entry == null)
         {
             break;
         }
     }
 }
Exemple #7
0
 /// <summary>
 /// Opens a textStream in the archive for writing as a text textStream.  Returns the resulting TextWriter.  
 /// </summary>
 public TextWriter CreateText(string archivePath)
 {
     ZipArchiveFile newEntry;
     if (!entries.TryGetValue(archivePath, out newEntry))
         newEntry = new ZipArchiveFile(this, archivePath);
     return newEntry.CreateText();
 }
Exemple #8
0
 /// <summary>
 /// Opens the archive textStream 'archivePath' for writing and returns the resulting Stream. If the textStream
 /// already exists, it is truncated to be an empty textStream.
 /// </summary>
 public Stream Create(string archivePath)
 {
     ZipArchiveFile newEntry;
     if (!entries.TryGetValue(archivePath, out newEntry))
         newEntry = new ZipArchiveFile(this, archivePath);
     return newEntry.Create();
 }
Exemple #9
0
        /// <summary>
        /// Reads a single archiveFile from a Zip Archive.  Should only be used by ZipArchive.  
        /// </summary>
        /// <returns>A ZipArchiveFile representing the archiveFile read from the archive.</returns>
        internal static ZipArchiveFile Read(ZipArchive archive)
        {
            Stream reader = archive.fromStream;
            ByteBuffer header = new ByteBuffer(30);
            int count = header.ReadContentsFrom(reader);
            if (count == 0)
                return null;

            //Local file header:
            //
            //local file header signature     4 bytes  (0x04034b50)
            //version needed to extract       2 bytes
            //general purpose bit flag        2 bytes
            //compression method              2 bytes
            //last mod file time              2 bytes
            //last mod file date              2 bytes
            //crc-32                          4 bytes
            //compressed size                 4 bytes
            //uncompressed size               4 bytes
            //file name length                2 bytes
            //extra field length              2 bytes
            //
            //file name (variable size)
            //extra field (variable size)

            uint fileSignature = header.ReadUInt32();
            if (fileSignature != SignatureFileEntry) {
                if (fileSignature != SignatureArchiveDirectory)
                    throw new ApplicationException("Bad ZipFile Header");
                return null;
            }

            ushort versionNeededToExtract = header.ReadUInt16();
            if (versionNeededToExtract > MaximumVersionExtractable)
                throw new ApplicationException("Zip file requires unsupported features");

            header.SkipBytes(2); // general purpose bit flag

            ZipArchiveFile newEntry = new ZipArchiveFile(archive, null);

            newEntry.compressionMethod = (CompressionMethod)header.ReadUInt16();
            newEntry.lastWriteTime = DosTimeToDateTime(header.ReadUInt32());
            newEntry.crc32 = header.ReadUInt32();
            newEntry.compressedLength = checked((int)header.ReadUInt32());
            newEntry.length = header.ReadUInt32();
            int fileNameLength = checked((int)header.ReadUInt16());

            byte[] fileNameBuffer = new byte[fileNameLength];
            int fileNameCount = reader.Read(fileNameBuffer, 0, fileNameLength);
            newEntry.name = Encoding.UTF8.GetString(fileNameBuffer).Replace('/', Path.DirectorySeparatorChar);
            archive.entries[newEntry.name] = newEntry;

            if (count != header.Length || fileNameCount != fileNameLength || fileNameLength == 0 || newEntry.LastWriteTime.Ticks == 0)
                throw new ApplicationException("Bad Zip File Header");
            if (newEntry.Name.IndexOfAny(invalidPathChars) >= 0)
                throw new ApplicationException("Invalid File Name");
            if (newEntry.compressionMethod != CompressionMethod.None && newEntry.compressionMethod != CompressionMethod.Deflate)
                throw new ApplicationException("Unsupported compression mode " + newEntry.compressionMethod);

            if (archive.IsReadOnly && reader.CanSeek) {
                // Optimization: we can defer reading in the data in the common case of a read-only archive.
                // by simply remembering where the data is and fetching it on demand.  This is nice because
                // we only hold on to memory of data we are actually operating on.  (instead of the whole archive)
                //
                // Because uncompresseData is null, we know that we fetch it from the archive 'fromStream'.
                newEntry.positionOfCompressedDataInArchive = archive.fromStream.Position;
                reader.Seek(newEntry.compressedLength, SeekOrigin.Current);
            } else {
                // We may be updating the archive in place, so we need to copy the data out.
                newEntry.compressedData = new byte[newEntry.compressedLength];
                reader.Read(newEntry.compressedData, 0, (int)newEntry.compressedLength);
            }

            #if DEBUG
            newEntry.Validate();
            #endif

            return newEntry;
        }
Exemple #10
0
 /// <summary>
 /// Overwrites the archive textStream 'archivePath' with the text in 'data'
 /// </summary>
 public void WriteAllText(string archivePath, string data)
 {
     ZipArchiveFile newEntry;
     if (!entries.TryGetValue(archivePath, out newEntry))
         newEntry = new ZipArchiveFile(this, archivePath);
     newEntry.WriteAllText(data);
 }
Exemple #11
0
    /// <summary>
    /// Reads a single archiveFile from a Zip Archive.  Should only be used by ZipArchive.
    /// </summary>
    /// <returns>A ZipArchiveFile representing the archiveFile read from the archive.</returns>
    internal static ZipArchiveFile Read(ZipArchive archive)
    {
        Stream     reader = archive.fromStream;
        ByteBuffer header = new ByteBuffer(30);
        int        count  = header.ReadContentsFrom(reader);

        if (count == 0)
        {
            return(null);
        }

        //Local file header:
        //
        //local file header signature     4 bytes  (0x04034b50)
        //version needed to extract       2 bytes
        //general purpose bit flag        2 bytes
        //compression method              2 bytes
        //last mod file time              2 bytes
        //last mod file date              2 bytes
        //crc-32                          4 bytes
        //compressed size                 4 bytes
        //uncompressed size               4 bytes
        //file name length                2 bytes
        //extra field length              2 bytes
        //
        //file name (variable size)
        //extra field (variable size)

        uint fileSignature = header.ReadUInt32();

        if (fileSignature != SignatureFileEntry)
        {
            if (fileSignature != SignatureArchiveDirectory)
            {
                throw new ApplicationException("Bad ZipFile Header");
            }
            return(null);
        }

        ushort versionNeededToExtract = header.ReadUInt16();

        if (versionNeededToExtract > MaximumVersionExtractable)
        {
            throw new ApplicationException("Zip file requires unsupported features");
        }

        header.SkipBytes(2); // general purpose bit flag

        ZipArchiveFile newEntry = new ZipArchiveFile(archive, null);

        newEntry.compressionMethod = (CompressionMethod)header.ReadUInt16();
        newEntry.lastWriteTime     = DosTimeToDateTime(header.ReadUInt32());
        newEntry.crc32             = header.ReadUInt32();
        newEntry.compressedLength  = checked ((int)header.ReadUInt32());
        newEntry.length            = header.ReadUInt32();
        int fileNameLength = checked ((int)header.ReadUInt16());

        byte[] fileNameBuffer = new byte[fileNameLength];
        int    fileNameCount  = reader.Read(fileNameBuffer, 0, fileNameLength);

        newEntry.name = Encoding.UTF8.GetString(fileNameBuffer);
        archive.entries[newEntry.name] = newEntry;

        if (count != header.Length || fileNameCount != fileNameLength || fileNameLength == 0 || newEntry.LastWriteTime.Ticks == 0)
        {
            throw new ApplicationException("Bad Zip File Header");
        }
        if (newEntry.Name.IndexOfAny(invalidPathChars) >= 0)
        {
            throw new ApplicationException("Invalid File Name");
        }
        if (newEntry.compressionMethod != CompressionMethod.None && newEntry.compressionMethod != CompressionMethod.Deflate)
        {
            throw new ApplicationException("Unsupported compression mode " + newEntry.compressionMethod);
        }

        if (archive.IsReadOnly && reader.CanSeek)
        {
            // Optimization: we can defer reading in the data in the common case of a read-only archive.
            // by simply remembering where the data is and fetching it on demand.  This is nice because
            // we only hold on to memory of data we are actually operating on.  (instead of the whole archive)
            //
            // Because uncompresseData is null, we know that we fetch it from the archive 'fromStream'.
            newEntry.positionOfCompressedDataInArchive = archive.fromStream.Position;
            reader.Seek(newEntry.compressedLength, SeekOrigin.Current);
        }
        else
        {
            // We may be updating the archive in place, so we need to copy the data out.
            newEntry.compressedData = new byte[newEntry.compressedLength];
            reader.Read(newEntry.compressedData, 0, (int)newEntry.compressedLength);
        }

#if DEBUG
        newEntry.Validate();
#endif

        return(newEntry);
    }
        public override bool Execute()
        {
            // There's nothing to do if we have no files or not Xap name given
            if (XapFile == null || Files == null || Files.Length == 0)
            {
                return(true);
            }

            string xapPath = XapFile.ItemSpec;

            if (!File.Exists(xapPath))
            {
                Log.LogError("The Xap file {0} could not be found.", xapPath);
                return(false);
            }

            bool succeeded = true;

            try
            {
                ZipArchive xap = new ZipArchive(xapPath, FileAccess.ReadWrite);

                // Process the files
                for (int i = 0; i < Files.Length; i++)
                {
                    string   sourcePath = Files[i].ItemSpec;
                    FileInfo sourceInfo = new FileInfo(sourcePath);

                    string saveFileAs = sourceInfo.Name;
                    if (!string.IsNullOrEmpty(FileReplacementToken))
                    {
                        saveFileAs = saveFileAs.Replace(FileReplacementToken, string.Empty);
                    }

                    // Make sure they didn't pass a directory as an item
                    if (Directory.Exists(sourcePath))
                    {
                        Log.LogError("Cannot process item \"{0}\" because it is a directory!", sourcePath);
                        succeeded = false;
                        continue;
                    }

                    // Make sure the source exists
                    if (!sourceInfo.Exists)
                    {
                        Log.LogError("Cannot process file \"{0}\" that does not exist!", sourcePath);
                        succeeded = false;
                        continue;
                    }

                    ZipArchiveFile zaf = xap[saveFileAs];
                    if (zaf == null)
                    {
                        Log.LogError(
                            "The file \"{0}\" was not found inside the Xap file \"{1}\"",
                            saveFileAs,
                            xapPath);
                        succeeded = false;
                    }
                    else
                    {
                        zaf.Delete();

                        // Overwrite the contents inside the Xap
                        using (Stream fileInsideXap = xap.Create(saveFileAs))
                        {
                            using (Stream newFile = sourceInfo.OpenRead())
                            {
                                ZipArchiveFile.CopyStream(newFile, fileInsideXap);
                            }
                        }

                        Log.LogMessage(
                            MessageImportance.High,
                            "File \"{0}\" inside the Xap file \"{1}\" was replaced with the contents of \"{2}\"",
                            saveFileAs,
                            xapPath,
                            sourcePath);
                    }
                }

                // Close the Xap file, saving any changes
                xap.Close();

                Log.LogMessage("Xap file \"{0}\" saved.", xapPath);
            }
            catch (Exception ex)
            {
                Log.LogErrorFromException(ex);
                succeeded = false;
            }

            return(succeeded);
        }