OSDN Git Service

余分なコードを削除。
[tpi/lychee.git] / src / plugin / cuiWrapper / cuiWrapper.cpp
1 /*******************************************************************************\r
2   TPI - flexible but useless plug-in framework.\r
3   Copyright (C) 2002-2009 Silky\r
4 \r
5   This library is free software; you can redistribute it and/or modify it under\r
6   the terms of the GNU Lesser General Public License as published by the Free\r
7   Software Foundation; either version 2.1 of the License, or (at your option)\r
8   any later version.\r
9 \r
10   This library is distributed in the hope that it will be useful, but WITHOUT\r
11   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \r
12   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\r
13   for more details.\r
14 \r
15   You should have received a copy of the GNU Lesser General Public License along\r
16   with this library; if not, write to the Free Software Foundation, Inc.,\r
17   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r
18 \r
19   $Id$\r
20 *******************************************************************************/\r
21 \r
22 //******************************************************************************\r
23 //    Includes\r
24 //******************************************************************************\r
25 \r
26 #include "../../common/header/plugin.h"\r
27 #include "../../common/header/plugin-extra.h"\r
28 #include "../../common/library/library.h"\r
29 #include <wx/config.h>\r
30 #include <wx/stdpaths.h>\r
31 #include <wx/xml/xml.h>\r
32 #include <wx/tokenzr.h>\r
33 #ifdef __WINDOWS__\r
34 #include <windows.h>\r
35 #endif\r
36 #include "cuiWrapper.h"\r
37 \r
38 //******************************************************************************\r
39 //    Global varients\r
40 //******************************************************************************\r
41 \r
42 struct g_LibInfo\r
43 {\r
44         wxString szExeFile;\r
45         wxString szExeFileAlt;\r
46         wxString szListCommand;\r
47         int nLibIndex;\r
48         wxXmlNode node;\r
49 }       g_LibInfo;\r
50 \r
51 TPI_PROC g_prProc;\r
52 wxString g_szCurrentArchive;\r
53 wxArrayString g_asOutput;\r
54 \r
55 //******************************************************************************\r
56 //    Entry\r
57 //******************************************************************************\r
58 \r
59 #ifdef __WINDOWS__\r
60 BOOL __stdcall DllMain(HMODULE, DWORD, void *)\r
61 {\r
62         return TRUE;\r
63 }\r
64 #endif\r
65 \r
66 //******************************************************************************\r
67 //    Inside Functions\r
68 //******************************************************************************\r
69 \r
70 int myExecute(wxString szCommandLine, wxString * szOutput, wxString szCwd, bool bCheckExist = false)\r
71 {\r
72         // Windows用の方法ではバッファサイズを有限にしか取れない?\r
73         // Linux用の方法ではコンソールが表示されてしまう。\r
74 #ifdef __LINUX__\r
75         wxString sz = ::wxGetCwd();\r
76         ::wxSetWorkingDirectory(szCwd);\r
77         FILE * fp = popen(szCommandLine.ToUTF8(), "r");\r
78         ::wxSetWorkingDirectory(sz);\r
79         if (fp == NULL)\r
80         {\r
81 //              wxMessageBox(wxString::Format(wxT("Error :\n\nCommandLine:\n%s"), szCommandLine.c_str()));\r
82                 return TPI_ERROR_U_USE_LIBRARY;\r
83         }\r
84 \r
85         if (bCheckExist)\r
86         {\r
87                 return TPI_ERROR_SUCCESS;\r
88         }\r
89 \r
90         if (szOutput != NULL)\r
91         {\r
92                 char sz[32769];\r
93                 while (! feof(fp))\r
94                 {\r
95                         memset(sz, 0, sizeof(sz));\r
96                         fread(sz, sizeof(char), sizeof(sz) - 1, fp);\r
97                         * szOutput += UTF82String(sz);\r
98                 }\r
99 //              ::wxMessageBox(* szOutput);\r
100         }\r
101 \r
102         pclose(fp);\r
103         return TPI_ERROR_SUCCESS;\r
104 #else\r
105         SECURITY_ATTRIBUTES sa;\r
106         memset(& sa, 0, sizeof(SECURITY_ATTRIBUTES));\r
107         sa.bInheritHandle = TRUE;\r
108         sa.nLength = sizeof(SECURITY_ATTRIBUTES);\r
109         HANDLE hRead, hWrite;\r
110         if (! ::CreatePipe(& hRead, & hWrite, & sa, 0xffffffff))\r
111         {\r
112                 return TPI_ERROR_U_USE_LIBRARY;\r
113         }\r
114         STARTUPINFO si;\r
115         memset(& si, 0, sizeof(STARTUPINFO));\r
116         si.cb = sizeof(STARTUPINFO);\r
117         si.dwFlags = STARTF_USESTDHANDLES;\r
118         si.hStdOutput = hWrite;\r
119         si.hStdError = hWrite;\r
120         PROCESS_INFORMATION pi;\r
121         if (! ::CreateProcess(NULL, szCommandLine.wchar_str(), NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, szCwd.IsEmpty() ? NULL : szCwd.wchar_str(), & si, & pi))\r
122         {\r
123                 return TPI_ERROR_U_USE_LIBRARY;\r
124         }\r
125 \r
126         ::WaitForInputIdle(pi.hProcess, INFINITE);\r
127         ::WaitForSingleObject(pi.hProcess, INFINITE);\r
128 \r
129         DWORD nErrorCode = 0;\r
130         ::GetExitCodeProcess(pi.hProcess, & nErrorCode);\r
131         ::CloseHandle(pi.hThread);\r
132         ::CloseHandle(pi.hProcess);\r
133 \r
134         if (bCheckExist)\r
135         {\r
136                 return TPI_ERROR_SUCCESS;\r
137         }\r
138 \r
139         if (szOutput != NULL)\r
140         {\r
141                 DWORD dwSize = 0;\r
142                 char sz[32769];\r
143                 for (wxULongLong llSize = 0; llSize < ::GetFileSize(hRead, NULL); llSize += dwSize)\r
144                 {\r
145                         memset(sz, 0, sizeof(sz));\r
146                         dwSize = 0;\r
147                         ::ReadFile(hRead, sz, sizeof(sz) - 1, & dwSize, NULL);\r
148                         * szOutput += UTF82String(sz);\r
149 //                      ::MessageBoxA(NULL, sz, NULL, 0);\r
150                 }\r
151         }\r
152         ::CloseHandle(hRead);\r
153         ::CloseHandle(hWrite);\r
154 \r
155         return nErrorCode == 0 ? TPI_ERROR_SUCCESS : TPI_ERROR_UNDEFINED;\r
156 #endif\r
157 }\r
158 \r
159 PosInfo MakePosInfo(wxString szPrefix)\r
160 {\r
161         PosInfo pi;\r
162         g_LibInfo.node.GetPropVal(wxT("list-") + szPrefix + wxT("-s"), wxEmptyString).ToULong(& pi.nStart);\r
163         g_LibInfo.node.GetPropVal(wxT("list-") + szPrefix + wxT("-c"), wxEmptyString).ToULong(& pi.nCount);\r
164         g_LibInfo.node.GetPropVal(wxT("list-") + szPrefix + wxT("-l"), wxT("0")).ToULong(& pi.nLine);\r
165         return pi;\r
166 }\r
167 \r
168 wxULongLong GetSize(PosInfo & pi, size_t uCurrent, wxArrayString & as)\r
169 {\r
170         if (pi.nStart == 0 && pi.nCount == 0)\r
171         {\r
172                 return 0;\r
173         }\r
174 \r
175         wxULongLong_t nTemp;\r
176         size_t nPos = uCurrent + pi.nLine;\r
177         wxString sz = pi.nCount == 0 ? as[nPos].Mid(pi.nStart) : as[nPos].Mid(pi.nStart, pi.nCount);\r
178         sz.ToULongLong(& nTemp);\r
179         return nTemp;\r
180 }\r
181 \r
182 //******************************************************************************\r
183 //    Functions\r
184 //******************************************************************************\r
185 \r
186 #ifdef __cplusplus\r
187 extern "C"\r
188 {\r
189 #endif\r
190 \r
191 int __stdcall GetPluginInformation\r
192 (\r
193         unsigned int _uInfoId,\r
194         wxULongLong,\r
195         void * _pPtr\r
196 )\r
197 {\r
198         if (_pPtr == NULL)\r
199         {\r
200                 return TPI_ERROR_D_PARAMETER;\r
201         }\r
202         switch (_uInfoId)\r
203         {\r
204         case TPI_INFO_VERSION_MAJOR:\r
205         case TPI_INFO_VERSION_MINOR:\r
206                 * (int *) _pPtr = 0;\r
207                 break;\r
208         case TPI_INFO_VERSION_API:\r
209                 * (int *) _pPtr = 2;\r
210                 break;\r
211         default:\r
212                 return TPI_ERROR_D_UNSUPPORTED;\r
213         }\r
214         return TPI_ERROR_SUCCESS;\r
215 }\r
216 \r
217 int __stdcall GetFormatInformation(TPI_FORMATINFO * _fiInfo, bool _bFirst)\r
218 {\r
219         static unsigned int s_uFileID;\r
220         wxStandardPaths p;\r
221         wxXmlDocument config(wxPathOnly(p.GetExecutablePath()) + wxT("/lib/cuiWrapper.xml"));\r
222         // 一気に先頭のライブラリの情報を取得。\r
223         wxXmlNode * xmlLibrary = config.GetRoot()->GetChildren();\r
224 \r
225         if (_bFirst)\r
226         {\r
227                 // xml解析開始。\r
228                 s_uFileID = 0;\r
229         }\r
230         else\r
231         {\r
232                 for (unsigned int i = 0; i < s_uFileID && xmlLibrary != NULL; i++)\r
233                 {\r
234                         xmlLibrary = xmlLibrary->GetNext();\r
235                 }\r
236         }\r
237 \r
238         if (xmlLibrary == NULL || xmlLibrary->GetName() != wxT("library"))\r
239         {\r
240                 // 終端に達した場合。\r
241                 return TPI_ERROR_S_ENDOFDATA;\r
242         }\r
243 \r
244         MakeFormatInfo(wxT("cuiWrapper"), _fiInfo, xmlLibrary, s_uFileID++);\r
245         if (myExecute(xmlLibrary->GetPropVal(wxT("name"), wxEmptyString), NULL, wxEmptyString, true) != TPI_ERROR_SUCCESS)\r
246         {\r
247                 _fiInfo->llSupportedCommand = 0;\r
248         }\r
249 \r
250         return TPI_ERROR_SUCCESS;\r
251 }\r
252 \r
253 int __stdcall LoadPlugin\r
254 (\r
255         const wxString & _szArcName,\r
256         wxULongLong _llSubOption\r
257 )\r
258 {\r
259         // xml解析開始。\r
260         wxStandardPaths p;\r
261         wxXmlDocument config(wxPathOnly(p.GetExecutablePath()) + wxT("/lib/cuiWrapper.xml"));\r
262         if (! config.IsOk())\r
263         {\r
264                 return TPI_ERROR_UNDEFINED;\r
265         }\r
266         // 一気に先頭のライブラリの情報を取得。\r
267         wxXmlNode * xmlLibrary = config.GetRoot()->GetChildren();\r
268 \r
269         // 対象が存在するならば対応するライブラリを調査、\r
270         // 対象が存在しないならば指示されたライブラリをロード。\r
271         if (! ::wxFileExists(_szArcName))\r
272         {\r
273                 // 適当な位置まで移動。\r
274                 for (g_LibInfo.nLibIndex = 0; g_LibInfo.nLibIndex < _llSubOption && xmlLibrary != NULL; g_LibInfo.nLibIndex++)\r
275                 {\r
276                         xmlLibrary = xmlLibrary->GetNext();\r
277                 }\r
278                 if (xmlLibrary == NULL || xmlLibrary->GetName() != wxT("library"))\r
279                 {\r
280                         // xml文法エラー。\r
281                         return TPI_ERROR_UNDEFINED;\r
282                 }\r
283                 g_LibInfo.szExeFile = xmlLibrary->GetPropVal(wxT("name"), wxEmptyString);\r
284                 g_LibInfo.szExeFileAlt = xmlLibrary->GetPropVal(wxT("name-alt"), wxEmptyString);\r
285                 g_LibInfo.node = * xmlLibrary;\r
286 \r
287                 return TPI_ERROR_SUCCESS;\r
288         }\r
289 \r
290         // 無限ループに陥らないよう上限を設定。\r
291         for (g_LibInfo.nLibIndex = 0; g_LibInfo.nLibIndex < 300 && xmlLibrary != NULL; g_LibInfo.nLibIndex++)\r
292         {\r
293                 // ライブラリをロード。\r
294                 g_LibInfo.szExeFile = xmlLibrary->GetPropVal(wxT("name"), wxEmptyString);\r
295                 g_LibInfo.szExeFileAlt = xmlLibrary->GetPropVal(wxT("name-alt"), wxEmptyString);\r
296                 g_LibInfo.node = * xmlLibrary;\r
297 \r
298                 // 書庫に対応しているかチェック。\r
299                 if (CheckArchive(_szArcName, NULL) == TPI_ERROR_SUCCESS)\r
300                 {\r
301                         // 対応していれば処理を終了。\r
302                         return TPI_ERROR_SUCCESS;\r
303                 }\r
304 \r
305                 xmlLibrary = xmlLibrary->GetNext();\r
306         }\r
307 \r
308         return TPI_ERROR_U_LOAD_LIBRARY;\r
309 }\r
310 \r
311 int __stdcall FreePlugin\r
312 (\r
313         void * // _pReserved\r
314 )\r
315 {\r
316         return TPI_ERROR_SUCCESS;\r
317 }\r
318 \r
319 int __stdcall CheckArchive\r
320 (\r
321         const wxString & _szArcName,\r
322         wxULongLong * _llFileCount\r
323 )\r
324 {\r
325         wxFileName fnArchive(_szArcName);\r
326         wxArrayString asExt = ::wxStringTokenize(g_LibInfo.node.GetPropVal(wxT("suffix"), wxEmptyString), wxT(";"));\r
327         if (! g_LibInfo.node.HasProp(wxT("list")))\r
328         {\r
329                 return TPI_ERROR_ARC_UNSUPPORTED;\r
330         }\r
331 \r
332         for (size_t i = 0; i < asExt.GetCount(); i++)\r
333         {\r
334                 // .tar.XXXなど二重判定への対応。\r
335 //              if (asExt[i].IsSameAs(fnArchive.GetExt(), false))\r
336                 if (fnArchive.GetFullName().EndsWith(wxT('.') + asExt[i]))\r
337                 {\r
338                         // 開いて確認。先行してデータを取得しておく。\r
339                         int nErrorCode = OpenArchive(_szArcName, NULL);\r
340 \r
341                         // 対応。\r
342                         if (_llFileCount != NULL)\r
343                         {\r
344                                 // ファイル数は多めに取っておく。\r
345                                 * _llFileCount = g_asOutput.GetCount();\r
346                         }\r
347                         return nErrorCode;\r
348                 }\r
349         }\r
350 \r
351         return TPI_ERROR_ARC_UNSUPPORTED;\r
352 }\r
353 \r
354 int __stdcall OpenArchive\r
355 (\r
356         const wxString & _szArcName,\r
357         void * * _hArchive\r
358 )\r
359 {\r
360         if (g_szCurrentArchive != _szArcName)\r
361         {\r
362                 wxString szOutput;\r
363                 if (myExecute(g_LibInfo.szExeFile + wxT(" ") + MakeCommandLineSend(g_LibInfo.node.GetPropVal(wxT("list"), wxEmptyString), _szArcName, NULL, NULL, wxEmptyString), & szOutput, wxEmptyString) != TPI_ERROR_SUCCESS)\r
364                 {\r
365                         return TPI_ERROR_U_USE_LIBRARY;\r
366                 }\r
367                 g_szCurrentArchive = _szArcName;\r
368                 g_asOutput = ::wxStringTokenize(szOutput, wxT("\r\n"));\r
369                 g_asOutput.Shrink();\r
370         }\r
371         if (_hArchive != NULL)\r
372         {\r
373                 * _hArchive = & g_asOutput;\r
374         }\r
375         return g_asOutput.IsEmpty() ? TPI_ERROR_UNDEFINED : TPI_ERROR_SUCCESS;\r
376 }\r
377 \r
378 int __stdcall CloseArchive\r
379 (\r
380         void * _hArchive\r
381 )\r
382 {\r
383         ((wxArrayString *) _hArchive)->Clear();\r
384         return TPI_ERROR_SUCCESS;\r
385 }\r
386 \r
387 int __stdcall GetFileInformation\r
388 (\r
389         void * _hArchive,\r
390         TPI_FILEINFO * _fiInfo,\r
391         bool _bFirst\r
392 )\r
393 {\r
394         static size_t s_uCurrentLine;\r
395         static wxULongLong s_llFileID;\r
396         if (_hArchive == NULL)\r
397         {\r
398                 return TPI_ERROR_UNDEFINED;\r
399         }\r
400         wxArrayString asOutput = * (wxArrayString *) _hArchive;\r
401 \r
402         // XMLからの読み込みは初回に行う。\r
403         static wxString szEndLine, szDateFormat;\r
404         static unsigned long nProcessPerLine;\r
405         static PosInfo piFName, piPSize, piUSize, piDate;\r
406         if (_bFirst)\r
407         {\r
408                 s_llFileID = 0;\r
409                 wxString szStartLine = g_LibInfo.node.GetPropVal(wxT("list-line-s"), wxEmptyString);\r
410                 if (! szStartLine.IsEmpty())\r
411                 {\r
412                         // 開始行の次の行にセット。\r
413                         s_uCurrentLine = asOutput.Index(szStartLine) + 1;\r
414                         if (s_uCurrentLine == wxNOT_FOUND + 1)\r
415                         {\r
416                                 // 書庫が読み込めなかった?\r
417                                 return TPI_ERROR_ARC_UNSUPPORTED;\r
418                         }\r
419                 }\r
420 \r
421                 // 初期設定。\r
422                 g_LibInfo.node.GetPropVal(wxT("list-line-c"), wxT("1")).ToULong(& nProcessPerLine);\r
423                 szEndLine = g_LibInfo.node.GetPropVal(wxT("list-line-e"), szStartLine);\r
424                 szDateFormat = g_LibInfo.node.GetPropVal(wxT("list-date-f"), wxDefaultDateTimeFormat);\r
425                 piFName = MakePosInfo(wxT("fname"));\r
426                 piPSize = MakePosInfo(wxT("psize"));\r
427                 piUSize = MakePosInfo(wxT("usize"));\r
428                 piDate = MakePosInfo(wxT("date"));\r
429         }\r
430 \r
431         if (s_uCurrentLine >= asOutput.GetCount())\r
432         {\r
433                 // 書庫が読み込めなかった?\r
434                 return TPI_ERROR_ARC_UNSUPPORTED;\r
435         }\r
436 \r
437         // 最終行かどうか確認。\r
438         if (asOutput[s_uCurrentLine] == szEndLine)\r
439         {\r
440                 return TPI_ERROR_S_ENDOFDATA;\r
441         }\r
442 \r
443         // ファイル名を取得。\r
444         _fiInfo->szStoredName = piFName.nCount == 0 ? asOutput[s_uCurrentLine + piFName.nLine].Mid(piFName.nStart) : asOutput[s_uCurrentLine + piFName.nLine].Mid(piFName.nStart, piFName.nCount);\r
445         _fiInfo->szStoredName.Trim();\r
446         _fiInfo->fnFileName = wxFileName::wxFileName(_fiInfo->szStoredName);\r
447 \r
448         // サイズ取得。\r
449         _fiInfo->llPackedSize   = GetSize(piPSize, s_uCurrentLine, asOutput);\r
450         _fiInfo->llUnpackedSize = GetSize(piUSize, s_uCurrentLine, asOutput);\r
451 \r
452         // 更新時刻取得。\r
453         if (piDate.nStart != 0 || piDate.nCount != 0)\r
454         {\r
455                 _fiInfo->tmModified.ParseFormat(piDate.nCount == 0 ? asOutput[s_uCurrentLine + piDate.nLine].Mid(piDate.nStart) : asOutput[s_uCurrentLine + piDate.nLine].Mid(piDate.nStart, piDate.nCount), szDateFormat);\r
456         }\r
457 \r
458         // 最後に次の行へ進めておく。\r
459         _fiInfo->llFileID = s_llFileID++;\r
460         s_uCurrentLine += nProcessPerLine;\r
461 \r
462         return TPI_ERROR_SUCCESS;\r
463 }\r
464 \r
465 int __stdcall GetArchiveInformation\r
466 (\r
467         void *,\r
468         TPI_ARCHIVEINFO * _aiInfo\r
469 )\r
470 {\r
471         // 形式に関する情報を取得。\r
472         MakeFormatInfo(wxT("cuiWrapper"), & _aiInfo->fiInfo, & g_LibInfo.node, 0);\r
473         return TPI_ERROR_SUCCESS;\r
474 }\r
475 \r
476 int __stdcall Command\r
477 (\r
478         unsigned int _uCommand,\r
479         TPI_SWITCHES * _swInfo,\r
480         const wxString & _szArcName,\r
481         const wxArrayString & _szFiles\r
482 )\r
483 {\r
484         // xmlからコマンドラインを取得。\r
485         wxString szPath, szCommandLine;\r
486 \r
487         // APIアドレス取得。\r
488         if (! g_LibInfo.node.GetPropVal(\r
489                         _uCommand == TPI_COMMAND_ADD     ? wxT("add") :\r
490                         _uCommand == TPI_COMMAND_EXTRACT ? wxT("extract") : \r
491                         _uCommand == TPI_COMMAND_DELETE  ? wxT("delete") : \r
492                         _uCommand == TPI_COMMAND_UPDATE  ? wxT("update") : \r
493                         _uCommand == TPI_COMMAND_TEST    ? wxT("test") : \r
494                         _uCommand == TPI_COMMAND_REPAIR  ? wxT("repair") : \r
495                         _uCommand == TPI_COMMAND_MOVE    ? wxT("move") : \r
496                         _uCommand == TPI_COMMAND_SFX     ? wxT("sfx") : \r
497                         _uCommand == TPI_COMMAND_UNSFX   ? wxT("unsfx") : wxEmptyString, & szCommandLine))\r
498         {\r
499                 g_LibInfo.node.GetPropVal(\r
500                         _uCommand == TPI_COMMAND_ADD     ? wxT("add-alt") :\r
501                         _uCommand == TPI_COMMAND_EXTRACT ? wxT("extract-alt") : \r
502                         _uCommand == TPI_COMMAND_DELETE  ? wxT("delete-alt") : \r
503                         _uCommand == TPI_COMMAND_UPDATE  ? wxT("update-alt") : \r
504                         _uCommand == TPI_COMMAND_TEST    ? wxT("test-alt") : \r
505                         _uCommand == TPI_COMMAND_REPAIR  ? wxT("repair-alt") : \r
506                         _uCommand == TPI_COMMAND_MOVE    ? wxT("move-alt") : \r
507                         _uCommand == TPI_COMMAND_SFX     ? wxT("sfx-alt") : \r
508                         _uCommand == TPI_COMMAND_UNSFX   ? wxT("unsfx-alt") : wxEmptyString, & szCommandLine);\r
509         }\r
510 \r
511         if (szCommandLine.IsEmpty())\r
512         {\r
513                 return TPI_ERROR_U_USE_LIBRARY;\r
514         }\r
515 \r
516         // コマンドライン・レスポンスファイル作成。\r
517         wxString\r
518                 szResponceFileName = MakeResponceFile(_szFiles, g_LibInfo.node.GetPropVal(wxT("quote-resp"), wxT("1")) == wxT("1")),\r
519                 szCommandLineSend  = MakeCommandLineSend(szCommandLine, _szArcName, _swInfo, _szFiles, szResponceFileName);\r
520 \r
521         // コマンドライン実行。\r
522         wxString szOutput;\r
523         int nErrorCode = myExecute(g_LibInfo.szExeFile + wxT(" ") + szCommandLineSend, & szOutput, _swInfo->fnDestinationDirectory.GetFullPath());\r
524 \r
525         // レスポンスファイル削除。\r
526         ::wxRemoveFile(szResponceFileName);\r
527 \r
528         if (nErrorCode != TPI_ERROR_SUCCESS)\r
529         {\r
530 #ifdef __LINUX__\r
531                 ::wxMessageBox(wxString::Format(wxT("Error :\n%d\n\nCommandLine:\n%s\n\nOutput:\n%s"), nErrorCode, szCommandLineSend.c_str(), szOutput.c_str()));\r
532 #else\r
533                 MessageBox(NULL, wxString::Format(wxT("Error :\n%d\n\nCommandLine:\n%s\n\nOutput:\n%s"), nErrorCode, szCommandLineSend.c_str(), szOutput.c_str()), NULL, 0);\r
534 #endif\r
535         }\r
536         return nErrorCode;\r
537 }\r
538 \r
539 int __stdcall SetCallbackProc\r
540 (\r
541         TPI_PROC _prArcProc\r
542 )\r
543 {\r
544         // ポインタを保存。\r
545         if (_prArcProc == NULL)\r
546         {\r
547                 return TPI_ERROR_D_PARAMETER;\r
548         }\r
549         g_prProc = * _prArcProc;\r
550 \r
551         return TPI_ERROR_SUCCESS;\r
552 }\r
553 \r
554 #ifdef __cplusplus\r
555 }\r
556 #endif\r