/** * @file cab.h Microsoft Cabinet module * * $Id: cab.h,v 1.6 2003/01/01 06:22:32 chipx86 Exp $ * * @Copyright (C) 1999-2003 The GNUpdate Project. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef _CAB_H_ #define _CAB_H_ #include #include #include "utils.h" /** * @page structure Cabinet File Structure * * 1. CabHeader (32 bytes) * * 2. Reserve area (if CabHeader.flags & CX_FLAG_RESERVE) * - Header Reserve size (2 bytes) * - Folder reserve size (1 byte) * - Data reserve size (1 byte) * - Reserve Data * * 3. Previous cabinet file * (NUL-terminated, if CabHeader.flags & CX_FLAG_HAS_PREV) * * 4. Previous disk name * (NUL-terminated, if CabHeader.flags & CX_FLAG_HAS_PREV) * * 5. Next cabinet file * (NUL-terminated, if CabHeader.flags & CX_FLAG_HAS_PREV) * * 6. Next disk name * (NUL-terminated, if CabHeader.flags & CX_FLAG_HAS_PREV) * * 7. 1 or more CabFolder (count == CabHeader.folderCount) * - Folder reserve (if Folder reserve size != 0) * * 8. 1 or more CanEntry (count == CabHeader.fileCount) * * 9. File data (offset == CabFolder.dataOffset) * - Data reserve (if Data reserve size != 0) */ /** @name Cabinet information */ #define CAB_SIGNATURE "MSCF" /**< Magic string. */ #define CAB_SIG_SIZE 4 /**< Size of the magic string. */ #define CAB_VERSION 0x0103 /**< Cabinet format version. */ /** @name Cabinet flags */ #define CAB_FLAG_HAS_PREV 0x0001 /**< Has a previous cabinet file. */ #define CAB_FLAG_HAS_NEXT 0x0002 /**< Has a next cabinet file. */ #define CAB_FLAG_RESERVE 0x0004 /**< Has a reserved data area. */ /** @name Convenience macros */ #define CAB_HAS_PREV(h) (((h)->flags & CAB_FLAG_HAS_PREV) == CAB_FLAG_HAS_PREV) #define CAB_HAS_NEXT(h) (((h)->flags & CAB_FLAG_HAS_NEXT) == CAB_FLAG_HAS_NEXT) #define CAB_HAS_RESERVE(h) \ (((h)->flags & CAB_FLAG_RESERVE) == CAB_FLAG_RESERVE) /** @name File attributes */ #define CAB_ATTRIB_READONLY 0x0001 /**< Read-only file. */ #define CAB_ATTRIB_HIDDEN 0x0002 /**< Hidden file. */ #define CAB_ATTRIB_SYSTEM 0x0004 /**< System file. */ #define CAB_ATTRIB_VOLUME 0x0008 /**< Volume. */ #define CAB_ATTRIB_DIRECTORY 0x0010 /**< Directory. */ #define CAB_ATTRIB_ARCHIVE 0x0020 /**< Archive file (normal). */ #define CAB_ATTRIB_EXEC 0x0040 /**< File is executable (?) */ #define CAB_ATTRIB_NAME_UTF 0x0080 /**< Name is UTF */ /** @name Folder control IDs */ #define CAB_ENTRY_FIRST 0x0000 /**< First block for the entry. */ /* #define CAB_ENTRY_NEXT 0x0001 */ #define CAB_ENTRY_CONT_NEXT 0xFFFE /**< Continued to the next cab. */ #define CAB_ENTRY_CONT_PREV 0xFFFD /**< Continued from a previous cab. */ #define CAB_ENTRY_CONT_PREV_NEXT 0xFFFF /**< Continued to a previous and next cab. */ /** @name Compression types */ #define CAB_COMP_MASK 0x000F #define CAB_COMP_NONE 0x0000 #define CAB_COMP_MSZIP 0x0001 #define CAB_COMP_QUANTUM 0x0002 #define CAB_COMP_LZX 0x0003 /** @name Structure sizes */ #define CAB_HEADER_SIZE 36 #define CAB_FOLDER_SIZE 8 #define CAB_ENTRY_SIZE 16 #define CAB_NAME_MAX 1024 /** * @name Cabinet header structure. * * 36 bytes. */ typedef struct { char sig[4]; /**< File signature ("MSCF") */ unsigned long headerChecksum; /**< Header checksum (0 if not used) */ unsigned long cabSize; /**< Cabinet file size. */ unsigned long folderChecksum; /**< Folders checksum (0 if not used) */ unsigned long firstOffset; /**< First entry offset. */ unsigned long fileChecksum; /**< Files checksum (0 if not used) */ unsigned short version; /**< Cabinet version. */ unsigned short folderCount; /**< Number of folders. */ unsigned short fileCount; /**< Number of files. */ unsigned short flags; /**< Cabinet flags. */ unsigned short setId; /**< Cabinet set ID. */ unsigned short cabNum; /**< 0-based cabinet number. */ } CabHeader; typedef struct _CabInfo CabInfo; struct _CabInfo { union { char buffer[CAB_HEADER_SIZE]; CabHeader header; } u; char *prevFile; char *nextFile; char *prevDesc; char *nextDesc; CxFP *fp; CabInfo *prev; CabInfo *next; }; /** * @name Cabinet folder. * * 8 bytes. */ typedef struct { unsigned long dataOffset; /**< Offset of folder data. */ unsigned short blockCount; /**< Number of blocks in the folder. */ unsigned short compressType; /**< Compression type. */ } CabFolder; /** * @name Cabinet entry. * * 16 bytes. */ typedef struct { unsigned long fileSize; /**< Uncompressed file size. */ unsigned long offset; /**< File offset after decompression. */ unsigned short folderId; /**< Folder control ID (CAB_FILE_*) */ unsigned short date; /**< DOS-based date stamp. */ unsigned short time; /**< DOS-based time stamp. */ unsigned short attribs; /**< File attributes (CAB_ATTRIB_*) */ } CabEntry; typedef struct { CabInfo *cabFiles; CabInfo *lastCabFile; } CabModuleData; CxStatus cxCabReadInfo(CxArchive *archive, CabInfo **destInfo, CxFP *fp); #endif /* _CAB_H_ */