00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #define LIBSMBIOS_SOURCE
00021 #include "smbios/compat.h"
00022
00023 #include <sstream>
00024
00025 #include "smbios/IMemory.h"
00026 #include "SmbiosImpl.h"
00027
00028
00029 #include "smbios/message.h"
00030
00031 using namespace smbiosLowlevel;
00032 using namespace std;
00033
00034 #if defined(DEBUG_SMBIOS_STRATEGY)
00035 # define DCOUT(line) do { cout << line; } while(0)
00036 # define DCERR(line) do { cerr << line; } while(0)
00037 #else
00038 # define DCOUT(line) do {} while(0)
00039 # define DCERR(line) do {} while(0)
00040 #endif
00041
00042 namespace smbios
00043 {
00044
00045 bool validateTableEntryPoint(
00046 const smbiosLowlevel::smbios_table_entry_point *tempTEP,
00047 bool strict,
00048 ParseExceptionImpl &parseException
00049 )
00050 {
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 bool retval = true;
00072
00073 u8 checksum = 0;
00074 const u8 *ptr = reinterpret_cast<const u8*>(tempTEP);
00075
00076
00077 for( unsigned int i = 0; (i < static_cast<unsigned int>(tempTEP->eps_length)) && (i < sizeof(*tempTEP)); ++i )
00078 {
00079
00080 checksum = (checksum + ptr[i]) & 0xFF;
00081 }
00082
00083 ostringstream oss;
00084 oss << _("validation of table entry point failed") << endl;
00085
00086 if(memcmp(tempTEP->dmi_anchor,"_DMI_",5)!=0)
00087 {
00088 oss << _("Intermediate anchor string does not match. anchor string: %(dmi_anchor)s") << endl;
00089 retval = false;
00090 }
00091 if(checksum!=0x00)
00092 {
00093 oss << _("Checksum check for table entry point should be zero. checksum: %(checksum)i ") << endl;
00094 retval = false;
00095 }
00096 if(tempTEP->major_ver!=0x02)
00097 {
00098 oss << _("Major version of table entry point should be 2: %(major_version)i") << endl;
00099 retval = false;
00100 }
00101
00102 if(tempTEP->eps_length < 0x0f)
00103 {
00104 oss << _("Entry Point Length field is at least 0x1f : %(eps_length)i") << endl;
00105 retval = false;
00106 }
00107
00108 parseException.setParameter("dmi_anchor", reinterpret_cast<const char *>(tempTEP->dmi_anchor));
00109 parseException.setParameter("checksum", static_cast<int>(checksum));
00110 parseException.setParameter("major_version", static_cast<int>(tempTEP->major_ver));
00111 parseException.setParameter("eps_length", static_cast<int>(tempTEP->eps_length));
00112 parseException.setMessageString(oss.str());
00113
00114 return strict ? retval : 1;
00115 }
00116
00117
00118
00119
00120
00121 bool SmbiosMemoryStrategy::getSmbiosTable(const u8 **smbiosBuffer, smbiosLowlevel::smbios_table_entry_point *table_header, bool strict)
00122 {
00123 bool ret = false;
00124 try
00125 {
00126
00127 DCERR("trying SmbiosMemoryStrategy" << endl);
00128 getSmbiosTableHeader(table_header, strict);
00129
00130
00131 getSmbiosTableBuf(smbiosBuffer, *table_header);
00132 if(smbiosBuffer)
00133 ret = true;
00134 }
00135 catch(const exception &e)
00136 {
00137 UNREFERENCED_PARAMETER(e);
00138 DCERR("got Exception: " << e.what() << endl);
00139 }
00140
00141 DCERR(" ret for SmbiosMemoryStrategy is: " << ret << endl);
00142 return ret;
00143 }
00144
00145 void SmbiosMemoryStrategy::getSmbiosTableBuf(const u8 **smbiosBuffer, smbiosLowlevel::smbios_table_entry_point table_header)
00146 {
00147 memory::IMemory *mem = memory::MemoryFactory::getFactory()->getSingleton();
00148
00149
00150 u8 *newSmbiosBuffer = new u8[table_header.table_length];
00151 try
00152 {
00153 mem->fillBuffer( newSmbiosBuffer, table_header.table_address, table_header.table_length );
00154
00155
00156 if( 0 != *smbiosBuffer )
00157 {
00158 memset (const_cast<u8 *>(*smbiosBuffer), 0, sizeof (**smbiosBuffer));
00159 delete [] const_cast<u8 *>(*smbiosBuffer);
00160 *smbiosBuffer = 0;
00161 }
00162 }
00163 catch(...)
00164 {
00165 delete [] newSmbiosBuffer;
00166 newSmbiosBuffer = 0;
00167 throw;
00168 }
00169
00170 *smbiosBuffer = reinterpret_cast<const u8 *>(newSmbiosBuffer);
00171 }
00172
00173
00174
00175 void SmbiosMemoryStrategy::getSmbiosTableHeader(smbiosLowlevel::smbios_table_entry_point *table_header, bool strict)
00176 {
00177 memory::IMemory *mem = memory::MemoryFactory::getFactory()->getSingleton();
00178
00179 unsigned long fp = E_BLOCK_START;
00180 if( offset )
00181 fp = offset;
00182
00183 ParseExceptionImpl parseException;
00184 if( offset )
00185 {
00186 parseException.setMessageString(_("SMBIOS Header not found at offset: %(offsetValue)i"));
00187 parseException.setParameter("offset",offset);
00188 }
00189 else
00190 {
00191 parseException.setMessageString(_("SMBIOS Header not found in search."));
00192 }
00193
00194 smbios_table_entry_point tempTEP;
00195 memset(&tempTEP, 0, sizeof(tempTEP));
00196 while ( (fp + sizeof(tempTEP)) < F_BLOCK_END)
00197 {
00198 mem->fillBuffer(
00199 reinterpret_cast<u8 *>(&tempTEP),
00200 fp,
00201 sizeof(tempTEP)
00202 );
00203
00204
00205 if (memcmp (&tempTEP, "_SM_", 4) == 0)
00206 {
00207 if(validateTableEntryPoint(&tempTEP, strict, parseException))
00208 {
00209 break;
00210 }
00211 }
00212
00213
00214
00215
00216
00217 if (offset)
00218 throw parseException;
00219
00220 fp += 16;
00221 }
00222
00223
00224 if ((fp + sizeof(tempTEP)) >= F_BLOCK_END)
00225 throw parseException;
00226
00227
00228 offset = fp;
00229 memcpy( const_cast<smbios_table_entry_point *>(table_header), &tempTEP, sizeof(*table_header) );
00230 }
00231 }