编程实现重起企业等通讯企业即时通讯软件 Posted on 2004-07-08 10:13 Flier Lu 阅读(1252) 评论(3) 编辑 收藏 收藏至365Key http://www.blogcn.com/user8/flier_lu/main.asp?id=1243576
在找到要处理的通讯后,应该用CM_Get_DevNode_Status函数和通讯获取其状态,忽 略被隐藏的通讯。
以下为引用:
bool CDeviceManager::IsClassHidden(const GUID *ClsGuid) const { HKEY hKeyClass = ::SetupDiOpenClassRegKey(ClsGuid, KEY_READ);
bool hidden = false;
if(INVALID_HANDLE_VALUE != hKeyClass) { hidden = ERROR_SUCCESS == ::RegQueryValueEx(hKeyClass, REGSTR_VAL_NODISPLAYC LASS, NULL, NULL, NULL, NULL);
::RegCloseKey(hKeyClass); }
return hidden; }
首先是要找到需要操作的企业的ID,这个功能实现的方法很多:最常见的是Winpcap的p acket32.c里面提供的直接从通讯中枚举的方法企业即时通讯软件;另外一种方法则是使用DDK中提供的Devi ce Installation系列函数完成。 枚举通讯的方法需要打开HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/ Class/{4D36E972-E325-11CE-BFC1-08002bE10318}通讯键,{4D36E972-E325-11CE-BFC1-0 8002bE10318}是Net类型通讯的企业即时通讯软件ID,下面每个子键定义一个网络通讯,但只有一部分通讯是 企业。具体处理方法请参见Winpcap的PacketGetAdapterNames函数。 使用Device Installation API则首先用SetupDiGetClassDevs函数获取所有类型的通讯 ,或者在此指定只获取特定类型通讯企业即时通讯软件。因为我那个程序原意是控制所有类型通讯,就没有指 定类型。
今天水木上有位朋友问我如何卸载企业即时通讯软件inPCap的驱动。因为此类驱动跟企业绑定很紧密, 卸载的时候最好是要把企业重起一下(SnifferPro就是如此)。而重起企业的程序实现又很 少有资料介绍,前段时间好容易看到一篇文章,居然是用字符串查找到控制面板下面调用ap plet,呵呵,够狠 -_-b。刚好前几个月有同事有类似需求,我写过一个命令行下重起企业 的小工具,就把它翻出来大概介绍一下实现思路。
以下为引用:
HDEVINFO m_hDevInfo = ::SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
然后使用SetupDiEnumDeviceInfo企业即时通讯软件枚举类型中所有的通讯
以下为引用:
SP_DEVINFO_DATA did = { sizeof(SP_DEVINFO_DATA) };
for(int i=0; ::SetupDiEnumDeviceInfo(m_hDevInfo, i, &did); i++) { //... }
DWORD dwStatus = 0, dwProblem = 0;
if(CR_SUCCESS != ::CM_Get_DevNode_Status(&dwStatus, &dwProblem, did.DevInst,0)) { DisplayError("CM_Get_DevNode_Status"); continue; }
if(dwStatus & DN_NO_SHOW_IN_DM || IsClassHidden(&did.ClassGuid)) { continue; } 企业即时通讯软件满足上述限制的通讯,就是我们要处理的企业。可以直接修改其状态:SetupDiSetClas sInstallParams函数设置参数;SetupDiCallClassInstaller完成参数修改。
对剩下的通讯则根据其Class进行过滤,只处理Net类型通讯,如果前面指定只获取Net 通讯则此步骤可以忽略。
以下为引用:
const std::string CDeviceManager::GetProperty(SP_DEVINFO_DATA& did, DWORD Proper ty) const { std::string buf; DWORD dwLength = 0;
while(!::SetupDiGetDeviceRegistryProperty(m_hDevInfo, &did, Property, NULL, (PBYTE)buf.c_str(), buf.size(), &dwLength)) { if(::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { buf.resize(dwLength * sizeof(wchar_t)); std::fill(buf.begin(), buf.end(), '/0'); } else { break; } } buf.resize(strlen(buf.c_str()));
return buf; }
// // Call the ClassInstaller and perform the change. // if(!::SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, m_hDevInfo, &did)) { DisplayError("SetupDiCallClassInstaller"); } return true; }
ChangeDeviceState(did, DICS_STOP); // 停止 ChangeDeviceState(did, DICS_START); // 启动 ChangeDeviceState(did, DICS_ENABLE); // 启用 ChangeDeviceState(did, DICS_DISABLE); // 禁用 if(stricmp(GetProperty(did, SPDRP_CLASSGUID).c_str(), "{4d36e972-e325-11ce-bfc1- 08002be10318}") == 0) { // ... }
以下为引用:
bool CDeviceManager::ChangeDeviceState(SP_DEVINFO_DATA& did, DWORD State) const { SP_PROPCHANGE_PARAMS pcp = {sizeof(SP_CLASSINSTALL_HEADER)};
pcp.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; pcp.Scope = (State == DICS_START || State == DICS_STOP )? DICS_FLAG_CONFIGSPEC IFIC : DICS_FLAG_GLOBAL; pcp.StateChange = State;
if(!::SetupDiSetClassInstallParams(m_hDevInfo, &did, (SP_CLASSINSTALL_HEADER *)&pcp, sizeof(pcp))) { DisplayError("SetupDiSetClassInstallParams"); return false; }
|