Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

838 lines
22 KiB

  1. //============================================================================
  2. // Copyright(c) 1996, Microsoft Corporation
  3. //
  4. // File: ipfltr.cpp
  5. //
  6. // History:
  7. // 08/30/96 Ram Cherala Created
  8. //
  9. // Implementation of IP Filter dialog code
  10. //============================================================================
  11. #include "stdafx.h"
  12. #include "rtrfiltr.h"
  13. #include "ipfltr.h"
  14. #include "ipadd.h"
  15. #include <ipinfoid.h>
  16. #include "strmap.h"
  17. extern "C" {
  18. #include <winsock2.h>
  19. #include <fltdefs.h>
  20. #include <iprtinfo.h>
  21. }
  22. #include "ipaddr.h"
  23. #include "listctrl.h"
  24. #include "rtradmin.hm"
  25. #ifdef _DEBUG
  26. #define new DEBUG_NEW
  27. #undef THIS_FILE
  28. static char THIS_FILE[] = __FILE__;
  29. #endif
  30. static UINT uStringIdTable[] = { IDS_COL_SOURCEADDRESS,
  31. IDS_COL_SOURCEMASK,
  32. IDS_COL_DESTADDRESS,
  33. IDS_COL_DESTMASK,
  34. IDS_COL_PROTOCOL,
  35. IDS_COL_SOURCEPORT,
  36. IDS_COL_DESTPORT } ;
  37. CString s_stFilterUDP;
  38. CString s_stFilterTCP;
  39. CString s_stFilterICMP;
  40. CString s_stFilterAny;
  41. CString s_stFilterUnknown;
  42. const CStringMapEntry IPFilterProtocolMap[] =
  43. {
  44. { FILTER_PROTO_UDP, &s_stFilterUDP, IDS_PROTOCOL_UDP },
  45. { FILTER_PROTO_TCP, &s_stFilterTCP, IDS_PROTOCOL_TCP },
  46. { FILTER_PROTO_ICMP, &s_stFilterICMP, IDS_PROTOCOL_ICMP },
  47. { FILTER_PROTO_ANY, &s_stFilterAny, IDS_PROTOCOL_ANY },
  48. { -1, &s_stFilterUnknown, IDS_PROTOCOL_UNKNOWN },
  49. };
  50. CString& ProtocolTypeToCString(DWORD dwType)
  51. {
  52. return MapDWORDToCString(dwType, IPFilterProtocolMap);
  53. }
  54. /////////////////////////////////////////////////////////////////////////////
  55. // CIpFltr dialog
  56. CIpFltr::CIpFltr(CWnd* pParent,
  57. IInfoBase * pInfoBase,
  58. DWORD dwFilterType,
  59. UINT idd)
  60. : CBaseDialog(idd, pParent),
  61. m_pParent(pParent),
  62. m_dwFilterType(dwFilterType)
  63. {
  64. m_spInfoBase.Set(pInfoBase);
  65. //{{AFX_DATA_INIT(CIpFltr)
  66. // NOTE: the ClassWizard will add member initialization here
  67. //}}AFX_DATA_INIT
  68. // SetHelpMap(m_dwHelpMap);
  69. }
  70. CIpFltr::~CIpFltr()
  71. {
  72. while (!m_filterList.IsEmpty()) {
  73. delete (FilterListEntry*)m_filterList.RemoveHead();
  74. }
  75. }
  76. void CIpFltr::DoDataExchange(CDataExchange* pDX)
  77. {
  78. CBaseDialog::DoDataExchange(pDX);
  79. //{{AFX_DATA_MAP(CIpFltr)
  80. DDX_Control(pDX, IDC_IP_FILTER_LIST, m_listCtrl);
  81. //}}AFX_DATA_MAP
  82. }
  83. BEGIN_MESSAGE_MAP(CIpFltr, CBaseDialog)
  84. //{{AFX_MSG_MAP(CIpFltr)
  85. ON_BN_CLICKED(IDC_IP_FILTER_ADD, OnIpFilterAdd)
  86. ON_BN_CLICKED(IDC_IP_FILTER_DELETE, OnIpFilterDelete)
  87. ON_BN_CLICKED(IDC_IP_FILTER_EDIT, OnIpFilterEdit)
  88. ON_NOTIFY(LVN_GETDISPINFO, IDC_IP_FILTER_LIST, OnGetdispinfo)
  89. ON_NOTIFY(NM_DBLCLK, IDC_IP_FILTER_LIST, OnDblclkIpFilterList)
  90. ON_NOTIFY(LVN_ITEMCHANGED, IDC_IP_FILTER_LIST, OnNotifyListItemChanged)
  91. //}}AFX_MSG_MAP
  92. END_MESSAGE_MAP()
  93. DWORD CIpFltr::m_dwHelpMap[] =
  94. {
  95. // IDC_IP_PERMIT, HIDC_IP_PERMIT,
  96. // IDC_IP_DENY, HIDC_IP_DENY,
  97. // IDC_IP_FILTER_LIST, HIDC_IP_FILTER_LIST,
  98. // IDC_IP_FILTER_ADD, HIDC_IP_FILTER_ADD,
  99. // IDC_IP_FILTER_EDIT, HIDC_IP_FILTER_EDIT,
  100. // IDC_IP_FILTER_DELETE, HIDC_IP_FILTER_DELETE,
  101. 0,0,
  102. };
  103. /////////////////////////////////////////////////////////////////////////////
  104. // CIpFltr message handlers
  105. //------------------------------------------------------------------------------
  106. // Function: CIpFltr::OnInitDialog
  107. //
  108. // Handles 'WM_INITDIALOG' notification from the dialog
  109. //------------------------------------------------------------------------------
  110. BOOL CIpFltr::OnInitDialog()
  111. {
  112. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  113. UINT i;
  114. CBaseDialog::OnInitDialog();
  115. CRect rcDlg, rc;
  116. CString sCol;
  117. CString stTitle;
  118. HRESULT hr = hrOK;
  119. DWORD dwFilterType;
  120. UINT idsTitle = 0;
  121. Assert( m_dwFilterType == FILTER_INBOUND ||
  122. m_dwFilterType == FILTER_OUTBOUND ||
  123. m_dwFilterType == FILTER_DEMAND_DIAL ||
  124. m_dwFilterType == FILTER_PERUSER_IN ||
  125. m_dwFilterType == FILTER_PERUSER_OUT );
  126. m_stAny.LoadString(IDS_ANY);
  127. m_stUserMask.LoadString(IDS_USER_MASK);
  128. m_stUserAddress.LoadString(IDS_USER_ADDRESS);
  129. switch (m_dwFilterType)
  130. {
  131. case FILTER_PERUSER_OUT: // from RAS server's perspective, it's INBOUND ( but out from user )
  132. case FILTER_INBOUND:
  133. dwFilterType = IP_IN_FILTER_INFO;
  134. idsTitle = IDS_IP_TITLE_INPUT;
  135. break;
  136. default:
  137. case FILTER_PERUSER_IN: // from RAS server's perspective, it's OUTBOUND ( but out to user )
  138. case FILTER_OUTBOUND:
  139. dwFilterType = IP_OUT_FILTER_INFO;
  140. idsTitle = IDS_IP_TITLE_OUTPUT;
  141. break;
  142. case FILTER_DEMAND_DIAL:
  143. dwFilterType = IP_DEMAND_DIAL_FILTER_INFO;
  144. idsTitle = IDS_IP_TITLE_DD;
  145. break;
  146. }
  147. stTitle.LoadString(idsTitle);
  148. SetWindowText(stTitle);
  149. // initialize rectangle for list control display
  150. GetClientRect(rcDlg);
  151. // Initialize the mask controls
  152. // insert columns
  153. m_listCtrl.GetClientRect(&rc);
  154. for (i = 0; i < IP_NUM_COLUMNS; i++ ) {
  155. sCol.LoadString(uStringIdTable[i]);
  156. m_listCtrl.InsertColumn(i, sCol);
  157. AdjustColumnWidth(m_listCtrl, i, sCol);
  158. }
  159. // set extended attributes
  160. ListView_SetExtendedListViewStyle( m_listCtrl.m_hWnd, LVS_EX_FULLROWSELECT );
  161. InfoBlock * pBlock;
  162. FILTER_DESCRIPTOR * pIPfDescriptor;
  163. FILTER_INFO * pIPfInfo;
  164. DWORD dwCount;
  165. hr = m_spInfoBase->GetBlock( dwFilterType, &pBlock, 0);
  166. // The filter was previously defined
  167. if (FHrSucceeded(hr) && (pBlock->pData != NULL))
  168. {
  169. pIPfDescriptor = ( FILTER_DESCRIPTOR * ) pBlock->pData;
  170. SetFilterActionButtonsAndText(m_dwFilterType, pIPfDescriptor->faDefaultAction);
  171. dwCount = pIPfDescriptor->dwNumFilters;
  172. pIPfInfo = (FILTER_INFO*)pIPfDescriptor->fiFilter;
  173. for ( i = 0; i < dwCount; i++, pIPfInfo++ ) {
  174. FilterListEntry* pfle = new FilterListEntry;
  175. if (!pfle)
  176. {
  177. hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  178. break;
  179. }
  180. pfle->dwSrcAddr = pIPfInfo->dwSrcAddr;
  181. pfle->dwSrcMask = pIPfInfo->dwSrcMask;
  182. pfle->dwDstAddr = pIPfInfo->dwDstAddr;
  183. pfle->dwDstMask = pIPfInfo->dwDstMask;
  184. pfle->dwProtocol = pIPfInfo->dwProtocol;
  185. if( pfle->dwProtocol == FILTER_PROTO_TCP ||
  186. pfle->dwProtocol == FILTER_PROTO_UDP)
  187. {
  188. pfle->wSrcPort = ntohs(pIPfInfo->wSrcPort);
  189. pfle->wDstPort = ntohs(pIPfInfo->wDstPort);
  190. }
  191. else
  192. {
  193. pfle->wSrcPort = pIPfInfo->wSrcPort;
  194. pfle->wDstPort = pIPfInfo->wDstPort;
  195. }
  196. pfle->fLateBound = pIPfInfo->fLateBound;
  197. pfle->pos = m_filterList.AddTail(pfle);
  198. INT item = m_listCtrl.InsertItem( LVIF_TEXT|LVIF_PARAM, i, LPSTR_TEXTCALLBACK,
  199. 0,0,0, (LPARAM)pfle);
  200. if(item != -1) {m_listCtrl.SetItemData( item, (DWORD_PTR)pfle); }
  201. }
  202. }
  203. else {
  204. // This should not trigger an error to be reported
  205. hr = hrOK;
  206. SetFilterActionButtonsAndText(m_dwFilterType, PF_ACTION_FORWARD);
  207. }
  208. // select the first item in the list if list is not empty, else
  209. // disable the radio controls and set sate to Allow
  210. if( m_listCtrl.GetItemCount())
  211. {
  212. m_listCtrl.SetItemState(0, LVIS_SELECTED, LVIS_SELECTED);
  213. m_listCtrl.SetFocus();
  214. GetDlgItem(IDC_IP_FILTER_DELETE)->EnableWindow(TRUE);
  215. GetDlgItem(IDC_IP_FILTER_EDIT)->EnableWindow(TRUE);
  216. }
  217. else
  218. {
  219. SetFilterActionButtonsAndText(m_dwFilterType, PF_ACTION_FORWARD, FALSE);
  220. GetDlgItem(IDC_IP_FILTER_DELETE)->EnableWindow(FALSE);
  221. GetDlgItem(IDC_IP_FILTER_EDIT)->EnableWindow(FALSE);
  222. }
  223. if (!FHrSucceeded(hr))
  224. {
  225. // report construction error and return
  226. ::AfxMessageBox(IDS_CONSTRUCTION_ERROR);
  227. }
  228. return FALSE; // return TRUE unless you set the focus to a control
  229. // EXCEPTION: OCX Property Pages should return FALSE
  230. }
  231. //------------------------------------------------------------------------------
  232. // Function: CIpFltr::OnIpFilterAdd
  233. //
  234. // Handles 'BN_CLICKED' notification from the 'Add' button
  235. //------------------------------------------------------------------------------
  236. void CIpFltr::OnIpFilterAdd()
  237. {
  238. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  239. // Display the IP filter Add/Edit dialog
  240. //
  241. FilterListEntry* pfle = NULL;
  242. CIpFltrAddEdit dlg( this, (FilterListEntry**)&pfle, m_dwFilterType);
  243. if ( dlg.DoModal() != IDOK ) { m_listCtrl.SetFocus(); return; }
  244. // Add the newly configured filter to our list and update list control
  245. pfle->pos = m_filterList.AddTail( pfle );
  246. int item = m_listCtrl.InsertItem( LVIF_TEXT|LVIF_PARAM, 0, LPSTR_TEXTCALLBACK,
  247. 0,0,0, (LPARAM)pfle);
  248. if(item != -1) {m_listCtrl.SetItemData( item, (DWORD_PTR)pfle); }
  249. // enable radio controls when the first item is added to list
  250. if( m_listCtrl.GetItemCount() == 1)
  251. {
  252. SetFilterActionButtonsAndText(m_dwFilterType, PF_ACTION_FORWARD);
  253. }
  254. m_listCtrl.SetItemState(item, LVIS_SELECTED, LVIS_SELECTED);
  255. m_listCtrl.SetFocus();
  256. }
  257. //------------------------------------------------------------------------------
  258. // Function: CIpFltr::OnIpFilterEdit
  259. //
  260. // Handles 'BN_CLICKED' notification from the 'Edit' button
  261. //------------------------------------------------------------------------------
  262. void CIpFltr::OnIpFilterEdit()
  263. {
  264. // Get the current list selection
  265. // get the corresponding itemdata
  266. // pass it down to the CIpFltrAddEdit dialog
  267. //
  268. // Get the selected item
  269. //
  270. int i = m_listCtrl.GetNextItem(-1, LVNI_SELECTED);
  271. if (i == -1) { m_listCtrl.SetFocus(); return ; }
  272. //
  273. // Get the interface for the selected item
  274. //
  275. FilterListEntry* pfle = (FilterListEntry*)m_listCtrl.GetItemData(i);
  276. CIpFltrAddEdit dlg( this, (FilterListEntry**)&pfle, m_dwFilterType );
  277. if ( dlg.DoModal() != IDOK ) { return; }
  278. m_listCtrl.Update(i);
  279. m_listCtrl.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
  280. m_listCtrl.SetFocus();
  281. }
  282. //------------------------------------------------------------------------------
  283. // Function: CIpFltr::OnIpFilterDelete
  284. //
  285. // Handles 'BN_CLICKED' notification from the 'Delete' button
  286. //------------------------------------------------------------------------------
  287. void CIpFltr::OnIpFilterDelete()
  288. {
  289. // Get the current list selection
  290. // delete it from our private list
  291. // delete the item from the list or just refresh the list view
  292. //
  293. // Get the selected item
  294. //
  295. int i = m_listCtrl.GetNextItem(-1, LVNI_SELECTED);
  296. if (i == -1) { return ; }
  297. //
  298. // Get the interface for the selected item
  299. //
  300. FilterListEntry* pfle = (FilterListEntry*)m_listCtrl.GetItemData(i);
  301. //
  302. // delete it
  303. m_listCtrl.DeleteItem(i);
  304. m_filterList.RemoveAt(pfle->pos);
  305. delete pfle;
  306. //
  307. // select the next available list item
  308. //
  309. // disable radio controls if all items in list are deleted
  310. // they will be reenabled when the first filter is added to list
  311. if( !m_listCtrl.GetItemCount())
  312. {
  313. SetFilterActionButtonsAndText(m_dwFilterType, PF_ACTION_FORWARD, FALSE);
  314. }
  315. else if (m_listCtrl.GetItemCount() == i)
  316. m_listCtrl.SetItemState((i == 0? i: i-1), LVIS_SELECTED, LVIS_SELECTED);
  317. else
  318. m_listCtrl.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
  319. m_listCtrl.SetFocus();
  320. }
  321. //------------------------------------------------------------------------------
  322. // Function: CIpFltr::OnOK
  323. //
  324. // Handles 'BN_CLICKED' notification from the 'OK' button
  325. //------------------------------------------------------------------------------
  326. void CIpFltr::OnOK()
  327. {
  328. // If the filters information changed, write this to registry
  329. // and return
  330. DWORD dwSize, dwCount;
  331. HRESULT hr = hrOK;
  332. DWORD dwFilterType;
  333. switch (m_dwFilterType)
  334. {
  335. case FILTER_PERUSER_OUT:
  336. case FILTER_INBOUND:
  337. dwFilterType = IP_IN_FILTER_INFO;
  338. break;
  339. default:
  340. case FILTER_PERUSER_IN:
  341. case FILTER_OUTBOUND:
  342. dwFilterType = IP_OUT_FILTER_INFO;
  343. break;
  344. case FILTER_DEMAND_DIAL:
  345. dwFilterType = IP_DEMAND_DIAL_FILTER_INFO;
  346. break;
  347. }
  348. dwCount = (DWORD) m_filterList.GetCount();
  349. if(dwCount)
  350. {
  351. InfoBlock * pBlock = new InfoBlock;
  352. if (!pBlock) { // display an error message for no memory
  353. AfxMessageBox(IDS_ERROR_NO_MEMORY);
  354. return;
  355. };
  356. pBlock->dwType = dwFilterType;
  357. // dwCount -1 because FILTER_DESCRIPTOR already has room for one FILTER_INFO structure
  358. dwSize = pBlock->dwSize = sizeof( FILTER_DESCRIPTOR ) + ( (dwCount - 1) * sizeof (FILTER_INFO) );
  359. pBlock->dwCount = 1;
  360. pBlock->pData = new BYTE[dwSize];
  361. if(!pBlock->pData) { // display an error message for no memory
  362. AfxMessageBox(IDS_ERROR_NO_MEMORY);
  363. return;
  364. }
  365. FILTER_DESCRIPTOR * pIPfDescriptor;
  366. FILTER_INFO * pIPfInfo;
  367. pIPfDescriptor = (FILTER_DESCRIPTOR*) pBlock->pData;
  368. pIPfDescriptor->dwVersion = IP_FILTER_DRIVER_VERSION;
  369. pIPfDescriptor->dwNumFilters = dwCount;
  370. if (dwFilterType == IP_DEMAND_DIAL_FILTER_INFO)
  371. {
  372. pIPfDescriptor->faDefaultAction = IsDlgButtonChecked(IDC_IP_FILTER_ONLY) ?
  373. PF_ACTION_DROP : PF_ACTION_FORWARD;
  374. }
  375. else
  376. {
  377. pIPfDescriptor->faDefaultAction = IsDlgButtonChecked(IDC_IP_PERMIT) ?
  378. PF_ACTION_FORWARD : PF_ACTION_DROP;
  379. }
  380. pIPfInfo = (FILTER_INFO*)pIPfDescriptor->fiFilter;
  381. POSITION pos;
  382. pos = m_filterList.GetHeadPosition();
  383. while(pos) {
  384. FilterListEntry* pfle = (FilterListEntry*)m_filterList.GetNext(pos);
  385. pIPfInfo->dwSrcAddr = pfle->dwSrcAddr;
  386. pIPfInfo->dwSrcMask = pfle->dwSrcMask;
  387. pIPfInfo->dwDstAddr = pfle->dwDstAddr;
  388. pIPfInfo->dwDstMask = pfle->dwDstMask;
  389. pIPfInfo->dwProtocol = pfle->dwProtocol;
  390. if( pIPfInfo->dwProtocol == FILTER_PROTO_TCP ||
  391. pIPfInfo->dwProtocol == FILTER_PROTO_UDP)
  392. {
  393. pIPfInfo->wSrcPort = htons(pfle->wSrcPort);
  394. pIPfInfo->wDstPort = htons(pfle->wDstPort);
  395. }
  396. else if ( pIPfInfo->dwProtocol == FILTER_PROTO_ICMP )
  397. {
  398. pIPfInfo->wSrcPort = MAKEWORD(pfle->wSrcPort, 0x00);
  399. pIPfInfo->wDstPort = MAKEWORD(pfle->wDstPort, 0x00);
  400. }
  401. else
  402. {
  403. pIPfInfo->wSrcPort = pfle->wSrcPort;
  404. pIPfInfo->wDstPort = pfle->wDstPort;
  405. }
  406. pIPfInfo->fLateBound = pfle->fLateBound;
  407. pIPfInfo++;
  408. }
  409. if( FHrOK(m_spInfoBase->BlockExists(dwFilterType)))
  410. {
  411. hr = m_spInfoBase->SetBlock(
  412. dwFilterType,
  413. pBlock, 0);
  414. }
  415. else
  416. {
  417. hr = m_spInfoBase->AddBlock(
  418. dwFilterType,
  419. dwSize,
  420. pBlock->pData,
  421. 1, FALSE);
  422. }
  423. if (!FHrSucceeded(hr))
  424. {
  425. AfxMessageBox(IDS_ERROR_SETTING_BLOCK);
  426. }
  427. delete[] pBlock->pData;
  428. delete pBlock;
  429. }
  430. else
  431. {
  432. // remove any previously defined filters
  433. InfoBlock * pBlock = new InfoBlock;
  434. if (!pBlock) { // display an error message for no memory
  435. AfxMessageBox(IDS_ERROR_NO_MEMORY);
  436. return;
  437. };
  438. pBlock->dwType = dwFilterType;
  439. dwSize = pBlock->dwSize = FIELD_OFFSET(FILTER_DESCRIPTOR,fiFilter[0]);
  440. pBlock->dwCount = 1;
  441. pBlock->pData = new BYTE[dwSize];
  442. if(!pBlock->pData) { // display an error message for no memory
  443. delete pBlock;
  444. AfxMessageBox(IDS_ERROR_NO_MEMORY);
  445. return;
  446. }
  447. FILTER_DESCRIPTOR * pIPfDescriptor;
  448. FILTER_INFO * pIPfInfo;
  449. pIPfDescriptor = (FILTER_DESCRIPTOR*) pBlock->pData;
  450. if (dwFilterType == IP_DEMAND_DIAL_FILTER_INFO)
  451. {
  452. pIPfDescriptor->faDefaultAction = IsDlgButtonChecked(
  453. IDC_IP_FILTER_ONLY) ?
  454. PF_ACTION_DROP : PF_ACTION_FORWARD;
  455. }
  456. else
  457. {
  458. pIPfDescriptor->faDefaultAction = IsDlgButtonChecked(IDC_IP_PERMIT) ?
  459. PF_ACTION_FORWARD : PF_ACTION_DROP;
  460. }
  461. pIPfDescriptor->dwVersion = IP_FILTER_DRIVER_VERSION;
  462. pIPfDescriptor->dwNumFilters = 0;
  463. if( FHrOK(m_spInfoBase->BlockExists(dwFilterType)))
  464. {
  465. hr = m_spInfoBase->SetBlock( dwFilterType,
  466. pBlock, 0);
  467. }
  468. else
  469. {
  470. hr = m_spInfoBase->AddBlock( dwFilterType,
  471. dwSize,
  472. pBlock->pData,
  473. 1, FALSE);
  474. }
  475. if (!FHrSucceeded(hr))
  476. {
  477. AfxMessageBox(IDS_ERROR_SETTING_BLOCK);
  478. }
  479. delete[] pBlock->pData;
  480. delete pBlock;
  481. // hr = m_spInfoBase->RemoveBlock(m_dwFilterType == FILTER_INBOUND ? IP_IN_FILTER_INFO : IP_OUT_FILTER_INFO);
  482. }
  483. CBaseDialog::OnOK();
  484. }
  485. void CIpFltr::OnCancel()
  486. {
  487. // TODO: Add extra cleanup here
  488. CBaseDialog::OnCancel();
  489. }
  490. enum {
  491. SRC_ADDRESS=0,
  492. SRC_MASK,
  493. DEST_ADDRESS,
  494. DEST_MASK,
  495. PROTOCOL,
  496. SRC_PORT,
  497. DEST_PORT
  498. };
  499. //------------------------------------------------------------------------------
  500. // Function: CIpFltr::OnGetdispinfo
  501. //
  502. // Handles 'LVN_GETDISPINFO' notification from the list control
  503. //------------------------------------------------------------------------------
  504. void CIpFltr::OnGetdispinfo(NMHDR* pNMHDR, LRESULT* pResult)
  505. {
  506. static WCHAR s_szDestPortBuffer[32];
  507. static WCHAR s_szSrcPortBuffer[32];
  508. LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
  509. FilterListEntry * pfle = (FilterListEntry*)pDispInfo->item.lParam;
  510. // Setup the default condition
  511. pDispInfo->item.pszText = (LPTSTR) (LPCTSTR) m_stAny;
  512. switch( pDispInfo->hdr.code )
  513. {
  514. case LVN_GETDISPINFO:
  515. switch( pDispInfo->item.iSubItem )
  516. {
  517. case SRC_ADDRESS:
  518. if (m_dwFilterType == FILTER_PERUSER_OUT)
  519. pDispInfo->item.pszText = (LPTSTR)(LPCTSTR) m_stUserAddress;
  520. else
  521. {
  522. if (pfle->dwSrcAddr != 0)
  523. pDispInfo->item.pszText = INET_NTOA(pfle->dwSrcAddr);
  524. }
  525. break;
  526. case SRC_MASK:
  527. if (m_dwFilterType == FILTER_PERUSER_OUT)
  528. pDispInfo->item.pszText = (LPTSTR) (LPCTSTR) m_stUserMask;
  529. else
  530. {
  531. if (pfle->dwSrcMask != 0)
  532. pDispInfo->item.pszText = INET_NTOA(pfle->dwSrcMask);
  533. }
  534. break;
  535. case DEST_ADDRESS:
  536. if (m_dwFilterType == FILTER_PERUSER_IN)
  537. pDispInfo->item.pszText = (LPTSTR) (LPCTSTR) m_stUserAddress;
  538. else
  539. {
  540. if (pfle->dwDstAddr != 0)
  541. pDispInfo->item.pszText = INET_NTOA(pfle->dwDstAddr);
  542. }
  543. break;
  544. case DEST_MASK:
  545. if (m_dwFilterType == FILTER_PERUSER_IN)
  546. pDispInfo->item.pszText = (LPTSTR) (LPCTSTR) m_stUserMask;
  547. else
  548. {
  549. if (pfle->dwDstMask != 0)
  550. pDispInfo->item.pszText = INET_NTOA(pfle->dwDstMask);
  551. }
  552. break;
  553. case PROTOCOL:
  554. // known protocol, display string, else number
  555. m_stTempOther = GetProtocolString(pfle->dwProtocol,pfle->fLateBound);
  556. pDispInfo->item.pszText = (LPTSTR) (LPCTSTR)m_stTempOther;
  557. break;
  558. case SRC_PORT:
  559. if (pfle->dwProtocol == FILTER_PROTO_ICMP)
  560. {
  561. if (pfle->wSrcPort != FILTER_ICMP_TYPE_ANY)
  562. pDispInfo->item.pszText = (LPTSTR)_itow(pfle->wSrcPort,
  563. s_szSrcPortBuffer, 10);
  564. }
  565. else
  566. {
  567. if (pfle->wSrcPort != 0)
  568. pDispInfo->item.pszText = (LPTSTR)_itow(pfle->wSrcPort,
  569. s_szSrcPortBuffer, 10);
  570. }
  571. break;
  572. case DEST_PORT:
  573. if (pfle->dwProtocol == FILTER_PROTO_ICMP)
  574. {
  575. if (pfle->wSrcPort != FILTER_ICMP_CODE_ANY)
  576. pDispInfo->item.pszText = (LPTSTR)_itow(pfle->wDstPort,
  577. s_szDestPortBuffer, 10);
  578. }
  579. else
  580. {
  581. if (pfle->wDstPort != 0)
  582. pDispInfo->item.pszText = (LPTSTR)_itow(pfle->wDstPort,
  583. s_szDestPortBuffer, 10);
  584. }
  585. break;
  586. default:
  587. break;
  588. }
  589. }
  590. *pResult = 0;
  591. }
  592. // --------------------------------------------------------------------
  593. // Function: CIpFltr::GetProtocolString
  594. //
  595. // returns protocol names for known protocols
  596. // --------------------------------------------------------------------
  597. CString CIpFltr::GetProtocolString(DWORD dwProtocol, DWORD fFlags)
  598. {
  599. WCHAR buffer[32];
  600. CString st;
  601. switch (dwProtocol)
  602. {
  603. case FILTER_PROTO_TCP:
  604. st = ProtocolTypeToCString(dwProtocol);
  605. if(fFlags & TCP_ESTABLISHED_FLAG)
  606. {
  607. st.LoadString(IDS_PROTOCOL_TCP_ESTABLISHED);
  608. }
  609. break;
  610. case FILTER_PROTO_UDP:
  611. case FILTER_PROTO_ICMP:
  612. case FILTER_PROTO_ANY:
  613. st = ProtocolTypeToCString(dwProtocol);
  614. break;
  615. default:
  616. st = (LPTSTR) _itow(dwProtocol, buffer, 10);
  617. break;
  618. }
  619. return st;
  620. }
  621. //------------------------------------------------------------------------------
  622. // Function: CIpFltr::SetFilterActionButtonsAndText
  623. //
  624. // Called to set the 'Filter Action' radio-buttons and corresponding text
  625. // Enables/Disables controls based on 'bEnable' value - defaults to enable
  626. //------------------------------------------------------------------------------
  627. VOID
  628. CIpFltr::SetFilterActionButtonsAndText(
  629. DWORD dwFilterType,
  630. DWORD dwAction,
  631. BOOL bEnable
  632. )
  633. {
  634. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  635. if (dwFilterType == FILTER_DEMAND_DIAL)
  636. {
  637. CheckDlgButton( IDC_IP_FILTER_ONLY, dwAction == PF_ACTION_DROP );
  638. CheckDlgButton( IDC_IP_FILTER_ALL, dwAction == PF_ACTION_FORWARD );
  639. GetDlgItem(IDC_IP_FILTER_ONLY)->EnableWindow(bEnable);
  640. GetDlgItem(IDC_IP_FILTER_ALL)->EnableWindow(bEnable);
  641. }
  642. else if ((dwFilterType == FILTER_PERUSER_IN) ||
  643. (dwFilterType == FILTER_PERUSER_OUT))
  644. {
  645. CheckDlgButton( IDC_IP_PERMIT, dwAction == PF_ACTION_FORWARD );
  646. CheckDlgButton( IDC_IP_DENY, dwAction == PF_ACTION_DROP );
  647. CString sItem;
  648. GetDlgItem(IDC_IP_PERMIT)->EnableWindow(bEnable);
  649. GetDlgItem(IDC_IP_DENY)->EnableWindow(bEnable);
  650. sItem.LoadString(IDS_PERUSER_PERMIT);
  651. SetDlgItemText( IDC_IP_PERMIT, sItem );
  652. sItem.LoadString(IDS_PERUSER_DENY);
  653. SetDlgItemText( IDC_IP_DENY, sItem );
  654. }
  655. else
  656. {
  657. CheckDlgButton( IDC_IP_PERMIT, dwAction == PF_ACTION_FORWARD );
  658. CheckDlgButton( IDC_IP_DENY, dwAction == PF_ACTION_DROP );
  659. CString sItem;
  660. GetDlgItem(IDC_IP_PERMIT)->EnableWindow(bEnable);
  661. GetDlgItem(IDC_IP_DENY)->EnableWindow(bEnable);
  662. sItem.LoadString( dwFilterType == FILTER_INBOUND? IDS_RECEIVE : IDS_TRANSMIT );
  663. SetDlgItemText( IDC_IP_PERMIT, sItem );
  664. sItem.LoadString( IDS_DROP );
  665. SetDlgItemText( IDC_IP_DENY, sItem );
  666. }
  667. }
  668. //------------------------------------------------------------------------------
  669. // Function: CIpFltr::OnDoubleclickedIpFilterList
  670. // `
  671. // Handles 'NM_DBLCLK' notification from the Filter list control
  672. //------------------------------------------------------------------------------
  673. void CIpFltr::OnDblclkIpFilterList(NMHDR* pNMHDR, LRESULT* pResult)
  674. {
  675. OnIpFilterEdit();
  676. *pResult = 0;
  677. }
  678. void CIpFltr::OnNotifyListItemChanged(NMHDR *pNmHdr, LRESULT *pResult)
  679. {
  680. NMLISTVIEW * pnmlv = reinterpret_cast<NMLISTVIEW *>(pNmHdr);
  681. BOOL fSelected;
  682. fSelected = (m_listCtrl.GetNextItem(-1, LVNI_SELECTED) != -1);
  683. GetDlgItem(IDC_IP_FILTER_DELETE)->EnableWindow(fSelected);
  684. GetDlgItem(IDC_IP_FILTER_EDIT)->EnableWindow(fSelected);
  685. }
  686. /////////////////////////////////////////////////////////////////////////////
  687. // CIpFltrDD dialog
  688. CIpFltrDD::CIpFltrDD(CWnd* pParent,
  689. IInfoBase * pInfoBase,
  690. DWORD dwFilterType)
  691. : CIpFltr(pParent, pInfoBase, dwFilterType, CIpFltrDD::IDD)
  692. {
  693. //{{AFX_DATA_INIT(CIpFltrDD)
  694. // NOTE: the ClassWizard will add member initialization here
  695. //}}AFX_DATA_INIT
  696. // SetHelpMap(m_dwHelpMap);
  697. }
  698. CIpFltrDD::~CIpFltrDD()
  699. {
  700. }