다음을 통해 공유


동기적으로 I/O 요청 보내기

다음 표에서는 드라이버가 I/O 요청을 I/O 대상에 동기적으로 보내기 위해 호출할 수 있는 I/O 대상 개체 메서드를 나열합니다. 이러한 메서드를 사용하는 방법에 대한 자세한 내용은 메서드의 참조 페이지를 참조하세요.

메서드 목적

WdfIoTargetSendReadSynchronously

읽기 요청을 보냅니다.

#B0 #A1 WdfIoTargetSendWriteSynchronously #A2 #C3

쓰기 요청을 보냅니다.

WdfIoTargetSendIoctlSynchronously

디바이스 제어 요청을 보냅니다.

#B0 #A1 WdfIoTargetSendInternalIoctlSynchronously #A2 #C3

내부 디바이스 제어 요청을 보냅니다.

#B0 #A1 WdfIoTargetSendInternalIoctlOthersSynchronously #A2 #C3

비표준 내부 디바이스 제어 요청을 보냅니다.

WdfRequestSend를 호출하여 요청을 동기적으로 보낼 수도 있지만, I/O 요청 보내기에 비동기적으로 설명된 규칙을 따라 먼저 요청의 형식을 지정해야 합니다.

I/O 요청을 I/O 대상에 동기적으로 보내는 것은 I/O 요청을 비동기적으로 보내는 것보다 프로그래밍하는 것이 더 간단합니다. 그러나 동기 I/O가 드라이버에 적합한지 여부를 결정하는 데 도움이 되도록 다음 지침을 사용해야 합니다.

  • 드라이버가 많은 I/O 요청을 보내지 않고 드라이버가 각 I/O 요청이 완료될 때까지 대기하므로 시스템 또는 디바이스 성능이 저하되지 않는 경우 동기 I/O를 사용할 수 있습니다.

  • 드라이버가 짧은 기간 동안 많은 I/O 요청을 처리해야 하는 경우 다음 요청을 보내기 전에 드라이버가 각 요청이 완료될 때까지 기다리는 것을 허용할 수 없습니다. 그렇지 않으면 드라이버가 데이터를 손실하거나 디바이스(및 전체 시스템)의 성능을 저하시킬 수 있습니다. 이러한 경우 비동기 I/O가 더 나은 선택일 수 있습니다.

  • 동기 I/O는 추가 동시 작업 없이 시작하고 완료해야 하는 작업을 처리하는 데 유용합니다. 이러한 작업에는 USB 파이프를 다시 설정하거나 디바이스 레지스터를 읽는 작업이 포함될 수 있습니다.

  • 대부분의 경우 드라이버는 I/O 요청을 동기적으로 보내는 개체 메서드를 호출할 때 시간 제한 값을 지정해야 합니다. 드라이버가 제한 시간 값을 지정하지 않고 디바이스 또는 하위 수준 드라이버가 응답하지 않는 경우 드라이버가 정지할 수 있습니다. 따라서 사용자는 응답하지 않는 애플리케이션을 경험할 수 있습니다. 또한 드라이버에서 해제하지 않는 경우 다른 드라이버가 작업 항목과 같은 시스템 리소스를 가져오지 못할 수 있습니다.

  • 스택의 위와 아래에 있는 드라이버가 동기적으로 작업을 진행해야 하는 경우 드라이버는 동기 I/O를 사용해야 합니다. 따라서 드라이버 스택에 있을 수 있는 다른 드라이버의 요구 사항에 대해 알아봅니다.

다음 예제에서는 IOCTL(동기 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;