iniwf

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

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

转自http://hi.baidu.com/combojiang/blog/item/109febad25deef0c4b36d6c7.html
.
步骤6:断开连接


这里没有特别的,就是实现TDI_DISCONNECT IOCTL来断开连接。

NTSTATUS TdiFuncs_Disconnect(PFILE_OBJECT pfoConnection) 



    NTSTATUS NtStatus 
= STATUS_INSUFFICIENT_RESOURCES; 

    PIRP pIrp; 

    IO_STATUS_BLOCK IoStatusBlock 
= {0}

    PDEVICE_OBJECT pTdiDevice; 

    TDI_CONNECTION_INFORMATION ReturnConnectionInfo 
= {0}

    LARGE_INTEGER TimeOut 
= {0}

    UINT NumberOfSeconds 
= 60*3

    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); 

     

    
/* 

     * 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_DISCONNECT, pTdiDevice, 

                  pfoConnection, 
&TdiCompletionContext.kCompleteEvent, 

                  
&IoStatusBlock); 


    
if(pIrp) 

    


        
/* 

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

         
*/
 


        
/* 

         * Time out value 

         
*/
 


        TimeOut.QuadPart 
= 10000000L

        TimeOut.QuadPart 
*= NumberOfSeconds; 

        TimeOut.QuadPart 
= -(TimeOut.QuadPart); 



        TdiBuildDisconnect(pIrp, pTdiDevice, pfoConnection, NULL, NULL, 

                            
&TimeOut, TDI_DISCONNECT_ABORT, NULL, 

                            
&ReturnConnectionInfo); 


        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 thread, we are a synchronous call so 

         * we want to wait until it has completed. The EVENT that 

         * we provided will be set when the IRP completes. 

         
*/
 


        
if(NtStatus == STATUS_PENDING) 

        


            KeWaitForSingleObject(
&TdiCompletionContext.kCompleteEvent, 

                                  Executive, KernelMode, FALSE, NULL); 


            
/* 

             * Find the Status of the completed IRP 

             
*/
 


            NtStatus 
= IoStatusBlock.Status; 

        }
 



    }
 


    
return NtStatus; 

}
 

步骤7:分离句柄关联


这个非常简单,我们只要实现另外的IOCTL调用就行了,如下:

NTSTATUS TdiFuncs_DisAssociateTransportAndConnection(PFILE_OBJECT pfoConnection) 



    NTSTATUS NtStatus 
= STATUS_INSUFFICIENT_RESOURCES; 

    PIRP pIrp; 

    IO_STATUS_BLOCK IoStatusBlock 
= {0}

    PDEVICE_OBJECT pTdiDevice; 

    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); 

     

    
/* 

     * 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_DISASSOCIATE_ADDRESS, 

             pTdiDevice, pfoConnection, 

             
&TdiCompletionContext.kCompleteEvent, &IoStatusBlock); 


    
if(pIrp) 

    


        
/* 

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

         
*/
 

        TdiBuildDisassociateAddress(pIrp, pTdiDevice, 

                        pfoConnection, NULL, NULL); 


        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 thread, we are a synchronous call   

         * so we want to wait until it has completed. The EVENT that we 

         * provided will be set when the IRP completes. 

         
*/
 


        
if(NtStatus == STATUS_PENDING) 

        


            KeWaitForSingleObject(
&TdiCompletionContext.kCompleteEvent, 

                                 Executive, KernelMode, FALSE, NULL); 


            
/* 

             * Find the Status of the completed IRP 

             
*/
 


            NtStatus 
= IoStatusBlock.Status; 

        }
 


    }
 


    
return NtStatus; 

}
 

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


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


导航

统计

常用链接

留言簿(2)

随笔分类

随笔档案

收藏夹

IT技术

积分与排名

最新评论

阅读排行榜

评论排行榜