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 "ExceptionImpl.h"
00028 #include "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 tempval = getString_FromItem(*(*table)[structure], stringNumber);
00248
00249 if(!tempval)
00250 throw exception();
00251
00252 size_t slen = strlen(tempval);
00253 char *retval = new char[slen + 1];
00254 strncpy(retval,tempval,slen);
00255 retval[slen] = '\0';
00256
00257 stripString(retval);
00258 if ( ! strlen(retval ))
00259 {
00260 delete [] retval;
00261 retval = 0;
00262 throw exception();
00263 }
00264
00265 return retval;
00266 }
00267
00268 static char *getServiceTagFromSysInfo()
00269 {
00270 DCOUT( "in getServiceTagFromSysInfo()" << endl);
00271 return getStringFromTable(System_Information, System_Information_Serial_Number_Offset);
00272 }
00273
00274 static char *getServiceTagFromSysEncl()
00275 {
00276 DCOUT( "in getServiceTagFromSysEncl()" << endl);
00277 return getStringFromTable(System_Enclosure_or_Chassis, System_Enclosure_or_Chassis_Service_Offset);
00278 }
00279
00280
00281 char *getServiceTagFromCMOSToken()
00282 {
00283 smbios::ITokenTable *table = 0;
00284 table = smbios::TokenTableFactory::getFactory()->getSingleton();
00285
00286 DCOUT( "in getServiceTagFromCMOSToken()" << endl);
00287
00288 if (0 == table)
00289 {
00290 throw InternalErrorImpl();
00291 }
00292
00293 char *tempval = 0;
00294 try
00295 {
00296
00297 tempval = new char[SVC_TAG_LEN_MAX + 1];
00298 memset(tempval, '\0', SVC_TAG_LEN_MAX + 1);
00299
00300 (*table)[Cmos_Service_Token]->getString(reinterpret_cast<u8*>(tempval), SVC_TAG_CMOS_LEN_MAX + 1);
00301
00302
00303 dell_decode_service_tag( tempval, SVC_TAG_LEN_MAX + 1 );
00304
00305
00306 u16 indexPort, dataPort;
00307 u8 location;
00308
00309 smbios::IToken *token = &(*((*table)[ Cmos_Service_Token ]));
00310 dynamic_cast< smbios::ICmosToken * >(token)->getCMOSDetails( &indexPort, &dataPort, &location );
00311
00312 u8 csum = 0;
00313 ICmosRW *cmos = cmos::CmosRWFactory::getFactory()->getSingleton();
00314
00315 for( u32 i = 0; i < SVC_TAG_CMOS_LEN_MAX; i++)
00316 {
00317
00318 csum = (csum + cmos->readByte( indexPort, dataPort, location + i )) & 0xFF;
00319 }
00320
00321
00322 csum = (csum - cmos->readByte( indexPort, dataPort, location + SVC_TAG_CMOS_LEN_MAX )) & 0xFF;
00323 if( csum )
00324 throw "Bad checksum";
00325 }
00326 catch( ... )
00327 {
00328 delete [] tempval;
00329 throw;
00330 }
00331
00332 return tempval;
00333 }
00334
00335
00336 char *getServiceTagFromSMI()
00337 {
00338 DCOUT( "in getServiceTagFromSMI()" << endl);
00339 return getTagFromSMI( 2 );
00340 }
00341
00342
00343 struct DellGetServiceTagFunctions
00344 {
00345 char *(*f_ptr)();
00346 }
00347
00348
00349 DellGetServiceTagFunctions[] = {
00350 {&getServiceTagFromSMI,},
00351 {&getServiceTagFromCMOSToken,},
00352 {&getServiceTagFromSysInfo,},
00353 {&getServiceTagFromSysEncl,},
00354 };
00355
00356 const char *SMBIOSGetServiceTag()
00357 {
00358 char *serviceTag = 0;
00359 int numEntries =
00360 sizeof (DellGetServiceTagFunctions) / sizeof (DellGetServiceTagFunctions[0]);
00361
00362 DCOUT( "numEntries: " << numEntries << endl);
00363
00364 for (int i = 0; (i < numEntries) && (!serviceTag); ++i)
00365 {
00366
00367 try
00368 {
00369 DCOUT(" try #" << i << endl);
00370
00371 serviceTag = DellGetServiceTagFunctions[i].f_ptr ();
00372 }
00373 catch(const exception &e)
00374 {
00375 DCOUT(" Caught exception: " << e.what() << endl);
00376 SysInfoException.setMessageString(e.what());
00377 }
00378 catch(...)
00379 {
00380 DCOUT(" Caught unknown exception" << endl);
00381 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00382 }
00383
00384 if(serviceTag)
00385 DCOUT( " GOT TAG: -->" << serviceTag << "<--" << endl);
00386 }
00387 stripString(serviceTag);
00388 return serviceTag;
00389 }
00390
00391 void setServiceTagUsingCMOSToken(const char *newTag, size_t len)
00392 {
00393 smbios::ITokenTable *table = 0;
00394 table = smbios::TokenTableFactory::getFactory()->getSingleton();
00395
00396 if (0 == table)
00397 {
00398 throw InternalErrorImpl();
00399 }
00400
00401 try
00402 {
00403
00404
00405 char codedTag[SVC_TAG_LEN_MAX + 1] = {0,};
00406
00407 strncpy(codedTag, newTag, len < SVC_TAG_LEN_MAX ? len : SVC_TAG_LEN_MAX);
00408
00409 dell_encode_service_tag(codedTag, len);
00410
00411
00412
00413 (*table)[Cmos_Service_Token]->setString(reinterpret_cast<const u8*>(codedTag), SVC_TAG_CMOS_LEN_MAX);
00414
00415
00416 u16 indexPort, dataPort;
00417 u8 location;
00418
00419 smbios::IToken *token = &(*((*table)[ Cmos_Service_Token ]));
00420 dynamic_cast< smbios::ICmosToken * >(token)->getCMOSDetails( &indexPort, &dataPort, &location );
00421
00422 u8 csum = 0;
00423 ICmosRW *cmos = cmos::CmosRWFactory::getFactory()->getSingleton();
00424
00425 for( u32 i = 0; i < SVC_TAG_CMOS_LEN_MAX; i++)
00426 {
00427
00428 csum = (csum + cmos->readByte( indexPort, dataPort, location + i )) & 0xFF;
00429 }
00430
00431 cmos->writeByte(
00432 indexPort,
00433 dataPort,
00434 location + SVC_TAG_CMOS_LEN_MAX,
00435 csum
00436 );
00437 }
00438 catch( const smbios::IException & )
00439 {
00440 throw;
00441 }
00442
00443 }
00444
00445
00446
00447
00448
00449 void setServiceTagUsingSMI(const char *newTag, size_t size)
00450 {
00451 (void) size;
00452 setTagUsingSMI( newTag, 3 );
00453 }
00454
00455
00456 struct DellSetServiceTagFunctions
00457 {
00458 void (*f_ptr)(const char *, size_t);
00459 }
00460
00461 DellSetServiceTagFunctions[] = {
00462 {&setServiceTagUsingSMI,},
00463 {&setServiceTagUsingCMOSToken,},
00464 };
00465
00466 int SMBIOSSetServiceTag(const char *password, const char *serviceTag, size_t len)
00467 {
00468 int retval = -1;
00469 int numEntries =
00470 sizeof (DellSetServiceTagFunctions) / sizeof (DellSetServiceTagFunctions[0]);
00471
00472 if(password)
00473 biosPassword = password;
00474
00475 for (int i = 0; (i < numEntries); ++i)
00476 {
00477
00478 try
00479 {
00480
00481 DellSetServiceTagFunctions[i].f_ptr (serviceTag, len);
00482 retval = 0;
00483 }
00484 catch(const smbios::IException &e)
00485 {
00486 SysInfoException.setMessageString(e.what());
00487 }
00488 catch(...)
00489 {
00490 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00491 }
00492 }
00493 return retval;
00494 }
00495
00496 static char *getAssetTagFromSysEncl()
00497 {
00498 return getStringFromTable(System_Enclosure_or_Chassis, System_Enclosure_or_Chassis_Asset_Offset);
00499 }
00500
00501
00502
00503 char *getAssetTagFromToken()
00504 {
00505 smbios::ITokenTable *table = 0;
00506 table = smbios::TokenTableFactory::getFactory()->getSingleton();
00507
00508 if (0 == table)
00509 {
00510 throw InternalErrorImpl();
00511 }
00512
00513 u8 *tempval = 0;
00514 try
00515 {
00516 tempval = new u8[ASSET_TAG_LEN_MAX + 1];
00517 memset(tempval, '\0', ASSET_TAG_LEN_MAX + 1);
00518 (*table)[Cmos_Asset_Token]->getString(tempval, ASSET_TAG_LEN_MAX + 1);
00519
00520
00521 u16 indexPort, dataPort;
00522 u8 location;
00523
00524 smbios::IToken *token = &(*((*table)[ Cmos_Asset_Token ]));
00525 dynamic_cast< smbios::ICmosToken * >(token)->getCMOSDetails( &indexPort, &dataPort, &location );
00526
00527 u8 csum = 0;
00528 ICmosRW *cmos = cmos::CmosRWFactory::getFactory()->getSingleton();
00529
00530 for( u32 i = 0; i < ASSET_TAG_CMOS_LEN_MAX; i++)
00531 {
00532
00533 csum = (csum + cmos->readByte( indexPort, dataPort, location + i )) & 0xFF;
00534 }
00535
00536
00537 csum = (csum - cmos->readByte( indexPort, dataPort, location + ASSET_TAG_CMOS_LEN_MAX )) & 0xFF;
00538 if( csum )
00539 throw "Bad checksum";
00540 }
00541 catch (...)
00542 {
00543 delete [] tempval;
00544 throw;
00545 }
00546
00547 return reinterpret_cast<char*>(tempval);
00548 }
00549
00550 char *getAssetTagFromSMI()
00551 {
00552 return getTagFromSMI( 0 );
00553 }
00554
00555
00556 struct DellAssetTagFunctions
00557 {
00558 char *(*f_ptr)();
00559 }
00560
00561
00562 DellAssetTagFunctions[] = {
00563 {&getAssetTagFromSMI,},
00564 {&getAssetTagFromToken,},
00565 {&getAssetTagFromSysEncl,},
00566 };
00567
00568 const char *SMBIOSGetAssetTag()
00569 {
00570 char *assetTag = 0;
00571 int numEntries =
00572 sizeof (DellAssetTagFunctions) / sizeof (DellAssetTagFunctions[0]);
00573
00574 for (int i = 0; (i < numEntries) && (!assetTag); ++i)
00575 {
00576
00577 try
00578 {
00579
00580 assetTag = DellAssetTagFunctions[i].f_ptr ();
00581 }
00582 catch(const smbios::IException &e)
00583 {
00584 SysInfoException.setMessageString(e.what());
00585 }
00586 catch(...)
00587 {
00588 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00589 }
00590 }
00591 stripString(assetTag);
00592 return assetTag;
00593 }
00594
00595
00596
00597 void setAssetTagUsingCMOSToken(const char *newTag, size_t len)
00598 {
00599 smbios::ITokenTable *table = 0;
00600 table = smbios::TokenTableFactory::getFactory()->getSingleton();
00601
00602 if (0 == table)
00603 {
00604 throw InternalErrorImpl();
00605 }
00606
00607 try
00608 {
00609
00610 (*table)[Cmos_Asset_Token]->setString(reinterpret_cast<const u8*>(newTag), len < ASSET_TAG_CMOS_LEN_MAX? len : ASSET_TAG_CMOS_LEN_MAX);
00611
00612
00613 u16 indexPort, dataPort;
00614 u8 location;
00615
00616 smbios::IToken *token = &(*((*table)[ Cmos_Asset_Token ]));
00617 dynamic_cast< smbios::ICmosToken * >(token)->getCMOSDetails( &indexPort, &dataPort, &location );
00618
00619 u8 csum = 0;
00620 ICmosRW *cmos = cmos::CmosRWFactory::getFactory()->getSingleton();
00621
00622 for( u32 i = 0; i < ASSET_TAG_CMOS_LEN_MAX; i++)
00623 {
00624
00625 csum = (csum + cmos->readByte( indexPort, dataPort, location + i )) & 0xFF;
00626 }
00627
00628 cmos->writeByte(
00629 indexPort,
00630 dataPort,
00631 location + ASSET_TAG_CMOS_LEN_MAX,
00632 csum
00633 );
00634 }
00635 catch( const smbios::IException & )
00636 {
00637 throw;
00638 }
00639
00640 }
00641
00642 void setAssetTagUsingSMI(const char *newTag, size_t size)
00643 {
00644 (void) size;
00645 setTagUsingSMI( newTag, 1 );
00646 }
00647
00648
00649 struct DellSetAssetTagFunctions
00650 {
00651 void (*f_ptr)(const char *, size_t);
00652 const char * desc;
00653 }
00654
00655 DellSetAssetTagFunctions[] = {
00656 {&setAssetTagUsingSMI, "SMI"},
00657 {&setAssetTagUsingCMOSToken, "CMOS"},
00658 };
00659
00660 int SMBIOSSetAssetTag(const char *password, const char *assetTag, size_t len)
00661 {
00662 int retval = -1;
00663 int numEntries =
00664 sizeof (DellSetAssetTagFunctions) / sizeof (DellSetAssetTagFunctions[0]);
00665
00666 if(password)
00667 biosPassword = password;
00668
00669 for (int i = 0; (i < numEntries); ++i)
00670 {
00671
00672 try
00673 {
00674
00675 DellSetAssetTagFunctions[i].f_ptr (assetTag, len);
00676 retval = 0;
00677 }
00678 catch(const smbios::IException &e)
00679 {
00680 SysInfoException.setMessageString(e.what());
00681 }
00682 catch(...)
00683 {
00684 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00685 }
00686 }
00687 return retval;
00688 }
00689
00690
00691 static char *getSystemNameFromSysInfo()
00692 {
00693 return getStringFromTable(System_Information, System_Information_Product_Name_Offset);
00694 }
00695
00696
00697 struct DellSystemNameFunctions
00698 {
00699 char *(*f_ptr)();
00700 }
00701
00702 DellSystemNameFunctions[] = {
00703 {&getSystemNameFromSysInfo,}
00704 };
00705
00706 const char *SMBIOSGetSystemName()
00707 {
00708 char *systemName= 0;
00709 int numEntries =
00710 sizeof (DellSystemNameFunctions) / sizeof (DellSystemNameFunctions[0]);
00711
00712 for (int i = 0; (i < numEntries) && (!systemName); ++i)
00713 {
00714
00715 try
00716 {
00717
00718 systemName = DellSystemNameFunctions[i].f_ptr ();
00719 }
00720 catch(const smbios::IException &e)
00721 {
00722 SysInfoException.setMessageString(e.what());
00723 }
00724 catch(...)
00725 {
00726 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00727 }
00728 }
00729
00730 stripString(systemName);
00731 return systemName;
00732 }
00733
00734
00735 static char *getBiosVersionFromOneByteStructForDiamond()
00736 {
00737 memory::IMemory *mem = 0;
00738 u8 strBuf[DELL_SYSTEM_STRING_LEN] = { 0, };
00739 u8 *biosVersion = 0;
00740
00741 mem = memory::MemoryFactory::getFactory()->getSingleton();
00742
00743 if( 0 == mem )
00744 throw InternalErrorImpl();
00745
00746
00747 mem->fillBuffer( strBuf, DELL_SYSTEM_STRING_LOC_DIAMOND_1, DELL_SYSTEM_STRING_LEN - 1 );
00748 if( strncmp( reinterpret_cast<char*>(strBuf), DELL_SYSTEM_STRING, DELL_SYSTEM_STRING_LEN ) == 0 )
00749 if( SYSTEM_ID_DIAMOND == mem->getByte( ID_BYTE_LOC_DIAMOND_1 ) )
00750 {
00751 biosVersion = new u8[4];
00752 mem->fillBuffer(biosVersion, ID_BYTE_LOC_DIAMOND_1 + 1, 3);
00753 biosVersion[3] = '\0';
00754 }
00755
00756 mem->fillBuffer( strBuf, DELL_SYSTEM_STRING_LOC_DIAMOND_2, DELL_SYSTEM_STRING_LEN - 1 );
00757 if( strncmp( reinterpret_cast<char*>(strBuf), DELL_SYSTEM_STRING, DELL_SYSTEM_STRING_LEN ) == 0 )
00758 if( SYSTEM_ID_DIAMOND == mem->getByte( ID_BYTE_LOC_DIAMOND_2 ) )
00759 {
00760 biosVersion = new u8[4];
00761 mem->fillBuffer(biosVersion, ID_BYTE_LOC_DIAMOND_2 + 1, 3);
00762 biosVersion[3] = '\0';
00763 }
00764
00765 return reinterpret_cast<char*>(biosVersion);
00766 }
00767
00768 static char *getBiosVersionFromSmbios()
00769 {
00770 return getStringFromTable(BIOS_Information, BIOS_Information_Version_Offset);
00771 }
00772
00773
00774 struct DellBiosVersionFunctions
00775 {
00776 char *(*f_ptr)();
00777 }
00778 DellBiosVersionFunctions[] = {
00779 {&getBiosVersionFromOneByteStructForDiamond,},
00780 {&getBiosVersionFromSmbios,}
00781 };
00782
00783 const char *SMBIOSGetBiosVersion()
00784 {
00785 char *systemName= 0;
00786 int numEntries =
00787 sizeof (DellBiosVersionFunctions) / sizeof (DellBiosVersionFunctions[0]);
00788
00789 for (int i = 0; (i < numEntries) && (!systemName); ++i)
00790 {
00791
00792 try
00793 {
00794
00795 systemName = DellBiosVersionFunctions[i].f_ptr ();
00796 }
00797 catch(const smbios::IException &e)
00798 {
00799 SysInfoException.setMessageString(e.what());
00800 }
00801 catch(...)
00802 {
00803 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00804 }
00805 }
00806
00807 stripString(systemName);
00808 return systemName;
00809 }
00810
00811
00812 const char *SMBIOSGetVendorName()
00813 {
00814 char *retval = 0;
00815
00816 try
00817 {
00818 retval = getStringFromTable(System_Information, System_Information_Manufacturer_Offset);
00819 }
00820 catch(const smbios::IException &e)
00821 {
00822 SysInfoException.setMessageString(e.what());
00823 }
00824 catch(...)
00825 {
00826 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00827 }
00828
00829 stripString(retval);
00830 return retval;
00831 }
00832
00833
00834 int SMBIOSHasNvramStateBytes()
00835 {
00836 int retval = 1;
00837 try
00838 {
00839 smbios::TokenTableFactory *ttFactory = smbios::TokenTableFactory::getFactory() ;
00840 smbios::ITokenTable *tokenTable = ttFactory->getSingleton();
00841
00842 u8 tempData[2] = {0,0};
00843 (*tokenTable)[ NvramByte1_Token ]->getString( tempData, 2 );
00844 (*tokenTable)[ NvramByte2_Token ]->getString( tempData, 2 );
00845 }
00846 catch(const smbios::IException &e)
00847 {
00848 SysInfoException.setMessageString(e.what());
00849 retval = 0;
00850 }
00851 catch(...)
00852 {
00853 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00854 }
00855
00856 return retval;
00857 }
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870 int SMBIOSGetNvramStateBytes( int user )
00871 {
00872 u8 tempData[2] = {0,0};
00873 int retval = 0;
00874 try
00875 {
00876 smbios::TokenTableFactory *ttFactory = smbios::TokenTableFactory::getFactory() ;
00877 smbios::ITokenTable *tokenTable = ttFactory->getSingleton();
00878
00879 (*tokenTable)[ NvramByte1_Token ]->getString( tempData, 2 );
00880 retval = *tempData;
00881 (*tokenTable)[ NvramByte2_Token ]->getString( tempData, 2 );
00882 retval |= (*tempData << 8);
00883 }
00884 catch(const smbios::IException &e)
00885 {
00886 SysInfoException.setMessageString(e.what());
00887 }
00888 catch(...)
00889 {
00890 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00891 }
00892
00893 if( user == 0x0000 )
00894 {
00895 if( (retval & 0x8000) != user )
00896 {
00897 retval = 0;
00898 }
00899 retval &= ~0x8000;
00900 }
00901 else
00902 {
00903 if ((user & 0xF000) == 0xF000 )
00904 {
00905 if( (retval & 0xFF00) != user )
00906 {
00907 retval = 0;
00908 }
00909 retval &= ~0xFF00;
00910 }
00911 else
00912 {
00913 if( (retval & 0xF000) != user )
00914 {
00915 retval = 0;
00916 }
00917 retval &= ~0xF000;
00918 }
00919 }
00920 return retval;
00921 }
00922
00923 void SMBIOSSetNvramStateBytes(int value, int user)
00924 {
00925 try
00926 {
00927 if ( user == 0x0000 )
00928 {
00929 value &= ~0x8000;
00930 value |= user;
00931 }
00932 else if( (user & 0xF000) == 0xF000 )
00933 {
00934 value &= ~0xFF00;
00935 value |= user;
00936 }
00937 else
00938 {
00939 value &= ~0xF000;
00940 value |= user;
00941 }
00942
00943 smbios::TokenTableFactory *ttFactory = smbios::TokenTableFactory::getFactory() ;
00944 smbios::ITokenTable *tokenTable = ttFactory->getSingleton();
00945
00946 u8 *tempData = reinterpret_cast<u8*>(&value);
00947 (*tokenTable)[ NvramByte1_Token ]->setString( tempData, 1 );
00948 (*tokenTable)[ NvramByte2_Token ]->setString( tempData+1, 1 );
00949 }
00950 catch(const smbios::IException &e)
00951 {
00952 SysInfoException.setMessageString(e.what());
00953 }
00954 catch(...)
00955 {
00956 SysInfoException.setMessageString( _("Unknown internal error occurred") );
00957 }
00958 return;
00959 }
00960
00961
00962 static bool getUpOffsetAndFlag (up_info *up)
00963 {
00964 memory::IMemory *mem =
00965 memory::MemoryFactory::getFactory()->getSingleton();
00966
00967 up_info tempUP;
00968 memset(&tempUP, 0, sizeof(tempUP));
00969 int step_size = 16;
00970
00971 unsigned int fp = 0xF0000;
00972 bool found = false;
00973 while( fp < (0xFFFFFUL - sizeof(tempUP)) )
00974 {
00975 mem->fillBuffer(
00976 reinterpret_cast<u8 *>(&tempUP),
00977 fp,
00978 sizeof(tempUP)
00979 );
00980
00981 if ( 0 == memcmp( &(tempUP.anchor), "_UP_", 4))
00982 {
00983 found = true;
00984 break;
00985 }
00986
00987 fp += step_size;
00988
00989
00990 if( step_size > 1 && fp >= (0xFFFFFUL - sizeof(tempUP)) )
00991 {
00992 step_size = 1;
00993 fp = 0xF0000;
00994 }
00995 }
00996
00997 if( found )
00998 memcpy( up, &tempUP, sizeof(tempUP) );
00999
01000 return found;
01001 }
01002
01003 static int upBootHelper(bool set
01004 =false, bool value=false)
01005 {
01006
01007
01008
01009
01010 int retval = 0;
01011 const u8 *buf = 0;
01012
01013 up_info up;
01014 memset( reinterpret_cast<u8*>(&up), 0, sizeof(up));
01015 try
01016 {
01017 bool found = getUpOffsetAndFlag( &up );
01018
01019 if( !found )
01020 goto out;
01021
01022 smbios::TokenTableFactory *ttFactory = smbios::TokenTableFactory::getFactory() ;
01023 smbios::ITokenTable *tokenTable = ttFactory->getSingleton();
01024 size_t length;
01025 buf = (*tokenTable)[ NvramByte2_Token ]->getItemRef().getBufferCopy(length);
01026
01027 const indexed_io_access_structure *io_struct =
01028 reinterpret_cast<const indexed_io_access_structure *>(buf);
01029
01030 cmos::ICmosRW *cmos = cmos::CmosRWFactory::getFactory()->getSingleton();
01031
01032 u8 byte = cmos->readByte( io_struct->indexPort, io_struct->dataPort, up.offset );
01033
01034 if( set
01035 )
01036 {
01037
01038 byte |= up.flag;
01039 retval = 1;
01040 if (!value)
01041 {
01042 byte &= ~up.flag;
01043 }
01044 cmos->writeByte( io_struct->indexPort, io_struct->dataPort, up.offset, byte );
01045 }
01046 else
01047 {
01048 if( (byte & up.flag) == up.flag )
01049 retval = 3;
01050
01051 if( (byte & up.flag) != up.flag )
01052 retval = 2;
01053 }
01054
01055 }
01056 catch(const smbios::IException &e)
01057 {
01058 SysInfoException.setMessageString(e.what());
01059 }
01060 catch(...)
01061 {
01062 SysInfoException.setMessageString( _("Unknown internal error occurred") );
01063 }
01064
01065 delete [] const_cast<u8 *>(buf);
01066 buf = 0;
01067
01068 out:
01069 return retval;
01070 }
01071
01072 int SMBIOSHasBootToUp()
01073 {
01074 return upBootHelper();
01075 }
01076
01077 int SMBIOSGetBootToUp()
01078 {
01079 int retval = upBootHelper();
01080 retval -= 2;
01081 return retval;
01082 }
01083
01084 void SMBIOSSetBootToUp(int state)
01085 {
01086 bool value = (state == 1) ? true: false;
01087 upBootHelper(true, value);
01088 }
01089
01090
01091 int SMBIOSGetSmiPasswordCoding()
01092 {
01093 int fmt=0;
01094 try
01095 {
01096 fmt = smi::getPasswordFormat();
01097 }
01098 catch(const exception &)
01099 {}
01100
01101 return fmt;
01102 }
01103