|
|
Microsoft Windows NT Build 511 (SDK Final Release) 07-24-1993
/*++
Copyright (c) 1993 Microsoft Corporation
Module Name:
browse.c
Abstract:
This file implements the functions that make use of the common
file open dialogs for browsing for files/directories.
Author:
Wesley Witt (wesw) 1-May-1993
Environment:
User Mode
--*/
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <commdlg.h>
#include <mmsystem.h>
#include <direct.h>
#include "drwatson.h"
#include "proto.h"
#include "resource.h"
#include "messages.h"
//
// defines
//
#define DEFAULT_WAIT_TIME (1000 * 60 * 5) // wait for 5 minutes
//
// static global variables
//
static HANDLE hThreadDebug;
static PDEBUGPACKET dp;
DWORD TimerKillThread( HWND hwnd );
LRESULT NotifyWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK UsageDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
void
NotifyWinMain ( void )
/*++
Routine Description:
This is the entry point for DRWTSN32
Arguments:
None.
Return Value:
None.
--*/
{
MSG msg;
WNDCLASS wndclass;
DWORD dwThreadId;
HINSTANCE hInst;
dp = (PDEBUGPACKET) malloc( sizeof(DEBUGPACKET) );
memset( dp, 0, sizeof(DEBUGPACKET) );
GetCommandLineArgs( &dp->dwPidToDebug, &dp->hEventToSignal );
RegInitialize( &dp->options );
if (dp->options.fVisual) {
hInst = GetModuleHandle( NULL );
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = NotifyWndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = DLGWINDOWEXTRA;
wndclass.hInstance = hInst;
wndclass.hIcon = LoadIcon( hInst, MAKEINTRESOURCE(APPICON) );
wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = "NotifyDialog";
RegisterClass( &wndclass );
dp->hwnd = CreateDialog( hInst,
MAKEINTRESOURCE( NOTIFYDIALOG ),
0,
NotifyWndProc );
}
hThreadDebug = CreateThread( NULL,
16000,
(LPTHREAD_START_ROUTINE)DispatchDebugEventThread,
dp,
THREAD_SET_INFORMATION,
(LPDWORD)&dwThreadId
);
if (dp->options.fSound) {
if ((waveOutGetNumDevs() == 0) || (!strlen(dp->options.szWaveFile))) {
MessageBeep( MB_ICONHAND );
MessageBeep( MB_ICONHAND );
}
else {
PlaySound( dp->options.szWaveFile, NULL, SND_FILENAME );
}
}
if (dp->options.fVisual) {
ShowWindow( dp->hwnd, SW_SHOWNORMAL );
while (GetMessage (&msg, NULL, 0, 0)) {
if (!IsDialogMessage( dp->hwnd, &msg )) {
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
}
else {
WaitForSingleObject( hThreadDebug, INFINITE );
}
return;
}
LRESULT
NotifyWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
/*++
Routine Description:
Window procedure for the DRWTSN32.EXE popup. This is the popup
that is displayed when an application error occurs.
Arguments:
hwnd - window handle to the dialog box
message - message number
wParam - first message parameter
lParam - second message parameter
Return Value:
TRUE - did not process the message
FALSE - did process the message
--*/
{
DWORD dwThreadId;
DWORD dwSize;
HANDLE hThread;
char szTaskName[MAX_PATH];
char szHelpFileName[MAX_PATH];
switch (message) {
case WM_CREATE:
return FALSE;
case WM_INITDIALOG:
//
// OK is not enabled until the debugger thread finishes
//
EnableWindow( GetDlgItem( hwnd, IDOK ), FALSE );
//
// CANCEL is not enabled until debugactiveprocess is finished
//
EnableWindow( GetDlgItem( hwnd, IDCANCEL ), FALSE );
//
// make sure that the user can see the dialog box
//
SetForegroundWindow( hwnd );
//
// get the task name and display it on the dialog box
//
dwSize = sizeof(szTaskName);
GetTaskName( dp->dwPidToDebug, szTaskName, &dwSize );
SetDlgItemText( hwnd, ID_TEXT1, szTaskName);
//
// create a thread to terminate DrWatson if the user does
// not push the OK putton
//
CreateThread( NULL,
16000,
(LPTHREAD_START_ROUTINE)TimerKillThread,
(LPVOID)hwnd,
THREAD_SET_INFORMATION,
(LPDWORD)&dwThreadId
);
return TRUE;
case WM_COMMAND:
switch (wParam) {
case IDOK:
PostQuitMessage( 0 );
break;
case IDCANCEL:
//
// terminate the debugger thread
//
TerminateThread( hThreadDebug, 0 );
//
// create a thread to terminate the debuggee
// this is necessary if cancel is pressed before the
// debugger thread finishes the postmortem dump
//
hThread = CreateThread( NULL,
16000,
(LPTHREAD_START_ROUTINE)TerminationThread,
dp,
THREAD_SET_INFORMATION,
(LPDWORD)&dwThreadId
);
//
// wait for the termination thread to kill the debuggee
//
WaitForSingleObject( hThread, 30000 );
//
// now post a quit message so that DrWatson will go away
//
PostQuitMessage( 0 );
break;
case ID_HELP:
//
// call winhelp
//
GetHelpFileName( szHelpFileName, sizeof(szHelpFileName) );
WinHelp( hwnd, szHelpFileName, HELP_CONTEXT, IDH_WHAT );
break;
}
break;
case WM_DUMPCOMPLETE:
//
// the message is received from the debugger thread
// when the postmortem dump is finished. all we need to do
// is enable the OK button and wait for the user to press the
// OK button or for the timer to expire. in either case
// DrWatson will terminate.
//
EnableWindow( GetDlgItem( hwnd, IDOK ), TRUE );
return 0;
case WM_ATTACHCOMPLETE:
//
// the message is received from the debugger thread when
// the debugactiveprocess() is completed
//
EnableWindow( GetDlgItem( hwnd, IDCANCEL ), TRUE );
return 0;
case WM_EXCEPTIONINFO:
SetDlgItemText( hwnd, ID_TEXT2, (char *) lParam);
break;
case WM_DESTROY:
PostQuitMessage( 0 );
return 0;
}
return DefWindowProc( hwnd, message, wParam, lParam );
}
DWORD
TimerKillThread( HWND hwnd )
/*++
Routine Description:
This function executes in its own thread. The purpose is to wait
dwMilliseconds and notify the hwndMain window by destroting it.
This thread is used to terminate DRWTSN32 when the use does not
respond to the application error popup.
Arguments:
dwMilliseconds - amount of time to wait
Return Value:
Zero.
--*/
{
//
// wait as long as i'm told to
//
Sleep( DEFAULT_WAIT_TIME );
//
// tell the popup that its time to go away
//
SendMessage( hwnd, WM_DESTROY, 0, 0 );
return 0;
}
BOOLEAN
GetCommandLineArgs( LPDWORD dwPidToDebug, LPHANDLE hEventToSignal )
/*++
Routine Description:
Parses the command line for the 3 possible command lines
arguments:
-p %ld process id
-e %ld event id
-g go
Arguments:
dp - pointer to a debug packet
Return Value:
None.
--*/
{
char *lpstrCmd = GetCommandLine();
UCHAR ch;
char buf[4096];
BOOLEAN rval = FALSE;
// skip over program name
do {
ch = *lpstrCmd++;
}
while (ch != ' ' && ch != '\t' && ch != '\0');
// skip over any following white space
while (ch == ' ' || ch == '\t') {
ch = *lpstrCmd++;
}
// process each switch character '-' as encountered
while (ch == '-') {
ch = *lpstrCmd++;
// process multiple switch characters as needed
do {
switch (ch) {
case 'e':
case 'E':
// event to signal takes decimal argument
// skip whitespace
do {
ch = *lpstrCmd++;
}
while (ch == ' ' || ch == '\t');
while (ch >= '0' && ch <= '9') {
(DWORD)*hEventToSignal =
(DWORD)*hEventToSignal * 10 + ch - '0';
ch = *lpstrCmd++;
}
rval = TRUE;
break;
case 'p':
case 'P':
// pid debug takes decimal argument
do
ch = *lpstrCmd++;
while (ch == ' ' || ch == '\t');
if ( ch == '-' ) {
ch = *lpstrCmd++;
if ( ch == '1' ) {
*dwPidToDebug = 0xffffffff;
ch = *lpstrCmd++;
}
}
else {
while (ch >= '0' && ch <= '9') {
*dwPidToDebug =
*dwPidToDebug * 10 + ch - '0';
ch = *lpstrCmd++;
}
}
rval = TRUE;
break;
case 'g':
case 'G':
ch = *lpstrCmd++;
break;
case '?':
DialogBox( GetModuleHandle(NULL),
MAKEINTRESOURCE(USAGEDIALOG),
NULL,
UsageDialogProc
);
rval = TRUE;
ch = *lpstrCmd++;
break;
case 'i':
case 'I':
FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE,
NULL,
MSG_INSTALL_NOTIFY,
0, // GetUserDefaultLangID(),
buf,
sizeof(buf),
NULL
);
RegInstallDrWatson();
MessageBox( NULL,
buf,
"Dr. Watson for Windows NT",
MB_ICONINFORMATION | MB_OK |
MB_SETFOREGROUND );
rval = TRUE;
ch = *lpstrCmd++;
break;
default:
return rval;
}
}
while (ch != ' ' && ch != '\t' && ch != '\0');
while (ch == ' ' || ch == '\t') {
ch = *lpstrCmd++;
}
}
return rval;
}
BOOL CALLBACK
UsageDialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
/*++
Routine Description:
This is the dialog procedure for the assert dialog box. Normally
an assertion box is simply a message box but in this case a Help
button is desired so a dialog box is used.
Arguments:
hDlg - window handle to the dialog box
message - message number
wParam - first message parameter
lParam - second message parameter
Return Value:
TRUE - did not process the message
FALSE - did process the message
--*/
{
char buf[4096];
switch (message) {
case WM_INITDIALOG:
FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE,
NULL,
MSG_USAGE,
0, // GetUserDefaultLangID(),
buf,
sizeof(buf),
NULL
);
SetDlgItemText( hDlg, ID_USAGE, buf );
break;
case WM_COMMAND:
switch (wParam) {
case IDOK:
EndDialog( hDlg, 0 );
break;
}
break;
}
return FALSE;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.