bigbao
驱动牛犊
驱动牛犊
  • 注册日期2005-03-30
  • 最后登录2005-04-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:4606回复:6

一个关于驱动程序与应用程序内存共享的问题。

楼主#
更多 发布于:2005-04-04 12:04
在我的应用程序中,我用如下代码创建一段共享映射内存。名为“TestMem”。我想在我的驱动程序中去读去这段内存中的内容。在我的驱动程序中,我应该如何获得这段共享内存的首地址呢?用我只知道ZwOpenSection 和 ZwMapViewOfSection,可以去取得内存物理地址的映射空间,但怎么样才能使我的驱动里面,能寻址到我这片应用程序共享出来的内存? 望大家指导。谢谢了。
#define BUF_SIZE 4096

TCHAR szName[]=TEXT(\"TestMem\");
HANDLE hMapFile;
LPCTSTR pBuf;
hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE,    
NULL,                    
PAGE_READWRITE,          
0,                      
BUF_SIZE,                
szName);              

if (hMapFile == NULL || hMapFile == INVALID_HANDLE_VALUE)
{
  AfxMessageBox(\"Could not create file mapping object (%d).\\n\", GetLastError());
}

pBuf = (LPTSTR) MapViewOfFile(hMapFile,FILE_MAP_ALL_ACCESS, 0, 0,BUF_SIZE);          

if (pBuf == NULL)
{
  AfxMessageBox(\"Could not map view of file (%d).\\n\", GetLastError());
  
}
CopyMemory((PVOID)pBuf, szMsg, strlen(szMsg));




最新喜欢:

linshierlinshi...
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
沙发#
发布于:2005-04-04 14:46
ZwMapViewOfSection会返回一个虚拟地址,通过它可以访问那块内存。
MSDN 里面提供了sample code,看看吧:

附件名称/大小 下载次数 最后更新
2005-04-04_Section.zip (11KB)  262
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
bmyyyud
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2010-01-21
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望130点
  • 贡献值0点
  • 好评度106点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-04-05 08:30
ZwMapViewOfSection会返回一个虚拟地址,通过它可以访问那块内存。
MSDN 里面提供了sample code,看看吧:

 

访问时一定要注意上下文
滚滚长江东逝水 浪花淘尽英雄 是非成败转头空 青山依旧在 几度夕阳红 白发渔樵江渚上 惯看秋月春风 一壶浊酒喜相逢 古今多少事 尽付笑谈中
zealsoft_zhu
驱动小牛
驱动小牛
  • 注册日期2004-03-30
  • 最后登录2014-07-30
  • 粉丝2
  • 关注0
  • 积分22分
  • 威望375点
  • 贡献值0点
  • 好评度137点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-04-14 16:43
我第一次在这个版回答别人的问题,因为我比较懒,不愿意打字。我也很少上这个网。今天上来是来查找一些资料,开发碰到一些麻烦了。别人一般都不回答我的问题,可能是我的问题比较复杂,或者做的人太少,也有可能是有些人和我一样不愿意打字。我想想,应该大家都别怕麻烦,都来回答别人的问题比较好。
共享内存这个东西,特别是在用户态和核心态,要注意很多方面。
1。我不建议程序员在用户态分配共享内存区域。因为是这样的,IRP可能在核心态一层一层传下去,可能进程上下文改变了。用户态的地址空间分配的内存显然不能在核心态访问了。
2.就算你在用户态分配内存,然后转换成物理地址,然后把物理地址传递给核心态,核心态在转换成虚拟地址访问。也存在一个问题。因为你的内存是在分页内存上分配的,可能会交换到硬盘上,然而你的驱动可能运行在比较高的IRQL上,这个时候发生缺页中断,那就只能蓝屏了。
所以,我建议,共享内存在核心态分配,如果要求不是很大的情况下,可以在非分页上分配。如果要在分页上访问,最好锁定(这个不能完全保证它在内存而不交换出,在特殊情况下还是会交换出)。
我建议这么做。
1。在核心态分配内存。
2。创建一个mdl和内存连接起来。
3。用MmBuildMdlForNonPagedPool或者相关函数把虚拟地址转换成物理地址。
4。用MmMapLockedPagesSpecifyCache把物理地址转换成本进程上下文中的虚拟地址。用户态就用这个地址访问。
注意点:
1。在核心态访问的时候如果不确定是在相同的进程上下文,别用
MmMapLockedPagesSpecifyCache函数返回的地址访问共享内存。而是用这个函数再转换一次。

顺便问一下:有没有人写scsi总线方面的东西,我要写一个虚拟scsi的target驱动

mybasket
驱动牛犊
驱动牛犊
  • 注册日期2005-12-30
  • 最后登录2009-04-16
  • 粉丝0
  • 关注0
  • 积分50分
  • 威望6点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-09-27 21:09
谢谢!好贴!顶!!!
ll_z
ownerscu
驱动牛犊
驱动牛犊
  • 注册日期2007-09-03
  • 最后登录2015-08-13
  • 粉丝1
  • 关注0
  • 积分4分
  • 威望27点
  • 贡献值0点
  • 好评度13点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2008-04-23 17:12
共享内存对象方法
通常,将页面文件支持的内存映射文件作为在用户进程之间共享内存的技术。但是,可以使用相同的技术在用户进程与设备驱动程序之间共享内存。使用这种技术有两种方法。

第一种方法中,通过使用 OpenFileMapping,然后调用 MapViewOfFile 函数以获取指向某个区域或所有共享内存的指针,驱动程序可以创建命名内存对象(称为“区域对象”),并且一个或多个用户应用程序可以打开相同的对象。通过向区域对象指定保护属性,可以定义进程操纵内存的方式。

第二种方法中,应用程序可以用 CreateFileMapping 在用户模式下创建命名内存对象。驱动程序通过使用 ZwOpenSection 并调用 ZwMapViewOfSection 获取指向它的指针,可以打开相同的内存对象。始终用异常处理程序在内核模式下访问此内存地址。

由于该对象始终映射在进程的用户地址空间(小于 0x80000000,无论对象是在内核模式还是在用户模式中创建的)中,因此只在进程上下文中访问地址时,地址才有效。每次在相同内存对象上调用 MapViewOfFile 或 ZwMapViewOfSection 时,都将返回不同的内存地址(即使是相同的进程,也是如此)。建议不要使用这种方法(尤其是低级设备驱动程序),正如前面所述,这是因为地址范围限定于进行对象映射的进程,并且不能在 DPC 或 ISR 中对地址进行访问。另外,在 DDK 中没有记载在内核模式下创建内存对象的 API。

但是,要在提高的 IRQL(如 DPC 或 ISR 中)上使用该地址,必须查明并锁定缓冲区页面,并获取系统虚拟地址 MmGetSystemAddressForMdl(正如本文前面 IOCTL 方法中所述)。

仅当要在两个(或更多)用户进程与一个(或多个)设备驱动程序之间共享内存的情况下,这种方法才比较简便。否则,使用 IOCTL 技术在用户进程与设备驱动程序之间共享内存更加简单高效。
niuyi
驱动牛犊
驱动牛犊
  • 注册日期2006-06-08
  • 最后登录2010-02-24
  • 粉丝1
  • 关注0
  • 积分13分
  • 威望34点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2010-01-21 10:01
scsi驱动我做过模拟
游客

返回顶部