OSDN Git Service

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