Driver에서는 이와 유사한 개념으로 특정 IRP(I/O Request Packet)를 처리하는데 관여할 수 있는 여러 driver들이 마치 chain과 같은 형태를 구성하고 있는데 이를 'Driver Stack'이라고 한다. IRP를 처리할 때 필요한 처리 루틴이나 파라미터 등의 정보를 각각의 driver 들은 I/O stack location이라는 구조체에 저장하여 해당 IRP에 append 시켜야 하며, 상위 레벨의 driver는 하위 레벨의 driver에게 IoCallDriver 를 호출해서 IRP를 전달하기 전에 해당 stack location의 정보를 반드시 채워야 한다.
I/O manager는 이러한 Driver Stack을 구현하기 위해서 각 IRP마다 I/O stack location 정보를 저장할 수 있도록 배열을 만든다. 각 driver들은 특정 IRP를 처리하기 전에 IoGetCurrentIrpStackLocation 함수를 호출함으로써 해당 driver가 I/O operation을 수앵하는데 필요한 고유의 I/O stack location 정보를 얻을 수 있다.
다음 그림은 IRP 내에 저장되는 데이터를 도식화한 것이다.
아래 부분에 흰색 블록으로 표현된 것이 하나의 I/O stack location이며, 만약 2개의 driver가 관여하고 있다면 I/O stack location이 하나 더 append 된 형태가 될 것이다.
하나의 I/O Stack Location 정보는 IO_STACK_LOCATION 구조체를 이용해서 정의할 수 있는데, WDK에서 확인할 수 있는 IO_STACK_LOCATION 구조체의 정의는 다음과 같다.
typedef struct _IO_STACK_LOCATION {
UCHAR MajorFunction; // 수행되어야 할 I/O operation 타입
UCHAR MinorFunction; // MajorFunction에 대한 Sub funtion code
UCHAR Flags; // 요청에 대한 플래그 (파일 시스템 드라이버에서 주로 사용됨)
UCHAR Control; //
union {
//
// Parameters for IRP_MJ_CREATE
//
struct {
PIO_SECURITY_CONTEXT SecurityContext;
ULONG Options;
USHORT POINTER_ALIGNMENT FileAttributes;
USHORT ShareAccess;
ULONG POINTER_ALIGNMENT EaLength;
} Create;
//
// Parameters for IRP_MJ_READ
//
struct {
ULONG Length;
ULONG POINTER_ALIGNMENT Key;
LARGE_INTEGER ByteOffset;
} Read;
/* 이하 생략 */
/* full list는 http://msdn.microsoft.com/en-us/library/aa491675.aspx 참고 */
} Parameters; // MajorFunction과 MinorFunction 수행에 필요한 파라미터
PDEVICE_OBJECT DeviceObject; // IRP를 처리해야하는 target device (DEVICE_OBJECT 구조체 포인터)
PFILE_OBJECT FileObject; // DeviceObject와 관련된 file object (FILE_OBJECT 구조체 포인터 )
.
} IO_STACK_LOCATION, *PIO_STACK_LOCATION;
WinDbg에서 !irp 명령을 이용하면 다음과 같이 특정 IRP에 관련된 I/O Stack Location 정보를 확인할 수 있다.
0: kd> !irp 0x831f4a00
Irp is active with 8 stacks 5 is current (= 0x831f4b00)
Mdl = 82b020d8 Thread 8c622118: Irp stack trace.
cmd flg cl Device File Completion-Context
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
>[ 3,34] 40 e1 828517a8 00000000 842511e0-00000000 Success Error Cancel pending
\Driver\disk partmgr!PmReadWriteCompletion
Args: 00007000 00000000 fe084e00 00000004
[ 3, 0] 40 e0 82851450 00000000 842414d4-82956350 Success Error Cancel
\Driver\PartMgr volmgr!VmpReadWriteCompletionRoutine
Args: 129131bb 000000de fe084e00 00000004
[ 3, 0] 0 e0 82956298 00000000 847eeed0-829e2ba8 Success Error Cancel
\Driver\volmgr Ntfs!NtfsMasterIrpSyncCompletionRoutine
Args: 00007000 00000000 1bdae400 00000000
[ 3, 0] 0 0 82ac2020 8e879410 00000000-00000000
\FileSystem\Ntfs
Args: 00007000 00000000 00018400 00000000
References
WDK I/O Stack Locations
http://msdn.microsoft.com/en-us/library/ms795764.aspx
'Programming' 카테고리의 다른 글
데이터 실행 방지(DEP) (0) | 2009.05.11 |
---|---|
응답 없음(Not Responding) (0) | 2009.05.11 |
PEVIEWER로 살펴보는 notepad.exe (1) | 2009.04.30 |
Example I/O request - an overview (0) | 2009.04.21 |
On-demand 메모리 관리 (0) | 2009.04.02 |