驱动程序和应用程序之间通信

本文介绍了一种驱动程序与应用程序之间实现实时通讯的方法,避免了应用程序采用定时查询的低效方式。通过创建和使用共享事件,可以使得驱动程序在特定事件发生时立即通知应用程序。
正文
Q:
请问有什么方法实现驱动程序主动和应用程序进行实时通讯,而不用应用程序采用定时查询的方法?
比如驱动有一事件发生需要立即通知应用程序,或驱动程序需要向应用程序读取一些内容.

A:
有一个很容易的方式,在驱动程序和应用程序之间用一个事件。
在应用程序CreateFile的时候,驱动程序IoCreateSynchronizationEvent一个有名的事件,然后应用程序CreateEvent/OpenEvent此有名事件即可。
注意点:
1,不要在驱动初始化的时候创建事件,此时大多不能成功创建;
2,让驱动先创建,那么此后应用程序打开时,只能读(Waitxxxx),不能写(SetEvent/ResetEvent)。反之,如果应用程序先创建,则应用程序和驱动程序都有读写权限;
3,用名字比较理想,注意驱动中名字在/BaseNamedObjects/下,例如应用程序用“xxxEvent”,那么驱动中就是“/BaseNamedObjects/xxxEvent”;
4,用HANDLE的方式也可以,但是在WIN98下是否可行,未知。
5,此后,驱动对读请求应立即返回,否则就返回失败。不然将失去用事件通知的意义(不再等待读完成,而是有需要(通知事件)时才会读);
6,应用程序发现有事件,应该在一个循环中读取,直到读取失败,表明没有数据可读;否则会漏掉后续数据,而没有及时读取;

Sample Code:


// Describe the share memory.
typedef struct _PKT_BUFFER
{
PMDL BufferMdl;
PVOID UserBaseAddress;
PVOID KernelBaseAddress;
}PKT_BUFFER, *PPKT_BUFFER;

typedef struct _SHARE_EVENT_CONTEXT
{
WCHAR EventName[128]; // Event name, the only connection btw ring0/ring3
HANDLE Win32EventHandle; // Ring3 copy of the event handle
HANDLE DriverEventHandle; // Ring0 copy of the event handle
PVOID DriverEventObject; // The event object
}SHARE_EVENT_CONTEXT, *PSHARE_EVENT_CONTEXT;


BOOLEAN CreateShareMemory(PPKT_BUFFER PktBuffer, ULONG Size)
{
PktBuffer->KernelBaseAddress = ExAllocatePoolWithTag(NonPagedPool,
Size,
'MpaM');

if(!PktBuffer->KernelBaseAddress)
return FALSE;

//
// Allocate and initalize an MDL that describes the buffer
//
PktBuffer->BufferMdl = IoAllocateMdl(PktBuffer->KernelBaseAddress,
Size,
FALSE,
FALSE,
NULL);

if(!PktBuffer->BufferMdl)
{
ExFreePool(PktBuffer->KernelBaseAddress);
PktBuffer->KernelBaseAddress =NULL;
return FALSE;
}

MmBuildMdlForNonPagedPool(PktBuffer->BufferMdl);

DEBUGP(DL_INFO, ("CreateShareMemory: KernelBaseAddress = 0x%p/n", PktBuffer->KernelBaseAddress));

return TRUE;
}

VOID DestroyShareMemory(PPKT_BUFFER PktBuffer)
{
if(PktBuffer->BufferMdl)
{
IoFreeMdl(PktBuffer->BufferMdl);
PktBuffer->BufferMdl = NULL;
}

if(PktBuffer->KernelBaseAddress)
{
ExFreePool(PktBuffer->KernelBaseAddress);
PktBuffer->KernelBaseAddress = NULL;
}
}

//This function works in user dispatch code.
BOOLEAN MapSharedMemory(PPKT_BUFFER PktBuffer)
{
if(!PktBuffer->BufferMdl)
return FALSE;

//
// The preferred V5 way to map the buffer into user space
//
PktBuffer->UserBaseAddress =
MmMapLockedPagesSpecifyCache(PktBuffer->BufferMdl, // MDL
UserMode, // Mode
MmCached, // Caching
NULL, // Address
FALSE, // Bugcheck?
NormalPagePriority); // Priority

if(!PktBuffer->UserBaseAddress)
return FALSE;

DEBUGP(DL_INFO, ("MapSharedMemory SUCCESS, UserBaseAddress %p/n", PktBuffer->UserBaseAddress));
return TRUE;
}

VOID UnmapSharedMemory(PPKT_BUFFER PktBuffer)
{
if(PktBuffer->UserBaseAddress)
{
MmUnmapLockedPages(PktBuffer->UserBaseAddress, PktBuffer->BufferMdl);
PktBuffer->UserBaseAddress = NULL;
}
}

BOOLEAN CreateShareEvent(PSHARE_EVENT_CONTEXT ShareEvent)
{
UNICODE_STRING UnicodeName;
WCHAR UnicodeBuffer[128] = L"/BaseNamedObjects/";

RtlInitUnicodeString(&UnicodeName, UnicodeBuffer);
UnicodeName.MaximumLength = 128;
RtlAppendUnicodeToString(&UnicodeName, ShareEvent->EventName);

ShareEvent->DriverEventObject = IoCreateSynchronizationEvent(&UnicodeName,
&ShareEvent->DriverEventHandle);

if(ShareEvent->DriverEventObject == NULL)
{
ShareEvent->DriverEventHandle = NULL;
DEBUGP(DL_INFO, ("CreateSynchronizationEvent FAILED Name=%ws/n", UnicodeBuffer));
return FALSE;
}
else
{
KeClearEvent(ShareEvent->DriverEventObject);

DEBUGP(DL_INFO, ("CreateSynchronizationEvent SUCCESS Name=%ws DriverEventObject=%p, DriverEventHandle=%u/n",
UnicodeBuffer,
ShareEvent->DriverEventObject,
ShareEvent->DriverEventHandle));

return TRUE;
}
}

VOID DestroyShareEvents(PSHARE_EVENT_CONTEXT ShareEvent)
{
if(ShareEvent->DriverEventHandle)
{
ZwClose(ShareEvent->DriverEventHandle);
ShareEvent->DriverEventObject = NULL;
ShareEvent->DriverEventHandle = NULL;
}
一、项目简介本项目是一套基于SSM的客户资料管理系统/客户关系管理系统,主要针对计算机相关专业的正在做毕设的学生需要项目实战练习的Java学习者。包含:项目源码、数据库脚本、软件工具、项目说明等,该项目可以直接作为毕设使用。项目都经过严格调试,确保可以运行!二、技术实现​后台框架:Spring、SpringMVC、MyBatis​数据库:MySQL开发环境:JDK、Eclipse、Tomcat三、系统功能该客户资料管理系统/客户关系管理系统以实际运用为开发背景,采用Eclipse开发工具,Java开发语言,使用JSP设计页面,Tomcat服务器作为Web服务器,数据的存储使用MySQL数据库,从而保证系统的稳定性。系统设计按标准化、规范化,分层设计,构件化进行相关功能的实现。本系统主要分为三种角色,分别是:管理员、客户经理、营销主管,其功能如下:1)管理员管理员的主要功能包括:员工信息管理、产品信息管理、客户信息管理、服务信息管理、交易信息管理、客户来源管理、支付方式管理、产品类型管理、职位信息管理、服务类型管理、客户等级管理、客户开发进度管理。2)客户经理客户经理的主要功能包括:产品信息管理、客户信息管理、服务信息管理、交易信息管理、基础信息查询。3)营销主管营销主管的主要功能包括:员工信息管理、产品信息管理、客户信息管理、服务信息管理、交易信息管理、基础信息查询。该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值