OSDN Git Service

数値の型をwxULongLong_tに変更。
[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 "rarArc.h"\r
32 \r
33 //******************************************************************************\r
34 //    Global varients\r
35 //******************************************************************************\r
36 \r
37 wxDynamicLibrary g_hLib;\r
38 TPI_PROC g_prProc;\r
39 TPI_SWITCHES * g_swInfo;\r
40 const wxArrayString * g_asFiles;\r
41 char g_szComment[64001];\r
42 RAROpenArchiveDataEx g_oaInfo;\r
43 RARHeaderDataEx * g_hdInfo;\r
44 \r
45 //******************************************************************************\r
46 //    Callback Wrapper\r
47 //******************************************************************************\r
48 \r
49 int __stdcall CallbackProc(unsigned int msg, long, long P1, long P2)\r
50 {\r
51         // 構造体を初期化。\r
52         static TPI_PROCESSINFO piInfo;\r
53 \r
54         switch (msg)\r
55         {\r
56         case UCM_CHANGEVOLUME:\r
57                 switch (P2)\r
58                 {\r
59                 case RAR_VOL_ASK:\r
60                         // 分割書庫の次の部分を要求。\r
61                         piInfo.uMessage = TPI_MESSAGE_ASK;\r
62                         piInfo.uStatus  = TPI_PARAM_NEXTVOLUME;\r
63                         piInfo.szParam.Clear();\r
64                         break;\r
65                 case RAR_VOL_NOTIFY:\r
66                         // 分割部分の読み込みを開始。\r
67                         piInfo.uMessage = TPI_MESSAGE_STATUS;\r
68                         piInfo.uStatus  = TPI_STATUS_OPENARCHIVE;\r
69                         piInfo.fiInfo.fnFileName = wxFileName(UTF82String((char *) P1));\r
70                         break;\r
71                 default:\r
72                         return 1;\r
73                 }\r
74                 break;\r
75         case UCM_PROCESSDATA:\r
76                 piInfo.uMessage = TPI_MESSAGE_STATUS;\r
77                 piInfo.uStatus  = TPI_STATUS_INPROCESS;\r
78                 piInfo.llProcessedSize += P2;\r
79                 break;\r
80         case UCM_NEEDPASSWORD:\r
81                 piInfo.uMessage = TPI_MESSAGE_ASK;\r
82                 piInfo.uStatus  = TPI_PARAM_PASSWORD;\r
83                 piInfo.szParam.Clear();\r
84                 break;\r
85         default:\r
86                 return 1;\r
87         }\r
88 \r
89         // コールバック関数に送信。\r
90         if (g_prProc == NULL || g_prProc(TPI_NOTIFY_COMMON, & piInfo) == TPI_CALLBACK_CONTINUE)\r
91         {\r
92                 if (msg != UCM_PROCESSDATA && P2 != RAR_VOL_NOTIFY)\r
93                 {\r
94                         strncpy((char *) P1, piInfo.szParam.char_str(), (msg == UCM_CHANGEVOLUME ? 1024 : P2) - 1);\r
95                 }\r
96                 return 1;\r
97         }\r
98         else\r
99         {\r
100                 return -1;\r
101         }\r
102 }\r
103 \r
104 //******************************************************************************\r
105 //    Inside Functions\r
106 //******************************************************************************\r
107 \r
108 int ErrorCodeConvert(int nErrorCode)\r
109 {\r
110         switch (nErrorCode)\r
111         {\r
112         case 0:                     return TPI_ERROR_SUCCESS;\r
113         case 1:                     return TPI_ERROR_SUCCESS;\r
114         case ERAR_END_ARCHIVE:      return TPI_ERROR_S_ENDOFDATA;\r
115         case ERAR_NO_MEMORY:        return TPI_ERROR_D_OUTOFMEMORY;\r
116         case ERAR_BAD_DATA:         return TPI_ERROR_ARC_BROKEN_MISC;\r
117         case ERAR_BAD_ARCHIVE:      return TPI_ERROR_ARC_UNSUPPORTED;\r
118         case ERAR_UNKNOWN_FORMAT:   return TPI_ERROR_ARC_ENCRYPTED;\r
119         case ERAR_EOPEN:            return TPI_ERROR_IO_ARC_OPEN;\r
120         case ERAR_ECREATE:          return TPI_ERROR_IO_FILE_OPEN;\r
121         case ERAR_ECLOSE:           return TPI_ERROR_IO_CLOSE;\r
122         case ERAR_EREAD:            return TPI_ERROR_IO_ARC_READ;\r
123         case ERAR_EWRITE:           return TPI_ERROR_IO_FILE_WRITE;\r
124         case ERAR_SMALL_BUF:        return TPI_ERROR_UNDEFINED;\r
125         case ERAR_UNKNOWN:          return TPI_ERROR_UNDEFINED;\r
126         case ERAR_MISSING_PASSWORD: return TPI_ERROR_ARC_ENCRYPTED;\r
127         default:                    return TPI_ERROR_UNDEFINED;\r
128         }\r
129 }\r
130 \r
131 //******************************************************************************\r
132 //    Functions\r
133 //******************************************************************************\r
134 \r
135 #ifdef __cplusplus\r
136 extern "C"\r
137 {\r
138 #endif\r
139 \r
140 int __stdcall GetPluginInformation\r
141 (\r
142         unsigned int _uInfoId,\r
143         wxULongLong_t,\r
144         void * _pPtr\r
145 )\r
146 {\r
147         if (_pPtr == NULL)\r
148         {\r
149                 return TPI_ERROR_D_PARAMETER;\r
150         }\r
151         switch (_uInfoId)\r
152         {\r
153         case TPI_INFO_VERSION_MAJOR:\r
154         case TPI_INFO_VERSION_MINOR:\r
155                 * (int *) _pPtr = 0;\r
156                 break;\r
157         case TPI_INFO_VERSION_API:\r
158                 * (int *) _pPtr = 2;\r
159                 break;\r
160         default:\r
161                 return TPI_ERROR_D_UNSUPPORTED;\r
162         }\r
163         return TPI_ERROR_SUCCESS;\r
164 }\r
165 \r
166 int __stdcall GetFormatInformation(TPI_FORMATINFO * _fiInfo, bool _bFirst)\r
167 {\r
168         if (! _bFirst)\r
169         {\r
170                 return TPI_ERROR_S_ENDOFDATA;\r
171         }\r
172 \r
173         _fiInfo->szTypeName   = wxT("RAR");\r
174         _fiInfo->szSuffix     = wxT("rar");\r
175         _fiInfo->szEngineName = g_hLib.CanonicalizeName(wxT("unrar"));\r
176         _fiInfo->szTPIName    = wxT("rarArc");\r
177         _fiInfo->llTypeId     = 0;\r
178         _fiInfo->llSupportedCommand = TPI_COMMAND_EXTRACT | TPI_COMMAND_TEST;\r
179         _fiInfo->fArchive     = true;\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 &,\r
192         wxULongLong_t\r
193 )\r
194 {\r
195         g_hLib.Load(g_hLib.CanonicalizeName(wxT("unrar")));\r
196         if (! g_hLib.IsLoaded())\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         wxULongLong_t * _llFileCount\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 (_llFileCount != NULL)\r
228         {\r
229                 * _llFileCount = 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         memset(& g_oaInfo, 0, sizeof(g_oaInfo));\r
252         g_oaInfo.ArcName    = NULL;\r
253         g_oaInfo.ArcNameW   = (wchar_t *) malloc((_szArcName.Len() + 1) * sizeof(wchar_t));\r
254         wcscpy(g_oaInfo.ArcNameW, _szArcName.wchar_str());\r
255         g_oaInfo.OpenMode   = RAR_OM_EXTRACT;\r
256         g_oaInfo.CmtBuf     = g_szComment;\r
257         g_oaInfo.CmtBufSize = sizeof(g_szComment) - 1;\r
258         * _hArchive = ((void * (__stdcall *)(RAROpenArchiveDataEx *)) p)(& g_oaInfo);\r
259         free(g_oaInfo.ArcNameW);\r
260         if (* _hArchive == NULL)\r
261         {\r
262                 return TPI_ERROR_UNDEFINED;\r
263         }\r
264         int nErrorCode = ErrorCodeConvert(g_oaInfo.OpenResult);\r
265         if (nErrorCode != TPI_ERROR_SUCCESS)\r
266         {\r
267                 return nErrorCode;\r
268         }\r
269 \r
270         // コールバック関数を設定。\r
271         if (! g_hLib.HasSymbol(wxT("RARSetCallback")))\r
272         {\r
273                 return TPI_ERROR_U_USE_LIBRARY;\r
274         }\r
275         p = g_hLib.GetSymbol(wxT("RARSetCallback"));\r
276         if (! p)\r
277         {\r
278                 return TPI_ERROR_U_USE_LIBRARY;\r
279         }\r
280         ((void (__stdcall *)(void *, void *, long)) p)(* _hArchive, (void *) CallbackProc, (long) & g_hdInfo);\r
281 \r
282         return TPI_ERROR_SUCCESS;\r
283 }\r
284 \r
285 int __stdcall CloseArchive\r
286 (\r
287         void * _hArchive\r
288 )\r
289 {\r
290         if (! g_hLib.HasSymbol(wxT("RARCloseArchive")))\r
291         {\r
292                 return TPI_ERROR_U_USE_LIBRARY;\r
293         }\r
294         void * p = g_hLib.GetSymbol(wxT("RARCloseArchive"));\r
295         return (! p || _hArchive == NULL) ? TPI_ERROR_U_USE_LIBRARY : ErrorCodeConvert(((int (__stdcall *)(void *)) p)(_hArchive));\r
296 }\r
297 \r
298 int __stdcall GetFileInformation\r
299 (\r
300         void * _hArchive,\r
301         TPI_FILEINFO * _fiInfo,\r
302         bool _bFirst\r
303 )\r
304 {\r
305         static wxULongLong_t s_nFileId;\r
306         static void * pR, * pP;\r
307         int nErrorCode;\r
308 \r
309         if (_bFirst)\r
310         {\r
311                 s_nFileId = 0;\r
312                 pR = g_hLib.HasSymbol(wxT("RARReadHeaderEx")) ? g_hLib.GetSymbol(wxT("RARReadHeaderEx")) : NULL;\r
313                 pP = g_hLib.HasSymbol(wxT("RARProcessFileW"))  ? g_hLib.GetSymbol(wxT("RARProcessFileW")) : NULL;\r
314                 if (! pR || ! pP)\r
315                 {\r
316                         return TPI_ERROR_U_USE_LIBRARY;\r
317                 }\r
318         }\r
319 \r
320         RARHeaderDataEx hdInfo;\r
321         nErrorCode = ErrorCodeConvert(((int (__stdcall *)(void *, RARHeaderDataEx *)) pR)(_hArchive, & hdInfo));\r
322         if (nErrorCode == TPI_ERROR_SUCCESS)\r
323         {\r
324                 _fiInfo->dwAttribute    = hdInfo.FileAttr;\r
325                 if (hdInfo.Flags & 0x04)\r
326                 {\r
327                         _fiInfo->dwAttribute |= TPI_ATTRIBUTE_ENCRYPTED;\r
328                 }\r
329                 _fiInfo->dwCRC32        = hdInfo.FileCRC;\r
330                 _fiInfo->llPackedSize   = wxLongLong(hdInfo.PackSizeHigh, hdInfo.PackSize).GetValue();\r
331                 _fiInfo->llUnpackedSize = wxLongLong(hdInfo.UnpSizeHigh,  hdInfo.UnpSize).GetValue();\r
332                 _fiInfo->tmModified.SetFromDOS(hdInfo.FileTime);\r
333                 _fiInfo->uOSType        = hdInfo.HostOS;\r
334                 _fiInfo->szStoredName   = WC2String(hdInfo.FileNameW);\r
335                 _fiInfo->szMethod       = wxString::Format(wxT("%x"), hdInfo.Method);\r
336                 _fiInfo->szComment      = UTF82String(hdInfo.CmtBuf);\r
337                 _fiInfo->llFileId       = s_nFileId++;\r
338                 _fiInfo->fnFileName     = wxFileName(_fiInfo->szStoredName);\r
339 \r
340                 // 次のファイルへ。\r
341                 nErrorCode = ErrorCodeConvert(((int (__stdcall *)(void *, int, wchar_t *, wchar_t *)) pP)(_hArchive, RAR_SKIP, NULL, NULL));\r
342                 if (nErrorCode != TPI_ERROR_SUCCESS)\r
343                 {\r
344                         return nErrorCode;\r
345                 }\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         _aiInfo->fSolid         = (g_oaInfo.Flags & 0x0008) == 1;\r
358         _aiInfo->fEncryptHeader = (g_oaInfo.Flags & 0x0080) == 1;\r
359         _aiInfo->szComment      = UTF82String(g_szComment);\r
360         GetFormatInformation(& _aiInfo->fiInfo, true);\r
361         return TPI_ERROR_SUCCESS;\r
362 }\r
363 \r
364 int __stdcall Command\r
365 (\r
366         unsigned int _uCommand,\r
367         TPI_SWITCHES * _swInfo,\r
368         const wxString & _szArcName,\r
369         const wxArrayString & _szFiles\r
370 )\r
371 {\r
372         if (_uCommand != TPI_COMMAND_EXTRACT && _uCommand != TPI_COMMAND_TEST)\r
373         {\r
374                 return TPI_ERROR_U_USE_LIBRARY;\r
375         }\r
376 \r
377         // 開きなおす。\r
378         void * hArc;\r
379         int nErrorCode = OpenArchive(_szArcName, & hArc);\r
380         if (nErrorCode != TPI_ERROR_SUCCESS)\r
381         {\r
382                 return nErrorCode;\r
383         }\r
384 \r
385         void\r
386                 * pS = g_hLib.HasSymbol(wxT("RARSetPassword"))  ? g_hLib.GetSymbol(wxT("RARSetPassword"))  : NULL,\r
387                 * pR = g_hLib.HasSymbol(wxT("RARReadHeaderEx")) ? g_hLib.GetSymbol(wxT("RARReadHeaderEx")) : NULL,\r
388                 * pP = g_hLib.HasSymbol(wxT("RARProcessFileW")) ? g_hLib.GetSymbol(wxT("RARProcessFileW")) : NULL;\r
389         if (! pR || ! pP)\r
390         {\r
391                 return TPI_ERROR_U_USE_LIBRARY;\r
392         }\r
393         if (pS)\r
394         {\r
395                 ((void (__stdcall *)(void *, char *)) pS)(hArc, _swInfo->szPassword.char_str());\r
396         }\r
397 \r
398         RARHeaderDataEx hdInfo;\r
399         g_hdInfo = & hdInfo;\r
400         while (nErrorCode == TPI_ERROR_SUCCESS && ErrorCodeConvert(((int (__stdcall *)(void *, RARHeaderDataEx *)) pR)(hArc, & hdInfo)) == TPI_ERROR_SUCCESS)\r
401         {\r
402                 nErrorCode =\r
403                         ErrorCodeConvert(\r
404                                 ((int (__stdcall *)(void *, int, wchar_t *, wchar_t *)) pP)(\r
405                                         hArc,\r
406                                         (_szFiles.GetCount() != 0 && _szFiles.Index(wxString(hdInfo.FileNameW)) == wxNOT_FOUND) ? RAR_SKIP : _uCommand == TPI_COMMAND_EXTRACT ? RAR_EXTRACT : RAR_TEST,\r
407                                         _swInfo->fStoreDirectoryPathes ? _swInfo->fnDestinationDirectory.GetFullPath().wchar_str() : NULL,\r
408                                         _swInfo->fStoreDirectoryPathes ? NULL : (_swInfo->fnDestinationDirectory.GetPathWithSep() + wxFileName(hdInfo.FileNameW).GetFullName()).wchar_str()\r
409                                 )\r
410                         );\r
411         }\r
412         CloseArchive(hArc);\r
413         return nErrorCode;\r
414 }\r
415 \r
416 int __stdcall SetCallbackProc\r
417 (\r
418         TPI_PROC _prArcProc\r
419 )\r
420 {\r
421         // ポインタを保存。\r
422         if (_prArcProc == NULL)\r
423         {\r
424                 return TPI_ERROR_D_PARAMETER;\r
425         }\r
426         g_prProc = * _prArcProc;\r
427 \r
428         return TPI_ERROR_SUCCESS;\r
429 }\r
430 \r
431 #ifdef __cplusplus\r
432 }\r
433 #endif\r