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

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

Generated on Wed Apr 11 16:25:10 2007 for SMBIOS Library by doxygen 1.3.5