dispatch.c

来自「一个类似windows」· C语言 代码 · 共 1,568 行 · 第 1/4 页

C
1,568
字号

  /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
  ObDereferenceObject(FileObject);

  return Status;
}


NTSTATUS DispTdiConnect(
  PIRP Irp)
/*
 * FUNCTION: TDI_CONNECT handler
 * ARGUMENTS:
 *     Irp = Pointer to an I/O request packet
 * RETURNS:
 *     Status of operation
 */
{
  PCONNECTION_ENDPOINT Connection;
  PTDI_REQUEST_KERNEL Parameters;
  PTRANSPORT_CONTEXT TranContext;
  PIO_STACK_LOCATION IrpSp;
  NTSTATUS Status;

  TI_DbgPrint(DEBUG_IRP, ("Called.\n"));

  IrpSp = IoGetCurrentIrpStackLocation(Irp);

  /* Get associated connection endpoint file object. Quit if none exists */

  TranContext = IrpSp->FileObject->FsContext;
  if (!TranContext) {
    TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
    return STATUS_INVALID_CONNECTION;
  }

  Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
  if (!Connection) {
    TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
    return STATUS_INVALID_CONNECTION;
  }

  Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;

  Status = TCPConnect(
      TranContext->Handle.ConnectionContext,
      Parameters->RequestConnectionInformation,
      Parameters->ReturnConnectionInformation,
      DispDataRequestComplete,
      Irp );

  TI_DbgPrint(MAX_TRACE, ("TCP Connect returned %08x\n", Status));

  return Status;
}


NTSTATUS DispTdiDisassociateAddress(
  PIRP Irp)
/*
 * FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
 * ARGUMENTS:
 *     Irp = Pointer to an I/O request packet
 * RETURNS:
 *     Status of operation
 */
{
  PCONNECTION_ENDPOINT Connection;
  PTRANSPORT_CONTEXT TranContext;
  PIO_STACK_LOCATION IrpSp;

  TI_DbgPrint(DEBUG_IRP, ("Called.\n"));

  IrpSp = IoGetCurrentIrpStackLocation(Irp);

  /* Get associated connection endpoint file object. Quit if none exists */

  TranContext = IrpSp->FileObject->FsContext;
  if (!TranContext) {
    TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
    return STATUS_INVALID_PARAMETER;
  }

  Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
  if (!Connection) {
    TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
    return STATUS_INVALID_PARAMETER;
  }

  if (!Connection->AddressFile) {
    TI_DbgPrint(MID_TRACE, ("No address file is asscociated.\n"));
    return STATUS_INVALID_PARAMETER;
  }

  return STATUS_SUCCESS;
}


NTSTATUS DispTdiDisconnect(
  PIRP Irp)
/*
 * FUNCTION: TDI_DISCONNECT handler
 * ARGUMENTS:
 *     Irp = Pointer to an I/O request packet
 * RETURNS:
 *     Status of operation
 */
{
  NTSTATUS Status;
  PTDI_REQUEST_KERNEL_DISCONNECT DisReq;
  PCONNECTION_ENDPOINT Connection;
  PTRANSPORT_CONTEXT TranContext;
  PIO_STACK_LOCATION IrpSp;

  TI_DbgPrint(DEBUG_IRP, ("Called.\n"));

  IrpSp = IoGetCurrentIrpStackLocation(Irp);
  DisReq = (PTDI_REQUEST_KERNEL_DISCONNECT)&IrpSp->Parameters;

  /* Get associated connection endpoint file object. Quit if none exists */

  TranContext = IrpSp->FileObject->FsContext;
  if (!TranContext) {
    TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
    return STATUS_INVALID_CONNECTION;
  }

  Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
  if (!Connection) {
    TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
    return STATUS_INVALID_CONNECTION;
  }

  Status = TCPDisconnect(
      TranContext->Handle.ConnectionContext,
      DisReq->RequestFlags,
      DisReq->RequestConnectionInformation,
      DisReq->ReturnConnectionInformation,
      DispDataRequestComplete,
      Irp );

  TI_DbgPrint(MAX_TRACE, ("TCP Connect returned %08x\n", Status));

  return Status;
}


NTSTATUS DispTdiListen(
  PIRP Irp)
/*
 * FUNCTION: TDI_LISTEN handler
 * ARGUMENTS:
 *     Irp = Pointer to an I/O request packet
 * RETURNS:
 *     Status of operation
 */
{
  PCONNECTION_ENDPOINT Connection;
  PTDI_REQUEST_KERNEL Parameters;
  PTRANSPORT_CONTEXT TranContext;
  PIO_STACK_LOCATION IrpSp;
  NTSTATUS Status = STATUS_SUCCESS;

  TI_DbgPrint(DEBUG_IRP, ("Called.\n"));

  IrpSp = IoGetCurrentIrpStackLocation(Irp);

  /* Get associated connection endpoint file object. Quit if none exists */

  TranContext = IrpSp->FileObject->FsContext;
  if (TranContext == NULL)
    {
      TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
      return STATUS_INVALID_CONNECTION;
    }

  Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
  if (Connection == NULL)
    {
      TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
      return STATUS_INVALID_CONNECTION;
    }

  Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;

  TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile: %x\n",
			  Connection->AddressFile ));
  if( Connection->AddressFile ) {
      TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile->Listener: %x\n",
			      Connection->AddressFile->Listener));
  }

  /* Listening will require us to create a listening socket and store it in
   * the address file.  It will be signalled, and attempt to complete an irp
   * when a new connection arrives. */
  /* The important thing to note here is that the irp we'll complete belongs
   * to the socket to be accepted onto, not the listener */
  if( !Connection->AddressFile->Listener ) {
      Connection->AddressFile->Listener =
	  TCPAllocateConnectionEndpoint( NULL );

      if( !Connection->AddressFile->Listener )
	  Status = STATUS_NO_MEMORY;

      if( NT_SUCCESS(Status) ) {
	  Connection->AddressFile->Listener->AddressFile =
	      Connection->AddressFile;

	  Status = TCPSocket( Connection->AddressFile->Listener,
			      Connection->AddressFile->Family,
			      SOCK_STREAM,
			      Connection->AddressFile->Protocol );
      }

      if( NT_SUCCESS(Status) )
	  Status = TCPListen( Connection->AddressFile->Listener, 1024 );
	  /* BACKLOG */
  }
  if( NT_SUCCESS(Status) ) {
      Status = DispPrepareIrpForCancel
          (TranContext->Handle.ConnectionContext,
           Irp,
           (PDRIVER_CANCEL)DispCancelListenRequest);
  }

  if( NT_SUCCESS(Status) ) {
      Status = TCPAccept
	  ( (PTDI_REQUEST)Parameters,
	    Connection->AddressFile->Listener,
	    Connection,
	    DispDataRequestComplete,
	    Irp );
  }

  TI_DbgPrint(MID_TRACE,("Leaving %x\n", Status));

  return Status;
}


NTSTATUS DispTdiQueryInformation(
  PDEVICE_OBJECT DeviceObject,
  PIRP Irp)
/*
 * FUNCTION: TDI_QUERY_INFORMATION handler
 * ARGUMENTS:
 *     DeviceObject = Pointer to device object structure
 *     Irp          = Pointer to an I/O request packet
 * RETURNS:
 *     Status of operation
 */
{
  PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters;
  PTRANSPORT_CONTEXT TranContext;
  PIO_STACK_LOCATION IrpSp;

  TI_DbgPrint(DEBUG_IRP, ("Called.\n"));

  IrpSp = IoGetCurrentIrpStackLocation(Irp);
  Parameters = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&IrpSp->Parameters;

  TranContext = IrpSp->FileObject->FsContext;
  if (!TranContext) {
    TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
    return STATUS_INVALID_CONNECTION;
  }

  switch (Parameters->QueryType)
  {
    case TDI_QUERY_ADDRESS_INFO:
      {
        PTDI_ADDRESS_INFO AddressInfo;
        PADDRESS_FILE AddrFile;
        PTA_IP_ADDRESS Address;

        AddressInfo = (PTDI_ADDRESS_INFO)MmGetSystemAddressForMdl(Irp->MdlAddress);

        switch ((ULONG)IrpSp->FileObject->FsContext2) {
          case TDI_TRANSPORT_ADDRESS_FILE:
            AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
            break;

          case TDI_CONNECTION_FILE:
            AddrFile =
              ((PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext)->
              AddressFile;
            break;

          default:
            TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
            return STATUS_INVALID_PARAMETER;
        }

        if (!AddrFile) {
          TI_DbgPrint(MID_TRACE, ("No address file object.\n"));
          return STATUS_INVALID_PARAMETER;
        }

        if (MmGetMdlByteCount(Irp->MdlAddress) <
            (FIELD_OFFSET(TDI_ADDRESS_INFO, Address.Address[0].Address) +
             sizeof(TDI_ADDRESS_IP))) {
          TI_DbgPrint(MID_TRACE, ("MDL buffer too small.\n"));
          return STATUS_BUFFER_OVERFLOW;
        }

        Address = (PTA_IP_ADDRESS)&AddressInfo->Address;
        Address->TAAddressCount = 1;
        Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
        Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
        Address->Address[0].Address[0].sin_port = AddrFile->Port;
        Address->Address[0].Address[0].in_addr =
          AddrFile->Address.Address.IPv4Address;
        RtlZeroMemory(
          &Address->Address[0].Address[0].sin_zero,
          sizeof(Address->Address[0].Address[0].sin_zero));

        return STATUS_SUCCESS;
      }

    case TDI_QUERY_CONNECTION_INFO:
      {
        PTDI_CONNECTION_INFORMATION AddressInfo;
        PADDRESS_FILE AddrFile;
        PCONNECTION_ENDPOINT Endpoint = NULL;

        AddressInfo = (PTDI_CONNECTION_INFORMATION)
          MmGetSystemAddressForMdl(Irp->MdlAddress);

        switch ((ULONG)IrpSp->FileObject->FsContext2) {
          case TDI_TRANSPORT_ADDRESS_FILE:
            AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
            break;

          case TDI_CONNECTION_FILE:
            Endpoint =
              (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
            break;

          default:
            TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
            return STATUS_INVALID_PARAMETER;
        }

        if (!Endpoint) {
          TI_DbgPrint(MID_TRACE, ("No connection object.\n"));
          return STATUS_INVALID_PARAMETER;
        }

        if (MmGetMdlByteCount(Irp->MdlAddress) <
            (FIELD_OFFSET(TDI_CONNECTION_INFORMATION, RemoteAddress) +
             sizeof(PVOID))) {
          TI_DbgPrint(MID_TRACE, ("MDL buffer too small (ptr).\n"));
          return STATUS_BUFFER_OVERFLOW;
        }

        return TCPGetPeerAddress( Endpoint, AddressInfo->RemoteAddress );
      }
  }

  return STATUS_NOT_IMPLEMENTED;
}


NTSTATUS DispTdiReceive(
  PIRP Irp)
/*
 * FUNCTION: TDI_RECEIVE handler
 * ARGUMENTS:
 *     Irp = Pointer to an I/O request packet
 * RETURNS:
 *     Status of operation
 */
{
  PIO_STACK_LOCATION IrpSp;
  PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo;
  PTRANSPORT_CONTEXT TranContext;
  NTSTATUS Status;
  ULONG BytesReceived;

  TI_DbgPrint(DEBUG_IRP, ("Called.\n"));

  IrpSp = IoGetCurrentIrpStackLocation(Irp);
  ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&(IrpSp->Parameters);

  TranContext = IrpSp->FileObject->FsContext;
  if (TranContext == NULL)
    {
      TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
      return STATUS_INVALID_CONNECTION;
    }

  if (TranContext->Handle.ConnectionContext == NULL)

⌨️ 快捷键说明

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