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/ISmbios.h"
00021 #include "smbios/IToken.h"
00022 #include "smbios/ISmi.h"
00023
00024 #include "smbios/SystemInfo.h"
00025 #include "smbios/IMemory.h"
00026 #include "smbios/SmbiosDefs.h"
00027 #include "../common/ExceptionImpl.h"
00028 #include "../token/TokenLowLevel.h"
00029
00030 #include "DellMagic.h"
00031
00032 #include "smbios/version.h"
00033
00034
00035 #include "smbios/message.h"
00036
00037 using namespace smbios;
00038 using namespace cmos;
00039 using namespace std;
00040
00041 #if defined(DEBUG_SYSINFO)
00042 # define DCOUT(line) do { cout << line; } while(0)
00043 # define DCERR(line) do { cerr << line; } while(0)
00044 #else
00045 # define DCOUT(line) do {} while(0)
00046 # define DCERR(line) do {} while(0)
00047 #endif
00048
00049
00050 extern smbios::Exception<smbios::IException> SysInfoException;
00051
00052
00053
00054
00055 static std::string biosPassword = "";
00056
00057 static void stripString( char *str )
00058 {
00059 if(!str)
00060 return;
00061
00062 if(strlen(str) == 0)
00063 return;
00064
00065 size_t ch = strlen(str);
00066 do
00067 {
00068 --ch;
00069 if( ' ' == str[ch] )
00070 str[ch] = '\0';
00071 else
00072 break;
00073
00074 } while(ch);
00075 }
00076
00077
00078
00079
00080
00081
00082
00083 static unsigned char dell_decode_digit( char tagval )
00084 {
00085
00086
00087
00088 if( tagval > 0x19 )
00089 tagval += 0x3C;
00090 else if( tagval > 0x14 )
00091 tagval += 0x3B;
00092 else if( tagval > 0x0F )
00093 tagval += 0x3A;
00094 else if( tagval > 0x0C )
00095 tagval += 0x39;
00096 else if( tagval > 0x09 )
00097 tagval += 0x38;
00098 else
00099 tagval += 0x30;
00100
00101 return tagval;
00102 }
00103
00104
00105 static void dell_decode_service_tag( char *tag, int len )
00106 {
00107
00108
00109 if( ((tag)[0] & (1<<7)) == (1<<7) )
00110 {
00111 char new_tag[SVC_TAG_LEN_MAX + 1] = {0,};
00112
00113
00114 new_tag[6] = dell_decode_digit( (tag[4] & 0x1F) );
00115 new_tag[5] = dell_decode_digit( ((tag[3] & 0x03)<<3) | ((tag[4]>>5) & 0x07) );
00116 new_tag[4] = dell_decode_digit( ((tag[3] & 0x7C)>>2) );
00117 new_tag[3] = dell_decode_digit( (((tag[2] & 0x0F)<<1) | ((tag[3]>>7) & 0x01)) );
00118 new_tag[2] = dell_decode_digit( (((tag[1] & 0x01)<<4) | ((tag[2]>>4) & 0xF)) & 0x1F);
00119 new_tag[1] = dell_decode_digit( ((tag[1] & 0x3E)>>1) & 0x1F );
00120 new_tag[0] = (tag[0] ^ (1<<7));
00121
00122 memset(tag, 0, len);
00123 strncpy(tag, new_tag, len < SVC_TAG_LEN_MAX ? len : SVC_TAG_LEN_MAX);
00124 }
00125 }
00126
00127 static unsigned char dell_encode_digit( char ch )
00128 {
00129
00130
00131
00132
00133
00134 int uc = toupper(ch);
00135 int retval = 0;
00136 if ( uc >= '0' && uc <= '9' )
00137 retval = uc - 0x30;
00138 if ( uc >= 'B' && uc <= 'D' )
00139 retval = uc - 0x38;
00140 if ( uc >= 'F' && uc <= 'H' )
00141 retval = uc - 0x39;
00142 if ( uc >= 'J' && uc <= 'N' )
00143 retval = uc - 0x3A;
00144 if ( uc >= 'P' && uc <= 'T' )
00145 retval = uc - 0x3B;
00146 if ( uc >= 'V' && uc <= 'Z' )
00147 retval = uc - 0x3C;
00148 return static_cast<unsigned char>(retval);
00149 }
00150
00151 static void dell_encode_service_tag( char *tag, size_t len )
00152 {
00153 if (len <= SVC_TAG_CMOS_LEN_MAX)
00154 return;
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 char tagToSet[SVC_TAG_LEN_MAX] = {0,};
00167 memcpy(tagToSet, tag, len < SVC_TAG_LEN_MAX ? len : SVC_TAG_LEN_MAX );
00168
00169 char newTagBuf[SVC_TAG_CMOS_LEN_MAX] = {0,};
00170
00171
00172 newTagBuf[0] = tagToSet[0] | 1<<7;
00173
00174
00175 newTagBuf[1] = dell_encode_digit(tagToSet[1]) << 1;
00176
00177
00178 newTagBuf[1] = newTagBuf[1] | dell_encode_digit(tagToSet[2]) >> 4;
00179 newTagBuf[2] = dell_encode_digit(tagToSet[2]) << 4;
00180
00181
00182 newTagBuf[2] = newTagBuf[2] | dell_encode_digit(tagToSet[3]) >> 1;
00183 newTagBuf[3] = dell_encode_digit(tagToSet[3]) << 7;
00184
00185
00186 newTagBuf[3] = newTagBuf[3] | dell_encode_digit(tagToSet[4]) << 2;
00187
00188
00189 newTagBuf[3] = newTagBuf[3] | dell_encode_digit(tagToSet[5]) >> 3;
00190 newTagBuf[4] = dell_encode_digit(tagToSet[5]) << 5;
00191
00192
00193 newTagBuf[4] = newTagBuf[4] | dell_encode_digit(tagToSet[6]);
00194
00195 memset(tag, 0, len);
00196 memcpy(tag, newTagBuf, len < SVC_TAG_CMOS_LEN_MAX ? len: SVC_TAG_CMOS_LEN_MAX);
00197 return;
00198 }
00199
00200
00201 const char *SMBIOSGetLibraryVersionString()
00202 {
00203
00204 return LIBSMBIOS_RELEASE_VERSION;
00205 }
00206
00207 void SMBIOSFreeMemory( const char *ptr )
00208 {
00209 delete [] const_cast<char *>(ptr);
00210 }
00211
00212
00213 static char *getTagFromSMI(u16 select)
00214 {
00215 u32 args[4] = {0,}, res[4] = {0,};
00216 smi::doSimpleCallingInterfaceSmi(11, select, args, res);
00217
00218 char *retval = new char[16];
00219 memset(retval, '\0', 16);
00220
00221 memcpy(retval, reinterpret_cast<u8 *>(&(res[1])), sizeof(res));
00222
00223 for(size_t i=0; i<strlen(retval); i++)
00224 if( static_cast<unsigned char>(retval[i]) == 0xFF ) retval[i] = '\0';
00225
00226 return retval;
00227 }
00228
00229
00230 static void setTagUsingSMI(const char *newTag, u16 select)
00231 {
00232 u32 args[4] = {0,}, res[4] = {0,};
00233 strncpy(reinterpret_cast<char *>(args), newTag, 12);
00234 args[3] = smi::getAuthenticationKey(biosPassword);
00235 smi::doSimpleCallingInterfaceSmi(11, select, args, res);
00236 }
00237
00238 static char *getStringFromTable(unsigned int structure, unsigned int stringNumber)
00239 {
00240 smbios::ISmbiosTable *table = 0;
00241 table = smbios::SmbiosFactory::getFactory()->getSingleton();
00242
00243 if (!table)
00244 throw InternalErrorImpl();
00245
00246 const char *tempval = 0;
00247 smbios::ISmbiosTable::iterator item;
00248 tempval = (*table)[structure]->getString(stringNumber);
00249
00250 if(!tempval)
00251 throw exception();
00252
00253 size_t slen = strlen(tempval);
00254 char *retval = new char[slen + 1];
00255 strncpy(retval,tempval,slen);
00256 retval[slen] = '\0';
00257
00258 stripString(retval);
00259 if ( ! strlen(retval ))
00260 {
00261 delete [] retval;
00262 retval = 0;
00263 throw exception();
00264 }
00265
00266 return retval;
00267 }
00268
00269 static char *getServiceTagFromSysInfo()
00270 {
00271 DCOUT( "in getServiceTagFromSysInfo()" << endl);
00272 return getStringFromTable(System_Information, System_Information_Serial_Number_Offset);
00273 }
00274
00275 static char *getServiceTagFromSysEncl()
00276 {
00277 DCOUT( "in getServiceTagFromSysEncl()" << endl);
00278 return getStringFromTable(System_Enclosure_or_Chassis, System_Enclosure_or_Chassis_Service_Offset);
00279 }
00280
00281
00282 char *getServiceTagFromCMOSToken()
00283 {
00284 smbios::ITokenTable *table = 0;
00285 table = smbios::TokenTableFactory::getFactory()->getSingleton();
00286
00287 DCOUT( "in getServiceTagFromCMOSToken()" << endl);
00288
00289 if (0 == table)
00290 {
00291 throw InternalErrorImpl();
00292 }
00293
00294 char *tempval = 0;
00295 try
00296 {
00297
00298 tempval = new char[SVC_TAG_LEN_MAX + 1];
00299 memset(tempval, '\0', SVC_TAG_LEN_MAX + 1);
00300
00301 (*table)[Cmos_Service_Token]->getString(reinterpret_cast<u8*>(tempval), SVC_TAG_CMOS_LEN_MAX + 1);
00302
00303
00304 dell_decode_service_tag( tempval, SVC_TAG_LEN_MAX + 1 );
00305
00306
00307 u16 indexPort, dataPort;
00308 u8 location;
00309
00310 smbios::IToken *token = &(*((*table)[ Cmos_Service_Token ]));
00311 dynamic_cast< smbios::ICmosToken * >(token)->getCMOSDetails( &indexPort, &dataPort, &location );
00312
00313 u8 csum = 0;
00314 ICmosRW *cmos = cmos::CmosRWFactory::getFactory()->getSingleton();
00315
00316 for( u32 i = 0; i < SVC_TAG_CMOS_LEN_MAX; i++)
00317 {
00318
00319 csum = (csum + cmos->readByte( indexPort, dataPort, location + i )) & 0xFF;
00320 }
00321
00322
00323 csum = (csum - cmos->readByte( indexPort, dataPort, location + SVC_TAG_CMOS_LEN_MAX )) & 0xFF;
00324 if( csum )
00325 throw "Bad checksum";
00326 }
00327 catch( ... )
00328 {
00329 delete [] tempval;
00330 throw;
00331 }
00332
00333 return tempval;
00334 }
00335
00336
00337 char *getServiceTagFromSMI()
00338 {
00339 DCOUT( "in getServiceTagFromSMI()" << endl);
00340 return getTagFromSMI( 2 );
00341 }
00342
00343
00344 struct DellGetServiceTagFunctions
00345 {
00346 char *(*f_ptr)();
00347 }
00348
00349
00350 DellGetServiceTagFunctions[] = {
00351 {&getServiceTagFromSMI,},
00352 {&getServiceTagFromCMOSToken,},
00353 {&getServiceTagFromSysInfo,},
00354 {&getServiceTagFromSysEncl,},
00355 };
00356
00357 const char *SMBIOSGetServiceTag()
00358 {
00359 char *serviceTag = 0;
00360 int numEntries =
00361 sizeof (DellGetServiceTagFunctions) / sizeof (DellGetServiceTagFunctions[0]);
00362
00363 DCOUT( "numEntries: " << numEntries << endl);
00364
00365 for (int i = 0; (i < numEntries) && (!serviceTag); ++i)
00366 {
00367
00368 try
00369 {
00370 DCOUT(" try #" << i << endl);
00371
00372 serviceTag = DellGetServiceTagFunctions[i].f_ptr ();
00373 }
00374 catch(const exception &e)
00375 {
00376 DCOUT(" Caught exception: " << e.what() << endl);
00377 SysInfoException.setMessageString(e.what());
00378 }
00379 catch(...)
00380 {
00381 DCOUT(" Caught unknown exception" << endl);
00382 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00383 }
00384
00385 if(serviceTag)
00386 DCOUT( " GOT TAG: -->" << serviceTag << "<--" << endl);
00387 }
00388 stripString(serviceTag);
00389 return serviceTag;
00390 }
00391
00392 void setServiceTagUsingCMOSToken(const char *newTag, size_t len)
00393 {
00394 smbios::ITokenTable *table = 0;
00395 table = smbios::TokenTableFactory::getFactory()->getSingleton();
00396
00397 if (0 == table)
00398 {
00399 throw InternalErrorImpl();
00400 }
00401
00402 try
00403 {
00404
00405
00406 char codedTag[SVC_TAG_LEN_MAX + 1] = {0,};
00407
00408 strncpy(codedTag, newTag, len < SVC_TAG_LEN_MAX ? len : SVC_TAG_LEN_MAX);
00409
00410 dell_encode_service_tag(codedTag, len);
00411
00412
00413
00414 (*table)[Cmos_Service_Token]->setString(reinterpret_cast<const u8*>(codedTag), SVC_TAG_CMOS_LEN_MAX);
00415
00416
00417 u16 indexPort, dataPort;
00418 u8 location;
00419
00420 smbios::IToken *token = &(*((*table)[ Cmos_Service_Token ]));
00421 dynamic_cast< smbios::ICmosToken * >(token)->getCMOSDetails( &indexPort, &dataPort, &location );
00422
00423 u8 csum = 0;
00424 ICmosRW *cmos = cmos::CmosRWFactory::getFactory()->getSingleton();
00425
00426 for( u32 i = 0; i < SVC_TAG_CMOS_LEN_MAX; i++)
00427 {
00428
00429 csum = (csum + cmos->readByte( indexPort, dataPort, location + i )) & 0xFF;
00430 }
00431
00432 cmos->writeByte(
00433 indexPort,
00434 dataPort,
00435 location + SVC_TAG_CMOS_LEN_MAX,
00436 csum
00437 );
00438 }
00439 catch( const smbios::IException & )
00440 {
00441 throw;
00442 }
00443
00444 }
00445
00446
00447
00448
00449
00450 void setServiceTagUsingSMI(const char *newTag, size_t size)
00451 {
00452 (void) size;
00453 setTagUsingSMI( newTag, 3 );
00454 }
00455
00456
00457 struct DellSetServiceTagFunctions
00458 {
00459 void (*f_ptr)(const char *, size_t);
00460 }
00461
00462 DellSetServiceTagFunctions[] = {
00463 {&setServiceTagUsingSMI,},
00464 {&setServiceTagUsingCMOSToken,},
00465 };
00466
00467 int SMBIOSSetServiceTag(const char *password, const char *serviceTag, size_t len)
00468 {
00469 int retval = -1;
00470 int numEntries =
00471 sizeof (DellSetServiceTagFunctions) / sizeof (DellSetServiceTagFunctions[0]);
00472
00473 if(password)
00474 biosPassword = password;
00475
00476 for (int i = 0; (i < numEntries); ++i)
00477 {
00478
00479 try
00480 {
00481
00482 DellSetServiceTagFunctions[i].f_ptr (serviceTag, len);
00483 retval = 0;
00484 }
00485 catch(const smbios::IException &e)
00486 {
00487 SysInfoException.setMessageString(e.what());
00488 }
00489 catch(...)
00490 {
00491 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00492 }
00493 }
00494 return retval;
00495 }
00496
00497 static char *getAssetTagFromSysEncl()
00498 {
00499 return getStringFromTable(System_Enclosure_or_Chassis, System_Enclosure_or_Chassis_Asset_Offset);
00500 }
00501
00502 static char *getAssetTagFromToken()
00503 {
00504 smbios::ITokenTable *table = 0;
00505 table = smbios::TokenTableFactory::getFactory()->getSingleton();
00506
00507 if (0 == table)
00508 {
00509 throw InternalErrorImpl();
00510 }
00511
00512 u8 *tempval = 0;
00513 try
00514 {
00515 tempval = new u8[ASSET_TAG_LEN_MAX + 1];
00516 memset(tempval, '\0', ASSET_TAG_LEN_MAX + 1);
00517 (*table)[Cmos_Asset_Token]->getString(tempval, ASSET_TAG_LEN_MAX + 1);
00518
00519
00520 u16 indexPort, dataPort;
00521 u8 location;
00522
00523 smbios::IToken *token = &(*((*table)[ Cmos_Asset_Token ]));
00524 dynamic_cast< smbios::ICmosToken * >(token)->getCMOSDetails( &indexPort, &dataPort, &location );
00525
00526 u8 csum = 0;
00527 ICmosRW *cmos = cmos::CmosRWFactory::getFactory()->getSingleton();
00528
00529 for( u32 i = 0; i < ASSET_TAG_CMOS_LEN_MAX; i++)
00530 {
00531
00532 csum = (csum + cmos->readByte( indexPort, dataPort, location + i )) & 0xFF;
00533 }
00534
00535
00536 csum = (csum - cmos->readByte( indexPort, dataPort, location + ASSET_TAG_CMOS_LEN_MAX )) & 0xFF;
00537 if( csum )
00538 throw "Bad checksum";
00539 }
00540 catch (...)
00541 {
00542 delete [] tempval;
00543 throw;
00544 }
00545
00546 return reinterpret_cast<char*>(tempval);
00547 }
00548
00549 char *getAssetTagFromSMI()
00550 {
00551 return getTagFromSMI( 0 );
00552 }
00553
00554
00555 struct DellAssetTagFunctions
00556 {
00557 char *(*f_ptr)();
00558 }
00559
00560
00561 DellAssetTagFunctions[] = {
00562 {&getAssetTagFromSMI,},
00563 {&getAssetTagFromToken,},
00564 {&getAssetTagFromSysEncl,},
00565 };
00566
00567 const char *SMBIOSGetAssetTag()
00568 {
00569 char *assetTag = 0;
00570 int numEntries =
00571 sizeof (DellAssetTagFunctions) / sizeof (DellAssetTagFunctions[0]);
00572
00573 for (int i = 0; (i < numEntries) && (!assetTag); ++i)
00574 {
00575
00576 try
00577 {
00578
00579 assetTag = DellAssetTagFunctions[i].f_ptr ();
00580 }
00581 catch(const smbios::IException &e)
00582 {
00583 SysInfoException.setMessageString(e.what());
00584 }
00585 catch(...)
00586 {
00587 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00588 }
00589 }
00590 stripString(assetTag);
00591 return assetTag;
00592 }
00593
00594
00595
00596 void setAssetTagUsingCMOSToken(const char *newTag, size_t len)
00597 {
00598 smbios::ITokenTable *table = 0;
00599 table = smbios::TokenTableFactory::getFactory()->getSingleton();
00600
00601 if (0 == table)
00602 {
00603 throw InternalErrorImpl();
00604 }
00605
00606 try
00607 {
00608
00609 (*table)[Cmos_Asset_Token]->setString(reinterpret_cast<const u8*>(newTag), len < ASSET_TAG_CMOS_LEN_MAX? len : ASSET_TAG_CMOS_LEN_MAX);
00610
00611
00612 u16 indexPort, dataPort;
00613 u8 location;
00614
00615 smbios::IToken *token = &(*((*table)[ Cmos_Asset_Token ]));
00616 dynamic_cast< smbios::ICmosToken * >(token)->getCMOSDetails( &indexPort, &dataPort, &location );
00617
00618 u8 csum = 0;
00619 ICmosRW *cmos = cmos::CmosRWFactory::getFactory()->getSingleton();
00620
00621 for( u32 i = 0; i < ASSET_TAG_CMOS_LEN_MAX; i++)
00622 {
00623
00624 csum = (csum + cmos->readByte( indexPort, dataPort, location + i )) & 0xFF;
00625 }
00626
00627 cmos->writeByte(
00628 indexPort,
00629 dataPort,
00630 location + ASSET_TAG_CMOS_LEN_MAX,
00631 csum
00632 );
00633 }
00634 catch( const smbios::IException & )
00635 {
00636 throw;
00637 }
00638
00639 }
00640
00641 void setAssetTagUsingSMI(const char *newTag, size_t size)
00642 {
00643 (void) size;
00644 setTagUsingSMI( newTag, 1 );
00645 }
00646
00647
00648 struct DellSetAssetTagFunctions
00649 {
00650 void (*f_ptr)(const char *, size_t);
00651 const char * desc;
00652 }
00653
00654 DellSetAssetTagFunctions[] = {
00655 {&setAssetTagUsingSMI, "SMI"},
00656 {&setAssetTagUsingCMOSToken, "CMOS"},
00657 };
00658
00659 int SMBIOSSetAssetTag(const char *password, const char *assetTag, size_t len)
00660 {
00661 int retval = -1;
00662 int numEntries =
00663 sizeof (DellSetAssetTagFunctions) / sizeof (DellSetAssetTagFunctions[0]);
00664
00665 if(password)
00666 biosPassword = password;
00667
00668 for (int i = 0; (i < numEntries); ++i)
00669 {
00670
00671 try
00672 {
00673
00674 DellSetAssetTagFunctions[i].f_ptr (assetTag, len);
00675 retval = 0;
00676 }
00677 catch(const smbios::IException &e)
00678 {
00679 SysInfoException.setMessageString(e.what());
00680 }
00681 catch(...)
00682 {
00683 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00684 }
00685 }
00686 return retval;
00687 }
00688
00689
00690 static char *getSystemNameFromSysInfo()
00691 {
00692 return getStringFromTable(System_Information, System_Information_Product_Name_Offset);
00693 }
00694
00695
00696 struct DellSystemNameFunctions
00697 {
00698 char *(*f_ptr)();
00699 }
00700
00701 DellSystemNameFunctions[] = {
00702 {&getSystemNameFromSysInfo,}
00703 };
00704
00705 const char *SMBIOSGetSystemName()
00706 {
00707 char *systemName= 0;
00708 int numEntries =
00709 sizeof (DellSystemNameFunctions) / sizeof (DellSystemNameFunctions[0]);
00710
00711 for (int i = 0; (i < numEntries) && (!systemName); ++i)
00712 {
00713
00714 try
00715 {
00716
00717 systemName = DellSystemNameFunctions[i].f_ptr ();
00718 }
00719 catch(const smbios::IException &e)
00720 {
00721 SysInfoException.setMessageString(e.what());
00722 }
00723 catch(...)
00724 {
00725 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00726 }
00727 }
00728
00729 stripString(systemName);
00730 return systemName;
00731 }
00732
00733
00734 static char *getBiosVersionFromOneByteStructForDiamond()
00735 {
00736 memory::IMemory *mem = 0;
00737 u8 strBuf[DELL_SYSTEM_STRING_LEN] = { 0, };
00738 u8 *biosVersion = 0;
00739
00740 mem = memory::MemoryFactory::getFactory()->getSingleton();
00741
00742 if( 0 == mem )
00743 throw InternalErrorImpl();
00744
00745
00746 mem->fillBuffer( strBuf, DELL_SYSTEM_STRING_LOC_DIAMOND_1, DELL_SYSTEM_STRING_LEN - 1 );
00747 if( strncmp( reinterpret_cast<char*>(strBuf), DELL_SYSTEM_STRING, DELL_SYSTEM_STRING_LEN ) == 0 )
00748 if( SYSTEM_ID_DIAMOND == mem->getByte( ID_BYTE_LOC_DIAMOND_1 ) )
00749 {
00750 biosVersion = new u8[4];
00751 mem->fillBuffer(biosVersion, ID_BYTE_LOC_DIAMOND_1 + 1, 3);
00752 biosVersion[3] = '\0';
00753 }
00754
00755 mem->fillBuffer( strBuf, DELL_SYSTEM_STRING_LOC_DIAMOND_2, DELL_SYSTEM_STRING_LEN - 1 );
00756 if( strncmp( reinterpret_cast<char*>(strBuf), DELL_SYSTEM_STRING, DELL_SYSTEM_STRING_LEN ) == 0 )
00757 if( SYSTEM_ID_DIAMOND == mem->getByte( ID_BYTE_LOC_DIAMOND_2 ) )
00758 {
00759 biosVersion = new u8[4];
00760 mem->fillBuffer(biosVersion, ID_BYTE_LOC_DIAMOND_2 + 1, 3);
00761 biosVersion[3] = '\0';
00762 }
00763
00764 return reinterpret_cast<char*>(biosVersion);
00765 }
00766
00767 static char *getBiosVersionFromSmbios()
00768 {
00769 return getStringFromTable(BIOS_Information, BIOS_Information_Version_Offset);
00770 }
00771
00772
00773 struct DellBiosVersionFunctions
00774 {
00775 char *(*f_ptr)();
00776 }
00777 DellBiosVersionFunctions[] = {
00778 {&getBiosVersionFromOneByteStructForDiamond,},
00779 {&getBiosVersionFromSmbios,}
00780 };
00781
00782 const char *SMBIOSGetBiosVersion()
00783 {
00784 char *systemName= 0;
00785 int numEntries =
00786 sizeof (DellBiosVersionFunctions) / sizeof (DellBiosVersionFunctions[0]);
00787
00788 for (int i = 0; (i < numEntries) && (!systemName); ++i)
00789 {
00790
00791 try
00792 {
00793
00794 systemName = DellBiosVersionFunctions[i].f_ptr ();
00795 }
00796 catch(const smbios::IException &e)
00797 {
00798 SysInfoException.setMessageString(e.what());
00799 }
00800 catch(...)
00801 {
00802 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00803 }
00804 }
00805
00806 stripString(systemName);
00807 return systemName;
00808 }
00809
00810
00811 const char *SMBIOSGetVendorName()
00812 {
00813 char *retval = 0;
00814
00815 try
00816 {
00817 retval = getStringFromTable(System_Information, System_Information_Manufacturer_Offset);
00818 }
00819 catch(const smbios::IException &e)
00820 {
00821 SysInfoException.setMessageString(e.what());
00822 }
00823 catch(...)
00824 {
00825 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00826 }
00827
00828 stripString(retval);
00829 return retval;
00830 }
00831
00832
00833 int SMBIOSHasNvramStateBytes()
00834 {
00835 int retval = 1;
00836 try
00837 {
00838 smbios::TokenTableFactory *ttFactory = smbios::TokenTableFactory::getFactory() ;
00839 smbios::ITokenTable *tokenTable = ttFactory->getSingleton();
00840
00841 u8 tempData[2] = {0,0};
00842 (*tokenTable)[ NvramByte1_Token ]->getString( tempData, 2 );
00843 (*tokenTable)[ NvramByte2_Token ]->getString( tempData, 2 );
00844 }
00845 catch(const smbios::IException &e)
00846 {
00847 SysInfoException.setMessageString(e.what());
00848 retval = 0;
00849 }
00850 catch(...)
00851 {
00852 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00853 }
00854
00855 return retval;
00856 }
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869 int SMBIOSGetNvramStateBytes( int user )
00870 {
00871 u8 tempData[2] = {0,0};
00872 int retval = 0;
00873 try
00874 {
00875 smbios::TokenTableFactory *ttFactory = smbios::TokenTableFactory::getFactory() ;
00876 smbios::ITokenTable *tokenTable = ttFactory->getSingleton();
00877
00878 (*tokenTable)[ NvramByte1_Token ]->getString( tempData, 2 );
00879 retval = *tempData;
00880 (*tokenTable)[ NvramByte2_Token ]->getString( tempData, 2 );
00881 retval |= (*tempData << 8);
00882 }
00883 catch(const smbios::IException &e)
00884 {
00885 SysInfoException.setMessageString(e.what());
00886 }
00887 catch(...)
00888 {
00889 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00890 }
00891
00892 if( user == 0x0000 )
00893 {
00894 if( (retval & 0x8000) != user )
00895 {
00896 retval = 0;
00897 }
00898 retval &= ~0x8000;
00899 }
00900 else
00901 {
00902 if ((user & 0xF000) == 0xF000 )
00903 {
00904 if( (retval & 0xFF00) != user )
00905 {
00906 retval = 0;
00907 }
00908 retval &= ~0xFF00;
00909 }
00910 else
00911 {
00912 if( (retval & 0xF000) != user )
00913 {
00914 retval = 0;
00915 }
00916 retval &= ~0xF000;
00917 }
00918 }
00919 return retval;
00920 }
00921
00922 void SMBIOSSetNvramStateBytes(int value, int user)
00923 {
00924 try
00925 {
00926 if ( user == 0x0000 )
00927 {
00928 value &= ~0x8000;
00929 value |= user;
00930 }
00931 else if( (user & 0xF000) == 0xF000 )
00932 {
00933 value &= ~0xFF00;
00934 value |= user;
00935 }
00936 else
00937 {
00938 value &= ~0xF000;
00939 value |= user;
00940 }
00941
00942 smbios::TokenTableFactory *ttFactory = smbios::TokenTableFactory::getFactory() ;
00943 smbios::ITokenTable *tokenTable = ttFactory->getSingleton();
00944
00945 u8 *tempData = reinterpret_cast<u8*>(&value);
00946 (*tokenTable)[ NvramByte1_Token ]->setString( tempData, 1 );
00947 (*tokenTable)[ NvramByte2_Token ]->setString( tempData+1, 1 );
00948 }
00949 catch(const smbios::IException &e)
00950 {
00951 SysInfoException.setMessageString(e.what());
00952 }
00953 catch(...)
00954 {
00955 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00956 }
00957 return;
00958 }
00959
00960
00961 static bool getUpOffsetAndFlag (up_info *up)
00962 {
00963 memory::IMemory *mem =
00964 memory::MemoryFactory::getFactory()->getSingleton();
00965
00966 up_info tempUP;
00967 memset(&tempUP, 0, sizeof(tempUP));
00968 int step_size = 16;
00969
00970 unsigned int fp = 0xF0000;
00971 bool found = false;
00972 while( fp < (0xFFFFFUL - sizeof(tempUP)) )
00973 {
00974 mem->fillBuffer(
00975 reinterpret_cast<u8 *>(&tempUP),
00976 fp,
00977 sizeof(tempUP)
00978 );
00979
00980 if ( 0 == memcmp( &(tempUP.anchor), "_UP_", 4))
00981 {
00982 found = true;
00983 break;
00984 }
00985
00986 fp += step_size;
00987
00988
00989 if( step_size > 1 && fp >= (0xFFFFFUL - sizeof(tempUP)) )
00990 {
00991 step_size = 1;
00992 fp = 0xF0000;
00993 }
00994 }
00995
00996 if( found )
00997 memcpy( up, &tempUP, sizeof(tempUP) );
00998
00999 return found;
01000 }
01001
01002 static int upBootHelper(bool set
01003 =false, bool value=false)
01004 {
01005
01006
01007
01008
01009 int retval = 0;
01010 const u8 *buf = 0;
01011
01012 up_info up;
01013 memset( reinterpret_cast<u8*>(&up), 0, sizeof(up));
01014 try
01015 {
01016 bool found = getUpOffsetAndFlag( &up );
01017
01018 if( !found )
01019 goto out;
01020
01021 smbios::TokenTableFactory *ttFactory = smbios::TokenTableFactory::getFactory() ;
01022 smbios::ITokenTable *tokenTable = ttFactory->getSingleton();
01023 size_t length;
01024 buf = (*tokenTable)[ NvramByte2_Token ]->getItemRef().getBufferCopy(length);
01025
01026 const indexed_io_access_structure *io_struct =
01027 reinterpret_cast<const indexed_io_access_structure *>(buf);
01028
01029 cmos::ICmosRW *cmos = cmos::CmosRWFactory::getFactory()->getSingleton();
01030
01031 u8 byte = cmos->readByte( io_struct->indexPort, io_struct->dataPort, up.offset );
01032
01033 if( set
01034 )
01035 {
01036
01037 byte |= up.flag;
01038 retval = 1;
01039 if (!value)
01040 {
01041 byte &= ~up.flag;
01042 }
01043 cmos->writeByte( io_struct->indexPort, io_struct->dataPort, up.offset, byte );
01044 }
01045 else
01046 {
01047 if( (byte & up.flag) == up.flag )
01048 retval = 3;
01049
01050 if( (byte & up.flag) != up.flag )
01051 retval = 2;
01052 }
01053
01054 }
01055 catch(const smbios::IException &e)
01056 {
01057 SysInfoException.setMessageString(e.what());
01058 }
01059 catch(...)
01060 {
01061 SysInfoException.setMessageString( _("Unknown internal error occurred") );
01062 }
01063
01064 delete [] const_cast<u8 *>(buf);
01065 buf = 0;
01066
01067 out:
01068 return retval;
01069 }
01070
01071 int SMBIOSHasBootToUp()
01072 {
01073 return upBootHelper();
01074 }
01075
01076 int SMBIOSGetBootToUp()
01077 {
01078 int retval = upBootHelper();
01079 retval -= 2;
01080 return retval;
01081 }
01082
01083 void SMBIOSSetBootToUp(int state)
01084 {
01085 bool value = (state == 1) ? true: false;
01086 upBootHelper(true, value);
01087 }
01088
01089
01090 int SMBIOSGetSmiPasswordCoding()
01091 {
01092 int fmt=0;
01093 try
01094 {
01095 fmt = smi::getPasswordFormat();
01096 }
01097 catch(const exception &)
01098 {}
01099
01100 return fmt;
01101 }
01102