메모장 입니다2

Windows] DeviceIoControl을 이용한 통신 본문

Study/Programming

Windows] DeviceIoControl을 이용한 통신

Wooum@n 2017. 9. 1. 22:36

1.특징


 -양방향 전달이 가능하다. (커널 <-> 유저)

     <->단방향 통신

>ReadFile

>WriteFile




2.컨트롤 코드


 -버퍼 전달 형식 등을 설정할 수 있음.

 -CTL_CODE() 메크로를 이용하여 간단히 설정 가능.


#define IOCTL_TEST_N CTL_CODE(FILE_DEVICE_UNKNOWN,0x4000,METHOD_NEITHER,FILE_ANY_ACCESS)

#define IOCTL_TEST_B CTL_CODE(FILE_DEVICE_UNKNOWN,0x4000,METHOD_BUFFERED,FILE_ANY_ACCESS)




3.순서

 0)커널] 디바이스 오브젝트 생성.

 1)커널] 심볼릭 링크 설정.

 2)유저] CreateFile(심볼릭 링크)로 드라이버 핸들 open.

 3)유저] DeviceIoControl로 in, out 인자, ioctrl 전달 후 호출

 4)커널] 컨트롤 코드를 이용하여 요청을 구분, 구분한 뒤 코드에 맞는 다른 응답을 처리.

 5)유저] DeviceIoControl 리턴.




4. 코드

 

//유저

 #include <stdio.h>

#include <Windows.h>

#include <conio.h>


#define IOCTL_TEST_N CTL_CODE(FILE_DEVICE_UNKNOWN,0x4000,METHOD_NEITHER,FILE_ANY_ACCESS)

#define IOCTL_TEST_B CTL_CODE(FILE_DEVICE_UNKNOWN,0x4000,METHOD_BUFFERED,FILE_ANY_ACCESS)


int main(void)

{

HANDLE dHandle;

WCHAR deviceLink[] = L"\\\\.\\woounnan";

DWORD retLen;

char sendMsg[] = "hi!!!!\n";

char buf[100] = { 0 };

dHandle = CreateFileW(

deviceLink,

GENERIC_READ | GENERIC_WRITE,

0,

NULL,

OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL,

NULL

);


if (dHandle == INVALID_HANDLE_VALUE)

{

printf("Get Device Handle Fail! : 0x%X \n", GetLastError());

_getch();

return 1;

}


if (!DeviceIoControl(dHandle, IOCTL_TEST_N, (LPVOID) buf, sizeof(buf), sendMsg, sizeof(sendMsg), &retLen, 0))

{

printf("DeviceIOControl Fail!! \n");

_getch();

CloseHandle(dHandle);

return 1;

}

printf("recv msg:%s\n", buf);

printf("size:%d\n", retLen);



CloseHandle(dHandle);


return 0;

}




//커널

#include <ntddk.h>
#include <string.h>
#define LINK_NAME L"\\DosDevices\\woounnan"
#define DEVICE_NAME L"\\Device\\woounnan"
#define IOCTL_TEST_N CTL_CODE(FILE_DEVICE_UNKNOWN,0x4000,METHOD_NEITHER,FILE_ANY_ACCESS)
#define IOCTL_TEST_B CTL_CODE(FILE_DEVICE_UNKNOWN,0x4000,METHOD_BUFFERED,FILE_ANY_ACCESS)

PDEVICE_OBJECT MyDevice;
UNICODE_STRING DeviceLink;
UNICODE_STRING DeviceName;

NTSTATUS MyIOControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
PIO_STACK_LOCATION pStack;
NTSTATUS returnStatus = STATUS_SUCCESS;
ULONG ControlCode;
PCHAR outBuf;
//PCHAR data = "ah ssibal";
pStack = IoGetCurrentIrpStackLocation(Irp);
ControlCode = pStack->Parameters.DeviceIoControl.IoControlCode;


switch (ControlCode)
{
case IOCTL_TEST_N:
DbgPrintEx(DPFLTR_ACPI_ID, 0, "\n IOCTL_TEST Call~~ \n");
DbgPrintEx(DPFLTR_ACPI_ID, 0, "recv:%d %d\n", pStack->Parameters.DeviceIoControl.InputBufferLength, pStack->Parameters.DeviceIoControl.OutputBufferLength);
DbgPrintEx(DPFLTR_ACPI_ID, 0, "recv:%s \n", Irp->UserBuffer);
outBuf = pStack->Parameters.DeviceIoControl.Type3InputBuffer;
//(PCHAR)Irp->AssociatedIrp.SystemBuffer;
//memcpy(outBuf, "test", 4);
memcpy(outBuf, "test", 4);
DbgPrintEx(DPFLTR_ACPI_ID, 0, "outbuf:%s\nsystembuf:%s\n", outBuf, pStack->Parameters.DeviceIoControl.Type3InputBuffer);
Irp->IoStatus.Information = 19;
break;
}
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);

return returnStatus;
}

NTSTATUS myCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);

return STATUS_SUCCESS;
}

VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
UNREFERENCED_PARAMETER(DriverObject);
IoDeleteDevice(MyDevice);
IoDeleteSymbolicLink(&DeviceLink);

DbgPrintEx(DPFLTR_ACPI_ID, 0, "Unloding driver \n");
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
NTSTATUS returnStatus = STATUS_SUCCESS;

UNREFERENCED_PARAMETER(RegistryPath);
RtlInitUnicodeString(&DeviceLink, LINK_NAME);
RtlInitUnicodeString(&DeviceName, DEVICE_NAME);

DbgPrintEx(DPFLTR_ACPI_ID, 0, "Loading driver\n");
returnStatus = IoCreateDevice(
DriverObject,
0,
&DeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&MyDevice
);
// DEVICE_OBJECT의 초기화가 끝났다
MyDevice->Flags &= ~DO_DEVICE_INITIALIZING;

MyDevice->Flags |= DO_BUFFERED_IO;
if (!NT_SUCCESS(returnStatus))
{
//DbgPrint("IoCreateDevice Fail! \n");
return returnStatus;
}
//DbgPrint("Success IoCreateDevice \n");

returnStatus = IoCreateSymbolicLink(&DeviceLink, &DeviceName);
if (!NT_SUCCESS(returnStatus))
{
//DbgPrint("IoCreateSymbolicLink Fail! \n");
return returnStatus;
}
//DbgPrint("Success IoCreateSymbolicLink \n");

DriverObject->DriverUnload = OnUnload;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyIOControl;
DriverObject->MajorFunction[IRP_MJ_CREATE] = myCreate;

return returnStatus;
}


'Study > Programming' 카테고리의 다른 글

Codility] FrogJmp  (0) 2017.09.07
Windows] KeDelayExecutionThread  (0) 2017.09.05
Windows] 커널 데이터 IO 방식  (0) 2017.09.01
Windows] DKOM - 1) 개요, 특징  (0) 2017.08.29
Windows] IRP 콜백 함수  (0) 2017.08.24