Можно ли отменить синхронный ввод-вывод автоматически, даже если драйвер не завершил IRP? - PullRequest
2 голосов
/ 15 февраля 2011

В коде пользовательского режима:

CreateFile(A device);
ReadFile(The device handle); // synchronously

В соответствующей процедуре отправки драйвера IRP_MJ_READ:

// To hold the irp. It will never complete the irp.
// This driver doesn't even have a cancel routine.
Sleep(INFINITE); 

Когда я принудительно завершаю приложение пользовательского режима после выполнения ReadFile (), могу ли яОтменить ввод / вывод?
Если это был асинхронный ввод / вывод, приложение не может быть прервано.
Но если ввод / вывод является синхронным, диспетчер ввода / вывода отменяет его автоматически?

Если да, то как?

Ответы [ 2 ]

3 голосов
/ 23 февраля 2011

Во-первых, как асинхронный, так и синхронный ввод-вывод реализованы с помощью IRP. API пользовательского режима ReadFile вызывает внутренний NT API (системный вызов) NtReadFile, который в итоге отправляет IRP. Если драйвер возвращает STATUS_PENDING, NT API вернет тот же статус. Если приложение пользовательского режима выполняет синхронный вызов ReadFile, ReadFile будет ожидать в дескрипторе файла завершения ввода-вывода. Драйвер также может выполнять IRP синхронно (независимо от того, как вызывается API пользовательского режима). Я думаю, что это тот случай, который вас интересует.

IRP связаны с потоком, который их отправил. Поэтому, когда поток завершается (например, из-за уничтожения процесса), менеджер ввода-вывода пытается отменить все IRP, связанные с этим потоком. Поток не может завершиться, пока не завершены все IRP.

Когда вы закрываете дескриптор, менеджер ввода-вывода отправляет драйвер IRP_MJ_CLEANUP и IRP_MJ_CLOSE. Это драйвер , который отменяет ожидающие IRP (или просто завершает их как отмененные) в этом случае.

Возможность отмены IRP зависит от сотрудничества водителя. Драйвер должен явно отменить IRP, вызвав IoSetCancelRoutine .

Если драйвер просто блокируется без отмены IRP, IRP не будет отменен.

3 голосов
/ 15 февраля 2011

В Vista и выше вы можете использовать CancelSynchronousIo, чтобы пометить все ожидающие операции ввода-вывода для потока как отмененные. NtCancelIoFile (заявление об отказе: я на самом деле не тестировал эту функцию) можно использовать для отмены ввода-вывода для определенного файла. Эффекты этих вызовов будут различаться, в зависимости от на реализацию драйвера. Если смотреть из приложения пользовательского режима, эффект должен быть немедленным отменой, даже если драйвер может долго ждать, пока запрос IO не будет полностью очищен.

http://www.microsoft.com/whdc/driver/kernel/iocancel.mspx имеет много информации об отмене.

...