kilroy_guo
驱动大牛
驱动大牛
  • 注册日期2002-10-29
  • 最后登录2005-11-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2933回复:16

如何把内核的buffer地址,映射到用户态的虚拟地址?大肥虫,老烟枪,肥猪,我来了!

楼主#
更多 发布于:2003-04-04 11:53
如何把内核的buffer地址,映射到用户态的虚拟地址,使得用户可以直接用虚拟地址访问内核buffer的数据?
以及内核的buffer使用什么方法创建?

小弟请教各位大侠了!(有代码给,更好)

最新喜欢:

cb615cbcb615c...
二姑家的猫想......
kilroy_guo
驱动大牛
驱动大牛
  • 注册日期2002-10-29
  • 最后登录2005-11-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-04-04 13:35
无人回答
凄凄惨惨凄凄

-_-
二姑家的猫想......
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2003-04-04 14:09
OSR有篇文章《Sharing Memory Between Drivers and Applications》,讲了的。
以前有人贴过。

部分如下。

The driver allocates an MDL to describe the buffer using IoAllocateMdl().  In addition to allocating the MDL from the I/O Manager’s look-aside list, this function fills in the MDL’s “fixed” part.  Next, to fill in the variable part of the MDL (the part with the page pointers) the driver calls MmBuildMdlForNonPagedPool().
 
With an MDL built that describes the buffer to be shared, the driver is now ready to map that buffer into the address space of the user process.  This is accomplished using the function MmMapLockedPagesSpecifyCache() (for Win2K) or MmMapLockedPages() (for NT V4).
 
The only “tricks” you need to know about calling either of the MmMapLocked…() functions are (a) you must call the function from within the context of the process into which you want to map the buffer, and (b) you specify UserMode for the AccessMode parameter.  The value returned from the MmMapLocked…() call is the user virtual address into which the buffer described by the MDL has been mapped.  The driver can return that to the user application in a buffer in response to an IOCTL.  That’s all there is to it.
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2003-04-04 14:11
下面是给的example

PVOID
CreateAndMapMemory()
{
    PVOID buffer;    
    PMDL  mdl;
    PVOID userVAToReturn;
 
    //
    // Allocate a 4K buffer to share with the application
    //
    buffer = ExAllocatePoolWithTag(NonPagedPool,
                                   PAGE_SIZE,
                                   \'MpaM\');
 
    if(!buffer)  {
        return(NULL);
    }
 
    //
    // Allocate and initalize an MDL that describes the buffer
    //
    mdl = IoAllocateMdl(buffer,
                        PAGE_SIZE,
                        FALSE,
                        FALSE,
                        NULL);
 
    if(!mdl)  {
        ExFreePool(buffer);
        return(NULL);
    }
 
    //
    // Finish building the MDL -- Fill in the \"page portion\"
    //
    MmBuildMdlForNonPagedPool(mdl);
 
#if NT_40
 
    //
    // Map the buffer into user space
    //
    // NOTE: This function bug checks if out of PTEs
    //
    userVAToReturn = MmMapLockedPages(mdl,
                                      UserMode);
 
#else
 
    //
    // The preferred V5 way to map the buffer into user space
    //
    userVAToReturn =
         MmMapLockedPagesSpecifyCache(mdl,          // MDL
                                      UserMode,     // Mode
                                      MmCached,     // Caching
                                      NULL,         // Address
                                      FALSE,        // Bugcheck?
                                      NormalPagePriority); // Priority
 
    //
    // If we get NULL back, the request didn\'t work.
    // I\'m thinkin\' that\'s better than a bug check anyday.
    //
    if(!userVAToReturn)  {
 
        IoFreeMdl(mdl);        
        ExFreePool(buffer);
        return(NULL);
    }
 
#endif
 
    //
    // Store away both the mapped VA and the MDL address, so that
    // later we can call MmUnmapLockedPages(StoredPointer, StoredMdl)
    //
    StoredPointer = userVAToReturn;
    StoredMdl = mdl;
 
    DbgPrint(\"UserVA = 0x%0x\\n\", userVAToReturn);
 
    return(userVAToReturn);
}
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
地下室#
发布于:2003-04-04 14:13
题外话:
大肥虫、老烟枪、肥猪都是who啊? :D
kilroy_guo
驱动大牛
驱动大牛
  • 注册日期2002-10-29
  • 最后登录2005-11-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-04-04 14:31
你好,arthurtu。以下是我先前做的,我的kernel buffer是用ExAllocatePool(NonPagedPoolCacheAligned , Size);创建的,当用户层调用
IOCTL_EZUSB_TW_CREATEBUFFER时候,我最终得到的pdx->userAddr是0xa40000,用户层一用到这个地址,就谈出错误框说这个地址访问错误,我的代码好像和你给的差不多。困惑阿!

case IOCTL_EZUSB_TW_CREATEBUFFER:

Irp->IoStatus.Status = STATUS_SUCCESS;

if(!pdx->userAddr)
{
  pdx->pMDL = IoAllocateMdl(pdx->Data3MRingBuffer->buffer,
DATABUF_SIZE,
FALSE,
FALSE,
NULL);
if( pdx->pMDL )
{
if (pdx->pMDL->ByteCount < DATABUF_SIZE)
{
Ezusb_KdPrint((\"kilroy pdx->pMDL->ByteCount < DATABUF_SIZE Th_ProcessIOCTL, pMDL %x\\n\", pdx->pMDL));
}
Ezusb_KdPrint((\"Th_ProcessIOCTL, pMDL %x\\n\", pdx->pMDL));

MmBuildMdlForNonPagedPool( pdx->pMDL );
MmProbeAndLockPages(pdx->pMDL ,KernelMode,IoWriteAccess|IoReadAccess|IoModifyAccess);
// pdx->userAddr = MmMapLockedPages( pdx->pMDL , UserMode );
pdx->pMDL->MdlFlags |= MDL_PAGES_LOCKED;
pdx->userAddr = MmMapLockedPagesSpecifyCache (pdx->pMDL,
                                         UserMode,
                                         MmCached,
                                         NULL,
                                         TRUE,
                                         HighPagePriority);
}
else
{
  Ezusb_KdPrint((\"Th_ProcessIOCTL, fail to IoAllocateMdl()\"));
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
}
}

Ezusb_KdPrint((\"Th_ProcessIOCTL, userAddr %x.\\n\", pdx->userAddr ));
*((PVOID*)ioBuffer) = pdx->userAddr;
outputBufferLength = sizeof(PVOID);
            Irp->IoStatus.Information = sizeof(PVOID);
break;
二姑家的猫想......
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
6楼#
发布于:2003-04-04 14:36
对不起,代码我并没有验证过。
kilroy_guo
驱动大牛
驱动大牛
  • 注册日期2002-10-29
  • 最后登录2005-11-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-04-04 14:41
没关系,我马上验证一下,多谢帮忙!
trent是肥猪
ydyuse好像是老烟枪又好像是大肥虫,另外一个姓名忘了。

^<+++++>^
二姑家的猫想......
kilroy_guo
驱动大牛
驱动大牛
  • 注册日期2002-10-29
  • 最后登录2005-11-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-04-04 14:58
验证结果和我的一样pdx->userAddr是0xa40000

另外说明一下我的kernel buffer大小是3M字节。
二姑家的猫想......
slwqw
驱动大牛
驱动大牛
  • 注册日期2002-07-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望197点
  • 贡献值0点
  • 好评度147点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-04-04 15:53
提一个建议:能不能使用Section啊?即在内核调用ZwCreateSection()建立空间,然后在App中调用NTDLL.DLL里边的ZwOpenSection()和ZwMapViewOfSection()来读取或者写入那块内存。

kilroy_guo
驱动大牛
驱动大牛
  • 注册日期2002-10-29
  • 最后登录2005-11-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-04-04 16:20
提一个建议:能不能使用Section啊?即在内核调用ZwCreateSection()建立空间,然后在App中调用NTDLL.DLL里边的ZwOpenSection()和ZwMapViewOfSection()来读取或者写入那块内存。

 


没找到ZwCreateSection,自己对这个不了解。我还是调查先前的那种做法

:‘(
二姑家的猫想......
Sunbeam
驱动小牛
驱动小牛
  • 注册日期2001-10-29
  • 最后登录2010-01-29
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望12点
  • 贡献值0点
  • 好评度11点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2003-04-04 17:47
提一个建议:能不能使用Section啊?即在内核调用ZwCreateSection()建立空间,然后在App中调用NTDLL.DLL里边的ZwOpenSection()和ZwMapViewOfSection()来读取或者写入那块内存。

 

肯定可以。最近事情忙,我给不了EXAMPLE,过几天再说。这种方法的功能巨强,想要做的话,可以看看它的原理。
堂堂正正做人,明明白白做事
kilroy_guo
驱动大牛
驱动大牛
  • 注册日期2002-10-29
  • 最后登录2005-11-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2003-04-04 18:06
[quote]提一个建议:能不能使用Section啊?即在内核调用ZwCreateSection()建立空间,然后在App中调用NTDLL.DLL里边的ZwOpenSection()和ZwMapViewOfSection()来读取或者写入那块内存。

 

肯定可以。最近事情忙,我给不了EXAMPLE,过几天再说。这种方法的功能巨强,想要做的话,可以看看它的原理。
 [/quote]


期待中。。。。。。
二姑家的猫想......
kilroy_guo
驱动大牛
驱动大牛
  • 注册日期2002-10-29
  • 最后登录2005-11-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2003-04-09 11:04
搞定了,我原来的方法是可行的,因为我的app在调用map地址的ioctrl后,又调用closedevicehandle,这个时候我把内存buffer又释放了,所以映射后的地址a50000不能访问!!!

自己粗心,搞了这么长时间,真是害人害己阿!
结案了,放点小分,酬谢大家  :)
二姑家的猫想......
cb615cb
驱动牛犊
驱动牛犊
  • 注册日期2002-08-18
  • 最后登录2005-01-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2003-09-19 21:10
有没有适用DS的??????谢谢!
libin2309
驱动大牛
驱动大牛
  • 注册日期2002-11-20
  • 最后登录2005-12-29
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2003-09-19 21:18
有没有适用DS的??????谢谢!


DS的帮助文件里专门讲了关于把驱动分配的缓冲映射到应用层的事,然后通过DEVICEIOCTL传递到应用层,我试了一下,能成功实现。但在什么地方,在什么时候来取消映射,我老是做不好,还请大虾们指点!
我是一只小小鸟,永远也飞也飞不高,但我永远在飞!
cb615cb
驱动牛犊
驱动牛犊
  • 注册日期2002-08-18
  • 最后登录2005-01-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2003-09-20 09:34
\"DS的帮助文件里专门讲了关于把驱动分配的缓冲映射到应用层的事,然后通过DEVICEIOCTL传递到应用层\"。在哪?DriverWorks Help里面我没有找到啊!
游客

返回顶部