251 lines
7.3 KiB
C
251 lines
7.3 KiB
C
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
|
|
#include <dlfcn.h>
|
|
|
|
#include "ftd2xx.h"
|
|
|
|
#define HIGHLEVEL
|
|
#include "libftfake_hl.h"
|
|
|
|
static void* libftd2xx;
|
|
static void lib_open(void) {
|
|
static bool opened = false;
|
|
if (!opened) {
|
|
libftd2xx = dlopen("build/libftd2xx.so.1.4.8", RTLD_LAZY);
|
|
opened = libftd2xx != NULL;
|
|
if (!opened) {
|
|
printf("cant open lib!\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
FT_Close
|
|
FT_GetBitMode
|
|
FT_GetQueueStatus
|
|
FT_ListDevices
|
|
FT_Open
|
|
FT_OpenEx
|
|
FT_Read
|
|
FT_SetBitMode
|
|
FT_SetLatencyTimer
|
|
FT_SetTimeouts
|
|
FT_SetUSBParameters
|
|
FT_SetVIDPID
|
|
FT_Write
|
|
FT_ReadEE
|
|
FT_WriteEE
|
|
|
|
FT_EE_Program
|
|
FT_EE_Read
|
|
FT_EE_UARead
|
|
FT_EE_UAWrite
|
|
*/
|
|
|
|
#define bind(rt, fntyp, ...) \
|
|
rt rv = ({ \
|
|
static rt (* fn) fntyp = NULL; \
|
|
if (fn == NULL) { lib_open(); fn = (rt(*)fntyp)dlsym(libftd2xx, __func__); } \
|
|
fn(__VA_ARGS__); \
|
|
}) \
|
|
|
|
/*FT_STATUS FT_GetDeviceInfo(FT_HANDLE ftHandle, FT_DEVICE* ftDevice,
|
|
LPDWORD lpdwID, PCHAR serialNumber, PCHAR descr, LPVOID dummy) {
|
|
FT_STATUS rv = bind(FT_STATUS, (FT_HANDLE, FT_DEVICE*, LPDWORD, PCHAR, PCHAR, LPVOID),
|
|
ftHandle, ftDevice, lpdwID, serialNumber, descr, dummy);
|
|
|
|
printf("FT_GetDeviceInfo(%p, &%d, &0x%x, %s, %s, %p) = %d\n",
|
|
ftHandle, *ftDevice, *lpdwID, serialNumber, descr, dummy, rv);
|
|
}*/
|
|
|
|
FT_STATUS FT_Close(FT_HANDLE ftHandle) {
|
|
bind(FT_STATUS, (FT_HANDLE), ftHandle);
|
|
printf("FT_Close(%p) = %d\n", ftHandle, rv);
|
|
return rv;
|
|
}
|
|
|
|
FT_STATUS FT_GetBitMode(FT_HANDLE ftHandle, PUCHAR pucMode) {
|
|
bind(FT_STATUS, (FT_HANDLE, PUCHAR), ftHandle, pucMode);
|
|
printf("FT_GetBitMode(%p, &0x%02x) = %d\n", ftHandle, *pucMode, rv);
|
|
return rv;
|
|
}
|
|
|
|
FT_STATUS FT_GetQueueStatus(FT_HANDLE ftHandle, DWORD* dwRxBytes) {
|
|
bind(FT_STATUS, (FT_HANDLE, DWORD*), ftHandle, dwRxBytes);
|
|
// responsible for lots of spam
|
|
#ifndef HIGHLEVEL
|
|
printf("FT_GetSqueueStatus(%p, &0x%x) = %d\n", ftHandle, *dwRxBytes, rv);
|
|
#endif
|
|
return rv;
|
|
}
|
|
|
|
FT_STATUS FT_ListDevices(PVOID pArg1, PVOID pArg2, DWORD flags) {
|
|
bind(FT_STATUS, (PVOID, PVOID, DWORD), pArg1, pArg2, flags);
|
|
// possible usages:
|
|
// * fn(nulterm array to strings, &numdevs, FT_LIST_ALL | FT_OPEN_BY_SERIAL_NUMBER)
|
|
// * fn(null??, charbuf, FT_LIST_BY_INDEX | FT_OPEN_BY_SERIAL_NUMBER);
|
|
// * fn(numdev, NULL, FT_LIST_NUMBER_ONLY);
|
|
#ifndef HIGHLEVEL
|
|
printf("FT_ListDevices(%p, %p, 0x%08x) = %d\n", pArg1, pArg2, flags, rv);
|
|
if (flags & FT_LIST_NUMBER_ONLY) {
|
|
if (pArg2) printf(" W! pArg2 != null!\n");
|
|
printf("-> #devs = %d\n", *(int*)pArg1);
|
|
} else if (flags & FT_LIST_ALL) {
|
|
int numdevs = *(int*)pArg2;
|
|
const char* descr;
|
|
if (flags & FT_OPEN_BY_SERIAL_NUMBER) descr = "serial number";
|
|
else if (flags & FT_OPEN_BY_DESCRIPTION) descr = "description";
|
|
else if (flags & FT_OPEN_BY_LOCATION) descr = "location";
|
|
else descr = "WTF";
|
|
printf("-> #devs = %d, %ss:\n", numdevs, descr);
|
|
for (int i = 0; i < numdevs; ++i) {
|
|
printf(" [%d] = \"%s\"\n", i, ((char**)pArg1)[i]);
|
|
}
|
|
} else if (flags & FT_LIST_BY_INDEX) {
|
|
printf(" W! FT_LIST_BY_INDEX not impl\n");
|
|
} else printf(" W! unk flags!\n");
|
|
#endif
|
|
return rv;
|
|
}
|
|
|
|
FT_STATUS FT_Open(int devno, FT_HANDLE* pHandle) {
|
|
bind(FT_STATUS, (int, FT_HANDLE*), devno, pHandle);
|
|
printf("FT_Open(%d, &%p) = %d\n", devno, *pHandle, rv);
|
|
return rv;
|
|
}
|
|
|
|
FT_STATUS FT_OpenEx(PVOID pArg1, DWORD flags, FT_HANDLE* pHandle) {
|
|
bind(FT_STATUS, (PVOID, DWORD, FT_HANDLE*), pArg1, flags, pHandle);
|
|
printf("FT_OpenEx(%p, 0x%08x, &%p) = %d\n", pArg1, flags, *pHandle, rv);
|
|
return rv;
|
|
}
|
|
|
|
FT_STATUS FT_Read(FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD dwBytesToRead, LPDWORD lpBytesReturned) {
|
|
bind(FT_STATUS, (FT_HANDLE, LPVOID, DWORD, LPDWORD),
|
|
ftHandle, lpBuffer, dwBytesToRead, lpBytesReturned);
|
|
if (dwBytesToRead != *lpBytesReturned) printf("\tW: AAAAAAAAAA size mismatch\n");
|
|
size_t nb = *lpBytesReturned;
|
|
#ifndef HIGHLEVEL
|
|
printf("FT_Read(%p, %p, 0x%x, &0x%x) = %d\n", ftHandle, lpBuffer, dwBytesToRead, *lpBytesReturned, rv);
|
|
#endif
|
|
if (nb <
|
|
#ifndef HIGHLEVEL
|
|
0x100
|
|
#else
|
|
0x10
|
|
#endif
|
|
) {
|
|
#ifdef HIGHLEVEL
|
|
printf("FT_Read(%p, %p, 0x%x, &0x%x) = %d\n", ftHandle, lpBuffer, dwBytesToRead, *lpBytesReturned, rv);
|
|
#endif
|
|
printf(" ");
|
|
size_t i;
|
|
for (i = 0; i < nb; ++i) {
|
|
printf("%02x ", ((uint8_t*)lpBuffer)[i]);
|
|
|
|
if ((i & 15) == 15) printf("\n ");
|
|
}
|
|
if ((i & 15)) printf("\n");
|
|
}
|
|
#ifdef HIGHLEVEL
|
|
ftfake_cb(lpBuffer, nb);
|
|
#endif
|
|
return rv;
|
|
}
|
|
|
|
FT_STATUS FT_SetBitMode(FT_HANDLE ftHandle, UCHAR ucMask, UCHAR ucEnable) {
|
|
bind(FT_STATUS, (FT_HANDLE, UCHAR, UCHAR), ftHandle, ucMask, ucEnable);
|
|
printf("FT_SetBitMode(%p, 0x%02x, 0x%02x) = %d\n", ftHandle, ucMask, ucEnable, rv);
|
|
return rv;
|
|
}
|
|
|
|
FT_STATUS FT_SetLatencyTimer(FT_HANDLE ftHandle, UCHAR ucLatency) {
|
|
bind(FT_STATUS, (FT_HANDLE, UCHAR), ftHandle, ucLatency);
|
|
printf("FT_SetLatencyTimer(%p, 0x%02x) = %d\n", ftHandle, ucLatency, rv);
|
|
return rv;
|
|
}
|
|
|
|
FT_STATUS FT_SetTimeouts(FT_HANDLE ftHandle, ULONG rto, ULONG wto) {
|
|
bind(FT_STATUS, (FT_HANDLE, ULONG, ULONG), ftHandle, rto, wto);
|
|
printf("FT_SetTimeouts(%p, 0x%08x, 0x%08x) = %d\n", ftHandle, rto, wto, rv);
|
|
return rv;
|
|
}
|
|
|
|
FT_STATUS FT_SetUSBParameters(FT_HANDLE ftHandle, ULONG inxfersz, ULONG outxfersz) {
|
|
bind(FT_STATUS, (FT_HANDLE, ULONG, ULONG), ftHandle, inxfersz, outxfersz);
|
|
printf("FT_SetUSBParameters(%p, 0x%08x, 0x%08x) = %d\n", ftHandle, inxfersz, outxfersz, rv);
|
|
return rv;
|
|
}
|
|
|
|
FT_STATUS FT_SetVIDPID(DWORD dwVid, DWORD dwPid) {
|
|
bind(FT_STATUS, (DWORD, DWORD), dwVid, dwPid);
|
|
#ifndef HIGHLEVEL
|
|
printf("FT_SetVIDPID(0x%04x, 0x%04x) = %d\n", dwVid, dwPid, rv);
|
|
#endif
|
|
return rv;
|
|
}
|
|
|
|
FT_STATUS FT_Write(FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD len, LPDWORD written) {
|
|
bind(FT_STATUS, (FT_HANDLE, LPVOID, DWORD, LPDWORD), ftHandle, lpBuffer, len, written);
|
|
printf("FT_Write(%p, %p, 0x%x, &0x%0x) = %d\n", ftHandle, lpBuffer, len, *written, rv);
|
|
if (*written != len) printf("\tW: AAAAAAAAAAAAAAAA size mismatch\n");
|
|
size_t nb = *written;
|
|
if (nb < 0x100) {
|
|
printf(" ");
|
|
size_t i;
|
|
for (i = 0; i < nb; ++i) {
|
|
printf("%02x ", ((uint8_t*)lpBuffer)[i]);
|
|
|
|
if ((i & 15) == 15) printf("\n ");
|
|
}
|
|
if ((i & 15)) printf("\n");
|
|
}
|
|
|
|
#ifdef HIGHLEVEL
|
|
ftfake_parsehl(lpBuffer, nb);
|
|
#endif
|
|
|
|
return rv;
|
|
}
|
|
|
|
FT_STATUS FT_ReadEE(FT_HANDLE ftHandle, DWORD off, LPWORD val) {
|
|
bind(FT_STATUS, (FT_HANDLE, DWORD, LPWORD), ftHandle, off, val);
|
|
printf("FT_ReadEE(%p, 0x%04x, &0x%04x) = %d\n", ftHandle, off, *val, rv);
|
|
return rv;
|
|
}
|
|
|
|
FT_STATUS FT_WriteEE(FT_HANDLE ftHandle, DWORD off, WORD val) {
|
|
bind(FT_STATUS, (FT_HANDLE, DWORD, WORD), ftHandle, off, val);
|
|
printf("FT_WriteEE(%p, 0x%04x, 0x%04x) = %d\n", ftHandle, off, val, rv);
|
|
return rv;
|
|
}
|
|
|
|
FT_STATUS FT_EE_Program(FT_HANDLE ftHandle, PFT_PROGRAM_DATA pData) {
|
|
bind(FT_STATUS, (FT_HANDLE, PFT_PROGRAM_DATA), ftHandle, pData);
|
|
printf("FT_EE_Program(%p, %p) = %d\n", ftHandle, pData, rv);
|
|
return rv;
|
|
}
|
|
|
|
FT_STATUS FT_EE_Read(FT_HANDLE ftHandle, PFT_PROGRAM_DATA pData) {
|
|
bind(FT_STATUS, (FT_HANDLE, PFT_PROGRAM_DATA), ftHandle, pData);
|
|
printf("FT_EE_Read(%p, %p) = %d\n", ftHandle, pData, rv);
|
|
return rv;
|
|
}
|
|
|
|
FT_STATUS FT_EE_UARead(FT_HANDLE ftHandle, PUCHAR pucData, DWORD len, LPDWORD read) {
|
|
bind(FT_STATUS, (FT_HANDLE, PUCHAR, DWORD, LPDWORD), ftHandle, pucData, len, read);
|
|
printf("FT_EE_UARead(%p, %p, 0x%x, &0x%x) = %d\n", ftHandle, pucData, len, *read, rv);
|
|
return rv;
|
|
}
|
|
|
|
FT_STATUS FT_EE_UAWrite(FT_HANDLE ftHandle, PUCHAR pucData, DWORD len) {
|
|
bind(FT_STATUS, (FT_HANDLE, PUCHAR, DWORD), ftHandle, pucData, len);
|
|
printf("FT_EE_UAWrite(%p, %p, 0x%x) = %d\n", ftHandle, pucData, len, rv);
|
|
return rv;
|
|
}
|
|
|