OSDN Git Service

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