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 #include "../../common/header/plugin.h"
\r
27 #include "../../common/header/plugin-extra.h"
\r
28 #include "../../common/library/library.h"
\r
29 #include <wx/file.h>
\r
30 #include <wx/stdpaths.h>
\r
32 #include <windows.h>
\r
33 #include "xpiLibrary.h"
\r
35 //******************************************************************************
\r
37 //******************************************************************************
\r
42 //******************************************************************************
\r
44 //******************************************************************************
\r
46 int __stdcall CallbackProc(int _nNow, int _nMax, long _lData)
\r
49 TPI_PROCESSINFO * piInfo = (TPI_PROCESSINFO *) _lData;
\r
50 piInfo->nProcessedSize = _nNow;
\r
51 piInfo->fiInfo.nUnpackedSize = _nMax;
\r
54 return g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, piInfo) == TPI_CALLBACK_CANCEL;
\r
57 //******************************************************************************
\r
59 //******************************************************************************
\r
61 int ErrorCodeConvert(int nErrorCode)
\r
65 case -1:case XPI_NO_FUNCTION: return TPI_ERROR_U_USE_LIBRARY;
\r
66 case 0: return TPI_ERROR_SUCCESS;
\r
67 case 1: case XPI_ABORT: return TPI_ERROR_D_SKIPPED;
\r
68 case 2: case XPI_NOT_SUPPRORT: return TPI_ERROR_ARC_UNSUPPORTED;
\r
69 case 3: case XPI_OUT_OF_ORDER: return TPI_ERROR_ARC_BROKEN_MISC;
\r
70 case 4: case XPI_NO_MEMORY: return TPI_ERROR_D_OUTOFMEMORY;
\r
71 case 5: case XPI_MEMORY_ERROR: return TPI_ERROR_D_USEMEMORY;
\r
72 case 6: case XPI_FILE_READ_ERROR: return TPI_ERROR_IO_ARC_READ;
\r
73 case XPI_OTHER_ERROR: return TPI_ERROR_UNDEFINED;
\r
74 case XPI_WINDOW_ERROR: return TPI_ERROR_UNDEFINED;
\r
75 case XPI_FILE_WRITE_ERROR: return TPI_ERROR_IO_FILE_WRITE;
\r
76 case XPI_END_OF_FILE: return TPI_ERROR_ARC_BROKEN_MISC;
\r
77 default: return TPI_ERROR_UNDEFINED;
\r
81 //******************************************************************************
\r
83 //******************************************************************************
\r
90 int __stdcall GetPluginInformation
\r
92 unsigned int _uInfoId,
\r
99 return TPI_ERROR_D_PARAMETER;
\r
103 case TPI_INFO_VERSION_MAJOR:
\r
104 case TPI_INFO_VERSION_MINOR:
\r
105 * (int *) _pPtr = 0;
\r
107 case TPI_INFO_VERSION_API:
\r
108 * (int *) _pPtr = 2;
\r
110 case TPI_INFO_HANDLE_ON_COMMAND:
\r
111 * (int *) _pPtr = 0;
\r
114 return TPI_ERROR_D_PARAMETER;
\r
116 return TPI_ERROR_SUCCESS;
\r
119 int __stdcall GetFormatInformation(TPI_FORMATINFO *, bool)
\r
121 return TPI_ERROR_D_UNSUPPORTED;
\r
124 int __stdcall LoadPlugin
\r
126 const wxString & _szArcName,
\r
135 if (! hFile.Exists(_szArcName) || ! hFile.Open(_szArcName, wxFile::read))
\r
137 return TPI_ERROR_IO_ARC_OPEN;
\r
141 ::ZeroMemory(buffer, sizeof(buffer));
\r
142 if (hFile.Read(buffer, sizeof(buffer)) == wxInvalidOffset)
\r
144 return TPI_ERROR_IO_ARC_READ;
\r
148 wxString szSPIPath = wxPathOnly(wxStandardPaths::Get().GetExecutablePath()) + wxT("/lib/"), szSPIName;
\r
149 wxDir fs(szSPIPath);
\r
150 if (fs.GetFirst(& szSPIName, wxT("*.spi")))
\r
155 g_hLib = ::LoadLibrary((szSPIPath + szSPIName).wchar_str());
\r
156 if (g_hLib == NULL)
\r
161 // GetPluginInfoを実行。
\r
162 FARPROC fpProc = ::GetProcAddress(g_hLib, "GetPluginInfo");
\r
163 char szPluginType[5]; // 種類4bytes + NULL
\r
165 || ((int (PASCAL *)(int, char *, int)) fpProc)(0, szPluginType, sizeof(szPluginType)) <= 0
\r
166 || szPluginType[2] != 'I' || szPluginType[3] != 'N')
\r
168 ::FreeLibrary(g_hLib);
\r
173 fpProc = ::GetProcAddress(g_hLib, "IsSupported");
\r
174 if (fpProc == NULL)
\r
176 ::FreeLibrary(g_hLib);
\r
180 if (((BOOL (PASCAL *)(const char *, unsigned long)) fpProc)(_szArcName.ToUTF8(), (unsigned long) buffer))
\r
183 if (_prProc != NULL)
\r
185 g_prProc = * _prProc;
\r
187 return TPI_ERROR_SUCCESS;
\r
190 while (fs.GetNext(& szSPIName));
\r
192 return TPI_ERROR_U_LOAD_LIBRARY;
\r
195 int __stdcall FreePlugin
\r
197 void * // _pReserved
\r
200 ::FreeLibrary(g_hLib);
\r
201 return TPI_ERROR_SUCCESS;
\r
204 int __stdcall OpenArchive
\r
206 const wxString & _szArcName,
\r
207 void * * _hArchive,
\r
211 * _hArchive = new wxString(_szArcName);
\r
212 return TPI_ERROR_SUCCESS;
\r
215 int __stdcall CloseArchive
\r
220 delete (wxString *) _hArchive;
\r
221 return TPI_ERROR_SUCCESS;
\r
224 int __stdcall GetFileInformation
\r
227 TPI_FILEINFO * _fiInfo,
\r
231 static wxString szXPIPath, szXPIName, szArcName = * (wxString *) _hArchive;
\r
232 static int nColorDepth;
\r
236 szXPIPath = wxPathOnly(wxStandardPaths::Get().GetExecutablePath()) + wxT("/lib/");
\r
237 fs.Open(szXPIPath);
\r
240 FARPROC fpProc = ::GetProcAddress(g_hLib, "GetPictureInfo");
\r
241 if (fpProc == NULL)
\r
243 return TPI_ERROR_U_USE_LIBRARY;
\r
245 PictureInfo picInfo;
\r
246 int nErrorCode = ErrorCodeConvert(((int (PASCAL *)(const char *, long, unsigned int, PictureInfo *)) fpProc)(szArcName.ToUTF8(), 0, 0, & picInfo));
\r
247 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
251 nColorDepth = picInfo.colorDepth;
\r
252 ::LocalUnlock(picInfo.hInfo);
\r
253 ::LocalFree(picInfo.hInfo);
\r
256 if (_bFirst ? fs.GetFirst(& szXPIName, wxT("*.xpi")) : fs.GetNext(& szXPIName))
\r
261 HMODULE hXPI = ::LoadLibrary((szXPIPath + szXPIName).wchar_str());
\r
267 // GetPluginInfoを実行。
\r
268 FARPROC fpProc = ::GetProcAddress(hXPI, "GetPluginInfo");
\r
270 memset(szTemp, 0, sizeof(szTemp));
\r
272 || ((int (PASCAL *)(int, char *, int)) fpProc)(0, szTemp, sizeof(szTemp) - 1) <= 0
\r
273 || szTemp[2] != 'X' || szTemp[3] != 'N')
\r
275 ::FreeLibrary(hXPI);
\r
279 _fiInfo->fnFileName = wxFileName(szArcName);
\r
280 _fiInfo->fnFileName.SetVolume(wxEmptyString);
\r
281 _fiInfo->fnFileName.SetPath(szXPIName);
\r
282 if (((int (PASCAL *)(int, char *, int)) fpProc)(1, szTemp, sizeof(szTemp) - 1) > 0)
\r
284 _fiInfo->szComment = MB2String(szTemp);
\r
286 if (((int (PASCAL *)(int, char *, int)) fpProc)(2, szTemp, sizeof(szTemp) - 1) > 0)
\r
288 _fiInfo->fnFileName.SetExt(MB2String(szTemp));
\r
290 _fiInfo->szStoredName = _fiInfo->fnFileName.GetFullPath();
\r
293 fpProc = ::GetProcAddress(hXPI, "IsSupported");
\r
294 if (fpProc == NULL || ! ((BOOL (PASCAL *)(int)) fpProc)(nColorDepth))
\r
296 ::FreeLibrary(hXPI);
\r
299 return TPI_ERROR_SUCCESS;
\r
301 while (fs.GetNext(& szXPIName));
\r
303 return TPI_ERROR_S_ENDOFDATA;
\r
306 int __stdcall GetArchiveInformation
\r
309 TPI_ARCHIVEINFO * _aiInfo
\r
313 FARPROC fpProc = ::GetProcAddress(g_hLib, "GetPictureInfo");
\r
314 if (fpProc == NULL)
\r
316 return TPI_ERROR_U_USE_LIBRARY;
\r
318 PictureInfo piInfo;
\r
319 int nErrorCode = ErrorCodeConvert(((int (PASCAL *)(const char *, long, unsigned int, PictureInfo *)) fpProc)(((wxString *) _hArchive)->ToUTF8(), 0, 0, & piInfo));
\r
320 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
324 _aiInfo->szComment = MB2String((char *) ::LocalLock(piInfo.hInfo));
\r
325 ::LocalUnlock(piInfo.hInfo);
\r
326 ::LocalFree(piInfo.hInfo);
\r
328 // GetPluginInfoを実行。
\r
329 fpProc = ::GetProcAddress(g_hLib, "GetPluginInfo");
\r
330 if (fpProc != NULL)
\r
333 memset(szTemp, 0, sizeof(szTemp));
\r
334 if (((int (PASCAL *)(int, char *, int)) fpProc)(1, szTemp, sizeof(szTemp) - 1) > 0)
\r
336 _aiInfo->fiInfo.szEngineName = MB2String(szTemp);
\r
338 if (((int (PASCAL *)(int, char *, int)) fpProc)(2, szTemp, sizeof(szTemp) - 1) > 0)
\r
340 _aiInfo->fiInfo.szSuffix = MB2String(szTemp);
\r
342 if (((int (PASCAL *)(int, char *, int)) fpProc)(3, szTemp, sizeof(szTemp) - 1) > 0)
\r
344 _aiInfo->fiInfo.szTypeName = MB2String(szTemp);
\r
347 _aiInfo->fiInfo.fArchive = false;
\r
348 _aiInfo->fiInfo.szTPIName = wxT("xpiLibrary");
\r
349 _aiInfo->fiInfo.eSupportedCommand = TPI_COMMAND_EXTRACT;
\r
351 return TPI_ERROR_SUCCESS;
\r
354 int __stdcall Command
\r
356 wxULongLong_t _eCommand,
\r
357 TPI_SWITCHES * _swInfo,
\r
358 void *,// _hArchive,
\r
359 const wxArrayString & _asFiles
\r
362 if (_eCommand != TPI_COMMAND_EXTRACT)
\r
364 return TPI_ERROR_D_UNSUPPORTED;
\r
368 FARPROC fpProc = ::GetProcAddress(g_hLib, "GetPictureInfo");
\r
369 if (fpProc == NULL)
\r
371 return TPI_ERROR_U_USE_LIBRARY;
\r
373 PictureInfo picInfo;
\r
374 int nErrorCode = ErrorCodeConvert(((int (PASCAL *)(const char *, long, unsigned int, PictureInfo *)) fpProc)(_swInfo->szArcName.ToUTF8(), 0, 0, & picInfo));
\r
375 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
381 wxFileName _fnArcName(_swInfo->szArcName);
\r
382 TPI_PROCESSINFO piInfo;
\r
383 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
384 piInfo.eStatus = TPI_STATUS_OPENARCHIVE;
\r
385 piInfo.fiInfo.fnFileName = _fnArcName;
\r
386 if (CallbackProc(0, 0, (long) & piInfo))
\r
388 return TPI_ERROR_D_SKIPPED;
\r
392 HANDLE hInfo, hMemory;
\r
393 fpProc = ::GetProcAddress(g_hLib, "GetPicture");
\r
394 if (fpProc == NULL)
\r
396 return TPI_ERROR_U_USE_LIBRARY;
\r
398 nErrorCode = ErrorCodeConvert(((int (PASCAL *)(const char *, long, unsigned int, HANDLE *, HANDLE *, FARPROC, long)) fpProc)(_swInfo->szArcName.ToUTF8(), 0, 0, & hInfo, & hMemory, (FARPROC) CallbackProc, (long) & piInfo));
\r
399 if (nErrorCode == TPI_ERROR_SUCCESS && (hMemory == NULL || hInfo == NULL))
\r
401 return TPI_ERROR_UNDEFINED;
\r
403 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
408 wxString szXPIPath = wxPathOnly(wxStandardPaths::Get().GetExecutablePath()) + wxT("/lib/");
\r
409 for (size_t i = 0; i < _asFiles.GetCount(); i++)
\r
412 piInfo.eMessage = TPI_MESSAGE_ASK;
\r
413 piInfo.eStatus = TPI_PARAM_DEST;
\r
414 piInfo.fiInfo.fnFileName = wxFileName(_asFiles[i]);
\r
415 piInfo.fnDestination = piInfo.fiInfo.fnFileName;
\r
416 piInfo.fnDestination.SetPath(_swInfo->fnDestinationDirectory.GetPath());
\r
417 if (CallbackProc(0, 0, (long) & piInfo))
\r
419 nErrorCode = TPI_ERROR_D_SKIPPED;
\r
422 if (! piInfo.fnDestination.IsOk())
\r
428 HMODULE hXPI = ::LoadLibrary((szXPIPath + piInfo.fiInfo.fnFileName.GetPath()).wchar_str());
\r
431 nErrorCode = TPI_ERROR_U_USE_LIBRARY;
\r
435 // GetPluginInfoを実行。
\r
436 FARPROC fpProc = ::GetProcAddress(hXPI, "GetPluginInfo");
\r
439 || ((int (PASCAL *)(int, char *, int)) fpProc)(2, szTemp, sizeof(szTemp)) <= 0)
\r
441 ::FreeLibrary(hXPI);
\r
442 nErrorCode = TPI_ERROR_U_USE_LIBRARY;
\r
447 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
448 piInfo.eStatus = TPI_STATUS_BEGINPROCESS;
\r
449 if (CallbackProc(0, 0, (long) & piInfo))
\r
451 ::FreeLibrary(hXPI);
\r
452 nErrorCode = TPI_ERROR_D_SKIPPED;
\r
457 piInfo.eStatus = TPI_STATUS_INPROCESS;
\r
458 fpProc = ::GetProcAddress(hXPI, "CreatePicture");
\r
459 if (fpProc == NULL)
\r
461 ::FreeLibrary(hXPI);
\r
462 nErrorCode = TPI_ERROR_U_USE_LIBRARY;
\r
465 nErrorCode = ErrorCodeConvert(((int (PASCAL *)(const char *, long, HANDLE *, HANDLE *, PictureInfo *, FARPROC, long)) fpProc)(piInfo.fnDestination.GetFullPath().ToUTF8(), 0, & hInfo, & hMemory, & picInfo, (FARPROC) CallbackProc, (long) & piInfo));
\r
466 ::FreeLibrary(hXPI);
\r
469 piInfo.eStatus = TPI_STATUS_ENDPROCESS;
\r
470 if (CallbackProc(0, 0, (long) & piInfo))
\r
472 nErrorCode = TPI_ERROR_D_SKIPPED;
\r
476 ::LocalUnlock(hInfo);
\r
477 ::LocalUnlock(hMemory);
\r
478 ::LocalUnlock(picInfo.hInfo);
\r
479 ::LocalFree(hInfo);
\r
480 ::LocalFree(hMemory);
\r
481 ::LocalFree(picInfo.hInfo);
\r
482 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
488 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
489 piInfo.eStatus = TPI_STATUS_CLOSEARCHIVE;
\r
490 piInfo.fiInfo.fnFileName = _fnArcName;
\r
491 if (CallbackProc(0, 0, (long) & piInfo))
\r
493 return TPI_ERROR_D_SKIPPED;
\r
496 return TPI_ERROR_SUCCESS;
\r