应用程序调用流驱动程序的变量地址转换

应用程序调用流驱动程序的变量地址转换

  因为每个应用程序都会占用一个Slot,所以他们的全局变量的地址不会发生冲突。

  例如:一个应用程序(PJ1.exe)被加载到Slot8的位置即地址范围为:0x10000000-0x11ffffff,该程序的CODE段与DATA段等都加载到该位置。程序定义一个全局变量时存储地址也在该范围内。若定义一个全局数组UCHAR Buff[100];假设该数组存储的地址范围为0x10010000-0x10010063。

  不同的进程被加载到不同的Slot,设备驱动程序device.exe也被加载到一个Slot3,地址范围为0x06000000-0x07ffffff。所以被设备驱动程序加载的流驱动(通常为DLL文件)也被加载到该地址范围。

  因为CE将当前正在运行的程序都映射为Slot0,所以应用程序运行时的地址范围为0x00000000-0x01ffffff。则Buff数组存储的地址范围为0x00010000-0x00010063。所以应用程序在运行时变量地址读取和写入都是在Slot的范围内。同理,device.exe其运行地址也为0x00000000-0x01ffffff。

  下面说一下当应用程序通过文件系统流驱动接口访问device.exe的接口时怎样传递数据。程序只是说明变量地址的变换,语法可能不正确。

 

  // 应用程序

  void fun (void)

  {

      UCHAR Buff[100];  // 加载地址0x10010000-0x10010063,运行地址0x00010000-0x00010063

 

      DeviceIoControl(L"IIC0",...,Buff,...);  // Buff为保存从驱动程序返回的数据,传递地址为运行地址0x00010000。

      ...

  }

 

  // 驱动程序

  BOOL IIC_IoControl (...,PUCHAR pUCHAR,...)  // 经过操作系统处理后,pUCHAR指针存储的地址为应用程序Buff加载地址即0x10010000。

  {

      UCHAR iic_rece[100];  // 加载地址0x06010000-0x06010063,运行地址0x00010000-0x00010063

 

      ...

      memcpy(pUCHAR,iic_rece,100);  // 所以驱动程序可以改变应用程序中变量的值。

      ...

  }

 

  也就是说,当应用程序传递给驱动程序为指针时,系统会自动转换应用程序变量的地址。而当应用程序传递给驱动程序为指向指针的变量时,驱动程序必须自己转换得到的地址到应用程序加载地址空间。

  举例:

  type struct REDATA {

      PUCHAR pbuff;

  } ReData;  

  // 应用程序

  void fun (void)

  {

      UCHAR Buff[100];  // 加载地址0x10010000-0x10010063,运行地址0x00010000-0x00010063

      ReData ReStruct;  // ReStruct加载地址0x0x10020000,运行地址0x00020000

     

      ReData.pbuff = Buff;  // pbuff存储的地址为0x00010000

      DeviceIoControl(L"IIC0",...,&ReStruct,...);  // ReStruct为保存从驱动程序返回的数据,传递地址为运行地址0x00020000。

      ...

  }

 

  // 驱动程序

  BOOL IIC_IoControl (...,ReData *pStruct,...)  // 经过操作系统处理后,pStruct指针存储的地址为应用程序ReStruct加载地址即0x0x10020000。

  {

      UCHAR iic_rece[100];  // 加载地址0x06010000-0x06010063,运行地址0x00010000-0x00010063

      ...

      memcpy(pStruct->pbuff,iic_rece,100);  // 程序出错,因为pStruct->pbuff存储的地址为应用程序Buff的运行地址0x00010000,所以改变的是驱动程序的地址。

 

      // 这时驱动程序可以调用MapPtrToProcess函数将pStruct->pbuff的地址修改为应用程序变量Buff的加载地址。

      pStruct->pbuff = MapPtrToProcess(pStruct->pbuff,GetCallerProcess());

      // 这是pStruct->pbuff存储的地址为应用程序Buff的加载地址0x10010000,可以执行memcpy函数。

      ...

  }

你可能感兴趣的:(Windows,CE)