TokenDA.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 <iomanip>
00024 
00025 #include "TokenImpl.h"
00026 
00027 #include "smbios/ISmi.h"
00028 
00029 #define TODO do { throw NotImplementedImpl(); } while(0)
00030 
00031 using namespace std;
00032 
00033 namespace smbios
00034 {
00035     SmiTokenDA::SmiTokenDA( const smbios::ISmbiosItem &initItem, const calling_interface_token *initToken )
00036             : IToken(), item(initItem.clone()), password("")
00037     {
00038         memcpy( const_cast<calling_interface_token *>(&token), initToken, sizeof(token) );
00039 
00040         size_t size;
00041         const u8 *ptr =  item->getBufferCopy(size) ; // MUST DELETE[]!
00042         memcpy( const_cast<calling_interface_structure*>(&structure), ptr, sizeof(structure) );
00043         delete [] const_cast<u8 *>(ptr); //const_cast to fix msvc++
00044     }
00045 
00046     // no dynamically allocated memory, yay!
00047     SmiTokenDA::~SmiTokenDA() throw()
00048     {}
00049 
00050     string SmiTokenDA::getTokenClass() const
00051     {
00052         return "TokenDA";
00053     }
00054 
00055     u32 SmiTokenDA::getValueFormat() const
00056     {
00057         return 0xFFFFFFFF;
00058     }
00059 
00060     bool SmiTokenDA::tryPassword(std::string pw) const
00061     {
00062         // can't really validate password without retrying operation
00063         password = pw;
00064         return true;
00065     }
00066 
00067     const ISmbiosItem &SmiTokenDA::getItemRef() const
00068     {
00069         return *item;
00070     }
00071 
00072     u32 SmiTokenDA::getType() const
00073     {
00074         return token.tokenId;
00075     }
00076 
00077     bool SmiTokenDA::isActive() const
00078     {
00079         bool ret = false;
00080 
00081         std::auto_ptr<smi::ISmi> smi = smi::SmiFactory::getFactory()->makeNew(smi::SmiFactory::DELL_CALLING_INTERFACE_SMI);
00082         smi->setCommandIOMagic( structure.cmdIOAddress, structure.cmdIOCode );
00083 
00084         smi::IDellCallingInterfaceSmi *ci = dynamic_cast<smi::IDellCallingInterfaceSmi *>(smi.get());
00085         ci->setClass( 0x0 );  /* Read Non-Volatile Storage class code */
00086         ci->setSelect( 0x0 );  /* Read Non-Volatile Storage select code */
00087         ci->setArg( 0, token.location );
00088         ci->execute();
00089 
00090         if (ci->getRes(2) == token.value )
00091             ret = true;
00092 
00093         return ret;
00094     }
00095 
00096     static void executeWithPassword(smi::IDellCallingInterfaceSmi *ci, u8 arg, string password)
00097     {
00098         for(int i=0; i<2; i++)
00099         {
00100             try
00101             {
00102                 ci->execute();
00103                 break;
00104             }
00105             catch(const smi::SmiExecutedWithError &)
00106             {
00107                 // on second time through, just pass exception upwards.
00108                 if(i==1)
00109                     throw;
00110 
00111                 //cout << "Caught error. Might be bad password. Trying password: " << password << endl;
00112                 ci->setArg( arg, smi::getAuthenticationKey(password));
00113             }
00114         }
00115     }
00116 
00117     void SmiTokenDA::activate() const
00118     {
00119         std::auto_ptr<smi::ISmi> smi = smi::SmiFactory::getFactory()->makeNew(smi::SmiFactory::DELL_CALLING_INTERFACE_SMI);
00120         smi->setCommandIOMagic( structure.cmdIOAddress, structure.cmdIOCode );
00121         smi::IDellCallingInterfaceSmi *ci = dynamic_cast<smi::IDellCallingInterfaceSmi *>(smi.get());
00122         ci->setClass( 0x1 );  /* Write Non-Volatile Storage class code */
00123         ci->setSelect( 0x0 );  /* Write Non-Volatile Storage select code */
00124         ci->setArg( 0, token.location );
00125         ci->setArg( 1, token.value );
00126         executeWithPassword(ci, 2, password);
00127     }
00128 
00129     bool SmiTokenDA::isString() const
00130     {
00131         return true;
00132     }
00133 
00134     bool SmiTokenDA::isBool() const
00135     {
00136         return true;
00137     }
00138 
00139     const string SmiTokenDA::getString(u8 *byteArray, unsigned int size ) const
00140     {
00141         std::auto_ptr<smi::ISmi> smi = smi::SmiFactory::getFactory()->makeNew(smi::SmiFactory::DELL_CALLING_INTERFACE_SMI);
00142         smi->setCommandIOMagic( structure.cmdIOAddress, structure.cmdIOCode );
00143 
00144         smi::IDellCallingInterfaceSmi *ci = dynamic_cast<smi::IDellCallingInterfaceSmi *>(smi.get());
00145         ci->setClass( 0x0 );  /* Read Non-Volatile Storage class code */
00146         ci->setSelect( 0x0 );  /* Read Non-Volatile Storage select code */
00147         ci->setArg( 0, token.location );
00148         ci->execute();
00149 
00150         // first word is data. ignore high bits.
00151         u16 word = static_cast<u16>(ci->getRes(1));
00152 
00153         if(byteArray && size >= 2)
00154         {
00155             memset(byteArray, 0, size);
00156             memcpy(byteArray, &word, sizeof(u16));
00157         }
00158 
00159         char ret[3]={0};
00160         memcpy(ret, &word, sizeof(u16));
00161 
00162         return ret; //automatically converted to std::string
00163     }
00164 
00165     void SmiTokenDA::setString( const u8 *byteArray, size_t size ) const
00166     {
00167         if( size < 2 )
00168             return;
00169 
00170         std::auto_ptr<smi::ISmi> smi = smi::SmiFactory::getFactory()->makeNew(smi::SmiFactory::DELL_CALLING_INTERFACE_SMI);
00171         smi->setCommandIOMagic( structure.cmdIOAddress, structure.cmdIOCode );
00172 
00173         smi::IDellCallingInterfaceSmi *ci = dynamic_cast<smi::IDellCallingInterfaceSmi *>(smi.get());
00174         ci->setClass( 0x1 );  /* Read Non-Volatile Storage class code */
00175         ci->setSelect( 0x0 );  /* Read Non-Volatile Storage select code */
00176         ci->setArg( 0, token.location );
00177         ci->setArg( 1, *reinterpret_cast<const u16 *>(byteArray) );
00178         executeWithPassword(ci, 2, password);
00179     }
00180 
00181     unsigned int SmiTokenDA::getStringLength() const
00182     {
00183         // pretend all SMI tokens are one word
00184         return 2;
00185     }
00186 
00187     std::ostream & SmiTokenDA::streamify( std::ostream & cout ) const
00188     {
00189         std::ios::fmtflags old_opts = cout.flags ();
00190 
00191         cout << hex << setfill('0');
00192         cout << "DMI type 0x"       << setw(2) << static_cast<int>(structure.type);
00193         cout << "  Handle 0x"       << setw(4) << static_cast<int>(structure.handle);
00194         cout << "  CmdIO Port 0x"  << setw(4) << static_cast<int>(structure.cmdIOAddress);
00195         cout << "  CmdIO Code 0x"  << setw(2) << static_cast<int>(structure.cmdIOCode);
00196         cout << "  Type 0x"         << setw(4) << static_cast<int>(getType());
00197         cout << "  Location 0x"     << setw(4) << static_cast<int>(token.location);
00198         cout << " value "           << setw(4) << static_cast<int>(token.value);
00199 
00200         cout.flags (old_opts);
00201 
00202         return cout;
00203     }
00204 
00205 }

Generated on Tue Jul 11 20:46:46 2006 for SMBIOS Library by  doxygen 1.4.7