// ZipFile.h 
// 
#ifndef ZIPFILE_H 
#define ZIPFILE_H 
#include <string> 
#include <vector> 
#define ZIP_OK 0 
#define ZIP_ERR_OPEN 1 
#define ZIP_ERR_WRONG_FILE 2 
#define ZIP_ERR_WRONG_HEADER 3 
#define BYTE unsigned char 
#define ui32 unsigned int 
#define ui16 unsigned short 
struct FileHeader 
{ 
ui32 signature; 
ui16 version_made_by; 
ui16 version_needed; 
ui16 bitflags; 
ui16 comp_method; 
ui16 lastModFileTime; 
ui16 lastModFileDate; 
ui32 crc_32; 
ui32 comp_size; 
ui32 uncompr_size; 
ui16 fname_len; 
ui16 extra_field_len; 
ui16 fcomment_len; 
ui16 disk_num_start; 
ui16 internal_fattribute; 
ui32 external_fattribute; 
ui32 relative_offset; 
char* file_name; 
char* extra_field; 
char* file_comment; 
}; 
class CZipFile 
{ 
private: 
public: 
CZipFile(); 
CZipFile(std::string); 
virtual ~CZipFile(); 
void ResetContent(void); 
std::string GetFileName(void); 
void SetFileName(std::string); 
bool OpenFile(void); 
int GetFilesNumber(void); 
FileHeader * GetFileAttributes(int); 
private: 
void ReadCentralDirectory(BYTE * data,long len); 
int ReadFileHeader(BYTE * data, FileHeader * hdr); 
ui32 ReadValue(unsigned char * buf, int nbits); 
std::string m_FileName; 
std::vector<void*> m_FileAttributes; 
}; 
#endif /*ZIPFILE_H */ 
// 
// ZipFile.cpp : implementation file 
// 
#include <stdio.h> 
#include <assert.h> 
#include <string.h> 
#include "ZipFile.h" 
using namespace std; 
///////////////////////////////////////////////////////////////////////////// 
// CZipFile 
CZipFile::CZipFile() 
{ 
m_FileName=""; 
} 
CZipFile::CZipFile(string fn) 
{ 
m_FileName = fn; 
} 
CZipFile::~CZipFile() 
{ 
ResetContent(); 
} 
void CZipFile::ResetContent(void) 
{ 
for(int i=0;i<GetFilesNumber();i++) 
delete(GetFileAttributes(i)); 
m_FileAttributes.clear(); 
m_FileName=""; 
} 
string CZipFile::GetFileName(void) 
{ 
return m_FileName; 
} 
void CZipFile::SetFileName(string fn) 
{ 
m_FileName = fn; 
} 
int CZipFile::GetFilesNumber(void) 
{ 
return (m_FileAttributes.size()); 
} 
bool CZipFile::OpenFile(void) 
{ 
if(m_FileName=="") 
return ZIP_ERR_OPEN; 
//read all the file data 
FILE * fp; 
fp=fopen(m_FileName.c_str(),"rb"); 
if(fp==NULL) 
return ZIP_ERR_OPEN; 
fseek(fp,0,SEEK_END); 
long siz=ftell(fp); 
fseek(fp,0,SEEK_SET); 
BYTE *buf=new BYTE[siz]; 
ui32 n= fread((void*) buf,(unsigned int)siz,1,fp); 
fclose(fp); 
//local file header signature control to check the file correctiveness 
if(*((ui32*)buf)!=0x04034b50) 
return ZIP_ERR_WRONG_FILE; 
ReadCentralDirectory(buf,siz); 
return ZIP_OK; 
} 
void CZipFile::ReadCentralDirectory(BYTE * data,long len) 
{ 
/*read the central Directory Data Structure; 
data contains the zipped archive; 
return the number of files read*/ 
BYTE * tmp; 
//search the signature 
tmp=data; 
ui32 * tmp2; 
tmp2= (ui32 *)tmp; 
len-=4; 
while((*tmp2)!=0x02014b50 && len) 
{ 
tmp++; 
tmp2= (ui32 *)tmp; 
len--; 
} 
//retrieve the FileHeader for each file 
int siz; 
do 
{ 
FileHeader fhdr; 
siz = ReadFileHeader(tmp, &fhdr); 
if(siz) 
{ 
FileHeader *pfhdr = new(FileHeader); 
*pfhdr=fhdr; 
m_FileAttributes.push_back(pfhdr); 
} 
tmp+=siz; 
}while(siz!=0); 
} 
int CZipFile::ReadFileHeader(BYTE * data, FileHeader * hdr) 
{ 
/*Name: int CZipFile::ReadFileHeader(BYTE * data, CString* stData) 
/*It read the file header in the Central Directory Structure 
Return the number of bytes read; if the stream does not contain 
a valid local_file_header 0 is returned and the stream pointer (f) 
is not modified 
st is filled with all the data; 
*/ 
BYTE * origdata=data; 
// FileHeader hdr; 
//fill the values into the file_header structure 
hdr->signature = (ui32) ReadValue(data ,32); 
if(hdr->signature!=0x02014b50) 
return 0; //no further file 
hdr->version_made_by = (ui16) ReadValue(data+4 ,16); 
hdr->version_needed = (ui16) ReadValue(data+6 ,16); 
hdr->bitflags = (ui16) ReadValue(data+8 ,16); 
hdr->comp_method = (ui16) ReadValue(data+10,16); 
hdr->lastModFileTime = (ui16) ReadValue(data+12,16); 
hdr->lastModFileDate = (ui16) ReadValue(data+14,16); 
hdr->crc_32 = (ui32) ReadValue(data+16,32); 
hdr->comp_size = (ui32) ReadValue(data+20,32); 
hdr->uncompr_size = (ui32) ReadValue(data+24,32); 
hdr->fname_len = (ui16) ReadValue(data+28,16); 
hdr->extra_field_len = (ui16) ReadValue(data+30,16); 
hdr->fcomment_len = (ui16) ReadValue(data+32,16); 
hdr->disk_num_start = (ui16) ReadValue(data+34,16); 
hdr->internal_fattribute = (ui16) ReadValue(data+36,16); 
hdr->external_fattribute = (ui32) ReadValue(data+38,32); 
hdr->relative_offset = (ui32) ReadValue(data+42,32); 
data+=46; 
if(hdr->fname_len>0) 
{ 
char *fn; 
fn=new (char[hdr->fname_len+1]); 
strncpy(fn,(char*)data,hdr->fname_len); 
fn[hdr->fname_len]='\0'; 
hdr->file_name = fn; 
data+=hdr->fname_len; 
} 
if(hdr->extra_field_len>0) 
{ 
char *fn; 
fn=new (char[hdr->extra_field_len+1]); 
strncpy(fn,(char*)data,hdr->extra_field_len); 
fn[hdr->extra_field_len]='\0'; 
hdr->extra_field = fn; 
data += hdr->extra_field_len; 
} 
//file comment 
if(hdr->fcomment_len>0) 
{ 
char *fn; 
fn=new (char[hdr->fcomment_len+1]); 
strncpy(fn,(char*)data,hdr->fcomment_len); 
fn[hdr->fcomment_len]='\0'; 
hdr->file_comment = fn; 
data += hdr->extra_field_len; 
} 
return (data-origdata); 
} 
ui32 CZipFile::ReadValue(unsigned char * buf, int nbits) 
{ 
/*Name: void ReadValue(char*buf, int nbits) 
/*Return the value read from the buffer of size nbits; 
*/ 
ui32 value = 0; 
switch (nbits) 
{ 
case (8): 
value = (ui32)*(buf); 
break; 
case(16): 
value = (((ui32)*(buf+1))<<8)+(ui32)*(buf); 
break; 
case(24): 
value = (((ui32)*(buf+2))<<16)+(((ui32)*(buf+1))<<8)+((ui32)*(buf)); 
break; 
case(32): 
value = (((ui32)*(buf+3))<<24)+(((ui32)*(buf+2))<<16)+(((ui32)*(buf+1))<<8)+((ui32)*(buf)); 
break; 
default: 
assert(1); 
break; 
} 
return(value); 
} 
FileHeader *CZipFile::GetFileAttributes(int index) 
{ 
if(index<0 || index >m_FileAttributes.size()) 
return NULL; 
else 
return((FileHeader *)m_FileAttributes.at(index)); 
} 
//main.cpp 
#include <stdio.h> 
#include "ZipFile.h" 
int main(int argc , char* argv[]) 
{ 
if(2 != argc) 
{ 
printf("zipFile must provide.\n"); 
return 0; 
} 
CZipFile zipTest; 
zipTest.SetFileName(argv[1]); 
zipTest.OpenFile(); 
for(int i = 0;i< zipTest.GetFilesNumber();i++) 
{ 
printf("%s\n", zipTest.GetFileAttributes(i)->file_name); 
} 
return 0; 
}