1 /* 2 * main.cpp 3 * 4 * Created on: Aug 17, 2015 5 * Author: smallcroco 6 * 7 * Discription: 8 * 1 首先打开解压包,可以设置打开方式,获得句柄; 9 * RAROpenArchive函数,需要RAROpenArchiveData结构体 10 * 或者 11 * RAROpenArchiveEx函数,需要RAROpenArchiveDataEx结构体 12 * 13 * 2 然后设置回调函数; 14 * RARSetCallback函数,需要设置回调函数 15 * 16 * 3 读取文件头,并判断是否解压完成; 17 * RARReader函数,需要RARHeaderData结构体 18 * 或者 19 * RARReaderEx函数,需要RARHeaderDataEx结构体 20 * 21 * 4 跳到下一个文件; 22 * RARProcessFile函数 23 * 或者 24 * RARProcessFileW函数 25 * 26 * 5 关闭句柄; 27 * RARCloseArchive函数 28 */ 29 30 #include <cstdio> 31 32 #define _UNIX 33 34 #include <string.h> 35 #include <iostream> 36 37 #include "dll.hpp" 38 39 using namespace std; 40 41 typedef int function(unsigned int msg, long int UserData, long int P1, 42 long int P2); 43 44 int main() { 45 46 cout<<"请输入解压模式:"<<endl; 47 cout<<"读取文件头不解压,输入:1"<<endl; 48 cout<<"解压文件,输入:2"<<endl; 49 50 long Mode; 51 cin>>Mode; 52 53 // 打开压缩包 54 RAROpenArchiveData ArchiveData; 55 memset(&ArchiveData, 0, sizeof(RAROpenArchiveData)); 56 char name[] = "./testRar/test.rar"; 57 ArchiveData.ArcName = name; 58 59 // 打开模式:RAR_OM_LIST或RAR_OM_EXTRACT 60 // RAR_OM_LIST 只读取文件头,获取一些文件信息,而不解压文件 61 // RAR_OM_EXTRACT 为检测或者解压缩而打开压缩包 62 if (Mode == 1) { 63 ArchiveData.OpenMode = RAR_OM_LIST; 64 } else if (Mode == 2){ 65 ArchiveData.OpenMode = RAR_OM_EXTRACT; 66 } 67 68 // 输出结果: 69 // 0成功 70 // ERAR_NO_MEMORY 内存不足,无法初始化数据结构 71 // ERAR_BAD_DATA 压缩包头损坏 72 // ERAR_BAD_ARCHIVE 不是有效的Rar压缩包 73 // ERAR_UNKNOWN_FORMAT 无法识别的压缩方式 74 // ERAR_EOPEN 压缩包打开错误 75 ArchiveData.OpenResult = 0; 76 // 设置存放注释缓冲区,最大不能超过64KB;设为null表示不读取注释 77 ArchiveData.CmtBuf = NULL; 78 // 设置缓冲区大小 79 ArchiveData.CmtBufSize = 0; 80 // 实际读取到的注释大小 81 ArchiveData.CmtSize = 0; 82 // 输出注释状态: 83 // 0 注释不存在 84 // 1 注释读取完毕 85 // ERAR_NO_MEMORY 内存不足 86 // ERAR_BAD_DATA 注释损坏 87 // ERAR_UNKNOWN_FORMAT 注释格式无效 88 // ERAR_SMALL_BUF 缓冲区过小 89 ArchiveData.CmtState = 0; 90 91 HANDLE handle = RAROpenArchive(&ArchiveData); 92 if (ArchiveData.OpenResult != 0) { 93 cout << "解压出错" << endl; 94 return -1; 95 } 96 97 // 设置回调函数 98 RARSetCallback(handle, function, Mode); 99 100 101 RARHeaderData headerdata; 102 int RHCode; 103 while ((RHCode = RARReadHeader(handle, &headerdata)) == 0) { 104 105 if (Mode == 1) { 106 cout << "解压:" << headerdata.FileName << endl; 107 108 // 第一个参数:句柄 109 // 第二个参数:路转方式 110 // 第三个参数:文件解压路径不带文件名,NULL表示当前路径;这个参数只有在DestName为NULL时才有效 111 // 第四个参数:文件解压路径带文件名,当第三个参数和第个参数同时设置时,以第四个参数为准 112 int PFCode = RARProcessFile(handle, RAR_EXTRACT, NULL, NULL); 113 if (PFCode != 0) { 114 cout << "解压出错" << endl; 115 break; 116 } 117 } 118 119 if (Mode == 2) { 120 cout << "测试:" << headerdata.FileName << endl; 121 int PFCode = RARProcessFile(handle, RAR_TEST, NULL, NULL); 122 if (PFCode != 0) { 123 cout << "解压出错" << endl; 124 break; 125 } 126 } 127 } 128 129 if (RHCode == ERAR_BAD_DATA) { 130 cout << "File Header broken" << endl; 131 } 132 133 RARCloseArchive(handle); 134 135 return 0; 136 137 } 138 139 // 回调函数 140 int function(unsigned int msg, long int UserData, long int P1, long int P2) { 141 142 switch (msg) { 143 144 // 表示解压多个卷的压缩包 145 case UCM_CHANGEVOLUME: { 146 147 // 如果P2为RAR_VOL_ASK,则表示需要的一个卷找不到,例如几个分卷不在同一文件夹下 148 // 需要的卷名称为P1指向的字符串。 149 // 此时有两种解决办法,一种是把需要的卷路径(带卷名称)赋值给P1,然后返回一个非负数,解压继续 150 // 另一种办法就是直接返回-1,终止解压过程 151 if (P2 == RAR_VOL_ASK) { 152 cout << "\n\nVolume " << (char*) P1 << "is required\n" 153 << "Possible options:\n" << endl; 154 cout << "\nEnter - try again" << endl; 155 cout << "‘R‘ -specify a new volume name" << endl; 156 cout << "‘Q‘ -quit" << endl; 157 cout << "Enter your choice:" << endl; 158 159 switch (getchar()) { 160 case ‘Q‘: 161 return -1; 162 case ‘R‘: { 163 cin >> (char*) P1; 164 return 0; 165 } 166 default: 167 return 0; 168 } 169 return 0; 170 } 171 172 // 如果P2为RAR_VOL_NOTIFY则表示,需要的卷找到了,正常打开了,P1指向的就是另一个卷的名称,此时不能修改P1的值 173 // 此时也有两种操作: 174 // 一种是直接返回非负数,继续解压过程 175 // 另一种是返回-1,终止解压过程 176 if (P2 == RAR_VOL_NOTIFY) { 177 cout << "\n... volume\n" << (char*) P1 << endl; 178 return 0; 179 } 180 return 0; 181 } 182 183 // 正常的解压过程 184 // P1指向解压数据的地址 185 // P2解压数据的大小 186 case UCM_PROCESSDATA: { 187 return 0; 188 } 189 190 // 需要密码才能解压 191 // P1指向密码缓冲区地址 192 // P2缓冲区大小 193 case UCM_NEEDPASSWORD: { 194 cin >> (char*) P1; 195 P2 = strlen((char*) P1); 196 return 0; 197 } 198 } 199 }
时间: 2024-11-06 12:44:08