mirror of
https://github.com/Proxmark/proxmark3.git
synced 2024-11-11 09:59:45 +08:00
a99c6a1921
the only reason any of the Windows code was in CPP files was because the MS compiler doesn't support C99. Switch to using MinGW, and that problem goes away, so we can rename the files back.
533 lines
14 KiB
C
533 lines
14 KiB
C
//-----------------------------------------------------------------------------
|
|
// Routines for the user interface when doing interactive things with prox
|
|
// cards; this is basically a command line thing, in one window, and then
|
|
// another window to do the graphs.
|
|
// Jonathan Westhues, Sept 2005
|
|
//-----------------------------------------------------------------------------
|
|
#include <windows.h>
|
|
#include <limits.h>
|
|
#include <commctrl.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
|
|
#include "prox.h"
|
|
|
|
#define oops() do { \
|
|
char line[100]; \
|
|
sprintf(line, "Internal error at line %d file '%s'", __LINE__, \
|
|
__FILE__); \
|
|
MessageBox(NULL, line, "Error", MB_ICONERROR); \
|
|
exit(-1); \
|
|
} while(0)
|
|
|
|
void dbp(char *str, ...)
|
|
{
|
|
va_list f;
|
|
char buf[1024];
|
|
va_start(f, str);
|
|
vsprintf(buf, str, f);
|
|
OutputDebugString(buf);
|
|
OutputDebugString("\n");
|
|
}
|
|
|
|
int GraphBuffer[MAX_GRAPH_TRACE_LEN];
|
|
int GraphTraceLen;
|
|
int PlotGridX, PlotGridY;
|
|
|
|
HPEN GreyPenLite, GreyPen, GreenPen, WhitePen, YellowPen;
|
|
HBRUSH GreenBrush, YellowBrush;
|
|
|
|
static int GraphStart = 0;
|
|
static double GraphPixelsPerPoint = 1;
|
|
|
|
static int CursorAPos;
|
|
static int CursorBPos;
|
|
double CursorScaleFactor = 1.0;
|
|
static HPEN CursorAPen;
|
|
static HPEN CursorBPen;
|
|
|
|
static HWND CommandWindow;
|
|
static HWND GraphWindow;
|
|
static HWND ScrollbackEdit;
|
|
static HWND CommandEdit;
|
|
|
|
#define COMMAND_HISTORY_MAX 16
|
|
static char CommandHistory[COMMAND_HISTORY_MAX][256];
|
|
static int CommandHistoryPos = -1;
|
|
static int CommandHistoryNext;
|
|
|
|
static HFONT MyFixedFont;
|
|
#define FixedFont(x) SendMessage((x), WM_SETFONT, (WPARAM)MyFixedFont, TRUE)
|
|
|
|
void ExecCmd(char *cmd)
|
|
{
|
|
}
|
|
|
|
int CommandFinished;
|
|
int offset = 64;
|
|
|
|
static void ResizeCommandWindow(void)
|
|
{
|
|
int w, h;
|
|
RECT r;
|
|
GetClientRect(CommandWindow, &r);
|
|
w = r.right - r.left;
|
|
h = r.bottom - r.top;
|
|
MoveWindow(ScrollbackEdit, 10, 10, w - 20, h - 50, TRUE);
|
|
MoveWindow(CommandEdit, 10, h - 29, w - 20, 22, TRUE);
|
|
}
|
|
|
|
void RepaintGraphWindow(void)
|
|
{
|
|
InvalidateRect(GraphWindow, NULL, TRUE);
|
|
}
|
|
|
|
static LRESULT CALLBACK
|
|
CommandWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (msg) {
|
|
case WM_DESTROY:
|
|
case WM_QUIT:
|
|
exit(0);
|
|
return 0;
|
|
|
|
case WM_SIZE:
|
|
ResizeCommandWindow();
|
|
return 0;
|
|
|
|
case WM_SETFOCUS:
|
|
SetFocus(CommandEdit);
|
|
break;
|
|
|
|
default:
|
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static void PaintGraph(HDC hdc)
|
|
{
|
|
RECT r;
|
|
HBRUSH brush;
|
|
HPEN pen;
|
|
char str[250];
|
|
int yMin = INT_MAX;
|
|
int yMax = INT_MIN;
|
|
int yMean = 0;
|
|
int startMax = 0;
|
|
int absYMax = 1;
|
|
int n = 0, i = 0;
|
|
|
|
brush = GreenBrush;
|
|
pen = GreenPen;
|
|
|
|
GetClientRect(GraphWindow, &r);
|
|
int zeroHeight = (r.top + r.bottom) >> 1;
|
|
|
|
// plot X and Y grid lines
|
|
if ((PlotGridX > 0) && ((PlotGridX * GraphPixelsPerPoint) > 1)) {
|
|
for(i = offset; i < r.right; i += (int)(PlotGridX * GraphPixelsPerPoint)) {
|
|
SelectObject(hdc, GreyPenLite);
|
|
MoveToEx(hdc, r.left + i, r.top, NULL);
|
|
LineTo(hdc, r.left + i, r.bottom);
|
|
}
|
|
}
|
|
|
|
if ((PlotGridY > 0) && ((PlotGridY * GraphPixelsPerPoint) > 1)){
|
|
for(i = 0; i < ((r.top + r.bottom)>>1); i += (int)(PlotGridY * GraphPixelsPerPoint)) {
|
|
SelectObject(hdc, GreyPenLite);
|
|
MoveToEx(hdc, r.left, zeroHeight + i, NULL);
|
|
LineTo(hdc, r.right, zeroHeight + i);
|
|
MoveToEx(hdc, r.left, zeroHeight - i, NULL);
|
|
LineTo(hdc, r.right, zeroHeight - i);
|
|
}
|
|
}
|
|
|
|
// print vertical separator white line on the left of the window
|
|
SelectObject(hdc, WhitePen);
|
|
MoveToEx(hdc, r.left + offset, r.top, NULL);
|
|
LineTo(hdc, r.left + offset, r.bottom);
|
|
|
|
// print horizontal grey zero axis line
|
|
SelectObject(hdc, GreyPen);
|
|
MoveToEx(hdc, r.left, zeroHeight, NULL);
|
|
LineTo(hdc, r.right, zeroHeight);
|
|
|
|
startMax = (GraphTraceLen - (int)((r.right - r.left - offset) / GraphPixelsPerPoint));
|
|
// check boundaries
|
|
if(startMax < 0) startMax = 0;
|
|
if(GraphStart > startMax) GraphStart = startMax;
|
|
if(GraphStart < 0) GraphStart = 0;
|
|
|
|
|
|
SelectObject(hdc, pen);
|
|
|
|
// go over the portion of the graph to be displayed and find the largest
|
|
// absolute value which will be used to auto scale the graph when displayed
|
|
for(i = GraphStart; ; i++) {
|
|
if(i >= GraphTraceLen) {
|
|
break;
|
|
}
|
|
if(fabs((double)GraphBuffer[i]) > absYMax) {
|
|
absYMax = (int)fabs((double)GraphBuffer[i]);
|
|
}
|
|
int x = offset + (int)((i - GraphStart)*GraphPixelsPerPoint);
|
|
if(x > r.right) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
absYMax = (int)(absYMax*1.2 + 1);
|
|
SelectObject(hdc, MyFixedFont);
|
|
SetTextColor(hdc, RGB(255, 255, 255));
|
|
SetBkColor(hdc, RGB(0, 0, 0));
|
|
|
|
// number of points that will be plotted
|
|
double span = (int)((r.right - r.left) / GraphPixelsPerPoint);
|
|
|
|
// one label every offset pixels, let us say
|
|
int labels = (r.right - r.left - offset) / offset;
|
|
if(labels <= 0) labels = 1;
|
|
// round to nearest power of 2
|
|
int pointsPerLabel = (int)(log(span / labels)/log(2.0));
|
|
if(pointsPerLabel <= 0) pointsPerLabel = 1;
|
|
pointsPerLabel = (int)pow(2.0,pointsPerLabel);
|
|
|
|
// go over the graph and plot samples and labels
|
|
for(i = GraphStart; ; i++) {
|
|
if(i >= GraphTraceLen) {
|
|
break;
|
|
}
|
|
int x = offset + (int)((i - GraphStart)*GraphPixelsPerPoint);
|
|
if(x > r.right + GraphPixelsPerPoint) {
|
|
break;
|
|
}
|
|
|
|
int y = GraphBuffer[i];
|
|
if(y < yMin) yMin = y;
|
|
if(y > yMax) yMax = y;
|
|
yMean += y;
|
|
n++;
|
|
|
|
y = (y * (r.top - r.bottom) / (2*absYMax)) + zeroHeight;
|
|
if(i == GraphStart) {
|
|
MoveToEx(hdc, x, y, NULL);
|
|
} else {
|
|
LineTo(hdc, x, y);
|
|
}
|
|
|
|
if(GraphPixelsPerPoint > 10) {
|
|
RECT f;
|
|
f.left = x - 3;
|
|
f.top = y - 3;
|
|
f.right = x + 3;
|
|
f.bottom = y + 3;
|
|
FillRect(hdc, &f, brush);
|
|
}
|
|
|
|
// plot labels
|
|
if(((i - GraphStart) % pointsPerLabel == 0) && i != GraphStart) {
|
|
SelectObject(hdc, WhitePen);
|
|
MoveToEx(hdc, x, zeroHeight - 8, NULL);
|
|
LineTo(hdc, x, zeroHeight + 8);
|
|
|
|
sprintf(str, "+%d", i);
|
|
SIZE size;
|
|
GetTextExtentPoint32(hdc, str, strlen(str), &size);
|
|
TextOut(hdc, x - size.cx, zeroHeight + 8, str, strlen(str));
|
|
|
|
SelectObject(hdc, pen);
|
|
MoveToEx(hdc, x, y, NULL);
|
|
}
|
|
|
|
// plot measurement cursors
|
|
if(i == CursorAPos || i == CursorBPos) {
|
|
if(i == CursorAPos) {
|
|
SelectObject(hdc, CursorAPen);
|
|
} else {
|
|
SelectObject(hdc, CursorBPen);
|
|
}
|
|
MoveToEx(hdc, x, r.top, NULL);
|
|
LineTo(hdc, x, r.bottom);
|
|
|
|
SelectObject(hdc, pen);
|
|
MoveToEx(hdc, x, y, NULL);
|
|
}
|
|
}
|
|
|
|
if(n != 0) {
|
|
yMean /= n;
|
|
}
|
|
|
|
// print misc information at bottom of graph window
|
|
sprintf(str, "@%d max=%d min=%d mean=%d n=%d/%d dt=%d [%.3f] zoom=%.3f CursorA=%d [%d] CursorB=%d [%d]",
|
|
GraphStart, yMax, yMin, yMean, n, GraphTraceLen,
|
|
CursorBPos - CursorAPos, (CursorBPos - CursorAPos)/CursorScaleFactor, GraphPixelsPerPoint,
|
|
CursorAPos, GraphBuffer[CursorAPos], CursorBPos, GraphBuffer[CursorBPos]);
|
|
TextOut(hdc, 50, r.bottom - 20, str, strlen(str));
|
|
}
|
|
|
|
static LRESULT CALLBACK
|
|
GraphWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (msg) {
|
|
case WM_DESTROY:
|
|
case WM_QUIT:
|
|
GraphWindow = NULL;
|
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
|
|
|
case WM_SIZE:
|
|
RepaintGraphWindow();
|
|
return 0;
|
|
|
|
case WM_PAINT: {
|
|
PAINTSTRUCT ps;
|
|
HDC hdc = BeginPaint(hwnd, &ps);
|
|
if(GraphStart < 0) {
|
|
GraphStart = 0;
|
|
}
|
|
// This draws the trace.
|
|
PaintGraph(hdc);
|
|
EndPaint(hwnd, &ps);
|
|
break;
|
|
}
|
|
case WM_KEYDOWN:
|
|
switch(wParam) {
|
|
case VK_DOWN:
|
|
if(GraphPixelsPerPoint <= 8) {
|
|
GraphPixelsPerPoint *= 2;
|
|
}
|
|
break;
|
|
|
|
case VK_UP:
|
|
if(GraphPixelsPerPoint >= 0.01) {
|
|
GraphPixelsPerPoint /= 2;
|
|
}
|
|
break;
|
|
|
|
case VK_RIGHT:
|
|
if(GraphPixelsPerPoint < 16) {
|
|
GraphStart += (int)(16 / GraphPixelsPerPoint);
|
|
} else {
|
|
GraphStart++;
|
|
}
|
|
break;
|
|
|
|
case VK_LEFT:
|
|
if(GraphPixelsPerPoint < 16) {
|
|
GraphStart -= (int)(16 / GraphPixelsPerPoint);
|
|
} else {
|
|
GraphStart--;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
goto nopaint;
|
|
}
|
|
RepaintGraphWindow();
|
|
nopaint:
|
|
break;
|
|
|
|
case WM_LBUTTONDOWN:
|
|
case WM_RBUTTONDOWN: {
|
|
int x = LOWORD(lParam);
|
|
x -= offset;
|
|
x = (int)(x / GraphPixelsPerPoint);
|
|
x += GraphStart;
|
|
|
|
if(msg == WM_LBUTTONDOWN) {
|
|
CursorAPos = x;
|
|
} else {
|
|
CursorBPos = x;
|
|
}
|
|
RepaintGraphWindow();
|
|
break;
|
|
}
|
|
default:
|
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void PrintToScrollback(char *fmt, ...)
|
|
{
|
|
va_list f;
|
|
char str[1024];
|
|
strcpy(str, "\r\n");
|
|
va_start(f, fmt);
|
|
vsprintf(str+2, fmt, f);
|
|
|
|
static char TextBuf[1024*32];
|
|
SendMessage(ScrollbackEdit, WM_GETTEXT, (WPARAM)sizeof(TextBuf),
|
|
(LPARAM)TextBuf);
|
|
|
|
if(strlen(TextBuf) + strlen(str) + 1 <= sizeof(TextBuf)) {
|
|
strcat(TextBuf, str);
|
|
} else {
|
|
lstrcpyn(TextBuf, str, sizeof(TextBuf));
|
|
}
|
|
|
|
SendMessage(ScrollbackEdit, WM_SETTEXT, 0, (LPARAM)TextBuf);
|
|
SendMessage(ScrollbackEdit, EM_LINESCROLL, 0, (LPARAM)INT_MAX);
|
|
}
|
|
|
|
void ShowGraphWindow(void)
|
|
{
|
|
if(GraphWindow) return;
|
|
|
|
GraphWindow = CreateWindowEx(0, "Graph", "graphed",
|
|
WS_OVERLAPPED | WS_BORDER | WS_MINIMIZEBOX | WS_SYSMENU |
|
|
WS_SIZEBOX | WS_VISIBLE, 200, 150, 600, 500, NULL, NULL, NULL,
|
|
NULL);
|
|
if(!GraphWindow) oops();
|
|
}
|
|
|
|
void HideGraphWindow(void)
|
|
{
|
|
if(GraphWindow) {
|
|
DestroyWindow(GraphWindow);
|
|
GraphWindow = NULL;
|
|
}
|
|
}
|
|
|
|
static void SetCommandEditTo(char *str)
|
|
{
|
|
SendMessage(CommandEdit, WM_SETTEXT, 0, (LPARAM)str);
|
|
SendMessage(CommandEdit, EM_SETSEL, strlen(str), strlen(str));
|
|
}
|
|
|
|
void ShowGui()
|
|
{
|
|
WNDCLASSEX wc;
|
|
memset(&wc, 0, sizeof(wc));
|
|
wc.cbSize = sizeof(wc);
|
|
|
|
wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_OWNDC;
|
|
wc.lpfnWndProc = (WNDPROC)CommandWindowProc;
|
|
wc.hInstance = NULL;
|
|
wc.hbrBackground = (HBRUSH)(COLOR_BTNSHADOW);
|
|
wc.lpszClassName = "Command";
|
|
wc.lpszMenuName = NULL;
|
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
|
|
if(!RegisterClassEx(&wc)) oops();
|
|
|
|
wc.lpszClassName = "Graph";
|
|
wc.lpfnWndProc = (WNDPROC)GraphWindowProc;
|
|
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
|
|
|
|
if(!RegisterClassEx(&wc)) oops();
|
|
|
|
CommandWindow = CreateWindowEx(0, "Command", "prox",
|
|
WS_OVERLAPPED | WS_BORDER | WS_MINIMIZEBOX | WS_SYSMENU |
|
|
WS_SIZEBOX | WS_VISIBLE, 20, 20, 500, 400, NULL, NULL, NULL,
|
|
NULL);
|
|
if(!CommandWindow) oops();
|
|
|
|
ScrollbackEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "edit", "",
|
|
WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | ES_MULTILINE |
|
|
ES_AUTOVSCROLL | WS_VSCROLL, 0, 0, 0, 0, CommandWindow, NULL,
|
|
NULL, NULL);
|
|
|
|
CommandEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "edit", "",
|
|
WS_CHILD | WS_CLIPSIBLINGS | WS_TABSTOP | WS_VISIBLE |
|
|
ES_AUTOHSCROLL, 0, 0, 0, 0, CommandWindow, NULL, NULL, NULL);
|
|
|
|
MyFixedFont = CreateFont(14, 0, 0, 0, FW_REGULAR, FALSE, FALSE, FALSE,
|
|
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
|
|
FF_DONTCARE, "Lucida Console");
|
|
if(!MyFixedFont)
|
|
MyFixedFont = (HFONT)GetStockObject(SYSTEM_FONT);
|
|
|
|
FixedFont(ScrollbackEdit);
|
|
FixedFont(CommandEdit);
|
|
|
|
ResizeCommandWindow();
|
|
SetFocus(CommandEdit);
|
|
|
|
PrintToScrollback(">> Started prox, built " __DATE__ " " __TIME__);
|
|
PrintToScrollback(">> Connected to device");
|
|
|
|
GreyPenLite = CreatePen(PS_SOLID, 1, RGB(50, 50, 50));
|
|
GreyPen = CreatePen(PS_SOLID, 1, RGB(100, 100, 100));
|
|
GreenPen = CreatePen(PS_SOLID, 1, RGB(100, 255, 100));
|
|
YellowPen = CreatePen(PS_SOLID, 1, RGB(255, 255, 0));
|
|
GreenBrush = CreateSolidBrush(RGB(100, 255, 100));
|
|
YellowBrush = CreateSolidBrush(RGB(255, 255, 0));
|
|
WhitePen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
|
|
|
|
CursorAPen = CreatePen(PS_DASH, 1, RGB(255, 255, 0));
|
|
CursorBPen = CreatePen(PS_DASH, 1, RGB(255, 0, 255));
|
|
|
|
MSG msg;
|
|
for(;;) {
|
|
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
|
if(msg.message == WM_KEYDOWN && msg.wParam == VK_RETURN) {
|
|
char got[1024];
|
|
SendMessage(CommandEdit, WM_GETTEXT, (WPARAM)sizeof(got),
|
|
(LPARAM)got);
|
|
|
|
if(strcmp(got, "cls")==0) {
|
|
SendMessage(ScrollbackEdit, WM_SETTEXT, 0, (LPARAM)"");
|
|
} else {
|
|
CommandReceived(got);
|
|
}
|
|
SendMessage(CommandEdit, WM_SETTEXT, 0, (LPARAM)"");
|
|
|
|
// Insert it into the command history, unless it is
|
|
// identical to the previous command in the history.
|
|
int prev = CommandHistoryNext - 1;
|
|
if(prev < 0) prev += COMMAND_HISTORY_MAX;
|
|
if(strcmp(CommandHistory[prev], got) != 0) {
|
|
strcpy(CommandHistory[CommandHistoryNext], got);
|
|
CommandHistoryNext++;
|
|
if(CommandHistoryNext == COMMAND_HISTORY_MAX) {
|
|
CommandHistoryNext = 0;
|
|
}
|
|
}
|
|
CommandHistoryPos = -1;
|
|
} else if(msg.message == WM_KEYDOWN && msg.wParam == VK_UP &&
|
|
msg.hwnd == CommandEdit)
|
|
{
|
|
if(CommandHistoryPos == -1) {
|
|
CommandHistoryPos = CommandHistoryNext;
|
|
}
|
|
CommandHistoryPos--;
|
|
if(CommandHistoryPos < 0) {
|
|
CommandHistoryPos = COMMAND_HISTORY_MAX-1;
|
|
}
|
|
SetCommandEditTo(CommandHistory[CommandHistoryPos]);
|
|
} else if(msg.message == WM_KEYDOWN && msg.wParam == VK_DOWN &&
|
|
msg.hwnd == CommandEdit)
|
|
{
|
|
CommandHistoryPos++;
|
|
if(CommandHistoryPos >= COMMAND_HISTORY_MAX) {
|
|
CommandHistoryPos = 0;
|
|
}
|
|
SetCommandEditTo(CommandHistory[CommandHistoryPos]);
|
|
} else if(msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE &&
|
|
msg.hwnd == CommandEdit)
|
|
{
|
|
SendMessage(CommandEdit, WM_SETTEXT, 0, (LPARAM)"");
|
|
} else {
|
|
if(msg.message == WM_KEYDOWN) {
|
|
CommandHistoryPos = -1;
|
|
}
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
|
|
if (!offline)
|
|
{
|
|
UsbCommand c;
|
|
if(ReceiveCommandPoll(&c))
|
|
UsbCommandReceived(&c);
|
|
}
|
|
|
|
Sleep(10);
|
|
}
|
|
}
|