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 #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
34 //******************************************************************************
\r
36 //******************************************************************************
\r
38 wxDynamicLibrary g_hLib;
\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
46 //******************************************************************************
\r
48 //******************************************************************************
\r
50 int __stdcall CallbackProc(unsigned int msg, long UserData, long P1, long P2)
\r
52 //
\8d\
\91¢
\91Ì
\82ð
\8f\89\8aú
\89»
\81B
\r
53 static TPI_PROCESSINFO piInfo;
\r
57 case UCM_CHANGEVOLUME:
\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
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
76 case UCM_PROCESSDATA:
\r
77 piInfo.uMessage = TPI_MESSAGE_STATUS;
\r
78 piInfo.uStatus = TPI_STATUS_INPROCESS;
\r
79 piInfo.llProcessedSize += P2;
\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
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
93 if (msg != UCM_PROCESSDATA && P2 != RAR_VOL_NOTIFY)
\r
95 strncpy((char *) P1, piInfo.szParam.char_str(), (msg == UCM_CHANGEVOLUME ? 1024 : P2) - 1);
\r
105 //******************************************************************************
\r
106 // Inside Functions
\r
107 //******************************************************************************
\r
109 int nErrorCodeConvert(int nErrorCode)
\r
111 switch (nErrorCode)
\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
132 //******************************************************************************
\r
134 //******************************************************************************
\r
141 int __stdcall GetPluginInformation
\r
143 unsigned int _uInfoId,
\r
150 return TPI_ERROR_D_PARAMETER;
\r
152 switch (LOWORD(_uInfoId))
\r
154 case TPI_INFO_VERSION_MAJOR:
\r
155 case TPI_INFO_VERSION_MINOR:
\r
156 * (int *) _pPtr = 0;
\r
158 case TPI_INFO_VERSION_API:
\r
159 * (int *) _pPtr = 2;
\r
162 return TPI_ERROR_D_UNSUPPORTED;
\r
164 return TPI_ERROR_SUCCESS;
\r
167 int __stdcall GetFormatInformation(TPI_FORMATINFO * _fiInfo, bool _bFirst)
\r
171 return TPI_ERROR_S_ENDOFDATA;
\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
186 return TPI_ERROR_SUCCESS;
\r
189 int __stdcall LoadPlugin
\r
191 const wxString & _szArcName,
\r
195 g_hLib.Load(g_hLib.CanonicalizeName(wxT("unrar")));
\r
196 if (! g_hLib.IsLoaded() || CheckArchive(_szArcName, NULL) != TPI_ERROR_SUCCESS)
\r
199 return TPI_ERROR_U_LOAD_LIBRARY;
\r
202 return TPI_ERROR_SUCCESS;
\r
205 int __stdcall FreePlugin
\r
207 void * // _pReserved
\r
211 return TPI_ERROR_SUCCESS;
\r
214 int __stdcall CheckArchive
\r
216 const wxString & _szArcName,
\r
221 int nErrorCode = OpenArchive(_szArcName, & _hArchive);
\r
222 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
227 if (_nFileCount != NULL)
\r
232 return CloseArchive(_hArchive);
\r
235 int __stdcall OpenArchive
\r
237 const wxString & _szArcName,
\r
241 if (! g_hLib.HasSymbol(wxT("RAROpenArchiveEx")))
\r
243 return TPI_ERROR_U_USE_LIBRARY;
\r
245 void * p = g_hLib.GetSymbol(wxT("RAROpenArchiveEx"));
\r
248 return TPI_ERROR_U_USE_LIBRARY;
\r
251 // TODO :
\95¶
\8e\9a\90\94\90§
\8cÀ
\93P
\94p
\81B
\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
263 return TPI_ERROR_UNDEFINED;
\r
265 int nErrorCode = nErrorCodeConvert(g_oaInfo.OpenResult);
\r
266 if (nErrorCode != TPI_ERROR_SUCCESS)
\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
274 return TPI_ERROR_U_USE_LIBRARY;
\r
276 p = g_hLib.GetSymbol(wxT("RARSetCallback"));
\r
279 return TPI_ERROR_U_USE_LIBRARY;
\r
281 ((void (__stdcall *)(void *, FARPROC, LPARAM)) p)(* _hArchive, (FARPROC) CallbackProc, (LPARAM) & g_hdInfo);
\r
283 return TPI_ERROR_SUCCESS;
\r
286 int __stdcall CloseArchive
\r
291 if (! g_hLib.HasSymbol(wxT("RARCloseArchive")))
\r
293 return TPI_ERROR_U_USE_LIBRARY;
\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
299 int __stdcall GetFileInformation
\r
302 TPI_FILEINFO * _fiInfo,
\r
306 static unsigned int s_uFileID;
\r
307 static void * pR, * pP;
\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
317 return TPI_ERROR_U_USE_LIBRARY;
\r
321 RARHeaderDataEx hdInfo;
\r
322 nErrorCode = nErrorCodeConvert(((int (__stdcall *)(void *, RARHeaderDataEx *)) pR)(_hArchive, & hdInfo));
\r
323 if (nErrorCode == TPI_ERROR_SUCCESS)
\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
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
347 int __stdcall GetArchiveInformation
\r
350 TPI_ARCHIVEINFO * _aiInfo
\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
360 int __stdcall Command
\r
362 unsigned int _uCommand,
\r
363 TPI_SWITCHES * _swInfo,
\r
364 const wxString & _szArcName,
\r
365 const wxArrayString & _szFiles
\r
368 if (_uCommand != TPI_COMMAND_EXTRACT && _uCommand != TPI_COMMAND_TEST)
\r
370 return TPI_ERROR_U_USE_LIBRARY;
\r
373 //
\8aJ
\82«
\82È
\82¨
\82·
\81B
\r
375 int nErrorCode = OpenArchive(_szArcName, & hArc);
\r
376 if (nErrorCode != TPI_ERROR_SUCCESS)
\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
387 return TPI_ERROR_U_USE_LIBRARY;
\r
391 ((void (__stdcall *)(void *, char *)) pS)(hArc, _swInfo->szPassword.char_str());
\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
400 ((int (__stdcall *)(void *, int, wchar_t *, wchar_t *)) pP)(
\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
408 CloseArchive(hArc);
\r
412 int __stdcall SetCallbackProc
\r
414 TPI_PROC _prArcProc
\r
417 //
\83|
\83C
\83\93\83^
\82ð
\95Û
\91¶
\81B
\r
418 if (_prArcProc == NULL)
\r
420 return TPI_ERROR_D_PARAMETER;
\r
422 g_prProc = * _prArcProc;
\r
424 return TPI_ERROR_SUCCESS;
\r