From: Alex Henrie Subject: [PATCH v2] ntdll: Check for several common battery and AC adapter names on Linux Message-Id: <20220422082001.127980-1-alexhenrie24@gmail.com> Date: Fri, 22 Apr 2022 02:20:01 -0600 These names come from ACPI, but the exact naming convention varies between hardware manufacturers. Try all of them and take the statistics from the first one that exists. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52831 Signed-off-by: Alex Henrie --- v2: Remove the bitwise ORs that are now unnecessary because we're only looking at the first battery --- dlls/ntdll/unix/system.c | 61 +++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c index 65c49b6ccd1..b51f2dddd6d 100644 --- a/dlls/ntdll/unix/system.c +++ b/dlls/ntdll/unix/system.c @@ -3425,10 +3425,14 @@ static ULONG mhz_from_cpuinfo(void) return cmz; } -static const char * get_sys_str(const char *path, char *s) +static const char * get_sys_str(const char *dirname, const char *basename, char *s) { - FILE *f = fopen(path, "r"); + FILE *f; const char *ret = NULL; + char path[64]; + + sprintf(path, "%s/%s", dirname, basename); + f = fopen(path, "r"); if (f) { @@ -3438,40 +3442,57 @@ static const char * get_sys_str(const char *path, char *s) return ret; } -static int get_sys_int(const char *path, int def) +static int get_sys_int(const char *dirname, const char *basename, int def) { char s[16]; - return get_sys_str(path, s) ? atoi(s) : def; + return get_sys_str(dirname, basename, s) ? atoi(s) : def; } static NTSTATUS fill_battery_state( SYSTEM_BATTERY_STATE *bs ) { - char s[16], path[64]; - unsigned int i = 0; + static const char* ac_names[] = + { + "AC", + "ACAD", + "ADP0", + "ADP1", + NULL + }; + static const char* bat_names[] = + { + "BAT0", + "BAT1", + NULL + }; + char s[16], dirname[64]; + const char** name; LONG64 voltage; /* microvolts */ - bs->AcOnLine = get_sys_int("/sys/class/power_supply/AC/online", 1); - - for (;;) + bs->AcOnLine = TRUE; + for (name = ac_names; name; name++) { - sprintf(path, "/sys/class/power_supply/BAT%u/status", i); - if (!get_sys_str(path, s)) break; - bs->Charging |= (strcmp(s, "Charging\n") == 0); - bs->Discharging |= (strcmp(s, "Discharging\n") == 0); - bs->BatteryPresent = TRUE; - i++; + sprintf(dirname, "/sys/class/power_supply/%s", *name); + if (!get_sys_str(dirname, "online", s)) continue; + bs->AcOnLine = atoi(s); + break; } - if (bs->BatteryPresent) + for (name = bat_names; name; name++) { - 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; + sprintf(dirname, "/sys/class/power_supply/%s", *name); + if (!get_sys_str(dirname, "status", s)) continue; + bs->Charging = (strcmp(s, "Charging\n") == 0); + bs->Discharging = (strcmp(s, "Discharging\n") == 0); + bs->BatteryPresent = TRUE; + voltage = get_sys_int(dirname, "voltage_now", 0); + bs->MaxCapacity = get_sys_int(dirname, "charge_full", 0) * voltage / 1e9; + bs->RemainingCapacity = get_sys_int(dirname, "charge_now", 0) * voltage / 1e9; + bs->Rate = -get_sys_int(dirname, "current_now", 0) * voltage / 1e9; if (!bs->Charging && (LONG)bs->Rate < 0) bs->EstimatedTime = 3600 * bs->RemainingCapacity / -(LONG)bs->Rate; else bs->EstimatedTime = ~0u; + break; } return STATUS_SUCCESS; -- 2.36.0