Skip to content

Instantly share code, notes, and snippets.

@phr34k
Created May 30, 2015 17:14
Show Gist options
  • Save phr34k/a20ba6dfacd5d058a0bb to your computer and use it in GitHub Desktop.
Save phr34k/a20ba6dfacd5d058a0bb to your computer and use it in GitHub Desktop.
zip archive reader
#include <windows.h>
#include <stdio.h>
#include <string>
#include <map>
#pragma pack(1)
struct package_file
{
unsigned int signature;
unsigned short version;
unsigned short flags;
unsigned short compression;
unsigned short lastmodified_time;
unsigned short lastmodified_date;
unsigned int crc32;
unsigned int compressed_size;
unsigned int uncompressed_size;
unsigned short filename_length;
unsigned short extra_length;
};
#pragma pack(1)
struct package_cd_file
{
unsigned int signature;
unsigned short versionCreated;
unsigned short version;
unsigned short flags;
unsigned short compression;
unsigned short lastmodified_time;
unsigned short lastmodified_date;
unsigned int crc32;
unsigned int compressed_size;
unsigned int uncompressed_size;
unsigned short filename_length;
unsigned short extra_length;
unsigned short filecomment_length;
unsigned short disk;
unsigned short internal_attributes;
unsigned int external_attributes;
unsigned int offset;
};
#pragma pack(1)
struct package_cd_end
{
unsigned int signature;
unsigned short disk_end;
unsigned short disk_start;
unsigned short number_disk;
unsigned short number_total;
unsigned int size;
unsigned int offset;
unsigned short comment_length;
};
struct packaged_entry
{
unsigned int signature;
unsigned short versionCreated;
unsigned short version;
unsigned short flags;
unsigned short compression;
unsigned short lastmodified_time;
unsigned short lastmodified_date;
unsigned int crc32;
unsigned int compressed_size;
unsigned int uncompressed_size;
unsigned short filename_length;
unsigned short extra_length;
unsigned short filecomment_length;
unsigned short disk;
unsigned short internal_attributes;
unsigned int external_attributes;
unsigned int offset;
public:
packaged_entry()
{
}
packaged_entry(const package_cd_file& cd)
{
signature=cd.signature;
versionCreated=cd.versionCreated;
version=cd.version;
flags=cd.flags;
compression=cd.compression;
lastmodified_time=cd.lastmodified_time;
lastmodified_date=cd.lastmodified_date;
crc32=cd.crc32;
compressed_size=cd.compressed_size;
uncompressed_size=cd.uncompressed_size;
filename_length=cd.filename_length;
extra_length=cd.extra_length;
filecomment_length=cd.filecomment_length;
disk=cd.disk;
internal_attributes=cd.internal_attributes;
external_attributes=cd.external_attributes;
offset=cd.offset;
}
packaged_entry& operator=(const packaged_entry& cd)
{
signature=cd.signature;
versionCreated=cd.versionCreated;
version=cd.version;
flags=cd.flags;
compression=cd.compression;
lastmodified_time=cd.lastmodified_time;
lastmodified_date=cd.lastmodified_date;
crc32=cd.crc32;
compressed_size=cd.compressed_size;
uncompressed_size=cd.uncompressed_size;
filename_length=cd.filename_length;
extra_length=cd.extra_length;
filecomment_length=cd.filecomment_length;
disk=cd.disk;
internal_attributes=cd.internal_attributes;
external_attributes=cd.external_attributes;
offset=cd.offset;
return *this;
}
};
std::map<std::string, packaged_entry> m_filetable;
void main()
{
HANDLE hZipArchive;
DWORD hZipArchiveLength;
hZipArchive = CreateFileA("E:\\Workspaces\\dds.zip", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING,0, 0);
hZipArchiveLength = ::GetFileSize(hZipArchive, 0);
if( hZipArchiveLength < 4 ) {
__asm int 3;
} else {
DWORD buffer = 0;
DWORD bytesRead = 0;
for( int i = 4; i < hZipArchiveLength; i++ ) {
DWORD retval = ::SetFilePointer(hZipArchive, -i, 0, FILE_END);
if( retval == INVALID_SET_FILE_POINTER || retval != (hZipArchiveLength - i))
{
__asm int 3;
printf("test");
}
package_cd_end eocd;
::ReadFile(hZipArchive, &buffer, 4, &bytesRead, 0);
if( bytesRead == 4 && buffer == 0x06054b50 ) {
DWORD retval = ::SetFilePointer(hZipArchive, -i, 0, FILE_END);
::ReadFile(hZipArchive, &eocd, sizeof(eocd), &bytesRead, 0);
retval = ::SetFilePointer(hZipArchive, eocd.offset, 0, FILE_BEGIN);
if( retval == INVALID_SET_FILE_POINTER || retval != eocd.offset) {
__asm int 3;
}
while(retval < (hZipArchiveLength - i) )
{
package_cd_file cd;
::ReadFile(hZipArchive, &cd, sizeof(package_cd_file), &bytesRead, 0);
if( cd.signature != 0x02014b50 )
__asm int 3;
std::string filename; filename.resize(cd.filename_length);
::ReadFile(hZipArchive, const_cast<char*>(filename.c_str()), cd.filename_length, &bytesRead, 0);
retval = ::SetFilePointer(hZipArchive, cd.extra_length + cd.filecomment_length, 0, FILE_CURRENT);
m_filetable[filename] = packaged_entry(cd);
printf("%s\r\n", filename.c_str());
}
break;
}
}
getchar();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment