阅读:2987回复: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 18:25
谢谢您们的指点啊!我没找到这个例子啊!
|
|
板凳#
发布于:2008-12-29 18:29
出错的地方说的是非法访问地址
|
|
地板#
发布于: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显示是一致的, 但是访问这个地址时就出错。 |
|