📄 zipin.cpp
字号:
ThrowIncorrectArchiveException(); */ item.FileHeaderWithNameSize = 4 + NFileHeader::kLocalBlockSize + fileNameSize; // IncreaseRealPosition(item.LocalExtraSize); if (item.LocalExtraSize > 0) { UInt64 localHeaderOffset = 0; UInt32 diskStartNumber = 0; CExtraBlock extraBlock; ReadExtra(item.LocalExtraSize, extraBlock, item.UnPackSize, item.PackSize, localHeaderOffset, diskStartNumber); } if (item.HasDescriptor()) { const int kBufferSize = (1 << 12); Byte buffer[kBufferSize]; UInt32 numBytesInBuffer = 0; UInt32 packedSize = 0; bool descriptorWasFound = false; while (true) { UInt32 processedSize; RINOK(ReadBytes(buffer + numBytesInBuffer, kBufferSize - numBytesInBuffer, &processedSize)); numBytesInBuffer += processedSize; if (numBytesInBuffer < NFileHeader::kDataDescriptorSize) ThrowIncorrectArchiveException(); UInt32 i; for (i = 0; i <= numBytesInBuffer - NFileHeader::kDataDescriptorSize; i++) { // descriptorSignature field is Info-ZIP's extension // to Zip specification. UInt32 descriptorSignature = GetUInt32(buffer + i); // !!!! It must be fixed for Zip64 archives UInt32 descriptorPackSize = GetUInt32(buffer + i + 8); if (descriptorSignature== NSignature::kDataDescriptor && descriptorPackSize == packedSize + i) { descriptorWasFound = true; item.FileCRC = GetUInt32(buffer + i + 4); item.PackSize = descriptorPackSize; item.UnPackSize = GetUInt32(buffer + i + 12); IncreaseRealPosition(Int64(Int32(0 - (numBytesInBuffer - i - NFileHeader::kDataDescriptorSize)))); break; }; } if (descriptorWasFound) break; packedSize += i; int j; for (j = 0; i < numBytesInBuffer; i++, j++) buffer[j] = buffer[i]; numBytesInBuffer = j; } } else IncreaseRealPosition(item.PackSize); items.Add(item); if (progress != 0) { UInt64 numItems = items.Size(); RINOK(progress->SetCompleted(&numItems)); } if (!ReadUInt32(m_Signature)) break; } UInt64 centralDirectorySize = 0; UInt64 centralDirectoryStartOffset = m_Position - 4; for(int i = 0; i < items.Size(); i++) { if (progress != 0) { UInt64 numItems = items.Size(); RINOK(progress->SetCompleted(&numItems)); } // if(m_Signature == NSignature::kEndOfCentralDir) // break; if(m_Signature != NSignature::kCentralFileHeader) ThrowIncorrectArchiveException(); // NFileHeader::CBlock header; // SafeReadBytes(&header, sizeof(header)); Byte headerMadeByVersionVersion = ReadByte(); Byte headerMadeByVersionHostOS = ReadByte(); Byte centalHeaderExtractVersionVersion = ReadByte(); Byte centalHeaderExtractVersionHostOS = ReadByte(); UInt16 headerFlags = ReadUInt16() & NFileHeader::NFlags::kUsedBitsMask; UInt16 headerCompressionMethod = ReadUInt16(); UInt32 headerTime = ReadUInt32(); UInt32 headerFileCRC = ReadUInt32(); UInt64 headerPackSize = ReadUInt32(); UInt64 headerUnPackSize = ReadUInt32(); UInt16 headerNameSize = ReadUInt16(); UInt16 headerExtraSize = ReadUInt16(); UInt16 headerCommentSize = ReadUInt16(); UInt32 headerDiskNumberStart = ReadUInt16(); UInt16 headerInternalAttributes = ReadUInt16(); UInt32 headerExternalAttributes = ReadUInt32(); UInt64 localHeaderOffset = ReadUInt32(); AString centralName = ReadFileName(headerNameSize); // item.Name = ReadFileName(fileNameSize); CExtraBlock centralExtra; if (headerExtraSize > 0) { ReadExtra(headerExtraSize, centralExtra, headerUnPackSize, headerPackSize, localHeaderOffset, headerDiskNumberStart); } int index; int left = 0, right = items.Size(); while(true) { if (left >= right) ThrowIncorrectArchiveException(); index = (left + right) / 2; UInt64 position = items[index].LocalHeaderPosition; if (localHeaderOffset == position) break; if (localHeaderOffset < position) right = index; else left = index + 1; } CItemEx &item = items[index]; item.MadeByVersion.Version = headerMadeByVersionVersion; item.MadeByVersion.HostOS = headerMadeByVersionHostOS; item.CentralExtra = centralExtra; if ( // item.ExtractVersion != centalHeaderExtractVersion || item.Flags != headerFlags || item.CompressionMethod != headerCompressionMethod || // item.Time != header.Time || item.FileCRC != headerFileCRC) ThrowIncorrectArchiveException(); if (item.Name.Length() != centralName.Length()) ThrowIncorrectArchiveException(); // test it maybe better compare names item.Name = centralName; // item.CentralExtraPosition = m_Position; // item.CentralExtraSize = headerExtraSize; // item.CommentSize = headerCommentSize; if (headerDiskNumberStart != 0) throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported); item.InternalAttributes = headerInternalAttributes; item.ExternalAttributes = headerExternalAttributes; // May be these strings must be deleted if (item.IsDirectory()) { // if (item.PackSize != 0 /* || item.UnPackSize != 0 */) // ThrowIncorrectArchiveException(); item.UnPackSize = 0; } UInt32 currentRecordSize = 4 + NFileHeader::kCentralBlockSize + headerNameSize + headerExtraSize + headerCommentSize; centralDirectorySize += currentRecordSize; // IncreaseRealPosition(headerExtraSize); if ( item.PackSize != headerPackSize || item.UnPackSize != headerUnPackSize ) ThrowIncorrectArchiveException(); // IncreaseRealPosition(headerCommentSize); ReadBuffer(item.Comment, headerCommentSize); if (!ReadUInt32(m_Signature)) break; } UInt32 thisDiskNumber = 0; UInt32 startCDDiskNumber = 0; UInt64 numEntriesInCDOnThisDisk = 0; UInt64 numEntriesInCD = 0; UInt64 cdSize = 0; UInt64 cdStartOffsetFromRecord = 0; bool isZip64 = false; UInt64 zip64EndOfCDStartOffset = m_Position - 4; if(m_Signature == NSignature::kZip64EndOfCentralDir) { isZip64 = true; UInt64 recordSize = ReadUInt64(); UInt16 versionMade = ReadUInt16(); UInt16 versionNeedExtract = ReadUInt16(); thisDiskNumber = ReadUInt32(); startCDDiskNumber = ReadUInt32(); numEntriesInCDOnThisDisk = ReadUInt64(); numEntriesInCD = ReadUInt64(); cdSize = ReadUInt64(); cdStartOffsetFromRecord = ReadUInt64(); IncreaseRealPosition(recordSize - kZip64EndOfCentralDirRecordSize); if (!ReadUInt32(m_Signature)) return S_FALSE; if (thisDiskNumber != 0 || startCDDiskNumber != 0) throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported); if (numEntriesInCDOnThisDisk != items.Size() || numEntriesInCD != items.Size() || cdSize != centralDirectorySize || (cdStartOffsetFromRecord != centralDirectoryStartOffset && (!items.IsEmpty()))) ThrowIncorrectArchiveException(); } if(m_Signature == NSignature::kZip64EndOfCentralDirLocator) { UInt32 startEndCDDiskNumber = ReadUInt32(); UInt64 endCDStartOffset = ReadUInt64(); UInt32 numberOfDisks = ReadUInt32(); if (zip64EndOfCDStartOffset != endCDStartOffset) ThrowIncorrectArchiveException(); if (!ReadUInt32(m_Signature)) return S_FALSE; } if(m_Signature != NSignature::kEndOfCentralDir) ThrowIncorrectArchiveException(); UInt16 thisDiskNumber16 = ReadUInt16(); if (!isZip64 || thisDiskNumber16) thisDiskNumber = thisDiskNumber16; UInt16 startCDDiskNumber16 = ReadUInt16(); if (!isZip64 || startCDDiskNumber16 != 0xFFFF) startCDDiskNumber = startCDDiskNumber16; UInt16 numEntriesInCDOnThisDisk16 = ReadUInt16(); if (!isZip64 || numEntriesInCDOnThisDisk16 != 0xFFFF) numEntriesInCDOnThisDisk = numEntriesInCDOnThisDisk16; UInt16 numEntriesInCD16 = ReadUInt16(); if (!isZip64 || numEntriesInCD16 != 0xFFFF) numEntriesInCD = numEntriesInCD16; UInt32 cdSize32 = ReadUInt32(); if (!isZip64 || cdSize32 != 0xFFFFFFFF) cdSize = cdSize32; UInt32 cdStartOffsetFromRecord32 = ReadUInt32(); if (!isZip64 || cdStartOffsetFromRecord32 != 0xFFFFFFFF) cdStartOffsetFromRecord = cdStartOffsetFromRecord32; UInt16 commentSize = ReadUInt16(); ReadBuffer(m_ArchiveInfo.Comment, commentSize); if (thisDiskNumber != 0 || startCDDiskNumber != 0) throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported); if ((UInt16)numEntriesInCDOnThisDisk != ((UInt16)items.Size()) || (UInt16)numEntriesInCD != ((UInt16)items.Size()) || (UInt32)cdSize != (UInt32)centralDirectorySize || ((UInt32)(cdStartOffsetFromRecord) != (UInt32)centralDirectoryStartOffset && (!items.IsEmpty()))) ThrowIncorrectArchiveException(); return S_OK;}ISequentialInStream* CInArchive::CreateLimitedStream(UInt64 position, UInt64 size){ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; CMyComPtr<ISequentialInStream> inStream(streamSpec); SeekInArchive(position); streamSpec->Init(m_Stream, size); return inStream.Detach();}IInStream* CInArchive::CreateStream(){ CMyComPtr<IInStream> inStream = m_Stream; return inStream.Detach();}bool CInArchive::SeekInArchive(UInt64 position){ UInt64 newPosition; if(m_Stream->Seek(position, STREAM_SEEK_SET, &newPosition) != S_OK) return false; return (newPosition == position);}}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -