summaryrefslogtreecommitdiffabout
authorMichael Krelin <hacker@klever.net>2004-07-05 01:53:09 (GMT)
committer Michael Krelin <hacker@klever.net>2004-07-05 01:53:09 (GMT)
commitfb8b43dbce8bc310718614384297aeaabb9a3cbb (patch) (side-by-side diff)
treeaf9d2c2b71ddffff93a97a02fe26611096b78645
downloadbigbrother-fb8b43dbce8bc310718614384297aeaabb9a3cbb.zip
bigbrother-fb8b43dbce8bc310718614384297aeaabb9a3cbb.tar.gz
bigbrother-fb8b43dbce8bc310718614384297aeaabb9a3cbb.tar.bz2
initial commit into svn repository
git-svn-id: http://svn.klever.net/kin/bigbrother/trunk@1 fe716a7a-6dde-0310-88d9-d003556173a8
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--.gitignore35
-rw-r--r--ActionPage.cpp278
-rw-r--r--ActionPage.h78
-rw-r--r--ActivityView.cpp297
-rw-r--r--ActivityView.h65
-rw-r--r--BigBrotherDoc.cpp1039
-rw-r--r--BigBrotherDoc.h183
-rw-r--r--BigBrotherView.cpp485
-rw-r--r--BigBrotherView.h89
-rw-r--r--COPYING19
-rw-r--r--GeneralPage.cpp168
-rw-r--r--GeneralPage.h52
-rw-r--r--HostPropertyPages.cpp124
-rw-r--r--HostPropertyPages.h58
-rw-r--r--KTAGS12
-rw-r--r--MainFrm.cpp299
-rw-r--r--MainFrm.h65
-rw-r--r--Preferences.cpp93
-rw-r--r--Preferences.h48
-rw-r--r--README32
-rw-r--r--SettingsPage.cpp186
-rw-r--r--SettingsPage.h61
-rw-r--r--bigbrother.clw313
-rw-r--r--bigbrother.cpp181
-rw-r--r--bigbrother.h41
-rw-r--r--bigbrother.mak1451
-rw-r--r--bigbrother.rc729
-rw-r--r--help/IDI_GOINGDOWN.bmpbin0 -> 246 bytes
-rw-r--r--help/IDI_HOST.bmpbin0 -> 246 bytes
-rw-r--r--help/IDI_HOSTDOWN.bmpbin0 -> 246 bytes
-rw-r--r--help/IDI_NOHOST.bmpbin0 -> 246 bytes
-rw-r--r--help/IDI_PINGING.bmpbin0 -> 246 bytes
-rw-r--r--help/bbullet.bmpbin0 -> 222 bytes
-rw-r--r--help/bigbro.cnt29
-rw-r--r--help/bigbrother.hpj33
-rw-r--r--help/bigbrother.rtf295
-rw-r--r--help/bigbrother.xml229
-rw-r--r--help/green.bmpbin0 -> 1318 bytes
-rw-r--r--help/red.bmpbin0 -> 1318 bytes
-rw-r--r--help/yellow.bmpbin0 -> 1318 bytes
-rw-r--r--install/custom.rch10
-rw-r--r--install/install.cpp68
-rw-r--r--install/install.rc182
-rw-r--r--install/resource.h24
-rw-r--r--makehelp.bat35
-rw-r--r--res/3angle.avibin0 -> 7656 bytes
-rw-r--r--res/BigBrotherDoc.icobin0 -> 1078 bytes
-rw-r--r--res/bigbrother.icobin0 -> 1078 bytes
-rw-r--r--res/bigbrother.rc213
-rw-r--r--res/goingdown.icobin0 -> 1078 bytes
-rw-r--r--res/host-down.wavbin0 -> 5978 bytes
-rw-r--r--res/host-up.wavbin0 -> 5978 bytes
-rw-r--r--res/host.icobin0 -> 766 bytes
-rw-r--r--res/hostdown.icobin0 -> 1078 bytes
-rw-r--r--res/junktoolbar.bmpbin0 -> 598 bytes
-rw-r--r--res/maintoolbar.bmpbin0 -> 1438 bytes
-rw-r--r--res/nohost.icobin0 -> 1078 bytes
-rw-r--r--res/pending.icobin0 -> 1078 bytes
-rw-r--r--res/pinging.icobin0 -> 1078 bytes
-rw-r--r--resource.h131
-rw-r--r--shared-code/BTreendex.h595
-rw-r--r--shared-code/BellsNWhistles.h146
-rw-r--r--shared-code/BitSet.h105
-rw-r--r--shared-code/Dynamide.h443
-rw-r--r--shared-code/FindIFace.h125
-rw-r--r--shared-code/LRUCache.h113
-rw-r--r--shared-code/RegEx.cpp1697
-rw-r--r--shared-code/RegEx.h158
-rw-r--r--shared-code/SNMPExtDll.h252
-rw-r--r--shared-code/SNMPOIDs.h221
-rw-r--r--shared-code/SNMPeer.h286
-rw-r--r--shared-code/install.h370
-rw-r--r--shared-code/ip_icmp.h91
-rw-r--r--shared-code/kHelpers.h159
-rw-r--r--shared-code/kICMP.cpp300
-rw-r--r--shared-code/kICMP.h80
-rw-r--r--shared-code/kinhelp.xsl250
-rw-r--r--shared-code/ms_icmp.h77
-rw-r--r--shared-data/browse-icon.icobin0 -> 1078 bytes
-rw-r--r--shared-data/install-icon.icobin0 -> 2998 bytes
-rw-r--r--shared-data/klever-background.bmpbin0 -> 2578 bytes
-rw-r--r--shared-data/play-icon.icobin0 -> 1078 bytes
-rw-r--r--stdafx.cpp6
-rw-r--r--stdafx.h33
84 files changed, 13037 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..01ef0bb
--- a/dev/null
+++ b/.gitignore
@@ -0,0 +1,35 @@
+
+# /
+/Debug
+/Release
+/Releast
+/debug
+/release
+/releast
+/DEBUG
+/RELEASE
+/RELEAST
+/*.mdp
+/*.ncb
+/*.aps
+/redist
+
+# /help/
+/help/BIGBRO.HLP
+/help/bigbro.hm
+/help/bigbro.GID
+
+# /install/
+/install/debug
+/install/pure
+/install/canned
+/install/static
+/install/Debug
+/install/Pure
+/install/Canned
+/install/Static
+/install/DEBUG
+/install/PURE
+/install/CANNED
+/install/STATIC
+/install/*.aps
diff --git a/ActionPage.cpp b/ActionPage.cpp
new file mode 100644
index 0000000..ec9699c
--- a/dev/null
+++ b/ActionPage.cpp
@@ -0,0 +1,278 @@
+// ActionPage.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "BigBrother.h"
+#include "ActionPage.h"
+#include "HostPropertyPages.h"
+#include "BigBrotherDoc.h"
+#include "BigBrotherView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CActionPage property page
+
+IMPLEMENT_DYNCREATE(CActionPage, CPropertyPage)
+
+CActionPage::CActionPage() : CPropertyPage(CActionPage::IDD)
+{
+ //{{AFX_DATA_INIT(CActionPage)
+ m_bCustomDn = FALSE;
+ m_bCustomUp = FALSE;
+ m_OverrideAction = FALSE;
+ m_bPlayASoundDn = FALSE;
+ m_bPlayASoundUp = FALSE;
+ m_CustomDn = _T("");
+ m_CustomUp = _T("");
+ m_SoundDn = _T("");
+ m_SoundUp = _T("");
+ //}}AFX_DATA_INIT
+ m_PreplayIcon = AfxGetApp()->LoadIcon(IDI_PREPLAY);
+ m_BrowseIcon = AfxGetApp()->LoadIcon(IDI_BROWSESOUND);
+}
+
+CActionPage::~CActionPage()
+{
+}
+
+void CActionPage::DoDataExchange(CDataExchange* pDX)
+{
+ CPropertyPage::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CActionPage)
+ DDX_Control(pDX, IDC_BROWSE_SOUND_UP, m_BrowseUpCtl);
+ DDX_Control(pDX, IDC_BROWSE_SOUND_DOWN, m_BrowseDnCtl);
+ DDX_Control(pDX, IDC_PREVIEW_SOUND_UP, m_SoundPreviewUp);
+ DDX_Control(pDX, IDC_PREVIEW_SOUND_DOWN, m_SoundPreviewDn);
+ DDX_Control(pDX, IDC_SOUND_UP, m_SoundUpCtl);
+ DDX_Control(pDX, IDC_SOUND_DOWN, m_SoundDnCtl);
+ DDX_Control(pDX, IDC_PROGRAM_UP, m_CustomUpCtl);
+ DDX_Control(pDX, IDC_PROGRAM_DOWN, m_CustomDnCtl);
+ DDX_Control(pDX, IDC_PLAYASOUND_UP, m_bPlayASoundUpCtl);
+ DDX_Control(pDX, IDC_PLAYASOUND_DOWN, m_bPlayASoundDnCtl);
+ DDX_Control(pDX, IDC_OVERRIDE_ACTION, m_OverrideActionCtl);
+ DDX_Control(pDX, IDC_CUSTOM_UP, m_bCustomUpCtl);
+ DDX_Control(pDX, IDC_CUSTOM_DOWN, m_bCustomDnCtl);
+ DDX_Check(pDX, IDC_CUSTOM_DOWN, m_bCustomDn);
+ DDX_Check(pDX, IDC_CUSTOM_UP, m_bCustomUp);
+ DDX_Check(pDX, IDC_OVERRIDE_ACTION, m_OverrideAction);
+ DDX_Check(pDX, IDC_PLAYASOUND_DOWN, m_bPlayASoundDn);
+ DDX_Check(pDX, IDC_PLAYASOUND_UP, m_bPlayASoundUp);
+ DDX_Text(pDX, IDC_PROGRAM_DOWN, m_CustomDn);
+ DDX_Text(pDX, IDC_PROGRAM_UP, m_CustomUp);
+ DDX_CBString(pDX, IDC_SOUND_DOWN, m_SoundDn);
+ DDX_CBString(pDX, IDC_SOUND_UP, m_SoundUp);
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CActionPage, CPropertyPage)
+ //{{AFX_MSG_MAP(CActionPage)
+ ON_BN_CLICKED(IDC_CUSTOM_DOWN, OnCustomDown)
+ ON_BN_CLICKED(IDC_CUSTOM_UP, OnCustomUp)
+ ON_BN_CLICKED(IDC_OVERRIDE_ACTION, OnOverrideAction)
+ ON_BN_CLICKED(IDC_PLAYASOUND_DOWN, OnPlayasoundDown)
+ ON_BN_CLICKED(IDC_PLAYASOUND_UP, OnPlayasoundUp)
+ ON_BN_CLICKED(IDC_PREVIEW_SOUND_UP, OnPreviewSoundUp)
+ ON_BN_CLICKED(IDC_PREVIEW_SOUND_DOWN, OnPreviewSoundDown)
+ ON_BN_CLICKED(IDC_BROWSE_SOUND_DOWN, OnBrowseSoundDown)
+ ON_BN_CLICKED(IDC_BROWSE_SOUND_UP, OnBrowseSoundUp)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CActionPage message handlers
+
+void CActionPage::SetupControls()
+{
+ m_bPlayASoundUpCtl.EnableWindow(m_OverrideAction);
+ m_bPlayASoundDnCtl.EnableWindow(m_OverrideAction);
+ m_bCustomUpCtl.EnableWindow(m_OverrideAction);
+ m_bCustomDnCtl.EnableWindow(m_OverrideAction);
+ m_SoundUpCtl.EnableWindow(m_bPlayASoundUp&&m_OverrideAction);
+ m_SoundDnCtl.EnableWindow(m_bPlayASoundDn&&m_OverrideAction);
+ m_SoundPreviewUp.EnableWindow(m_bPlayASoundUp);
+ m_SoundPreviewDn.EnableWindow(m_bPlayASoundDn);
+ m_BrowseUpCtl.EnableWindow(m_bPlayASoundUp&&m_OverrideAction);
+ m_BrowseDnCtl.EnableWindow(m_bPlayASoundDn&&m_OverrideAction);
+ m_CustomUpCtl.EnableWindow(m_bCustomUp&&m_OverrideAction);
+ m_CustomDnCtl.EnableWindow(m_bCustomDn&&m_OverrideAction);
+}
+
+void CActionPage::UpdatePage()
+{
+ if(!m_dad->m_Brother)
+ return;
+ if(::IsWindow(m_hWnd)){
+ m_SoundPreviewUp.SetIcon(m_PreplayIcon);
+ m_SoundPreviewDn.SetIcon(m_PreplayIcon);
+ m_BrowseUpCtl.SetIcon(m_BrowseIcon);
+ m_BrowseDnCtl.SetIcon(m_BrowseIcon);
+ if(m_dad->m_Brother->m_Daddy)
+ m_OverrideActionCtl.EnableWindow(TRUE);
+ else
+ m_OverrideActionCtl.EnableWindow(FALSE);
+ }
+ if(m_dad->m_Brother->flags&CBrother::flagsOverrideActions)
+ m_OverrideAction=TRUE;
+ else
+ m_OverrideAction=FALSE;
+ if(m_dad->m_Brother->m_Up.flags&CAction::flagsPlayASound)
+ m_bPlayASoundUp=TRUE;
+ else
+ m_bPlayASoundUp=FALSE;
+ if(m_dad->m_Brother->m_Up.flags&CAction::flagsRunCustom)
+ m_bCustomUp=TRUE;
+ else
+ m_bCustomUp=FALSE;
+ if(m_dad->m_Brother->m_Down.flags&CAction::flagsPlayASound)
+ m_bPlayASoundDn=TRUE;
+ else
+ m_bPlayASoundDn=FALSE;
+ if(m_dad->m_Brother->m_Down.flags&CAction::flagsRunCustom)
+ m_bCustomDn=TRUE;
+ else
+ m_bCustomDn=FALSE;
+ m_SoundUp=m_dad->m_Brother->m_Up.m_Sound;
+ m_CustomUp=m_dad->m_Brother->m_Up.m_Custom;
+ m_SoundDn=m_dad->m_Brother->m_Down.m_Sound;
+ m_CustomDn=m_dad->m_Brother->m_Down.m_Custom;
+ if(::IsWindow(m_hWnd)){
+ UpdateData(FALSE);
+ SetupControls();
+ }
+}
+
+BOOL CActionPage::OnSetActive()
+{
+ UpdatePage();
+ return CPropertyPage::OnSetActive();
+}
+
+void CActionPage::UpdateBrother()
+{
+ if(!m_dad->m_Brother){
+ TRACE0("No brother on update\n");
+ return;
+ }
+ if(::IsWindow(m_hWnd))
+ UpdateData();
+CBrother toCompare;
+ toCompare = *m_dad->m_Brother;
+ if(m_OverrideAction)
+ m_dad->m_Brother->flags|=CBrother::flagsOverrideActions;
+ else
+ m_dad->m_Brother->flags&=~CBrother::flagsOverrideActions;
+ if(m_bPlayASoundUp)
+ m_dad->m_Brother->m_Up.flags|=CAction::flagsPlayASound;
+ else
+ m_dad->m_Brother->m_Up.flags&=~CAction::flagsPlayASound;
+ m_dad->m_Brother->m_Up.m_Sound=m_SoundUp;
+ if(m_bCustomUp)
+ m_dad->m_Brother->m_Up.flags|=CAction::flagsRunCustom;
+ else
+ m_dad->m_Brother->m_Up.flags&=~CAction::flagsRunCustom;
+ m_dad->m_Brother->m_Up.m_Custom=m_CustomUp;
+ if(m_bPlayASoundDn)
+ m_dad->m_Brother->m_Down.flags|=CAction::flagsPlayASound;
+ else
+ m_dad->m_Brother->m_Down.flags&=~CAction::flagsPlayASound;
+ m_dad->m_Brother->m_Down.m_Sound=m_SoundDn;
+ if(m_bCustomDn)
+ m_dad->m_Brother->m_Down.flags|=CAction::flagsRunCustom;
+ else
+ m_dad->m_Brother->m_Down.flags&=~CAction::flagsRunCustom;
+ m_dad->m_Brother->m_Down.m_Custom=m_CustomDn;
+ m_dad->m_Brother->ParentalAdjust();
+ if(toCompare!=(*m_dad->m_Brother)){
+ ASSERT(m_dad->m_Daddy);
+ CDocument *pDoc = m_dad->m_Daddy->GetDocument();
+ ASSERT(pDoc);
+ pDoc->SetModifiedFlag();
+ }
+ if(::IsWindow(m_hWnd)){
+ UpdateData(FALSE);
+ SetupControls();
+ }
+}
+
+BOOL CActionPage::OnKillActive()
+{
+ UpdateBrother();
+ return CPropertyPage::OnKillActive();
+}
+
+void CActionPage::OnCustomDown()
+{
+ UpdateBrother();
+ if(m_bCustomDn)
+ m_CustomDnCtl.SetFocus();
+}
+
+void CActionPage::OnCustomUp()
+{
+ UpdateBrother();
+ if(m_bCustomUp)
+ m_CustomUpCtl.SetFocus();
+}
+
+void CActionPage::OnOverrideAction()
+{
+ UpdateBrother();
+}
+
+void CActionPage::OnPlayasoundDown()
+{
+ UpdateBrother();
+ if(m_bPlayASoundDn)
+ m_SoundDnCtl.SetFocus();
+}
+
+void CActionPage::OnPlayasoundUp()
+{
+ UpdateBrother();
+ if(m_bPlayASoundUp)
+ m_SoundUpCtl.SetFocus();
+}
+
+void CActionPage::OnPreviewSoundUp()
+{
+ ASSERT(m_bPlayASoundUp);
+ UpdateBrother();
+ CAction::PlayASound(m_SoundUp);
+}
+
+void CActionPage::OnPreviewSoundDown()
+{
+ ASSERT(m_bPlayASoundDn);
+ UpdateBrother();
+ CAction::PlayASound(m_SoundDn);
+}
+
+void CActionPage::OnBrowseSoundDown()
+{
+ BrowseCtl(m_SoundDnCtl);
+}
+
+void CActionPage::OnBrowseSoundUp()
+{
+ BrowseCtl(m_SoundUpCtl);
+}
+
+void CActionPage::BrowseCtl(CComboBox& ctl)
+{
+CString filter;
+ filter.LoadString(IDS_WAVFILTER);
+CString title;
+ title.LoadString(IDS_SOUND_SELECT);
+CFileDialog cfd(TRUE,NULL,NULL,OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY,filter,this);
+ cfd.m_ofn.lpstrTitle=title;
+ if(cfd.DoModal()==IDOK){
+ ctl.SetWindowText(cfd.GetPathName());
+ UpdateBrother();
+ }
+}
diff --git a/ActionPage.h b/ActionPage.h
new file mode 100644
index 0000000..570abd0
--- a/dev/null
+++ b/ActionPage.h
@@ -0,0 +1,78 @@
+// ActionPage.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CActionPage dialog
+
+class CHostPropertyPages;
+class CActionPage : public CPropertyPage
+{
+ DECLARE_DYNCREATE(CActionPage)
+
+// Construction
+public:
+ void BrowseCtl(CComboBox& ctl);
+ HICON m_BrowseIcon;
+ HICON m_PreplayIcon;
+ void UpdateBrother();
+ void UpdatePage();
+ void SetupControls();
+ CHostPropertyPages* m_dad;
+ CActionPage();
+ ~CActionPage();
+
+// Dialog Data
+ //{{AFX_DATA(CActionPage)
+ enum { IDD = IDD_PROPS_ACTION };
+ CButton m_BrowseUpCtl;
+ CButton m_BrowseDnCtl;
+ CButton m_SoundPreviewUp;
+ CButton m_SoundPreviewDn;
+ CComboBox m_SoundUpCtl;
+ CComboBox m_SoundDnCtl;
+ CEdit m_CustomUpCtl;
+ CEdit m_CustomDnCtl;
+ CButton m_bPlayASoundUpCtl;
+ CButton m_bPlayASoundDnCtl;
+ CButton m_OverrideActionCtl;
+ CButton m_bCustomUpCtl;
+ CButton m_bCustomDnCtl;
+ BOOL m_bCustomDn;
+ BOOL m_bCustomUp;
+ BOOL m_OverrideAction;
+ BOOL m_bPlayASoundDn;
+ BOOL m_bPlayASoundUp;
+ CString m_CustomDn;
+ CString m_CustomUp;
+ CString m_SoundDn;
+ CString m_SoundUp;
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generate virtual function overrides
+ //{{AFX_VIRTUAL(CActionPage)
+ public:
+ virtual BOOL OnSetActive();
+ virtual BOOL OnKillActive();
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ // Generated message map functions
+ //{{AFX_MSG(CActionPage)
+ afx_msg void OnCustomDown();
+ afx_msg void OnCustomUp();
+ afx_msg void OnOverrideAction();
+ afx_msg void OnPlayasoundDown();
+ afx_msg void OnPlayasoundUp();
+ afx_msg void OnPreviewSoundUp();
+ afx_msg void OnPreviewSoundDown();
+ afx_msg void OnBrowseSoundDown();
+ afx_msg void OnBrowseSoundUp();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+
+};
diff --git a/ActivityView.cpp b/ActivityView.cpp
new file mode 100644
index 0000000..664b3d4
--- a/dev/null
+++ b/ActivityView.cpp
@@ -0,0 +1,297 @@
+// ActivityView.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "BigBrother.h"
+#include "ActivityView.h"
+
+#include "BigBrotherDoc.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CActivityView
+
+IMPLEMENT_DYNCREATE(CActivityView, CScrollView)
+
+CActivityView::CActivityView()
+{
+ m_Background = GetSysColor(COLOR_MENU);
+ //RGB(128,255,128);
+ m_BoxColor = RGB(192,255,255);
+ m_Red = RGB(255,0,0);
+ m_Green = RGB(0,192,0);
+ m_Yellow = RGB(255,255,0);
+ m_Dim = RGB(192,192,192);
+ m_Brothers = new CBrotherList;
+}
+
+CActivityView::~CActivityView()
+{
+ delete m_Brothers;
+}
+
+
+BEGIN_MESSAGE_MAP(CActivityView, CScrollView)
+ //{{AFX_MSG_MAP(CActivityView)
+ ON_WM_ERASEBKGND()
+ ON_WM_CREATE()
+ ON_WM_MOUSEMOVE()
+ ON_WM_LBUTTONDOWN()
+ ON_WM_LBUTTONUP()
+ ON_WM_SIZE()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CActivityView drawing
+
+void CActivityView::OnInitialUpdate()
+{
+ CScrollView::OnInitialUpdate();
+
+ OnUpdate(NULL,0,NULL);
+}
+
+void CActivityView::OnDraw(CDC* pDC)
+{
+CBigBrotherDoc* pDoc = (CBigBrotherDoc*)GetDocument();
+ if(!pDoc)
+ return;
+ ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CBigBrotherDoc)));
+ if(m_Brothers->IsEmpty())
+ return;
+BOOL bt = FALSE, et=FALSE;
+BOOL isAny = FALSE;
+CTime beginTime, endTime;
+POSITION p = m_Brothers->GetHeadPosition();
+ while(p){
+ CBrother *b = m_Brothers->GetNext(p);
+ ASSERT(b);
+ if(b->m_Log.IsEmpty())
+ continue;
+ isAny=TRUE;
+ if((!bt) || b->m_Log.GetHead()->m_Time<beginTime){
+ bt=TRUE;
+ beginTime=b->m_Log.GetHead()->m_Time;
+ }
+ if((!et) || b->m_Log.GetTail()->m_Time>endTime){
+ et=TRUE;
+ endTime=b->m_Log.GetTail()->m_Time;
+ }
+ }
+ if(!isAny){
+ m_bPainted=FALSE;
+ return;
+ }
+ m_bPainted=TRUE;
+CTimeSpan ts = endTime-beginTime;
+ if(ts<pDoc->m_MaxLogTime)
+ ts = pDoc->m_MaxLogTime;
+ m_BeginTime=beginTime;
+ m_TimeSpan=ts;
+ p = m_Brothers->GetHeadPosition();
+int host = 0;
+ while(p){
+ CBrother *b = m_Brothers->GetNext(p);
+ ASSERT(b);
+ CRect rc(10,20+host*105,10+500,20+host*105+100);
+ pDC->FillSolidRect(rc,m_BoxColor);
+ PaintHost(b,pDC,rc,&beginTime,&ts);
+ host++;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CActivityView diagnostics
+
+#ifdef _DEBUG
+void CActivityView::AssertValid() const
+{
+ CScrollView::AssertValid();
+}
+
+void CActivityView::Dump(CDumpContext& dc) const
+{
+ CScrollView::Dump(dc);
+}
+#endif //_DEBUG
+
+/////////////////////////////////////////////////////////////////////////////
+// CActivityView message handlers
+
+void CActivityView::PaintHost(CBrother *b,CDC *pDC,CRect& rc,CTime *bTime,CTimeSpan *tSpan)
+{
+ ASSERT(b);
+ if(b->m_Log.IsEmpty())
+ return;
+CBigBrotherDoc* pDoc = (CBigBrotherDoc*)GetDocument();
+ ASSERT(pDoc);
+ ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CBigBrotherDoc)));
+ULONG rttMax = b->m_TimeOut;
+CTime beginTime;
+CTimeSpan ts;
+ if(bTime && tSpan){
+ beginTime= *bTime;
+ ts = *tSpan;
+ }else{
+ beginTime = b->m_Log.GetHead()->m_Time;
+ CTime endTime = b->m_Log.GetTail()->m_Time;
+ ts = endTime-beginTime;
+ if(ts<pDoc->m_MaxLogTime)
+ ts = pDoc->m_MaxLogTime;
+ }
+POSITION p = b->m_Log.GetHeadPosition();
+ ASSERT(p);
+CLogEntry *le = b->m_Log.GetNext(p);
+ ASSERT(le);
+int x = rc.left+(le->m_Time-beginTime).GetTotalSeconds()*rc.Width()/ts.GetTotalSeconds();
+ while(p){
+ le = b->m_Log.GetNext(p);
+ ASSERT(le);
+ int newx=rc.left+(le->m_Time-beginTime).GetTotalSeconds()*rc.Width()/ts.GetTotalSeconds();
+ if(!(le->flags&CLogEntry::flagsSeparator)){
+ UINT size = le->m_bReached?min(rttMax,le->m_RTT):rttMax;
+ int drawSize=(rttMax-size)*rc.Height()/rttMax;
+ COLORREF color=le->m_bReached?((size<(rttMax/3))?m_Green:((size<(rttMax*2/3))?m_Yellow:m_Red)):m_Dim;
+ pDC->FillSolidRect(x,rc.bottom-drawSize,newx-x,drawSize,color);
+ }
+ x=newx;
+ }
+}
+
+void CActivityView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
+{
+CBigBrotherDoc* pDoc = (CBigBrotherDoc*)GetDocument();
+ if(!pDoc)
+ return;
+ ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CBigBrotherDoc)));
+ if(pHint){
+ CBrother *b = (CBrother*)pHint;
+ if(m_Brothers->Find(b)){
+ CClientDC dc(this);
+ OnPrepareDC(&dc);
+ CRect rc = b->m_rc;
+ dc.LPtoDP(&rc);
+ InvalidateRect(rc,FALSE);
+ }
+ return;
+ }
+ m_Brothers->RemoveAll();
+CBrother *b = pDoc->GetCurrentBrother();
+ if(b)
+ pDoc->GetFamily(b,m_Brothers);
+ SetScaleToFitSize(CSize(10+500+10,20+m_Brothers->GetCount()*105+20));
+POSITION p = m_Brothers->GetHeadPosition();
+int host = 0;
+ while(p){
+ CBrother *b = m_Brothers->GetNext(p);
+ b->m_rc.SetRect(10,20+host*105,10+500,20+host*105+100);
+ host++;
+ }
+ CScrollView::OnUpdate(pSender,lHint,pHint);
+}
+
+BOOL CActivityView::OnEraseBkgnd(CDC* pDC)
+{
+CRect rc;
+ GetClientRect(rc);
+ pDC->FillSolidRect(rc,m_Background);
+ return TRUE;
+}
+
+int CActivityView::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if (CScrollView::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ m_ToolTip.Create(this);
+ m_ToolTip.Activate(TRUE);
+ m_ToolTip.AddTool(this,IDS_AVIEW_NOTIP);
+
+ return 0;
+}
+
+BOOL CActivityView::PreTranslateMessage(MSG* pMsg)
+{
+ m_ToolTip.RelayEvent(pMsg);
+ return CScrollView::PreTranslateMessage(pMsg);
+}
+
+void CActivityView::OnMouseMove(UINT nFlags, CPoint point)
+{
+ UpdateTip(nFlags,point);
+ CScrollView::OnMouseMove(nFlags, point);
+}
+
+void CActivityView::UpdateTip(UINT nFlags,CPoint point)
+{
+CClientDC dc(this);
+ OnPrepareDC(&dc);
+ dc.DPtoLP(&point);
+POSITION p = m_Brothers->GetHeadPosition();
+ while(p){
+ CBrother *b = m_Brothers->GetNext(p);
+ if(b->m_rc.PtInRect(point)){
+ CString tmp;
+ tmp.Format(IDS_AVIEW_SHORTTIP,(LPCTSTR)b->m_Desc,(LPCTSTR)b->m_Host);
+ if(m_bPainted && (nFlags&(MK_LBUTTON|MK_CONTROL|MK_SHIFT))){
+ CTime theTime = m_BeginTime + CTimeSpan((point.x-b->m_rc.left)*m_TimeSpan.GetTotalSeconds()/b->m_rc.Width());
+ if(nFlags&(MK_LBUTTON|MK_CONTROL)){
+ // Add Time
+ tmp += ", "+theTime.Format(IDS_AVIEW_TIP_TIMEFORMAT);
+ }
+ if(nFlags&MK_SHIFT){
+ // Add RTT report
+ CLogEntry *le = NULL;
+ POSITION p = b->m_Log.GetTailPosition();
+ while(p){
+ CLogEntry *l = b->m_Log.GetPrev(p);
+ if(theTime<l->m_Time)
+ le = l;
+ else
+ break;
+ }
+ CString ttmp;
+ if(le){
+ if(le->m_bReached)
+ ttmp.Format(IDS_AVIEW_TIP_RTTREPORT, le->m_RTT);
+ else
+ ttmp.LoadString(IDS_AVIEW_TIP_UNREACHABLE);
+ }else
+ ttmp.LoadString(IDS_AVIEW_TIP_UNPINGED);
+ tmp += ", "+ttmp;
+ }
+ }
+ m_ToolTip.Activate(TRUE);
+ m_ToolTip.UpdateTipText(tmp,this);
+ return;
+ }
+ }
+ m_ToolTip.Activate(FALSE);
+ m_ToolTip.UpdateTipText(IDS_AVIEW_NOTIP,this);
+}
+
+void CActivityView::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ UpdateTip(nFlags,point);
+ CScrollView::OnLButtonDown(nFlags, point);
+}
+
+void CActivityView::OnLButtonUp(UINT nFlags, CPoint point)
+{
+ UpdateTip(nFlags,point);
+ CScrollView::OnLButtonUp(nFlags, point);
+}
+
+void CActivityView::OnSize(UINT nType, int cx, int cy)
+{
+ CScrollView::OnSize(nType, cx, cy);
+CDocument *pDoc = GetDocument();
+ ASSERT(pDoc);
+ pDoc->UpdateAllViews(NULL);
+}
diff --git a/ActivityView.h b/ActivityView.h
new file mode 100644
index 0000000..aea3503
--- a/dev/null
+++ b/ActivityView.h
@@ -0,0 +1,65 @@
+// ActivityView.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CActivityView view
+
+class CBrother;
+typedef CTypedPtrList<CObList,CBrother*> CBrotherList;
+class CActivityView : public CScrollView
+{
+protected:
+ CActivityView(); // protected constructor used by dynamic creation
+ DECLARE_DYNCREATE(CActivityView)
+
+// Attributes
+public:
+ void UpdateTip(UINT nFlags,CPoint point);
+ BOOL m_bPainted;
+ CTimeSpan m_TimeSpan;
+ CTime m_BeginTime;
+ CToolTipCtrl m_ToolTip;
+ COLORREF m_Background;
+ CBrotherList *m_Brothers;
+ void PaintHost(CBrother *b,CDC *pDC,CRect& rc,CTime* bTime=NULL,CTimeSpan* tSpan=NULL);
+ COLORREF m_Dim;
+ COLORREF m_Yellow;
+ COLORREF m_Green;
+ COLORREF m_Red;
+ COLORREF m_BoxColor;
+
+// Operations
+public:
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CActivityView)
+ public:
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+ protected:
+ virtual void OnDraw(CDC* pDC); // overridden to draw this view
+ virtual void OnInitialUpdate(); // first time after construct
+ virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ virtual ~CActivityView();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+ // Generated message map functions
+ //{{AFX_MSG(CActivityView)
+ afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/BigBrotherDoc.cpp b/BigBrotherDoc.cpp
new file mode 100644
index 0000000..4a5328e
--- a/dev/null
+++ b/BigBrotherDoc.cpp
@@ -0,0 +1,1039 @@
+// BigBrotherDoc.cpp : implementation of the CBigBrotherDoc class
+//
+
+#include "stdafx.h"
+#include "BigBrother.h"
+
+#include "BigBrotherDoc.h"
+#include "BigBrotherView.h"
+#include "ActivityView.h"
+#include "HostPropertyPages.h"
+#include "MainFrm.h"
+#include "Preferences.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CBigBrotherDoc
+
+IMPLEMENT_SERIAL(CBigBrotherDoc, CDocument, VERSIONABLE_SCHEMA | 3 )
+IMPLEMENT_SERIAL(CBrother, CObject, VERSIONABLE_SCHEMA | 2 )
+IMPLEMENT_SERIAL(CAction, CObject, VERSIONABLE_SCHEMA | 1 )
+IMPLEMENT_SERIAL(CLogEntry, CObject, VERSIONABLE_SCHEMA | 2 )
+
+BEGIN_MESSAGE_MAP(CBigBrotherDoc, CDocument)
+ //{{AFX_MSG_MAP(CBigBrotherDoc)
+ ON_COMMAND(ID_BROTHERS_NEW, OnBrothersNew)
+ ON_UPDATE_COMMAND_UI(ID_BROTHERS_ADDBROTHER, OnUpdateBrothersAddbrother)
+ ON_COMMAND(ID_BROTHERS_ADDBROTHER, OnBrothersAddbrother)
+ ON_UPDATE_COMMAND_UI(ID_BROTHERS_DELETE, OnUpdateBrothersDelete)
+ ON_COMMAND(ID_BROTHERS_DELETE, OnBrothersDelete)
+ ON_COMMAND(ID_FILE_PREFERENCES, OnFilePreferences)
+ ON_UPDATE_COMMAND_UI(ID_FILE_PAUSE, OnUpdateFilePause)
+ ON_COMMAND(ID_FILE_PAUSE, OnFilePause)
+ ON_UPDATE_COMMAND_UI(ID_VIEW_HOSTPROPERTIES, OnUpdateViewHostproperties)
+ ON_COMMAND(ID_VIEW_HOSTPROPERTIES, OnViewHostproperties)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CBigBrotherDoc construction/destruction
+
+CBigBrotherDoc::CBigBrotherDoc()
+ : m_MaxLogTime(0,1,0,0), m_Threads(0), m_MaxThreads(10), m_PingSize(32), m_RootBrother(NULL),
+ m_bSaveOnShutdown(TRUE), m_AutoSave(0,0,30,0), m_bStoreLastActivity(FALSE)
+{
+ m_BBView = NULL;
+ m_AView = NULL;
+}
+
+CBigBrotherDoc::~CBigBrotherDoc()
+{
+ CleanUp();
+}
+
+BOOL CBigBrotherDoc::OnNewDocument()
+{
+ if (!CDocument::OnNewDocument())
+ return FALSE;
+
+ CleanUp();
+ m_RootBrother=new CBrother();
+
+ return TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CBigBrotherDoc serialization
+
+void CBigBrotherDoc::Serialize(CArchive& ar)
+{
+ ASSERT_VALID(this);
+
+ CDocument::Serialize(ar);
+
+ ar.MapObject(this);
+ ar.SerializeClass(RUNTIME_CLASS(CBigBrotherDoc));
+
+ if (ar.IsStoring())
+ {
+ // Store to archive
+ ar << m_PingSize;
+ ar << m_MaxThreads;
+ ar << m_MaxLogTime;
+ ar << m_bSaveOnShutdown;
+ ar << m_AutoSave;
+ ar << m_LogFile;
+ ar << m_bStoreLastActivity;
+ ar << m_RootBrother;
+ m_Brotherhood.Serialize(ar);
+ }
+ else
+ {
+ UINT schema = ar.GetObjectSchema();
+#ifndef NDEBUG
+ {
+ CString tmp;
+ tmp.Format("Doc-OSchema: %u\n",schema);
+ TRACE0(tmp);
+ }
+#endif
+ CleanUp();
+ m_ThisMap.RemoveAll();
+ // Read from archive
+ ar >> m_PingSize;
+ ar >> m_MaxThreads;
+ ar >> m_MaxLogTime;
+ if(schema>=2){
+ ar >> m_bSaveOnShutdown;
+ ar >> m_AutoSave;
+ }
+ ar >> m_LogFile;
+ if(schema>=3)
+ ar >> m_bStoreLastActivity;
+ ar >> m_RootBrother;
+ m_Brotherhood.Serialize(ar);
+ // Read from archive
+ m_ThisMap.RemoveAll();
+ // Log loading
+ CString logLine;
+ logLine.Format(IDS_LOG_LOADFILE,(LPCTSTR)GetTitle());
+ logLine=CTime::GetCurrentTime().Format(IDS_LOG_DATEFORMAT)+" "+logLine;
+ LogLine(logLine);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CBigBrotherDoc diagnostics
+
+#ifdef _DEBUG
+void CBigBrotherDoc::AssertValid() const
+{
+ CDocument::AssertValid();
+}
+
+void CBigBrotherDoc::Dump(CDumpContext& dc) const
+{
+ CDocument::Dump(dc);
+}
+#endif //_DEBUG
+
+/////////////////////////////////////////////////////////////////////////////
+// CBigBrotherDoc commands
+
+CBrother::CBrother(CBrother *daddy)
+{
+ CleanUp();
+ m_Daddy=daddy;
+ ParentalAdjust(TRUE);
+}
+
+void CBrother::CleanUp()
+{
+ m_Item=NULL;
+ flags=0;
+ m_bLog=TRUE;
+ m_Daddy=NULL;
+ m_Desc.Empty();
+ m_Down.CleanUp();
+ m_Host.Empty();
+ m_IntervalBad=30;
+ m_IntervalGood=30;
+ m_Retries=3;
+ m_TimeOut=5000;
+ m_Up.CleanUp();
+ m_bPinged=FALSE;
+ m_bPending=FALSE;
+ m_bIsUp=TRUE;
+ m_bPinging=FALSE;
+ m_bUp=TRUE;
+ m_bToKill=FALSE;
+ m_Doc=NULL;
+}
+
+CAction::CAction()
+{
+ CleanUp();
+}
+
+void CAction::CleanUp()
+{
+ flags=0;
+ m_Custom.Empty();
+ m_Sound.Empty();
+}
+
+CAction& CAction::operator=(CAction& src)
+{
+ flags=src.flags;
+ m_Custom=src.m_Custom;
+ m_Sound=src.m_Sound;
+ return *this;
+}
+
+void CBrother::ParentalAdjust(BOOL cleanUp)
+{
+ if(!m_Daddy){
+ flags|=flagsOverrideIntervals|flagsOverrideTimeout|flagsOverrideRetries|flagsOverrideActions|flagsOverrideLogging;
+ if(cleanUp){
+ m_Desc.LoadString(IDS_ROOTNODENAME);
+ m_IntervalBad=30, m_IntervalGood=30;
+ m_TimeOut=5000;
+ m_Retries=3;
+ {
+ m_Up.CleanUp();
+ m_Down.CleanUp();
+ m_Up.flags=m_Down.flags=CAction::flagsPlayASound;
+ m_Up.m_Sound.LoadString(IDS_ACTION_HOST_UP);
+ m_Down.m_Sound.LoadString(IDS_ACTION_HOST_DOWN);
+ }
+ m_bLog=TRUE;
+ }
+ }else{
+ if(!(flags&flagsOverrideIntervals)){
+ CBrother *parent = m_Daddy;
+ while(!(parent->flags&flagsOverrideIntervals)){
+ ASSERT(parent->m_Daddy);
+ parent=parent->m_Daddy;
+ }
+ m_IntervalBad=parent->m_IntervalBad;
+ m_IntervalGood=parent->m_IntervalGood;
+ }
+ if(!(flags&flagsOverrideTimeout)){
+ CBrother *parent = m_Daddy;
+ while(!(parent->flags&flagsOverrideTimeout)){
+ ASSERT(parent->m_Daddy);
+ parent=parent->m_Daddy;
+ }
+ m_TimeOut=parent->m_TimeOut;
+ }
+ if(!(flags&flagsOverrideRetries)){
+ CBrother *parent = m_Daddy;
+ while(!(parent->flags&flagsOverrideRetries)){
+ ASSERT(parent->m_Daddy);
+ parent=parent->m_Daddy;
+ }
+ m_Retries=parent->m_Retries;
+ }
+ if(!(flags&flagsOverrideActions)){
+ CBrother *parent = m_Daddy;
+ while(!(parent->flags&flagsOverrideActions)){
+ ASSERT(parent->m_Daddy);
+ parent=parent->m_Daddy;
+ }
+ m_Up=parent->m_Up;
+ m_Down=parent->m_Down;
+ }
+ if(!(flags&flagsOverrideLogging)){
+ CBrother *parent = m_Daddy;
+ while(!(parent->flags&flagsOverrideLogging)){
+ ASSERT(parent->m_Daddy);
+ parent=parent->m_Daddy;
+ }
+ m_bLog=parent->m_bLog;
+ }
+ }
+}
+
+void CBigBrotherDoc::OnChangedViewList()
+{
+ m_BBView=NULL;
+ m_AView=NULL;
+POSITION p = GetFirstViewPosition();
+ while(p){
+ CView* v = GetNextView(p);
+ if(v->IsKindOf(RUNTIME_CLASS(CBigBrotherView))){
+ ASSERT(!m_BBView);
+ m_BBView=(CBigBrotherView*)v;
+ }else if(v->IsKindOf(RUNTIME_CLASS(CActivityView))){
+ ASSERT(!m_AView);
+ m_AView=(CActivityView*)v;
+ }
+ }
+
+ CDocument::OnChangedViewList();
+}
+
+void CBigBrotherDoc::OnBrothersNew()
+{
+ ASSERT(m_BBView);
+CBrother *bro = m_BBView->GetCurrentBrother();
+ ASSERT(bro);
+CBrother *lb = new CBrother(bro);
+ m_Brotherhood.AddTail(lb);
+ SetModifiedFlag();
+ m_BBView->AddBrother(lb);
+ m_BBView->GotoBrother(lb);
+}
+
+void CBigBrotherDoc::CheckPendingQueue()
+{
+ if(flags&flagsSuspended)
+ return;
+CTime currentTime = CTime::GetCurrentTime();
+CTime nearestCheck;
+BOOL nearested = CheckPendingBrother(m_RootBrother,currentTime,nearestCheck,FALSE);
+POSITION p = m_Brotherhood.GetHeadPosition();
+ while(p){
+ CBrother *b = (CBrother*)m_Brotherhood.GetNext(p);
+ ASSERT(b);
+ nearested|=CheckPendingBrother(b,currentTime,nearestCheck,nearested);
+ }
+ if(m_AutoSave.GetTotalMinutes()){
+ CTime nc = m_AutoSaved+m_AutoSave;
+ if(nc<=currentTime){
+ if(IsModified())
+ DoFileSave();
+ m_AutoSaved=currentTime;
+ while(nc<=currentTime)
+ nc=nc+m_AutoSave;
+ }
+ if((!nearested) || nc<nearestCheck){
+ nearestCheck=nc;
+ nearested=TRUE;
+ }
+ }
+ if(!nearested)
+ return;
+ currentTime = CTime::GetCurrentTime();
+CTimeSpan nextto = nearestCheck-currentTime;
+UINT timer = 60000;
+ if(nextto.GetTotalSeconds()<60)
+ timer=nextto.GetTotalSeconds()*1000;
+ if(m_BBView) // In case we're destroying..
+ m_BBView->SetTimer(TM_CHECK,timer,NULL);
+}
+
+BOOL CBigBrotherDoc::CheckPendingBrother(CBrother* b,CTime& currentTime,CTime& nearestCheck,BOOL nearested)
+{
+ if(!b)
+ return FALSE;
+ if(b->m_Host.IsEmpty() || b->m_bPinging){
+ b->m_bPending=FALSE;
+ return FALSE;
+ }
+ if(b->m_bPending){
+ TryBrother(b);
+ return FALSE;
+ }
+CTime nextCheck = b->m_Pinged+CTimeSpan(b->m_bIsUp?b->m_IntervalGood:b->m_IntervalBad);
+ if(nextCheck<=currentTime){
+ TryBrother(b);
+ return FALSE;
+ }
+ if((!nearested) || nextCheck<nearestCheck){
+ nearestCheck=nextCheck;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void CBigBrotherDoc::TryBrother(CBrother *b)
+{
+ ASSERT(!b->m_Host.IsEmpty());
+ if(!(m_Threads<m_MaxThreads)){
+ b->m_bPending=TRUE;
+ return;
+ }
+ if(!m_BBView)
+ return; // In case we're dying
+ m_BBView->SendMessage(WM_ACTIVITYCOUNT,1,0);
+ b->m_Doc=this;
+ b->m_bPinging=TRUE;
+ VERIFY(AfxBeginThread(CBrother::DoCheck,(LPVOID)b));
+}
+
+UINT CBrother::DoCheck(LPVOID pParam)
+{
+CBrother *b = (CBrother*)pParam;
+ ASSERT(b);
+ return b->Check();
+}
+
+UINT CBrother::Check()
+{
+CBigBrotherDoc *m_Doc = (CBigBrotherDoc*)CBrother::m_Doc;
+
+ if(!m_bToKill){
+ ASSERT(m_Doc);
+ ASSERT(m_Doc->IsKindOf(RUNTIME_CLASS(CBigBrotherDoc)));
+ ASSERT(m_Doc->m_BBView);
+ m_Doc->m_BBView->PostMessage(WM_UPDATETREEBROTHER,0,(LPARAM)this);
+ }
+
+CICMP *pICMP = NULL;
+UINT dataSize = m_bToKill?32:m_Doc->m_PingSize;
+in_addr ip;
+ ip.s_addr = inet_addr(m_Host);
+CLogEntry le;
+ if(ip.s_addr==INADDR_NONE){
+ hostent *he = gethostbyname(m_Host);
+ if(!he){
+ le.m_Status.LoadString(IDS_PS_FAILEDTORESOLVE);
+ goto goBye;
+ }
+ memmove(&ip.s_addr,he->h_addr,sizeof(ip.s_addr));
+ }
+ pICMP = CICMP::CreateICMP();
+ if(!(pICMP && pICMP->Initialize())) {
+ le.m_Status.LoadString(IDS_PS_UNABLETOICMP);
+ goto goBye;
+ }
+ INT status;
+ LONG rtt;
+ rtt=pICMP->Ping(ip,dataSize,m_TimeOut,&status);
+ switch(status){
+ case CICMP::ipSuccess:
+ le.m_bReached=TRUE;
+ le.m_RTT=rtt;
+ le.m_Status.Empty();
+ break;
+ case CICMP::ipBuffTooSmall:
+ le.m_Status.LoadString(IDS_PS_INTERNALERROR);
+ break;
+ case CICMP::ipDestNetUnreachable:
+ le.m_Status.LoadString(IDS_PS_NETUNREACHABLE);
+ break;
+ case CICMP::ipDestHostUnreachable:
+ le.m_Status.LoadString(IDS_PS_HOSTUNREACHABLE);
+ break;
+ case CICMP::ipDestProtUnreachable:
+ le.m_Status.LoadString(IDS_PS_PROTUNREACHABLE);
+ break;
+ case CICMP::ipDestPortUnreachable:
+ le.m_Status.LoadString(IDS_PS_PORTUNREACHABLE);
+ case CICMP::ipNoResources:
+ le.m_Status.LoadString(IDS_PS_NORESOURCES);
+ break;
+ case CICMP::ipBadOption:
+ le.m_Status.LoadString(IDS_PS_INTERNALERROR);
+ break;
+ case CICMP::ipHWError:
+ le.m_Status.LoadString(IDS_PS_HWERROR);
+ break;
+ case CICMP::ipPacketTooBig:
+ le.m_Status.LoadString(IDS_PS_BIGPACKET);
+ break;
+ case CICMP::ipTimeOut:
+ le.m_Status.LoadString(IDS_PS_TIMEOUT);
+ break;
+ case CICMP::ipBadRequest:
+ le.m_Status.LoadString(IDS_PS_INTERNALERROR);
+ break;
+ case CICMP::ipBadRoute:
+ le.m_Status.LoadString(IDS_PS_BADROUTE);
+ break;
+ case CICMP::ipTTLExpiredInTransit:
+ le.m_Status.LoadString(IDS_PS_TTLEXPTRANSIT);
+ break;
+ case CICMP::ipTTLExpiredInReasm:
+ le.m_Status.LoadString(IDS_PS_TTLEXPREASM);
+ break;
+ case CICMP::ipParamProblem:
+ le.m_Status.LoadString(IDS_PS_IPARAMP);
+ break;
+ case CICMP::ipSourceQuench:
+ le.m_Status.LoadString(IDS_PS_SOURCEQUENCH);
+ break;
+ case CICMP::ipOptionTooBig:
+ le.m_Status.LoadString(IDS_PS_BIGOPTION);
+ break;
+ case CICMP::ipBadDest:
+ le.m_Status.LoadString(IDS_PS_BADDEST);
+ break;
+ default:
+ le.m_Status.Format(IDS_PS_UNKNOWNERROR,status);
+ break;
+ }
+goBye:
+ if(pICMP) {
+ pICMP->Deinitialize();
+ delete pICMP;
+ }
+ if(le.m_bReached)
+ m_bIsUp=TRUE;
+ else{
+ if(m_bIsUp)
+ m_HowDown=0;
+ m_bIsUp=FALSE;
+ m_HowDown++;
+ }
+
+ le.m_Time=CTime::GetCurrentTime();
+
+CLogEntry *newLE = NULL;
+ if(!m_Log.IsEmpty()){
+ CLogEntry *head = m_Log.GetHead();
+ while(head && (m_bToKill?FALSE:(m_Doc->m_MaxLogTime<(le.m_Time-head->m_Time)))){
+ m_Log.RemoveHead();
+ if(newLE)
+ delete head;
+ else
+ newLE=head;
+ if(m_Log.IsEmpty())
+ head=NULL;
+ else
+ head = m_Log.GetHead();
+ }
+ }
+ if(newLE)
+ (*newLE)=le;
+ else
+ newLE=new CLogEntry(le);
+ m_Log.AddTail(newLE);
+
+ if(m_bToKill)
+ delete this;
+ else{
+ m_bPinged=TRUE;
+ m_Pinged = CTime::GetCurrentTime();
+ if(m_Doc)
+ m_Doc->m_BBView->SendMessage(WM_ACTIVITYCOUNT,(WPARAM)-1,0);
+ if(m_Doc)
+ m_Doc->SetModifiedFlag();
+ if(m_Doc)
+ m_Doc->m_BBView->SendMessage(WM_UPDATETREEBROTHER,TRUE,(LPARAM)this);
+ }
+ return 0;
+}
+
+CLogEntry::CLogEntry()
+{
+ flags=0;
+ m_bReached=FALSE;
+ m_Status.Empty();
+ m_Time=CTime::GetCurrentTime();
+}
+
+CBrother::~CBrother()
+{
+POSITION p = m_Log.GetHeadPosition();
+ while(p){
+ CLogEntry *le = m_Log.GetNext(p);
+ delete le;
+ }
+ m_Log.RemoveAll();
+}
+
+void CBigBrotherDoc::CleanUp()
+{
+ if(m_BBView && m_BBView->m_Pages){
+ m_BBView->m_Pages->SetBrother(NULL);
+ }
+ if(m_RootBrother){
+ while(!m_Brotherhood.IsEmpty()){
+ CBrother *b = m_Brotherhood.GetHead();
+ ASSERT(b);
+ b->m_Doc=this;
+ b->Suicide();
+ }
+ m_RootBrother->m_Doc=this;
+ m_RootBrother->Suicide();
+ m_RootBrother=NULL;
+ }
+ m_MaxLogTime = CTimeSpan(0,1,0,0);
+ m_MaxThreads = 5;
+ m_PingSize = 32;
+ m_bSaveOnShutdown = TRUE;
+ m_AutoSave = CTimeSpan(0,0,30,0);
+ m_AutoSaved = CTime::GetCurrentTime();
+ flags=0;
+}
+
+CBrother* CBigBrotherDoc::GetCurrentBrother()
+{
+ if(m_BBView);
+ return m_BBView->GetCurrentBrother();
+ return NULL;
+}
+
+BOOL CBrother::IsValuable()
+{
+ return !m_Host.IsEmpty();
+}
+
+void CBigBrotherDoc::GetFamily(CBrother *b,CBrotherList *bh)
+{
+ ASSERT(b);
+ ASSERT(bh);
+ ASSERT(m_BBView);
+ m_BBView->GetFamily(b,bh);
+}
+
+void CBigBrotherDoc::OnUpdateBrothersAddbrother(CCmdUI* pCmdUI)
+{
+ ASSERT(m_BBView);
+CBrother *bro = m_BBView->GetCurrentBrother();
+ if(bro)
+ pCmdUI->Enable(bro->m_Daddy!=NULL);
+ else
+ pCmdUI->Enable(FALSE);
+}
+
+void CBigBrotherDoc::OnBrothersAddbrother()
+{
+ ASSERT(m_BBView);
+CBrother *bro = m_BBView->GetCurrentBrother();
+ ASSERT(bro);
+ bro = bro->m_Daddy;
+ ASSERT(bro);
+CBrother *lb = new CBrother(bro);
+ m_Brotherhood.AddTail(lb);
+ SetModifiedFlag();
+ m_BBView->AddBrother(lb);
+ m_BBView->GotoBrother(lb);
+}
+
+BOOL CAction::PlayASound(LPCTSTR sound)
+{
+CString str;
+ str.LoadString(IDS_ACTION_HOST_UP);
+ if(!str.CompareNoCase(sound))
+ return ::PlaySound((LPCTSTR)IDW_HOST_UP,AfxGetApp()->m_hInstance,SND_ASYNC|SND_NODEFAULT|SND_NOSTOP|SND_NOWAIT|SND_RESOURCE);
+ str.LoadString(IDS_ACTION_HOST_DOWN);
+ if(!str.CompareNoCase(sound))
+ return ::PlaySound((LPCTSTR)IDW_HOST_DOWN,AfxGetApp()->m_hInstance,SND_ASYNC|SND_NODEFAULT|SND_NOSTOP|SND_NOWAIT|SND_RESOURCE);
+ str.LoadString(IDS_ACTION_SYSTEM_OK);
+ if(!str.CompareNoCase(sound))
+ return MessageBeep(MB_ICONASTERISK);
+ str.LoadString(IDS_ACTION_SYSTEM_CRITICAL);
+ if(!str.CompareNoCase(sound))
+ return MessageBeep(MB_ICONHAND);
+ return ::PlaySound(sound,AfxGetApp()->m_hInstance,SND_ASYNC|SND_NODEFAULT|SND_NOSTOP|SND_NOWAIT|SND_FILENAME);
+}
+
+CLogEntry& CLogEntry::operator=(CLogEntry& src)
+{
+ m_bReached=src.m_bReached;
+ m_RTT=src.m_RTT;
+ m_Status=src.m_Status;
+ m_Time=src.m_Time;
+ flags=src.flags;
+ return *this;
+}
+
+CLogEntry::CLogEntry(CLogEntry& src)
+{
+ (*this)=src;
+}
+
+void CAction::PerformAction(CBrother *b)
+{
+ if(flags&flagsPlayASound)
+ PlayASound(m_Sound);
+ if(flags&flagsRunCustom){
+ CString cmd = FormatLine(m_Custom,b);
+ system(cmd);
+ }
+}
+
+void CBrother::Serialize(CArchive& ar)
+{
+ ASSERT_VALID(this);
+
+ CObject::Serialize(ar);
+
+CBigBrotherDoc *pDoc = (CBigBrotherDoc*)ar.m_pDocument;
+ ASSERT(pDoc);
+ ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CBigBrotherDoc)));
+
+ if (ar.IsStoring())
+ {
+ if(pDoc->m_BBView && (pDoc->m_BBView->GetTreeCtrl().GetItemState(m_Item,TVIS_EXPANDED)&TVIS_EXPANDED))
+ flags|=flagsExpandedTree;
+ else
+ flags&=~flagsExpandedTree;
+ if(pDoc->GetCurrentBrother()==this)
+ flags|=flagsCurrentBrother;
+ else
+ flags&=~flagsCurrentBrother;
+ // Store to archive
+ ar << (DWORD)this;
+ ar << (DWORD)m_Daddy;
+ ar << flags;
+ ar << m_bLog;
+ ar << m_Host;
+ ar << m_Desc;
+ ar << m_IntervalGood;
+ ar << m_IntervalBad;
+ ar << m_TimeOut;
+ ar << m_Retries;
+ ar << &m_Up;
+ ar << &m_Down;
+ if(pDoc->m_bStoreLastActivity)
+ m_Log.Serialize(ar);
+ else{
+ CLogList tmp;
+ tmp.Serialize(ar);
+ }
+ }else{
+#ifndef NDEBUG
+ {
+ CString tmp;
+ tmp.Format("Bro-OSchema: %u\n",ar.GetObjectSchema());
+ TRACE0(tmp);
+ }
+#endif
+ // Read from archive
+ DWORD dw;
+ ar >> dw;
+ pDoc->m_ThisMap[dw]=this;
+ ar >> dw;
+ if(dw){
+ VERIFY(pDoc->m_ThisMap.Lookup(dw,m_Daddy));
+ }else
+ m_Daddy=NULL;
+ ar >> flags;
+ ar >> m_bLog;
+ ar >> m_Host;
+ ar >> m_Desc;
+ ar >> m_IntervalGood;
+ ar >> m_IntervalBad;
+ ar >> m_TimeOut;
+ ar >> m_Retries;
+ CAction *act = NULL;
+ ar >> act;
+ m_Up = *act;
+ delete act;
+ act = NULL;
+ ar >> act;
+ m_Down = *act;
+ delete act;
+ m_Log.Serialize(ar);
+ ParentalAdjust();
+ }
+}
+
+void CAction::Serialize(CArchive& ar)
+{
+ ASSERT_VALID(this);
+
+ CObject::Serialize(ar);
+
+ if (ar.IsStoring())
+ {
+ // Store to archive
+ ar << flags;
+ ar << m_Sound;
+ ar << m_Custom;
+ }else{
+#ifndef NDEBUG
+ {
+ CString tmp;
+ tmp.Format("Act-OSchema: %u\n",ar.GetObjectSchema());
+ TRACE0(tmp);
+ }
+#endif
+ // Read from archive
+ ar >> flags;
+ ar >> m_Sound;
+ ar >> m_Custom;
+ }
+}
+
+void CLogEntry::Serialize(CArchive& ar)
+{
+ ASSERT_VALID(this);
+
+ CObject::Serialize(ar);
+
+ if (ar.IsStoring())
+ {
+ // Store to archive
+ ar << flags;
+ ar << m_Time;
+ ar << m_bReached;
+ ar << m_RTT;
+ ar << m_Status;
+ }else{
+ UINT schema = ar.GetObjectSchema();
+ /*
+#ifndef NDEBUG
+ {
+ CString tmp;
+ tmp.Format("Log-OSchema: %u\n",schema);
+ TRACE0(tmp);
+ }
+#endif
+ */
+ // Read from archive
+ if(schema>=2){
+ ar >> flags;
+ }
+ ar >> m_Time;
+ ar >> m_bReached;
+ ar >> m_RTT;
+ ar >> m_Status;
+ }
+}
+
+CBrother::CBrother()
+{
+ CleanUp();
+ ParentalAdjust(TRUE);
+}
+
+void CBigBrotherDoc::OnUpdateBrothersDelete(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(GetCurrentBrother()!=NULL);
+}
+
+void CBigBrotherDoc::OnBrothersDelete()
+{
+ ASSERT(m_BBView);
+CBrother *b = GetCurrentBrother();
+ ASSERT(b);
+ m_BBView->KillBrother(b);
+ SetModifiedFlag();
+}
+
+void CBrother::Suicide()
+{
+ ASSERT(m_Doc);
+ ASSERT(m_Doc->IsKindOf(RUNTIME_CLASS(CBigBrotherDoc)));
+CBigBrotherDoc *pDoc = (CBigBrotherDoc*)m_Doc;
+ if(pDoc->m_BBView && pDoc->m_BBView->m_Pages->m_Brother==this)
+ pDoc->m_BBView->m_Pages->m_Brother=NULL;
+POSITION p = pDoc->m_Brotherhood.Find(this);
+ if(p)
+ pDoc->m_Brotherhood.RemoveAt(p);
+#ifndef NDEBUG
+ else{
+ ASSERT(!m_Daddy);
+ }
+#endif
+ m_Item=NULL;
+ if(m_bPinging){
+ m_bToKill=TRUE;
+ m_Daddy=NULL;
+ m_Doc=NULL;
+ }else
+ delete this;
+}
+
+BOOL CBrother::operator==(CBrother& b)
+{
+ if(flags!=b.flags)
+ return FALSE;
+ if(m_bLog!=b.m_bLog)
+ return FALSE;
+ if(m_Desc.Compare(b.m_Desc))
+ return FALSE;
+ if(m_Down!=b.m_Down)
+ return FALSE;
+ if(m_Host.Compare(b.m_Host))
+ return FALSE;
+ if(m_IntervalGood!=b.m_IntervalGood || m_IntervalBad!=b.m_IntervalBad)
+ return FALSE;
+ if(m_Retries!=b.m_Retries)
+ return FALSE;
+ if(m_TimeOut!=b.m_TimeOut)
+ return FALSE;
+ if(m_Up!=b.m_Up)
+ return FALSE;
+ return TRUE;
+}
+
+BOOL CBrother::operator!=(CBrother& b)
+{
+ return !((*this)==b);
+}
+
+BOOL CAction::operator==(CAction& a)
+{
+ if(flags!=a.flags)
+ return FALSE;
+ if(m_Custom.Compare(a.m_Custom))
+ return FALSE;
+ if(m_Sound.Compare(a.m_Sound))
+ return FALSE;
+ return TRUE;
+}
+
+BOOL CAction::operator!=(CAction& a)
+{
+ return !((*this)==a);
+}
+
+CBrother& CBrother::operator=(CBrother& b)
+{
+ flags=b.flags;
+ m_bLog=b.m_bLog;
+ m_Desc=b.m_Desc;
+ m_Down=b.m_Down;
+ m_Host=b.m_Host;
+ m_IntervalGood=b.m_IntervalGood;
+ m_IntervalBad=b.m_IntervalBad;
+ m_Retries=b.m_Retries;
+ m_TimeOut=b.m_TimeOut;
+ m_Up=b.m_Up;
+ return *this;
+}
+
+BOOL CBigBrotherDoc::SaveModified()
+{
+ if(((CMainFrame*)(AfxGetApp()->m_pMainWnd))->m_bShuttingDown && m_bSaveOnShutdown){
+ DoFileSave();
+ ((CMainFrame*)(AfxGetApp()->m_pMainWnd))->m_bShuttingDown = FALSE;
+ return TRUE;
+ }
+ return CDocument::SaveModified();
+}
+
+void CBrother::AppendSeparator()
+{
+CLogEntry *le = new CLogEntry();
+ le->flags=CLogEntry::flagsSeparator;
+ m_Log.AddTail(le);
+}
+
+void CBigBrotherDoc::OnFilePreferences()
+{
+CPreferences prefs(AfxGetApp()->m_pMainWnd);
+ prefs.m_AutosaveMinutes=m_AutoSave.GetTotalMinutes();
+ prefs.m_LogFile=m_LogFile;
+ prefs.m_MaxThreads=m_MaxThreads;
+ prefs.m_PingSize=m_PingSize;
+ prefs.m_SaveOnShutdown=m_bSaveOnShutdown;
+ prefs.m_LogMins=m_MaxLogTime.GetTotalMinutes();
+ prefs.m_bStoreLastActivity=m_bStoreLastActivity;
+ if(prefs.DoModal()==IDOK){
+ m_AutoSave = CTimeSpan(0,prefs.m_AutosaveMinutes/60,prefs.m_AutosaveMinutes%60,0);
+ m_LogFile=prefs.m_LogFile;
+ m_MaxThreads=prefs.m_MaxThreads;
+ m_PingSize=prefs.m_PingSize;
+ m_bSaveOnShutdown=prefs.m_SaveOnShutdown;
+ m_MaxLogTime = CTimeSpan(0,prefs.m_LogMins/60,prefs.m_LogMins%60,0);
+ m_bStoreLastActivity=prefs.m_bStoreLastActivity;
+ }
+}
+
+void CBigBrotherDoc::LogLine(LPCTSTR str)
+{
+ if(!m_LogFile.IsEmpty()){
+ TRY{
+ CFile file(m_LogFile,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite|CFile::shareDenyWrite|CFile::typeBinary);
+ file.SeekToEnd();
+ file.Write(str,strlen(str));
+ file.Write("\r\n",2);
+ file.Close();
+ }CATCH(CFileException, e){
+#ifndef NDEBUG
+ afxDump << "Logging error: " << e->m_cause << "\n";
+#endif
+ }END_CATCH
+ }
+}
+
+CString CAction::FormatLine(LPCTSTR fmt,CBrother *b)
+{
+ ASSERT(b);
+CString str = fmt;
+CString rv;
+ while(!str.IsEmpty()){
+ int pe = str.Find('%');
+ if(pe<0){
+ rv+=str;
+ str.Empty();
+ }else{
+ rv+=str.Left(pe);
+ str = str.Mid(pe+1);
+ if(!str.IsEmpty()){
+ switch(str[0]){
+ case '%':
+ rv+="%";
+ break;
+ case 'h':
+ case 'H':
+ rv+=b->m_Host;
+ break;
+ case 'd':
+ case 'D':
+ rv+=b->m_Desc;
+ break;
+ }
+ str=str.Mid(1);
+ }else{
+ rv+="%"+str;
+ str.Empty();
+ }
+ }
+ }
+ return rv;
+}
+
+void CBigBrotherDoc::OnUpdateFilePause(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck((flags&flagsSuspended)?1:0);
+}
+
+void CBigBrotherDoc::OnFilePause()
+{
+ flags^=flagsSuspended;
+ if(!(flags&flagsSuspended)){
+ ASSERT(m_RootBrother);
+ m_RootBrother->AppendSeparator();
+ POSITION p = m_Brotherhood.GetHeadPosition();
+ while(p){
+ CBrother *b = m_Brotherhood.GetNext(p);
+ ASSERT(b);
+ b->AppendSeparator();
+ }
+ CheckPendingQueue();
+ }else{
+ ASSERT(m_BBView);
+ m_BBView->KillTimer(TM_CHECK);
+ }
+}
+
+void CBigBrotherDoc::DeleteContents()
+{
+ CleanUp();
+ CDocument::DeleteContents();
+}
+
+void CBigBrotherDoc::OnCloseDocument()
+{
+ CleanUp();
+ CDocument::OnCloseDocument();
+}
+
+void CBigBrotherDoc::OnUpdateViewHostproperties(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck((flags&flagsShowProps)?1:0);
+}
+
+void CBigBrotherDoc::OnViewHostproperties()
+{
+ ASSERT(m_BBView);
+ ASSERT(m_BBView->m_Pages);
+ flags^=flagsShowProps;
+ if(flags&flagsShowProps)
+ m_BBView->m_Pages->ShowWindow(SW_SHOW);
+ else
+ m_BBView->m_Pages->ShowWindow(SW_HIDE);
+}
diff --git a/BigBrotherDoc.h b/BigBrotherDoc.h
new file mode 100644
index 0000000..3343e18
--- a/dev/null
+++ b/BigBrotherDoc.h
@@ -0,0 +1,183 @@
+// BigBrotherDoc.h : interface of the CBigBrotherDoc class
+//
+/////////////////////////////////////////////////////////////////////////////
+
+class CLogEntry : public CObject {
+public:
+ enum {
+ flagsSeparator=1
+ };
+ UINT flags;
+ virtual void Serialize(CArchive& ar);
+ CLogEntry(CLogEntry& src);
+ CLogEntry& operator=(CLogEntry& src);
+ BOOL m_bReached;
+ CString m_Status;
+ ULONG m_RTT;
+ CTime m_Time;
+
+ CLogEntry();
+ DECLARE_SERIAL(CLogEntry)
+};
+
+typedef CTypedPtrList<CObList,CLogEntry*> CLogList;
+
+class CBrother;
+class CAction : public CObject {
+public:
+ static CString FormatLine(LPCTSTR fmt,CBrother *b);
+ BOOL operator!=(CAction& a);
+ BOOL operator==(CAction& a);
+ virtual void Serialize(CArchive& ar);
+ void PerformAction(CBrother *b);
+ static BOOL PlayASound(LPCTSTR sound);
+ CAction& operator=(CAction& src);
+ void CleanUp();
+ enum {
+ flagsPlayASound = 1,
+ flagsRunCustom = 2
+ };
+ UINT flags;
+ CString m_Sound;
+ CString m_Custom;
+
+ CAction();
+ DECLARE_SERIAL(CAction)
+};
+
+class CBrother : public CObject {
+public:
+ void AppendSeparator();
+ CBrother& operator=(CBrother& b);
+ BOOL operator!=(CBrother& b);
+ BOOL operator==(CBrother& b);
+ BOOL m_bToKill;
+ void Suicide();
+ virtual void Serialize(CArchive& ar);
+ BOOL m_bUp;
+ CRect m_rc;
+ BOOL IsValuable();
+ ~CBrother();
+ UINT m_HowDown;
+ BOOL m_bPinging;
+ UINT Check();
+ CDocument* m_Doc;
+ static UINT DoCheck(LPVOID pParam);
+ BOOL m_bIsUp;
+ BOOL m_bPending;
+ CTime m_Pinged;
+ BOOL m_bPinged;
+ CLogList m_Log;
+ HTREEITEM m_Item;
+ void ParentalAdjust(BOOL cleanUp=FALSE);
+ void CleanUp();
+ CBrother(CBrother* daddy);
+ CBrother* m_Daddy;
+ UINT m_Retries;
+ DWORD m_TimeOut;
+ UINT m_IntervalBad;
+ UINT m_IntervalGood;
+ BOOL m_bLog;
+ CAction m_Down;
+ CAction m_Up;
+ enum {
+ flagsOverrideIntervals=1,
+ flagsOverrideTimeout=2,
+ flagsOverrideRetries=4,
+ flagsOverrideActions=8,
+ flagsOverrideLogging=16,
+ flagsExpandedTree=32,
+ flagsCurrentBrother=64
+ };
+ UINT flags;
+ CString m_Desc;
+ CString m_Host;
+
+ CBrother();
+ DECLARE_SERIAL(CBrother)
+};
+
+typedef CTypedPtrList<CObList,CBrother*> CBrotherList;
+typedef CMap<DWORD,DWORD,CBrother*,CBrother*> CThisMap;
+
+class CBigBrotherView;
+class CActivityView;
+class CBigBrotherDoc : public CDocument
+{
+protected: // create from serialization only
+ CBigBrotherDoc();
+ DECLARE_SERIAL(CBigBrotherDoc)
+
+// Attributes
+public:
+ BOOL m_bStoreLastActivity;
+ enum {
+ flagsSuspended=1,
+ flagsShowProps=2
+ };
+ UINT flags;
+ CTime m_AutoSaved;
+ void LogLine(LPCTSTR str);
+ CTimeSpan m_AutoSave;
+ BOOL m_bSaveOnShutdown;
+ CThisMap m_ThisMap;
+ CString m_LogFile;
+ void GetFamily(CBrother *b,CBrotherList *bh);
+ CBrother* GetCurrentBrother();
+ void CleanUp();
+ UINT m_PingSize;
+ int m_MaxThreads;
+ int m_Threads;
+ void TryBrother(CBrother *b);
+ BOOL CheckPendingBrother(CBrother* b,CTime& currentTime,CTime& nearestCheck,BOOL nearested);
+ void CheckPendingQueue();
+ CTimeSpan m_MaxLogTime;
+ CActivityView *m_AView;
+ CBigBrotherView* m_BBView;
+ CBrotherList m_Brotherhood;
+ CBrother* m_RootBrother;
+
+// Operations
+public:
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CBigBrotherDoc)
+ public:
+ virtual BOOL OnNewDocument();
+ virtual void Serialize(CArchive& ar);
+ virtual void OnChangedViewList();
+ virtual void DeleteContents();
+ virtual void OnCloseDocument();
+ protected:
+ virtual BOOL SaveModified();
+ //}}AFX_VIRTUAL
+
+// Implementation
+public:
+ virtual ~CBigBrotherDoc();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+protected:
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(CBigBrotherDoc)
+ afx_msg void OnBrothersNew();
+ afx_msg void OnUpdateBrothersAddbrother(CCmdUI* pCmdUI);
+ afx_msg void OnBrothersAddbrother();
+ afx_msg void OnUpdateBrothersDelete(CCmdUI* pCmdUI);
+ afx_msg void OnBrothersDelete();
+ afx_msg void OnFilePreferences();
+ afx_msg void OnUpdateFilePause(CCmdUI* pCmdUI);
+ afx_msg void OnFilePause();
+ afx_msg void OnUpdateViewHostproperties(CCmdUI* pCmdUI);
+ afx_msg void OnViewHostproperties();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/BigBrotherView.cpp b/BigBrotherView.cpp
new file mode 100644
index 0000000..1fb529b
--- a/dev/null
+++ b/BigBrotherView.cpp
@@ -0,0 +1,485 @@
+// BigBrotherView.cpp : implementation of the CBigBrotherView class
+//
+
+#include "stdafx.h"
+#include "BigBrother.h"
+
+#include "BigBrotherDoc.h"
+#include "BigBrotherView.h"
+#include "HostPropertyPages.h"
+#include "MainFrm.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CBigBrotherView
+
+IMPLEMENT_DYNCREATE(CBigBrotherView, CTreeView)
+
+BEGIN_MESSAGE_MAP(CBigBrotherView, CTreeView)
+ //{{AFX_MSG_MAP(CBigBrotherView)
+ ON_WM_DESTROY()
+ ON_WM_CREATE()
+ ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
+ ON_NOTIFY_REFLECT(NM_RETURN, OnReturn)
+ ON_MESSAGE(WM_ACTIVITYCOUNT, OnActivityCount)
+ ON_MESSAGE(WM_UPDATETREEBROTHER, OnUpdateTreeBrother)
+ ON_MESSAGE(WM_CHECKQUEUE, OnCheckQueue)
+ ON_WM_TIMER()
+ ON_WM_CONTEXTMENU()
+ ON_NOTIFY_REFLECT(NM_RCLICK, OnRclick)
+ ON_WM_CHAR()
+ ON_MESSAGE(WM_BROTHERUPDOWN, OnUpDown)
+ ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, OnItemexpanded)
+ ON_WM_SETFOCUS()
+ //}}AFX_MSG_MAP
+ // Standard printing commands
+ ON_COMMAND(ID_FILE_PRINT, CTreeView::OnFilePrint)
+ ON_COMMAND(ID_FILE_PRINT_DIRECT, CTreeView::OnFilePrint)
+ ON_COMMAND(ID_FILE_PRINT_PREVIEW, CTreeView::OnFilePrintPreview)
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CBigBrotherView construction/destruction
+
+CBigBrotherView::CBigBrotherView()
+ : m_Pages(NULL)
+{
+ // Load Images
+ m_Images.Create(16,16,TRUE,5,2);
+CWinApp *app=AfxGetApp();
+ VERIFY((m_iNoHost=m_Images.Add(app->LoadIcon(IDI_NOHOST)))>=0);
+ VERIFY((m_iHost=m_Images.Add(app->LoadIcon(IDI_HOST)))>=0);
+ VERIFY((m_iGoingDown=m_Images.Add(app->LoadIcon(IDI_GOINGDOWN)))>=0);
+ VERIFY((m_iHostDown=m_Images.Add(app->LoadIcon(IDI_HOSTDOWN)))>=0);
+ VERIFY((m_iPending=m_Images.Add(app->LoadIcon(IDI_PENDING)))>=0);
+ VERIFY((m_iPinging=m_Images.Add(app->LoadIcon(IDI_PINGING)))>=0);
+}
+
+CBigBrotherView::~CBigBrotherView()
+{
+}
+
+BOOL CBigBrotherView::PreCreateWindow(CREATESTRUCT& cs)
+{
+ return CTreeView::PreCreateWindow(cs);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CBigBrotherView drawing
+
+void CBigBrotherView::OnDraw(CDC* pDC)
+{
+ CBigBrotherDoc* pDoc = GetDocument();
+ ASSERT(pDoc);
+ ASSERT_VALID(pDoc);
+}
+
+void CBigBrotherView::OnInitialUpdate()
+{
+ CTreeView::OnInitialUpdate();
+
+CWinApp *app=AfxGetApp();
+ ASSERT(app);
+CTreeCtrl& ctl = GetTreeCtrl();
+CBigBrotherDoc* doc = GetDocument();
+ ASSERT(doc);
+ ctl.SetImageList(&m_Images,TVSIL_NORMAL);
+ ctl.ModifyStyle(0,TVS_LINESATROOT|TVS_HASLINES|TVS_HASBUTTONS);
+ ctl.DeleteAllItems();
+POSITION p = doc->m_Brotherhood.GetHeadPosition();
+ VERIFY(doc->m_RootBrother);
+ AddBrother(doc->m_RootBrother);
+ while(p){
+ CBrother *b = (CBrother*)doc->m_Brotherhood.GetNext(p);
+ ASSERT(b->m_Daddy);
+ AddBrother(b);
+ }
+ SetupExpansion(doc->m_RootBrother);
+ doc->UpdateAllViews(this);
+CRect rc;
+ GetClientRect(rc);
+ ClientToScreen(rc);
+CRect prc;
+ m_Pages->GetWindowRect(prc);
+CRect nrc;
+ if(m_Pages->m_InitialPosition.x<0 || m_Pages->m_InitialPosition.y<0){
+ nrc.bottom=rc.bottom; nrc.right=rc.right;
+ nrc.top=nrc.bottom-prc.Height(); nrc.left=nrc.right-prc.Width();
+ }else{
+ nrc.left=m_Pages->m_InitialPosition.x;nrc.top=m_Pages->m_InitialPosition.y;
+ nrc.right=nrc.left+prc.Width(); nrc.bottom=nrc.top+prc.Height();
+ }
+ m_Pages->MoveWindow(nrc,FALSE);
+ m_Pages->ShowWindow((doc->flags&CBigBrotherDoc::flagsShowProps)?SW_SHOW:SW_HIDE);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CBigBrotherView printing
+
+BOOL CBigBrotherView::OnPreparePrinting(CPrintInfo* pInfo)
+{
+ // default preparation
+ return DoPreparePrinting(pInfo);
+}
+
+void CBigBrotherView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
+{
+}
+
+void CBigBrotherView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CBigBrotherView diagnostics
+
+#ifdef _DEBUG
+void CBigBrotherView::AssertValid() const
+{
+ CTreeView::AssertValid();
+}
+
+void CBigBrotherView::Dump(CDumpContext& dc) const
+{
+ CTreeView::Dump(dc);
+}
+
+CBigBrotherDoc* CBigBrotherView::GetDocument() // non-debug version is inline
+{
+ if(m_pDocument)
+ ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CBigBrotherDoc)));
+ return (CBigBrotherDoc*)m_pDocument;
+}
+#endif //_DEBUG
+
+/////////////////////////////////////////////////////////////////////////////
+// CBigBrotherView message handlers
+
+void CBigBrotherView::OnDestroy()
+{
+ CTreeView::OnDestroy();
+
+ if(m_Pages){
+ m_Pages->DestroyWindow();
+ delete m_Pages;
+ m_Pages=NULL;
+ }
+}
+
+int CBigBrotherView::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if (CTreeView::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ m_Pages = new CHostPropertyPages(IDS_PROPS_TITLE);
+ m_Pages->m_Daddy=this;
+ m_Pages->Create(this,WS_POPUP||WS_CLIPSIBLINGS|WS_BORDER|WS_DLGFRAME,WS_EX_TOOLWINDOW|WS_EX_WINDOWEDGE);
+
+ return 0;
+}
+
+HTREEITEM CBigBrotherView::FindItem(CBrother* brother)
+{
+DWORD b = (DWORD)brother;
+CTreeCtrl& ctl = GetTreeCtrl();
+HTREEITEM rv = ctl.GetRootItem();
+ ASSERT(rv);
+ do{
+ if(ctl.GetItemData(rv)==b)
+ return rv;
+ }while((rv=ctl.GetNextItem(rv,TVGN_NEXT)));
+ ASSERT(0);
+ return NULL;
+}
+
+CBrother* CBigBrotherView::GetCurrentBrother()
+{
+HTREEITEM hItem = GetTreeCtrl().GetSelectedItem();
+ if(!hItem)
+ return NULL;
+CBrother *rv = (CBrother*)GetTreeCtrl().GetItemData(hItem);
+ ASSERT(rv);
+ return rv;
+}
+
+void CBigBrotherView::AddBrother(CBrother *b)
+{
+HTREEITEM hDaddy=TVI_ROOT;
+ if(b->m_Daddy){
+ ASSERT(b->m_Daddy->m_Item);
+ hDaddy=b->m_Daddy->m_Item;
+ }
+CString tmp;
+ tmp=b->m_Desc;
+ if(tmp.IsEmpty())
+ tmp.LoadString(IDS_NODESC);
+ b->AppendSeparator();
+ b->m_Item=GetTreeCtrl().InsertItem(TVIF_PARAM|TVIF_TEXT,tmp,0,0,0,0,(LPARAM)b,hDaddy,TVI_LAST);
+ ASSERT(b->m_Item);
+ UpdateBrother(b);
+}
+
+void CBigBrotherView::GotoBrother(CBrother *b)
+{
+ ASSERT(b->m_Item);
+ GetTreeCtrl().SelectItem(b->m_Item);
+}
+
+void CBigBrotherView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
+ m_Pages->SetBrother(GetCurrentBrother());
+CBigBrotherDoc *pDoc = GetDocument();
+ if(pDoc)
+ pDoc->UpdateAllViews(this);
+ *pResult = 0;
+}
+
+void CBigBrotherView::UpdateBrother(CBrother* b)
+{
+ if(!b->m_Item)
+ return;
+ ASSERT(b->m_Item);
+CString tmp;
+ tmp=b->m_Desc;
+ if(tmp.IsEmpty())
+ tmp.LoadString(IDS_NODESC);
+ GetTreeCtrl().SetItemText(b->m_Item,tmp);
+int image = m_iNoHost;
+ if(!b->m_Host.IsEmpty()){
+ if(b->m_bPending)
+ image = m_iPending;
+ else if(b->m_bPinging)
+ image=m_iPinging;
+ else if(b->m_bPinged){
+ if(b->m_bIsUp){
+ image=m_iHost;
+ if(!b->m_bUp){
+ PostMessage(WM_BROTHERUPDOWN,TRUE,(LPARAM)b);
+ b->m_bUp=TRUE;
+ }
+ }else{
+ if(b->m_HowDown>=b->m_Retries){
+ image=m_iHostDown;
+ if(b->m_bUp){
+ PostMessage(WM_BROTHERUPDOWN,FALSE,(LPARAM)b);
+ b->m_bUp=FALSE;
+ }
+ }else
+ image=m_iGoingDown;
+ b->m_HowDown=min(b->m_HowDown,b->m_Retries+1);
+ }
+ }else
+ image=m_iHost;
+ }
+ GetTreeCtrl().SetItemImage(b->m_Item,image,image);
+ PostMessage(WM_CHECKQUEUE);
+}
+
+void CBigBrotherView::OnReturn(NMHDR* pNMHDR, LRESULT* pResult)
+{
+CBigBrotherDoc *pDoc = GetDocument();
+ ASSERT(pDoc);
+ pDoc->flags|=CBigBrotherDoc::flagsShowProps;
+ m_Pages->ShowWindow(SW_SHOW);
+ m_Pages->SetFocus();
+ *pResult = 0;
+}
+
+LRESULT CBigBrotherView::OnActivityCount(WPARAM wP,LPARAM)
+{
+CMainFrame *mf = (CMainFrame*)(AfxGetApp()->m_pMainWnd);
+ ASSERT(mf);
+ ASSERT(mf->IsKindOf(RUNTIME_CLASS(CMainFrame)));
+int crement = (int)wP;
+CBigBrotherDoc *doc = GetDocument();
+ ASSERT(doc);
+ ASSERT(doc->IsKindOf(RUNTIME_CLASS(CBigBrotherDoc)));
+ doc->m_Threads+=crement;
+ if(doc->m_Threads<0)
+ doc->m_Threads=0;
+ if(doc->m_Threads){
+ mf->m_PingBar.Play(0,(UINT)-1,(UINT)-1);
+ }else{
+ mf->m_PingBar.Stop();
+ mf->m_PingBar.Seek(0);
+ }
+ if(crement<0)
+ PostMessage(WM_CHECKQUEUE);
+ return doc->m_Threads;
+}
+
+LRESULT CBigBrotherView::OnUpdateTreeBrother(WPARAM wP,LPARAM lP)
+{
+CBrother *b = (CBrother*)lP;
+ ASSERT(b);
+ if(wP)
+ b->m_bPinging=FALSE;
+ UpdateBrother(b);
+CBigBrotherDoc *pDoc = GetDocument();
+ if(pDoc)
+ pDoc->UpdateAllViews(this,0,b);
+ return 0;
+}
+
+LRESULT CBigBrotherView::OnCheckQueue(WPARAM,LPARAM)
+{
+CBigBrotherDoc *doc = GetDocument();
+ if(doc)
+ doc->CheckPendingQueue();
+ return 0;
+}
+
+void CBigBrotherView::OnTimer(UINT nIDEvent)
+{
+ switch(nIDEvent){
+ case TM_CHECK:
+ KillTimer(TM_CHECK);
+ PostMessage(WM_CHECKQUEUE);
+ break;
+ }
+ CTreeView::OnTimer(nIDEvent);
+}
+
+void CBigBrotherView::GetFamily(CBrother* b,CBrotherList* bh)
+{
+ if(b->IsValuable())
+ bh->AddTail(b);
+ ASSERT(b->m_Item);
+CTreeCtrl& ctl = GetTreeCtrl();
+ if(!(ctl.GetItemState(b->m_Item,TVIS_EXPANDED)&TVIS_EXPANDED))
+ return;
+HTREEITEM hItem = ctl.GetNextItem(b->m_Item,TVGN_CHILD);
+ while(hItem){
+ CBrother *bb = (CBrother*)ctl.GetItemData(hItem);
+ ASSERT(bb);
+ GetFamily(bb,bh);
+ hItem = ctl.GetNextItem(hItem,TVGN_NEXT);
+ }
+}
+
+void CBigBrotherView::OnContextMenu(CWnd* pWnd, CPoint point)
+{
+ if(point.x<0 || point.y<0){
+ CBrother *b = GetCurrentBrother();
+ ASSERT(b);
+ CRect rc;
+ GetTreeCtrl().GetItemRect(b->m_Item,&rc,TRUE);
+ point = rc.TopLeft();
+ ClientToScreen(&point);
+ }
+ ContextMenu(point);
+}
+
+void CBigBrotherView::OnRclick(NMHDR* pNMHDR, LRESULT* pResult)
+{
+CPoint pt;
+ VERIFY(GetCursorPos(&pt));
+ ContextMenu(pt);
+ *pResult = 0;
+}
+
+void CBigBrotherView::ContextMenu(CPoint pt)
+{
+CMenu m;
+ VERIFY(m.LoadMenu(IDR_MAINFRAME));
+CMenu *popUp = m.GetSubMenu(1); // Brothers
+ ASSERT(popUp);
+ popUp->TrackPopupMenu(TPM_CENTERALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,pt.x,pt.y,AfxGetApp()->m_pMainWnd);
+}
+
+void CBigBrotherView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
+{
+}
+
+LRESULT CBigBrotherView::OnUpDown(WPARAM wP,LPARAM lP)
+{
+BOOL isUp = (BOOL)wP;
+CBrother *b = (CBrother*)lP;
+ ASSERT(b);
+UINT strResource;
+ b->ParentalAdjust();
+ if(isUp){
+ b->m_Up.PerformAction(b);
+ strResource = IDS_LOG_HOSTUP;
+ }else{
+ b->m_Down.PerformAction(b);
+ strResource = IDS_LOG_HOSTDOWN;
+ }
+CString logLine;
+ logLine.Format(strResource,(LPCTSTR)b->m_Desc,(LPCTSTR)b->m_Host);
+ logLine=b->m_Pinged.Format(IDS_LOG_DATEFORMAT)+" "+logLine;
+CBigBrotherDoc *pDoc = GetDocument();
+ ASSERT(pDoc);
+ pDoc->LogLine(logLine);
+ return 0;
+}
+
+void CBigBrotherView::KillBrother(CBrother *b)
+{
+ ASSERT(b->m_Item);
+CTreeCtrl& ctl = GetTreeCtrl();
+HTREEITEM hItem = ctl.GetNextItem(b->m_Item,TVGN_CHILD);
+ while(hItem){
+ CBrother *bb = (CBrother*)ctl.GetItemData(hItem);
+ ASSERT(bb);
+ KillBrother(bb);
+ hItem = ctl.GetNextItem(b->m_Item,TVGN_CHILD);
+ }
+ if(b->m_Daddy)
+ KillOneBrother(b);
+ // ??? Else - Cleanup?
+}
+
+void CBigBrotherView::KillOneBrother(CBrother *b)
+{
+ ASSERT(b);
+ ASSERT(b->m_Item);
+CTreeCtrl& ctl = GetTreeCtrl();
+ ASSERT(!ctl.ItemHasChildren(b->m_Item));
+ ctl.DeleteItem(b->m_Item);
+ VERIFY(b->m_Doc=GetDocument());
+ b->m_Item=NULL;
+ b->Suicide();
+}
+
+void CBigBrotherView::SetupExpansion(CBrother *b)
+{
+ ASSERT(b->m_Item);
+CTreeCtrl& ctl = GetTreeCtrl();
+ if(b->flags&CBrother::flagsExpandedTree)
+ ctl.Expand(b->m_Item,TVE_EXPAND);
+HTREEITEM hItem = ctl.GetNextItem(b->m_Item,TVGN_CHILD);
+ while(hItem){
+ CBrother *bb = (CBrother*)ctl.GetItemData(hItem);
+ ASSERT(bb);
+ SetupExpansion(bb);
+ hItem = ctl.GetNextItem(bb->m_Item,TVGN_NEXT);
+ }
+ if(b->flags&CBrother::flagsCurrentBrother)
+ GotoBrother(b);
+}
+
+void CBigBrotherView::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult)
+{
+NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
+CBigBrotherDoc *pDoc = GetDocument();
+ if(pDoc)
+ pDoc->UpdateAllViews(this);
+ *pResult = 0;
+}
+
+void CBigBrotherView::OnSetFocus(CWnd* pOldWnd)
+{
+ CTreeView::OnSetFocus(pOldWnd);
+
+CBigBrotherDoc *pDoc = GetDocument();
+ if(!(pDoc && m_Pages))
+ return;
+ m_Pages->ShowWindow((pDoc->flags&CBigBrotherDoc::flagsShowProps)?SW_SHOW:SW_HIDE);
+}
diff --git a/BigBrotherView.h b/BigBrotherView.h
new file mode 100644
index 0000000..5dda0ac
--- a/dev/null
+++ b/BigBrotherView.h
@@ -0,0 +1,89 @@
+// BigBrotherView.h : interface of the CBigBrotherView class
+//
+/////////////////////////////////////////////////////////////////////////////
+
+class CHostPropertyPages;
+class CBrother;
+class CBigBrotherDoc;
+typedef CTypedPtrList<CObList,CBrother*> CBrotherList;
+class CBigBrotherView : public CTreeView
+{
+protected: // create from serialization only
+ CBigBrotherView();
+ DECLARE_DYNCREATE(CBigBrotherView)
+
+// Attributes
+public:
+ void SetupExpansion(CBrother *b);
+ void KillOneBrother(CBrother *b);
+ void KillBrother(CBrother *b);
+ void ContextMenu(CPoint pt);
+ void GetFamily(CBrother* b,CBrotherList* bh);
+ int m_iPinging;
+ int m_iPending;
+ int m_iHostDown;
+ int m_iGoingDown;
+ int m_iHost;
+ int m_iNoHost;
+ CImageList m_Images;
+ void UpdateBrother(CBrother* b);
+ void GotoBrother(CBrother *b);
+ void AddBrother(CBrother *b);
+ CBrother* GetCurrentBrother();
+ HTREEITEM FindItem(CBrother* brother);
+ CHostPropertyPages* m_Pages;
+ CBigBrotherDoc* GetDocument();
+
+// Operations
+public:
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CBigBrotherView)
+ public:
+ virtual void OnDraw(CDC* pDC); // overridden to draw this view
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ protected:
+ virtual void OnInitialUpdate(); // called first time after construct
+ virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
+ virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
+ //}}AFX_VIRTUAL
+
+// Implementation
+public:
+ virtual ~CBigBrotherView();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+protected:
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(CBigBrotherView)
+ afx_msg void OnDestroy();
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnReturn(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg LRESULT OnActivityCount(WPARAM,LPARAM);
+ afx_msg LRESULT OnUpdateTreeBrother(WPARAM,LPARAM);
+ afx_msg LRESULT OnCheckQueue(WPARAM,LPARAM);
+ afx_msg void OnTimer(UINT nIDEvent);
+ afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
+ afx_msg void OnRclick(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg LRESULT OnUpDown(WPARAM,LPARAM);
+ afx_msg void OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnSetFocus(CWnd* pOldWnd);
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+#ifndef _DEBUG // debug version in BigBrotherView.cpp
+inline CBigBrotherDoc* CBigBrotherView::GetDocument()
+ { return (CBigBrotherDoc*)m_pDocument; }
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..d3b2450
--- a/dev/null
+++ b/COPYING
@@ -0,0 +1,19 @@
+Copyright (c) 1996, 2002 Klever Group (http://www.klever.net/)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/GeneralPage.cpp b/GeneralPage.cpp
new file mode 100644
index 0000000..58ebe74
--- a/dev/null
+++ b/GeneralPage.cpp
@@ -0,0 +1,168 @@
+// GeneralPage.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "BigBrother.h"
+#include "GeneralPage.h"
+#include "HostPropertyPages.h"
+#include "BigBrotherDoc.h"
+#include "BigBrotherView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CGeneralPage property page
+
+IMPLEMENT_DYNCREATE(CGeneralPage, CPropertyPage)
+
+CGeneralPage::CGeneralPage() : CPropertyPage(CGeneralPage::IDD)
+{
+ //{{AFX_DATA_INIT(CGeneralPage)
+ m_Desc = _T("");
+ m_Host = _T("");
+ m_LogActivity = FALSE;
+ //}}AFX_DATA_INIT
+}
+
+CGeneralPage::~CGeneralPage()
+{
+}
+
+void CGeneralPage::DoDataExchange(CDataExchange* pDX)
+{
+ CPropertyPage::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CGeneralPage)
+ DDX_Control(pDX, IDC_LOG_ACTIVITY, m_LogActivityCtl);
+ DDX_Control(pDX, IDC_HOST, m_HostCtl);
+ DDX_Control(pDX, IDC_DESC, m_DescCtl);
+ DDX_Text(pDX, IDC_DESC, m_Desc);
+ DDX_Text(pDX, IDC_HOST, m_Host);
+ DDX_Check(pDX, IDC_LOG_ACTIVITY, m_LogActivity);
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CGeneralPage, CPropertyPage)
+ //{{AFX_MSG_MAP(CGeneralPage)
+ ON_EN_CHANGE(IDC_HOST, OnChangeHost)
+ ON_BN_CLICKED(IDC_LOG_ACTIVITY, OnLogActivity)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CGeneralPage message handlers
+
+void CGeneralPage::OnChangeHost()
+{
+CString h,d;
+ m_HostCtl.GetWindowText(h);
+ m_DescCtl.GetWindowText(d);
+ if(d==m_Host){
+ m_Desc=h;
+ m_Host=h;
+ m_DescCtl.SetWindowText(m_Desc);
+ }
+}
+
+void CGeneralPage::OnLogActivity()
+{
+ ASSERT(m_dad->m_Brother);
+ if(!m_dad->m_Brother->m_Daddy){
+ int tmp = m_LogActivityCtl.GetCheck();
+ if(tmp==2){
+ if(m_LogActivity)
+ tmp=0;
+ else
+ tmp=1;
+ }
+ m_LogActivity=tmp;
+ }else
+ m_LogActivity=m_LogActivityCtl.GetCheck();
+ m_LogActivityCtl.SetCheck(m_LogActivity);
+ SetupControls();
+}
+
+void CGeneralPage::UpdatePage()
+{
+ if(!m_dad->m_Brother)
+ return;
+ m_Host=m_dad->m_Brother->m_Host;
+ m_Desc=m_dad->m_Brother->m_Desc;
+ m_LogActivity=(m_dad->m_Brother->flags&CBrother::flagsOverrideLogging)?(m_dad->m_Brother->m_bLog?1:0):2;
+ if(::IsWindow(m_hWnd)){
+ UpdateData(FALSE);
+ SetupControls();
+ }
+}
+
+BOOL CGeneralPage::OnSetActive()
+{
+ UpdatePage();
+
+ return CPropertyPage::OnSetActive();
+}
+
+void CGeneralPage::UpdateBrother()
+{
+ if(!m_dad->m_Brother){
+ TRACE0("No brother on update\n");
+ return;
+ }
+ if(::IsWindow(m_hWnd))
+ UpdateData();
+CBrother toCompare;
+ toCompare = *m_dad->m_Brother;
+ m_dad->m_Brother->m_Host=m_Host;
+ m_dad->m_Brother->m_Desc=m_Desc;
+ switch(m_LogActivity){
+ case 0:
+ m_dad->m_Brother->m_bLog=FALSE;
+ m_dad->m_Brother->flags|=CBrother::flagsOverrideLogging;
+ break;
+ case 1:
+ m_dad->m_Brother->m_bLog=TRUE;
+ m_dad->m_Brother->flags|=CBrother::flagsOverrideLogging;
+ break;
+ default:
+ m_dad->m_Brother->flags&=~CBrother::flagsOverrideLogging;
+ break;
+ }
+ m_dad->m_Brother->ParentalAdjust();
+ if(toCompare!=(*m_dad->m_Brother)){
+ CDocument *pDoc = m_dad->m_Daddy->GetDocument();
+ ASSERT(pDoc);
+ pDoc->SetModifiedFlag();
+ }
+ if(::IsWindow(m_hWnd)){
+ UpdateData(FALSE);
+ SetupControls();
+ }
+ m_dad->m_Daddy->UpdateBrother(m_dad->m_Brother);
+}
+
+void CGeneralPage::SetupControls()
+{
+CString tmp;
+ switch(m_LogActivity){
+ case 0:
+ tmp.LoadString(IDS_LOG_DONTLOG);
+ break;
+ case 1:
+ tmp.LoadString(IDS_LOG_DOLOG);
+ break;
+ default:
+ tmp.LoadString(IDS_LOG_ASKBIGBROTHER);
+ break;
+ }
+ m_LogActivityCtl.SetWindowText(tmp);
+}
+
+BOOL CGeneralPage::OnKillActive()
+{
+ UpdateBrother();
+ return CPropertyPage::OnKillActive();
+}
diff --git a/GeneralPage.h b/GeneralPage.h
new file mode 100644
index 0000000..e0153ee
--- a/dev/null
+++ b/GeneralPage.h
@@ -0,0 +1,52 @@
+// GeneralPage.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CGeneralPage dialog
+
+class CHostPropertyPages;
+class CGeneralPage : public CPropertyPage
+{
+ DECLARE_DYNCREATE(CGeneralPage)
+
+// Construction
+public:
+ void SetupControls();
+ void UpdateBrother();
+ void UpdatePage();
+ CHostPropertyPages* m_dad;
+ CGeneralPage();
+ ~CGeneralPage();
+
+// Dialog Data
+ //{{AFX_DATA(CGeneralPage)
+ enum { IDD = IDD_PROPS_GENERAL };
+ CButton m_LogActivityCtl;
+ CEdit m_HostCtl;
+ CEdit m_DescCtl;
+ CString m_Desc;
+ CString m_Host;
+ int m_LogActivity;
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generate virtual function overrides
+ //{{AFX_VIRTUAL(CGeneralPage)
+ public:
+ virtual BOOL OnSetActive();
+ virtual BOOL OnKillActive();
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ // Generated message map functions
+ //{{AFX_MSG(CGeneralPage)
+ afx_msg void OnChangeHost();
+ afx_msg void OnLogActivity();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+
+};
diff --git a/HostPropertyPages.cpp b/HostPropertyPages.cpp
new file mode 100644
index 0000000..8583bf8
--- a/dev/null
+++ b/HostPropertyPages.cpp
@@ -0,0 +1,124 @@
+// HostPropertyPages.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "BigBrother.h"
+#include "HostPropertyPages.h"
+#include "GeneralPage.h"
+#include "SettingsPage.h"
+#include "ActionPage.h"
+#include "BigBrotherDoc.h"
+#include "BigBrotherView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CHostPropertyPages
+
+IMPLEMENT_DYNAMIC(CHostPropertyPages, CPropertySheet)
+
+CHostPropertyPages::CHostPropertyPages(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
+ :CPropertySheet(nIDCaption, pParentWnd, iSelectPage), m_Brother(NULL)
+{
+ CreatePages();
+}
+
+CHostPropertyPages::CHostPropertyPages(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
+ :CPropertySheet(pszCaption, pParentWnd, iSelectPage), m_Brother(NULL)
+{
+ CreatePages();
+}
+
+CHostPropertyPages::~CHostPropertyPages()
+{
+ delete m_Action;
+ delete m_Settings;
+ delete m_General;
+}
+
+
+BEGIN_MESSAGE_MAP(CHostPropertyPages, CPropertySheet)
+ //{{AFX_MSG_MAP(CHostPropertyPages)
+ ON_WM_CREATE()
+ ON_WM_DESTROY()
+ ON_BN_CLICKED(IDOK, OnOK)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CHostPropertyPages message handlers
+
+void CHostPropertyPages::CreatePages()
+{
+ m_General = new CGeneralPage();
+ m_Settings = new CSettingsPage();
+ m_Action = new CActionPage();
+ m_General->m_dad=this;
+ m_Settings->m_dad=this;
+ m_Action->m_dad=this;
+ AddPage(m_General);
+ AddPage(m_Settings);
+ AddPage(m_Action);
+ m_InitialPosition.x=AfxGetApp()->GetProfileInt("PropertiesPosition","left",-1);
+ m_InitialPosition.y=AfxGetApp()->GetProfileInt("PropertiesPosition","top",-1);
+}
+
+void CHostPropertyPages::SetBrother(CBrother* b)
+{
+ if(m_Brother)
+ UpdateBrother();
+ m_Brother=b;
+ m_General->UpdatePage();
+ m_Settings->UpdatePage();
+ m_Action->UpdatePage();
+}
+
+void CHostPropertyPages::UpdateBrother()
+{
+ if(!m_Brother)
+ return;
+ m_General->UpdateBrother();
+ m_Settings->UpdateBrother();
+ m_Action->UpdateBrother();
+ ASSERT(m_Daddy);
+CDocument *pDoc = m_Daddy->GetDocument();
+ if(pDoc);
+ pDoc->UpdateAllViews(NULL);
+ //PostMessage(WM_UPDATETREEBROTHER,0,(LPARAM)m_Brother);
+}
+
+int CHostPropertyPages::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if (CPropertySheet::OnCreate(lpCreateStruct) == -1)
+ return -1;
+ ModifyStyle(m_Daddy->IsWindowVisible()?0:WS_VISIBLE,WS_POPUP||WS_CLIPSIBLINGS|WS_BORDER|WS_DLGFRAME);
+ ModifyStyleEx(0,WS_EX_TOOLWINDOW|WS_EX_WINDOWEDGE);
+ return 0;
+}
+
+void CHostPropertyPages::OnDestroy()
+{
+ CPropertySheet::OnDestroy();
+CRect rc;
+ GetWindowRect(rc);
+ AfxGetApp()->WriteProfileInt("PropertiesPosition","left",rc.left);
+ AfxGetApp()->WriteProfileInt("PropertiesPosition","top",rc.top);
+}
+
+BOOL CHostPropertyPages::OnInitDialog()
+{
+BOOL rv = CPropertySheet::OnInitDialog();
+ VERIFY(m_OK.SubclassWindow(GetDlgItem(IDOK)->m_hWnd));
+ m_OK.EnableWindow(TRUE);
+ return rv;
+}
+
+void CHostPropertyPages::OnOK()
+{
+ UpdateBrother();
+ AfxGetApp()->GetMainWnd()->SetFocus();
+}
diff --git a/HostPropertyPages.h b/HostPropertyPages.h
new file mode 100644
index 0000000..4c4218a
--- a/dev/null
+++ b/HostPropertyPages.h
@@ -0,0 +1,58 @@
+// HostPropertyPages.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CHostPropertyPages
+
+class CGeneralPage;
+class CSettingsPage;
+class CActionPage;
+class CBrother;
+class CBigBrotherView;
+class CHostPropertyPages : public CPropertySheet
+{
+ DECLARE_DYNAMIC(CHostPropertyPages)
+
+// Construction
+public:
+ CButton m_OK;
+ CPoint m_InitialPosition;
+ CBigBrotherView* m_Daddy;
+ void UpdateBrother();
+ CBrother* m_Brother;
+ void SetBrother(CBrother* b);
+ void CreatePages();
+ CActionPage* m_Action;
+ CSettingsPage* m_Settings;
+ CGeneralPage* m_General;
+ CHostPropertyPages(UINT nIDCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
+ CHostPropertyPages(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
+
+// Attributes
+public:
+
+// Operations
+public:
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CHostPropertyPages)
+ public:
+ virtual BOOL OnInitDialog();
+ //}}AFX_VIRTUAL
+
+// Implementation
+public:
+ virtual ~CHostPropertyPages();
+
+ // Generated message map functions
+protected:
+ //{{AFX_MSG(CHostPropertyPages)
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnDestroy();
+ afx_msg void OnOK();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/KTAGS b/KTAGS
new file mode 100644
index 0000000..78dd936
--- a/dev/null
+++ b/KTAGS
@@ -0,0 +1,12 @@
+about-date bigbrother.rc /LTEXT\s\+"Copyright /;" kind:d
+about-version bigbrother.rc /LTEXT\s\+"Big Brother, Version/;" kind:v
+help-license-date ./help/bigbrother.xml /<license\s/;" kind:d
+help-news ./help/bigbrother.xml /<newsfor\s/
+install-version ./install/install.cpp /^#define\s\+VERSION\s\+"/;" kind:v
+install-vsinfo-date install/install.rc /^\s\+VALUE\s\+"LegalCopyright",/;" kind:d
+install-vsinfo-numeric-version install/install.rc /^\s\+FILEVERSION\s\+/;" kind:v
+install-vsinfo-string-version install/install.rc /^\s\+VALUE\s\+"FileVersion",/;" kind:v
+license-date COPYING :1;" kind:d
+vsinfo-date bigbrother.rc /VALUE\s\+"LegalCopyright",/;" kind:d
+vsinfo-numeric-version bigbrother.rc /^\s\+FILEVERSION\s\+/;" kind:v
+vsinfo-string-version bigbrother.rc /^\s\+VALUE\s\+"FileVersion",/;" kind:v
diff --git a/MainFrm.cpp b/MainFrm.cpp
new file mode 100644
index 0000000..97de7b2
--- a/dev/null
+++ b/MainFrm.cpp
@@ -0,0 +1,299 @@
+// MainFrm.cpp : implementation of the CMainFrame class
+//
+
+#include "stdafx.h"
+#include "BigBrother.h"
+
+#include "MainFrm.h"
+#include "BigBrotherView.h"
+#include "ActivityView.h"
+#include "BigBrotherDoc.h"
+#include "HostPropertyPages.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CMainFrame
+
+IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
+
+BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
+ //{{AFX_MSG_MAP(CMainFrame)
+ ON_WM_CREATE()
+ ON_WM_DESTROY()
+ ON_UPDATE_COMMAND_UI(ID_VIEW_MAINWINDOW, OnUpdateViewMainwindow)
+ ON_COMMAND(ID_VIEW_MAINWINDOW, OnViewMainwindow)
+ ON_WM_WINDOWPOSCHANGING()
+ ON_UPDATE_COMMAND_UI(ID_INDICATOR_PINGBAR, OnUpdateIndicatorPingbar)
+ ON_WM_CLOSE()
+ ON_MESSAGE(WM_TRAYICONMESSAGE, OnNotifyIcon)
+ ON_WM_QUERYENDSESSION()
+ //}}AFX_MSG_MAP
+ // Global help commands
+ ON_COMMAND(ID_HELP_FINDER, CFrameWnd::OnHelpFinder)
+ ON_COMMAND(ID_HELP, CFrameWnd::OnHelp)
+ ON_COMMAND(ID_CONTEXT_HELP, CFrameWnd::OnContextHelp)
+ ON_COMMAND(ID_DEFAULT_HELP, CFrameWnd::OnHelpFinder)
+END_MESSAGE_MAP()
+
+static UINT indicators[] =
+{
+ ID_INDICATOR_PINGBAR,
+ ID_SEPARATOR // status line indicator
+/* ID_INDICATOR_CAPS,
+ ID_INDICATOR_NUM,
+ ID_INDICATOR_SCRL*/
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// CMainFrame construction/destruction
+
+CMainFrame::CMainFrame()
+{
+ m_bExiting=FALSE;
+ m_bShuttingDown=FALSE;
+}
+
+CMainFrame::~CMainFrame()
+{
+}
+
+int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ if (!m_wndToolBar.Create(this) ||
+ !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
+ {
+ TRACE0("Failed to create toolbar\n");
+ return -1; // fail to create
+ }
+
+ if (!m_wndStatusBar.Create(this,WS_CHILD | WS_VISIBLE | CBRS_BOTTOM|CBRS_SIZE_DYNAMIC) ||
+ !m_wndStatusBar.SetIndicators(indicators,
+ sizeof(indicators)/sizeof(UINT)))
+ {
+ TRACE0("Failed to create status bar\n");
+ return -1; // fail to create
+ }
+ m_wndStatusBar.SetPaneStyle(1,m_wndStatusBar.GetPaneStyle(1)|SBPS_STRETCH);
+ VERIFY(m_PingBar.Create(WS_CHILD|WS_VISIBLE|ACS_TRANSPARENT,CRect(0,0,0,0),&m_wndStatusBar,ID_INDICATOR_PINGBAR));
+ m_PingBar.Open(IDR_PINGBAR);
+CRect rc;
+ m_PingBar.GetWindowRect(rc);
+int nHorz, nVert, nSpacing;
+ m_wndStatusBar.GetStatusBarCtrl().GetBorders(nHorz,nVert,nSpacing);
+ m_wndStatusBar.GetStatusBarCtrl().SetMinHeight(rc.Height()+nVert*2);
+ m_wndStatusBar.SetTheMinHeight(rc.Height()+nVert*2);
+ m_wndStatusBar.SetPaneInfo(m_wndStatusBar.CommandToIndex(ID_INDICATOR_PINGBAR),ID_INDICATOR_PINGBAR,SBPS_NORMAL,rc.Width());
+ m_PingBar.SetWindowPos(NULL,nHorz+nSpacing+1,nVert+1,0,0,SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
+
+ m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
+ CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
+
+ m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
+ EnableDocking(CBRS_ALIGN_ANY);
+ DockControlBar(&m_wndToolBar);
+
+NOTIFYICONDATA nid;
+ memset(&nid,0,sizeof(nid));
+ nid.cbSize=sizeof(nid);
+ nid.hWnd=m_hWnd;
+ nid.uID=IDC_TRAYICON;
+ nid.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP;
+ nid.uCallbackMessage=WM_TRAYICONMESSAGE;
+ nid.hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+ // *** Load from resource
+ strcpy(nid.szTip,"Big Brother");
+ VERIFY(Shell_NotifyIcon(NIM_ADD,&nid));
+ return 0;
+}
+
+BOOL CMainFrame::OnCreateClient( LPCREATESTRUCT /*lpcs*/,
+ CCreateContext* pContext)
+{
+ if(!m_wndSplitter.CreateStatic(this,2,1)){
+ TRACE0("Failed to create static splitter\n");
+ return FALSE;
+ }
+CRect rc;
+ GetClientRect(rc);
+int cySize = AfxGetApp()->GetProfileInt("SplitterPosition","TreeSize",-1);
+ if(!m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CBigBrotherView),CSize(0,(cySize<0)?(rc.Height()/2):cySize),pContext)){
+ TRACE0("Failed to create Tree View\n");
+ return FALSE;
+ }
+ cySize = AfxGetApp()->GetProfileInt("SplitterPosition","ActivitySize",-1);
+ if(!m_wndSplitter.CreateView(1,0,RUNTIME_CLASS(CActivityView),CSize(0,(cySize<0)?(rc.Height()/2):cySize),pContext)){
+ TRACE0("Failed to create Activity View\n");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
+{
+CRect rc;
+CWinApp *app = AfxGetApp();
+ rc.left=app->GetProfileInt("FramePosition","left",-1);
+ rc.top=app->GetProfileInt("FramePosition","top",-1);
+ rc.right=app->GetProfileInt("FramePosition","right",-1);
+ rc.bottom=app->GetProfileInt("FramePosition","bottom",-1);
+ if(rc.left>=0 && rc.top>=0 && rc.right>=0 && rc.bottom>=0){
+ cs.x=rc.left, cs.y=rc.top;
+ cs.cx=rc.Width(), cs.cy=rc.Height();
+ }
+int tmp = app->GetProfileInt("FramePosition","shown",-1);
+ if(!tmp){
+ cs.style&=~WS_VISIBLE;
+ m_bShown=FALSE;
+ }else
+ m_bShown=TRUE;
+ cs.style&=~WS_MINIMIZEBOX|WS_MAXIMIZEBOX;
+ return CFrameWnd::PreCreateWindow(cs);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CMainFrame diagnostics
+
+#ifdef _DEBUG
+void CMainFrame::AssertValid() const
+{
+ CFrameWnd::AssertValid();
+}
+
+void CMainFrame::Dump(CDumpContext& dc) const
+{
+ CFrameWnd::Dump(dc);
+}
+
+#endif //_DEBUG
+
+/////////////////////////////////////////////////////////////////////////////
+// CMainFrame message handlers
+
+void CMainFrame::OnDestroy()
+{
+ CFrameWnd::OnDestroy();
+
+ m_bExiting=TRUE;
+
+ // Save window size and position
+CRect rc;
+ GetWindowRect(rc);
+CWinApp *app = AfxGetApp();
+ app->WriteProfileInt("FramePosition","left",rc.left);
+ app->WriteProfileInt("FramePosition","top",rc.top);
+ app->WriteProfileInt("FramePosition","right",rc.right);
+ app->WriteProfileInt("FramePosition","bottom",rc.bottom);
+int cyCur,cyMin;
+ m_wndSplitter.GetRowInfo(0,cyCur,cyMin);
+ app->WriteProfileInt("SplitterPosition","TreeSize",cyCur);
+ m_wndSplitter.GetRowInfo(1,cyCur,cyMin);
+ app->WriteProfileInt("SplitterPosition","ActivitySize",cyCur);
+ app->WriteProfileInt("FramePosition","shown",m_bShown);
+
+NOTIFYICONDATA nid;
+ memset(&nid,0,sizeof(nid));
+ nid.cbSize=sizeof(nid);
+ nid.hWnd=m_hWnd;
+ nid.uID=IDC_TRAYICON;
+ nid.uFlags=0;
+ VERIFY(Shell_NotifyIcon(NIM_DELETE,&nid));
+}
+
+LRESULT CMainFrame::OnNotifyIcon(WPARAM wP,LPARAM lP)
+{
+ ASSERT(wP==IDC_TRAYICON);
+ switch(lP){
+ case WM_LBUTTONDOWN:
+ OnViewMainwindow();
+ break;
+ case WM_RBUTTONDOWN:
+ {
+ CMenu menu;
+ VERIFY(menu.LoadMenu(IDM_POPUPS));
+ CMenu *popUp = menu.GetSubMenu(0);
+ ASSERT(popUp);
+ CPoint pt;
+ VERIFY(::GetCursorPos(&pt));
+ popUp->TrackPopupMenu(TPM_RIGHTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,pt.x,pt.y,this,NULL);
+ }
+ break;
+ default:
+/* {
+ CString tmp;
+ tmp.Format("NIMESSAGE: %08lX\n",lP);
+ TRACE0(tmp);
+ }*/
+ break;
+ }
+ return 0;
+}
+
+void CMainFrame::FrameDisplayState(BOOL bShow)
+{
+ m_bShown=bShow;
+ ShowWindow(bShow?SW_SHOW:SW_HIDE);
+CBigBrotherDoc *doc = (CBigBrotherDoc*)GetActiveDocument();
+ if(doc){
+ ASSERT(doc->IsKindOf(RUNTIME_CLASS(CBigBrotherDoc)));
+ ASSERT(doc->m_BBView);
+ ASSERT(doc->m_BBView->m_Pages);
+ ASSERT(::IsWindow(doc->m_BBView->m_Pages->m_hWnd));
+ doc->m_BBView->m_Pages->ShowWindow(bShow?SW_SHOW:SW_HIDE);
+ }
+ if(bShow){
+ SetForegroundWindow();
+ SetFocus();
+ }
+}
+
+void CMainFrame::OnUpdateViewMainwindow(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(IsWindowVisible()?1:0);
+}
+
+void CMainFrame::OnViewMainwindow()
+{
+ FrameDisplayState(!IsWindowVisible());
+}
+
+void CMainFrame::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
+{
+ if(!m_bExiting){
+ if(m_bShown){
+ lpwndpos->flags&=~SWP_HIDEWINDOW;
+ lpwndpos->flags|=SWP_SHOWWINDOW;
+ }else{
+ lpwndpos->flags&=~SWP_SHOWWINDOW;
+ lpwndpos->flags|=SWP_HIDEWINDOW;
+ }
+ }
+ CFrameWnd::OnWindowPosChanging(lpwndpos);
+}
+
+void CMainFrame::OnUpdateIndicatorPingbar(CCmdUI* pCmdUI)
+{
+ pCmdUI->Enable(TRUE);
+}
+
+void CMainFrame::OnClose()
+{
+ m_bExiting=TRUE;
+ CFrameWnd::OnClose();
+}
+
+BOOL CMainFrame::OnQueryEndSession()
+{
+ m_bShuttingDown=TRUE;
+ if (!CFrameWnd::OnQueryEndSession())
+ return FALSE;
+ ::PostQuitMessage(0);
+ return TRUE;
+}
diff --git a/MainFrm.h b/MainFrm.h
new file mode 100644
index 0000000..25a520c
--- a/dev/null
+++ b/MainFrm.h
@@ -0,0 +1,65 @@
+// MainFrm.h : interface of the CMainFrame class
+//
+/////////////////////////////////////////////////////////////////////////////
+
+class CGoodStatusBar : public CStatusBar {
+public:
+ void SetTheMinHeight(int nMinHeight) {m_nMinHeight=nMinHeight;}
+};
+
+class CMainFrame : public CFrameWnd
+{
+protected: // create from serialization only
+ CMainFrame();
+ DECLARE_DYNCREATE(CMainFrame)
+
+// Attributes
+protected:
+ CSplitterWnd m_wndSplitter;
+public:
+ BOOL m_bShuttingDown;
+ CAnimateCtrl m_PingBar;
+ BOOL m_bExiting;
+ BOOL m_bShown;
+ void FrameDisplayState(BOOL bShow);
+
+// Operations
+public:
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CMainFrame)
+ public:
+ virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ //}}AFX_VIRTUAL
+
+// Implementation
+public:
+ virtual ~CMainFrame();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+protected: // control bar embedded members
+ CGoodStatusBar m_wndStatusBar;
+ CToolBar m_wndToolBar;
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(CMainFrame)
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnDestroy();
+ afx_msg void OnUpdateViewMainwindow(CCmdUI* pCmdUI);
+ afx_msg void OnViewMainwindow();
+ afx_msg void OnWindowPosChanging(WINDOWPOS FAR* lpwndpos);
+ afx_msg void OnUpdateIndicatorPingbar(CCmdUI* pCmdUI);
+ afx_msg void OnClose();
+ afx_msg LRESULT OnNotifyIcon(WPARAM,LPARAM);
+ afx_msg BOOL OnQueryEndSession();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/Preferences.cpp b/Preferences.cpp
new file mode 100644
index 0000000..b975d00
--- a/dev/null
+++ b/Preferences.cpp
@@ -0,0 +1,93 @@
+// Preferences.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "BigBrother.h"
+#include "Preferences.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CPreferences dialog
+
+
+CPreferences::CPreferences(CWnd* pParent /*=NULL*/)
+ : CDialog(CPreferences::IDD, pParent)
+{
+ //{{AFX_DATA_INIT(CPreferences)
+ m_AutosaveMinutes = 0;
+ m_LogFile = _T("");
+ m_MaxThreads = 0;
+ m_PingSize = 0;
+ m_SaveOnShutdown = FALSE;
+ m_LogMins = 0;
+ m_bStoreLastActivity = FALSE;
+ //}}AFX_DATA_INIT
+}
+
+
+void CPreferences::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CPreferences)
+ DDX_Control(pDX, IDC_LOGMINSPIN, m_LogMinSpinCtl);
+ DDX_Control(pDX, IDC_LOGFILE, m_LogFileCtl);
+ DDX_Control(pDX, IDC_THREADSPIN, m_ThreadsSpinCtl);
+ DDX_Control(pDX, IDC_DATASIZESPIN, m_DatasizeSpinCtl);
+ DDX_Control(pDX, IDC_BROWSE, m_BrowseCtl);
+ DDX_Control(pDX, IDC_AUTOSPIN, m_AutosaveSpinCtl);
+ DDX_Text(pDX, IDC_AUTOSAVEMINS, m_AutosaveMinutes);
+ DDV_MinMaxUInt(pDX, m_AutosaveMinutes, 0, 300);
+ DDX_Text(pDX, IDC_LOGFILE, m_LogFile);
+ DDX_Text(pDX, IDC_MAXTHREADS, m_MaxThreads);
+ DDV_MinMaxUInt(pDX, m_MaxThreads, 1, 50);
+ DDX_Text(pDX, IDC_PINGSIZE, m_PingSize);
+ DDV_MinMaxUInt(pDX, m_PingSize, 0, 32768);
+ DDX_Check(pDX, IDC_SAVEONSHUTDOWN, m_SaveOnShutdown);
+ DDX_Text(pDX, IDC_LOGMINS, m_LogMins);
+ DDV_MinMaxUInt(pDX, m_LogMins, 1, 1440);
+ DDX_Check(pDX, IDC_STOREACTIVITY, m_bStoreLastActivity);
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CPreferences, CDialog)
+ //{{AFX_MSG_MAP(CPreferences)
+ ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CPreferences message handlers
+
+BOOL CPreferences::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ m_BrowseCtl.SetIcon(AfxGetApp()->LoadIcon(IDI_BROWSESOUND));
+ m_AutosaveSpinCtl.SetRange(0,300);
+ m_DatasizeSpinCtl.SetRange(1,32767);
+ m_ThreadsSpinCtl.SetRange(1,50);
+ m_LogMinSpinCtl.SetRange(1,1440);
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CPreferences::OnBrowse()
+{
+CString filter;
+ filter.LoadString(IDS_LOGFILTER);
+CString title;
+ title.LoadString(IDS_LOGFILE_SELECT);
+CFileDialog cfd(FALSE,NULL,m_LogFile,OFN_EXPLORER|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY|OFN_NOTESTFILECREATE,filter,this);
+ cfd.m_ofn.lpstrTitle=title;
+ if(cfd.DoModal()==IDOK){
+ m_LogFile=cfd.GetPathName();
+ m_LogFileCtl.SetWindowText(cfd.GetPathName());
+ }
+}
diff --git a/Preferences.h b/Preferences.h
new file mode 100644
index 0000000..04885f2
--- a/dev/null
+++ b/Preferences.h
@@ -0,0 +1,48 @@
+// Preferences.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CPreferences dialog
+
+class CPreferences : public CDialog
+{
+// Construction
+public:
+ CPreferences(CWnd* pParent = NULL); // standard constructor
+
+// Dialog Data
+ //{{AFX_DATA(CPreferences)
+ enum { IDD = IDD_PREFS };
+ CSpinButtonCtrl m_LogMinSpinCtl;
+ CEdit m_LogFileCtl;
+ CSpinButtonCtrl m_ThreadsSpinCtl;
+ CSpinButtonCtrl m_DatasizeSpinCtl;
+ CButton m_BrowseCtl;
+ CSpinButtonCtrl m_AutosaveSpinCtl;
+ UINT m_AutosaveMinutes;
+ CString m_LogFile;
+ UINT m_MaxThreads;
+ UINT m_PingSize;
+ BOOL m_SaveOnShutdown;
+ UINT m_LogMins;
+ BOOL m_bStoreLastActivity;
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CPreferences)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+
+ // Generated message map functions
+ //{{AFX_MSG(CPreferences)
+ virtual BOOL OnInitDialog();
+ afx_msg void OnBrowse();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
diff --git a/README b/README
new file mode 100644
index 0000000..114afa5
--- a/dev/null
+++ b/README
@@ -0,0 +1,32 @@
+
+Before compiling canned install executable the following files should be placed
+in the build tree:
+
+redist/mfc42.dl_
+
+Release checklist:
+ (These are tags stored in KTAGS file. please, keep in sync. Use vim to
+ jump to these tags. I haven't tried it on windows, though).
+
+|help-news| - Release notes in help file
+
+Version number in the following places:
+
+|about-version| - About box
+|vsinfo-numeric-version| - VERSIONINFO numerical File&Prod V
+|vsinfo-string-version| - VERSIONINFO string File&Prod V
+|install-version| - Version used in install
+|install-vsinfo-numeric-version| - install's VERSIONINFO block
+|install-vsinfo-string-version| - install's VERSIONINFO block
+
+If the year flips check these:
+
+|about-date| - About box
+|help-license-date| - license in help file
+|license-date| - license in COPYING file
+|vsinfo-date| - Copyright in VERSIONINFO block
+|install-vsinfo-date| - Copyright in install's VERSIONINFO
+ block
+
+This is for vim (don't remove):
+ vim:set tags=KTAGS isk=!-~,^*,^\|,^\" ft=help:
diff --git a/SettingsPage.cpp b/SettingsPage.cpp
new file mode 100644
index 0000000..2fa42d0
--- a/dev/null
+++ b/SettingsPage.cpp
@@ -0,0 +1,186 @@
+// SettingsPage.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "BigBrother.h"
+#include "SettingsPage.h"
+#include "HostPropertyPages.h"
+#include "BigBrotherDoc.h"
+#include "BigBrotherView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CSettingsPage property page
+
+IMPLEMENT_DYNCREATE(CSettingsPage, CPropertyPage)
+
+CSettingsPage::CSettingsPage() : CPropertyPage(CSettingsPage::IDD)
+{
+ //{{AFX_DATA_INIT(CSettingsPage)
+ m_OverrideIntervals = FALSE;
+ m_OverrideRetries = FALSE;
+ m_OverrideTimeout = FALSE;
+ m_IntervalBad = 0;
+ m_IntervalGood = 0;
+ m_TimeOut = 0;
+ m_Retries = 0;
+ //}}AFX_DATA_INIT
+}
+
+CSettingsPage::~CSettingsPage()
+{
+}
+
+void CSettingsPage::DoDataExchange(CDataExchange* pDX)
+{
+ CPropertyPage::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CSettingsPage)
+ DDX_Control(pDX, IDC_RETRIES, m_RetriesCtl);
+ DDX_Control(pDX, IDC_PINGTIMEOUT, m_TimeOutCtl);
+ DDX_Control(pDX, IDC_PINGINTERVAL_GOOD, m_IntervalGoodCtl);
+ DDX_Control(pDX, IDC_PINGINTERVAL_BAD, m_IntervalBadCtl);
+ DDX_Control(pDX, IDC_OVERRIDE_TIMEOUT, m_OverrideTimeoutCtl);
+ DDX_Control(pDX, IDC_OVERRIDE_RETRIES, m_OverrideRetriesCtl);
+ DDX_Control(pDX, IDC_OVERRIDE_INTERVALS, m_OverrideIntervalsCtl);
+ DDX_Check(pDX, IDC_OVERRIDE_INTERVALS, m_OverrideIntervals);
+ DDX_Check(pDX, IDC_OVERRIDE_RETRIES, m_OverrideRetries);
+ DDX_Check(pDX, IDC_OVERRIDE_TIMEOUT, m_OverrideTimeout);
+ DDX_Text(pDX, IDC_PINGINTERVAL_BAD, m_IntervalBad);
+ DDX_Text(pDX, IDC_PINGINTERVAL_GOOD, m_IntervalGood);
+ DDX_Text(pDX, IDC_PINGTIMEOUT, m_TimeOut);
+ DDX_Text(pDX, IDC_RETRIES, m_Retries);
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CSettingsPage, CPropertyPage)
+ //{{AFX_MSG_MAP(CSettingsPage)
+ ON_BN_CLICKED(IDC_OVERRIDE_INTERVALS, OnOverrideIntervals)
+ ON_BN_CLICKED(IDC_OVERRIDE_RETRIES, OnOverrideRetries)
+ ON_BN_CLICKED(IDC_OVERRIDE_TIMEOUT, OnOverrideTimeout)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CSettingsPage message handlers
+
+void CSettingsPage::SetupControls()
+{
+ m_IntervalBadCtl.EnableWindow(m_OverrideIntervals);
+ m_IntervalGoodCtl.EnableWindow(m_OverrideIntervals);
+ m_RetriesCtl.EnableWindow(m_OverrideRetries);
+ m_TimeOutCtl.EnableWindow(m_OverrideTimeout);
+}
+
+void CSettingsPage::UpdatePage()
+{
+ if(!m_dad->m_Brother)
+ return;
+ if(::IsWindow(m_hWnd)){
+ if(m_dad->m_Brother->m_Daddy){
+ m_OverrideIntervalsCtl.EnableWindow(TRUE);
+ m_OverrideRetriesCtl.EnableWindow(TRUE);
+ m_OverrideTimeoutCtl.EnableWindow(TRUE);
+ }else{
+ m_OverrideIntervalsCtl.EnableWindow(FALSE);
+ m_OverrideRetriesCtl.EnableWindow(FALSE);
+ m_OverrideTimeoutCtl.EnableWindow(FALSE);
+ }
+ }
+ if(m_dad->m_Brother->flags&CBrother::flagsOverrideIntervals)
+ m_OverrideIntervals=TRUE;
+ else
+ m_OverrideIntervals=FALSE;
+ if(m_dad->m_Brother->flags&CBrother::flagsOverrideTimeout)
+ m_OverrideTimeout=TRUE;
+ else
+ m_OverrideTimeout=FALSE;
+ if(m_dad->m_Brother->flags&CBrother::flagsOverrideRetries)
+ m_OverrideRetries=TRUE;
+ else
+ m_OverrideRetries=FALSE;
+ m_IntervalBad=m_dad->m_Brother->m_IntervalBad;
+ m_IntervalGood=m_dad->m_Brother->m_IntervalGood;
+ m_Retries=m_dad->m_Brother->m_Retries;
+ m_TimeOut=m_dad->m_Brother->m_TimeOut;
+ if(::IsWindow(m_hWnd)){
+ UpdateData(FALSE);
+ SetupControls();
+ }
+}
+
+BOOL CSettingsPage::OnSetActive()
+{
+ UpdatePage();
+ return CPropertyPage::OnSetActive();
+}
+
+void CSettingsPage::OnOverrideIntervals()
+{
+ UpdateBrother();
+ if(m_OverrideIntervals)
+ m_IntervalGoodCtl.SetFocus();
+}
+
+void CSettingsPage::OnOverrideRetries()
+{
+ UpdateBrother();
+ if(m_OverrideRetries)
+ m_RetriesCtl.SetFocus();
+}
+
+void CSettingsPage::OnOverrideTimeout()
+{
+ UpdateBrother();
+ if(m_OverrideTimeout)
+ m_TimeOutCtl.SetFocus();
+}
+
+void CSettingsPage::UpdateBrother()
+{
+ if(!m_dad->m_Brother){
+ TRACE0("No brother on update\n");
+ return;
+ }
+ if(::IsWindow(m_hWnd))
+ UpdateData();
+CBrother toCompare;
+ toCompare = *m_dad->m_Brother;
+ m_dad->m_Brother->m_IntervalBad=m_IntervalBad;
+ m_dad->m_Brother->m_IntervalGood=m_IntervalGood;
+ if(m_OverrideIntervals)
+ m_dad->m_Brother->flags|=CBrother::flagsOverrideIntervals;
+ else
+ m_dad->m_Brother->flags&=~CBrother::flagsOverrideIntervals;
+ m_dad->m_Brother->m_Retries=m_Retries;
+ if(m_OverrideRetries)
+ m_dad->m_Brother->flags|=CBrother::flagsOverrideRetries;
+ else
+ m_dad->m_Brother->flags&=~CBrother::flagsOverrideRetries;
+ m_dad->m_Brother->m_TimeOut=m_TimeOut;
+ if(m_OverrideTimeout)
+ m_dad->m_Brother->flags|=CBrother::flagsOverrideTimeout;
+ else
+ m_dad->m_Brother->flags&=~CBrother::flagsOverrideTimeout;
+ m_dad->m_Brother->ParentalAdjust();
+ if(toCompare!=(*m_dad->m_Brother)){
+ CDocument *pDoc = m_dad->m_Daddy->GetDocument();
+ ASSERT(pDoc);
+ pDoc->SetModifiedFlag();
+ }
+ if(::IsWindow(m_hWnd)){
+ UpdateData(FALSE);
+ SetupControls();
+ }
+}
+
+BOOL CSettingsPage::OnKillActive()
+{
+ UpdateBrother();
+ return CPropertyPage::OnKillActive();
+}
diff --git a/SettingsPage.h b/SettingsPage.h
new file mode 100644
index 0000000..c075bde
--- a/dev/null
+++ b/SettingsPage.h
@@ -0,0 +1,61 @@
+// SettingsPage.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CSettingsPage dialog
+
+class CHostPropertyPages;
+class CSettingsPage : public CPropertyPage
+{
+ DECLARE_DYNCREATE(CSettingsPage)
+
+// Construction
+public:
+ void UpdateBrother();
+ void UpdatePage();
+ void SetupControls();
+ CHostPropertyPages* m_dad;
+ CSettingsPage();
+ ~CSettingsPage();
+
+// Dialog Data
+ //{{AFX_DATA(CSettingsPage)
+ enum { IDD = IDD_PROPS_SETTINGS };
+ CEdit m_RetriesCtl;
+ CEdit m_TimeOutCtl;
+ CEdit m_IntervalGoodCtl;
+ CEdit m_IntervalBadCtl;
+ CButton m_OverrideTimeoutCtl;
+ CButton m_OverrideRetriesCtl;
+ CButton m_OverrideIntervalsCtl;
+ BOOL m_OverrideIntervals;
+ BOOL m_OverrideRetries;
+ BOOL m_OverrideTimeout;
+ DWORD m_IntervalBad;
+ DWORD m_IntervalGood;
+ DWORD m_TimeOut;
+ UINT m_Retries;
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generate virtual function overrides
+ //{{AFX_VIRTUAL(CSettingsPage)
+ public:
+ virtual BOOL OnSetActive();
+ virtual BOOL OnKillActive();
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ // Generated message map functions
+ //{{AFX_MSG(CSettingsPage)
+ afx_msg void OnOverrideIntervals();
+ afx_msg void OnOverrideRetries();
+ afx_msg void OnOverrideTimeout();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+
+};
diff --git a/bigbrother.clw b/bigbrother.clw
new file mode 100644
index 0000000..4716ae4
--- a/dev/null
+++ b/bigbrother.clw
@@ -0,0 +1,313 @@
+; CLW file contains information for the MFC ClassWizard
+
+[General Info]
+Version=1
+LastClass=CPreferences
+LastTemplate=CDialog
+NewFileInclude1=#include "stdafx.h"
+NewFileInclude2=#include "BigBrother.h"
+LastPage=0
+
+ClassCount=11
+Class1=CBigBrotherApp
+Class2=CBigBrotherDoc
+Class3=CBigBrotherView
+Class4=CMainFrame
+
+ResourceCount=9
+Resource1=IDD_PREFS
+Resource2=IDD_PROPS_SETTINGS
+Class5=CAboutDlg
+Resource3=IDM_POPUPS
+Class6=CGeneralPage
+Class7=CSettingsPage
+Class8=CHostPropertyPages
+Resource4=IDR_JUNKTOOLBAR
+Class9=CActionPage
+Class10=CActivityView
+Resource5=IDD_PROPS_GENERAL
+Resource6=IDR_JUNKACCELERATOR
+Resource7=IDD_PROPS_ACTION
+Resource8=IDD_ABOUTBOX
+Class11=CPreferences
+Resource9=IDR_MAINFRAME
+
+[CLS:CBigBrotherApp]
+Type=0
+HeaderFile=BigBrother.h
+ImplementationFile=BigBrother.cpp
+Filter=N
+BaseClass=CWinApp
+VirtualFilter=AC
+LastObject=ID_HELP_LEGEND
+
+[CLS:CBigBrotherDoc]
+Type=0
+HeaderFile=BigBrotherDoc.h
+ImplementationFile=BigBrotherDoc.cpp
+Filter=N
+BaseClass=CDocument
+VirtualFilter=DC
+LastObject=ID_VIEW_HOSTPROPERTIES
+
+[CLS:CBigBrotherView]
+Type=0
+HeaderFile=BigBrotherView.h
+ImplementationFile=BigBrotherView.cpp
+Filter=C
+LastObject=CBigBrotherView
+BaseClass=CTreeView
+VirtualFilter=VWC
+
+[CLS:CMainFrame]
+Type=0
+HeaderFile=MainFrm.h
+ImplementationFile=MainFrm.cpp
+Filter=W
+BaseClass=CFrameWnd
+VirtualFilter=fWC
+LastObject=CMainFrame
+
+
+
+[CLS:CAboutDlg]
+Type=0
+HeaderFile=BigBrother.cpp
+ImplementationFile=BigBrother.cpp
+Filter=D
+LastObject=CAboutDlg
+
+[DLG:IDD_ABOUTBOX]
+Type=1
+Class=CAboutDlg
+ControlCount=5
+Control1=IDC_STATIC,static,1342177283
+Control2=IDC_STATIC,static,1342308480
+Control3=IDC_STATIC,static,1342308352
+Control4=IDOK,button,1342373889
+Control5=IDC_KLEVERNET,button,1342242816
+
+[MNU:IDR_MAINFRAME]
+Type=1
+Class=CMainFrame
+Command1=ID_FILE_NEW
+Command2=ID_FILE_OPEN
+Command3=ID_FILE_SAVE
+Command4=ID_FILE_SAVE_AS
+Command5=ID_FILE_AUTOLOAD
+Command6=ID_FILE_PREFERENCES
+Command7=ID_FILE_PAUSE
+Command8=ID_FILE_MRU_FILE1
+Command9=ID_APP_EXIT
+Command10=ID_BROTHERS_NEW
+Command11=ID_BROTHERS_ADDBROTHER
+Command12=ID_BROTHERS_DELETE
+Command13=ID_VIEW_TOOLBAR
+Command14=ID_VIEW_STATUS_BAR
+Command15=ID_WINDOW_SPLIT
+Command16=ID_VIEW_MAINWINDOW
+Command17=ID_VIEW_HOSTPROPERTIES
+Command18=ID_HELP_FINDER
+Command19=ID_HELP_LEGEND
+Command20=ID_APP_ABOUT
+CommandCount=20
+
+[ACL:IDR_MAINFRAME]
+Type=1
+Class=CMainFrame
+Command1=ID_FILE_NEW
+Command2=ID_FILE_OPEN
+Command3=ID_FILE_PREFERENCES
+Command4=ID_FILE_SAVE
+Command5=ID_BROTHERS_DELETE
+Command6=ID_BROTHERS_DELETE
+Command7=ID_HELP
+Command8=ID_CONTEXT_HELP
+Command9=ID_NEXT_PANE
+Command10=ID_PREV_PANE
+Command11=ID_BROTHERS_NEW
+Command12=ID_APP_EXIT
+CommandCount=12
+
+[DLG:IDD_PROPS_SETTINGS]
+Type=1
+Class=CSettingsPage
+ControlCount=10
+Control1=IDC_STATIC,button,1342193671
+Control2=IDC_OVERRIDE_INTERVALS,button,1342242819
+Control3=IDC_STATIC,static,1342308352
+Control4=IDC_PINGINTERVAL_GOOD,edit,1350631552
+Control5=IDC_STATIC,static,1342308352
+Control6=IDC_PINGINTERVAL_BAD,edit,1350631552
+Control7=IDC_OVERRIDE_TIMEOUT,button,1342242819
+Control8=IDC_PINGTIMEOUT,edit,1350631552
+Control9=IDC_OVERRIDE_RETRIES,button,1342242819
+Control10=IDC_RETRIES,edit,1350631552
+
+[TB:IDR_MAINFRAME]
+Type=1
+Command1=ID_FILE_NEW
+Command2=ID_FILE_OPEN
+Command3=ID_FILE_SAVE
+Command4=ID_BROTHERS_NEW
+Command5=ID_BROTHERS_ADDBROTHER
+Command6=ID_BROTHERS_DELETE
+Command7=ID_VIEW_HOSTPROPERTIES
+Command8=ID_FILE_PAUSE
+Command9=ID_APP_ABOUT
+Command10=ID_CONTEXT_HELP
+Command11=ID_HELP_LEGEND
+CommandCount=11
+
+[DLG:IDD_PROPS_GENERAL]
+Type=1
+Class=CGeneralPage
+ControlCount=5
+Control1=IDC_STATIC,static,1342308352
+Control2=IDC_HOST,edit,1350631568
+Control3=IDC_STATIC,static,1342308352
+Control4=IDC_DESC,edit,1350631552
+Control5=IDC_LOG_ACTIVITY,button,1342246918
+
+[CLS:CGeneralPage]
+Type=0
+HeaderFile=GeneralPage.h
+ImplementationFile=GeneralPage.cpp
+BaseClass=CPropertyPage
+Filter=D
+LastObject=CGeneralPage
+VirtualFilter=idWC
+
+[CLS:CSettingsPage]
+Type=0
+HeaderFile=SettingsPage.h
+ImplementationFile=SettingsPage.cpp
+BaseClass=CPropertyPage
+Filter=D
+LastObject=CSettingsPage
+VirtualFilter=idWC
+
+[CLS:CHostPropertyPages]
+Type=0
+HeaderFile=HostPropertyPages.h
+ImplementationFile=HostPropertyPages.cpp
+BaseClass=CPropertySheet
+Filter=W
+LastObject=CHostPropertyPages
+VirtualFilter=hWC
+
+[DLG:IDD_PROPS_ACTION]
+Type=1
+Class=CActionPage
+ControlCount=15
+Control1=IDC_OVERRIDE_ACTION,button,1342246915
+Control2=IDC_STATIC,button,1342177287
+Control3=IDC_PLAYASOUND_DOWN,button,1342242819
+Control4=IDC_SOUND_DOWN,combobox,1344340034
+Control5=IDC_BROWSE_SOUND_DOWN,button,1342263104
+Control6=IDC_PREVIEW_SOUND_DOWN,button,1342263104
+Control7=IDC_CUSTOM_DOWN,button,1342242819
+Control8=IDC_PROGRAM_DOWN,edit,1350631552
+Control9=IDC_STATIC,button,1342177287
+Control10=IDC_PLAYASOUND_UP,button,1342242819
+Control11=IDC_SOUND_UP,combobox,1344340034
+Control12=IDC_BROWSE_SOUND_UP,button,1342263104
+Control13=IDC_PREVIEW_SOUND_UP,button,1342263104
+Control14=IDC_CUSTOM_UP,button,1342242819
+Control15=IDC_PROGRAM_UP,edit,1350631552
+
+[CLS:CActionPage]
+Type=0
+HeaderFile=ActionPage.h
+ImplementationFile=ActionPage.cpp
+BaseClass=CPropertyPage
+Filter=D
+LastObject=CActionPage
+VirtualFilter=idWC
+
+[CLS:CActivityView]
+Type=0
+HeaderFile=ActivityView.h
+ImplementationFile=ActivityView.cpp
+BaseClass=CScrollView
+Filter=C
+LastObject=CActivityView
+VirtualFilter=VWC
+
+[MNU:IDM_POPUPS]
+Type=1
+Command1=ID_VIEW_MAINWINDOW
+Command2=ID_HELP_FINDER
+Command3=ID_APP_ABOUT
+Command4=ID_APP_EXIT
+Command5=ID_INDICATOR_PINGBAR
+Command6=ID_EDIT_UNDO
+Command7=ID_EDIT_CUT
+Command8=ID_EDIT_COPY
+Command9=ID_EDIT_PASTE
+Command10=ID_FILE_PRINT
+Command11=ID_FILE_PRINT_PREVIEW
+Command12=ID_FILE_PRINT_SETUP
+CommandCount=12
+
+[ACL:IDR_JUNKACCELERATOR]
+Type=1
+Command1=ID_EDIT_COPY
+Command2=ID_FILE_PRINT
+Command3=ID_EDIT_PASTE
+Command4=ID_EDIT_UNDO
+Command5=ID_EDIT_CUT
+Command6=ID_EDIT_COPY
+Command7=ID_EDIT_PASTE
+Command8=ID_EDIT_CUT
+Command9=ID_EDIT_UNDO
+CommandCount=9
+
+[TB:IDR_JUNKTOOLBAR]
+Type=1
+Command1=ID_FILE_PRINT
+Command2=ID_EDIT_CUT
+Command3=ID_EDIT_COPY
+Command4=ID_EDIT_PASTE
+CommandCount=4
+
+[DLG:IDD_PREFS]
+Type=1
+Class=CPreferences
+ControlCount=26
+Control1=IDC_STATIC,button,1342177287
+Control2=IDC_SAVEONSHUTDOWN,button,1342268163
+Control3=IDC_STATIC,static,1342308352
+Control4=IDC_AUTOSAVEMINS,edit,1350631552
+Control5=IDC_AUTOSPIN,msctls_updown32,1342177463
+Control6=IDC_STATIC,static,1342308352
+Control7=IDC_STATIC,button,1342177287
+Control8=IDC_STATIC,static,1342308608
+Control9=IDC_PINGSIZE,edit,1350631552
+Control10=IDC_DATASIZESPIN,msctls_updown32,1342177463
+Control11=IDC_STATIC,static,1342308352
+Control12=IDC_STATIC,static,1342308352
+Control13=IDC_MAXTHREADS,edit,1350631552
+Control14=IDC_THREADSPIN,msctls_updown32,1342177463
+Control15=IDC_STATIC,static,1342308352
+Control16=IDC_STATIC,button,1342177287
+Control17=IDC_STATIC,static,1342308352
+Control18=IDC_LOGFILE,edit,1350631552
+Control19=IDC_BROWSE,button,1342263104
+Control20=IDC_STATIC,static,1342308352
+Control21=IDC_LOGMINS,edit,1350631552
+Control22=IDC_LOGMINSPIN,msctls_updown32,1342177463
+Control23=IDC_STATIC,static,1342308608
+Control24=IDOK,button,1342242817
+Control25=IDCANCEL,button,1342242816
+Control26=IDC_STOREACTIVITY,button,1342242819
+
+[CLS:CPreferences]
+Type=0
+HeaderFile=Preferences.h
+ImplementationFile=Preferences.cpp
+BaseClass=CDialog
+Filter=D
+LastObject=CPreferences
+VirtualFilter=dWC
+
diff --git a/bigbrother.cpp b/bigbrother.cpp
new file mode 100644
index 0000000..0036987
--- a/dev/null
+++ b/bigbrother.cpp
@@ -0,0 +1,181 @@
+// BigBrother.cpp : Defines the class behaviors for the application.
+//
+
+#include "stdafx.h"
+#include "BigBrother.h"
+
+#include "MainFrm.h"
+#include "BigBrotherDoc.h"
+#include "BigBrotherView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CBigBrotherApp
+
+BEGIN_MESSAGE_MAP(CBigBrotherApp, CWinApp)
+ //{{AFX_MSG_MAP(CBigBrotherApp)
+ ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
+ ON_UPDATE_COMMAND_UI(ID_FILE_AUTOLOAD, OnUpdateFileAutoload)
+ ON_COMMAND(ID_FILE_AUTOLOAD, OnFileAutoload)
+ ON_COMMAND(ID_HELP_LEGEND, OnHelpLegend)
+ //}}AFX_MSG_MAP
+ // Standard file based document commands
+ ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
+ ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
+ // Standard print setup command
+ ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CBigBrotherApp construction
+
+CBigBrotherApp::CBigBrotherApp()
+{
+ m_bLoadMRUOnStartup=TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// The one and only CBigBrotherApp object
+
+CBigBrotherApp theApp;
+
+/////////////////////////////////////////////////////////////////////////////
+// CBigBrotherApp initialization
+
+BOOL CBigBrotherApp::InitInstance()
+{
+ if (!AfxSocketInit())
+ {
+ AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
+ return FALSE;
+ }
+
+ // Standard initialization
+ // If you are not using these features and wish to reduce the size
+ // of your final executable, you should remove from the following
+ // the specific initialization routines you do not need.
+
+#ifdef _AFXDLL
+ Enable3dControls(); // Call this when using MFC in a shared DLL
+#else
+ Enable3dControlsStatic(); // Call this when linking to MFC statically
+#endif
+
+ SetRegistryKey(IDS_REGISTRYKEY);
+ m_pszHelpFilePath="bigbro.hlp>Default";
+
+ LoadStdProfileSettings(); // Load standard INI file options (including MRU)
+ m_bLoadMRUOnStartup=GetProfileInt("Settings","LoadMRUOnStartup",m_bLoadMRUOnStartup);
+
+ // Register the application's document templates. Document templates
+ // serve as the connection between documents, frame windows and views.
+
+ CSingleDocTemplate* pDocTemplate;
+ pDocTemplate = new CSingleDocTemplate(
+ IDR_MAINFRAME,
+ RUNTIME_CLASS(CBigBrotherDoc),
+ RUNTIME_CLASS(CMainFrame), // main SDI frame window
+ RUNTIME_CLASS(CBigBrotherView));
+ AddDocTemplate(pDocTemplate);
+
+ // Enable DDE Execute open
+ EnableShellOpen();
+ RegisterShellFileTypes(TRUE);
+
+ // Parse command line for standard shell commands, DDE, file open
+ CCommandLineInfo cmdInfo;
+ ParseCommandLine(cmdInfo);
+
+ // Dispatch commands specified on the command line
+ if (!ProcessShellCommand(cmdInfo))
+ return FALSE;
+ if(m_bLoadMRUOnStartup && (cmdInfo.m_nShellCommand==CCommandLineInfo::FileNew))
+ m_pMainWnd->SendMessage(WM_COMMAND,ID_FILE_MRU_FILE1,0);
+
+ // Enable drag/drop open
+ m_pMainWnd->DragAcceptFiles();
+
+ return TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CAboutDlg dialog used for App About
+
+class CAboutDlg : public CDialog
+{
+public:
+ CAboutDlg();
+
+// Dialog Data
+ //{{AFX_DATA(CAboutDlg)
+ enum { IDD = IDD_ABOUTBOX };
+ //}}AFX_DATA
+
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CAboutDlg)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ //{{AFX_MSG(CAboutDlg)
+ // No message handlers
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
+{
+ //{{AFX_DATA_INIT(CAboutDlg)
+ //}}AFX_DATA_INIT
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CAboutDlg)
+ //}}AFX_DATA_MAP
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
+ //{{AFX_MSG_MAP(CAboutDlg)
+ // No message handlers
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+// App command to run the dialog
+void CBigBrotherApp::OnAppAbout()
+{
+ CAboutDlg aboutDlg;
+ aboutDlg.DoModal();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CBigBrotherApp commands
+
+int CBigBrotherApp::ExitInstance()
+{
+ WriteProfileInt("Settings","LoadMRUOnStartup",m_bLoadMRUOnStartup);
+ return CWinApp::ExitInstance();
+}
+
+void CBigBrotherApp::OnUpdateFileAutoload(CCmdUI* pCmdUI)
+{
+ pCmdUI->SetCheck(m_bLoadMRUOnStartup?1:0);
+}
+
+void CBigBrotherApp::OnFileAutoload()
+{
+ m_bLoadMRUOnStartup=!m_bLoadMRUOnStartup;
+}
+
+void CBigBrotherApp::OnHelpLegend()
+{
+ WinHelp(0x10000lu+ID_HELP_LEGEND,HELP_CONTEXTPOPUP);
+}
diff --git a/bigbrother.h b/bigbrother.h
new file mode 100644
index 0000000..1c348dc
--- a/dev/null
+++ b/bigbrother.h
@@ -0,0 +1,41 @@
+// BigBrother.h : main header file for the BIGBROTHER application
+//
+
+#ifndef __AFXWIN_H__
+ #error include 'stdafx.h' before including this file for PCH
+#endif
+
+#include "resource.h" // main symbols
+
+/////////////////////////////////////////////////////////////////////////////
+// CBigBrotherApp:
+// See BigBrother.cpp for the implementation of this class
+//
+
+class CBigBrotherApp : public CWinApp
+{
+public:
+ BOOL m_bLoadMRUOnStartup;
+ CBigBrotherApp();
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CBigBrotherApp)
+ public:
+ virtual BOOL InitInstance();
+ virtual int ExitInstance();
+ //}}AFX_VIRTUAL
+
+// Implementation
+
+ //{{AFX_MSG(CBigBrotherApp)
+ afx_msg void OnAppAbout();
+ afx_msg void OnUpdateFileAutoload(CCmdUI* pCmdUI);
+ afx_msg void OnFileAutoload();
+ afx_msg void OnHelpLegend();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/bigbrother.mak b/bigbrother.mak
new file mode 100644
index 0000000..a5fc893
--- a/dev/null
+++ b/bigbrother.mak
@@ -0,0 +1,1451 @@
+# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+!IF "$(CFG)" == ""
+CFG=install - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to install - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "Big Brother - Win32 Release" && "$(CFG)" !=\
+ "Big Brother - Win32 Debug" && "$(CFG)" != "Big Brother - Win32 Release Static"\
+ && "$(CFG)" != "install - Win32 Debug" && "$(CFG)" != "install - Win32 Pure" &&\
+ "$(CFG)" != "install - Win32 Canned" && "$(CFG)" != "install - Win32 Static"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE on this makefile
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "bigbrother.mak" CFG="install - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Big Brother - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "Big Brother - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE "Big Brother - Win32 Release Static" (based on\
+ "Win32 (x86) Application")
+!MESSAGE "install - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE "install - Win32 Pure" (based on "Win32 (x86) Application")
+!MESSAGE "install - Win32 Canned" (based on "Win32 (x86) Application")
+!MESSAGE "install - Win32 Static" (based on "Win32 (x86) Application")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+################################################################################
+# Begin Project
+# PROP Target_Last_Scanned "install - Win32 Static"
+RSC=rc.exe
+MTL=mktyplib.exe
+CPP=cl.exe
+
+!IF "$(CFG)" == "Big Brother - Win32 Release"
+
+# PROP BASE Use_MFC 6
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 6
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+OUTDIR=.\Release
+INTDIR=.\Release
+# Begin Custom Macros
+OutDir=.\Release
+TargetName=BigBro
+# End Custom Macros
+
+ALL : "$(OUTDIR)\BigBro.exe" "$(OUTDIR)\BigBro.ex_" "$(OUTDIR)\BigBro.hlp"\
+ "$(OUTDIR)\BigBro.cnt" "$(OUTDIR)\BigBro.hl_" "$(OUTDIR)\BigBro.cn_"
+
+CLEAN :
+ -@erase "$(INTDIR)\ActionPage.obj"
+ -@erase "$(INTDIR)\ActivityView.obj"
+ -@erase "$(INTDIR)\BigBro.cn_"
+ -@erase "$(INTDIR)\BigBro.cnt"
+ -@erase "$(INTDIR)\BigBro.hl_"
+ -@erase "$(INTDIR)\BigBro.hlp"
+ -@erase "$(INTDIR)\BigBrother.obj"
+ -@erase "$(INTDIR)\bigbrother.pch"
+ -@erase "$(INTDIR)\bigbrother.res"
+ -@erase "$(INTDIR)\BigBrotherDoc.obj"
+ -@erase "$(INTDIR)\BigBrotherView.obj"
+ -@erase "$(INTDIR)\GeneralPage.obj"
+ -@erase "$(INTDIR)\HostPropertyPages.obj"
+ -@erase "$(INTDIR)\kICMP.obj"
+ -@erase "$(INTDIR)\MainFrm.obj"
+ -@erase "$(INTDIR)\Preferences.obj"
+ -@erase "$(INTDIR)\SettingsPage.obj"
+ -@erase "$(INTDIR)\StdAfx.obj"
+ -@erase "$(OUTDIR)\BigBro.ex_"
+ -@erase "$(OUTDIR)\BigBro.exe"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /c
+# ADD CPP /nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /c
+CPP_PROJ=/nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D\
+ "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)/bigbrother.pch" /Yu"stdafx.h"\
+ /Fo"$(INTDIR)/" /c
+CPP_OBJS=.\Release/
+CPP_SBRS=.\.
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /win32
+MTL_PROJ=/nologo /D "NDEBUG" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
+# ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)/bigbrother.res" /d "NDEBUG" /d "_AFXDLL"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/bigbrother.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
+# ADD LINK32 /nologo /subsystem:windows /machine:I386 /out:"Release/BigBro.exe"
+LINK32_FLAGS=/nologo /subsystem:windows /incremental:no\
+ /pdb:"$(OUTDIR)/BigBro.pdb" /machine:I386 /out:"$(OUTDIR)/BigBro.exe"
+LINK32_OBJS= \
+ "$(INTDIR)\ActionPage.obj" \
+ "$(INTDIR)\ActivityView.obj" \
+ "$(INTDIR)\BigBrother.obj" \
+ "$(INTDIR)\bigbrother.res" \
+ "$(INTDIR)\BigBrotherDoc.obj" \
+ "$(INTDIR)\BigBrotherView.obj" \
+ "$(INTDIR)\GeneralPage.obj" \
+ "$(INTDIR)\HostPropertyPages.obj" \
+ "$(INTDIR)\kICMP.obj" \
+ "$(INTDIR)\MainFrm.obj" \
+ "$(INTDIR)\Preferences.obj" \
+ "$(INTDIR)\SettingsPage.obj" \
+ "$(INTDIR)\StdAfx.obj"
+
+"$(OUTDIR)\BigBro.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+# Begin Custom Build
+OutDir=.\Release
+TargetName=BigBro
+InputPath=.\Release\BigBro.exe
+SOURCE=$(InputPath)
+
+"$(OutDir)\$(TargetName).ex_" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ compress $(OutDir)\$(TargetName).exe $(OutDir)\$(TargetName).ex_
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Debug"
+
+# PROP BASE Use_MFC 6
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 6
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+OUTDIR=.\Debug
+INTDIR=.\Debug
+# Begin Custom Macros
+OutDir=.\Debug
+TargetName=BigBro
+# End Custom Macros
+
+ALL : "$(OUTDIR)\BigBro.exe" "$(OUTDIR)\bigbrother.bsc" "$(OUTDIR)\BigBro.hlp"\
+ "$(OUTDIR)\BigBro.cnt" "$(OUTDIR)\BigBro.hl_" "$(OUTDIR)\BigBro.cn_"\
+ "$(OUTDIR)\bigbro.ex_"
+
+CLEAN :
+ -@erase "$(INTDIR)\ActionPage.obj"
+ -@erase "$(INTDIR)\ActionPage.sbr"
+ -@erase "$(INTDIR)\ActivityView.obj"
+ -@erase "$(INTDIR)\ActivityView.sbr"
+ -@erase "$(INTDIR)\BigBro.cn_"
+ -@erase "$(INTDIR)\BigBro.cnt"
+ -@erase "$(INTDIR)\BigBro.hl_"
+ -@erase "$(INTDIR)\BigBro.hlp"
+ -@erase "$(INTDIR)\BigBrother.obj"
+ -@erase "$(INTDIR)\bigbrother.pch"
+ -@erase "$(INTDIR)\bigbrother.res"
+ -@erase "$(INTDIR)\BigBrother.sbr"
+ -@erase "$(INTDIR)\BigBrotherDoc.obj"
+ -@erase "$(INTDIR)\BigBrotherDoc.sbr"
+ -@erase "$(INTDIR)\BigBrotherView.obj"
+ -@erase "$(INTDIR)\BigBrotherView.sbr"
+ -@erase "$(INTDIR)\GeneralPage.obj"
+ -@erase "$(INTDIR)\GeneralPage.sbr"
+ -@erase "$(INTDIR)\HostPropertyPages.obj"
+ -@erase "$(INTDIR)\HostPropertyPages.sbr"
+ -@erase "$(INTDIR)\kICMP.obj"
+ -@erase "$(INTDIR)\kICMP.sbr"
+ -@erase "$(INTDIR)\MainFrm.obj"
+ -@erase "$(INTDIR)\MainFrm.sbr"
+ -@erase "$(INTDIR)\Preferences.obj"
+ -@erase "$(INTDIR)\Preferences.sbr"
+ -@erase "$(INTDIR)\SettingsPage.obj"
+ -@erase "$(INTDIR)\SettingsPage.sbr"
+ -@erase "$(INTDIR)\StdAfx.obj"
+ -@erase "$(INTDIR)\StdAfx.sbr"
+ -@erase "$(INTDIR)\vc40.idb"
+ -@erase "$(INTDIR)\vc40.pdb"
+ -@erase "$(OUTDIR)\bigbro.ex_"
+ -@erase "$(OUTDIR)\BigBro.exe"
+ -@erase "$(OUTDIR)\BigBro.ilk"
+ -@erase "$(OUTDIR)\BigBro.pdb"
+ -@erase "$(OUTDIR)\bigbrother.bsc"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /Yu"stdafx.h" /c
+CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\
+ /D "_AFXDLL" /D "_MBCS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/bigbrother.pch"\
+ /Yu"stdafx.h" /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c
+CPP_OBJS=.\Debug/
+CPP_SBRS=.\Debug/
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /win32
+MTL_PROJ=/nologo /D "_DEBUG" /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
+# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)/bigbrother.res" /d "_DEBUG" /d "_AFXDLL"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/bigbrother.bsc"
+BSC32_SBRS= \
+ "$(INTDIR)\ActionPage.sbr" \
+ "$(INTDIR)\ActivityView.sbr" \
+ "$(INTDIR)\BigBrother.sbr" \
+ "$(INTDIR)\BigBrotherDoc.sbr" \
+ "$(INTDIR)\BigBrotherView.sbr" \
+ "$(INTDIR)\GeneralPage.sbr" \
+ "$(INTDIR)\HostPropertyPages.sbr" \
+ "$(INTDIR)\kICMP.sbr" \
+ "$(INTDIR)\MainFrm.sbr" \
+ "$(INTDIR)\Preferences.sbr" \
+ "$(INTDIR)\SettingsPage.sbr" \
+ "$(INTDIR)\StdAfx.sbr"
+
+"$(OUTDIR)\bigbrother.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386
+# ADD LINK32 /nologo /subsystem:windows /debug /machine:I386 /out:"Debug/BigBro.exe"
+LINK32_FLAGS=/nologo /subsystem:windows /incremental:yes\
+ /pdb:"$(OUTDIR)/BigBro.pdb" /debug /machine:I386 /out:"$(OUTDIR)/BigBro.exe"
+LINK32_OBJS= \
+ "$(INTDIR)\ActionPage.obj" \
+ "$(INTDIR)\ActivityView.obj" \
+ "$(INTDIR)\BigBrother.obj" \
+ "$(INTDIR)\bigbrother.res" \
+ "$(INTDIR)\BigBrotherDoc.obj" \
+ "$(INTDIR)\BigBrotherView.obj" \
+ "$(INTDIR)\GeneralPage.obj" \
+ "$(INTDIR)\HostPropertyPages.obj" \
+ "$(INTDIR)\kICMP.obj" \
+ "$(INTDIR)\MainFrm.obj" \
+ "$(INTDIR)\Preferences.obj" \
+ "$(INTDIR)\SettingsPage.obj" \
+ "$(INTDIR)\StdAfx.obj"
+
+"$(OUTDIR)\BigBro.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+# Begin Custom Build
+OutDir=.\Debug
+TargetName=BigBro
+InputPath=.\Debug\BigBro.exe
+SOURCE=$(InputPath)
+
+"$(OutDir)\$(TargetName).ex_" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ compress $(OutDir)\$(TargetName).exe $(OutDir)\$(TargetName).ex_
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Release Static"
+
+# PROP BASE Use_MFC 6
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "BigBroth"
+# PROP BASE Intermediate_Dir "BigBroth"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 5
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Releast"
+# PROP Intermediate_Dir "Releast"
+# PROP Target_Dir ""
+OUTDIR=.\Releast
+INTDIR=.\Releast
+# Begin Custom Macros
+OutDir=.\Releast
+TargetName=BigBro
+# End Custom Macros
+
+ALL : "$(OUTDIR)\BigBro.exe" "$(OUTDIR)\BigBro.hlp" "$(OUTDIR)\BigBro.cnt"\
+ "$(OUTDIR)\BigBro.hl_" "$(OUTDIR)\BigBro.cn_" "$(OUTDIR)\bigbro.ex_"
+
+CLEAN :
+ -@erase "$(INTDIR)\ActionPage.obj"
+ -@erase "$(INTDIR)\ActivityView.obj"
+ -@erase "$(INTDIR)\BigBro.cn_"
+ -@erase "$(INTDIR)\BigBro.cnt"
+ -@erase "$(INTDIR)\BigBro.hl_"
+ -@erase "$(INTDIR)\BigBro.hlp"
+ -@erase "$(INTDIR)\BigBrother.obj"
+ -@erase "$(INTDIR)\bigbrother.pch"
+ -@erase "$(INTDIR)\bigbrother.res"
+ -@erase "$(INTDIR)\BigBrotherDoc.obj"
+ -@erase "$(INTDIR)\BigBrotherView.obj"
+ -@erase "$(INTDIR)\GeneralPage.obj"
+ -@erase "$(INTDIR)\HostPropertyPages.obj"
+ -@erase "$(INTDIR)\kICMP.obj"
+ -@erase "$(INTDIR)\MainFrm.obj"
+ -@erase "$(INTDIR)\Preferences.obj"
+ -@erase "$(INTDIR)\SettingsPage.obj"
+ -@erase "$(INTDIR)\StdAfx.obj"
+ -@erase "$(OUTDIR)\bigbro.ex_"
+ -@erase "$(OUTDIR)\BigBro.exe"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+# ADD BASE CPP /nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /c
+# ADD CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /c
+CPP_PROJ=/nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D\
+ "_MBCS" /Fp"$(INTDIR)/bigbrother.pch" /Yu"stdafx.h" /Fo"$(INTDIR)/" /c
+CPP_OBJS=.\Releast/
+CPP_SBRS=.\.
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /win32
+MTL_PROJ=/nologo /D "NDEBUG" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
+# ADD RSC /l 0x409 /d "NDEBUG"
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)/bigbrother.res" /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/bigbrother.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
+# ADD LINK32 /nologo /subsystem:windows /machine:I386 /out:"Releast/BigBro.exe"
+LINK32_FLAGS=/nologo /subsystem:windows /incremental:no\
+ /pdb:"$(OUTDIR)/BigBro.pdb" /machine:I386 /out:"$(OUTDIR)/BigBro.exe"
+LINK32_OBJS= \
+ "$(INTDIR)\ActionPage.obj" \
+ "$(INTDIR)\ActivityView.obj" \
+ "$(INTDIR)\BigBrother.obj" \
+ "$(INTDIR)\bigbrother.res" \
+ "$(INTDIR)\BigBrotherDoc.obj" \
+ "$(INTDIR)\BigBrotherView.obj" \
+ "$(INTDIR)\GeneralPage.obj" \
+ "$(INTDIR)\HostPropertyPages.obj" \
+ "$(INTDIR)\kICMP.obj" \
+ "$(INTDIR)\MainFrm.obj" \
+ "$(INTDIR)\Preferences.obj" \
+ "$(INTDIR)\SettingsPage.obj" \
+ "$(INTDIR)\StdAfx.obj"
+
+"$(OUTDIR)\BigBro.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+# Begin Custom Build
+OutDir=.\Releast
+TargetName=BigBro
+InputPath=.\Releast\BigBro.exe
+SOURCE=$(InputPath)
+
+"$(OutDir)\$(TargetName).ex_" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ compress $(OutDir)\$(TargetName).exe $(OutDir)\$(TargetName).ex_
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "install - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "install\Debug"
+# PROP BASE Intermediate_Dir "install\Debug"
+# PROP BASE Target_Dir "install"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "install\Debug"
+# PROP Intermediate_Dir "install\Debug"
+# PROP Target_Dir "install"
+OUTDIR=.\install\Debug
+INTDIR=.\install\Debug
+
+ALL : "$(OUTDIR)\install.exe"
+
+CLEAN :
+ -@erase "$(INTDIR)\install.obj"
+ -@erase "$(INTDIR)\install.res"
+ -@erase "$(INTDIR)\vc40.idb"
+ -@erase "$(INTDIR)\vc40.pdb"
+ -@erase "$(OUTDIR)\install.exe"
+ -@erase "$(OUTDIR)\install.ilk"
+ -@erase "$(OUTDIR)\install.pdb"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
+CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\
+ /Fp"$(INTDIR)/install.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c
+CPP_OBJS=.\install\Debug/
+CPP_SBRS=.\.
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /win32
+MTL_PROJ=/nologo /D "_DEBUG" /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)/install.res" /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/install.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib version.lib /nologo /subsystem:windows /debug /machine:I386
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
+ odbccp32.lib version.lib /nologo /subsystem:windows /incremental:yes\
+ /pdb:"$(OUTDIR)/install.pdb" /debug /machine:I386 /out:"$(OUTDIR)/install.exe"
+LINK32_OBJS= \
+ "$(INTDIR)\install.obj" \
+ "$(INTDIR)\install.res"
+
+"$(OUTDIR)\install.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "install - Win32 Pure"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "install\Pure"
+# PROP BASE Intermediate_Dir "install\Pure"
+# PROP BASE Target_Dir "install"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "install\Pure"
+# PROP Intermediate_Dir "install\Pure"
+# PROP Target_Dir "install"
+OUTDIR=.\install\Pure
+INTDIR=.\install\Pure
+
+ALL : "$(OUTDIR)\install.exe"
+
+CLEAN :
+ -@erase "$(INTDIR)\install.obj"
+ -@erase "$(INTDIR)\install.res"
+ -@erase "$(OUTDIR)\install.exe"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
+CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\
+ /Fp"$(INTDIR)/install.pch" /YX /Fo"$(INTDIR)/" /c
+CPP_OBJS=.\install\Pure/
+CPP_SBRS=.\.
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /win32
+MTL_PROJ=/nologo /D "NDEBUG" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)/install.res" /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/install.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib version.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib version.lib /nologo /subsystem:windows /machine:I386
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
+ odbccp32.lib version.lib /nologo /subsystem:windows /incremental:no\
+ /pdb:"$(OUTDIR)/install.pdb" /machine:I386 /out:"$(OUTDIR)/install.exe"
+LINK32_OBJS= \
+ "$(INTDIR)\install.obj" \
+ "$(INTDIR)\install.res"
+
+"$(OUTDIR)\install.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "install - Win32 Canned"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "install\Canned"
+# PROP BASE Intermediate_Dir "install\Canned"
+# PROP BASE Target_Dir "install"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "install\Canned"
+# PROP Intermediate_Dir "install\Canned"
+# PROP Target_Dir "install"
+OUTDIR=.\install\Canned
+INTDIR=.\install\Canned
+
+ALL : "$(OUTDIR)\install.exe"
+
+CLEAN :
+ -@erase "$(INTDIR)\install.obj"
+ -@erase "$(INTDIR)\install.res"
+ -@erase "$(OUTDIR)\install.exe"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "K_ANNED" /YX /c
+CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D\
+ "K_ANNED" /Fp"$(INTDIR)/install.pch" /YX /Fo"$(INTDIR)/" /c
+CPP_OBJS=.\install\Canned/
+CPP_SBRS=.\.
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /win32
+MTL_PROJ=/nologo /D "NDEBUG" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG" /d "K_ANNED"
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)/install.res" /d "NDEBUG" /d "K_ANNED"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/install.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib version.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib version.lib /nologo /subsystem:windows /machine:I386
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
+ odbccp32.lib version.lib /nologo /subsystem:windows /incremental:no\
+ /pdb:"$(OUTDIR)/install.pdb" /machine:I386 /out:"$(OUTDIR)/install.exe"
+LINK32_OBJS= \
+ "$(INTDIR)\install.obj" \
+ "$(INTDIR)\install.res"
+
+"$(OUTDIR)\install.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "install - Win32 Static"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "install\Static"
+# PROP BASE Intermediate_Dir "install\Static"
+# PROP BASE Target_Dir "install"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "install\Static"
+# PROP Intermediate_Dir "install\Static"
+# PROP Target_Dir "install"
+OUTDIR=.\install\Static
+INTDIR=.\install\Static
+
+ALL : "$(OUTDIR)\install.exe"
+
+CLEAN :
+ -@erase "$(INTDIR)\install.obj"
+ -@erase "$(INTDIR)\install.res"
+ -@erase "$(OUTDIR)\install.exe"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "STATI_K" /YX /c
+CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D\
+ "STATI_K" /Fp"$(INTDIR)/install.pch" /YX /Fo"$(INTDIR)/" /c
+CPP_OBJS=.\install\Static/
+CPP_SBRS=.\.
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /win32
+MTL_PROJ=/nologo /D "NDEBUG" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG" /d "STATI_K"
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)/install.res" /d "NDEBUG" /d "STATI_K"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/install.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib version.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib version.lib /nologo /subsystem:windows /machine:I386
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
+ odbccp32.lib version.lib /nologo /subsystem:windows /incremental:no\
+ /pdb:"$(OUTDIR)/install.pdb" /machine:I386 /out:"$(OUTDIR)/install.exe"
+LINK32_OBJS= \
+ "$(INTDIR)\install.obj" \
+ "$(INTDIR)\install.res"
+
+"$(OUTDIR)\install.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ENDIF
+
+.c{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cpp{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cxx{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.c{$(CPP_SBRS)}.sbr:
+ $(CPP) $(CPP_PROJ) $<
+
+.cpp{$(CPP_SBRS)}.sbr:
+ $(CPP) $(CPP_PROJ) $<
+
+.cxx{$(CPP_SBRS)}.sbr:
+ $(CPP) $(CPP_PROJ) $<
+
+################################################################################
+# Begin Target
+
+# Name "Big Brother - Win32 Release"
+# Name "Big Brother - Win32 Debug"
+# Name "Big Brother - Win32 Release Static"
+
+!IF "$(CFG)" == "Big Brother - Win32 Release"
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Release Static"
+
+!ENDIF
+
+################################################################################
+# Begin Source File
+
+SOURCE=.\BigBrother.cpp
+DEP_CPP_BIGBR=\
+ ".\bigbrother.h"\
+ ".\BigBrotherDoc.h"\
+ ".\BigBrotherView.h"\
+ ".\MainFrm.h"\
+ ".\shared-code\ip_icmp.h"\
+ ".\shared-code\kICMP.h"\
+ ".\shared-code\ms_icmp.h"\
+ ".\stdafx.h"\
+
+
+!IF "$(CFG)" == "Big Brother - Win32 Release"
+
+
+"$(INTDIR)\BigBrother.obj" : $(SOURCE) $(DEP_CPP_BIGBR) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Debug"
+
+
+"$(INTDIR)\BigBrother.obj" : $(SOURCE) $(DEP_CPP_BIGBR) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+"$(INTDIR)\BigBrother.sbr" : $(SOURCE) $(DEP_CPP_BIGBR) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Release Static"
+
+
+"$(INTDIR)\BigBrother.obj" : $(SOURCE) $(DEP_CPP_BIGBR) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ENDIF
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+DEP_CPP_STDAF=\
+ ".\shared-code\ip_icmp.h"\
+ ".\shared-code\kICMP.h"\
+ ".\shared-code\ms_icmp.h"\
+ ".\stdafx.h"\
+
+
+!IF "$(CFG)" == "Big Brother - Win32 Release"
+
+# ADD CPP /Yc"stdafx.h"
+
+BuildCmds= \
+ $(CPP) /nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D\
+ "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)/bigbrother.pch" /Yc"stdafx.h"\
+ /Fo"$(INTDIR)/" /c $(SOURCE) \
+
+
+"$(INTDIR)\StdAfx.obj" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)"
+ $(BuildCmds)
+
+"$(INTDIR)\bigbrother.pch" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)"
+ $(BuildCmds)
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Debug"
+
+# ADD CPP /Yc"stdafx.h"
+
+BuildCmds= \
+ $(CPP) /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\
+ /D "_AFXDLL" /D "_MBCS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/bigbrother.pch"\
+ /Yc"stdafx.h" /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \
+
+
+"$(INTDIR)\StdAfx.obj" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)"
+ $(BuildCmds)
+
+"$(INTDIR)\StdAfx.sbr" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)"
+ $(BuildCmds)
+
+"$(INTDIR)\bigbrother.pch" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)"
+ $(BuildCmds)
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Release Static"
+
+# ADD BASE CPP /Yc"stdafx.h"
+# ADD CPP /Yc"stdafx.h"
+
+BuildCmds= \
+ $(CPP) /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS"\
+ /Fp"$(INTDIR)/bigbrother.pch" /Yc"stdafx.h" /Fo"$(INTDIR)/" /c $(SOURCE) \
+
+
+"$(INTDIR)\StdAfx.obj" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)"
+ $(BuildCmds)
+
+"$(INTDIR)\bigbrother.pch" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)"
+ $(BuildCmds)
+
+!ENDIF
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\MainFrm.cpp
+DEP_CPP_MAINF=\
+ ".\ActivityView.h"\
+ ".\bigbrother.h"\
+ ".\BigBrotherDoc.h"\
+ ".\BigBrotherView.h"\
+ ".\HostPropertyPages.h"\
+ ".\MainFrm.h"\
+ ".\shared-code\ip_icmp.h"\
+ ".\shared-code\kICMP.h"\
+ ".\shared-code\ms_icmp.h"\
+ ".\stdafx.h"\
+
+
+!IF "$(CFG)" == "Big Brother - Win32 Release"
+
+
+"$(INTDIR)\MainFrm.obj" : $(SOURCE) $(DEP_CPP_MAINF) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Debug"
+
+
+"$(INTDIR)\MainFrm.obj" : $(SOURCE) $(DEP_CPP_MAINF) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+"$(INTDIR)\MainFrm.sbr" : $(SOURCE) $(DEP_CPP_MAINF) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Release Static"
+
+
+"$(INTDIR)\MainFrm.obj" : $(SOURCE) $(DEP_CPP_MAINF) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ENDIF
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\BigBrotherDoc.cpp
+DEP_CPP_BIGBRO=\
+ ".\ActivityView.h"\
+ ".\bigbrother.h"\
+ ".\BigBrotherDoc.h"\
+ ".\BigBrotherView.h"\
+ ".\HostPropertyPages.h"\
+ ".\MainFrm.h"\
+ ".\Preferences.h"\
+ ".\shared-code\ip_icmp.h"\
+ ".\shared-code\kICMP.h"\
+ ".\shared-code\ms_icmp.h"\
+ ".\stdafx.h"\
+
+
+!IF "$(CFG)" == "Big Brother - Win32 Release"
+
+
+"$(INTDIR)\BigBrotherDoc.obj" : $(SOURCE) $(DEP_CPP_BIGBRO) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Debug"
+
+
+"$(INTDIR)\BigBrotherDoc.obj" : $(SOURCE) $(DEP_CPP_BIGBRO) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+"$(INTDIR)\BigBrotherDoc.sbr" : $(SOURCE) $(DEP_CPP_BIGBRO) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Release Static"
+
+
+"$(INTDIR)\BigBrotherDoc.obj" : $(SOURCE) $(DEP_CPP_BIGBRO) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ENDIF
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\BigBrotherView.cpp
+DEP_CPP_BIGBROT=\
+ ".\bigbrother.h"\
+ ".\BigBrotherDoc.h"\
+ ".\BigBrotherView.h"\
+ ".\HostPropertyPages.h"\
+ ".\MainFrm.h"\
+ ".\shared-code\ip_icmp.h"\
+ ".\shared-code\kICMP.h"\
+ ".\shared-code\ms_icmp.h"\
+ ".\stdafx.h"\
+
+
+!IF "$(CFG)" == "Big Brother - Win32 Release"
+
+
+"$(INTDIR)\BigBrotherView.obj" : $(SOURCE) $(DEP_CPP_BIGBROT) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Debug"
+
+
+"$(INTDIR)\BigBrotherView.obj" : $(SOURCE) $(DEP_CPP_BIGBROT) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+"$(INTDIR)\BigBrotherView.sbr" : $(SOURCE) $(DEP_CPP_BIGBROT) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Release Static"
+
+
+"$(INTDIR)\BigBrotherView.obj" : $(SOURCE) $(DEP_CPP_BIGBROT) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ENDIF
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\bigbrother.rc
+DEP_RSC_BIGBROTH=\
+ ".\res\3angle.avi"\
+ ".\res\bigbrother.ico"\
+ ".\res\bigbrother.rc2"\
+ ".\res\BigBrotherDoc.ico"\
+ ".\res\goingdown.ico"\
+ ".\res\host-down.wav"\
+ ".\res\host-up.wav"\
+ ".\res\host.ico"\
+ ".\res\hostdown.ico"\
+ ".\res\junktoolbar.bmp"\
+ ".\res\maintoolbar.bmp"\
+ ".\res\nohost.ico"\
+ ".\res\pending.ico"\
+ ".\res\pinging.ico"\
+ ".\shared-data\browse-icon.ico"\
+ ".\shared-data\play-icon.ico"\
+
+
+!IF "$(CFG)" == "Big Brother - Win32 Release"
+
+
+"$(INTDIR)\bigbrother.res" : $(SOURCE) $(DEP_RSC_BIGBROTH) "$(INTDIR)"
+ $(RSC) $(RSC_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Debug"
+
+
+"$(INTDIR)\bigbrother.res" : $(SOURCE) $(DEP_RSC_BIGBROTH) "$(INTDIR)"
+ $(RSC) $(RSC_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Release Static"
+
+
+"$(INTDIR)\bigbrother.res" : $(SOURCE) $(DEP_RSC_BIGBROTH) "$(INTDIR)"
+ $(RSC) $(RSC_PROJ) $(SOURCE)
+
+
+!ENDIF
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\GeneralPage.cpp
+DEP_CPP_GENER=\
+ ".\bigbrother.h"\
+ ".\BigBrotherDoc.h"\
+ ".\BigBrotherView.h"\
+ ".\GeneralPage.h"\
+ ".\HostPropertyPages.h"\
+ ".\shared-code\ip_icmp.h"\
+ ".\shared-code\kICMP.h"\
+ ".\shared-code\ms_icmp.h"\
+ ".\stdafx.h"\
+
+
+!IF "$(CFG)" == "Big Brother - Win32 Release"
+
+
+"$(INTDIR)\GeneralPage.obj" : $(SOURCE) $(DEP_CPP_GENER) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Debug"
+
+
+"$(INTDIR)\GeneralPage.obj" : $(SOURCE) $(DEP_CPP_GENER) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+"$(INTDIR)\GeneralPage.sbr" : $(SOURCE) $(DEP_CPP_GENER) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Release Static"
+
+
+"$(INTDIR)\GeneralPage.obj" : $(SOURCE) $(DEP_CPP_GENER) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ENDIF
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\SettingsPage.cpp
+DEP_CPP_SETTI=\
+ ".\bigbrother.h"\
+ ".\BigBrotherDoc.h"\
+ ".\BigBrotherView.h"\
+ ".\HostPropertyPages.h"\
+ ".\SettingsPage.h"\
+ ".\shared-code\ip_icmp.h"\
+ ".\shared-code\kICMP.h"\
+ ".\shared-code\ms_icmp.h"\
+ ".\stdafx.h"\
+
+
+!IF "$(CFG)" == "Big Brother - Win32 Release"
+
+
+"$(INTDIR)\SettingsPage.obj" : $(SOURCE) $(DEP_CPP_SETTI) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Debug"
+
+
+"$(INTDIR)\SettingsPage.obj" : $(SOURCE) $(DEP_CPP_SETTI) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+"$(INTDIR)\SettingsPage.sbr" : $(SOURCE) $(DEP_CPP_SETTI) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Release Static"
+
+
+"$(INTDIR)\SettingsPage.obj" : $(SOURCE) $(DEP_CPP_SETTI) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ENDIF
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\HostPropertyPages.cpp
+DEP_CPP_HOSTP=\
+ ".\ActionPage.h"\
+ ".\bigbrother.h"\
+ ".\BigBrotherDoc.h"\
+ ".\BigBrotherView.h"\
+ ".\GeneralPage.h"\
+ ".\HostPropertyPages.h"\
+ ".\SettingsPage.h"\
+ ".\shared-code\ip_icmp.h"\
+ ".\shared-code\kICMP.h"\
+ ".\shared-code\ms_icmp.h"\
+ ".\stdafx.h"\
+
+
+!IF "$(CFG)" == "Big Brother - Win32 Release"
+
+
+"$(INTDIR)\HostPropertyPages.obj" : $(SOURCE) $(DEP_CPP_HOSTP) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Debug"
+
+
+"$(INTDIR)\HostPropertyPages.obj" : $(SOURCE) $(DEP_CPP_HOSTP) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+"$(INTDIR)\HostPropertyPages.sbr" : $(SOURCE) $(DEP_CPP_HOSTP) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Release Static"
+
+
+"$(INTDIR)\HostPropertyPages.obj" : $(SOURCE) $(DEP_CPP_HOSTP) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ENDIF
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\ActionPage.cpp
+DEP_CPP_ACTIO=\
+ ".\ActionPage.h"\
+ ".\bigbrother.h"\
+ ".\BigBrotherDoc.h"\
+ ".\BigBrotherView.h"\
+ ".\HostPropertyPages.h"\
+ ".\shared-code\ip_icmp.h"\
+ ".\shared-code\kICMP.h"\
+ ".\shared-code\ms_icmp.h"\
+ ".\stdafx.h"\
+
+
+!IF "$(CFG)" == "Big Brother - Win32 Release"
+
+
+"$(INTDIR)\ActionPage.obj" : $(SOURCE) $(DEP_CPP_ACTIO) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Debug"
+
+
+"$(INTDIR)\ActionPage.obj" : $(SOURCE) $(DEP_CPP_ACTIO) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+"$(INTDIR)\ActionPage.sbr" : $(SOURCE) $(DEP_CPP_ACTIO) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Release Static"
+
+
+"$(INTDIR)\ActionPage.obj" : $(SOURCE) $(DEP_CPP_ACTIO) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ENDIF
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\ActivityView.cpp
+DEP_CPP_ACTIV=\
+ ".\ActivityView.h"\
+ ".\bigbrother.h"\
+ ".\BigBrotherDoc.h"\
+ ".\shared-code\ip_icmp.h"\
+ ".\shared-code\kICMP.h"\
+ ".\shared-code\ms_icmp.h"\
+ ".\stdafx.h"\
+
+
+!IF "$(CFG)" == "Big Brother - Win32 Release"
+
+
+"$(INTDIR)\ActivityView.obj" : $(SOURCE) $(DEP_CPP_ACTIV) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Debug"
+
+
+"$(INTDIR)\ActivityView.obj" : $(SOURCE) $(DEP_CPP_ACTIV) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+"$(INTDIR)\ActivityView.sbr" : $(SOURCE) $(DEP_CPP_ACTIV) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Release Static"
+
+
+"$(INTDIR)\ActivityView.obj" : $(SOURCE) $(DEP_CPP_ACTIV) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ENDIF
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\Preferences.cpp
+DEP_CPP_PREFE=\
+ ".\bigbrother.h"\
+ ".\Preferences.h"\
+ ".\shared-code\ip_icmp.h"\
+ ".\shared-code\kICMP.h"\
+ ".\shared-code\ms_icmp.h"\
+ ".\stdafx.h"\
+
+
+!IF "$(CFG)" == "Big Brother - Win32 Release"
+
+
+"$(INTDIR)\Preferences.obj" : $(SOURCE) $(DEP_CPP_PREFE) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Debug"
+
+
+"$(INTDIR)\Preferences.obj" : $(SOURCE) $(DEP_CPP_PREFE) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+"$(INTDIR)\Preferences.sbr" : $(SOURCE) $(DEP_CPP_PREFE) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Release Static"
+
+
+"$(INTDIR)\Preferences.obj" : $(SOURCE) $(DEP_CPP_PREFE) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+
+
+!ENDIF
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\help\bigbrother.hpj
+
+!IF "$(CFG)" == "Big Brother - Win32 Release"
+
+# Begin Custom Build - Making help file..
+OutDir=.\Release
+ProjDir=.
+TargetName=BigBro
+InputPath=.\help\bigbrother.hpj
+
+BuildCmds= \
+ "$(ProjDir)\makehelp.bat" \
+ compress $(OutDir)\$(TargetName).hlp $(OutDir)\$(TargetName).hl_ \
+ compress $(OutDir)\$(TargetName).cnt $(OutDir)\$(TargetName).cn_ \
+
+
+"$(OutDir)\$(TargetName).hlp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(OutDir)\$(TargetName).cnt" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(OutDir)\$(TargetName).hl_" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(OutDir)\$(TargetName).cn_" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Debug"
+
+# Begin Custom Build - Making help file..
+OutDir=.\Debug
+ProjDir=.
+TargetName=BigBro
+InputPath=.\help\bigbrother.hpj
+
+BuildCmds= \
+ "$(ProjDir)\makehelp.bat" \
+ compress $(OutDir)\$(TargetName).hlp $(OutDir)\$(TargetName).hl_ \
+ compress $(OutDir)\$(TargetName).cnt $(OutDir)\$(TargetName).cn_ \
+
+
+"$(OutDir)\$(TargetName).hlp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(OutDir)\$(TargetName).cnt" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(OutDir)\$(TargetName).hl_" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(OutDir)\$(TargetName).cn_" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Release Static"
+
+# Begin Custom Build - Making help file..
+OutDir=.\Releast
+ProjDir=.
+TargetName=BigBro
+InputPath=.\help\bigbrother.hpj
+
+BuildCmds= \
+ "$(ProjDir)\makehelp.bat" \
+ compress $(OutDir)\$(TargetName).hlp $(OutDir)\$(TargetName).hl_ \
+ compress $(OutDir)\$(TargetName).cnt $(OutDir)\$(TargetName).cn_ \
+
+
+"$(OutDir)\$(TargetName).hlp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(OutDir)\$(TargetName).cnt" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(OutDir)\$(TargetName).hl_" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"$(OutDir)\$(TargetName).cn_" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=".\shared-code\kICMP.cpp"
+DEP_CPP_KICMP=\
+ ".\shared-code\ip_icmp.h"\
+ ".\shared-code\kICMP.h"\
+ ".\shared-code\ms_icmp.h"\
+ ".\stdafx.h"\
+
+
+!IF "$(CFG)" == "Big Brother - Win32 Release"
+
+# ADD CPP /Yu"../stdafx.h"
+
+"$(INTDIR)\kICMP.obj" : $(SOURCE) $(DEP_CPP_KICMP) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+ $(CPP) /nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D\
+ "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)/bigbrother.pch" /Yu"../stdafx.h"\
+ /Fo"$(INTDIR)/" /c $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Debug"
+
+# ADD CPP /Yu"../stdafx.h"
+
+BuildCmds= \
+ $(CPP) /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\
+ /D "_AFXDLL" /D "_MBCS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/bigbrother.pch"\
+ /Yu"../stdafx.h" /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \
+
+
+"$(INTDIR)\kICMP.obj" : $(SOURCE) $(DEP_CPP_KICMP) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+ $(BuildCmds)
+
+"$(INTDIR)\kICMP.sbr" : $(SOURCE) $(DEP_CPP_KICMP) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+ $(BuildCmds)
+
+!ELSEIF "$(CFG)" == "Big Brother - Win32 Release Static"
+
+# ADD BASE CPP /Yu"../stdafx.h"
+# ADD CPP /Yu"../stdafx.h"
+
+"$(INTDIR)\kICMP.obj" : $(SOURCE) $(DEP_CPP_KICMP) "$(INTDIR)"\
+ "$(INTDIR)\bigbrother.pch"
+ $(CPP) /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D\
+ "_MBCS" /Fp"$(INTDIR)/bigbrother.pch" /Yu"../stdafx.h" /Fo"$(INTDIR)/" /c\
+ $(SOURCE)
+
+
+!ENDIF
+
+# End Source File
+# End Target
+################################################################################
+# Begin Target
+
+# Name "install - Win32 Debug"
+# Name "install - Win32 Pure"
+# Name "install - Win32 Canned"
+# Name "install - Win32 Static"
+
+!IF "$(CFG)" == "install - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "install - Win32 Pure"
+
+!ELSEIF "$(CFG)" == "install - Win32 Canned"
+
+!ELSEIF "$(CFG)" == "install - Win32 Static"
+
+!ENDIF
+
+################################################################################
+# Begin Source File
+
+SOURCE=.\install\install.cpp
+DEP_CPP_INSTA=\
+ ".\shared-code\install.h"\
+
+
+!IF "$(CFG)" == "install - Win32 Debug"
+
+
+"$(INTDIR)\install.obj" : $(SOURCE) $(DEP_CPP_INSTA) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "install - Win32 Pure"
+
+
+"$(INTDIR)\install.obj" : $(SOURCE) $(DEP_CPP_INSTA) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "install - Win32 Canned"
+
+
+"$(INTDIR)\install.obj" : $(SOURCE) $(DEP_CPP_INSTA) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "install - Win32 Static"
+
+
+"$(INTDIR)\install.obj" : $(SOURCE) $(DEP_CPP_INSTA) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\install\install.rc
+DEP_RSC_INSTAL=\
+ ".\install\custom.rch"\
+ ".\shared-data\install-icon.ico"\
+
+
+!IF "$(CFG)" == "install - Win32 Debug"
+
+
+"$(INTDIR)\install.res" : $(SOURCE) $(DEP_RSC_INSTAL) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)/install.res" /i "install" /d "_DEBUG"\
+ $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "install - Win32 Pure"
+
+
+"$(INTDIR)\install.res" : $(SOURCE) $(DEP_RSC_INSTAL) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)/install.res" /i "install" /d "NDEBUG"\
+ $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "install - Win32 Canned"
+
+
+"$(INTDIR)\install.res" : $(SOURCE) $(DEP_RSC_INSTAL) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)/install.res" /i "install" /d "NDEBUG" /d\
+ "K_ANNED" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "install - Win32 Static"
+
+
+"$(INTDIR)\install.res" : $(SOURCE) $(DEP_RSC_INSTAL) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)/install.res" /i "install" /d "NDEBUG" /d\
+ "STATI_K" $(SOURCE)
+
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project
+################################################################################
diff --git a/bigbrother.rc b/bigbrother.rc
new file mode 100644
index 0000000..787af72
--- a/dev/null
+++ b/bigbrother.rc
@@ -0,0 +1,729 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#define _AFX_NO_OLE_RESOURCES\r\n"
+ "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+ "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+ "\r\n"
+ "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+ "#ifdef _WIN32\r\n"
+ "LANGUAGE 9, 1\r\n"
+ "#pragma code_page(1252)\r\n"
+ "#endif\r\n"
+ "#include ""res\\BigBrother.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
+ "#include ""afxres.rc"" // Standard components\r\n"
+ "#include ""afxprint.rc"" // printing/print preview resources\r\n"
+ "#endif\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME ICON DISCARDABLE "res\\bigbrother.ico"
+IDR_BIGBROTYPE ICON DISCARDABLE "res\\BigBrotherDoc.ico"
+IDI_NOHOST ICON DISCARDABLE "res\\nohost.ico"
+IDI_PENDING ICON DISCARDABLE "res\\pending.ico"
+IDI_HOST ICON DISCARDABLE "res\\host.ico"
+IDI_PINGING ICON DISCARDABLE "res\\pinging.ico"
+IDI_GOINGDOWN ICON DISCARDABLE "res\\goingdown.ico"
+IDI_HOSTDOWN ICON DISCARDABLE "res\\hostdown.ico"
+IDI_PREPLAY ICON DISCARDABLE "shared-data/play-icon.ico"
+IDI_BROWSESOUND ICON DISCARDABLE "shared-data/browse-icon.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDR_MAINFRAME BITMAP MOVEABLE PURE "res\\maintoolbar.bmp"
+IDR_JUNKTOOLBAR BITMAP DISCARDABLE "res\\junktoolbar.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Toolbar
+//
+
+IDR_MAINFRAME TOOLBAR DISCARDABLE 16, 15
+BEGIN
+ BUTTON ID_FILE_NEW
+ BUTTON ID_FILE_OPEN
+ BUTTON ID_FILE_SAVE
+ SEPARATOR
+ BUTTON ID_BROTHERS_NEW
+ BUTTON ID_BROTHERS_ADDBROTHER
+ BUTTON ID_BROTHERS_DELETE
+ SEPARATOR
+ BUTTON ID_VIEW_HOSTPROPERTIES
+ BUTTON ID_FILE_PAUSE
+ SEPARATOR
+ BUTTON ID_APP_ABOUT
+ BUTTON ID_CONTEXT_HELP
+ BUTTON ID_HELP_LEGEND
+END
+
+IDR_JUNKTOOLBAR TOOLBAR DISCARDABLE 16, 15
+BEGIN
+ BUTTON ID_FILE_PRINT
+ BUTTON ID_EDIT_CUT
+ BUTTON ID_EDIT_COPY
+ BUTTON ID_EDIT_PASTE
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MAINFRAME MENU PRELOAD DISCARDABLE
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "&New\tCtrl+N", ID_FILE_NEW
+ MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN
+ MENUITEM "&Save\tCtrl+S", ID_FILE_SAVE
+ MENUITEM "Save &As...", ID_FILE_SAVE_AS
+ MENUITEM SEPARATOR
+ MENUITEM "&Autoload", ID_FILE_AUTOLOAD
+ MENUITEM "Preferences\tCtrl+P", ID_FILE_PREFERENCES
+ MENUITEM "&Pause", ID_FILE_PAUSE
+ MENUITEM SEPARATOR
+ MENUITEM "Recent File", ID_FILE_MRU_FILE1, GRAYED
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit", ID_APP_EXIT
+ END
+ POPUP "&Brother"
+ BEGIN
+ MENUITEM "Add &child", ID_BROTHERS_NEW
+ MENUITEM "Add &brother", ID_BROTHERS_ADDBROTHER
+ MENUITEM "&Delete", ID_BROTHERS_DELETE
+ END
+ POPUP "&View"
+ BEGIN
+ MENUITEM "&Toolbar", ID_VIEW_TOOLBAR
+ MENUITEM "&Status Bar", ID_VIEW_STATUS_BAR
+ MENUITEM "Adjust s&plitter", ID_WINDOW_SPLIT
+ MENUITEM SEPARATOR
+ MENUITEM "&Main Window", ID_VIEW_MAINWINDOW
+ MENUITEM "&Host Properties", ID_VIEW_HOSTPROPERTIES
+ END
+ POPUP "&Help"
+ BEGIN
+ MENUITEM "&Help Topics", ID_HELP_FINDER
+ MENUITEM "&Legend", ID_HELP_LEGEND
+ MENUITEM SEPARATOR
+ MENUITEM "&About BigBrother...", ID_APP_ABOUT
+ END
+END
+
+IDM_POPUPS MENU DISCARDABLE
+BEGIN
+ POPUP "Tray"
+ BEGIN
+ MENUITEM "&Show main window", ID_VIEW_MAINWINDOW
+ MENUITEM SEPARATOR
+ MENUITEM "&Help Topics", ID_HELP_FINDER
+ MENUITEM "&About Big Brother", ID_APP_ABOUT
+ MENUITEM "E&xit", ID_APP_EXIT
+ END
+ POPUP "Junk"
+ BEGIN
+ MENUITEM "PingBar", ID_INDICATOR_PINGBAR
+ POPUP "&Edit"
+ BEGIN
+ MENUITEM "&Undo\tCtrl+Z", ID_EDIT_UNDO
+ MENUITEM SEPARATOR
+ MENUITEM "Cu&t\tCtrl+X", ID_EDIT_CUT
+ MENUITEM "&Copy\tCtrl+C", ID_EDIT_COPY
+ MENUITEM "&Paste\tCtrl+V", ID_EDIT_PASTE
+ END
+ MENUITEM SEPARATOR
+ MENUITEM "&Print...\tCtrl+P", ID_FILE_PRINT
+ MENUITEM "Print Pre&view", ID_FILE_PRINT_PREVIEW
+ MENUITEM "P&rint Setup...", ID_FILE_PRINT_SETUP
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE
+BEGIN
+ "N", ID_FILE_NEW, VIRTKEY, CONTROL, NOINVERT
+ "O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
+ "P", ID_FILE_PREFERENCES, VIRTKEY, CONTROL, NOINVERT
+ "S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT
+ VK_DELETE, ID_BROTHERS_DELETE, VIRTKEY, NOINVERT
+ VK_DELETE, ID_BROTHERS_DELETE, VIRTKEY, NOINVERT
+ VK_F1, ID_HELP, VIRTKEY, NOINVERT
+ VK_F1, ID_CONTEXT_HELP, VIRTKEY, SHIFT, NOINVERT
+ VK_F6, ID_NEXT_PANE, VIRTKEY, NOINVERT
+ VK_F6, ID_PREV_PANE, VIRTKEY, SHIFT, NOINVERT
+ VK_INSERT, ID_BROTHERS_NEW, VIRTKEY, NOINVERT
+ "X", ID_APP_EXIT, VIRTKEY, ALT, NOINVERT
+END
+
+IDR_JUNKACCELERATOR ACCELERATORS DISCARDABLE
+BEGIN
+ "C", ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
+ "P", ID_FILE_PRINT, VIRTKEY, CONTROL, NOINVERT
+ "V", ID_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT
+ VK_BACK, ID_EDIT_UNDO, VIRTKEY, ALT, NOINVERT
+ VK_DELETE, ID_EDIT_CUT, VIRTKEY, SHIFT, NOINVERT
+ VK_INSERT, ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
+ VK_INSERT, ID_EDIT_PASTE, VIRTKEY, SHIFT, NOINVERT
+ "X", ID_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT
+ "Z", ID_EDIT_UNDO, VIRTKEY, CONTROL, NOINVERT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 217, 74
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "About Big Brother"
+FONT 8, "MS Sans Serif"
+BEGIN
+ ICON IDR_MAINFRAME,IDC_STATIC,13,16,18,20
+ LTEXT "Big Brother, Version 1.5",IDC_STATIC,48,16,119,8,
+ SS_NOPREFIX
+ LTEXT "Copyright 1996,2002 Klever Group",IDC_STATIC,48,31,119,8
+ DEFPUSHBUTTON "OK",IDOK,178,7,32,14,WS_GROUP
+ PUSHBUTTON "http://www.klever.net/",IDC_KLEVERNET,65,53,86,14
+END
+
+IDD_PROPS_SETTINGS DIALOG DISCARDABLE 0, 0, 220, 90
+STYLE DS_3DLOOK | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Settings"
+FONT 8, "MS Sans Serif"
+BEGIN
+ GROUPBOX "",IDC_STATIC,7,7,206,45,BS_NOTIFY
+ CONTROL "Ping &Intervals",IDC_OVERRIDE_INTERVALS,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,14,7,55,10
+ LTEXT "When the host is known as reach&able:",IDC_STATIC,14,18,
+ 122,8
+ EDITTEXT IDC_PINGINTERVAL_GOOD,165,16,40,13,ES_AUTOHSCROLL
+ LTEXT "When the host is known as &unreachable:",IDC_STATIC,14,
+ 32,130,8
+ EDITTEXT IDC_PINGINTERVAL_BAD,165,30,40,13,ES_AUTOHSCROLL
+ CONTROL "Maximum ping reply &timeout:",IDC_OVERRIDE_TIMEOUT,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,56,104,10
+ EDITTEXT IDC_PINGTIMEOUT,165,55,40,13,ES_AUTOHSCROLL
+ CONTROL "Maimum &retries count:",IDC_OVERRIDE_RETRIES,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,14,70,85,10
+ EDITTEXT IDC_RETRIES,165,70,40,13,ES_AUTOHSCROLL
+END
+
+IDD_PROPS_GENERAL DIALOG DISCARDABLE 0, 0, 221, 90
+STYLE DS_3DLOOK | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "General"
+FONT 8, "MS Sans Serif"
+BEGIN
+ LTEXT "&Host:",IDC_STATIC,7,7,18,8
+ EDITTEXT IDC_HOST,7,17,205,13,ES_LOWERCASE | ES_AUTOHSCROLL
+ LTEXT "&Description:",IDC_STATIC,7,33,38,8
+ EDITTEXT IDC_DESC,7,44,205,13,ES_AUTOHSCROLL
+ CONTROL "&Log host's activity",IDC_LOG_ACTIVITY,"Button",
+ BS_AUTO3STATE | BS_PUSHLIKE | WS_TABSTOP,7,63,205,14
+END
+
+IDD_PROPS_ACTION DIALOG DISCARDABLE 0, 0, 220, 90
+STYLE DS_3DLOOK | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Action"
+FONT 8, "MS Sans Serif"
+BEGIN
+ CONTROL "&Override Action",IDC_OVERRIDE_ACTION,"Button",
+ BS_AUTOCHECKBOX | BS_PUSHLIKE | WS_TABSTOP,7,7,208,11
+ GROUPBOX "Going down",IDC_STATIC,7,20,102,63
+ CONTROL "&Play a sound:",IDC_PLAYASOUND_DOWN,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,13,29,59,10
+ COMBOBOX IDC_SOUND_DOWN,13,40,91,43,CBS_DROPDOWN |
+ CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "",IDC_BROWSE_SOUND_DOWN,78,29,12,10,BS_ICON | BS_CENTER |
+ BS_VCENTER | BS_NOTIFY
+ PUSHBUTTON "",IDC_PREVIEW_SOUND_DOWN,92,29,12,10,BS_ICON |
+ BS_CENTER | BS_VCENTER | BS_NOTIFY
+ CONTROL "&Run custom program:",IDC_CUSTOM_DOWN,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,13,55,83,10
+ EDITTEXT IDC_PROGRAM_DOWN,13,66,91,12,ES_AUTOHSCROLL
+ GROUPBOX "Going up",IDC_STATIC,111,20,102,63
+ CONTROL "P&lay a sound:",IDC_PLAYASOUND_UP,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,117,29,59,10
+ COMBOBOX IDC_SOUND_UP,117,40,91,43,CBS_DROPDOWN | CBS_AUTOHSCROLL |
+ WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "",IDC_BROWSE_SOUND_UP,182,29,12,10,BS_ICON | BS_CENTER |
+ BS_VCENTER | BS_NOTIFY
+ PUSHBUTTON "",IDC_PREVIEW_SOUND_UP,196,29,12,10,BS_ICON | BS_CENTER |
+ BS_VCENTER | BS_NOTIFY
+ CONTROL "R&un custom program:",IDC_CUSTOM_UP,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,117,55,83,10
+ EDITTEXT IDC_PROGRAM_UP,117,66,91,12,ES_AUTOHSCROLL
+END
+
+IDD_PREFS DIALOGEX 0, 0, 191, 156
+STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION
+EXSTYLE WS_EX_TOOLWINDOW | WS_EX_CLIENTEDGE
+CAPTION "Preferences"
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Save options",IDC_STATIC,7,7,121,41
+ CONTROL "On windows shut&down save without confirmation.",
+ IDC_SAVEONSHUTDOWN,"Button",BS_AUTOCHECKBOX | BS_CENTER |
+ BS_MULTILINE | BS_NOTIFY | WS_TABSTOP,13,15,110,16
+ LTEXT "&Autosave every",IDC_STATIC,13,35,50,8
+ EDITTEXT IDC_AUTOSAVEMINS,67,33,27,12,ES_AUTOHSCROLL
+ CONTROL "Spin1",IDC_AUTOSPIN,"msctls_updown32",UDS_WRAP |
+ UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |
+ UDS_ARROWKEYS | UDS_NOTHOUSANDS,82,33,11,12
+ LTEXT "minutes",IDC_STATIC,99,35,25,8
+ GROUPBOX "ICMP options",IDC_STATIC,7,49,177,37
+ LTEXT "&Ping data packet size:",IDC_STATIC,13,59,71,8,
+ SS_NOTIFY
+ EDITTEXT IDC_PINGSIZE,87,57,35,12,ES_AUTOHSCROLL
+ CONTROL "Spin2",IDC_DATASIZESPIN,"msctls_updown32",UDS_WRAP |
+ UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |
+ UDS_ARROWKEYS | UDS_NOTHOUSANDS,106,57,11,12
+ LTEXT "bytes",IDC_STATIC,125,59,18,8
+ LTEXT "&hosts simultaneously",IDC_STATIC,63,72,65,8
+ EDITTEXT IDC_MAXTHREADS,33,70,27,12,ES_AUTOHSCROLL
+ CONTROL "Spin3",IDC_THREADSPIN,"msctls_updown32",UDS_WRAP |
+ UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |
+ UDS_ARROWKEYS | UDS_NOTHOUSANDS,50,70,10,12
+ LTEXT "Ping ",IDC_STATIC,13,72,17,8
+ GROUPBOX "Watch options",IDC_STATIC,7,88,177,61
+ LTEXT "Log to &file:",IDC_STATIC,13,96,34,8
+ EDITTEXT IDC_LOGFILE,13,106,150,13,ES_AUTOHSCROLL
+ PUSHBUTTON "",IDC_BROWSE,166,106,14,13,BS_ICON | BS_CENTER |
+ BS_VCENTER | BS_NOTIFY
+ LTEXT "Show &last ",IDC_STATIC,13,122,34,8
+ EDITTEXT IDC_LOGMINS,47,120,27,12,ES_AUTOHSCROLL
+ CONTROL "Spin1",IDC_LOGMINSPIN,"msctls_updown32",UDS_WRAP |
+ UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY |
+ UDS_ARROWKEYS | UDS_NOTHOUSANDS,64,120,10,12
+ LTEXT "minutes in activity pane",IDC_STATIC,79,122,74,8,
+ SS_NOTIFY
+ DEFPUSHBUTTON "OK",IDOK,134,14,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,134,31,50,14
+ CONTROL "&Store recent activity pane data",IDC_STOREACTIVITY,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,31,134,113,10
+END
+
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,5,0,0
+ PRODUCTVERSION 1,5,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Klever Group (http://www.klever.net/)\0"
+ VALUE "FileDescription", "Big Brother, network monitoring tool\0"
+ VALUE "FileVersion", "1, 5, 0, 0\0"
+ VALUE "InternalName", "BIGBROTHER\0"
+ VALUE "LegalCopyright", "Copyright 1996, 2002 Klever Group (http://www.klever.net/)\0"
+ VALUE "LegalTrademarks", "Klever Group (http://www.klever.net/)\0"
+ VALUE "OriginalFilename", "BIGBRO.EXE\0"
+ VALUE "ProductName", "Big Brother\0"
+ VALUE "ProductVersion", "1, 5, 0, 0\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_ABOUTBOX, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 210
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 67
+ END
+
+ IDD_PROPS_SETTINGS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 213
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 83
+ END
+
+ IDD_PROPS_GENERAL, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 214
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 83
+ END
+
+ IDD_PROPS_ACTION, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 213
+ VERTGUIDE, 110
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 83
+ HORZGUIDE, 20
+ END
+
+ IDD_PREFS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 184
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 149
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog Info
+//
+
+IDD_PROPS_ACTION DLGINIT
+BEGIN
+ IDC_SOUND_DOWN, 0x403, 10, 0
+0x6828, 0x736f, 0x2d74, 0x7075, 0x0029,
+ IDC_SOUND_DOWN, 0x403, 12, 0
+0x6828, 0x736f, 0x2d74, 0x6f64, 0x6e77, 0x0029,
+ IDC_SOUND_DOWN, 0x403, 12, 0
+0x7328, 0x7379, 0x6574, 0x2d6d, 0x6b6f, 0x0029,
+ IDC_SOUND_DOWN, 0x403, 18, 0
+0x7328, 0x7379, 0x6574, 0x2d6d, 0x7263, 0x7469, 0x6369, 0x6c61, 0x0029,
+
+ IDC_SOUND_UP, 0x403, 10, 0
+0x6828, 0x736f, 0x2d74, 0x7075, 0x0029,
+ IDC_SOUND_UP, 0x403, 12, 0
+0x6828, 0x736f, 0x2d74, 0x6f64, 0x6e77, 0x0029,
+ IDC_SOUND_UP, 0x403, 12, 0
+0x7328, 0x7379, 0x6574, 0x2d6d, 0x6b6f, 0x0029,
+ IDC_SOUND_UP, 0x403, 18, 0
+0x7328, 0x7379, 0x6574, 0x2d6d, 0x7263, 0x7469, 0x6369, 0x6c61, 0x0029,
+
+ 0
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// AVI
+//
+
+IDR_PINGBAR AVI DISCARDABLE "res\\3angle.avi"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// WAVE
+//
+
+IDW_HOST_UP WAVE DISCARDABLE "res\\host-up.wav"
+IDW_HOST_DOWN WAVE DISCARDABLE "res\\host-down.wav"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDP_SOCKETS_INIT_FAILED "Windows sockets initialization failed."
+ IDS_PROPS_TITLE "Properties"
+ IDS_LOG_DOLOG "&Log host activity"
+ IDS_LOG_DONTLOG "Don't &Log host activity"
+ IDS_LOG_ASKBIGBROTHER "&Log if parent does"
+ IDS_NODESC "..no description.."
+ IDS_PS_FAILEDTORESOLVE "Failed to resolve host"
+ IDS_PS_UNABLETOICMP "Failed to request ICMP service"
+END
+
+STRINGTABLE PRELOAD DISCARDABLE
+BEGIN
+ IDR_MAINFRAME "Big Brother\n\nBigBro\nBig Brother Files (*.bro)\n.BRO\nBigBrother.Document\nBigBro Document"
+ IDS_PS_UNKNOWNERROR "Unkown error %lu"
+ IDS_REGISTRYKEY "Klever Group, Inc."
+ IDS_AVIEW_NOTIP "Host(s) activity"
+ IDS_AVIEW_SHORTTIP "%s (%s)"
+ IDS_AVIEW_TIP_TIMEFORMAT "%c"
+ IDS_AVIEW_TIP_UNPINGED "no timing information"
+ IDS_AVIEW_TIP_UNREACHABLE "not reached"
+ IDS_AVIEW_TIP_RTTREPORT "RTT = %lu"
+ IDS_ROOTNODENAME "Global Settings"
+ IDS_WAVFILTER "Wave files (*.wav)|*.wav|All files (*.*)|*.*|"
+ IDS_ACTION_HOST_UP "(host-up)"
+ IDS_ACTION_HOST_DOWN "(host-down)"
+ IDS_LOGFILTER "Log files (*.log)|*.log|All files (*.*)|*.*|"
+ IDS_LOG_HOSTUP "%s (%s) has changed state to up"
+ IDS_LOG_HOSTDOWN "%s (%s) has changed state to down"
+END
+
+STRINGTABLE PRELOAD DISCARDABLE
+BEGIN
+ AFX_IDS_APP_TITLE "BigBrother"
+ AFX_IDS_IDLEMESSAGE "For Help, press F1"
+ AFX_IDS_HELPMODEMESSAGE "Select an object on which to get Help"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_INDICATOR_EXT "EXT"
+ ID_INDICATOR_CAPS "CAP"
+ ID_INDICATOR_NUM "NUM"
+ ID_INDICATOR_SCRL "SCRL"
+ ID_INDICATOR_OVR "OVR"
+ ID_INDICATOR_REC "REC"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_FILE_NEW "Create a new document\nNew"
+ ID_FILE_OPEN "Open an existing document\nOpen"
+ ID_FILE_CLOSE "Close the active document\nClose"
+ ID_FILE_SAVE "Save the active document\nSave"
+ ID_FILE_SAVE_AS "Save the active document with a new name\nSave As"
+ ID_FILE_PAGE_SETUP "Change the printing options\nPage Setup"
+ ID_FILE_PRINT_SETUP "Change the printer and printing options\nPrint Setup"
+ ID_FILE_PRINT "Print the active document\nPrint"
+ ID_FILE_PRINT_PREVIEW "Display full pages\nPrint Preview"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_APP_ABOUT "Display program information, version number and copyright\nAbout"
+ ID_APP_EXIT "Quit the application; prompts to save documents\nExit"
+ ID_HELP_INDEX "Opens Help\nHelp Topics"
+ ID_HELP_FINDER "List Help topics\nHelp Topics"
+ ID_HELP_USING "Display instructions about how to use help\nHelp"
+ ID_CONTEXT_HELP "Display help for clicked on buttons, menus and windows\nHelp"
+ ID_HELP "Display help for current task or command\nHelp"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_FILE_MRU_FILE1 "Open this document"
+ ID_FILE_MRU_FILE2 "Open this document"
+ ID_FILE_MRU_FILE3 "Open this document"
+ ID_FILE_MRU_FILE4 "Open this document"
+ ID_FILE_MRU_FILE5 "Open this document"
+ ID_FILE_MRU_FILE6 "Open this document"
+ ID_FILE_MRU_FILE7 "Open this document"
+ ID_FILE_MRU_FILE8 "Open this document"
+ ID_FILE_MRU_FILE9 "Open this document"
+ ID_FILE_MRU_FILE10 "Open this document"
+ ID_FILE_MRU_FILE11 "Open this document"
+ ID_FILE_MRU_FILE12 "Open this document"
+ ID_FILE_MRU_FILE13 "Open this document"
+ ID_FILE_MRU_FILE14 "Open this document"
+ ID_FILE_MRU_FILE15 "Open this document"
+ ID_FILE_MRU_FILE16 "Open this document"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_NEXT_PANE "Switch to the next window pane\nNext Pane"
+ ID_PREV_PANE "Switch back to the previous window pane\nPrevious Pane"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_WINDOW_SPLIT "Adjust splitter position\nSplitter"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_EDIT_CLEAR "Erase the selection\nErase"
+ ID_EDIT_CLEAR_ALL "Erase everything\nErase All"
+ ID_EDIT_COPY "Copy the selection and put it on the Clipboard\nCopy"
+ ID_EDIT_CUT "Cut the selection and put it on the Clipboard\nCut"
+ ID_EDIT_FIND "Find the specified text\nFind"
+ ID_EDIT_PASTE "Insert Clipboard contents\nPaste"
+ ID_EDIT_REPEAT "Repeat the last action\nRepeat"
+ ID_EDIT_REPLACE "Replace specific text with different text\nReplace"
+ ID_EDIT_SELECT_ALL "Select the entire document\nSelect All"
+ ID_EDIT_UNDO "Undo the last action\nUndo"
+ ID_EDIT_REDO "Redo the previously undone action\nRedo"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_VIEW_TOOLBAR "Show or hide the toolbar\nToggle ToolBar"
+ ID_VIEW_STATUS_BAR "Show or hide the status bar\nToggle StatusBar"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ AFX_IDS_SCSIZE "Change the window size"
+ AFX_IDS_SCMOVE "Change the window position"
+ AFX_IDS_SCMINIMIZE "Reduce the window to an icon"
+ AFX_IDS_SCMAXIMIZE "Enlarge the window to full size"
+ AFX_IDS_SCNEXTWINDOW "Switch to the next document window"
+ AFX_IDS_SCPREVWINDOW "Switch to the previous document window"
+ AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ AFX_IDS_SCRESTORE "Restore the window to normal size"
+ AFX_IDS_SCTASKLIST "Activate Task List"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ AFX_IDS_PREVIEW_CLOSE "Close print preview mode\nCancel Preview"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_BROTHERS_NEW "Add new host to monitor. Child to current\nNew Child"
+ ID_VIEW_MAINWINDOW "Show/hide main window\nHide/Show window"
+ ID_INDICATOR_PINGBAR " "
+ ID_BROTHERS_ADDBROTHER "Add new host to monitor. Brother to current\nNew brother"
+ ID_BROTHERS_DELETE "Remove current host and subtree\nDelete"
+ ID_FILE_AUTOLOAD "Automatically load most recently used file on startup\nAutoload"
+ ID_FILE_PREFERENCES "Monitoring options\nPreferences"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_PS_INTERNALERROR "Internal error. Please report to Klever"
+ IDS_PS_NETUNREACHABLE "Destination network is unreachable"
+ IDS_PS_HOSTUNREACHABLE "Destination host is unreachable"
+ IDS_PS_PROTUNREACHABLE "Destination protocol is unreachable"
+ IDS_PS_PORTUNREACHABLE "Destination port is unreachable"
+ IDS_PS_NORESOURCES "No resources"
+ IDS_PS_HWERROR "Hardware error"
+ IDS_PS_BIGPACKET "Packet size is too big"
+ IDS_PS_TIMEOUT "Request timed out"
+ IDS_PS_BADROUTE "Bad route"
+ IDS_PS_TTLEXPTRANSIT "TTL expired in transition"
+ IDS_PS_TTLEXPREASM "TTL Expired during reassembling"
+ IDS_PS_IPARAMP "IP parameter problem"
+ IDS_PS_SOURCEQUENCH "Source quench received"
+ IDS_PS_BIGOPTION "Option is too big"
+ IDS_PS_BADDEST "Bad destination"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_LOG_DATEFORMAT "%a, %d %b %Y %H:%M:%S %z"
+ IDS_LOGFILE_SELECT "Log To"
+ IDS_SOUND_SELECT "Select Sound"
+ IDS_LOG_LOADFILE "'%s' file loaded"
+ IDS_ACTION_SYSTEM_OK "(system-ok)"
+ IDS_ACTION_SYSTEM_CRITICAL "(system-critical)"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_FILE_PAUSE "Temporarily suspend monitoring\nPause"
+ ID_VIEW_HOSTPROPERTIES "Show/hide host properties window\nHost Properties"
+ ID_HELP_LEGEND "Shows The Legend\nLegend"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#endif
+#include "res\bigbrother.rc2" // non-Microsoft Visual C++ edited resources
+#include "afxres.rc" // Standard components
+#include "afxprint.rc" // printing/print preview resources
+#endif
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/help/IDI_GOINGDOWN.bmp b/help/IDI_GOINGDOWN.bmp
new file mode 100644
index 0000000..9179dd5
--- a/dev/null
+++ b/help/IDI_GOINGDOWN.bmp
Binary files differ
diff --git a/help/IDI_HOST.bmp b/help/IDI_HOST.bmp
new file mode 100644
index 0000000..dc7a2cb
--- a/dev/null
+++ b/help/IDI_HOST.bmp
Binary files differ
diff --git a/help/IDI_HOSTDOWN.bmp b/help/IDI_HOSTDOWN.bmp
new file mode 100644
index 0000000..5864007
--- a/dev/null
+++ b/help/IDI_HOSTDOWN.bmp
Binary files differ
diff --git a/help/IDI_NOHOST.bmp b/help/IDI_NOHOST.bmp
new file mode 100644
index 0000000..e21bb4f
--- a/dev/null
+++ b/help/IDI_NOHOST.bmp
Binary files differ
diff --git a/help/IDI_PINGING.bmp b/help/IDI_PINGING.bmp
new file mode 100644
index 0000000..bd90963
--- a/dev/null
+++ b/help/IDI_PINGING.bmp
Binary files differ
diff --git a/help/bbullet.bmp b/help/bbullet.bmp
new file mode 100644
index 0000000..772fe15
--- a/dev/null
+++ b/help/bbullet.bmp
Binary files differ
diff --git a/help/bigbro.cnt b/help/bigbro.cnt
new file mode 100644
index 0000000..423b538
--- a/dev/null
+++ b/help/bigbro.cnt
@@ -0,0 +1,29 @@
+:Base BigBro.hlp>Standard
+:Title Big Brother
+1 Big Brother
+2 About Big Brother=About
+2 What's New=News
+2 Using Big Brother=Using
+1 Menus
+2 File
+3 New=HID_FILE_NEW
+3 Open=HID_FILE_OPEN
+3 Save=HID_FILE_SAVE
+3 Save as=HID_FILE_SAVE_AS
+3 Autoload=HID_FILE_AUTOLOAD
+3 Preferences=HID_FILE_PREFERENCES
+3 Pause=HID_FILE_PAUSE
+3 Exit=HID_APP_EXIT
+2 Brothers
+3 Add child=HID_BROTHERS_NEW
+3 Add brother=HID_BROTHERS_ADDBROTHER
+3 Delete=HID_BROTHERS_DELETE
+2 View
+3 Toolbar=HID_VIEW_TOOLBAR
+3 Status bar=HID_VIEW_STATUS_BAR
+3 Adjust splitter=HID_WINDOW_SPLIT
+3 Main Window=HID_VIEW_MAINWINDOW
+3 Host Properties=HID_VIEW_HOSTPROPERTIES
+2 Help
+3 Help Topics=HID_HELP_FINDER
+3 About BigBrother=HID_APP_ABOUT
diff --git a/help/bigbrother.hpj b/help/bigbrother.hpj
new file mode 100644
index 0000000..afb4543
--- a/dev/null
+++ b/help/bigbrother.hpj
@@ -0,0 +1,33 @@
+; This file is maintained by HCW. Do not modify this file directly.
+
+[OPTIONS]
+COMPRESS=12 Hall Zeck
+LCID=0x409 0x0 0x0 ; English (United States)
+REPORT=Yes
+CONTENTS=About
+TITLE=Big Brother
+CNT=bigbro.cnt
+HLP=BIGBRO.HLP
+
+[FILES]
+bigbrother.rtf
+
+[ALIAS]
+AFX_HIDW_DOCKBAR_TOP=Using
+HID_APP_ABOUT=About
+HID_FILE_MRU_FILE1=MRUFile
+HID_FILE_MRU_FILE2=MRUFile
+HID_FILE_MRU_FILE3=MRUFile
+HID_FILE_MRU_FILE4=MRUFile
+HID_FILE_PREFERENCES=HIDD_PREFS
+HID_HT_CAPTION=Using
+HID_HT_MAXBUTTON=HID_SC_MAXIMIZE
+HID_HT_MINBUTTON=Using
+HIDD_ABOUTBOX=About
+HIDR_MAINFRAME=Using
+
+[MAP]
+#include bigbro.hm
+
+[WINDOWS]
+Standard="",(208,13,513,954),20740,(r14876671),(r12632256),f2
diff --git a/help/bigbrother.rtf b/help/bigbrother.rtf
new file mode 100644
index 0000000..eb128ac
--- a/dev/null
+++ b/help/bigbrother.rtf
@@ -0,0 +1,295 @@
+{\rtf1\ansi
+@{\footnote
+THIS FILE WAS AUTOMATICALLY GENERATED FROM XML DOCUMENT.
+DO NOT MODIFY THIS FILE DIRECTLY. EDIT XML DOCUMENT INSTEAD
+}
+{\fonttbl{\f0\froman Times New Roman;}{\f1\fswiss Arial;}{\f3\froman Symbol;}}{\colortbl;
+ \red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;
+ \red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;
+ \red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;
+ \red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}
+
+\pard\plain\keepn
+#{\footnote About}
+${\footnote About Big Brother}
+K{\footnote about}
+{ \f1\fs18\b\sb120 About {\b Big Brother}}
+\par\sa120\sb120\qr\f1\fs16 dedicated to Kundel
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 {\b Big Brother} is a program designed to monitor your IP-network activities. it gives you a comprehensive picture of what happened to any point on the Net that you put in. Just {\uldb add}{\v Add} this point by specifying it's IP address or hostname and optional short description (for your information only).
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 The hosts are organized into a hierarchical tree so that you may configure your network picture according to your needs and imagination. Most of the father host properties are inherited by his children unless you wish to specify child's settings explicitly.
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Every specified period of time {\b Big Brother} will send echo request to every host. And wait for response for at most specified {\uldb timeout}{\v timeOutHIDD_PROPS_SETTINGS}.
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Results are presented in a graphical form in the lower pane. Each line of the lower window is related to specific host which is shown on the tooltip when you move your mouse over the graphics. Host activities are also {\uldb logged into file}{\v fileHIDD_PREFS}.
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Your current {\uldb preferences}{\v HIDD_PREFS} and network tree are automatically saved on Windows shutdown (unless specified otherwise) and may be {\uldb autosaved}{\v autosaveHIDD_PREFS} every specified amount of minutes. Most recently used {\uldb file}{\v MRUFile} is {\uldb automatically loaded}{\v HID_FILE_AUTOLOAD} at {\b Big Brother}'s startup unless you don't want it.
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 You can also hide {\b Big Brother} into your notify tray so that it won't occupy more than 16x16 square of your precious windows' desktop. Just click \{bmct bbullet.bmp\} in your notify tray or select {\uldb View/Main Window}{\v HID_VIEW_MAINWINDOW} from menu. Click \{bmct bbullet.bmp\} again to restore {\b Big Brother} to its full size.
+\par\sa120\sb120\qj\pard \f1\fs18\sb120
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 {\b {\i Enjoy!}}
+{
+\par\pard\plain\sb360\sa120 \f1\fs16 Copyright (c) 1996, 2002 {\uldb\cf0 Klever Group (http://www.klever.net/)}{\v %!ExecFile("http://www.klever.net/")}
+\par\qj\sb120\sa120Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+\par The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+\par \sa360 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+}
+\par \sa0\sb120\ql \f1\fs16 Author: {\b\uldb\cf11 Michael Krelin ({\i hacker@klever.net})}{\v %!ExecFile("mailto:hacker@klever.net")}
+\par \sa0\sb0 Fan mail send to {\i\uldb gefilte@klever.net}{\v %!ExecFile("mailto:gefilte@klever.net")}
+\page
+
+\pard\plain
+#{\footnote News}
+${\footnote What's New}
+\par\pard\plain\f1\fs24\qc\cf2\b 1.5 - August 19th, 2002
+\par\pard\plain\fi0\li0\f1\fs18 \bullet License change and opening the source code
+\par\pard\plain\fi0\li0\f1\fs18 \bullet Made it work with Win2k and friends
+\par\pard\plain\fi0\li0\f1\fs18 \bullet Added kinwide installer
+\page
+
+\pard\plain\keepn
+#{\footnote Using}
+${\footnote Using Big Brother}
+{ \f1\fs18\b\sb120 Using {\b Big Brother}}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Using {\b Big Brother} consists of two parts - designing your network tree and monitoring it's activity. The latter takes no effort of yours.
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 To design the network layout is to put your hosts into Network Tree pane. To {\uldb add a child host}{\v HID_BROTHERS_NEW} to the current just press insert or Select Brothers/Add child from menu. To {\uldb add a brother}{\v HID_BROTHERS_ADDBROTHER} of the current host select Brothers/Add brother from menu. (note: You can't add brother to the root node)
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 You may also show {\uldb properties}{\v HostProps} dialog box by selecting View/Host Properties menu. {\uldb Properties}{\v HostProps} dialog box also pops up automatically whenever you press {\b Enter} in the tree view pane.
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Monitoring your network activities is even easier. You just relax and watch the screen (or listen to your speakers if you have ones). Network activities are reflected using the lower host activity pane and icons in the tree view. The possible states of the host are:\pard
+\par \fi0\li0 \bullet \{bmct IDI_NOHOST.bmp\}{\b Network} - you haven't specified host name or ip address for this host. The only reason that makes sense is that you probably want to use this node as a father for family of hosts.
+\par \fi0\li0 \bullet \{bmct IDI_PINGING.bmp\}{\b In progress} - checking of this host is in progress.
+\par \fi0\li0 \bullet \{bmct IDI_HOST.bmp\}{\b Reachable host} - this host is reachable and you have no reason to worry about it.
+\par \fi0\li0 \bullet \{bmct IDI_GOINGDOWN.bmp\}{\b Worrisome host} - this host was reported as unreachable, but less than for specified {\uldb retries}{\v HIDD_PROPS_SETTINGS} times.
+\par \fi0\li0 \bullet \{bmct IDI_HOSTDOWN.bmp\}{\b Unreachable host} - this host is known as unreachable for a long time. Whenever the host enters or leaves this state specified {\uldb actions}{\v HIDD_PROPS_ACTION} are taken.\pard
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Lower pane shows a histogram of response times for a {\uldb specified}{\v logLengthHIDD_PREFS} amount of time. Histograms are shown for current host and it's descendants. Hidden (collapsed) children are not shown in activity pane. When you move your mouse over histogram tooltip shows the host name and host address for the corresponding host. If you also hold left mouse button or Ctrl key it will also show you the time corresponding to the point you point at. If you hold Shift key it will also show the Round Trip Time.
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Histogram shows the Round Trip Time in the following colours:\pard
+\par \fi0\li0 \bullet \{bmct green.bmp\} Host's response time is less than 1/3 of the {\uldb specified}{\v timeOutHIDD_PROPS_SETTINGS} timeout.
+\par \fi0\li0 \bullet \{bmct yellow.bmp\} Host's response time is more than 1/3, but less then 2/3 of the {\uldb specified}{\v timeOutHIDD_PROPS_SETTINGS} timeout.
+\par \fi0\li0 \bullet \{bmct red.bmp\} Host's response time is more than 2/3 of the {\uldb specified}{\v timeOutHIDD_PROPS_SETTINGS} timeout.\pard
+\page
+
+\pard\plain\keepn
+#{\footnote HIDD_PREFS}
+${\footnote Preferences}
+{ \f1\fs18\b\sb120 Preferences}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 The Preferences dialog box allows you to change global system preferences which are:\pard
+\par \fi0\li0 \bullet {\b On windows shutdown save without confirmation} - you may specify how does {\b Big Brother} act on windows shutdown, whether to save current tree without a confirmation or not.
+\par \fi0\li0 \bullet {#{\footnote autosaveHIDD_PREFS}}Autosave - the interval at wich {\b Big Brother} will save current tree automatically. Specify 0 if you don't want to use this feature.
+\par \fi0\li0 \bullet Ping data packet size - the size of echo request packet in bytes.
+\par \fi0\li0 \bullet Ping .. hosts simultaneously - number of hosts to ping at a time. If you have a big network to monitor and have a slow computer or connection, you may want to limit number of hosts to ping simultaneously.
+\par \fi0\li0 \bullet {#{\footnote fileHIDD_PREFS}}Log to file - Here is where you specify the name of the file to log hosts activities to.
+\par \fi0\li0 \bullet {#{\footnote logLengthHIDD_PREFS}}Show last .. minutes in activity pane - This is the time length of your graphical pane window.
+\par \fi0\li0 \bullet {#{\footnote storeActivityHIDD_PREFS}}Store activity pane data - This lets you specify where to store activity pane data when saving file or not.\pard
+\page
+
+\pard\plain\keepn
+#{\footnote HID_VIEW_HOSTPROPERTIES}
+{ \f1\fs18\b\sb120 Host Properties}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 You may show/hide Host Properties dialog box using this menu command
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 {#{\footnote HostProps}}Host Properties dialog box consists of three tabs. See {\uldb General tab}{\v HIDD_PROPS_GENERAL}, {\uldb Settings tab}{\v HIDD_PROPS_SETTINGS} and {\uldb Action tab}{\v HIDD_PROPS_ACTION} for further details.
+\page
+
+\pard\plain\keepn
+#{\footnote HID_BROTHERS_NEW}
+{ \f1\fs18\b\sb120 Add new host (child to current)}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 You can add new host into your network using this menu command. New host will be the child to current.
+\page
+
+\pard\plain\keepn
+#{\footnote HID_FILE_AUTOLOAD}
+{ \f1\fs18\b\sb120 Autoload}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 You may specify whether you want Big Brother to load most recently used file at the startup or not.
+\page
+
+\pard\plain\keepn
+#{\footnote HIDD_PROPS_ACTION}
+${\footnote Action tab}
+{ \f1\fs18\b\sb120 Action}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Using action tab of {\uldb host properties}{\v HostProps} dialog box you may specify the actions to be taken whenever host changes its state from up to down and vice versa.\pard
+\par \fi0\li0 \bullet Override action - You may specify if you want this host to specify some specific actions to take or if you want it to act as it's parent does.
+\par \fi0\li0 \bullet Going down - Actions to take whenever host goes down (is known as unreachable for {\uldb retries}{\v retriesHIDD_PROPS_SETTINGS} times in a row). See {\uldb below}{\v Action} for details.
+\par \fi0\li0 \bullet Going up - Actions to take whenever host becomes reachable after it is considered to be down.\pard
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 {#{\footnote Action}}Possible actions are:\pard
+\par \fi0\li0 \bullet Play a sound - Plays a sound. You may specify a .wav file or use one of the predefined sounds which are
+ \pard
+\par \fi0\li0 \bullet (host-up) - Default sound indicating host recovering from crash
+\par \fi0\li0 \bullet (host-down) - Default sound indicating crashing host
+\par \fi0\li0 \bullet (system-ok) - System sound as defined in Control Panel/Sounds 'Asterisk'
+\par \fi0\li0 \bullet (system-critical) - System sound as defined in Control Panel/Sounds 'Critical Stop'\pard
+\par \fi0\li0 \bullet Run custom program - Run custom program. The following special sequences are defined:
+ \pard
+\par \fi0\li0 \bullet %h - Host name
+\par \fi0\li0 \bullet %d - Host description
+\par \fi0\li0 \bullet %% - % sign\pard\pard
+\page
+
+\pard\plain\keepn
+#{\footnote HID_VIEW_MAINWINDOW}
+{ \f1\fs18\b\sb120 Main Window}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 You may hide {\b Big Brother}'s main window using this command. You may get the window back by clicking the \{bmct bbullet.bmp\} in your notification tray area.
+\page
+
+\pard\plain\keepn
+#{\footnote HIDD_PROPS_GENERAL}
+${\footnote General tab}
+{ \f1\fs18\b\sb120 General tab}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 General tab of {\uldb Host Properties}{\v HostProps} dialog box lets you specify the following:\pard
+\par \fi0\li0 \bullet Host - either host name or ip address of host you want to monitor.
+\par \fi0\li0 \bullet Description - a short description of the host. The name you want to refer to this host by in the future.
+\par \fi0\li0 \bullet Log Activity - You may specify if you do or don't want to log changes of this host's state into {\uldb file}{\v fileHIDD_PREFS}.\pard
+\page
+
+\pard\plain\keepn
+#{\footnote HID_FILE_PAUSE}
+{ \f1\fs18\b\sb120 Pause}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 This command lets you temporarily disable monitoring of hosts. {\b Big Brother} will just sit and wait until you let him do his work.
+\page
+
+\pard\plain\keepn
+#{\footnote HIDD_PROPS_SETTINGS}
+${\footnote Settings tab}
+{ \f1\fs18\b\sb120 Settings tab}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Settings tab of {\uldb Host Properties}{\v HostProps} dialog box lets you specify the following:\pard
+\par \fi0\li0 \bullet Ping intervals - check this if you want to specify intervals for this host explicitly. If you don't - this host will use parent's settings. You can't uncheck this for root node.
+ \pard
+\par \fi0\li0 \bullet When the host is known as reachable - time to wait until next ping if the last ping succeeded.
+\par \fi0\li0 \bullet When the host is known as unreachable - time to wait until next ping If the last ping failed.\pard
+\par \fi0\li0 \bullet {#{\footnote timeOutHIDD_PROPS_SETTINGS}}Maximum ping reply timeout - amount of milliseconds to wait for echo reply.
+\par \fi0\li0 \bullet {#{\footnote retriesHIDD_PROPS_SETTINGS}}Maximum retries count - number of failed pings before Big Brother considers the host is down.\pard
+\page
+
+\pard\plain\keepn
+#{\footnote HID_BROTHERS_DELETE}
+{ \f1\fs18\b\sb120 Delete}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Use this feature to remove current host and all of its children. You can't remove the root node, although you may remove all hosts but root using this command.
+\page
+
+\pard\plain\keepn
+#{\footnote HID_BROTHERS_ADDBROTHER}
+{ \f1\fs18\b\sb120 Add new host (brother to current)}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 You can add new host into your network using this menu command. New host will be a brother to current. (note: You can't add brother to the root node)
+\page
+
+\pard\plain\keepn
+#{\footnote HID_FILE_NEW}
+{ \f1\fs18\b\sb120 New}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Create the whole new network tree. This command will remove all hosts you currently have.
+\page
+
+\pard\plain\keepn
+#{\footnote HID_FILE_OPEN}
+{ \f1\fs18\b\sb120 Open}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Open previously {\uldb saved}{\v HID_FILE_SAVE} network file.
+\page
+
+\pard\plain\keepn
+#{\footnote HID_FILE_SAVE}
+{ \f1\fs18\b\sb120 Save}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Save your current network layout to disk file for future {\uldb retrieval}{\v HID_FILE_OPEN}
+\page
+
+\pard\plain\keepn
+#{\footnote HID_FILE_SAVE_AS}
+{ \f1\fs18\b\sb120 Save as}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Save your current network layout under different name.
+\page
+
+\pard\plain\keepn
+#{\footnote HID_APP_EXIT}
+{ \f1\fs18\b\sb120 Exit}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Leave {\b Big Brother}. you will be prompted if you have unsaved information.
+\page
+
+\pard\plain\keepn
+#{\footnote HID_VIEW_TOOLBAR}
+{ \f1\fs18\b\sb120 Toolbar}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Use this command to hide or show toolbar.
+\page
+
+\pard\plain\keepn
+#{\footnote HID_VIEW_STATUS_BAR}
+{ \f1\fs18\b\sb120 Status bar}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Use this command to hide or show status bar.
+\page
+
+\pard\plain\keepn
+#{\footnote HID_WINDOW_SPLIT}
+{ \f1\fs18\b\sb120 Adjust Splitter}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Adjust position of splitter between tree view pane and host activity pane
+\page
+
+\pard\plain\keepn
+#{\footnote HID_HELP_FINDER}
+{ \f1\fs18\b\sb120 Help Topics}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Show help topics.
+\page
+
+\pard\plain\keepn
+#{\footnote MRUFile}
+{ \f1\fs18\b\sb120 Most Recently Used Files}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 The menu commands right before the Exit allows you to quickly retrieve one of the most recently used files.
+\page
+
+\pard\plain\keepn
+#{\footnote HID_INDICATOR_PINGBAR}
+{ \f1\fs18\b\sb120 {\b Big Brother} Activity indicator}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 {\b Big Brother} activity indicator is a small red triangle spinning and turning to black whenever Big Brother is busy pinging hosts.
+\page
+
+\pard\plain\keepn
+#{\footnote AFX_HIDW_STATUS_BAR}
+{ \f1\fs18\b\sb120 Status bar}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Sometimes you may see some useful messages in there. For instance, long descriptions of menu items whenever you are exploring the menu.
+\page
+
+\pard\plain\keepn
+#{\footnote HID_CONTEXT_HELP}
+{ \f1\fs18\b\sb120 Context help}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Move mouse cursor with question mark wherever you want and get help for something you click on.
+\page
+
+\pard\plain\keepn
+#{\footnote HID_SC_MAXIMIZE}
+{ \f1\fs18\b\sb120 Maximize}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 This option will maximize {\b Big Brother} window to full screen.
+\page
+
+\pard\plain\keepn
+#{\footnote HID_SC_MOVE}
+{ \f1\fs18\b\sb120 Move}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 This option will let you move {\b Big Brother} window around the screen.
+\page
+
+\pard\plain\keepn
+#{\footnote HID_SC_SIZE}
+{ \f1\fs18\b\sb120 Size}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 This option will let you resize {\b Big Brother}'s window
+\page
+
+\pard\plain\keepn
+#{\footnote HID_SC_RESTORE}
+{ \f1\fs18\b\sb120 Restore}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 You option may use this to restore {\b Big Brother}'s window to its original size after you've maximized it.
+\page
+
+\pard\plain\keepn
+#{\footnote HID_SC_CLOSE}
+{ \f1\fs18\b\sb120 Close}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 This option does about the same as the {\uldb Exit}{\v HID_APP_EXIT} menu command does.
+\page
+
+\pard\plain\keepn
+#{\footnote Add}
+${\footnote Add new host}
+{ \f1\fs18\b\sb120 Add new host}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 You may add new hosts for monitoring in two ways - by adding it {\uldb as a child}{\v HID_BROTHERS_NEW} or {\uldb as a brother}{\v HID_BROTHERS_ADDBROTHER} to current one.
+\page
+
+\pard\plain
+#{\footnote HID_HELP_LEGEND}
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Tree view pane:\pard
+\par \fi0\li0 \bullet \{bmct IDI_NOHOST.bmp\} Network - no particular host specified.
+\par \fi0\li0 \bullet \{bmct IDI_PINGING.bmp\} In progress - host is being checked.
+\par \fi0\li0 \bullet \{bmct IDI_HOST.bmp\} Reachable host - host is reachable.
+\par \fi0\li0 \bullet \{bmct IDI_GOINGDOWN.bmp\} Worrisome host - host is dying.
+\par \fi0\li0 \bullet \{bmct IDI_HOSTDOWN.bmp\} Unreachable host - host is unreachable.\pard
+\par\sa120\sb120\qj\pard \f1\fs18\sb120 Activity pane:\pard
+\par \fi0\li0 \bullet \{bmct green.bmp\} Good response time
+\par \fi0\li0 \bullet \{bmct yellow.bmp\} Average response time
+\par \fi0\li0 \bullet \{bmct red.bmp\} Critical response time\pard
+\page
+} \ No newline at end of file
diff --git a/help/bigbrother.xml b/help/bigbrother.xml
new file mode 100644
index 0000000..d83ae43
--- a/dev/null
+++ b/help/bigbrother.xml
@@ -0,0 +1,229 @@
+<?xml version="1.0"?>
+<winhelp>
+ <topic id="About" title="About Big Brother" keywords="about">
+ <heading scroll="no">About <kin>Big Brother</kin></heading>
+ <dedication>dedicated to Kundel</dedication>
+ <p><kin>Big Brother</kin> is a program designed to monitor your IP-network activities. it gives you a comprehensive picture of what happened to any point on the Net that you put in. Just <a href="#Add">add</a> this point by specifying it's IP address or hostname and optional short description (for your information only).</p>
+ <p>The hosts are organized into a hierarchical tree so that you may configure your network picture according to your needs and imagination. Most of the father host properties are inherited by his children unless you wish to specify child's settings explicitly.</p>
+ <p>Every specified period of time <kin>Big Brother</kin> will send echo request to every host. And wait for response for at most specified <a href="#timeOutHIDD_PROPS_SETTINGS">timeout</a>.</p>
+ <p>Results are presented in a graphical form in the lower pane. Each line of the lower window is related to specific host which is shown on the tooltip when you move your mouse over the graphics. Host activities are also <a href="#fileHIDD_PREFS">logged into file</a>.</p>
+ <p>Your current <a href="#HIDD_PREFS">preferences</a> and network tree are automatically saved on Windows shutdown (unless specified otherwise) and may be <a href="#autosaveHIDD_PREFS">autosaved</a> every specified amount of minutes. Most recently used <a href="#MRUFile">file</a> is <a href="#HID_FILE_AUTOLOAD">automatically loaded</a> at <kin>Big Brother</kin>'s startup unless you don't want it.</p>
+ <p>You can also hide <kin>Big Brother</kin> into your notify tray so that it won't occupy more than 16x16 square of your precious windows' desktop. Just click <image source="bbullet.bmp"/> in your notify tray or select <a href="#HID_VIEW_MAINWINDOW">View/Main Window</a> from menu. Click <image source="bbullet.bmp"/> again to restore <kin>Big Brother</kin> to its full size.</p>
+ <p/>
+ <p><b><i>Enjoy!</i></b></p>
+ <license years="1996, 2002"/>
+ <credits/>
+ </topic>
+ <topic id="News" title="What's New">
+ <newsfor version="1.5" date="August 19th, 2002">
+ <ni>License change and opening the source code</ni>
+ <ni>Made it work with Win2k and friends</ni>
+ <ni>Added kinwide installer</ni>
+ </newsfor>
+ </topic>
+ <topic id="Using" title="Using Big Brother">
+ <heading scroll="no">Using <kin>Big Brother</kin></heading>
+ <p>Using <kin>Big Brother</kin> consists of two parts - designing your network tree and monitoring it's activity. The latter takes no effort of yours.</p>
+ <p>To design the network layout is to put your hosts into Network Tree pane. To <a href="#HID_BROTHERS_NEW">add a child host</a> to the current just press insert or Select Brothers/Add child from menu. To <a href="#HID_BROTHERS_ADDBROTHER">add a brother</a> of the current host select Brothers/Add brother from menu. (note: You can't add brother to the root node)</p>
+ <p>You may also show <a href="#HostProps">properties</a> dialog box by selecting View/Host Properties menu. <a href="#HostProps">Properties</a> dialog box also pops up automatically whenever you press <b>Enter</b> in the tree view pane.</p>
+ <p>Monitoring your network activities is even easier. You just relax and watch the screen (or listen to your speakers if you have ones). Network activities are reflected using the lower host activity pane and icons in the tree view. The possible states of the host are:</p>
+ <ul>
+ <li><image source="IDI_NOHOST.bmp"/> <b>Network</b> - you haven't specified host name or ip address for this host. The only reason that makes sense is that you probably want to use this node as a father for family of hosts.</li>
+ <li><image source="IDI_PINGING.bmp"/> <b>In progress</b> - checking of this host is in progress.</li>
+ <li><image source="IDI_HOST.bmp"/> <b>Reachable host</b> - this host is reachable and you have no reason to worry about it.</li>
+ <li><image source="IDI_GOINGDOWN.bmp"/> <b>Worrisome host</b> - this host was reported as unreachable, but less than for specified <a href="#HIDD_PROPS_SETTINGS">retries</a> times.</li>
+ <li><image source="IDI_HOSTDOWN.bmp"/> <b>Unreachable host</b> - this host is known as unreachable for a long time. Whenever the host enters or leaves this state specified <a href="#HIDD_PROPS_ACTION">actions</a> are taken.</li>
+ </ul>
+ <p>Lower pane shows a histogram of response times for a <a href="#logLengthHIDD_PREFS">specified</a> amount of time. Histograms are shown for current host and it's descendants. Hidden (collapsed) children are not shown in activity pane. When you move your mouse over histogram tooltip shows the host name and host address for the corresponding host. If you also hold left mouse button or Ctrl key it will also show you the time corresponding to the point you point at. If you hold Shift key it will also show the Round Trip Time.</p>
+ <p>Histogram shows the Round Trip Time in the following colours:</p>
+ <ul>
+ <li><image source="green.bmp"/> Host's response time is less than 1/3 of the <a href="#timeOutHIDD_PROPS_SETTINGS">specified</a> timeout.</li>
+ <li><image source="yellow.bmp"/> Host's response time is more than 1/3, but less then 2/3 of the <a href="#timeOutHIDD_PROPS_SETTINGS">specified</a> timeout.</li>
+ <li><image source="red.bmp"/> Host's response time is more than 2/3 of the <a href="#timeOutHIDD_PROPS_SETTINGS">specified</a> timeout.</li>
+ </ul>
+ </topic>
+ <topic id="HIDD_PREFS" title="Preferences">
+ <heading scroll="no">Preferences</heading>
+ <p>The Preferences dialog box allows you to change global system preferences which are:</p>
+ <ul>
+ <li><b>On windows shutdown save without confirmation</b> - you may specify how does <kin>Big Brother</kin> act on windows shutdown, whether to save current tree without a confirmation or not.</li>
+ <li><a name="autosaveHIDD_PREFS"/>Autosave - the interval at wich <kin>Big Brother</kin> will save current tree automatically. Specify 0 if you don't want to use this feature.</li>
+ <li>Ping data packet size - the size of echo request packet in bytes.</li>
+ <li>Ping .. hosts simultaneously - number of hosts to ping at a time. If you have a big network to monitor and have a slow computer or connection, you may want to limit number of hosts to ping simultaneously.</li>
+ <li><a name="fileHIDD_PREFS"/>Log to file - Here is where you specify the name of the file to log hosts activities to.</li>
+ <li><a name="logLengthHIDD_PREFS"/>Show last .. minutes in activity pane - This is the time length of your graphical pane window.</li>
+ <li><a name="storeActivityHIDD_PREFS"/>Store activity pane data - This lets you specify where to store activity pane data when saving file or not.</li>
+ </ul>
+ </topic>
+ <topic id="HID_VIEW_HOSTPROPERTIES">
+ <heading scroll="no">Host Properties</heading>
+ <p>You may show/hide Host Properties dialog box using this menu command</p>
+ <p><a name="HostProps"/>Host Properties dialog box consists of three tabs. See <a href="#HIDD_PROPS_GENERAL">General tab</a>, <a href="#HIDD_PROPS_SETTINGS">Settings tab</a> and <a href="#HIDD_PROPS_ACTION">Action tab</a> for further details.</p>
+ </topic>
+ <topic id="HID_BROTHERS_NEW">
+ <heading scroll="no">Add new host (child to current)</heading>
+ <p>You can add new host into your network using this menu command. New host will be the child to current.</p>
+ </topic>
+ <topic id="HID_FILE_AUTOLOAD">
+ <heading scroll="no">Autoload</heading>
+ <p>You may specify whether you want Big Brother to load most recently used file at the startup or not.</p>
+ </topic>
+ <topic id="HIDD_PROPS_ACTION" title="Action tab">
+ <heading scroll="no">Action</heading>
+ <p>Using action tab of <a href="#HostProps">host properties</a> dialog box you may specify the actions to be taken whenever host changes its state from up to down and vice versa.</p>
+ <ul>
+ <li>Override action - You may specify if you want this host to specify some specific actions to take or if you want it to act as it's parent does.</li>
+ <li>Going down - Actions to take whenever host goes down (is known as unreachable for <a href="#retriesHIDD_PROPS_SETTINGS">retries</a> times in a row). See <a href="#Action">below</a> for details.</li>
+ <li>Going up - Actions to take whenever host becomes reachable after it is considered to be down.</li>
+ </ul>
+ <p><a name="Action"/>Possible actions are:</p>
+ <ul>
+ <li>Play a sound - Plays a sound. You may specify a .wav file or use one of the predefined sounds which are
+ <ul>
+ <li>(host-up) - Default sound indicating host recovering from crash</li>
+ <li>(host-down) - Default sound indicating crashing host</li>
+ <li>(system-ok) - System sound as defined in Control Panel/Sounds 'Asterisk'</li>
+ <li>(system-critical) - System sound as defined in Control Panel/Sounds 'Critical Stop'</li>
+ </ul>
+ </li>
+ <li>Run custom program - Run custom program. The following special sequences are defined:
+ <ul>
+ <li>%h - Host name</li>
+ <li>%d - Host description</li>
+ <li>%% - % sign</li>
+ </ul>
+ </li>
+ </ul>
+ </topic>
+ <topic id="HID_VIEW_MAINWINDOW">
+ <heading scroll="no">Main Window</heading>
+ <p>You may hide <kin>Big Brother</kin>'s main window using this command. You may get the window back by clicking the <image source="bbullet.bmp"/> in your notification tray area.</p>
+ </topic>
+ <topic id="HIDD_PROPS_GENERAL" title="General tab">
+ <heading scroll="no">General tab</heading>
+ <p>General tab of <a href="#HostProps">Host Properties</a> dialog box lets you specify the following:</p>
+ <ul>
+ <li>Host - either host name or ip address of host you want to monitor.</li>
+ <li>Description - a short description of the host. The name you want to refer to this host by in the future.</li>
+ <li>Log Activity - You may specify if you do or don't want to log changes of this host's state into <a href="#fileHIDD_PREFS">file</a>.</li>
+ </ul>
+ </topic>
+ <topic id="HID_FILE_PAUSE">
+ <heading scroll="no">Pause</heading>
+ <p>This command lets you temporarily disable monitoring of hosts. <kin>Big Brother</kin> will just sit and wait until you let him do his work.</p>
+ </topic>
+ <topic id="HIDD_PROPS_SETTINGS" title="Settings tab">
+ <heading scroll="no">Settings tab</heading>
+ <p>Settings tab of <a href="#HostProps">Host Properties</a> dialog box lets you specify the following:</p>
+ <ul>
+ <li>Ping intervals - check this if you want to specify intervals for this host explicitly. If you don't - this host will use parent's settings. You can't uncheck this for root node.
+ <ul>
+ <li>When the host is known as reachable - time to wait until next ping if the last ping succeeded.</li>
+ <li>When the host is known as unreachable - time to wait until next ping If the last ping failed.</li>
+ </ul>
+ </li>
+ <li><a name="timeOutHIDD_PROPS_SETTINGS"/>Maximum ping reply timeout - amount of milliseconds to wait for echo reply.</li>
+ <li><a name="retriesHIDD_PROPS_SETTINGS"/>Maximum retries count - number of failed pings before Big Brother considers the host is down.</li>
+ </ul>
+ </topic>
+ <topic id="HID_BROTHERS_DELETE">
+ <heading scroll="no">Delete</heading>
+ <p>Use this feature to remove current host and all of its children. You can't remove the root node, although you may remove all hosts but root using this command.</p>
+ </topic>
+ <topic id="HID_BROTHERS_ADDBROTHER">
+ <heading scroll="no">Add new host (brother to current)</heading>
+ <p>You can add new host into your network using this menu command. New host will be a brother to current. (note: You can't add brother to the root node)</p>
+ </topic>
+ <topic id="HID_FILE_NEW">
+ <heading scroll="no">New</heading>
+ <p>Create the whole new network tree. This command will remove all hosts you currently have.</p>
+ </topic>
+ <topic id="HID_FILE_OPEN">
+ <heading scroll="no">Open</heading>
+ <p>Open previously <a href="#HID_FILE_SAVE">saved</a> network file.</p>
+ </topic>
+ <topic id="HID_FILE_SAVE">
+ <heading scroll="no">Save</heading>
+ <p>Save your current network layout to disk file for future <a href="#HID_FILE_OPEN">retrieval</a></p>
+ </topic>
+ <topic id="HID_FILE_SAVE_AS">
+ <heading scroll="no">Save as</heading>
+ <p>Save your current network layout under different name.</p>
+ </topic>
+ <topic id="HID_APP_EXIT">
+ <heading scroll="no">Exit</heading>
+ <p>Leave <kin>Big Brother</kin>. you will be prompted if you have unsaved information.</p>
+ </topic>
+ <topic id="HID_VIEW_TOOLBAR">
+ <heading scroll="no">Toolbar</heading>
+ <p>Use this command to hide or show toolbar.</p>
+ </topic>
+ <topic id="HID_VIEW_STATUS_BAR">
+ <heading scroll="no">Status bar</heading>
+ <p>Use this command to hide or show status bar.</p>
+ </topic>
+ <topic id="HID_WINDOW_SPLIT">
+ <heading scroll="no">Adjust Splitter</heading>
+ <p>Adjust position of splitter between tree view pane and host activity pane</p>
+ </topic>
+ <topic id="HID_HELP_FINDER">
+ <heading scroll="no">Help Topics</heading>
+ <p>Show help topics.</p>
+ </topic>
+ <topic id="MRUFile">
+ <heading scroll="no">Most Recently Used Files</heading>
+ <p>The menu commands right before the Exit allows you to quickly retrieve one of the most recently used files.</p>
+ </topic>
+ <topic id="HID_INDICATOR_PINGBAR">
+ <heading scroll="no"><kin>Big Brother</kin> Activity indicator</heading>
+ <p><kin>Big Brother</kin> activity indicator is a small red triangle spinning and turning to black whenever Big Brother is busy pinging hosts.</p>
+ </topic>
+ <topic id="AFX_HIDW_STATUS_BAR">
+ <heading scroll="no">Status bar</heading>
+ <p>Sometimes you may see some useful messages in there. For instance, long descriptions of menu items whenever you are exploring the menu.</p>
+ </topic>
+ <topic id="HID_CONTEXT_HELP">
+ <heading scroll="no">Context help</heading>
+ <p>Move mouse cursor with question mark wherever you want and get help for something you click on.</p>
+ </topic>
+ <topic id="HID_SC_MAXIMIZE">
+ <heading scroll="no">Maximize</heading>
+ <p>This option will maximize <kin>Big Brother</kin> window to full screen.</p>
+ </topic>
+ <topic id="HID_SC_MOVE">
+ <heading scroll="no">Move</heading>
+ <p>This option will let you move <kin>Big Brother</kin> window around the screen.</p>
+ </topic>
+ <topic id="HID_SC_SIZE">
+ <heading scroll="no">Size</heading>
+ <p>This option will let you resize <kin>Big Brother</kin>'s window</p>
+ </topic>
+ <topic id="HID_SC_RESTORE">
+ <heading scroll="no">Restore</heading>
+ <p>You option may use this to restore <kin>Big Brother</kin>'s window to its original size after you've maximized it.</p>
+ </topic>
+ <topic id="HID_SC_CLOSE">
+ <heading scroll="no">Close</heading>
+ <p>This option does about the same as the <a href="#HID_APP_EXIT">Exit</a> menu command does.</p>
+ </topic>
+ <topic id="Add" title="Add new host">
+ <heading scroll="no">Add new host</heading>
+ <p>You may add new hosts for monitoring in two ways - by adding it <a href="#HID_BROTHERS_NEW">as a child</a> or <a href="#HID_BROTHERS_ADDBROTHER">as a brother</a> to current one.</p>
+ </topic>
+ <topic id="HID_HELP_LEGEND">
+ <p>Tree view pane:</p>
+ <ul>
+ <li><image source="IDI_NOHOST.bmp"/> Network - no particular host specified.</li>
+ <li><image source="IDI_PINGING.bmp"/> In progress - host is being checked.</li>
+ <li><image source="IDI_HOST.bmp"/> Reachable host - host is reachable.</li>
+ <li><image source="IDI_GOINGDOWN.bmp"/> Worrisome host - host is dying.</li>
+ <li><image source="IDI_HOSTDOWN.bmp"/> Unreachable host - host is unreachable.</li>
+ </ul>
+ <p>Activity pane:</p>
+ <ul>
+ <li><image source="green.bmp"/> Good response time</li>
+ <li><image source="yellow.bmp"/> Average response time</li>
+ <li><image source="red.bmp"/> Critical response time</li>
+ </ul>
+ </topic>
+</winhelp>
diff --git a/help/green.bmp b/help/green.bmp
new file mode 100644
index 0000000..1e6dcde
--- a/dev/null
+++ b/help/green.bmp
Binary files differ
diff --git a/help/red.bmp b/help/red.bmp
new file mode 100644
index 0000000..0625b12
--- a/dev/null
+++ b/help/red.bmp
Binary files differ
diff --git a/help/yellow.bmp b/help/yellow.bmp
new file mode 100644
index 0000000..76410b6
--- a/dev/null
+++ b/help/yellow.bmp
Binary files differ
diff --git a/install/custom.rch b/install/custom.rch
new file mode 100644
index 0000000..f28380c
--- a/dev/null
+++ b/install/custom.rch
@@ -0,0 +1,10 @@
+#ifdef STATI_K
+bigbro.ex_ rcdata discardable "../releast/bigbro.ex_"
+#else
+bigbro.ex_ rcdata discardable "../release/bigbro.ex_"
+#endif
+bigbro.cn_ rcdata discardable "../release/bigbro.cn_"
+bigbro.hl_ rcdata discardable "../release/bigbro.hl_"
+#ifdef K_ANNED
+mfc42.dl_ rcdata discardable "../redist/mfc42.dl_"
+#endif
diff --git a/install/install.cpp b/install/install.cpp
new file mode 100644
index 0000000..0ab8fa9
--- a/dev/null
+++ b/install/install.cpp
@@ -0,0 +1,68 @@
+#include "resource.h"
+#include "../shared-code/install.h"
+
+#define KINSHORT "BigBro"
+#define KINNAME "Big Brother"
+#define VERSION "1.5"
+
+BOOL Install(void)
+{
+STRING dPath = strFETCH_REG_KEY(HKEY_LOCAL_MACHINE,"Software\\Klever Group, Inc.",KINSHORT "Path");
+STRING kPath = strFETCH_REG_KEY(HKEY_LOCAL_MACHINE,"Software\\Klever Group, Inc.","KINPath");
+LPCSTR qPath = ((LPCSTR)dPath)?(LPCSTR)dPath:(((LPCSTR)kPath)?(LPSTR)kPath:"C:\\Program Files\\Klever\\Nothings");
+STRING path = REQUESTPATH(" " KINNAME " " VERSION,"\nEnter destination path:",qPath);
+ if(!path)
+ return NULL;
+
+#ifdef K_ANNED
+STRING sysDir(_MAX_PATH);
+ GetSystemDirectory(sysDir,_MAX_PATH);
+ INSTALLFILE("mfc42.dl_",sysDir,"mfc42.dll");
+#endif
+
+ MAKE_PATH(path);
+STRING shortPath = GET_SHORT_PATH(path);
+ if(!shortPath){
+ MessageBox(NULL,"Failed to install " KINNAME " " VERSION " in specified directory",NULL,MB_ICONERROR|MB_OK);
+ return FALSE;
+ }
+
+ if(!(
+ INSTALLFILE("bigbro.ex_",path,"bigbro.exe") &&
+ INSTALLFILE("bigbro.hl_",path,"bigbro.hlp") &&
+ INSTALLFILE("bigbro.cn_",path,"bigbro.cnt")
+ )){
+ MessageBox(NULL,"Failed to install " KINNAME " " VERSION " in specified directory",NULL,MB_ICONERROR|MB_OK);
+ return FALSE;
+ }
+ ADDMENU("Accessories\\Klever Co.",KINNAME,path,"bigbro.exe");
+
+ strSET_REG_KEY(HKEY_LOCAL_MACHINE,"Software\\Klever Group, Inc.",KINSHORT "Path",path);
+ strSET_REG_KEY(HKEY_LOCAL_MACHINE,"Software\\Klever Group, Inc.","KINPath",path);
+
+FILE* inf=CREATE_INF_FILE(path,KINSHORT ".INF");
+ if(!inf){
+ MessageBox(NULL,"Failed to install " KINNAME " " VERSION,NULL,MB_ICONERROR|MB_OK);
+ return FALSE;
+ }
+ INF_FILE_HEADER(inf);
+ INF_FILE_SECTION(inf,"Uninstall");
+ fprintf(inf,"AddReg=kFiles\nDelReg=kReg\nUpdateInis=kMenu\n");
+ INF_FILE_SECTION(inf,"kFiles");
+ INF_REMOVE_ROOT(inf,KINSHORT "Files",path);
+ INF_REMOVE_FILE(inf,KINSHORT "Files","bigbro.exe");
+ INF_REMOVE_HELP_FILE(inf,KINSHORT "Files","bigbro");
+ INF_REMOVE_FILE(inf,KINSHORT "Files","bigbro.inf");
+ INF_FILE_SECTION(inf,"kReg");
+ INF_UNINSTALL_REG(inf,KINSHORT);
+ INF_FILE_SECTION(inf,"kMenu");
+ INF_MENU_GROUP(inf,1,"Accessories\\Klever Co.");
+ INF_MENU_ITEM(inf,1,KINNAME);
+ fclose(inf);
+
+ REG_UNINSTALL_COMMAND(KINSHORT,"Klever " KINNAME " " VERSION,shortPath,KINSHORT".INF","Uninstall");
+
+ MessageBox(NULL,KINNAME" " VERSION " installed successfully, you may now run it from Programs/Accessories/Klever Co. menu or remove it using Control Panel Add/Remove Programs applet."," Rejoice!",MB_ICONINFORMATION|MB_OK);
+
+ return TRUE;
+}
diff --git a/install/install.rc b/install/install.rc
new file mode 100644
index 0000000..12740e5
--- a/dev/null
+++ b/install/install.rc
@@ -0,0 +1,182 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+#if defined(APSTUDIO_INVOKED) || defined(FALSE)
+#if defined(APSTUDIO_INVOKED)
+IDD_INSTALLING$(FALSE) DIALOGEX 0, 0, 200, 74
+#else
+IDD_INSTALLING DIALOGEX 0, 0, 200, 74
+#endif
+STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ PUSHBUTTON "Cancel",IDCANCEL,143,53,50,14,BS_CENTER | BS_VCENTER |
+ BS_NOTIFY | BS_FLAT,WS_EX_DLGMODALFRAME
+ CONTROL "Animate1",IDC_DISKS,"SysAnimate32",ACS_TRANSPARENT |
+ ACS_AUTOPLAY | WS_TABSTOP,161,7,32,32
+ LTEXT "",IDC_STATE,7,7,150,32,SS_NOPREFIX | SS_NOTIFY
+ CONTROL "Progress1",IDC_PROGRESS,"msctls_progress32",0x0,7,45,
+ 186,7,WS_EX_DLGMODALFRAME
+END
+#endif
+
+IDD_PATH DIALOGEX 0, 0, 255, 73
+STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_CENTER | WS_POPUP |
+ WS_VISIBLE | WS_CAPTION
+EXSTYLE WS_EX_TOOLWINDOW | WS_EX_CLIENTEDGE
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ LTEXT "",IDC_PROMPT,7,7,241,30
+ EDITTEXT IDC_PATH,7,37,195,12,ES_AUTOHSCROLL
+ PUSHBUTTON "B&rowse..",IDC_BROWSE,208,37,40,12
+ DEFPUSHBUTTON "OK",IDOK,69,52,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,135,52,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ "IDD_INSTALLING$(FALSE)", DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 193
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 67
+ HORZGUIDE, 39
+ END
+
+ IDD_PATH, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 248
+ VERTGUIDE, 202
+ VERTGUIDE, 208
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 66
+ HORZGUIDE, 37
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""custom.rch""\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON ICON DISCARDABLE "../shared-data/install-icon.ico"
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,5,0,0
+ PRODUCTVERSION 1,5,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Klever Group (http://www.klever.net/)\0"
+ VALUE "FileDescription", "INSTALL: Big Brother, network monitoring tool\0"
+ VALUE "FileVersion", "1, 5, 0, 0\0"
+ VALUE "InternalName", "INSTALL\0"
+ VALUE "LegalCopyright", "Copyright 1996, 2002 Klever Group (http://www.klever.net/)\0"
+ VALUE "LegalTrademarks", "Klever Group (http://www.klever.net/)\0"
+ VALUE "OriginalFilename", "INSTALL.EXE\0"
+ VALUE "ProductName", "Big Brother\0"
+ VALUE "ProductVersion", "1, 5, 0, 0\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "custom.rch"
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/install/resource.h b/install/resource.h
new file mode 100644
index 0000000..ebf7991
--- a/dev/null
+++ b/install/resource.h
@@ -0,0 +1,24 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by Install.rc
+//
+#define IDD_INSTALLING 101
+#define IDD_PATH 102
+#define IDI_ICON 105
+#define IDC_DISKS 1000
+#define IDC_STATE 1001
+#define IDC_PROGRESS 1002
+#define IDC_PROMPT 1003
+#define IDC_PATH 1004
+#define IDC_BROWSE 1005
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 107
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1006
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/makehelp.bat b/makehelp.bat
new file mode 100644
index 0000000..e78c2d6
--- a/dev/null
+++ b/makehelp.bat
@@ -0,0 +1,35 @@
+@echo off
+REM -- First make map file from Microsoft Visual C++ generated resource.h
+echo // MAKEHELP.BAT generated Help Map file. Used by BIGBRO.HPJ. >"help\bigbro.hm"
+echo. >>"help\bigbro.hm"
+echo // Commands (ID_* and IDM_*) >>"help\bigbro.hm"
+makehm ID_,HID_,0x10000 IDM_,HIDM_,0x10000 resource.h >>"help\bigbro.hm"
+echo. >>"help\bigbro.hm"
+echo // Prompts (IDP_*) >>"help\bigbro.hm"
+makehm IDP_,HIDP_,0x30000 resource.h >>"help\bigbro.hm"
+echo. >>"help\bigbro.hm"
+echo // Resources (IDR_*) >>"help\bigbro.hm"
+makehm IDR_,HIDR_,0x20000 resource.h >>"help\bigbro.hm"
+echo. >>"help\bigbro.hm"
+echo // Dialogs (IDD_*) >>"help\bigbro.hm"
+makehm IDD_,HIDD_,0x20000 resource.h >>"help\bigbro.hm"
+echo. >>"help\bigbro.hm"
+echo // Frame Controls (IDW_*) >>"help\bigbro.hm"
+makehm IDW_,HIDW_,0x50000 resource.h >>"help\bigbro.hm"
+REM -- Make help for Project BIGBROTHER
+
+
+echo Building RTF file
+xsltproc -o help/bigbrother.rtf shared-code/kinhelp.xsl help/bigbrother.xml
+echo Building Win32 Help files
+start /wait hcrtf -x "help\bigbrother.hpj"
+echo.
+if exist Debug\nul copy "help\bigbro.hlp" Debug
+if exist Debug\nul copy "help\bigbro.cnt" Debug
+if exist Release\nul copy "help\bigbro.hlp" Release
+if exist Release\nul copy "help\bigbro.cnt" Release
+if exist Releast\nul copy "help\bigbro.hlp" Releast
+if exist Releast\nul copy "help\bigbro.cnt" Releast
+echo.
+
+
diff --git a/res/3angle.avi b/res/3angle.avi
new file mode 100644
index 0000000..5dcd036
--- a/dev/null
+++ b/res/3angle.avi
Binary files differ
diff --git a/res/BigBrotherDoc.ico b/res/BigBrotherDoc.ico
new file mode 100644
index 0000000..3fba5b7
--- a/dev/null
+++ b/res/BigBrotherDoc.ico
Binary files differ
diff --git a/res/bigbrother.ico b/res/bigbrother.ico
new file mode 100644
index 0000000..cfca70d
--- a/dev/null
+++ b/res/bigbrother.ico
Binary files differ
diff --git a/res/bigbrother.rc2 b/res/bigbrother.rc2
new file mode 100644
index 0000000..4d9fb32
--- a/dev/null
+++ b/res/bigbrother.rc2
@@ -0,0 +1,13 @@
+//
+// BIGBROTHER.RC2 - resources Microsoft Visual C++ does not edit directly
+//
+
+#ifdef APSTUDIO_INVOKED
+ #error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Add manually edited resources here...
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/res/goingdown.ico b/res/goingdown.ico
new file mode 100644
index 0000000..ca31de6
--- a/dev/null
+++ b/res/goingdown.ico
Binary files differ
diff --git a/res/host-down.wav b/res/host-down.wav
new file mode 100644
index 0000000..9f074db
--- a/dev/null
+++ b/res/host-down.wav
Binary files differ
diff --git a/res/host-up.wav b/res/host-up.wav
new file mode 100644
index 0000000..73aecfd
--- a/dev/null
+++ b/res/host-up.wav
Binary files differ
diff --git a/res/host.ico b/res/host.ico
new file mode 100644
index 0000000..494ba76
--- a/dev/null
+++ b/res/host.ico
Binary files differ
diff --git a/res/hostdown.ico b/res/hostdown.ico
new file mode 100644
index 0000000..68912d2
--- a/dev/null
+++ b/res/hostdown.ico
Binary files differ
diff --git a/res/junktoolbar.bmp b/res/junktoolbar.bmp
new file mode 100644
index 0000000..001fca2
--- a/dev/null
+++ b/res/junktoolbar.bmp
Binary files differ
diff --git a/res/maintoolbar.bmp b/res/maintoolbar.bmp
new file mode 100644
index 0000000..e2e21ad
--- a/dev/null
+++ b/res/maintoolbar.bmp
Binary files differ
diff --git a/res/nohost.ico b/res/nohost.ico
new file mode 100644
index 0000000..58267ed
--- a/dev/null
+++ b/res/nohost.ico
Binary files differ
diff --git a/res/pending.ico b/res/pending.ico
new file mode 100644
index 0000000..4c4a71c
--- a/dev/null
+++ b/res/pending.ico
Binary files differ
diff --git a/res/pinging.ico b/res/pinging.ico
new file mode 100644
index 0000000..0e0d835
--- a/dev/null
+++ b/res/pinging.ico
Binary files differ
diff --git a/resource.h b/resource.h
new file mode 100644
index 0000000..06de53b
--- a/dev/null
+++ b/resource.h
@@ -0,0 +1,131 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by BigBrother.rc
+//
+#define IDD_ABOUTBOX 100
+#define IDC_TRAYICON 101
+#define IDD_PROPS_SETTINGS 102
+#define ID_PINGBAR 102
+#define IDD_PROPS_GENERAL 103
+#define TM_CHECK 103
+#define IDP_SOCKETS_INIT_FAILED 104
+#define IDD_PROPS_ACTION 104
+#define IDS_PROPS_TITLE 105
+#define IDS_LOG_DOLOG 106
+#define IDS_LOG_DONTLOG 107
+#define IDS_LOG_ASKBIGBROTHER 108
+#define IDS_NODESC 109
+#define IDS_PS_FAILEDTORESOLVE 110
+#define IDS_PS_UNABLETOICMP 111
+#define IDS_PS_INTERNALERROR 112
+#define IDS_PS_NETUNREACHABLE 113
+#define IDS_PS_HOSTUNREACHABLE 114
+#define IDS_PS_PROTUNREACHABLE 115
+#define IDS_PS_PORTUNREACHABLE 116
+#define IDS_PS_NORESOURCES 117
+#define IDS_PS_HWERROR 118
+#define IDS_PS_BIGPACKET 119
+#define IDS_PS_TIMEOUT 120
+#define IDS_PS_BADROUTE 121
+#define IDS_PS_TTLEXPTRANSIT 122
+#define IDS_PS_TTLEXPREASM 123
+#define IDS_PS_IPARAMP 124
+#define IDS_PS_SOURCEQUENCH 125
+#define IDS_PS_BIGOPTION 126
+#define IDS_PS_BADDEST 127
+#define IDR_MAINFRAME 128
+#define IDR_BIGBROTYPE 129
+#define IDS_PS_UNKNOWNERROR 129
+#define IDS_REGISTRYKEY 130
+#define IDI_NOHOST 131
+#define IDS_AVIEW_NOTIP 131
+#define IDI_PENDING 132
+#define IDS_AVIEW_SHORTTIP 132
+#define IDI_HOST 133
+#define IDM_POPUPS 133
+#define IDS_AVIEW_TIP_TIMEFORMAT 133
+#define IDI_PINGING 134
+#define IDR_PINGBAR 134
+#define IDS_AVIEW_TIP_UNPINGED 134
+#define IDI_GOINGDOWN 135
+#define IDR_JUNKACCELERATOR 135
+#define IDS_AVIEW_TIP_UNREACHABLE 135
+#define IDI_HOSTDOWN 136
+#define IDR_JUNKTOOLBAR 136
+#define IDS_AVIEW_TIP_RTTREPORT 136
+#define IDS_ROOTNODENAME 137
+#define IDS_WAVFILTER 138
+#define IDW_HOST_UP 138
+#define IDW_HOST_DOWN 139
+#define IDS_ACTION_HOST_UP 139
+#define IDS_ACTION_HOST_DOWN 140
+#define IDI_PREPLAY 140
+#define IDI_BROWSESOUND 141
+#define IDD_PREFS 141
+#define IDS_LOGFILTER 141
+#define IDS_LOG_HOSTUP 142
+#define IDS_LOG_HOSTDOWN 143
+#define IDS_LOG_DATEFORMAT 144
+#define IDS_LOGFILE_SELECT 145
+#define IDS_SOUND_SELECT 146
+#define IDS_LOG_LOADFILE 147
+#define IDS_ACTION_SYSTEM_OK 148
+#define IDS_ACTION_SYSTEM_CRITICAL 149
+#define IDC_OVERRIDE_INTERVALS 1000
+#define IDC_PINGINTERVAL_GOOD 1001
+#define IDC_PINGINTERVAL_BAD 1002
+#define IDC_OVERRIDE_TIMEOUT 1003
+#define IDC_PINGTIMEOUT 1004
+#define IDC_HOST 1004
+#define IDC_OVERRIDE_RETRIES 1005
+#define IDC_DESC 1005
+#define IDC_RETRIES 1006
+#define IDC_LOG_ACTIVITY 1006
+#define IDC_OVERRIDE_ACTION 1010
+#define IDC_PLAYASOUND_DOWN 1011
+#define IDC_SOUND_DOWN 1012
+#define IDC_PLAYASOUND_UP 1013
+#define IDC_CUSTOM_DOWN 1014
+#define IDC_PROGRAM_DOWN 1015
+#define IDC_SOUND_UP 1016
+#define IDC_CUSTOM_UP 1017
+#define IDC_PROGRAM_UP 1018
+#define IDC_KLEVERNET 1018
+#define IDC_PREVIEW_SOUND_UP 1020
+#define IDC_PREVIEW_SOUND_DOWN 1021
+#define IDC_SAVEONSHUTDOWN 1021
+#define IDC_BROWSE_SOUND_UP 1022
+#define IDC_AUTOSAVEMINS 1022
+#define IDC_BROWSE_SOUND_DOWN 1023
+#define IDC_AUTOSPIN 1023
+#define IDC_PINGSIZE 1024
+#define IDC_DATASIZESPIN 1025
+#define IDC_MAXTHREADS 1026
+#define IDC_THREADSPIN 1027
+#define IDC_LOGFILE 1028
+#define IDC_BROWSE 1029
+#define IDC_LOGMINS 1030
+#define IDC_LOGMINSPIN 1032
+#define IDC_STOREACTIVITY 1033
+#define ID_BROTHERS_NEW 32771
+#define ID_VIEW_MAINWINDOW 32773
+#define ID_INDICATOR_PINGBAR 32775
+#define ID_BROTHERS_ADDBROTHER 32776
+#define ID_BROTHERS_DELETE 32777
+#define ID_FILE_AUTOLOAD 32782
+#define ID_FILE_PREFERENCES 32783
+#define ID_FILE_PAUSE 32784
+#define ID_VIEW_HOSTPROPERTIES 32789
+#define ID_HELP_LEGEND 32791
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_3D_CONTROLS 1
+#define _APS_NEXT_RESOURCE_VALUE 142
+#define _APS_NEXT_COMMAND_VALUE 32795
+#define _APS_NEXT_CONTROL_VALUE 1034
+#define _APS_NEXT_SYMED_VALUE 104
+#endif
+#endif
diff --git a/shared-code/BTreendex.h b/shared-code/BTreendex.h
new file mode 100644
index 0000000..88109ab
--- a/dev/null
+++ b/shared-code/BTreendex.h
@@ -0,0 +1,595 @@
+#ifndef __BTREENDEX_H
+#define __BTREENDEX_H
+
+#include "Dynamide.h"
+
+namespace Klever {
+
+template<class key,class value,int treeOrder,int cluster>
+class CBTreendex : public CObject {
+public:
+ typedef LONG CBTPageRef;
+ struct CBTRecordRef {
+ CBTPageRef m_Page;
+ INT m_Offset;
+ CBTRecordRef(CBTPageRef page=-1,INT offset=-1) : m_Page(page), m_Offset(offset) {}
+ };
+ class CBTRecord : public CObject {
+ public:
+ CBTPageRef m_ptrLeft;
+ CBTPageRef m_ptrRight;
+ key m_Key;
+ value m_Value;
+ CBTRecord() : m_ptrLeft(-1), m_ptrRight(-1) {}
+ CBTRecord(key& _key,value& _value,CBTPageRef left=-1,CBTPageRef right=-1) : m_Key(_key), m_Value(_value), m_ptrLeft(left), m_ptrRight(right) {}
+ CBTRecord(CBTRecord& r) : m_Key(r.m_Key), m_Value(r.m_Value), m_ptrLeft(r.m_ptrLeft), m_ptrRight(r.m_ptrRight) {}
+
+ CBTRecord& operator=(CBTRecord& r) {m_Key=r.m_Key, m_Value=r.m_Value, m_ptrLeft=r.m_ptrLeft, m_ptrRight=r.m_ptrRight;return *this;}
+
+ void Serialize(CArchive& ar) {
+ if(ar.IsStoring()){
+ ar << m_ptrLeft;
+ ar << m_ptrRight;
+ }else{
+ ar >> m_ptrLeft;
+ ar >> m_ptrRight;
+ }
+ SerializeElements(ar,&m_Key,1);
+ SerializeElements(ar,&m_Value,1);
+ }
+ };
+ class CBTPage : public CArray<CBTRecord,CBTRecord&> {
+ public:
+ void Serialize(CArchive& ar) {
+ int nCount = -1;
+ if(ar.IsStoring()){
+ nCount = GetSize();
+ ar << nCount;
+ }else{
+ nCount = 0;
+ ar >> nCount;
+ RemoveAll();
+ SetSize(nCount);
+ }
+ for(int tmp=0;tmp<nCount;tmp++)
+ ElementAt(tmp).Serialize(ar);
+ }
+ };
+ typedef CDynamide<256,cluster> CBTDyna;
+ typedef CBTDyna::CDynaFile CBTDynaFile;
+ typedef CArray<CBTRecordRef,CBTRecordRef&> CBTRStack;
+
+ CBTDyna m_BT;
+ struct _btCrap {
+ BOOL m_bRootSet;
+ CBTPageRef m_Root;
+ } *m_BTCrap;
+ BOOL m_bRO;
+ CBTRStack m_btStack;
+ CBTPage m_stackTop;
+
+ CBTreendex() {}
+ ~CBTreendex() { Close(); }
+ BOOL Attach(CFile* file,BOOL bAutodelete) {
+ m_bRO = FALSE;
+ if(!m_BT.Attach(file,bAutodelete))
+ return FALSE;
+ return Attach();
+ }
+ BOOL Open(LPCTSTR file,BOOL bReadOnly) {
+ if(!m_BT.Open(file,bReadOnly))
+ return FALSE;
+ m_bRO = bReadOnly;
+ return Attach();
+ }
+ BOOL Create(LPCTSTR file) {
+ try{
+ CFile* f = new CFile(file,CFile::modeCreate|CFile::modeReadWrite|CFile::shareDenyRead|CFile::shareDenyWrite|CFile::typeBinary);
+ ASSERT(f);
+ return Attach(f,TRUE);
+ }catch(CException* e){
+ e->Delete();
+ return FALSE;
+ }
+ }
+ BOOL Attach() {
+ ASSERT(m_BT.IsOpened());
+ m_BTCrap = (_btCrap*)m_BT.m_FB.crap;
+ if(!m_BTCrap->m_bRootSet){
+ m_BTCrap->m_Root = AllocatePage();
+ if(m_BTCrap->m_Root<0)
+ return FALSE;
+ m_BTCrap->m_bRootSet = TRUE;
+ m_BT.Write1stBlock();
+ }
+ return TRUE;
+ }
+ BOOL Close() {
+ m_BT.Close();
+ return TRUE;
+ }
+ BOOL IsOpened() {
+ return m_BT.IsOpened();
+ }
+
+ BOOL Lookup(key& _key,value& value) {
+ if(!IsOpened())
+ return FALSE;
+ ASSERT(m_BTCrap->m_bRootSet);
+ if(!SeekToPage(_key))
+ return FALSE;
+ CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()];
+ if(rr.m_Offset<0)
+ return FALSE;
+ ASSERT(rr.m_Offset<m_stackTop.GetSize());
+ if(_key != m_stackTop[rr.m_Offset].m_Key)
+ return FALSE;
+ value = m_stackTop[rr.m_Offset].m_Value;
+ return TRUE;
+ }
+ BOOL Add(key& _key,value& _value) {
+ if(!IsOpened())
+ return FALSE;
+ ASSERT(m_BTCrap->m_bRootSet);
+ if(!SeekToPage(_key))
+ return FALSE;
+ CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()];
+ CBTRecord nuRecord(_key,_value);
+ if(rr.m_Offset<0){
+ if(m_stackTop.GetSize())
+ nuRecord.m_ptrLeft = m_stackTop[m_stackTop.GetUpperBound()].m_ptrRight;
+ }else if(rr.m_Offset==0){
+ nuRecord.m_ptrRight = m_stackTop[0].m_ptrLeft;
+ }else{
+ nuRecord.m_ptrLeft = m_stackTop[rr.m_Offset-1].m_ptrRight;
+ nuRecord.m_ptrRight = m_stackTop[rr.m_Offset].m_ptrLeft;
+ }
+// ASSERT(rr.m_Offset==0 || (m_stackTop[rr.m_Offset-1].m_Key<_key && m_stackTop[rr.m_Offset-1].m_ptrRight<0));
+// ASSERT(rr.m_Offset<0 || m_stackTop[rr.m_Offset].m_Key>=_key && m_stackTop[rr.m_Offset].m_ptrLeft<0);
+ if(rr.m_Offset>=0 && m_stackTop[rr.m_Offset].m_Key==_key){
+ // Exact match found - just replace.
+ m_stackTop[rr.m_Offset].m_Value = _value;
+ if(!SavePage(rr.m_Page,m_stackTop))
+ return FALSE;
+ return TRUE;
+ }
+ // Split the page and propagate the split if needed..
+ // Insert new element at rr.m_Offset..
+ BOOL nuisnew = TRUE;
+ for(int sp=m_btStack.GetUpperBound();sp>=0;sp--){
+ CBTPageRef opr = m_btStack[sp].m_Page;
+ int iAt = m_btStack[sp].m_Offset;
+ CBTPage op;
+ VERIFY(LoadPage(opr,op));
+ if(iAt<0)
+ iAt = op.GetSize();
+ else{
+ if(op[iAt].m_Key<nuRecord.m_Key)
+ iAt++;
+ ASSERT(iAt==op.GetSize() || op[iAt].m_Key > nuRecord.m_Key);
+ }
+ op.InsertAt(iAt,nuRecord);
+ if(iAt>0)
+ op[iAt-1].m_ptrRight=nuRecord.m_ptrLeft;
+ if(iAt<op.GetUpperBound())
+ op[iAt+1].m_ptrLeft=nuRecord.m_ptrRight;
+ if(op.GetSize()<=treeOrder*2){
+ // This isn't causing overflow
+ VERIFY(SavePage(opr,op));
+ return TRUE;
+ }
+ TRACE0("Split\n");
+ ASSERT(op.GetSize()==(treeOrder*2+1));
+ CBTPageRef npr = AllocatePage();
+ ASSERT(npr>=0);
+ CBTPage np;
+ ASSERT(LoadPage(npr,np));
+ ASSERT(!np.GetSize());
+ nuRecord = op[treeOrder];
+ if(iAt==treeOrder){
+ // We're inserting central element! - drop out the stack top if this is still new one
+ for(int tmp=0;tmp<treeOrder;tmp++)
+ np.InsertAt(tmp,op[tmp]);
+ op.RemoveAt(0,treeOrder+1);
+ nuRecord.m_ptrLeft = npr;
+ nuRecord.m_ptrRight = opr;
+ if(nuisnew)
+ m_btStack.RemoveAt(m_btStack.GetUpperBound());
+ }else{
+ if(iAt<treeOrder){
+ // We're inserting in the left subtree.
+ // Make newpage the right one and forget it.
+ for(int tmp=0;tmp<treeOrder;tmp++)
+ np.InsertAt(tmp,op[tmp+treeOrder+1]);
+ op.RemoveAt(treeOrder,treeOrder+1);
+ nuRecord.m_ptrLeft = opr;
+ nuRecord.m_ptrRight = npr;
+ }else{
+ // We're inserting in the right subtree.
+ // Make newpage the left one, forget it, but also adjust offset in the stack
+ for(int tmp=0;tmp<treeOrder;tmp++)
+ np.InsertAt(tmp,op[tmp]);
+ op.RemoveAt(0,treeOrder+1);
+ nuRecord.m_ptrLeft = npr;
+ nuRecord.m_ptrRight = opr;
+ m_btStack[sp].m_Offset-=treeOrder+1;
+ }
+ // Note that we're not inserting new element anymore.
+ nuisnew = FALSE;
+ }
+ // Do, excessive sanity checks and save pages
+ ASSERT(op.GetSize());
+ ASSERT(np.GetSize());
+ VERIFY(SavePage(opr,op));
+ VERIFY(SavePage(npr,np));
+ }
+ // Here we have root page overflow, which means that we're simply putting new
+ // record in this brand new root page and also inserting this page on the bottom of the stack
+ CBTPageRef nuroot = AllocatePage();
+ ASSERT(nuroot>=0);
+ CBTPage nurpa;
+ ASSERT(LoadPage(nuroot,nurpa));
+ ASSERT(!nurpa.GetSize());
+ nurpa.Add(nuRecord);
+ VERIFY(SavePage(nuroot,nurpa));
+ m_btStack.InsertAt(0,CBTRecordRef(nuroot,0));
+ m_BTCrap->m_Root = nuroot;
+ m_BT.Write1stBlock();
+ return TRUE;
+ }
+ BOOL Delete(key& _key) {
+ if(!IsOpened())
+ return FALSE;
+ ASSERT(m_BTCrap->m_bRootSet);
+ value _value;
+ if(!Lookup(_key,_value))
+ return FALSE;
+ // Found key, check if it's a leaf
+ {
+ CBTRecordRef* rr = &m_btStack[m_btStack.GetUpperBound()];
+ int rrIdx = m_btStack.GetUpperBound();
+ if(m_stackTop[rr->m_Offset].m_ptrLeft>=0){
+ ASSERT(m_stackTop[rr->m_Offset].m_ptrRight>=0);
+ // It isn't - scan for the _next_ key and do dirty deeds
+ m_btStack.Add(CBTRecordRef(m_stackTop[rr->m_Offset].m_ptrRight,0));
+ for(;;){
+ CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()];
+ if(!LoadPage(rr.m_Page,m_stackTop))
+ return FALSE;
+ if(m_stackTop[0].m_ptrLeft<0)
+ break;
+ m_btStack.Add(CBTRecordRef(m_stackTop[0].m_ptrLeft,0));
+ }
+ // We have a leaf node here, replace victim with the first element and kill it.
+ CBTPage uppage;
+ rr = &m_btStack[rrIdx];
+ if(!LoadPage(rr->m_Page,uppage))
+ return FALSE;
+ uppage[rr->m_Offset].m_Key=m_stackTop[0].m_Key; uppage[rr->m_Offset].m_Value=m_stackTop[0].m_Value;
+ m_stackTop.RemoveAt(0);
+ if(!(SavePage(rr->m_Page,uppage) && SavePage(m_btStack[m_btStack.GetUpperBound()].m_Page,m_stackTop)))
+ return FALSE;
+ }else{
+ ASSERT(m_stackTop[rr->m_Offset].m_ptrRight<0);
+ m_stackTop.RemoveAt(rr->m_Offset);
+ if(!SavePage(rr->m_Page,m_stackTop))
+ return FALSE;
+ }
+ }
+ // We have a page to check for underflow at the top of the stack now.
+ for(;;){
+ CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()];
+ if(!LoadPage(rr.m_Page,m_stackTop))
+ return FALSE;
+ if(m_stackTop.GetSize()>=treeOrder || m_btStack.GetSize()==1)
+ return TRUE;
+ CBTRecordRef& rr1 = m_btStack[m_btStack.GetUpperBound()-1];
+ CBTPage daddy;
+ if(!LoadPage(rr1.m_Page,daddy))
+ return FALSE;
+ CBTPageRef nPage = daddy[rr1.m_Offset].m_ptrRight;
+ BOOL bRight=TRUE;
+ if(nPage<0 || nPage==rr.m_Page){
+ nPage = daddy[rr1.m_Offset].m_ptrLeft;
+ bRight = FALSE;
+ }
+ ASSERT(nPage>=0 && nPage!=rr.m_Page);
+ CBTPage neighbor;
+ if(!LoadPage(nPage,neighbor))
+ return FALSE;
+ // Here we have possibly two cases:
+ // 1. Neighboring page can share some data with use, then do share and leave
+ // 2. Neighboring page is of treeorder in size, then merge and propagate
+ if(neighbor.GetSize()>treeOrder){
+ TRACE0("Redistributing..\n");
+ // Borrow some data from there.
+ int toBorrow = neighbor.GetSize()-treeOrder;
+ toBorrow=toBorrow/2+1;
+ ASSERT(toBorrow);
+ if(bRight)
+ m_stackTop.Add(CBTRecord(daddy[rr1.m_Offset].m_Key,daddy[rr1.m_Offset].m_Value,m_stackTop[m_stackTop.GetUpperBound()].m_ptrRight,neighbor[0].m_ptrLeft));
+ else
+ m_stackTop.InsertAt(0,CBTRecord(daddy[rr1.m_Offset].m_Key,daddy[rr1.m_Offset].m_Value,neighbor[neighbor.GetUpperBound()].m_ptrRight,m_stackTop[0].m_ptrLeft));
+ for(toBorrow--;toBorrow;toBorrow--){
+ if(bRight){
+ m_stackTop.Add(neighbor[0]);
+ neighbor.RemoveAt(0);
+ }else{
+ m_stackTop.InsertAt(0,neighbor[neighbor.GetUpperBound()]);
+ neighbor.RemoveAt(neighbor.GetUpperBound());
+ }
+ }
+ daddy[rr1.m_Offset].m_Key = neighbor[bRight?0:neighbor.GetUpperBound()].m_Key; daddy[rr1.m_Offset].m_Value = neighbor[bRight?0:neighbor.GetUpperBound()].m_Value;
+ neighbor.RemoveAt(bRight?0:neighbor.GetUpperBound());
+ if(!(SavePage(rr1.m_Page,daddy) && SavePage(nPage,neighbor) && SavePage(rr.m_Page,m_stackTop)))
+ return FALSE;
+ rr.m_Offset = -1; // *** Point to the next??
+ return TRUE;
+ }
+ TRACE0("Merging..\n");
+ // We need to merge pages here..
+ // We will merge them at stacktop, then we'll discard neighbor guy..
+ if(bRight)
+ m_stackTop.Add(CBTRecord(daddy[rr1.m_Offset].m_Key,daddy[rr1.m_Offset].m_Value,m_stackTop[m_stackTop.GetUpperBound()].m_ptrRight,neighbor[0].m_ptrLeft));
+ else
+ m_stackTop.InsertAt(0,CBTRecord(daddy[rr1.m_Offset].m_Key,daddy[rr1.m_Offset].m_Value,neighbor[neighbor.GetUpperBound()].m_ptrRight,m_stackTop[0].m_ptrLeft));
+ if(bRight){
+ while(neighbor.GetSize()){
+ m_stackTop.Add(neighbor[0]);
+ neighbor.RemoveAt(0);
+ }
+ }else{
+ while(neighbor.GetSize()){
+ m_stackTop.InsertAt(0,neighbor[neighbor.GetUpperBound()]);
+ neighbor.RemoveAt(neighbor.GetUpperBound());
+ }
+ }
+ if(rr1.m_Offset>0)
+ daddy[rr1.m_Offset-1].m_ptrRight=rr.m_Page;
+ if(rr1.m_Offset<daddy.GetUpperBound())
+ daddy[rr1.m_Offset+1].m_ptrLeft=rr.m_Page;
+ daddy.RemoveAt(rr1.m_Offset);
+ if(!(SavePage(rr1.m_Page,daddy) && SavePage(rr.m_Page,m_stackTop)))
+ return FALSE;
+ VERIFY(DeallocatePage(nPage));
+ m_btStack.RemoveAt(m_btStack.GetUpperBound());
+ }
+ return FALSE;
+ }
+ BOOL GoFirst() {
+ if(!IsOpened())
+ return FALSE;
+ ASSERT(m_BTCrap->m_bRootSet);
+ m_btStack.RemoveAll();
+ m_btStack.Add(CBTRecordRef(m_BTCrap->m_Root,-1));
+ for(;;){
+ CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()];
+ if(!LoadPage(rr.m_Page,m_stackTop))
+ return FALSE;
+ if(!m_stackTop.GetSize()){
+ ASSERT(m_btStack.GetSize()==1);
+ return FALSE;
+ }
+ rr.m_Offset = 0;
+ if(m_stackTop[rr.m_Offset].m_ptrLeft<0)
+ return TRUE;
+ m_btStack.Add(CBTRecordRef(m_stackTop[rr.m_Offset].m_ptrLeft,-1));
+ }
+ }
+ BOOL GoLast() {
+ if(!IsOpened())
+ return FALSE;
+ ASSERT(m_BTCrap->m_bRootSet);
+ m_btStack.RemoveAll();
+ m_btStack.Add(CBTRecordRef(m_BTCrap->m_Root,-1));
+ for(;;){
+ CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()];
+ if(!LoadPage(rr.m_Page,m_stackTop))
+ return FALSE;
+ if(!m_stackTop.GetSize()){
+ ASSERT(m_btStack.GetSize()==1);
+ return FALSE;
+ }
+ rr.m_Offset = m_stackTop.GetUpperBound();
+ if(m_stackTop[rr.m_Offset].m_ptrRight<0)
+ return TRUE;
+ m_btStack.Add(CBTRecordRef(m_stackTop[rr.m_Offset++].m_ptrRight,-1));
+ }
+ }
+ BOOL GoNext() {
+ if(!IsOpened())
+ return FALSE;
+ if(!(m_btStack.GetSize() && m_btStack[m_btStack.GetUpperBound()].m_Offset>=0))
+ return FALSE;
+ CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()];
+ if(!LoadPage(rr.m_Page,m_stackTop))
+ return FALSE;
+ ASSERT(rr.m_Offset<m_stackTop.GetSize());
+ if(m_stackTop[rr.m_Offset].m_ptrRight>=0){
+ // Advance pointer in this page and dive into subtree
+ // going left and left until we have nowhere to go.
+// TRACE1("Dive into page %lu",m_stackTop[rr.m_Offset].m_ptrRight);
+ m_btStack.Add(CBTRecordRef(m_stackTop[rr.m_Offset++].m_ptrRight,0));
+ for(;;){
+ CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()];
+ ASSERT(rr.m_Offset==0);
+ if(!LoadPage(rr.m_Page,m_stackTop))
+ return FALSE;
+ if(m_stackTop[rr.m_Offset].m_ptrLeft<0)
+ break;
+// TRACE1(", %lu",m_stackTop[rr.m_Offset].m_ptrLeft);
+ m_btStack.Add(CBTRecordRef(m_stackTop[rr.m_Offset].m_ptrLeft,0));
+ }
+// TRACE0("\n");
+ return TRUE;
+ }else if(rr.m_Offset<m_stackTop.GetUpperBound()){
+ rr.m_Offset++;
+ return TRUE;
+ }
+ // We're at the end of page go up until we're done or we have data.
+ m_btStack.RemoveAt(m_btStack.GetUpperBound());
+// TRACE0("Go up");
+ while(m_btStack.GetSize()){
+ CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()];
+ if(!LoadPage(rr.m_Page,m_stackTop))
+ return FALSE;
+ if(rr.m_Offset<m_stackTop.GetSize()){
+// TRACE0("\n");
+ return TRUE;
+ }
+// TRACE0(", up");
+ m_btStack.RemoveAt(m_btStack.GetUpperBound());
+ }
+// TRACE0("\nBtree is done\n");
+ return FALSE;
+ }
+ BOOL GoPrev() {
+ if(!IsOpened())
+ return FALSE;
+ if(!(m_btStack.GetSize() && m_btStack[m_btStack.GetUpperBound()].m_Offset>=0))
+ return FALSE;
+ CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()];
+ if(!LoadPage(rr.m_Page,m_stackTop))
+ return FALSE;
+ ASSERT(rr.m_Offset<m_stackTop.GetSize());
+ if(m_stackTop[rr.m_Offset].m_ptrLeft>=0){
+ // Dive in and go right and right from the rightmost until
+ // we have nowhere to go.
+ m_btStack.Add(CBTRecordRef(m_stackTop[rr.m_Offset].m_ptrLeft,-1));
+ for(;;){
+ CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()];
+ if(!LoadPage(rr.m_Page,m_stackTop))
+ return FALSE;
+ rr.m_Offset = m_stackTop.GetUpperBound();
+ if(m_stackTop[rr.m_Offset].m_ptrRight<0)
+ return TRUE;
+ m_btStack.Add(CBTRecordRef(m_stackTop[rr.m_Offset++].m_ptrRight,-1));
+ }
+ return TRUE;
+ }else if(rr.m_Offset>0){
+ rr.m_Offset--;
+ return TRUE;
+ }
+ // We're at the leftmost element in page - go up and left until we're
+ // done or we have data.
+ m_btStack.RemoveAt(m_btStack.GetUpperBound());
+ while(m_btStack.GetSize()){
+ CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()];
+ if(!LoadPage(rr.m_Page,m_stackTop))
+ return FALSE;
+ rr.m_Offset--;
+ if(rr.m_Offset>=0)
+ return TRUE;
+ m_btStack.RemoveAt(m_btStack.GetUpperBound());
+ }
+ // No more data - we were at the first element in tree.
+ return FALSE;
+ }
+ BOOL GetThis(key& _key,value& _value) {
+ if(!IsOpened())
+ return FALSE;
+ // *** MORE CHECKING
+ CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()];
+ if(!LoadPage(rr.m_Page,m_stackTop))
+ return FALSE;
+ _key = m_stackTop[rr.m_Offset].m_Key;
+ _value = m_stackTop[rr.m_Offset].m_Value;
+ return TRUE;
+ }
+
+ BOOL SeekToPage(const key& _key) {
+ ASSERT(IsOpened());
+ ASSERT(m_BTCrap->m_bRootSet);
+ m_btStack.RemoveAll();
+ m_btStack.Add(CBTRecordRef(m_BTCrap->m_Root,-1));
+ for(;;){
+ CBTRecordRef& rr = m_btStack[m_btStack.GetUpperBound()];
+ if(!LoadPage(rr.m_Page,m_stackTop))
+ return FALSE;
+ ASSERT(m_stackTop.GetSize() || !m_btStack.GetUpperBound());
+ if(!m_stackTop.GetSize()){
+ rr.m_Offset=-1;
+ return TRUE;
+ }
+ for(rr.m_Offset=0;rr.m_Offset<m_stackTop.GetSize();rr.m_Offset++){
+ if(_key == m_stackTop[rr.m_Offset].m_Key)
+ return TRUE;
+ if(_key < m_stackTop[rr.m_Offset].m_Key){
+ ASSERT(rr.m_Offset==0 || m_stackTop[rr.m_Offset].m_ptrLeft==m_stackTop[rr.m_Offset-1].m_ptrRight);
+ if(m_stackTop[rr.m_Offset].m_ptrLeft<0)
+ return TRUE;
+ m_btStack.Add(CBTRecordRef(m_stackTop[rr.m_Offset].m_ptrLeft,-1));
+ break;
+ }
+ if(rr.m_Offset==m_stackTop.GetUpperBound()){
+ if(m_stackTop[rr.m_Offset].m_ptrRight<0){
+ rr.m_Offset=-1;
+ return TRUE;
+ }
+ m_btStack.Add(CBTRecordRef(m_stackTop[rr.m_Offset].m_ptrRight,-1));
+ break;
+ }
+ }
+ }
+ }
+
+ BOOL LoadPage(CBTPageRef ref,CBTPage& page) {
+ CFile* pageFile = m_BT.OpenFile(ref);
+ if(!pageFile)
+ return FALSE;
+ BOOL rv = TRUE;
+ try{
+ CArchive ar(pageFile,CArchive::load);
+ page.Serialize(ar);
+ if(m_bRO)
+ page.FreeExtra(); // ** ???
+ ar.Close();
+ }catch(CException* e){
+ e->Delete();
+ rv = FALSE;
+ }
+ delete pageFile;
+ return rv;
+ }
+ BOOL SavePage(CBTPageRef ref,CBTPage& page) {
+ CFile* pageFile = m_BT.OpenFile(ref);
+ if(!pageFile)
+ return FALSE;
+ BOOL rv = TRUE;
+ try{
+ CArchive ar(pageFile,CArchive::store);
+ page.Serialize(ar);
+ ar.Close();
+ }catch(CException* e){
+ e->Delete();
+ rv = FALSE;
+ }
+ delete pageFile;
+ return rv;
+ }
+ CBTPageRef AllocatePage() {
+ CBTDynaFile* pageFile = m_BT.CreateFile();
+ if(!pageFile)
+ return -1;
+ CBTPage nothing;
+ CBTPageRef rv = pageFile->GetFile();
+ try{
+ CArchive ar(pageFile,CArchive::store);
+ nothing.Serialize(ar);
+ ar.Close();
+ }catch(CException* e){
+ e->Delete();
+ rv = -1;
+ }
+ delete pageFile;
+ return rv;
+ }
+ BOOL DeallocatePage(CBTPageRef ref) {
+ return m_BT.DeleteFile(ref);
+ }
+
+};
+
+};
+
+#endif // __BTREENDEX_H
diff --git a/shared-code/BellsNWhistles.h b/shared-code/BellsNWhistles.h
new file mode 100644
index 0000000..1de77ae
--- a/dev/null
+++ b/shared-code/BellsNWhistles.h
@@ -0,0 +1,146 @@
+#ifndef __BELLSNWHISTLES_H
+#define __BELLSNWHISTLES_H
+
+class CBellsNWhistles {
+public:
+ class CBang {
+ public:
+ CString m_codeName;
+ enum _bangType {
+ bangNone, bangSpeaker, bangSystem, bangResource,
+ bangWaveform
+ } m_type;
+ BOOL m_bLoop;
+ union {
+ UINT system;
+ LPCTSTR resource;
+ LPCTSTR wave;
+
+ LPCTSTR str;
+ UINT id;
+ };
+ CString m_strWave;
+ CBang() : m_type(bangNone), m_bLoop(FALSE) {}
+ };
+ typedef CTypedPtrMap<CMapStringToPtr,CString,CBang*> CBangs;
+ struct CBelling {
+ LPCSTR snd;
+ HMODULE hm;
+ DWORD flags;
+ CBelling(LPCSTR snd,HMODULE hm,DWORD flags) : snd(snd), hm(hm),
+ flags(flags) {}
+ CBelling(CBelling& s) : snd(s.snd), hm(s.hm), flags(s.flags) {}
+ CBelling& operator=(CBelling& s) {
+ snd=s.snd; hm=s.hm; flags=s.flags;
+ return *this;
+ }
+ };
+ typedef CBelling* Whistling;
+
+ CBangs m_bangs;
+
+ ~CBellsNWhistles() {
+ POSITION p = m_bangs.GetStartPosition();
+ while(p){
+ CString s; CBang* b;
+ m_bangs.GetNextAssoc(p,s,b);
+ delete b;
+ }
+ m_bangs.RemoveAll();
+ }
+
+ BOOL AssignSound(LPCTSTR codeName,LPCTSTR id,CBang::_bangType type=CBang::bangWaveform) {
+ CString cn = codeName;
+ cn.MakeLower();
+ CBang* b;
+ if(!m_bangs.Lookup(cn,b)) {
+ b = new CBang;
+ b->m_codeName=cn;
+ m_bangs[cn]=b;
+ }
+ b->m_type=type;
+ b->str = id;
+ if(type==CBang::bangWaveform){
+ b->m_strWave=id; b->str = b->m_strWave;
+ }
+ return TRUE;
+ }
+ BOOL AssignSound(LPCTSTR codeName,UINT nID,CBang::_bangType type=CBang::bangResource) {
+ CString cn = codeName;
+ cn.MakeLower();
+ CBang* b;
+ if(!m_bangs.Lookup(cn,b)) {
+ b = new CBang;
+ b->m_codeName=cn;
+ m_bangs[cn]=b;
+ }
+ b->m_type=type;
+ b->id = nID;
+ ASSERT(type!=CBang::bangWaveform);
+ return TRUE;
+ }
+ BOOL UnassignSound(LPCTSTR codeName) {
+ CString cn = codeName;
+ cn.MakeLower();
+ CBang* b;
+ if(m_bangs.Lookup(cn,b)) {
+ m_bangs.RemoveKey(cn);
+ delete b;
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ Whistling StartSound(LPCTSTR codeName) {
+ Whistling* rv = NULL;
+ CString cn = codeName;
+ CBang* b;
+ if(!m_bangs.Lookup(cn,b)){
+ ::PlaySound(cn,AfxGetInstanceHandle(),SND_ASYNC|SND_NODEFAULT|SND_NOWAIT|SND_FILENAME);
+ return NULL;
+ }
+ UINT flags = SND_ASYNC|SND_NODEFAULT|SND_NOWAIT;
+ LPCSTR snd = NULL;
+ switch(b->m_type){
+ case CBang::bangNone: return NULL;
+ case CBang::bangSpeaker: MessageBeep(0xFFFFFFFF); return NULL;
+ case CBang::bangSystem: MessageBeep(b->system); return NULL;
+ case CBang::bangResource:
+ snd = b->resource;
+ flags|=SND_RESOURCE; break;
+ case CBang::bangWaveform:
+ snd = b->wave;
+ flags|=SND_FILENAME; break;
+#ifdef _DEBUG
+ default:
+ ASSERT(FALSE); return NULL;
+#endif
+ }
+ if(b->m_bLoop)
+ flags|=SND_LOOP;
+ HMODULE hm = AfxGetInstanceHandle();
+ if(!::PlaySound(snd,hm,flags))
+ return NULL;
+ return b->m_bLoop?new CBelling(snd,hm,flags):NULL;
+ }
+ BOOL StopSound(Whistling whistle) {
+ if(!whistle)
+ return FALSE;
+ ::PlaySound(whistle->snd,whistle->hm,whistle->flags|SND_PURGE);
+ delete whistle;
+ return TRUE;
+ }
+ UINT FillInCombo(CComboBox* combo) {
+ POSITION p = m_bangs.GetStartPosition();
+ UINT rv = 0;
+ while(p) {
+ CString s;
+ CBang* b;
+ m_bangs.GetNextAssoc(p,s,b);
+ combo->AddString(s);
+ }
+ return rv;
+ }
+};
+
+#endif // _BELLSNWHISTLES_H \ No newline at end of file
diff --git a/shared-code/BitSet.h b/shared-code/BitSet.h
new file mode 100644
index 0000000..cf36e3b
--- a/dev/null
+++ b/shared-code/BitSet.h
@@ -0,0 +1,105 @@
+#ifndef __BITSET_H
+#define __BITSET_H
+
+namespace Klever {
+
+class CBitSet : public CObject {
+public:
+ CWordArray m_Bits;
+ ULONG m_BitsInSet;
+ enum {
+ bitsPerWord = sizeof(WORD)*8
+ };
+
+ CBitSet(ULONG size = 0) : m_BitsInSet(0) { SetSize(size); }
+ CBitSet(CBitSet& o) : m_BitsInSet(0) { CopyFrom(o); }
+
+ void SetSize(ULONG size,BOOL bFillOnes=FALSE) {
+ UINT os = m_Bits.GetSize();
+ UINT ns = (size+bitsPerWord-1)/bitsPerWord;
+ if(os==ns){
+ if(os){
+ if(bFillOnes)
+ m_Bits[m_BitsInSet/bitsPerWord]|=(~(WORD)0)<<(m_BitsInSet%bitsPerWord);
+ else
+ m_Bits[m_BitsInSet/bitsPerWord]&=~((~(WORD)0)<<(m_BitsInSet%bitsPerWord));
+ }
+ m_BitsInSet=size;
+ }else{
+ // *?* ASSERT((!os) || (((os-1)*bitsPerWord)<=m_BitsInSet && m_BitsInSet<(os*bitsPerWord)));
+ if(os<ns){
+ m_Bits.SetSize(ns);
+ if(bFillOnes)
+ m_Bits[m_BitsInSet/bitsPerWord]|=(~(WORD)0)<<(m_BitsInSet%bitsPerWord);
+ else
+ m_Bits[m_BitsInSet/bitsPerWord]&=~((~(WORD)0)<<(m_BitsInSet%bitsPerWord));
+ WORD* ws = m_Bits.GetData();
+ ASSERT(ws);
+ memset(&ws[os],bFillOnes?0xFF:0,(ns-os)*sizeof(WORD));
+ m_BitsInSet=size;
+ }else{
+ m_Bits.SetSize(ns);
+ m_BitsInSet=size;
+ }
+ }
+ }
+ BOOL BitSet(UINT bit,BOOL bGrow=TRUE) { return SetBit(bit,TRUE,bGrow); }
+ BOOL BitClear(UINT bit,BOOL bGrow=TRUE) { return SetBit(bit,FALSE,bGrow); }
+ BOOL SetBit(UINT bit,BOOL state,BOOL bGrow=TRUE) {
+ if(m_BitsInSet<=bit){
+ if(!bGrow)
+ return FALSE;
+ SetSize(bit+1);
+ }
+ WORD mask = ((WORD)1)<<(bit%bitsPerWord);
+ if(state)
+ m_Bits[bit/bitsPerWord]|=mask;
+ else
+ m_Bits[bit/bitsPerWord]&=~mask;
+ return TRUE;
+ }
+ BOOL IsSet(UINT bit) {
+ if(m_BitsInSet<=bit)
+ return FALSE;
+ return (m_Bits[bit/bitsPerWord]&(((WORD)1)<<(bit%bitsPerWord)))!=0;
+ }
+ void Invert() {
+ for(int i=m_Bits.GetUpperBound();i>=0;i--)
+ m_Bits[i]=~m_Bits[i];
+ }
+ CBitSet& operator&=(CBitSet& o) {
+ if(o.m_BitsInSet<m_BitsInSet)
+ SetSize(o.m_BitsInSet);
+ for(int i=m_Bits.GetUpperBound();i>=0;i--)
+ m_Bits[i]&=o.m_Bits[i];
+ return *this;
+ }
+ CBitSet& operator|=(CBitSet& o) {
+ if(o.m_BitsInSet>m_BitsInSet)
+ SetSize(o.m_BitsInSet);
+ for(int i=o.m_Bits.GetUpperBound();i>=0;i--)
+ m_Bits[i]|=o.m_Bits[i];
+ return *this;
+ }
+ CBitSet& operator=(CBitSet& o) {
+ CopyFrom(o);
+ return *this;
+ }
+ void CopyFrom(CBitSet& o) {
+ m_BitsInSet=o.m_BitsInSet;
+ m_Bits.Copy(o.m_Bits);
+ }
+ void Serialize(CArchive& ar) {
+ if(ar.IsStoring()){
+ ar << m_BitsInSet;
+ m_Bits.Serialize(ar);
+ }else{
+ ar >> m_BitsInSet;
+ m_Bits.Serialize(ar);
+ }
+ }
+};
+
+};
+
+#endif // __BITSET_H
diff --git a/shared-code/Dynamide.h b/shared-code/Dynamide.h
new file mode 100644
index 0000000..32c93f7
--- a/dev/null
+++ b/shared-code/Dynamide.h
@@ -0,0 +1,443 @@
+#ifndef __DYNAMIDE_H
+#define __DYNAMIDE_H
+
+#include "LRUCache.h"
+
+namespace Klever {
+
+template<int fbSize,int bSize>
+class CDynamide : public CObject {
+ struct firstBlock {
+ LONG freeFile;
+ BYTE crap[fbSize-sizeof(LONG)];
+ };
+ struct theBlock {
+ LONG next;
+ BYTE data[bSize-sizeof(LONG)];
+ };
+public:
+ static firstBlock FirstBlock;
+ static theBlock TheBlock;
+private:
+ class CDynaCache : public CLRUCache<DWORD,DWORD,theBlock> {
+ public:
+ CFile* m_File;
+ BOOL m_bAutodelete;
+ CDynaCache(CFile* file,BOOL bAutodelete=TRUE) : CLRUCache<DWORD,DWORD,theBlock>(64) {
+ m_File=file;
+ m_bAutodelete=bAutodelete;
+ }
+ virtual ~CDynaCache() {
+ Flush();
+ if(m_bAutodelete){
+ m_File->Close();
+ delete m_File;
+ }
+ }
+ virtual BOOL _ReadIn(DWORD idx,theBlock* data) {
+ LONG p = sizeof(firstBlock)+idx*sizeof(theBlock);
+ LONG s = m_File->Seek(p,CFile::begin);
+ if(p==s){
+ UINT rb = m_File->Read(data,sizeof(*data));
+ if(rb==sizeof(*data))
+ return TRUE;
+ if(rb)
+ return FALSE;
+ memset(data,0,sizeof(*data));
+ data->next=-1;
+ try{
+ m_File->Write(data,sizeof(*data));
+ }catch(CException* e){
+ e->Delete();
+ return FALSE;
+ }
+ }else{
+ LONG togo = p-s;
+ ASSERT(togo>0);
+ ASSERT(!(togo%sizeof(theBlock)));
+ memset(data,0,sizeof(*data));
+ data->next=-1;
+ while(togo>=0){
+ try{
+ m_File->Write(data,sizeof(*data));
+ }catch(CException* e){
+ e->Delete();
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+ }
+ virtual BOOL _WriteOut(DWORD idx,theBlock* data) {
+ LONG p = sizeof(firstBlock)+idx*sizeof(theBlock);
+ LONG s = m_File->Seek(p,CFile::begin);
+ if(p!=s)
+ return FALSE;
+ try{
+ m_File->Write(data,sizeof(*data));
+ }catch(CException* e){
+ e->Delete();
+ return FALSE;
+ }
+ return TRUE;
+ }
+ DWORD AllocateNode() {
+ LONG l = m_File->GetLength();
+ ASSERT(!((l-sizeof(firstBlock))%sizeof(theBlock)));
+ m_File->SetLength(l+sizeof(theBlock));
+ return (l-sizeof(firstBlock))/sizeof(theBlock);
+ }
+ BOOL Read1stBlock(firstBlock* fb) {
+ m_File->SeekToBegin();
+ UINT rb = m_File->Read(fb,sizeof(*fb));
+ if(rb==sizeof(*fb))
+ return TRUE;
+ if(rb)
+ return FALSE;
+ memset(fb,0,sizeof(*fb));
+ fb->freeFile = -1;
+ try{
+ m_File->Write(fb,sizeof(*fb));
+ }catch(CException* e){
+ e->Delete();
+ return FALSE;
+ }
+ return TRUE;
+ }
+ BOOL Write1stBlock(firstBlock* fb) {
+ m_File->SeekToBegin();
+ try{
+ m_File->Write(fb,sizeof(*fb));
+ }catch(CException* e){
+ e->Delete();
+ return FALSE;
+ }
+ return TRUE;
+ }
+ };
+public:
+ class CDynaFile : public CFile {
+ public:
+ CDynamide<fbSize,bSize>* m_Daddy;
+ CArray<LONG,LONG> m_Blocks;
+ LONG m_Position;
+
+ CDynaFile(CDynamide<fbSize,bSize>* daddy) : m_Daddy(NULL) { AttachToDaddy(daddy); }
+ virtual ~CDynaFile() { Close(); DetachFromDaddy(); }
+
+ void AttachToDaddy(CDynamide<fbSize,bSize>* daddy) {
+ ASSERT(!m_Daddy);
+ ASSERT(daddy);
+ m_Daddy=daddy;
+ m_Daddy->AttachDynaFile(this);
+ }
+ void DetachFromDaddy() {
+ ASSERT(m_Daddy);
+ ASSERT(!IsOpened());
+ m_Daddy->DetachDynaFile(this);
+ m_Daddy=NULL;
+ }
+
+ BOOL Create() {
+ if(IsOpened())
+ return FALSE;
+ m_Blocks.SetAtGrow(0,m_Daddy->Allocate());
+ ASSERT(m_Blocks[0]>=0);
+ m_Position=0;
+ return TRUE;
+ }
+ BOOL Open(LONG fb) {
+ if(IsOpened())
+ return FALSE;
+ ASSERT(fb>=0);
+ theBlock* b;
+ do{
+ m_Blocks.Add(fb);
+ b = m_Daddy->m_File->GetCached(fb);
+ ASSERT(b);
+ fb=b->next;
+ if(m_Blocks[m_Blocks.GetUpperBound()]==fb)
+ return FALSE;
+ }while(fb>=0);
+ m_Position=0;
+ return TRUE;
+ }
+
+ LONG GetFile() {
+ if(!IsOpened())
+ return -1;
+ return m_Blocks[0];
+ }
+ virtual DWORD GetPosition() const {
+ if(!IsOpened())
+ return 0;
+ if(m_Position<0)
+ return 0;
+ if(m_Position>GetLength())
+ return GetLength();
+ return m_Position;
+ }
+ virtual CString GetFileName() {
+ CString rv;
+ if(IsOpened())
+ rv.Format("0x%08lX",m_Blocks[0]);
+ else
+ rv.Format("None");
+ return rv;
+ }
+ virtual CString GetFileTitle() { return GetFileName(); }
+ virtual CString GetFilePath() { return GetFileName(); }
+ virtual void SetFilePath(LPCTSTR lpszNewName) { ASSERT(FALSE); }
+
+ virtual BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL) { ASSERT(FALSE); return FALSE; }
+ virtual CFile* Duplicate() { ASSERT(FALSE); return NULL; }
+
+ virtual LONG Seek(LONG lOff, UINT nFrom) {
+ if(!IsOpened())
+ return -1;
+ switch(nFrom){
+ case CFile::begin:
+ m_Position=lOff;
+ break;
+ case CFile::current:
+ m_Position+=lOff;
+ break;
+ case CFile::end:
+ m_Position=GetLength()+lOff;
+ break;
+ default:
+ ASSERT(FALSE);
+ return -1;
+ }
+ if(m_Position<0)
+ m_Position=0;
+ if(m_Position>GetLength())
+ m_Position=GetLength();
+ return m_Position;
+ }
+ virtual void SetLength(DWORD dwNewLen) {
+ if(!IsOpened())
+ return;
+ if(dwNewLen<GetLength()){
+ dwNewLen=dwNewLen+sizeof(TheBlock.data);
+ dwNewLen-=dwNewLen%sizeof(TheBlock.data);
+ while(dwNewLen<GetLength() && m_Blocks.GetSize()>1){
+ LONG mb = m_Blocks[m_Blocks.GetUpperBound()];
+ LONG mb1 = m_Blocks[m_Blocks.GetUpperBound()-1];
+ theBlock* b = m_Daddy->m_File->GetCached(mb1);
+ ASSERT(b);
+ ASSERT(b->next==mb);
+ b->next=-1;
+ m_Daddy->m_File->MakeDirty(mb1);
+ m_Daddy->Deallocate(mb);
+ m_Blocks.SetSize(m_Blocks.GetSize()-1);
+ }
+ }else{
+ while(dwNewLen>GetLength()){
+ LONG mb = m_Blocks[m_Blocks.GetUpperBound()];
+ LONG newBlock = m_Daddy->Allocate();
+ ASSERT(newBlock>=0);
+ theBlock* b = m_Daddy->m_File->GetCached(mb);
+ ASSERT(b);
+ ASSERT(b->next<0);
+ b->next=newBlock;
+ m_Daddy->m_File->MakeDirty(mb);
+ m_Blocks.Add(newBlock);
+ }
+ }
+ }
+ virtual DWORD GetLength() const {
+ return ((long)m_Blocks.GetSize())*((long)sizeof(TheBlock.data));
+ }
+
+ virtual UINT Read(void* lpBuf, UINT nCount) {
+ UINT rv = 0;
+ ASSERT(m_Position>=0 && m_Position<=GetLength());
+ LPBYTE data = (LPBYTE)lpBuf;
+ while(nCount && m_Position<GetLength()){
+ UINT bn = m_Position/sizeof(TheBlock.data);
+ UINT bo = m_Position%sizeof(TheBlock.data);
+ theBlock* b = m_Daddy->m_File->GetCached(m_Blocks[bn]);
+ ASSERT(b);
+ UINT bc = min(nCount,sizeof(TheBlock.data)-bo);
+ memmove(data,&b->data[bo],bc);
+ nCount-=bc;
+ data=&data[bc];
+ rv+=bc;
+ m_Position+=bc;
+ }
+ return rv;
+ }
+ virtual void Write(const void* lpBuf, UINT nCount) {
+ ASSERT(m_Position>=0 && m_Position<=GetLength());
+ LPBYTE data = (LPBYTE)lpBuf;
+ while(nCount){
+ UINT bn = m_Position/sizeof(TheBlock.data);
+ UINT bo = m_Position%sizeof(TheBlock.data);
+ while(bn>=m_Blocks.GetSize()){
+ LONG mb = m_Blocks[m_Blocks.GetUpperBound()];
+ LONG newBlock = m_Daddy->Allocate();
+ ASSERT(newBlock>=0);
+ theBlock* b = m_Daddy->m_File->GetCached(mb);
+ ASSERT(b);
+ ASSERT(b->next<0);
+ b->next=newBlock;
+ m_Daddy->m_File->MakeDirty(mb);
+ m_Blocks.Add(newBlock);
+ }
+ theBlock* b = m_Daddy->m_File->GetCached(m_Blocks[bn]);
+ ASSERT(b);
+ UINT bc = min(nCount,sizeof(TheBlock.data)-bo);
+ memmove(&b->data[bo],data,bc);
+ m_Daddy->m_File->MakeDirty(m_Blocks[bn]);
+ nCount-=bc;
+ data=&data[bc];
+ m_Position+=bc;
+ }
+ }
+
+ virtual void LockRange(DWORD dwPos, DWORD dwCount) { ASSERT(FALSE); }
+ virtual void UnlockRange(DWORD dwPos, DWORD dwCount) { ASSERT(FALSE); }
+
+ virtual void Abort() { ASSERT(FALSE); }
+ virtual void Flush() {
+ m_Daddy->m_File->Flush();
+ }
+ virtual void Close() {
+ m_Blocks.RemoveAll();
+ }
+
+ BOOL IsOpened() const { return m_Blocks.GetSize()!=0; }
+ };
+
+ CDynaCache* m_File;
+ firstBlock m_FB;
+
+ CDynamide() : m_File(NULL) {}
+ ~CDynamide() { Close(); }
+
+ BOOL AttachDynaFile(CDynaFile* f) {
+ // ASSERT(!m_Files.Find(f));
+ // m_Files.AddHead(f);
+ return TRUE;
+ }
+ BOOL DetachDynaFile(CDynaFile* f) {
+ //POSITION p = m_Files.Find(f);
+ // ASSERT(p);
+ // m_Files.RemoveAt(p);
+ return TRUE;
+ }
+
+ BOOL Open(LPCTSTR file,BOOL bRO=FALSE) {
+ Close();
+ try{
+ CFile* f = new CFile(file,CFile::typeBinary|(bRO?CFile::modeRead|CFile::shareDenyWrite:CFile::modeReadWrite|CFile::shareDenyRead));
+ return Attach(f,TRUE);
+ }catch(CException* e){
+ e->Delete();
+ return FALSE;
+ }
+ }
+ BOOL Create(LPCTSTR file) {
+ Close();
+ try{
+ CFile* f = new CFile(file,CFile::typeBinary|CFile::modeCreate|CFile::modeReadWrite|CFile::shareDenyRead);
+ return Attach(f,TRUE);
+ }catch(CException* e){
+ e->Delete();
+ return FALSE;
+ }
+ }
+ BOOL Attach(CFile* file,BOOL bAutodelete=TRUE) {
+ if(IsOpened())
+ return FALSE;
+ m_File = new CDynaCache(file,bAutodelete);
+ if(!m_File->Read1stBlock(&m_FB)){
+ memset(&m_FB,0,sizeof(m_FB));
+ m_FB.freeFile=-1;
+ VERIFY(m_File->Write1stBlock(&m_FB));
+ }
+ return IsOpened();
+ }
+ // CFile* Detach();
+ BOOL Close() {
+ if(!IsOpened())
+ return FALSE;
+ m_File->Write1stBlock(&m_FB);
+ delete m_File;
+ m_File=NULL;
+ return TRUE;
+ }
+ BOOL IsOpened() {
+ return m_File != NULL;
+ }
+ BOOL Write1stBlock(void) {
+ if(!IsOpened())
+ return FALSE;
+ VERIFY(m_File->Write1stBlock(&m_FB));
+ return TRUE;
+ }
+
+ CDynaFile* CreateFile() {
+ CDynaFile* rv = new CDynaFile(this);
+ if(rv->Create())
+ return rv;
+ delete rv;
+ return NULL;
+ }
+ CDynaFile* OpenFile(LONG fb) {
+ CDynaFile* rv = new CDynaFile(this);
+ if(rv->Open(fb))
+ return rv;
+ delete rv;
+ return NULL;
+ }
+ BOOL DeleteFile(LONG fb) {
+ while(fb>=0){
+ theBlock* b = m_File->GetCached(fb);
+ LONG nb = b->next;
+ Deallocate(fb);
+ fb=nb;
+ }
+ return TRUE;
+ }
+
+ LONG Allocate() {
+ if(!IsOpened())
+ return -1;
+ if(m_FB.freeFile<0){
+ LONG rv = m_File->AllocateNode();
+ theBlock *b = m_File->GetCached(rv);
+ b->next=-1;
+ m_File->MakeDirty(rv);
+ return rv;
+ }
+ LONG rv = m_FB.freeFile;
+ theBlock *b = m_File->GetCached(rv);
+ m_FB.freeFile=b->next;
+ b->next=-1;
+ m_File->MakeDirty(rv);
+ m_File->Write1stBlock(&m_FB);
+ return rv;
+ }
+ BOOL Deallocate(LONG bk) {
+ if(!IsOpened())
+ return FALSE;
+ theBlock* b = m_File->GetCached(bk);
+ ASSERT(b);
+ if(m_FB.freeFile<0){
+ b->next=-1;
+ m_FB.freeFile=bk;
+ }else{
+ b->next=m_FB.freeFile;
+ m_FB.freeFile=bk;
+ }
+ m_File->MakeDirty(bk);
+ m_File->Write1stBlock(&m_FB);
+ return TRUE;
+ }
+};
+
+};
+
+#endif // __DYNAMIDE_H
diff --git a/shared-code/FindIFace.h b/shared-code/FindIFace.h
new file mode 100644
index 0000000..8dec8c4
--- a/dev/null
+++ b/shared-code/FindIFace.h
@@ -0,0 +1,125 @@
+#ifndef __FINDIFACE_H
+#define __FINDIFACE_H
+
+#include "SNMPeer.h"
+#include "SNMPExtDLL.h"
+#include "SNMPOIDs.h"
+
+namespace Klever {
+
+inline BOOL FindIFace(in_addr& target,in_addr& source)
+{
+DEFINE_OID(ipRouteDest, OIDipRouteDest);
+DEFINE_OID(ipRouteMask, OIDipRouteMask);
+DEFINE_OID(ipRouteIfIndex, OIDipRouteIfIndex);
+DEFINE_OID(ipRouteMetric1, OIDipRouteMetric1);
+DEFINE_OID(ipAdEntIfIndex, OIDipAdEntIfIndex);
+DEFINE_OID(ipAdEntAddr, OIDipAdEntAddr);
+struct _route {
+ int iface;
+ int metric;
+ DWORD nm;
+} routes[16];
+int nRoutes = 0;
+CSNMPVarBindList vbl;
+ vbl.AddTail(CSNMPVarBind(CASNAny(CASNAny::typeASNOID,ipRouteDest,sizeof(ipRouteDest))));
+ vbl.AddTail(CSNMPVarBind(CASNAny(CASNAny::typeASNOID,ipRouteMask,sizeof(ipRouteMask))));
+ vbl.AddTail(CSNMPVarBind(CASNAny(CASNAny::typeASNOID,ipRouteIfIndex,sizeof(ipRouteIfIndex))));
+ vbl.AddTail(CSNMPVarBind(CASNAny(CASNAny::typeASNOID,ipRouteMetric1,sizeof(ipRouteMetric1))));
+CSNMPExtDLL snmp("INETMIB1");
+ while(nRoutes<(sizeof(routes)/sizeof(routes[0]))){
+ if(
+ snmp.Request(CASNAny::typeASNGetNextRequest,vbl,vbl)
+ && vbl.GetCount() == 4
+ ){
+ POSITION p = vbl.GetHeadPosition();
+ _route r = {-1,-1};
+ in_addr d, m;
+ BOOL bD = FALSE, bM = FALSE;
+ while(p){
+ CSNMPVarBind& vb = vbl.GetNext(p);
+ if(
+ vb.IsName(ipRouteDest,sizeof(ipRouteDest))
+ && vb.value.type==CASNAny::typeASNIP
+ ){
+ d.s_addr=vb.value.value.ip.s_addr; bD = TRUE;
+ }else if(
+ vb.IsName(ipRouteMask,sizeof(ipRouteMask))
+ && vb.value.type==CASNAny::typeASNIP
+ ){
+ m.s_addr=vb.value.value.ip.s_addr; bM = TRUE;
+ }else if(
+ vb.IsName(ipRouteIfIndex,sizeof(ipRouteIfIndex))
+ && vb.value.type==CASNAny::typeASNInteger
+ ){
+ r.iface=vb.value.value.number;
+ }else if(
+ vb.IsName(ipRouteMetric1,sizeof(ipRouteMetric1))
+ && vb.value.type==CASNAny::typeASNInteger
+ ){
+ r.metric=vb.value.value.number;
+ }else
+ break;
+ }
+ if(r.iface<0 || r.metric<0 || (!bD) || (!bM))
+ break;
+ if((target.s_addr&m.s_addr)==(d.s_addr&m.s_addr)){
+ r.nm=htonl(m.s_addr);
+ memmove(&routes[nRoutes++],&r,sizeof(routes[0]));
+ }
+ }else
+ break;
+ }
+ if(!nRoutes)
+ return FALSE;
+int rn = 0;
+ if(nRoutes>1){
+ for(int tmp=1;tmp<nRoutes;tmp++)
+ if(
+ routes[tmp].metric<routes[rn].metric
+ || routes[tmp].nm>routes[rn].nm
+ )
+ rn = tmp;
+ }
+int iface = routes[rn].iface;
+ vbl.RemoveAll();
+ vbl.AddTail(CSNMPVarBind(CASNAny(CASNAny::typeASNOID,ipAdEntAddr,sizeof(ipAdEntAddr))));
+ vbl.AddTail(CSNMPVarBind(CASNAny(CASNAny::typeASNOID,ipAdEntIfIndex,sizeof(ipAdEntIfIndex))));
+ for(;;){
+ if(
+ snmp.Request(CASNAny::typeASNGetNextRequest,vbl,vbl)
+ && vbl.GetCount()==2
+ ){
+ in_addr a; a.s_addr = INADDR_NONE;
+ int ifn = -1;
+ POSITION p = vbl.GetHeadPosition();
+ while(p){
+ CSNMPVarBind& vb = vbl.GetNext(p);
+ if(
+ vb.IsName(ipAdEntAddr,sizeof(ipAdEntAddr))
+ && vb.value.type==CASNAny::typeASNIP
+ ){
+ a.s_addr=vb.value.value.ip.s_addr;
+ }else if(
+ vb.IsName(ipAdEntIfIndex,sizeof(ipAdEntIfIndex))
+ && vb.value.type==CASNAny::typeASNInteger
+ ){
+ ifn = vb.value.value.number;
+ }else
+ break;
+ }
+ if(ifn<0)
+ break;
+ if(ifn==iface){
+ source.s_addr=a.s_addr;
+ return TRUE;
+ }
+ }else
+ break;
+ }
+ return FALSE;
+}
+
+};
+
+#endif // __FINDIFACE_H
diff --git a/shared-code/LRUCache.h b/shared-code/LRUCache.h
new file mode 100644
index 0000000..569e829
--- a/dev/null
+++ b/shared-code/LRUCache.h
@@ -0,0 +1,113 @@
+#ifndef __LRUCACHE_H
+#define __LRUCACHE_H
+
+namespace Klever {
+
+template<class IDX,class ARGIDX,class DATA>
+class CLRUCache : public CObject {
+public:
+ struct CacheEntry {
+ enum cacheState {
+ cacheClean, cacheDirty, cacheEmpty
+ };
+ cacheState m_State;
+ UINT m_hits;
+
+ IDX m_idx;
+ DATA* m_pData;
+
+ CacheEntry() { m_State=cacheEmpty; VERIFY(m_pData=new DATA); m_hits=0; }
+ virtual ~CacheEntry() { delete m_pData; }
+ };
+ typedef CMap<IDX,ARGIDX,CacheEntry*,CacheEntry*> CCacheMap;
+ typedef CList<CacheEntry*,CacheEntry*> CCacheList;
+
+ CCacheList m_Cache;
+ CCacheMap m_Map;
+
+ CLRUCache(UINT cacheSize) {
+ for(int tmp=0;tmp<cacheSize;tmp++){
+ CacheEntry* p = new CacheEntry;
+ m_Cache.AddTail(p);
+ }
+ }
+ virtual ~CLRUCache() {
+ Flush();
+ POSITION p = m_Cache.GetHeadPosition();
+ while(p){
+ CacheEntry* c = m_Cache.GetNext(p);
+ delete c;
+ }
+ }
+
+ DATA* GetCached(ARGIDX idx,BOOL bLoad=TRUE) {
+ CacheEntry* rv;
+ if(m_Map.Lookup(idx,rv)){
+ rv->m_hits++;
+ PopUp(rv);
+ return rv->m_pData;
+ }
+ if(!bLoad)
+ return NULL;
+ rv = m_Cache.GetTail();
+ ASSERT(rv);
+ switch(rv->m_State){
+ case CacheEntry::cacheDirty:
+ FlushEntry(rv);
+ case CacheEntry::cacheClean:
+ m_Map.RemoveKey(rv->m_idx);
+ rv->m_State=CacheEntry::cacheEmpty;
+ case CacheEntry::cacheEmpty:
+ break;
+ default:
+ ASSERT(FALSE);
+ }
+ if(!_ReadIn(idx,rv->m_pData))
+ return NULL;
+ rv->m_hits=1;
+ rv->m_State=CacheEntry::cacheClean;
+ rv->m_idx=idx;
+ m_Map[idx]=rv;
+ PopUp(rv);
+ return rv->m_pData;
+ }
+ BOOL MakeDirty(ARGIDX idx) {
+ CacheEntry* pEntry;
+ if(m_Map.Lookup(idx,pEntry)){
+ ASSERT(pEntry->m_State==CacheEntry::cacheClean || pEntry->m_State==CacheEntry::cacheDirty);
+ pEntry->m_State=CacheEntry::cacheDirty;
+ return TRUE;
+ }
+ return FALSE;
+ }
+ BOOL Flush() {
+ POSITION p = m_Cache.GetHeadPosition();
+ while(p){
+ CacheEntry* pEntry = m_Cache.GetNext(p);
+ ASSERT(pEntry);
+ FlushEntry(pEntry);
+ }
+ return TRUE;
+ }
+ BOOL FlushEntry(CacheEntry* pEntry) {
+ if(pEntry->m_State==CacheEntry::cacheDirty){
+ BOOL rv = _WriteOut(pEntry->m_idx,pEntry->m_pData);
+ if(rv)
+ pEntry->m_State=CacheEntry::cacheClean;
+ }
+ return FALSE;
+ }
+ void PopUp(CacheEntry* pEntry) {
+ POSITION p = m_Cache.Find(pEntry);
+ ASSERT(p);
+ m_Cache.RemoveAt(p);
+ VERIFY(m_Cache.AddHead(pEntry));
+ }
+
+ virtual BOOL _ReadIn(ARGIDX idx,DATA* data) = 0;
+ virtual BOOL _WriteOut(ARGIDX idx,DATA* data) = 0;
+};
+
+};
+
+#endif // __LRUCACHE_H
diff --git a/shared-code/RegEx.cpp b/shared-code/RegEx.cpp
new file mode 100644
index 0000000..b7bab62
--- a/dev/null
+++ b/shared-code/RegEx.cpp
@@ -0,0 +1,1697 @@
+#include "../stdafx.h"
+#include "RegEx.h"
+
+#define isWordableChar(c) (isalnum(c) || (c)=='_')
+
+BOOL CRegEx::Compile(LPCTSTR regex,int flags)
+{
+ ASSERT(!((flags&regExtended) && (flags&regLiteral)));
+ m_Matches.RemoveAll();
+ m_Strip.RemoveAll();
+ m_Strip.SetSize(0,15);
+ m_Pattern=regex;
+ m_ParsePointer=0;
+ m_Error=0;
+ m_Sets.RemoveAll();
+ m_Flags=flags;
+ m_iFlags=0;
+ m_BOLs=m_EOLs=0;
+ m_Subexps = 0;
+ m_Categories=1; // 0 is 'everything else'
+ m_bBackRefs=FALSE;
+ memset(m_Category,0,sizeof(m_Category));
+
+ // Go ahead.
+ m_Error || m_Strip.Add(CSop(CSop::opEnd));
+ if(flags&regExtended){
+ ParseERE();
+ }else if(flags&regLiteral){
+ ParseLiteral();
+ }else{
+ ParseBRE();
+ }
+ m_Error || m_Strip.Add(CSop(CSop::opEnd));
+ Categorize();
+ m_Strip.FreeExtra();
+ FigureMust();
+ m_Pluses=CountPluses();
+ if(m_iFlags&iflagsBad){
+ m_Error || (m_Error=regeAssert);
+ // ??? point to nuls? ;-)
+ }
+ // We may wish to free some memory here if we're erroneous (ie. m_Error..)
+ m_ParseParens.RemoveAll();
+#ifdef _DEBUG
+ if(m_Error){
+ CString tmp;
+ tmp.Format("RE: ParseError: %d\n",m_Error);
+ TRACE0(tmp);
+ }
+// DumpStrip(afxDump);
+#endif
+ return (m_bCompiled=(!m_Error));
+}
+
+BOOL CRegEx::Match(LPCTSTR src,int flags)
+{
+ if(!m_bCompiled)
+ return FALSE;
+ if(m_iFlags&iflagsBad)
+ return FALSE;
+ m_Input=src;
+ m_mFlags=flags;
+ m_mPointer=m_Input;
+ m_mBegin=m_Input;
+ m_mEnd=&m_mBegin[m_Input.GetLength()];
+ ASSERT(m_mPointer<=m_mEnd);
+ m_Matches.RemoveAll();
+ if(!m_Must.IsEmpty()){
+ if(m_Input.Find(m_Must)<0)
+ return FALSE;
+ }
+ // Go ahead..
+int stripLen = m_Strip.GetSize();
+ m_mLastPos.SetSize(0);
+ for(int tmp=0;tmp<stripLen;tmp++)
+ m_Strip[tmp].m_MatchData=0;
+LPCTSTR beginp = m_mBegin;
+LPCTSTR endp;
+ for(;;){
+ endp = MatchFast(beginp);
+ if(!endp)
+ return FALSE;
+ if((m_mFlags&regNoSubExpressions) && !m_bBackRefs)
+ break;
+ ASSERT(m_cOldP);
+ for(;;){
+ endp = MatchSlow(m_cOldP,m_mEnd,1,stripLen-1);
+ if(endp)
+ break;
+ ASSERT(m_cOldP<m_mEnd);
+ m_cOldP++;
+ }
+ if((m_mFlags&regOneMatch) && !m_bBackRefs)
+ break;
+ // Oh, his, we want the subexpression..
+ m_Matches.SetSize(m_Subexps+1);
+ LPCTSTR dp;
+ if(!m_bBackRefs && !(m_mFlags&regBackRefs)){
+ dp = MatchDissect(m_cOldP,endp,1,stripLen-1);
+ }else{
+ if(m_Pluses>0 && !m_mLastPos.GetSize())
+ m_mLastPos.SetSize(m_Pluses);
+ dp = MatchBackRef(m_cOldP,endp,1,stripLen-1,0);
+ }
+ if(dp)
+ break;
+ // Uh.. oh.. we couldn't find a subexpression-level match
+ ASSERT(m_bBackRefs);
+ ASSERT(m_Pluses==0 || m_mLastPos.GetSize());
+ for(;;){
+ if(dp || endp <= m_cOldP)
+ break; // defeat.. ?
+ endp = MatchSlow(m_cOldP,endp-1,1,stripLen-1);
+ if(!endp)
+ break; // defeat.. ?
+ // Try it on a shorter possibility..
+#ifdef _DEBUG
+ for(tmp=1;tmp<=m_Subexps;tmp++)
+ ASSERT(m_Matches[tmp].m_Begin<0 && m_Matches[tmp].m_End<0);
+#endif
+ dp = MatchBackRef(m_cOldP,endp,1,stripLen-1,0);
+ }
+ ASSERT((!dp) || dp==endp);
+ if(dp) // Found a shorter one..
+ break;
+ // Despite initial appearances, there is no match here
+ beginp = m_cOldP+1;
+ ASSERT(beginp<=m_mEnd);
+ }
+ // Fill in the detail if so requested..
+ if(!(m_mFlags&regNoSubExpressions)){
+ if(!m_Matches.GetSize())
+ m_Matches.SetSize(1);
+ m_Matches[0].m_Begin=m_cOldP-m_mBegin;
+ m_Matches[0].m_End=endp-m_mBegin;
+ }
+ m_mLastPos.RemoveAll();
+ return TRUE;
+}
+
+CString CRegEx::Replace(LPCTSTR src,LPCTSTR rep,int flags)
+{
+ // ***
+ return CString();
+}
+
+void CRegEx::ParseERE(int stop)
+{
+UCHAR c;
+BOOL first=TRUE;
+int prevF, prevB;
+ for(;;){
+ int co = m_Strip.GetSize();
+ while(m_ParsePointer < m_Pattern.GetLength() && ((c=m_Pattern[m_ParsePointer])!='|') && c!=stop)
+ ParseEREexp();
+ if(m_Strip.GetSize()==co){
+ m_Error || (m_Error=regeEmpty);
+ // ??? point to nuls?
+ }
+ if(m_ParsePointer>=m_Pattern.GetLength() || m_Pattern[m_ParsePointer]!='|')
+ break;
+ else
+ m_ParsePointer++;
+ if(first){
+ StripInsert(co,CSop(CSop::opChoice0,m_Strip.GetSize()-co+1));
+ prevF = prevB = co;
+ first=FALSE;
+ }
+ m_Error || m_Strip.Add(CSop(CSop::opOr0,m_Strip.GetSize()-prevB));
+ prevB = m_Strip.GetSize()-1;
+ m_Error || (m_Strip[prevF].m_Operand=m_Strip.GetSize()-prevF);
+ prevF = m_Strip.GetSize();
+ m_Error || m_Strip.Add(CSop(CSop::opOr1,0)); // offset isn't really right.. very so..
+ }
+ if(!first){
+ m_Error || (m_Strip[prevF].m_Operand=m_Strip.GetSize()-prevF);
+ m_Error || m_Strip.Add(CSop(CSop::opChoice1,m_Strip.GetSize()-prevB));
+ }
+ ASSERT(m_ParsePointer >= m_Pattern.GetLength() || m_Pattern[m_ParsePointer]==stop);
+}
+
+void CRegEx::ParseEREexp()
+{
+ ASSERT(m_ParsePointer < m_Pattern.GetLength());
+UCHAR c = m_Pattern[m_ParsePointer++];
+int pos = m_Strip.GetSize();
+int subno;
+int count, count2;
+BOOL wascaret=FALSE;
+ switch(c){
+ case '(':
+ if(!(m_ParsePointer<m_Pattern.GetLength())){
+ TRACE0("RE: '(' at the end of the pattern\n");
+ if(!m_Error)
+ m_Error = regeParen;
+ // ??? point to nuls?
+ }
+ m_Subexps++;
+ subno=m_Subexps;
+ m_ParseParens.SetAtGrow(m_Subexps,CParenthesis(m_Strip.GetSize()));
+ m_Error || m_Strip.Add(CSop(CSop::opLeftParen,subno));
+ if(m_ParsePointer>=m_Pattern.GetLength() || m_Pattern[m_ParsePointer]!=')')
+ ParseERE(')');
+ VERIFY(m_ParseParens[m_Subexps].m_End = m_Strip.GetSize());
+ m_Error || m_Strip.Add(CSop(CSop::opRightParen,subno));
+ if(m_ParsePointer >= m_Pattern.GetLength() || m_Pattern[m_ParsePointer++]!=')'){
+ TRACE0("RE: No matching ')'\n");
+ if(!m_Error)
+ m_Error = regeParen;
+ // ??? point to nuls?
+ }
+ break;
+ case '^':
+ m_Error || m_Strip.Add(CSop(CSop::opBOL));
+ m_iFlags|=iflagsUseBOL;
+ m_BOLs++;
+ wascaret=TRUE;
+ break;
+ case '$':
+ m_Error || m_Strip.Add(CSop(CSop::opEOL));
+ m_iFlags|=iflagsUseEOL;
+ m_EOLs++;
+ break;
+ case '|':
+ TRACE0("RE: '|' outside of expression\n");
+ if(!m_Error)
+ m_Error = regeEmpty;
+ // ??? point to nuls?
+ break;
+ case '*':
+ case '+':
+ case '?':
+ TRACE0("RE: '*'/'+'/'?' with no previous expression\n");
+ if(!m_Error)
+ m_Error = regeBadRepeat;
+ // ??? point to nuls?
+ break;
+ case '.':
+ if(m_Flags&regNewLine)
+ EmitNonNewLineAny();
+ else
+ m_Error || m_Strip.Add(CSop(CSop::opAny));
+ break;
+ case '[':
+ ParseBracket();
+ break;
+ case '\\':
+ if(m_ParsePointer >= m_Pattern.GetLength()){
+ TRACE0("RE: '\\' at the end of the pattern\n");
+ if(!m_Error)
+ m_Error = regeEscape;
+ // ??? point to nuls?
+ }else{
+ c = m_Pattern[m_ParsePointer++];
+ EmitOrdinary(c);
+ }
+ break;
+ case '{':
+ if(m_ParsePointer >= m_Pattern.GetLength() || !isdigit(m_Pattern[m_ParsePointer])){
+ TRACE0("RE: '{' with no repeat count\n");
+ if(!m_Error)
+ m_Error = regeBadRepeat;
+ // ??? point to nuls?
+ }
+ // Fallthrough..
+ default:
+ EmitOrdinary(c);
+ break;
+ }
+ if(m_ParsePointer >= m_Pattern.GetLength())
+ return;
+ c = m_Pattern[m_ParsePointer];
+ // Call a '{' repetition if followed by a digit
+ if (!(c=='*' || c=='+' || c=='?' || ( c=='{' && (m_ParsePointer+1) < m_Pattern.GetLength() && isdigit(m_Pattern[m_ParsePointer+1])) ))
+ return; // No repetitor - done.
+ m_ParsePointer++;
+ if(wascaret){
+ TRACE0("RE: repetitive '^' detected\n");
+ if(!m_Error)
+ m_Error = regeBadRepeat;
+ // ??? point to nuls?
+ }
+ switch(c){
+ case '*': // Implemeted as +?
+ // + expression
+ StripInsert(pos,CSop(CSop::opPlus0,m_Strip.GetSize()-pos+1));
+ m_Error || m_Strip.Add(CSop(CSop::opPlus1,m_Strip.GetSize()-pos));
+ // ? expression
+ StripInsert(pos,CSop(CSop::opQuest0,m_Strip.GetSize()-pos+1));
+ m_Error || m_Strip.Add(CSop(CSop::opQuest1,m_Strip.GetSize()-pos));
+ break;
+ case '+':
+ // + expression
+ StripInsert(pos,CSop(CSop::opPlus0,m_Strip.GetSize()-pos+1));
+ m_Error || m_Strip.Add(CSop(CSop::opPlus1,m_Strip.GetSize()-pos));
+ break;
+ case '?':
+ // Kludge - emit y? as (y|) until subtle bug gets fixed :-)
+ StripInsert(pos,CSop(CSop::opChoice0,m_Strip.GetSize()-pos+1));
+ m_Error || m_Strip.Add(CSop(CSop::opOr0,m_Strip.GetSize()-pos));
+ m_Error || (m_Strip[pos].m_Operand=m_Strip.GetSize()-pos);
+ m_Error || m_Strip.Add(CSop(CSop::opOr1,1));
+ m_Error || m_Strip.Add(CSop(CSop::opChoice1,2));
+ break;
+ case '{':
+ count = ParseCount();
+ if(m_ParsePointer < m_Pattern.GetLength() && m_Pattern[m_ParsePointer]==','){
+ m_ParsePointer++;
+ if(isdigit(m_Pattern[m_ParsePointer])){ // HHH Personally, I doubt it is always available
+ count2=ParseCount();
+ if(!(count<=count2)){
+ TRACE0("RE: Disbalanced counts in '{}' repeater\n");
+ m_Error || (m_Error=regeBadBrace);
+ // ??? point to nuls?
+ }
+ }else // Single number with comma
+ count2=256; // Infinity
+ }else // Single number
+ count2=count;
+ EmitRepeat(pos,count,count2);
+ if(m_ParsePointer >= m_Pattern.GetLength() || m_Pattern[m_ParsePointer]!='}'){
+ // No '}'..
+ TRACE0("RE: No immediately following '}' of '{' expression\n");
+ while(m_ParsePointer < m_Pattern.GetLength() && m_Pattern[m_ParsePointer]!='}')
+ m_ParsePointer++;
+ if(m_ParsePointer >= m_Pattern.GetLength()){
+ TRACE0("RE: No closing '}' found\n");
+ m_Error || (m_Error=regeBrace);
+ }else
+ m_Error || (m_Error=regeBadBrace);
+ // ??? point to nuls?
+ }else
+ m_ParsePointer++;
+ break;
+ }
+ if(m_ParsePointer >= m_Pattern.GetLength())
+ return;
+ c = m_Pattern[m_ParsePointer];
+ if(!(c=='*' || c=='+' || c=='?' || (c=='{' && (m_ParsePointer+1)<m_Pattern.GetLength() && isdigit(m_Pattern[m_ParsePointer+1]))))
+ return;
+ TRACE0("RE: Double repeater\n");
+ m_Error || (m_Error=regeBadRepeat);
+ // ??? point to nuls?
+}
+
+void CRegEx::StripInsert(int pos,CSop& sop)
+{
+ if(m_Error)
+ return;
+int sn = m_Strip.GetSize();
+ m_Strip.InsertAt(pos,sop);
+ for(int tmp=1;tmp<m_ParseParens.GetSize();tmp++){
+ if(m_ParseParens[tmp].m_Begin>=pos)
+ m_ParseParens[tmp].m_Begin++;
+ if(m_ParseParens[tmp].m_End>=pos)
+ m_ParseParens[tmp].m_End++;
+ }
+}
+
+void CRegEx::EmitOrdinary(UCHAR c)
+{
+ if(m_Flags&regIgnoreCase && isalpha(c) && (tolower(c) !=toupper(c))){
+ // Emit both cases
+ CString savePattern = m_Pattern;
+ int savePointer = m_ParsePointer;
+ m_Pattern=c;
+ m_Pattern+=']';
+ m_ParsePointer=0;
+ ParseBracket();
+ m_Pattern=savePattern;
+ m_ParsePointer=savePointer;
+ }else{
+ m_Error || m_Strip.Add(CSop(CSop::opChar,c));
+ if(!m_Category[(BYTE)c])
+ m_Category[(BYTE)c]=m_Categories++;
+ }
+}
+
+void CRegEx::EmitNonNewLineAny()
+{
+ // Kludges're going on and on..
+CString savePattern = m_Pattern;
+int savePointer = m_ParsePointer;
+ m_Pattern="^\n]";
+ m_ParsePointer=0;
+ ParseBracket();
+ m_Pattern=savePattern;
+ m_ParsePointer=savePointer;
+}
+
+int CRegEx::ParseCount()
+{
+BOOL nonEmpty=FALSE;
+int rv = 0;
+UCHAR c;
+ while(m_ParsePointer < m_Pattern.GetLength() && isdigit(c=m_Pattern[m_ParsePointer]) && rv <=255){
+ rv = rv*10 + c-'0';
+ nonEmpty=TRUE;
+ m_ParsePointer++;
+ }
+ if(rv>255 || !nonEmpty){
+ m_Error || (m_Error=regeBadBrace);
+ // ??? point to nuls?
+ }
+ return rv;
+}
+
+void CRegEx::ParseBracket()
+{
+ // Dept. of truly sickening special case kludges
+ if((m_ParsePointer+5) < m_Pattern.GetLength() && !m_Pattern.Mid(m_ParsePointer,6).Compare("[:<]]")){
+ m_Error || m_Strip.Add(CSop(CSop::opBOW));
+ m_ParsePointer+=6;
+ return;
+ }
+ if((m_ParsePointer+5) < m_Pattern.GetLength() && !m_Pattern.Mid(m_ParsePointer,6).Compare("[:>]]")){
+ m_Error || m_Strip.Add(CSop(CSop::opEOW));
+ m_ParsePointer+=6;
+ return;
+ }
+BOOL invert=TRUE;
+ if(m_ParsePointer < m_Pattern.GetLength() && m_Pattern[m_ParsePointer]=='^')
+ m_ParsePointer++;
+ else
+ invert=FALSE;
+CSet cset;
+ if(m_ParsePointer < m_Pattern.GetLength()){
+ switch(m_Pattern[m_ParsePointer]){
+ case ']':
+ case '-':
+ cset.Add(m_Pattern[m_ParsePointer]);
+ m_ParsePointer++;
+ break;
+ }
+ }
+ while(m_ParsePointer < m_Pattern.GetLength() && m_Pattern[m_ParsePointer]!=']' && !((m_ParsePointer+1)<m_Pattern.GetLength() && !m_Pattern.Mid(m_ParsePointer,2).Compare("-]")))
+ ParseBracketTerm(cset);
+ if(m_ParsePointer < m_Pattern.GetLength() && m_Pattern[m_ParsePointer]=='-'){
+ m_ParsePointer++;
+ cset.Add('-');
+ }
+ if(m_ParsePointer < m_Pattern.GetLength() && m_Pattern[m_ParsePointer]==']')
+ m_ParsePointer++;
+ else{
+ m_Error || (m_Error=regeBracket);
+ // ??? point to nuls?
+ return;
+ }
+ if(m_Flags&regIgnoreCase){
+ for(int tmp=CSet::size-1;tmp>=0;tmp--){
+ if(cset.IsIn(tmp) && isalpha(tmp) && (toupper(tmp)!=tolower(tmp)))
+ cset.Add(isupper(tmp)?tolower(tmp):toupper(tmp));
+ }
+ /*
+ if(!cset->m_Multis.IsEmpty())
+ cset.CollatingCase();
+ */
+ }
+ if(invert){
+ for(int tmp=CSet::size-1;tmp>=0;tmp--)
+ if(cset.IsIn(tmp))
+ cset.Sub(tmp);
+ else
+ cset.Add(tmp);
+ if(m_Flags&regNewLine)
+ cset.Sub('\n');
+ /*
+ if(!cset.m_Multis.IsEmpty())
+ cset.CollatingInvert();
+ */
+ }
+UCHAR c = cset.GetOnly();
+ if(c){
+ EmitOrdinary(c);
+ }else
+ m_Error || m_Strip.Add(CSop(CSop::opAnyOf,StoreSet(cset)));
+}
+
+void CRegEx::CSet::Add(UCHAR c)
+{
+ m_Set[(BYTE)c]=TRUE;
+ m_Hash+=c;
+}
+
+BOOL CRegEx::CSet::IsIn(UCHAR c)
+{
+ return m_Set[(BYTE)c];
+}
+
+void CRegEx::CSet::Sub(UCHAR c)
+{
+ m_Set[(BYTE)c]=FALSE;
+ m_Hash-=c;
+}
+
+UCHAR CRegEx::CSet::GetOnly()
+{
+int rv = 0;
+UCHAR only = 0;
+ for(int tmp=0;tmp<size;tmp++){
+ rv+=m_Set[tmp]?(only=tmp,1):0;
+ }
+ return (rv==1)?only:0;
+}
+
+int CRegEx::StoreSet(CSet& cset)
+{
+ for(int tmp=0;tmp<m_Sets.GetSize();tmp++)
+ if(m_Sets[tmp]==cset)
+ return tmp;
+ return m_Sets.Add(cset);
+}
+
+void CRegEx::ParseBracketTerm(CSet& cset)
+{
+UCHAR c;
+ switch((m_ParsePointer<m_Pattern.GetLength())?m_Pattern[m_ParsePointer]:0){
+ case '[':
+ c = ((m_ParsePointer+1)<m_Pattern.GetLength())?m_Pattern[m_ParsePointer+1]:0;
+ break;
+ case '-':
+ m_Error || (m_Error=regeRange);
+ // ??? point to nuls?
+ return;
+ default:
+ c = 0;
+ break;
+ }
+ switch(c){
+ case ':': // Character class
+ m_ParsePointer+=2;
+ if(m_ParsePointer>=m_Pattern.GetLength()){
+ m_Error || (m_Error=regeBracket);
+ // ??? point to nuls?
+ }
+ c = m_Pattern[m_ParsePointer];
+ if(c== '-' || c==']'){
+ m_Error || (m_Error=regeCType);
+ // ??? point to nuls?
+ }
+ ParseBracketCClass(cset);
+ if(m_ParsePointer>=m_Pattern.GetLength()){
+ m_Error || (m_Error=regeBracket);
+ // ??? point to nuls?
+ }
+ if((m_ParsePointer+1)>=m_Pattern.GetLength() || (m_Pattern.Mid(m_ParsePointer,2).Compare(":]"))){
+ m_Error || (m_Error=regeCType);
+ // ??? point to nuls?
+ }else
+ m_ParsePointer+=2;
+ break;
+ case '=': // Equivalence class
+ m_ParsePointer+=2;
+ if(m_ParsePointer >= m_Pattern.GetLength()){
+ m_Error || (m_Error=regeBracket);
+ // ??? point to nuls?
+ }
+ c = m_Pattern[m_ParsePointer];
+ if(c== '-' || c==']'){
+ m_Error || (m_Error=regeCollate);
+ // ??? point to nuls?
+ }
+ ParseBracketEClass(cset);
+ if((m_ParsePointer+1)>=m_Pattern.GetLength() || (m_Pattern.Mid(m_ParsePointer,2).Compare("=]"))){
+ m_Error || (m_Error=regeCollate);
+ // ??? point to nuls?
+ }else
+ m_ParsePointer+=2;
+ break;
+ default: // Symbol, character or range
+ {
+ UCHAR start, finish;
+ start = ParseBracketSymbol();
+ if((m_ParsePointer<m_Pattern.GetLength() && m_Pattern[m_ParsePointer]=='-') /*&& (m_ParsePointer+1)<m_Pattern.GetLength() && m_Pattern[m_ParsePointer+1]==']'*/){
+ // I believe the expression above is seetwo..
+ // range.
+ m_ParsePointer++;
+ if(m_ParsePointer<m_Pattern.GetLength() && m_Pattern[m_ParsePointer]=='-'){
+ m_ParsePointer++;
+ finish='-';
+ }else
+ finish=ParseBracketSymbol();
+ }else
+ finish=start;
+ if(((BYTE)start)>((BYTE)finish)){
+ m_Error || (m_Error=regeRange);
+ // ??? point to nuls?
+ }
+ for(int tmp=start;tmp<=(BYTE)finish;tmp++)
+ cset.Add(tmp);
+ }
+ break;
+ }
+}
+
+void CRegEx::ParseBracketCClass(CSet& cset)
+{
+static struct {
+ char *className;
+ char *classChars;
+} cc[] = {
+ {"alnum","ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"},
+ {"alpha","ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"},
+ {"blank"," \t"},
+ {"cntrl","\007\b\t\n\v\f\r\1\2\3\4\5\6\16\17\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37\177"},
+ {"digit","0123456789"},
+ {"graph","ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"},
+ {"lower","abcdefghijklmnopqrstuvwxyz"},
+ {"print","ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ "},
+ {"punct","!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"},
+ {"space","\t\n\v\f\r "},
+ {"upper","ABCDEFGHIJKLMNOPQRSTUVWXYZ"},
+ {"xdigit","0123456789ABCDEFabcdef"}
+};
+CString cclass;
+UCHAR c;
+ while(m_ParsePointer < m_Pattern.GetLength() && isalpha(c=m_Pattern[m_ParsePointer])){
+ cclass+=c;
+ m_ParsePointer++;
+ }
+char *classChars = NULL;
+ for(int tmp=0;tmp<(sizeof(cc)/sizeof(cc[0]));tmp++){
+ if(!cclass.CompareNoCase(cc[tmp].className)){
+ classChars=cc[tmp].classChars;
+ break;
+ }
+ }
+ if(!classChars){
+ m_Error || (m_Error=regeCType);
+ // ??? point to nuls?
+ return;
+ }
+ while(*classChars)
+ cset.Add(*(classChars++));
+ // --- multis
+}
+
+void CRegEx::ParseBracketEClass(CSet& cset)
+{
+ cset.Add(ParseBracketCollatingElement('='));;
+}
+
+UCHAR CRegEx::ParseBracketCollatingElement(UCHAR term)
+{
+static struct {
+ char *entityName;
+ char entity;
+} cc[] = { {"NUL",'\0'},{"SOH",'\001'},{"STX",'\002'},{"ETX",'\003'},{"EOT",'\004'},{"ENQ",'\005'},{"ACK",'\006'},{"BEL",'\007'},{"alert",'\007'},{"BS",'\010'},{"backspace",'\b'},{"HT",'\011'},{"tab",'\t'},{"LF",'\012'},{"newline",'\n'},{"VT",'\013'},{"vertical-tab",'\v'},{"FF",'\014'},{"form-feed",'\f'},{"CR",'\015'},{"carriage-return",'\r'},{"SO",'\016'},{"SI",'\017'},{"DLE",'\020'},{"DC1",'\021'},{"DC2",'\022'},{"DC3",'\023'},{"DC4",'\024'},{"NAK",'\025'},{"SYN",'\026'},{"ETB",'\027'},{"CAN",'\030'},{"EM",'\031'},{"SUB",'\032'},{"ESC",'\033'},{"IS4",'\034'},{"FS",'\034'},{"IS3",'\035'},{"GS",'\035'},{"IS2",'\036'},{"RS",'\036'},{"IS1",'\037'},{"US",'\037'},{"space",' '},{"exclamation-mark",'!'},{"quotation-mark",'"'},{"number-sign",'#'},{"dollar-sign",'$'},{"percent-sign",'%'},{"ampersand",'&'},{"apostrophe",'\''},{"left-parenthesis",'('},{"right-parenthesis",')'},{"asterisk",'*'},{"plus-sign",'+'},{"comma",','},{"hyphen",'-'},{"hyphen-minus",'-'},{"period",'.'},{"full-stop",'.'},{"slash",'/'},{"solidus",'/'},{"zero",'0'},{"one",'1'},{"two",'2'},{"three",'3'},{"four",'4'},{"five",'5'},{"six",'6'},{"seven",'7'},{"eight",'8'},{"nine",'9'},{"colon",':'},{"semicolon",';'},{"less-than-sign",'<'},{"equals-sign",'='},{"greater-than-sign",'>'},{"question-mark",'?'},{"commercial-at",'@'},{"left-square-bracket",'['},{"backslash",'\\'},{"reverse-solidus",'\\'},{"right-square-bracket",']'},{"circumflex",'^'},{"circumflex-accent",'^'},{"underscore",'_'},{"low-line",'_'},{"grave-accent",'`'},{"left-brace",'{'},{"left-curly-bracket",'{'},{"vertical-line",'|'},{"right-brace",'}'},{"right-curly-bracket",'}'},{"tilde",'~'},{"DEL",'\177'} };
+CString seeTwo;
+ seeTwo=term;
+ seeTwo+=']';
+CString entityName;
+ while(m_ParsePointer<m_Pattern.GetLength() && !((m_ParsePointer+1)<m_Pattern.GetLength() && !m_Pattern.Mid(m_ParsePointer,2).Compare(seeTwo)))
+ entityName+=m_Pattern[m_ParsePointer++];
+ if(m_ParsePointer>=m_Pattern.GetLength()){
+ m_Error || (m_Error=regeBracket);
+ // ??? point to nuls?
+ return 0;
+ }
+ for(int tmp=0;tmp<(sizeof(cc)/sizeof(cc[0]));tmp++)
+ if(!entityName.CompareNoCase(cc[tmp].entityName))
+ return cc[tmp].entity;
+ if(entityName.GetLength()==1)
+ return entityName[0];
+ m_Error || (m_Error=regeCollate);
+ // ??? point to nuls?
+ return 0;
+}
+
+UCHAR CRegEx::ParseBracketSymbol()
+{
+ if(m_ParsePointer>=m_Pattern.GetLength()){
+ m_Error || (m_Error=regeBracket);
+ // ??? point to nuls?
+ }
+ if((m_ParsePointer+1)<m_Pattern.GetLength() && !m_Pattern.Mid(m_ParsePointer,2).Compare("[."))
+ m_ParsePointer+=2;
+ else
+ return m_Pattern[m_ParsePointer++];
+ // Collating symbol
+UCHAR rv = ParseBracketCollatingElement('.');
+ if((m_ParsePointer+1)<m_Pattern.GetLength() && !m_Pattern.Mid(m_ParsePointer,2).Compare("[."))
+ m_ParsePointer+=2;
+ else{
+ m_Error || (m_Error=regeCollate);
+ // ??? point to nuls?
+ }
+ return rv;
+}
+
+void CRegEx::EmitRepeat(int pos,int from,int to)
+{
+ if(m_Error)
+ return;
+ ASSERT(from<=to);
+int finish = m_Strip.GetSize();
+int copy;
+#define N 2
+#define INF 3
+#define REP(f,t) ((f)*8+(t))
+#define MAP(n) (((n)<=1)?(n):((n)==256)?INF:N)
+ switch(REP(MAP(from),MAP(to))){
+ case REP(0,0): // must be user doing ths??
+ m_Strip.SetSize(pos);
+ break;
+ case REP(0,1): // as in '?'
+ case REP(0,N): // as in '{1,n}?'
+ case REP(0,INF): // as in '{1,}?'
+ // Kludge - emit y? as (y|) until something gets fixed..
+ StripInsert(pos,CSop(CSop::opChoice0,pos));
+ EmitRepeat(pos+1,1,to);
+ m_Error || m_Strip.Add(CSop(CSop::opOr0,m_Strip.GetSize()-pos));
+ m_Error || (m_Strip[pos].m_Operand=m_Strip.GetSize()-pos);
+ m_Error || m_Strip.Add(CSop(CSop::opOr1,1));
+ m_Error || m_Strip.Add(CSop(CSop::opChoice1,2));
+ break;
+ case REP(1,1):
+ break;
+ case REP(1,N): // as in 'x?x{1,n-1}'
+ // Kludge again..
+ StripInsert(pos,CSop(CSop::opChoice0,pos));
+ m_Error || m_Strip.Add(CSop(CSop::opOr0,m_Strip.GetSize()-pos));
+ m_Error || (m_Strip[pos].m_Operand=m_Strip.GetSize()-pos);
+ m_Error || m_Strip.Add(CSop(CSop::opOr1,1));
+ m_Error || m_Strip.Add(CSop(CSop::opChoice1,2));
+ copy = StripDuplicate(pos+1,finish+1);
+ ASSERT(copy==(finish+4));
+ EmitRepeat(copy,1,to-1);
+ break;
+ case REP(1,INF): // as in '+'
+ StripInsert(pos,CSop(CSop::opPlus0,pos));
+ m_Error || m_Strip.Add(CSop(CSop::opPlus1,m_Strip.GetSize()-pos));
+ break;
+ case REP(N,N): // as in 'xx{from-1,to-1}'
+ copy = StripDuplicate(pos,finish);
+ EmitRepeat(copy,from-1,to-1);
+ break;
+ case REP(N,INF): // as in 'xx{n-1,}'
+ copy = StripDuplicate(pos,finish);
+ EmitRepeat(copy,from-1,to);
+ break;
+#ifndef NDEBUG
+ default:
+ ASSERT(FALSE);
+ break;
+#endif
+ }
+#undef MAP
+#undef REP
+#undef INF
+#undef N
+}
+
+int CRegEx::StripDuplicate(int from,int to)
+{
+int rv = m_Strip.GetSize();
+ ASSERT(from<=to);
+ if(from==to)
+ return rv;
+ // Maybe should be optimized for copying the whole thing.
+ for(int tmp=from;tmp<to;tmp++)
+ m_Strip.Add(m_Strip[tmp]);
+ return rv;
+}
+
+void CRegEx::Categorize()
+{
+ if(m_Error)
+ return;
+ for(int tmp=0;tmp<(sizeof(m_Category)/sizeof(m_Category[0]));tmp++)
+ if((!m_Category[tmp]) && IsInSets(tmp)){
+ int cat = m_Categories++;
+ m_Category[tmp]=cat;
+ for(int c=tmp+1;c<(sizeof(m_Category)/sizeof(m_Category[0]));c++)
+ if((!m_Category[c]) && IsInSameSets(tmp,c))
+ m_Category[c]=cat;
+ }
+}
+
+BOOL CRegEx::IsInSets(UCHAR c)
+{
+ for(int tmp=0;tmp<m_Sets.GetSize();tmp++)
+ if(m_Sets[tmp].IsIn(c))
+ return TRUE;
+ return FALSE;
+}
+
+BOOL CRegEx::IsInSameSets(UCHAR c1,UCHAR c2)
+{
+ for(int tmp=0;tmp<m_Sets.GetSize();tmp++)
+ if(m_Sets[tmp].IsIn(c1)!=m_Sets[tmp].IsIn(c2))
+ return FALSE;
+ return TRUE;
+}
+
+void CRegEx::FigureMust()
+{
+ if(m_Error)
+ return;
+ m_Must.Empty();
+int stripLen = m_Strip.GetSize();
+int seqStart, seqLength = 0;
+int mustStart, mustLength = 0;
+ for(int tmp=1;tmp<stripLen;tmp++){
+ switch(m_Strip[tmp].m_Operator){
+ case CSop::opChar:
+ if(!seqLength)
+ seqStart=tmp;
+ seqLength++;
+ break;
+ case CSop::opPlus0:
+ case CSop::opLeftParen:
+ case CSop::opRightParen:
+ break; // Break, since they don't break the sequence
+ case CSop::opQuest0:
+ case CSop::opChoice0:
+ // These ones we skip.
+ do{
+ tmp+=m_Strip[tmp].m_Operand;
+ // I still think it could be ASSERTed..
+ if(m_Strip[tmp].m_Operator!=CSop::opQuest1 && m_Strip[tmp].m_Operator!=CSop::opChoice1 && m_Strip[tmp].m_Operator!=CSop::opOr1){
+ m_iFlags|=iflagsBad;
+ return;
+ }
+ }while(m_Strip[tmp].m_Operator!=CSop::opQuest1 && m_Strip[tmp].m_Operator!=CSop::opChoice1);
+ // Fallthrough..
+ default:
+ // End of sequence
+ if(seqLength>mustLength){
+ mustStart=seqStart;
+ mustLength=seqLength;
+ }
+ seqLength=0;
+ break;
+ }
+ } // Hmm.. originally it's meant to be do while not opEnd..
+ if(!mustLength)
+ return;
+ // Turn into string, but, wait, personally I'm sure it could be put in the main loop.. or maybe not..
+ for(tmp=0;tmp<seqLength;tmp++){
+ while(m_Strip[seqStart+tmp].m_Operator!=CSop::opChar)
+ ASSERT(tmp<seqLength);
+ m_Must+=m_Strip[tmp].m_Operand;
+ }
+}
+
+int CRegEx::CountPluses()
+{
+ if(m_Error)
+ return 0;
+int stripLen = m_Strip.GetSize();
+int rv = 0;
+int nest = 0;
+ for(int tmp=0;tmp<stripLen;tmp++){
+ switch(m_Strip[tmp].m_Operator){
+ case CSop::opPlus0:
+ nest++;
+ break;
+ case CSop::opPlus1:
+ if(nest>rv)
+ rv = nest;
+ nest--;
+ break;
+ }
+ } // Again, originally we were supposed to scan till opEnd..
+ if(nest)
+ m_iFlags|=iflagsBad; // Could this be an ASSERTion?
+ return rv;
+}
+
+void CRegEx::ParseLiteral()
+{
+ if(!m_Pattern.GetLength()){
+ m_Error || (m_Error=regeEmpty);
+ // ??? point to nuls?
+ }
+ while(m_ParsePointer < m_Pattern.GetLength())
+ EmitOrdinary(m_Pattern[m_ParsePointer++]);
+}
+
+void CRegEx::ParseBRE(int stopa,int stopb)
+{
+int start = m_Strip.GetSize();
+BOOL first=TRUE;
+BOOL wasDollar=FALSE;
+ if(m_ParsePointer<m_Pattern.GetLength() && m_Pattern[m_ParsePointer]=='^'){
+ m_ParsePointer++;
+ m_Error || m_Strip.Add(CSop(CSop::opBOL,0));
+ m_iFlags|=iflagsUseBOL;
+ m_BOLs++;
+ }
+CString stopstr;
+ if(stopa){
+ stopstr+=stopa;
+ if(stopb)
+ stopstr+=stopb;
+ }
+ while(m_ParsePointer < m_Pattern.GetLength() && !((m_ParsePointer+1)<m_Pattern.GetLength() && !m_Pattern.Mid(m_ParsePointer,2).Compare(stopstr))){
+ wasDollar = ParseBREexp(first);
+ first=FALSE;
+ }
+ if(wasDollar){ // Trailing anchor that was..
+ m_Strip.SetSize(m_Strip.GetSize()-1);
+ m_Error || m_Strip.Add(CSop(CSop::opEOL,0));
+ m_iFlags|=iflagsUseEOL;
+ m_EOLs++;
+ }
+ if(m_Strip.GetSize()==start){
+ m_Error || (m_Error=regeEmpty);
+ // ??? point to nuls?
+ }
+}
+
+BOOL CRegEx::ParseBREexp(BOOL ordinaryStar)
+{
+int subno;
+int pos = m_Strip.GetSize();
+ ASSERT(m_ParsePointer<m_Pattern.GetLength());
+int c = m_Pattern[m_ParsePointer++];
+ if(c=='\\'){
+ if(m_ParsePointer>=m_Pattern.GetLength()){
+ m_Error || (m_Error=regeEscape);
+ // ??? point to nuls
+ }else
+ c = 0x100|m_Pattern[m_ParsePointer++];
+ }
+ switch(c){
+ case '.':
+ if(m_Flags&regNewLine)
+ EmitNonNewLineAny();
+ else
+ m_Error || m_Strip.Add(CSop(CSop::opAny,0));
+ break;
+ case '[':
+ ParseBracket();
+ break;
+ case 0x100|'{':
+ m_Error || (m_Error=regeBadRepeat);
+ // ??? point to nuls?
+ break;
+ case 0x100|'(':
+ m_Subexps++;
+ subno=m_Subexps;
+ m_ParseParens.SetAtGrow(m_Subexps,CParenthesis(m_Strip.GetSize()));
+ m_Error || m_Strip.Add(CSop(CSop::opLeftParen,subno));
+ if(m_ParsePointer<m_Pattern.GetLength() && !((m_ParsePointer+1)<m_Pattern.GetLength() && !m_Pattern.Mid(m_ParsePointer,2).Compare("\\)")))
+ ParseBRE('\\',')');
+ VERIFY(m_ParseParens[m_Subexps].m_End = m_Strip.GetSize());
+ m_Error || m_Strip.Add(CSop(CSop::opRightParen,subno));
+ if((m_ParsePointer+1) < m_Pattern.GetLength() && !m_Pattern.Mid(m_ParsePointer,2).Compare("\\)"))
+ m_ParsePointer+=2;
+ else{
+ m_Error || (m_Error=regeParen);
+ // ??? point to nuls?
+ }
+ break;
+ case 0x100|')':
+ case 0x100|'}':
+ // Can this possibly happen?!
+ m_Error || (m_Error=regeParen);
+ // ??? point to nuls?
+ break;
+ case 0x100|'1':
+ case 0x100|'2':
+ case 0x100|'3':
+ case 0x100|'4':
+ case 0x100|'5':
+ case 0x100|'6':
+ case 0x100|'7':
+ case 0x100|'8':
+ case 0x100|'9':
+ {
+ int i = (c&0xFF)-'0';
+ if(i < m_ParseParens.GetSize() && m_ParseParens[i].m_End){
+ m_Error || m_Strip.Add(CSop(CSop::opBackRef0,i));
+ ASSERT(m_ParseParens[i].m_Begin);
+ ASSERT(m_Strip[m_ParseParens[i].m_Begin].m_Operator==CSop::opLeftParen);
+ ASSERT(m_Strip[m_ParseParens[i].m_End].m_Operator==CSop::opRightParen);
+ StripDuplicate(m_ParseParens[i].m_Begin+1,m_ParseParens[i].m_End);
+ m_Error || m_Strip.Add(CSop(CSop::opBackRef1,i));
+ }else{
+ m_Error || (m_Error=regeSubReg);
+ // ??? point to nuls?
+ }
+ m_bBackRefs=TRUE;
+ }
+ break;
+ case '*':
+ if(!ordinaryStar){
+ m_Error || (m_Error=regeBadRepeat);
+ // ??? point to nuls?
+ }
+ // Fallthrough..
+ default:
+ EmitOrdinary(c&0xFF);
+ break;
+ }
+ if(m_ParsePointer<m_Pattern.GetLength() && m_Pattern[m_ParsePointer]=='*'){
+ m_ParsePointer++;
+ // as in '+?'
+ StripInsert(pos,CSop(CSop::opPlus0,m_Strip.GetSize()-pos+1));
+ m_Error || m_Strip.Add(CSop(CSop::opPlus1,m_Strip.GetSize()-pos));
+ StripInsert(pos,CSop(CSop::opQuest0,m_Strip.GetSize()-pos+1));
+ m_Error || m_Strip.Add(CSop(CSop::opQuest1,m_Strip.GetSize()-pos));
+ }else if ((m_ParsePointer+1)<m_Pattern.GetLength() && !m_Pattern.Mid(m_ParsePointer,2).Compare("\\{")){
+ m_ParsePointer+=2;
+ int count = ParseCount();
+ int count2;
+ if(m_ParsePointer<m_Pattern.GetLength() && m_Pattern[m_ParsePointer]==','){
+ m_ParsePointer++;
+ if(m_ParsePointer<m_Pattern.GetLength() && isdigit(m_Pattern[m_ParsePointer])){
+ count2=ParseCount();
+ if(count>count2){
+ m_Error || (m_Error=regeBadBrace);
+ // ??? poin to nuls?
+ }
+ }else // Single number with comma
+ count2=256;
+ }else // Single number
+ count2=count;
+ EmitRepeat(pos,count,count2);
+ if((m_ParsePointer+1)>=m_Pattern.GetLength() || m_Pattern.Mid(m_ParsePointer,2).Compare("\\}")){
+ while(m_ParsePointer<m_Pattern.GetLength() && !((m_ParsePointer+1)<m_Pattern.GetLength() && !m_Pattern.Mid(m_ParsePointer,2).Compare("\\}")))
+ m_ParsePointer++;
+ if(m_ParsePointer>=m_Pattern.GetLength()){
+ m_Error || (m_Error=regeBrace);
+ // ??? point to nuls?
+ }
+ m_Error || (m_Error=regeBadBrace);
+ }else
+ m_ParsePointer+=2;
+ }else if(c=='$')
+ return TRUE;
+ return FALSE;
+}
+
+CRegEx::CRegEx()
+{
+ m_bCompiled=FALSE;
+}
+
+LPCTSTR CRegEx::MatchFast(LPCTSTR begin)
+{
+ MatchStatesClear(CSop::stCurrent);
+ m_Strip[1].m_MatchData|=CSop::stCurrent;
+int stripLen = m_Strip.GetSize();
+ MatchStep(1,stripLen-1,CSop::stCurrent,charNothing,CSop::stCurrent);
+ MatchStatesCopy(CSop::stFresh,CSop::stCurrent);
+LPCTSTR coldp = NULL;
+LPCTSTR p = begin;
+int c = (begin==m_mBegin)?charOut:((int)(BYTE)m_mPointer[-1]);
+ for(;;){
+ // next character..
+ int lastc = c;
+ c = (p==m_mEnd)?charOut:(int)*(BYTE*)p;
+ if(MatchStatesEqual(CSop::stCurrent,CSop::stFresh))
+ coldp=p;
+ // Is there an EOL and/or BOL between lastc and c? - they ask..
+ int flagc=0;
+ int i = 0;
+ if((lastc=='\n' && m_Flags&regNewLine) || (lastc==charOut && !(m_mFlags&regNotBOL))){
+ flagc=charBOL;
+ i=m_BOLs;
+ }
+ if((c=='\n' && m_Flags&regNewLine) || (c==charOut && !(m_mFlags&regNotEOL))){
+ flagc=(flagc==charBOL)?charBOLEOL:charEOL;
+ i+=m_EOLs;
+ }
+ if(i){
+ for(;i>0;i--)
+ MatchStep(1,stripLen-1,CSop::stCurrent,flagc,CSop::stCurrent);
+ }
+ // What about a word boundary? - they wonder..
+ if((flagc==charBOL || (lastc!=charOut && !isWordableChar(c))) && (c!=charOut && isWordableChar(c)))
+ flagc = charBOW;
+ if((lastc!=charOut && isWordableChar(lastc)) && (flagc==charEOL || (c!=charOut && !isWordableChar(c))))
+ flagc = charEOW;
+ if(flagc==charBOW || flagc==charEOW){
+ MatchStep(1,stripLen-1,CSop::stCurrent,flagc,CSop::stCurrent);
+ }
+ // Are we done? Now WE wonder..
+ if((m_Strip[stripLen-1].m_MatchData&CSop::stCurrent) || p==m_mEnd)
+ break; // They insist I need to note break out.. Okay, I do..
+ // Nope, we're not done. We have to face this character..
+ MatchStatesCopy(CSop::stTemp,CSop::stCurrent);
+ MatchStatesCopy(CSop::stCurrent,CSop::stFresh);
+ ASSERT(c!=charOut);
+ MatchStep(1,stripLen-1,CSop::stTemp,c,CSop::stCurrent);
+ p++;
+ }
+ ASSERT(coldp);
+ m_cOldP=coldp; // *** I believe this variable can be changed 'in-place'
+ if(m_Strip[stripLen-1].m_MatchData&CSop::stCurrent)
+ return &p[1];
+ else
+ return NULL;
+}
+
+void CRegEx::MatchStatesClear(BYTE mask)
+{
+int stripLen = m_Strip.GetSize();
+ for(int tmp=0;tmp<stripLen;tmp++)
+ m_Strip[tmp].m_MatchData&=~mask;
+}
+
+void CRegEx::MatchStep(int from,int to,BYTE maskBefore,int charCode,BYTE maskAfter)
+{
+BOOL i;
+int look;
+int here = from;
+ for(int pc=from;pc!=to;pc++,here++){
+ CSop s=m_Strip[pc];
+ switch(s.m_Operator){
+ case CSop::opEnd:
+ ASSERT(pc==(to-1));
+ break;
+ case CSop::opChar:
+ // Only characters can match..
+ ASSERT((charCode<charOut) || charCode!=s.m_Operand);
+ if(charCode==s.m_Operand)
+ m_Strip[here+1].m_MatchData|=(m_Strip[here].m_MatchData&maskBefore)?maskAfter:0;
+ break;
+ case CSop::opBOL:
+ if(charCode==charBOL || charCode==charBOLEOL)
+ m_Strip[here+1].m_MatchData|=(m_Strip[here].m_MatchData&maskBefore)?maskAfter:0;
+ break;
+ case CSop::opEOL:
+ if(charCode==charEOL || charCode==charBOLEOL)
+ m_Strip[here+1].m_MatchData|=(m_Strip[here].m_MatchData&maskBefore)?maskAfter:0;
+ break;
+ case CSop::opBOW:
+ if(charCode==charBOW)
+ m_Strip[here+1].m_MatchData|=(m_Strip[here].m_MatchData&maskBefore)?maskAfter:0;
+ break;
+ case CSop::opEOW:
+ if(charCode==charEOW)
+ m_Strip[here+1].m_MatchData|=(m_Strip[here].m_MatchData&maskBefore)?maskAfter:0;
+ break;
+ case CSop::opAny:
+ if(charCode<charOut)
+ m_Strip[here+1].m_MatchData|=(m_Strip[here].m_MatchData&maskBefore)?maskAfter:0;
+ break;
+ case CSop::opAnyOf:
+ if(charCode<charOut && m_Sets[s.m_Operand].m_Set[charCode])
+ m_Strip[here+1].m_MatchData|=(m_Strip[here].m_MatchData&maskBefore)?maskAfter:0;
+ break;
+ case CSop::opBackRef0: // Ignored here..
+ case CSop::opBackRef1:
+ m_Strip[here+1].m_MatchData|=(m_Strip[here].m_MatchData&maskAfter)?maskAfter:0;
+ break;
+ case CSop::opPlus0:
+ // Forward, this is just an empty, comment says..
+ m_Strip[here+1].m_MatchData|=(m_Strip[here].m_MatchData&maskAfter)?maskAfter:0;
+ break;
+ case CSop::opPlus1:
+ m_Strip[here+1].m_MatchData|=(m_Strip[here].m_MatchData&maskAfter)?maskAfter:0;
+ i =(m_Strip[here-s.m_Operand].m_MatchData&maskAfter)!=0;
+ m_Strip[here-s.m_Operand].m_MatchData|=(m_Strip[here].m_MatchData&maskAfter)?maskAfter:0;
+ if(!i && (m_Strip[here-s.m_Operand].m_MatchData&maskAfter)){
+ // oho, must reconsider loop body, comment says.. what's so 'oho' about it?
+ pc-=s.m_Operand+1;
+ here=pc;
+ }
+ break;
+ case CSop::opQuest0:
+ // two branches, both forward..
+ m_Strip[here+1].m_MatchData|=(m_Strip[here].m_MatchData&maskAfter)?maskAfter:0;
+ m_Strip[here+s.m_Operand].m_MatchData|=(m_Strip[here].m_MatchData&maskAfter)?maskAfter:0;
+ break;
+ case CSop::opQuest1:
+ // just an empty.. aren't we tired of justanempties?
+ m_Strip[here+1].m_MatchData|=(m_Strip[here].m_MatchData&maskAfter)?maskAfter:0;
+ break;
+ case CSop::opLeftParen: // they say it's not significan there..
+ case CSop::opRightParen:
+ m_Strip[here+1].m_MatchData|=(m_Strip[here].m_MatchData&maskAfter)?maskAfter:0;
+ break;
+ case CSop::opChoice0: // mark the first two branches..
+ m_Strip[here+1].m_MatchData|=(m_Strip[here].m_MatchData&maskAfter)?maskAfter:0;
+ ASSERT(m_Strip[pc+s.m_Operand].m_Operator==CSop::opOr1);
+ m_Strip[here+s.m_Operand].m_MatchData|=(m_Strip[here].m_MatchData&maskAfter)?maskAfter:0;
+ break;
+ case CSop::opOr0: // done a branch, find the end of choice..
+ if(m_Strip[here].m_MatchData&maskAfter){
+ for(look=1;(s=m_Strip[pc+look]).m_Operator!=CSop::opChoice1;look+=s.m_Operand)
+ ASSERT(s.m_Operator==CSop::opOr1);
+ m_Strip[here+look].m_MatchData|=(m_Strip[here].m_MatchData&maskAfter)?maskAfter:0;
+ }
+ break;
+ case CSop::opOr1: // Propagate Choice's marking..
+ m_Strip[here+1].m_MatchData|=(m_Strip[here].m_MatchData&maskAfter)?maskAfter:0;
+ if(m_Strip[pc+s.m_Operand].m_Operator!=CSop::opChoice1){
+ ASSERT(m_Strip[pc+s.m_Operand].m_Operator==CSop::opOr1);
+ m_Strip[here+s.m_Operand].m_MatchData|=(m_Strip[here].m_MatchData&maskAfter)?maskAfter:0;
+ }
+ break;
+ case CSop::opChoice1: // Just empty.. :-)..
+ m_Strip[here+1].m_MatchData|=(m_Strip[here].m_MatchData&maskAfter)?maskAfter:0;
+ break;
+#ifdef _DEBUG
+ default:
+ ASSERT(FALSE);
+ break;
+#endif
+ }
+ }
+}
+
+void CRegEx::MatchStatesCopy(BYTE dst,BYTE src)
+{
+int stripLen = m_Strip.GetSize();
+ for(int tmp=0;tmp<stripLen;tmp++){
+ // I believe this can be optimized, easily..
+ m_Strip[tmp].m_MatchData&=~dst;
+ m_Strip[tmp].m_MatchData|=(m_Strip[tmp].m_MatchData&src)?dst:0;
+ }
+}
+
+BOOL CRegEx::MatchStatesEqual(BYTE m1,BYTE m2)
+{
+int stripLen = m_Strip.GetSize();
+ for(int tmp=0;tmp<stripLen;tmp++){
+ BYTE mm = m_Strip[tmp].m_MatchData;
+ if(((mm&m1) && (mm&m2)) || !(mm&(m1|m2)))
+ continue;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+LPCTSTR CRegEx::MatchSlow(LPCTSTR begin,LPCTSTR end,int from,int to)
+{
+ MatchStatesClear(CSop::stCurrent);
+ m_Strip[from].m_MatchData|=CSop::stCurrent;
+ MatchStep(from,to,CSop::stCurrent,charNothing,CSop::stCurrent);
+LPCTSTR mp = NULL;
+int c = (m_mBegin==m_mPointer)?charOut:(int)(BYTE)begin[-1];
+LPCTSTR p = begin;
+ for(;;){
+ // next character..
+ int lastc = c;
+ c = (p==m_mEnd)?charOut:(int)*(BYTE*)p;
+ // Now we start to wonder if there is an EOL and/or BOL between lastc and c
+ int flagc = 0;
+ int i = 0;
+ if((lastc=='\n' && m_Flags&regNewLine) || (lastc==charOut && !(m_mFlags&regNotBOL))){
+ flagc = charBOL;
+ i = m_BOLs;
+ }
+ if((c=='\n' && m_Flags&regNewLine) || (c==charOut && !(m_mFlags&regNotEOL))){
+ flagc = (flagc==charBOL)?charBOLEOL:charEOL;
+ i+=m_EOLs;
+ }
+ if(i){
+ for(;i>0;i--)
+ MatchStep(from,to,CSop::stCurrent,flagc,CSop::stCurrent);
+ }
+ // Now we wonder about word boundaries..
+ if((flagc==charBOL || (lastc!=charOut && !isWordableChar(lastc))) && (c!=charOut && isWordableChar(c)))
+ flagc=charBOW;
+ if((lastc!=charOut && isWordableChar(lastc)) && (flagc==charEOL || (c!=charOut && !isWordableChar(c))))
+ flagc=charEOW;
+ if(flagc==charBOW || flagc==charEOW){
+ MatchStep(from,to,CSop::stCurrent,flagc,CSop::stCurrent);
+ }
+ // Are we done we all wonder??
+ if(m_Strip[to].m_MatchData&CSop::stCurrent)
+ mp=p;
+ if(MatchStatesEqual(CSop::stCurrent,CSop::stEmpty) || p==end)
+ break; // Again, we're obliged to note break out. We do.
+ // Sucks.. we have to face this character..
+ MatchStatesCopy(CSop::stTemp,CSop::stCurrent);
+ MatchStatesCopy(CSop::stCurrent,CSop::stEmpty);
+ ASSERT(c!=charOut);
+ MatchStep(from,to,CSop::stTemp,c,CSop::stCurrent);
+ MatchStep(from,to,CSop::stCurrent,charNothing,CSop::stCurrent);
+ p++;
+ }
+ return mp;
+}
+
+LPCTSTR CRegEx::MatchDissect(LPCTSTR begin,LPCTSTR end,int from,int to)
+{
+LPCTSTR sp = begin, dp;
+LPCTSTR stp, rest, tail, ssp, oldssp, sep;
+int ssub, esub;
+int es;
+int i;
+ for(int ss=from;ss<to;ss = es){
+ // Identify end of SubRE
+ es = ss;
+ switch(m_Strip[es].m_Operator){
+ case CSop::opPlus0:
+ case CSop::opQuest0:
+ es+=m_Strip[es].m_Operand;
+ break;
+ case CSop::opChoice0:
+ while(m_Strip[es].m_Operator!=CSop::opChoice1)
+ es+=m_Strip[es].m_Operand;
+ break;
+ }
+ es++;
+ // Figure out what it matched
+ switch(m_Strip[ss].m_Operator){
+ case CSop::opEnd:
+ ASSERT(FALSE);
+ break;
+ case CSop::opChar:
+ sp++;
+ break;
+ case CSop::opBOL:
+ case CSop::opEOL:
+ case CSop::opBOW:
+ case CSop::opEOW:
+ break;
+ case CSop::opAny:
+ case CSop::opAnyOf:
+ sp++;
+ break;
+ case CSop::opBackRef0:
+ case CSop::opBackRef1:
+ ASSERT(FALSE);
+ break;
+ // Cases where lenght of match is hard to find..
+ case CSop::opQuest0:
+ stp=end;
+ for(;;){
+ // How long could this one be??
+ rest = MatchSlow(sp,stp,ss,es);
+ ASSERT(rest); // It did match.. It should've..
+ // Could the rest match the rest? (good question)
+ tail = MatchSlow(rest,end,es,to);
+ if(tail==end)
+ break; // yup.
+ // nope, try a shorter match for this one..
+ stp=rest-1;
+ ASSERT(stp>=sp); // It did work.. It should've..
+ }
+ ssub=ss+1;
+ esub=es-1;
+ // Did innards match?
+ if(MatchSlow(sp,rest,ssub,esub)){
+ dp = MatchDissect(sp,rest,ssub,esub);
+ ASSERT(dp==rest);
+ }else // nope..
+ ASSERT(sp==rest);
+ sp = rest;
+ break;
+ case CSop::opPlus0:
+ stp=end;
+ for(;;){
+ // How long could this one be??
+ rest = MatchSlow(sp,stp,ss,es);
+ ASSERT(rest); // It did.. It should've..
+ // Could the rest match the rest?
+ tail = MatchSlow(rest,end,es,to);
+ if(tail==end)
+ break; // yup.
+ // nope..
+ stp=rest-1;
+ ASSERT(stp>=sp); // It should've worked, we believe..
+ }
+ ssub=ss+1;
+ esub=es-1;
+ ssp=sp;
+ oldssp=ssp;
+ for(;;){ // Find last match of innards..
+ sep = MatchSlow(ssp,rest,ssub,esub);
+ if((!sep) || sep==ssp)
+ break; // Failed or matched nothin'
+ oldssp=ssp;
+ ssp=sep;
+ }
+ if(!sep){
+ // Last successfull..
+ sep=ssp;
+ ssp=oldssp;
+ }
+ ASSERT(sep=rest); // Must exhaust substring they say..
+ VERIFY(MatchSlow(ssp,sep,ssub,esub)==rest); // Assert or verify - that is the question..
+ dp = MatchDissect(ssp,sep,ssub,esub);
+ ASSERT(dp==sep);
+ sp=rest;
+ break;
+ case CSop::opChoice0:
+ stp = end;
+ for(;;){
+ // how long..
+ rest = MatchSlow(sp,stp,ss,es);
+ ASSERT(rest);
+ // Could it..
+ tail = MatchSlow(rest,end,es,to);
+ if(tail==end)
+ break; // y
+ // n
+ stp = rest-1;
+ ASSERT(stp>=sp);
+ }
+ ssub=ss+1;
+ esub=ss+m_Strip[ss].m_Operand-1;
+ ASSERT(m_Strip[esub].m_Operator==CSop::opOr0);
+ for(;;){ // Find first matching branch..
+ if(MatchSlow(sp,rest,ssub,esub)==rest)
+ break;
+ // this one missed, try next..
+ ASSERT(m_Strip[esub].m_Operator==CSop::opOr0);
+ esub++;
+ ASSERT(m_Strip[esub].m_Operator==CSop::opOr1);
+ ssub=esub+1;
+ esub+=m_Strip[esub].m_Operand;
+ if(m_Strip[esub].m_Operator==CSop::opOr1)
+ esub--;
+ else
+ ASSERT(m_Strip[esub].m_Operator==CSop::opChoice1);
+ }
+ dp = MatchDissect(sp,rest,ssub,esub);
+ ASSERT(dp==rest);
+ sp=rest;
+ break;
+ case CSop::opPlus1:
+ case CSop::opQuest1:
+ case CSop::opOr0:
+ case CSop::opOr1:
+ case CSop::opChoice1:
+ ASSERT(FALSE);
+ break;
+ case CSop::opLeftParen:
+ i = m_Strip[ss].m_Operand;
+ ASSERT(0<i && i<=m_Subexps);
+ m_Matches[i].m_Begin=sp-m_mBegin;
+ break;
+ case CSop::opRightParen:
+ i = m_Strip[ss].m_Operand;
+ ASSERT(0<i && i<=m_Subexps);
+ m_Matches[i].m_End=sp-m_mBegin;
+ break;
+#ifdef _DEBUG
+ default: // Uh.. oh..
+ ASSERT(FALSE);
+ break;
+#endif
+ }
+ }
+ ASSERT(sp==end);
+ return sp;
+}
+
+LPCTSTR CRegEx::MatchBackRef(LPCTSTR begin,LPCTSTR end,int from,int to,int level)
+{
+LPCTSTR sp = begin;
+BOOL hard = FALSE;
+ // Get as far as we can as long as it's easy
+ for(int ss=from;!hard && ss<to;ss++){
+ CSop s = m_Strip[ss];
+ switch(s.m_Operator){
+ case CSop::opChar:
+ if(sp==end || *sp++ != s.m_Operand)
+ return NULL;
+ break;
+ case CSop::opAny:
+ if(sp==end)
+ return NULL;
+ sp++; // I'm sure this ++ could be embedded in previous expression..
+ break;
+ case CSop::opAnyOf:
+ if(sp==end || !m_Sets[s.m_Operand].IsIn(*sp++))
+ return NULL;
+ break;
+ case CSop::opBOL:
+ if(!((sp==m_mBegin && !(m_mFlags&regNotBOL)) || (sp<m_mEnd && *(sp-1)=='\n' && (m_Flags&regNewLine))))
+ return NULL;
+ break;
+ case CSop::opEOL:
+ if(!((sp==m_mEnd && !(m_mFlags&regNotEOL)) || (sp<m_mEnd && *sp=='\n' && (m_Flags&regNewLine))))
+ return NULL;
+ break;
+ case CSop::opBOW:
+ if(!(((sp==m_mBegin && !(m_mFlags&regNotBOL)) || (sp<m_mEnd && *(sp-1)=='\n' && (m_Flags&regNewLine)) || (sp>m_mBegin && !isWordableChar(*(sp-1)))) && (sp<m_mEnd && isWordableChar(*sp))))
+ return NULL;
+ break;
+ case CSop::opEOW:
+ if(!(((sp==m_mEnd && !(m_mFlags&regNotEOL)) || (sp<m_mEnd && *sp=='\n' && (m_Flags&regNewLine)) || (sp<m_mEnd && !isWordableChar(*sp))) && (sp>m_mBegin && isWordableChar(*(sp-1)))))
+ return NULL;
+ break;
+ case CSop::opQuest1:
+ break;
+ case CSop::opOr0: // Matches null, but needs to skip
+ ss++;
+ s = m_Strip[ss];
+ do{
+ ASSERT(s.m_Operator==CSop::opOr1);
+ ss+=s.m_Operand;
+ }while((s=m_Strip[ss]).m_Operator!=CSop::opChoice1);
+ // Now we should note that ss++ gets us past the Choice1..
+ break;
+ default:
+ // Have to make a choice..
+ hard=TRUE;
+ break;
+ }
+ }
+ if(!hard){ // That was it..
+ if(sp!=end)
+ return NULL;
+ return sp;
+ }
+ ss--; // Adjust for ther for's final increment..
+ // Hard stuff.. is going on and on..
+CSop s = m_Strip[ss];
+int i, len, offsave;
+int ssub,esub;
+LPCTSTR ssp, dp;
+ switch(s.m_Operator){
+ case CSop::opBackRef0: // The vilest depths they say.. If I only knew what the 'viles' stands for..
+ i = s.m_Operand;
+ ASSERT(0<i && i<=m_Subexps);
+ if(m_Matches[i].m_End<0)
+ return NULL;
+ ASSERT(m_Matches[i].m_Begin>=0);
+ len = m_Matches[i].GetLength();
+ ASSERT((end-m_mBegin)>=len);
+ if(sp>end-len)
+ return NULL; // Not enough left to match..
+ ssp = m_mBegin+m_Matches[i].m_Begin;
+ if(memcmp(sp,ssp,len))
+ return NULL;
+ while(m_Strip[ss]!=CSop(CSop::opBackRef1,i))
+ ss++;
+ return MatchBackRef(sp+len,end,ss+1,to,level-1);
+ break;
+ case CSop::opQuest0: // to null or not they wonder..
+ dp = MatchBackRef(sp,end,ss+1,to,level);
+ if(dp)
+ return dp; // not..
+ return MatchBackRef(sp,end,ss+s.m_Operand+1,to,level-1);
+ break;
+ case CSop::opPlus0:
+ ASSERT(m_mLastPos.GetSize());
+ ASSERT(level+1 <= m_Pluses);
+ m_mLastPos[level+1]=sp;
+ return MatchBackRef(sp,end,ss+1,to,level+1);
+ break;
+ case CSop::opPlus1:
+ if(sp == m_mLastPos[level]) // Last pass matched null
+ return MatchBackRef(sp,end,ss+1,to,level-1);
+ // Try another pass..
+ m_mLastPos[level]=sp;
+ dp = MatchBackRef(sp,end,ss-s.m_Operand+1,to,level);
+ if(dp)
+ return dp;
+ return MatchBackRef(sp,end,ss+1,to,level-1);
+ break;
+ case CSop::opChoice0: // find the right one, ifany
+ ssub = ss+1;
+ esub = ss+s.m_Operand-1;
+ ASSERT(m_Strip[esub].m_Operator==CSop::opOr0);
+ for(;;){ // Find first matching branch.
+ dp = MatchBackRef(sp,end,ssub,esub,level);
+ if(dp)
+ return dp;
+ // This one missed, try next one..
+ if(m_Strip[esub].m_Operator==CSop::opChoice1)
+ return NULL; // There is none..
+ esub++;
+ ASSERT(m_Strip[esub].m_Operator==CSop::opOr1);
+ ssub=esub+1;
+ esub+=m_Strip[esub].m_Operand;
+ if(m_Strip[esub].m_Operator==CSop::opOr1)
+ esub--;
+ else
+ ASSERT(m_Strip[esub].m_Operator==CSop::opChoice1);
+ }
+ break;
+ case CSop::opLeftParen: // Must undo assignment if rest fails..
+ i = s.m_Operand;
+ ASSERT(0<i && i<=m_Subexps);
+ offsave = m_Matches[i].m_Begin;
+ m_Matches[i].m_Begin = sp-m_mBegin;
+ dp = MatchBackRef(sp,end,ss+1,to,level);
+ if(dp)
+ return dp;
+ m_Matches[i].m_Begin=offsave;
+ return NULL;
+ break;
+ case CSop::opRightParen: // Must undo assignment if rest fails..
+ i = s.m_Operand;
+ ASSERT(0<i && i<=m_Subexps);
+ offsave = m_Matches[i].m_End;
+ m_Matches[i].m_End = sp-m_mBegin;
+ dp = MatchBackRef(sp,end,ss+1,to,level);
+ if(dp)
+ return dp;
+ m_Matches[i].m_End = offsave;
+ return NULL;
+ break;
+#ifdef _DEBUG
+ default:
+ ASSERT(FALSE);
+ break;
+#endif
+ }
+ ASSERT(FALSE);
+ return NULL; // Anyway - we can never get here..
+}
+
+#ifdef _DEBUG
+void CRegEx::CSop::Dump(CDumpContext& dc)
+{
+ switch(m_Operator){
+ case opEnd:
+ dc << "end";
+ break;
+ case opChar:
+ dc << "char('" << (char)m_Operand << "')";
+ break;
+ case opBOL:
+ dc << "BOL";
+ break;
+ case opEOL:
+ dc << "EOL";
+ break;
+ case opAny:
+ dc << "any";
+ break;
+ case opAnyOf:
+ dc << "anyOf(" << m_Operand << ")";
+ break;
+ case opBackRef0:
+ dc << "[ backref(" << m_Operand << ")";
+ break;
+ case opBackRef1:
+ dc << "] backref(" << m_Operand << ")";
+ break;
+ case opPlus0:
+ dc << "[ + (" << m_Operand << ")";
+ break;
+ case opPlus1:
+ dc << "] + (" << m_Operand << ")";
+ break;
+ case opQuest0:
+ dc << "[ ? (" << m_Operand << ")";
+ break;
+ case opQuest1:
+ dc << "] ? (" << m_Operand << ")";
+ break;
+ case opLeftParen:
+ dc << "[ ( (" << m_Operand << ")";
+ break;
+ case opRightParen:
+ dc << "] ) (" << m_Operand << ")";
+ break;
+ case opChoice0:
+ dc << "[ choice (" << m_Operand << ")";
+ break;
+ case opOr0:
+ dc << "[ | (" << m_Operand << ")";
+ break;
+ case opOr1:
+ dc << "] | (" << m_Operand << ")";
+ break;
+ case opChoice1:
+ dc << "] choice (" << m_Operand << ")";
+ break;
+ case opBOW:
+ dc << "BOW";
+ break;
+ case opEOW:
+ dc << "EOW";
+ break;
+ }
+}
+void CRegEx::DumpStrip(CDumpContext& dc)
+{
+ for(int tmp=0;tmp<m_Strip.GetSize();tmp++)
+ dc << tmp << ": " << m_Strip[tmp] << ";\n";
+}
+#endif
+
+
+CString CRegEx::GetMatch(int match)
+{
+CString rv;
+ if(!m_Matches.GetSize())
+ return rv;
+ ASSERT(m_Matches[0].m_Begin<m_Input.GetLength() && m_Matches[0].m_End<=m_Input.GetLength());
+ if(match==matchPreMatch)
+ return m_Input.Left(m_Matches[0].m_Begin);
+ if(match==matchPostMatch)
+ return m_Input.Mid(m_Matches[0].m_End);
+ if(match<0 || match >= m_Matches.GetSize())
+ return rv;
+ if(m_Matches[match].m_Begin<0 || m_Matches[match].m_End<0)
+ return rv;
+ ASSERT(m_Matches[match].m_Begin<m_Input.GetLength() && m_Matches[match].m_End<=m_Input.GetLength());
+ rv = m_Input.Mid(m_Matches[match].m_Begin,m_Matches[match].m_End-m_Matches[match].m_Begin);
+ return rv;
+}
diff --git a/shared-code/RegEx.h b/shared-code/RegEx.h
new file mode 100644
index 0000000..2534768
--- a/dev/null
+++ b/shared-code/RegEx.h
@@ -0,0 +1,158 @@
+#ifndef __REGEX_H
+#define __REGEX_H
+
+class CRegEx {
+public:
+ CString GetMatch(int match=0);
+ CString m_Input;
+ struct CMatch {
+ CMatch() : m_Begin(-1), m_End(-1) {}
+ int GetLength() { return m_End-m_Begin; }
+ int m_Begin;
+ int m_End;
+ };
+ typedef CArray<CMatch,CMatch&> CMatchBox;
+ enum {
+ matchMatch = 0,
+ matchPreMatch = -1,
+ matchPostMatch = -2
+ };
+ CMatchBox m_Matches;
+ enum {
+ charOut = 256,
+ charBOL, charEOL, charBOLEOL, charNothing, charBOW, charEOW,
+ charMaxCode = charEOW,
+ charNNChars = (charMaxCode-255)
+ };
+ int m_mFlags;
+ enum {
+ regeSuccess = 0,
+ regeNoMatch = 1, regeBadPattern, regeCollate, regeCType, regeEscape, regeSubReg, regeBracket,
+ regeParen, regeBrace, regeBadBrace, regeRange, regeSpace, regeBadRepeat, regeEmpty, regeAssert,
+ regeInvArg
+ };
+ int m_Error;
+ CRegEx();
+ BOOL m_bCompiled;
+ CString m_Pattern;
+ BOOL m_bBackRefs;
+ int m_Pluses;
+ CString m_Must;
+ BYTE m_Category[CHAR_MAX-CHAR_MIN+1];
+ int m_Categories;
+ int m_EOLs;
+ int m_BOLs;
+ int m_iFlags;
+ int m_Subexps;
+ struct CSop {
+ void Dump(CDumpContext& dc);
+ CSop() {}
+ CSop(BYTE op,DWORD opnd=0) : m_Operator(op), m_Operand(opnd) {}
+ BOOL operator==(CSop& other) {return m_Operator==other.m_Operator && m_Operand==other.m_Operand;}
+ BOOL operator!=(CSop& other) { return !((*this)==other);}
+ enum {
+ opEnd = 1, opChar, opBOL, opEOL, opAny, opAnyOf, opBackRef0, opBackRef1,
+ opPlus0, opPlus1, opQuest0, opQuest1, opLeftParen, opRightParen, opChoice0,
+ opOr0, opOr1, opChoice1, opBOW, opEOW
+ };
+ BYTE m_Operator;
+ DWORD m_Operand;
+ enum {
+ stCurrent = 1, stFresh = 2, stTemp = 4, stEmpty = 8
+ };
+ BYTE m_MatchData;
+ };
+ typedef CArray<CSop,CSop&> CStrip;
+ CStrip m_Strip;
+ int m_Flags;
+ struct CSet {
+ CSet() : m_Hash(0) { memset(m_Set,0,sizeof(m_Set)); }
+ CSet(CSet& src) { (*this)=src; }
+ CSet& operator=(CSet& src) { memmove(this,&src,sizeof(*this)); return *this; }
+ BOOL operator==(CSet& other) { if(m_Hash!=other.m_Hash)return FALSE;return !memcmp(m_Set,other.m_Set,sizeof(m_Set)); }
+ enum {
+ size = (CHAR_MAX-CHAR_MIN+1)
+ };
+ BOOL m_Set[size];
+ BYTE m_Hash;
+ public:
+ UCHAR GetOnly();
+ void Sub(UCHAR c);
+ BOOL IsIn(UCHAR c);
+ void Add(UCHAR c);
+ };
+ typedef CArray<CSet,CSet&> CSets;
+ CSets m_Sets;
+ enum {
+ // Compile flags
+ regBasic = 0, regExtended = 1,
+ regIgnoreCase = 2,
+ regNoSubExpressions = 4, // Also works for matching.
+ regNewLine = 16,
+ regLiteral = 32,
+ // Match Flags
+ regNotBOL = 1,
+ regNotEOL = 2,
+ regOneMatch=64,
+ regBackRefs=128,
+ // iFlags
+ iflagsUseBOL=1, iflagsUseEOL=2, iflagsBad=4
+ };
+ CString Replace(LPCTSTR src,LPCTSTR rep,int flags=0);
+ BOOL Match(LPCTSTR src,int flags=0);
+ BOOL Compile(LPCTSTR regex,int flags=0);
+private:
+#ifdef _DEBUG
+ void DumpStrip(CDumpContext& dc);
+#endif
+ LPCTSTR MatchBackRef(LPCTSTR begin,LPCTSTR end,int from,int to,int level);
+ typedef CArray<LPCTSTR,LPCTSTR> CStrPtrArray;
+ CStrPtrArray m_mLastPos;
+ LPCTSTR MatchDissect(LPCTSTR begin,LPCTSTR end,int from,int to);
+ LPCTSTR MatchSlow(LPCTSTR begin,LPCTSTR end,int from,int to);
+ LPCTSTR m_cOldP;
+ BOOL MatchStatesEqual(BYTE m1,BYTE m2);
+ LPCTSTR m_mBegin;
+ void MatchStatesCopy(BYTE dst,BYTE src);
+ void MatchStep(int from,int to,BYTE maskBefore,int charCode,BYTE maskAfter);
+ void MatchStatesClear(BYTE mask);
+ LPCTSTR MatchFast(LPCTSTR begin);
+ LPCTSTR m_mEnd;
+ LPCTSTR m_mPointer;
+ BOOL ParseBREexp(BOOL ordinaryStar);
+ void ParseBRE(int stopa=0,int stopb=0);
+ void ParseLiteral();
+ int CountPluses();
+ void FigureMust();
+ BOOL IsInSameSets(UCHAR c1,UCHAR c2);
+ BOOL IsInSets(UCHAR c);
+ void Categorize();
+ int StripDuplicate(int from,int to);
+ void EmitRepeat(int pos,int from,int to);
+ UCHAR ParseBracketSymbol();
+ UCHAR ParseBracketCollatingElement(UCHAR term);
+ void ParseBracketEClass(CSet& cset);
+ void ParseBracketCClass(CSet& cset);
+ void ParseBracketTerm(CSet& cset);
+ int StoreSet(CSet& cset);
+ void ParseBracket();
+ int ParseCount();
+ void EmitNonNewLineAny();
+ void EmitOrdinary(UCHAR c);
+ void StripInsert(int pos,CSop& sop);
+ void ParseEREexp();
+ void ParseERE(int stop=0);
+ struct CParenthesis {
+ long m_Begin;
+ long m_End;
+ CParenthesis(long b=0,long e=0) : m_Begin(b), m_End(e) {}
+ };
+ typedef CArray<CParenthesis,CParenthesis&> CParens;
+ CParens m_ParseParens;
+ int m_ParsePointer;
+};
+#ifdef _DEBUG
+inline CDumpContext& operator<<(CDumpContext& dc, CRegEx::CSop& sop) { sop.Dump(dc); return dc; }
+#endif
+
+#endif // __REGEX_H \ No newline at end of file
diff --git a/shared-code/SNMPExtDll.h b/shared-code/SNMPExtDll.h
new file mode 100644
index 0000000..14c920d
--- a/dev/null
+++ b/shared-code/SNMPExtDll.h
@@ -0,0 +1,252 @@
+#ifndef __SNMPEXTDLL_H
+#define __SNMPEXTDLL_H
+
+#include "snmpeer.h"
+
+#include <snmp.h>
+
+namespace Klever {
+
+class CSNMPExtDLL : public CSNMPeer {
+public:
+ HINSTANCE m_hInstance;
+ HANDLE m_hEvent;
+ AsnObjectIdentifier m_OID;
+ BOOL (SNMP_FUNC_TYPE *m_extInit)(DWORD dw,HANDLE h,AsnObjectIdentifier* aoid);
+ BOOL (SNMP_FUNC_TYPE *m_extQuery)(BYTE b,RFC1157VarBindList* rvbl,AsnInteger* ai1,AsnInteger* ai2);
+ BOOL (SNMP_FUNC_TYPE *m_extTrap)(AsnObjectIdentifier*,AsnNetworkAddress*,AsnInteger*,AsnInteger*,AsnTimeticks*,RFC1157VarBindList*);
+
+ HINSTANCE m_hSNMPAPI;
+ void (SNMP_FUNC_TYPE *m_snmpOIDFree)(AsnObjectIdentifier*);
+ LPVOID (SNMP_FUNC_TYPE *m_snmpAlloc)(UINT);
+ void (SNMP_FUNC_TYPE *m_snmpFree)(LPVOID);
+ void (SNMP_FUNC_TYPE *m_snmpVBLFree)(RFC1157VarBindList* vbl);
+ void InitSNMP() {
+ m_hSNMPAPI = ::LoadLibraryEx("SNMPAPI",NULL,0);
+ if(!m_hSNMPAPI)
+ return;
+ *(FARPROC*)&m_snmpOIDFree = ::GetProcAddress(m_hSNMPAPI,"SnmpUtilOidFree");
+ *(FARPROC*)&m_snmpAlloc = ::GetProcAddress(m_hSNMPAPI,"SnmpUtilMemAlloc");
+ *(FARPROC*)&m_snmpFree = ::GetProcAddress(m_hSNMPAPI,"SnmpUtilMemFree");
+ *(FARPROC*)&m_snmpVBLFree = ::GetProcAddress(m_hSNMPAPI,"SnmpUtilVarBindListFree");
+ if(
+ (m_snmpFree && !m_snmpAlloc) ||
+ (m_snmpAlloc && !m_snmpFree)
+ )
+ DeinitSNMP();
+ }
+ void DeinitSNMP() {
+ if(!m_hSNMPAPI)
+ return;
+ ::FreeLibrary(m_hSNMPAPI);
+ m_hSNMPAPI=NULL;
+ }
+ void SNMPFreeOID(AsnObjectIdentifier* oid) {
+ if(m_hSNMPAPI && m_snmpOIDFree)
+ (*m_snmpOIDFree)(oid);
+ else
+ ::GlobalFree((HGLOBAL)oid->ids);
+ }
+ LPVOID SNMPAlloc(UINT size) {
+ if(m_hSNMPAPI && m_snmpAlloc)
+ return (*m_snmpAlloc)(size);
+ else
+ return ::GlobalAlloc(GMEM_FIXED,size);
+ }
+ void SNMPFree(LPVOID addr) {
+ if(m_hSNMPAPI && m_snmpFree)
+ (*m_snmpFree)(addr);
+ else
+ :: GlobalFree((HGLOBAL)addr);
+ }
+ void SNMPFreeVBL(RFC1157VarBindList& vbl) {
+ if(m_hSNMPAPI && m_snmpVBLFree)
+ (*m_snmpVBLFree)(&vbl);
+ else{
+ for(UINT tmp=0;tmp<vbl.len;tmp++) {
+ SNMPFree(vbl.list[tmp].name.ids);
+ switch(vbl.list[tmp].value.asnType){
+ case ASN_OCTETSTRING:
+ case ASN_SEQUENCE:
+ case ASN_RFC1155_IPADDRESS:
+ case ASN_RFC1155_OPAQUE:
+// case ASN_RFC1213_DISPSTRING:
+ if(vbl.list[tmp].value.asnValue.arbitrary.dynamic)
+ SNMPFree(vbl.list[tmp].value.asnValue.arbitrary.stream);
+ break;
+ case ASN_OBJECTIDENTIFIER:
+ SNMPFree(vbl.list[tmp].value.asnValue.object.ids);
+ break;
+ default:
+ break;
+ }
+ }
+ SNMPFree(vbl.list);
+ }
+ }
+
+ BOOL SNMPBuildVBL(RFC1157VarBindList& vbl,CSNMPVarBindList& in) {
+ vbl.len = in.GetCount();
+ vbl.list = (RFC1157VarBind*)SNMPAlloc(sizeof(RFC1157VarBind)*vbl.len);
+ POSITION p = in.GetHeadPosition();
+ UINT ptr = 0;
+ while(p){
+ CSNMPVarBind& vb = in.GetNext(p);
+ ASSERT(ptr<vbl.len);
+ SNMPBuildVB(vbl.list[ptr++],vb);
+ }
+ return TRUE;
+ }
+ BOOL SNMPBuildVB(RFC1157VarBind& vb,CSNMPVarBind& in) {
+ ASSERT(in.name.type==CASNAny::typeASNOID);
+ return SNMPBuildOID(vb.name,in.name.value.oid) && SNMPBuildAA(vb.value,in.value);
+ }
+ BOOL SNMPBuildAA(AsnAny& aa,CASNAny& in) {
+ aa.asnType=in.type;
+ switch(in.type) {
+ case CASNAny::typeASNInteger:
+ aa.asnValue.number=in.value.number; break;
+ case CASNAny::typeASNOctetString:
+// case CASNAny::typeASNDispString:
+ SNMPBuildOS(aa.asnValue.string,in.value.string); break;
+ case CASNAny::typeASNNull:
+ break;
+ case CASNAny::typeASNOID:
+ SNMPBuildOID(aa.asnValue.object,in.value.oid); break;
+ case CASNAny::typeASNSequence:
+// case CASNAny::typeASNSequenceOf:
+ SNMPBuildOS(aa.asnValue.sequence,in.value.sequence); break;
+ case CASNAny::typeASNIP:
+ SNMPBuildFLOS(aa.asnValue.address,(LPBYTE)&in.value.ip,sizeof(in.value.ip)); break;
+ case CASNAny::typeASNCounter:
+ aa.asnValue.counter = in.value.counter; break;
+ case CASNAny::typeASNGauge:
+ aa.asnValue.gauge = in.value.gauge; break;
+ case CASNAny::typeASNTicks:
+ aa.asnValue.ticks = in.value.ticks; break;
+ case CASNAny::typeASNOpaque:
+ ASSERT(in.storeType==CASNAny::storeDynamic);
+ SNMPBuildOS(aa.asnValue.arbitrary,in.value.data); break;
+ break;
+ default:
+ ASSERT(FALSE);
+ return FALSE;
+ }
+ return TRUE;
+ }
+ BOOL SNMPBuildOS(AsnOctetString& os,CASNAny::asnOctetString& in) {
+ return SNMPBuildFLOS(os,in.data,in.size);
+ }
+ BOOL SNMPBuildOID(AsnObjectIdentifier& oid,CASNAny::asnOID& in) {
+ oid.idLength = in.size/sizeof(UINT);
+ ASSERT(!(in.size%sizeof(UINT)));
+ VERIFY(oid.ids = (UINT*)SNMPAlloc(in.size));
+ memmove(oid.ids,in.data,in.size);
+ return TRUE;
+ }
+ BOOL SNMPBuildFLOS(AsnOctetString& os,LPBYTE data,UINT size) {
+ os.length = size;
+ VERIFY(os.stream = (BYTE*)SNMPAlloc(os.length));
+ os.dynamic=TRUE;
+ memmove(os.stream,data,size);
+ return TRUE;
+ }
+ BOOL SNMPParseVBL(RFC1157VarBindList& vbl,CSNMPVarBindList& ou) {
+ for(UINT tmp=0;tmp<vbl.len;tmp++){
+ CSNMPVarBind vb;
+ SNMPParseVB(vbl.list[tmp],vb);
+ ou.AddTail(vb);
+ }
+ return TRUE;
+ }
+ BOOL SNMPParseVB(RFC1157VarBind& vb,CSNMPVarBind& ou) {
+ ou.name.Set(CASNAny::typeASNOID,(LPBYTE)vb.name.ids,vb.name.idLength*sizeof(UINT));
+ return SNMPParseAA(vb.value,ou.value);
+ }
+ BOOL SNMPParseAA(AsnAny& aa,CASNAny& ou) {
+ switch(aa.asnType){
+ case ASN_INTEGER:
+ ou.Set(CASNAny::typeASNInteger,aa.asnValue.number); break;
+ case ASN_OCTETSTRING:
+// case ASN_RFC1213_DISPSTRING:
+ ou.Set(CASNAny::typeASNOctetString,aa.asnValue.string.stream,aa.asnValue.string.length); break;
+ case ASN_OBJECTIDENTIFIER:
+ ou.Set(CASNAny::typeASNOID,(LPBYTE)aa.asnValue.object.ids,aa.asnValue.object.idLength);
+ SNMPParseOID(aa.asnValue.object,ou.value.oid); break;
+ case ASN_SEQUENCE:
+ ou.Set(CASNAny::typeASNSequence,aa.asnValue.sequence.stream,aa.asnValue.sequence.length); break;
+ case ASN_RFC1155_IPADDRESS:
+ SNMPParseIP(aa.asnValue.address,ou); break;
+ case ASN_RFC1155_COUNTER:
+ ou.Set(CASNAny::typeASNCounter,(LONG)aa.asnValue.counter); break;
+ case ASN_RFC1155_GAUGE:
+ ou.Set(CASNAny::typeASNGauge,(LONG)aa.asnValue.gauge); break;
+ case ASN_RFC1155_TIMETICKS:
+ ou.Set(CASNAny::typeASNTicks,(LONG)aa.asnValue.ticks); break;
+ case ASN_RFC1155_OPAQUE:
+ ou.Set(CASNAny::typeASNOpaque,aa.asnValue.arbitrary.stream,aa.asnValue.arbitrary.length); break;
+ case ASN_NULL:
+ ou.Free(); break;
+ default:
+ ASSERT(FALSE);
+ return FALSE;
+ }
+ return TRUE;
+ }
+ BOOL SNMPParseOID(AsnObjectIdentifier& oid,CASNAny::asnOID& ou) {
+ ASSERT(ou.size==(oid.idLength*sizeof(UINT)));
+ memmove(ou.data,oid.ids,ou.size);
+ return TRUE;
+ }
+ BOOL SNMPParseIP(AsnIPAddress& ip,CASNAny& ou) {
+ in_addr i;
+ if(ip.length>sizeof(i))
+ return FALSE;
+ i.s_addr=0;
+ memmove(&i,ip.stream,ip.length);
+ ou.Set(i);
+ return TRUE;
+ }
+
+
+ CSNMPExtDLL(LPCTSTR dllName) : m_hInstance(NULL) { InitSNMP(); Init(dllName); }
+ ~CSNMPExtDLL() { Deinit(); DeinitSNMP(); }
+
+ BOOL Init(LPCTSTR dllName) {
+ Deinit();
+ m_hInstance = ::LoadLibraryEx(dllName,NULL,0);
+ if(!m_hInstance)
+ return FALSE;
+ *(FARPROC*)&m_extInit = ::GetProcAddress(m_hInstance,"SnmpExtensionInit");
+ *(FARPROC*)&m_extQuery = ::GetProcAddress(m_hInstance,"SnmpExtensionQuery");
+ *(FARPROC*)&m_extTrap = ::GetProcAddress(m_hInstance,"SnmpExtensionTrap");
+ if(!(m_extInit && m_extQuery && m_extTrap)){
+ Deinit();
+ return FALSE;
+ }
+ if(!((*m_extInit)(GetCurrentTime(),&m_hEvent,&m_OID))){
+ Deinit();
+ return FALSE;
+ }
+ return TRUE;
+ }
+ void Deinit() {
+ if(!m_hInstance)
+ return;
+ ::FreeLibrary(m_hInstance);
+ }
+ virtual BOOL Request(BYTE type,CSNMPVarBindList& in,CSNMPVarBindList& ou) {
+ RFC1157VarBindList vbl;
+ SNMPBuildVBL(vbl,in);
+ AsnInteger errorStatus, errorIndex;
+ (*m_extQuery)(type,&vbl,&errorStatus,&errorIndex);
+ ou.RemoveAll();
+ SNMPParseVBL(vbl,ou);
+ SNMPFreeVBL(vbl);
+ return TRUE;
+ }
+};
+
+};
+
+#endif // __SNMPEXTDLL_H
diff --git a/shared-code/SNMPOIDs.h b/shared-code/SNMPOIDs.h
new file mode 100644
index 0000000..68ee659
--- a/dev/null
+++ b/shared-code/SNMPOIDs.h
@@ -0,0 +1,221 @@
+#ifndef __SNMPOIDS_H
+#define __SNMPOIDS_H
+
+#define DEFINE_OID(name,oid) static UINT name[] = oid
+
+// MIB-II OIDs
+
+#define OIDccitt {0}
+#define OIDnull {0,0}
+#define OIDiso {1}
+#define OIDorg {1,3}
+#define OIDdod {1,3,6}
+#define OIDinternet {1,3,6,1}
+#define OIDdirectory {1,3,6,1,1}
+#define OIDmgmt {1,3,6,1,2}
+#define OIDmib_2 {1,3,6,1,2,1}
+#define OIDsystem {1,3,6,1,2,1,1}
+#define OIDsysDescr {1,3,6,1,2,1,1,1}
+#define OIDsysObjectID {1,3,6,1,2,1,1,2}
+#define OIDsysUpTime {1,3,6,1,2,1,1,3}
+#define OIDsysContact {1,3,6,1,2,1,1,4}
+#define OIDsysName {1,3,6,1,2,1,1,5}
+#define OIDsysLocation {1,3,6,1,2,1,1,6}
+#define OIDsysServices {1,3,6,1,2,1,1,7}
+#define OIDtransmission {1,3,6,1,2,1,10}
+#define OIDsnmp {1,3,6,1,2,1,11}
+#define OIDsnmpInPkts {1,3,6,1,2,1,11,1}
+#define OIDsnmpInBadValues {1,3,6,1,2,1,11,10}
+#define OIDsnmpInReadOnlys {1,3,6,1,2,1,11,11}
+#define OIDsnmpInGenErrs {1,3,6,1,2,1,11,12}
+#define OIDsnmpInTotalReqVars {1,3,6,1,2,1,11,13}
+#define OIDsnmpInTotalSetVars {1,3,6,1,2,1,11,14}
+#define OIDsnmpInGetRequests {1,3,6,1,2,1,11,15}
+#define OIDsnmpInGetNexts {1,3,6,1,2,1,11,16}
+#define OIDsnmpInSetRequests {1,3,6,1,2,1,11,17}
+#define OIDsnmpInGetResponses {1,3,6,1,2,1,11,18}
+#define OIDsnmpInTraps {1,3,6,1,2,1,11,19}
+#define OIDsnmpOutPkts {1,3,6,1,2,1,11,2}
+#define OIDsnmpOutTooBigs {1,3,6,1,2,1,11,20}
+#define OIDsnmpOutNoSuchNames {1,3,6,1,2,1,11,21}
+#define OIDsnmpOutBadValues {1,3,6,1,2,1,11,22}
+#define OIDsnmpOutGenErrs {1,3,6,1,2,1,11,24}
+#define OIDsnmpOutGetRequests {1,3,6,1,2,1,11,25}
+#define OIDsnmpOutGetNexts {1,3,6,1,2,1,11,26}
+#define OIDsnmpOutSetRequests {1,3,6,1,2,1,11,27}
+#define OIDsnmpOutGetResponses {1,3,6,1,2,1,11,28}
+#define OIDsnmpOutTraps {1,3,6,1,2,1,11,29}
+#define OIDsnmpInBadVersions {1,3,6,1,2,1,11,3}
+#define OIDsnmpEnableAuthenTraps {1,3,6,1,2,1,11,30}
+#define OIDsnmpInBadCommunityNames {1,3,6,1,2,1,11,4}
+#define OIDsnmpInBadCommunityUses {1,3,6,1,2,1,11,5}
+#define OIDsnmpInASNParseErrs {1,3,6,1,2,1,11,6}
+#define OIDsnmpInTooBigs {1,3,6,1,2,1,11,8}
+#define OIDsnmpInNoSuchNames {1,3,6,1,2,1,11,9}
+#define OIDinterfaces {1,3,6,1,2,1,2}
+#define OIDifNumber {1,3,6,1,2,1,2,1}
+#define OIDifTable {1,3,6,1,2,1,2,2}
+#define OIDifEntry {1,3,6,1,2,1,2,2,1}
+#define OIDifIndex {1,3,6,1,2,1,2,2,1,1}
+#define OIDifInOctets {1,3,6,1,2,1,2,2,1,10}
+#define OIDifInUcastPkts {1,3,6,1,2,1,2,2,1,11}
+#define OIDifInNUcastPkts {1,3,6,1,2,1,2,2,1,12}
+#define OIDifInDiscards {1,3,6,1,2,1,2,2,1,13}
+#define OIDifInErrors {1,3,6,1,2,1,2,2,1,14}
+#define OIDifInUnknownProtos {1,3,6,1,2,1,2,2,1,15}
+#define OIDifOutOctets {1,3,6,1,2,1,2,2,1,16}
+#define OIDifOutUcastPkts {1,3,6,1,2,1,2,2,1,17}
+#define OIDifOutNUcastPkts {1,3,6,1,2,1,2,2,1,18}
+#define OIDifOutDiscards {1,3,6,1,2,1,2,2,1,19}
+#define OIDifDescr {1,3,6,1,2,1,2,2,1,2}
+#define OIDifOutErrors {1,3,6,1,2,1,2,2,1,20}
+#define OIDifOutQLen {1,3,6,1,2,1,2,2,1,21}
+#define OIDifSpecific {1,3,6,1,2,1,2,2,1,22}
+#define OIDifType {1,3,6,1,2,1,2,2,1,3}
+#define OIDifMtu {1,3,6,1,2,1,2,2,1,4}
+#define OIDifSpeed {1,3,6,1,2,1,2,2,1,5}
+#define OIDifPhysAddress {1,3,6,1,2,1,2,2,1,6}
+#define OIDifAdminStatus {1,3,6,1,2,1,2,2,1,7}
+#define OIDifOperStatus {1,3,6,1,2,1,2,2,1,8}
+#define OIDifLastChange {1,3,6,1,2,1,2,2,1,9}
+#define OIDat {1,3,6,1,2,1,3}
+#define OIDatTable {1,3,6,1,2,1,3,1}
+#define OIDatEntry {1,3,6,1,2,1,3,1,1}
+#define OIDatIfIndex {1,3,6,1,2,1,3,1,1,1}
+#define OIDatPhysAddress {1,3,6,1,2,1,3,1,1,2}
+#define OIDatNetAddress {1,3,6,1,2,1,3,1,1,3}
+#define OIDip {1,3,6,1,2,1,4}
+#define OIDipForwarding {1,3,6,1,2,1,4,1}
+#define OIDipOutRequests {1,3,6,1,2,1,4,10}
+#define OIDipOutDiscards {1,3,6,1,2,1,4,11}
+#define OIDipOutNoRoutes {1,3,6,1,2,1,4,12}
+#define OIDipReasmTimeout {1,3,6,1,2,1,4,13}
+#define OIDipReasmReqds {1,3,6,1,2,1,4,14}
+#define OIDipReasmOKs {1,3,6,1,2,1,4,15}
+#define OIDipReasmFails {1,3,6,1,2,1,4,16}
+#define OIDipFragOKs {1,3,6,1,2,1,4,17}
+#define OIDipFragFails {1,3,6,1,2,1,4,18}
+#define OIDipFragCreates {1,3,6,1,2,1,4,19}
+#define OIDipDefaultTTL {1,3,6,1,2,1,4,2}
+#define OIDipAddrTable {1,3,6,1,2,1,4,20}
+#define OIDipAddrEntry {1,3,6,1,2,1,4,20,1}
+#define OIDipAdEntAddr {1,3,6,1,2,1,4,20,1,1}
+#define OIDipAdEntIfIndex {1,3,6,1,2,1,4,20,1,2}
+#define OIDipAdEntNetMask {1,3,6,1,2,1,4,20,1,3}
+#define OIDipAdEntBcastAddr {1,3,6,1,2,1,4,20,1,4}
+#define OIDipAdEntReasmMaxSize {1,3,6,1,2,1,4,20,1,5}
+#define OIDipRouteTable {1,3,6,1,2,1,4,21}
+#define OIDipRouteEntry {1,3,6,1,2,1,4,21,1}
+#define OIDipRouteDest {1,3,6,1,2,1,4,21,1,1}
+#define OIDipRouteAge {1,3,6,1,2,1,4,21,1,10}
+#define OIDipRouteMask {1,3,6,1,2,1,4,21,1,11}
+#define OIDipRouteMetric5 {1,3,6,1,2,1,4,21,1,12}
+#define OIDipRouteInfo {1,3,6,1,2,1,4,21,1,13}
+#define OIDipRouteIfIndex {1,3,6,1,2,1,4,21,1,2}
+#define OIDipRouteMetric1 {1,3,6,1,2,1,4,21,1,3}
+#define OIDipRouteMetric2 {1,3,6,1,2,1,4,21,1,4}
+#define OIDipRouteMetric3 {1,3,6,1,2,1,4,21,1,5}
+#define OIDipRouteMetric4 {1,3,6,1,2,1,4,21,1,6}
+#define OIDipRouteNextHop {1,3,6,1,2,1,4,21,1,7}
+#define OIDipRouteType {1,3,6,1,2,1,4,21,1,8}
+#define OIDipRouteProto {1,3,6,1,2,1,4,21,1,9}
+#define OIDipNetToMediaTable {1,3,6,1,2,1,4,22}
+#define OIDipNetToMediaEntry {1,3,6,1,2,1,4,22,1}
+#define OIDipNetToMediaIfIndex {1,3,6,1,2,1,4,22,1,1}
+#define OIDipNetToMediaPhysAddress {1,3,6,1,2,1,4,22,1,2}
+#define OIDipNetToMediaNetAddress {1,3,6,1,2,1,4,22,1,3}
+#define OIDipNetToMediaType {1,3,6,1,2,1,4,22,1,4}
+#define OIDipRoutingDiscards {1,3,6,1,2,1,4,23}
+#define OIDipInReceives {1,3,6,1,2,1,4,3}
+#define OIDipInHdrErrors {1,3,6,1,2,1,4,4}
+#define OIDipInAddrErrors {1,3,6,1,2,1,4,5}
+#define OIDipForwDatagrams {1,3,6,1,2,1,4,6}
+#define OIDipInUnknownProtos {1,3,6,1,2,1,4,7}
+#define OIDipInDiscards {1,3,6,1,2,1,4,8}
+#define OIDipInDelivers {1,3,6,1,2,1,4,9}
+#define OIDicmp {1,3,6,1,2,1,5}
+#define OIDicmpInMsgs {1,3,6,1,2,1,5,1}
+#define OIDicmpInTimestamps {1,3,6,1,2,1,5,10}
+#define OIDicmpInTimestampReps {1,3,6,1,2,1,5,11}
+#define OIDicmpInAddrMasks {1,3,6,1,2,1,5,12}
+#define OIDicmpInAddrMaskReps {1,3,6,1,2,1,5,13}
+#define OIDicmpOutMsgs {1,3,6,1,2,1,5,14}
+#define OIDicmpOutErrors {1,3,6,1,2,1,5,15}
+#define OIDicmpOutDestUnreachs {1,3,6,1,2,1,5,16}
+#define OIDicmpOutTimeExcds {1,3,6,1,2,1,5,17}
+#define OIDicmpOutParmProbs {1,3,6,1,2,1,5,18}
+#define OIDicmpOutSrcQuenchs {1,3,6,1,2,1,5,19}
+#define OIDicmpInErrors {1,3,6,1,2,1,5,2}
+#define OIDicmpOutRedirects {1,3,6,1,2,1,5,20}
+#define OIDicmpOutEchos {1,3,6,1,2,1,5,21}
+#define OIDicmpOutEchoReps {1,3,6,1,2,1,5,22}
+#define OIDicmpOutTimestamps {1,3,6,1,2,1,5,23}
+#define OIDicmpOutTimestampReps {1,3,6,1,2,1,5,24}
+#define OIDicmpOutAddrMasks {1,3,6,1,2,1,5,25}
+#define OIDicmpOutAddrMaskReps {1,3,6,1,2,1,5,26}
+#define OIDicmpInDestUnreachs {1,3,6,1,2,1,5,3}
+#define OIDicmpInTimeExcds {1,3,6,1,2,1,5,4}
+#define OIDicmpInParmProbs {1,3,6,1,2,1,5,5}
+#define OIDicmpInSrcQuenchs {1,3,6,1,2,1,5,6}
+#define OIDicmpInRedirects {1,3,6,1,2,1,5,7}
+#define OIDicmpInEchos {1,3,6,1,2,1,5,8}
+#define OIDicmpInEchoReps {1,3,6,1,2,1,5,9}
+#define OIDtcp {1,3,6,1,2,1,6}
+#define OIDtcpRtoAlgorithm {1,3,6,1,2,1,6,1}
+#define OIDtcpInSegs {1,3,6,1,2,1,6,10}
+#define OIDtcpOutSegs {1,3,6,1,2,1,6,11}
+#define OIDtcpRetransSegs {1,3,6,1,2,1,6,12}
+#define OIDtcpConnTable {1,3,6,1,2,1,6,13}
+#define OIDtcpConnEntry {1,3,6,1,2,1,6,13,1}
+#define OIDtcpConnState {1,3,6,1,2,1,6,13,1,1}
+#define OIDtcpConnLocalAddress {1,3,6,1,2,1,6,13,1,2}
+#define OIDtcpConnLocalPort {1,3,6,1,2,1,6,13,1,3}
+#define OIDtcpConnRemAddress {1,3,6,1,2,1,6,13,1,4}
+#define OIDtcpConnRemPort {1,3,6,1,2,1,6,13,1,5}
+#define OIDtcpInErrs {1,3,6,1,2,1,6,14}
+#define OIDtcpOutRsts {1,3,6,1,2,1,6,15}
+#define OIDtcpRtoMin {1,3,6,1,2,1,6,2}
+#define OIDtcpRtoMax {1,3,6,1,2,1,6,3}
+#define OIDtcpMaxConn {1,3,6,1,2,1,6,4}
+#define OIDtcpActiveOpens {1,3,6,1,2,1,6,5}
+#define OIDtcpPassiveOpens {1,3,6,1,2,1,6,6}
+#define OIDtcpAttemptFails {1,3,6,1,2,1,6,7}
+#define OIDtcpEstabResets {1,3,6,1,2,1,6,8}
+#define OIDtcpCurrEstab {1,3,6,1,2,1,6,9}
+#define OIDudp {1,3,6,1,2,1,7}
+#define OIDudpInDatagrams {1,3,6,1,2,1,7,1}
+#define OIDudpNoPorts {1,3,6,1,2,1,7,2}
+#define OIDudpInErrors {1,3,6,1,2,1,7,3}
+#define OIDudpOutDatagrams {1,3,6,1,2,1,7,4}
+#define OIDudpTable {1,3,6,1,2,1,7,5}
+#define OIDudpEntry {1,3,6,1,2,1,7,5,1}
+#define OIDudpLocalAddress {1,3,6,1,2,1,7,5,1,1}
+#define OIDudpLocalPort {1,3,6,1,2,1,7,5,1,2}
+#define OIDegp {1,3,6,1,2,1,8}
+#define OIDegpInMsgs {1,3,6,1,2,1,8,1}
+#define OIDegpInErrors {1,3,6,1,2,1,8,2}
+#define OIDegpOutMsgs {1,3,6,1,2,1,8,3}
+#define OIDegpOutErrors {1,3,6,1,2,1,8,4}
+#define OIDegpNeighTable {1,3,6,1,2,1,8,5}
+#define OIDegpNeighEntry {1,3,6,1,2,1,8,5,1}
+#define OIDegpNeighState {1,3,6,1,2,1,8,5,1,1}
+#define OIDegpNeighStateUps {1,3,6,1,2,1,8,5,1,10}
+#define OIDegpNeighStateDowns {1,3,6,1,2,1,8,5,1,11}
+#define OIDegpNeighIntervalHello {1,3,6,1,2,1,8,5,1,12}
+#define OIDegpNeighIntervalPoll {1,3,6,1,2,1,8,5,1,13}
+#define OIDegpNeighMode {1,3,6,1,2,1,8,5,1,14}
+#define OIDegpNeighEventTrigger {1,3,6,1,2,1,8,5,1,15}
+#define OIDegpNeighAddr {1,3,6,1,2,1,8,5,1,2}
+#define OIDegpNeighAs {1,3,6,1,2,1,8,5,1,3}
+#define OIDegpNeighInMsgs {1,3,6,1,2,1,8,5,1,4}
+#define OIDegpNeighInErrs {1,3,6,1,2,1,8,5,1,5}
+#define OIDegpNeighOutMsgs {1,3,6,1,2,1,8,5,1,6}
+#define OIDegpNeighOutErrs {1,3,6,1,2,1,8,5,1,7}
+#define OIDegpNeighInErrMsgs {1,3,6,1,2,1,8,5,1,8}
+#define OIDegpNeighOutErrMsgs {1,3,6,1,2,1,8,5,1,9}
+#define OIDegpAs {1,3,6,1,2,1,8,6}
+#define OIDexperimental {1,3,6,1,3}
+#define OIDprivate {1,3,6,1,4}
+#define OIDenterprises {1,3,6,1,4,1}
+
+#endif // __SNMPOIDS_H \ No newline at end of file
diff --git a/shared-code/SNMPeer.h b/shared-code/SNMPeer.h
new file mode 100644
index 0000000..68f2efe
--- a/dev/null
+++ b/shared-code/SNMPeer.h
@@ -0,0 +1,286 @@
+#ifndef __SNMPEER_H
+#define __SNMPEER_H
+
+namespace Klever {
+
+class CASNAny {
+public:
+ enum {
+ asnCls = 0xC0,
+ asnClsUniversal = 0x00,
+ asnClsApplication = 0x40,
+ asnClsContextSpecific = 0x80,
+ asnClsPrivate = 0xC0,
+ asnConstructed = 0x20,
+ asnPrimitive = 0x00,
+ asnTag = 0x1F,
+ // ASN.1 Primitive Tags
+ asnTagInteger = 0x02,
+ asnTagOctetString = 0x04,
+ asnTagNull = 0x05,
+ asnTagOID = 0x06,
+ // ASN.1 Constructed Tags
+ asnTagSequence = 0x10,
+ // RFC1155 Primitive Tags
+ asnTagIP = 0x00,
+ asnTagCounter = 0x01,
+ asnTagGauge = 0x02,
+ asnTagTicks = 0x03,
+ asnTagOpaque = 0x04,
+ // RFC1213 alias
+ asnTagDispString = 0x04, // (ASN.1 Octet string)
+ // RFC1157 Constructed Tags
+ asnTagGetRequest = 0x00,
+ asnTagGetNextRequest = 0x01,
+ asnTagGetResponse = 0x02,
+ asnTagSetRequest = 0x03,
+ asnTagTrap = 0x04
+ };
+ enum {
+ typeASNInteger = (asnClsUniversal|asnPrimitive|asnTagInteger),
+ typeASNOctetString = (asnClsUniversal|asnPrimitive|asnTagOctetString),
+ typeASNNull = (asnClsUniversal|asnPrimitive|asnTagNull),
+ typeASNOID = (asnClsUniversal|asnPrimitive|asnTagOID),
+
+ typeASNSequence = (asnClsUniversal|asnConstructed|asnTagSequence),
+ typeASNSequenceOf = (asnClsUniversal|asnConstructed|asnTagSequence),
+
+ typeASNIP = (asnClsApplication|asnPrimitive|asnTagIP),
+ typeASNCounter = (asnClsApplication|asnPrimitive|asnTagCounter),
+ typeASNGauge = (asnClsApplication|asnPrimitive|asnTagGauge),
+ typeASNTicks = (asnClsApplication|asnPrimitive|asnTagTicks),
+ typeASNOpaque = (asnClsApplication|asnPrimitive|asnTagOpaque),
+ typeASNDispString = (asnClsUniversal|asnPrimitive|asnTagOctetString),
+
+ typeASNGetRequest = (asnClsContextSpecific|asnConstructed|asnTagGetRequest),
+ typeASNGetNextRequest = (asnClsContextSpecific|asnConstructed|asnTagGetNextRequest),
+ typeASNGetResponse = (asnClsContextSpecific|asnConstructed|asnTagGetResponse),
+ typeASNSetRequest = (asnClsContextSpecific|asnConstructed|asnTagSetRequest),
+ typeASNTrap = (asnClsContextSpecific|asnConstructed|asnTagTrap)
+ };
+
+ typedef LONG asnInteger;
+ typedef LARGE_INTEGER asnInteger64;
+ typedef DWORD asnCounter;
+ typedef ULARGE_INTEGER asnCounter64;
+ typedef DWORD asnGauge;
+ typedef ULARGE_INTEGER asnGauge64;
+ typedef DWORD asnTicks;
+ typedef ULARGE_INTEGER asnTicks64;
+ struct asnDynamic {
+ UINT size;
+ LPBYTE data;
+ BOOL Allocate(UINT size) {
+ BOOL rv = Free();
+ if(size)
+ rv=rv&&(data=new BYTE[size]);
+ if(rv)
+ asnDynamic::size=size;
+ return rv;
+ }
+ BOOL Set(LPBYTE data,UINT size) {
+ BOOL rv = Allocate(size);
+ if(rv && size)
+ memmove(asnDynamic::data,data,size);
+ return rv;
+ }
+ BOOL Free() {
+ if(!size)
+ return TRUE;
+ delete data;
+ size=0;
+ data=0;
+ return TRUE;
+ }
+ void Clean() {
+ size=0;
+ data=0;
+ }
+ BOOL Copy(asnDynamic& src) {
+ BOOL rv = Free();
+ if(rv){
+ if(src.size)
+ rv=rv&&(data = new BYTE[src.size]);
+ if(rv){
+ if(size=src.size)
+ memmove(data,src.data,size);
+ }
+ }
+ return rv;
+ }
+ };
+ typedef asnDynamic asnOctetString;
+ typedef asnDynamic asnOID;
+ typedef in_addr asnIP;
+ typedef asnDynamic asnSequence;
+
+ BYTE type;
+ enum _storeType {
+ storeDynamic,
+ storeStatic
+ } storeType;
+ union {
+ asnInteger number;
+ asnInteger64 number64;
+ asnOctetString string;
+ asnOID oid;
+ asnSequence sequence;
+ asnIP ip;
+ asnCounter counter;
+ asnCounter64 counter64;
+ asnGauge gauge;
+ asnGauge64 gauge64;
+ asnTicks ticks;
+ asnTicks64 ticks64;
+ asnDynamic data;
+ } value;
+
+ CASNAny() : type(typeASNNull), storeType(storeStatic) { value.data.Clean(); }
+ CASNAny(CASNAny& src) : type(typeASNNull), storeType(storeStatic) { value.data.Clean();Copy(src); }
+ CASNAny(BYTE type) : type(type), storeType(storeStatic) { value.data.Clean(); }
+ CASNAny(BYTE type,LONG number) : type(typeASNNull), storeType(storeStatic) { value.data.Clean();Set(type,number); }
+ CASNAny(BYTE type,LONGLONG number) : type(typeASNNull), storeType(storeStatic) { value.data.Clean();Set(type,number); }
+ CASNAny(BYTE type,LPCTSTR string) : type(typeASNNull), storeType(storeStatic) { value.data.Clean();Set(type,string); }
+ CASNAny(BYTE type,LPBYTE data,UINT length) : type(typeASNNull), storeType(storeStatic) { value.data.Clean();Set(type,data,length); }
+ CASNAny(BYTE type,UINT* data,UINT size) : type(typeASNNull), storeType(storeStatic) { value.data.Clean();Set(type,(LPBYTE)data,size); }
+ CASNAny(in_addr& ip) : type(typeASNNull), storeType(storeStatic) { value.data.Clean();Set(ip); }
+ ~CASNAny() { Free(); }
+
+ BOOL Set(BYTE type) {
+ BOOL rv = Free();
+ CASNAny::type=type;
+ return rv;
+ }
+ BOOL Set(BYTE type,LONG number) {
+ BOOL rv = Free();
+ CASNAny::type=type;
+ value.number=number;
+ storeType=storeStatic;
+ return rv;
+ }
+ BOOL Set(BYTE type,LONGLONG number) {
+ BOOL rv = Free();
+ CASNAny::type=type;
+ value.number64.QuadPart = number;
+ storeType=storeStatic;
+ return rv;
+ }
+ BOOL Set(BYTE type,LPCTSTR string) {
+ BOOL rv = Free();
+ CASNAny::type=type;
+ rv=rv&&value.string.Set((LPBYTE)string,strlen(string)+1);
+ if(rv){
+ value.string.size--;
+ storeType=storeDynamic;
+ }
+ return rv;
+ }
+ BOOL Set(BYTE type,LPBYTE data,UINT length) {
+ BOOL rv = Free();
+ CASNAny::type=type;
+ rv=rv&&value.data.Set(data,length);
+ if(rv)
+ storeType=storeDynamic;
+ return rv;
+ }
+ BOOL Set(in_addr& ip) {
+ BOOL rv = Free();
+ memmove(&value.ip,&ip,sizeof(value.ip));
+ type=typeASNIP;
+ storeType=storeStatic;
+ return rv;
+ }
+ BOOL Free() {
+ if(storeType==storeDynamic)
+ value.data.Free();
+ else{
+ memset(&value,0,sizeof(value));
+ value.data.Clean();
+ }
+ storeType=storeStatic;
+ type=typeASNNull;
+ return TRUE;
+ }
+ BOOL Copy(CASNAny& src) {
+ BOOL rv = Free();
+ if(src.storeType==storeDynamic){
+ rv=rv&&value.data.Copy(src.value.data);
+ if(rv){
+ type=src.type;
+ storeType=src.storeType;
+ }
+ }else{
+ memmove(this,&src,sizeof(*this));
+ }
+ return rv;
+ }
+ CASNAny& operator=(CASNAny& src) {
+ VERIFY(Copy(src));
+ return *this;
+ }
+
+ // High Level
+ CString GetString() {
+ ASSERT(storeType==storeDynamic);
+ CString rv;
+ LPTSTR b = rv.GetBuffer(value.data.size+1);
+ ASSERT(b);
+ b[value.data.size]=0;
+ memmove(b,value.data.data,value.data.size);
+ rv.ReleaseBuffer();
+ return rv;
+ }
+};
+
+
+class CSNMPVarBind {
+public:
+ CASNAny name;
+ CASNAny value;
+
+ CSNMPVarBind() {}
+ CSNMPVarBind(CASNAny& name,CASNAny& value) : name(name), value(value) {}
+ CSNMPVarBind(CASNAny& name) : name(name) {}
+ CSNMPVarBind(CSNMPVarBind& src) { Copy(src); }
+ BOOL Copy(CSNMPVarBind& src) {
+ name.Copy(src.name);
+ value.Copy(src.value);
+ return TRUE;
+ }
+ CSNMPVarBind& operator=(CSNMPVarBind& src) {
+ Copy(src);
+ return *this;
+ }
+ // High level
+ BOOL IsName(UINT* prefix,UINT prefixSize,BOOL bExact=FALSE) {
+ if(name.type!=CASNAny::typeASNOID)
+ return FALSE;
+ if(name.value.oid.size<prefixSize)
+ return FALSE;
+ if(bExact && (name.value.oid.size!=prefixSize))
+ return FALSE;
+ return !memcmp(prefix,name.value.oid.data,prefixSize);
+ }
+};
+
+class CSNMPVarBindList : public CList<CSNMPVarBind,CSNMPVarBind&> {
+public:
+ CSNMPVarBind* GetVarBind(UINT* prefix,UINT prefixSize,BOOL bExact=FALSE) {
+ POSITION p = GetHeadPosition();
+ while(p){
+ CSNMPVarBind& vb = GetNext(p);
+ if(vb.IsName(prefix,prefixSize,bExact))
+ return &vb;
+ }
+ return NULL;
+ }
+};
+
+class CSNMPeer {
+public:
+ virtual BOOL Request(BYTE type,CSNMPVarBindList& in,CSNMPVarBindList& ou) = 0;
+};
+
+};
+
+#endif // __SNMPEER_H
diff --git a/shared-code/install.h b/shared-code/install.h
new file mode 100644
index 0000000..8c55ca9
--- a/dev/null
+++ b/shared-code/install.h
@@ -0,0 +1,370 @@
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRALEAN
+#define WIN32_EXTRALEAN
+#include <windows.h>
+#include <shlobj.h>
+#include <winver.h>
+#include <crtdbg.h>
+#include <string.h>
+#include <stdio.h>
+
+extern "C" WINSHELLAPI void WINAPI SHFree( LPVOID);
+
+template<class T> class Smart {
+public:
+ T *pT;
+
+ Smart() : pT(NULL) {}
+ Smart(int cb) : pT(new T[cb]) {}
+ Smart(T* p) : pT(p) {}
+ ~Smart() { if(pT)delete pT; }
+
+ Smart& operator=(T* p) { if(pT)delete pT; pT=p; return *this; }
+ operator T* () { return pT; }
+
+// T& operator[](int ndx) { return pT[ndx]; }
+
+ T* Detach() { T* rv = pT; pT=NULL; return rv; }
+};
+typedef Smart<char> STRING;
+
+#define APPEND_SLASH(str) if((str)[strlen(str)-1]!='\\')strcat(str,"\\")
+
+HINSTANCE theInstance;
+
+LPSTR strFETCH_REG_KEY(HKEY hRoot,LPCSTR subKey,LPCSTR val)
+{
+HKEY hkey;
+ if(RegOpenKeyEx(hRoot,subKey,0,KEY_QUERY_VALUE,&hkey)!=ERROR_SUCCESS)
+ return NULL;
+DWORD kType,cb=0;
+STRING rv;
+ if(RegQueryValueEx(hkey,val,NULL,&kType,NULL,&cb)==ERROR_SUCCESS && kType==REG_SZ){
+ rv= new char[cb];
+ _ASSERT(rv!=NULL);
+ if(RegQueryValueEx(hkey,val,NULL,&kType,(LPBYTE)(LPSTR)rv,&cb)!=ERROR_SUCCESS)
+ rv=NULL;
+ }
+ RegCloseKey(hkey);
+ return rv.Detach();
+}
+
+BOOL strSET_REG_KEY(HKEY hRoot,LPCSTR subKey,LPCSTR valName,LPCSTR val)
+{
+HKEY hkey;
+DWORD dw;
+ if(RegCreateKeyEx(hRoot,subKey,0,REG_NONE,REG_OPTION_NON_VOLATILE,KEY_READ|KEY_WRITE,NULL,&hkey,&dw)!=ERROR_SUCCESS)
+ return FALSE;
+BOOL rv = (RegSetValueEx(hkey,valName,0,REG_SZ,(LPBYTE)val,strlen(val)+1)==ERROR_SUCCESS);
+ RegCloseKey(hkey);
+ return rv;
+}
+
+void MAKE_PATH(LPCSTR path)
+{
+STRING tmp(strlen(path)+1);
+LPCSTR t0=path;
+LPSTR t1=tmp;
+ while(*t0){
+ if((*t0)=='\\'){
+ *t1=0;
+ CreateDirectory(tmp,NULL);
+ }
+ *(t1++)=*(t0++);
+ }
+ *t1=0;
+ CreateDirectory(tmp,NULL);
+}
+
+BOOL ADDMENU(LPCSTR menu,LPCSTR item,LPCSTR path,LPCSTR program)
+{
+STRING stm = strFETCH_REG_KEY(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders","Programs");
+ if(!stm)
+ return FALSE;
+int pil = 1+strlen(path)+1+strlen(program)+1+1;
+STRING pi(pil);
+ strcpy(pi,path);
+ APPEND_SLASH(pi);
+ strcat(pi,program);
+int ipl = strlen(stm)+1+strlen(menu)+1+strlen(item)+4+1;
+STRING ip(ipl);
+ memmove(ip,stm,strlen(stm)+1);
+ APPEND_SLASH(ip);
+ strcat(ip,menu);
+ MAKE_PATH(ip);
+ APPEND_SLASH(ip);
+ strcat(ip,item);
+ strcat(ip,".lnk");
+IShellLink* sl = NULL;
+IPersistFile* pf = NULL;
+BOOL rv = FALSE;
+ do{
+ HRESULT hrv = CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(LPVOID*)&sl);
+ if(!SUCCEEDED(hrv))
+ break;
+ sl->SetDescription(item);
+ sl->SetPath(pi);
+ hrv = sl->QueryInterface(IID_IPersistFile,(LPVOID*)&pf);
+ if(!SUCCEEDED(hrv))
+ break;
+ WORD wsz[MAX_PATH];
+ MultiByteToWideChar(CP_ACP,0,ip,-1,wsz,MAX_PATH);
+ hrv = pf->Save(wsz,TRUE);
+ if(SUCCEEDED(hrv))
+ rv=TRUE;
+ }while(FALSE);
+ if(pf)
+ pf->Release();
+ if(sl)
+ sl->Release();
+ return rv;
+}
+
+FILE* CREATE_INF_FILE(LPCSTR path,LPCSTR file)
+{
+STRING fn(strlen(path)+1+strlen(file)+1);
+ strcpy(fn,path);
+ APPEND_SLASH(fn);
+ strcat(fn,file);
+ return fopen(fn,"wt");
+}
+
+BOOL INSTALLFILE(LPCSTR res,LPCSTR path,LPCSTR file)
+{
+STRING temp(MAX_PATH);
+ if(!GetTempPath(MAX_PATH,temp)) return FALSE;
+STRING tf(MAX_PATH);
+ if(!GetTempFileName(temp,"KGI",0,tf)) return FALSE;
+HRSRC hrsrc = FindResource(NULL,res,MAKEINTRESOURCE(RT_RCDATA));
+ if(!hrsrc) return FALSE;
+DWORD sor = SizeofResource(NULL,hrsrc);
+ if(!sor) return FALSE;
+HGLOBAL hglobal = LoadResource(NULL,hrsrc);
+ if(!hglobal) return FALSE;
+LPVOID lpv = LockResource(hglobal);
+ if(!lpv) return FALSE;
+HANDLE hf = CreateFile(tf,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY,NULL);
+ if(!hf) return FALSE;
+DWORD written = 0;
+ if(!WriteFile(hf,lpv,sor,&written,NULL) || written!=sor){
+ CloseHandle(hf);
+ return FALSE;
+ }
+ CloseHandle(hf);
+STRING toKill(strlen(tf)+1);
+ strcpy(toKill,tf);
+ for(int tmp=strlen(tf)-1;tmp>0 && ((tf[tmp])!='\\');tmp--);
+ if(tf[tmp]=='\\')
+ tf[tmp++]=0;
+STRING nothing(_MAX_PATH);
+UINT nothingLength=_MAX_PATH;
+ if(VerInstallFile(0,&tf[tmp],(LPSTR)file,tf,(LPSTR)path,NULL,nothing,&nothingLength)){
+ DeleteFile(toKill);
+ return FALSE;
+ }
+ DeleteFile(toKill);
+ return TRUE;
+}
+
+LPCSTR pdTitle, pdPrompt;
+char pdPath[_MAX_PATH];
+BOOL CALLBACK pathDlgProc(HWND hwnd,UINT uMsg,WPARAM wP,LPARAM lP)
+{
+ switch(uMsg){
+ case WM_INITDIALOG:
+ SetWindowText(hwnd,pdTitle);
+ SetDlgItemText(hwnd,IDC_PROMPT,pdPrompt);
+ SetDlgItemText(hwnd,IDC_PATH,pdPath);
+ SetWindowPos(hwnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
+ return 1;
+ case WM_COMMAND:
+ switch(LOWORD(wP)){ // ID
+ case IDC_BROWSE:
+ switch(HIWORD(wP)){
+ case BN_CLICKED:
+ {
+ BROWSEINFO bi;
+ memset(&bi,0,sizeof(bi));
+ bi.hwndOwner=hwnd;
+ bi.pszDisplayName=pdPath;
+ bi.lpszTitle="Select Folder..";
+ bi.ulFlags=BIF_RETURNONLYFSDIRS;
+ LPITEMIDLIST lpidl=SHBrowseForFolder(&bi);
+ if(lpidl){
+ SHGetPathFromIDList(lpidl,pdPath);
+ SHFree(lpidl);
+ SetDlgItemText(hwnd,IDC_PATH,pdPath);
+ }
+ }
+ return 1;
+ }
+ break;
+ case IDOK:
+ switch(HIWORD(wP)){
+ case BN_CLICKED:
+ if(GetDlgItemText(hwnd,IDC_PATH,pdPath,sizeof(pdPath)))
+ EndDialog(hwnd,IDOK);
+ else
+ // *** Error message
+ EndDialog(hwnd,IDCANCEL);
+ return 1;
+ }
+ break;
+ case IDCANCEL:
+ switch(HIWORD(wP)){
+ case BN_CLICKED:
+ EndDialog(hwnd,IDCANCEL);
+ return 1;
+ }
+ break;
+ };
+ break;
+ }
+ return 0;
+}
+
+LPSTR REQUESTPATH(LPCSTR title,LPCSTR prompt,LPCSTR defPath)
+{
+ pdTitle=title;pdPrompt=prompt;
+ strcpy(pdPath,defPath);
+ if(DialogBox(NULL,MAKEINTRESOURCE(IDD_PATH),NULL/*Parent*/,(DLGPROC)&pathDlgProc)!=IDOK)
+ return NULL;
+STRING rv(strlen(pdPath)+1);
+ strcpy(rv,pdPath);
+ return rv.Detach();
+}
+
+HKEY uninstallKey(LPCSTR regKey) {
+ STRING rk(100+strlen(regKey)+1);
+ sprintf(rk,"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s",regKey);
+ HKEY rv = NULL;
+ DWORD dw;
+ if(RegCreateKeyEx(HKEY_LOCAL_MACHINE,rk,0,REG_NONE,REG_OPTION_NON_VOLATILE,KEY_READ|KEY_WRITE,NULL,&rv,&dw)!=ERROR_SUCCESS)
+ return NULL;
+ return rv;
+}
+
+BOOL REG_UNINSTALL_COMMAND(LPCSTR regKey,LPCSTR dName,LPCSTR iPath,LPCSTR iFile,LPCSTR iSection)
+{
+ HKEY hKey = uninstallKey(regKey);
+ if(!hKey)
+ return FALSE;
+ BOOL rv=FALSE;
+ do{
+ if(RegSetValueEx(hKey,"DisplayName",0,REG_SZ,(LPBYTE)dName,strlen(dName)+1)!=ERROR_SUCCESS)
+ break;
+ STRING us(50+strlen(iPath)+1+strlen(iFile)+strlen(iSection)+1);
+ strcpy(us,"RunDll32 setupapi.dll,InstallHinfSection ");
+ strcat(us,iSection);
+ strcat(us," 132 ");
+ strcat(us,iPath);
+ APPEND_SLASH(us);
+ strcat(us,iFile);
+ if(RegSetValueEx(hKey,"UninstallString",0,REG_SZ,(LPBYTE)(LPCSTR)us,strlen(us)+1)!=ERROR_SUCCESS)
+ break;
+ rv=TRUE;
+ }while(FALSE);
+ RegCloseKey(hKey);
+ return rv;
+}
+BOOL REG_UNINSTALL_ICON(LPCSTR regKey,LPCSTR path,LPCSTR file,int n) {
+ HKEY hKey = uninstallKey(regKey);
+ if(!hKey)
+ return FALSE;
+ STRING uis(strlen(path)+1+strlen(file)+7);
+ strcpy(uis,path);
+ APPEND_SLASH(uis);
+ strcat(uis,file);
+ char tmp[8];
+ sprintf(tmp,";%d",n);
+ strcat(uis,tmp);
+ BOOL rv = TRUE;
+ if(RegSetValueEx(hKey,"DisplayIcon",0,REG_SZ,(LPBYTE)(LPCSTR)uis,strlen(uis)+1)!=ERROR_SUCCESS)
+ rv = FALSE;
+ RegCloseKey(hKey);
+ return rv;
+}
+BOOL REG_UNINSTALL_COMMENT(LPCSTR regKey,LPCSTR comment) {
+ HKEY hKey = uninstallKey(regKey);
+ if(!hKey)
+ return FALSE;
+ BOOL rv = TRUE;
+ if(RegSetValueEx(hKey,"lComment",0,REG_SZ,(LPBYTE)comment,strlen(comment)+1)!=ERROR_SUCCESS)
+ rv = FALSE;
+ RegCloseKey(hKey);
+ return rv;
+}
+BOOL REG_UNINSTALL_VERSION(LPCSTR regKey,LPCSTR version) {
+ HKEY hKey = uninstallKey(regKey);
+ if(!hKey)
+ return FALSE;
+ BOOL rv = TRUE;
+ if(RegSetValueEx(hKey,"DisplayVersion",0,REG_SZ,(LPBYTE)version,strlen(version)+1)!=ERROR_SUCCESS)
+ rv = FALSE;
+ RegCloseKey(hKey);
+ return rv;
+}
+BOOL REG_UNINSTALL_LOCATION(LPCSTR regKey,LPCSTR location) {
+ HKEY hKey = uninstallKey(regKey);
+ if(!hKey)
+ return FALSE;
+ BOOL rv = TRUE;
+ if(RegSetValueEx(hKey,"InstallLocation",0,REG_SZ,(LPBYTE)location,strlen(location)+1)!=ERROR_SUCCESS)
+ rv = FALSE;
+ RegCloseKey(hKey);
+ return rv;
+}
+BOOL REG_UNINSTALL_PUBLISHER(LPCSTR regKey,LPCSTR publisher) {
+ HKEY hKey = uninstallKey(regKey);
+ if(!hKey)
+ return FALSE;
+ BOOL rv = TRUE;
+ if(RegSetValueEx(hKey,"Publisher",0,REG_SZ,(LPBYTE)publisher,strlen(publisher)+1)!=ERROR_SUCCESS)
+ rv = FALSE;
+ RegCloseKey(hKey);
+ return rv;
+}
+BOOL REG_UNINSTALL_URLS(LPCSTR regKey,LPCSTR about,LPCSTR update) {
+ HKEY hKey = uninstallKey(regKey);
+ if(!hKey)
+ return FALSE;
+ BOOL rv = TRUE;
+ if(RegSetValueEx(hKey,"URLInfoAbout",0,REG_SZ,(LPBYTE)about,strlen(about)+1)!=ERROR_SUCCESS)
+ rv = FALSE;
+ if(RegSetValueEx(hKey,"URLUpdateInfo",0,REG_SZ,(LPBYTE)update,strlen(update)+1)!=ERROR_SUCCESS)
+ rv = FALSE;
+ RegCloseKey(hKey);
+ return rv;
+}
+
+#define INF_FILE_HEADER(i) fprintf(i,"[Version]\nSignature=\"$CHICAGO$\"\n\n")
+#define INF_FILE_SECTION(i,s) fprintf(i,"\n[%s]\n",s)
+#define INF_UNINSTALL_REG(i,p) fprintf(i,"HKLM,Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s\nHKLM,Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s,DisplayName\nHKLM,Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s,UninstallString\n",p,p,p)
+#define INF_MENU_GROUP(i,n,m) fprintf(i,"setup.ini, progman.groups,,\"group%d=%s\"\n",n,m)
+#define INF_MENU_ITEM(i,n,m) fprintf(i,"setup.ini, group%d,, \"\"\"%s\"\"\"\n",n,m);
+#define INF_REMOVE_ROOT(i,g,r) fprintf(i,"HKLM,Software\\Microsoft\\Windows\\CurrentVersion\\DeleteFiles\\%s,,,\"%s\"\n",g,r)
+#define INF_REMOVE_FILE(i,g,f) fprintf(i,"HKLM,Software\\Microsoft\\Windows\\CurrentVersion\\DeleteFiles\\%s,%s,,\"%s\"\n",g,f,f)
+#define INF_REMOVE_HELP_FILE(i,g,f) {INF_REMOVE_FILE(i,g,f".hlp");INF_REMOVE_FILE(i,g,f".cnt");INF_REMOVE_FILE(i,g,f".GID");INF_REMOVE_FILE(i,g,f".FTS");}
+
+LPSTR GET_SHORT_PATH(LPCSTR path)
+{
+char tmp;
+DWORD len = GetShortPathName(path,&tmp,1);
+ if(!len)
+ return NULL;
+STRING rv(len+1);
+ if(!GetShortPathName(path,rv,len+1))
+ return NULL;
+ return rv.Detach();
+}
+
+BOOL Install(void);
+
+int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR,int)
+{
+ theInstance=hInstance;
+ CoInitialize(NULL);
+ Install();
+ CoUninitialize();
+ return 0;
+}
diff --git a/shared-code/ip_icmp.h b/shared-code/ip_icmp.h
new file mode 100644
index 0000000..acaf7e9
--- a/dev/null
+++ b/shared-code/ip_icmp.h
@@ -0,0 +1,91 @@
+#ifndef IP_ICMPHEADER
+
+#define IP_ICMPHEADER
+
+struct icmp {
+ BYTE icmp_type;
+ BYTE icmp_code;
+ WORD icmp_cksum;
+ WORD icmp_id;
+ WORD icmp_seq;
+ char icmp_data[1];
+};
+
+#define SIZE_ICMP_HDR 8
+#define SIZE_TIME_DATA 8
+
+struct ip {
+ BYTE ip_hl:4, /* header length */
+ ip_v:4; /* version */
+ BYTE ip_tos; /* type of service */
+ short ip_len; /* total length */
+ u_short ip_id; /* identification */
+ short ip_off; /* fragment offset field */
+ BYTE ip_ttl; /* time to live */
+ BYTE ip_p; /* protocol */
+ u_short ip_sum; /* checksum */
+ struct in_addr ip_src,ip_dst; /* source and dest address */
+};
+
+#define ICMP_ECHOREPLY 0 /* echo reply */
+#define ICMP_UNREACH 3 /* dest unreachable, codes: */
+#define ICMP_UNREACH_NET 0 /* bad net */
+#define ICMP_UNREACH_HOST 1 /* bad host */
+#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */
+#define ICMP_UNREACH_PORT 3 /* bad port */
+#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */
+#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */
+#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */
+#define ICMP_REDIRECT 5 /* shorter route, codes: */
+#define ICMP_REDIRECT_NET 0 /* for network */
+#define ICMP_REDIRECT_HOST 1 /* for host */
+#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */
+#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */
+#define ICMP_ECHO 8 /* echo service */
+#define ICMP_TIMXCEED 11 /* time exceeded, code: */
+#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */
+#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */
+#define ICMP_PARAMPROB 12 /* ip header bad */
+#define ICMP_TSTAMP 13 /* timestamp request */
+#define ICMP_TSTAMPREPLY 14 /* timestamp reply */
+#define ICMP_IREQ 15 /* information request */
+#define ICMP_IREQREPLY 16 /* information reply */
+#define ICMP_MASKREQ 17 /* address mask request */
+#define ICMP_MASKREPLY 18 /* address mask reply */
+
+#define ICMP_MAXTYPE 18
+
+#define ICMP_MINLEN 8 /* abs minimum */
+#define ICMP_TSLEN (8 + 3 * sizeof (n_time)) /* timestamp */
+#define ICMP_MASKLEN 12 /* address mask */
+#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */
+#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8)
+
+#define STNORM 0
+
+/* Definition of the lowest telnet byte following an IAC byte */
+#define LOW_TEL_OPT 236
+
+#define TEL_EOF 236
+#define SUSP 237
+#define ABORT 238
+
+#define SE 240
+#define NOP 241
+#define DM 242
+#define BREAK 243
+#define IP 244
+#define AO 245
+#define AYT 246
+#define EC 247
+#define EL 248
+#define GOAHEAD 249
+#define SB 250
+#define WILL 251
+#define WONT 252
+#define DO 253
+#define DONT 254
+#define IAC 255
+
+#endif
+
diff --git a/shared-code/kHelpers.h b/shared-code/kHelpers.h
new file mode 100644
index 0000000..209c6b0
--- a/dev/null
+++ b/shared-code/kHelpers.h
@@ -0,0 +1,159 @@
+#ifndef __KHELPERS_H
+#define __KHELPERS_H
+
+#include <shlobj.h>
+
+extern "C" WINSHELLAPI void WINAPI SHFree( LPVOID);
+
+namespace Klever {
+
+ inline BOOL BrowseForFolder(CString& folder,LPCTSTR title=NULL,CWnd* pParent=NULL) {
+ BROWSEINFO bi;
+ memset(&bi,0,sizeof(bi));
+ if(pParent)
+ bi.hwndOwner=pParent->GetSafeHwnd();
+ CString rv;
+ bi.pszDisplayName=rv.GetBuffer(MAX_PATH);
+ bi.lpszTitle=title;
+ bi.ulFlags=BIF_RETURNONLYFSDIRS;
+ LPITEMIDLIST lpidl = SHBrowseForFolder(&bi);
+ if(lpidl){
+ SHGetPathFromIDList(lpidl,bi.pszDisplayName);
+ SHFree(lpidl);
+ rv.ReleaseBuffer();
+ folder=rv;
+ return TRUE;
+ }
+ rv.ReleaseBuffer();
+ return FALSE;
+ }
+ inline BOOL BrowseForFolder(CString& folder,UINT idTitle,CWnd* pParent=NULL) {
+ CString title;
+ VERIFY(title.LoadString(idTitle));
+ return BrowseForFolder(folder,title,pParent);
+ }
+ inline CString GluePathAndFile(LPCTSTR path,LPCTSTR file) {
+ CString rv = path;
+ while((!rv.IsEmpty()) && rv[rv.GetLength()-1]=='\\')
+ rv=rv.Left(rv.GetLength()-1);
+ rv+='\\';
+ while(*file && *file=='\\')
+ file++;
+ rv+=file;
+ return rv;
+ }
+ inline UINT TokenizeString(CStringList& rv,LPCTSTR string,LPCTSTR delimiter) {
+ CString s = string;
+ int found;
+ int delength = strlen(delimiter);
+ int rvc = 0;
+ while((found=s.Find(delimiter))>=0){
+ rv.AddTail(s.Left(found));
+ rvc++;
+ s=s.Mid(found+delength);
+ }
+ if(!s.IsEmpty()){
+ rv.AddTail(s);
+ rvc++;
+ }
+ return rvc;
+ }
+ inline BOOL LogRecord(LPCTSTR logFile,LPCTSTR logRecord) {
+ try{
+ CFile f(logFile,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite|CFile::shareDenyWrite);
+ f.SeekToEnd();
+ CString s = CTime::GetCurrentTime().Format("[%c] ")+logRecord+"\r\n";
+ f.Write((LPCTSTR)s,s.GetLength());
+ }catch(CException* e){
+ e->Delete();
+ return FALSE;
+ }
+ return TRUE;
+ }
+ inline BOOL ReadString(CFile* file,CString& rv) {
+ rv.Empty();
+ int nBuffer = 256;
+ TCHAR* ch = rv.GetBuffer(nBuffer);
+ int nPos = 0;
+ BOOL bRV = FALSE;
+ for(;;){
+ TCHAR c;
+ try{
+ if(file->Read(&c,sizeof(c))!=sizeof(c))
+ break;
+ bRV=TRUE;
+ }catch(CException* e){
+ e->Delete();
+ TRACE0("Exception in ReadString\n");
+ return FALSE;
+ }
+ if(nPos>=(nBuffer-1)){
+ rv.ReleaseBuffer();
+ ch = rv.GetBuffer(nBuffer=nBuffer+256);
+ ASSERT(ch);
+ }
+ if(c=='\n')
+ break;
+ ch[nPos++]=c;
+ }
+ ch[nPos]=0;
+ for(;;){
+ nPos--;
+ if(nPos<0)
+ break;
+ if(ch[nPos]!='\r')
+ break;
+ ch[nPos]=0;
+ }
+ rv.ReleaseBuffer();
+ rv.FreeExtra();
+ return bRV;
+ }
+
+ inline int LoadStringList(CStringList& list,LPCTSTR section) {
+ CString n;
+ list.RemoveAll();
+ CWinApp* app = AfxGetApp();
+ ASSERT(app);
+ for(int tmp=0;;tmp++){
+ n.Format("%d",tmp);
+ CString str = app->GetProfileString(section,n,NULL);
+ if(str.IsEmpty())
+ break;
+ list.AddTail(str);
+ }
+ return tmp;
+ }
+ inline int SaveStringList(CStringList& list,LPCTSTR section) {
+ CString n;
+ CWinApp* app = AfxGetApp();
+ ASSERT(app);
+ POSITION p = list.GetHeadPosition();
+ for(int tmp=0;p;tmp++){
+ n.Format("%d",tmp);
+ app->WriteProfileString(section,n,list.GetNext(p));
+ }
+ n.Format("%d",tmp);
+ app->WriteProfileString(section,n,NULL);
+ return tmp;
+ }
+
+ inline BOOL WriteProfileString(LPCTSTR section,LPCTSTR entry,LPCTSTR str) {
+ CWinApp* app = AfxGetApp();
+ return app->WriteProfileBinary(section,entry,(LPBYTE)str,strlen(str)+1);
+ }
+ inline CString GetProfileString(LPCTSTR section,LPCTSTR entry,LPCTSTR defval) {
+ CWinApp* app = AfxGetApp();
+ LPBYTE pData;
+ UINT nCount;
+ CString rv = defval;
+ if(app->GetProfileBinary(section,entry,&pData,&nCount)){
+ rv = (LPCTSTR)pData;
+ delete pData;
+ }
+ return rv;
+ }
+
+};
+
+#endif // __KHELPERS_H
diff --git a/shared-code/kICMP.cpp b/shared-code/kICMP.cpp
new file mode 100644
index 0000000..09a8f94
--- a/dev/null
+++ b/shared-code/kICMP.cpp
@@ -0,0 +1,300 @@
+#include "../stdafx.h"
+#include "kICMP.h"
+
+CICMP::_mechanismus CICMP::m_mechanismus = CICMP::_icmpUndetermined;
+
+BOOL CICMPDll::Initialize()
+{
+ if(m_hICMP!=INVALID_HANDLE_VALUE || m_hICMPDLL)
+ Deinitialize();
+ m_hICMPDLL = ::LoadLibraryEx("ICMP",NULL,0);
+ if(!m_hICMPDLL)
+ return FALSE;
+ *(FARPROC*)&m_icmpCF = ::GetProcAddress(m_hICMPDLL,"IcmpCreateFile");
+ *(FARPROC*)&m_icmpSE = ::GetProcAddress(m_hICMPDLL,"IcmpSendEcho");
+ *(FARPROC*)&m_icmpCH = ::GetProcAddress(m_hICMPDLL,"IcmpCloseHandle");
+ if(!(m_icmpCF && m_icmpSE && m_icmpCH)){
+ Deinitialize(); return FALSE;
+ }
+ m_hICMP = (*m_icmpCF)();
+ if(m_hICMP==INVALID_HANDLE_VALUE){
+ Deinitialize(); return FALSE;
+ }
+ TRACE0("ICMP-DLL Initialized\n");
+ return TRUE;
+}
+void CICMPDll::Deinitialize()
+{
+ if(m_hICMPDLL){
+ if(m_hICMP!=INVALID_HANDLE_VALUE && m_icmpCH)
+ (*m_icmpCH)(m_hICMP);
+ ::FreeLibrary(m_hICMPDLL); m_hICMPDLL = NULL;
+ m_icmpCF = NULL;
+ m_icmpSE = NULL;
+ m_icmpCH = NULL;
+ }
+ m_hICMP=INVALID_HANDLE_VALUE;
+ if(m_sizeOut && m_bsOut){
+ delete m_bsOut;
+ m_bsOut = NULL; m_sizeOut = 0;
+ }
+ if(m_sizeIn && m_bsIn){
+ delete m_bsIn;
+ m_bsIn = NULL; m_sizeIn = 0;
+ }
+}
+
+LONG CICMPDll::Ping(const in_addr host,const UINT packetSize,
+ const UINT timeOut,LPINT pStatus)
+{
+ if(!(m_hICMP && m_hICMPDLL && m_icmpSE)){
+ if(pStatus)
+ (*pStatus) = icmpNotInitialized;
+ return -1;
+ }
+ VERIFY(AdjustBuffers(packetSize));
+IPINFO ipi;
+ memset(&ipi,0,sizeof(ipi));
+ ipi.Ttl = 30;
+ for(UINT tmp=0;tmp<packetSize;tmp++)
+ m_bsOut[tmp]=tmp&0xFF;
+LPICMPECHO pRep = (LPICMPECHO)m_bsIn;
+ pRep->Status = 0xFFFFFFFFl;
+ if((*m_icmpSE)(m_hICMP,host.s_addr,m_bsOut,packetSize,
+ &ipi,pRep,m_sizeIn,timeOut))
+ TRACE0("ICMP-SendEcho succeeded\n");
+ else
+ TRACE0("ICMP-SendEcho failed\n");
+LONG lrv = -1;
+INT rv = ipUnknown;
+ switch(pRep->Status){
+ case IP_SUCCESS:
+ lrv = pRep->RTTime; rv = ipSuccess;
+ break;
+ case IP_BUF_TOO_SMALL: rv = ipBuffTooSmall; break;
+ case IP_DEST_NET_UNREACHABLE: rv = ipDestNetUnreachable; break;
+ case IP_DEST_HOST_UNREACHABLE: rv = ipDestHostUnreachable; break;
+ case IP_DEST_PROT_UNREACHABLE: rv = ipDestProtUnreachable; break;
+ case IP_DEST_PORT_UNREACHABLE: rv = ipDestPortUnreachable; break;
+ case IP_NO_RESOURCES: rv = ipNoResources; break;
+ case IP_BAD_OPTION: rv = ipBadOption; break;
+ case IP_HW_ERROR: rv = ipHWError; break;
+ case IP_PACKET_TOO_BIG: rv = ipPacketTooBig; break;
+ case IP_REQ_TIMED_OUT: rv = ipTimeOut; break;
+ case IP_BAD_REQ: rv = ipBadRequest; break;
+ case IP_BAD_ROUTE: rv = ipBadRoute; break;
+ case IP_TTL_EXPIRED_TRANSIT: rv = ipTTLExpiredInTransit; break;
+ case IP_TTL_EXPIRED_REASSEM: rv = ipTTLExpiredInReasm; break;
+ case IP_PARAM_PROBLEM: rv = ipParamProblem; break;
+ case IP_SOURCE_QUENCH: rv = ipSourceQuench; break;
+ case IP_OPTION_TOO_BIG: rv = ipOptionTooBig; break;
+ case IP_BAD_DESTINATION: rv = ipBadDest; break;
+ }
+ if(pStatus)
+ (*pStatus)=rv;
+ return lrv;
+}
+
+BOOL CICMPDll::AdjustBuffers(UINT packetSize)
+{
+ if(!packetSize)
+ packetSize=1;
+ if(packetSize>m_sizeOut){
+ if(m_sizeOut && m_bsOut)
+ delete m_bsOut;
+ m_bsOut = new BYTE[m_sizeOut=packetSize];
+ if(!m_bsOut)
+ return FALSE;
+ }
+UINT sin = sizeof(ICMPECHO)+SIZE_ICMP_HDR+packetSize;
+ if(sin>m_sizeIn){
+ if(m_sizeIn && m_bsIn)
+ delete m_bsIn;
+ m_bsIn = new BYTE[m_sizeIn=sin];
+ if(!m_bsIn)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+WORD CICMPWS::m_icmpSeq = 0;
+
+BOOL CICMPWS::Initialize()
+{
+ if(m_socket!=INVALID_SOCKET)
+ Deinitialize();
+ m_socket = socket(AF_INET,SOCK_RAW,1/*ICMP*/);
+ if(m_socket==INVALID_SOCKET)
+ return FALSE;
+ TRACE0("ICMP-WS Initialized\n");
+ return TRUE;
+}
+void CICMPWS::Deinitialize()
+{
+ if(m_socket!=INVALID_SOCKET){
+ closesocket(m_socket);
+ m_socket=INVALID_SOCKET;
+ }
+ if(m_sizeOut && m_bsOut){
+ delete m_bsOut;
+ m_bsOut = NULL; m_sizeOut = 0;
+ }
+ if(m_sizeIn && m_bsIn){
+ delete m_bsIn;
+ m_bsIn = NULL; m_sizeIn = 0;
+ }
+}
+LONG CICMPWS::Ping(const in_addr host,const UINT packetSize,
+ const UINT timeOut,LPINT pStatus)
+{
+ if(m_socket==INVALID_SOCKET){
+ if(pStatus)
+ (*pStatus)=icmpNotInitialized;
+ }
+ VERIFY(AdjustBuffers(packetSize));
+icmp* pPacket = (icmp*)m_bsOut;
+ memset(pPacket,0,m_sizeOut);
+ pPacket->icmp_type = ICMP_ECHO;
+ pPacket->icmp_seq = m_icmpSeq++;
+ pPacket->icmp_id = (WORD)(::GetCurrentThreadId()&0xFFFF);
+ for(UINT tmp=0;tmp<packetSize;tmp++)
+ pPacket->icmp_data[tmp]=tmp&0xFF;
+ pPacket->icmp_cksum = cksum(pPacket,SIZE_ICMP_HDR+packetSize);
+sockaddr_in to;
+ memset(&to,0,sizeof(to));
+ to.sin_addr.s_addr = host.s_addr;
+ to.sin_family = AF_INET;
+ if(sendto(m_socket,(char*)pPacket,SIZE_ICMP_HDR+packetSize,0,
+ (SOCKADDR*)&to,sizeof(to)) != (int)(SIZE_ICMP_HDR+packetSize)){
+ TRACE1("sendto: %lu\n",WSAGetLastError());
+ if(pStatus)
+ (*pStatus)=icmpSocketError;
+ return -1;
+ }
+DWORD sentTime = ::GetTickCount();
+sockaddr_in from;
+ memset(&from,0,sizeof(from));
+ from.sin_family=AF_INET;
+ from.sin_addr.s_addr=INADDR_ANY;
+fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(m_socket,&fds);
+long lrv = -1;
+INT rv = ipTimeOut;
+ for(;;){
+ DWORD ct = ::GetTickCount();
+ if((ct-sentTime)>=timeOut){
+ TRACE0("Timeout\n");
+ break;
+ }
+ timeval tv = {
+ (timeOut-ct+sentTime)/1000,
+ (timeOut-ct+sentTime)%1000
+ }; // tv_sec, tv_usec (secs,microsecs)
+ if(!select(m_socket,&fds,NULL,NULL,&tv)){
+ TRACE1("select: %d\n",WSAGetLastError());
+ break;
+ }
+ DWORD rtime = ::GetTickCount();
+ ASSERT(FD_ISSET(m_socket,&fds));
+ int fl = sizeof(from);
+ int rb = recvfrom(m_socket,(char*)m_bsIn,m_sizeIn,0,(SOCKADDR*)&from,&fl);
+ ip* pIP = (ip*)m_bsIn;
+ icmp* pICMP = (icmp*)&m_bsIn[sizeof(ip)];
+ if(pICMP->icmp_id!=pPacket->icmp_id)
+ continue;
+ if(pICMP->icmp_seq!=pPacket->icmp_seq)
+ continue;
+ if(from.sin_addr.s_addr!=host.s_addr)
+ continue;
+ if(pICMP->icmp_type==ICMP_ECHOREPLY){
+ lrv=rtime-sentTime;
+ rv=ipSuccess;
+ break;
+ }
+ rv = ipUnknown; // ***
+ break;
+ }
+ if(pStatus)
+ (*pStatus)=rv;
+ return lrv;
+}
+
+BOOL CICMPWS::AdjustBuffers(UINT packetSize)
+{
+ if(!packetSize)
+ packetSize=0;
+UINT osize = packetSize+SIZE_ICMP_HDR;
+ if(m_sizeOut<osize){
+ if(m_sizeOut && m_bsOut)
+ delete m_bsOut;
+ m_bsOut = new BYTE[m_sizeOut=osize];
+ if(!m_bsOut)
+ return FALSE;
+ }
+UINT isize = osize+sizeof(ip);
+ if(m_sizeIn<isize){
+ if(m_sizeIn && m_bsIn)
+ delete m_bsIn;
+ m_bsIn = new BYTE[m_sizeIn=isize];
+ if(!m_bsIn)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+WORD CICMPWS::cksum(LPVOID data,int count)
+{
+long lSum = 0;
+WORD *pData = (WORD*)data;
+ while(count>0){
+ if(count>1){
+ lSum+=*(pData++);
+ count-=2;
+ }else{
+ lSum+=((WORD)*(BYTE*)pData)&0xFF;
+ count--;
+ }
+ }
+ lSum = (lSum&0xFFFF)+(lSum>>16);
+ lSum += (lSum>>16);
+ return (~lSum)&0xFFFF;
+}
+
+CICMP* CICMP::CreateICMP()
+{
+ if(m_mechanismus==_icmpUndetermined)
+ GuessMechanismus();
+ switch(m_mechanismus){
+ case _icmpWinsock:
+ return new CICMPWS;
+ break;
+ case _icmpDLL:
+ return new CICMPDll;
+ break;
+ }
+ return NULL;
+}
+
+void CICMP::GuessMechanismus()
+{
+ m_mechanismus=_icmpUndetermined;
+SOCKET testSocket = socket(AF_INET,SOCK_RAW,1);
+ if(testSocket!=INVALID_SOCKET){
+ closesocket(testSocket);
+ m_mechanismus=_icmpWinsock;
+ }else{
+ HINSTANCE hICMP = ::LoadLibraryEx("ICMP",NULL,0);
+ if(!hICMP)
+ return;
+ BOOL isThere = (
+ ::GetProcAddress(hICMP,"IcmpCreateFile")
+ && ::GetProcAddress(hICMP,"IcmpSendEcho")
+ && ::GetProcAddress(hICMP,"IcmpCloseHandle")
+ );
+ ::FreeLibrary(hICMP);
+ if(isThere)
+ m_mechanismus=_icmpDLL;
+ }
+} \ No newline at end of file
diff --git a/shared-code/kICMP.h b/shared-code/kICMP.h
new file mode 100644
index 0000000..7a5ceaa
--- a/dev/null
+++ b/shared-code/kICMP.h
@@ -0,0 +1,80 @@
+#ifndef __KICMP_H
+#define __KICMP_H
+
+class CICMP {
+ enum _mechanismus {
+ _icmpUndetermined = -1,
+ _icmpWinsock = 0, _icmpDLL
+ };
+static _mechanismus m_mechanismus;
+static void GuessMechanismus();
+public:
+static
+ CICMP* CreateICMP();
+
+ enum {
+ ipSuccess = 0,
+ ipBuffTooSmall, ipDestNetUnreachable, ipDestHostUnreachable,
+ ipDestProtUnreachable, ipDestPortUnreachable, ipNoResources,
+ ipBadOption, ipHWError, ipPacketTooBig, ipTimeOut, ipBadRequest,
+ ipBadRoute, ipTTLExpiredInTransit, ipTTLExpiredInReasm,
+ ipParamProblem, ipSourceQuench, ipOptionTooBig, ipBadDest,
+ ipUnknown = -1,
+ icmpNotInitialized = -2,
+ icmpSocketError = -3
+ };
+
+ virtual BOOL Initialize() = 0;
+ virtual void Deinitialize() = 0;
+
+ virtual LONG Ping(const in_addr host,const UINT packetSize=0,
+ const UINT timeOut=10000,LPINT pStatus=NULL) = 0;
+};
+
+class CICMPDll : public CICMP {
+ HANDLE (WINAPI *m_icmpCF)(VOID);
+ BOOL (WINAPI *m_icmpSE)(HANDLE,ULONG,LPVOID,WORD,
+ PIPINFO,LPVOID,DWORD,DWORD);
+ BOOL (WINAPI *m_icmpCH)(HANDLE);
+public:
+ HINSTANCE m_hICMPDLL;
+ HANDLE m_hICMP;
+ LPBYTE m_bsIn, m_bsOut;
+ UINT m_sizeIn, m_sizeOut;
+
+ CICMPDll() : m_hICMP(INVALID_HANDLE_VALUE), m_hICMPDLL(NULL),
+ m_bsIn(NULL), m_bsOut(NULL), m_sizeIn(0), m_sizeOut(0) {}
+ virtual ~CICMPDll() { Deinitialize(); }
+
+ virtual BOOL Initialize();
+ virtual void Deinitialize();
+
+ virtual LONG Ping(const in_addr host,const UINT packetSize=0,
+ const UINT timeOut=10000,LPINT pStatus=NULL);
+
+ BOOL AdjustBuffers(UINT packetSize=0);
+};
+
+class CICMPWS : public CICMP {
+static
+ WORD m_icmpSeq;
+public:
+ SOCKET m_socket;
+ LPBYTE m_bsIn, m_bsOut;
+ UINT m_sizeIn, m_sizeOut;
+
+ CICMPWS() : m_socket(INVALID_SOCKET), m_bsIn(NULL), m_bsOut(NULL),
+ m_sizeIn(0), m_sizeOut(0) {}
+ virtual ~CICMPWS() { Deinitialize(); }
+
+ virtual BOOL Initialize();
+ virtual void Deinitialize();
+
+ virtual LONG Ping(const in_addr host,const UINT packetSize=0,
+ const UINT timeOut=10000,LPINT pStatus=NULL);
+
+ BOOL AdjustBuffers(UINT packetSize=0);
+ WORD cksum(LPVOID data,int count);
+};
+
+#endif // __KICMP_H \ No newline at end of file
diff --git a/shared-code/kinhelp.xsl b/shared-code/kinhelp.xsl
new file mode 100644
index 0000000..0bb384a
--- a/dev/null
+++ b/shared-code/kinhelp.xsl
@@ -0,0 +1,250 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ >
+ <xsl:output
+ method="text"
+ encoding="us-ascii"/>
+ <xsl:strip-space elements="*"/>
+
+ <xsl:template match="winhelp">
+ <xsl:text>{\rtf1\ansi</xsl:text>
+ <xsl:text>&#xA;@{\footnote</xsl:text>
+ <xsl:text>&#xA;THIS FILE WAS AUTOMATICALLY GENERATED FROM XML DOCUMENT.</xsl:text>
+ <xsl:text>&#xA;DO NOT MODIFY THIS FILE DIRECTLY. EDIT XML DOCUMENT INSTEAD</xsl:text>
+ <xsl:text>&#xA;}&#xA;</xsl:text>
+ <xsl:call-template name="fonttbl"/>
+ <xsl:call-template name="colortbl"/>
+ <xsl:apply-templates/>
+ <xsl:text>}</xsl:text>
+ </xsl:template>
+
+ <xsl:template match="topic">
+ <xsl:text>&#xA;\pard\plain</xsl:text>
+ <xsl:if test="descendant::*[ (@scroll='no') and
+ count(preceding-sibling::*[not(@scroll='no') and (name()!='a' and @name)])=0] ">
+ <xsl:text>\keepn</xsl:text>
+ </xsl:if>
+ <xsl:if test="@id">
+ <xsl:text>&#xA;#{\footnote </xsl:text>
+ <xsl:value-of select="@id"/>
+ <xsl:text>}</xsl:text>
+ </xsl:if>
+ <xsl:if test="@title">
+ <xsl:text>&#xA;${\footnote </xsl:text>
+ <xsl:value-of select="@title"/>
+ <xsl:text>}</xsl:text>
+ </xsl:if>
+ <xsl:if test="@keywords">
+ <xsl:text>&#xA;K{\footnote </xsl:text>
+ <xsl:value-of select="@keywords"/>
+ <xsl:text>}</xsl:text>
+ </xsl:if>
+ <xsl:apply-templates/>
+ <xsl:text>&#xA;\page&#xA;</xsl:text>
+ </xsl:template>
+
+ <xsl:template match="a[@name]">
+ <xsl:text>{#{\footnote </xsl:text>
+ <xsl:value-of select="@name"/>
+ <xsl:text>}}</xsl:text>
+ </xsl:template>
+ <xsl:template match="a[@href]">
+ <xsl:call-template name="hyperref">
+ <xsl:with-param name="href" select="@href"/>
+ <xsl:with-param name="inset"><xsl:apply-templates/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:template>
+ <xsl:template name="hyperref">
+ <xsl:param name="href"/>
+ <xsl:param name="inset"/>
+ <xsl:choose>
+ <xsl:when test="starts-with($href,'http:') or starts-with($href,'mailto:') or
+ starts-with($href,'ftp:')">
+ <xsl:text>{\uldb </xsl:text>
+ <xsl:value-of select="$inset"/>
+ <xsl:text>}{\v %!ExecFile("</xsl:text>
+ <xsl:value-of select="$href"/>
+ <xsl:text>")}</xsl:text>
+ </xsl:when>
+ <xsl:when test="starts-with($href,'#')">
+ <xsl:text>{\uldb </xsl:text>
+ <xsl:value-of select="$inset"/>
+ <xsl:text>}{\v </xsl:text>
+ <xsl:value-of select="substring($href,2)"/>
+ <xsl:text>}</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:message>Warining: Unqualified hyper-reference. Using as help-internal</xsl:message>
+ <xsl:text>{\uldb </xsl:text>
+ <xsl:value-of select="$inset"/>
+ <xsl:text>}{\v </xsl:text>
+ <xsl:value-of select="$href"/>
+ <xsl:text>}</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="heading">
+ <xsl:text>&#xA;</xsl:text>
+ <xsl:if test="@scroll!='no'">
+ <xsl:text>\pard </xsl:text>
+ </xsl:if>
+ <xsl:text>{ \f1\fs18\b\sb120 </xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>}</xsl:text>
+ </xsl:template>
+
+ <xsl:template match="p">
+ <xsl:text>&#xA;\par\sa120\sb120\qj</xsl:text>
+ <xsl:if test="@scroll!='no'">
+ <xsl:text>\pard</xsl:text>
+ </xsl:if>
+ <xsl:text> \f1\fs18\sb120 </xsl:text>
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="note">
+ <xsl:text>&#xA;\par\sa120\sb120\qj\f1\fs16 </xsl:text>
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="dedication">
+ <xsl:text>&#xA;\par\sa120\sb120\qr\f1\fs16 </xsl:text>
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="image">
+ <xsl:text>\{bmct </xsl:text>
+ <xsl:value-of select="@source"/>
+ <xsl:text>\}</xsl:text>
+ </xsl:template>
+
+ <xsl:template match="newsfor">
+ <xsl:text>&#xA;\par\pard\plain\f1\fs24\qc\cf2\b </xsl:text>
+ <xsl:value-of select="@version"/>
+ <xsl:text> - </xsl:text>
+ <xsl:value-of select="@date"/>
+ <xsl:apply-templates/>
+ </xsl:template>
+ <xsl:template match="ni">
+ <xsl:text>&#xA;\par\pard\plain\fi0\li0\f1\fs18 \bullet </xsl:text>
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="b">
+ <xsl:text>{\b </xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>}</xsl:text>
+ </xsl:template>
+ <xsl:template match="i">
+ <xsl:text>{\i </xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>}</xsl:text>
+ </xsl:template>
+ <xsl:template match="u">
+ <xsl:text>{\ul </xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>}</xsl:text>
+ </xsl:template>
+ <xsl:template match="strike">
+ <xsl:text>{\strike </xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>}</xsl:text>
+ </xsl:template>
+
+ <xsl:template match="kin">
+ <xsl:choose>
+ <xsl:when test="@href">
+ <xsl:call-template name="hyperref">
+ <xsl:with-param name="href" select="@href"/>
+ <xsl:with-param name="inset"><xsl:text>{\b </xsl:text><xsl:apply-templates/><xsl:text>}</xsl:text></xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>{\b </xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>}</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+ <xsl:template match="product">
+ <xsl:choose>
+ <xsl:when test="@href">
+ <xsl:call-template name="hyperref">
+ <xsl:with-param name="href" select="@href"/>
+ <xsl:with-param name="inset"><xsl:text>{\b\cf6 </xsl:text><xsl:apply-templates/><xsl:text>}</xsl:text></xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>{\b\cf6 </xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>}</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+ <xsl:template match="term">
+ <xsl:text>{\i </xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>}</xsl:text>
+ </xsl:template>
+
+ <xsl:template match="rfc">
+ <xsl:call-template name="hyperref">
+ <xsl:with-param name="href" select="concat('http://www.rfc-editor.org/rfc/rfc',@num,'.txt')"/>
+ <xsl:with-param name="inset" select="concat('{\b RFC',@num,'}')"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="license">
+ <xsl:text>&#xA;{</xsl:text>
+ <xsl:text>&#xA;\par\pard\plain\sb360\sa120 \f1\fs16 Copyright (c) </xsl:text>
+ <xsl:value-of select="@years"/>
+ <xsl:text> {\uldb\cf0 Klever Group (http://www.klever.net/)}{\v %!ExecFile("http://www.klever.net/")}</xsl:text>
+ <xsl:text>&#xA;\par\qj\sb120\sa120</xsl:text>
+ <xsl:text>Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:</xsl:text>
+ <xsl:text>&#xA;\par The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.</xsl:text>
+ <xsl:text>&#xA;\par \sa360 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</xsl:text>
+ <xsl:text>&#xA;}</xsl:text>
+ </xsl:template>
+ <xsl:template match="credits">
+ <xsl:text>&#xA;\par \sa0\sb120\ql \f1\fs16 Author: {\b\uldb\cf11 Michael Krelin ({\i hacker@klever.net})}{\v %!ExecFile("mailto:hacker@klever.net")}</xsl:text>
+ <xsl:text>&#xA;\par \sa0\sb0 Fan mail send to {\i\uldb gefilte@klever.net}{\v %!ExecFile("mailto:gefilte@klever.net")}</xsl:text>
+ </xsl:template>
+
+ <xsl:template match="ul">
+ <xsl:text>\pard</xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>\pard</xsl:text>
+ </xsl:template>
+ <xsl:template match="li">
+ <!-- TODO: could be done better, but you never know with winhelp.. -->
+ <xsl:variable name="li" select=" count(ancestor::ul) "/>
+ <xsl:text>&#xA;\par \fi0\li</xsl:text><xsl:value-of
+ select="0"/><xsl:text> \bullet </xsl:text>
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="topic/text()">
+ <!-- maybe only omit spaces? -->
+ </xsl:template>
+ <xsl:template match="ul/text()">
+ </xsl:template>
+
+ <xsl:template name="colortbl">
+ <xsl:text>{\colortbl;
+ \red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;
+ \red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;
+ \red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;
+ \red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}
+ </xsl:text>
+ </xsl:template>
+ <xsl:template name="fonttbl">
+ <xsl:text>{\fonttbl</xsl:text>
+ <xsl:text>{\f0\froman Times New Roman;}</xsl:text>
+ <xsl:text>{\f1\fswiss Arial;}</xsl:text>
+ <xsl:text>{\f3\froman Symbol;}</xsl:text>
+ <xsl:text>}</xsl:text>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/shared-code/ms_icmp.h b/shared-code/ms_icmp.h
new file mode 100644
index 0000000..32d97f5
--- a/dev/null
+++ b/shared-code/ms_icmp.h
@@ -0,0 +1,77 @@
+/*------------------------------------------------------------------
+* Filename: MS_ICMP.H
+*
+* Description: Prototypes of Microsoft's ICMP.DLL functions for
+* access to Internet Control Message Protocol (their stacks do
+* not support the standard Berkeley Sockets raw socket API).
+* Use this to do "ping" or "traceroute," although beware that
+* Microsoft discourages its use.
+*/
+
+
+/* Note 2: For the most part, you can refer to RFC 791 for detials on
+* how to fill in values for the IP option information structure. */
+typedef struct ip_option_information {
+ u_char Ttl; /* Time To Live (used for traceroute) */
+ u_char Tos; /* Type Of Service (usually 0) */
+ u_char Flags; /* IP header flags (usually 0) */
+ u_char OptionsSize; /* Size of options data (usually 0, max 40) */
+ u_char FAR *OptionsData;/* Options data buffer */
+} IPINFO, *PIPINFO, FAR *LPIPINFO;
+
+/* Note 1: The Reply Buffer will have an array of ICMP_ECHO_REPLY
+* structures, followed by options and the data in ICMP echo reply
+* datagram received. You must have room for at least one ICMP
+* echo reply structure, plus 8 bytes for an ICMP header. */
+typedef struct icmp_echo_reply {
+ u_long Address; /* source address */
+ u_long Status; /* IP status value (see below) */
+ u_long RTTime; /* Round Trip Time in milliseconds */
+ u_short DataSize; /* reply data size */
+ u_short Reserved; /* */
+ void FAR *Data; /* reply data buffer */
+ typedef struct ip_option_information Options; /* reply options */
+} ICMPECHO, *PICMPECHO, FAR *LPICMPECHO;
+
+#define IP_STATUS_BASE 11000
+#define IP_SUCCESS 0
+#define IP_BUF_TOO_SMALL (IP_STATUS_BASE + 1)
+#define IP_DEST_NET_UNREACHABLE (IP_STATUS_BASE + 2)
+#define IP_DEST_HOST_UNREACHABLE (IP_STATUS_BASE + 3)
+#define IP_DEST_PROT_UNREACHABLE (IP_STATUS_BASE + 4)
+#define IP_DEST_PORT_UNREACHABLE (IP_STATUS_BASE + 5)
+#define IP_NO_RESOURCES (IP_STATUS_BASE + 6)
+#define IP_BAD_OPTION (IP_STATUS_BASE + 7)
+#define IP_HW_ERROR (IP_STATUS_BASE + 8)
+#define IP_PACKET_TOO_BIG (IP_STATUS_BASE + 9)
+#define IP_REQ_TIMED_OUT (IP_STATUS_BASE + 10)
+#define IP_BAD_REQ (IP_STATUS_BASE + 11)
+#define IP_BAD_ROUTE (IP_STATUS_BASE + 12)
+#define IP_TTL_EXPIRED_TRANSIT (IP_STATUS_BASE + 13)
+#define IP_TTL_EXPIRED_REASSEM (IP_STATUS_BASE + 14)
+#define IP_PARAM_PROBLEM (IP_STATUS_BASE + 15)
+#define IP_SOURCE_QUENCH (IP_STATUS_BASE + 16)
+#define IP_OPTION_TOO_BIG (IP_STATUS_BASE + 17)
+#define IP_BAD_DESTINATION (IP_STATUS_BASE + 18)
+#define IP_ADDR_DELETED (IP_STATUS_BASE + 19)
+#define IP_SPEC_MTU_CHANGE (IP_STATUS_BASE + 20)
+#define IP_MTU_CHANGE (IP_STATUS_BASE + 21)
+#define IP_UNLOAD (IP_STATUS_BASE + 22)
+#define IP_GENERAL_FAILURE (IP_STATUS_BASE + 50)
+#define MAX_IP_STATUS IP_GENERAL_FAILURE
+#define IP_PENDING (IP_STATUS_BASE + 255)
+
+
+HANDLE WINAPI PASCAL IcmpCreateFile(VOID); /* INVALID_HANDLE_VALUE on error */
+BOOL WINAPI PASCAL IcmpCloseHandle(HANDLE IcmpHandle); /* FALSE on error */
+DWORD WINAPI PASCAL IcmpSendEcho(
+ HANDLE IcmpHandle, /* handle returned from IcmpCreateFile() */
+ u_long DestAddress, /* destination IP address (in network order) */
+ LPVOID RequestData, /* pointer to buffer to send */
+ WORD RequestSize, /* length of data in buffer */
+ LPIPINFO RequestOptns, /* see Note 2 below */
+ LPVOID ReplyBuffer, /* see Note 1 below */
+ DWORD ReplySize, /* length of reply (must allow at least 1 reply) */
+ DWORD Timeout /* time in milliseconds to wait for reply */
+);
+
diff --git a/shared-data/browse-icon.ico b/shared-data/browse-icon.ico
new file mode 100644
index 0000000..d2d1b3c
--- a/dev/null
+++ b/shared-data/browse-icon.ico
Binary files differ
diff --git a/shared-data/install-icon.ico b/shared-data/install-icon.ico
new file mode 100644
index 0000000..23e86a6
--- a/dev/null
+++ b/shared-data/install-icon.ico
Binary files differ
diff --git a/shared-data/klever-background.bmp b/shared-data/klever-background.bmp
new file mode 100644
index 0000000..e4d87ec
--- a/dev/null
+++ b/shared-data/klever-background.bmp
Binary files differ
diff --git a/shared-data/play-icon.ico b/shared-data/play-icon.ico
new file mode 100644
index 0000000..3d2a11e
--- a/dev/null
+++ b/shared-data/play-icon.ico
Binary files differ
diff --git a/stdafx.cpp b/stdafx.cpp
new file mode 100644
index 0000000..a9dae61
--- a/dev/null
+++ b/stdafx.cpp
@@ -0,0 +1,6 @@
+// stdafx.cpp : source file that includes just the standard includes
+// BigBrother.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
diff --git a/stdafx.h b/stdafx.h
new file mode 100644
index 0000000..37403c2
--- a/dev/null
+++ b/stdafx.h
@@ -0,0 +1,33 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+
+#include <afxwin.h> // MFC core and standard components
+#include <afxext.h> // MFC extensions
+#include <afxcview.h>
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h> // MFC support for Windows 95 Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+#include <afxsock.h> // MFC socket extensions
+
+#include <afxtempl.h>
+
+#include <winsock.h>
+#include "shared-code/ms_icmp.h"
+#include "shared-code/ip_icmp.h"
+#include "shared-code/kICMP.h"
+
+enum {
+ WM_TRAYICONMESSAGE = WM_USER,
+ WM_ACTIVITYCOUNT,
+ WM_UPDATETREEBROTHER,
+ WM_CHECKQUEUE,
+ WM_BROTHERUPDOWN
+};
+#include <MMSystem.h>
+// CG: The following line was added by the Windows Multimedia component.
+#pragma comment(lib, "winmm.lib")