📄 file.cpp
字号:
extern "C" ULONG
COM_Seek(file_extension* fx, LONG pos, DWORD mode)
{
dmesg(L"_seek\n");
return -1;
};
BOOL
fxGetCommMask(file_extension* fx, DWORD* pmask)
{
dmesg(L"GetCommMask\n");
*pmask= fx->waitmask;
return TRUE;
};
BOOL
fxSetCommMask(file_extension* fx, DWORD mask)
{
dmesg(L"SetCommMask x%x\n", mask);
fx->waitmask= mask;
fx->waitbit= 0;
InterlockedTestExchange(&fx->waituse, 1, 2);
SetEvent(fx->waitevent);
return TRUE;
};
BOOL
fxWaitCommEvent(file_extension* fx, DWORD* pbit, OVERLAPPED* over)
{
dmesg(L"WaitCommEvent\n");
if(InterlockedTestExchange(&fx->waituse, 0, 1)!=0) {
SetLastError(ERROR_ACCESS_DENIED);
return FALSE;
};
DWORD mask= fx->waitmask;
if(mask==0) {
SetLastError(ERROR_INVALID_PARAMETER);
fx->waituse= 0;
return FALSE;
};
ResetEvent(fx->waitevent);
DWORD bit= 0;
for(;;) {
if(fx->dx==0) break; //closed
if(fx->waituse!=1) break; //abort
bit= InterlockedExchange((long*)&fx->waitbit, 0)&mask;
if(bit) break;
dmesg(L"waitfor\n");
WaitForSingleObject(fx->waitevent, INFINITE);
};
*pbit= bit;
fx->waituse= 0;
dmesg(L"waitreturn x%x\n", bit);
return TRUE;
};
extern "C" BOOL
COM_IOControl(file_extension *fx, DWORD code
, PBYTE ibuf, DWORD ilen, PBYTE obuf, DWORD olen, PDWORD odone)
{
dmesg(L"_ioctl x%x %d\n", fx, code>>2&0xfff);
if(code==CTL_CODE(0x103/*FILE_DEVICE_PSL*/, 255, METHOD_NEITHER, FILE_ANY_ACCESS)) {
if(ilen>=sizeof(DWORD)*2&&((DWORD*)ibuf)[0]>=sizeof(DWORD)*2
&&((DWORD*)ibuf)[1]==DLL_PROCESS_EXITING) {
long oldx= InterlockedExchange((long *)&fx->dx, 0); // flag to close
waitRef((device_extension*)oldx, fx);
InterlockedTestExchange((long*)&fx->dx, 0, oldx);
};
return TRUE;
};
device_extension *dx= fx->dx;
if(dx==0) { SetLastError(ERROR_INVALID_HANDLE); return(ULONG)-1; };
if((code&~(0xfff<<2))!=CTL_CODE(FILE_DEVICE_SERIAL_PORT, 0,METHOD_BUFFERED,FILE_ANY_ACCESS)) return FALSE;
InterlockedIncrement(&fx->ref);
int rc= FALSE;
switch(code>>2&0xfff) {
case 1: {//EscapeCommFunction(SETBREAK)==SetCommBreak
rc= dx->sendbreak(0xffff);
} break;
case 2: {//EscapeCommFunction(CLRBREAK)==ClearCommBreak
rc= dx->sendbreak(0);
} break;
case 3: {//EscapeCommFunction(SETDTR)
if(dx->dcb.fDtrControl==DTR_CONTROL_HANDSHAKE) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
};
rc= dx->setlinestate(1, 1);
} break;
case 4: {//EscapeCommFunction(CLRDTR)
if(dx->dcb.fDtrControl==DTR_CONTROL_HANDSHAKE) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
};
rc= dx->setlinestate(1, 0);
} break;
case 5: {//EscapeCommFunction(SETRTS)
if(dx->dcb.fRtsControl==RTS_CONTROL_HANDSHAKE) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
};
rc= dx->setlinestate(2, 2);
} break;
case 6: {//EscapeCommFunction(CLRRTS)
if(dx->dcb.fRtsControl==RTS_CONTROL_HANDSHAKE) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
};
rc= dx->setlinestate(2, 0);
} break;
case 7: {//EscapeCommFunction(SETXOFF)
if(dx->dcb.fOutX) dx->sendxoff= 1;
rc= TRUE;
} break;
case 8: {//EscapeCommFunction(SETXON)
if(dx->dcb.fOutX) dx->sendxoff= 0;
SetEvent(dx->writeevent);
rc= TRUE;
} break;
case 9: {//GetCommMask
if(odone) *odone= 0;
if(obuf==0||odone==0||olen<sizeof(DWORD)) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
};
rc= fxGetCommMask(fx, (DWORD*)obuf);
if(rc) *odone= sizeof(DWORD);
} break;
case 10:{//SetCommMask
if(ibuf==0||ilen<sizeof(DWORD)) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
};
rc= fxSetCommMask(fx, *(DWORD*)ibuf);
} break;
case 11:{//WaitCommEvent
if(odone) *odone= 0;
if(obuf==0||odone==0||olen<sizeof(DWORD)) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
};
rc= fxWaitCommEvent(fx, (DWORD*)obuf, 0);
if(rc) *odone= sizeof(DWORD);
} break;
case 12:{//ClearCommError (GET_COMMSTATUS)
if(odone) *odone= 0;
if(obuf==0||odone==0||olen<sizeof(DWORD)+sizeof(COMSTAT)) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
};
*(DWORD*)obuf= dx->comstat((COMSTAT*)(obuf+sizeof(DWORD)));
rc= TRUE;
*odone= sizeof(DWORD)+sizeof(COMSTAT);
} break;
case 13:{//GetCommModemStatus
if(odone) *odone= 0;
if(obuf==0||odone==0||olen<sizeof(DWORD)) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
};
DWORD r= 0;
if((dx->usbmode&1)==0||(dx->linein&0x80)) r|= MS_CTS_ON;
if(dx->linein&2) r|= MS_DSR_ON;
if(dx->linein&8) r|= MS_RING_ON;
if(dx->linein&1) r|= MS_RLSD_ON;
*(DWORD*)obuf= r;
rc= TRUE;
*odone= sizeof(DWORD);
} break;
case 14:{//GetCommProperties
if(odone) *odone= 0;
if(obuf==0||odone==0||olen<sizeof(COMMPROP)) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
};
memset(obuf, 0, sizeof(COMMPROP));
COMMPROP *cp= (COMMPROP*)obuf;
//sets dummy data...
cp->wPacketLength= ~0; cp->wPacketVersion= ~0;
cp->dwServiceMask= SP_SERIALCOMM;
cp->dwMaxBaud= BAUD_USER;
cp->dwProvSubType= PST_RS232;
cp->dwProvCapabilities= (DWORD)~0>>1;
cp->dwSettableParams= (DWORD)~0>>1;
cp->dwSettableBaud= (DWORD)~0>>1;
cp->wSettableData= (WORD)~0>>1;
cp->wSettableStopParity= (WORD)~0>>1;
rc= TRUE;
*odone= sizeof(COMMPROP);
} break;
case 15:{//SetCommTimeouts
if(ibuf==0||ilen<sizeof(COMMTIMEOUTS)) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
};
dx->timeout= *(COMMTIMEOUTS*)ibuf;
rc= TRUE;
} break;
case 16:{//GetCommTimeouts
if(odone) *odone= 0;
if(obuf==0||odone==0||olen<sizeof(COMMTIMEOUTS)) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
};
*(COMMTIMEOUTS*)obuf= dx->timeout;
rc= TRUE;
*odone= sizeof(COMMTIMEOUTS);
} break;
case 17:{//PurgeComm (terminate pending read/write)
if(ibuf==0||ilen<sizeof(DWORD)) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
};
DWORD f= *(DWORD*)ibuf;
if(f&PURGE_TXABORT) InterlockedTestExchange(&dx->writeuse, 1, 2);
if(f&PURGE_RXABORT) InterlockedTestExchange(&dx->readuse, 1, 2);
if(f&PURGE_RXCLEAR) dx->recvout= dx->recvin;
rc= TRUE;
} break;
case 18:{//SetupComm (SET_QUEUE_SIZE)
//ignored
rc= TRUE;
} break;
case 19:{//TransmitCommChar
if(ibuf==0||ilen<sizeof(BYTE)) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
};
USB_TRANSFER ut= dx->uf->lpIssueBulkTransfer(dx->sendpipe, 0, 0
, USB_OUT_TRANSFER, 1, ibuf, 0);
if(ut) {
DWORD sz= 0;
dx->uf->lpGetTransferStatus(ut, &sz, 0);
dx->uf->lpCloseTransfer(ut);
if(sz==1) rc= TRUE;
};
} break;
case 20:{//GetCommState (GET_DCB)
if(odone) *odone= 0;
if(obuf==0||odone==0||olen<sizeof(DCB)) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
};
*(DCB*)obuf= dx->dcb;
rc= TRUE;
*odone= sizeof(DCB);
} break;
case 21:{//SetCommState (SET_DCB)
if(ibuf==0||ilen<sizeof(DCB)) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
};
if(((DCB*)ibuf)->DCBlength!=sizeof(DCB)) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
};
dx->dcb= *(DCB*)ibuf;
dx->applydcb();
rc= TRUE;
} break;
case 22:{//EscapeCommFunction(SETIR)
rc= FALSE;
} break;
case 23:{//EscapeCommFunction(CLRIR)
rc= TRUE;
} break;
};
InterlockedDecrement(&fx->ref);
return(rc);
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -