184 lines
3.6 KiB
C
184 lines
3.6 KiB
C
|
|
||
|
//
|
||
|
// Test the quick return timeouts
|
||
|
//
|
||
|
// Assume that we are using a loopback connector.
|
||
|
//
|
||
|
// Assume that it isn't running on a stressed machine.
|
||
|
//
|
||
|
|
||
|
#include "windows.h"
|
||
|
#include "stdio.h"
|
||
|
|
||
|
#define FAILURE printf("FAIL: %d\n",__LINE__);exit(1)
|
||
|
|
||
|
int _CRTAPI1 main(int argc, char *argv[]) {
|
||
|
CHAR *myPort = "COM1";
|
||
|
DCB myDcb;
|
||
|
DWORD junk;
|
||
|
COMMTIMEOUTS myTimeOuts;
|
||
|
DWORD numberActuallyRead;
|
||
|
DWORD numberActuallyWritten;
|
||
|
UCHAR readBuff[1000];
|
||
|
HANDLE comHandle;
|
||
|
DWORD startingTicks;
|
||
|
OVERLAPPED readOl;
|
||
|
OVERLAPPED writeOl;
|
||
|
UCHAR writeBuff[5] = {0,1,2,3,4};
|
||
|
|
||
|
if (argc > 1) {
|
||
|
|
||
|
myPort = argv[1];
|
||
|
|
||
|
}
|
||
|
|
||
|
if ((comHandle = CreateFile(
|
||
|
myPort,
|
||
|
GENERIC_READ | GENERIC_WRITE,
|
||
|
0,
|
||
|
NULL,
|
||
|
CREATE_ALWAYS,
|
||
|
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
|
||
|
NULL
|
||
|
)) == ((HANDLE)-1)) {
|
||
|
|
||
|
FAILURE;
|
||
|
|
||
|
}
|
||
|
|
||
|
if (!(readOl.hEvent = CreateEvent(
|
||
|
NULL,
|
||
|
TRUE,
|
||
|
FALSE,
|
||
|
NULL
|
||
|
))) {
|
||
|
|
||
|
FAILURE;
|
||
|
|
||
|
}
|
||
|
|
||
|
if (!GetCommState(
|
||
|
comHandle,
|
||
|
&myDcb
|
||
|
)) {
|
||
|
|
||
|
FAILURE;
|
||
|
|
||
|
}
|
||
|
|
||
|
myDcb.BaudRate = 19200;
|
||
|
myDcb.ByteSize = 8;
|
||
|
myDcb.StopBits = ONESTOPBIT;
|
||
|
myDcb.Parity = NOPARITY;
|
||
|
myDcb.fOutxCtsFlow = FALSE;
|
||
|
myDcb.fOutxDsrFlow = FALSE;
|
||
|
myDcb.fDsrSensitivity = FALSE;
|
||
|
myDcb.fOutX = FALSE;
|
||
|
myDcb.fInX = FALSE;
|
||
|
myDcb.fRtsControl = RTS_CONTROL_ENABLE;
|
||
|
myDcb.fDtrControl = DTR_CONTROL_ENABLE;
|
||
|
if (!SetCommState(
|
||
|
comHandle,
|
||
|
&myDcb
|
||
|
)) {
|
||
|
|
||
|
FAILURE;
|
||
|
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Make sure that the IO doesn't time out.
|
||
|
//
|
||
|
|
||
|
myTimeOuts.ReadIntervalTimeout = 0;
|
||
|
myTimeOuts.ReadTotalTimeoutMultiplier = 0;
|
||
|
myTimeOuts.ReadTotalTimeoutConstant = 0;
|
||
|
myTimeOuts.WriteTotalTimeoutMultiplier = 0;
|
||
|
myTimeOuts.WriteTotalTimeoutConstant = 0;
|
||
|
|
||
|
if (!SetCommTimeouts(
|
||
|
comHandle,
|
||
|
&myTimeOuts
|
||
|
)) {
|
||
|
|
||
|
FAILURE;
|
||
|
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Start off a read. It shouldn't complete
|
||
|
//
|
||
|
|
||
|
if (!ReadFile(
|
||
|
comHandle,
|
||
|
&readBuff[0],
|
||
|
1000,
|
||
|
&numberActuallyRead,
|
||
|
&readOl
|
||
|
)) {
|
||
|
|
||
|
if (GetLastError() != ERROR_IO_PENDING) {
|
||
|
|
||
|
FAILURE;
|
||
|
|
||
|
}
|
||
|
|
||
|
if (GetOverlappedResult(
|
||
|
comHandle,
|
||
|
&readOl,
|
||
|
&numberActuallyRead,
|
||
|
FALSE
|
||
|
)) {
|
||
|
|
||
|
FAILURE;
|
||
|
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
|
||
|
FAILURE;
|
||
|
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// The read should still be there. Now do a purge comm. We
|
||
|
// should then do a sleep for 2 seconds to give the read time
|
||
|
// to complete. Then we should first make sure that the
|
||
|
// read has completed (via a get overlapped). Then we should
|
||
|
// do a SetupComm (with a "large" value so that we will actually
|
||
|
// allocate a new typeahead buffer). If there is still a "dangling"
|
||
|
// read, then we should never return from SetupComm.
|
||
|
//
|
||
|
|
||
|
if (!PurgeComm(
|
||
|
comHandle,
|
||
|
PURGE_TXABORT | PURGE_RXABORT
|
||
|
)) {
|
||
|
|
||
|
FAILURE;
|
||
|
|
||
|
}
|
||
|
|
||
|
if (WaitForSingleObject(
|
||
|
readOl.hEvent,
|
||
|
2000
|
||
|
) != WAIT_OBJECT_0) {
|
||
|
|
||
|
FAILURE;
|
||
|
|
||
|
}
|
||
|
|
||
|
if (!SetupComm(
|
||
|
comHandle,
|
||
|
20000,
|
||
|
20000
|
||
|
)) {
|
||
|
|
||
|
FAILURE;
|
||
|
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
|
||
|
}
|