阅读:3089回复:11
求助:共享内存+事件:驱动向应用程序通信,应用程序怎么不能读共享内存?
驱动这样写的:
case GET_EVENT: { OBJECT_HANDLE_INFORMATION objHandleInfo; HANDLE hEvent = *(HANDLE *)inputBuffer; Irp->IoStatus.Status =ObReferenceObjectByHandle(hEvent,GENERIC_ALL,NULL, KernelMode, &gpEventObject, &objHandleInfo); if(gpEventObject) { DbgPrint("gpEventObject\n"); psharememory = ExAllocatePoolWithTag(NonPagedPool, sizeof(PKT_BUFFER),'MhSp'); CreateShareMemory(psharememory,sizeof(Monitor_Message)); } DbgPrint("Get_EVENT\n"); break; } case MONITOR_INFO: { MapSharedMemory(psharememory);DbgPrint("sendINFO11\n"); *((PVOID *)outputBuffer) = psharememory->UserBaseAddress;DbgPrint("sendINFO22:%d\n",psharememory->UserBaseAddress); Irp->IoStatus.Information = sizeof(PVOID);DbgPrint("sendINFO333\n"); DbgPrint("sendINFO\n"); break; } BOOLEAN CreateShareMemory(PPKT_BUFFER PktBuffer, ULONG Size) { PktBuffer->KernelBaseAddress = ExAllocatePoolWithTag(NonPagedPool, Size,'MpaM'); if(!PktBuffer->KernelBaseAddress) return FALSE; DbgPrint("allot 1"); // // 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; DbgPrint("allot 2"); return FALSE; } MmBuildMdlForNonPagedPool(PktBuffer->BufferMdl); //页面用这个:MmProbeAndLockPages DbgPrint("CreateShareMemory: KernelBaseAddress = 0x%p\n", PktBuffer->KernelBaseAddress); return TRUE; } 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; DbgPrint("MapSharedMemory SUCCESS, UserBaseAddress %p\n", PktBuffer->UserBaseAddress); return TRUE; } 应用程序的createthread线程这样写的(本来用的是DELPHI,改成了C,可能没改彻底): dword GetMonitorInfo( ThreadPara * para); { PVOID pInfo ; PULONG pSend; ULONG addr; DWORD bytesReturned; if eventhandle==0 { eventhandle=CreateEvent(nil,false,false,nil);//eventhandle全局变量 pSend=malloc(sizeof(ULONG)); Copymemory(pSend,&eventhandle,sizeof(eventhandle)); DeviceIoControl(m_handle,GET_EVENT,pSend,sizeof(eventhandle),NULL,0,bytesReturned,NULL);//发送事件句柄,并共享内存 f ree(pSend); } pInfo=malloc(sizeof(TMonitorMessage)); while(true) { WaitForSingleObject(eventhandle, INFINITE); DeviceIoControl(m_handle,MONITOR_INFO,null,0,&addr,sizeof(PVOID),bytesReturned,null);//锁住内存并传送地址 pinfo=PVOID(addr);//转换为指针 //下面是往LISTVIEW里加信息 para->ListItem.SubItems.Add((PMonitorMessage pinfo)->fun));//这里读取共享内存出错,把共享内存转换成PMonitorMessage 指针读出想要的信息 para->ListItem.SubItems.Add((PMonitorMessage pinfo)->work))); 请各们前辈帮忙看看是怎么回事? |
|
沙发#
发布于:2008-12-29 15:54
AP是无法直接访问内核内存地址的。
为什么要把内核内存向AP隐射呐? 可以把内核内存映射到AP的地址空间,但需要是使用函数MmMapIoSpace。 我记得有一个PortIo的例子里讲解了这中方法怎么用。但不建议这样使用。 共享内存最简单的使用方法,应该是DDK的SAMPLE中的\src\general\ioctl\sys, 这个例子里的IOCTL_SIOCTL_METHOD_NEITHER可以满足你的要求的。 建议先看一下这个例子。 |
|
|
板凳#
发布于:2008-12-29 17:41
1.基本方法没有错,但是在case GET_EVENT里映射一次就可以,返回用户态的指针,用不着每次映射。你现在碰到的是什么错误,指针非法,还是内容不对。
2.你要实现什么功能,用2楼说得常见的方法不能满足你的需要,再考虑你目前的方法。不然尽量用标准的方法 |
|
地板#
发布于:2008-12-29 18:20
你的IOCTL使用什么缓冲方法,METHOD_BUFFERED?
*((PVOID *)outputBuffer) = psharememory->UserBaseAddress; 确定正确返回给app? *((PVOID *)(pIrp->AssociatedIrp.SystemBuffer)) =*((PVOID *)outputBuffer)? bytesReturned应该是&bytesReturned吧。。 为什么要把创建和映射共享内存分开呢?不清楚你这样分开会不会有问题。 |
|
地下室#
发布于:2008-12-29 18:25
谢谢您们的指点啊!我没找到这个例子啊!
|
|
5楼#
发布于:2008-12-29 18:29
出错的地方说的是非法访问地址
|
|
6楼#
发布于:2008-12-29 23:04
那就是你没有正确把地址映射到app的空间吧,建议你把创建和映射共享内存在一个case里面处理。
*((PVOID *)outputBuffer)不清楚你的outputBuffer是什么,正确的应该系 *((PVOID *)(pIrp->AssociatedIrp.SystemBuffer)) ,试试吧 |
|
7楼#
发布于:2008-12-30 12:20
按您的意思:那就是你没有正确把地址映射到app的空间吧,建议你把创建和映射共享内存在一个case里面处理。已修改。
我的outputBuffer=Irp->AssociatedIrp.SystemBuffer;IO方式是METHOD_BUFFERED; 通过显示:应用程序得到的地址和驱动传来的UserBaseAddress是一致的。 DBG显示如下: CreateShareMemory: KernelBaseAddress = 0x817DA138 MapSharedMemory SUCCESS, UserBaseAddress 011A0138//这里还没锁定 Get_EVENT sendINFO22:18481464//这个锁定后的,APP用showmessage显示是一致的, 但是访问这个地址时就出错。 |
|
8楼#
发布于:2008-12-30 18:34
DDK的例子默认是不会安装的。需要选择完全安装。
|
|
|
驱动牛犊
|
9楼#
发布于:2009-11-18 16:21
应用程序使用共享内存的时候,需要在所使用的那个线程获得映射地址,然后再使用,如果在另一个线程使用共享内存还需要重新映射一次。
|
10楼#
发布于:2010-03-13 09:53
我在驱动中给共享内存拷贝数据就蓝屏
|
|
11楼#
发布于:2010-03-15 16:21
奇怪了 我在驱动给应用层发事件 编译 的是server2003版本 装在server2003机子上就蓝屏 装在XP上不蓝屏 不知道什么原因呢
|
|