본문 바로가기
IT

디바이스 드라이버와 응용 프로그램 간의 통신 방법(feat.DeviceIoControl)

by %? 2020. 11. 1.

1. DeviceIoControl() : 지정된 장치 드라이버로 제어 코드를 직접 전송하여 해당 장치가 해당 작업을 수행하도록 하는 함수

[함수 원형]

BOOL DeviceIoControl(

  HANDLE hDevice,

  DWORD dwIoControlCode,

  LPVOID lpInBuffer,

  DWORD nInBufferSize,

  LPVOID lpOutBuffer,

  DWORD nOutBufferSize,

  LPDWORD lpBytesReturned,

  LPOVERLAPPED lpOverlapped

);

 

[매개변수]

hDevice : 작업을 수행할 장치에 대한 핸들. 디바이스 핸들을 검색할 때는 CreateFile() 함수를 사용한다.

 

dwIoControlCode : 수행에 필요한 조종 코드. 이 값으로 수행할 특정한 작업과 장치의 유형을 알 수 있다.

 

lpInBuffer : 작업 수행에 필요한 데이터를 포함한 입력 버퍼의 포인터. 입력 데이터가 필요없으면 NULL로 표시 가능하다.

 

nInBufferSize : 입력 버퍼의 크기를 바이트 단위로 표시.

 

lpOutBuffer : 작업에서 반환된 데이터를 받기 위한 출력 버퍼에 대한 포인터.

 

nOutBufferSize : 출력 버퍼의 크기를 바이트 단위로 표시.

 

lpBytesReturned : 출력 버퍼에 저장된 데이터의 크기를 수신하는 변수에 대한 포인터.

 

lpOverlapped : OVERLAPPED 구조에 대한 포인터

 

2. 디바이스 드라이버와 응용 프로그램 간의 통신

※ 소스 코드 작성할 때 제가 잘 알지 못 한 상황에서 작성하여서 User Mode를 Device로, Kernel Mode를 Driver로 지정했습니다. 이 점 양해해주시고 봐주세요. ※

(1) 순서

- Kernel / 디바이스 오브젝트 생성

- Kernel / 심볼릭 링크 설정

- User / CreateFile로 드라이버 핸들 열기

- User / DeviceIoControl로 I/O 인자, ioctrl 전달 후 호출

- Kernel / CTL_CODE(컨트롤 코드)를 이용하여 요청을 구분 후 코드에 맞는 응답을 처리

- User / DeviceIoControl 리턴

(2) 응용 프로그램 (User Mode)

드라이버와는 같은 솔루션 위치. 파일은 c파일

- CTL_CODE() 매크로를 사용하여 버퍼 전달 형식 등을 설정 가능.

- L"\\\\.\\A"와 같은 형식으로 드라이버에서 접근하는 심볼릭 링크 설정

- CreateFileW()로 드라이버에 접근

- DeviceIoControl로 드라이버에게 전달할 인자와 리턴 받을 인자 설정 // 현 소스에서는 IOCTL_TEST_N이라는 컨트롤 코드를 사용, buf를 전달, sendMsg를 리턴

 

(3) 디바이스 드라이버 (Kernel Mode)

Driver(1) - 파일은 c파일
Driver(2)
Driver(3)

- DriverEntry 안의 IoCreateDevice로 디바이스 생성

- IoCreateSymbolicLink로 유저에서 접근 가능하도록 이름 지정 // 심볼릭 링크는 L"\\DosDevices\\A"와 같은 형식으로, 이름은 L"\\Device\\A"와 같은 형식 사용

- IRPDispatch 루틴들 등록

  ㄴ Unload 루틴 등록으로 생성했던 디바이스와 심볼릭 링크 제거

  ㄴ DeviceIoControl() 함수가 IRP를 보낼 때, 그 IRP를 처리할 MyIOControl 핸들러 등록

  ㄴ CreateFile() 함수 호출을 성공적으로 이루어지도록 IRP_MJ_CREATE 등록

 

참고한 사이트들

docs.microsoft.com/en-us/windows/win32/api/ioapiset/nf-ioapiset-deviceiocontrol

 

docs.microsoft.com/en-us/windows/win32/DevIO/calling-deviceiocontrol

 

docs.microsoft.com/en-us/windows-hardware/drivers/gettingstarted/writing-a-very-small-kmdf--driver

 

blog.naver.com/719121812/20177548119

 

ezbeat.tistory.com/286

 

woounnan.tistory.com/160

 

jeep-shoes.tistory.com/60