应用与内核通信

驱动通信:

0环:

1.设备对象

驱动如果想和应用程序进行通讯,需要有设备对象,首先要先创建驱动对象;

NTSTATUS    //原型
IoCreateDevice(
    _In_  PDRIVER_OBJECT DriverObject,
    _In_  ULONG DeviceExtensionSize,
    _In_opt_ PUNICODE_STRING DeviceName,
    _In_  DEVICE_TYPE DeviceType,
    _In_  ULONG DeviceCharacteristics,
    _In_  BOOLEAN Exclusive,
    
    PDEVICE_OBJECT *DeviceObject
    );
    
//使用例子:
IoCreateDevice(pDriver, 
               0, 
               &DeviceName, 
               FILE_DEVICE_UNKNOWN, 
               FILE_DEVICE_SECURE_OPEN, 
               TRUE, 
               &pDevice);

2.符号链接

应用层是无法直接通过设备名字访问设备的,需要通过建立符号链接进行访问

NTSTATUS    //原型
IoCreateSymbolicLink(
    _In_ PUNICODE_STRING SymbolicLinkName,
    _In_ PUNICODE_STRING DeviceName
    );
//使用例子:
IoCreateSymbolicLink(&SymNameLink,&DeviceName);

注意:符号链接得原理就是记录一个字符串对应到另一个字符串的一种简单结构,所以符号链接的方式并不安全,存在和其他驱动的符号链接发生冲突的情况下
方式1:先进行尝试删除这个符号链接,如果存在就被删除了,如果不存在也无所谓,再创建
方式2:使用GUID的方式来访问设备

3.分发函数

处理三环发送给设备对象的请求的函数,比如:OPEN,CLOSE,DEVICE CONTROL等

#define IRP_MJ_CREATE                   0x00
#define IRP_MJ_CREATE_NAMED_PIPE        0x01
#define IRP_MJ_CLOSE                    0x02
#define IRP_MJ_READ                     0x03
#define IRP_MJ_WRITE                    0x04
#define IRP_MJ_QUERY_INFORMATION        0x05
#define IRP_MJ_SET_INFORMATION          0x06
#define IRP_MJ_QUERY_EA                 0x07
...

不同的分发函数对应处理不同的请求

NTSTATUS    //分发函数原型
DRIVER_DISPATCH (
    _In_ struct _DEVICE_OBJECT *DeviceObject,
    _Inout_ struct _IRP *Irp
    );

需要把分发函数添加给对应的设备对象,可以把所有的Irp接收都用同一个分发函数,在函数内部进行区分,也可以对应不同的分发函数;

//方式1
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{
	pDriver->MajorFunction[i] = DisPatch;
}
//方式2
pDriver->MajorFunction[IRP_MJ_CREATE] = CreateCallBack;		
pDriver->MajorFunction[IRP_MJ_CLOSE ] = CloseCallBack;	

4.请求的处理

通过以下函数的函数框架,获取控制码,不同的控制码实现不同的具体的功能请求;

NTSTATUS
CreateCallBack(
	_In_ struct _DEVICE_OBJECT* DeviceObject,
	_Inout_ struct _IRP* Irp
)
{
        ULONG Code = psl->Parameters.DeviceIoControl.IoControlCode;

...
	Irp->IoStatus.Information = Ret_len;         //返回的输出长度是多少
	Irp->IoStatus.Status = status;                //请求的返回状态
	IoCompleteRequest(Irp, IO_NO_INCREMENT);      //结束请求
	return STATUS_SUCCESS;
}

5.删除

结束之前,需要删除控制设备和符号。这两项操作最好是在Driver->DriverUnload中进行

IoDeleteDevice(pDriver->DeviceObject);    //删除控制设备
IoDeleteSymbolicLink(&SymNameLink);       //删除符号链接

3环

1.打开设备

在0环代码实现中,已经介绍过,在三环是无法通过设备名访问设备的,需要通过符号链接名,注意,如果失败了返回值INVALID_HANDLE_VALUE

ret = CreateFile(
           SYMBOL_NAME_LINK, //符号链接名
           GENERIC_READ | GENERIC_WRITE, 
           0, 
           0, 
           OPEN_EXISTING,
           FILE_ATTRIBUTE_SYSTEM,
           NULL
);
if(ret == INVALID_HANDLE_VALUE)
{
    return FALSE;
}

2.设备控制请求

设备的请求,在系统中只规定了0x1b个,显然这并不能满足请求的种类,这就需要我们自己去定义不同的请求,通过宏CTL_CODE

CTL_CODE(FILE_DEVICE_UNKNOWN,0x900,METHOD_BUFFERED,FILE_ANY_ACCESS)

//注意0-7FF是系统保留的,所以我们只能定义0x7FF以上,且不超出0xFFF的CODE
通过DeviceIoControl把消息进行传输

BOOL
WINAPI
DeviceIoControl(
    __in        HANDLE hDevice,
    __in        DWORD dwIoControlCode,
    __in_bcount_opt(nInBufferSize) LPVOID lpInBuffer,
    __in        DWORD nInBufferSize,
    __out_bcount_part_opt(nOutBufferSize, *lpBytesReturned) LPVOID lpOutBuffer,
    __in        DWORD nOutBufferSize,
    __out_opt   LPDWORD lpBytesReturned,
    __inout_opt LPOVERLAPPED lpOverlapped
    );
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值