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)
- CTL_CODE() 매크로를 사용하여 버퍼 전달 형식 등을 설정 가능.
- L"\\\\.\\A"와 같은 형식으로 드라이버에서 접근하는 심볼릭 링크 설정
- CreateFileW()로 드라이버에 접근
- DeviceIoControl로 드라이버에게 전달할 인자와 리턴 받을 인자 설정 // 현 소스에서는 IOCTL_TEST_N이라는 컨트롤 코드를 사용, buf를 전달, sendMsg를 리턴
(3) 디바이스 드라이버 (Kernel Mode)
- 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
'IT' 카테고리의 다른 글
LG 울트라 PC GT(15U780-PA70K)에 우분투 설치하기 (15) | 2021.01.03 |
---|---|
Hyper-V와 WinDbg를 이용연결해서 Windows kernel 디버깅하기 (0) | 2020.12.31 |
CreateFile(), ReadFile(), WriteFile() (0) | 2020.10.02 |
프로세스(Process), 스레드(Thread), 모듈(Module) 정의 및 열거 방법 (0) | 2020.07.19 |
가상 주소 공간 (VAS, Virtual Address Space) (0) | 2020.06.08 |