检测com端口代码实现
程序员文章站
2022-04-11 16:01:57
1:scan 2:detect for one type ......
1:scan
hresult cdevhound::scan(const vector<cstring> &guiinfo, vector<dev_info> &vportinfo) // scan port
{
hdevinfo hdevinfo;
sp_devinfo_data deviceinfodata;
dword i;
dev_info epi;
// create a hdevinfo with all present devices.
hdevinfo = setupdigetclassdevs((lpguid)&guid_devclass_ports,
0, // enumerator
0,
digcf_present);
if (hdevinfo == invalid_handle_value)
{
// insert error handling here.
return 1;
}
// enumerate through all devices in set.
deviceinfodata.cbsize = sizeof(sp_devinfo_data);
for(dword i = 0; setupdienumdeviceinfo(hdevinfo,i,&deviceinfodata); i++)
{
memset( &epi,0,sizeof(epi) );
int msgtype = wm_dev_msg;
tchar szdis[max_path] = {0};
dword nsize = 0;
memset( &szdis, 0, max_path);
dword datat;
lptstr buffer = null;
dword buffersize = 0;
memset( &epi,0,sizeof(epi) );
if(false==m_bwork)
{
break;
}
//
// call function with null to begin with,
// then use the returned buffer size
// to alloc the buffer. keep calling until
// success or an unknown failure.
//
while (!setupdigetdeviceregistryproperty(
hdevinfo,
&deviceinfodata,
spdrp_friendlyname,
&datat,
(pbyte)buffer,
buffersize,
&buffersize))
{
if (getlasterror() ==
error_insufficient_buffer)
{
// change the buffer size.
if (buffer) localfree(buffer);
buffer = (lptstr)localalloc(lptr,buffersize);
}
else
{
// insert error handling here.
break;
}
}
setupdigetdeviceregistryproperty( hdevinfo, &deviceinfodata, spdrp_friendlyname, null,(pbyte)epi.szfriendlyname, dev_name_max_len*sizeof(tchar), null);
// get port description from registry
setupdigetdeviceregistryproperty( hdevinfo, &deviceinfodata, spdrp_devicedesc, null,(pbyte)epi.szdescription, dev_name_max_len*sizeof(tchar), null);
hkey hdevkey = setupdiopendevregkey( hdevinfo,&deviceinfodata,dics_flag_global,0,direg_dev,key_read );
if( invalid_handle_value != hdevkey )
{
// get port name
dword dwcount = 256;
regqueryvalueex( hdevkey,_t( "portname" ),null,null,(byte*)epi.szportname,&dwcount );
regclosekey( hdevkey );
}
// tchar szdis[max_path] = {0};
// dword nsize = 0;
bool bget = setupdigetdeviceinstanceid(hdevinfo, &deviceinfodata, szdis, sizeof(szdis), &nsize);
if(true==bget)
{
tstring strid(szdis);
tstring strchar(_t("\\"));
std::size_t pos = strid.rfind(_t("\\"));
strchar = strid.substr(0,pos);
if(guidinfofind(strchar, msgtype,guiinfo))
{
pos = strid.find_first_of('&');
_tcscpy(epi.szvid,strid.substr(0,pos).c_str());
pos = strid.rfind(_t("\\"));
strchar = strid.substr(pos+1);
_tcscpy(epi.szguid,strchar.c_str());
insertportinfo(epi, false, msgtype,vportinfo);
}
else
{
continue;
}
}
}
if(hdevinfo != invalid_handle_value)
{
setupdidestroydeviceinfolist(hdevinfo);
hdevinfo = invalid_handle_value;
}
return s_ok;
}
2:detect for one type
uint cdevhound::houndthreadproc() //detect for one type port
{
guid *guiddev = (guid*)&guid_class_port;
hdevinfo hdevinfo = invalid_handle_value;
// get port class set
// note:we use digcf_present flag,so maybe you can see
// some ports on the device manager,but they are not
// enumerated by setupdienumdeviceinterfaces in the do-while
// loop,because their driver are disabled,no application
// can open and use them.
hdevinfo = setupdigetclassdevs( guiddev,
null,
null,
digcf_present | digcf_deviceinterface
);
if(hdevinfo == invalid_handle_value)
{
return 0;
}
sp_device_interface_data ifcdata;
ifcdata.cbsize = sizeof(sp_device_interface_data);
dword dwindex = 0;
dev_info epi;
bool binit = true;
// enumerate port and modem class device interfaces
do
{
memset( &epi,0,sizeof(epi) );
if( setupdienumdeviceinterfaces(hdevinfo,null, guiddev, dwindex, &ifcdata) )
{
sp_devinfo_data devdata;
devdata.cbsize = sizeof( sp_devinfo_data );
if( !setupdigetdeviceinterfacedetail( hdevinfo,&ifcdata,null,0,null,&devdata ) )
{
if( error_insufficient_buffer != getlasterror() )
{
// can not get detail interface info
continue;
}
}
// get friendly name from registry
setupdigetdeviceregistryproperty( hdevinfo, &devdata, spdrp_friendlyname, null,(pbyte)epi.szfriendlyname, dev_name_max_len*sizeof(tchar), null);
// get port description from registry
setupdigetdeviceregistryproperty( hdevinfo, &devdata, spdrp_devicedesc, null,(pbyte)epi.szdescription, dev_name_max_len*sizeof(tchar), null);
// get class name from registry
//tchar szclass[epi_max_len];
//setupdigetdeviceregistryproperty( hdevinfo, &devdata, spdrp_class, null,(pbyte)szclass, epi_max_len*sizeof(tchar), null);
//epi.ntype = checkdeviceclass( szclass );
hkey hdevkey = setupdiopendevregkey( hdevinfo,&devdata,dics_flag_global,0,direg_dev,key_read );
if( invalid_handle_value != hdevkey )
{
// get port name
dword dwcount = dev_name_max_len;
regqueryvalueex( hdevkey,_t( "portname" ),null,null,(byte*)epi.szportname,&dwcount );
regclosekey( hdevkey );
}
// insert to port info array
tchar szdis[max_path] = {0};
dword nsize = 0;
bool bget = setupdigetdeviceinstanceid(hdevinfo, &devdata, szdis, sizeof(szdis), &nsize);
if(true==bget)
{
tstring strid(szdis);
tstring strchar(_t("\\"));
std::size_t pos = strid.rfind(_t("\\"));
std::size_t posbegin = strid.find_first_of('\\');
strchar = strid.substr(0,pos);
dwindex++;
uses_conversion;
if(tstring::npos != strchar.find(_t("usb\\vid_1782&pid_4d00")))
{
strchar = strchar.substr(posbegin+1,pos);
_tcscpy(epi.szvid,strchar.c_str());
pos = strid.rfind(_t("\\"));
strchar = strid.substr(pos+1);
tstring strcominfo(epi.szportname);
tstring strcominfo2 = boost::to_lower_copy(strcominfo);
boost::erase_first(strcominfo2, "com");
_tcscpy(epi.szguid,strcominfo2.c_str());
#if 0
string strlog;
ofstream out("d:\\scanport.log",ios::app);
strlog = convert<string>(binit);
out <<"init="<< strlog << "\n";
out << w2a(epi.szdescription) << "\n";
out << w2a(epi.szfriendlyname)<< "\n";
#endif
for(size_t nthreadx=0; nthreadx<m_guidvec.size(); nthreadx++)
{
if(m_guidvec[nthreadx]==strcominfo2)
{
insertportinfo( epi,nthreadx, binit);
#ifdef _write_port_logfile
string strthrdxlog;
string strinitlog;
strthrdxlog = convert<string>(nthreadx);
ofstream out("d:\\scanport2.log",ios::app);
strinitlog = convert<string>(binit);
out <<"init="<< strinitlog << "\n";
out << "thread id= " << strthrdxlog << "\n";
#endif
}
}
}
}
}
else
{
if( error_no_more_items != getlasterror() )
{
dwindex++;
continue;
}
dwindex = 0;
binit = false;
clearstate();
sleep(1);
setupdidestroydeviceinfolist(hdevinfo);
hdevinfo = invalid_handle_value;
hdevinfo = setupdigetclassdevs( guiddev,
null,
null,
digcf_present | digcf_deviceinterface
);
memset(&ifcdata,0,sizeof(sp_device_interface_data));
ifcdata.cbsize = sizeof(sp_device_interface_data);
}
}while( m_bwork && (hdevinfo != invalid_handle_value) );
if(hdevinfo != invalid_handle_value)
{
setupdidestroydeviceinfolist(hdevinfo);
hdevinfo = invalid_handle_value;
}
return 0;
}
上一篇: vivo V15 Pro曝光:升降式前摄 2月20日发
下一篇: 如何将apk大小减少