Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

IdByte.cpp

Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  * vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=c:cindent:textwidth=0:
00003  *
00004  * Copyright (C) 2005 Dell Inc.
00005  *  by Michael Brown <Michael_E_Brown@dell.com>
00006  * Licensed under the Open Software License version 2.1
00007  *
00008  * Alternatively, you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published
00010  * by the Free Software Foundation; either version 2 of the License,
00011  * or (at your option) any later version.
00012 
00013  * This program is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016  * See the GNU General Public License for more details.
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 
00027 #include "smbios/SystemInfo.h"
00028 #include "smbios/IMemory.h"
00029 #include "smbios/SmbiosDefs.h"
00030 #include "ExceptionImpl.h"
00031 
00032 #include "SystemDetect.h"
00033 #include "DellMagic.h"
00034 
00035 // should always be included last.
00036 #include "smbios/message.h"
00037 
00038 using namespace smbios;
00039 using namespace cmos;
00040 using namespace std;
00041 
00042 extern smbios::Exception<smbios::IException> SysInfoException;
00043 
00044 //
00045 //
00046 // ID Byte functions
00047 //
00048 //
00049 static u16 getIdByteFromMem ()
00050 {
00051     u16 tempWord = 0;
00052     u16 idWord = 0;
00053     memory::IMemory *mem = 0;
00054 
00055     struct two_byte_structure tbs;
00056     struct two_byte_structure *ptbs = &tbs;
00057     struct one_byte_structure *pobs =
00058                     reinterpret_cast<one_byte_structure*>(&(tbs.bios_version));
00059 
00060     mem = memory::MemoryFactory::getFactory()->getSingleton();
00061 
00062     if( 0 == mem )
00063         throw InternalErrorImpl();
00064 
00065     // Step 1: Check that "Dell System" is present at the proper offset
00066     u8 strBuf[DELL_SYSTEM_STRING_LEN] = { 0, };
00067     mem->fillBuffer( strBuf, DELL_SYSTEM_STRING_LOC, DELL_SYSTEM_STRING_LEN - 1 );
00068     if( strncmp( reinterpret_cast<char*>(strBuf), DELL_SYSTEM_STRING, DELL_SYSTEM_STRING_LEN ) != 0 )
00069         goto out;
00070 
00071     // Step 2: fill the id structs
00072     mem->fillBuffer( reinterpret_cast<u8 *>(ptbs), TWO_BYTE_STRUCT_LOC, sizeof(two_byte_structure) );
00073 
00074     // Step 3: check the checksum of one-byte struct
00075     //    update: checksum is not reliable, so don't use it...
00076 
00077     // Step 4: Check one byte ID
00078     tempWord = pobs->system_id;
00079 
00080     // Step 5: if 0xFE, then it is a double byte (word) ID.
00081     // *  -- byte at 0xFE845 is 0xFE
00082     if (0xFE == tempWord)
00083 {
00084         // Step 6: check two byte struct checksum
00085         // *  -- three bytes at 0xFE845 sum to 0x00 but are not all 0x00.
00086         //*  -- extension checksum is 0
00087 
00088         // Step 7: get ID.
00089         tempWord = ptbs->two_byte_id;
00090     }
00091 
00092     idWord = tempWord;
00093 
00094 out:
00095     return idWord;
00096 }
00097 
00098 static u16 getIdByteFromMem_Diamond ()
00099 {
00100     u16 idWord = 0;
00101     memory::IMemory *mem = 0;
00102     u8 strBuf[DELL_SYSTEM_STRING_LEN] = { 0, };
00103 
00104     mem = memory::MemoryFactory::getFactory()->getSingleton();
00105 
00106     if( 0 == mem )
00107         throw InternalErrorImpl();
00108 
00109     // Step 1: Check that "Dell System" is present at the proper offset
00110     mem->fillBuffer( strBuf, DELL_SYSTEM_STRING_LOC_DIAMOND_1, DELL_SYSTEM_STRING_LEN - 1 );
00111     if( strncmp( reinterpret_cast<char*>(strBuf), DELL_SYSTEM_STRING, DELL_SYSTEM_STRING_LEN ) == 0 )
00112         if( SYSTEM_ID_DIAMOND == mem->getByte( ID_BYTE_LOC_DIAMOND_1 ) )
00113             idWord = SYSTEM_ID_DIAMOND;
00114 
00115     mem->fillBuffer( strBuf, DELL_SYSTEM_STRING_LOC_DIAMOND_2, DELL_SYSTEM_STRING_LEN - 1 );
00116     if( strncmp( reinterpret_cast<char*>(strBuf), DELL_SYSTEM_STRING, DELL_SYSTEM_STRING_LEN ) == 0 )
00117         if( SYSTEM_ID_DIAMOND == mem->getByte( ID_BYTE_LOC_DIAMOND_2 ) )
00118             idWord = SYSTEM_ID_DIAMOND;
00119 
00120     return idWord;
00121 }
00122 
00123 static u16 getIdByteFromOEMItem ()
00124 {
00125     //functionEnter( "%s", "" );
00126     u16 idWord = 0;
00127     const smbios::ISmbiosTable *table = 0;
00128     smbios::ISmbiosTable::const_iterator item;
00129     if (!couldBeBayonet())
00130         goto out;
00131 
00132     table = smbios::SmbiosFactory::getFactory()->getSingleton();
00133 
00134     if (0 == table)
00135         throw InternalErrorImpl();
00136 
00137     // search through 0x0B (OEM_Strings) items
00138     for( item = (*table)[OEM_Strings] ; item != table->end(); ++item)
00139     {
00140         const char *str = item->getStringByStringNumber (2);
00141         //isBayonet = true;
00142         //  Id byte is in second string in table 0x0B
00143         //  the format is "n[NN]", where NN is the idbyte;
00144         //  note the &str[2] below to skip the 'n['
00145         if( 0 != str )
00146             // quiet vc.net warning using cast
00147             idWord = static_cast<u16>(strtol( &str[2], NULL, 16 ));
00148     }
00149 
00150 out:
00151     //functionLeave( "\t\tretval = %i\n", (int)idWord );
00152     return idWord;
00153 }
00154 
00155 static u16 getIdByteFromRevItem ()
00156 {
00157     //functionEnter( "%s", "" );
00158     u16 idWord = 0;
00159     const smbios::ISmbiosTable *table = 0;
00160     smbios::ISmbiosTable::const_iterator item;
00161 
00162     table = smbios::SmbiosFactory::getFactory()->getSingleton();
00163 
00164     if (0 == table)
00165         throw InternalErrorImpl();
00166 
00167     // search through 0x0B (Revisions_and_IDs_Structure)
00168     for( item = (*table)[Dell_Revisions_and_IDs]; item != table->end(); ++item)
00169     {
00170         //If byte field is 0xFE, we need to look in the extension field
00171         idWord = getU8_FromItem(*item, 0x06);
00172         if( 0xFE == idWord )
00173         {
00174             idWord = getU16_FromItem(*item, 0x08);
00175         }
00176     }
00177     //functionLeave( "\t\tretval = %i\n", (int)idWord );
00178     return idWord;
00179 }
00180 
00181 //The code for detecting ID byte in case of Diamond is left out.
00182 //  need to write a function for it.
00183 struct DellIdByteFunctions
00184 {
00185     u16 (*f_ptr)();
00186 }
00187 DellIdByteFunctions[] = {
00188                             {&getIdByteFromMem,},       // normal system -- try this last always.
00189 
00190                             {&getIdByteFromOEMItem,},   // bayonet
00191                             {&getIdByteFromMem_Diamond,}, // diamond
00192 
00193                             // do this last because this may contain an OEM id
00194                             // do this as a last resort because it is
00195                             // unreliable.
00196                             {&getIdByteFromRevItem,},   // Dell Smbios Revisions and ID's struct
00197                         };
00198 
00199 
00200 
00201 
00202 int SMBIOSGetDellSystemId()
00203 {
00204     //functionEnter( "%s", "" );
00205     int systemId = 0;
00206     int numEntries =
00207         sizeof (DellIdByteFunctions) / sizeof (DellIdByteFunctions[0]);
00208 
00209     for (int i = 0; i < numEntries; ++i)
00210     {
00211         // eat exceptions from lowlevel functions and keep going.
00212         try
00213         {
00214             // first function to return non-zero id wins.
00215             systemId = DellIdByteFunctions[i].f_ptr ();
00216         }
00217         catch(const smbios::IException &e)
00218         {
00219             SysInfoException.setMessageString(e.what());
00220         }
00221         catch(...)
00222         {
00223             SysInfoException.setMessageString( _("Unknown internal error occurred") );
00224         }
00225         if (0 != systemId)
00226         {
00227             break;
00228         }
00229     }
00230 
00231     return systemId;
00232 }
00233 

Generated on Tue Feb 26 14:39:00 2008 for SMBIOS Library by  doxygen 1.3.9.1