0

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);
}

すべてのバッテリーの名前を印刷しようとしていますが、プログラムを実行しても何も印刷されませんが、文字列 BatteryDeviceName の代わりに battery_information 構造を要求すると機能します助けてください

4

1 に答える 1

3

問題は、あなたの呼び出し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書き込み可能なrawバッファのアドレスを期待します。少なくともそのバッファに適切なサイズを指定しますが、それでもある意味で間違っています。基本的に、その関数が戻ったとき、それ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))
于 2013-02-09T00:27:32.327 に答える