谁用过DRIVERWORKS下的KKernelSharedFifo呀,我想在驱动和应用之间共享内存,但是用不起

de177 2003-09-24 10:39:48
KKernelSharedFifo
...全文
24 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
de177 2003-09-24
  • 打赏
  • 举报
回复
谢谢,
是不是做映射之后,要把指针通过DEVICECONTROL传送给应用程序呢?
Leo 2003-09-24
  • 打赏
  • 举报
回复
转帖
影射核心内存到用户模式进程

映射由核心模式分配的缓冲到一个特定用户进程的虚拟地址空间,这种方法非常简单。并能使驱动程序保留对这种内存最大控制权。

驱动程序可以使用任意标准的方法来分配要共享的缓冲,如果没有特殊的要求并且大小适度,可以将它分配在非分页池中。

驱 动 程 序 使 用 IoAllocateMdl() 分 配 一 个 MDL 来 描 述 这 个 缓 冲, 然 后 调 用MmBuildMdlForNonPagedPool()。这个函数修改MDL以描述内核模式中一个非分页内存区域。
当用来描述共享缓冲的MDL建立起来以后,驱动程序现在可以准备将缓冲映射到用户进程的地 址空间了,由MmMapLockedPagesSpecifyCache() 这个函数完成。

你必须要在你想要映射共享缓冲的进程上下文环境中调用MmMapLockedPagesSpecifyCache(),并且指定AccessMode参数为UserMode。这个函数返回由MDL映射的用户态虚拟地址。 驱动程序可以把这个值作为用户程序发送IOCTL请求时的返回值返回给用户程序。

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);

}

在映射完共享缓冲以后,可以在任意进程上下文环境中对它进行访问,并且可以在提升的IRQL上访问(因为是在非分页内存中)。

如果使用这种方法,有一个情况必须注意:你必须保证驱动程序提供一个方法在用户程序退出的时候来取消映射。



21,597

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧