www.pudn.com > 18900_netwall_lite.rar > LogListView.cpp


// LogListView.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "netwall.h" 
#include "LogListView.h" 
#include "MainFrm.h" 
#include "RuleUtil.h" 
#include "log.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CLogListView 
 
ThreadParams *CLogListView::m_pThreadParams = NULL; 
 
IMPLEMENT_DYNCREATE(CLogListView, CListView) 
 
CLogListView::CLogListView() 
{ 
    m_nType          = LOG;     
    m_bLogLoaded     = FALSE; 
    m_bThreadStarted = FALSE; 
    m_dwCurItem      = 0; 
    m_dwLogCount     = 0; 
} 
 
CLogListView::~CLogListView() 
{ 
    if (NULL != m_pThreadParams) 
    { 
        delete m_pThreadParams; 
        m_pThreadParams = NULL; 
    } 
 
    m_bThreadStarted = FALSE; 
} 
 
 
BEGIN_MESSAGE_MAP(CLogListView, CListView) 
	//{{AFX_MSG_MAP(CLogListView) 
	ON_COMMAND(ID_LOG_PAUSE, OnLogPause) 
	ON_UPDATE_COMMAND_UI(ID_LOG_PAUSE, OnUpdateLogPause) 
	ON_COMMAND(ID_LOG_STOP_DISPLAY, OnLogStopDisplay) 
	ON_UPDATE_COMMAND_UI(ID_LOG_STOP_DISPLAY, OnUpdateLogStopDisplay) 
	ON_COMMAND(ID_LOG_CONTINUE, OnLogContinue) 
	ON_UPDATE_COMMAND_UI(ID_LOG_CONTINUE, OnUpdateLogContinue) 
	//}}AFX_MSG_MAP 
    ON_MESSAGE(WM_USER_ADD_ITEM, OnAddLogItem) 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CLogListView drawing 
 
void CLogListView::OnDraw(CDC* pDC) 
{ 
	CDocument* pDoc = GetDocument(); 
	// TODO: add draw code here 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CLogListView diagnostics 
 
#ifdef _DEBUG 
void CLogListView::AssertValid() const 
{ 
	CListView::AssertValid(); 
} 
 
void CLogListView::Dump(CDumpContext& dc) const 
{ 
	CListView::Dump(dc); 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CLogListView message handlers 
 
BOOL CLogListView::PreCreateWindow(CREATESTRUCT& cs)  
{ 
    cs.style = (cs.style & ~LVS_TYPEMASK) | LVS_REPORT | LVS_SHOWSELALWAYS; 
    cs.style |= LVS_AUTOARRANGE; 
    // Set full line select 
    //ListView_SetExtendedListViewStyle(GetSafeHwnd(), LVS_EX_FULLROWSELECT); 
     
    return CListView::PreCreateWindow(cs); 
} 
 
void CLogListView::OnInitialUpdate()  
{ 
    CListView::OnInitialUpdate(); 
     
    // this code only works for a report-mode list view 
    VERIFY(GetStyle() & LVS_REPORT); 
} 
 
void CLogListView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)  
{ 
    m_nType = (UINT)lHint; 
     
    switch (m_nType)  
    { 
    case LOG: 
        InitHeadForLog(); 
        RefreshLog((CAdapterInfo *)pHint); 
        break;                
         
    default: 
        break; 
    } 
     
    ((CMainFrame *)AfxGetMainWnd())->SendMessage(WM_SIZE);	 
} 
 
BOOL CLogListView::InitHeadForLog() 
{ 
    // Gain a reference to the list control itself 
    CListCtrl& listView = GetListCtrl(); 
    listView.SetBkColor(RGB(255,255,255));  // set bk color to white 
     
    // Set full line select 
    ListView_SetExtendedListViewStyle(GetSafeHwnd(), LVS_EX_FULLROWSELECT); 
     
    // Delete all of the items 
    listView.DeleteAllItems(); 
     
    // Delete all of the columns     
    int nColumnCount = listView.GetHeaderCtrl()->GetItemCount(); 
     
    for (int i = 0; i < nColumnCount; i++) 
    { 
        listView.DeleteColumn(0); 
    } 
     
    // Insert Columns 
    listView.InsertColumn(0, _T("序号"),    LVCFMT_LEFT, 40, 0);   
    listView.InsertColumn(1, _T("时间"),    LVCFMT_LEFT, 140, 0);   
    listView.InsertColumn(2, _T("协议"),    LVCFMT_LEFT, 40, 0); 
    listView.InsertColumn(3, _T("方向"),    LVCFMT_LEFT, 40, 0); 
    listView.InsertColumn(4, _T("动作"),    LVCFMT_LEFT, 40, 0); 
     
    listView.InsertColumn(5, _T("源IP地址"),    LVCFMT_LEFT, 100, 0); 
    listView.InsertColumn(6, _T("源端口"),      LVCFMT_LEFT, 60, 0); 
     
    listView.InsertColumn(7, _T("目的IP地址"),  LVCFMT_LEFT, 100, 0); 
    listView.InsertColumn(8, _T("目的端口"),    LVCFMT_LEFT, 60, 0); 
     
    listView.InsertColumn(9, _T("大小"),     LVCFMT_LEFT, 40, 0); 
     
    return TRUE; 
} 
 
 
BOOL CLogListView::AddLogItem(LOG_ITEM *pItem, int nIndex, DWORD dwSerial, CListCtrl& listView) 
{ 
    ASSERT(pItem && nIndex >= 0); 
     
    static TCHAR szIndex[16]; 
    static TCHAR szTime[20];             
     
    // Order 
    _stprintf(szIndex, _T("%d"), dwSerial); 
    listView.InsertItem(nIndex, szIndex); 
     
    // Time 
    //_stprintf(szTime, _T("%d.%d.%d.%d.%d.%d.%d.%d"), pItem->Now.Year, pItem->Now.Month, pItem->Now.Day, pItem->Now.Hour, pItem->Now.Minute, pItem->Now.Second, pItem->Now.Milliseconds, pItem->Now.Weekday); 
    _stprintf(szTime, _T("%d.%d.%d.%d.%d.%d.%d"), pItem->Now.Year, pItem->Now.Month, pItem->Now.Day, pItem->Now.Hour, pItem->Now.Minute, pItem->Now.Second, pItem->Now.Weekday); 
    listView.SetItemText(nIndex, 1, szTime); 
     
    // Protocol 
    char * pTemp = CRuleUtil::GetProtocolDescById(pItem->iProto); 
    listView.SetItemText(nIndex, 2, _T(pTemp)); 
     
    // Direction 
    pTemp = CRuleUtil::GetDescByDirectionId(pItem->ucDirection); 
    listView.SetItemText(nIndex, 3, _T(pTemp)); 
     
    // Action 
    //pTemp = CRuleUtil::GetDescByActionId(pItem->ucAction); 
    pTemp = "通过"; 
    listView.SetItemText(nIndex, 4, _T(pTemp)); 
     
    // Source IP 
    TCHAR szBuf[20]; 
    DWORD dwIP = pItem->ulSrcAddress; 
    _stprintf(szBuf, _T("%d.%d.%d.%d"), (dwIP >> 24) & 0xFF, (dwIP >> 16) & 0xFF, (dwIP >> 8) & 0xFF, dwIP & 0xFF); 
    listView.SetItemText(nIndex, 5, szBuf); 
     
    // Source Port 
    _stprintf(szBuf, _T("%d"), pItem->usSrcPort);             
    listView.SetItemText(nIndex, 6, szBuf); 
     
    // Destination IP 
    dwIP = pItem->ulDestAddress; 
    _stprintf(szBuf, _T("%d.%d.%d.%d"), (dwIP >> 24) & 0xFF, (dwIP >> 16) & 0xFF, (dwIP >> 8) & 0xFF, dwIP & 0xFF); 
    listView.SetItemText(nIndex, 7, szBuf); 
     
    // Destination Port 
    _stprintf(szBuf, _T("%d"), pItem->usDestPort);             
    listView.SetItemText(nIndex, 8, szBuf); 
     
    // Packet Size 
    _stprintf(szBuf, _T("%d"), pItem->iSize);             
    listView.SetItemText(nIndex, 9, szBuf); 
     
    return TRUE; 
} 
 
int CLogListView::RefreshLog(CAdapterInfo *pAdapterInfo) 
{ 
    CListCtrl& listCtrl = GetListCtrl();             
     
    // 1. 装载日志到系统内存空间 
    if (! (m_bLogLoaded = ((CMainFrame *)AfxGetMainWnd())->LoadLogFile())) 
    {         
        return 0; 
    } 
     
    // 2. 计算总共有多少项日志以及一页可以显示的项数	 
    DWORD dwLogSize		= ((CMainFrame *)AfxGetMainWnd())->m_dwLogFileSize; 
    DWORD dwLogCount	= dwLogSize / sizeof(LOG_ITEM);//38 
    int   nCountPerPage = listCtrl.GetCountPerPage(); 
    int   nPageCount	= (dwLogSize + nCountPerPage) / nCountPerPage; 
     
    // 3. 如果数据超过10页,则首先显示前5页数据,否则显示所有数据 
    int nIndex   = 0;    
    m_dwCurItem  = 0; 
    m_dwLogCount = dwLogCount; 
    LOG_ITEM * pItem = (PLOG_ITEM)(((CMainFrame *)AfxGetMainWnd())->m_lpMapAddr); 
     
    // 4. 如果数据少于10页,则显示所有数据 
    if (nPageCount < 10) 
    { 
        while (m_dwCurItem < dwLogCount) 
        { 
            AddLogItem(pItem++, nIndex++, ++m_dwCurItem, listCtrl);	 
        }	 
         
        return m_dwCurItem; 
    } 
     
    // 5. 如果数据超过10页,则首先显示前5页数据, 
    while (m_dwCurItem < dwLogCount) 
    { 
        AddLogItem(pItem++, nIndex++, ++m_dwCurItem, listCtrl);                  
         
        if (m_dwCurItem == nCountPerPage * 5) 
        { 
            break; 
        } 
    } 
     
    // 6. 如果执行到这里,需要创建一个线程继续添加后面的项 
    m_pThreadParams = new ThreadParams; 
    if (! m_pThreadParams)  
    { 
        AfxMessageBox("不能创建日志装载线程!"); 
        return m_dwCurItem; 
    } 
     
    HANDLE hWaitEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 
    if (hWaitEvent == NULL) 
    { 
        AfxMessageBox("不能创建日志装载线程!"); 
        delete m_pThreadParams; 
        m_pThreadParams = NULL; 
        return m_dwCurItem; 
    } 
     
    m_pThreadParams->m_hwndProgress = AfxGetMainWnd()->m_hWnd;	 
    m_pThreadParams->m_hwndView   = this->GetSafeHwnd(); 
    m_pThreadParams->m_lpLogBase  = ((CMainFrame *)AfxGetMainWnd())->m_lpMapAddr; 
    m_pThreadParams->m_dwLogCount = m_dwLogCount;  
    m_pThreadParams->m_dwCurItem  = m_dwCurItem; 
    m_pThreadParams->m_hWaitEvent = hWaitEvent; 
    m_pThreadParams->m_bPaused    = FALSE; 
    m_pThreadParams->m_bInterrupt = FALSE; 
    m_pThreadParams->m_bDone	  = FALSE; 
     
    AfxBeginThread(LogThreadFunction, m_pThreadParams); 
     
    m_bThreadStarted = TRUE; 
 
    SetEvent(m_pThreadParams->m_hWaitEvent); 
     
    ::SendMessage(m_pThreadParams->m_hwndProgress, 
        WM_USER_LOGTHREAD_STATUS, 0, (LPARAM)m_pThreadParams); 
 
    ::SendMessage(m_pThreadParams->m_hwndProgress, 
        WM_USER_LOGTHREAD_STATUS, 1, (LPARAM)m_pThreadParams); 
 
    ::SendMessage(m_pThreadParams->m_hwndProgress, 
        WM_USER_LOGTHREAD_STATUS, 2, (LPARAM)m_pThreadParams); 
 
    ::SendMessage(m_pThreadParams->m_hwndProgress, 
        WM_USER_LOGTHREAD_STATUS, 3, (LPARAM)m_pThreadParams); 
 
    return m_dwCurItem; 
} 
 
UINT CLogListView::LogThreadFunction(LPVOID pParam) 
{ 
    ThreadParams * lpThreadParams = (PThreadParams)pParam; 
    if (lpThreadParams == NULL)  
    { 
        return -1; 
    } 
     
    //DWORD dwCurItem  = lpThreadParams->m_dwCurItem; 
    DWORD dwLogCount = lpThreadParams->m_dwLogCount; 
    LOG_ITEM * pItem = (PLOG_ITEM)((LPBYTE)lpThreadParams->m_lpLogBase + lpThreadParams->m_dwCurItem * sizeof(LOG_ITEM)); 
     
    while (TRUE) 
    { 
        // Wait for user continue display LOG_ITEM of the rest. 
        // (check for m_bInterrupt going TRUE every 100ms) 
        while (WaitForSingleObject(lpThreadParams->m_hWaitEvent, 100) == WAIT_TIMEOUT) 
        { 
            if (lpThreadParams->m_bInterrupt) 
            {                 
                goto Exit; 
            } 
        }         
         
        while (lpThreadParams->m_dwCurItem < dwLogCount) 
        {			 
            lpThreadParams->m_dwCurItem = ::SendMessage(lpThreadParams->m_hwndView, WM_USER_ADD_ITEM, 0, (LPARAM)pItem); 
            ::SendMessage(lpThreadParams->m_hwndProgress, 
                WM_USER_LOGTHREAD_STATUS, 2, (LPARAM)lpThreadParams); 
 
            Sleep(1); 
            if (lpThreadParams->m_bInterrupt) 
            {                                 
                goto Exit; 
            } 
            else if (lpThreadParams->m_bPaused) 
            {                 
                break; 
            }                           
        } 
         
        if (lpThreadParams->m_dwCurItem == dwLogCount) 
        { 
            lpThreadParams->m_bDone = TRUE;             
            break; 
        } 
    } 
     
    ::SendMessage(lpThreadParams->m_hwndProgress, 
       WM_USER_LOGTHREAD_STATUS, 3, (LPARAM)lpThreadParams);  
     
Exit:     
    return 0; 
} 
 
LRESULT CLogListView::OnAddLogItem(WPARAM wParam, LPARAM lParam) 
{ 
    CListCtrl& listCtrl = GetListCtrl(); 
    int nListEntries = listCtrl.GetItemCount(); 
    LOG_ITEM * pItem = (PLOG_ITEM)lParam; 
     
    AddLogItem(pItem, nListEntries, ++m_dwCurItem, listCtrl);     	 
     
    return m_dwCurItem; 
} 
 
void CLogListView::OnUpdateLogPause(CCmdUI* pCmdUI)  
{ 
    pCmdUI->Enable(m_bThreadStarted && ! m_pThreadParams->m_bPaused);     
} 
 
void CLogListView::OnLogPause()  
{ 
    m_pThreadParams->m_bPaused = TRUE; 
    ResetEvent(m_pThreadParams->m_hWaitEvent); 
     
    ::SendMessage(m_pThreadParams->m_hwndProgress, 
        WM_USER_LOGTHREAD_STATUS, 3, (LPARAM)m_pThreadParams);  
} 
 
void CLogListView::OnUpdateLogContinue(CCmdUI* pCmdUI)  
{ 
    pCmdUI->Enable(m_bThreadStarted && m_pThreadParams->m_bPaused);     
} 
 
void CLogListView::OnLogContinue()  
{ 
    m_pThreadParams->m_bPaused = FALSE; 
    SetEvent(m_pThreadParams->m_hWaitEvent); 
 
    ::SendMessage(m_pThreadParams->m_hwndProgress, 
        WM_USER_LOGTHREAD_STATUS, 3, (LPARAM)m_pThreadParams); 
} 
 
void CLogListView::OnUpdateLogStopDisplay(CCmdUI* pCmdUI)  
{ 
    pCmdUI->Enable(m_bThreadStarted && ! m_pThreadParams->m_bDone);  
} 
 
void CLogListView::OnLogStopDisplay()  
{ 
    m_pThreadParams->m_bPaused = TRUE; 
    m_pThreadParams->m_bInterrupt = TRUE; 
    ResetEvent(m_pThreadParams->m_hWaitEvent); 
 
    ::SendMessage(m_pThreadParams->m_hwndProgress, 
        WM_USER_LOGTHREAD_STATUS, 3, (LPARAM)m_pThreadParams); 
 
    ((CMainFrame *)AfxGetMainWnd())->m_bLoadCompleted = TRUE; 
    m_bThreadStarted = FALSE; 
 
    if (NULL != m_pThreadParams) 
    { 
        delete m_pThreadParams; 
        m_pThreadParams = NULL; 
    }     
}