Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

714 lines
21 KiB

  1. // watcher.cpp : Defines the class behaviors for the application.
  2. //
  3. #include "StdAfx.h"
  4. #include "watcher.h"
  5. #include "MainFrm.h"
  6. #include "ChildFrm.h"
  7. #include "watcherDoc.h"
  8. #include "watcherView.h"
  9. #include "ManageDialog.h"
  10. #ifdef _DEBUG
  11. #define new DEBUG_NEW
  12. #undef THIS_FILE
  13. static char THIS_FILE[] = __FILE__;
  14. #endif
  15. /////////////////////////////////////////////////////////////////////////////
  16. // CWatcherApp
  17. BEGIN_MESSAGE_MAP(CWatcherApp, CWinApp)
  18. //{{AFX_MSG_MAP(CWatcherApp)
  19. ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
  20. ON_COMMAND(ID_APP_EXIT, OnAppExit)
  21. //}}AFX_MSG_MAP
  22. // Standard file based document commands
  23. ON_COMMAND(ID_FILE_MANAGE,OnFileManage)
  24. ON_COMMAND(ID_DEFAULT_HELP, OnHelp)
  25. // Standard print setup command
  26. ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
  27. END_MESSAGE_MAP()
  28. /////////////////////////////////////////////////////////////////////////////
  29. // CWatcherApp construction
  30. CWatcherApp::CWatcherApp()
  31. :m_hkey(NULL),
  32. m_pDocTemplate(NULL),
  33. m_pManageDialog(NULL)
  34. {
  35. // TODO: add construction code here,
  36. // Place all significant initialization in InitInstance
  37. }
  38. /////////////////////////////////////////////////////////////////////////////
  39. // The one and only CWatcherApp object
  40. CWatcherApp theApp;
  41. /////////////////////////////////////////////////////////////////////////////
  42. // CWatcherApp initialization
  43. BOOL CWatcherApp::InitInstance()
  44. {
  45. if (!AfxSocketInit()){
  46. AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
  47. return FALSE;
  48. }
  49. AfxEnableControlContainer();
  50. // Standard initialization
  51. // If you are not using these features and wish to reduce the size
  52. // of your final executable, you should remove from the following
  53. // the specific initialization routines you do not need.
  54. #ifdef _AFXDLL
  55. Enable3dControls(); // Call this when using MFC in a shared DLL
  56. #else
  57. Enable3dControlsStatic(); // Call this when linking to MFC statically
  58. #endif
  59. // Change the registry key under which our settings are stored.
  60. // TODO: You should modify this string to be something appropriate
  61. // such as the name of your company or organization.
  62. // will do this in the ProcessShellCommand part.....
  63. // SetRegistryKey(AFX_IDS_COMPANY);
  64. LoadStdProfileSettings(); // Load standard INI file options (including MRU)
  65. // Register the application's document templates. Document templates
  66. // serve as the connection between documents, frame windows and views.
  67. m_pDocTemplate = new CMultiDocTemplate(IDR_WATCHETYPE,
  68. RUNTIME_CLASS(CWatcherDoc),
  69. RUNTIME_CLASS(CChildFrame),
  70. // custom MDI child frame
  71. RUNTIME_CLASS(CWatcherView));
  72. if(!m_pDocTemplate){
  73. // Will almost never occur , but ...
  74. // Oops !!
  75. return FALSE;
  76. }
  77. AddDocTemplate(m_pDocTemplate);
  78. // create main MDI Frame window
  79. CMainFrame* pMainFrame = new CMainFrame;
  80. if(!pMainFrame){
  81. // Will almost never occur , but ...
  82. // Oops !!
  83. return FALSE;
  84. }
  85. if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
  86. return FALSE;
  87. m_pMainWnd = pMainFrame;
  88. // Parse command line for standard shell commands, DDE, file open
  89. CCommandLineInfo cmdInfo;
  90. ParseCommandLine(cmdInfo);
  91. // The main window has been initialized, so show and update it.
  92. pMainFrame->ShowWindow(m_nCmdShow);
  93. pMainFrame->UpdateWindow();
  94. // Dispatch commands specified on the command line
  95. m_hkey = GetAppRegistryKey();
  96. if(m_hkey == NULL){
  97. return FALSE;
  98. }
  99. if (!ProcessShellCommand(cmdInfo))
  100. return FALSE;
  101. // Get the value of the key in the registry where all the parameters are stored.
  102. return TRUE;
  103. }
  104. /////////////////////////////////////////////////////////////////////////////
  105. // CAboutDlg dialog used for App About
  106. class CAboutDlg : public CDialog
  107. {
  108. public:
  109. CAboutDlg();
  110. // Dialog Data
  111. //{{AFX_DATA(CAboutDlg)
  112. enum { IDD = IDD_ABOUTBOX };
  113. //}}AFX_DATA
  114. // ClassWizard generated virtual function overrides
  115. //{{AFX_VIRTUAL(CAboutDlg)
  116. protected:
  117. virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
  118. //}}AFX_VIRTUAL
  119. // Implementation
  120. protected:
  121. //{{AFX_MSG(CAboutDlg)
  122. // No message handlers
  123. //}}AFX_MSG
  124. DECLARE_MESSAGE_MAP()
  125. };
  126. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  127. {
  128. //{{AFX_DATA_INIT(CAboutDlg)
  129. //}}AFX_DATA_INIT
  130. }
  131. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  132. {
  133. CDialog::DoDataExchange(pDX);
  134. //{{AFX_DATA_MAP(CAboutDlg)
  135. //}}AFX_DATA_MAP
  136. }
  137. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  138. //{{AFX_MSG_MAP(CAboutDlg)
  139. // No message handlers
  140. //}}AFX_MSG_MAP
  141. END_MESSAGE_MAP()
  142. // App command to run the dialog
  143. void CWatcherApp::OnAppAbout()
  144. {
  145. CAboutDlg aboutDlg;
  146. aboutDlg.DoModal();
  147. }
  148. /////////////////////////////////////////////////////////////////////////////
  149. // CWatcherApp message handlers
  150. void CWatcherApp::OnFileManage(){
  151. // Here we bring up the manage window.
  152. if (m_pManageDialog){
  153. m_pManageDialog->ShowWindow(SW_SHOWNORMAL);
  154. return;
  155. }
  156. // Actually construct the dialog box here
  157. m_pManageDialog = new ManageDialog();
  158. if( !m_pManageDialog){
  159. // Oops!! Memory problem
  160. return;
  161. }
  162. ((ManageDialog *) m_pManageDialog)->SetApplicationPtr(this);
  163. m_pManageDialog->Create(Manage);
  164. m_pManageDialog->ShowWindow(SW_SHOWNORMAL);
  165. return;
  166. }
  167. void CWatcherApp::OnHelp()
  168. {
  169. // Need to expand on this a little bit.
  170. CWinApp::WinHelp(0,HELP_CONTENTS);
  171. }
  172. void CWatcherApp::ParseCommandLine(CCommandLineInfo& rCmdInfo)
  173. {
  174. BOOL setReg = FALSE;
  175. for (int i = 1; i < __argc; i++){
  176. LPCTSTR pszParam = __targv[i];
  177. BOOL bFlag = FALSE;
  178. BOOL bLast = ((i + 1) == __argc);
  179. if (pszParam[0] == '-' || pszParam[0] == '/'){
  180. // remove flag specifier
  181. bFlag = TRUE;
  182. ++pszParam;
  183. if (_tcscmp(pszParam, TEXT("r")) == 0){
  184. // we are being given a new registry profile string
  185. // Can only change this from watcher.
  186. // HKEY_CURRENT_USER\\SOFTWARE\\%KEY%\\WATCHER
  187. if(!bLast) {
  188. // the next argument is the string
  189. SetRegistryKey(__targv[i+1]);
  190. i++;
  191. setReg = TRUE;
  192. if(i==__argc){
  193. if (rCmdInfo.m_nShellCommand == CCommandLineInfo::FileNew && !rCmdInfo.m_strFileName.IsEmpty())
  194. rCmdInfo.m_nShellCommand = CCommandLineInfo::FileOpen;
  195. rCmdInfo.m_bShowSplash = !rCmdInfo.m_bRunEmbedded && !rCmdInfo.m_bRunAutomated;
  196. }
  197. continue;
  198. }
  199. }
  200. }
  201. rCmdInfo.ParseParam(pszParam, bFlag, bLast);
  202. }
  203. if(!setReg){
  204. SetRegistryKey(AFX_IDS_COMPANY);
  205. }
  206. }
  207. BOOL CWatcherApp::ProcessShellCommand(CCommandLineInfo& rCmdInfo)
  208. {
  209. BOOL bResult = TRUE;
  210. switch (rCmdInfo.m_nShellCommand)
  211. {
  212. case CCommandLineInfo::FileNew:
  213. // Load parameters from the registry
  214. bResult = LoadRegistryParameters();
  215. break;
  216. // If we've been asked to open a file, call OpenDocumentFile()
  217. case CCommandLineInfo::FileOpen:
  218. // cannot happen ...... maybe later allow the user to read
  219. // parameters from a file.
  220. break;
  221. // If the user wanted to print, hide our main window and
  222. // fire a message to ourselves to start the printing
  223. case CCommandLineInfo::FilePrintTo:
  224. case CCommandLineInfo::FilePrint:
  225. m_nCmdShow = SW_HIDE;
  226. ASSERT(m_pCmdInfo == NULL);
  227. OpenDocumentFile(rCmdInfo.m_strFileName);
  228. m_pCmdInfo = &rCmdInfo;
  229. m_pMainWnd->SendMessage(WM_COMMAND, ID_FILE_PRINT_DIRECT);
  230. m_pCmdInfo = NULL;
  231. bResult = FALSE;
  232. break;
  233. // If we're doing DDE, hide ourselves
  234. case CCommandLineInfo::FileDDE:
  235. // m_pCmdInfo = (CCommandLineInfo*)m_nCmdShow;
  236. m_nCmdShow = SW_HIDE;
  237. break;
  238. // If we've been asked to unregister, unregister and then terminate
  239. case CCommandLineInfo::AppUnregister:
  240. {
  241. UnregisterShellFileTypes();
  242. BOOL bUnregistered = Unregister();
  243. // if you specify /EMBEDDED, we won't make an success/failure box
  244. // this use of /EMBEDDED is not related to OLE
  245. if (!rCmdInfo.m_bRunEmbedded)
  246. {
  247. if (bUnregistered)
  248. AfxMessageBox(AFX_IDP_UNREG_DONE);
  249. else
  250. AfxMessageBox(AFX_IDP_UNREG_FAILURE);
  251. }
  252. bResult = FALSE; // that's all we do
  253. // If nobody is using it already, we can use it.
  254. // We'll flag that we're unregistering and not save our state
  255. // on the way out. This new object gets deleted by the
  256. // app object destructor.
  257. if (m_pCmdInfo == NULL)
  258. {
  259. m_pCmdInfo = new CCommandLineInfo;
  260. m_pCmdInfo->m_nShellCommand = CCommandLineInfo::AppUnregister;
  261. }
  262. }
  263. break;
  264. }
  265. return bResult;
  266. }
  267. BOOL CWatcherApp::LoadRegistryParameters()
  268. {
  269. DWORD dwIndex=0;
  270. CString sess,lgnName, lgnPasswd;
  271. CString mac, com;
  272. UINT port;
  273. LONG RetVal;
  274. int tc, lang,hist;
  275. //Get each session parameters from here
  276. // There are NO optional values.
  277. while(1){
  278. RetVal = GetParametersByIndex(dwIndex,
  279. sess,
  280. mac,
  281. com,
  282. port,
  283. lang,
  284. tc,
  285. hist,
  286. lgnName,
  287. lgnPasswd
  288. );
  289. if(RetVal == ERROR_NO_MORE_ITEMS){
  290. return TRUE;
  291. }
  292. if (RetVal != ERROR_SUCCESS) {
  293. return FALSE;
  294. }
  295. // Make sure that the string buffers are NOT shared by locking
  296. // them.
  297. mac.LockBuffer();
  298. com.LockBuffer();
  299. lgnName.LockBuffer();
  300. lgnPasswd.LockBuffer();
  301. sess.LockBuffer(); // Passing references is really cool.
  302. CreateNewSession(mac, com, port,lang, tc, hist,lgnName, lgnPasswd,sess);
  303. dwIndex ++;
  304. }
  305. return TRUE;
  306. }
  307. int CWatcherApp::GetParametersByIndex(int dwIndex,
  308. CString &sess,
  309. CString &mac,
  310. CString &com,
  311. UINT &port,
  312. int &lang,
  313. int &tc,
  314. int &hist,
  315. CString &lgnName,
  316. CString &lgnPasswd
  317. )
  318. {
  319. LONG RetVal;
  320. TCHAR lpName[MAX_BUFFER_SIZE];
  321. DWORD lpcName;
  322. FILETIME lpftLastWriteTime;
  323. HKEY child;
  324. DWORD lpType = 0;
  325. if (m_hkey == NULL) return -1;
  326. lpcName = MAX_BUFFER_SIZE;
  327. RetVal = RegEnumKeyEx(m_hkey,
  328. dwIndex,
  329. lpName,
  330. &lpcName,
  331. NULL,
  332. NULL,
  333. NULL,
  334. &lpftLastWriteTime
  335. );
  336. if(RetVal == ERROR_NO_MORE_ITEMS){
  337. return RetVal;
  338. }
  339. if(RetVal != ERROR_SUCCESS){
  340. RegCloseKey(m_hkey);
  341. m_hkey = NULL;
  342. return FALSE;
  343. }
  344. sess = lpName;
  345. RetVal= RegOpenKeyEx(m_hkey,
  346. lpName, // subkey name
  347. 0, // reserved
  348. KEY_ALL_ACCESS, // security access mask
  349. &child
  350. );
  351. if(RetVal != ERROR_SUCCESS){
  352. // Hmm problem with main key itself
  353. RegCloseKey(m_hkey);
  354. m_hkey = NULL;
  355. return RetVal;
  356. }
  357. // We open the key corresponding to the session and then try to
  358. // obtain the parameters. Now, we need a lock possibly to achieve
  359. // synchronization.That would be a complete solution.
  360. // Use some kind of readers-writers solution.
  361. // Fault tolerant ???
  362. // Get the remaining parameters.
  363. RetVal = GetParameters(mac,
  364. com,
  365. lgnName,
  366. lgnPasswd,
  367. port,
  368. lang,
  369. tc,
  370. hist,
  371. child
  372. );
  373. RegCloseKey(child);
  374. return RetVal;
  375. }
  376. void CWatcherApp::CreateNewSession(CString &mac,
  377. CString &com,
  378. UINT port,
  379. int lang,
  380. int tc,
  381. int hist,
  382. CString &lgnName,
  383. CString &lgnPasswd,
  384. CString &sess
  385. )
  386. {
  387. CCreateContext con;
  388. CChildFrame *cmdiFrame;
  389. con.m_pNewViewClass = RUNTIME_CLASS(CWatcherView);
  390. con.m_pCurrentFrame = NULL;
  391. con.m_pNewDocTemplate = m_pDocTemplate;
  392. // A new document is created using these parameters.
  393. // BUGBUG - Memory inefficiency :-(
  394. // This function must be shared between the ManageDialog and
  395. // the Watcher Application.
  396. // Will probably declare them as friends of each other.
  397. // For the moment , let use have two copies of the function.
  398. con.m_pCurrentDoc = new CWatcherDoc(mac,
  399. com,
  400. port,
  401. tc,
  402. lang,
  403. hist,
  404. lgnName,
  405. lgnPasswd,
  406. sess
  407. );
  408. // Add the document to the template.
  409. // this is how the document is available to the document
  410. // manager.
  411. if(!con.m_pCurrentDoc){
  412. // Can occur if you keep on opening newer sessions.
  413. // Oops !!
  414. return;
  415. }
  416. m_pDocTemplate->AddDocument(con.m_pCurrentDoc);
  417. cmdiFrame = new CChildFrame();
  418. if(!cmdiFrame){
  419. // Oops !!
  420. return;
  421. }
  422. BOOL ret = cmdiFrame->LoadFrame(IDR_WATCHETYPE,
  423. WS_OVERLAPPEDWINDOW|FWS_ADDTOTITLE,
  424. NULL,
  425. &con);
  426. ret = con.m_pCurrentDoc->OnNewDocument();
  427. cmdiFrame->InitialUpdateFrame(con.m_pCurrentDoc,TRUE);
  428. return;
  429. }
  430. int CWatcherApp::GetParameters(CString &mac,
  431. CString &com,
  432. CString &lgnName,
  433. CString &lgnPasswd,
  434. UINT &port,
  435. int &lang,
  436. int &tc,
  437. int &hist,
  438. HKEY &child
  439. )
  440. {
  441. DWORD lpcName, lpType;
  442. TCHAR lpName[MAX_BUFFER_SIZE];
  443. int RetVal;
  444. // I see this kind of function in all the programs that use the
  445. // registry. Should try to simplify this.
  446. // BUGBUG - Memory inefficiency :-(
  447. // This function must be shared between the ManageDialog and
  448. // the Watcher Application.
  449. // Will probably declare them as friends of each other.
  450. // For the moment , let use have two copies of the function.
  451. lpcName = MAX_BUFFER_SIZE;
  452. RetVal = RegQueryValueEx(child,
  453. _TEXT("Machine"),
  454. NULL,
  455. &lpType,
  456. (LPBYTE)lpName,
  457. &lpcName
  458. );
  459. if(RetVal != ERROR_SUCCESS){
  460. return RetVal;
  461. }
  462. mac = lpName;
  463. lpName[0] = 0;
  464. lpcName = MAX_BUFFER_SIZE;
  465. RetVal = RegQueryValueEx(child,
  466. _TEXT("Command"),
  467. NULL,
  468. &lpType,
  469. (LPBYTE)lpName,
  470. &lpcName
  471. );
  472. if(RetVal != ERROR_SUCCESS){
  473. return RetVal;
  474. }
  475. com = lpName;
  476. lpcName = MAX_BUFFER_SIZE;
  477. lpName[0] = 0;
  478. RetVal = RegQueryValueEx(child,
  479. _TEXT("Password"),
  480. NULL,
  481. &lpType,
  482. (LPBYTE)lpName,
  483. &lpcName
  484. );
  485. if(RetVal != ERROR_SUCCESS){
  486. return RetVal;
  487. }
  488. lgnPasswd = lpName;
  489. lpName[0] = 0;
  490. lpcName = MAX_BUFFER_SIZE;
  491. RetVal = RegQueryValueEx(child,
  492. _TEXT("User Name"),
  493. NULL,
  494. &lpType,
  495. (LPBYTE)lpName,
  496. &lpcName
  497. );
  498. if(RetVal != ERROR_SUCCESS){
  499. return RetVal;
  500. }
  501. lgnName = lpName;
  502. lpcName = sizeof(int);
  503. RetVal = RegQueryValueEx(child,
  504. _TEXT("Port"),
  505. NULL,
  506. &lpType,
  507. (LPBYTE)&port,
  508. &lpcName
  509. );
  510. if(RetVal != ERROR_SUCCESS){
  511. return RetVal;
  512. }
  513. lpcName = sizeof(int);
  514. RetVal = RegQueryValueEx(child,
  515. _TEXT("Client Type"),
  516. NULL,
  517. &lpType,
  518. (LPBYTE)&tc,
  519. &lpcName
  520. );
  521. if(RetVal != ERROR_SUCCESS){
  522. return RetVal;
  523. }
  524. lpcName = sizeof(int);
  525. RetVal = RegQueryValueEx(child,
  526. _TEXT("Language"),
  527. NULL,
  528. &lpType,
  529. (LPBYTE)&lang,
  530. &lpcName
  531. );
  532. if(RetVal != ERROR_SUCCESS){
  533. return RetVal;
  534. }
  535. lpcName = sizeof(int);
  536. RetVal = RegQueryValueEx(child,
  537. _TEXT("History"),
  538. NULL,
  539. &lpType,
  540. (LPBYTE)&hist,
  541. &lpcName
  542. );
  543. return RetVal;
  544. }
  545. void CWatcherApp::OnAppExit()
  546. {
  547. // TODO: Add your command handler code here
  548. if (m_pManageDialog){
  549. delete m_pManageDialog;
  550. }
  551. if(m_hkey){
  552. RegCloseKey(m_hkey);
  553. m_hkey = NULL;
  554. }
  555. CWinApp::OnAppExit();
  556. }
  557. HKEY & CWatcherApp::GetKey()
  558. {
  559. return m_hkey;
  560. }
  561. void CWatcherApp::Refresh(ParameterDialog &pd, BOOLEAN del){
  562. POSITION index;
  563. if(m_pDocTemplate == NULL){
  564. return;
  565. }
  566. CDocument *doc;
  567. CWatcherDoc *wdoc;
  568. index = m_pDocTemplate->GetFirstDocPosition();
  569. while(index != NULL){
  570. doc = m_pDocTemplate->GetNextDoc(index);
  571. if(doc->GetTitle() == pd.Session){
  572. // May be conflict
  573. if(doc->IsKindOf(RUNTIME_CLASS(CWatcherDoc))){
  574. wdoc = (CWatcherDoc *) doc;
  575. ParameterDialog & dpd = wdoc->GetParameters();
  576. if(EqualParameters(pd, dpd)==FALSE){
  577. DeleteSession(doc);
  578. if(!del){
  579. CreateNewSession(pd.Machine, pd.Command, pd.Port,
  580. pd.language, pd.tcclnt, pd.history,
  581. pd.LoginName, pd.LoginPasswd,
  582. pd.Session
  583. );
  584. }
  585. return;
  586. }
  587. }else{
  588. // Doc Template returning junk values.
  589. return;
  590. }
  591. }
  592. }
  593. if(!del){
  594. CreateNewSession(pd.Machine, pd.Command, pd.Port,
  595. pd.language, pd.tcclnt, pd.history,
  596. pd.LoginName, pd.LoginPasswd,
  597. pd.Session
  598. );
  599. }
  600. }
  601. void CWatcherApp::DeleteSession(CDocument *wdoc)
  602. {
  603. POSITION pos;
  604. pos = wdoc->GetFirstViewPosition();
  605. while (pos != NULL){
  606. CView* pView = wdoc->GetNextView(pos);
  607. CWnd *pParent = pView->GetParent();
  608. if(pParent){
  609. pParent->PostMessage(WM_CLOSE,0,0);
  610. return;
  611. }
  612. }
  613. }
  614. BOOLEAN CWatcherApp::EqualParameters(ParameterDialog & pd1, ParameterDialog & pd2)
  615. {
  616. if((pd1.Session != pd2.Session)||
  617. (pd1.Machine != pd2.Machine)||
  618. (pd1.Command != pd2.Command)||
  619. (pd1.history != pd2.history)||
  620. (pd1.language != pd2.language)||
  621. (pd1.tcclnt != pd2.tcclnt)||
  622. (pd1.Port != pd2.Port)){
  623. return FALSE;
  624. }
  625. if((pd1.LoginPasswd != pd2.LoginPasswd)||
  626. (pd1.LoginName != pd2.LoginName)){
  627. return FALSE;
  628. }
  629. return TRUE;
  630. }