Rewrite of core ASUSWmi module, now app doesn't need admin permissions

This commit is contained in:
seerge
2023-02-22 19:14:31 +01:00
parent 16f6f3f934
commit 2ee9110016
6 changed files with 194 additions and 112 deletions

184
ASUSWmi.cs Normal file
View File

@@ -0,0 +1,184 @@
using System.Management;
using System.Runtime.InteropServices;
public class ASUSWmi
{
const string FILE_NAME = @"\\.\\ATKACPI";
const uint CONTROL_CODE = 0x0022240C;
const uint DSTS = 0x53545344;
const uint DEVS = 0x53564544;
public const uint CPU_Fan = 0x00110013;
public const uint GPU_Fan = 0x00110014;
public const uint PerformanceMode = 0x00120075; // Thermal Control
public const uint GPUEco = 0x00090020;
public const uint GPUMux = 0x00090016;
public const uint BatteryLimit = 0x00120057;
public const uint ScreenOverdrive = 0x00050019;
public const uint DevsCPUFanCurve = 0x00110024;
public const uint DevsGPUFanCurve = 0x00110025;
public const int PerformanceBalanced = 0;
public const int PerformanceTurbo = 1;
public const int PerformanceSilent = 2;
public const int GPUModeEco = 0;
public const int GPUModeStandard = 1;
public const int GPUModeUltimate = 2;
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern IntPtr CreateFile(
string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr lpSecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile
);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool DeviceIoControl(
IntPtr hDevice,
uint dwIoControlCode,
byte[] lpInBuffer,
uint nInBufferSize,
byte[] lpOutBuffer,
uint nOutBufferSize,
ref uint lpBytesReturned,
IntPtr lpOverlapped
);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CloseHandle(IntPtr hObject);
private const uint GENERIC_READ = 0x80000000;
private const uint GENERIC_WRITE = 0x40000000;
private const uint OPEN_EXISTING = 3;
private const uint FILE_ATTRIBUTE_NORMAL = 0x80;
private const uint FILE_SHARE_READ = 1;
private const uint FILE_SHARE_WRITE = 2;
private IntPtr handle;
public ASUSWmi()
{
handle = CreateFile(
FILE_NAME,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
IntPtr.Zero,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero
);
if (handle == new IntPtr(-1))
{
throw new Exception("Can't connect to ACPI");
}
}
public void Control(uint dwIoControlCode, byte[] lpInBuffer, byte[] lpOutBuffer)
{
uint lpBytesReturned = 0;
bool result = DeviceIoControl(
handle,
dwIoControlCode,
lpInBuffer,
(uint)lpInBuffer.Length,
lpOutBuffer,
(uint)lpOutBuffer.Length,
ref lpBytesReturned,
IntPtr.Zero
);
}
public void Close()
{
CloseHandle(handle);
}
protected byte[] CallMethod(uint MethodID, byte[] args)
{
byte[] acpiBuf = new byte[8 + args.Length];
byte[] outBuffer = new byte[20];
BitConverter.GetBytes((uint)MethodID).CopyTo(acpiBuf, 0);
BitConverter.GetBytes((uint)args.Length).CopyTo(acpiBuf, 4);
Array.Copy(args, 0, acpiBuf, 8, args.Length);
Console.WriteLine(BitConverter.ToString(acpiBuf, 0, acpiBuf.Length));
Control(CONTROL_CODE, acpiBuf, outBuffer);
return outBuffer;
}
public void DeviceSet(uint DeviceID, int Status)
{
byte[] args = new byte[8];
BitConverter.GetBytes((uint)DeviceID).CopyTo(args, 0);
BitConverter.GetBytes((uint)Status).CopyTo(args, 4);
CallMethod(DEVS, args);
}
public void DeviceSet(uint DeviceID, byte[] Params)
{
byte[] args = new byte[4 + Params.Length];
BitConverter.GetBytes((uint)DeviceID).CopyTo(args, 0);
Params.CopyTo(args, 4);
CallMethod(DEVS, args);
}
public int DeviceGet(uint DeviceID)
{
byte[] args = new byte[8];
BitConverter.GetBytes((uint)DeviceID).CopyTo(args, 0);
byte[] status = CallMethod(DSTS, args);
return BitConverter.ToInt32(status, 0)-65536;
}
public byte[] DeviceGetBuffer(uint DeviceID, int Status = 0)
{
byte[] args = new byte[8];
BitConverter.GetBytes((uint)DeviceID).CopyTo(args, 0);
BitConverter.GetBytes((uint)Status).CopyTo(args, 4);
return CallMethod(DSTS, args);
}
public void SetFanCurve(byte[] curve)
{
DeviceSet(DevsCPUFanCurve, curve);
}
public byte[] GetFanCurve(int mode = 0)
{
if (mode == 1) mode = 2;
if (mode == 2) mode = 1; // because it's asus, and modes are swapped here
return DeviceGetBuffer(DevsCPUFanCurve, mode);
}
public void SubscribeToEvents(Action<object, EventArrivedEventArgs> EventHandler)
{
ManagementEventWatcher watcher = new ManagementEventWatcher();
watcher.EventArrived += new EventArrivedEventHandler(EventHandler);
watcher.Scope = new ManagementScope("root\\wmi");
watcher.Query = new WqlEventQuery("SELECT * FROM AsusAtkWmiEvent");
watcher.Start();
}
}

View File

@@ -34,7 +34,6 @@
<ItemGroup>
<PackageReference Include="hidlibrary" Version="3.3.40" />
<PackageReference Include="LibreHardwareMonitorLib" Version="0.9.1" />
<PackageReference Include="System.Management" Version="7.0.0" />
<PackageReference Include="TaskScheduler" Version="2.10.1" />
</ItemGroup>

View File

@@ -4,112 +4,13 @@ using Microsoft.Win32.TaskScheduler;
using System.Diagnostics;
using System.Management;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text.Json;
public class ASUSWmi
{
private ManagementObject mo;
private ManagementClass classInstance;
public const int CPU_Fan = 0x00110013;
public const int GPU_Fan = 0x00110014;
public const int PerformanceMode = 0x00120075;
public const int GPUEco = 0x00090020;
public const int GPUMux = 0x00090016;
public const int BatteryLimit = 0x00120057;
public const int ScreenOverdrive = 0x00050019;
public const int PerformanceBalanced = 0;
public const int PerformanceTurbo = 1;
public const int PerformanceSilent = 2;
public const int GPUModeEco = 0;
public const int GPUModeStandard = 1;
public const int GPUModeUltimate = 2;
public ASUSWmi()
{
this.classInstance = new ManagementClass(new ManagementScope("root\\wmi"), new ManagementPath("AsusAtkWmi_WMNB"), null);
foreach (ManagementObject mo in this.classInstance.GetInstances())
{
this.mo = mo;
}
}
private int WMICall(string MethodName, int Device_Id, int Control_status = -1)
{
ManagementBaseObject inParams = this.classInstance.Methods[MethodName].InParameters;
inParams["Device_ID"] = Device_Id;
if (Control_status != -1)
{
inParams["Control_status"] = Control_status;
}
ManagementBaseObject outParams = this.mo.InvokeMethod(MethodName, inParams, null);
foreach (PropertyData property in outParams.Properties)
{
if (property.Name == "device_status")
{
int status;
try
{
status = int.Parse(property.Value.ToString());
status -= 65536;
return status;
}
catch
{
return -1;
}
}
if (property.Name == "result")
{
try
{
return int.Parse(property.Value.ToString());
}
catch
{
return -1;
}
}
}
return -1;
}
public int DeviceGet(int Device_Id)
{
return this.WMICall("DSTS", Device_Id);
}
public int DeviceSet(int Device_Id, int Control_status)
{
return this.WMICall("DEVS", Device_Id, Control_status);
}
public void SubscribeToEvents(Action<object, EventArrivedEventArgs> EventHandler)
{
ManagementEventWatcher watcher = new ManagementEventWatcher();
watcher.EventArrived += new EventArrivedEventHandler(EventHandler);
watcher.Scope = new ManagementScope("root\\wmi");
watcher.Query = new WqlEventQuery("SELECT * FROM AsusAtkWmiEvent");
watcher.Start();
}
}
public class Startup
{
static string taskName = "GSharpHelper";
static string taskName = "GHelper";
public Startup()
{
@@ -130,14 +31,14 @@ public class Startup
if (strExeFilePath is null) return;
var userId = WindowsIdentity.GetCurrent().Name;
Debug.WriteLine(strExeFilePath);
TaskDefinition td = TaskService.Instance.NewTask();
td.RegistrationInfo.Description = "GSharpHelper Auto Start";
LogonTrigger lt = new LogonTrigger();
td.Triggers.Add(lt);
td.RegistrationInfo.Description = "GHelper Auto Start";
td.Triggers.Add(new LogonTrigger { UserId = userId, });
td.Actions.Add(strExeFilePath);
td.Principal.RunLevel = TaskRunLevel.Highest;
td.Settings.StopIfGoingOnBatteries = false;
td.Settings.DisallowStartIfOnBatteries = false;
@@ -620,7 +521,6 @@ namespace GHelper
public static AppConfig config;
public static SettingsForm settingsForm;
public static ToastForm toastForm;
public static Startup scheduler;
public static HardwareMonitor hwmonitor;

4
Settings.Designer.cs generated
View File

@@ -506,10 +506,10 @@
// labelBattery
//
this.labelBattery.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.labelBattery.Location = new System.Drawing.Point(491, 869);
this.labelBattery.Location = new System.Drawing.Point(425, 869);
this.labelBattery.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.labelBattery.Name = "labelBattery";
this.labelBattery.Size = new System.Drawing.Size(211, 32);
this.labelBattery.Size = new System.Drawing.Size(277, 32);
this.labelBattery.TabIndex = 27;
this.labelBattery.Text = " ";
this.labelBattery.TextAlign = System.Drawing.ContentAlignment.TopRight;

View File

@@ -432,7 +432,6 @@ namespace GHelper
int eco = Program.wmi.DeviceGet(ASUSWmi.GPUEco);
int mux = Program.wmi.DeviceGet(ASUSWmi.GPUMux);
int GPUMode;
if (mux == 0) // GPU in Ultimate, ignore
return;

View File

@@ -16,7 +16,7 @@
Remove this element if your application requires this virtualization for backwards
compatibility.
-->
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>