Hardware/Mainboard/SMBIOS.cs
author moel.mich
Sat, 02 Oct 2010 18:15:46 +0000
changeset 206 1fa8eddc24a7
parent 177 510f27ad65ac
child 220 e51749b206ee
permissions -rw-r--r--
Replaced HttpUtility.UrlEncode with Uri.EscapeDataString and deleted the reference to the System.Web assembly. The System.Web assembly seems to be missing on some .NET 4.0 installations (and the overhead of using it is a bit large, just for the UrlEncode method).
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@64
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2010
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@195
    51
    private readonly BIOSInformation biosInformation;
moel@195
    52
    private readonly BaseBoardInformation baseBoardInformation;
moel@64
    53
moel@167
    54
    private static string ReadSysFS(string path) {
moel@136
    55
      try {
moel@136
    56
        if (File.Exists(path)) {
moel@136
    57
          using (StreamReader reader = new StreamReader(path)) 
moel@136
    58
            return reader.ReadLine();
moel@136
    59
        } else {
moel@136
    60
          return null;
moel@136
    61
        }
moel@136
    62
      } catch {
moel@136
    63
        return null;
moel@136
    64
      }
moel@136
    65
    }
moel@136
    66
    
moel@64
    67
    public SMBIOS() {
moel@195
    68
      int p = (int)Environment.OSVersion.Platform;
moel@136
    69
      if ((p == 4) || (p == 128)) {
moel@136
    70
        this.raw = null;
moel@136
    71
        this.table = null;
moel@136
    72
        
moel@136
    73
        string boardVendor = ReadSysFS("/sys/class/dmi/id/board_vendor");
moel@136
    74
        string boardName = ReadSysFS("/sys/class/dmi/id/board_name");        
moel@136
    75
        string boardVersion = ReadSysFS("/sys/class/dmi/id/board_version");        
moel@136
    76
        this.baseBoardInformation = new BaseBoardInformation(
moel@136
    77
          boardVendor, boardName, boardVersion, null);
moel@136
    78
        
moel@136
    79
        string biosVendor = ReadSysFS("/sys/class/dmi/id/bios_vendor");
moel@136
    80
        string biosVersion = ReadSysFS("/sys/class/dmi/id/bios_version");
moel@136
    81
        this.biosInformation = new BIOSInformation(biosVendor, biosVersion);
moel@136
    82
        
moel@136
    83
      } else {              
moel@136
    84
        List<Structure> structureList = new List<Structure>();
moel@64
    85
moel@136
    86
        raw = null;
moel@136
    87
        try {
moel@167
    88
          ManagementObjectCollection collection;
moel@167
    89
          using (ManagementObjectSearcher searcher = 
moel@136
    90
            new ManagementObjectSearcher("root\\WMI", 
moel@167
    91
              "SELECT SMBiosData FROM MSSMBios_RawSMBiosTables")) {
moel@167
    92
            collection = searcher.Get();
moel@167
    93
          }
moel@136
    94
         
moel@136
    95
          foreach (ManagementObject mo in collection) {
moel@136
    96
            raw = (byte[])mo["SMBiosData"];
moel@89
    97
            break;
moel@136
    98
          }
moel@136
    99
        } catch { }
moel@136
   100
  
moel@136
   101
        if (raw != null && raw.Length > 0) {
moel@136
   102
          int offset = 0;
moel@136
   103
          byte type = raw[offset];
moel@136
   104
          while (offset + 4 < raw.Length && type != 127) {
moel@136
   105
  
moel@136
   106
            type = raw[offset];
moel@136
   107
            int length = raw[offset + 1];
moel@136
   108
            ushort handle = (ushort)((raw[offset + 2] << 8) | raw[offset + 3]);
moel@136
   109
  
moel@136
   110
            if (offset + length > raw.Length)
moel@136
   111
              break;
moel@136
   112
            byte[] data = new byte[length];
moel@136
   113
            Array.Copy(raw, offset, data, 0, length);
moel@136
   114
            offset += length;
moel@136
   115
  
moel@136
   116
            List<string> stringsList = new List<string>();
moel@136
   117
            if (offset < raw.Length && raw[offset] == 0)
moel@136
   118
              offset++;
moel@136
   119
  
moel@89
   120
            while (offset < raw.Length && raw[offset] != 0) {
moel@136
   121
              StringBuilder sb = new StringBuilder();
moel@136
   122
              while (offset < raw.Length && raw[offset] != 0) {
moel@136
   123
                sb.Append((char)raw[offset]); offset++;
moel@136
   124
              }
moel@136
   125
              offset++;
moel@136
   126
              stringsList.Add(sb.ToString());
moel@64
   127
            }
moel@64
   128
            offset++;
moel@136
   129
            switch (type) {
moel@136
   130
              case 0x00:
moel@136
   131
                this.biosInformation = new BIOSInformation(
moel@136
   132
                  type, handle, data, stringsList.ToArray());
moel@136
   133
                structureList.Add(this.biosInformation); break;
moel@136
   134
              case 0x02: this.baseBoardInformation = new BaseBoardInformation(
moel@136
   135
                  type, handle, data, stringsList.ToArray());
moel@136
   136
                structureList.Add(this.baseBoardInformation); break;
moel@136
   137
              default: structureList.Add(new Structure(
moel@136
   138
                type, handle, data, stringsList.ToArray())); break;
moel@136
   139
            }
moel@64
   140
          }
moel@64
   141
        }
moel@136
   142
              
moel@136
   143
        table = structureList.ToArray();
moel@89
   144
      }
moel@64
   145
    }
moel@64
   146
moel@64
   147
    public string GetReport() {
moel@136
   148
      StringBuilder r = new StringBuilder();
moel@64
   149
moel@167
   150
      if (BIOS != null) {
moel@167
   151
        r.Append("BIOS Vendor: "); r.AppendLine(BIOS.Vendor);
moel@167
   152
        r.Append("BIOS Version: "); r.AppendLine(BIOS.Version);
moel@64
   153
        r.AppendLine();
moel@64
   154
      }
moel@64
   155
moel@167
   156
      if (Board != null) {
moel@136
   157
        r.Append("Mainboard Manufacturer: ");
moel@167
   158
        r.AppendLine(Board.ManufacturerName);
moel@136
   159
        r.Append("Mainboard Name: ");
moel@167
   160
        r.AppendLine(Board.ProductName);
moel@167
   161
        r.Append("Mainboard Version: ");
moel@167
   162
        r.AppendLine(Board.Version);
moel@64
   163
        r.AppendLine();
moel@64
   164
      }
moel@136
   165
moel@136
   166
      if (raw != null) {
moel@136
   167
        string base64 = Convert.ToBase64String(raw);
moel@136
   168
        r.AppendLine("SMBIOS Table");
moel@136
   169
        r.AppendLine();
moel@136
   170
moel@136
   171
        for (int i = 0; i < Math.Ceiling(base64.Length / 64.0); i++) {
moel@136
   172
          r.Append(" ");
moel@136
   173
          for (int j = 0; j < 0x40; j++) {
moel@136
   174
            int index = (i << 6) | j;
moel@136
   175
            if (index < base64.Length) {              
moel@136
   176
              r.Append(base64[index]);
moel@136
   177
            }
moel@136
   178
          }
moel@136
   179
          r.AppendLine();
moel@136
   180
        }
moel@136
   181
        r.AppendLine();
moel@136
   182
      }
moel@136
   183
moel@64
   184
      return r.ToString();
moel@64
   185
    }
moel@64
   186
moel@64
   187
    public BIOSInformation BIOS {
moel@64
   188
      get { return biosInformation; }
moel@64
   189
    }
moel@64
   190
moel@64
   191
    public BaseBoardInformation Board {
moel@64
   192
      get { return baseBoardInformation; }
moel@64
   193
    }
moel@64
   194
moel@64
   195
    public class Structure {
moel@195
   196
      private readonly byte type;
moel@195
   197
      private readonly ushort handle;
moel@64
   198
moel@195
   199
      private readonly byte[] data;
moel@195
   200
      private readonly string[] strings;
moel@64
   201
moel@64
   202
      protected string GetString(int offset) {
moel@64
   203
        if (offset < data.Length && data[offset] > 0 &&
moel@64
   204
         data[offset] <= strings.Length)
moel@64
   205
          return strings[data[offset] - 1];
moel@64
   206
        else
moel@64
   207
          return "";
moel@64
   208
      }
moel@64
   209
moel@64
   210
      public Structure(byte type, ushort handle, byte[] data, string[] strings) 
moel@64
   211
      {
moel@64
   212
        this.type = type;
moel@64
   213
        this.handle = handle;
moel@64
   214
        this.data = data;
moel@64
   215
        this.strings = strings;
moel@64
   216
      }
moel@64
   217
moel@64
   218
      public byte Type { get { return type; } }
moel@64
   219
moel@64
   220
      public ushort Handle { get { return handle; } }
moel@64
   221
    }
moel@136
   222
      
moel@64
   223
    public class BIOSInformation : Structure {
moel@64
   224
moel@195
   225
      private readonly string vendor;
moel@195
   226
      private readonly string version;
moel@136
   227
      
moel@136
   228
      public BIOSInformation(string vendor, string version) 
moel@136
   229
        : base (0x00, 0, null, null) 
moel@136
   230
      {
moel@136
   231
        this.vendor = vendor;
moel@136
   232
        this.version = version;
moel@136
   233
      }
moel@136
   234
      
moel@64
   235
      public BIOSInformation(byte type, ushort handle, byte[] data,
moel@64
   236
        string[] strings)
moel@136
   237
        : base(type, handle, data, strings) 
moel@136
   238
      {
moel@64
   239
        this.vendor = GetString(0x04);
moel@64
   240
        this.version = GetString(0x05);
moel@64
   241
      }
moel@64
   242
moel@64
   243
      public string Vendor { get { return vendor; } }
moel@64
   244
moel@64
   245
      public string Version { get { return version; } }
moel@64
   246
    }
moel@64
   247
moel@64
   248
    public class BaseBoardInformation : Structure {
moel@64
   249
moel@195
   250
      private readonly string manufacturerName;
moel@195
   251
      private readonly string productName;
moel@195
   252
      private readonly string version;
moel@195
   253
      private readonly string serialNumber;
moel@195
   254
      private readonly Manufacturer manufacturer;
moel@195
   255
      private readonly Model model;
moel@64
   256
moel@195
   257
      private static Manufacturer GetManufacturer(string name) {               
moel@167
   258
        switch (name) {
moel@153
   259
          case "ASRock":
moel@195
   260
            return Manufacturer.ASRock;
moel@64
   261
          case "ASUSTeK Computer INC.":
moel@195
   262
            return Manufacturer.ASUS;
moel@152
   263
          case "Dell Inc.":
moel@195
   264
            return Manufacturer.Dell;
moel@64
   265
          case "DFI":
moel@72
   266
          case "DFI Inc.":            
moel@195
   267
            return Manufacturer.DFI;
moel@177
   268
          case "ECS":
moel@195
   269
            return Manufacturer.ECS;
moel@64
   270
          case "EPoX COMPUTER CO., LTD":
moel@195
   271
            return Manufacturer.EPoX;
moel@132
   272
          case "EVGA":
moel@195
   273
            return  Manufacturer.EVGA;
moel@152
   274
          case "First International Computer, Inc.":
moel@195
   275
            return Manufacturer.FIC;
moel@64
   276
          case "Gigabyte Technology Co., Ltd.":
moel@195
   277
            return  Manufacturer.Gigabyte;
moel@152
   278
          case "Hewlett-Packard":
moel@195
   279
            return  Manufacturer.HP;
moel@72
   280
          case "IBM":
moel@195
   281
            return  Manufacturer.IBM;
moel@64
   282
          case "MICRO-STAR INTERNATIONAL CO., LTD":
moel@72
   283
          case "MICRO-STAR INTERNATIONAL CO.,LTD":
moel@195
   284
            return  Manufacturer.MSI;
moel@152
   285
          case "XFX":
moel@195
   286
            return  Manufacturer.XFX;
moel@152
   287
          case "To be filled by O.E.M.":
moel@195
   288
            return  Manufacturer.Unknown;
moel@64
   289
          default:
moel@195
   290
            return  Manufacturer.Unknown;
moel@126
   291
        }
moel@136
   292
      }
moel@195
   293
moel@195
   294
      private static Model GetModel(string name) {
moel@167
   295
        switch (name) {
moel@153
   296
          case "880GMH/USB3":
moel@195
   297
            return Model._880GMH_USB3;
moel@133
   298
          case "Crosshair III Formula":
moel@195
   299
            return Model.Crosshair_III_Formula;
moel@133
   300
          case "M2N-SLI DELUXE":
moel@195
   301
            return Model.M2N_SLI_DELUXE;
moel@144
   302
          case "M4A79XTD EVO":
moel@195
   303
            return Model.M4A79XTD_EVO;
moel@130
   304
          case "P5W DH Deluxe":
moel@195
   305
            return Model.P5W_DH_Deluxe;
moel@152
   306
          case "P6X58D-E":
moel@195
   307
            return Model.P6X58D_E;
moel@174
   308
          case "Rampage Extreme":
moel@195
   309
            return Model.Rampage_Extreme;
moel@174
   310
          case "Rampage II GENE":
moel@195
   311
            return Model.Rampage_II_GENE;
moel@126
   312
          case "LP BI P45-T2RS Elite":
moel@195
   313
            return Model.LP_BI_P45_T2RS_Elite;
moel@126
   314
          case "LP DK P55-T3eH9":
moel@195
   315
            return Model.LP_DK_P55_T3eH9;
moel@177
   316
          case "A890GXM-A":
moel@195
   317
            return Model.A890GXM_A;
moel@132
   318
          case "X58 SLI Classified":
moel@195
   319
            return Model.X58_SLI_Classified;
moel@130
   320
          case "965P-S3":
moel@195
   321
            return Model._965P_S3;
moel@126
   322
          case "EP45-DS3R":
moel@195
   323
            return Model.EP45_DS3R;
moel@130
   324
          case "EP45-UD3R":
moel@195
   325
            return Model.EP45_UD3R;
moel@133
   326
          case "EX58-EXTREME":
moel@195
   327
            return Model.EX58_EXTREME;
moel@154
   328
          case "GA-MA770T-UD3":
moel@195
   329
            return Model.GA_MA770T_UD3;
moel@126
   330
          case "GA-MA785GMT-UD2H":
moel@195
   331
            return Model.GA_MA785GMT_UD2H;
moel@126
   332
          case "P35-DS3":
moel@195
   333
            return Model.P35_DS3;
moel@133
   334
          case "P35-DS3L":
moel@195
   335
            return Model.P35_DS3L;
moel@148
   336
          case "P55-UD4":
moel@195
   337
            return Model.P55_UD4;
moel@168
   338
          case "P55M-UD4":
moel@195
   339
            return Model.P55M_UD4;
moel@130
   340
          case "X38-DS5":
moel@195
   341
            return Model.X38_DS5;
moel@138
   342
          case "X58A-UD3R":
moel@195
   343
            return Model.X58A_UD3R;
moel@152
   344
          case "To be filled by O.E.M.":
moel@195
   345
            return Model.Unknown;
moel@126
   346
          default:
moel@195
   347
            return Model.Unknown;
moel@64
   348
        }
moel@64
   349
      }
moel@136
   350
      
moel@136
   351
      public BaseBoardInformation(string manufacturerName, string productName, 
moel@136
   352
        string version, string serialNumber) 
moel@136
   353
        : base(0x02, 0, null, null) 
moel@195
   354
      {
moel@195
   355
        this.manufacturerName = manufacturerName;
moel@195
   356
        this.manufacturer = GetManufacturer(manufacturerName);
moel@195
   357
        this.productName = productName;
moel@195
   358
        this.model = GetModel(productName);
moel@136
   359
        this.version = version;
moel@136
   360
        this.serialNumber = serialNumber;
moel@136
   361
      }
moel@136
   362
      
moel@136
   363
      public BaseBoardInformation(byte type, ushort handle, byte[] data,
moel@136
   364
        string[] strings)
moel@136
   365
        : base(type, handle, data, strings) {
moel@64
   366
moel@195
   367
        this.manufacturerName = GetString(0x04).Trim();
moel@195
   368
        this.manufacturer = GetManufacturer(this.manufacturerName);
moel@195
   369
        this.productName = GetString(0x05).Trim();
moel@195
   370
        this.model = GetModel(this.productName);
moel@136
   371
        this.version = GetString(0x06).Trim();
moel@136
   372
        this.serialNumber = GetString(0x07).Trim();               
moel@136
   373
      }
moel@136
   374
      
moel@64
   375
      public string ManufacturerName { get { return manufacturerName; } }
moel@64
   376
moel@64
   377
      public string ProductName { get { return productName; } }
moel@64
   378
moel@89
   379
      public string Version { get { return version; } }
moel@89
   380
moel@89
   381
      public string SerialNumber { get { return serialNumber; } }
moel@89
   382
moel@64
   383
      public Manufacturer Manufacturer { get { return manufacturer; } }
moel@89
   384
moel@126
   385
      public Model Model { get { return model; } }
moel@126
   386
moel@64
   387
    }
moel@64
   388
  }
moel@64
   389
}