Upload
renee
View
45
Download
3
Embed Size (px)
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 Presentation
Citation preview
ISLab Flash TeamISLab Flash Team
Ch 7. Driver Dispatch RoutinesCh 7. Driver Dispatch Routines
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 를 제어할수 있음
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
ISLab Flash TeamISLab Flash Team
Driver Dispatch RoutinesDriver Dispatch Routines
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 스택 로케이션 필드 >
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 요청자에게 리턴
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 포인터로 다채운다 .
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
ISLab Flash TeamISLab Flash Team
Writing Driver Dispatch RoutinesWriting Driver Dispatch Routines
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 에 따른 문제
Ch 7. Driver Dispatch Routines 11
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
디스패치 루틴에서 수행하는 동작디스패치 루틴에서 수행하는 동작
• IoGetCurrentIrpStackLocation• IRP 에 대한 유효성 체크• 하부 드라이버로 전달• 에러발생시 _IopInvalidDeviceRequest 를 리턴하고
수행중지
Ch 7. Driver Dispatch Routines 12
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
디스패치 루틴에서 빠져나오기디스패치 루틴에서 빠져나오기 (1)(1)
• 에러 통보• 요청 완료• 디바이스 동작을 스케줄링
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;
}
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;
}
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;
}
ISLab Flash TeamISLab Flash Team
Processing Read and Write RequestsProcessing Read and Write Requests
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 관리자는 어떤 버퍼 관리도 처리하지 않는다 .
ISLab Flash TeamISLab Flash Team
Code ExampleCode Example
loop-back routine
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)
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)
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)
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)
Ch 7. Driver Dispatch Routines 23
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
Code Example : Code Example : 루프백 디바이스루프백 디바이스 (5)(5)
ISLab Flash TeamISLab Flash Team
Extending the Dispatch InterfaceExtending the Dispatch Interface
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 와 유사
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
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 매크로 인자 >
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
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)
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;
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)
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;
}
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
ISLab Flash TeamISLab Flash Team
Testing Driver Dispatch RoutinesTesting Driver Dispatch Routines
Ch 7. Driver Dispatch Routines 35
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
테스트 과정테스트 과정
• 디바이스의 핸들을 제대로 열고 닫을 수 있는지• 비록 데이터의 전송은 수행하지 않는다 하더라도 ,
Win32 I/O 함수의 호출이 성공적인지• 다수의 I/O 요청에 대해 정상동작을 하는지
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 콘솔 테스트 프로그램>
Ch 7. Driver Dispatch Routines 37
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
예제 테스트 프로그램 결과예제 테스트 프로그램 결과
ISLab Flash TeamISLab Flash Team
SummarySummary
Ch 7. Driver Dispatch Routines 39
ISLab Flash TeamISLab Flash Team
Made By ICEUNI
SummarySummary
• 드라이버 디스패치 루틴은 드라이버와 I/O 요청자 간의 인터페이스를 제공한다 .
• 드라이버는 읽기 , 쓰기 그리고 디바이스 I/O 컨트롤을 지원한다 .