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

Last change on this file since 234 was 234, checked in by Eugene Romanenko, 14 years ago

return dot to wildcard, small interface fixes

File size: 9.2 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    }
318    return cRet;
319}
320
321
Note: See TracBrowser for help on using the repository browser.