1 /*******************************************************************************
\r
2 TPI - flexible but useless plug-in framework.
\r
3 Copyright (C) 2002-2009 Silky
\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
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
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
20 *******************************************************************************/
\r
22 //******************************************************************************
\r
24 //******************************************************************************
\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
37 //******************************************************************************
\r
39 //******************************************************************************
\r
48 bool fCallback32bit;
\r
50 } g_LibInfo, g_LibInfoAlt;
\r
54 //******************************************************************************
\r
56 //******************************************************************************
\r
58 #define MyConvEI322PI(EI, strconv) \
\r
59 EI * ex = (EI *) _lpEis; \
\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
70 piInfo.nProcessedSize = ex->exinfo.dwWriteSize; \
\r
71 piInfo.fnDestination = wxFileName(strconv(ex->exinfo.szDestFileName));
\r
73 #define MyConvEI642PI(EI, strconv) \
\r
74 EI * ex = (EI *) _lpEis; \
\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
88 piInfo.nProcessedSize = ex->llWriteSize; \
\r
89 piInfo.fnDestination = wxFileName(strconv(ex->exinfo.szDestFileName));
\r
91 #define MyConvEM322PI(EM, strconv) \
\r
92 EM * ex = (EM *) _lpEis; \
\r
93 if (ex->uCommand != COMMAND_EXTRACT) \
\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
110 piInfo.fnDestination = wxFileName(strconv(ex->szAddFileName)); \
\r
111 g_prProc(TPI_NOTIFY_COMMON, & piInfo);
\r
113 #define MyConvEM642PI(EM, strconv) \
\r
114 EM * ex = (EM *) _lpEis; \
\r
115 if (ex->uCommand != COMMAND_EXTRACT) \
\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
132 piInfo.fnDestination = wxFileName(strconv(ex->szAddFileName)); \
\r
133 g_prProc(TPI_NOTIFY_COMMON, & piInfo);
\r
135 #define MySetArcSize(api_base, var) \
\r
136 fpProc = ::GetAPIAddress(#api_base L"Ex", false); \
\r
137 if (fpProc != NULL) \
\r
139 ((BOOL (__stdcall *)(void *, LONGLONG *)) fpProc)(_hArchive, (LONGLONG *) & _aiInfo->var); \
\r
143 fpProc = ::GetAPIAddress(#api_base, false); \
\r
144 if (fpProc != NULL) \
\r
146 _aiInfo->var = ((DWORD (__stdcall *)(void *)) fpProc)(_hArchive); \
\r
150 #define MySetArcTime(api_base, var, ismod) \
\r
151 fpProc = ::GetAPIAddress(#api_base L"64", false); \
\r
152 if (fpProc != NULL) \
\r
154 ((BOOL (__stdcall *)(void *, LONGLONG *)) fpProc)(_hArchive, & ll); \
\r
155 _aiInfo->var.Set((time_t) ll); \
\r
159 fpProc = ::GetAPIAddress(#api_base L"Ex", false); \
\r
160 if (fpProc != NULL) \
\r
162 ((BOOL (__stdcall *)(void *, FILETIME *)) fpProc)(_hArchive, & ft); \
\r
163 _aiInfo->var = FileTimeToWxDateTime(& ft); \
\r
167 fpProc = ::GetAPIAddress(#api_base, false); \
\r
168 if (fpProc != NULL) \
\r
170 _aiInfo->var.Set((time_t) ((DWORD (__stdcall *)(void *)) fpProc)(_hArchive)); \
\r
176 fpProc = ::GetAPIAddress("GetArcDate", false); \
\r
177 WORD wDate = fpProc == NULL ? 0 : ((WORD (__stdcall *)(void *)) fpProc)(_hArchive); \
\r
178 fpProc = ::GetAPIAddress("GetArcTime", false); \
\r
179 WORD wTime = fpProc == NULL ? 0 : ((WORD (__stdcall *)(void *)) fpProc)(_hArchive); \
\r
180 _aiInfo->var.SetFromDOS(MAKELONG(wTime, wDate)); \
\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
189 //******************************************************************************
\r
190 // Callback Wrapper
\r
191 //******************************************************************************
\r
193 BOOL __stdcall CallbackProc(HWND, unsigned int _uMsg, unsigned int _uState, void * _lpEis)
\r
195 static unsigned int uWM = ::RegisterWindowMessage(WM_ARCEXTRACT);
\r
198 // 独自仕様などに対する予備コード。
\r
203 TPI_PROCESSINFO piInfo;
\r
204 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
206 if (_lpEis != NULL)
\r
208 if ((g_LibInfo.fRunning && g_LibInfo.fCallback32bit) || (g_LibInfoAlt.fRunning && g_LibInfoAlt.fCallback32bit))
\r
210 if ((g_LibInfo.fRunning && g_LibInfo.fUnicode) || (g_LibInfoAlt.fRunning && g_LibInfoAlt.fUnicode))
\r
212 // EXTRACTINGINFOEXW -> TPI_PROCESSINFO変換。
\r
213 MyConvEI322PI(EXTRACTINGINFOEXW, WC2String);
\r
217 // EXTRACTINGINFOEX -> TPI_PROCESSINFO変換。
\r
218 MyConvEI322PI(EXTRACTINGINFOEX, UTF82String);
\r
220 piInfo.fiInfo.dwAttribute = 0;
\r
224 if ((g_LibInfo.fRunning && g_LibInfo.fUnicode) || (g_LibInfoAlt.fRunning && g_LibInfoAlt.fUnicode))
\r
226 // EXTRACTINGINFOEX64W -> TPI_PROCESSINFO変換。
\r
227 MyConvEI642PI(EXTRACTINGINFOEX64W, WC2String);
\r
231 // EXTRACTINGINFOEX64 -> TPI_PROCESSINFO変換。
\r
232 MyConvEI642PI(EXTRACTINGINFOEX64, UTF82String);
\r
235 piInfo.fiInfo.fnFileName = wxFileName(piInfo.fiInfo.szStoredName);
\r
238 // 数字の順でなく処理の順で並んでいることに注意。
\r
241 case ARCEXTRACT_OPEN:
\r
243 piInfo.eStatus = TPI_STATUS_OPENARCHIVE;
\r
247 piInfo.eStatus = TPI_STATUS_SEEKFILE;
\r
249 case ARCEXTRACT_BEGIN:
\r
251 piInfo.eStatus = TPI_STATUS_BEGINPROCESS;
\r
253 case ARCEXTRACT_INPROCESS:
\r
255 piInfo.eStatus = TPI_STATUS_INPROCESS;
\r
259 piInfo.eStatus = TPI_STATUS_ENDPROCESS;
\r
263 piInfo.eStatus = TPI_STATUS_TESTARCHIVE;
\r
265 case ARCEXTRACT_COPY:
\r
267 piInfo.eStatus = TPI_STATUS_COPYARCHIVE;
\r
269 case ARCEXTRACT_END:
\r
271 piInfo.eStatus = TPI_STATUS_CLOSEARCHIVE;
\r
276 if (g_prProc == NULL)
\r
281 return g_prProc(TPI_NOTIFY_COMMON, & piInfo) != TPI_CALLBACK_CANCEL;
\r
284 BOOL __stdcall EnumMembersProc(void * _lpEis)
\r
287 TPI_PROCESSINFO piInfo;
\r
288 piInfo.eMessage = TPI_MESSAGE_ASK;
\r
289 piInfo.eStatus = TPI_PARAM_DEST;
\r
290 if (g_prProc == NULL)
\r
295 if (_lpEis != NULL)
\r
297 if ((g_LibInfo.fRunning && g_LibInfo.fCallback32bit) || (g_LibInfoAlt.fRunning && g_LibInfoAlt.fCallback32bit))
\r
299 if ((g_LibInfo.fRunning && g_LibInfo.fUnicode) || (g_LibInfoAlt.fRunning && g_LibInfoAlt.fUnicode))
\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
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
314 if ((g_LibInfo.fRunning && g_LibInfo.fUnicode) || (g_LibInfoAlt.fRunning && g_LibInfoAlt.fUnicode))
\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
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
329 return piInfo.fnDestination.IsOk();
\r
332 //******************************************************************************
\r
333 // Inside Functions
\r
334 //******************************************************************************
\r
336 int ErrorCodeConvert(int nErrorCode)
\r
338 switch (nErrorCode)
\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
421 int CalSetCallbackProc(bool fAlt)
\r
423 // 先にコールバック関数の設定を解除しておく。
\r
427 fpProc = ::GetAPIAddressAlt("KillOwnerWindowEx64", false);
\r
428 g_LibInfoAlt.fCallback32bit = fpProc == NULL;
\r
429 if (g_LibInfoAlt.fCallback32bit)
\r
431 fpProc = ::GetAPIAddressAlt("KillOwnerWindowEx", false);
\r
436 fpProc = ::GetAPIAddress("KillOwnerWindowEx64", false);
\r
437 g_LibInfo.fCallback32bit = fpProc == NULL;
\r
438 if (g_LibInfo.fCallback32bit)
\r
440 fpProc = ::GetAPIAddress("KillOwnerWindowEx", false);
\r
443 if (fpProc == NULL)
\r
445 return TPI_ERROR_U_USE_LIBRARY;
\r
448 ((BOOL (__stdcall *)(HWND)) fpProc)(NULL);
\r
453 fpProc = ::GetAPIAddressAlt("SetOwnerWindowEx64", false);
\r
454 g_LibInfoAlt.fCallback32bit = fpProc == NULL;
\r
455 if (g_LibInfoAlt.fCallback32bit)
\r
457 fpProc = ::GetAPIAddressAlt("SetOwnerWindowEx", true);
\r
462 fpProc = ::GetAPIAddress("SetOwnerWindowEx64", false);
\r
463 g_LibInfo.fCallback32bit = fpProc == NULL;
\r
464 if (g_LibInfo.fCallback32bit)
\r
466 fpProc = ::GetAPIAddress("SetOwnerWindowEx", true);
\r
470 if (fpProc == NULL || ! ((fAlt ? g_LibInfoAlt.fCallback32bit : g_LibInfo.fCallback32bit)
\r
471 ? ((BOOL (__stdcall *)(HWND, ARCHIVERPROC * )) fpProc)(NULL, (ARCHIVERPROC *) CallbackProc)
\r
472 : ((BOOL (__stdcall *)(HWND, ARCHIVERPROC *, DWORD)) fpProc)(NULL, (ARCHIVERPROC *) CallbackProc, (fAlt ? g_LibInfoAlt.fUnicode : g_LibInfo.fUnicode) ? sizeof(EXTRACTINGINFOEX64W) : sizeof(EXTRACTINGINFOEX64))))
\r
474 return TPI_ERROR_U_USE_LIBRARY;
\r
477 // EnumMembersProc系。
\r
480 fpProc = ::GetAPIAddressAlt("ClearEnumMembersProc64", false);
\r
481 g_LibInfoAlt.fCallback32bit = fpProc == NULL;
\r
482 if (g_LibInfoAlt.fCallback32bit)
\r
484 fpProc = ::GetAPIAddressAlt("ClearEnumMembersProc", false);
\r
489 fpProc = ::GetAPIAddress("ClearEnumMembersProc64", false);
\r
490 g_LibInfo.fCallback32bit = fpProc == NULL;
\r
491 if (g_LibInfo.fCallback32bit)
\r
493 fpProc = ::GetAPIAddress("ClearEnumMembersProc", false);
\r
496 if (fpProc == NULL)
\r
498 return TPI_ERROR_U_USE_LIBRARY;
\r
501 // ((BOOL (__stdcall *)(void)) fpProc)();
\r
506 fpProc = ::GetAPIAddressAlt("SetEnumMembersProc64", false);
\r
507 g_LibInfoAlt.fCallback32bit = fpProc == NULL;
\r
508 if (g_LibInfoAlt.fCallback32bit)
\r
510 fpProc = ::GetAPIAddressAlt("SetEnumMembersProc", true);
\r
515 fpProc = ::GetAPIAddress("SetEnumMembersProc64", false);
\r
516 g_LibInfo.fCallback32bit = fpProc == NULL;
\r
517 if (g_LibInfo.fCallback32bit)
\r
519 fpProc = ::GetAPIAddress("SetEnumMembersProc", true);
\r
523 return (fpProc == NULL || ! ((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
529 //******************************************************************************
\r
531 //******************************************************************************
\r
538 int __stdcall GetPluginInformation
\r
540 unsigned int _uInfoId,
\r
547 return TPI_ERROR_D_PARAMETER;
\r
551 case TPI_INFO_VERSION_MAJOR:
\r
552 case TPI_INFO_VERSION_MINOR:
\r
553 * (int *) _pPtr = 0;
\r
555 case TPI_INFO_VERSION_API:
\r
556 * (int *) _pPtr = 2;
\r
559 return TPI_ERROR_D_UNSUPPORTED;
\r
561 return TPI_ERROR_SUCCESS;
\r
564 int __stdcall GetFormatInformation(TPI_FORMATINFO * _fiInfo, bool _bFirst)
\r
566 static wxULongLong_t s_nFileId;
\r
567 static wxXmlDocument xmlDoc(myMakeXMLName(wxT("calLibrary")));
\r
568 static wxXmlNode * xmlLibrary;
\r
573 xmlLibrary = myGetFirstLib(& xmlDoc);
\r
577 xmlLibrary = myGetNextLib(xmlLibrary);
\r
579 if (xmlLibrary == NULL)
\r
582 return TPI_ERROR_S_ENDOFDATA;
\r
585 MakeFormatInfo(xmlLibrary, wxT("calLibrary"), _fiInfo, s_nFileId++);
\r
586 return TPI_ERROR_SUCCESS;
\r
589 int __stdcall LoadPlugin
\r
591 const wxString & _szArcName,
\r
593 wxULongLong_t _nTypeId
\r
597 wxXmlDocument xmlDoc(myMakeXMLName(wxT("calLibrary")));
\r
598 wxXmlNode * xmlLibrary;
\r
600 // 対象が存在するならば対応するライブラリを調査、
\r
601 // 対象が存在しないならば指示されたライブラリをロード。
\r
602 ::RemoveCwdFromSearchPath();
\r
603 if (! ::wxFileExists(_szArcName))
\r
605 xmlLibrary = myGetFirstLib(& xmlDoc, _nTypeId);
\r
606 if (xmlLibrary == NULL)
\r
609 return TPI_ERROR_UNDEFINED;
\r
613 g_LibInfo.hLib = ::LoadLibrary(xmlLibrary->GetAttribute(wxT("name"), wxEmptyString).wchar_str());
\r
614 if (g_LibInfo.hLib == NULL)
\r
616 return TPI_ERROR_U_LOAD_LIBRARY;
\r
618 g_LibInfo.szPrefix = xmlLibrary->GetAttribute(wxT("prefix"), wxEmptyString);
\r
619 g_LibInfo.fUnicode = myGetAttributeBool(xmlLibrary, wxT("unicode"));
\r
620 g_LibInfo.node = * xmlLibrary;
\r
621 g_LibInfo.nLibIndex = _nTypeId;
\r
623 // 代替ライブラリもロード。ロードできなくてもエラーにはしない。
\r
624 g_LibInfoAlt.szPrefix = xmlLibrary->GetAttribute(wxT("prefix-alt"), wxEmptyString);
\r
625 g_LibInfoAlt.fUnicode = myGetAttributeBool(xmlLibrary, wxT("unicode-alt"));
\r
626 g_LibInfoAlt.hLib = ::LoadLibrary(xmlLibrary->GetAttribute(wxT("name-alt"), wxEmptyString).wchar_str());
\r
629 if (_prProc != NULL)
\r
631 g_prProc = * _prProc;
\r
632 CalSetCallbackProc(true);
\r
633 CalSetCallbackProc(false);
\r
635 return TPI_ERROR_SUCCESS;
\r
638 // 無限ループに陥らないよう上限を設定。
\r
639 xmlLibrary = myGetFirstLib(& xmlDoc);
\r
640 for (g_LibInfo.nLibIndex = 0; g_LibInfo.nLibIndex < 300 && xmlLibrary != NULL; g_LibInfo.nLibIndex++)
\r
643 g_LibInfo.hLib = ::LoadLibrary(xmlLibrary->GetAttribute(wxT("name"), wxEmptyString).wchar_str());
\r
644 if (g_LibInfo.hLib == NULL)
\r
646 xmlLibrary = myGetNextLib(xmlLibrary);
\r
649 g_LibInfo.szPrefix = xmlLibrary->GetAttribute(wxT("prefix"), wxEmptyString);
\r
650 g_LibInfo.fUnicode = myGetAttributeBool(xmlLibrary, wxT("unicode"));
\r
651 g_LibInfo.node = * xmlLibrary;
\r
653 // 代替ライブラリもロード。ロードできなくてもエラーにはしない。
\r
654 g_LibInfoAlt.szPrefix = xmlLibrary->GetAttribute(wxT("prefix-alt"), wxEmptyString);
\r
655 g_LibInfoAlt.fUnicode = myGetAttributeBool(xmlLibrary, wxT("unicode-alt"));
\r
656 g_LibInfoAlt.hLib = ::LoadLibrary(xmlLibrary->GetAttribute(wxT("name-alt"), wxEmptyString).wchar_str());
\r
659 FARPROC fpProc = ::GetAPIAddress("SetUnicodeMode", false);
\r
660 if (fpProc != NULL)
\r
662 ((BOOL (__stdcall *)(BOOL)) fpProc)(TRUE);
\r
666 fpProc = ::GetAPIAddress("CheckArchive", true);
\r
667 if (fpProc != NULL && (g_LibInfo.fUnicode
\r
668 ? ((BOOL (__stdcall *)(const wchar_t *, const int)) fpProc)(_szArcName.wchar_str(), 0)
\r
669 : ((BOOL (__stdcall *)(const char *, const int)) fpProc)(_szArcName.ToUTF8(), 0)))
\r
672 if (_prProc != NULL)
\r
674 g_prProc = * _prProc;
\r
675 CalSetCallbackProc(true);
\r
676 CalSetCallbackProc(false);
\r
678 return TPI_ERROR_SUCCESS;
\r
680 ::FreeLibrary(g_LibInfo.hLib);
\r
681 ::FreeLibrary(g_LibInfoAlt.hLib);
\r
682 xmlLibrary = myGetNextLib(xmlLibrary);
\r
684 return TPI_ERROR_U_LOAD_LIBRARY;
\r
687 int __stdcall FreePlugin
\r
689 void * // _pReserved
\r
692 ::FreeLibrary(g_LibInfo.hLib);
\r
693 ::FreeLibrary(g_LibInfoAlt.hLib);
\r
694 return TPI_ERROR_SUCCESS;
\r
697 int __stdcall OpenArchive
\r
699 const wxString & _szArcName,
\r
700 void * * _hArchive,
\r
701 wxULongLong_t * _nFileCount
\r
706 if (_nFileCount != NULL)
\r
708 fpProc = ::GetAPIAddress("GetFileCount", true);
\r
709 if (fpProc != NULL)
\r
711 int n = g_LibInfo.fUnicode
\r
712 ? ((int (__stdcall *)(const wchar_t *)) fpProc)(_szArcName.wchar_str())
\r
713 : ((int (__stdcall *)(const char *)) fpProc)(_szArcName.ToUTF8());
\r
722 fpProc = ::GetAPIAddress("OpenArchive", true);
\r
723 if (fpProc == NULL)
\r
725 return TPI_ERROR_U_USE_LIBRARY;
\r
728 * _hArchive = g_LibInfo.fUnicode
\r
729 ? ((void * (__stdcall *)(const HWND, const wchar_t *, const DWORD)) fpProc)(NULL, _szArcName.wchar_str(), 0)
\r
730 : ((void * (__stdcall *)(const HWND, const char *, const DWORD)) fpProc)(NULL, _szArcName.ToUTF8(), 0);
\r
731 return _hArchive == NULL ? TPI_ERROR_UNDEFINED : TPI_ERROR_SUCCESS;
\r
734 int __stdcall CloseArchive
\r
739 FARPROC fpProc = ::GetAPIAddress("CloseArchive", false);
\r
740 return fpProc == NULL ? TPI_ERROR_U_USE_LIBRARY : ErrorCodeConvert(((int (__stdcall *)(void *)) fpProc)(_hArchive));
\r
743 int __stdcall GetFileInformation
\r
746 TPI_FILEINFO * _fiInfo,
\r
750 static wxULongLong_t s_nFileId;
\r
751 static FARPROC fpNext, fpAttr, fpName;
\r
753 INDIVIDUALINFO iiInfo;
\r
754 INDIVIDUALINFOW iiInfoW;
\r
755 memset(& iiInfo, 0, sizeof(iiInfo));
\r
756 memset(& iiInfoW, 0, sizeof(iiInfoW));
\r
761 FARPROC fpProc = ::GetAPIAddress("FindFirst", true);
\r
762 fpNext = ::GetAPIAddress("FindNext", true);
\r
763 fpAttr = ::GetAPIAddress("GetAttribute", false);
\r
764 fpName = ::GetAPIAddress("GetFileName", true);
\r
765 if (fpProc == NULL)
\r
767 return TPI_ERROR_U_USE_LIBRARY;
\r
770 nErrorCode = g_LibInfo.fUnicode
\r
771 ? ((int (__stdcall *)(void *, const wchar_t *, LPINDIVIDUALINFOW)) fpProc)(_hArchive, L"*", & iiInfoW)
\r
772 : ((int (__stdcall *)(void *, const char *, LPINDIVIDUALINFO)) fpProc)(_hArchive, "*", & iiInfo);
\r
776 if (fpNext == NULL)
\r
778 return TPI_ERROR_U_USE_LIBRARY;
\r
781 nErrorCode = g_LibInfo.fUnicode
\r
782 ? ((int (__stdcall *)(void *, LPINDIVIDUALINFOW)) fpNext)(_hArchive, & iiInfoW)
\r
783 : ((int (__stdcall *)(void *, LPINDIVIDUALINFO)) fpNext)(_hArchive, & iiInfo);
\r
786 nErrorCode = ErrorCodeConvert(nErrorCode);
\r
787 if (nErrorCode == TPI_ERROR_SUCCESS)
\r
789 _fiInfo->dwAttribute = (fpAttr == NULL) ? 0 : ((int (__stdcall *)(void *)) fpAttr)(_hArchive);
\r
790 if (_fiInfo->dwAttribute == (unsigned) -1)
\r
792 _fiInfo->dwAttribute = 0;
\r
795 if (g_LibInfo.fUnicode)
\r
797 _fiInfo->dwCRC32 = iiInfoW.dwCRC;
\r
798 _fiInfo->eOSType = iiInfoW.uOSType;
\r
799 _fiInfo->nPackedSize = iiInfoW.dwCompressedSize;
\r
800 _fiInfo->nUnpackedSize = iiInfoW.dwOriginalSize;
\r
801 _fiInfo->tmModify.SetFromDOS(MAKELONG(iiInfoW.wTime, iiInfoW.wDate));
\r
802 _fiInfo->szStoredName = WC2String(iiInfoW.szFileName);
\r
803 if (wcslen(iiInfoW.szFileName) >= 510 && fpName)
\r
805 ((int (__stdcall *)(void *, wchar_t *, const int)) fpName)(_hArchive, wxStringBuffer(_fiInfo->szStoredName, 32769), 32768);
\r
807 _fiInfo->szMethod = WC2String(iiInfoW.szMode);
\r
808 _fiInfo->wCompressRatio = iiInfoW.wRatio;
\r
812 _fiInfo->dwCRC32 = iiInfo.dwCRC;
\r
813 _fiInfo->eOSType = iiInfo.uOSType;
\r
814 _fiInfo->nPackedSize = iiInfo.dwCompressedSize;
\r
815 _fiInfo->nUnpackedSize = iiInfo.dwOriginalSize;
\r
816 _fiInfo->tmModify.SetFromDOS(MAKELONG(iiInfo.wTime, iiInfo.wDate));
\r
817 _fiInfo->szStoredName = UTF82String(iiInfo.szFileName);
\r
818 if (strlen(iiInfo.szFileName) >= 510 && fpName)
\r
820 char * sz = (char *) malloc(32769);
\r
821 memset(sz, 0, 32769);
\r
822 ((int (__stdcall *)(void *, char *, const int)) fpName)(_hArchive, sz, 32768);
\r
823 _fiInfo->szStoredName = UTF82String(sz);
\r
826 _fiInfo->szMethod = UTF82String(iiInfo.szMode);
\r
827 _fiInfo->wCompressRatio = iiInfo.wRatio;
\r
829 _fiInfo->nFileId = s_nFileId++;
\r
830 _fiInfo->fnFileName = wxFileName(_fiInfo->szStoredName);
\r
831 // _fiInfo->ftAccessTime = 0;
\r
832 // _fiInfo->ftCreateTime = 0;
\r
838 int __stdcall GetArchiveInformation
\r
841 TPI_ARCHIVEINFO * _aiInfo
\r
844 FARPROC fpProc = ::GetAPIAddress("GetArcFileName", true);
\r
845 if (fpProc != NULL)
\r
847 // TODO : ファイル名の文字数制限を撤廃。
\r
849 if (g_LibInfo.fUnicode)
\r
852 memset(sz, 0, sizeof(sz));
\r
853 ((int (__stdcall *)(void *, wchar_t *, const int)) fpProc)(_hArchive, sz, 2048);
\r
859 memset(sz, 0, sizeof(sz));
\r
860 ((int (__stdcall *)(void *, char *, const int)) fpProc)(_hArchive, sz, 2048);
\r
861 s = UTF82String(sz);
\r
863 _aiInfo->fnArchive = wxFileName(s);
\r
866 wxLongLong_t ll = 0;
\r
867 MySetArcSize(GetArcFileSize, nFileSize);
\r
868 MySetArcSize(GetArcOriginalSize, nUnpackedSize);
\r
869 MySetArcSize(GetArcCompressedSize, nPackedSize);
\r
870 MySetArcSize(GetArcReadSize, nReadSize);
\r
871 if (_aiInfo->nPackedSize == (DWORD) -1)
\r
873 // 圧縮後サイズの取得に対応していない場合、書庫のサイズで代替。
\r
874 _aiInfo->nPackedSize = _aiInfo->nFileSize;
\r
878 MySetArcTime(GetArcAccessTime, tmAccess, false);
\r
879 MySetArcTime(GetArcCreateTime, tmCreate, false);
\r
880 MySetArcTime(GetArcWriteTime, tmModify, true);
\r
882 fpProc = ::GetAPIAddress("GetArcRatio", false);
\r
883 if (fpProc != NULL)
\r
885 _aiInfo->wCompressRatio = ((WORD (__stdcall *)(void *)) fpProc)(_hArchive);
\r
886 if (_aiInfo->wCompressRatio == (WORD) -1)
\r
889 _aiInfo->wCompressRatio = 0;
\r
893 fpProc = ::GetAPIAddress("GetArcOSType", false);
\r
894 if (fpProc != NULL)
\r
896 _aiInfo->eOSType = ((UINT (__stdcall *)(void *)) fpProc)(_hArchive);
\r
899 fpProc = ::GetAPIAddress("IsSFXFile", false);
\r
900 _aiInfo->fSFX = fpProc != NULL && ((int (__stdcall *)(void *)) fpProc)(_hArchive) > 0;
\r
903 MakeFormatInfo(& g_LibInfo.node, wxT("calLibrary"), & _aiInfo->fiInfo, 0);
\r
905 return TPI_ERROR_SUCCESS;
\r
908 int __stdcall Command
\r
910 wxULongLong_t _eCommand,
\r
911 TPI_SWITCHES * _swInfo,
\r
912 const wxString & _szArcName,
\r
913 const wxArrayString & _szFiles
\r
916 // xmlからコマンドラインを取得。
\r
917 wxString szPath, szCommandLine;
\r
920 g_LibInfoAlt.fRunning
\r
921 = g_LibInfo.node.GetAttribute(
\r
922 _eCommand == TPI_COMMAND_CREATE ? wxT("create-alt") :
\r
923 _eCommand == TPI_COMMAND_ADD ? wxT("add-alt") :
\r
924 _eCommand == TPI_COMMAND_EXTRACT ? wxT("extract-alt") :
\r
925 _eCommand == TPI_COMMAND_DELETE ? wxT("delete-alt") :
\r
926 _eCommand == TPI_COMMAND_UPDATE ? wxT("update-alt") :
\r
927 _eCommand == TPI_COMMAND_TEST ? wxT("test-alt") :
\r
928 _eCommand == TPI_COMMAND_REPAIR ? wxT("repair-alt") :
\r
929 _eCommand == TPI_COMMAND_MOVE ? wxT("move-alt") :
\r
930 _eCommand == TPI_COMMAND_SFX ? wxT("sfx-alt") :
\r
931 _eCommand == TPI_COMMAND_UNSFX ? wxT("unsfx-alt") : wxEmptyString, & szCommandLine);
\r
933 = g_LibInfo.node.GetAttribute(
\r
934 _eCommand == TPI_COMMAND_CREATE ? wxT("create") :
\r
935 _eCommand == TPI_COMMAND_ADD ? wxT("add") :
\r
936 _eCommand == TPI_COMMAND_EXTRACT ? wxT("extract") :
\r
937 _eCommand == TPI_COMMAND_DELETE ? wxT("delete") :
\r
938 _eCommand == TPI_COMMAND_UPDATE ? wxT("update") :
\r
939 _eCommand == TPI_COMMAND_TEST ? wxT("test") :
\r
940 _eCommand == TPI_COMMAND_REPAIR ? wxT("repair") :
\r
941 _eCommand == TPI_COMMAND_MOVE ? wxT("move") :
\r
942 _eCommand == TPI_COMMAND_SFX ? wxT("sfx") :
\r
943 _eCommand == TPI_COMMAND_UNSFX ? wxT("unsfx") : wxEmptyString, & szCommandLine);
\r
946 g_LibInfo.fRunning ? ::GetAPIAddress( "", true) :
\r
947 g_LibInfoAlt.fRunning ? ::GetAPIAddressAlt("", true) : NULL;
\r
948 if (fpProc == NULL || szCommandLine.IsEmpty())
\r
950 return TPI_ERROR_U_USE_LIBRARY;
\r
953 // コマンドライン・レスポンスファイル作成。
\r
955 szResponceFileName = g_LibInfo.fRunning ?
\r
956 MakeResponceFile(_szFiles, myGetAttributeBool(& g_LibInfo.node, wxT("quote-resp"), true), g_LibInfo.fUnicode) :
\r
957 MakeResponceFile(_szFiles, myGetAttributeBool(& g_LibInfoAlt.node, wxT("quote-resp"), true), g_LibInfoAlt.fUnicode),
\r
958 szCommandLineSend = MakeCommandLineSend(szCommandLine, _szArcName, _swInfo, _szFiles, szResponceFileName);
\r
963 if ((g_LibInfo.fRunning && g_LibInfo.fUnicode) || (g_LibInfoAlt.fRunning && g_LibInfoAlt.fUnicode))
\r
965 wchar_t szTmpOut[2049];
\r
966 nErrorCode = ((int (__stdcall *)(const HWND, const wchar_t *, wchar_t *, DWORD)) fpProc)(NULL, szCommandLineSend.wchar_str(), szTmpOut, 2048);
\r
967 szOutput = WC2String(szTmpOut);
\r
971 char szTmpOut[2049];
\r
972 nErrorCode = ((int (__stdcall *)(const HWND, const char *, char *, DWORD)) fpProc)(NULL, szCommandLineSend.ToUTF8(), szTmpOut, 2048);
\r
973 szOutput = UTF82String(szTmpOut);
\r
977 ::wxRemoveFile(szResponceFileName);
\r
979 if (nErrorCode != 0)
\r
981 wxLogError(L"Error :\n%x\n\nCommandLine:\n%s\n\nOutput:\n%s", nErrorCode, szCommandLineSend.c_str(), szOutput.c_str());
\r
983 return ErrorCodeConvert(nErrorCode);
\r