Alex Henrie : ntdll: Implement NtPowerInformation(SystemBatteryState) on Linux.

Alexandre Julliard julliard at winehq.org
Thu Oct 31 17:39:29 CDT 2019


Module: wine
Branch: master
Commit: 63ddf0343b352d5709a587b9a1efc52bf111ab6a
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=63ddf0343b352d5709a587b9a1efc52bf111ab6a

Author: Alex Henrie <alexhenrie24 at gmail.com>
Date:   Tue Oct 29 20:22:23 2019 -0600

ntdll: Implement NtPowerInformation(SystemBatteryState) on Linux.

Signed-off-by: Alex Henrie <alexhenrie24 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/nt.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 5afdf77986..81bac70b0f 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -3137,6 +3137,73 @@ static ULONG mhz_from_cpuinfo(void)
 }
 #endif
 
+#ifdef linux
+
+static const char * get_sys_str(const char *path)
+{
+	static char s[16];
+	FILE *f = fopen(path, "r");
+	const char *ret = NULL;
+	if (f)
+	{
+		if (fgets(s, sizeof(s), f))
+			ret = s;
+		fclose(f);
+	}
+	return ret;
+}
+
+static int get_sys_int(const char *path, int def)
+{
+	const char *s = get_sys_str(path);
+	return s ? atoi(s) : def;
+}
+
+static NTSTATUS fill_battery_state(SYSTEM_BATTERY_STATE *bs)
+{
+	char path[64];
+	const char *s;
+	unsigned int i = 0;
+	LONG64 voltage; /* microvolts */
+
+	bs->AcOnLine = get_sys_int("/sys/class/power_supply/AC/online", 1);
+
+	for (;;)
+	{
+		sprintf(path, "/sys/class/power_supply/BAT%u/status", i);
+		s = get_sys_str(path);
+		if (!s) break;
+		bs->Charging |= (strcmp(s, "Charging\n") == 0);
+		bs->Discharging |= (strcmp(s, "Discharging\n") == 0);
+		bs->BatteryPresent = TRUE;
+		i++;
+	}
+
+	if (bs->BatteryPresent)
+	{
+		voltage = get_sys_int("/sys/class/power_supply/BAT0/voltage_now", 0);
+		bs->MaxCapacity = get_sys_int("/sys/class/power_supply/BAT0/charge_full", 0) * voltage / 1e9;
+		bs->RemainingCapacity = get_sys_int("/sys/class/power_supply/BAT0/charge_now", 0) * voltage / 1e9;
+		bs->Rate = -get_sys_int("/sys/class/power_supply/BAT0/current_now", 0) * voltage / 1e9;
+		if (!bs->Charging && (LONG)bs->Rate < 0)
+			bs->EstimatedTime = 3600 * bs->RemainingCapacity / -(LONG)bs->Rate;
+		else
+			bs->EstimatedTime = ~0u;
+	}
+
+	return STATUS_SUCCESS;
+}
+
+#else
+
+static NTSTATUS fill_battery_state(SYSTEM_BATTERY_STATE *)
+{
+	FIXME("SystemBatteryState not implemented on this platform\n");
+	return STATUS_NOT_IMPLEMENTED;
+}
+
+#endif
+
 /******************************************************************************
  *  NtPowerInformation				[NTDLL.@]
  *
@@ -3190,6 +3257,12 @@ NTSTATUS WINAPI NtPowerInformation(
 			PowerCaps->DefaultLowLatencyWake = PowerSystemUnspecified;
 			return STATUS_SUCCESS;
 		}
+		case SystemBatteryState: {
+			if (nOutputBufferSize < sizeof(SYSTEM_BATTERY_STATE))
+				return STATUS_BUFFER_TOO_SMALL;
+			memset(lpOutputBuffer, 0, sizeof(SYSTEM_BATTERY_STATE));
+			return fill_battery_state(lpOutputBuffer);
+		}
 		case SystemExecutionState: {
 			PULONG ExecutionState = lpOutputBuffer;
 			WARN("semi-stub: SystemExecutionState\n"); /* Needed for .NET Framework, but using a FIXME is really noisy. */




More information about the wine-cvs mailing list