OSDN Git Service

xpiLibraryを追加。
[tpi/lychee.git] / src / plugin / xpiLibrary / xpiLibrary.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 #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
31 #include <wx/dir.h>\r
32 #include <windows.h>\r
33 #include "xpiLibrary.h"\r
34 \r
35 //******************************************************************************\r
36 //    Global varients\r
37 //******************************************************************************\r
38 \r
39 HMODULE g_hLib;\r
40 TPI_PROC g_prProc;\r
41 wxString g_szArcName;\r
42 \r
43 //******************************************************************************\r
44 //    Entry\r
45 //******************************************************************************\r
46 \r
47 BOOL __stdcall DllMain(HMODULE, DWORD fdwReason, void *)\r
48 {\r
49         switch (fdwReason)\r
50         {\r
51         case DLL_PROCESS_DETACH:\r
52                 ::FreeLibrary(g_hLib);\r
53                 break;\r
54         }\r
55         return TRUE;\r
56 }\r
57 \r
58 //******************************************************************************\r
59 //    Callback Wrapper\r
60 //******************************************************************************\r
61 \r
62 int __stdcall CallbackProc(int _nNow, int _nMax, long _lData)\r
63 {\r
64         // \8d\\91¢\91Ì\82ð\8f\89\8aú\89»\81B\r
65         TPI_PROCESSINFO piInfo;\r
66         piInfo.uMessage = TPI_MESSAGE_STATUS;\r
67         piInfo.uStatus  = _nNow == 0     ? TPI_STATUS_BEGINPROCESS\r
68                                         : _nNow == _nMax ? TPI_STATUS_ENDPROCESS\r
69                                         : _nNow <  0     ? TPI_STATUS_OPENARCHIVE : TPI_STATUS_INPROCESS;\r
70         piInfo.llProcessedSize       = _nNow;\r
71         piInfo.fiInfo.llUnpackedSize = _nMax;\r
72 //      piInfo.fiInfo.fnFileName = * (wxFileName *) _lData;\r
73 \r
74         // \83R\81[\83\8b\83o\83b\83N\8aÖ\90\94\82É\91\97\90M\81B\r
75         return g_prProc != NULL && g_prProc(TPI_NOTIFY_COMMON, & piInfo) == TPI_CALLBACK_CANCEL;\r
76 }\r
77 \r
78 //******************************************************************************\r
79 //    Inside Functions\r
80 //******************************************************************************\r
81 \r
82 int XpiErrorCodeConvert(int nXpiErrorCode)\r
83 {\r
84         switch (nXpiErrorCode)\r
85         {       \r
86         case -1:case XPI_NO_FUNCTION:       return TPI_ERROR_U_USE_LIBRARY;\r
87         case 0:                             return TPI_ERROR_SUCCESS;\r
88         case 1: case XPI_ABORT:             return TPI_ERROR_D_SKIPPED;\r
89         case 2: case XPI_NOT_SUPPRORT:      return TPI_ERROR_ARC_UNSUPPORTED;\r
90         case 3: case XPI_OUT_OF_ORDER:      return TPI_ERROR_ARC_BROKEN_MISC;\r
91         case 4: case XPI_NO_MEMORY:         return TPI_ERROR_D_OUTOFMEMORY;\r
92         case 5: case XPI_MEMORY_ERROR:      return TPI_ERROR_D_USEMEMORY;\r
93         case 6: case XPI_FILE_READ_ERROR:   return TPI_ERROR_IO_ARC_READ;\r
94                         case XPI_OTHER_ERROR:           return TPI_ERROR_UNDEFINED;\r
95                         case XPI_WINDOW_ERROR:      return TPI_ERROR_UNDEFINED;\r
96                         case XPI_FILE_WRITE_ERROR:  return TPI_ERROR_IO_FILE_WRITE;\r
97                         case XPI_END_OF_FILE:       return TPI_ERROR_ARC_BROKEN_MISC;\r
98         default:                            return TPI_ERROR_UNDEFINED;\r
99         }\r
100 }\r
101 \r
102 //******************************************************************************\r
103 //    Functions\r
104 //******************************************************************************\r
105 \r
106 #ifdef __cplusplus\r
107 extern "C"\r
108 {\r
109 #endif\r
110 \r
111 int __stdcall GetPluginInformation\r
112 (\r
113         unsigned int _uInfoId,\r
114         wxULongLong,\r
115         void * _pPtr\r
116 )\r
117 {\r
118         if (_pPtr == NULL)\r
119         {\r
120                 return TPI_ERROR_D_PARAMETER;\r
121         }\r
122         switch (_uInfoId)\r
123         {\r
124         case TPI_INFO_VERSION_MAJOR:\r
125         case TPI_INFO_VERSION_MINOR:\r
126                 * (int *) _pPtr = 0;\r
127                 break;\r
128         case TPI_INFO_VERSION_API:\r
129                 * (int *) _pPtr = 2;\r
130                 break;\r
131         default:\r
132                 return TPI_ERROR_D_PARAMETER;\r
133         }\r
134         return TPI_ERROR_SUCCESS;\r
135 }\r
136 \r
137 int __stdcall GetFormatInformation(TPI_FORMATINFO *, bool)\r
138 {\r
139         return TPI_ERROR_D_UNSUPPORTED;\r
140 }\r
141 \r
142 int __stdcall LoadPlugin\r
143 (\r
144         const wxString & _szArcName,\r
145         wxULongLong _llSubOption\r
146 )\r
147 {\r
148         wxStandardPaths p;\r
149         wxString szSPIPath = wxPathOnly(p.GetExecutablePath()) + wxT("/lib/"), szSPIName;\r
150         wxDir fs(szSPIPath);\r
151 \r
152         bool b = fs.GetFirst(& szSPIName, wxT("*.spi"));\r
153         while (b)\r
154         {\r
155                 // SPI\82ð\83\8d\81[\83h\81B\r
156                 wxString szLibName = szSPIPath + szSPIName;\r
157                 g_hLib = ::LoadLibrary(szLibName.wchar_str());\r
158                 if (g_hLib == NULL)\r
159                 {\r
160                         b = fs.GetNext(& szSPIName);\r
161                         continue;\r
162                 }\r
163 \r
164                 // GetPluginInfo\82ð\8eÀ\8ds\81B\r
165                 FARPROC fpProc = ::GetProcAddress(g_hLib, "GetPluginInfo");\r
166                 char szPluginType[5]; // \8eí\97Þ4bytes + NULL\r
167                 if (fpProc == NULL\r
168                         || ((int (PASCAL *)(int, char *, int)) fpProc)(0, szPluginType, sizeof(szPluginType)) < 0\r
169                         || szPluginType[2] != 'I' || szPluginType[3] != 'N')\r
170                 {\r
171                         ::FreeLibrary(g_hLib);\r
172                         b = fs.GetNext(& szSPIName);\r
173                         continue;\r
174                 }\r
175 \r
176                 // \8f\91\8cÉ\82É\91Î\89\9e\82µ\82Ä\82¢\82é\82©\83`\83F\83b\83N\81B\r
177                 if (CheckArchive(_szArcName, NULL) == TPI_ERROR_SUCCESS)\r
178                 {\r
179                         // \91Î\89\9e\82µ\82Ä\82¢\82ê\82Î\8f\88\97\9d\82ð\8fI\97¹\81B\r
180                         return TPI_ERROR_SUCCESS;\r
181                 }\r
182 \r
183                 b = fs.GetNext(& szSPIName);\r
184         }\r
185         return TPI_ERROR_U_LOAD_LIBRARY;\r
186 }\r
187 \r
188 int __stdcall FreePlugin\r
189 (\r
190         void * // _pReserved\r
191 )\r
192 {\r
193         ::FreeLibrary(g_hLib);\r
194         return TPI_ERROR_SUCCESS;\r
195 }\r
196 \r
197 int __stdcall CheckArchive\r
198 (\r
199         const wxString & _szArcName,\r
200         int * _nFileCount\r
201 )\r
202 {\r
203         FARPROC fpProc = ::GetProcAddress(g_hLib, "IsSupported");\r
204         if (fpProc == NULL)\r
205         {\r
206                 return TPI_ERROR_U_USE_LIBRARY;\r
207         }\r
208 \r
209         wxFile hFile(_szArcName, wxFile::read);\r
210         if (! hFile.IsOpened())\r
211         {\r
212                 return TPI_ERROR_IO_ARC_OPEN;\r
213         }\r
214 \r
215         char buffer[2050];\r
216         ::ZeroMemory(buffer, sizeof(buffer));\r
217         if (hFile.Read(buffer, sizeof(buffer)) == wxInvalidOffset)\r
218         {\r
219                 hFile.Close();\r
220                 return TPI_ERROR_IO_ARC_READ;\r
221         }\r
222 \r
223         if (! ((BOOL (PASCAL *)(const char *, unsigned long)) fpProc)(_szArcName.ToUTF8(), (unsigned long) buffer))\r
224         {\r
225                 hFile.Close();\r
226                 return TPI_ERROR_D_UNSUPPORTED;\r
227         }\r
228         hFile.Close();\r
229 \r
230         if (_nFileCount != NULL)\r
231         {\r
232                 * _nFileCount = 1;\r
233         }\r
234 \r
235         return TPI_ERROR_SUCCESS;\r
236 }\r
237 \r
238 int __stdcall OpenArchive\r
239 (\r
240         const wxString & _szArcName,\r
241         void * * _hArchive\r
242 )\r
243 {\r
244         g_szArcName = _szArcName;\r
245         * _hArchive = & g_szArcName;\r
246         return TPI_ERROR_SUCCESS;\r
247 }\r
248 \r
249 int __stdcall CloseArchive\r
250 (\r
251         void * _hArchive\r
252 )\r
253 {\r
254         g_szArcName.Clear();\r
255         return TPI_ERROR_SUCCESS;\r
256 }\r
257 \r
258 int __stdcall GetFileInformation\r
259 (\r
260         void * _hArchive,\r
261         TPI_FILEINFO * _fiInfo,\r
262         bool _bFirst\r
263 )\r
264 {\r
265         if (! _bFirst)\r
266         {\r
267                 return TPI_ERROR_S_ENDOFDATA;\r
268         }\r
269 \r
270         _fiInfo->fnFileName     = wxFileName(* (wxString *) _hArchive);\r
271         _fiInfo->fnFileName.SetVolume(wxEmptyString);\r
272         _fiInfo->fnFileName.SetPath(wxEmptyString);\r
273         _fiInfo->fnFileName.SetExt(wxT("bmp"));\r
274         _fiInfo->szStoredName   = _fiInfo->fnFileName.GetFullPath();\r
275 \r
276         return TPI_ERROR_SUCCESS;\r
277 }\r
278 \r
279 int __stdcall GetArchiveInformation\r
280 (\r
281         void * _hArchive,\r
282         TPI_ARCHIVEINFO * _aiInfo\r
283 )\r
284 {\r
285         // \89æ\91\9c\82Ì\8fî\95ñ\82ð\8eæ\93¾\81B\r
286         FARPROC fpProc = ::GetProcAddress(g_hLib, "GetPictureInfo");\r
287         if (fpProc == NULL)\r
288         {\r
289                 return TPI_ERROR_U_USE_LIBRARY;\r
290         }\r
291         PictureInfo piInfo;\r
292         int nErrorCode = XpiErrorCodeConvert(((int (PASCAL *)(const char *, long, unsigned int, PictureInfo *)) fpProc)(((wxString *) _hArchive)->ToUTF8(), 0, 0, & piInfo));\r
293         if (nErrorCode != TPI_ERROR_SUCCESS)\r
294         {\r
295                 return nErrorCode;\r
296         }\r
297         _aiInfo->szComment = MB2String((char *) ::LocalLock(piInfo.hInfo));\r
298         ::LocalUnlock(piInfo.hInfo);\r
299         ::LocalFree(piInfo.hInfo);\r
300 \r
301         // GetPluginInfo\82ð\8eÀ\8ds\81B\r
302         fpProc = ::GetProcAddress(g_hLib, "GetPluginInfo");\r
303         if (fpProc != NULL)\r
304         {\r
305                 char szTemp[20];\r
306                 if (((int (PASCAL *)(int, char *, int)) fpProc)(2, szTemp, sizeof(szTemp)) > 0)\r
307                 {\r
308                         _aiInfo->fiInfo.szSuffix = MB2String(szTemp);\r
309                 }\r
310                 if (((int (PASCAL *)(int, char *, int)) fpProc)(3, szTemp, sizeof(szTemp)) > 0)\r
311                 {\r
312                         _aiInfo->fiInfo.szTypeName = MB2String(szTemp);\r
313                 }\r
314         }\r
315         _aiInfo->fiInfo.fArchive = false;\r
316         _aiInfo->fiInfo.szTPIName = wxT("xpiLibrary");\r
317         _aiInfo->fiInfo.llSupportedCommand = TPI_COMMAND_EXTRACT;\r
318 \r
319         return TPI_ERROR_SUCCESS;\r
320 }\r
321 \r
322 int __stdcall Command\r
323 (\r
324         unsigned int _uCommand,\r
325         TPI_SWITCHES * _swInfo,\r
326         const wxString & _szArcName,\r
327         const wxArrayString & _szFiles\r
328 )\r
329 {\r
330         if (_uCommand != TPI_COMMAND_EXTRACT)\r
331         {\r
332                 return TPI_ERROR_D_UNSUPPORTED;\r
333         }\r
334 \r
335         // \89æ\91\9c\82Ì\8fî\95ñ\82ð\8eæ\93¾\81B\r
336         FARPROC fpProc = ::GetProcAddress(g_hLib, "GetPictureInfo");\r
337         if (fpProc == NULL)\r
338         {\r
339                 return TPI_ERROR_U_USE_LIBRARY;\r
340         }\r
341         PictureInfo piInfo;\r
342         int nErrorCode = XpiErrorCodeConvert(((int (PASCAL *)(const char *, long, unsigned int, PictureInfo *)) fpProc)(_szArcName.ToUTF8(), 0, 0, & piInfo));\r
343         if (nErrorCode != TPI_ERROR_SUCCESS)\r
344         {\r
345                 return nErrorCode;\r
346         }\r
347 \r
348         // \93W\8aJ\8f\88\97\9d\82Ì\82Ý\82ð\8ds\82¤\81B\r
349         fpProc = ::GetProcAddress(g_hLib, "GetPicture");\r
350         if (fpProc == NULL)\r
351         {\r
352                 return TPI_ERROR_U_USE_LIBRARY;\r
353         }\r
354 \r
355         // \83R\81[\83\8b\83o\83b\83N\82ð\91\97\90M\81B\95Ö\8bX\8fã-1\82ð\91\97\90M\81B\r
356         wxFileName _fnArcName(_szArcName);\r
357         if (CallbackProc(-1, 0, (long) & _fnArcName))\r
358         {\r
359                 return TPI_ERROR_D_SKIPPED;\r
360         }\r
361 \r
362         // \83\81\83\82\83\8a\8fo\97Í\81B\r
363         HANDLE hInfo, hMemory;\r
364         nErrorCode = XpiErrorCodeConvert(((int (PASCAL *)(const char *, long, unsigned int, HANDLE *, HANDLE *, FARPROC, long)) fpProc)(_szArcName.ToUTF8(), 0, 0, & hInfo, & hMemory, (FARPROC) CallbackProc, 0));\r
365         if (nErrorCode == TPI_ERROR_SUCCESS && (hMemory == NULL || hInfo == NULL))\r
366         {\r
367                 return TPI_ERROR_UNDEFINED;\r
368         }\r
369         if (nErrorCode != TPI_ERROR_SUCCESS)\r
370         {\r
371                 return nErrorCode;\r
372         }\r
373 \r
374         // XPI\82ð\93Ç\82Ý\8d\9e\82Þ\81B\r
375         wxStandardPaths p;\r
376         wxString szXPIPath = wxPathOnly(p.GetExecutablePath()) + wxT("/lib/exbmp.xpi");\r
377         HMODULE hXPI = ::LoadLibrary(szXPIPath.wchar_str());\r
378         if (hXPI == NULL)\r
379         {\r
380                 return TPI_ERROR_U_USE_LIBRARY;\r
381         }\r
382 \r
383         // \91Î\89\9e\8am\94F\81B\r
384         fpProc = ::GetProcAddress(hXPI, "IsSupported");\r
385         if (fpProc == NULL)\r
386         {\r
387                 return TPI_ERROR_U_USE_LIBRARY;\r
388         }\r
389         if (! XpiErrorCodeConvert(((BOOL (PASCAL *)(int)) fpProc)(piInfo.colorDepth)))\r
390         {\r
391                 return TPI_ERROR_ARC_UNSUPPORTED;\r
392         }\r
393 \r
394         // \8fo\97Í\96¼\8dì\90¬\81B\r
395         wxString szTargetPath = _swInfo->fnDestinationDirectory.GetPathWithSep() + _fnArcName.GetName() + wxT(".bmp");\r
396 \r
397         // \8f\91\82«\8d\9e\82Ý\81B\r
398         fpProc = ::GetProcAddress(hXPI, "CreatePicture");\r
399         if (fpProc == NULL)\r
400         {\r
401                 return TPI_ERROR_U_USE_LIBRARY;\r
402         }\r
403         nErrorCode = XpiErrorCodeConvert(((int (PASCAL *)(const char *, long, HANDLE *, HANDLE *, PictureInfo *, FARPROC, long)) fpProc)(szTargetPath.ToUTF8(), 0, & hInfo, & hMemory, & piInfo, (FARPROC) CallbackProc, 0));\r
404         ::LocalUnlock(hInfo);\r
405         ::LocalUnlock(hMemory);\r
406         ::LocalFree(hInfo);\r
407         ::LocalFree(hMemory);\r
408         ::FreeLibrary(hXPI);\r
409 \r
410         return nErrorCode;\r
411 }\r
412 \r
413 int __stdcall SetCallbackProc\r
414 (\r
415         TPI_PROC _prArcProc\r
416 )\r
417 {\r
418         // \83|\83C\83\93\83^\82ð\95Û\91\81B\r
419         if (_prArcProc == NULL)\r
420         {\r
421                 return TPI_ERROR_D_PARAMETER;\r
422         }\r
423         g_prProc = * _prArcProc;\r
424 \r
425         return TPI_ERROR_SUCCESS;\r
426 }\r
427 \r
428 #ifdef __cplusplus\r
429 }\r
430 #endif\r