Dispatch

La fonction dispatch, c'est l'aiguillage du driver. Elle a été connectée au démarrage du driver

On récupère le contexte du driver (extension), la requête de l'appelant (irp) la copie du tampon de l'appelant (iobuffer)

Notez que si le programme appelant transmet deux tampons séparés, le driver n'en utilise qu'un. Le tampon d'entrée est copié par le système dans le tampon du driver. à la fin du traitement, le tampon du driver est copié dans le tampon de sortie du programme appelant.

Suivant l'ioctl appelant, on peut faire le travail tout de suite et rendre un status STATUS_SUCCESS. Si d'autre traitements sont nécessaire (ex réceptions sous it) il faut rendre un ntStatus = STATUS_PENDING;Le programme appelant reste suspendu jusqu'à ce que d'autres traitements renvoient STATUS_SUCCESS sur cette irp. 

En attendant, le driver continuera à traiter d'autres irps.

// simpldrvit.c driver it en mode kernel 
extern "C"
{
#include "ntddk.h"
#include "stdarg.h"
#include "stdio.h"
}
extern "C"
{
// interfaces externes/interne
#include "driver.h"
}


//********************************************************************************************

// fonction de dispatching du driver pour recupérer l'IRP
NTSTATUS MonDriverDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
    PIO_STACK_LOCATION irpStack;
    PDEVICE_EXTENSION deviceExtension;
    ULONG ioControlCode;
    NTSTATUS ntStatus;
    ULONG inputBufferLength;
    ULONG outputBufferLength;
    PVOID ioBuffer;
    KIRQL savIrq;
    long wait; // pour traitement time out

    // char *message;
    Irp->IoStatus.Status = STATUS_SUCCESS; // retour de l'IRP
    Irp->IoStatus.Information = 0;


    // recupère le point d'entrée pour le code fonction et les paramêtres dans l'IRP
    irpStack = IoGetCurrentIrpStackLocation (Irp);
    // récupère l'extension du device Object 
    deviceExtension = (class deviceExtension *)DeviceObject->DeviceExtension; 
    // récupère les infos sur les buffers
    ioBuffer = Irp->AssociatedIrp.SystemBuffer;
    inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
    outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
    wait = 0; // à priori pas de mise en attente de l'irp

// récupère le code fonction et appelle la bonne fonction en conséquence 
switch (irpStack->MajorFunction)
{
    case IRP_MJ_CREATE: // lors de la fonction Create file 
    break; 

    case IRP_MJ_CLOSE: // lors de la fermeture du fichier CloseHandle
    break; 

    case IRP_MJ_DEVICE_CONTROL: // lors d'un appel par DEVICEIO
    // récupération du code de controle passé au driver par DEVICEIO
    ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
    switch (ioControlCode) 
    {
        //
        // Pour chaque code ioctl défini dans l'interface
            case IOCTL_IOCTL_RE_INITIALIZE : 
                if((inputBufferLength != sizeof(TMonDriverMsgInRE_INITIALIZE)) 
                        || (outputBufferLength < sizeof(MonDriverMsgOutRE_INITIALIZE)) ) 
                    Irp->IoStatus.Status = STATUS_INVALID_BUFFER_SIZE; 
            else
            { 
                TMonDriverMsgInRE_INITIALIZE *msgIn = (TMonDriverMsgInRE_INITIALIZE *) ioBuffer; 
                TMonDriverRE_INITIALIZE *msgOut = (TMonDriverMsgOutRE_INITIALIZE *) ioBuffer;
                //

                // code de traitement de la demande

                Irp->IoStatus.Information = sizeof(TMonDriverNtMsgOutRE_INITIALIZE); 
                Irp->IoStatus.Status = STATUS_SUCCESS; 
            }; 

        case autre ioctl....

    }
    return ntStatus; // succes ou erreur 
}


Accueil ] Remonter ] IOport ] IOmem ] Interruption ] Ressources ]