Собственно, сабж...
#include <stdio.h>
#include <stdlib.h>
//---------------------------------------------------------------------------
#pragma pack(push,1) // выравнивание по границе 1 байт
typedef struct
{
unsigned int sig; // file signature 'MSCF' (CAB_SIGNATURE)
unsigned int csumHeader; // header checksum (0 if not used)
unsigned int cbCabinet; // cabinet file size
unsigned int csumFolders; // folders checksum (0 if not used)
unsigned int coffFiles; // offset of first CAB_ENTRY
unsigned int csumFiles; // files checksum (0 if not used)
unsigned short version; // cabinet version (CAB_VERSION)
unsigned short cFolders; // number of folders
unsigned short cFiles; // number of files
unsigned short flags; // cabinet flags (CAB_FLAG_*)
unsigned short setID; // cabinet set id
unsigned short iCabinet; // zero-based cabinet number
}TCabHeader;
#pragma pack(pop) // отмена выравнивания
//---------------------------------------------------------------------------
#define CAB_HEADER_SIZE 36 // size of TCabHeader
//---------------------------------------------------------------------------
#pragma pack(push,1) // выравнивание по границе 1 байт
typedef struct
{
unsigned int cbFile; // uncompressed file size
unsigned int uoffFolderStart; // file offset after decompression
unsigned short iFolder; // file control id (CAB_FILE_*)
unsigned short date; // file date stamp, as used by DOS
unsigned short time; // file time stamp, as used by DOS
unsigned short attribs; // file attributes (CAB_ATTRIB_*)
char* fName; // file name
}TCabFile;
#pragma pack(pop) // отмена выравнивания
//---------------------------------------------------------------------------
#define CAB_FILE_SIZE 17 // size of TCabFile
//---------------------------------------------------------------------------
// прототип функции, которая будет вызываться для каждого файла в архиве
typedef void (*FLAMER_CAB_FUNC)(const char* FileName, int UnCompressedSize);
//---------------------------------------------------------------------------
bool GetFilesInCAB(const char* FileName,FLAMER_CAB_FUNC pFunc=NULL);
//---------------------------------------------------------------------------
bool GetFilesInCAB(const char* FileName,FLAMER_CAB_FUNC pFunc)
{
TCabHeader FCabHeader = {0};
TCabFile FCabFile = {0};
FCabFile.fName = NULL;
FILE* hFile = fopen(FileName, "rb");
if(!hFile) return false;
// read header
if(fread(&FCabHeader,1,CAB_HEADER_SIZE,hFile)!=CAB_HEADER_SIZE) {
fclose(hFile); return false;
}
if(FCabHeader.sig!=0x4643534D) { // check header
fclose(hFile); return false;
}
if(fseek(hFile,FCabHeader.coffFiles,SEEK_SET)!=0) {
fclose(hFile); return false;
}
int j;
char ch;
for(int i=0;i< FCabHeader.cFiles;i++) {
if(FCabFile.fName) delete [] FCabFile.fName;
memset(&FCabFile,0,CAB_FILE_SIZE);
FCabFile.fName = NULL;
j=0;
ch = 1;
if(fread(&FCabFile,1,(CAB_FILE_SIZE-1),hFile)!=(CAB_FILE_SIZE-1)) {
fclose(hFile); return false;
}
while(ch !='\0') {
j++;
fread(&ch,1,1,hFile);
if(!FCabFile.fName) {
FCabFile.fName = new char[j+1];
FCabFile.fName[1]='\0';
FCabFile.fName[0]=ch;
} else {
char* cNew = new char[j+1];
strcpy(cNew,FCabFile.fName);
cNew[j-1]=ch;
cNew[j]='\0';
delete [] FCabFile.fName;
FCabFile.fName = cNew;
}
} //while
if(pFunc) pFunc(FCabFile.fName,FCabFile.cbFile);
}//for
fclose(hFile);
if(FCabFile.fName) delete [] FCabFile.fName;
return true;
}
//---------------------------------------------------------------------------
Пример использования:
//---------------------------------------------------------------------------
void CabProgressFunc(const char* FileName, int UnCompressedSize)
{
printf("%s\t%i\n",FileName,UnCompressedSize);
}
//---------------------------------------------------------------------------
int main(int argc, char **argv)
{
GetFilesInCAB("C:\\test.cab",CabProgressFunc);
}
//---------------------------------------------------------------------------