OSDN Git Service

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