Microsoft公司 .CAB文件格式
_Inside Windows Cabinet Files_Listing One// =================================================================// CAB FILE LAYOUT// =================================================================/*(1) CAB_HEADER structure(2) Reserved area, if CAB_HEADER.flags & CAB_FLAG_RESERVE(3) Previous cabinet name, if CAB_HEADER.flags & CAB_FLAG_HASPREV(4) Previous disk name, if CAB_HEADER.flags & CAB_FLAG_HASPREV(5) Next cabinet name, if CAB_HEADER.flags & CAB_FLAG_HASNEXT(6) Next disk name, if CAB_HEADER.flags & CAB_FLAG_HASNEXT(7) CAB_FOLDER structures (n = CAB_HEADER.cFolders)(8) CAB_ENTRY structures / file names (n = CAB_HEADER.cFiles)(9) File data (offset = CAB_FOLDER.coffCabStart)*/
// =================================================================// MACROS// =================================================================#define SWAPWORD(x) ((WORD) (((x) << 8) | ((x) >> 8)))#define SWAPDWORD(x) ((SWAPWORD ((WORD) (x)) << 16) | / (SWAPWORD ((WORD) ((x) >> 16))))
// =================================================================// CONSTANTS// =================================================================#define CAB_SIGNATURE SWAPDWORD ('MSCF')#define CAB_VERSION 0x0103
#define CAB_FLAG_HASPREV 0x0001#define CAB_FLAG_HASNEXT 0x0002#define CAB_FLAG_RESERVE 0x0004
#define CAB_ATTRIB_READONLY 0x0001#define CAB_ATTRIB_HIDDEN 0x0002#define CAB_ATTRIB_SYSTEM 0x0004#define CAB_ATTRIB_VOLUME 0x0008#define CAB_ATTRIB_DIRECTORY 0x0010#define CAB_ATTRIB_ARCHIVE 0x0020
#define CAB_FILE_FIRST 0x0000#define CAB_FILE_NEXT 0x0001#define CAB_FILE_SPLIT 0xFFFE#define CAB_FILE_CONTINUED 0xFFFD
#define CAB_NOTIFY_OK 1#define CAB_NOTIFY_ERROR 0#define CAB_NOTIFY_SKIP 0#define CAB_NOTIFY_ABORT (-1)
// =================================================================// CABINET STRUCTURES// =================================================================typedef struct _CAB_HEADER { DWORD sig; // file signature 'MSCF' (CAB_SIGNATURE) DWORD csumHeader; // header checksum (0 if not used) DWORD cbCabinet; // cabinet file size DWORD csumFolders; // folders checksum (0 if not used) DWORD coffFiles; // offset of first CAB_ENTRY DWORD csumFiles; // files checksum (0 if not used) WORD version; // cabinet version (CAB_VERSION) WORD cFolders; // number of folders WORD cFiles; // number of files WORD flags; // cabinet flags (CAB_FLAG_*) WORD setID; // cabinet set id WORD iCabinet; // zero-based cabinet number } CAB_HEADER, *PCAB_HEADER;#define CAB_HEADER_ sizeof (CAB_HEADER)
// -----------------------------------------------------------------typedef struct _CAB_FOLDER { DWORD coffCabStart; // offset of folder data WORD cCFData; // ??? WORD typeCompress; // compression type (tcomp* in FDI.h)
} CAB_FOLDER, *PCAB_FOLDER;#define CAB_FOLDER_ sizeof (CAB_FOLDER)
// -----------------------------------------------------------------typedef struct _CAB_ENTRY { DWORD cbFile; // uncompressed file size DWORD uoffFolderStart; // file offset after decompression WORD iFolder; // file control id (CAB_FILE_*) WORD date; // file date stamp, as used by DOS WORD time; // file time stamp, as used by DOS WORD attribs; // file attributes (CAB_ATTRIB_*) } CAB_ENTRY, *PCAB_ENTRY;#define CAB_ENTRY_ sizeof (CAB_ENTRY)
Listing Two// =================================================================// FILE EXTRACTION CALLBACK// =================================================================int DIAMONDAPI FDIExtract (FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin) { FILETIME ft, lft; BYTE abFile [MAX_PATH]; int hf, iResult;
switch (fdint) { case fdintCOPY_FILE: if (lstrcmpi (pfdin->psz1, ((PEXTRACT_FILE) pfdin->pv)->pbEntry)) { iResult = CAB_NOTIFY_SKIP; } else { hf = FDIOpen (((PEXTRACT_FILE) pfdin->pv)->pbFile, _O_RDWR | _O_CREAT | _O_TRUNC, _S_IREAD | _S_IWRITE); if (hf != -1) { iResult = hf; } else { printfMessage (((PEXTRACT_FILE) pfdin->pv)->hWnd, MB_ICONERROR | MB_OK, "CabLib Error", "Unable to create file /"%s/"", ((PEXTRACT_FILE) pfdin->pv)->pbFile); iResult = CAB_NOTIFY_ABORT;
} } break; case fdintNEXT_CABINET: if (lstrlen (pfdin->psz3) + lstrlen (pfdin->psz1) < MAX_PATH) { lstrcpy (abFile, pfdin->psz3); lstrcat (abFile, pfdin->psz1); hf = FDIOpen (abFile, _O_RDONLY, 0); } else { hf = -1; } if (hf != -1) { FDIClose (hf); iResult = CAB_NOTIFY_OK; } else { printfMessage (((PEXTRACT_FILE) pfdin->pv)->hWnd, MB_ICONERROR | MB_OK, "CabLib Error", "Unable to open file /"%s%s/"", pfdin->psz3, pfdin->psz1); iResult = CAB_NOTIFY_ABORT; } break; case fdintCLOSE_FILE_INFO: DosDateTimeToFileTime (pfdin->date, pfdin->time, &lft); LocalFileTimeToFileTime (&lft, &ft); SetFileTime ((HANDLE) pfdin->hf, &ft, &ft, &ft);
if (FDIClose (pfdin->hf) == -1) { printfMessage (((PEXTRACT_FILE) pfdin->pv)->hWnd, MB_ICONERROR | MB_OK, "CabLib Error", "Unable to close file /"%s/"", ((PEXTRACT_FILE) pfdin->pv)->pbFile); } iResult = CAB_NOTIFY_OK; break; default: iResult = CAB_NOTIFY_OK; break; } return iResult; }
Example 1: HFDI FAR DIAMONDAPI FDICreate (PFNALLOC pfnalloc, PFNFREE pfnfree, PFNOPEN pfnopen, PFNREAD pfnread, PFNWRITE pfnwrite, PFNCLOSE pfnclose, PFNSEEK pfnseek, int cpuType, PERF perf);
Example 2:BOOL FAR DIAMONDAPI FDICopy (HFDI hfdi, char FAR *pszCabinet, char FAR *pszCabPath, int flags, PFNFDINOTIFY pfnfdin, PFNFDIDECRYPT pfnfdid, void FAR *pvUser);
4