Envío de solicitudes de E/S de forma sincrónica

En la tabla siguiente se enumeran los métodos de objeto de destino de E/S a los que el controlador puede llamar para enviar solicitudes de E/S de forma sincrónica a un destino de E/S. Para obtener información detallada sobre cómo usar estos métodos, consulte las páginas de referencia de los métodos.

Método Propósito

WdfIoTargetSendReadSynchronously

Envía una solicitud de lectura.

WdfIoTargetSendWriteSynchronously

Envía una solicitud de escritura.

WdfIoTargetSendIoctlSynchronously

Envía una solicitud de control de dispositivo

WdfIoTargetSendInternalIoctlSynchronously

Envía una solicitud de control de dispositivo interno.

WdfIoTargetSendInternalIoctlOthersSynchronously

Envía una solicitud de control de dispositivo interna no estándar.

También puede enviar solicitudes de forma sincrónica llamando a WdfRequestSend, pero primero debe dar formato a la solicitud siguiendo las reglas que se describen en Envío de solicitudes de E/S de forma asincrónica.

Enviar solicitudes de E/S a un destino de E/S de forma sincrónica es más sencillo programar que enviar solicitudes de E/S de forma asincrónica. Sin embargo, debe usar las siguientes directrices para ayudarle a decidir si la E/S sincrónica es adecuada para el controlador:

  • Puede usar E/S sincrónica si el controlador no envía muchas solicitudes de E/S y si el rendimiento del sistema o del dispositivo no se reduce porque el controlador espera a que se complete cada solicitud de E/S.

  • Si el controlador debe controlar muchas solicitudes de E/S en breves períodos de tiempo, es probable que no pueda permitir que el controlador espere a que se complete cada solicitud antes de enviar la siguiente solicitud. De lo contrario, el controlador podría perder datos o reducir el rendimiento de su dispositivo (y, posiblemente, todo el sistema). En tales casos, la E/S asincrónica podría ser la mejor opción.

  • La E/S sincrónica es útil para controlar las operaciones que deben iniciarse y finalizar sin actividad simultánea adicional. Estas operaciones pueden incluir restablecer una canalización USB o leer registros de dispositivos.

  • La mayoría de las veces, el controlador debe especificar un valor de tiempo de espera cuando llama a un método de objeto que envía una solicitud de E/S de forma sincrónica. Si el controlador no especifica un valor de tiempo de espera y si un dispositivo o un controlador de nivel inferior no responden, el controlador puede detenerse. Como resultado, el usuario puede experimentar una aplicación que no responde. Además, es posible que otros controladores no puedan obtener recursos del sistema, como elementos de trabajo, si el controlador no los libera.

  • Si los controladores anteriores y debajo de la pila requieren que las operaciones continúen sincrónicamente, el controlador debe usar E/S sincrónica. Por lo tanto, debe obtener información sobre los requisitos de otros controladores que pueden existir en la pila de controladores.

En el ejemplo siguiente se muestra cómo enviar una solicitud de control de E/S sincrónica (IOCTL):

NTSTATUS                status;
    WDF_MEMORY_DESCRIPTOR   inputDesc, outputDesc;
    PWDF_MEMORY_DESCRIPTOR  pInputDesc = NULL, pOutputDesc = NULL;
    ULONG_PTR               bytesReturned;

    UNREFERENCED_PARAMETER(FileObject);

    if (InputBuffer) {
        WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&inputDesc,
                                    InputBuffer,
                                    InputBufferLength);
        pInputDesc = &inputDesc;
    }

    if (OutputBuffer) {
        WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&outputDesc,
                                    OutputBuffer,
                                    OutputBufferLength);
        pOutputDesc = &outputDesc;
    }

    status = WdfIoTargetSendIoctlSynchronously(
                        IoTarget,
                        WDF_NO_HANDLE, // Request
                        IoctlControlCode,
                        pInputDesc,
                        pOutputDesc,
                        NULL, // PWDF_REQUEST_SEND_OPTIONS
                        &bytesReturned);
    if (!NT_SUCCESS(status)) {
         DEBUGP(MP_ERROR,
        ("WdfIoTargetSendIoctlSynchronously failed 0x%x\n",
          status));
    }

    *BytesReadOrWritten = (ULONG)bytesReturned;