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

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

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

接上

步骤4:连接

创建一个TCP连接的客户端,我们需要连接。

NTSTATUS TdiFuncs_Connect(PFILE_OBJECT pfoConnection, 

                                UINT uiAddress, USHORT uiPort) 



    NTSTATUS NtStatus 
= STATUS_INSUFFICIENT_RESOURCES; 

    PIRP pIrp; 

    IO_STATUS_BLOCK IoStatusBlock 
= {0}

    PDEVICE_OBJECT pTdiDevice; 

    TDI_CONNECTION_INFORMATION RequestConnectionInfo 
= {0}

    TDI_CONNECTION_INFORMATION ReturnConnectionInfo 
= {0}

    LARGE_INTEGER TimeOut 
= {0}

    UINT NumberOfSeconds 
= 60*3

    
char cBuffer[256= {0}

    PTRANSPORT_ADDRESS pTransportAddress 
=(PTRANSPORT_ADDRESS)&cBuffer; 

    PTDI_ADDRESS_IP pTdiAddressIp; 

    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. 

     * 

     * 
http://msdn.microsoft.com/library/en-us/network/hh/network/ 

     *   34bldmac_f430860a-9ae2-4379-bffc-6b0a81092e7c.xml.asp?frame=true 

     
*/
 

   pIrp 
= TdiBuildInternalDeviceControlIrp(TDI_CONNECT, 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); 


        
/**//* 

         * Initialize the RequestConnectionInfo which specifies 

         * the address of the REMOTE computer 

         
*/
 


        RequestConnectionInfo.RemoteAddress       
= (PVOID)pTransportAddress; 

        RequestConnectionInfo.RemoteAddressLength 
= 

                      
sizeof(PTRANSPORT_ADDRESS) + sizeof(TDI_ADDRESS_IP); 


         
/**//* 

          * The number of transport addresses 

          
*/
 

         pTransportAddress
->TAAddressCount = 1

     

         
/**//* 

          * This next piece will essentially describe what the 

          *                             transport being opened is. 

          *     AddressType   = Type of transport 

          *     AddressLength = Length of the address 

          *     Address       = A data structure that is essentially 

          *                      related to the chosen AddressType. 

          
*/
 

     

         pTransportAddress
->Address[0].AddressType    = 

                                              TDI_ADDRESS_TYPE_IP; 

         pTransportAddress
->Address[0].AddressLength = 

                                              
sizeof(TDI_ADDRESS_IP); 

         pTdiAddressIp 
= 

             (TDI_ADDRESS_IP 
*)&pTransportAddress->Address[0].Address; 

     

         
/**//* 

          * The TDI_ADDRESS_IP data structure is essentially simmilar   

          *                to the usermode sockets data structure. 

          *    sin_port 

          *    sin_zero 

          *    in_addr 

          
*/
 


        
/**//* 

         * Remember, these must be in NETWORK BYTE ORDER (Big Endian) 

         
*/
 

          

        
/**//* Example: 1494 = 0x05D6 (Little Endian) or 0xD605 (Big Endian)*/ 

         

        pTdiAddressIp
->sin_port = uiPort;    

         

        
/**//* Example: 10.60.2.159 = 0A.3C.02.9F (Little Endian) 

           or 9F.02.3C.0A (Big Endian) 

        
*/
     

        pTdiAddressIp
->in_addr = uiAddress;     


        TdiBuildConnect(pIrp, pTdiDevice, pfoConnection, NULL, NULL, 

               
&TimeOut, &RequestConnectionInfo, 

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

}
 

你可能感兴趣的:(驱动开发之五 --- TDI之四 【译文】)