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

http://hi.baidu.com/combojiang/item/edb1fb995490c48d5814610e

步骤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 @ 2013-01-15 11:09  himessage  阅读(372)  评论(0编辑  收藏  举报