Replaced the non-kernel code of WinRing0 with a managed implementation. The new implementation should fix Issue 32 and simplify further work on Issue 46.
authormoel.mich
Sun, 31 Oct 2010 22:08:47 +0000
changeset 236763675f19ff4
parent 235 99b6bab765f8
child 237 9bf70d316cea
Replaced the non-kernel code of WinRing0 with a managed implementation. The new implementation should fix Issue 32 and simplify further work on Issue 46.
External/WinRing0.dll
External/WinRing0.sys
External/WinRing0x64.dll
External/WinRing0x64.sys
Hardware/CPU/AMD0FCPU.cs
Hardware/CPU/AMD10CPU.cs
Hardware/CPU/AMDCPU.cs
Hardware/CPU/CPUGroup.cs
Hardware/CPU/CPUID.cs
Hardware/CPU/GenericCPU.cs
Hardware/CPU/IntelCPU.cs
Hardware/Computer.cs
Hardware/IOControlCode.cs
Hardware/KernelDriver.cs
Hardware/LPC/F718XX.cs
Hardware/LPC/IT87XX.cs
Hardware/LPC/LPCIO.cs
Hardware/LPC/W836XX.cs
Hardware/Opcode.cs
Hardware/Ring0.cs
Hardware/WinRing0.cs
Hardware/WinRing0.sys
Hardware/WinRing0x64.sys
OpenHardwareMonitorLib.csproj
Program.cs
     1.1 Binary file External/WinRing0.dll has changed
     2.1 Binary file External/WinRing0.sys has changed
     3.1 Binary file External/WinRing0x64.dll has changed
     4.1 Binary file External/WinRing0x64.sys has changed
     5.1 --- a/Hardware/CPU/AMD0FCPU.cs	Mon Oct 18 07:18:14 2010 +0000
     5.2 +++ b/Hardware/CPU/AMD0FCPU.cs	Sun Oct 31 22:08:47 2010 +0000
     5.3 @@ -118,13 +118,13 @@
     5.4      public override void Update() {
     5.5        base.Update();
     5.6  
     5.7 -      if (miscellaneousControlAddress != WinRing0.InvalidPciAddress) {
     5.8 +      if (miscellaneousControlAddress != Ring0.InvalidPciAddress) {
     5.9          for (uint i = 0; i < coreTemperatures.Length; i++) {
    5.10 -          if (WinRing0.WritePciConfigDwordEx(
    5.11 +          if (Ring0.WritePciConfig(
    5.12              miscellaneousControlAddress, THERMTRIP_STATUS_REGISTER,
    5.13              i > 0 ? THERM_SENSE_CORE_SEL_CPU1 : THERM_SENSE_CORE_SEL_CPU0)) {
    5.14              uint value;
    5.15 -            if (WinRing0.ReadPciConfigDwordEx(
    5.16 +            if (Ring0.ReadPciConfig(
    5.17                miscellaneousControlAddress, THERMTRIP_STATUS_REGISTER, 
    5.18                out value)) 
    5.19              {
    5.20 @@ -145,7 +145,7 @@
    5.21            Thread.Sleep(1);
    5.22  
    5.23            uint eax, edx;
    5.24 -          if (WinRing0.RdmsrTx(FIDVID_STATUS, out eax, out edx,
    5.25 +          if (Ring0.RdmsrTx(FIDVID_STATUS, out eax, out edx,
    5.26              (UIntPtr)(1L << cpuid[i][0].Thread))) {
    5.27              // CurrFID can be found in eax bits 0-5, MaxFID in 16-21
    5.28              // 8-13 hold StartFID, we don't use that here.
     6.1 --- a/Hardware/CPU/AMD10CPU.cs	Mon Oct 18 07:18:14 2010 +0000
     6.2 +++ b/Hardware/CPU/AMD10CPU.cs	Sun Oct 31 22:08:47 2010 +0000
     6.3 @@ -93,15 +93,15 @@
     6.4          (UIntPtr)(1L << cpuid[0][0].Thread));
     6.5  
     6.6        uint ctlEax, ctlEdx;
     6.7 -      WinRing0.Rdmsr(PERF_CTL_0, out ctlEax, out ctlEdx);
     6.8 +      Ring0.Rdmsr(PERF_CTL_0, out ctlEax, out ctlEdx);
     6.9        uint ctrEax, ctrEdx;
    6.10 -      WinRing0.Rdmsr(PERF_CTR_0, out ctrEax, out ctrEdx);
    6.11 +      Ring0.Rdmsr(PERF_CTR_0, out ctrEax, out ctrEdx);
    6.12  
    6.13        timeStampCounterMultiplier = estimateTimeStampCounterMultiplier();
    6.14  
    6.15        // restore the performance counter registers
    6.16 -      WinRing0.Wrmsr(PERF_CTL_0, ctlEax, ctlEdx);
    6.17 -      WinRing0.Wrmsr(PERF_CTR_0, ctrEax, ctrEdx);
    6.18 +      Ring0.Wrmsr(PERF_CTL_0, ctlEax, ctlEdx);
    6.19 +      Ring0.Wrmsr(PERF_CTR_0, ctrEax, ctrEdx);
    6.20  
    6.21        // restore the thread affinity.
    6.22        NativeMethods.SetThreadAffinityMask(thread, mask);
    6.23 @@ -126,14 +126,14 @@
    6.24        uint eax, edx;
    6.25       
    6.26        // select event "076h CPU Clocks not Halted" and enable the counter
    6.27 -      WinRing0.Wrmsr(PERF_CTL_0,
    6.28 +      Ring0.Wrmsr(PERF_CTL_0,
    6.29          (1 << 22) | // enable performance counter
    6.30          (1 << 17) | // count events in user mode
    6.31          (1 << 16) | // count events in operating-system mode
    6.32          0x76, 0x00000000);
    6.33  
    6.34        // set the counter to 0
    6.35 -      WinRing0.Wrmsr(PERF_CTR_0, 0, 0);
    6.36 +      Ring0.Wrmsr(PERF_CTR_0, 0, 0);
    6.37  
    6.38        long ticks = (long)(timeWindow * Stopwatch.Frequency);
    6.39        uint lsbBegin, msbBegin, lsbEnd, msbEnd;
    6.40 @@ -142,11 +142,11 @@
    6.41          (long)Math.Ceiling(0.001 * ticks);
    6.42        long timeEnd = timeBegin + ticks;
    6.43        while (Stopwatch.GetTimestamp() < timeBegin) { }
    6.44 -      WinRing0.Rdmsr(PERF_CTR_0, out lsbBegin, out msbBegin);
    6.45 +      Ring0.Rdmsr(PERF_CTR_0, out lsbBegin, out msbBegin);
    6.46        while (Stopwatch.GetTimestamp() < timeEnd) { }
    6.47 -      WinRing0.Rdmsr(PERF_CTR_0, out lsbEnd, out msbEnd);
    6.48 +      Ring0.Rdmsr(PERF_CTR_0, out lsbEnd, out msbEnd);
    6.49  
    6.50 -      WinRing0.Rdmsr(COFVID_STATUS, out eax, out edx);
    6.51 +      Ring0.Rdmsr(COFVID_STATUS, out eax, out edx);
    6.52        uint cpuDid = (eax >> 6) & 7;
    6.53        uint cpuFid = eax & 0x1F;
    6.54        double coreMultiplier = MultiplierFromIDs(cpuDid, cpuFid);
    6.55 @@ -188,9 +188,9 @@
    6.56      public override void Update() {
    6.57        base.Update();
    6.58  
    6.59 -      if (miscellaneousControlAddress != WinRing0.InvalidPciAddress) {
    6.60 +      if (miscellaneousControlAddress != Ring0.InvalidPciAddress) {
    6.61          uint value;
    6.62 -        if (WinRing0.ReadPciConfigDwordEx(miscellaneousControlAddress,
    6.63 +        if (Ring0.ReadPciConfig(miscellaneousControlAddress,
    6.64            REPORTED_TEMPERATURE_CONTROL_REGISTER, out value)) {
    6.65            coreTemperature.Value = ((value >> 21) & 0x7FF) / 8.0f +
    6.66              coreTemperature.Parameters[0].Value;
    6.67 @@ -207,7 +207,7 @@
    6.68            Thread.Sleep(1);
    6.69  
    6.70            uint curEax, curEdx;
    6.71 -          if (WinRing0.RdmsrTx(COFVID_STATUS, out curEax, out curEdx,
    6.72 +          if (Ring0.RdmsrTx(COFVID_STATUS, out curEax, out curEdx,
    6.73              (UIntPtr)(1L << cpuid[i][0].Thread))) 
    6.74            {
    6.75              // 8:6 CpuDid: current core divisor ID
     7.1 --- a/Hardware/CPU/AMDCPU.cs	Mon Oct 18 07:18:14 2010 +0000
     7.2 +++ b/Hardware/CPU/AMDCPU.cs	Sun Oct 31 22:08:47 2010 +0000
     7.3 @@ -50,17 +50,17 @@
     7.4      protected uint GetPciAddress(byte function, ushort deviceId) {
     7.5        
     7.6        // assemble the pci address
     7.7 -      uint address = WinRing0.GetPciAddress(PCI_BUS,
     7.8 +      uint address = Ring0.GetPciAddress(PCI_BUS,
     7.9          (byte)(PCI_BASE_DEVICE + processorIndex), function);
    7.10  
    7.11        // verify that we have the correct bus, device and function
    7.12        uint deviceVendor;
    7.13 -      if (!WinRing0.ReadPciConfigDwordEx(
    7.14 +      if (!Ring0.ReadPciConfig(
    7.15          address, DEVICE_VENDOR_ID_REGISTER, out deviceVendor))
    7.16 -        return WinRing0.InvalidPciAddress;
    7.17 +        return Ring0.InvalidPciAddress;
    7.18        
    7.19        if (deviceVendor != (deviceId << 16 | AMD_VENDOR_ID))
    7.20 -        return WinRing0.InvalidPciAddress;
    7.21 +        return Ring0.InvalidPciAddress;
    7.22  
    7.23        return address;
    7.24      }
     8.1 --- a/Hardware/CPU/CPUGroup.cs	Mon Oct 18 07:18:14 2010 +0000
     8.2 +++ b/Hardware/CPU/CPUGroup.cs	Sun Oct 31 22:08:47 2010 +0000
     8.3 @@ -104,10 +104,7 @@
     8.4        // No implementation for cpuid on Unix systems
     8.5        int p = (int)Environment.OSVersion.Platform;
     8.6        if ((p == 4) || (p == 128)) 
     8.7 -        return;
     8.8 -      
     8.9 -      if (!WinRing0.IsCpuid())
    8.10 -        return;
    8.11 +        return;     
    8.12  
    8.13        CPUID[][] processorThreads = GetProcessorThreads();
    8.14        this.threads = new CPUID[processorThreads.Length][][];
     9.1 --- a/Hardware/CPU/CPUID.cs	Mon Oct 18 07:18:14 2010 +0000
     9.2 +++ b/Hardware/CPU/CPUID.cs	Sun Oct 31 22:08:47 2010 +0000
     9.3 @@ -107,7 +107,7 @@
     9.4          throw new ArgumentOutOfRangeException("thread");
     9.5        UIntPtr mask = (UIntPtr)(1L << thread);
     9.6  
     9.7 -      if (WinRing0.CpuidTx(CPUID_0, 0,
     9.8 +      if (Opcode.CpuidTx(CPUID_0, 0,
     9.9            out eax, out ebx, out ecx, out edx, mask)) {
    9.10          if (eax > 0)
    9.11            maxCpuid = eax;
    9.12 @@ -131,7 +131,7 @@
    9.13              break;
    9.14          }
    9.15          eax = ebx = ecx = edx = 0;
    9.16 -        if (WinRing0.CpuidTx(CPUID_EXT, 0,
    9.17 +        if (Opcode.CpuidTx(CPUID_EXT, 0,
    9.18            out eax, out ebx, out ecx, out edx, mask)) {
    9.19            if (eax > CPUID_EXT)
    9.20              maxCpuidExt = eax - CPUID_EXT;
    9.21 @@ -149,19 +149,19 @@
    9.22  
    9.23        cpuidData = new uint[maxCpuid + 1, 4];
    9.24        for (uint i = 0; i < (maxCpuid + 1); i++)
    9.25 -        WinRing0.CpuidTx(CPUID_0 + i, 0, 
    9.26 +        Opcode.CpuidTx(CPUID_0 + i, 0, 
    9.27            out cpuidData[i, 0], out cpuidData[i, 1],
    9.28            out cpuidData[i, 2], out cpuidData[i, 3], mask);
    9.29  
    9.30        cpuidExtData = new uint[maxCpuidExt + 1, 4];
    9.31        for (uint i = 0; i < (maxCpuidExt + 1); i++)
    9.32 -        WinRing0.CpuidTx(CPUID_EXT + i, 0, 
    9.33 +        Opcode.CpuidTx(CPUID_EXT + i, 0, 
    9.34            out cpuidExtData[i, 0], out cpuidExtData[i, 1], 
    9.35            out cpuidExtData[i, 2], out cpuidExtData[i, 3], mask);
    9.36  
    9.37        StringBuilder nameBuilder = new StringBuilder();
    9.38        for (uint i = 2; i <= 4; i++) {
    9.39 -        if (WinRing0.CpuidTx(CPUID_EXT + i, 0, 
    9.40 +        if (Opcode.CpuidTx(CPUID_EXT + i, 0, 
    9.41            out eax, out ebx, out ecx, out edx, mask)) 
    9.42          {
    9.43            AppendRegister(nameBuilder, eax);
    10.1 --- a/Hardware/CPU/GenericCPU.cs	Mon Oct 18 07:18:14 2010 +0000
    10.2 +++ b/Hardware/CPU/GenericCPU.cs	Sun Oct 31 22:08:47 2010 +0000
    10.3 @@ -39,6 +39,7 @@
    10.4  using System.Collections.Generic;
    10.5  using System.Diagnostics;
    10.6  using System.Globalization;
    10.7 +using System.Runtime.InteropServices;
    10.8  using System.Text;
    10.9  using System.Threading;
   10.10  
   10.11 @@ -55,6 +56,8 @@
   10.12      protected readonly int coreCount;
   10.13      protected readonly string name;
   10.14  
   10.15 +    private readonly bool hasModelSpecificRegisters;
   10.16 +
   10.17      private readonly bool hasTimeStampCounter;
   10.18      private readonly bool isInvariantTimeStampCounter;
   10.19      private readonly double estimatedTimeStampCounterFrequency;
   10.20 @@ -87,7 +90,14 @@
   10.21  
   10.22        this.processorIndex = processorIndex;
   10.23        this.coreCount = cpuid.Length;
   10.24 -      this.name = cpuid[0][0].Name;      
   10.25 +      this.name = cpuid[0][0].Name;    
   10.26 +  
   10.27 +      // check if processor has MSRs
   10.28 +      if (cpuid[0][0].Data.GetLength(0) > 1
   10.29 +        && (cpuid[0][0].Data[1, 3] & 0x20) != 0)
   10.30 +        hasModelSpecificRegisters = true;
   10.31 +      else
   10.32 +        hasModelSpecificRegisters = false;
   10.33  
   10.34        // check if processor has a TSC
   10.35        if (cpuid[0][0].Data.GetLength(0) > 1
   10.36 @@ -144,28 +154,26 @@
   10.37  
   10.38      private static double EstimateTimeStampCounterFrequency(double timeWindow) {
   10.39        long ticks = (long)(timeWindow * Stopwatch.Frequency);
   10.40 -      uint lsbBegin, msbBegin, lsbEnd, msbEnd;
   10.41 +      ulong countBegin, countEnd;
   10.42  
   10.43        Thread.BeginThreadAffinity();
   10.44        long timeBegin = Stopwatch.GetTimestamp() +
   10.45          (long)Math.Ceiling(0.001 * ticks);
   10.46        long timeEnd = timeBegin + ticks;
   10.47        while (Stopwatch.GetTimestamp() < timeBegin) { }
   10.48 -      WinRing0.Rdtsc(out lsbBegin, out msbBegin);
   10.49 +      countBegin = Opcode.Rdtsc();
   10.50        while (Stopwatch.GetTimestamp() < timeEnd) { }
   10.51 -      WinRing0.Rdtsc(out lsbEnd, out msbEnd);
   10.52 +      countEnd = Opcode.Rdtsc();
   10.53        Thread.EndThreadAffinity();
   10.54  
   10.55 -      ulong countBegin = ((ulong)msbBegin << 32) | lsbBegin;
   10.56 -      ulong countEnd = ((ulong)msbEnd << 32) | lsbEnd;
   10.57 -
   10.58        return (((double)(countEnd - countBegin)) * Stopwatch.Frequency) /
   10.59          (timeEnd - timeBegin);
   10.60      }
   10.61  
   10.62 +
   10.63      private static void AppendMSRData(StringBuilder r, uint msr, int thread) {
   10.64        uint eax, edx;
   10.65 -      if (WinRing0.RdmsrTx(msr, out eax, out edx, (UIntPtr)(1L << thread))) {
   10.66 +      if (Ring0.RdmsrTx(msr, out eax, out edx, (UIntPtr)(1L << thread))) {
   10.67          r.Append(" ");
   10.68          r.Append((msr).ToString("X8", CultureInfo.InvariantCulture));
   10.69          r.Append("  ");
   10.70 @@ -240,6 +248,10 @@
   10.71        get { return HardwareType.CPU; }
   10.72      }
   10.73  
   10.74 +    public bool HasModelSpecificRegisters {
   10.75 +      get { return hasModelSpecificRegisters; }
   10.76 +    }
   10.77 +
   10.78      public bool HasTimeStampCounter {
   10.79        get { return hasTimeStampCounter; }
   10.80      }
   10.81 @@ -250,14 +262,20 @@
   10.82  
   10.83      public override void Update() {
   10.84        if (hasTimeStampCounter && isInvariantTimeStampCounter) {
   10.85 -        uint lsb, msb;
   10.86 +
   10.87 +        // make sure always the same thread is used
   10.88 +        IntPtr thread = NativeMethods.GetCurrentThread();
   10.89 +        UIntPtr mask = NativeMethods.SetThreadAffinityMask(thread,
   10.90 +          (UIntPtr)(1L << cpuid[0][0].Thread));
   10.91  
   10.92          // read time before and after getting the TSC to estimate the error
   10.93          long firstTime = Stopwatch.GetTimestamp();
   10.94 -        WinRing0.RdtscTx(out lsb, out msb, (UIntPtr)1);
   10.95 +        ulong timeStampCount = Opcode.Rdtsc();
   10.96          long time = Stopwatch.GetTimestamp();
   10.97  
   10.98 -        ulong timeStampCount = ((ulong)msb << 32) | lsb;
   10.99 +        // restore the thread affinity mask
  10.100 +        NativeMethods.SetThreadAffinityMask(thread, mask);
  10.101 +
  10.102          double delta = ((double)(time - lastTime)) / Stopwatch.Frequency;
  10.103          double error = ((double)(time - firstTime)) / Stopwatch.Frequency;
  10.104  
  10.105 @@ -286,5 +304,16 @@
  10.106            totalLoad.Value = cpuLoad.GetTotalLoad();
  10.107        }
  10.108      }
  10.109 +
  10.110 +    private static class NativeMethods {
  10.111 +      private const string KERNEL = "kernel32.dll";
  10.112 +
  10.113 +      [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
  10.114 +      public static extern UIntPtr
  10.115 +        SetThreadAffinityMask(IntPtr handle, UIntPtr mask);
  10.116 +
  10.117 +      [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
  10.118 +      public static extern IntPtr GetCurrentThread();
  10.119 +    }
  10.120    }
  10.121  }
    11.1 --- a/Hardware/CPU/IntelCPU.cs	Mon Oct 18 07:18:14 2010 +0000
    11.2 +++ b/Hardware/CPU/IntelCPU.cs	Sun Oct 31 22:08:47 2010 +0000
    11.3 @@ -117,7 +117,7 @@
    11.4                  uint eax, edx;
    11.5                  tjMax = new float[coreCount];
    11.6                  for (int i = 0; i < coreCount; i++) {
    11.7 -                  if (WinRing0.RdmsrTx(IA32_TEMPERATURE_TARGET, out eax,
    11.8 +                  if (Ring0.RdmsrTx(IA32_TEMPERATURE_TARGET, out eax,
    11.9                      out edx, (UIntPtr)(1L << cpuid[i][0].Thread))) {
   11.10                      tjMax[i] = (eax >> 16) & 0xFF;
   11.11                    } else {
   11.12 @@ -142,14 +142,14 @@
   11.13          case Microarchitecture.Atom:
   11.14          case Microarchitecture.Core: {
   11.15              uint eax, edx;
   11.16 -            if (WinRing0.Rdmsr(IA32_PERF_STATUS, out eax, out edx)) {
   11.17 +            if (Ring0.Rdmsr(IA32_PERF_STATUS, out eax, out edx)) {
   11.18                timeStampCounterMultiplier = 
   11.19                  ((edx >> 8) & 0x1f) + 0.5 * ((edx >> 14) & 1);
   11.20              }
   11.21            } break;
   11.22          case Microarchitecture.Nehalem: {
   11.23              uint eax, edx;
   11.24 -            if (WinRing0.Rdmsr(MSR_PLATFORM_INFO, out eax, out edx)) {
   11.25 +            if (Ring0.Rdmsr(MSR_PLATFORM_INFO, out eax, out edx)) {
   11.26                timeStampCounterMultiplier = (eax >> 8) & 0xff;
   11.27              }
   11.28            } break;
   11.29 @@ -215,7 +215,7 @@
   11.30  
   11.31        for (int i = 0; i < coreTemperatures.Length; i++) {
   11.32          uint eax, edx;
   11.33 -        if (WinRing0.RdmsrTx(
   11.34 +        if (Ring0.RdmsrTx(
   11.35            IA32_THERM_STATUS_MSR, out eax, out edx,
   11.36              (UIntPtr)(1L << cpuid[i][0].Thread))) {
   11.37            // if reading is valid
   11.38 @@ -236,7 +236,7 @@
   11.39          uint eax, edx;
   11.40          for (int i = 0; i < coreClocks.Length; i++) {
   11.41            System.Threading.Thread.Sleep(1);
   11.42 -          if (WinRing0.RdmsrTx(IA32_PERF_STATUS, out eax, out edx,
   11.43 +          if (Ring0.RdmsrTx(IA32_PERF_STATUS, out eax, out edx,
   11.44              (UIntPtr)(1L << cpuid[i][0].Thread))) 
   11.45            {
   11.46              newBusClock = 
    12.1 --- a/Hardware/Computer.cs	Mon Oct 18 07:18:14 2010 +0000
    12.2 +++ b/Hardware/Computer.cs	Sun Oct 31 22:08:47 2010 +0000
    12.3 @@ -40,6 +40,7 @@
    12.4  using System.Globalization;
    12.5  using System.IO;
    12.6  using System.Security.Permissions;
    12.7 +using System.Reflection;
    12.8  
    12.9  namespace OpenHardwareMonitor.Hardware {
   12.10  
   12.11 @@ -86,7 +87,8 @@
   12.12        if (open)
   12.13          return;
   12.14  
   12.15 -      WinRing0.Open();
   12.16 +      Ring0.Open();
   12.17 +      Opcode.Open();
   12.18  
   12.19        Add(new Mainboard.MainboardGroup(settings));
   12.20        Add(new CPU.CPUGroup(settings));
   12.21 @@ -262,7 +264,8 @@
   12.22          group.Close();
   12.23        groups.Clear();
   12.24  
   12.25 -      WinRing0.Close();
   12.26 +      Opcode.Close();
   12.27 +      Ring0.Close();
   12.28  
   12.29        open = false;
   12.30      }
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/Hardware/IOControlCode.cs	Sun Oct 31 22:08:47 2010 +0000
    13.3 @@ -0,0 +1,70 @@
    13.4 +/*
    13.5 +  
    13.6 +  Version: MPL 1.1/GPL 2.0/LGPL 2.1
    13.7 +
    13.8 +  The contents of this file are subject to the Mozilla Public License Version
    13.9 +  1.1 (the "License"); you may not use this file except in compliance with
   13.10 +  the License. You may obtain a copy of the License at
   13.11 + 
   13.12 +  http://www.mozilla.org/MPL/
   13.13 +
   13.14 +  Software distributed under the License is distributed on an "AS IS" basis,
   13.15 +  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
   13.16 +  for the specific language governing rights and limitations under the License.
   13.17 +
   13.18 +  The Original Code is the Open Hardware Monitor code.
   13.19 +
   13.20 +  The Initial Developer of the Original Code is 
   13.21 +  Michael Möller <m.moeller@gmx.ch>.
   13.22 +  Portions created by the Initial Developer are Copyright (C) 2010
   13.23 +  the Initial Developer. All Rights Reserved.
   13.24 +
   13.25 +  Contributor(s):
   13.26 +
   13.27 +  Alternatively, the contents of this file may be used under the terms of
   13.28 +  either the GNU General Public License Version 2 or later (the "GPL"), or
   13.29 +  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
   13.30 +  in which case the provisions of the GPL or the LGPL are applicable instead
   13.31 +  of those above. If you wish to allow use of your version of this file only
   13.32 +  under the terms of either the GPL or the LGPL, and not to allow others to
   13.33 +  use your version of this file under the terms of the MPL, indicate your
   13.34 +  decision by deleting the provisions above and replace them with the notice
   13.35 +  and other provisions required by the GPL or the LGPL. If you do not delete
   13.36 +  the provisions above, a recipient may use your version of this file under
   13.37 +  the terms of any one of the MPL, the GPL or the LGPL.
   13.38 + 
   13.39 +*/
   13.40 +
   13.41 +using System;
   13.42 +using System.Runtime.InteropServices;
   13.43 +
   13.44 +namespace OpenHardwareMonitor.Hardware {
   13.45 +
   13.46 +  [StructLayout(LayoutKind.Sequential, Pack = 1)]
   13.47 +  internal struct IOControlCode {
   13.48 +    private uint code;
   13.49 +
   13.50 +    public IOControlCode(uint deviceType, uint function, Access access) :
   13.51 +      this(deviceType, function, Method.Buffered, access) { }
   13.52 +
   13.53 +    public IOControlCode(uint deviceType, uint function, Method method, 
   13.54 +      Access access) 
   13.55 +    {
   13.56 +      code = (deviceType << 16) | 
   13.57 +        ((uint)access << 14) | (function << 2) | (uint)method;
   13.58 +    }
   13.59 +
   13.60 +    public enum Method : uint {
   13.61 +      Buffered = 0,
   13.62 +      InDirect = 1,
   13.63 +      OutDirect = 2,
   13.64 +      Neither = 3
   13.65 +    }
   13.66 +
   13.67 +    public enum Access : uint {
   13.68 +      Any = 0,
   13.69 +      Read = 1,
   13.70 +      Write = 2
   13.71 +    }
   13.72 +  }    
   13.73 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/Hardware/KernelDriver.cs	Sun Oct 31 22:08:47 2010 +0000
    14.3 @@ -0,0 +1,300 @@
    14.4 +/*
    14.5 +  
    14.6 +  Version: MPL 1.1/GPL 2.0/LGPL 2.1
    14.7 +
    14.8 +  The contents of this file are subject to the Mozilla Public License Version
    14.9 +  1.1 (the "License"); you may not use this file except in compliance with
   14.10 +  the License. You may obtain a copy of the License at
   14.11 + 
   14.12 +  http://www.mozilla.org/MPL/
   14.13 +
   14.14 +  Software distributed under the License is distributed on an "AS IS" basis,
   14.15 +  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
   14.16 +  for the specific language governing rights and limitations under the License.
   14.17 +
   14.18 +  The Original Code is the Open Hardware Monitor code.
   14.19 +
   14.20 +  The Initial Developer of the Original Code is 
   14.21 +  Michael Möller <m.moeller@gmx.ch>.
   14.22 +  Portions created by the Initial Developer are Copyright (C) 2010
   14.23 +  the Initial Developer. All Rights Reserved.
   14.24 +
   14.25 +  Contributor(s):
   14.26 +
   14.27 +  Alternatively, the contents of this file may be used under the terms of
   14.28 +  either the GNU General Public License Version 2 or later (the "GPL"), or
   14.29 +  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
   14.30 +  in which case the provisions of the GPL or the LGPL are applicable instead
   14.31 +  of those above. If you wish to allow use of your version of this file only
   14.32 +  under the terms of either the GPL or the LGPL, and not to allow others to
   14.33 +  use your version of this file under the terms of the MPL, indicate your
   14.34 +  decision by deleting the provisions above and replace them with the notice
   14.35 +  and other provisions required by the GPL or the LGPL. If you do not delete
   14.36 +  the provisions above, a recipient may use your version of this file under
   14.37 +  the terms of any one of the MPL, the GPL or the LGPL.
   14.38 + 
   14.39 +*/
   14.40 +
   14.41 +using System;
   14.42 +using System.Runtime.InteropServices;
   14.43 +using Microsoft.Win32.SafeHandles;
   14.44 +
   14.45 +namespace OpenHardwareMonitor.Hardware {
   14.46 +  internal class KernelDriver {
   14.47 +
   14.48 +    private string id;
   14.49 +
   14.50 +    private SafeFileHandle device; 
   14.51 +    
   14.52 +    public KernelDriver(string id) {
   14.53 +      this.id = id;
   14.54 +    }
   14.55 +   
   14.56 +    public bool Install(string path) {
   14.57 +      IntPtr manager = NativeMethods.OpenSCManager(null, null,
   14.58 +        ServiceControlManagerAccessRights.SC_MANAGER_ALL_ACCESS);
   14.59 +
   14.60 +      if (manager == IntPtr.Zero)
   14.61 +        return false;
   14.62 +
   14.63 +      IntPtr service = NativeMethods.CreateService(manager, id, id,
   14.64 +        ServiceAccessRights.SERVICE_ALL_ACCESS,
   14.65 +        ServiceType.SERVICE_KERNEL_DRIVER, StartType.SERVICE_DEMAND_START,
   14.66 +        ErrorControl.SERVICE_ERROR_NORMAL, path, null, null, null, null,
   14.67 +        null);
   14.68 +
   14.69 +      if (service == IntPtr.Zero) {
   14.70 +        if (Marshal.GetHRForLastWin32Error() == ERROR_SERVICE_EXISTS)
   14.71 +          service = NativeMethods.OpenService(manager, id,
   14.72 +            ServiceAccessRights.SERVICE_ALL_ACCESS);
   14.73 +        else
   14.74 +          return false;
   14.75 +      }
   14.76 +
   14.77 +      if (!NativeMethods.StartService(service, 0, null)) {
   14.78 +        if (Marshal.GetHRForLastWin32Error() != ERROR_SERVICE_ALREADY_RUNNING)
   14.79 +          return false;
   14.80 +      }
   14.81 +
   14.82 +      NativeMethods.CloseServiceHandle(service);
   14.83 +      NativeMethods.CloseServiceHandle(manager);
   14.84 +
   14.85 +      return true;
   14.86 +    }
   14.87 +
   14.88 +    public bool Open() {
   14.89 +      device = new SafeFileHandle(NativeMethods.CreateFile(@"\\.\" + id,
   14.90 +        FileAccess.GENERIC_READ | FileAccess.GENERIC_WRITE, 0, IntPtr.Zero,
   14.91 +        CreationDisposition.OPEN_EXISTING, FileAttributes.FILE_ATTRIBUTE_NORMAL,
   14.92 +        IntPtr.Zero), true);
   14.93 +
   14.94 +      if (device.IsInvalid) {
   14.95 +        device.Close();
   14.96 +        device.Dispose();
   14.97 +        device = null;
   14.98 +      }
   14.99 +
  14.100 +      return device != null;
  14.101 +    }
  14.102 +
  14.103 +    public bool IsOpen {
  14.104 +      get { return device != null; }
  14.105 +    }
  14.106 +
  14.107 +    public bool DeviceIOControl(IOControlCode ioControlCode, object inBuffer) {
  14.108 +      if (device == null)
  14.109 +        return false;
  14.110 +
  14.111 +      uint bytesReturned;
  14.112 +      bool b = NativeMethods.DeviceIoControl(device, ioControlCode,
  14.113 +        inBuffer, inBuffer == null ? 0 : (uint)Marshal.SizeOf(inBuffer),
  14.114 +        null, 0, out bytesReturned, IntPtr.Zero);
  14.115 +      return b;
  14.116 +    }
  14.117 +
  14.118 +    public bool DeviceIOControl<T>(IOControlCode ioControlCode, object inBuffer, 
  14.119 +      ref T outBuffer) 
  14.120 +    {
  14.121 +      if (device == null)
  14.122 +        return false;
  14.123 +
  14.124 +      object boxedOutBuffer = outBuffer;
  14.125 +      uint bytesReturned;
  14.126 +      bool b = NativeMethods.DeviceIoControl(device, ioControlCode,
  14.127 +        inBuffer, inBuffer == null ? 0 : (uint)Marshal.SizeOf(inBuffer),
  14.128 +        boxedOutBuffer, (uint)Marshal.SizeOf(boxedOutBuffer),
  14.129 +        out bytesReturned, IntPtr.Zero);
  14.130 +      outBuffer = (T)boxedOutBuffer;
  14.131 +      return b;
  14.132 +    }
  14.133 +
  14.134 +    public void Close() {
  14.135 +      if (device != null) {
  14.136 +        device.Close();
  14.137 +        device.Dispose();
  14.138 +        device = null;
  14.139 +      }
  14.140 +    }
  14.141 +
  14.142 +    public bool Delete() {
  14.143 +      IntPtr manager = NativeMethods.OpenSCManager(null, null,
  14.144 +      ServiceControlManagerAccessRights.SC_MANAGER_ALL_ACCESS);
  14.145 +
  14.146 +      if (manager == IntPtr.Zero)
  14.147 +        return false;      
  14.148 +
  14.149 +      IntPtr service = NativeMethods.OpenService(manager, id,
  14.150 +        ServiceAccessRights.SERVICE_ALL_ACCESS);
  14.151 +
  14.152 +      if (service == IntPtr.Zero)
  14.153 +        return true;
  14.154 +
  14.155 +      ServiceStatus status = new ServiceStatus();
  14.156 +      NativeMethods.ControlService(service, ServiceControl.SERVICE_CONTROL_STOP, 
  14.157 +        ref status);
  14.158 +
  14.159 +      NativeMethods.DeleteService(service);
  14.160 +
  14.161 +      NativeMethods.CloseServiceHandle(service);
  14.162 +      NativeMethods.CloseServiceHandle(manager);
  14.163 +      
  14.164 +      return true;
  14.165 +    }
  14.166 +
  14.167 +    private enum ServiceAccessRights : uint {
  14.168 +      SERVICE_ALL_ACCESS = 0xF01FF
  14.169 +    }
  14.170 +
  14.171 +    private enum ServiceControlManagerAccessRights : uint {
  14.172 +      SC_MANAGER_ALL_ACCESS = 0xF003F
  14.173 +    }
  14.174 +
  14.175 +    private enum ServiceType : uint {
  14.176 +      SERVICE_KERNEL_DRIVER = 1,
  14.177 +      SERVICE_FILE_SYSTEM_DRIVER = 2
  14.178 +    }
  14.179 +
  14.180 +    private enum StartType : uint {
  14.181 +      SERVICE_BOOT_START = 0,
  14.182 +      SERVICE_SYSTEM_START = 1,
  14.183 +      SERVICE_AUTO_START = 2,
  14.184 +      SERVICE_DEMAND_START = 3,
  14.185 +      SERVICE_DISABLED = 4
  14.186 +    }
  14.187 +
  14.188 +    private enum ErrorControl : uint {
  14.189 +      SERVICE_ERROR_IGNORE = 0,
  14.190 +      SERVICE_ERROR_NORMAL = 1,
  14.191 +      SERVICE_ERROR_SEVERE = 2,
  14.192 +      SERVICE_ERROR_CRITICAL = 3
  14.193 +    }
  14.194 +
  14.195 +    private enum ServiceControl : uint {
  14.196 +      SERVICE_CONTROL_STOP = 1,
  14.197 +      SERVICE_CONTROL_PAUSE = 2,
  14.198 +      SERVICE_CONTROL_CONTINUE = 3,
  14.199 +      SERVICE_CONTROL_INTERROGATE = 4,
  14.200 +      SERVICE_CONTROL_SHUTDOWN = 5,
  14.201 +      SERVICE_CONTROL_PARAMCHANGE = 6,
  14.202 +      SERVICE_CONTROL_NETBINDADD = 7,
  14.203 +      SERVICE_CONTROL_NETBINDREMOVE = 8,
  14.204 +      SERVICE_CONTROL_NETBINDENABLE = 9,
  14.205 +      SERVICE_CONTROL_NETBINDDISABLE = 10,
  14.206 +      SERVICE_CONTROL_DEVICEEVENT = 11,
  14.207 +      SERVICE_CONTROL_HARDWAREPROFILECHANGE = 12,
  14.208 +      SERVICE_CONTROL_POWEREVENT = 13,
  14.209 +      SERVICE_CONTROL_SESSIONCHANGE = 14
  14.210 +    }
  14.211 +
  14.212 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  14.213 +    private struct ServiceStatus {
  14.214 +      public uint dwServiceType;
  14.215 +      public uint dwCurrentState;
  14.216 +      public uint dwControlsAccepted;
  14.217 +      public uint dwWin32ExitCode;
  14.218 +      public uint dwServiceSpecificExitCode;
  14.219 +      public uint dwCheckPoint;
  14.220 +      public uint dwWaitHint;
  14.221 +    }
  14.222 +
  14.223 +    private enum FileAccess : uint {
  14.224 +      GENERIC_READ = 0x80000000,
  14.225 +      GENERIC_WRITE = 0x40000000
  14.226 +    }
  14.227 +
  14.228 +    private enum CreationDisposition : uint {
  14.229 +      CREATE_NEW = 1,
  14.230 +      CREATE_ALWAYS = 2,
  14.231 +      OPEN_EXISTING = 3,
  14.232 +      OPEN_ALWAYS = 4,
  14.233 +      TRUNCATE_EXISTING = 5
  14.234 +    }
  14.235 +
  14.236 +    private enum FileAttributes : uint {
  14.237 +      FILE_ATTRIBUTE_NORMAL = 0x80
  14.238 +    }
  14.239 +
  14.240 +    private const int
  14.241 +      ERROR_SERVICE_EXISTS = unchecked((int)0x80070431),
  14.242 +      ERROR_SERVICE_ALREADY_RUNNING = unchecked((int)0x80070420);
  14.243 +
  14.244 +    private static class NativeMethods {
  14.245 +      private const string ADVAPI = "advapi32.dll";
  14.246 +      private const string KERNEL = "kernel32.dll";
  14.247 +
  14.248 +      [DllImport(ADVAPI, CallingConvention = CallingConvention.Winapi)]
  14.249 +      public static extern IntPtr OpenSCManager(string machineName,
  14.250 +        string databaseName, ServiceControlManagerAccessRights dwAccess);
  14.251 +
  14.252 +      [DllImport(ADVAPI, CallingConvention = CallingConvention.Winapi)]
  14.253 +      [return: MarshalAs(UnmanagedType.Bool)]
  14.254 +      public static extern bool CloseServiceHandle(IntPtr hSCObject);
  14.255 +
  14.256 +      [DllImport(ADVAPI, CallingConvention = CallingConvention.Winapi,
  14.257 +        SetLastError = true)]
  14.258 +      public static extern IntPtr CreateService(IntPtr hSCManager,
  14.259 +        string lpServiceName, string lpDisplayName, 
  14.260 +        ServiceAccessRights dwDesiredAccess, ServiceType dwServiceType,
  14.261 +        StartType dwStartType, ErrorControl dwErrorControl,
  14.262 +        string lpBinaryPathName, string lpLoadOrderGroup, string lpdwTagId,
  14.263 +        string lpDependencies, string lpServiceStartName, string lpPassword);
  14.264 +
  14.265 +      [DllImport(ADVAPI, CallingConvention = CallingConvention.Winapi,
  14.266 +        SetLastError = true)]
  14.267 +      public static extern IntPtr OpenService(IntPtr hSCManager,
  14.268 +        string lpServiceName, ServiceAccessRights dwDesiredAccess);
  14.269 +
  14.270 +      [DllImport(ADVAPI, CallingConvention = CallingConvention.Winapi,
  14.271 +        SetLastError = true)]
  14.272 +      [return: MarshalAs(UnmanagedType.Bool)]
  14.273 +      public static extern bool DeleteService(IntPtr hService);
  14.274 +
  14.275 +      [DllImport(ADVAPI, CallingConvention = CallingConvention.Winapi,
  14.276 +        SetLastError = true)]
  14.277 +      [return: MarshalAs(UnmanagedType.Bool)]
  14.278 +      public static extern bool StartService(IntPtr hService, 
  14.279 +        uint dwNumServiceArgs, string[] lpServiceArgVectors);
  14.280 +
  14.281 +      [DllImport(ADVAPI, CallingConvention = CallingConvention.Winapi,
  14.282 +        SetLastError = true)]
  14.283 +      [return: MarshalAs(UnmanagedType.Bool)]
  14.284 +      public static extern bool ControlService(IntPtr hService,
  14.285 +        ServiceControl dwControl, ref ServiceStatus lpServiceStatus);
  14.286 +
  14.287 +      [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
  14.288 +      public static extern bool DeviceIoControl(SafeFileHandle device,
  14.289 +        IOControlCode ioControlCode, 
  14.290 +        [MarshalAs(UnmanagedType.AsAny)] [In] object inBuffer, 
  14.291 +        uint inBufferSize,
  14.292 +        [MarshalAs(UnmanagedType.AsAny)] [Out] object outBuffer,
  14.293 +        uint nOutBufferSize, out uint bytesReturned, IntPtr overlapped);
  14.294 +
  14.295 +      [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi, 
  14.296 +        SetLastError = true)]
  14.297 +      public static extern IntPtr CreateFile(string lpFileName,
  14.298 +        FileAccess dwDesiredAccess, uint dwShareMode, 
  14.299 +        IntPtr lpSecurityAttributes, CreationDisposition dwCreationDisposition, 
  14.300 +        FileAttributes dwFlagsAndAttributes, IntPtr hTemplateFile);
  14.301 +    }
  14.302 +  }
  14.303 +}
    15.1 --- a/Hardware/LPC/F718XX.cs	Mon Oct 18 07:18:14 2010 +0000
    15.2 +++ b/Hardware/LPC/F718XX.cs	Sun Oct 31 22:08:47 2010 +0000
    15.3 @@ -60,9 +60,9 @@
    15.4        new byte[] { 0xA0, 0xB0, 0xC0, 0xD0 };
    15.5      
    15.6      private byte ReadByte(byte register) {
    15.7 -      WinRing0.WriteIoPortByte(
    15.8 +      Ring0.WriteIoPort(
    15.9          (ushort)(address + ADDRESS_REGISTER_OFFSET), register);
   15.10 -      return WinRing0.ReadIoPortByte((ushort)(address + DATA_REGISTER_OFFSET));
   15.11 +      return Ring0.ReadIoPort((ushort)(address + DATA_REGISTER_OFFSET));
   15.12      }
   15.13  
   15.14      public byte? ReadGPIO(int index) {
   15.15 @@ -94,7 +94,7 @@
   15.16        r.AppendLine(address.ToString("X4", CultureInfo.InvariantCulture));
   15.17        r.AppendLine();
   15.18  
   15.19 -      if (!WinRing0.WaitIsaBusMutex(100))
   15.20 +      if (!Ring0.WaitIsaBusMutex(100))
   15.21          return r.ToString();
   15.22  
   15.23        r.AppendLine("Hardware Monitor Registers");
   15.24 @@ -114,13 +114,13 @@
   15.25        }
   15.26        r.AppendLine();
   15.27  
   15.28 -      WinRing0.ReleaseIsaBusMutex();
   15.29 +      Ring0.ReleaseIsaBusMutex();
   15.30  
   15.31        return r.ToString();
   15.32      }
   15.33  
   15.34      public void Update() {
   15.35 -      if (!WinRing0.WaitIsaBusMutex(10))
   15.36 +      if (!Ring0.WaitIsaBusMutex(10))
   15.37          return;
   15.38  
   15.39        for (int i = 0; i < voltages.Length; i++) {
   15.40 @@ -173,7 +173,7 @@
   15.41            fans[i] = null;        
   15.42        }
   15.43  
   15.44 -      WinRing0.ReleaseIsaBusMutex();
   15.45 +      Ring0.ReleaseIsaBusMutex();
   15.46      }
   15.47    }
   15.48  }
    16.1 --- a/Hardware/LPC/IT87XX.cs	Mon Oct 18 07:18:14 2010 +0000
    16.2 +++ b/Hardware/LPC/IT87XX.cs	Sun Oct 31 22:08:47 2010 +0000
    16.3 @@ -76,9 +76,9 @@
    16.4      private const byte VOLTAGE_BASE_REG = 0x20;
    16.5  
    16.6      private byte ReadByte(byte register, out bool valid) {
    16.7 -      WinRing0.WriteIoPortByte(addressReg, register);
    16.8 -      byte value = WinRing0.ReadIoPortByte(dataReg);
    16.9 -      valid = register == WinRing0.ReadIoPortByte(addressReg);
   16.10 +      Ring0.WriteIoPort(addressReg, register);
   16.11 +      byte value = Ring0.ReadIoPort(dataReg);
   16.12 +      valid = register == Ring0.ReadIoPort(addressReg);
   16.13        return value;
   16.14      }
   16.15  
   16.16 @@ -86,14 +86,14 @@
   16.17        if (index >= gpioCount)
   16.18          return null;
   16.19  
   16.20 -      return WinRing0.ReadIoPortByte((ushort)(gpioAddress + index));
   16.21 +      return Ring0.ReadIoPort((ushort)(gpioAddress + index));
   16.22      }
   16.23  
   16.24      public void WriteGPIO(int index, byte value) {
   16.25        if (index >= gpioCount)
   16.26          return;
   16.27  
   16.28 -      WinRing0.WriteIoPortByte((ushort)(gpioAddress + index), value);
   16.29 +      Ring0.WriteIoPort((ushort)(gpioAddress + index), value);
   16.30      }
   16.31  
   16.32      public IT87XX(Chip chip, ushort address, ushort gpioAddress, byte version) {
   16.33 @@ -162,7 +162,7 @@
   16.34          gpioAddress.ToString("X4", CultureInfo.InvariantCulture));
   16.35        r.AppendLine();
   16.36  
   16.37 -      if (!WinRing0.WaitIsaBusMutex(100))
   16.38 +      if (!Ring0.WaitIsaBusMutex(100))
   16.39          return r.ToString();
   16.40  
   16.41        r.AppendLine("Environment Controller Registers");
   16.42 @@ -194,13 +194,13 @@
   16.43        r.AppendLine();
   16.44        r.AppendLine();
   16.45  
   16.46 -      WinRing0.ReleaseIsaBusMutex();
   16.47 +      Ring0.ReleaseIsaBusMutex();
   16.48  
   16.49        return r.ToString();
   16.50      }
   16.51  
   16.52      public void Update() {
   16.53 -      if (!WinRing0.WaitIsaBusMutex(10))
   16.54 +      if (!Ring0.WaitIsaBusMutex(10))
   16.55          return;
   16.56  
   16.57        for (int i = 0; i < voltages.Length; i++) {
   16.58 @@ -246,7 +246,7 @@
   16.59          }
   16.60        }
   16.61  
   16.62 -      WinRing0.ReleaseIsaBusMutex();
   16.63 +      Ring0.ReleaseIsaBusMutex();
   16.64      }
   16.65    } 
   16.66  }
    17.1 --- a/Hardware/LPC/LPCIO.cs	Mon Oct 18 07:18:14 2010 +0000
    17.2 +++ b/Hardware/LPC/LPCIO.cs	Sun Oct 31 22:08:47 2010 +0000
    17.3 @@ -62,8 +62,8 @@
    17.4      private const byte BASE_ADDRESS_REGISTER = 0x60;
    17.5  
    17.6      private byte ReadByte(byte register) {
    17.7 -      WinRing0.WriteIoPortByte(registerPort, register);
    17.8 -      return WinRing0.ReadIoPortByte(valuePort);
    17.9 +      Ring0.WriteIoPort(registerPort, register);
   17.10 +      return Ring0.ReadIoPort(valuePort);
   17.11      }
   17.12  
   17.13      private ushort ReadWord(byte register) {
   17.14 @@ -72,8 +72,8 @@
   17.15      }
   17.16  
   17.17      private void Select(byte logicalDeviceNumber) {
   17.18 -      WinRing0.WriteIoPortByte(registerPort, DEVCIE_SELECT_REGISTER);
   17.19 -      WinRing0.WriteIoPortByte(valuePort, logicalDeviceNumber);
   17.20 +      Ring0.WriteIoPort(registerPort, DEVCIE_SELECT_REGISTER);
   17.21 +      Ring0.WriteIoPort(valuePort, logicalDeviceNumber);
   17.22      }
   17.23  
   17.24      private void ReportUnknownChip(string type, int chip) {
   17.25 @@ -99,12 +99,12 @@
   17.26      private const byte FINTEK_HARDWARE_MONITOR_LDN = 0x04;
   17.27  
   17.28      private void WinbondFintekEnter() {
   17.29 -      WinRing0.WriteIoPortByte(registerPort, 0x87);
   17.30 -      WinRing0.WriteIoPortByte(registerPort, 0x87);
   17.31 +      Ring0.WriteIoPort(registerPort, 0x87);
   17.32 +      Ring0.WriteIoPort(registerPort, 0x87);
   17.33      }
   17.34  
   17.35      private void WinbondFintekExit() {
   17.36 -      WinRing0.WriteIoPortByte(registerPort, 0xAA);
   17.37 +      Ring0.WriteIoPort(registerPort, 0xAA);
   17.38      }
   17.39  
   17.40      private bool DetectWinbondFintek() {
   17.41 @@ -308,15 +308,15 @@
   17.42      private const byte IT87_CHIP_VERSION_REGISTER = 0x22;
   17.43  
   17.44      private void IT87Enter() {
   17.45 -      WinRing0.WriteIoPortByte(registerPort, 0x87);
   17.46 -      WinRing0.WriteIoPortByte(registerPort, 0x01);
   17.47 -      WinRing0.WriteIoPortByte(registerPort, 0x55);
   17.48 -      WinRing0.WriteIoPortByte(registerPort, 0x55);
   17.49 +      Ring0.WriteIoPort(registerPort, 0x87);
   17.50 +      Ring0.WriteIoPort(registerPort, 0x01);
   17.51 +      Ring0.WriteIoPort(registerPort, 0x55);
   17.52 +      Ring0.WriteIoPort(registerPort, 0x55);
   17.53      }
   17.54  
   17.55      private void IT87Exit() {
   17.56 -      WinRing0.WriteIoPortByte(registerPort, CONFIGURATION_CONTROL_REGISTER);
   17.57 -      WinRing0.WriteIoPortByte(valuePort, 0x02);
   17.58 +      Ring0.WriteIoPort(registerPort, CONFIGURATION_CONTROL_REGISTER);
   17.59 +      Ring0.WriteIoPort(valuePort, 0x02);
   17.60      }
   17.61  
   17.62      private bool DetectIT87() {
   17.63 @@ -392,11 +392,11 @@
   17.64      #region SMSC
   17.65  
   17.66      private void SMSCEnter() {
   17.67 -      WinRing0.WriteIoPortByte(registerPort, 0x55);
   17.68 +      Ring0.WriteIoPort(registerPort, 0x55);
   17.69      }
   17.70  
   17.71      private void SMSCExit() {
   17.72 -      WinRing0.WriteIoPortByte(registerPort, 0xAA);
   17.73 +      Ring0.WriteIoPort(registerPort, 0xAA);
   17.74      }
   17.75  
   17.76      private bool DetectSMSC() {
   17.77 @@ -438,15 +438,15 @@
   17.78      }
   17.79  
   17.80      public LPCIO() {
   17.81 -      if (!WinRing0.IsAvailable)
   17.82 +      if (!Ring0.IsOpen)
   17.83          return;
   17.84  
   17.85 -      if (!WinRing0.WaitIsaBusMutex(100))
   17.86 +      if (!Ring0.WaitIsaBusMutex(100))
   17.87          return;
   17.88  
   17.89        Detect();
   17.90  
   17.91 -      WinRing0.ReleaseIsaBusMutex();
   17.92 +      Ring0.ReleaseIsaBusMutex();
   17.93      }
   17.94  
   17.95      public ISuperIO[] SuperIO {
    18.1 --- a/Hardware/LPC/W836XX.cs	Mon Oct 18 07:18:14 2010 +0000
    18.2 +++ b/Hardware/LPC/W836XX.cs	Sun Oct 31 22:08:47 2010 +0000
    18.3 @@ -84,24 +84,24 @@
    18.4      private readonly byte[] FAN_DIV_BIT2 = new byte[] { 5, 6, 7, 23, 15 };
    18.5  
    18.6      private byte ReadByte(byte bank, byte register) {
    18.7 -      WinRing0.WriteIoPortByte(
    18.8 +      Ring0.WriteIoPort(
    18.9           (ushort)(address + ADDRESS_REGISTER_OFFSET), BANK_SELECT_REGISTER);
   18.10 -      WinRing0.WriteIoPortByte(
   18.11 +      Ring0.WriteIoPort(
   18.12           (ushort)(address + DATA_REGISTER_OFFSET), bank);
   18.13 -      WinRing0.WriteIoPortByte(
   18.14 +      Ring0.WriteIoPort(
   18.15           (ushort)(address + ADDRESS_REGISTER_OFFSET), register);
   18.16 -      return WinRing0.ReadIoPortByte(
   18.17 +      return Ring0.ReadIoPort(
   18.18          (ushort)(address + DATA_REGISTER_OFFSET));
   18.19      } 
   18.20  
   18.21      private void WriteByte(byte bank, byte register, byte value) {
   18.22 -      WinRing0.WriteIoPortByte(
   18.23 +      Ring0.WriteIoPort(
   18.24           (ushort)(address + ADDRESS_REGISTER_OFFSET), BANK_SELECT_REGISTER);
   18.25 -      WinRing0.WriteIoPortByte(
   18.26 +      Ring0.WriteIoPort(
   18.27           (ushort)(address + DATA_REGISTER_OFFSET), bank);
   18.28 -      WinRing0.WriteIoPortByte(
   18.29 +      Ring0.WriteIoPort(
   18.30           (ushort)(address + ADDRESS_REGISTER_OFFSET), register);
   18.31 -      WinRing0.WriteIoPortByte(
   18.32 +      Ring0.WriteIoPort(
   18.33           (ushort)(address + DATA_REGISTER_OFFSET), value); 
   18.34      }
   18.35  
   18.36 @@ -203,7 +203,7 @@
   18.37      public float?[] Fans { get { return fans; } }
   18.38  
   18.39      public void Update() {
   18.40 -      if (!WinRing0.WaitIsaBusMutex(10))
   18.41 +      if (!Ring0.WaitIsaBusMutex(10))
   18.42          return;
   18.43  
   18.44        for (int i = 0; i < voltages.Length; i++) {
   18.45 @@ -291,7 +291,7 @@
   18.46            WriteByte(0, FAN_BIT_REG[i], newByte);        
   18.47        }
   18.48  
   18.49 -      WinRing0.ReleaseIsaBusMutex();
   18.50 +      Ring0.ReleaseIsaBusMutex();
   18.51      }
   18.52  
   18.53      public string GetReport() {
   18.54 @@ -306,7 +306,7 @@
   18.55        r.AppendLine(address.ToString("X4", CultureInfo.InvariantCulture));
   18.56        r.AppendLine();
   18.57  
   18.58 -      if (!WinRing0.WaitIsaBusMutex(100))
   18.59 +      if (!Ring0.WaitIsaBusMutex(100))
   18.60          return r.ToString();
   18.61  
   18.62        r.AppendLine("Hardware Monitor Registers");
   18.63 @@ -340,7 +340,7 @@
   18.64        }
   18.65        r.AppendLine();
   18.66  
   18.67 -      WinRing0.ReleaseIsaBusMutex();
   18.68 +      Ring0.ReleaseIsaBusMutex();
   18.69  
   18.70        return r.ToString();
   18.71      }
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/Hardware/Opcode.cs	Sun Oct 31 22:08:47 2010 +0000
    19.3 @@ -0,0 +1,244 @@
    19.4 +/*
    19.5 +  
    19.6 +  Version: MPL 1.1/GPL 2.0/LGPL 2.1
    19.7 +
    19.8 +  The contents of this file are subject to the Mozilla Public License Version
    19.9 +  1.1 (the "License"); you may not use this file except in compliance with
   19.10 +  the License. You may obtain a copy of the License at
   19.11 + 
   19.12 +  http://www.mozilla.org/MPL/
   19.13 +
   19.14 +  Software distributed under the License is distributed on an "AS IS" basis,
   19.15 +  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
   19.16 +  for the specific language governing rights and limitations under the License.
   19.17 +
   19.18 +  The Original Code is the Open Hardware Monitor code.
   19.19 +
   19.20 +  The Initial Developer of the Original Code is 
   19.21 +  Michael Möller <m.moeller@gmx.ch>.
   19.22 +  Portions created by the Initial Developer are Copyright (C) 2010
   19.23 +  the Initial Developer. All Rights Reserved.
   19.24 +
   19.25 +  Contributor(s):
   19.26 +
   19.27 +  Alternatively, the contents of this file may be used under the terms of
   19.28 +  either the GNU General Public License Version 2 or later (the "GPL"), or
   19.29 +  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
   19.30 +  in which case the provisions of the GPL or the LGPL are applicable instead
   19.31 +  of those above. If you wish to allow use of your version of this file only
   19.32 +  under the terms of either the GPL or the LGPL, and not to allow others to
   19.33 +  use your version of this file under the terms of the MPL, indicate your
   19.34 +  decision by deleting the provisions above and replace them with the notice
   19.35 +  and other provisions required by the GPL or the LGPL. If you do not delete
   19.36 +  the provisions above, a recipient may use your version of this file under
   19.37 +  the terms of any one of the MPL, the GPL or the LGPL.
   19.38 + 
   19.39 +*/
   19.40 +
   19.41 +using System;
   19.42 +using System.Runtime.InteropServices;
   19.43 +
   19.44 +namespace OpenHardwareMonitor.Hardware {
   19.45 +  internal static class Opcode {
   19.46 +    private static IntPtr codeBuffer;
   19.47 +
   19.48 +    public static void Open() {
   19.49 +      // No implementation for Unix systems
   19.50 +      int p = (int)Environment.OSVersion.Platform;
   19.51 +      if ((p == 4) || (p == 128))
   19.52 +        return;  
   19.53 +
   19.54 +      byte[] rdtscCode;
   19.55 +      byte[] cpuidCode;
   19.56 +      if (IntPtr.Size == 4) {
   19.57 +        rdtscCode = RDTSC_32;
   19.58 +        cpuidCode = CPUID_32;
   19.59 +      } else {
   19.60 +        rdtscCode = RDTSC_64;
   19.61 +        cpuidCode = CPUID_64;
   19.62 +      }
   19.63 +
   19.64 +      codeBuffer = NativeMethods.VirtualAlloc(IntPtr.Zero,
   19.65 +        (UIntPtr)(rdtscCode.Length + cpuidCode.Length),
   19.66 +      AllocationType.COMMIT | AllocationType.RESERVE, 
   19.67 +      MemoryProtection.EXECUTE_READWRITE);
   19.68 +
   19.69 +      Marshal.Copy(rdtscCode, 0, codeBuffer, rdtscCode.Length);
   19.70 +
   19.71 +      Rdtsc = Marshal.GetDelegateForFunctionPointer(
   19.72 +        codeBuffer, typeof(RdtscDelegate)) as RdtscDelegate;
   19.73 +
   19.74 +      IntPtr cpuidAddress = (IntPtr)((long)codeBuffer + rdtscCode.Length);
   19.75 +      Marshal.Copy(cpuidCode, 0, cpuidAddress, cpuidCode.Length);
   19.76 +
   19.77 +      Cpuid = Marshal.GetDelegateForFunctionPointer(
   19.78 +        cpuidAddress, typeof(CpuidDelegate)) as CpuidDelegate;
   19.79 +    }
   19.80 +
   19.81 +    public static void Close() {
   19.82 +      Rdtsc = null;
   19.83 +      Cpuid = null;
   19.84 +
   19.85 +      NativeMethods.VirtualFree(codeBuffer, UIntPtr.Zero, 
   19.86 +        FreeType.RELEASE);
   19.87 +    }
   19.88 +
   19.89 +    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
   19.90 +    public delegate ulong RdtscDelegate();
   19.91 +
   19.92 +    public static RdtscDelegate Rdtsc;
   19.93 +
   19.94 +    // unsigned __int64 __stdcall rdtsc() {
   19.95 +    //   return __rdtsc();
   19.96 +    // }
   19.97 +
   19.98 +    private static readonly byte[] RDTSC_32 = new byte[] {
   19.99 +      0x0F, 0x31,                     // rdtsc   
  19.100 +      0xC3                            // ret  
  19.101 +    };
  19.102 +
  19.103 +    private static readonly byte[] RDTSC_64 = new byte[] {
  19.104 +      0x0F, 0x31,                     // rdtsc  
  19.105 +      0x48, 0xC1, 0xE2, 0x20,         // shl rdx,20h  
  19.106 +      0x48, 0x0B, 0xC2,               // or rax,rdx  
  19.107 +      0xC3                            // ret  
  19.108 +    };
  19.109 +    
  19.110 +    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
  19.111 +    public delegate bool CpuidDelegate(uint index, uint ecxValue,
  19.112 +      out uint eax, out uint ebx, out uint ecx, out uint edx);
  19.113 +
  19.114 +    public static CpuidDelegate Cpuid;
  19.115 +
  19.116 +
  19.117 +    // void __stdcall cpuidex(unsigned int index, unsigned int ecxValue, 
  19.118 +    //   unsigned int* eax, unsigned int* ebx, unsigned int* ecx, 
  19.119 +    //   unsigned int* edx)
  19.120 +    // {
  19.121 +    //   int info[4];	
  19.122 +    //   __cpuidex(info, index, ecxValue);
  19.123 +    //   *eax = info[0];
  19.124 +    //   *ebx = info[1];
  19.125 +    //   *ecx = info[2];
  19.126 +    //   *edx = info[3];
  19.127 +    // }
  19.128 +
  19.129 +    private static readonly byte[] CPUID_32 = new byte[] {
  19.130 +      0x55,                           // push ebp  
  19.131 +      0x8B, 0xEC,                      // mov ebp,esp  
  19.132 +      0x83, 0xEC, 0x10,               // sub esp,10h  
  19.133 +      0x8B, 0x45, 0x08,               // mov eax,dword ptr [ebp+8]  
  19.134 +      0x8B, 0x4D, 0x0C,               // mov ecx,dword ptr [ebp+0Ch]  
  19.135 +      0x53,                           // push ebx  
  19.136 +      0x0F, 0xA2,                     // cpuid  
  19.137 +      0x56,                           // push esi  
  19.138 +      0x8D, 0x75, 0xF0,               // lea esi,[info]  
  19.139 +      0x89, 0x06,                      // mov dword ptr [esi],eax  
  19.140 +      0x8B, 0x45, 0x10,               // mov eax,dword ptr [eax]  
  19.141 +      0x89, 0x5E, 0x04,               // mov dword ptr [esi+4],ebx  
  19.142 +      0x89, 0x4E, 0x08,               // mov dword ptr [esi+8],ecx  
  19.143 +      0x89, 0x56, 0x0C,               // mov dword ptr [esi+0Ch],edx  
  19.144 +      0x8B, 0x4D, 0xF0,               // mov ecx,dword ptr [info]  
  19.145 +      0x89, 0x08,                      // mov dword ptr [eax],ecx  
  19.146 +      0x8B, 0x45, 0x14,               // mov eax,dword ptr [ebx]  
  19.147 +      0x8B, 0x4D, 0xF4,               // mov ecx,dword ptr [ebp-0Ch]  
  19.148 +      0x89, 0x08,                      // mov dword ptr [eax],ecx  
  19.149 +      0x8B, 0x45, 0x18,               // mov eax,dword ptr [ecx]  
  19.150 +      0x8B, 0x4D, 0xF8,               // mov ecx,dword ptr [ebp-8]  
  19.151 +      0x89, 0x08,                      // mov dword ptr [eax],ecx  
  19.152 +      0x8B, 0x45, 0x1C,               // mov eax,dword ptr [edx]  
  19.153 +      0x8B, 0x4D, 0xFC,               // mov ecx,dword ptr [ebp-4]  
  19.154 +      0x5E,                           // pop esi  
  19.155 +      0x89, 0x08,                     // mov dword ptr [eax],ecx  
  19.156 +      0x5B,                           // pop ebx  
  19.157 +      0xC9,                           // leave  
  19.158 +      0xC2, 0x18, 0x00                // ret 18h  
  19.159 +    };
  19.160 +             
  19.161 +    private static readonly byte[] CPUID_64 = new byte[] {
  19.162 +      0x48, 0x89, 0x5C, 0x24, 0x08,   // mov qword ptr [rsp+8],rbx  
  19.163 +      0x8B, 0xC1,                     // mov eax,ecx  
  19.164 +      0x8B, 0xCA,                     // mov ecx,edx  
  19.165 +      0x0F, 0xA2,                     // cpuid  
  19.166 +      0x41, 0x89, 0x00,               // mov dword ptr [r8],eax  
  19.167 +      0x48, 0x8B, 0x44, 0x24, 0x28,   // mov rax,qword ptr [ecx]  
  19.168 +      0x41, 0x89, 0x19,               // mov dword ptr [r9],ebx  
  19.169 +      0x48, 0x8B, 0x5C, 0x24, 0x08,   // mov rbx,qword ptr [rsp+8]  
  19.170 +      0x89, 0x08,                     // mov dword ptr [rax],ecx  
  19.171 +      0x48, 0x8B, 0x44, 0x24, 0x30,   // mov rax,qword ptr [rsp+30h]  
  19.172 +      0x89, 0x10,                     // mov dword ptr [rax],edx  
  19.173 +      0xC3                            // ret  
  19.174 +    };
  19.175 +
  19.176 +    public static bool CpuidTx(uint index, uint ecxValue, 
  19.177 +      out uint eax, out uint ebx, out uint ecx, out uint edx, 
  19.178 +      UIntPtr threadAffinityMask) {
  19.179 +
  19.180 +      IntPtr thread = NativeMethods.GetCurrentThread();
  19.181 +      UIntPtr mask = NativeMethods.SetThreadAffinityMask(thread, 
  19.182 +        threadAffinityMask);
  19.183 +
  19.184 +      if (mask == UIntPtr.Zero) {
  19.185 +        eax = ebx = ecx = edx = 0;
  19.186 +        return false;
  19.187 +      }
  19.188 +
  19.189 +      Cpuid(index, ecxValue, out eax, out ebx, out ecx, out edx);
  19.190 +
  19.191 +      NativeMethods.SetThreadAffinityMask(thread, mask);
  19.192 +      
  19.193 +      return true;
  19.194 +    }
  19.195 +
  19.196 +    [Flags()]
  19.197 +    public enum AllocationType : uint {
  19.198 +      COMMIT = 0x1000,
  19.199 +      RESERVE = 0x2000,
  19.200 +      RESET = 0x80000,
  19.201 +      LARGE_PAGES = 0x20000000,
  19.202 +      PHYSICAL = 0x400000,
  19.203 +      TOP_DOWN = 0x100000,
  19.204 +      WRITE_WATCH = 0x200000
  19.205 +    }
  19.206 +
  19.207 +    [Flags()]
  19.208 +    public enum MemoryProtection : uint {
  19.209 +      EXECUTE = 0x10,
  19.210 +      EXECUTE_READ = 0x20,
  19.211 +      EXECUTE_READWRITE = 0x40,
  19.212 +      EXECUTE_WRITECOPY = 0x80,
  19.213 +      NOACCESS = 0x01,
  19.214 +      READONLY = 0x02,
  19.215 +      READWRITE = 0x04,
  19.216 +      WRITECOPY = 0x08,
  19.217 +      GUARD = 0x100,
  19.218 +      NOCACHE = 0x200,
  19.219 +      WRITECOMBINE = 0x400
  19.220 +    }
  19.221 +
  19.222 +    [Flags]
  19.223 +    enum FreeType {
  19.224 +      DECOMMIT = 0x4000,
  19.225 +      RELEASE = 0x8000
  19.226 +    }
  19.227 +
  19.228 +    private static class NativeMethods {
  19.229 +      private const string KERNEL = "kernel32.dll";
  19.230 +
  19.231 +      [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
  19.232 +      public static extern IntPtr VirtualAlloc(IntPtr lpAddress, UIntPtr dwSize,
  19.233 +        AllocationType flAllocationType, MemoryProtection flProtect);
  19.234 +
  19.235 +      [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
  19.236 +      public static extern bool VirtualFree(IntPtr lpAddress, UIntPtr dwSize,
  19.237 +        FreeType dwFreeType);
  19.238 +
  19.239 +      [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
  19.240 +      public static extern UIntPtr
  19.241 +        SetThreadAffinityMask(IntPtr handle, UIntPtr mask);
  19.242 +
  19.243 +      [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
  19.244 +      public static extern IntPtr GetCurrentThread();
  19.245 +    }
  19.246 +  }
  19.247 +}
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/Hardware/Ring0.cs	Sun Oct 31 22:08:47 2010 +0000
    20.3 @@ -0,0 +1,291 @@
    20.4 +/*
    20.5 +  
    20.6 +  Version: MPL 1.1/GPL 2.0/LGPL 2.1
    20.7 +
    20.8 +  The contents of this file are subject to the Mozilla Public License Version
    20.9 +  1.1 (the "License"); you may not use this file except in compliance with
   20.10 +  the License. You may obtain a copy of the License at
   20.11 + 
   20.12 +  http://www.mozilla.org/MPL/
   20.13 +
   20.14 +  Software distributed under the License is distributed on an "AS IS" basis,
   20.15 +  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
   20.16 +  for the specific language governing rights and limitations under the License.
   20.17 +
   20.18 +  The Original Code is the Open Hardware Monitor code.
   20.19 +
   20.20 +  The Initial Developer of the Original Code is 
   20.21 +  Michael Möller <m.moeller@gmx.ch>.
   20.22 +  Portions created by the Initial Developer are Copyright (C) 2010
   20.23 +  the Initial Developer. All Rights Reserved.
   20.24 +
   20.25 +  Contributor(s):
   20.26 +
   20.27 +  Alternatively, the contents of this file may be used under the terms of
   20.28 +  either the GNU General Public License Version 2 or later (the "GPL"), or
   20.29 +  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
   20.30 +  in which case the provisions of the GPL or the LGPL are applicable instead
   20.31 +  of those above. If you wish to allow use of your version of this file only
   20.32 +  under the terms of either the GPL or the LGPL, and not to allow others to
   20.33 +  use your version of this file under the terms of the MPL, indicate your
   20.34 +  decision by deleting the provisions above and replace them with the notice
   20.35 +  and other provisions required by the GPL or the LGPL. If you do not delete
   20.36 +  the provisions above, a recipient may use your version of this file under
   20.37 +  the terms of any one of the MPL, the GPL or the LGPL.
   20.38 + 
   20.39 +*/
   20.40 +
   20.41 +using System;
   20.42 +using System.IO;
   20.43 +using System.Reflection;
   20.44 +using System.Runtime.InteropServices;
   20.45 +using System.Threading;
   20.46 +
   20.47 +namespace OpenHardwareMonitor.Hardware {
   20.48 +  internal static class Ring0 {
   20.49 +
   20.50 +    private static KernelDriver driver;
   20.51 +    private static Mutex isaBusMutex;
   20.52 +
   20.53 +    private const uint OLS_TYPE = 40000;
   20.54 +    private static IOControlCode
   20.55 +      IOCTL_OLS_GET_REFCOUNT = new IOControlCode(OLS_TYPE, 0x801,
   20.56 +        IOControlCode.Access.Any),
   20.57 +      IOCTL_OLS_GET_DRIVER_VERSION = new IOControlCode(OLS_TYPE, 0x800,
   20.58 +        IOControlCode.Access.Any),
   20.59 +      IOCTL_OLS_READ_MSR = new IOControlCode(OLS_TYPE, 0x821,
   20.60 +        IOControlCode.Access.Any),
   20.61 +      IOCTL_OLS_WRITE_MSR = new IOControlCode(OLS_TYPE, 0x822, 
   20.62 +        IOControlCode.Access.Any),
   20.63 +      IOCTL_OLS_READ_IO_PORT_BYTE = new IOControlCode(OLS_TYPE, 0x833,
   20.64 +        IOControlCode.Access.Read),
   20.65 +      IOCTL_OLS_WRITE_IO_PORT_BYTE = new IOControlCode(OLS_TYPE, 0x836, 
   20.66 +        IOControlCode.Access.Write),
   20.67 +      IOCTL_OLS_READ_PCI_CONFIG = new IOControlCode(OLS_TYPE, 0x851, 
   20.68 +        IOControlCode.Access.Read),
   20.69 +      IOCTL_OLS_WRITE_PCI_CONFIG = new IOControlCode(OLS_TYPE, 0x852,
   20.70 +        IOControlCode.Access.Write);
   20.71 +
   20.72 +    private static bool ExtractDriver(string fileName) {
   20.73 +      string resourceName = "OpenHardwareMonitor.Hardware." +
   20.74 +        (IntPtr.Size == 4 ? "WinRing0.sys" : "WinRing0x64.sys");
   20.75 +
   20.76 +      string[] names =
   20.77 +        Assembly.GetExecutingAssembly().GetManifestResourceNames();
   20.78 +      byte[] buffer = null;
   20.79 +      for (int i = 0; i < names.Length; i++) {
   20.80 +        if (names[i].Replace('\\', '.') == resourceName) {
   20.81 +          using (Stream stream = Assembly.GetExecutingAssembly().
   20.82 +            GetManifestResourceStream(names[i])) 
   20.83 +          {
   20.84 +              buffer = new byte[stream.Length];
   20.85 +              stream.Read(buffer, 0, buffer.Length);
   20.86 +          }
   20.87 +        }
   20.88 +      }
   20.89 +
   20.90 +      if (buffer == null)
   20.91 +        return false;
   20.92 +
   20.93 +      using (FileStream target = new FileStream(fileName, FileMode.Create)) {
   20.94 +        target.Write(buffer, 0, buffer.Length);
   20.95 +      }
   20.96 +
   20.97 +      return true;
   20.98 +    }
   20.99 +
  20.100 +    public static void Open() {
  20.101 +      if (driver != null)
  20.102 +        return;
  20.103 +     
  20.104 +      driver = new KernelDriver("WinRing0_1_2_0");
  20.105 +      driver.Open();
  20.106 +
  20.107 +      if (!driver.IsOpen) {
  20.108 +        string fileName = Path.GetTempFileName();
  20.109 +        if (ExtractDriver(fileName)) {
  20.110 +
  20.111 +          driver.Install(fileName);
  20.112 +          File.Delete(fileName);
  20.113 +
  20.114 +          driver.Open();
  20.115 +
  20.116 +          if (!driver.IsOpen)
  20.117 +            driver.Delete();
  20.118 +        }
  20.119 +      }
  20.120 +
  20.121 +      if (!driver.IsOpen) 
  20.122 +        driver = null;
  20.123 +
  20.124 +      isaBusMutex = new Mutex(false, "Access_ISABUS.HTP.Method");
  20.125 +    }
  20.126 +
  20.127 +    public static bool IsOpen {
  20.128 +      get { return driver != null; }
  20.129 +    }
  20.130 +
  20.131 +    public static void Close() {
  20.132 +      if (driver == null)
  20.133 +        return;
  20.134 +
  20.135 +      uint refCount = 0;
  20.136 +      driver.DeviceIOControl(IOCTL_OLS_GET_REFCOUNT, null, ref refCount);
  20.137 +
  20.138 +      driver.Close();
  20.139 +
  20.140 +      if (refCount <= 1)
  20.141 +        driver.Delete();
  20.142 +
  20.143 +      driver = null;
  20.144 +
  20.145 +      isaBusMutex.Close(); 
  20.146 +    }
  20.147 +
  20.148 +    public static bool WaitIsaBusMutex(int millisecondsTimeout) {
  20.149 +      try {
  20.150 +        return isaBusMutex.WaitOne(millisecondsTimeout, false);
  20.151 +      } catch (AbandonedMutexException) { return false; } 
  20.152 +        catch (InvalidOperationException) { return false; }
  20.153 +    }
  20.154 +
  20.155 +    public static void ReleaseIsaBusMutex() {
  20.156 +      isaBusMutex.ReleaseMutex();
  20.157 +    }
  20.158 +
  20.159 +    public static bool Rdmsr(uint index, out uint eax, out uint edx) {
  20.160 +      if (driver == null) {
  20.161 +        eax = 0;
  20.162 +        edx = 0;
  20.163 +        return false;
  20.164 +      }
  20.165 +
  20.166 +      ulong buffer = 0;
  20.167 +      bool result = driver.DeviceIOControl(IOCTL_OLS_READ_MSR, index,
  20.168 +        ref buffer);
  20.169 +
  20.170 +      edx = (uint)((buffer >> 32) & 0xFFFFFFFF);
  20.171 +      eax = (uint)(buffer & 0xFFFFFFFF);
  20.172 +      return result;
  20.173 +    }
  20.174 +
  20.175 +    public static bool RdmsrTx(uint index, out uint eax, out uint edx,
  20.176 +      UIntPtr threadAffinityMask) 
  20.177 +    {
  20.178 +      IntPtr thread = NativeMethods.GetCurrentThread();
  20.179 +      UIntPtr mask = NativeMethods.SetThreadAffinityMask(thread, 
  20.180 +        threadAffinityMask);
  20.181 +
  20.182 +      bool result = Rdmsr(index, out eax, out edx);
  20.183 +
  20.184 +      NativeMethods.SetThreadAffinityMask(thread, mask);
  20.185 +      return result;
  20.186 +    }
  20.187 +
  20.188 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  20.189 +    private struct WrmsrInput {
  20.190 +      public uint Register;
  20.191 +      public ulong Value;
  20.192 +    }
  20.193 +
  20.194 +    public static bool Wrmsr(uint index, uint eax, uint edx) {
  20.195 +      if (driver == null)
  20.196 +        return false;
  20.197 +
  20.198 +      WrmsrInput input = new WrmsrInput();
  20.199 +      input.Register = index;
  20.200 +      input.Value = ((ulong)edx << 32) | eax;
  20.201 +
  20.202 +      return driver.DeviceIOControl(IOCTL_OLS_WRITE_MSR, input);
  20.203 +    }
  20.204 +
  20.205 +    public static byte ReadIoPort(uint port) {
  20.206 +      if (driver == null)
  20.207 +        return 0;
  20.208 +
  20.209 +      uint value = 0;
  20.210 +      driver.DeviceIOControl(IOCTL_OLS_READ_IO_PORT_BYTE, port, ref value);
  20.211 +
  20.212 +      return (byte)(value & 0xFF);
  20.213 +    }
  20.214 +
  20.215 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  20.216 +    private struct WriteIoPortInput {
  20.217 +      public uint PortNumber;
  20.218 +      public byte Value;
  20.219 +    }
  20.220 +
  20.221 +    public static void WriteIoPort(uint port, byte value) {
  20.222 +      if (driver == null)
  20.223 +        return;
  20.224 +
  20.225 +      WriteIoPortInput input = new WriteIoPortInput();
  20.226 +      input.PortNumber = port;
  20.227 +      input.Value = value;
  20.228 +
  20.229 +      driver.DeviceIOControl(IOCTL_OLS_WRITE_IO_PORT_BYTE, input);
  20.230 +    }
  20.231 +
  20.232 +    public const uint InvalidPciAddress = 0xFFFFFFFF;
  20.233 +
  20.234 +    public static uint GetPciAddress(byte bus, byte device, byte function) {
  20.235 +      return
  20.236 +        (uint)(((bus & 0xFF) << 8) | ((device & 0x1F) << 3) | (function & 7));
  20.237 +    }
  20.238 +
  20.239 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  20.240 +    private struct ReadPciConfigInput {
  20.241 +      public uint PciAddress;
  20.242 +      public uint RegAddress;
  20.243 +    }
  20.244 +
  20.245 +    public static bool ReadPciConfig(uint pciAddress, uint regAddress, 
  20.246 +      out uint value) 
  20.247 +    {
  20.248 +      if (driver == null || (regAddress & 3) != 0) {
  20.249 +        value = 0;
  20.250 +        return false;
  20.251 +      }
  20.252 +
  20.253 +      ReadPciConfigInput input = new ReadPciConfigInput();
  20.254 +      input.PciAddress = pciAddress;
  20.255 +      input.RegAddress = regAddress;
  20.256 +
  20.257 +      value = 0;
  20.258 +      return driver.DeviceIOControl(IOCTL_OLS_READ_PCI_CONFIG, input, 
  20.259 +        ref value);
  20.260 +    }
  20.261 +
  20.262 +    [StructLayout(LayoutKind.Sequential, Pack = 1)]
  20.263 +    private struct WritePciConfigInput {
  20.264 +      public uint PciAddress;
  20.265 +      public uint RegAddress;
  20.266 +      public uint Value;
  20.267 +    }
  20.268 +
  20.269 +    public static bool WritePciConfig(uint pciAddress, uint regAddress, 
  20.270 +      uint value) 
  20.271 +    {
  20.272 +      if (driver == null || (regAddress & 3) != 0)
  20.273 +        return false;
  20.274 +
  20.275 +      WritePciConfigInput input = new WritePciConfigInput();
  20.276 +      input.PciAddress = pciAddress;
  20.277 +      input.RegAddress = regAddress;
  20.278 +      input.Value = value;
  20.279 +
  20.280 +      return driver.DeviceIOControl(IOCTL_OLS_WRITE_PCI_CONFIG, input);
  20.281 +    }
  20.282 +
  20.283 +    private static class NativeMethods {
  20.284 +      private const string KERNEL = "kernel32.dll";
  20.285 +
  20.286 +      [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
  20.287 +      public static extern UIntPtr
  20.288 +        SetThreadAffinityMask(IntPtr handle, UIntPtr mask);
  20.289 +
  20.290 +      [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
  20.291 +      public static extern IntPtr GetCurrentThread();
  20.292 +    }
  20.293 +  }
  20.294 +}
    21.1 --- a/Hardware/WinRing0.cs	Mon Oct 18 07:18:14 2010 +0000
    21.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.3 @@ -1,179 +0,0 @@
    21.4 -/*
    21.5 -  
    21.6 -  Version: MPL 1.1/GPL 2.0/LGPL 2.1
    21.7 -
    21.8 -  The contents of this file are subject to the Mozilla Public License Version
    21.9 -  1.1 (the "License"); you may not use this file except in compliance with
   21.10 -  the License. You may obtain a copy of the License at
   21.11 - 
   21.12 -  http://www.mozilla.org/MPL/
   21.13 -
   21.14 -  Software distributed under the License is distributed on an "AS IS" basis,
   21.15 -  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
   21.16 -  for the specific language governing rights and limitations under the License.
   21.17 -
   21.18 -  The Original Code is the Open Hardware Monitor code.
   21.19 -
   21.20 -  The Initial Developer of the Original Code is 
   21.21 -  Michael Möller <m.moeller@gmx.ch>.
   21.22 -  Portions created by the Initial Developer are Copyright (C) 2009-2010
   21.23 -  the Initial Developer. All Rights Reserved.
   21.24 -
   21.25 -  Contributor(s):
   21.26 -
   21.27 -  Alternatively, the contents of this file may be used under the terms of
   21.28 -  either the GNU General Public License Version 2 or later (the "GPL"), or
   21.29 -  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
   21.30 -  in which case the provisions of the GPL or the LGPL are applicable instead
   21.31 -  of those above. If you wish to allow use of your version of this file only
   21.32 -  under the terms of either the GPL or the LGPL, and not to allow others to
   21.33 -  use your version of this file under the terms of the MPL, indicate your
   21.34 -  decision by deleting the provisions above and replace them with the notice
   21.35 -  and other provisions required by the GPL or the LGPL. If you do not delete
   21.36 -  the provisions above, a recipient may use your version of this file under
   21.37 -  the terms of any one of the MPL, the GPL or the LGPL.
   21.38 - 
   21.39 -*/
   21.40 -
   21.41 -using System;
   21.42 -using System.Runtime.InteropServices;
   21.43 -using System.Threading;
   21.44 -
   21.45 -namespace OpenHardwareMonitor.Hardware {
   21.46 -
   21.47 -  internal class WinRing0 {
   21.48 -
   21.49 -    private WinRing0() { }
   21.50 -    
   21.51 -    public enum OlsDllStatus{
   21.52 -      OLS_DLL_NO_ERROR                        = 0,
   21.53 -      OLS_DLL_UNSUPPORTED_PLATFORM            = 1,
   21.54 -      OLS_DLL_DRIVER_NOT_LOADED               = 2,
   21.55 -      OLS_DLL_DRIVER_NOT_FOUND                = 3,
   21.56 -      OLS_DLL_DRIVER_UNLOADED                 = 4,
   21.57 -      OLS_DLL_DRIVER_NOT_LOADED_ON_NETWORK    = 5,
   21.58 -      OLS_DLL_UNKNOWN_ERROR                   = 9
   21.59 -    }
   21.60 -
   21.61 -    private static bool available;
   21.62 -    private static Mutex isaBusMutex;
   21.63 -
   21.64 -    private static string GetDllName() {   
   21.65 -      int p = (int)Environment.OSVersion.Platform;
   21.66 -      if ((p == 4) || (p == 128)) {
   21.67 -        if (IntPtr.Size == 4) {
   21.68 -          return "libring0.so";
   21.69 -        } else {
   21.70 -          return "libring0x64.so";
   21.71 -        }
   21.72 -      } else {
   21.73 -        if (IntPtr.Size == 4) {
   21.74 -          return "WinRing0.dll";
   21.75 -        } else {
   21.76 -          return "WinRing0x64.dll";
   21.77 -        }
   21.78 -      }                       
   21.79 -    }
   21.80 -    
   21.81 -    private delegate bool InitializeOlsDelegate();
   21.82 -    private delegate void DeinitializeOlsDelegate();
   21.83 -    
   21.84 -    public delegate bool IsCpuidDelegate();
   21.85 -    public delegate bool CpuidTxDelegate(uint index, uint ecxValue,
   21.86 -      out uint eax, out uint ebx, out uint ecx, out uint edx,
   21.87 -      UIntPtr threadAffinityMask);
   21.88 -    public delegate bool RdmsrDelegate(uint index, out uint eax, out uint edx);
   21.89 -    public delegate bool RdmsrTxDelegate(uint index, out uint eax, out uint edx,
   21.90 -      UIntPtr threadAffinityMask);
   21.91 -    public delegate byte ReadIoPortByteDelegate(ushort port);
   21.92 -    public delegate void WriteIoPortByteDelegate(ushort port, byte value);
   21.93 -    public delegate bool ReadPciConfigDwordExDelegate(uint pciAddress, 
   21.94 -      uint regAddress, out uint value);
   21.95 -    public delegate bool WritePciConfigDwordExDelegate(uint pciAddress, 
   21.96 -      uint regAddress, uint value);    
   21.97 -    public delegate bool RdtscDelegate(out uint eax, out uint edx);
   21.98 -    public delegate bool RdtscTxDelegate(out uint eax, out uint edx,
   21.99 -      UIntPtr threadAffinityMask);    
  21.100 -    public delegate bool WrmsrDelegate(uint index, uint eax, uint edx);
  21.101 -    public delegate bool WrmsrTxDelegate(uint index, uint eax, uint edx,
  21.102 -      UIntPtr threadAffinityMask);
  21.103 -
  21.104 -    private static readonly InitializeOlsDelegate InitializeOls = 
  21.105 -      CreateDelegate<InitializeOlsDelegate>("InitializeOls");
  21.106 -    private static readonly DeinitializeOlsDelegate DeinitializeOls =
  21.107 -      CreateDelegate<DeinitializeOlsDelegate>("DeinitializeOls");
  21.108 -
  21.109 -    public static readonly IsCpuidDelegate IsCpuid =
  21.110 -      CreateDelegate<IsCpuidDelegate>("IsCpuid");
  21.111 -    public static readonly CpuidTxDelegate CpuidTx =
  21.112 -      CreateDelegate<CpuidTxDelegate>("CpuidTx");
  21.113 -    public static readonly RdmsrDelegate Rdmsr =
  21.114 -      CreateDelegate<RdmsrDelegate>("Rdmsr");
  21.115 -    public static readonly RdmsrTxDelegate RdmsrTx =
  21.116 -      CreateDelegate<RdmsrTxDelegate>("RdmsrTx");
  21.117 -    public static readonly ReadIoPortByteDelegate ReadIoPortByte =
  21.118 -      CreateDelegate<ReadIoPortByteDelegate>("ReadIoPortByte");
  21.119 -    public static readonly WriteIoPortByteDelegate WriteIoPortByte =
  21.120 -      CreateDelegate<WriteIoPortByteDelegate>("WriteIoPortByte");
  21.121 -    public static readonly ReadPciConfigDwordExDelegate ReadPciConfigDwordEx =
  21.122 -      CreateDelegate<ReadPciConfigDwordExDelegate>("ReadPciConfigDwordEx");
  21.123 -    public static readonly WritePciConfigDwordExDelegate WritePciConfigDwordEx =
  21.124 -      CreateDelegate<WritePciConfigDwordExDelegate>("WritePciConfigDwordEx");
  21.125 -    public static readonly RdtscDelegate Rdtsc =
  21.126 -      CreateDelegate<RdtscDelegate>("Rdtsc");
  21.127 -    public static readonly RdtscTxDelegate RdtscTx =
  21.128 -      CreateDelegate<RdtscTxDelegate>("RdtscTx");    
  21.129 -    public static readonly WrmsrDelegate Wrmsr =
  21.130 -      CreateDelegate<WrmsrDelegate>("Wrmsr");
  21.131 -    public static readonly WrmsrTxDelegate WrmsrTx =
  21.132 -      CreateDelegate<WrmsrTxDelegate>("WrmsrTx");
  21.133 - 
  21.134 -    private static T CreateDelegate<T>(string entryPoint) where T : class {
  21.135 -      DllImportAttribute attribute = new DllImportAttribute(GetDllName());
  21.136 -      attribute.CallingConvention = CallingConvention.Winapi;
  21.137 -      attribute.PreserveSig = true;
  21.138 -      attribute.EntryPoint = entryPoint;
  21.139 -      attribute.CharSet = CharSet.Auto;
  21.140 -      T result;
  21.141 -      PInvokeDelegateFactory.CreateDelegate(attribute, out result);
  21.142 -      return result;
  21.143 -    }
  21.144 -
  21.145 -    public static void Open() {
  21.146 -      try {
  21.147 -        if (InitializeOls != null && InitializeOls())
  21.148 -          available = true;
  21.149 -      } catch (DllNotFoundException) { }   
  21.150 -      
  21.151 -      isaBusMutex = new Mutex(false, "Access_ISABUS.HTP.Method");
  21.152 -    }
  21.153 -
  21.154 -    public static bool IsAvailable {
  21.155 -      get { return available; }
  21.156 -    }
  21.157 -
  21.158 -    public static void Close() {
  21.159 -      if (available)
  21.160 -        DeinitializeOls();        
  21.161 -      isaBusMutex.Close();      
  21.162 -    }    
  21.163 -
  21.164 -    public static bool WaitIsaBusMutex(int millisecondsTimeout) {
  21.165 -      try {
  21.166 -        return isaBusMutex.WaitOne(millisecondsTimeout, false);
  21.167 -      } catch (AbandonedMutexException) { return false; } 
  21.168 -        catch (InvalidOperationException) { return false; }     
  21.169 -    }
  21.170 -
  21.171 -    public static void ReleaseIsaBusMutex() {
  21.172 -      isaBusMutex.ReleaseMutex();
  21.173 -    }
  21.174 -
  21.175 -    public const uint InvalidPciAddress = 0xFFFFFFFF;
  21.176 -
  21.177 -    public static uint GetPciAddress(byte bus, byte device, byte function)	{
  21.178 -      return 
  21.179 -        (uint)(((bus & 0xFF) << 8) | ((device & 0x1F) << 3) | (function & 7));
  21.180 -    }
  21.181 -  }
  21.182 -}
    22.1 Binary file Hardware/WinRing0.sys has changed
    23.1 Binary file Hardware/WinRing0x64.sys has changed
    24.1 --- a/OpenHardwareMonitorLib.csproj	Mon Oct 18 07:18:14 2010 +0000
    24.2 +++ b/OpenHardwareMonitorLib.csproj	Sun Oct 31 22:08:47 2010 +0000
    24.3 @@ -60,6 +60,7 @@
    24.4      <Compile Include="Hardware\ATI\ADL.cs" />
    24.5      <Compile Include="Hardware\ATI\ATIGPU.cs" />
    24.6      <Compile Include="Hardware\ATI\ATIGroup.cs" />
    24.7 +    <Compile Include="Hardware\IOControlCode.cs" />
    24.8      <Compile Include="Hardware\Computer.cs" />
    24.9      <Compile Include="Hardware\CPU\AMDCPU.cs" />
   24.10      <Compile Include="Hardware\CPU\GenericCPU.cs" />
   24.11 @@ -69,6 +70,9 @@
   24.12      <Compile Include="Hardware\CPU\CPUID.cs" />
   24.13      <Compile Include="Hardware\CPU\CPULoad.cs" />
   24.14      <Compile Include="Hardware\CPU\IntelCPU.cs" />
   24.15 +    <Compile Include="Hardware\Opcode.cs" />
   24.16 +    <Compile Include="Hardware\Ring0.cs" />
   24.17 +    <Compile Include="Hardware\KernelDriver.cs" />
   24.18      <Compile Include="Hardware\Hardware.cs" />
   24.19      <Compile Include="Hardware\HDD\HDD.cs" />
   24.20      <Compile Include="Hardware\HDD\HDDGroup.cs" />
   24.21 @@ -105,7 +109,6 @@
   24.22      <Compile Include="Hardware\TBalancer\FTD2XX.cs" />
   24.23      <Compile Include="Hardware\TBalancer\TBalancer.cs" />
   24.24      <Compile Include="Hardware\TBalancer\TBalancerGroup.cs" />
   24.25 -    <Compile Include="Hardware\WinRing0.cs" />
   24.26      <Compile Include="Hardware\ISettings.cs" />
   24.27      <Compile Include="Hardware\HexStringArray.cs" />
   24.28      <Compile Include="Collections\IReadOnlyArray.cs" />
   24.29 @@ -132,7 +135,10 @@
   24.30        <Install>true</Install>
   24.31      </BootstrapperPackage>
   24.32    </ItemGroup>
   24.33 -  <ItemGroup />
   24.34 +  <ItemGroup>
   24.35 +    <EmbeddedResource Include="Hardware\WinRing0.sys" />
   24.36 +    <EmbeddedResource Include="Hardware\WinRing0x64.sys" />
   24.37 +  </ItemGroup>
   24.38    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   24.39    <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
   24.40         Other similar extension points exist, see Microsoft.Common.targets.
    25.1 --- a/Program.cs	Mon Oct 18 07:18:14 2010 +0000
    25.2 +++ b/Program.cs	Sun Oct 31 22:08:47 2010 +0000
    25.3 @@ -87,17 +87,6 @@
    25.4        if (!IsFileAvailable("Aga.Controls.dll"))
    25.5          return false;
    25.6  
    25.7 -      if (IntPtr.Size == 4) {
    25.8 -        if (!IsFileAvailable("WinRing0.dll"))
    25.9 -          return false;
   25.10 -        if (!IsFileAvailable("WinRing0.sys"))
   25.11 -          return false;
   25.12 -      } else {
   25.13 -        if (!IsFileAvailable("WinRing0x64.dll"))
   25.14 -          return false;
   25.15 -        if (!IsFileAvailable("WinRing0x64.sys"))
   25.16 -          return false;
   25.17 -      }
   25.18        return true;
   25.19      }
   25.20