📄 comm.c
字号:
dcb.Parity = NOPARITY;
dcb.fRtsControl=RTS_CONTROL_ENABLE;
dcb.fDtrControl=DTR_CONTROL_ENABLE;
dcb.StopBits = ONESTOPBIT;
ok(SetCommState(hcom, &dcb), "SetCommState failed\n");
ok(SetCommMask(hcom, EV_RXCHAR), "SetCommMask failed\n");
ok(WriteFile(hcom,tbuf,sizeof(tbuf),&written, NULL), "WriteFile failed\n");
ok(written == sizeof(tbuf),"WriteFile %ld bytes written, expected %d\n",
written, sizeof(tbuf));
trace("WaitCommEventEV_RXCHAR\n");
ok(WaitCommEvent(hcom, &evtmask, NULL), "WaitCommEvent failed\n");
ok(evtmask == EV_RXCHAR, "WaitCommEvent: Unexpected EvtMask 0x%08lx, expected 0x%08x\n",
evtmask, EV_RXCHAR);
before = GetTickCount();
res = ReadFile(hcom, rbuf, sizeof(rbuf), &read, NULL);
after = GetTickCount();
ok(res, "Readfile failed\n");
ok(read == sizeof(tbuf),"ReadFile read %ld bytes, expected %d\n", read, sizeof(tbuf));
diff = after - before;
trace("Readfile for %d chars with %d avail took %ld ms\n",
sizeof(rbuf), sizeof(tbuf), diff);
ok( (diff > TIMEOUT - TIMEDELTA) && (diff < TIMEOUT + TIMEDELTA),
"Timedout Wait took %ld ms, expected around %d\n", diff, TIMEOUT);
/* now do a plain read with slow speed
* This will result in several low level reads and a timeout to happen
*/
dcb.BaudRate = SLOWBAUD;
ok(SetCommState(hcom, &dcb), "SetCommState failed\n");
ok(WriteFile(hcom,tbuf,sizeof(tbuf),&written, NULL), "WriteFile failed\n");
before = GetTickCount();
read = 0;
read1 =0;
i=0;
do
{
res = ReadFile(hcom, rbuf+read, sizeof(rbuf-read), &read1, NULL);
ok(res, "Readfile failed\n");
read += read1;
i++;
}
while ((read < sizeof(tbuf)) && (i <10));
after = GetTickCount();
ok( read == sizeof(tbuf),"ReadFile read %ld bytes, expected %d\n", read, sizeof(tbuf));
trace("Plain Read for %d char at %d baud took %ld ms\n", sizeof(tbuf), SLOWBAUD, after-before);
}
static void test_LoopbackCtsRts(HANDLE hcom)
{
DWORD ModemStat, defaultStat;
DCB dcb;
ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
if (dcb.fRtsControl == RTS_CONTROL_HANDSHAKE)
{
trace("RTS_CONTROL_HANDSHAKE is set, so don't manipulate RTS\n");
return;
}
ok(GetCommModemStatus(hcom, &defaultStat), "GetCommModemStatus failed\n");
/* XP returns some values in the low nibble, so mask them out*/
defaultStat &= MS_CTS_ON|MS_DSR_ON|MS_RING_ON|MS_RLSD_ON;
if(defaultStat & MS_CTS_ON)
{
ok(EscapeCommFunction(hcom, CLRRTS), "EscapeCommFunction failed to clear RTS\n");
ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
ok ((ModemStat & MS_CTS_ON) == 0, "CTS didn't react: 0x%04lx, expected 0x%04lx\n",
ModemStat, (defaultStat & ~MS_CTS_ON));
ok(EscapeCommFunction(hcom, SETRTS), "EscapeCommFunction failed to clear RTS\n");
ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
ok (ModemStat == defaultStat, "Failed to restore CTS: 0x%04lx, expected 0x%04lx\n",
ModemStat, defaultStat);
}
else
{
ok(EscapeCommFunction(hcom, SETRTS), "EscapeCommFunction failed to set RTS\n");
ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
ok ((ModemStat & MS_CTS_ON) == MS_CTS_ON,
"CTS didn't react: 0x%04lx, expected 0x%04lx\n",
ModemStat, (defaultStat | MS_CTS_ON));
ok(EscapeCommFunction(hcom, CLRRTS), "EscapeCommFunction failed to clear RTS\n");
ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
ok (ModemStat == defaultStat, "Failed to restore CTS: 0x%04lx, expected 0x%04lx\n",
ModemStat, defaultStat);
}
}
static void test_LoopbackDtrDcd(HANDLE hcom)
{
DWORD ModemStat, defaultStat;
DCB dcb;
ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
if (dcb.fDtrControl == DTR_CONTROL_HANDSHAKE)
{
trace("DTR_CONTROL_HANDSHAKE is set, so don't manipulate DTR\n");
return;
}
ok(GetCommModemStatus(hcom, &defaultStat), "GetCommModemStatus failed\n");
/* XP returns some values in the low nibble, so mask them out*/
defaultStat &= MS_CTS_ON|MS_DSR_ON|MS_RING_ON|MS_RLSD_ON;
if(defaultStat & MS_RLSD_ON)
{
ok(EscapeCommFunction(hcom, CLRDTR), "EscapeCommFunction failed to clear DTR\n");
ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
ok ((ModemStat & MS_RLSD_ON) == 0, "RLSD didn't react: 0x%04lx, expected 0x%04lx\n",
ModemStat, (defaultStat & ~MS_RLSD_ON));
ok(EscapeCommFunction(hcom, SETDTR), "EscapeCommFunction failed to set DTR\n");
ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
ok (ModemStat == defaultStat, "Failed to restore RLSD: 0x%04lx, expected 0x%04lx\n",
ModemStat, defaultStat);
}
else
{
ok(EscapeCommFunction(hcom, SETDTR), "EscapeCommFunction failed to set DTR\n");
ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
ok ((ModemStat & MS_RLSD_ON) == MS_RLSD_ON,
"RLSD didn't react: 0x%04lx, expected 0x%04lx\n",
ModemStat, (defaultStat | MS_RLSD_ON));
ok(EscapeCommFunction(hcom, CLRDTR), "EscapeCommFunction failed to clear DTR\n");
ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
ok (ModemStat == defaultStat, "Failed to restore RLSD: 0x%04lx, expected 0x%04lx\n",
ModemStat, defaultStat);
}
}
static void test_LoopbackDtrDsr(HANDLE hcom)
{
DWORD ModemStat, defaultStat;
DCB dcb;
ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
if (dcb.fDtrControl == DTR_CONTROL_DISABLE)
{
trace("DTR_CONTROL_HANDSHAKE is set, so don't manipulate DTR\n");
return;
}
ok(GetCommModemStatus(hcom, &defaultStat), "GetCommModemStatus failed\n");
/* XP returns some values in the low nibble, so mask them out*/
defaultStat &= MS_CTS_ON|MS_DSR_ON|MS_RING_ON|MS_RLSD_ON;
if(defaultStat & MS_DSR_ON)
{
ok(EscapeCommFunction(hcom, CLRDTR), "EscapeCommFunction failed to clear DTR\n");
ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
ok ((ModemStat & MS_DSR_ON) == 0, "CTS didn't react: 0x%04lx, expected 0x%04lx\n",
ModemStat, (defaultStat & ~MS_DSR_ON));
ok(EscapeCommFunction(hcom, SETDTR), "EscapeCommFunction failed to clear DTR\n");
ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
ok (ModemStat == defaultStat, "Failed to restore DSR: 0x%04lx, expected 0x%04lx\n",
ModemStat, defaultStat);
}
else
{
ok(EscapeCommFunction(hcom, SETDTR), "EscapeCommFunction failed to set DTR\n");
ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
ok ((ModemStat & MS_DSR_ON) == MS_DSR_ON,
"CTS didn't react: 0x%04lx,expected 0x%04lx\n",
ModemStat, (defaultStat | MS_DSR_ON));
ok(EscapeCommFunction(hcom, CLRDTR), "EscapeCommFunction failed to clear DTR\n");
ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
ok (ModemStat == defaultStat, "Failed to restore DSR: 0x%04lx, expected 0x%04lx\n",
ModemStat, defaultStat);
}
}
static void test_LoopbackDtrRing(HANDLE hcom)
{
DWORD ModemStat, defaultStat;
DCB dcb;
ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
if (dcb.fDtrControl == DTR_CONTROL_HANDSHAKE)
{
trace("DTR_CONTROL_HANDSHAKE is set, so don't manipulate DTR\n");
return;
}
ok(GetCommModemStatus(hcom, &defaultStat), "GetCommModemStatus failed\n");
/* XP returns some values in the low nibble, so mask them out*/
defaultStat &= MS_CTS_ON|MS_DSR_ON|MS_RING_ON|MS_RLSD_ON;
if(defaultStat & MS_RING_ON)
{
ok(EscapeCommFunction(hcom, CLRDTR), "EscapeCommFunction failed to clear DTR\n");
ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
ok ((ModemStat & MS_RING_ON) == 0, "RING didn't react: 0x%04lx, expected 0x%04lx\n",
ModemStat, (defaultStat & ~MS_RING_ON));
ok(EscapeCommFunction(hcom, SETDTR), "EscapeCommFunction failed to set DTR\n");
ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
ok (ModemStat == defaultStat, "Failed to restore RING: 0x%04lx, expected 0x%04lx\n",
ModemStat, defaultStat);
}
else
{
ok(EscapeCommFunction(hcom, SETDTR), "EscapeCommFunction failed to set DTR\n");
ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
ok ((ModemStat & MS_RING_ON) == MS_RING_ON,
"RING didn't react: 0x%04lx,expected 0x%04lx\n",
ModemStat, (defaultStat | MS_RING_ON));
ok(EscapeCommFunction(hcom, CLRDTR), "EscapeCommFunction failed to clear DTR\n");
ok(GetCommModemStatus(hcom, &ModemStat), "GetCommModemStatus failed\n");
ok (ModemStat == defaultStat, "Failed to restore RING: 0x%04lx, expected 0x%04lx\n",
ModemStat, defaultStat);
}
}
/*
* Set up a WaitCommEvent for anything in the receive buffer,
* then write to TX to put a character
* into the RX buffer
* Need Loopback TX->RX
*/
static void test_WaitRx(HANDLE hcom)
{
OVERLAPPED overlapped, overlapped_w;
HANDLE hComPortEvent, hComWriteEvent;
DWORD before, after, after1, diff, success_wait = FALSE, success_write;
DWORD err_wait, err_write, written, evtmask=0;
ok(SetCommMask(hcom, EV_RXCHAR), "SetCommMask failed\n");
hComPortEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
ok(hComPortEvent != 0, "CreateEvent failed\n");
ZeroMemory( &overlapped, sizeof(overlapped));
overlapped.hEvent = hComPortEvent;
ok((hComWriteEvent = CreateEvent( NULL, TRUE, FALSE, NULL )) !=0,
"CreateEvent res 0x%08lx\n",
GetLastError());
ZeroMemory( &overlapped_w, sizeof(overlapped_w));
overlapped_w.hEvent = hComWriteEvent;
before = GetTickCount();
{success_wait = WaitCommEvent(hcom, &evtmask, &overlapped);}
err_wait = GetLastError();
after = GetTickCount();
trace("Success 0x%08lx err 0x%08lx evtmask 0x%08lx\n", success_wait, err_wait, evtmask);
ok(success_wait || err_wait == ERROR_IO_PENDING, "overlapped WaitCommEvent failed\n");
trace("overlapped WriteCommEvent returned.\n");
success_write= WriteFile(hcom, "X", 1, &written, &overlapped_w);
err_write = GetLastError();
ok(success_write || err_write == ERROR_IO_PENDING,
"overlapped WriteFile failed, err 0x%08lx\n",
err_write);
if (!success_write && (err_write == ERROR_IO_PENDING)) {
success_write = WaitForSingleObjectEx(hComWriteEvent, TIMEOUT, TRUE);
err_write = GetLastError();
ok(success_write == WAIT_OBJECT_0, "WaitForSingleObjectEx, res 0x%08lx, err 0x%08lx\n",
success_write, err_write);
}
Sleep(TIMEOUT >>1);
success_write = GetOverlappedResult(hcom, &overlapped_w, &written, FALSE);
err_write = GetLastError();
trace("Write after Wait res 0x%08lx err 0x%08lx\n",success_write, err_write);
ok(success_write && written ==1, "Write after Wait res 0x%08lx err 0x%08lx\n",
success_write, err_write);
if (!success_wait && (err_wait == ERROR_IO_PENDING)) {
success_wait = WaitForSingleObjectEx(hComPortEvent, TIMEOUT, TRUE);
err_wait = GetLastError();
ok(success_wait == WAIT_OBJECT_0, "wait hComPortEvent, res 0x%08lx, err 0x%08lx\n",
success_wait, err_wait);
}
success_wait = GetOverlappedResult(hcom, &overlapped, &written, FALSE);
err_wait = GetLastError();
after1 = GetTickCount();
trace("Success 0x%08lx err 0x%08lx evtmask 0x%08lx diff1 %ld, diff2 %ld\n",
success_wait, err_wait, evtmask, after-before, after1-before);
ok(evtmask & EV_RXCHAR, "Detect EV_RXCHAR: 0x%08lx, expected 0x%08x\n",
evtmask, EV_RXCHAR);
diff = after1 - before;
ok ((diff > (TIMEOUT>>1) -TIMEDELTA) && (diff < (TIMEOUT>>1) + TIMEDELTA),
"Unexpected time %ld, expected around %d\n", diff, TIMEOUT>>1);
}
/* Change the controling line after the given timeout to the given state
By the loopback, this should trigger the WaitCommEvent
*/
static DWORD CALLBACK toggle_ctlLine(LPVOID arg)
{
DWORD *args = (DWORD *) arg;
DWORD timeout = args[0];
DWORD ctl = args[1];
HANDLE hcom = (HANDLE) args[2];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -