// <...>
BOOL bWRes = WaitCommEvent(hComm, &evtMask, &ovOverlapped);
printf("After WaitCommEvent 1.\n");
if (!bWRes)
{
    if ((dwError = GetLastError()) == ERROR_IO_PENDING)
    {    // Запущено ожидание события COM порта
        //fWaitOnStat = TRUE;
WHILE_LOOP:
        dwResult = WaitForSingleObject(ovOverlapped.hEvent, 50);

        printf("%d: WaitForSingleObject, retval=%d\n", i++, dwResult);
        switch(dwResult)
        {
        case WAIT_TIMEOUT:
            //Ничего не произошло по таймауту, ждем...
            Sleep(1);
            goto WHILE_LOOP;
            break;
        case WAIT_FAILED:
            printf("FATAL. WaitForSingleObject WAIT_FAILED.\n");
            // WaitForSingleObject завершилась неудачно
            fWaitOnStat = FALSE;    // Произошло событие COM порта
            break;
        case WAIT_OBJECT_0:
            if (!(bOvResult = GetOverlappedResult(hComm, &ovOverlapped, &dwOvRes, FALSE)))
            {
                printf("FATAL. GetOverlappedResult() system error.\n");
                // GetOverlappedResult завершилась неудачно
                return 0;
                break;
            }
            else
            {
                // Анализируем событие
                // Произошло событие COM порта
                if (evtMask & EV_RXCHAR)
                {
                    memset(m_buf, 0 , ncBufferSize);
                    printf("ReadFile start.\n");
                    if (!(dwReadResult = ReadFile(hComm, m_buf, ncBufferSize, &dwRead, &ovOverlapped)))
                    {//Начинаем операцию чтения из порта
                        printf("ReadFile done.\n");
                        dwError = GetLastError();
                        if (dwError == ERROR_IO_PENDING)
                        {
                            printf("dwError==ERROR_IO_PENDING\n");
                            bOvResult = GetOverlappedResult(hComm, &ovOverlapped, &dwOvRes, FALSE);
                            dwError = GetLastError();
                            if (!bOvResult)
                                while (dwError == ERROR_IO_INCOMPLETE)
                                {//Wine get stuck in this loop.
                                    printf("Waiting for result.\tovOverlapped.Internal=%lu\t(Here wine get stuck. But windows gets some event and going on.\n",ovOverlapped.Internal);

                                    bOvResult = GetOverlappedResult(hComm, &ovOverlapped, &dwOvRes, FALSE);
                                    dwError = GetLastError();
                                    if (bOvResult) break;
                                    if (!bOvResult && (dwError != ERROR_IO_INCOMPLETE)) break;
                                    Sleep(50);
                                }

                                if (bOvResult)
                                {/* ALL IS GREAT */}
                        }
                    }
                }//if (evtMask & EV_RXCHAR)
                else if (evtMask & EV_BREAK)
                {
                    return 0;
                    break;
                }
                else Sleep(1);
            }
            break;
        }
    }
    else
    {    // Ошибка функции WaitCommEvent
        printf("FATAL. WaitCommEvent error (%d).\n", dwError);
    }
}
else
{    // WaitCommEvent вернула управление сразу
    printf("WaitCommEvent 2.\n");
    Sleep(1);
}
//<...>

