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