Partager via


WdfRequestProbeAndLockUserBufferForRead, fonction (wdfrequest.h)

[S’applique uniquement à KMDF]

La méthode WdfRequestProbeAndLockUserBufferForRead vérifie qu’une mémoire tampon en mode utilisateur d’une requête d’E/S est lisible, puis verrouille les pages de mémoire physique de la mémoire tampon afin que les pilotes de la pile des pilotes puissent lire la mémoire tampon.

Syntaxe

NTSTATUS WdfRequestProbeAndLockUserBufferForRead(
  [in]  WDFREQUEST Request,
  [in]  PVOID      Buffer,
  [in]  size_t     Length,
  [out] WDFMEMORY  *MemoryObject
);

Paramètres

[in] Request

Handle vers un objet de requête de framework.

[in] Buffer

Pointeur vers la mémoire tampon d’entrée de la requête. Pour plus d’informations, consultez la section Remarques suivante.

[in] Length

Longueur, en octets, de la mémoire tampon d’entrée de la requête.

[out] MemoryObject

Pointeur vers un emplacement qui reçoit un handle vers un objet mémoire framework qui représente la mémoire tampon d’entrée utilisateur.

Valeur de retour

WdfRequestProbeAndLockUserBufferForRead retourne STATUS_SUCCESS si l’opération réussit. Sinon, cette méthode peut retourner l’une des valeurs suivantes :

Retourner le code Description
STATUS_INVALID_PARAMETER
Un paramètre d’entrée n’est pas valide.
STATUS_INVALID_USER_BUFFER
Le paramètre Length est égal à zéro.
STATUS_INVALID_DEVICE_REQUEST
La demande a déjà été effectuée ou n’est pas valide.
STATUS_ACCESS_VIOLATION
Le thread actuel n’est pas le créateur de la requête d’E/S.
STATUS_INSUFFICIENT_RESOURCES
La mémoire est insuffisante pour terminer l’opération.
 

Cette méthode peut également retourner d’autres valeurs NTSTATUS .

Une vérification de bogue se produit si le pilote fournit un handle d’objet non valide.

Remarques

Seul un pilote de niveau supérieur peut appeler la méthode WdfRequestProbeAndLockUserBufferForRead, car la méthode nécessite le contexte de processus du processus qui a créé la requête d’E/S.

La mémoire tampon d’entrée utilisateur contient généralement des informations à écrire sur l’appareil.

La mémoire tampon en mode utilisateur spécifiée par le paramètre Buffer peut être la mémoire tampon qui WdfRequestRetrieveUnsafeUserInputBuffer récupère, ou il peut s’agir d’une mémoire tampon d’entrée en mode utilisateur différente. Par exemple, un code de contrôle d’E/S qui utilise la méthode d’accès mis en mémoire tampon peut passer une structure qui contient un pointeur incorporé vers une mémoire tampon en mode utilisateur. Dans ce cas, le pilote peut utiliserWdfRequestProbeAndLockUserBufferForRead pour obtenir un objet mémoire pour la mémoire tampon.

La longueur de la mémoire tampon spécifiée par le paramètre Length ne doit pas être supérieure à la taille réelle de la mémoire tampon. Sinon, les pilotes peuvent accéder à la mémoire en dehors de la mémoire tampon, ce qui constitue un risque de sécurité.

Si WdfRequestProbeAndLockUserBufferForRead retourne STATUS_SUCCESS, le pilote reçoit un handle vers un objet mémoire du framework qui représente la mémoire tampon en mode utilisateur. Pour accéder à la mémoire tampon, le pilote doit appeler WdfMemoryGetBuffer.

L’objet mémoire du framework est automatiquement libéré lorsque le pilote appelle WdfRequestComplete.

Pour plus d’informations sur WdfRequestProbeAndLockUserBufferForRead, consultez Accès aux mémoires tampons de données dans Framework-Based Drivers.

Exemples

L’exemple de code suivant est une version abrégée de la fonction de rappel EvtIoInCallerContext que contient l’exemple de pilote nonPNP NONPNP. Lorsque la fonction de rappel reçoit une requête d’E/S, elle détermine si la requête contient un code de contrôle d’E/S avec un type de transfert de METHOD_NEITHER. Si la requête contient un tel code de contrôle d’E/S, la fonction :

  1. Appelle WdfRequestRetrieveUnsafeUserInputBuffer et WdfRequestRetrieveUnsafeUserOutputBuffer pour obtenir les adresses virtuelles des mémoires tampons de lecture et d’écriture de la requête.
  2. Appelle WdfRequestProbeAndLockUserBufferForRead et WdfRequestProbeAndLockUserBufferForWrite pour sonder et verrouiller les mémoires tampons et obtenir un handle sur un objet mémoire de framework qui représente chaque mémoire tampon.
VOID
NonPnpEvtIoInCallerContext(
    IN WDFDEVICE  Device,
    IN WDFREQUEST Request
    )
{
    NTSTATUS  status = STATUS_SUCCESS;
    PREQUEST_CONTEXT  reqContext = NULL;
    WDF_OBJECT_ATTRIBUTES  attributes;
    WDF_REQUEST_PARAMETERS  params;
    size_t  inBufLen, outBufLen;
    PVOID  inBuf, outBuf;

    WDF_REQUEST_PARAMETERS_INIT(&params);
    WdfRequestGetParameters(
                            Request,
                            &params
                            );

    //
    // Check to see whether the driver received a METHOD_NEITHER I/O control code.
    // If not, just send the request back to the framework.
    //
    if(!(params.Type == WdfRequestTypeDeviceControl &&
            params.Parameters.DeviceIoControl.IoControlCode ==
                                    IOCTL_NONPNP_METHOD_NEITHER)) {
        status = WdfDeviceEnqueueRequest(
                                         Device,
                                         Request
                                         );
        if( !NT_SUCCESS(status) ) {
            goto End;
        }
        return;
    }

    //
    // The I/O control code is METHOD_NEITHER.
    // First, retrieve the virtual addresses of 
    // the input and output buffers.
    //
    status = WdfRequestRetrieveUnsafeUserInputBuffer(
                                                     Request,
                                                     0,
                                                     &inBuf,
                                                     &inBufLen
                                                     );
    if(!NT_SUCCESS(status)) {
        goto End;
    }
    status = WdfRequestRetrieveUnsafeUserOutputBuffer(
                                                      Request,
                                                      0,
                                                      &outBuf,
                                                      &outBufLen
                                                      );
    if(!NT_SUCCESS(status)) {
       goto End;
    }

    //
    // Next, allocate context space for the request, so that the
    // driver can store handles to the memory objects that will
    // be created for input and output buffers.
    //
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes,
                                        REQUEST_CONTEXT);
    status = WdfObjectAllocateContext(
                                      Request,
                                      &attributes,
                                      &reqContext
                                      );
    if(!NT_SUCCESS(status)) {
        goto End;
    }

    //
    // Next, probe and lock the read and write buffers.
    //
    status = WdfRequestProbeAndLockUserBufferForRead(
                                                     Request,
                                                     inBuf,
                                                     inBufLen,
                                                     &reqContext->InputMemoryBuffer
                                                     );
    if(!NT_SUCCESS(status)) {
        goto End;
    }

    status = WdfRequestProbeAndLockUserBufferForWrite(
                                                      Request,
                                                      outBuf,
                                                      outBufLen,
                                                      &reqContext->OutputMemoryBuffer
                                                      );
    if(!NT_SUCCESS(status)) {
        goto End;
    }

    //
    // Finally, return the request to the framework.
    //
    status = WdfDeviceEnqueueRequest(
                                     Device,
                                     Request
                                     );
    if(!NT_SUCCESS(status)) {
        goto End;
    }
    return;

End:
    WdfRequestComplete(
                       Request,
                       status
                       );
    return;
}

Exigences

Exigence Valeur
plateforme cible Universel
version minimale de KMDF 1.0
d’en-tête wdfrequest.h (include Wdf.h)
bibliothèque Wdf01000.sys (voir Versioning de la bibliothèque Framework.)
IRQL PASSIVE_LEVEL
règles de conformité DDI DriverCreate(kmdf), InvalidReqAccess(kmdf), InvalidReqAccessLocal(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf)

Voir aussi

WdfMemoryGetBuffer

WdfRequestProbeAndLockUserBufferForWrite

WdfRequestRetrieveUnsafeUserInputBuffer