merge linux and windows clients into one directory... will consolidate makefiles shortly

This commit is contained in:
bushing 2009-12-22 12:11:15 +00:00
parent e3dfa42772
commit cd00aa3043
27 changed files with 9 additions and 9 deletions

40
client/Makefile Normal file
View file

@ -0,0 +1,40 @@
#COMMON_FLAGS = -m32
LDLIBS = -L/usr/local/lib -lusb -lreadline -lpthread
LDFLAGS = $(COMMON_FLAGS)
CFLAGS = -I. -I/opt/local/include -Wall -Wno-unused-function $(COMMON_FLAGS)
CXXFLAGS = $(shell pkg-config --cflags QtCore QtGui 2>/dev/null) -Wall
QTLDLIBS = $(shell pkg-config --libs QtCore QtGui 2>/dev/null)
ifneq ($(QTLDLIBS),)
QTGUI = proxgui.o proxguiqt.o proxguiqt.moc.o
CFLAGS += -DHAVE_GUI
MOC = $(shell type moc-qt4 >/dev/null 2>&1 && echo moc-qt4 || echo moc)
LINK.o = $(LINK.cpp)
else
QTGUI = guidummy.o
endif
all: proxmark3 snooper cli flasher
all-static: LDLIBS:=-static $(LDLIBS)
all-static: snooper cli flasher
proxmark3: LDLIBS+=$(QTLDLIBS)
proxmark3: proxmark3.o gui.o command.o usb.o $(QTGUI)
command.o: command.cpp translate.h
snooper: snooper.o gui.o command.o usb.o guidummy.o
cli: cli.o gui.o command.o usb.o guidummy.o
flasher: flasher.o usb.o
proxguiqt.moc.cpp: proxguiqt.h
$(MOC) -o$@ $^
clean:
rm -f cli flasher proxmark3 snooper *.o *.moc.cpp
.PHONY: all clean

33
client/Makefile.win Normal file
View file

@ -0,0 +1,33 @@
CC=cl
BASE_DIR ?= "..\..\devkitWIN"
BASE_DEFS = /D_WIN32_WINNT=0x501 /DISOLATION_AWARE_ENABLED /D_WIN32_IE=0x600 /DWIN32_LEAN_AND_MEAN /DWIN32 /D_MT /D_CRT_SECURE_NO_WARNINGS
BASE_CFLAGS = /W3 /nologo /Zi /MT /Fdobj/vc90.pdb
LIB = $(BASE_DIR)\lib
DEFINES = $(BASE_DEFS)
INCLUDES = /I$(BASE_DIR)\include
CFLAGS = $(BASE_CFLAGS) $(INCLUDES)
OBJDIR = obj
OBJS = $(OBJDIR)\prox.obj \
$(OBJDIR)\gui.obj \
$(OBJDIR)\command.obj
LIBS = $(LIB)\user32.lib $(LIB)\gdi32.lib $(LIB)\setupapi.lib $(LIB)\libcmt.lib $(LIB)\oldnames.lib $(LIB)\kernel32.lib
all: proxmark3
proxmark3:
$(CC) $(CFLAGS) $(DEFINES) -c -Foobj/prox.obj prox.cpp
$(CC) $(CFLAGS) $(DEFINES) -c -Foobj/gui.obj gui.cpp
$(CC) $(CFLAGS) $(DEFINES) -c -Foobj/command.obj command.cpp
$(CC) $(CFLAGS) $(DEFINES) -Fe$(OBJDIR)/prox.exe $(OBJS) $(LIBS)
copy obj\prox.exe .
clean:
del /q obj\*.obj
del /q obj\*.ilk
del /q obj\*.exe
del /q obj\*.pdb
del prox.exe

61
client/cli.c Normal file
View file

@ -0,0 +1,61 @@
#include <usb.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <errno.h>
#include "translate.h"
#include "prox.h"
#include "proxmark3.h"
#define HANDLE_ERROR if (error_occured) { \
error_occured = 0;\
break;\
}
int main(int argc, char **argv)
{
if(argc != 3 && argc != 4)
{
printf("\n\tusage: cli <command 1> <command 2> [logfile (default cli.log)]\n");
printf("\n");
printf("\texample: cli hi14asnoop hi14alist h14a.log\n");
printf("\n");
return -1;
}
usb_init();
if (argc == 4)
setlogfilename(argv[3]);
else
setlogfilename("cli.log");
return_on_error = 1;
while(1) {
while(!(devh=OpenProxmark(0))) { sleep(1); }
while(1) {
UsbCommand cmdbuf;
int i;
CommandReceived(argv[1]);
HANDLE_ERROR
ReceiveCommand(&cmdbuf);
HANDLE_ERROR
for (i=0; i<5; i++) {
ReceiveCommandP(&cmdbuf);
}
HANDLE_ERROR
CommandReceived(argv[2]);
HANDLE_ERROR
}
}
CloseProxmark();
return 0;
}

2
client/command.c Normal file
View file

@ -0,0 +1,2 @@
#include "translate.h"
#include "command.cpp"

3093
client/command.cpp Normal file

File diff suppressed because it is too large Load diff

355
client/flasher.c Normal file
View file

@ -0,0 +1,355 @@
#include <usb.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "translate.h"
#include "prox.h"
#include "proxmark3.h"
static DWORD ExpectedAddr;
static BYTE QueuedToSend[256];
static BOOL AllWritten;
#define PHYSICAL_FLASH_START 0x100000
struct partition {
int start;
int end;
int precious;
const char *name;
};
struct partition partitions[] = {
{0x100000, 0x102000, 1, "bootrom"},
{0x102000, 0x110000, 0, "fpga"},
{0x110000, 0x140000, 0, "os"},
};
/* If translate is set, subtract PHYSICAL_FLASH_START to translate for old
* bootroms.
*/
static void FlushPrevious(int translate)
{
UsbCommand c;
memset(&c, 0, sizeof(c));
printf("expected = %08x flush, ", ExpectedAddr);
int i;
for(i = 0; i < 240; i += 48) {
c.cmd = CMD_SETUP_WRITE;
memcpy(c.d.asBytes, QueuedToSend+i, 48);
c.ext1 = (i/4);
SendCommand(&c, TRUE);
}
c.cmd = CMD_FINISH_WRITE;
c.ext1 = (ExpectedAddr-1) & (~255);
if(translate) {
c.ext1 -= PHYSICAL_FLASH_START;
}
printf("c.ext1 = %08x\r", c.ext1);
memcpy(c.d.asBytes, QueuedToSend+240, 16);
SendCommand(&c, TRUE);
AllWritten = TRUE;
}
/* Where must be between start_addr (inclusive) and end_addr (exclusive).
*/
static void GotByte(DWORD where, BYTE which, int start_addr, int end_addr, int translate)
{
AllWritten = FALSE;
if(where < start_addr || where >= end_addr) {
printf("bad: got byte at %08x, outside of range %08x-%08x\n", where, start_addr, end_addr);
exit(-1);
}
if(where != ExpectedAddr) {
printf("bad: got at %08x, expected at %08x\n", where, ExpectedAddr);
exit(-1);
}
QueuedToSend[where & 255] = which;
ExpectedAddr++;
if((where & 255) == 255) {
// we have completed a full page
FlushPrevious(translate);
}
}
static int HexVal(int c)
{
c = tolower(c);
if(c >= '0' && c <= '9') {
return c - '0';
} else if(c >= 'a' && c <= 'f') {
return (c - 'a') + 10;
} else {
printf("bad hex digit '%c'\n", c);
exit(-1);
}
}
static BYTE HexByte(char *s)
{
return (HexVal(s[0]) << 4) | HexVal(s[1]);
}
static void LoadFlashFromSRecords(const char *file, int start_addr, int end_addr, int translate)
{
ExpectedAddr = start_addr;
FILE *f = fopen(file, "r");
if(!f) {
printf("couldn't open file\n");
exit(-1);
}
char line[512];
while(fgets(line, sizeof(line), f)) {
if(memcmp(line, "S3", 2)==0) {
char *s = line + 2;
int len = HexByte(s) - 5;
s += 2;
char addrStr[9];
memcpy(addrStr, s, 8);
addrStr[8] = '\0';
DWORD addr;
sscanf(addrStr, "%x", &addr);
s += 8;
/* Accept files that are located at PHYSICAL_FLASH_START, and files that are located at 0 */
if(addr < PHYSICAL_FLASH_START)
addr += PHYSICAL_FLASH_START;
int i;
for(i = 0; i < len; i++) {
while((addr+i) > ExpectedAddr) {
GotByte(ExpectedAddr, 0xff, start_addr, end_addr, translate);
}
GotByte(addr+i, HexByte(s), start_addr, end_addr, translate);
s += 2;
}
}
}
if(!AllWritten) FlushPrevious(translate);
fclose(f);
printf("\ndone.\n");
}
static int PrepareFlash(struct partition *p, const char *filename, unsigned int state)
{
int translate = 0;
if(state & DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) {
UsbCommand c;
c.cmd = CMD_START_FLASH;
c.ext1 = p->start;
c.ext2 = p->end;
/* Only send magic when flashing bootrom */
if(p->precious) {
c.ext3 = START_FLASH_MAGIC;
} else {
c.ext3 = 0;
}
SendCommand(&c, TRUE);
translate = 0;
} else {
fprintf(stderr, "Warning: Your bootloader does not understand the new START_FLASH command\n");
fprintf(stderr, " It is recommended that you update your bootloader\n\n");
translate = 1;
}
LoadFlashFromSRecords(filename, p->start, p->end, translate);
return 1;
}
static unsigned int GetProxmarkState(void)
{
unsigned int state = 0;
UsbCommand c;
c.cmd = CMD_DEVICE_INFO;
SendCommand(&c, FALSE);
UsbCommand resp;
ReceiveCommand(&resp);
/* Three cases:
* 1. The old bootrom code will ignore CMD_DEVICE_INFO, but respond with an ACK
* 2. The old os code will respond with CMD_DEBUG_PRINT_STRING and "unknown command"
* 3. The new bootrom and os codes will respond with CMD_DEVICE_INFO and flags
*/
switch(resp.cmd) {
case CMD_ACK:
state = DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM;
break;
case CMD_DEBUG_PRINT_STRING:
state = DEVICE_INFO_FLAG_CURRENT_MODE_OS;
break;
case CMD_DEVICE_INFO:
state = resp.ext1;
break;
default:
fprintf(stderr, "Couldn't get proxmark state, bad response type: 0x%04X\n", resp.cmd);
exit(-1);
break;
}
#if 0
if(state & DEVICE_INFO_FLAG_BOOTROM_PRESENT) printf("New bootrom present\n");
if(state & DEVICE_INFO_FLAG_OSIMAGE_PRESENT) printf("New osimage present\n");
if(state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM) printf("Currently in bootrom\n");
if(state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) printf("Currently in OS\n");
#endif
return state;
}
static unsigned int EnterFlashState(void)
{
unsigned int state = GetProxmarkState();
if(state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM) {
/* Already in flash state, we're done. */
return state;
}
if(state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) {
fprintf(stderr,"Entering flash-mode...\n");
UsbCommand c;
bzero(&c, sizeof(c));
if( (state & DEVICE_INFO_FLAG_BOOTROM_PRESENT) && (state & DEVICE_INFO_FLAG_OSIMAGE_PRESENT) ) {
/* New style handover: Send CMD_START_FLASH, which will reset the board and
* enter the bootrom on the next boot.
*/
c.cmd = CMD_START_FLASH;
SendCommand(&c, FALSE);
fprintf(stderr,"(You don't have to do anything. Press and release the button only if you want to abort)\n");
fprintf(stderr,"Waiting for Proxmark to reappear on USB... ");
} else {
/* Old style handover: Ask the user to press the button, then reset the board */
c.cmd = CMD_HARDWARE_RESET;
SendCommand(&c, FALSE);
fprintf(stderr,"(Press and hold down button NOW if your bootloader requires it)\n");
fprintf(stderr,"Waiting for Proxmark to reappear on USB... ");
}
CloseProxmark();
sleep(1);
while(!(devh=OpenProxmark(0))) { sleep(1); }
fprintf(stderr,"Found.\n");
return GetProxmarkState();
}
return 0;
}
static void usage(char **argv)
{
int i;
fprintf(stderr, "Usage: %s areas image [image [image]]\n", argv[0]);
fprintf(stderr, " areas is a comma-separated list of areas to flash, with no spaces\n");
fprintf(stderr, " Known areas are:");
for(i=0; i<(sizeof(partitions)/sizeof(partitions[0])); i++) {
fprintf(stderr, " %s", partitions[i].name);
}
fprintf(stderr, "\n");
fprintf(stderr, " image is the path to the corresponding image\n\n");
fprintf(stderr, "Example: %s os,fpga path/to/osimage.s19 path/to/fpgaimage.s19\n", argv[0]);
}
/* On first call, have *offset = -1, *length = 0; */
static int find_next_area(const char *str, int *offset, int *length)
{
if(*str == '\0') return 0;
if((*offset >= 0) && str[*offset + *length] == '\0') return 0;
*offset += 1 + *length;
char *next_comma = strchr(str + *offset, ',');
if(next_comma == NULL) {
*length = strlen(str) - *offset;
} else {
*length = next_comma-(str+*offset);
}
return 1;
}
int main(int argc, char **argv) {
if(argc < 2) {
usage(argv);
exit(-1);
}
/* Count area arguments */
int areas = 0, offset=-1, length=0;
while(find_next_area(argv[1], &offset, &length)) areas++;
if(areas != argc - 2) {
usage(argv);
exit(-1);
}
usb_init();
fprintf(stderr,"Waiting for Proxmark to appear on USB... ");
while(!(devh=OpenProxmark(0))) { sleep(1); }
fprintf(stderr,"Found.\n");
unsigned int state = EnterFlashState();
if( !(state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM) ) {
fprintf(stderr, "Proxmark would not enter flash state, abort\n");
exit(-1);
}
offset=-1; length=0;
int current_area = 0;
while(find_next_area(argv[1], &offset, &length)) {
int i;
struct partition *p = NULL;
for(i=0; i<sizeof(partitions)/sizeof(partitions[0]); i++) {
if(strncmp(partitions[i].name, argv[1] + offset, length) == 0) {
/* Check if the name matches the bootrom partition, and if so, require "bootrom" to
* be written in full. The other names may be abbreviated.
*/
if(!partitions[i].precious || (strlen(partitions[i].name) == length)) {
p = &partitions[i];
}
break;
}
}
if(p == NULL) {
fprintf(stderr, "Warning: area name '");
fwrite(argv[1]+offset, length, 1, stderr);
fprintf(stderr, "' unknown, ignored\n");
} else {
fprintf(stderr, "Flashing %s from %s\n", p->name, argv[2+current_area]);
PrepareFlash(p, argv[2+current_area], state);
}
current_area++;
}
UsbCommand c;
bzero(&c, sizeof(c));
c.cmd = CMD_HARDWARE_RESET;
SendCommand(&c, FALSE);
CloseProxmark();
fprintf(stderr,"Have a nice day!\n");
return 0;
}

58
client/gui.c Normal file
View file

@ -0,0 +1,58 @@
#include <stdarg.h>
#include <stdio.h>
#include <time.h>
#include "proxgui.h"
#include "translate.h"
#include "prox.h"
int GraphBuffer[MAX_GRAPH_TRACE_LEN];
int GraphTraceLen;
double CursorScaleFactor;
int PlotGridX, PlotGridY;
int CommandFinished;
int offline;
static char *logfilename = "proxmark3.log";
void PrintToScrollback(char *fmt, ...) {
va_list argptr, argptr2;
static FILE *logfile = NULL;
static int logging=1;
if (logging && !logfile) {
logfile=fopen(logfilename, "a");
if (!logfile) {
fprintf(stderr, "Can't open logfile, logging disabled!\n");
logging=0;
}
}
va_start(argptr, fmt);
va_copy(argptr2, argptr);
vprintf(fmt, argptr);
va_end(argptr);
printf("\n");
if (logging && logfile) {
#if 0
char zeit[25];
time_t jetzt_t;
struct tm *jetzt;
jetzt_t = time(NULL);
jetzt = localtime(&jetzt_t);
strftime(zeit, 25, "%b %e %T", jetzt);
fprintf(logfile,"%s ", zeit);
#endif
vfprintf(logfile, fmt, argptr2);
fprintf(logfile,"\n");
fflush(logfile);
}
va_end(argptr2);
}
void setlogfilename(char *fn)
{
logfilename = fn;
}

533
client/gui.cpp Normal file
View file

@ -0,0 +1,533 @@
//-----------------------------------------------------------------------------
// 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);
}
}

17
client/guidummy.c Normal file
View file

@ -0,0 +1,17 @@
#include <stdio.h>
void ShowGraphWindow(void)
{
static int warned = 0;
if (!warned) {
printf("No GUI in this build!\n");
warned = 1;
}
}
void HideGraphWindow(void) {}
void RepaintGraphWindow(void) {}
void MainGraphics() {}
void InitGraphics(int argc, char **argv) {}
void ExitGraphics(void) {}

1787
client/include/hidpi.h Normal file

File diff suppressed because it is too large Load diff

412
client/include/hidsdi.h Normal file
View file

@ -0,0 +1,412 @@
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
HIDSDI.H
Abstract:
This module contains the PUBLIC definitions for the
code that implements the HID dll.
Environment:
Kernel & user mode
--*/
#ifndef _HIDSDI_H
#define _HIDSDI_H
#include <pshpack4.h>
//#include "wtypes.h"
//#include <windef.h>
//#include <win32.h>
//#include <basetyps.h>
typedef LONG NTSTATUS;
#include "hidusage.h"
#include "hidpi.h"
typedef struct _HIDD_CONFIGURATION {
PVOID cookie;
ULONG size;
ULONG RingBufferSize;
} HIDD_CONFIGURATION, *PHIDD_CONFIGURATION;
typedef struct _HIDD_ATTRIBUTES {
ULONG Size; // = sizeof (struct _HIDD_ATTRIBUTES)
//
// Vendor ids of this hid device
//
USHORT VendorID;
USHORT ProductID;
USHORT VersionNumber;
//
// Additional fields will be added to the end of this structure.
//
} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
BOOLEAN __stdcall
HidD_GetAttributes (
IN HANDLE HidDeviceObject,
OUT PHIDD_ATTRIBUTES Attributes
);
/*++
Routine Description:
Fill in the given HIDD_ATTRIBUTES structure with the attributes of the
given hid device.
--*/
void __stdcall
HidD_GetHidGuid (
OUT LPGUID HidGuid
);
BOOLEAN __stdcall
HidD_GetPreparsedData (
IN HANDLE HidDeviceObject,
OUT PHIDP_PREPARSED_DATA * PreparsedData
);
/*++
Routine Description:
Given a handle to a valid Hid Class Device Object, retrieve the preparsed
data for the device. This routine will allocate the appropriately
sized buffer to hold this preparsed data. It is up to client to call
HidP_FreePreparsedData to free the memory allocated to this structure when
it is no longer needed.
Arguments:
HidDeviceObject A handle to a Hid Device that the client obtains using
a call to CreateFile on a valid Hid device string name.
The string name can be obtained using standard PnP calls.
PreparsedData An opaque data structure used by other functions in this
library to retrieve information about a given device.
Return Value:
TRUE if successful.
FALSE otherwise -- Use GetLastError() to get extended error information
--*/
BOOLEAN __stdcall
HidD_FreePreparsedData (
IN PHIDP_PREPARSED_DATA PreparsedData
);
BOOLEAN __stdcall
HidD_FlushQueue (
IN HANDLE HidDeviceObject
);
/*++
Routine Description:
Flush the input queue for the given HID device.
Arguments:
HidDeviceObject A handle to a Hid Device that the client obtains using
a call to CreateFile on a valid Hid device string name.
The string name can be obtained using standard PnP calls.
Return Value:
TRUE if successful
FALSE otherwise -- Use GetLastError() to get extended error information
--*/
BOOLEAN __stdcall
HidD_GetConfiguration (
IN HANDLE HidDeviceObject,
OUT PHIDD_CONFIGURATION Configuration,
IN ULONG ConfigurationLength
);
/*++
Routine Description:
Get the configuration information for this Hid device
Arguments:
HidDeviceObject A handle to a Hid Device Object.
Configuration A configuration structure. HidD_GetConfiguration MUST
be called before the configuration can be modified and
set using HidD_SetConfiguration
ConfigurationLength That is ``sizeof (HIDD_CONFIGURATION)''. Using this
parameter, we can later increase the length of the
configuration array and not break older apps.
Return Value:
TRUE if successful
FALSE otherwise -- Use GetLastError() to get extended error information
--*/
BOOLEAN __stdcall
HidD_SetConfiguration (
IN HANDLE HidDeviceObject,
IN PHIDD_CONFIGURATION Configuration,
IN ULONG ConfigurationLength
);
/*++
Routine Description:
Set the configuration information for this Hid device...
NOTE: HidD_GetConfiguration must be called to retrieve the current
configuration information before this information can be modified
and set.
Arguments:
HidDeviceObject A handle to a Hid Device Object.
Configuration A configuration structure. HidD_GetConfiguration MUST
be called before the configuration can be modified and
set using HidD_SetConfiguration
ConfigurationLength That is ``sizeof (HIDD_CONFIGURATION)''. Using this
parameter, we can later increase the length of the
configuration array and not break older apps.
Return Value:
TRUE if successful
FALSE otherwise -- Use GetLastError() to get extended error information
--*/
BOOLEAN __stdcall
HidD_GetFeature (
IN HANDLE HidDeviceObject,
OUT PVOID ReportBuffer,
IN ULONG ReportBufferLength
);
/*++
Routine Description:
Retrieve a feature report from a HID device.
Arguments:
HidDeviceObject A handle to a Hid Device Object.
ReportBuffer The buffer that the feature report should be placed
into. The first byte of the buffer should be set to
the report ID of the desired report
ReportBufferLength The size (in bytes) of ReportBuffer. This value
should be greater than or equal to the
FeatureReportByteLength field as specified in the
HIDP_CAPS structure for the device
Return Value:
TRUE if successful
FALSE otherwise -- Use GetLastError() to get extended error information
--*/
BOOLEAN __stdcall
HidD_SetFeature (
IN HANDLE HidDeviceObject,
IN PVOID ReportBuffer,
IN ULONG ReportBufferLength
);
/*++
Routine Description:
Send a feature report to a HID device.
Arguments:
HidDeviceObject A handle to a Hid Device Object.
ReportBuffer The buffer of the feature report to send to the device
ReportBufferLength The size (in bytes) of ReportBuffer. This value
should be greater than or equal to the
FeatureReportByteLength field as specified in the
HIDP_CAPS structure for the device
Return Value:
TRUE if successful
FALSE otherwise -- Use GetLastError() to get extended error information
--*/
BOOLEAN __stdcall
HidD_GetNumInputBuffers (
IN HANDLE HidDeviceObject,
OUT PULONG NumberBuffers
);
/*++
Routine Description:
This function returns the number of input buffers used by the specified
file handle to the Hid device. Each file object has a number of buffers
associated with it to queue reports read from the device but which have
not yet been read by the user-mode app with a handle to that device.
Arguments:
HidDeviceObject A handle to a Hid Device Object.
NumberBuffers Number of buffers currently being used for this file
handle to the Hid device
Return Value:
TRUE if successful
FALSE otherwise -- Use GetLastError() to get extended error information
--*/
BOOLEAN __stdcall
HidD_SetNumInputBuffers (
IN HANDLE HidDeviceObject,
OUT ULONG NumberBuffers
);
/*++
Routine Description:
This function sets the number of input buffers used by the specified
file handle to the Hid device. Each file object has a number of buffers
associated with it to queue reports read from the device but which have
not yet been read by the user-mode app with a handle to that device.
Arguments:
HidDeviceObject A handle to a Hid Device Object.
NumberBuffers New number of buffers to use for this file handle to
the Hid device
Return Value:
TRUE if successful
FALSE otherwise -- Use GetLastError() to get extended error information
--*/
BOOLEAN __stdcall
HidD_GetPhysicalDescriptor (
IN HANDLE HidDeviceObject,
OUT PVOID Buffer,
IN ULONG BufferLength
);
/*++
Routine Description:
This function retrieves the raw physical descriptor for the specified
Hid device.
Arguments:
HidDeviceObject A handle to a Hid Device Object.
Buffer Buffer which on return will contain the physical
descriptor if one exists for the specified device
handle
BufferLength Length of buffer (in bytes)
Return Value:
TRUE if successful
FALSE otherwise -- Use GetLastError() to get extended error information
--*/
BOOLEAN __stdcall
HidD_GetManufacturerString (
IN HANDLE HidDeviceObject,
OUT PVOID Buffer,
IN ULONG BufferLength
);
/*++
Routine Description:
This function retrieves the manufacturer string from the specified
Hid device.
Arguments:
HidDeviceObject A handle to a Hid Device Object.
Buffer Buffer which on return will contain the manufacturer
string returned from the device. This string is a
wide-character string
BufferLength Length of Buffer (in bytes)
Return Value:
TRUE if successful
FALSE otherwise -- Use GetLastError() to get extended error information
--*/
BOOLEAN __stdcall
HidD_GetProductString (
IN HANDLE HidDeviceObject,
OUT PVOID Buffer,
IN ULONG BufferLength
);
/*++
Routine Description:
This function retrieves the product string from the specified
Hid device.
Arguments:
HidDeviceObject A handle to a Hid Device Object.
Buffer Buffer which on return will contain the product
string returned from the device. This string is a
wide-character string
BufferLength Length of Buffer (in bytes)
Return Value:
TRUE if successful
FALSE otherwise -- Use GetLastError() to get extended error information
--*/
BOOLEAN __stdcall
HidD_GetIndexedString (
IN HANDLE HidDeviceObject,
IN ULONG StringIndex,
OUT PVOID Buffer,
IN ULONG BufferLength
);
/*++
Routine Description:
This function retrieves a string from the specified Hid device that is
specified with a certain string index.
Arguments:
HidDeviceObject A handle to a Hid Device Object.
StringIndex Index of the string to retrieve
Buffer Buffer which on return will contain the product
string returned from the device. This string is a
wide-character string
BufferLength Length of Buffer (in bytes)
Return Value:
TRUE if successful
FALSE otherwise -- Use GetLastError() to get extended error information
--*/
BOOLEAN __stdcall
HidD_GetSerialNumberString (
IN HANDLE HidDeviceObject,
OUT PVOID Buffer,
IN ULONG BufferLength
);
/*++
Routine Description:
This function retrieves the serial number string from the specified
Hid device.
Arguments:
HidDeviceObject A handle to a Hid Device Object.
Buffer Buffer which on return will contain the serial number
string returned from the device. This string is a
wide-character string
BufferLength Length of Buffer (in bytes)
Return Value:
TRUE if successful
FALSE otherwise -- Use GetLastError() to get extended error information
--*/
#include <poppack.h>
#endif

263
client/include/hidusage.h Normal file
View file

@ -0,0 +1,263 @@
/*++
Copyright (c) 1996, 1997 Microsoft Corporation
Module Name:
HIDUSAGE.H
Abstract:
Public Definitions of HID USAGES.
Environment:
Kernel & user mode
--*/
#ifndef __HIDUSAGE_H__
#define __HIDUSAGE_H__
//
// Usage Pages
//
typedef USHORT USAGE, *PUSAGE;
#define HID_USAGE_PAGE_GENERIC ((USAGE) 0x01)
#define HID_USAGE_PAGE_SIMULATION ((USAGE) 0x02)
#define HID_USAGE_PAGE_VR ((USAGE) 0x03)
#define HID_USAGE_PAGE_SPORT ((USAGE) 0x04)
#define HID_USAGE_PAGE_GAME ((USAGE) 0x05)
#define HID_USAGE_PAGE_KEYBOARD ((USAGE) 0x07)
#define HID_USAGE_PAGE_LED ((USAGE) 0x08)
#define HID_USAGE_PAGE_BUTTON ((USAGE) 0x09)
#define HID_USAGE_PAGE_ORDINAL ((USAGE) 0x0A)
#define HID_USAGE_PAGE_TELEPHONY ((USAGE) 0x0B)
#define HID_USAGE_PAGE_CONSUMER ((USAGE) 0x0C)
#define HID_USAGE_PAGE_DIGITIZER ((USAGE) 0x0D)
#define HID_USAGE_PAGE_UNICODE ((USAGE) 0x10)
#define HID_USAGE_PAGE_ALPHANUMERIC ((USAGE) 0x14)
//
// Usages from Generic Desktop Page (0x01)
//
#define HID_USAGE_GENERIC_POINTER ((USAGE) 0x01)
#define HID_USAGE_GENERIC_MOUSE ((USAGE) 0x02)
#define HID_USAGE_GENERIC_JOYSTICK ((USAGE) 0x04)
#define HID_USAGE_GENERIC_GAMEPAD ((USAGE) 0x05)
#define HID_USAGE_GENERIC_KEYBOARD ((USAGE) 0x06)
#define HID_USAGE_GENERIC_KEYPAD ((USAGE) 0x07)
#define HID_USAGE_GENERIC_SYSTEM_CTL ((USAGE) 0x80)
#define HID_USAGE_GENERIC_X ((USAGE) 0x30)
#define HID_USAGE_GENERIC_Y ((USAGE) 0x31)
#define HID_USAGE_GENERIC_Z ((USAGE) 0x32)
#define HID_USAGE_GENERIC_RX ((USAGE) 0x33)
#define HID_USAGE_GENERIC_RY ((USAGE) 0x34)
#define HID_USAGE_GENERIC_RZ ((USAGE) 0x35)
#define HID_USAGE_GENERIC_SLIDER ((USAGE) 0x36)
#define HID_USAGE_GENERIC_DIAL ((USAGE) 0x37)
#define HID_USAGE_GENERIC_WHEEL ((USAGE) 0x38)
#define HID_USAGE_GENERIC_HATSWITCH ((USAGE) 0x39)
#define HID_USAGE_GENERIC_COUNTED_BUFFER ((USAGE) 0x3A)
#define HID_USAGE_GENERIC_BYTE_COUNT ((USAGE) 0x3B)
#define HID_USAGE_GENERIC_MOTION_WAKEUP ((USAGE) 0x3C)
#define HID_USAGE_GENERIC_VX ((USAGE) 0x40)
#define HID_USAGE_GENERIC_VY ((USAGE) 0x41)
#define HID_USAGE_GENERIC_VZ ((USAGE) 0x42)
#define HID_USAGE_GENERIC_VBRX ((USAGE) 0x43)
#define HID_USAGE_GENERIC_VBRY ((USAGE) 0x44)
#define HID_USAGE_GENERIC_VBRZ ((USAGE) 0x45)
#define HID_USAGE_GENERIC_VNO ((USAGE) 0x46)
#define HID_USAGE_GENERIC_SYSCTL_POWER ((USAGE) 0x81)
#define HID_USAGE_GENERIC_SYSCTL_SLEEP ((USAGE) 0x82)
#define HID_USAGE_GENERIC_SYSCTL_WAKE ((USAGE) 0x83)
#define HID_USAGE_GENERIC_SYSCTL_CONTEXT_MENU ((USAGE) 0x84)
#define HID_USAGE_GENERIC_SYSCTL_MAIN_MENU ((USAGE) 0x85)
#define HID_USAGE_GENERIC_SYSCTL_APP_MENU ((USAGE) 0x86)
#define HID_USAGE_GENERIC_SYSCTL_HELP_MENU ((USAGE) 0x87)
#define HID_USAGE_GENERIC_SYSCTL_MENU_EXIT ((USAGE) 0x88)
#define HID_USAGE_GENERIC_SYSCTL_MENU_SELECT ((USAGE) 0x89)
#define HID_USAGE_GENERIC_SYSCTL_MENU_RIGHT ((USAGE) 0x8A)
#define HID_USAGE_GENERIC_SYSCTL_MENU_LEFT ((USAGE) 0x8B)
#define HID_USAGE_GENERIC_SYSCTL_MENU_UP ((USAGE) 0x8C)
#define HID_USAGE_GENERIC_SYSCTL_MENU_DOWN ((USAGE) 0x8D)
//
// Usages from Simulation Controls Page (0x02)
//
#define HID_USAGE_SIMULATION_RUDDER ((USAGE) 0xBA)
#define HID_USAGE_SIMULATION_THROTTLE ((USAGE) 0xBB)
//
// Virtual Reality Controls Page (0x03)
//
//
// Sport Controls Page (0x04)
//
//
// Game Controls Page (0x05)
//
//
// Keyboard/Keypad Page (0x07)
//
// Error "keys"
#define HID_USAGE_KEYBOARD_NOEVENT ((USAGE) 0x00)
#define HID_USAGE_KEYBOARD_ROLLOVER ((USAGE) 0x01)
#define HID_USAGE_KEYBOARD_POSTFAIL ((USAGE) 0x02)
#define HID_USAGE_KEYBOARD_UNDEFINED ((USAGE) 0x03)
// Letters
#define HID_USAGE_KEYBOARD_aA ((USAGE) 0x04)
#define HID_USAGE_KEYBOARD_zZ ((USAGE) 0x1D)
// Numbers
#define HID_USAGE_KEYBOARD_ONE ((USAGE) 0x1E)
#define HID_USAGE_KEYBOARD_ZERO ((USAGE) 0x27)
// Modifier Keys
#define HID_USAGE_KEYBOARD_LCTRL ((USAGE) 0xE0)
#define HID_USAGE_KEYBOARD_LSHFT ((USAGE) 0xE1)
#define HID_USAGE_KEYBOARD_LALT ((USAGE) 0xE2)
#define HID_USAGE_KEYBOARD_LGUI ((USAGE) 0xE3)
#define HID_USAGE_KEYBOARD_RCTRL ((USAGE) 0xE4)
#define HID_USAGE_KEYBOARD_RSHFT ((USAGE) 0xE5)
#define HID_USAGE_KEYBOARD_RALT ((USAGE) 0xE6)
#define HID_USAGE_KEYBOARD_RGUI ((USAGE) 0xE7)
#define HID_USAGE_KEYBOARD_SCROLL_LOCK ((USAGE) 0x47)
#define HID_USAGE_KEYBOARD_NUM_LOCK ((USAGE) 0x53)
#define HID_USAGE_KEYBOARD_CAPS_LOCK ((USAGE) 0x39)
// Funtion keys
#define HID_USAGE_KEYBOARD_F1 ((USAGE) 0x3A)
#define HID_USAGE_KEYBOARD_F12 ((USAGE) 0x45)
#define HID_USAGE_KEYBOARD_RETURN ((USAGE) 0x28)
#define HID_USAGE_KEYBOARD_ESCAPE ((USAGE) 0x29)
#define HID_USAGE_KEYBOARD_DELETE ((USAGE) 0x2A)
#define HID_USAGE_KEYBOARD_PRINT_SCREEN ((USAGE) 0x46)
// and hundreds more...
//
// LED Page (0x08)
//
#define HID_USAGE_LED_NUM_LOCK ((USAGE) 0x01)
#define HID_USAGE_LED_CAPS_LOCK ((USAGE) 0x02)
#define HID_USAGE_LED_SCROLL_LOCK ((USAGE) 0x03)
#define HID_USAGE_LED_COMPOSE ((USAGE) 0x04)
#define HID_USAGE_LED_KANA ((USAGE) 0x05)
#define HID_USAGE_LED_POWER ((USAGE) 0x06)
#define HID_USAGE_LED_SHIFT ((USAGE) 0x07)
#define HID_USAGE_LED_DO_NOT_DISTURB ((USAGE) 0x08)
#define HID_USAGE_LED_MUTE ((USAGE) 0x09)
#define HID_USAGE_LED_TONE_ENABLE ((USAGE) 0x0A)
#define HID_USAGE_LED_HIGH_CUT_FILTER ((USAGE) 0x0B)
#define HID_USAGE_LED_LOW_CUT_FILTER ((USAGE) 0x0C)
#define HID_USAGE_LED_EQUALIZER_ENABLE ((USAGE) 0x0D)
#define HID_USAGE_LED_SOUND_FIELD_ON ((USAGE) 0x0E)
#define HID_USAGE_LED_SURROUND_FIELD_ON ((USAGE) 0x0F)
#define HID_USAGE_LED_REPEAT ((USAGE) 0x10)
#define HID_USAGE_LED_STEREO ((USAGE) 0x11)
#define HID_USAGE_LED_SAMPLING_RATE_DETECT ((USAGE) 0x12)
#define HID_USAGE_LED_SPINNING ((USAGE) 0x13)
#define HID_USAGE_LED_CAV ((USAGE) 0x14)
#define HID_USAGE_LED_CLV ((USAGE) 0x15)
#define HID_USAGE_LED_RECORDING_FORMAT_DET ((USAGE) 0x16)
#define HID_USAGE_LED_OFF_HOOK ((USAGE) 0x17)
#define HID_USAGE_LED_RING ((USAGE) 0x18)
#define HID_USAGE_LED_MESSAGE_WAITING ((USAGE) 0x19)
#define HID_USAGE_LED_DATA_MODE ((USAGE) 0x1A)
#define HID_USAGE_LED_BATTERY_OPERATION ((USAGE) 0x1B)
#define HID_USAGE_LED_BATTERY_OK ((USAGE) 0x1C)
#define HID_USAGE_LED_BATTERY_LOW ((USAGE) 0x1D)
#define HID_USAGE_LED_SPEAKER ((USAGE) 0x1E)
#define HID_USAGE_LED_HEAD_SET ((USAGE) 0x1F)
#define HID_USAGE_LED_HOLD ((USAGE) 0x20)
#define HID_USAGE_LED_MICROPHONE ((USAGE) 0x21)
#define HID_USAGE_LED_COVERAGE ((USAGE) 0x22)
#define HID_USAGE_LED_NIGHT_MODE ((USAGE) 0x23)
#define HID_USAGE_LED_SEND_CALLS ((USAGE) 0x24)
#define HID_USAGE_LED_CALL_PICKUP ((USAGE) 0x25)
#define HID_USAGE_LED_CONFERENCE ((USAGE) 0x26)
#define HID_USAGE_LED_STAND_BY ((USAGE) 0x27)
#define HID_USAGE_LED_CAMERA_ON ((USAGE) 0x28)
#define HID_USAGE_LED_CAMERA_OFF ((USAGE) 0x29)
#define HID_USAGE_LED_ON_LINE ((USAGE) 0x2A)
#define HID_USAGE_LED_OFF_LINE ((USAGE) 0x2B)
#define HID_USAGE_LED_BUSY ((USAGE) 0x2C)
#define HID_USAGE_LED_READY ((USAGE) 0x2D)
#define HID_USAGE_LED_PAPER_OUT ((USAGE) 0x2E)
#define HID_USAGE_LED_PAPER_JAM ((USAGE) 0x2F)
#define HID_USAGE_LED_REMOTE ((USAGE) 0x30)
#define HID_USAGE_LED_FORWARD ((USAGE) 0x31)
#define HID_USAGE_LED_REVERSE ((USAGE) 0x32)
#define HID_USAGE_LED_STOP ((USAGE) 0x33)
#define HID_USAGE_LED_REWIND ((USAGE) 0x34)
#define HID_USAGE_LED_FAST_FORWARD ((USAGE) 0x35)
#define HID_USAGE_LED_PLAY ((USAGE) 0x36)
#define HID_USAGE_LED_PAUSE ((USAGE) 0x37)
#define HID_USAGE_LED_RECORD ((USAGE) 0x38)
#define HID_USAGE_LED_ERROR ((USAGE) 0x39)
#define HID_USAGE_LED_SELECTED_INDICATOR ((USAGE) 0x3A)
#define HID_USAGE_LED_IN_USE_INDICATOR ((USAGE) 0x3B)
#define HID_USAGE_LED_MULTI_MODE_INDICATOR ((USAGE) 0x3C)
#define HID_USAGE_LED_INDICATOR_ON ((USAGE) 0x3D)
#define HID_USAGE_LED_INDICATOR_FLASH ((USAGE) 0x3E)
#define HID_USAGE_LED_INDICATOR_SLOW_BLINK ((USAGE) 0x3F)
#define HID_USAGE_LED_INDICATOR_FAST_BLINK ((USAGE) 0x40)
#define HID_USAGE_LED_INDICATOR_OFF ((USAGE) 0x41)
#define HID_USAGE_LED_FLASH_ON_TIME ((USAGE) 0x42)
#define HID_USAGE_LED_SLOW_BLINK_ON_TIME ((USAGE) 0x43)
#define HID_USAGE_LED_SLOW_BLINK_OFF_TIME ((USAGE) 0x44)
#define HID_USAGE_LED_FAST_BLINK_ON_TIME ((USAGE) 0x45)
#define HID_USAGE_LED_FAST_BLINK_OFF_TIME ((USAGE) 0x46)
#define HID_USAGE_LED_INDICATOR_COLOR ((USAGE) 0x47)
#define HID_USAGE_LED_RED ((USAGE) 0x48)
#define HID_USAGE_LED_GREEN ((USAGE) 0x49)
#define HID_USAGE_LED_AMBER ((USAGE) 0x4A)
#define HID_USAGE_LED_GENERIC_INDICATOR ((USAGE) 0x3B)
//
// Button Page (0x09)
//
// There is no need to label these usages.
//
//
// Ordinal Page (0x0A)
//
// There is no need to label these usages.
//
//
// Telephony Device Page (0x0B)
//
#define HID_USAGE_TELEPHONY_PHONE ((USAGE) 0x01)
#define HID_USAGE_TELEPHONY_ANSWERING_MACHINE ((USAGE) 0x02)
#define HID_USAGE_TELEPHONY_MESSAGE_CONTROLS ((USAGE) 0x03)
#define HID_USAGE_TELEPHONY_HANDSET ((USAGE) 0x04)
#define HID_USAGE_TELEPHONY_HEADSET ((USAGE) 0x05)
#define HID_USAGE_TELEPHONY_KEYPAD ((USAGE) 0x06)
#define HID_USAGE_TELEPHONY_PROGRAMMABLE_BUTTON ((USAGE) 0x07)
//
// and others...
//
#endif

0
client/obj/.dummy Normal file
View file

580
client/prox.cpp Normal file
View file

@ -0,0 +1,580 @@
#include <windows.h>
#include <setupapi.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
extern "C" {
#include "include/hidsdi.h"
#include "include/hidpi.h"
}
#include "prox.h"
#define OUR_VID 0x9ac4
#define OUR_PID 0x4b8f
#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
int offline = 0;
HANDLE UsbHandle;
static void ShowError(void)
{
char buf[1024];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,
buf, sizeof(buf), NULL);
printf("ERROR: %s", buf);
}
static BOOL UsbConnect(void)
{
typedef void (__stdcall *GetGuidProc)(GUID *);
typedef BOOLEAN (__stdcall *GetAttrProc)(HANDLE, HIDD_ATTRIBUTES *);
typedef BOOLEAN (__stdcall *GetPreparsedProc)(HANDLE,
PHIDP_PREPARSED_DATA *);
typedef NTSTATUS (__stdcall *GetCapsProc)(PHIDP_PREPARSED_DATA, PHIDP_CAPS);
GetGuidProc getGuid;
GetAttrProc getAttr;
GetPreparsedProc getPreparsed;
GetCapsProc getCaps;
HMODULE h = LoadLibrary("hid.dll");
getGuid = (GetGuidProc)GetProcAddress(h, "HidD_GetHidGuid");
getAttr = (GetAttrProc)GetProcAddress(h, "HidD_GetAttributes");
getPreparsed = (GetPreparsedProc)GetProcAddress(h, "HidD_GetPreparsedData");
getCaps = (GetCapsProc)GetProcAddress(h, "HidP_GetCaps");
GUID hidGuid;
getGuid(&hidGuid);
HDEVINFO devInfo;
devInfo = SetupDiGetClassDevs(&hidGuid, NULL, NULL,
DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
SP_DEVICE_INTERFACE_DATA devInfoData;
devInfoData.cbSize = sizeof(devInfoData);
int i;
for(i = 0;; i++) {
if(!SetupDiEnumDeviceInterfaces(devInfo, 0, &hidGuid, i, &devInfoData))
{
if(GetLastError() != ERROR_NO_MORE_ITEMS) {
// printf("SetupDiEnumDeviceInterfaces failed\n");
}
// printf("done list\n");
SetupDiDestroyDeviceInfoList(devInfo);
return FALSE;
}
// printf("item %d:\n", i);
DWORD sizeReqd = 0;
if(!SetupDiGetDeviceInterfaceDetail(devInfo, &devInfoData,
NULL, 0, &sizeReqd, NULL))
{
if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
// printf("SetupDiGetDeviceInterfaceDetail (0) failed\n");
continue;
}
}
SP_DEVICE_INTERFACE_DETAIL_DATA *devInfoDetailData =
(SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(sizeReqd);
devInfoDetailData->cbSize = sizeof(*devInfoDetailData);
if(!SetupDiGetDeviceInterfaceDetail(devInfo, &devInfoData,
devInfoDetailData, 87, NULL, NULL))
{
// printf("SetupDiGetDeviceInterfaceDetail (1) failed\n");
continue;
}
char *path = devInfoDetailData->DevicePath;
UsbHandle = CreateFile(path, /*GENERIC_READ |*/ GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, NULL);
if(UsbHandle == INVALID_HANDLE_VALUE) {
ShowError();
// printf("CreateFile failed: for '%s'\n", path);
continue;
}
HIDD_ATTRIBUTES attr;
attr.Size = sizeof(attr);
if(!getAttr(UsbHandle, &attr)) {
ShowError();
// printf("HidD_GetAttributes failed\n");
continue;
}
// printf("VID: %04x PID %04x\n", attr.VendorID, attr.ProductID);
if(attr.VendorID != OUR_VID || attr.ProductID != OUR_PID) {
CloseHandle(UsbHandle);
// printf(" nope, not us\n");
continue;
}
// printf ("got it!\n");
CloseHandle(UsbHandle);
UsbHandle = CreateFile(path, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, NULL);
if(UsbHandle == INVALID_HANDLE_VALUE) {
ShowError();
// printf("Error, couldn't open our own handle as desired.\n");
return FALSE;
}
PHIDP_PREPARSED_DATA pp;
getPreparsed(UsbHandle, &pp);
HIDP_CAPS caps;
if(getCaps(pp, &caps) != HIDP_STATUS_SUCCESS) {
// printf("getcaps failed\n");
return FALSE;
}
// printf("input/out report %d/%d\n", caps.InputReportByteLength,
// caps.OutputReportByteLength);
return TRUE;
}
return FALSE;
}
BOOL ReceiveCommandPoll(UsbCommand *c)
{
static BOOL ReadInProgress = FALSE;
static OVERLAPPED Ov;
static BYTE Buf[65];
static DWORD HaveRead;
if(!ReadInProgress) {
memset(&Ov, 0, sizeof(Ov));
ReadFile(UsbHandle, Buf, 65, &HaveRead, &Ov);
if(GetLastError() != ERROR_IO_PENDING) {
ShowError();
exit(-1);
}
ReadInProgress = TRUE;
}
if(HasOverlappedIoCompleted(&Ov)) {
ReadInProgress = FALSE;
if(!GetOverlappedResult(UsbHandle, &Ov, &HaveRead, FALSE)) {
ShowError();
exit(-1);
}
memcpy(c, Buf+1, 64);
return TRUE;
} else {
return FALSE;
}
}
void ReceiveCommand(UsbCommand *c)
{
while(!ReceiveCommandPoll(c)) {
Sleep(0);
}
}
void SendCommand(UsbCommand *c, BOOL wantAck)
{
BYTE buf[65];
buf[0] = 0;
memcpy(buf+1, c, 64);
DWORD written;
OVERLAPPED ov;
memset(&ov, 0, sizeof(ov));
WriteFile(UsbHandle, buf, 65, &written, &ov);
if(GetLastError() != ERROR_IO_PENDING) {
ShowError();
exit(-1);
}
while(!HasOverlappedIoCompleted(&ov)) {
Sleep(0);
}
if(!GetOverlappedResult(UsbHandle, &ov, &written, FALSE)) {
ShowError();
exit(-1);
}
if(wantAck) {
UsbCommand ack;
ReceiveCommand(&ack);
if(ack.cmd != CMD_ACK) {
printf("bad ACK\n");
exit(-1);
}
}
}
static DWORD ExpectedAddr;
static BYTE QueuedToSend[256];
static BOOL AllWritten;
#define PHYSICAL_FLASH_START 0x100000
struct partition {
int start;
int end;
int precious;
const char *name;
};
struct partition partitions[] = {
{0x100000, 0x102000, 1, "bootrom"},
{0x102000, 0x110000, 0, "fpga"},
{0x110000, 0x140000, 0, "os"},
};
/* If translate is set, subtract PHYSICAL_FLASH_START to translate for old
* bootroms.
*/
static void FlushPrevious(int translate)
{
UsbCommand c;
memset(&c, 0, sizeof(c));
// printf("expected = %08x flush, ", ExpectedAddr);
int i;
for(i = 0; i < 240; i += 48) {
c.cmd = CMD_SETUP_WRITE;
memcpy(c.d.asBytes, QueuedToSend+i, 48);
c.ext1 = (i/4);
SendCommand(&c, TRUE);
}
c.cmd = CMD_FINISH_WRITE;
c.ext1 = (ExpectedAddr-1) & (~255);
if(translate) {
c.ext1 -= PHYSICAL_FLASH_START;
}
printf("Flashing address: %08x\r", c.ext1);
memcpy(c.d.asBytes, QueuedToSend+240, 16);
SendCommand(&c, TRUE);
AllWritten = TRUE;
}
/* Where must be between start_addr (inclusive) and end_addr (exclusive).
*/
static void GotByte(int where, BYTE which, int start_addr, int end_addr, int translate)
{
AllWritten = FALSE;
if(where < start_addr || where >= end_addr) {
printf("bad: got byte at %08x, outside of range %08x-%08x\n", where, start_addr, end_addr);
exit(-1);
}
if(where != ExpectedAddr) {
printf("bad: got at %08x, expected at %08x\n", where, ExpectedAddr);
exit(-1);
}
QueuedToSend[where & 255] = which;
ExpectedAddr++;
if((where & 255) == 255) {
// we have completed a full page
FlushPrevious(translate);
}
}
static int HexVal(int c)
{
c = tolower(c);
if(c >= '0' && c <= '9') {
return c - '0';
} else if(c >= 'a' && c <= 'f') {
return (c - 'a') + 10;
} else {
printf("bad hex digit '%c'\n", c);
exit(-1);
}
}
static BYTE HexByte(char *s)
{
return (HexVal(s[0]) << 4) | HexVal(s[1]);
}
static void LoadFlashFromSRecords(const char *file, int start_addr, int end_addr, int translate)
{
ExpectedAddr = start_addr;
FILE *f = fopen(file, "r");
if(!f) {
printf("couldn't open file\n");
exit(-1);
}
char line[512];
while(fgets(line, sizeof(line), f)) {
if(memcmp(line, "S3", 2)==0) {
char *s = line + 2;
int len = HexByte(s) - 5;
s += 2;
char addrStr[9];
memcpy(addrStr, s, 8);
addrStr[8] = '\0';
DWORD addr;
sscanf(addrStr, "%x", &addr);
s += 8;
/* Accept files that are located at PHYSICAL_FLASH_START, and files that are located at 0 */
if(addr < PHYSICAL_FLASH_START)
addr += PHYSICAL_FLASH_START;
int i;
for(i = 0; i < len; i++) {
while((addr+i) > ExpectedAddr) {
GotByte(ExpectedAddr, 0xff, start_addr, end_addr, translate);
}
GotByte(addr+i, HexByte(s), start_addr, end_addr, translate);
s += 2;
}
}
}
if(!AllWritten) FlushPrevious(translate);
fclose(f);
printf("\ndone.\n");
}
static int PrepareFlash(struct partition *p, const char *filename, unsigned int state)
{
int translate = 0;
if(state & DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) {
UsbCommand c;
c.cmd = CMD_START_FLASH;
c.ext1 = p->start;
c.ext2 = p->end;
/* Only send magic when flashing bootrom */
if(p->precious) {
c.ext3 = START_FLASH_MAGIC;
} else {
c.ext3 = 0;
}
SendCommand(&c, TRUE);
translate = 0;
} else {
fprintf(stderr, "Warning: Your bootloader does not understand the new START_FLASH command\n");
fprintf(stderr, " It is recommended that you update your bootloader\n\n");
translate = 1;
}
LoadFlashFromSRecords(filename, p->start, p->end, translate);
return 1;
}
static unsigned int GetProxmarkState(void)
{
unsigned int state = 0;
UsbCommand c;
c.cmd = CMD_DEVICE_INFO;
SendCommand(&c, FALSE);
UsbCommand resp;
ReceiveCommand(&resp);
/* Three cases:
* 1. The old bootrom code will ignore CMD_DEVICE_INFO, but respond with an ACK
* 2. The old os code will respond with CMD_DEBUG_PRINT_STRING and "unknown command"
* 3. The new bootrom and os codes will respond with CMD_DEVICE_INFO and flags
*/
switch(resp.cmd) {
case CMD_ACK:
state = DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM;
break;
case CMD_DEBUG_PRINT_STRING:
state = DEVICE_INFO_FLAG_CURRENT_MODE_OS;
break;
case CMD_DEVICE_INFO:
state = resp.ext1;
break;
default:
fprintf(stderr, "Couldn't get proxmark state, bad response type: 0x%04X\n", resp.cmd);
exit(-1);
break;
}
#if 0
if(state & DEVICE_INFO_FLAG_BOOTROM_PRESENT) printf("New bootrom present\n");
if(state & DEVICE_INFO_FLAG_OSIMAGE_PRESENT) printf("New osimage present\n");
if(state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM) printf("Currently in bootrom\n");
if(state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) printf("Currently in OS\n");
#endif
return state;
}
static unsigned int EnterFlashState(void)
{
unsigned int state = GetProxmarkState();
if(state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM) {
/* Already in flash state, we're done. */
return state;
}
if(state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) {
fprintf(stderr,"Entering flash-mode...\n");
UsbCommand c;
bzero(&c, sizeof(c));
if( (state & DEVICE_INFO_FLAG_BOOTROM_PRESENT) && (state & DEVICE_INFO_FLAG_OSIMAGE_PRESENT) ) {
/* New style handover: Send CMD_START_FLASH, which will reset the board and
* enter the bootrom on the next boot.
*/
c.cmd = CMD_START_FLASH;
SendCommand(&c, FALSE);
fprintf(stderr,"(You don't have to do anything. Press and release the button only if you want to abort)\n");
fprintf(stderr,"Waiting for Proxmark to reappear on USB... ");
} else {
/* Old style handover: Ask the user to press the button, then reset the board */
c.cmd = CMD_HARDWARE_RESET;
SendCommand(&c, FALSE);
fprintf(stderr,"(Press and hold down button NOW if your bootloader requires it)\n");
fprintf(stderr,"Waiting for Proxmark to reappear on USB... ");
}
Sleep(1000);
while(!UsbConnect()) { Sleep(1000); }
fprintf(stderr,"Found.\n");
return GetProxmarkState();
}
return 0;
}
static void usage(char **argv)
{
int i;
printf("Usage: %s gui\n", argv[0]);
printf(" %s offline\n", argv[0]);
printf(" %s areas file.s19\n", argv[0]);
printf(" Known areas are:");
for(i=0; i<(sizeof(partitions)/sizeof(partitions[0])); i++) {
fprintf(stderr, " %s", partitions[i].name);
}
printf("\n");
}
/* On first call, have *offset = -1, *length = 0; */
static int find_next_area(char *str, int *offset, int *length)
{
if(*str == '\0') return 0;
if((*offset >= 0) && str[*offset + *length] == '\0') return 0;
*offset += 1 + *length;
char *next_comma = strchr(str + *offset, ',');
if(next_comma == NULL) {
*length = strlen(str) - *offset;
} else {
*length = next_comma-(str+*offset);
}
return 1;
}
int main(int argc, char **argv)
{
int i = 0;
if(argc < 2) {
usage(argv);
exit(-1);
}
// Only do this if NOT in offline mode
if (strcmp(argv[1], "offline"))
{
for(;;) {
if(UsbConnect()) {
break;
}
if(i == 0) {
printf("...no device connected, polling for it now\n");
}
if(i > 50000) {
printf("Could not connect to USB device; exiting.\n");
return -1;
}
i++;
Sleep(5);
}
}
if(strcmp(argv[1], "gui")==0) {
ShowGui();
} else if(strcmp(argv[1], "offline")==0) {
offline = 1;
ShowGui();
}
/* Count area arguments */
int areas = 0, offset=-1, length=0;
while(find_next_area(argv[1], &offset, &length)) areas++;
if(areas != argc - 2) {
usage(argv);
exit(-1);
}
unsigned int state = EnterFlashState();
if( !(state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM) ) {
fprintf(stderr, "Proxmark would not enter flash state, abort\n");
exit(-1);
}
offset=-1; length=0;
int current_area = 0;
while(find_next_area(argv[1], &offset, &length)) {
int i;
struct partition *p = NULL;
for(i=0; i<sizeof(partitions)/sizeof(partitions[0]); i++) {
if(strncmp(partitions[i].name, argv[1] + offset, length) == 0) {
/* Check if the name matches the bootrom partition, and if so, require "bootrom" to
* be written in full. The other names may be abbreviated.
*/
if(!partitions[i].precious || (strlen(partitions[i].name) == length)) {
p = &partitions[i];
}
break;
}
}
if(p == NULL) {
fprintf(stderr, "Warning: area name '");
fwrite(argv[1]+offset, length, 1, stderr);
fprintf(stderr, "' unknown, ignored\n");
} else {
fprintf(stderr, "Flashing %s from %s\n", p->name, argv[2+current_area]);
PrepareFlash(p, argv[2+current_area], state);
}
current_area++;
}
return 0;
}

107
client/prox.h Normal file
View file

@ -0,0 +1,107 @@
#ifndef __PROX_H
#define __PROX_H
#include "../include/usb_cmd.h"
// prox.cpp
void ReceiveCommand(UsbCommand *c);
BOOL ReceiveCommandPoll(UsbCommand *c);
void SendCommand(UsbCommand *c, BOOL wantAck);
// gui.cpp
void ShowGui();
void HideGraphWindow(void);
void ShowGraphWindow(void);
void RepaintGraphWindow(void);
void PrintToScrollback(char *fmt, ...);
#define MAX_GRAPH_TRACE_LEN (1024*128)
extern int GraphBuffer[MAX_GRAPH_TRACE_LEN];
extern int GraphTraceLen;
extern double CursorScaleFactor;
extern int PlotGridX, PlotGridY;
extern int CommandFinished;
extern int offline;
// command.cpp
static void CmdBuffClear(char *str);
static void GetFromBigBuf(BYTE *dest, int bytes);
static void CmdReset(char *str);
static void CmdQuit(char *str);
static void CmdEM410xread(char *str);
static void CmdEM410xwatch(char *str);
static void ChkBitstream(char *str);
int GetClock(char *str, int peak);
static void CmdHIDdemodFSK(char *str);
static void Cmdmanchestermod(char *str);
static void CmdTune(char *str);
static void CmdHi15read(char *str);
static void CmdHi14read(char *str);
static void CmdSri512read(char *str);
static void CmdHi14areader(char *str);
static void CmdHi15reader(char *str);
static void CmdHi15tag(char *str);
static void CmdHi14read_sim(char *str);
static void CmdHi14readt(char *str);
static void CmdHisimlisten(char *str);
static void CmdReadmem(char *str);
static void CmdHi14sim(char *str);
static void CmdHi14asim(char *str);
static void CmdHi14snoop(char *str);
static void CmdHi14asnoop(char *str);
static void CmdFPGAOff(char *str);
int CmdClearGraph(int redraw);
static void CmdAppendGraph(int redraw, int clock, int bit);
static void CmdEM410xsim(char *str);
static void CmdLosim(char *str);
static void CmdLoCommandRead(char *str);
static void CmdLoread(char *str);
static void CmdLosamples(char *str);
static void CmdBitsamples(char *str);
static void CmdHisamples(char *str);
static int CmdHisamplest(char *str, int nrlow);
static void CmdHexsamples(char *str);
static void CmdHisampless(char *str);
static WORD Iso15693Crc(BYTE *v, int n);
static void CmdHi14bdemod(char *str);
static void CmdHi14list(char *str);
static void CmdHi14alist(char *str);
static void CmdHi15demod(char *str);
static void CmdTiread(char *str);
static void CmdTibits(char *str);
static void CmdTidemod(char *cmdline);
static void CmdNorm(char *str);
static void CmdDec(char *str);
static void CmdHpf(char *str);
static void CmdZerocrossings(char *str);
static void CmdLtrim(char *str);
static void CmdAutoCorr(char *str);
static void CmdVchdemod(char *str);
static void CmdIndalademod(char *str);
static void CmdFlexdemod(char *str);
static void Cmdaskdemod(char *str);
static void Cmddetectclockrate(char *str);
int detectclock(int peak);
static void Cmdbitstream(char *str);
static void Cmdmanchesterdemod(char *str);
static void CmdHiddemod(char *str);
static void CmdPlot(char *str);
static void CmdHide(char *str);
static void CmdScale(char *str);
static void CmdSave(char *str);
static void CmdLoad(char *str);
static void CmdHIDsimTAG(char *str);
static void CmdLcdReset(char *str);
static void CmdLcd(char *str);
static void CmdTest(char *str);
static void CmdSetDivisor(char *str);
static void CmdSweepLF(char *str);
void CommandReceived(char *cmd);
void UsbCommandReceived(UsbCommand *c);
// cmdline.cpp
void ShowCommandline(void);
void ExecCmd(char *cmd);
//void PrintToScrollback(char *fmt, ...);
#endif

58
client/proxgui.cpp Normal file
View file

@ -0,0 +1,58 @@
#include "proxgui.h"
#include "proxguiqt.h"
static ProxGuiQT *gui = NULL;
extern "C" void ShowGraphWindow(void)
{
if (!gui)
return;
gui->ShowGraphWindow();
}
extern "C" void HideGraphWindow(void)
{
if (!gui)
return;
gui->HideGraphWindow();
}
extern "C" void RepaintGraphWindow(void)
{
if (!gui)
return;
gui->RepaintGraphWindow();
}
extern "C" void MainGraphics(void)
{
if (!gui)
return;
gui->MainLoop();
}
extern "C" void InitGraphics(int argc, char **argv)
{
#ifdef Q_WS_X11
bool useGUI = getenv("DISPLAY") != 0;
#else
bool useGUI = true;
#endif
if (!useGUI)
return;
gui = new ProxGuiQT(argc, argv);
}
extern "C" void ExitGraphics(void)
{
if (!gui)
return;
delete gui;
gui = NULL;
}

22
client/proxgui.h Normal file
View file

@ -0,0 +1,22 @@
#ifdef __cplusplus
extern "C" {
#endif
void ShowGraphWindow(void);
void HideGraphWindow(void);
void RepaintGraphWindow(void);
void MainGraphics(void);
void InitGraphics(int argc, char **argv);
void ExitGraphics(void);
#define MAX_GRAPH_TRACE_LEN (1024*128)
extern int GraphBuffer[MAX_GRAPH_TRACE_LEN];
extern int GraphTraceLen;
extern double CursorScaleFactor;
extern int PlotGridX, PlotGridY;
extern int CommandFinished;
extern int offline;
#ifdef __cplusplus
}
#endif

337
client/proxguiqt.cpp Normal file
View file

@ -0,0 +1,337 @@
#include <iostream>
#include <QPainterPath>
#include <QBrush>
#include <QPen>
#include <QTimer>
#include <QCloseEvent>
#include <QMouseEvent>
#include <QKeyEvent>
#include <math.h>
#include <limits.h>
#include <stdio.h>
#include "proxguiqt.h"
#include "proxgui.h"
void ProxGuiQT::ShowGraphWindow(void)
{
emit ShowGraphWindowSignal();
}
void ProxGuiQT::RepaintGraphWindow(void)
{
emit RepaintGraphWindowSignal();
}
void ProxGuiQT::HideGraphWindow(void)
{
emit HideGraphWindowSignal();
}
void ProxGuiQT::_ShowGraphWindow(void)
{
if(!plotapp)
return;
if (!plotwidget)
plotwidget = new ProxWidget();
plotwidget->show();
}
void ProxGuiQT::_RepaintGraphWindow(void)
{
if (!plotapp || !plotwidget)
return;
plotwidget->update();
}
void ProxGuiQT::_HideGraphWindow(void)
{
if (!plotapp || !plotwidget)
return;
plotwidget->hide();
}
void ProxGuiQT::MainLoop()
{
plotapp = new QApplication(argc, argv);
connect(this, SIGNAL(ShowGraphWindowSignal()), this, SLOT(_ShowGraphWindow()));
connect(this, SIGNAL(RepaintGraphWindowSignal()), this, SLOT(_RepaintGraphWindow()));
connect(this, SIGNAL(HideGraphWindowSignal()), this, SLOT(_HideGraphWindow()));
plotapp->exec();
}
ProxGuiQT::ProxGuiQT(int argc, char **argv) : plotapp(NULL), plotwidget(NULL),
argc(argc), argv(argv)
{
}
ProxGuiQT::~ProxGuiQT(void)
{
if (plotwidget) {
delete plotwidget;
plotwidget = NULL;
}
if (plotapp) {
plotapp->quit();
delete plotapp;
plotapp = NULL;
}
}
void ProxWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QPainterPath penPath, whitePath, greyPath, lightgreyPath, cursorAPath, cursorBPath;
QRect r;
QBrush brush(QColor(100, 255, 100));
QPen pen(QColor(100, 255, 100));
painter.setFont(QFont("Arial", 10));
if(GraphStart < 0) {
GraphStart = 0;
}
if (CursorAPos > GraphTraceLen)
CursorAPos= 0;
if(CursorBPos > GraphTraceLen)
CursorBPos= 0;
r = rect();
painter.fillRect(r, QColor(0, 0, 0));
whitePath.moveTo(r.left() + 40, r.top());
whitePath.lineTo(r.left() + 40, r.bottom());
int zeroHeight = r.top() + (r.bottom() - r.top()) / 2;
greyPath.moveTo(r.left(), zeroHeight);
greyPath.lineTo(r.right(), zeroHeight);
painter.setPen(QColor(100, 100, 100));
painter.drawPath(greyPath);
// plot X and Y grid lines
int i;
if ((PlotGridX > 0) && ((PlotGridX * GraphPixelsPerPoint) > 1)) {
for(i = 40; 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);
lightgreyPath.moveTo(r.left()+i,r.top());
lightgreyPath.lineTo(r.left()+i,r.bottom());
painter.drawPath(lightgreyPath);
}
}
if ((PlotGridY > 0) && ((PlotGridY * GraphPixelsPerPoint) > 1)){
for(i = 0; i < ((r.top() + r.bottom())>>1); i += (int)(PlotGridY * GraphPixelsPerPoint)) {
lightgreyPath.moveTo(r.left() + 40,zeroHeight + i);
lightgreyPath.lineTo(r.right(),zeroHeight + i);
painter.drawPath(lightgreyPath);
lightgreyPath.moveTo(r.left() + 40,zeroHeight - i);
lightgreyPath.lineTo(r.right(),zeroHeight - i);
painter.drawPath(lightgreyPath);
}
}
int startMax =
(GraphTraceLen - (int)((r.right() - r.left() - 40) / GraphPixelsPerPoint));
if(startMax < 0) {
startMax = 0;
}
if(GraphStart > startMax) {
GraphStart = startMax;
}
int absYMax = 1;
for(i = GraphStart; ; i++) {
if(i >= GraphTraceLen) {
break;
}
if(fabs((double)GraphBuffer[i]) > absYMax) {
absYMax = (int)fabs((double)GraphBuffer[i]);
}
int x = 40 + (int)((i - GraphStart)*GraphPixelsPerPoint);
if(x > r.right()) {
break;
}
}
absYMax = (int)(absYMax*1.2 + 1);
// number of points that will be plotted
int span = (int)((r.right() - r.left()) / GraphPixelsPerPoint);
// one label every 100 pixels, let us say
int labels = (r.right() - r.left() - 40) / 100;
if(labels <= 0) labels = 1;
int pointsPerLabel = span / labels;
if(pointsPerLabel <= 0) pointsPerLabel = 1;
int yMin = INT_MAX;
int yMax = INT_MIN;
int yMean = 0;
int n = 0;
for(i = GraphStart; ; i++) {
if(i >= GraphTraceLen) {
break;
}
int x = 40 + (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) {
penPath.moveTo(x, y);
} else {
penPath.lineTo(x, y);
}
if(GraphPixelsPerPoint > 10) {
QRect f(QPoint(x - 3, y - 3),QPoint(x + 3, y + 3));
painter.fillRect(f, brush);
}
if(((i - GraphStart) % pointsPerLabel == 0) && i != GraphStart) {
whitePath.moveTo(x, zeroHeight - 3);
whitePath.lineTo(x, zeroHeight + 3);
char str[100];
sprintf(str, "+%d", (i - GraphStart));
painter.setPen(QColor(255, 255, 255));
QRect size;
QFontMetrics metrics(painter.font());
size = metrics.boundingRect(str);
painter.drawText(x - (size.right() - size.left()), zeroHeight + 9, str);
penPath.moveTo(x,y);
}
if(i == CursorAPos || i == CursorBPos) {
QPainterPath *cursorPath;
if(i == CursorAPos) {
cursorPath = &cursorAPath;
} else {
cursorPath = &cursorBPath;
}
cursorPath->moveTo(x, r.top());
cursorPath->lineTo(x, r.bottom());
penPath.moveTo(x, y);
}
}
if(n != 0) {
yMean /= n;
}
painter.setPen(QColor(255, 255, 255));
painter.drawPath(whitePath);
painter.setPen(pen);
painter.drawPath(penPath);
painter.setPen(QColor(255, 255, 0));
painter.drawPath(cursorAPath);
painter.setPen(QColor(255, 0, 255));
painter.drawPath(cursorBPath);
char str[100];
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]);
painter.setPen(QColor(255, 255, 255));
painter.drawText(50, r.bottom() - 20, str);
}
ProxWidget::ProxWidget(QWidget *parent) : QWidget(parent), GraphStart(0), GraphPixelsPerPoint(1)
{
resize(600, 500);
QPalette palette(QColor(0,0,0,0));
palette.setColor(QPalette::WindowText, QColor(255,255,255));
palette.setColor(QPalette::Text, QColor(255,255,255));
palette.setColor(QPalette::Button, QColor(100, 100, 100));
setPalette(palette);
setAutoFillBackground(true);
}
void ProxWidget::closeEvent(QCloseEvent *event)
{
event->ignore();
this->hide();
}
void ProxWidget::mouseMoveEvent(QMouseEvent *event)
{
int x = event->x();
x -= 40;
x = (int)(x / GraphPixelsPerPoint);
x += GraphStart;
if((event->buttons() & Qt::LeftButton)) {
CursorAPos = x;
} else if (event->buttons() & Qt::RightButton) {
CursorBPos = x;
}
this->update();
}
void ProxWidget::keyPressEvent(QKeyEvent *event)
{
switch(event->key()) {
case Qt::Key_Down:
if(GraphPixelsPerPoint <= 50) {
GraphPixelsPerPoint *= 2;
}
break;
case Qt::Key_Up:
if(GraphPixelsPerPoint >= 0.02) {
GraphPixelsPerPoint /= 2;
}
break;
case Qt::Key_Right:
if(GraphPixelsPerPoint < 20) {
GraphStart += (int)(20 / GraphPixelsPerPoint);
} else {
GraphStart++;
}
break;
case Qt::Key_Left:
if(GraphPixelsPerPoint < 20) {
GraphStart -= (int)(20 / GraphPixelsPerPoint);
} else {
GraphStart--;
}
break;
default:
QWidget::keyPressEvent(event);
return;
break;
}
this->update();
}

56
client/proxguiqt.h Normal file
View file

@ -0,0 +1,56 @@
#include <QApplication>
#include <QPushButton>
#include <QObject>
#include <QWidget>
#include <QPainter>
class ProxWidget : public QWidget
{
Q_OBJECT;
private:
int GraphStart;
double GraphPixelsPerPoint;
int CursorAPos;
int CursorBPos;
public:
ProxWidget(QWidget *parent = 0);
protected:
void paintEvent(QPaintEvent *event);
void closeEvent(QCloseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event) { mouseMoveEvent(event); }
void keyPressEvent(QKeyEvent *event);
};
class ProxGuiQT : public QObject
{
Q_OBJECT;
private:
QApplication *plotapp;
ProxWidget *plotwidget;
int argc;
char **argv;
void (*main_func)(void);
public:
ProxGuiQT(int argc, char **argv);
~ProxGuiQT(void);
void ShowGraphWindow(void);
void RepaintGraphWindow(void);
void HideGraphWindow(void);
void MainLoop(void);
private slots:
void _ShowGraphWindow(void);
void _RepaintGraphWindow(void);
void _HideGraphWindow(void);
signals:
void ShowGraphWindowSignal(void);
void RepaintGraphWindowSignal(void);
void HideGraphWindowSignal(void);
};

106
client/proxmark3.c Normal file
View file

@ -0,0 +1,106 @@
#include <usb.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <errno.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <pthread.h>
#include "translate.h"
#include "prox.h"
#include "proxmark3.h"
#include "proxgui.h"
struct usb_receiver_arg {
int run;
};
struct main_loop_arg {
int usb_present;
};
static void *usb_receiver(void *targ) {
struct usb_receiver_arg *arg = (struct usb_receiver_arg*)targ;
UsbCommand cmdbuf;
while(arg->run) {
if (ReceiveCommandP(&cmdbuf) > 0) {
int i;
for (i=0; i<strlen(PROXPROMPT); i++)
putchar(0x08);
UsbCommandReceived(&cmdbuf);
printf(PROXPROMPT);
fflush(NULL);
}
}
pthread_exit(NULL);
}
static void *main_loop(void *targ)
{
struct main_loop_arg *arg = (struct main_loop_arg*)targ;
char *cmd = NULL;
while(1) {
struct usb_receiver_arg rarg;
pthread_t reader_thread;
rarg.run=1;
if (arg->usb_present == 1) {
pthread_create(&reader_thread, NULL, &usb_receiver, &rarg);
}
cmd = readline(PROXPROMPT);
rarg.run=0;
if (arg->usb_present == 1) {
pthread_join(reader_thread, NULL);
}
if (cmd) {
if (cmd[0] != 0x00) {
CommandReceived(cmd);
add_history(cmd);
}
free(cmd);
} else {
printf("\n");
break;
}
}
ExitGraphics();
pthread_exit(NULL);
}
int main(int argc, char **argv)
{
struct main_loop_arg marg;
pthread_t main_loop_t;
usb_init();
if (!(devh = OpenProxmark(1))) {
fprintf(stderr,"PROXMARK3: NOT FOUND!\n");
marg.usb_present = 0;
offline = 1;
} else {
marg.usb_present = 1;
offline = 0;
}
pthread_create(&main_loop_t, NULL, &main_loop, &marg);
InitGraphics(argc, argv);
MainGraphics();
pthread_join(main_loop_t, NULL);
if (marg.usb_present == 1) {
CloseProxmark();
}
return 0;
}

14
client/proxmark3.h Normal file
View file

@ -0,0 +1,14 @@
#define PROXPROMPT "proxmark3> "
#define FLASH_ADDR_OS 0x10000
#define FLASH_ADDR_FPGA 0x2000
extern usb_dev_handle *devh;
extern unsigned char return_on_error;
extern unsigned char error_occured;
int ReceiveCommandP(UsbCommand *c);
usb_dev_handle* OpenProxmark(int);
void CloseProxmark(void);
void setlogfilename(char *fn);

49
client/snooper.c Normal file
View file

@ -0,0 +1,49 @@
#include <usb.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <errno.h>
#include "translate.h"
#include "prox.h"
#include "proxmark3.h"
#define HANDLE_ERROR if (error_occured) { \
error_occured = 0;\
break;\
}
int main()
{
usb_init();
setlogfilename("snooper.log");
return_on_error = 1;
while(1) {
while(!(devh=OpenProxmark(0))) { sleep(1); }
while(1) {
UsbCommand cmdbuf;
int i;
CommandReceived("hi14asnoop");
HANDLE_ERROR
ReceiveCommand(&cmdbuf);
HANDLE_ERROR
for (i=0; i<5; i++) {
ReceiveCommandP(&cmdbuf);
}
HANDLE_ERROR
CommandReceived("hi14alist");
HANDLE_ERROR
}
}
CloseProxmark();
return 0;
}

9
client/translate.h Normal file
View file

@ -0,0 +1,9 @@
#define BYTE unsigned char
#define WORD unsigned short
#define DWORD unsigned int
#define TRUE 1
#define FALSE 0
#define BOOL int
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)>(b))?(b):(a))

16
client/unbind-proxmark Executable file
View file

@ -0,0 +1,16 @@
#!/bin/sh
for i in /sys/bus/usb/devices/*; do
if grep "9ac4" "${i}/idVendor" >/dev/null 2>&1; then
echo "Found Proxmark..."
dev=`basename "${i}"`
for j in /sys/bus/usb/drivers/usbhid/*; do
if basename "${j}"|grep "^${dev}" >/dev/null; then
bound="`basename "${j}"`"
echo "Unbinding ${bound}..."
echo -n "${bound}" >/sys/bus/usb/drivers/usbhid/unbind
fi
done
fi
done

178
client/usb.c Normal file
View file

@ -0,0 +1,178 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <usb.h>
#include <strings.h>
#include <errno.h>
#include "translate.h"
#include "prox.h"
#include "proxmark3.h"
usb_dev_handle *devh = NULL;
static unsigned int claimed_iface = 0;
unsigned char return_on_error = 0;
unsigned char error_occured = 0;
void SendCommand(UsbCommand *c, BOOL wantAck) {
int ret;
#if 0
printf("Sending %d bytes\n", sizeof(UsbCommand));
#endif
ret = usb_bulk_write(devh, 0x01, (char*)c, sizeof(UsbCommand), 1000);
if (ret<0) {
error_occured = 1;
if (return_on_error)
return;
fprintf(stderr, "write failed: %s!\nTrying to reopen device...\n",
usb_strerror());
if (devh) {
usb_close(devh);
devh = NULL;
}
while(!(devh=OpenProxmark(0))) { sleep(1); }
printf(PROXPROMPT);
fflush(NULL);
return;
}
if(wantAck) {
UsbCommand ack;
ReceiveCommand(&ack);
if(ack.cmd != CMD_ACK) {
printf("bad ACK\n");
exit(-1);
}
}
}
int ReceiveCommandP(UsbCommand *c) {
int ret;
bzero(c, sizeof(UsbCommand));
ret = usb_bulk_read(devh, 0x82, (char*)c, sizeof(UsbCommand), 500);
if (ret<0) {
if (ret != -ETIMEDOUT) {
error_occured = 1;
if (return_on_error)
return 0;
fprintf(stderr, "read failed: %s(%d)!\nTrying to reopen device...\n",
usb_strerror(), ret);
if (devh) {
usb_close(devh);
devh = NULL;
}
while(!(devh=OpenProxmark(0))) { sleep(1); }
printf(PROXPROMPT);
fflush(NULL);
return 0;
}
} else {
if (ret && (ret < sizeof(UsbCommand))) {
fprintf(stderr, "Read only %d instead of requested %d bytes!\n",
ret, (int)sizeof(UsbCommand));
}
#if 0
{
int i;
printf("Read %d bytes\n", ret);
for (i = 0; i < ret; i++) {
printf("0x%02X ", ((unsigned char*)c)[i]);
if (!((i+1)%8))
printf("\n");
}
printf("\n");
}
#endif
}
return ret;
}
void ReceiveCommand(UsbCommand *c) {
while(ReceiveCommandP(c)<0) {}
}
usb_dev_handle* findProxmark(int verbose, unsigned int *iface) {
struct usb_bus *busses, *bus;
usb_dev_handle *handle = NULL;
usb_find_busses();
usb_find_devices();
busses = usb_get_busses();
for (bus = busses; bus; bus = bus->next) {
struct usb_device *dev;
for (dev = bus->devices; dev; dev = dev->next) {
struct usb_device_descriptor *desc = &(dev->descriptor);
if ((desc->idProduct == 0x4b8f) && (desc->idVendor == 0x9ac4)) {
handle = usb_open(dev);
if (!handle) {
if (verbose)
fprintf(stderr, "open failed: %s!\n", usb_strerror());
return NULL;
}
*iface = dev->config[0].interface[0].altsetting[0].bInterfaceNumber;
return handle;
}
}
}
return NULL;
}
usb_dev_handle* OpenProxmark(int verbose) {
int ret;
usb_dev_handle *handle = NULL;
unsigned int iface;
#ifndef __APPLE__
handle = findProxmark(verbose, &iface);
if (!handle)
return NULL;
/* Whatever... */
usb_reset(handle);
#endif
handle = findProxmark(verbose, &iface);
if (!handle)
return NULL;
#ifndef __APPLE__
/* detach kernel driver first */
ret = usb_detach_kernel_driver_np(handle, iface);
/* don't complain if no driver attached */
if (ret<0 && ret != -61 && verbose)
fprintf(stderr, "detach kernel driver failed: (%d) %s!\n", ret, usb_strerror());
#endif
ret = usb_claim_interface(handle, iface);
if (ret<0) {
if (verbose)
fprintf(stderr, "claim failed: %s!\n", usb_strerror());
return NULL;
}
claimed_iface = iface;
devh = handle;
return handle;
}
void CloseProxmark(void) {
usb_release_interface(devh, claimed_iface);
usb_close(devh);
}

0
client/windows.h Normal file
View file