Created
May 30, 2015 17:14
-
-
Save phr34k/a20ba6dfacd5d058a0bb to your computer and use it in GitHub Desktop.
zip archive reader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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