搜索
您的当前位置:首页windows 设备管理器中的设备控制

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盘





因篇幅问题不能全部显示,请点此查看更多更全内容

Top