#include "Compress.h"
#include "Utility.h"
#include <io.h>
#include <fcntl.h>
#include <share.h>
namespace
{
FNFCIFILEPLACED(FCIFilePlaced)
{
return 0;
}
FNFCIALLOC(FCIAlloc)
{
return malloc(cb);
}
FNFCIFREE(FCIFree)
{
return free(memory);
}
FNFCIOPEN(FCIOpen)
{
INT_PTR hf = -1;
*err = _sopen_s(&hf, pszFile, oflag | _O_RAW, _SH_DENYWR, pmode);
return hf;
}
FNFCIREAD(FCIRead)
{
return _read(hf, memory, cb);
}
FNFCIWRITE(FCIWrite)
{
return _write(hf, memory, cb);
}
FNFCICLOSE(FCIClose)
{
return _close(hf);
}
FNFCISEEK(FCISeek)
{
return _lseek(hf, dist, seektype);
}
FNFCIDELETE(FCIDelete)
{
return remove(pszFile);
}
FNFCIGETTEMPFILE(FCIGetTempFile)
{
CHAR szTempPath[MAX_PATH];
CHAR szTempFile[MAX_PATH];
if(GetTempPathA(MAX_PATH, szTempPath) == 0)
{
return FALSE;
}
if(GetTempFileNameA(szTempPath, "CABINET", 0, szTempFile) == 0)
{
return FALSE;
}
if(!DeleteFileA(szTempFile))
{
return FALSE;
}
HRESULT hr = StringCbCopyA(pszTempName, cbTempName, szTempFile);
return SUCCEEDED(hr);
}
FNFCIGETNEXTCABINET(FCIGetNextCabinet)
{
HRESULT hr = StringCbPrintfA(pccab->szCab, CB_MAX_CABINET_NAME, reinterpret_cast<PCSTR>(pv), pccab->iCab);
return SUCCEEDED(hr);
}
FNFCISTATUS(FCIStatus)
{
return 0;
}
FNFCIGETOPENINFO(FCIGetOpenInfo)
{
WIN32_FIND_DATAA FindFileData;
HANDLE hFind = FindFirstFileA(pszName, &FindFileData);
if(hFind != INVALID_HANDLE_VALUE)
{
FindClose(hFind);
Cabinet::Utility::FileTimeToDosTime(FindFileData.ftLastWriteTime, pdate, ptime);
*pattribs = static_cast<USHORT>(FindFileData.dwFileAttributes);
}
return FCIOpen(pszName, _O_RDONLY, 0, err, pv);
}
} //anonymous namespace
Cabinet::CCompress::CCompress() : m_hFCI(NULL)
{
m_szCab[0] = '\0';
}
Cabinet::CCompress::~CCompress()
{
_Destroy();
}
BOOL Cabinet::CCompress::Create(ULONG cbCab, LPCSTR lpCabPath)
{
_Destroy();
ERF erf;
CCAB ccab = {};
ccab.cb = cbCab;
PCCH pBackslash = strrchr(lpCabPath, '\\');
if(pBackslash == NULL)
{
return FALSE;
}
if(cbCab == 0)
{
StringCbCopyA(ccab.szCab, CB_MAX_CABINET_NAME, pBackslash + 1);
}
else
{
PCCH pExtension = strrchr(pBackslash + 1, '.');
if(pExtension == NULL)
{
StringCbCopyA(m_szCab, CB_MAX_CABINET_NAME, pBackslash + 1);
StringCbCatA(m_szCab, CB_MAX_CABINET_NAME, "%02d");
}
else
{
StringCbCopyNA(m_szCab, CB_MAX_CABINET_NAME, pBackslash + 1, pExtension - pBackslash - 1);
StringCbCatA(m_szCab, CB_MAX_CABINET_NAME, "%02d");
StringCbCatA(m_szCab, CB_MAX_CABINET_NAME, pExtension);
}
FCIGetNextCabinet(&ccab, 0, m_szCab);
}
StringCbCopyNA(ccab.szCabPath, CB_MAX_CAB_PATH, lpCabPath, pBackslash - lpCabPath + 1);
m_hFCI = FCICreate(&erf, FCIFilePlaced, FCIAlloc, FCIFree, FCIOpen, FCIRead, FCIWrite, FCIClose, FCISeek, FCIDelete, FCIGetTempFile, &ccab, m_szCab);
return m_hFCI != NULL;
}
BOOL Cabinet::CCompress::AddFile(LPCSTR lpSourceFile) CONST
{
PCCH pBackslash = strrchr(lpSourceFile, '\\');
if(pBackslash == NULL)
{
return FALSE;
}
CHAR szSourceFile[CB_MAX_CAB_PATH];
StringCbCopyA(szSourceFile, CB_MAX_CAB_PATH, lpSourceFile);
CHAR szFileName[CB_MAX_CABINET_NAME];
StringCbCopyA(szFileName, CB_MAX_CABINET_NAME, pBackslash + 1);
return FCIAddFile(m_hFCI, szSourceFile, szFileName, FALSE, FCIGetNextCabinet, FCIStatus, FCIGetOpenInfo, tcompTYPE_MSZIP);
}
BOOL Cabinet::CCompress::AddFolder(LPCSTR lpSourceFolder) CONST
{
CHAR szSourceFolder[MAX_PATH];
StringCbCopyA(szSourceFolder, MAX_PATH, lpSourceFolder);
Utility::PathRemoveBackslash(szSourceFolder);
PCCH pBackslash = strrchr(szSourceFolder, '\\');
if(pBackslash == NULL)
{
return FALSE;
}
return _AddFolder(szSourceFolder, pBackslash - szSourceFolder + 1);
}
BOOL Cabinet::CCompress::FlushCabinet() CONST
{
return FCIFlushCabinet(m_hFCI, FALSE, FCIGetNextCabinet, FCIStatus);
}
BOOL Cabinet::CCompress::_AddFolder(LPCSTR lpSourceFolder, SIZE_T Offset) CONST
{
CHAR szFindFile[MAX_PATH];
StringCbCopyA(szFindFile, MAX_PATH, lpSourceFolder);
StringCbCatA(szFindFile, MAX_PATH, "\\*.*");
SIZE_T cb = strlen(lpSourceFolder) + 1;
BOOL bRet = FALSE;
WIN32_FIND_DATAA FindFileData;
HANDLE hFind = FindFirstFileA(szFindFile, &FindFileData);
if(hFind != INVALID_HANDLE_VALUE)
{
do
{
if(strcmp(FindFileData.cFileName, ".") == 0 || strcmp(FindFileData.cFileName, "..") == 0)
{
continue;
}
StringCbCopyA(szFindFile + cb, MAX_PATH, FindFileData.cFileName);
if((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
{
bRet = _AddFolder(szFindFile, Offset);
if(!bRet)
{
break;
}
}
else
{
bRet = FCIAddFile(m_hFCI, szFindFile, szFindFile + Offset, FALSE, FCIGetNextCabinet, FCIStatus, FCIGetOpenInfo, tcompTYPE_MSZIP);
if(!bRet)
{
break;
}
}
}
while(FindNextFileA(hFind, &FindFileData));
FindClose(hFind);
}
return bRet;
}
VOID Cabinet::CCompress::_Destroy()
{
if(m_hFCI != NULL)
{
FCIDestroy(m_hFCI);
m_hFCI = NULL;
}
}
CAB文件压缩/解压1.0.0.2


CAB( Cabinet)文件是微软开发的一种用于存储和分发软件的压缩文件格式,主要在Windows操作系统中使用。它主要用于减少文件的存储空间,便于软件的分发和更新。CAB文件可以包含多个文件和目录结构,且通常与安装程序一起使用。在本项目中,"CAB文件压缩/解压1.0.0.2" 是一个C++实现的库,能够在Windows环境下对CAB文件进行压缩和解压操作,并且已经通过了Visual Studio 2008的编译测试。 1. CAB文件格式: - CAB文件由一系列的" cabinet"段组成,每个段包含一个或多个"文件"记录。 - 每个文件记录包含一个或多个压缩的数据块,以及文件的元数据,如文件名、大小等。 - CAB文件还支持错误检测和恢复,通过使用CRC校验和来验证数据的完整性。 2. C++源码实现: - `Compress.cpp` 和 `Extract.cpp` 文件很可能包含了CAB文件压缩和解压的核心算法实现。压缩部分可能使用了如LZ77或LZSS等压缩算法,而解压部分则负责还原这些压缩的数据块。 - `Utility.h` 可能包含了辅助函数和通用工具,例如内存管理、文件I/O、错误处理等。 - `Compress.h` 和 `Extract.h` 是对应的头文件,声明了压缩和解压相关的类或函数接口,供其他模块调用。 3. Visual Studio 2008兼容性: - 使用VS2008编译通过表明代码遵循了C++标准,并且与该版本的编译器兼容。这可能意味着代码使用了标准模板库(STL)的部分功能,如容器、迭代器和算法,但可能没有使用C++11及以后版本的新特性。 - 项目的配置文件(如`.vcproj`或`.sln`)可以帮助用户在VS2008环境中快速构建和调试代码。 4. 压缩和解压流程: - 压缩流程:读取原始文件,使用特定的压缩算法对文件内容进行编码,将编码后的数据块写入CAB文件,并记录相应的文件元数据。 - 解压流程:解析CAB文件结构,读取文件记录,解码数据块,然后将原始文件内容恢复到磁盘上。 5. 应用场景: - 软件分发:CAB文件常用于软件安装程序,因为它可以有效地减少文件大小,加速下载和安装过程。 - 系统更新:Windows系统更新经常使用CAB文件来传输更新的驱动程序和系统文件。 - 存储优化:在有限的存储空间中,CAB文件可以用于备份和归档大量文件。 6. 扩展性: - 虽然此项目专注于CAB文件,但它可以作为基础,扩展到支持其他压缩格式,如ZIP、RAR等。 - 可以添加多线程或并行处理以提高压缩和解压速度。 - 通过增加命令行界面或图形用户界面,使得用户更方便地操作这个库。 以上是对"CAB文件压缩/解压1.0.0.2"项目的一些技术分析和知识点介绍,具体实现细节需要查看源码才能深入了解。



















- 1

- #完美解决问题
- #运行顺畅
- #内容详尽
- #全网独家
- #注释完整

- 粉丝: 12
- 资源: 35
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- 【故障诊断】基于matlab快速频率稀疏学习方法轴承故障诊断【含Matlab源码 11085期】.mp4
- 【故障诊断】基于matlab合物稀疏贝叶斯学习法轴承故障诊断【含Matlab源码 12065期】.mp4
- 【故障诊断】基于matlab稀疏包络谱分析多通道数据驱动的BRB故障诊断【含Matlab源码 9922期】.mp4
- 【故障诊断】基于matlab稀疏包络光谱分析多通道数据驱动的断裂转子杆故障诊断【含Matlab源码 13028期】.mp4
- 碳酸钙岩石的酸蚀与酸溶特性及其在非均质地层中的酸溶模型研究,基于非均质地层的碳酸钙岩石酸蚀酸溶现象的COMSOL模拟分析,碳酸钙岩石酸蚀酸溶COMSOL 非均质地层,酸溶模型 ,核心关键词:碳酸钙岩石
- 【故障诊断】基于matlab稀疏贝叶斯学习方法旋翼条状故障诊断【含Matlab源码 12074期】.mp4
- 【故障诊断】基于matlab稀疏包膜光谱分析多渠道数据驱动破碎转子杆故障诊断【含Matlab源码 11087期】.mp4
- 【光无线通信】基于matlab光无线通信的可见光通信VLC仿真【含Matlab源码 9879期】.mp4
- 【故障诊断】基于matlab轴承故障诊断频率稀疏性学习【含Matlab源码 11077期】.mp4
- 【光学通信】基于matlab自由空间光学FSO通信系统(含信噪比)【含Matlab源码 9878期】.mp4
- 【轨迹优化】基于matlab脉冲干扰下高超音速飞机轨迹优化【含Matlab源码 11088期】.mp4
- 【航天器控制】基于matab GPS导航和航天器姿态控制【含Matlab源码 9829期】.mp4
- 【毫米波雷达】基于matlab毫米波频段基础设施到车辆 I2V)通信模拟【含Matlab源码 9810期】.mp4
- 【毫米波雷达】基于matlab TDMA-MIMO毫米波雷达原始数据生成和信号处理【含Matlab源码 9811期】.mp4
- 【肌电信号EMG】基于matlab EMG信号检测患者肌肉疾病(比较了不同患者EMG信号的RMS、功率谱)【含Matlab源码 11150期】含报告.mp4
- 【机器人定位】基于matlab未知测量噪声的非完整机器人扩展卡尔曼滤波器同时定位和建图【含Matlab源码 9958期】.mp4


