데이타 버퍼 어드레싱
n 커널 드라이버는 대부분의 경우 User-Mode 가상 어드레스를 사용하는 메모리에 직접 접근하지 않는다. MS 윈도우즈 NT는 사용자 모드 데이타 버퍼에 접근할 수 있는 3가지 방법을 제공한다.
u Buffered 메소드
ü I/O 매니저는 User-Mode 데이터 버퍼의 크기와 같은 시스템 버퍼를 만든다. 여러분의 드라이버는 이 시스템 버퍼를 통해 작업할 수 있으며, I/O매니저는 User-Mode 버퍼와 System 버퍼 사이의 데이타를 복사한다.
ü I/O 매니저가 IRP_MJ_READ 또는 IRP_MJ_WRITE 요청을 만들때 I/O매니저는 새로운 IRP에서 데이터 버퍼를 어떻게 설명하는지를 결정하기 위한 Direct와 Bufferd 플래그를 조사한다. DO_BUFFERED_IO가 설정되어 있으면 I/O매니저는 사용자 버퍼와 같은 크기의 NonPaged메모리를 할당한다.
ü 메소드 기술
NTSTATUS AddDevice(...)
{
PDEVICE_OBJECT fdo;
IoCreateDevice(..., fdo);
fdo->Flags |= DO_BUFFERED_IO
} |
ü IRP구조체 내의 관련 필드
Irp->AssociatedIrp.SystemBuffer
ü IO_STACK_LOCATION 구조체 내의 관련 필드
READ 요청: stack->Parameters.Read.Length
WRITE 요청: stact->Parameters.Write.Length
u Direct 메소드
ü I/O 매니저는 사용자 모드 버퍼를 포함하는 물리적 페이지를 잠그고 잠긴 페이지들을 설명하기 위한 MDL(Memory Descripter List)라고 불리는 보조 데이터 구조체를 생성한다. 여러분은 MDL을 이용하여 작업할 수 있다.
ü 디바이스 객체에 DO_DIRECT_IO 플래그가 설정되어 있다면 I/O매니저는 사용자 모드 데이터버퍼를 포함하는 Locked Page를 설명하는 MDL을 생성한다.
ü 메소드 기술
NTSTATUS AddDevice(...)
{
PDEVICE_OBJECT fdo;
IoCreateDevice(..., fdo);
fdo->Flags |= DO_DIRECT_IO
} |
ü IRP 구조체 내의 관련 필드
Irp->MdlAddress
ü 메모리를 엑세스하기 위해 MDL 구조체를 직접사용하지는 않으며, 대신 매크로와 서포트 함수를 이용한다.
매크로 또는 함수 |
IoAllocateMdl |
IoBuildPartialMdl |
IoFreeMdl |
MmBuildMdlForNonPagedPool |
MmGetMdlByteCount |
MmGetMdlByteOffset |
MmGetMdlVirtualAddress |
MmGetPhysicalAddress |
MmGetSystemAddressForMdl |
MmGetSystemAddressForMdlSafe |
MmInitializeMdl |
MmPrepareMdlForReuse |
MmProbeAndLockPages |
MmSizeOfMdl |
MmUnlockPages |
u Neither 메소드
ü I/O매니저는 단순히 사용자 모드 가상 어드레스를 여러분에게 보낸다. 여러분은 사용자 모드 어드레스와 함께 – 매우 조심스럽게 – 작업할 수 있다.
ü 디바이스 객체에 DO_DIRECT_IO 플래그가 설정되어 있다면 I/O매니저는 사용자 모드 데이터버퍼를 포함하는 Locked Page를 설명하는 MDL을 생성한다.
ü 메소드 기술
NTSTATUS AddDevice(...)
{
PDEVICE_OBJECT fdo;
IoCreateDevice(..., fdo);
fdo->Flags |= 0
} |
ü IRP 구조체 내의 관련 필드
Irp->UserBuffer
ü IO_STACK_LOCATION 구조체 내의 관련 필드
stack->Parameters.Read.Length
stack->Parameters.Write.Length