PortScanDlg.cpp
上传用户:qzzxgm
上传日期:2009-12-14
资源大小:1882k
文件大小:13k
源码类别:

书籍源码

开发平台:

Visual C++

  1. // PortScanDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "PortScan.h"
  5. #include "PortScanDlg.h"
  6. #include <fcntl.h>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <io.h>
  10. #ifdef _DEBUG
  11. #define new DEBUG_NEW
  12. #undef THIS_FILE
  13. static char THIS_FILE[] = __FILE__;
  14. #endif
  15. /////////////////////////////////////////////////////////////////////////////
  16. // CAboutDlg dialog used for App About
  17. class CAboutDlg : public CDialog
  18. {
  19. public:
  20. CAboutDlg();
  21. // Dialog Data
  22. //{{AFX_DATA(CAboutDlg)
  23. enum { IDD = IDD_ABOUTBOX };
  24. //}}AFX_DATA
  25. // ClassWizard generated virtual function overrides
  26. //{{AFX_VIRTUAL(CAboutDlg)
  27. protected:
  28. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  29. //}}AFX_VIRTUAL
  30. // Implementation
  31. protected:
  32. //{{AFX_MSG(CAboutDlg)
  33. //}}AFX_MSG
  34. DECLARE_MESSAGE_MAP()
  35. };
  36. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  37. {
  38. //{{AFX_DATA_INIT(CAboutDlg)
  39. //}}AFX_DATA_INIT
  40. }
  41. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  42. {
  43. CDialog::DoDataExchange(pDX);
  44. //{{AFX_DATA_MAP(CAboutDlg)
  45. //}}AFX_DATA_MAP
  46. }
  47. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  48. //{{AFX_MSG_MAP(CAboutDlg)
  49. // No message handlers
  50. //}}AFX_MSG_MAP
  51. END_MESSAGE_MAP()
  52. /////////////////////////////////////////////////////////////////////////////
  53. // CPortScanDlg dialog
  54. CPortScanDlg::CPortScanDlg(CWnd* pParent /*=NULL*/)
  55. : CDialog(CPortScanDlg::IDD, pParent)
  56. {
  57. //{{AFX_DATA_INIT(CPortScanDlg)
  58. // NOTE: the ClassWizard will add member initialization here
  59. //}}AFX_DATA_INIT
  60. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  61. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  62. m_pColumns = new CStringList;
  63. ASSERT(m_pColumns);
  64. m_bSinglePort = TRUE;
  65. m_nMaxAttempts = 1;
  66. m_pStatusList = new CPtrList;
  67. ASSERT(m_pStatusList);
  68. }
  69. void CPortScanDlg::DoDataExchange(CDataExchange* pDX)
  70. {
  71. CDialog::DoDataExchange(pDX);
  72. //{{AFX_DATA_MAP(CPortScanDlg)
  73. DDX_Control(pDX, IDC_PROGRESS, m_cProgress);
  74. DDX_Control(pDX, IDC_LIST_RESULT, m_cResult);
  75. DDX_Control(pDX, IDC_IP_ADDRESS, m_cIP);
  76. DDX_Control(pDX, IDC_EDIT_SINGLE_PORT_TO, m_cPortTo);
  77. DDX_Control(pDX, IDC_EDIT_SINGLE_PORT_FROM, m_cPortFrom);
  78. DDX_Control(pDX, IDC_EDIT_SINGLE_PORT, m_cSinglePort);
  79. DDX_Control(pDX, IDC_EDIT_ATTEMPTS, m_cAttempts);
  80. DDX_Control(pDX, IDC_BUTTON_STOP, m_cBtnStop);
  81. DDX_Control(pDX, IDC_BUTTON_SCAN, m_cBtnScan);
  82. //}}AFX_DATA_MAP
  83. }
  84. BEGIN_MESSAGE_MAP(CPortScanDlg, CDialog)
  85. //{{AFX_MSG_MAP(CPortScanDlg)
  86. ON_WM_SYSCOMMAND()
  87. ON_WM_PAINT()
  88. ON_WM_QUERYDRAGICON()
  89. ON_WM_DESTROY()
  90. ON_BN_CLICKED(IDC_RADIO_SINGLE, OnRadioSingle)
  91. ON_BN_CLICKED(IDC_RADIO_RANGE, OnRadioRange)
  92. ON_BN_CLICKED(IDC_BUTTON_SCAN, OnButtonScan)
  93. ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop)
  94. ON_BN_CLICKED(IDC_BUTTON_SAVE, OnButtonSave)
  95. //}}AFX_MSG_MAP
  96. END_MESSAGE_MAP()
  97. /////////////////////////////////////////////////////////////////////////////
  98. // CPortScanDlg message handlers
  99. BOOL CPortScanDlg::OnInitDialog()
  100. {
  101. CDialog::OnInitDialog();
  102. // Add "About..." menu item to system menu.
  103. // IDM_ABOUTBOX must be in the system command range.
  104. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  105. ASSERT(IDM_ABOUTBOX < 0xF000);
  106. CMenu* pSysMenu = GetSystemMenu(FALSE);
  107. if (pSysMenu != NULL)
  108. {
  109. CString strAboutMenu;
  110. strAboutMenu.LoadString(IDS_ABOUTBOX);
  111. if (!strAboutMenu.IsEmpty())
  112. {
  113. pSysMenu->AppendMenu(MF_SEPARATOR);
  114. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  115. }
  116. }
  117. // Set the icon for this dialog.  The framework does this automatically
  118. //  when the application's main window is not a dialog
  119. SetIcon(m_hIcon, TRUE); // Set big icon
  120. SetIcon(m_hIcon, FALSE); // Set small icon
  121. // TODO: Add extra initialization here
  122. //给列表框加标题栏
  123. AddHeader(_T("IP address"));
  124. AddHeader(_T("Port number"));
  125. AddHeader(_T("Port Status"));
  126. AddHeader(_T("Attempts"));
  127. AddHeader(_T("Remarks"));
  128. ShowHeaders();
  129. //设置扫描单个端口
  130. CheckRadioButton(IDC_RADIO_SINGLE,IDC_RADIO_RANGE,IDC_RADIO_SINGLE);
  131. //设置控件的默认状态
  132. m_cSinglePort.EnableWindow();
  133. m_cPortFrom.EnableWindow(FALSE);
  134. m_cPortTo.EnableWindow(FALSE);
  135. m_cBtnStop.EnableWindow(FALSE);
  136. m_cAttempts.SetWindowText(_T("1"));
  137. return TRUE;  // return TRUE  unless you set the focus to a control
  138. }
  139. void CPortScanDlg::OnSysCommand(UINT nID, LPARAM lParam)
  140. {
  141. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  142. {
  143. CAboutDlg dlgAbout;
  144. dlgAbout.DoModal();
  145. }
  146. else
  147. {
  148. CDialog::OnSysCommand(nID, lParam);
  149. }
  150. }
  151. // If you add a minimize button to your dialog, you will need the code below
  152. //  to draw the icon.  For MFC applications using the document/view model,
  153. //  this is automatically done for you by the framework.
  154. void CPortScanDlg::OnPaint() 
  155. {
  156. if (IsIconic())
  157. {
  158. CPaintDC dc(this); // device context for painting
  159. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  160. // Center icon in client rectangle
  161. int cxIcon = GetSystemMetrics(SM_CXICON);
  162. int cyIcon = GetSystemMetrics(SM_CYICON);
  163. CRect rect;
  164. GetClientRect(&rect);
  165. int x = (rect.Width() - cxIcon + 1) / 2;
  166. int y = (rect.Height() - cyIcon + 1) / 2;
  167. // Draw the icon
  168. dc.DrawIcon(x, y, m_hIcon);
  169. }
  170. else
  171. {
  172. CDialog::OnPaint();
  173. }
  174. }
  175. // The system calls this to obtain the cursor to display while the user drags
  176. //  the minimized window.
  177. HCURSOR CPortScanDlg::OnQueryDragIcon()
  178. {
  179. return (HCURSOR) m_hIcon;
  180. }
  181. void CPortScanDlg::OnDestroy() 
  182. {
  183. //清除扫描结果
  184. if (m_pStatusList)
  185. {
  186. POSITION p = m_pStatusList->GetHeadPosition();
  187. while (p)
  188. {
  189. POSITION temp = p;
  190. DATA* pNode = (DATA*)m_pStatusList->GetNext(p);
  191. m_pStatusList->RemoveAt(temp);
  192. if (pNode)
  193. delete pNode;
  194. }
  195. delete m_pStatusList;
  196. }
  197. CDialog::OnDestroy();
  198. }
  199. //增加列表框标题栏的某一列
  200. BOOL CPortScanDlg::AddColumn(LPCTSTR strItem,int nItem,int nSubItem,int nMask,int nFmt)
  201. {
  202. LV_COLUMN lvc;
  203. lvc.mask = nMask;
  204. lvc.fmt = nFmt;
  205. lvc.pszText = (LPTSTR) strItem;
  206. lvc.cx = m_cResult.GetStringWidth(lvc.pszText) + 25;
  207. if(nMask & LVCF_SUBITEM)
  208. {
  209. if(nSubItem != -1)
  210. lvc.iSubItem = nSubItem;
  211. else
  212. lvc.iSubItem = nItem;
  213. }
  214. return m_cResult.InsertColumn(nItem,&lvc);
  215. }
  216. //在列表框中加一条
  217. BOOL CPortScanDlg::AddItem(int nItem,int nSubItem,LPCTSTR strItem ,int nImageIndex)
  218. {
  219. LV_ITEM lvItem;
  220. lvItem.mask = LVIF_TEXT;
  221. lvItem.iItem = nItem;
  222. lvItem.iSubItem = nSubItem;
  223. lvItem.pszText = (LPTSTR)strItem;
  224. if(nImageIndex != -1)
  225. {
  226. lvItem.mask |= LVIF_IMAGE;
  227. lvItem.iImage |= LVIF_IMAGE;
  228. }
  229. if(nSubItem == 0)
  230. return m_cResult.InsertItem(&lvItem);
  231. return m_cResult.SetItem(&lvItem);
  232. }
  233. //加一列标题栏字符
  234. void CPortScanDlg::AddHeader(LPTSTR hdr)
  235. {
  236. if (m_pColumns)
  237. m_pColumns->AddTail(hdr);
  238. }
  239. //显示列表框标题栏
  240. void CPortScanDlg::ShowHeaders()
  241. {
  242. int nIndex = 0;
  243. POSITION pos = m_pColumns->GetHeadPosition();
  244. while(pos)
  245. {
  246. CString hdr = (CString)m_pColumns->GetNext(pos);
  247. AddColumn(hdr,nIndex++);
  248. }
  249. }
  250. //单击“扫描单个端口”单选按钮
  251. void CPortScanDlg::OnRadioSingle() 
  252. {
  253. m_bSinglePort = TRUE;
  254. m_cSinglePort.EnableWindow();
  255. m_cPortFrom.EnableWindow(FALSE);
  256. m_cPortTo.EnableWindow(FALSE);
  257. }
  258. //单击“扫描多个端口”单选按钮
  259. void CPortScanDlg::OnRadioRange() 
  260. {
  261. m_bSinglePort = FALSE;
  262. m_cSinglePort.EnableWindow(FALSE);
  263. m_cPortFrom.EnableWindow();
  264. m_cPortTo.EnableWindow();
  265. m_cBtnStop.EnableWindow(FALSE);
  266. }
  267. //开始扫描
  268. void CPortScanDlg::OnButtonScan() 
  269. {
  270. CString btnTxt,IP;
  271. UINT nSinglePort;
  272. BYTE f1,f2,f3,f4;
  273. TCHAR temp[10] = "";
  274. //设置进度条初始位置
  275. m_cProgress.SetPos(0);
  276. //清空列表框
  277. m_cResult.DeleteAllItems();
  278. //清空扫描结果链表
  279. POSITION p = m_pStatusList->GetHeadPosition();
  280. while (p)
  281. {
  282. POSITION temp = p;
  283. DATA* pNode = (DATA*)m_pStatusList->GetNext(p);
  284. m_pStatusList->RemoveAt(temp);
  285. if (pNode)
  286. delete pNode;
  287. }
  288. //如果输入没有主机地址
  289. if (m_cIP.IsBlank())
  290. {
  291. MessageBox(_T("Please specify the remote machine's IP address."),
  292. _T("Error"),
  293. MB_OK | MB_ICONEXCLAMATION);
  294. return;
  295. }
  296. //不合理的IP
  297. if (m_cIP.GetAddress(f1,f2,f3,f4) < 4)
  298. {
  299. MessageBox(_T("Please specify the IP address again."),
  300. _T("Invalid IP address"),MB_OK | MB_ICONEXCLAMATION);
  301. return;
  302. }
  303. //获得IP字符串
  304. IP = _itoa(f1,temp,10);
  305. IP += _T('.');
  306. IP += _itoa(f2,temp,10);
  307. IP += _T('.');
  308. IP += _itoa(f3,temp,10);
  309. IP += _T('.');
  310. IP += _itoa(f4,temp,10);
  311. //设置按钮状态
  312. m_cBtnStop.EnableWindow();
  313. m_cBtnScan.EnableWindow(FALSE);
  314. //扫描单个端口
  315. if (m_bSinglePort)
  316. {
  317. CString port;
  318. m_cSinglePort.GetWindowText(port);
  319. m_minPort = m_maxPort = nSinglePort = atoi(port);
  320. }
  321. else//扫描多个端口
  322. {
  323. CString port1,port2;
  324. m_cPortFrom.GetWindowText(port1);
  325. m_cPortTo.GetWindowText(port2);
  326. m_minPort = atoi(port1);
  327. m_maxPort = atoi(port2);
  328. m_cProgress.SetRange32(0,m_maxPort - m_minPort+1);
  329. m_cProgress.SetStep(1);
  330. }
  331. //不合理的端口范围
  332. if (!m_bSinglePort && m_maxPort < m_minPort)
  333. {
  334. MessageBox(_T("The maximum range cannot be less than the minimum one."),
  335. _T("Caution"),
  336. MB_OK | MB_ICONINFORMATION);
  337. return;
  338. }
  339. UINT m_nMaxAttempts = GetDlgItemInt(IDC_EDIT_ATTEMPTS);
  340. for (m_nCounter = m_minPort; m_nCounter <= m_maxPort; m_nCounter++)
  341. {
  342. BOOL bIsOpen = FALSE;
  343. UINT nAttempt = 1;
  344. while(nAttempt <= m_nMaxAttempts && !bIsOpen)
  345. {
  346. //显示扫描状态
  347. TCHAR temp[10]="";
  348. CString str = _T("Trying port# ");
  349. str += itoa(m_nCounter,temp,10);
  350. str += _T(", IP Address=");
  351. str += IP;
  352. str += _T(", Attempt=");
  353. str += itoa(nAttempt,temp,10);
  354. CStatic* pStatic = (CStatic*)GetDlgItem(IDC_STATIC_STATUS);
  355. pStatic->SetWindowText(str);
  356. str.Empty();
  357. //连接主机,测试端口是否打开
  358. bIsOpen = TestConnection(IP,m_nCounter);
  359. //如果是打开的,将结果保存到链表中
  360. if (bIsOpen)
  361. {
  362. DATA* pNode = new DATA;
  363. ASSERT(pNode);
  364. strcpy(pNode->IPAddress,IP.GetBuffer(IP.GetLength()));
  365. strcpy(pNode->port,_itoa(m_nCounter,temp,10));
  366. pNode->bStatus = 1; //open
  367. pNode->nAttempts = nAttempt;
  368. m_pStatusList->AddTail(pNode);
  369. }
  370. nAttempt++;
  371. }
  372. //如果没有被打开,也将结果保存到链表中
  373. if (!bIsOpen)
  374. {
  375. DATA* pNode = new DATA;
  376. ASSERT(pNode);
  377. strcpy(pNode->IPAddress,IP.GetBuffer(IP.GetLength()));
  378. strcpy(pNode->port,_itoa(m_nCounter,temp,10));
  379. pNode->bStatus = 0; //close
  380. pNode->nAttempts = nAttempt-1;
  381. m_pStatusList->AddTail(pNode);
  382. }
  383. MSG message;
  384. if (::PeekMessage(&message,NULL,0,0,PM_REMOVE))
  385. {
  386. ::TranslateMessage(&message);
  387. ::DispatchMessage(&message);
  388. }
  389. m_cProgress.StepIt();
  390. }
  391. //设置扫描完毕状态
  392. CStatic* pStatic = (CStatic*)GetDlgItem(IDC_STATIC_STATUS);
  393. pStatic->SetWindowText((CString)_T("Ready"));
  394. m_cBtnScan.EnableWindow();
  395. m_cBtnStop.EnableWindow(FALSE);
  396. //将扫描结果填充到列表框中
  397. UINT nIndex = 0;
  398. POSITION pos = m_pStatusList->GetHeadPosition();
  399. while (pos)
  400. {
  401. DATA* pNode = (DATA*)m_pStatusList->GetNext(pos);
  402. AddItem(nIndex,0,pNode->IPAddress);
  403. AddItem(nIndex,1,pNode->port);
  404. if (pNode->bStatus)
  405. {
  406. AddItem(nIndex,2,_T("Open"));
  407. AddItem(nIndex,4,_T("*"));
  408. }
  409. else
  410. {
  411. AddItem(nIndex,2,_T("Close"));
  412. AddItem(nIndex,4,_T(" "));
  413. }
  414. AddItem(nIndex++,3,_itoa(pNode->nAttempts,temp,10));
  415. }
  416. }
  417. //测试主机的某个端口是否打开
  418. BOOL CPortScanDlg::TestConnection(CString IP, UINT nPort)
  419. {
  420. //创建套节字
  421. CSocket* pSocket;
  422. pSocket = new CSocket;
  423. ASSERT(pSocket);
  424. if (!pSocket->Create())
  425. {
  426. delete pSocket;
  427. pSocket = NULL;
  428. return FALSE;
  429. }
  430. //连接主机
  431. while (!pSocket->Connect(IP , nPort))
  432. {
  433. delete pSocket;
  434. pSocket = NULL;
  435. return FALSE;
  436. }
  437. //清除套节字
  438. pSocket->Close();
  439. delete pSocket;
  440. return TRUE;
  441. }
  442. //停止扫描
  443. void CPortScanDlg::OnButtonStop() 
  444. {
  445. //设置控件状态
  446. m_nCounter = m_maxPort+1;
  447. m_cBtnStop.EnableWindow(FALSE);
  448. m_cBtnScan.EnableWindow();
  449. CStatic* pStatic = (CStatic*)GetDlgItem(IDC_STATIC_STATUS);
  450. pStatic->SetWindowText((CString)_T("Ready"));
  451. }
  452. //保存扫描结果到文本文件中
  453. void CPortScanDlg::OnButtonSave() 
  454. {
  455. //构造文件对话框
  456. CFileDialog* pDlg = new CFileDialog(FALSE,
  457. _T("txt"),NULL,
  458. OFN_OVERWRITEPROMPT | 
  459. OFN_EXPLORER | OFN_LONGNAMES,
  460. _T("Scanned ports files (*.txt)"),this);
  461. ASSERT(pDlg);
  462. if (pDlg->DoModal() == IDOK)
  463. {
  464. int nHandle,retVal;
  465. //打开文件
  466. nHandle = _open(pDlg->GetPathName(),_O_BINARY | _O_CREAT | _O_TRUNC | _O_RDWR);
  467. if (nHandle == -1)
  468. {
  469. MessageBox(_T("Unable to open output file to write."),
  470. _T("Error"),
  471. MB_OK | MB_ICONEXCLAMATION);
  472. delete pDlg;
  473. return;
  474. }
  475. //保存结果
  476. POSITION pos = m_pStatusList->GetHeadPosition();
  477. while (pos)
  478. {
  479. CString buffer;
  480. DATA* pNode = (DATA*)m_pStatusList->GetNext(pos);
  481. buffer = pNode->IPAddress;
  482. buffer += _T(',');
  483. buffer += pNode->port;
  484. buffer += _T(',');
  485. if (pNode->bStatus)
  486. buffer += _T("Open");
  487. else
  488. buffer += _T("Close");
  489. buffer += _T("rn");
  490. retVal = _write(nHandle,
  491. (void*)buffer.GetBuffer(buffer.GetLength()), 
  492. buffer.GetLength());
  493. if (retVal != buffer.GetLength())
  494. {
  495. MessageBox(_T("An error occured while writing records."),
  496. _T("Error"),MB_OK | MB_ICONEXCLAMATION);
  497. delete pDlg;
  498. return;
  499. }
  500. buffer.Empty();
  501. }
  502. //关闭文件
  503. _close(nHandle);
  504. }
  505. delete pDlg;
  506. }