WinRing0 revert (#478)
This commit is contained in:
@@ -583,6 +583,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
}
|
||||
|
||||
OpCode.Close();
|
||||
InpOut.Close();
|
||||
Ring0.Close();
|
||||
|
||||
_smbios = null;
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using LibreHardwareMonitor.Interop;
|
||||
|
||||
namespace LibreHardwareMonitor.Hardware
|
||||
{
|
||||
internal static class InpOut
|
||||
{
|
||||
private static string _filePath;
|
||||
private static IntPtr _libraryHandle;
|
||||
private static Interop.InpOut.MapPhysToLinDelegate _mapPhysToLin;
|
||||
private static Interop.InpOut.UnmapPhysicalMemoryDelegate _unmapPhysicalMemory;
|
||||
|
||||
public static bool IsOpen { get; private set; }
|
||||
|
||||
public static bool Open()
|
||||
{
|
||||
if (IsOpen)
|
||||
return true;
|
||||
|
||||
|
||||
_filePath = GetFilePath();
|
||||
if (_filePath != null && (File.Exists(_filePath) || Extract(_filePath)))
|
||||
{
|
||||
_libraryHandle = Kernel32.LoadLibrary(_filePath);
|
||||
if (_libraryHandle != IntPtr.Zero)
|
||||
{
|
||||
IntPtr mapPhysToLinAddress = Kernel32.GetProcAddress(_libraryHandle, "MapPhysToLin");
|
||||
IntPtr unmapPhysicalMemoryAddress = Kernel32.GetProcAddress(_libraryHandle, "UnmapPhysicalMemory");
|
||||
|
||||
if (mapPhysToLinAddress != IntPtr.Zero)
|
||||
_mapPhysToLin = Marshal.GetDelegateForFunctionPointer<Interop.InpOut.MapPhysToLinDelegate>(mapPhysToLinAddress);
|
||||
|
||||
if (unmapPhysicalMemoryAddress != IntPtr.Zero)
|
||||
_unmapPhysicalMemory = Marshal.GetDelegateForFunctionPointer<Interop.InpOut.UnmapPhysicalMemoryDelegate>(unmapPhysicalMemoryAddress);
|
||||
|
||||
IsOpen = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsOpen)
|
||||
DeleteDll();
|
||||
|
||||
return IsOpen;
|
||||
}
|
||||
|
||||
public static void Close()
|
||||
{
|
||||
if (_libraryHandle != IntPtr.Zero)
|
||||
{
|
||||
Kernel32.FreeLibrary(_libraryHandle);
|
||||
DeleteDll();
|
||||
|
||||
_libraryHandle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] ReadMemory(IntPtr baseAddress, uint size)
|
||||
{
|
||||
if (_mapPhysToLin != null && _unmapPhysicalMemory != null)
|
||||
{
|
||||
IntPtr pdwLinAddr = _mapPhysToLin(baseAddress, size, out IntPtr pPhysicalMemoryHandle);
|
||||
if (pdwLinAddr != IntPtr.Zero)
|
||||
{
|
||||
byte[] bytes = new byte[size];
|
||||
Marshal.Copy(pdwLinAddr, bytes, 0, bytes.Length);
|
||||
_unmapPhysicalMemory(pPhysicalMemoryHandle, pdwLinAddr);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void DeleteDll()
|
||||
{
|
||||
try
|
||||
{
|
||||
// try to delete the DLL
|
||||
if (_filePath != null && File.Exists(_filePath))
|
||||
{
|
||||
File.Delete(_filePath);
|
||||
}
|
||||
|
||||
_filePath = null;
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
|
||||
private static string GetFilePath()
|
||||
{
|
||||
string filePath;
|
||||
|
||||
try
|
||||
{
|
||||
filePath = Path.GetTempFileName();
|
||||
if (!string.IsNullOrEmpty(filePath))
|
||||
return Path.ChangeExtension(filePath, ".dll");
|
||||
}
|
||||
catch (IOException)
|
||||
{ }
|
||||
|
||||
|
||||
const string fileName = "inpout.dll";
|
||||
|
||||
try
|
||||
{
|
||||
ProcessModule processModule = Process.GetCurrentProcess().MainModule;
|
||||
if (!string.IsNullOrEmpty(processModule?.FileName))
|
||||
return Path.Combine(Path.GetDirectoryName(processModule.FileName) ?? string.Empty, fileName);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Continue with the other options.
|
||||
}
|
||||
|
||||
filePath = GetPathFromAssembly(Assembly.GetExecutingAssembly());
|
||||
if (!string.IsNullOrEmpty(filePath))
|
||||
return Path.Combine(Path.GetDirectoryName(filePath) ?? string.Empty, fileName);
|
||||
|
||||
|
||||
filePath = GetPathFromAssembly(typeof(Ring0).Assembly);
|
||||
if (!string.IsNullOrEmpty(filePath))
|
||||
return Path.Combine(Path.GetDirectoryName(filePath) ?? string.Empty, fileName);
|
||||
|
||||
|
||||
return null;
|
||||
|
||||
|
||||
static string GetPathFromAssembly(Assembly assembly)
|
||||
{
|
||||
try
|
||||
{
|
||||
string location = assembly?.Location;
|
||||
return !string.IsNullOrEmpty(location) ? location : null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool Extract(string filePath)
|
||||
{
|
||||
string resourceName = $"{nameof(LibreHardwareMonitor)}.Resources.{(Software.OperatingSystem.Is64Bit ? "inpoutx64.dll" : "inpout32.dll")}";
|
||||
|
||||
Assembly assembly = typeof(Ring0).Assembly;
|
||||
|
||||
string[] names = assembly.GetManifestResourceNames();
|
||||
byte[] buffer = null;
|
||||
|
||||
for (int i = 0; i < names.Length; i++)
|
||||
{
|
||||
if (names[i].Replace('\\', '.') == resourceName)
|
||||
{
|
||||
using Stream stream = assembly.GetManifestResourceStream(names[i]);
|
||||
|
||||
if (stream != null)
|
||||
{
|
||||
buffer = new byte[stream.Length];
|
||||
stream.Read(buffer, 0, buffer.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer == null)
|
||||
return false;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
using FileStream target = new(filePath, FileMode.Create);
|
||||
|
||||
target.Write(buffer, 0, buffer.Length);
|
||||
target.Flush();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// for example there is not enough space on the disk
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure the file is actually written to the file system
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
|
||||
while (stopwatch.ElapsedMilliseconds < 2000)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(filePath) && new FileInfo(filePath).Length == buffer.Length)
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
|
||||
// file still has not the right size, something is wrong
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,12 +15,14 @@ namespace LibreHardwareMonitor.Hardware
|
||||
{
|
||||
internal class KernelDriver
|
||||
{
|
||||
private readonly string _id;
|
||||
private readonly string _driverId;
|
||||
private readonly string _serviceName;
|
||||
private SafeFileHandle _device;
|
||||
|
||||
public KernelDriver(string id)
|
||||
public KernelDriver(string serviceName, string driverId)
|
||||
{
|
||||
_id = id;
|
||||
_serviceName = serviceName;
|
||||
_driverId = driverId;
|
||||
}
|
||||
|
||||
public bool IsOpen
|
||||
@@ -38,8 +40,8 @@ namespace LibreHardwareMonitor.Hardware
|
||||
}
|
||||
|
||||
IntPtr service = AdvApi32.CreateService(manager,
|
||||
_id,
|
||||
_id,
|
||||
_serviceName,
|
||||
_serviceName,
|
||||
AdvApi32.SERVICE_ACCESS_MASK.SERVICE_ALL_ACCESS,
|
||||
AdvApi32.SERVICE_TYPE.SERVICE_KERNEL_DRIVER,
|
||||
AdvApi32.SERVICE_START.SERVICE_DEMAND_START,
|
||||
@@ -53,22 +55,24 @@ namespace LibreHardwareMonitor.Hardware
|
||||
|
||||
if (service == IntPtr.Zero)
|
||||
{
|
||||
if (Marshal.GetHRForLastWin32Error() == Kernel32.ERROR_SERVICE_EXISTS)
|
||||
int error = Marshal.GetHRForLastWin32Error();
|
||||
if (error == Kernel32.ERROR_SERVICE_EXISTS)
|
||||
{
|
||||
errorMessage = "Service already exists";
|
||||
return false;
|
||||
}
|
||||
|
||||
errorMessage = "CreateService returned the error: " + Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()).Message;
|
||||
errorMessage = "CreateService returned the error: " + Marshal.GetExceptionForHR(error).Message;
|
||||
AdvApi32.CloseServiceHandle(manager);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AdvApi32.StartService(service, 0, null))
|
||||
{
|
||||
if (Marshal.GetHRForLastWin32Error() != Kernel32.ERROR_SERVICE_ALREADY_RUNNING)
|
||||
int error = Marshal.GetHRForLastWin32Error();
|
||||
if (error != Kernel32.ERROR_SERVICE_ALREADY_RUNNING)
|
||||
{
|
||||
errorMessage = "StartService returned the error: " + Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()).Message;
|
||||
errorMessage = "StartService returned the error: " + Marshal.GetExceptionForHR(error).Message;
|
||||
AdvApi32.CloseServiceHandle(service);
|
||||
AdvApi32.CloseServiceHandle(manager);
|
||||
return false;
|
||||
@@ -78,25 +82,26 @@ namespace LibreHardwareMonitor.Hardware
|
||||
AdvApi32.CloseServiceHandle(service);
|
||||
AdvApi32.CloseServiceHandle(manager);
|
||||
|
||||
#if NETFRAMEWORK
|
||||
try
|
||||
{
|
||||
// restrict the driver access to system (SY) and builtin admins (BA)
|
||||
// TODO: replace with a call to IoCreateDeviceSecure in the driver
|
||||
FileSecurity fileSecurity = File.GetAccessControl(@"\\.\" + _id);
|
||||
FileInfo fileInfo = new(@"\\.\" + _driverId);
|
||||
FileSecurity fileSecurity = fileInfo.GetAccessControl();
|
||||
fileSecurity.SetSecurityDescriptorSddlForm("O:BAG:SYD:(A;;FA;;;SY)(A;;FA;;;BA)");
|
||||
File.SetAccessControl(@"\\.\" + _id, fileSecurity);
|
||||
fileInfo.SetAccessControl(fileSecurity);
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
#endif
|
||||
|
||||
errorMessage = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Open()
|
||||
{
|
||||
_device = new SafeFileHandle(Kernel32.CreateFile(@"\\.\" + _id, 0xC0000000, FileShare.None, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero), true);
|
||||
IntPtr fileHandle = Kernel32.CreateFile(@"\\.\" + _driverId, 0xC0000000, FileShare.None, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero);
|
||||
_device = new SafeFileHandle(fileHandle, true);
|
||||
if (_device.IsInvalid)
|
||||
{
|
||||
_device.Close();
|
||||
@@ -113,8 +118,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
return false;
|
||||
|
||||
|
||||
bool b = Kernel32.DeviceIoControl(_device, ioControlCode, inBuffer, inBuffer == null ? 0 : (uint)Marshal.SizeOf(inBuffer), null, 0, out uint _, IntPtr.Zero);
|
||||
return b;
|
||||
return Kernel32.DeviceIoControl(_device, ioControlCode, inBuffer, inBuffer == null ? 0 : (uint)Marshal.SizeOf(inBuffer), null, 0, out uint _, IntPtr.Zero);
|
||||
}
|
||||
|
||||
public bool DeviceIOControl<T>(Kernel32.IOControlCode ioControlCode, object inBuffer, ref T outBuffer)
|
||||
@@ -174,12 +178,14 @@ namespace LibreHardwareMonitor.Hardware
|
||||
return false;
|
||||
|
||||
|
||||
IntPtr service = AdvApi32.OpenService(manager, _id, AdvApi32.SERVICE_ACCESS_MASK.SERVICE_ALL_ACCESS);
|
||||
IntPtr service = AdvApi32.OpenService(manager, _serviceName, AdvApi32.SERVICE_ACCESS_MASK.SERVICE_ALL_ACCESS);
|
||||
if (service == IntPtr.Zero)
|
||||
{
|
||||
AdvApi32.CloseServiceHandle(manager);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
AdvApi32.SERVICE_STATUS status = new AdvApi32.SERVICE_STATUS();
|
||||
AdvApi32.SERVICE_STATUS status = new();
|
||||
AdvApi32.ControlService(service, AdvApi32.SERVICE_CONTROL.SERVICE_CONTROL_STOP, ref status);
|
||||
AdvApi32.DeleteService(service);
|
||||
AdvApi32.CloseServiceHandle(service);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// All Rights Reserved.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -13,126 +14,18 @@ using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
//SecurityIdentifier
|
||||
|
||||
namespace LibreHardwareMonitor.Hardware
|
||||
{
|
||||
internal static class Ring0
|
||||
{
|
||||
private static KernelDriver _driver;
|
||||
private static string _fileName;
|
||||
private static string _filePath;
|
||||
private static Mutex _isaBusMutex;
|
||||
private static Mutex _pciBusMutex;
|
||||
|
||||
private static readonly StringBuilder _report = new StringBuilder();
|
||||
|
||||
public static bool IsOpen
|
||||
{
|
||||
get { return _driver != null; }
|
||||
}
|
||||
private static readonly StringBuilder _report = new();
|
||||
|
||||
private static Assembly GetAssembly()
|
||||
{
|
||||
return typeof(Ring0).Assembly;
|
||||
}
|
||||
|
||||
private static string GetTempFileName()
|
||||
{
|
||||
// try to create one in the application folder
|
||||
string location = GetAssembly().Location;
|
||||
if (!string.IsNullOrEmpty(location))
|
||||
{
|
||||
try
|
||||
{
|
||||
string fileName = Path.ChangeExtension(location, ".sys");
|
||||
|
||||
using (File.Create(fileName))
|
||||
return fileName;
|
||||
}
|
||||
catch (Exception)
|
||||
{ }
|
||||
}
|
||||
|
||||
// if this failed, try to get a file in the temporary folder
|
||||
try
|
||||
{
|
||||
return Path.GetTempFileName();
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
// some I/O exception
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
// we do not have the right to create a file in the temp folder
|
||||
}
|
||||
catch (NotSupportedException)
|
||||
{
|
||||
// invalid path format of the TMP system environment variable
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static bool ExtractDriver(string fileName)
|
||||
{
|
||||
string resourceName = nameof(LibreHardwareMonitor) + "." + nameof(Hardware) + "." + (Software.OperatingSystem.Is64Bit ? "WinRing0x64.sys" : "WinRing0.sys");
|
||||
|
||||
string[] names = GetAssembly().GetManifestResourceNames();
|
||||
byte[] buffer = null;
|
||||
for (int i = 0; i < names.Length; i++)
|
||||
{
|
||||
if (names[i].Replace('\\', '.') == resourceName)
|
||||
{
|
||||
using Stream stream = GetAssembly().GetManifestResourceStream(names[i]);
|
||||
|
||||
if (stream != null)
|
||||
{
|
||||
buffer = new byte[stream.Length];
|
||||
stream.Read(buffer, 0, buffer.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer == null)
|
||||
return false;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
using FileStream target = new FileStream(fileName, FileMode.Create);
|
||||
|
||||
target.Write(buffer, 0, buffer.Length);
|
||||
target.Flush();
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
// for example there is not enough space on the disk
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure the file is actually written to the file system
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(fileName) &&
|
||||
new FileInfo(fileName).Length == buffer.Length)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
// file still has not the right size, something is wrong
|
||||
return false;
|
||||
}
|
||||
public static bool IsOpen => _driver != null;
|
||||
|
||||
public static void Open()
|
||||
{
|
||||
@@ -147,24 +40,21 @@ namespace LibreHardwareMonitor.Hardware
|
||||
// clear the current report
|
||||
_report.Length = 0;
|
||||
|
||||
_driver = new KernelDriver("WinRing0_1_2_0");
|
||||
_driver = new KernelDriver(GetServiceName(), "WinRing0_1_2_0");
|
||||
_driver.Open();
|
||||
|
||||
if (!_driver.IsOpen)
|
||||
{
|
||||
// driver is not loaded, try to install and open
|
||||
_fileName = GetTempFileName();
|
||||
if (_fileName != null && ExtractDriver(_fileName))
|
||||
_filePath = GetFilePath();
|
||||
if (_filePath != null && ExtractDriver(_filePath))
|
||||
{
|
||||
if (_driver.Install(_fileName, out string installError))
|
||||
if (_driver.Install(_filePath, out string installError))
|
||||
{
|
||||
_driver.Open();
|
||||
|
||||
if (!_driver.IsOpen)
|
||||
{
|
||||
_driver.Delete();
|
||||
_report.AppendLine("Status: Opening driver failed after install");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -176,41 +66,29 @@ namespace LibreHardwareMonitor.Hardware
|
||||
// wait a short moment to give the OS a chance to remove the driver
|
||||
Thread.Sleep(2000);
|
||||
|
||||
if (_driver.Install(_fileName, out string errorSecondInstall))
|
||||
if (_driver.Install(_filePath, out string errorSecondInstall))
|
||||
{
|
||||
_driver.Open();
|
||||
|
||||
if (!_driver.IsOpen)
|
||||
{
|
||||
_driver.Delete();
|
||||
_report.AppendLine("Status: Opening driver failed after reinstall");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_report.AppendLine("Status: Installing driver \"" + _fileName + "\" failed" + (File.Exists(_fileName) ? " and file exists" : string.Empty));
|
||||
_report.AppendLine("Status: Installing driver \"" + _filePath + "\" failed" + (File.Exists(_filePath) ? " and file exists" : string.Empty));
|
||||
_report.AppendLine("First Exception: " + errorFirstInstall);
|
||||
_report.AppendLine("Second Exception: " + errorSecondInstall);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_driver.IsOpen)
|
||||
{
|
||||
_driver.Delete();
|
||||
DeleteDriver();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_report.AppendLine("Status: Extracting driver failed");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// try to delete the driver file
|
||||
if (File.Exists(_fileName) && _fileName != null)
|
||||
File.Delete(_fileName);
|
||||
|
||||
_fileName = null;
|
||||
}
|
||||
catch (IOException)
|
||||
{ }
|
||||
catch (UnauthorizedAccessException)
|
||||
{ }
|
||||
}
|
||||
|
||||
if (!_driver.IsOpen)
|
||||
@@ -266,6 +144,191 @@ namespace LibreHardwareMonitor.Hardware
|
||||
}
|
||||
}
|
||||
|
||||
private static bool ExtractDriver(string filePath)
|
||||
{
|
||||
string resourceName = $"{nameof(LibreHardwareMonitor)}.Resources.{(Software.OperatingSystem.Is64Bit ? "WinRing0x64.sys" : "WinRing0.sys")}";
|
||||
Assembly assembly = typeof(Ring0).Assembly;
|
||||
|
||||
string[] names = assembly.GetManifestResourceNames();
|
||||
byte[] buffer = null;
|
||||
|
||||
for (int i = 0; i < names.Length; i++)
|
||||
{
|
||||
if (names[i].Replace('\\', '.') == resourceName)
|
||||
{
|
||||
using Stream stream = assembly.GetManifestResourceStream(names[i]);
|
||||
|
||||
if (stream != null)
|
||||
{
|
||||
buffer = new byte[stream.Length];
|
||||
stream.Read(buffer, 0, buffer.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer == null)
|
||||
return false;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
using FileStream target = new(filePath, FileMode.Create);
|
||||
|
||||
target.Write(buffer, 0, buffer.Length);
|
||||
target.Flush();
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
// for example there is not enough space on the disk
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure the file is actually written to the file system
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
|
||||
while (stopwatch.ElapsedMilliseconds < 2000)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(filePath) && new FileInfo(filePath).Length == buffer.Length)
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
|
||||
// file still has not the right size, something is wrong
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void DeleteDriver()
|
||||
{
|
||||
try
|
||||
{
|
||||
// try to delete the driver file
|
||||
if (_filePath != null && File.Exists(_filePath))
|
||||
File.Delete(_filePath);
|
||||
|
||||
_filePath = null;
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
|
||||
private static string GetServiceName()
|
||||
{
|
||||
string name;
|
||||
|
||||
try
|
||||
{
|
||||
ProcessModule processModule = Process.GetCurrentProcess().MainModule;
|
||||
if (!string.IsNullOrEmpty(processModule?.FileName))
|
||||
{
|
||||
name = Path.GetFileNameWithoutExtension(processModule.FileName);
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
return GetWinRing0Name(name);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Continue with the other options.
|
||||
}
|
||||
|
||||
AssemblyName assemblyName = typeof(Ring0).Assembly.GetName();
|
||||
|
||||
name = assemblyName.Name;
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
return GetWinRing0Name(name);
|
||||
|
||||
|
||||
name = nameof(LibreHardwareMonitor);
|
||||
return GetWinRing0Name(name);
|
||||
|
||||
|
||||
static string GetWinRing0Name(string name)
|
||||
{
|
||||
return $"R0{name}".Replace(" ", string.Empty).Replace(".", "_");
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetFilePath()
|
||||
{
|
||||
string filePath;
|
||||
|
||||
try
|
||||
{
|
||||
ProcessModule processModule = Process.GetCurrentProcess().MainModule;
|
||||
if (!string.IsNullOrEmpty(processModule?.FileName))
|
||||
{
|
||||
filePath = Path.ChangeExtension(processModule.FileName, ".sys");
|
||||
if (TryCreate(filePath))
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Continue with the other options.
|
||||
}
|
||||
|
||||
filePath = GetPathFromAssembly(Assembly.GetExecutingAssembly());
|
||||
if (!string.IsNullOrEmpty(filePath) && TryCreate(filePath))
|
||||
return filePath;
|
||||
|
||||
|
||||
filePath = GetPathFromAssembly(typeof(Ring0).Assembly);
|
||||
if (!string.IsNullOrEmpty(filePath) && TryCreate(filePath))
|
||||
return filePath;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
filePath = Path.GetTempFileName();
|
||||
if (!string.IsNullOrEmpty(filePath))
|
||||
{
|
||||
filePath = Path.ChangeExtension(filePath, ".sys");
|
||||
if (TryCreate(filePath))
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
|
||||
static string GetPathFromAssembly(Assembly assembly)
|
||||
{
|
||||
try
|
||||
{
|
||||
string location = assembly?.Location;
|
||||
return !string.IsNullOrEmpty(location) ? Path.ChangeExtension(location, ".sys") : null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static bool TryCreate(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (File.Create(path))
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Close()
|
||||
{
|
||||
if (_driver != null)
|
||||
@@ -293,25 +356,14 @@ namespace LibreHardwareMonitor.Hardware
|
||||
}
|
||||
|
||||
// try to delete temporary driver file again if failed during open
|
||||
if (_fileName != null && File.Exists(_fileName))
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(_fileName);
|
||||
_fileName = null;
|
||||
}
|
||||
catch (IOException)
|
||||
{ }
|
||||
catch (UnauthorizedAccessException)
|
||||
{ }
|
||||
}
|
||||
DeleteDriver();
|
||||
}
|
||||
|
||||
public static string GetReport()
|
||||
{
|
||||
if (_report.Length > 0)
|
||||
{
|
||||
StringBuilder r = new StringBuilder();
|
||||
StringBuilder r = new();
|
||||
r.AppendLine("Ring0");
|
||||
r.AppendLine();
|
||||
r.Append(_report);
|
||||
@@ -402,7 +454,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
return false;
|
||||
|
||||
|
||||
WriteMsrInput input = new WriteMsrInput { Register = index, Value = ((ulong)edx << 32) | eax };
|
||||
WriteMsrInput input = new() { Register = index, Value = ((ulong)edx << 32) | eax };
|
||||
return _driver.DeviceIOControl(Interop.Ring0.IOCTL_OLS_WRITE_MSR, input);
|
||||
}
|
||||
|
||||
@@ -423,7 +475,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
return;
|
||||
|
||||
|
||||
WriteIoPortInput input = new WriteIoPortInput { PortNumber = port, Value = value };
|
||||
WriteIoPortInput input = new() { PortNumber = port, Value = value };
|
||||
_driver.DeviceIOControl(Interop.Ring0.IOCTL_OLS_WRITE_IO_PORT_BYTE, input);
|
||||
}
|
||||
|
||||
@@ -440,7 +492,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
return false;
|
||||
}
|
||||
|
||||
ReadPciConfigInput input = new ReadPciConfigInput { PciAddress = pciAddress, RegAddress = regAddress };
|
||||
ReadPciConfigInput input = new() { PciAddress = pciAddress, RegAddress = regAddress };
|
||||
|
||||
value = 0;
|
||||
return _driver.DeviceIOControl(Interop.Ring0.IOCTL_OLS_READ_PCI_CONFIG, input, ref value);
|
||||
@@ -452,7 +504,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
return false;
|
||||
|
||||
|
||||
WritePciConfigInput input = new WritePciConfigInput { PciAddress = pciAddress, RegAddress = regAddress, Value = value };
|
||||
WritePciConfigInput input = new() { PciAddress = pciAddress, RegAddress = regAddress, Value = value };
|
||||
return _driver.DeviceIOControl(Interop.Ring0.IOCTL_OLS_WRITE_PCI_CONFIG, input);
|
||||
}
|
||||
|
||||
@@ -462,7 +514,7 @@ namespace LibreHardwareMonitor.Hardware
|
||||
return false;
|
||||
|
||||
|
||||
ReadMemoryInput input = new ReadMemoryInput { Address = address, UnitSize = 1, Count = (uint)Marshal.SizeOf(buffer) };
|
||||
ReadMemoryInput input = new() { Address = address, UnitSize = 1, Count = (uint)Marshal.SizeOf(buffer) };
|
||||
return _driver.DeviceIOControl(Interop.Ring0.IOCTL_OLS_READ_MEMORY, input, ref buffer);
|
||||
}
|
||||
|
||||
@@ -471,7 +523,8 @@ namespace LibreHardwareMonitor.Hardware
|
||||
if (_driver == null)
|
||||
return false;
|
||||
|
||||
ReadMemoryInput input = new ReadMemoryInput { Address = address, UnitSize = (uint)Marshal.SizeOf(typeof(T)), Count = (uint)buffer.Length };
|
||||
|
||||
ReadMemoryInput input = new() { Address = address, UnitSize = (uint)Marshal.SizeOf(typeof(T)), Count = (uint)buffer.Length };
|
||||
return _driver.DeviceIOControl(Interop.Ring0.IOCTL_OLS_READ_MEMORY, input, ref buffer);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@ namespace LibreHardwareMonitor.Hardware
|
||||
// Zen Raven Ridge APU.
|
||||
0x001E0004, new Dictionary<uint, SmuSensorType>
|
||||
{
|
||||
{ 7, new SmuSensorType { Name = "TDC", Type = SensorType.Current, Scale = 1}},
|
||||
{ 11, new SmuSensorType { Name = "EDC", Type = SensorType.Current, Scale = 1}},
|
||||
{ 7, new SmuSensorType { Name = "TDC", Type = SensorType.Current, Scale = 1 } },
|
||||
{ 11, new SmuSensorType { Name = "EDC", Type = SensorType.Current, Scale = 1 } },
|
||||
//{ 61, new SmuSensorType { Name = "Core", Type = SensorType.Voltage } },
|
||||
//{ 62, new SmuSensorType { Name = "Core", Type = SensorType.Current, Scale = 1} },
|
||||
//{ 63, new SmuSensorType { Name = "Core", Type = SensorType.Power, Scale = 1 } },
|
||||
@@ -57,12 +57,12 @@ namespace LibreHardwareMonitor.Hardware
|
||||
// Zen 2.
|
||||
0x00240903, new Dictionary<uint, SmuSensorType>
|
||||
{
|
||||
{ 15, new SmuSensorType { Name = "TDC", Type = SensorType.Current, Scale = 1}},
|
||||
{ 21, new SmuSensorType { Name = "EDC", Type = SensorType.Current, Scale = 1}},
|
||||
{ 48, new SmuSensorType { Name = "Fabric", Type = SensorType.Clock, Scale = 1} },
|
||||
{ 50, new SmuSensorType { Name = "Uncore", Type = SensorType.Clock, Scale = 1} },
|
||||
{ 51, new SmuSensorType { Name = "Memory", Type = SensorType.Clock, Scale = 1} },
|
||||
{ 115, new SmuSensorType { Name = "SoC", Type = SensorType.Temperature, Scale = 1} },
|
||||
{ 15, new SmuSensorType { Name = "TDC", Type = SensorType.Current, Scale = 1 } },
|
||||
{ 21, new SmuSensorType { Name = "EDC", Type = SensorType.Current, Scale = 1 } },
|
||||
{ 48, new SmuSensorType { Name = "Fabric", Type = SensorType.Clock, Scale = 1 } },
|
||||
{ 50, new SmuSensorType { Name = "Uncore", Type = SensorType.Clock, Scale = 1 } },
|
||||
{ 51, new SmuSensorType { Name = "Memory", Type = SensorType.Clock, Scale = 1 } },
|
||||
{ 115, new SmuSensorType { Name = "SoC", Type = SensorType.Temperature, Scale = 1 } },
|
||||
//{ 66, new SmuSensorType { Name = "Bus Speed", Type = SensorType.Clock, Scale = 1 } },
|
||||
//{ 188, new SmuSensorType { Name = "Core #1", Type = SensorType.Clock, Scale = 1000 } },
|
||||
//{ 189, new SmuSensorType { Name = "Core #2", Type = SensorType.Clock, Scale = 1000 } },
|
||||
@@ -88,6 +88,9 @@ namespace LibreHardwareMonitor.Hardware
|
||||
|
||||
_supportedCPU = SetAddresses(_cpuCodeName);
|
||||
|
||||
if (_supportedCPU)
|
||||
InpOut.Open();
|
||||
|
||||
SetupPmTableAddrAndSize();
|
||||
}
|
||||
|
||||
@@ -249,9 +252,8 @@ namespace LibreHardwareMonitor.Hardware
|
||||
uint[] args = { 1 };
|
||||
|
||||
if (SendCommand(0x02, ref args))
|
||||
{
|
||||
return args[0];
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -283,7 +285,9 @@ namespace LibreHardwareMonitor.Hardware
|
||||
|
||||
|
||||
float[] table = ReadDramToArray();
|
||||
if (table[0] == 0) /* Fix for Zen+ empty values at first call bug */
|
||||
|
||||
// Fix for Zen+ empty values on first call.
|
||||
if (table[0] == 0)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
TransferTableToDram();
|
||||
@@ -297,7 +301,9 @@ namespace LibreHardwareMonitor.Hardware
|
||||
{
|
||||
float[] table = new float[_pmTableSize / 4];
|
||||
|
||||
Ring0.ReadMemory(_dramBaseAddr, ref table);
|
||||
byte[] bytes = InpOut.ReadMemory(new IntPtr(_dramBaseAddr), _pmTableSize);
|
||||
if (bytes != null)
|
||||
Buffer.BlockCopy(bytes, 0, table, 0, bytes.Length);
|
||||
|
||||
return table;
|
||||
}
|
||||
@@ -305,14 +311,10 @@ namespace LibreHardwareMonitor.Hardware
|
||||
private bool SetupPmTableAddrAndSize()
|
||||
{
|
||||
if (_pmTableSize == 0)
|
||||
{
|
||||
SetupPmTableSize();
|
||||
}
|
||||
|
||||
if (_dramBaseAddr == 0)
|
||||
{
|
||||
SetupDramBaseAddr();
|
||||
}
|
||||
|
||||
return _dramBaseAddr != 0 && _pmTableSize != 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace LibreHardwareMonitor.Interop
|
||||
{
|
||||
internal class InpOut
|
||||
{
|
||||
public delegate IntPtr MapPhysToLinDelegate(IntPtr pbPhysAddr, uint dwPhysSize, out IntPtr pPhysicalMemoryHandle);
|
||||
|
||||
public delegate bool UnmapPhysicalMemoryDelegate(IntPtr PhysicalMemoryHandle, IntPtr pbLinAddr);
|
||||
|
||||
[DllImport("inpout.dll", EntryPoint = "MapPhysToLin", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern IntPtr MapPhysToLin(IntPtr pbPhysAddr, uint dwPhysSize, out IntPtr pPhysicalMemoryHandle);
|
||||
|
||||
[DllImport("inpout.dll", EntryPoint = "UnmapPhysicalMemory", CallingConvention = CallingConvention.StdCall)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool UnmapPhysicalMemory(IntPtr PhysicalMemoryHandle, IntPtr pbLinAddr);
|
||||
}
|
||||
}
|
||||
@@ -24,17 +24,21 @@
|
||||
<OutputPath>..\bin\Release\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Hardware\WinRing0.sys" />
|
||||
<EmbeddedResource Include="Hardware\WinRing0x64.sys" />
|
||||
<EmbeddedResource Include="Resources\inpout32.dll" />
|
||||
<EmbeddedResource Include="Resources\inpoutx64.dll" />
|
||||
<EmbeddedResource Include="Resources\WinRing0.sys" />
|
||||
<EmbeddedResource Include="Resources\WinRing0x64.sys" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
|
||||
<PackageReference Include="Microsoft.Win32.Registry" Version="4.7.0" />
|
||||
<PackageReference Include="System.IO.Ports" Version="4.7.0" />
|
||||
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net5.0'">
|
||||
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
|
||||
<PackageReference Include="System.IO.Ports" Version="5.0.0" />
|
||||
<PackageReference Include="System.Management" Version="5.0.0" />
|
||||
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="HidSharp" Version="2.1.0" />
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user