OSDN Git Service

CallbackProcに関する変更。
[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->llProcessedSize       = _nNow;\r
67         piInfo->fiInfo.llUnpackedSize = _nMax;\r
68 \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
71 }\r
72 \r
73 //******************************************************************************\r
74 //    Inside Functions\r
75 //******************************************************************************\r
76 \r
77 int XpiErrorCodeConvert(int nXpiErrorCode)\r
78 {\r
79         switch (nXpiErrorCode)\r
80         {       \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
94         }\r
95 }\r
96 \r
97 //******************************************************************************\r
98 //    Functions\r
99 //******************************************************************************\r
100 \r
101 #ifdef __cplusplus\r
102 extern "C"\r
103 {\r
104 #endif\r
105 \r
106 int __stdcall GetPluginInformation\r
107 (\r
108         unsigned int _uInfoId,\r
109         wxULongLong,\r
110         void * _pPtr\r
111 )\r
112 {\r
113         if (_pPtr == NULL)\r
114         {\r
115                 return TPI_ERROR_D_PARAMETER;\r
116         }\r
117         switch (_uInfoId)\r
118         {\r
119         case TPI_INFO_VERSION_MAJOR:\r
120         case TPI_INFO_VERSION_MINOR:\r
121                 * (int *) _pPtr = 0;\r
122                 break;\r
123         case TPI_INFO_VERSION_API:\r
124                 * (int *) _pPtr = 2;\r
125                 break;\r
126         default:\r
127                 return TPI_ERROR_D_PARAMETER;\r
128         }\r
129         return TPI_ERROR_SUCCESS;\r
130 }\r
131 \r
132 int __stdcall GetFormatInformation(TPI_FORMATINFO *, bool)\r
133 {\r
134         return TPI_ERROR_D_UNSUPPORTED;\r
135 }\r
136 \r
137 int __stdcall LoadPlugin\r
138 (\r
139         const wxString & _szArcName,\r
140         wxULongLong _llSubOption\r
141 )\r
142 {\r
143         wxStandardPaths p;\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
147         while (b)\r
148         {\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
153                 {\r
154                         b = fs.GetNext(& szSPIName);\r
155                         continue;\r
156                 }\r
157 \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
161                 if (fpProc == NULL\r
162                         || ((int (PASCAL *)(int, char *, int)) fpProc)(0, szPluginType, sizeof(szPluginType)) < 0\r
163                         || szPluginType[2] != 'I' || szPluginType[3] != 'N')\r
164                 {\r
165                         ::FreeLibrary(g_hLib);\r
166                         b = fs.GetNext(& szSPIName);\r
167                         continue;\r
168                 }\r
169 \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
172                 {\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
175                 }\r
176 \r
177                 b = fs.GetNext(& szSPIName);\r
178         }\r
179         return TPI_ERROR_U_LOAD_LIBRARY;\r
180 }\r
181 \r
182 int __stdcall FreePlugin\r
183 (\r
184         void * // _pReserved\r
185 )\r
186 {\r
187         ::FreeLibrary(g_hLib);\r
188         return TPI_ERROR_SUCCESS;\r
189 }\r
190 \r
191 int __stdcall CheckArchive\r
192 (\r
193         const wxString & _szArcName,\r
194         int * _nFileCount\r
195 )\r
196 {\r
197         FARPROC fpProc = ::GetProcAddress(g_hLib, "IsSupported");\r
198         if (fpProc == NULL)\r
199         {\r
200                 return TPI_ERROR_U_USE_LIBRARY;\r
201         }\r
202 \r
203         wxFile hFile(_szArcName, wxFile::read);\r
204         if (! hFile.IsOpened())\r
205         {\r
206                 return TPI_ERROR_IO_ARC_OPEN;\r
207         }\r
208 \r
209         char buffer[2050];\r
210         ::ZeroMemory(buffer, sizeof(buffer));\r
211         if (hFile.Read(buffer, sizeof(buffer)) == wxInvalidOffset)\r
212         {\r
213                 hFile.Close();\r
214                 return TPI_ERROR_IO_ARC_READ;\r
215         }\r
216 \r
217         if (! ((BOOL (PASCAL *)(const char *, unsigned long)) fpProc)(_szArcName.ToUTF8(), (unsigned long) buffer))\r
218         {\r
219                 hFile.Close();\r
220                 return TPI_ERROR_D_UNSUPPORTED;\r
221         }\r
222         hFile.Close();\r
223 \r
224         if (_nFileCount != NULL)\r
225         {\r
226                 * _nFileCount = 1;\r
227         }\r
228 \r
229         return TPI_ERROR_SUCCESS;\r
230 }\r
231 \r
232 int __stdcall OpenArchive\r
233 (\r
234         const wxString & _szArcName,\r
235         void * * _hArchive\r
236 )\r
237 {\r
238         g_szArcName = _szArcName;\r
239         * _hArchive = & g_szArcName;\r
240         return TPI_ERROR_SUCCESS;\r
241 }\r
242 \r
243 int __stdcall CloseArchive\r
244 (\r
245         void * _hArchive\r
246 )\r
247 {\r
248         g_szArcName.Clear();\r
249         return TPI_ERROR_SUCCESS;\r
250 }\r
251 \r
252 int __stdcall GetFileInformation\r
253 (\r
254         void * _hArchive,\r
255         TPI_FILEINFO * _fiInfo,\r
256         bool _bFirst\r
257 )\r
258 {\r
259         if (! _bFirst)\r
260         {\r
261                 return TPI_ERROR_S_ENDOFDATA;\r
262         }\r
263 \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
269 \r
270         return TPI_ERROR_SUCCESS;\r
271 }\r
272 \r
273 int __stdcall GetArchiveInformation\r
274 (\r
275         void * _hArchive,\r
276         TPI_ARCHIVEINFO * _aiInfo\r
277 )\r
278 {\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
282         {\r
283                 return TPI_ERROR_U_USE_LIBRARY;\r
284         }\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
288         {\r
289                 return nErrorCode;\r
290         }\r
291         _aiInfo->szComment = MB2String((char *) ::LocalLock(piInfo.hInfo));\r
292         ::LocalUnlock(piInfo.hInfo);\r
293         ::LocalFree(piInfo.hInfo);\r
294 \r
295         // GetPluginInfo\82ð\8eÀ\8ds\81B\r
296         fpProc = ::GetProcAddress(g_hLib, "GetPluginInfo");\r
297         if (fpProc != NULL)\r
298         {\r
299                 char szTemp[20];\r
300                 if (((int (PASCAL *)(int, char *, int)) fpProc)(2, szTemp, sizeof(szTemp)) > 0)\r
301                 {\r
302                         _aiInfo->fiInfo.szSuffix = MB2String(szTemp);\r
303                 }\r
304                 if (((int (PASCAL *)(int, char *, int)) fpProc)(3, szTemp, sizeof(szTemp)) > 0)\r
305                 {\r
306                         _aiInfo->fiInfo.szTypeName = MB2String(szTemp);\r
307                 }\r
308         }\r
309         _aiInfo->fiInfo.fArchive = false;\r
310         _aiInfo->fiInfo.szTPIName = wxT("xpiLibrary");\r
311         _aiInfo->fiInfo.llSupportedCommand = TPI_COMMAND_EXTRACT;\r
312 \r
313         return TPI_ERROR_SUCCESS;\r
314 }\r
315 \r
316 int __stdcall Command\r
317 (\r
318         unsigned int _uCommand,\r
319         TPI_SWITCHES * _swInfo,\r
320         const wxString & _szArcName,\r
321         const wxArrayString & _szFiles\r
322 )\r
323 {\r
324         if (_uCommand != TPI_COMMAND_EXTRACT)\r
325         {\r
326                 return TPI_ERROR_D_UNSUPPORTED;\r
327         }\r
328 \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
332         {\r
333                 return TPI_ERROR_U_USE_LIBRARY;\r
334         }\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
338         {\r
339                 return nErrorCode;\r
340         }\r
341 \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
345         {\r
346                 return TPI_ERROR_U_USE_LIBRARY;\r
347         }\r
348 \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
356         {\r
357                 return TPI_ERROR_D_SKIPPED;\r
358         }\r
359 \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
369         {\r
370                 return TPI_ERROR_D_SKIPPED;\r
371         }\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
375         {\r
376                 return TPI_ERROR_UNDEFINED;\r
377         }\r
378         if (nErrorCode != TPI_ERROR_SUCCESS)\r
379         {\r
380                 return nErrorCode;\r
381         }\r
382 \r
383         // XPI\82ð\93Ç\82Ý\8d\9e\82Þ\81B\r
384         wxStandardPaths p;\r
385         wxString szXPIPath = wxPathOnly(p.GetExecutablePath()) + wxT("/lib/exbmp.xpi");\r
386         HMODULE hXPI = ::LoadLibrary(szXPIPath.wchar_str());\r
387         if (hXPI == NULL)\r
388         {\r
389                 return TPI_ERROR_U_USE_LIBRARY;\r
390         }\r
391 \r
392         // \91Î\89\9e\8am\94F\81B\r
393         fpProc = ::GetProcAddress(hXPI, "IsSupported");\r
394         if (fpProc == NULL)\r
395         {\r
396                 return TPI_ERROR_U_USE_LIBRARY;\r
397         }\r
398         if (! XpiErrorCodeConvert(((BOOL (PASCAL *)(int)) fpProc)(picInfo.colorDepth)))\r
399         {\r
400                 return TPI_ERROR_ARC_UNSUPPORTED;\r
401         }\r
402 \r
403         // \8f\91\82«\8d\9e\82Ý\81B\r
404         fpProc = ::GetProcAddress(hXPI, "CreatePicture");\r
405         if (fpProc == NULL)\r
406         {\r
407                 return TPI_ERROR_U_USE_LIBRARY;\r
408         }\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
415 \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
419         {\r
420                 return TPI_ERROR_D_SKIPPED;\r
421         }\r
422         piInfo.uStatus  = TPI_STATUS_CLOSEARCHIVE;\r
423         piInfo.fiInfo.fnFileName = _fnArcName;\r
424         if (CallbackProc(0, 0, (long) & piInfo))\r
425         {\r
426                 return TPI_ERROR_D_SKIPPED;\r
427         }\r
428 \r
429         return nErrorCode;\r
430 }\r
431 \r
432 int __stdcall SetCallbackProc\r
433 (\r
434         TPI_PROC _prArcProc\r
435 )\r
436 {\r
437         // \83|\83C\83\93\83^\82ð\95Û\91\81B\r
438         if (_prArcProc == NULL)\r
439         {\r
440                 return TPI_ERROR_D_PARAMETER;\r
441         }\r
442         g_prProc = * _prArcProc;\r
443 \r
444         return TPI_ERROR_SUCCESS;\r
445 }\r
446 \r
447 #ifdef __cplusplus\r
448 }\r
449 #endif\r