메모리 버퍼 사용

드라이버는 일반적으로 메모리 버퍼를 사용하여 프레임워크 및 기타 드라이버와 데이터를 전달하거나 정보를 로컬로 저장합니다. 이 항목에서는 프레임워크 메모리 개체, lookaside 목록, MDL로컬 버퍼에 대해 설명합니다.

프레임워크 메모리 개체 사용

프레임워크는 메모리 개체 를 사용하여 드라이버가 수신하여 프레임워크에 전달하는 메모리 버퍼를 설명합니다. 각 프레임워크 메모리 개체는 하나의 버퍼를 나타냅니다.

메모리 개체를 만들기 위해 드라이버는 다음 개체 메서드 중 하나를 호출합니다.

받은 I/O 요청의 버퍼를 나타내는 메모리 개체를 가져오기 위해 드라이버는 WdfRequestRetrieveInputMemoryWdfRequestRetrieveOutputMemory를 호출합니다. I/O 요청의 버퍼를 검색하는 방법에 대한 자세한 내용은 Framework-Based 드라이버에서 데이터 버퍼 액세스를 참조하세요.

메모리 개체 버퍼의 주소와 크기를 가져오기 위해 드라이버는 WdfMemoryGetBuffer를 호출합니다.

메모리 개체의 버퍼 안팎으로 데이터를 이동하려면 드라이버가 WdfMemoryCopyFromBuffer 또는 WdfMemoryCopyToBuffer를 호출합니다. 이러한 개체 메서드는 원본 및 대상 크기를 확인하고 버퍼 오버런 오류를 방지합니다.

드라이버가 WdfMemoryCreatePreallocated를 호출하여 메모리 개체를 만드는 경우 이후에 WdfMemoryAssignBuffer를 호출하여 메모리 개체에 다른 버퍼를 할당할 수 있습니다.

드라이버는 I/O 대상에 I/O 요청을 보낼 때 일반적으로 프레임워크 I/O 대상 개체 메서드에 입력 또는 출력 버퍼를 전달합니다. 드라이버는 버퍼를 설명하는 WDF_MEMORY_DESCRIPTOR 구조를 전달하거나 메모리 개체 핸들을 전달하여 버퍼를 지정합니다. I/O 요청을 동기적으로 보내는 I/O 대상 개체 메서드에는 WDF_MEMORY_DESCRIPTOR 구조가 필요하며 I/O 요청을 비동기적으로 보내는 메서드에는 메모리 개체 핸들이 필요합니다.

메모리 버퍼가 유효한 시기에 대한 자세한 내용은 메모리 버퍼 수명 주기를 참조하세요.

Lookaside 목록 사용

드라이버에 거의 동일한 크기의 버퍼가 많이 필요한 경우 lookaside 목록에서 할당해야 합니다. 드라이버는 WdfLookasideListCreate를 호출하여 lookaside 목록을 만듭니다. 그 후 드라이버는 WdfMemoryCreateFromLookaside를 호출하여 lookaside 목록에서 버퍼를 가져올 수 있습니다.

드라이버가 WdfMemoryCreateFromLookaside를 호출할 때마다 프레임워크는 메모리 개체를 만들고, lookaside 목록에서 버퍼를 가져오고, 버퍼를 개체에 할당합니다. 드라이버가 이러한 메모리 개체 중 하나를 사용하여 완료되면 메모리 개체를 삭제하고 버퍼 공간을 lookaside 목록으로 반환하는 WdfObjectDelete를 호출합니다.

운영 체제는 lookaside 목록에 할당된 메모리 리소스를 관리합니다. 드라이버가 WdfMemoryCreateFromLookaside를 처음 호출하는 경우와 같이 사용할 수 없는 경우 드라이버가 lookaside 목록에서 버퍼를 요청하는 경우 시스템은 버퍼를 할당하고 목록에 할당합니다. 드라이버가 WdfObjectDelete 를 호출하고 버퍼 공간이 lookaside 목록으로 반환되면 드라이버는 다시 필요할 때까지 할당되지 않은 버퍼를 목록에 유지합니다. 시스템은 필요에 따라 목록의 크기를 늘입니다. 예를 들어 버퍼를 더 자주 요청하는 드라이버는 더 큰 lookaside 목록을 받습니다. 반면에 드라이버가 버퍼를 모두 사용하지 않는 경우 시스템에서 목록의 버퍼 수를 줄일 수 있습니다.

MDL 사용

일부 드라이버는 메모리 설명자 목록(MDL)을 사용하여 버퍼를 설명합니다. 예를 들어 DMA(직접 메모리 액세스) 디바이스용 드라이버는 해당 메서드를 호출하는 경우 MDL을 WdfDmaTransactionInitialize 메서드에 전달해야 합니다.

MDL을 사용하는 드라이버는 WdfRequestRetrieveInputWdmMdl 및 WdfRequestRetrieveOutputWdmdl을 호출하여 수신된 I/O 요청의 버퍼를 나타내는 MDL을 가져올 수 있습니다.

대부분의 프레임워크 기반 드라이버는 MDL을 사용하지 않습니다.

로컬 버퍼 할당

프레임워크에 전달하지 않을 로컬 내부 버퍼 공간이 필요한 드라이버는 버퍼를 나타내는 메모리 개체를 만들 필요가 없습니다. 드라이버는 ExAllocatePoolWithTag 를 호출하여 내부 버퍼를 할당할 수 있습니다. 드라이버가 버퍼 사용을 마치면 ExFreePoolWithTag를 호출해야 합니다.

그러나 드라이버는 로컬 버퍼에 메모리 개체를 사용할 수도 있습니다. ExAllocatePoolWithTag를 호출하는 대신 메모리 버퍼를 사용하는 이점은 프레임워크가 각 개체의 부모 개체가 삭제되면 메모리 개체와 해당 버퍼를 자동으로 삭제한다는 것입니다.

중요

이 항목에서 설명하는 ExAllocatePool DDI는 Windows 10 버전 2004에서 더 이상 사용되지 않으며 ExAllocatePool2ExAllocatePool3으로 대체되었습니다. 자세한 내용은 ExAllocatePool2 및 ExAllocatePool3에 사용되지 않는 ExAllocatePool 호출 업데이트를 참조하세요.

버퍼 정렬

드라이버는 WDF_ALIGN_SIZE_UP 또는 WDF_ALIGN_SIZE_DOWN 함수를 사용하여 지정된 맞춤 오프셋에 맞춰진 버퍼 크기를 계산할 수 있습니다. 이 계산은 각 버퍼가 주소 맞춤 경계에서 시작해야 하는 경우 드라이버가 여러 연속 버퍼를 할당해야 하는 경우에 유용합니다.