Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
smbios.cpp
Go to the documentation of this file.
1 /* Copyright (c) 2011 Wildfire Games
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining
4  * a copy of this software and associated documentation files (the
5  * "Software"), to deal in the Software without restriction, including
6  * without limitation the rights to use, copy, modify, merge, publish,
7  * distribute, sublicense, and/or sell copies of the Software, and to
8  * permit persons to whom the Software is furnished to do so, subject to
9  * the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22 
23 /*
24  * provide access to System Management BIOS information
25  */
26 
27 #include "precompiled.h"
28 #include "lib/sysdep/smbios.h"
29 
30 #include "lib/bits.h"
31 #include "lib/alignment.h"
32 #include "lib/byte_order.h" // FOURCC_BE
33 #include "lib/module_init.h"
34 
35 #if OS_WIN
36 # include "lib/sysdep/os/win/wutil.h"
38 #endif
39 
40 #include <sstream>
41 
42 namespace SMBIOS {
43 
44 //-----------------------------------------------------------------------------
45 // GetTable
46 
47 #if OS_WIN
48 
49 static Status GetTable(wfirmware::Table& table)
50 {
51  // (MSDN mentions 'RSMB', but multi-character literals are implementation-defined.)
52  const DWORD provider = FOURCC_BE('R','S','M','B');
53 
54  // (MSDN says this will be 0, but we'll retrieve it for 100% correctness.)
55  wfirmware::TableIds tableIds = wfirmware::GetTableIDs(provider);
56  if(tableIds.empty())
57  return ERR::_1; // NOWARN (happens on 32-bit XP)
58 
59  table = wfirmware::GetTable(provider, tableIds[0]);
60  if(table.empty())
62 
63  // strip the WmiHeader
64  struct WmiHeader
65  {
66  u8 used20CallingMethod;
67  u8 majorVersion;
68  u8 minorVersion;
69  u8 dmiRevision;
70  u32 length;
71  };
72  const WmiHeader* wmiHeader = (const WmiHeader*)&table[0];
73  ENSURE(table.size() == sizeof(WmiHeader) + wmiHeader->length);
74  memmove(&table[0], &table[sizeof(WmiHeader)], table.size()-sizeof(WmiHeader));
75 
76  return INFO::OK;
77 }
78 
79 #endif // OS_WIN
80 
81 
82 //-----------------------------------------------------------------------------
83 // strings
84 
85 // pointers to the strings (if any) at the end of an SMBIOS structure
86 typedef std::vector<const char*> Strings;
87 
88 static Strings ExtractStrings(const Header* header, const char* end, const Header*& next)
89 {
90  Strings strings;
91 
92  const char* pos = ((const char*)header) + header->length;
93  while(pos <= end-2)
94  {
95  if(*pos == '\0')
96  {
97  pos++;
98  if(*pos == 0)
99  {
100  pos++;
101  break;
102  }
103  }
104 
105  strings.push_back(pos);
106  pos += strlen(pos);
107  }
108 
109  next = (const Header*)pos;
110  return strings;
111 }
112 
113 
114 // storage for all structures' strings (must be copied from the original
115 // wfirmware table since its std::vector container cannot be stored in a
116 // static variable because we may be called before _cinit)
117 static char* stringStorage;
118 static char* stringStoragePos;
119 
120 // pointers to dynamically allocated structures
122 
123 static void Cleanup() // called via atexit
124 {
126  stringStoragePos = 0;
127 
128  // free each allocated structure
129 #define STRUCTURE(name, id)\
130  while(structures.name##_)\
131  {\
132  name* next = structures.name##_->next;\
133  SAFE_FREE(structures.name##_);\
134  structures.name##_ = next;\
135  }
136  STRUCTURES
137 #undef STRUCTURE
138 }
139 
140 
141 //-----------------------------------------------------------------------------
142 // FieldInitializer
143 
144 // define function templates that invoke a Visitor for each of a structure's fields
145 #define FIELD(flags, type, name, units) visitor(flags, p.name, #name, units);
146 #define STRUCTURE(name, id) template<class Visitor> void VisitFields(name& p, Visitor& visitor) { name##_FIELDS }
148 #undef STRUCTURE
149 #undef FIELD
150 
151 
152 // initialize each of a structure's fields by copying from the SMBIOS data
154 {
155  NONCOPYABLE(FieldInitializer); // reference member
156 public:
157  FieldInitializer(const Header* header, const Strings& strings)
158  : data((const u8*)(header+1))
159  , end((const u8*)header + header->length)
160  , strings(strings)
161  {
162  }
163 
164  template<typename Field>
165  void operator()(size_t flags, Field& field, const char* UNUSED(name), const char* UNUSED(units))
166  {
167  if((flags & F_DERIVED) || data >= end)
168  {
169  field = Field();
170  return;
171  }
172 
173  Read(field, 0); // SFINAE
174  }
175 
176 private:
177  template<typename T>
179  {
180  T value;
181  memcpy(&value, data, sizeof(value));
182  data += sizeof(value);
183  return value;
184  }
185 
186  // construct from SMBIOS representations that don't match the
187  // actual type (e.g. enum)
188  template<typename Field>
189  void Read(Field& field, typename Field::T*)
190  {
191  field = Field(ReadValue<typename Field::T>());
192  }
193 
194  template<typename Field>
195  void Read(Field& field, ...)
196  {
197  field = ReadValue<Field>();
198  }
199 
200  const u8* data;
201  const u8* end;
202  const Strings& strings;
203 };
204 
205 
206 // C++03 14.7.3(2): "An explicit specialization shall be declared [..] in the
207 // namespace of which the enclosing class [..] is a member.
208 
209 // (this specialization avoids a "forcing value to bool true or false" warning)
210 template<>
211 void FieldInitializer::operator()<bool>(size_t flags, bool& UNUSED(t), const char* UNUSED(name), const char* UNUSED(units))
212 {
213  // SMBIOS doesn't specify any individual booleans, so we're only called for
214  // derived fields and don't need to do anything.
215  ENSURE(flags & F_DERIVED);
216 }
217 
218 template<>
219 void FieldInitializer::operator()<const char*>(size_t flags, const char*& t, const char* UNUSED(name), const char* UNUSED(units))
220 {
221  t = 0; // (allow immediate `return' when the string is found to be invalid)
222 
223  u8 number;
224  operator()(flags, number, 0, 0);
225  if(number == 0) // no string given
226  return;
227 
228  if(number > strings.size())
229  {
230  debug_printf(L"SMBIOS: invalid string number %d (count=%d)\n", number, (int)strings.size());
231  return;
232  }
233 
234  // copy to stringStorage
235  strcpy(stringStoragePos, strings[number-1]);
236  t = stringStoragePos;
237  stringStoragePos += strlen(t)+1;
238 }
239 
240 
241 //-----------------------------------------------------------------------------
242 // Fixup (e.g. compute derived fields)
243 
244 template<class Structure>
245 void Fixup(Structure& UNUSED(structure))
246 {
247  // primary template: do nothing
248 }
249 
250 template<>
251 void Fixup<Bios>(Bios& p)
252 {
253  p.size = size_t(p.encodedSize+1) * 64*KiB;
254 }
255 
256 template<>
257 void Fixup<Processor>(Processor& p)
258 {
259  p.populated = (p.status & 0x40) != 0;
260  p.status = (ProcessorStatus)bits(p.status, 0, 2);
261 
262  if(p.voltage & 0x80)
263  p.voltage &= ~0x80;
264  else
265  {
266  // (arbitrarily) report the lowest supported value
267  if(IsBitSet(p.voltage, 0))
268  p.voltage = 50;
269  if(IsBitSet(p.voltage, 1))
270  p.voltage = 33;
271  if(IsBitSet(p.voltage, 2))
272  p.voltage = 29;
273  }
274 }
275 
276 template<>
278 {
279  struct DecodeSize
280  {
281  u64 operator()(u16 size) const
282  {
283  const size_t granularity = IsBitSet(size, 15)? 64*KiB : 1*KiB;
284  return u64(bits(size, 0, 14)) * granularity;
285  }
286  };
287  p.maxSize = DecodeSize()(p.maxSize16);
288  p.installedSize = DecodeSize()(p.installedSize16);
289  p.level = bits(p.configuration, 0, 2)+1;
290  p.location = (CacheLocation)bits(p.configuration, 5, 6);
291  p.mode = (CacheMode)bits(p.configuration, 8, 9);
292  p.configuration = (CacheConfigurationFlags)(p.configuration & ~0x367);
293 }
294 
295 template<>
296 void Fixup<SystemSlot>(SystemSlot& p)
297 {
298  // (only initialize function and device numbers if functionAndDeviceNumber is valid)
299  if(p.functionAndDeviceNumber != 0xFF)
300  {
301  p.functionNumber = bits(p.functionAndDeviceNumber, 0, 2);
302  p.deviceNumber = bits(p.functionAndDeviceNumber, 3, 7);
303  }
304 }
305 
306 template<>
307 void Fixup<OnBoardDevices>(OnBoardDevices& p)
308 {
309  p.enabled = (p.type.value & 0x80) != 0;
310  p.type = (OnBoardDeviceType)(p.type & ~0x80);
311 }
312 
313 template<>
314 void Fixup<MemoryArray>(MemoryArray& p)
315 {
316  if(p.maxCapacity32 != (u32)INT32_MIN)
317  p.maxCapacity = u64(p.maxCapacity32) * KiB;
318 }
319 
320 template<>
321 void Fixup<MemoryDevice>(MemoryDevice& p)
322 {
323  if(p.size16 != INT16_MAX)
324  p.size = u64(bits(p.size16, 0, 14)) * (IsBitSet(p.size16, 15)? 1*KiB : 1*MiB);
325  else
326  p.size = u64(bits(p.size32, 0, 30)) * MiB;
327  p.rank = bits(p.attributes, 0, 3);
328 }
329 
330 template<>
331 void Fixup<MemoryArrayMappedAddress>(MemoryArrayMappedAddress& p)
332 {
333  if(p.startAddress32 != UINT32_MAX)
334  p.startAddress = u64(p.startAddress32) * KiB;
335  if(p.endAddress32 != UINT32_MAX)
336  p.endAddress = u64(p.endAddress32) * KiB;
337 }
338 
339 template<>
340 void Fixup<MemoryDeviceMappedAddress>(MemoryDeviceMappedAddress& p)
341 {
342  if(p.startAddress32 != UINT32_MAX)
343  p.startAddress = u64(p.startAddress32) * KiB;
344  if(p.endAddress32 != UINT32_MAX)
345  p.endAddress = u64(p.endAddress32) * KiB;
346 }
347 
348 template<>
349 void Fixup<VoltageProbe>(VoltageProbe& p)
350 {
351  p.location = (VoltageProbeLocation)bits(p.locationAndStatus, 0, 4);
352  p.status = (State)bits(p.locationAndStatus, 5, 7);
353 }
354 
355 template<>
356 void Fixup<CoolingDevice>(CoolingDevice& p)
357 {
358  p.type = (CoolingDeviceType)bits(p.typeAndStatus, 0, 4);
359  p.status = (State)bits(p.typeAndStatus, 5, 7);
360 }
361 
362 template<>
363 void Fixup<TemperatureProbe>(TemperatureProbe& p)
364 {
365  p.location = (TemperatureProbeLocation)bits(p.locationAndStatus, 0, 4);
366  p.status = (State)bits(p.locationAndStatus, 5, 7);
367 }
368 
369 template<>
370 void Fixup<SystemPowerSupply>(SystemPowerSupply& p)
371 {
372  p.type = (SystemPowerSupplyType)bits(p.characteristics, 10, 13);
373  p.status = (State)bits(p.characteristics, 7, 9);
374  p.inputSwitching = (SystemPowerSupplyInputSwitching)bits(p.characteristics, 3, 6);
375  p.characteristics = bits(p.characteristics, 0, 2);
376 }
377 
378 template<>
379 void Fixup<OnboardDevices2>(OnboardDevices2& p)
380 {
381  p.enabled = IsBitSet(p.type, 7);
382  p.type = (OnBoardDeviceType)bits(p.type, 0, 6);
383  p.deviceNumber = bits(p.functionAndDeviceNumber, 3, 7);
384  p.functionNumber = bits(p.functionAndDeviceNumber, 0, 2);
385 }
386 
387 
388 //-----------------------------------------------------------------------------
389 // InitStructures
390 
391 template<class Structure>
392 void AddStructure(const Header* header, const Strings& strings, Structure*& listHead)
393 {
394  Structure* const p = (Structure*)calloc(1, sizeof(Structure)); // freed in Cleanup
395  p->header = *header;
396 
397  if(listHead)
398  {
399  // insert at end of list to preserve order of caches/slots
400  Structure* last = listHead;
401  while(last->next)
402  last = last->next;
403  last->next = p;
404  }
405  else
406  listHead = p;
407 
408  FieldInitializer fieldInitializer(header, strings);
409  VisitFields(*p, fieldInitializer);
410 
411  Fixup(*p);
412 }
413 
414 
416 {
417 #if OS_WIN
418  wfirmware::Table table;
420 #else
421  std::vector<u8> table;
422  return ERR::NOT_SUPPORTED;
423 #endif
424 
425  // (instead of counting the total string size, just use the
426  // SMBIOS size - typically 1-2 KB - as an upper bound.)
427  stringStoragePos = stringStorage = (char*)calloc(table.size(), sizeof(char)); // freed in Cleanup
428  if(!stringStorage)
430 
431  atexit(Cleanup);
432 
433  const Header* header = (const Header*)&table[0];
434  const Header* const end = (const Header*)(&table[0] + table.size());
435  for(;;)
436  {
437  if(header+1 > end)
438  {
439  debug_printf(L"SMBIOS: table not terminated\n");
440  break;
441  }
442  if(header->id == 127) // end
443  break;
444  if(header->length < sizeof(Header))
446 
447  const Header* next;
448  const Strings strings = ExtractStrings(header, (const char*)end, next);
449 
450  switch(header->id)
451  {
452 #define STRUCTURE(name, id) case id: AddStructure(header, strings, structures.name##_); break;
453  STRUCTURES
454 #undef STRUCTURE
455 
456  default:
457  if(32 < header->id && header->id < 126) // only mention non-proprietary structures of which we are not aware
458  debug_printf(L"SMBIOS: unknown structure type %d\n", header->id);
459  break;
460  }
461 
462  header = next;
463  }
464 
465  return INFO::OK;
466 }
467 
468 
469 //-----------------------------------------------------------------------------
470 // StringFromEnum
471 
472 template<class Enum>
473 std::string StringFromEnum(Enum UNUSED(field))
474 {
475  return "(unknown enumeration)";
476 }
477 
478 #define ENUM(enumerator, VALUE)\
479  if(field.value == VALUE) /* single bit flag or matching enumerator */\
480  return #enumerator;\
481  if(!is_pow2(VALUE)) /* these aren't bit flags */\
482  {\
483  allowFlags = false;\
484  string.clear();\
485  }\
486  if(allowFlags && (field.value & (VALUE)))\
487  {\
488  if(!string.empty())\
489  string += "|";\
490  string += #enumerator;\
491  }
492 #define ENUMERATION(name, type)\
493  template<>\
494  std::string StringFromEnum<name>(name field)\
495  {\
496  std::string string;\
497  bool allowFlags = true;\
498  name##_ENUMERATORS\
499  /* (don't warn about the value 0, e.g. optional fields) */\
500  if(string.empty() && field != 0)\
501  {\
502  std::stringstream ss;\
503  ss << "(unknown " << #name << " " << field.value << ")";\
504  return ss.str();\
505  }\
506  return string;\
507  }
509 #undef ENUMERATION
510 #undef ENUM
511 
512 
513 //-----------------------------------------------------------------------------
514 // FieldStringizer
515 
517 {
518  NONCOPYABLE(FieldStringizer); // reference member
519 public:
520  FieldStringizer(std::stringstream& ss)
521  : ss(ss)
522  {
523  }
524 
525  template<typename Field>
526  void operator()(size_t flags, Field& field, const char* name, const char* units)
527  {
528  if(flags & F_INTERNAL)
529  return;
530 
531  Write(flags, field, name, units, 0); // SFINAE
532  }
533 
534  // special case for sizes [bytes]
535  template<typename T>
536  void operator()(size_t flags, Size<T>& size, const char* name, const char* units)
537  {
538  if(flags & F_INTERNAL)
539  return;
540 
541  const u64 value = (u64)size.value;
542  if(value == 0)
543  return;
544 
545  u64 divisor;
546  if(value > GiB)
547  {
548  divisor = GiB;
549  units = " GiB";
550  }
551  else if(value > MiB)
552  {
553  divisor = MiB;
554  units = " MiB";
555  }
556  else if(value > KiB)
557  {
558  divisor = KiB;
559  units = " KiB";
560  }
561  else
562  {
563  divisor = 1;
564  units = " bytes";
565  }
566 
567  WriteName(name);
568 
569  // (avoid floating-point output unless division would truncate the value)
570  if(value % divisor == 0)
571  ss << (value/divisor);
572  else
573  ss << (double(value)/divisor);
574 
575  WriteUnits(units);
576  }
577 
578 private:
579  void WriteName(const char* name)
580  {
581  ss << " "; // indent
582  ss << name << ": ";
583  }
584 
585  void WriteUnits(const char* units)
586  {
587  ss << units;
588  ss << "\n";
589  }
590 
591  // enumerations and bit flags
592  template<typename Field>
593  void Write(size_t UNUSED(flags), Field& field, const char* name, const char* units, typename Field::Enum*)
594  {
595  // 0 usually means "not included in structure", but some packed
596  // enumerations actually use that value. therefore, only skip this
597  // field if it is zero AND no matching enumerator is found.
598  const std::string string = StringFromEnum(field);
599  if(string.empty())
600  return;
601 
602  WriteName(name);
603  ss << StringFromEnum(field);
604  WriteUnits(units);
605  }
606 
607  // all other field types
608  template<typename Field>
609  void Write(size_t flags, Field& field, const char* name, const char* units, ...)
610  {
611  // SMBIOS uses the smallest and sometimes also largest representable
612  // signed/unsigned value to indicate `unknown' (except enumerators -
613  // but those are handled in the other function overload), so skip them.
614  if(field == std::numeric_limits<Field>::min() || field == std::numeric_limits<Field>::max())
615  return;
616 
617  WriteName(name);
618 
619  if(flags & F_HEX)
620  ss << std::hex << std::uppercase;
621 
622  if(sizeof(field) == 1) // avoid printing as a character
623  ss << unsigned(field);
624  else
625  ss << field;
626 
627  if(flags & F_HEX)
628  ss << std::dec; // (revert to decimal, e.g. for displaying sizes)
629 
630  WriteUnits(units);
631  }
632 
633  std::stringstream& ss;
634 };
635 
636 template<>
637 void FieldStringizer::operator()<bool>(size_t flags, bool& value, const char* name, const char* units)
638 {
639  if(flags & F_INTERNAL)
640  return;
641 
642  WriteName(name);
643  ss << (value? "true" : "false");
644  WriteUnits(units);
645 }
646 
647 template<>
648 void FieldStringizer::operator()<Handle>(size_t flags, Handle& handle, const char* name, const char* units)
649 {
650  if(flags & F_INTERNAL)
651  return;
652 
653  // don't display useless handles
654  if(handle.value == 0 || handle.value == 0xFFFE || handle.value == 0xFFFF)
655  return;
656 
657  WriteName(name);
658  ss << handle.value;
659  WriteUnits(units);
660 }
661 
662 
663 template<>
664 void FieldStringizer::operator()<const char*>(size_t flags, const char*& value, const char* name, const char* units)
665 {
666  if(flags & F_INTERNAL)
667  return;
668 
669  // don't display useless strings
670  if(value == 0)
671  return;
672  std::string string(value);
673  const size_t lastChar = string.find_last_not_of(' ');
674  if(lastChar == std::string::npos) // nothing but spaces
675  return;
676  string.resize(lastChar+1); // strip trailing spaces
677  if(!strcasecmp(value, "To Be Filled By O.E.M."))
678  return;
679 
680  WriteName(name);
681  ss << "\"" << string << "\"";
682  WriteUnits(units);
683 }
684 
685 
686 //-----------------------------------------------------------------------------
687 // public interface
688 
690 {
691  static ModuleInitState initState;
692  Status ret = ModuleInit(&initState, InitStructures);
693  // (callers have to check if member pointers are nonzero anyway, so
694  // we always return a valid pointer to simplify most use cases.)
695  UNUSED2(ret);
696  return &structures;
697 }
698 
699 
700 template<class Structure>
701 void StringizeStructure(const char* name, Structure* p, std::stringstream& ss)
702 {
703  for(; p; p = p->next)
704  {
705  ss << "\n[" << name << "]\n";
706  FieldStringizer fieldStringizer(ss);
707  VisitFields(*p, fieldStringizer);
708  }
709 }
710 
712 {
713  std::stringstream ss;
714 #define STRUCTURE(name, id) StringizeStructure(#name, structures->name##_, ss);
715  STRUCTURES
716 #undef STRUCTURE
717 
718  return ss.str();
719 }
720 
721 } // namespace SMBIOS
#define ENUMERATIONS
Definition: smbios.h:36
#define u8
Definition: types.h:39
const Status _1
Definition: status.h:441
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
void StringizeStructure(const char *name, Structure *p, std::stringstream &ss)
Definition: smbios.cpp:701
const Strings & strings
Definition: smbios.cpp:202
const Status OK
Definition: status.h:386
void Read(Field &field,...)
Definition: smbios.cpp:195
void Fixup< MemoryDeviceMappedAddress >(MemoryDeviceMappedAddress &p)
Definition: smbios.cpp:340
std::string StringizeStructures(const Structures *structures)
Definition: smbios.cpp:711
void operator()(size_t flags, Size< T > &size, const char *name, const char *units)
Definition: smbios.cpp:536
static Status InitStructures()
Definition: smbios.cpp:415
void Fixup< MemoryArray >(MemoryArray &p)
Definition: smbios.cpp:314
const Status _3
Definition: status.h:443
void Fixup< OnBoardDevices >(OnBoardDevices &p)
Definition: smbios.cpp:307
void Fixup< SystemPowerSupply >(SystemPowerSupply &p)
Definition: smbios.cpp:370
#define INT32_MIN
Definition: wposix_types.h:72
Table GetTable(Provider provider, TableId tableId)
Definition: wfirmware.cpp:27
static ModuleInitState initState
Definition: h_mgr.cpp:742
std::vector< const char * > Strings
Definition: smbios.cpp:86
const Structures * GetStructures()
Definition: smbios.cpp:689
#define UINT32_MAX
Definition: wposix_types.h:73
static void Cleanup()
Definition: smbios.cpp:123
const Status NOT_SUPPORTED
Definition: status.h:429
static const size_t GiB
Definition: alignment.h:73
#define SAFE_FREE(p)
free memory ensuing from malloc and set the pointer to zero (thus making double-frees safe / a no-op)...
void Write(size_t flags, Field &field, const char *name, const char *units, typename Field::Enum *)
Definition: smbios.cpp:593
#define ENSURE(expr)
ensure the expression &lt;expr&gt; evaluates to non-zero.
Definition: debug.h:282
#define UNUSED2(param)
mark a function local variable or parameter as unused and avoid the corresponding compiler warning...
intptr_t ModuleInitState
initialization state of a module (class, source file, etc.) must be initialized to zero (e...
Definition: module_init.h:35
static Structures structures
Definition: smbios.cpp:121
void Read(Field &field, typename Field::T *)
Definition: smbios.cpp:189
std::vector< u8 > Table
Definition: wfirmware.h:13
bool IsBitSet(T value, size_t index)
Definition: bits.h:54
void Fixup< Cache >(Cache &p)
Definition: smbios.cpp:277
static const size_t KiB
Definition: alignment.h:71
FieldStringizer(std::stringstream &ss)
Definition: smbios.cpp:520
unsigned long DWORD
Definition: wgl.h:56
static const size_t MiB
Definition: alignment.h:72
void Fixup< MemoryArrayMappedAddress >(MemoryArrayMappedAddress &p)
Definition: smbios.cpp:331
void Fixup< Bios >(Bios &p)
Definition: smbios.cpp:251
void Write(size_t flags, Field &field, const char *name, const char *units,...)
Definition: smbios.cpp:609
i64 Status
Error handling system.
Definition: status.h:171
void Fixup< SystemSlot >(SystemSlot &p)
Definition: smbios.cpp:296
std::vector< TableId > TableIds
Definition: wfirmware.h:9
#define T(string_literal)
Definition: secure_crt.cpp:70
T bits(T num, size_t lo_idx, size_t hi_idx)
extract the value of bits hi_idx:lo_idx within num
Definition: bits.h:97
void WriteUnits(const char *units)
Definition: smbios.cpp:585
void Fixup< OnboardDevices2 >(OnboardDevices2 &p)
Definition: smbios.cpp:379
void Fixup< MemoryDevice >(MemoryDevice &p)
Definition: smbios.cpp:321
static char * stringStoragePos
Definition: smbios.cpp:118
void Fixup< Processor >(Processor &p)
Definition: smbios.cpp:257
#define u16
Definition: types.h:40
#define FOURCC_BE(a, b, c, d)
big-endian version of FOURCC
Definition: byte_order.h:61
#define u64
Definition: types.h:42
std::stringstream & ss
Definition: smbios.cpp:633
#define u32
Definition: types.h:41
FieldInitializer(const Header *header, const Strings &strings)
Definition: smbios.cpp:157
static Strings ExtractStrings(const Header *header, const char *end, const Header *&next)
Definition: smbios.cpp:88
void Fixup(Structure &structure)
Definition: smbios.cpp:245
#define WARN_RETURN(status)
Definition: status.h:255
static Handle handle(size_t idx, u64 tag)
Definition: h_mgr.cpp:121
#define INT16_MAX
Definition: wposix_types.h:67
const Status _2
Definition: status.h:442
NONCOPYABLE(FieldStringizer)
void WriteName(const char *name)
Definition: smbios.cpp:579
TableIds GetTableIDs(Provider provider)
Definition: wfirmware.cpp:8
#define STRUCTURES
Definition: smbios.h:86
NONCOPYABLE(FieldInitializer)
void AddStructure(const Header *header, const Strings &strings, Structure *&listHead)
Definition: smbios.cpp:392
void operator()(size_t flags, Field &field, const char *name, const char *units)
Definition: smbios.cpp:165
const Status NO_MEM
Definition: status.h:430
void operator()(size_t flags, Field &field, const char *name, const char *units)
Definition: smbios.cpp:526
Status ModuleInit(volatile ModuleInitState *initState, Status(*init)())
calls a user-defined init function if initState is zero.
Definition: module_init.cpp:40
void Fixup< CoolingDevice >(CoolingDevice &p)
Definition: smbios.cpp:356
std::string StringFromEnum(Enum field)
Definition: smbios.cpp:473
static char * stringStorage
Definition: smbios.cpp:117
void Fixup< TemperatureProbe >(TemperatureProbe &p)
Definition: smbios.cpp:363
void debug_printf(const wchar_t *fmt,...)
write a formatted string to the debug channel, subject to filtering (see below).
Definition: debug.cpp:142
void Fixup< VoltageProbe >(VoltageProbe &p)
Definition: smbios.cpp:349
#define RETURN_STATUS_IF_ERR(expression)
Definition: status.h:276