NTSTATUS ZwDeviceIoControlFile( IN HANDLE FileHandle, IN HANDLE Event, IN PIO_APC_ROUTINE ApcRoutine, IN PVOID ApcContext, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG IoControlCode, IN PVOID InputBuffer, IN ULONG InputBufferLength, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength ); ApcRoutine Address of an optional, caller-supplied APC routine to be called when the requested operation completes. This parameter can be NULL. It must be NULL if there is an I/O completion object associated with the file object. Я из user-mode вызываю эту функцию, получаю STATUS_PENDING, но обработчик ApcRoutine так и не вызывается. Работает ли вообще ApcRoutine в юзер-моде?
Код (Text): h_device = CreateFile(wz_dev_name, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); ntstatus = ZwDeviceIoControlFile( h_device, 0, ApcComplete, p, &status_block, SOME_REQUEST, wz_name, wcslen(wz_adapter_name) * sizeof(wchar_t) + sizeof(wchar_t), 0, 0 );
Так ведь по идее по завершении операции должна быть вызвана ApcComplete.. дальше я просто проверяю результат и там незначитальные дейтвия, типа SetDlgItemText(..."wait...") или SetDlgItemText(..."success");
Странно, что этой возможности нет в DeviceIoControl - поэтому и складывается такое такое ощущение, что в третьем кольце работает только событие, а асинхронный вызов работает только в нулевом кольце...
Проблемма рашена. Спасибо TarasCo. When a user-mode APC is queued, the thread is not directed to call the APC function unless it is in an alertable state. After the thread is in an alertable state, the thread handles all pending APCs in first in, first out (FIFO) order, and the wait operation returns WAIT_IO_COMPLETION. A thread enters an alertable state by using SleepEx, SignalObjectAndWait, WaitForSingleObjectEx, WaitForMultipleObjectsEx, or MsgWaitForMultipleObjectsEx to perform an alertable wait operation.