home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / image / drwatson / notify.c < prev    next >
C/C++ Source or Header  |  1996-06-19  |  14KB  |  498 lines

  1. /*++
  2.  
  3. Copyright (c) 1993  Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     browse.c
  8.  
  9. Abstract:
  10.     This file implements the functions that make use of the common
  11.     file open dialogs for browsing for files/directories.
  12.  
  13. Author:
  14.  
  15.     Wesley Witt (wesw) 1-May-1993
  16.  
  17. Environment:
  18.  
  19.     User Mode
  20.  
  21. --*/
  22.  
  23. #include <windows.h>
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <commdlg.h>
  28. #include <mmsystem.h>
  29. #include <direct.h>
  30.  
  31. #include "drwatson.h"
  32. #include "proto.h"
  33. #include "resource.h"
  34. #include "messages.h"
  35.  
  36.  
  37. //
  38. // defines
  39. //
  40. #define DEFAULT_WAIT_TIME   (1000 * 60 * 5)     // wait for 5 minutes
  41.  
  42. //
  43. // static global variables
  44. //
  45. static HANDLE         hThreadDebug;
  46. static PDEBUGPACKET   dp;
  47.  
  48.  
  49. LRESULT NotifyWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
  50. BOOL CALLBACK UsageDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  51.  
  52.  
  53. void
  54. NotifyWinMain ( void )
  55.  
  56. /*++
  57.  
  58. Routine Description:
  59.  
  60.     This is the entry point for DRWTSN32
  61.  
  62. Arguments:
  63.  
  64.     None.
  65.  
  66. Return Value:
  67.  
  68.     None.
  69.  
  70. --*/
  71.  
  72. {
  73.     MSG            msg;
  74.     WNDCLASS       wndclass;
  75.     DWORD          dwThreadId;
  76.     HINSTANCE      hInst;
  77.  
  78.  
  79.     dp = (PDEBUGPACKET) malloc( sizeof(DEBUGPACKET) );
  80.     memset( dp, 0, sizeof(DEBUGPACKET) );
  81.     GetCommandLineArgs( &dp->dwPidToDebug, &dp->hEventToSignal );
  82.  
  83.     InitializeListHead(&dp->ThreadList);
  84.  
  85.     RegInitialize( &dp->options );
  86.  
  87.     if (dp->options.fVisual) {
  88.         hInst                   = GetModuleHandle( NULL );
  89.         wndclass.style          = CS_HREDRAW | CS_VREDRAW;
  90.         wndclass.lpfnWndProc    = NotifyWndProc;
  91.         wndclass.cbClsExtra     = 0;
  92.         wndclass.cbWndExtra     = DLGWINDOWEXTRA;
  93.         wndclass.hInstance      = hInst;
  94.         wndclass.hIcon          = LoadIcon( hInst, MAKEINTRESOURCE(APPICON) );
  95.         wndclass.hCursor        = LoadCursor( NULL, IDC_ARROW );
  96.         wndclass.hbrBackground  = (HBRUSH) (COLOR_3DFACE + 1);
  97.         wndclass.lpszMenuName   = NULL;
  98.         wndclass.lpszClassName  = "NotifyDialog";
  99.         RegisterClass( &wndclass );
  100.  
  101.         dp->hwnd = CreateDialog( hInst,
  102.                                  MAKEINTRESOURCE( NOTIFYDIALOG ),
  103.                                  0,
  104.                                  NotifyWndProc );
  105.     }
  106.  
  107.     hThreadDebug = CreateThread( NULL,
  108.                             16000,
  109.                             (LPTHREAD_START_ROUTINE)DispatchDebugEventThread,
  110.                             dp,
  111.                             0,
  112.                             (LPDWORD)&dwThreadId
  113.                           );
  114.  
  115.     if (dp->options.fSound) {
  116.         if ((waveOutGetNumDevs() == 0) || (!strlen(dp->options.szWaveFile))) {
  117.             MessageBeep( MB_ICONHAND );
  118.             MessageBeep( MB_ICONHAND );
  119.         }
  120.         else {
  121.             PlaySound( dp->options.szWaveFile, NULL, SND_FILENAME );
  122.         }
  123.     }
  124.  
  125.     if (dp->options.fVisual) {
  126.         ShowWindow( dp->hwnd, SW_SHOWNORMAL );
  127.         while (GetMessage (&msg, NULL, 0, 0)) {
  128.             if (!IsDialogMessage( dp->hwnd, &msg )) {
  129.                 TranslateMessage (&msg) ;
  130.                 DispatchMessage (&msg) ;
  131.             }
  132.         }
  133.     }
  134.     else {
  135.         WaitForSingleObject( hThreadDebug, INFINITE );
  136.     }
  137.  
  138.     CloseHandle( hThreadDebug );
  139.  
  140.     return;
  141. }
  142.  
  143. LRESULT
  144. NotifyWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  145.  
  146. /*++
  147.  
  148. Routine Description:
  149.  
  150.     Window procedure for the DRWTSN32.EXE popup.  This is the popup
  151.     that is displayed when an application error occurs.
  152.  
  153. Arguments:
  154.  
  155.     hwnd       - window handle to the dialog box
  156.     message    - message number
  157.     wParam     - first message parameter
  158.     lParam     - second message parameter
  159.  
  160. Return Value:
  161.  
  162.     TRUE       - did not process the message
  163.     FALSE      - did process the message
  164.  
  165. --*/
  166.  
  167. {
  168.     DWORD          dwThreadId;
  169.     DWORD          dwSize;
  170.     HANDLE         hThread;
  171.     char           szTaskName[MAX_PATH];
  172.     char           szHelpFileName[MAX_PATH];
  173.  
  174.     switch (message) {
  175.         case WM_CREATE:
  176.             return FALSE;
  177.  
  178.         case WM_INITDIALOG:
  179.  
  180.             SubclassControls( hwnd );
  181.  
  182.             //
  183.             // OK is not enabled until the debugger thread finishes
  184.             //
  185.             EnableWindow( GetDlgItem( hwnd, IDOK ), FALSE );
  186.  
  187.             //
  188.             // CANCEL is not enabled until debugactiveprocess is finished
  189.             //
  190.             EnableWindow( GetDlgItem( hwnd, IDCANCEL ), FALSE );
  191.  
  192.             //
  193.             //  make sure that the user can see the dialog box
  194.             //
  195.             SetForegroundWindow( hwnd );
  196.  
  197.             //
  198.             // get the task name and display it on the dialog box
  199.             //
  200.             dwSize = sizeof(szTaskName);
  201.             GetTaskName( dp->dwPidToDebug, szTaskName, &dwSize );
  202.  
  203.             //
  204.             // prevent recursion in the case where drwatson faults
  205.             //
  206.             if (_stricmp(szTaskName,"drwtsn32")==0) {
  207.                 ExitProcess(0);
  208.             }
  209.  
  210.             SetDlgItemText( hwnd, ID_TEXT1, szTaskName);
  211.  
  212.             return TRUE;
  213.  
  214.         case WM_ACTIVATEAPP:
  215.         case WM_SETFOCUS:
  216.             SetFocusToCurrentControl();
  217.             return 0;
  218.  
  219.         case WM_COMMAND:
  220.             switch (wParam) {
  221.                 case IDOK:
  222.                     PostQuitMessage( 0 );
  223.                     break;
  224.  
  225.                 case IDCANCEL:
  226.                     //
  227.                     // terminate the debugger thread
  228.                     //
  229.                     TerminateThread( hThreadDebug, 0 );
  230.  
  231.                     //
  232.                     // create a thread to terminate the debuggee
  233.                     // this is necessary if cancel is pressed before the
  234.                     // debugger thread finishes the postmortem dump
  235.                     //
  236.                     hThread = CreateThread( NULL,
  237.                                   16000,
  238.                                   (LPTHREAD_START_ROUTINE)TerminationThread,
  239.                                   dp,
  240.                                   0,
  241.                                   (LPDWORD)&dwThreadId
  242.                                 );
  243.  
  244.                     //
  245.                     // wait for the termination thread to kill the debuggee
  246.                     //
  247.                     WaitForSingleObject( hThread, 30000 );
  248.  
  249.                     CloseHandle( hThread );
  250.  
  251.                     //
  252.                     // now post a quit message so that DrWatson will go away
  253.                     //
  254.                     PostQuitMessage( 0 );
  255.                     break;
  256.  
  257.                 case ID_HELP:
  258.                     //
  259.                     // call winhelp
  260.                     //
  261.                     GetHelpFileName( szHelpFileName, sizeof(szHelpFileName) );
  262.                     WinHelp( hwnd, szHelpFileName, HELP_FINDER, IDH_WHAT );
  263.                     break;
  264.             }
  265.             break;
  266.  
  267.         case WM_NEXTDLGCTL:
  268.             DefDlgProc( hwnd, message, wParam, lParam );
  269.             return 0;
  270.  
  271.         case WM_DUMPCOMPLETE:
  272.  
  273.             //
  274.             // the message is received from the debugger thread
  275.             // when the postmortem dump is finished.  all we need to do
  276.             // is enable the OK button and wait for the user to press the
  277.             // OK button or for the timer to expire.  in either case
  278.             // DrWatson will terminate.
  279.             //
  280.             EnableWindow( GetDlgItem( hwnd, IDOK ), TRUE );
  281.             SetFocus( GetDlgItem(hwnd, IDOK) );
  282.             SetFocusToCurrentControl();
  283.             return 0;
  284.  
  285.         case WM_ATTACHCOMPLETE:
  286.  
  287.             //
  288.             // the message is received from the debugger thread when
  289.             // the debugactiveprocess() is completed
  290.             //
  291.             EnableWindow( GetDlgItem( hwnd, IDCANCEL ), TRUE );
  292.             return 0;
  293.  
  294.         case WM_EXCEPTIONINFO:
  295.  
  296.             SetDlgItemText( hwnd, ID_TEXT2, (char *) lParam);
  297.             return 0;
  298.  
  299.         case WM_DESTROY:
  300.             PostQuitMessage( 0 );
  301.             return 0;
  302.     }
  303.  
  304.     return DefWindowProc( hwnd, message, wParam, lParam );
  305. }
  306.  
  307. BOOLEAN
  308. GetCommandLineArgs( LPDWORD dwPidToDebug, LPHANDLE hEventToSignal )
  309.  
  310. /*++
  311.  
  312. Routine Description:
  313.  
  314.     Parses the command line for the 3 possible command lines
  315.     arguments:
  316.  
  317.          -p %ld        process id
  318.          -e %ld        event id
  319.          -g            go
  320.  
  321. Arguments:
  322.  
  323.     dp             - pointer to a debug packet
  324.  
  325. Return Value:
  326.  
  327.     None.
  328.  
  329. --*/
  330.  
  331. {
  332.     char        *lpstrCmd = GetCommandLine();
  333.     UCHAR       ch;
  334.     char        buf[4096];
  335.     BOOLEAN     rval = FALSE;
  336.  
  337.     // skip over program name
  338.     do {
  339.         ch = *lpstrCmd++;
  340.     }
  341.     while (ch != ' ' && ch != '\t' && ch != '\0');
  342.  
  343.     //  skip over any following white space
  344.     while (ch == ' ' || ch == '\t') {
  345.         ch = *lpstrCmd++;
  346.     }
  347.  
  348.     //  process each switch character '-' as encountered
  349.  
  350.     while (ch == '-') {
  351.         ch = *lpstrCmd++;
  352.         //  process multiple switch characters as needed
  353.         do {
  354.             switch (ch) {
  355.                 case 'e':
  356.                 case 'E':
  357.                     // event to signal takes decimal argument
  358.                     // skip whitespace
  359.                     do {
  360.                         ch = *lpstrCmd++;
  361.                     }
  362.                     while (ch == ' ' || ch == '\t');
  363.                     while (ch >= '0' && ch <= '9') {
  364.                         (DWORD)*hEventToSignal =
  365.                                   (DWORD)*hEventToSignal * 10 + ch - '0';
  366.                         ch = *lpstrCmd++;
  367.                     }
  368.                     rval = TRUE;
  369.                     break;
  370.  
  371.                 case 'p':
  372.                 case 'P':
  373.                     // pid debug takes decimal argument
  374.  
  375.                     do
  376.                         ch = *lpstrCmd++;
  377.                     while (ch == ' ' || ch == '\t');
  378.  
  379.                     if ( ch == '-' ) {
  380.                         ch = *lpstrCmd++;
  381.                         if ( ch == '1' ) {
  382.                             *dwPidToDebug = 0xffffffff;
  383.                             ch = *lpstrCmd++;
  384.                         }
  385.                     }
  386.                     else {
  387.                         while (ch >= '0' && ch <= '9') {
  388.                             *dwPidToDebug =
  389.                                        *dwPidToDebug * 10 + ch - '0';
  390.                             ch = *lpstrCmd++;
  391.                         }
  392.                     }
  393.                     rval = TRUE;
  394.                     break;
  395.  
  396.                 case 'g':
  397.                 case 'G':
  398.                     ch = *lpstrCmd++;
  399.                     break;
  400.  
  401.                 case '?':
  402.                     DialogBox( GetModuleHandle(NULL),
  403.                                MAKEINTRESOURCE(USAGEDIALOG),
  404.                                NULL,
  405.                                UsageDialogProc
  406.                              );
  407.                     rval = TRUE;
  408.                     ch = *lpstrCmd++;
  409.                     break;
  410.  
  411.                 case 'i':
  412.                 case 'I':
  413.                     FormatMessage(
  414.                       FORMAT_MESSAGE_FROM_HMODULE,
  415.                       NULL,
  416.                       MSG_INSTALL_NOTIFY,
  417.                       0,
  418.                       buf,
  419.                       sizeof(buf),
  420.                       NULL
  421.                       );
  422.                     RegInstallDrWatson( tolower(lpstrCmd[0]) == 'q' );
  423.                     MessageBox( NULL,
  424.                                 buf,
  425.                                 "Dr. Watson for Windows NT",
  426.                                 MB_ICONINFORMATION | MB_OK |
  427.                                 MB_SETFOREGROUND );
  428.                     rval = TRUE;
  429.                     ch = *lpstrCmd++;
  430.                     break;
  431.  
  432.                 default:
  433.                     return rval;
  434.             }
  435.         }
  436.         while (ch != ' ' && ch != '\t' && ch != '\0');
  437.  
  438.         while (ch == ' ' || ch == '\t') {
  439.             ch = *lpstrCmd++;
  440.         }
  441.     }
  442.     return rval;
  443. }
  444.  
  445. BOOL CALLBACK
  446. UsageDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  447.  
  448. /*++
  449.  
  450. Routine Description:
  451.  
  452.     This is the dialog procedure for the assert dialog box.  Normally
  453.     an assertion box is simply a message box but in this case a Help
  454.     button is desired so a dialog box is used.
  455.  
  456. Arguments:
  457.  
  458.     hDlg       - window handle to the dialog box
  459.     message    - message number
  460.     wParam     - first message parameter
  461.     lParam     - second message parameter
  462.  
  463. Return Value:
  464.  
  465.     TRUE       - did not process the message
  466.     FALSE      - did process the message
  467.  
  468. --*/
  469.  
  470. {
  471.     char        buf[4096];
  472.  
  473.     switch (message) {
  474.         case WM_INITDIALOG:
  475.             FormatMessage(
  476.               FORMAT_MESSAGE_FROM_HMODULE,
  477.               NULL,
  478.               MSG_USAGE,
  479.               0, // GetUserDefaultLangID(),
  480.               buf,
  481.               sizeof(buf),
  482.               NULL
  483.               );
  484.             SetDlgItemText( hDlg, ID_USAGE, buf );
  485.             break;
  486.  
  487.         case WM_COMMAND:
  488.             switch (wParam) {
  489.                 case IDOK:
  490.                     EndDialog( hDlg, 0 );
  491.                     break;
  492.             }
  493.             break;
  494.     }
  495.  
  496.     return FALSE;
  497. }
  498.