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