SMBIOS Library
TokenD5.cpp
Go to the documentation of this file.
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  * vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=c:cindent:textwidth=0:
3  *
4  * Copyright (C) 2005 Dell Inc.
5  * by Michael Brown <Michael_E_Brown@dell.com>
6  * Licensed under the Open Software License version 2.1
7  *
8  * Alternatively, you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published
10  * by the Free Software Foundation; either version 2 of the License,
11  * or (at your option) any later version.
12 
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  */
18 
19 // compat header should always be first header if including system headers
20 #define LIBSMBIOS_SOURCE
21 #include "smbios/compat.h"
22 
23 #include <sstream>
24 #include <iomanip>
25 #include <string.h>
26 
27 #include "TokenImpl.h"
28 
29 using namespace std;
30 
31 namespace smbios
32 {
33  CmosTokenD5::CmosTokenD5( const smbios::ISmbiosItem &initItem, std::vector< CmosRWChecksumObserver > &initChecksumList)
34  : IToken(), ICmosToken(), IProtectedToken(), item(initItem.clone()), cmos(cmos::CmosRWFactory::getFactory()->getSingleton()),
35  validationKey(""), checksumList(initChecksumList)
36  {
37  size_t size;
38  const u8 *ptr = item->getBufferCopy(size) ; // MUST DELETE[]!
39  size = size < sizeof(structure)? size : sizeof(structure);
40  memcpy( const_cast<dell_protected_value_1_structure*>(&structure), ptr, size );
41  delete [] const_cast<u8 *>(ptr); //const_cast to fix msvc++
42 
43  // note that if password is set (validation key non-null), then most
44  // of the structure is "encrypted" with the password
45  if (! structure.validationKey )
46  {
48  }
49  }
50 
51  // no dynamically allocated memory, yay!
53  {}
54 
56  {
57  return "TokenD5";
58  }
59 
61  {
62  return structure.valueFormat;
63  }
64 
66  {
67  return *item;
68  }
69 
71  {
72  return structure.tokenId;
73  }
74 
75  bool CmosTokenD5::isActive() const
76  {
77  throw InvalidAccessModeImpl();
78  }
79 
80  void CmosTokenD5::activate() const
81  {
82  throw InvalidAccessModeImpl();
83  }
84 
85  bool CmosTokenD5::isString() const
86  {
87  return true;
88  }
89 
90  bool CmosTokenD5::isBool() const
91  {
92  return ! isString();
93  }
94 
95  const string CmosTokenD5::getString(u8 *byteArray, unsigned int size ) const
96  {
98  throw NeedAuthenticationImpl("not decoded yet");
99 
100  bool allocatedMem = false;
101  try
102  {
103  unsigned int strSize = getStringLength();
104  if( !byteArray )
105  {
106  size = strSize + 1;
107  byteArray = new u8[size];
108  allocatedMem = true;
109  }
110 
111  if( size < strSize + 1 )
112  throw ParameterErrorImpl(); // not enough space to store results
113 
114  for( unsigned int i=0; i<strSize; ++i )
115  byteArray[i] = '\0';
116 
118  *cmos,
122  byteArray,
123  strSize
124  );
125 
126  byteArray[ getStringLength() ] = '\0';
127  string retval(reinterpret_cast<const char *>(byteArray));
128  if( allocatedMem )
129  {
130  delete [] byteArray;
131  byteArray = 0;
132  allocatedMem = false;
133  }
134  return retval;
135 
136  }
137  catch ( const std::exception & )
138  {
139  if( allocatedMem )
140  {
141  delete [] byteArray;
142  byteArray = 0;
143  allocatedMem = false;
144  }
145  throw;
146  }
147 
148  }
149 
150  void CmosTokenD5::setString( const u8 *byteArray, size_t size ) const
151  {
152  if ( structure.validationKey )
153  throw NeedAuthenticationImpl("not decoded yet");
154 
155  unsigned int strSize = getStringLength();
156 
157  u8 *targetBuffer = new u8[strSize];
158  try
159  {
160  memset(targetBuffer, 0, strSize);
161  memcpy( targetBuffer, byteArray, size < strSize ? size : strSize );
162 
164  *cmos,
168  targetBuffer,
169  strSize
170  );
171  // keep this in sync with below
172  delete[](targetBuffer);
173  targetBuffer=0;
174  }
175  catch(...)
176  {
177  // keep this in sync with above
178  delete[](targetBuffer);
179  targetBuffer=0;
180  throw;
181  }
182  }
183 
184  unsigned int CmosTokenD5::getStringLength() const
185  {
186  // STRING must be at least 1 byte. Does not make sense
187  // otherwise. BIOS Error? NVRAM byte tokens (0x83/0x84) seem to be
188  // string tokens of length 0. That looks wrong.
189  return structure.valueLen ? structure.valueLen : 1;
190  }
191 
192  void CmosTokenD5::getCMOSDetails( u16 *indexPort, u16 *dataPort, u8 *location ) const
193  {
194  if ( structure.validationKey )
195  throw NeedAuthenticationImpl("not decoded yet");
196 
197  *indexPort = structure.indexPort;
198  *dataPort = structure.dataPort;
199  *location = structure.valueStartIndex;
200  return;
201  }
202 
204  {
205  ostringstream ost;
206  ost << *item;
207 
209  ost.str(),
210  cmos,
217  checksumList.push_back( chk );
218  }
219 
220  bool CmosTokenD5::tryPassword(std::string pw) const
221  {
222  cout << "Password decode code not yet present." << pw << endl;
223  return false;
224  // addChecksumObserver() after we successfully decode password
225  }
226 
227  std::ostream & CmosTokenD5::streamify( std::ostream & cout ) const
228  {
229  std::ios::fmtflags old_opts = cout.flags ();
230 
231  cout << "DMI type 0x" << hex << setfill ('0') << setw (2) << static_cast<int>(structure.type);
232  cout << " Handle 0x" << hex << setfill ('0') << setw (4) << static_cast<int>(structure.handle);
233  cout << " Index Port 0x" << hex << setw(2) << structure.indexPort;
234  cout << " Data Port 0x" << hex << setw(2) << structure.dataPort;
235  cout << " Type 0x" << hex << setw(4) << static_cast<int>(getType());
236  cout << " Location 0x" << hex << setw(2) << static_cast<int>(structure.valueStartIndex);
237  cout << " STRING Length " << dec << setfill('0') << setw(2) << getStringLength() ;
238  cout << " value(" << getString() << ")";
239 
240  cout.flags (old_opts);
241 
242  return cout;
243  }
244 
245 }