Reputation: 139
I am opening and reading a port from a USB device (thermal printer):
HANDLE hUsb = CreateFile(symbolicName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
ReadFile(hUsb, buffer, bytes, &read, NULL);
I need to setup timeout to read, but it's an USB port, not a COM port, so I can't use the function SetCommTimeouts.
Is there any function that I can use and has the same effect of SetCommTimeouts?
If there's a simply way, I prefer to not use thread.
I am using Visual Studio 2010 with Windows 10.
Grateful.
Upvotes: 1
Views: 714
Reputation: 33744
first of all any Visual Studio here absolute unrelated.
general solution - use asynchronous io, which never block. and you can yourself cancel io operation by some timeout. good way of course set timer (via CreateTimerQueueTimer
) and cancel io in timer callback. or if io will complete before this - cancel timer. but if want simplest implementation, which do synchronous io in place - possible do next:
inline ULONG BOOL_TO_ERROR(BOOL f)
{
return f ? NOERROR : GetLastError();
}
//------------------------------------------------------------------------
HANDLE hFile = CreateFileW(symbolicName, FILE_GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
OVERLAPPED ov = {};
if (ov.hEvent = CreateEventW(0, 0, 0, 0))
{
char buf[16];
ULONG NumberOfBytesRead = 0;
ULONG err = BOOL_TO_ERROR(ReadFile(hFile, buf, sizeof(buf), 0, &ov));
switch (err)
{
case ERROR_IO_PENDING:
if (WaitForSingleObject(ov.hEvent, timeout) != WAIT_OBJECT_0)
{
CancelIo(hFile);
}
case NOERROR:
err = BOOL_TO_ERROR(GetOverlappedResult(hFile, &ov, &NumberOfBytesRead, TRUE));
break;
}
CloseHandle(ov.hEvent);
}
CloseHandle(hFile);
}
Upvotes: 1