堆栈损坏使用SetupDiXxx结构

时间:2015-02-20 00:54:28

标签: c++ windows-8 device-driver hid

我在使用用于获取设备信息的结构时遇到了一些麻烦。根据我的理解,正确设置cbSize有点棘手,因此API正在将数据写入超出预期的位置(导致堆栈损坏)。到目前为止,我有以下代码:

GUID guid;
HidD_GetHidGuid(&guid);

HDEVINFO info;
info = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

SP_DEVINFO_DATA DeviceInfoData;

memset(&DeviceInfoData, 0, sizeof(SP_DEVINFO_DATA));
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);


int deviceIndex = 0;
while (SetupDiEnumDeviceInfo(info, deviceIndex++, &DeviceInfoData))
{
    SP_INTERFACE_DEVICE_DATA data;
    data.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);

    int interfaceIndex = 0;


    while (SetupDiEnumDeviceInterfaces(info, &DeviceInfoData, &guid, interfaceIndex++, &data))
    {

        //https://msdn.microsoft.com/en-us/library/windows/hardware/ff551120%28v=vs.85%29.aspx
        //Get the required buffer size. Call SetupDiGetDeviceInterfaceDetail with a NULLDeviceInterfaceDetailData pointer, 
        //a DeviceInterfaceDetailDataSize of zero, and a valid RequiredSize variable. In response to such a call, this function
        //returns the required buffer size at RequiredSize and fails with GetLastError returning ERROR_INSUFFICIENT_BUFFER.

        SP_DEVICE_INTERFACE_DETAIL_DATA interfaceData;
        interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

        DWORD bufferSize = 0;
        SetupDiGetDeviceInterfaceDetail(info, &data, NULL, 0, &bufferSize, nullptr);

        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
        {
            //Call the function again
            SetupDiGetDeviceInterfaceDetail(info, &data, &interfaceData, bufferSize, NULL, &DeviceInfoData);

            DWORD error = GetLastError();
            if (error != ERROR_SUCCESS)
            {
                printf("Could not obtain device interface details. Error: %d \n", error);
            }
        }
    }

我得到的错误是:

    Run-Time Check Failure #2 - Stack around the variable 'DeviceInfoData' was corrupted.

虽然我看到SP_INTERFACE_DEVICE_DATASP_DEVICE_INTERFACE_DETAIL_DATA导致同样的错误

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:2)

看起来你的interfaceData缓冲区太小了。

再次检查the documentation DeviceInterfaceDetailData的{​​{1}}参数。

答案 1 :(得分:1)

如果您想获得有关驱动程序开发的更多信息,我建议您使用本书USB Complete。我根据他们的解释修正了这个问题。问题如下:

首先,获取缓冲区大小:

SetupDiGetDeviceInterfaceDetail(info, &data, NULL, 0, &bufferSize, nullptr);

然后,根据返回的大小使用malloc手动分配PSP_DEVICE_INTERFACE_DETAIL_DATA结构:

PSP_DEVICE_INTERFACE_DETAIL_DATA interfaceData;
interfaceData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

注意P前面的PSP_DEVICE_INTERFACE_DETAIL_DATA。这是此API的Microsofts语义。它代表指针;在查看文档时(如果您还错过->

,很容易错过

SetupDiGetDeviceInterfaceDetail函数返回整个结构的大小,因此您需要将其分配给该大小。我已经看到过尝试增加大小的示例,直到错误消失为止。出于很多原因,这种做法是错误的。从SetupDiGetDeviceInterfaceDetail获取大小,然后根据该大小分配整个PSP_DEVICE_INTERFACE_DETAIL_DATA内存块。不要忘记将cbSize设置为结构SP_DEVICE_INTERFACE_DETAIL_DATA

的大小

请再次注意命名约定中的P,因为它很容易错误地获取sizeof(PSP_DEVICE_INTERFACE_DETAIL_DATA)