//============================================================================ // Copyright(c) 1996, Microsoft Corporation // // File: ipxfltr.cpp // // History: // 08/30/96 Ram Cherala Created // // Implementation of IPX Filter dialog code //============================================================================ #include "stdafx.h" #include "rtrfiltr.h" #include "ipxfltr.h" #include "datafmt.h" #include "ipxadd.h" #include #include extern "C" { #include } #include "rtradmin.hm" #include "listctrl.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #if 1 static UINT uStringIdTable[] = { IDS_COL_SOURCENETWORK, IDS_COL_SOURCEMASK, IDS_COL_SOURCENODE, IDS_COL_SOURCESOCKET, IDS_COL_DESTNETWORK, IDS_COL_DESTMASK, IDS_COL_DESTNODE, IDS_COL_DESTSOCKET, IDS_COL_PACKETTYPE } ; #else static UINT uStringIdTable[] = { IDS_COL_SOURCEADDRESS, IDS_COL_DESTADDRESS, IDS_COL_PACKETTYPE } ; #endif ///////////////////////////////////////////////////////////////////////////// // CIpxFilter dialog CIpxFilter::CIpxFilter(CWnd* pParent /*=NULL*/, IInfoBase * pInfoBase, DWORD dwFilterType) : CBaseDialog( (dwFilterType == FILTER_INBOUND ? CIpxFilter::IDD_INBOUND : CIpxFilter::IDD_OUTBOUND), pParent), m_pParent(pParent), m_dwFilterType(dwFilterType) { //{{AFX_DATA_INIT(CIpxFilter) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT m_spInfoBase.Set(pInfoBase); // SetHelpMap(m_dwHelpMap); } CIpxFilter::~CIpxFilter() { while (!m_filterList.IsEmpty()) { delete (FilterListEntry*)m_filterList.RemoveHead(); } } void CIpxFilter::DoDataExchange(CDataExchange* pDX) { CBaseDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CIpxFilter) DDX_Control(pDX, IDC_IPX_FILTER_LIST, m_listCtrl); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CIpxFilter, CBaseDialog) //{{AFX_MSG_MAP(CIpxFilter) ON_NOTIFY(NM_DBLCLK, IDC_IPX_FILTER_LIST, OnDblclkIpxFilterList) ON_BN_CLICKED(IDC_IPX_FILTER_ADD, OnIpxFilterAdd) ON_BN_CLICKED(IDC_IPX_FILTER_EDIT, OnIpxFilterEdit) ON_BN_CLICKED(IDC_IPX_FILTER_DELETE, OnIpxFilterDelete) ON_NOTIFY(LVN_GETDISPINFO, IDC_IPX_FILTER_LIST, OnGetdispinfoIpxFilterList) ON_NOTIFY(LVN_ITEMCHANGED, IDC_IPX_FILTER_LIST, OnNotifyListItemChanged) //}}AFX_MSG_MAP END_MESSAGE_MAP() DWORD CIpxFilter::m_dwHelpMap[] = { // IDC_IPX_PERMIT, HIDC_IPX_PERMIT, // IDC_IPX_DENY, HIDC_IPX_DENY, // IDC_IPX_FILTER_LIST, HIDC_IPX_FILTER_LIST, // IDC_IPX_FILTER_ADD, HIDC_IPX_FILTER_ADD, // IDC_IPX_FILTER_EDIT, HIDC_IPX_FILTER_EDIT, // IDC_IPX_FILTER_DELETE, HIDC_IPX_FILTER_DELETE, 0,0 }; ///////////////////////////////////////////////////////////////////////////// // CIpxFilter message handlers //------------------------------------------------------------------------------ // Function: CIpxFilter::OnInitDialog // // Handles 'WM_INITDIALOG' notification from the dialog //------------------------------------------------------------------------------ BOOL CIpxFilter::OnInitDialog() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CBaseDialog::OnInitDialog(); ASSERT( m_dwFilterType == FILTER_INBOUND || m_dwFilterType == FILTER_OUTBOUND ); InfoBlock * pBlock; IPX_TRAFFIC_FILTER_GLOBAL_INFO * pIpxGlobal; IPX_TRAFFIC_FILTER_INFO * pIpxInfo; CRect rcDlg, rc; CString sCol; DWORD dwErr = NO_ERROR; HRESULT hr = hrOK; m_stAny.LoadString(IDS_ANY); // initialize rectangle for list control display GetClientRect(rcDlg); // insert columns m_listCtrl.GetClientRect(&rc); UINT i; for ( i = 0; i < IPX_NUM_COLUMNS; i++ ) { sCol.LoadString(uStringIdTable[i]); m_listCtrl.InsertColumn(i, sCol); AdjustColumnWidth(m_listCtrl, i, sCol); } // set extended attributes ListView_SetExtendedListViewStyle( m_listCtrl.m_hWnd, LVS_EX_FULLROWSELECT ); hr = m_spInfoBase->GetBlock((m_dwFilterType == FILTER_INBOUND) ? IPX_IN_TRAFFIC_FILTER_GLOBAL_INFO_TYPE : IPX_OUT_TRAFFIC_FILTER_GLOBAL_INFO_TYPE, &pBlock, 0); // The filter was previously defined // Windows NT Bug : 267091 // We may get a NULL block (one that has 0 data), so we need // to check for that case also. if (FHrSucceeded(hr) && (pBlock->pData != NULL)) { pIpxGlobal = ( IPX_TRAFFIC_FILTER_GLOBAL_INFO * ) pBlock->pData; SetFilterActionButtonsAndText(m_dwFilterType, pIpxGlobal->FilterAction); } else { SetFilterActionButtonsAndText(m_dwFilterType, IPX_TRAFFIC_FILTER_ACTION_DENY); } DWORD dwCount; hr = m_spInfoBase->GetBlock( (m_dwFilterType == FILTER_INBOUND) ? IPX_IN_TRAFFIC_FILTER_INFO_TYPE : IPX_OUT_TRAFFIC_FILTER_INFO_TYPE, &pBlock, 0); if (FHrSucceeded(hr)) { dwCount = pBlock->dwCount; pIpxInfo = ( PIPX_TRAFFIC_FILTER_INFO ) pBlock->pData; if (pIpxInfo) { for ( i = 0; i < dwCount; i++, pIpxInfo++ ) { FilterListEntry* pfle = new FilterListEntry; if (!pfle) { dwErr = ERROR_NOT_ENOUGH_MEMORY; break; } CopyMemory(pfle, pIpxInfo, sizeof(IPX_TRAFFIC_FILTER_INFO)); pfle->pos = m_filterList.AddTail(pfle); INT item = m_listCtrl.InsertItem( LVIF_TEXT|LVIF_PARAM, i, LPSTR_TEXTCALLBACK, 0,0,0, (LPARAM)pfle); if(item != -1) {m_listCtrl.SetItemData( item, (DWORD_PTR)pfle); } } } } // select the first item in the list if list is not empty, else // disable the radio controls and set sate to Allow if( m_listCtrl.GetItemCount()) { m_listCtrl.SetItemState(0, LVIS_SELECTED, LVIS_SELECTED); m_listCtrl.SetFocus(); GetDlgItem(IDC_IPX_FILTER_DELETE)->EnableWindow(TRUE); GetDlgItem(IDC_IPX_FILTER_EDIT)->EnableWindow(TRUE); } else { SetFilterActionButtonsAndText(m_dwFilterType, IPX_TRAFFIC_FILTER_ACTION_DENY, FALSE); GetDlgItem(IDC_IPX_FILTER_DELETE)->EnableWindow(FALSE); GetDlgItem(IDC_IPX_FILTER_EDIT)->EnableWindow(FALSE); } #if 0 if ( dwErr != NO_ERROR ) { // report construction error and return ::AfxMessageBox(IDS_CONSTRUCTION_ERROR); } #endif return FALSE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } //------------------------------------------------------------------------------ // Function: CIpxFilter::OnDblclkIpxFilterList // ` // Handles 'NM_DBLCLK' notification from the Filter list control //------------------------------------------------------------------------------ void CIpxFilter::OnDblclkIpxFilterList(NMHDR* pNMHDR, LRESULT* pResult) { OnIpxFilterEdit(); *pResult = 0; } //------------------------------------------------------------------------------ // Function: CIpxFilter::OnIpxFilterAdd // ` // Handles 'NM_DBLCLK' notification from the Filter list control //------------------------------------------------------------------------------ void CIpxFilter::OnIpxFilterAdd() { // Display the IP filter Add/Edit dialog // FilterListEntry* pfle = NULL; CIpxAddEdit dlg( this, (FilterListEntry**)&pfle); if ( dlg.DoModal() != IDOK ) { return; } // Add the newly configured filter to our list and update list control pfle->pos = m_filterList.AddTail( pfle ); int item = m_listCtrl.InsertItem( LVIF_TEXT|LVIF_PARAM, 0, LPSTR_TEXTCALLBACK, 0,0,0, (LPARAM)pfle); if(item != -1) {m_listCtrl.SetItemData( item, (DWORD_PTR)pfle); } // enable radio controls when the first item is added to list m_listCtrl.SetItemState(item, LVIS_SELECTED, LVIS_SELECTED); m_listCtrl.SetFocus(); } //------------------------------------------------------------------------------ // Function: CIpxFilter::OnIpxFilterEdit // ` // Handles 'NM_DBLCLK' notification from the Filter list control //------------------------------------------------------------------------------ void CIpxFilter::OnIpxFilterEdit() { // Get the current list selection // get the corresponding itemdata // pass it down to the CIpFltrAddEdit dialog // // Get the selected item // int i = m_listCtrl.GetNextItem(-1, LVNI_SELECTED); if (i == -1) { return ; } // // Get the interface for the selected item // FilterListEntry* pfle = (FilterListEntry*)m_listCtrl.GetItemData(i); CIpxAddEdit dlg( this, (FilterListEntry**)&pfle ); if ( dlg.DoModal() != IDOK ) { return; } m_listCtrl.Update(i); m_listCtrl.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED); m_listCtrl.SetFocus(); } //------------------------------------------------------------------------------ // Function: CIpxFilter::OnIpxFilterDelete // ` // Handles 'NM_DBLCLK' notification from the Filter list control //------------------------------------------------------------------------------ void CIpxFilter::OnIpxFilterDelete() { // Get the current list selection // delete it from our private list // delete the item from the list or just refresh the list view // // Get the selected item // int i = m_listCtrl.GetNextItem(-1, LVNI_SELECTED); if (i == -1) { return ; } // // Get the interface for the selected item // FilterListEntry* pfle = (FilterListEntry*)m_listCtrl.GetItemData(i); // // delete it m_listCtrl.DeleteItem(i); m_filterList.RemoveAt(pfle->pos); delete pfle; // // select the next available list item // // disable radio controls if all items in list are deleted // they will be reenabled when the first filter is added to list if( !m_listCtrl.GetItemCount()) { SetFilterActionButtonsAndText(m_dwFilterType, IPX_TRAFFIC_FILTER_ACTION_DENY, FALSE); } else if (m_listCtrl.GetItemCount() == i) m_listCtrl.SetItemState((i == 0? i: i-1), LVIS_SELECTED, LVIS_SELECTED); else m_listCtrl.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED); m_listCtrl.SetFocus(); } //------------------------------------------------------------------------------ // Function: CIpxFilter::OnOK // ` // Handles 'NM_DBLCLK' notification from the Filter list control //------------------------------------------------------------------------------ void CIpxFilter::OnOK() { // If the filters information changed, write this to registry // and return DWORD dwSize, dwCount, dwErr; HRESULT hr = hrOK; dwCount = (DWORD) m_filterList.GetCount(); if (!dwCount && IsDlgButtonChecked(IDC_IPX_DENY) ) { if (m_dwFilterType == FILTER_INBOUND) AfxMessageBox(IDS_RECEIVE_NO_FILTER, MB_OK); else AfxMessageBox(IDS_TRANSMIT_NO_FILTER, MB_OK); return; } if(dwCount) { InfoBlock * pBlock = new InfoBlock; // First Set the global information if (!pBlock) { // display an error message for no memory AfxMessageBox(IDS_ERROR_NO_MEMORY); return; }; dwSize = pBlock->dwSize = sizeof( IPX_TRAFFIC_FILTER_GLOBAL_INFO ); pBlock->dwType = (m_dwFilterType == FILTER_INBOUND) ? IPX_IN_TRAFFIC_FILTER_GLOBAL_INFO_TYPE : IPX_OUT_TRAFFIC_FILTER_GLOBAL_INFO_TYPE, pBlock->dwCount = 1; pBlock->pData = new BYTE[dwSize]; if(!pBlock->pData) { // display an error message for no memory delete pBlock; AfxMessageBox(IDS_ERROR_NO_MEMORY); return; } IPX_TRAFFIC_FILTER_GLOBAL_INFO * pIpxGlobal = (IPX_TRAFFIC_FILTER_GLOBAL_INFO*)pBlock->pData; pIpxGlobal->FilterAction = IsDlgButtonChecked(IDC_IPX_PERMIT) ? IPX_TRAFFIC_FILTER_ACTION_DENY : IPX_TRAFFIC_FILTER_ACTION_PERMIT; if( FHrOK(m_spInfoBase->BlockExists( (m_dwFilterType == FILTER_INBOUND)? IPX_IN_TRAFFIC_FILTER_GLOBAL_INFO_TYPE : IPX_OUT_TRAFFIC_FILTER_GLOBAL_INFO_TYPE ))) { hr = m_spInfoBase->SetBlock( (m_dwFilterType == FILTER_INBOUND)? IPX_IN_TRAFFIC_FILTER_GLOBAL_INFO_TYPE : IPX_OUT_TRAFFIC_FILTER_GLOBAL_INFO_TYPE , pBlock, 0); } else { hr = m_spInfoBase->AddBlock( (m_dwFilterType == FILTER_INBOUND)? IPX_IN_TRAFFIC_FILTER_GLOBAL_INFO_TYPE : IPX_OUT_TRAFFIC_FILTER_GLOBAL_INFO_TYPE, dwSize, pBlock->pData, 1, FALSE); } delete[] pBlock->pData; // now set the filter information pBlock->dwType = (m_dwFilterType == FILTER_INBOUND) ? IPX_IN_TRAFFIC_FILTER_INFO_TYPE : IPX_OUT_TRAFFIC_FILTER_INFO_TYPE ; // dwCount -1 because FILTER_DESCRIPTOR already has room for one FILTER_INFO structure pBlock->dwSize = sizeof(IPX_TRAFFIC_FILTER_INFO); dwSize = sizeof (IPX_TRAFFIC_FILTER_INFO) * dwCount; pBlock->dwCount = dwCount; pBlock->pData = new BYTE[dwSize]; if(!pBlock->pData) { // display an error message for no memory delete pBlock; AfxMessageBox(IDS_ERROR_NO_MEMORY); return; } IPX_TRAFFIC_FILTER_INFO * pIPXfInfo; pIPXfInfo = (IPX_TRAFFIC_FILTER_INFO*)pBlock->pData; POSITION pos; pos = m_filterList.GetHeadPosition(); while(pos) { FilterListEntry* pfle = (FilterListEntry*)m_filterList.GetNext(pos); CopyMemory(pIPXfInfo, pfle, sizeof(IPX_TRAFFIC_FILTER_INFO)); pIPXfInfo++; } if( FHrOK(m_spInfoBase->BlockExists(m_dwFilterType == FILTER_INBOUND?IPX_IN_TRAFFIC_FILTER_INFO_TYPE:IPX_OUT_TRAFFIC_FILTER_INFO_TYPE))) { hr = m_spInfoBase->SetBlock( (m_dwFilterType == FILTER_INBOUND) ? IPX_IN_TRAFFIC_FILTER_INFO_TYPE : IPX_OUT_TRAFFIC_FILTER_INFO_TYPE, pBlock, 0); } else { hr = m_spInfoBase->AddBlock( (m_dwFilterType == FILTER_INBOUND) ? IPX_IN_TRAFFIC_FILTER_INFO_TYPE : IPX_OUT_TRAFFIC_FILTER_INFO_TYPE, pBlock->dwSize, pBlock->pData, pBlock->dwCount, FALSE); } if (!FHrSucceeded(hr)) { AfxMessageBox(IDS_ERROR_SETTING_BLOCK); } delete[] pBlock->pData; delete pBlock; } else { // remove any previously defined filters hr = m_spInfoBase->AddBlock((m_dwFilterType == FILTER_INBOUND) ? IPX_IN_TRAFFIC_FILTER_GLOBAL_INFO_TYPE : IPX_OUT_TRAFFIC_FILTER_GLOBAL_INFO_TYPE, 0, NULL, 0, TRUE); hr = m_spInfoBase->AddBlock((m_dwFilterType == FILTER_INBOUND) ? IPX_IN_TRAFFIC_FILTER_INFO_TYPE : IPX_OUT_TRAFFIC_FILTER_INFO_TYPE, 0, NULL, 0, TRUE); } CBaseDialog::OnOK(); } //------------------------------------------------------------------------------ // Function: CIpxFilter::OnCancel // ` // Handles 'NM_DBLCLK' notification from the Filter list control //------------------------------------------------------------------------------ void CIpxFilter::OnCancel() { // TODO: Add extra cleanup here CBaseDialog::OnCancel(); } //------------------------------------------------------------------------------ // Function: CIpxFilter::SetFilterActionButtonsAndText // // Called to set the 'Filter Action' radio-buttons and corresponding text // Enables/Disables controls based on 'bEnable' value - defaults to enable //------------------------------------------------------------------------------ VOID CIpxFilter::SetFilterActionButtonsAndText( DWORD dwFilterType, DWORD dwAction, BOOL bEnable ) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CheckDlgButton( IDC_IPX_PERMIT, dwAction == IPX_TRAFFIC_FILTER_ACTION_DENY ); CheckDlgButton( IDC_IPX_DENY, dwAction == IPX_TRAFFIC_FILTER_ACTION_PERMIT ); CString sItem; // GetDlgItem(IDC_IPX_PERMIT)->EnableWindow(bEnable); // GetDlgItem(IDC_IPX_DENY)->EnableWindow(bEnable); // sItem.LoadString( dwFilterType == FILTER_INBOUND? IDS_RECEIVE : IDS_TRANSMIT ); // SetDlgItemText( IDC_IPX_PERMIT, sItem ); // sItem.LoadString( IDS_DROP ); // SetDlgItemText( IDC_IPX_DENY, sItem ); } #if 1 enum { SRC_NETWORK=0, SRC_MASK, SRC_NODE, SRC_SOCKET, DEST_NETWORK, DEST_MASK, DEST_NODE, DEST_SOCKET, PACKET_TYPE }; #else enum { SRC_ADDRESS=0, DEST_ADDRESS, PACKET_TYPE }; #endif //------------------------------------------------------------------------------ // Function: CIpxFilter::OnGetdispinfoIpxFilterList // // Handles 'LVN_GETDISPINFO' notification from the list control //------------------------------------------------------------------------------ void CIpxFilter::OnGetdispinfoIpxFilterList(NMHDR* pNMHDR, LRESULT* pResult) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); WCHAR buffer[32]; LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR; CString cStr; BOOL bFilter; FilterListEntry * pfle = (FilterListEntry*)pDispInfo->item.lParam; // Setup some default pDispInfo->item.pszText = (LPTSTR) (LPCTSTR) m_stAny; switch( pDispInfo->hdr.code ) { case LVN_GETDISPINFO: switch( pDispInfo->item.iSubItem ) { case SRC_NETWORK: if (pfle->FilterDefinition & IPX_TRAFFIC_FILTER_ON_SRCNET) pfle->stSourceNetwork << CIPX_NETWORK(pfle->SourceNetwork); else pfle->stSourceNetwork = m_stAny; pDispInfo->item.pszText = (LPTSTR) (LPCTSTR) pfle->stSourceNetwork; break; case SRC_MASK: if (pfle->FilterDefinition & IPX_TRAFFIC_FILTER_ON_SRCNET) pfle->stSourceNetworkMask << CIPX_NETWORK(pfle->SourceNetworkMask); else pfle->stSourceNetworkMask = m_stAny; pDispInfo->item.pszText = (LPTSTR) (LPCTSTR) pfle->stSourceNetworkMask; break; case SRC_NODE: if (pfle->FilterDefinition & IPX_TRAFFIC_FILTER_ON_SRCNODE) pfle->stSourceNode << CIPX_NODE(pfle->SourceNode); else pfle->stSourceNode = m_stAny; pDispInfo->item.pszText = (LPTSTR) (LPCTSTR) pfle->stSourceNode; break; case SRC_SOCKET: if (pfle->FilterDefinition & IPX_TRAFFIC_FILTER_ON_SRCSOCKET) pfle->stSourceSocket << CIPX_SOCKET(pfle->SourceSocket); else pfle->stSourceSocket = m_stAny; pDispInfo->item.pszText = (LPTSTR) (LPCTSTR) pfle->stSourceSocket; break; case DEST_NETWORK: if (pfle->FilterDefinition & IPX_TRAFFIC_FILTER_ON_DSTNET) pfle->stDestinationNetwork << CIPX_NETWORK(pfle->DestinationNetwork); else pfle->stDestinationNetwork = m_stAny; pDispInfo->item.pszText = (LPTSTR) (LPCTSTR) pfle->stDestinationNetwork; break; case DEST_MASK: if (pfle->FilterDefinition & IPX_TRAFFIC_FILTER_ON_DSTNET) pfle->stDestinationNetworkMask << CIPX_NETWORK(pfle->DestinationNetworkMask); else pfle->stDestinationNetworkMask = m_stAny; pDispInfo->item.pszText = (LPTSTR) (LPCTSTR) pfle->stDestinationNetworkMask; break; case DEST_NODE: if (pfle->FilterDefinition & IPX_TRAFFIC_FILTER_ON_DSTNODE) pfle->stDestinationNode << CIPX_NODE(pfle->DestinationNode); else pfle->stDestinationNode = m_stAny; pDispInfo->item.pszText = (LPTSTR) (LPCTSTR) pfle->stDestinationNode; break; case DEST_SOCKET: if (pfle->FilterDefinition & IPX_TRAFFIC_FILTER_ON_DSTSOCKET) pfle->stDestinationSocket << CIPX_SOCKET(pfle->DestinationSocket); else pfle->stDestinationSocket = m_stAny; pDispInfo->item.pszText = (LPTSTR) (LPCTSTR) pfle->stDestinationSocket; break; case PACKET_TYPE: if (pfle->FilterDefinition & IPX_TRAFFIC_FILTER_ON_PKTTYPE) pfle->stPacketType << CIPX_PACKET_TYPE(pfle->PacketType); else pfle->stPacketType = m_stAny; pDispInfo->item.pszText = (LPTSTR) (LPCTSTR) pfle->stPacketType; break; default: break; } } *pResult = 0; } void CIpxFilter::OnNotifyListItemChanged(NMHDR *pNmHdr, LRESULT *pResult) { BOOL fSelected; fSelected = (m_listCtrl.GetNextItem(-1, LVNI_SELECTED) != -1); GetDlgItem(IDC_IPX_FILTER_DELETE)->EnableWindow(fSelected); GetDlgItem(IDC_IPX_FILTER_EDIT)->EnableWindow(fSelected); }