micetools/src/micetools/dll/comdevice.c

117 lines
4.1 KiB
C

#include "comdevice.h"
BOOL DevGetCommState(void* data, LPDCB lpDCB) { return TRUE; }
BOOL DevSetCommState(void* data, LPDCB lpDCB) { return TRUE; }
BOOL DevGetCommTimeouts(void* data, LPCOMMTIMEOUTS lpCommTimeouts) { return TRUE; }
BOOL DevSetCommTimeouts(void* data, LPCOMMTIMEOUTS lpCommTimeouts) { return TRUE; }
BOOL DevSetupComm(void* data, DWORD dwInQueue, DWORD dwOutQueue) { return TRUE; }
BOOL DevPurgeComm(void* data, DWORD dwFlags) {
if (dwFlags & PURGE_RXCLEAR) ringbuf_purge(&((com_device_t*)data)->out);
return TRUE;
}
BOOL DevGetCommModemStatus(void* data, LPDWORD lpModelStat) {
// TODO: JVS SENSE
return TRUE;
}
BOOL DevWaitCommEvent(void* data, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped) {
WaitForSingleObject(((com_device_t*)data)->event, INFINITE);
if (lpOverlapped != NULL) SetEvent(lpOverlapped->hEvent);
return TRUE;
}
BOOL DevClearCommError(void* data, LPDWORD lpErrors, LPCOMSTAT lpStat) {
if (lpErrors != NULL) *lpErrors = 0;
if (lpStat != NULL) {
lpStat->fCtsHold = FALSE;
lpStat->fDsrHold = FALSE;
lpStat->fRlsdHold = FALSE;
lpStat->fXoffHold = FALSE;
lpStat->fXoffSent = FALSE;
lpStat->fEof = FALSE;
lpStat->fTxim = FALSE;
lpStat->fReserved = 0;
lpStat->cbInQue = ringbuf_available(&((com_device_t*)data)->out);
lpStat->cbOutQue = ringbuf_available(&((com_device_t*)data)->in);
}
return TRUE;
}
BOOL DevWriteFile(void* file, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped) {
if (nNumberOfBytesToWrite > 0xffff) return FALSE;
// Ignore overflow
ringbuf_write(&((com_device_t*)file)->in, lpBuffer, nNumberOfBytesToWrite & 0xffff);
if (lpNumberOfBytesWritten) *lpNumberOfBytesWritten = nNumberOfBytesToWrite;
return TRUE;
}
BOOL DevReadFile(void* file, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped) {
if (nNumberOfBytesToRead > 0xffff) return FALSE;
// Make sure we have at least one byte to return
// while (!ringbuf_available(&((com_device_t*)file)->out)) {
// WaitForSingleObject(((com_device_t*)file)->event, INFINITE);
// }
short read = ringbuf_read(&((com_device_t*)file)->out, lpBuffer, nNumberOfBytesToRead & 0xffff);
if (lpNumberOfBytesRead) *lpNumberOfBytesRead = read;
if (read != 0) {
// log_info("drf", "%d", read);
// for (int i = 0; i < read; i++) {
// printf("%02x ", ((unsigned char*)lpBuffer)[i]);
// }
// puts("");
}
return TRUE;
}
short comdev_read(com_device_t* com, unsigned char* buffer, short bytes) {
return ringbuf_read(&com->in, buffer, bytes);
}
bool comdev_write(com_device_t* com, unsigned char* buffer, short bytes) {
bool ret = ringbuf_write(&com->out, buffer, bytes);
SetEvent(com->event);
return ret;
}
short comdev_available(com_device_t* com) { return ringbuf_available(&com->in); }
void com_device_thread(com_device_t* com, FnComDeviceThread* thread) {
com->thread = CreateThread(NULL, 0, thread, com, 0, NULL);
}
com_device_t* new_com_device(BYTE port) {
com_device_t* hook = (com_device_t*)malloc(sizeof *hook);
com_hook_t* com = new_com_hook(port);
file_hook_t* file = new_file_hook(com->wName);
file->altFilename = com->wDosName;
com->data = hook;
file->data = hook;
hook->com = com;
hook->file = file;
com->GetCommState = DevGetCommState;
com->SetCommState = DevSetCommState;
com->GetCommTimeouts = DevGetCommTimeouts;
com->SetCommTimeouts = DevSetCommTimeouts;
com->SetupComm = DevSetupComm;
com->PurgeComm = DevPurgeComm;
com->GetCommModemStatus = DevGetCommModemStatus;
com->WaitCommEvent = DevWaitCommEvent;
com->ClearCommError = DevClearCommError;
file->ReadFile = DevReadFile;
file->WriteFile = DevWriteFile;
ringbuf_purge(&hook->in);
ringbuf_purge(&hook->out);
hook->event = CreateEventW(NULL, TRUE, FALSE, hook->com->wName);
hook_file(file);
hook_com(com);
free(com->virtual_handle);
com->virtual_handle = file->virtual_handle;
return hook;
}