// Includes\r
//******************************************************************************\r
\r
+#define MYUSE_LIBPATH 1\r
#include "../../common/header/plugin.h"\r
#include "../../common/header/plugin-extra.h"\r
#include "../../common/library/library.h"\r
#include "../../common/library/xmldoc.h"\r
#include <wx/tokenzr.h>\r
-#include <wx/process.h>\r
-#include <wx/txtstrm.h>\r
#include "cuiWrapper.h"\r
+#define min(a, b) ((a) < (b) ? (a) : (b))\r
\r
//******************************************************************************\r
// Global varients\r
// Inside Functions\r
//******************************************************************************\r
\r
-int myExecute(const wxString & szCommandLine, bool fWine)\r
+int myExecute(const wxString & szCommandLine, wxString * szOutput, const wxString & szCwd, bool fWine)\r
{\r
#ifdef __LINUX__\r
+ wxString sz = ::wxGetCwd();\r
+ ::wxSetWorkingDirectory(szCwd);\r
FILE * fp = popen(fWine ? (wxT("wine ") + szCommandLine).ToUTF8() : szCommandLine.ToUTF8(), "r");\r
+ ::wxSetWorkingDirectory(sz);\r
if (fp == NULL)\r
{\r
wxLogError(L"Error :\n\nCommandLine:\n%s", szCommandLine.c_str());\r
return TPI_ERROR_U_USE_LIBRARY;\r
}\r
\r
+ if (szOutput != NULL)\r
+ {\r
+ char sz[32769];\r
+ while (! feof(fp))\r
+ {\r
+ memset(sz, 0, sizeof(sz));\r
+ fread(sz, sizeof(char), sizeof(sz) - 1, fp);\r
+ * szOutput += UTF82String(sz);\r
+ }\r
+// ::wxMessageBox(* szOutput);\r
+ }\r
+\r
// 127を返した場合はコマンドが存在しない。\r
int nErrorCode = pclose(fp);\r
return (WIFEXITED(nErrorCode) && WEXITSTATUS(nErrorCode) != 127) ? TPI_ERROR_SUCCESS : TPI_ERROR_U_USE_LIBRARY;\r
#else\r
+ SECURITY_ATTRIBUTES sa;\r
+ memset(& sa, 0, sizeof(SECURITY_ATTRIBUTES));\r
+ sa.bInheritHandle = TRUE;\r
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);\r
+ HANDLE hRead, hWrite;\r
+ if (! ::CreatePipe(& hRead, & hWrite, & sa, 4096))\r
+ {\r
+ return TPI_ERROR_U_USE_LIBRARY;\r
+ }\r
STARTUPINFO si;\r
- PROCESS_INFORMATION pi;\r
memset(& si, 0, sizeof(STARTUPINFO));\r
si.cb = sizeof(STARTUPINFO);\r
- if (! ::CreateProcess(NULL, szCommandLine.wchar_str(), NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, & si, & pi))\r
+ si.dwFlags = STARTF_USESTDHANDLES;\r
+ si.hStdOutput = hWrite;\r
+ si.hStdError = hWrite;\r
+ PROCESS_INFORMATION pi;\r
+ if (! ::CreateProcess(NULL, szCommandLine.wchar_str(), NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, szCwd.IsEmpty() ? NULL : szCwd.wchar_str(), & si, & pi))\r
{\r
return TPI_ERROR_U_USE_LIBRARY;\r
}\r
::CloseHandle(pi.hThread);\r
+\r
+ if (szOutput != NULL)\r
+ {\r
+ bool bSignal;\r
+ do\r
+ {\r
+ DWORD dwSize = 0;\r
+ bSignal = ::WaitForSingleObject(pi.hProcess, 100) == WAIT_OBJECT_0;\r
+ ::PeekNamedPipe(hRead, NULL, 0, NULL, & dwSize, NULL);\r
+ while (dwSize > 0)\r
+ {\r
+ char sz[4097];\r
+ memset(sz, 0, sizeof(sz));\r
+ ::ReadFile(hRead, & sz, sizeof(sz) - 1, & dwSize, NULL);\r
+ * szOutput += wxString(sz);\r
+ // UTF-8以外の文字コードだと、UTF82Stringを使うと書庫が開けなくなる。データの切り出しにも影響。\r
+// * szOutput += UTF82String(sz);\r
+// ::MessageBoxA(NULL, sz, NULL, 0);\r
+ ::PeekNamedPipe(hRead, NULL, 0, NULL, & dwSize, NULL);\r
+ }\r
+ }\r
+ while (! bSignal);\r
+ }\r
+\r
::CloseHandle(pi.hProcess);\r
+ ::CloseHandle(hRead);\r
+ ::CloseHandle(hWrite);\r
return TPI_ERROR_SUCCESS;\r
#endif\r
}\r
return pi;\r
}\r
\r
-wxULongLong_t GetSize(const PosInfo & pi, const wxArrayString & as)\r
+wxULongLong_t GetSize(const PosInfo & pi, wxULongLong_t nCurrent, const wxArrayString & as)\r
{\r
if (pi.nStart == 0 && pi.nCount == 0)\r
{\r
return 0;\r
}\r
\r
- wxULongLong_t nTemp = 0;\r
- wxString sz =\r
- pi.nCount == 0 ?\r
- as[pi.nLine].Mid(pi.nStart) :\r
- as[pi.nLine].Mid(pi.nStart, pi.nCount);\r
+ wxULongLong_t nTemp = 0, nPos = nCurrent + pi.nLine;\r
+ wxString sz = pi.nCount == 0 ? as[nPos].Mid(pi.nStart) : as[nPos].Mid(pi.nStart, pi.nCount);\r
sz.ToULongLong(& nTemp);\r
return nTemp;\r
}\r
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
\r
MakeFormatInfo(xmlLibrary, wxT("cuiWrapper"), _fiInfo, s_nFileId++);\r
wxString szExeFile = xmlLibrary->GetAttribute(wxT("name"), wxEmptyString);\r
- if (myExecute(szExeFile, szExeFile.EndsWith(wxT(".exe"))) != TPI_ERROR_SUCCESS)\r
+ if (myExecute(szExeFile, NULL, wxEmptyString, szExeFile.MakeLower().EndsWith(wxT(".exe"))) != TPI_ERROR_SUCCESS)\r
{\r
_fiInfo->eSupportedCommand = 0;\r
}\r
{\r
// .tar.XXXなど二重判定への対応。\r
// if (asExt[i].IsSameAs(fnArchive.GetExt(), false))\r
- if (fnArchive.GetFullName().EndsWith(wxT('.') + asExt[i]))\r
+ if (fnArchive.GetFullName().MakeLower().EndsWith(wxT('.') + asExt[i].MakeLower()))\r
{\r
// ライブラリをロード。\r
g_LibInfo.szExeFile = xmlLibrary->GetAttribute(wxT("name"), wxEmptyString);\r
(\r
const wxString & _szArcName,\r
void * * _hArchive,\r
- wxULongLong_t *\r
+ wxULongLong_t * _nFileCount\r
)\r
{\r
- wxString szCommandLine = g_LibInfo.szExeFile + wxT(" ") + MakeCommandLineSend(g_LibInfo.node.GetAttribute(wxT("list"), wxEmptyString), _szArcName);\r
-#ifdef __LINUX__\r
- wxProcess * p = ::wxProcess::Open(g_LibInfo.szExeFile.EndsWith(wxT(".exe")) ? (wxT("wine ") + szCommandLine) : szCommandLine, wxEXEC_ASYNC);\r
-#else\r
- wxProcess * p = ::wxProcess::Open(szCommandLine, wxEXEC_ASYNC);\r
-#endif\r
- if (p == NULL)\r
+ wxString szOutput;\r
+ TPI_SWITCHES swInfo;\r
+ swInfo.szArcName = _szArcName;\r
+ if (myExecute(g_LibInfo.szExeFile + wxT(" ") + MakeCommandLineSend(g_LibInfo.node.GetAttribute(wxT("list"), wxEmptyString), & swInfo), & szOutput, wxEmptyString, g_LibInfo.szExeFile.MakeLower().EndsWith(wxT(".exe"))) != TPI_ERROR_SUCCESS)\r
{\r
- wxLogError(L"Error :\n\nCommandLine:\n%s", szCommandLine.c_str());\r
return TPI_ERROR_U_USE_LIBRARY;\r
}\r
+ wxArrayString * as = new wxArrayString(::wxStringTokenize(szOutput, wxT("\r\n")));\r
+ * _hArchive = (void *) as;\r
+ as->Shrink();\r
+ if (_nFileCount != NULL)\r
+ {\r
+ * _nFileCount = as->GetCount();\r
+ }\r
\r
- p->Redirect();\r
- wxInputStream * is = p->GetInputStream();\r
- wxTextInputStream tis(* is);\r
wxString szStartLine = g_LibInfo.node.GetAttribute(wxT("list-line-s"), wxEmptyString);\r
- if (! szStartLine.IsEmpty())\r
+ if ((! szStartLine.IsEmpty() && as->Index(szStartLine) == wxNOT_FOUND) || as->IsEmpty())\r
{\r
- // 開始行まで読み飛ばす。\r
- while (! is->Eof() && tis.ReadLine() != szStartLine);\r
- if (is->Eof())\r
- {\r
- // 書庫が読み込めなかった?\r
- ::wxSafeShowMessage(wxEmptyString, wxT("Unsupported archive!"));\r
- p->Detach();\r
- return TPI_ERROR_ARC_UNSUPPORTED;\r
- }\r
+ // 書庫が読み込めなかった?\r
+ delete as;\r
+ return TPI_ERROR_ARC_UNSUPPORTED;\r
}\r
\r
- * _hArchive = (void *) is;\r
- return is->Eof() ? TPI_ERROR_UNDEFINED : TPI_ERROR_SUCCESS;\r
+ return TPI_ERROR_SUCCESS;\r
}\r
\r
int __stdcall CloseArchive\r
(\r
- void *\r
+ void * _hArchive\r
)\r
{\r
+ wxArrayString * as = (wxArrayString *) _hArchive;\r
+ as->Clear();\r
+ delete as;\r
return TPI_ERROR_SUCCESS;\r
}\r
\r
bool _bFirst\r
)\r
{\r
+ static size_t s_nCurrentLine;\r
static wxULongLong_t s_nFileId;\r
if (_hArchive == NULL)\r
{\r
return TPI_ERROR_UNDEFINED;\r
}\r
- wxInputStream * is = (wxInputStream *) _hArchive;\r
- wxTextInputStream tis(* is);\r
+ wxArrayString asOutput = * (wxArrayString *) _hArchive;\r
\r
// XMLからの読み込みは初回に行う。\r
static wxString szEndLine, szDateFormat;\r
static PosInfo piFName, piPSize, piUSize, piDate;\r
if (_bFirst)\r
{\r
- // 初期設定。\r
s_nFileId = 0;\r
+ wxString szStartLine = g_LibInfo.node.GetAttribute(wxT("list-line-s"), wxEmptyString);\r
+ if (! szStartLine.IsEmpty())\r
+ {\r
+ // 開始行の次の行にセット。エラーはOpenArchiveでチェック済み。\r
+ s_nCurrentLine = asOutput.Index(szStartLine) + 1;\r
+ }\r
+\r
+ // 初期設定。\r
nProcessPerLine = myGetAttributeInt(& g_LibInfo.node, wxT("list-line-c"), 1);\r
- szEndLine = g_LibInfo.node.GetAttribute(wxT("list-line-e"), g_LibInfo.node.GetAttribute(wxT("list-line-s"), wxEmptyString));\r
- szDateFormat = g_LibInfo.node.GetAttribute(wxT("list-date-f"), wxDefaultDateTimeFormat);\r
+ szEndLine = g_LibInfo.node.GetAttribute(wxT("list-line-e"), szStartLine);\r
+ szDateFormat = g_LibInfo.node.GetAttribute(wxT("list-date-f"), wxDefaultDateTimeFormat);\r
piFName = MakePosInfo(wxT("fname"));\r
piPSize = MakePosInfo(wxT("psize"));\r
piUSize = MakePosInfo(wxT("usize"));\r
piDate = MakePosInfo(wxT("date"));\r
}\r
\r
- if (is->Eof())\r
+ if (s_nCurrentLine >= asOutput.GetCount())\r
{\r
// 空行で終わるとき以外はエラーとする。\r
return szEndLine.IsEmpty() ? TPI_ERROR_S_ENDOFDATA : TPI_ERROR_ARC_UNSUPPORTED;\r
}\r
\r
- // 必要な行数だけ取得。\r
- wxArrayString as;\r
- as.Add(tis.ReadLine());\r
- if (as[0] == szEndLine)\r
+ // 最終行かどうか確認。\r
+ if (asOutput[s_nCurrentLine] == szEndLine)\r
{\r
return TPI_ERROR_S_ENDOFDATA;\r
}\r
- for (wxULongLong_t i = 1; i < nProcessPerLine; i++)\r
- {\r
- as.Add(tis.ReadLine());\r
- }\r
\r
// ファイル名を取得。\r
- _fiInfo->szStoredName =\r
- piFName.nCount == 0 ?\r
- as[piFName.nLine].Mid(piFName.nStart) :\r
- as[piFName.nLine].Mid(piFName.nStart, piFName.nCount);\r
+ _fiInfo->szStoredName = piFName.nCount == 0 ? asOutput[s_nCurrentLine + piFName.nLine].Mid(piFName.nStart) : asOutput[s_nCurrentLine + piFName.nLine].Mid(piFName.nStart, piFName.nCount);\r
_fiInfo->szStoredName.Trim();\r
_fiInfo->fnFileName = wxFileName(_fiInfo->szStoredName, wxPATH_DOS);\r
\r
// サイズ取得。\r
- _fiInfo->nPackedSize = GetSize(piPSize, as);\r
- _fiInfo->nUnpackedSize = GetSize(piUSize, as);\r
+ _fiInfo->nPackedSize = GetSize(piPSize, s_nCurrentLine, asOutput);\r
+ _fiInfo->nUnpackedSize = GetSize(piUSize, s_nCurrentLine, asOutput);\r
\r
// 更新時刻取得。\r
if (piDate.nStart != 0 || piDate.nCount != 0)\r
{\r
- _fiInfo->tmModify.ParseFormat(\r
- piDate.nCount == 0 ?\r
- as[piDate.nLine].Mid(piDate.nStart) :\r
- as[piDate.nLine].Mid(piDate.nStart, piDate.nCount),\r
- szDateFormat\r
- );\r
+ _fiInfo->tmModify.ParseFormat(piDate.nCount == 0 ? asOutput[s_nCurrentLine + piDate.nLine].Mid(piDate.nStart) : asOutput[s_nCurrentLine + piDate.nLine].Mid(piDate.nStart, piDate.nCount), szDateFormat);\r
}\r
\r
// 最後に次の行へ進めておく。\r
_fiInfo->nFileId = s_nFileId++;\r
+ s_nCurrentLine += nProcessPerLine;\r
+\r
return TPI_ERROR_SUCCESS;\r
}\r
\r
(\r
wxULongLong_t _eCommand,\r
TPI_SWITCHES * _swInfo,\r
- const wxString & _szArcName,\r
+ void *,// _hArchive,\r
const wxArrayString & _szFiles\r
)\r
{\r
// コマンドライン・レスポンスファイル作成。\r
wxString\r
szResponceFileName = MakeResponceFile(_szFiles, myGetAttributeBool(& g_LibInfo.node, wxT("quote-resp"), true)),\r
- szCommandLineSend = g_LibInfo.szExeFile + wxT(" ") + MakeCommandLineSend(szCommandLine, _szArcName, _swInfo, _szFiles, szResponceFileName),\r
- sz = ::wxGetCwd();\r
+ szCommandLineSend = MakeCommandLineSend(szCommandLine, _swInfo, _szFiles, szResponceFileName);\r
\r
// コマンドライン実行。\r
- ::wxSetWorkingDirectory(_swInfo->fnDestinationDirectory.GetFullPath());\r
-#ifdef __LINUX__\r
- wxProcess * p = ::wxProcess::Open(g_LibInfo.szExeFile.EndsWith(wxT(".exe")) ? (wxT("wine ") + szCommandLineSend) : szCommandLineSend, wxEXEC_ASYNC);\r
-#else\r
- wxProcess * p = ::wxProcess::Open(szCommandLineSend, wxEXEC_ASYNC);\r
-#endif\r
- ::wxSetWorkingDirectory(sz);\r
- if (p == NULL)\r
- {\r
- ::wxRemoveFile(szResponceFileName);\r
- wxLogError(L"CommandLine:\n%s", szCommandLineSend.c_str());\r
- return TPI_ERROR_U_USE_LIBRARY;\r
- }\r
-\r
- TPI_PROCESSINFO piInfo;\r
- piInfo.eMessage = TPI_MESSAGE_STATUS;\r
- piInfo.eStatus = TPI_STATUS_INPROCESS;\r
- piInfo.nProcessedSize = 0;\r
-\r
- p->Redirect();\r
wxString szOutput;\r
- wxInputStream * is = p->GetInputStream();\r
- while (! is->Eof())\r
- {\r
- // コールバック関数に送信。\r
- if (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & piInfo) == TPI_CALLBACK_CANCEL)\r
- {\r
- p->Kill(p->GetPid(), wxSIGKILL);\r
- p->Detach();\r
- ::wxRemoveFile(szResponceFileName);\r
- return TPI_ERROR_D_SKIPPED;\r
- }\r
-\r
- if (! is->CanRead())\r
- {\r
- continue;\r
- }\r
-\r
- char sz[8192];\r
- is->Read(sz, sizeof(sz));\r
- szOutput += UTF82String(sz);\r
- }\r
-// ::wxMessageBox(szOutput);\r
+ int nErrorCode = myExecute(g_LibInfo.szExeFile + wxT(" ") + szCommandLineSend, & szOutput, _swInfo->fnDestinationDirectory.GetFullPath(), g_LibInfo.szExeFile.MakeLower().EndsWith(wxT(".exe")));\r
\r
// レスポンスファイル削除。\r
::wxRemoveFile(szResponceFileName);\r
- return TPI_ERROR_SUCCESS;\r
+\r
+ if (nErrorCode != TPI_ERROR_SUCCESS)\r
+ {\r
+ wxLogError(L"Error :\n%x\n\nCommandLine:\n%s\n\nOutput:\n%s", nErrorCode, szCommandLineSend.c_str(), szOutput.c_str());\r
+ }\r
+ return nErrorCode;\r
}\r
\r
#ifdef __cplusplus\r