ch 7. driver dispatch routines
DESCRIPTION
Ch 7. Driver Dispatch Routines. Goals. 드라이버와 드라이버 디스패치 루틴 점진적인 개발 방법론. Kernel Mode Object Type 결정 Driver 에 필요한 Context 결정 및 Store Place 결정 DriverEntry, Unload Routine 을 작성 (6 장 ) IRP_MJ_CREATE, IRP_MJ_CLOSE dispatch Routine(7 장 ) CreateFile , CloseHandle - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/1.jpg)
ISLab Flash TeamISLab Flash Team
Ch 7. Driver Dispatch RoutinesCh 7. Driver Dispatch Routines
![Page 2: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/2.jpg)
Ch 7. Driver Dispatch Routines 2
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
GoalsGoals
• 드라이버와 드라이버 디스패치 루틴• 점진적인 개발 방법론
Kernel Mode Object Type 결정 Driver 에 필요한 Context 결정 및 Store Place 결정 DriverEntry, Unload Routine 을 작성 (6 장 ) IRP_MJ_CREATE, IRP_MJ_CLOSE dispatch Routine(7
장 )• CreateFile , CloseHandle
Hardware 검색및 자원을 할당하는 Code 추가 Unload 시 할당된 자원을 해제하는 Code 추가 IRP_MJ_XXX 함수를 처리하는 dispatch Routine 추가
• Win32 App 에서 ReadFile, WriteFile 등으로 Test 가능 실질적인 Routine 작성
• Start I/O Routine• Interrupt Service Routine• DPC Routine
DeviceIOControl Code 추가• Win32 App 가 직접 Hardware Register 를 제어할수 있음
![Page 3: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/3.jpg)
Ch 7. Driver Dispatch Routines 3
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
ContentsContents
• Driver Dispatch Routines• Writing Driver Dispatch Routines• Processing Read and Write Requests• Code Example : Loop-back Device• Extending the Dispatch interface• Testing Driver Dispatch Routine• Summary
![Page 4: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/4.jpg)
ISLab Flash TeamISLab Flash Team
Driver Dispatch RoutinesDriver Dispatch Routines
![Page 5: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/5.jpg)
Ch 7. Driver Dispatch Routines 5
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
디스패치 루틴에서의 디스패치 루틴에서의 I/O I/O 요청 메커니즘요청 메커니즘 (1)(1)
IRP
IoStatus
Stack
Header
IO_STATUS_BLOCK
Status
Information
IO_STACK_LOCATION
MajorFunction
MinorFunction
union { struct {…} Read; struct {…} Write; struct {…} DeviceControl} Parameters;
IO_STACK_LOCATION, *PIO_STACK_LOCATION
Filed Contents
UCHAR MajorFunction IRP_MJXXX 값이 할당되어 있다 .
UCHAR MinorFunctionFile System 이나 SCSI 드라이버에 의해서
사용되어진다 .
Union Paramenters MajorFunction Code 에 대한 Union 값들
struct Write
IRP_MJ_WRITE 에 대한 파라미터• ULONG Length• ULONG Key• LARGE_INTEGER ByteOffset
struct DeviceIOControl
IRP_MJ_DEVICE_CONTROL 대한 파라미터• ULONG OutputBufferLength• ULONG InputBufferLength• ULONG IoControlCode• PVOID Ttpe3InputBuffer
struct Others PVOID Argument1-Argument4
PDEVICE_OBJECT DeviceObject
I/O Request 의 타켓 다바이스 객체
PFILE_OBJECT FileOnject
요청을 수행한 File Object
struct Read
IRP_MJ_READ 에 대한 파라미터• ULONG Length• ULONG Key• LARGE_INTEGER ByteOffset
Driver Object
DeviceObject
DriverStatIo
DriverUnload
MajorFunction[]
……..
Start I/ORoutine
UnloadRoutine
DispatchRoutine
DispatchRoutine
DeviceObject
DeviceObject
<IRP 의 구조 >
<DriverObject 구조 ><IRP 외부로 보여지는 IRP 스택 로케이션 필드 >
![Page 6: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/6.jpg)
Ch 7. Driver Dispatch Routines 6
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
디스패치 루틴에서의 디스패치 루틴에서의 I/O I/O 요청 메커니즘요청 메커니즘 (2)(2)IRP
IRP_MJ_WRITE
드라이버 객체
:
DispatchCreate
_IopInvalidDeviceRequest
DispatchRead
DispatchWite
_IopInvalidDeviceRequest 쓰기디스패치
루틴
MajorFunction
MajorFunction[] [IRP_MJ_CREATE]
[IRP_MJ_READ]
[IRP_MJ_WRITE]
.
.
.
.
.
.
※ _IopInvalidDeviceRequest 는 올바르지 않은 I/O 요청일 경우에 불리는 함수로써 에러를 I/O 요청자에게 리턴
![Page 7: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/7.jpg)
Ch 7. Driver Dispatch Routines 7
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
특정 함수 코드의 활성화특정 함수 코드의 활성화
NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDO, IN PUNICODE_STRING pRegPath){
:pDO->MajorFunction[ IRP_MJ_CREATE ] = DispCreate;pDO->MajorFunction[ IRP_MJ_CLOSE ] = DispClose;pDO->MajorFunction[ IRP_MJ_CLEANUP ] = DispCleanup;pDO->MajorFunction[ IRP_MJ_READ ] = DispRead;pDO->MajorFunction[ IRP_MJ_WRITE ] = DispWrite;
:return STATUS_SUCCESS;
}
• IRP_MJ_XXX(NTDDK.h, WDM.h) • DriverEntry 가 호출되기 전에 _IopInvalidDeviceRequest 포인터로 다채운다 .
![Page 8: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/8.jpg)
Ch 7. Driver Dispatch Routines 8
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
어떤 함수 코드를 지원할 지 결정하기어떤 함수 코드를 지원할 지 결정하기IRP MajorFunction 코드
함수 코드 설명
IRP_MJ_CREATE 핸들을 요청한다 .• CreateFile
IRP_MJ_CLEANUP 핸들을 닫을 때 지연된 IRP 를 취소시킨다 .• CloseHandle
IRP_MJ_CLOSE 핸들을 닫는다 .• CloseHandle
IRP_MJ_READ 디바이스로부터 데이터를 얻는다 .• ReadFile
IRP_MJ_WRITE 디바이스로 데이터를 보낸다• WriteFile
IRP_MJ_DEVICE_CONTROL Control 동작을 수행한다 .• DeviceIOControl
IRP_MJ_INTERNAL_DEVICE_CONTROL 커널 모드 클라이언트에 대해서만 Control 동작을 수행한다 (Win32 호출에서는 수행할 수 없다 .
IRP_MJ_FLUSH_BUFFERS 버퍼에 쓰거나 버퍼를 비운다 .• FlushFileBuffers• FlushConsoleInputBuffer• PurgeComm
IRP_MJ_SHUTDOWN 시스템이 셧다운될 때• InitiateSystemShutdown
![Page 9: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/9.jpg)
ISLab Flash TeamISLab Flash Team
Writing Driver Dispatch RoutinesWriting Driver Dispatch Routines
![Page 10: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/10.jpg)
Ch 7. Driver Dispatch Routines 10
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
실행 컨텍스트실행 컨텍스트
NTSTATUS 디스패치 IRQL == PASSIVE_LEVEL
인자 설명
IN PDEVICE_OBJECT pDevObject 요청을 위한 타겟 디바이스의 포인터
IN PIRP pIrp 요청을 서술하는 IRP 의 포인터
리턴 값 • STATUS_SUCCESS – 요청 완료• STATUS_PENDING – 지연 요청• STATUS_XXX – 적당한 에러 코드
• 디스패치 루틴은 비슷한 형태를 가진다 .• PASSIVE_LEVEL IRQL
< 디스패치 루틴의 함수 원형 >
• Buffered I/O 와 Direct I/O 문제• IRP 와 IRP 이외의 구조체의 사용에 대한 문제• 공유 데이터 구조 IRP 에 따른 문제
![Page 11: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/11.jpg)
Ch 7. Driver Dispatch Routines 11
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
디스패치 루틴에서 수행하는 동작디스패치 루틴에서 수행하는 동작
• IoGetCurrentIrpStackLocation• IRP 에 대한 유효성 체크• 하부 드라이버로 전달• 에러발생시 _IopInvalidDeviceRequest 를 리턴하고
수행중지
![Page 12: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/12.jpg)
Ch 7. Driver Dispatch Routines 12
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
디스패치 루틴에서 빠져나오기디스패치 루틴에서 빠져나오기 (1)(1)
• 에러 통보• 요청 완료• 디바이스 동작을 스케줄링
![Page 13: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/13.jpg)
Ch 7. Driver Dispatch Routines 13
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
디스패치 루틴에서 빠져나오기디스패치 루틴에서 빠져나오기 (2)(2)
• 에러의 통보
NTSTATUS DispatchWrite(IN PDEVICE_OBJECT pDO, IN PIRP pIrp){
:// 만약 해당 요청이 이 디바이스에서 지원되지 않는 것이라면// 결과를 보고하고 요청을 거절한다 .pIrp->IoStatus.Status = STATUS_NOT_INCREMENT_SUPPORTED;// 전송된 데이터가 없음을 보고한다 .pIrp->IoStatus.Information = 0;// 우선순위의 증가 없이 IRP 를 완료시킨다 .IoCompleteRequest(pIrp, IO_NO_INCREMENT);return STATUS_NOT_SUPPORTED;
}
![Page 14: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/14.jpg)
Ch 7. Driver Dispatch Routines 14
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
디스패치 루틴에서 빠져나오기디스패치 루틴에서 빠져나오기 (3)(3)
• 요청의 완료
NTSTATUS DispatchClose(IN PDEVICE_OBJECT pDO, IN PIRP pIrp){
:pIrp->IoStatus.Status = STATUS_SUCCESS;// 전송된 데이터가 0 바이트라고 지정한다 .pIrp->IoStatus.Information = 0;// IRP 를 완료로 지정한다 . – 더 이상의 처리를 수행하지 않는다 .IoCompleteRequest(pIrp, IO_NO_INCREMENT);return STATUS_SUCCESS;
}
![Page 15: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/15.jpg)
Ch 7. Driver Dispatch Routines 15
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
디스패치 루틴에서 빠져나오기디스패치 루틴에서 빠져나오기 (4)(4)
• 디바이스 동작을 스케줄링
NTSTATUS DispatchWrite(IN PDEVICE_OBJECT pDO, IN PIRP pIrp){
:// IRP 를 진행중으로 설정한다 .IoMarkIrpPending(pIrp);// 드라이버의 Start I/O 루틴을 통해 이벤트 처리의 // IRP 를 큐잉 ( 스케줄링 ) 한다 .// 세 번째 매개변수는 해당 I/O 요청을 큐의 끝에 삽입되도록 한다 .// 네 번째 매개변수는 Cancel 루틴에 대한 지점이다 .IoStartPacket(pDO, pIrp, 0, NULL);return STATUS_PENDING;
}
![Page 16: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/16.jpg)
ISLab Flash TeamISLab Flash Team
Processing Read and Write RequestsProcessing Read and Write Requests
![Page 17: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/17.jpg)
Ch 7. Driver Dispatch Routines 17
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
사용자 버퍼로의 접근사용자 버퍼로의 접근
• 디바이스 객체의 Flags 필드 (DO_BUFFERED_IO, DO_DIRECT_IO)
• BUFFERED I/O - Non-paged 풀 (pool) 버퍼를 할당 - IRP 의 AssociatedIrp.SystemBuffer 필드에 위치
• DIRECT I/O - 사용자 버퍼에 해당하는 물리 메모리 페이지를 잠근다 (lock) - MDL(Memory Descriptor List) - IRP 의 MdlAddress 필드에 저장
• NEITHER Method - Flags 필드 세팅이 되지 않았을 경우 - I/O 관리자는 어떤 버퍼 관리도 처리하지 않는다 .
![Page 18: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/18.jpg)
ISLab Flash TeamISLab Flash Team
Code ExampleCode Example
loop-back routine
![Page 19: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/19.jpg)
Ch 7. Driver Dispatch Routines 19
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
Code Example : Code Example : 루프백 디바이스루프백 디바이스 (1)(1)
NTSTATUS DispatchWrite ( IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp ) {
NTSTATUS status = STATUS_SUCCESS;PVOID userBuffer;ULONG xferSize;// 스택 로케이션은 사용자 버퍼의 정보를 갖고 있다 .PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation( pIrp );
// 현재 버퍼의 포인터는 디바이스 객체 내에 포함된 DEVICE_EXTENSION 안에 저장된다 .PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
// 버퍼가 이미 할당되어 있다면 해제한다 .if (pDevExt->deviceBuffer != NULL) {
ExFreePool(pDevExt->deviceBuffer);pDevExt->deviceBuffer = NULL;pDevExt->deviceBufferSize = 0;
}
xferSize = pIrpStack->Parameters.Write.Length;
// 이 예제에서는 디바이스가 Buffered I/O 를 사용하고 있다고 가정userBuffer = pIrp->AssociatedIrp.SystemBuffer;
Write 요청에 대한 디스패치 루틴 (1)
![Page 20: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/20.jpg)
Ch 7. Driver Dispatch Routines 20
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
Code Example : Code Example : 루프백 디바이스루프백 디바이스 (2)(2)
pDevExt->deviceBuffer = ExAllocatePool( PagedPool, xferSize );
if (pDevExt->deviceBuffer == NULL) {// 버퍼 할당에 실패status = STATUS_INSUFFICIENT_RESOURCES;xferSize = 0;
} else {// 버퍼를 복사pDevExt->deviceBufferSize = xferSize;RtlCopyMemory( pDevExt->deviceBuffer, userBuffer, xferSize );
}
// 디바이스 동작을 수행하지 않고 IRP 를 완료한다 .pIrp->IoStatus.Status = status;pIrp->IoStatus.Information = xferSize; // bytes xferedIoCompleteRequest( pIrp, IO_NO_INCREMENT );return status;
}
Write 요청에 대한 디스패치 루틴 (2)
![Page 21: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/21.jpg)
Ch 7. Driver Dispatch Routines 21
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
Code Example : Code Example : 루프백 디바이스루프백 디바이스 (3)(3)
NTSTATUS DispatchRead (IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp){
NTSTATUS status = STATUS_SUCCESS;PVOID userBuffer;ULONG xferSize;
// 스택 로케이션은 사용자 버퍼의 정보를 가지고 있다 .PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation( pIrp );
// 현재 버퍼의 포인터는 디바이스 객체 내에 포함된 DEVICE_EXTENSION 안에 저장PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;xferSize = pIrpStack->Parameters.Read.Length;userBuffer = pIrp->AssociatedIrp.SystemBuffer;
// 사용자의 요청에 대해 더 이상 전송을 수행하지 않는다 .xferSize = (xferSize < pDevExt->deviceBufferSize) ?
xferSize : pDevExt->deviceBufferSize;
Read 요청에 대한 디스패치 루틴 (1)
![Page 22: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/22.jpg)
Ch 7. Driver Dispatch Routines 22
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
Code Example : Code Example : 루프백 디바이스루프백 디바이스 (4)(4)
// 현재 버퍼를 사용자 공간으로 복사한다 .RtlCopyMemory( userBuffer, pDevExt->deviceBuffer, xferSize );
// 현재 paged 풀 버퍼를 해제한다 .ExFreePool( pDevExt->deviceBuffer );pDevExt->deviceBuffer = NULL;pDevExt->deviceBufferSize = 0;
// 그리고 I/O 요청을 완료한다 .pIrp->IoStatus.Status = status;pIrp->IoStatus.Information = xferSize;IoCompleteRequest( pIrp, IO_NO_INCREMENT );return status;
}
Read 요청에 대한 디스패치 루틴 (1)
![Page 23: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/23.jpg)
Ch 7. Driver Dispatch Routines 23
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
Code Example : Code Example : 루프백 디바이스루프백 디바이스 (5)(5)
![Page 24: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/24.jpg)
ISLab Flash TeamISLab Flash Team
Extending the Dispatch InterfaceExtending the Dispatch Interface
![Page 25: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/25.jpg)
Ch 7. Driver Dispatch Routines 25
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
디스패치 인터페이스의 확장디스패치 인터페이스의 확장
• read/write 동작 이외에 다른 동작( 예 : 디스크 포맷 , 파티션 )
• IRP_MJ_DEVICE_CONTROL- IoControl(IOCTL 디바이스 컨트롤 값 )
• IRP_MJ_INTERNAL_DEVICE_CONTROL- 커널 모드에서의 확장- IRP_MJ_DEVICE_CONTROL 와 유사
![Page 26: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/26.jpg)
Ch 7. Driver Dispatch Routines 26
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
개별적인 개별적인 IOCTL IOCTL 값에 대한 정의값에 대한 정의 (1)(1)
31-16 15-14 13-2 1-0
디바이스 타입
요청된 접근
컨트롤 코드
전송 타입<IOCTL 코드 구조체의 레이아웃>
031
![Page 27: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/27.jpg)
Ch 7. Driver Dispatch Routines 27
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
개별적인 개별적인 IOCTL IOCTL 값에 대한 정의값에 대한 정의 (2)(2)
CTL_CODE 매크로
인자 설명DeviceType IoCreateDevice 에 제공되는 FILE_DEVICE_XXX 의 값
• 0x0000~0x7fff – Microsoft 에 의해 예약된 값• 0x8000~0xffff – 사용자 정의 값
ControlCode 드라이버에서 정의된 IOCTL 코드• 0x00~0x7ff – Microsoft 에 의해 예약된 값• 0x8000~0xfff – 사용자 정의 값
TransferType 해당 컨트롤 코드를 위한 버퍼 전송 매커니즘• METHOD_BUFFERED• METHOD_IN_DIRECT• METHOD_OUT_DIRECT• METHOD_NEITHER
RequiredAccess 요청자의 접근 요청• FILE_ANY_ACCESS• FILE_READ_DATA• FILE_WRITE_DATA• FILE_READ_DATA | FILE_WRITE_DATA
<CTL_CODE 매크로 인자 >
![Page 28: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/28.jpg)
Ch 7. Driver Dispatch Routines 28
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
IOCTL IOCTL 인자 전달 방법인자 전달 방법
• CTL_CODE 의 TransferType(2bit)
• METHOD_BUFFERED• METHOD_IN_DIRECT• METHOD_OUT_DIRECT• METHOD_NEITHER
![Page 29: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/29.jpg)
Ch 7. Driver Dispatch Routines 29
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
IOCTL IOCTL 헤더 파일 작성하기헤더 파일 작성하기
#define IOCTL_MISSLEDEVICE_AIM CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_ACCESS_ANY)
// IOCTL_MISSLEDEVICE_AIM 에서 사용된 구조체Typedef struct _AIM_IN_BUFFER {
ULONG Longitude;ULONG Latitude;
} AIM_IN_BUFFER, *PAIM_IN_BUFFER;
Typedef struct _AIM_OUT_BUFFER {ULONG ExtendedStatus;
} AIM_OUT_BUFFER, *PAIM_OUT_BUFFER;
#define IOCTL_MISSLEDEVICE_LAUNCH CTL_CODE( \FILE_DEVICE_UNKNOWN, \0x802, \METHOD_NEITHER, \FILE_ACCESS_ANY)
![Page 30: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/30.jpg)
Ch 7. Driver Dispatch Routines 30
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
IOCTL IOCTL 요청의 처리요청의 처리 (1)(1)
• I/O 관리자가 아닌 드라이버의 책임NTSTATUS DispatchIoControl(IN PDEVICE_OBJECT pDO, IN PIRP pIrp) {
NTSTATUS status = STATUS_SUCCESS;PDEVICE_EXTENSION pDE;PVOID userBuffer;ULONG inSize;ULONG outSize;ULONG controlCode; // IOCTL 요청 변수
// 스택 로케이션은 사용자 버퍼의 정보를 담고 있다 .PIO_STACK_LOCATION pIrpStack;pIrpStack = IoGetCurrentIrpStackLocation(pIrp);// IOCTL 요청을 뽑아낸다 .controlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
// 그리고 요청된 전송 크기도 알아낸다 .inSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;outSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
![Page 31: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/31.jpg)
Ch 7. Driver Dispatch Routines 31
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
//// 두 번째 Switch 문을 구현한다 .switch (controlCode) {case IOCTL_MISSLEDEVICEAIM :
// 각 case 에서 항상 매개변수의 유효함을 확인하다 .if(inSize < sizeof(AIM_IN_BUFFER) ||
outSize < sizeof(AIM_OUT_BUFFER)){
status = STATUS_INVALID_BUFFER_SIZE;break;
}// 유효한 IRP 이므로 디바이스를 구동한다 .IoMarkIrpPending(pIrp);IoStartPacket(pDO, pIrp, 0, NULL);return STATUS_PENDING;
case IOCTL_DEVICE_LAUNCH :if(inSize > 0 || outSize >0)
// 진짜 에러는 아니다 . 그러나 호출자에게 해당 호출의 //목적에 대해 다시 생각하도록 주의를 준다 .
{status = STATUS_INVALID_PARAMETER;break;
}// 디바이스를 구동하게 하는 동일한 코드를 넣는다 .// :return STATUS_PENDING;
default :// 드라이버에서 인식할 수 없는 요청을 받았다 .status = STATUS_INVALID_DEVICE_REQUEST;break;
}
IOCTL IOCTL 요청의 처리요청의 처리 (2)(2)
![Page 32: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/32.jpg)
Ch 7. Driver Dispatch Routines 32
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
IOCTL IOCTL 요청의 처리요청의 처리 (3)(3)
// 유효한 컨트롤 코드의 경우는 상위 계층으로 리턴된다 .// 이 부분에서의 실행은 에러가 발생했을 경우이다 .// IRP 요청을 실패 처리한다 . pIrp->IoStatus.Status = status;pIrp->IoStatus.Information = 0; // 아무런 데이터가 없음을 지정한다 .IoCompleteRequest(pIrp, IO_NO_INCREMENT);return status;
}
![Page 33: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/33.jpg)
Ch 7. Driver Dispatch Routines 33
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
IOCTL IOCTL 버퍼 관리버퍼 관리
• 독립적인 버퍼 전송 메커니즘• 입력과 출력의 2 개의 버퍼
METHOD_BUFFERED METHOD_IN_DIRECT METHOD_OUT_DIRECT
METHOD_NEITHER
![Page 34: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/34.jpg)
ISLab Flash TeamISLab Flash Team
Testing Driver Dispatch RoutinesTesting Driver Dispatch Routines
![Page 35: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/35.jpg)
Ch 7. Driver Dispatch Routines 35
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
테스트 과정테스트 과정
• 디바이스의 핸들을 제대로 열고 닫을 수 있는지• 비록 데이터의 전송은 수행하지 않는다 하더라도 ,
Win32 I/O 함수의 호출이 성공적인지• 다수의 I/O 요청에 대해 정상동작을 하는지
![Page 36: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/36.jpg)
Ch 7. Driver Dispatch Routines 36
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
예제 테스트 프로그램예제 테스트 프로그램
#include <windows.h>#include <stdio.h>
Void main() {HANDLE hDevice;BOOL status;hDevice = CreateFile(\\\\.\\LBK1 ...);:status = ReadFile(hDevice, ...);:status = WriteFile(hDevice, ...);:status = DeviceIoControl(hDevice, ...);:status = CloseHandle(hDevice, ...);
}
<Win32 콘솔 테스트 프로그램>
![Page 37: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/37.jpg)
Ch 7. Driver Dispatch Routines 37
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
예제 테스트 프로그램 결과예제 테스트 프로그램 결과
![Page 38: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/38.jpg)
ISLab Flash TeamISLab Flash Team
SummarySummary
![Page 39: Ch 7. Driver Dispatch Routines](https://reader036.vdocuments.site/reader036/viewer/2022070410/56814624550346895db3306a/html5/thumbnails/39.jpg)
Ch 7. Driver Dispatch Routines 39
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
SummarySummary
• 드라이버 디스패치 루틴은 드라이버와 I/O 요청자 간의 인터페이스를 제공한다 .
• 드라이버는 읽기 , 쓰기 그리고 디바이스 I/O 컨트롤을 지원한다 .