需求:应用层申请一个空间,然后将地址传递到驱动层,驱动直接将处理后的数据放到应用层指定的空间中,类似于Linux下的copy_from_user。
应用层代码片段:将申请的地址传递到驱动层
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: 0xae44b3b0MmGetSystemAddressForMdlSafe: 0xae44b3b0
MmGetMdlVirtualAddress: 0x7013b0
以上三个函数都可以完成需求。
源代码下载:http://download.csdn.net/detail/xiaowen_10/8347813