SmbiosWorkaround.cpp

Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  * vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=c:cindent:textwidth=0:
00003  *
00004  * Copyright (C) 2005 Dell Inc.
00005  *  by Michael Brown <Michael_E_Brown@dell.com>
00006  * Licensed under the Open Software License version 2.1
00007  *
00008  * Alternatively, you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published
00010  * by the Free Software Foundation; either version 2 of the License,
00011  * or (at your option) any later version.
00012 
00013  * This program is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016  * See the GNU General Public License for more details.
00017  */
00018 
00019 #define LIBSMBIOS_SOURCE
00020 #include "smbios/compat.h"
00021 
00022 #include <string.h>
00023 
00024 #include "SmbiosWorkaroundImpl.h"
00025 #include "smbios/SmbiosDefs.h"
00026 #include "SmbiosImpl.h"
00027 
00028 #include "StdWorkarounds.h"
00029 
00030 // message.h should be included last.
00031 #include "smbios/message.h"
00032 
00033 using namespace std;
00034 
00035 // convenience function.
00036 #define _X( expr ) do{ try {  expr } catch( const std::exception & ){} }while(0)
00037 
00038 namespace smbios
00039 {
00040     SmbiosWorkaroundTable   *SmbiosWorkaroundFactory::_tableInstance = 0;
00041 
00042     factory::TFactory<smbios::SmbiosWorkaroundFactory> *SmbiosWorkaroundFactory::getFactory()
00043     {
00044         // reinterpret_cast<...>(0) to ensure template parameter is correct
00045         // this is a workaround for VC6 which cannot use explicit member template
00046         // function initialization.
00047         return factory::TFactory<SmbiosWorkaroundFactory>::getFactory(reinterpret_cast<factory::TFactory<SmbiosWorkaroundFactory> *>(0));
00048     }
00049 
00050     SmbiosWorkaroundFactory::~SmbiosWorkaroundFactory() throw()
00051     {
00052         if( _tableInstance )
00053         {
00054             delete _tableInstance;
00055             _tableInstance = 0;
00056         }
00057 
00058     }
00059 
00060     SmbiosWorkaroundTable *SmbiosWorkaroundFactory::makeNew( const ISmbiosTable *table )
00061     {
00062         int systemId = 0;
00063 
00064         _X( systemId = getU8_FromItem( *(*table)[ Dell_Revisions_and_IDs ], 0x06 ); );
00065         if( 0xFE == systemId )
00066             _X(systemId = getU16_FromItem(*(*table)[ Dell_Revisions_and_IDs ], 0x08 ););
00067 
00068         const char * chBiosVersion = 0;
00069 
00070         std::string biosVersion = "";
00071 
00072         _X( chBiosVersion = getString_FromItem(*(*table)[ BIOS_Information ], 0x05 ); );
00073 
00074         if ( 0 != chBiosVersion )
00075             biosVersion = chBiosVersion;
00076 
00077         const Workaround **thisSystemWA = 0;
00078         for( int i=0; i < numSystemWorkarounds; ++i )
00079         {
00080             if( workaroundMasterList[i].system->systemId == systemId )
00081             {
00082                 thisSystemWA = workaroundMasterList[i].workarounds;
00083                 break;
00084             }
00085         }
00086 
00087         return new SmbiosWorkaroundTable( table, thisSystemWA );
00088     }
00089 
00090     SmbiosWorkaroundTable::SmbiosWorkaroundTable( const ISmbiosTable *, const Workaround **initWorkarounds )
00091             : systemId(0), biosVersion(""), workaroundsForThisSystem(initWorkarounds)
00092     {}
00093 
00094     SmbiosWorkaroundTable::~SmbiosWorkaroundTable()
00095     {}
00096 
00097     static bool compare( int size, const ISmbiosItem *item, int offset, datatron data )
00098     {
00099         bool retval = false;
00100         u8 *cmpPtr = new u8[size];
00101     
00102         try
00103         {
00104             item->getData(offset, cmpPtr, size);
00105             if(0 == memcmp(cmpPtr, data.data, size))
00106                     retval = true;
00107         }
00108         catch(...)
00109         {
00110             delete [] cmpPtr;
00111             cmpPtr = 0;
00112             throw;
00113         }
00114 
00115         delete [] cmpPtr;
00116         cmpPtr = 0;
00117 
00118         return retval;
00119     }
00120 
00121     static void fixupData( u8 *buf, size_t size, unsigned int offset, unsigned int len, datatron data )
00122     {
00123         InternalErrorImpl internalError;
00124         if( offset > size )
00125         {
00126             internalError.setMessageString(_("Data overflow. Offset requested is larger than data size. offset: %(offset)i, data size: %(size)i"));
00127             internalError.setParameter("offset",offset);
00128             internalError.setParameter("size",static_cast<int>(size));
00129             throw internalError;
00130         }
00131 
00132         memcpy(&(buf[offset]), data.data, len);
00133         //for(unsigned int i=0; i<len; i++)
00134             //buf[offset + i] = data.data[i];
00135     }
00136 
00137     static void doFixupItem( const Workaround *wa, const ISmbiosItem *item, u8 *buf, size_t bufSize )
00138     {
00139         int i = 0;  //loop counter. workaround MSVC++ braindamage.
00140 
00141         // check all of the symptoms. If any symptom does not match, bail.
00142         for( i=0; 0!=wa->symptoms[i].type; ++i )
00143         {
00144             bool ret = compare( wa->symptoms[i].fieldDataType, item, wa->symptoms[i].fieldOffset, wa->symptoms[i].data );
00145             if( ! ret )
00146                 goto out;
00147         }
00148 
00149         // All symptoms present if we got here.
00150         //cout << "GOT HERE!" << flush;
00151 
00152         // apply all of the fixups.
00153         for( i=0; 0!=wa->fixups[i].type; ++i )
00154         {
00155             fixupData(buf, bufSize, wa->fixups[i].fieldOffset, wa->fixups[i].fieldDataType, wa->fixups[i].data );
00156         }
00157 
00158 out:
00159         return;
00160     }
00161 
00162     void SmbiosWorkaroundTable::fixupItem( const ISmbiosItem *item, u8 *buffer, size_t bufSize ) const
00163     {
00164         int i = 0; //declare i up here to work around braindamaged MSVC++ for()
00165         // scoping violation.
00166 
00167         if( 0 == workaroundsForThisSystem )
00168             goto out;
00169 
00170         // workaroundsForThisSystem is a NULL-terminated array
00171         // of Workaround pointers.
00172         for( i=0; 0 != workaroundsForThisSystem[i]; ++i )
00173         {
00174             if( workaroundsForThisSystem[i]->symptoms->type  == item->getType() )
00175             {
00176                 //cout << "-F-" << flush;
00177                 doFixupItem( workaroundsForThisSystem[i], item, buffer, bufSize );
00178             }
00179         }
00180 
00181 out:
00182         return;
00183     }
00184 
00185 }

Generated on Wed Apr 2 16:37:32 2008 for SMBIOS Library by  doxygen 1.5.1