2012-05-19 51 views
0

我試圖通過使用SetupDiGetDeviceInterfaceDetail()函數來獲取設備的路徑,但每當我調用它時就會崩潰。我一直在研究這個問題已經超過了12個小時,但仍然無法找出它有什麼問題......有人可以看看他們是否能找到真正導致這種情況發生的原因嗎?繼承人的代碼:當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定義:

獲取所需的緩衝區大小。用一個NULLDeviceInterfaceDetailData指針,一個DeviceInterfaceDetailDataSize爲零和一個有效的RequiredSize變量來調用SetupDiGetDeviceInterfaceDetail。 作爲對此調用的響應,此函數在RequiredSize返回所需的緩衝區大小,並且在GetLastError返回ERROR_INSUFFICIENT_BUFFER時失敗。

因此,在ERROR_INSUFFICIENT_BUFFER錯誤之後只使用requiredSize值。

+0

感謝您的答覆。但是,我已經在第二個SetupDiGetDeviceInterfaceDetail函數中完成了這個工作。但它仍然沒有運氣。 – Danny

1

找到這個主題後,我想分享我的問題,即使用完全相同的源代碼,我從調用中獲得了ERROR_INVALID_USER_BUFFER。

的原因是該行:

deviceInterfaceDetailedData->cbSize = 
     sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); 

這對我quadbyte對準編譯器設定值8而不是所需的值爲5

相關問題