</pre><p>需求:应用层申请一个空间,然后将地址传递到驱动层,驱动直接将处理后的数据放到应用层指定的空间中,类似于Linux下的copy_from_user。</p><p></p><p>应用层代码片段:</p><p><span style="white-space:pre">将申请的地址传递到驱动层</span></p><pre code_snippet_id="576642" snippet_file_name="blog_20150110_2_1402064" name="code" class="cpp"> CHAR buf[64] = {0}; int iWriteLen = 0; char *pWaddr = NULL; char *pRaddr = NULL; unsigned long *pTmp = NULL; pWaddr = (char*)calloc(1, 32); pRaddr = (char*)calloc(1, 32); if ((pWaddr ==NULL) || (pRaddr==NULL)) { puts("calloc error"); CloseHandle(hDevice); return 0; } memset(pWaddr, 'A', 24); pTmp = (unsigned long*)buf; pTmp[0] = (unsigned long)0;//pWaddr; pTmp[1] = (unsigned long)pRaddr; if (WriteFile(hDevice, buf, 8, (LPDWORD)&iWriteLen, NULL)) { puts("write Success"); } else { puts("Write Failed"); }
驱动层代码片段:
VOID uAddr2dAddr(PVOID pUsr, unsigned long iUsrLen, BOOLEAN bRead) { int i = 0; LOCK_OPERATION opt = IoWriteAccess; PUCHAR pVir = NULL; PMDL mdl ; if (!MmIsAddressValid(pUsr))//如果没有这个判断,应用传入的是非法地址时,会导致在下面获得虚拟地址时,蓝屏 { KdPrint(("MmIsAddressValid UnIvalid error\n")); return ; } mdl = IoAllocateMdl(pUsr, iUsrLen, FALSE, TRUE, NULL); if (mdl == NULL) { KdPrint(("IoAllocateMdl error\n")); return ; } if (bRead) { opt = IoReadAccess; } MmProbeAndLockPages(mdl, UserMode, opt); pVir = MmMapLockedPagesSpecifyCache(mdl,KernelMode,MmCached,NULL,FALSE,NormalPagePriority);//如果pUser不合法时,调用此函数会引起蓝屏 KdPrint(("MmMapLockedPagesSpecifyCache: %#x\n", (unsigned long)pVir)); pVir = MmGetSystemAddressForMdlSafe(mdl, NormalPagePriority);<span style="font-family: Arial, Helvetica, sans-serif;">//如果pUser不合法时,调用此函数会引起蓝屏</span> KdPrint(("MmGetSystemAddressForMdlSafe: %#x\n", (unsigned long)pVir)); pVir = MmGetMdlVirtualAddress(mdl);<span style="font-family: Arial, Helvetica, sans-serif;">//如果pUser不合法时,调用此函数会引起蓝屏</span> KdPrint(("MmGetMdlVirtualAddress: %#x\n", (unsigned long)pVir)); if (pVir == NULL) { KdPrint(("IoAllocateMdl error\n")); return ; } KdPrint(("\n----------------------DML Data------------------\n\n")); if (bRead) { for (i=0; i<4; i++) { for (i=0; i<4; i++) { pVir[i] = 'B'; } } } else { for (i=0; i<4; i++) { KdPrint(("%c ", pVir[i])); } } KdPrint(("\n-------------------End DML Data------------------\n\n")); MmUnlockPages(mdl); IoFreeMdl(mdl); }
用DbgView打印驱动中:分别通过3个函数获得的虚拟地址值如下:
MmMapLockedPagesSpecifyCache: 0xae44b3b0
MmGetSystemAddressForMdlSafe: 0xae44b3b0
MmGetMdlVirtualAddress: 0x7013b0
以上三个函数都可以完成需求。
代码下载:
时间: 2024-10-10 13:17:39