Повреждение стека с помощью структур SetupDiXxx

У меня возникли проблемы со структурами, используемыми для получения информации об устройстве. Из того, что я понимаю, довольно сложно правильно установить 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_DATA а также SP_DEVICE_INTERFACE_DETAIL_DATA вызвать ту же ошибку

Любая помощь очень ценится!

0

Решение

Похоже, ваш interfaceData буфер слишком мал.

Проверьте документация для DeviceInterfaceDetailData аргумент SetupDiGetDeviceInterfaceDetail снова.

2

Другие решения

Если вы хотите получить больше информации о разработке драйверов, я рекомендую книгу USB Complete, Я исправил проблему, основываясь на их объяснении. Вопрос заключается в следующем:

Сначала получите размер буфера:

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

Затем выделите PSP_DEVICE_INTERFACE_DETAIL_DATA структура вручную с использованием malloc на основе размера, который был возвращен:

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

обратите внимание на P перед PSP_DEVICE_INTERFACE_DETAIL_DATA, Это семантика Microsoft для этого API. Это обозначает указатель; что-то действительно легко пропустить при просмотре документации (если вы также пропустите ->)

SetupDiGetDeviceInterfaceDetail Функция возвращает размер всей структуры, поэтому вам нужно выделить его под этот размер. Я видел примеры, которые пытаются увеличить размер, пока ошибка не исчезнет. Такой подход неправильный … по многим причинам. Получить размер от SetupDiGetDeviceInterfaceDetail а затем выделить весь PSP_DEVICE_INTERFACE_DETAIL_DATA блок памяти на основе этого размера. Не забудьте установить cbSize в размер структуры SP_DEVICE_INTERFACE_DETAIL_DATA

Еще раз обратите внимание на P в соглашениях об именах, потому что это легко получить sizeof(PSP_DEVICE_INTERFACE_DETAIL_DATA) по ошибке.

1

По вопросам рекламы [email protected]