# HG changeset patch
# User moel.mich
# Date 1281883618 0
# Node ID b7cc9d09aefe61054c0628781b3f410d2ce38f9e
# Parent  fa9dfbfc4145075b37249c6d4c40a9619345549f
Fixed some Code Analysis warnings.

diff -r fa9dfbfc4145 -r b7cc9d09aefe Collections/ListSet.cs
--- a/Collections/ListSet.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Collections/ListSet.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -41,6 +41,7 @@
 using System.Text;
 
 namespace OpenHardwareMonitor.Collections {
+
   public class ListSet<T> : IEnumerable<T> {
 
     private List<T> list = new List<T>();
diff -r fa9dfbfc4145 -r b7cc9d09aefe Collections/ReadOnlyArray.cs
--- a/Collections/ReadOnlyArray.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Collections/ReadOnlyArray.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -66,5 +66,9 @@
     public static implicit operator ReadOnlyArray<T>(T[] array) {
       return new ReadOnlyArray<T>(array);
     }
+
+    public T[] ToArray() {
+      return (T[])array.Clone();
+    }
   }
 }
diff -r fa9dfbfc4145 -r b7cc9d09aefe GUI/Node.cs
--- a/GUI/Node.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/GUI/Node.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -159,7 +159,7 @@
 
       protected override void InsertItem(int index, Node item) {
         if (item == null)
-          throw new ArgumentNullException();
+          throw new ArgumentNullException("item");
 
         if (item.parent != owner) {
           if (item.parent != null)
@@ -189,7 +189,7 @@
 
       protected override void SetItem(int index, Node item) {
         if (item == null)
-          throw new ArgumentNullException();
+          throw new ArgumentNullException("item");
 
         RemoveAt(index);
         InsertItem(index, item);
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/ATI/ADL.cs
--- a/Hardware/ATI/ADL.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/ATI/ADL.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -156,7 +156,7 @@
     private static ADL_Adapter_AdapterInfo_GetDelegate
       _ADL_Adapter_AdapterInfo_Get;
 
-    public static ADL_Main_Control_DestroyDelegate 
+    public static ADL_Main_Control_DestroyDelegate
       ADL_Main_Control_Destroy;
     public static ADL_Adapter_NumberOfAdapters_GetDelegate
       ADL_Adapter_NumberOfAdapters_Get;
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/ATI/ATIGroup.cs
--- a/Hardware/ATI/ATIGroup.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/ATI/ATIGroup.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -104,7 +104,7 @@
                 report.Append("AdapterID: 0x");
                 report.AppendLine(adapterID.ToString("X", CultureInfo.InvariantCulture));
 
-                if (adapterID != 0 && adapterInfo[i].UDID != "" &&
+                if (adapterID != 0 && !string.IsNullOrEmpty(adapterInfo[i].UDID) &&
                   (adapterInfo[i].VendorID == ADL.ATI_VENDOR_ID1 ||
                    adapterInfo[i].VendorID == ADL.ATI_VENDOR_ID2)) {
                   bool found = false;
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/CPU/CPUGroup.cs
--- a/Hardware/CPU/CPUGroup.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/CPU/CPUGroup.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -48,13 +48,13 @@
 
     private CPUID[][][] threads;
 
-    private CPUID[][] GetProcessorThreads() {
+    private static CPUID[][] GetProcessorThreads() {
 
       List<CPUID> threads = new List<CPUID>();
       for (int i = 0; i < 32; i++) {
         try {
           threads.Add(new CPUID(i));
-        } catch (ArgumentException) { }
+        } catch (ArgumentOutOfRangeException) { }
       }
 
       SortedDictionary<uint, List<CPUID>> processors =
@@ -78,7 +78,7 @@
       return processorThreads;
     }
 
-    private CPUID[][] GroupThreadsByCore(CPUID[] threads) {
+    private static CPUID[][] GroupThreadsByCore(CPUID[] threads) {
 
       SortedDictionary<uint, List<CPUID>> cores = 
         new SortedDictionary<uint, List<CPUID>>();
@@ -151,7 +151,9 @@
       }
     }
 
-    private void AppendCpuidData(StringBuilder r, uint[,] data, uint offset) {
+    private static void AppendCpuidData(StringBuilder r, uint[,] data, 
+      uint offset) 
+    {
       for (int i = 0; i < data.GetLength(0); i++) {
         r.Append(" ");
         r.Append((i + offset).ToString("X8", CultureInfo.InvariantCulture));
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/CPU/CPUID.cs
--- a/Hardware/CPU/CPUID.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/CPU/CPUID.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -75,14 +75,14 @@
     public static uint CPUID_0 = 0;
     public static uint CPUID_EXT = 0x80000000;
 
-    private void AppendRegister(StringBuilder b, uint value) {
+    private static void AppendRegister(StringBuilder b, uint value) {
       b.Append((char)((value) & 0xff));
       b.Append((char)((value >> 8) & 0xff));
       b.Append((char)((value >> 16) & 0xff));
       b.Append((char)((value >> 24) & 0xff));
     }
 
-    private uint NextLog2(long x) {
+    private static uint NextLog2(long x) {
       if (x <= 0)
         return 0;
 
@@ -105,7 +105,7 @@
       uint eax, ebx, ecx, edx;
 
       if (thread >= 32)
-        throw new ArgumentException();
+        throw new ArgumentOutOfRangeException("thread");
       UIntPtr mask = (UIntPtr)(1L << thread);
 
       if (WinRing0.CpuidTx(CPUID_0, 0,
@@ -139,10 +139,10 @@
           else
             return;
         } else {
-          throw new ArgumentException();
+          throw new ArgumentOutOfRangeException("thread");
         }
       } else {
-        throw new ArgumentException();
+        throw new ArgumentOutOfRangeException("thread");
       }
 
       maxCpuid = Math.Min(maxCpuid, 1024);
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/CPU/CPULoad.cs
--- a/Hardware/CPU/CPULoad.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/CPU/CPULoad.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -62,12 +62,6 @@
       SystemProcessorPerformanceInformation = 8
     }
 
-    [DllImport("ntdll.dll")]
-    private static extern int NtQuerySystemInformation(
-      SystemInformationClass informationClass,
-      [Out] SystemProcessorPerformanceInformation[] informations, 
-      int structSize, out IntPtr returnLength);
-
     private CPUID[][] cpuid;
 
     private long systemTime;
@@ -78,16 +72,17 @@
 
     private bool available = false;
 
-    private long[] GetIdleTimes() {      
+    private static long[] GetIdleTimes() {      
       SystemProcessorPerformanceInformation[] informations = new
         SystemProcessorPerformanceInformation[64];
 
       int size = Marshal.SizeOf(typeof(SystemProcessorPerformanceInformation));
 
       IntPtr returnLength;
-      NtQuerySystemInformation(
+      if (NativeMethods.NtQuerySystemInformation(
         SystemInformationClass.SystemProcessorPerformanceInformation,
-        informations, informations.Length * size, out returnLength);
+        informations, informations.Length * size, out returnLength) != 0)
+        return null;
 
       long[] result = new long[(int)returnLength / size];
 
@@ -127,10 +122,13 @@
       if (this.idleTimes == null)
         return;
 
-      long localSystemTime = DateTime.Now.Ticks;
-      long[] localIdleTimes = GetIdleTimes();
+      long newSystemTime = DateTime.Now.Ticks;
+      long[] newIdleTimes = GetIdleTimes();
 
-      if (localSystemTime - this.systemTime < 10000)
+      if (newSystemTime - this.systemTime < 10000)
+        return;
+
+      if (newIdleTimes == null)
         return;
 
       float total = 0;
@@ -139,29 +137,37 @@
         float value = 0;
         for (int j = 0; j < cpuid[i].Length; j++) {
           long index = cpuid[i][j].Thread;
-          if (index < localIdleTimes.Length) {
-            long delta = localIdleTimes[index] - this.idleTimes[index];
+          if (index < newIdleTimes.Length) {
+            long delta = newIdleTimes[index] - this.idleTimes[index];
             value += delta;
             total += delta;
             count++;
           }
         }
         value = 1.0f - value / (cpuid[i].Length * 
-          (localSystemTime - this.systemTime));
+          (newSystemTime - this.systemTime));
         value = value < 0 ? 0 : value;
         coreLoads[i] = value * 100;
       }
       if (count > 0) {
-        total = 1.0f - total / (count * (localSystemTime - this.systemTime));
+        total = 1.0f - total / (count * (newSystemTime - this.systemTime));
         total = total < 0 ? 0 : total;
       } else {
         total = 0;
       }
       this.totalLoad = total * 100;
 
-      this.systemTime = localSystemTime;
-      this.idleTimes = localIdleTimes;
+      this.systemTime = newSystemTime;
+      this.idleTimes = newIdleTimes;
     }
 
+    private static class NativeMethods {
+
+      [DllImport("ntdll.dll")]
+      public static extern int NtQuerySystemInformation(
+        SystemInformationClass informationClass,
+        [Out] SystemProcessorPerformanceInformation[] informations,
+        int structSize, out IntPtr returnLength);
+    }
   }
 }
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/CPU/IntelCPU.cs
--- a/Hardware/CPU/IntelCPU.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/CPU/IntelCPU.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -253,7 +253,7 @@
       get { return HardwareType.CPU; }
     }
 
-    private void AppendMSRData(StringBuilder r, uint msr, int thread) {
+    private static void AppendMSRData(StringBuilder r, uint msr, int thread) {
       uint eax, edx;
       if (WinRing0.RdmsrTx(msr, out eax, out edx, (UIntPtr)(1L << thread))) {
         r.Append(" ");
@@ -298,7 +298,7 @@
       return r.ToString();
     }
 
-    private double EstimateMaxClock(double timeWindow) {
+    private static double EstimateMaxClock(double timeWindow) {
       long ticks = (long)(timeWindow * Stopwatch.Frequency);
       uint lsbBegin, msbBegin, lsbEnd, msbEnd; 
       
@@ -359,7 +359,7 @@
           else
             maxClock = estimatedMaxClock;
 
-          double busClock = 0;
+          double newBusClock = 0;
           uint eax, edx;
           for (int i = 0; i < coreClocks.Length; i++) {
             System.Threading.Thread.Sleep(1);
@@ -369,7 +369,7 @@
                 uint nehalemMultiplier = eax & 0xff;
                 coreClocks[i].Value =
                   (float)(nehalemMultiplier * maxClock / maxNehalemMultiplier);
-                busClock = (float)(maxClock / maxNehalemMultiplier);
+                newBusClock = (float)(maxClock / maxNehalemMultiplier);
               } else { // Core 2
                 uint multiplier = (eax >> 8) & 0x1f;
                 uint maxMultiplier = (edx >> 8) & 0x1f;
@@ -378,7 +378,7 @@
                 uint maxFactor = (maxMultiplier << 1) | ((edx >> 14) & 1);
                 if (maxFactor > 0) {
                   coreClocks[i].Value = (float)(factor * maxClock / maxFactor);
-                  busClock = (float)(2 * maxClock / maxFactor);
+                  newBusClock = (float)(2 * maxClock / maxFactor);
                 }
               }
             } else { // Intel Pentium 4
@@ -386,8 +386,8 @@
               coreClocks[i].Value = (float)maxClock;
             }
           }
-          if (busClock > 0) {
-            this.busClock.Value = (float)busClock;
+          if (newBusClock > 0) {
+            this.busClock.Value = (float)newBusClock;
             ActivateSensor(this.busClock);
           }
         }
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/Computer.cs
--- a/Hardware/Computer.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/Computer.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -41,6 +41,9 @@
 using System.Globalization;
 using System.Text;
 using System.Threading;
+using System.Security;
+using System.Security.Permissions;
+
 
 namespace OpenHardwareMonitor.Hardware {
 
@@ -86,10 +89,13 @@
           HardwareRemoved(hardware);
     }
 
+    [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
     public void Open() {
       if (open)
         return;
 
+      WinRing0.Open();
+
       Add(new Mainboard.MainboardGroup(settings));
       Add(new CPU.CPUGroup(settings));
       Add(new ATI.ATIGroup(settings));
@@ -101,9 +107,11 @@
 
       open = true;
     }
-
+    
     public bool HDDEnabled {
       get { return hddEnabled; }
+
+      [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
       set {
         if (open && value && !hddEnabled) {
           Add(new HDD.HDDGroup(settings));
@@ -129,7 +137,7 @@
       }
     }
 
-    private void NewSection(TextWriter writer) {
+    private static void NewSection(TextWriter writer) {
       for (int i = 0; i < 8; i++)
         writer.Write("----------");
       writer.WriteLine();
@@ -186,7 +194,7 @@
 
     private void ReportHardware(IHardware hardware, TextWriter w) {
       string hardwareReport = hardware.GetReport();
-      if (hardwareReport != null && hardwareReport != "") {
+      if (!string.IsNullOrEmpty(hardwareReport)) {
         NewSection(w);
         w.Write(hardwareReport);
       }
@@ -237,7 +245,7 @@
 
         foreach (IGroup group in groups) {
           string report = group.GetReport();
-          if (report != null && report != "") {
+          if (!string.IsNullOrEmpty(report)) {
             NewSection(w);
             w.Write(report);
           }
@@ -259,6 +267,8 @@
         group.Close();
       groups.Clear();
 
+      WinRing0.Close();
+
       open = false;
     }
 
@@ -266,8 +276,9 @@
     public event HardwareEventHandler HardwareRemoved;
 
     public void Accept(IVisitor visitor) {
-      if (visitor != null)
-        visitor.VisitComputer(this);
+      if (visitor == null)
+        throw new ArgumentNullException("visitor");
+      visitor.VisitComputer(this);
     }
 
     public void Traverse(IVisitor visitor) {
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/HDD/HDD.cs
--- a/Hardware/HDD/HDD.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/HDD/HDD.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -117,8 +117,9 @@
     #pragma warning restore 67    
 
     public void Accept(IVisitor visitor) {
-      if (visitor != null)
-        visitor.VisitHardware(this);
+      if (visitor == null)
+        throw new ArgumentNullException("visitor");
+      visitor.VisitHardware(this);
     }
 
     public void Traverse(IVisitor visitor) { }
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/HDD/SMART.cs
--- a/Hardware/HDD/SMART.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/HDD/SMART.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -232,37 +232,10 @@
 
     private const int MAX_DRIVE_ATTRIBUTES = 512;
 
-    private const string KERNEL = "kernel32.dll";
-
-    [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
-    private static extern IntPtr CreateFile(string fileName, 
-      AccessMode desiredAccess, ShareMode shareMode, IntPtr securityAttributes,
-      CreationMode creationDisposition, FileAttribute flagsAndAttributes, 
-      IntPtr templateFilehandle);
-
-    [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
-    public static extern int CloseHandle(IntPtr handle);
-
-    [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
-    private static extern bool DeviceIoControl(IntPtr handle,
-      DriveCommand command, ref DriveCommandParameter parameter,
-      int parameterSize, out DriveSmartReadResult result, int resultSize, 
-      out uint bytesReturned, IntPtr overlapped);
-
-    [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
-    private static extern bool DeviceIoControl(IntPtr handle,
-      DriveCommand command, ref DriveCommandParameter parameter,
-      int parameterSize, out DriveCommandResult result, int resultSize,
-      out uint bytesReturned, IntPtr overlapped);
-
-    [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
-    private static extern bool DeviceIoControl(IntPtr handle,
-      DriveCommand command, ref DriveCommandParameter parameter,
-      int parameterSize, out DriveIdentifyResult result, int resultSize,
-      out uint bytesReturned, IntPtr overlapped);
+    private SMART() { }
 
     public static IntPtr OpenPhysicalDrive(int driveNumber) {
-      return CreateFile(@"\\.\PhysicalDrive" + driveNumber,
+      return NativeMethods.CreateFile(@"\\.\PhysicalDrive" + driveNumber,
         AccessMode.Read | AccessMode.Write, ShareMode.Read | ShareMode.Write,
         IntPtr.Zero, CreationMode.OpenExisting, FileAttribute.Device,
         IntPtr.Zero);
@@ -279,8 +252,8 @@
       parameter.Registers.LBAHigh = SMART_LBA_HI;
       parameter.Registers.Command = SMART_CMD;
 
-      return DeviceIoControl(handle, DriveCommand.SendDriveCommand, 
-        ref parameter, Marshal.SizeOf(parameter), out result,
+      return NativeMethods.DeviceIoControl(handle, DriveCommand.SendDriveCommand, 
+        ref parameter, Marshal.SizeOf(typeof(DriveCommandParameter)), out result,
         Marshal.SizeOf(typeof(DriveCommandResult)), out bytesReturned, 
         IntPtr.Zero);
     }
@@ -296,10 +269,10 @@
       parameter.Registers.LBAHigh = SMART_LBA_HI;
       parameter.Registers.Command = SMART_CMD;
 
-      bool valid = DeviceIoControl(handle, DriveCommand.ReceiveDriveData,
-        ref parameter, Marshal.SizeOf(parameter), out result,
-        Marshal.SizeOf(typeof(DriveSmartReadResult)), out bytesReturned,
-        IntPtr.Zero);
+      bool valid = NativeMethods.DeviceIoControl(handle, 
+        DriveCommand.ReceiveDriveData, ref parameter, Marshal.SizeOf(parameter), 
+        out result, Marshal.SizeOf(typeof(DriveSmartReadResult)), 
+        out bytesReturned, IntPtr.Zero);
 
       if (!valid)
         return null;
@@ -315,10 +288,10 @@
       parameter.DriveNumber = (byte)driveNumber;
       parameter.Registers.Command = ID_CMD;
 
-      bool valid = DeviceIoControl(handle, DriveCommand.ReceiveDriveData,
-        ref parameter, Marshal.SizeOf(parameter), out result,
-        Marshal.SizeOf(typeof(DriveIdentifyResult)), out bytesReturned,
-        IntPtr.Zero);
+      bool valid = NativeMethods.DeviceIoControl(handle, 
+        DriveCommand.ReceiveDriveData, ref parameter, Marshal.SizeOf(parameter), 
+        out result, Marshal.SizeOf(typeof(DriveIdentifyResult)), 
+        out bytesReturned, IntPtr.Zero);
 
       if (!valid)
         return null;
@@ -335,5 +308,43 @@
       }
     }
 
+    public static int CloseHandle(IntPtr handle) {
+      return NativeMethods.CloseHandle(handle);
+    }
+
+    private static class NativeMethods {
+      private const string KERNEL = "kernel32.dll";
+
+      [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi,
+        CharSet = CharSet.Unicode)]
+      public static extern IntPtr CreateFile(string fileName,
+        AccessMode desiredAccess, ShareMode shareMode, IntPtr securityAttributes,
+        CreationMode creationDisposition, FileAttribute flagsAndAttributes,
+        IntPtr templateFilehandle);
+
+      [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
+      public static extern int CloseHandle(IntPtr handle);
+
+      [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
+      [return: MarshalAsAttribute(UnmanagedType.Bool)]
+      public static extern bool DeviceIoControl(IntPtr handle,
+        DriveCommand command, ref DriveCommandParameter parameter,
+        int parameterSize, out DriveSmartReadResult result, int resultSize,
+        out uint bytesReturned, IntPtr overlapped);
+
+      [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
+      [return: MarshalAsAttribute(UnmanagedType.Bool)]
+      public static extern bool DeviceIoControl(IntPtr handle,
+        DriveCommand command, ref DriveCommandParameter parameter,
+        int parameterSize, out DriveCommandResult result, int resultSize,
+        out uint bytesReturned, IntPtr overlapped);
+
+      [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
+      [return: MarshalAsAttribute(UnmanagedType.Bool)]
+      public static extern bool DeviceIoControl(IntPtr handle,
+        DriveCommand command, ref DriveCommandParameter parameter,
+        int parameterSize, out DriveIdentifyResult result, int resultSize,
+        out uint bytesReturned, IntPtr overlapped);
+    }    
   }
 }
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/Hardware.cs
--- a/Hardware/Hardware.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/Hardware.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -80,8 +80,9 @@
     public abstract void Update();
 
     public void Accept(IVisitor visitor) {
-      if (visitor != null)
-        visitor.VisitHardware(this);
+      if (visitor == null)
+        throw new ArgumentNullException("visitor");
+      visitor.VisitHardware(this);
     }
 
     public void Traverse(IVisitor visitor) {
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/IComputer.cs
--- a/Hardware/IComputer.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/IComputer.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -46,7 +46,7 @@
 
     IHardware[] Hardware { get; }
 
-    bool HDDEnabled { get; set; }
+    bool HDDEnabled { get; }
 
     string GetReport();
 
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/Identifier.cs
--- a/Hardware/Identifier.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/Identifier.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -45,7 +45,7 @@
 
     private static char SEPARATOR = '/';
 
-    private void CheckIdentifiers(string[] identifiers) {
+    private static void CheckIdentifiers(string[] identifiers) {
       foreach (string s in identifiers)
         if (s.Contains(" ") || s.Contains(SEPARATOR.ToString()))
           throw new ArgumentException("Invalid identifier");
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/LPC/Chip.cs
--- a/Hardware/LPC/Chip.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/LPC/Chip.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -25,7 +25,39 @@
     F71869 = 0x0814,
     F71882 = 0x0541,
     F71889ED = 0x0909,
-    F71889F = 0x0723    
+    F71889F = 0x0723      
+  }
+
+  internal class ChipName {
+
+    private ChipName() { }
+
+    public static string GetName(Chip chip) {
+      switch (chip) {
+        case Chip.F71858: return "Fintek F71858";
+        case Chip.F71862: return "Fintek F71862";
+        case Chip.F71869: return "Fintek F71869";
+        case Chip.F71882: return "Fintek F71882";
+        case Chip.F71889ED: return "Fintek F71889ED";
+        case Chip.F71889F: return "Fintek F71889F";
+        case Chip.IT8712F: return "ITE IT8712F";
+        case Chip.IT8716F: return "ITE IT8716F";
+        case Chip.IT8718F: return "ITE IT8718F";
+        case Chip.IT8720F: return "ITE IT8720F";
+        case Chip.IT8726F: return "ITE IT8726F";
+        case Chip.W83627DHG: return "Winbond W83627DHG";
+        case Chip.W83627DHGP: return "Winbond W83627DHG-P";
+        case Chip.W83627EHF: return "Winbond W83627EHF";
+        case Chip.W83627HF: return "Winbond W83627HF";
+        case Chip.W83627THF: return "Winbond W83627THF";
+        case Chip.W83667HG: return "Winbond W83667HG";
+        case Chip.W83667HGB: return "Winbond W83667HG-B";
+        case Chip.W83687THF: return "Winbond W83687THF";
+        case Chip.Unknown: return "Unkown";
+        default: return "Unknown";
+      }
+    }
+
   }
 
 }
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/LPC/LMSensors.cs
--- a/Hardware/LPC/LMSensors.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/LPC/LMSensors.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -51,9 +51,8 @@
       foreach (string path in devicePaths) {
         string name = null;
         try {
-          StreamReader reader = new StreamReader(path + "/device/name");
-          name = reader.ReadLine();
-          reader.Close();
+          using (StreamReader reader = new StreamReader(path + "/device/name")) 
+            name = reader.ReadLine();
         } catch (IOException) { }
         switch (name) {
           case "f71858fg":
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/LPC/LPCIO.cs
--- a/Hardware/LPC/LPCIO.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/LPC/LPCIO.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -47,8 +47,6 @@
     private List<ISuperIO> superIOs = new List<ISuperIO>();
     private StringBuilder report = new StringBuilder();
 
-    private Chip chip = Chip.Unknown;
-
     // I/O Ports
     private ushort[] REGISTER_PORTS = new ushort[] { 0x2e, 0x4e };
     private ushort[] VALUE_PORTS = new ushort[] { 0x2f, 0x4f };
@@ -121,261 +119,290 @@
       WinRing0.WriteIoPortByte(registerPort, 0xAA);
     }
 
+    private void ReportUnknownChip(string type, int chip) {
+      report.Append("Chip ID: Unknown ");
+      report.Append(type);
+      report.Append(" with ID 0x");
+      report.Append(chip.ToString("X", CultureInfo.InvariantCulture));
+      report.Append(" at 0x");
+      report.Append(registerPort.ToString("X", CultureInfo.InvariantCulture));
+      report.Append("/0x");
+      report.AppendLine(valuePort.ToString("X", CultureInfo.InvariantCulture));
+      report.AppendLine();
+    }
+
+    private bool DetectWinbondFintek() {
+      WinbondFintekEnter();
+
+      byte logicalDeviceNumber;
+      byte id = ReadByte(CHIP_ID_REGISTER);
+      byte revision = ReadByte(CHIP_REVISION_REGISTER);
+      Chip chip = Chip.Unknown;
+      logicalDeviceNumber = 0;
+      switch (id) {
+        case 0x05:
+          switch (revision) {
+            case 0x07:
+              chip = Chip.F71858;
+              logicalDeviceNumber = F71858_HARDWARE_MONITOR_LDN;
+              break;
+            case 0x41:
+              chip = Chip.F71882;
+              logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
+              break;
+          } break;
+        case 0x06:
+          switch (revision) {
+            case 0x01:
+              chip = Chip.F71862;
+              logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
+              break;
+          } break;
+        case 0x07:
+          switch (revision) {
+            case 0x23:
+              chip = Chip.F71889F;
+              logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
+              break;
+          } break;
+        case 0x08:
+          switch (revision) {
+            case 0x14:
+              chip = Chip.F71869;
+              logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
+              break;
+          } break;
+        case 0x09:
+          switch (revision) {
+            case 0x09:
+              chip = Chip.F71889ED;
+              logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
+              break;
+          } break;
+        case 0x52:
+          switch (revision) {
+            case 0x17:
+            case 0x3A:
+            case 0x41:
+              chip = Chip.W83627HF;
+              logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
+              break;
+          } break;
+        case 0x82:
+          switch (revision & 0xF0) {
+            case 0x80:
+              chip = Chip.W83627THF;
+              logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
+              break;
+          } break;
+        case 0x85:
+          switch (revision) {
+            case 0x41:
+              chip = Chip.W83687THF;
+              logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
+              break;
+          } break;
+        case 0x88:
+          switch (revision & 0xF0) {
+            case 0x50:
+            case 0x60:
+              chip = Chip.W83627EHF;
+              logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
+              break;
+          } break;
+        case 0xA0:
+          switch (revision & 0xF0) {
+            case 0x20:
+              chip = Chip.W83627DHG;
+              logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
+              break;
+          } break;
+        case 0xA5:
+          switch (revision & 0xF0) {
+            case 0x10:
+              chip = Chip.W83667HG;
+              logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
+              break;
+          } break;
+        case 0xB0:
+          switch (revision & 0xF0) {
+            case 0x70:
+              chip = Chip.W83627DHGP;
+              logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
+              break;
+          } break;
+        case 0xB3:
+          switch (revision & 0xF0) {
+            case 0x50:
+              chip = Chip.W83667HGB;
+              logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
+              break;
+          } break;
+      }
+      if (chip == Chip.Unknown) {
+        if (id != 0 && id != 0xff) {
+          WinbondFintekExit();
+
+          ReportUnknownChip("Winbond / Fintek", ((id << 8) | revision));         
+        }
+      } else {
+
+        Select(logicalDeviceNumber);
+        ushort address = ReadWord(BASE_ADDRESS_REGISTER);
+        Thread.Sleep(1);
+        ushort verify = ReadWord(BASE_ADDRESS_REGISTER);
+
+        ushort vendorID = ReadWord(FINTEK_VENDOR_ID_REGISTER);
+
+        WinbondFintekExit();
+
+        if (address != verify) {
+          report.Append("Chip ID: 0x");
+          report.AppendLine(chip.ToString("X"));
+          report.Append("Chip revision: 0x");
+          report.AppendLine(revision.ToString("X", 
+            CultureInfo.InvariantCulture));
+          report.AppendLine("Error: Address verification failed");
+          report.AppendLine();
+          return false;
+        }
+
+        // some Fintek chips have address register offset 0x05 added already
+        if ((address & 0x07) == 0x05)
+          address &= 0xFFF8;
+
+        if (address < 0x100 || (address & 0xF007) != 0) {
+          report.Append("Chip ID: 0x");
+          report.AppendLine(chip.ToString("X"));
+          report.Append("Chip revision: 0x");
+          report.AppendLine(revision.ToString("X", 
+            CultureInfo.InvariantCulture));
+          report.Append("Error: Invalid address 0x");
+          report.AppendLine(address.ToString("X", 
+            CultureInfo.InvariantCulture));
+          report.AppendLine();
+          return false;
+        }
+
+        switch (chip) {
+          case Chip.W83627DHG:
+          case Chip.W83627DHGP:
+          case Chip.W83627EHF:
+          case Chip.W83627HF:
+          case Chip.W83627THF:
+          case Chip.W83667HG:
+          case Chip.W83667HGB:
+          case Chip.W83687THF:
+            superIOs.Add(new W836XX(chip, revision, address));
+            break;
+          case Chip.F71858:
+          case Chip.F71862:
+          case Chip.F71869:
+          case Chip.F71882:
+          case Chip.F71889ED:
+          case Chip.F71889F:
+            if (vendorID != FINTEK_VENDOR_ID) {
+              report.Append("Chip ID: 0x");
+              report.AppendLine(chip.ToString("X"));
+              report.Append("Chip revision: 0x");
+              report.AppendLine(revision.ToString("X", 
+                CultureInfo.InvariantCulture));
+              report.Append("Error: Invalid vendor ID 0x");
+              report.AppendLine(vendorID.ToString("X", 
+                CultureInfo.InvariantCulture));
+              report.AppendLine();
+              return false;
+            }
+            superIOs.Add(new F718XX(chip, address));
+            break;
+          default: break;
+        }
+
+        return true;
+      }
+
+      return false;
+    }
+
+    private bool DetectIT87() {
+      IT87Enter();
+
+      ushort chipID = ReadWord(CHIP_ID_REGISTER);
+      Chip chip;
+      switch (chipID) {
+        case 0x8712: chip = Chip.IT8712F; break;
+        case 0x8716: chip = Chip.IT8716F; break;
+        case 0x8718: chip = Chip.IT8718F; break;
+        case 0x8720: chip = Chip.IT8720F; break;
+        case 0x8726: chip = Chip.IT8726F; break;
+        default: chip = Chip.Unknown; break;
+      }
+      if (chip == Chip.Unknown) {
+        if (chipID != 0 && chipID != 0xffff) {
+          IT87Exit();
+
+          ReportUnknownChip("ITE", chipID);
+        }
+      } else {
+        Select(IT87_ENVIRONMENT_CONTROLLER_LDN);
+        ushort address = ReadWord(BASE_ADDRESS_REGISTER);
+        Thread.Sleep(1);
+        ushort verify = ReadWord(BASE_ADDRESS_REGISTER);
+
+        byte version = (byte)(ReadByte(IT87_CHIP_VERSION_REGISTER) & 0x0F);
+
+        IT87Exit();
+
+        if (address != verify || address < 0x100 || (address & 0xF007) != 0) {
+          report.Append("Chip ID: 0x");
+          report.AppendLine(chip.ToString("X"));
+          report.Append("Error: Invalid address 0x");
+          report.AppendLine(address.ToString("X",
+            CultureInfo.InvariantCulture));
+          report.AppendLine();
+          return false;
+        }
+
+        superIOs.Add(new IT87XX(chip, address, version));
+        return true;
+      }
+
+      return false;
+    }
+
+    private bool DetectSMSC() {
+      SMSCEnter();
+
+      ushort chipID = ReadWord(CHIP_ID_REGISTER);
+      Chip chip;
+      switch (chipID) {
+        default: chip = Chip.Unknown; break;
+      }
+      if (chip == Chip.Unknown) {
+        if (chipID != 0 && chipID != 0xffff) {
+          SMSCExit();
+
+          ReportUnknownChip("SMSC", chipID);
+        }
+      } else {
+        SMSCExit();
+        return true;
+      }
+
+      return false;
+    }
+
     private void Detect() {
 
       for (int i = 0; i < REGISTER_PORTS.Length; i++) {
         registerPort = REGISTER_PORTS[i];
         valuePort = VALUE_PORTS[i];
 
-        WinbondFintekEnter();
+        if (DetectWinbondFintek()) continue;
 
-        byte logicalDeviceNumber;
-        byte id = ReadByte(CHIP_ID_REGISTER);
-        byte revision = ReadByte(CHIP_REVISION_REGISTER);
-        chip = Chip.Unknown;
-        logicalDeviceNumber = 0;
-        switch (id) {
-          case 0x05:
-            switch (revision) {
-              case 0x07:
-                chip = Chip.F71858;
-                logicalDeviceNumber = F71858_HARDWARE_MONITOR_LDN;
-                break;
-              case 0x41:
-                chip = Chip.F71882;
-                logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
-                break;
-            } break;
-          case 0x06:
-            switch (revision) {
-              case 0x01:
-                chip = Chip.F71862;
-                logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
-                break;
-            } break;
-          case 0x07:
-            switch (revision) {
-              case 0x23:
-                chip = Chip.F71889F;
-                logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
-                break;
-            } break;
-          case 0x08:
-            switch (revision) {
-              case 0x14:
-                chip = Chip.F71869;
-                logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
-                break;
-            } break;
-          case 0x09:
-            switch (revision) {
-              case 0x09:
-                chip = Chip.F71889ED;
-                logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
-                break;
-            } break;
-          case 0x52:
-            switch (revision) {
-              case 0x17:
-              case 0x3A:
-              case 0x41:
-                chip = Chip.W83627HF;
-                logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
-                break;
-            } break;
-          case 0x82:
-            switch (revision & 0xF0) {
-              case 0x80:
-                chip = Chip.W83627THF;
-                logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
-                break;
-            } break;
-          case 0x85:
-            switch (revision) {
-              case 0x41:
-                chip = Chip.W83687THF;
-                logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
-                break;
-            } break;
-          case 0x88:
-            switch (revision & 0xF0) {
-              case 0x50:
-              case 0x60:
-                chip = Chip.W83627EHF;
-                logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
-                break;
-            } break;
-          case 0xA0:
-            switch (revision & 0xF0) {
-              case 0x20:
-                chip = Chip.W83627DHG;
-                logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
-                break;
-            } break;
-          case 0xA5:
-            switch (revision & 0xF0) {
-              case 0x10:
-                chip = Chip.W83667HG;
-                logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
-                break;
-            } break;
-          case 0xB0:
-            switch (revision & 0xF0) {
-              case 0x70:
-                chip = Chip.W83627DHGP;
-                logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
-                break;
-            } break;
-          case 0xB3:
-            switch (revision & 0xF0) {
-              case 0x50:
-                chip = Chip.W83667HGB;
-                logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
-                break;
-            } break;
-        }
-        if (chip == Chip.Unknown) {
-          if (id != 0 && id != 0xff) {
-            WinbondFintekExit();
+        if (DetectIT87()) continue;
 
-            report.Append("Chip ID: Unknown Winbond / Fintek with ID 0x");
-            report.AppendLine(((id << 8) | revision).ToString("X", 
-              CultureInfo.InvariantCulture));
-            report.AppendLine();
-          }
-        } else {
-
-          Select(logicalDeviceNumber);
-          ushort address = ReadWord(BASE_ADDRESS_REGISTER);
-          Thread.Sleep(1);
-          ushort verify = ReadWord(BASE_ADDRESS_REGISTER);
-
-          ushort vendorID = ReadWord(FINTEK_VENDOR_ID_REGISTER);
-
-          WinbondFintekExit();
-
-          if (address != verify) {
-            report.Append("Chip ID: 0x");
-            report.AppendLine(chip.ToString("X"));
-            report.Append("Chip revision: 0x");
-            report.AppendLine(revision.ToString("X", CultureInfo.InvariantCulture));
-            report.AppendLine("Error: Address verification failed");
-            report.AppendLine();
-            return;
-          }
-
-          // some Fintek chips have address register offset 0x05 added already
-          if ((address & 0x07) == 0x05)
-            address &= 0xFFF8;
-
-          if (address < 0x100 || (address & 0xF007) != 0) {
-            report.Append("Chip ID: 0x");
-            report.AppendLine(chip.ToString("X"));
-            report.Append("Chip revision: 0x");
-            report.AppendLine(revision.ToString("X", CultureInfo.InvariantCulture));
-            report.Append("Error: Invalid address 0x");
-            report.AppendLine(address.ToString("X", CultureInfo.InvariantCulture));
-            report.AppendLine();
-            return;
-          }
-
-          switch (chip) {
-            case Chip.W83627DHG:
-            case Chip.W83627DHGP:
-            case Chip.W83627EHF:
-            case Chip.W83627HF:
-            case Chip.W83627THF:
-            case Chip.W83667HG:
-            case Chip.W83667HGB:
-            case Chip.W83687THF:
-              superIOs.Add(new W836XX(chip, revision, address));
-              break;
-            case Chip.F71858:
-            case Chip.F71862:
-            case Chip.F71869:
-            case Chip.F71882:
-            case Chip.F71889ED:
-            case Chip.F71889F:
-              if (vendorID != FINTEK_VENDOR_ID) {
-                report.Append("Chip ID: 0x");
-                report.AppendLine(chip.ToString("X"));
-                report.Append("Chip revision: 0x");
-                report.AppendLine(revision.ToString("X", CultureInfo.InvariantCulture));
-                report.Append("Error: Invalid vendor ID 0x");
-                report.AppendLine(vendorID.ToString("X", CultureInfo.InvariantCulture));
-                report.AppendLine();
-                return;
-              }
-              superIOs.Add(new F718XX(chip, address));
-              break;
-            default: break;
-          }
-
-          return;
-        }
-
-        IT87Enter();
-
-        ushort chipID = ReadWord(CHIP_ID_REGISTER);
-        switch (chipID) {
-          case 0x8712: chip = Chip.IT8712F; break;
-          case 0x8716: chip = Chip.IT8716F; break;
-          case 0x8718: chip = Chip.IT8718F; break;
-          case 0x8720: chip = Chip.IT8720F; break;
-          case 0x8726: chip = Chip.IT8726F; break;
-          default: chip = Chip.Unknown; break;
-        }
-        if (chip == Chip.Unknown) {
-          if (chipID != 0 && chipID != 0xffff) {
-            IT87Exit();
-
-            report.Append("Chip ID: Unknown ITE with ID 0x");
-            report.AppendLine(chipID.ToString("X", CultureInfo.InvariantCulture));
-            report.AppendLine();
-          }
-        } else {
-          Select(IT87_ENVIRONMENT_CONTROLLER_LDN);
-          ushort address = ReadWord(BASE_ADDRESS_REGISTER);
-          Thread.Sleep(1);
-          ushort verify = ReadWord(BASE_ADDRESS_REGISTER);
-
-          byte version = (byte)(ReadByte(IT87_CHIP_VERSION_REGISTER) & 0x0F);
-
-          IT87Exit();
-
-          if (address != verify || address < 0x100 || (address & 0xF007) != 0) {
-            report.Append("Chip ID: 0x");
-            report.AppendLine(chip.ToString("X"));
-            report.Append("Error: Invalid address 0x");
-            report.AppendLine(address.ToString("X", CultureInfo.InvariantCulture));
-            report.AppendLine();
-            return;
-          }
-
-          superIOs.Add(new IT87XX(chip, address, version));
-
-          return;
-        }
-
-        SMSCEnter();
-
-        chipID = ReadWord(CHIP_ID_REGISTER);
-        switch (chipID) {
-          default: chip = Chip.Unknown; break;
-        }
-        if (chip == Chip.Unknown) {
-          if (chipID != 0 && chipID != 0xffff) {
-            SMSCExit();
-
-            report.Append("Chip ID: Unknown SMSC with ID 0x");
-            report.AppendLine(chipID.ToString("X", CultureInfo.InvariantCulture));
-            report.AppendLine();
-          }
-        } else {
-          SMSCExit();
-
-          return;
-        }
+        if (DetectSMSC()) continue;
       }  
     }
 
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/LPC/W836XX.cs
--- a/Hardware/LPC/W836XX.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/LPC/W836XX.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -178,7 +178,7 @@
       return vendorId == WINBOND_VENDOR_ID;
     }
 
-    private ulong SetBit(ulong target, int bit, int value) {
+    private static ulong SetBit(ulong target, int bit, int value) {
       if ((value & 1) != value)
         throw new ArgumentException("Value must be one bit only.");
 
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/Mainboard/Mainboard.cs
--- a/Hardware/Mainboard/Mainboard.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/Mainboard/Mainboard.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -53,8 +53,7 @@
       this.smbios = new SMBIOS();
      
       if (smbios.Board != null) {
-        if (smbios.Board.ProductName != null
-          && smbios.Board.ProductName != "") {
+        if (!string.IsNullOrEmpty(smbios.Board.ProductName)) {
           if (smbios.Board.Manufacturer == Manufacturer.Unknown)
             this.name = smbios.Board.ProductName;
           else
@@ -131,8 +130,9 @@
     #pragma warning restore 67
 
     public void Accept(IVisitor visitor) {
-      if (visitor != null)
-        visitor.VisitHardware(this);
+      if (visitor == null)
+        throw new ArgumentNullException("visitor");
+      visitor.VisitHardware(this);
     }
 
     public void Traverse(IVisitor visitor) {
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/Mainboard/SMBIOS.cs
--- a/Hardware/Mainboard/SMBIOS.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/Mainboard/SMBIOS.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -51,7 +51,7 @@
     private BIOSInformation biosInformation = null;
     private BaseBoardInformation baseBoardInformation = null;
 
-    private string ReadSysFS(string path) {
+    private static string ReadSysFS(string path) {
       try {
         if (File.Exists(path)) {
           using (StreamReader reader = new StreamReader(path)) 
@@ -85,9 +85,12 @@
 
         raw = null;
         try {
-          ManagementObjectCollection collection = 
+          ManagementObjectCollection collection;
+          using (ManagementObjectSearcher searcher = 
             new ManagementObjectSearcher("root\\WMI", 
-              "SELECT SMBiosData FROM MSSMBios_RawSMBiosTables").Get();
+              "SELECT SMBiosData FROM MSSMBios_RawSMBiosTables")) {
+            collection = searcher.Get();
+          }
          
           foreach (ManagementObject mo in collection) {
             raw = (byte[])mo["SMBiosData"];
@@ -144,17 +147,19 @@
     public string GetReport() {
       StringBuilder r = new StringBuilder();
 
-      if (biosInformation != null) {
-        r.Append("BIOS Vendor: "); r.AppendLine(biosInformation.Vendor);
-        r.Append("BIOS Version: "); r.AppendLine(biosInformation.Version);
+      if (BIOS != null) {
+        r.Append("BIOS Vendor: "); r.AppendLine(BIOS.Vendor);
+        r.Append("BIOS Version: "); r.AppendLine(BIOS.Version);
         r.AppendLine();
       }
 
-      if (baseBoardInformation != null) {
+      if (Board != null) {
         r.Append("Mainboard Manufacturer: ");
-        r.AppendLine(baseBoardInformation.ManufacturerName);
+        r.AppendLine(Board.ManufacturerName);
         r.Append("Mainboard Name: ");
-        r.AppendLine(baseBoardInformation.ProductName);
+        r.AppendLine(Board.ProductName);
+        r.Append("Mainboard Version: ");
+        r.AppendLine(Board.Version);
         r.AppendLine();
       }
 
@@ -249,10 +254,10 @@
       private Manufacturer manufacturer;
       private Model model;
 
-      private void SetManufacturerName(string manufacturerName) {
-        this.manufacturerName = manufacturerName;
+      private void SetManufacturerName(string name) {
+        this.manufacturerName = name;
         
-        switch (manufacturerName) {
+        switch (name) {
           case "ASRock":
             manufacturer = Manufacturer.ASRock; break;
           case "ASUSTeK Computer INC.":
@@ -286,10 +291,10 @@
         }
       }
       
-      private void SetProductName(string productName) {
-        this.productName = productName;
+      private void SetProductName(string name) {
+        this.productName = name;
         
-        switch (productName) {
+        switch (name) {
           case "880GMH/USB3":
             model = Model._880GMH_USB3; break;
           case "Crosshair III Formula":
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/Mainboard/SuperIOHardware.cs
--- a/Hardware/Mainboard/SuperIOHardware.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/Mainboard/SuperIOHardware.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -44,39 +44,18 @@
   internal class SuperIOHardware : Hardware {
 
     private ISuperIO superIO;
-    protected readonly string name;
+    private string name;
 
     private List<Sensor> voltages = new List<Sensor>();
     private List<Sensor> temperatures = new List<Sensor>();
-    private List<Sensor> fans = new List<Sensor>();  
+    private List<Sensor> fans = new List<Sensor>();
+
 
     public SuperIOHardware(ISuperIO superIO, Manufacturer manufacturer,
       Model model, ISettings settings) 
     {
       this.superIO = superIO;
-
-      switch (superIO.Chip) {
-        case Chip.F71858: name = "Fintek F71858"; break;
-        case Chip.F71862: name = "Fintek F71862"; break;
-        case Chip.F71869: name = "Fintek F71869"; break;
-        case Chip.F71882: name = "Fintek F71882"; break;
-        case Chip.F71889ED: name = "Fintek F71889ED"; break;
-        case Chip.F71889F: name = "Fintek F71889F"; break;
-        case Chip.IT8712F: this.name = "ITE IT8712F"; break;
-        case Chip.IT8716F: this.name = "ITE IT8716F"; break;
-        case Chip.IT8718F: this.name = "ITE IT8718F"; break;
-        case Chip.IT8720F: this.name = "ITE IT8720F"; break;
-        case Chip.IT8726F: this.name = "ITE IT8726F"; break;
-        case Chip.W83627DHG: this.name = "Winbond W83627DHG"; break;
-        case Chip.W83627DHGP: this.name = "Winbond W83627DHG-P"; break;
-        case Chip.W83627EHF: this.name = "Winbond W83627EHF"; break;
-        case Chip.W83627HF: this.name = "Winbond W83627HF"; break;
-        case Chip.W83627THF: this.name = "Winbond W83627THF"; break;
-        case Chip.W83667HG: this.name = "Winbond W83667HG"; break;
-        case Chip.W83667HGB: this.name = "Winbond W83667HG-B"; break;
-        case Chip.W83687THF: this.name = "Winbond W83687THF"; break;
-        case Chip.Unknown: this.name = "Unkown"; break;
-      }
+      this.name = ChipName.GetName(superIO.Chip);
 
       List<Voltage> v = new List<Voltage>();
       List<Temperature> t = new List<Temperature>();
@@ -483,7 +462,6 @@
                   v.Add(new Voltage("Standby +3.3V", 7, 34, 34, 0));
                   v.Add(new Voltage("VBAT", 8, 34, 34, 0));
                   t.Add(new Temperature("CPU", 0));
-                  t.Add(new Temperature("Auxiliary", 1, true));
                   t.Add(new Temperature("Motherboard", 2));
                   f.Add(new Fan("Chassis Fan #1", 0));
                   f.Add(new Fan("CPU Fan", 1));
@@ -673,15 +651,10 @@
     private class Temperature {
       public readonly string Name;
       public readonly int Index;
-      public readonly bool Hidden;
 
-      public Temperature(string name, int index) :
-        this(name, index, false) { }
-
-      public Temperature(string name, int index, bool hidden) {
+      public Temperature(string name, int index) {
         this.Name = name;
         this.Index = index;
-        this.Hidden = hidden;
       }
     }
 
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/Nvidia/NVAPI.cs
--- a/Hardware/Nvidia/NVAPI.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/Nvidia/NVAPI.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -310,7 +310,9 @@
     public static readonly NvAPI_GPU_GetMemoryInfoDelegate
       NvAPI_GPU_GetMemoryInfo;
     public static readonly NvAPI_GetDisplayDriverVersionDelegate
-      NvAPI_GetDisplayDriverVersion;    
+      NvAPI_GetDisplayDriverVersion;
+
+    private NVAPI() { }
 
     public static NvStatus NvAPI_GPU_GetFullName(NvPhysicalGpuHandle gpuHandle,
       out string name) {
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/Nvidia/NvidiaGPU.cs
--- a/Hardware/Nvidia/NvidiaGPU.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/Nvidia/NvidiaGPU.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -239,7 +239,8 @@
           r.Append("Driver Version: ");
           r.Append(driverVersion.DriverVersion / 100);
           r.Append(".");
-          r.Append((driverVersion.DriverVersion % 100).ToString("00", CultureInfo.InvariantCulture));
+          r.Append((driverVersion.DriverVersion % 100).ToString("00", 
+            CultureInfo.InvariantCulture));
           r.AppendLine();
           r.Append("Driver Branch: ");
           r.AppendLine(driverVersion.BuildBranch);
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/PInvokeDelegateFactory.cs
--- a/Hardware/PInvokeDelegateFactory.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/PInvokeDelegateFactory.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -45,25 +45,15 @@
 
   internal sealed class PInvokeDelegateFactory {
 
-    private static AssemblyBuilder assemblyBuilder;
-    private static ModuleBuilder moduleBuilder;
+    private static ModuleBuilder moduleBuilder = 
+      AppDomain.CurrentDomain.DefineDynamicAssembly(
+        new AssemblyName("PInvokeDelegateFactoryInternalAssembly"),
+        AssemblyBuilderAccess.Run).DefineDynamicModule(
+        "PInvokeDelegateFactoryInternalModule");
 
     private static IDictionary<DllImportAttribute, Type> wrapperTypes =
       new Dictionary<DllImportAttribute, Type>();
 
-    static PInvokeDelegateFactory() {
-
-      AssemblyName assemblyName = new AssemblyName();
-      assemblyName.Name = "PInvokeDelegateFactoryInternalAssembly";
-
-      assemblyBuilder =
-        AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName,
-        AssemblyBuilderAccess.Run);
-
-      moduleBuilder = assemblyBuilder.DefineDynamicModule(
-        "PInvokeDelegateFactoryInternalModule");
-    }
-
     private PInvokeDelegateFactory() { }
 
     public static void CreateDelegate<T>(DllImportAttribute dllImportAttribute,
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/Parameter.cs
--- a/Hardware/Parameter.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/Parameter.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -41,7 +41,7 @@
 
 namespace OpenHardwareMonitor.Hardware {
 
-  public struct ParameterDescription {
+  internal struct ParameterDescription {
     private string name;
     private string description;
     private float defaultValue;    
@@ -60,7 +60,7 @@
     public float DefaultValue { get { return defaultValue; } }
   }
 
-  public class Parameter : IParameter {
+  internal class Parameter : IParameter {
     private ISensor sensor;
     private ParameterDescription description;
     private float value;
@@ -129,8 +129,9 @@
     }
 
     public void Accept(IVisitor visitor) {
-      if (visitor != null)
-        visitor.VisitParameter(this);
+      if (visitor == null)
+        throw new ArgumentNullException("visitor");
+      visitor.VisitParameter(this);
     }
 
     public void Traverse(IVisitor visitor) { }
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/Sensor.cs
--- a/Hardware/Sensor.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/Sensor.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -51,9 +51,9 @@
     private SensorType sensorType;
     private IHardware hardware;
     private ReadOnlyArray<IParameter> parameters;
-    private float? value;
-    private float? min;
-    private float? max;
+    private float? currentValue;
+    private float? minValue;
+    private float? maxValue;
     private Queue<SensorValue> values =
       new Queue<SensorValue>(MAX_MINUTES * 15);
     private ISettings settings;
@@ -114,7 +114,7 @@
         return name; 
       }
       set {
-        if (value != "") 
+        if (!string.IsNullOrEmpty(value)) 
           name = value;          
         else 
           name = defaultName;
@@ -136,7 +136,7 @@
 
     public float? Value {
       get { 
-        return value; 
+        return currentValue; 
       }
       set {
         while (values.Count > 0 && 
@@ -153,23 +153,23 @@
           }
         }
 
-        this.value = value;
-        if (min > value || !min.HasValue)
-          min = value;
-        if (max < value || !max.HasValue)
-          max = value;
+        this.currentValue = value;
+        if (minValue > value || !minValue.HasValue)
+          minValue = value;
+        if (maxValue < value || !maxValue.HasValue)
+          maxValue = value;
       }
     }
 
-    public float? Min { get { return min; } }
-    public float? Max { get { return max; } }
+    public float? Min { get { return minValue; } }
+    public float? Max { get { return maxValue; } }
 
     public void ResetMin() {
-      min = null;
+      minValue = null;
     }
 
     public void ResetMax() {
-      max = null;
+      maxValue = null;
     }
 
     public IEnumerable<SensorValue> Values {
@@ -177,8 +177,9 @@
     }    
 
     public void Accept(IVisitor visitor) {
-      if (visitor != null)
-        visitor.VisitSensor(this);
+      if (visitor == null)
+        throw new ArgumentNullException("visitor");
+      visitor.VisitSensor(this);
     }
 
     public void Traverse(IVisitor visitor) {
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/SensorVisitor.cs
--- a/Hardware/SensorVisitor.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/SensorVisitor.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -45,14 +45,20 @@
     private SensorEventHandler handler;
 
     public SensorVisitor(SensorEventHandler handler) {
+      if (handler == null)
+        throw new ArgumentNullException("handler");
       this.handler = handler;
     }
 
     public void VisitComputer(IComputer computer) {
+      if (computer == null)
+        throw new ArgumentNullException("computer");
       computer.Traverse(this);
     }
 
     public void VisitHardware(IHardware hardware) {
+      if (hardware == null)
+        throw new ArgumentNullException("hardware");
       hardware.Traverse(this);
     }
 
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/TBalancer/FTD2XX.cs
--- a/Hardware/TBalancer/FTD2XX.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/TBalancer/FTD2XX.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -128,18 +128,44 @@
     public delegate FT_STATUS FT_ReadDelegate(FT_HANDLE handle, 
       [Out] byte[] buffer, uint bytesToRead, out uint bytesReturned);
 
-    public static FT_CreateDeviceInfoListDelegate FT_CreateDeviceInfoList;
-    public static FT_GetDeviceInfoListDelegate FT_GetDeviceInfoList;
-    public static FT_OpenDelegate FT_Open;
-    public static FT_CloseDelegate FT_Close;
-    public static FT_SetBaudRateDelegate FT_SetBaudRate;
-    public static FT_SetDataCharacteristicsDelegate FT_SetDataCharacteristics;
-    public static FT_SetFlowControlDelegate FT_SetFlowControl;
-    public static FT_SetTimeoutsDelegate FT_SetTimeouts;
-    public static FT_WriteDelegate FT_Write;
-    public static FT_PurgeDelegate FT_Purge;
-    public static FT_GetStatusDelegate FT_GetStatus;
-    public static FT_ReadDelegate FT_Read;
+    public static readonly FT_CreateDeviceInfoListDelegate 
+      FT_CreateDeviceInfoList = CreateDelegate<
+      FT_CreateDeviceInfoListDelegate>("FT_CreateDeviceInfoList");
+    public static readonly FT_GetDeviceInfoListDelegate 
+      FT_GetDeviceInfoList = CreateDelegate<
+      FT_GetDeviceInfoListDelegate>("FT_GetDeviceInfoList");
+    public static readonly FT_OpenDelegate 
+      FT_Open = CreateDelegate<
+      FT_OpenDelegate>("FT_Open");
+    public static readonly FT_CloseDelegate 
+      FT_Close = CreateDelegate<
+      FT_CloseDelegate>("FT_Close");
+    public static readonly FT_SetBaudRateDelegate 
+      FT_SetBaudRate = CreateDelegate<
+      FT_SetBaudRateDelegate>("FT_SetBaudRate");
+    public static readonly FT_SetDataCharacteristicsDelegate 
+      FT_SetDataCharacteristics = CreateDelegate<
+      FT_SetDataCharacteristicsDelegate>("FT_SetDataCharacteristics");
+    public static readonly FT_SetFlowControlDelegate 
+      FT_SetFlowControl = CreateDelegate<
+      FT_SetFlowControlDelegate>("FT_SetFlowControl");
+    public static readonly FT_SetTimeoutsDelegate 
+      FT_SetTimeouts = CreateDelegate<
+      FT_SetTimeoutsDelegate>("FT_SetTimeouts");
+    public static readonly FT_WriteDelegate 
+      FT_Write = CreateDelegate<
+      FT_WriteDelegate>("FT_Write");
+    public static readonly FT_PurgeDelegate 
+      FT_Purge = CreateDelegate<
+      FT_PurgeDelegate>("FT_Purge");
+    public static readonly FT_GetStatusDelegate 
+      FT_GetStatus = CreateDelegate<
+      FT_GetStatusDelegate>("FT_GetStatus");
+    public static readonly FT_ReadDelegate 
+      FT_Read = CreateDelegate<
+      FT_ReadDelegate>("FT_Read");
+
+    private FTD2XX() { }
 
     public static FT_STATUS Write(FT_HANDLE handle, byte[] buffer) {
       uint bytesWritten;
@@ -168,40 +194,27 @@
       uint bytesReturned;
       FT_STATUS status = FT_Read(handle, buffer, 1, out bytesReturned);
       if (status != FT_STATUS.FT_OK || bytesReturned != 1)
-        throw new Exception();
+        throw new InvalidOperationException();
       return buffer[0];
     }
 
-    private static string dllName;
+    private static string GetDllName() {
+      int p = (int)System.Environment.OSVersion.Platform;
+      if ((p == 4) || (p == 128))
+        return "libftd2xx.so";
+      else
+        return "ftd2xx.dll";
+    }
 
-    private static void GetDelegate<T>(string entryPoint, out T newDelegate)
+    private static T CreateDelegate<T>(string entryPoint)
       where T : class {
-      DllImportAttribute attribute = new DllImportAttribute(dllName);
+      DllImportAttribute attribute = new DllImportAttribute(GetDllName());
       attribute.CallingConvention = CallingConvention.StdCall;
       attribute.PreserveSig = true;
       attribute.EntryPoint = entryPoint;
+      T newDelegate;
       PInvokeDelegateFactory.CreateDelegate(attribute, out newDelegate);
-    }
-
-    static FTD2XX() {
-      int p = (int)System.Environment.OSVersion.Platform;
-      if ((p == 4) || (p == 128))
-        dllName = "libftd2xx.so";
-      else
-        dllName = "ftd2xx.dll";
-
-      GetDelegate("FT_CreateDeviceInfoList", out FT_CreateDeviceInfoList);
-      GetDelegate("FT_GetDeviceInfoList", out FT_GetDeviceInfoList);
-      GetDelegate("FT_Open", out FT_Open);
-      GetDelegate("FT_Close", out FT_Close);
-      GetDelegate("FT_SetBaudRate", out FT_SetBaudRate);
-      GetDelegate("FT_SetDataCharacteristics", out FT_SetDataCharacteristics);
-      GetDelegate("FT_SetFlowControl", out FT_SetFlowControl);
-      GetDelegate("FT_SetTimeouts", out FT_SetTimeouts);
-      GetDelegate("FT_Write", out FT_Write);
-      GetDelegate("FT_Purge", out FT_Purge);
-      GetDelegate("FT_GetStatus", out FT_GetStatus);
-      GetDelegate("FT_Read", out FT_Read);
+      return newDelegate;
     }
   }
 }
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/TBalancer/TBalancer.cs
--- a/Hardware/TBalancer/TBalancer.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/TBalancer/TBalancer.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -161,8 +161,6 @@
       }
 
       for (int i = 0; i < 2; i++) {
-        float maxRPM = 20.0f * data[offset + 44 + 2 * i];
-
         if (miniNGFans[number * 2 + i] == null)
           miniNGFans[number * 2 + i] = 
             new Sensor("miniNG #" + (number + 1) + " Fan Channel " + (i + 1),
@@ -376,8 +374,9 @@
     public event SensorEventHandler SensorRemoved;
 
     public void Accept(IVisitor visitor) {
-      if (visitor != null)
-        visitor.VisitHardware(this);
+      if (visitor == null)
+        throw new ArgumentNullException("visitor");
+      visitor.VisitHardware(this);
     }
 
     public void Traverse(IVisitor visitor) { }
diff -r fa9dfbfc4145 -r b7cc9d09aefe Hardware/WinRing0.cs
--- a/Hardware/WinRing0.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Hardware/WinRing0.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -44,6 +44,8 @@
 namespace OpenHardwareMonitor.Hardware {
 
   internal class WinRing0 {
+
+    private WinRing0() { }
     
     public enum OlsDllStatus{
       OLS_DLL_NO_ERROR                        = 0,
@@ -56,7 +58,7 @@
     }
 
     private static bool available = false;
-    public static Mutex isaBusMutex;
+    private static Mutex isaBusMutex;
 
     private static string GetDllName() {   
       int p = (int)System.Environment.OSVersion.Platform;
@@ -78,10 +80,7 @@
     private delegate bool InitializeOlsDelegate();
     private delegate void DeinitializeOlsDelegate();
     
-    public delegate uint GetDllStatusDelegate();
     public delegate bool IsCpuidDelegate();
-    public delegate bool CpuidDelegate(uint index, uint ecxValue, 
-      out uint eax, out uint ebx, out uint ecx, out uint edx);
     public delegate bool CpuidTxDelegate(uint index, uint ecxValue,
       out uint eax, out uint ebx, out uint ecx, out uint edx,
       UIntPtr threadAffinityMask);
@@ -90,7 +89,6 @@
       UIntPtr threadAffinityMask);
     public delegate byte ReadIoPortByteDelegate(ushort port);
     public delegate void WriteIoPortByteDelegate(ushort port, byte value);
-    public delegate void SetPciMaxBusIndexDelegate(byte max);
     public delegate uint FindPciDeviceByIdDelegate(ushort vendorId, 
       ushort deviceId, byte index);
     public delegate bool ReadPciConfigDwordExDelegate(uint pciAddress, 
@@ -101,85 +99,73 @@
       UIntPtr threadAffinityMask);
     public delegate bool RdtscDelegate(out uint eax, out uint edx);
 
-    private static InitializeOlsDelegate InitializeOls;
-    private static DeinitializeOlsDelegate DeinitializeOls;
+    private static InitializeOlsDelegate InitializeOls = 
+      CreateDelegate<InitializeOlsDelegate>("InitializeOls");
+    private static DeinitializeOlsDelegate DeinitializeOls =
+      CreateDelegate<DeinitializeOlsDelegate>("DeinitializeOls");
 
-    public static readonly GetDllStatusDelegate GetDllStatus;
-    public static readonly IsCpuidDelegate IsCpuid;
-    public static readonly CpuidDelegate Cpuid;
-    public static readonly CpuidTxDelegate CpuidTx;
-    public static readonly RdmsrDelegate Rdmsr;
-    public static readonly RdmsrTxDelegate RdmsrTx;
-    public static readonly ReadIoPortByteDelegate ReadIoPortByte;
-    public static readonly WriteIoPortByteDelegate WriteIoPortByte;
-    public static readonly SetPciMaxBusIndexDelegate SetPciMaxBusIndex;
-    public static readonly FindPciDeviceByIdDelegate FindPciDeviceById;
-    public static readonly ReadPciConfigDwordExDelegate ReadPciConfigDwordEx;
-    public static readonly WritePciConfigDwordExDelegate WritePciConfigDwordEx;
-    public static readonly RdtscTxDelegate RdtscTx;
-    public static readonly RdtscDelegate Rdtsc;
-
-    
-
-    private static void GetDelegate<T>(string entryPoint, out T newDelegate) 
-      where T : class 
-    {
+    public static readonly IsCpuidDelegate IsCpuid =
+      CreateDelegate<IsCpuidDelegate>("IsCpuid");
+    public static readonly CpuidTxDelegate CpuidTx =
+      CreateDelegate<CpuidTxDelegate>("CpuidTx");
+    public static readonly RdmsrDelegate Rdmsr =
+      CreateDelegate<RdmsrDelegate>("Rdmsr");
+    public static readonly RdmsrTxDelegate RdmsrTx =
+      CreateDelegate<RdmsrTxDelegate>("RdmsrTx");
+    public static readonly ReadIoPortByteDelegate ReadIoPortByte =
+      CreateDelegate<ReadIoPortByteDelegate>("ReadIoPortByte");
+    public static readonly WriteIoPortByteDelegate WriteIoPortByte =
+      CreateDelegate<WriteIoPortByteDelegate>("WriteIoPortByte");
+    public static readonly FindPciDeviceByIdDelegate FindPciDeviceById =
+      CreateDelegate<FindPciDeviceByIdDelegate>("FindPciDeviceById");
+    public static readonly ReadPciConfigDwordExDelegate ReadPciConfigDwordEx =
+      CreateDelegate<ReadPciConfigDwordExDelegate>("ReadPciConfigDwordEx");
+    public static readonly WritePciConfigDwordExDelegate WritePciConfigDwordEx =
+      CreateDelegate<WritePciConfigDwordExDelegate>("WritePciConfigDwordEx");
+    public static readonly RdtscTxDelegate RdtscTx =
+      CreateDelegate<RdtscTxDelegate>("RdtscTx");
+    public static readonly RdtscDelegate Rdtsc =
+      CreateDelegate<RdtscDelegate>("Rdtsc");
+ 
+    private static T CreateDelegate<T>(string entryPoint) where T : class {
       DllImportAttribute attribute = new DllImportAttribute(GetDllName());
       attribute.CallingConvention = CallingConvention.Winapi;
       attribute.PreserveSig = true;
       attribute.EntryPoint = entryPoint;
       attribute.CharSet = CharSet.Auto;
-      PInvokeDelegateFactory.CreateDelegate(attribute, out newDelegate);
+      T result;
+      PInvokeDelegateFactory.CreateDelegate(attribute, out result);
+      return result;
     }
 
-    static WinRing0() {
-      GetDelegate("InitializeOls", out InitializeOls);
-      GetDelegate("DeinitializeOls", out DeinitializeOls);
-      GetDelegate("GetDllStatus", out GetDllStatus);
-      GetDelegate("IsCpuid", out IsCpuid);
-      GetDelegate("Cpuid", out Cpuid);
-      GetDelegate("CpuidTx", out CpuidTx);
-      GetDelegate("Rdmsr", out  Rdmsr);
-      GetDelegate("RdmsrTx", out  RdmsrTx);
-      GetDelegate("ReadIoPortByte", out ReadIoPortByte);
-      GetDelegate("WriteIoPortByte", out WriteIoPortByte);
-      GetDelegate("SetPciMaxBusIndex", out SetPciMaxBusIndex);
-      GetDelegate("FindPciDeviceById", out FindPciDeviceById);
-      GetDelegate("ReadPciConfigDwordEx", out ReadPciConfigDwordEx);
-      GetDelegate("WritePciConfigDwordEx", out WritePciConfigDwordEx);
-      GetDelegate("RdtscTx", out RdtscTx);
-      GetDelegate("Rdtsc", out Rdtsc);
-
+    public static void Open() {
       try {
         if (InitializeOls != null && InitializeOls())
           available = true;
-      } catch (DllNotFoundException) { }
-
+      } catch (DllNotFoundException) { }   
+      
       isaBusMutex = new Mutex(false, "Access_ISABUS.HTP.Method");
     }
-    
+
     public static bool IsAvailable {
       get { return available; }
     }
 
+    public static void Close() {
+      if (available)
+        DeinitializeOls();        
+      isaBusMutex.Close();      
+    }    
+
     public static bool WaitIsaBusMutex(int millisecondsTimeout) {
       try {
-        return isaBusMutex.WaitOne(millisecondsTimeout);
-      } catch { return false; }
+        return isaBusMutex.WaitOne(millisecondsTimeout, false);
+      } catch (AbandonedMutexException) { return false; } 
+        catch (InvalidOperationException) { return false; }     
     }
 
     public static void ReleaseIsaBusMutex() {
       isaBusMutex.ReleaseMutex();
-    }
-
-    private static Deinitializer deinitializer = new Deinitializer();
-    private class Deinitializer {
-      ~Deinitializer() {
-        if (available)
-          DeinitializeOls();
-        
-        isaBusMutex.Close();
-      }
-    }
+    }    
   }
 }
diff -r fa9dfbfc4145 -r b7cc9d09aefe OpenHardwareMonitorLib.csproj
--- a/OpenHardwareMonitorLib.csproj	Thu Aug 12 20:53:27 2010 +0000
+++ b/OpenHardwareMonitorLib.csproj	Sun Aug 15 14:46:58 2010 +0000
@@ -41,6 +41,7 @@
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>none</DebugType>
diff -r fa9dfbfc4145 -r b7cc9d09aefe Properties/AssemblyLibInfo.cs
--- a/Properties/AssemblyLibInfo.cs	Thu Aug 12 20:53:27 2010 +0000
+++ b/Properties/AssemblyLibInfo.cs	Sun Aug 15 14:46:58 2010 +0000
@@ -50,4 +50,5 @@
 [assembly: AssemblyCulture("")]
 
 [assembly: ComVisible(false)]
-[assembly: CLSCompliant(true)]
\ No newline at end of file
+[assembly: CLSCompliant(true)]
+