OSDN Git Service

書庫化可能な形式かどうかを表すTPI_FORMATINFO::fArchiveを追加。
[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         // \8d\\91¢\91Ì\82ð\8f\89\8aú\89»\81B\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                 // \93W\8aJ\82·\82é\82©\82Ç\82¤\82©\94»\92f\81B\r
59                 // TODO : \83A\83v\83\8a\83P\81[\83V\83\87\83\93\91¤\82Ö\81B\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                 // \93W\8aJ\82·\82é\81B\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.ToULong() / 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                 // \83p\83X\83\8f\81[\83h\96â\82¢\8d\87\82í\82¹\81B\r
88                 // TODO : \8cÂ\95Ê\83t\83@\83C\83\8b\82É\91Î\82·\82é\96â\82¢\8d\87\82í\82¹\82Ì\8eÀ\91\95\81B\r
89                 piInfo.uMessage = TPI_MESSAGE_ASK;\r
90                 piInfo.uStatus  = TPI_PARAM_PASSWORD;\r
91 \r
92                 // \83R\81[\83\8b\83o\83b\83N\8aÖ\90\94\82É\91\97\90M\81B\r
93                 eggevent::QueryPassword * p = (eggevent::QueryPassword *) param;\r
94                 // \8f\89\89ñ\82Í\8aù\92è\82Ì\83p\83X\83\8f\81[\83h\82ð\8e\8e\82·\81B\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\89ñ\96Ú\88È\8d~\82Í\83R\81[\83\8b\83o\83b\83N\8aÖ\90\94\82É\91\97\90M\82·\82é\81B\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                 // \8aù\92è\82Ì\83p\83X\83\8f\81[\83h\82à\95Ï\8dX\82µ\82Ä\82¨\82­\81B\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         // \83R\81[\83\8b\83o\83b\83N\8aÖ\90\94\82É\91\97\90M\81B\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 nErrorCodeConvert(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,\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("UnEGG.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 & _szArcName,\r
209         wxULongLong\r
210 )\r
211 {\r
212         g_hLib = ::LoadLibrary(L"UnEGG.dll");\r
213         if (g_hLib == NULL || CheckArchive(_szArcName, NULL) != TPI_ERROR_SUCCESS)\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         int * _nFileCount\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 (_nFileCount != NULL)\r
244         {\r
245                 * _nFileCount = 1;\r
246         }\r
247 \r
248         egg_type eType;\r
249         return nErrorCodeConvert(((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 = nErrorCodeConvert(((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 : nErrorCodeConvert(((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 = nErrorCodeConvert(((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 : nErrorCodeConvert(((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 unsigned int s_uFileID, s_uFileCount;\r
305         static FARPROC fpProc;\r
306         int nErrorCode;\r
307 \r
308         if (_bFirst)\r
309         {\r
310                 s_uFileID = 0;\r
311                 fpProc = ::GetAPIAddress("GetFileCount");\r
312                 if (fpProc == NULL)\r
313                 {\r
314                         return TPI_ERROR_U_USE_LIBRARY;\r
315                 }\r
316                 nErrorCode = nErrorCodeConvert(((UINT (__cdecl *)(void *, size_t *)) fpProc)(_hArchive, & s_uFileCount));\r
317                 if (nErrorCode != TPI_ERROR_SUCCESS)\r
318                 {\r
319                         return nErrorCode;\r
320                 }\r
321 \r
322                 fpProc = ::GetAPIAddress("GetFileHeader");\r
323                 if (fpProc == NULL)\r
324                 {\r
325                         return TPI_ERROR_U_USE_LIBRARY;\r
326                 }\r
327         }\r
328         if (s_uFileID >= s_uFileCount)\r
329         {\r
330                 return TPI_ERROR_S_ENDOFDATA;\r
331         }\r
332 \r
333         EGGFileHeader fhInfo;\r
334         nErrorCode = nErrorCodeConvert(((UINT (__cdecl *)(void *, size_t, EGGFileHeader *)) fpProc)(_hArchive, s_uFileID, & fhInfo));\r
335         if (nErrorCode == TPI_ERROR_SUCCESS)\r
336         {\r
337                 _fiInfo->dwAttribute    = fhInfo.attribute;\r
338                 _fiInfo->dwCRC32        = fhInfo.crc;\r
339                 _fiInfo->llPackedSize   = fhInfo.packedSize;\r
340                 _fiInfo->llUnpackedSize = fhInfo.unpackedSize;\r
341                 _fiInfo->tmModified     = fhInfo.lastModified;\r
342                 _fiInfo->szStoredName   = WC2String(fhInfo.fileName);\r
343                 _fiInfo->szMethod       = fhInfo.method == 2 ? wxT("ALZ") : fhInfo.method == 0 ? wxT("EGG") : wxT("unknown");\r
344                 _fiInfo->llFileID       = s_uFileID++;\r
345                 _fiInfo->fnFileName     = wxFileName(_fiInfo->szStoredName);\r
346         }\r
347 \r
348         return nErrorCode;\r
349 }\r
350 \r
351 int __stdcall GetArchiveInformation\r
352 (\r
353         void *,\r
354         TPI_ARCHIVEINFO * _aiInfo\r
355 )\r
356 {\r
357         GetFormatInformation(& _aiInfo->fiInfo, true);\r
358         return TPI_ERROR_SUCCESS;\r
359 }\r
360 \r
361 int __stdcall Command\r
362 (\r
363         unsigned int _uCommand,\r
364         TPI_SWITCHES * _swInfo,\r
365         const wxString & _szArcName,\r
366         const wxArrayString & _szFiles\r
367 )\r
368 {\r
369         if (_uCommand != TPI_COMMAND_EXTRACT)\r
370         {\r
371                 return TPI_ERROR_U_USE_LIBRARY;\r
372         }\r
373 \r
374         // \8aJ\82«\82È\82¨\82·\81B\r
375         void * hArc;\r
376         int nErrorCode = OpenArchive(_szArcName, & hArc);\r
377         if (nErrorCode != TPI_ERROR_SUCCESS)\r
378         {\r
379                 return nErrorCode;\r
380         }\r
381 \r
382         // \83O\83\8d\81[\83o\83\8b\95Ï\90\94\82É\83|\83C\83\93\83^\82ð\95Û\91\81B\r
383         g_swInfo = _swInfo;\r
384         g_asFiles = & _szFiles;\r
385 \r
386         FARPROC fpProc = ::GetAPIAddress("Extract");\r
387         if (fpProc == NULL)\r
388         {\r
389                 return TPI_ERROR_U_USE_LIBRARY;\r
390         }\r
391         nErrorCode = nErrorCodeConvert(((UINT (__cdecl *)(void *)) fpProc)(hArc));\r
392         if (nErrorCode != TPI_ERROR_SUCCESS)\r
393         {\r
394                 return nErrorCode;\r
395         }\r
396 \r
397         return CloseArchive(hArc);\r
398 }\r
399 \r
400 int __stdcall SetCallbackProc\r
401 (\r
402         TPI_PROC _prArcProc\r
403 )\r
404 {\r
405         // \83|\83C\83\93\83^\82ð\95Û\91\81B\r
406         if (_prArcProc == NULL)\r
407         {\r
408                 return TPI_ERROR_D_PARAMETER;\r
409         }\r
410         g_prProc = * _prArcProc;\r
411 \r
412         return TPI_ERROR_SUCCESS;\r
413 }\r
414 \r
415 #ifdef __cplusplus\r
416 }\r
417 #endif\r