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; }
/// <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); }
/// <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); } }
/// <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); }
/// <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()); }
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; } } }
/// <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(); }
/// <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(); }
/// <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; }
/// <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); }
/// <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); }