OSDN Git Service

C++11のauto, nullptrを導入。
[tpi/lychee.git] / src / plugin / sqxArc / sqxArc.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 <windows.h>\r
30 #include "sqxArc.h"\r
31 \r
32 //******************************************************************************\r
33 //    Global varients\r
34 //******************************************************************************\r
35 \r
36 HMODULE g_hLib;\r
37 TPI_PROC g_prProc;\r
38 \r
39 //******************************************************************************\r
40 //    Inside Functions\r
41 //******************************************************************************\r
42 \r
43 #define GetAPIAddress(name) GetProcAddress(g_hLib, "Sqx" name)\r
44 \r
45 int ErrorCodeConvert(int nErrorCode)\r
46 {\r
47         switch (nErrorCode)\r
48         {\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
125         }\r
126 }\r
127 \r
128 //******************************************************************************\r
129 //    Callback Wrapper\r
130 //******************************************************************************\r
131 \r
132 int CALLBACK CallbackProc(void *, SQX_CALLBACKINFO * pCallbackInfo)\r
133 {\r
134         static TPI_PROCESSINFO piInfo;\r
135         switch (pCallbackInfo->dwCallbackType)\r
136         {\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
143                 return\r
144                         g_prProc == nullptr || g_prProc(TPI_NOTIFY_COMMON, & piInfo) != TPI_CALLBACK_CANCEL ?\r
145                                 SQX_PROGRESS_OK : SQX_PROGRESS_CANCEL;\r
146 \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
151                 return\r
152                         g_prProc == nullptr || g_prProc(TPI_NOTIFY_COMMON, & piInfo) != TPI_CALLBACK_CANCEL ?\r
153                                 SQX_PROGRESS_OK : SQX_PROGRESS_CANCEL;\r
154 \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
165                 return\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
169 \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
176                 {\r
177                         return SQX_PASSWORD_CANCEL;\r
178                 }\r
179                 wcsncpy(pCallbackInfo->szCryptKey, piInfo.szParam.c_str(), sizeof(pCallbackInfo->szCryptKey));\r
180                 return SQX_PASSWORD_OK;\r
181 \r
182         case SQX_CALLBACK_SKIP:\r
183                 return SQX_SKIPFILE_SKIP;\r
184 \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
190                 {\r
191                         return SQX_NEXTDISK_CANCEL;\r
192                 }\r
193                 wcsncpy(pCallbackInfo->szNextDiskPath, piInfo.szParam.c_str(), sizeof(pCallbackInfo->szNextDiskPath));\r
194                 return SQX_NEXTDISK_OK;\r
195 \r
196         case SQX_CALLBACK_SIGNAL:\r
197                 piInfo.eMessage = TPI_MESSAGE_STATUS;\r
198                 switch (pCallbackInfo->dwSignal)\r
199                 {\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
206                         break;\r
207                 case SQX_SIGNAL_TEMP_ARC_COPY:\r
208                         piInfo.eStatus  = TPI_STATUS_COPYARCHIVE;\r
209                         break;\r
210                 default:\r
211                         return 0;\r
212                 }\r
213 \r
214                 // コールバック関数に送信。\r
215                 if (g_prProc != nullptr)\r
216                 {\r
217                         g_prProc(TPI_NOTIFY_COMMON, & piInfo);\r
218                 }\r
219                 return 0;\r
220 \r
221         default:\r
222                 return 0;\r
223         }\r
224 }\r
225 \r
226 //******************************************************************************\r
227 //    Functions\r
228 //******************************************************************************\r
229 \r
230 #ifdef __cplusplus\r
231 extern "C"\r
232 {\r
233 #endif\r
234 \r
235 int __stdcall GetPluginInformation\r
236 (\r
237         unsigned int _uInfoId,\r
238         wxULongLong_t,\r
239         void * _pPtr\r
240 )\r
241 {\r
242         if (_pPtr == nullptr)\r
243         {\r
244                 return TPI_ERROR_D_PARAMETER;\r
245         }\r
246         switch (_uInfoId)\r
247         {\r
248         case TPI_INFO_VERSION_MAJOR:\r
249         case TPI_INFO_VERSION_MINOR:\r
250                 * (int *) _pPtr = 0;\r
251                 break;\r
252         case TPI_INFO_VERSION_API:\r
253                 * (int *) _pPtr = 2;\r
254                 break;\r
255         case TPI_INFO_HANDLE_ON_COMMAND:\r
256                 * (int *) _pPtr = 1;\r
257                 break;\r
258         default:\r
259                 return TPI_ERROR_D_UNSUPPORTED;\r
260         }\r
261         return TPI_ERROR_SUCCESS;\r
262 }\r
263 \r
264 int __stdcall GetFormatInformation(TPI_FORMATINFO * _fiInfo, bool _bFirst)\r
265 {\r
266         static int s_uFileId = 0;\r
267         if (s_uFileId == 2)\r
268         {\r
269                 return TPI_ERROR_S_ENDOFDATA;\r
270         }\r
271         if (_bFirst)\r
272         {\r
273                 s_uFileId = 0;\r
274         }\r
275 \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
294 \r
295         return TPI_ERROR_SUCCESS;\r
296 }\r
297 \r
298 int __stdcall LoadPlugin\r
299 (\r
300         const wxString &,\r
301         TPI_PROC _prProc,\r
302         wxULongLong_t\r
303 )\r
304 {\r
305         ::RemoveCwdFromSearchPath();\r
306         g_hLib = ::LoadLibrary(L"sqx20u.dll");\r
307         if (g_hLib == nullptr)\r
308         {\r
309                 return TPI_ERROR_U_LOAD_LIBRARY;\r
310         }\r
311 \r
312         // コールバック関数を設定。\r
313         if (_prProc != nullptr)\r
314         {\r
315                 g_prProc = * _prProc;\r
316         }\r
317         return TPI_ERROR_SUCCESS;\r
318 }\r
319 \r
320 int __stdcall FreePlugin\r
321 (\r
322         void * // _pReserved\r
323 )\r
324 {\r
325         ::FreeLibrary(g_hLib);\r
326         return TPI_ERROR_SUCCESS;\r
327 }\r
328 \r
329 int __stdcall OpenArchive\r
330 (\r
331         const wxString & _szArcName,\r
332         void * * _hArchive,\r
333         wxULongLong_t * _nFileCount\r
334 )\r
335 {\r
336         FARPROC fpProc = ::GetAPIAddress("InitArchive");\r
337         if (fpProc == nullptr)\r
338         {\r
339                 return TPI_ERROR_U_USE_LIBRARY;\r
340         }\r
341 \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
344         {\r
345                 return nErrorCode;\r
346         }\r
347 \r
348         if (_nFileCount != nullptr)\r
349         {\r
350                 fpProc = ::GetAPIAddress("InitArcFileList");\r
351                 if (fpProc == nullptr)\r
352                 {\r
353                         CloseArchive(* _hArchive);\r
354                         return TPI_ERROR_U_USE_LIBRARY;\r
355                 }\r
356                 SQX_ARCLIST * al = ((SQX_ARCLIST * (__stdcall *)(void *)) fpProc)(* _hArchive);\r
357                 if (al == nullptr)\r
358                 {\r
359                         CloseArchive(* _hArchive);\r
360                         return TPI_ERROR_UNDEFINED;\r
361                 }\r
362                 * _nFileCount = al->dwItemCount;\r
363 \r
364                 fpProc = ::GetAPIAddress("DoneArcFileList");\r
365                 if (fpProc == nullptr)\r
366                 {\r
367                         CloseArchive(* _hArchive);\r
368                         return TPI_ERROR_U_USE_LIBRARY;\r
369                 }\r
370                 ((void (__stdcall *)(void *, SQX_ARCLIST *)) fpProc)(* _hArchive, al);\r
371         }\r
372 \r
373         return TPI_ERROR_SUCCESS;\r
374 }\r
375 \r
376 int __stdcall CloseArchive\r
377 (\r
378         void * _hArchive\r
379 )\r
380 {\r
381         FARPROC fpProc = ::GetAPIAddress("DoneArchive");\r
382         if (fpProc == nullptr || _hArchive == nullptr)\r
383         {\r
384                 return TPI_ERROR_U_USE_LIBRARY;\r
385         }\r
386         ((void (__stdcall *)(void *)) fpProc)(_hArchive);\r
387         return TPI_ERROR_SUCCESS;\r
388 }\r
389 \r
390 int __stdcall GetFileInformation\r
391 (\r
392         void * _hArchive,\r
393         TPI_FILEINFO * _fiInfo,\r
394         bool _bFirst\r
395 )\r
396 {\r
397         static wxULongLong_t s_nFileId;\r
398         static SQX_ARCLISTNODE * aln;\r
399         static SQX_ARCLIST * al;\r
400         static void * fl;\r
401         if (_bFirst)\r
402         {\r
403                 s_nFileId = 0;\r
404                 FARPROC fpProc = ::GetAPIAddress("InitArcFileList");\r
405                 if (fpProc == nullptr)\r
406                 {\r
407                         return TPI_ERROR_U_USE_LIBRARY;\r
408                 }\r
409                 al = ((SQX_ARCLIST * (__stdcall *)(void *)) fpProc)(_hArchive);\r
410                 if (al == nullptr)\r
411                 {\r
412                         return TPI_ERROR_UNDEFINED;\r
413                 }\r
414 \r
415                 fpProc = ::GetAPIAddress("InitFileList");\r
416                 if (fpProc == nullptr)\r
417                 {\r
418                         return TPI_ERROR_U_USE_LIBRARY;\r
419                 }\r
420                 fl = ((void * (__stdcall *)(void *)) fpProc)(_hArchive);\r
421                 if (fl == nullptr)\r
422                 {\r
423                         return TPI_ERROR_UNDEFINED;\r
424                 }\r
425 \r
426                 fpProc = ::GetAPIAddress("AppendFileList");\r
427                 if (fpProc == nullptr)\r
428                 {\r
429                         return TPI_ERROR_U_USE_LIBRARY;\r
430                 }\r
431                 ((void (__stdcall *)(void *, void *, const wchar_t *)) fpProc)(_hArchive, fl, L"*");\r
432 \r
433                 fpProc = ::GetAPIAddress("ListFiles");\r
434                 if (fpProc == nullptr)\r
435                 {\r
436                         return TPI_ERROR_U_USE_LIBRARY;\r
437                 }\r
438 \r
439                 SQX_ARCINFO ai;\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
444                 {\r
445                         return nErrorCode;\r
446                 }\r
447                 aln = al->pHead;\r
448         }\r
449 \r
450         if (aln == nullptr)\r
451         {\r
452                 FARPROC fpProc = ::GetAPIAddress("DoneArcFileList");\r
453                 if (fpProc == nullptr)\r
454                 {\r
455                         return TPI_ERROR_U_USE_LIBRARY;\r
456                 }\r
457                 ((void (__stdcall *)(void *, SQX_ARCLIST *)) fpProc)(_hArchive, al);\r
458 \r
459                 fpProc = ::GetAPIAddress("DoneFileList");\r
460                 if (fpProc == nullptr)\r
461                 {\r
462                         return TPI_ERROR_U_USE_LIBRARY;\r
463                 }\r
464                 ((void (__stdcall *)(void *, void *)) fpProc)(_hArchive, fl);\r
465 \r
466                 return TPI_ERROR_S_ENDOFDATA;\r
467         }\r
468 \r
469         SQX_ARCNODE * an = aln->pArcNode;\r
470         if (! an->fTagged)\r
471         {\r
472                 aln = aln->pNext;\r
473                 return GetFileInformation(_hArchive, _fiInfo, false);\r
474         }\r
475 \r
476         _fiInfo->eOSType        = an->dwHostOS;\r
477         _fiInfo->dwAttribute    = an->dwAttributes;\r
478         if (an->fEncrypted)\r
479         {\r
480                 _fiInfo->dwAttribute |= TPI_ATTRIBUTE_ENCRYPTED;\r
481         }\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
487         {\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
491         }\r
492         else\r
493         {\r
494                 _fiInfo->tmModify.SetFromDOS(an->dwDosFileTime);\r
495         }\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
508         aln = aln->pNext;\r
509         return TPI_ERROR_SUCCESS;\r
510 }\r
511 \r
512 int __stdcall GetArchiveInformation\r
513 (\r
514         void * _hArchive,\r
515         TPI_ARCHIVEINFO * _aiInfo\r
516 )\r
517 {\r
518         FARPROC fpProc = ::GetAPIAddress("InitArcFileList");\r
519         if (fpProc == nullptr)\r
520         {\r
521                 return TPI_ERROR_U_USE_LIBRARY;\r
522         }\r
523         SQX_ARCLIST * al = ((SQX_ARCLIST * (__stdcall *)(void *)) fpProc)(_hArchive);\r
524         if (al == nullptr)\r
525         {\r
526                 return TPI_ERROR_UNDEFINED;\r
527         }\r
528 \r
529         fpProc = ::GetAPIAddress("InitFileList");\r
530         if (fpProc == nullptr)\r
531         {\r
532                 return TPI_ERROR_U_USE_LIBRARY;\r
533         }\r
534         void * fl = ((void * (__stdcall *)(void *)) fpProc)(_hArchive);\r
535         if (fl == nullptr)\r
536         {\r
537                 return TPI_ERROR_UNDEFINED;\r
538         }\r
539 \r
540         fpProc = ::GetAPIAddress("AppendFileList");\r
541         if (fpProc == nullptr)\r
542         {\r
543                 return TPI_ERROR_U_USE_LIBRARY;\r
544         }\r
545         ((void (__stdcall *)(void *, void *, const wchar_t *)) fpProc)(_hArchive, fl, L"*");\r
546 \r
547         fpProc = ::GetAPIAddress("ListFiles");\r
548         if (fpProc == nullptr)\r
549         {\r
550                 return TPI_ERROR_U_USE_LIBRARY;\r
551         }\r
552 \r
553         SQX_ARCINFO ai;\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
558         {\r
559                 return nErrorCode;\r
560         }\r
561 \r
562         fpProc = ::GetAPIAddress("DoneArcFileList");\r
563         if (fpProc == nullptr)\r
564         {\r
565                 return TPI_ERROR_U_USE_LIBRARY;\r
566         }\r
567         ((void (__stdcall *)(void *, SQX_ARCLIST *)) fpProc)(_hArchive, al);\r
568 \r
569         fpProc = ::GetAPIAddress("DoneFileList");\r
570         if (fpProc == nullptr)\r
571         {\r
572                 return TPI_ERROR_U_USE_LIBRARY;\r
573         }\r
574         ((void (__stdcall *)(void *, void *)) fpProc)(_hArchive, fl);\r
575 \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
586         {\r
587                 fpProc = ::GetAPIAddress("GetArchiveComment");\r
588                 if (fpProc == nullptr)\r
589                 {\r
590                         return TPI_ERROR_U_USE_LIBRARY;\r
591                 }\r
592                 wchar_t sz[4097];\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
596         }\r
597         if (ai.avInfo.fAVInfoPresent)\r
598         {\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
601         }\r
602         GetFormatInformation(& _aiInfo->fiInfo, ai.dwFileFormat == SQX_FILEFORMAT_10);\r
603         return TPI_ERROR_SUCCESS;\r
604 }\r
605 \r
606 int __stdcall Command\r
607 (\r
608         wxULongLong_t _eCommand,\r
609         TPI_SWITCHES * _swInfo,\r
610         void * _hArchive,\r
611         const wxArrayString & _szFiles\r
612 )\r
613 {\r
614         int nErrorCode = TPI_ERROR_SUCCESS;\r
615         if (_eCommand == TPI_COMMAND_CREATE)\r
616         {\r
617                 nErrorCode = OpenArchive(_swInfo->szArcName, & _hArchive);\r
618                 if (nErrorCode != TPI_ERROR_SUCCESS)\r
619                 {\r
620                         return nErrorCode;\r
621                 }\r
622         }\r
623 \r
624         FARPROC fpProc;\r
625         void * fl = nullptr;\r
626         if (_eCommand != TPI_COMMAND_TEST && _eCommand != TPI_COMMAND_REPAIR)\r
627         {\r
628                 fpProc = ::GetAPIAddress("InitFileList");\r
629                 if (fpProc == nullptr)\r
630                 {\r
631                         if (_eCommand == TPI_COMMAND_CREATE)\r
632                         {\r
633                                 CloseArchive(_hArchive);\r
634                         }\r
635                         return TPI_ERROR_U_USE_LIBRARY;\r
636                 }\r
637                 fl = ((void * (__stdcall *)(void *)) fpProc)(_hArchive);\r
638                 if (fl == nullptr)\r
639                 {\r
640                         if (_eCommand == TPI_COMMAND_CREATE)\r
641                         {\r
642                                 CloseArchive(_hArchive);\r
643                         }\r
644                         return TPI_ERROR_UNDEFINED;\r
645                 }\r
646 \r
647                 fpProc = ::GetAPIAddress("AppendFileList");\r
648                 if (fpProc == nullptr)\r
649                 {\r
650                         if (_eCommand == TPI_COMMAND_CREATE)\r
651                         {\r
652                                 CloseArchive(_hArchive);\r
653                         }\r
654                         return TPI_ERROR_U_USE_LIBRARY;\r
655                 }\r
656                 for (size_t i = 0; i < _szFiles.Count(); i++)\r
657                 {\r
658                         ((void (__stdcall *)(void *, void *, const wchar_t *)) fpProc)(_hArchive, fl, _szFiles[i].c_str());\r
659                 }\r
660         }\r
661 \r
662         // グローバル変数にポインタを保存。\r
663         fpProc =\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
671         {\r
672                 if (_eCommand == TPI_COMMAND_CREATE)\r
673                 {\r
674                         CloseArchive(_hArchive);\r
675                 }\r
676                 return TPI_ERROR_U_USE_LIBRARY;\r
677         }\r
678 \r
679         switch (_eCommand)\r
680         {\r
681         case TPI_COMMAND_CREATE:\r
682 //      case TPI_COMMAND_ADD:\r
683         {\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
706                 {\r
707                         wcsncpy(co.szPasswordHeader, _swInfo->szPassword.c_str(), sizeof(co.szPasswordHeader) / sizeof(wchar_t) - 1);\r
708                 }\r
709                 nErrorCode = ErrorCodeConvert(((int (__stdcall *)(void *, SQXCALLBACK, void *, void *, SQX_COMPRESSOPTIONS *)) fpProc)(_hArchive, CallbackProc, nullptr, fl, & co));\r
710                 break;\r
711         }\r
712         case TPI_COMMAND_EXTRACT:\r
713         {\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
730                 break;\r
731         }\r
732         case TPI_COMMAND_DELETE:\r
733                 nErrorCode = ErrorCodeConvert(((int (__stdcall *)(void *, SQXCALLBACK, void *, void *)) fpProc)(_hArchive, CallbackProc, nullptr, fl));\r
734                 break;\r
735         case TPI_COMMAND_TEST:\r
736                 nErrorCode = ErrorCodeConvert(((int (__stdcall *)(void *, SQXCALLBACK, void *)) fpProc)(_hArchive, CallbackProc, nullptr));\r
737                 break;\r
738         case TPI_COMMAND_REPAIR:\r
739         {\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
742                 break;\r
743         }\r
744         }\r
745 \r
746         if (nErrorCode != TPI_ERROR_SUCCESS)\r
747         {\r
748                 if (_eCommand == TPI_COMMAND_CREATE)\r
749                 {\r
750                         CloseArchive(_hArchive);\r
751                 }\r
752                 return nErrorCode;\r
753         }\r
754 \r
755         if (_eCommand != TPI_COMMAND_TEST && _eCommand != TPI_COMMAND_REPAIR)\r
756         {\r
757                 fpProc = ::GetAPIAddress("DoneFileList");\r
758                 if (fpProc == nullptr)\r
759                 {\r
760                         if (_eCommand == TPI_COMMAND_CREATE)\r
761                         {\r
762                                 CloseArchive(_hArchive);\r
763                         }\r
764                         return TPI_ERROR_U_USE_LIBRARY;\r
765                 }\r
766                 ((void (__stdcall *)(void *, void *)) fpProc)(_hArchive, fl);\r
767         }\r
768 \r
769         return _eCommand == TPI_COMMAND_CREATE ? CloseArchive(_hArchive) : TPI_ERROR_SUCCESS;\r
770 }\r
771 \r
772 #ifdef __cplusplus\r
773 }\r
774 #endif\r