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

📄 tdi.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
  PIO_COMPLETION_ROUTINE CompletionRoutine,
  PVOID CompletionContext )
{
    PDEVICE_OBJECT DeviceObject;
    NTSTATUS Status = STATUS_SUCCESS;
    PMDL Mdl;

    DeviceObject = IoGetRelatedDeviceObject(TransportObject);
    if (!DeviceObject) {
        AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
        return STATUS_INVALID_PARAMETER;
    }

    *Irp = TdiBuildInternalDeviceControlIrp
	( TDI_SEND,                /* Sub function */
	  DeviceObject,            /* Device object */
	  TransportObject,         /* File object */
	  NULL,                    /* Event */
	  Iosb );                  /* Status */

    if (!*Irp) {
        AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    AFD_DbgPrint(MID_TRACE, ("Allocating irp for %x:%d\n", Buffer,BufferLength));

    Mdl = IoAllocateMdl(Buffer,         /* Virtual address */
                        BufferLength,   /* Length of buffer */
                        FALSE,          /* Not secondary */
                        FALSE,          /* Don't charge quota */
                        *Irp);          /* use IRP */
    if (!Mdl) {
        AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
        IoFreeIrp(*Irp);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    _SEH_TRY {
        MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
    } _SEH_HANDLE {
        AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
        IoFreeIrp(*Irp);
        Status = STATUS_INSUFFICIENT_RESOURCES;
    } _SEH_END;

    if( !NT_SUCCESS(Status) ) {
	IoFreeIrp(*Irp);
	return Status;
    }

    AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl));

    TdiBuildSend(*Irp,                   /* I/O Request Packet */
		 DeviceObject,           /* Device object */
		 TransportObject,        /* File object */
		 CompletionRoutine,      /* Completion routine */
		 CompletionContext,      /* Completion context */
		 Mdl,                    /* Data buffer */
		 Flags,                  /* Flags */
		 BufferLength);          /* Length of data */

    Status = TdiCall(*Irp, DeviceObject, NULL, Iosb);
    /* Does not block...  The MDL is deleted in the receive completion
       routine. */

    return Status;
}

NTSTATUS TdiReceive(
    PIRP *Irp,
    PFILE_OBJECT TransportObject,
    USHORT Flags,
    PCHAR Buffer,
    UINT BufferLength,
    PIO_STATUS_BLOCK Iosb,
    PIO_COMPLETION_ROUTINE CompletionRoutine,
    PVOID CompletionContext)
{
    NTSTATUS Status = STATUS_SUCCESS;
    PDEVICE_OBJECT DeviceObject;
    PMDL Mdl;

    DeviceObject = IoGetRelatedDeviceObject(TransportObject);
    if (!DeviceObject) {
        AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
        return STATUS_INVALID_PARAMETER;
    }

    *Irp = TdiBuildInternalDeviceControlIrp
	( TDI_RECEIVE,             /* Sub function */
	  DeviceObject,            /* Device object */
	  TransportObject,         /* File object */
	  NULL,                    /* Event */
	  Iosb );                  /* Status */

    if (!*Irp) {
        AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    AFD_DbgPrint(MID_TRACE, ("Allocating irp for %x:%d\n", Buffer,BufferLength));

    Mdl = IoAllocateMdl(Buffer,         /* Virtual address */
                        BufferLength,   /* Length of buffer */
                        FALSE,          /* Not secondary */
                        FALSE,          /* Don't charge quota */
                        *Irp);          /* Don't use IRP */
    if (!Mdl) {
        AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
        IoFreeIrp(*Irp);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    _SEH_TRY {
        AFD_DbgPrint(MIN_TRACE, ("probe and lock\n"));
        MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
        AFD_DbgPrint(MIN_TRACE, ("probe and lock done\n"));
    } _SEH_HANDLE {
        AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
        IoFreeIrp(*Irp);
	Status = STATUS_INSUFFICIENT_RESOURCES;
    } _SEH_END;

    if( !NT_SUCCESS(Status) ) {
	IoFreeIrp(*Irp);
	return Status;
    }

    AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl));

    TdiBuildReceive(*Irp,                   /* I/O Request Packet */
		    DeviceObject,           /* Device object */
		    TransportObject,        /* File object */
		    CompletionRoutine,      /* Completion routine */
		    CompletionContext,      /* Completion context */
		    Mdl,                    /* Data buffer */
		    Flags,                  /* Flags */
		    BufferLength);          /* Length of data */


    Status = TdiCall(*Irp, DeviceObject, NULL, Iosb);
    /* Does not block...  The MDL is deleted in the receive completion
       routine. */

    AFD_DbgPrint(MID_TRACE,("Status %x Information %d\n",
			    Status, Iosb->Information));

    return Status;
}


NTSTATUS TdiReceiveDatagram(
    PIRP *Irp,
    PFILE_OBJECT TransportObject,
    USHORT Flags,
    PCHAR Buffer,
    UINT BufferLength,
    PTDI_CONNECTION_INFORMATION Addr,
    PIO_STATUS_BLOCK Iosb,
    PIO_COMPLETION_ROUTINE CompletionRoutine,
    PVOID CompletionContext)
/*
 * FUNCTION: Receives a datagram
 * ARGUMENTS:
 *     TransportObject = Pointer to transport object
 *     From            = Receive filter (NULL if none)
 *     Address         = Address of buffer to place remote address
 *     Buffer          = Address of buffer to place received data
 *     BufferSize      = Address of buffer with length of Buffer (updated)
 * RETURNS:
 *     Status of operation
 */
{
    PDEVICE_OBJECT DeviceObject;
    NTSTATUS Status;
    PMDL Mdl;

    DeviceObject = IoGetRelatedDeviceObject(TransportObject);
    if (!DeviceObject) {
        AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
        return STATUS_INVALID_PARAMETER;
    }

    *Irp = TdiBuildInternalDeviceControlIrp
	( TDI_RECEIVE_DATAGRAM,    /* Sub function */
	  DeviceObject,            /* Device object */
	  TransportObject,         /* File object */
	  NULL,                    /* Event */
	  Iosb );                  /* Status */

    if (!*Irp) {
        AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    AFD_DbgPrint(MID_TRACE, ("Allocating irp for %x:%d\n", Buffer,BufferLength));

    Mdl = IoAllocateMdl(Buffer,         /* Virtual address */
                        BufferLength,   /* Length of buffer */
                        FALSE,          /* Not secondary */
                        FALSE,          /* Don't charge quota */
                        *Irp);          /* Don't use IRP */
    if (!Mdl) {
        AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
        IoFreeIrp(*Irp);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    _SEH_TRY {
        MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
    } _SEH_HANDLE {
        AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
        IoFreeIrp(*Irp);
        _SEH_YIELD(return STATUS_INSUFFICIENT_RESOURCES);
    } _SEH_END;

    AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl));

    TdiBuildReceiveDatagram
	(*Irp,                   /* I/O Request Packet */
	 DeviceObject,           /* Device object */
	 TransportObject,        /* File object */
	 CompletionRoutine,      /* Completion routine */
	 CompletionContext,      /* Completion context */
	 Mdl,                    /* Data buffer */
	 BufferLength,
	 Addr,
	 Addr,
	 Flags);                 /* Length of data */

    Status = TdiCall(*Irp, DeviceObject, NULL, Iosb);
    /* Does not block...  The MDL is deleted in the receive completion
       routine. */

    return Status;
}


NTSTATUS TdiSendDatagram(
    PIRP *Irp,
    PFILE_OBJECT TransportObject,
    PCHAR Buffer,
    UINT BufferLength,
    PTDI_CONNECTION_INFORMATION Addr,
    PIO_STATUS_BLOCK Iosb,
    PIO_COMPLETION_ROUTINE CompletionRoutine,
    PVOID CompletionContext)
/*
 * FUNCTION: Sends a datagram
 * ARGUMENTS:
 *     TransportObject = Pointer to transport object
 *     From            = Send filter (NULL if none)
 *     Address         = Address of buffer to place remote address
 *     Buffer          = Address of buffer to place send data
 *     BufferSize      = Address of buffer with length of Buffer (updated)
 * RETURNS:
 *     Status of operation
 */
{
    PDEVICE_OBJECT DeviceObject;
    NTSTATUS Status;
    PMDL Mdl;

    AFD_DbgPrint(MID_TRACE,("Called(TransportObject %x)\n", TransportObject));

    DeviceObject = IoGetRelatedDeviceObject(TransportObject);
    if (!DeviceObject) {
        AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
        return STATUS_INVALID_PARAMETER;
    }

    *Irp = TdiBuildInternalDeviceControlIrp
	( TDI_SEND_DATAGRAM,       /* Sub function */
	  DeviceObject,            /* Device object */
	  TransportObject,         /* File object */
	  NULL,                    /* Event */
	  Iosb );                  /* Status */

    if (!*Irp) {
        AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    AFD_DbgPrint(MID_TRACE, ("Allocating irp for %x:%d\n", Buffer,BufferLength));

    Mdl = IoAllocateMdl(Buffer,         /* Virtual address */
                        BufferLength,   /* Length of buffer */
                        FALSE,          /* Not secondary */
                        FALSE,          /* Don't charge quota */
                        *Irp);          /* Don't use IRP */

    if (!Mdl) {
        AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
        IoFreeIrp(*Irp);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    _SEH_TRY {
        MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
    } _SEH_HANDLE {
        AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
        IoFreeIrp(*Irp);
        _SEH_YIELD(return STATUS_INSUFFICIENT_RESOURCES);
    } _SEH_END;

    AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl));

    TdiBuildSendDatagram
	(*Irp,                   /* I/O Request Packet */
	 DeviceObject,           /* Device object */
	 TransportObject,        /* File object */
	 CompletionRoutine,      /* Completion routine */
	 CompletionContext,      /* Completion context */
	 Mdl,                    /* Data buffer */
	 BufferLength,           /* Bytes to send */
	 Addr);                  /* Address */

    Status = TdiCall(*Irp, DeviceObject, NULL, Iosb);
    /* Does not block...  The MDL is deleted in the send completion
       routine. */

    return Status;
}

NTSTATUS TdiDisconnect(
    PFILE_OBJECT TransportObject,
    PLARGE_INTEGER Time,
    USHORT Flags,
    PIO_STATUS_BLOCK Iosb,
    PIO_COMPLETION_ROUTINE CompletionRoutine,
    PVOID CompletionContext,
    PTDI_CONNECTION_INFORMATION RequestConnectionInfo,
    PTDI_CONNECTION_INFORMATION ReturnConnectionInfo) {
    PDEVICE_OBJECT DeviceObject;
    NTSTATUS Status;
    KEVENT Event;
    PIRP Irp;

    DeviceObject = IoGetRelatedDeviceObject(TransportObject);

    KeInitializeEvent(&Event, NotificationEvent, FALSE);

    AFD_DbgPrint(MID_TRACE,("Called(TransportObject %x)\n", TransportObject));

    DeviceObject = IoGetRelatedDeviceObject(TransportObject);
    if (!DeviceObject) {
        AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
        return STATUS_INVALID_PARAMETER;
    }

    Irp = TdiBuildInternalDeviceControlIrp
	( TDI_SEND_DATAGRAM,       /* Sub function */
	  DeviceObject,            /* Device object */
	  TransportObject,         /* File object */
	  &Event,                  /* Event */
	  Iosb );                  /* Status */

    if (!Irp) {
        AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    TdiBuildDisconnect
	(Irp,                    /* I/O Request Packet */
	 DeviceObject,           /* Device object */
	 TransportObject,        /* File object */
	 CompletionRoutine,      /* Completion routine */
	 CompletionContext,      /* Completion context */
	 Time,                   /* Time */
	 Flags,                  /* Disconnect flags */
	 RequestConnectionInfo,  /* Indication of who to disconnect */
	 ReturnConnectionInfo);  /* Indication of who disconnected */

    Status = TdiCall(Irp, DeviceObject, &Event, Iosb);

    return Status;
}

/* EOF */

⌨️ 快捷键说明

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