Здравствуйте, Cyr, Вы писали:
Cyr>Появилась такая задача — работа с USBшной камерой...
Cyr>иногда камера входит в непонятный режим, что требует ее перезапуска...
Cyr>самый простой вариант — это сбросить питание, благо питается по USB...
Cyr>Вопрос такой — как это сделать?
Хмм... Перезапуск устройства можно сделать из USER-mode. Вот фрагмент кода из SniffUSB:
//начало кода//
HDEVINFO m_devInfo;
SP_DEVINFO_DATA m_devInfoData;
int m_nDevIndex;
// ..............
// здесь вы находите m_devInfo — устройства, которые удовлетворяют вашим требованиям
// m_devInfo = SetupDiGetClassDevs (...
//
//m_nDevIndex — индекс устройства в m_devInfo.
// ..............
SP_PROPCHANGE_PARAMS params;
memset(¶ms, 0, sizeof(SP_PROPCHANGE_PARAMS));
params.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
params.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
params.StateChange = DICS_PROPCHANGE;
params.Scope = DICS_FLAG_CONFIGSPECIFIC;
params.HwProfile = 0; // current profile
if(!SetupDiSetClassInstallParams(m_devInfo, &m_devInfoData,
(PSP_CLASSINSTALL_HEADER) ¶ms,
sizeof(SP_PROPCHANGE_PARAMS)))
{
TRACE("in RestartDevice(): couldn't set the install parameters!");
TRACE(" error: %u\n", GetLastError());
return FALSE;
}
// restart the device
if(!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, m_devInfo, &m_devInfoData))
{
TRACE("in RestartDevice(): call to class installer (STOP) failed!");
TRACE(" error: %u\n", GetLastError() );
return FALSE;
}
//конец кода//
А вообще, стоит посмотреть DevCon от Microsoft — консольный аналог Менеджера Устройств. Исходники есть в XP DDK. Он позволяет удалять усройства, рестартовать, проверять, нет ли новых подключенных и т.д.
У меня вот другой вопрос возник: как сделать рестарт девайса из kernel-mode (из фильтр драйвера). Например, повесить такой фильтр где-то на USB и отслеживать контролы к конкретному USB устройству, и ежели встречается IOCTL_INTERNAL_USB_CYCLE_PORT, отрубить питание самому а потом врубить. Только вот проблема, если фильтр будет висеть на самом устройстве, он выгрузиться (насколько я понял) при отключении питания и некому будет оное включить. Так что мне сдаеться, надо чтоб фильтр висел на USB hub-ах и если на одном его порту висит мое устройство и к этому устройству идет IOCTL_INTERNAL_USB_CYCLE_PORT, вырубить/врубить питание на порт.
Что в свою очередь пробуждает вопросы:
Как USB hub может узнать, на каком порту висит мое устройство?
Как USB hub может отловить, пришло ли к моему устройству IOCTL_INTERNAL_USB_CYCLE_PORT?
И наконец, как вообще отрубается питание в kernel-mode?
Regards,
iGNER