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 "SmbiosImpl.h"
00026
00027
00028 #include "smbios/message.h"
00029
00030 using namespace smbiosLowlevel;
00031 using namespace std;
00032
00033 #if defined(DEBUG_SMBIOS)
00034 # define DCOUT(line) do { cout << line; } while(0)
00035 # define DCERR(line) do { cerr << line; } while(0)
00036 #else
00037 # define DCOUT(line) do {} while(0)
00038 # define DCERR(line) do {} while(0)
00039 #endif
00040
00041 namespace smbios
00042 {
00043
00044 ISmbiosTable::ISmbiosTable()
00045 {}
00046
00047 ISmbiosTable::~ISmbiosTable()
00048 {}
00049
00050
00051
00052 SmbiosTable::SmbiosTable ()
00053 : ISmbiosTable(), itemList(), initializing(true), strictValidationMode(false), workaround(0), smbiosBuffer (0)
00054 {
00055 memset (
00056 const_cast<smbios_table_entry_point *>(&table_header),
00057 0,
00058 sizeof (table_header)
00059 );
00060 }
00061
00062
00063 SmbiosTable::SmbiosTable(std::vector<SmbiosStrategy *> initStrategyList, bool strictValidation)
00064 :ISmbiosTable(), itemList(), initializing(true), strictValidationMode(strictValidation), workaround(0), smbiosBuffer (0), strategyList(initStrategyList)
00065 {
00066
00067 reReadTable();
00068 }
00069
00070
00071 SmbiosTable::~SmbiosTable ()
00072 {
00073 clearItemCache();
00074
00075 if (0 != smbiosBuffer)
00076 {
00077 memset ( const_cast<u8 *>(smbiosBuffer), 0, sizeof (*smbiosBuffer));
00078 delete [] const_cast<u8 *>(smbiosBuffer);
00079 smbiosBuffer = 0;
00080 }
00081
00082 memset (
00083 const_cast<smbios_table_entry_point *>(&table_header),
00084 0,
00085 sizeof (table_header)
00086 );
00087
00088 std::vector< SmbiosStrategy *>::iterator strategy;
00089 for( strategy = strategyList.begin(); strategy != strategyList.end(); ++strategy )
00090 {
00091 delete *strategy;
00092 }
00093 }
00094
00095 ISmbiosItem *SmbiosTable::getCachedItem( const void * itemPtr ) const
00096 {
00097 ISmbiosItem *ret = 0;
00098 if ((itemList.find (itemPtr) !=
00099 itemList.end ()))
00100 {
00101 if( 0 != itemList[itemPtr] )
00102 {
00103 ret = itemList[itemPtr];
00104 }
00105 else
00106 {
00107 throw InternalErrorImpl(_("No null pointers should ever leak into the itemList"));
00108 }
00109 }
00110 return ret;
00111 }
00112
00113 void SmbiosTable::cacheItem( const void *ptr, ISmbiosItem &newitem ) const
00114 {
00115
00116
00117
00118 pair < const void *, ISmbiosItem * >myPair (ptr, &newitem);
00119 itemList.insert (itemList.begin (), myPair);
00120 }
00121
00122 SmbiosTable::iterator SmbiosTable::begin ()
00123 {
00124 return SmbiosTable::iterator (this);
00125 }
00126
00127 SmbiosTable::const_iterator SmbiosTable::begin () const
00128 {
00129 return SmbiosTable::const_iterator (this);
00130 }
00131
00132 SmbiosTable::iterator SmbiosTable::end ()
00133 {
00134 return SmbiosTable::iterator ();
00135 }
00136
00137 SmbiosTable::const_iterator SmbiosTable::end ()const
00138 {
00139 return SmbiosTable::const_iterator ();
00140 }
00141
00142 SmbiosTable::iterator SmbiosTable::operator[] (const int type)
00143 {
00144 return SmbiosTable::iterator (this, type);
00145 }
00146
00147 SmbiosTable::const_iterator SmbiosTable::operator[](const int type) const
00148 {
00149 return SmbiosTable::const_iterator (this, type);
00150 }
00151
00152 SmbiosTable::iterator SmbiosTable::operator[] (const string &)
00153 {
00154 throw NotImplementedImpl(_("This is an enhanced function call that is not available in the base Smbios library. You must be using an enhanced library such as SmbiosXml to use this API"));
00155 }
00156
00157 SmbiosTable::const_iterator SmbiosTable::operator[](const string &) const
00158 {
00159 throw NotImplementedImpl(_("This is an enhanced function call that is not available in the base Smbios library. You must be using an enhanced library such as SmbiosXml to use this API"));
00160 }
00161
00162 void SmbiosTable::reReadTable()
00163 {
00164 bool gotTable = false;
00165
00166
00167
00168 if( ! initializing )
00169 clearItemCache();
00170
00171
00172
00173 DCERR("calling strategy code to read table" << endl);
00174 std::vector< SmbiosStrategy *>::iterator strategy;
00175 for( strategy = strategyList.begin(); strategy != strategyList.end(); ++strategy )
00176 {
00177 try
00178 {
00179 DCERR(" strategy: 0x" << hex << (int)(*strategy) << endl);
00180 if( (*strategy)->getSmbiosTable(&smbiosBuffer, &table_header, getStrictValidationMode()) )
00181 {
00182 DCERR(" RETURNED SUCCESS" << endl);
00183 gotTable = true;
00184 break;
00185 }
00186 }
00187 catch(...)
00188 {
00189
00190 }
00191 }
00192 DCERR("TABLE HEADER DUMP: " << endl << *this << endl);
00193 DCERR("TABLE BUFFER: 0x" << hex << (int)smbiosBuffer << endl);
00194
00195 if (! gotTable)
00196 {
00197
00198
00199 std::vector< SmbiosStrategy *>::iterator strategy;
00200 for( strategy = strategyList.begin(); strategy != strategyList.end(); ++strategy )
00201 {
00202 delete *strategy;
00203 }
00204 throw InternalErrorImpl(_("Could not instantiate SMBIOS table."));
00205 }
00206 }
00207
00208 void SmbiosTable::initializeWorkaround() const
00209 {
00210
00211
00212
00213
00214 const SmbiosWorkaroundTable *ptr = workaround.get();
00215 workaround.release();
00216 delete const_cast<SmbiosWorkaroundTable *>(ptr);
00217 std::auto_ptr<SmbiosWorkaroundTable> foo(
00218 SmbiosWorkaroundFactory::getFactory()->makeNew( this ));
00219 workaround = foo;
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 clearItemCache();
00233
00234 initializing = false;
00235 }
00236
00237 void SmbiosTable::rawMode(bool m) const
00238 {
00239 initializing = m;
00240 }
00241
00242 void SmbiosTable::clearItemCache() const
00243 {
00244
00245 std::map < const void *, ISmbiosItem * >::iterator position;
00246 for (position = itemList.begin ();
00247 position != itemList.end (); ++position)
00248 {
00249 delete position->second;
00250 }
00251
00252 itemList.clear();
00253 }
00254
00255
00256 void SmbiosTable::setStrictValidationMode(bool mode) const
00257 {
00258 strictValidationMode = mode;
00259 }
00260
00261 bool SmbiosTable::getStrictValidationMode() const
00262 {
00263 return strictValidationMode;
00264 }
00265
00266
00267 ISmbiosItem &SmbiosTable::makeItem(
00268 const void *header) const
00269 {
00270 const smbios_structure_header *structure =
00271 reinterpret_cast<const smbios_structure_header *>(header);
00272 ISmbiosItem *item = new SmbiosItem( structure );
00273 if( ! initializing )
00274 {
00275 dynamic_cast<SmbiosItem*>(item)->fixup( workaround.get() );
00276 }
00277 return *item;
00278 }
00279
00280 const void *SmbiosTable::nextSmbiosStruct (const void* current) const
00281 {
00282 const smbios_structure_header *currStruct =
00283 reinterpret_cast<const smbios_structure_header *>(current);
00284 const u8 *data = 0;
00285
00286
00287 if (0 == smbiosBuffer)
00288 goto out1;
00289
00290 data = smbiosBuffer;
00291
00292
00293 if (0 == currStruct)
00294 goto out1;
00295
00296
00297
00298 if (0x7f == currStruct->type)
00299 {
00300 data = 0;
00301 goto out1;
00302 }
00303
00304
00305
00306
00307 data = reinterpret_cast<const u8 *>(currStruct) + currStruct->length;
00308
00309
00310
00311
00312
00313
00314
00315 while (((data - smbiosBuffer) < (table_header.dmi.table_length - 3)) && (*data || data[1]))
00316 data++;
00317
00318
00319 data += 2;
00320
00321
00322
00323
00324 if ( (data - smbiosBuffer) > (table_header.dmi.table_length - 4))
00325 {
00326
00327
00328 data = 0;
00329 goto out1;
00330 }
00331
00332 out1:
00333 return reinterpret_cast<const void *>(data);
00334 }
00335
00336
00337 int SmbiosTable::getNumberOfEntries () const
00338 {
00339 return table_header.dmi.table_num_structs;
00340 }
00341
00342 smbiosLowlevel::smbios_table_entry_point SmbiosTable::getTableEPS() const
00343 {
00344 return table_header;
00345 }
00346
00347 ostream & SmbiosTable::streamify(ostream & cout) const
00348 {
00349 cout << "\nSMBIOS table " << endl;
00350 cout << "\tversion : ";
00351 cout << static_cast<int>(table_header.major_ver) << ".";
00352 cout << static_cast<int>(table_header.minor_ver) << endl;
00353 cout << hex ;
00354 cout << "\taddress : " << table_header.dmi.table_address << endl;
00355 cout << dec;
00356 cout << "\tlength : " << table_header.dmi.table_length << endl;
00357 cout << "\tnum structs: " << table_header.dmi.table_num_structs << endl;
00358 cout << endl;
00359
00360 SmbiosTable::const_iterator position = begin();
00361 while (position != end())
00362 {
00363 cout << *position << endl;
00364 ++position;
00365 }
00366 return cout;
00367 }
00368
00369 ostream & operator << (ostream & cout, const ISmbiosTable & table)
00370 {
00371 table.streamify( cout );
00372 return cout;
00373 }
00374
00375 }