⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tdifuncs.c

📁 Introduction to the Transport Device Interface-f
💻 C
📖 第 1 页 / 共 2 页
字号:
 * 
 *  TdiFuncs_Connect
 *
 *    This is called to make a connection with a remote computer
 *
 **********************************************************************/

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)
         */

        pTdiAddressIp->sin_port = uiPort;       /* Example: 1494 = 0x05D6 (Little Endian) or 0xD605 (Big Endian)                  */
        pTdiAddressIp->in_addr  = uiAddress;    /* Example: 10.60.2.159 = 0A.3C.02.9F (Little Endian) or 9F.02.3C.0A (Big Endian) */

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



/**********************************************************************
 * 
 *  TdiFuncs_Send
 *
 *    This API demonstrates how to send data
 *
 **********************************************************************/
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.
             *
             *  http://msdn.microsoft.com/library/en-us/network/hh/network/34bldmac_f430860a-9ae2-4379-bffc-6b0a81092e7c.xml.asp?frame=true
             */
            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
                 *  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);
        
                }

                NtStatus   = IoStatusBlock.Status;
                *pDataSent = (UINT)IoStatusBlock.Information;
    
               /* 
                * I/O Manager will free the MDL
                *
                if(pSendMdl)
                {
                    MmUnlockPages(pSendMdl);
                    IoFreeMdl(pSendMdl);
                } */

            }
        }
    }

    return NtStatus;
}



/**********************************************************************
 * 
 *  TdiFuncs_Disconnect
 *
 *    This is called to disconnect from the remote computer
 *
 **********************************************************************/

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.
     *
     *  http://msdn.microsoft.com/library/en-us/network/hh/network/34bldmac_f430860a-9ae2-4379-bffc-6b0a81092e7c.xml.asp?frame=true
     */
    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;
}



/**********************************************************************
 * 
 *  TdiFuncs_DisAssociateTransportAndConnection
 *
 *    This is called to disassociate the transport with the connection
 *
 **********************************************************************/

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.
     *
     *  http://msdn.microsoft.com/library/en-us/network/hh/network/34bldmac_f430860a-9ae2-4379-bffc-6b0a81092e7c.xml.asp?frame=true
     */
    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;
}



/**********************************************************************
 * 
 *  TdiFuncs_CloseTdiOpenHandle
 *
 *    This is called to close open handles.
 *
 **********************************************************************/

NTSTATUS TdiFuncs_CloseTdiOpenHandle(HANDLE hTdiHandle, PFILE_OBJECT pfoTdiFileObject)
{
    NTSTATUS NtStatus = STATUS_SUCCESS;

    /*
     * De-Reference the FILE_OBJECT and Close The Handle
     */

    ObDereferenceObject(pfoTdiFileObject);
    ZwClose(hTdiHandle);

    return NtStatus;
}

/**********************************************************************
 * 
 *  TdiFuncs_CompleteIrp
 *
 *    This is called when the IRP is completed
 *
 **********************************************************************
NTSTATUS TdiFuncs_CompleteIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
    PTDI_COMPLETION_CONTEXT pTdiCompletionContext = (PTDI_COMPLETION_CONTEXT)Context;

       Do not mark the IRP as pending, we created it we may overwrite memory locations
       we don't want to !
    

    return STATUS_CONTINUE_COMPLETION ;
}
*/



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -