7z作为开源的解压缩项目,支持多种格式的解压缩,由 Igor Pavlov 开发,最新的版本为 19.00 版。
源码下载位置:https://www.7-zip.org/a/7z1900-src.7z
源码解压之后,是这样的结构:
Asm | 包含主要算法的汇编实现,直接使用汇编可以提高执行效率。但是却对跨平台移植造成了一些困难 |
C | 主要是算法的代码,由C语言实现 |
CPP | 相关COM接口的实现,界面,工程文件等 |
DOC | 相关文档 |
对于我们编译项目来说,最主要的就是 CPP 文件夹,编译的项目文件在 CPP\7zip\Bundles\ 中可以找到。
Alone |
独立的可执行程序,支持的解压格式仅包括7z, cab, tar, zip这几种。 |
Alone7z |
独立的可执行程序,仅支持7z格式。 |
FM |
文件管理器(File Manager),通过加载7z.dll的导出函数进行解压。 |
Format7z | 7za.dll 7z Standalone Plugin,7z 独立插件(仅7z格式) |
Format7zF | 7z.dll 7z Plugin, 7z插件,包含各种格式。 |
SFXCon |
自解压(控制台程序) |
SFXSetup |
自解压程序(安装包) |
SFXWin | 自解压程序(Windows界面)。 |
7z.dll 中的每一种支持的格式被称作 Archive,代码位于CPP\7zip\Archive中。
每一种Archive包含一个Handler,Handler里包含处理每一种Archive的接口。
每一种Archive包含一个Register,用于向全局对象注册,只有注册后的Handler才会被调用。
Handler必须继承IInArchive接口,用于传入给Handler的对象,用于解压。
Handler可以继承IOutArchive接口,用于生成Archive对象,用于压缩文档。
根据官方说明:
仅这几种Archive是可以被压缩的,因此这些Archive的Handler要继承IOutArchive接口。
如果代码只用于解压,而不用于压缩,可定义EXTRACT_ONLY宏,可不生成IOutArchive,可以减少文件体积。
打开 CPP\7zip\Bundles\Format7zF\Format7z.dsw,即可打开7z.dll工程。
我使用的编译器是vs2008,打开dsw文件提示升级,转换后可生成 sln 文件和对应的 vcproj 文件。
直接编译。
第一次编译,报错:
1>LINK : 无法创建 .ILK 文件的映射;正在非增量链接
1>LINK : fatal error LNK1104: 无法打开文件“C:\Program Files\7-Zip\7z.dll”
解决方法:文件占用,编译器权限不够,不能对此文件进行修改,修改生成目标地址,生成到其他地方就可以了。
第二次编译,报错:
1>正在链接...
1>.\Debug\7zCrcOpt.obj : fatal error LNK1107: 文件无效或损坏: 无法在 0x276 处读取
解决方法:删除工程中的asm文件,改由对应的c文件实现,记得将这些c文件的预编译头选项改为“不使用预编译头”。
第三次编译,成功。
通过IDA打开7z.dll可发现其导出函数。
CreateDecoder:创建解码器
CreateEncoder:创建编码器
CreateObject:创建对象
GetHandlerProperty2:获取Handler属性
GetHandlerProperty:获取Handler属性
GetHashers:获取 IHasher 对象
GetIsArc:获取 IsArc 函数地址
GetMethodProperty:获取解码器属性。传入codecIndex和PROPID,传出PROPVARIANT*
GetNumberOfFormats:获取文件格式的数量。
GetNumberOfMethods:获取解码器的数量。
SetCaseSensitive:设置当前文件系统是否大小写敏感,WINDOWS默认不敏感,其他系统默认敏感。
SetCodecs:传入ICompressCodecsInfo对象,设置外部解码器。
SetLargePageMode:设置大内存页模式,这种模式可申请更多的内存。
------先写这么多,后续更------