Add support for battery monitoring (#612)

Thanks to @EMN-CSharp.
This commit is contained in:
EMN-CSharp
2022-02-07 17:05:36 +01:00
committed by GitHub
parent 0ed564e7c6
commit 5152b435fc
19 changed files with 844 additions and 149 deletions
+135 -1
View File
@@ -26,6 +26,9 @@ namespace LibreHardwareMonitor.Interop
internal const byte SMART_LBA_MID = 0x4F;
internal const byte SMART_LBA_HI_EXCEEDED = 0x2C;
internal const byte SMART_LBA_MID_EXCEEDED = 0xF4;
internal const uint LPTR = 0x0000 | 0x0040;
private const string DllName = "kernel32.dll";
[Flags]
@@ -203,6 +206,64 @@ namespace LibreHardwareMonitor.Interop
out uint lpBytesReturned,
IntPtr lpOverlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeviceIoControl
(
SafeFileHandle hDevice,
IOCTL dwIoControlCode,
ref BATTERY_QUERY_INFORMATION lpInBuffer,
int nInBufferSize,
ref BATTERY_INFORMATION lpOutBuffer,
int nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeviceIoControl
(
SafeFileHandle hDevice,
IOCTL dwIoControlCode,
ref uint lpInBuffer,
int nInBufferSize,
ref uint lpOutBuffer,
int nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeviceIoControl
(
SafeFileHandle hDevice,
IOCTL dwIoControlCode,
ref BATTERY_WAIT_STATUS lpInBuffer,
int nInBufferSize,
ref BATTERY_STATUS lpOutBuffer,
int nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeviceIoControl
(
SafeFileHandle hDevice,
IOCTL dwIoControlCode,
ref BATTERY_QUERY_INFORMATION lpInBuffer,
int nInBufferSize,
IntPtr lpOutBuffer,
int nOutBufferSize,
out uint lpBytesReturned,
IntPtr lpOverlapped);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi)]
internal static extern IntPtr LocalAlloc(uint uFlags, ulong uBytes);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi)]
internal static extern IntPtr LocalFree(IntPtr hMem);
[DllImport(DllName, SetLastError = true)]
internal static extern void RtlZeroMemory(IntPtr Destination, int Length);
@@ -291,7 +352,80 @@ namespace LibreHardwareMonitor.Interop
IOCTL_SCSI_MINIPORT = 0x04d008,
IOCTL_SCSI_PASS_THROUGH_DIRECT = 0x04d014,
IOCTL_SCSI_GET_ADDRESS = 0x41018,
IOCTL_STORAGE_QUERY_PROPERTY = 0x2D1400
IOCTL_STORAGE_QUERY_PROPERTY = 0x2D1400,
IOCTL_BATTERY_QUERY_TAG = 0x294040,
IOCTL_BATTERY_QUERY_INFORMATION = 0x294044,
IOCTL_BATTERY_QUERY_STATUS = 0x29404C
}
[Flags]
internal enum BatteryCapabilities : uint
{
BATTERY_CAPACITY_RELATIVE = 0x40000000,
BATTERY_IS_SHORT_TERM = 0x20000000,
BATTERY_SET_CHARGE_SUPPORTED = 0x00000001,
BATTERY_SET_DISCHARGE_SUPPORTED = 0x00000002,
BATTERY_SYSTEM_BATTERY = 0x80000000
}
internal enum BATTERY_QUERY_INFORMATION_LEVEL
{
BatteryInformation,
BatteryGranularityInformation,
BatteryTemperature,
BatteryEstimatedTime,
BatteryDeviceName,
BatteryManufactureDate,
BatteryManufactureName,
BatteryUniqueID,
BatterySerialNumber
}
[StructLayout(LayoutKind.Sequential)]
internal struct BATTERY_QUERY_INFORMATION
{
public uint BatteryTag;
public BATTERY_QUERY_INFORMATION_LEVEL InformationLevel;
public uint AtRate;
}
[StructLayout(LayoutKind.Sequential)]
internal struct BATTERY_INFORMATION
{
public BatteryCapabilities Capabilities;
public byte Technology;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] Reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public char[] Chemistry;
public uint DesignedCapacity;
public uint FullChargedCapacity;
public uint DefaultAlert1;
public uint DefaultAlert2;
public uint CriticalBias;
public uint CycleCount;
}
[StructLayout(LayoutKind.Sequential)]
internal struct BATTERY_WAIT_STATUS
{
public uint BatteryTag;
public uint Timeout;
public uint PowerState;
public uint LowCapacity;
public uint HighCapacity;
}
[StructLayout(LayoutKind.Sequential)]
internal struct BATTERY_STATUS
{
public uint PowerState;
public uint Capacity;
public uint Voltage;
public int Rate;
}
[Flags]
@@ -0,0 +1,50 @@
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// Copyright (C) LibreHardwareMonitor and Contributors.
// All Rights Reserved.
using System;
using System.Runtime.InteropServices;
namespace LibreHardwareMonitor.Interop
{
internal class SetupApi
{
internal const int ERROR_INSUFFICIENT_BUFFER = 122;
internal const int ERROR_NO_MORE_ITEMS = 259;
internal const int DIGCF_PRESENT = 0x00000002;
internal const int DIGCF_DEVICEINTERFACE = 0x00000010;
internal static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
internal static Guid GUID_DEVICE_BATTERY = new Guid(0x72631e54, 0x78A4, 0x11d0, 0xbc, 0xf7, 0x00, 0xaa, 0x00, 0xb7, 0xb3, 0x2a);
private const string DllName = "SetupAPI.dll";
[StructLayout(LayoutKind.Sequential)]
internal struct SP_DEVICE_INTERFACE_DATA
{
public uint cbSize;
public Guid InterfaceClassGuid;
public uint Flags;
public IntPtr Reserved;
}
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
internal static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid, IntPtr Enumerator, IntPtr hwndParent, uint Flags);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, ref Guid InterfaceClassGuid, uint MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
[DllImport(DllName, SetLastError = true, EntryPoint = "SetupDiGetDeviceInterfaceDetailW", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet,
in SP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
[Out, Optional] IntPtr DeviceInterfaceDetailData,
uint DeviceInterfaceDetailDataSize,
out uint RequiredSize,
IntPtr DeviceInfoData = default);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
}
}