Ignore:
Timestamp:
Aug 4, 2007, 5:45:12 PM (14 years ago)
Author:
Eugene Romanenko
Message:

better solution for ticket #43

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Lucide/SOURCE/gui/pluginman.cpp

    r216 r217  
    5959
    6060    // enum plugins, (LU*.DLL) except for LUDOC.DLL, which is 'null' plugin
    61     // and Lucide.dll, which isn't plugin.
     61    // and Lucide.dll, which is not a plugin.
    6262    struct find_t ffblk;
    6363    unsigned done = _dos_findfirst( buffer, _A_RDONLY | _A_NORMAL, &ffblk );
     
    8989{
    9090    // Function pointer variables
    91     LuDocument * APIENTRY (*pCreateObject)()      = NULL;
    92     char * APIENTRY (*pGetSupportedExtensions)() = NULL;
    93     char * APIENTRY (*pGetDescription)()          = NULL;
    94     LuCheckStruct * APIENTRY (*pGetCheckStruct)() = NULL;
     91    LuDocument       * APIENTRY (*pCreateObject)()           = NULL;
     92    char             * APIENTRY (*pGetSupportedExtensions)() = NULL;
     93    char             * APIENTRY (*pGetDescription)()         = NULL;
     94    LuSignatureCheck * APIENTRY (*pGetSignatureCheck)()      = NULL;
    9595
    9696    std::string fulldllname = path;
     
    116116
    117117        // optional
    118         if ( DosQueryProcAddr( h, 0, "getCheckStruct", (PFN *)&pGetCheckStruct ) != 0 ) {
    119             pGetCheckStruct = NULL;
     118        if ( DosQueryProcAddr( h, 0, "getSignatureCheck", (PFN *)&pGetSignatureCheck ) != 0 ) {
     119            pGetSignatureCheck = NULL;
    120120        }
    121121
     
    126126    {
    127127        PluginInfo pi;
    128         pi.handle = h;
    129         pi.name = dllname;
    130         pi.extensions = pGetSupportedExtensions();
     128        pi.handle      = h;
     129        pi.name        = dllname;
     130        pi.extensions  = pGetSupportedExtensions();
    131131        pi.description = pGetDescription();
    132         pi.checkStruct = ( pGetCheckStruct == NULL ) ? NULL : pGetCheckStruct();
     132        pi.signatures  = ( pGetSignatureCheck == NULL ) ? NULL : pGetSignatureCheck();
    133133
    134134        plugins->push_back( pi );
     
    136136}
    137137
     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}
    138154
    139155// returns NULL if no suitable plugin found
     
    144160        return NULL;
    145161    }
    146 
    147     LuDocument * APIENTRY (*pCreateObject)() = NULL;
    148162
    149163    for ( int i = 0; i < plugins->size(); i++ )
     
    165179        if ( strstr( cExts, cExt ) != NULL )
    166180        {
    167             if ( DosQueryProcAddr( pi->handle, 0, "createObject",
    168                                    (PFN *)&pCreateObject ) == 0 )
     181            LuDocument *d = createDocFromDll( pi->handle, checkOnly );
     182            if ( d != NULL )
    169183            {
    170184                delete cExt;
    171185                delete cExts;
    172 
    173                 if ( checkOnly ) {
    174                     return (LuDocument *)TRUE;
    175                 }
    176                 else {
    177                     return pCreateObject();
    178                 }
     186                return d;
    179187            }
    180188        }
     
    187195}
    188196
    189 static bool checkDataEntry( LuCheckData *data, int h )
    190 {
    191     lseek( h, data->offset, SEEK_SET );
    192     unsigned char *buf = new char[ data->length ];
    193     read( h, buf, data->length );
    194     bool result = ( memcmp( data->data, buf, data->length ) == 0 );
     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 );
    195203    delete buf;
    196204    return result;
    197205}
    198206
    199 static bool checkData( LuCheckStruct *checkStruct, const char *file )
     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 )
    200224{
    201225    int h = open( file, O_RDONLY | O_BINARY );
    202226
    203     if ( h != -1 )
    204     {
    205         bool result = true;
    206 
    207         for ( unsigned long i = 0; i < checkStruct->count; i++ )
    208         {
    209             if ( !checkDataEntry( &(checkStruct->cdata[ i ]), h ) ) {
    210                 result = false;
    211                 break;
    212             }
    213         }
    214 
    215         close( h );
    216         return result;
    217     }
    218 
    219     return false;
     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;
    220243}
    221244
     
    237260
    238261    // Search by checkstruct
    239     LuDocument * APIENTRY (*pCreateObject)() = NULL;
    240 
    241     for ( int i = 0; i < plugins->size(); i++ )
    242     {
    243         PluginInfo *pi = &(*plugins)[ i ];
    244 
    245         if ( pi->checkStruct != NULL )
     262    for ( int i = 0; i < plugins->size(); i++ )
     263    {
     264        PluginInfo *pi = &(*plugins)[ i ];
     265
     266        if ( pi->signatures != NULL )
    246267        {
    247             if ( checkData( pi->checkStruct, file ) )
     268            if ( checkSignatures( pi->signatures, file ) )
    248269            {
    249                 if ( DosQueryProcAddr( pi->handle, 0, "createObject",
    250                                        (PFN *)&pCreateObject ) == 0 )
    251                 {
    252                     if ( checkOnly ) {
    253                         return (LuDocument *)TRUE;
    254                     }
    255                     else {
    256                         return pCreateObject();
    257                     }
     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;
    258294                }
    259295            }
Note: See TracChangeset for help on using the changeset viewer.