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

📄 memwnd.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
*
*                            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:  Memory dump display window.
*
****************************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <io.h>
#include <time.h>
#define INCLUDE_TOOLHELP_H
#include <windows.h>
#include "font.h"
#include "segmem.h"
#include "mem.h"
#include "dlgmod.h"
#include "descript.h"
#include "savelbox.h"
#include "memwnd.h"
#include "standard.h"
#include "deasm.h"
#include "ctl3d.h"
#include "win1632.h"
#include "ldstr.h"
#include "rcstr.gh"

#define  ISCODE( x )    ( (x)->disp_type == MEMINFO_CODE_16 || \
                          (x)->disp_type == MEMINFO_CODE_32 )

#define  MAX_BYTES      50

/* NO_DATA_SPACE consists of 11 bytes to display the offsets on the left
 * and 1 additional byte so that italic fonts don't get cut off on the right
 */
#define  NO_DATA_SPACE  12

WORD                    FontWidth = 8;
WORD                    FontHeight = 15;

static  HFONT           CurFont;
static  HWND            CurWindow;
static  char            Buffer[ MAX_BYTES * 4 + 20 ];
#ifndef __NT__
static  FARPROC         DialProc;
static  unsigned        DialCount;
#endif

static MemWndConfig     MemConfigInfo ;

static DWORD Disp_Types[] = {
    MWND_DISP_BYTES,
    MWND_DISP_WORDS,
    MWND_DISP_DWORDS,
    MWND_DISP_CODE_16,
    MWND_DISP_CODE_32
};

/* forward declarations */
BOOL __export FAR PASCAL MemDisplayProc( HWND, UINT, WPARAM, DWORD );
static void CalcTextDimensions( HWND hwnd, HDC dc, MemWndInfo *info );
static void DisplaySegInfo( HWND parent, HANDLE instance, MemWndInfo *info );
static void PositionSegInfo( HWND hwnd );
static BOOL GenLine( char digits, DWORD limit, WORD type, WORD sel, char *buf, DWORD offset );

typedef enum {
    MT_FREE,
    MT_RESERVE,
    MT_UNREADABLE,
    MT_READABLE
} MemType;

#ifdef __NT__

static HANDLE   ProcessHdl;
static DWORD    CurLimit;
static DWORD    CurBase;


DWORD far GetASelectorLimit( WORD sel ) {
    sel = sel;
    return( CurLimit );
}

DWORD ReadMem( WORD sel, DWORD off, void *buff, DWORD size ) {

    DWORD       bytesread;

    sel = sel;
    bytesread = 0;
    size++;
    while( bytesread != size && size != 0 ) {
        size--;
        ReadProcessMemory( ProcessHdl, (void *)off, buff, size, &bytesread );
    }
    return( bytesread );
}
#else

/*
 * CreateAccessString
 */

static void CreateAccessString( char *ptr, descriptor *desc ) {

    if( desc->type == 2 )  {
        *ptr =  'R';
        ptr ++;
        if( desc->writeable_or_readable ) {
            *ptr = '/';
            ptr ++;
            *ptr = 'W';
            ptr ++;
        }
    } else {
        *ptr = 'E';
        ptr++;
        *ptr = 'x';
        ptr ++;
        if( desc->writeable_or_readable ) {
            *ptr = '/';
            ptr ++;
            *ptr = 'R';
            ptr ++;
        }
    }
    *ptr = '\0';
} /* CreateAccessString */
#endif

/*
 * MemDumpHeader - put summary information at the top of a memory dump
 */

static void MemDumpHeader( int hdl, MemWndInfo *info ) {

    time_t              tm;
    char                buf[80];
    unsigned            len;
    WORD                type_index;
    char                *rcstr;
#ifndef __NT__
    GLOBALENTRY         ge;
    descriptor          desc;
    char                access[20];
#endif

    tm = time( NULL );
    RCsprintf( buf, MWND_MEM_DMP_CREATED, asctime( localtime( &tm ) ), &len );
    write( hdl, buf, len );

#ifndef __NT__
    if( info->isdpmi ) {
        rcstr = AllocRCString( MWND_DPMI_ITEM );
        len = strlen( rcstr );
        write( hdl, rcstr, len );
        FreeRCString( rcstr );
        GetADescriptor( info->sel, &desc );
        RCsprintf( buf, MWND_SELECTOR, info->sel, &len );
        write( hdl, buf, len );
        RCsprintf( buf, MWND_BASE, GET_DESC_BASE( desc ), &len );
        write( hdl, buf, len );
        RCsprintf( buf, MWND_LIMIT, GET_DESC_LIMIT( desc), &len );
        write( hdl, buf, len );
        if( desc.type == 2 ) {
            RCsprintf( buf, MWND_TYPE_DATA, &len );
        } else {
            RCsprintf( buf, MWND_TYPE_CODE, &len );
        }
        write( hdl, buf, len );
        sprintf( buf, "DPL:         \t%1d\n%n", desc.dpl, &len );
        write( hdl, buf, len );
        if( desc.granularity ) {
            RCsprintf( buf, MWND_GRANULARITY_PAGE, &len );
        } else {
            RCsprintf( buf, MWND_GRANULARITY_BYTE, &len );
        }
        write( hdl, buf, len );
        CreateAccessString( access, &desc );
        RCsprintf( buf, MWND_ACCESS, access, &len );
        write( hdl, buf, len );
    } else {
        ge.dwSize = sizeof( GLOBALENTRY );
        GlobalEntryHandle( &ge, (HGLOBAL)info->sel );
        RCsprintf( buf, MWND_BLOCK_ADDR, ge.dwAddress, &len );
        write( hdl, buf, len );
        RCsprintf( buf, MWND_BLOCK_HDL, ge.hBlock, &len );
        write( hdl, buf, len );
        RCsprintf( buf, MWND_BLOCK_SIZE, ge.dwBlockSize, &len );
        write( hdl, buf, len );
        RCsprintf( buf, MWND_LOCK_CNT, ge.wcLock, &len );
        write( hdl, buf, len );
        RCsprintf( buf, MWND_PAGE_LOCK_CNT, ge.wcPageLock, &len );
        write( hdl, buf, len );
    }
#endif

    type_index = info->disp_type - MEMINFO_BYTE;
    rcstr = AllocRCString( Disp_Types[type_index] );
    sprintf( buf, "%s\n\n%n", rcstr, &len );
    FreeRCString( rcstr );
    write( hdl, buf, len );
} /* MemDumpHeader */

/*
 * MemSave - save the contents of a memory display box
 */

static void MemSave( MemWndInfo *info, HWND hwnd, BOOL gen_name ) {

    char        fname[_MAX_PATH];
//    OFSTRUCT  finfo;
    DWORD       offset;
    DWORD       limit;
    int         hdl;
    size_t      len;
    BOOL        ret;
    HCURSOR     hourglass;
    HCURSOR     oldcursor;

    if( gen_name ) {
        ret = GenTmpFileName( MemConfigInfo.fname, fname );
        if( !ret ) ReportSave( hwnd, fname, MemConfigInfo.appname, ret );
    } else {
        ret = GetSaveFName( hwnd, fname );
    }
    if( ret ) {
//      hdl = OpenFile( fname, &finfo, OF_CREATE | OF_WRITE );
        hdl = open( fname, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE );
        if( hdl == -1 ) {
            ret = FALSE;
        } else {
            hourglass = LoadCursor( NULL, IDC_WAIT );
            SetCapture( hwnd );
            oldcursor= SetCursor( hourglass );
            MemDumpHeader( hdl, info );
            if( ISCODE( info ) ) {
                DumpMemAsm( info, hdl );
            } else {
                offset = info->base;
                limit = info->limit;
                while( offset < limit ) {
                    GenLine( 16, limit, info->disp_type, info->sel, Buffer,
                                offset );
                    len = strlen( Buffer );
                    write( hdl, Buffer, len );
                    write( hdl, "\n", 1 );
                    offset += 16;
                }
            }
            close( hdl );
            SetCursor( oldcursor );
            ReleaseCapture();
        }
        ReportSave( hwnd, fname, MemConfigInfo.appname, ret );
    }
} /* MemSave */

/*
 * RegMemWndClass - must be called by the first instance of a using
 *                  program to register window classes
 */

BOOL RegMemWndClass( HANDLE instance ) {

    WNDCLASS    wc;

    wc.style = 0L;
    wc.lpfnWndProc = (LPVOID) MemDisplayProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 4;
    wc.hInstance = instance;
    wc.hIcon = NULL;
    wc.hCursor = LoadCursor( NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
    wc.lpszMenuName = "MEMINFOMENU";
    wc.lpszClassName = MEM_DISPLAY_CLASS;
    return( RegisterClass( &wc ) );
} /* RegMemWndClass */

/*
 * SetMemWndConfig - set memory display window configuration info
 */

void SetMemWndConfig( MemWndConfig *cfg ) {
   MemConfigInfo = *cfg;
   MemConfigInfo.init = TRUE;
} /* SetMemWndConfig */

/*
 * GetMemWndConfig - get memory display window configuration info
 */

void GetMemWndConfig( MemWndConfig *cfg ) {
    *cfg = MemConfigInfo;
} /* GetMemWndConfig */

void GetMemWndDefault( MemWndConfig *info ) {

    info->init = TRUE;
    info->xpos = 0;
    info->ypos = 0;
    info->ysize = GetSystemMetrics( SM_CYSCREEN ) / 5;
    info->xsize = GetSystemMetrics( SM_CXSCREEN );
    info->disp_info = TRUE;
    info->maximized = FALSE;
    info->allowmult = WND_MULTI;
    strcpy( info->fname, "mem.txt" );
    info->appname = "";
    info->autopos_info = TRUE;
    info->forget_pos = FALSE;
    info->disp_type = MEMINFO_BYTE;
    info->code_disp_type = MEMINFO_CODE_16;
} /* GetMemWndDefault */

/*
 * SetDefMemConfig
 */

void SetDefMemConfig( void ) {
    GetMemWndDefault( &MemConfigInfo );
} /* SetDefMemConfig */

char MkHexDigit( char ch ) {
    if( ch < 0xA ) return( '0' + ch );
    return( 'A' + ch - 0xA );
} /* MkHexDigit */

static char *GenByte( char ch, char *ptr ) {
        *ptr = MkHexDigit( ch >> 4 );
        ptr++;
        *ptr = MkHexDigit( ch & 0xF );
        ptr++;
        return( ptr );
} /* GenByte */

/*
 * GenLine - create a line for output of the form:
XXXXXXXX  dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd  cccccccccccccccc
 */

static BOOL GenLine( char digits, DWORD limit, WORD type,
                     WORD sel, char *buf, DWORD offset )
{

    char        *ptr;
    char        pad_char;
    char        data[ MAX_BYTES ];
    size_t      len;
    unsigned    i;
#ifdef __NT__
    DWORD       bytesread;

    bytesread = ReadMem( sel, offset, data, digits );
    if( bytesread == 0 ) return( FALSE );
    pad_char = ' ';
#else
    ReadMem( sel, offset, data, digits );
    pad_char = ' ';
#endif

    sprintf( buf, "%08lX  ", offset );
    ptr = buf + 10;
    switch( type ) {
    case MEMINFO_BYTE:
        for( i=0; i < digits; i++ ) {
            if( offset + i >= limit ) {
               *ptr = pad_char;
               ptr++;
               *ptr = pad_char;
               ptr++;
            } else {
                ptr = GenByte( data[i], ptr );
            }
            *ptr = ' ';
            ptr++;
        }
//      if( i < digits ) {
//          len = ( digits - i ) * 3;
//          memset( ptr, ' ', len );
//          ptr += len;
//      }
        break;
    case MEMINFO_WORD:
        for( i=0; i < digits; i += 2 ) {
            if( offset + i == limit -1 ) {
                ptr = GenByte( data[i], ptr );
                memset( ptr, ' ', 3 );
                ptr += 3;
                i += 2;
            }
            if( offset + i >= limit ) break;
            ptr = GenByte( data[i+1], ptr );
            ptr = GenByte( data[i], ptr );
            *ptr = ' ';
            ptr++;
        }
        if( i < digits ) {
            len = ( ( digits - i ) / 2  ) * 5;
            memset( ptr, ' ', len );
            ptr += len;
        }
        break;
    case MEMINFO_DWORD:
        for( i=0; i < digits; i += 4 ) {
            if( offset + i < limit && offset + i > limit - 4 ) {
                len = 0;
                for( ; offset + i < limit ; i++ ) {
                    ptr = GenByte( data[i], ptr );
                    *ptr = ' ';
                    ptr++;
                    len += 3;

⌨️ 快捷键说明

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