[gelöst]Binary File wird nicht geöffnet :'(



  • Ich hatte ja geschrieben, dass SwapBytes aufgerufen werden kann, um die Variablen mit den Werten im Hexeditor einfacher zu vergleichen. Die Werte sind _ohne_ den Aufruf natürlich richtig.
    Und ja, zum falschen Einlsen:

    struct zipRecord{               //Structure of file records
        char frSignature[4]; // 4 Bytes
        unsigned short frVersion; // 6
        unsigned short frFlags; // 8
        unsigned short frCompression; // 10
        unsigned short frFileTime; // 12
        unsigned short frFileDate; // 14  -> 14%4!=0-> der Compiler schiebt hier 2 Bytes ein
        unsigned int frCRC;
        unsigned int frCompressedSize;
        unsigned int frUncompressedSize;
        unsigned short frFileNameLength;
        unsigned short frExtraFieldLength;
    };
    

    In den Standardeinstellungen kann man das "Padding" einstellen, standardmäßig ist es bei mir 8, kann aber auch 4 sein.
    Warum die Entwickler des Formats das so gemacht haben, keine Ahnung.
    Mit #pragma pack(push,2) kann dieses Padding beim MSVC auf 2 gesetzt werden. Unter der Struktur sollte dann #pragma pack(pop) stehen, um den alten Wert wieder herzustellen.

    Edit: Du kannst auch

    void SwapBytes(unsigned int* pi);
    // in
    unsigned int SwapBytes(unsigned int i);
    

    ändern, damit es sich nicht auf die Werte auswirkt.



  • So, ich habe jetzt das Programm fertiggestellt und wirklich einiges gelernt 🙂 Vielen Dank, hier ist mein Sourcecode:

    main.cpp

    #include <iostream>
    #include <fstream>
    #include "funcs.h"
    
    using namespace std;
    
    unsigned short frFileNameLength;
    unsigned int frCompressedSize;
    unsigned int frChecksum;
    int main()
    {
        ifstream oZip("C:\\Sample.zip",ios::binary);
    
        bool isValidZip = isZIP(oZip);
    
        if(isValidZip)
        {
            unsigned short numEntries = numberOfEntries(oZip);
            cout << "Gueltiges ZIP Format!" << endl;
            cout << "Zahl der Dateien: " << numEntries << endl;
            for(int i=0;i<numEntries;i++)
            {
                oZip.seekg(OFFSET_CRC, ios::cur);                                                       //Zur Checksumme springen
                oZip.read(reinterpret_cast<char*>(&frChecksum),sizeof(int));                            //Wert auslesen
    
                oZip.read(reinterpret_cast<char*>(&frCompressedSize),sizeof(int));
    
                oZip.seekg(4, ios::cur);
                oZip.read(reinterpret_cast<char*>(&frFileNameLength), sizeof(short));                   //Größe des Dateinamens ermitteln
    
                char *frFileName = new char[(frFileNameLength+1)];                                      //Speicher für den Dateinamen reservieren
    
                oZip.seekg(2, ios::cur);
                oZip.read(&(*frFileName),frFileNameLength);                                             //Dateinamen einlesen
    
                frFileName[11] = '\0';                                                                  //Null-Terminator an Dateinamen anhängen
    
                printf("Datei %d: %s (CRC Checksumme: %X)\n",(i+1),frFileName,frChecksum);                   //Daten ausgeben
                delete[] frFileName;                                                                    //Speicher für Dateinamen löschen
    
                oZip.seekg(frCompressedSize,ios::cur);                                                  //Den Data Block überspringen und nochmal anfangen
            }
        }
        else
        {
            cout << "Ungueltige Datei!" << endl;
            return 0;
        }
    }
    

    funcs.h

    #ifndef FUNCS_H_INCLUDED
    #define FUNCS_H_INCLUDED
    
    #include <fstream>
    #include <iostream>
    
    #define OFFSET_SIGNATURE 0
    #define OFFSET_VERSION 4
    #define OFFSET_FLAGS 6
    #define OFFSET_COMPRESSION 8
    #define OFFSET_FILE_TIME 10
    #define OFFSET_FILE_DATE 12
    #define OFFSET_CRC 14
    #define OFFSET_COMPRESSED_SIZE 18
    #define OFFSET_UNCOMPRESSED_SIZE 22
    #define OFFSET_FILE_NAME_LENGTH 26
    #define OFFSET_EXTRA_FIELD_LENGTH 28
    #define OFFSET_FILE_NAME 30
    
    using namespace std;
    
    typedef unsigned char BYTE;
    
    enum COMPTYPE{                          //Compression type
        COMP_STORED,
        COMP_SHRUNK,
        COMP_REDUCED1,
        COMP_REDUCED2,
        COMP_REDUCED3,
        COMP_REDUCED4,
        COMP_IMPLODED,
        COMP_TOKEN,
        COMP_DEFLATE,
        COMP_DEFLATE64
    };
    void SwapBytes(unsigned int* pi)
    {
        unsigned int i = *pi;
        unsigned int ui;
        ui = (i) & 0xFF;
        ui<<=8;
        ui|= (i>>8) & 0xFF;
        ui<<=8;
        ui|= (i>>16) & 0xFF;
        ui<<=8;
        ui|= (i>>24) & 0xFF;
        *pi = ui;
    }
    
    void SwapBytes(unsigned short* ps)
    {
        unsigned short s = *ps;
        unsigned short us;
        us = (s) & 0xFF;
        us<<=8;
        us|= (s>>8) & 0xFF;
        *ps = us;
    }
    
    unsigned short GetWord(ifstream& in)
    {
        char c;
        unsigned short s;
        in.get(c);
        s=(BYTE)c;
        s<<=8;
        in.get(c);
        s|=(BYTE)c;
        return s;
    }
    unsigned short GetByte(ifstream& in)
    {
        char c;
        unsigned short s;
        in.get(c);
        s=(BYTE)c;
        return s;
    }
    bool isZIP(ifstream& in)
    {
        bool bFound = false;
        streampos startPos = in.tellg();
        in.seekg(0,ios::beg);
        while(!in.eof() && !bFound)
        {
            char c;
            in.get(c);
            if((BYTE)c!=0x50)
                continue;
            in.get(c);
            if((BYTE)c!=0x4B)
                continue;
            else
            {
                bFound = true;
                in.seekg(startPos);
            }
        }
        return bFound;
    }
    unsigned short numberOfEntries(ifstream& in)
    {
        unsigned short num;
        streampos startPos = in.tellg();
        in.seekg(-12,ios::end);
        in.read(reinterpret_cast<char*>(&num),sizeof(short));
        in.seekg(startPos,ios::beg);
        return num;
    }
    #endif // FUNCS_H_INCLUDED
    

Anmelden zum Antworten