Народ если у кого есть немного времени объясните пожалуйста что в этом коде происходит. Если есть возможность прокоментируйте по строчкам. Передача данных от драйвера клиентской программе через ассинхронные запросы к устройству.Особенности генерации и обработки ассинхронных запросов. Способ простой, но кривой. Программа регулярно делает DeviceIoControl, драйвер пишет в буфер все, что накопил к данному моменту (возможно, ничего). Способ не кривой, но сложный и потенциально глючный. В клиентской программе: OVERLAPPED o; PVOID pNotificationData; DWORD LastError, dw; HANDLE hEvent = CreateEvent (NULL, // default security FALSE, // ресетится само FALSE, // пока не случилось NULL); // безымянное HANDLE hDevice = CreateFile (DeviceName, DexiredAccess, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED/*важно*/, NULL); o.hEvent = hEvent; for (; { DeviceIoControl (hDevice, IOCTL_NOTIFY_ME, NULL, 0, pNotificationData, MaxDataSize, &dw, &o); LastError = GetLastError (); if (LastError != STATUS_SUCCESS && LastError != ERROR_IO_PENDING) облом; WaitForSingleObject (hEvent, MAX_TIMEOUT/*в миллисекундах, INFINITE – ждать вечно*/); } В драйвере по приходу IRP с кодом IOCTL_NOTIFY_ME: KIRQL kCancelSpin; if (pNotificationIrp)/*глобальный указатель типа PIRP*/ как-то обработать ситуацию; pNotificationIrp = pIrp; IoAcquireCancelSpinLock (&kCancelSpin); IoSetCancelRoutine (pIrp, CancelIrpProc); IoReleaseCancelSpinLock (kCancelSpin); IoMarkIrpPending (Irp); return STATUS_PENDING; void CancelIrpProc (PDEVICE_OBJECT DeviceObject, pPIRP Irp) { IoReleaseCancelSpinLock (pIrp->CancelIrql); pIrp->IoStatus.Status = STATUS_CANCELLED; pIrp->IoStatus.Information = 0; IoCompleteRequest (pIrp, IO_NO_INCREMENT); } В драйвере при наступлении отслеживаемого события: PIRP pTmpIrp; KIRQL kCancelSpin; if (!pNotificationIrp || !MmIsAddressValid (pNotificationIrp)) return FALSE; IoAcquireCancelSpinLock (&kCancelSpin); IoSetCancelRoutine (pNotificationIrp, NULL); IoReleaseCancelSpinLock (kCancelSpin); pNotificationIrp->IoStatus.Information = сколько байт выдаем клиенту; pNotificationIrp->IoStatus.Status = STATUS_SUCCESS; записываем данные в pNotificationIrp->AssociatedIrp.SystemBuffer; pTmpIrp = pNotificationIrp; pNotificationIrp = NULL; IoCompleteRequest (pTmpIrp, IO_NO_INCREMENT); Проблема: если клиентская программа неожиданно завершается, cancel IRP может не произойти и тогда при IoCompleteRequest происходит синий экран. Надо отслеживать жизнедеятельность клиентской программы, например, через именованное событие.
Внимательно не смотрел, но кажется, что кто-то бредил. Посмотри http://www.wasm.ru/article.php?article=drvw2k14 И в DDK есть правильный пример DDK\src\general\event