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
41 wxString g_szArcName;
\r
43 //******************************************************************************
\r
45 //******************************************************************************
\r
47 BOOL __stdcall DllMain(HMODULE, DWORD fdwReason, void *)
\r
51 case DLL_PROCESS_DETACH:
\r
52 ::FreeLibrary(g_hLib);
\r
58 //******************************************************************************
\r
60 //******************************************************************************
\r
62 int __stdcall CallbackProc(int _nNow, int _nMax, long _lData)
\r
64 //
\8d\
\91¢
\91Ì
\82ð
\8f\89\8aú
\89»
\81B
\r
65 TPI_PROCESSINFO * piInfo = (TPI_PROCESSINFO *) _lData;
\r
66 piInfo->llProcessedSize = _nNow;
\r
67 piInfo->fiInfo.llUnpackedSize = _nMax;
\r
69 //
\83R
\81[
\83\8b\83o
\83b
\83N
\8aÖ
\90\94\82É
\91\97\90M
\81B
\r
70 return g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, piInfo) == TPI_CALLBACK_CANCEL;
\r
73 //******************************************************************************
\r
75 //******************************************************************************
\r
77 int XpiErrorCodeConvert(int nXpiErrorCode)
\r
79 switch (nXpiErrorCode)
\r
81 case -1:case XPI_NO_FUNCTION: return TPI_ERROR_U_USE_LIBRARY;
\r
82 case 0: return TPI_ERROR_SUCCESS;
\r
83 case 1: case XPI_ABORT: return TPI_ERROR_D_SKIPPED;
\r
84 case 2: case XPI_NOT_SUPPRORT: return TPI_ERROR_ARC_UNSUPPORTED;
\r
85 case 3: case XPI_OUT_OF_ORDER: return TPI_ERROR_ARC_BROKEN_MISC;
\r
86 case 4: case XPI_NO_MEMORY: return TPI_ERROR_D_OUTOFMEMORY;
\r
87 case 5: case XPI_MEMORY_ERROR: return TPI_ERROR_D_USEMEMORY;
\r
88 case 6: case XPI_FILE_READ_ERROR: return TPI_ERROR_IO_ARC_READ;
\r
89 case XPI_OTHER_ERROR: return TPI_ERROR_UNDEFINED;
\r
90 case XPI_WINDOW_ERROR: return TPI_ERROR_UNDEFINED;
\r
91 case XPI_FILE_WRITE_ERROR: return TPI_ERROR_IO_FILE_WRITE;
\r
92 case XPI_END_OF_FILE: return TPI_ERROR_ARC_BROKEN_MISC;
\r
93 default: return TPI_ERROR_UNDEFINED;
\r
97 //******************************************************************************
\r
99 //******************************************************************************
\r
106 int __stdcall GetPluginInformation
\r
108 unsigned int _uInfoId,
\r
115 return TPI_ERROR_D_PARAMETER;
\r
119 case TPI_INFO_VERSION_MAJOR:
\r
120 case TPI_INFO_VERSION_MINOR:
\r
121 * (int *) _pPtr = 0;
\r
123 case TPI_INFO_VERSION_API:
\r
124 * (int *) _pPtr = 2;
\r
127 return TPI_ERROR_D_PARAMETER;
\r
129 return TPI_ERROR_SUCCESS;
\r
132 int __stdcall GetFormatInformation(TPI_FORMATINFO *, bool)
\r
134 return TPI_ERROR_D_UNSUPPORTED;
\r
137 int __stdcall LoadPlugin
\r
139 const wxString & _szArcName,
\r
140 wxULongLong _llSubOption
\r
144 wxString szSPIPath = wxPathOnly(p.GetExecutablePath()) + wxT("/lib/"), szSPIName;
\r
145 wxDir fs(szSPIPath);
\r
146 bool b = fs.GetFirst(& szSPIName, wxT("*.spi"));
\r
149 // SPI
\82ð
\83\8d\81[
\83h
\81B
\r
150 wxString szLibName = szSPIPath + szSPIName;
\r
151 g_hLib = ::LoadLibrary(szLibName.wchar_str());
\r
152 if (g_hLib == NULL)
\r
154 b = fs.GetNext(& szSPIName);
\r
158 // GetPluginInfo
\82ð
\8eÀ
\8ds
\81B
\r
159 FARPROC fpProc = ::GetProcAddress(g_hLib, "GetPluginInfo");
\r
160 char szPluginType[5]; //
\8eí
\97Þ4bytes + NULL
\r
162 || ((int (PASCAL *)(int, char *, int)) fpProc)(0, szPluginType, sizeof(szPluginType)) < 0
\r
163 || szPluginType[2] != 'I' || szPluginType[3] != 'N')
\r
165 ::FreeLibrary(g_hLib);
\r
166 b = fs.GetNext(& szSPIName);
\r
170 //
\8f\91\8cÉ
\82É
\91Î
\89\9e\82µ
\82Ä
\82¢
\82é
\82©
\83`
\83F
\83b
\83N
\81B
\r
171 if (CheckArchive(_szArcName, NULL) == TPI_ERROR_SUCCESS)
\r
173 //
\91Î
\89\9e\82µ
\82Ä
\82¢
\82ê
\82Î
\8f\88\97\9d\82ð
\8fI
\97¹
\81B
\r
174 return TPI_ERROR_SUCCESS;
\r
177 b = fs.GetNext(& szSPIName);
\r
179 return TPI_ERROR_U_LOAD_LIBRARY;
\r
182 int __stdcall FreePlugin
\r
184 void * // _pReserved
\r
187 ::FreeLibrary(g_hLib);
\r
188 return TPI_ERROR_SUCCESS;
\r
191 int __stdcall CheckArchive
\r
193 const wxString & _szArcName,
\r
197 FARPROC fpProc = ::GetProcAddress(g_hLib, "IsSupported");
\r
198 if (fpProc == NULL)
\r
200 return TPI_ERROR_U_USE_LIBRARY;
\r
203 wxFile hFile(_szArcName, wxFile::read);
\r
204 if (! hFile.IsOpened())
\r
206 return TPI_ERROR_IO_ARC_OPEN;
\r
210 ::ZeroMemory(buffer, sizeof(buffer));
\r
211 if (hFile.Read(buffer, sizeof(buffer)) == wxInvalidOffset)
\r
214 return TPI_ERROR_IO_ARC_READ;
\r
217 if (! ((BOOL (PASCAL *)(const char *, unsigned long)) fpProc)(_szArcName.ToUTF8(), (unsigned long) buffer))
\r
220 return TPI_ERROR_D_UNSUPPORTED;
\r
224 if (_nFileCount != NULL)
\r
229 return TPI_ERROR_SUCCESS;
\r
232 int __stdcall OpenArchive
\r
234 const wxString & _szArcName,
\r
238 g_szArcName = _szArcName;
\r
239 * _hArchive = & g_szArcName;
\r
240 return TPI_ERROR_SUCCESS;
\r
243 int __stdcall CloseArchive
\r
248 g_szArcName.Clear();
\r
249 return TPI_ERROR_SUCCESS;
\r
252 int __stdcall GetFileInformation
\r
255 TPI_FILEINFO * _fiInfo,
\r
261 return TPI_ERROR_S_ENDOFDATA;
\r
264 _fiInfo->fnFileName = wxFileName(* (wxString *) _hArchive);
\r
265 _fiInfo->fnFileName.SetVolume(wxEmptyString);
\r
266 _fiInfo->fnFileName.SetPath(wxEmptyString);
\r
267 _fiInfo->fnFileName.SetExt(wxT("bmp"));
\r
268 _fiInfo->szStoredName = _fiInfo->fnFileName.GetFullPath();
\r
270 return TPI_ERROR_SUCCESS;
\r
273 int __stdcall GetArchiveInformation
\r
276 TPI_ARCHIVEINFO * _aiInfo
\r
279 //
\89æ
\91\9c\82Ì
\8fî
\95ñ
\82ð
\8eæ
\93¾
\81B
\r
280 FARPROC fpProc = ::GetProcAddress(g_hLib, "GetPictureInfo");
\r
281 if (fpProc == NULL)
\r
283 return TPI_ERROR_U_USE_LIBRARY;
\r
285 PictureInfo piInfo;
\r
286 int nErrorCode = XpiErrorCodeConvert(((int (PASCAL *)(const char *, long, unsigned int, PictureInfo *)) fpProc)(((wxString *) _hArchive)->ToUTF8(), 0, 0, & piInfo));
\r
287 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
291 _aiInfo->szComment = MB2String((char *) ::LocalLock(piInfo.hInfo));
\r
292 ::LocalUnlock(piInfo.hInfo);
\r
293 ::LocalFree(piInfo.hInfo);
\r
295 // GetPluginInfo
\82ð
\8eÀ
\8ds
\81B
\r
296 fpProc = ::GetProcAddress(g_hLib, "GetPluginInfo");
\r
297 if (fpProc != NULL)
\r
300 if (((int (PASCAL *)(int, char *, int)) fpProc)(2, szTemp, sizeof(szTemp)) > 0)
\r
302 _aiInfo->fiInfo.szSuffix = MB2String(szTemp);
\r
304 if (((int (PASCAL *)(int, char *, int)) fpProc)(3, szTemp, sizeof(szTemp)) > 0)
\r
306 _aiInfo->fiInfo.szTypeName = MB2String(szTemp);
\r
309 _aiInfo->fiInfo.fArchive = false;
\r
310 _aiInfo->fiInfo.szTPIName = wxT("xpiLibrary");
\r
311 _aiInfo->fiInfo.llSupportedCommand = TPI_COMMAND_EXTRACT;
\r
313 return TPI_ERROR_SUCCESS;
\r
316 int __stdcall Command
\r
318 unsigned int _uCommand,
\r
319 TPI_SWITCHES * _swInfo,
\r
320 const wxString & _szArcName,
\r
321 const wxArrayString & _szFiles
\r
324 if (_uCommand != TPI_COMMAND_EXTRACT)
\r
326 return TPI_ERROR_D_UNSUPPORTED;
\r
329 //
\89æ
\91\9c\82Ì
\8fî
\95ñ
\82ð
\8eæ
\93¾
\81B
\r
330 FARPROC fpProc = ::GetProcAddress(g_hLib, "GetPictureInfo");
\r
331 if (fpProc == NULL)
\r
333 return TPI_ERROR_U_USE_LIBRARY;
\r
335 PictureInfo picInfo;
\r
336 int nErrorCode = XpiErrorCodeConvert(((int (PASCAL *)(const char *, long, unsigned int, PictureInfo *)) fpProc)(_szArcName.ToUTF8(), 0, 0, & picInfo));
\r
337 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
342 //
\93W
\8aJ
\8f\88\97\9d\82Ì
\82Ý
\82ð
\8ds
\82¤
\81B
\r
343 fpProc = ::GetProcAddress(g_hLib, "GetPicture");
\r
344 if (fpProc == NULL)
\r
346 return TPI_ERROR_U_USE_LIBRARY;
\r
349 //
\83R
\81[
\83\8b\83o
\83b
\83N
\82ð
\91\97\90M
\81B
\r
350 wxFileName _fnArcName(_szArcName);
\r
351 TPI_PROCESSINFO piInfo;
\r
352 piInfo.uMessage = TPI_MESSAGE_STATUS;
\r
353 piInfo.uStatus = TPI_STATUS_OPENARCHIVE;
\r
354 piInfo.fiInfo.fnFileName = _fnArcName;
\r
355 if (CallbackProc(0, 0, (long) & piInfo))
\r
357 return TPI_ERROR_D_SKIPPED;
\r
360 //
\83\81\83\82\83\8a\8fo
\97Í
\81B
\r
361 HANDLE hInfo, hMemory;
\r
362 //
\8fo
\97Í
\96¼
\8dì
\90¬
\81B
\r
363 piInfo.uStatus = TPI_STATUS_BEGINPROCESS;
\r
364 piInfo.fnDestination = _fnArcName;
\r
365 piInfo.fnDestination.SetPath(_swInfo->fnDestinationDirectory.GetPath());
\r
366 piInfo.fnDestination.SetExt(wxT("bmp"));
\r
367 piInfo.fiInfo.fnFileName = wxFileName(piInfo.fnDestination.GetFullName());
\r
368 if (CallbackProc(0, 0, (long) & piInfo))
\r
370 return TPI_ERROR_D_SKIPPED;
\r
372 piInfo.uStatus = TPI_STATUS_INPROCESS;
\r
373 nErrorCode = XpiErrorCodeConvert(((int (PASCAL *)(const char *, long, unsigned int, HANDLE *, HANDLE *, FARPROC, long)) fpProc)(_szArcName.ToUTF8(), 0, 0, & hInfo, & hMemory, (FARPROC) CallbackProc, (long) & piInfo));
\r
374 if (nErrorCode == TPI_ERROR_SUCCESS && (hMemory == NULL || hInfo == NULL))
\r
376 return TPI_ERROR_UNDEFINED;
\r
378 if (nErrorCode != TPI_ERROR_SUCCESS)
\r
383 // XPI
\82ð
\93Ç
\82Ý
\8d\9e\82Þ
\81B
\r
385 wxString szXPIPath = wxPathOnly(p.GetExecutablePath()) + wxT("/lib/exbmp.xpi");
\r
386 HMODULE hXPI = ::LoadLibrary(szXPIPath.wchar_str());
\r
389 return TPI_ERROR_U_USE_LIBRARY;
\r
392 //
\91Î
\89\9e\8am
\94F
\81B
\r
393 fpProc = ::GetProcAddress(hXPI, "IsSupported");
\r
394 if (fpProc == NULL)
\r
396 return TPI_ERROR_U_USE_LIBRARY;
\r
398 if (! XpiErrorCodeConvert(((BOOL (PASCAL *)(int)) fpProc)(picInfo.colorDepth)))
\r
400 return TPI_ERROR_ARC_UNSUPPORTED;
\r
403 //
\8f\91\82«
\8d\9e\82Ý
\81B
\r
404 fpProc = ::GetProcAddress(hXPI, "CreatePicture");
\r
405 if (fpProc == NULL)
\r
407 return TPI_ERROR_U_USE_LIBRARY;
\r
409 nErrorCode = XpiErrorCodeConvert(((int (PASCAL *)(const char *, long, HANDLE *, HANDLE *, PictureInfo *, FARPROC, long)) fpProc)(piInfo.fnDestination.GetFullPath().ToUTF8(), 0, & hInfo, & hMemory, & picInfo, (FARPROC) CallbackProc, (long) & piInfo));
\r
410 ::LocalUnlock(hInfo);
\r
411 ::LocalUnlock(hMemory);
\r
412 ::LocalFree(hInfo);
\r
413 ::LocalFree(hMemory);
\r
414 ::FreeLibrary(hXPI);
\r
416 //
\8dÅ
\8cã
\82É
\83R
\81[
\83\8b\83o
\83b
\83N
\82ð
\91\97\90M
\81B
\r
417 piInfo.uStatus = TPI_STATUS_ENDPROCESS;
\r
418 if (CallbackProc(0, 0, (long) & piInfo))
\r
420 return TPI_ERROR_D_SKIPPED;
\r
422 piInfo.uStatus = TPI_STATUS_CLOSEARCHIVE;
\r
423 piInfo.fiInfo.fnFileName = _fnArcName;
\r
424 if (CallbackProc(0, 0, (long) & piInfo))
\r
426 return TPI_ERROR_D_SKIPPED;
\r
432 int __stdcall SetCallbackProc
\r
434 TPI_PROC _prArcProc
\r
437 //
\83|
\83C
\83\93\83^
\82ð
\95Û
\91¶
\81B
\r
438 if (_prArcProc == NULL)
\r
440 return TPI_ERROR_D_PARAMETER;
\r
442 g_prProc = * _prArcProc;
\r
444 return TPI_ERROR_SUCCESS;
\r