在驱动层直接使用应用层的空间

需求:应用层申请一个空间,然后将地址传递到驱动层,驱动直接将处理后的数据放到应用层指定的空间中,类似于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: 0xae44b3b0
MmGetSystemAddressForMdlSafe: 0xae44b3b0
MmGetMdlVirtualAddress: 0x7013b0

以上三个函数都可以完成需求。

源代码下载:http://download.csdn.net/detail/xiaowen_10/8347813



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值