Получить имя устройства батареи

Я пытаюсь получить имена всех аккумуляторных устройств на моем компьютере, используя этот код, полученный в основном из руководства Microsoft, но он не работает.

#define INITGUID
#include <windows.h>
#include<batclass.h>
#include<setupapi.h>
#define GBS_HASBATTERY 0x1
#define GBS_ONBATTERY  0x2
#include<iostream>

using namespace std;

int main()
{
DWORD dwResult = GBS_ONBATTERY;
HDEVINFO hdev = SetupDiGetClassDevs(&GUID_DEVICE_BATTERY, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

for (int idev = 0; idev < 100; idev++)
{
SP_DEVICE_INTERFACE_DATA did = {0};
did.cbSize = sizeof(did);

if (SetupDiEnumDeviceInterfaces(hdev, 0, &GUID_DEVICE_BATTERY, idev, &did))
{
DWORD cbRequired = 0;
SetupDiGetDeviceInterfaceDetail(hdev, &did, 0, 0, &cbRequired, 0);

if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
{
PSP_DEVICE_INTERFACE_DETAIL_DATA pdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR,cbRequired);

if (pdidd)
{
pdidd->cbSize = sizeof(*pdidd);

if (SetupDiGetDeviceInterfaceDetail(hdev,&did,pdidd,cbRequired,&cbRequired,0))
{
HANDLE hBattery = CreateFile(pdidd->DevicePath,GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if (INVALID_HANDLE_VALUE != hBattery)
{
BATTERY_QUERY_INFORMATION bqi = {0};

DWORD dwWait = 0;
DWORD dwOut;

if (DeviceIoControl(hBattery,
IOCTL_BATTERY_QUERY_TAG,
&dwWait,
sizeof(dwWait),
&bqi.BatteryTag,
sizeof(bqi.BatteryTag),
&dwOut,
NULL)
&& bqi.BatteryTag)
{////////////////////////////////////////problem around here///////
string  bi;
bqi.InformationLevel = BatteryDeviceName;
if (DeviceIoControl(hBattery,
IOCTL_BATTERY_QUERY_INFORMATION,
&bqi,
sizeof(bqi),
&bi,
sizeof(bi),
&dwOut,
NULL))
{
cout<<bi;

BATTERY_WAIT_STATUS bws = {0};
bws.BatteryTag = bqi.BatteryTag;

BATTERY_STATUS bs;
if (DeviceIoControl(hBattery,
IOCTL_BATTERY_QUERY_STATUS,
&bws,
sizeof(bws),
&bs,
sizeof(bs),
&dwOut,
NULL))
{
if (bs.PowerState & BATTERY_POWER_ON_LINE)
{
dwResult &= ~GBS_ONBATTERY;
}
}
}
}
CloseHandle(hBattery);
}
}
LocalFree(pdidd);
}
}
}
else  if (ERROR_NO_MORE_ITEMS == GetLastError())
{
break;
}
}
SetupDiDestroyDeviceInfoList(hdev);
}

я пытаюсь напечатать имена всех батарей, но когда я запускаю программу, она вообще ничего не печатает, однако она работает, когда я запрашиваю структуру battery_information вместо строки BatteryDeviceName, пожалуйста, помогите

0

Решение

Проблема в том, что в вашем звонке DeviceIoControl неправильно. Вы попадаете в мусор, а когда вы кладете мусор, вы вывозите мусор.

string bi;

if(DeviceIoControl(hBattery,
IOCTL_BATTERY_QUERY_INFORMATION,
bqi,
sizeof(bqi),
&bi,         // Really?!?!?!
sizeof(bi),  // WHAT?!?
&dwOut,
NULL))

Вы передаете адрес std::string Возражать DeviceIoControl, который ничего не знает о std::string и ожидает адрес необработанного буфера, в который он может записать. Вы по крайней мере указываете правильный размер для этого буфера, но даже это в некотором смысле неверно. По сути, когда эта функция возвращается, std::string Это мусор, и доступ к нему может сделать практически все — от сбоя программы до воспроизведения Vivaldi на ваших динамиках.

Попробуйте что-то вроде этого:

WCHAR szBuf[_MAX_PATH] = { 0 }; // In a real program you'd dynamically
// allocate an appropriately sized buffer
// instead.

if(DeviceIoControl(hBattery,
IOCTL_BATTERY_QUERY_INFORMATION,
bqi,
sizeof(bqi),
szBuf,
sizeof(szBuf),
&dwOut,
NULL))
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]