Для простого создания порта нужно в качестве первого
параметра передать INVALID_HANDLE_VALUE, а в качестве второго и третьего – 0.
Для связывания файла с портом нужно указать первые три параметра и
проигнорировать четвертый.
После того, как файл (под файлом здесь подразумевается
объект подсистемы Win32, который реализуется с помощью объекта "файл
исполнительной системы", к таковым относятся файлы, сокеты, почтовые
ящики, именованные каналы и проч.) связан с портом, окончания всех асинхронных
запросов ввода/вывода попадают в очередь порта и могут быть обработаны пулом
потоков. Следующие функции могут быть использованы с портом завершения для
обработки асинхронных операций ввода/вывода:
ConnectNamedPipe – ожидает подключения клиента к
именованному каналу.
DeviceIoControl – низкоуровневый ввод/вывод.
LockFileEx – блокировка региона файла.
ReadDirectoryChangesW – ожидание изменений в
директории.
ReadFile – чтение файла.
TransactNamedPipe – Комбинированное чтение и запись по
именованному каналу, осуществляемые за одну сетевую операцию.
WaitCommEvent – ожидание события последовательного
интерфейса (СОМ-порт).
WriteFile – запись в файл.
Если вы не хотите, чтобы окончание асинхронного
ввода/вывода обрабатывалось портом (например, когда вам не важен результат
операции), нужно использовать следующий трюк [1]. Нужно установить поле hEvent
структуры OVERLAPPED равным описателю события с установленным первым битом.
Делается это примерно так:
OVERLAPPED
ov = {0};
ov.hEvent
= CreateEvent(...);
ov.hEvent
= (HANDLE)((DWORD_PTR)(ov.hEvent) | 1);
|
И не забывайте сбрасывать младший бит при закрытии
хендла события.
Добавлять поток к пулу (подключать его к обработке
запросов) можно с помощью следующей функции: