동기적으로 I/O 요청 보내기
다음 표에서는 드라이버가 I/O 요청을 I/O 대상에 동기적으로 보내기 위해 호출할 수 있는 I/O 대상 개체 메서드를 나열합니다. 이러한 메서드를 사용하는 방법에 대한 자세한 내용은 메서드의 참조 페이지를 참조하세요.
메서드 | 용도 |
---|---|
읽기 요청을 보냅니다. |
|
쓰기 요청을 보냅니다. |
|
디바이스 제어 요청을 보냅니다. |
|
내부 디바이스 제어 요청을 보냅니다. |
|
비표준 내부 디바이스 제어 요청을 보냅니다. |
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;