NOTIFY.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:13k
源码类别:

Windows编程

开发平台:

Visual C++

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