示例#1
0
VOID NTAPI
DisconnectTimeoutDpc(PKDPC Dpc,
                     PVOID DeferredContext,
                     PVOID SystemArgument1,
                     PVOID SystemArgument2)
{
    PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)DeferredContext;
    PLIST_ENTRY Entry;
    PTDI_BUCKET Bucket;

    LockObjectAtDpcLevel(Connection);

    /* We timed out waiting for pending sends so force it to shutdown */
    TCPTranslateError(LibTCPShutdown(Connection, 0, 1));

    while (!IsListEmpty(&Connection->SendRequest))
    {
        Entry = RemoveHeadList(&Connection->SendRequest);
        
        Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
        
        Bucket->Information = 0;
        Bucket->Status = STATUS_FILE_CLOSED;
        
        CompleteBucket(Connection, Bucket, FALSE);
    }
    
    while (!IsListEmpty(&Connection->ShutdownRequest))
    {
        Entry = RemoveHeadList( &Connection->ShutdownRequest );
        
        Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
        
        Bucket->Status = STATUS_TIMEOUT;
        Bucket->Information = 0;
        
        CompleteBucket(Connection, Bucket, FALSE);
    }
    
    UnlockObjectFromDpcLevel(Connection);
    
    DereferenceObject(Connection);
}
示例#2
0
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;
  KIRQL OldIrql;

  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"));
      Status = STATUS_INVALID_PARAMETER;
      goto done;
    }

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

  Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;

  Status = DispPrepareIrpForCancel
      (TranContext->Handle.ConnectionContext,
       Irp,
       (PDRIVER_CANCEL)DispCancelListenRequest);

  LockObject(Connection, &OldIrql);

  if (Connection->AddressFile == NULL)
  {
     TI_DbgPrint(MID_TRACE, ("No associated address file\n"));
     UnlockObject(Connection, OldIrql);
     Status = STATUS_INVALID_PARAMETER;
     goto done;
  }

  LockObjectAtDpcLevel(Connection->AddressFile);

  /* 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( NT_SUCCESS(Status) && !Connection->AddressFile->Listener ) {
      Connection->AddressFile->Listener =
	  TCPAllocateConnectionEndpoint( NULL );

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

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

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

      if( NT_SUCCESS(Status) ) {
	  ReferenceObject(Connection->AddressFile->Listener);
	  Status = TCPListen( Connection->AddressFile->Listener, 1024 );
	  /* BACKLOG */
      }
  }

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

  UnlockObjectFromDpcLevel(Connection->AddressFile);
  UnlockObject(Connection, OldIrql);

done:
  if (Status != STATUS_PENDING) {
      DispDataRequestComplete(Irp, Status, 0);
  } else
      IoMarkIrpPending(Irp);

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

  return Status;
}
示例#3
0
NTSTATUS DispTdiAssociateAddress(
    PIRP Irp)
/*
 * FUNCTION: TDI_ASSOCIATE_ADDRESS handler
 * ARGUMENTS:
 *     Irp = Pointer to an I/O request packet
 * RETURNS:
 *     Status of operation
 */
{
  PTDI_REQUEST_KERNEL_ASSOCIATE Parameters;
  PTRANSPORT_CONTEXT TranContext;
  PIO_STACK_LOCATION IrpSp;
  PCONNECTION_ENDPOINT Connection, LastConnection;
  PFILE_OBJECT FileObject;
  PADDRESS_FILE AddrFile = NULL;
  NTSTATUS Status;
  KIRQL OldIrql;

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

  Parameters = (PTDI_REQUEST_KERNEL_ASSOCIATE)&IrpSp->Parameters;

  Status = ObReferenceObjectByHandle(
    Parameters->AddressHandle,
    0,
    *IoFileObjectType,
    KernelMode,
    (PVOID*)&FileObject,
    NULL);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MID_TRACE, ("Bad address file object handle (0x%X): %x.\n",
      Parameters->AddressHandle, Status));
    return STATUS_INVALID_PARAMETER;
  }

  LockObject(Connection, &OldIrql);

  if (Connection->AddressFile) {
    ObDereferenceObject(FileObject);
    UnlockObject(Connection, OldIrql);
    TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n"));
    return STATUS_INVALID_PARAMETER;
  }

  if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
    ObDereferenceObject(FileObject);
    UnlockObject(Connection, OldIrql);
    TI_DbgPrint(MID_TRACE, ("Bad address file object. Magic (0x%X).\n",
      FileObject->FsContext2));
    return STATUS_INVALID_PARAMETER;
  }

  /* Get associated address file object. Quit if none exists */

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

  AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
  if (!AddrFile) {
      UnlockObject(Connection, OldIrql);
      ObDereferenceObject(FileObject);
      TI_DbgPrint(MID_TRACE, ("No address file object.\n"));
      return STATUS_INVALID_PARAMETER;
  }

  LockObjectAtDpcLevel(AddrFile);

  ReferenceObject(AddrFile);
  Connection->AddressFile = AddrFile;

  /* Add connection endpoint to the address file */
  ReferenceObject(Connection);
  if (AddrFile->Connection == NULL)
      AddrFile->Connection = Connection;
  else
  {
      LastConnection = AddrFile->Connection;
      while (LastConnection->Next != NULL)
         LastConnection = LastConnection->Next;
      LastConnection->Next = Connection;
  }

  ObDereferenceObject(FileObject);

  UnlockObjectFromDpcLevel(AddrFile);
  UnlockObject(Connection, OldIrql);

  return STATUS_SUCCESS;
}