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.
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