00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
00031 #include "smbios/message.h"
00032
00033 using namespace std;
00034
00035
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
00045
00046
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
00134
00135 }
00136
00137 static void doFixupItem( const Workaround *wa, const ISmbiosItem *item, u8 *buf, size_t bufSize )
00138 {
00139 int i = 0;
00140
00141
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
00150
00151
00152
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;
00165
00166
00167 if( 0 == workaroundsForThisSystem )
00168 goto out;
00169
00170
00171
00172 for( i=0; 0 != workaroundsForThisSystem[i]; ++i )
00173 {
00174 if( workaroundsForThisSystem[i]->symptoms->type == item->getType() )
00175 {
00176
00177 doFixupItem( workaroundsForThisSystem[i], item, buffer, bufSize );
00178 }
00179 }
00180
00181 out:
00182 return;
00183 }
00184
00185 }