Search code examples
c#zipcompression.net-5c#-ziparchive

C# open SFX Zip file


I have the following code:

 using (var zip = new ZipArchive(passStream))
        {
            Pass = Json.Deserialize<Pass>(Encoding.UTF8.GetString(Json.ReadFully(zip.GetEntry("pass.json").Open())));

on the zip.GetEntry line I am getting the error:

InvalidDataException: Number of entries expected in End Of Central Directory does not correspond to number of entries in Central Directory.

I am fairly certain this is because the zip file being processed is a SFX Zip file (I opened in WinRar and that was the format it stated.) Files that are standard Zip files open and process just fine. Also - if I double click on the SFX format zip file directly in windows, I get an error state 'The compressed folder XXXXXXXXXXX is invalid'. If I double click on the standard zip files, they open fine.

Is there a built-in way to process SFX Zip files in C#. I have explored the System.IO.Compression name space and did not see anything there.

If there is nothing in .net / C# is there a nuget package that can accomplish this. I have looked at many of them and have not found any that specifically state they handle SFX Zip files. Any assistance would be greatly appreciated.

##UPDATED## Based on the info @Shingo provided, I did the following:

        var bs = new BufferedStream(fs);
        int b;

        bs.Position = 0;

        while ((b = bs.ReadByte()) != -1)
        {
            if (b == 0x50)
            {
                var p = bs.Position;
                if (bs.ReadByte() == 0x4b &&
                   bs.ReadByte() == 0x03 &&
                   bs.ReadByte() == 0x04)
                {

                    //Copy from the current location (Positiong 6) to the new stream. This will remove the first 6 positions (index 0 -5) 
                    var tobj_NewStream = new MemoryStream();
                    bs.CopyTo(tobj_NewStream);
                    bs.Close();

                    using (var zip = new ZipArchive(tobj_NewStream))
                    {
                        var ti_Entries = zip.Entries.Count();
                    }
                    break;
                }
                else
                {
                    bs.Position = p + 1;
                }
            }
        }

The first several entries in the array after the SFX characters are 20,0,8,8,8,0. After the new stream was created, I verified that is started with the series in index 0 - 5 and it did. However, when I loaded the stream into the ZipArchive, I still could not see / access the entries in it. I received the same error message I have been receiving:

System.IO.InvalidDataException HResult=0x80131501 Message=Number of entries expected in End Of Central Directory does not correspond to number of entries in Central Directory. Source=System.IO.Compression

Any other suggestions??


Solution

  • Here's a simple example you may have a try.

    var bs = new BufferedStream(filestream);
    int b;
    
    while((b = bs.ReadByte()) != -1)
    {
        if(b == 0x50)
        {
            var p = bs.Position;
            if(bs.ReadByte() == 0x4b &&
               bs.ReadByte() == 0x03 &&
               bs.ReadByte() == 0x04)
            {
                var ms = new MemoryStream();
                filestream.Position = p - 1;
                filestream.CopyTo(ms);
    
                using (var zip = new ZipArchive(ms))
                {
                    //...
                }
                break;
            }
            else
            {
                bs.Position = p;
            }
        }
    }