久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4920|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

驅(qū)動程序和應(yīng)用程序之間通信

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:108531 發(fā)表于 2016-3-12 16:05 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
Q:
請問有什么方法實(shí)現(xiàn)驅(qū)動程序主動和應(yīng)用程序進(jìn)行實(shí)時(shí)通訊,而不用應(yīng)用程序采用定時(shí)查詢的方法?
比如驅(qū)動有一事件發(fā)生需要立即通知應(yīng)用程序,或驅(qū)動程序需要向應(yīng)用程序讀取一些內(nèi)容.
A:
有一個(gè)很容易的方式,在驅(qū)動程序和應(yīng)用程序之間用一個(gè)事件。
在應(yīng)用程序CreateFile的時(shí)候,驅(qū)動程序IoCreateSynchronizationEvent一個(gè)有名的事件,然后應(yīng)用程序CreateEvent/OpenEvent此有名事件即可。
注意點(diǎn):
1,不要在驅(qū)動初始化的時(shí)候創(chuàng)建事件,此時(shí)大多不能成功創(chuàng)建;
2,讓驅(qū)動先創(chuàng)建,那么此后應(yīng)用程序打開時(shí),只能讀(Waitxxxx),不能寫(SetEvent/ResetEvent)。反之,如果應(yīng)用程序先創(chuàng)建,則應(yīng)用程序和驅(qū)動程序都有讀寫權(quán)限;
3,用名字比較理想,注意驅(qū)動中名字在\BaseNamedObjects\下,例如應(yīng)用程序用“xxxEvent”,那么驅(qū)動中就是“\BaseNamedObjects\xxxEvent”;
4,用HANDLE的方式也可以,但是在WIN98下是否可行,未知。
5,此后,驅(qū)動對讀請求應(yīng)立即返回,否則就返回失敗。不然將失去用事件通知的意義(不再等待讀完成,而是有需要(通知事件)時(shí)才會讀);
6,應(yīng)用程序發(fā)現(xiàn)有事件,應(yīng)該在一個(gè)循環(huán)中讀取,直到讀取失敗,表明沒有數(shù)據(jù)可讀;否則會漏掉后續(xù)數(shù)據(jù),而沒有及時(shí)讀。
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;
}
}

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 日韩综合在线 | 亚洲一区二区电影在线观看 | 亚洲欧美久久 | 中文字幕视频在线观看 | 国产精品视频在线免费观看 | 精品久久久久国产 | 精品国产乱码久久久久久影片 | 亚州精品天堂中文字幕 | 国产精品毛片av一区 | 综合国产 | 亚洲精品一区二区在线观看 | 亚洲精品久久久一区二区三区 | 成人午夜影院 | 91毛片在线看 | 久久久国产一区 | 国产成人精品在线 | 欧美一区二区三区在线观看 | 亚洲成人在线网 | 国产人成精品一区二区三 | 国产日韩一区二区三免费 | 婷婷色国产偷v国产偷v小说 | 综合网在线 | 日韩欧美在线不卡 | 日日干夜夜草 | 亚洲成人第一页 | 国产日韩欧美在线 | 欧美精品成人一区二区三区四区 | 亚洲日本欧美日韩高观看 | 国产va| 国产在线资源 | 永久精品| 精品国产乱码一区二区三区a | 亚洲精品成人av久久 | 一级毛片视频免费观看 | 一级毛片播放 | 欧美一区免费 | 亚洲综合无码一区二区 | 精品一二区 | 久久久精彩视频 | 国产午夜精品一区二区三区嫩草 | 亚洲精品aⅴ |