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

http://hi.baidu.com/combojiang/item/623461f6f690a6b031c19932

接上

步骤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;

}

 

 

posted @ 2013-01-15 11:08  himessage  阅读(360)  评论(0编辑  收藏  举报