Microsoft公司.CAB文件格式

本文介绍Microsoft CAB文件格式的内部结构,包括CAB_HEADER、CAB_FOLDER及CAB_ENTRY等关键结构体定义,以及文件提取回调函数FDIExtract的工作流程。

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); 

### .cab 文件格式概述 .cab 文件是一种由 Microsoft 开发的压缩文件格式,主要用于软件分发和安装包的压缩。它支持数据压缩、文件分割以及数字签名等功能。以下是关于 .cab 文件的解压、创建及使用方法的详细说明。 --- ### 解压 .cab 文件 在 Windows 系统中,可以使用内置工具或第三方软件来解压 .cab 文件。 1. **使用 Windows 内置工具** Windows 提供了 `expand` 命令行工具来解压 .cab 文件。例如: ```cmd expand -r archive.cab C:\output_directory\ ``` 上述命令将 `archive.cab` 中的所有文件解压到指定目录 `C:\output_directory\`[^1]。 2. **使用第三方工具** 第三方工具如 7-Zip 或 WinRAR 可以更方便地解压 .cab 文件。只需右键点击 .cab 文件并选择“解压到”即可完成操作。 3. **使用 Python 解压 .cab 文件** Python 的 `pycab` 模块可以用于处理 .cab 文件。以下是一个简单的代码示例: ```python from pycab import CabFile cab = CabFile("archive.cab") cab.extractall("output_directory") ``` 此代码会将 `archive.cab` 中的所有文件提取到 `output_directory` 文件夹中[^1]。 --- ### 创建 .cab 文件 创建 .cab 文件通常需要使用 Microsoft 提供的 `makecab` 工具或其他第三方工具。 1. **使用 `makecab` 工具** `makecab` 是 Windows 自带的一个命令行工具,用于创建 .cab 文件。以下是一个基本示例: ```cmd makecab /D CompressionType=LZX /D CompressionLevel=7 file_to_compress.txt archive.cab ``` 上述命令将 `file_to_compress.txt` 压缩为 `archive.cab` 文件,并使用 LZX 压缩算法[^3]。 2. **使用脚本批量创建 .cab 文件** 如果需要批量压缩多个文件,可以编写一个 `.ddf`(Directives Definition File)文件来定义压缩规则。例如: ```plaintext .Set CabinetNameTemplate=archive.cab .Set CompressionType=LZX .Set CompressionLevel=7 file1.txt file2.txt ``` 然后运行以下命令: ```cmd makecab /F directive_file.ddf ``` --- ### 使用 .cab 文件 .cab 文件常用于以下场景: 1. **Windows 安装程序** 许多 Windows 软件安装包中包含 .cab 文件,用于存储压缩后的程序文件。安装时,系统会自动解压这些文件。 2. **驱动程序更新** Windows 驱动程序更新包中也经常使用 .cab 文件格式。用户可以通过设备管理器直接安装这些驱动程序。 3. **嵌入式系统** 在某些嵌入式系统中,.cab 文件被用作固件更新的载体,因为其体积小且易于传输。 --- ### Linux 下处理 .cab 文件 在 Linux 系统中,可以使用 `cabextract` 工具来解压 .cab 文件。 1. **安装 cabextract 工具** 在基于 Debian 的系统上,可以运行以下命令安装 `cabextract`: ```bash sudo apt-get install cabextract ``` 2. **解压 .cab 文件** 使用以下命令解压 .cab 文件: ```bash cabextract archive.cab -d output_directory ``` --- ### 注意事项 - 如果 .cab 文件受密码保护,则需要在解压时提供正确的密码。 - 在某些情况下,.cab 文件可能包含损坏的数据,导致无法正常解压。此时可以尝试使用修复工具或检查文件完整性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值