Hardware/Mainboard/SMBIOS.cs
author moel.mich
Sat, 25 Jun 2011 14:46:28 +0000
changeset 304 16a86362c2ca
parent 290 22214a7e85a9
child 305 9652074e6ee5
permissions -rw-r--r--
Changed the maximum buffer size for double buffering of controls that isn't disposed after each draw call to the size of the screen. This should reduce the memory allocation and disposing on each sensor update. Also page faults are no longer increasing with this change.
moel@64
     1
/*
moel@64
     2
  
moel@64
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@64
     4
moel@64
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@64
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@64
     7
  the License. You may obtain a copy of the License at
moel@64
     8
 
moel@64
     9
  http://www.mozilla.org/MPL/
moel@64
    10
moel@64
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@64
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@64
    13
  for the specific language governing rights and limitations under the License.
moel@64
    14
moel@64
    15
  The Original Code is the Open Hardware Monitor code.
moel@64
    16
moel@64
    17
  The Initial Developer of the Original Code is 
moel@64
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@265
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2011
moel@64
    20
  the Initial Developer. All Rights Reserved.
moel@64
    21
moel@64
    22
  Contributor(s):
moel@64
    23
moel@64
    24
  Alternatively, the contents of this file may be used under the terms of
moel@64
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@64
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@64
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@64
    28
  of those above. If you wish to allow use of your version of this file only
moel@64
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@64
    30
  use your version of this file under the terms of the MPL, indicate your
moel@64
    31
  decision by deleting the provisions above and replace them with the notice
moel@64
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@64
    33
  the provisions above, a recipient may use your version of this file under
moel@64
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@64
    35
 
moel@64
    36
*/
moel@64
    37
moel@64
    38
using System;
moel@64
    39
using System.Collections.Generic;
moel@136
    40
using System.IO;
moel@64
    41
using System.Management;
moel@64
    42
using System.Text;
moel@64
    43
moel@64
    44
namespace OpenHardwareMonitor.Hardware.Mainboard {
moel@64
    45
moel@165
    46
  internal class SMBIOS {
moel@64
    47
moel@195
    48
    private readonly byte[] raw;
moel@195
    49
    private readonly Structure[] table;
moel@64
    50
moel@242
    51
    private readonly Version version;
moel@195
    52
    private readonly BIOSInformation biosInformation;
moel@195
    53
    private readonly BaseBoardInformation baseBoardInformation;
moel@64
    54
moel@167
    55
    private static string ReadSysFS(string path) {
moel@136
    56
      try {
moel@136
    57
        if (File.Exists(path)) {
moel@136
    58
          using (StreamReader reader = new StreamReader(path)) 
moel@136
    59
            return reader.ReadLine();
moel@136
    60
        } else {
moel@136
    61
          return null;
moel@136
    62
        }
moel@136
    63
      } catch {
moel@136
    64
        return null;
moel@136
    65
      }
moel@136
    66
    }
moel@136
    67
    
moel@64
    68
    public SMBIOS() {
moel@195
    69
      int p = (int)Environment.OSVersion.Platform;
moel@136
    70
      if ((p == 4) || (p == 128)) {
moel@136
    71
        this.raw = null;
moel@136
    72
        this.table = null;
moel@136
    73
        
moel@136
    74
        string boardVendor = ReadSysFS("/sys/class/dmi/id/board_vendor");
moel@136
    75
        string boardName = ReadSysFS("/sys/class/dmi/id/board_name");        
moel@136
    76
        string boardVersion = ReadSysFS("/sys/class/dmi/id/board_version");        
moel@136
    77
        this.baseBoardInformation = new BaseBoardInformation(
moel@136
    78
          boardVendor, boardName, boardVersion, null);
moel@136
    79
        
moel@136
    80
        string biosVendor = ReadSysFS("/sys/class/dmi/id/bios_vendor");
moel@136
    81
        string biosVersion = ReadSysFS("/sys/class/dmi/id/bios_version");
moel@136
    82
        this.biosInformation = new BIOSInformation(biosVendor, biosVersion);
moel@136
    83
        
moel@136
    84
      } else {              
moel@136
    85
        List<Structure> structureList = new List<Structure>();
moel@64
    86
moel@136
    87
        raw = null;
moel@242
    88
        byte majorVersion = 0;
moel@242
    89
        byte minorVersion = 0;
moel@136
    90
        try {
moel@167
    91
          ManagementObjectCollection collection;
moel@167
    92
          using (ManagementObjectSearcher searcher = 
moel@136
    93
            new ManagementObjectSearcher("root\\WMI", 
moel@242
    94
              "SELECT * FROM MSSMBios_RawSMBiosTables")) {
moel@167
    95
            collection = searcher.Get();
moel@167
    96
          }
moel@136
    97
         
moel@136
    98
          foreach (ManagementObject mo in collection) {
moel@136
    99
            raw = (byte[])mo["SMBiosData"];
moel@242
   100
            majorVersion = (byte)mo["SmbiosMajorVersion"];
moel@242
   101
            minorVersion = (byte)mo["SmbiosMinorVersion"];            
moel@89
   102
            break;
moel@136
   103
          }
moel@136
   104
        } catch { }
moel@242
   105
moel@242
   106
        if (majorVersion > 0 || minorVersion > 0)
moel@242
   107
          version = new Version(majorVersion, minorVersion);
moel@136
   108
  
moel@136
   109
        if (raw != null && raw.Length > 0) {
moel@136
   110
          int offset = 0;
moel@136
   111
          byte type = raw[offset];
moel@136
   112
          while (offset + 4 < raw.Length && type != 127) {
moel@136
   113
  
moel@136
   114
            type = raw[offset];
moel@136
   115
            int length = raw[offset + 1];
moel@136
   116
            ushort handle = (ushort)((raw[offset + 2] << 8) | raw[offset + 3]);
moel@136
   117
  
moel@136
   118
            if (offset + length > raw.Length)
moel@136
   119
              break;
moel@136
   120
            byte[] data = new byte[length];
moel@136
   121
            Array.Copy(raw, offset, data, 0, length);
moel@136
   122
            offset += length;
moel@136
   123
  
moel@136
   124
            List<string> stringsList = new List<string>();
moel@136
   125
            if (offset < raw.Length && raw[offset] == 0)
moel@136
   126
              offset++;
moel@136
   127
  
moel@89
   128
            while (offset < raw.Length && raw[offset] != 0) {
moel@136
   129
              StringBuilder sb = new StringBuilder();
moel@136
   130
              while (offset < raw.Length && raw[offset] != 0) {
moel@136
   131
                sb.Append((char)raw[offset]); offset++;
moel@136
   132
              }
moel@136
   133
              offset++;
moel@136
   134
              stringsList.Add(sb.ToString());
moel@64
   135
            }
moel@64
   136
            offset++;
moel@136
   137
            switch (type) {
moel@136
   138
              case 0x00:
moel@136
   139
                this.biosInformation = new BIOSInformation(
moel@136
   140
                  type, handle, data, stringsList.ToArray());
moel@136
   141
                structureList.Add(this.biosInformation); break;
moel@136
   142
              case 0x02: this.baseBoardInformation = new BaseBoardInformation(
moel@136
   143
                  type, handle, data, stringsList.ToArray());
moel@136
   144
                structureList.Add(this.baseBoardInformation); break;
moel@136
   145
              default: structureList.Add(new Structure(
moel@136
   146
                type, handle, data, stringsList.ToArray())); break;
moel@136
   147
            }
moel@64
   148
          }
moel@64
   149
        }
moel@136
   150
              
moel@136
   151
        table = structureList.ToArray();
moel@89
   152
      }
moel@64
   153
    }
moel@64
   154
moel@64
   155
    public string GetReport() {
moel@136
   156
      StringBuilder r = new StringBuilder();
moel@64
   157
moel@242
   158
      if (version != null) {
moel@242
   159
        r.Append("SMBIOS Version: "); r.AppendLine(version.ToString(2));
moel@242
   160
        r.AppendLine();
moel@242
   161
      }
moel@242
   162
moel@167
   163
      if (BIOS != null) {
moel@167
   164
        r.Append("BIOS Vendor: "); r.AppendLine(BIOS.Vendor);
moel@167
   165
        r.Append("BIOS Version: "); r.AppendLine(BIOS.Version);
moel@64
   166
        r.AppendLine();
moel@64
   167
      }
moel@64
   168
moel@167
   169
      if (Board != null) {
moel@136
   170
        r.Append("Mainboard Manufacturer: ");
moel@167
   171
        r.AppendLine(Board.ManufacturerName);
moel@136
   172
        r.Append("Mainboard Name: ");
moel@167
   173
        r.AppendLine(Board.ProductName);
moel@167
   174
        r.Append("Mainboard Version: ");
moel@167
   175
        r.AppendLine(Board.Version);
moel@64
   176
        r.AppendLine();
moel@64
   177
      }
moel@136
   178
moel@136
   179
      if (raw != null) {
moel@136
   180
        string base64 = Convert.ToBase64String(raw);
moel@136
   181
        r.AppendLine("SMBIOS Table");
moel@136
   182
        r.AppendLine();
moel@136
   183
moel@136
   184
        for (int i = 0; i < Math.Ceiling(base64.Length / 64.0); i++) {
moel@136
   185
          r.Append(" ");
moel@136
   186
          for (int j = 0; j < 0x40; j++) {
moel@136
   187
            int index = (i << 6) | j;
moel@136
   188
            if (index < base64.Length) {              
moel@136
   189
              r.Append(base64[index]);
moel@136
   190
            }
moel@136
   191
          }
moel@136
   192
          r.AppendLine();
moel@136
   193
        }
moel@136
   194
        r.AppendLine();
moel@136
   195
      }
moel@136
   196
moel@64
   197
      return r.ToString();
moel@64
   198
    }
moel@64
   199
moel@64
   200
    public BIOSInformation BIOS {
moel@64
   201
      get { return biosInformation; }
moel@64
   202
    }
moel@64
   203
moel@64
   204
    public BaseBoardInformation Board {
moel@64
   205
      get { return baseBoardInformation; }
moel@64
   206
    }
moel@64
   207
moel@64
   208
    public class Structure {
moel@195
   209
      private readonly byte type;
moel@195
   210
      private readonly ushort handle;
moel@64
   211
moel@195
   212
      private readonly byte[] data;
moel@195
   213
      private readonly string[] strings;
moel@64
   214
moel@64
   215
      protected string GetString(int offset) {
moel@64
   216
        if (offset < data.Length && data[offset] > 0 &&
moel@64
   217
         data[offset] <= strings.Length)
moel@64
   218
          return strings[data[offset] - 1];
moel@64
   219
        else
moel@64
   220
          return "";
moel@64
   221
      }
moel@64
   222
moel@64
   223
      public Structure(byte type, ushort handle, byte[] data, string[] strings) 
moel@64
   224
      {
moel@64
   225
        this.type = type;
moel@64
   226
        this.handle = handle;
moel@64
   227
        this.data = data;
moel@64
   228
        this.strings = strings;
moel@64
   229
      }
moel@64
   230
moel@64
   231
      public byte Type { get { return type; } }
moel@64
   232
moel@64
   233
      public ushort Handle { get { return handle; } }
moel@64
   234
    }
moel@136
   235
      
moel@64
   236
    public class BIOSInformation : Structure {
moel@64
   237
moel@195
   238
      private readonly string vendor;
moel@195
   239
      private readonly string version;
moel@136
   240
      
moel@136
   241
      public BIOSInformation(string vendor, string version) 
moel@136
   242
        : base (0x00, 0, null, null) 
moel@136
   243
      {
moel@136
   244
        this.vendor = vendor;
moel@136
   245
        this.version = version;
moel@136
   246
      }
moel@136
   247
      
moel@64
   248
      public BIOSInformation(byte type, ushort handle, byte[] data,
moel@64
   249
        string[] strings)
moel@136
   250
        : base(type, handle, data, strings) 
moel@136
   251
      {
moel@64
   252
        this.vendor = GetString(0x04);
moel@64
   253
        this.version = GetString(0x05);
moel@64
   254
      }
moel@64
   255
moel@64
   256
      public string Vendor { get { return vendor; } }
moel@64
   257
moel@64
   258
      public string Version { get { return version; } }
moel@64
   259
    }
moel@64
   260
moel@64
   261
    public class BaseBoardInformation : Structure {
moel@64
   262
moel@195
   263
      private readonly string manufacturerName;
moel@195
   264
      private readonly string productName;
moel@195
   265
      private readonly string version;
moel@195
   266
      private readonly string serialNumber;
moel@195
   267
      private readonly Manufacturer manufacturer;
moel@195
   268
      private readonly Model model;
moel@64
   269
moel@195
   270
      private static Manufacturer GetManufacturer(string name) {               
moel@167
   271
        switch (name) {
moel@296
   272
          case "Alienware":
moel@296
   273
            return Manufacturer.Alienware;
moel@296
   274
          case "Apple Inc.":
moel@296
   275
            return Manufacturer.Apple;
moel@153
   276
          case "ASRock":
moel@195
   277
            return Manufacturer.ASRock;
moel@64
   278
          case "ASUSTeK Computer INC.":
moel@195
   279
            return Manufacturer.ASUS;
moel@152
   280
          case "Dell Inc.":
moel@195
   281
            return Manufacturer.Dell;
moel@64
   282
          case "DFI":
moel@72
   283
          case "DFI Inc.":            
moel@195
   284
            return Manufacturer.DFI;
moel@177
   285
          case "ECS":
moel@195
   286
            return Manufacturer.ECS;
moel@64
   287
          case "EPoX COMPUTER CO., LTD":
moel@195
   288
            return Manufacturer.EPoX;
moel@132
   289
          case "EVGA":
moel@195
   290
            return  Manufacturer.EVGA;
moel@152
   291
          case "First International Computer, Inc.":
moel@195
   292
            return Manufacturer.FIC;
moel@296
   293
          case "FUJITSU":
moel@296
   294
          case "FUJITSU SIEMENS":
moel@296
   295
            return Manufacturer.Fujitsu;
moel@64
   296
          case "Gigabyte Technology Co., Ltd.":
moel@195
   297
            return  Manufacturer.Gigabyte;
moel@152
   298
          case "Hewlett-Packard":
moel@195
   299
            return  Manufacturer.HP;
moel@72
   300
          case "IBM":
moel@195
   301
            return  Manufacturer.IBM;
moel@296
   302
          case "Intel":
moel@296
   303
          case "Intel Corp.":
moel@296
   304
          case "Intel Corporation":
moel@296
   305
          case "INTEL Corporation":
moel@296
   306
            return Manufacturer.Intel;   
moel@296
   307
          case "Lenovo":
moel@296
   308
          case "LENOVO":
moel@296
   309
            return Manufacturer.Lenovo;
moel@296
   310
          case "Micro-Star International":
moel@64
   311
          case "MICRO-STAR INTERNATIONAL CO., LTD":
moel@72
   312
          case "MICRO-STAR INTERNATIONAL CO.,LTD":
moel@296
   313
          case "MSI":
moel@195
   314
            return  Manufacturer.MSI;
moel@296
   315
          case "Supermicro":
moel@296
   316
            return Manufacturer.Supermicro;
moel@296
   317
          case "TOSHIBA":
moel@296
   318
            return Manufacturer.Toshiba;
moel@152
   319
          case "XFX":
moel@195
   320
            return  Manufacturer.XFX;
moel@152
   321
          case "To be filled by O.E.M.":
moel@195
   322
            return  Manufacturer.Unknown;
moel@64
   323
          default:
moel@195
   324
            return  Manufacturer.Unknown;
moel@126
   325
        }
moel@136
   326
      }
moel@195
   327
moel@195
   328
      private static Model GetModel(string name) {
moel@167
   329
        switch (name) {
moel@153
   330
          case "880GMH/USB3":
moel@195
   331
            return Model._880GMH_USB3;
moel@220
   332
          case "ASRock AOD790GX/128M":
moel@220
   333
            return Model.AOD790GX_128M;
moel@221
   334
          case "P55 Deluxe":
moel@221
   335
            return Model.P55_Deluxe;
moel@133
   336
          case "Crosshair III Formula":
moel@195
   337
            return Model.Crosshair_III_Formula;
moel@133
   338
          case "M2N-SLI DELUXE":
moel@195
   339
            return Model.M2N_SLI_DELUXE;
moel@144
   340
          case "M4A79XTD EVO":
moel@195
   341
            return Model.M4A79XTD_EVO;
moel@130
   342
          case "P5W DH Deluxe":
moel@195
   343
            return Model.P5W_DH_Deluxe;
moel@152
   344
          case "P6X58D-E":
moel@195
   345
            return Model.P6X58D_E;
moel@265
   346
          case "P8P67 PRO":
moel@265
   347
            return Model.P8P67_PRO;
moel@276
   348
          case "P8P67-M PRO":
moel@276
   349
            return Model.P8P67_M_PRO;
moel@174
   350
          case "Rampage Extreme":
moel@195
   351
            return Model.Rampage_Extreme;
moel@174
   352
          case "Rampage II GENE":
moel@195
   353
            return Model.Rampage_II_GENE;
moel@126
   354
          case "LP BI P45-T2RS Elite":
moel@195
   355
            return Model.LP_BI_P45_T2RS_Elite;
moel@126
   356
          case "LP DK P55-T3eH9":
moel@195
   357
            return Model.LP_DK_P55_T3eH9;
moel@177
   358
          case "A890GXM-A":
moel@195
   359
            return Model.A890GXM_A;
moel@132
   360
          case "X58 SLI Classified":
moel@195
   361
            return Model.X58_SLI_Classified;
moel@130
   362
          case "965P-S3":
moel@195
   363
            return Model._965P_S3;
moel@126
   364
          case "EP45-DS3R":
moel@195
   365
            return Model.EP45_DS3R;
moel@130
   366
          case "EP45-UD3R":
moel@195
   367
            return Model.EP45_UD3R;
moel@133
   368
          case "EX58-EXTREME":
moel@195
   369
            return Model.EX58_EXTREME;
moel@154
   370
          case "GA-MA770T-UD3":
moel@195
   371
            return Model.GA_MA770T_UD3;
moel@126
   372
          case "GA-MA785GMT-UD2H":
moel@195
   373
            return Model.GA_MA785GMT_UD2H;
moel@290
   374
          case "H67A-UD3H-B3":
moel@290
   375
            return Model.H67A_UD3H_B3;
moel@126
   376
          case "P35-DS3":
moel@195
   377
            return Model.P35_DS3;
moel@133
   378
          case "P35-DS3L":
moel@195
   379
            return Model.P35_DS3L;
moel@148
   380
          case "P55-UD4":
moel@195
   381
            return Model.P55_UD4;
moel@168
   382
          case "P55M-UD4":
moel@195
   383
            return Model.P55M_UD4;
moel@278
   384
          case "P67A-UD4-B3":
moel@278
   385
            return Model.P67A_UD4_B3;
moel@130
   386
          case "X38-DS5":
moel@195
   387
            return Model.X38_DS5;
moel@138
   388
          case "X58A-UD3R":
moel@195
   389
            return Model.X58A_UD3R;
moel@296
   390
          case "Base Board Product Name":
moel@152
   391
          case "To be filled by O.E.M.":
moel@195
   392
            return Model.Unknown;
moel@126
   393
          default:
moel@195
   394
            return Model.Unknown;
moel@64
   395
        }
moel@64
   396
      }
moel@136
   397
      
moel@136
   398
      public BaseBoardInformation(string manufacturerName, string productName, 
moel@136
   399
        string version, string serialNumber) 
moel@136
   400
        : base(0x02, 0, null, null) 
moel@195
   401
      {
moel@195
   402
        this.manufacturerName = manufacturerName;
moel@195
   403
        this.manufacturer = GetManufacturer(manufacturerName);
moel@195
   404
        this.productName = productName;
moel@195
   405
        this.model = GetModel(productName);
moel@136
   406
        this.version = version;
moel@136
   407
        this.serialNumber = serialNumber;
moel@136
   408
      }
moel@136
   409
      
moel@136
   410
      public BaseBoardInformation(byte type, ushort handle, byte[] data,
moel@136
   411
        string[] strings)
moel@136
   412
        : base(type, handle, data, strings) {
moel@64
   413
moel@195
   414
        this.manufacturerName = GetString(0x04).Trim();
moel@195
   415
        this.manufacturer = GetManufacturer(this.manufacturerName);
moel@195
   416
        this.productName = GetString(0x05).Trim();
moel@195
   417
        this.model = GetModel(this.productName);
moel@136
   418
        this.version = GetString(0x06).Trim();
moel@136
   419
        this.serialNumber = GetString(0x07).Trim();               
moel@136
   420
      }
moel@136
   421
      
moel@64
   422
      public string ManufacturerName { get { return manufacturerName; } }
moel@64
   423
moel@64
   424
      public string ProductName { get { return productName; } }
moel@64
   425
moel@89
   426
      public string Version { get { return version; } }
moel@89
   427
moel@89
   428
      public string SerialNumber { get { return serialNumber; } }
moel@89
   429
moel@64
   430
      public Manufacturer Manufacturer { get { return manufacturer; } }
moel@89
   431
moel@126
   432
      public Model Model { get { return model; } }
moel@126
   433
moel@64
   434
    }
moel@64
   435
  }
moel@64
   436
}