00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #define LIBSMBIOS_SOURCE
00020 #include "SmbiosWorkaroundImpl.h"
00021 #include "smbios/SmbiosDefs.h"
00022 #include "SmbiosImpl.h"
00023
00024 #include "StdWorkarounds.h"
00025
00026
00027 #include "smbios/message.h"
00028
00029 using namespace std;
00030
00031
00032 #define _X( expr ) do{ try { expr } catch( const std::exception & ){} }while(0)
00033
00034 namespace smbios
00035 {
00036 SmbiosWorkaroundTable *SmbiosWorkaroundFactory::_tableInstance = 0;
00037
00038 factory::TFactory<smbios::SmbiosWorkaroundFactory> *SmbiosWorkaroundFactory::getFactory()
00039 {
00040
00041
00042
00043 return factory::TFactory<SmbiosWorkaroundFactory>::getFactory(reinterpret_cast<factory::TFactory<SmbiosWorkaroundFactory> *>(0));
00044 }
00045
00046 SmbiosWorkaroundFactory::~SmbiosWorkaroundFactory() throw()
00047 {
00048 if( _tableInstance )
00049 {
00050 delete _tableInstance;
00051 _tableInstance = 0;
00052 }
00053
00054 }
00055
00056 SmbiosWorkaroundTable *SmbiosWorkaroundFactory::makeNew( const ISmbiosTable *table )
00057 {
00058 int systemId = 0;
00059
00060 _X( systemId = getU8_FromItem( *(*table)[ Dell_Revisions_and_IDs ], 0x06 ); );
00061 if( 0xFE == systemId )
00062 _X(systemId = getU16_FromItem(*(*table)[ Dell_Revisions_and_IDs ], 0x08 ););
00063
00064 const char * chBiosVersion = 0;
00065
00066 std::string biosVersion = "";
00067
00068 _X( chBiosVersion = getString_FromItem(*(*table)[ BIOS_Information ], 0x05 ); );
00069
00070 if ( 0 != chBiosVersion )
00071 biosVersion = chBiosVersion;
00072
00073 const Workaround **thisSystemWA = 0;
00074 for( int i=0; i < numSystemWorkarounds; ++i )
00075 {
00076 if( workaroundMasterList[i].system->systemId == systemId )
00077 {
00078 thisSystemWA = workaroundMasterList[i].workarounds;
00079 break;
00080 }
00081 }
00082
00083 return new SmbiosWorkaroundTable( table, thisSystemWA );
00084 }
00085
00086 SmbiosWorkaroundTable::SmbiosWorkaroundTable( const ISmbiosTable *, const Workaround **initWorkarounds )
00087 : systemId(0), biosVersion(""), workaroundsForThisSystem(initWorkarounds)
00088 {}
00089
00090 SmbiosWorkaroundTable::~SmbiosWorkaroundTable()
00091 {}
00092
00093 static bool compare( int size, const ISmbiosItem *item, int offset, datatron data )
00094 {
00095 bool retval = false;
00096 u8 *cmpPtr = new u8[size];
00097
00098 try
00099 {
00100 item->getData(offset, cmpPtr, size);
00101 if(0 == memcmp(cmpPtr, data.data, size))
00102 retval = true;
00103 }
00104 catch(...)
00105 {
00106 delete [] cmpPtr;
00107 cmpPtr = 0;
00108 throw;
00109 }
00110
00111 delete [] cmpPtr;
00112 cmpPtr = 0;
00113
00114 return retval;
00115 }
00116
00117 static void fixupData( u8 *buf, size_t size, unsigned int offset, unsigned int len, datatron data )
00118 {
00119 InternalErrorImpl internalError;
00120 if( offset > size )
00121 {
00122 internalError.setMessageString(_("Data overflow. Offset requested is larger than data size. offset: %(offset)i, data size: %(size)i"));
00123 internalError.setParameter("offset",offset);
00124 internalError.setParameter("size",static_cast<int>(size));
00125 throw internalError;
00126 }
00127
00128 memcpy(&(buf[offset]), data.data, len);
00129
00130
00131 }
00132
00133 static void doFixupItem( const Workaround *wa, const ISmbiosItem *item, u8 *buf, size_t bufSize )
00134 {
00135 int i = 0;
00136
00137
00138 for( i=0; 0!=wa->symptoms[i].type; ++i )
00139 {
00140 bool ret = compare( wa->symptoms[i].fieldDataType, item, wa->symptoms[i].fieldOffset, wa->symptoms[i].data );
00141 if( ! ret )
00142 goto out;
00143 }
00144
00145
00146
00147
00148
00149 for( i=0; 0!=wa->fixups[i].type; ++i )
00150 {
00151 fixupData(buf, bufSize, wa->fixups[i].fieldOffset, wa->fixups[i].fieldDataType, wa->fixups[i].data );
00152 }
00153
00154 out:
00155 return;
00156 }
00157
00158 void SmbiosWorkaroundTable::fixupItem( const ISmbiosItem *item, u8 *buffer, size_t bufSize ) const
00159 {
00160 int i = 0;
00161
00162
00163 if( 0 == workaroundsForThisSystem )
00164 goto out;
00165
00166
00167
00168 for( i=0; 0 != workaroundsForThisSystem[i]; ++i )
00169 {
00170 if( workaroundsForThisSystem[i]->symptoms->type == item->getType() )
00171 {
00172
00173 doFixupItem( workaroundsForThisSystem[i], item, buffer, bufSize );
00174 }
00175 }
00176
00177 out:
00178 return;
00179 }
00180
00181 }