예제 #1
0
 public SevenZipFileInfo(IDirectoryInfo parentDir, string sevenZipPath, uint fileIndex, FileItem fileItem)
 {
     _parentDir = parentDir;
     _sevenZipPath = sevenZipPath;
     _fileIndex = fileIndex;
     _fileItem = fileItem;
     _fullPath = fileItem.Name.Replace("\0", "");
     _size = (long)fileItem.Size;
 }
예제 #2
0
        public static byte[] GetBytes(string sevenZipPath, FileItem fileItem)
        {
            lock (_readLock)
            {
                //Create temporary directory
                string tempDir = SysPath.Combine(Environment.CurrentDirectory, "Temp");
                if (!Directory.Exists(tempDir))
                    Directory.CreateDirectory(tempDir);

                //TODO Will create problems if file name from two different archive are the same
                //Return file if already extracted
                string tempFile = SysPath.Combine(tempDir, fileItem.Name.Replace("\0", ""));
                if (File.Exists(tempFile))
                    return File.ReadAllBytes(tempFile);

                //Extract file
                using (FileStream inStream = File.OpenRead(sevenZipPath))
                {
                    ArchiveDatabaseEx archivedatabaseex;
                    new SzIn().szArchiveOpen(inStream, out archivedatabaseex);

                    uint fileIndex = 0;
                    foreach (FileItem item in archivedatabaseex.Database.Files)
                    {
                        if (item.Name.Equals(fileItem.Name))
                            break;
                        fileIndex = fileIndex + 1;
                    }
                    if (fileIndex == archivedatabaseex.Database.Files.Length)
                        throw new Exception("File is not found within files list");

                    uint folderIndex = archivedatabaseex.FileIndexToFolderIndexMap[fileIndex];

                    Dictionary<string, byte[]> outDict = SzExtract.ExtractFolder(inStream, archivedatabaseex, folderIndex);
                    foreach (string fileName in outDict.Keys)
                    {
                        string outPath = SysPath.Combine(tempDir, fileName);
                        string dirPath = SysPath.GetDirectoryName(outPath);
                        if (!Directory.Exists(dirPath))
                            Directory.CreateDirectory(dirPath);
                        File.WriteAllBytes(outPath, outDict[fileName]);
                    }
                }
                return File.ReadAllBytes(tempFile);
            }
        }
예제 #3
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 <<<");
        }
예제 #4
0
        void szReadFileNames(SzData sd, uint numFiles, FileItem[] files)
        {
            //Console.WriteLine("szReadFileNames >>> numfiles: " + numFiles);
            uint i;
            for (i = 0; i < numFiles; i++)
            {
                uint len = 0;
                ulong pos = sd.Offset;
                FileItem file = files[i];
                while (pos + 2 <= sd.Length )
                {
                    int numAdds;
                    uint value = (uint)(sd.Data[ pos] | (((uint)sd.Data[ pos + 1]) << 8));
                    pos += 2;
                    len++;
                    if (value == 0)
                        break;
                    if (value < 0x80)
                        continue;
                    if (value >= 0xD800 && value < 0xE000)
                    {
                        uint c2;
                        if (value >= 0xDC00)
                        {
                            throw new Exception("Unexpected value in szReadFileNames: " + value);
                            //return SZE_ARCHIVE_ERROR;
                        }
                        if (pos + 2 > sd.Length )
                        {
                            throw new Exception("End of file error in szReadFileNames");
                            //return SZE_ARCHIVE_ERROR;
                        }
                        c2 = (uint)(sd.Data[pos ] | (((uint)sd.Data[pos + 1]) << 8));
                        pos += 2;
                        if (c2 < 0xDC00 || c2 >= 0xE000)
                        {
                            throw new Exception("Unexpected c2 value in szReadFileNames: " + c2);
                            //return SZE_ARCHIVE_ERROR;
                        }
                        value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
                    }
                    for (numAdds = 1; numAdds < 5; numAdds++)
                        if (value < (((uint)1) << (numAdds * 5 + 6)))
                            break;
                    len += (uint)numAdds;
                }

                char[] namechararray = new char[len];
                //RINOK(MySzInAlloc((void **)&file->Name, (size_t)len * sizeof(char), allocFunc));
                len = 0;
                while ( sd.Length - sd.Offset >= 2 )
                {
                    int numAdds;
                    uint value = (uint)(sd.Data[sd.Offset] | (((uint)sd.Data[sd.Offset + 1]) << 8));
                    szSkeepDataSize(sd, 2);
                    if (value < 0x80)
                    {
                        namechararray[len++] = (char)value;
                        if (value == 0)
                            break;
                        continue;
                    }
                    if (value >= 0xD800 && value < 0xE000)
                    {
                        uint c2 = (uint)(sd.Data[sd.Offset] | (((uint)sd.Data[sd.Offset + 1]) << 8));
                        szSkeepDataSize(sd, 2);
                        value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
                    }
                    for (numAdds = 1; numAdds < 5; numAdds++)
                        if (value < (((uint)1) << (numAdds * 5 + 6)))
                            break;
                    namechararray[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
                    do
                    {
                        numAdds--;
                        namechararray[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
                    }
                    while (numAdds > 0);

                    len += (uint)numAdds;
                }
                file.Name = new String( namechararray );
                //Console.WriteLine("Filename: " + file.Name);
            }
        }