Partager via


FltSendMessage, fonction (fltkernel.h)

FltSendMessage envoie un message à une application en mode utilisateur en attente au nom d’un pilote minifilter ou d’une instance de pilote minifilter.

Syntaxe

NTSTATUS FLTAPI FltSendMessage(
  [in]            PFLT_FILTER    Filter,
  [in]            PFLT_PORT      *ClientPort,
  [in]            PVOID          SenderBuffer,
  [in]            ULONG          SenderBufferLength,
  [out, optional] PVOID          ReplyBuffer,
  [in, out]       PULONG         ReplyLength,
  [in, optional]  PLARGE_INTEGER Timeout
);

Paramètres

[in] Filter

Pointeur de filtre opaque pour l’appelant. Ce paramètre est obligatoire et ne peut pas être NULL.

[in] ClientPort

Pointeur vers une variable qui contient le pointeur de port client opaque pour le port de connexion entre l’application en mode utilisateur et le pilote minifilter en mode noyau. Pour plus d’informations sur le pointeur de port client, consultez la description du paramètre ConnectNotifyCallback dans l’entrée de référence pour FltCreateCommunicationPort.

[in] SenderBuffer

Pointeur vers une mémoire tampon allouée par un minifiltre contenant le message à envoyer à l’application en mode utilisateur. Ce paramètre est obligatoire et ne peut pas être NULL.

[in] SenderBufferLength

Taille, en octets, de la mémoire tampon vers laquelle SenderBuffer pointe. Pour plus d’informations, consultez remarques.

[out, optional] ReplyBuffer

Pointeur vers une mémoire tampon allouée par miniport qui reçoit une réponse de l’application, le cas échéant. Ce paramètre est facultatif et peut être NULL.

[in, out] ReplyLength

Taille, en octets, de la mémoire tampon vers laquelle ReplyBuffer pointe vers. Ce paramètre est facultatif, mais doit être non NULL lorsque ReplyBuffer n’est pas NULL.

[in, optional] Timeout

Pointeur vers une valeur de délai d’expiration qui spécifie la durée absolue ou relative totale, en unités de 100 nanosecondes, pendant laquelle l’appelant (miniport) peut être mis dans un état d’attente jusqu’à ce que le message soit reçu par l’application en mode utilisateur et jusqu’à ce qu’elle reçoive une réponse si une réponse est attendue.

Une valeur positive spécifie une heure absolue, par rapport au 1er janvier 1601. Une valeur négative spécifie un intervalle par rapport à l’heure actuelle. Définissez le délai d’attente sur NULL si l’appelant peut être mis en état d’attente indéfiniment.

Valeur de retour

FltSendMessage retourne STATUS_SUCCESS ou une valeur NTSTATUS appropriée, comme l’une des opérations suivantes :

Retourner le code Descriptif
STATUS_BUFFER_OVERFLOW Une mémoire tampon allouée par miniport n’était pas assez grande. Il s’agit d’un code d’erreur.
STATUS_INSUFFICIENT_RESOURCES FltSendMessage a rencontré un échec d’allocation de pool. Il s’agit d’un code d’erreur.
STATUS_PORT_DISCONNECTED Le port de communication a été déconnecté. Il s’agit d’un code d’erreur.
STATUS_THREAD_IS_TERMINATING L’attente a été interrompue, car le thread a été arrêté par une application ou un utilisateur.
STATUS_TIMEOUT Délai d’expiration intervalle expiré avant la remise du message ou avant la réception d’une réponse. Il s’agit d’un code de réussite.

Remarques

FltSendMessage envoie un message à une application en mode utilisateur au nom d’un pilote minifilter ou d’une instance de pilote minifilter.

Si l’application appelle FilterGetMessage pour obtenir le message avant que le pilote de minifiltre n’appelle FltSendMessage pour l’envoyer, le message vers lequel pointe SendBuffer est remis immédiatement lorsque FltSendMessage est appelé. Cela est généralement le cas lorsque l’application appelle FilterGetMessage à partir d’une boucle de message.

Sinon, si une application n’a pas appelé pour obtenir un message, FltMgr met le minifiltre dans un état d’attente comme suit :

  • Si le délai d’expiration pointe vers une valeur différente de zéro et que l’application appelle FilterGetMessage avant l’expiration de l’intervalle de délai d’expiration , le message est remis.

  • Si le délai d’expiration pointe vers une valeur différente de zéro et que l’application n’appelle pas FilterGetMessage avant l’expiration de l’intervalle de délai d’expiration , le message n’est pas remis et FltSendMessage renvoie STATUS_TIMEOUT en tant que code de réussite.

  • Si le délai d’expiration pointe vers zéro (*Timeout == 0), FltSendMessage renvoie sans attendre.

  • Si Timeout est NULL (Timeout == NULL), le minifiltre est mis en état d’attente indéfiniment. Lorsque l’application appelle FilterGetMessage, le message est remis.

Une fois le message remis, si ReplyBuffer a la valeur NULL, FltSendMessage renvoie STATUS_SUCCESS.

Sinon, si ReplyBuffer n’est pas NULL, le minifiltre est placé dans un état d’attente comme suit :

  • Si le délai d’expiration est différent de zéro et que l’application appelle FilterReplyMessage avant l’expiration de l’intervalle de délai d’expiration , le minifiltre reçoit la réponse et FltSendMessage renvoie STATUS_SUCCESS.

  • Si le délai d’expiration est différent de zéro et que le minifiltre ne reçoit pas de réponse avant l’expiration de l’intervalle de délai d’expiration , FltSendMessage renvoie STATUS_TIMEOUT en tant que code de réussite.

  • Si le délai d’expiration pointe vers zéro (*Timeout == 0), FltSendMessage renvoie sans attendre.

  • Si le délai d’attente est égal à zéro lorsque le minifiltre attend la réponse, le minifiltre est mis en état d’attente indéfiniment. Lorsque l’application appelle FilterReplyMessage, le minifiltre reçoit la réponse et FltSendMessage renvoie STATUS_SUCCESS.

Remplissage et taille de la mémoire tampon

Des problèmes peuvent se produire lorsque l’appelant ne tient pas compte correctement du remplissage de structure spécifique au système qui peut se produire.

Par exemple, supposons qu’un minifiltre déclare la structure suivante dans laquelle recevoir une réponse et lui passe un pointeur dans ReplyBuffer :

typedef struct _REPLY_STRUCT
{
    FILTER_REPLY_HEADER Header;
    REPLY_DATA Data;  // The structure to be sent to the minifilter with the reply.
} REPLY_STRUCT, *PREPLY_STRUCT;

ReplyBuffer doit être alloué avec suffisamment d’espace pour contenir toute la structure, y compris tout remplissage. Par conséquent, ReplyLength doit être défini sur sizeof(REPLY_STRUCT), et non sizeof(FILTER_REPLY_HEADER) + sizeof(REPLY_DATA).

La définition de ReplyLengthsizeof(FILTER_REPLY_HEADER) + sizeof(REPLY_DATA) ne tient pas compte du remplissage qui peut être inséré entre les membres d’en-tête et de données . Cela peut entraîner le retour de FltSendMessage STATUS_BUFFER_OVERFLOW même lorsque la mémoire tampon est suffisamment grande pour contenir les deux structures.

Une fois que FltSendMessage retourne correctement, utilisez offsetof(REPLY_STRUCT, Data) pour localiser le début de la structure de données dans ReplyBuffer et examinez la valeur de sortie ReplyLength pour déterminer le nombre réel d’octets écrits par l’application en mode utilisateur.

Exigences

Exigence Valeur
client minimum pris en charge Correctif cumulatif Windows 2000 1 pour SP4, Windows XP SP2
Serveur minimal pris en charge Windows Server 2003 SP1
plateforme cible Universel
d’en-tête fltkernel.h (inclut FltKernel.h)
bibliothèque FltMgr.lib
DLL Fltmgr.sys
IRQL <= APC_LEVEL

Voir aussi

FilterGetMessage

FiltreRépondreMessage

filterSendMessage

FltCreateCommunicationPort