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

📄 accmap.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:  Routines to keep track of loaded modules and address maps.
*
****************************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stdnt.h"


typedef struct lli {
    HANDLE      file_handle;
    LPVOID      base;
    addr_off    code_size;
    LPVOID      except_base;
    addr_off    except_size;
    char        is_16 : 1;
    char        has_real_filename : 1;
    char        newly_unloaded : 1;
    char        newly_loaded : 1;
    char        filename[MAX_PATH + 1];
    char        modname[40]; //
} lib_load_info;

typedef struct list {
    struct list *next;
    int         is_16;
    int         segcount;
    addr48_ptr  _WCUNALIGNED *segs;
    char        *filename;
    char        *modname;
} lib_list_info;

static lib_load_info    *moduleInfo;
static DWORD            lastLib = 0;
static const char       libPrefix[] = "NoName";

static lib_list_info    *listInfoHead;
static lib_list_info    *listInfoTail;

/*
 * freeListItem - free an individual lib list item
 */
static void freeListItem( lib_list_info *curr )
{
    LocalFree( curr->filename );
    LocalFree( curr->modname );
    LocalFree( curr->segs );
    LocalFree( curr );
}

/*
 * FreeLibList - free the lib list info
 */
void FreeLibList( void )
{
    lib_list_info   *curr;
    lib_list_info   *next;

    curr = listInfoHead;
    while( curr != NULL ) {
        next = curr->next;
        freeListItem( curr );
        curr = next;
    }
    listInfoHead = NULL;
    listInfoTail = NULL;
}

/*
 * addModuleToLibList - saves away the information about the current
 *                             module.  This is used to dump it out later
 *                             (TrapListLibs calls DoListLibs)
 */
static void addModuleToLibList( DWORD module )
{
    lib_list_info   *curr;
    lib_load_info   *lli;

    lli = &moduleInfo[module];
    curr = listInfoHead;
    while( curr != NULL ) {
        if( !stricmp( lli->modname, curr->modname ) &&
            !stricmp( lli->filename, curr->filename ) ) {
            return;
        }
        curr = curr->next;
    }

    curr = LocalAlloc( LMEM_FIXED, sizeof( lib_list_info ) );
    if( curr == NULL ) {
        return;
    }
    curr->filename = LocalAlloc( LMEM_FIXED, strlen( lli->filename ) + 1 );
    if( curr->filename == NULL ) {
        LocalFree( curr );
        return;
    }
    strcpy( curr->filename, lli->filename );
    curr->modname = LocalAlloc( LMEM_FIXED, strlen( lli->modname ) + 1 );
    if( curr->modname == NULL ) {
        LocalFree( curr->filename );
        LocalFree( curr );
        return;
    }
    strcpy( curr->modname, lli->modname );
    curr->segcount = 0;
    curr->segs = NULL;
    curr->is_16 = lli->is_16;
    curr->next = NULL;
    if( listInfoHead == NULL ) {
        listInfoHead = listInfoTail = curr;
    } else {
        listInfoTail->next = curr;
        listInfoTail = curr;
    }
}

/*
 * RemoveModuleFromLibList - removes a module from our list once it is
 *                           unloaded or exits
 */
void RemoveModuleFromLibList( char *module, char *filename )
{
    lib_list_info   *curr;
    lib_list_info   *prev;

    curr = listInfoHead;
    prev = NULL;
    while( curr != NULL ) {
        if( !stricmp( module, curr->modname ) &&
                !stricmp( filename, curr->filename ) ) {
            if( prev == NULL ) {
                listInfoHead = curr->next;
            } else {
                prev->next = curr->next;
            }
            if( curr == listInfoTail ) {
                listInfoTail = prev;
            }
            freeListItem( curr );
            return;
        }
        prev = curr;
        curr = curr->next;
    }
}

/*
 * addSegmentToLibList - add a new segment. We keep track of this so that
 *                       we can dump it later.
 */
static void addSegmentToLibList( DWORD module, WORD seg, DWORD off )
{
    addr48_ptr  *new;

    if( listInfoTail == NULL ) {
        addModuleToLibList( module );
        if( listInfoTail == NULL ) {
            return;
        }
    }
    new = LocalAlloc( LMEM_FIXED, ( listInfoTail->segcount + 1 )
                        * sizeof( addr48_ptr ) );

    if( new == NULL ) {
        return;
    }
    if( listInfoTail->segs != NULL ) {
        memcpy( new, listInfoTail->segs, sizeof( addr48_ptr )*
                                listInfoTail->segcount );
    }
    listInfoTail->segs = new;
    listInfoTail->segs[listInfoTail->segcount].segment = seg;
    listInfoTail->segs[listInfoTail->segcount].offset = off;
    listInfoTail->segcount++;
}

BOOL FindExceptInfo( addr_off off, LPVOID *base, addr_off *size )
{
    unsigned        i;
    lib_load_info   *lli;

    for( i = 0; i < ModuleTop; ++i ) {
        lli = &moduleInfo[0];
        if( off >= ( addr_off ) lli->base
         && off < ( addr_off ) lli->base + lli->code_size ) {
            /* this is the image */
            if( lli->except_size == 0 ) {
                return( FALSE );
            }
            *base = lli->except_base;
            *size = lli->except_size;
            return( TRUE );
        }
    }
    return( FALSE );
}

static void FillInExceptInfo( lib_load_info *lli )
{
    DWORD       pe_off;
    DWORD       bytes;
    pe_header   hdr;

    ReadProcessMemory( ProcessInfo.process_handle,
                ( LPVOID ) ( ( DWORD ) lli->base + OS2_NE_OFFSET ), &pe_off,
                sizeof( pe_off ), &bytes );
    ReadProcessMemory( ProcessInfo.process_handle,
                ( LPVOID ) ( ( DWORD ) lli->base + pe_off ), &hdr,
                sizeof( hdr ), &bytes );
    lli->code_size = hdr.code_base + hdr.code_size;
    lli->except_base = ( LPVOID ) ( ( DWORD ) lli->base +
        hdr.table[PE_TBL_EXCEPTION].rva );
    lli->except_size = hdr.table[PE_TBL_EXCEPTION].size;
}

/*
 * AddProcess - a new process has been created
 */
void AddProcess( header_info *hi )
{
    lib_load_info   *lli;

    moduleInfo = LocalAlloc( LMEM_FIXED, sizeof( lib_load_info ) );
    memset( moduleInfo, 0, sizeof( lib_load_info ) );
    ModuleTop = 1;

    lli = &moduleInfo[0];

    if( IsWOW || IsDOS ) {
        lli->is_16 = TRUE;
        lli->file_handle = 0;
        lli->base = 0;
        lli->has_real_filename = TRUE;
        strcpy( lli->modname, hi->modname );
        strcpy( lli->filename, CurrEXEName );
    } else {
        lli->has_real_filename = FALSE;
        lli->is_16 = FALSE;
        lli->file_handle = DebugEvent.u.CreateProcessInfo.hFile;
        // kludge - NT doesn't give us a handle sometimes
        if( lli->file_handle == INVALID_HANDLE_VALUE ) {
            lli->file_handle = CreateFile( ( LPTSTR )CurrEXEName, GENERIC_READ,
                FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
        }
        lli->base = DebugEvent.u.CreateProcessInfo.lpBaseOfImage;
        FillInExceptInfo( lli );
        lli->modname[0] = 0;
        lli->filename[0] = 0;
    }
}

/*
 * NameFromProcess - get fully qualified filename for last DLL
 * that was loaded in process. Intended for Win9x.
 */
BOOL NameFromProcess( lib_load_info *lli, DWORD dwPID, char *name )
{
    HANDLE          hModuleSnap = INVALID_HANDLE_VALUE;
    MODULEENTRY32   me32;
    BOOL            bSuccess = FALSE;

    // Check if we have the KERNEL32 entrypoints.
    if( !pCreateToolhelp32Snapshot || !pModule32First || !pModule32Next )
        goto error_exit;

    // Take a snapshot of all modules in the specified process.
    hModuleSnap = pCreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwPID );
    if( hModuleSnap == INVALID_HANDLE_VALUE )
        goto error_exit;

    // Set the size of the structure before using it.
    me32.dwSize = sizeof( MODULEENTRY32 );

    // Attempt to retrieve information about the first module.
    if( !pModule32First( hModuleSnap, &me32 ) )
        goto error_exit;

    // Look for freshly loaded module. Not tested on Win9x.
    // Unfortunately in WinXP not all newly loaded modules are in the list.
    // This should not be relevant as all NT versions will use the PSAPI method anyway.
    // The PSAPI method works reliably but is not available on Win9x.
    do {
        if( me32.modBaseAddr == lli->base ) {
            strcpy( name, me32.szExePath );
            bSuccess = TRUE;
            break;
        }
    } while( pModule32Next( hModuleSnap, &me32 ) );

error_exit:
    if( hModuleSnap != INVALID_HANDLE_VALUE )
        CloseHandle( hModuleSnap );

    return( bSuccess );
}

/*
 * NameFromHandle - get fully qualified filename from file handle.
 * Intended for Windows NT.
 */
BOOL NameFromHandle( HANDLE hFile, char *name )
{
#define BUFSIZE 512
    BOOL        bSuccess = FALSE;
    char        pszFilename[MAX_PATH + 1];
    HANDLE      hFileMap = NULL;
    void        *pMem = NULL;
    char        szTemp[BUFSIZE];
    DWORD       dwFileSizeHi;
    DWORD       dwFileSizeLo;

    name[0] = 0;

    // Check if we have the required entrypoints (results depend on OS version).
    if( (hFile == INVALID_HANDLE_VALUE) || !pGetMappedFileName || !pQueryDosDevice )
        goto error_exit;

    // Get the file size.
    dwFileSizeLo = GetFileSize( hFile, &dwFileSizeHi );
    if( dwFileSizeLo == 0 && dwFileSizeHi == 0 )
        goto error_exit;

    // Create a file mapping object and map the file.
    if( !(hFileMap = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 1, NULL ))
     || !(pMem = MapViewOfFile( hFileMap, FILE_MAP_READ, 0, 0, 1 ))
     || !pGetMappedFileName( GetCurrentProcess(), pMem, pszFilename, MAX_PATH ) ) {
        goto error_exit;
    }

    // Translate path with device name to drive letters.
    szTemp[0] = '\0';

    if( GetLogicalDriveStrings( BUFSIZE - 1, szTemp ) ) {
        char    szName[MAX_PATH];
        char    szDrive[3] = " :";
        BOOL    bFound = FALSE;
        char    *p = szTemp;

        do {
            // Copy the drive letter to the template string
            *szDrive = *p;

            // Look up each device name
            if( pQueryDosDevice( szDrive, szName, BUFSIZE ) ) {
                UINT    uNameLen = strlen( szName );

                if( uNameLen < MAX_PATH ) {
                    bFound = strnicmp( pszFilename, szName, uNameLen ) == 0;

                    if( bFound ) {
                        // Reconstruct pszFilename using szTemp
                        // Replace device path with DOS path
                        char    szTempFile[MAX_PATH];

                        sprintf( szTempFile, "%s%s", szDrive, pszFilename + uNameLen );
                        strlcpy( name, szTempFile, MAX_PATH );
                        bSuccess = TRUE;
                    }
                }
            }

            // Go to the next NULL character.
            while( *p++ )
                ;
        } while( !bFound && *p ); // end of string
    }

⌨️ 快捷键说明

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