Code:
#include "Editor.hpp"
void m(const char *m) {
MessageBoxA(0,m,m,0);
}
void error(const char *msg) {
MessageBoxA(0,msg,"Psych Hex Editor|Error",0);
}
void Console::init(const char* title) {
cHandle = (HANDLE)GetStdHandle(STD_OUTPUT_HANDLE);
if (cHandle == INVALID_HANDLE_VALUE) {
error("Invalid handle value of std output handle.");
}
SetConsoleTitle(title);
}
void Console::clear() {
for (int x = 0; x < 80; x++) {
for (int y = 0; y < 25; y++) {
console_buffer[y][x].Char.AsciiChar = '\0';
console_buffer[y][x].Attributes = FOREGROUND_GREEN | BACKGROUND_BLUE;
}
}
}
void Console::write(int x, int y, const char *c, WORD attributes) {
int len = strlen(c);
for (int i = 0; i < len; i++) {
console_buffer[y][x+i].Char.AsciiChar = c[i];
console_buffer[y][x+i].Attributes = attributes;
}
}
void Console::render() {
COORD size = {80,25};
COORD pos = {0,0};
SMALL_RECT region = {0,0,79,24};
WriteConsoleOutput(cHandle,(CHAR_INFO*)console_buffer,size,pos,®ion);
}
void HexEditor::draw(Console *g) {
char outBuf[80];
if (hasFile) {
sprintf(outBuf,"%s %f kb",fname,(float)fsize/1024);
} else {
sprintf(outBuf,"No File Loaded");
}
g->write(0,0,outBuf,FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY|BACKGROUND_BLUE);
char out[4];
scrollAmount = sTimes*16;
if (hasFile) {
for (lc = 0; lc < fsize; lc++) {
if (lc < 304 && lc+scrollAmount < fsize) {
switch (mode) {
case 0:
sprintf(out,"x%x",edit[lc+scrollAmount].data);
break;
case 1:
sprintf(out,"%c",edit[lc+scrollAmount].data);
break;
}
if (selected == lc+scrollAmount) {
if (editMode) {
g->write(edit[lc+scrollAmount].x,edit[lc+scrollAmount].y-sTimes,out,FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY);
} else {
g->write(edit[lc+scrollAmount].x,edit[lc+scrollAmount].y-sTimes,out,FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_GREEN);
}
} else {
g->write(edit[lc+scrollAmount].x,edit[lc+scrollAmount].y-sTimes,out,BACKGROUND_BLUE|BACKGROUND_RED|BACKGROUND_GREEN);
}
}
}
}
}
void HexEditor::select(int add) {
if (selected+add < 0 || selected+add == fsize || selected+add > fsize) {
return;
}
selected += add;
}
void HexEditor::scroll(int add) {
if (sTimes+add < 0 || sTimes+add > (fsize-288)/16) {
return;
}
sTimes += add;
}
void HexEditor::switchmodes() {
if (mode != 1 || mode > 1) {
mode++;
} else {
mode = 0;
}
gen_edit();
}
void HexEditor::load_file() {
OPENFILENAME ofn;
ZeroMemory(&ofn,sizeof(ofn));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFilter = "All Files (*.*)\0*.*\0";
ofn.lpstrFile = completePath;
ofn.nMaxFile = 255;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST;
ofn.lpstrDefExt = "";
if (GetOpenFileName(&ofn)) {
hasFile = true;
grab_file_info();
}
}
void HexEditor::grab_file_info() {
SHFILEINFOA sfi = {0};
SHGetFileInfo(completePath,-1,&sfi,sizeof(sfi),SHGFI_DISPLAYNAME);
sprintf(fname,"%s",sfi.szDisplayName);
FILE *fp = fopen(completePath,"rb");
fseek(fp,0,SEEK_END);
fsize = ftell(fp);
fseek(fp,0,SEEK_SET);
fileByte = (char*)malloc(sizeof(char)*fsize);
fread(fileByte,1,fsize,fp);
fclose(fp);
gen_edit();
}
void HexEditor::gen_edit() {
edit = (Editable*)malloc(sizeof(Editable)*fsize);
short currX = 0;
int currY = 3;
for (lc = 0; lc < fsize; lc++) {
if (fileByte[lc] < 0x20 && mode == 1) {
edit[lc].data = ' ';
} else {
edit[lc].data = fileByte[lc];
}
edit[lc].x = currX;
edit[lc].y = currY;
if (currX != 75) {
currX += 5;
} else {
currY++;
currX = 0;
}
}
}
void HexEditor::go_edit(Console *g) {
editMode = true;
if (mode == 0) {
g->clear();
g->write(0,24,"Please enter a valid hexadecimal number-",FOREGROUND_GREEN|BACKGROUND_BLUE);
draw(g);
g->render();
short hex;
char c[4];
c[0] = '0';
c[1] = 'x';
c[2] = getch();
if ((c[2] > 0x29 && c[2] < 0x3A) || (c[2] > 0x60 && c[2] < 0x67) || (c[2] > 0x40 && c[2] < 0x47)) {
sscanf(c,"%x",&hex);
edit[selected].data = (char)hex;
g->clear();
g->write(0,24,"Please enter a valid hexadecimal number-",FOREGROUND_GREEN|BACKGROUND_BLUE);
draw(g);
g->render();
c[3] = getch();
if ((c[3] > 0x29 && c[3] < 0x3A) || (c[3] > 0x60 && c[3] < 0x67) || (c[2] > 0x40 && c[2] < 0x47)) {
sscanf(c,"%x",&hex);
edit[selected].data = (char)hex;
fileByte[selected] = (char)hex;
editMode = false;
return;
} else {
editMode = false;
return;
}
} else {
editMode = false;
return;
}
}
if (mode == 1) {
g->clear();
g->write(0,24,"Please enter a new character-",FOREGROUND_GREEN|BACKGROUND_BLUE);
draw(g);
g->render();
char c = getch();
if (c > 0x19 && c < 0x7F) {
edit[selected].data = c;
fileByte[selected] = c;
editMode = false;
return;
} else {
editMode = false;
return;
}
}
}
void HexEditor::save() {
OPENFILENAME ofn;
char sfilePath[255];
ZeroMemory(&ofn,sizeof(ofn));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFilter = "All Files (*.*)\0*.*\0";
ofn.lpstrFile = sfilePath;
ofn.nMaxFile = 255;
ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST;
ofn.lpstrInitialDir = completePath;
ofn.lpstrDefExt = "";
if (GetSaveFileName(&ofn)) {
FILE *fp = fopen(sfilePath,"wb");
fwrite(fileByte,fsize,1,fp);
fclose(fp);
}
}
void HexEditor::findbytes(Console *g) {
char texBuf[255],text[64],bytes[24];
memset(text,'\0',64);
short currLen = 0;
sprintf(texBuf,"Please enter bytes to find(FORMAT=0x??,0x??)->");
g->clear();
g->write(0,23,"Press escape to exit find",FOREGROUND_GREEN|BACKGROUND_BLUE);
g->write(0,24,texBuf,FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY|BACKGROUND_BLUE);
draw(g);
g->render();
bool end = false;
char in;
while (!end) {
in = getch();
if (in == VK_ESCAPE) {
end = true;
} else {
if (in == VK_BACK) {
if (currLen != 0) {
text[currLen-1] = '\0';
currLen--;
}
} else {
if (in != VK_RETURN) {
text[currLen] = in;
currLen++;
}
}
sprintf(texBuf,"Please enter bytes to find(FORMAT=0x??,0x??)->%s",text);
if (currLen%5 == 0) {
converttobytes(bytes,text);
findandselect(bytes);
}
g->clear();
g->write(0,23,"Press escape to exit find",FOREGROUND_GREEN|BACKGROUND_BLUE);
g->write(0,24,texBuf,FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY|BACKGROUND_BLUE);
draw(g);
g->render();
}
}
}
void HexEditor::converttobytes(char *bytebuf, const char* text) {
short currByte = 0,currBB = 0;
char currBytebuf[4];
int sLen = strlen(text);
for (int i = 0; i < sLen; i++) {
if (text[i] != ',') {
currBytebuf[currByte] = text[i];
} else {
currByte = 0;
int in;
sscanf(text,"%x",&in);
bytebuf[currBB] = (char)in;
currBB++;
}
}
}
void HexEditor::findtext(Console *g) {
char texBuf[255],text[64];
memset(text,'\0',64);
short currLen = 0;
sprintf(texBuf,"Please enter text to find->");
g->clear();
g->write(0,23,"Press escape to exit find",FOREGROUND_GREEN|BACKGROUND_BLUE);
g->write(0,24,texBuf,FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY|BACKGROUND_BLUE);
draw(g);
g->render();
bool end = false;
char in;
while (!end) {
in = getch();
if (in == VK_ESCAPE) {
end = true;
} else {
if (in == VK_BACK) {
if (currLen != 0) {
text[currLen-1] = '\0';
currLen--;
}
} else {
if (in != VK_RETURN) {
text[currLen] = in;
currLen++;
}
}
sprintf(texBuf,"Please enter text to find->%s",text);
findandselect(text);
g->clear();
g->write(0,23,"Press escape to exit find",FOREGROUND_GREEN|BACKGROUND_BLUE);
g->write(0,24,texBuf,FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY|BACKGROUND_BLUE);
draw(g);
g->render();
}
}
}
void HexEditor::find(Console* g) {
switch (mode) {
case 0:
findbytes(g);
break;
case 1:
findtext(g);
break;
}
}
void HexEditor::findandselect(const char *find) {
char fBuf[64];
memset(fBuf,'\0',64);
int flen = strlen(find);
for (lc = selected; lc < fsize; lc++) {
for (int i = 0; i < flen; i++) {
fBuf[i] = fileByte[lc+i];
}
if (!strcmp(fBuf,find)) {
selected = lc;
if ((lc-288)/16 < 0) {
sTimes = 0;
} else {
sTimes = (lc-288)/16;
}
return;
}
}
}