The CancelIoEx function can be used to cancel synchronous I/O.
This is handy if you have a program that processes a file in large chunks and you want to give it a Cancel button. Without CancelIoEx, you would either have to accept that the program won’t respond to the Cancel button until the large I/O is complete, or you would have to change your program so it processed the file in small chunks, which is less efficient.
But with CancelIoEx, you can do your large chunk processing and still let the user cancel it immediately.
#define STRICT
#include <windows.h>
#include <stdio.h>
#define FILESIZE (200*1024*1024)
DWORD CALLBACK ThreadProc(void* h)
{
void* buffer = VirtualAlloc(0, FILESIZE, MEM_COMMIT, PAGE_READWRITE);
DWORD actual;
auto result = ReadFile(h, buffer, FILESIZE, &actual, 0);
auto lastError = GetLastError();
printf("ReadFile -> %d, GetLastError = %d\n", result, lastError);
return 0;
}
int __cdecl main(int, char**)
{
auto h = CreateFile("D:\\setup.exe", GENERIC_READ, 0, 0,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_NO_BUFFERING, 0);
DWORD id;
auto thread = CreateThread(0, 0, ThreadProc, h, 0, &id);
Sleep(1000);
CancelIoEx(h, nullptr);
WaitForSingleObject(thread, INFINITE);
return 0;
}
This program reads 200MB of data from a file that I hard-coded, which on my machine happens to be on a CD-ROM. One thread reads the beginning portion of the file into memory, and the other thread calls CancelIoEx to cancel the large I/O operation.
ReadFile -> 0, GetLastError = 995
Error 995 is
C:\> NET HELPMSG 995 The I/O operation has been aborted because of either a thread exit or an application request.
which corresponds to ERROR_OPERATION_ABORTED, just like the documentation says.
Related reading: CancelIoEx can cancel I/O on console input, which is kind of nice.
0 comments