Les E / S synchrones peuvent-elles être annulées automatiquement même si le pilote ne complète pas l’IRP?

En mode utilisateur code:

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

Dans la routine de dissortingbution IRP_MJ_READ du pilote correspondant:

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

Lorsque je termine l’application en mode utilisateur après avoir fait ReadFile (), les E / S peuvent-elles être annulées?
S’il s’agissait d’E / S asynchrones, l’application ne pouvait pas être interrompue.
Mais si les E / S sont synchrones, le gestionnaire d’E / S les annule-t-il automatiquement?

Si c’est le cas, comment?

Tout d’abord, les E / S asynchrones et synchrones sont implémentées avec les IRP. L’API en mode utilisateur ReadFile appelle une API interne NT (appel système) NtReadFile qui finit par envoyer un IRP. Si le pilote retourne STATUS_PENDING, l’API NT retournera le même statut. Si l’application en mode utilisateur effectue un appel synchrone à ReadFile, ReadFile attend sur le descripteur de fichier que les E / S se terminent. Le pilote peut également compléter le protocole IRP de manière synchrone (quelle que soit la manière dont l’API en mode utilisateur est appelée). Je pense que c’est le cas qui vous intéresse.

Les IRP sont associées au thread qui les a envoyées. Ainsi, lorsqu’un thread est arrêté (par exemple en raison de la suppression du processus), le gestionnaire d’E / S tente d’annuler tous les IRP associés à ce thread. Le thread ne peut pas se terminer tant que tous les IRP ne sont pas terminés.

Lorsque vous fermez une poignée, le gestionnaire d’E / S envoie les pilotes IRP_MJ_CLEANUP et IRP_MJ_CLOSE. C’est le pilote qui annule les IRP en attente (ou les complète simplement comme annulé) dans ce cas.

La possibilité d’annuler un IRP dépend de la coopération du conducteur. Le pilote doit explicitement rendre l’ annulation IRP en appelant IoSetCancelRoutine .

Si le pilote ne fait que bloquer sans rendre l’annulation IRP, le IRP ne sera pas annulé.

Sous Vista et les versions ultérieures, vous pouvez utiliser CancelSynchronousIo pour marquer toutes les E / S en attente d’un thread comme étant annulées. NtCancelIoFile (avertissement: je n’ai pas encore testé cette fonction) peut être utilisé pour annuler IO pour un fichier spécifique. Les effets de ces appels varient en fonction de l’implémentation du pilote. Vu de l’application en mode utilisateur, l’effet doit être une annulation immédiate, même si le pilote peut attendre longtemps avant que la demande d’E / S ne soit complètement nettoyée.

http://www.microsoft.com/whdc/driver/kernel/iocancel.mspx a beaucoup d’informations sur l’annulation.