SMBIOS Library
IdByte.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 #define LIBSMBIOS_SOURCE
20 #include "smbios/compat.h"
21 
22 #include <string.h>
23 
24 #include "smbios/ISmbios.h"
25 #include "smbios/IToken.h"
26 
27 #include "smbios/SystemInfo.h"
28 #include "smbios/IMemory.h"
29 #include "smbios/SmbiosDefs.h"
30 #include "ExceptionImpl.h"
31 
32 #include "SystemDetect.h"
33 #include "DellMagic.h"
34 
35 // should always be included last.
36 #include "smbios/message.h"
37 
38 using namespace smbios;
39 using namespace cmos;
40 using namespace std;
41 
43 
44 //
45 //
46 // ID Byte functions
47 //
48 //
50 {
51  u16 tempWord = 0;
52  u16 idWord = 0;
53  memory::IMemory *mem = 0;
54 
55  struct two_byte_structure tbs;
56  struct two_byte_structure *ptbs = &tbs;
57  struct one_byte_structure *pobs =
58  reinterpret_cast<one_byte_structure*>(&(tbs.bios_version));
59 
61 
62  if( 0 == mem )
63  throw InternalErrorImpl();
64 
65  // Step 1: Check that "Dell System" is present at the proper offset
66  u8 strBuf[DELL_SYSTEM_STRING_LEN] = { 0, };
68  if( strncmp( reinterpret_cast<char*>(strBuf), DELL_SYSTEM_STRING, DELL_SYSTEM_STRING_LEN ) != 0 )
69  goto out;
70 
71  // Step 2: fill the id structs
72  mem->fillBuffer( reinterpret_cast<u8 *>(ptbs), TWO_BYTE_STRUCT_LOC, sizeof(two_byte_structure) );
73 
74  // Step 3: check the checksum of one-byte struct
75  // update: checksum is not reliable, so don't use it...
76 
77  // Step 4: Check one byte ID
78  tempWord = pobs->system_id;
79 
80  // Step 5: if 0xFE, then it is a double byte (word) ID.
81  // * -- byte at 0xFE845 is 0xFE
82  if (0xFE == tempWord)
83 {
84  // Step 6: check two byte struct checksum
85  // * -- three bytes at 0xFE845 sum to 0x00 but are not all 0x00.
86  //* -- extension checksum is 0
87 
88  // Step 7: get ID.
89  tempWord = ptbs->two_byte_id;
90  }
91 
92  idWord = tempWord;
93 
94 out:
95  return idWord;
96 }
97 
99 {
100  u16 idWord = 0;
101  memory::IMemory *mem = 0;
102  u8 strBuf[DELL_SYSTEM_STRING_LEN] = { 0, };
103 
105 
106  if( 0 == mem )
107  throw InternalErrorImpl();
108 
109  // Step 1: Check that "Dell System" is present at the proper offset
111  if( strncmp( reinterpret_cast<char*>(strBuf), DELL_SYSTEM_STRING, DELL_SYSTEM_STRING_LEN ) == 0 )
113  idWord = SYSTEM_ID_DIAMOND;
114 
116  if( strncmp( reinterpret_cast<char*>(strBuf), DELL_SYSTEM_STRING, DELL_SYSTEM_STRING_LEN ) == 0 )
118  idWord = SYSTEM_ID_DIAMOND;
119 
120  return idWord;
121 }
122 
124 {
125  //functionEnter( "%s", "" );
126  u16 idWord = 0;
127  const smbios::ISmbiosTable *table = 0;
129  if (!couldBeBayonet())
130  goto out;
131 
133 
134  if (0 == table)
135  throw InternalErrorImpl();
136 
137  // search through 0x0B (OEM_Strings) items
138  for( item = (*table)[OEM_Strings] ; item != table->end(); ++item)
139  {
140  const char *str = item->getStringByStringNumber (2);
141  //isBayonet = true;
142  // Id byte is in second string in table 0x0B
143  // the format is "n[NN]", where NN is the idbyte;
144  // note the &str[2] below to skip the 'n['
145  if( 0 != str )
146  // quiet vc.net warning using cast
147  idWord = static_cast<u16>(strtol( &str[2], NULL, 16 ));
148  }
149 
150 out:
151  //functionLeave( "\t\tretval = %i\n", (int)idWord );
152  return idWord;
153 }
154 
156 {
157  //functionEnter( "%s", "" );
158  u16 idWord = 0;
159  const smbios::ISmbiosTable *table = 0;
161 
163 
164  if (0 == table)
165  throw InternalErrorImpl();
166 
167  // search through 0x0B (Revisions_and_IDs_Structure)
168  for( item = (*table)[Dell_Revisions_and_IDs]; item != table->end(); ++item)
169  {
170  //If byte field is 0xFE, we need to look in the extension field
171  idWord = getU8_FromItem(*item, 0x06);
172  if( 0xFE == idWord )
173  {
174  idWord = getU16_FromItem(*item, 0x08);
175  }
176  }
177  //functionLeave( "\t\tretval = %i\n", (int)idWord );
178  return idWord;
179 }
180 
181 //The code for detecting ID byte in case of Diamond is left out.
182 // need to write a function for it.
184 {
185  u16 (*f_ptr)();
186 }
188  {&getIdByteFromMem,}, // normal system -- try this last always.
189 
190  {&getIdByteFromOEMItem,}, // bayonet
191  {&getIdByteFromMem_Diamond,}, // diamond
192 
193  // do this last because this may contain an OEM id
194  // do this as a last resort because it is
195  // unreliable.
196  {&getIdByteFromRevItem,}, // Dell Smbios Revisions and ID's struct
197  };
198 
199 
200 
201 
203 {
204  //functionEnter( "%s", "" );
205  int systemId = 0;
206  int numEntries =
207  sizeof (DellIdByteFunctions) / sizeof (DellIdByteFunctions[0]);
208 
209  for (int i = 0; i < numEntries; ++i)
210  {
211  // eat exceptions from lowlevel functions and keep going.
212  try
213  {
214  // first function to return non-zero id wins.
215  systemId = DellIdByteFunctions[i].f_ptr ();
216  }
217  catch(const smbios::IException &e)
218  {
219  SysInfoException.setMessageString(e.what());
220  }
221  catch(...)
222  {
223  SysInfoException.setMessageString( _("Unknown internal error occurred") );
224  }
225  if (0 != systemId)
226  {
227  break;
228  }
229  }
230 
231  return systemId;
232 }
233