Leaked source code of windows server 2003
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.

1588 lines
41 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. // Copyright (c) 2002 Microsoft Corporation. All rights reserved.
  3. // Copyright (c) 2002 OSR Open Systems Resources, Inc.
  4. //
  5. // LogSessionDialog.cpp : implementation file
  6. //////////////////////////////////////////////////////////////////////////////
  7. #include "stdafx.h"
  8. #include <tchar.h>
  9. #include <wmistr.h>
  10. #include <initguid.h>
  11. extern "C" {
  12. #include <evntrace.h>
  13. }
  14. #include <traceprt.h>
  15. #include "TraceView.h"
  16. #include "DockDialogBar.h"
  17. #include "LogSession.h"
  18. #include "DisplayDlg.h"
  19. #include "ListCtrlEx.h"
  20. #include "Utils.h"
  21. #include "LogSessionDlg.h"
  22. // CLogSessionDlg dialog
  23. IMPLEMENT_DYNAMIC(CLogSessionDlg, CDialog)
  24. CLogSessionDlg::CLogSessionDlg(CWnd* pParent /*=NULL*/)
  25. : CDialog(CLogSessionDlg::IDD, pParent)
  26. {
  27. //
  28. // Set the column titles
  29. //
  30. m_columnName.Add("State ");
  31. m_columnName.Add("Event Count");
  32. m_columnName.Add("Lost Events");
  33. m_columnName.Add("Buffers Read");
  34. m_columnName.Add("Flags");
  35. m_columnName.Add("Flush Time");
  36. m_columnName.Add("Max Buf");
  37. m_columnName.Add("Min Buf");
  38. m_columnName.Add("Buf Size");
  39. m_columnName.Add("Age");
  40. m_columnName.Add("Circular");
  41. m_columnName.Add("Sequential");
  42. m_columnName.Add("New File");
  43. m_columnName.Add("Global Seq");
  44. m_columnName.Add("Local Seq");
  45. m_columnName.Add("Level");
  46. //
  47. // Set the initial column widths
  48. //
  49. for(LONG ii = 0; ii < MaxLogSessionOptions; ii++) {
  50. m_columnWidth[ii] = 100;
  51. }
  52. //
  53. // Initialize the ID arrays
  54. //
  55. memset(m_logSessionIDList, 0, sizeof(BOOL) * MAX_LOG_SESSIONS);
  56. memset(m_displayWndIDList, 0, sizeof(BOOL) * MAX_LOG_SESSIONS);
  57. m_displayFlags = 0;
  58. m_logSessionDisplayFlags = 0x00000000;
  59. //
  60. // Create the parameter change signalling event
  61. //
  62. m_hParameterChangeEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  63. }
  64. CLogSessionDlg::~CLogSessionDlg()
  65. {
  66. CLogSession *pLogSession;
  67. //
  68. // Get the log session array protection
  69. //
  70. WaitForSingleObject(m_logSessionArrayMutex, INFINITE);
  71. //
  72. // cleanup our display bar list
  73. //
  74. while(m_logSessionArray.GetSize() > 0) {
  75. pLogSession = (CLogSession *)m_logSessionArray.GetAt(0);
  76. m_logSessionArray.RemoveAt(0);
  77. if(pLogSession != NULL) {
  78. if((pLogSession->m_bTraceActive) && (!pLogSession->m_bStoppingTrace)) {
  79. pLogSession->EndTrace();
  80. }
  81. //
  82. // Disengage the display window from this log session
  83. //
  84. ReleaseDisplayWnd(pLogSession);
  85. ReleaseLogSessionID(pLogSession);
  86. delete pLogSession;
  87. }
  88. }
  89. //
  90. // Release the log session array protection
  91. //
  92. ReleaseMutex(m_logSessionArrayMutex);
  93. ASSERT(m_traceDisplayWndArray.GetSize() == 0);
  94. //
  95. // close our event handle
  96. //
  97. CloseHandle(m_hParameterChangeEvent);
  98. //
  99. // Close the mutex handles
  100. //
  101. CloseHandle(m_traceDisplayWndMutex);
  102. CloseHandle(m_logSessionArrayMutex);
  103. }
  104. BOOL CLogSessionDlg::OnInitDialog()
  105. {
  106. RECT rc;
  107. RECT parentRC;
  108. CString str;
  109. CDialog::OnInitDialog();
  110. //
  111. // Create the trace window pointer array protection mutex
  112. //
  113. m_traceDisplayWndMutex = CreateMutex(NULL,TRUE,NULL);
  114. if(m_traceDisplayWndMutex == NULL) {
  115. DWORD error = GetLastError();
  116. str.Format(_T("CreateMutex Error error %d %x"),error,error);
  117. AfxMessageBox(str);
  118. return FALSE;
  119. }
  120. ReleaseMutex(m_traceDisplayWndMutex);
  121. //
  122. // Create the log session array protection mutex
  123. //
  124. m_logSessionArrayMutex = CreateMutex(NULL, TRUE, NULL);
  125. if(m_logSessionArrayMutex == NULL) {
  126. DWORD error = GetLastError();
  127. str.Format(_T("CreateMutex Error error %d %x"),error,error);
  128. AfxMessageBox(str);
  129. return FALSE;
  130. }
  131. ReleaseMutex(m_logSessionArrayMutex);
  132. //
  133. // get the parent dimensions
  134. //
  135. GetParent()->GetParent()->GetClientRect(&parentRC);
  136. //
  137. // get the dialog dimensions
  138. //
  139. GetWindowRect(&rc);
  140. //
  141. // adjust the list control dimensions
  142. //
  143. rc.right = parentRC.right - parentRC.left - 24;
  144. rc.bottom = rc.bottom - rc.top;
  145. rc.left = 0;
  146. rc.top = 0;
  147. if(!m_displayCtrl.Create(WS_CHILD|WS_VISIBLE|WS_BORDER|LVS_REPORT,
  148. rc,
  149. this,
  150. IDC_DISPLAY_LIST))
  151. {
  152. TRACE(_T("Failed to create logger list control\n"));
  153. return FALSE;
  154. }
  155. for(LONG ii = 0; ii < MaxLogSessionOptions; ii++) {
  156. //
  157. // This lookup table allows a retrieval of the current
  158. // position of a given column like m_retrievalArray[State]
  159. // will return the correct column value for the State
  160. // column
  161. //
  162. m_retrievalArray[ii] = ii;
  163. //
  164. // This lookup table allows correct placement of
  165. // a column being added. So, if the State column
  166. // needed to be inserted, then m_insertionArray[State]
  167. // would give the correct insertion column value.
  168. // It is also used in SetItemText to update the correct
  169. // column.
  170. //
  171. m_insertionArray[ii] = ii;
  172. }
  173. //
  174. // We have to return zero here to get the focus set correctly
  175. // for the app.
  176. //
  177. return 0;
  178. }
  179. void CLogSessionDlg::OnNcPaint()
  180. {
  181. CRect pRect;
  182. GetClientRect(&pRect);
  183. InvalidateRect(&pRect, TRUE);
  184. }
  185. void CLogSessionDlg::DoDataExchange(CDataExchange* pDX)
  186. {
  187. CDialog::DoDataExchange(pDX);
  188. }
  189. VOID CLogSessionDlg::SetDisplayFlags(LONG DisplayFlags)
  190. {
  191. LONG addDisplayFlags = ~m_displayFlags & DisplayFlags;
  192. LONG removeDisplayFlags = m_displayFlags & ~DisplayFlags;
  193. LONG updateDisplayFlags = m_displayFlags & DisplayFlags;
  194. LONG ii;
  195. LONG jj;
  196. LONG kk;
  197. LONG ll;
  198. CString str;
  199. CLogSession *pLog;
  200. LONG limit;
  201. //
  202. // Now insert any new columns and remove any uneeded
  203. //
  204. for(ii = 0, jj = 1; ii < MaxLogSessionOptions; ii++, jj <<= 1) {
  205. //
  206. // add the columns
  207. //
  208. if(addDisplayFlags & jj) {
  209. //
  210. // insert the column
  211. //
  212. m_displayCtrl.InsertColumn(m_insertionArray[ii + 1],
  213. m_columnName[ii],
  214. LVCFMT_LEFT,
  215. m_columnWidth[ii]);
  216. //
  217. // update the column positions
  218. //
  219. for(kk = 0, ll = 1; kk < MaxLogSessionOptions; kk++) {
  220. m_insertionArray[kk + 1] = ll;
  221. if(DisplayFlags & (1 << kk)) {
  222. m_retrievalArray[ll] = kk;
  223. ll++;
  224. }
  225. }
  226. }
  227. //
  228. // remove the columns
  229. //
  230. if(removeDisplayFlags & jj) {
  231. //
  232. // Get the width of the column to be removed
  233. //
  234. m_columnWidth[ii] =
  235. m_displayCtrl.GetColumnWidth(m_insertionArray[ii + 1]);
  236. //
  237. // remove the column
  238. //
  239. m_displayCtrl.DeleteColumn(m_insertionArray[ii + 1]);
  240. //
  241. // update the column positions
  242. //
  243. for(kk = 0, ll = 1; kk < MaxLogSessionOptions; kk++) {
  244. m_insertionArray[kk + 1] = ll;
  245. if(DisplayFlags & (1 << kk)) {
  246. m_retrievalArray[ll] = kk;
  247. ll++;
  248. }
  249. }
  250. }
  251. }
  252. //
  253. // Save our new flags
  254. //
  255. m_displayFlags = DisplayFlags;
  256. //
  257. // Get the log session array protection
  258. //
  259. WaitForSingleObject(m_logSessionArrayMutex, INFINITE);
  260. //
  261. // Now display the log session properties that
  262. // have been selected
  263. //
  264. for(ii = 0; ii < m_logSessionArray.GetSize(); ii++) {
  265. pLog = (CLogSession *)m_logSessionArray[ii];
  266. if(NULL == pLog) {
  267. continue;
  268. }
  269. limit = MaxLogSessionOptions;
  270. if(pLog->m_bDisplayExistingLogFileOnly) {
  271. limit = 1;
  272. }
  273. for(jj = 0; jj < limit; jj++) {
  274. SetItemText(ii,
  275. jj + 1,
  276. pLog->m_logSessionValues[jj]);
  277. }
  278. }
  279. //
  280. // Release the log session array protection
  281. //
  282. ReleaseMutex(m_logSessionArrayMutex);
  283. }
  284. BOOL CLogSessionDlg::SetItemText(int nItem, int nSubItem, LPCTSTR lpszText)
  285. {
  286. //
  287. // Adjust the subitem value for the correct column and insert
  288. //
  289. if(m_displayFlags & (1 << (nSubItem - 1))) {
  290. return m_displayCtrl.SetItemText(nItem,
  291. m_insertionArray[nSubItem],
  292. lpszText);
  293. }
  294. return FALSE;
  295. }
  296. BOOL CLogSessionDlg::AddSession(CLogSession *pLogSession)
  297. {
  298. CLogSession *pLog;
  299. CString text;
  300. LONG numberOfEntries;
  301. //
  302. // Get the log session array protection
  303. //
  304. WaitForSingleObject(m_logSessionArrayMutex, INFINITE);
  305. //
  306. // add the element to the array
  307. //
  308. m_logSessionArray.Add(pLogSession);
  309. //
  310. // Release the log session array protection
  311. //
  312. ReleaseMutex(m_logSessionArrayMutex);
  313. //
  314. // Get a trace display window for the session
  315. //
  316. if(!AssignDisplayWnd(pLogSession)) {
  317. return FALSE;
  318. }
  319. //
  320. // Get the log session array protection
  321. //
  322. WaitForSingleObject(m_logSessionArrayMutex, INFINITE);
  323. numberOfEntries = (LONG)m_logSessionArray.GetSize();
  324. //
  325. // Release the log session array protection
  326. //
  327. ReleaseMutex(m_logSessionArrayMutex);
  328. for(LONG ii = 0; ii < numberOfEntries; ii++) {
  329. //
  330. // Get the log session array protection
  331. //
  332. WaitForSingleObject(m_logSessionArrayMutex, INFINITE);
  333. pLog = (CLogSession *)m_logSessionArray[ii];
  334. //
  335. // Release the log session array protection
  336. //
  337. ReleaseMutex(m_logSessionArrayMutex);
  338. if(pLog == pLogSession) {
  339. text.Format(_T("%d "), pLogSession->GetGroupID());
  340. text += pLogSession->GetDisplayName();
  341. //
  342. // Display the name
  343. //
  344. m_displayCtrl.InsertItem(ii,
  345. text,
  346. pLogSession);
  347. UpdateSession(pLogSession);
  348. if(numberOfEntries <= 1) {
  349. AutoSizeColumns();
  350. }
  351. return TRUE;
  352. }
  353. }
  354. return FALSE;
  355. }
  356. VOID CLogSessionDlg::UpdateSession(CLogSession *pLogSession)
  357. {
  358. LONG logSessionDisplayFlags;
  359. CLogSession *pLog;
  360. BOOL bActiveSession = FALSE;
  361. LONG traceDisplayFlags;
  362. LONG numberOfEntries;
  363. //
  364. // Get the log session array protection
  365. //
  366. WaitForSingleObject(m_logSessionArrayMutex, INFINITE);
  367. numberOfEntries = (LONG)m_logSessionArray.GetSize();
  368. //
  369. // Release the log session array protection
  370. //
  371. ReleaseMutex(m_logSessionArrayMutex);
  372. //
  373. // recalculate the display flags
  374. //
  375. for(LONG ii = 0; ii < numberOfEntries; ii++) {
  376. //
  377. // Get the log session array protection
  378. //
  379. WaitForSingleObject(m_logSessionArrayMutex, INFINITE);
  380. pLog = (CLogSession *)m_logSessionArray[ii];
  381. //
  382. // Release the log session array protection
  383. //
  384. ReleaseMutex(m_logSessionArrayMutex);
  385. if((NULL != pLog) && !pLog->m_bDisplayExistingLogFileOnly) {
  386. bActiveSession = TRUE;
  387. }
  388. }
  389. //
  390. // Figure out if we need to stop displaying columns
  391. //
  392. logSessionDisplayFlags = GetDisplayFlags();
  393. SetDisplayFlags(logSessionDisplayFlags ? logSessionDisplayFlags : 0xFFFFFFFF);
  394. //
  395. // Force an update of the display window as well
  396. //
  397. traceDisplayFlags = pLogSession->GetDisplayWnd()->GetDisplayFlags();
  398. pLogSession->GetDisplayWnd()->SetDisplayFlags(traceDisplayFlags);
  399. }
  400. VOID CLogSessionDlg::RemoveSession(CLogSession *pLogSession)
  401. {
  402. CDisplayDlg *pDisplayDlg;
  403. CDockDialogBar *pDialogBar;
  404. CLogSession *pLog;
  405. if(pLogSession == NULL) {
  406. return;
  407. }
  408. //
  409. // Disengage the display window from this log session
  410. //
  411. ReleaseDisplayWnd(pLogSession);
  412. //
  413. // Get the log session array protection
  414. //
  415. WaitForSingleObject(m_logSessionArrayMutex, INFINITE);
  416. //
  417. // remove the session from display
  418. //
  419. for(LONG ii = (LONG)m_logSessionArray.GetSize() - 1; ii >= 0; ii--) {
  420. pLog = (CLogSession *)m_logSessionArray[ii];
  421. if(pLog == pLogSession) {
  422. m_displayCtrl.DeleteItem(ii);
  423. //
  424. // delete the log session from the array
  425. //
  426. m_logSessionArray.RemoveAt(ii);
  427. break;
  428. }
  429. }
  430. //
  431. // Release the log session array protection
  432. //
  433. ReleaseMutex(m_logSessionArrayMutex);
  434. //
  435. // Return the log session ID
  436. //
  437. ReleaseLogSessionID(pLogSession);
  438. if(m_logSessionArray.GetSize() == 0) {
  439. SetDisplayFlags(0);
  440. }
  441. }
  442. VOID CLogSessionDlg::RemoveSelectedLogSessions()
  443. {
  444. POSITION pos;
  445. LONG index;
  446. CLogSession *pLogSession;
  447. CDisplayDlg *pDisplayDlg;
  448. pos = m_displayCtrl.GetFirstSelectedItemPosition();
  449. while(pos != NULL) {
  450. //
  451. // Find any selected sessions
  452. //
  453. index = m_displayCtrl.GetNextSelectedItem(pos);
  454. //
  455. // Get the log session array protection
  456. //
  457. WaitForSingleObject(m_logSessionArrayMutex, INFINITE);
  458. pLogSession = (CLogSession *)m_logSessionArray[index];
  459. //
  460. // Release the log session array protection
  461. //
  462. ReleaseMutex(m_logSessionArrayMutex);
  463. pDisplayDlg = pLogSession->GetDisplayWnd();
  464. if(pDisplayDlg->m_sessionArray.GetSize() > 1) {
  465. //
  466. // Don't allow grouped sessions to get removed
  467. //
  468. continue;
  469. }
  470. RemoveSession(pLogSession);
  471. //
  472. // delete the log session
  473. //
  474. delete pLogSession;
  475. }
  476. }
  477. VOID CLogSessionDlg::GroupSessions(CPtrArray *pLogSessionArray)
  478. {
  479. CLogSession *pLogSession = NULL;
  480. LONG groupID = -1;
  481. CString str;
  482. //
  483. // Disconnect sessions from group display windows
  484. //
  485. for(LONG ii = 0; ii < pLogSessionArray->GetSize(); ii++) {
  486. pLogSession = (CLogSession *)pLogSessionArray->GetAt(ii);
  487. if(NULL == pLogSession) {
  488. continue;
  489. }
  490. //
  491. // Disconnect the display window and possibly remove it
  492. //
  493. ReleaseDisplayWnd(pLogSession);
  494. }
  495. //
  496. // Attach the first log session to a group window
  497. // then use this for all subsequent log sessions
  498. //
  499. for(LONG ii = 0; ii < pLogSessionArray->GetSize(); ii++) {
  500. pLogSession = (CLogSession *)pLogSessionArray->GetAt(ii);
  501. if(NULL == pLogSession) {
  502. continue;
  503. }
  504. //
  505. // Set the group ID
  506. //
  507. pLogSession->SetGroupID(groupID);
  508. //
  509. // Hook up the group window
  510. //
  511. AssignDisplayWnd(pLogSession);
  512. //
  513. // Update the session group ID in the display
  514. //
  515. str.Format(_T("%d %ls"), pLogSession->GetGroupID(), pLogSession->GetDisplayName());
  516. for(LONG jj = 0; jj < m_displayCtrl.GetItemCount(); jj++) {
  517. if(pLogSession == (CLogSession *)m_displayCtrl.GetItemData(jj)) {
  518. m_displayCtrl.SetItemText(jj, 0, str);
  519. break;
  520. }
  521. }
  522. //
  523. // Get the new group ID
  524. //
  525. groupID = pLogSession->GetGroupID();
  526. }
  527. //
  528. // Now start the new group
  529. //
  530. pLogSession->GetDisplayWnd()->BeginTrace();
  531. }
  532. VOID CLogSessionDlg::UnGroupSessions(CPtrArray *pLogSessionArray)
  533. {
  534. CLogSession *pLogSession = NULL;
  535. LONG groupID = -1;
  536. CString str;
  537. LONG ii;
  538. //
  539. // Disconnect all sessions from their groups
  540. //
  541. for(ii = 0; ii < pLogSessionArray->GetSize(); ii++) {
  542. pLogSession = (CLogSession *)pLogSessionArray->GetAt(ii);
  543. if(NULL == pLogSession) {
  544. continue;
  545. }
  546. //
  547. // Disconnect the display window and possibly remove it
  548. //
  549. ReleaseDisplayWnd(pLogSession);
  550. }
  551. //
  552. // Create a unique group for each
  553. //
  554. for(ii = 0; ii < pLogSessionArray->GetSize(); ii++) {
  555. pLogSession = (CLogSession *)pLogSessionArray->GetAt(ii);
  556. if(NULL == pLogSession) {
  557. continue;
  558. }
  559. //
  560. // Hook up the group window
  561. //
  562. AssignDisplayWnd(pLogSession);
  563. //
  564. // Update the session group ID in the display
  565. //
  566. str.Format(_T("%d %ls"), pLogSession->GetGroupID(), pLogSession->GetDisplayName());
  567. for(LONG jj = 0; jj < m_displayCtrl.GetItemCount(); jj++) {
  568. if(pLogSession == (CLogSession *)m_displayCtrl.GetItemData(jj)) {
  569. m_displayCtrl.SetItemText(jj, 0, str);
  570. break;
  571. }
  572. }
  573. //
  574. // Now start the new group
  575. //
  576. pLogSession->GetDisplayWnd()->BeginTrace();
  577. }
  578. }
  579. BOOL CLogSessionDlg::AssignDisplayWnd(CLogSession *pLogSession)
  580. {
  581. CDisplayDlg *pDisplayDlg;
  582. CString str;
  583. DWORD extendedStyles;
  584. LONG numberOfEntries;
  585. //
  586. // If we have a valid group number see if there is an
  587. // existing group window
  588. //
  589. if(pLogSession->GetGroupID() != -1) {
  590. //
  591. // Get the trace display window array protection
  592. //
  593. WaitForSingleObject(m_traceDisplayWndMutex, INFINITE);
  594. numberOfEntries = (LONG)m_traceDisplayWndArray.GetSize();
  595. //
  596. // Release the trace display window array protection
  597. //
  598. ReleaseMutex(m_traceDisplayWndMutex);
  599. //
  600. // Use the group window if there is one
  601. //
  602. for(LONG ii = 0; ii < numberOfEntries; ii++) {
  603. //
  604. // Get the trace display window array protection
  605. //
  606. WaitForSingleObject(m_traceDisplayWndMutex, INFINITE);
  607. pDisplayDlg = (CDisplayDlg *)m_traceDisplayWndArray[ii];
  608. if(pDisplayDlg == NULL) {
  609. continue;
  610. }
  611. //
  612. // Release the trace display window array protection
  613. //
  614. ReleaseMutex(m_traceDisplayWndMutex);
  615. if(pDisplayDlg->GetDisplayID() == pLogSession->GetGroupID()) {
  616. pLogSession->SetDisplayWnd(pDisplayDlg);
  617. //
  618. // add the element to the display wnd
  619. //
  620. pDisplayDlg->AddSession(pLogSession);
  621. return TRUE;
  622. }
  623. }
  624. }
  625. //
  626. // Otherwise create a new group display window
  627. //
  628. CDockDialogBar *pDialogBar = new CDockDialogBar();
  629. if(NULL == pDialogBar) {
  630. AfxMessageBox(_T("Failed To Create Display Window\nMemory Allocation Failure"));
  631. return FALSE;
  632. }
  633. pDisplayDlg = new CDisplayDlg(GetParentFrame(),
  634. GetDisplayWndID());
  635. if(NULL == pDisplayDlg) {
  636. AfxMessageBox(_T("Failed To Create Display Window\nMemory Allocation Failure"));
  637. delete pDialogBar;
  638. return FALSE;
  639. }
  640. str.Format(_T("Group %d"), pDisplayDlg->GetDisplayID());
  641. //
  642. // create our dockable dialog bar with list control
  643. //
  644. if(!pDialogBar->Create(GetParentFrame(),
  645. pDisplayDlg,
  646. str,
  647. IDD_DISPLAY_DIALOG,
  648. WS_CHILD|WS_VISIBLE|CBRS_BOTTOM|CBRS_TOOLTIPS|CBRS_SIZE_DYNAMIC,
  649. TRUE))
  650. {
  651. AfxMessageBox(_T("Failed To Create Display Window"));
  652. delete pDisplayDlg;
  653. delete pDialogBar;
  654. return FALSE;
  655. }
  656. //
  657. // Store the dock dialog pointer in the display dialog instance
  658. //
  659. pDisplayDlg->SetDockDialogBar((PVOID)pDialogBar);
  660. //
  661. // set our preferred extended styles
  662. //
  663. extendedStyles = LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT;
  664. //
  665. // Set the extended styles for the list control
  666. //
  667. pDisplayDlg->m_displayCtrl.SetExtendedStyle(extendedStyles);
  668. //
  669. // make the dialog dockable and dock it to the top
  670. //
  671. pDialogBar->EnableDocking(CBRS_ALIGN_TOP);
  672. //
  673. // dock the bar to the top
  674. //
  675. GetParentFrame()->DockControlBar(pDialogBar, AFX_IDW_DOCKBAR_TOP);
  676. //
  677. // Get the trace display window array protection
  678. //
  679. WaitForSingleObject(m_traceDisplayWndMutex, INFINITE);
  680. //
  681. // Add the bar to our array
  682. //
  683. m_traceDisplayWndArray.Add(pDisplayDlg);
  684. //
  685. // Release the trace display window array protection
  686. //
  687. ReleaseMutex(m_traceDisplayWndMutex);
  688. //
  689. // Set the log session group ID
  690. //
  691. pLogSession->SetGroupID(pDisplayDlg->GetDisplayID());
  692. //
  693. // Set the log session display pointer
  694. //
  695. pLogSession->SetDisplayWnd(pDisplayDlg);
  696. //
  697. // add the element to the display wnd
  698. //
  699. pDisplayDlg->AddSession(pLogSession);
  700. return TRUE;
  701. }
  702. VOID CLogSessionDlg::ReleaseDisplayWnd(CLogSession *pLogSession)
  703. {
  704. CString str;
  705. CDisplayDlg *pDisplayDlg;
  706. CDockDialogBar *pDialogBar = NULL;
  707. CLogSession *pLog;
  708. if(pLogSession == NULL) {
  709. return;
  710. }
  711. //
  712. // get the session's display window
  713. //
  714. pDisplayDlg = pLogSession->GetDisplayWnd();
  715. //
  716. // Clear the display window pointer from the log session
  717. //
  718. pLogSession->SetDisplayWnd(NULL);
  719. //
  720. // Set the group ID to an invalid ID
  721. //
  722. pLogSession->SetGroupID(-1);
  723. if(NULL == pDisplayDlg) {
  724. return;
  725. }
  726. //
  727. // Pull the log session from the displayDlg's array
  728. //
  729. pDisplayDlg->RemoveSession(pLogSession);
  730. //
  731. // Get the array protection
  732. //
  733. WaitForSingleObject(pDisplayDlg->m_hSessionArrayMutex, INFINITE);
  734. //
  735. // If there are still log sessions attached to this window
  736. // just return
  737. //
  738. if(pDisplayDlg->m_sessionArray.GetSize() > 0) {
  739. //
  740. // Release the array protection
  741. //
  742. ReleaseMutex(pDisplayDlg->m_hSessionArrayMutex);
  743. return;
  744. }
  745. //
  746. // Release the array protection
  747. //
  748. ReleaseMutex(pDisplayDlg->m_hSessionArrayMutex);
  749. //
  750. // Get the trace display window array protection
  751. //
  752. WaitForSingleObject(m_traceDisplayWndMutex, INFINITE);
  753. //
  754. // Remove this window from the list of display windows
  755. //
  756. for (LONG ii = (LONG)m_traceDisplayWndArray.GetSize() - 1; ii >=0 ; ii--) {
  757. if(m_traceDisplayWndArray[ii] == pDisplayDlg) {
  758. m_traceDisplayWndArray.RemoveAt(ii);
  759. break;
  760. }
  761. }
  762. //
  763. // Release the trace display window array protection
  764. //
  765. ReleaseMutex(m_traceDisplayWndMutex);
  766. //
  767. // Get the dock dialog bar so it can be deleted
  768. //
  769. pDialogBar = (CDockDialogBar *)pDisplayDlg->GetDockDialogBar();
  770. //
  771. // Clear the pointer in the class
  772. //
  773. pDisplayDlg->SetDockDialogBar(NULL);
  774. //
  775. // Release the window ID
  776. //
  777. ReleaseDisplayWndID(pDisplayDlg);
  778. //
  779. // delete the display window
  780. //
  781. delete pDisplayDlg;
  782. //
  783. // Delete the dock dialog bar
  784. //
  785. if(NULL != pDialogBar) {
  786. delete pDialogBar;
  787. }
  788. }
  789. BEGIN_MESSAGE_MAP(CLogSessionDlg, CDialog)
  790. //{{AFX_MSG_MAP(CLogSessionDlg)
  791. ON_WM_WINDOWPOSCHANGED()
  792. ON_WM_NCCALCSIZE()
  793. ON_WM_SIZE()
  794. ON_MESSAGE(WM_PARAMETER_CHANGED, OnParameterChanged)
  795. ON_NOTIFY(NM_CLICK, IDC_DISPLAY_LIST, OnNMClickDisplayList)
  796. ON_NOTIFY(NM_RCLICK, IDC_DISPLAY_LIST, OnNMRclickDisplayList)
  797. ON_NOTIFY(HDN_ITEMRCLICK, IDC_DISPLAY_LIST, OnHDNRclickDisplayList)
  798. //}}AFX_MSG_MAP
  799. END_MESSAGE_MAP()
  800. // CLogSessionDlg message handlers
  801. void CLogSessionDlg::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos)
  802. {
  803. CDialog::OnWindowPosChanged(lpwndpos);
  804. }
  805. void CLogSessionDlg::OnSize(UINT nType, int cx,int cy)
  806. {
  807. CRect rc;
  808. if(!IsWindow(m_displayCtrl.GetSafeHwnd()))
  809. {
  810. return;
  811. }
  812. GetParent()->GetClientRect(&rc);
  813. //
  814. // reset the size of the dialog
  815. //
  816. SetWindowPos(NULL,
  817. 0,
  818. 0,
  819. rc.right - rc.left,
  820. rc.bottom - rc.top,
  821. SWP_NOMOVE|SWP_SHOWWINDOW|SWP_NOZORDER);
  822. GetClientRect(&rc);
  823. m_displayCtrl.MoveWindow(rc);
  824. }
  825. BOOL CLogSessionDlg::PreTranslateMessage(MSG* pMsg)
  826. {
  827. if(pMsg->message == WM_KEYDOWN)
  828. {
  829. if((pMsg->wParam == VK_ESCAPE) || (pMsg->wParam == VK_RETURN))
  830. {
  831. //
  832. // Ignore the escape and return keys, otherwise
  833. // the client area grays out on escape
  834. //
  835. return TRUE;
  836. }
  837. //
  838. // Fix for key accelerators, otherwise they are never
  839. // processed
  840. //
  841. if (AfxGetMainWnd()->PreTranslateMessage(pMsg))
  842. return TRUE;
  843. return CDialog::PreTranslateMessage(pMsg);
  844. }
  845. return CDialog::PreTranslateMessage(pMsg);
  846. }
  847. LRESULT CLogSessionDlg::OnParameterChanged(WPARAM wParam, LPARAM lParam)
  848. {
  849. CLogSession *pLogSession;
  850. CString str;
  851. //
  852. // Get the log session array protection
  853. //
  854. WaitForSingleObject(m_logSessionArrayMutex, INFINITE);
  855. pLogSession = (CLogSession *)m_logSessionArray[wParam];
  856. //
  857. // Release the log session array protection
  858. //
  859. ReleaseMutex(m_logSessionArrayMutex);
  860. if(NULL == pLogSession) {
  861. return 0;
  862. }
  863. pLogSession->m_logSessionValues[m_retrievalArray[(int)lParam]] =
  864. m_displayCtrl.GetItemText((int)wParam, (int)lParam);
  865. if((m_retrievalArray[lParam] == Circular) &&
  866. !pLogSession->m_logSessionValues[m_retrievalArray[lParam]].IsEmpty()) {
  867. pLogSession->m_logSessionValues[Sequential].Empty();
  868. pLogSession->m_logSessionValues[NewFile].Empty();
  869. }
  870. if((m_retrievalArray[lParam] == Sequential) &&
  871. !pLogSession->m_logSessionValues[m_retrievalArray[lParam]].IsEmpty()) {
  872. pLogSession->m_logSessionValues[Circular].Empty();
  873. pLogSession->m_logSessionValues[NewFile].Empty();
  874. }
  875. if((m_retrievalArray[lParam] == NewFile) &&
  876. !pLogSession->m_logSessionValues[m_retrievalArray[lParam]].IsEmpty()) {
  877. pLogSession->m_logSessionValues[Circular].Empty();
  878. pLogSession->m_logSessionValues[Sequential].Empty();
  879. }
  880. if((m_retrievalArray[lParam] == GlobalSequence) &&
  881. !pLogSession->m_logSessionValues[m_retrievalArray[lParam]].Compare(_T("TRUE"))) {
  882. pLogSession->m_logSessionValues[LocalSequence] = _T("FALSE");
  883. }
  884. if((m_retrievalArray[lParam] == LocalSequence) &&
  885. !pLogSession->m_logSessionValues[m_retrievalArray[lParam]].Compare(_T("TRUE"))) {
  886. pLogSession->m_logSessionValues[GlobalSequence] = _T("FALSE");
  887. }
  888. if(pLogSession->m_bTraceActive) {
  889. pLogSession->GetDisplayWnd()->UpdateSession(pLogSession);
  890. }
  891. //
  892. // Restart updating the log session list control
  893. //
  894. m_displayCtrl.SuspendUpdates(FALSE);
  895. UpdateSession(pLogSession);
  896. return 0;
  897. }
  898. void CLogSessionDlg::OnNMClickDisplayList(NMHDR *pNMHDR, LRESULT *pResult)
  899. {
  900. CString str;
  901. DWORD position;
  902. int listIndex;
  903. LVHITTESTINFO lvhti;
  904. CRect itemRect;
  905. CRect parentRect;
  906. CLogSession *pLogSession;
  907. // BUGBUG -- clean out uneeded str formats
  908. *pResult = 0;
  909. //
  910. // Get the position of the mouse when this
  911. // message posted
  912. //
  913. position = ::GetMessagePos();
  914. //
  915. // Get the position in an easy to use format
  916. //
  917. CPoint point((int) LOWORD (position), (int)HIWORD(position));
  918. //
  919. // Convert to client coordinates
  920. //
  921. ScreenToClient(&point);
  922. lvhti.pt = point;
  923. listIndex = m_displayCtrl.SubItemHitTest(&lvhti);
  924. if(0 == lvhti.iSubItem) {
  925. if(-1 == lvhti.iItem) {
  926. //str.Format(_T("NM Click: Item = %d, Flags = 0x%X\n"), lvhti.iItem, lvhti.flags);
  927. //TRACE(str);
  928. } else {
  929. //str.Format(_T("NM Click: Item = %d\n"), lvhti.iItem);
  930. //TRACE(str);
  931. }
  932. } else if(-1 == lvhti.iItem) {
  933. //str.Format(_T("NM Click: Item = %d, Flags = 0x%X\n"), lvhti.iItem, lvhti.flags);
  934. //TRACE(str);
  935. } else {
  936. //str.Format(_T("NM Click: Item = %d, "), lvhti.iItem);
  937. //TRACE(str);
  938. //str.Format(_T("SubItem = %d\n"), lvhti.iSubItem);
  939. //TRACE(str);
  940. GetClientRect(&parentRect);
  941. m_displayCtrl.GetSubItemRect(lvhti.iItem, lvhti.iSubItem, LVIR_BOUNDS, itemRect);
  942. //
  943. // Get the log session array protection
  944. //
  945. WaitForSingleObject(m_logSessionArrayMutex, INFINITE);
  946. //
  947. // Get the log session for this row
  948. //
  949. pLogSession = (CLogSession *)m_logSessionArray[lvhti.iItem];
  950. //
  951. // Release the log session array protection
  952. //
  953. ReleaseMutex(m_logSessionArrayMutex);
  954. if(pLogSession == NULL) {
  955. return;
  956. }
  957. //
  958. // State, EventCount, LostEvents, BuffersRead
  959. //
  960. if((m_retrievalArray[lvhti.iSubItem] == State) ||
  961. (m_retrievalArray[lvhti.iSubItem] == EventCount) ||
  962. (m_retrievalArray[lvhti.iSubItem] == LostEvents) ||
  963. (m_retrievalArray[lvhti.iSubItem] == BuffersRead)) {
  964. return;
  965. }
  966. //
  967. // Flags - special handling for Kernel Logger
  968. //
  969. if((m_retrievalArray[lvhti.iSubItem] == Flags) &&
  970. !_tcscmp(pLogSession->GetDisplayName(), _T("NT Kernel Logger"))) {
  971. return;
  972. }
  973. //
  974. // MaxBuffers
  975. //
  976. if((m_retrievalArray[lvhti.iSubItem] == MaximumBuffers) &&
  977. !pLogSession->m_bDisplayExistingLogFileOnly){
  978. //
  979. // Stop updating the log session list control until
  980. // this control goes away. Otherwise, this control
  981. // is disrupted. Updating is turned back on in the
  982. // OnParameterChanged callback.
  983. //
  984. m_displayCtrl.SuspendUpdates(TRUE);
  985. CEdit *pEdit = new CSubItemEdit(lvhti.iItem,
  986. lvhti.iSubItem,
  987. &m_displayCtrl);
  988. pEdit->Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP,
  989. itemRect,
  990. this,
  991. IDC_CUSTOM_EDIT);
  992. return;
  993. }
  994. //
  995. // FlushTime
  996. //
  997. if((m_retrievalArray[lvhti.iSubItem] == FlushTime) &&
  998. !pLogSession->m_bDisplayExistingLogFileOnly){
  999. //
  1000. // Stop updating the log session list control until
  1001. // this control goes away. Otherwise, this control
  1002. // is disrupted. Updating is turned back on in the
  1003. // OnParameterChanged callback.
  1004. //
  1005. m_displayCtrl.SuspendUpdates(TRUE);
  1006. CEdit *pEdit = new CSubItemEdit(lvhti.iItem,
  1007. lvhti.iSubItem,
  1008. &m_displayCtrl);
  1009. pEdit->Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP,
  1010. itemRect,
  1011. this,
  1012. IDC_CUSTOM_EDIT);
  1013. return;
  1014. }
  1015. //
  1016. // Flags
  1017. //
  1018. if((m_retrievalArray[lvhti.iSubItem] == Flags) &&
  1019. !pLogSession->m_bDisplayExistingLogFileOnly){
  1020. //
  1021. // Stop updating the log session list control until
  1022. // this control goes away. Otherwise, this control
  1023. // is disrupted. Updating is turned back on in the
  1024. // OnParameterChanged callback.
  1025. //
  1026. m_displayCtrl.SuspendUpdates(TRUE);
  1027. CEdit *pEdit = new CSubItemEdit(lvhti.iItem,
  1028. lvhti.iSubItem,
  1029. &m_displayCtrl);
  1030. pEdit->Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP,
  1031. itemRect,
  1032. this,
  1033. IDC_CUSTOM_EDIT);
  1034. return;
  1035. }
  1036. //
  1037. // Global Sequence
  1038. //
  1039. if((m_retrievalArray[lvhti.iSubItem] == GlobalSequence) &&
  1040. !pLogSession->m_bTraceActive &&
  1041. !pLogSession->m_bDisplayExistingLogFileOnly) {
  1042. CComboBox *pCombo = new CSubItemCombo(lvhti.iItem,
  1043. lvhti.iSubItem,
  1044. &m_displayCtrl);
  1045. //
  1046. // Stop updating the log session list control until
  1047. // this control goes away. Otherwise, this control
  1048. // is disrupted. Updating is turned back on in the
  1049. // OnParameterChanged callback.
  1050. //
  1051. m_displayCtrl.SuspendUpdates(TRUE);
  1052. pCombo->Create(WS_BORDER|WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST,
  1053. itemRect,
  1054. &m_displayCtrl,
  1055. IDC_CUSTOM_COMBO);
  1056. return;
  1057. }
  1058. //
  1059. // Local Sequence
  1060. //
  1061. if((m_retrievalArray[lvhti.iSubItem] == LocalSequence) &&
  1062. !pLogSession->m_bTraceActive &&
  1063. !pLogSession->m_bDisplayExistingLogFileOnly) {
  1064. CComboBox *pCombo = new CSubItemCombo(lvhti.iItem,
  1065. lvhti.iSubItem,
  1066. &m_displayCtrl);
  1067. //
  1068. // Stop updating the log session list control until
  1069. // this control goes away. Otherwise, this control
  1070. // is disrupted. Updating is turned back on in the
  1071. // OnParameterChanged callback.
  1072. //
  1073. m_displayCtrl.SuspendUpdates(TRUE);
  1074. pCombo->Create(WS_BORDER|WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST,
  1075. itemRect,
  1076. &m_displayCtrl,
  1077. IDC_CUSTOM_COMBO);
  1078. return;
  1079. }
  1080. //
  1081. // The Rest
  1082. //
  1083. if(!pLogSession->m_bTraceActive &&
  1084. !pLogSession->m_bDisplayExistingLogFileOnly) {
  1085. //
  1086. // Stop updating the log session list control until
  1087. // this control goes away. Otherwise, this control
  1088. // is disrupted. Updating is turned back on in the
  1089. // OnParameterChanged callback.
  1090. //
  1091. m_displayCtrl.SuspendUpdates(TRUE);
  1092. CEdit *pEdit = new CSubItemEdit(lvhti.iItem,
  1093. lvhti.iSubItem,
  1094. &m_displayCtrl);
  1095. pEdit->Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP,
  1096. itemRect,
  1097. this,
  1098. IDC_CUSTOM_EDIT);
  1099. return;
  1100. }
  1101. }
  1102. }
  1103. void CLogSessionDlg::OnNMRclickDisplayList(NMHDR *pNMHDR, LRESULT *pResult)
  1104. {
  1105. CString str;
  1106. DWORD position;
  1107. int listIndex;
  1108. LVHITTESTINFO lvhti;
  1109. *pResult = 0;
  1110. //
  1111. // Get the position of the mouse when this
  1112. // message posted
  1113. //
  1114. position = ::GetMessagePos();
  1115. //
  1116. // Get the position in an easy to use format
  1117. //
  1118. CPoint point((int) LOWORD (position), (int)HIWORD(position));
  1119. CPoint screenPoint(point);
  1120. //
  1121. // Convert to client coordinates
  1122. //
  1123. ScreenToClient(&point);
  1124. lvhti.pt = point;
  1125. listIndex = m_displayCtrl.SubItemHitTest(&lvhti);
  1126. //
  1127. // Pop-up menu for log session creation
  1128. //
  1129. if(-1 == lvhti.iItem) {
  1130. CMenu menu;
  1131. menu.LoadMenu(IDR_LOG_SESSION_POPUP_MENU);
  1132. CMenu* pPopup = menu.GetSubMenu(0);
  1133. ASSERT(pPopup != NULL);
  1134. pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, screenPoint.x, screenPoint.y, AfxGetMainWnd());
  1135. return;
  1136. }
  1137. //
  1138. // Pop-up menu for existing log session options
  1139. //
  1140. CMenu menu;
  1141. menu.LoadMenu(IDR_LOG_OPTIONS_POPUP_MENU);
  1142. CMenu* pPopup = menu.GetSubMenu(0);
  1143. ASSERT(pPopup != NULL);
  1144. pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, screenPoint.x, screenPoint.y, AfxGetMainWnd());
  1145. return;
  1146. }
  1147. void CLogSessionDlg::OnHDNRclickDisplayList(NMHDR *pNMHDR, LRESULT *pResult)
  1148. {
  1149. int index;
  1150. CRect rcCol;
  1151. BOOL bActiveSession = FALSE;
  1152. CLogSession *pLogSession;
  1153. LONG numberOfEntries;
  1154. //
  1155. // Get the log session array protection
  1156. //
  1157. WaitForSingleObject(m_logSessionArrayMutex, INFINITE);
  1158. if(m_logSessionArray.GetSize() == 0) {
  1159. *pResult = 0;
  1160. }
  1161. for(LONG ii = 0; ii < m_logSessionArray.GetSize(); ii++) {
  1162. pLogSession = (CLogSession *)m_logSessionArray[ii];
  1163. if(NULL != pLogSession) {
  1164. bActiveSession = TRUE;
  1165. break;
  1166. }
  1167. }
  1168. //
  1169. // Release the log session array protection
  1170. //
  1171. ReleaseMutex(m_logSessionArrayMutex);
  1172. if(!bActiveSession) {
  1173. *pResult = 0;
  1174. return;
  1175. }
  1176. //
  1177. // Right button was clicked on header
  1178. //
  1179. CPoint pt(GetMessagePos());
  1180. CPoint screenPt(GetMessagePos());
  1181. CHeaderCtrl *pHeader = m_displayCtrl.GetHeaderCtrl();
  1182. pHeader->ScreenToClient(&pt);
  1183. //
  1184. // Determine the column index
  1185. //
  1186. for(int i=0; Header_GetItemRect(pHeader->m_hWnd, i, &rcCol); i++) {
  1187. if(rcCol.PtInRect(pt)) {
  1188. //
  1189. // Column index if its ever needed
  1190. //
  1191. index = i;
  1192. break;
  1193. }
  1194. }
  1195. CMenu menu;
  1196. menu.LoadMenu(IDR_LOG_DISPLAY_OPTIONS_POPUP_MENU);
  1197. CMenu *pPopup = menu.GetSubMenu(0);
  1198. ASSERT(pPopup != NULL);
  1199. pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, screenPt.x, screenPt.y, AfxGetMainWnd());
  1200. *pResult = 0;
  1201. }
  1202. void CLogSessionDlg::AutoSizeColumns()
  1203. {
  1204. LONG colWidth1;
  1205. LONG colWidth2;
  1206. LONG columnCount;
  1207. CHeaderCtrl *pHeaderCtrl;
  1208. //
  1209. // Call this after the list control is filled
  1210. //
  1211. pHeaderCtrl = m_displayCtrl.GetHeaderCtrl();
  1212. if (pHeaderCtrl != NULL)
  1213. {
  1214. columnCount = pHeaderCtrl->GetItemCount();
  1215. //
  1216. // Add a bogus column to the end, or the end column will
  1217. // get resized to fit the remaining screen width
  1218. //
  1219. m_displayCtrl.InsertColumn(columnCount,_T(""));
  1220. for(LONG ii = 0; ii < columnCount; ii++) {
  1221. //
  1222. // Get the max width of the column entries
  1223. //
  1224. m_displayCtrl.SetColumnWidth(ii, LVSCW_AUTOSIZE);
  1225. colWidth1 = m_displayCtrl.GetColumnWidth(ii);
  1226. //
  1227. // Get the width of the column header
  1228. //
  1229. m_displayCtrl.SetColumnWidth(ii, LVSCW_AUTOSIZE_USEHEADER);
  1230. colWidth2 = m_displayCtrl.GetColumnWidth(ii);
  1231. //
  1232. // Set the column width to the max of the two
  1233. //
  1234. m_displayCtrl.SetColumnWidth(ii, max(colWidth1,colWidth2));
  1235. }
  1236. //
  1237. // Remove the bogus column
  1238. //
  1239. m_displayCtrl.DeleteColumn(columnCount);
  1240. }
  1241. }
  1242. LONG CLogSessionDlg::GetDisplayWndID()
  1243. {
  1244. for(LONG ii = 0; ii < MAX_LOG_SESSIONS; ii++) {
  1245. if(FALSE == m_displayWndIDList[ii]) {
  1246. m_displayWndIDList[ii] = TRUE;
  1247. return ii;
  1248. }
  1249. }
  1250. return -1;
  1251. }
  1252. VOID CLogSessionDlg::ReleaseDisplayWndID(CDisplayDlg *pDisplayDlg)
  1253. {
  1254. LONG displayID;
  1255. displayID = pDisplayDlg->GetDisplayID();
  1256. ASSERT(displayID < MAX_LOG_SESSIONS);
  1257. //
  1258. // Free the ID to be reused
  1259. //
  1260. m_displayWndIDList[displayID] = FALSE;
  1261. }
  1262. LONG CLogSessionDlg::GetLogSessionID()
  1263. {
  1264. for(LONG ii = 0; ii < MAX_LOG_SESSIONS; ii++) {
  1265. if(FALSE == m_logSessionIDList[ii]) {
  1266. m_logSessionIDList[ii] = TRUE;
  1267. return ii;
  1268. }
  1269. }
  1270. return -1;
  1271. }
  1272. VOID CLogSessionDlg::ReleaseLogSessionID(CLogSession *pLogSession)
  1273. {
  1274. LONG sessionID;
  1275. sessionID = pLogSession->GetLogSessionID();
  1276. ASSERT(sessionID < MAX_LOG_SESSIONS);
  1277. //
  1278. // Free the ID to be reused
  1279. //
  1280. m_logSessionIDList[sessionID] = FALSE;
  1281. }