Condividi tramite


Invio di richieste di I/O in modo sincrono

Nella tabella seguente sono elencati i metodi degli oggetti di destinazione I/O che il driver può chiamare per inviare richieste di I/O in modo sincrono a una destinazione di I/O. Per informazioni dettagliate su come usare questi metodi, vedere le pagine di riferimento dei metodi.

Metodo Scopo

WdfIoTargetSendReadSynchronously

Invia una richiesta di lettura

WdfIoTargetSendWriteSynchronously

Invia una richiesta di scrittura

WdfIoTargetSendIoctlSynchronously

Invia una richiesta di controllo del dispositivo

WdfIoTargetSendInternalIoctlSynchronously

Invia una richiesta di controllo del dispositivo interna

WdfIoTargetSendInternalIoctlOthersSynchronously

Invia una richiesta di controllo del dispositivo interno non standard

È anche possibile inviare richieste in modo sincrono chiamando WdfRequestSend, ma è necessario formattare prima la richiesta seguendo le regole descritte in Invio di richieste di I/O in modo asincrono.

L'invio di richieste di I/O a una destinazione di I/O in modo sincrono è più semplice da programmare rispetto all'invio di richieste di I/O in modo asincrono. È tuttavia consigliabile usare le linee guida seguenti per decidere se l'I/O sincrono è appropriato per il driver:

  • È possibile usare l'I/O sincrona se il driver non invia molte richieste di I/O e se le prestazioni del sistema o del dispositivo non vengono ridotte perché il driver attende il completamento di ogni richiesta di I/O.

  • Se il driver deve gestire molte richieste di I/O in breve periodo di tempo, probabilmente non è possibile consentire al driver di attendere il completamento di ogni richiesta prima di inviare la richiesta successiva. In caso contrario, il driver potrebbe perdere dati o ridurre le prestazioni del dispositivo (e, eventualmente, l'intero sistema). In questi casi, l'I/O asincrona potrebbe essere la scelta migliore.

  • L'I/O sincrona è utile per la gestione delle operazioni che devono iniziare e terminare senza attività simultanee aggiuntive. Tali operazioni potrebbero includere la reimpostazione di una pipe USB o la lettura dei registri del dispositivo.

  • La maggior parte dei casi, il driver deve specificare un valore di timeout quando chiama un metodo oggetto che invia una richiesta di I/O in modo sincrono. Se il driver non specifica un valore di timeout e se un dispositivo o un driver di livello inferiore non risponde, il driver può bloccarsi. Di conseguenza, l'utente può sperimentare un'applicazione non rispondente. Inoltre, altri driver potrebbero non essere in grado di ottenere risorse di sistema, ad esempio elementi di lavoro, se il driver non li rilascia.

  • Se i driver precedenti e inferiori agli utenti nello stack richiedono operazioni per procedere in modo sincrono, il driver deve usare I/O sincrono. Di conseguenza, è necessario conoscere i requisiti di altri driver che potrebbero esistere nello stack di driver.

Nell'esempio seguente viene illustrato come inviare una richiesta I/O sincrona (I/O):

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;