O>>Во первых: CompletionKey ассоциирован с файлом, а не с операцией. И если вы запускаете не более одной операции над файлом — это не значит что их нельзя запустить 1000500. Или запустить одновременно WSASend и WSARecv.
O>Ну даже, если я запущу несколько операцией над сокетом/файлом, зачем мне WSAOVERLAPPED, если "внутреннее назначение полей WSAOVERLAPPED — недокументированные вещи напрямую их ковырять не стоит".
O>Если поля WSAOVERLAPPED напрямую ковырять не стоит — зачем тогда он нужен ?
Это — контескт асинхронной операцции, в его начале на самом деле лежит структура, в которую ядро асинхронно пишет результат — IO_STATUS_BLOCK —
https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_io_status_block — и такую структуру требуют все IO сервисы ядра, типа
https://docs.microsoft.com/en-us/windows/win32/devnotes/ntreadfile.
В случае синхронных апи, типа ReadFile/send() этот контекст можно положить на стек и забыть при завершении операции. Для асинхронных операций этот контекст должен ктото выделить на время работы операции. Этот ктото — это вы.