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