Hardware/Computer.cs
author moel.mich
Sun, 08 May 2011 22:10:13 +0000
changeset 279 6bce967ba1b5
parent 256 6dc6410489f4
child 324 c6ee430d6995
permissions -rw-r--r--
Fixed the bus and core clock reading on AMD family 10h model Ah CPUs. The new "Core Performance Boost" feature of these CPUs resulted in very low accuracy of the bus speed (and as a consequence also an inaccurate TSC multiplier). This fixed Issue 205.
moel@28
     1
/*
moel@28
     2
  
moel@28
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@28
     4
moel@28
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@28
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@28
     7
  the License. You may obtain a copy of the License at
moel@28
     8
 
moel@28
     9
  http://www.mozilla.org/MPL/
moel@28
    10
moel@28
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@28
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@28
    13
  for the specific language governing rights and limitations under the License.
moel@28
    14
moel@28
    15
  The Original Code is the Open Hardware Monitor code.
moel@28
    16
moel@28
    17
  The Initial Developer of the Original Code is 
moel@28
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@28
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2010
moel@28
    20
  the Initial Developer. All Rights Reserved.
moel@28
    21
moel@28
    22
  Contributor(s):
moel@28
    23
moel@28
    24
  Alternatively, the contents of this file may be used under the terms of
moel@28
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@28
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@28
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@28
    28
  of those above. If you wish to allow use of your version of this file only
moel@28
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@28
    30
  use your version of this file under the terms of the MPL, indicate your
moel@28
    31
  decision by deleting the provisions above and replace them with the notice
moel@28
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@28
    33
  the provisions above, a recipient may use your version of this file under
moel@28
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@28
    35
 
moel@28
    36
*/
moel@28
    37
moel@28
    38
using System;
moel@28
    39
using System.Collections.Generic;
moel@182
    40
using System.Globalization;
moel@28
    41
using System.IO;
moel@167
    42
using System.Security.Permissions;
moel@236
    43
using System.Reflection;
moel@167
    44
moel@28
    45
namespace OpenHardwareMonitor.Hardware {
moel@28
    46
moel@83
    47
  public class Computer : IComputer {
moel@28
    48
moel@195
    49
    private readonly List<IGroup> groups = new List<IGroup>();
moel@195
    50
    private readonly ISettings settings;
moel@28
    51
moel@195
    52
    private bool open;
moel@195
    53
    private bool hddEnabled;    
moel@28
    54
moel@165
    55
    public Computer() {
moel@165
    56
      this.settings = new Settings();
moel@165
    57
    }
moel@165
    58
moel@165
    59
    public Computer(ISettings settings) {
moel@195
    60
      this.settings = settings ?? new Settings();
moel@165
    61
    }
moel@28
    62
moel@28
    63
    private void Add(IGroup group) {
moel@28
    64
      if (groups.Contains(group))
moel@28
    65
        return;
moel@28
    66
moel@28
    67
      groups.Add(group);
moel@28
    68
moel@28
    69
      if (HardwareAdded != null)
moel@83
    70
        foreach (IHardware hardware in group.Hardware)
moel@28
    71
          HardwareAdded(hardware);
moel@28
    72
    }
moel@28
    73
moel@28
    74
    private void Remove(IGroup group) {
moel@28
    75
      if (!groups.Contains(group))
moel@28
    76
        return;
moel@28
    77
moel@28
    78
      groups.Remove(group);
moel@28
    79
moel@28
    80
      if (HardwareRemoved != null)
moel@83
    81
        foreach (IHardware hardware in group.Hardware)
moel@28
    82
          HardwareRemoved(hardware);
moel@28
    83
    }
moel@28
    84
moel@167
    85
    [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
moel@28
    86
    public void Open() {
moel@28
    87
      if (open)
moel@28
    88
        return;
moel@28
    89
moel@236
    90
      Ring0.Open();
moel@236
    91
      Opcode.Open();
moel@167
    92
moel@165
    93
      Add(new Mainboard.MainboardGroup(settings));
moel@165
    94
      Add(new CPU.CPUGroup(settings));
moel@165
    95
      Add(new ATI.ATIGroup(settings));
moel@171
    96
      Add(new Nvidia.NvidiaGroup(settings));      
moel@165
    97
      Add(new TBalancer.TBalancerGroup(settings));
moel@171
    98
      Add(new Heatmaster.HeatmasterGroup(settings));
moel@28
    99
moel@83
   100
      if (hddEnabled)
moel@165
   101
        Add(new HDD.HDDGroup(settings));
moel@28
   102
moel@28
   103
      open = true;
moel@28
   104
    }
moel@167
   105
    
moel@28
   106
    public bool HDDEnabled {
moel@28
   107
      get { return hddEnabled; }
moel@167
   108
moel@167
   109
      [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
moel@28
   110
      set {
moel@28
   111
        if (open && value && !hddEnabled) {
moel@165
   112
          Add(new HDD.HDDGroup(settings));
moel@28
   113
        } else if (open && !value && hddEnabled) {
moel@28
   114
          List<IGroup> list = new List<IGroup>();
moel@28
   115
          foreach (IGroup group in groups)
moel@28
   116
            if (group is HDD.HDDGroup)
moel@28
   117
              list.Add(group);
moel@28
   118
          foreach (IGroup group in list)
moel@83
   119
            Remove(group);
moel@28
   120
        }
moel@28
   121
        hddEnabled = value;
moel@28
   122
      }
moel@28
   123
    }
moel@28
   124
moel@83
   125
    public IHardware[] Hardware {
moel@83
   126
      get {
moel@83
   127
        List<IHardware> list = new List<IHardware>();
moel@28
   128
        foreach (IGroup group in groups)
moel@28
   129
          foreach (IHardware hardware in group.Hardware)
moel@83
   130
            list.Add(hardware);
moel@83
   131
        return list.ToArray();
moel@28
   132
      }
moel@28
   133
    }
moel@28
   134
moel@167
   135
    private static void NewSection(TextWriter writer) {
moel@28
   136
      for (int i = 0; i < 8; i++)
moel@28
   137
        writer.Write("----------");
moel@28
   138
      writer.WriteLine();
moel@28
   139
      writer.WriteLine();
moel@28
   140
    }
moel@28
   141
moel@195
   142
    private static int CompareSensor(ISensor a, ISensor b) {
moel@149
   143
      int c = a.SensorType.CompareTo(b.SensorType);
moel@149
   144
      if (c == 0)
moel@149
   145
        return a.Index.CompareTo(b.Index);
moel@149
   146
      else
moel@149
   147
        return c;
moel@149
   148
    }
moel@149
   149
moel@195
   150
    private static void ReportHardwareSensorTree(
moel@195
   151
      IHardware hardware, TextWriter w, string space) 
moel@195
   152
    {
moel@64
   153
      w.WriteLine("{0}|", space);
moel@256
   154
      w.WriteLine("{0}+- {1} ({2})",
moel@64
   155
        space, hardware.Name, hardware.Identifier);
moel@149
   156
      ISensor[] sensors = hardware.Sensors;
moel@195
   157
      Array.Sort(sensors, CompareSensor);
moel@149
   158
      foreach (ISensor sensor in sensors) {
moel@256
   159
        w.WriteLine("{0}|  +- {1,-14} : {2,8:G6} {3,8:G6} {4,8:G6} ({5})", 
moel@256
   160
          space, sensor.Name, sensor.Value, sensor.Min, sensor.Max, 
moel@256
   161
          sensor.Identifier);
moel@149
   162
      }
moel@149
   163
      foreach (IHardware subHardware in hardware.SubHardware)
moel@256
   164
        ReportHardwareSensorTree(subHardware, w, "|  ");
moel@149
   165
    }
moel@149
   166
moel@195
   167
    private static void ReportHardwareParameterTree(
moel@256
   168
      IHardware hardware, TextWriter w, string space) {
moel@149
   169
      w.WriteLine("{0}|", space);
moel@256
   170
      w.WriteLine("{0}+- {1} ({2})",
moel@149
   171
        space, hardware.Name, hardware.Identifier);
moel@149
   172
      ISensor[] sensors = hardware.Sensors;
moel@195
   173
      Array.Sort(sensors, CompareSensor);
moel@149
   174
      foreach (ISensor sensor in sensors) {
moel@256
   175
        string innerSpace = space + "|  ";
moel@149
   176
        if (sensor.Parameters.Length > 0) {
moel@256
   177
          w.WriteLine("{0}|", innerSpace);
moel@256
   178
          w.WriteLine("{0}+- {1} ({2})",
moel@256
   179
            innerSpace, sensor.Name, sensor.Identifier);
moel@149
   180
          foreach (IParameter parameter in sensor.Parameters) {
moel@256
   181
            string innerInnerSpace = innerSpace + "|  ";
moel@256
   182
            w.WriteLine("{0}+- {1} : {2}",
moel@256
   183
              innerInnerSpace, parameter.Name,
moel@149
   184
              string.Format(CultureInfo.InvariantCulture, "{0} : {1}",
moel@149
   185
                parameter.DefaultValue, parameter.Value));
moel@149
   186
          }
moel@64
   187
        }
moel@64
   188
      }
moel@64
   189
      foreach (IHardware subHardware in hardware.SubHardware)
moel@256
   190
        ReportHardwareParameterTree(subHardware, w, "|  ");
moel@64
   191
    }
moel@64
   192
moel@195
   193
    private static void ReportHardware(IHardware hardware, TextWriter w) {
moel@64
   194
      string hardwareReport = hardware.GetReport();
moel@167
   195
      if (!string.IsNullOrEmpty(hardwareReport)) {
moel@64
   196
        NewSection(w);
moel@64
   197
        w.Write(hardwareReport);
moel@64
   198
      }
moel@64
   199
      foreach (IHardware subHardware in hardware.SubHardware)
moel@64
   200
        ReportHardware(subHardware, w);
moel@64
   201
    }
moel@64
   202
moel@83
   203
    public string GetReport() {
moel@28
   204
moel@166
   205
      using (StringWriter w = new StringWriter(CultureInfo.InvariantCulture)) {
moel@28
   206
moel@28
   207
        w.WriteLine();
moel@28
   208
        w.WriteLine("Open Hardware Monitor Report");
moel@28
   209
        w.WriteLine();
moel@28
   210
moel@83
   211
        Version version = typeof(Computer).Assembly.GetName().Version;
moel@83
   212
moel@28
   213
        NewSection(w);
moel@28
   214
        w.Write("Version: "); w.WriteLine(version.ToString());
moel@28
   215
        w.WriteLine();
moel@28
   216
moel@28
   217
        NewSection(w);
moel@119
   218
        w.Write("Common Language Runtime: ");
moel@119
   219
        w.WriteLine(Environment.Version.ToString());
moel@119
   220
        w.Write("Operating System: ");
moel@119
   221
        w.WriteLine(Environment.OSVersion.ToString());
moel@119
   222
        w.Write("Process Type: ");
moel@119
   223
        w.WriteLine(IntPtr.Size == 4 ? "32-Bit" : "64-Bit");
moel@119
   224
        w.WriteLine();
moel@119
   225
moel@254
   226
        string r = Ring0.GetReport();
moel@254
   227
        if (r != null) {
moel@254
   228
          NewSection(w);
moel@254
   229
          w.Write(r);
moel@254
   230
          w.WriteLine();
moel@254
   231
        }
moel@254
   232
moel@119
   233
        NewSection(w);
moel@149
   234
        w.WriteLine("Sensors");
moel@149
   235
        w.WriteLine();
moel@28
   236
        foreach (IGroup group in groups) {
moel@64
   237
          foreach (IHardware hardware in group.Hardware)
moel@149
   238
            ReportHardwareSensorTree(hardware, w, "");
moel@149
   239
        }
moel@149
   240
        w.WriteLine();
moel@149
   241
moel@149
   242
        NewSection(w);
moel@149
   243
        w.WriteLine("Parameters");
moel@149
   244
        w.WriteLine();
moel@149
   245
        foreach (IGroup group in groups) {
moel@149
   246
          foreach (IHardware hardware in group.Hardware)
moel@149
   247
            ReportHardwareParameterTree(hardware, w, "");
moel@28
   248
        }
moel@28
   249
        w.WriteLine();
moel@28
   250
moel@28
   251
        foreach (IGroup group in groups) {
moel@28
   252
          string report = group.GetReport();
moel@167
   253
          if (!string.IsNullOrEmpty(report)) {
moel@28
   254
            NewSection(w);
moel@28
   255
            w.Write(report);
moel@28
   256
          }
moel@28
   257
moel@28
   258
          IHardware[] hardwareArray = group.Hardware;
moel@64
   259
          foreach (IHardware hardware in hardwareArray)
moel@64
   260
            ReportHardware(hardware, w);
moel@83
   261
moel@28
   262
        }
moel@83
   263
        return w.ToString();
moel@28
   264
      }
moel@28
   265
    }
moel@28
   266
moel@83
   267
    public void Close() {      
moel@28
   268
      if (!open)
moel@28
   269
        return;
moel@28
   270
moel@262
   271
      while (groups.Count > 0) {
moel@262
   272
        IGroup group = groups[groups.Count - 1];
moel@262
   273
        Remove(group);
moel@262
   274
        group.Close(); 
moel@262
   275
      } 
moel@28
   276
moel@236
   277
      Opcode.Close();
moel@236
   278
      Ring0.Close();
moel@167
   279
moel@28
   280
      open = false;
moel@28
   281
    }
moel@28
   282
moel@28
   283
    public event HardwareEventHandler HardwareAdded;
moel@28
   284
    public event HardwareEventHandler HardwareRemoved;
moel@110
   285
moel@110
   286
    public void Accept(IVisitor visitor) {
moel@167
   287
      if (visitor == null)
moel@167
   288
        throw new ArgumentNullException("visitor");
moel@167
   289
      visitor.VisitComputer(this);
moel@110
   290
    }
moel@110
   291
moel@110
   292
    public void Traverse(IVisitor visitor) {
moel@110
   293
      foreach (IGroup group in groups)
moel@110
   294
        foreach (IHardware hardware in group.Hardware) 
moel@110
   295
          hardware.Accept(visitor);
moel@110
   296
    }
moel@165
   297
moel@165
   298
    private class Settings : ISettings {
moel@165
   299
moel@165
   300
      public bool Contains(string name) {
moel@165
   301
        return false;
moel@165
   302
      }
moel@165
   303
moel@166
   304
      public void SetValue(string name, string value) { }
moel@165
   305
moel@166
   306
      public string GetValue(string name, string value) {
moel@165
   307
        return value;
moel@165
   308
      }
moel@165
   309
moel@165
   310
      public void Remove(string name) { }
moel@165
   311
    }
moel@28
   312
  }
moel@28
   313
}