|
|
// watcher.cpp : Defines the class behaviors for the application.
//
#include "StdAfx.h"
#include "watcher.h"
#include "MainFrm.h"
#include "ChildFrm.h"
#include "watcherDoc.h"
#include "watcherView.h"
#include "ManageDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
/////////////////////////////////////////////////////////////////////////////
// CWatcherApp
BEGIN_MESSAGE_MAP(CWatcherApp, CWinApp) //{{AFX_MSG_MAP(CWatcherApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout) ON_COMMAND(ID_APP_EXIT, OnAppExit) //}}AFX_MSG_MAP
// Standard file based document commands
ON_COMMAND(ID_FILE_MANAGE,OnFileManage) ON_COMMAND(ID_DEFAULT_HELP, OnHelp) // Standard print setup command
ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup) END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CWatcherApp construction
CWatcherApp::CWatcherApp() :m_hkey(NULL), m_pDocTemplate(NULL), m_pManageDialog(NULL) { // TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CWatcherApp object
CWatcherApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CWatcherApp initialization
BOOL CWatcherApp::InitInstance() { if (!AfxSocketInit()){ AfxMessageBox(IDP_SOCKETS_INIT_FAILED); return FALSE; }
AfxEnableControlContainer();
// 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
// Change the registry key under which our settings are stored.
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization.
// will do this in the ProcessShellCommand part.....
// SetRegistryKey(AFX_IDS_COMPANY);
LoadStdProfileSettings(); // Load standard INI file options (including MRU)
// Register the application's document templates. Document templates
// serve as the connection between documents, frame windows and views.
m_pDocTemplate = new CMultiDocTemplate(IDR_WATCHETYPE, RUNTIME_CLASS(CWatcherDoc), RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CWatcherView)); if(!m_pDocTemplate){ // Will almost never occur , but ...
// Oops !!
return FALSE; } AddDocTemplate(m_pDocTemplate);
// create main MDI Frame window
CMainFrame* pMainFrame = new CMainFrame; if(!pMainFrame){ // Will almost never occur , but ...
// Oops !!
return FALSE; }
if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE; m_pMainWnd = pMainFrame;
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo);
// The main window has been initialized, so show and update it.
pMainFrame->ShowWindow(m_nCmdShow); pMainFrame->UpdateWindow(); // Dispatch commands specified on the command line
m_hkey = GetAppRegistryKey();
if(m_hkey == NULL){ return FALSE; } if (!ProcessShellCommand(cmdInfo)) return FALSE; // Get the value of the key in the registry where all the parameters are stored.
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 CWatcherApp::OnAppAbout() { CAboutDlg aboutDlg; aboutDlg.DoModal(); }
/////////////////////////////////////////////////////////////////////////////
// CWatcherApp message handlers
void CWatcherApp::OnFileManage(){ // Here we bring up the manage window.
if (m_pManageDialog){ m_pManageDialog->ShowWindow(SW_SHOWNORMAL); return; } // Actually construct the dialog box here
m_pManageDialog = new ManageDialog(); if( !m_pManageDialog){ // Oops!! Memory problem
return; } ((ManageDialog *) m_pManageDialog)->SetApplicationPtr(this); m_pManageDialog->Create(Manage); m_pManageDialog->ShowWindow(SW_SHOWNORMAL); return; }
void CWatcherApp::OnHelp() { // Need to expand on this a little bit.
CWinApp::WinHelp(0,HELP_CONTENTS); }
void CWatcherApp::ParseCommandLine(CCommandLineInfo& rCmdInfo) { BOOL setReg = FALSE; for (int i = 1; i < __argc; i++){ LPCTSTR pszParam = __targv[i]; BOOL bFlag = FALSE; BOOL bLast = ((i + 1) == __argc); if (pszParam[0] == '-' || pszParam[0] == '/'){ // remove flag specifier
bFlag = TRUE; ++pszParam; if (_tcscmp(pszParam, TEXT("r")) == 0){ // we are being given a new registry profile string
// Can only change this from watcher.
// HKEY_CURRENT_USER\\SOFTWARE\\%KEY%\\WATCHER
if(!bLast) { // the next argument is the string
SetRegistryKey(__targv[i+1]); i++; setReg = TRUE; if(i==__argc){ if (rCmdInfo.m_nShellCommand == CCommandLineInfo::FileNew && !rCmdInfo.m_strFileName.IsEmpty()) rCmdInfo.m_nShellCommand = CCommandLineInfo::FileOpen; rCmdInfo.m_bShowSplash = !rCmdInfo.m_bRunEmbedded && !rCmdInfo.m_bRunAutomated; } continue; }
} } rCmdInfo.ParseParam(pszParam, bFlag, bLast); } if(!setReg){ SetRegistryKey(AFX_IDS_COMPANY); } }
BOOL CWatcherApp::ProcessShellCommand(CCommandLineInfo& rCmdInfo) { BOOL bResult = TRUE; switch (rCmdInfo.m_nShellCommand) { case CCommandLineInfo::FileNew: // Load parameters from the registry
bResult = LoadRegistryParameters(); break;
// If we've been asked to open a file, call OpenDocumentFile()
case CCommandLineInfo::FileOpen: // cannot happen ...... maybe later allow the user to read
// parameters from a file.
break;
// If the user wanted to print, hide our main window and
// fire a message to ourselves to start the printing
case CCommandLineInfo::FilePrintTo: case CCommandLineInfo::FilePrint: m_nCmdShow = SW_HIDE; ASSERT(m_pCmdInfo == NULL); OpenDocumentFile(rCmdInfo.m_strFileName); m_pCmdInfo = &rCmdInfo; m_pMainWnd->SendMessage(WM_COMMAND, ID_FILE_PRINT_DIRECT); m_pCmdInfo = NULL; bResult = FALSE; break;
// If we're doing DDE, hide ourselves
case CCommandLineInfo::FileDDE: // m_pCmdInfo = (CCommandLineInfo*)m_nCmdShow;
m_nCmdShow = SW_HIDE; break;
// If we've been asked to unregister, unregister and then terminate
case CCommandLineInfo::AppUnregister: { UnregisterShellFileTypes(); BOOL bUnregistered = Unregister();
// if you specify /EMBEDDED, we won't make an success/failure box
// this use of /EMBEDDED is not related to OLE
if (!rCmdInfo.m_bRunEmbedded) { if (bUnregistered) AfxMessageBox(AFX_IDP_UNREG_DONE); else AfxMessageBox(AFX_IDP_UNREG_FAILURE); } bResult = FALSE; // that's all we do
// If nobody is using it already, we can use it.
// We'll flag that we're unregistering and not save our state
// on the way out. This new object gets deleted by the
// app object destructor.
if (m_pCmdInfo == NULL) { m_pCmdInfo = new CCommandLineInfo; m_pCmdInfo->m_nShellCommand = CCommandLineInfo::AppUnregister; } } break; } return bResult; }
BOOL CWatcherApp::LoadRegistryParameters() {
DWORD dwIndex=0; CString sess,lgnName, lgnPasswd; CString mac, com; UINT port; LONG RetVal; int tc, lang,hist;
//Get each session parameters from here
// There are NO optional values.
while(1){ RetVal = GetParametersByIndex(dwIndex, sess, mac, com, port, lang, tc, hist, lgnName, lgnPasswd ); if(RetVal == ERROR_NO_MORE_ITEMS){ return TRUE; } if (RetVal != ERROR_SUCCESS) { return FALSE; } // Make sure that the string buffers are NOT shared by locking
// them.
mac.LockBuffer(); com.LockBuffer(); lgnName.LockBuffer(); lgnPasswd.LockBuffer(); sess.LockBuffer(); // Passing references is really cool.
CreateNewSession(mac, com, port,lang, tc, hist,lgnName, lgnPasswd,sess); dwIndex ++; } return TRUE; }
int CWatcherApp::GetParametersByIndex(int dwIndex, CString &sess, CString &mac, CString &com, UINT &port, int &lang, int &tc, int &hist, CString &lgnName, CString &lgnPasswd ) { LONG RetVal; TCHAR lpName[MAX_BUFFER_SIZE]; DWORD lpcName; FILETIME lpftLastWriteTime; HKEY child; DWORD lpType = 0;
if (m_hkey == NULL) return -1; lpcName = MAX_BUFFER_SIZE; RetVal = RegEnumKeyEx(m_hkey, dwIndex, lpName, &lpcName, NULL, NULL, NULL, &lpftLastWriteTime ); if(RetVal == ERROR_NO_MORE_ITEMS){ return RetVal; }
if(RetVal != ERROR_SUCCESS){ RegCloseKey(m_hkey); m_hkey = NULL; return FALSE; }
sess = lpName; RetVal= RegOpenKeyEx(m_hkey, lpName, // subkey name
0, // reserved
KEY_ALL_ACCESS, // security access mask
&child ); if(RetVal != ERROR_SUCCESS){ // Hmm problem with main key itself
RegCloseKey(m_hkey); m_hkey = NULL; return RetVal; } // We open the key corresponding to the session and then try to
// obtain the parameters. Now, we need a lock possibly to achieve
// synchronization.That would be a complete solution.
// Use some kind of readers-writers solution.
// Fault tolerant ???
// Get the remaining parameters.
RetVal = GetParameters(mac, com, lgnName, lgnPasswd, port, lang, tc, hist, child ); RegCloseKey(child); return RetVal; }
void CWatcherApp::CreateNewSession(CString &mac, CString &com, UINT port, int lang, int tc, int hist, CString &lgnName, CString &lgnPasswd, CString &sess ) { CCreateContext con; CChildFrame *cmdiFrame;
con.m_pNewViewClass = RUNTIME_CLASS(CWatcherView); con.m_pCurrentFrame = NULL; con.m_pNewDocTemplate = m_pDocTemplate;
// A new document is created using these parameters.
// BUGBUG - Memory inefficiency :-(
// This function must be shared between the ManageDialog and
// the Watcher Application.
// Will probably declare them as friends of each other.
// For the moment , let use have two copies of the function.
con.m_pCurrentDoc = new CWatcherDoc(mac, com, port, tc, lang, hist, lgnName, lgnPasswd, sess ); // Add the document to the template.
// this is how the document is available to the document
// manager.
if(!con.m_pCurrentDoc){ // Can occur if you keep on opening newer sessions.
// Oops !!
return; } m_pDocTemplate->AddDocument(con.m_pCurrentDoc); cmdiFrame = new CChildFrame(); if(!cmdiFrame){ // Oops !!
return; } BOOL ret = cmdiFrame->LoadFrame(IDR_WATCHETYPE, WS_OVERLAPPEDWINDOW|FWS_ADDTOTITLE, NULL, &con); ret = con.m_pCurrentDoc->OnNewDocument(); cmdiFrame->InitialUpdateFrame(con.m_pCurrentDoc,TRUE); return; }
int CWatcherApp::GetParameters(CString &mac, CString &com, CString &lgnName, CString &lgnPasswd, UINT &port, int &lang, int &tc, int &hist, HKEY &child ) {
DWORD lpcName, lpType; TCHAR lpName[MAX_BUFFER_SIZE]; int RetVal;
// I see this kind of function in all the programs that use the
// registry. Should try to simplify this.
// BUGBUG - Memory inefficiency :-(
// This function must be shared between the ManageDialog and
// the Watcher Application.
// Will probably declare them as friends of each other.
// For the moment , let use have two copies of the function.
lpcName = MAX_BUFFER_SIZE; RetVal = RegQueryValueEx(child, _TEXT("Machine"), NULL, &lpType, (LPBYTE)lpName, &lpcName ); if(RetVal != ERROR_SUCCESS){ return RetVal; } mac = lpName; lpName[0] = 0; lpcName = MAX_BUFFER_SIZE; RetVal = RegQueryValueEx(child, _TEXT("Command"), NULL, &lpType, (LPBYTE)lpName, &lpcName ); if(RetVal != ERROR_SUCCESS){ return RetVal; } com = lpName; lpcName = MAX_BUFFER_SIZE; lpName[0] = 0; RetVal = RegQueryValueEx(child, _TEXT("Password"), NULL, &lpType, (LPBYTE)lpName, &lpcName ); if(RetVal != ERROR_SUCCESS){ return RetVal; } lgnPasswd = lpName; lpName[0] = 0; lpcName = MAX_BUFFER_SIZE; RetVal = RegQueryValueEx(child, _TEXT("User Name"), NULL, &lpType, (LPBYTE)lpName, &lpcName ); if(RetVal != ERROR_SUCCESS){ return RetVal; } lgnName = lpName; lpcName = sizeof(int); RetVal = RegQueryValueEx(child, _TEXT("Port"), NULL, &lpType, (LPBYTE)&port, &lpcName ); if(RetVal != ERROR_SUCCESS){ return RetVal; } lpcName = sizeof(int); RetVal = RegQueryValueEx(child, _TEXT("Client Type"), NULL, &lpType, (LPBYTE)&tc, &lpcName ); if(RetVal != ERROR_SUCCESS){ return RetVal; } lpcName = sizeof(int); RetVal = RegQueryValueEx(child, _TEXT("Language"), NULL, &lpType, (LPBYTE)&lang, &lpcName ); if(RetVal != ERROR_SUCCESS){ return RetVal; } lpcName = sizeof(int); RetVal = RegQueryValueEx(child, _TEXT("History"), NULL, &lpType, (LPBYTE)&hist, &lpcName ); return RetVal; }
void CWatcherApp::OnAppExit() { // TODO: Add your command handler code here
if (m_pManageDialog){ delete m_pManageDialog; } if(m_hkey){ RegCloseKey(m_hkey); m_hkey = NULL; } CWinApp::OnAppExit(); }
HKEY & CWatcherApp::GetKey() { return m_hkey; }
void CWatcherApp::Refresh(ParameterDialog &pd, BOOLEAN del){ POSITION index;
if(m_pDocTemplate == NULL){ return; } CDocument *doc; CWatcherDoc *wdoc; index = m_pDocTemplate->GetFirstDocPosition(); while(index != NULL){ doc = m_pDocTemplate->GetNextDoc(index); if(doc->GetTitle() == pd.Session){ // May be conflict
if(doc->IsKindOf(RUNTIME_CLASS(CWatcherDoc))){ wdoc = (CWatcherDoc *) doc; ParameterDialog & dpd = wdoc->GetParameters(); if(EqualParameters(pd, dpd)==FALSE){ DeleteSession(doc); if(!del){ CreateNewSession(pd.Machine, pd.Command, pd.Port, pd.language, pd.tcclnt, pd.history, pd.LoginName, pd.LoginPasswd, pd.Session ); } return; }
}else{ // Doc Template returning junk values.
return; }
} } if(!del){ CreateNewSession(pd.Machine, pd.Command, pd.Port, pd.language, pd.tcclnt, pd.history, pd.LoginName, pd.LoginPasswd, pd.Session ); }
}
void CWatcherApp::DeleteSession(CDocument *wdoc) { POSITION pos; pos = wdoc->GetFirstViewPosition(); while (pos != NULL){ CView* pView = wdoc->GetNextView(pos); CWnd *pParent = pView->GetParent(); if(pParent){ pParent->PostMessage(WM_CLOSE,0,0); return; } }
}
BOOLEAN CWatcherApp::EqualParameters(ParameterDialog & pd1, ParameterDialog & pd2) { if((pd1.Session != pd2.Session)|| (pd1.Machine != pd2.Machine)|| (pd1.Command != pd2.Command)|| (pd1.history != pd2.history)|| (pd1.language != pd2.language)|| (pd1.tcclnt != pd2.tcclnt)|| (pd1.Port != pd2.Port)){ return FALSE; } if((pd1.LoginPasswd != pd2.LoginPasswd)|| (pd1.LoginName != pd2.LoginName)){ return FALSE; } return TRUE;
}
|