欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

检测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;
}