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