windows 设备管理器中的设备控制
控制主要功能程序:
控制基本设备:
GUID guid;
BOOL StateChange(HDEVINFO hDevInfo,DWORD dwNewState, DWORD dwDevID)
{
SP_PROPCHANGE_PARAMS PropChangeParams;
SP_DEVINFO_DATA DevInfoData = {sizeof(SP_DEVINFO_DATA)};
SP_DEVINSTALL_PARAMS devParams;
//查询设备信息
if (!SetupDiEnumDeviceInfo( hDevInfo, dwDevID, &DevInfoData))
{
OutputDebugString("SetupDiEnumDeviceInfo FAILED");
return FALSE;
}
//设置设备属性变化参数
PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
PropChangeParams.Scope = DICS_FLAG_GLOBAL; //使修改的属性保存在所有的硬件属性文件
PropChangeParams.StateChange = dwNewState;
PropChangeParams.HwProfile = 0;
//改变设备属性
if (!SetupDiSetClassInstallParams( hDevInfo,
&DevInfoData,
(SP_CLASSINSTALL_HEADER *)&PropChangeParams,
sizeof(PropChangeParams)))
{
OutputDebugString("SetupDiSetClassInstallParams FAILED");
return FALSE;
}
PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
PropChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC;//使修改的属性保存在指定的属性文件
PropChangeParams.StateChange = dwNewState;
PropChangeParams.HwProfile = 0;
//改变设备属性并调用安装服务
if (!SetupDiSetClassInstallParams( hDevInfo,
&DevInfoData,
(SP_CLASSINSTALL_HEADER *)&PropChangeParams,
sizeof(PropChangeParams)) ||
!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &DevInfoData))
{
int nErr = GetLastError();
OutputDebugString("SetupDiSetClassInstallParams or SetupDiCallClassInstaller FAILED");
return FALSE;
}
else
{
//判断是否需要重新启动
devParams.cbSize = sizeof(devParams);
if (!SetupDiGetDeviceInstallParams( hDevInfo, &DevInfoData, &devParams))
{
OutputDebugString("SetupDiGetDeviceInstallParams FAILED");
return FALSE;
}
if (devParams.Flags & (DI_NEEDRESTART|DI_NEEDREBOOT))
{
OutputDebugString("Need Restart Computer");
return TRUE;
}
return TRUE;
}
}
注意事项:
1.32位系统和64位系统对应要编译不同的程序。Setup..序列函数区分系统的
2. win7以后的系统开发时,一些API函数需要程序有管理员权限 如Setup..族,编译时 项目-属性-连接器-清单文件-UAC执行级别 选择:requireAdministrator (/level='requireAdministrator') ,程序就会以管理员权限运行。
3.设备句柄在程序中被占用时,会出现禁用函数成功返回。需要重启电脑生效的情况。实际是禁用不成功,目前没有找到问题,采用函数setup_remove移除了禁用失败的设备(setup_remove在设备被占用时移除也会失败)。
2018年7月11日14:15:21 BEGIN
找到新的方法了:使用DeviceIoControl弹出U盘存储设备
#define LOCK_TIMEOUT 10000 // 10 Seconds
#define LOCK_RETRIES 20
/***************
Function: UninstallUsb
Description: 根据盘符将usb设备弹出
Parameters:
discId 要弹出的盘符
Returns:
-1 失败
0 成功
***************/
int CDeviceMng::UninstallUsb(char *discId)
{
DWORD accessMode = GENERIC_WRITE | GENERIC_READ;
DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
HANDLE hDevice;
DWORD retu = 0;
DWORD dwError;
DWORD dwBytesReturned;
DWORD dwSleepAmount;
int nTryCount;
char szDriv[10];
bool bResult;
if(discId == NULL){
return 0;
}
dwSleepAmount = LOCK_TIMEOUT/LOCK_RETRIES;
sprintf(szDriv,"\\\\.\\%s:",discId);
hDevice = CreateFile(szDriv,accessMode,shareMode,NULL,OPEN_EXISTING,0,NULL);
if(hDevice == INVALID_HANDLE_VALUE){
//printf("uninstallusb createfile failed error:%d\n",GetLastError());
return -1;
}
#if 0
//此循环是用于锁定要弹出的U盘设备,如果U盘在使用,则循环等待
// Do this in a loop until a timeout period has expired
for(nTryCount = 0;nTryCount < LOCK_RETRIES;nTryCount++){
if(DeviceIoControl(hDevice,FSCTL_LOCK_VOLUME,NULL,0,NULL,0,&dwBytesReturned,NULL)){
break;
}
}
//卸载U盘卷,不论是否在使用
dwBytesReturned = 0;
if(!DeviceIoControl(hDevice,FSCTL_DISMOUNT_VOLUME,NULL,0,NULL,0,&dwBytesReturned,NULL)){
printf("deviceIoConrol FSCTL_DISMOUNT_VOLUME failed\n");
}
#endif
dwBytesReturned = 0;
PREVENT_MEDIA_REMOVAL PMRBuffer;
PMRBuffer.PreventMediaRemoval = FALSE;
if(!DeviceIoControl(hDevice,IOCTL_STORAGE_MEDIA_REMOVAL,&PMRBuffer,sizeof(PREVENT_MEDIA_REMOVAL),NULL,0,&dwBytesReturned,NULL)){
//DEBUG_LOG("DeviceIoControl IOCTL_STORAGE_MEDIA_REMOVAL failed:%d\n",GetLastError());
}
bResult = DeviceIoControl(hDevice,IOCTL_STORAGE_EJECT_MEDIA,NULL,0,NULL,0,&retu,NULL);
if(!bResult){
CloseHandle(hDevice);
//DEBUG_LOG("uninstallusb DeviceIoControl failed error:%d\n",GetLastError());
return -1;
}
CloseHandle(hDevice);
return 0;
}
2018年7月11日14:15:21 END
指定U盘设备禁用
代码:
BOOL CEnableUsbDeviceApp::CtrlDevice( const TCHAR* lpszInterfaceGuid,const TCHAR* lpszDevicePath,const TCHAR* lpszAction )
{
GUID guid;
HDEVINFO info;
DWORD devindex;
SP_INTERFACE_DEVICE_DATA ifdata;
BOOL bRet=FALSE;
if (!lpszInterfaceGuid || !lpszDevicePath || !lpszAction)
{
return FALSE;
}
#ifdef _UNICODE
RPC_STATUS status=UuidFromString((RPC_WSTR)lpszInterfaceGuid,&guid);
#else
RPC_STATUS status=UuidFromString((RPC_CSTR)lpszInterfaceGuid,&guid);
#endif
if(status!=RPC_S_OK) return FALSE;
info = SetupDiGetClassDevs(&guid,NULL,NULL,DIGCF_ALLCLASSES|DIGCF_INTERFACEDEVICE);
if(INVALID_HANDLE_VALUE==info)
{
return FALSE;
}
ifdata.cbSize = sizeof(ifdata);
for(devindex = 0 ; SetupDiEnumDeviceInterfaces(info,NULL,&guid,devindex,&ifdata) ; ++devindex)
{
DWORD needed=0;
PSP_INTERFACE_DEVICE_DETAIL_DATA detail=NULL;
SP_DEVINFO_DATA did;
SetupDiGetDeviceInterfaceDetail(info,&ifdata,NULL,0,&needed,NULL);
if(!needed)
{
continue;
}
detail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)new char[needed+2];
if(detail==NULL)
{
continue;
}
detail->cbSize=sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
memset(&did,0x00,sizeof(SP_DEVINFO_DATA));
did.cbSize = sizeof(SP_DEVINFO_DATA);
if(!SetupDiGetDeviceInterfaceDetail(info,&ifdata,detail,needed,&needed,&did))
{
delete[](char*)detail;
detail=NULL;
continue;
}
if (_tcsicmp(detail->DevicePath,lpszDevicePath)==0)
{
DWORD Status, Problem;
if (CR_SUCCESS == CM_Get_DevNode_Status(&Status, &Problem,did.DevInst,0))
{
if (_tcsicmp(lpszAction,_T("eject"))==0)
{
//if (Status & DN_REMOVABLE)
{
PNP_VETO_TYPE VetoType = PNP_VetoTypeUnknown;
TCHAR VetoName[MAX_PATH];
VetoName[0] = 0;
// get drives's parent, e.g. the USB bridge, the SATA port, an IDE channel with two drives!
DEVINST DevInstParent = 0;
CONFIGRET res = CM_Get_Parent(&DevInstParent, did.DevInst, 0);
for ( long tries=1; tries<=3; tries++ ) // sometimes we need some tries...
{
VetoName[0] = 0;
res = CM_Request_Device_Eject(DevInstParent, &VetoType, VetoName, MAX_PATH, 0);
if(res!=CR_SUCCESS)
{
MyoutputDebugString(_T("CM_Request_Device_Eject call fail disable"));
res = CM_Query_And_Remove_SubTree(DevInstParent, &VetoType, VetoName, MAX_PATH, CM_REMOVE_NO_RESTART); // CM_Query_And_Remove_SubTreeA is not implemented under W2K!
}
//MyoutputDebugString(_T("CM_Query_And_Remove_SubTree call fail disable"));
if (res==CR_SUCCESS && VetoType==PNP_VetoTypeUnknown)
{
MyoutputDebugString(_T("禁用成功"));
bRet=TRUE;
break;
}
MyoutputDebugString(_T("禁用3次循环"));
Sleep(500); // required to give the next tries a chance!
}
//如果退出仍然失败,那么禁用
if (!bRet)
{
MyoutputDebugString(_T("如果退出仍然失败,那么禁用"));
SP_PROPCHANGE_PARAMS PropChangeParams;
PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
PropChangeParams.StateChange =DICS_DISABLE;
PropChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC;
PropChangeParams.HwProfile = 0;
if(SetupDiSetClassInstallParams(info,&did,(SP_CLASSINSTALL_HEADER *)&PropChangeParams,sizeof(PropChangeParams)))
{
MyoutputDebugString(_T("SetupDiSetClassInstallParams call successful disable"));
if (SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,info,&did))
{
MyoutputDebugString(_T("SetupDiCallClassInstaller call successful disable"));
bRet=TRUE;
}
}
}
}
}
else if (_tcsicmp(lpszAction,_T("enable"))==0)
{
if ((Status & DN_HAS_PROBLEM) && (Problem==CM_PROB_DISABLED))
{
SP_PROPCHANGE_PARAMS PropChangeParams;
PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
PropChangeParams.StateChange =DICS_ENABLE;
PropChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC;
PropChangeParams.HwProfile = 0;
if(SetupDiSetClassInstallParams(info,&did,(SP_CLASSINSTALL_HEADER *)&PropChangeParams,sizeof(PropChangeParams)))
{
MyoutputDebugString(_T("SetupDiSetClassInstallParams call successful enable"));
if (SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,info,&did))
{
MyoutputDebugString(_T("SetupDiCallClassInstaller call successful enable"));
bRet=TRUE;
}
}
}
}
else if (_tcsicmp(lpszAction,_T("disable"))==0)
{
if (!((Status & DN_HAS_PROBLEM) && (Problem==CM_PROB_DISABLED)))
{
SP_PROPCHANGE_PARAMS PropChangeParams;
//test
设置设备属性变化参数
PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
PropChangeParams.Scope = DICS_FLAG_GLOBAL; //使修改所有的硬件属性文件
PropChangeParams.StateChange = DICS_DISABLE;
PropChangeParams.HwProfile = 0;
//改变设备属性
if (SetupDiSetClassInstallParams( info,
&did,
(SP_CLASSINSTALL_HEADER *)&PropChangeParams,
sizeof(PropChangeParams)))
{
MyoutputDebugString(_T("SetupDiSetClassInstallParams DICS_FLAG_GLOBAL successful"));
//return FALSE;
}
//test end
PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
PropChangeParams.StateChange =DICS_DISABLE;
PropChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC;
PropChangeParams.HwProfile = 0;
if(SetupDiSetClassInstallParams(info,&did,(SP_CLASSINSTALL_HEADER *)&PropChangeParams,sizeof(PropChangeParams)))
{
MyoutputDebugString(_T("SetupDiSetClassInstallParams call successful disable"));
if (SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,info,&did))
{
MyoutputDebugString(_T("SetupDiCallClassInstaller call successful disable"));
bRet=TRUE;
}
}
//test
SP_DEVINSTALL_PARAMS devParams;
devParams.cbSize = sizeof(devParams);
if (!SetupDiGetDeviceInstallParams( info, &did, &devParams))
{
MyoutputDebugString(_T("SetupDiGetDeviceInstallParams FAILED"));
continue;
}
if (devParams.Flags & (DI_NEEDRESTART|DI_NEEDREBOOT))
{
OutputDebugString(_T("Need Restart Computer"));
if(SetupDiRemoveDevice(info,&did)) //禁用不成功就移除U盘
{
OutputDebugString(_T("SetupDiRemoveDevice successful"));
}
}
//test end
}
}
}
delete[](char*)detail;
detail=NULL;
needed=0;
break;
}
else
{
delete[](char*)detail;
detail=NULL;
continue;
}
}
SetupDiDestroyDeviceInfoList(info);
return bRet;
}
U盘禁用与设备禁用是一样的 ,这里用设备实例路径来区分指定U盘
windows 设备管理器中的设备控制相关推荐
- Windows设备管理器中的错误代码
适用于: Windows 10 Pro released in July 2015,Windows 10 Enterprise released in July 2015,Windows 8 概要 本 ...
- windows设备管理器中找不到独立显卡
RT. 我的电脑是Thinkpad R400 2784 A42,独立显卡是ATI的HD3400系列.曾经到联想thinkpad官方维修店换了主板.现在使用everst或者是驱动精灵或者是驱动大师进行检 ...
- 设置 DevMgr_Show_NonPresent_Devices 令未连接的历史设备在 Windows 设备管理器中现形
转自:http://blogs.itecn.net/blogs/alexis/archive/2011/07/07/How-to-show-NonPresent-Devices-in-Device-M ...
- windows10中如何在d盘新建kaoshi.log文件_命令行备份Windows 10驱动amp;设备管理器中安装驱动。...
一. 为何需要备份驱动. 1. 现在电脑驱动的一些情况: Windows 10系统安装好后,系统会自动在网络上查找合适的驱动并下载安装. 此外,多数电脑厂商都已提供自家的驱动管理软件,用以对驱动进行统 ...
- win10计算机设备感叹号,Win10资源管理器无法显示iphone,设备管理器中存在黄色感叹号。...
1.现象:之前iphone 6s正常连接PC,资源管理器中有盘符,可以查看照片.突然有一天盘符无法显示,设备管理器中"其他设备"中应该是iphone的部分显示"未知设备& ...
- 自动识别查找特定的串口号 比如设备管理器中Modem属性里的串口 按这个方法可以获取设备管理器任意信息。C++
1.目标: 自动识别查找特定的串口号 2.注册表里搜串口号 设备管理器中所有的信息都在注册表中有,那么我直接在注册表里搜COM143. 搜到了这个,但这里有2个名称key相同的.后面193,192还是 ...
- windows设备管理器_如何打开Windows设备管理器?
windows设备管理器 Windows Device Manager is used to list hardware and software devices in the current sys ...
- 计算机设备管理器怎么删鼠标,在电脑的设备管理器中怎么查看鼠标设备
在电脑的设备管理器中怎么查看鼠标设备 腾讯视频/爱奇艺/优酷/外卖 充值4折起 今天给大家介绍一下在电脑的设备管理器中怎么查看鼠标设备的具体操作步骤. 1. 首先打开电脑,进入桌面,找到桌面上的此电脑 ...
- 设备管理器中:红叉问号感叹号的涵义
设备管理器是管理计算机硬件设备的工具,我们可以借助设备管理器查看计算机中所安装的硬件设备.设置设备属性.安装或更新驱动程序.停用或卸载设备,可设备管理器常会出现些问题符号如:红叉.问号.感叹号等. 在 ...
最新文章
- 卷积神经网络模型可解释性
- 浏览器兼容性--IE11以及Edge等下载文件的中文名出现乱码,前后端解决方案
- 测试mysql安装成功_MySQL安装之“测试”
- 尝试.Net Core—使用.Net Core + Entity FrameWork Core构建WebAPI(一)
- Hive中实现有序,有序concat拼接,有序集合,hive方法操作命令,与自带方法列表
- lua中元素的下标是从1开始的
- hdu 2141 Can you find it(二分)
- visual studio installer可以卸载吗_技术帖 | 这些宝藏软件你安装了吗?
- 单片机输出脉冲的C语言简易程序,单片机简易程序, 电子琴 内附图 有说明...
- 解决fabric编译失败(make: *** [release/linux-amd64/bin/configtxgen] Error 1)
- 【百度LOGO权限】三天时间从获取LOGO权限到审核通过
- retina 显示屏详细理解
- 知识图谱-实体消歧(语义消歧)
- uniapp-路由和navigate跳转
- Verilog学习:ICE40UP5K_PICO按键点灯
- 访问网站只有文字,没有图片
- 4G、5G中的基本时间单位Ts和Tc
- GitHub 上六大爆款AI学习项目,Star超过5.6w
- 知道计算机组装,电脑组装不担心被电脑店套路,就要懂得如何查看电脑的硬件配置...
- linker command failed with exit code 1 (use -v to see invocat)错误的处理方法
热门文章
- 好用的翻译软件-大家都在用的互译软件
- Ceph集群显示XXX daemons have recently crashed警告
- ajax判断远程服务器是否存在某文件
- 莱布尼兹乘积微分公式证明纠错
- java基础-数组-案例练习-检测一个字符串是否为回文 回文字符串是指正着读和反着读该字符串都是相同拼写
- 精彩东博会丨我委会员单位联通沃音乐打卡第五届中国—东盟信息港论坛:穿越元宇宙 沉浸新技术
- CSS之关于min-width、max-width、min-height和max-height的使用
- 什么是流量网站流量的概念
- 计算机未来的发展趋势三百字,用牛顿电脑苹果机器人写作文三百字
- 在【Window】系统下更改 【pip install】 默认安装依赖路径