SRC: Список файлов в CAB-архиве
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 02.09.02 14:01
Оценка: 8 (2)
Собственно, сабж...


#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);
}
//---------------------------------------------------------------------------
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.