Реальные таймауты чтения записи задаются SetCommTimeout. И при некотором везении WaitForSingleObject никогда не вернет WAIT_TIMEOUT, при том, что новых данных в порту нет.
IMHO:
Если чтение в обработчике оконного сообщения, тогда непонятно что за ReadFile в бесконечном цикле.
Если используете же треды -- то overlapped там нафиг не нужен.