다음을 통해 공유


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

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

메서드 용도

WdfIoTargetSendReadSynchronously

읽기 요청을 보냅니다.

WdfIoTargetSendWriteSynchronously

쓰기 요청을 보냅니다.

WdfIoTargetSendIoctlSynchronously

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

WdfIoTargetSendInternalIoctlSynchronously

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

WdfIoTargetSendInternalIoctlOthersSynchronously

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

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;