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

📄 accload.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*
*                            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 <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "stdnt.h"
#include "trperr.h"
#include "srvcdbg.h"
#define ERR_CODES
#include "dosmsgs.h"

#ifndef CREATE_SEPARATE_WOW_VDM
#define CREATE_SEPARATE_WOW_VDM     0x00000800  // new for NT 3.5 (daytona)
#endif

/*
 * executeUntilStart - run program until start address hit
 */
static BOOL executeUntilStart( BOOL was_running )
{
    HANDLE      ph;
    brkpnt_type old;
    brkpnt_type brk = BRK_POINT;
    LPVOID      base;
    DWORD       bytes;
    CONTEXT     con;
    thread_info *ti;

    ph = DebugEvent.u.CreateProcessInfo.hProcess;
    if( !was_running ) {
        /*
         * if we are not debugging an already running app, then we
         * plant a breakpoint at the first instruction of our new app
         */
        base = DebugEvent.u.CreateProcessInfo.lpStartAddress;
        ReadProcessMemory( ph, ( LPVOID )base, ( LPVOID )&old, sizeof( old ),
            ( LPDWORD )&bytes );
        WriteProcessMemory( ph, ( LPVOID )base, ( LPVOID )&brk, sizeof( brk ),
            ( LPDWORD )&bytes );
    } else {
        // a trick to make app execute long enough to hit a breakpoint
        PostMessage( HWND_TOPMOST, WM_NULL, 0, 0 );
    }

    for( ;; ) {
        /*
         * if we encounter anything but a break point, then we are in
         * trouble!
         */
        if( DebugExecute( STATE_IGNORE_DEBUG_OUT | STATE_IGNORE_DEAD_THREAD,
                        NULL, FALSE ) & COND_BREAK ) {
            ti = FindThread( DebugEvent.dwThreadId );
            MyGetThreadContext( ti, &con );
            if( was_running ) {
                AdjustIP( &con, sizeof( brk ) );
                MySetThreadContext( ti, &con );
                return( TRUE );
            }
            if( StopForDLLs ) {
                /*
                 * the user has asked us to stop before any DLL's run
                 * their startup code (";dll"), so we do.
                 */
                WriteProcessMemory( ph, ( LPVOID )base, ( LPVOID )&old,
                    sizeof( old ), ( LPDWORD )&bytes );
                AdjustIP( &con, sizeof( brk ) );
                MySetThreadContext( ti, &con );
                return( TRUE );
            }
            if( ( AdjustIP( &con, 0 ) == ( DWORD ) base ) ) {
                /*
                 * we stopped at the applications starting address,
                 * so we can offically declare that the app has loaded
                 */
                WriteProcessMemory( ph, ( LPVOID )base, ( LPVOID )&old,
                    sizeof( old ), ( LPDWORD )&bytes );
                return( TRUE );
            }
            /*
             * skip this breakpoint and continue
             */
            AdjustIP( &con, sizeof( brk ) );
            MySetThreadContext( ti, &con );
        } else {
            return( FALSE );
        }
    }

}

#ifdef WOW
/*
 * addKERNEL - add the KERNEL module to the library load (WOW)
 */
static void addKERNEL( void )
{
    #if 0
    /*
     * there are bugs in the way VDMDBG.DLL implements some of this
     * stuff, so this is currently disabled
     */
    MODULEENTRY                 me;
    thread_info                 *ti;
    IMAGE_NOTE                  im;

    ti = FindThread( DebugeeTid );
    me.dwSize = sizeof( MODULEENTRY );
    if( pVDMModuleFirst( ProcessInfo.process_handle, ti->thread_handle,
                    &me, NULL, 0 ) ) {
        do {
            if( !memicmp( me.szModule, "KERNEL", 6 ) ) {
                memcpy( &im.Module, &me.szModule, sizeof( me.szModule ) );
                memcpy( &im.FileName, &me.szExePath, sizeof( me.szExePath ) );
                AddLib( TRUE, &im );
                break;
            }
            me.dwSize = sizeof( MODULEENTRY );
        } while( pVDMModuleNext( ProcessInfo.process_handle, ti->thread_handle,
                        &me, NULL, 0 ) );
    }
    #else
    IMAGE_NOTE                  im;

    /*
     * this is a giant kludge, but it works.  Since KERNEL is already
     * loaded in the WOW , we never get a DLL load notification, so
     * we can't show any symbols.  This fakes up the necessary information
     */
    strcpy( im.Module, "KERNEL" );
    GetSystemDirectory( im.FileName, sizeof( im.FileName ) );
    strcat( im.FileName, "\\KRNL386.EXE" );
    AddLib( TRUE, &im );
    #endif

}

/*
 * addAllWOWModules - add all modules as libraries.  This is invoked if
 *                    WOW was already running, since we will get no
 *                    lib load notifications if it was.
 */
static void addAllWOWModules( void )
{
    MODULEENTRY         me;
    thread_info         *ti;
    IMAGE_NOTE          im;

    ti = FindThread( DebugeeTid );
    me.dwSize = sizeof( MODULEENTRY );
    if( pVDMModuleFirst( ProcessInfo.process_handle, ti->thread_handle,
                    &me, NULL, 0 ) ) {
        do {
            if( !strcmp( me.szModule, WOWAppInfo.modname ) ) {
                continue;
            }
            memcpy( &im.Module, &me.szModule, sizeof( me.szModule ) );
            memcpy( &im.FileName, &me.szExePath, sizeof( me.szExePath ) );
            AddLib( TRUE, &im );
            me.dwSize = sizeof( MODULEENTRY );
        } while( pVDMModuleNext( ProcessInfo.process_handle, ti->thread_handle,
                        &me, NULL, 0 ) );
    }

}

/*
 * executeUntilVDMStart - go until we hit our first VDM exception
 */
static BOOL executeUntilVDMStart( void )
{
    int rc;

    for( ;; ) {
        rc = DebugExecute( STATE_WAIT_FOR_VDM_START, NULL, FALSE );
        if( rc == COND_VDM_START ) {
            return( TRUE );
        }
        return( FALSE );
    }

}

/*
 * EnumWOWProcessFunc - callback for each WOW process in the system
 */
static BOOL WINAPI EnumWOWProcessFunc( DWORD pid, DWORD attrib, LPARAM lparam )
{
    if( attrib & WOW_SYSTEM ) {
        *( DWORD * ) lparam = pid;
        return( FALSE );
    }
    return( TRUE );

}
#else
static BOOL WINAPI EnumWOWProcessFunc( DWORD pid, DWORD attrib, LPARAM lparam )
{
    (void)pid, (void)attrib; // Unused
    *( DWORD *)lparam = 0;
    return( FALSE );
}
#endif

/*
 * AccLoadProg - create a new process for debugging
 */
unsigned ReqProg_load( void )
{
    char            *parm;
    char            *src;
    char            *dst;
    char            *endsrc;
    char            exe_name[PATH_MAX];
    char            ch;
    BOOL            rc;
    int             len;
    CONTEXT         con;
    thread_info     *ti;
    HANDLE          handle;
    prog_load_req   *acc;
    prog_load_ret   *ret;
    header_info     hi;
    WORD            stack;
    WORD            version;
    DWORD           pid;
    DWORD           pid_started;
    DWORD           cr_flags;
    char            *buff = NULL;
    size_t          nBuffRequired = 0;
    char            *dll_name;
    char            *service_name;
    char            *dll_destination;
    char            *service_parm;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    parm = GetInPtr( sizeof( *acc ) );

    /*
     * reset status variables
     */
    LastExceptionCode = -1;
    DebugString = NULL;
    DebugeeEnded = FALSE;
    RemoveAllThreads();
    FreeLibList();
    DidWaitForDebugEvent = FALSE;
    DebugeePid = NULL;
    DebugeeTid = NULL;

    /*
     * check if pid is specified
     */
    ParseServiceStuff( parm, &dll_name, &service_name, &dll_destination,
        &service_parm );
    pid = 0;
    src = parm;

    /*
    //  Just to be really safe!
    */
    nBuffRequired = GetTotalSize() + PATH_MAX + 16;
    if( NULL == ( buff = malloc( nBuffRequired ) ) ) {
        ret->err = ERROR_NOT_ENOUGH_MEMORY;
        return( sizeof( *ret ) );

⌨️ 快捷键说明

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