OSDN Git Service

Modified translate-catalog.
[tpi/lychee.git] / src / plugin / calLibrary / calLibrary.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 #define MYUSE_LIBPATH 1\r
27 #include "../../common/header/plugin.h"\r
28 #include "../../common/header/plugin-extra.h"\r
29 #include "../../common/library/library.h"\r
30 #include "../../common/library/xmldoc.h"\r
31 #include <wx/dynlib.h>\r
32 #include <wx/config.h>\r
33 #include <wx/xml/xml.h>\r
34 #include <windows.h>\r
35 #include "calLibrary.h"\r
36 \r
37 //******************************************************************************\r
38 //    Global varients\r
39 //******************************************************************************\r
40 \r
41 struct g_LibInfo\r
42 {\r
43         HMODULE hLib;\r
44         wxString szPrefix;\r
45         int nLibIndex;\r
46         wxXmlNode node;\r
47         bool fUnicode;\r
48         bool fCallback32bit;\r
49         bool fRunning;\r
50 }       g_LibInfo, g_LibInfoAlt;\r
51 \r
52 TPI_PROC g_prProc;\r
53 \r
54 //******************************************************************************\r
55 //    Inline Functions\r
56 //******************************************************************************\r
57 \r
58 #define MyConvEI322PI(EI, strconv) \\r
59         EI * ex = (EI *) _lpEis; \\r
60         \\r
61         piInfo.fiInfo.dwCRC32           = ex->dwCRC; \\r
62         piInfo.fiInfo.tmModify.SetFromDOS(MAKELONG(ex->wTime, ex->wDate)); \\r
63         piInfo.fiInfo.nPackedSize       = ex->dwCompressedSize; \\r
64         piInfo.fiInfo.nUnpackedSize     = ex->exinfo.dwFileSize; \\r
65         piInfo.fiInfo.eOSType           = ex->uOSType; \\r
66         piInfo.fiInfo.wCompressRatio    = ex->wRatio; \\r
67         piInfo.fiInfo.szStoredName      = strconv(ex->exinfo.szSourceFileName); \\r
68         piInfo.fiInfo.szMethod          = strconv(ex->szMode); \\r
69         \\r
70         piInfo.nProcessedSize           = ex->exinfo.dwWriteSize; \\r
71         piInfo.fnDestination            = wxFileName(strconv(ex->exinfo.szDestFileName));\r
72 \r
73 #define MyConvEI642PI(EI, strconv) \\r
74         EI * ex = (EI *) _lpEis; \\r
75         \\r
76         piInfo.fiInfo.dwAttribute       = ex->dwAttributes; \\r
77         piInfo.fiInfo.dwCRC32           = ex->dwCRC; \\r
78         piInfo.fiInfo.tmAccess          = FileTimeToWxDateTime(& ex->ftAccessTime); \\r
79         piInfo.fiInfo.tmCreate          = FileTimeToWxDateTime(& ex->ftCreateTime); \\r
80         piInfo.fiInfo.tmModify          = FileTimeToWxDateTime(& ex->ftWriteTime); \\r
81         piInfo.fiInfo.nPackedSize       = ex->llCompressedSize; \\r
82         piInfo.fiInfo.nUnpackedSize     = ex->llFileSize; \\r
83         piInfo.fiInfo.eOSType           = ex->uOSType; \\r
84         piInfo.fiInfo.wCompressRatio    = ex->wRatio; \\r
85         piInfo.fiInfo.szStoredName      = strconv(ex->exinfo.szSourceFileName); \\r
86         piInfo.fiInfo.szMethod          = strconv(ex->szMode); \\r
87         \\r
88         piInfo.nProcessedSize           = ex->llWriteSize; \\r
89         piInfo.fnDestination            = wxFileName(strconv(ex->exinfo.szDestFileName));\r
90 \r
91 #define MyConvEM322PI(EM, strconv) \\r
92         EM * ex = (EM *) _lpEis; \\r
93         if (ex->uCommand != COMMAND_EXTRACT) \\r
94         { \\r
95                 return TRUE; \\r
96         } \\r
97         \\r
98         piInfo.fiInfo.dwAttribute       = ex->dwAttributes; \\r
99         piInfo.fiInfo.dwCRC32           = ex->dwCRC; \\r
100         piInfo.fiInfo.tmAccess          = FileTimeToWxDateTime(& ex->ftAccessTime); \\r
101         piInfo.fiInfo.tmCreate          = FileTimeToWxDateTime(& ex->ftCreateTime); \\r
102         piInfo.fiInfo.tmModify          = FileTimeToWxDateTime(& ex->ftWriteTime); \\r
103         piInfo.fiInfo.nPackedSize       = ex->dwCompressedSize; \\r
104         piInfo.fiInfo.nUnpackedSize     = ex->dwOriginalSize; \\r
105         piInfo.fiInfo.eOSType           = ex->uOSType; \\r
106         piInfo.fiInfo.wCompressRatio    = ex->wRatio; \\r
107         piInfo.fiInfo.szStoredName      = strconv(ex->szFileName); \\r
108         piInfo.fiInfo.fnFileName        = wxFileName(piInfo.fiInfo.szStoredName); \\r
109         \\r
110         piInfo.fnDestination            = wxFileName(strconv(ex->szAddFileName)); \\r
111         g_prProc(TPI_NOTIFY_COMMON, & piInfo);\r
112 \r
113 #define MyConvEM642PI(EM, strconv) \\r
114         EM * ex = (EM *) _lpEis; \\r
115         if (ex->uCommand != COMMAND_EXTRACT) \\r
116         { \\r
117                 return TRUE; \\r
118         } \\r
119         \\r
120         piInfo.fiInfo.dwAttribute       = ex->dwAttributes; \\r
121         piInfo.fiInfo.dwCRC32           = ex->dwCRC; \\r
122         piInfo.fiInfo.tmAccess          = FileTimeToWxDateTime(& ex->ftAccessTime); \\r
123         piInfo.fiInfo.tmCreate          = FileTimeToWxDateTime(& ex->ftCreateTime); \\r
124         piInfo.fiInfo.tmModify          = FileTimeToWxDateTime(& ex->ftWriteTime); \\r
125         piInfo.fiInfo.nPackedSize       = ex->llCompressedSize; \\r
126         piInfo.fiInfo.nUnpackedSize     = ex->llOriginalSize; \\r
127         piInfo.fiInfo.eOSType           = ex->uOSType; \\r
128         piInfo.fiInfo.wCompressRatio    = ex->wRatio; \\r
129         piInfo.fiInfo.szStoredName      = strconv(ex->szFileName); \\r
130         piInfo.fiInfo.fnFileName        = wxFileName(piInfo.fiInfo.szStoredName); \\r
131         \\r
132         piInfo.fnDestination            = wxFileName(strconv(ex->szAddFileName)); \\r
133         g_prProc(TPI_NOTIFY_COMMON, & piInfo);\r
134 \r
135 #define MySetArcSize(api_base, var) \\r
136         fpProc = ::GetAPIAddress(#api_base L"Ex", false); \\r
137         if (fpProc != nullptr) \\r
138         { \\r
139                 ((BOOL (__stdcall *)(void *, LONGLONG *)) fpProc)(_hArchive, (LONGLONG *) & _aiInfo->var); \\r
140         } \\r
141         else \\r
142         { \\r
143                 fpProc = ::GetAPIAddress(#api_base, false); \\r
144                 if (fpProc != nullptr) \\r
145                 { \\r
146                         _aiInfo->var = ((DWORD (__stdcall *)(void *)) fpProc)(_hArchive); \\r
147                 } \\r
148         }\r
149 \r
150 #define MySetArcTime(api_base, var, ismod) \\r
151         fpProc = ::GetAPIAddress(#api_base L"64", false); \\r
152         if (fpProc != nullptr) \\r
153         { \\r
154                 ((BOOL (__stdcall *)(void *, LONGLONG *)) fpProc)(_hArchive, & ll); \\r
155                 _aiInfo->var.Set((time_t) ll); \\r
156         } \\r
157         else \\r
158         { \\r
159                 fpProc = ::GetAPIAddress(#api_base L"Ex", false); \\r
160                 if (fpProc != nullptr) \\r
161                 { \\r
162                         ((BOOL (__stdcall *)(void *, FILETIME *)) fpProc)(_hArchive, & ft); \\r
163                         _aiInfo->var = FileTimeToWxDateTime(& ft); \\r
164                 } \\r
165                 else \\r
166                 { \\r
167                         fpProc = ::GetAPIAddress(#api_base, false); \\r
168                         if (fpProc != nullptr) \\r
169                         { \\r
170                                 _aiInfo->var.Set((time_t) ((DWORD (__stdcall *)(void *)) fpProc)(_hArchive)); \\r
171                         } \\r
172                         else \\r
173                         { \\r
174                                 if (ismod) \\r
175                                 { \\r
176                                         fpProc = ::GetAPIAddress("GetArcDate", false); \\r
177                                         WORD wDate = fpProc == nullptr ? 0 : ((WORD (__stdcall *)(void *)) fpProc)(_hArchive); \\r
178                                         fpProc = ::GetAPIAddress("GetArcTime", false); \\r
179                                         WORD wTime = fpProc == nullptr ? 0 : ((WORD (__stdcall *)(void *)) fpProc)(_hArchive); \\r
180                                         _aiInfo->var.SetFromDOS(MAKELONG(wTime, wDate)); \\r
181                                 } \\r
182                         } \\r
183                 } \\r
184         }\r
185 \r
186 #define GetAPIAddress(name, unicode) GetProcAddress(g_LibInfo.hLib, (g_LibInfo.szPrefix + wxT(name) + ((unicode && g_LibInfo.fUnicode) ? wxT("W") : wxEmptyString)).char_str())\r
187 #define GetAPIAddressAlt(name, unicode) GetProcAddress(g_LibInfoAlt.hLib, (g_LibInfoAlt.szPrefix + wxT(name) + ((unicode && g_LibInfoAlt.fUnicode) ? wxT("W") : wxEmptyString)).char_str())\r
188 \r
189 //******************************************************************************\r
190 //    Callback Wrapper\r
191 //******************************************************************************\r
192 \r
193 BOOL __stdcall CallbackProc(HWND, unsigned int _uMsg, unsigned int _uState, void * _lpEis)\r
194 {\r
195         static unsigned int uWM = ::RegisterWindowMessage(WM_ARCEXTRACT);\r
196         if (_uMsg != uWM)\r
197         {\r
198                 // 独自仕様などに対する予備コード。\r
199                 return TRUE;\r
200         }\r
201 \r
202         // 構造体を初期化。\r
203         TPI_PROCESSINFO piInfo;\r
204         piInfo.eMessage = TPI_MESSAGE_STATUS;\r
205 \r
206         if (_lpEis != nullptr)\r
207         {\r
208                 if ((g_LibInfo.fRunning && g_LibInfo.fCallback32bit) || (g_LibInfoAlt.fRunning && g_LibInfoAlt.fCallback32bit))\r
209                 {\r
210                         if ((g_LibInfo.fRunning && g_LibInfo.fUnicode) || (g_LibInfoAlt.fRunning && g_LibInfoAlt.fUnicode))\r
211                         {\r
212                                 // EXTRACTINGINFOEXW -> TPI_PROCESSINFO変換。\r
213                                 MyConvEI322PI(EXTRACTINGINFOEXW, WC2String);\r
214                         }\r
215                         else\r
216                         {\r
217                                 // EXTRACTINGINFOEX -> TPI_PROCESSINFO変換。\r
218                                 MyConvEI322PI(EXTRACTINGINFOEX, UTF82String);\r
219                         }\r
220                         piInfo.fiInfo.dwAttribute       = 0;\r
221                 }\r
222                 else\r
223                 {\r
224                         if ((g_LibInfo.fRunning && g_LibInfo.fUnicode) || (g_LibInfoAlt.fRunning && g_LibInfoAlt.fUnicode))\r
225                         {\r
226                                 // EXTRACTINGINFOEX64W -> TPI_PROCESSINFO変換。\r
227                                 MyConvEI642PI(EXTRACTINGINFOEX64W, WC2String);\r
228                         }\r
229                         else\r
230                         {\r
231                                 // EXTRACTINGINFOEX64 -> TPI_PROCESSINFO変換。\r
232                                 MyConvEI642PI(EXTRACTINGINFOEX64, UTF82String);\r
233                         }\r
234                 }\r
235                 piInfo.fiInfo.fnFileName        = wxFileName(piInfo.fiInfo.szStoredName);\r
236         }\r
237 \r
238         // 数字の順でなく処理の順で並んでいることに注意。\r
239         switch (_uState)\r
240         {\r
241         case ARCEXTRACT_OPEN:\r
242                 // 当該書庫の処理を開始。\r
243                 piInfo.eStatus = TPI_STATUS_OPENARCHIVE;\r
244                 break;\r
245         case 5:\r
246                 // 当該ファイルの検索中。\r
247                 piInfo.eStatus = TPI_STATUS_SEEKFILE;\r
248                 break;\r
249         case ARCEXTRACT_BEGIN:\r
250                 // 当該ファイルの処理を開始。\r
251                 piInfo.eStatus = TPI_STATUS_BEGINPROCESS;\r
252                 break;\r
253         case ARCEXTRACT_INPROCESS:\r
254                 // 当該ファイルの処理を実行中。\r
255                 piInfo.eStatus = TPI_STATUS_INPROCESS;\r
256                 break;\r
257         case 6:\r
258                 // 当該ファイルの処理を終了。\r
259                 piInfo.eStatus = TPI_STATUS_ENDPROCESS;\r
260                 break;\r
261         case 7:\r
262                 // 当該書庫の検査中。\r
263                 piInfo.eStatus = TPI_STATUS_TESTARCHIVE;\r
264                 break;\r
265         case ARCEXTRACT_COPY:\r
266                 // 当該書庫の書き戻し中。\r
267                 piInfo.eStatus = TPI_STATUS_COPYARCHIVE;\r
268                 break;\r
269         case ARCEXTRACT_END:\r
270                 // 当該書庫の処理を終了。\r
271                 piInfo.eStatus = TPI_STATUS_CLOSEARCHIVE;\r
272                 break;\r
273         }\r
274 \r
275         // コールバック関数に送信。\r
276         if (g_prProc == nullptr)\r
277         {\r
278                 return TRUE;\r
279         }\r
280 \r
281         return g_prProc(TPI_NOTIFY_COMMON, & piInfo) != TPI_CALLBACK_CANCEL;\r
282 }\r
283 \r
284 BOOL __stdcall EnumMembersProc(void * _lpEis)\r
285 {\r
286         // 構造体を初期化。\r
287         TPI_PROCESSINFO piInfo;\r
288         piInfo.eMessage = TPI_MESSAGE_ASK;\r
289         piInfo.eStatus  = TPI_PARAM_DEST;\r
290         if (g_prProc == nullptr)\r
291         {\r
292                 return TRUE;\r
293         }\r
294 \r
295         if (_lpEis != nullptr)\r
296         {\r
297                 if ((g_LibInfo.fRunning && g_LibInfo.fCallback32bit) || (g_LibInfoAlt.fRunning && g_LibInfoAlt.fCallback32bit))\r
298                 {\r
299                         if ((g_LibInfo.fRunning && g_LibInfo.fUnicode) || (g_LibInfoAlt.fRunning && g_LibInfoAlt.fUnicode))\r
300                         {\r
301                                 // ENUM_MEMBER_INFOW -> TPI_FILEINFO変換。\r
302                                 MyConvEM322PI(ENUM_MEMBER_INFOW, WC2String);\r
303                                 wcsncpy(ex->szAddFileName, piInfo.fnDestination.GetFullPath().c_str(), FNAME_MAX32);\r
304                         }\r
305                         else\r
306                         {\r
307                                 // ENUM_MEMBER_INFO -> TPI_FILEINFO変換。\r
308                                 MyConvEM322PI(ENUM_MEMBER_INFO, UTF82String);\r
309                                 strncpy(ex->szAddFileName, piInfo.fnDestination.GetFullPath().ToUTF8(), FNAME_MAX32);\r
310                         }\r
311                 }\r
312                 else\r
313                 {\r
314                         if ((g_LibInfo.fRunning && g_LibInfo.fUnicode) || (g_LibInfoAlt.fRunning && g_LibInfoAlt.fUnicode))\r
315                         {\r
316                                 // ENUM_MEMBER_INFO64W -> TPI_FILEINFO変換。\r
317                                 MyConvEM642PI(ENUM_MEMBER_INFO64W, WC2String);\r
318                                 wcsncpy(ex->szAddFileName, piInfo.fnDestination.GetFullPath().c_str(), FNAME_MAX32);\r
319                         }\r
320                         else\r
321                         {\r
322                                 // ENUM_MEMBER_INFO64 -> TPI_FILEINFO変換。\r
323                                 MyConvEM642PI(ENUM_MEMBER_INFO64, UTF82String);\r
324                                 strncpy(ex->szAddFileName, piInfo.fnDestination.GetFullPath().ToUTF8(), FNAME_MAX32);\r
325                         }\r
326                 }\r
327         }\r
328 \r
329         return piInfo.fnDestination.IsOk();\r
330 }\r
331 \r
332 //******************************************************************************\r
333 //    Inside Functions\r
334 //******************************************************************************\r
335 \r
336 int ErrorCodeConvert(int nErrorCode)\r
337 {\r
338         switch (nErrorCode)\r
339         {\r
340         case 0:                     return TPI_ERROR_SUCCESS;\r
341         case -1:                                        return TPI_ERROR_S_ENDOFDATA;\r
342         case ERROR_DISK_SPACE:      return TPI_ERROR_IO_ARC_WRITE;\r
343         case ERROR_READ_ONLY:       return TPI_ERROR_IO_FILE_WRITE;\r
344         case ERROR_USER_SKIP:       return TPI_ERROR_D_SKIPPED;\r
345         case ERROR_UNKNOWN_TYPE:    return TPI_ERROR_IO_MISC;\r
346         case ERROR_METHOD:          return TPI_ERROR_ARC_UNSUPPORTED;\r
347         case ERROR_PASSWORD_FILE:   return TPI_ERROR_ARC_ENCRYPTED;\r
348         case ERROR_VERSION:         return TPI_ERROR_ARC_UNSUPPORTED;\r
349         case ERROR_FILE_CRC:        return TPI_ERROR_ARC_BROKEN_SUM;\r
350         case ERROR_FILE_OPEN:       return TPI_ERROR_IO_FILE_OPEN;\r
351         case ERROR_MORE_FRESH:      return TPI_ERROR_IO_FILE_MISC;\r
352         case ERROR_NOT_EXIST:       return TPI_ERROR_IO_FILE_ACCESS;\r
353         case ERROR_ALREADY_EXIST:   return TPI_ERROR_IO_FILE_ACCESS;\r
354         case ERROR_TOO_MANY_FILES:  return TPI_ERROR_IO_ARC_MISC;\r
355         case ERROR_MAKEDIRECTORY:   return TPI_ERROR_IO_DIR_OPEN;\r
356         case ERROR_CANNOT_WRITE:    return TPI_ERROR_IO_FILE_WRITE;\r
357         case ERROR_HUFFMAN_CODE:    return TPI_ERROR_ARC_BROKEN_MISC;\r
358         case ERROR_COMMENT_HEADER:  return TPI_ERROR_ARC_BROKEN_HEADER;\r
359         case ERROR_HEADER_CRC:      return TPI_ERROR_ARC_BROKEN_SUM;\r
360         case ERROR_HEADER_BROKEN:   return TPI_ERROR_ARC_BROKEN_HEADER;\r
361         case ERROR_ARC_FILE_OPEN:   return TPI_ERROR_IO_ARC_OPEN;\r
362         case ERROR_NOT_ARC_FILE:    return TPI_ERROR_D_UNSUPPORTED;\r
363         case ERROR_CANNOT_READ:     return TPI_ERROR_IO_ARC_READ;\r
364         case ERROR_FILE_STYLE:      return TPI_ERROR_D_UNSUPPORTED;\r
365         case ERROR_COMMAND_NAME:    return TPI_ERROR_UNDEFINED;\r
366         case ERROR_MORE_HEAP_MEMORY:return TPI_ERROR_D_OUTOFMEMORY;\r
367         case ERROR_ENOUGH_MEMORY:   return TPI_ERROR_D_OUTOFMEMORY;\r
368         case ERROR_ALREADY_RUNNING: return TPI_ERROR_UNDEFINED;\r
369         case ERROR_USER_CANCEL:     return TPI_ERROR_D_SKIPPED;\r
370         case ERROR_HARC_ISNOT_OPENED: return TPI_ERROR_D_PARAMETER;\r
371         case ERROR_NOT_SEARCH_MODE: return TPI_ERROR_D_PARAMETER;\r
372         case ERROR_NOT_SUPPORT:     return TPI_ERROR_U_USE_LIBRARY;\r
373         case ERROR_TIME_STAMP:      return TPI_ERROR_UNDEFINED;\r
374         case ERROR_TMP_OPEN:        return TPI_ERROR_IO_TMP_OPEN;\r
375         case ERROR_LONG_FILE_NAME:  return TPI_ERROR_IO_FILE_ACCESS;\r
376         case ERROR_ARC_READ_ONLY:   return TPI_ERROR_IO_ARC_ACCESS;\r
377         case ERROR_SAME_NAME_FILE:  return TPI_ERROR_UNDEFINED;\r
378         case ERROR_NOT_FIND_ARC_FILE: return TPI_ERROR_IO_ARC_NOTFOUND;\r
379         case ERROR_RESPONSE_READ:   return TPI_ERROR_IO_MISC_READ;\r
380         case ERROR_NOT_FILENAME:    return TPI_ERROR_IO_FILE_NOTFOUND;\r
381         case ERROR_TMP_COPY:        return TPI_ERROR_IO_TMP_COPY;\r
382         case ERROR_EOF:             return TPI_ERROR_ARC_BROKEN_SIZE;\r
383         case ERROR_ADD_TO_LARC:     return TPI_ERROR_UNDEFINED;\r
384         case ERROR_TMP_BACK_SPACE:  return TPI_ERROR_IO_TMP_MOVE;\r
385         case ERROR_SHARING:         return TPI_ERROR_IO_FILE_ACCESS;\r
386         case ERROR_NOT_FIND_FILE:   return TPI_ERROR_IO_NOTFOUND;\r
387         case ERROR_LOG_FILE:        return TPI_ERROR_IO_MISC_WRITE;\r
388         case ERROR_NO_DEVICE:       return TPI_ERROR_IO_FILE_ACCESS;\r
389         case ERROR_GET_ATTRIBUTES:  return TPI_ERROR_IO_FILE_GETINFO;\r
390         case ERROR_SET_ATTRIBUTES:  return TPI_ERROR_IO_FILE_SETINFO;\r
391         case ERROR_GET_INFORMATION: return TPI_ERROR_IO_FILE_GETINFO;\r
392         case ERROR_GET_POINT:       return TPI_ERROR_IO_FILE_POINT;\r
393         case ERROR_SET_POINT:       return TPI_ERROR_IO_FILE_POINT;\r
394         case ERROR_CONVERT_TIME:    return TPI_ERROR_UNDEFINED;\r
395         case ERROR_GET_TIME:        return TPI_ERROR_IO_FILE_GETINFO;\r
396         case ERROR_SET_TIME:        return TPI_ERROR_IO_FILE_SETINFO;\r
397         case ERROR_CLOSE_FILE:      return TPI_ERROR_IO_FILE_CLOSE;\r
398         case ERROR_HEAP_MEMORY:     return TPI_ERROR_D_USEMEMORY;\r
399         case ERROR_HANDLE:          return TPI_ERROR_UNDEFINED;\r
400         case ERROR_TIME_STAMP_RANGE:return TPI_ERROR_UNDEFINED;\r
401         case ERROR_MAKE_ARCHIVE:    return TPI_ERROR_ARC_BROKEN_MISC;\r
402         case ERROR_NOT_CONFIRM_NAME:return TPI_ERROR_ARC_BROKEN_HEADER;\r
403         case ERROR_UNEXPECTED_EOF:  return TPI_ERROR_ARC_BROKEN_HEADER;\r
404         case ERROR_INVALID_END_MARK:return TPI_ERROR_ARC_BROKEN_SIZE;\r
405         case ERROR_INVOLVED_LZH:    return TPI_ERROR_ARC_BROKEN_MISC;\r
406         case ERROR_NO_END_MARK:     return TPI_ERROR_ARC_BROKEN_SIZE;\r
407         case ERROR_HDR_INVALID_SIZE:return TPI_ERROR_ARC_BROKEN_HEADER;\r
408         case ERROR_UNKNOWN_LEVEL:   return TPI_ERROR_ARC_UNSUPPORTED;\r
409         case ERROR_BROKEN_DATA:     return TPI_ERROR_ARC_BROKEN_MISC;\r
410         case ERROR_INVALID_PATH:    return TPI_ERROR_ARC_DANGER;\r
411         case ERROR_TOO_BIG:         return TPI_ERROR_IO_FILE_WRITE;\r
412         case ERROR_EXECUTABLE_FILE: return TPI_ERROR_ARC_DANGER;\r
413         case ERROR_INVALID_VALUE:   return TPI_ERROR_UNDEFINED;\r
414         case ERROR_HDR_EXPLOIT:     return TPI_ERROR_ARC_DANGER;\r
415         case ERROR_HDR_NO_CRC:      return TPI_ERROR_ARC_BROKEN_HEADER;\r
416         case ERROR_HDR_NO_NAME:     return TPI_ERROR_ARC_BROKEN_HEADER;\r
417         default:                    return TPI_ERROR_UNDEFINED;\r
418         }\r
419 }\r
420 \r
421 int CalSetCallbackProc(bool fAlt)\r
422 {\r
423         // 先にコールバック関数の設定を解除しておく。\r
424         FARPROC fpProc;\r
425         if (fAlt)\r
426         {\r
427                 fpProc = ::GetAPIAddressAlt("KillOwnerWindowEx64", false);\r
428                 g_LibInfoAlt.fCallback32bit = fpProc == nullptr;\r
429                 if (g_LibInfoAlt.fCallback32bit)\r
430                 {\r
431                         fpProc = ::GetAPIAddressAlt("KillOwnerWindowEx", false);\r
432                 }\r
433         }\r
434         else\r
435         {\r
436                 fpProc = ::GetAPIAddress("KillOwnerWindowEx64", false);\r
437                 g_LibInfo.fCallback32bit = fpProc == nullptr;\r
438                 if (g_LibInfo.fCallback32bit)\r
439                 {\r
440                         fpProc = ::GetAPIAddress("KillOwnerWindowEx", false);\r
441                 }\r
442         }\r
443         if (fpProc == nullptr)\r
444         {\r
445                 return TPI_ERROR_U_USE_LIBRARY;\r
446         }\r
447         // エラーでも無視する。\r
448         ((BOOL (__stdcall *)(HWND)) fpProc)(nullptr);\r
449 \r
450         // 続いてコールバック関数の設定。\r
451         if (fAlt)\r
452         {\r
453                 fpProc = ::GetAPIAddressAlt("SetOwnerWindowEx64", false);\r
454                 g_LibInfoAlt.fCallback32bit = fpProc == nullptr;\r
455                 if (g_LibInfoAlt.fCallback32bit)\r
456                 {\r
457                         fpProc = ::GetAPIAddressAlt("SetOwnerWindowEx", true);\r
458                 }\r
459         }\r
460         else\r
461         {\r
462                 fpProc = ::GetAPIAddress("SetOwnerWindowEx64", false);\r
463                 g_LibInfo.fCallback32bit = fpProc == nullptr;\r
464                 if (g_LibInfo.fCallback32bit)\r
465                 {\r
466                         fpProc = ::GetAPIAddress("SetOwnerWindowEx", true);\r
467                 }\r
468         }\r
469 \r
470         if (fpProc == nullptr || ! ((fAlt ? g_LibInfoAlt.fCallback32bit : g_LibInfo.fCallback32bit)\r
471                 ? ((BOOL (__stdcall *)(HWND, ARCHIVERPROC *       )) fpProc)(nullptr, (ARCHIVERPROC *) CallbackProc)\r
472                 : ((BOOL (__stdcall *)(HWND, ARCHIVERPROC *, DWORD)) fpProc)(nullptr, (ARCHIVERPROC *) CallbackProc, (fAlt ? g_LibInfoAlt.fUnicode : g_LibInfo.fUnicode) ? sizeof(EXTRACTINGINFOEX64W) : sizeof(EXTRACTINGINFOEX64))))\r
473         {\r
474                 return TPI_ERROR_U_USE_LIBRARY;\r
475         }\r
476 \r
477         // EnumMembersProc系。\r
478         if (fAlt)\r
479         {\r
480                 fpProc = ::GetAPIAddressAlt("ClearEnumMembersProc64", false);\r
481                 g_LibInfoAlt.fCallback32bit = fpProc == nullptr;\r
482                 if (g_LibInfoAlt.fCallback32bit)\r
483                 {\r
484                         fpProc = ::GetAPIAddressAlt("ClearEnumMembersProc", false);\r
485                 }\r
486         }\r
487         else\r
488         {\r
489                 fpProc = ::GetAPIAddress("ClearEnumMembersProc64", false);\r
490                 g_LibInfo.fCallback32bit = fpProc == nullptr;\r
491                 if (g_LibInfo.fCallback32bit)\r
492                 {\r
493                         fpProc = ::GetAPIAddress("ClearEnumMembersProc", false);\r
494                 }\r
495         }\r
496         if (fpProc == nullptr)\r
497         {\r
498                 return TPI_ERROR_U_USE_LIBRARY;\r
499         }\r
500         // エラーでも無視する。\r
501 //      ((BOOL (__stdcall *)(void)) fpProc)();\r
502 \r
503         // 続いて設定。\r
504         if (fAlt)\r
505         {\r
506                 fpProc = ::GetAPIAddressAlt("SetEnumMembersProc64", false);\r
507                 g_LibInfoAlt.fCallback32bit = fpProc == nullptr;\r
508                 if (g_LibInfoAlt.fCallback32bit)\r
509                 {\r
510                         fpProc = ::GetAPIAddressAlt("SetEnumMembersProc", true);\r
511                 }\r
512         }\r
513         else\r
514         {\r
515                 fpProc = ::GetAPIAddress("SetEnumMembersProc64", false);\r
516                 g_LibInfo.fCallback32bit = fpProc == nullptr;\r
517                 if (g_LibInfo.fCallback32bit)\r
518                 {\r
519                         fpProc = ::GetAPIAddress("SetEnumMembersProc", true);\r
520                 }\r
521         }\r
522 \r
523         return (fpProc == nullptr || ! ((fAlt ? g_LibInfoAlt.fCallback32bit : g_LibInfo.fCallback32bit)\r
524                 ? ((BOOL (__stdcall *)(WND_ENUMMEMBPROC *       )) fpProc)((WND_ENUMMEMBPROC *) EnumMembersProc)\r
525                 : ((BOOL (__stdcall *)(WND_ENUMMEMBPROC *, DWORD)) fpProc)((WND_ENUMMEMBPROC *) EnumMembersProc, (fAlt ? g_LibInfoAlt.fUnicode : g_LibInfo.fUnicode) ? sizeof(ENUM_MEMBER_INFO64W) : sizeof(ENUM_MEMBER_INFO))))\r
526                 ? TPI_ERROR_U_USE_LIBRARY : TPI_ERROR_SUCCESS;\r
527 }\r
528 \r
529 //******************************************************************************\r
530 //    Functions\r
531 //******************************************************************************\r
532 \r
533 #ifdef __cplusplus\r
534 extern "C"\r
535 {\r
536 #endif\r
537 \r
538 int __stdcall GetPluginInformation\r
539 (\r
540         unsigned int _uInfoId,\r
541         wxULongLong_t,\r
542         void * _pPtr\r
543 )\r
544 {\r
545         if (_pPtr == nullptr)\r
546         {\r
547                 return TPI_ERROR_D_PARAMETER;\r
548         }\r
549         switch (_uInfoId)\r
550         {\r
551         case TPI_INFO_VERSION_MAJOR:\r
552         case TPI_INFO_VERSION_MINOR:\r
553                 * (int *) _pPtr = 0;\r
554                 break;\r
555         case TPI_INFO_VERSION_API:\r
556                 * (int *) _pPtr = 2;\r
557                 break;\r
558         case TPI_INFO_HANDLE_ON_COMMAND:\r
559                 * (int *) _pPtr = 0;\r
560                 break;\r
561         default:\r
562                 return TPI_ERROR_D_UNSUPPORTED;\r
563         }\r
564         return TPI_ERROR_SUCCESS;\r
565 }\r
566 \r
567 int __stdcall GetFormatInformation(TPI_FORMATINFO * _fiInfo, bool _bFirst)\r
568 {\r
569         static wxULongLong_t s_nFileId;\r
570         static wxXmlDocument xmlDoc(myMakeXMLName(wxT("calLibrary")));\r
571         static wxXmlNode * xmlLibrary;\r
572         if (_bFirst)\r
573         {\r
574                 // xml解析開始。\r
575                 s_nFileId = 0;\r
576                 xmlLibrary = myGetFirstLib(& xmlDoc);\r
577         }\r
578         else\r
579         {\r
580                 xmlLibrary = myGetNextLib(xmlLibrary);\r
581         }\r
582         if (xmlLibrary == nullptr)\r
583         {\r
584                 // データの終端に達した場合。\r
585                 return TPI_ERROR_S_ENDOFDATA;\r
586         }\r
587 \r
588         MakeFormatInfo(xmlLibrary, wxT("calLibrary"), _fiInfo, s_nFileId++);\r
589         HMODULE hLib = ::LoadLibrary(_fiInfo->szEngineName.wchar_str());\r
590         if (hLib == nullptr)\r
591         {\r
592                 _fiInfo->eSupportedCommand = 0;\r
593         }\r
594         else\r
595         {\r
596                 ::FreeLibrary(hLib);\r
597         }\r
598         return TPI_ERROR_SUCCESS;\r
599 }\r
600 \r
601 int __stdcall LoadPlugin\r
602 (\r
603         const wxString & _szArcName,\r
604         TPI_PROC _prProc,\r
605         wxULongLong_t _nTypeId\r
606 )\r
607 {\r
608         // xml解析開始。\r
609         wxXmlDocument xmlDoc(myMakeXMLName(wxT("calLibrary")));\r
610         wxXmlNode * xmlLibrary;\r
611 \r
612         // 対象が存在するならば対応するライブラリを調査、\r
613         // 対象が存在しないならば指示されたライブラリをロード。\r
614         // 対象が空文字列なら処理を終了。\r
615         ::RemoveCwdFromSearchPath();\r
616         if (_szArcName.IsEmpty())\r
617         {\r
618                 return TPI_ERROR_SUCCESS;\r
619         }\r
620         if (! ::wxFileExists(_szArcName))\r
621         {\r
622                 xmlLibrary = myGetFirstLib(& xmlDoc, _nTypeId);\r
623                 if (xmlLibrary == nullptr)\r
624                 {\r
625                         // xml文法エラー。\r
626                         return TPI_ERROR_UNDEFINED;\r
627                 }\r
628 \r
629                 // ライブラリをロード。\r
630                 g_LibInfo.hLib = ::LoadLibrary(xmlLibrary->GetAttribute(wxT("name"), wxEmptyString).wchar_str());\r
631                 if (g_LibInfo.hLib == nullptr)\r
632                 {\r
633                         return TPI_ERROR_U_LOAD_LIBRARY;\r
634                 }\r
635                 g_LibInfo.szPrefix = xmlLibrary->GetAttribute(wxT("prefix"), wxEmptyString);\r
636                 g_LibInfo.fUnicode = myGetAttributeBool(xmlLibrary, wxT("unicode"));\r
637                 g_LibInfo.node = * xmlLibrary;\r
638                 g_LibInfo.nLibIndex = _nTypeId;\r
639 \r
640                 // 代替ライブラリもロード。ロードできなくてもエラーにはしない。\r
641                 g_LibInfoAlt.szPrefix = xmlLibrary->GetAttribute(wxT("prefix-alt"), wxEmptyString);\r
642                 g_LibInfoAlt.fUnicode = myGetAttributeBool(xmlLibrary, wxT("unicode-alt"));\r
643                 g_LibInfoAlt.hLib = ::LoadLibrary(xmlLibrary->GetAttribute(wxT("name-alt"), wxEmptyString).wchar_str());\r
644 \r
645                 // コールバック関数を設定。\r
646                 if (_prProc != nullptr)\r
647                 {\r
648                         g_prProc = * _prProc;\r
649                         CalSetCallbackProc(true);\r
650                         CalSetCallbackProc(false);\r
651                 }\r
652                 return TPI_ERROR_SUCCESS;\r
653         }\r
654 \r
655         // 無限ループに陥らないよう上限を設定。\r
656         xmlLibrary = myGetFirstLib(& xmlDoc);\r
657         for (g_LibInfo.nLibIndex = 0; g_LibInfo.nLibIndex < 300 && xmlLibrary != nullptr; g_LibInfo.nLibIndex++)\r
658         {\r
659                 // ライブラリをロード。\r
660                 g_LibInfo.hLib = ::LoadLibrary(xmlLibrary->GetAttribute(wxT("name"), wxEmptyString).wchar_str());\r
661                 if (g_LibInfo.hLib == nullptr)\r
662                 {\r
663                         xmlLibrary = myGetNextLib(xmlLibrary);\r
664                         continue;\r
665                 }\r
666                 g_LibInfo.szPrefix = xmlLibrary->GetAttribute(wxT("prefix"), wxEmptyString);\r
667                 g_LibInfo.fUnicode = myGetAttributeBool(xmlLibrary, wxT("unicode"));\r
668                 g_LibInfo.node = * xmlLibrary;\r
669 \r
670                 // 代替ライブラリもロード。ロードできなくてもエラーにはしない。\r
671                 g_LibInfoAlt.szPrefix = xmlLibrary->GetAttribute(wxT("prefix-alt"), wxEmptyString);\r
672                 g_LibInfoAlt.fUnicode = myGetAttributeBool(xmlLibrary, wxT("unicode-alt"));\r
673                 g_LibInfoAlt.hLib = ::LoadLibrary(xmlLibrary->GetAttribute(wxT("name-alt"), wxEmptyString).wchar_str());\r
674 \r
675                 // Unicodeモードに設定。\r
676                 FARPROC fpProc = ::GetAPIAddress("SetUnicodeMode", false);\r
677                 if (fpProc != nullptr)\r
678                 {\r
679                         ((BOOL (__stdcall *)(BOOL)) fpProc)(TRUE);\r
680                 }\r
681 \r
682                 // 書庫に対応しているかチェック。\r
683                 fpProc = ::GetAPIAddress("CheckArchive", true);\r
684                 if (fpProc != nullptr && (g_LibInfo.fUnicode\r
685                                 ? ((BOOL (__stdcall *)(const wchar_t *, const int)) fpProc)(_szArcName.wchar_str(), 0)\r
686                                 : ((BOOL (__stdcall *)(const char    *, const int)) fpProc)(_szArcName.ToUTF8(),    0)))\r
687                 {\r
688                         // コールバック関数を設定。\r
689                         if (_prProc != nullptr)\r
690                         {\r
691                                 g_prProc = * _prProc;\r
692                                 CalSetCallbackProc(true);\r
693                                 CalSetCallbackProc(false);\r
694                         }\r
695                         return TPI_ERROR_SUCCESS;\r
696                 }\r
697                 ::FreeLibrary(g_LibInfo.hLib);\r
698                 ::FreeLibrary(g_LibInfoAlt.hLib);\r
699                 xmlLibrary = myGetNextLib(xmlLibrary);\r
700         }\r
701         return TPI_ERROR_U_LOAD_LIBRARY;\r
702 }\r
703 \r
704 int __stdcall FreePlugin\r
705 (\r
706         void * // _pReserved\r
707 )\r
708 {\r
709         ::FreeLibrary(g_LibInfo.hLib);\r
710         ::FreeLibrary(g_LibInfoAlt.hLib);\r
711         return TPI_ERROR_SUCCESS;\r
712 }\r
713 \r
714 int __stdcall OpenArchive\r
715 (\r
716         const wxString & _szArcName,\r
717         void * * _hArchive,\r
718         wxULongLong_t * _nFileCount\r
719 )\r
720 {\r
721         // ファイル数を取得。\r
722         FARPROC fpProc;\r
723         if (_nFileCount != nullptr)\r
724         {\r
725                 fpProc = ::GetAPIAddress("GetFileCount", true);\r
726                 if (fpProc != nullptr)\r
727                 {\r
728                         int n = g_LibInfo.fUnicode\r
729                                 ? ((int (__stdcall *)(const wchar_t *)) fpProc)(_szArcName.wchar_str())\r
730                                 : ((int (__stdcall *)(const char    *)) fpProc)(_szArcName.ToUTF8());\r
731                         * _nFileCount = n < 0 ? 0 : n;\r
732                 }\r
733         }\r
734 \r
735         fpProc = ::GetAPIAddress("OpenArchive", true);\r
736         if (fpProc == nullptr)\r
737         {\r
738                 return TPI_ERROR_U_USE_LIBRARY;\r
739         }\r
740 \r
741         * _hArchive = g_LibInfo.fUnicode\r
742                 ? ((void * (__stdcall *)(const HWND, const wchar_t *, const DWORD)) fpProc)(nullptr, _szArcName.wchar_str(), 0)\r
743                 : ((void * (__stdcall *)(const HWND, const char    *, const DWORD)) fpProc)(nullptr, _szArcName.ToUTF8(),  0);\r
744         return _hArchive == nullptr ? TPI_ERROR_UNDEFINED : TPI_ERROR_SUCCESS;\r
745 }\r
746 \r
747 int __stdcall CloseArchive\r
748 (\r
749         void * _hArchive\r
750 )\r
751 {\r
752         FARPROC fpProc = ::GetAPIAddress("CloseArchive", false);\r
753         return fpProc == nullptr ? TPI_ERROR_U_USE_LIBRARY : ErrorCodeConvert(((int (__stdcall *)(void *)) fpProc)(_hArchive));\r
754 }\r
755 \r
756 int __stdcall GetFileInformation\r
757 (\r
758         void * _hArchive,\r
759         TPI_FILEINFO * _fiInfo,\r
760         bool _bFirst\r
761 )\r
762 {\r
763         static wxULongLong_t s_nFileId;\r
764         static FARPROC fpNext, fpAttr, fpName;\r
765         int nErrorCode;\r
766         INDIVIDUALINFO iiInfo;\r
767         INDIVIDUALINFOW iiInfoW;\r
768         memset(& iiInfo,  0, sizeof(iiInfo));\r
769         memset(& iiInfoW, 0, sizeof(iiInfoW));\r
770 \r
771         if (_bFirst)\r
772         {\r
773                 s_nFileId = 0;\r
774                 FARPROC fpProc = ::GetAPIAddress("FindFirst", true);\r
775                 fpNext = ::GetAPIAddress("FindNext", true);\r
776                 fpAttr = ::GetAPIAddress("GetAttribute", false);\r
777                 fpName = ::GetAPIAddress("GetFileName", true);\r
778                 if (fpProc == nullptr)\r
779                 {\r
780                         return TPI_ERROR_U_USE_LIBRARY;\r
781                 }\r
782 \r
783                 nErrorCode = g_LibInfo.fUnicode\r
784                         ? ((int (__stdcall *)(void *, const wchar_t *, LPINDIVIDUALINFOW)) fpProc)(_hArchive, L"*", & iiInfoW)\r
785                         : ((int (__stdcall *)(void *, const char *,    LPINDIVIDUALINFO))  fpProc)(_hArchive,  "*", & iiInfo);\r
786         }\r
787         else\r
788         {\r
789                 if (fpNext == nullptr)\r
790                 {\r
791                         return TPI_ERROR_U_USE_LIBRARY;\r
792                 }\r
793 \r
794                 nErrorCode = g_LibInfo.fUnicode\r
795                         ? ((int (__stdcall *)(void *, LPINDIVIDUALINFOW)) fpNext)(_hArchive, & iiInfoW)\r
796                         : ((int (__stdcall *)(void *, LPINDIVIDUALINFO))  fpNext)(_hArchive, & iiInfo);\r
797         }\r
798 \r
799         nErrorCode = ErrorCodeConvert(nErrorCode);\r
800         if (nErrorCode == TPI_ERROR_SUCCESS)\r
801         {\r
802                 _fiInfo->dwAttribute = (fpAttr == nullptr) ? 0 : ((int (__stdcall *)(void *)) fpAttr)(_hArchive);\r
803                 if (_fiInfo->dwAttribute == (unsigned) -1)\r
804                 {\r
805                         _fiInfo->dwAttribute = 0;\r
806                 }\r
807 \r
808                 if (g_LibInfo.fUnicode)\r
809                 {\r
810                         _fiInfo->dwCRC32        = iiInfoW.dwCRC;\r
811                         _fiInfo->eOSType        = iiInfoW.uOSType;\r
812                         _fiInfo->nPackedSize    = iiInfoW.dwCompressedSize;\r
813                         _fiInfo->nUnpackedSize  = iiInfoW.dwOriginalSize;\r
814                         _fiInfo->tmModify.SetFromDOS(MAKELONG(iiInfoW.wTime, iiInfoW.wDate));\r
815                         _fiInfo->szStoredName   = WC2String(iiInfoW.szFileName);\r
816                         if (wcslen(iiInfoW.szFileName) >= 510 && fpName)\r
817                         {\r
818                                 ((int (__stdcall *)(void *, wchar_t *, const int)) fpName)(_hArchive, wxStringBuffer(_fiInfo->szStoredName, 32769), 32768);\r
819                         }\r
820                         _fiInfo->szMethod       = WC2String(iiInfoW.szMode);\r
821                         _fiInfo->wCompressRatio = iiInfoW.wRatio;\r
822                 }\r
823                 else\r
824                 {\r
825                         _fiInfo->dwCRC32        = iiInfo.dwCRC;\r
826                         _fiInfo->eOSType        = iiInfo.uOSType;\r
827                         _fiInfo->nPackedSize    = iiInfo.dwCompressedSize;\r
828                         _fiInfo->nUnpackedSize  = iiInfo.dwOriginalSize;\r
829                         _fiInfo->tmModify.SetFromDOS(MAKELONG(iiInfo.wTime, iiInfo.wDate));\r
830                         _fiInfo->szStoredName   = UTF82String(iiInfo.szFileName);\r
831                         if (strlen(iiInfo.szFileName) >= 510 && fpName)\r
832                         {\r
833                                 char * sz = (char *) malloc(32769);\r
834                                 memset(sz, 0, 32769);\r
835                                 ((int (__stdcall *)(void *, char *, const int)) fpName)(_hArchive, sz, 32768);\r
836                                 _fiInfo->szStoredName = UTF82String(sz);\r
837                                 free(sz);\r
838                         }\r
839                         _fiInfo->szMethod       = UTF82String(iiInfo.szMode);\r
840                         _fiInfo->wCompressRatio = iiInfo.wRatio;\r
841                 }\r
842                 _fiInfo->nFileId        = s_nFileId++;\r
843                 _fiInfo->fnFileName     = wxFileName(_fiInfo->szStoredName);\r
844 //              _fiInfo->ftAccessTime   = 0;\r
845 //              _fiInfo->ftCreateTime   = 0;\r
846         }\r
847 \r
848         return nErrorCode;\r
849 }\r
850 \r
851 int __stdcall GetArchiveInformation\r
852 (\r
853         void * _hArchive,\r
854         TPI_ARCHIVEINFO * _aiInfo\r
855 )\r
856 {\r
857         FARPROC fpProc = ::GetAPIAddress("GetArcFileName", true);\r
858         if (fpProc != nullptr)\r
859         {\r
860                 // TODO : ファイル名の文字数制限を撤廃。\r
861                 wxString s;\r
862                 if (g_LibInfo.fUnicode)\r
863                 {\r
864                         wchar_t sz[2049];\r
865                         memset(sz, 0, sizeof(sz));\r
866                         ((int (__stdcall *)(void *, wchar_t *, const int)) fpProc)(_hArchive, sz, 2048);\r
867                         s = WC2String(sz);\r
868                 }\r
869                 else\r
870                 {\r
871                         char sz[2049];\r
872                         memset(sz, 0, sizeof(sz));\r
873                         ((int (__stdcall *)(void *, char *, const int)) fpProc)(_hArchive, sz, 2048);\r
874                         s = UTF82String(sz);\r
875                 }\r
876                 _aiInfo->fnArchive = wxFileName(s);\r
877         }\r
878 \r
879         wxLongLong_t ll = 0;\r
880         MySetArcSize(GetArcFileSize,       nFileSize);\r
881         MySetArcSize(GetArcOriginalSize,   nUnpackedSize);\r
882         MySetArcSize(GetArcCompressedSize, nPackedSize);\r
883         MySetArcSize(GetArcReadSize,       nReadSize);\r
884         if (_aiInfo->nPackedSize == (DWORD) -1)\r
885         {\r
886                 // 圧縮後サイズの取得に対応していない場合、書庫のサイズで代替。\r
887                 _aiInfo->nPackedSize = _aiInfo->nFileSize;\r
888         }\r
889 \r
890         FILETIME ft;\r
891         MySetArcTime(GetArcAccessTime, tmAccess, false);\r
892         MySetArcTime(GetArcCreateTime, tmCreate, false);\r
893         MySetArcTime(GetArcWriteTime,  tmModify, true);\r
894 \r
895         fpProc = ::GetAPIAddress("GetArcRatio", false);\r
896         if (fpProc != nullptr)\r
897         {\r
898                 _aiInfo->wCompressRatio = ((WORD (__stdcall *)(void *)) fpProc)(_hArchive);\r
899                 if (_aiInfo->wCompressRatio == (WORD) -1)\r
900                 {\r
901                         // エラーなら0にしておく。\r
902                         _aiInfo->wCompressRatio = 0;\r
903                 }\r
904         }\r
905 \r
906         fpProc = ::GetAPIAddress("GetArcOSType", false);\r
907         if (fpProc != nullptr)\r
908         {\r
909                 _aiInfo->eOSType = ((UINT (__stdcall *)(void *)) fpProc)(_hArchive);\r
910         }\r
911 \r
912         fpProc = ::GetAPIAddress("IsSFXFile", false);\r
913         _aiInfo->fSFX = fpProc != nullptr && ((int (__stdcall *)(void *)) fpProc)(_hArchive) > 0;\r
914 \r
915         // 形式に関する情報を取得。\r
916         MakeFormatInfo(& g_LibInfo.node, wxT("calLibrary"), & _aiInfo->fiInfo, 0);\r
917 \r
918         return TPI_ERROR_SUCCESS;\r
919 }\r
920 \r
921 int __stdcall Command\r
922 (\r
923         wxULongLong_t _eCommand,\r
924         TPI_SWITCHES * _swInfo,\r
925         void *,// _hArchive,\r
926         const wxArrayString & _szFiles\r
927 )\r
928 {\r
929         // xmlからコマンドラインを取得。\r
930         wxString szPath, szCommandLine;\r
931 \r
932         // APIアドレス取得。\r
933         g_LibInfoAlt.fRunning\r
934                 = g_LibInfo.node.GetAttribute(\r
935                         _eCommand == TPI_COMMAND_CREATE  ? wxT("create-alt") :\r
936                         _eCommand == TPI_COMMAND_ADD     ? wxT("add-alt") :\r
937                         _eCommand == TPI_COMMAND_EXTRACT ? wxT("extract-alt") : \r
938                         _eCommand == TPI_COMMAND_DELETE  ? wxT("delete-alt") : \r
939                         _eCommand == TPI_COMMAND_UPDATE  ? wxT("update-alt") : \r
940                         _eCommand == TPI_COMMAND_TEST    ? wxT("test-alt") : \r
941                         _eCommand == TPI_COMMAND_REPAIR  ? wxT("repair-alt") : \r
942                         _eCommand == TPI_COMMAND_MOVE    ? wxT("move-alt") : \r
943                         _eCommand == TPI_COMMAND_SFX     ? wxT("sfx-alt") : \r
944                         _eCommand == TPI_COMMAND_UNSFX   ? wxT("unsfx-alt") : wxEmptyString, & szCommandLine);\r
945         g_LibInfo.fRunning\r
946                 = g_LibInfo.node.GetAttribute(\r
947                         _eCommand == TPI_COMMAND_CREATE  ? wxT("create") :\r
948                         _eCommand == TPI_COMMAND_ADD     ? wxT("add") :\r
949                         _eCommand == TPI_COMMAND_EXTRACT ? wxT("extract") : \r
950                         _eCommand == TPI_COMMAND_DELETE  ? wxT("delete") : \r
951                         _eCommand == TPI_COMMAND_UPDATE  ? wxT("update") : \r
952                         _eCommand == TPI_COMMAND_TEST    ? wxT("test") : \r
953                         _eCommand == TPI_COMMAND_REPAIR  ? wxT("repair") : \r
954                         _eCommand == TPI_COMMAND_MOVE    ? wxT("move") : \r
955                         _eCommand == TPI_COMMAND_SFX     ? wxT("sfx") : \r
956                         _eCommand == TPI_COMMAND_UNSFX   ? wxT("unsfx") : wxEmptyString, & szCommandLine);\r
957 \r
958         FARPROC fpProc =\r
959                 g_LibInfo.fRunning    ? ::GetAPIAddress(   "", true) :\r
960                 g_LibInfoAlt.fRunning ? ::GetAPIAddressAlt("", true) : nullptr;\r
961         if (fpProc == nullptr || szCommandLine.IsEmpty())\r
962         {\r
963                 return TPI_ERROR_U_USE_LIBRARY;\r
964         }\r
965 \r
966         // コマンドライン・レスポンスファイル作成。\r
967         wxString\r
968                 szResponceFileName = g_LibInfo.fRunning ?\r
969                         MakeResponceFile(_szFiles, myGetAttributeBool(& g_LibInfo.node,    wxT("quote-resp"), true), g_LibInfo.fUnicode) :\r
970                         MakeResponceFile(_szFiles, myGetAttributeBool(& g_LibInfoAlt.node, wxT("quote-resp"), true), g_LibInfoAlt.fUnicode),\r
971                 szCommandLineSend  = MakeCommandLineSend(szCommandLine, _swInfo, _szFiles, szResponceFileName);\r
972 \r
973         // コマンドライン実行。\r
974         int nErrorCode;\r
975         wxString szOutput;\r
976         if ((g_LibInfo.fRunning && g_LibInfo.fUnicode) || (g_LibInfoAlt.fRunning && g_LibInfoAlt.fUnicode))\r
977         {\r
978                 wchar_t szTmpOut[2049];\r
979                 nErrorCode = ((int (__stdcall *)(const HWND, const wchar_t *, wchar_t *, DWORD)) fpProc)(nullptr, szCommandLineSend.wchar_str(), szTmpOut, 2048);\r
980                 szOutput = WC2String(szTmpOut);\r
981         }\r
982         else\r
983         {\r
984                 char szTmpOut[2049];\r
985                 nErrorCode = ((int (__stdcall *)(const HWND, const char *, char *, DWORD)) fpProc)(nullptr, szCommandLineSend.ToUTF8(), szTmpOut, 2048);\r
986                 szOutput = UTF82String(szTmpOut);\r
987         }\r
988 \r
989         // レスポンスファイル削除。\r
990         ::wxRemoveFile(szResponceFileName);\r
991 \r
992         if (nErrorCode != 0)\r
993         {\r
994                 wxLogError(L"Error :\n%x\n\nCommandLine:\n%s\n\nOutput:\n%s", nErrorCode, szCommandLineSend.c_str(), szOutput.c_str());\r
995         }\r
996         return ErrorCodeConvert(nErrorCode);\r
997 }\r
998 \r
999 #ifdef __cplusplus\r
1000 }\r
1001 #endif\r