Leaked source code of windows server 2003
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.

840 lines
23 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. stTitle.LoadString(IDS_OUTPUT_TEXT);
  142. SetDlgItemText(IDC_STATIC, stTitle);
  143. break;
  144. case FILTER_DEMAND_DIAL:
  145. dwFilterType = IP_DEMAND_DIAL_FILTER_INFO;
  146. idsTitle = IDS_IP_TITLE_DD;
  147. break;
  148. }
  149. stTitle.LoadString(idsTitle);
  150. SetWindowText(stTitle);
  151. // initialize rectangle for list control display
  152. GetClientRect(rcDlg);
  153. // Initialize the mask controls
  154. // insert columns
  155. m_listCtrl.GetClientRect(&rc);
  156. for (i = 0; i < IP_NUM_COLUMNS; i++ ) {
  157. sCol.LoadString(uStringIdTable[i]);
  158. m_listCtrl.InsertColumn(i, sCol);
  159. AdjustColumnWidth(m_listCtrl, i, sCol);
  160. }
  161. // set extended attributes
  162. ListView_SetExtendedListViewStyle( m_listCtrl.m_hWnd, LVS_EX_FULLROWSELECT );
  163. InfoBlock * pBlock;
  164. FILTER_DESCRIPTOR * pIPfDescriptor;
  165. FILTER_INFO * pIPfInfo;
  166. DWORD dwCount;
  167. hr = m_spInfoBase->GetBlock( dwFilterType, &pBlock, 0);
  168. // The filter was previously defined
  169. if (FHrSucceeded(hr) && (pBlock->pData != NULL))
  170. {
  171. pIPfDescriptor = ( FILTER_DESCRIPTOR * ) pBlock->pData;
  172. SetFilterActionButtonsAndText(m_dwFilterType, pIPfDescriptor->faDefaultAction);
  173. dwCount = pIPfDescriptor->dwNumFilters;
  174. pIPfInfo = (FILTER_INFO*)pIPfDescriptor->fiFilter;
  175. for ( i = 0; i < dwCount; i++, pIPfInfo++ ) {
  176. FilterListEntry* pfle = new FilterListEntry;
  177. if (!pfle)
  178. {
  179. hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  180. break;
  181. }
  182. pfle->dwSrcAddr = pIPfInfo->dwSrcAddr;
  183. pfle->dwSrcMask = pIPfInfo->dwSrcMask;
  184. pfle->dwDstAddr = pIPfInfo->dwDstAddr;
  185. pfle->dwDstMask = pIPfInfo->dwDstMask;
  186. pfle->dwProtocol = pIPfInfo->dwProtocol;
  187. if( pfle->dwProtocol == FILTER_PROTO_TCP ||
  188. pfle->dwProtocol == FILTER_PROTO_UDP)
  189. {
  190. pfle->wSrcPort = ntohs(pIPfInfo->wSrcPort);
  191. pfle->wDstPort = ntohs(pIPfInfo->wDstPort);
  192. }
  193. else
  194. {
  195. pfle->wSrcPort = pIPfInfo->wSrcPort;
  196. pfle->wDstPort = pIPfInfo->wDstPort;
  197. }
  198. pfle->fLateBound = pIPfInfo->fLateBound;
  199. pfle->pos = m_filterList.AddTail(pfle);
  200. INT item = m_listCtrl.InsertItem( LVIF_TEXT|LVIF_PARAM, i, LPSTR_TEXTCALLBACK,
  201. 0,0,0, (LPARAM)pfle);
  202. if(item != -1) {m_listCtrl.SetItemData( item, (DWORD_PTR)pfle); }
  203. }
  204. }
  205. else {
  206. // This should not trigger an error to be reported
  207. hr = hrOK;
  208. SetFilterActionButtonsAndText(m_dwFilterType, PF_ACTION_FORWARD);
  209. }
  210. // select the first item in the list if list is not empty, else
  211. // disable the radio controls and set sate to Allow
  212. if( m_listCtrl.GetItemCount())
  213. {
  214. m_listCtrl.SetItemState(0, LVIS_SELECTED, LVIS_SELECTED);
  215. m_listCtrl.SetFocus();
  216. GetDlgItem(IDC_IP_FILTER_DELETE)->EnableWindow(TRUE);
  217. GetDlgItem(IDC_IP_FILTER_EDIT)->EnableWindow(TRUE);
  218. }
  219. else
  220. {
  221. SetFilterActionButtonsAndText(m_dwFilterType, PF_ACTION_FORWARD, FALSE);
  222. GetDlgItem(IDC_IP_FILTER_DELETE)->EnableWindow(FALSE);
  223. GetDlgItem(IDC_IP_FILTER_EDIT)->EnableWindow(FALSE);
  224. }
  225. if (!FHrSucceeded(hr))
  226. {
  227. // report construction error and return
  228. ::AfxMessageBox(IDS_CONSTRUCTION_ERROR);
  229. }
  230. return FALSE; // return TRUE unless you set the focus to a control
  231. // EXCEPTION: OCX Property Pages should return FALSE
  232. }
  233. //------------------------------------------------------------------------------
  234. // Function: CIpFltr::OnIpFilterAdd
  235. //
  236. // Handles 'BN_CLICKED' notification from the 'Add' button
  237. //------------------------------------------------------------------------------
  238. void CIpFltr::OnIpFilterAdd()
  239. {
  240. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  241. // Display the IP filter Add/Edit dialog
  242. //
  243. FilterListEntry* pfle = NULL;
  244. CIpFltrAddEdit dlg( this, (FilterListEntry**)&pfle, m_dwFilterType);
  245. if ( dlg.DoModal() != IDOK ) { m_listCtrl.SetFocus(); return; }
  246. // Add the newly configured filter to our list and update list control
  247. pfle->pos = m_filterList.AddTail( pfle );
  248. int item = m_listCtrl.InsertItem( LVIF_TEXT|LVIF_PARAM, 0, LPSTR_TEXTCALLBACK,
  249. 0,0,0, (LPARAM)pfle);
  250. if(item != -1) {m_listCtrl.SetItemData( item, (DWORD_PTR)pfle); }
  251. // enable radio controls when the first item is added to list
  252. if( m_listCtrl.GetItemCount() == 1)
  253. {
  254. SetFilterActionButtonsAndText(m_dwFilterType, PF_ACTION_FORWARD);
  255. }
  256. m_listCtrl.SetItemState(item, LVIS_SELECTED, LVIS_SELECTED);
  257. m_listCtrl.SetFocus();
  258. }
  259. //------------------------------------------------------------------------------
  260. // Function: CIpFltr::OnIpFilterEdit
  261. //
  262. // Handles 'BN_CLICKED' notification from the 'Edit' button
  263. //------------------------------------------------------------------------------
  264. void CIpFltr::OnIpFilterEdit()
  265. {
  266. // Get the current list selection
  267. // get the corresponding itemdata
  268. // pass it down to the CIpFltrAddEdit dialog
  269. //
  270. // Get the selected item
  271. //
  272. int i = m_listCtrl.GetNextItem(-1, LVNI_SELECTED);
  273. if (i == -1) { m_listCtrl.SetFocus(); return ; }
  274. //
  275. // Get the interface for the selected item
  276. //
  277. FilterListEntry* pfle = (FilterListEntry*)m_listCtrl.GetItemData(i);
  278. CIpFltrAddEdit dlg( this, (FilterListEntry**)&pfle, m_dwFilterType );
  279. if ( dlg.DoModal() != IDOK ) { return; }
  280. m_listCtrl.Update(i);
  281. m_listCtrl.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
  282. m_listCtrl.SetFocus();
  283. }
  284. //------------------------------------------------------------------------------
  285. // Function: CIpFltr::OnIpFilterDelete
  286. //
  287. // Handles 'BN_CLICKED' notification from the 'Delete' button
  288. //------------------------------------------------------------------------------
  289. void CIpFltr::OnIpFilterDelete()
  290. {
  291. // Get the current list selection
  292. // delete it from our private list
  293. // delete the item from the list or just refresh the list view
  294. //
  295. // Get the selected item
  296. //
  297. int i = m_listCtrl.GetNextItem(-1, LVNI_SELECTED);
  298. if (i == -1) { return ; }
  299. //
  300. // Get the interface for the selected item
  301. //
  302. FilterListEntry* pfle = (FilterListEntry*)m_listCtrl.GetItemData(i);
  303. //
  304. // delete it
  305. m_listCtrl.DeleteItem(i);
  306. m_filterList.RemoveAt(pfle->pos);
  307. delete pfle;
  308. //
  309. // select the next available list item
  310. //
  311. // disable radio controls if all items in list are deleted
  312. // they will be reenabled when the first filter is added to list
  313. if( !m_listCtrl.GetItemCount())
  314. {
  315. SetFilterActionButtonsAndText(m_dwFilterType, PF_ACTION_FORWARD, FALSE);
  316. }
  317. else if (m_listCtrl.GetItemCount() == i)
  318. m_listCtrl.SetItemState((i == 0? i: i-1), LVIS_SELECTED, LVIS_SELECTED);
  319. else
  320. m_listCtrl.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
  321. m_listCtrl.SetFocus();
  322. }
  323. //------------------------------------------------------------------------------
  324. // Function: CIpFltr::OnOK
  325. //
  326. // Handles 'BN_CLICKED' notification from the 'OK' button
  327. //------------------------------------------------------------------------------
  328. void CIpFltr::OnOK()
  329. {
  330. // If the filters information changed, write this to registry
  331. // and return
  332. DWORD dwSize, dwCount;
  333. HRESULT hr = hrOK;
  334. DWORD dwFilterType;
  335. switch (m_dwFilterType)
  336. {
  337. case FILTER_PERUSER_OUT:
  338. case FILTER_INBOUND:
  339. dwFilterType = IP_IN_FILTER_INFO;
  340. break;
  341. default:
  342. case FILTER_PERUSER_IN:
  343. case FILTER_OUTBOUND:
  344. dwFilterType = IP_OUT_FILTER_INFO;
  345. break;
  346. case FILTER_DEMAND_DIAL:
  347. dwFilterType = IP_DEMAND_DIAL_FILTER_INFO;
  348. break;
  349. }
  350. dwCount = (DWORD) m_filterList.GetCount();
  351. if(dwCount)
  352. {
  353. InfoBlock * pBlock = new InfoBlock;
  354. if (!pBlock) { // display an error message for no memory
  355. AfxMessageBox(IDS_ERROR_NO_MEMORY);
  356. return;
  357. };
  358. pBlock->dwType = dwFilterType;
  359. // dwCount -1 because FILTER_DESCRIPTOR already has room for one FILTER_INFO structure
  360. dwSize = pBlock->dwSize = sizeof( FILTER_DESCRIPTOR ) + ( (dwCount - 1) * sizeof (FILTER_INFO) );
  361. pBlock->dwCount = 1;
  362. pBlock->pData = new BYTE[dwSize];
  363. if(!pBlock->pData) { // display an error message for no memory
  364. AfxMessageBox(IDS_ERROR_NO_MEMORY);
  365. return;
  366. }
  367. FILTER_DESCRIPTOR * pIPfDescriptor;
  368. FILTER_INFO * pIPfInfo;
  369. pIPfDescriptor = (FILTER_DESCRIPTOR*) pBlock->pData;
  370. pIPfDescriptor->dwVersion = IP_FILTER_DRIVER_VERSION;
  371. pIPfDescriptor->dwNumFilters = dwCount;
  372. if (dwFilterType == IP_DEMAND_DIAL_FILTER_INFO)
  373. {
  374. pIPfDescriptor->faDefaultAction = IsDlgButtonChecked(IDC_IP_FILTER_ONLY) ?
  375. PF_ACTION_DROP : PF_ACTION_FORWARD;
  376. }
  377. else
  378. {
  379. pIPfDescriptor->faDefaultAction = IsDlgButtonChecked(IDC_IP_PERMIT) ?
  380. PF_ACTION_FORWARD : PF_ACTION_DROP;
  381. }
  382. pIPfInfo = (FILTER_INFO*)pIPfDescriptor->fiFilter;
  383. POSITION pos;
  384. pos = m_filterList.GetHeadPosition();
  385. while(pos) {
  386. FilterListEntry* pfle = (FilterListEntry*)m_filterList.GetNext(pos);
  387. pIPfInfo->dwSrcAddr = pfle->dwSrcAddr;
  388. pIPfInfo->dwSrcMask = pfle->dwSrcMask;
  389. pIPfInfo->dwDstAddr = pfle->dwDstAddr;
  390. pIPfInfo->dwDstMask = pfle->dwDstMask;
  391. pIPfInfo->dwProtocol = pfle->dwProtocol;
  392. if( pIPfInfo->dwProtocol == FILTER_PROTO_TCP ||
  393. pIPfInfo->dwProtocol == FILTER_PROTO_UDP)
  394. {
  395. pIPfInfo->wSrcPort = htons(pfle->wSrcPort);
  396. pIPfInfo->wDstPort = htons(pfle->wDstPort);
  397. }
  398. else if ( pIPfInfo->dwProtocol == FILTER_PROTO_ICMP )
  399. {
  400. pIPfInfo->wSrcPort = MAKEWORD(pfle->wSrcPort, 0x00);
  401. pIPfInfo->wDstPort = MAKEWORD(pfle->wDstPort, 0x00);
  402. }
  403. else
  404. {
  405. pIPfInfo->wSrcPort = pfle->wSrcPort;
  406. pIPfInfo->wDstPort = pfle->wDstPort;
  407. }
  408. pIPfInfo->fLateBound = pfle->fLateBound;
  409. pIPfInfo++;
  410. }
  411. if( FHrOK(m_spInfoBase->BlockExists(dwFilterType)))
  412. {
  413. hr = m_spInfoBase->SetBlock(
  414. dwFilterType,
  415. pBlock, 0);
  416. }
  417. else
  418. {
  419. hr = m_spInfoBase->AddBlock(
  420. dwFilterType,
  421. dwSize,
  422. pBlock->pData,
  423. 1, FALSE);
  424. }
  425. if (!FHrSucceeded(hr))
  426. {
  427. AfxMessageBox(IDS_ERROR_SETTING_BLOCK);
  428. }
  429. delete[] pBlock->pData;
  430. delete pBlock;
  431. }
  432. else
  433. {
  434. // remove any previously defined filters
  435. InfoBlock * pBlock = new InfoBlock;
  436. if (!pBlock) { // display an error message for no memory
  437. AfxMessageBox(IDS_ERROR_NO_MEMORY);
  438. return;
  439. };
  440. pBlock->dwType = dwFilterType;
  441. dwSize = pBlock->dwSize = FIELD_OFFSET(FILTER_DESCRIPTOR,fiFilter[0]);
  442. pBlock->dwCount = 1;
  443. pBlock->pData = new BYTE[dwSize];
  444. if(!pBlock->pData) { // display an error message for no memory
  445. delete pBlock;
  446. AfxMessageBox(IDS_ERROR_NO_MEMORY);
  447. return;
  448. }
  449. FILTER_DESCRIPTOR * pIPfDescriptor;
  450. FILTER_INFO * pIPfInfo;
  451. pIPfDescriptor = (FILTER_DESCRIPTOR*) pBlock->pData;
  452. if (dwFilterType == IP_DEMAND_DIAL_FILTER_INFO)
  453. {
  454. pIPfDescriptor->faDefaultAction = IsDlgButtonChecked(
  455. IDC_IP_FILTER_ONLY) ?
  456. PF_ACTION_DROP : PF_ACTION_FORWARD;
  457. }
  458. else
  459. {
  460. pIPfDescriptor->faDefaultAction = IsDlgButtonChecked(IDC_IP_PERMIT) ?
  461. PF_ACTION_FORWARD : PF_ACTION_DROP;
  462. }
  463. pIPfDescriptor->dwVersion = IP_FILTER_DRIVER_VERSION;
  464. pIPfDescriptor->dwNumFilters = 0;
  465. if( FHrOK(m_spInfoBase->BlockExists(dwFilterType)))
  466. {
  467. hr = m_spInfoBase->SetBlock( dwFilterType,
  468. pBlock, 0);
  469. }
  470. else
  471. {
  472. hr = m_spInfoBase->AddBlock( dwFilterType,
  473. dwSize,
  474. pBlock->pData,
  475. 1, FALSE);
  476. }
  477. if (!FHrSucceeded(hr))
  478. {
  479. AfxMessageBox(IDS_ERROR_SETTING_BLOCK);
  480. }
  481. delete[] pBlock->pData;
  482. delete pBlock;
  483. // hr = m_spInfoBase->RemoveBlock(m_dwFilterType == FILTER_INBOUND ? IP_IN_FILTER_INFO : IP_OUT_FILTER_INFO);
  484. }
  485. CBaseDialog::OnOK();
  486. }
  487. void CIpFltr::OnCancel()
  488. {
  489. // TODO: Add extra cleanup here
  490. CBaseDialog::OnCancel();
  491. }
  492. enum {
  493. SRC_ADDRESS=0,
  494. SRC_MASK,
  495. DEST_ADDRESS,
  496. DEST_MASK,
  497. PROTOCOL,
  498. SRC_PORT,
  499. DEST_PORT
  500. };
  501. //------------------------------------------------------------------------------
  502. // Function: CIpFltr::OnGetdispinfo
  503. //
  504. // Handles 'LVN_GETDISPINFO' notification from the list control
  505. //------------------------------------------------------------------------------
  506. void CIpFltr::OnGetdispinfo(NMHDR* pNMHDR, LRESULT* pResult)
  507. {
  508. static WCHAR s_szDestPortBuffer[32];
  509. static WCHAR s_szSrcPortBuffer[32];
  510. LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
  511. FilterListEntry * pfle = (FilterListEntry*)pDispInfo->item.lParam;
  512. // Setup the default condition
  513. pDispInfo->item.pszText = (LPTSTR) (LPCTSTR) m_stAny;
  514. switch( pDispInfo->hdr.code )
  515. {
  516. case LVN_GETDISPINFO:
  517. switch( pDispInfo->item.iSubItem )
  518. {
  519. case SRC_ADDRESS:
  520. if (m_dwFilterType == FILTER_PERUSER_OUT)
  521. pDispInfo->item.pszText = (LPTSTR)(LPCTSTR) m_stUserAddress;
  522. else
  523. {
  524. if (pfle->dwSrcAddr != 0)
  525. pDispInfo->item.pszText = INET_NTOA(pfle->dwSrcAddr);
  526. }
  527. break;
  528. case SRC_MASK:
  529. if (m_dwFilterType == FILTER_PERUSER_OUT)
  530. pDispInfo->item.pszText = (LPTSTR) (LPCTSTR) m_stUserMask;
  531. else
  532. {
  533. if (pfle->dwSrcMask != 0)
  534. pDispInfo->item.pszText = INET_NTOA(pfle->dwSrcMask);
  535. }
  536. break;
  537. case DEST_ADDRESS:
  538. if (m_dwFilterType == FILTER_PERUSER_IN)
  539. pDispInfo->item.pszText = (LPTSTR) (LPCTSTR) m_stUserAddress;
  540. else
  541. {
  542. if (pfle->dwDstAddr != 0)
  543. pDispInfo->item.pszText = INET_NTOA(pfle->dwDstAddr);
  544. }
  545. break;
  546. case DEST_MASK:
  547. if (m_dwFilterType == FILTER_PERUSER_IN)
  548. pDispInfo->item.pszText = (LPTSTR) (LPCTSTR) m_stUserMask;
  549. else
  550. {
  551. if (pfle->dwDstMask != 0)
  552. pDispInfo->item.pszText = INET_NTOA(pfle->dwDstMask);
  553. }
  554. break;
  555. case PROTOCOL:
  556. // known protocol, display string, else number
  557. m_stTempOther = GetProtocolString(pfle->dwProtocol,pfle->fLateBound);
  558. pDispInfo->item.pszText = (LPTSTR) (LPCTSTR)m_stTempOther;
  559. break;
  560. case SRC_PORT:
  561. if (pfle->dwProtocol == FILTER_PROTO_ICMP)
  562. {
  563. if (pfle->wSrcPort != FILTER_ICMP_TYPE_ANY)
  564. pDispInfo->item.pszText = (LPTSTR)_itow(pfle->wSrcPort,
  565. s_szSrcPortBuffer, 10);
  566. }
  567. else
  568. {
  569. if (pfle->wSrcPort != 0)
  570. pDispInfo->item.pszText = (LPTSTR)_itow(pfle->wSrcPort,
  571. s_szSrcPortBuffer, 10);
  572. }
  573. break;
  574. case DEST_PORT:
  575. if (pfle->dwProtocol == FILTER_PROTO_ICMP)
  576. {
  577. if (pfle->wSrcPort != FILTER_ICMP_CODE_ANY)
  578. pDispInfo->item.pszText = (LPTSTR)_itow(pfle->wDstPort,
  579. s_szDestPortBuffer, 10);
  580. }
  581. else
  582. {
  583. if (pfle->wDstPort != 0)
  584. pDispInfo->item.pszText = (LPTSTR)_itow(pfle->wDstPort,
  585. s_szDestPortBuffer, 10);
  586. }
  587. break;
  588. default:
  589. break;
  590. }
  591. }
  592. *pResult = 0;
  593. }
  594. // --------------------------------------------------------------------
  595. // Function: CIpFltr::GetProtocolString
  596. //
  597. // returns protocol names for known protocols
  598. // --------------------------------------------------------------------
  599. CString CIpFltr::GetProtocolString(DWORD dwProtocol, DWORD fFlags)
  600. {
  601. WCHAR buffer[32];
  602. CString st;
  603. switch (dwProtocol)
  604. {
  605. case FILTER_PROTO_TCP:
  606. st = ProtocolTypeToCString(dwProtocol);
  607. if(fFlags & TCP_ESTABLISHED_FLAG)
  608. {
  609. st.LoadString(IDS_PROTOCOL_TCP_ESTABLISHED);
  610. }
  611. break;
  612. case FILTER_PROTO_UDP:
  613. case FILTER_PROTO_ICMP:
  614. case FILTER_PROTO_ANY:
  615. st = ProtocolTypeToCString(dwProtocol);
  616. break;
  617. default:
  618. st = (LPTSTR) _itow(dwProtocol, buffer, 10);
  619. break;
  620. }
  621. return st;
  622. }
  623. //------------------------------------------------------------------------------
  624. // Function: CIpFltr::SetFilterActionButtonsAndText
  625. //
  626. // Called to set the 'Filter Action' radio-buttons and corresponding text
  627. // Enables/Disables controls based on 'bEnable' value - defaults to enable
  628. //------------------------------------------------------------------------------
  629. VOID
  630. CIpFltr::SetFilterActionButtonsAndText(
  631. DWORD dwFilterType,
  632. DWORD dwAction,
  633. BOOL bEnable
  634. )
  635. {
  636. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  637. if (dwFilterType == FILTER_DEMAND_DIAL)
  638. {
  639. CheckDlgButton( IDC_IP_FILTER_ONLY, dwAction == PF_ACTION_DROP );
  640. CheckDlgButton( IDC_IP_FILTER_ALL, dwAction == PF_ACTION_FORWARD );
  641. GetDlgItem(IDC_IP_FILTER_ONLY)->EnableWindow(bEnable);
  642. GetDlgItem(IDC_IP_FILTER_ALL)->EnableWindow(bEnable);
  643. }
  644. else if ((dwFilterType == FILTER_PERUSER_IN) ||
  645. (dwFilterType == FILTER_PERUSER_OUT))
  646. {
  647. CheckDlgButton( IDC_IP_PERMIT, dwAction == PF_ACTION_FORWARD );
  648. CheckDlgButton( IDC_IP_DENY, dwAction == PF_ACTION_DROP );
  649. CString sItem;
  650. GetDlgItem(IDC_IP_PERMIT)->EnableWindow(bEnable);
  651. GetDlgItem(IDC_IP_DENY)->EnableWindow(bEnable);
  652. sItem.LoadString(IDS_PERUSER_PERMIT);
  653. SetDlgItemText( IDC_IP_PERMIT, sItem );
  654. sItem.LoadString(IDS_PERUSER_DENY);
  655. SetDlgItemText( IDC_IP_DENY, sItem );
  656. }
  657. else
  658. {
  659. CheckDlgButton( IDC_IP_PERMIT, dwAction == PF_ACTION_FORWARD );
  660. CheckDlgButton( IDC_IP_DENY, dwAction == PF_ACTION_DROP );
  661. CString sItem;
  662. GetDlgItem(IDC_IP_PERMIT)->EnableWindow(bEnable);
  663. GetDlgItem(IDC_IP_DENY)->EnableWindow(bEnable);
  664. sItem.LoadString( dwFilterType == FILTER_INBOUND? IDS_RECEIVE : IDS_TRANSMIT );
  665. SetDlgItemText( IDC_IP_PERMIT, sItem );
  666. sItem.LoadString( IDS_DROP );
  667. SetDlgItemText( IDC_IP_DENY, sItem );
  668. }
  669. }
  670. //------------------------------------------------------------------------------
  671. // Function: CIpFltr::OnDoubleclickedIpFilterList
  672. // `
  673. // Handles 'NM_DBLCLK' notification from the Filter list control
  674. //------------------------------------------------------------------------------
  675. void CIpFltr::OnDblclkIpFilterList(NMHDR* pNMHDR, LRESULT* pResult)
  676. {
  677. OnIpFilterEdit();
  678. *pResult = 0;
  679. }
  680. void CIpFltr::OnNotifyListItemChanged(NMHDR *pNmHdr, LRESULT *pResult)
  681. {
  682. NMLISTVIEW * pnmlv = reinterpret_cast<NMLISTVIEW *>(pNmHdr);
  683. BOOL fSelected;
  684. fSelected = (m_listCtrl.GetNextItem(-1, LVNI_SELECTED) != -1);
  685. GetDlgItem(IDC_IP_FILTER_DELETE)->EnableWindow(fSelected);
  686. GetDlgItem(IDC_IP_FILTER_EDIT)->EnableWindow(fSelected);
  687. }
  688. /////////////////////////////////////////////////////////////////////////////
  689. // CIpFltrDD dialog
  690. CIpFltrDD::CIpFltrDD(CWnd* pParent,
  691. IInfoBase * pInfoBase,
  692. DWORD dwFilterType)
  693. : CIpFltr(pParent, pInfoBase, dwFilterType, CIpFltrDD::IDD)
  694. {
  695. //{{AFX_DATA_INIT(CIpFltrDD)
  696. // NOTE: the ClassWizard will add member initialization here
  697. //}}AFX_DATA_INIT
  698. // SetHelpMap(m_dwHelpMap);
  699. }
  700. CIpFltrDD::~CIpFltrDD()
  701. {
  702. }