📄 7zin.c
字号:
break; if (value < 0x80) continue; if (value >= 0xD800 && value < 0xE000) { UInt32 c2; if (value >= 0xDC00) return SZE_ARCHIVE_ERROR; if (pos + 2 > sd->Size) return SZE_ARCHIVE_ERROR; c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8)); pos += 2; if (c2 < 0xDC00 || c2 >= 0xE000) return SZE_ARCHIVE_ERROR; value = ((value - 0xD800) << 10) | (c2 - 0xDC00); } for (numAdds = 1; numAdds < 5; numAdds++) if (value < (((UInt32)1) << (numAdds * 5 + 6))) break; len += numAdds; } MY_ALLOC(char, file->Name, (size_t)len, allocFunc); len = 0; while(2 <= sd->Size) { int numAdds; UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8)); SzSkeepDataSize(sd, 2); if (value < 0x80) { file->Name[len++] = (char)value; if (value == 0) break; continue; } if (value >= 0xD800 && value < 0xE000) { UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8)); SzSkeepDataSize(sd, 2); value = ((value - 0xD800) << 10) | (c2 - 0xDC00); } for (numAdds = 1; numAdds < 5; numAdds++) if (value < (((UInt32)1) << (numAdds * 5 + 6))) break; file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds))); do { numAdds--; file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); } while(numAdds > 0); len += numAdds; } } return SZ_OK;}SZ_RESULT SzReadHeader2( CSzData *sd, CArchiveDatabaseEx *db, /* allocMain */ CFileSize **unPackSizes, /* allocTemp */ Byte **digestsDefined, /* allocTemp */ UInt32 **digests, /* allocTemp */ Byte **emptyStreamVector, /* allocTemp */ Byte **emptyFileVector, /* allocTemp */ ISzAlloc *allocMain, ISzAlloc *allocTemp){ UInt64 type; UInt32 numUnPackStreams = 0; UInt32 numFiles = 0; CFileItem *files = 0; UInt32 numEmptyStreams = 0; UInt32 i; RINOK(SzReadID(sd, &type)); if (type == k7zIdArchiveProperties) { RINOK(SzReadArchiveProperties(sd)); RINOK(SzReadID(sd, &type)); } if (type == k7zIdMainStreamsInfo) { RINOK(SzReadStreamsInfo(sd, &db->ArchiveInfo.DataStartPosition, &db->Database, &numUnPackStreams, unPackSizes, digestsDefined, digests, allocMain->Alloc, allocTemp)); db->ArchiveInfo.DataStartPosition += db->ArchiveInfo.StartPositionAfterHeader; RINOK(SzReadID(sd, &type)); } if (type == k7zIdEnd) return SZ_OK; if (type != k7zIdFilesInfo) return SZE_ARCHIVE_ERROR; RINOK(SzReadNumber32(sd, &numFiles)); db->Database.NumFiles = numFiles; MY_ALLOC(CFileItem, files, (size_t)numFiles, allocMain->Alloc); db->Database.Files = files; for(i = 0; i < numFiles; i++) SzFileInit(files + i); while(1) { UInt64 type; UInt64 size; RINOK(SzReadID(sd, &type)); if (type == k7zIdEnd) break; RINOK(SzReadNumber(sd, &size)); if ((UInt64)(int)type != type) { RINOK(SzSkeepDataSize(sd, size)); } else switch((int)type) { case k7zIdName: { RINOK(SzReadSwitch(sd)); RINOK(SzReadFileNames(sd, numFiles, files, allocMain->Alloc)) break; } case k7zIdEmptyStream: { RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp->Alloc)); numEmptyStreams = 0; for (i = 0; i < numFiles; i++) if ((*emptyStreamVector)[i]) numEmptyStreams++; break; } case k7zIdEmptyFile: { RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp->Alloc)); break; } default: { RINOK(SzSkeepDataSize(sd, size)); } } } { UInt32 emptyFileIndex = 0; UInt32 sizeIndex = 0; for(i = 0; i < numFiles; i++) { CFileItem *file = files + i; file->IsAnti = 0; if (*emptyStreamVector == 0) file->HasStream = 1; else file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1); if(file->HasStream) { file->IsDirectory = 0; file->Size = (*unPackSizes)[sizeIndex]; file->FileCRC = (*digests)[sizeIndex]; file->IsFileCRCDefined = (Byte)(*digestsDefined)[sizeIndex]; sizeIndex++; } else { if (*emptyFileVector == 0) file->IsDirectory = 1; else file->IsDirectory = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1); emptyFileIndex++; file->Size = 0; file->IsFileCRCDefined = 0; } } } return SzArDbExFill(db, allocMain->Alloc);}SZ_RESULT SzReadHeader( CSzData *sd, CArchiveDatabaseEx *db, ISzAlloc *allocMain, ISzAlloc *allocTemp){ CFileSize *unPackSizes = 0; Byte *digestsDefined = 0; UInt32 *digests = 0; Byte *emptyStreamVector = 0; Byte *emptyFileVector = 0; SZ_RESULT res = SzReadHeader2(sd, db, &unPackSizes, &digestsDefined, &digests, &emptyStreamVector, &emptyFileVector, allocMain, allocTemp); allocTemp->Free(unPackSizes); allocTemp->Free(digestsDefined); allocTemp->Free(digests); allocTemp->Free(emptyStreamVector); allocTemp->Free(emptyFileVector); return res;} SZ_RESULT SzReadAndDecodePackedStreams2( ISzInStream *inStream, CSzData *sd, CSzByteBuffer *outBuffer, CFileSize baseOffset, CArchiveDatabase *db, CFileSize **unPackSizes, Byte **digestsDefined, UInt32 **digests, #ifndef _LZMA_IN_CB Byte **inBuffer, #endif ISzAlloc *allocTemp){ UInt32 numUnPackStreams = 0; CFileSize dataStartPos; CFolder *folder; #ifndef _LZMA_IN_CB CFileSize packSize = 0; UInt32 i = 0; #endif CFileSize unPackSize; size_t outRealSize; SZ_RESULT res; RINOK(SzReadStreamsInfo(sd, &dataStartPos, db, &numUnPackStreams, unPackSizes, digestsDefined, digests, allocTemp->Alloc, allocTemp)); dataStartPos += baseOffset; if (db->NumFolders != 1) return SZE_ARCHIVE_ERROR; folder = db->Folders; unPackSize = SzFolderGetUnPackSize(folder); RINOK(inStream->Seek(inStream, dataStartPos)); #ifndef _LZMA_IN_CB for (i = 0; i < db->NumPackStreams; i++) packSize += db->PackSizes[i]; MY_ALLOC(Byte, *inBuffer, (size_t)packSize, allocTemp->Alloc); RINOK(SafeReadDirect(inStream, *inBuffer, (size_t)packSize)); #endif if (!SzByteBufferCreate(outBuffer, (size_t)unPackSize, allocTemp->Alloc)) return SZE_OUTOFMEMORY; res = SzDecode(db->PackSizes, folder, #ifdef _LZMA_IN_CB inStream, #else *inBuffer, #endif outBuffer->Items, (size_t)unPackSize, &outRealSize, allocTemp); RINOK(res) if (outRealSize != (UInt32)unPackSize) return SZE_FAIL; if (folder->UnPackCRCDefined) if (!CrcVerifyDigest(folder->UnPackCRC, outBuffer->Items, (size_t)unPackSize)) return SZE_FAIL; return SZ_OK;}SZ_RESULT SzReadAndDecodePackedStreams( ISzInStream *inStream, CSzData *sd, CSzByteBuffer *outBuffer, CFileSize baseOffset, ISzAlloc *allocTemp){ CArchiveDatabase db; CFileSize *unPackSizes = 0; Byte *digestsDefined = 0; UInt32 *digests = 0; #ifndef _LZMA_IN_CB Byte *inBuffer = 0; #endif SZ_RESULT res; SzArchiveDatabaseInit(&db); res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset, &db, &unPackSizes, &digestsDefined, &digests, #ifndef _LZMA_IN_CB &inBuffer, #endif allocTemp); SzArchiveDatabaseFree(&db, allocTemp->Free); allocTemp->Free(unPackSizes); allocTemp->Free(digestsDefined); allocTemp->Free(digests); #ifndef _LZMA_IN_CB allocTemp->Free(inBuffer); #endif return res;}SZ_RESULT SzArchiveOpen2( ISzInStream *inStream, CArchiveDatabaseEx *db, ISzAlloc *allocMain, ISzAlloc *allocTemp){ Byte signature[k7zSignatureSize]; Byte version; UInt32 crcFromArchive; UInt64 nextHeaderOffset; UInt64 nextHeaderSize; UInt32 nextHeaderCRC; UInt32 crc; CFileSize pos = 0; CSzByteBuffer buffer; CSzData sd; SZ_RESULT res; RINOK(SafeReadDirect(inStream, signature, k7zSignatureSize)); if (!TestSignatureCandidate(signature)) return SZE_ARCHIVE_ERROR; /* db.Clear(); db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition; */ RINOK(SafeReadDirectByte(inStream, &version)); if (version != k7zMajorVersion) return SZE_ARCHIVE_ERROR; RINOK(SafeReadDirectByte(inStream, &version)); RINOK(SafeReadDirectUInt32(inStream, &crcFromArchive)); CrcInit(&crc); RINOK(SafeReadDirectUInt64(inStream, &nextHeaderOffset)); CrcUpdateUInt64(&crc, nextHeaderOffset); RINOK(SafeReadDirectUInt64(inStream, &nextHeaderSize)); CrcUpdateUInt64(&crc, nextHeaderSize); RINOK(SafeReadDirectUInt32(inStream, &nextHeaderCRC)); CrcUpdateUInt32(&crc, nextHeaderCRC); pos = k7zStartHeaderSize; db->ArchiveInfo.StartPositionAfterHeader = pos; if (CrcGetDigest(&crc) != crcFromArchive) return SZE_ARCHIVE_ERROR; if (nextHeaderSize == 0) return SZ_OK; RINOK(inStream->Seek(inStream, (CFileSize)(pos + nextHeaderOffset))); if (!SzByteBufferCreate(&buffer, (size_t)nextHeaderSize, allocTemp->Alloc)) return SZE_OUTOFMEMORY; res = SafeReadDirect(inStream, buffer.Items, (size_t)nextHeaderSize); if (res == SZ_OK) { if (CrcVerifyDigest(nextHeaderCRC, buffer.Items, (UInt32)nextHeaderSize)) { while (1) { UInt64 type; sd.Data = buffer.Items; sd.Size = buffer.Capacity; res = SzReadID(&sd, &type); if (res != SZ_OK) break; if (type == k7zIdHeader) { res = SzReadHeader(&sd, db, allocMain, allocTemp); break; } if (type != k7zIdEncodedHeader) { res = SZE_ARCHIVE_ERROR; break; } { CSzByteBuffer outBuffer; res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, db->ArchiveInfo.StartPositionAfterHeader, allocTemp); if (res != SZ_OK) { SzByteBufferFree(&outBuffer, allocTemp->Free); break; } SzByteBufferFree(&buffer, allocTemp->Free); buffer.Items = outBuffer.Items; buffer.Capacity = outBuffer.Capacity; } } } } SzByteBufferFree(&buffer, allocTemp->Free); return res;}SZ_RESULT SzArchiveOpen( ISzInStream *inStream, CArchiveDatabaseEx *db, ISzAlloc *allocMain, ISzAlloc *allocTemp){ SZ_RESULT res = SzArchiveOpen2(inStream, db, allocMain, allocTemp); if (res != SZ_OK) SzArDbExFree(db, allocMain->Free); return res;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -