OSDN Git Service

使用しているSPIの情報をTPI_ARCHIVEINFO::TPI_FORMATINFOに格納する機能を追加。
[tpi/lychee.git] / src / plugin / xpiLibrary / xpiLibrary.cpp
index 465adb7..829e0be 100644 (file)
 \r
 HMODULE g_hLib;\r
 TPI_PROC g_prProc;\r
-wxString g_szArcName;\r
-\r
-//******************************************************************************\r
-//    Entry\r
-//******************************************************************************\r
-\r
-BOOL __stdcall DllMain(HMODULE, DWORD fdwReason, void *)\r
-{\r
-       switch (fdwReason)\r
-       {\r
-       case DLL_PROCESS_DETACH:\r
-               ::FreeLibrary(g_hLib);\r
-               break;\r
-       }\r
-       return TRUE;\r
-}\r
 \r
 //******************************************************************************\r
 //    Callback Wrapper\r
@@ -61,28 +45,23 @@ BOOL __stdcall DllMain(HMODULE, DWORD fdwReason, void *)
 \r
 int __stdcall CallbackProc(int _nNow, int _nMax, long _lData)\r
 {\r
-       // \8d\\91¢\91Ì\82ð\8f\89\8aú\89»\81B\r
-       TPI_PROCESSINFO piInfo;\r
-       piInfo.uMessage = TPI_MESSAGE_STATUS;\r
-       piInfo.uStatus  = _nNow == 0     ? TPI_STATUS_BEGINPROCESS\r
-                                       : _nNow == _nMax ? TPI_STATUS_ENDPROCESS\r
-                                       : _nNow <  0     ? TPI_STATUS_OPENARCHIVE : TPI_STATUS_INPROCESS;\r
-       piInfo.llProcessedSize       = _nNow;\r
-       piInfo.fiInfo.llUnpackedSize = _nMax;\r
-//     piInfo.fiInfo.fnFileName = * (wxFileName *) _lData;\r
-\r
-       // \83R\81[\83\8b\83o\83b\83N\8aÖ\90\94\82É\91\97\90M\81B\r
-       return g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & piInfo) == TPI_CALLBACK_CANCEL;\r
+       // 構造体を初期化。\r
+       TPI_PROCESSINFO * piInfo = (TPI_PROCESSINFO *) _lData;\r
+       piInfo->nProcessedSize          = _nNow;\r
+       piInfo->fiInfo.nUnpackedSize    = _nMax;\r
+\r
+       // コールバック関数に送信。\r
+       return g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, piInfo) == TPI_CALLBACK_CANCEL;\r
 }\r
 \r
 //******************************************************************************\r
 //    Inside Functions\r
 //******************************************************************************\r
 \r
-int XpiErrorCodeConvert(int nXpiErrorCode)\r
+int ErrorCodeConvert(int nErrorCode)\r
 {\r
-       switch (nXpiErrorCode)\r
-       {       \r
+       switch (nErrorCode)\r
+       {\r
        case -1:case XPI_NO_FUNCTION:       return TPI_ERROR_U_USE_LIBRARY;\r
        case 0:                             return TPI_ERROR_SUCCESS;\r
        case 1: case XPI_ABORT:             return TPI_ERROR_D_SKIPPED;\r
@@ -111,7 +90,7 @@ extern "C"
 int __stdcall GetPluginInformation\r
 (\r
        unsigned int _uInfoId,\r
-       wxULongLong,\r
+       wxULongLong_t,\r
        void * _pPtr\r
 )\r
 {\r
@@ -142,76 +121,17 @@ int __stdcall GetFormatInformation(TPI_FORMATINFO *, bool)
 int __stdcall LoadPlugin\r
 (\r
        const wxString & _szArcName,\r
-       wxULongLong _llSubOption\r
+       wxULongLong_t\r
 )\r
 {\r
-       wxStandardPaths p;\r
-       wxString szSPIPath = wxPathOnly(p.GetExecutablePath()) + wxT("/lib/"), szSPIName;\r
-       wxDir fs(szSPIPath);\r
-\r
-       bool b = fs.GetFirst(& szSPIName, wxT("*.spi"));\r
-       while (b)\r
-       {\r
-               // SPI\82ð\83\8d\81[\83h\81B\r
-               wxString szLibName = szSPIPath + szSPIName;\r
-               g_hLib = ::LoadLibrary(szLibName.wchar_str());\r
-               if (g_hLib == NULL)\r
-               {\r
-                       b = fs.GetNext(& szSPIName);\r
-                       continue;\r
-               }\r
-\r
-               // GetPluginInfo\82ð\8eÀ\8ds\81B\r
-               FARPROC fpProc = ::GetProcAddress(g_hLib, "GetPluginInfo");\r
-               char szPluginType[5]; // \8eí\97Þ4bytes + NULL\r
-               if (fpProc == NULL\r
-                       || ((int (PASCAL *)(int, char *, int)) fpProc)(0, szPluginType, sizeof(szPluginType)) < 0\r
-                       || szPluginType[2] != 'I' || szPluginType[3] != 'N')\r
-               {\r
-                       ::FreeLibrary(g_hLib);\r
-                       b = fs.GetNext(& szSPIName);\r
-                       continue;\r
-               }\r
-\r
-               // \8f\91\8cÉ\82É\91Î\89\9e\82µ\82Ä\82¢\82é\82©\83`\83F\83b\83N\81B\r
-               if (CheckArchive(_szArcName, NULL) == TPI_ERROR_SUCCESS)\r
-               {\r
-                       // \91Î\89\9e\82µ\82Ä\82¢\82ê\82Î\8f\88\97\9d\82ð\8fI\97¹\81B\r
-                       return TPI_ERROR_SUCCESS;\r
-               }\r
-\r
-               b = fs.GetNext(& szSPIName);\r
-       }\r
-       return TPI_ERROR_U_LOAD_LIBRARY;\r
-}\r
-\r
-int __stdcall FreePlugin\r
-(\r
-       void * // _pReserved\r
-)\r
-{\r
-       ::FreeLibrary(g_hLib);\r
-       return TPI_ERROR_SUCCESS;\r
-}\r
-\r
-int __stdcall CheckArchive\r
-(\r
-       const wxString & _szArcName,\r
-       int * _nFileCount\r
-)\r
-{\r
-       FARPROC fpProc = ::GetProcAddress(g_hLib, "IsSupported");\r
-       if (fpProc == NULL)\r
-       {\r
-               return TPI_ERROR_U_USE_LIBRARY;\r
-       }\r
-\r
-       wxFile hFile(_szArcName, wxFile::read);\r
-       if (! hFile.IsOpened())\r
+       // ファイルを開く。\r
+       wxFile hFile;\r
+       if (! hFile.Exists(_szArcName) || ! hFile.Open(_szArcName, wxFile::read))\r
        {\r
                return TPI_ERROR_IO_ARC_OPEN;\r
        }\r
 \r
+       // 最初の2KBを読み込み。\r
        char buffer[2050];\r
        ::ZeroMemory(buffer, sizeof(buffer));\r
        if (hFile.Read(buffer, sizeof(buffer)) == wxInvalidOffset)\r
@@ -219,30 +139,69 @@ int __stdcall CheckArchive
                hFile.Close();\r
                return TPI_ERROR_IO_ARC_READ;\r
        }\r
-\r
-       if (! ((BOOL (PASCAL *)(const char *, unsigned long)) fpProc)(_szArcName.ToUTF8(), (unsigned long) buffer))\r
-       {\r
-               hFile.Close();\r
-               return TPI_ERROR_D_UNSUPPORTED;\r
-       }\r
        hFile.Close();\r
 \r
-       if (_nFileCount != NULL)\r
+       wxStandardPaths p;\r
+       wxString szSPIPath = wxPathOnly(p.GetExecutablePath()) + wxT("/lib/"), szSPIName;\r
+       wxDir fs(szSPIPath);\r
+       if (fs.GetFirst(& szSPIName, wxT("*.spi")))\r
        {\r
-               * _nFileCount = 1;\r
+               do\r
+               {\r
+                       // SPIをロード。\r
+                       g_hLib = ::LoadLibrary((szSPIPath + szSPIName).wchar_str());\r
+                       if (g_hLib == NULL)\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       // GetPluginInfoを実行。\r
+                       FARPROC fpProc = ::GetProcAddress(g_hLib, "GetPluginInfo");\r
+                       char szPluginType[5]; // 種類4bytes + NULL\r
+                       if (fpProc == NULL\r
+                               || ((int (PASCAL *)(int, char *, int)) fpProc)(0, szPluginType, sizeof(szPluginType)) <= 0\r
+                               || szPluginType[2] != 'I' || szPluginType[3] != 'N')\r
+                       {\r
+                               ::FreeLibrary(g_hLib);\r
+                               continue;\r
+                       }\r
+\r
+                       // 書庫に対応しているかチェック。\r
+                       fpProc = ::GetProcAddress(g_hLib, "IsSupported");\r
+                       if (fpProc == NULL)\r
+                       {\r
+                               ::FreeLibrary(g_hLib);\r
+                               continue;\r
+                       }\r
+\r
+                       if (((BOOL (PASCAL *)(const char *, unsigned long)) fpProc)(_szArcName.ToUTF8(), (unsigned long) buffer))\r
+                       {\r
+                               // 対応していれば処理を終了。\r
+                               return TPI_ERROR_SUCCESS;\r
+                       }\r
+               }\r
+               while (fs.GetNext(& szSPIName));\r
        }\r
+       return TPI_ERROR_U_LOAD_LIBRARY;\r
+}\r
 \r
+int __stdcall FreePlugin\r
+(\r
+       void * // _pReserved\r
+)\r
+{\r
+       ::FreeLibrary(g_hLib);\r
        return TPI_ERROR_SUCCESS;\r
 }\r
 \r
 int __stdcall OpenArchive\r
 (\r
        const wxString & _szArcName,\r
-       void * * _hArchive\r
+       void * * _hArchive,\r
+       wxULongLong_t *\r
 )\r
 {\r
-       g_szArcName = _szArcName;\r
-       * _hArchive = & g_szArcName;\r
+       * _hArchive = new wxString(_szArcName);\r
        return TPI_ERROR_SUCCESS;\r
 }\r
 \r
@@ -251,7 +210,7 @@ int __stdcall CloseArchive
        void * _hArchive\r
 )\r
 {\r
-       g_szArcName.Clear();\r
+       delete (wxString *) _hArchive;\r
        return TPI_ERROR_SUCCESS;\r
 }\r
 \r
@@ -262,18 +221,80 @@ int __stdcall GetFileInformation
        bool _bFirst\r
 )\r
 {\r
-       if (! _bFirst)\r
+       static wxString szXPIPath, szXPIName, szArcName = * (wxString *) _hArchive;\r
+       static int nColorDepth;\r
+       static wxDir fs;\r
+       if (_bFirst)\r
        {\r
-               return TPI_ERROR_S_ENDOFDATA;\r
-       }\r
+               wxStandardPaths p;\r
+               szXPIPath = wxPathOnly(p.GetExecutablePath()) + wxT("/lib/");\r
+               fs.Open(szXPIPath);\r
 \r
-       _fiInfo->fnFileName     = wxFileName(* (wxString *) _hArchive);\r
-       _fiInfo->fnFileName.SetVolume(wxEmptyString);\r
-       _fiInfo->fnFileName.SetPath(wxEmptyString);\r
-       _fiInfo->fnFileName.SetExt(wxT("bmp"));\r
-       _fiInfo->szStoredName   = _fiInfo->fnFileName.GetFullPath();\r
+               // 画像の情報を取得。\r
+               FARPROC fpProc = ::GetProcAddress(g_hLib, "GetPictureInfo");\r
+               if (fpProc == NULL)\r
+               {\r
+                       return TPI_ERROR_U_USE_LIBRARY;\r
+               }\r
+               PictureInfo picInfo;\r
+               int nErrorCode = ErrorCodeConvert(((int (PASCAL *)(const char *, long, unsigned int, PictureInfo *)) fpProc)(szArcName.ToUTF8(), 0, 0, & picInfo));\r
+               if (nErrorCode != TPI_ERROR_SUCCESS)\r
+               {\r
+                       return nErrorCode;\r
+               }\r
+               nColorDepth = picInfo.colorDepth;\r
+               ::LocalUnlock(picInfo.hInfo);\r
+               ::LocalFree(picInfo.hInfo);\r
+       }\r
 \r
-       return TPI_ERROR_SUCCESS;\r
+       if (_bFirst ? fs.GetFirst(& szXPIName, wxT("*.xpi")) : fs.GetNext(& szXPIName))\r
+       {\r
+               do\r
+               {\r
+                       // XPIをロード。\r
+                       HMODULE hXPI = ::LoadLibrary((szXPIPath + szXPIName).wchar_str());\r
+                       if (hXPI == NULL)\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       // GetPluginInfoを実行。\r
+                       FARPROC fpProc = ::GetProcAddress(hXPI, "GetPluginInfo");\r
+                       char szTemp[513];\r
+                       memset(szTemp, 0, sizeof(szTemp));\r
+                       if (fpProc == NULL\r
+                               || ((int (PASCAL *)(int, char *, int)) fpProc)(0, szTemp, sizeof(szTemp) - 1) <= 0\r
+                               || szTemp[2] != 'X' || szTemp[3] != 'N')\r
+                       {\r
+                               ::FreeLibrary(hXPI);\r
+                               continue;\r
+                       }\r
+\r
+                       _fiInfo->fnFileName = wxFileName(szArcName);\r
+                       _fiInfo->fnFileName.SetVolume(wxEmptyString);\r
+                       _fiInfo->fnFileName.SetPath(szXPIName);\r
+                       if (((int (PASCAL *)(int, char *, int)) fpProc)(1, szTemp, sizeof(szTemp) - 1) > 0)\r
+                       {\r
+                               _fiInfo->szComment = MB2String(szTemp);\r
+                       }\r
+                       if (((int (PASCAL *)(int, char *, int)) fpProc)(2, szTemp, sizeof(szTemp) - 1) > 0)\r
+                       {\r
+                               _fiInfo->fnFileName.SetExt(MB2String(szTemp));\r
+                       }\r
+                       _fiInfo->szStoredName = _fiInfo->fnFileName.GetFullPath();\r
+\r
+                       // 対応確認。\r
+                       fpProc = ::GetProcAddress(hXPI, "IsSupported");\r
+                       if (fpProc == NULL || ! ((BOOL (PASCAL *)(int)) fpProc)(nColorDepth))\r
+                       {\r
+                               ::FreeLibrary(hXPI);\r
+                               continue;\r
+                       }\r
+                       return TPI_ERROR_SUCCESS;\r
+               }\r
+               while (fs.GetNext(& szXPIName));\r
+       }\r
+       return TPI_ERROR_S_ENDOFDATA;\r
 }\r
 \r
 int __stdcall GetArchiveInformation\r
@@ -282,14 +303,14 @@ int __stdcall GetArchiveInformation
        TPI_ARCHIVEINFO * _aiInfo\r
 )\r
 {\r
-       // \89æ\91\9c\82Ì\8fî\95ñ\82ð\8eæ\93¾\81B\r
+       // 画像の情報を取得。\r
        FARPROC fpProc = ::GetProcAddress(g_hLib, "GetPictureInfo");\r
        if (fpProc == NULL)\r
        {\r
                return TPI_ERROR_U_USE_LIBRARY;\r
        }\r
        PictureInfo piInfo;\r
-       int nErrorCode = XpiErrorCodeConvert(((int (PASCAL *)(const char *, long, unsigned int, PictureInfo *)) fpProc)(((wxString *) _hArchive)->ToUTF8(), 0, 0, & piInfo));\r
+       int nErrorCode = ErrorCodeConvert(((int (PASCAL *)(const char *, long, unsigned int, PictureInfo *)) fpProc)(((wxString *) _hArchive)->ToUTF8(), 0, 0, & piInfo));\r
        if (nErrorCode != TPI_ERROR_SUCCESS)\r
        {\r
                return nErrorCode;\r
@@ -298,70 +319,77 @@ int __stdcall GetArchiveInformation
        ::LocalUnlock(piInfo.hInfo);\r
        ::LocalFree(piInfo.hInfo);\r
 \r
-       // GetPluginInfo\82ð\8eÀ\8ds\81B\r
+       // GetPluginInfoを実行。\r
        fpProc = ::GetProcAddress(g_hLib, "GetPluginInfo");\r
        if (fpProc != NULL)\r
        {\r
-               char szTemp[20];\r
-               if (((int (PASCAL *)(int, char *, int)) fpProc)(2, szTemp, sizeof(szTemp)) > 0)\r
+               char szTemp[513];\r
+               memset(szTemp, 0, sizeof(szTemp));\r
+               if (((int (PASCAL *)(int, char *, int)) fpProc)(1, szTemp, sizeof(szTemp) - 1) > 0)\r
+               {\r
+                       _aiInfo->fiInfo.szEngineName = MB2String(szTemp);\r
+               }\r
+               if (((int (PASCAL *)(int, char *, int)) fpProc)(2, szTemp, sizeof(szTemp) - 1) > 0)\r
                {\r
                        _aiInfo->fiInfo.szSuffix = MB2String(szTemp);\r
                }\r
-               if (((int (PASCAL *)(int, char *, int)) fpProc)(3, szTemp, sizeof(szTemp)) > 0)\r
+               if (((int (PASCAL *)(int, char *, int)) fpProc)(3, szTemp, sizeof(szTemp) - 1) > 0)\r
                {\r
                        _aiInfo->fiInfo.szTypeName = MB2String(szTemp);\r
                }\r
        }\r
        _aiInfo->fiInfo.fArchive = false;\r
        _aiInfo->fiInfo.szTPIName = wxT("xpiLibrary");\r
-       _aiInfo->fiInfo.llSupportedCommand = TPI_COMMAND_EXTRACT;\r
+       _aiInfo->fiInfo.eSupportedCommand = TPI_COMMAND_EXTRACT;\r
 \r
        return TPI_ERROR_SUCCESS;\r
 }\r
 \r
 int __stdcall Command\r
 (\r
-       unsigned int _uCommand,\r
+       wxULongLong_t _eCommand,\r
        TPI_SWITCHES * _swInfo,\r
        const wxString & _szArcName,\r
-       const wxArrayString & _szFiles\r
+       const wxArrayString & _asFiles\r
 )\r
 {\r
-       if (_uCommand != TPI_COMMAND_EXTRACT)\r
+       if (_eCommand != TPI_COMMAND_EXTRACT)\r
        {\r
                return TPI_ERROR_D_UNSUPPORTED;\r
        }\r
 \r
-       // \89æ\91\9c\82Ì\8fî\95ñ\82ð\8eæ\93¾\81B\r
+       // 画像の情報を取得。\r
        FARPROC fpProc = ::GetProcAddress(g_hLib, "GetPictureInfo");\r
        if (fpProc == NULL)\r
        {\r
                return TPI_ERROR_U_USE_LIBRARY;\r
        }\r
-       PictureInfo piInfo;\r
-       int nErrorCode = XpiErrorCodeConvert(((int (PASCAL *)(const char *, long, unsigned int, PictureInfo *)) fpProc)(_szArcName.ToUTF8(), 0, 0, & piInfo));\r
+       PictureInfo picInfo;\r
+       int nErrorCode = ErrorCodeConvert(((int (PASCAL *)(const char *, long, unsigned int, PictureInfo *)) fpProc)(_szArcName.ToUTF8(), 0, 0, & picInfo));\r
        if (nErrorCode != TPI_ERROR_SUCCESS)\r
        {\r
                return nErrorCode;\r
        }\r
 \r
-       // \93W\8aJ\8f\88\97\9d\82Ì\82Ý\82ð\8ds\82¤\81B\r
-       fpProc = ::GetProcAddress(g_hLib, "GetPicture");\r
-       if (fpProc == NULL)\r
-       {\r
-               return TPI_ERROR_U_USE_LIBRARY;\r
-       }\r
-\r
-       // \83R\81[\83\8b\83o\83b\83N\82ð\91\97\90M\81B\95Ö\8bX\8fã-1\82ð\91\97\90M\81B\r
+       // コールバックを送信。\r
        wxFileName _fnArcName(_szArcName);\r
-       if (CallbackProc(-1, 0, (long) & _fnArcName))\r
+       TPI_PROCESSINFO piInfo;\r
+       piInfo.eMessage = TPI_MESSAGE_STATUS;\r
+       piInfo.eStatus  = TPI_STATUS_OPENARCHIVE;\r
+       piInfo.fiInfo.fnFileName = _fnArcName;\r
+       if (CallbackProc(0, 0, (long) & piInfo))\r
        {\r
                return TPI_ERROR_D_SKIPPED;\r
        }\r
 \r
-       // \83\81\83\82\83\8a\8fo\97Í\81B\r
+       // メモリ上に展開。\r
        HANDLE hInfo, hMemory;\r
-       nErrorCode = XpiErrorCodeConvert(((int (PASCAL *)(const char *, long, unsigned int, HANDLE *, HANDLE *, FARPROC, long)) fpProc)(_szArcName.ToUTF8(), 0, 0, & hInfo, & hMemory, (FARPROC) CallbackProc, 0));\r
+       fpProc = ::GetProcAddress(g_hLib, "GetPicture");\r
+       if (fpProc == NULL)\r
+       {\r
+               return TPI_ERROR_U_USE_LIBRARY;\r
+       }\r
+       nErrorCode = ErrorCodeConvert(((int (PASCAL *)(const char *, long, unsigned int, HANDLE *, HANDLE *, FARPROC, long)) fpProc)(_szArcName.ToUTF8(), 0, 0, & hInfo, & hMemory, (FARPROC) CallbackProc, (long) & piInfo));\r
        if (nErrorCode == TPI_ERROR_SUCCESS && (hMemory == NULL || hInfo == NULL))\r
        {\r
                return TPI_ERROR_UNDEFINED;\r
@@ -371,43 +399,100 @@ int __stdcall Command
                return nErrorCode;\r
        }\r
 \r
-       // XPI\82ð\93Ç\82Ý\8d\9e\82Þ\81B\r
-       wxStandardPaths p;\r
-       wxString szXPIPath = wxPathOnly(p.GetExecutablePath()) + wxT("/lib/exbmp.xpi");\r
-       HMODULE hXPI = ::LoadLibrary(szXPIPath.wchar_str());\r
-       if (hXPI == NULL)\r
+       wxString szXPIPath;\r
        {\r
-               return TPI_ERROR_U_USE_LIBRARY;\r
+               wxStandardPaths p;\r
+               szXPIPath = wxPathOnly(p.GetExecutablePath()) + wxT("/lib/");\r
        }\r
 \r
-       // \91Î\89\9e\8am\94F\81B\r
-       fpProc = ::GetProcAddress(hXPI, "IsSupported");\r
-       if (fpProc == NULL)\r
-       {\r
-               return TPI_ERROR_U_USE_LIBRARY;\r
-       }\r
-       if (! XpiErrorCodeConvert(((BOOL (PASCAL *)(int)) fpProc)(piInfo.colorDepth)))\r
+       for (size_t i = 0; i < _asFiles.GetCount(); i++)\r
        {\r
-               return TPI_ERROR_ARC_UNSUPPORTED;\r
-       }\r
+               // 処理を行うか確認。\r
+               piInfo.eMessage = TPI_MESSAGE_ASK;\r
+               piInfo.eStatus = TPI_PARAM_DEST;\r
+               piInfo.fiInfo.fnFileName = wxFileName(_asFiles[i]);\r
+               piInfo.fnDestination = piInfo.fiInfo.fnFileName;\r
+               piInfo.fnDestination.SetPath(_swInfo->fnDestinationDirectory.GetPath());\r
+               if (CallbackProc(0, 0, (long) & piInfo))\r
+               {\r
+                       nErrorCode = TPI_ERROR_D_SKIPPED;\r
+                       break;\r
+               }\r
+               if (! piInfo.fnDestination.IsOk())\r
+               {\r
+                       continue;\r
+               }\r
 \r
-       // \8fo\97Í\96¼\8dì\90¬\81B\r
-       wxString szTargetPath = _swInfo->fnDestinationDirectory.GetPathWithSep() + _fnArcName.GetName() + wxT(".bmp");\r
+               // XPIをロード。\r
+               HMODULE hXPI = ::LoadLibrary((szXPIPath + piInfo.fiInfo.fnFileName.GetPath()).wchar_str());\r
+               if (hXPI == NULL)\r
+               {\r
+                       nErrorCode = TPI_ERROR_U_USE_LIBRARY;\r
+                       break;\r
+               }\r
 \r
-       // \8f\91\82«\8d\9e\82Ý\81B\r
-       fpProc = ::GetProcAddress(hXPI, "CreatePicture");\r
-       if (fpProc == NULL)\r
-       {\r
-               return TPI_ERROR_U_USE_LIBRARY;\r
+               // GetPluginInfoを実行。\r
+               FARPROC fpProc = ::GetProcAddress(hXPI, "GetPluginInfo");\r
+               char szTemp[20];\r
+               if (fpProc == NULL\r
+                       || ((int (PASCAL *)(int, char *, int)) fpProc)(2, szTemp, sizeof(szTemp)) <= 0)\r
+               {\r
+                       ::FreeLibrary(hXPI);\r
+                       nErrorCode = TPI_ERROR_U_USE_LIBRARY;\r
+                       break;\r
+               }\r
+\r
+               // コールバックを送信。\r
+               piInfo.eMessage = TPI_MESSAGE_STATUS;\r
+               piInfo.eStatus = TPI_STATUS_BEGINPROCESS;\r
+               if (CallbackProc(0, 0, (long) & piInfo))\r
+               {\r
+                       ::FreeLibrary(hXPI);\r
+                       nErrorCode = TPI_ERROR_D_SKIPPED;\r
+                       break;\r
+               }\r
+\r
+               // 書き込み。\r
+               piInfo.eStatus = TPI_STATUS_INPROCESS;\r
+               fpProc = ::GetProcAddress(hXPI, "CreatePicture");\r
+               if (fpProc == NULL)\r
+               {\r
+                       ::FreeLibrary(hXPI);\r
+                       nErrorCode = TPI_ERROR_U_USE_LIBRARY;\r
+                       break;\r
+               }\r
+               nErrorCode = ErrorCodeConvert(((int (PASCAL *)(const char *, long, HANDLE *, HANDLE *, PictureInfo *, FARPROC, long)) fpProc)(piInfo.fnDestination.GetFullPath().ToUTF8(), 0, & hInfo, & hMemory, & picInfo, (FARPROC) CallbackProc, (long) & piInfo));\r
+               ::FreeLibrary(hXPI);\r
+\r
+               // 最後にコールバックを送信。\r
+               piInfo.eStatus  = TPI_STATUS_ENDPROCESS;\r
+               if (CallbackProc(0, 0, (long) & piInfo))\r
+               {\r
+                       nErrorCode = TPI_ERROR_D_SKIPPED;\r
+                       break;\r
+               }\r
        }\r
-       nErrorCode = XpiErrorCodeConvert(((int (PASCAL *)(const char *, long, HANDLE *, HANDLE *, PictureInfo *, FARPROC, long)) fpProc)(szTargetPath.ToUTF8(), 0, & hInfo, & hMemory, & piInfo, (FARPROC) CallbackProc, 0));\r
        ::LocalUnlock(hInfo);\r
        ::LocalUnlock(hMemory);\r
+       ::LocalUnlock(picInfo.hInfo);\r
        ::LocalFree(hInfo);\r
        ::LocalFree(hMemory);\r
-       ::FreeLibrary(hXPI);\r
+       ::LocalFree(picInfo.hInfo);\r
+       if (nErrorCode != TPI_ERROR_SUCCESS)\r
+       {\r
+               return nErrorCode;\r
+       }\r
+\r
+       // 最終のコールバック。\r
+       piInfo.eMessage = TPI_MESSAGE_STATUS;\r
+       piInfo.eStatus  = TPI_STATUS_CLOSEARCHIVE;\r
+       piInfo.fiInfo.fnFileName = _fnArcName;\r
+       if (CallbackProc(0, 0, (long) & piInfo))\r
+       {\r
+               return TPI_ERROR_D_SKIPPED;\r
+       }\r
 \r
-       return nErrorCode;\r
+       return TPI_ERROR_SUCCESS;\r
 }\r
 \r
 int __stdcall SetCallbackProc\r
@@ -415,7 +500,7 @@ int __stdcall SetCallbackProc
        TPI_PROC _prArcProc\r
 )\r
 {\r
-       // \83|\83C\83\93\83^\82ð\95Û\91\81B\r
+       // ポインタを保存。\r
        if (_prArcProc == NULL)\r
        {\r
                return TPI_ERROR_D_PARAMETER;\r