MapCallerPtr究竟动了什么?

问题:

LPVOID MapCallerPtr(LPVOID ptr,DWORD dwLen);MapCallerPtr一般用来对应用程序向驱动程序传递的参数做访问检查。我想问的如果应用程序有访问权限,那么ptr指针的值是否和MapCallerPtr函数的返回值相等?MapCallerPtr究竟为我们做了什么,难道只是做访问检查,有没有重新映射内存的动作,请教高手解答?首先我们先来看几段最简单的代码:
这是定义了的一个参数结构:
Code Snippet
typedef struct _DEV_Param
{
UNCHAR DeviceAddr;
UNCHAR nWriteByte;
UNCHAR *pWriteBuffer;
UNCHAR nReadByte;
UNCHAR *pReadBuffer;
} DEV_Param;
接下来这是驱动里面的响应DeviceIoControl的函数:
Code Snippet
BOOL DEV_IOControl( DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut )
{
....
DEV_Param *pDEV_Param = (DEV_Param *)pBufIn;
for(int i = 0; i < pDEV_Param->nWriteByte; i++)
{
RETAILMSG(TRUE,(TEXT("Write code is [%x]/n"),pDEV_Param->pWriteBuffer[i]));
}
...
}
再然后呢,我们在应用程序中调用该驱动:
....
Code Snippet
DEV_Param param = {0};
UNCHAR szBuf[20] = {0x10,0x20,0x30};
param.nWriteByte = 20;
param.pWriteBuffer = szBuf;
...
DeviceIoControl(hd,IOCTL_WRITE,&param,sizeof(param),NULL,NULL,NULL);
...
如果我说,
Code Snippet
RETAILMSG(TRUE,(TEXT("Write code is [%x]/n"),pDEV_Param->pWriteBuffer[i]))
这语句能否正确输出pWriteBuffer里面的数值,取决于应用程序的szBuf的定义:比方说,当szBuf为局部变量,就能正常输出;如果为static或全局变量,输出就不正常,你会不会觉得奇怪? 这是因为什么?

 

回答:

在Windows CE 5.0中,低2G的用户地址空间被分为64个Slot,其中0—32这33个Slot分配给不同的用户进程,而且Slot 0会映射给当前运行的进程,Slot 1专门映射给XIP的DLL。也就是说每一个用户进程执行时都被映射到Slot 0,所以不管哪一个用户进程,它里面的数据地址都位于0x00000000—0x0001FFFF这个地址空间。应用程序传给驱动程序缓冲区的地址也位于Slot 0的虚拟地址空间范围之内。当驱动程序运行时,如果再使用这个地址直接访问,那么访问的就不是应用程序实际的地址空间,而是当前运行的设备管理器的地址空间,所以需要将这个地址进行转换。在Windows CE 5.0中,Marshalling的过程相当简单,只是把指针做一个简单的偏移计算:
转换后的指针 = 转换前的指针 + 应用程序所在的Slot编号 * 32MB
这个转换后的地址就是MapCallerPtr返回指针。在Windows CE 5.0中,MapCallerPtr函数即负责访问权限的检查,也负责Marshalling操作。

 

我的理解:

感觉此回答没有讲到点子上,szBuf如果是局部变量那它是在进程的栈上动态分配,如果是全局或静态变量那它是在进程的堆上分配。前者是在进程运行的时候根据SP的值来决定,因SP地址是落在相应的slot的,所以szBuf地址也是正确的,后者是在编译的时候就决定了地址:编译器假设系统加载进程到虚拟地址0(前0x10000做为Guard Section,然后是进程的代码、数据、堆及线程的栈,从下面的图可清楚的看出)来生成szBuf的地址(位于data段的某处),这个地址落在slot0地址范围内,在本例子中是错误的。

wince5内存布局

 

附:实际例子(测试程序在slot7)
1、szBuf是局部变量
param应用程序中地址:0xE04F63C
szBuf应用程序中地址:0xE04F654

驱动能正常访问
2、szBuf是全局或静态变量
param同上
szBuf应用程序中地址:0x2A360,在驱动中此地址实际是device.exe的某个地址,正确地址应该是0x2A360+7*0x2000000=0xE02A360

From: http://social.microsoft.com/forums/zh-CN/windowsembeddedcezhchs/thread/8ae4facf-69fa-4e8f-adb3-e8493dd83543/

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值