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
38 TPI_SWITCHES * g_swInfo;
\r
39 const wxArrayString * g_asFiles;
\r
41 //******************************************************************************
\r
43 //******************************************************************************
\r
45 #define GetAPIAddress(name) GetProcAddress(g_hLib, "EGG_" name)
\r
47 int ErrorCodeConvert(int nErrorCode)
\r
51 case EGG_ERROR_FAIL: return TPI_ERROR_UNDEFINED;
\r
52 case EGG_ERROR_SUCCESS: return TPI_ERROR_SUCCESS;
\r
53 case EGG_ERROR_SKIP: return TPI_ERROR_D_SKIPPED;
\r
54 case EGG_ERROR_CANCEL: return TPI_ERROR_D_SKIPPED;
\r
55 case EGG_ERROR_IO: return TPI_ERROR_IO_MISC;
\r
56 case EGG_ERROR_TYPEMISMATCH:return TPI_ERROR_ARC_UNSUPPORTED;
\r
57 case EGG_ERROR_FILE: return TPI_ERROR_IO_MISC;
\r
58 case EGG_ERROR_FORMAT: return TPI_ERROR_IO_ARC_MISC;
\r
59 case EGG_ERROR_ALGORITHM: return TPI_ERROR_UNDEFINED;
\r
60 default: return TPI_ERROR_UNDEFINED;
\r
64 int __stdcall GetFileInformation2
\r
67 TPI_FILEINFO * _fiInfo,
\r
68 wxULongLong_t _nIndex
\r
71 static FARPROC fpProc = ::GetAPIAddress("GetFileHeader");
\r
74 return TPI_ERROR_U_USE_LIBRARY;
\r
77 EGGFileHeader fhInfo;
\r
78 int nErrorCode = ErrorCodeConvert(((UINT (__cdecl *)(void *, size_t, EGGFileHeader *)) fpProc)(_hArchive, _nIndex, & fhInfo));
\r
79 if (nErrorCode == TPI_ERROR_SUCCESS)
\r
81 _fiInfo->dwAttribute = fhInfo.attribute;
\r
82 if (fhInfo.encrypted)
\r
84 _fiInfo->dwAttribute |= TPI_ATTRIBUTE_ENCRYPTED;
\r
86 _fiInfo->dwCRC32 = fhInfo.crc;
\r
87 _fiInfo->nPackedSize = fhInfo.packedSize;
\r
88 _fiInfo->nUnpackedSize = fhInfo.unpackedSize;
\r
89 _fiInfo->tmModified = fhInfo.lastModified;
\r
90 _fiInfo->szComment = WC2String(fhInfo.comment);
\r
91 _fiInfo->szStoredName = WC2String(fhInfo.fileName);
\r
92 _fiInfo->szMethod = fhInfo.method == 2 ? wxT("ALZ") : fhInfo.method == 0 ? wxT("EGG") : wxT("unknown");
\r
93 _fiInfo->nFileId = _nIndex;
\r
94 _fiInfo->fnFileName = wxFileName(_fiInfo->szStoredName);
\r
100 //******************************************************************************
\r
101 // Callback Wrapper
\r
102 //******************************************************************************
\r
104 UINT __cdecl CallbackProc(void * user, UINT code, void* param)
\r
107 static TPI_PROCESSINFO piInfo;
\r
108 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
112 case eggevent::Start::CODE:
\r
113 piInfo.eStatus = TPI_STATUS_OPENARCHIVE;
\r
115 case eggevent::Extract::CODE:
\r
118 eggevent::Extract * p = (eggevent::Extract *) param;
\r
119 GetFileInformation2(* (void **) user, & piInfo.fiInfo, p->index);
\r
120 if (g_asFiles->Count() != 0 && g_asFiles->Index(piInfo.fiInfo.szStoredName) == wxNOT_FOUND)
\r
122 return EGG_ERROR_SKIP;
\r
126 piInfo.eMessage = TPI_MESSAGE_ASK;
\r
127 piInfo.eStatus = TPI_PARAM_DEST;
\r
128 piInfo.fnDestination = wxFileName(g_swInfo->fnDestinationDirectory.GetPathWithSep() + (g_swInfo->fStoreDirectoryPathes ? piInfo.fiInfo.fnFileName.GetFullPath() : piInfo.fiInfo.fnFileName.GetFullName()));
\r
129 if (g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & piInfo) != TPI_CALLBACK_CONTINUE)
\r
131 return EGG_ERROR_CANCEL;
\r
133 if (! piInfo.fnDestination.IsOk())
\r
135 return EGG_ERROR_SKIP;
\r
139 wcsncpy(p->fileName, piInfo.fnDestination.GetFullPath().wchar_str(), MAX_PATH - 1);
\r
140 return EGG_ERROR_SUCCESS;
\r
142 case eggevent::Test::CODE:
\r
145 eggevent::Test * p = (eggevent::Test *) param;
\r
146 GetFileInformation2(* (void **) user, & piInfo.fiInfo, p->index);
\r
147 if (g_asFiles->Count() != 0 && g_asFiles->Index(piInfo.fiInfo.szStoredName) == wxNOT_FOUND)
\r
149 p->skipThisFile = true;
\r
150 return EGG_ERROR_SKIP;
\r
152 return EGG_ERROR_SUCCESS;
\r
154 case eggevent::ActivityStart::CODE:
\r
155 piInfo.eStatus = TPI_STATUS_BEGINPROCESS;
\r
156 GetFileInformation2(* (void **) user, & piInfo.fiInfo, ((eggevent::ActivityStart *) param)->index);
\r
158 case eggevent::Progress::CODE:
\r
159 piInfo.eStatus = TPI_STATUS_INPROCESS;
\r
160 piInfo.nProcessedSize = ((eggevent::Progress *) param)->current * (piInfo.fiInfo.nUnpackedSize / 10000);
\r
162 case eggevent::ActivityFinish::CODE:
\r
163 piInfo.eStatus = TPI_STATUS_ENDPROCESS;
\r
165 case eggevent::Finish::CODE:
\r
166 piInfo.eStatus = TPI_STATUS_CLOSEARCHIVE;
\r
168 case eggevent::QueryPassword::CODE:
\r
171 piInfo.eMessage = TPI_MESSAGE_ASK;
\r
172 piInfo.eStatus = TPI_PARAM_PASSWORD;
\r
175 eggevent::QueryPassword * p = (eggevent::QueryPassword *) param;
\r
177 if (p->queryCount == 1)
\r
179 wcsncpy(p->password, g_swInfo->szPassword.wchar_str(), 1024 - 1);
\r
180 return EGG_ERROR_SUCCESS;
\r
183 // 2回目以降はコールバック関数に送信する。
\r
184 if (g_prProc == NULL || g_prProc(TPI_NOTIFY_COMMON, & piInfo) != TPI_CALLBACK_CONTINUE)
\r
186 return EGG_ERROR_CANCEL;
\r
189 // 既定のパスワードも変更しておく。
\r
190 g_swInfo->szPassword = piInfo.szParam;
\r
191 wcsncpy(p->password, piInfo.szParam.wchar_str(), 1024 - 1);
\r
192 return EGG_ERROR_SUCCESS;
\r
195 return EGG_ERROR_SUCCESS;
\r
199 if (g_prProc == NULL)
\r
201 return EGG_ERROR_SUCCESS;
\r
204 return g_prProc(TPI_NOTIFY_COMMON, & piInfo) != TPI_CALLBACK_CANCEL ? EGG_ERROR_SUCCESS : EGG_ERROR_CANCEL;
\r
207 //******************************************************************************
\r
209 //******************************************************************************
\r
216 int __stdcall GetPluginInformation
\r
218 unsigned int _uInfoId,
\r
225 return TPI_ERROR_D_PARAMETER;
\r
229 case TPI_INFO_VERSION_MAJOR:
\r
230 case TPI_INFO_VERSION_MINOR:
\r
231 * (int *) _pPtr = 0;
\r
233 case TPI_INFO_VERSION_API:
\r
234 * (int *) _pPtr = 2;
\r
237 return TPI_ERROR_D_UNSUPPORTED;
\r
239 return TPI_ERROR_SUCCESS;
\r
242 int __stdcall GetFormatInformation(TPI_FORMATINFO * _fiInfo, bool _bFirst)
\r
246 return TPI_ERROR_S_ENDOFDATA;
\r
249 _fiInfo->szTypeName = wxT("EGG/ALZ");
\r
250 _fiInfo->szSuffix = wxT("egg;alz");
\r
251 _fiInfo->szEngineName = wxT("UnEGG32.dll");
\r
252 _fiInfo->szTPIName = wxT("eggArc");
\r
253 _fiInfo->nTypeId = 0;
\r
254 _fiInfo->eSupportedCommand = TPI_COMMAND_EXTRACT | TPI_COMMAND_TEST;
\r
255 _fiInfo->fArchive = true;
\r
256 _fiInfo->fComment = true;
\r
257 _fiInfo->fSFX = true;
\r
258 _fiInfo->fSolid = true;
\r
259 _fiInfo->fEncryptPassword = true;
\r
260 _fiInfo->fMultiVolume = true;
\r
262 return TPI_ERROR_SUCCESS;
\r
265 int __stdcall LoadPlugin
\r
271 ::RemoveCwdFromSearchPath();
\r
272 g_hLib = ::LoadLibrary(L"UnEGG32.dll");
\r
273 if (g_hLib == NULL)
\r
275 ::FreeLibrary(g_hLib);
\r
276 return TPI_ERROR_U_LOAD_LIBRARY;
\r
279 return TPI_ERROR_SUCCESS;
\r
282 int __stdcall FreePlugin
\r
284 void * // _pReserved
\r
287 ::FreeLibrary(g_hLib);
\r
288 return TPI_ERROR_SUCCESS;
\r
291 int __stdcall OpenArchive
\r
293 const wxString & _szArcName,
\r
294 void * * _hArchive,
\r
295 wxULongLong_t * _nFileCount
\r
298 FARPROC fpProc = ::GetAPIAddress("IsValidArchive");
\r
299 if (fpProc == NULL)
\r
301 return TPI_ERROR_U_USE_LIBRARY;
\r
305 int nErrorCode = ErrorCodeConvert(((UINT (__cdecl *)(const wchar_t *, egg_type *)) fpProc)(_szArcName.wchar_str(), & eType));
\r
306 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
311 fpProc = ::GetAPIAddress("CreateEgg");
\r
312 if (fpProc == NULL)
\r
314 return TPI_ERROR_U_USE_LIBRARY;
\r
316 nErrorCode = ErrorCodeConvert(((UINT (__cdecl *)(void **, eggevent::Proc, void *)) fpProc)(_hArchive, CallbackProc, _hArchive));
\r
317 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
321 if (_hArchive == NULL)
\r
323 return TPI_ERROR_UNDEFINED;
\r
326 fpProc = ::GetAPIAddress("OpenArchive");
\r
327 if (fpProc == NULL)
\r
329 return TPI_ERROR_U_USE_LIBRARY;
\r
331 nErrorCode = ErrorCodeConvert(((UINT (__cdecl *)(void *, wchar_t *)) fpProc)(* _hArchive, _szArcName.wchar_str()));
\r
332 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
337 if (_nFileCount != NULL)
\r
339 fpProc = ::GetAPIAddress("GetFileCount");
\r
340 if (fpProc == NULL)
\r
342 return TPI_ERROR_U_USE_LIBRARY;
\r
345 nErrorCode = ErrorCodeConvert(((UINT (__cdecl *)(void *, size_t *)) fpProc)(* _hArchive, & n));
\r
346 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
353 return TPI_ERROR_SUCCESS;
\r
356 int __stdcall CloseArchive
\r
361 FARPROC fpProc = ::GetAPIAddress("CloseArchive");
\r
362 if (fpProc == NULL || _hArchive == NULL)
\r
364 return TPI_ERROR_U_USE_LIBRARY;
\r
366 int nErrorCode = ErrorCodeConvert(((UINT (__cdecl *)(void *)) fpProc)(_hArchive));
\r
367 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
372 fpProc = ::GetAPIAddress("DestroyEgg");
\r
373 return fpProc == NULL ? TPI_ERROR_U_USE_LIBRARY : ErrorCodeConvert(((UINT (__cdecl *)(void **)) fpProc)(& _hArchive));
\r
376 int __stdcall GetFileInformation
\r
379 TPI_FILEINFO * _fiInfo,
\r
383 static wxULongLong_t s_nFileId;
\r
384 static size_t s_nFileCount;
\r
388 FARPROC fpProc = ::GetAPIAddress("GetFileCount");
\r
389 if (fpProc == NULL)
\r
391 return TPI_ERROR_U_USE_LIBRARY;
\r
393 int nErrorCode = ErrorCodeConvert(((UINT (__cdecl *)(void *, size_t *)) fpProc)(_hArchive, & s_nFileCount));
\r
394 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
399 return s_nFileId >= s_nFileCount ? TPI_ERROR_S_ENDOFDATA : GetFileInformation2(_hArchive, _fiInfo, s_nFileId++);
\r
402 int __stdcall GetArchiveInformation
\r
405 TPI_ARCHIVEINFO * _aiInfo
\r
408 GetFormatInformation(& _aiInfo->fiInfo, true);
\r
409 return TPI_ERROR_SUCCESS;
\r
412 int __stdcall Command
\r
414 wxULongLong_t _eCommand,
\r
415 TPI_SWITCHES * _swInfo,
\r
416 const wxString & _szArcName,
\r
417 const wxArrayString & _szFiles
\r
420 if (_eCommand != TPI_COMMAND_EXTRACT && _eCommand != TPI_COMMAND_TEST)
\r
422 return TPI_ERROR_U_USE_LIBRARY;
\r
427 int nErrorCode = OpenArchive(_szArcName, & hArc);
\r
428 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
433 // グローバル変数にポインタを保存。
\r
434 g_swInfo = _swInfo;
\r
435 g_asFiles = & _szFiles;
\r
437 FARPROC fpProc = _eCommand == TPI_COMMAND_EXTRACT ? ::GetAPIAddress("Extract") : ::GetAPIAddress("Test");
\r
438 if (fpProc == NULL)
\r
440 return TPI_ERROR_U_USE_LIBRARY;
\r
442 nErrorCode = ErrorCodeConvert(((UINT (__cdecl *)(void *)) fpProc)(hArc));
\r
443 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
448 return CloseArchive(hArc);
\r
451 int __stdcall SetCallbackProc
\r
453 TPI_PROC _prArcProc
\r
457 if (_prArcProc == NULL)
\r
459 return TPI_ERROR_D_PARAMETER;
\r
461 g_prProc = * _prArcProc;
\r
463 return TPI_ERROR_SUCCESS;
\r