📄 memwnd.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: 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 + -