moel@1: /*
moel@1:   
moel@1:   Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@1: 
moel@1:   The contents of this file are subject to the Mozilla Public License Version
moel@1:   1.1 (the "License"); you may not use this file except in compliance with
moel@1:   the License. You may obtain a copy of the License at
moel@1:  
moel@1:   http://www.mozilla.org/MPL/
moel@1: 
moel@1:   Software distributed under the License is distributed on an "AS IS" basis,
moel@1:   WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@1:   for the specific language governing rights and limitations under the License.
moel@1: 
moel@1:   The Original Code is the Open Hardware Monitor code.
moel@1: 
moel@1:   The Initial Developer of the Original Code is 
moel@1:   Michael Möller <m.moeller@gmx.ch>.
moel@1:   Portions created by the Initial Developer are Copyright (C) 2009-2010
moel@1:   the Initial Developer. All Rights Reserved.
moel@1: 
moel@1:   Contributor(s):
moel@1: 
moel@1:   Alternatively, the contents of this file may be used under the terms of
moel@1:   either the GNU General Public License Version 2 or later (the "GPL"), or
moel@1:   the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@1:   in which case the provisions of the GPL or the LGPL are applicable instead
moel@1:   of those above. If you wish to allow use of your version of this file only
moel@1:   under the terms of either the GPL or the LGPL, and not to allow others to
moel@1:   use your version of this file under the terms of the MPL, indicate your
moel@1:   decision by deleting the provisions above and replace them with the notice
moel@1:   and other provisions required by the GPL or the LGPL. If you do not delete
moel@1:   the provisions above, a recipient may use your version of this file under
moel@1:   the terms of any one of the MPL, the GPL or the LGPL.
moel@1:  
moel@1: */
moel@1: 
moel@1: using System;
moel@1: using System.Collections.Generic;
moel@1: using System.IO;
moel@1: using System.Runtime.InteropServices;
moel@1: using System.Text;
moel@1: 
moel@1: namespace OpenHardwareMonitor.Hardware {
moel@1: 
moel@1:   public class WinRing0 {
moel@1:     
moel@1:     public enum OlsDllStatus{
moel@1:       OLS_DLL_NO_ERROR                        = 0,
moel@1:       OLS_DLL_UNSUPPORTED_PLATFORM            = 1,
moel@1:       OLS_DLL_DRIVER_NOT_LOADED               = 2,
moel@1:       OLS_DLL_DRIVER_NOT_FOUND                = 3,
moel@1:       OLS_DLL_DRIVER_UNLOADED                 = 4,
moel@1:       OLS_DLL_DRIVER_NOT_LOADED_ON_NETWORK    = 5,
moel@1:       OLS_DLL_UNKNOWN_ERROR                   = 9
moel@1:     }
moel@1: 
moel@1:     private static bool available = false;
moel@1: 
moel@1:     private static string GetDllName() {   
moel@1:       int p = (int)System.Environment.OSVersion.Platform;
moel@1:       if ((p == 4) || (p == 128)) {
moel@1:         if (IntPtr.Size == 4) {
moel@1:           return "libring0.so";
moel@1:         } else {
moel@1:           return "libring0x64.so";
moel@1:         }
moel@1:       } else {
moel@1:         if (IntPtr.Size == 4) {
moel@1:           return "WinRing0.dll";
moel@1:         } else {
moel@1:           return "WinRing0x64.dll";
moel@1:         }
moel@1:       }                       
moel@1:     }
moel@1:     
moel@1:     private delegate bool InitializeOlsDelegate();
moel@1:     private delegate void DeinitializeOlsDelegate();
moel@1:     
moel@1:     public delegate uint GetDllStatusDelegate();
moel@1:     public delegate bool IsCpuidDelegate();
moel@22:     public delegate bool CpuidDelegate(uint index, 
moel@22:       out uint eax, out uint ebx, out uint ecx, out uint edx);
moel@22:     public delegate bool CpuidExDelegate(uint index, uint ecxValue, 
moel@22:       out uint eax, out uint ebx, out uint ecx, out uint edx);
moel@46:     public delegate bool RdmsrDelegate(uint index, out uint eax, out uint edx);
moel@46:     public delegate bool RdmsrTxDelegate(uint index, out uint eax, out uint edx,
moel@46:       UIntPtr threadAffinityMask);
moel@1:     public delegate byte ReadIoPortByteDelegate(ushort port);
moel@1:     public delegate void WriteIoPortByteDelegate(ushort port, byte value);
moel@1:     public delegate void SetPciMaxBusIndexDelegate(byte max);
moel@1:     public delegate uint FindPciDeviceByIdDelegate(ushort vendorId, 
moel@1:       ushort deviceId, byte index);
moel@1:     public delegate bool ReadPciConfigDwordExDelegate(uint pciAddress, 
moel@1:       uint regAddress, out uint value);
moel@14:     public delegate bool WritePciConfigDwordExDelegate(uint pciAddress, 
moel@14:       uint regAddress, uint value);
moel@46:     public delegate bool RdtscTxDelegate(out uint eax, out uint edx,
moel@46:       UIntPtr threadAffinityMask);
moel@79:     public delegate bool RdtscDelegate(out uint eax, out uint edx);
moel@1: 
moel@1:     private static InitializeOlsDelegate InitializeOls;
moel@1:     private static DeinitializeOlsDelegate DeinitializeOls;
moel@1: 
moel@1:     public static GetDllStatusDelegate GetDllStatus;
moel@1:     public static IsCpuidDelegate IsCpuid;
moel@1:     public static CpuidDelegate Cpuid;
moel@22:     public static CpuidExDelegate CpuidEx;
moel@46:     public static RdmsrDelegate Rdmsr;
moel@46:     public static RdmsrTxDelegate RdmsrTx;
moel@1:     public static ReadIoPortByteDelegate ReadIoPortByte;
moel@1:     public static WriteIoPortByteDelegate WriteIoPortByte;
moel@1:     public static SetPciMaxBusIndexDelegate SetPciMaxBusIndex;
moel@1:     public static FindPciDeviceByIdDelegate FindPciDeviceById;
moel@1:     public static ReadPciConfigDwordExDelegate ReadPciConfigDwordEx;
moel@44:     public static WritePciConfigDwordExDelegate WritePciConfigDwordEx;
moel@46:     public static RdtscTxDelegate RdtscTx;
moel@79:     public static RdtscDelegate Rdtsc;
moel@1: 
moel@1:     private static void GetDelegate<T>(string entryPoint, out T newDelegate) 
moel@1:       where T : class 
moel@1:     {
moel@1:       DllImportAttribute attribute = new DllImportAttribute(GetDllName());
moel@1:       attribute.CallingConvention = CallingConvention.Winapi;
moel@1:       attribute.PreserveSig = true;
moel@1:       attribute.EntryPoint = entryPoint;
moel@1:       attribute.CharSet = CharSet.Auto;
moel@1:       PInvokeDelegateFactory.CreateDelegate(attribute, out newDelegate);
moel@1:     }
moel@1: 
moel@1:     static WinRing0() {
moel@1:       GetDelegate("InitializeOls", out InitializeOls);
moel@1:       GetDelegate("DeinitializeOls", out DeinitializeOls);
moel@1:       GetDelegate("GetDllStatus", out GetDllStatus);
moel@1:       GetDelegate("IsCpuid", out IsCpuid);
moel@1:       GetDelegate("Cpuid", out Cpuid);
moel@22:       GetDelegate("CpuidEx", out CpuidEx);
moel@46:       GetDelegate("Rdmsr", out  Rdmsr);
moel@46:       GetDelegate("RdmsrTx", out  RdmsrTx);
moel@1:       GetDelegate("ReadIoPortByte", out ReadIoPortByte);
moel@1:       GetDelegate("WriteIoPortByte", out WriteIoPortByte);
moel@1:       GetDelegate("SetPciMaxBusIndex", out SetPciMaxBusIndex);
moel@1:       GetDelegate("FindPciDeviceById", out FindPciDeviceById);
moel@1:       GetDelegate("ReadPciConfigDwordEx", out ReadPciConfigDwordEx);
moel@14:       GetDelegate("WritePciConfigDwordEx", out WritePciConfigDwordEx);
moel@46:       GetDelegate("RdtscTx", out RdtscTx);
moel@79:       GetDelegate("Rdtsc", out Rdtsc);
moel@1: 
moel@1:       try {
moel@1:         if (InitializeOls != null && InitializeOls())
moel@1:           available = true;
moel@1:       } catch (DllNotFoundException) { }       
moel@1:     }
moel@1:     
moel@1:     public static bool IsAvailable {
moel@1:       get { return available; }
moel@1:     }
moel@1: 
moel@1:     private static Deinitializer deinitializer = new Deinitializer();
moel@1:     private class Deinitializer {
moel@1:       ~Deinitializer() {
moel@1:         if (available)
moel@1:           DeinitializeOls();
moel@1:       }
moel@1:     }
moel@1:   }
moel@1: }