X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fplugin%2FrarArc%2FrarArc.cpp;h=aa1f846f167190eaf9aa7bb818162b42aabf4a03;hb=7d691df6f4265eefceab0ccd7f6f1006d50cabde;hp=f9157f102c3fd46d817592072e97cd9900638c3f;hpb=0e3cff3c673e28ba66e84c69d54eea5717c87d65;p=tpi%2Flychee.git diff --git a/src/plugin/rarArc/rarArc.cpp b/src/plugin/rarArc/rarArc.cpp index f9157f1..aa1f846 100644 --- a/src/plugin/rarArc/rarArc.cpp +++ b/src/plugin/rarArc/rarArc.cpp @@ -36,62 +36,66 @@ wxDynamicLibrary g_hLib; TPI_PROC g_prProc; -TPI_SWITCHES * g_swInfo; -const wxArrayString * g_asFiles; char g_szComment[64001]; RAROpenArchiveDataEx g_oaInfo; -RARHeaderDataEx * g_hdInfo; //****************************************************************************** // Callback Wrapper //****************************************************************************** -int __stdcall CallbackProc(unsigned int msg, long, long P1, long P2) +int __stdcall CallbackProc(unsigned int msg, long p, long P1, long P2) { - // \‘¢‘Ì‚ð‰Šú‰»B - static TPI_PROCESSINFO piInfo; + // 構造体を初期化。 + static TPI_PROCESSINFO pi; + TPI_PROCESSINFO * piInfo = p == 0 ? & pi : (TPI_PROCESSINFO *) p; switch (msg) { case UCM_CHANGEVOLUME: + case UCM_CHANGEVOLUMEW: switch (P2) { case RAR_VOL_ASK: - // •ªŠ„‘ŒÉ‚ÌŽŸ‚Ì•”•ª‚ð—v‹B - piInfo.uMessage = TPI_MESSAGE_ASK; - piInfo.uStatus = TPI_PARAM_NEXTVOLUME; - piInfo.szParam = wxEmptyString; + // 分割書庫の次の部分を要求。 + piInfo->eMessage = TPI_MESSAGE_ASK; + piInfo->eStatus = TPI_PARAM_NEXTVOLUME; + piInfo->szParam.Empty(); break; case RAR_VOL_NOTIFY: - // •ªŠ„•”•ª‚̓ǂݍž‚Ý‚ðŠJŽnB - piInfo.uMessage = TPI_MESSAGE_STATUS; - piInfo.uStatus = TPI_STATUS_OPENARCHIVE; - piInfo.fiInfo.fnFileName = wxFileName(UTF82String((char *) P1)); + // 分割部分の読み込みを開始。 + piInfo->eMessage = TPI_MESSAGE_STATUS; + piInfo->eStatus = TPI_STATUS_OPENARCHIVE; + piInfo->fiInfo.fnFileName = wxFileName(msg == UCM_CHANGEVOLUMEW ? WC2String((wchar_t *) P1) : UTF82String((char *) P1)); break; default: - return 1; + return 0; } break; case UCM_PROCESSDATA: - piInfo.uMessage = TPI_MESSAGE_STATUS; - piInfo.uStatus = TPI_STATUS_INPROCESS; - piInfo.llProcessedSize += P2; + piInfo->eMessage = TPI_MESSAGE_STATUS; + piInfo->eStatus = TPI_STATUS_INPROCESS; + piInfo->nProcessedSize += P2; break; case UCM_NEEDPASSWORD: - piInfo.uMessage = TPI_MESSAGE_ASK; - piInfo.uStatus = TPI_PARAM_PASSWORD; - piInfo.szParam = wxEmptyString; + case UCM_NEEDPASSWORDW: + piInfo->eMessage = TPI_MESSAGE_ASK; + piInfo->eStatus = TPI_PARAM_PASSWORD; + piInfo->szParam.Empty(); break; default: - return 1; + return 0; } - // ƒR[ƒ‹ƒoƒbƒNŠÖ”‚É‘—MB - if (g_prProc == NULL || g_prProc(TPI_NOTIFY_COMMON, & piInfo) == TPI_CALLBACK_CONTINUE) + // コールバック関数に送信。 + if (g_prProc == NULL || g_prProc(TPI_NOTIFY_COMMON, piInfo) == TPI_CALLBACK_CONTINUE) { - if (msg != UCM_PROCESSDATA && P2 != RAR_VOL_NOTIFY) + if (msg == UCM_NEEDPASSWORDW || (msg == UCM_CHANGEVOLUMEW && P2 == RAR_VOL_ASK)) + { + wcsncpy((wchar_t *) P1, piInfo->szParam.wchar_str(), (msg == UCM_CHANGEVOLUMEW ? 1024 : P2) - 1); + } + if (msg == UCM_NEEDPASSWORD || (msg == UCM_CHANGEVOLUME && P2 == RAR_VOL_ASK)) { - strncpy((char *) P1, piInfo.szParam.char_str(), (msg == UCM_CHANGEVOLUME ? 1024 : P2) - 1); + strncpy((char *) P1, piInfo->szParam.char_str(), (msg == UCM_CHANGEVOLUME ? 1024 : P2) - 1); } return 1; } @@ -105,7 +109,7 @@ int __stdcall CallbackProc(unsigned int msg, long, long P1, long P2) // Inside Functions //****************************************************************************** -int nErrorCodeConvert(int nErrorCode) +int ErrorCodeConvert(int nErrorCode) { switch (nErrorCode) { @@ -124,6 +128,8 @@ int nErrorCodeConvert(int nErrorCode) case ERAR_SMALL_BUF: return TPI_ERROR_UNDEFINED; case ERAR_UNKNOWN: return TPI_ERROR_UNDEFINED; case ERAR_MISSING_PASSWORD: return TPI_ERROR_ARC_ENCRYPTED; + case ERAR_EREFERENCE: return TPI_ERROR_UNDEFINED; + case ERAR_BAD_PASSWORD: return TPI_ERROR_ARC_ENCRYPTED; default: return TPI_ERROR_UNDEFINED; } } @@ -140,7 +146,7 @@ extern "C" int __stdcall GetPluginInformation ( unsigned int _uInfoId, - wxULongLong, + wxULongLong_t, void * _pPtr ) { @@ -157,6 +163,9 @@ int __stdcall GetPluginInformation case TPI_INFO_VERSION_API: * (int *) _pPtr = 2; break; + case TPI_INFO_HANDLE_ON_COMMAND: + * (int *) _pPtr = 0; + break; default: return TPI_ERROR_D_UNSUPPORTED; } @@ -171,11 +180,12 @@ int __stdcall GetFormatInformation(TPI_FORMATINFO * _fiInfo, bool _bFirst) } _fiInfo->szTypeName = wxT("RAR"); - _fiInfo->szSuffix = wxT(".rar"); + _fiInfo->szSuffix = wxT("rar"); _fiInfo->szEngineName = g_hLib.CanonicalizeName(wxT("unrar")); _fiInfo->szTPIName = wxT("rarArc"); - _fiInfo->llTypeId = 0; - _fiInfo->llSupportedCommand = TPI_COMMAND_EXTRACT | TPI_COMMAND_TEST; + _fiInfo->nTypeId = 0; + _fiInfo->eSupportedCommand = TPI_COMMAND_EXTRACT | TPI_COMMAND_TEST; + _fiInfo->fArchive = true; _fiInfo->fComment = true; _fiInfo->fSFX = true; _fiInfo->fSolid = true; @@ -187,17 +197,24 @@ int __stdcall GetFormatInformation(TPI_FORMATINFO * _fiInfo, bool _bFirst) int __stdcall LoadPlugin ( - const wxString & _szArcName, - wxULongLong + const wxString &, + TPI_PROC _prProc, + wxULongLong_t ) { - g_hLib.Load(g_hLib.CanonicalizeName(wxT("unrar"))); - if (! g_hLib.IsLoaded() || CheckArchive(_szArcName, NULL) != TPI_ERROR_SUCCESS) + ::RemoveCwdFromSearchPath(); + g_hLib.Load(g_hLib.CanonicalizeName(wxT("unrar")), wxDL_QUIET); + if (! g_hLib.IsLoaded()) { g_hLib.Unload(); return TPI_ERROR_U_LOAD_LIBRARY; } + // コールバック関数を設定。 + if (_prProc != NULL) + { + g_prProc = * _prProc; + } return TPI_ERROR_SUCCESS; } @@ -210,31 +227,11 @@ int __stdcall FreePlugin return TPI_ERROR_SUCCESS; } -int __stdcall CheckArchive -( - const wxString & _szArcName, - int * _nFileCount -) -{ - void * _hArchive; - int nErrorCode = OpenArchive(_szArcName, & _hArchive); - if (nErrorCode != TPI_ERROR_SUCCESS) - { - return nErrorCode; - } - - if (_nFileCount != NULL) - { - * _nFileCount = 1; - } - - return CloseArchive(_hArchive); -} - int __stdcall OpenArchive ( const wxString & _szArcName, - void * * _hArchive + void * * _hArchive, + wxULongLong_t * ) { if (! g_hLib.HasSymbol(wxT("RAROpenArchiveEx"))) @@ -247,39 +244,18 @@ int __stdcall OpenArchive return TPI_ERROR_U_USE_LIBRARY; } - // TODO : •¶Žš”§ŒÀ“P”pB - wchar_t sz[2048]; - wcsncpy(sz, _szArcName.wchar_str(), 2047); memset(& g_oaInfo, 0, sizeof(g_oaInfo)); g_oaInfo.ArcName = NULL; - g_oaInfo.ArcNameW = sz; - g_oaInfo.OpenMode = RAR_OM_EXTRACT; +// g_oaInfo.ArcNameW = _szArcName.wchar_str(); + g_oaInfo.ArcNameW = (wchar_t *) malloc((_szArcName.Len() + 1) * sizeof(wchar_t)); + wcscpy(g_oaInfo.ArcNameW, _szArcName.wchar_str()); + g_oaInfo.OpenMode = RAR_OM_LIST; g_oaInfo.CmtBuf = g_szComment; g_oaInfo.CmtBufSize = sizeof(g_szComment) - 1; + g_oaInfo.Callback = CallbackProc; * _hArchive = ((void * (__stdcall *)(RAROpenArchiveDataEx *)) p)(& g_oaInfo); - if (* _hArchive == NULL) - { - return TPI_ERROR_UNDEFINED; - } - int nErrorCode = nErrorCodeConvert(g_oaInfo.OpenResult); - if (nErrorCode != TPI_ERROR_SUCCESS) - { - return nErrorCode; - } - - // ƒR[ƒ‹ƒoƒbƒNŠÖ”‚ðÝ’èB - if (! g_hLib.HasSymbol(wxT("RARSetCallback"))) - { - return TPI_ERROR_U_USE_LIBRARY; - } - p = g_hLib.GetSymbol(wxT("RARSetCallback")); - if (! p) - { - return TPI_ERROR_U_USE_LIBRARY; - } - ((void (__stdcall *)(void *, void *, long)) p)(* _hArchive, (void *) CallbackProc, (long) & g_hdInfo); - - return TPI_ERROR_SUCCESS; + free(g_oaInfo.ArcNameW); + return * _hArchive == NULL ? TPI_ERROR_UNDEFINED : ErrorCodeConvert(g_oaInfo.OpenResult); } int __stdcall CloseArchive @@ -292,7 +268,7 @@ int __stdcall CloseArchive return TPI_ERROR_U_USE_LIBRARY; } void * p = g_hLib.GetSymbol(wxT("RARCloseArchive")); - return (! p || _hArchive == NULL) ? TPI_ERROR_U_USE_LIBRARY : nErrorCodeConvert(((int (__stdcall *)(void *)) p)(_hArchive)); + return (! p || _hArchive == NULL) ? TPI_ERROR_U_USE_LIBRARY : ErrorCodeConvert(((int (__stdcall *)(void *)) p)(_hArchive)); } int __stdcall GetFileInformation @@ -302,15 +278,15 @@ int __stdcall GetFileInformation bool _bFirst ) { - static unsigned int s_uFileID; + static wxULongLong_t s_nFileId; static void * pR, * pP; int nErrorCode; if (_bFirst) { - s_uFileID = 0; + s_nFileId = 0; pR = g_hLib.HasSymbol(wxT("RARReadHeaderEx")) ? g_hLib.GetSymbol(wxT("RARReadHeaderEx")) : NULL; - pP = g_hLib.HasSymbol(wxT("RARProcessFileW")) ? g_hLib.GetSymbol(wxT("RARProcessFileW")) : NULL; + pP = g_hLib.HasSymbol(wxT("RARProcessFileW")) ? g_hLib.GetSymbol(wxT("RARProcessFileW")) : NULL; if (! pR || ! pP) { return TPI_ERROR_U_USE_LIBRARY; @@ -318,26 +294,41 @@ int __stdcall GetFileInformation } RARHeaderDataEx hdInfo; - nErrorCode = nErrorCodeConvert(((int (__stdcall *)(void *, RARHeaderDataEx *)) pR)(_hArchive, & hdInfo)); + char szComment[64001]; + hdInfo.CmtBuf = szComment; + hdInfo.CmtBufSize = sizeof(szComment) - 1; + nErrorCode = ErrorCodeConvert(((int (__stdcall *)(void *, RARHeaderDataEx *)) pR)(_hArchive, & hdInfo)); if (nErrorCode == TPI_ERROR_SUCCESS) { - _fiInfo->dwAttribute = hdInfo.FileAttr; + if (hdInfo.HostOS == 3) + { + _fiInfo->wPermission = hdInfo.FileAttr; + } + else + { + _fiInfo->dwAttribute = hdInfo.FileAttr; + } + if (hdInfo.Flags & 0x04) + { + _fiInfo->dwAttribute |= TPI_ATTRIBUTE_ENCRYPTED; + } _fiInfo->dwCRC32 = hdInfo.FileCRC; - _fiInfo->llPackedSize = wxLongLong(hdInfo.PackSizeHigh, hdInfo.PackSize); - _fiInfo->llUnpackedSize = wxLongLong(hdInfo.UnpSizeHigh, hdInfo.UnpSize); - _fiInfo->tmModified.SetFromDOS(hdInfo.FileTime); - _fiInfo->uOSType = hdInfo.HostOS; + _fiInfo->nPackedSize = hdInfo.PackSizeHigh; + _fiInfo->nPackedSize = _fiInfo->nPackedSize << 32; + _fiInfo->nPackedSize += hdInfo.PackSize; + _fiInfo->nUnpackedSize = hdInfo.UnpSizeHigh; + _fiInfo->nUnpackedSize = _fiInfo->nUnpackedSize << 32; + _fiInfo->nUnpackedSize += hdInfo.UnpSize; + _fiInfo->tmModify.SetFromDOS(hdInfo.FileTime); + _fiInfo->eOSType = hdInfo.HostOS; _fiInfo->szStoredName = WC2String(hdInfo.FileNameW); -// _fiInfo->szMethod = hdInfo.Method; - _fiInfo->llFileID = s_uFileID++; + _fiInfo->szMethod.Printf(wxT("%x"), hdInfo.Method); + _fiInfo->szComment = UTF82String(hdInfo.CmtBuf); + _fiInfo->nFileId = s_nFileId++; _fiInfo->fnFileName = wxFileName(_fiInfo->szStoredName); - // ŽŸ‚̃tƒ@ƒCƒ‹‚ցB - nErrorCode = nErrorCodeConvert(((int (__stdcall *)(void *, int, wchar_t *, wchar_t *)) pP)(_hArchive, RAR_SKIP, NULL, NULL)); - if (nErrorCode != TPI_ERROR_SUCCESS) - { - return nErrorCode; - } + // 次のファイルへ。 + nErrorCode = ErrorCodeConvert(((int (__stdcall *)(void *, int, wchar_t *, wchar_t *)) pP)(_hArchive, RAR_SKIP, NULL, NULL)); } return nErrorCode; @@ -358,20 +349,53 @@ int __stdcall GetArchiveInformation int __stdcall Command ( - unsigned int _uCommand, + wxULongLong_t _eCommand, TPI_SWITCHES * _swInfo, - const wxString & _szArcName, + void *,// _hArchive, const wxArrayString & _szFiles ) { - if (_uCommand != TPI_COMMAND_EXTRACT && _uCommand != TPI_COMMAND_TEST) + if (_eCommand != TPI_COMMAND_EXTRACT && _eCommand != TPI_COMMAND_TEST) { return TPI_ERROR_U_USE_LIBRARY; } - // ŠJ‚«‚È‚¨‚·B - void * hArc; - int nErrorCode = OpenArchive(_szArcName, & hArc); + // 開きなおす。 + if (! g_hLib.HasSymbol(wxT("RAROpenArchiveEx"))) + { + return TPI_ERROR_U_USE_LIBRARY; + } + void * p = g_hLib.GetSymbol(wxT("RAROpenArchiveEx")); + if (! p) + { + return TPI_ERROR_U_USE_LIBRARY; + } + + TPI_PROCESSINFO piInfo; + piInfo.eMessage = TPI_MESSAGE_STATUS; + piInfo.eStatus = TPI_STATUS_OPENARCHIVE; + piInfo.fiInfo.fnFileName = wxFileName(_swInfo->szArcName); + if (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & piInfo) != TPI_CALLBACK_CONTINUE) + { + return TPI_ERROR_D_SKIPPED; + } + RAROpenArchiveDataEx oaInfo; + memset(& oaInfo, 0, sizeof(oaInfo)); + oaInfo.ArcName = NULL; +// oaInfo.ArcNameW = _swInfo->szArcName.wchar_str(); + oaInfo.ArcNameW = (wchar_t *) malloc((_swInfo->szArcName.Len() + 1) * sizeof(wchar_t)); + wcscpy(oaInfo.ArcNameW, _swInfo->szArcName.wchar_str()); + oaInfo.OpenMode = RAR_OM_EXTRACT; + oaInfo.CmtBufSize = 0; + oaInfo.Callback = CallbackProc; + oaInfo.UserData = (long) & piInfo; + void * hArc = ((void * (__stdcall *)(RAROpenArchiveDataEx *)) p)(& oaInfo); + free(oaInfo.ArcNameW); + if (hArc == NULL) + { + return TPI_ERROR_UNDEFINED; + } + int nErrorCode = ErrorCodeConvert(oaInfo.OpenResult); if (nErrorCode != TPI_ERROR_SUCCESS) { return nErrorCode; @@ -383,6 +407,7 @@ int __stdcall Command * pP = g_hLib.HasSymbol(wxT("RARProcessFileW")) ? g_hLib.GetSymbol(wxT("RARProcessFileW")) : NULL; if (! pR || ! pP) { + CloseArchive(hArc); return TPI_ERROR_U_USE_LIBRARY; } if (pS) @@ -391,38 +416,58 @@ int __stdcall Command } RARHeaderDataEx hdInfo; - g_hdInfo = & hdInfo; - while (nErrorCode == TPI_ERROR_SUCCESS && nErrorCodeConvert(((int (__stdcall *)(void *, RARHeaderDataEx *)) pR)(hArc, & hdInfo)) == TPI_ERROR_SUCCESS) + while (nErrorCode == TPI_ERROR_SUCCESS && ErrorCodeConvert(((int (__stdcall *)(void *, RARHeaderDataEx *)) pR)(hArc, & hdInfo)) == TPI_ERROR_SUCCESS) { - nErrorCode = - nErrorCodeConvert( - ((int (__stdcall *)(void *, int, wchar_t *, wchar_t *)) pP)( - hArc, - (_szFiles.GetCount() != 0 && _szFiles.Index(wxString(hdInfo.FileNameW)) == wxNOT_FOUND) ? RAR_SKIP : _uCommand == TPI_COMMAND_EXTRACT ? RAR_EXTRACT : RAR_TEST, - _swInfo->fStoreDirectoryPathes ? _swInfo->fnDestinationDirectory.GetFullPath().wchar_str() : NULL, - _swInfo->fStoreDirectoryPathes ? NULL : (_swInfo->fnDestinationDirectory.GetPathWithSep() + wxFileName(hdInfo.FileNameW).GetFullName()).wchar_str() - ) - ); + piInfo.fiInfo.fnFileName = wxFileName(WC2String(hdInfo.FileNameW)); + piInfo.fnDestination = wxFileName(_swInfo->fnDestinationDirectory.GetPathWithSep() + (_swInfo->fStoreDirectoryPathes ? piInfo.fiInfo.fnFileName.GetFullPath() : piInfo.fiInfo.fnFileName.GetFullName())); + bool bSkip = _szFiles.GetCount() != 0 && _szFiles.Index(piInfo.fiInfo.fnFileName.GetFullPath()) == wxNOT_FOUND; + if (! bSkip && _eCommand == TPI_COMMAND_EXTRACT) + { + // 処理するかどうか確認。 + piInfo.eMessage = TPI_MESSAGE_ASK; + piInfo.eStatus = TPI_PARAM_DEST; + piInfo.fiInfo.nUnpackedSize = hdInfo.UnpSizeHigh; + piInfo.fiInfo.nUnpackedSize = piInfo.fiInfo.nUnpackedSize << 32; + piInfo.fiInfo.nUnpackedSize += hdInfo.UnpSize; + piInfo.fiInfo.tmModify.SetFromDOS(hdInfo.FileTime); + if (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & piInfo) != TPI_CALLBACK_CONTINUE) + { + nErrorCode = TPI_ERROR_D_SKIPPED; + break; + } + bSkip = ! piInfo.fnDestination.IsOk(); + } + + if (! bSkip) + { + // 処理の開始を通知。 + piInfo.eMessage = TPI_MESSAGE_STATUS; + piInfo.eStatus = TPI_STATUS_BEGINPROCESS; + if (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & piInfo) != TPI_CALLBACK_CONTINUE) + { + nErrorCode = TPI_ERROR_D_SKIPPED; + break; + } + } + + nErrorCode = ErrorCodeConvert(((int (__stdcall *)(void *, int, wchar_t *, wchar_t *)) pP)(hArc, bSkip ? RAR_SKIP : _eCommand == TPI_COMMAND_EXTRACT ? RAR_EXTRACT : RAR_TEST, NULL, piInfo.fnDestination.GetFullPath().wchar_str())); + + if (! bSkip) + { + // 処理の終了を通知。 + piInfo.eMessage = TPI_MESSAGE_STATUS; + piInfo.eStatus = TPI_STATUS_ENDPROCESS; + if (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & piInfo) != TPI_CALLBACK_CONTINUE) + { + nErrorCode = TPI_ERROR_D_SKIPPED; + break; + } + } } CloseArchive(hArc); return nErrorCode; } -int __stdcall SetCallbackProc -( - TPI_PROC _prArcProc -) -{ - // ƒ|ƒCƒ“ƒ^‚ð•Û‘¶B - if (_prArcProc == NULL) - { - return TPI_ERROR_D_PARAMETER; - } - g_prProc = * _prArcProc; - - return TPI_ERROR_SUCCESS; -} - #ifdef __cplusplus } #endif