У меня возникли проблемы со структурами, используемыми для получения информации об устройстве. Из того, что я понимаю, довольно сложно правильно установить 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
вызвать ту же ошибку
Любая помощь очень ценится!
Похоже, ваш interfaceData
буфер слишком мал.
Проверьте документация для DeviceInterfaceDetailData
аргумент SetupDiGetDeviceInterfaceDetail
снова.
Если вы хотите получить больше информации о разработке драйверов, я рекомендую книгу 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)
по ошибке.