From 53906a450c1ee072534d08f90ab445c016ed2735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Thu, 12 Dec 2013 01:06:43 -0800 Subject: [PATCH] Fixed rar support in Unix systems (Rar29.so) --- compressed_archive/7z_includes.h | 2 + compressed_archive/compressed_archive.cpp | 120 ++++++++++++++++++++-- compressed_archive/compressed_archive.h | 28 ++++- compressed_archive/wrapper.pri | 5 +- 4 files changed, 145 insertions(+), 10 deletions(-) diff --git a/compressed_archive/7z_includes.h b/compressed_archive/7z_includes.h index bf357344..d80e8dc1 100644 --- a/compressed_archive/7z_includes.h +++ b/compressed_archive/7z_includes.h @@ -54,6 +54,8 @@ extern "C" #include "libp7zip/CPP/7zip/Common/StreamObjects.h" #include "libp7zip/CPP/7zip/Common/StreamUtils.h" +#include "libp7zip/CPP/7zip/ICoder.h" + extern "C" { #include "libp7zip/C/Alloc.h" diff --git a/compressed_archive/compressed_archive.cpp b/compressed_archive/compressed_archive.cpp index 7a5ae860..e4f1efac 100644 --- a/compressed_archive/compressed_archive.cpp +++ b/compressed_archive/compressed_archive.cpp @@ -34,10 +34,20 @@ DEFINE_GUID(CLSID_CFormatSplit, 0x23170f69, 0x40c1, 0x278a, 0x10, 0x00, 0x00, DEFINE_GUID(CLSID_CFormatWim, 0x23170f69, 0x40c1, 0x278a, 0x10, 0x00, 0x00, 0x01, 0x10, 0xe6, 0x00, 0x00); DEFINE_GUID(CLSID_CFormatZ, 0x23170f69, 0x40c1, 0x278a, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00); +#ifdef Q_OS_WIN GUID _supportedFileFormats[] = {CLSID_CFormatRar,CLSID_CFormatZip,CLSID_CFormatTar,CLSID_CFormat7z,CLSID_CFormatArj}; +#else +GUID _supportedFileFormats[] = {CLSID_CFormatZip,CLSID_CFormatTar,CLSID_CFormat7z,CLSID_CFormatArj}; +#endif std::vector supportedFileFormats (_supportedFileFormats, _supportedFileFormats + sizeof(_supportedFileFormats) / sizeof(_supportedFileFormats[0]) ); -DEFINE_GUID(IID_InArchive, 0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x06, 0x00, 0x60, 0x00, 0x00); +DEFINE_GUID(IID_InArchive, 0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x06, 0x00, 0x60, 0x00, 0x00); +DEFINE_GUID(IID_ISetCompressCodecsInfo, 0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00, 0x00); + +DEFINE_GUID(IID_IOutStream, 0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00); +DEFINE_GUID(IID_IInStream, 0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00); +DEFINE_GUID(IID_IStreamGetSize, 0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00); +DEFINE_GUID(IID_ISequentialInStream, 0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00); struct SevenZipInterface { CreateObjectFunc createObjectFunc; @@ -48,6 +58,12 @@ struct SevenZipInterface { GetHandlerPropertyFunc2 getHandlerPropertyFunc2; SetLargePageModeFunc setLargePageModeFunc; +#ifdef Q_OS_UNIX + CreateObjectFunc createObjectFuncRar; + GetMethodPropertyFunc getMethodPropertyFuncRar; + GetNumberOfMethodsFunc getNumberOfMethodsFuncRar; +#endif + CMyComPtr archive; //--- @@ -99,15 +115,57 @@ CompressedArchive::CompressedArchive(const QString & filePath, QObject *parent) } } if(!formatFound) + { +#ifdef Q_OS_WIN qDebug() << "Can not open archive" << endl; +#else + if (szInterface->createObjectFunc(&CLSID_CFormatRar, &IID_InArchive, (void **)&szInterface->archive) != S_OK) + { + qDebug() << "Error creating rar archive :" + filePath; + return; + } + + CMyComPtr codecsInfo; + if (szInterface->archive->QueryInterface(IID_ISetCompressCodecsInfo,(void **)&codecsInfo) != S_OK) + { + qDebug() << "Error getting rar codec :" + filePath; + return; + } + + if (codecsInfo->SetCompressCodecsInfo(this) != S_OK) + { + qDebug() << "Error setting rar codec"; + return; + } + + if (!fileSpec->Open((LPCTSTR)filePath.toStdWString().data())) + { + qDebug() << "Error opening rar file :" + filePath; + return; + } + //qDebug() << "Can not open archive file : " + filePath << endl; + + if (szInterface->archive->Open(file, 0, openCallback) == S_OK) + { + valid = formatFound = true; + } + else + qDebug() << "Error opening rar archive"; + + +#endif + } } } CompressedArchive::~CompressedArchive() { //szInterface->fileSpec->Release(); - delete szInterface; - delete sevenzLib; + delete szInterface; +#ifdef Q_OS_UNIX + delete rarLib; +#endif + delete sevenzLib; } bool CompressedArchive::loadFunctions() @@ -117,11 +175,22 @@ bool CompressedArchive::loadFunctions() // fix1: try to load "7z.so" // fix2: rename 7z.so to 7z.dylib if(sevenzLib == 0) + { +#ifdef Q_OS_UNIX + rarLib = new QLibrary(QApplication::applicationDirPath()+"/utils/Codecs/Rar29"); + if(!rarLib->load()) + { + qDebug() << "Error Loading Rar29.so : " + rarLib->errorString() << endl; + QApplication::exit(YACReader::SevenZNotFound); + return false; + } +#endif sevenzLib = new QLibrary(QApplication::applicationDirPath()+"/utils/7z"); + } if(!sevenzLib->load()) { - qDebug() << "Loading 7z.dll : " + sevenzLib->errorString() << endl; - QApplication::exit(YACReader::SevenZNotFound); //TODO app still crashing + qDebug() << "Error Loading 7z.dll : " + sevenzLib->errorString() << endl; + QApplication::exit(YACReader::SevenZNotFound); return false; } else @@ -142,6 +211,15 @@ bool CompressedArchive::loadFunctions() qDebug() << "fail loading function : GetHandlerProperty2" << endl; if((szInterface->setLargePageModeFunc = (SetLargePageModeFunc)sevenzLib->resolve("SetLargePageMode")) == 0) qDebug() << "fail loading function : SetLargePageMode" << endl; + +#ifdef Q_OS_UNIX + if((szInterface->createObjectFuncRar = (CreateObjectFunc)rarLib->resolve("CreateObject")) == 0) + qDebug() << "fail loading function (rar) : CreateObject" << endl; + if((szInterface->getMethodPropertyFuncRar = (GetMethodPropertyFunc)rarLib->resolve("GetMethodProperty")) == 0) + qDebug() << "fail loading function (rar) : GetMethodProperty" << endl; + if((szInterface->getNumberOfMethodsFuncRar = (GetNumberOfMethodsFunc)rarLib->resolve("GetNumberOfMethods")) == 0) + qDebug() << "fail loading function (rar) : GetNumberOfMethods" << endl; +#endif } return true; @@ -191,6 +269,7 @@ int CompressedArchive::getNumFiles() szInterface->archive->GetNumberOfItems(&numItems); return numItems; } + QList CompressedArchive::getAllData(const QVector & indexes, ExtractDelegate * delegate) { CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback(true,delegate); @@ -230,5 +309,34 @@ QByteArray CompressedArchive::getRawDataAtIndex(int index) return QByteArray((char *)extractCallbackSpec->data,extractCallbackSpec->newFileSize); } - return QByteArray(); + return QByteArray(); } + +#ifdef Q_OS_UNIX + +STDMETHODIMP CompressedArchive::GetNumberOfMethods(UInt32 *numMethods) +{ + return szInterface->getNumberOfMethodsFuncRar(numMethods); +} + +STDMETHODIMP CompressedArchive::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + return szInterface->getMethodPropertyFuncRar(index,propID,value); +} + +int i = 0; +STDMETHODIMP CompressedArchive::CreateDecoder(UInt32 index, const GUID *interfaceID, void **coder) +{ + NCOM::CPropVariant propVariant; + szInterface->getMethodPropertyFuncRar(index,NMethodPropID::kDecoder,&propVariant); + return szInterface->createObjectFuncRar((const GUID *)propVariant.bstrVal,interfaceID,coder); +} + +STDMETHODIMP CompressedArchive::CreateEncoder(UInt32 index, const GUID *interfaceID, void **coder) +{ + return szInterface->createObjectFuncRar(&CLSID_CFormatRar,interfaceID,coder); +} + +#endif + + diff --git a/compressed_archive/compressed_archive.h b/compressed_archive/compressed_archive.h index 29ccf1c0..bbc4f1df 100644 --- a/compressed_archive/compressed_archive.h +++ b/compressed_archive/compressed_archive.h @@ -3,6 +3,11 @@ #include +#ifdef Q_OS_UNIX + #include "libp7zip/CPP/7zip/ICoder.h" + #include "libp7zip/CPP/Common/MyCom.h" +#endif + class ExtractDelegate; #ifdef Q_OS_WIN @@ -26,13 +31,28 @@ class QLibrary; struct SevenZipInterface; -class CompressedArchive : public QObject +class MyCodecs; + +#ifdef Q_OS_UNIX + class CompressedArchive : public QObject, public ICompressCodecsInfo, public CMyUnknownImp +#else + class CompressedArchive : public QObject +#endif { Q_OBJECT public: explicit CompressedArchive(const QString & filePath, QObject *parent = 0); ~CompressedArchive(); - + +#ifdef Q_OS_UNIX + MY_UNKNOWN_IMP + + STDMETHOD(GetNumberOfMethods)(UInt32 *numMethods); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(CreateDecoder)(UInt32 index, const GUID *iid, void **coder); + STDMETHOD(CreateEncoder)(UInt32 index, const GUID *iid, void **coder); +#endif + signals: public slots: @@ -45,10 +65,14 @@ public slots: private: SevenZipInterface * szInterface; QLibrary * sevenzLib; +#ifdef Q_OS_UNIX + QLibrary * rarLib; +#endif bool loadFunctions(); bool tools; bool valid; + friend class MyCodecs; }; #endif // COMPRESSED_ARCHIVE_H diff --git a/compressed_archive/wrapper.pri b/compressed_archive/wrapper.pri index 58b71a5a..97ba4b8d 100644 --- a/compressed_archive/wrapper.pri +++ b/compressed_archive/wrapper.pri @@ -102,8 +102,9 @@ HEADERS += $$PWD/compressed_archive.h \ $$PWD/libp7zip/CPP/7zip/Common/StreamUtils.h \ $$PWD/libp7zip/C/Alloc.h \ $$PWD/libp7zip/CPP/7zip/Common/StreamObjects.h \ - $$PWD/libp7zip/CPP/Common/MyWindows.h + $$PWD/libp7zip/CPP/Common/MyWindows.h \ + $$PWD/libp7zip/CPP/7zip/ICoder.h \ } - \ No newline at end of file +