检测com端口代码实现

Posted manongdashu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了检测com端口代码实现相关的知识,希望对你有一定的参考价值。

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 << "
";
					out <<  W2A(epi.szDescription) << "
";
					out << W2A(epi.szFriendlyName)<< "
";
#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 << "
";
							out << "thread id= " << strthrdxlog << "
";
#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;
}

  

以上是关于检测com端口代码实现的主要内容,如果未能解决你的问题,请参考以下文章

十条实用的jQuery代码片段

Python代码阅读(第13篇):检测列表中的元素是否都一样

使用 Pygments 检测代码片段的编程语言

如何使用模块化代码片段中的LeakCanary检测内存泄漏?

Python-通过socket实现一个小型的端口检测工具

Android:使用Tab检测单个片段viewpager