Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
	}
}