精华内容
下载资源
问答
  • IOControl

    千次阅读 2012-03-14 21:43:00
    在Driver_Entry()关联了一个处理IRP_MJ_DEVICE_CONTROL类型IRP的MajorFunction,xxxControl用于处理上层与驱动通信的数据。上层应用程序可以通过DeviceIoContro()与驱动程序进行通信。  pDriverObject-&...

    在Driver_Entry()关联了一个处理IRP_MJ_DEVICE_CONTROL类型IRP的MajorFunction,xxxControl用于处理上层与驱动通信的数据。上层应用程序可以通过DeviceIoContro()与驱动程序进行通信。

     pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =xxxControl;

    xxxControl函数的框架可定义为:

    NTSTATUS xxxControl(PDEVICE_OBJECT fdo, PIRP pIrp)

    {                                                               

             PAGED_CODE();

             PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

     

     

             //得到当前堆栈

             PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);

             //得到输入缓冲区大小

             ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;

             //得到输出缓冲区大小

             ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;

             //得到IOCTL码

             ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;

     

             switch (code)

             {                                                      

             case IOCTL_MMAP_ADDR:

             …

             default:

     

             }

     

     

             return CompleteRequest(pIrp, status, info);

    }

     

    首先来说说下面这一行:

    ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;

    这一行获取IOCTL码。IOCTL码是通过DeviceIoControl()函数的第二个参数传输进来的。

    IOCTL是我们遵行一定的方式自定义的,通过CTL_CODE这个宏来定义。

    CTL_CODE的定义如下:

    #define CTL_CODE(DeviceType, Function, Method, Access) ( ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) )

    可通过下图的直观描述来进一步了解这个宏:

     

    举一个实例:

    #define   IOCTL_MMAP_ADDR   \

              CTL_CODE(FILE_DEVICE_UNKNOWN,0x806,METHOD_BUFFERED,FILE_ANY_ACCESS)

    第一个参数一般可设置为FILE_DEVICE_UNKNOWN,第二个参数的值须在2048-4095之间,0 – 2047由微软保留。第三个参数的功能意义是定义用于与在驱动程序中获取应用程序数据缓冲区的地址方式,一般可以设定为METHOD_BUFFERED 或者 METHOD_IN_DIRECT、METHOD_OUT_DIRECT。最后一个参数可以直接使用FILE_ANY_ACCESS。

     

    顺便就说说DeviceIoControl():

    函数定义为:

    BOOL DeviceIoControl

    (

     HANDLE                  hDevice,

     DWORD                   dwIoControlCode,

    LPVOID                  lpInBuffer,

    DWORD                  nInBufferSize,

     LPVOID                  lpOutBuffer,

    DWORD                  nOutBufferSize,

    LPDWORD              lpBytesReturned,

    LPOVERLAPPED    lpOverlapped

     );

    参数的含义为:

    hDevice :CreateFile返回的设备句柄

    dwIoControlCode :IO_CTL code

    lpInBuffer:应用程序传递给驱动程序的数据缓冲区地址

    nInBufferSize:应用程序传递给驱动程序的数据缓冲区大小,字节数

    lpOutBuffer:驱动程序返回给应用程序的数据缓冲区地址

    nOutBufferSize:驱动程序返回给应用程序的数据缓冲区大小,字节数

    lpBytesReturned:驱动程序实际返回给应用程序的数据字节数地址

    lpOverlapped: 一般设为NULL

     

     

    映射地址:

    send=*(int *)pIrp->AssociatedIrp.SystemBuffer;

                       //操作输出缓冲区

                       switch(send)

                       {

                       case 2:

                                OutputBuffer1=(PVOID *)pIrp->AssociatedIrp.SystemBuffer;//使OutputBuffer1与

    //SystemBuffer关联相同的地址

                                KdPrint(("\n Mmap address of send!\n"));

                                pdx->pMdlDesc=IoAllocateMdl(pdx->RxDescVirBase,DESC_ADDRESS*PORT_NUM,FALSE,FALSE,NULL);

                                if(!pdx->pMdlDesc)

                                {

                                         KdPrint(("\n Allocate DESCMDL failed!"));

                                }

                                MmBuildMdlForNonPagedPool(pdx->pMdlDesc);

                                pdx->pMdlDesc->MdlFlags |= MDL_PAGES_LOCKED;

                                pdx->UserDescAddress=MmMapLockedPages(pdx->pMdlDesc,UserMode);

                                *(PVOID *)OutputBuffer1=(PVOID)pdx->UserDescAddress;

    //注意这里是将映射出来的地址通过输出缓冲区传回上层去

                                KdPrint(("\n UserDescAddress is 0x%8x\n",pdx->UserDescAddress));

                                info=cbout;      

                                break;

     

    其中IoAllocateMdl()用来分配一个足够大的内存描述符列表来映射一块缓冲区地址。定义为:

    PMDL IoAllocateMdl(

      __in_opt     PVOID VirtualAddress,

      __in         ULONG Length,

      __in         BOOLEAN SecondaryBuffer,

      __in         BOOLEAN ChargeQuota,

      __inout_opt  PIRP Irp

    );

    用法如上面,一般后三个参数设为FALSE。

    之后需要调用MmBuildMdlForNonPagedPool()函数来处理刚刚分配的MDL,是这块MDL能够描述实际的物理地址。

    最后调用MmMapLockedPages()完成映射,该函数的返回值就是映射的虚拟地址首址。

    注意保存输出缓冲区的长度:info = cbout,用于设置IRP处理完成状态。

     

     

     

     

    展开全文
  • Opto 22 控制组态软件:ioControlzip,Opto 22 控制组态软件:ioControl
  • iocontrol软件包提供了io.Writer和io.Reader实现,可以实现对数据传输速率的测量和调节。 用法 const ( KiB = 1 << 10 MiB = 1 << 20 GiB = 1 << 30 ) 数据量级,以千字节为单位(2的幂或...
  • WINCE 流驱动的xx_IOControl

    千次阅读 2008-12-11 12:58:00
    前言 刚刚完成一个WINCE 下的I2C的流驱动,由于在读I2C 时要进行参数的传入和传出,所以其中的xx_IOControl必须要完成,像一些简单的传递单向数据的驱动,要xx_Read或xx_Write就可以实现. 之前没有写过xx_IOControl,...
     
     
     

    前言

           刚刚完成一个WINCE 下的I2C的流驱动,由于在读I2C 时要进行参数的传入和传出,所以其中的xx_IOControl必须要完成,像一些简单的传递单向数据的驱动,要xx_Read或xx_Write就可以实现.

           之前没有写过xx_IOControl,所以参考了网上的代码又结合自己的软硬件环境,我现有的BSP 里已经实现了I2C 读写的基本函数,所以只需要我驱动了作好初始化,并处理好读写I2C 之前的工作,正确的传入参数,正确的调用现有的i2c读写函数就可以了.

          说明下,我访问的I2C 从器件是eeprom :CAT24C04.功能只实现简单的读byte和写byte.

     

    准备工作:了解IOControl 的使用,这里引用下其他人的总结

    =========引用开始=================================

     原文地址: http://hi.baidu.com/magical/blog/item/3e6746103ea036f9c2ce79c0.html

    DeviceIoControl的使用说明
    2008-07-15 10:57

            应用程序和驱动程序的通信过程是:应用程序使用CreateFile函数打开设备,然后用DeviceIoControl与驱动程序进行通信,包括读和写两种操作。还可以用ReadFile读数据用WriteFile写数据。操作完毕时用CloseHandle关闭设备。我们比较常用的就是用DeviceIoControl对设备进行读写操作。先看看DeviceIoControl是怎么定义的:

    BOOL DeviceIoControl(
      HANDLE hDevice, 
      DWORD dwIoControlCode, 
      LPVOID lpInBuffer, 
      DWORD nInBufferSize, 
      LPVOID lpOutBuffer, 
      DWORD nOutBufferSize, 
      LPDWORD lpBytesReturned, 
      LPOVERLAPPED lpOverlapped
    );

    Parameters(参数)

    hDevice (CreateFile返回的设备句柄)
    [in] Handle to the device that is to perform the operation. To obtain a device handle, call the CreateFile function.
    dwIoControlCode (应用程序调用驱动程序的控制命令,就是IOCTL_XXX IOCTLs )
    [in] IOCTL for the operation. This value identifies the specific operation to perform and the type of device on which to perform the operation. There are no specific values defined for the dwIoControlCode parameter. However, you can define custom IOCTL_XXX IOCTLs with the CTL_CODE macro. You can then advertise these IOCTLs and an application can use these IOCTLs with DeviceIoControl to perform the driver-specific functions.
    lpInBuffer (应用程序传递给驱动程序的数据缓冲区地址)
    [in] Long pointer to a buffer that contains the data required to perform the operation. Set to NULL if the dwIoControlCode parameter specifies an operation that does not require input data.
    nInBufferSize (应用程序传递给驱动程序的数据缓冲区大小,字节数)
    [in] Size, in bytes, of the buffer pointed to by lpInBuffer.
    lpOutBuffer (驱动程序返回给应用程序的数据缓冲区地址)
    [out] Long pointer to a buffer that receives the output data for the operation. Set to NULL if the dwIoControlCode parameter specifies an operation that does not produce output data.
    nOutBufferSize (驱动程序返回给应用程序的数据缓冲区大小,字节数)
    [out] Size, in bytes, of the buffer pointed to by lpOutBuffer.
    lpBytesReturned (驱动程序实际返回给应用程序的数据字节数地址)
    [out] Long pointer to a variable that receives the size, in bytes, of the data stored in lpOutBuffer. The DeviceIoControl function may unnecessarily use this parameter. For example, if an operation does not produce data for lpOutBuffer and lpOutBuffer is NULL, the value of lpBytesReturned is meaningless.
    lpOverlapped (重叠操作结构)
    [in] Ignored; set to NULL.

    Return Values(返回值)

    Nonzero indicates success. Zero indicates failure. To obtain extended error information, call the GetLastError function. (非0成功,0失败)

    具体使用我们看看列子:

    1,向设备传递数据,我们定义一个函数来实现

    bool CDeviceOperDlg::SendKeyData(HANDLE handle, BYTE *bData, int iSize)
    {
    ULONG nOutput;
    BYTE bTemp[512];

    //将数据放置到发送数组
    memset(bTemp,0,sizeof(bTemp));
    memcpy(bTemp,&bData[0],iSize);
    //向设备发送
    if (!DeviceIoControl(handle,        
           ATST2004_IOCTL_WRITE,     //根据具体的设备有相关的定义
           bTemp,                                        //向设备传递的数据地址
           iSize,                                            //数据大小,字节数
           NULL,                                          //没有返回的数据,置为NULL
           0,                                                  //没有返回的数据,置为0

           &nOutput,
           NULL)
        )
    {
       return false;
    }

    return true;
    }

    2,从设备读取数据


    bool CDeviceOperDlg::ReviceKeyData(HANDLE handle, BYTE *bData, int iSize)
    {

    ULONG nOutput;
    BYTE bTemp[512];
    //数组清零
    memset(bTemp,0,sizeof(bTemp));
    //向设备发送
    if (!DeviceIoControl(handle,
           ATST2004_IOCTL_READ,           //根据具体的设备有相关的定义
           NULL,                                              //没有向设备传递的数据,置为NULL
           0,                                                      //没有向设备传递的数据,置为NULL
           bTemp,                                            //读取设备的数据返回地址
           iSize,                                                //读取数据的字节数
           &nOutput,
           NULL)
        )
    {
       return false;
    }
    //放置到公用数组
    memcpy(&bData[0],&bTemp[0],iSize);
    return true;
    }

    ==================引用结束===============================

    现在开始我的代码

    驱动代码实现:

     oemi2c_write与 oemi2c_read ,其中XllpI2CWrite和XllpI2CRead是BSP实现得代码.

    1. int  oemi2c_write(XLLP_UINT8_T slaveAddr, XLLP_UINT8_T * bytesBuf, int bytesCount)
    2. {
    3.     int status;
    4.     Lock();
    5.     status = XllpI2CWrite((P_XLLP_I2C_T)(m_I2CBase),(P_XLLP_OST_T)(m_OSTBase),slaveAddr,bytesBuf,bytesCount,1);
    6.     if (status != XLLP_STATUS_SUCCESS) {
    7.         RETAILMSG(1, (TEXT("I2C: XllpI2CWrite failed %d/r/n"), status));
    8.     }
    9.      UnLock();
    10.     return status;
    11. }
    12. int oemi2c_read(XLLP_UINT8_T slaveAddr, XLLP_UINT8_T subAddr,XLLP_UINT8_T * bytesBuf, int bytesCount)
    13. {
    14.     int  status;
    15.     Lock();
    16.     status = XllpI2CWrite((P_XLLP_I2C_T)(m_I2CBase), (P_XLLP_OST_T)(m_OSTBase),slaveAddr,&subAddr,1,1);
    17.     if (status != XLLP_STATUS_SUCCESS) {
    18.         RETAILMSG(1, (TEXT("I2C:1  XllpI2CWrite failed %d/r/n"), status));
    19.     }
    20.     status = XllpI2CRead((P_XLLP_I2C_T)(m_I2CBase), (P_XLLP_OST_T)(m_OSTBase),slaveAddr,bytesBuf,bytesCount,1);
    21.     if (status != XLLP_STATUS_SUCCESS) {
    22.         RETAILMSG(1, (TEXT("I2C:2  XllpI2CRead failed %d/r/n"), status));
    23.     }
    24.      UnLock();
    25.     return status;
    26. }

    IIC_IOControl函数

      1. typedef struct _I2C_IO_DESC  
      2.  DWORD SlaveAddr; // Target Slave Address 
      3.  DWORD WordAddr; // Starting Slave Word Address 
      4.  //LPBYTE  pData; // pBuffer 
      5.  XLLP_UINT8_T *pData; 
      6.  XLLP_UINT32_T Count; // nBytes to read/write 
      7. } I2C_IO_DESC, *PI2C_IO_DESC; 
      8. #define IOCTL_I2C_READ 1 
      9. #define IOCTL_I2C_WRITE 4 
      10. BOOL IIC_IOControl(DWORD hOpenContext,DWORD dwCode,PBYTE pBufIn,DWORD dwLenIn,PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut) 
      11.  DWORD dwErr = ERROR_SUCCESS; 
      12.      BOOL  bRc = TRUE; 
      13.  XLLP_UINT8_T *pval;//received data 
      14.  XLLP_UINT8_T Address,SlaveAddr,ActiveAdress; 
      15.  I2C_IO_DESC *pI2C_Desc; 
      16.  XLLP_STATUS_T status; 
      17.  XLLP_UINT8_T WRbuf[2]; 
      18.      RETAILMSG(ZONE_IIC,(TEXT(">IIC -IOControl(0x%x,0x%x, 0x%x, %d, 0x%x)/n"), 
      19.         dwCode, pBufIn, dwLenIn, pBufOut, dwLenOut )); 
      20.     if ( !m_I2CBase || !g_OpenCount )  
      21.   { 
      22.            RETAILMSG (1, (TEXT("IIC-IOControl: ERROR_INVALID_HANDLE/r/n"))); 
      23.           SetLastError (ERROR_INVALID_HANDLE); 
      24.           return(FALSE); 
      25.       } 
      26.      if (pdwActualOut) 
      27.          *pdwActualOut = 0; 
      28.      //--------------------------------------------  
      29.      switch (dwCode)  
      30.   { 
      31.     case IOCTL_I2C_READ: 
      32.               if ( (dwLenIn < sizeof(I2C_IO_DESC)) || !pBufIn || !((PI2C_IO_DESC)pBufIn)->pData )  
      33.     { 
      34.                    dwErr = ERROR_INVALID_PARAMETER; 
      35.                    bRc = FALSE; 
      36.      RETAILMSG (1, (TEXT("1:IOCTL_I2C_READ: ERROR_INVALID_PARAMETER/r/n"))); 
      37.                   break
      38.                } 
      39.    pI2C_Desc=(PI2C_IO_DESC)MapPtrToProcess(pBufIn,(HANDLE) GetCurrentProcess()); //得到传入参数 
      40.    if (pBufIn != NULL && pI2C_Desc == NULL)  
      41.     { 
      42.      // Security violation 
      43.      RETAILMSG(1, (TEXT("I2CRead>Failed to map pointer to caller/r/n"))); 
      44.                   dwErr = ERROR_INVALID_PARAMETER; 
      45.      RETAILMSG (1, (TEXT("2:IOCTL_I2C_READ: ERROR_INVALID_PARAMETER/r/n"))); 
      46.                    bRc = FALSE; 
      47.                    break
      48.     }  
      49.    pval=(XLLP_UINT8_T *)MapPtrToProcess(pI2C_Desc->pData,(HANDLE) GetCurrentProcess()); 
      50.    if (pI2C_Desc->pData != NULL && pval == NULL)  
      51.     { 
      52.      // Security violation 
      53.      RETAILMSG(1, (TEXT("I2CRead>Failed to map pointer to caller/r/n"))); 
      54.                    dwErr = ERROR_INVALID_PARAMETER; 
      55.      RETAILMSG (1, (TEXT("3:IOCTL_I2C_READ: ERROR_INVALID_PARAMETER/r/n"))); 
      56.                   bRc = FALSE; 
      57.                   break
      58.     } 
      59.               Address =(XLLP_UINT8_T)(pI2C_Desc->WordAddr); 
      60.    ActiveAdress = (Address & 0xFF); 
      61.    SlaveAddr = (XLLP_UINT8_T)(pI2C_Desc->SlaveAddr);// | (((dwAddress/255)&0x07)<<1)); 
      62.     WRbuf[0]=*pval; 
      63.    status=oemi2c_read(SlaveAddr,ActiveAdress,WRbuf,1);//read one byte 
      64.    *pBufOut=WRbuf[0];//输出的数据 
      65.    *pdwActualOut=1;//READ ONE BYTE 
      66.    if(status!=XLLP_STATUS_SUCCESS) 
      67.     { 
      68.      bRc = FALSE; 
      69.      RETAILMSG (1, (TEXT("4 IOCTL_I2C_READ error: /r/n"))); 
      70.      break
      71.     } 
      72.               UnMapPtr(pval); 
      73.               UnMapPtr(pI2C_Desc);    
      74.    break
      75.     
      76.   case IOCTL_I2C_WRITE: 
      77.    if ( (dwLenIn < sizeof(I2C_IO_DESC)) || !pBufIn || !((PI2C_IO_DESC)pBufIn)->pData)  
      78.     { 
      79.                    dwErr = ERROR_INVALID_PARAMETER; 
      80.      RETAILMSG (1, (TEXT("1 IOCTL_I2C_WRITE ERROR_INVALID_PARAMETER/r/n"))); 
      81.                    bRc = FALSE; 
      82.                    break
      83.                } 
      84.    pI2C_Desc=(PI2C_IO_DESC)MapPtrToProcess(pBufIn,(HANDLE) GetCurrentProcess()); 
      85.    if (pBufIn != NULL && pI2C_Desc == NULL)  
      86.     { 
      87.      // Security violation 
      88.      RETAILMSG(1, (TEXT("I2CRead>Failed to map pointer to caller/r/n"))); 
      89.                   dwErr = ERROR_INVALID_PARAMETER; 
      90.                    bRc = FALSE; 
      91.      RETAILMSG (1, (TEXT("2 IOCTL_I2C_WRITE ERROR_INVALID_PARAMETER/r/n"))); 
      92.                    break
      93.     }  
      94.    pval=(XLLP_UINT8_T *)MapPtrToProcess(pI2C_Desc->pData,(HANDLE) GetCurrentProcess()); 
      95.    if (pI2C_Desc->pData != NULL && pval == NULL)  
      96.     { 
      97.      // Security violation 
      98.      RETAILMSG(1, (TEXT("I2CRead>Failed to map pointer to caller/r/n"))); 
      99.                    dwErr = ERROR_INVALID_PARAMETER; 
      100.                   bRc = FALSE; 
      101.      RETAILMSG (1, (TEXT("3 IOCTL_I2C_WRITE ERROR_INVALID_PARAMETER/r/n"))); 
      102.                   break
      103.     } 
      104.    Address = (XLLP_UINT8_T)(pI2C_Desc->WordAddr); 
      105.    ActiveAdress = (Address & 0xFF); 
      106.    SlaveAddr = (XLLP_UINT8_T)(pI2C_Desc->SlaveAddr );//| (((dwAddress/255)&0x07)<<1)); 
      107.    //begain I2C 
      108.    WRbuf[0] = ActiveAdress; 
      109.    WRbuf[1] = *pval; 
      110.     status=oemi2c_write(SlaveAddr,WRbuf,2);//write one byte 
      111.     *pdwActualOut =1; 
      112.    if(status!= XLLP_STATUS_SUCCESS) 
      113.     { bRc = FALSE; 
      114.      RETAILMSG (1, (TEXT("4 IOCTL_I2C_WRITE ERror/r/n"))); 
      115.      break
      116.     } 
      117.    UnMapPtr(pval); 
      118.               UnMapPtr(pI2C_Desc);    
      119.    break
      120.   default
      121.    bRc  = FALSE; 
      122.               dwErr = ERROR_INVALID_FUNCTION; 
      123.               RETAILMSG (1, (TEXT("I2C_IOControl Unknown Ioctl: 0x%X/r/n"), dwCode)); 
      124.    break
      125.       } 
      126.  //------------------------------------- 
      127.  if ( !bRc ) 
      128.  { 
      129.          RETAILMSG (1, (TEXT("I2C_IOControl ERROR: %u/r/n"), dwErr)); 
      130.          SetLastError(dwErr); 
      131.      } 
      132.      RETAILMSG(ZONE_IIC,(TEXT("<I2C_IOControl:%d/n"), bRc)); 
      133.  return bRc;; 
      134. }

    ========================================================

    EVC 应用程序代码:

    typedef struct _I2C_IO_DESC
    {
     DWORD SlaveAddr; // Target Slave Address
     DWORD WordAddr; // Starting Slave Word Address
     //LPBYTE  pData; // pBuffer
     unsigned char *pData;
     unsigned long Count; // nBytes to read/write
    } I2C_IO_DESC, *PI2C_IO_DESC;

     

    #define IOCTL_I2C_READ 1
    #define IOCTL_I2C_WRITE 4
    #define CAT24C04Addr (0x0a0>>1)

         DWORD RetBytes;
        I2C_IO_DESC   DataFamily;

    1. // Cpage_i2c message handlers
    2. BOOL Cpage_i2c::OnInitDialog() 
    3. {
    4.  CPropertyPage::OnInitDialog();
    5.  // TODO: Add extra initialization here
    6.  m_hIIC=CreateFile(TEXT("IIC1:"),GENERIC_READ|GENERIC_WRITE,NULL,NULL,OPEN_EXISTING,NULL,NULL);
    7.  if(m_hIIC==INVALID_HANDLE_VALUE)
    8.  {
    9.   AfxMessageBox(_T("I2C CreateFile failed!!"));
    10.   return 0;
    11.  }
    12.  return TRUE;  // return TRUE unless you set the focus to a control
    13.                // EXCEPTION: OCX Property Pages should return FALSE
    14. }
    15. //----write byte button--------------
    16. void Cpage_i2c::OnBUTTONi2cWB() 
    17. {
    18.  // TODO: Add your control notification handler code here
    19. // AfxMessageBox(_T("I2C OnBUTTON i2c WB!!"));
    20.  DWORD Ret;
    21.  UpdateData(true);
    22.  pBuffOut[0]=(unsigned char)m_i2cWrData;
    23.  DataFamily.SlaveAddr=CAT24C04Addr;
    24.  DataFamily.WordAddr=(unsigned char)m_i2cWrAddr;
    25.  DataFamily.pData=pBuffOut;
    26.  DataFamily.Count=1;  
    27.     Ret=DeviceIoControl(m_hIIC,IOCTL_I2C_WRITE,&DataFamily,sizeof(DataFamily),NULL,0,&RetBytes,NULL);  //
    28.  if(!Ret)
       {
        AfxMessageBox(_T("I2C communication error!!"));
        return;
       }
    29. }
    30. //----read byte button--------------
    31. void Cpage_i2c::OnBUTTONi2cRB() 
    32. {
    33.  // TODO: Add your control notification handler code here
    34.  // AfxMessageBox(_T("I2C OnBUTTON i2c RB!!"));
    35.  BYTE  poutBuff[2]={0,0};
    36.  DWORD Ret;
    37.  UpdateData(true);
    38.  DataFamily.SlaveAddr=CAT24C04Addr;
    39.  DataFamily.WordAddr=(unsigned char)m_i2cRdAddr;
    40.  DataFamily.pData=pBuffin;
    41.  DataFamily.Count=1;  
    42.     Ret=DeviceIoControl(m_hIIC,IOCTL_I2C_READ,&DataFamily,sizeof(DataFamily),poutBuff,1,&RetBytes,NULL);  //
    43.  if(!Ret)
       {
        AfxMessageBox(_T("I2C communication error!!"));
        return;
       }
    44.  m_i2cRdData=poutBuff[0]; //收到得数据
    45.  UpdateData(FALSE); 
    46. }

    运行界面:

        

    展开全文
  • Atmega64的io口程序,实现控制小灯亮灭功能
  • Windows Mobile驱动中安全的处理IoControl

    千次阅读 2007-11-08 20:16:00
    我们有时并不希望驱动中的iocontrol可以被任意应用程序调用,因此可以在Iocontrol中加一些签证的验证来确保能call进来的程序都是“自己人”。下面是一段例子: if (CeGetCallerTrust() != OEM_CERTIFY_TRUST) { ...
    我们有时并不希望驱动中的iocontrol可以被任意应用程序调用,因此可以在Iocontrol中加一些签证的验证来确保能call进来的程序都是“自己人”。 下面是一段例子: 
            if (CeGetCallerTrust() != OEM_CERTIFY_TRUST)
    
            {
                RETAILMSG(ZONE_ERROR, (L"ERROR: : "
                                      L"Caller is untrused/r/n"
                                     ));
                SetLastError(ERROR_ACCESS_DENIED);
                break;
            }

            if (!CeSafeCopyMemory(&dx, pBufIn, sizeof(dx)))
            {
                SetLastError(ERROR_INVALID_PARAMETER);
                break;
            } 同时用CeSafeCopyMemory来处理传入的指针。
    展开全文
  • 上一章大概介绍了WDM/WDF的驱动模型, ... 这一章我们主要来看一下驱动程序中的IO请求是如何处理的。 其实驱动程序的主要功能也就是负责处理IO请求,其中大部分IO请求是在派遣函数中处理的。用户模式下的所有对驱动...

    上一章大概介绍了WDM/WDF的驱动模型,

    链接:https://blog.csdn.net/o0xwh_93150o/article/details/104213348

    这一章我们主要来看一下驱动程序中的IO请求是如何处理的。

    其实驱动程序的主要功能也就是负责处理IO请求,其中大部分IO请求是在派遣函数中处理的。用户模式下的所有对驱动程序的IO请求,全部由操作系统转化为一个叫做IRP(IO request package)的数据结构,不同的IRP会被“派遣”到不同的派遣函数(dispatch function)中。IRP的处理机制类似windows应用程序中的“消息处理”机制,驱动程序接收到不同类型的IRP后,会进入不同的派遣函数。

    首先,IRP拥有两个基本的属性,一个是MajorFunction,另一个则是MinorFunction,分别记录IRP的主类型和子类型。操作系统根据MajorFunction将IRP派遣到不同的派遣函数中,然后再判断这个IRP属于哪种MinorFunction。如下所示:

    //创建设备,CreateFile时触发

    DriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDispatchCreate;

    //关闭设备,CloseHandle时触发

    DriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDispatchClose;

    //对设备进行WriteFile时触发

    DriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDispatchWrite;

    //对设备进行ReadFile时触发

    DriverObject->MajorFunction[IRP_MJ_READ] = HelloDispatchRead;

    当然,IRP的类型远不止这四种,对于其他没有设置的IRP类型,系统会默认将这些IRP类型与IoInvalidDeviceRequest函数关联。大部分的IRP都源于文件IO处理Win32 API,例如CreateFile与ReadFile。假如我们对这个类型的IRP不需要特别处理的话,只需要在派遣函数中直接返回success就可以了。如下:

    NTSTATUS status = STATUS_SUCCESS;

    //设置irp的完成状态

    pIrp->IoStatus.Status = status;

    //设置irp操作的实际字节数

    pIrp->IoStatus.Infomation = 0;

    //结束irp请求时需调用IoCompleteRequest

    IoCompleteRequest(pIrp, IO_NO_INCREMENT);

    return status;

    在驱动程序设置完这些IRP之后,是不是就可以使用用户应用程序向该驱动发送IO请求了呢?其实并不是如此,我们都知道,在用户态假如要操作这个设备,CreateFile时必要的一个参数,就是设备句柄,但是在用户态,其实是看不到内核态设备的句柄的,例如该设备的句柄为“\\Devices\\HelloDevice0”,这个句柄仅能被内核模式下的其他驱动所看见,所以我们需要创建一个符号链接,让用户态的程序可以得到这个句柄,类似“\\DosDevices\\HelloDevice0_LINK”这样。如下实例:

    #define MYWDF_KDEVICE L“\\Devices\\HelloDevice0”

    #define MYWDF_LINKNAME L“\\DosDevices\\HelloDevice0_LINK”

            // 创建设备

            WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&object_attribs, DEVICE_CONTEXT_CTRL);

    //为设备首先分配内存

    device_init = WdfControlDeviceInitAllocate(WdfDeviceGetDriver(Device), &SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RW_RES_R);

    RtlInitUnicodeString(&ustring, MYWDF_KDEVICE);

    //将设备名字存入device_init中

    status = WdfDeviceInitAssignName(device_init, &ustring);

            if (!NT_SUCCESS(status)) {

                 //

            }

    //创建一个controldevice,用于创建符号链接

            status = WdfDeviceCreate(&device_init, &object_attribs, &control_device);

            if (!NT_SUCCESS(status)) {

    //

            }

            RtlInitUnicodeString(&ustring, MYWDF_LINKNAME);

    //创建符号链接

            status = WdfDeviceCreateSymbolicLink(control_device, &ustring);

            if (!NT_SUCCESS(status)) {

       //

            }

    这样,你的设备就可以被用户态的程序所使用了,接下来,再在用户态使用CreateFIle打开这个符号链接就可以了。驱动程序中我们已经设置好了Write和Read的派遣函数,只要使用WriteFile和ReadFile,就可以触发这两个IRP回调函数了,这个就不再举例子了。

    当然,有时候应用程序并不需要真的向这个设备进行读和写操作,它可能仅仅需要“告知”驱动程序,我想要做什么,驱动程序可以在自己的会话空间里就足够处理,这时,微软为我们准备了另一个Win32 API:DeviceIoControl。这个API会在内部使操作系统创建一个IRP_DEVICE_CONTROL类型的IRP,你只需要在驱动中设置这个类型IRP的回调函数就可以了。

    DeviceIoControl的函数原型如下:

    BOOL WINAPI DeviceIoControl(

    _In_ HANDLE hDevice,

    _In_ DWORD dwIoControlCode,

    _In_opt_ LPVOID lpInBuffer,

    _In_ DWORD nInBufferSize,

    _Out_opt_ LPVOID lpOutBuffer,

      _In_ DWORD nOutBufferSize,

    _Out_opt_ LPDWORD lpBytesReturned,

    _Inout_opt_ LPOVERLAPPED lpOverlapped);

    其中第二个参数dwIoControlCode,就是IO控制码,即IOCTL值,用来告诉驱动程序,我需要进行哪种类型的交互,当然,前提是这个IOCTL值是驱动程序预先设置好已知的,我们可以用CTL_CODE这个宏来定义一组IOCTL值。CTL_CODE的定义为(DeviceType,Function,Method,Access),DeviceType为设备对象的类型,这个类型应该与创建设备(IoCreateDevice)时的类型匹配,如FILE_DEVICE_XX这样的宏;Function为驱动程序定义的IOCTL宏,0x0000-0x7FFFF为微软保留,0x800-0xFFF为程序员自定义;Method为操作模式,应使用如下四种之一,METHOD_BUFFERED(使用缓冲区操作),METHOD_IN_DIRECT(使用直写操作),METHOD_OUT_DIRECT(使用直写操作),METHOD_NEITHER(使用其他方式操作);Access为访问权限,如果没有特殊要求,一般使用FILE_ANY_ACCESS。如下是一个实例:

    #define IOCTL_HELLO CTL_CODE(\

     FILE_DEVICE_UNKNOWN, \

     0x999, \

     METHOD_BUFFERED, \

       FILE_ANY_ACCESS)

    这里说一下关于METHOD_BUFFERED,使用缓冲内存模式的IOCTL,要避免在驱动中直接访问用户模式下的内存地址。在这种模式下,DeviceIoControl的大致流程是这样的,定义CTL_CODE宏->得到当前堆栈(IoGetCurrentIrpStackLocation)->得到输入缓冲区大小(DeviceIoControl.InputBufferLength)->得到输出缓冲区大小(DeviceIoControl.OutputBufferLength)->得到IOCTL码(DeviceIoControl.IoControlCode)->switch处理该IOCTL->设置IRP状态->结束IRP请求(IoCompleteRequest)。

    关于驱动程序的IO请求就说到这里,下一章的话,我们就直接进入实战篇吧~拿一个WDF的总线驱动来分析一下。

    展开全文
  • UDP的IOControl(低级操作模式)

    千次阅读 2016-12-28 13:23:43
    private IPEndPoint LocaIPEP; //udp 本地节点 private IPEndPoint RemoteIPEP;... MyClient.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null); MyClient.Bind(local); }
  • NTSTATUS MakeDeviceControl(PDEVICE_OBJECT DeviceObject, ULONG IoctlCode, PVOID InputBuffer, ULONG InputBufferSize, PVOID OutputBuffer, ULONG OutputBufferSize) { PIRP...
  • 在6410SPI的驱动中函数SPI_IOControl有以下几个参数: BOOL SPI_IOControl( DWORD dwInst, DWORD dwIoControlCode, PBYTE lpInBuf, DWORD nInBufSize, PBYTE lpOutBuf, DWORD ...
  • 最近在写一个在Linux上运行的.netcore的网络底层库,踩到....net core有两个api可以设定socket的KeepAlive:IOControl和SetSocketOption。 IOControl public int IOControl (System.Net.Sockets.IOControlCode ioCon...
  • windows 驱动 应用层与驱动层通信(读、写文件) 源码,WDF、WDM IOCONTROL
  • 在驱动程序里面有个xxx_iocontrol()函数(xxx为驱动的名字),这个函数主要是对IO口的控制,你要对IO口实现怎样的控制都可以在这里编写。比如:BOOL LED_IOControl(DWORD hOpenContext, //XXX_Open返回给上层的那个...
  • pci9054I/O模式驱动

    2010-03-23 22:31:37
    pci9054的驱动程序,I/O方式,通过iocontrol函数访问9054的i/o口
  • DeviceIoControl对应npf.sys中的NPF_IoControl函数;   NTSTATUS NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) {  POPEN_INSTANCE Open;  PIO_STACK_LOCATION IrpSp;  PLIST_ENTRY
  • IIC驱动

    千次阅读 2010-07-02 16:14:00
    WINCE 流驱动的xx_IOControl 收藏  前言  刚刚完成一个WINCE 下的I2C的流驱动,由于在读I2C 时要进行参数的传入和传出,所以其中的xx_IOControl必须要完成,像一些简单的传递单向数据的驱动,要xx_Read或...
  • 用c# 实现的简单的嗅探工具 vs2008下编写 内有代码 另外在用无线网卡的时候会出现错误 socket.IOControl() 报错 error 10022 谁知道什么原因欢迎联系 E_mail:ailnindex@gmail.com
  • 上一章大概介绍了WDM/WDF的IOControl, 链接:https://blog.csdn.net/o0xwh_93150o/article/details/104234021 鸽太久了,刚好闲下来,就把这个实例入门篇给补了吧。话不多说,先上代码。 DriverEntry例程: ...
  • OV9650流接口驱动程序的设计部分,主要论述CIS_IOControl()、Cam_Init()等流接口函数的编写。在EVC开发环境中,基于MFC编程完成了系统应用软件开发,主要用Creatfile()函数打开驱动程序,调用DeviceIoControl...
  • uint IOC_IN = 0x80000000; uint IOC_VENDOR = 0x18000000; uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;...UdpClient.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);  
  • SharpSniffer--C#版Sniffer

    2019-10-08 19:22:55
    虽然网上已经有了SharpSniffer这一个SharpSniffer...1、创建套接字2、绑定到本机3、设置IOControl4、接收数据5、处理(显示)数据 关键代码 创建socket ,据MSDN,IOControlCode.ReceiveAll(后面要使用到)使用...
  • openni2 源码中的通过deviceIoControl将命令发到驱动程序,按照常理,IpOutBuffer是从驱动中读取返回的数据,但是openni2 将这个参数 往设备发送数据。... PSDrv_DbgPrint(3, ("IOControl: ControlTransfer\n"));
  • 第六章 iotcl

    2019-09-23 17:33:19
    第三章介绍了一个简单的字符设备驱动程序,它是一块内存当做设备...ioctl函数,从函数名来看的话,iocontrol,看上去是用来操作IO的。更通俗的讲,对于硬件控制的代码应该置于此处。对于当前的scull来说,最常用的对...
  • 本文分析从应用程序启动到开始预览整个过程中,驱动代码的执行流程。开发环境是WinCE6.0+Android6410开发板。 ...二、通过CAM_IOControl接口操作各种属性,下面的步骤中也会不断调用该接口,此...
  • 近日为了解决telechips的wince平台下百度carlife语音识别时,出现wavedev.dll报错的问题。花了两天的时间来阅读wavedev的驱动源码。...1、waveOutOpen,waveOutWrite--->WAV_IOControl(IOCTL_WAV_MESSAG
  • 学习WinCE6.0下面的Camera也一段时间了,准备做些记录结束了。由于Camera驱动中有太多的数据结构、层次结构,而且...应用层操作Camera设备的接口主要就是IOCONTROL,今天先来看看Camera和Pin的各种IO控制码。 本人...
  • 今天下午只是大概了解了一下,流程中的一些地方看不到代码, 所以这些看不到代码的地方只能猜想WINCE的行为了. ... 这是由UfnPdd_IOControl调用的, 这和WINCE HELP里的要求一致. 而根据WINCE HELP, 设备应该有D0~D4五...
  • 应用程序如何调用驱动程序

    千次阅读 2010-12-03 15:29:00
     在驱动程序里面有个xxx_iocontrol()函数(xxx为驱动的名字),这个函数主要是对IO口的控制, 你要对IO口实现怎样的控制都可以在这里编写。比如: BOOL LED_IOControl(DWORD hOpenContext, //XXX_...
  • ioctl是iocontrol的缩写,就是IO控制。 行为上: 简单来说,如果你在写驱动程序时zhi候,碰到一些IO操作,在逻辑上不能归类到read,不能归类到write,那就可以认为是ioctl的部分。read和write应该是写入和读出数据的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,264
精华内容 905
关键字:

IOcontrol