OSDN Git Service

使用しているSPIの情報をTPI_ARCHIVEINFO::TPI_FORMATINFOに格納する機能を追加。
[tpi/lychee.git] / src / plugin / spiLibrary / spiLibrary.cpp
index efdc402..f37316a 100644 (file)
@@ -40,21 +40,6 @@ HMODULE g_hLib;
 TPI_PROC g_prProc;\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
 //******************************************************************************\r
 \r
@@ -62,7 +47,7 @@ int __stdcall CallbackProc(int _nNow, int, long _lData)
 {\r
        // 構造体を初期化。\r
        TPI_PROCESSINFO * piInfo = (TPI_PROCESSINFO *) _lData;\r
-       piInfo->llProcessedSize = _nNow;\r
+       piInfo->nProcessedSize = _nNow;\r
 \r
        // コールバック関数に送信。\r
        return g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, piInfo) == TPI_CALLBACK_CANCEL;\r
@@ -100,7 +85,7 @@ extern "C"
 int __stdcall GetPluginInformation\r
 (\r
        unsigned int _uInfoId,\r
-       wxULongLong,\r
+       wxULongLong_t,\r
        void * _pPtr\r
 )\r
 {\r
@@ -131,44 +116,66 @@ int __stdcall GetFormatInformation(TPI_FORMATINFO *, bool)
 int __stdcall LoadPlugin\r
 (\r
        const wxString & _szArcName,\r
-       wxULongLong\r
+       wxULongLong_t\r
 )\r
 {\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
+       {\r
+               hFile.Close();\r
+               return TPI_ERROR_IO_ARC_READ;\r
+       }\r
+       hFile.Close();\r
+\r
        wxStandardPaths p;\r
        wxString szSPIPath = wxPathOnly(p.GetExecutablePath()) + wxT("/lib/"), szSPIName;\r
        wxDir fs(szSPIPath);\r
-       bool b = fs.GetFirst(& szSPIName, wxT("*.spi"));\r
-       while (b)\r
+       if (fs.GetFirst(& szSPIName, wxT("*.spi")))\r
        {\r
-               // SPIをロード。\r
-               wxString szLibName = szSPIPath + szSPIName;\r
-               g_hLib = ::LoadLibrary(szLibName.wchar_str());\r
-               if (g_hLib == NULL)\r
+               do\r
                {\r
-                       b = fs.GetNext(& szSPIName);\r
-                       continue;\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] != 'A' || szPluginType[3] != 'M')\r
-               {\r
-                       ::FreeLibrary(g_hLib);\r
-                       b = fs.GetNext(& szSPIName);\r
-                       continue;\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] != 'A' || szPluginType[3] != 'M')\r
+                       {\r
+                               ::FreeLibrary(g_hLib);\r
+                               continue;\r
+                       }\r
 \r
-               // 書庫に対応しているかチェック。\r
-               if (CheckArchive(_szArcName, NULL) == TPI_ERROR_SUCCESS)\r
-               {\r
-                       // 対応していれば処理を終了。\r
-                       return TPI_ERROR_SUCCESS;\r
-               }\r
+                       // 書庫に対応しているかチェック。\r
+                       fpProc = ::GetProcAddress(g_hLib, "IsSupported");\r
+                       if (fpProc == NULL)\r
+                       {\r
+                               ::FreeLibrary(g_hLib);\r
+                               continue;\r
+                       }\r
 \r
-               b = fs.GetNext(& szSPIName);\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
@@ -182,63 +189,11 @@ int __stdcall FreePlugin
        return TPI_ERROR_SUCCESS;\r
 }\r
 \r
-int __stdcall CheckArchive\r
-(\r
-       const wxString & _szArcName,\r
-       wxULongLong * _llFileCount\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
-               return TPI_ERROR_IO_ARC_OPEN;\r
-       }\r
-\r
-       char buffer[2050];\r
-       ::ZeroMemory(buffer, sizeof(buffer));\r
-       if (hFile.Read(buffer, sizeof(buffer)) == wxInvalidOffset)\r
-       {\r
-               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
-       fpProc = ::GetProcAddress(g_hLib, "GetArchiveInfo");\r
-       if (fpProc == NULL)\r
-       {\r
-               return TPI_ERROR_U_USE_LIBRARY;\r
-       }\r
-\r
-       HLOCAL hMemory;\r
-       int nReturnCode = ErrorCodeConvert(((int (PASCAL *)(const char *, long, unsigned int, HLOCAL *)) fpProc)(_szArcName.ToUTF8(), 0, 0, & hMemory));\r
-       if (nReturnCode == TPI_ERROR_SUCCESS)\r
-       {\r
-               if (_llFileCount != NULL)\r
-               {\r
-                       * _llFileCount = ::LocalSize(hMemory) / sizeof(fileInfo);\r
-               }\r
-               ::LocalFree(hMemory);\r
-       }\r
-\r
-       return nReturnCode;\r
-}\r
-\r
 int __stdcall OpenArchive\r
 (\r
        const wxString & _szArcName,\r
-       void * * _hArchive\r
+       void * * _hArchive,\r
+       wxULongLong_t * _nFileCount\r
 )\r
 {\r
        FARPROC fpProc = ::GetProcAddress(g_hLib, "GetArchiveInfo");\r
@@ -252,7 +207,10 @@ int __stdcall OpenArchive
        {\r
                return nReturnCode;\r
        }\r
-\r
+       if (_nFileCount != NULL)\r
+       {\r
+               * _nFileCount = ::LocalSize(* _hArchive) / sizeof(fileInfo);\r
+       }\r
        return * _hArchive == NULL ? TPI_ERROR_IO_ARC_OPEN : nReturnCode;\r
 }\r
 \r
@@ -271,33 +229,33 @@ int __stdcall GetFileInformation
        bool _bFirst\r
 )\r
 {\r
-       static unsigned int uFileCount, uFilePointer;\r
+       static wxULongLong_t nFileCount, nFilePointer;\r
 \r
        if (_bFirst)\r
        {\r
-               uFilePointer = 0;\r
-               uFileCount = (unsigned int) (::LocalSize(_hArchive) / sizeof(fileInfo));\r
+               nFilePointer = 0;\r
+               nFileCount = ::LocalSize(_hArchive) / sizeof(fileInfo);\r
        }\r
 \r
-       if (uFilePointer > uFileCount)\r
+       if (nFilePointer > nFileCount)\r
        {\r
                return TPI_ERROR_S_ENDOFDATA;\r
        }\r
 \r
-       fileInfo pfiInfo = ((fileInfo *) ::LocalLock(_hArchive))[uFilePointer];\r
+       fileInfo pfiInfo = ((fileInfo *) ::LocalLock(_hArchive))[nFilePointer];\r
        if (pfiInfo.method[0] == 0)\r
        {\r
                // 丁寧なプラグインのための数合わせ (^^;\r
-               uFileCount = uFilePointer;\r
+               nFileCount = nFilePointer;\r
                return TPI_ERROR_S_ENDOFDATA;\r
        }\r
 \r
        _fiInfo->dwAttribute    = 0;\r
        _fiInfo->dwCRC32        = pfiInfo.crc;\r
-       _fiInfo->llPackedSize   = pfiInfo.compsize;\r
-       _fiInfo->llUnpackedSize = pfiInfo.filesize;\r
+       _fiInfo->nPackedSize    = pfiInfo.compsize;\r
+       _fiInfo->nUnpackedSize  = pfiInfo.filesize;\r
        _fiInfo->wCompressRatio = pfiInfo.compsize >= pfiInfo.filesize ? 1000 : (WORD) (1000 * pfiInfo.compsize / pfiInfo.filesize);\r
-       _fiInfo->llFileID       = uFilePointer++;\r
+       _fiInfo->nFileId        = nFilePointer++;\r
        _fiInfo->tmModified     = pfiInfo.timestamp;\r
        _fiInfo->szStoredName   = MB2String(pfiInfo.path) + MB2String(pfiInfo.filename);\r
        _fiInfo->fnFileName     = wxFileName(_fiInfo->szStoredName);\r
@@ -318,31 +276,36 @@ int __stdcall GetArchiveInformation
        FARPROC 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.szTPIName = wxT("spiLibrary");\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
 )\r
 {\r
-       if (_uCommand != TPI_COMMAND_EXTRACT)\r
+       if (_eCommand != TPI_COMMAND_EXTRACT)\r
        {\r
                return TPI_ERROR_D_UNSUPPORTED;\r
        }\r
@@ -365,8 +328,8 @@ int __stdcall Command
        // コールバックを送信。\r
        wxFileName _fnArcName(_szArcName);\r
        TPI_PROCESSINFO piInfo;\r
-       piInfo.uMessage = TPI_MESSAGE_STATUS;\r
-       piInfo.uStatus  = TPI_STATUS_OPENARCHIVE;\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
@@ -374,44 +337,48 @@ int __stdcall Command
        }\r
 \r
        // 処理実行。\r
-       piInfo.uStatus = TPI_STATUS_INPROCESS;\r
+       piInfo.eStatus = TPI_STATUS_INPROCESS;\r
        nErrorCode = GetFileInformation(hArchive, & piInfo.fiInfo, true);\r
        if (nErrorCode == TPI_ERROR_SUCCESS)\r
        {\r
                do\r
                {\r
-                       // コールバックを送信。\r
-                       piInfo.uStatus = TPI_STATUS_BEGINPROCESS;\r
+                       // 処理対象かどうか判定。\r
+                       if ((! _szFiles.IsEmpty()) && _szFiles.Index(piInfo.fiInfo.szStoredName) == wxNOT_FOUND)\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       // 処理を行うか確認。\r
+                       piInfo.eMessage = TPI_MESSAGE_ASK;\r
+                       piInfo.eStatus = TPI_PARAM_DEST;\r
+                       piInfo.fnDestination = wxFileName(_swInfo->fnDestinationDirectory.GetPathWithSep() + (_swInfo->fStoreDirectoryPathes ? piInfo.fiInfo.fnFileName.GetFullPath() : piInfo.fiInfo.fnFileName.GetFullName()));\r
                        if (CallbackProc(0, 0, (long) & piInfo))\r
                        {\r
                                nErrorCode = TPI_ERROR_D_SKIPPED;\r
                                break;\r
                        }\r
-                       piInfo.uStatus = TPI_STATUS_INPROCESS;\r
-\r
-                       // 処理対象かどうか判定。\r
-                       if ((! _szFiles.IsEmpty()) && _szFiles.Index(piInfo.fiInfo.szStoredName) == wxNOT_FOUND)\r
+                       if (! piInfo.fnDestination.IsOk())\r
                        {\r
                                continue;\r
                        }\r
 \r
-                       // 出力名作成。\r
-                       wxString szTargetPath = _swInfo->fnDestinationDirectory.GetPathWithSep();\r
-                       if (_swInfo->fStoreDirectoryPathes)\r
+                       // 出力先作成。\r
+                       if (! piInfo.fnDestination.Mkdir(0777, wxPATH_MKDIR_FULL))\r
                        {\r
-                               // 展開先ディレクトリを作成。\r
-                               szTargetPath += piInfo.fiInfo.fnFileName.GetFullPath();\r
-                               wxFileName fnDest(szTargetPath);\r
-                               if (! fnDest.Mkdir(0777, wxPATH_MKDIR_FULL) || ::wxDirExists(fnDest.GetFullPath()))\r
-                               {\r
-                                       nErrorCode = TPI_ERROR_IO_DIR_WRITE;\r
-                                       break;\r
-                               }\r
+                               nErrorCode = TPI_ERROR_IO_DIR_WRITE;\r
+                               break;\r
                        }\r
-                       else\r
+\r
+                       // コールバックを送信。\r
+                       piInfo.eMessage = TPI_MESSAGE_STATUS;\r
+                       piInfo.eStatus = TPI_STATUS_BEGINPROCESS;\r
+                       if (CallbackProc(0, 0, (long) & piInfo))\r
                        {\r
-                               szTargetPath += piInfo.fiInfo.fnFileName.GetFullName();\r
+                               nErrorCode = TPI_ERROR_D_SKIPPED;\r
+                               break;\r
                        }\r
+                       piInfo.eStatus = TPI_STATUS_INPROCESS;\r
 \r
                        // ファイル出力には対応してないのでメモリ出力で代行。\r
                        HLOCAL hMemory = NULL;\r
@@ -427,14 +394,13 @@ int __stdcall Command
 \r
                        // 展開先に出力。\r
                        wxFile hFile;\r
-                       // 強制上書きするので注意。\r
-                       if (! hFile.Create(szTargetPath, true))\r
+                       if (! hFile.Create(piInfo.fnDestination.GetFullPath()))\r
                        {\r
                                nErrorCode = TPI_ERROR_IO_FILE_OPEN;\r
                                break;\r
                        }\r
 \r
-                       bool bErrorOccured = hFile.Write(::LocalLock(hMemory), (size_t) piInfo.fiInfo.llUnpackedSize.GetValue()) != piInfo.fiInfo.llUnpackedSize;\r
+                       bool bErrorOccured = hFile.Write(::LocalLock(hMemory), piInfo.fiInfo.nUnpackedSize) != piInfo.fiInfo.nUnpackedSize;\r
                        ::LocalUnlock(hMemory);\r
                        ::LocalFree(hMemory);\r
                        hFile.Close();\r
@@ -446,7 +412,7 @@ int __stdcall Command
                        nErrorCode = TPI_ERROR_SUCCESS;\r
 \r
                        // コールバックを送信。\r
-                       piInfo.uStatus = TPI_STATUS_ENDPROCESS;\r
+                       piInfo.eStatus = TPI_STATUS_ENDPROCESS;\r
                        if (CallbackProc(0, 0, (long) & piInfo))\r
                        {\r
                                nErrorCode = TPI_ERROR_D_SKIPPED;\r