I have reworked this to simplify the code so you can see how to manage overlapped operations, and capture the results correctly.
#include <Windows.h>
#include <iostream>
#include <string>
int main()
{
HANDLE hFile = CreateFileA(
"MainFile.txt",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL
);
if (hFile == INVALID_HANDLE_VALUE) {
std::cout << "****CreateFileA: Error " << GetLastError() << "****" << std::endl;
return 1;
}
LPCSTR lpszPrompt1{ "Option: " };
DWORD dwWritten;
DWORD dwError;
OVERLAPPED ovWrite = { 0, 0, 0, 0, CreateEvent(NULL, FALSE, FALSE, "ovWrite") };
if (!WriteFile(
hFile,
lpszPrompt1,
lstrlen(lpszPrompt1),
&dwWritten,
&ovWrite))
{
dwError = GetLastError();
if (dwError != ERROR_IO_PENDING)
{
std::cout << "****WriteFile: Error " << GetLastError() << "****" << std::endl;
ExitProcess(0);
}
else
{
std::cout << "WriteFile returned ERROR_IO_PENDING" << std::endl;
BOOL bw = GetOverlappedResult(hFile, &ovWrite, &dwWritten, TRUE);
if (!bw)
{
std::cout << "GetOverlappedResult failed" << std::endl;
}
}
}
std::cout << "WriteFile wrote " << dwWritten << " bytes" << std::endl;
DWORD dwRead;
CHAR chBuffer[200]{};
OVERLAPPED ovRead = { 0, 0, 0, 0, CreateEvent(NULL, FALSE, FALSE, "ovRead") };
if (!ReadFile(
hFile,
chBuffer,
200,
&dwRead,
&ovRead))
{
dwError = GetLastError();
if (dwError != ERROR_IO_PENDING)
{
std::cout << "****ReadFile: Error " << GetLastError() << "****" << std::endl;
ExitProcess(0);
}
else
{
std::cout << "ReadFile returned ERROR_IO_PENDING" << std::endl;
BOOL bw = GetOverlappedResult(hFile, &ovRead, &dwRead, TRUE);
if (!bw)
{
std::cout << "GetOverlappedResult failed" << std::endl;
}
}
}
std::cout << "ReadFile read " << dwRead << " bytes: ";
std::cout << "\"" << chBuffer << "\"" << std::endl;
CloseHandle(hFile);
return 0;
}
I have run tests on the above code and the output is:
WriteFile returned ERROR_IO_PENDING
WriteFile wrote 8 bytes
ReadFile returned ERROR_IO_PENDING
ReadFile read 8 bytes: "Option: "