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; }
HANDLE ComicBookRAR::openRar(RAROpenArchiveDataEx *flags, RARHeaderDataEx *header, wxUint8 mode) { HANDLE rarFile; memset(flags, 0, sizeof(*flags)); #ifdef wxUSE_UNICODE #ifdef __WXOSX__ const char *filenameData = filename.fn_str().data(); flags->ArcName = new char[strlen(filenameData) + 1]; strcpy(flags->ArcName, filenameData); #else flags->ArcNameW = new wchar_t[filename.Length() + 1]; wcscpy(flags->ArcNameW, filename.c_str()); #endif #else // ASCII flags->ArcName = new char[filename.Length() + 1]; strcpy(flags->ArcName, filename.c_str()); #endif flags->CmtBuf = NULL; flags->OpenMode = mode; rarFile = RAROpenArchiveEx(flags); if (flags->OpenResult != 0) { closeRar(rarFile, flags); throw ArchiveException(filename, OpenArchiveError(flags->OpenResult)); } header->CmtBuf = NULL; return rarFile; }
} HANDLE ImgBookRAR::openRar(string file, RAROpenArchiveDataEx *flags, RARHeaderDataEx *header, int mode) { HANDLE rarFile; memset(flags, 0, sizeof(*flags)); flags->ArcName = new char[file.length() + 1]; strcpy(flags->ArcName, file.c_str()); flags->CmtBuf = NULL; flags->OpenMode = mode; rarFile = RAROpenArchiveEx(flags); if (flags->OpenResult != 0) { closeRar(rarFile, flags); string aux = openArchiveError(flags->OpenResult); PV_LOGPRINTF("%s", aux.c_str()); return NULL; // throw ArchiveException(filename, OpenArchiveError(flags->OpenResult)); } header->CmtBuf = NULL;
HANDLE ComicBookRAR::openRar(RAROpenArchiveDataEx *flags, RARHeaderDataEx *header, wxUint8 mode) { HANDLE rarFile; memset(flags, 0, sizeof(*flags)); flags->ArcNameW = const_cast<wchar_t*>(filename.wc_str()); flags->CmtBuf = NULL; flags->OpenMode = mode; rarFile = RAROpenArchiveEx(flags); if (flags->OpenResult != 0) { closeRar(rarFile, flags); throw ArchiveException(filename, OpenArchiveError(flags->OpenResult)); } header->CmtBuf = NULL; return rarFile; }
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; } }
ImgBookRAR::ImgBookRAR(string file) : ImgBook(file) { HANDLE rarFile; int RHCode = 0, PFCode = 0; struct RARHeaderDataEx header; struct RAROpenArchiveDataEx flags; string page, new_password; PV_LOGPRINTF("full Name %s", file.c_str()); string nom = getFileName(file); PV_LOGPRINTF("fileName %s", nom.c_str()); string nouNom; nouNom.assign(file); nouNom.append("/"); nouNom.append(nom); if (existFile(nouNom) == true) file.assign(nouNom); PV_LOGPRINTF("file name prepared %s", nouNom.c_str()); PV_LOGPRINTF("full Name %s", file.c_str()); filename = file; open_rar: rarFile = openRar(file, &flags, &header, RAR_OM_LIST); if (rarFile == NULL) { PV_LOGPRINTF("error open RarFile"); return; } PV_LOGPRINTF("rarFile opened"); if (flags.Flags & 0x0080) { // if the headers are encrypted PV_LOGPRINTF("rarFile encrypted"); return; } PV_LOGPRINTF("reading file name"); while ((RHCode = RARReadHeaderEx(rarFile, &header)) == 0) { PV_LOGPRINTF("while"); page = string(header.FileName); if (testFile (page) == TRUE) { PV_LOGPRINTF("imageAdded %s", header.FileName); imagenes->addEnd(page); } if ((PFCode = RARProcessFile(rarFile, RAR_SKIP, NULL, NULL)) != 0) { closeRar(rarFile, &flags); perror("error al abrir fichero\n"); return; } } PV_LOGPRINTF("close rar"); closeRar(rarFile, &flags); PV_LOGPRINTF("rar closed"); // Wrong return code + needs password = wrong password given if (RHCode != ERAR_END_ARCHIVE && flags.Flags & 0x0080) goto open_rar; currentPage = 1; PV_LOGPRINTF("currentPage %d", currentPage); pageCount = imagenes->getCount();
//Img *ImgBookRAR::ExtractStream(int pageindex, int aWidth, int aHeight) GrPixbuf *ImgBookRAR::ExtractStream(int pageindex, int aWidth, int aHeight) { HANDLE rarFile; int RHCode = 0, PFCode = 0; struct RARHeaderDataEx header; struct RAROpenArchiveDataEx flags; imagenes->setPos(pageindex); string page = imagenes->get(); size_t length = 0; rarFile = openRar(filename, &flags, &header, RAR_OM_EXTRACT); while ((RHCode = RARReadHeaderEx(rarFile, &header)) == 0) { if (page.compare(header.FileName) == 0) { length = header.UnpSize; break; } else { if ((PFCode = RARProcessFile(rarFile, RAR_SKIP, NULL, NULL)) != 0) { closeRar(rarFile, &flags); string msg = ProcessFileError(PFCode, page); return NULL; } } } if (length == 0) { // archived file not found closeRar(rarFile, &flags); return NULL; } if (RHCode) { closeRar(rarFile, &flags); return NULL; } unsigned char *buffer; unsigned char *callBackBuffer; buffer = new unsigned char[length]; callBackBuffer = buffer; RARSetCallback(rarFile, CallbackProc, (long) &callBackBuffer); PFCode = RARProcessFile(rarFile, RAR_TEST, NULL, NULL); closeRar(rarFile, &flags); if (PFCode != 0) { return NULL; } // Img *pageImg = getPixbuf((const guchar*)buffer, length, page); GrPixbuf *pageImg = getPixbuf((const guchar*)buffer, length, page, aWidth, aHeight); delete[] buffer;