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.

871 lines
24 KiB

  1. /*++
  2. Copyright (c) 1993-2001 Microsoft Corporation
  3. Module Name:
  4. ui.cpp
  5. Abstract:
  6. This function implements the ui (dialog) that controls the
  7. options maintenace for drwatson.
  8. Author:
  9. Wesley Witt (wesw) 1-May-1993
  10. Environment:
  11. User Mode
  12. --*/
  13. #include "pch.cpp"
  14. void
  15. InitializeDialog(
  16. HWND hwnd
  17. );
  18. void
  19. InitializeCrashList(
  20. HWND hwnd
  21. );
  22. BOOL
  23. GetDialogValues(
  24. HWND hwnd
  25. );
  26. INT_PTR
  27. CALLBACK
  28. LogFileViewerDialogProc(
  29. HWND hwnd,
  30. UINT message,
  31. WPARAM wParam,
  32. LPARAM lParam
  33. );
  34. INT_PTR
  35. CALLBACK
  36. DrWatsonDialogProc (
  37. HWND hwnd,
  38. UINT message,
  39. WPARAM wParam,
  40. LPARAM lParam
  41. );
  42. PTSTR
  43. ExpandPath(
  44. PTSTR lpPath
  45. );
  46. const
  47. DWORD
  48. DrWatsonHelpIds[] = {
  49. ID_LOGPATH_TEXT, IDH_LOG_FILE_PATH,
  50. ID_LOGPATH, IDH_LOG_FILE_PATH,
  51. ID_BROWSE_LOGPATH, IDH_BROWSE,
  52. ID_CRASH_DUMP_TEXT, IDH_CRASH_DUMP,
  53. ID_CRASH_DUMP, IDH_CRASH_DUMP,
  54. ID_BROWSE_CRASH, IDH_BROWSE,
  55. ID_WAVEFILE_TEXT, IDH_WAVE_FILE,
  56. ID_WAVE_FILE, IDH_WAVE_FILE,
  57. ID_BROWSE_WAVEFILE, IDH_BROWSE,
  58. ID_INSTRUCTIONS, IDH_NUMBER_OF_INSTRUCTIONS,
  59. ID_NUM_CRASHES, IDH_NUMBER_OF_ERRORS_TO_SAVE,
  60. ID_DUMPSYMBOLS, IDH_DUMP_SYMBOL_TABLE,
  61. ID_DUMPALLTHREADS, IDH_DUMP_ALL_THREAD_CONTEXTS,
  62. ID_APPENDTOLOGFILE, IDH_APPEND_TO_EXISTING_LOGFILE,
  63. ID_VISUAL, IDH_VISUAL_NOTIFICATION,
  64. ID_SOUND, IDH_SOUND_NOTIFICATION,
  65. ID_CRASH, IDH_CREATE_CRASH_DUMP_FILE,
  66. ID_LOGFILE_VIEW, IDH_VIEW,
  67. ID_CLEAR, IDH_CLEAR,
  68. ID_CRASHES, IDH_APPLICATION_ERRORS,
  69. ID_TEST_WAVE, IDH_WAVE_FILE,
  70. psh15, IDH_INDEX,
  71. 0, 0
  72. };
  73. void
  74. DrWatsonWinMain(
  75. void
  76. )
  77. /*++
  78. Routine Description:
  79. This is the entry point for DRWTSN32
  80. Arguments:
  81. None.
  82. Return Value:
  83. None.
  84. --*/
  85. {
  86. HWND hwnd;
  87. MSG msg;
  88. HINSTANCE hInst;
  89. WNDCLASS wndclass;
  90. hInst = GetModuleHandle( NULL );
  91. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  92. wndclass.lpfnWndProc = (WNDPROC)DrWatsonDialogProc;
  93. wndclass.cbClsExtra = 0;
  94. wndclass.cbWndExtra = DLGWINDOWEXTRA;
  95. wndclass.hInstance = hInst;
  96. wndclass.hIcon = LoadIcon( hInst, MAKEINTRESOURCE(APPICON) );
  97. wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
  98. wndclass.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1);
  99. wndclass.lpszMenuName = NULL;
  100. wndclass.lpszClassName = _T("DrWatsonDialog");
  101. RegisterClass( &wndclass );
  102. hwnd = CreateDialog( hInst,
  103. MAKEINTRESOURCE( DRWATSONDIALOG ),
  104. 0,
  105. DrWatsonDialogProc
  106. );
  107. if (hwnd == NULL) {
  108. return;
  109. }
  110. ShowWindow( hwnd, SW_SHOWNORMAL );
  111. while (GetMessage (&msg, NULL, 0, 0)) {
  112. if (!IsDialogMessage( hwnd, &msg )) {
  113. TranslateMessage (&msg) ;
  114. DispatchMessage (&msg) ;
  115. }
  116. }
  117. return;
  118. }
  119. INT_PTR
  120. CALLBACK
  121. DrWatsonDialogProc (
  122. HWND hwnd,
  123. UINT message,
  124. WPARAM wParam,
  125. LPARAM lParam
  126. )
  127. /*++
  128. Routine Description:
  129. Window procedure for the DRWTSN32.EXE main user interface.
  130. Arguments:
  131. hwnd - window handle to the dialog box
  132. message - message number
  133. wParam - first message parameter
  134. lParam - second message parameter
  135. Return Value:
  136. TRUE - did not process the message
  137. FALSE - did process the message
  138. --*/
  139. {
  140. DWORD helpId;
  141. DWORD ctlId;
  142. UINT Checked;
  143. _TCHAR szCurrDir[MAX_PATH];
  144. _TCHAR szWave[MAX_PATH];
  145. _TCHAR szDump[MAX_PATH];
  146. _TCHAR szHelpFileName[MAX_PATH];
  147. PTSTR p;
  148. PDWORD pdw;
  149. switch (message) {
  150. case WM_CREATE:
  151. return 0;
  152. case WM_INITDIALOG:
  153. SubclassControls( hwnd );
  154. InitializeDialog( hwnd );
  155. return 1;
  156. case WM_HELP: // F1 key and ?
  157. ctlId = ((LPHELPINFO)lParam)->iCtrlId;
  158. helpId = IDH_INDEX;
  159. for (pdw = (PDWORD)DrWatsonHelpIds; *pdw; pdw+=2) {
  160. if (*pdw == ctlId) {
  161. helpId = pdw[1];
  162. break;
  163. }
  164. }
  165. if ( helpId == IDH_BROWSE ) {
  166. _tcscpy( szHelpFileName, _T("windows.hlp") );
  167. }
  168. else {
  169. GetWinHelpFileName( szHelpFileName,
  170. sizeof(szHelpFileName) / sizeof(_TCHAR) );
  171. }
  172. WinHelp( (HWND)((LPHELPINFO) lParam)->hItemHandle,
  173. szHelpFileName,
  174. HELP_WM_HELP,
  175. (DWORD_PTR)(LPVOID)DrWatsonHelpIds );
  176. return TRUE;
  177. case WM_CONTEXTMENU: // right mouse click
  178. if( hwnd == (HWND) wParam ) {
  179. POINT pt;
  180. GetCursorPos(&pt);
  181. ScreenToClient(hwnd, &pt);
  182. wParam = (WPARAM) ChildWindowFromPoint(hwnd, pt);
  183. }
  184. ctlId = GetDlgCtrlID((HWND)wParam);
  185. helpId = IDH_INDEX;
  186. for (pdw = (PDWORD)DrWatsonHelpIds; *pdw; pdw+=2) {
  187. if (*pdw == ctlId) {
  188. helpId = pdw[1];
  189. break;
  190. }
  191. }
  192. if ( helpId == IDH_BROWSE ) {
  193. _tcscpy( szHelpFileName, _T("windows.hlp") );
  194. }
  195. else {
  196. GetWinHelpFileName( szHelpFileName,
  197. sizeof(szHelpFileName) / sizeof(_TCHAR) );
  198. }
  199. WinHelp((HWND)wParam,
  200. szHelpFileName,
  201. HELP_CONTEXTMENU,
  202. (DWORD_PTR)DrWatsonHelpIds
  203. );
  204. return TRUE;
  205. case WM_ACTIVATEAPP:
  206. case WM_SETFOCUS:
  207. SetFocusToCurrentControl();
  208. return 0;
  209. case WM_SYSCOMMAND:
  210. if (wParam == ID_ABOUT) {
  211. _TCHAR title[256];
  212. _TCHAR extra[256];
  213. _tcscpy( title, LoadRcString( IDS_ABOUT_TITLE ) );
  214. _tcscpy( extra, LoadRcString( IDS_ABOUT_EXTRA ) );
  215. ShellAbout( hwnd,
  216. title,
  217. extra,
  218. LoadIcon( GetModuleHandle(NULL), MAKEINTRESOURCE(APPICON) )
  219. );
  220. return 0;
  221. }
  222. break;
  223. case WM_COMMAND:
  224. switch (wParam) {
  225. case IDOK:
  226. if (GetDialogValues( hwnd )) {
  227. HtmlHelp( NULL, NULL, HH_CLOSE_ALL, 0);
  228. PostQuitMessage( 0 );
  229. }
  230. break;
  231. case IDCANCEL:
  232. HtmlHelp( NULL, NULL, HH_CLOSE_ALL, 0);
  233. PostQuitMessage( 0 );
  234. break;
  235. case ID_BROWSE_LOGPATH:
  236. GetDlgItemText( hwnd, ID_LOGPATH, szCurrDir, MAX_PATH );
  237. p = ExpandPath( szCurrDir );
  238. if (p) {
  239. _tcscpy( szCurrDir, p );
  240. free( p );
  241. }
  242. EnableWindow( GetDlgItem( hwnd, ID_BROWSE_LOGPATH ), FALSE );
  243. if (BrowseForDirectory(hwnd, szCurrDir )) {
  244. SetDlgItemText( hwnd, ID_LOGPATH, szCurrDir );
  245. }
  246. EnableWindow( GetDlgItem( hwnd, ID_BROWSE_LOGPATH ), TRUE );
  247. SetFocus( GetDlgItem(hwnd, ID_BROWSE_LOGPATH) );
  248. return FALSE;
  249. break;
  250. case ID_BROWSE_WAVEFILE:
  251. szWave[0] = _T('\0');
  252. GetDlgItemText( hwnd, ID_WAVE_FILE, szWave, MAX_PATH );
  253. EnableWindow( GetDlgItem( hwnd, ID_BROWSE_WAVEFILE ), FALSE );
  254. if (GetWaveFileName(hwnd, szWave )) {
  255. SetDlgItemText( hwnd, ID_WAVE_FILE, szWave );
  256. }
  257. EnableWindow( GetDlgItem( hwnd, ID_BROWSE_WAVEFILE ), TRUE );
  258. SetFocus( GetDlgItem(hwnd, ID_BROWSE_WAVEFILE) );
  259. return FALSE;
  260. break;
  261. case ID_BROWSE_CRASH:
  262. szDump[0] = _T('\0');
  263. GetDlgItemText( hwnd, ID_CRASH_DUMP, szDump, MAX_PATH );
  264. EnableWindow( GetDlgItem( hwnd, ID_BROWSE_CRASH ), FALSE );
  265. if (GetDumpFileName(hwnd, szDump )) {
  266. SetDlgItemText( hwnd, ID_CRASH_DUMP, szDump );
  267. }
  268. EnableWindow( GetDlgItem( hwnd, ID_BROWSE_CRASH ), TRUE );
  269. SetFocus( GetDlgItem(hwnd, ID_BROWSE_CRASH) );
  270. return FALSE;
  271. break;
  272. case ID_CLEAR:
  273. ElClearAllEvents();
  274. InitializeCrashList( hwnd );
  275. break;
  276. case ID_TEST_WAVE:
  277. GetDlgItemText( hwnd, ID_WAVE_FILE, szWave, sizeof(szWave) / sizeof(_TCHAR) );
  278. PlaySound( szWave, NULL, SND_FILENAME );
  279. break;
  280. case ID_LOGFILE_VIEW:
  281. DialogBoxParam( GetModuleHandle( NULL ),
  282. MAKEINTRESOURCE( LOGFILEVIEWERDIALOG ),
  283. hwnd,
  284. LogFileViewerDialogProc,
  285. SendMessage((HWND)GetDlgItem(hwnd,ID_CRASHES),
  286. LB_GETCURSEL,0,0)
  287. );
  288. break;
  289. case IDHELP:
  290. //
  291. // call HtmlHelp
  292. //
  293. GetHtmlHelpFileName( szHelpFileName, sizeof(szHelpFileName) / sizeof(_TCHAR) );
  294. HtmlHelp( hwnd,
  295. szHelpFileName,
  296. HH_DISPLAY_TOPIC,
  297. (DWORD_PTR)(IDHH_INDEX)
  298. );
  299. SetFocus( GetDlgItem(hwnd, IDHELP) );
  300. break;
  301. default:
  302. if (((HWND)lParam == GetDlgItem( hwnd, ID_CRASHES )) &&
  303. (HIWORD( wParam ) == LBN_DBLCLK)) {
  304. DialogBoxParam( GetModuleHandle( NULL ),
  305. MAKEINTRESOURCE( LOGFILEVIEWERDIALOG ),
  306. hwnd,
  307. LogFileViewerDialogProc,
  308. SendMessage((HWND)lParam,LB_GETCURSEL,0,0)
  309. );
  310. }
  311. if (((HWND)lParam == GetDlgItem( hwnd, ID_CRASH )) &&
  312. (HIWORD( wParam ) == BN_CLICKED)) {
  313. Checked = IsDlgButtonChecked( hwnd, ID_CRASH );
  314. EnableWindow( GetDlgItem( hwnd, ID_CRASH_DUMP_TEXT ), Checked == 1 );
  315. EnableWindow( GetDlgItem( hwnd, ID_CRASH_DUMP ), Checked == 1 );
  316. EnableWindow( GetDlgItem( hwnd, ID_BROWSE_CRASH ), Checked == 1 );
  317. EnableWindow( GetDlgItem( hwnd, ID_DUMP_TYPE_TEXT ), Checked == 1 );
  318. EnableWindow( GetDlgItem( hwnd, ID_DUMP_TYPE_FULL_OLD ), Checked == 1 );
  319. EnableWindow( GetDlgItem( hwnd, ID_DUMP_TYPE_MINI ), Checked == 1 );
  320. EnableWindow( GetDlgItem( hwnd, ID_DUMP_TYPE_FULLMINI ), Checked == 1 );
  321. }
  322. if (((HWND)lParam == GetDlgItem( hwnd, ID_SOUND )) &&
  323. (HIWORD( wParam ) == BN_CLICKED)) {
  324. Checked = IsDlgButtonChecked( hwnd, ID_SOUND );
  325. EnableWindow( GetDlgItem( hwnd, ID_WAVEFILE_TEXT ), Checked == 1 );
  326. EnableWindow( GetDlgItem( hwnd, ID_WAVE_FILE ), Checked == 1 );
  327. EnableWindow( GetDlgItem( hwnd, ID_BROWSE_WAVEFILE ), Checked == 1 );
  328. }
  329. break;
  330. }
  331. break;
  332. case IDH_WAVE_FILE:
  333. //
  334. // call HtmlHelp
  335. //
  336. GetHtmlHelpFileName( szHelpFileName, sizeof(szHelpFileName) / sizeof(_TCHAR) );
  337. HtmlHelp(hwnd,
  338. szHelpFileName,
  339. HH_DISPLAY_TOPIC,
  340. (DWORD_PTR)(IDHH_WAVEFILE)
  341. );
  342. break;
  343. case IDH_CRASH_DUMP:
  344. //
  345. // call HtmlHelp
  346. //
  347. GetHtmlHelpFileName( szHelpFileName, sizeof(szHelpFileName) / sizeof(_TCHAR) );
  348. HtmlHelp( hwnd,
  349. szHelpFileName,
  350. HH_DISPLAY_TOPIC,
  351. (DWORD_PTR)(IDHH_LOGFILELOCATION)
  352. );
  353. break;
  354. case WM_DESTROY:
  355. HtmlHelp( NULL, NULL, HH_CLOSE_ALL, 0);
  356. PostQuitMessage( 0 );
  357. return 0;
  358. }
  359. return DefWindowProc( hwnd, message, wParam, lParam );
  360. }
  361. BOOL
  362. CALLBACK
  363. EnumCrashes(
  364. PCRASHINFO crashInfo
  365. )
  366. /*++
  367. Routine Description:
  368. Enumeration function for crash records. This function is called
  369. once for each crash record. This function places the formatted
  370. crash data in a listbox.
  371. Arguments:
  372. crashInfo - pointer to a CRASHINFO structure
  373. Return Value:
  374. TRUE - caller should continue calling the enum procedure
  375. FALSE - caller should stop calling the enum procedure
  376. --*/
  377. {
  378. SIZE size;
  379. _TCHAR buf[1024];
  380. _stprintf( buf, _T("%s %08x %s(%08p)"),
  381. crashInfo->crash.szAppName,
  382. crashInfo->crash.dwExceptionCode,
  383. crashInfo->crash.szFunction,
  384. crashInfo->crash.dwAddress
  385. );
  386. SendMessage( crashInfo->hList, LB_ADDSTRING, 0, (LPARAM)buf );
  387. GetTextExtentPoint( crashInfo->hdc, buf, _tcslen(buf), &size );
  388. if (size.cx > (LONG)crashInfo->cxExtent) {
  389. crashInfo->cxExtent = size.cx;
  390. }
  391. return TRUE;
  392. }
  393. void
  394. InitializeCrashList(
  395. HWND hwnd
  396. )
  397. /*++
  398. Routine Description:
  399. Initializes the listbox that contains the crash information.
  400. Arguments:
  401. None.
  402. Return Value:
  403. None.
  404. --*/
  405. {
  406. CRASHINFO crashInfo;
  407. TEXTMETRIC tm;
  408. HFONT hFont;
  409. crashInfo.hList = GetDlgItem( hwnd, ID_CRASHES );
  410. SendMessage( crashInfo.hList, LB_RESETCONTENT, FALSE, 0L );
  411. SendMessage( crashInfo.hList, WM_SETREDRAW, FALSE, 0L );
  412. crashInfo.hdc = GetDC( crashInfo.hList );
  413. crashInfo.cxExtent = 0;
  414. ElEnumCrashes( &crashInfo, EnumCrashes );
  415. hFont = (HFONT)SendMessage( crashInfo.hList, WM_GETFONT, 0, 0L );
  416. if (hFont != NULL) {
  417. SelectObject( crashInfo.hdc, hFont );
  418. }
  419. if (crashInfo.hdc != NULL) {
  420. GetTextMetrics( crashInfo.hdc, &tm );
  421. ReleaseDC( crashInfo.hList, crashInfo.hdc );
  422. }
  423. SendMessage( crashInfo.hList, LB_SETHORIZONTALEXTENT, crashInfo.cxExtent, 0L );
  424. SendMessage( crashInfo.hList, WM_SETREDRAW, TRUE, 0L );
  425. return;
  426. }
  427. void
  428. InitializeDialog(
  429. HWND hwnd
  430. )
  431. /*++
  432. Routine Description:
  433. Initializes the DRWTSN32 user interface dialog with the values
  434. stored in the registry.
  435. Arguments:
  436. hwnd - window handle to the dialog
  437. Return Value:
  438. None.
  439. --*/
  440. {
  441. OPTIONS o;
  442. _TCHAR buf[256];
  443. HMENU hMenu;
  444. RegInitialize( &o );
  445. SetDlgItemText( hwnd, ID_LOGPATH, o.szLogPath );
  446. SetDlgItemText( hwnd, ID_WAVE_FILE, o.szWaveFile );
  447. SetDlgItemText( hwnd, ID_CRASH_DUMP, o.szCrashDump );
  448. _stprintf( buf, _T("%d"), o.dwMaxCrashes );
  449. SetDlgItemText( hwnd, ID_NUM_CRASHES, buf );
  450. _stprintf( buf, _T("%d"), o.dwInstructions );
  451. SetDlgItemText( hwnd, ID_INSTRUCTIONS, buf );
  452. SendMessage( GetDlgItem( hwnd, ID_DUMPSYMBOLS ), BM_SETCHECK, o.fDumpSymbols, 0 );
  453. SendMessage( GetDlgItem( hwnd, ID_DUMPALLTHREADS ), BM_SETCHECK, o.fDumpAllThreads, 0 );
  454. SendMessage( GetDlgItem( hwnd, ID_APPENDTOLOGFILE ), BM_SETCHECK, o.fAppendToLogFile, 0 );
  455. SendMessage( GetDlgItem( hwnd, ID_VISUAL ), BM_SETCHECK, o.fVisual, 0 );
  456. SendMessage( GetDlgItem( hwnd, ID_SOUND ), BM_SETCHECK, o.fSound, 0 );
  457. SendMessage( GetDlgItem( hwnd, ID_CRASH ), BM_SETCHECK, o.fCrash, 0 );
  458. SendMessage( GetDlgItem( hwnd, ID_DUMP_TYPE_FULL_OLD ), BM_SETCHECK, o.dwType == FullDump, 0 );
  459. SendMessage( GetDlgItem( hwnd, ID_DUMP_TYPE_MINI ), BM_SETCHECK, o.dwType == MiniDump, 0 );
  460. SendMessage( GetDlgItem( hwnd, ID_DUMP_TYPE_FULLMINI ), BM_SETCHECK, o.dwType == FullMiniDump, 0 );
  461. if (waveOutGetNumDevs() == 0) {
  462. EnableWindow( GetDlgItem( hwnd, ID_WAVEFILE_TEXT ), FALSE );
  463. EnableWindow( GetDlgItem( hwnd, ID_WAVE_FILE ), FALSE );
  464. EnableWindow( GetDlgItem( hwnd, ID_BROWSE_WAVEFILE ), FALSE );
  465. }
  466. else {
  467. EnableWindow( GetDlgItem( hwnd, ID_WAVEFILE_TEXT ), o.fSound );
  468. EnableWindow( GetDlgItem( hwnd, ID_WAVE_FILE ), o.fSound );
  469. EnableWindow( GetDlgItem( hwnd, ID_BROWSE_WAVEFILE ), o.fSound );
  470. }
  471. EnableWindow( GetDlgItem( hwnd, ID_CRASH_DUMP_TEXT ), o.fCrash );
  472. EnableWindow( GetDlgItem( hwnd, ID_CRASH_DUMP ), o.fCrash );
  473. EnableWindow( GetDlgItem( hwnd, ID_BROWSE_CRASH ), o.fCrash );
  474. EnableWindow( GetDlgItem( hwnd, ID_DUMP_TYPE_TEXT ), o.fCrash );
  475. EnableWindow( GetDlgItem( hwnd, ID_DUMP_TYPE_FULL_OLD ), o.fCrash );
  476. EnableWindow( GetDlgItem( hwnd, ID_DUMP_TYPE_MINI ), o.fCrash );
  477. EnableWindow( GetDlgItem( hwnd, ID_DUMP_TYPE_FULLMINI ), o.fCrash );
  478. InitializeCrashList( hwnd );
  479. if (SendMessage( GetDlgItem( hwnd, ID_CRASHES ), LB_GETCOUNT, 0 ,0 ) == 0) {
  480. EnableWindow( GetDlgItem( hwnd, ID_CLEAR ), FALSE );
  481. EnableWindow( GetDlgItem( hwnd, ID_LOGFILE_VIEW ), FALSE );
  482. }
  483. hMenu = GetSystemMenu( hwnd, FALSE );
  484. if (hMenu != NULL) {
  485. AppendMenu( hMenu, MF_SEPARATOR, 0, NULL );
  486. AppendMenu( hMenu, MF_STRING, ID_ABOUT, LoadRcString( IDS_ABOUT ) );
  487. }
  488. return;
  489. }
  490. BOOL
  491. GetDialogValues(
  492. HWND hwnd
  493. )
  494. /*++
  495. Routine Description:
  496. Retrieves the values in the DRWTSN32 dialog controls and saves
  497. them in the registry.
  498. Arguments:
  499. hwnd - window handle to the dialog
  500. Return Value:
  501. TRUE - all values were retrieved and saved
  502. FALSE - an error occurred
  503. --*/
  504. {
  505. OPTIONS o;
  506. _TCHAR buf[256];
  507. DWORD dwFa;
  508. PTSTR p,p1;
  509. _TCHAR szDrive [_MAX_DRIVE];
  510. _TCHAR szDir [_MAX_DIR];
  511. _TCHAR szPath [MAX_PATH];
  512. RegInitialize( &o );
  513. GetDlgItemText( hwnd, ID_LOGPATH, buf, sizeof(buf) / sizeof(_TCHAR) );
  514. p = ExpandPath( buf );
  515. if (p) {
  516. dwFa = GetFileAttributes( p );
  517. free( p );
  518. } else {
  519. dwFa = GetFileAttributes( buf );
  520. }
  521. if ((dwFa == 0xffffffff) || (!(dwFa&FILE_ATTRIBUTE_DIRECTORY))) {
  522. NonFatalError( LoadRcString(IDS_INVALID_PATH) );
  523. return FALSE;
  524. }
  525. if (_tcslen(buf) > 0) {
  526. _tcscpy( o.szLogPath, buf );
  527. }
  528. o.fCrash = SendMessage( GetDlgItem( hwnd, ID_CRASH ), BM_GETCHECK, 0, 0 ) ? TRUE : FALSE;
  529. GetDlgItemText( hwnd, ID_CRASH_DUMP, buf, sizeof(buf) / sizeof(_TCHAR) );
  530. if (o.fCrash) {
  531. p = ExpandPath( buf );
  532. if (p) {
  533. dwFa = GetFileAttributes( p );
  534. free( p );
  535. } else {
  536. dwFa = GetFileAttributes( buf );
  537. }
  538. if (dwFa == 0xffffffff) {
  539. //
  540. // file does not exist, check to see if the dir is ok
  541. //
  542. p = ExpandPath( buf );
  543. if (p) {
  544. p1 = p;
  545. } else {
  546. p1 = buf;
  547. }
  548. _tsplitpath( p1, szDrive, szDir, NULL, NULL );
  549. _tmakepath( szPath, szDrive, szDir, NULL, NULL );
  550. if (p) {
  551. free( p );
  552. }
  553. dwFa = GetFileAttributes( szPath );
  554. if (dwFa == 0xffffffff) {
  555. NonFatalError( LoadRcString(IDS_INVALID_CRASH_PATH) );
  556. return FALSE;
  557. }
  558. } else if (dwFa & FILE_ATTRIBUTE_DIRECTORY) {
  559. NonFatalError( LoadRcString(IDS_INVALID_CRASH_PATH) );
  560. return FALSE;
  561. }
  562. if (_tcslen(buf) > 0) {
  563. _tcscpy( o.szCrashDump, buf );
  564. }
  565. if (SendMessage( GetDlgItem( hwnd, ID_DUMP_TYPE_FULL_OLD ), BM_GETCHECK, 0, 0 )) {
  566. o.dwType = FullDump;
  567. } else if (SendMessage( GetDlgItem( hwnd, ID_DUMP_TYPE_MINI ), BM_GETCHECK, 0, 0 )) {
  568. o.dwType = MiniDump;
  569. } else if (SendMessage( GetDlgItem( hwnd, ID_DUMP_TYPE_FULLMINI ), BM_GETCHECK, 0, 0 )) {
  570. o.dwType = FullMiniDump;
  571. }
  572. }
  573. GetDlgItemText( hwnd, ID_WAVE_FILE, buf, sizeof(buf) / sizeof(_TCHAR) );
  574. if (_tcslen(buf) > 0) {
  575. dwFa = GetFileAttributes( buf );
  576. if ((dwFa == 0xffffffff) || (dwFa&FILE_ATTRIBUTE_DIRECTORY)) {
  577. NonFatalError( LoadRcString(IDS_INVALID_WAVE) );
  578. return FALSE;
  579. }
  580. }
  581. _tcscpy( o.szWaveFile, buf );
  582. GetDlgItemText( hwnd, ID_NUM_CRASHES, buf, sizeof(buf) / sizeof(_TCHAR) );
  583. o.dwMaxCrashes = (DWORD) _ttol( buf );
  584. GetDlgItemText( hwnd, ID_INSTRUCTIONS, buf, sizeof(buf) / sizeof(_TCHAR) );
  585. o.dwInstructions = (DWORD) _ttol( buf );
  586. o.fDumpSymbols = SendMessage( GetDlgItem( hwnd, ID_DUMPSYMBOLS ), BM_GETCHECK, 0, 0 ) ? TRUE : FALSE;
  587. o.fDumpAllThreads = SendMessage( GetDlgItem( hwnd, ID_DUMPALLTHREADS ), BM_GETCHECK, 0, 0 ) ? TRUE : FALSE;
  588. o.fAppendToLogFile = SendMessage( GetDlgItem( hwnd, ID_APPENDTOLOGFILE ), BM_GETCHECK, 0, 0 ) ? TRUE : FALSE;
  589. o.fVisual = SendMessage( GetDlgItem( hwnd, ID_VISUAL ), BM_GETCHECK, 0, 0 ) ? TRUE : FALSE;
  590. o.fSound = SendMessage( GetDlgItem( hwnd, ID_SOUND ), BM_GETCHECK, 0, 0 ) ? TRUE : FALSE;
  591. RegSave( &o );
  592. return TRUE;
  593. }
  594. BOOL
  595. CALLBACK
  596. EnumCrashesForViewer(
  597. PCRASHINFO crashInfo
  598. )
  599. /*++
  600. Routine Description:
  601. Enumeration function for crash records. This function is called
  602. once for each crash record. This function looks for s specific crash
  603. that is identified by the crashIndex.
  604. Arguments:
  605. crashInfo - pointer to a CRASHINFO structure
  606. Return Value:
  607. TRUE - caller should continue calling the enum procedure
  608. FALSE - caller should stop calling the enum procedure
  609. --*/
  610. {
  611. PWSTR p;
  612. if ((crashInfo->dwIndex == crashInfo->dwIndexDesired) &&
  613. (crashInfo->dwCrashDataSize > 0) ) {
  614. p = (PWSTR)crashInfo->pCrashData;
  615. crashInfo->pCrashData = (PBYTE)
  616. calloc( crashInfo->dwCrashDataSize+10, sizeof(BYTE) );
  617. if (crashInfo->pCrashData != NULL) {
  618. if (IsTextUnicode(p, crashInfo->dwCrashDataSize, NULL)) {
  619. WideCharToMultiByte(CP_ACP, WC_SEPCHARS | WC_COMPOSITECHECK,
  620. p, crashInfo->dwCrashDataSize,
  621. (LPSTR)crashInfo->pCrashData, crashInfo->dwCrashDataSize + 10, NULL, NULL);
  622. } else {
  623. memcpy( crashInfo->pCrashData, p, crashInfo->dwCrashDataSize+10 );
  624. }
  625. crashInfo->pCrashData[crashInfo->dwCrashDataSize] = 0;
  626. }
  627. return FALSE;
  628. }
  629. crashInfo->dwIndex++;
  630. return TRUE;
  631. }
  632. INT_PTR
  633. CALLBACK
  634. LogFileViewerDialogProc(
  635. HWND hwnd,
  636. UINT message,
  637. WPARAM wParam,
  638. LPARAM lParam
  639. )
  640. /*++
  641. Routine Description:
  642. Window procedure for the log file viewer dialog box.
  643. Arguments:
  644. hwnd - window handle to the dialog box
  645. message - message number
  646. wParam - first message parameter
  647. lParam - second message parameter
  648. Return Value:
  649. TRUE - did not process the message
  650. FALSE - did process the message
  651. --*/
  652. {
  653. static CRASHINFO crashInfo;
  654. HFONT hFont;
  655. switch (message) {
  656. case WM_INITDIALOG:
  657. hFont = (HFONT)GetStockObject( SYSTEM_FIXED_FONT );
  658. Assert( hFont != NULL );
  659. SendDlgItemMessage( hwnd,
  660. ID_LOGFILE_VIEW,
  661. WM_SETFONT,
  662. (WPARAM) hFont,
  663. (LPARAM) FALSE
  664. );
  665. crashInfo.dwIndex = 0;
  666. crashInfo.dwIndexDesired = (DWORD)lParam;
  667. ElEnumCrashes( &crashInfo, EnumCrashesForViewer );
  668. if (crashInfo.dwIndex != crashInfo.dwIndexDesired) {
  669. MessageBeep( 0 );
  670. EndDialog( hwnd, 0 );
  671. return FALSE;
  672. }
  673. SetDlgItemTextA( hwnd, ID_LOGFILE_VIEW,
  674. (LPSTR)crashInfo.pCrashData );
  675. return TRUE;
  676. case WM_COMMAND:
  677. if (wParam == IDOK) {
  678. free( crashInfo.pCrashData );
  679. EndDialog( hwnd, 0 );
  680. }
  681. break;
  682. case WM_CLOSE:
  683. free( crashInfo.pCrashData );
  684. EndDialog( hwnd, 0 );
  685. return TRUE;
  686. }
  687. return FALSE;
  688. }