void SzReadHeader( SzData sd, ArchiveDatabaseEx db ) { ulong[] unPackSizes; bool[] digestsDefined; uint[]digests; bool[] emptyStreamVector; bool[] emptyFileVector; SzReadHeader2(sd, db, out unPackSizes, out digestsDefined, out digests, out emptyStreamVector, out emptyFileVector ); }
void SzReadHeader2(SzData sd, ArchiveDatabaseEx db, out ulong[] unPackSizes, out bool[] digestsDefined, out uint[] digests, out bool[] emptyStreamVector, out bool[] emptyFileVector) { // Console.WriteLine("SzReadHeader2 >>>"); EIdEnum type; uint numUnPackStreams = 0; uint numFiles = 0; FileItem[] files = null; uint numEmptyStreams = 0; unPackSizes = null; digestsDefined = null; digests = null; emptyStreamVector = null; emptyFileVector = null; type = szReadID(sd); //Console.WriteLine("SzReadHeader2, got type: " + type); if (type == EIdEnum.k7zIdArchiveProperties) { //SzReadArchiveProperties( sd ); throw new Exception("Need to write szReadArchiveProperties, please contact 7zip port developer"); //type = szReadID(sd); } if (type == EIdEnum.k7zIdMainStreamsInfo) { szReadStreamsInfo(sd, out db.ArchiveInfo.DataStartPosition, db.Database, out numUnPackStreams, out unPackSizes, out digestsDefined, out digests); db.ArchiveInfo.DataStartPosition += db.ArchiveInfo.StartPositionAfterHeader; type = szReadID(sd); } if (type == EIdEnum.k7zIdEnd) { return; } if (type != EIdEnum.k7zIdFilesInfo) { throw new Exception("Error, unexpected type: " + type); } numFiles = szReadNumber32(sd); //Console.WriteLine("SzReadHeader2 Number files: " + numFiles); db.Database.NumFiles = numFiles; files = new FileItem[numFiles]; //RINOK(MySzInAlloc((void **)&files, (size_t)numFiles * sizeof(CFileItem), allocMain->Alloc)); db.Database.Files = files; for (uint i = 0; i < numFiles; i++) { db.Database.Files[i] = new FileItem(); // SzFileInit(files + i); } while (true) { ulong size; type = szReadID(sd); // note to self: maybe need to read type as UInt64??? if (type == EIdEnum.k7zIdEnd) { break; } size = szReadNumber(sd); if ((UInt64)((int)type) != (UInt64)type) // note to self: maybe need to read type as UInt64??? { szSkeepDataSize(sd, size); } else { switch (type) { case EIdEnum.k7zIdName: { szReadSwitch(sd); szReadFileNames(sd, numFiles, files); //RINOK(SzReadFileNames(sd, numFiles, files, allocMain->Alloc)) break; } case EIdEnum.k7zIdEmptyStream: { emptyStreamVector = szReadBoolVector(sd, numFiles); //RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp->Alloc)); numEmptyStreams = 0; for (uint i = 0; i < numFiles; i++) if (emptyStreamVector[i]) numEmptyStreams++; break; } case EIdEnum.k7zIdEmptyFile: { emptyFileVector = szReadBoolVector(sd, numEmptyStreams); //RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp->Alloc)); break; } default: { szSkeepDataSize(sd, size); // RINOK(SzSkeepDataSize(sd, size)); break; } } } uint emptyFileIndex = 0; uint sizeIndex = 0; for (uint i = 0; i < numFiles; i++) { FileItem file = files[i]; file.IsAnti = false; if (emptyStreamVector == null) { file.HasStream = true; } else { file.HasStream = !emptyStreamVector[i]; //file.HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1); } if (file.HasStream) { file.IsDirectory = false; file.Size = unPackSizes[sizeIndex]; file.FileCRC = digests[sizeIndex]; file.IsFileCRCDefined = digestsDefined[sizeIndex]; sizeIndex++; } else { if (emptyFileVector == null) { file.IsDirectory = true; } else { file.IsDirectory = !emptyFileVector[emptyFileIndex]; //file.IsDirectory = (Byte)((*emptyFileVector)[emptyFileIndex] ? false : true); } emptyFileIndex++; file.Size = 0; file.IsFileCRCDefined = false; } } } db.Fill(); //foreach (FileItem file in files) //{ // Console.WriteLine(file); //} //Console.WriteLine("SzReadHeader <<<"); }
public void szArchiveOpen( FileStream inStream, out ArchiveDatabaseEx db) { szArchiveOpen2(inStream, out db ); }
void szArchiveOpen2(FileStream inStream, out ArchiveDatabaseEx db) { this.inStream = inStream; db = new ArchiveDatabaseEx(); byte[] signature = new byte[k7zSignatureSize]; inStream.Read(signature, 0, k7zSignatureSize); bytesread += k7zSignatureSize; CheckSignature(signature); byte MajorVersion = ReadByte(); CheckMajorVersion(MajorVersion); byte version = ReadByte(); UInt32 crc = ReadUInt32(); ulong nextHeaderOffset = Readulong(); ulong nextHeaderSize = Readulong(); UInt32 nextHeaderCRC = ReadUInt32(); //Console.WriteLine("bytesread: " + bytesread); //Console.WriteLine("k7zStartHeaderSize: " + k7zStartHeaderSize); //Console.WriteLine("headeroffset: " + nextHeaderOffset); //Console.WriteLine("nextHeaderSize: " + nextHeaderSize); /* note to self: to do CrcInit(&crc); RINOK(SafeReadDirectUInt64(inStream, &nextHeaderOffset)); CrcUpdateUInt64(&crc, nextHeaderOffset); RINOK(SafeReadDirectUInt64(inStream, &nextHeaderSize)); CrcUpdateUInt64(&crc, nextHeaderSize); RINOK(SafeReadDirectUInt32(inStream, &nextHeaderCRC)); CrcUpdateUInt32(&crc, nextHeaderCRC); */ uint pos = k7zStartHeaderSize; db.ArchiveInfo.StartPositionAfterHeader = pos; //if (CrcGetDigest(&crc) != crcFromArchive) //return SZE_ARCHIVE_ERROR; if (nextHeaderSize == 0) return; inStream.Seek((long)(pos + nextHeaderOffset), SeekOrigin.Begin); byte[] thisheader = new byte[nextHeaderSize]; inStream.Read(thisheader, 0, (int)nextHeaderSize); // note to self: to do // CrcVerifyDigest(nextHeaderCRC, buffer.Items, (UInt32)nextHeaderSize); SzData sd = new SzData(); sd.Data = thisheader; sd.Length = nextHeaderSize; while (true) { //ulong thisheaderoffset = 0; // Console.WriteLine((int)EIdEnum.k7zIdHeader); //Console.WriteLine((int)EIdEnum.k7zIdEnd); EIdEnum type = szReadID(sd); //Console.WriteLine("szArchiveOpen2, got type: " + type); if (type == EIdEnum.k7zIdHeader) { SzReadHeader(sd, db); break; } if (type != EIdEnum.k7zIdEncodedHeader) { throw new Exception("Error: invalid type number read: " + type); //break; } byte[] outBuffer; //CSzByteBuffer outBuffer; szReadAndDecodePackedStreams(inStream, sd, out outBuffer, db.ArchiveInfo.StartPositionAfterHeader); //res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, // db->ArchiveInfo.StartPositionAfterHeader, // allocTemp); thisheader = outBuffer; sd.Data = outBuffer; sd.Length = Convert.ToUInt64(outBuffer.GetLongLength(0) ); sd.Offset = 0; //Console.WriteLine(sd.Length); //buffer.Items = outBuffer.Items; //buffer.Capacity = outBuffer.Capacity; } }
public void Extract( FileStream inStream, ArchiveDatabaseEx db, uint fileIndex, out uint blockIndex, out byte[] outBuffer, out ulong outBufferSize, ref ulong offset, ref ulong outSizeProcessed) { //Console.WriteLine("Extract >>>"); uint folderIndex = db.FileIndexToFolderIndexMap[fileIndex]; offset = 0; outSizeProcessed = 0; outBuffer = null; if (folderIndex == UInt32.MaxValue) { //Console.WriteLine("folderindex is UInt32.MaxValue"); blockIndex = folderIndex; outBuffer = null; outBufferSize = 0; return; } Folder folder = db.Database.Folders[folderIndex]; ulong unPackSize = folder.GetUnPackSize(); //#ifndef _LZMA_IN_CB ulong packSize = db.GetFolderFullPackSize(folderIndex); //Console.WriteLine("packsize: " + packSize + " unpacksize: " + unPackSize ); //Byte *inBuffer = 0; //size_t processedSize; //#endif blockIndex = folderIndex; outBuffer = null; //Console.WriteLine("folderstreampos: " + db.GetFolderStreamPos(folderIndex, 0)); inStream.Seek((long)db.GetFolderStreamPos(folderIndex, 0), SeekOrigin.Begin); //RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0))); //#ifndef _LZMA_IN_CB //if (packSize != 0) //{ // inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize); // if (inBuffer == 0) // return SZE_OUTOFMEMORY; // } // res = inStream->Read(inStream, inBuffer, (size_t)packSize, &processedSize); // if (res == SZ_OK && processedSize != (size_t)packSize) // res = SZE_FAIL; //#endif outBufferSize = unPackSize; if (unPackSize != 0) { outBuffer = new byte[unPackSize]; //*outBuffer = (Byte *)allocMain->Alloc((size_t)unPackSize); //if (*outBuffer == 0) //res = SZE_OUTOFMEMORY; } ulong outRealSize; Compression.LZMA.Decoder decoder = new Compression.LZMA.Decoder(); decoder.SetDecoderProperties(folder.Coders[0].Properties); Stream outStream = new MemoryStream(outBuffer); decoder.Code(inStream, outStream, (long)packSize, (long)unPackSize, null); //SzDecode(db.Database.PackSizes + // db.FolderStartPackStreamIndex[folderIndex], folder, // //#ifdef _LZMA_IN_CB // inStream, // //#else // //inBuffer, // //#endif //outBuffer, unPackSize, out outRealSize); outStream.Close(); //Console.WriteLine( Encoding.UTF8.GetString( outBuffer, 0, (int)unPackSize ) ); outRealSize = unPackSize; if (outRealSize == unPackSize) { //if (folde.UnPackCRCDefined) //{ // if (!CrcVerifyDigest(folder->UnPackCRC, *outBuffer, (size_t)unPackSize)) // res = SZE_FAIL; //} } else { throw new Exception("Unpack size was different from packsize: " + unPackSize + " vs " + outRealSize); //res = SZE_FAIL; } UInt32 i; FileItem fileItem = db.Database.Files[fileIndex]; offset = 0; for (i = db.FolderStartFileIndex[folderIndex]; i < fileIndex; i++) { offset += (UInt32)db.Database.Files[i].Size; } outSizeProcessed = fileItem.Size; if (offset + outSizeProcessed > outBufferSize) { throw new Exception("offset + outsizeprocessed > outbuffersize " + offset + " + " + outSizeProcessed + " > " + outBufferSize); // return SZE_FAIL; } //if (fileItem->IsFileCRCDefined) //{ // if (!CrcVerifyDigest(fileItem->FileCRC, *outBuffer + *offset, *outSizeProcessed)) // res = SZE_FAIL; //} }
public static Dictionary<string, byte[]> ExtractFolder( FileStream inStream, ArchiveDatabaseEx db, uint folderIndex) { Dictionary<string, byte[]> fileDict = new Dictionary<string, byte[]>(); ulong packSize = db.GetFolderFullPackSize(folderIndex); Folder folder = db.Database.Folders[folderIndex]; ulong unPackSize = folder.GetUnPackSize(); //byte[] outBuffer; = new byte[unPackSize]; inStream.Seek((long)db.GetFolderStreamPos(folderIndex, 0), SeekOrigin.Begin); Compression.LZMA.Decoder decoder = new Compression.LZMA.Decoder(); decoder.SetDecoderProperties(folder.Coders[0].Properties); using (MemoryStream ms = new MemoryStream()) { decoder.Code(inStream, ms, (long)packSize, (long)unPackSize, null); //Extract file FileItem[] fileItemList = db.Database.Files; long offset = 0; for (uint i = db.FolderStartFileIndex[folderIndex]; i < fileItemList.Length; i++) { FileItem item = fileItemList[i]; if (item.IsDirectory) continue; byte[] tempBuf = new byte[item.Size]; if ((offset + (long)item.Size) > ms.Capacity) throw new Exception("offset + filesize > length " + offset + " + " + item.Size + " > " + ms.Capacity); ms.Seek(offset, SeekOrigin.Begin); ms.Read(tempBuf, 0, tempBuf.Length); string fileName = item.Name.Replace("\0", ""); fileDict.Add(fileName, tempBuf); offset += (long)fileItemList[i].Size; } } return fileDict; }