int ExtractFile(char* filename) { char* outputFolder = "temp\\"; HANDLE hData; INT RHCode; INT PFCode; RARHeaderData HeaderData; RAROpenArchiveDataEx OpenArchiveData = { 0 }; { OpenArchiveData.ArcName = filename; //OpenArchiveData.CmtBuf = NULL; //OpenArchiveData.CmtBufSize = 0; OpenArchiveData.OpenMode = RAR_OM_EXTRACT; } hData = RAROpenArchiveEx(&OpenArchiveData); if(OpenArchiveData.OpenResult != 0) { char buf[128]; memset(buf, 0, sizeof(buf)); sprintf_s(buf, "Error opening <%s>", filename); MessageBox(NULL, "Error!", buf, MB_OK|MB_ICONERROR); return -1; } RARSetPassword(hData, "8863da099df8adc830836744e19293ef"); while((RHCode = RARReadHeader(hData, &HeaderData)) == 0) { PFCode = RARProcessFile(hData, RAR_EXTRACT, outputFolder, NULL); if(PFCode != 0) { char buf[128]; memset(buf, 0, sizeof(buf)); sprintf_s(buf, "Error extracting <%s>", filename); MessageBox(NULL, "Error!", buf, MB_OK|MB_ICONERROR); return -1; } struct stat st; std::string file = outputFolder; file += HeaderData.FileName; stat(file.c_str(), &st); if(st.st_mode & S_IFREG) { vfs->patchfiles.push_back(file); } } if(RHCode == ERAR_BAD_DATA) { char buf[128]; memset(buf, 0, sizeof(buf)); sprintf_s(buf, "Error <%s> is corrupt", filename); MessageBox(NULL, "Error!", buf, MB_OK|MB_ICONERROR); return -1; } RARCloseArchive(hData); DeleteFile(filename); return 0; }
void YKZip::Extra(const YKString& srcFile, const YKString& desPath, const YK_CHAR* passWord /* = "" */) { #if YK_OS == YK_OS_WINDOWS_NT setlocale(LC_ALL, NULL); HANDLE hArcData; int RHCode,PFCode; char CmtBuf[16384]; struct RARHeaderDataEx HeaderData; struct RAROpenArchiveDataEx OpenArchiveData; memset(&HeaderData,0,sizeof(HeaderData)); memset(&OpenArchiveData,0,sizeof(OpenArchiveData)); YKBuffer<YK_WCHAR> buffSrc(srcFile.size()+1); std::wcscpy(buffSrc.Begin(), srcFile.c_str()); YKBuffer<YK_WCHAR> buffDes(desPath.size()+1); std::wcscpy(buffDes.Begin(), desPath.c_str()); OpenArchiveData.ArcNameW = buffSrc.Begin(); OpenArchiveData.CmtBuf=CmtBuf; OpenArchiveData.CmtBufSize=sizeof(CmtBuf); OpenArchiveData.OpenMode=RAR_OM_EXTRACT; OpenArchiveData.Callback=YK_NULL; OpenArchiveData.UserData=0; hArcData = RAROpenArchiveEx(&OpenArchiveData); if (OpenArchiveData.OpenResult!=0) return; RARSetPassword(hArcData, const_cast<YK_CHAR*>(passWord)); while ((RHCode=RARReadHeaderEx(hArcData,&HeaderData))==0) { PFCode = RARProcessFileW(hArcData,RAR_EXTRACT, buffDes.Begin(), NULL); } RARCloseArchive(hArcData); #endif // YKString strExtra = g_Application.GetCurModulePath(); // strExtra.Append(L"HaoZip\\HaoZipC.exe x ").Append(srcFile).Append(L" -ao -y -o").Append(desPath); // strExtra.Append(L" -p").Append(L"42F7AA9A-67E0-4CC7-9526-B2E8B358F179"); // system(strExtra.ToString().c_str()); // return; // HZIP hz = OpenZip(srcFile.c_str(), passWord); // ZIPENTRY ze; // GetZipItem(hz,-1,&ze); // int num = ze.index; // for (int i = 0; i < num; ++i) // { // GetZipItem(hz, i, &ze); // UnzipItem(hz,i, (desPath + ze.name).c_str()); // } // // CloseZip(hz); }
ComicBookRAR::ComicBookRAR(wxString file, wxUint32 cacheLen, COMICAL_ZOOM zoom, long zoomLevel, bool fitOnlyOversize, COMICAL_MODE mode, FREE_IMAGE_FILTER filter, COMICAL_DIRECTION direction, wxInt32 scrollbarThickness) : ComicBook(file, cacheLen, zoom, zoomLevel, fitOnlyOversize, mode, filter, direction, scrollbarThickness) { HANDLE rarFile; int RHCode = 0, PFCode = 0; struct RARHeaderDataEx header; struct RAROpenArchiveDataEx flags; wxString page, new_password; open_rar: rarFile = openRar(&flags, &header, RAR_OM_LIST); if (flags.Flags & 0x0080) { // if the headers are encrypted new_password = wxGetPasswordFromUser( wxT("This archive is password-protected. Please enter the password."), wxT("Enter Password")); if (new_password.IsEmpty()) { // the dialog was cancelled, and the archive cannot be opened closeRar(rarFile, &flags); throw ArchiveException(filename, wxT("Comical could not open this file because it is password-protected.")); } SetPassword(new_password.ToAscii()); } if (password) RARSetPassword(rarFile, password); while ((RHCode = RARReadHeaderEx(rarFile, &header)) == 0) { #ifdef wxUSE_UNICODE page = wxString(header.FileNameW); #else page = wxString(header.FileName); #endif if(page.Right(5).Upper() == wxT(".JPEG") || page.Right(4).Upper() == wxT(".JPG") || page.Right(4).Upper() == wxT(".GIF") || page.Right(4).Upper() == wxT(".PNG")) Filenames->Add(page); if ((PFCode = RARProcessFile(rarFile, RAR_SKIP, NULL, NULL)) != 0) { closeRar(rarFile, &flags); throw ArchiveException(filename, ProcessFileError(PFCode, page)); } } closeRar(rarFile, &flags); // Wrong return code + needs password = wrong password given if (RHCode != ERAR_END_ARCHIVE && flags.Flags & 0x0080) goto open_rar; postCtor(); Create(); // create the wxThread }
bool ComicBookRAR::TestPassword() { HANDLE rarFile; int RHCode = 0, PFCode = 0; struct RARHeaderDataEx header; struct RAROpenArchiveDataEx flags; bool passwordCorrect = true; if (Pages.size() == 0) // nothing in the archive to open return true; wxString page = Pages.at(0)->Filename; // test using the first page rarFile = openRar(&flags, &header, RAR_OM_EXTRACT); if (password) RARSetPassword(rarFile, password); while ((RHCode = RARReadHeaderEx(rarFile, &header)) == 0) { if (page.Cmp(header.FileNameW) == 0) { break; } else { if ((PFCode = RARProcessFile(rarFile, RAR_SKIP, NULL, NULL)) != 0) { closeRar(rarFile, &flags); throw ArchiveException(filename, ProcessFileError(PFCode, page)); } } } if (RHCode != 0) { closeRar(rarFile, &flags); throw new ArchiveException(filename, OpenArchiveError(RHCode)); } RARSetCallback(rarFile, TestPasswordCallbackProc, (long) &passwordCorrect); PFCode = RARProcessFile(rarFile, RAR_TEST, NULL, NULL); closeRar(rarFile, &flags); // If the password is wrong, RARProcessFile will return ERAR_BAD_DATA. Of // course, it will also return ERAR_BAD_DATA when the first file in the archive // is corrupted. How does one tell the difference? if (PFCode == ERAR_BAD_DATA) return false; return passwordCorrect; }
////////////////////////////////////////////////////////// // // ExtractFiles // // Extract files from supplied archive filename // ////////////////////////////////////////////////////////// bool ExtractFiles ( const SString& strFile ) { // Open archive RAROpenArchiveData archiveData; memset ( &archiveData, 0, sizeof ( archiveData ) ); archiveData.ArcName = (char*)*strFile; archiveData.OpenMode = RAR_OM_EXTRACT; HANDLE hArcData = RAROpenArchive ( &archiveData ); if ( !hArcData ) return false; char* szPassword = "******"; RARSetPassword ( hArcData, szPassword ); bool bOk = false; // Do each file while ( true ) { // Read file header RARHeaderData headerData; memset ( &headerData, 0, sizeof ( headerData ) ); int iStatus = RARReadHeader ( hArcData, &headerData ); if ( iStatus != 0 ) { if ( iStatus == ERAR_END_ARCHIVE ) bOk = true; break; } // Read file data iStatus = RARProcessFile ( hArcData, RAR_EXTRACT, NULL, NULL ); if ( iStatus != 0 ) break; } RARCloseArchive ( hArcData ); return bOk; }
wxRarInputStream::wxRarInputStream(const wxChar* szFile) { RAROpenArchiveDataEx rx; memset(&rx,0,sizeof(rx)); #if wxUSE_UNICODE rx.ArcNameW =((wxChar*) szFile); #else /* !wxUSE_UNICODE */ rx.ArcName =((wxChar*) szFile); #endif rx.OpenMode=RAR_OM_EXTRACT; rx.CmtBuf=m_Info.szComment=new char[2000]; rx.CmtBufSize=2000; m_hRar = RAROpenArchiveEx(&rx); if (!m_hRar) { wxLogSysError(wxString::Format(_("Couldn't open rar file %s"), szFile)); delete m_Info.szComment; } RARSetPassword(m_hRar,""); }
int unrar_test_password(const char * file, const char * pwd) { void * unrar; struct RARHeaderData headerdata; struct RAROpenArchiveData archivedata; int password_incorrect; password_incorrect = 0; memset(&headerdata, 0, sizeof(headerdata)); memset(&archivedata, 0, sizeof(archivedata)); archivedata.ArcName = (char *) file; archivedata.OpenMode = RAR_OM_EXTRACT; unrar = RAROpenArchive(&archivedata); if (!unrar || archivedata.OpenResult) return -2; RARSetPassword(unrar, (char *) pwd); RARSetCallback(unrar, _unrar_test_password_callback, (long) &password_incorrect); if (RARReadHeader(unrar, &headerdata) != 0) goto error; if (RARProcessFile(unrar, RAR_TEST, NULL, NULL) != 0) goto error; if (password_incorrect) goto error; RARCloseArchive(unrar); return 0; error: RARCloseArchive(unrar); return -1; }
/* ======================================= RAR 文件读取 ======================================= */ CR_API sFMT_PRT* load_rar ( __CR_IO__ iDATIN* datin, __CR_IN__ const sLOADER* param ) { HANDLE rar; sARRAY list; int32u attr; sint_t retc; leng_t fpos; iPAK_RAR* port; sFMT_PRT* rett; sPAK_RAR_FILE temp; RARHeaderDataEx info; RAROpenArchiveDataEx open; /* 只支持磁盘文件 */ if (param->type != CR_LDR_ANSI && param->type != CR_LDR_WIDE) return (NULL); /* 列表模式打开 RAR 文件 */ struct_zero(&open, RAROpenArchiveDataEx); if (param->type == CR_LDR_ANSI) open.ArcName = (ansi_t*)param->name.ansi; else open.ArcNameW = (wide_t*)param->name.wide; open.OpenMode = RAR_OM_LIST; rar = RAROpenArchiveEx(&open); if (rar == NULL) return (NULL); if (param->aprm != NULL && *(byte_t*)param->aprm != 0x00) { RARSetPassword(rar, (ansi_t*)param->aprm); attr = PAK_FILE_ENC; } else { attr = 0; } /* 开始逐个文件读取信息并定位 */ array_initT(&list, sPAK_RAR_FILE); list.free = rar_free; struct_zero(&info, RARHeaderDataEx); for (fpos = 0; ; fpos++) { /* 读取一个文件记录头 */ retc = RARReadHeaderEx(rar, &info); if (retc == ERAR_END_ARCHIVE) break; if (retc != ERAR_SUCCESS) goto _failure1; /* 目录文件不加入列表 */ if (info.Flags & RHDF_DIRECTORY) { retc = RARProcessFile(rar, RAR_SKIP, NULL, NULL); if (retc != ERAR_SUCCESS) goto _failure1; continue; } /* 文件名统一使用 UTF-8 编码 */ struct_zero(&temp, sPAK_RAR_FILE); temp.base.name = local_to_utf8(param->page, info.FileName); if (temp.base.name == NULL) goto _failure1; /* 设置公用文件属性 (偏移没有实际用处) */ temp.base.skip = sizeof(sPAK_RAR_FILE); temp.base.attr = attr; temp.base.offs = 0; temp.base.pack = mk_size(info.PackSizeHigh, info.PackSize); temp.base.size = mk_size(info.UnpSizeHigh, info.UnpSize); if (info.Method != 0x30) temp.base.attr |= PAK_FILE_CMP; if (info.Flags & RHDF_ENCRYPTED) temp.base.attr |= PAK_FILE_ENC; else temp.base.attr &= ~PAK_FILE_ENC; switch (info.Method) { case 0x30: temp.base.memo = "Storing"; break; case 0x31: temp.base.memo = "Fastest compression"; break; case 0x32: temp.base.memo = "Fast compression"; break; case 0x33: temp.base.memo = "Normal compression"; break; case 0x34: temp.base.memo = "Good compression"; break; case 0x35: temp.base.memo = "Best compression"; break; default: temp.base.memo = "Unknown compression"; break; } /* 设置私有文件属性 */ temp.id = fpos; temp.crc32 = (int32u)(info.FileCRC); temp.fattr = (int32u)(info.FileAttr); temp.ftime = (int16u)(info.FileTime & 0xFFFF); temp.fdate = (int16u)(info.FileTime >> 16); temp.htype = (int32u)(info.HashType); mem_cpy(temp.hash, info.Hash, sizeof(temp.hash)); /* 文件信息压入列表 */ if (array_push_growT(&list, sPAK_RAR_FILE, &temp) == NULL) { mem_free(temp.base.name); goto _failure1; } /* 跳过当前已读文件 */ retc = RARProcessFile(rar, RAR_SKIP, NULL, NULL); if (retc != ERAR_SUCCESS && retc != ERAR_BAD_DATA) goto _failure1; } /* 固定一下列表大小 */ if (!array_no_growT(&list, sPAK_RAR_FILE)) goto _failure1; /* 生成读包接口对象 */ port = struct_new(iPAK_RAR); if (port == NULL) goto _failure1; /* 保存需要用到的参数 */ port->m_temp = NULL; if (attr == 0) { port->m_pass = NULL; } else { port->m_pass = str_dupA((ansi_t*)param->aprm); if (port->m_pass == NULL) goto _failure2; } if (param->type == CR_LDR_ANSI) { port->m_wide = NULL; port->m_ansi = str_dupA(param->name.ansi); if (port->m_ansi == NULL) goto _failure3; } else { port->m_ansi = NULL; port->m_wide = str_dupW(param->name.wide); if (port->m_wide == NULL) goto _failure3; } port->m_rar = NULL; port->m_cur = (leng_t)-1; port->m_cnt = array_get_sizeT(&list, sPAK_RAR_FILE); port->pack.__filelst__ = array_get_dataT(&list, sPAK_FILE); port->pack.__vptr__ = &s_pack_vtbl; if (!pack_init_list((iPACKAGE*)port, TRUE)) goto _failure4; RARCloseArchive(rar); /* 返回读取的文件数据 */ rett = struct_new(sFMT_PRT); if (rett == NULL) { iPAK_RAR_release((iPACKAGE*)port); return (NULL); } CR_NOUSE(datin); rett->type = CR_FMTZ_PRT; rett->port = (iPORT*)port; rett->more = "iPACKAGE"; rett->infor = "Roshal ARchive (RAR)"; return (rett); _failure4: TRY_FREE(port->m_ansi); TRY_FREE(port->m_wide); _failure3: TRY_FREE(port->m_pass); _failure2: mem_free(port); _failure1: array_freeT(&list, sPAK_RAR_FILE); RARCloseArchive(rar); return (NULL); }
/* --------------------------------------- 读取文件数据 --------------------------------------- */ static bool_t iPAK_RAR_getFileData ( __CR_IN__ iPACKAGE* that, __CR_OT__ sBUFFER* buff, __CR_IN__ int64u index, __CR_IN__ bool_t hash ) { sint_t rett; int64u size; void_t* data; iPAK_RAR* real; sPAK_RAR_FILE* item; RARHeaderDataEx info; RAROpenArchiveDataEx open; /* 定位文件索引 */ CR_NOUSE(hash); real = (iPAK_RAR*)that; if (index >= real->m_cnt) return (FALSE); item = (sPAK_RAR_FILE*)real->pack.__filelst__; item += (leng_t)index; /* 获取文件数据 (0大小文件分配1个字节) */ size = item->base.size; if (size == 0) { data = mem_malloc(1); if (data == NULL) return (FALSE); size = 1; *(byte_t*)data = 0x00; } else { real->m_temp = data = mem_malloc64(size); if (data == NULL) return (FALSE); /* RAR 只能顺序读取文件 */ if (real->m_rar == NULL || item->id < real->m_cur) { /* 需要重新打开封包 */ if (real->m_rar != NULL) { RARCloseArchive(real->m_rar); real->m_rar = NULL; } struct_zero(&open, RAROpenArchiveDataEx); if (real->m_ansi != NULL) open.ArcName = real->m_ansi; else open.ArcNameW = real->m_wide; open.OpenMode = RAR_OM_EXTRACT; open.Callback = rar_mem_copy; open.UserData = (LPARAM)(&real->m_temp); real->m_rar = RAROpenArchiveEx(&open); if (real->m_rar == NULL) goto _failure1; if (real->m_pass != NULL) RARSetPassword(real->m_rar, real->m_pass); real->m_cur = 0; } /* 定位到指定文件 */ struct_zero(&info, RARHeaderDataEx); while (real->m_cur != item->id) { rett = RARReadHeaderEx(real->m_rar, &info); if (rett != ERAR_SUCCESS) goto _failure2; rett = RARProcessFile(real->m_rar, RAR_SKIP, NULL, NULL); if (rett != ERAR_SUCCESS && rett != ERAR_BAD_DATA) goto _failure2; real->m_cur += 1; } /* 测试目标文件就不会有磁盘操作了 */ rett = RARReadHeaderEx(real->m_rar, &info); if (rett != ERAR_SUCCESS) goto _failure2; rett = RARProcessFile(real->m_rar, RAR_TEST, NULL, NULL); if (rett != ERAR_SUCCESS) goto _failure2; real->m_cur += 1; } /* 返回文件数据 */ return (buffer_init(buff, data, (leng_t)size, TRUE)); _failure2: RARCloseArchive(real->m_rar); real->m_rar = NULL; _failure1: real->m_cur = (leng_t)-1; mem_free(data); return (FALSE); }
ComicBookRAR::ComicBookRAR(wxString file, wxUint32 cacheLen, COMICAL_ZOOM zoom, long zoomLevel, bool fitOnlyOversize, COMICAL_MODE mode, FREE_IMAGE_FILTER filter, COMICAL_DIRECTION direction, wxInt32 scrollbarThickness) : ComicBook(file, cacheLen, zoom, zoomLevel, fitOnlyOversize, mode, filter, direction, scrollbarThickness) { HANDLE rarFile; int RHCode = 0, PFCode = 0; struct RARHeaderDataEx header; struct RAROpenArchiveDataEx flags; wxString path, new_password; wxInputStream *stream; ComicPage *page; int numEntries, progress=0; open_rar: rarFile = openRar(&flags, &header, RAR_OM_LIST); if (flags.Flags & 0x0080) { // if the headers are encrypted new_password = wxGetPasswordFromUser( wxT("This archive is password-protected. Please enter the password."), wxT("Enter Password")); if (new_password.IsEmpty()) { // the dialog was cancelled, and the archive cannot be opened closeRar(rarFile, &flags); throw ArchiveException(filename, wxT("Comical could not open this file because it is password-protected.")); } SetPassword(new_password.ToAscii()); } if (password) RARSetPassword(rarFile, password); // skip through the entire archive to count the number of entries for (numEntries = 0; RARReadHeaderEx(rarFile, &header) == 0; numEntries++) { if ((PFCode = RARProcessFile(rarFile, RAR_SKIP, NULL, NULL)) != 0) { closeRar(rarFile, &flags); throw ArchiveException(filename, ProcessFileError(PFCode, header.FileNameW)); } } wxProgressDialog progressDlg(wxString(wxT("Opening ")) + file, wxString(), numEntries); progressDlg.SetMinSize(wxSize(400, -1)); // close and re-open the archive to restart at the first header closeRar(rarFile, &flags); rarFile = openRar(&flags, &header, RAR_OM_LIST); while ((RHCode = RARReadHeaderEx(rarFile, &header)) == 0) { path = header.FileNameW; progressDlg.Update(progress, wxString(wxT("Scanning: ")) + path); progressDlg.CentreOnParent(wxHORIZONTAL); stream = ExtractStream(path); page = new ComicPage(path, stream); if (page->GetBitmapType() == wxBITMAP_TYPE_INVALID) delete page; else Pages.push_back(page); wxDELETE(stream); if ((PFCode = RARProcessFileW(rarFile, RAR_SKIP, NULL, NULL)) != 0) { closeRar(rarFile, &flags); throw ArchiveException(filename, ProcessFileError(PFCode, path)); } progressDlg.Update(++progress); } closeRar(rarFile, &flags); // Wrong return code + needs password = wrong password given if (RHCode != ERAR_END_ARCHIVE && flags.Flags & 0x0080) goto open_rar; postCtor(); Create(); // create the wxThread }
wxInputStream * ComicBookRAR::ExtractStream(wxUint32 pageindex) { HANDLE rarFile; int RHCode = 0, PFCode = 0; struct RARHeaderDataEx header; struct RAROpenArchiveDataEx flags; wxString page = Filenames->Item(pageindex); size_t length = 0; rarFile = openRar(&flags, &header, RAR_OM_EXTRACT); if (password) RARSetPassword(rarFile, password); while ((RHCode = RARReadHeaderEx(rarFile, &header)) == 0) { #ifdef wxUSE_UNICODE if (page.IsSameAs(wxString(header.FileNameW))) { #else // ASCII if (page.IsSameAs(header.FileName)) { #endif length = header.UnpSize; break; } else { if ((PFCode = RARProcessFile(rarFile, RAR_SKIP, NULL, NULL)) != 0) { closeRar(rarFile, &flags); throw ArchiveException(filename, ProcessFileError(PFCode, page)); } } } if (length == 0) { // archived file not found closeRar(rarFile, &flags); throw new ArchiveException(filename, page + wxT(" not found in this archive.")); } if (RHCode) { closeRar(rarFile, &flags); throw new ArchiveException(filename, OpenArchiveError(PFCode)); } wxUint8 *buffer = new wxUint8[length]; wxUint8 *callBackBuffer = buffer; RARSetCallback(rarFile, CallbackProc, (long) &callBackBuffer); PFCode = RARProcessFile(rarFile, RAR_TEST, NULL, NULL); closeRar(rarFile, &flags); if (PFCode != 0) throw new ArchiveException(filename, ProcessFileError(PFCode, page)); return new wxMemoryInputStream(buffer, length); } bool ComicBookRAR::TestPassword() { HANDLE rarFile; int RHCode = 0, PFCode = 0; struct RARHeaderDataEx header; struct RAROpenArchiveDataEx flags; bool passwordCorrect = true; wxString page = Filenames->Item(0); // test using the first page rarFile = openRar(&flags, &header, RAR_OM_EXTRACT); if (password) RARSetPassword(rarFile, password); while ((RHCode = RARReadHeaderEx(rarFile, &header)) == 0) { #ifdef wxUSE_UNICODE if (page.IsSameAs(wxString(header.FileNameW))) { #else // ASCII if (page.IsSameAs(header.FileName)) { #endif break; } else { if ((PFCode = RARProcessFile(rarFile, RAR_SKIP, NULL, NULL)) != 0) { closeRar(rarFile, &flags); throw ArchiveException(filename, ProcessFileError(PFCode, page)); } } } if (RHCode != 0) { closeRar(rarFile, &flags); throw new ArchiveException(filename, OpenArchiveError(RHCode)); } RARSetCallback(rarFile, TestPasswordCallbackProc, (long) &passwordCorrect); PFCode = RARProcessFile(rarFile, RAR_TEST, NULL, NULL); closeRar(rarFile, &flags); // If the password is wrong, RARProcessFile will return ERAR_BAD_DATA. Of // course, it will also return ERAR_BAD_DATA when the first file in the archive // is corrupted. How does one tell the difference? if (PFCode == ERAR_BAD_DATA) return false; return passwordCorrect; } wxString ComicBookRAR::OpenArchiveError(int Error) { wxString prefix = wxT("Could not open ") + filename; switch(Error) { case ERAR_NO_MEMORY: return wxString(prefix + wxT(": out of memory")); case ERAR_EOPEN: return prefix; case ERAR_BAD_ARCHIVE: return wxString(prefix + wxT(": it is not a valid RAR archive")); case ERAR_BAD_DATA: return wxString(prefix + wxT(": archive header broken")); case ERAR_UNKNOWN: return wxString(prefix + wxT(": unknown error")); default: return prefix; } }
void extract(const std::string & archive_name, const std::string & dest_dir, const std::string & password) { bool already_extracted; #ifdef WINDOWS already_extracted = contains(extracted_files, archive_name, false); #else already_extracted = contains(extracted_files, archive_name, true); #endif if (already_extracted) return; fprintf(stdout, "Extracting %s to %s\n", archive_name.c_str(), dest_dir.c_str()); HANDLE archive; struct RAROpenArchiveData data; struct RARHeaderData header; if (!fileExists(archive_name)) return; if (!createDir(dest_dir)) return; data.ArcName = (char *)archive_name.c_str(); data.OpenMode = RAR_OM_EXTRACT; data.CmtBuf = NULL; data.CmtBufSize = 0; //fprintf(stdout, "Opening %s\n", argv[1]); archive = RAROpenArchive(&data); if (!archive || data.OpenResult != 0) { fprintf(stderr, "Couldn't open %s\n", archive_name.c_str()); return; } header.CmtBuf = NULL; //fprintf(stdout, "Clearing password\n"); RARSetPassword(archive, (char*)password.c_str()); MultipartInfo info; //fprintf(stdout, "Setting callback\n"); RARSetCallback(archive, &missing_file, (ssize_t)&info); //fprintf(stdout, "Starting to process file\n"); // the complete path to the file to be extracted std::string dest_path; start_timer(); while (!RARReadHeader(archive, &header)) { dest_path = dest_dir + PATH_SEP + header.FileName; if (pathExists(dest_path)) { fprintf(stderr, "Skpping %s\n", header.FileName); continue; } if (RARProcessFile(archive, RAR_EXTRACT, (char *)dest_dir.c_str(), NULL)) { /*if (!pathExists(dest_path)) { fprintf(stderr, "Couldn't create %s\n", dest_path.c_str()); break; }*/ if (elapsed(five_seconds)) { info.bytes_processed = 0; start_timer(); } } else { break; } // (bytes / (1024 * 1024) = MBytes // ms / 1000 = s // (bytes / (1024 * 1024) / (ms / 1000) = 0.00095367431640625 * bytes/ms //fprintf(stdout, "%d MB/s", (int)(0.00095367431640625 * (info.bytes_processed / calc_elapsed()))); } //fprintf(stdout, "Closing file\n"); RARCloseArchive(archive); extracted_files.push_back(archive_name); }