0

SetupDiGetDeviceInterfaceDetail() 関数を使用してデバイスのパスを取得しようとしていますが、呼び出すたびにクラッシュします。私はこれに12時間以上取り組んできましたが、まだ何が問題なのかを見つけることができませんでした.これが実際に起こっている原因を誰かが見つけられるかどうかを確認できますか? コードは次のとおりです。

//DeviceManager.h
#include <windows.h>
//#include <hidsdi.h>
#include <setupapi.h>
#include <iostream>
#include <cfgmgr32.h>
#include <tchar.h>
#include <devpkey.h>
#include <string>

extern "C"{
    #include <hidsdi.h>
}

//#pragma comment (lib, "setupapi.lib")

class DeviceManager
{
public:
    DeviceManager();
    ~DeviceManager();

    void ListAllDevices();
    void GetDeviceHandler();

    //HANDLE PSMove;
    //byte reportBuffer[57];
    GUID guid;
//private:
    HDEVINFO deviceInfoSet;             //A list of all the devices
    SP_DEVINFO_DATA deviceInfoData;     //A device from deviceInfoSet

    SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
    SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailedData;
};

//DeviceManager.cpp
#include"DeviceManager.h"

DeviceManager::DeviceManager()
{
    //deviceInterfaceData = new SP_DEVICE_INTERFACE_DATA;
    //deviceInterfaceDetailedData = new SP_DEVICE_INTERFACE_DETAIL_DATA;

    HidD_GetHidGuid(&guid);
    deviceInfoSet = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); //Gets all Devices
    GetDeviceHandler();
}

DeviceManager::~DeviceManager()
{
}

void DeviceManager::ListAllDevices()
{
    DWORD deviceIndex = 0;

    deviceInfoData.cbSize = sizeof(deviceInfoData);

    while(SetupDiEnumDeviceInfo(deviceInfoSet, deviceIndex, &deviceInfoData))
    {
        deviceInfoData.cbSize = sizeof(deviceInfoData);

        ULONG tcharSize;
        CM_Get_Device_ID_Size(&tcharSize, deviceInfoData.DevInst, 0);
        TCHAR* deviceIDBuffer = new TCHAR[tcharSize];   //the device ID will be stored in this array, so the tcharSize needs to be big enough to hold all the info.
                                                        //Or we can use MAX_DEVICE_ID_LEN, which is 200
        CM_Get_Device_ID(deviceInfoData.DevInst, deviceIDBuffer, MAX_PATH, 0); //gets the devices ID - a long string that looks like a file path.

        std::cout << deviceIDBuffer << std::endl;

        deviceIndex++;
    }
}

void DeviceManager::GetDeviceHandler()
{
     DWORD deviceIndex = 0;

SP_DEVINFO_DATA deviceInfoData;
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailedData;

deviceInfoData.cbSize = sizeof(deviceInfoData);

while(SetupDiEnumDeviceInfo(deviceInfoSet, deviceIndex, &deviceInfoData))
{
    TCHAR deviceID[MAX_DEVICE_ID_LEN];

    CM_Get_Device_ID(deviceInfoData.DevInst, deviceID, MAX_DEVICE_ID_LEN, 0);

    //std::cout << deviceID << std::endl;

    deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
    if(SetupDiEnumDeviceInterfaces(deviceInfoSet, &deviceInfoData, &guid, 0, &deviceInterfaceData))
    {
        DWORD bufferLength = 0;
        //deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
        deviceInterfaceData.cbSize = 2048;
        //std::cout << "it works not" << std::endl;

        if(SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, NULL, 0, &bufferLength, NULL))
        {
            //deviceInterfaceData.cbSize = sizeof(bufferLength);
            std::cout << "It works!" << std::endl;
        }
        else
        {
            std::cout << GetLastError() << std::endl;
        }

    }
    else
    {
        //std::cout << GetLastError() << std::endl;
    }


    deviceIndex++;
}

}

//mainapp.cpp
#pragma once

int main()
{
DeviceManager deviceManager;

return 0;
}

SetupDiGetDeviceInterfaceDetail 関数は、DeviceManager の GetDeviceHandler() 関数で呼び出されます。

助けてください。ありがとう。

更新: 最初の SetupDiGetDeviceInterfaceDetail で失敗し、122 エラー (ERROR_INSUFFICIENT_BUFFER) を返していることがわかりました。しかし、私は必要なバッファサイズを取得しようとしているだけなので、どうすればよいでしょうか??

更新 2: そうです、deviceInterfaceData.cbsize を 2048 (テスト用の巨大なスペース) に設定して関数を少し変更し (上記のコードを参照)、ERROR_INVALID_PARAMETER を取得しています。これはますます混乱しています...どうして私が与えたパラメータが無効になるのでしょうか? 意味がありません。唯一の違いは、ポインターの代わりに参照を渡したということです。そうしないと、アクセス違反エラーが発生するためです...

4

3 に答える 3

3

このトピックを見つけたので、まったく同じソースを使用して呼び出しから ERROR_INVALID_USER_BUFFER を取得したという問題を共有したいと思います。

その理由は次の行でした。

deviceInterfaceDetailedData->cbSize =
        sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);

クアッドバイト アライン コンパイラでは、必要な値 5 の代わりに値 8 を設定します。

于 2014-02-10T14:34:23.203 に答える
1

これは、MSDN の定義によると次のとおりです。

必要なバッファ サイズを取得します。NULLDeviceInterfaceDetailData ポインター、0 の DeviceInterfaceDetailDataSize、および有効な RequiredSize 変数を指定して、SetupDiGetDeviceInterfaceDetail を呼び出します。このような呼び出しに応答して、この関数は RequiredSize で必要なバッファー サイズを返し、GetLastError が ERROR_INSUFFICIENT_BUFFER を返すことで失敗します。

したがって、ERROR_INSUFFICIENT_BUFFER エラーが発生した後は、requiredSize 値を使用してください。

于 2012-05-20T14:48:49.443 に答える
1

にメモリを適切に割り当てていませんSP_DEVICE_INTERFACE_DETAIL_DATA

これを削除して、ブロックSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailedData;内に配置してみてください。if

    // Get the required bufferLength
    SetupDiGetDeviceInterfaceDetail(deviceInfoSet,
                                    &deviceInterfaceData,
                                    nullptr,
                                    0,
                                    &bufferLength,
                                    nullptr);
    if(GetLastError() != ERROR_INSUFFICIENT_BUFFER)
    {
        std::cout << "Failed to get bufferLength.  Error "
                  << GetLastError() << '\n';
        return;
    }

    // Create device interface detailed information struct pointer
    // and allocate memory to it.
    PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailedData(nullptr);
    deviceInterfaceDetailedData =
        static_cast<PSP_INTERFACE_DEVICE_DETAIL_DATA>(malloc(bufferLength));
    if(deviceInterfaceDetailedData == nullptr)
    {
        std::cout << "Failed to allocate memory.  Error "
                  << GetLastError() << '\n';
        return;
    }
    deviceInterfaceDetailedData->cbSize =
        sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);

    // Get detailed information
    if(SetupDiGetDeviceInterfaceDetail(deviceInfoSet,
                                       &deviceInterfaceData,
                                       deviceInterfaceDetailedData,
                                       bufferLength,
                                       &bufferLength,
                                       nullptr))
    {
        //deviceInterfaceData.cbSize = sizeof(bufferLength);
        std::cout << "It works!" << std::endl;
    }
    else
    {
        std::cout << GetLastError() << std::endl;
    }

    free(deviceInterfaceDetailedData);

コードの残りの部分は見ていません。エラーもあるかもしれませんが、これは元の質問に答えます。

于 2012-05-20T17:02:54.463 に答える