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 <windows.h>
\r
32 //******************************************************************************
\r
34 //******************************************************************************
\r
39 //******************************************************************************
\r
41 //******************************************************************************
\r
43 #define GetAPIAddress(name) GetProcAddress(g_hLib, "Sqx" name)
\r
45 int ErrorCodeConvert(int nErrorCode)
\r
49 case SQX_ERR_SUCCESS: return TPI_ERROR_SUCCESS;
\r
50 case SQX_ERR_ERROR: return TPI_ERROR_UNDEFINED;
\r
51 case SQX_ERR_FILE_NOT_FOUND: return TPI_ERROR_IO_NOTFOUND;
\r
52 case SQX_ERR_PATH_NOT_FOUND: return TPI_ERROR_IO_NOTFOUND;
\r
53 case SQX_ERR_TOO_MANY_FILES: return TPI_ERROR_IO_OPEN;
\r
54 case SQX_ERR_ACCESS_DENIED: return TPI_ERROR_IO_ACCESS;
\r
55 case SQX_ERR_INVALID_HANDLE: return TPI_ERROR_D_PARAMETER;
\r
56 case SQX_ERR_DISK_FULL: return TPI_ERROR_IO_WRITE;
\r
57 case SQX_ERR_OUT_OF_MEMORY: return TPI_ERROR_D_OUTOFMEMORY;
\r
58 case SQX_ERR_CANT_ACCESS_TEMP_DIR: return TPI_ERROR_IO_TMP_ACCESS;
\r
59 case SQX_ERR_TEMP_DIR_FULL: return TPI_ERROR_IO_TMP_WRITE;
\r
60 case SQX_ERR_USER_ABORT: return TPI_ERROR_D_SKIPPED;
\r
61 case SQX_ERR_INVALID_ARC_HANDLE: return TPI_ERROR_D_PARAMETER;
\r
62 case SQX_ERR_CANT_FIND_LANG_DATA: return TPI_ERROR_UNDEFINED;
\r
63 case SQX_ERR_UNKNOWN_SUBSTREAM: return TPI_ERROR_UNDEFINED;
\r
64 case SQX_ERR_BAD_SUBSTREAM_CRC: return TPI_ERROR_ARC_BROKEN_SUM;
\r
65 case SQX_ERR_UNKNOWN_METHOD: return TPI_ERROR_ARC_UNSUPPORTED;
\r
66 case SQX_ERR_FILE_ENCRYPTED: return TPI_ERROR_ARC_ENCRYPTED;
\r
67 case SQX_ERR_BAD_CRC: return TPI_ERROR_ARC_BROKEN_SUM;
\r
68 case SQX_ERR_CANT_CREATE_FILE: return TPI_ERROR_IO_OPEN;
\r
69 case SQX_ERR_BAD_FILE_FORMAT: return TPI_ERROR_ARC_BROKEN_HEADER;
\r
70 case SQX_ERR_FUNCTION_NOT_SUPPORTED: return TPI_ERROR_D_UNSUPPORTED;
\r
71 case SQX_ERR_FUNC_NOT_SUPPORTED_BY_ARCHIVE: return TPI_ERROR_D_UNSUPPORTED;
\r
72 case SQX_ERR_CANT_CREATE_ARC_DIR: return TPI_ERROR_IO_ARC_WRITE;
\r
73 case SQX_ERR_INVALID_DIR_NAME: return TPI_ERROR_IO_ARC_WRITE;
\r
74 case SQX_ERR_INVALID_FILE_NAME: return TPI_ERROR_IO_ARC_WRITE;
\r
75 case SQX_ERR_TOO_MANY_BROKEN_FBLOCKS: return TPI_ERROR_ARC_BROKEN_MISC;
\r
76 case SQX_ERR_ARCHIVE_OK_RDATA_NOT: return TPI_ERROR_ARC_BROKEN_MISC;
\r
77 case SQX_ERR_RDATA_DAMAGED: return TPI_ERROR_ARC_BROKEN_MISC;
\r
78 case SQX_ERR_RDATA_NEW_VERSION: return TPI_ERROR_ARC_UNSUPPORTED;
\r
79 case SQX_ERR_RDATA_DOES_NOT_MATCH: return TPI_ERROR_ARC_BROKEN_MISC;
\r
80 case SQX_ERR_CANT_FIND_RDATA: return TPI_ERROR_ARC_MISC;
\r
81 case SQX_ERR_ARCHIVE_IS_LOCKED: return TPI_ERROR_ARC_MISC;
\r
82 case SQX_ERR_CANT_ADD_TO_MV: return TPI_ERROR_ARC_UNSUPPORTED;
\r
83 case SQX_ERR_CANT_DELETE_FROM_MV: return TPI_ERROR_ARC_UNSUPPORTED;
\r
84 case SQX_ERR_NEED_1ST_VOLUME: return TPI_ERROR_ARC_MISC;
\r
85 case SQX_ERR_MISSING_VOLUME: return TPI_ERROR_ARC_MISC;
\r
86 case SQX_ERR_VOLUME_LIMIT_REACHED: return TPI_ERROR_ARC_MISC;
\r
87 case SQX_ERR_SFXSTUB_NOT_INSTALLED: return TPI_ERROR_UNDEFINED;
\r
88 case SQX_ERR_BACKUP_READ_ACCESS_DENIED: return TPI_ERROR_IO_ACCESS;
\r
89 case SQX_ERR_BACKUP_WRITE_ACCESS_DENIED: return TPI_ERROR_IO_WRITE;
\r
90 case SQX_ERR_ACL_READ_ACCESS_DENIED: return TPI_ERROR_IO_READ;
\r
91 case SQX_ERR_ACL_WRITE_ACCESS_DENIED: return TPI_ERROR_IO_WRITE;
\r
92 case SQX_ERR_WRONG_ARCHIVER_VERSION: return TPI_ERROR_ARC_UNSUPPORTED;
\r
93 case SQX_ERR_CANT_COPY_SOURCE_TO_SOURCE: return TPI_ERROR_IO_ARC_COPY;
\r
94 case SQX_ERR_VOLUMES_TOO_SMALL: return TPI_ERROR_ARC_MISC;
\r
95 case SQX_ERR_ARCHIVE_VERSION_TOO_HIGH: return TPI_ERROR_ARC_UNSUPPORTED;
\r
96 case SQX_ERR_EXT_RDATA_DOES_NOT_MATCH: return TPI_ERROR_ARC_MISC;
\r
97 case SQX_ERR_BAD_PARAMETER: return TPI_ERROR_D_PARAMETER;
\r
98 case SQX_ERR_EQUAL_PASSWORDS: return TPI_ERROR_ARC_MISC;
\r
99 case SQX_ERR_REQUIRES_ENCRYPTION: return TPI_ERROR_ARC_MISC;
\r
100 case SQX_ERR_MISSING_HEADER_PASSWORD: return TPI_ERROR_ARC_MISC;
\r
101 case SQX_ERR_MISSING_SQX_PRIVATE_KEY: return TPI_ERROR_ARC_MISC;
\r
102 case SQX_ERR_MISSING_SQX_AVKEY: return TPI_ERROR_ARC_MISC;
\r
103 case SQX_ERR_MISSING_EXTERNAL_AVKEY: return TPI_ERROR_ARC_MISC;
\r
104 case SQX_ERR_INVALID_SQX_AVKEY: return TPI_ERROR_UNDEFINED;
\r
105 case SQX_ERR_SQX_AVKEY_VERSION: return TPI_ERROR_UNDEFINED;
\r
106 case SQX_ERR_SQX_AVDATA_VERSION: return TPI_ERROR_UNDEFINED;
\r
107 case SQX_ERR_SQX_BROKEN_AVRECORD: return TPI_ERROR_ARC_BROKEN_HEADER;
\r
108 case SQX_ERR_RIJNDAEL_RSA: return TPI_ERROR_UNDEFINED;
\r
109 case SQX_ERR_REQUIRES_NTFS: return TPI_ERROR_UNDEFINED;
\r
110 case SQX_ERR_REQUIRES_WINNT: return TPI_ERROR_UNDEFINED;
\r
111 case SQX_ERR_REQUIRES_W2K: return TPI_ERROR_UNDEFINED;
\r
112 case SQX_ERR_REQUIRES_WINXP: return TPI_ERROR_UNDEFINED;
\r
113 case SQX_ERR_REQUIRES_WINXP_SP1: return TPI_ERROR_UNDEFINED;
\r
114 case SQX_ERR_REQUIRES_WINXP_SP2: return TPI_ERROR_UNDEFINED;
\r
115 case SQX_ERR_REQUIRES_LONGHORN: return TPI_ERROR_UNDEFINED;
\r
116 case SQX_ERR_NO_RESOURCES_FOUND: return TPI_ERROR_UNDEFINED;
\r
117 case SQX_ERR_UNKNOWN_ICON_FORMAT: return TPI_ERROR_UNDEFINED;
\r
118 case SQX_ERR_NO_MATCHING_ICON_SIZE: return TPI_ERROR_UNDEFINED;
\r
119 case SQX_ERR_UNKNOWN_EXE_FORMAT: return TPI_ERROR_UNDEFINED;
\r
120 case SQX_ERR_REQUIRES_SOURCE_PATH: return TPI_ERROR_D_PARAMETER;
\r
121 case SQX_ERR_FILE_DATA_NOT_EQUAL: return TPI_ERROR_ARC_BROKEN_MISC;
\r
122 case SQX_ERR_COMMENT_BIGGER_4K: return TPI_ERROR_ARC_MISC;
\r
123 case SQX_ERR_CANT_CREATE_SFX_FROM_MV: return TPI_ERROR_ARC_UNSUPPORTED;
\r
124 default: return TPI_ERROR_UNDEFINED;
\r
128 //******************************************************************************
\r
129 // Callback Wrapper
\r
130 //******************************************************************************
\r
132 int CALLBACK CallbackProc(void *, SQX_CALLBACKINFO * pCallbackInfo)
\r
134 static TPI_PROCESSINFO piInfo;
\r
135 switch (pCallbackInfo->dwCallbackType)
\r
137 case SQX_CALLBACK_FILENAME:
\r
138 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
139 piInfo.eStatus = TPI_STATUS_BEGINPROCESS;
\r
140 piInfo.fiInfo.szStoredName = WC2String(pCallbackInfo->pszSourceFileName);
\r
141 piInfo.fiInfo.fnFileName = wxFileName(piInfo.fiInfo.szStoredName);
\r
142 piInfo.fnDestination = wxFileName(WC2String(pCallbackInfo->pszTargetFileName));
\r
144 g_prProc == nullptr || g_prProc(TPI_NOTIFY_COMMON, & piInfo) != TPI_CALLBACK_CANCEL ?
\r
145 SQX_PROGRESS_OK : SQX_PROGRESS_CANCEL;
\r
147 case SQX_CALLBACK_PROGRESS:
\r
148 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
149 piInfo.eStatus = TPI_STATUS_INPROCESS;
\r
150 piInfo.nProcessedSize = pCallbackInfo->iProgress;
\r
152 g_prProc == nullptr || g_prProc(TPI_NOTIFY_COMMON, & piInfo) != TPI_CALLBACK_CANCEL ?
\r
153 SQX_PROGRESS_OK : SQX_PROGRESS_CANCEL;
\r
155 case SQX_CALLBACK_REPLACE:
\r
156 piInfo.eMessage = TPI_MESSAGE_ASK;
\r
157 piInfo.eStatus = TPI_PARAM_DEST;
\r
158 piInfo.fiInfo.szStoredName = WC2String(pCallbackInfo->pFindDataReplace->cFileName);
\r
159 piInfo.fiInfo.fnFileName = wxFileName(piInfo.fiInfo.szStoredName);
\r
160 piInfo.fiInfo.dwAttribute = pCallbackInfo->pFindDataReplace->dwFileAttributes;
\r
161 piInfo.fiInfo.nUnpackedSize = pCallbackInfo->pFindDataReplace->nFileSizeLow | ((wxULongLong_t) pCallbackInfo->pFindDataReplace->nFileSizeHigh) << 32;
\r
162 piInfo.fiInfo.tmAccess = FileTimeToWxDateTime(& pCallbackInfo->pFindDataReplace->ftLastAccessTime);
\r
163 piInfo.fiInfo.tmModify = FileTimeToWxDateTime(& pCallbackInfo->pFindDataReplace->ftLastWriteTime);
\r
164 piInfo.fiInfo.tmCreate = FileTimeToWxDateTime(& pCallbackInfo->pFindDataReplace->ftCreationTime);
\r
166 g_prProc == nullptr ? SQX_REPLACE_OVERWRITE :
\r
167 g_prProc(TPI_NOTIFY_COMMON, & piInfo) == TPI_CALLBACK_CANCEL ? SQX_PROGRESS_CANCEL :
\r
168 piInfo.fnDestination.IsOk() ? SQX_REPLACE_OVERWRITE : SQX_REPLACE_SKIP;
\r
170 case SQX_CALLBACK_PASSWORD:
\r
171 case SQX_CALLBACK_PASSWORD_HEADER:
\r
172 piInfo.eMessage = TPI_MESSAGE_ASK;
\r
173 piInfo.eStatus = TPI_PARAM_PASSWORD;
\r
174 piInfo.szParam.Empty();
\r
175 if (g_prProc == nullptr || g_prProc(TPI_NOTIFY_COMMON, & piInfo) != TPI_CALLBACK_CONTINUE)
\r
177 return SQX_PASSWORD_CANCEL;
\r
179 wcsncpy(pCallbackInfo->szCryptKey, piInfo.szParam.c_str(), sizeof(pCallbackInfo->szCryptKey));
\r
180 return SQX_PASSWORD_OK;
\r
182 case SQX_CALLBACK_SKIP:
\r
183 return SQX_SKIPFILE_SKIP;
\r
185 case SQX_CALLBACK_NEXTDISK:
\r
186 piInfo.eMessage = TPI_MESSAGE_ASK;
\r
187 piInfo.eStatus = TPI_PARAM_NEXTVOLUME;
\r
188 piInfo.szParam.Empty();
\r
189 if (g_prProc == nullptr || g_prProc(TPI_NOTIFY_COMMON, & piInfo) != TPI_CALLBACK_CONTINUE)
\r
191 return SQX_NEXTDISK_CANCEL;
\r
193 wcsncpy(pCallbackInfo->szNextDiskPath, piInfo.szParam.c_str(), sizeof(pCallbackInfo->szNextDiskPath));
\r
194 return SQX_NEXTDISK_OK;
\r
196 case SQX_CALLBACK_SIGNAL:
\r
197 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
198 switch (pCallbackInfo->dwSignal)
\r
200 case SQX_SIGNAL_COMPRESS:
\r
201 case SQX_SIGNAL_UNCOMPRESS:
\r
202 case SQX_SIGNAL_DELETE:
\r
203 case SQX_SIGNAL_REPAIR_ARCHIVE:
\r
204 case SQX_SIGNAL_TEST_ARCHIVE:
\r
205 piInfo.eStatus = TPI_STATUS_OPENARCHIVE;
\r
207 case SQX_SIGNAL_TEMP_ARC_COPY:
\r
208 piInfo.eStatus = TPI_STATUS_COPYARCHIVE;
\r
215 if (g_prProc != nullptr)
\r
217 g_prProc(TPI_NOTIFY_COMMON, & piInfo);
\r
226 //******************************************************************************
\r
228 //******************************************************************************
\r
235 int __stdcall GetPluginInformation
\r
237 unsigned int _uInfoId,
\r
242 if (_pPtr == nullptr)
\r
244 return TPI_ERROR_D_PARAMETER;
\r
248 case TPI_INFO_VERSION_MAJOR:
\r
249 case TPI_INFO_VERSION_MINOR:
\r
250 * (int *) _pPtr = 0;
\r
252 case TPI_INFO_VERSION_API:
\r
253 * (int *) _pPtr = 2;
\r
255 case TPI_INFO_HANDLE_ON_COMMAND:
\r
256 * (int *) _pPtr = 1;
\r
259 return TPI_ERROR_D_UNSUPPORTED;
\r
261 return TPI_ERROR_SUCCESS;
\r
264 int __stdcall GetFormatInformation(TPI_FORMATINFO * _fiInfo, bool _bFirst)
\r
266 static int s_uFileId = 0;
\r
267 if (s_uFileId == 2)
\r
269 return TPI_ERROR_S_ENDOFDATA;
\r
276 _fiInfo->szTypeName = _bFirst ? wxT("SQX1") : wxT("SQX2");
\r
277 _fiInfo->szSuffix = wxT("sqx");
\r
278 _fiInfo->szEngineName = wxT("sqx20u.dll");
\r
279 _fiInfo->szTPIName = wxT("sqxArc");
\r
280 _fiInfo->nTypeId = s_uFileId++;
\r
281 _fiInfo->eSupportedCommand = TPI_COMMAND_CREATE | TPI_COMMAND_EXTRACT | TPI_COMMAND_DELETE | TPI_COMMAND_TEST | TPI_COMMAND_REPAIR;
\r
282 _fiInfo->fArchive = true;
\r
283 _fiInfo->fComment = true;
\r
284 _fiInfo->fSFX = true;
\r
285 _fiInfo->fSolid = true;
\r
286 _fiInfo->fEncryptPassword = true;
\r
287 _fiInfo->fEncryptHeader = true;
\r
288 _fiInfo->fMultiVolume = true;
\r
289 _fiInfo->fMMOptimize = true;
\r
290 _fiInfo->nCompressLevelMin = 0;
\r
291 _fiInfo->nCompressLevelMax = 5;
\r
292 _fiInfo->nRecoveryRecordMin = 0;
\r
293 _fiInfo->nRecoveryRecordMax = 5;
\r
295 return TPI_ERROR_SUCCESS;
\r
298 int __stdcall LoadPlugin
\r
305 ::RemoveCwdFromSearchPath();
\r
306 g_hLib = ::LoadLibrary(L"sqx20u.dll");
\r
307 if (g_hLib == nullptr)
\r
309 return TPI_ERROR_U_LOAD_LIBRARY;
\r
313 if (_prProc != nullptr)
\r
315 g_prProc = * _prProc;
\r
317 return TPI_ERROR_SUCCESS;
\r
320 int __stdcall FreePlugin
\r
322 void * // _pReserved
\r
325 ::FreeLibrary(g_hLib);
\r
326 return TPI_ERROR_SUCCESS;
\r
329 int __stdcall OpenArchive
\r
331 const wxString & _szArcName,
\r
332 void * * _hArchive,
\r
333 wxULongLong_t * _nFileCount
\r
336 FARPROC fpProc = ::GetAPIAddress("InitArchive");
\r
337 if (fpProc == nullptr)
\r
339 return TPI_ERROR_U_USE_LIBRARY;
\r
342 int nErrorCode = ErrorCodeConvert(((int (__stdcall *)(const wchar_t *, SQXCALLBACK, void *, void **)) fpProc)(_szArcName.wchar_str(), CallbackProc, nullptr, _hArchive));
\r
343 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
348 if (_nFileCount != nullptr)
\r
350 fpProc = ::GetAPIAddress("InitArcFileList");
\r
351 if (fpProc == nullptr)
\r
353 CloseArchive(* _hArchive);
\r
354 return TPI_ERROR_U_USE_LIBRARY;
\r
356 SQX_ARCLIST * al = ((SQX_ARCLIST * (__stdcall *)(void *)) fpProc)(* _hArchive);
\r
359 CloseArchive(* _hArchive);
\r
360 return TPI_ERROR_UNDEFINED;
\r
362 * _nFileCount = al->dwItemCount;
\r
364 fpProc = ::GetAPIAddress("DoneArcFileList");
\r
365 if (fpProc == nullptr)
\r
367 CloseArchive(* _hArchive);
\r
368 return TPI_ERROR_U_USE_LIBRARY;
\r
370 ((void (__stdcall *)(void *, SQX_ARCLIST *)) fpProc)(* _hArchive, al);
\r
373 return TPI_ERROR_SUCCESS;
\r
376 int __stdcall CloseArchive
\r
381 FARPROC fpProc = ::GetAPIAddress("DoneArchive");
\r
382 if (fpProc == nullptr || _hArchive == nullptr)
\r
384 return TPI_ERROR_U_USE_LIBRARY;
\r
386 ((void (__stdcall *)(void *)) fpProc)(_hArchive);
\r
387 return TPI_ERROR_SUCCESS;
\r
390 int __stdcall GetFileInformation
\r
393 TPI_FILEINFO * _fiInfo,
\r
397 static wxULongLong_t s_nFileId;
\r
398 static SQX_ARCLISTNODE * aln;
\r
399 static SQX_ARCLIST * al;
\r
404 FARPROC fpProc = ::GetAPIAddress("InitArcFileList");
\r
405 if (fpProc == nullptr)
\r
407 return TPI_ERROR_U_USE_LIBRARY;
\r
409 al = ((SQX_ARCLIST * (__stdcall *)(void *)) fpProc)(_hArchive);
\r
412 return TPI_ERROR_UNDEFINED;
\r
415 fpProc = ::GetAPIAddress("InitFileList");
\r
416 if (fpProc == nullptr)
\r
418 return TPI_ERROR_U_USE_LIBRARY;
\r
420 fl = ((void * (__stdcall *)(void *)) fpProc)(_hArchive);
\r
423 return TPI_ERROR_UNDEFINED;
\r
426 fpProc = ::GetAPIAddress("AppendFileList");
\r
427 if (fpProc == nullptr)
\r
429 return TPI_ERROR_U_USE_LIBRARY;
\r
431 ((void (__stdcall *)(void *, void *, const wchar_t *)) fpProc)(_hArchive, fl, L"*");
\r
433 fpProc = ::GetAPIAddress("ListFiles");
\r
434 if (fpProc == nullptr)
\r
436 return TPI_ERROR_U_USE_LIBRARY;
\r
440 memset(& ai, 0, sizeof(SQX_ARCINFO));
\r
441 ai.cbSize = sizeof(SQX_ARCINFO);
\r
442 int nErrorCode = ErrorCodeConvert(((int (__stdcall *)(void *, void *, SQX_ARCLIST *, SQX_ARCINFO *)) fpProc)(_hArchive, fl, al, & ai));
\r
443 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
450 if (aln == nullptr)
\r
452 FARPROC fpProc = ::GetAPIAddress("DoneArcFileList");
\r
453 if (fpProc == nullptr)
\r
455 return TPI_ERROR_U_USE_LIBRARY;
\r
457 ((void (__stdcall *)(void *, SQX_ARCLIST *)) fpProc)(_hArchive, al);
\r
459 fpProc = ::GetAPIAddress("DoneFileList");
\r
460 if (fpProc == nullptr)
\r
462 return TPI_ERROR_U_USE_LIBRARY;
\r
464 ((void (__stdcall *)(void *, void *)) fpProc)(_hArchive, fl);
\r
466 return TPI_ERROR_S_ENDOFDATA;
\r
469 SQX_ARCNODE * an = aln->pArcNode;
\r
473 return GetFileInformation(_hArchive, _fiInfo, false);
\r
476 _fiInfo->eOSType = an->dwHostOS;
\r
477 _fiInfo->dwAttribute = an->dwAttributes;
\r
478 if (an->fEncrypted)
\r
480 _fiInfo->dwAttribute |= TPI_ATTRIBUTE_ENCRYPTED;
\r
482 _fiInfo->dwCRC32 = an->dwFileCRC;
\r
483 _fiInfo->nPackedSize = an->dwlSize;
\r
484 _fiInfo->nUnpackedSize = an->dwlSizeOrig;
\r
485 _fiInfo->nFileId = s_nFileId++;
\r
486 if (an->win32FileTime.fBlockPresent)
\r
488 _fiInfo->tmCreate = FileTimeToWxDateTime(& an->win32FileTime.ftCreationTime);
\r
489 _fiInfo->tmAccess = FileTimeToWxDateTime(& an->win32FileTime.ftLastAccessTime);
\r
490 _fiInfo->tmModify = FileTimeToWxDateTime(& an->win32FileTime.ftLastWriteTime);
\r
494 _fiInfo->tmModify.SetFromDOS(an->dwDosFileTime);
\r
496 _fiInfo->szComment = WC2String(an->pszComment);
\r
497 _fiInfo->szStoredName = WC2String(an->pszFileName);
\r
498 _fiInfo->fnFileName = wxFileName(_fiInfo->szStoredName);
\r
499 _fiInfo->szMethod =
\r
500 an->dwMethod == SQX_METHOD_STORED ? wxT("store") :
\r
501 an->dwMethod == SQX_METHOD_NORMAL ? wxT("lzh-1") :
\r
502 an->dwMethod == SQX_METHOD_GOOD ? wxT("lzh-2") :
\r
503 an->dwMethod == SQX_METHOD_HIGH ? wxT("lzh-3") :
\r
504 an->dwMethod == SQX_METHOD_BEST ? wxT("lzh-4") :
\r
505 an->dwMethod == SQX_METHOD_AUDIO ? wxT("audio") :
\r
506 an->dwMethod == SQX_METHOD_TEXT ? wxT("text") :
\r
507 an->dwMethod == SQX_METHOD_ULTRA ? wxT("ultra") : wxT("unknown");
\r
509 return TPI_ERROR_SUCCESS;
\r
512 int __stdcall GetArchiveInformation
\r
515 TPI_ARCHIVEINFO * _aiInfo
\r
518 FARPROC fpProc = ::GetAPIAddress("InitArcFileList");
\r
519 if (fpProc == nullptr)
\r
521 return TPI_ERROR_U_USE_LIBRARY;
\r
523 SQX_ARCLIST * al = ((SQX_ARCLIST * (__stdcall *)(void *)) fpProc)(_hArchive);
\r
526 return TPI_ERROR_UNDEFINED;
\r
529 fpProc = ::GetAPIAddress("InitFileList");
\r
530 if (fpProc == nullptr)
\r
532 return TPI_ERROR_U_USE_LIBRARY;
\r
534 void * fl = ((void * (__stdcall *)(void *)) fpProc)(_hArchive);
\r
537 return TPI_ERROR_UNDEFINED;
\r
540 fpProc = ::GetAPIAddress("AppendFileList");
\r
541 if (fpProc == nullptr)
\r
543 return TPI_ERROR_U_USE_LIBRARY;
\r
545 ((void (__stdcall *)(void *, void *, const wchar_t *)) fpProc)(_hArchive, fl, L"*");
\r
547 fpProc = ::GetAPIAddress("ListFiles");
\r
548 if (fpProc == nullptr)
\r
550 return TPI_ERROR_U_USE_LIBRARY;
\r
554 memset(& ai, 0, sizeof(SQX_ARCINFO));
\r
555 ai.cbSize = sizeof(SQX_ARCINFO);
\r
556 int nErrorCode = ErrorCodeConvert(((int (__stdcall *)(void *, void *, SQX_ARCLIST *, SQX_ARCINFO *)) fpProc)(_hArchive, fl, al, & ai));
\r
557 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
562 fpProc = ::GetAPIAddress("DoneArcFileList");
\r
563 if (fpProc == nullptr)
\r
565 return TPI_ERROR_U_USE_LIBRARY;
\r
567 ((void (__stdcall *)(void *, SQX_ARCLIST *)) fpProc)(_hArchive, al);
\r
569 fpProc = ::GetAPIAddress("DoneFileList");
\r
570 if (fpProc == nullptr)
\r
572 return TPI_ERROR_U_USE_LIBRARY;
\r
574 ((void (__stdcall *)(void *, void *)) fpProc)(_hArchive, fl);
\r
576 _aiInfo->fSolid = ai.fSolid == TRUE;
\r
577 _aiInfo->fEncryptHeader = ai.fHeaderEncrypted == TRUE;
\r
578 _aiInfo->fEncryptData = ai.dwEncryption != SQX_ENCRYPTION_NONE;
\r
579 _aiInfo->eOSType = ai.dwHostOS;
\r
580 _aiInfo->nRecoveryRecord= ai.fRecoveryData;
\r
581 _aiInfo->wCompressRatio = ai.iRatio * 10;
\r
582 _aiInfo->nFileSize = ai.dwlUncompressedSize;
\r
583 _aiInfo->nPackedSize = ai.dwlCompressedSize;
\r
584 _aiInfo->nUnpackedSize = ai.dwlUncompressedSize;
\r
585 if (ai.fArchiveComment)
\r
587 fpProc = ::GetAPIAddress("GetArchiveComment");
\r
588 if (fpProc == nullptr)
\r
590 return TPI_ERROR_U_USE_LIBRARY;
\r
593 memset(sz, 0, sizeof(sz));
\r
594 ((void (__stdcall *)(void *, wchar_t *, DWORD)) fpProc)(_hArchive, sz, sizeof(sz) - 1);
\r
595 _aiInfo->szComment = WC2String(sz);
\r
597 if (ai.avInfo.fAVInfoPresent)
\r
599 wxDateTime tm = FileTimeToWxDateTime(& ai.avInfo.ftCreationTime);
\r
600 _aiInfo->szComment += wxT("\nSignatured by ") + WC2String(ai.avInfo.szAV_ID) + wxT(" at ") + tm.Format(wxT("%Y/%m/%d %H:%M:%S"));
\r
602 GetFormatInformation(& _aiInfo->fiInfo, ai.dwFileFormat == SQX_FILEFORMAT_10);
\r
603 return TPI_ERROR_SUCCESS;
\r
606 int __stdcall Command
\r
608 wxULongLong_t _eCommand,
\r
609 TPI_SWITCHES * _swInfo,
\r
611 const wxArrayString & _szFiles
\r
614 int nErrorCode = TPI_ERROR_SUCCESS;
\r
615 if (_eCommand == TPI_COMMAND_CREATE)
\r
617 nErrorCode = OpenArchive(_swInfo->szArcName, & _hArchive);
\r
618 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
625 void * fl = nullptr;
\r
626 if (_eCommand != TPI_COMMAND_TEST && _eCommand != TPI_COMMAND_REPAIR)
\r
628 fpProc = ::GetAPIAddress("InitFileList");
\r
629 if (fpProc == nullptr)
\r
631 if (_eCommand == TPI_COMMAND_CREATE)
\r
633 CloseArchive(_hArchive);
\r
635 return TPI_ERROR_U_USE_LIBRARY;
\r
637 fl = ((void * (__stdcall *)(void *)) fpProc)(_hArchive);
\r
640 if (_eCommand == TPI_COMMAND_CREATE)
\r
642 CloseArchive(_hArchive);
\r
644 return TPI_ERROR_UNDEFINED;
\r
647 fpProc = ::GetAPIAddress("AppendFileList");
\r
648 if (fpProc == nullptr)
\r
650 if (_eCommand == TPI_COMMAND_CREATE)
\r
652 CloseArchive(_hArchive);
\r
654 return TPI_ERROR_U_USE_LIBRARY;
\r
656 for (size_t i = 0; i < _szFiles.Count(); i++)
\r
658 ((void (__stdcall *)(void *, void *, const wchar_t *)) fpProc)(_hArchive, fl, _szFiles[i].c_str());
\r
662 // グローバル変数にポインタを保存。
\r
664 _eCommand == TPI_COMMAND_CREATE ? ::GetAPIAddress("CompressFiles") :
\r
665 // _eCommand == TPI_COMMAND_ADD ? ::GetAPIAddress("CompressFiles") :
\r
666 _eCommand == TPI_COMMAND_EXTRACT ? ::GetAPIAddress("ExtractFiles") :
\r
667 _eCommand == TPI_COMMAND_DELETE ? ::GetAPIAddress("DeleteFiles") :
\r
668 _eCommand == TPI_COMMAND_TEST ? ::GetAPIAddress("TestArchive") :
\r
669 _eCommand == TPI_COMMAND_REPAIR ? ::GetAPIAddress("RepairArchive") : nullptr;
\r
670 if (fpProc == nullptr)
\r
672 if (_eCommand == TPI_COMMAND_CREATE)
\r
674 CloseArchive(_hArchive);
\r
676 return TPI_ERROR_U_USE_LIBRARY;
\r
681 case TPI_COMMAND_CREATE:
\r
682 // case TPI_COMMAND_ADD:
\r
684 SQX_COMPRESSOPTIONS co;
\r
685 memset(& co, 0, sizeof(co));
\r
686 co.cbSize = sizeof(co);
\r
687 co.dwFileFormat = _swInfo->nArchiveType;
\r
688 co.compOptions.dwCompRate = _swInfo->nCompressLevel;
\r
689 co.compOptions.fSolidFlag = true;
\r
690 co.compOptions.dwMultimediaCompression = _swInfo->fMMOptimize;
\r
691 co.sfxCommand.fCreateSfx = _swInfo->fMakeSFX;
\r
692 co.dwRecoveryData = _swInfo->nRecoveryRecord;
\r
693 co.pszMainComment = _swInfo->szComment.c_str();
\r
694 co.dwEncryption = _swInfo->szPassword.IsEmpty() ? SQX_ENCRYPTION_NONE : SQX_ENCRYPTION_AES_256BIT;
\r
695 co.fEncryptHeaders = _swInfo->fEncryptHeader;
\r
696 co.dwFileNames = SQX_FILENAME_UNICODE;
\r
697 co.fRetainFolderStructure = _swInfo->fStoreDirectoryPathes;
\r
698 co.fStoreACL = true;
\r
699 co.fStoreStreams = true;
\r
700 co.fStoreWin32FileTime = true;
\r
701 co.fAutoSaveComments = true;
\r
702 co.dwlVolumeSize = _swInfo->nSplitSize;
\r
703 wcsncpy(co.szInputPath, _swInfo->fnDestinationDirectory.GetFullPath().c_str(), sizeof(co.szInputPath) / sizeof(wchar_t) - 1);
\r
704 wcsncpy(co.szPassword, _swInfo->szPassword.c_str(), sizeof(co.szPassword) / sizeof(wchar_t) - 1);
\r
705 if (_swInfo->fEncryptHeader)
\r
707 wcsncpy(co.szPasswordHeader, _swInfo->szPassword.c_str(), sizeof(co.szPasswordHeader) / sizeof(wchar_t) - 1);
\r
709 nErrorCode = ErrorCodeConvert(((int (__stdcall *)(void *, SQXCALLBACK, void *, void *, SQX_COMPRESSOPTIONS *)) fpProc)(_hArchive, CallbackProc, nullptr, fl, & co));
\r
712 case TPI_COMMAND_EXTRACT:
\r
714 SQX_EXTRACTOPTIONS eo;
\r
715 memset(& eo, 0, sizeof(eo));
\r
716 eo.cbSize = sizeof(eo);
\r
717 eo.fCreateFolders = _swInfo->fStoreDirectoryPathes;
\r
718 eo.fKeepBrokenFiles = true;
\r
719 eo.fRestoreACLs = true;
\r
720 eo.fRestoreStreams = true;
\r
721 eo.fRestoreUnicodeNames = true;
\r
722 eo.fRestoreWin32FileTimes = true;
\r
723 eo.fRestoreDirectoryTimeStamps = true;
\r
724 eo.fAutoRestoreComments = true;
\r
725 eo.fSetZoneID = true;
\r
726 wcsncpy(eo.szPassword, _swInfo->szPassword.c_str(), sizeof(eo.szPassword) / sizeof(wchar_t) - 1);
\r
727 wcsncpy(eo.szPasswordHeader, _swInfo->szPassword.c_str(), sizeof(eo.szPasswordHeader) / sizeof(wchar_t) - 1);
\r
728 wcsncpy(eo.szOutputPath, _swInfo->fnDestinationDirectory.GetFullPath().c_str(), sizeof(eo.szOutputPath) / sizeof(wchar_t) - 1);
\r
729 nErrorCode = ErrorCodeConvert(((int (__stdcall *)(void *, SQXCALLBACK, void *, void *, SQX_EXTRACTOPTIONS *)) fpProc)(_hArchive, CallbackProc, nullptr, fl, & eo));
\r
732 case TPI_COMMAND_DELETE:
\r
733 nErrorCode = ErrorCodeConvert(((int (__stdcall *)(void *, SQXCALLBACK, void *, void *)) fpProc)(_hArchive, CallbackProc, nullptr, fl));
\r
735 case TPI_COMMAND_TEST:
\r
736 nErrorCode = ErrorCodeConvert(((int (__stdcall *)(void *, SQXCALLBACK, void *)) fpProc)(_hArchive, CallbackProc, nullptr));
\r
738 case TPI_COMMAND_REPAIR:
\r
740 wxString sz = _swInfo->szArcName + wxT("_repaired");
\r
741 nErrorCode = ErrorCodeConvert(((int (__stdcall *)(void *, const wchar_t *, SQX_ARCLIST *, SQX_ARCLIST *)) fpProc)(_hArchive, sz.c_str(), nullptr, nullptr));
\r
746 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
748 if (_eCommand == TPI_COMMAND_CREATE)
\r
750 CloseArchive(_hArchive);
\r
755 if (_eCommand != TPI_COMMAND_TEST && _eCommand != TPI_COMMAND_REPAIR)
\r
757 fpProc = ::GetAPIAddress("DoneFileList");
\r
758 if (fpProc == nullptr)
\r
760 if (_eCommand == TPI_COMMAND_CREATE)
\r
762 CloseArchive(_hArchive);
\r
764 return TPI_ERROR_U_USE_LIBRARY;
\r
766 ((void (__stdcall *)(void *, void *)) fpProc)(_hArchive, fl);
\r
769 return _eCommand == TPI_COMMAND_CREATE ? CloseArchive(_hArchive) : TPI_ERROR_SUCCESS;
\r