// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. // If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // Copyright (C) LibreHardwareMonitor and Contributors. // Partial Copyright (C) Michael Möller and Contributors. // All Rights Reserved. using System; using System.Collections.Generic; using System.IO; using System.Text; using LibreHardwareMonitor.Interop; // ReSharper disable CommentTypo // ReSharper disable IdentifierTypo // ReSharper disable InconsistentNaming namespace LibreHardwareMonitor.Hardware; /// /// System enclosure security status based on DMTF SMBIOS Reference Specification v.3.3.0, Chapter 7.4.3. /// public enum SystemEnclosureSecurityStatus { Other = 1, Unknown, None, ExternalInterfaceLockedOut, ExternalInterfaceEnabled } /// /// System enclosure state based on DMTF SMBIOS Reference Specification v.3.3.0, Chapter 7.4.2. /// public enum SystemEnclosureState { Other = 1, Unknown, Safe, Warning, Critical, NonRecoverable } /// /// System enclosure type based on DMTF SMBIOS Reference Specification v.3.3.0, Chapter 7.4.1. /// public enum SystemEnclosureType { Other = 1, Unknown, Desktop, LowProfileDesktop, PizzaBox, MiniTower, Tower, Portable, Laptop, Notebook, HandHeld, DockingStation, AllInOne, SubNotebook, SpaceSaving, LunchBox, MainServerChassis, ExpansionChassis, SubChassis, BusExpansionChassis, PeripheralChassis, RaidChassis, RackMountChassis, SealedCasePc, MultiSystemChassis, CompactPci, AdvancedTca, Blade, BladeEnclosure, Tablet, Convertible, Detachable, IoTGateway, EmbeddedPc, MiniPc, StickPc } /// /// Processor family based on DMTF SMBIOS Reference Specification v.3.3.0, Chapter 7.5.2. /// public enum ProcessorFamily { Other = 1, Intel8086 = 3, Intel80286 = 4, Intel386, Intel486, Intel8087, Intel80287, Intel80387, Intel80487, IntelPentium, IntelPentiumPro, IntelPentiumII, IntelPentiumMMX, IntelCeleron, IntelPentiumIIXeon, IntelPentiumIII, M1, M2, IntelCeleronM, IntelPentium4HT, AmdDuron = 24, AmdK5, AmdK6, AmdK62, AmdK63, AmdAthlon, Amd2900, AmdK62Plus, PowerPc, PowerPc601, PowerPc603, PowerPc603Plus, PowerPc604, PowerPc620, PowerPcx704, PowerPc750, IntelCoreDuo, IntelCoreDuoMobile, IntelCoreSoloMobile, IntelAtom, IntelCoreM, IntelCoreM3, IntelCoreM5, IntelCoreM7, Alpha, Alpha21064, Alpha21066, Alpha21164, Alpha21164Pc, Alpha21164a, Alpha21264, Alpha21364, AmdTurionIIUltraDualCoreMobileM, AmdTurionDualCoreMobileM, AmdAthlonIIDualCoreM, AmdOpteron6100Series, AmdOpteron4100Series, AmdOpteron6200Series, AmdOpteron4200Series, AmdFxSeries, Mips, MipsR4000, MipsR4200, MipsR4400, MipsR4600, MipsR10000, AmdCSeries, AmdESeries, AmdASeries, AmdGSeries, AmdZSeries, AmdRSeries, AmdOpteron4300Series, AmdOpteron6300Series, AmdOpteron3300Series, AmdFireProSeries, Sparc, SuperSparc, MicroSparcII, MicroSparcIIep, UltraSparc, UltraSparcII, UltraSparcIIi, UltraSparcIII, UltraSparcIIIi, Motorola68040 = 96, Motorola68xxx, Motorola68000, Motorola68010, Motorola68020, Motorola68030, AmdAthlonX4QuadCore, AmdOpteronX1000Series, AmdOpteronX2000Series, AmdOpteronASeries, AmdOpteronX3000Series, AmdZen, Hobbit = 112, CrusoeTm5000 = 120, CrusoeTm3000, EfficeonTm8000, Weitek = 128, IntelItanium = 130, AmdAthlon64, AmdOpteron, AmdSempron, AmdTurio64Mobile, AmdOpteronDualCore, AmdAthlon64X2DualCore, AmdTurion64X2Mobile, AmdOpteronQuadCore, AmdOpteronThirdGen, AmdPhenomFXQuadCore, AmdPhenomX4QuadCore, AmdPhenomX2DualCore, AmdAthlonX2DualCore, PaRisc, PaRisc8500, PaRisc8000, PaRisc7300LC, PaRisc7200, PaRisc7100LC, PaRisc7100, V30 = 160, IntelXeon3200QuadCoreSeries, IntelXeon3000DualCoreSeries, IntelXeon5300QuadCoreSeries, IntelXeon5100DualCoreSeries, IntelXeon5000DualCoreSeries, IntelXeonLVDualCore, IntelXeonULVDualCore, IntelXeon7100Series, IntelXeon5400Series, IntelXeonQuadCore, IntelXeon5200DualCoreSeries, IntelXeon7200DualCoreSeries, IntelXeon7300QuadCoreSeries, IntelXeon7400QuadCoreSeries, IntelXeon7400MultiCoreSeries, IntelPentiumIIIXeon, IntelPentiumIIISpeedStep, IntelPentium4, IntelXeon, As400, IntelXeonMP, AmdAthlonXP, AmdAthlonMP, IntelItanium2, IntelPentiumM, IntelCeleronD, IntelPentiumD, IntelPentiumExtreme, IntelCoreSolo, IntelCore2Duo = 191, IntelCore2Solo, IntelCore2Extreme, IntelCore2Quad, IntelCore2ExtremeMobile, IntelCore2DuoMobile, IntelCore2SoloMobile, IntelCoreI7, IntelCeleronDualCore, Ibm390, PowerPcG4, PowerPcG5, Esa390G6, ZArchitecture, IntelCoreI5, IntelCoreI3, IntelCoreI9, ViaC7M = 210, ViaC7D, ViaC7, ViaEden, IntelXeonMultiCore, IntelXeon3xxxDualCoreSeries, IntelXeon3xxxQuadCoreSeries, ViaNano, IntelXeon5xxxDualCoreSeries, IntelXeon5xxxQuadCoreSeries, IntelXeon7xxxDualCoreSeries = 221, IntelXeon7xxxQuadCoreSeries, IntelXeon7xxxMultiCoreSeries, IntelXeon3400MultiCoreSeries, AmdOpteron3000Series = 228, AmdSempronII, AmdOpteronQuadCoreEmbedded, AmdPhenomTripleCore, AmdTurionUltraDualCoreMobile, AmdTurionDualCoreMobile, AmdTurionDualCore, AmdAthlonDualCore, AmdSempronSI, AmdPhenomII, AmdAthlonII, AmdOpteronSixCore, AmdSempronM, IntelI860 = 250, IntelI960, ArmV7 = 256, ArmV8, HitachiSh3, HitachiSh4, Arm, StrongArm, _686, MediaGX, MII, WinChip, Dsp, VideoProcessor } /// /// Processor characteristics based on DMTF SMBIOS Reference Specification v.3.3.0, Chapter 7.5.9. /// [Flags] public enum ProcessorCharacteristics { None = 0, _64BitCapable = 1, MultiCore = 2, HardwareThread = 4, ExecuteProtection = 8, EnhancedVirtualization = 16, PowerPerformanceControl = 32, _128BitCapable = 64 } /// /// Processor type based on DMTF SMBIOS Reference Specification v.3.3.0, Chapter 7.5.1. /// public enum ProcessorType { Other = 1, Unknown, CentralProcessor, MathProcessor, DspProcessor, VideoProcessor } /// /// Processor socket based on DMTF SMBIOS Reference Specification v.3.3.0, Chapter 7.5.5. /// public enum ProcessorSocket { Other = 1, Unknown, DaughterBoard, ZifSocket, PiggyBack, None, LifSocket, Zif423 = 13, A, Zif478, Zif754, Zif940, Zif939, MPga604, Lga771, Lga775, S1, AM2, F, Lga1366, G34, AM3, C32, Lga1156, Lga1567, Pga988A, Bga1288, RPga088B, Bga1023, Bga1224, Lga1155, Lga1356, Lga2011, FS1, FS2, FM1, FM2, Lga20113, Lga13563, Lga1150, Bga1168, Bga1234, Bga1364, AM4, Lga1151, Bga1356, Bga1440, Bga1515, Lga36471, SP3, SP3R2, Lga2066, Bga1510, Bga1528, Lga4189 } /// /// System wake-up type based on DMTF SMBIOS Reference Specification v.3.3.0, Chapter 7.2.2. /// public enum SystemWakeUp { Reserved, Other, Unknown, ApmTimer, ModemRing, LanRemote, PowerSwitch, PciPme, AcPowerRestored } /// /// Cache associativity based on DMTF SMBIOS Reference Specification v.3.3.0, Chapter 7.8.5. /// public enum CacheAssociativity { Other = 1, Unknown, DirectMapped, _2Way, _4Way, FullyAssociative, _8Way, _16Way, _12Way, _24Way, _32Way, _48Way, _64Way, _20Way } /// /// Processor cache level. /// public enum CacheDesignation { Other, L1, L2, L3 } /// /// Memory type. /// public enum MemoryType { Other = 0x01, Unknown = 0x02, DRAM = 0x03, EDRAM = 0x04, VRAM = 0x05, SRAM = 0x06, RAM = 0x07, ROM = 0x08, FLASH = 0x09, EEPROM = 0x0a, FEPROM = 0x0b, EPROM = 0x0c, CDRAM = 0x0d, _3DRAM = 0x0e, SDRAM = 0x0f, SGRAM = 0x10, RDRAM = 0x11, DDR = 0x12, DDR2 = 0x13, DDR2_FBDIMM = 0x14, DDR3 = 0x18, FBD2 = 0x19, DDR4 = 0x1a, LPDDR = 0x1b, LPDDR2 = 0x1c, LPDDR3 = 0x1d, LPDDR4 = 0x1e, LogicalNonVolatileDevice = 0x1f, HBM = 0x20, HBM2 = 0x21, DDR5 = 0x22, LPDDR5 = 0x23 } public class InformationBase { private readonly byte[] _data; private readonly IList _strings; /// /// Initializes a new instance of the class. /// /// The data. /// The strings. protected InformationBase(byte[] data, IList strings) { _data = data; _strings = strings; } /// /// Gets the byte. /// /// The offset. /// . protected byte GetByte(int offset) { if (offset < _data.Length && offset >= 0) return _data[offset]; return 0; } /// /// Gets the word. /// /// The offset. /// . protected ushort GetWord(int offset) { if (offset + 1 < _data.Length && offset >= 0) { return BitConverter.ToUInt16(_data, offset); } return 0; } /// /// Gets the dword. /// /// The offset. /// . protected uint GetDword(int offset) { if (offset + 3 < _data.Length && offset >= 0) { return BitConverter.ToUInt32(_data, offset); } return 0; } /// /// Gets the qword. /// /// The offset. /// . protected ulong GetQword(int offset) { if (offset + 7 < _data.Length && offset >= 0) { return BitConverter.ToUInt64(_data, offset); } return 0; } /// /// Gets the string. /// /// The offset. /// . protected string GetString(int offset) { if (offset < _data.Length && _data[offset] > 0 && _data[offset] <= _strings.Count) return _strings[_data[offset] - 1]; return string.Empty; } } /// /// Motherboard BIOS information obtained from the SMBIOS table. /// public class BiosInformation : InformationBase { internal BiosInformation(string vendor, string version, string date = null, ulong? size = null) : base(null, null) { Vendor = vendor; Version = version; Date = GetDate(date); Size = size; } internal BiosInformation(byte[] data, IList strings) : base(data, strings) { Vendor = GetString(0x04); Version = GetString(0x05); Date = GetDate(GetString(0x08)); Size = GetSize(); } /// /// Gets the BIOS release date. /// public DateTime? Date { get; } /// /// Gets the size of the physical device containing the BIOS. /// public ulong? Size { get; } /// /// Gets the string number of the BIOS Vendor’s Name. /// public string Vendor { get; } /// /// Gets the string number of the BIOS Version. This value is a free-form string that may contain Core and OEM version information. /// public string Version { get; } /// /// Gets the size. /// /// . private ulong? GetSize() { int biosRomSize = GetByte(0x09); ushort extendedBiosRomSize = GetWord(0x18); bool isExtendedBiosRomSize = biosRomSize == 0xFF && extendedBiosRomSize != 0; if (!isExtendedBiosRomSize) return 65536 * (ulong)(biosRomSize + 1); int unit = (extendedBiosRomSize & 0xC000) >> 14; ulong extendedSize = (ulong)(extendedBiosRomSize & ~0xC000) * 1024 * 1024; switch (unit) { case 0x00: return extendedSize; // Megabytes case 0x01: return extendedSize * 1024; // Gigabytes - might overflow in the future } return null; // Other patterns not defined in DMI 3.2.0 } /// /// Gets the date. /// /// The bios date. /// . private static DateTime? GetDate(string date) { string[] parts = (date ?? string.Empty).Split('/'); if (parts.Length == 3 && int.TryParse(parts[0], out int month) && int.TryParse(parts[1], out int day) && int.TryParse(parts[2], out int year)) { // Check if the SMBIOS specification is followed. if (month > 12 || day > 31) return null; return new DateTime(year < 100 ? 1900 + year : year, month, day); } return null; } } /// /// System information obtained from the SMBIOS table. /// public class SystemInformation : InformationBase { internal SystemInformation ( string manufacturerName, string productName, string version, string serialNumber, string family, SystemWakeUp wakeUp = SystemWakeUp.Unknown) : base(null, null) { ManufacturerName = manufacturerName; ProductName = productName; Version = version; SerialNumber = serialNumber; Family = family; WakeUp = wakeUp; } internal SystemInformation(byte[] data, IList strings) : base(data, strings) { ManufacturerName = GetString(0x04); ProductName = GetString(0x05); Version = GetString(0x06); SerialNumber = GetString(0x07); Family = GetString(0x1A); WakeUp = (SystemWakeUp)GetByte(0x18); } /// /// Gets the family associated with system. /// /// This text string identifies the family to which a particular computer belongs. A family refers to a set of computers that are similar but not identical from a hardware or software point of /// view. Typically, a family is composed of different computer models, which have different configurations and pricing points. Computers in the same family often have similar branding and cosmetic /// features. /// /// public string Family { get; } /// /// Gets the manufacturer name associated with system. /// public string ManufacturerName { get; } /// /// Gets the product name associated with system. /// public string ProductName { get; } /// /// Gets the serial number string associated with system. /// public string SerialNumber { get; } /// /// Gets the version string associated with system. /// public string Version { get; } /// /// Gets /// public SystemWakeUp WakeUp { get; } } /// /// System enclosure obtained from the SMBIOS table. /// public class SystemEnclosure : InformationBase { internal SystemEnclosure(byte[] data, IList strings) : base(data, strings) { ManufacturerName = GetString(0x04).Trim(); Version = GetString(0x06).Trim(); SerialNumber = GetString(0x07).Trim(); AssetTag = GetString(0x08).Trim(); RackHeight = GetByte(0x11); PowerCords = GetByte(0x12); SKU = GetString(0x15).Trim(); LockDetected = (GetByte(0x05) & 128) == 128; Type = (SystemEnclosureType)(GetByte(0x05) & 127); BootUpState = (SystemEnclosureState)GetByte(0x09); PowerSupplyState = (SystemEnclosureState)GetByte(0x0A); ThermalState = (SystemEnclosureState)GetByte(0x0B); SecurityStatus = (SystemEnclosureSecurityStatus)GetByte(0x0C); } /// /// Gets the asset tag associated with the enclosure or chassis. /// public string AssetTag { get; } /// /// Gets /// public SystemEnclosureState BootUpState { get; } /// /// Gets or sets the system enclosure lock. /// /// System enclosure lock is present if . Otherwise, either a lock is not present or it is unknown if the enclosure has a lock. public bool LockDetected { get; set; } /// /// Gets the string describing the chassis or enclosure manufacturer name. /// public string ManufacturerName { get; } /// /// Gets the number of power cords associated with the enclosure or chassis. /// public byte PowerCords { get; } /// /// Gets the state of the enclosure’s power supply (or supplies) when last booted. /// public SystemEnclosureState PowerSupplyState { get; } /// /// Gets the height of the enclosure, in 'U's. A U is a standard unit of measure for the height of a rack or rack-mountable component and is equal to 1.75 inches or 4.445 cm. A value of 0 /// indicates that the enclosure height is unspecified. /// public byte RackHeight { get; } /// /// Gets the physical security status of the enclosure when last booted. /// public SystemEnclosureSecurityStatus SecurityStatus { get; set; } /// /// Gets the string describing the chassis or enclosure serial number. /// public string SerialNumber { get; } /// /// Gets the string describing the chassis or enclosure SKU number. /// public string SKU { get; } /// /// Gets the thermal state of the enclosure when last booted. /// public SystemEnclosureState ThermalState { get; } /// /// Gets /// public SystemEnclosureType Type { get; } /// /// Gets the number of null-terminated string representing the chassis or enclosure version. /// public string Version { get; } } /// /// Motherboard information obtained from the SMBIOS table. /// public class BaseBoardInformation : InformationBase { internal BaseBoardInformation(string manufacturerName, string productName, string version, string serialNumber) : base(null, null) { ManufacturerName = manufacturerName; ProductName = productName; Version = version; SerialNumber = serialNumber; } internal BaseBoardInformation(byte[] data, IList strings) : base(data, strings) { ManufacturerName = GetString(0x04).Trim(); ProductName = GetString(0x05).Trim(); Version = GetString(0x06).Trim(); SerialNumber = GetString(0x07).Trim(); } /// /// Gets the value that represents the manufacturer's name. /// public string ManufacturerName { get; } /// /// Gets the value that represents the motherboard's name. /// public string ProductName { get; } /// /// Gets the value that represents the motherboard's serial number. /// public string SerialNumber { get; } /// /// Gets the value that represents the motherboard's revision number. /// public string Version { get; } } /// /// Processor information obtained from the SMBIOS table. /// public class ProcessorInformation : InformationBase { internal ProcessorInformation(byte[] data, IList strings) : base(data, strings) { SocketDesignation = GetString(0x04).Trim(); ManufacturerName = GetString(0x07).Trim(); Version = GetString(0x10).Trim(); CoreCount = GetByte(0x23) != 255 ? GetByte(0x23) : GetWord(0x2A); CoreEnabled = GetByte(0x24) != 255 ? GetByte(0x24) : GetWord(0x2C); ThreadCount = GetByte(0x25) != 255 ? GetByte(0x25) : GetWord(0x2E); ExternalClock = GetWord(0x12); MaxSpeed = GetWord(0x14); CurrentSpeed = GetWord(0x16); Serial = GetString(0x20).Trim(); Id = GetQword(0x08); Handle = GetWord(0x02); byte characteristics1 = GetByte(0x26); byte characteristics2 = GetByte(0x27); Characteristics = ProcessorCharacteristics.None; if (IsBitSet(characteristics1, 2)) Characteristics |= ProcessorCharacteristics._64BitCapable; if (IsBitSet(characteristics1, 3)) Characteristics |= ProcessorCharacteristics.MultiCore; if (IsBitSet(characteristics1, 4)) Characteristics |= ProcessorCharacteristics.HardwareThread; if (IsBitSet(characteristics1, 5)) Characteristics |= ProcessorCharacteristics.ExecuteProtection; if (IsBitSet(characteristics1, 6)) Characteristics |= ProcessorCharacteristics.EnhancedVirtualization; if (IsBitSet(characteristics1, 7)) Characteristics |= ProcessorCharacteristics.PowerPerformanceControl; if (IsBitSet(characteristics2, 0)) Characteristics |= ProcessorCharacteristics._128BitCapable; ProcessorType = (ProcessorType)GetByte(0x05); Socket = (ProcessorSocket)GetByte(0x19); int family = GetByte(0x06); Family = (ProcessorFamily)(family == 254 ? GetWord(0x28) : family); L1CacheHandle = GetWord(0x1A); L2CacheHandle = GetWord(0x1C); L3CacheHandle = GetWord(0x1E); bool IsBitSet(byte b, int pos) { return (b & (1 << pos)) != 0; } } /// /// Gets the characteristics of the processor. /// public ProcessorCharacteristics Characteristics { get; } /// /// Gets the value that represents the number of cores per processor socket. /// public ushort CoreCount { get; } /// /// Gets the value that represents the number of enabled cores per processor socket. /// public ushort CoreEnabled { get; } /// /// Gets the value that represents the current processor speed (in MHz). /// public ushort CurrentSpeed { get; } /// /// Gets the external Clock Frequency, in MHz. If the value is unknown, the field is set to 0. /// public ushort ExternalClock { get; } /// /// Gets /// public ProcessorFamily Family { get; } /// /// Gets the handle. /// /// The handle. public ushort Handle { get; } /// /// Gets the identifier. /// public ulong Id { get; } /// /// Gets the L1 cache handle. /// public ushort L1CacheHandle { get; } /// /// Gets the L2 cache handle. /// public ushort L2CacheHandle { get; } /// /// Gets the L3 cache handle. /// public ushort L3CacheHandle { get; } /// /// Gets the string number of Processor Manufacturer. /// public string ManufacturerName { get; } /// /// Gets the value that represents the maximum processor speed (in MHz) supported by the system for this processor socket. /// public ushort MaxSpeed { get; } /// /// Gets /// public ProcessorType ProcessorType { get; } /// /// Gets the value that represents the string number for the serial number of this processor. /// This value is set by the manufacturer and normally not changeable. /// public string Serial { get; } /// /// Gets /// public ProcessorSocket Socket { get; } /// /// Gets the string number for Reference Designation. /// public string SocketDesignation { get; } /// /// Gets the value that represents the number of threads per processor socket. /// public ushort ThreadCount { get; } /// /// Gets the value that represents the string number describing the Processor. /// public string Version { get; } } /// /// Cache information obtained from the SMBIOS table. /// public class CacheInformation : InformationBase { internal CacheInformation(byte[] data, IList strings) : base(data, strings) { Handle = GetWord(0x02); Designation = GetCacheDesignation(); Associativity = (CacheAssociativity)GetByte(0x12); Size = GetWord(0x09); } /// /// Gets /// public CacheAssociativity Associativity { get; } /// /// Gets /// public CacheDesignation Designation { get; } /// /// Gets the handle. /// public ushort Handle { get; } /// /// Gets the value that represents the installed cache size. /// public ushort Size { get; } /// /// Gets the cache designation. /// /// . private CacheDesignation GetCacheDesignation() { string rawCacheType = GetString(0x04); if (rawCacheType.Contains("L1")) return CacheDesignation.L1; if (rawCacheType.Contains("L2")) return CacheDesignation.L2; if (rawCacheType.Contains("L3")) return CacheDesignation.L3; return CacheDesignation.Other; } } /// /// Memory information obtained from the SMBIOS table. /// public class MemoryDevice : InformationBase { internal MemoryDevice(byte[] data, IList strings) : base(data, strings) { DeviceLocator = GetString(0x10).Trim(); BankLocator = GetString(0x11).Trim(); ManufacturerName = GetString(0x17).Trim(); SerialNumber = GetString(0x18).Trim(); PartNumber = GetString(0x1A).Trim(); Speed = GetWord(0x15); ConfiguredSpeed = GetWord(0x20); ConfiguredVoltage = GetWord(0x26); Size = GetWord(0x0C); if (Size == 0x7FFF) Size = GetDword(0x1C); Type = (MemoryType)GetByte(0x12); } /// /// Gets the string number of the string that identifies the physically labeled bank where the memory device is located. /// public string BankLocator { get; } /// /// Gets the string number of the string that identifies the physically-labeled socket or board position where the memory device is located. /// public string DeviceLocator { get; } /// /// Gets the string number for the manufacturer of this memory device. /// public string ManufacturerName { get; } /// /// Gets the string number for the part number of this memory device. /// public string PartNumber { get; } /// /// Gets the string number for the serial number of this memory device. /// public string SerialNumber { get; } /// /// Gets the size of the memory device. /// If the value is 0, no memory device is installed in the socket. /// If the value is 0xFFFF, the size is unknown. /// public uint Size { get; } /// /// Gets the value that identifies the maximum capable speed of the device, in mega transfers per second (MT/s). /// public ushort Speed { get; } /// /// Gets the configured speed of the device, in mega transfers per second (MT/s). /// public ushort ConfiguredSpeed { get; } /// /// Gets the configured voltage of this memory device, in millivolts (mV). /// public ushort ConfiguredVoltage { get; } /// /// Gets the type of this memory device. /// /// The type. public MemoryType Type { get; } } /// /// Reads and processes information encoded in an SMBIOS table. /// public class SMBios { private readonly byte[] _raw; private readonly Version _version; /// /// Initializes a new instance of the class. /// public SMBios() { if (Software.OperatingSystem.IsUnix) { _raw = null; string boardVendor = ReadSysFs("/sys/class/dmi/id/board_vendor"); string boardName = ReadSysFs("/sys/class/dmi/id/board_name"); string boardVersion = ReadSysFs("/sys/class/dmi/id/board_version"); Board = new BaseBoardInformation(boardVendor, boardName, boardVersion, null); string systemVendor = ReadSysFs("/sys/class/dmi/id/sys_vendor"); string productName = ReadSysFs("/sys/class/dmi/id/product_name"); string productVersion = ReadSysFs("/sys/class/dmi/id/product_version"); System = new SystemInformation(systemVendor, productName, productVersion, null, null); string biosVendor = ReadSysFs("/sys/class/dmi/id/bios_vendor"); string biosVersion = ReadSysFs("/sys/class/dmi/id/bios_version"); string biosDate = ReadSysFs("/sys/class/dmi/id/bios_date"); Bios = new BiosInformation(biosVendor, biosVersion, biosDate); MemoryDevices = Array.Empty(); ProcessorCaches = Array.Empty(); } else { List memoryDeviceList = new(); List processorCacheList = new(); List processorInformationList = new(); string[] tables = FirmwareTable.EnumerateTables(Kernel32.Provider.RSMB); if (tables is { Length: > 0 }) { _raw = FirmwareTable.GetTable(Kernel32.Provider.RSMB, tables[0]); if (_raw == null || _raw.Length == 0) return; byte majorVersion = _raw[1]; byte minorVersion = _raw[2]; if (majorVersion > 0 || minorVersion > 0) _version = new Version(majorVersion, minorVersion); if (_raw is { Length: > 0 }) { int offset = 8; byte type = _raw[offset]; while (offset + 4 < _raw.Length && type != 127) { type = _raw[offset]; int length = _raw[offset + 1]; if (offset + length > _raw.Length) break; byte[] data = new byte[length]; Array.Copy(_raw, offset, data, 0, length); offset += length; List strings = new(); if (offset < _raw.Length && _raw[offset] == 0) offset++; while (offset < _raw.Length && _raw[offset] != 0) { StringBuilder stringBuilder = new(); while (offset < _raw.Length && _raw[offset] != 0) { stringBuilder.Append((char)_raw[offset]); offset++; } offset++; strings.Add(stringBuilder.ToString()); } offset++; switch (type) { case 0x00: Bios = new BiosInformation(data, strings); break; case 0x01: System = new SystemInformation(data, strings); break; case 0x02: Board = new BaseBoardInformation(data, strings); break; case 0x03: SystemEnclosure = new SystemEnclosure(data, strings); break; case 0x04: processorInformationList.Add(new ProcessorInformation(data, strings)); break; case 0x07: processorCacheList.Add(new CacheInformation(data, strings)); break; case 0x11: memoryDeviceList.Add(new MemoryDevice(data, strings)); break; } } } } MemoryDevices = memoryDeviceList.ToArray(); ProcessorCaches = processorCacheList.ToArray(); Processors = processorInformationList.ToArray(); } } /// /// Gets /// public BiosInformation Bios { get; } /// /// Gets /// public BaseBoardInformation Board { get; } /// /// Gets /// public MemoryDevice[] MemoryDevices { get; } /// /// Gets /// public CacheInformation[] ProcessorCaches { get; } /// /// Gets /// public ProcessorInformation[] Processors { get; } /// /// Gets /// public SystemInformation System { get; } /// /// Gets /// public SystemEnclosure SystemEnclosure { get; } private static string ReadSysFs(string path) { try { if (File.Exists(path)) { using StreamReader reader = new(path); return reader.ReadLine(); } return string.Empty; } catch { return string.Empty; } } /// /// Report containing most of the information that could be read from the SMBIOS table. /// /// A formatted text string with computer information and the entire SMBIOS table. public string GetReport() { StringBuilder r = new(); if (_version != null) { r.Append("SMBios Version: "); r.AppendLine(_version.ToString(2)); r.AppendLine(); } if (Bios != null) { r.Append("BIOS Vendor: "); r.AppendLine(Bios.Vendor); r.Append("BIOS Version: "); r.AppendLine(Bios.Version); if (Bios.Date != null) { r.Append("BIOS Date: "); r.AppendLine(Bios.Date.Value.ToShortDateString()); } if (Bios.Size != null) { const int megabyte = 1024 * 1024; r.Append("BIOS Size: "); if (Bios.Size > megabyte) r.AppendLine((Bios.Size.Value / megabyte) + " MB"); else r.AppendLine((Bios.Size.Value / 1024) + " KB"); } r.AppendLine(); } if (System != null) { r.Append("System Manufacturer: "); r.AppendLine(System.ManufacturerName); r.Append("System Name: "); r.AppendLine(System.ProductName); r.Append("System Version: "); r.AppendLine(System.Version); r.Append("System Wakeup: "); r.AppendLine(System.WakeUp.ToString()); r.AppendLine(); } if (Board != null) { r.Append("Motherboard Manufacturer: "); r.AppendLine(Board.ManufacturerName); r.Append("Motherboard Name: "); r.AppendLine(Board.ProductName); r.Append("Motherboard Version: "); r.AppendLine(Board.Version); r.Append("Motherboard Serial: "); r.AppendLine(Board.SerialNumber); r.AppendLine(); } if (SystemEnclosure != null) { r.Append("System Enclosure Type: "); r.AppendLine(SystemEnclosure.Type.ToString()); r.Append("System Enclosure Manufacturer: "); r.AppendLine(SystemEnclosure.ManufacturerName); r.Append("System Enclosure Version: "); r.AppendLine(SystemEnclosure.Version); r.Append("System Enclosure Serial: "); r.AppendLine(SystemEnclosure.SerialNumber); r.Append("System Enclosure Asset Tag: "); r.AppendLine(SystemEnclosure.AssetTag); if (!string.IsNullOrEmpty(SystemEnclosure.SKU)) { r.Append("System Enclosure SKU: "); r.AppendLine(SystemEnclosure.SKU); } r.Append("System Enclosure Boot Up State: "); r.AppendLine(SystemEnclosure.BootUpState.ToString()); r.Append("System Enclosure Power Supply State: "); r.AppendLine(SystemEnclosure.PowerSupplyState.ToString()); r.Append("System Enclosure Thermal State: "); r.AppendLine(SystemEnclosure.ThermalState.ToString()); r.Append("System Enclosure Power Cords: "); r.AppendLine(SystemEnclosure.PowerCords.ToString()); if (SystemEnclosure.RackHeight > 0) { r.Append("System Enclosure Rack Height: "); r.AppendLine(SystemEnclosure.RackHeight.ToString()); } r.Append("System Enclosure Lock Detected: "); r.AppendLine(SystemEnclosure.LockDetected ? "Yes" : "No"); r.Append("System Enclosure Security Status: "); r.AppendLine(SystemEnclosure.SecurityStatus.ToString()); r.AppendLine(); } if (Processors != null) { foreach (ProcessorInformation processor in Processors) { r.Append("Processor Manufacturer: "); r.AppendLine(processor.ManufacturerName); r.Append("Processor Type: "); r.AppendLine(processor.ProcessorType.ToString()); r.Append("Processor Version: "); r.AppendLine(processor.Version); r.Append("Processor Serial: "); r.AppendLine(processor.Serial); r.Append("Processor Socket Destignation: "); r.AppendLine(processor.SocketDesignation); r.Append("Processor Socket: "); r.AppendLine(processor.Socket.ToString()); r.Append("Processor Version: "); r.AppendLine(processor.Version); r.Append("Processor Family: "); r.AppendLine(processor.Family.ToString()); r.Append("Processor Core Count: "); r.AppendLine(processor.CoreCount.ToString()); r.Append("Processor Core Enabled: "); r.AppendLine(processor.CoreEnabled.ToString()); r.Append("Processor Thread Count: "); r.AppendLine(processor.ThreadCount.ToString()); r.Append("Processor External Clock: "); r.Append(processor.ExternalClock); r.AppendLine(" Mhz"); r.Append("Processor Max Speed: "); r.Append(processor.MaxSpeed); r.AppendLine(" Mhz"); r.Append("Processor Current Speed: "); r.Append(processor.CurrentSpeed); r.AppendLine(" Mhz"); r.AppendLine(); } } if (ProcessorCaches != null) { foreach (CacheInformation processorCaches in ProcessorCaches) { r.Append("Cache [" + processorCaches.Designation + "] Size: "); r.AppendLine(processorCaches.Size.ToString()); r.Append("Cache [" + processorCaches.Designation + "] Associativity: "); r.AppendLine(processorCaches.Associativity.ToString().Replace("_", string.Empty)); r.AppendLine(); } } for (int i = 0; i < MemoryDevices.Length; i++) { r.Append("Memory Device [" + i + "] Manufacturer: "); r.AppendLine(MemoryDevices[i].ManufacturerName); r.Append("Memory Device [" + i + "] Part Number: "); r.AppendLine(MemoryDevices[i].PartNumber); r.Append("Memory Device [" + i + "] Device Locator: "); r.AppendLine(MemoryDevices[i].DeviceLocator); r.Append("Memory Device [" + i + "] Bank Locator: "); r.AppendLine(MemoryDevices[i].BankLocator); r.Append("Memory Device [" + i + "] Speed: "); r.AppendLine(MemoryDevices[i].Speed.ToString()); r.Append("Memory Device [" + i + "] Configured Speed: "); r.AppendLine(MemoryDevices[i].ConfiguredSpeed.ToString()); r.Append("Memory Device [" + i + "] Configured Voltage: "); r.AppendLine(MemoryDevices[i].ConfiguredVoltage.ToString()); r.Append("Memory Device [" + i + "] Size: "); r.Append(MemoryDevices[i].Size.ToString()); r.AppendLine(" MB"); r.AppendLine(); } if (_raw != null) { string base64 = Convert.ToBase64String(_raw); r.AppendLine("SMBios Table"); r.AppendLine(); for (int i = 0; i < Math.Ceiling(base64.Length / 64.0); i++) { r.Append(" "); for (int j = 0; j < 0x40; j++) { int index = (i << 6) | j; if (index < base64.Length) { r.Append(base64[index]); } } r.AppendLine(); } r.AppendLine(); } return r.ToString(); } }