diff --git a/includes/battery.h b/includes/battery.h new file mode 100644 index 0000000..c7fcf7e --- /dev/null +++ b/includes/battery.h @@ -0,0 +1,6 @@ +#pragma once + +#include + +// Get the current battery level +int get_battery_level(const char *device_path, bool *is_charging); diff --git a/includes/helper.h b/includes/helper.h new file mode 100644 index 0000000..b136156 --- /dev/null +++ b/includes/helper.h @@ -0,0 +1,7 @@ +#pragma once + +#define PID_WIRED 0x007A +#define PID_WIRELESS 0x007B + +// Enumerate through HID devices and find device path +void find_device_path(int pid, char *device_path); diff --git a/src/helper.c b/src/helper.c new file mode 100644 index 0000000..cc303ff --- /dev/null +++ b/src/helper.c @@ -0,0 +1,60 @@ +#include "../includes/helper.h" + +#include + +#include +#include +#include + +#define VID 0x1532 + +void find_device_path(int pid, char *device_path) { + GUID hidGuid; + HidD_GetHidGuid(&hidGuid); + + HDEVINFO hDevInfo = SetupDiGetClassDevs( + &hidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + if (hDevInfo == INVALID_HANDLE_VALUE) { + fprintf_s(stderr, "Failed to get device information.\n"); + return; + } + + SP_DEVICE_INTERFACE_DATA deviceInterfaceData; + deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + + for (DWORD i = 0; SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &hidGuid, i, + &deviceInterfaceData); + i++) { + DWORD requiredSize; + SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, NULL, 0, + &requiredSize, NULL); + + PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = + (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(requiredSize); + detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); + + if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, + detailData, requiredSize, NULL, NULL)) { + HANDLE hDevice = CreateFile( + detailData->DevicePath, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if (hDevice != INVALID_HANDLE_VALUE) { + // Get device attributes + HIDD_ATTRIBUTES attributes; + attributes.Size = sizeof(HIDD_ATTRIBUTES); + if (HidD_GetAttributes(hDevice, &attributes)) { + // Check VID and PID + if (attributes.VendorID == VID && attributes.ProductID == pid) { + strcpy(device_path, detailData->DevicePath); + CloseHandle(hDevice); + break; + } + } + CloseHandle(hDevice); + } + } + free(detailData); + } + + SetupDiDestroyDeviceInfoList(hDevInfo); +} diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..1896904 --- /dev/null +++ b/src/main.c @@ -0,0 +1,35 @@ +#include "../includes/battery.h" +#include "../includes/helper.h" + +#include +#include + +int main(void) { + char device_path[2048]; + + // Try wired + find_device_path(PID_WIRED, device_path); + + if (strlen(device_path) < 10) { + // Try wireless + find_device_path(PID_WIRELESS, device_path); + + if (strlen(device_path) < 10) { + fprintf_s(stderr, "Can't find any compatible device.\n"); + return 1; + } + } + printf("Device: %s\n", device_path); + + bool is_charging; + int battery_level; + if ((battery_level = get_battery_level(device_path, &is_charging)) < 0) { + fprintf_s(stderr, "Failed to get battery level.\n"); + return 1; + } + + printf("Battery Level: %d%%\n", battery_level); + printf("Charging: %s\n", is_charging ? "Yes" : "No"); + + return 0; +}