📄 comm.c
字号:
static void test_BuildCommDCBAndTimeoutsW(TEST *ptest, int initial_value, DCB *pexpected_dcb, COMMTIMEOUTS *pexpected_timeouts)
{
BOOL result;
DCB dcb;
COMMTIMEOUTS timeouts;
WCHAR wide_string[sizeof(ptest->string)];
MultiByteToWideChar(CP_ACP, 0, ptest->string, -1, wide_string, sizeof(wide_string) / sizeof(WCHAR));
/* set initial conditions */
memset(&dcb, initial_value, sizeof(DCB));
memset(&timeouts, initial_value, sizeof(COMMTIMEOUTS));
SetLastError(0xdeadbeef);
result = BuildCommDCBAndTimeoutsW(wide_string, &dcb, &timeouts);
if(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
return;
/* check results */
check_result("BuildCommDCBAndTimeoutsA", ptest, initial_value, result);
check_dcb("BuildCommDCBAndTimeoutsA", ptest, initial_value, &dcb, pexpected_dcb);
check_timeouts("BuildCommDCBAndTimeoutsA", ptest, initial_value, &timeouts, pexpected_timeouts);
}
static void test_BuildCommDCB(void)
{
char port_name[] = "COMx";
char port = 0;
unsigned int i;
char *ptr;
/* Some of these tests require a valid COM port. This loop will try to find
a valid port. */
for(port_name[3] = '1'; port_name[3] <= '9'; port_name[3]++)
{
COMMCONFIG commconfig;
DWORD size = sizeof(COMMCONFIG);
if(GetDefaultCommConfig(port_name, &commconfig, &size))
{
port = port_name[3];
break;
}
}
if(!port)
trace("Could not find a valid COM port. Some tests will be skipped.\n");
for(i = 0; i < TEST_COUNT; i++)
{
/* Check if this test case needs a valid COM port. */
ptr = strstr(test[i].string, "COMx");
/* If required, substitute valid port number into device control string. */
if(ptr)
{
if(port)
ptr[3] = port;
else
continue;
}
test_BuildCommDCBA(&test[i], 0x00, &test[i].dcb1);
test_BuildCommDCBA(&test[i], 0xff, &test[i].dcb2);
test_BuildCommDCBAndTimeoutsA(&test[i], 0x00, &test[i].dcb1, &test[i].timeouts1);
test_BuildCommDCBAndTimeoutsA(&test[i], 0xff, &test[i].dcb2, &test[i].timeouts2);
test_BuildCommDCBW(&test[i], 0x00, &test[i].dcb1);
test_BuildCommDCBW(&test[i], 0xff, &test[i].dcb2);
test_BuildCommDCBAndTimeoutsW(&test[i], 0x00, &test[i].dcb1, &test[i].timeouts1);
test_BuildCommDCBAndTimeoutsW(&test[i], 0xff, &test[i].dcb2, &test[i].timeouts2);
}
}
static HANDLE test_OpenComm(BOOL doOverlap)
{
HANDLE hcom = INVALID_HANDLE_VALUE;
char port_name[] = "COMx";
static BOOL shown = FALSE;
DWORD errors;
COMSTAT comstat;
/* Try to find a port */
for(port_name[3] = '1'; port_name[3] <= '9'; port_name[3]++)
{
hcom = CreateFile( port_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
(doOverlap)?FILE_FLAG_OVERLAPPED:0, NULL );
if (hcom != INVALID_HANDLE_VALUE)
break;
}
if(!shown)
{
if (hcom == INVALID_HANDLE_VALUE)
trace("Could not find a valid COM port. Skipping test_ReadTimeOut\n");
else
trace("Found Com port %s. Connected devices may disturbe results\n", port_name);
/*shown = TRUE; */
}
if (hcom != INVALID_HANDLE_VALUE)
{
ok(ClearCommError(hcom,&errors,&comstat), "Unexpected errors on open\n");
ok(comstat.cbInQue == 0, "Unexpected %ld chars in InQueue\n",comstat.cbInQue);
ok(comstat.cbOutQue == 0, "Still pending %ld charcters in OutQueue\n", comstat.cbOutQue);
ok(errors == 0, "Unexpected errors 0x%08lx\n", errors);
}
return hcom;
}
static void test_GetModemStatus(HANDLE hcom)
{
DWORD ModemStat;
ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
trace("GetCommModemStatus returned 0x%08lx->%s%s%s%s\n", ModemStat,
(ModemStat &MS_RLSD_ON)?"MS_RLSD_ON ":"",
(ModemStat &MS_RING_ON)?"MS_RING_ON ":"",
(ModemStat &MS_DSR_ON)?"MS_DSR_ON ":"",
(ModemStat &MS_CTS_ON)?"MS_CTS_ON ":"");
}
/* When we don't write anything, Read should time out even on a loopbacked port */
static void test_ReadTimeOut(HANDLE hcom)
{
DCB dcb;
COMMTIMEOUTS timeouts;
char rbuf[32];
DWORD before, after, read, timediff, LastError;
BOOL res;
ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
dcb.BaudRate = FASTBAUD;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.fRtsControl=RTS_CONTROL_ENABLE;
dcb.fDtrControl=DTR_CONTROL_ENABLE;
dcb.StopBits = ONESTOPBIT;
ok(SetCommState(hcom, &dcb), "SetCommState failed\n");
ZeroMemory( &timeouts, sizeof(timeouts));
timeouts.ReadTotalTimeoutConstant = TIMEOUT;
ok(SetCommTimeouts(hcom, &timeouts),"SetCommTimeouts failed\n");
before = GetTickCount();
SetLastError(0xdeadbeef);
res = ReadFile(hcom, rbuf, sizeof(rbuf), &read, NULL);
LastError = GetLastError();
after = GetTickCount();
ok( res == TRUE, "A timed-out read should return TRUE\n");
ok( LastError == 0xdeadbeef, "err=%ld\n", LastError);
timediff = after - before;
ok( timediff > TIMEOUT>>2 && timediff < TIMEOUT *2,
"Unexpected TimeOut %ld, expected %d\n", timediff, TIMEOUT);
}
static void test_waittxempty(HANDLE hcom)
{
DCB dcb;
COMMTIMEOUTS timeouts;
char tbuf[]="test_waittxempty";
DWORD before, after, written, timediff, evtmask = 0;
BOOL res_write, res;
DWORD baud = SLOWBAUD;
trace("test_waittxempty\n");
/* set a low baud rate to have ample time*/
ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
dcb.BaudRate = baud;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.fRtsControl=RTS_CONTROL_ENABLE;
dcb.fDtrControl=DTR_CONTROL_ENABLE;
dcb.StopBits = ONESTOPBIT;
ok(SetCommState(hcom, &dcb), "SetCommState failed\n");
ZeroMemory( &timeouts, sizeof(timeouts));
timeouts.ReadTotalTimeoutConstant = TIMEOUT;
ok(SetCommTimeouts(hcom, &timeouts),"SetCommTimeouts failed\n");
ok(SetupComm(hcom,1024,1024),"SetUpComm failed\n");
ok(SetCommMask(hcom, EV_TXEMPTY), "SetCommMask failed\n");
before = GetTickCount();
res_write=WriteFile(hcom, tbuf, sizeof(tbuf), &written, NULL);
after = GetTickCount();
ok(res_write == TRUE, "WriteFile failed\n");
ok(written == sizeof(tbuf),
"WriteFile: Unexpected write_size %ld , expected %d\n", written, sizeof(tbuf));
trace("WriteFile succeeded, took %ld ms to write %d Bytes at %ld Baud\n",
after - before, sizeof(tbuf), baud);
before = GetTickCount();
res = WaitCommEvent(hcom, &evtmask, NULL);
after = GetTickCount();
ok(res == TRUE, "WaitCommEvent failed\n");
ok((evtmask & EV_TXEMPTY),
"WaitCommEvent: Unexpected EvtMask 0x%08lx, expected 0x%08x\n",
evtmask, EV_TXEMPTY);
timediff = after - before;
trace("WaitCommEvent for EV_TXEMPTY took %ld ms\n", timediff);
/* 050604: This shows a difference between XP (tested with mingw compiled crosstest):
XP returns Writefile only after everything went out of the Serial port,
while wine returns immedate.
Thus on XP, WaintCommEvent after setting the CommMask for EV_TXEMPTY
nearly return immediate,
while on wine the most time is spent here
*/
}
/* A new open handle should not return error or have bytes in the Queues */
static void test_ClearCommErrors(HANDLE hcom)
{
DWORD errors;
COMSTAT lpStat;
ok(ClearCommError(hcom, &errors, &lpStat), "ClearCommError failed\n");
ok(lpStat.cbInQue == 0, "Unexpected %ld chars in InQueue\n", lpStat.cbInQue);
ok(lpStat.cbOutQue == 0, "Unexpected %ld chars in OutQueue\n", lpStat.cbOutQue);
ok(errors == 0, "ClearCommErrors: Unexpected error 0x%08lx\n", errors);
trace("test_ClearCommErrors done\n");
}
static void test_non_pending_errors(HANDLE hcom)
{
DCB dcb;
DWORD err;
ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
dcb.ByteSize = 255; /* likely bogus */
ok(!SetCommState(hcom, &dcb), "SetCommState should have failed\n");
ok(ClearCommError(hcom, &err, NULL), "ClearCommError should succeed\n");
ok(!(err & CE_MODE), "ClearCommError shouldn't set CE_MODE byte in this case (%lx)\n", err);
}
/**/
static void test_LoopbackRead(HANDLE hcom)
{
DCB dcb;
COMMTIMEOUTS timeouts;
char rbuf[32];
DWORD before, after, diff, read, read1, written, evtmask=0, i;
BOOL res;
char tbuf[]="test_LoopbackRead";
trace("Starting test_LoopbackRead\n");
ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
dcb.BaudRate = FASTBAUD;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.fRtsControl=RTS_CONTROL_ENABLE;
dcb.fDtrControl=DTR_CONTROL_ENABLE;
dcb.StopBits = ONESTOPBIT;
ok(SetCommState(hcom, &dcb), "SetCommState failed\n");
ZeroMemory( &timeouts, sizeof(timeouts));
timeouts.ReadTotalTimeoutConstant = TIMEOUT;
ok(SetCommTimeouts(hcom, &timeouts),"SetCommTimeouts failed\n");
ok(SetCommMask(hcom, EV_TXEMPTY), "SetCommMask failed\n");
before = GetTickCount();
ok(WriteFile(hcom,tbuf,sizeof(tbuf),&written, NULL), "WriteFile failed\n");
after = GetTickCount();
ok(written == sizeof(tbuf),"WriteFile %ld bytes written, expected %d\n",
written, sizeof(tbuf));
diff = after -before;
/* make sure all bytes are written, so Readfile will succeed in one call*/
ok(WaitCommEvent(hcom, &evtmask, NULL), "WaitCommEvent failed\n");
before = GetTickCount();
ok(evtmask == EV_TXEMPTY,
"WaitCommEvent: Unexpected EvtMask 0x%08lx, expected 0x%08x\n",
evtmask, EV_TXEMPTY);
trace("Write %ld ms WaitCommEvent EV_TXEMPTY %ld ms\n", diff, before- after);
read=0;
ok(ReadFile(hcom, rbuf, sizeof(rbuf), &read, NULL), "Readfile failed\n");
ok(read == sizeof(tbuf),"ReadFile read %ld bytes, expected %d \"%s\"\n", read, sizeof(tbuf),rbuf);
/* Now do the same withe a slower Baud rate.
As we request more characters then written, we will hit the timeout
*/
ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
dcb.BaudRate = 9600;
dcb.ByteSize = 8;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -