OSDN Git Service

wxArrayString::CountをGetCountへ修正。
[tpi/lychee.git] / src / plugin / rarArc / rarArc.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 #define wxUSE_DYNLIB_CLASS 1\r
27 #include "../../common/header/plugin.h"\r
28 #include "../../common/header/plugin-extra.h"\r
29 #include "../../common/library/library.h"\r
30 #include <wx/dynlib.h>\r
31 #include <windows.h>\r
32 #include "rarArc.h"\r
33 \r
34 //******************************************************************************\r
35 //    Global varients\r
36 //******************************************************************************\r
37 \r
38 wxDynamicLibrary g_hLib;\r
39 TPI_PROC g_prProc;\r
40 TPI_SWITCHES * g_swInfo;\r
41 const wxArrayString * g_asFiles;\r
42 char g_szComment[64001];\r
43 RAROpenArchiveDataEx g_oaInfo;\r
44 RARHeaderDataEx * g_hdInfo;\r
45 \r
46 //******************************************************************************\r
47 //    Callback Wrapper\r
48 //******************************************************************************\r
49 \r
50 int __stdcall CallbackProc(unsigned int msg, long UserData, long P1, long P2)\r
51 {\r
52         // \8d\\91¢\91Ì\82ð\8f\89\8aú\89»\81B\r
53         static TPI_PROCESSINFO piInfo;\r
54 \r
55         switch (msg)\r
56         {\r
57         case UCM_CHANGEVOLUME:\r
58                 switch (P2)\r
59                 {\r
60                 case RAR_VOL_ASK:\r
61                         // \95ª\8a\84\8f\91\8cÉ\82Ì\8e\9f\82Ì\95\94\95ª\82ð\97v\8b\81\81B\r
62                         piInfo.uMessage = TPI_MESSAGE_ASK;\r
63                         piInfo.uStatus  = TPI_PARAM_NEXTVOLUME;\r
64                         piInfo.szParam  = wxEmptyString;\r
65                         break;\r
66                 case RAR_VOL_NOTIFY:\r
67                         // \95ª\8a\84\95\94\95ª\82Ì\93Ç\82Ý\8d\9e\82Ý\82ð\8aJ\8en\81B\r
68                         piInfo.uMessage = TPI_MESSAGE_STATUS;\r
69                         piInfo.uStatus  = TPI_STATUS_OPENARCHIVE;\r
70                         piInfo.fiInfo.fnFileName = wxFileName(UTF82String((char *) P1));\r
71                         break;\r
72                 default:\r
73                         return 1;\r
74                 }\r
75                 break;\r
76         case UCM_PROCESSDATA:\r
77                 piInfo.uMessage = TPI_MESSAGE_STATUS;\r
78                 piInfo.uStatus  = TPI_STATUS_INPROCESS;\r
79                 piInfo.llProcessedSize += P2;\r
80                 break;\r
81         case UCM_NEEDPASSWORD:\r
82                 piInfo.uMessage = TPI_MESSAGE_ASK;\r
83                 piInfo.uStatus  = TPI_PARAM_PASSWORD;\r
84                 piInfo.szParam  = wxEmptyString;\r
85                 break;\r
86         default:\r
87                 return 1;\r
88         }\r
89 \r
90         // \83R\81[\83\8b\83o\83b\83N\8aÖ\90\94\82É\91\97\90M\81B\r
91         if (g_prProc == NULL || g_prProc(TPI_NOTIFY_COMMON, & piInfo) == TPI_CALLBACK_CONTINUE)\r
92         {\r
93                 if (msg != UCM_PROCESSDATA && P2 != RAR_VOL_NOTIFY)\r
94                 {\r
95                         strncpy((char *) P1, piInfo.szParam.char_str(), (msg == UCM_CHANGEVOLUME ? 1024 : P2) - 1);\r
96                 }\r
97                 return 1;\r
98         }\r
99         else\r
100         {\r
101                 return -1;\r
102         }\r
103 }\r
104 \r
105 //******************************************************************************\r
106 //    Inside Functions\r
107 //******************************************************************************\r
108 \r
109 int nErrorCodeConvert(int nErrorCode)\r
110 {\r
111         switch (nErrorCode)\r
112         {\r
113         case 0:                     return TPI_ERROR_SUCCESS;\r
114         case 1:                     return TPI_ERROR_SUCCESS;\r
115         case ERAR_END_ARCHIVE:      return TPI_ERROR_S_ENDOFDATA;\r
116         case ERAR_NO_MEMORY:        return TPI_ERROR_D_OUTOFMEMORY;\r
117         case ERAR_BAD_DATA:         return TPI_ERROR_ARC_BROKEN_MISC;\r
118         case ERAR_BAD_ARCHIVE:      return TPI_ERROR_ARC_UNSUPPORTED;\r
119         case ERAR_UNKNOWN_FORMAT:   return TPI_ERROR_ARC_ENCRYPTED;\r
120         case ERAR_EOPEN:            return TPI_ERROR_IO_ARC_OPEN;\r
121         case ERAR_ECREATE:          return TPI_ERROR_IO_FILE_OPEN;\r
122         case ERAR_ECLOSE:           return TPI_ERROR_IO_CLOSE;\r
123         case ERAR_EREAD:            return TPI_ERROR_IO_ARC_READ;\r
124         case ERAR_EWRITE:           return TPI_ERROR_IO_FILE_WRITE;\r
125         case ERAR_SMALL_BUF:        return TPI_ERROR_UNDEFINED;\r
126         case ERAR_UNKNOWN:          return TPI_ERROR_UNDEFINED;\r
127         case ERAR_MISSING_PASSWORD: return TPI_ERROR_ARC_ENCRYPTED;\r
128         default:                    return TPI_ERROR_UNDEFINED;\r
129         }\r
130 }\r
131 \r
132 //******************************************************************************\r
133 //    Functions\r
134 //******************************************************************************\r
135 \r
136 #ifdef __cplusplus\r
137 extern "C"\r
138 {\r
139 #endif\r
140 \r
141 int __stdcall GetPluginInformation\r
142 (\r
143         unsigned int _uInfoId,\r
144         wxULongLong,\r
145         void * _pPtr\r
146 )\r
147 {\r
148         if (_pPtr == NULL)\r
149         {\r
150                 return TPI_ERROR_D_PARAMETER;\r
151         }\r
152         switch (LOWORD(_uInfoId))\r
153         {\r
154         case TPI_INFO_VERSION_MAJOR:\r
155         case TPI_INFO_VERSION_MINOR:\r
156                 * (int *) _pPtr = 0;\r
157                 break;\r
158         case TPI_INFO_VERSION_API:\r
159                 * (int *) _pPtr = 2;\r
160                 break;\r
161         default:\r
162                 return TPI_ERROR_D_UNSUPPORTED;\r
163         }\r
164         return TPI_ERROR_SUCCESS;\r
165 }\r
166 \r
167 int __stdcall GetFormatInformation(TPI_FORMATINFO * _fiInfo, bool _bFirst)\r
168 {\r
169         if (! _bFirst)\r
170         {\r
171                 return TPI_ERROR_S_ENDOFDATA;\r
172         }\r
173 \r
174         _fiInfo->szTypeName   = wxT("RAR");\r
175         _fiInfo->szSuffix     = wxT(".rar");\r
176         _fiInfo->szEngineName = g_hLib.CanonicalizeName(wxT("unrar"));\r
177         _fiInfo->szTPIName    = wxT("rarArc");\r
178         _fiInfo->llTypeId     = 0;\r
179         _fiInfo->llSupportedCommand = TPI_COMMAND_EXTRACT | TPI_COMMAND_TEST;\r
180         _fiInfo->fComment     = true;\r
181         _fiInfo->fSFX         = true;\r
182         _fiInfo->fSolid       = true;\r
183         _fiInfo->fEncryptPassword = true;\r
184         _fiInfo->fMultiVolume = true;\r
185 \r
186         return TPI_ERROR_SUCCESS;\r
187 }\r
188 \r
189 int __stdcall LoadPlugin\r
190 (\r
191         const wxString & _szArcName,\r
192         wxULongLong\r
193 )\r
194 {\r
195         g_hLib.Load(g_hLib.CanonicalizeName(wxT("unrar")));\r
196         if (! g_hLib.IsLoaded() || CheckArchive(_szArcName, NULL) != TPI_ERROR_SUCCESS)\r
197         {\r
198                 g_hLib.Unload();\r
199                 return TPI_ERROR_U_LOAD_LIBRARY;\r
200         }\r
201 \r
202         return TPI_ERROR_SUCCESS;\r
203 }\r
204 \r
205 int __stdcall FreePlugin\r
206 (\r
207         void * // _pReserved\r
208 )\r
209 {\r
210         g_hLib.Unload();\r
211         return TPI_ERROR_SUCCESS;\r
212 }\r
213 \r
214 int __stdcall CheckArchive\r
215 (\r
216         const wxString & _szArcName,\r
217         int * _nFileCount\r
218 )\r
219 {\r
220         void * _hArchive;\r
221         int nErrorCode = OpenArchive(_szArcName, & _hArchive);\r
222         if (nErrorCode != TPI_ERROR_SUCCESS)\r
223         {\r
224                 return nErrorCode;\r
225         }\r
226 \r
227         if (_nFileCount != NULL)\r
228         {\r
229                 * _nFileCount = 1;\r
230         }\r
231 \r
232         return CloseArchive(_hArchive);\r
233 }\r
234 \r
235 int __stdcall OpenArchive\r
236 (\r
237         const wxString & _szArcName,\r
238         void * * _hArchive\r
239 )\r
240 {\r
241         if (! g_hLib.HasSymbol(wxT("RAROpenArchiveEx")))\r
242         {\r
243                 return TPI_ERROR_U_USE_LIBRARY;\r
244         }\r
245         void * p = g_hLib.GetSymbol(wxT("RAROpenArchiveEx"));\r
246         if (! p)\r
247         {\r
248                 return TPI_ERROR_U_USE_LIBRARY;\r
249         }\r
250 \r
251         // TODO : \95\8e\9a\90\94\90§\8cÀ\93P\94p\81B\r
252         wchar_t sz[2048];\r
253         wcsncpy(sz, _szArcName.wchar_str(), 2047);\r
254         memset(& g_oaInfo, 0, sizeof(g_oaInfo));\r
255         g_oaInfo.ArcName    = NULL;\r
256         g_oaInfo.ArcNameW   = sz;\r
257         g_oaInfo.OpenMode   = RAR_OM_EXTRACT;\r
258         g_oaInfo.CmtBuf     = g_szComment;\r
259         g_oaInfo.CmtBufSize = sizeof(g_szComment) - 1;\r
260         * _hArchive = ((void * (__stdcall *)(RAROpenArchiveDataEx *)) p)(& g_oaInfo);\r
261         if (* _hArchive == NULL)\r
262         {\r
263                 return TPI_ERROR_UNDEFINED;\r
264         }\r
265         int nErrorCode = nErrorCodeConvert(g_oaInfo.OpenResult);\r
266         if (nErrorCode != TPI_ERROR_SUCCESS)\r
267         {\r
268                 return nErrorCode;\r
269         }\r
270 \r
271         // \83R\81[\83\8b\83o\83b\83N\8aÖ\90\94\82ð\90Ý\92è\81B\r
272         if (! g_hLib.HasSymbol(wxT("RARSetCallback")))\r
273         {\r
274                 return TPI_ERROR_U_USE_LIBRARY;\r
275         }\r
276         p = g_hLib.GetSymbol(wxT("RARSetCallback"));\r
277         if (! p)\r
278         {\r
279                 return TPI_ERROR_U_USE_LIBRARY;\r
280         }\r
281         ((void (__stdcall *)(void *, FARPROC, LPARAM)) p)(* _hArchive, (FARPROC) CallbackProc, (LPARAM) & g_hdInfo);\r
282 \r
283         return TPI_ERROR_SUCCESS;\r
284 }\r
285 \r
286 int __stdcall CloseArchive\r
287 (\r
288         void * _hArchive\r
289 )\r
290 {\r
291         if (! g_hLib.HasSymbol(wxT("RARCloseArchive")))\r
292         {\r
293                 return TPI_ERROR_U_USE_LIBRARY;\r
294         }\r
295         void * p = g_hLib.GetSymbol(wxT("RARCloseArchive"));\r
296         return (! p || _hArchive == NULL) ? TPI_ERROR_U_USE_LIBRARY : nErrorCodeConvert(((int (__stdcall *)(void *)) p)(_hArchive));\r
297 }\r
298 \r
299 int __stdcall GetFileInformation\r
300 (\r
301         void * _hArchive,\r
302         TPI_FILEINFO * _fiInfo,\r
303         bool _bFirst\r
304 )\r
305 {\r
306         static unsigned int s_uFileID;\r
307         static void * pR, * pP;\r
308         int nErrorCode;\r
309 \r
310         if (_bFirst)\r
311         {\r
312                 s_uFileID = 0;\r
313                 pR = g_hLib.HasSymbol(wxT("RARReadHeaderEx")) ? g_hLib.GetSymbol(wxT("RARReadHeaderEx")) : NULL;\r
314                 pP = g_hLib.HasSymbol(wxT("RARProcessFileW"))  ? g_hLib.GetSymbol(wxT("RARProcessFileW")) : NULL;\r
315                 if (! pR || ! pP)\r
316                 {\r
317                         return TPI_ERROR_U_USE_LIBRARY;\r
318                 }\r
319         }\r
320 \r
321         RARHeaderDataEx hdInfo;\r
322         nErrorCode = nErrorCodeConvert(((int (__stdcall *)(void *, RARHeaderDataEx *)) pR)(_hArchive, & hdInfo));\r
323         if (nErrorCode == TPI_ERROR_SUCCESS)\r
324         {\r
325                 _fiInfo->dwAttribute    = hdInfo.FileAttr;\r
326                 _fiInfo->dwCRC32        = hdInfo.FileCRC;\r
327                 _fiInfo->llPackedSize   = wxLongLong(hdInfo.PackSizeHigh, hdInfo.PackSize);\r
328                 _fiInfo->llUnpackedSize = wxLongLong(hdInfo.UnpSizeHigh,  hdInfo.UnpSize);\r
329                 _fiInfo->tmModified.SetFromDOS(hdInfo.FileTime);\r
330                 _fiInfo->uOSType        = hdInfo.HostOS;\r
331                 _fiInfo->szStoredName   = WC2String(hdInfo.FileNameW);\r
332 //              _fiInfo->szMethod       = hdInfo.Method;\r
333                 _fiInfo->llFileID       = s_uFileID++;\r
334                 _fiInfo->fnFileName     = wxFileName(_fiInfo->szStoredName);\r
335 \r
336                 // \8e\9f\82Ì\83t\83@\83C\83\8b\82Ö\81B\r
337                 nErrorCode = nErrorCodeConvert(((int (__stdcall *)(void *, int, wchar_t *, wchar_t *)) pP)(_hArchive, RAR_SKIP, NULL, NULL));\r
338                 if (nErrorCode != TPI_ERROR_SUCCESS)\r
339                 {\r
340                         return nErrorCode;\r
341                 }\r
342         }\r
343 \r
344         return nErrorCode;\r
345 }\r
346 \r
347 int __stdcall GetArchiveInformation\r
348 (\r
349         void *,\r
350         TPI_ARCHIVEINFO * _aiInfo\r
351 )\r
352 {\r
353         _aiInfo->fSolid         = (g_oaInfo.Flags & 0x0008) == 1;\r
354         _aiInfo->fEncryptHeader = (g_oaInfo.Flags & 0x0080) == 1;\r
355         _aiInfo->szComment      = UTF82String(g_szComment);\r
356         GetFormatInformation(& _aiInfo->fiInfo, true);\r
357         return TPI_ERROR_SUCCESS;\r
358 }\r
359 \r
360 int __stdcall Command\r
361 (\r
362         unsigned int _uCommand,\r
363         TPI_SWITCHES * _swInfo,\r
364         const wxString & _szArcName,\r
365         const wxArrayString & _szFiles\r
366 )\r
367 {\r
368         if (_uCommand != TPI_COMMAND_EXTRACT && _uCommand != TPI_COMMAND_TEST)\r
369         {\r
370                 return TPI_ERROR_U_USE_LIBRARY;\r
371         }\r
372 \r
373         // \8aJ\82«\82È\82¨\82·\81B\r
374         void * hArc;\r
375         int nErrorCode = OpenArchive(_szArcName, & hArc);\r
376         if (nErrorCode != TPI_ERROR_SUCCESS)\r
377         {\r
378                 return nErrorCode;\r
379         }\r
380 \r
381         void\r
382                 * pS = g_hLib.HasSymbol(wxT("RARSetPassword"))  ? g_hLib.GetSymbol(wxT("RARSetPassword"))  : NULL,\r
383                 * pR = g_hLib.HasSymbol(wxT("RARReadHeaderEx")) ? g_hLib.GetSymbol(wxT("RARReadHeaderEx")) : NULL,\r
384                 * pP = g_hLib.HasSymbol(wxT("RARProcessFileW")) ? g_hLib.GetSymbol(wxT("RARProcessFileW")) : NULL;\r
385         if (! pR || ! pP)\r
386         {\r
387                 return TPI_ERROR_U_USE_LIBRARY;\r
388         }\r
389         if (pS)\r
390         {\r
391                 ((void (__stdcall *)(void *, char *)) pS)(hArc, _swInfo->szPassword.char_str());\r
392         }\r
393 \r
394         RARHeaderDataEx hdInfo;\r
395         g_hdInfo = & hdInfo;\r
396         while (nErrorCode == TPI_ERROR_SUCCESS && nErrorCodeConvert(((int (__stdcall *)(void *, RARHeaderDataEx *)) pR)(hArc, & hdInfo)) == TPI_ERROR_SUCCESS)\r
397         {\r
398                 nErrorCode =\r
399                         nErrorCodeConvert(\r
400                                 ((int (__stdcall *)(void *, int, wchar_t *, wchar_t *)) pP)(\r
401                                         hArc,\r
402                                         (_szFiles.GetCount() != 0 && _szFiles.Index(wxString(hdInfo.FileNameW)) == wxNOT_FOUND) ? RAR_SKIP : _uCommand == TPI_COMMAND_EXTRACT ? RAR_EXTRACT : RAR_TEST,\r
403                                         _swInfo->fStoreDirectoryPathes ? _swInfo->fnDestinationDirectory.GetFullPath().wchar_str() : NULL,\r
404                                         _swInfo->fStoreDirectoryPathes ? NULL : (_swInfo->fnDestinationDirectory.GetPathWithSep() + wxFileName(hdInfo.FileNameW).GetFullName()).wchar_str()\r
405                                 )\r
406                         );\r
407         }\r
408         CloseArchive(hArc);\r
409         return nErrorCode;\r
410 }\r
411 \r
412 int __stdcall SetCallbackProc\r
413 (\r
414         TPI_PROC _prArcProc\r
415 )\r
416 {\r
417         // \83|\83C\83\93\83^\82ð\95Û\91\81B\r
418         if (_prArcProc == NULL)\r
419         {\r
420                 return TPI_ERROR_D_PARAMETER;\r
421         }\r
422         g_prProc = * _prArcProc;\r
423 \r
424         return TPI_ERROR_SUCCESS;\r
425 }\r
426 \r
427 #ifdef __cplusplus\r
428 }\r
429 #endif\r