⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcpscanpage.cpp

📁 VC网络程序设计实例导航配套代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	// ricava i puntatori (classe e lista) per accedere alla pagina dei servizi
	CServicesPage* pServicesPage = NULL;
	CListCtrlEx* pServicesList = NULL;
	PROPERTYPAGE* p;
	if((p = FindPage(IDD_PAGE_SERVICES))!=(PROPERTYPAGE*)NULL)
	{
		pServicesPage = (CServicesPage*)p->page;
		pServicesList = &(pServicesPage->m_wndServicesList);
	}

	// e' riuscito ad ottenere il puntatore alla pagina dei servizi
	if(pServicesPage)
	{
		// fa in modo che venga chiamato il codice di inizializzazione della pagina se 
		// questa non e' stata ancora visualizzata
		if(!pServicesPage->Dirty())
			ActivatePage(IDD_PAGE_SERVICES);

		// copia gli elementi presenti nella lista dei servizi in quella per lo scanning
		int tot = pServicesList->GetItemCount();
		if(tot > 0)
		{
			m_nPortFlag   = 0;
			m_nPortList   = 0;
			m_strPortList = "";
			m_nStartPort  = 0;
			m_nEndPort    = 0;
			
			char szPort[PORT_NAME+1] = {0};

			for(int i = 0; i < tot; i++)
			{
				pServicesList->GetItemText(i,1,szPort,sizeof(szPort)-1);
				m_strPortList += szPort;
				if(i+1!=tot)
					m_strPortList += ", ";
			}

			// aggiorna i campi della pagina
			UpdateData(FALSE);
			OnRadioButtonPortList();
		}
	}
}

/*
	OnScanPopupMenuClearPorts()
	
	Azzera i numeri di porte (lista/range) correnti.
*/
void CScanPage::OnScanPopupMenuClearPorts(void)
{
	m_strPortList  = "0";
	m_nStartPort = 0;
	m_nEndPort   = 0;
	m_wndScanList.DeleteAllItems();
	UpdateData(FALSE);
}

/*
	OnScan()

	Effettua lo scanning dell'host/porta specificati.
	Chiamata dallo sheet per il click sul bottone (IDOK).
*/
LONG CScanPage::OnScan(UINT wParam,LONG lParam)
{
	static char szPortBuffer[MAX_PORTLIST_STRING+1];
	static UINT* nPortArray = NULL;
	static UINT nScanIndex = (UINT)-1;
	static UINT nScanArray = 0;
	static char* pIpAddr = NULL;
	static TCPSCAN tcpscan;
	static char nItem[HOSTNAME_SIZE + 5 + 256 + 1];
	CString strStatus;

	::PeekAndPump();

	if(!m_pAsyncSock)
		return(0);

	// e' stato cliccato il bottone Cancel, annulla lo scanning
	if(CHECK_PARAM_MESSAGE(WM_CANCEL))
	{
		// resetta le variabili
		m_pAsyncSock->AsyncClose();
		delete m_pAsyncSock,m_pAsyncSock = NULL;

		wParam = (UINT)-1,lParam = (LONG)-1;
		nScanIndex = nScanArray;
		if(nPortArray)
		{
			delete [] nPortArray;
			nPortArray = NULL;
		}

		// elimina gli eventuali messaggi messi in coda dalle OnAsync...()
		MSG msg;
		while(::PeekMessage(&msg,this->m_hWnd,WM_ASYNCCONNECT,WM_ASYNCCONNECT,PM_REMOVE))
			;

		SetTitle(PROGRAM_NAME);

		nScanIndex = (UINT)-1;
		nScanArray = 0;
		if(nPortArray)
		{
			delete [] nPortArray;
			nPortArray = NULL;
		}

		// abilita il bottone Scan e trasforma Cancel in Exit
		EnablePropertySheetOkButton();
		SetPropertySheetCancelButton(IDCANCEL_EXIT_PROMPT);

		LeavePageBusyState(IDD_PAGE_SCAN);

		return(0);
	}
	// e' stato cliccato il bottone Exit, annulla lo scanning
	else if(CHECK_PARAM_MESSAGE(WM_CLOSE))
	{
		// resetta le variabili
		m_pAsyncSock->Close();
		wParam = lParam = 0;
		nScanIndex = nScanArray;
		if(nPortArray)
		{
			delete [] nPortArray;
			nPortArray = NULL;
		}

		return(0);
	}

	// prima chiamata, inizializza
	if(nScanIndex==(UINT)-1)
	{
		// aggiorna la dimensione delle colonne della lista
		m_pConfig->UpdateNumber(TCPSCAN_OPTIONS_KEY,TCPSCAN_SCAN_HOST_COLSIZE_KEY,m_wndScanList.GetColWidth(0));
		m_pConfig->UpdateNumber(TCPSCAN_OPTIONS_KEY,TCPSCAN_SCAN_PORT_COLSIZE_KEY,m_wndScanList.GetColWidth(1));
		m_pConfig->UpdateNumber(TCPSCAN_OPTIONS_KEY,TCPSCAN_SCAN_DESC_COLSIZE_KEY,m_wndScanList.GetColWidth(2));
		m_pConfig->Save();

		UINT i;

		// azzera per le chiamate successive (usa la variabile come indice corrente per l'array host/porta)
		nScanIndex = 0;

		// carica l'array per le porte (lista/intervallo)
		if(m_nPortFlag==0)
		{
			char *token;

			// conta il numero di porte per dimensionare l'array
			strcpyn(szPortBuffer,LPCTSTR(m_strPortList),sizeof(szPortBuffer));
			for(i = 1,token = strtok(szPortBuffer,".,; "); token!=NULL; i++)
				token = strtok(NULL,".,; ");

			nPortArray = new UINT[i];
			if(nPortArray)
			{
				// inserisce le porte nell'array
				strcpyn(szPortBuffer,LPCTSTR(m_strPortList),sizeof(szPortBuffer));
				for(i = 1,token = strtok(szPortBuffer,".,; "); token!=NULL; i++)
				{
					nPortArray[i] = (UINT)atol(token);
					token = strtok(NULL,".,; ");
				}

				// il primo elemento dell'array contiene il totale degli elementi presenti
				nPortArray[0] = (UINT)i - 1;

				// imposta la porta iniziale e finale per lo scanning
				m_nStartPort = nPortArray[1];
				m_nEndPort   = nPortArray[nPortArray[0]];
			}
		}
		else if(m_nPortFlag==1)
		{
			unsigned tot;
			
			// ricava il numero di porte per dimensionare l'array
			tot = (m_nEndPort-m_nStartPort) + 1;
			
			nPortArray = new UINT[tot+1];
			if(nPortArray)
			{
				// inserisce le porte nell'array
				for(i = 0; i < tot; i++)
					nPortArray[i+1] = m_nStartPort + i;
				
				// il primo elemento dell'array contiene il totale degli elementi presenti
				nPortArray[0] = tot;
			}
		}
		else
		{
			AfxMessageBox("No port number specified.",MB_ICONWARNING);
			return(0);
		}

		// imposta la dimensione max della linea di output per la lista
		strStatus.GetBuffer(MAX_PORTLIST_STRING+1);

		// crea la lista
		CreateScanningList();

		// compone la stringa
		strStatus.Format("scanning host %s through %s, TCP ports %u through %u...",m_strStartHost,m_strEndHost,m_nStartPort,m_nEndPort);
		SetTitle(strStatus);

		// inizializza la lista per le coppie host/porta
		nScanArray = 0;
		nScanArray = nPortArray[0];

		// disabilita il bottone Scan e trasforma Exit in Cancel
		DisablePropertySheetOkButton();
		SetPropertySheetCancelButton(IDCANCEL_CANCEL_PROMPT);
	}

	// alla prima chiamata wParam=lParam=0, alle successive (generate da OnAsyncConnect())
	// in wParam/lParam gli errori winsock (numero/stringa)
	BOOL bConnected = wParam==0;
	
	// se si tratta di una delle chiamate successive alla prima (alla prima chiamata wParam=0)
	if(wParam!=(UINT)-1)
	{
		char winsock[256+1];

		if(bConnected)
		{
			strcpyn(winsock,m_pAsyncSock->GetServiceByPort(tcpscan.port,"tcp"),sizeof(winsock)-1);
			strStatus.Format("%s:%d %s service running",tcpscan.ip,tcpscan.port,winsock);
			SetTitle(strStatus);
		}
		else
		{
			strcpyn(winsock,m_pAsyncSock->GetWSAErrorString(),sizeof(winsock)-1);
			strStatus.Format("%s:%d error: %s",tcpscan.ip,tcpscan.port,winsock);
			SetTitle(strStatus);
		}

		// chiude il socket
		m_pAsyncSock->Close();

		// il valore viene sempre ricaricato dalla configurazione e non dalla pagina
		// (la pagina relativa lo salva ad ogni cambio)
		BOOL m_bShowOnlyValidConn = m_pConfig->GetNumber(TCPSCAN_OPTIONS_KEY,TCPSCAN_SHOWCONN_KEY);

		// visualizza il risultato e registra sul file di log
		if(m_bShowOnlyValidConn ? bConnected : TRUE)
		{
			wsprintf(nItem,"%s;%d;%s",tcpscan.ip,tcpscan.port,winsock);
			m_wndScanList.AddItem(nItem,bConnected ? 1:0,IDM_SCAN);
		}

		::PeekAndPump();
	}

	// per qualsiasi chiamata (prima o successive), se non ha raggiunto la fine dell'array host/porta
	if(nScanIndex < nScanArray)
	{
		// ricava l'elemento corrente
		TCPSCAN* t = NULL;
		if(!pIpAddr)
			pIpAddr = (char*)m_pAsyncSock->ParseIPRange(m_strStartHost,m_strEndHost);

		if(pIpAddr)
		{
			strcpy(tcpscan.ip,pIpAddr);
			tcpscan.port = nPortArray[nScanIndex+1];
			t = &tcpscan;
		}

		if(t)
		{
			// il valore viene sempre ricaricato dalla configurazione e non dalla pagina
			// (la pagina relativa lo salva ad ogni cambio)
			int m_iScanDelay = m_pConfig->GetNumber(TCPSCAN_OPTIONS_KEY,TCPSCAN_SCANDELAY_KEY);

			// ritardo tra le connessioni
			if(m_iScanDelay > 0)
			{
				strStatus.Format("scanning %s:%d (delayed %d secs.)",tcpscan.ip,tcpscan.port,m_iScanDelay);
				
				Delay(m_iScanDelay);

				if(nScanIndex==(UINT)-1 && nScanArray==0)
					return(0L);
			}
			else
				strStatus.Format("scanning %s:%d...",tcpscan.ip,tcpscan.port);
			
			SetTitle(strStatus);

			// scan della coppia host/porta
			if(m_pAsyncSock->Open())
			{
				//socket->SetSocketTimeout(10);
				m_pAsyncSock->AsyncConnect(t->ip,t->port);
			}
			else
			{
				// apertura fallita, invia autonomamente il messaggio
				int wsaerror = m_pAsyncSock->GetWSAErrorNumber();
				static char wsastring[128];
				strcpyn(wsastring,m_pAsyncSock->GetWSAErrorString(),sizeof(wsastring));
				::PostMessage(this->m_hWnd,WM_ASYNCCONNECT,wsaerror,MAKELPARAM(LOWORD(wsastring),HIWORD(wsastring)));
			}

			// incrementa l'elemento corrente dell'array
			nScanIndex++;
			if(nScanIndex >= nScanArray)
			{
				pIpAddr = (char*)m_pAsyncSock->ParseIPRange(m_strStartHost,m_strEndHost);
				if(pIpAddr)
					nScanIndex = 0;
			}
		}
	}
	else // scanning terminato
	{
		SetTitle(PROGRAM_NAME);

		nScanIndex = (UINT)-1;
		nScanArray = 0;
		if(nPortArray)
		{
			delete [] nPortArray;
			nPortArray = NULL;
		}

		// abilita il bottone Scan e trasforma Cancel in Exit
		EnablePropertySheetOkButton();
		SetPropertySheetCancelButton(IDCANCEL_EXIT_PROMPT);

		LeavePageBusyState(IDD_PAGE_SCAN);
	}

	return(0L);
}

/*
	CreateScanningList()

	Crea il controllo per la lista per lo scanning.
*/
BOOL CScanPage::CreateScanningList(void)
{
	BOOL bCreate = m_wndScanList.Create();

	if(bCreate)
	{
		// menu di default per lista vuota
		m_wndScanList.SetDefaultMenu(IDM_SCAN_EMPTY);

		// il click col destro imposta la riga come selezionata
		m_wndScanList.RightClickSelects(TRUE);

		// icone
		m_wndScanList.AddIcon(IDI_ICONPORTERROR);
		m_wndScanList.AddIcon(IDI_ICONPORT);
		
		// colonne
		m_wndScanList.AddCol("Host",'C',m_pConfig->GetNumber(TCPSCAN_OPTIONS_KEY,TCPSCAN_SCAN_HOST_COLSIZE_KEY));
		m_wndScanList.AddCol("Port",'N',m_pConfig->GetNumber(TCPSCAN_OPTIONS_KEY,TCPSCAN_SCAN_PORT_COLSIZE_KEY));
		m_wndScanList.AddCol("Description",'C',m_pConfig->GetNumber(TCPSCAN_OPTIONS_KEY,TCPSCAN_SCAN_DESC_COLSIZE_KEY));
	}

	return(bCreate);
}

/*
	RemovePort()

	Elimina l'elemento corrente della lista (controllo).
*/
void CScanPage::RemovePort(void)
{
	int nItem = 0;

	if((nItem = m_wndScanList.GetCurrentItem()) >= 0)
		m_wndScanList.DeleteItem(nItem);
}

/*
	SaveScanning()

	Salva lo scanning nel registro.
*/
BOOL CScanPage::SaveScanning(void)
{
	UpdateData(TRUE);

	// host inizio/fine
	m_pConfig->UpdateString(TCPSCAN_SCAN_KEY,TCPSCAN_SCANNING_STARTHOST_KEY,m_strStartHost);
	m_pConfig->UpdateString(TCPSCAN_SCAN_KEY,TCPSCAN_SCANNING_ENDHOST_KEY,m_strEndHost);
	
	// porte (lista/intervallo)
	m_pConfig->UpdateNumber(TCPSCAN_SCAN_KEY,TCPSCAN_SCANNING_PORTMODE_KEY,m_nPortFlag);
	if(m_nPortFlag!=0)
	{
		char szPort[(PORT_NAME*2)+1];
		wsprintf(szPort,"%u,%u",m_nStartPort,m_nEndPort);
		m_pConfig->UpdateString(TCPSCAN_SCAN_KEY,TCPSCAN_SCANNING_PORTNUMBERS_KEY,szPort);
	}
	else
		m_pConfig->UpdateString(TCPSCAN_SCAN_KEY,TCPSCAN_SCANNING_PORTNUMBERS_KEY,m_strPortList);
	
	m_pConfig->Save();

	return(TRUE);
}

/*
	LoadScanning()

	Carica lo scanning dal registro.
*/
BOOL CScanPage::LoadScanning(void)
{
	// crea la lista (controllo)
	BOOL bCreate = CreateScanningList();

	if(bCreate)
	{
		// carica lo scanning dal registro
		m_strStartHost.Format("%s",m_pConfig->GetString(TCPSCAN_SCAN_KEY,TCPSCAN_SCANNING_STARTHOST_KEY));
		m_strEndHost.Format("%s",m_pConfig->GetString(TCPSCAN_SCAN_KEY,TCPSCAN_SCANNING_ENDHOST_KEY));
		m_nPortFlag = m_pConfig->GetNumber(TCPSCAN_SCAN_KEY,TCPSCAN_SCANNING_PORTMODE_KEY);
		
		if(m_nPortFlag==0) // lista
		{
			m_strPortList.Format("%s",m_pConfig->GetString(TCPSCAN_SCAN_KEY,TCPSCAN_SCANNING_PORTNUMBERS_KEY));
			OnRadioButtonPortList();
		}
		else // intervallo
		{
			int i;
			char* token;
			char szPort[(PORT_NAME*2)+1];
			strcpyn(szPort,m_pConfig->GetString(TCPSCAN_SCAN_KEY,TCPSCAN_SCANNING_PORTNUMBERS_KEY),sizeof(szPort)-1);

			m_nStartPort = m_nEndPort = 0;

			for(i = 0,token = strtok(szPort,".,; "); token!=NULL; i++)
			{
				if(i==0)
					m_nStartPort = (UINT)atol(token);

				m_nEndPort = (UINT)atol(token);
				
				token = strtok(NULL,".,; ");
			}

			OnRadioButtonPortRange();
		}

		m_nPortList = m_nPortFlag;
		UpdateData(FALSE);
	}

	return(bCreate);
}

/*
	DDV_...()
*/
void AFXAPI DDV_ValidateIP(CDataExchange* pDX,int nIDC,CString& cIpAddr)
{
	pDX->PrepareEditCtrl(nIDC);
	
	if(pDX->m_bSaveAndValidate)
		if(cIpAddr.GetLength() <= 0 || cIpAddr.GetLength() > HOSTNAME_SIZE)
		{
			AfxMessageBox("Must enter a valid ip/host name string.",MB_ICONWARNING);
			pDX->Fail();
		}
}

void AFXAPI DDV_ValidatePortList(CDataExchange* pDX,int nIDC,CString& cPortList)
{
	pDX->PrepareEditCtrl(nIDC);
	
	if(pDX->m_bSaveAndValidate)
		if(cPortList.GetLength() <= 0 || cPortList.GetLength() >= MAX_PORTLIST_STRING)
		{
			AfxMessageBox("Must enter a valid port number(s).",MB_ICONWARNING);
			pDX->Fail();
		}
}

void AFXAPI DDV_ValidatePortNumber(CDataExchange* pDX,int nIDC,UINT& uiPortNumber)
{
	pDX->PrepareEditCtrl(nIDC);
	
	if(pDX->m_bSaveAndValidate)
		if(uiPortNumber < 0 || uiPortNumber >= UINT_MAX)
		{
			AfxMessageBox("Must enter a valid port number.",MB_ICONWARNING);
			pDX->Fail();
		}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -