TokenD5.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 // compat header should always be first header if including system headers
00020 #define LIBSMBIOS_SOURCE
00021 #include "smbios/compat.h"
00022 
00023 #include <sstream>
00024 #include <iomanip>
00025 #include <string.h>
00026 
00027 #include "TokenImpl.h"
00028 
00029 using namespace std;
00030 
00031 namespace smbios
00032 {
00033     CmosTokenD5::CmosTokenD5( const smbios::ISmbiosItem &initItem, std::vector< CmosRWChecksumObserver > &initChecksumList)
00034             : IToken(), ICmosToken(), IProtectedToken(), item(initItem.clone()), cmos(cmos::CmosRWFactory::getFactory()->getSingleton()),
00035             validationKey(""), checksumList(initChecksumList)
00036     {
00037         size_t size;
00038         const u8 *ptr =  item->getBufferCopy(size) ; // MUST DELETE[]!
00039         size = size < sizeof(structure)? size : sizeof(structure);
00040         memcpy( const_cast<dell_protected_value_1_structure*>(&structure), ptr, size );
00041         delete [] const_cast<u8 *>(ptr); //const_cast to fix msvc++
00042 
00043         // note that if password is set (validation key non-null), then most
00044         //  of the structure is "encrypted" with the password
00045         if (! structure.validationKey )
00046         {
00047             addChecksumObserver();
00048         }
00049     }
00050 
00051     // no dynamically allocated memory, yay!
00052     CmosTokenD5::~CmosTokenD5() throw()
00053     {}
00054 
00055     string CmosTokenD5::getTokenClass() const
00056     {
00057         return "TokenD5";
00058     }
00059 
00060     u32 CmosTokenD5::getValueFormat() const
00061     {
00062         return structure.valueFormat;
00063     }
00064 
00065     const ISmbiosItem &CmosTokenD5::getItemRef() const
00066     {
00067         return *item;
00068     }
00069 
00070     u32 CmosTokenD5::getType() const
00071     {
00072         return structure.tokenId;
00073     }
00074 
00075     bool CmosTokenD5::isActive() const
00076     {
00077         throw InvalidAccessModeImpl();
00078     }
00079 
00080     void CmosTokenD5::activate() const
00081     {
00082         throw InvalidAccessModeImpl();
00083     }
00084 
00085     bool CmosTokenD5::isString() const
00086     {
00087         return true;
00088     }
00089 
00090     bool CmosTokenD5::isBool() const
00091     {
00092         return ! isString();
00093     }
00094 
00095     const string CmosTokenD5::getString(u8 *byteArray, unsigned int size ) const
00096     {
00097         if ( structure.validationKey )
00098             throw NeedAuthenticationImpl("not decoded yet");
00099 
00100         bool allocatedMem = false;
00101         try
00102         {
00103             unsigned int strSize = getStringLength();
00104             if( !byteArray )
00105             {
00106                 size = strSize + 1;
00107                 byteArray = new u8[size];
00108                 allocatedMem = true;
00109             }
00110 
00111             if( size < strSize + 1 )
00112                 throw ParameterErrorImpl(); // not enough space to store results
00113 
00114             for( unsigned int i=0; i<strSize; ++i )
00115                 byteArray[i] = '\0';
00116 
00117             cmos::readByteArray(
00118                 *cmos,
00119                 structure.indexPort,
00120                 structure.dataPort,
00121                 structure.valueStartIndex,
00122                 byteArray,
00123                 strSize
00124             );
00125 
00126             byteArray[ getStringLength() ] = '\0';
00127             string retval(reinterpret_cast<const char *>(byteArray));
00128             if( allocatedMem )
00129             {
00130                 delete [] byteArray;
00131                 byteArray = 0;
00132                 allocatedMem = false;
00133             }
00134             return retval;
00135 
00136         }
00137         catch ( const std::exception & )
00138         {
00139             if( allocatedMem )
00140             {
00141                 delete [] byteArray;
00142                 byteArray = 0;
00143                 allocatedMem = false;
00144             }
00145             throw;
00146         }
00147 
00148     }
00149 
00150     void CmosTokenD5::setString( const u8 *byteArray, size_t size ) const
00151     {
00152         if ( structure.validationKey )
00153             throw NeedAuthenticationImpl("not decoded yet");
00154 
00155         unsigned int strSize = getStringLength();
00156 
00157         u8 *targetBuffer = new u8[strSize];
00158         try
00159         {
00160             memset(targetBuffer, 0, strSize);
00161             memcpy( targetBuffer, byteArray, size < strSize ? size : strSize );
00162 
00163             cmos::writeByteArray(
00164                 *cmos,
00165                 structure.indexPort,
00166                 structure.dataPort,
00167                 structure.valueStartIndex,
00168                 targetBuffer,
00169                 strSize
00170             );
00171             // keep this in sync with below
00172             delete[](targetBuffer);
00173             targetBuffer=0;
00174         }
00175         catch(...)
00176         {
00177             // keep this in sync with above
00178             delete[](targetBuffer);
00179             targetBuffer=0;
00180             throw;
00181         }
00182     }
00183 
00184     unsigned int CmosTokenD5::getStringLength() const
00185     {
00186         // STRING must be at least 1 byte. Does not make sense
00187         // otherwise. BIOS Error? NVRAM byte tokens (0x83/0x84) seem to be
00188         // string tokens of length 0. That looks wrong.
00189         return structure.valueLen ? structure.valueLen : 1;
00190     }
00191 
00192     void CmosTokenD5::getCMOSDetails( u16 *indexPort, u16 *dataPort, u8 *location ) const
00193     {
00194         if ( structure.validationKey )
00195             throw NeedAuthenticationImpl("not decoded yet");
00196 
00197         *indexPort = structure.indexPort;
00198         *dataPort = structure.dataPort;
00199         *location = structure.valueStartIndex;
00200         return;
00201     }
00202 
00203     void CmosTokenD5::addChecksumObserver() const
00204     {
00205         ostringstream ost;
00206         ost << *item;
00207 
00208         CmosRWChecksumObserver chk(
00209             ost.str(),
00210             cmos,
00211             structure.checkType,
00212             structure.indexPort,
00213             structure.dataPort,
00214             structure.valueStartIndex,
00215             structure.valueStartIndex + structure.valueLen - 1,
00216             structure.checkIndex  );
00217         checksumList.push_back( chk );
00218     }
00219 
00220     bool CmosTokenD5::tryPassword(std::string pw) const
00221     {
00222         cout << "Password decode code not yet present." << pw << endl;
00223         return false;
00224         // addChecksumObserver() after we successfully decode password
00225     }
00226 
00227     std::ostream & CmosTokenD5::streamify( std::ostream & cout ) const
00228     {
00229         std::ios::fmtflags old_opts = cout.flags ();
00230 
00231         cout << "DMI type 0x" << hex << setfill ('0') << setw (2) << static_cast<int>(structure.type);
00232         cout << "  Handle 0x" << hex << setfill ('0') << setw (4) << static_cast<int>(structure.handle);
00233         cout << "  Index Port 0x" << hex << setw(2) << structure.indexPort;
00234         cout << "  Data Port 0x"  << hex << setw(2) << structure.dataPort;
00235         cout << "  Type 0x" << hex << setw(4) << static_cast<int>(getType());
00236         cout << "  Location 0x" << hex << setw(2) << static_cast<int>(structure.valueStartIndex);
00237         cout << " STRING  Length " << dec << setfill('0') << setw(2) << getStringLength() ;
00238         cout << " value(" << getString() << ")";
00239 
00240         cout.flags (old_opts);
00241 
00242         return cout;
00243     }
00244 
00245 }

Generated on Tue Feb 26 14:51:55 2008 for SMBIOS Library by  doxygen 1.4.7