Beispiel #1
0
 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 );
 }
Beispiel #2
0
        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 <<<");
        }
Beispiel #3
0
 public void szArchiveOpen(
     FileStream inStream,
     out ArchiveDatabaseEx db)
 {
     szArchiveOpen2(inStream, out db );
 }
Beispiel #4
0
        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;
            }
        }
Beispiel #5
0
        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;
            //}
        }
Beispiel #6
0
        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;
        }