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

📄 accmap.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:

error_exit:
    if( pMem )
        UnmapViewOfFile( pMem );
    if( hFileMap )
        CloseHandle( hFileMap );
    return( bSuccess );
#undef BUFSIZE
}




/*
 * AddLib - a new library has loaded
 */
void AddLib( BOOL is_16, IMAGE_NOTE *im )
{
    lib_load_info   *lli;

    ModuleTop++;
    lli = LocalAlloc( LMEM_FIXED, ModuleTop*sizeof( lib_load_info ) );
    memset( lli, 0, ModuleTop*sizeof( lib_load_info ) );
    memcpy( lli, moduleInfo, ( ModuleTop - 1 ) *sizeof( lib_load_info ) );
    LocalFree( moduleInfo );
    moduleInfo = lli;
    lli = &moduleInfo[ModuleTop - 1];

#ifndef WOW
    (void)im, (void)is_16; // Unused
#else
    if( is_16 ) {
        lli->is_16 = TRUE;
        lli->has_real_filename = TRUE;
        lli->file_handle = 0;
        lli->base = 0;
        lli->newly_loaded = TRUE;
        lli->newly_unloaded = FALSE;
        strcpy( lli->filename, im->FileName );
        strcpy( lli->modname, im->Module );
    } else
#endif
 {
        lli->is_16 = FALSE;
        lli->has_real_filename = FALSE;
        /*
         * for a 32-bit DLL, we make up a fake name to tell the debugger
         * when the debugger asks to open this fake name, we return the
         * saved file handle
         */
        lli->file_handle = DebugEvent.u.LoadDll.hFile;
        lli->base = DebugEvent.u.LoadDll.lpBaseOfDll;
        lli->modname[0] = 0;
        if ( NameFromHandle( lli->file_handle, lli->filename) ) {
            lli->has_real_filename = TRUE;
        } else if( NameFromProcess( lli, DebugeePid, lli->filename ) ) {
            lli->has_real_filename = TRUE;
        } else if( !GetModuleName( lli->file_handle, lli->filename ) ) {
            lastLib++;
            strcpy( lli->filename, libPrefix );
            ultoa( lastLib, &lli->filename[sizeof( libPrefix ) - 1], 16 );
            strcat( lli->filename, ".dll" );
        }
        FillInExceptInfo( lli );
        lli->newly_loaded = TRUE;
        lli->newly_unloaded = FALSE;
    }
}

void DelLib( void )
{
    unsigned    i;

    for( i = 0; i < ModuleTop; ++i ) {
        if( moduleInfo[i].base == DebugEvent.u.UnloadDll.lpBaseOfDll ) {
            moduleInfo[i].newly_unloaded = TRUE;
            moduleInfo[i].base = NULL;
            moduleInfo[i].code_size = 0;
            if( moduleInfo[i].file_handle != INVALID_HANDLE_VALUE ) {
                CloseHandle( moduleInfo[i].file_handle );
                moduleInfo[i].file_handle = INVALID_HANDLE_VALUE;
            }
            break;
        }
    }
}

void DelProcess( BOOL closeHandles )
{
    unsigned    i;

    for( i = 0; i < ModuleTop; ++i ) {
        if( closeHandles ) {
            CloseHandle( moduleInfo[i].file_handle );
            moduleInfo[i].file_handle = INVALID_HANDLE_VALUE;
        }
        moduleInfo[i].base = NULL;
        moduleInfo[i].code_size = 0;
    }
}

/*
 * force16SegmentLoad - force a wow app to access its segment so that it
 *                      will be loaded into memory.
 */
#ifdef WOW

#define INS_BYTES 7

static void force16SegmentLoad( thread_info *ti, WORD sel )
{
    static char     getMemIns[INS_BYTES] = {
        0x8e, 0xc0, 0x26, 0xa1, 0x00, 0x00, 0xcc
    };
    static char     origBytes[INS_BYTES];
    static BOOL     gotOrig;
    auto   CONTEXT  con;
    auto   CONTEXT  oldcon;

    if( !UseVDMStuff ) {
        return;
    }

    if( !gotOrig ) {
        gotOrig = TRUE;
        ReadMem( WOWAppInfo.segment, WOWAppInfo.offset, origBytes, INS_BYTES );
    }
    WriteMem( WOWAppInfo.segment, WOWAppInfo.offset, getMemIns, INS_BYTES );
    MyGetThreadContext( ti, &con );
    oldcon = con;
    con.Eax = sel;
    con.Eip = WOWAppInfo.offset;
    con.SegCs = WOWAppInfo.segment;
    MySetThreadContext( ti, &con );
    DebugExecute( STATE_IGNORE_DEBUG_OUT | STATE_IGNORE_DEAD_THREAD |
                        STATE_EXPECTING_FAULT, NULL, FALSE );
    MySetThreadContext( ti, &oldcon );
    WriteMem( WOWAppInfo.segment, WOWAppInfo.offset, origBytes, INS_BYTES );
}
#endif

unsigned ReqMap_addr( void )
{
    int             i;
    HANDLE          handle;
    DWORD           bytes;
    pe_object       obj;
    WORD            seg;
    map_addr_req    *acc;
    map_addr_ret    *ret;
    header_info     hi;
    lib_load_info   *lli;
    WORD            stack;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );

    seg = acc->in_addr.segment;
    switch( seg ) {
    case MAP_FLAT_CODE_SELECTOR:
    case MAP_FLAT_DATA_SELECTOR:
        seg = 0;
        break;
    default:
        --seg;
        break;
    }

    lli = &moduleInfo[acc->handle];

#ifdef WOW
    if( lli->is_16 ) {
        LDT_ENTRY   ldt;
        WORD        sel;
        thread_info *ti;
        /*
         * much simpler for a WOW app.  We just ask for the selector that
         * maps to the given segment number.
         */
        ti = FindThread( DebugeeTid );
        pVDMGetModuleSelector( ProcessInfo.process_handle,
                        ti->thread_handle, seg, lli->modname, &sel );
        pVDMGetThreadSelectorEntry( ProcessInfo.process_handle,
                        ti->thread_handle, sel, &ldt );
        if( !ldt.HighWord.Bits.Pres ) {
            /*
             * if the segment is not present, then we make the app load it
             */
            force16SegmentLoad( ti, sel );
        }
        ret->out_addr.segment = sel;
        ret->out_addr.offset = 0;
    } else
#endif
 {
        /*
         * for a 32-bit app, we get the PE header. We can look the up the
         * object in the header and determine if it is code or data, and
         * use that to assign the appropriate selector (either FlatCS
         * or FlatDS).
         */
        handle = lli->file_handle;

        if( !GetEXEHeader( handle, &hi, &stack ) ) {
            return( 0 );
        }
        if( hi.sig == EXE_PE ) {
            for( i = 0; i < hi.peh.num_objects; i++ ) {
                ReadFile( handle, &obj, sizeof( obj ), &bytes, NULL );
                if( i == seg ) {
                    break;
                }
            }
            if( i == hi.peh.num_objects ) {
                return( 0 );
            }
            if( obj.flags & ( PE_OBJ_CODE | PE_OBJ_EXECUTABLE ) ) {
                ret->out_addr.segment = FlatCS;
            } else {
                ret->out_addr.segment = FlatDS;
            }
            ret->out_addr.offset = ( DWORD ) lli->base + obj.rva;
        } else {
            return( 0 );
        }
    }
    addSegmentToLibList( acc->handle, ret->out_addr.segment,
         ret->out_addr.offset );
    ret->out_addr.offset += acc->in_addr.offset;
    ret->lo_bound = 0;
    ret->hi_bound = ~( addr48_off ) 0;
    return( sizeof( *ret ) );
}

/*
 * AccGetLibName - get lib name of current module
 */
unsigned ReqGet_lib_name( void )
{
    get_lib_name_req    *acc;
    get_lib_name_ret    *ret;
    char                *name;
    unsigned            i;

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

    ret->handle = 0;

    for( i = 0; i < ModuleTop; ++i ) {
        if( moduleInfo[i].newly_unloaded ) {
            ret->handle = i;
            name[0] = '\0';
            moduleInfo[i].newly_unloaded = FALSE;
            return( sizeof( *ret ) );
        } else if( moduleInfo[i].newly_loaded ) {
            ret->handle = i;
            strcpy( name, moduleInfo[i].filename );
            moduleInfo[i].newly_loaded = FALSE;
            /*
             * once the debugger asks for a lib name, we also add it to our lib
             * list.  This list is used to dump the list of all DLL's, and their
             * selectors
             */
            addModuleToLibList( i );
            return( sizeof( *ret ) + strlen( name ) + 1 );
        }
    }
    return( sizeof( *ret ) );
}

/*
 * GetMagicalFileHandle - check if name is already opened by NT
 */
HANDLE GetMagicalFileHandle( char *name )
{
    DWORD i;

    for( i = 0; i < ModuleTop; i++ ) {
        if( !stricmp( name, moduleInfo[i].filename ) ) {
            if( moduleInfo[i].has_real_filename ) {
                return( NULL );
            } else {
                return( moduleInfo[i].file_handle );
            }
        }
    }
    return( NULL );
}

/*
 * IsMagicalFileHandle - test if a handle is one given by NT
 */
BOOL IsMagicalFileHandle( HANDLE h )
{
    DWORD i;

    for( i = 0; i < ModuleTop; i++ ) {
        if( moduleInfo[i].file_handle == h ) {
            return( TRUE );
        }
    }
    return( FALSE );
}

#if 0
static lib_list_info    *currInfo;
static int              currSeg;

/*
 * formatSel - format a selector for display
 */
static void formatSel( char *buff, int verbose )
{
    thread_info *ti;
    LDT_ENTRY   ldt;
    DWORD       base;
    DWORD       limit;
    DWORD       off;
    WORD        seg;

    seg = currInfo->segs[currSeg].segment;
    off = currInfo->segs[currSeg].offset;

    if( currInfo->is_16 ) {
        wsprintf( buff, "%04x", seg );
    } else {
        wsprintf( buff, "%04x:%08lx", seg, off );
    }
    if( verbose ) {
        ti = FindThread( DebugeeTid );
        GetThreadSelectorEntry( ti->thread_handle, seg, &ldt );
        base = off + ( DWORD ) ldt.BaseLow +
            ( ( DWORD ) ldt.HighWord.Bytes.BaseMid << 16L ) +
            ( ( DWORD ) ldt.HighWord.Bytes.BaseHi << 24L );
        buff = &buff[strlen( buff )];
        limit = 1 + ( DWORD ) ldt.LimitLow +
            ( ( DWORD ) ldt.HighWord.Bits.LimitHi << 16L );
        if( ldt.HighWord.Bits.Granularity ) {
            limit *= 0x1000L;
        }
        if( currInfo->is_16 ) {
            wsprintf( buff, " - base:%08lx size:%04x", base, limit );
        } else {
            wsprintf( buff, " - base:%08lx size:%08lx", base, limit );
        }
    }
}

/*
 * DoListLibs - format up lib list info.  This is called repeatedly by
 *              the debugger to dump all DLL's and their segments
 */
int DoListLibs( char *buff, int is_first, int want_16, int want_32,
                                        int verbose, int sel )
{
    BOOL    done;

    sel = sel;
    verbose = verbose;

    if( is_first ) {
        currInfo = listInfoHead;
        currSeg = -1;
    }
    done = FALSE;
    while( !done ) {
        if( currInfo == NULL ) {
            return( FALSE );
        }
        if( (  currInfo->is_16 && want_16 )
        ||  ( !currInfo->is_16 && want_32 ) ) {
            done = TRUE;
            if( currSeg == -1 ) {
                wsprintf( buff, "%s (%s):", currInfo->modname,
                    currInfo->filename );
            } else {
                formatSel( buff, verbose );
            }
        } else {
            currSeg = currInfo->segcount - 1;
        }
        if( currSeg == currInfo->segcount - 1 ) {
            currInfo = currInfo->next;
            currSeg = -1;
        } else {
            currSeg++;
        }
    }
    return( TRUE );
}
#endif

⌨️ 快捷键说明

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