Отключить устройство API
От: _agg  
Дата: 20.09.18 08:03
Оценка:
Всем привет, прошу совета у знающих API установки/отключения/удаления устройств, я никогда не касался этой темы, понадобилось отключить на время драйвер контроллера USB мобильного телефона, через диспетчер устройств без труда можно найти драйвер нажать кнопку "Отключить устройство", но как это сделать с помощью WIN API не знаю, прошу подсказать хотя бы какие функции использовать и может какие-нибудь ссылки на примеры.
Спасибо.
Re: Отключить устройство API
От: okman Беларусь https://searchinform.ru/
Дата: 20.09.18 09:11
Оценка: 11 (2)
Здравствуйте, _agg, Вы писали:

_>...

_> через диспетчер устройств без труда можно найти драйвер нажать кнопку "Отключить устройство", но как это сделать с помощью WIN API

1. Находим устройство с помощью Setup API, см. SetupDiGetClassDevs, SetupDiEnumDeviceInfo и т.д.

2. Заполняем структуру SP_PROPCHANGE_PARAMS, в StateChange пишем DICS_ENABLE (включить) или DICS_DISABLE (отключить).

3. Вызываем SetupDiSetClassInstallParams и затем SetupDiCallClassInstaller с кодом DIF_PROPERTYCHANGE.

4. На системах до Windows Vista, где поддерживаются профили оборудования, SetupDiCallClassInstaller нужно
вызвать дважды: сначала для глобальной конфигурации (DICS_FLAG_GLOBAL), затем для конфигурации
текущего профиля (DICS_FLAG_CONFIGSPECIFIC).

Я когда-то таким способом включал/отключал сетевые адаптеры.

Парочка нюансов:

* разрядность приложения должна совпадать с разрядностью Windows, иначе можно получить ошибку ERROR_IN_WOW64 (0xe0000235).
* для работы нужны права администратора.

Еще можно исходники утилиты devcon посмотреть, она много схожих задач выполняет.
Re[2]: Отключить устройство API
От: _agg  
Дата: 21.09.18 05:07
Оценка:
Спасибо, большое, так то вроде все понятно кроме одного, в моем случае есть идентификатор устройства "\\?\usb#vid_04e8&pid_6860&ms_comp_mtp&samsung_android#6&2ba8483f&0&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}" вот вопрос есть ли такое API которое по этому идентификатору сможет получить SP_DEVINFO_DATA, код:
    static bool DisableDevice(const CString &id, bool enable, CString &err_msg){
        
        const GUID *pDevInterfaceGuid = &GUID_DEVINTERFACE_USB_DEVICE;

        HDEVINFO hDevInfo = SetupDiGetClassDevs(pDevInterfaceGuid, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE);

        SP_DEVINFO_DATA devInfoData = { sizeof(SP_DEVINFO_DATA) };
        BOOL ret=SetupDiOpenDeviceInfo(hDevInfo, id, NULL, DIOD_INHERIT_CLASSDRVS, &devInfoData);
        if (!ret)
            err_msg = GetErrorMessage();

        SP_PROPCHANGE_PARAMS param;

        param.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
        param.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
        param.StateChange = enable ? DICS_ENABLE : DICS_DISABLE;

        param.Scope = DICS_FLAG_CONFIGSPECIFIC;
        param.HwProfile = 0;

        ret=SetupDiSetClassInstallParams(hDevInfo, &devInfoData, &param.ClassInstallHeader, sizeof(param));
        ret=SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &devInfoData);
        return ret ? true : false;
    }


Этот код не работает, вызов SetupDiOpenDeviceInfo возвращает FALSE а GetLastError 0xe0000205(ERROR_INVALID_DEVINST_NAME), ему не нравиться идентификатор, прошу помощи в этом вопросе?
Спасибо
Re[3]: Отключить устройство API
От: _agg  
Дата: 21.09.18 08:36
Оценка:
Я понял какой нужен идентификатор устройства вот эта строка "\\?\usb#vid_04e8&pid_6860&ms_comp_mtp&samsung_android#6&2ba8483f&0&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}" в мсдн называется "Plug and Play ID string for the device", но с этой строкой в качестве идентификатора, метода SetupDiOpenDeviceInfo ругается на идентификатор, если руками взять строку из сведений об оборудовании "путь к экземпляру устройства" ("USB\\VID_04E8&PID_6860\\B882D671") то все отрабатывает, теперь вопрос как имея вот такой ид устройства "\\?\usb#vid_04e8&pid_6860&ms_comp_mtp&samsung_android#6&2ba8483f&0&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}" получить путь к экземпляру устройства не перечисляя все оборудование?
Re[4]: Отключить устройство API
От: okman Беларусь https://searchinform.ru/
Дата: 22.09.18 05:11
Оценка:
Здравствуйте, _agg, Вы писали:

_> теперь вопрос как имея вот такой ид устройства "\\?\usb#vid_04e8&pid_6860&ms_comp_mtp&samsung_android#6&2ba8483f&0&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}" получить путь к экземпляру устройства не перечисляя все оборудование?


Не перечисляя все оборудование — никак, скорее всего.
Твой "ид устройства" — это не более, чем символьная ссылка, которая диспетчером PnP еще забита где-то в реестре, в
одном из стандартных разделов. Ссылку эту можно у Setup API получить, перечисляя интерфейсы с помощью SetupDiEnumDeviceInterfaces, а
затем спрашивая у каждого SetupDiGetDeviceInterfaceDetail.

А Instance ID получается с помощью SetupDiGetDeviceInstanceId.
Re[5]: Отключить устройство API
От: _agg  
Дата: 26.09.18 04:41
Оценка:
Спасибо за помощь вам большое, вот еще вопрос по поводу работы с устройствами, есть интерфейс IPortableDevice, в него регистрируешь указатель на IPortableDeviceEventCallback, и получаешь события с устройства записи/чтения/удаления/извлечения устройства/вставки устройства. Устройства работающие по MTP протоколу шлют все события как положено, но обычные USB flash не шлют событий записи/чтения/удаления объектов на устройстве, это как то настраивается или просто эти события шлются только с устройств работающих по MTP?
Re[6]: Отключить устройство API
От: okman Беларусь https://searchinform.ru/
Дата: 26.09.18 07:58
Оценка:
Здравствуйте, _agg, Вы писали:

_>Спасибо за помощь вам большое, вот еще вопрос по поводу работы с устройствами, есть интерфейс IPortableDevice, в него регистрируешь указатель на IPortableDeviceEventCallback, и получаешь события с устройства записи/чтения/удаления/извлечения устройства/вставки устройства. Устройства работающие по MTP протоколу шлют все события как положено, но обычные USB flash не шлют событий записи/чтения/удаления объектов на устройстве, это как то настраивается или просто эти события шлются только с устройств работающих по MTP?


Если USB-флэшка не определяется как переносное устройство (Portable Devices), то
работать с ним через WPD API не получится.
Re[7]: Отключить устройство API
От: _agg  
Дата: 26.09.18 11:33
Оценка:
IPortableDevice::GetDevices флэшку в списке устройств видит, и после регистрации указателя на IPortableDeviceEventCallback извлекаешь флэшку приходит событие извлечения устройства, после того как она уже зарегистрирована при дальнейшей вставке этой же флэшки приходит событие добавления устройства в IPortableDeviceEventCallback::Event, но событий вставки/удаления/чтения в этот интерфейс не приходит, по идее если поддерживаются события вставки/извлечения флэшки то и остальные должны поддерживаться, поэтому и возник вопрос может я просто не умею готовить его(IPortableDevice) как положено что бы приходили все события.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.