2012-05-19 3 views
0

SetupDiGetDeviceInterfaceDetail() 함수를 사용하여 장치의 경로를 가져 오려고하는데 호출 할 때마다 충돌이 발생합니다. 나는 12 시간 이상 동안이 일을 해왔지만 여전히 무엇이 잘못되었는지를 알 수 없었다. 실제로 어떤 일이 실제로 일어나고 있는지를 알 수 있는지 누군가가 볼 수 있는가? Heres는 코드 :SetupDiGetDeviceInterfaceDetail이 호출되면 프로그램이 충돌합니다.

//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가 표시됩니다. 점점 더 혼란스러워지고 있습니다 ... 내가 제공 한 매개 변수가 어떻게 잘못 되었습니까? 그냥 말이되지 않습니다.

필요한 버퍼 크기를 가져옵니다 : 유일한 차이점은, 그렇지 않으면 내가

답변

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

, 너무 오류가있을 수 있지만, 이것은 원래의 질문에 대한 대답.

+0

답장을 보내 주셔서 감사합니다. SetupDiGetDeviceInterfaceDetail (deviceInfoSet, & deviceInterfaceData, nullptr, 0, & bufferLength, nullptr);을 입력했습니다. 당신이 보여 줬던 것처럼 그것은 심지어 그것을 통과시키지 않았다. 코드에서 설명한대로 122 (ERROR_INSUFFICIENT_BUFFER)를 반환했습니다. ( – Danny

+0

죄송합니다, nvm. 코드 작동 : P 실수로 뭔가 잘못 입력했습니다 : D. – Danny

1

이 MSDN의 정의에 따라 있습니다 ... 액세스 위반 오류가 발생합니다 때문에 내가 대신 포인터의 참조에 전달됩니다. SetupDiGetDeviceInterfaceDetail을 NULLDeviceInterfaceDetailData 포인터, DeviceInterfaceDetailDataSize 0 및 유효한 RequiredSize 변수와 함께 호출하십시오. 이 호출에 대한 응답으로이 함수는 RequiredSize에 필요한 버퍼 크기를 반환하고 GetLastError가 ERROR_INSUFFICIENT_BUFFER를 반환하여 실패합니다.

그래서 ERROR_INSUFFICIENT_BUFFER 오류 다음에 requiredSize 값을 사용하십시오.

+0

감사를 설정

deviceInterfaceDetailedData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); 

. 그러나 두 번째 SetupDiGetDeviceInterfaceDetail 함수 내에서 이미 수행했습니다. 그러나 여전히 운이 없다. – Danny

1

이 주제를 찾았 으면 정확히 동일한 출처를 사용하여 통화에서 ERROR_INVALID_USER_BUFFER이 (가) 발생하는 문제를 공유하고 싶습니다.

이유

라인이었다 내 quadbyte 정렬 컴파일러에 값 8 대신 필요한 값 응답 5.

관련 문제