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.

1039 lines
27 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. Options Dialog
  5. Abstract:
  6. This class implements the options dialog which sets the
  7. tracing properties
  8. Author:
  9. Marc Reyhner 9/12/2000
  10. --*/
  11. #include "stdafx.h"
  12. #include "OptionsDialog.h"
  13. #include "eZippy.h"
  14. #include "TraceManager.h"
  15. #include "windows.h"
  16. #include "resource.h"
  17. #define MAX_MRU 10
  18. #define MRU_STR_PREFIX _T("PrefixMru")
  19. #define MRU_STR_BUFFER_SIZE 12
  20. COptionsDialog::COptionsDialog(
  21. IN CTraceManager *rTracer
  22. )
  23. /*++
  24. Routine Description:
  25. This just sets the pointer to the trace manager.
  26. Arguments:
  27. rTracer - Pointer to the trace manager class
  28. Return value:
  29. None
  30. --*/
  31. {
  32. m_rTracer = rTracer;
  33. }
  34. VOID
  35. COptionsDialog::DoDialog(
  36. IN HWND hWndParent
  37. )
  38. /*++
  39. Routine Description:
  40. This does the dialog modally. We fill in the fields for the two property
  41. sheet pages and then do the property sheet. When the user hits OK
  42. the pages themselves take care of applying the settings.
  43. Arguments:
  44. hWndParent - Parent window for the dialog
  45. Return value:
  46. None - Since we handle applying the settings within the class
  47. as well as error UI there is no need for a return value.
  48. --*/
  49. {
  50. PROPSHEETPAGE pages[2];
  51. PROPSHEETHEADER psh;
  52. TCHAR caption[MAX_STR_LEN];
  53. // filter tab
  54. pages[0].dwSize = sizeof(PROPSHEETPAGE);
  55. pages[0].dwFlags = PSP_DEFAULT;
  56. pages[0].hInstance = g_hInstance;
  57. pages[0].pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGEFILTER);
  58. pages[0].pfnDlgProc = _FilterDialogProc;
  59. pages[0].lParam = (LPARAM)this;
  60. // trace tab
  61. pages[1].dwSize = sizeof(PROPSHEETPAGE);
  62. pages[1].dwFlags = PSP_DEFAULT;
  63. pages[1].hInstance = g_hInstance;
  64. pages[1].pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGETRACE);
  65. pages[1].pfnDlgProc = _TraceDialogProc;
  66. pages[1].lParam = (LPARAM)this;
  67. // header
  68. psh.dwSize = sizeof(PROPSHEETHEADER);
  69. psh.dwFlags = PSH_NOCONTEXTHELP|PSH_PROPSHEETPAGE|PSH_NOAPPLYNOW;
  70. psh.hwndParent = hWndParent;
  71. psh.hInstance = g_hInstance;
  72. LoadStringSimple(IDS_PREFERENCESDLGTITLE,caption);
  73. psh.pszCaption = caption;
  74. psh.nPages = 2;
  75. psh.nStartPage = 0;
  76. psh.ppsp = pages;
  77. PropertySheet(&psh);
  78. }
  79. INT_PTR CALLBACK
  80. COptionsDialog::_FilterDialogProc(
  81. IN HWND hwndDlg,
  82. IN UINT uMsg,
  83. IN WPARAM wParam,
  84. IN LPARAM lParam
  85. )
  86. /*++
  87. Routine Description:
  88. If this is a WM_INITDIALOG OnCreate is called. Otherwise the non-static
  89. DialogProc function is called.
  90. Arguments:
  91. See win32 DialogProc docs
  92. Return value:
  93. TRUE - Message was handles
  94. FALSE - We did not handle the message
  95. --*/
  96. {
  97. COptionsDialog *rDialog;
  98. if (uMsg == WM_INITDIALOG) {
  99. rDialog = (COptionsDialog*)((LPPROPSHEETPAGE)lParam)->lParam;
  100. SetWindowLongPtr(hwndDlg,GWLP_USERDATA,(LPARAM)rDialog);
  101. return rDialog->OnCreateFilter(hwndDlg);
  102. }
  103. rDialog = (COptionsDialog*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA);
  104. if (!rDialog) {
  105. return FALSE;
  106. }
  107. return rDialog->FilterDialogProc(hwndDlg,uMsg,wParam,lParam);
  108. }
  109. INT_PTR CALLBACK
  110. COptionsDialog::_TraceDialogProc(
  111. IN HWND hwndDlg,
  112. IN UINT uMsg,
  113. IN WPARAM wParam,
  114. IN LPARAM lParam
  115. )
  116. /*++
  117. Routine Description:
  118. If this is a WM_INITDIALOG OnCreate is called. Otherwise the non-static
  119. DialogProc function is called.
  120. Arguments:
  121. See win32 DialogProc docs
  122. Return value:
  123. TRUE - Message was handles
  124. FALSE - We did not handle the message
  125. --*/
  126. {
  127. COptionsDialog *rDialog;
  128. if (uMsg == WM_INITDIALOG) {
  129. rDialog = (COptionsDialog*)((LPPROPSHEETPAGE)lParam)->lParam;
  130. SetWindowLongPtr(hwndDlg,GWLP_USERDATA,(LPARAM)rDialog);
  131. return rDialog->OnCreateTrace(hwndDlg);
  132. }
  133. rDialog = (COptionsDialog*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA);
  134. if (!rDialog) {
  135. return FALSE;
  136. }
  137. return rDialog->TraceDialogProc(hwndDlg,uMsg,wParam,lParam);
  138. }
  139. INT_PTR
  140. COptionsDialog::OnCreateFilter(
  141. IN HWND hWnd
  142. )
  143. /*++
  144. Routine Description:
  145. We populate all the filter dialog fields here.
  146. Arguments:
  147. hWnd - Dialog window
  148. Return value:
  149. FALSE - An error occured. DestroyWindow was called. This should never
  150. happen unless someone hosed the template
  151. TRUE - success in creating everything
  152. --*/
  153. {
  154. TCHAR traceLevelString[MAX_STR_LEN];
  155. UINT traceLevelStringId;
  156. TRC_CONFIG trcConfig;
  157. m_hFilterDlg = hWnd;
  158. if (!m_rTracer->GetCurrentConfig(&trcConfig)) {
  159. DestroyWindow(hWnd);
  160. return FALSE;
  161. }
  162. // Now we set all the fields in the dialog.
  163. // Do the slider
  164. traceLevelStringId = IDS_TRACELEVELDETAILED + trcConfig.traceLevel;
  165. LoadStringSimple(traceLevelStringId,traceLevelString);
  166. SetDlgItemText(hWnd,IDC_FILTERLEVELDESC,traceLevelString);
  167. m_hFilterSliderControl = GetDlgItem(hWnd,IDC_FILTERLEVEL);
  168. if (!m_hFilterSliderControl) {
  169. DestroyWindow(hWnd);
  170. return FALSE;
  171. }
  172. SendDlgItemMessage(hWnd,IDC_FILTERLEVEL,TBM_SETRANGE,TRUE,MAKELONG(TRC_LEVEL_DBG,TRC_LEVEL_DIS));
  173. SendDlgItemMessage(hWnd,IDC_FILTERLEVEL,TBM_SETPOS,TRUE,trcConfig.traceLevel);
  174. // Set the first item of the combo box to the prefix string and then
  175. // select it.
  176. SendDlgItemMessage(m_hFilterDlg,IDC_FILTERPREFIX,CB_ADDSTRING,0,
  177. (LPARAM)trcConfig.prefixList);
  178. SendDlgItemMessage(m_hFilterDlg,IDC_FILTERPREFIX,CB_SETCURSEL,0,0);
  179. // Limit the amount you can enter to the size of the prefix buffer.
  180. SendDlgItemMessage(hWnd,IDC_FILTERPREFIX,EM_LIMITTEXT,TRC_PREFIX_LIST_SIZE-1,0);
  181. // Now set the other items to be the prefix MRU.
  182. LoadPrefixMRU(trcConfig.prefixList);
  183. // The group control stuff
  184. if (trcConfig.components & TRC_GROUP_NETWORK) {
  185. SendDlgItemMessage(hWnd,IDC_GROUPNETWORK,BM_SETCHECK,BST_CHECKED,0);
  186. }
  187. if (trcConfig.components & TRC_GROUP_SECURITY) {
  188. SendDlgItemMessage(hWnd,IDC_GROUPSECURITY,BM_SETCHECK,BST_CHECKED,0);
  189. }
  190. if (trcConfig.components & TRC_GROUP_CORE) {
  191. SendDlgItemMessage(hWnd,IDC_GROUPCORE,BM_SETCHECK,BST_CHECKED,0);
  192. }
  193. if (trcConfig.components & TRC_GROUP_UI) {
  194. SendDlgItemMessage(hWnd,IDC_GROUPUI,BM_SETCHECK,BST_CHECKED,0);
  195. }
  196. if (trcConfig.components & TRC_GROUP_UTILITIES) {
  197. SendDlgItemMessage(hWnd,IDC_GROUPUTILITIES,BM_SETCHECK,BST_CHECKED,0);
  198. }
  199. if (trcConfig.components & TRC_GROUP_UNUSED1) {
  200. SendDlgItemMessage(hWnd,IDC_GROUPUNUSED1,BM_SETCHECK,BST_CHECKED,0);
  201. }
  202. if (trcConfig.components & TRC_GROUP_UNUSED2) {
  203. SendDlgItemMessage(hWnd,IDC_GROUPUNUSED2,BM_SETCHECK,BST_CHECKED,0);
  204. }
  205. if (trcConfig.components & TRC_GROUP_UNUSED3) {
  206. SendDlgItemMessage(hWnd,IDC_GROUPUNUSED3,BM_SETCHECK,BST_CHECKED,0);
  207. }
  208. if (trcConfig.components & TRC_GROUP_UNUSED4) {
  209. SendDlgItemMessage(hWnd,IDC_GROUPUNUSED4,BM_SETCHECK,BST_CHECKED,0);
  210. }
  211. if (trcConfig.components & TRC_GROUP_UNUSED5) {
  212. SendDlgItemMessage(hWnd,IDC_GROUPUNUSED5,BM_SETCHECK,BST_CHECKED,0);
  213. }
  214. return 0;
  215. }
  216. INT_PTR
  217. COptionsDialog::OnCreateTrace(
  218. IN HWND hWnd
  219. )
  220. /*++
  221. Routine Description:
  222. We populate all the trace dialog fields here.
  223. Arguments:
  224. hWnd - Dialog window
  225. Return value:
  226. FALSE - An error occured. DestroyWindow was called. This should never
  227. happen unless someone hosed the template
  228. TRUE - success in creating everything
  229. --*/
  230. {
  231. TRC_CONFIG trcConfig;
  232. // Since the numbers we are outputing are 32bit ints. They can't go over 4 billion
  233. // meaning eleven characters is enough to print a UINT plus a null terminator.
  234. TCHAR numberFormat[11];
  235. // save the window handle
  236. m_hTraceDlg = hWnd;
  237. m_rTracer->GetCurrentConfig(&trcConfig);
  238. if (trcConfig.flags & TRC_OPT_FILE_OUTPUT) {
  239. SendDlgItemMessage(hWnd,IDC_OUTPUT_FILE,BM_SETCHECK,BST_CHECKED,0);
  240. }
  241. if (trcConfig.flags & TRC_OPT_DEBUGGER_OUTPUT) {
  242. SendDlgItemMessage(hWnd,IDC_OUTPUT_DEBUGGER,BM_SETCHECK,BST_CHECKED,0);
  243. }
  244. if (trcConfig.flags & TRC_OPT_BEEP_ON_ERROR) {
  245. SendDlgItemMessage(hWnd,IDC_ERROR_BEEP,BM_SETCHECK,BST_CHECKED,0);
  246. }
  247. if (trcConfig.flags & TRC_OPT_BREAK_ON_ERROR) {
  248. SendDlgItemMessage(hWnd,IDC_ERROR_BREAK,BM_SETCHECK,BST_CHECKED,0);
  249. }
  250. if (trcConfig.flags & TRC_OPT_TIME_STAMP) {
  251. SendDlgItemMessage(hWnd,IDC_OPTION_STAMP,BM_SETCHECK,BST_CHECKED,0);
  252. }
  253. if (trcConfig.flags & TRC_OPT_PROCESS_ID) {
  254. SendDlgItemMessage(hWnd,IDC_OPTION_PROCID,BM_SETCHECK,BST_CHECKED,0);
  255. }
  256. if (trcConfig.flags & TRC_OPT_THREAD_ID) {
  257. SendDlgItemMessage(hWnd,IDC_OPTION_THREAID,BM_SETCHECK,BST_CHECKED,0);
  258. }
  259. if (trcConfig.flags & TRC_OPT_BREAK_ON_ASSERT) {
  260. SendDlgItemMessage(hWnd,IDC_OPTION_BREAKASSERT,BM_SETCHECK,BST_CHECKED,0);
  261. }
  262. // DCUINT32s are defined as u longs hence use %lu for the wsprintf
  263. wsprintf(numberFormat,_T("%lu"),trcConfig.funcNameLength);
  264. SetDlgItemText(hWnd,IDC_FUNCTION_LENGTH,numberFormat);
  265. // Limit the amount you can enter to the size of a ulong
  266. SendDlgItemMessage(hWnd,IDC_FUNCTION_LENGTH,EM_LIMITTEXT,10,0);
  267. wsprintf(numberFormat,_T("%lu"),trcConfig.dataTruncSize);
  268. SetDlgItemText(hWnd,IDC_TRUNCATION_LENGTH,numberFormat);
  269. SendDlgItemMessage(hWnd,IDC_TRUNCATION_LENGTH,EM_LIMITTEXT,10,0);
  270. if (trcConfig.flags & TRC_OPT_PROFILE_TRACING) {
  271. SendDlgItemMessage(hWnd,IDC_OPTION_PROFILE,BM_SETCHECK,BST_CHECKED,0);
  272. }
  273. if (trcConfig.flags & TRC_OPT_FLUSH_ON_TRACE) {
  274. SendDlgItemMessage(hWnd,IDC_OPTION_FLUSH,BM_SETCHECK,BST_CHECKED,0);
  275. }
  276. if (trcConfig.flags & TRC_OPT_STACK_TRACING) {
  277. SendDlgItemMessage(hWnd,IDC_OPTION_STACK,BM_SETCHECK,BST_CHECKED,0);
  278. }
  279. return TRUE;
  280. }
  281. INT_PTR CALLBACK
  282. COptionsDialog::FilterDialogProc(
  283. IN HWND hwndDlg,
  284. IN UINT uMsg,
  285. IN WPARAM wParam,
  286. IN LPARAM lParam
  287. )
  288. /*++
  289. Routine Description:
  290. The FilterDialogProc forwards messages to the appropriate
  291. handlers. See the handlers comments for what they do,
  292. Arguments:
  293. See win32 docs for a DialogProc
  294. Return value:
  295. TRUE - We handled the message
  296. FALSE - We didn't handle the message.
  297. --*/
  298. {
  299. WORD command;
  300. BOOL retValue;
  301. retValue = FALSE;
  302. switch (uMsg) {
  303. case WM_COMMAND:
  304. command = LOWORD(wParam);
  305. switch (command) {
  306. case IDC_SELECTALL:
  307. OnFilterSelectAll();
  308. retValue = TRUE;
  309. break;
  310. case IDC_CLEARALL:
  311. OnFilterClearAll();
  312. retValue = TRUE;
  313. break;
  314. }
  315. break;
  316. case WM_NOTIFY:
  317. if (((LPNMHDR)lParam)->code == PSN_APPLY) {
  318. OnFilterOk();
  319. retValue = TRUE;
  320. }
  321. break;
  322. case WM_HSCROLL:
  323. if ((HWND)lParam == m_hFilterSliderControl) {
  324. OnFilterSliderMove();
  325. retValue = TRUE;
  326. }
  327. break;
  328. }
  329. return retValue;
  330. }
  331. INT_PTR CALLBACK
  332. COptionsDialog::TraceDialogProc(
  333. IN HWND hwndDlg,
  334. IN UINT uMsg,
  335. IN WPARAM wParam,
  336. IN LPARAM lParam
  337. )
  338. /*++
  339. Routine Description:
  340. The TraceDialogProc forwards messages to the appropriate
  341. handlers. See the handlers comments for what they do,
  342. Arguments:
  343. See win32 docs for a DialogProc
  344. Return value:
  345. TRUE - We handled the message
  346. FALSE - We didn't handle the message.
  347. --*/
  348. {
  349. if (uMsg == WM_NOTIFY) {
  350. if (((LPNMHDR)lParam)->code == PSN_APPLY) {
  351. if (!OnTraceOk()) {
  352. // invalid fields from the user
  353. SetWindowLong(hwndDlg,DWLP_MSGRESULT,PSNRET_INVALID);
  354. }
  355. return TRUE;
  356. } else if (((LPNMHDR)lParam)->code == PSN_KILLACTIVE) {
  357. if (!TraceVerifyParameters()) {
  358. SetWindowLong(hwndDlg,DWLP_MSGRESULT,TRUE);
  359. }
  360. return TRUE;
  361. }
  362. }
  363. return FALSE;
  364. }
  365. VOID
  366. COptionsDialog::OnFilterSelectAll(
  367. )
  368. /*++
  369. Routine Description:
  370. This is called when we need to make all the component boxes be checked.
  371. Arguments:
  372. None
  373. Return value:
  374. None
  375. --*/
  376. {
  377. // It might not be perfect coding style but harcoding each set is a lot easier
  378. // than some complicated system constructing an array with the ID of all the buttons.
  379. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPNETWORK,BM_SETCHECK,BST_CHECKED,0);
  380. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPSECURITY,BM_SETCHECK,BST_CHECKED,0);
  381. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPCORE,BM_SETCHECK,BST_CHECKED,0);
  382. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUI,BM_SETCHECK,BST_CHECKED,0);
  383. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUTILITIES,BM_SETCHECK,BST_CHECKED,0);
  384. // If you ever make these groups do something just add the correct items
  385. // in. It looks weird to have the disabled boxes checked so we don't
  386. // do it.
  387. /*
  388. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUNUSED1,BM_SETCHECK,BST_CHECKED,0);
  389. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUNUSED2,BM_SETCHECK,BST_CHECKED,0);
  390. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUNUSED3,BM_SETCHECK,BST_CHECKED,0);
  391. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUNUSED4,BM_SETCHECK,BST_CHECKED,0);
  392. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUNUSED5,BM_SETCHECK,BST_CHECKED,0);
  393. */
  394. }
  395. VOID
  396. COptionsDialog::OnFilterSliderMove(
  397. )
  398. /*++
  399. Routine Description:
  400. This is called whenever the slider is moved. We update the
  401. text to the right of the slider to show the new descriptive
  402. name for the tracing level.
  403. Arguments:
  404. None
  405. Return value:
  406. None
  407. --*/
  408. {
  409. UINT sliderPos;
  410. TCHAR traceLevelString[MAX_STR_LEN];
  411. sliderPos = (UINT)SendMessage(m_hFilterSliderControl,TBM_GETPOS,0,0);
  412. // Set the slider description
  413. LoadStringSimple(IDS_TRACELEVELDETAILED+sliderPos,traceLevelString);
  414. SetDlgItemText(m_hFilterDlg,IDC_FILTERLEVELDESC,traceLevelString);
  415. }
  416. VOID
  417. COptionsDialog::OnFilterClearAll(
  418. )
  419. /*++
  420. Routine Description:
  421. This clears all the component check boxes.
  422. Arguments:
  423. None
  424. Return value:
  425. None
  426. --*/
  427. {
  428. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPNETWORK,BM_SETCHECK,BST_UNCHECKED,0);
  429. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPSECURITY,BM_SETCHECK,BST_UNCHECKED,0);
  430. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPCORE,BM_SETCHECK,BST_UNCHECKED,0);
  431. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUI,BM_SETCHECK,BST_UNCHECKED,0);
  432. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUTILITIES,BM_SETCHECK,BST_UNCHECKED,0);
  433. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUNUSED1,BM_SETCHECK,BST_UNCHECKED,0);
  434. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUNUSED2,BM_SETCHECK,BST_UNCHECKED,0);
  435. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUNUSED3,BM_SETCHECK,BST_UNCHECKED,0);
  436. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUNUSED4,BM_SETCHECK,BST_UNCHECKED,0);
  437. SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUNUSED5,BM_SETCHECK,BST_UNCHECKED,0);
  438. }
  439. VOID COptionsDialog::OnFilterOk(
  440. )
  441. /*++
  442. Routine Description:
  443. This reads in all the dialog parameters and then sets the trace
  444. filtering parameters accordingly.
  445. Arguments:
  446. None
  447. Return value:
  448. None
  449. --*/
  450. {
  451. TRC_CONFIG trcConfig;
  452. m_rTracer->GetCurrentConfig(&trcConfig);
  453. // set the trace level.
  454. trcConfig.traceLevel = (DCUINT32)SendDlgItemMessage(m_hFilterDlg,IDC_FILTERLEVEL,TBM_GETPOS,
  455. 0,0);
  456. // Get the prefix string
  457. GetDlgItemText(m_hFilterDlg,IDC_FILTERPREFIX,trcConfig.prefixList,TRC_PREFIX_LIST_SIZE-1);
  458. // Save the prefix MRU
  459. StorePrefixMRU(trcConfig.prefixList);
  460. // Construct the components variable.
  461. if (BST_CHECKED == SendDlgItemMessage(m_hFilterDlg,IDC_GROUPNETWORK,BM_GETCHECK,0,0)) {
  462. trcConfig.components |= TRC_GROUP_NETWORK;
  463. } else {
  464. trcConfig.components &= ~TRC_GROUP_NETWORK;
  465. }
  466. if (BST_CHECKED == SendDlgItemMessage(m_hFilterDlg,IDC_GROUPSECURITY,BM_GETCHECK,0,0)) {
  467. trcConfig.components |= TRC_GROUP_SECURITY;
  468. } else {
  469. trcConfig.components &= ~TRC_GROUP_SECURITY;
  470. }
  471. if (BST_CHECKED == SendDlgItemMessage(m_hFilterDlg,IDC_GROUPCORE,BM_GETCHECK,0,0)) {
  472. trcConfig.components |= TRC_GROUP_CORE;
  473. } else {
  474. trcConfig.components &= ~TRC_GROUP_CORE;
  475. }
  476. if (BST_CHECKED == SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUI,BM_GETCHECK,0,0)) {
  477. trcConfig.components |= TRC_GROUP_UI;
  478. } else {
  479. trcConfig.components &= ~TRC_GROUP_UI;
  480. }
  481. if (BST_CHECKED == SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUTILITIES,BM_GETCHECK,0,0)) {
  482. trcConfig.components |= TRC_GROUP_UTILITIES;
  483. } else {
  484. trcConfig.components &= ~TRC_GROUP_UTILITIES;
  485. }
  486. if (BST_CHECKED == SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUNUSED1,BM_GETCHECK,0,0)) {
  487. trcConfig.components |= TRC_GROUP_UNUSED1;
  488. } else {
  489. trcConfig.components &= ~TRC_GROUP_UNUSED1;
  490. }
  491. if (BST_CHECKED == SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUNUSED2,BM_GETCHECK,0,0)) {
  492. trcConfig.components |= TRC_GROUP_UNUSED2;
  493. } else {
  494. trcConfig.components &= ~TRC_GROUP_UNUSED2;
  495. }
  496. if (BST_CHECKED == SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUNUSED3,BM_GETCHECK,0,0)) {
  497. trcConfig.components |= TRC_GROUP_UNUSED3;
  498. } else {
  499. trcConfig.components &= ~TRC_GROUP_UNUSED3;
  500. }
  501. if (BST_CHECKED == SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUNUSED4,BM_GETCHECK,0,0)) {
  502. trcConfig.components |= TRC_GROUP_UNUSED4;
  503. } else {
  504. trcConfig.components &= ~TRC_GROUP_UNUSED4;
  505. }
  506. if (BST_CHECKED == SendDlgItemMessage(m_hFilterDlg,IDC_GROUPUNUSED5,BM_GETCHECK,0,0)) {
  507. trcConfig.components |= TRC_GROUP_UNUSED5;
  508. } else {
  509. trcConfig.components &= ~TRC_GROUP_UNUSED5;
  510. }
  511. m_rTracer->SetCurrentConfig(&trcConfig);
  512. }
  513. BOOL COptionsDialog::OnTraceOk(
  514. )
  515. /*++
  516. Routine Description:
  517. This reads in all the dialog parameters and then sets the trace
  518. parameters accordingly.
  519. Arguments:
  520. None
  521. Return value:
  522. TRUE - Success in setting the conf.
  523. FALSE - The user entered invalid data so the dialog should not be closed.
  524. --*/
  525. {
  526. TRC_CONFIG trcConfig;
  527. // again enough to hold a string representing a ulong.
  528. TCHAR numberFormat[11];
  529. m_rTracer->GetCurrentConfig(&trcConfig);
  530. if (BST_CHECKED == SendDlgItemMessage(m_hTraceDlg,IDC_OUTPUT_FILE,BM_GETCHECK,0,0)) {
  531. trcConfig.flags |= TRC_OPT_FILE_OUTPUT;
  532. } else {
  533. trcConfig.flags &= ~TRC_OPT_FILE_OUTPUT;
  534. }
  535. if (BST_CHECKED == SendDlgItemMessage(m_hTraceDlg,IDC_OUTPUT_DEBUGGER,BM_GETCHECK,0,0)) {
  536. trcConfig.flags |= TRC_OPT_DEBUGGER_OUTPUT;
  537. } else {
  538. trcConfig.flags &= ~TRC_OPT_DEBUGGER_OUTPUT;
  539. }
  540. if (BST_CHECKED == SendDlgItemMessage(m_hTraceDlg,IDC_ERROR_BEEP,BM_GETCHECK,0,0)) {
  541. trcConfig.flags |= TRC_OPT_BEEP_ON_ERROR;
  542. } else {
  543. trcConfig.flags &= ~TRC_OPT_BEEP_ON_ERROR;
  544. }
  545. if (BST_CHECKED == SendDlgItemMessage(m_hTraceDlg,IDC_ERROR_BREAK,BM_GETCHECK,0,0)) {
  546. trcConfig.flags |= TRC_OPT_BREAK_ON_ERROR;
  547. } else {
  548. trcConfig.flags &= ~TRC_OPT_BREAK_ON_ERROR;
  549. }
  550. if (BST_CHECKED == SendDlgItemMessage(m_hTraceDlg,IDC_OPTION_STAMP,BM_GETCHECK,0,0)) {
  551. trcConfig.flags |= TRC_OPT_TIME_STAMP;
  552. } else {
  553. trcConfig.flags &= ~TRC_OPT_TIME_STAMP;
  554. }
  555. if (BST_CHECKED == SendDlgItemMessage(m_hTraceDlg,IDC_OPTION_PROCID,BM_GETCHECK,0,0)) {
  556. trcConfig.flags |= TRC_OPT_PROCESS_ID;
  557. } else {
  558. trcConfig.flags &= ~TRC_OPT_PROCESS_ID;
  559. }
  560. if (BST_CHECKED == SendDlgItemMessage(m_hTraceDlg,IDC_OPTION_THREAID,BM_GETCHECK,0,0)) {
  561. trcConfig.flags |= TRC_OPT_THREAD_ID;
  562. } else {
  563. trcConfig.flags &= ~TRC_OPT_THREAD_ID;
  564. }
  565. if (BST_CHECKED == SendDlgItemMessage(m_hTraceDlg,IDC_OPTION_BREAKASSERT,BM_GETCHECK,0,0)) {
  566. trcConfig.flags |= TRC_OPT_BREAK_ON_ASSERT;
  567. } else {
  568. trcConfig.flags &= ~TRC_OPT_BREAK_ON_ASSERT;
  569. }
  570. GetDlgItemText(m_hTraceDlg,IDC_FUNCTION_LENGTH,numberFormat,10);
  571. if (!VerifyNumberFormat(numberFormat)) {
  572. return FALSE;
  573. }
  574. trcConfig.funcNameLength = _ttol(numberFormat);
  575. GetDlgItemText(m_hTraceDlg,IDC_TRUNCATION_LENGTH,numberFormat,10);
  576. if (!VerifyNumberFormat(numberFormat)) {
  577. return FALSE;
  578. }
  579. trcConfig.dataTruncSize = _ttol(numberFormat);
  580. if (BST_CHECKED == SendDlgItemMessage(m_hTraceDlg,IDC_OPTION_PROFILE,BM_GETCHECK,0,0)) {
  581. trcConfig.flags |= TRC_OPT_PROFILE_TRACING;
  582. } else {
  583. trcConfig.flags &= ~TRC_OPT_PROFILE_TRACING;
  584. }
  585. if (BST_CHECKED == SendDlgItemMessage(m_hTraceDlg,IDC_OPTION_FLUSH,BM_GETCHECK,0,0)) {
  586. trcConfig.flags |= TRC_OPT_FLUSH_ON_TRACE;
  587. } else {
  588. trcConfig.flags &= ~TRC_OPT_FLUSH_ON_TRACE;
  589. }
  590. if (BST_CHECKED == SendDlgItemMessage(m_hTraceDlg,IDC_OPTION_STACK,BM_GETCHECK,0,0)) {
  591. trcConfig.flags |= TRC_OPT_STACK_TRACING;
  592. } else {
  593. trcConfig.flags &= ~TRC_OPT_STACK_TRACING;
  594. }
  595. m_rTracer->SetCurrentConfig(&trcConfig);
  596. return TRUE;
  597. }
  598. BOOL
  599. COptionsDialog::VerifyNumberFormat(
  600. IN LPCTSTR numberFormat
  601. )
  602. /*++
  603. Routine Description:
  604. This checks to make sure the passed in string is in the form
  605. /^\d*$/. If not a dialog box is popped up telling the user
  606. that the string must be a valid postive number.
  607. Arguments:
  608. numberFormat - String to check if it is a number string
  609. Return value:
  610. TRUE - The string only containts the characters 0-9
  611. FALSE - The string has illegal characters.
  612. --*/
  613. {
  614. WCHAR current;
  615. TCHAR dlgTitle[MAX_STR_LEN];
  616. TCHAR dlgMessage[MAX_STR_LEN];
  617. while (current = *(numberFormat++)) {
  618. if (!_istdigit(current)) {
  619. LoadStringSimple(IDS_SETTINGSNOTNUMBER,dlgMessage);
  620. LoadStringSimple(IDS_ZIPPYWINDOWTITLE,dlgTitle);
  621. MessageBox(m_hTraceDlg,dlgMessage,dlgTitle,MB_OK|MB_ICONWARNING);
  622. return FALSE;
  623. }
  624. }
  625. return TRUE;
  626. }
  627. BOOL
  628. COptionsDialog::TraceVerifyParameters(
  629. )
  630. /*++
  631. Routine Description:
  632. Makes sure the trace parameters are valid
  633. Arguments:
  634. None
  635. Return value:
  636. TRUE - Trace parameters are valid.
  637. FALSE - Trace parameters are invalid.
  638. --*/
  639. {
  640. TCHAR numberFormat[11];
  641. GetDlgItemText(m_hTraceDlg,IDC_FUNCTION_LENGTH,numberFormat,10);
  642. if (!VerifyNumberFormat(numberFormat)) {
  643. return FALSE;
  644. }
  645. GetDlgItemText(m_hTraceDlg,IDC_TRUNCATION_LENGTH,numberFormat,10);
  646. if (!VerifyNumberFormat(numberFormat)) {
  647. return FALSE;
  648. }
  649. return TRUE;
  650. }
  651. VOID
  652. COptionsDialog::LoadPrefixMRU(
  653. IN LPCTSTR currentPrefix
  654. )
  655. /*++
  656. Routine Description:
  657. This loads the prefix MRU list into the prefix
  658. combo box.
  659. Arguments:
  660. currentPrefix - The current selected prefix
  661. Return value:
  662. None
  663. --*/
  664. {
  665. TCHAR prefix[TRC_PREFIX_LIST_SIZE];
  666. TCHAR valueName[MRU_STR_BUFFER_SIZE];
  667. HKEY hKey;
  668. INT i;
  669. DWORD dwSize;
  670. DWORD dwType;
  671. DWORD dwResult;
  672. dwResult = RegOpenKeyEx(HKEY_CURRENT_USER,ZIPPY_REG_KEY,0,KEY_QUERY_VALUE,
  673. &hKey);
  674. if (dwResult) {
  675. // error opening reg key return
  676. return;
  677. }
  678. for (i=0;i<MAX_MRU;i++) {
  679. wsprintf(valueName,_T("%s%d"),MRU_STR_PREFIX,i);
  680. dwSize = sizeof(TCHAR)*TRC_PREFIX_LIST_SIZE;
  681. dwResult = RegQueryValueEx(hKey,valueName,NULL,&dwType,(LPBYTE)prefix,
  682. &dwSize);
  683. if (dwResult) {
  684. // if there is an error loading a value then quit
  685. break;
  686. } else if (0 == _tcsicmp(prefix,currentPrefix)) {
  687. // if the MRU item is the same as the current don't display it
  688. continue;
  689. }
  690. SendDlgItemMessage(m_hFilterDlg,IDC_FILTERPREFIX,CB_ADDSTRING,0,
  691. (LPARAM)prefix);
  692. }
  693. RegCloseKey(hKey);
  694. }
  695. VOID
  696. COptionsDialog::StorePrefixMRU(
  697. IN LPCTSTR currentPrefix
  698. )
  699. /*++
  700. Routine Description:
  701. This updates the registry MRU list to put
  702. the new prefix at the head of the list.
  703. Arguments:
  704. currentPrefix - The current selected prefix
  705. Return value:
  706. None
  707. --*/
  708. {
  709. HKEY hKey;
  710. TCHAR savedMruPrefix[TRC_PREFIX_LIST_SIZE];
  711. TCHAR newMruPrefix[TRC_PREFIX_LIST_SIZE];
  712. TCHAR currentLoadName[MRU_STR_BUFFER_SIZE];
  713. TCHAR currentSaveName[MRU_STR_BUFFER_SIZE];
  714. INT loadIndex;
  715. INT saveIndex;
  716. DWORD dwSize;
  717. DWORD dwType;
  718. DWORD dwResult;
  719. dwResult = RegOpenKeyEx(HKEY_CURRENT_USER,ZIPPY_REG_KEY,0,
  720. KEY_QUERY_VALUE|KEY_SET_VALUE,&hKey);
  721. if (dwResult) {
  722. // error opening reg key return
  723. return;
  724. }
  725. // The new currentPrefix is the first item in the MRU list
  726. _tcscpy(newMruPrefix,currentPrefix);
  727. for (loadIndex=0,saveIndex=0;loadIndex<MAX_MRU;loadIndex++) {
  728. wsprintf(currentLoadName,_T("%s%d"),MRU_STR_PREFIX,loadIndex);
  729. wsprintf(currentSaveName,_T("%s%d"),MRU_STR_PREFIX,saveIndex);
  730. dwSize = sizeof(TCHAR)*TRC_PREFIX_LIST_SIZE;
  731. dwResult = RegQueryValueEx(hKey,currentLoadName,NULL,&dwType,
  732. (LPBYTE)savedMruPrefix,&dwSize);
  733. if (dwResult) {
  734. // no more valid keys. Write out the current and exit.
  735. RegSetValueEx(hKey,currentLoadName,0,REG_SZ,(LPBYTE)newMruPrefix,sizeof(TCHAR) *
  736. (_tcslen(newMruPrefix)+1));
  737. break;
  738. } else if (0 == _tcsicmp(savedMruPrefix,currentPrefix)) {
  739. // if this MRU is the same as the currentPrefix we already have saved it.
  740. // so we will advance i and leave the currentMru the same
  741. if (loadIndex == MAX_MRU-1) {
  742. // If this is the last MRU to load then we need to save
  743. RegSetValueEx(hKey,currentSaveName,0,REG_SZ,(LPBYTE)newMruPrefix,sizeof(TCHAR) *
  744. (_tcslen(newMruPrefix)+1));
  745. }
  746. continue;
  747. } else {
  748. // we are going to save in this position so advance the index
  749. saveIndex++;
  750. }
  751. RegSetValueEx(hKey,currentSaveName,0,REG_SZ,(LPBYTE)newMruPrefix,sizeof(TCHAR) *
  752. (_tcslen(newMruPrefix)+1));
  753. _tcscpy(newMruPrefix,savedMruPrefix);
  754. }
  755. RegCloseKey(hKey);
  756. }