⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 notify.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
字号:
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <stdio.h>
#include <dos.h>
#include "wdebug.h"
#include "stdwin.h"

#ifdef DEBUG
char *notify_msgs[] = {
    "NFY_UNKNOWN",
    "NFY_LOADSEG",
    "NFY_FREESEG",
    "NFY_STARTDLL",
    "NFY_STARTTASK",
    "NFY_EXITTASK",
    "NFY_DELMODULE",
    "NFY_RIP",
    "NFY_TASKIN",
    "NFY_TASKOUT",
    "NFY_INCHAR",
    "NFY_OUTSTR",
    "NFY_LOGERROR",
    "NFY_LOGPARAMERROR"
};
#endif

static HANDLE   TaskAtNotify;

/*
 * doLoadSeg:
 *
 * handle NFY_LOADSEG notification
 *
 * If we get a segment load, then we make sure that
 * any breakpoints we may have set in the segment are re-planted
 */
static BOOL doLoadSeg( DWORD data )
{
    NFYLOADSEG  *ls;

    ls = (NFYLOADSEG *) data;
    if( DebuggerState != LOADING_DEBUGEE ) {
        ResetBreakpoints( ls->wSelector );
    }
    return( FALSE );

} /* doLoadSeg */

/*
 * doStartTask:
 *
 * handle NFY_STARTTASK notification
 *
 * If we are waiting for the debuggee to load, then this is the task.
 * We remember the module and task ID's, and plant a breakpoint at the
 * starting address of the application.  We can do that now, since we
 * now know the code selector for the segment with the start address.
 *
 * Otherwise, we simply record it so that we can notify the debugger
 * about a loaded module later.
 */
static BOOL doStartTask( DWORD data )
{
    char        val;
    TASKENTRY   te;

    te.dwSize = sizeof( te );
    TaskFindHandle( &te, TaskAtNotify );

    if( DebuggerState == LOADING_DEBUGEE ) {
        DebugeeModule = te.hModule;
        DebugeeTask = TaskAtNotify;
        StopNewTask.loc.segment = HIWORD( data );
        ReadMem( StopNewTask.loc.segment, StopNewTask.loc.offset,
                &StopNewTask.value, 1 );
        val = 0xcc;
        WriteMem( StopNewTask.loc.segment, StopNewTask.loc.offset,
                    &val, 1 );
        ReadMem( StopNewTask.loc.segment, StopNewTask.loc.offset,
                &val, 1 );
        Out((OUT_RUN,"           wrote breakpoint at %04x:%04lx, oldbyte=%02x(is now %02x)",
                    StopNewTask.loc.segment, StopNewTask.loc.offset,
                    StopNewTask.value, val ));
        Out((OUT_RUN,"   StartTask: cs:ip = %Fp", data ));
        ToDebugger( TASK_LOADED );
    } else {
        AddModuleLoaded( te.hModule, FALSE );
    }
    return( FALSE );

} /* doStartTask */

/*
 * doStartDLL:
 *
 * handle a NFY_STARTDLL notification
 *
 * Record the module to notify the debugger of it later.
 */
static BOOL doStartDLL( DWORD data )
{
    NFYSTARTDLL *sd;
    char        val;

    sd = (NFYSTARTDLL *) data;
    AddModuleLoaded( sd->hModule, TRUE );
    if( DebuggerState == RUNNING_DEBUGEE ) {
        ReadMem( sd->wCS, sd->wIP, &DLLLoadSaveByte, 1 );
        DLLLoadCS = sd->wCS;
        DLLLoadIP = sd->wIP;
        val = 0xcc;
        WriteMem( sd->wCS, sd->wIP, &val, 1 );
    }
    Out((OUT_ERR,"DLL Loaded '%4.4x:%4.4x'",sd->wCS,sd->wIP));
    return( FALSE );

} /* doStartDLL */


/*
 * doOutStr:
 *
 * handle a NFY_OUTSTR notification
 *
 * We return to the debugger so that it can display the string for the
 * user to see.
 */
static BOOL doOutStr( DWORD data )
{
    char        *src;

    if( DebuggerState != RUNNING_DEBUGEE ) {
        Out((OUT_ERR,"Debugger was bad! '%s'",OutBuff));
        return( 0 );
    }
    src = (LPSTR) data;
    while( *src ) {
        if( *src == '\r' || OutPos == (MAX_STR-1) ) {
            OutBuff[ OutPos++ ] = '\0';
            Out((OUT_RUN,"Going to debugger for OUT_STR '%s'",OutBuff));
            if( DebugeeTask == NULL ) return( 0 );
            ToDebugger( OUT_STR );
        }
        if( *src != '\n' && *src != '\t' ) {
            OutBuff[ OutPos++ ] = *src;
        }
        src++;
    }
    return( 0 );
} /* doOutStr */

/*
 * doInChar:
 *
 * handle a NFY_INCHAR notification.
 *
 * the kernel wants a character (typically after a fatal exit), so
 * we flip back to the debugger to get a character from the user.
 */
static BOOL doInChar( void )
{

    if( DebuggerState != RUNNING_DEBUGEE ) return( 'i' ); // cover our ass!
    Out((OUT_RUN,"Going to debugger for GET_CHAR"));
    return( 'b' );
//  ToDebugger( GET_CHAR );
//  return( IntResult.EAX );

} /* doInChar */

/*
 * doExitTask:
 *
 * handle NFY_EXITTASK notification
 *
 * If the task was the debuggee, we notify the debugger that the
 * debuggee has terminated.
 */
static BOOL doExitTask( DWORD data )
{
    data = data;

    if( TaskAtNotify == DebugeeTask ) {
        TerminateCSIP = TaskGetCSIP( DebugeeTask );
        PostAppMessage( DebuggerTask, WM_NULL, TASK_ENDED, MAGIC_COOKIE );
    }
    return( FALSE );

} /* doExitTask */

/*
 * NotifyHandler - recieves notifications from toolhelp and processes them
 */
BOOL __far __pascal NotifyHandler( WORD id, DWORD data )
{
    BOOL        rc;

    TaskAtNotify = GetCurrentTask();
    if( id == NFY_LOADSEG || id == NFY_LOGERROR || id == NFY_FREESEG ||
                id == NFY_LOGPARAMERROR ) {
        return( FALSE );
    }
    if( id == NFY_OUTSTR ) {
        Out((OUT_RUN,"%s(%d): Task=%04x, data=%08lx",
                notify_msgs[id], id, TaskAtNotify, data ));
        Out((OUT_RUN,"        \"%Fs\"", data ));
    } else {
        Out((OUT_RUN,"%s(%d): Task=%04x, data=%08lx",
                notify_msgs[id], id, TaskAtNotify, data));
    }

    switch( id ) {
    case NFY_OUTSTR:
        rc = doOutStr( data );
        break;
    case NFY_INCHAR:
        rc = doInChar();
        break;
    case NFY_STARTTASK:
        rc = doStartTask( data );
        break;
    case NFY_EXITTASK:
        rc = doExitTask( data );
        break;
    case NFY_STARTDLL:
        rc = doStartDLL( data );
        break;
    case NFY_LOADSEG:
        rc = doLoadSeg( data );
        break;
    default:
        rc = FALSE;
        break;
    }

    return( rc );

} /* NotifyHandler */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -