source: trunk/Lucide/SOURCE/gui/pluginman.cpp@ 238

Last change on this file since 238 was 238, checked in by Eugene Romanenko, 18 years ago

fix for ticket #86, testing needed

File size: 9.6 KB
Line 
1/* ***** BEGIN LICENSE BLOCK *****
2 * Version: CDDL 1.0/LGPL 2.1
3 *
4 * The contents of this file are subject to the COMMON DEVELOPMENT AND
5 * DISTRIBUTION LICENSE (CDDL) Version 1.0 (the "License"); you may not use
6 * this file except in compliance with the License. You may obtain a copy of
7 * the License at http://www.sun.com/cddl/
8 *
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
13 *
14 * The Initial Developer of the Original Code is
15 * Eugene Romanenko, netlabs.org.
16 * Portions created by the Initial Developer are Copyright (C) 2006
17 * the Initial Developer. All Rights Reserved.
18 *
19 * Contributor(s):
20 *
21 * Alternatively, the contents of this file may be used under the terms of
22 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
23 * in which case the provisions of the LGPL are applicable instead of those
24 * above. If you wish to allow use of your version of this file only under the
25 * terms of the LGPL, and not to allow others to use your version of this file
26 * under the terms of the CDDL, indicate your decision by deleting the
27 * provisions above and replace them with the notice and other provisions
28 * required by the LGPL. If you do not delete the provisions above, a recipient
29 * may use your version of this file under the terms of any one of the CDDL
30 * or the LGPL.
31 *
32 * ***** END LICENSE BLOCK ***** */
33
34
35#define INCL_DOS
36#include <os2.h>
37
38#include "pluginman.h"
39#include "luutils.h"
40#include <dos.h>
41#include <fcntl.h>
42#include <stdio.h>
43#include <ludoc.xh>
44
45
46PluginManager::PluginManager()
47{
48 plugins = new PluginInfoList;
49
50 // Find exe path
51 char buffer[ _MAX_PATH ];
52 char path[ _MAX_PATH ];
53 char drive[ _MAX_DRIVE ];
54 char dir[ _MAX_DIR ];
55 _splitpath( __argv[0], drive, dir, NULL, NULL );
56 _makepath( path, drive, dir, NULL, NULL );
57 strcpy( buffer, path );
58 strcat( buffer, "LU*.DLL" );
59
60 // enum plugins, (LU*.DLL) except for LUDOC.DLL, which is 'null' plugin
61 // and Lucide.dll, which is not a plugin.
62 struct find_t ffblk;
63 unsigned done = _dos_findfirst( buffer, _A_RDONLY | _A_NORMAL, &ffblk );
64 while ( done == 0 )
65 {
66 if ( ( stricmp( ffblk.name, "LUDOC.DLL" ) != 0 ) &&
67 ( stricmp( ffblk.name, "LUCIDE.DLL" ) != 0 ) )
68 {
69 loadPlugin( path, ffblk.name );
70 }
71 done = _dos_findnext( &ffblk );
72 }
73 _dos_findclose( &ffblk );
74}
75
76PluginManager::~PluginManager()
77{
78 for ( int i = 0; i < plugins->size(); i++ )
79 {
80 PluginInfo *pi = &(*plugins)[ i ];
81 DosFreeModule( pi->handle );
82 //printf( "NAME: %s EXT: %s DESC: %s\n", pi->name.c_str(),
83 // pi->extensions.c_str(), pi->description.c_str() );
84 }
85 delete plugins;
86}
87
88void PluginManager::loadPlugin( const char *path, const char *dllname )
89{
90 // Function pointer variables
91 LuDocument * APIENTRY (*pCreateObject)() = NULL;
92 char * APIENTRY (*pGetSupportedExtensions)() = NULL;
93 char * APIENTRY (*pGetDescription)() = NULL;
94 LuSignatureCheck * APIENTRY (*pGetSignatureCheck)() = NULL;
95
96 std::string fulldllname = path;
97 fulldllname += dllname;
98
99 // cut DLL name at last point
100 char *lpoint = strrchr( dllname, '.' );
101 *lpoint = '\0';
102
103 // load a DLL
104 HMODULE h = NULLHANDLE;
105 bool res = false;
106 do
107 {
108 if ( DosLoadModule( NULL, 0, fulldllname.c_str(), &h ) != 0 )
109 break;
110 if ( DosQueryProcAddr( h, 0, "createObject", (PFN *)&pCreateObject ) != 0 )
111 break;
112 if ( DosQueryProcAddr( h, 0, "getSupportedExtensions", (PFN *)&pGetSupportedExtensions ) != 0 )
113 break;
114 if ( DosQueryProcAddr( h, 0, "getDescription", (PFN *)&pGetDescription ) != 0 )
115 break;
116
117 // optional
118 if ( DosQueryProcAddr( h, 0, "getSignatureCheck", (PFN *)&pGetSignatureCheck ) != 0 ) {
119 pGetSignatureCheck = NULL;
120 }
121
122 res = true;
123 } while (0);
124
125 if ( res )
126 {
127 PluginInfo pi;
128 pi.handle = h;
129 pi.name = dllname;
130 pi.extensions = pGetSupportedExtensions();
131 pi.description = pGetDescription();
132 pi.signatures = ( pGetSignatureCheck == NULL ) ? NULL : pGetSignatureCheck();
133
134 plugins->push_back( pi );
135 }
136}
137
138static LuDocument *createDocFromDll( HMODULE handle, bool checkOnly )
139{
140 LuDocument * APIENTRY (*pCreateObject)() = NULL;
141
142 if ( DosQueryProcAddr( handle, 0, "createObject", (PFN *)&pCreateObject ) == 0 )
143 {
144 if ( checkOnly ) {
145 return (LuDocument *)TRUE;
146 }
147 else {
148 return pCreateObject();
149 }
150 }
151
152 return NULL;
153}
154
155// returns NULL if no suitable plugin found
156// if checkOnly is true - just check if suitable plugin exist
157LuDocument *PluginManager::createDocumentForExt( const char *ext, bool checkOnly )
158{
159 if ( ext == NULL ) {
160 return NULL;
161 }
162
163 for ( int i = 0; i < plugins->size(); i++ )
164 {
165 PluginInfo *pi = &(*plugins)[ i ];
166
167 char *cExt = new char[ strlen( ext ) + 5 ];
168 strcpy( cExt, ";" );
169 strcat( cExt, ext );
170 strcat( cExt, ";" );
171 strupr( cExt );
172
173 char *cExts = new char[ pi->extensions.length() + 5 ];
174 strcpy( cExts, ";" );
175 strcat( cExts, pi->extensions.c_str() );
176 strcat( cExts, ";" );
177 strupr( cExts );
178
179 if ( strstr( cExts, cExt ) != NULL )
180 {
181 LuDocument *d = createDocFromDll( pi->handle, checkOnly );
182 if ( d != NULL )
183 {
184 delete cExt;
185 delete cExts;
186 return d;
187 }
188 }
189
190 delete cExt;
191 delete cExts;
192 }
193
194 return NULL;
195}
196
197static bool checkSignature( LuSignature *signature, int h )
198{
199 lseek( h, signature->offset, ( signature->origin == 0 ) ? SEEK_SET : SEEK_END );
200 unsigned char *buf = new char[ signature->length ];
201 read( h, buf, signature->length );
202 bool result = ( memcmp( signature->data, buf, signature->length ) == 0 );
203 delete buf;
204 return result;
205}
206
207static bool checkSignatureList( LuSignatureList *siglist, int h )
208{
209 bool result = true;
210
211 // all signatures must be checked for positive result
212 for ( unsigned long i = 0; i < siglist->count; i++ )
213 {
214 if ( !checkSignature( &(siglist->signatures[ i ]), h ) ) {
215 result = false;
216 break;
217 }
218 }
219
220 return result;
221}
222
223static bool checkSignatures( LuSignatureCheck *signatures, const char *file )
224{
225 int h = open( file, O_RDONLY | O_BINARY );
226
227 if ( h == -1 ) {
228 return false;
229 }
230
231 bool result = false;
232
233 // if one signature list checked - result is positive
234 for ( unsigned long i = 0; i < signatures->count; i++ )
235 {
236 if ( result = checkSignatureList( &(signatures->slists[ i ]), h ) ) {
237 break;
238 }
239 }
240 close( h );
241
242 return result;
243}
244
245// returns NULL if no suitable plugin found
246// if checkOnly is true - just check if suitable plugin exist
247LuDocument *PluginManager::createDocumentForFile( const char *file, bool checkOnly )
248{
249 LuDocument *ld = NULL;
250
251 // Search by extension
252 char *ext = strrchr( file, '.' );
253 if ( ext != NULL ) {
254 ld = createDocumentForExt( ext + 1, checkOnly );
255 }
256
257 if ( ld != NULL ) {
258 return ld;
259 }
260
261 // Search by checkstruct
262 for ( int i = 0; i < plugins->size(); i++ )
263 {
264 PluginInfo *pi = &(*plugins)[ i ];
265
266 if ( pi->signatures != NULL )
267 {
268 if ( checkSignatures( pi->signatures, file ) )
269 {
270 LuDocument *d = createDocFromDll( pi->handle, checkOnly );
271 if ( d != NULL ) {
272 return d;
273 }
274 }
275 }
276 }
277
278
279 // Search by isFileSupported()
280 BOOL APIENTRY (*pIsFileSupported)(PCSZ) = NULL;
281
282 for ( int i = 0; i < plugins->size(); i++ )
283 {
284 PluginInfo *pi = &(*plugins)[ i ];
285
286 if ( DosQueryProcAddr( pi->handle, 0, "isFileSupported",
287 (PFN *)&pIsFileSupported ) == 0 )
288 {
289 if ( pIsFileSupported( file ) )
290 {
291 LuDocument *d = createDocFromDll( pi->handle, checkOnly );
292 if ( d != NULL ) {
293 return d;
294 }
295 }
296 }
297 }
298
299 return NULL;
300}
301
302std::string PluginManager::getExtsMask()
303{
304 std::string cRet = "";
305
306 for ( int i = 0; i < plugins->size(); i++ )
307 {
308 PluginInfo *pi = &(*plugins)[ i ];
309 char *tmpexts = newstrdup( pi->extensions.c_str() );
310 char *p = strtok( tmpexts, ";" );
311 while ( p != NULL ) {
312 cRet += "*.";
313 cRet += p;
314 cRet += ';';
315 p = strtok( NULL, ";" );
316 }
317 delete tmpexts;
318 }
319 return cRet;
320}
321
322void PluginManager::getExtsList( std::vector<std::string> *list )
323{
324 for ( int i = 0; i < plugins->size(); i++ )
325 {
326 PluginInfo *pi = &(*plugins)[ i ];
327 char *tmpexts = newstrdup( pi->extensions.c_str() );
328 char *p = strtok( tmpexts, ";" );
329 while ( p != NULL ) {
330 list->push_back( p );
331 p = strtok( NULL, ";" );
332 }
333 delete tmpexts;
334 }
335}
336
337
Note: See TracBrowser for help on using the repository browser.