关于MDL的一些事(2)
对驱动程序采用 Direct I/O 方式进行数据读的测试
采用这种方式进行读数据时, I/O Manager 调用 MmProbeAndLockPages 将 ReadFile 参数提供的用户空间缓冲区对应的物理页面锁定为不可换出,然后将得到的MDL放在Irp->MdlAddress里,将IRP传递给相应驱动程序的DispatchRead。根据Walter Oney在书中的描述,此时I/O Manager的行为可以用下面的代码来描述:
KPROCESSOR_MODE mode; // <== either KernelMode or UserMode PMDL mdl = IoAllocateMdl(uva, length, FALSE, TRUE, Irp); MmProbeAndLockPages(mdl, mode, reading ? IoWriteAccess : IoReadAccess); <code to send and await IRP> MmUnlockPages(mdl); IoFreeMdl(mdl);
这里主要关注的地方是MmProbeAndLockPages有没有进行实际的虚拟地址的映射,即将物理页面映射到内核地址空间中。我们用下面的驱动代码来测试这一行为。
NTSTATUS DispatchRead(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) { PVOID pSysAddr; PMDL pMDL = pIrp->MdlAddress; DbgPrint("******************DispatchRead******************/n"); DbgPrint("Before MmGetSystemAddressForMdlSafe/n"); OutputMDL(pMDL); pSysAddr = MmGetSystemAddressForMdlSafe(pMDL,LowPagePriority); if(!pSysAddr) { DbgPrint("MmGetSystemAddressForMdlSafe failed./n"); return STATUS_SUCCESS; } DbgPrint("After MmGetSystemAddressForMdlSafe/n"); OutputMDL(pMDL); pIrp->IoStatus.Status = STATUS_SUCCESS; pIrp->IoStatus.Information = MmGetMdlByteCount(pMDL); IoCompleteRequest(pIrp,IO_NO_INCREMENT); return STATUS_SUCCESS; }
再写一个应用程序来发起一个读操作:
void TestMDLDriver() { HANDLE hDevice; BOOL bRet; DWORD dwRead; BYTE buf[10000] = {'S','Q','U','I'}; hDevice = CreateFile(_T(".//MDLTest"),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(hDevice==INVALID_HANDLE_VALUE) { fprintf(stderr,"CreateFile error : %d/n",GetLastError()); return; } //issue a read request bRet = ReadFile(hDevice,buf,sizeof(buf),&dwRead,NULL); if(!bRet) { fprintf(stderr,"ReadFile error : %d/n",GetLastError()); return; } printf("Read bytes:%d/n",dwRead); // CloseHandle(hDevice); }
导致的内核输出如下:
00000009 4.27463436 ******************DispatchRead****************** 00000010 4.27464771 Before MmGetSystemAddressForMdlSafe 00000011 4.27465439 MDL_TEST: Size=40 00000012 4.27466011 MDL_TEST: MdlFlags=0x008a 00000013 4.27466583 MDL_TEST: Process=0x86ca7b58 00000014 4.27467155 MDL_TEST: MappedSystemVa=0x92b1f000 00000015 4.27467775 MDL_TEST: StartVa=0x001ad000 00000016 4.27468348 MDL_TEST: ByteCount=10000 00000017 4.27468824 MDL_TEST: ByteOffset=1148 00000018 4.27469397 MDL_TEST: p[0]=0x00064429 00000019 4.27469969 MDL_TEST: p[1]=0x000619fc 00000020 4.27470541 MDL_TEST: p[2]=0x000618ee 00000021 4.27471066 MDL_TEST: p[3]=0x00060749 00000022 4.27471685 MDL_TEST: p[4]=0x86abca24 00000023 4.27472448 After MmGetSystemAddressForMdlSafe 00000024 4.27472973 MDL_TEST: Size=40 00000025 4.27473545 MDL_TEST: MdlFlags=0x008b 00000026 4.27474070 MDL_TEST: Process=0x86ca7b58 00000027 4.27474689 MDL_TEST: MappedSystemVa=0xb01e747c 00000028 4.27475214 MDL_TEST: StartVa=0x001ad000 00000029 4.27475786 MDL_TEST: ByteCount=10000 00000030 4.27476311 MDL_TEST: ByteOffset=1148 00000031 4.27476835 MDL_TEST: p[0]=0x00064429 00000032 4.27477455 MDL_TEST: p[1]=0x000619fc 00000033 4.27477980 MDL_TEST: p[2]=0x000618ee 00000034 4.27478504 MDL_TEST: p[3]=0x00060749 00000035 4.27479029 MDL_TEST: p[4]=0x86abca24
此时从VS的调试器中看到,应用程序中buf[10000]的地址为0x001ad47c
从输出可以得到如下结论:
1.MmProbeAndLockPages并不将物理页面映射到内核地址空间,而仅锁定物理页面;MappedSystemVa的变化可以显示这一点
2.buf的地址=StartVa+ByteOffset;
3.MmGetSystemAddressForMdlSafe进行实际的映射操作,并设置MdlFlags的MDL_MAPPED_TO_SYSTEM_VA标志。
4.MmProbeAndLockPages将MdlFlags=MDL_WRITE_OPERATION | MDL_ALLOCATED_FIXED_SIZE | MDL_PAGES_LOCKED
关于MDL的一些事(2)相关推荐
- MySQL的MDL元数据锁
一 序 本来在看mysql.taobao介绍InnoDB 事务子系统介绍 ,真的头大,名词都看不懂,还是分开来学习的好,本文主要整理MDL(metadata locking)锁.作为尝试学习人新人,发 ...
- 遇事不责怪别人,换位思考能成全更好的自己
在生活中,有时候有些人做的某些事可能会让你感觉不爽:这时,你最好不要急着去责怪他:试着把自己放在对方的处境,看看别人的生活,你才能看到人间百态,理解他人的难处. 每个人的生长环境不同,心境就不同:有些 ...
- 力所能及的做些自己喜欢和有趣的事
我们每个人都有自己喜欢做的事:在自己可控且力所能及的情况下,在闲时,按自己的意愿去做些自己喜欢和有趣的事,会感觉到这事很有意义.在忙时,要为理想和奋斗而忙:不浪费时间在无意义的事和人身上. 朋友要的是 ...
- 不要纠结于过去发生的事
在这个社会中,有些人很早就经历了一些不好的事,遇到不好的人:让他留了一些阴影.这时,应该学会不要纠结于过去发生的事情了!一件事情已经发生了,不管再怎么后悔也不能改变结局: 对这件事一直有懊悔之心,只会 ...
- 【运维学习笔记】生命不息,搞事开始。。。
001生命不息,搞事不止!!! 这段时间和hexesdesu搞了很多事情! 之前是机械硬盘和固态硬盘的测速,我就在那默默的看着他一个硬盘一个机械测来测去. 坐在他后面,每天都能看到这位萌萌的小男孩,各 ...
- 保护嵌入式802.11 Wi-Fi设备时需要考虑的10件事
保护嵌入式802.11 Wi-Fi设备时需要考虑的10件事 10 things to consider when securing an embedded 802.11 Wi-Fi device 随着 ...
- Python爬虫实战糗事百科实例
爬取糗事百科段子,假设页面的URL是 http://www.qiushibaike.com/8hr/page/1 要求: 使用requests获取页面信息,用XPath / re 做数据提取 获取每个 ...
- 关于.NET玩爬虫这些事 【初码干货】
这几天在微信群里又聊到.NET可以救中国但是案例太少不深的问题,我说.NET玩爬虫简直就是宇宙第一,于是大神朱永光说,你为何不来写一篇总结一下? 那么今天就全面的来总结一下,在.NET生态下,如何玩爬 ...
- 《创业维艰分享之五》所有得,有所乐,日事日清,循序渐进。
这两个月公司连续做了两个大客户紧接着发布新版本再然后又是连续五个小版本迭代计划. 每天16小时的超强度工作,我已经看到兄弟的脸上都写着一个字:累! 我自己又何尝不是,既是客服,又是程序员,还必须是行政 ...
最新文章
- 汽车电子及ADAS安全部分相关测试标准
- /bin/sh^M:损坏的解释器: No such file or directory
- 类属性-使用对象名+类属性赋值语句会创建实例属性
- Debian 新负责人发表演讲:Debian 的现状与面临的一些问题
- vue 子组件 调用、触发父组件中的方法
- python的六大数据类型中可以改变_在python中更改数组的数据类型
- echo添加换行 linux_在 Linux 上创建文件的 10 个方法
- python-环境安装-pycharm安装-新手入门可使用社区版
- DevOps 转型,只有工具是远远不够的!
- textbox控件输入内容后按下Enter键后执行button1的click方法
- SQL SERVER 2008数据库管理与维护总结
- javascript实现划词搜索功能(兼容IE,firefox,opera)
- thinkphp sql查询条件 一个字段多个限制条件
- 当当网图书爬虫与数据分析
- UVa 1586 Molar mass
- USB-HDD和USB-ZIP制作U盘启动盘有什么区别?
- JQuery实现动态漂浮广告
- win10:如何通过注册表删除右键菜单
- matlab曲线拟合工具箱 cftool
- 纯C语言日志类库 Zlog