Что я могу придумать, так это использовать буфер, в котором хранятся куски, приходящие к вам, вы знаете размер через lpNumberOfBytesRead, поэтому для каждого чанка вы проверяете, содержит ли он символ новой строки / s, и если он есть, вы выводите все буферизованные символы до символа новой строки, затем начинайте буферизацию до тех пор, пока не получите другой блок с символами новой строки и т. д.
Некоторые псевдокоды могут выглядеть следующим образом:
w_char buffer[BUFFER_SIZE]; // enough for few chunks (use new to allocate dynamic memory)
ReadLine(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
if (w_char has new_line_character) {
process_whole_line(); // don't forget to clear up the buffer
}