1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/* 7zIn.c -- 7z Input functions 2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync2010-10-29 : Igor Pavlov : Public domain */ 3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include <string.h> 5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7z.h" 7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7zCrc.h" 8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "CpuArch.h" 9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 10baa3858d3f5d128a5c8466b700098109edcad5f2repo syncByte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; 11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; } 13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define NUM_FOLDER_CODERS_MAX 32 15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define NUM_CODER_STREAMS_MAX 32 16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 17baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid SzCoderInfo_Init(CSzCoderInfo *p) 18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Buf_Init(&p->Props); 20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 22baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc) 23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Buf_Free(&p->Props, alloc); 25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SzCoderInfo_Init(p); 26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 28baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid SzFolder_Init(CSzFolder *p) 29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->Coders = 0; 31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->BindPairs = 0; 32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->PackStreams = 0; 33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->UnpackSizes = 0; 34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->NumCoders = 0; 35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->NumBindPairs = 0; 36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->NumPackStreams = 0; 37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->UnpackCRCDefined = 0; 38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->UnpackCRC = 0; 39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->NumUnpackStreams = 0; 40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 42baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid SzFolder_Free(CSzFolder *p, ISzAlloc *alloc) 43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 i; 45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->Coders) 46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < p->NumCoders; i++) 47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SzCoderInfo_Free(&p->Coders[i], alloc); 48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(alloc, p->Coders); 49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(alloc, p->BindPairs); 50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(alloc, p->PackStreams); 51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(alloc, p->UnpackSizes); 52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SzFolder_Init(p); 53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 55baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt32 SzFolder_GetNumOutStreams(CSzFolder *p) 56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 result = 0; 58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 i; 59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < p->NumCoders; i++) 60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync result += p->Coders[i].NumOutStreams; 61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return result; 62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 64baa3858d3f5d128a5c8466b700098109edcad5f2repo syncint SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex) 65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 i; 67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < p->NumBindPairs; i++) 68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->BindPairs[i].InIndex == inStreamIndex) 69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return i; 70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return -1; 71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 74baa3858d3f5d128a5c8466b700098109edcad5f2repo syncint SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex) 75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 i; 77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < p->NumBindPairs; i++) 78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->BindPairs[i].OutIndex == outStreamIndex) 79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return i; 80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return -1; 81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 83baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt64 SzFolder_GetUnpackSize(CSzFolder *p) 84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int i = (int)SzFolder_GetNumOutStreams(p); 86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (i == 0) 87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 0; 88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i--; i >= 0; i--) 89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (SzFolder_FindBindPairForOutStream(p, i) < 0) 90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return p->UnpackSizes[i]; 91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* throw 1; */ 92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 0; 93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 95baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid SzFile_Init(CSzFileItem *p) 96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->HasStream = 1; 98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->IsDir = 0; 99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->IsAnti = 0; 100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->CrcDefined = 0; 101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->MTimeDefined = 0; 102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 104baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid SzAr_Init(CSzAr *p) 105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->PackSizes = 0; 107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->PackCRCsDefined = 0; 108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->PackCRCs = 0; 109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->Folders = 0; 110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->Files = 0; 111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->NumPackStreams = 0; 112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->NumFolders = 0; 113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->NumFiles = 0; 114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 116baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid SzAr_Free(CSzAr *p, ISzAlloc *alloc) 117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 i; 119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->Folders) 120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < p->NumFolders; i++) 121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SzFolder_Free(&p->Folders[i], alloc); 122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(alloc, p->PackSizes); 124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(alloc, p->PackCRCsDefined); 125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(alloc, p->PackCRCs); 126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(alloc, p->Folders); 127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(alloc, p->Files); 128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SzAr_Init(p); 129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 132baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid SzArEx_Init(CSzArEx *p) 133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SzAr_Init(&p->db); 135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->FolderStartPackStreamIndex = 0; 136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->PackStreamStartPositions = 0; 137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->FolderStartFileIndex = 0; 138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->FileIndexToFolderIndexMap = 0; 139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->FileNameOffsets = 0; 140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Buf_Init(&p->FileNames); 141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 143baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid SzArEx_Free(CSzArEx *p, ISzAlloc *alloc) 144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(alloc, p->FolderStartPackStreamIndex); 146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(alloc, p->PackStreamStartPositions); 147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(alloc, p->FolderStartFileIndex); 148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(alloc, p->FileIndexToFolderIndexMap); 149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(alloc, p->FileNameOffsets); 151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Buf_Free(&p->FileNames, alloc); 152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SzAr_Free(&p->db, alloc); 154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SzArEx_Init(p); 155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/* 158baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const 159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; 161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 163baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt64 GetFilePackSize(int fileIndex) const 164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int folderIndex = FileIndexToFolderIndexMap[fileIndex]; 166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (folderIndex >= 0) 167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CSzFolder &folderInfo = Folders[folderIndex]; 169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (FolderStartFileIndex[folderIndex] == fileIndex) 170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return GetFolderFullPackSize(folderIndex); 171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 0; 173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync*/ 175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \ 177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; } 178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 179baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc) 180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 startPos = 0; 182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 startPosSize = 0; 183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 i; 184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 folderIndex = 0; 185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 indexInFolder = 0; 186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_ALLOC(UInt32, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc); 187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < p->db.NumFolders; i++) 188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->FolderStartPackStreamIndex[i] = startPos; 190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync startPos += p->db.Folders[i].NumPackStreams; 191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc); 194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < p->db.NumPackStreams; i++) 196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->PackStreamStartPositions[i] = startPosSize; 198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync startPosSize += p->db.PackSizes[i]; 199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders, alloc); 202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc); 203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < p->db.NumFiles; i++) 205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzFileItem *file = p->db.Files + i; 207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int emptyStream = !file->HasStream; 208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (emptyStream && indexInFolder == 0) 209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->FileIndexToFolderIndexMap[i] = (UInt32)-1; 211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (indexInFolder == 0) 214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* 216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync v3.13 incorrectly worked with empty folders 217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync v4.07: Loop for skipping empty folders 218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync */ 219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (folderIndex >= p->db.NumFolders) 222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_ARCHIVE; 223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->FolderStartFileIndex[folderIndex] = i; 224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->db.Folders[folderIndex].NumUnpackStreams != 0) 225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync folderIndex++; 227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->FileIndexToFolderIndexMap[i] = folderIndex; 230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (emptyStream) 231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync indexInFolder++; 233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams) 234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync folderIndex++; 236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync indexInFolder = 0; 237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 243baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder) 244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return p->dataPos + 246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder]; 247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 249baa3858d3f5d128a5c8466b700098109edcad5f2repo syncint SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize) 250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex]; 252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzFolder *folder = p->db.Folders + folderIndex; 253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 size = 0; 254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 i; 255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < folder->NumPackStreams; i++) 256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 t = size + p->db.PackSizes[packStreamIndex + i]; 258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (t < size) /* check it */ 259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_FAIL; 260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size = t; 261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *resSize = size; 263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/* 268baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSRes SzReadTime(const CObjectVector<CBuf> &dataVector, 269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CObjectVector<CSzFileItem> &files, UInt64 type) 270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CBoolVector boolVector; 272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(ReadBoolVector2(files.Size(), boolVector)) 273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CStreamSwitch streamSwitch; 275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(streamSwitch.Set(this, &dataVector)); 276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < files.Size(); i++) 278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzFileItem &file = files[i]; 280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CArchiveFileTime fileTime; 281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool defined = boolVector[i]; 282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (defined) 283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 low, high; 285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadUInt32(low)); 286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadUInt32(high)); 287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync fileTime.dwLowDateTime = low; 288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync fileTime.dwHighDateTime = high; 289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync switch(type) 291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break; 293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break; 294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break; 295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync*/ 300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 301baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic int TestSignatureCandidate(Byte *testBytes) 302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t i; 304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < k7zSignatureSize; i++) 305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (testBytes[i] != k7zSignature[i]) 306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 0; 307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 1; 308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 310baa3858d3f5d128a5c8466b700098109edcad5f2repo synctypedef struct _CSzState 311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte *Data; 313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t Size; 314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}CSzData; 315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 316baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadByte(CSzData *sd, Byte *b) 317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (sd->Size == 0) 319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_ARCHIVE; 320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sd->Size--; 321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *b = *sd->Data++; 322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 325baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadBytes(CSzData *sd, Byte *data, size_t size) 326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t i; 328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < size; i++) 329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadByte(sd, data + i)); 331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 335baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadUInt32(CSzData *sd, UInt32 *value) 336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int i; 338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *value = 0; 339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < 4; i++) 340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 341baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte b; 342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadByte(sd, &b)); 343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *value |= ((UInt32)(b) << (8 * i)); 344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 348baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadNumber(CSzData *sd, UInt64 *value) 349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte firstByte; 351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte mask = 0x80; 352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int i; 353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadByte(sd, &firstByte)); 354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *value = 0; 355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < 8; i++) 356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte b; 358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((firstByte & mask) == 0) 359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 highPart = firstByte & (mask - 1); 361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *value += (highPart << (8 * i)); 362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadByte(sd, &b)); 365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *value |= ((UInt64)b << (8 * i)); 366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync mask >>= 1; 367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 371baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadNumber32(CSzData *sd, UInt32 *value) 372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 value64; 374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber(sd, &value64)); 375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (value64 >= 0x80000000) 376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_UNSUPPORTED; 377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2))) 378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_UNSUPPORTED; 379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *value = (UInt32)value64; 380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 383baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadID(CSzData *sd, UInt64 *value) 384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SzReadNumber(sd, value); 386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 388baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzSkeepDataSize(CSzData *sd, UInt64 size) 389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (size > sd->Size) 391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_ARCHIVE; 392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sd->Size -= (size_t)size; 393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sd->Data += (size_t)size; 394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 397baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzSkeepData(CSzData *sd) 398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 size; 400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber(sd, &size)); 401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SzSkeepDataSize(sd, size); 402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 403baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 404baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadArchiveProperties(CSzData *sd) 405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 type; 409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadID(sd, &type)); 410baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == k7zIdEnd) 411baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SzSkeepData(sd); 413baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 415baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 417baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzWaitAttribute(CSzData *sd, UInt64 attribute) 418baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 419baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 type; 422baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadID(sd, &type)); 423baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == attribute) 424baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 425baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == k7zIdEnd) 426baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_ARCHIVE; 427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzSkeepData(sd)); 428baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 431baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) 432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 433baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte b = 0; 434baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte mask = 0; 435baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t i; 436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_ALLOC(Byte, *v, numItems, alloc); 437baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numItems; i++) 438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 439baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (mask == 0) 440baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadByte(sd, &b)); 442baa3858d3f5d128a5c8466b700098109edcad5f2repo sync mask = 0x80; 443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0); 445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync mask >>= 1; 446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 448baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 449baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 450baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) 451baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 452baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte allAreDefined; 453baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t i; 454baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadByte(sd, &allAreDefined)); 455baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (allAreDefined == 0) 456baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SzReadBoolVector(sd, numItems, v, alloc); 457baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_ALLOC(Byte, *v, numItems, alloc); 458baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numItems; i++) 459baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (*v)[i] = 1; 460baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 461baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 462baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 463baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadHashDigests( 464baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzData *sd, 465baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t numItems, 466baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte **digestsDefined, 467baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 **digests, 468baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISzAlloc *alloc) 469baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 470baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t i; 471baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc)); 472baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_ALLOC(UInt32, *digests, numItems, alloc); 473baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numItems; i++) 474baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((*digestsDefined)[i]) 475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 476baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadUInt32(sd, (*digests) + i)); 477baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 478baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 479baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 480baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 481baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadPackInfo( 482baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzData *sd, 483baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 *dataOffset, 484baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 *numPackStreams, 485baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 **packSizes, 486baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte **packCRCsDefined, 487baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 **packCRCs, 488baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISzAlloc *alloc) 489baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 490baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 i; 491baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber(sd, dataOffset)); 492baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber32(sd, numPackStreams)); 493baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 494baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzWaitAttribute(sd, k7zIdSize)); 495baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 496baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc); 497baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 498baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < *numPackStreams; i++) 499baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 500baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber(sd, (*packSizes) + i)); 501baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 502baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 503baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 504baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 505baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 type; 506baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadID(sd, &type)); 507baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == k7zIdEnd) 508baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 509baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == k7zIdCRC) 510baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 511baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc)); 512baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 513baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 514baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzSkeepData(sd)); 515baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 516baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (*packCRCsDefined == 0) 517baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 518baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc); 519baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc); 520baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < *numPackStreams; i++) 521baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 522baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (*packCRCsDefined)[i] = 0; 523baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (*packCRCs)[i] = 0; 524baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 525baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 526baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 527baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 528baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 529baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadSwitch(CSzData *sd) 530baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 531baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte external; 532baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadByte(sd, &external)); 533baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED; 534baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 535baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 536baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc) 537baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 538baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numCoders, numBindPairs, numPackStreams, i; 539baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numInStreams = 0, numOutStreams = 0; 540baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 541baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber32(sd, &numCoders)); 542baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numCoders > NUM_FOLDER_CODERS_MAX) 543baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_UNSUPPORTED; 544baa3858d3f5d128a5c8466b700098109edcad5f2repo sync folder->NumCoders = numCoders; 545baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 546baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc); 547baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 548baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numCoders; i++) 549baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SzCoderInfo_Init(folder->Coders + i); 550baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 551baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numCoders; i++) 552baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 553baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte mainByte; 554baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzCoderInfo *coder = folder->Coders + i; 555baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 556baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unsigned idSize, j; 557baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte longID[15]; 558baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadByte(sd, &mainByte)); 559baa3858d3f5d128a5c8466b700098109edcad5f2repo sync idSize = (unsigned)(mainByte & 0xF); 560baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadBytes(sd, longID, idSize)); 561baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (idSize > sizeof(coder->MethodID)) 562baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_UNSUPPORTED; 563baa3858d3f5d128a5c8466b700098109edcad5f2repo sync coder->MethodID = 0; 564baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (j = 0; j < idSize; j++) 565baa3858d3f5d128a5c8466b700098109edcad5f2repo sync coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j); 566baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 567baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((mainByte & 0x10) != 0) 568baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 569baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber32(sd, &coder->NumInStreams)); 570baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber32(sd, &coder->NumOutStreams)); 571baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (coder->NumInStreams > NUM_CODER_STREAMS_MAX || 572baa3858d3f5d128a5c8466b700098109edcad5f2repo sync coder->NumOutStreams > NUM_CODER_STREAMS_MAX) 573baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_UNSUPPORTED; 574baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 575baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 576baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 577baa3858d3f5d128a5c8466b700098109edcad5f2repo sync coder->NumInStreams = 1; 578baa3858d3f5d128a5c8466b700098109edcad5f2repo sync coder->NumOutStreams = 1; 579baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 580baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((mainByte & 0x20) != 0) 581baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 582baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 propertiesSize = 0; 583baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber(sd, &propertiesSize)); 584baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc)) 585baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_MEM; 586baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadBytes(sd, coder->Props.data, (size_t)propertiesSize)); 587baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 588baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 589baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while ((mainByte & 0x80) != 0) 590baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 591baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadByte(sd, &mainByte)); 592baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzSkeepDataSize(sd, (mainByte & 0xF))); 593baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((mainByte & 0x10) != 0) 594baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 595baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 n; 596baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber32(sd, &n)); 597baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber32(sd, &n)); 598baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 599baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((mainByte & 0x20) != 0) 600baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 601baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 propertiesSize = 0; 602baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber(sd, &propertiesSize)); 603baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzSkeepDataSize(sd, propertiesSize)); 604baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 605baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 606baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numInStreams += coder->NumInStreams; 607baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numOutStreams += coder->NumOutStreams; 608baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 609baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 610baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numOutStreams == 0) 611baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_UNSUPPORTED; 612baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 613baa3858d3f5d128a5c8466b700098109edcad5f2repo sync folder->NumBindPairs = numBindPairs = numOutStreams - 1; 614baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_ALLOC(CSzBindPair, folder->BindPairs, (size_t)numBindPairs, alloc); 615baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 616baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numBindPairs; i++) 617baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 618baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzBindPair *bp = folder->BindPairs + i; 619baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber32(sd, &bp->InIndex)); 620baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber32(sd, &bp->OutIndex)); 621baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 622baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 623baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numInStreams < numBindPairs) 624baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_UNSUPPORTED; 625baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 626baa3858d3f5d128a5c8466b700098109edcad5f2repo sync folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs; 627baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackStreams, alloc); 628baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 629baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numPackStreams == 1) 630baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 631baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numInStreams ; i++) 632baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (SzFolder_FindBindPairForInStream(folder, i) < 0) 633baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 634baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (i == numInStreams) 635baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_UNSUPPORTED; 636baa3858d3f5d128a5c8466b700098109edcad5f2repo sync folder->PackStreams[0] = i; 637baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 638baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 639baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numPackStreams; i++) 640baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 641baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber32(sd, folder->PackStreams + i)); 642baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 643baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 644baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 645baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 646baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadUnpackInfo( 647baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzData *sd, 648baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 *numFolders, 649baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzFolder **folders, /* for alloc */ 650baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISzAlloc *alloc, 651baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISzAlloc *allocTemp) 652baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 653baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 i; 654baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzWaitAttribute(sd, k7zIdFolder)); 655baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber32(sd, numFolders)); 656baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 657baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadSwitch(sd)); 658baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 659baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc); 660baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 661baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < *numFolders; i++) 662baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SzFolder_Init((*folders) + i); 663baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 664baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < *numFolders; i++) 665baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 666baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc)); 667baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 668baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 669baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 670baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize)); 671baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 672baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < *numFolders; i++) 673baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 674baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 j; 675baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzFolder *folder = (*folders) + i; 676baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder); 677baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 678baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc); 679baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 680baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (j = 0; j < numOutStreams; j++) 681baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 682baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber(sd, folder->UnpackSizes + j)); 683baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 684baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 685baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 686baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 687baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 688baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 type; 689baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadID(sd, &type)); 690baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == k7zIdEnd) 691baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 692baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == k7zIdCRC) 693baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 694baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SRes res; 695baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte *crcsDefined = 0; 696baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 *crcs = 0; 697baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp); 698baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == SZ_OK) 699baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 700baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < *numFolders; i++) 701baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 702baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzFolder *folder = (*folders) + i; 703baa3858d3f5d128a5c8466b700098109edcad5f2repo sync folder->UnpackCRCDefined = crcsDefined[i]; 704baa3858d3f5d128a5c8466b700098109edcad5f2repo sync folder->UnpackCRC = crcs[i]; 705baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 706baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 707baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(allocTemp, crcs); 708baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(allocTemp, crcsDefined); 709baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(res); 710baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 711baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 712baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzSkeepData(sd)); 713baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 714baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 715baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 716baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadSubStreamsInfo( 717baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzData *sd, 718baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numFolders, 719baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzFolder *folders, 720baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 *numUnpackStreams, 721baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 **unpackSizes, 722baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte **digestsDefined, 723baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 **digests, 724baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISzAlloc *allocTemp) 725baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 726baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 type = 0; 727baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 i; 728baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 si = 0; 729baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numDigests = 0; 730baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 731baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numFolders; i++) 732baa3858d3f5d128a5c8466b700098109edcad5f2repo sync folders[i].NumUnpackStreams = 1; 733baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *numUnpackStreams = numFolders; 734baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 735baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 736baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 737baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadID(sd, &type)); 738baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == k7zIdNumUnpackStream) 739baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 740baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *numUnpackStreams = 0; 741baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numFolders; i++) 742baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 743baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numStreams; 744baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber32(sd, &numStreams)); 745baa3858d3f5d128a5c8466b700098109edcad5f2repo sync folders[i].NumUnpackStreams = numStreams; 746baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *numUnpackStreams += numStreams; 747baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 748baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 749baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 750baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == k7zIdCRC || type == k7zIdSize) 751baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 752baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == k7zIdEnd) 753baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 754baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzSkeepData(sd)); 755baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 756baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 757baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (*numUnpackStreams == 0) 758baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 759baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *unpackSizes = 0; 760baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *digestsDefined = 0; 761baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *digests = 0; 762baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 763baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 764baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 765baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64)); 766baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOM(*unpackSizes); 767baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte)); 768baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOM(*digestsDefined); 769baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32)); 770baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOM(*digests); 771baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 772baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 773baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numFolders; i++) 774baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 775baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* 776baa3858d3f5d128a5c8466b700098109edcad5f2repo sync v3.13 incorrectly worked with empty folders 777baa3858d3f5d128a5c8466b700098109edcad5f2repo sync v4.07: we check that folder is empty 778baa3858d3f5d128a5c8466b700098109edcad5f2repo sync */ 779baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 sum = 0; 780baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 j; 781baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numSubstreams = folders[i].NumUnpackStreams; 782baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numSubstreams == 0) 783baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 784baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == k7zIdSize) 785baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (j = 1; j < numSubstreams; j++) 786baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 787baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 size; 788baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber(sd, &size)); 789baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (*unpackSizes)[si++] = size; 790baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sum += size; 791baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 792baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum; 793baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 794baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == k7zIdSize) 795baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 796baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadID(sd, &type)); 797baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 798baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 799baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < *numUnpackStreams; i++) 800baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 801baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (*digestsDefined)[i] = 0; 802baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (*digests)[i] = 0; 803baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 804baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 805baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 806baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numFolders; i++) 807baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 808baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numSubstreams = folders[i].NumUnpackStreams; 809baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numSubstreams != 1 || !folders[i].UnpackCRCDefined) 810baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numDigests += numSubstreams; 811baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 812baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 813baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 814baa3858d3f5d128a5c8466b700098109edcad5f2repo sync si = 0; 815baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 816baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 817baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == k7zIdCRC) 818baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 819baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int digestIndex = 0; 820baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte *digestsDefined2 = 0; 821baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 *digests2 = 0; 822baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp); 823baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == SZ_OK) 824baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 825baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numFolders; i++) 826baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 827baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzFolder *folder = folders + i; 828baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numSubstreams = folder->NumUnpackStreams; 829baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numSubstreams == 1 && folder->UnpackCRCDefined) 830baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 831baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (*digestsDefined)[si] = 1; 832baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (*digests)[si] = folder->UnpackCRC; 833baa3858d3f5d128a5c8466b700098109edcad5f2repo sync si++; 834baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 835baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 836baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 837baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 j; 838baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (j = 0; j < numSubstreams; j++, digestIndex++) 839baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 840baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (*digestsDefined)[si] = digestsDefined2[digestIndex]; 841baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (*digests)[si] = digests2[digestIndex]; 842baa3858d3f5d128a5c8466b700098109edcad5f2repo sync si++; 843baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 844baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 845baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 846baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 847baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(allocTemp, digestsDefined2); 848baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(allocTemp, digests2); 849baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(res); 850baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 851baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else if (type == k7zIdEnd) 852baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 853baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 854baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 855baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzSkeepData(sd)); 856baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 857baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadID(sd, &type)); 858baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 859baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 860baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 861baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 862baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadStreamsInfo( 863baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzData *sd, 864baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 *dataOffset, 865baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzAr *p, 866baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 *numUnpackStreams, 867baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 **unpackSizes, /* allocTemp */ 868baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte **digestsDefined, /* allocTemp */ 869baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 **digests, /* allocTemp */ 870baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISzAlloc *alloc, 871baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISzAlloc *allocTemp) 872baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 873baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 874baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 875baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 type; 876baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadID(sd, &type)); 877baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((UInt64)(int)type != type) 878baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_UNSUPPORTED; 879baa3858d3f5d128a5c8466b700098109edcad5f2repo sync switch((int)type) 880baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 881baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case k7zIdEnd: 882baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 883baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case k7zIdPackInfo: 884baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 885baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams, 886baa3858d3f5d128a5c8466b700098109edcad5f2repo sync &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc)); 887baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 888baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 889baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case k7zIdUnpackInfo: 890baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 891baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp)); 892baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 893baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 894baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case k7zIdSubStreamsInfo: 895baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 896baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders, 897baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp)); 898baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 899baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 900baa3858d3f5d128a5c8466b700098109edcad5f2repo sync default: 901baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_UNSUPPORTED; 902baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 903baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 904baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 905baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 906baa3858d3f5d128a5c8466b700098109edcad5f2repo syncsize_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest) 907baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 908baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t len = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex]; 909baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (dest != 0) 910baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 911baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t i; 912baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const Byte *src = p->FileNames.data + (p->FileNameOffsets[fileIndex] * 2); 913baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < len; i++) 914baa3858d3f5d128a5c8466b700098109edcad5f2repo sync dest[i] = GetUi16(src + i * 2); 915baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 916baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return len; 917baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 918baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 919baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadFileNames(const Byte *p, size_t size, UInt32 numFiles, size_t *sizes) 920baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 921baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 i; 922baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t pos = 0; 923baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numFiles; i++) 924baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 925baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sizes[i] = pos; 926baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 927baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 928baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (pos >= size) 929baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_ARCHIVE; 930baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p[pos * 2] == 0 && p[pos * 2 + 1] == 0) 931baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 932baa3858d3f5d128a5c8466b700098109edcad5f2repo sync pos++; 933baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 934baa3858d3f5d128a5c8466b700098109edcad5f2repo sync pos++; 935baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 936baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sizes[i] = pos; 937baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE; 938baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 939baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 940baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadHeader2( 941baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzArEx *p, /* allocMain */ 942baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzData *sd, 943baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 **unpackSizes, /* allocTemp */ 944baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte **digestsDefined, /* allocTemp */ 945baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 **digests, /* allocTemp */ 946baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte **emptyStreamVector, /* allocTemp */ 947baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte **emptyFileVector, /* allocTemp */ 948baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte **lwtVector, /* allocTemp */ 949baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISzAlloc *allocMain, 950baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISzAlloc *allocTemp) 951baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 952baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 type; 953baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numUnpackStreams = 0; 954baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numFiles = 0; 955baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzFileItem *files = 0; 956baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numEmptyStreams = 0; 957baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 i; 958baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 959baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadID(sd, &type)); 960baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 961baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == k7zIdArchiveProperties) 962baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 963baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadArchiveProperties(sd)); 964baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadID(sd, &type)); 965baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 966baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 967baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 968baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == k7zIdMainStreamsInfo) 969baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 970baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadStreamsInfo(sd, 971baa3858d3f5d128a5c8466b700098109edcad5f2repo sync &p->dataPos, 972baa3858d3f5d128a5c8466b700098109edcad5f2repo sync &p->db, 973baa3858d3f5d128a5c8466b700098109edcad5f2repo sync &numUnpackStreams, 974baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unpackSizes, 975baa3858d3f5d128a5c8466b700098109edcad5f2repo sync digestsDefined, 976baa3858d3f5d128a5c8466b700098109edcad5f2repo sync digests, allocMain, allocTemp)); 977baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->dataPos += p->startPosAfterHeader; 978baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadID(sd, &type)); 979baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 980baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 981baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == k7zIdEnd) 982baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 983baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type != k7zIdFilesInfo) 984baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_ARCHIVE; 985baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 986baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber32(sd, &numFiles)); 987baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->db.NumFiles = numFiles; 988baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 989baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain); 990baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 991baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->db.Files = files; 992baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numFiles; i++) 993baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SzFile_Init(files + i); 994baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 995baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 996baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 997baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 type; 998baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 size; 999baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadID(sd, &type)); 1000baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == k7zIdEnd) 1001baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1002baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadNumber(sd, &size)); 1003baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (size > sd->Size) 1004baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_ARCHIVE; 1005baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((UInt64)(int)type != type) 1006baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1007baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzSkeepDataSize(sd, size)); 1008baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1009baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 1010baa3858d3f5d128a5c8466b700098109edcad5f2repo sync switch((int)type) 1011baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1012baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case k7zIdName: 1013baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1014baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t namesSize; 1015baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadSwitch(sd)); 1016baa3858d3f5d128a5c8466b700098109edcad5f2repo sync namesSize = (size_t)size - 1; 1017baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((namesSize & 1) != 0) 1018baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_ARCHIVE; 1019baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!Buf_Create(&p->FileNames, namesSize, allocMain)) 1020baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_MEM; 1021baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain); 1022baa3858d3f5d128a5c8466b700098109edcad5f2repo sync memcpy(p->FileNames.data, sd->Data, namesSize); 1023baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadFileNames(sd->Data, namesSize >> 1, numFiles, p->FileNameOffsets)) 1024baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzSkeepDataSize(sd, namesSize)); 1025baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1026baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1027baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case k7zIdEmptyStream: 1028baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1029baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp)); 1030baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numEmptyStreams = 0; 1031baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numFiles; i++) 1032baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((*emptyStreamVector)[i]) 1033baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numEmptyStreams++; 1034baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1035baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1036baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case k7zIdEmptyFile: 1037baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1038baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp)); 1039baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1040baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1041baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case k7zIdWinAttributes: 1042baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1043baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); 1044baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadSwitch(sd)); 1045baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numFiles; i++) 1046baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1047baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzFileItem *f = &files[i]; 1048baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte defined = (*lwtVector)[i]; 1049baa3858d3f5d128a5c8466b700098109edcad5f2repo sync f->AttribDefined = defined; 1050baa3858d3f5d128a5c8466b700098109edcad5f2repo sync f->Attrib = 0; 1051baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (defined) 1052baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1053baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadUInt32(sd, &f->Attrib)); 1054baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1055baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1056baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(allocTemp, *lwtVector); 1057baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *lwtVector = NULL; 1058baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1059baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1060baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case k7zIdMTime: 1061baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1062baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); 1063baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadSwitch(sd)); 1064baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numFiles; i++) 1065baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1066baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzFileItem *f = &files[i]; 1067baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte defined = (*lwtVector)[i]; 1068baa3858d3f5d128a5c8466b700098109edcad5f2repo sync f->MTimeDefined = defined; 1069baa3858d3f5d128a5c8466b700098109edcad5f2repo sync f->MTime.Low = f->MTime.High = 0; 1070baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (defined) 1071baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1072baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadUInt32(sd, &f->MTime.Low)); 1073baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadUInt32(sd, &f->MTime.High)); 1074baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1075baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1076baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(allocTemp, *lwtVector); 1077baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *lwtVector = NULL; 1078baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1079baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1080baa3858d3f5d128a5c8466b700098109edcad5f2repo sync default: 1081baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1082baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzSkeepDataSize(sd, size)); 1083baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1084baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1085baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1086baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1087baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1088baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 emptyFileIndex = 0; 1089baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 sizeIndex = 0; 1090baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numFiles; i++) 1091baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1092baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzFileItem *file = files + i; 1093baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file->IsAnti = 0; 1094baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (*emptyStreamVector == 0) 1095baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file->HasStream = 1; 1096baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 1097baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1); 1098baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (file->HasStream) 1099baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file->IsDir = 0; 1101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file->Size = (*unpackSizes)[sizeIndex]; 1102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file->Crc = (*digests)[sizeIndex]; 1103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file->CrcDefined = (Byte)(*digestsDefined)[sizeIndex]; 1104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sizeIndex++; 1105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 1107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (*emptyFileVector == 0) 1109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file->IsDir = 1; 1110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 1111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1); 1112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync emptyFileIndex++; 1113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file->Size = 0; 1114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file->Crc = 0; 1115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file->CrcDefined = 0; 1116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SzArEx_Fill(p, allocMain); 1120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 1121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1122baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadHeader( 1123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzArEx *p, 1124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzData *sd, 1125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISzAlloc *allocMain, 1126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISzAlloc *allocTemp) 1127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 1128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 *unpackSizes = 0; 1129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte *digestsDefined = 0; 1130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 *digests = 0; 1131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte *emptyStreamVector = 0; 1132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte *emptyFileVector = 0; 1133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte *lwtVector = 0; 1134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SRes res = SzReadHeader2(p, sd, 1135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync &unpackSizes, &digestsDefined, &digests, 1136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync &emptyStreamVector, &emptyFileVector, &lwtVector, 1137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync allocMain, allocTemp); 1138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(allocTemp, unpackSizes); 1139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(allocTemp, digestsDefined); 1140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(allocTemp, digests); 1141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(allocTemp, emptyStreamVector); 1142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(allocTemp, emptyFileVector); 1143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(allocTemp, lwtVector); 1144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return res; 1145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 1146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1147baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadAndDecodePackedStreams2( 1148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ILookInStream *inStream, 1149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzData *sd, 1150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CBuf *outBuffer, 1151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 baseOffset, 1152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzAr *p, 1153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 **unpackSizes, 1154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte **digestsDefined, 1155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 **digests, 1156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISzAlloc *allocTemp) 1157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 1158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numUnpackStreams = 0; 1160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 dataStartPos; 1161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzFolder *folder; 1162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 unpackSize; 1163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SRes res; 1164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SzReadStreamsInfo(sd, &dataStartPos, p, 1166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync &numUnpackStreams, unpackSizes, digestsDefined, digests, 1167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync allocTemp, allocTemp)); 1168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync dataStartPos += baseOffset; 1170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p->NumFolders != 1) 1171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_ARCHIVE; 1172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync folder = p->Folders; 1174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unpackSize = SzFolder_GetUnpackSize(folder); 1175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(LookInStream_SeekTo(inStream, dataStartPos)); 1177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp)) 1179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_MEM; 1180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = SzFolder_Decode(folder, p->PackSizes, 1182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync inStream, dataStartPos, 1183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync outBuffer->data, (size_t)unpackSize, allocTemp); 1184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(res); 1185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (folder->UnpackCRCDefined) 1186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC) 1187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_CRC; 1188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 1189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 1190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1191baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadAndDecodePackedStreams( 1192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ILookInStream *inStream, 1193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzData *sd, 1194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CBuf *outBuffer, 1195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 baseOffset, 1196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISzAlloc *allocTemp) 1197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 1198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzAr p; 1199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 *unpackSizes = 0; 1200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte *digestsDefined = 0; 1201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 *digests = 0; 1202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SRes res; 1203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SzAr_Init(&p); 1204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset, 1205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync &p, &unpackSizes, &digestsDefined, &digests, 1206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync allocTemp); 1207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SzAr_Free(&p, allocTemp); 1208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(allocTemp, unpackSizes); 1209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(allocTemp, digestsDefined); 1210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(allocTemp, digests); 1211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return res; 1212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 1213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1214baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzArEx_Open2( 1215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzArEx *p, 1216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ILookInStream *inStream, 1217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISzAlloc *allocMain, 1218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISzAlloc *allocTemp) 1219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 1220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte header[k7zStartHeaderSize]; 1221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Int64 startArcPos; 1222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 nextHeaderOffset, nextHeaderSize; 1223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t nextHeaderSizeT; 1224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 nextHeaderCRC; 1225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CBuf buffer; 1226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SRes res; 1227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync startArcPos = 0; 1229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR)); 1230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); 1232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!TestSignatureCandidate(header)) 1234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_NO_ARCHIVE; 1235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (header[6] != k7zMajorVersion) 1236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_UNSUPPORTED; 1237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nextHeaderOffset = GetUi64(header + 12); 1239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nextHeaderSize = GetUi64(header + 20); 1240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nextHeaderCRC = GetUi32(header + 28); 1241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->startPosAfterHeader = startArcPos + k7zStartHeaderSize; 1243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (CrcCalc(header + 12, 20) != GetUi32(header + 8)) 1245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_CRC; 1246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nextHeaderSizeT = (size_t)nextHeaderSize; 1248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (nextHeaderSizeT != nextHeaderSize) 1249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_MEM; 1250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (nextHeaderSizeT == 0) 1251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 1252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize || 1253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize) 1254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_NO_ARCHIVE; 1255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Int64 pos = 0; 1258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END)); 1259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((UInt64)pos < startArcPos + nextHeaderOffset || 1260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset || 1261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) 1262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_INPUT_EOF; 1263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset)); 1266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp)) 1268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_MEM; 1269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT); 1271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == SZ_OK) 1272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = SZ_ERROR_ARCHIVE; 1274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC) 1275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzData sd; 1277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 type; 1278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sd.Data = buffer.data; 1279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sd.Size = buffer.size; 1280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = SzReadID(&sd, &type); 1281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == SZ_OK) 1282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == k7zIdEncodedHeader) 1284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CBuf outBuffer; 1286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Buf_Init(&outBuffer); 1287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp); 1288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res != SZ_OK) 1289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Buf_Free(&outBuffer, allocTemp); 1290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 1291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Buf_Free(&buffer, allocTemp); 1293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync buffer.data = outBuffer.data; 1294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync buffer.size = outBuffer.size; 1295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sd.Data = buffer.data; 1296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sd.Size = buffer.size; 1297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = SzReadID(&sd, &type); 1298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == SZ_OK) 1302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == k7zIdHeader) 1304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = SzReadHeader(p, &sd, allocMain, allocTemp); 1305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 1306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = SZ_ERROR_UNSUPPORTED; 1307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Buf_Free(&buffer, allocTemp); 1311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return res; 1312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 1313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1314baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp) 1315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 1316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); 1317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res != SZ_OK) 1318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SzArEx_Free(p, allocMain); 1319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return res; 1320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 1321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1322baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSRes SzArEx_Extract( 1323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CSzArEx *p, 1324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ILookInStream *inStream, 1325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 fileIndex, 1326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 *blockIndex, 1327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte **outBuffer, 1328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t *outBufferSize, 1329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t *offset, 1330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t *outSizeProcessed, 1331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISzAlloc *allocMain, 1332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISzAlloc *allocTemp) 1333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 1334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex]; 1335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SRes res = SZ_OK; 1336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *offset = 0; 1337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *outSizeProcessed = 0; 1338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (folderIndex == (UInt32)-1) 1339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(allocMain, *outBuffer); 1341baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *blockIndex = folderIndex; 1342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *outBuffer = 0; 1343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *outBufferSize = 0; 1344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_OK; 1345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (*outBuffer == 0 || *blockIndex != folderIndex) 1348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzFolder *folder = p->db.Folders + folderIndex; 1350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder); 1351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t unpackSize = (size_t)unpackSizeSpec; 1352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0); 1353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (unpackSize != unpackSizeSpec) 1355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_MEM; 1356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *blockIndex = folderIndex; 1357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IAlloc_Free(allocMain, *outBuffer); 1358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *outBuffer = 0; 1359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(LookInStream_SeekTo(inStream, startOffset)); 1361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == SZ_OK) 1363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *outBufferSize = unpackSize; 1365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (unpackSize != 0) 1366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize); 1368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (*outBuffer == 0) 1369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = SZ_ERROR_MEM; 1370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == SZ_OK) 1372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = SzFolder_Decode(folder, 1374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync p->db.PackSizes + p->FolderStartPackStreamIndex[folderIndex], 1375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync inStream, startOffset, 1376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *outBuffer, unpackSize, allocTemp); 1377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == SZ_OK) 1378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (folder->UnpackCRCDefined) 1380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC) 1382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = SZ_ERROR_CRC; 1383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == SZ_OK) 1389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 i; 1391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSzFileItem *fileItem = p->db.Files + fileIndex; 1392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *offset = 0; 1393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) 1394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *offset += (UInt32)p->db.Files[i].Size; 1395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *outSizeProcessed = (size_t)fileItem->Size; 1396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (*offset + *outSizeProcessed > *outBufferSize) 1397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SZ_ERROR_FAIL; 1398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (fileItem->CrcDefined && CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->Crc) 1399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = SZ_ERROR_CRC; 1400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return res; 1402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 1403