def _get_overlapped_result_ex_impl(pipe, olap, nbytes, millis, alertable):
    """ Windows 7 and earlier does not support GetOverlappedResultEx. The
    alternative is to use GetOverlappedResult and wait for read or write
    operation to complete. This is done be using CreateEvent and
    WaitForSingleObjectEx. CreateEvent, WaitForSingleObjectEx
    and GetOverlappedResult are all part of Windows API since WindowsXP.
    This is the exact same implementation that can be found in the watchman
    source code (see get_overlapped_result_ex_impl in stream_win.c). This
    way, maintenance should be simplified.
    """
    log("Preparing to wait for maximum %dms", millis)
    if millis != 0:
        waitReturnCode = WaitForSingleObjectEx(olap.hEvent, millis, alertable)
        if waitReturnCode == WAIT_OBJECT_0:
            # Event is signaled, overlapped IO operation result should be available.
            pass
        elif waitReturnCode == WAIT_IO_COMPLETION:
            # WaitForSingleObjectEx returnes because the system added an I/O completion
            # routine or an asynchronous procedure call (APC) to the thread queue.
            SetLastError(WAIT_IO_COMPLETION)
            pass
        elif waitReturnCode == WAIT_TIMEOUT:
            # We reached the maximum allowed wait time, the IO operation failed
            # to complete in timely fashion.
            SetLastError(WAIT_TIMEOUT)
            return False
        elif waitReturnCode == WAIT_FAILED:
            # something went wrong calling WaitForSingleObjectEx
            err = GetLastError()
            log("WaitForSingleObjectEx failed: %s", _win32_strerror(err))
            return False
        else:
            # unexpected situation deserving investigation.
            err = GetLastError()
            log("Unexpected error: %s", _win32_strerror(err))
            return False

    return GetOverlappedResult(pipe, olap, nbytes, False)