lovehunterboy
驱动小牛
驱动小牛
  • 注册日期2008-05-29
  • 最后登录2010-04-16
  • 粉丝2
  • 关注0
  • 积分67分
  • 威望463点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2969回复:11

求助:共享内存+事件:驱动向应用程序通信,应用程序怎么不能读共享内存?

楼主#
更多 发布于:2008-12-29 12:25
驱动这样写的:
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)));

请各们前辈帮忙看看是怎么回事?


        


dreamsity
驱动小牛
驱动小牛
  • 注册日期2006-09-01
  • 最后登录2013-07-04
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望821点
  • 贡献值1点
  • 好评度68点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2008-12-29 15:54
AP是无法直接访问内核内存地址的。
为什么要把内核内存向AP隐射呐?
可以把内核内存映射到AP的地址空间,但需要是使用函数MmMapIoSpace。
我记得有一个PortIo的例子里讲解了这中方法怎么用。但不建议这样使用。
共享内存最简单的使用方法,应该是DDK的SAMPLE中的\src\general\ioctl\sys,
这个例子里的IOCTL_SIOCTL_METHOD_NEITHER可以满足你的要求的。
建议先看一下这个例子。
一切都是时间问题!
zhaock
驱动太牛
驱动太牛
  • 注册日期2002-01-26
  • 最后登录2018-06-02
  • 粉丝3
  • 关注2
  • 积分73328分
  • 威望362317点
  • 贡献值1点
  • 好评度226点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2008-12-29 17:41
1.基本方法没有错,但是在case GET_EVENT里映射一次就可以,返回用户态的指针,用不着每次映射。你现在碰到的是什么错误,指针非法,还是内容不对。
2.你要实现什么功能,用2楼说得常见的方法不能满足你的需要,再考虑你目前的方法。不然尽量用标准的方法
troylees
驱动牛犊
驱动牛犊
  • 注册日期2006-05-10
  • 最后登录2009-05-01
  • 粉丝0
  • 关注0
  • 积分678分
  • 威望128点
  • 贡献值0点
  • 好评度67点
  • 原创分0分
  • 专家分0分
地板#
发布于:2008-12-29 18:20
你的IOCTL使用什么缓冲方法,METHOD_BUFFERED?
*((PVOID *)outputBuffer) = psharememory->UserBaseAddress;
确定正确返回给app?
*((PVOID *)(pIrp->AssociatedIrp.SystemBuffer))  =*((PVOID *)outputBuffer)?
bytesReturned应该是&bytesReturned吧。。

为什么要把创建和映射共享内存分开呢?不清楚你这样分开会不会有问题。  
lovehunterboy
驱动小牛
驱动小牛
  • 注册日期2008-05-29
  • 最后登录2010-04-16
  • 粉丝2
  • 关注0
  • 积分67分
  • 威望463点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2008-12-29 18:25
谢谢您们的指点啊!我没找到这个例子啊!
lovehunterboy
驱动小牛
驱动小牛
  • 注册日期2008-05-29
  • 最后登录2010-04-16
  • 粉丝2
  • 关注0
  • 积分67分
  • 威望463点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2008-12-29 18:29
出错的地方说的是非法访问地址
troylees
驱动牛犊
驱动牛犊
  • 注册日期2006-05-10
  • 最后登录2009-05-01
  • 粉丝0
  • 关注0
  • 积分678分
  • 威望128点
  • 贡献值0点
  • 好评度67点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2008-12-29 23:04
那就是你没有正确把地址映射到app的空间吧,建议你把创建和映射共享内存在一个case里面处理。
*((PVOID *)outputBuffer)不清楚你的outputBuffer是什么,正确的应该系
*((PVOID *)(pIrp->AssociatedIrp.SystemBuffer))  ,试试吧
lovehunterboy
驱动小牛
驱动小牛
  • 注册日期2008-05-29
  • 最后登录2010-04-16
  • 粉丝2
  • 关注0
  • 积分67分
  • 威望463点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
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显示是一致的,
但是访问这个地址时就出错。
dreamsity
驱动小牛
驱动小牛
  • 注册日期2006-09-01
  • 最后登录2013-07-04
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望821点
  • 贡献值1点
  • 好评度68点
  • 原创分1分
  • 专家分0分
8楼#
发布于:2008-12-30 18:34
DDK的例子默认是不会安装的。需要选择完全安装。
一切都是时间问题!
lee922@gmail.co
驱动牛犊
驱动牛犊
  • 注册日期2007-07-31
  • 最后登录2010-06-22
  • 粉丝0
  • 关注0
  • 积分39分
  • 威望340点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分1分
9楼#
发布于:2009-11-18 16:21
应用程序使用共享内存的时候,需要在所使用的那个线程获得映射地址,然后再使用,如果在另一个线程使用共享内存还需要重新映射一次。
vipfengxiao
驱动牛犊
驱动牛犊
  • 注册日期2009-12-29
  • 最后登录2011-12-21
  • 粉丝1
  • 关注0
  • 积分79分
  • 威望681点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2010-03-13 09:53
我在驱动中给共享内存拷贝数据就蓝屏
vipfengxiao
驱动牛犊
驱动牛犊
  • 注册日期2009-12-29
  • 最后登录2011-12-21
  • 粉丝1
  • 关注0
  • 积分79分
  • 威望681点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2010-03-15 16:21
奇怪了 我在驱动给应用层发事件 编译 的是server2003版本 装在server2003机子上就蓝屏  装在XP上不蓝屏 不知道什么原因呢
游客

返回顶部