iniwf

风是温柔的,雨是伤心的,云是快乐的,月是多情的,爱是迷失的,恋是醉人的,情是难忘的,天是长久的,地是永恒的

驱动开发之五 --- TDI之五 【译文】

转自http://hi.baidu.com/combojiang/blog/item/854e66314a51adad5edf0ec6.html

步骤5:发送和接收数据

为了发送数据,你只需创建一个TDI_SEND IOCTL,然后把它传送给传输设备。下面的代码实现了数据发送。

NTSTATUS TdiFuncs_Send(PFILE_OBJECT pfoConnection, PVOID pData, 

                                UINT uiSendLength, UINT 
*pDataSent) 



    NTSTATUS NtStatus 
= STATUS_INSUFFICIENT_RESOURCES; 

    PIRP pIrp; 

    IO_STATUS_BLOCK IoStatusBlock 
= {0}

    PDEVICE_OBJECT pTdiDevice; 

    PMDL pSendMdl; 

    TDI_COMPLETION_CONTEXT TdiCompletionContext; 


    KeInitializeEvent(
&TdiCompletionContext.kCompleteEvent, 

                                             NotificationEvent, FALSE); 


    
/* 

     * The TDI Device Object is required to 

     *               send these requests to the TDI Driver. 

     
*/
 


    pTdiDevice 
= IoGetRelatedDeviceObject(pfoConnection); 


    
*pDataSent = 0


    
/* 

     * The send requires an MDL which is what you may remember from DIRECT_IO.   

     * However, instead of using an MDL we need to create one. 

     
*/
 

    pSendMdl 
= IoAllocateMdl((PCHAR )pData, uiSendLength, FALSE, FALSE, NULL); 


    
if(pSendMdl) 

    



        __try 



            MmProbeAndLockPages(pSendMdl, KernelMode, IoModifyAccess); 


        }
 __except (EXCEPTION_EXECUTE_HANDLER) 

                IoFreeMdl(pSendMdl); 

                pSendMdl 
= NULL; 

        }



        
if(pSendMdl) 

        


     

            
/* 

             * Step 1: Build the IRP. TDI defines several macros and functions 

             *         that can quickly create IRP's, etc. for variuos purposes.   

             *         While this can be done manually it's easiest to use 

             *         the macros. 

             
*/
 

            pIrp 
= TdiBuildInternalDeviceControlIrp(TDI_SEND, 

                     pTdiDevice, pfoConnection, 

                     
&TdiCompletionContext.kCompleteEvent, 

                     
&IoStatusBlock); 

         

            
if(pIrp) 

            


                
/* 

                 * Step 2: Add the correct parameters into the IRP. 

                 
*/
 

         

          

                TdiBuildSend(pIrp, pTdiDevice, pfoConnection, NULL, 

                                       NULL, pSendMdl, 
0, uiSendLength); 

         

                NtStatus 
= IoCallDriver(pTdiDevice, pIrp); 

         

                
/* 

                 * If the status returned is STATUS_PENDING this means that the 

                 * IRP will not be completed synchronously and the driver has 

                 * queued the IRP for later processing. This is fine but we do 

                 * not want to return this not want to return this not want to 

                 * return this to wait until it has completed. The EVENT 

                 * that we providedwill be set when the IRP completes. 

                 
*/
 

         

                
if(NtStatus == STATUS_PENDING) 

                


                    KeWaitForSingleObject(
&TdiCompletionContext.kCompleteEvent, 

                                           Executive, KernelMode, FALSE, NULL); 

         

                }
 


                NtStatus   
= IoStatusBlock.Status; 

                
*pDataSent = (UINT)IoStatusBlock.Information; 

     

               
/* 

                * I/O Manager will free the MDL 

                * 

                if(pSendMdl) 

                { 

                    MmUnlockPages(pSendMdl); 

                    IoFreeMdl(pSendMdl); 

                } 
*/
 


            }
 

        }
 

    }
 


    
return NtStatus; 

}
 

posted on 2009-03-23 22:07 iniwf 阅读(268) 评论(0)  编辑 收藏 引用 所属分类: 驱动


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

统计

常用链接

留言簿(2)

随笔分类

随笔档案

收藏夹

IT技术

积分与排名

最新评论

阅读排行榜

评论排行榜