阅读:2933回复:16
如何把内核的buffer地址,映射到用户态的虚拟地址?大肥虫,老烟枪,肥猪,我来了!
如何把内核的buffer地址,映射到用户态的虚拟地址,使得用户可以直接用虚拟地址访问内核buffer的数据?
以及内核的buffer使用什么方法创建? 小弟请教各位大侠了!(有代码给,更好) |
|
最新喜欢:cb615c...
|
沙发#
发布于:2003-04-04 13:35
无人回答
凄凄惨惨凄凄 -_- |
|
|
板凳#
发布于: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. |
|
地板#
发布于: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); } |
|
地下室#
发布于:2003-04-04 14:13
题外话:
大肥虫、老烟枪、肥猪都是who啊? :D |
|
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; |
|
|
6楼#
发布于:2003-04-04 14:36
对不起,代码我并没有验证过。
|
|
7楼#
发布于:2003-04-04 14:41
没关系,我马上验证一下,多谢帮忙!
trent是肥猪 ydyuse好像是老烟枪又好像是大肥虫,另外一个姓名忘了。 ^<+++++>^ |
|
|
8楼#
发布于:2003-04-04 14:58
验证结果和我的一样pdx->userAddr是0xa40000
另外说明一下我的kernel buffer大小是3M字节。 |
|
|
9楼#
发布于:2003-04-04 15:53
提一个建议:能不能使用Section啊?即在内核调用ZwCreateSection()建立空间,然后在App中调用NTDLL.DLL里边的ZwOpenSection()和ZwMapViewOfSection()来读取或者写入那块内存。
|
|
10楼#
发布于:2003-04-04 16:20
提一个建议:能不能使用Section啊?即在内核调用ZwCreateSection()建立空间,然后在App中调用NTDLL.DLL里边的ZwOpenSection()和ZwMapViewOfSection()来读取或者写入那块内存。 没找到ZwCreateSection,自己对这个不了解。我还是调查先前的那种做法 :‘( |
|
|
11楼#
发布于:2003-04-04 17:47
提一个建议:能不能使用Section啊?即在内核调用ZwCreateSection()建立空间,然后在App中调用NTDLL.DLL里边的ZwOpenSection()和ZwMapViewOfSection()来读取或者写入那块内存。 肯定可以。最近事情忙,我给不了EXAMPLE,过几天再说。这种方法的功能巨强,想要做的话,可以看看它的原理。 |
|
|
12楼#
发布于:2003-04-04 18:06
[quote]提一个建议:能不能使用Section啊?即在内核调用ZwCreateSection()建立空间,然后在App中调用NTDLL.DLL里边的ZwOpenSection()和ZwMapViewOfSection()来读取或者写入那块内存。 肯定可以。最近事情忙,我给不了EXAMPLE,过几天再说。这种方法的功能巨强,想要做的话,可以看看它的原理。 [/quote] 期待中。。。。。。 |
|
|
13楼#
发布于:2003-04-09 11:04
搞定了,我原来的方法是可行的,因为我的app在调用map地址的ioctrl后,又调用closedevicehandle,这个时候我把内存buffer又释放了,所以映射后的地址a50000不能访问!!!
自己粗心,搞了这么长时间,真是害人害己阿! 结案了,放点小分,酬谢大家 :) |
|
|
14楼#
发布于:2003-09-19 21:10
有没有适用DS的??????谢谢!
|
|
15楼#
发布于:2003-09-19 21:18
有没有适用DS的??????谢谢! DS的帮助文件里专门讲了关于把驱动分配的缓冲映射到应用层的事,然后通过DEVICEIOCTL传递到应用层,我试了一下,能成功实现。但在什么地方,在什么时候来取消映射,我老是做不好,还请大虾们指点! |
|
|
16楼#
发布于:2003-09-20 09:34
\"DS的帮助文件里专门讲了关于把驱动分配的缓冲映射到应用层的事,然后通过DEVICEIOCTL传递到应用层\"。在哪?DriverWorks Help里面我没有找到啊!
|
|