OSDN Git Service

コンパイルエラーなどを修正。
[tpi/lychee.git] / src / plugin / eggArc / eggArc.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 "eggArc.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 TPI_SWITCHES * g_swInfo;\r
39 const wxArrayString * g_asFiles;\r
40 \r
41 //******************************************************************************\r
42 //    Callback Wrapper\r
43 //******************************************************************************\r
44 \r
45 UINT __cdecl CallbackProc(void * user, UINT code, void* param)\r
46 {\r
47         // 構造体を初期化。\r
48         static TPI_PROCESSINFO piInfo;\r
49         piInfo.uMessage = TPI_MESSAGE_STATUS;\r
50 \r
51         switch (code)\r
52         {\r
53         case eggevent::Start::CODE:\r
54                 piInfo.uStatus = TPI_STATUS_OPENARCHIVE;\r
55                 break;\r
56         case eggevent::Extract::CODE:\r
57         {\r
58                 // 展開するかどうか判断。\r
59                 // TODO : アプリケーション側へ。\r
60                 eggevent::Extract * p = (eggevent::Extract *) param;\r
61                 wxString szFileName = WC2String(p->nameInArchive);\r
62                 if (g_asFiles->Count() != 0 && g_asFiles->Index(szFileName) == wxNOT_FOUND)\r
63                 {\r
64                         return EGG_ERROR_SKIP;\r
65                 }\r
66 \r
67                 // 展開する。\r
68                 wcsncpy(p->fileName, (g_swInfo->fnDestinationDirectory.GetPathWithSep() + (g_swInfo->fStoreDirectoryPathes ? szFileName : wxFileName(szFileName).GetFullName())).wchar_str(), MAX_PATH - 1);\r
69                 return EGG_ERROR_SUCCESS;\r
70         }\r
71         case eggevent::ActivityStart::CODE:\r
72                 piInfo.uStatus = TPI_STATUS_BEGINPROCESS;\r
73                 GetFileInformation(* (void **) user, & piInfo.fiInfo, ((eggevent::ActivityStart *) param)->index == 0);\r
74                 break;\r
75         case eggevent::Progress::CODE:\r
76                 piInfo.uStatus = TPI_STATUS_INPROCESS;\r
77                 piInfo.llProcessedSize = ((eggevent::Progress *) param)->current * (piInfo.fiInfo.llUnpackedSize / 10000);\r
78                 break;\r
79         case eggevent::ActivityFinish::CODE:\r
80                 piInfo.uStatus = TPI_STATUS_ENDPROCESS;\r
81                 break;\r
82         case eggevent::Finish::CODE:\r
83                 piInfo.uStatus = TPI_STATUS_CLOSEARCHIVE;\r
84                 break;\r
85         case eggevent::QueryPassword::CODE:\r
86         {\r
87                 // パスワード問い合わせ。\r
88                 // TODO : 個別ファイルに対する問い合わせの実装。\r
89                 piInfo.uMessage = TPI_MESSAGE_ASK;\r
90                 piInfo.uStatus  = TPI_PARAM_PASSWORD;\r
91 \r
92                 // コールバック関数に送信。\r
93                 eggevent::QueryPassword * p = (eggevent::QueryPassword *) param;\r
94                 // 初回は既定のパスワードを試す。\r
95                 if (p->queryCount == 1)\r
96                 {\r
97                         wcsncpy(p->password, g_swInfo->szPassword.wchar_str(), 1024 - 1);\r
98                         return EGG_ERROR_SUCCESS;\r
99                 }\r
100 \r
101                 // 2回目以降はコールバック関数に送信する。\r
102                 if (g_prProc == NULL || g_prProc(TPI_NOTIFY_COMMON, & piInfo) != TPI_CALLBACK_CONTINUE)\r
103                 {\r
104                         return EGG_ERROR_CANCEL;\r
105                 }\r
106 \r
107                 // 既定のパスワードも変更しておく。\r
108                 g_swInfo->szPassword = piInfo.szParam;\r
109                 wcsncpy(p->password, piInfo.szParam.wchar_str(), 1024 - 1);\r
110                 return EGG_ERROR_SUCCESS;\r
111         }\r
112         default:\r
113                 return EGG_ERROR_SUCCESS;\r
114         }\r
115 \r
116         // コールバック関数に送信。\r
117         if (g_prProc == NULL)\r
118         {\r
119                 return EGG_ERROR_SUCCESS;\r
120         }\r
121 \r
122         return g_prProc(TPI_NOTIFY_COMMON, & piInfo) != TPI_CALLBACK_CANCEL ? EGG_ERROR_SUCCESS : EGG_ERROR_CANCEL;\r
123 }\r
124 \r
125 //******************************************************************************\r
126 //    Inside Functions\r
127 //******************************************************************************\r
128 \r
129 #define GetAPIAddress(name) GetProcAddress(g_hLib, "EGG_" name)\r
130 \r
131 int ErrorCodeConvert(int nErrorCode)\r
132 {\r
133         switch (nErrorCode)\r
134         {\r
135         case EGG_ERROR_FAIL:        return TPI_ERROR_UNDEFINED;\r
136         case EGG_ERROR_SUCCESS:     return TPI_ERROR_SUCCESS;\r
137         case EGG_ERROR_SKIP:        return TPI_ERROR_D_SKIPPED;\r
138         case EGG_ERROR_CANCEL:      return TPI_ERROR_D_SKIPPED;\r
139         case EGG_ERROR_IO:          return TPI_ERROR_IO_MISC;\r
140         case EGG_ERROR_TYPEMISMATCH:return TPI_ERROR_ARC_UNSUPPORTED;\r
141         case EGG_ERROR_FILE:        return TPI_ERROR_IO_MISC;\r
142         case EGG_ERROR_FORMAT:      return TPI_ERROR_IO_ARC_MISC;\r
143         case EGG_ERROR_ALGORITHM:   return TPI_ERROR_UNDEFINED;\r
144         default:                    return TPI_ERROR_UNDEFINED;\r
145         }\r
146 }\r
147 \r
148 //******************************************************************************\r
149 //    Functions\r
150 //******************************************************************************\r
151 \r
152 #ifdef __cplusplus\r
153 extern "C"\r
154 {\r
155 #endif\r
156 \r
157 int __stdcall GetPluginInformation\r
158 (\r
159         unsigned int _uInfoId,\r
160         wxULongLong_t,\r
161         void * _pPtr\r
162 )\r
163 {\r
164         if (_pPtr == NULL)\r
165         {\r
166                 return TPI_ERROR_D_PARAMETER;\r
167         }\r
168         switch (_uInfoId)\r
169         {\r
170         case TPI_INFO_VERSION_MAJOR:\r
171         case TPI_INFO_VERSION_MINOR:\r
172                 * (int *) _pPtr = 0;\r
173                 break;\r
174         case TPI_INFO_VERSION_API:\r
175                 * (int *) _pPtr = 2;\r
176                 break;\r
177         default:\r
178                 return TPI_ERROR_D_UNSUPPORTED;\r
179         }\r
180         return TPI_ERROR_SUCCESS;\r
181 }\r
182 \r
183 int __stdcall GetFormatInformation(TPI_FORMATINFO * _fiInfo, bool _bFirst)\r
184 {\r
185         if (! _bFirst)\r
186         {\r
187                 return TPI_ERROR_S_ENDOFDATA;\r
188         }\r
189 \r
190         _fiInfo->szTypeName   = wxT("EGG/ALZ");\r
191         _fiInfo->szSuffix     = wxT("egg;alz");\r
192         _fiInfo->szEngineName = wxT("UnEGG32.dll");\r
193         _fiInfo->szTPIName    = wxT("eggArc");\r
194         _fiInfo->llTypeId     = 0;\r
195         _fiInfo->llSupportedCommand = TPI_COMMAND_EXTRACT;\r
196         _fiInfo->fArchive     = true;\r
197         _fiInfo->fComment     = true;\r
198         _fiInfo->fSFX         = true;\r
199         _fiInfo->fSolid       = true;\r
200         _fiInfo->fEncryptPassword = true;\r
201         _fiInfo->fMultiVolume = true;\r
202 \r
203         return TPI_ERROR_SUCCESS;\r
204 }\r
205 \r
206 int __stdcall LoadPlugin\r
207 (\r
208         const wxString &,\r
209         wxULongLong_t\r
210 )\r
211 {\r
212         g_hLib = ::LoadLibrary(L"UnEGG32.dll");\r
213         if (g_hLib == NULL)\r
214         {\r
215                 ::FreeLibrary(g_hLib);\r
216                 return TPI_ERROR_U_LOAD_LIBRARY;\r
217         }\r
218 \r
219         return TPI_ERROR_SUCCESS;\r
220 }\r
221 \r
222 int __stdcall FreePlugin\r
223 (\r
224         void * // _pReserved\r
225 )\r
226 {\r
227         ::FreeLibrary(g_hLib);\r
228         return TPI_ERROR_SUCCESS;\r
229 }\r
230 \r
231 int __stdcall CheckArchive\r
232 (\r
233         const wxString & _szArcName,\r
234         wxULongLong_t * _llFileCount\r
235 )\r
236 {\r
237         FARPROC fpProc = ::GetAPIAddress("IsValidArchive");\r
238         if (fpProc == NULL)\r
239         {\r
240                 return TPI_ERROR_U_USE_LIBRARY;\r
241         }\r
242 \r
243         if (_llFileCount != NULL)\r
244         {\r
245                 * _llFileCount = 1;\r
246         }\r
247 \r
248         egg_type eType;\r
249         return ErrorCodeConvert(((UINT (__cdecl *)(const wchar_t *, egg_type *)) fpProc)(_szArcName.wchar_str(), & eType));\r
250 }\r
251 \r
252 int __stdcall OpenArchive\r
253 (\r
254         const wxString & _szArcName,\r
255         void * * _hArchive\r
256 )\r
257 {\r
258         FARPROC fpProc = ::GetAPIAddress("CreateEgg");\r
259         if (fpProc == NULL)\r
260         {\r
261                 return TPI_ERROR_U_USE_LIBRARY;\r
262         }\r
263         int nErrorCode = ErrorCodeConvert(((UINT (__cdecl *)(void **, eggevent::Proc, void *)) fpProc)(_hArchive, CallbackProc, _hArchive));\r
264         if (nErrorCode != TPI_ERROR_SUCCESS)\r
265         {\r
266                 return nErrorCode;\r
267         }\r
268         if (_hArchive == NULL)\r
269         {\r
270                 return TPI_ERROR_UNDEFINED;\r
271         }\r
272 \r
273         fpProc = ::GetAPIAddress("OpenArchive");\r
274         return fpProc == NULL ? TPI_ERROR_U_USE_LIBRARY : ErrorCodeConvert(((UINT (__cdecl *)(void *, wchar_t *)) fpProc)(* _hArchive, _szArcName.wchar_str()));\r
275 }\r
276 \r
277 int __stdcall CloseArchive\r
278 (\r
279         void * _hArchive\r
280 )\r
281 {\r
282         FARPROC fpProc = ::GetAPIAddress("CloseArchive");\r
283         if (fpProc == NULL || _hArchive == NULL)\r
284         {\r
285                 return TPI_ERROR_U_USE_LIBRARY;\r
286         }\r
287         int nErrorCode = ErrorCodeConvert(((UINT (__cdecl *)(void *)) fpProc)(_hArchive));\r
288         if (nErrorCode != TPI_ERROR_SUCCESS)\r
289         {\r
290                 return nErrorCode;\r
291         }\r
292 \r
293         fpProc = ::GetAPIAddress("DestroyEgg");\r
294         return fpProc == NULL ? TPI_ERROR_U_USE_LIBRARY : ErrorCodeConvert(((UINT (__cdecl *)(void **)) fpProc)(& _hArchive));\r
295 }\r
296 \r
297 int __stdcall GetFileInformation\r
298 (\r
299         void * _hArchive,\r
300         TPI_FILEINFO * _fiInfo,\r
301         bool _bFirst\r
302 )\r
303 {\r
304         static wxULongLong_t s_nFileId;\r
305         static size_t s_nFileCount;\r
306         static FARPROC fpProc;\r
307         int nErrorCode;\r
308 \r
309         if (_bFirst)\r
310         {\r
311                 s_nFileId = 0;\r
312                 fpProc = ::GetAPIAddress("GetFileCount");\r
313                 if (fpProc == NULL)\r
314                 {\r
315                         return TPI_ERROR_U_USE_LIBRARY;\r
316                 }\r
317                 nErrorCode = ErrorCodeConvert(((UINT (__cdecl *)(void *, size_t *)) fpProc)(_hArchive, & s_nFileCount));\r
318                 if (nErrorCode != TPI_ERROR_SUCCESS)\r
319                 {\r
320                         return nErrorCode;\r
321                 }\r
322 \r
323                 fpProc = ::GetAPIAddress("GetFileHeader");\r
324                 if (fpProc == NULL)\r
325                 {\r
326                         return TPI_ERROR_U_USE_LIBRARY;\r
327                 }\r
328         }\r
329         if (s_nFileId >= s_nFileCount)\r
330         {\r
331                 return TPI_ERROR_S_ENDOFDATA;\r
332         }\r
333 \r
334         EGGFileHeader fhInfo;\r
335         nErrorCode = ErrorCodeConvert(((UINT (__cdecl *)(void *, size_t, EGGFileHeader *)) fpProc)(_hArchive, s_nFileId, & fhInfo));\r
336         if (nErrorCode == TPI_ERROR_SUCCESS)\r
337         {\r
338                 _fiInfo->dwAttribute    = fhInfo.attribute;\r
339                 if (fhInfo.encrypted)\r
340                 {\r
341                         _fiInfo->dwAttribute |= TPI_ATTRIBUTE_ENCRYPTED;\r
342                 }\r
343                 _fiInfo->dwCRC32        = fhInfo.crc;\r
344                 _fiInfo->llPackedSize   = fhInfo.packedSize;\r
345                 _fiInfo->llUnpackedSize = fhInfo.unpackedSize;\r
346                 _fiInfo->tmModified     = fhInfo.lastModified;\r
347                 _fiInfo->szComment      = WC2String(fhInfo.comment);\r
348                 _fiInfo->szStoredName   = WC2String(fhInfo.fileName);\r
349                 _fiInfo->szMethod       = fhInfo.method == 2 ? wxT("ALZ") : fhInfo.method == 0 ? wxT("EGG") : wxT("unknown");\r
350                 _fiInfo->llFileId       = s_nFileId++;\r
351                 _fiInfo->fnFileName     = wxFileName(_fiInfo->szStoredName);\r
352         }\r
353 \r
354         return nErrorCode;\r
355 }\r
356 \r
357 int __stdcall GetArchiveInformation\r
358 (\r
359         void *,\r
360         TPI_ARCHIVEINFO * _aiInfo\r
361 )\r
362 {\r
363         GetFormatInformation(& _aiInfo->fiInfo, true);\r
364         return TPI_ERROR_SUCCESS;\r
365 }\r
366 \r
367 int __stdcall Command\r
368 (\r
369         unsigned int _uCommand,\r
370         TPI_SWITCHES * _swInfo,\r
371         const wxString & _szArcName,\r
372         const wxArrayString & _szFiles\r
373 )\r
374 {\r
375         if (_uCommand != TPI_COMMAND_EXTRACT)\r
376         {\r
377                 return TPI_ERROR_U_USE_LIBRARY;\r
378         }\r
379 \r
380         // 開きなおす。\r
381         void * hArc;\r
382         int nErrorCode = OpenArchive(_szArcName, & hArc);\r
383         if (nErrorCode != TPI_ERROR_SUCCESS)\r
384         {\r
385                 return nErrorCode;\r
386         }\r
387 \r
388         // グローバル変数にポインタを保存。\r
389         g_swInfo = _swInfo;\r
390         g_asFiles = & _szFiles;\r
391 \r
392         FARPROC fpProc = ::GetAPIAddress("Extract");\r
393         if (fpProc == NULL)\r
394         {\r
395                 return TPI_ERROR_U_USE_LIBRARY;\r
396         }\r
397         nErrorCode = ErrorCodeConvert(((UINT (__cdecl *)(void *)) fpProc)(hArc));\r
398         if (nErrorCode != TPI_ERROR_SUCCESS)\r
399         {\r
400                 return nErrorCode;\r
401         }\r
402 \r
403         return CloseArchive(hArc);\r
404 }\r
405 \r
406 int __stdcall SetCallbackProc\r
407 (\r
408         TPI_PROC _prArcProc\r
409 )\r
410 {\r
411         // ポインタを保存。\r
412         if (_prArcProc == NULL)\r
413         {\r
414                 return TPI_ERROR_D_PARAMETER;\r
415         }\r
416         g_prProc = * _prArcProc;\r
417 \r
418         return TPI_ERROR_SUCCESS;\r
419 }\r
420 \r
421 #ifdef __cplusplus\r
422 }\r
423 #endif\r