2013-02-16 16:14:39 -08:00

1051 lines
23 KiB
C++

// hexvisDlg.cpp : implementation file
//
#include "stdafx.h"
#include "hexvis.h"
#include "hexvisDlg.h"
#include <float.h>
#include "Winuser.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHexvisDlg dialog
CHexvisDlg::CHexvisDlg(CWnd* pParent /*=NULL*/)
: CDialog(CHexvisDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CHexvisDlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_processed = false;
}
void CHexvisDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CHexvisDlg)
DDX_Control(pDX, IDC_STATE, m_status);
DDX_Control(pDX, IDC_BIN_REP, m_binRep);
DDX_Control(pDX, IDC_SEARCH_NUMBER, m_searchNumber);
DDX_Control(pDX, IDC_OFFSET, m_offset);
DDX_Control(pDX, IDC_UNIX_TIME, m_unix_time);
DDX_Control(pDX, IDC_STRING, m_string);
DDX_Control(pDX, IDC_SHORT_LE, m_short_le);
DDX_Control(pDX, IDC_SHORT_BE, m_short_be);
DDX_Control(pDX, IDC_REAL, m_real);
DDX_Control(pDX, IDC_PACKET_BODY, m_packetBody);
DDX_Control(pDX, IDC_LONG_LE, m_long_le);
DDX_Control(pDX, IDC_LONG_BE, m_long_be);
DDX_Control(pDX, IDC_INT64_LE, m_int64_le);
DDX_Control(pDX, IDC_INT64_BE, m_int64_be);
DDX_Control(pDX, IDC_BYTE, m_byte);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CHexvisDlg, CDialog)
//{{AFX_MSG_MAP(CHexvisDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_PROCESS, OnProcess)
ON_EN_UPDATE(IDC_PACKET_BODY, OnUpdatePacketBody)
ON_NOTIFY(EN_SELCHANGE, IDC_PACKET_BODY, OnSelchangePacketBody)
ON_BN_CLICKED(IDC_CLEAR, OnClear)
ON_BN_CLICKED(IDC_FIND_NUMBER, OnFindNumber)
ON_BN_CLICKED(IDC_LOAD_FILE, OnLoadFile)
ON_BN_CLICKED(IDC_COPY_TO_CLIP, OnCopyToClip)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHexvisDlg message handlers
BOOL CHexvisDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
m_packetBody.SetEventMask(m_packetBody.GetEventMask() | ENM_UPDATE | ENM_SELCHANGE);
CHARFORMAT cf;
cf.cbSize = sizeof(cf);
cf.dwMask = CFM_FACE;
_tcsncpy(cf.szFaceName, "Courier New", LF_FACESIZE);
m_packetBody.SetDefaultCharFormat(cf);
m_packetBody.parent = this;
return TRUE; // return TRUE unless you set the focus to a control
}
void CHexvisDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CHexvisDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CHexvisDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CHexvisDlg::OnProcess() {
CString packet;
m_packetBody.GetWindowText(packet);
m_offsetStart = -1;
m_digits.clear();
m_digits.reserve(packet.GetLength()/3);
m_lineStarts.clear();
m_processed = false;
int linelen;
const char *start = packet.GetBuffer(0);
const char *cur = start;
linelen = 0;
while(*cur != '\0') {
if(*cur == '\r' || *cur == '\n') {
ProcessLine(start, linelen);
cur++;
if(*cur == '\n')
cur++;
start = cur;
linelen = 0;
} else {
linelen++;
cur++;
}
}
if(linelen > 0)
ProcessLine(start, linelen);
DisplayDigits();
m_processed = true;
//this will trigger the sel change
m_packetBody.SetSel(8, 9);
m_status.SetWindowText("Press clear to process another block");
}
void CHexvisDlg::build_hex_line(const char *buffer, unsigned long length, unsigned long offset, unsigned char padding)
{
char out_buffer[128];
char *ptr=out_buffer;
int i;
char printable[17];
CHARFORMAT cf;
cf.cbSize = sizeof(cf);
cf.dwMask = CFM_COLOR;
cf.dwEffects = 0;
m_packetBody.SetSel(-1, -1);
sprintf(out_buffer,"%0*i:",padding, offset + m_offsetStart);
cf.crTextColor = RGB(0,0,0);
m_packetBody.SetSelectionCharFormat(cf);
m_packetBody.ReplaceSel(out_buffer, false);
m_lineStarts.push_back(m_packetBody.GetTextLength());
//m_packetBody.SetSel(-1, -1);
for(i=0;i<16; i++) {
if (i==8) {
strcpy(ptr," -");
ptr+=2;
}
if (i+offset < length) {
unsigned char c=*(const unsigned char *)(buffer+offset+i);
ptr+=sprintf(ptr," %02x",c);
printable[i]=isprint(c) ? c : '.';
} else {
ptr+=sprintf(ptr," ");
printable[i]=0;
}
}
//hex contents
cf.crTextColor = RGB(0,155,0);
m_packetBody.SetSelectionCharFormat(cf);
m_packetBody.ReplaceSel(out_buffer, false);
//ascii
sprintf(out_buffer," | %.16s\r\n",printable);
cf.crTextColor = RGB(0,0,155);
m_packetBody.SetSelectionCharFormat(cf);
m_packetBody.ReplaceSel(out_buffer, false);
}
void CHexvisDlg::DisplayDigits() {
m_packetBody.SetSel(0, -1);
m_packetBody.Clear();
int len = m_digits.size();
if(len == 0)
return;
const char *buf = (const char *) &m_digits[0];
int offset;
for(offset = 0; offset < len; offset += 16) {
build_hex_line(buf, len, offset, 4);
}
/*
CHARFORMAT cf;
cf.cbSize = sizeof(cf);
cf.dwMask = CFM_FACE;
_tcsncpy(cf.szFaceName, "Courier New", LF_FACESIZE);
m_packetBody.SetSel(0, -1);
m_packetBody.SetSelectionCharFormat(cf);*/
/*CHARFORMAT cf;
cf.cbSize = sizeof(cf);
cf.dwMask = CFM_COLOR;
cf.dwEffects = 0;
cf.crTextColor = RGB(0,0,155);
m_packetBody.SetSel(0, -1);
m_packetBody.SetSelectionCharFormat(cf);*/
m_packetBody.SetSel(-1, -1);
/*
CHARFORMAT cf;
cf.cbSize = sizeof(cf);
cf.cbSize = sizeof(CHARFORMAT);
cf.dwMask = CFM_BOLD|CFM_COLOR|CFM_ITALIC|CFM_STRIKEOUT|CFM_UNDERLINE;
cf.dwEffects = 0;
//per ANSI, he bold attribute changes the color, and does not actually bold the text.
// if(f.bold)
// cf.dwEffects |= CFE_BOLD;
if(f.italics)
cf.dwEffects |= CFE_ITALIC;
if(f.underline)
cf.dwEffects |= CFE_UNDERLINE;
if(f.strikethrough)
cf.dwEffects |= CFE_STRIKEOUT;
//f.inverse
cf.crTextColor = lt_colors[(f.bold?10:0) + f.color_index];
//bg_color_index
SetSelectionCharFormat(cf); */
}
void CHexvisDlg::ProcessLine(const char *line, int len) {
const char *startnum = NULL;
int numlen = 0;
bool maybe_hex = false;
bool found_offset = false;
for(; len > 0; len--, line++) {
switch(*line) {
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
maybe_hex = true;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if(startnum == NULL) {
startnum = line;
numlen = 1;
} else {
numlen++;
}
break;
case 'x':
if(startnum != NULL) {
if(numlen == 1) {
numlen++; //could be valid 0x notation
maybe_hex = true;
} else
startnum = NULL; //out of place.
}
break;
case ':':
case '|':
case '>':
if(found_offset) {
//this is assumed to be the start of the ascii
len = 0; //'break'
} else {
if(m_offsetStart == -1)
if(startnum != NULL) {
//we found a leading offset
std::string num(startnum, numlen);
m_offsetStart = strtoul(num.c_str(), NULL, maybe_hex?16:10);
} else {
m_offsetStart = 0;
}
found_offset = true;
}
startnum = NULL;
maybe_hex = false;
break;
case ' ':
case '\t':
case '-':
if(!found_offset) {
if(startnum != NULL) {
if(_ProcessDigits(startnum, numlen)) {
if(m_offsetStart == -1)
m_offsetStart = 0;
found_offset = true;
}
} else {
//just leading junk... do nothing
}
} else {
if(startnum != NULL) {
_ProcessDigits(startnum, numlen);
}
}
startnum = NULL;
maybe_hex = false;
break;
default:
startnum = NULL;
maybe_hex = false;
break;
}
}
if(startnum != NULL) {
if(m_offsetStart == -1)
m_offsetStart = 0;
_ProcessDigits(startnum, numlen);
}
}
bool CHexvisDlg::_ProcessDigits(const char *startnum, int numlen) {
/*if(numlen == 2) {
std::string num(startnum, 2);
unsigned char digit = strtoul(num.c_str(), NULL, 16);
m_digits.push_back(digit);
return(true);
} else if(numlen == 4) {
std::string num(startnum, 2);
unsigned char digit = strtoul(num.c_str(), NULL, 16);
m_digits.push_back(digit);
std::string num2(startnum+2, 2);
digit = strtoul(num2.c_str(), NULL, 16);
m_digits.push_back(digit);
return(true);
} else */
if(numlen > 0 && (numlen & 0x1) == 0) {
//an even number of hex digits, divide them in twos
int doffset;
for(doffset = 0; doffset < numlen; doffset += 2) {
std::string num(startnum+doffset, 2);
unsigned char digit = strtoul(num.c_str(), NULL, 16);
m_digits.push_back(digit);
}
return(true);
}
return(false);
}
void CHexvisDlg::AnalyzeBytes(int byte) {
CString s;
int maxlen = m_digits.size() - byte;
const unsigned char *bptr = (const unsigned char *) &m_digits[byte];
s.Format("%d = 0x%X", byte+m_offsetStart, byte+m_offsetStart);
m_offset.SetWindowText(s);
if(maxlen >= sizeof(char)) {
s.Format("0x%02X = %d = %c", *bptr, *bptr, *bptr);
m_byte.SetWindowText(s);
s.Format("%.*s", maxlen, bptr);
m_string.SetWindowText(s);
CString b;
s = "";
int r;
for(r = 0; r < 1 && r < maxlen; r++) {
unsigned char cb = *(bptr+r);
b.Format("%d%d%d%d %d%d%d%d",
(cb&0x80)>>7,
(cb&0x40)>>6,
(cb&0x20)>>5,
(cb&0x10)>>4,
(cb&0x08)>>3,
(cb&0x04)>>2,
(cb&0x02)>>1,
(cb&0x01) );
if(!s.IsEmpty())
s += " - ";
s += b;
}
m_binRep.SetWindowText(s);
} else {
m_byte.SetWindowText("");
m_binRep.SetWindowText("");
m_string.SetWindowText("");
}
if(maxlen >= sizeof(short)) {
const unsigned short *le = (const unsigned short *) bptr;
signed short sle = *le;
unsigned short be = ((*le & 0xFF)<<8) | ((*le &0xFF00)>>8);
signed short sbe = be;
s.Format("0x%04X = %d = %u", *le, sle, *le);
m_short_le.SetWindowText(s);
s.Format("0x%04X = %d = %u", be, sbe, be);
m_short_be.SetWindowText(s);
} else {
m_short_le.SetWindowText("");
m_short_be.SetWindowText("");
}
if(maxlen >= sizeof(long)) {
const unsigned long *le = (const unsigned long *) bptr;
signed long sle = *le;
unsigned long be =
((*le & 0x000000FF) <<24)
| ((*le & 0x0000FF00L)<<8)
| ((*le & 0x00FF0000L)>>8)
| ((*le & 0xFF000000L)>>24)
;
signed long sbe = be;
s.Format("0x%08lX = %ld = %lu", *le, sle, *le);
m_long_le.SetWindowText(s);
s.Format("0x%08lX = %ld = %lu", be, sbe, be);
m_long_be.SetWindowText(s);
std::string tt;
time_t t = *le;
const char *p = ctime(&t);
if(p == NULL)
p = "(ERROR)";
tt = p;
t = be;
p = ctime(&t);
if(p == NULL)
p = "(ERROR)";
s.Format("%s | %s", tt.c_str(), p);
m_unix_time.SetWindowText(s);
} else {
m_long_le.SetWindowText("");
m_long_be.SetWindowText("");
m_unix_time.SetWindowText("");
}
if(maxlen >= sizeof(float)) {
const float *f = (const float *) bptr;
if(maxlen >= sizeof(double)) {
const double *d = (const double *) bptr;
s.Format("%.13f %.13f", *f, *d);
m_real.SetWindowText(s);
} else {
s.Format("%.13f", *f);
m_real.SetWindowText(s);
}
} else {
m_real.SetWindowText("");
}
if(maxlen >= sizeof(__int64)) {
const unsigned __int64 *le = (const unsigned __int64 *) bptr;
signed __int64 sle = *le;
unsigned __int64 be =
((*le & 0x00000000000000FF)<<56)
| ((*le & 0x000000000000FF00)<<40)
| ((*le & 0x0000000000FF0000)<<24)
| ((*le & 0x00000000FF000000)<<8)
| ((*le & 0x000000FF00000000)>>8)
| ((*le & 0x0000FF0000000000)>>24)
| ((*le & 0x00FF000000000000)>>40)
| ((*le & 0xFF00000000000000)>>56)
;
signed __int64 sbe = be;
s.Format("0x%I64X = %I64d = %I64u", *le, sle, *le);
m_int64_le.SetWindowText(s);
s.Format("0x%I64X = %I64d = %I64u", be, sbe, be);
m_int64_be.SetWindowText(s);
} else {
m_int64_le.SetWindowText("");
m_int64_be.SetWindowText("");
}
}
void CHexvisDlg::OnUpdatePacketBody()
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CDialog::OnInitDialog()
// function to send the EM_SETEVENTMASK message to the control
// with the ENM_UPDATE flag ORed into the lParam mask.
// TODO: Add your control notification handler code here
}
void CHexvisDlg::OnSelchangePacketBody(NMHDR* pNMHDR, LRESULT* pResult)
{
SELCHANGE *pSelChange = reinterpret_cast<SELCHANGE *>(pNMHDR);
// TODO: The control will not send this notification unless you override the
// CDialog::OnInitDialog() function to send the EM_SETEVENTMASK message
// to the control with the ENM_SELCHANGE flag ORed into the lParam mask.
static int line_mid = 3*8;
static int ascii_start = 3*16 + 3;
static int ascii_end = 3*16 + 5 + 16;
if(m_processed) {
long start, end;
m_packetBody.GetSel(start, end);
if(start != -1) {
int line = m_packetBody.LineFromChar(start);
if(line >= 0 && line < m_lineStarts.size()) {
int lstart = m_lineStarts[line]+1;
int loffset = start - lstart;
if(loffset > line_mid)
loffset -= 2;
int coffset;
if(loffset <= 0)
coffset = 0;
else if(loffset < ascii_start) {
coffset = (loffset / 3);
if(coffset >= 16)
coffset = 15;
} else if(loffset < ascii_end) {
//into the ascii section
coffset = (loffset-ascii_start);
} else {
coffset = 15;
}
int abscoffset = coffset + line*16;
if(abscoffset >= m_digits.size()) {
int diff = 1 + abscoffset - m_digits.size();
coffset -= diff;
abscoffset -= diff;
}
int seloffset = lstart + 3*coffset;
if(coffset >= 8)
seloffset += 2;
//they have selected byte 'abscoffset'
AnalyzeBytes(abscoffset);
m_activeByte = abscoffset;
m_packetBody.SetSel(seloffset, seloffset + 2);
}
}
}
*pResult = 0;
}
void CHexvisDlg::SelectByte(int byte) {
if(byte < 0)
byte = 0;
if(byte >= m_digits.size())
byte = m_digits.size()-1;
int seloffset = 0;
if(byte > 0) {
//first figure out what line its on...
//then figure out the char offset into that line.
int line = byte/16;
int coffset = byte%16;
int lstart = m_lineStarts[line]+1;
seloffset = lstart + 3*coffset;
if(coffset >= 8)
seloffset += 2;
m_activeByte = byte;
}
//this will trigger a sel change which will update the fields
m_packetBody.SetSel(seloffset, seloffset + 2);
}
void CHexvisDlg::OnClear()
{
m_processed = false;
m_activeByte = -1;
m_packetBody.SetSel(0, -1);
m_packetBody.Clear();
m_status.SetWindowText("Paste text above an process");
}
static __int64 _strtoll(char *str)
{
__int64 result = 0;
int negative=0;
while (*str == ' ' || *str == '\t')
str++;
if (*str == '+')
str++;
else if (*str == '-') {
negative = 1;
str++;
}
while (*str >= '0' && *str <= '9') {
result = (result*10)+(*str++ - '0');
}
return negative ? -result : result;
}
void CHexvisDlg::OnFindNumber()
{
if(!m_processed || m_digits.empty())
return;
CString num;
m_searchNumber.GetWindowText(num);
const char *buf = num.GetBuffer(0);
if(buf[0] == '\0')
return;
FindSpec s;
//we dont handle unsigned 64 bit ints very well.
s.intval = strtol(buf, NULL, 0);
s.dval = strtod(buf, NULL);
s.fval = s.dval; //only cast it down once.
int bytecount = m_digits.size();
int sval = m_activeByte;
int eval = bytecount-1;
if(sval < 1) {
sval = 0;
} else {
eval = sval;
sval++;
}
m_status.SetWindowText("Searching...");
bool found = false;
while(true) {
if(sval >= bytecount)
sval = 0;
if(FindNumber(sval, &s)) {
SelectByte(sval);
found = true;
break;
}
if(sval == eval)
break;
sval++;
}
if(!found)
m_status.SetWindowText("Not found");
}
static bool isnormal(double f) {
int c = _fpclass(f);
return(
(c & (_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF)) == 0
);
}
static void _findDebug() {
static int x;
x++;
}
bool CHexvisDlg::FindNumber(int byte, const FindSpec *f) {
int maxlen = m_digits.size() - byte;
const unsigned char *bptr = (const unsigned char *) &m_digits[byte];
if(maxlen >= sizeof(char)) {
if(*bptr == f->intval) {
_findDebug();
m_status.SetWindowText("Found as a byte");
return(true);
}
}
if(maxlen >= sizeof(short)) {
const unsigned short *le = (const unsigned short *) bptr;
signed short sle = *le;
unsigned short be = ((*le & 0xFF)<<8) | ((*le &0xFF00)>>8);
signed short sbe = be;
if(*le == f->intval) {
m_status.SetWindowText("Found as a native short");
_findDebug();
return(true);
}
if(sle == f->intval) {
m_status.SetWindowText("Found as a signed native short");
_findDebug();
return(true);
}
if(be == f->intval) {
m_status.SetWindowText("Found as a swapped short");
_findDebug();
return(true);
}
if(sbe == f->intval) {
m_status.SetWindowText("Found as a signed swapped short");
_findDebug();
return(true);
}
}
if(maxlen >= sizeof(long)) {
const unsigned long *le = (const unsigned long *) bptr;
signed long sle = *le;
unsigned long be =
((*le & 0x000000FF) <<24)
| ((*le & 0x0000FF00L)<<8)
| ((*le & 0x00FF0000L)>>8)
| ((*le & 0xFF000000L)>>24)
;
signed long sbe = be;
if(*le == f->intval) {
m_status.SetWindowText("Found as a native long");
_findDebug();
return(true);
}
if(sle == f->intval) {
m_status.SetWindowText("Found as a signed native long");
_findDebug();
return(true);
}
if(be == f->intval) {
m_status.SetWindowText("Found as a swapped long");
_findDebug();
return(true);
}
if(sbe == f->intval) {
m_status.SetWindowText("Found as a signed swapped long");
_findDebug();
return(true);
}
}
if(f->fval != 0.0f && maxlen >= sizeof(float)) {
const float *fv = (const float *) bptr;
if(isnormal(*fv)) {
if(*fv == f->fval) {
m_status.SetWindowText("Found as a float");
_findDebug();
return(true);
}
if(__int64(*fv) == f->intval) {
m_status.SetWindowText("Found as a rounded float");
_findDebug();
return(true);
}
}
}
if(f->dval != 0.0f && maxlen >= sizeof(double)) {
const double *d = (const double *) bptr;
if(isnormal(*d)) {
if(*d == f->dval) {
m_status.SetWindowText("Found as a double");
_findDebug();
return(true);
}
if(__int64(*d) == f->intval) {
m_status.SetWindowText("Found as a rounded double");
_findDebug();
return(true);
}
}
}
if(maxlen >= sizeof(__int64)) {
const unsigned __int64 *le = (const unsigned __int64 *) bptr;
signed __int64 sle = *le;
unsigned __int64 be =
((*le & 0x00000000000000FF)<<56)
| ((*le & 0x000000000000FF00)<<40)
| ((*le & 0x0000000000FF0000)<<24)
| ((*le & 0x00000000FF000000)<<8)
| ((*le & 0x000000FF00000000)>>8)
| ((*le & 0x0000FF0000000000)>>24)
| ((*le & 0x00FF000000000000)>>40)
| ((*le & 0xFF00000000000000)>>56)
;
signed __int64 sbe = be;
if(*le == f->intval) {
m_status.SetWindowText("Found as a native int64");
_findDebug();
return(true);
}
if(sle == f->intval) {
m_status.SetWindowText("Found as a signed native int64");
_findDebug();
return(true);
}
if(be == f->intval) {
m_status.SetWindowText("Found as a swapped int64");
_findDebug();
return(true);
}
if(sbe == f->intval) {
m_status.SetWindowText("Found as a signed swapped int64");
_findDebug();
return(true);
}
}
return(false);
}
void CHexvisDlg::PrevByte() {
if(m_activeByte > 0)
SelectByte(m_activeByte-1);
}
void CHexvisDlg::NextByte() {
int t = m_activeByte+1;
if(t < m_digits.size())
SelectByte(t);
}
void CHexvisDlg::PrevLine() {
if(m_activeByte == 0)
return;
if(m_activeByte > 15)
SelectByte(m_activeByte-16);
else
SelectByte(0);
}
void CHexvisDlg::NextLine() {
int max = m_digits.size();
if((m_activeByte+16) < max)
SelectByte(m_activeByte+16);
else
SelectByte(max-1);
}
void CHexvisDlg::OnLoadFile()
{
CFileDialog *fileopendialog = new CFileDialog( true, NULL, NULL,
OFN_HIDEREADONLY ,
"Any Raw File (*.*)|*.*||", this );
if ( fileopendialog->DoModal() == IDOK ) {
HANDLE hFile;
hFile = CreateFile(fileopendialog->GetPathName(),
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(hFile == INVALID_HANDLE_VALUE) {
m_status.SetWindowText("Failed to open file.");
return;
}
int size = GetFileSize(hFile, NULL);
m_offsetStart = 0;
m_digits.clear();
m_digits.resize(size);
m_lineStarts.clear();
m_processed = false;
DWORD out;
if(!ReadFile(hFile, &m_digits[0], size, &out, NULL)) {
m_status.SetWindowText("Failed to load file.");
m_digits.resize(0);
return;
}
CloseHandle(hFile);
DisplayDigits();
m_processed = true;
//this will trigger the sel change
m_packetBody.SetSel(8, 9);
m_status.SetWindowText("Press clear to process another block");
}
}
void CHexvisDlg::OnCopyToClip()
{
bool v = m_processed;
if(v) {
m_processed = false;
}
m_packetBody.SetSel(0, -1);
m_packetBody.Copy();
if(v) {
m_processed = true;
m_packetBody.SetSel(8, 9);
}
}