如何利用C++提取压缩文件中的某一个文件,高手进来帮我解答一下。

h641330010 2014-07-11 01:11:43
因为我才疏学浅,所以不知道怎么改,求高手帮我解答一下,问题如下:
首先是一个MPQ文件,MPQ 是 Blizzard 公司将游戏数据包装在一起的一种档案格式,详见:http://blog.csdn.net/zhyjunFov/article/details/25376595
目前我有个MPQ文件,里面有两个文件,一个是文件名是1.a另一个的文件名是2.a
但是2.a这个文件名在文件名的前面和后面多了一个回车,但是平常的方法根本解压不出来2.a这个文件名,
1是由于windows系统本身的限制就是文件名不能含有回车等字符,
2是普通的MPQ解压文件能看到这个文件但是不能解压,
求个高手帮我改改这一段源码,能将2.a这个文件解压出来,因为魔兽争霸的读取机制能忽略回车读取这个文件
program Mpq;

{$APPTYPE CONSOLE}

uses
SysUtils,
Classes
,windows
;

//Storm API
Const Storm='Storm.dll';

function SFileDestroy:LongBool;stdcall;external Storm Index 262;

function SFileOpenArchive(lpFileName: Pchar;
dwPriority: LongInt;
dwFlags: LongInt;
var hMPQ: LongWord):LongBool;stdcall;external Storm Index 266;

function SFileCloseArchive(hMPQ: LongWord):LongBool;stdcall;external Storm Index 252;


function SFileOpenFileEx(hMPQ: LongWord;
lpFileName: Pchar;
dwSearchScope: LongInt;
var hFile: LongWord): LongBool;stdcall;external Storm Index 268;

function SFileOpenFile(lpFileName: Pchar;
var hFile: LongWord): LongBool;stdcall;external Storm Index 267;



function SFileCloseFile(hFile: LongWord): LongBool;stdcall;external Storm Index 253;

function SFileGetFileSize(hFile: LongWord;
lpFileSizeHigh: LongInt{point dw null}): LongInt ;stdcall;external Storm Index 265;

function SFileReadFile(hFile: LongWord;
lpBuffe:pointer;
nNumberOfBytesToRead: LongInt;
lpNumberOfBytesRead:pointer;
lpOverlapped:pointer
): LongBool;stdcall;external Storm Index 269;



function SFileSetLocale(nNewLocale: LongWord): LongWord;stdcall;external Storm Index 272;


//主程序区
var
MyPath:string;
hmpq, //保存MPQ句柄
hf, //文件句柄
FileSize//文件大小
:LongWord;
Mem:TMemoryStream; //内存流
begin
Writeln('========================================================');
Writeln('You must type in like this:Mpq.exe MpqFileName FileName');
Writeln('For example:c:\>Mpq demo.w3m war3map.j');
Writeln('then you can extract war3map.j from demo.w3m');
Writeln('========================================================');
Writeln;

MyPath:=ExtractFilePath(ParamStr(0)); //获得自己的路径
if ((ParamStr(1)<>'')and(ParamStr(2)<>''))then //2个参数都不为空
begin
SFileDestroy; //初始化MPQ内部函数结构
SFileSetLocale($409);//设置MPQ语言
//以上2个不设置一般也没事 但是某些文件会无法读取
if SFileOpenArchive(Pchar(MyPath+(ParamStr(1))),0,0,hMPQ)then //打开Mpq文件镜像
begin
if(SFileOpenFileEx(hMPQ,Pchar(ParamStr(2)),0,hF))then //打开Mpq内部文件句柄
begin
FileSize:=SFileGetFileSize(hF,0);//获得文件大小
Mem:=TMemoryStream.Create; //创建内存流
Mem.SetSize(FileSize); //设置大小
Mem.Position:=0; //指针移动到流顶部
if SFileReadFile(hf,Mem.Memory,FileSize,nil,nil) then //读取数据到内存
begin
Mem.Position:=0; //指针移动到流顶部
Mem.SaveToFile(MyPath+"5"); //保存到文件
Writeln('File has been extract!');
end
else
begin
Writeln('Could not Read Data!');
end;
Mem.Free;
SFileCloseFile(hF);//关闭文件句柄
end
else
begin
Writeln('Could not open file in Mpq Archive!');
end;
end
else //打开失败
begin
Writeln('Could not open Mpq Archive!');
end;
SFileCloseArchive(hMPQ);//关闭MPQ句柄
end
else
begin
Writeln('You should type in command!');
end;
end.


我所使用的工具是:MpqEditor
Storm.dll文件 http://download.csdn.net/detail/jingqiyixian/5074943

←←←←←
↑↑↑↑↑这个图片就是1.w3m,存在电脑上格式改为mpq或者w3m就可以用软件分析了↑↑↑↑↑
...全文
243 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
caewow 2014-07-14
  • 打赏
  • 举报
回复
祝贺楼主,顺便说一句,我是来接分的
h641330010 2014-07-14
  • 打赏
  • 举报
回复
已经搞定了啦。直接读MPQ文件,将读出来的数据重新命名就得到文件了。
zilaishuichina 2014-07-11
  • 打赏
  • 举报
回复
不明觉历 只能接分
shenchenman 2014-07-11
  • 打赏
  • 举报
回复
我以为我看错了。请问怎么提在c++里
jamesguo37 2014-07-11
  • 打赏
  • 举报
回复
MPQ有一定的格式,即文件头+文件内容。试一下直接读该MPQ文件,然后解析文件格式,最后将读取出来的数据保存为文件即可。
赵4老师 2014-07-11
  • 打赏
  • 举报
回复
Pascal

64,639

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧