[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