|   
 UID1 威望1240 点 金钱24019 金币 点卡317 点 
 | 
1#
 发表于 2004-11-17 18:05 
 | 只看该作者 
所需阅读权限 1 [转帖]驱动程序和应用程序之间通信(For Win2000 or later v)
| 作者 Fang 关键字 驱动 应用 通信
 原作者姓名 Fang
 文章原始出处 根据网上一些资料整理。
 正文
 Q:
 请问有什么方法实现驱动程序主动和应用程序进行实时通讯,而不用应用程序采用定时查询的方法?
 比如驱动有一事件发生需要立即通知应用程序,或驱动程序需要向应用程序读取一些内容.
 A:
 有一个很容易的方式,在驱动程序和应用程序之间用一个事件。
 在应用程序CreateFile的时候,驱动程序IoCreateSynchronizationEvent一个有名的事件,然后应用程序CreateEvent/OpenEvent此有名事件即可。
 注意点:
 1,不要在驱动初始化的时候创建事件,此时大多不能成功创建;
 2,让驱动先创建,那么此后应用程序打开时,只能读(Waitxxxx),不能写(SetEvent/ResetEvent)。反之,如果应用程序先创建,则应用程序和驱动程序都有读写权限;
 3,用名字比较理想,注意驱动中名字在\BaseNamedObjects\下,例如应用程序用“xxxEvent”,那么驱动中就是“\BaseNamedObjects\xxxEvent”;
 4,用HANDLE的方式也可以,但是在WIN98下是否可行,未知。
 5,此后,驱动对读请求应立即返回,否则就返回失败。不然将失去用事件通知的意义(不再等待读完成,而是有需要(通知事件)时才会读);
 6,应用程序发现有事件,应该在一个循环中读取,直到读取失败,表明没有数据可读;否则会漏掉后续数据,而没有及时读取;
 Sample Code:
 [fquote]// 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;
 }
 }[/fquote]
 | 
 
| 我是一个呼吸着现在的空气而生活在过去的人
 这样的注定孤独,孤独的身处闹市却犹如置身于荒漠
 我已习惯了孤独,爱上孤独
 他让我看清了自我,还原了自我
 让我再静静的沉思中得到快乐和满足
 再孤独的世界里我一遍又一遍
 不厌其烦的改写着自己的过去
 延伸到现在与未来
 然而那只是泡沫般的美梦
 产生的时刻又伴随着破灭的到来
 在灰飞烟灭的瞬间我看到的是过程的美丽
 而不是结果的悲哀。。。
 
 |  |